Mercurial > audlegacy
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 |
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 |
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 | 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 | 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 | 569 |
570 void SAD_dither_init_rand(uint32_t seed) { | |
571 noicegen_init_rand(seed); | |
572 } |