1 /* plugin_common - Routines common to several plugins
2 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Josh Coalson
4 * dithering routine derived from (other GPLed source):
5 * mad - MPEG audio decoder
6 * Copyright (C) 2000-2001 Robert Leslie
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.
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.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "FLAC/assert.h"
33 #define max(a,b) ((a)>(b)?(a):(b))
40 /* 32-bit pseudo-random number generator
42 * @@@ According to Miroslav, this one is poor quality, the one from the
43 * @@@ original replaygain code is much better
45 static FLaC__INLINE FLAC__uint32
prng(FLAC__uint32 state
)
47 return (state
* 0x0019660dL
+ 0x3c6ef35fL
) & 0xffffffffL
;
50 /* dither routine derived from MAD winamp plugin */
57 static 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 FLAC__int32 output
, mask
, random
;
62 FLAC__ASSERT(source_bps
< 32);
63 FLAC__ASSERT(target_bps
<= 24);
64 FLAC__ASSERT(target_bps
<= source_bps
);
67 sample
+= dither
->error
[0] - dither
->error
[1] + dither
->error
[2];
69 dither
->error
[2] = dither
->error
[1];
70 dither
->error
[1] = dither
->error
[0] / 2;
73 output
= sample
+ (1L << (source_bps
- target_bps
- 1));
75 scalebits
= source_bps
- target_bps
;
76 mask
= (1L << scalebits
) - 1;
79 random
= (FLAC__int32
)prng(dither
->random
);
80 output
+= (random
& mask
) - (dither
->random
& mask
);
82 dither
->random
= random
;
91 else if(output
< MIN
) {
102 dither
->error
[0] = sample
- output
;
105 return output
>> scalebits
;
108 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
)
110 static dither_state dither
[FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS
];
111 FLAC__byte
* const start
= data
;
113 const FLAC__int32
*input_
;
114 unsigned samples
, channel
;
115 const unsigned bytes_per_sample
= target_bps
/ 8;
116 const unsigned incr
= bytes_per_sample
* channels
;
118 FLAC__ASSERT(channels
> 0 && channels
<= FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS
);
119 FLAC__ASSERT(source_bps
< 32);
120 FLAC__ASSERT(target_bps
<= 24);
121 FLAC__ASSERT(target_bps
<= source_bps
);
122 FLAC__ASSERT((source_bps
& 7) == 0);
123 FLAC__ASSERT((target_bps
& 7) == 0);
125 if(source_bps
!= target_bps
) {
126 const FLAC__int32 MIN
= -(1L << (source_bps
- 1));
127 const FLAC__int32 MAX
= ~MIN
; /*(1L << (source_bps-1)) - 1 */
129 for(channel
= 0; channel
< channels
; channel
++) {
131 samples
= wide_samples
;
132 data
= start
+ bytes_per_sample
* channel
;
133 input_
= input
[channel
];
136 sample
= linear_dither(source_bps
, target_bps
, *input_
++, &dither
[channel
], MIN
, MAX
);
140 data
[0] = sample
^ 0x80;
143 data
[0] = (FLAC__byte
)(sample
>> 8);
144 data
[1] = (FLAC__byte
)sample
;
147 data
[0] = (FLAC__byte
)(sample
>> 16);
148 data
[1] = (FLAC__byte
)(sample
>> 8);
149 data
[2] = (FLAC__byte
)sample
;
158 for(channel
= 0; channel
< channels
; channel
++) {
159 samples
= wide_samples
;
160 data
= start
+ bytes_per_sample
* channel
;
161 input_
= input
[channel
];
168 data
[0] = sample
^ 0x80;
171 data
[0] = (FLAC__byte
)(sample
>> 8);
172 data
[1] = (FLAC__byte
)sample
;
175 data
[0] = (FLAC__byte
)(sample
>> 16);
176 data
[1] = (FLAC__byte
)(sample
>> 8);
177 data
[2] = (FLAC__byte
)sample
;
186 return wide_samples
* channels
* (target_bps
/8);
189 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
)
191 static dither_state dither
[FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS
];
192 FLAC__byte
* const start
= data
;
194 const FLAC__int32
*input_
;
195 unsigned samples
, channel
;
196 const unsigned bytes_per_sample
= target_bps
/ 8;
197 const unsigned incr
= bytes_per_sample
* channels
;
199 FLAC__ASSERT(channels
> 0 && channels
<= FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS
);
200 FLAC__ASSERT(source_bps
< 32);
201 FLAC__ASSERT(target_bps
<= 24);
202 FLAC__ASSERT(target_bps
<= source_bps
);
203 FLAC__ASSERT((source_bps
& 7) == 0);
204 FLAC__ASSERT((target_bps
& 7) == 0);
206 if(source_bps
!= target_bps
) {
207 const FLAC__int32 MIN
= -(1L << (source_bps
- 1));
208 const FLAC__int32 MAX
= ~MIN
; /*(1L << (source_bps-1)) - 1 */
210 for(channel
= 0; channel
< channels
; channel
++) {
212 samples
= wide_samples
;
213 data
= start
+ bytes_per_sample
* channel
;
214 input_
= input
[channel
];
217 sample
= linear_dither(source_bps
, target_bps
, *input_
++, &dither
[channel
], MIN
, MAX
);
221 data
[0] = sample
^ 0x80;
224 data
[2] = (FLAC__byte
)(sample
>> 16);
227 data
[1] = (FLAC__byte
)(sample
>> 8);
228 data
[0] = (FLAC__byte
)sample
;
236 for(channel
= 0; channel
< channels
; channel
++) {
237 samples
= wide_samples
;
238 data
= start
+ bytes_per_sample
* channel
;
239 input_
= input
[channel
];
246 data
[0] = sample
^ 0x80;
249 data
[2] = (FLAC__byte
)(sample
>> 16);
252 data
[1] = (FLAC__byte
)(sample
>> 8);
253 data
[0] = (FLAC__byte
)sample
;
261 return wide_samples
* channels
* (target_bps
/8);