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