/*
 * 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
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_AUDIO_RESAMPLER_DYN_H
#define ANDROID_AUDIO_RESAMPLER_DYN_H

#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 {
public:
    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);

private:

    class Constants { // stores the filter constants.
    public:
        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
    public:
        InBuffer();
        ~InBuffer();
        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);

    private:
        // 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

#endif /*ANDROID_AUDIO_RESAMPLER_DYN_H*/
