complete largefile support
[flac.git] / src / plugin_common / dither.c
1 /* plugin_common - Routines common to several plugins
2  * Copyright (C) 2002,2003,2004,2005,2006  Josh Coalson
3  *
4  * dithering routine derived from (other GPLed source):
5  * mad - MPEG audio decoder
6  * Copyright (C) 2000-2001 Robert Leslie
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  */
22
23 #if HAVE_CONFIG_H
24 #  include <config.h>
25 #endif
26
27 #include "dither.h"
28 #include "FLAC/assert.h"
29
30 #ifdef max
31 #undef max
32 #endif
33 #define max(a,b) ((a)>(b)?(a):(b))
34
35
36 #if defined _MSC_VER
37 #define FLAC__INLINE __inline
38 #else
39 #define FLAC__INLINE
40 #endif
41
42 /* 32-bit pseudo-random number generator
43  *
44  * @@@ According to Miroslav, this one is poor quality, the one from the
45  * @@@ original replaygain code is much better
46  */
47 static FLAC__INLINE FLAC__uint32 prng(FLAC__uint32 state)
48 {
49         return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
50 }
51
52 /* dither routine derived from MAD winamp plugin */
53
54 typedef struct {
55         FLAC__int32 error[3];
56         FLAC__int32 random;
57 } dither_state;
58
59 static FLAC__INLINE FLAC__int32 linear_dither(unsigned source_bps, unsigned target_bps, FLAC__int32 sample, dither_state *dither, const FLAC__int32 MIN, const FLAC__int32 MAX)
60 {
61         unsigned scalebits;
62         FLAC__int32 output, mask, random;
63
64         FLAC__ASSERT(source_bps < 32);
65         FLAC__ASSERT(target_bps <= 24);
66         FLAC__ASSERT(target_bps <= source_bps);
67
68         /* noise shape */
69         sample += dither->error[0] - dither->error[1] + dither->error[2];
70
71         dither->error[2] = dither->error[1];
72         dither->error[1] = dither->error[0] / 2;
73
74         /* bias */
75         output = sample + (1L << (source_bps - target_bps - 1));
76
77         scalebits = source_bps - target_bps;
78         mask = (1L << scalebits) - 1;
79
80         /* dither */
81         random = (FLAC__int32)prng(dither->random);
82         output += (random & mask) - (dither->random & mask);
83
84         dither->random = random;
85
86         /* clip */
87         if(output > MAX) {
88                 output = MAX;
89
90                 if(sample > MAX)
91                         sample = MAX;
92         }
93         else if(output < MIN) {
94                 output = MIN;
95
96                 if(sample < MIN)
97                         sample = MIN;
98         }
99
100         /* quantize */
101         output &= ~mask;
102
103         /* error feedback */
104         dither->error[0] = sample - output;
105
106         /* scale */
107         return output >> scalebits;
108 }
109
110 size_t FLAC__plugin_common__pack_pcm_signed_big_endian(FLAC__byte *data, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, unsigned source_bps, unsigned target_bps)
111 {
112         static dither_state dither[FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS];
113         FLAC__byte * const start = data;
114         FLAC__int32 sample;
115         const FLAC__int32 *input_;
116         unsigned samples, channel;
117         const unsigned bytes_per_sample = target_bps / 8;
118         const unsigned incr = bytes_per_sample * channels;
119
120         FLAC__ASSERT(channels > 0 && channels <= FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS);
121         FLAC__ASSERT(source_bps < 32);
122         FLAC__ASSERT(target_bps <= 24);
123         FLAC__ASSERT(target_bps <= source_bps);
124         FLAC__ASSERT((source_bps & 7) == 0);
125         FLAC__ASSERT((target_bps & 7) == 0);
126
127         if(source_bps != target_bps) {
128                 const FLAC__int32 MIN = -(1L << (source_bps - 1));
129                 const FLAC__int32 MAX = ~MIN; /*(1L << (source_bps-1)) - 1 */
130
131                 for(channel = 0; channel < channels; channel++) {
132                         
133                         samples = wide_samples;
134                         data = start + bytes_per_sample * channel;
135                         input_ = input[channel];
136
137                         while(samples--) {
138                                 sample = linear_dither(source_bps, target_bps, *input_++, &dither[channel], MIN, MAX);
139
140                                 switch(target_bps) {
141                                         case 8:
142                                                 data[0] = sample ^ 0x80;
143                                                 break;
144                                         case 16:
145                                                 data[0] = (FLAC__byte)(sample >> 8);
146                                                 data[1] = (FLAC__byte)sample;
147                                                 break;
148                                         case 24:
149                                                 data[0] = (FLAC__byte)(sample >> 16);
150                                                 data[1] = (FLAC__byte)(sample >> 8);
151                                                 data[2] = (FLAC__byte)sample;
152                                                 break;
153                                 }
154
155                                 data += incr;
156                         }
157                 }
158         }
159         else {
160                 for(channel = 0; channel < channels; channel++) {
161                         samples = wide_samples;
162                         data = start + bytes_per_sample * channel;
163                         input_ = input[channel];
164
165                         while(samples--) {
166                                 sample = *input_++;
167
168                                 switch(target_bps) {
169                                         case 8:
170                                                 data[0] = sample ^ 0x80;
171                                                 break;
172                                         case 16:
173                                                 data[0] = (FLAC__byte)(sample >> 8);
174                                                 data[1] = (FLAC__byte)sample;
175                                                 break;
176                                         case 24:
177                                                 data[0] = (FLAC__byte)(sample >> 16);
178                                                 data[1] = (FLAC__byte)(sample >> 8);
179                                                 data[2] = (FLAC__byte)sample;
180                                                 break;
181                                 }
182
183                                 data += incr;
184                         }
185                 }
186         }
187
188         return wide_samples * channels * (target_bps/8);
189 }
190
191 size_t FLAC__plugin_common__pack_pcm_signed_little_endian(FLAC__byte *data, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, unsigned source_bps, unsigned target_bps)
192 {
193         static dither_state dither[FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS];
194         FLAC__byte * const start = data;
195         FLAC__int32 sample;
196         const FLAC__int32 *input_;
197         unsigned samples, channel;
198         const unsigned bytes_per_sample = target_bps / 8;
199         const unsigned incr = bytes_per_sample * channels;
200
201         FLAC__ASSERT(channels > 0 && channels <= FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS);
202         FLAC__ASSERT(source_bps < 32);
203         FLAC__ASSERT(target_bps <= 24);
204         FLAC__ASSERT(target_bps <= source_bps);
205         FLAC__ASSERT((source_bps & 7) == 0);
206         FLAC__ASSERT((target_bps & 7) == 0);
207
208         if(source_bps != target_bps) {
209                 const FLAC__int32 MIN = -(1L << (source_bps - 1));
210                 const FLAC__int32 MAX = ~MIN; /*(1L << (source_bps-1)) - 1 */
211
212                 for(channel = 0; channel < channels; channel++) {
213                         
214                         samples = wide_samples;
215                         data = start + bytes_per_sample * channel;
216                         input_ = input[channel];
217
218                         while(samples--) {
219                                 sample = linear_dither(source_bps, target_bps, *input_++, &dither[channel], MIN, MAX);
220
221                                 switch(target_bps) {
222                                         case 8:
223                                                 data[0] = sample ^ 0x80;
224                                                 break;
225                                         case 24:
226                                                 data[2] = (FLAC__byte)(sample >> 16);
227                                                 /* fall through */
228                                         case 16:
229                                                 data[1] = (FLAC__byte)(sample >> 8);
230                                                 data[0] = (FLAC__byte)sample;
231                                 }
232
233                                 data += incr;
234                         }
235                 }
236         }
237         else {
238                 for(channel = 0; channel < channels; channel++) {
239                         samples = wide_samples;
240                         data = start + bytes_per_sample * channel;
241                         input_ = input[channel];
242
243                         while(samples--) {
244                                 sample = *input_++;
245
246                                 switch(target_bps) {
247                                         case 8:
248                                                 data[0] = sample ^ 0x80;
249                                                 break;
250                                         case 24:
251                                                 data[2] = (FLAC__byte)(sample >> 16);
252                                                 /* fall through */
253                                         case 16:
254                                                 data[1] = (FLAC__byte)(sample >> 8);
255                                                 data[0] = (FLAC__byte)sample;
256                                 }
257
258                                 data += incr;
259                         }
260                 }
261         }
262
263         return wide_samples * channels * (target_bps/8);
264 }