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