1 /* the Music Player Daemon (MPD)
2 * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
3 * This project's homepage is: 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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "pcm_utils.h"
21 #include "mpd_types.h"
30 void pcm_volumeChange(char *buffer, int bufferSize, AudioFormat * format,
34 mpd_sint8 *buffer8 = (mpd_sint8 *) buffer;
35 mpd_sint16 *buffer16 = (mpd_sint16 *) buffer;
41 memset(buffer, 0, bufferSize);
45 switch (format->bits) {
47 while (bufferSize > 0) {
50 temp32 += rand() & 511;
51 temp32 -= rand() & 511;
54 *buffer16 = temp32 > 32767 ? 32767 :
55 (temp32 < -32768 ? -32768 : temp32);
61 while (bufferSize > 0) {
64 temp32 += rand() & 511;
65 temp32 -= rand() & 511;
68 *buffer8 = temp32 > 127 ? 127 :
69 (temp32 < -128 ? -128 : temp32);
75 FATAL("%i bits not supported by pcm_volumeChange!\n",
80 static void pcm_add(char *buffer1, char *buffer2, size_t bufferSize1,
81 size_t bufferSize2, int vol1, int vol2,
85 mpd_sint8 *buffer8_1 = (mpd_sint8 *) buffer1;
86 mpd_sint8 *buffer8_2 = (mpd_sint8 *) buffer2;
87 mpd_sint16 *buffer16_1 = (mpd_sint16 *) buffer1;
88 mpd_sint16 *buffer16_2 = (mpd_sint16 *) buffer2;
90 switch (format->bits) {
92 while (bufferSize1 > 0 && bufferSize2 > 0) {
94 (vol1 * (*buffer16_1) +
95 vol2 * (*buffer16_2));
96 temp32 += rand() & 511;
97 temp32 -= rand() & 511;
101 temp32 > 32767 ? 32767 : (temp32 <
102 -32768 ? -32768 : temp32);
109 memcpy(buffer16_1, buffer16_2, bufferSize2);
112 while (bufferSize1 > 0 && bufferSize2 > 0) {
114 (vol1 * (*buffer8_1) + vol2 * (*buffer8_2));
115 temp32 += rand() & 511;
116 temp32 -= rand() & 511;
120 temp32 > 127 ? 127 : (temp32 <
121 -128 ? -128 : temp32);
128 memcpy(buffer8_1, buffer8_2, bufferSize2);
131 FATAL("%i bits not supported by pcm_add!\n", format->bits);
135 void pcm_mix(char *buffer1, char *buffer2, size_t bufferSize1,
136 size_t bufferSize2, AudioFormat * format, float portion1)
139 float s = sin(M_PI_2 * portion1);
142 vol1 = s * 1000 + 0.5;
143 vol1 = vol1 > 1000 ? 1000 : (vol1 < 0 ? 0 : vol1);
145 pcm_add(buffer1, buffer2, bufferSize1, bufferSize2, vol1, 1000 - vol1,
149 #ifdef HAVE_LIBSAMPLERATE
150 static int pcm_getSampleRateConverter(void)
152 const char *conf = getConfigParamValue(CONF_SAMPLERATE_CONVERTER);
158 convalgo = SRC_SINC_FASTEST;
162 convalgo = strtol(conf, &test, 10);
163 if (*test == '\0' && src_get_name(convalgo))
167 for (convalgo = 0 ; ; convalgo++) {
168 test = (char *)src_get_name(convalgo);
170 convalgo = SRC_SINC_FASTEST;
173 if (strncasecmp(test, conf, len) == 0)
177 ERROR("unknown samplerate converter \"%s\"\n", conf);
179 DEBUG("selecting samplerate converter \"%s\"\n",
180 src_get_name(convalgo));
186 #ifdef HAVE_LIBSAMPLERATE
187 static size_t pcm_convertSampleRate(mpd_sint8 channels, mpd_uint32 inSampleRate,
188 char *inBuffer, size_t inSize,
189 mpd_uint32 outSampleRate, char *outBuffer,
190 size_t outSize, ConvState *convState)
192 static int convalgo = -1;
193 SRC_DATA *data = &convState->data;
199 convalgo = pcm_getSampleRateConverter();
201 /* (re)set the state/ratio if the in or out format changed */
202 if ((channels != convState->lastChannels) ||
203 (inSampleRate != convState->lastInSampleRate) ||
204 (outSampleRate != convState->lastOutSampleRate)) {
205 convState->error = 0;
206 convState->lastChannels = channels;
207 convState->lastInSampleRate = inSampleRate;
208 convState->lastOutSampleRate = outSampleRate;
210 if (convState->state)
211 convState->state = src_delete(convState->state);
213 convState->state = src_new(convalgo, channels, &error);
214 if (!convState->state) {
215 ERROR("cannot create new libsamplerate state: %s\n",
216 src_strerror(error));
217 convState->error = 1;
221 data->src_ratio = (double)outSampleRate / (double)inSampleRate;
222 DEBUG("setting samplerate conversion ratio to %.2lf\n",
224 src_set_ratio(convState->state, data->src_ratio);
227 /* there was an error previously, and nothing has changed */
228 if (convState->error)
231 data->input_frames = inSize / 2 / channels;
232 dataInSize = data->input_frames * sizeof(float) * channels;
233 if (dataInSize > convState->dataInSize) {
234 convState->dataInSize = dataInSize;
235 data->data_in = xrealloc(data->data_in, dataInSize);
238 data->output_frames = outSize / 2 / channels;
239 dataOutSize = data->output_frames * sizeof(float) * channels;
240 if (dataOutSize > convState->dataOutSize) {
241 convState->dataOutSize = dataOutSize;
242 data->data_out = xrealloc(data->data_out, dataOutSize);
245 src_short_to_float_array((short *)inBuffer, data->data_in,
246 data->input_frames * channels);
248 error = src_process(convState->state, data);
250 ERROR("error processing samples with libsamplerate: %s\n",
251 src_strerror(error));
252 convState->error = 1;
256 src_float_to_short_array(data->data_out, (short *)outBuffer,
257 data->output_frames_gen * channels);
259 return data->output_frames_gen * 2 * channels;
261 #else /* !HAVE_LIBSAMPLERATE */
262 /* resampling code blatantly ripped from ESD */
263 static size_t pcm_convertSampleRate(mpd_sint8 channels, mpd_uint32 inSampleRate,
264 char *inBuffer, size_t inSize,
265 mpd_uint32 outSampleRate, char *outBuffer,
266 size_t outSize, ConvState *convState)
268 mpd_uint32 rd_dat = 0;
269 mpd_uint32 wr_dat = 0;
270 mpd_sint16 *in = (mpd_sint16 *)inBuffer;
271 mpd_sint16 *out = (mpd_sint16 *)outBuffer;
272 mpd_uint32 nlen = outSize / 2;
273 mpd_sint16 lsample, rsample;
277 while (wr_dat < nlen) {
278 rd_dat = wr_dat * inSampleRate / outSampleRate;
280 lsample = in[rd_dat++];
282 out[wr_dat++] = lsample;
286 while (wr_dat < nlen) {
287 rd_dat = wr_dat * inSampleRate / outSampleRate;
290 lsample = in[rd_dat++];
291 rsample = in[rd_dat++];
293 out[wr_dat++] = lsample;
294 out[wr_dat++] = rsample;
301 #endif /* !HAVE_LIBSAMPLERATE */
303 static char *pcm_convertChannels(mpd_sint8 channels, char *inBuffer,
304 size_t inSize, size_t *outSize)
308 char *outBuffer = NULL;;
314 /* convert from 1 -> 2 channels */
316 *outSize = (inSize >> 1) << 2;
317 if (*outSize > len) {
319 buf = xrealloc(buf, len);
323 inSamples = inSize >> 1;
324 in = (mpd_sint16 *)inBuffer;
325 out = (mpd_sint16 *)outBuffer;
326 for (i = 0; i < inSamples; i++) {
332 /* convert from 2 -> 1 channels */
334 *outSize = inSize >> 1;
335 if (*outSize > len) {
337 buf = xrealloc(buf, len);
341 inSamples = inSize >> 2;
342 in = (mpd_sint16 *)inBuffer;
343 out = (mpd_sint16 *)outBuffer;
344 for (i = 0; i < inSamples; i++) {
346 *out++ += (*in++) / 2;
351 ERROR("only 1 or 2 channels are supported for conversion!\n");
357 static char *pcm_convertTo16bit(mpd_sint8 bits, char *inBuffer, size_t inSize,
362 char *outBuffer = NULL;
369 *outSize = inSize << 1;
370 if (*outSize > len) {
372 buf = xrealloc(buf, len);
376 in = (mpd_sint8 *)inBuffer;
377 out = (mpd_sint16 *)outBuffer;
378 for (i = 0; i < inSize; i++)
379 *out++ = (*in++) << 8;
384 outBuffer = inBuffer;
387 /* put dithering code from mp3_decode here */
389 ERROR("only 8 or 16 bits are supported for conversion!\n");
395 /* outFormat bits must be 16 and channels must be 1 or 2! */
396 size_t pcm_convertAudioFormat(AudioFormat * inFormat, char *inBuffer,
397 size_t inSize, AudioFormat * outFormat,
398 char *outBuffer, ConvState *convState)
402 size_t outSize = pcm_sizeOfConvBuffer(inFormat, inSize, outFormat);
404 assert(outFormat->bits == 16);
405 assert(outFormat->channels == 2 || outFormat->channels == 1);
407 /* everything else supports 16 bit only, so convert to that first */
408 buf = pcm_convertTo16bit(inFormat->bits, inBuffer, inSize, &len);
412 if (inFormat->channels != outFormat->channels) {
413 buf = pcm_convertChannels(inFormat->channels, buf, len, &len);
418 if (inFormat->sampleRate == outFormat->sampleRate) {
419 assert(outSize >= len);
420 memcpy(outBuffer, buf, len);
422 len = pcm_convertSampleRate(outFormat->channels,
423 inFormat->sampleRate, buf, len,
424 outFormat->sampleRate, outBuffer,
433 size_t pcm_sizeOfConvBuffer(AudioFormat * inFormat, size_t inSize,
434 AudioFormat * outFormat)
436 const double ratio = (double)outFormat->sampleRate /
437 (double)inFormat->sampleRate;
438 const int shift = 2 * outFormat->channels;
439 size_t outSize = inSize;
441 switch (inFormat->bits) {
448 FATAL("only 8 or 16 bits are supported for conversion!\n");
451 if (inFormat->channels != outFormat->channels) {
452 switch (inFormat->channels) {
454 outSize = (outSize >> 1) << 2;
460 FATAL("only 1 or 2 channels are supported "
461 "for conversion!\n");
466 outSize = floor(0.5 + (double)outSize * ratio);