The previous tutorial chapters were concerned only with monophonic ToolKit instrument playback and control. At this point, it should be relatively clear that one can instantiate multiple instruments and perhaps sum together their outputs or even direct their outputs to separate channels. It is less clear how one might go about controlling a group of instruments. The stk::Voicer class is designed to serve just this purpose.
#include "BeeThree.h"
#include "Messager.h"
#include "Voicer.h"
#include "SKINImsg.h"
#include <algorithm>
using std::min;
struct TickData {
int counter;
bool haveMessage;
bool done;
TickData()
: counter(0), haveMessage(false), done( false ) {}
};
#define DELTA_CONTROL_TICKS 64
void processMessage( TickData* data )
{
register StkFloat value1 = data->message.floatValues[0];
register StkFloat value2 = data->message.floatValues[1];
switch( data->message.type ) {
case __SK_Exit_:
data->done = true;
return;
case __SK_NoteOn_:
if ( value2 == 0.0 )
data->voicer.noteOff( value1, 64.0 );
else {
data->voicer.noteOn( value1, value2 );
}
break;
case __SK_NoteOff_:
data->voicer.noteOff( value1, value2 );
break;
case __SK_ControlChange_:
data->voicer.controlChange( (int) value1, value2 );
break;
case __SK_AfterTouch_:
data->voicer.controlChange( 128, value1 );
case __SK_PitchChange_:
data->voicer.setFrequency( value1 );
break;
case __SK_PitchBend_:
data->voicer.pitchBend( value1 );
}
data->haveMessage = false;
return;
}
int tick( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
{
TickData *data = (TickData *) dataPointer;
register StkFloat *samples = (StkFloat *) outputBuffer;
int counter, nTicks = (int) nBufferFrames;
while ( nTicks > 0 && !data->done ) {
if ( !data->haveMessage ) {
data->messager.popMessage( data->message );
if ( data->message.type > 0 ) {
data->counter = (long) (data->message.time * Stk::sampleRate());
data->haveMessage = true;
}
else
data->counter = DELTA_CONTROL_TICKS;
}
counter = min( nTicks, data->counter );
data->counter -= counter;
for ( int i=0; i<counter; i++ ) {
*samples++ = data->voicer.tick();
nTicks--;
}
if ( nTicks == 0 ) break;
if ( data->haveMessage ) processMessage( data );
}
return 0;
}
int main()
{
Stk::setSampleRate( 44100.0 );
Stk::setRawwavePath( "../../rawwaves/" );
int i;
TickData data;
for ( i=0; i<3; i++ ) instrument[i] = 0;
RtAudioFormat format = (
sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
unsigned int bufferFrames = RT_BUFFER_SIZE;
try {
dac.
openStream( ¶meters, NULL, format, (
unsigned int)Stk::sampleRate(), &bufferFrames, &tick, (
void *)&data );
}
goto cleanup;
}
try {
for ( i=0; i<3; i++ )
}
goto cleanup;
}
for ( i=0; i<3; i++ )
data.voicer.addInstrument( instrument[i] );
if ( data.messager.startStdInput() == false )
goto cleanup;
try {
}
goto cleanup;
}
while ( !data.done )
Stk::sleep( 100 );
try {
}
}
cleanup:
for ( i=0; i<3; i++ ) delete instrument[i];
return 0;
}
unsigned long RtAudioFormat
RtAudio data format type.
Definition RtAudio.h:86
unsigned int RtAudioStreamStatus
RtAudio stream status (over- or underflow) flags.
Definition RtAudio.h:159
Exception handling class for RtAudio.
Definition RtAudio.h:220
virtual void printMessage(void) const
Prints thrown error message to stderr.
Definition RtAudio.h:243
Realtime audio i/o C++ classes.
Definition RtAudio.h:280
unsigned int getDefaultOutputDevice(void)
A function that returns the index of the default output device.
Definition RtAudio.h:860
void openStream(RtAudio::StreamParameters *outputParameters, RtAudio::StreamParameters *inputParameters, RtAudioFormat format, unsigned int sampleRate, unsigned int *bufferFrames, RtAudioCallback callback, void *userData=NULL, RtAudio::StreamOptions *options=NULL, RtAudioErrorCallback errorCallback=NULL)
A public function for opening a stream with the specified parameters.
void closeStream(void)
A function that closes a stream and frees any associated stream memory.
Definition RtAudio.h:861
void startStream(void)
A function that starts a stream.
Definition RtAudio.h:862
STK Hammond-oid organ FM synthesis instrument.
Definition BeeThree.h:43
STK instrument abstract base class.
Definition Instrmnt.h:20
STK input control message parser.
Definition Messager.h:56
STK error handling class.
Definition Stk.h:87
STK voice manager class.
Definition Voicer.h:35
The STK namespace.
Definition ADSR.h:6
The structure for specifying input or output stream parameters.
Definition RtAudio.h:313
unsigned int nChannels
Definition RtAudio.h:315
unsigned int deviceId
Definition RtAudio.h:314
A message structure to store and pass parsed SKINI messages.
Definition Skini.h:43