Extending the Faust VST Architecture with Polyphony, Portamento and Pitch Bend Yan Michalevsky Julius O
Total Page:16
File Type:pdf, Size:1020Kb
Extending the Faust VST Architecture with Polyphony, Portamento and Pitch Bend Yan Michalevsky Julius O. Smith Andrew Best Department of Electrical Center for Computer Research in Blamsoft, Inc. Engineering, Music and Acoustics (CCRMA), [email protected] Stanford University Stanford University [email protected] AES Fellow [email protected] Abstract VST (Virtual Studio Technology) plugin stan- We introduce the vsti-poly.cpp architecture for dard was released by Steinberg GmbH (famous the Faust programming language. It provides sev- for Cubase and other music and sound produc- eral features that are important for practical use of tion products) in 1996, and was followed by the Faust-generated VSTi synthesizers. We focus on widespread version 2.0 in 1999 [8]. It is a partic- the VST architecture as one that has been used tra- ularly common format supported by many older ditionally and is supported by many popular tools, and newer tools. and add several important features: polyphony, note Some of the features expected from a VST history and pitch-bend support. These features take plugin can be found in the VST SDK code.2 Faust-generated VST instruments a step forward in Examining the list of MIDI events [1] can also terms of generating plugins that could be used in Digital Audio Workstations (DAW) for real-world hint at what capabilities are expected to be im- music production. plemented by instrument plugins. We also draw from our experience with MIDI instruments and Keywords commercial VST plugins in order to formulate sound feature requirements. Faust, VST, Plugin, DAW In order for Faust to be a practical tool for generating such plugins, it should support most 1 Introduction of the features expected, such as the following: Faust [5] is a popular music/audio signal pro- • Responding to MIDI keyboard events cessing language developed by Yann Orlarey et al. at GRAME,1 with contributions from a com- • Polyphony munity of developers. The toolset en- Faust • Portamento ables the generation of standalone synthesizers as well as plugins for various operating systems • Pitch-bending (wheel controlled) and environments. Considering a conve- Faust • Arpeggio nient tool and a fast way for prototyping and even creating production level sound effects and • Other effects dependent on note occurrence synthesizers, we would like to use Faust in com- history bination with real-world music production tools and DAWs (Digital Audio Workstations). All of the plugin formats mentioned above can be generated from Faust code with varying We believe it is necessary to facilitate work- levels of feature support. For example, there ing with tools such as Cubase, Ableton or other is a very complete faust2lv2 shell-script dis- DAWs providing a similar level of user experi- tributed with Faust provided by Albert Gräf ence and features. In the past ten years those [3]. There is also a highly useful faust2au tools shifted from relying on built-in PC sound- script by Reza Payami that is still under devel- blaster or external MIDI-controlled modules to opment. Useful VST 2.4 plugins can be gener- a plugin based architecture. Plugins are used ated using the faust2vst script, and relatively to generate sound and apply audio effects. Sev- limited VSTi plugins (i.e., VST synthesizer or eral common plugin architectures exist: VST, “instrument” plugins) can be generated using Apple’s Audio Unit (AU), LV2 (the successor faust2vsti. Initial VSTi support was limited of LADSPA and DSSI under Linux OS). The 2Specifically in the PlugCanDos namespace, declared 1http://faust.grame.fr in audioeffectx.cpp (in VST 2.4 SDK) a single voice (implemented in the Faust archi- The VST plugin controls are created and up- tecture file vsti-mono.cpp). dated using the vstUI class. There is an in- This paper describes the VSTi support stance of vstUI held by the Faust class which is implemented in the Faust architecture file used for knobs and sliders controlled by the user vsti-poly.cpp.3 This effort adds polyphony via the graphical interface or by mapping MIDI support, pitch-bend, note-history, and other fea- controls. This instance is for controlling param- tures described below. Pitch-bend and note his- eters that are global and should affect every note tory support facilitates effects such as porta- played. The instances of vstUI that are created mento slide,4 and creating arpeggiators. Finally, as part of each Voice instance are for control- we provide an example of how it can be used ling per note parameters (frequency, gain, pre- to create instruments. We demonstrate using viously played frequency and gate). The Faust Faust-generated VST plugins with MuLab [4] class implementation of the setParameter inter- and Renoise [7] workstations. We also discuss face method is broadcasting any change in the possible future improvements and additions. global plugin parameter to all Voice instances. Related work Handling MIDI events For handling MIDI events and polyphony sup- Faust VSTi architecture handles MIDI events port in a Faust architecture file, we bene- delegated by the VST host. The host sends the fited from the MIDI plugin section of [3] and events to the plugin by calling processEvents. the Faust DSSI architecture-file source code An event of type kVstMidiType indicates a dssi.cpp. Additionally, vsti-mono.cpp was MIDI event. useful as a basis for our extended Faust VSTi Note On architecture. A MIDI note-on event (status byte is 0x9) re- 2 Design sults in searching for a free voice instance to handle the new note in the freeVoices list con- Following the convention introduced by Albert tained in the Faust class. The search proceeds Gräf for [2] and [3] et faust2pd faust2lv2 in a classic round robin pattern as found in hard- al. [6], the VST architecture file implements ware synthesizers. If a free voice is found, the functionality for recognizing the “freq”, “gate” voice is designated as the new voice, otherwise and “gain” -control labels to set the note Faust the oldest playing voice is stolen and designated and velocity upon MIDI Note-On events (0x90) as the new voice. Its frequency is set according and to set the gate to 0 for a MIDI Note-Off to the note number, the gain parameter is set event (0x80). One approach to implementing according to the note velocity, and the gate is polyphony for the VSTi architecture is doing it set to 1. An entry is added to playingVoices, similarly to the DSSI plugin architecture. The mapping the note to the voice index, and the “freq”, “gate” and “gain” are mapped to the con- voice index is removed from the freeVoices list. trols multiple times which enables playing si- The previously played note is saved in order to multaneously a predefined maximum number of enable the portamento slide. notes. The VST format operates with multiple sam- We combine the approaches taken in ples in a processing block. The note-on event in- and . Figure 1 vsti-mono.cpp dssi.cpp cludes a sample offset within the current block. shows a UML diagram describing our design These deltas are stored in a list so that multi- ( ). A VST host interacts with vsti-poly.cpp ple note-on events can be handled in the block. the VST plugin through the AudioEffectX The note to voice allocation occurs within the interface. The class defines the func- Faust processing loop, so that each note starts at its tionality of the plugin by implementing that correct sample position within the block. interface. The mydsp class performs the signal processing and synthesis—it is the code that is Note Off actually produced by the Faust compiler. We A MIDI note-off event (status byte is 0x8) re- instantiate mydsp for each voice (Voice class). sults in searching for the corresponding Voice instance in the playingVoices list contained in 3 It is expected that this name will later change to the Faust class. The gate is then set to 0. Be- vsti.cpp. The faust2vsti command-line script will of course be updated as well in that case. cause the voice may have a release tail after the 4Although for a monophonic synthesizer portamento gate is zeroed, a silence detection algorithm is can be implemented by smoothing the input frequency. used to determine when the voice index should Figure 1: Faust VSTi design be added to the freeVoices list. The voice out- the range -1..1 and broadcast the value to all put must be below the silence threshold for an voices thus affecting all currently playing notes. entire block before it is marked as free. Silence The frequency is not updated by the architec- detection allows sounding voices to not be re- ture, as it is the responsibility of the Faust code allocated prematurely and also provides better to use the pitchbend control value. This sepa- CPU efficiency compared to always processing ration enables the user to ignore or handle the all voices. Like note-on events, note-off events pitch-bend MIDI event according to the desired are sample accurate within a block. behavior. Pitch Bend All-notes-off Event A MIDI pitch bend is indicated by status byte The All-notes-off MIDI event is indicated by a 0xE. The MIDI event pitch argument has values note number of 0, and velocity 0. Like the sin- in the range 0..16384. We normalize it to be in gle note-off event, the voice gate is set to 0 and entered into the release silence detection state. This is done for all active voices. Portamento Slide Implementation We demonstrated the very common portamento slide effect by creating a Faust VSTi based on the sawtooth synthesizer that is part of the Faust oscillator library (oscillator.lib).