Initial revision 6759
[qball-mpd.git] / src / .svn / text-base / pcm_utils.c.svn-base
blob53409562092af5e64b753215a1795331c6ec44f8
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
4  *
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.
9  *
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
17  */
19 #include "pcm_utils.h"
21 #include "mpd_types.h"
22 #include "log.h"
23 #include "utils.h"
24 #include "conf.h"
26 #include <string.h>
27 #include <math.h>
28 #include <assert.h>
30 void pcm_volumeChange(char *buffer, int bufferSize, AudioFormat * format,
31                       int volume)
33         mpd_sint32 temp32;
34         mpd_sint8 *buffer8 = (mpd_sint8 *) buffer;
35         mpd_sint16 *buffer16 = (mpd_sint16 *) buffer;
37         if (volume >= 1000)
38                 return;
40         if (volume <= 0) {
41                 memset(buffer, 0, bufferSize);
42                 return;
43         }
45         switch (format->bits) {
46         case 16:
47                 while (bufferSize > 0) {
48                         temp32 = *buffer16;
49                         temp32 *= volume;
50                         temp32 += rand() & 511;
51                         temp32 -= rand() & 511;
52                         temp32 += 500;
53                         temp32 /= 1000;
54                         *buffer16 = temp32 > 32767 ? 32767 :
55                             (temp32 < -32768 ? -32768 : temp32);
56                         buffer16++;
57                         bufferSize -= 2;
58                 }
59                 break;
60         case 8:
61                 while (bufferSize > 0) {
62                         temp32 = *buffer8;
63                         temp32 *= volume;
64                         temp32 += rand() & 511;
65                         temp32 -= rand() & 511;
66                         temp32 += 500;
67                         temp32 /= 1000;
68                         *buffer8 = temp32 > 127 ? 127 :
69                             (temp32 < -128 ? -128 : temp32);
70                         buffer8++;
71                         bufferSize--;
72                 }
73                 break;
74         default:
75                 FATAL("%i bits not supported by pcm_volumeChange!\n",
76                       format->bits);
77         }
80 static void pcm_add(char *buffer1, char *buffer2, size_t bufferSize1,
81                     size_t bufferSize2, int vol1, int vol2,
82                     AudioFormat * format)
84         mpd_sint32 temp32;
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) {
91         case 16:
92                 while (bufferSize1 > 0 && bufferSize2 > 0) {
93                         temp32 =
94                             (vol1 * (*buffer16_1) +
95                              vol2 * (*buffer16_2));
96                         temp32 += rand() & 511;
97                         temp32 -= rand() & 511;
98                         temp32 += 500;
99                         temp32 /= 1000;
100                         *buffer16_1 =
101                             temp32 > 32767 ? 32767 : (temp32 <
102                                                       -32768 ? -32768 : temp32);
103                         buffer16_1++;
104                         buffer16_2++;
105                         bufferSize1 -= 2;
106                         bufferSize2 -= 2;
107                 }
108                 if (bufferSize2 > 0)
109                         memcpy(buffer16_1, buffer16_2, bufferSize2);
110                 break;
111         case 8:
112                 while (bufferSize1 > 0 && bufferSize2 > 0) {
113                         temp32 =
114                             (vol1 * (*buffer8_1) + vol2 * (*buffer8_2));
115                         temp32 += rand() & 511;
116                         temp32 -= rand() & 511;
117                         temp32 += 500;
118                         temp32 /= 1000;
119                         *buffer8_1 =
120                             temp32 > 127 ? 127 : (temp32 <
121                                                   -128 ? -128 : temp32);
122                         buffer8_1++;
123                         buffer8_2++;
124                         bufferSize1--;
125                         bufferSize2--;
126                 }
127                 if (bufferSize2 > 0)
128                         memcpy(buffer8_1, buffer8_2, bufferSize2);
129                 break;
130         default:
131                 FATAL("%i bits not supported by pcm_add!\n", format->bits);
132         }
135 void pcm_mix(char *buffer1, char *buffer2, size_t bufferSize1,
136              size_t bufferSize2, AudioFormat * format, float portion1)
138         int vol1;
139         float s = sin(M_PI_2 * portion1);
140         s *= s;
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,
146                 format);
149 #ifdef HAVE_LIBSAMPLERATE
150 static int pcm_getSampleRateConverter(void)
152         const char *conf = getConfigParamValue(CONF_SAMPLERATE_CONVERTER);
153         long convalgo;
154         char *test;
155         size_t len;
157         if (!conf) {
158                 convalgo = SRC_SINC_FASTEST;
159                 goto out;
160         }
162         convalgo = strtol(conf, &test, 10);
163         if (*test == '\0' && src_get_name(convalgo))
164                 goto out;
166         len = strlen(conf);
167         for (convalgo = 0 ; ; convalgo++) {
168                 test = (char *)src_get_name(convalgo);
169                 if (!test) {
170                         convalgo = SRC_SINC_FASTEST;
171                         break;
172                 }
173                 if (strncasecmp(test, conf, len) == 0)
174                         goto out;
175         }
177         ERROR("unknown samplerate converter \"%s\"\n", conf);
178 out:
179         DEBUG("selecting samplerate converter \"%s\"\n",
180               src_get_name(convalgo));
182         return convalgo;
184 #endif
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;
194         size_t dataInSize;
195         size_t dataOutSize;
196         int error;
198         if (convalgo < 0)
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;
218                         return 0;
219                 }
220                 
221                 data->src_ratio = (double)outSampleRate / (double)inSampleRate;
222                 DEBUG("setting samplerate conversion ratio to %.2lf\n",
223                       data->src_ratio);
224                 src_set_ratio(convState->state, data->src_ratio);
225         }
227         /* there was an error previously, and nothing has changed */
228         if (convState->error)
229                 return 0;
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);
236         }
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);
243         }
245         src_short_to_float_array((short *)inBuffer, data->data_in,
246                                  data->input_frames * channels);
248         error = src_process(convState->state, data);
249         if (error) {
250                 ERROR("error processing samples with libsamplerate: %s\n",
251                       src_strerror(error));
252                 convState->error = 1;
253                 return 0;
254         }
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;
275         switch (channels) {
276         case 1:
277                 while (wr_dat < nlen) {
278                         rd_dat = wr_dat * inSampleRate / outSampleRate;
280                         lsample = in[rd_dat++];
282                         out[wr_dat++] = lsample;
283                 }
284                 break;
285         case 2:
286                 while (wr_dat < nlen) {
287                         rd_dat = wr_dat * inSampleRate / outSampleRate;
288                         rd_dat &= ~1;
290                         lsample = in[rd_dat++];
291                         rsample = in[rd_dat++];
293                         out[wr_dat++] = lsample;
294                         out[wr_dat++] = rsample;
295                 }
296                 break;
297         }
299         return outSize;
301 #endif /* !HAVE_LIBSAMPLERATE */
303 static char *pcm_convertChannels(mpd_sint8 channels, char *inBuffer,
304                                  size_t inSize, size_t *outSize)
306         static char *buf;
307         static size_t len;
308         char *outBuffer = NULL;;
309         mpd_sint16 *in;
310         mpd_sint16 *out;
311         int inSamples, i;
313         switch (channels) {
314         /* convert from 1 -> 2 channels */
315         case 1:
316                 *outSize = (inSize >> 1) << 2;
317                 if (*outSize > len) {
318                         len = *outSize;
319                         buf = xrealloc(buf, len);
320                 }
321                 outBuffer = buf;
323                 inSamples = inSize >> 1;
324                 in = (mpd_sint16 *)inBuffer;
325                 out = (mpd_sint16 *)outBuffer;
326                 for (i = 0; i < inSamples; i++) {
327                         *out++ = *in;
328                         *out++ = *in++;
329                 }
331                 break;
332         /* convert from 2 -> 1 channels */
333         case 2:
334                 *outSize = inSize >> 1;
335                 if (*outSize > len) {
336                         len = *outSize;
337                         buf = xrealloc(buf, len);
338                 }
339                 outBuffer = buf;
341                 inSamples = inSize >> 2;
342                 in = (mpd_sint16 *)inBuffer;
343                 out = (mpd_sint16 *)outBuffer;
344                 for (i = 0; i < inSamples; i++) {
345                         *out = (*in++) / 2;
346                         *out++ += (*in++) / 2;
347                 }
349                 break;
350         default:
351                 ERROR("only 1 or 2 channels are supported for conversion!\n");
352         }
354         return outBuffer;
357 static char *pcm_convertTo16bit(mpd_sint8 bits, char *inBuffer, size_t inSize,
358                                 size_t *outSize)
360         static char *buf;
361         static size_t len;
362         char *outBuffer = NULL;
363         mpd_sint8 *in;
364         mpd_sint16 *out;
365         int i;
367         switch (bits) {
368         case 8:
369                 *outSize = inSize << 1;
370                 if (*outSize > len) {
371                         len = *outSize;
372                         buf = xrealloc(buf, len);
373                 }
374                 outBuffer = buf;
376                 in = (mpd_sint8 *)inBuffer;
377                 out = (mpd_sint16 *)outBuffer;
378                 for (i = 0; i < inSize; i++)
379                         *out++ = (*in++) << 8;
381                 break;
382         case 16:
383                 *outSize = inSize;
384                 outBuffer = inBuffer;
385                 break;
386         case 24:
387                 /* put dithering code from mp3_decode here */
388         default:
389                 ERROR("only 8 or 16 bits are supported for conversion!\n");
390         }
392         return outBuffer;
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)
400         char *buf;
401         size_t len;
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);
409         if (!buf)
410                 exit(EXIT_FAILURE);
412         if (inFormat->channels != outFormat->channels) {
413                 buf = pcm_convertChannels(inFormat->channels, buf, len, &len);
414                 if (!buf)
415                         exit(EXIT_FAILURE);
416         }
418         if (inFormat->sampleRate == outFormat->sampleRate) {
419                 assert(outSize >= len);
420                 memcpy(outBuffer, buf, len);
421         } else {
422                 len = pcm_convertSampleRate(outFormat->channels,
423                                             inFormat->sampleRate, buf, len,
424                                             outFormat->sampleRate, outBuffer,
425                                             outSize, convState);
426                 if (len == 0)
427                         exit(EXIT_FAILURE);
428         }
430         return len;
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) {
442         case 8:
443                 outSize <<= 1;
444                 break;
445         case 16:
446                 break;
447         default:
448                 FATAL("only 8 or 16 bits are supported for conversion!\n");
449         }
451         if (inFormat->channels != outFormat->channels) {
452                 switch (inFormat->channels) {
453                 case 1:
454                         outSize = (outSize >> 1) << 2;
455                         break;
456                 case 2:
457                         outSize >>= 1;
458                         break;
459                 default:
460                         FATAL("only 1 or 2 channels are supported "
461                               "for conversion!\n");
462                 }
463         }
465         outSize /= shift;
466         outSize = floor(0.5 + (double)outSize * ratio);
467         outSize *= shift;
469         return outSize;