//--------------------------------------------------------------
// Reverberation generator
//
//  2017/04/10, Copyright (c) 2017 MIKAMI, Naoki
//--------------------------------------------------------------

#ifndef REVERBERATION_SYSTEM_HPP
#define REVERBERATION_SYSTEM_HPP

#include "ReverbUnit.hpp"
#include "ProcessingBase.hpp"

namespace Mikami
{
    class Reverberator : public ProcessingBase
    {
    public:
        Reverberator(float gC = 0.8f, float gA = 0.6f)
            : G0_(1.0f - gC),
              DELAY_INIT_(6000), variableDelay_(6000),
              cmF1_(gC, 887+1500), cmF2_(gC, 1153+3000),
              cmF3_(gC, 1499+6000),
              apF1_(gA, 97), apF2_(gA, 131) {}

        virtual float Execute(float sn)
        {
            float xn = G0_*sn;
            float yn = cmF1_.Execute(xn, variableDelay_/4)
                     + cmF2_.Execute(xn, variableDelay_/2)
                     + cmF3_.Execute(xn, variableDelay_);
            yn = apF2_.Execute(apF1_.Execute(yn));
            yn = yn + xn;   // add direct input signal
            return yn;
        }

        void SetDelay(int n) { variableDelay_ = DELAY_INIT_ - n; }

    private:
        const float G0_;
        const int DELAY_INIT_;
        int variableDelay_;

        CombFilter cmF1_, cmF2_, cmF3_;
        AllPassFilter apF1_, apF2_;

        // disallow copy constructor and assignment operator
        Reverberator(const Reverberator&);
        Reverberator& operator=(const Reverberator&);
    };
}
#endif  // REVERBERATION_SYSTEM_HPP
