Mercurial > audlegacy
annotate src/libSAD/dither.c @ 4650:31a4cc265f31
Removed the deprecated set_eq() function from InputPlugin and other places.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 16 Jun 2008 06:37:18 +0300 |
parents | b0ca963fd965 |
children | bb0638143fc8 |
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 | 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 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
28 #include <assert.h> |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
29 #include <math.h> |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
30 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
31 /* |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
32 * Supported conversions: |
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 * O U T P U T |
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 * | |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
|
37 * +------------------+-----------------------------------------------+ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
38 * | 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
|
39 * | 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
|
40 * 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
|
41 * 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
|
42 * 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
|
43 * 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
|
44 * 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
|
45 * | 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
|
46 * | 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
|
47 * | 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
|
48 * `------------------+-----------------------------------------------' |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
49 */ |
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 #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
|
52 #define MAXINT(a) (1L << ((a)-1)) |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
53 #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
|
54 |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
55 #define ADJUSTMENT_COEFFICIENT 0.1 |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
56 |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
57 /* private object */ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
58 typedef struct { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
59 SAD_sample_format input_sample_format; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
60 SAD_sample_format output_sample_format; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
61 int input_bits; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
62 int input_fracbits; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
63 int output_bits; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
64 int output_fracbits; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
65 int channels; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
66 SAD_channels_order input_chorder; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
67 SAD_channels_order output_chorder; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
68 SAD_get_sample_proc get_sample; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
69 SAD_put_sample_proc put_sample; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
70 int dither; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
71 int hardlimit; |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
72 double scale; |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
73 double rg_scale; |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
74 int adaptive_scaler; |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
75 } SAD_state_priv; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
76 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
77 /* error code */ |
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 //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
|
80 |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
81 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
|
82 sample *= scale; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
83 const double k = 0.5; /* -6dBFS */ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
84 if (sample > k) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
85 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
|
86 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
87 else if (sample < -k) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
88 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
|
89 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
90 return sample; |
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 |
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 * 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
|
95 * 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
|
96 */ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
97 |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
98 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
|
99 int hardlimit, int adaptive_scale) |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
100 { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
101 int n_bits_to_loose, bitwidth, precision_loss; |
4233
74c6f3d3cf1d
it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4232
diff
changeset
|
102 int32_t maxint = MAXINT(outbits); |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
103 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
104 n_bits_to_loose = 0; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
105 bitwidth = inbits; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
106 precision_loss = FALSE; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
107 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
108 /*#ifdef DEEP_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
109 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
|
110 #endif*/ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
111 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
112 if (fracbits == 0) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
113 if (inbits<29) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
114 /* convert to 4.28 fixed-point */ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
115 n_bits_to_loose = 29 - inbits; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
116 sample <<= n_bits_to_loose; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
117 bitwidth += n_bits_to_loose; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
118 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
119 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
120 n_bits_to_loose += inbits - outbits; |
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 if (inbits > outbits) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
123 precision_loss = TRUE; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
124 #ifdef PRECISION_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
125 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
|
126 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
127 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
128 } else { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
129 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
|
130 bitwidth = fracbits; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
131 precision_loss = TRUE; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
132 #ifdef PRECISION_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
133 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
|
134 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
135 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
136 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
137 assert(n_bits_to_loose >=0 ); |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
138 |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
139 /* adaptive scaler */ |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
140 if (adaptive_scale) { |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
141 int sam = sample >> n_bits_to_loose; |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
142 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
|
143 if (d_sam * *scale > 1.0) { |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
144 #ifdef CLIPPING_DEBUG |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
145 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
|
146 #endif |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
147 *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
|
148 #ifdef CLIPPING_DEBUG |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
149 printf("%f\n", *scale); |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
150 #endif |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
151 } |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
152 sample = SCALE(sample, *scale); |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
153 } else |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
154 /*****************/ |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
155 if (hardlimit) { |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
156 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
|
157 #ifdef PRECISION_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
158 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
|
159 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
160 precision_loss = TRUE; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
161 } else { |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
162 sample = SCALE(sample, *scale); |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
163 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
164 |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
165 if (*scale != 1.0){ |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
166 precision_loss = TRUE; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
167 #ifdef PRECISION_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
168 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
|
169 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
170 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
171 |
4241
63eb5966f105
prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4240
diff
changeset
|
172 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
|
173 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
174 #ifdef DITHER_DEBUG |
4235
2d4b4f13d10d
set_replaygain_info added to PAPI
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4234
diff
changeset
|
175 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
|
176 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
|
177 #endif |
4241
63eb5966f105
prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4240
diff
changeset
|
178 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
|
179 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
|
180 sample += dither_num; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
181 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
182 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
183 sample >>= n_bits_to_loose; |
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 /* Clipping */ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
186 #ifdef CLIPPING_DEBUG |
4233
74c6f3d3cf1d
it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4232
diff
changeset
|
187 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
|
188 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
189 sample = CLIP(sample, maxint); |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
190 #ifdef CLIPPING_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
191 if (val_wo_clip != sample) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
192 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
|
193 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
194 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
195 #ifdef DITHER_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
196 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
|
197 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
198 return sample; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
199 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
200 |
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 * 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
|
203 * 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
|
204 */ |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
205 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
|
206 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
207 #ifdef DEEP_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
208 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
|
209 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
210 |
4233
74c6f3d3cf1d
it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4232
diff
changeset
|
211 int32_t maxint = MAXINT(nbits); |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
212 |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
213 /* adaptive scaler */ |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
214 if (adaptive_scale) { |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
215 if (fabs(sample) * *scale > 1.0) { |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
216 #ifdef CLIPPING_DEBUG |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
217 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
|
218 #endif |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
219 *scale -= (*scale - 1.0 / sample) * ADJUSTMENT_COEFFICIENT; |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
220 #ifdef CLIPPING_DEBUG |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
221 printf("%f\n", *scale); |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
222 #endif |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
223 } |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
224 sample = SCALE(sample, *scale); |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
225 } else |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
226 /*****************/ |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
227 if (hardlimit) { |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
228 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
|
229 } else { |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
230 sample = SCALE(sample, *scale); |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
231 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
232 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
233 sample *= maxint; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
234 /* we want to round precisely */ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
235 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
|
236 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
237 #ifdef DITHER_DEBUG |
4233
74c6f3d3cf1d
it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4232
diff
changeset
|
238 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
|
239 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
|
240 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
241 if (dither) { |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
242 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
|
243 sample += dither_num; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
244 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
245 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
246 /* Round and clipping */ |
4233
74c6f3d3cf1d
it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4232
diff
changeset
|
247 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
|
248 #ifdef CLIPPING_DEBUG |
4233
74c6f3d3cf1d
it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4232
diff
changeset
|
249 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
|
250 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
251 value = CLIP(value, maxint); |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
252 #ifdef CLIPPING_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
253 if (val_wo_clip != value) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
254 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
|
255 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
256 #endif |
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 #ifdef DITHER_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
259 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
|
260 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
261 return value; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
262 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
263 |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
264 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
|
265 #ifdef DEEP_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
266 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
|
267 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
268 if (hardlimit) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
269 sample = compute_hardlimit((double)sample, scale); |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
270 } else { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
271 sample = SCALE(sample, scale); |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
272 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
273 return sample; |
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 |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
276 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
|
277 float fsample; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
278 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
279 #ifdef DEEP_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
280 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
|
281 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
282 if (fracbits == 0) { |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
283 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
|
284 } else { |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
285 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
|
286 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
287 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
|
288 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
289 |
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 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
|
295 SAD_state_priv *priv; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
296 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
297 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
|
298 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
299 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
|
300 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
301 /* 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
|
302 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
|
303 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
304 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
|
305 if (inops != NULL) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
306 priv->get_sample = inops->get_sample; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
307 } else { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
308 free(priv); |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
309 *error = SAD_ERROR_INCORRECT_INPUT_SAMPLEFORMAT; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
310 return NULL; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
311 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
312 } |
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 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
|
315 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
316 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
|
317 if (outops != NULL) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
318 priv->put_sample = outops->put_sample; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
319 } else { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
320 free(priv); |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
321 *error = SAD_ERROR_INCORRECT_OUTPUT_SAMPLEFORMAT; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
322 return NULL; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
323 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
324 } |
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 priv->input_fracbits = 0; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
327 priv->output_fracbits = 0; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
328 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
|
329 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
|
330 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
|
331 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
|
332 priv->channels = inbuf_format->channels; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
333 priv->scale = 1.0; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
334 priv->rg_scale = 1.0; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
335 priv->dither = TRUE; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
336 priv->hardlimit = FALSE; |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
337 priv->adaptive_scaler = FALSE; |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
338 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
339 switch(outbuf_format->sample_format){ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
340 case SAD_SAMPLE_S8: |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
341 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
|
342 case SAD_SAMPLE_S16: |
4234 | 343 case SAD_SAMPLE_S16_LE: |
4238
75ea2083e744
some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4237
diff
changeset
|
344 case SAD_SAMPLE_S16_BE: |
75ea2083e744
some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4237
diff
changeset
|
345 case SAD_SAMPLE_U16: |
75ea2083e744
some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4237
diff
changeset
|
346 case SAD_SAMPLE_U16_LE: |
75ea2083e744
some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4237
diff
changeset
|
347 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
|
348 case SAD_SAMPLE_S24: |
4239
51291ce4eb54
some endianness-related changes, corrected error handling
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4238
diff
changeset
|
349 case SAD_SAMPLE_S24_LE: |
51291ce4eb54
some endianness-related changes, corrected error handling
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4238
diff
changeset
|
350 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
|
351 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
|
352 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
|
353 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
|
354 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
|
355 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
|
356 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
|
357 case SAD_SAMPLE_U32: |
63eb5966f105
prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4240
diff
changeset
|
358 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
|
359 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
|
360 case SAD_SAMPLE_FLOAT: break; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
361 default: |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
362 free(priv); |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
363 *error = SAD_ERROR_INCORRECT_OUTPUT_SAMPLEFORMAT; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
364 return NULL; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
365 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
366 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
367 switch(inbuf_format->sample_format){ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
368 case SAD_SAMPLE_S8: |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
369 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
|
370 case SAD_SAMPLE_S16: |
4234 | 371 case SAD_SAMPLE_S16_LE: |
4238
75ea2083e744
some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4237
diff
changeset
|
372 case SAD_SAMPLE_S16_BE: |
75ea2083e744
some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4237
diff
changeset
|
373 case SAD_SAMPLE_U16: |
75ea2083e744
some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4237
diff
changeset
|
374 case SAD_SAMPLE_U16_LE: |
75ea2083e744
some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4237
diff
changeset
|
375 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
|
376 case SAD_SAMPLE_S24: |
4239
51291ce4eb54
some endianness-related changes, corrected error handling
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4238
diff
changeset
|
377 case SAD_SAMPLE_S24_LE: |
51291ce4eb54
some endianness-related changes, corrected error handling
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4238
diff
changeset
|
378 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
|
379 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
|
380 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
|
381 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
|
382 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
|
383 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
|
384 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
|
385 case SAD_SAMPLE_U32: |
63eb5966f105
prevented clipping for FMT_*32_*; some endianness-related changes
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4240
diff
changeset
|
386 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
|
387 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
|
388 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
|
389 case SAD_SAMPLE_FLOAT: break; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
390 default: |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
391 free(priv); |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
392 *error = SAD_ERROR_INCORRECT_INPUT_SAMPLEFORMAT; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
393 return NULL; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
394 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
395 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
396 *error = SAD_ERROR_OK; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
397 return (SAD_dither_t*)priv; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
398 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
399 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
400 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
|
401 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
|
402 free(state); |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
403 return SAD_ERROR_OK; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
404 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
405 |
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 * 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
|
408 * 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
|
409 * accordingly |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
410 * |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
411 * 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
|
412 */ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
413 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
414 #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
|
415 #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
|
416 if (o == SAD_CHORDER_INTERLEAVED) { \ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
417 ((float*)b)[i*n+c] = s; \ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
418 } else { \ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
419 ((float**)b)[c][i] = s; \ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
420 } \ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
421 } |
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 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
|
424 { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
425 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
|
426 int i, ch; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
427 int channels = priv->channels; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
428 int inbits = priv->input_bits; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
429 int outbits = priv->output_bits; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
430 int fracbits = priv->input_fracbits; |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
431 double scale = priv->scale * priv->rg_scale; |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
432 double oldscale = scale; |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
433 int dither = priv->dither; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
434 int hardlimit = priv->hardlimit; |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
435 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
|
436 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
|
437 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
|
438 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
439 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
|
440 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
|
441 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
442 #ifdef DEEP_DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
443 printf("f: SAD_process_buffer\n"); |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
444 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
445 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
446 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
|
447 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
|
448 /* process buffer */ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
449 for(i=0; i<frames; i++) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
450 for(ch=0; ch<channels; ch++) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
451 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
|
452 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
|
453 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
|
454 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
455 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
456 } else { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
457 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
|
458 /* process buffer */ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
459 for(i=0; i<frames; i++) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
460 for(ch=0; ch<channels; ch++) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
461 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
|
462 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
|
463 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
|
464 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
465 } |
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 } else { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
468 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
|
469 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
|
470 /* process buffer */ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
471 for(i=0; i<frames; i++) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
472 for(ch=0; ch<channels; ch++) { |
4233
74c6f3d3cf1d
it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4232
diff
changeset
|
473 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
|
474 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
|
475 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
|
476 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
477 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
478 } else { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
479 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
|
480 /* process buffer */ |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
481 for(i=0; i<frames; i++) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
482 for(ch=0; ch<channels; ch++){ |
4233
74c6f3d3cf1d
it buids successfully :)
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4232
diff
changeset
|
483 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
|
484 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
|
485 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
|
486 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
487 } |
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 |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
491 /* recalc scale factor */ |
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
492 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
|
493 |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
494 return SAD_ERROR_OK; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
495 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
496 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
497 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
|
498 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
|
499 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
|
500 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
501 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
|
502 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
503 if(!rg_info->present) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
504 priv->rg_scale = 1.0; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
505 priv->hardlimit = FALSE; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
506 return SAD_ERROR_OK; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
507 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
508 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
509 switch(mode->mode) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
510 case SAD_RG_ALBUM: |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
511 scale = db2scale(rg_info->album_gain); |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
512 peak = rg_info->album_peak; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
513 if (peak == 0.0) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
514 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
|
515 peak = rg_info->track_peak; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
516 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
|
517 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
518 break; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
519 case SAD_RG_TRACK: |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
520 scale = db2scale(rg_info->track_gain); |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
521 peak = rg_info->track_peak; |
4237
8f6956130372
initial Replay Gain support
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4235
diff
changeset
|
522 if (peak == 0.0) { |
8f6956130372
initial Replay Gain support
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4235
diff
changeset
|
523 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
|
524 peak = rg_info->album_peak; |
8f6956130372
initial Replay Gain support
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4235
diff
changeset
|
525 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
|
526 } |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
527 break; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
528 case SAD_RG_NONE: |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
529 scale = -1.0; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
530 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
531 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
532 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
|
533 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
|
534 scale *= db2scale(mode->preamp); |
4232
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
535 // Clipping prevention |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
536 if(mode->clipping_prevention) { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
537 #ifdef DEBUG |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
538 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
|
539 #endif |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
540 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
|
541 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
|
542 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
543 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
|
544 priv->rg_scale = scale; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
545 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
|
546 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
|
547 } else { |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
548 priv->rg_scale = 1.0; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
549 priv->hardlimit = FALSE; |
4256
b0ca963fd965
adaptive scaler added, disabled hard limiter
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
4241
diff
changeset
|
550 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
|
551 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
552 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
553 return SAD_ERROR_OK; |
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 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
556 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
|
557 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
|
558 priv->scale = scale; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
559 return SAD_ERROR_OK; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
560 } |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
561 |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
562 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
|
563 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
|
564 priv->dither = dither; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
565 return SAD_ERROR_OK; |
704607c1f858
1st attempt to integrate dithering and RG engine
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
566 } |
4234 | 567 |
568 void SAD_dither_init_rand(uint32_t seed) { | |
569 noicegen_init_rand(seed); | |
570 } |