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 {
Voicer voicer;
Messager messager;
Skini::Message message;
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->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()
{
int i;
TickData data;
Instrmnt *instrument[3];
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 {
}
goto cleanup;
}
try {
for ( i=0; i<3; i++ )
instrument[i] = new BeeThree();
}
catch ( StkError & ) {
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 )
try {
}
}
cleanup:
for ( i=0; i<3; i++ ) delete instrument[i];
return 0;
}
unsigned int RtAudioStreamStatus
RtAudio stream status (over- or underflow) flags.
Definition: RtAudio.h:159
unsigned long RtAudioFormat
RtAudio data format type.
Definition: RtAudio.h:86
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
static void setSampleRate(StkFloat rate)
Static method that sets the STK sample rate.
static void setRawwavePath(std::string path)
Static method that sets the STK rawwave path.
static StkFloat sampleRate(void)
Static method that returns the current STK sample rate.
Definition: Stk.h:148
static void sleep(unsigned long milliseconds)
Static cross-platform method to sleep for a number of milliseconds.
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