Home | History | Annotate | Download | only in libaudioprocessing
      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
     59     int getHalfLength() const {
     60         return mConstants.mHalfNumCoefs;
     61     }
     62 
     63     const TC *getFilterCoefs() const {
     64         return mConstants.mFirCoefs;
     65     }
     66 
     67     int getPhases() const {
     68         return mConstants.mL;
     69     }
     70 
     71     double getStopbandAttenuationDb() const {
     72         return mStopbandAttenuationDb;
     73     }
     74 
     75     double getPassbandRippleDb() const {
     76         return mPassbandRippleDb;
     77     }
     78 
     79     double getNormalizedTransitionBandwidth() const {
     80         return mNormalizedTransitionBandwidth;
     81     }
     82 
     83     double getFilterAttenuation() const {
     84         return mFilterAttenuation;
     85     }
     86 
     87     double getNormalizedCutoffFrequency() const {
     88         return mNormalizedCutoffFrequency;
     89     }
     90 
     91 private:
     92 
     93     class Constants { // stores the filter constants.
     94     public:
     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
    116         inline TI* getImpulse() {
    117             return mImpulse;
    118         }
    119 
    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