186eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung/* 286eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * Copyright (C) 2013 The Android Open Source Project 386eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * 486eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * Licensed under the Apache License, Version 2.0 (the "License"); 586eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * you may not use this file except in compliance with the License. 686eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * You may obtain a copy of the License at 786eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * 886eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * http://www.apache.org/licenses/LICENSE-2.0 986eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * 1086eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * Unless required by applicable law or agreed to in writing, software 1186eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * distributed under the License is distributed on an "AS IS" BASIS, 1286eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1386eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * See the License for the specific language governing permissions and 1486eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung * limitations under the License. 1586eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung */ 1686eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 1786eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung#ifndef ANDROID_AUDIO_RESAMPLER_DYN_H 1886eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung#define ANDROID_AUDIO_RESAMPLER_DYN_H 1986eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 2086eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung#include <stdint.h> 2186eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung#include <sys/types.h> 2286eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung#include <cutils/log.h> 2386eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 2486eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung#include "AudioResampler.h" 2586eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 2686eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hungnamespace android { 2786eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 28771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung/* AudioResamplerDyn 29771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung * 30771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung * This class template is used for floating point and integer resamplers. 31771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung * 32771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung * Type variables: 33771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung * TC = filter coefficient type (one of int16_t, int32_t, or float) 34771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung * TI = input data type (one of int16_t or float) 35771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung * TO = output data type (one of int32_t or float) 36771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung * 37771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung * For integer input data types TI, the coefficient type TC is either int16_t or int32_t. 38771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung * For float input data types TI, the coefficient type TC is float. 39771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung */ 40771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung 41771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hungtemplate<typename TC, typename TI, typename TO> 4286eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hungclass AudioResamplerDyn: public AudioResampler { 4386eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hungpublic: 443348e36c51e91e78020bcc6578eda83d97c31becAndy Hung AudioResamplerDyn(int inChannelCount, 45771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung int32_t sampleRate, src_quality quality); 4686eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 4786eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung virtual ~AudioResamplerDyn(); 4886eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 4986eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung virtual void init(); 5086eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 5186eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung virtual void setSampleRate(int32_t inSampleRate); 5286eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 535e58b0abe5b6c8f5bd96a8f78bbeeeb4d3892020Andy Hung virtual void setVolume(float left, float right); 5486eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 556b3b7e304e0f8f167241b2c75f1eb04a9ef192ecAndy Hung virtual size_t resample(int32_t* out, size_t outFrameCount, 5686eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung AudioBufferProvider* provider); 5786eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 5886eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hungprivate: 5986eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 6086eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung class Constants { // stores the filter constants. 6186eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung public: 6286eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung Constants() : 63771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung mL(0), mShift(0), mHalfNumCoefs(0), mFirCoefs(NULL) 6486eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung {} 6586eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung void set(int L, int halfNumCoefs, 6686eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung int inSampleRate, int outSampleRate); 6786eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 68771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung int mL; // interpolation phases in the filter. 69771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung int mShift; // right shift to get polyphase index 7086eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung unsigned int mHalfNumCoefs; // filter half #coefs 71771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung const TC* mFirCoefs; // polyphase filter bank 7286eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung }; 7386eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 74771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung class InBuffer { // buffer management for input type TI 7586eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung public: 7686eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung InBuffer(); 7786eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung ~InBuffer(); 7886eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung void init(); 79771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung 8086eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung void resize(int CHANNELS, int halfNumCoefs); 8186eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 8286eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung // used for direct management of the mImpulse pointer 8386eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung inline TI* getImpulse() { 8486eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung return mImpulse; 8586eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung } 86771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung 8786eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung inline void setImpulse(TI *impulse) { 8886eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung mImpulse = impulse; 8986eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung } 90771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung 9186eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung template<int CHANNELS> 9286eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung inline void readAgain(TI*& impulse, const int halfNumCoefs, 9386eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung const TI* const in, const size_t inputIndex); 94771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung 9586eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung template<int CHANNELS> 9686eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung inline void readAdvance(TI*& impulse, const int halfNumCoefs, 9786eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung const TI* const in, const size_t inputIndex); 9886eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 9986eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung private: 10086eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung // tuning parameter guidelines: 2 <= multiple <= 8 10186eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung static const int kStateSizeMultipleOfFilterLength = 4; 10286eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 10386eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung // in general, mRingFull = mState + mStateSize - halfNumCoefs*CHANNELS. 104771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung TI* mState; // base pointer for the input buffer storage 105771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung TI* mImpulse; // current location of the impulse response (centered) 106771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung TI* mRingFull; // mState <= mImpulse < mRingFull 107771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung size_t mStateCount; // size of state in units of TI. 10886eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung }; 10986eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 11086eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung void createKaiserFir(Constants &c, double stopBandAtten, 11186eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung int inSampleRate, int outSampleRate, double tbwCheat); 11286eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 113771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung template<int CHANNELS, bool LOCKED, int STRIDE> 1146b3b7e304e0f8f167241b2c75f1eb04a9ef192ecAndy Hung size_t resample(TO* out, size_t outFrameCount, AudioBufferProvider* provider); 115771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung 116075abae2a954bf3edf18ad1705c2c0f188454ae0Andy Hung // define a pointer to member function type for resample 1176b3b7e304e0f8f167241b2c75f1eb04a9ef192ecAndy Hung typedef size_t (AudioResamplerDyn<TC, TI, TO>::*resample_ABP_t)(TO* out, 118771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung size_t outFrameCount, AudioBufferProvider* provider); 119771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung 120771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung // data - the contiguous storage and layout of these is important. 121771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung InBuffer mInBuffer; 122771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung Constants mConstants; // current set of coefficient parameters 123771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung TO __attribute__ ((aligned (8))) mVolumeSimd[2]; // must be aligned or NEON may crash 124771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung resample_ABP_t mResampleFunc; // called function for resampling 125771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung int32_t mFilterSampleRate; // designed filter sample rate. 126771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung src_quality mFilterQuality; // designed filter quality. 127771386e6e6e79697e2d839ef0f25a242946ba1e5Andy Hung void* mCoefBuffer; // if a filter is created, this is not null 12886eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung}; 12986eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 13063238efb0d674758902918e3cdaac322126484b7Glenn Kasten} // namespace android 13186eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung 13286eae0e5931103e040ac2cdd023ef5db252e09f6Andy Hung#endif /*ANDROID_AUDIO_RESAMPLER_DYN_H*/ 133