LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 > Class Template Reference

#include <lv2synth.hpp>

Inheritance diagram for LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >:

LV2::Plugin< D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >

List of all members.

Public Member Functions

 Synth (uint32_t ports, uint32_t midi_input)
 ~Synth ()
unsigned find_free_voice (unsigned char key, unsigned char velocity)
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)

Protected Member Functions

template<typename T>
T *& p (uint32_t port)
float *& p (uint32_t port)


Detailed Description

template<class V, class D, template< class, bool > class Ext1 = End, bool Req1 = false, template< class, bool > class Ext2 = End, bool Req2 = false, template< class, bool > class Ext3 = End, bool Req3 = false, template< class, bool > class Ext4 = End, bool Req4 = false, template< class, bool > class Ext5 = End, bool Req5 = false, template< class, bool > class Ext6 = End, bool Req6 = false, template< class, bool > class Ext7 = End, bool Req7 = false, template< class, bool > class Ext8 = End, bool Req8 = false, template< class, bool > class Ext9 = End, bool Req9 = false>
class LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >

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.

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:

enum {
  MIDI_PORT,
  AUDIO_PORT,
  NUM_PORTS
};

struct NoiseVoice : public LV2::Voice {

  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 = LV2::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 LV2::Synth<NoiseVoice, NoiseSynth> {

  NoiseSynth(double, const char*, const LV2::Feature* const*) 
    : LV2::Synth<NoiseVoice, NoiseSynth>(NUM_PORTS, MIDI_PORT), m_state(0) {
    add_voices(new NoiseVoice, new NoiseVoice, new NoiseVoice);
    add_audio_outputs(AUDIO_PORT);
  }

  void post_process(uint32_t from, uint32_t to) {
    for (uint32_t i = from; i < to; ++i) {
      p(AUDIO_PORT)[i] = m_state * 0.9 + p(AUDIO_PORT)[i] * 0.1;
      m_state = p(AUDIO_PORT)[i];
    }
  }

  float m_state;
};

Constructor & Destructor Documentation

template<class V, class D, template< class, bool > class Ext1 = End, bool Req1 = false, template< class, bool > class Ext2 = End, bool Req2 = false, template< class, bool > class Ext3 = End, bool Req3 = false, template< class, bool > class Ext4 = End, bool Req4 = false, template< class, bool > class Ext5 = End, bool Req5 = false, template< class, bool > class Ext6 = End, bool Req6 = false, template< class, bool > class Ext7 = End, bool Req7 = false, template< class, bool > class Ext8 = End, bool Req8 = false, template< class, bool > class Ext9 = End, bool Req9 = false>
LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >::Synth ( uint32_t  ports,
uint32_t  midi_input 
) [inline]

ports is the total number of ports in this plugin, and midi_input is the index of the main MIDI input port (the one that the synth should use for note input).

template<class V, class D, template< class, bool > class Ext1 = End, bool Req1 = false, template< class, bool > class Ext2 = End, bool Req2 = false, template< class, bool > class Ext3 = End, bool Req3 = false, template< class, bool > class Ext4 = End, bool Req4 = false, template< class, bool > class Ext5 = End, bool Req5 = false, template< class, bool > class Ext6 = End, bool Req6 = false, template< class, bool > class Ext7 = End, bool Req7 = false, template< class, bool > class Ext8 = End, bool Req8 = false, template< class, bool > class Ext9 = End, bool Req9 = false>
LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >::~Synth (  )  [inline]

This is needed to delete the voices.


Member Function Documentation

template<class V, class D, template< class, bool > class Ext1 = End, bool Req1 = false, template< class, bool > class Ext2 = End, bool Req2 = false, template< class, bool > class Ext3 = End, bool Req3 = false, template< class, bool > class Ext4 = End, bool Req4 = false, template< class, bool > class Ext5 = End, bool Req5 = false, template< class, bool > class Ext6 = End, bool Req6 = false, template< class, bool > class Ext7 = End, bool Req7 = false, template< class, bool > class Ext8 = End, bool Req8 = false, template< class, bool > class Ext9 = End, bool Req9 = false>
unsigned LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >::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.

template<class V, class D, template< class, bool > class Ext1 = End, bool Req1 = false, template< class, bool > class Ext2 = End, bool Req2 = false, template< class, bool > class Ext3 = End, bool Req3 = false, template< class, bool > class Ext4 = End, bool Req4 = false, template< class, bool > class Ext5 = End, bool Req5 = false, template< class, bool > class Ext6 = End, bool Req6 = false, template< class, bool > class Ext7 = End, bool Req7 = false, template< class, bool > class Ext8 = End, bool Req8 = false, template< class, bool > class Ext9 = End, bool Req9 = false>
void LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >::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.

template<class V, class D, template< class, bool > class Ext1 = End, bool Req1 = false, template< class, bool > class Ext2 = End, bool Req2 = false, template< class, bool > class Ext3 = End, bool Req3 = false, template< class, bool > class Ext4 = End, bool Req4 = false, template< class, bool > class Ext5 = End, bool Req5 = false, template< class, bool > class Ext6 = End, bool Req6 = false, template< class, bool > class Ext7 = End, bool Req7 = false, template< class, bool > class Ext8 = End, bool Req8 = false, template< class, bool > class Ext9 = End, bool Req9 = false>
void LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >::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.

template<class V, class D, template< class, bool > class Ext1 = End, bool Req1 = false, template< class, bool > class Ext2 = End, bool Req2 = false, template< class, bool > class Ext3 = End, bool Req3 = false, template< class, bool > class Ext4 = End, bool Req4 = false, template< class, bool > class Ext5 = End, bool Req5 = false, template< class, bool > class Ext6 = End, bool Req6 = false, template< class, bool > class Ext7 = End, bool Req7 = false, template< class, bool > class Ext8 = End, bool Req8 = false, template< class, bool > class Ext9 = End, bool Req9 = false>
void LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >::run ( uint32_t  sample_count  )  [inline]

This is the main run function. It handles incoming MIDI events and mixes the voices to the output buffers with pre- and post-processing applied. Don't override it unless you know what you're doing.

Reimplemented from LV2::Plugin< D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >.

template<class V, class D, template< class, bool > class Ext1 = End, bool Req1 = false, template< class, bool > class Ext2 = End, bool Req2 = false, template< class, bool > class Ext3 = End, bool Req3 = false, template< class, bool > class Ext4 = End, bool Req4 = false, template< class, bool > class Ext5 = End, bool Req5 = false, template< class, bool > class Ext6 = End, bool Req6 = false, template< class, bool > class Ext7 = End, bool Req7 = false, template< class, bool > class Ext8 = End, bool Req8 = false, template< class, bool > class Ext9 = End, bool Req9 = false>
void LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >::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 
) [inline]

This is typically called in the constructor of your derived class to tell the synth which ports the voices are using as audio output buffers, so the synth engine can fill them with zeros before rendering the voice audio.

template<class V, class D, template< class, bool > class Ext1 = End, bool Req1 = false, template< class, bool > class Ext2 = End, bool Req2 = false, template< class, bool > class Ext3 = End, bool Req3 = false, template< class, bool > class Ext4 = End, bool Req4 = false, template< class, bool > class Ext5 = End, bool Req5 = false, template< class, bool > class Ext6 = End, bool Req6 = false, template< class, bool > class Ext7 = End, bool Req7 = false, template< class, bool > class Ext8 = End, bool Req8 = false, template< class, bool > class Ext9 = End, bool Req9 = false>
void LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >::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 
) [inline]

This is typically called in the constructor of your derived class to add voices to the synth. The number of voices you add determine the polyphony. It can also be called while the plugin is running to change the polyphony on the fly, but it is NOT threadsafe - you have to make sure that the run() callback isn't executing simultaneously with this function.

template<class V, class D, template< class, bool > class Ext1 = End, bool Req1 = false, template< class, bool > class Ext2 = End, bool Req2 = false, template< class, bool > class Ext3 = End, bool Req3 = false, template< class, bool > class Ext4 = End, bool Req4 = false, template< class, bool > class Ext5 = End, bool Req5 = false, template< class, bool > class Ext6 = End, bool Req6 = false, template< class, bool > class Ext7 = End, bool Req7 = false, template< class, bool > class Ext8 = End, bool Req8 = false, template< class, bool > class Ext9 = End, bool Req9 = false>
template<typename T>
T*& LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >::p ( uint32_t  port  )  [inline, protected]

Use this function to access data buffers for ports.

Reimplemented from LV2::Plugin< D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >.

template<class V, class D, template< class, bool > class Ext1 = End, bool Req1 = false, template< class, bool > class Ext2 = End, bool Req2 = false, template< class, bool > class Ext3 = End, bool Req3 = false, template< class, bool > class Ext4 = End, bool Req4 = false, template< class, bool > class Ext5 = End, bool Req5 = false, template< class, bool > class Ext6 = End, bool Req6 = false, template< class, bool > class Ext7 = End, bool Req7 = false, template< class, bool > class Ext8 = End, bool Req8 = false, template< class, bool > class Ext9 = End, bool Req9 = false>
float*& LV2::Synth< V, D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >::p ( uint32_t  port  )  [inline, protected]

Use this function to access data buffers for control or audio ports.

Reimplemented from LV2::Plugin< D, Ext1, Req1, Ext2, Req2, Ext3, Req3, Ext4, Req4, Ext5, Req5, Ext6, Req6, Ext7, Req7, Ext8, Req8, Ext9, Req9 >.


The documentation for this class was generated from the following file:
Generated on Tue Jan 8 23:08:21 2008 by  doxygen 1.5.4