// No audio is rendered in this method. // This code is only here to get updates synchronized in audio frame time. private void OnAudioFilterRead(float[] data, int channels) { bool playNote = (audioFrameCount % speed) == 0; if (playNote) { int note = sequence[sequenceIdx++]; sequenceIdx %= sequence.Length; if (note != -1) { note += pitch; synth.HandleEventNow(new EventQueue.QueuedEvent(EventQueue.EventType.Note_off, 0, -1)); synth.HandleEventNow(new EventQueue.QueuedEvent(EventQueue.EventType.Note_on, note, -1)); } } if (lfo1enabled) { lfo1.set_freq(lfo1Freq * 1024); lfo1.update(); synth.set_parameter(lfo1Param, lfo1BaseValue + lfo1.sin() * lfo1Strength); } if (lfo2enabled) { lfo2.set_freq(lfo2Freq * 1024); lfo2.update(); synth.set_parameter(lfo2Param, lfo2BaseValue + lfo2.sin() * lfo2Strength); } audioFrameCount++; }
private void update_params() { // Set synth params float freq = freqtab[current_note & 0x7f]; osc1.set_freq(freq, sample_rate); osc2.set_freq(freq * 0.5f, sample_rate); fenv.set_freq(1.0f / filterEnvDecay, sample_rate); lfo.set_freq(pwmFrequency * 2.3f, sample_rate); float env01 = fenv.quad_down01(); if (filterType == FilterType.Schmid) { filter1.SetResonance(resonance); filter2.SetResonance(resonance); filter1.SetCutoff(cutoffFrequency * env01); // 0 Hz cutoff is bad filter2.SetCutoff(cutoffFrequency * env01); filter1.SetOversampling(oversampling); filter2.SetOversampling(oversampling); } #if LAZZARINI_FILTER else if (filterType == FilterType.Lazzarini) { filter1Laz.SetResonance(resonance); filter2Laz.SetResonance(resonance); filter1Laz.SetCutoff(cutoffFrequency * env01); filter2Laz.SetCutoff(cutoffFrequency * env01); } #endif aenv.setAttackRate(aenv_attack * sample_rate); aenv.setDecayRate(aenv_decay * sample_rate); aenv.setReleaseRate(aenv_release * sample_rate); aenv.setSustainLevel(aenv_sustain); }