1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_NDEBUG 1 18 #include <audio_utils/primitives.h> 19 #include <utils/Log.h> 20 #include "AudioMixer.h" 21 #include "VideoEditorResampler.h" 22 23 namespace android { 24 25 struct VideoEditorResampler : public AudioBufferProvider { 26 27 public: 28 29 virtual status_t getNextBuffer(Buffer* buffer, int64_t pts); 30 virtual void releaseBuffer(Buffer* buffer); 31 32 enum { //Sampling freq 33 kFreq8000Hz = 8000, 34 kFreq11025Hz = 11025, 35 kFreq12000Hz = 12000, 36 kFreq16000Hz = 16000, 37 kFreq22050Hz = 22050, 38 kFreq24000Hz = 24000, 39 kFreq32000Hz = 32000, 40 kFreq44100 = 44100, 41 kFreq48000 = 48000, 42 }; 43 44 AudioResampler *mResampler; 45 int16_t* mInput; 46 int nbChannels; 47 int nbSamples; 48 M4OSA_Int32 outSamplingRate; 49 M4OSA_Int32 inSamplingRate; 50 51 int16_t *mTmpInBuffer; 52 }; 53 54 #define MAX_SAMPLEDURATION_FOR_CONVERTION 40 //ms 55 56 status_t VideoEditorResampler::getNextBuffer(AudioBufferProvider::Buffer *pBuffer, int64_t pts) { 57 58 uint32_t dataSize = pBuffer->frameCount * this->nbChannels * sizeof(int16_t); 59 mTmpInBuffer = (int16_t*)malloc(dataSize); 60 memcpy(mTmpInBuffer, this->mInput, dataSize); 61 pBuffer->raw = (void*)mTmpInBuffer; 62 63 return OK; 64 } 65 66 void VideoEditorResampler::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) { 67 68 if(pBuffer->raw != NULL) { 69 free(pBuffer->raw); 70 pBuffer->raw = NULL; 71 mTmpInBuffer = NULL; 72 } 73 pBuffer->frameCount = 0; 74 } 75 76 extern "C" { 77 78 M4OSA_Context LVAudioResamplerCreate(M4OSA_Int32 bitDepth, M4OSA_Int32 inChannelCount, 79 M4OSA_Int32 sampleRate, M4OSA_Int32 quality) { 80 81 VideoEditorResampler *context = new VideoEditorResampler(); 82 context->mResampler = AudioResampler::create( 83 bitDepth, inChannelCount, sampleRate); 84 if (context->mResampler == NULL) { 85 return NULL; 86 } 87 context->mResampler->setSampleRate(android::VideoEditorResampler::kFreq32000Hz); 88 context->mResampler->setVolume(0x1000, 0x1000); 89 context->nbChannels = inChannelCount; 90 context->outSamplingRate = sampleRate; 91 context->mInput = NULL; 92 context->mTmpInBuffer = NULL; 93 94 return ((M4OSA_Context )context); 95 } 96 97 98 void LVAudiosetSampleRate(M4OSA_Context resamplerContext, M4OSA_Int32 inSampleRate) { 99 100 VideoEditorResampler *context = 101 (VideoEditorResampler *)resamplerContext; 102 context->mResampler->setSampleRate(inSampleRate); 103 /* 104 * nbSamples is calculated for 40ms worth of data;hence sample rate 105 * is used to calculate the nbSamples 106 */ 107 context->inSamplingRate = inSampleRate; 108 // Allocate buffer for maximum allowed number of samples. 109 context->mInput = (int16_t*)malloc( (inSampleRate * MAX_SAMPLEDURATION_FOR_CONVERTION * 110 context->nbChannels * sizeof(int16_t)) / 1000); 111 } 112 113 void LVAudiosetVolume(M4OSA_Context resamplerContext, M4OSA_Int16 left, M4OSA_Int16 right) { 114 115 VideoEditorResampler *context = 116 (VideoEditorResampler *)resamplerContext; 117 context->mResampler->setVolume(left,right); 118 } 119 120 void LVDestroy(M4OSA_Context resamplerContext) { 121 122 VideoEditorResampler *context = 123 (VideoEditorResampler *)resamplerContext; 124 125 if (context->mTmpInBuffer != NULL) { 126 free(context->mTmpInBuffer); 127 context->mTmpInBuffer = NULL; 128 } 129 130 if (context->mInput != NULL) { 131 free(context->mInput); 132 context->mInput = NULL; 133 } 134 135 if (context->mResampler != NULL) { 136 delete context->mResampler; 137 context->mResampler = NULL; 138 } 139 140 if (context != NULL) { 141 delete context; 142 context = NULL; 143 } 144 } 145 146 void LVAudioresample_LowQuality(M4OSA_Int16* out, M4OSA_Int16* input, 147 M4OSA_Int32 outFrameCount, M4OSA_Context resamplerContext) { 148 149 VideoEditorResampler *context = 150 (VideoEditorResampler *)resamplerContext; 151 int32_t *pTmpBuffer = NULL; 152 153 context->nbSamples = (context->inSamplingRate * outFrameCount) / context->outSamplingRate; 154 memcpy(context->mInput,input,(context->nbSamples * context->nbChannels * sizeof(int16_t))); 155 156 /* 157 SRC module always gives stereo output, hence 2 for stereo audio 158 */ 159 pTmpBuffer = (int32_t*)malloc(outFrameCount * 2 * sizeof(int32_t)); 160 memset(pTmpBuffer, 0x00, outFrameCount * 2 * sizeof(int32_t)); 161 162 context->mResampler->resample((int32_t *)pTmpBuffer, 163 (size_t)outFrameCount, (VideoEditorResampler *)resamplerContext); 164 // Convert back to 16 bits 165 ditherAndClamp((int32_t*)out, pTmpBuffer, outFrameCount); 166 free(pTmpBuffer); 167 pTmpBuffer = NULL; 168 } 169 170 } 171 172 } //namespace android 173