blob: 3b1c381a443a656fd254ded34f2f1635da55914c [file] [log] [blame]
* Copyright (C) 2013 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
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* See the License for the specific language governing permissions and
* limitations under the License.
#include <stdint.h>
#include <sys/types.h>
#include <cutils/log.h>
#include "AudioResampler.h"
namespace android {
/* AudioResamplerDyn
* This class template is used for floating point and integer resamplers.
* Type variables:
* TC = filter coefficient type (one of int16_t, int32_t, or float)
* TI = input data type (one of int16_t or float)
* TO = output data type (one of int32_t or float)
* For integer input data types TI, the coefficient type TC is either int16_t or int32_t.
* For float input data types TI, the coefficient type TC is float.
template<typename TC, typename TI, typename TO>
class AudioResamplerDyn: public AudioResampler {
AudioResamplerDyn(int inChannelCount,
int32_t sampleRate, src_quality quality);
virtual ~AudioResamplerDyn();
virtual void init();
virtual void setSampleRate(int32_t inSampleRate);
virtual void setVolume(float left, float right);
virtual size_t resample(int32_t* out, size_t outFrameCount,
AudioBufferProvider* provider);
class Constants { // stores the filter constants.
Constants() :
mL(0), mShift(0), mHalfNumCoefs(0), mFirCoefs(NULL)
void set(int L, int halfNumCoefs,
int inSampleRate, int outSampleRate);
int mL; // interpolation phases in the filter.
int mShift; // right shift to get polyphase index
unsigned int mHalfNumCoefs; // filter half #coefs
const TC* mFirCoefs; // polyphase filter bank
class InBuffer { // buffer management for input type TI
void init();
void resize(int CHANNELS, int halfNumCoefs);
// used for direct management of the mImpulse pointer
inline TI* getImpulse() {
return mImpulse;
inline void setImpulse(TI *impulse) {
mImpulse = impulse;
template<int CHANNELS>
inline void readAgain(TI*& impulse, const int halfNumCoefs,
const TI* const in, const size_t inputIndex);
template<int CHANNELS>
inline void readAdvance(TI*& impulse, const int halfNumCoefs,
const TI* const in, const size_t inputIndex);
// tuning parameter guidelines: 2 <= multiple <= 8
static const int kStateSizeMultipleOfFilterLength = 4;
// in general, mRingFull = mState + mStateSize - halfNumCoefs*CHANNELS.
TI* mState; // base pointer for the input buffer storage
TI* mImpulse; // current location of the impulse response (centered)
TI* mRingFull; // mState <= mImpulse < mRingFull
size_t mStateCount; // size of state in units of TI.
void createKaiserFir(Constants &c, double stopBandAtten,
int inSampleRate, int outSampleRate, double tbwCheat);
template<int CHANNELS, bool LOCKED, int STRIDE>
size_t resample(TO* out, size_t outFrameCount, AudioBufferProvider* provider);
// define a pointer to member function type for resample
typedef size_t (AudioResamplerDyn<TC, TI, TO>::*resample_ABP_t)(TO* out,
size_t outFrameCount, AudioBufferProvider* provider);
// data - the contiguous storage and layout of these is important.
InBuffer mInBuffer;
Constants mConstants; // current set of coefficient parameters
TO __attribute__ ((aligned (8))) mVolumeSimd[2]; // must be aligned or NEON may crash
resample_ABP_t mResampleFunc; // called function for resampling
int32_t mFilterSampleRate; // designed filter sample rate.
src_quality mFilterQuality; // designed filter quality.
void* mCoefBuffer; // if a filter is created, this is not null
} // namespace android