/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_NDEBUG 1 #include <utils/Log.h> #include "AudioMixer.h" #include "VideoEditorResampler.h" namespace android { struct VideoEditorResampler : public AudioBufferProvider { public: virtual status_t getNextBuffer(Buffer* buffer); virtual void releaseBuffer(Buffer* buffer); enum { //Sampling freq kFreq8000Hz = 8000, kFreq11025Hz = 11025, kFreq12000Hz = 12000, kFreq16000Hz = 16000, kFreq22050Hz = 22050, kFreq240000Hz = 24000, kFreq32000Hz = 32000, kFreq44100 = 44100, kFreq48000 = 48000, }; AudioResampler *mResampler; int16_t* mInput; int nbChannels; int nbSamples; M4OSA_Int32 outSamplingRate; M4OSA_Int32 inSamplingRate; int16_t *mTmpInBuffer; }; #define MAX_SAMPLEDURATION_FOR_CONVERTION 40 //ms status_t VideoEditorResampler::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) { uint32_t dataSize = pBuffer->frameCount * this->nbChannels * sizeof(int16_t); mTmpInBuffer = (int16_t*)malloc(dataSize); memcpy(mTmpInBuffer, this->mInput, dataSize); pBuffer->raw = (void*)mTmpInBuffer; return OK; } void VideoEditorResampler::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) { if(pBuffer->raw != NULL) { free(pBuffer->raw); pBuffer->raw = NULL; mTmpInBuffer = NULL; } pBuffer->frameCount = 0; } extern "C" { M4OSA_Context LVAudioResamplerCreate(M4OSA_Int32 bitDepth, M4OSA_Int32 inChannelCount, M4OSA_Int32 sampleRate, M4OSA_Int32 quality) { VideoEditorResampler *context = new VideoEditorResampler(); context->mResampler = AudioResampler::create( bitDepth, inChannelCount, sampleRate, AudioResampler::DEFAULT); if (context->mResampler == NULL) { return NULL; } context->mResampler->setSampleRate(android::VideoEditorResampler::kFreq32000Hz); context->mResampler->setVolume(0x1000, 0x1000); context->nbChannels = inChannelCount; context->outSamplingRate = sampleRate; context->mInput = NULL; context->mTmpInBuffer = NULL; return ((M4OSA_Context )context); } void LVAudiosetSampleRate(M4OSA_Context resamplerContext, M4OSA_Int32 inSampleRate) { VideoEditorResampler *context = (VideoEditorResampler *)resamplerContext; context->mResampler->setSampleRate(inSampleRate); /* * nbSamples is calculated for 40ms worth of data;hence sample rate * is used to calculate the nbSamples */ context->inSamplingRate = inSampleRate; // Allocate buffer for maximum allowed number of samples. context->mInput = (int16_t*)malloc( (inSampleRate * MAX_SAMPLEDURATION_FOR_CONVERTION * context->nbChannels * sizeof(int16_t)) / 1000); } void LVAudiosetVolume(M4OSA_Context resamplerContext, M4OSA_Int16 left, M4OSA_Int16 right) { VideoEditorResampler *context = (VideoEditorResampler *)resamplerContext; context->mResampler->setVolume(left,right); } void LVDestroy(M4OSA_Context resamplerContext) { VideoEditorResampler *context = (VideoEditorResampler *)resamplerContext; if (context->mTmpInBuffer != NULL) { free(context->mTmpInBuffer); context->mTmpInBuffer = NULL; } if (context->mInput != NULL) { free(context->mInput); context->mInput = NULL; } if (context->mResampler != NULL) { delete context->mResampler; context->mResampler = NULL; } if (context != NULL) { delete context; context = NULL; } } void LVAudioresample_LowQuality(M4OSA_Int16* out, M4OSA_Int16* input, M4OSA_Int32 outFrameCount, M4OSA_Context resamplerContext) { VideoEditorResampler *context = (VideoEditorResampler *)resamplerContext; int32_t *pTmpBuffer = NULL; context->nbSamples = (context->inSamplingRate * outFrameCount) / context->outSamplingRate; memcpy(context->mInput,input,(context->nbSamples * context->nbChannels * sizeof(int16_t))); /* SRC module always gives stereo output, hence 2 for stereo audio */ pTmpBuffer = (int32_t*)malloc(outFrameCount * 2 * sizeof(int32_t)); memset(pTmpBuffer, 0x00, outFrameCount * 2 * sizeof(int32_t)); context->mResampler->resample((int32_t *)pTmpBuffer, (size_t)outFrameCount, (VideoEditorResampler *)resamplerContext); // Convert back to 16 bits AudioMixer::ditherAndClamp((int32_t*)out, pTmpBuffer, outFrameCount); free(pTmpBuffer); pTmpBuffer = NULL; } } } //namespace android