Skip to content

File PolyPluck.h

File List > DaisySP > DaisySP-LGPL > Source > PhysicalModeling > PolyPluck.h

Go to the documentation of this file

Source Code

/*
Copyright (c) 2023 Electrosmith, Corp

Use of this source code is governed by the LGPL V2.1
license that can be found in the LICENSE file or at
https://opensource.org/license/lgpl-2-1/
*/

#pragma once
#ifndef DSY_POLYPLUCK_H
#define DSY_POLYPLUCK_H

#include <stdlib.h>
#include "Utility/dsp.h"
#include "PhysicalModeling/pluck.h"
#include "Utility/dcblock.h"

namespace daisysp
{
template <size_t num_voices>
class PolyPluck
{
  public:
    void Init(float sample_rate)
    {
        active_voice_ = 0;
        p_damp_       = 0.95f;
        p_decay_      = 0.75f;
        for(size_t i = 0; i < num_voices; i++)
        {
            plk_[i].Init(sample_rate, plkbuff_[i], 256, PLUCK_MODE_RECURSIVE);
            plk_[i].SetDamp(0.85f);
            plk_[i].SetAmp(0.18f);
            plk_[i].SetDecay(0.85f);
        }
        blk_.Init(sample_rate);
    }

    float Process(float &trig, float note)
    {
        float sig, tval;
        sig = 0.0f;
        if(trig > 0.0f)
        {
            // increment active voice
            active_voice_ = (active_voice_ + 1) % num_voices;
            // set new voice to new note
            plk_[active_voice_].SetDamp(p_damp_);
            plk_[active_voice_].SetDecay(p_decay_);
            plk_[active_voice_].SetAmp(0.25f);
        }
        plk_[active_voice_].SetFreq(mtof(note));

        for(size_t i = 0; i < num_voices; i++)
        {
            tval = (trig > 0.0f && i == active_voice_) ? 1.0f : 0.0f;
            sig += plk_[i].Process(tval);
        }
        if(trig > 0.0f)
            trig = 0.0f;
        return blk_.Process(sig);
    }

    void SetDecay(float p) { p_damp_ = p; }

  private:
    DcBlock blk_;
    Pluck   plk_[num_voices];
    float   plkbuff_[num_voices][256];
    float   p_damp_, p_decay_;
    size_t  active_voice_;
};

} // namespace daisysp

#endif