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