1/* plugin_common - Routines common to several plugins
2 * Copyright (C) 2002,2003,2004,2005,2006,2007  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#ifndef FLaC__INLINE
36#define FLaC__INLINE
37#endif
38
39
40/* 32-bit pseudo-random number generator
41 *
42 * @@@ According to Miroslav, this one is poor quality, the one from the
43 * @@@ original replaygain code is much better
44 */
45static FLaC__INLINE FLAC__uint32 prng(FLAC__uint32 state)
46{
47	return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
48}
49
50/* dither routine derived from MAD winamp plugin */
51
52typedef struct {
53	FLAC__int32 error[3];
54	FLAC__int32 random;
55} dither_state;
56
57static 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)
58{
59	unsigned scalebits;
60	FLAC__int32 output, mask, random;
61
62	FLAC__ASSERT(source_bps < 32);
63	FLAC__ASSERT(target_bps <= 24);
64	FLAC__ASSERT(target_bps <= source_bps);
65
66	/* noise shape */
67	sample += dither->error[0] - dither->error[1] + dither->error[2];
68
69	dither->error[2] = dither->error[1];
70	dither->error[1] = dither->error[0] / 2;
71
72	/* bias */
73	output = sample + (1L << (source_bps - target_bps - 1));
74
75	scalebits = source_bps - target_bps;
76	mask = (1L << scalebits) - 1;
77
78	/* dither */
79	random = (FLAC__int32)prng(dither->random);
80	output += (random & mask) - (dither->random & mask);
81
82	dither->random = random;
83
84	/* clip */
85	if(output > MAX) {
86		output = MAX;
87
88		if(sample > MAX)
89			sample = MAX;
90	}
91	else if(output < MIN) {
92		output = MIN;
93
94		if(sample < MIN)
95			sample = MIN;
96	}
97
98	/* quantize */
99	output &= ~mask;
100
101	/* error feedback */
102	dither->error[0] = sample - output;
103
104	/* scale */
105	return output >> scalebits;
106}
107
108size_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)
109{
110	static dither_state dither[FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS];
111	FLAC__byte * const start = data;
112	FLAC__int32 sample;
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;
117
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);
124
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 */
128
129		for(channel = 0; channel < channels; channel++) {
130
131			samples = wide_samples;
132			data = start + bytes_per_sample * channel;
133			input_ = input[channel];
134
135			while(samples--) {
136				sample = linear_dither(source_bps, target_bps, *input_++, &dither[channel], MIN, MAX);
137
138				switch(target_bps) {
139					case 8:
140						data[0] = sample ^ 0x80;
141						break;
142					case 16:
143						data[0] = (FLAC__byte)(sample >> 8);
144						data[1] = (FLAC__byte)sample;
145						break;
146					case 24:
147						data[0] = (FLAC__byte)(sample >> 16);
148						data[1] = (FLAC__byte)(sample >> 8);
149						data[2] = (FLAC__byte)sample;
150						break;
151				}
152
153				data += incr;
154			}
155		}
156	}
157	else {
158		for(channel = 0; channel < channels; channel++) {
159			samples = wide_samples;
160			data = start + bytes_per_sample * channel;
161			input_ = input[channel];
162
163			while(samples--) {
164				sample = *input_++;
165
166				switch(target_bps) {
167					case 8:
168						data[0] = sample ^ 0x80;
169						break;
170					case 16:
171						data[0] = (FLAC__byte)(sample >> 8);
172						data[1] = (FLAC__byte)sample;
173						break;
174					case 24:
175						data[0] = (FLAC__byte)(sample >> 16);
176						data[1] = (FLAC__byte)(sample >> 8);
177						data[2] = (FLAC__byte)sample;
178						break;
179				}
180
181				data += incr;
182			}
183		}
184	}
185
186	return wide_samples * channels * (target_bps/8);
187}
188
189size_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)
190{
191	static dither_state dither[FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS];
192	FLAC__byte * const start = data;
193	FLAC__int32 sample;
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;
198
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);
205
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 */
209
210		for(channel = 0; channel < channels; channel++) {
211
212			samples = wide_samples;
213			data = start + bytes_per_sample * channel;
214			input_ = input[channel];
215
216			while(samples--) {
217				sample = linear_dither(source_bps, target_bps, *input_++, &dither[channel], MIN, MAX);
218
219				switch(target_bps) {
220					case 8:
221						data[0] = sample ^ 0x80;
222						break;
223					case 24:
224						data[2] = (FLAC__byte)(sample >> 16);
225						/* fall through */
226					case 16:
227						data[1] = (FLAC__byte)(sample >> 8);
228						data[0] = (FLAC__byte)sample;
229				}
230
231				data += incr;
232			}
233		}
234	}
235	else {
236		for(channel = 0; channel < channels; channel++) {
237			samples = wide_samples;
238			data = start + bytes_per_sample * channel;
239			input_ = input[channel];
240
241			while(samples--) {
242				sample = *input_++;
243
244				switch(target_bps) {
245					case 8:
246						data[0] = sample ^ 0x80;
247						break;
248					case 24:
249						data[2] = (FLAC__byte)(sample >> 16);
250						/* fall through */
251					case 16:
252						data[1] = (FLAC__byte)(sample >> 8);
253						data[0] = (FLAC__byte)sample;
254				}
255
256				data += incr;
257			}
258		}
259	}
260
261	return wide_samples * channels * (target_bps/8);
262}
263