1 /* 2 * Copyright (C) 2013 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 #ifndef ANDROID_AUDIO_RESAMPLER_DYN_H 18 #define ANDROID_AUDIO_RESAMPLER_DYN_H 19 20 #include <stdint.h> 21 #include <sys/types.h> 22 #include <android/log.h> 23 24 #include <media/AudioResampler.h> 25 26 namespace android { 27 28 /* AudioResamplerDyn 29 * 30 * This class template is used for floating point and integer resamplers. 31 * 32 * Type variables: 33 * TC = filter coefficient type (one of int16_t, int32_t, or float) 34 * TI = input data type (one of int16_t or float) 35 * TO = output data type (one of int32_t or float) 36 * 37 * For integer input data types TI, the coefficient type TC is either int16_t or int32_t. 38 * For float input data types TI, the coefficient type TC is float. 39 */ 40 41 template<typename TC, typename TI, typename TO> 42 class AudioResamplerDyn: public AudioResampler { 43 public: 44 AudioResamplerDyn(int inChannelCount, 45 int32_t sampleRate, src_quality quality); 46 47 virtual ~AudioResamplerDyn(); 48 49 virtual void init(); 50 51 virtual void setSampleRate(int32_t inSampleRate); 52 53 virtual void setVolume(float left, float right); 54 55 virtual size_t resample(int32_t* out, size_t outFrameCount, 56 AudioBufferProvider* provider); 57 58 // Make available key design criteria for testing getHalfLength()59 int getHalfLength() const { 60 return mConstants.mHalfNumCoefs; 61 } 62 getFilterCoefs()63 const TC *getFilterCoefs() const { 64 return mConstants.mFirCoefs; 65 } 66 getPhases()67 int getPhases() const { 68 return mConstants.mL; 69 } 70 getStopbandAttenuationDb()71 double getStopbandAttenuationDb() const { 72 return mStopbandAttenuationDb; 73 } 74 getPassbandRippleDb()75 double getPassbandRippleDb() const { 76 return mPassbandRippleDb; 77 } 78 getNormalizedTransitionBandwidth()79 double getNormalizedTransitionBandwidth() const { 80 return mNormalizedTransitionBandwidth; 81 } 82 getFilterAttenuation()83 double getFilterAttenuation() const { 84 return mFilterAttenuation; 85 } 86 getNormalizedCutoffFrequency()87 double getNormalizedCutoffFrequency() const { 88 return mNormalizedCutoffFrequency; 89 } 90 91 private: 92 93 class Constants { // stores the filter constants. 94 public: Constants()95 Constants() : 96 mL(0), mShift(0), mHalfNumCoefs(0), mFirCoefs(NULL) 97 {} 98 void set(int L, int halfNumCoefs, 99 int inSampleRate, int outSampleRate); 100 101 int mL; // interpolation phases in the filter. 102 int mShift; // right shift to get polyphase index 103 unsigned int mHalfNumCoefs; // filter half #coefs 104 const TC* mFirCoefs; // polyphase filter bank 105 }; 106 107 class InBuffer { // buffer management for input type TI 108 public: 109 InBuffer(); 110 ~InBuffer(); 111 void init(); 112 113 void resize(int CHANNELS, int halfNumCoefs); 114 115 // used for direct management of the mImpulse pointer getImpulse()116 inline TI* getImpulse() { 117 return mImpulse; 118 } 119 setImpulse(TI * impulse)120 inline void setImpulse(TI *impulse) { 121 mImpulse = impulse; 122 } 123 124 template<int CHANNELS> 125 inline void readAgain(TI*& impulse, const int halfNumCoefs, 126 const TI* const in, const size_t inputIndex); 127 128 template<int CHANNELS> 129 inline void readAdvance(TI*& impulse, const int halfNumCoefs, 130 const TI* const in, const size_t inputIndex); 131 132 void reset(); 133 134 private: 135 // tuning parameter guidelines: 2 <= multiple <= 8 136 static const int kStateSizeMultipleOfFilterLength = 4; 137 138 // in general, mRingFull = mState + mStateSize - halfNumCoefs*CHANNELS. 139 TI* mState; // base pointer for the input buffer storage 140 TI* mImpulse; // current location of the impulse response (centered) 141 TI* mRingFull; // mState <= mImpulse < mRingFull 142 size_t mStateCount; // size of state in units of TI. 143 }; 144 145 void createKaiserFir(Constants &c, double stopBandAtten, 146 int inSampleRate, int outSampleRate, double tbwCheat); 147 148 void createKaiserFir(Constants &c, double stopBandAtten, double fcr); 149 150 template<int CHANNELS, bool LOCKED, int STRIDE> 151 size_t resample(TO* out, size_t outFrameCount, AudioBufferProvider* provider); 152 153 // define a pointer to member function type for resample 154 typedef size_t (AudioResamplerDyn<TC, TI, TO>::*resample_ABP_t)(TO* out, 155 size_t outFrameCount, AudioBufferProvider* provider); 156 157 // data - the contiguous storage and layout of these is important. 158 InBuffer mInBuffer; 159 Constants mConstants; // current set of coefficient parameters 160 TO __attribute__ ((aligned (8))) mVolumeSimd[2]; // must be aligned or NEON may crash 161 resample_ABP_t mResampleFunc; // called function for resampling 162 int32_t mFilterSampleRate; // designed filter sample rate. 163 src_quality mFilterQuality; // designed filter quality. 164 void* mCoefBuffer; // if a filter is created, this is not null 165 166 // Property selected design parameters. 167 // This will enable fixed high quality resampling. 168 169 // 32 char PROP_NAME_MAX limit enforced before Android O 170 171 // Use for sample rates greater than or equal to this value. 172 // Set to non-negative to enable, negative to disable. 173 int32_t mPropertyEnableAtSampleRate = 48000; 174 // "ro.audio.resampler.psd.enable_at_samplerate" 175 176 // Specify HALF the resampling filter length. 177 // Set to a value which is a multiple of 4. 178 int32_t mPropertyHalfFilterLength = 32; 179 // "ro.audio.resampler.psd.halflength" 180 181 // Specify the stopband attenuation in positive dB. 182 // Set to a value greater or equal to 20. 183 int32_t mPropertyStopbandAttenuation = 90; 184 // "ro.audio.resampler.psd.stopband" 185 186 // Specify the cutoff frequency as a percentage of Nyquist. 187 // Set to a value between 50 and 100. 188 int32_t mPropertyCutoffPercent = 100; 189 // "ro.audio.resampler.psd.cutoff_percent" 190 191 // Filter creation design parameters, see setSampleRate() 192 double mStopbandAttenuationDb = 0.; 193 double mPassbandRippleDb = 0.; 194 double mNormalizedTransitionBandwidth = 0.; 195 double mFilterAttenuation = 0.; 196 double mNormalizedCutoffFrequency = 0.; 197 }; 198 199 } // namespace android 200 201 #endif /*ANDROID_AUDIO_RESAMPLER_DYN_H*/ 202