annotate src/libSAD/dither.c @ 4840:a4dd5fcc46ce

Add 5px padding for label_time
author Michal Lipski <tallica@o2.pl>
date Wed, 04 Mar 2009 15:36:58 +0100
parents bb0638143fc8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
1 /* Scale & Dither library (libSAD)
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
2 * High-precision bit depth converter with ReplayGain support
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
3 *
4233
74c6f3d3cf1d it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4232
diff changeset
4 * Copyright (c) 2007-2008 Eugene Zagidullin (e.asphyx@gmail.com)
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
5 *
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
6 * This program is free software; you can redistribute it and/or modify
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
7 * it under the terms of the GNU General Public License as published by
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
8 * the Free Software Foundation; either version 2 of the License, or
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
9 * (at your option) any later version.
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
10 *
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
11 * This program is distributed in the hope that it will be useful,
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
14 * GNU General Public License for more details.
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
16 * along with this program; if not, write to the Free Software
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
18 */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
19
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
20 /* #define CLIPPING_DEBUG
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
21 #define DEBUG
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
22 #define DITHER_DEBUG */
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
23
4234
b293ce14a01a partially works...
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4233
diff changeset
24 #include "common.h"
4233
74c6f3d3cf1d it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4232
diff changeset
25 #include "dither_ops.h"
74c6f3d3cf1d it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4232
diff changeset
26 #include "noicegen.h"
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
27
4757
bb0638143fc8 move libSAD's DEBUG_MSG out of global scope, as it breaks timidity and possible something else
Andrew O. Shadoura <bugzilla@tut.by>
parents: 4256
diff changeset
28 #include "debug.h"
bb0638143fc8 move libSAD's DEBUG_MSG out of global scope, as it breaks timidity and possible something else
Andrew O. Shadoura <bugzilla@tut.by>
parents: 4256
diff changeset
29
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
30 #include <assert.h>
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
31 #include <math.h>
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
32
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
33 /*
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
34 * Supported conversions:
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
35 *
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
36 * O U T P U T
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
37 * ,------------------+-----------------------------------------------.
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
38 * | |S8 U8 S16 U16 S24 U24 S32 U32 FLOAT FIXED-POINT|
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
39 * +------------------+-----------------------------------------------+
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
40 * | S8 |X X X X X X X X - - |
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
41 * | U8 |X X X X X X X X - - |
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
42 * I | S16 |X X X X X X X X - - |
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
43 * N | U16 |X X X X X X X X - - |
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
44 * P | S24 |X X X X X X X X - - |
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
45 * U | U24 |X X X X X X X X - - |
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
46 * T | S32 |X X X X X X X X - - |
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
47 * | U32 |X X X X X X X X - - |
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
48 * | FLOAT |X X X X X X X X X - |
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
49 * | FIXED-POINT |X X X X X X X X X - |
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
50 * `------------------+-----------------------------------------------'
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
51 */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
52
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
53 #define SCALE(x,s) (s != 1.0 ? x * s : x)
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
54 #define MAXINT(a) (1L << ((a)-1))
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
55 #define CLIP(x,m) (x > m-1 ? m-1 : (x < -m ? -m : x))
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
56
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
57 #define ADJUSTMENT_COEFFICIENT 0.1
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
58
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
59 /* private object */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
60 typedef struct {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
61 SAD_sample_format input_sample_format;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
62 SAD_sample_format output_sample_format;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
63 int input_bits;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
64 int input_fracbits;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
65 int output_bits;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
66 int output_fracbits;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
67 int channels;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
68 SAD_channels_order input_chorder;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
69 SAD_channels_order output_chorder;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
70 SAD_get_sample_proc get_sample;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
71 SAD_put_sample_proc put_sample;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
72 int dither;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
73 int hardlimit;
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
74 double scale;
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
75 double rg_scale;
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
76 int adaptive_scaler;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
77 } SAD_state_priv;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
78
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
79 /* error code */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
80
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
81 //static SAD_error SAD_last_error = SAD_ERROR_OK;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
82
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
83 static inline double compute_hardlimit (double sample, double scale) {
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
84 sample *= scale;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
85 const double k = 0.5; /* -6dBFS */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
86 if (sample > k) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
87 return tanh((sample - k) / (1 - k)) * (1 - k) + k;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
88 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
89 else if (sample < -k) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
90 return tanh((sample + k) / (1 - k)) * (1 - k) - k;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
91 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
92 return sample;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
93 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
94
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
95 /*
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
96 * Dither fixed-point normalized or integer sample to n-bits integer
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
97 * samples < -1 and > 1 will be clipped
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
98 */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
99
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
100 static inline int32_t __dither_sample_fixed_to_int (int32_t sample, int inbits, int fracbits, int outbits, double *scale, int dither,
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
101 int hardlimit, int adaptive_scale)
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
102 {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
103 int n_bits_to_loose, bitwidth, precision_loss;
4233
74c6f3d3cf1d it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4232
diff changeset
104 int32_t maxint = MAXINT(outbits);
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
105
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
106 n_bits_to_loose = 0;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
107 bitwidth = inbits;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
108 precision_loss = FALSE;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
109
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
110 /*#ifdef DEEP_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
111 printf("f: __dither_sample_fixed_to_int\n");
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
112 #endif*/
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
113
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
114 if (fracbits == 0) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
115 if (inbits<29) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
116 /* convert to 4.28 fixed-point */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
117 n_bits_to_loose = 29 - inbits;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
118 sample <<= n_bits_to_loose;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
119 bitwidth += n_bits_to_loose;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
120 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
121
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
122 n_bits_to_loose += inbits - outbits;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
123
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
124 if (inbits > outbits) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
125 precision_loss = TRUE;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
126 #ifdef PRECISION_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
127 printf("Precision loss, reason: bitwidth loss %d --> %d\n", inbits, outbits);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
128 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
129 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
130 } else {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
131 n_bits_to_loose = fracbits + 1 - outbits;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
132 bitwidth = fracbits;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
133 precision_loss = TRUE;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
134 #ifdef PRECISION_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
135 printf("Precision loss, reason: fixed-point input\n", inbits, outbits);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
136 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
137 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
138
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
139 assert(n_bits_to_loose >=0 );
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
140
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
141 /* adaptive scaler */
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
142 if (adaptive_scale) {
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
143 int sam = sample >> n_bits_to_loose;
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
144 double d_sam = fabs((double)sam) / (double)(maxint - 1);
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
145 if (d_sam * *scale > 1.0) {
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
146 #ifdef CLIPPING_DEBUG
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
147 printf("sample val %d, scale factor adjusted %f --> ", sam, *scale);
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
148 #endif
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
149 *scale -= (*scale - 1.0 / d_sam) * ADJUSTMENT_COEFFICIENT;
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
150 #ifdef CLIPPING_DEBUG
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
151 printf("%f\n", *scale);
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
152 #endif
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
153 }
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
154 sample = SCALE(sample, *scale);
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
155 } else
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
156 /*****************/
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
157 if (hardlimit) {
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
158 sample = (int32_t)(compute_hardlimit((double)sample/(double)MAXINT(bitwidth), *scale) * (double)MAXINT(bitwidth));
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
159 #ifdef PRECISION_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
160 printf("Precision loss, reason: hard limiter\n", inbits, outbits);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
161 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
162 precision_loss = TRUE;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
163 } else {
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
164 sample = SCALE(sample, *scale);
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
165 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
166
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
167 if (*scale != 1.0){
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
168 precision_loss = TRUE;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
169 #ifdef PRECISION_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
170 printf("Precision loss, reason: scale\n", inbits, outbits);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
171 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
172 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
173
4241
63eb5966f105 prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4240
diff changeset
174 if (precision_loss && (n_bits_to_loose >= 1) && (inbits < 32 || fracbits != 0)) sample += (1L << (n_bits_to_loose - 1));
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
175
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
176 #ifdef DITHER_DEBUG
4235
2d4b4f13d10d set_replaygain_info added to PAPI
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4234
diff changeset
177 int32_t val_wo_dither = sample >> n_bits_to_loose;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
178 val_wo_dither = CLIP(val_wo_dither, maxint);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
179 #endif
4241
63eb5966f105 prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4240
diff changeset
180 if (dither && precision_loss && (n_bits_to_loose >= 1) && (inbits < 32 || fracbits != 0)) {
4233
74c6f3d3cf1d it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4232
diff changeset
181 int32_t dither_num = triangular_dither_noise(n_bits_to_loose + 1);
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
182 sample += dither_num;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
183 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
184
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
185 sample >>= n_bits_to_loose;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
186
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
187 /* Clipping */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
188 #ifdef CLIPPING_DEBUG
4233
74c6f3d3cf1d it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4232
diff changeset
189 int32_t val_wo_clip = sample;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
190 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
191 sample = CLIP(sample, maxint);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
192 #ifdef CLIPPING_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
193 if (val_wo_clip != sample) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
194 printf("Clipping: %d --> %d\n", val_wo_clip, sample);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
195 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
196 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
197 #ifdef DITHER_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
198 if (dither && precision_loss && (n_bits_to_loose >= 1)) printf("%d --> %d, noise: %d\n", val_wo_dither, sample, sample - val_wo_dither);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
199 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
200 return sample;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
201 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
202
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
203 /*
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
204 * Dither floating-point normalized sample to n-bits integer
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
205 * samples < -1 and > 1 will be clipped
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
206 */
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
207 static inline int32_t __dither_sample_float_to_int (float sample, int nbits, double *scale, int dither, int hardlimit, int adaptive_scale) {
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
208
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
209 #ifdef DEEP_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
210 printf("f: __dither_sample_float_to_int\n");
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
211 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
212
4233
74c6f3d3cf1d it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4232
diff changeset
213 int32_t maxint = MAXINT(nbits);
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
214
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
215 /* adaptive scaler */
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
216 if (adaptive_scale) {
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
217 if (fabs(sample) * *scale > 1.0) {
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
218 #ifdef CLIPPING_DEBUG
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
219 printf("sample val %f, scale factor adjusted %f --> ", sample, *scale);
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
220 #endif
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
221 *scale -= (*scale - 1.0 / sample) * ADJUSTMENT_COEFFICIENT;
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
222 #ifdef CLIPPING_DEBUG
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
223 printf("%f\n", *scale);
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
224 #endif
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
225 }
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
226 sample = SCALE(sample, *scale);
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
227 } else
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
228 /*****************/
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
229 if (hardlimit) {
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
230 sample = compute_hardlimit((double)sample, *scale);
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
231 } else {
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
232 sample = SCALE(sample, *scale);
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
233 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
234
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
235 sample *= maxint;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
236 /* we want to round precisely */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
237 sample = (sample < 0 ? sample - 0.5 : sample + 0.5);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
238
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
239 #ifdef DITHER_DEBUG
4233
74c6f3d3cf1d it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4232
diff changeset
240 int32_t val_wo_dither = (int32_t) sample;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
241 val_wo_dither = CLIP(val_wo_dither, maxint);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
242 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
243 if (dither) {
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
244 double dither_num = triangular_dither_noise_f();
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
245 sample += dither_num;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
246 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
247
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
248 /* Round and clipping */
4233
74c6f3d3cf1d it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4232
diff changeset
249 int32_t value = (int32_t) sample;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
250 #ifdef CLIPPING_DEBUG
4233
74c6f3d3cf1d it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4232
diff changeset
251 int32_t val_wo_clip = value;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
252 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
253 value = CLIP(value, maxint);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
254 #ifdef CLIPPING_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
255 if (val_wo_clip != value) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
256 printf("Clipping: %d --> %d\n", val_wo_clip, value);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
257 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
258 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
259
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
260 #ifdef DITHER_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
261 printf("%d --> %d, noise: %d\n", val_wo_dither, value, value - val_wo_dither);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
262 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
263 return value;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
264 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
265
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
266 static inline float __dither_sample_float_to_float (float sample, double scale, int hardlimit) {
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
267 #ifdef DEEP_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
268 printf("f: __dither_sample_float_to_float\n");
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
269 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
270 if (hardlimit) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
271 sample = compute_hardlimit((double)sample, scale);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
272 } else {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
273 sample = SCALE(sample, scale);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
274 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
275 return sample;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
276 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
277
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
278 static inline float __dither_sample_fixed_to_float (int32_t sample, int inbits, int fracbits, double scale, int hardlimit) {
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
279 float fsample;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
280
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
281 #ifdef DEEP_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
282 printf("f: __dither_sample_fixed_to_float\n");
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
283 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
284 if (fracbits == 0) {
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
285 fsample = (double)sample / (double)MAXINT(inbits);
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
286 } else {
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
287 fsample = (double)sample / (double)MAXINT(fracbits+1);
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
288 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
289 return __dither_sample_float_to_float (fsample, scale, hardlimit);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
290 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
291
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
292
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
293
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
294
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
295
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
296 SAD_dither_t* SAD_dither_init(SAD_buffer_format *inbuf_format, SAD_buffer_format *outbuf_format, int *error) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
297 SAD_state_priv *priv;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
298
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
299 DEBUG_MSG("f: SAD_dither_init\n",0);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
300
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
301 priv = calloc(sizeof(SAD_state_priv), 1);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
302
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
303 /* Check buffer formats and assign buffer ops */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
304 SAD_buffer_ops* inops = SAD_assign_buf_ops(inbuf_format);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
305
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
306 if (inbuf_format->sample_format != SAD_SAMPLE_FLOAT) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
307 if (inops != NULL) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
308 priv->get_sample = inops->get_sample;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
309 } else {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
310 free(priv);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
311 *error = SAD_ERROR_INCORRECT_INPUT_SAMPLEFORMAT;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
312 return NULL;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
313 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
314 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
315
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
316 SAD_buffer_ops* outops = SAD_assign_buf_ops(outbuf_format);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
317
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
318 if (outbuf_format->sample_format != SAD_SAMPLE_FLOAT) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
319 if (outops != NULL) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
320 priv->put_sample = outops->put_sample;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
321 } else {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
322 free(priv);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
323 *error = SAD_ERROR_INCORRECT_OUTPUT_SAMPLEFORMAT;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
324 return NULL;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
325 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
326 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
327
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
328 priv->input_fracbits = 0;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
329 priv->output_fracbits = 0;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
330 priv->input_sample_format = inbuf_format->sample_format;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
331 priv->output_sample_format = outbuf_format->sample_format;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
332 priv->input_chorder = inbuf_format->channels_order;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
333 priv->output_chorder = outbuf_format->channels_order;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
334 priv->channels = inbuf_format->channels;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
335 priv->scale = 1.0;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
336 priv->rg_scale = 1.0;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
337 priv->dither = TRUE;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
338 priv->hardlimit = FALSE;
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
339 priv->adaptive_scaler = FALSE;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
340
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
341 switch(outbuf_format->sample_format){
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
342 case SAD_SAMPLE_S8:
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
343 case SAD_SAMPLE_U8: priv->output_bits = 8; break;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
344 case SAD_SAMPLE_S16:
4234
b293ce14a01a partially works...
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4233
diff changeset
345 case SAD_SAMPLE_S16_LE:
4238
75ea2083e744 some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4237
diff changeset
346 case SAD_SAMPLE_S16_BE:
75ea2083e744 some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4237
diff changeset
347 case SAD_SAMPLE_U16:
75ea2083e744 some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4237
diff changeset
348 case SAD_SAMPLE_U16_LE:
75ea2083e744 some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4237
diff changeset
349 case SAD_SAMPLE_U16_BE: priv->output_bits = 16; break;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
350 case SAD_SAMPLE_S24:
4239
51291ce4eb54 some endianness-related changes, corrected error handling
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4238
diff changeset
351 case SAD_SAMPLE_S24_LE:
51291ce4eb54 some endianness-related changes, corrected error handling
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4238
diff changeset
352 case SAD_SAMPLE_S24_BE:
4240
29c8603a877a added FMT_FIXED32, an equivalent of mad_fixed_t, already supported by libSAD; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4239
diff changeset
353 case SAD_SAMPLE_U24:
29c8603a877a added FMT_FIXED32, an equivalent of mad_fixed_t, already supported by libSAD; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4239
diff changeset
354 case SAD_SAMPLE_U24_LE:
29c8603a877a added FMT_FIXED32, an equivalent of mad_fixed_t, already supported by libSAD; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4239
diff changeset
355 case SAD_SAMPLE_U24_BE: priv->output_bits = 24; break;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
356 case SAD_SAMPLE_S32:
4241
63eb5966f105 prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4240
diff changeset
357 case SAD_SAMPLE_S32_LE:
63eb5966f105 prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4240
diff changeset
358 case SAD_SAMPLE_S32_BE:
63eb5966f105 prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4240
diff changeset
359 case SAD_SAMPLE_U32:
63eb5966f105 prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4240
diff changeset
360 case SAD_SAMPLE_U32_LE:
63eb5966f105 prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4240
diff changeset
361 case SAD_SAMPLE_U32_BE: priv->output_bits = 32; break;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
362 case SAD_SAMPLE_FLOAT: break;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
363 default:
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
364 free(priv);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
365 *error = SAD_ERROR_INCORRECT_OUTPUT_SAMPLEFORMAT;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
366 return NULL;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
367 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
368
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
369 switch(inbuf_format->sample_format){
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
370 case SAD_SAMPLE_S8:
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
371 case SAD_SAMPLE_U8: priv->input_bits = 8; break;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
372 case SAD_SAMPLE_S16:
4234
b293ce14a01a partially works...
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4233
diff changeset
373 case SAD_SAMPLE_S16_LE:
4238
75ea2083e744 some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4237
diff changeset
374 case SAD_SAMPLE_S16_BE:
75ea2083e744 some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4237
diff changeset
375 case SAD_SAMPLE_U16:
75ea2083e744 some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4237
diff changeset
376 case SAD_SAMPLE_U16_LE:
75ea2083e744 some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4237
diff changeset
377 case SAD_SAMPLE_U16_BE: priv->input_bits = 16; break;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
378 case SAD_SAMPLE_S24:
4239
51291ce4eb54 some endianness-related changes, corrected error handling
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4238
diff changeset
379 case SAD_SAMPLE_S24_LE:
51291ce4eb54 some endianness-related changes, corrected error handling
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4238
diff changeset
380 case SAD_SAMPLE_S24_BE:
4240
29c8603a877a added FMT_FIXED32, an equivalent of mad_fixed_t, already supported by libSAD; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4239
diff changeset
381 case SAD_SAMPLE_U24:
29c8603a877a added FMT_FIXED32, an equivalent of mad_fixed_t, already supported by libSAD; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4239
diff changeset
382 case SAD_SAMPLE_U24_LE:
29c8603a877a added FMT_FIXED32, an equivalent of mad_fixed_t, already supported by libSAD; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4239
diff changeset
383 case SAD_SAMPLE_U24_BE: priv->input_bits = 24; break;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
384 case SAD_SAMPLE_S32:
4241
63eb5966f105 prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4240
diff changeset
385 case SAD_SAMPLE_S32_LE:
63eb5966f105 prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4240
diff changeset
386 case SAD_SAMPLE_S32_BE:
63eb5966f105 prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4240
diff changeset
387 case SAD_SAMPLE_U32:
63eb5966f105 prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4240
diff changeset
388 case SAD_SAMPLE_U32_LE:
63eb5966f105 prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4240
diff changeset
389 case SAD_SAMPLE_U32_BE: priv->input_bits = 32; break;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
390 case SAD_SAMPLE_FIXED32: priv->input_fracbits = inbuf_format->fracbits; break;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
391 case SAD_SAMPLE_FLOAT: break;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
392 default:
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
393 free(priv);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
394 *error = SAD_ERROR_INCORRECT_INPUT_SAMPLEFORMAT;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
395 return NULL;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
396 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
397
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
398 *error = SAD_ERROR_OK;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
399 return (SAD_dither_t*)priv;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
400 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
401
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
402 int SAD_dither_free(SAD_dither_t* state) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
403 DEBUG_MSG("f: SAD_dither_free\n",0);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
404 free(state);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
405 return SAD_ERROR_OK;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
406 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
407
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
408 /*
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
409 * Depend on format->channels_order inbuf and outbuf will be treated as
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
410 * smth* or smth** if channels_order = SAD_CHORDER_INTERLEAVED or SAD_CHORDER_SEPARATED
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
411 * accordingly
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
412 *
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
413 * frame is aggregate of format->channels samples
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
414 */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
415
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
416 #define GET_FLOAT_SAMPLE(b,o,n,c,i) (o == SAD_CHORDER_INTERLEAVED ? (((float*)b)[i*n+c]) : (((float**)b)[c][i]))
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
417 #define PUT_FLOAT_SAMPLE(b,o,n,c,i,s) { \
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
418 if (o == SAD_CHORDER_INTERLEAVED) { \
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
419 ((float*)b)[i*n+c] = s; \
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
420 } else { \
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
421 ((float**)b)[c][i] = s; \
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
422 } \
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
423 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
424
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
425 int SAD_dither_process_buffer (SAD_dither_t *state, void *inbuf, void *outbuf, int frames)
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
426 {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
427 SAD_state_priv *priv = (SAD_state_priv*) state;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
428 int i, ch;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
429 int channels = priv->channels;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
430 int inbits = priv->input_bits;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
431 int outbits = priv->output_bits;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
432 int fracbits = priv->input_fracbits;
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
433 double scale = priv->scale * priv->rg_scale;
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
434 double oldscale = scale;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
435 int dither = priv->dither;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
436 int hardlimit = priv->hardlimit;
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
437 int adaptive_scale = priv->adaptive_scaler;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
438 SAD_channels_order input_chorder = priv->input_chorder;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
439 SAD_channels_order output_chorder = priv->output_chorder;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
440
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
441 SAD_get_sample_proc get_sample = priv->get_sample;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
442 SAD_put_sample_proc put_sample = priv->put_sample;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
443
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
444 #ifdef DEEP_DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
445 printf("f: SAD_process_buffer\n");
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
446 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
447
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
448 if (priv->input_sample_format == SAD_SAMPLE_FLOAT) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
449 if (priv->output_sample_format == SAD_SAMPLE_FLOAT) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
450 /* process buffer */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
451 for(i=0; i<frames; i++) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
452 for(ch=0; ch<channels; ch++) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
453 float sample = GET_FLOAT_SAMPLE(inbuf, input_chorder, channels, ch ,i);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
454 sample = __dither_sample_float_to_float(sample, scale, hardlimit);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
455 PUT_FLOAT_SAMPLE(outbuf, output_chorder, channels, ch ,i, sample);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
456 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
457 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
458 } else {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
459 if (put_sample == NULL) return SAD_ERROR_CORRUPTED_PRIVATE_DATA;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
460 /* process buffer */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
461 for(i=0; i<frames; i++) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
462 for(ch=0; ch<channels; ch++) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
463 float sample = GET_FLOAT_SAMPLE(inbuf, input_chorder, channels, ch ,i);
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
464 int32_t isample = __dither_sample_float_to_int(sample, outbits, &scale, dither, hardlimit, adaptive_scale);
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
465 put_sample (outbuf, isample, channels, ch, i);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
466 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
467 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
468 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
469 } else {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
470 if (priv->output_sample_format == SAD_SAMPLE_FLOAT) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
471 if (get_sample == NULL) return SAD_ERROR_CORRUPTED_PRIVATE_DATA;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
472 /* process buffer */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
473 for(i=0; i<frames; i++) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
474 for(ch=0; ch<channels; ch++) {
4233
74c6f3d3cf1d it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4232
diff changeset
475 int32_t sample = get_sample (inbuf, channels, ch, i);
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
476 float fsample = __dither_sample_fixed_to_float (sample, inbits, fracbits, scale, hardlimit);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
477 PUT_FLOAT_SAMPLE(outbuf, output_chorder, channels, ch ,i, fsample);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
478 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
479 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
480 } else {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
481 if (put_sample == NULL || get_sample == NULL) return SAD_ERROR_CORRUPTED_PRIVATE_DATA;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
482 /* process buffer */
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
483 for(i=0; i<frames; i++) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
484 for(ch=0; ch<channels; ch++){
4233
74c6f3d3cf1d it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4232
diff changeset
485 int32_t sample = get_sample (inbuf, channels, ch, i);
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
486 int32_t isample = __dither_sample_fixed_to_int (sample, inbits, fracbits, outbits, &scale, dither, hardlimit, adaptive_scale);
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
487 put_sample (outbuf, isample, channels, ch, i);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
488 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
489 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
490 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
491 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
492
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
493 /* recalc scale factor */
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
494 if (adaptive_scale && oldscale != scale) priv->rg_scale = scale / priv->scale;
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
495
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
496 return SAD_ERROR_OK;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
497 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
498
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
499 int SAD_dither_apply_replaygain (SAD_dither_t *state, SAD_replaygain_info *rg_info, SAD_replaygain_mode *mode) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
500 SAD_state_priv *priv = (SAD_state_priv*) state;
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
501 double scale = -1.0, peak = 0.0;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
502
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
503 DEBUG_MSG("f: SAD_dither_apply_replaygain\n",0);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
504
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
505 if(!rg_info->present) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
506 priv->rg_scale = 1.0;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
507 priv->hardlimit = FALSE;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
508 return SAD_ERROR_OK;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
509 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
510
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
511 switch(mode->mode) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
512 case SAD_RG_ALBUM:
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
513 scale = db2scale(rg_info->album_gain);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
514 peak = rg_info->album_peak;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
515 if (peak == 0.0) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
516 scale = db2scale(rg_info->track_gain); // fallback to per-track mode
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
517 peak = rg_info->track_peak;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
518 DEBUG_MSG("f: SAD_dither_apply_replaygain: fallback to track mode\n",0);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
519 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
520 break;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
521 case SAD_RG_TRACK:
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
522 scale = db2scale(rg_info->track_gain);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
523 peak = rg_info->track_peak;
4237
8f6956130372 initial Replay Gain support
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4235
diff changeset
524 if (peak == 0.0) {
8f6956130372 initial Replay Gain support
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4235
diff changeset
525 scale = db2scale(rg_info->album_gain); // fallback to per-album mode
8f6956130372 initial Replay Gain support
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4235
diff changeset
526 peak = rg_info->album_peak;
8f6956130372 initial Replay Gain support
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4235
diff changeset
527 DEBUG_MSG("f: SAD_dither_apply_replaygain: fallback to album mode\n",0);
8f6956130372 initial Replay Gain support
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4235
diff changeset
528 }
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
529 break;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
530 case SAD_RG_NONE:
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
531 scale = -1.0;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
532 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
533
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
534 if (scale != -1.0 && peak != 0.0) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
535 DEBUG_MSG("f: SAD_dither_apply_replaygain: applying\n",0);
4237
8f6956130372 initial Replay Gain support
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4235
diff changeset
536 scale *= db2scale(mode->preamp);
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
537 // Clipping prevention
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
538 if(mode->clipping_prevention) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
539 #ifdef DEBUG
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
540 if(scale * peak > 1.0) DEBUG_MSG("f: SAD_dither_apply_replaygain: clipping prevented\n",0);
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
541 #endif
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
542 scale = scale * peak > 1.0 ? 1.0 / peak : scale;
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
543 DEBUG_MSG("f: SAD_dither_apply_replaygain: new scale %f\n", scale);
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
544 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
545 scale = scale > 15.0 ? 15.0 : scale; // safety
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
546 priv->rg_scale = scale;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
547 priv->hardlimit = mode->hard_limit; // apply settings
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
548 priv->adaptive_scaler = mode->adaptive_scaler;
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
549 } else {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
550 priv->rg_scale = 1.0;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
551 priv->hardlimit = FALSE;
4256
b0ca963fd965 adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4241
diff changeset
552 priv->adaptive_scaler = FALSE; // apply settings
4232
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
553 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
554
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
555 return SAD_ERROR_OK;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
556 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
557
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
558 int SAD_dither_set_scale (SAD_dither_t *state, float scale) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
559 SAD_state_priv *priv = (SAD_state_priv*) state;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
560 priv->scale = scale;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
561 return SAD_ERROR_OK;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
562 }
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
563
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
564 int SAD_dither_set_dither (SAD_dither_t *state, int dither) {
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
565 SAD_state_priv *priv = (SAD_state_priv*) state;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
566 priv->dither = dither;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
567 return SAD_ERROR_OK;
704607c1f858 1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff changeset
568 }
4234
b293ce14a01a partially works...
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4233
diff changeset
569
b293ce14a01a partially works...
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4233
diff changeset
570 void SAD_dither_init_rand(uint32_t seed) {
b293ce14a01a partially works...
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4233
diff changeset
571 noicegen_init_rand(seed);
b293ce14a01a partially works...
Eugene Zagidullin <e.asphyx@gmail.com>
parents: 4233
diff changeset
572 }