Home   Information   Classes   Download   Usage   Mail List   Requirements   Links   FAQ   Tutorial


Instruments

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.

// bethree.cpp STK tutorial program
#include "BeeThree.h"
#include "RtAudio.h"
using namespace stk;
// The TickData structure holds all the class instances and data that
// are shared by the various processing functions.
struct TickData {
Instrmnt *instrument;
StkFloat frequency;
StkFloat scaler;
long counter;
bool done;
// Default constructor.
TickData()
: instrument(0), scaler(1.0), counter(0), done( false ) {}
};
// This tick() function handles sample computation only. It will be
// called automatically when the system needs a new buffer of audio
// samples.
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()
{
// Set the global sample rate and rawwave path before creating class instances.
Stk::setSampleRate( 44100.0 );
Stk::setRawwavePath( "../../rawwaves/" );
TickData data;
RtAudio dac;
// Figure out how many bytes in an StkFloat and setup the RtAudio stream.
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( &parameters, NULL, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick, (void *)&data );
}
catch ( RtAudioError& error ) {
error.printMessage();
goto cleanup;
}
try {
// Define and load the BeeThree instrument
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;
}
// Block waiting until callback signals done.
while ( !data.done )
Stk::sleep( 100 );
// Shut down the callback and output stream.
try {
dac.closeStream();
}
catch ( RtAudioError &error ) {
error.printMessage();
}
cleanup:
delete data.instrument;
return 0;
}

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]

RtAudioFormat
unsigned long RtAudioFormat
RtAudio data format type.
Definition: RtAudio.h:86
RtAudioError
Exception handling class for RtAudio.
Definition: RtAudio.h:219
RtAudio::openStream
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.
RtAudioError::printMessage
virtual void printMessage(void) const
Prints thrown error message to stderr.
Definition: RtAudio.h:243
RtAudio::getDefaultOutputDevice
unsigned int getDefaultOutputDevice(void)
A function that returns the index of the default output device.
Definition: RtAudio.h:873
stk::Stk::sleep
static void sleep(unsigned long milliseconds)
Static cross-platform method to sleep for a number of milliseconds.
stk::Stk::setRawwavePath
static void setRawwavePath(std::string path)
Static method that sets the STK rawwave path.
stk::Stk::sampleRate
static StkFloat sampleRate(void)
Static method that returns the current STK sample rate.
Definition: Stk.h:145
stk::Stk::setSampleRate
static void setSampleRate(StkFloat rate)
Static method that sets the STK sample rate.
RtAudio::closeStream
void closeStream(void)
A function that closes a stream and frees any associated stream memory.
Definition: RtAudio.h:874
RtAudio::StreamParameters::nChannels
unsigned int nChannels
Definition: RtAudio.h:320
RtAudio::startStream
void startStream(void)
A function that starts a stream.
Definition: RtAudio.h:875
stk::BeeThree
STK Hammond-oid organ FM synthesis instrument.
Definition: BeeThree.h:42
stk
The STK namespace.
Definition: ADSR.h:6
stk::Instrmnt
STK instrument abstract base class.
Definition: Instrmnt.h:19
RtAudioStreamStatus
unsigned int RtAudioStreamStatus
RtAudio stream status (over- or underflow) flags.
Definition: RtAudio.h:159
RtAudio
Realtime audio i/o C++ classes.
Definition: RtAudio.h:279
RtAudio::StreamParameters
The structure for specifying input or ouput stream parameters.
Definition: RtAudio.h:318
RtAudio::StreamParameters::deviceId
unsigned int deviceId
Definition: RtAudio.h:319
RtAudio.h
stk::StkError
STK error handling class.
Definition: Stk.h:85

The Synthesis ToolKit in C++ (STK)
©1995--2019 Perry R. Cook and Gary P. Scavone. All Rights Reserved.