Skip to content
Snippets Groups Projects
Select Git revision
  • 7267e7300031fb90b0f74c9350457e24b8d4bd3c
  • main default protected
2 results

HiHat.h

Blame
  • HiHat.h 2.96 KiB
    class HiHat {
      public:
        float frequency;
        float base_frequency;
        float frequency_range;
        float wavetable_start = 0;
        int wavetable_window_size = 1048;
        EnvelopeSimpleLog volume_envelope;
        HPF hpf;
        float gain = 1.0;
        void setup();
        void update();
        void reset();
        void trigger();
        float render();
        void advanceOscillator();
        void setVolumeDecay(float speed);
        void setFrequency(float frequency);
        void setWavetableStart(float start);
        void setHpfFrequency(float frequency);
    
      private:
        
        // Generate the wavetable using the python script. Make sure the lenght is updated wherever it occures in this script
        #include "HihatWavetable.h"
    
        float wavetable_progress = 0.0;
    };
    
    void HiHat::setup() {
      // Set some parameters
      this->volume_envelope.amount = 1.0;
      this->hpf.setFrequency(700.0);
      this->volume_envelope.setSnap(0.0005);
    
    }
    
    void HiHat::update() {
      this->volume_envelope.update();
    }
    
    void HiHat::reset() {
      this->volume_envelope.reset();
    }
    
    void HiHat::trigger() {
      this->reset();
      this->setWavetableStart(random(this->wavetable_start-0.2, this->wavetable_start+0.2));
    }
    
    float HiHat::render() {
      float orig_sample = this->volume_envelope.value * this->wavetable[min(104728-1, max(0, (int)this->wavetable_progress))];
      float filtered_sample = hpf.render(orig_sample);
      float sample = (orig_sample/8 + filtered_sample/2) * this->gain;
      return sample / 2 + 511;
    }
    
    void HiHat::advanceOscillator() {
      this->wavetable_progress += this->frequency;
    
      // Ensure the wavetable progress is within bounds
      if (this->wavetable_progress > 104728-1) {
        this->wavetable_progress = this->wavetable_start;
      }
    
      // Restart the wavetable if we are at the end of the table
      if (this->wavetable_progress > (this->wavetable_start + this->wavetable_window_size)) {
        this->wavetable_progress = this->wavetable_start;
        this->setWavetableStart(random(this->wavetable_start-0.2, this->wavetable_start+0.2));
      }
    }
    
    void HiHat::setVolumeDecay(float speed) {
      // Speed defines the decrement with which the envelope counter falls each update
      // the incoming variable is assumed to be in the range 0.0 to 1.0
      speed = 0.0001 + speed/200.0;
      this->volume_envelope.setSpeed(speed);
    }
    void HiHat::setFrequency(float frequency) {
      this->frequency = this->base_frequency + frequency * this->frequency_range;
    }
    
    void HiHat::setWavetableStart(float start) {
      // Set start to be somewhere within the sample (start is assumed to have a value from 0.0 to 1.0)
      start = start * (104728 - this->wavetable_window_size);
      this->wavetable_start = max(0.0, min(104728-1-this->wavetable_window_size, start));
      // Figure out the previous offset so we can keep the relative phase within the window
      float previous_offset = this->wavetable_progress - this->wavetable_start;
      this->wavetable_progress = this->wavetable_start + previous_offset;
    }
    
    void HiHat::setHpfFrequency(float frequency) {
      frequency = 350.0 + frequency * 4000.0;
      this->hpf.setFrequency(frequency);
    }