GetDunne Wiki

Notes from the desk of Shane Dunne, software development consultant

User Tools

Site Tools


the_synthesizer

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
the_synthesizer [2017/08/30 22:47]
shane [SynthEnvelopeGenerator]
the_synthesizer [2017/08/30 23:49] (current)
shane [SynthOscillator]
Line 197: Line 197:
 This simplistic code is acceptable for low-frequency oscillators (LFOs), but it's not good enough for audio-frequency oscillators, because mathematical functions which define the waveforms are not //band-limited// (with the exception of the sine waveform, which is in fact perfectly band-limited). As a result, higher-frequency harmonics will be "aliased" to completely different audio frequencies when you play higher notes. This simplistic code is acceptable for low-frequency oscillators (LFOs), but it's not good enough for audio-frequency oscillators, because mathematical functions which define the waveforms are not //band-limited// (with the exception of the sine waveform, which is in fact perfectly band-limited). As a result, higher-frequency harmonics will be "aliased" to completely different audio frequencies when you play higher notes.
  
-VanillaJuce is essentially an early iteration of a project which was eventually renamed //SARAH// (//Synthèse à Rapide Analyse Harmonique//, or "synthesis with fast harmonic analysis"), which I plan to publish soon.+VanillaJuce is essentially an early iteration of a project which was eventually renamed [[sarah|SARAH]] (//Synthèse à Rapide Analyse Harmonique//, or "synthesis with fast harmonic analysis"), which I plan to publish soon.
  
 ===== SynthEnvelopeGenerator ===== ===== SynthEnvelopeGenerator =====
Line 329: Line 329:
  
 ===== Summary: What happens when you play a note ===== ===== Summary: What happens when you play a note =====
 +When the VanillaJuce plugin is compiled and instantiated in a DAW, and the user presses down a note on a MIDI keyboard (or the same sequence of MIDI-events occurs during the playback of a recorded MIDI sequence), the following things happen:
 +  - The //juce::Synthesiser::noteOn()// member function is called, with ''this'' pointing to the one and only //Synth// object (member variable //synth// of //VanillaJuceAudioProcessor//)
 +  - The //juce::Synthesiser// code assigns (or re-assigns) one of the sixteen available //SynthVoice// objects to play the note, and calls that object's //startNote()// function.
 +  - The //SynthVoice::startNote()// code (see above) sets up its two oscillators and envelope-generator according to the current program/patch parameters, and starts the note sounding by calling the envelope-generator's //start()// function.
 +  - Because the //SynthVoice// instance is now "active", calls made from the plugin host to //juce::Synthesiser::renderNextBlock()// are passed on to //SynthVoice::renderNextBlock()// (see above), which generates the required number of samples, //adding them in// to the supplied //juce::AudioSampleBuffer// so that all active voices are effectively summed (mixed with equal intensity) to the output.
 +  - With each successive sample, the envelope generator is advanced through the ADSR shape.
 +
 +When the MIDI note-off event occurs in the MIDI input sequence:
 +  - //juce::Synthesiser::noteOff()// is called.
 +  - The //juce::Synthesiser// code uses the MIDI note-number to determine which of the currently-active //SynthVoice// is playing the note, and calls that object's //stopNote()// function, with the //allowTailOff// argument set to //true//.
 +  - The //SynthVoice::stopNote()// code (see above) forces the ADSR envelope generator to go straight to the start of its Release phase.
 +  - Eventually, the test of //ampEG.isRunning()// in //SynthVoice::renderNextBlock()// returns //false//, because the envelope generator has reached the end of the Release ramp, and //juce::SynthesiserVoice::clearCurrentNote()// gets called; this causes the voice to become inactive, suppressing further calls to //SynthVoice::renderNextBlock()// for that voice.
 +
 +There are two special voice-assignment scenarios you should be aware of. The first one, //note reassignment// was already discussed above. If a MIDI note-on event occurs while there is already an active voice sounding the same MIDI note-number, //juce::Synthesiser::noteOn()// will simply call //startNote()// again on the active //SynthVoice// instance. Care must then be taken to ensure that there is not much of an audible "click" as the note goes back to its Attack phase.
 +
 +The second special case concerns what happens when the synthesizer runs out of voices. That case is actually almost identical to the first one; the only difference is how the //juce::Synthesiser// code selects which active voice to reassign---a process called //note-stealing//. Have a look at the //juce::Synthesiser// source code to learn exactly how its note-stealing algorithm works, and be aware that this is just one of several possible ways to do it. If you wanted a different note-stealing algorithm, you would simply have to override more of the //juce::Synthesiser// member functions.
  
the_synthesizer.1504133233.txt.gz · Last modified: 2017/08/30 22:47 by shane