From 4f76ba5a427b27c9d354f2fca762eebacea5ee0c Mon Sep 17 00:00:00 2001 From: Warren Dukes Date: Mon, 10 May 2004 17:08:46 +0000 Subject: format conversion for 8->16 bis and mono->stereo git-svn-id: https://svn.musicpd.org/mpd/trunk@973 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- src/pcm_utils.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 12 deletions(-) diff --git a/src/pcm_utils.c b/src/pcm_utils.c index 8ef431841..5465af65e 100644 --- a/src/pcm_utils.c +++ b/src/pcm_utils.c @@ -138,27 +138,92 @@ void pcm_mix(char * buffer1, char * buffer2, size_t bufferSize1, pcm_add(buffer1,buffer2,bufferSize1,bufferSize2,vol1,1000-vol1,format); } + +/* outFormat bits must be 16 and channels must be 2! */ void pcm_convertAudioFormat(AudioFormat * inFormat, char * inBuffer, size_t inSize, AudioFormat * outFormat, char * outBuffer) { - /*int inSampleSize = inFormat->bits*inFormat->channels/8; - int outSampleSize = outFormat->bits*outFormat->channels/8;*/ + static char * bitConvBuffer = NULL; + static int bitConvBufferLength = 0; + static char * channelConvBuffer = NULL; + static int channelConvBufferLength = 0; + char * dataChannelConv; + int dataChannelLen; + char * dataBitConv; + int dataBitLen; - assert(inFormat->bits==16); assert(outFormat->bits==16); - assert(inFormat->channels==2); assert(outFormat->channels==2); - if(inFormat->sampleRate == outFormat->sampleRate) return; + /* converts */ + switch(inFormat->bits) { + case 8: + dataBitLen = inSize << 1; + if(dataBitLen > bitConvBufferLength) { + bitConvBuffer = realloc(bitConvBuffer, dataBitLen); + bitConvBufferLength = dataBitLen; + } + dataBitConv = bitConvBuffer; + { + mpd_sint8 * in = (mpd_sint8 *)inBuffer; + mpd_sint16 * out = (mpd_sint16 *)dataBitConv; + int i; + for(i=0; ichannels) { + case 1: + dataChannelLen = (dataBitLen >> 1) << 2; + if(dataChannelLen > channelConvBufferLength) { + channelConvBuffer = realloc(channelConvBuffer, + dataChannelLen); + channelConvBufferLength = dataChannelLen; + } + dataChannelConv = channelConvBuffer; + { + mpd_sint16 * in = (mpd_sint16 *)dataBitConv; + mpd_sint16 * out = (mpd_sint16 *)dataChannelConv; + int i, inSamples = dataChannelLen >> 1; + for(i=0;isampleRate == outFormat->sampleRate) { + memcpy(outBuffer,dataChannelConv,dataChannelLen); + } + else { + /* only works if outFormat is 16-bit stereo! */ + /* resampling code blatantly ripped from XMMS */ const int shift = sizeof(mpd_sint16); mpd_sint32 i, in_samples, out_samples, x, delta; - mpd_sint16 * inptr = (mpd_sint16 *)inBuffer; + mpd_sint16 * inptr = (mpd_sint16 *)dataChannelConv; mpd_sint16 * outptr = (mpd_sint16 *)outBuffer; - mpd_uint32 nlen = (((inSize >> shift) * + mpd_uint32 nlen = (((dataChannelLen >> shift) * (mpd_uint32)(outFormat->sampleRate)) / inFormat->sampleRate); nlen <<= shift; @@ -197,9 +262,7 @@ size_t pcm_sizeOfOutputBufferForAudioFormatConversion(AudioFormat * inFormat, nlen <<= shift; - assert(inFormat->bits==16); assert(outFormat->bits==16); - assert(inFormat->channels==2); assert(outFormat->channels==2); return nlen; -- cgit v1.2.3