main/alles.c
void play_event(struct event e) {
    if(e.midi_note >= 0) { synth[e.voice].midi_note = e.midi_note; synth[e.voice].freq = freq_for_midi_note(e.midi_note); } 
    if(e.wave >= 0) synth[e.voice].wave = e.wave;
    if(e.phase >= 0) synth[e.voice].phase = e.phase;
    if(e.patch >= 0) synth[e.voice].patch = e.patch;
    if(e.duty >= 0) synth[e.voice].duty = e.duty;
    if(e.feedback >= 0) synth[e.voice].feedback = e.feedback;
    if(e.freq >= 0) synth[e.voice].freq = e.freq;
    
    if(e.adsr_target >= 0) synth[e.voice].adsr_target = e.adsr_target;
    if(e.adsr_a >= 0) synth[e.voice].adsr_a = e.adsr_a;
    if(e.adsr_d >= 0) synth[e.voice].adsr_d = e.adsr_d;
    if(e.adsr_s >= 0) synth[e.voice].adsr_s = e.adsr_s;
    if(e.adsr_r >= 0) synth[e.voice].adsr_r = e.adsr_r;

    if(e.lfo_source >= 0) { synth[e.voice].lfo_source = e.lfo_source; synth[e.lfo_source].status = LFO_SOURCE; }
    if(e.lfo_target >= 0) synth[e.voice].lfo_target = e.lfo_target;

    // For global changes, just make the change, no need to update the per-voice synth
    if(e.volume >= 0) global.volume = e.volume; 
    if(e.filter_freq >= 0) global.filter_freq = e.filter_freq; 
    if(e.resonance >= 0) global.resonance = e.resonance; 

    // Triggers / envelopes 
    // The only way a sound is made is if velocity (note on) is >0.
    if(e.velocity>0 ) { // New note on (even if something is already playing on this voice)
        synth[e.voice].amp = e.velocity; 
        synth[e.voice].velocity = e.velocity;
        synth[e.voice].status = AUDIBLE;
        // Take care of FM & KS first -- no special treatment for ADSR/LFO
        if(synth[e.voice].wave==FM) { fm_note_on(e.voice); } 
        else if(synth[e.voice].wave==KS) { ks_note_on(e.voice); } 
        else {
            // an oscillator voice came in with a note on.
            // Start the ADSR clock
            synth[e.voice].adsr_on_clock = esp_timer_get_time() / 1000;

            // Restart the waveforms, adjusting for phase if given
            if(synth[e.voice].wave==SINE) sine_note_on(e.voice);
            if(synth[e.voice].wave==SAW) saw_note_on(e.voice);
            if(synth[e.voice].wave==TRIANGLE) triangle_note_on(e.voice);
            if(synth[e.voice].wave==PULSE) pulse_note_on(e.voice);
            if(synth[e.voice].wave==PCM) pcm_note_on(e.voice);

            // Also trigger "note ons" for the LFO source, if we have one
            if(synth[e.voice].lfo_source >= 0) {
                if(synth[synth[e.voice].lfo_source].wave==SINE) sine_note_on(synth[e.voice].lfo_source);
                if(synth[synth[e.voice].lfo_source].wave==SAW) saw_note_on(synth[e.voice].lfo_source);
                if(synth[synth[e.voice].lfo_source].wave==TRIANGLE) triangle_note_on(synth[e.voice].lfo_source);
                if(synth[synth[e.voice].lfo_source].wave==PULSE) pulse_note_on(synth[e.voice].lfo_source);
                if(synth[synth[e.voice].lfo_source].wave==PCM) pcm_note_on(synth[e.voice].lfo_source);
            }

        }
    } else if(synth[e.voice].velocity > 0 && e.velocity == 0) { // new note off
        synth[e.voice].velocity = e.velocity;
        if(synth[e.voice].wave==FM) { fm_note_off(e.voice); }
        else if(synth[e.voice].wave==KS) { ks_note_off(e.voice); }
        else {
            // osc voice note off, start release
            synth[e.voice].adsr_on_clock = -1;
            synth[e.voice].adsr_off_clock = esp_timer_get_time() / 1000;
        }
    }

}
// Play an event, now -- tell the audio loop to start making noise
Play an event, now -- tell the audio loop to start making noise
Play an event now -- tell the audio loop to start making noise
void play_event(struct event e) {
    if(e.midi_note >= 0) { synth[e.voice].midi_note = e.midi_note; synth[e.voice].freq = freq_for_midi_note(e.midi_note); } 
    if(e.wave >= 0) synth[e.voice].wave = e.wave;
    if(e.phase >= 0) synth[e.voice].phase = e.phase;
    if(e.patch >= 0) synth[e.voice].patch = e.patch;
    if(e.duty >= 0) synth[e.voice].duty = e.duty;
    if(e.feedback >= 0) synth[e.voice].feedback = e.feedback;
    if(e.freq >= 0) synth[e.voice].freq = e.freq;
    if(e.adsr_target >= 0) synth[e.voice].adsr_target = e.adsr_target;
    if(e.adsr_a >= 0) synth[e.voice].adsr_a = e.adsr_a;
    if(e.adsr_d >= 0) synth[e.voice].adsr_d = e.adsr_d;
    if(e.adsr_s >= 0) synth[e.voice].adsr_s = e.adsr_s;
    if(e.adsr_r >= 0) synth[e.voice].adsr_r = e.adsr_r;
    if(e.lfo_source >= 0) { synth[e.voice].lfo_source = e.lfo_source; synth[e.lfo_source].status = LFO_SOURCE; }
    if(e.lfo_target >= 0) synth[e.voice].lfo_target = e.lfo_target;
    if(e.volume >= 0) global.volume = e.volume; 
    if(e.filter_freq >= 0) global.filter_freq = e.filter_freq; 
    if(e.resonance >= 0) global.resonance = e.resonance; 
    if(e.velocity>0 ) { 
        synth[e.voice].amp = e.velocity; 
        synth[e.voice].velocity = e.velocity;
        synth[e.voice].status = AUDIBLE;
        if(synth[e.voice].wave==FM) { fm_note_on(e.voice); } 
        else if(synth[e.voice].wave==KS) { ks_note_on(e.voice); } 
        else {
            synth[e.voice].adsr_on_clock = esp_timer_get_time() / 1000;
            if(synth[e.voice].wave==SINE) sine_note_on(e.voice);
            if(synth[e.voice].wave==SAW) saw_note_on(e.voice);
            if(synth[e.voice].wave==TRIANGLE) triangle_note_on(e.voice);
            if(synth[e.voice].wave==PULSE) pulse_note_on(e.voice);
            if(synth[e.voice].wave==PCM) pcm_note_on(e.voice);
            if(synth[e.voice].lfo_source >= 0) {
                if(synth[synth[e.voice].lfo_source].wave==SINE) sine_note_on(synth[e.voice].lfo_source);
                if(synth[synth[e.voice].lfo_source].wave==SAW) saw_note_on(synth[e.voice].lfo_source);
                if(synth[synth[e.voice].lfo_source].wave==TRIANGLE) triangle_note_on(synth[e.voice].lfo_source);
                if(synth[synth[e.voice].lfo_source].wave==PULSE) pulse_note_on(synth[e.voice].lfo_source);
                if(synth[synth[e.voice].lfo_source].wave==PCM) pcm_note_on(synth[e.voice].lfo_source);
            }
        }
    } else if(synth[e.voice].velocity > 0 && e.velocity == 0) { 
        synth[e.voice].velocity = e.velocity;
        if(synth[e.voice].wave==FM) { fm_note_off(e.voice); }
        else if(synth[e.voice].wave==KS) { ks_note_off(e.voice); }
        else {
            synth[e.voice].adsr_on_clock = -1;
            synth[e.voice].adsr_off_clock = esp_timer_get_time() / 1000;
        }
    }
}
void play_event ( struct event e ) { if ( e . midi_note >= 0 ) { synth [ e . voice ] . midi_note = e . midi_note ; synth [ e . voice ] . freq = freq_for_midi_note ( e . midi_note ) ; } if ( e . wave >= 0 ) synth [ e . voice ] . wave = e . wave ; if ( e . phase >= 0 ) synth [ e . voice ] . phase = e . phase ; if ( e . patch >= 0 ) synth [ e . voice ] . patch = e . patch ; if ( e . duty >= 0 ) synth [ e . voice ] . duty = e . duty ; if ( e . feedback >= 0 ) synth [ e . voice ] . feedback = e . feedback ; if ( e . freq >= 0 ) synth [ e . voice ] . freq = e . freq ; if ( e . adsr_target >= 0 ) synth [ e . voice ] . adsr_target = e . adsr_target ; if ( e . adsr_a >= 0 ) synth [ e . voice ] . adsr_a = e . adsr_a ; if ( e . adsr_d >= 0 ) synth [ e . voice ] . adsr_d = e . adsr_d ; if ( e . adsr_s >= 0 ) synth [ e . voice ] . adsr_s = e . adsr_s ; if ( e . adsr_r >= 0 ) synth [ e . voice ] . adsr_r = e . adsr_r ; if ( e . lfo_source >= 0 ) { synth [ e . voice ] . lfo_source = e . lfo_source ; synth [ e . lfo_source ] . status = LFO_SOURCE ; } if ( e . lfo_target >= 0 ) synth [ e . voice ] . lfo_target = e . lfo_target ; if ( e . volume >= 0 ) global . volume = e . volume ; if ( e . filter_freq >= 0 ) global . filter_freq = e . filter_freq ; if ( e . resonance >= 0 ) global . resonance = e . resonance ; if ( e . velocity > 0 ) { synth [ e . voice ] . amp = e . velocity ; synth [ e . voice ] . velocity = e . velocity ; synth [ e . voice ] . status = AUDIBLE ; if ( synth [ e . voice ] . wave == FM ) { fm_note_on ( e . voice ) ; } else if ( synth [ e . voice ] . wave == KS ) { ks_note_on ( e . voice ) ; } else { synth [ e . voice ] . adsr_on_clock = esp_timer_get_time ( ) / 1000 ; if ( synth [ e . voice ] . wave == SINE ) sine_note_on ( e . voice ) ; if ( synth [ e . voice ] . wave == SAW ) saw_note_on ( e . voice ) ; if ( synth [ e . voice ] . wave == TRIANGLE ) triangle_note_on ( e . voice ) ; if ( synth [ e . voice ] . wave == PULSE ) pulse_note_on ( e . voice ) ; if ( synth [ e . voice ] . wave == PCM ) pcm_note_on ( e . voice ) ; if ( synth [ e . voice ] . lfo_source >= 0 ) { if ( synth [ synth [ e . voice ] . lfo_source ] . wave == SINE ) sine_note_on ( synth [ e . voice ] . lfo_source ) ; if ( synth [ synth [ e . voice ] . lfo_source ] . wave == SAW ) saw_note_on ( synth [ e . voice ] . lfo_source ) ; if ( synth [ synth [ e . voice ] . lfo_source ] . wave == TRIANGLE ) triangle_note_on ( synth [ e . voice ] . lfo_source ) ; if ( synth [ synth [ e . voice ] . lfo_source ] . wave == PULSE ) pulse_note_on ( synth [ e . voice ] . lfo_source ) ; if ( synth [ synth [ e . voice ] . lfo_source ] . wave == PCM ) pcm_note_on ( synth [ e . voice ] . lfo_source ) ; } } } else if ( synth [ e . voice ] . velocity > 0 && e . velocity == 0 ) { synth [ e . voice ] . velocity = e . velocity ; if ( synth [ e . voice ] . wave == FM ) { fm_note_off ( e . voice ) ; } else if ( synth [ e . voice ] . wave == KS ) { ks_note_off ( e . voice ) ; } else { synth [ e . voice ] . adsr_on_clock = -1 ; synth [ e . voice ] . adsr_off_clock = esp_timer_get_time ( ) / 1000 ; } } }
Play an event, now -- tell the audio loop to start making noise
Play an event now -- tell the audio loop to start making noise
// For global changes, just make the change, no need to update the per-voice synth // Triggers / envelopes  // The only way a sound is made is if velocity (note on) is >0. // New note on (even if something is already playing on this voice) // Take care of FM & KS first -- no special treatment for ADSR/LFO // an oscillator voice came in with a note on. // Start the ADSR clock // Restart the waveforms, adjusting for phase if given // Also trigger "note ons" for the LFO source, if we have one // new note off // osc voice note off, start release