1
/* the Music Player Daemon (MPD)
2
* (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
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
20
#include "pcm_utils.h"
22
#include "mpd_types.h"
29
void pcm_changeBufferEndianness(char * buffer, int bufferSize, int bits) {
36
*buffer = *(buffer+1);
44
void pcm_volumeChange(char * buffer, int bufferSize, AudioFormat * format,
48
mpd_sint8 * buffer8 = (mpd_sint8 *)buffer;
49
mpd_sint16 * buffer16 = (mpd_sint16 *)buffer;
51
if(volume>=1000) return;
54
memset(buffer,0,bufferSize);
58
switch(format->bits) {
64
*buffer16 = temp32>32767 ? 32767 :
65
(temp32<-32768 ? -32768 : temp32);
75
*buffer8 = temp32>127 ? 127 :
76
(temp32<-128 ? -128 : temp32);
82
ERROR("%i bits not supported by pcm_volumeChange!\n",
88
void pcm_add(char * buffer1, char * buffer2, size_t bufferSize1,
89
size_t bufferSize2, int vol1, int vol2, AudioFormat * format)
92
mpd_sint8 * buffer8_1 = (mpd_sint8 *)buffer1;
93
mpd_sint8 * buffer8_2 = (mpd_sint8 *)buffer2;
94
mpd_sint16 * buffer16_1 = (mpd_sint16 *)buffer1;
95
mpd_sint16 * buffer16_2 = (mpd_sint16 *)buffer2;
97
switch(format->bits) {
99
while(bufferSize1>0 && bufferSize2>0) {
100
temp32 = (vol1*(*buffer16_1)+vol2*(*buffer16_2))/1000;
101
*buffer16_1 = temp32>32767 ? 32767 :
102
(temp32<-32768 ? -32768 : temp32);
108
if(bufferSize2>0) memcpy(buffer16_1,buffer16_2,bufferSize2);
111
while(bufferSize1>0 && bufferSize2>0) {
112
temp32 = (vol1*(*buffer8_1)+vol2*(*buffer8_2))/1000;
113
*buffer8_1 = temp32>127 ? 127 :
114
(temp32<-128 ? -128 : temp32);
120
if(bufferSize2>0) memcpy(buffer8_1,buffer8_2,bufferSize2);
123
ERROR("%i bits not supported by pcm_add!\n",format->bits);
128
void pcm_mix(char * buffer1, char * buffer2, size_t bufferSize1,
129
size_t bufferSize2, AudioFormat * format, float portion1)
132
float s = sin(M_PI_2*portion1);
136
vol1 = vol1>1000 ? 1000 : ( vol1<0 ? 0 : vol1 );
138
pcm_add(buffer1,buffer2,bufferSize1,bufferSize2,vol1,1000-vol1,format);
142
/* outFormat bits must be 16 and channels must be 2! */
143
void pcm_convertAudioFormat(AudioFormat * inFormat, char * inBuffer, size_t
144
inSize, AudioFormat * outFormat, char * outBuffer)
146
static char * bitConvBuffer = NULL;
147
static int bitConvBufferLength = 0;
148
static char * channelConvBuffer = NULL;
149
static int channelConvBufferLength = 0;
150
char * dataChannelConv;
155
assert(outFormat->bits==16);
156
assert(outFormat->channels==2);
159
switch(inFormat->bits) {
161
dataBitLen = inSize << 1;
162
if(dataBitLen > bitConvBufferLength) {
163
bitConvBuffer = realloc(bitConvBuffer, dataBitLen);
164
bitConvBufferLength = dataBitLen;
166
dataBitConv = bitConvBuffer;
168
mpd_sint8 * in = (mpd_sint8 *)inBuffer;
169
mpd_sint16 * out = (mpd_sint16 *)dataBitConv;
171
for(i=0; i<inSize; i++) {
172
*out++ = (*in++) << 8;
177
dataBitConv = inBuffer;
181
/* put dithering code from mp3_decode here */
183
ERROR("only 8 or 16 bits are supported for conversion!\n");
187
/* converts only between 16 bit audio between mono and stereo */
188
switch(inFormat->channels) {
190
dataChannelLen = (dataBitLen >> 1) << 2;
191
if(dataChannelLen > channelConvBufferLength) {
192
channelConvBuffer = realloc(channelConvBuffer,
194
channelConvBufferLength = dataChannelLen;
196
dataChannelConv = channelConvBuffer;
198
mpd_sint16 * in = (mpd_sint16 *)dataBitConv;
199
mpd_sint16 * out = (mpd_sint16 *)dataChannelConv;
200
int i, inSamples = dataBitLen >> 1;
201
for(i=0;i<inSamples;i++) {
208
dataChannelConv = dataBitConv;
209
dataChannelLen = dataBitLen;
212
ERROR("only 1 or 2 channels are supported for conversion!\n");
216
if(inFormat->sampleRate == outFormat->sampleRate) {
217
memcpy(outBuffer,dataChannelConv,dataChannelLen);
220
/* only works if outFormat is 16-bit stereo! */
221
/* resampling code blatantly ripped from ESD */
222
mpd_sint32 rd_dat = 0;
223
mpd_uint32 wr_dat = 0;
224
mpd_sint16 lsample, rsample;
225
register mpd_sint16 * out = (mpd_sint16 *)outBuffer;
226
register mpd_sint16 * in = (mpd_sint16 *)dataChannelConv;
227
const int shift = sizeof(mpd_sint16);
228
mpd_uint32 nlen = ((( dataChannelLen >> shift) *
229
(mpd_uint32)(outFormat->sampleRate)) /
230
inFormat->sampleRate);
233
while( wr_dat < nlen / shift) {
234
rd_dat = wr_dat * inFormat->sampleRate /
235
outFormat->sampleRate;
238
lsample = in[ rd_dat++ ];
239
rsample = in[ rd_dat++ ];
241
out[ wr_dat++ ] = lsample;
242
out[ wr_dat++ ] = rsample;
249
size_t pcm_sizeOfOutputBufferForAudioFormatConversion(AudioFormat * inFormat,
250
char * inBuffer, size_t inSize, AudioFormat * outFormat)
252
const int shift = sizeof(mpd_sint16);
253
size_t outSize = inSize;
255
switch(inFormat->bits) {
257
outSize = outSize << 1;
262
ERROR("only 8 or 16 bits are supported for conversion!\n");
266
switch(inFormat->channels) {
268
outSize = (outSize >> 1) << 2;
273
ERROR("only 1 or 2 channels are supported for conversion!\n");
277
outSize = (((outSize >> shift) * (mpd_uint32)(outFormat->sampleRate)) /
278
inFormat->sampleRate);