/*************************************************************************************
 * Original code copyright (C) 2012 Steve Folta
 * Converted to Juce module (C) 2016 Leo Olivers
 * Forked from https://github.com/stevefolta/SFZero
 * For license info please see the LICENSE file distributed with this source code
 *************************************************************************************/
#ifndef SFZVOICE_H_INCLUDED
#define SFZVOICE_H_INCLUDED

#include "SFZEG.h"

namespace sfzero
{
    class Region;
    
    class Voice : public juce::SynthesiserVoice
    {
    public:
        Voice();
        virtual ~Voice();
        
        bool canPlaySound(juce::SynthesiserSound *sound) override;
        void startNote(int midiNoteNumber, float velocity, juce::SynthesiserSound *sound, int currentPitchWheelPosition) override;
        void stopNote(float velocity, bool allowTailOff) override;
        void stopNoteForGroup();
        void stopNoteQuick();
        void pitchWheelMoved(int newValue) override;
        void controllerMoved(int controllerNumber, int newValue) override;
        void renderNextBlock(juce::AudioSampleBuffer &outputBuffer, int startSample, int numSamples) override;
        bool isPlayingNoteDown();
        bool isPlayingOneShot();
        
        int getGroup();
        juce::uint64 getOffBy();
        
        // Set the region to be used by the next startNote().
        void setRegion(Region::Ptr nextRegion);
        
        juce::String infoString();
        
    private:
        Region::Ptr region_;
        int trigger_;
        int curMidiNote_, curPitchWheel_;
        double pitchRatio_;
        float noteGainLeft_, noteGainRight_;
        double sourceSamplePosition_;
        EG ampeg_;
        juce::int64 sampleEnd_;
        juce::int64 loopStart_, loopEnd_;
        
        // Info only.
        int numLoops_;
        int curVelocity_;
        
        void calcPitchRatio();
        void killNote();
        double fractionalMidiNoteInHz(double note, double freqOfA = 440.0);
        
        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Voice)
    };
}

#endif // SFZVOICE_H_INCLUDED

