configure.ac: Move OggVorbis Encoder to Encoder Plugins.
[mpd-mk.git] / src / pcm_dither.c
blob03388f0e04752c66cc1731f15d608c88709e888e
1 /*
2 * Copyright (C) 2003-2010 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "config.h"
21 #include "pcm_dither.h"
22 #include "pcm_prng.h"
24 static int16_t
25 pcm_dither_sample_24_to_16(int32_t sample, struct pcm_dither *dither)
27 int32_t output, rnd;
29 enum {
30 from_bits = 24,
31 to_bits = 16,
32 scale_bits = from_bits - to_bits,
33 round = 1 << (scale_bits - 1),
34 mask = (1 << scale_bits) - 1,
35 ONE = 1 << (from_bits - 1),
36 MIN = -ONE,
37 MAX = ONE - 1
40 sample += dither->error[0] - dither->error[1] + dither->error[2];
42 dither->error[2] = dither->error[1];
43 dither->error[1] = dither->error[0] / 2;
45 /* round */
46 output = sample + round;
48 rnd = pcm_prng(dither->random);
49 output += (rnd & mask) - (dither->random & mask);
51 dither->random = rnd;
53 /* clip */
54 if (output > MAX) {
55 output = MAX;
57 if (sample > MAX)
58 sample = MAX;
59 } else if (output < MIN) {
60 output = MIN;
62 if (sample < MIN)
63 sample = MIN;
66 output &= ~mask;
68 dither->error[0] = sample - output;
70 return (int16_t)(output >> scale_bits);
73 void
74 pcm_dither_24_to_16(struct pcm_dither *dither,
75 int16_t *dest, const int32_t *src,
76 unsigned num_samples)
78 while (num_samples-- > 0)
79 *dest++ = pcm_dither_sample_24_to_16(*src++, dither);
82 static int16_t
83 pcm_dither_sample_32_to_16(int32_t sample, struct pcm_dither *dither)
85 return pcm_dither_sample_24_to_16(sample >> 8, dither);
88 void
89 pcm_dither_32_to_16(struct pcm_dither *dither,
90 int16_t *dest, const int32_t *src,
91 unsigned num_samples)
93 while (num_samples-- > 0)
94 *dest++ = pcm_dither_sample_32_to_16(*src++, dither);