|
| Synth (uint32_t ports, uint32_t midi_input) |
|
| ~Synth () |
|
unsigned | find_free_voice (unsigned char key, unsigned char velocity) |
|
void | handle_midi (uint32_t size, unsigned char *data) |
|
void | handle_atom_event (LV2_Atom_Event *ev) |
|
void | pre_process (uint32_t from, uint32_t to) |
|
void | post_process (uint32_t from, uint32_t to) |
|
void | run (uint32_t sample_count) |
|
void | add_audio_outputs (uint32_t p1=-1, uint32_t p2=-1, uint32_t p3=-1, uint32_t p4=-1, uint32_t p5=-1, uint32_t p6=-1) |
|
void | add_voices (V *v01=0, V *v02=0, V *v03=0, V *v04=0, V *v05=0, V *v06=0, V *v07=0, V *v08=0, V *v09=0, V *v10=0, V *v11=0, V *v12=0, V *v13=0, V *v14=0, V *v15=0, V *v16=0, V *v17=0, V *v18=0, V *v19=0, V *v20=0) |
|
void | connect_port (uint32_t port, void *data_location) |
|
void | activate () |
|
void | deactivate () |
|
bool | check_ok () |
|
template<class V, class D, class Ext1 = end, class Ext2 = end, class Ext3 = end, class Ext4 = end, class Ext5 = end, class Ext6 = end, class Ext7 = end>
class lvtk::Synth< V, D, Ext1, Ext2, Ext3, Ext4, Ext5, Ext6, Ext7 >
This is a base class template for LV2 synth plugins. Its parameters
are a voice class, either a subclass of Voice or something written from
scratch, and the derived class itself. By using the derived class as a
template parameter the base class can call member functions in the
derived class without resorting to virtual function calls, which are
hard to optimise.
You can use @ref pluginmixins "mixins" with this class just like with
the Plugin class, but don't use URID - they are already
added automatically.
Here is an example of a complete synth plugin. Granted, not a very
exciting one, but it should be enough to explain how to do it:
#include <cstdlib>
#include <lvtk/synth.hpp>
enum {
MIDI_PORT,
AUDIO_PORT,
NUM_PORTS
};
NoiseVoice() : m_gain(0), m_key(INVALID_KEY) { }
void on(unsigned char k, unsigned char velocity) {
m_gain = 1.0;
m_key = k;
}
void off(unsigned char velocity) {
m_gain = 0.0;
m_key = lvtk::INVALID_KEY;
}
unsigned char get_key() const {
return m_key;
}
void render(uint32_t from, uint32_t to) {
for (uint32_t i = from; i < to; ++i) {
p(AUDIO_PORT)[i] += m_gain * 2 * (rand() / float(RAND_MAX) - 0.5);
m_gain *= 0.9999;
}
}
float m_gain;
unsigned char m_key;
};
struct NoiseSynth :
public lvtk::Synth<NoiseVoice, NoiseSynth> {
NoiseSynth(double)
: lvtk::
Synth<NoiseVoice, NoiseSynth>(NUM_PORTS, MIDI_PORT), m_filterstate(0) {
add_voices(
new NoiseVoice,
new NoiseVoice,
new NoiseVoice);
}
for (uint32_t i = from; i < to; ++i) {
p(AUDIO_PORT)[i] = m_filterstate * 0.9 +
p(AUDIO_PORT)[i] * 0.1;
m_filterstate =
p(AUDIO_PORT)[i];
}
}
float m_filterstate;
};
- Examples:
- beep.cpp.
unsigned find_free_voice |
( |
unsigned char |
key, |
|
|
unsigned char |
velocity |
|
) |
| |
|
inline |
This function implements the voice stealing algorithm. The key
and velocity
arguments are the parameters for the MIDI Note On event that needs a voice. This default implementation just returns the first free voice, and if there is none it steals voice 0.
This is not a virtual function, but if you override it in a subclass this class will still use that implementation thanks to the second template class parameter. This means that you can override this function if you want to implement your own voice stealing algorithm.
void post_process |
( |
uint32_t |
from, |
|
|
uint32_t |
to |
|
) |
| |
|
inline |
This function is called after the synth renders a chunk of audio from the voices, from sample from
to sample to
in the output buffers. It can be used to apply global effects to the mixed audio. This default implementation does nothing.
This is not a virtual function, but if you override it in a subclass this class will still use that implementation thanks to the second template class parameter. This means that you can override this function if you want to implement your own post-processing.
void pre_process |
( |
uint32_t |
from, |
|
|
uint32_t |
to |
|
) |
| |
|
inline |
This function is called before the synth renders a chunk of audio from the voices, from sample from
to sample to
in the output buffers. It can be used to compute parameters for the voices or adding initial ambient noise to the output buffers or something else. This default implementation does nothing.
This is not a virtual function, but if you override it in a subclass this class will still use that implementation thanks to the second template class parameter. This means that you can override this function if you want to implement your own pre-processing.