The ToolKit comes with a wide variety of synthesis algorithms, all of which inherit from the stk::Instrmnt class. In this example, we'll fire up an instance of the stk::BeeThree FM synthesis class and show how its frequency can be modified over time.
#include "BeeThree.h"
#include "RtAudio.h"
struct TickData {
Instrmnt *instrument;
StkFloat frequency;
StkFloat scaler;
long counter;
bool done;
TickData()
: instrument(0), scaler(1.0), counter(0), done( false ) {}
};
int tick( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
double streamTime, RtAudioStreamStatus status, void *userData )
{
TickData *data = (TickData *) userData;
register StkFloat *samples = (StkFloat *) outputBuffer;
for ( unsigned int i=0; i<nBufferFrames; i++ ) {
*samples++ = data->instrument->tick();
if ( ++data->counter % 2000 == 0 ) {
data->scaler += 0.025;
data->instrument->setFrequency( data->frequency * data->scaler );
}
}
if ( data->counter > 80000 )
data->done = true;
return 0;
}
int main()
{
TickData data;
RtAudio dac;
RtAudio::StreamParameters parameters;
parameters.deviceId = dac.getDefaultOutputDevice();
parameters.nChannels = 1;
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 );
}
catch ( RtAudioError& error ) {
error.printMessage();
goto cleanup;
}
try {
data.instrument = new BeeThree();
}
catch ( StkError & ) {
goto cleanup;
}
data.frequency = 220.0;
data.instrument->noteOn( data.frequency, 0.5 );
try {
dac.startStream();
}
catch ( RtAudioError &error ) {
error.printMessage();
goto cleanup;
}
while ( !data.done )
try {
dac.closeStream();
}
catch ( RtAudioError &error ) {
error.printMessage();
}
cleanup:
delete data.instrument;
return 0;
}
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
We have used an Instrmnt pointer when referencing the BeeThree instance above, so it would be simple to replace the BeeThree class with any other STK instrument class. It should be noted, however, that a few classes do not respond to the setFrequency() function (e.g., Shakers, Drummer).
The noteOn() function initiates an instrument attack. Instruments that are continuously excited (e.g., stk::Clarinet, stk::BeeThree) will continue to sound until stopped with a noteOff(). Impulsively excited instrument sounds (e.g., stk::Plucked, stk::Wurley) typically decay within a few seconds time, requiring subsequent noteOn() messages for re-attack.
Instrument parameters can be precisely controlled as demonstrated above. A more flexible approach to instrument control, allowing arbitrary scorefile or realtime updates, is described in the next tutorial chapter.
[Main tutorial page] [Next tutorial]