### Compile Example Programs using Makefile Source: https://github.com/thestk/stk/blob/master/doc/doxygen/compile.txt This command illustrates how to compile tutorial and example programs using a provided Makefile. This approach is useful when working with multiple projects or upgrading STK versions, as it leverages Makefiles generated by the configure script. It simplifies the compilation process by abstracting the specific class files and linking requirements. ```bash make sineosc ``` -------------------------------- ### SKINI File Example Source: https://github.com/thestk/stk/blob/master/doc/doxygen/skini.txt A short example of a SKINI file demonstrating various message types like NoteOn, NoteOff, and StringDetune. SKINI messages are typically space-delimited and include a message name, timestamp, channel, and optional parameters. ```skini /* Howdy!!! Welcome to SKINI, by P. Cook 1999 NoteOn 0.000082 2 55 82 NoteOff 1.000000 2 55 0 NoteOn 0.000082 2 69 82 StringDetune 0.100000 2 10 StringDetune 0.100000 2 30 StringDetune 0.100000 2 50 NoteOn 0.000000 2 69 82 ``` -------------------------------- ### Example SKINI Configuration Data Source: https://github.com/thestk/stk/blob/master/doc/doxygen/skini.txt Sample configuration lines from a SKINI file, demonstrating various musical events like note on/off, string detuning, and damping. ```text StringDetune 0.100000 2 40 StringDetune 0.100000 2 22 StringDetune 0.100000 2 12 // StringDamping 0.000100 2 0.0 NoteOn 0.000082 2 55 82 NoteOn 0.200000 2 62 82 NoteOn 0.100000 2 71 82 NoteOn 0.200000 2 79 82 NoteOff 1.000000 2 55 82 NoteOff 0.000000 2 62 82 NoteOff 0.000000 2 71 82 NoteOff 0.000000 2 79 82 StringDamping =4.000000 2 0.0 NoteOn 0.000082 2 55 82 NoteOn 0.200000 2 62 82 NoteOn 0.100000 2 71 82 NoteOn 0.200000 2 79 82 NoteOff 1.000000 2 55 82 NoteOff 0.000000 2 62 82 NoteOff 0.000000 2 71 82 NoteOff 0.000000 2 79 82 ``` -------------------------------- ### BeeThree FM Synthesis Example (C++) Source: https://github.com/thestk/stk/blob/master/doc/doxygen/instruments.txt Demonstrates initializing and controlling the stk::BeeThree FM synthesis instrument. It shows how to modify the instrument's frequency over time using the setFrequency() function. This example utilizes a base Instrument pointer, allowing easy replacement with other STK instrument classes. ```cpp #include "stk/BeeThree.h" #include "stk/Stk.h" #include int main() { stk::Stk::setSampleRate(44100.0); stk::BeeThree *instrument; instrument = new stk::BeeThree; // Instrument frequency can be set directly. instrument->setFrequency(440.0); // Enters the control loop. while (1) { // Tick the global STK stuff. if (stk::Stk::testNoteOn) { instrument->noteOn(440.0, 1.0); stk::Stk::testNoteOn = false; } if (stk::Stk::testNoteOff) { instrument->noteOff(1.0); stk::Stk::testNoteOff = false; } // Return the next audio sample. std::cout << instrument->tick() << "\n"; } return 0; } ``` -------------------------------- ### Compile STK Example with Standard Include Path Source: https://github.com/thestk/stk/blob/master/doc/doxygen/compile.txt Compiles the sineosc.cpp example using g++ after modifying include statements, assuming STK header files are in a standard search path. This simplifies the compilation command by removing the need for an explicit include path. ```bash g++ -Wall -D__LITTLE_ENDIAN__ -o sineosc sineosc.cpp -lstk ``` -------------------------------- ### ControlChange vs. Volume SKINI Message Example Source: https://github.com/thestk/stk/blob/master/doc/SKINI.txt Illustrates the equivalence of ControlChange and Volume messages in SKINI, demonstrating how both can be used to change MIDI volume on a specific channel. This highlights the flexibility and design choices within the SKINI format. ```text ControlChange 0.000000 2 7 64.1 Volume 0.000000 2 64.1 ``` -------------------------------- ### STK Compilation and Configuration on Unix/MinGW Source: https://github.com/thestk/stk/blob/master/INSTALL.md Steps to compile and configure the STK library on Unix-like systems and Windows with MinGW. This involves running `autoconf`, `configure` with various options, and `make`. Options allow customization of audio/MIDI APIs, debugging, and paths. ```bash autoconf ``` ```bash tar -xzf stk-4.x.x.tar.gz ``` ```bash ./configure ``` ```bash make ``` ```bash ./configure --disable-realtime ``` ```bash ./configure --enable-debug ``` ```bash ./configure --with-alsa ``` ```bash ./configure --with-oss ``` ```bash ./configure --with-jack ``` ```bash ./configure --with-core ``` ```bash ./configure --with-asio ``` ```bash ./configure --with-ds ``` ```bash ./configure --with-wasapi ``` ```bash ./configure RAWWAVE_PATH='/home/me/rawwaves/' ``` ```bash ./configure INCLUDE_PATH='/home/me/include/' ``` ```bash ./configure CXX=CC ``` -------------------------------- ### SKINI Table Entry Examples Source: https://github.com/thestk/stk/blob/master/doc/doxygen/skini.txt Illustrates typical entries in the SKINI.tbl file, mapping message strings to internal types and specifying data field formats (SK_DBL, SK_INT). ```c++ {"NoteOff" , __SK_NoteOff_, SK_DBL, SK_DBL}, {"NoteOn" , __SK_NoteOn_, SK_DBL, SK_DBL}, ``` ```c++ {"ControlChange" , __SK_ControlChange_, SK_INT, SK_DBL}, {"Volume" , __SK_ControlChange_, __SK_Volume_ , SK_DBL}, ``` ```c++ {"StringDamping" , __SK_ControlChange_, __SK_StringDamping_, SK_DBL}, {"StringDetune" , __SK_ControlChange_, __SK_StringDetune_, SK_DBL} ``` -------------------------------- ### Install STK Library and Config Files (CMake) Source: https://github.com/thestk/stk/blob/master/CMakeLists.txt Defines the installation rules for the STK library targets and CMake configuration files. It specifies destinations for libraries, archives, executables, and public headers. ```cmake install(TARGETS ${STK_TARGETS} EXPORT stk-config LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin PUBLIC_HEADER DESTINATION include/stk) install(EXPORT stk-config DESTINATION lib/cmake/stk) ``` -------------------------------- ### SKINItbl.h Message Definitions (C) Source: https://github.com/thestk/stk/blob/master/doc/SKINI.txt Examples of message definitions from the SKINItbl.h file, showing how message strings are mapped to types and data field specifications (SK_DBL, SK_INT). ```c {"NoteOff" , __SK_NoteOff_, SK_DBL, SK_DBL}, {"NoteOn" , __SK_NoteOn_, SK_DBL, SK_DBL}, {"ControlChange" , __SK_ControlChange_, SK_INT, SK_DBL}, {"Volume" , __SK_ControlChange_, __SK_Volume_ , SK_DBL}, {"StringDamping" , __SK_ControlChange_, __SK_StringDamping_, SK_DBL}, {"StringDetune" , __SK_ControlChange_, __SK_StringDetune_, SK_DBL}, ``` -------------------------------- ### Compile STK Example with Explicit Include Path Source: https://github.com/thestk/stk/blob/master/doc/doxygen/compile.txt Compiles the sineosc.cpp example using g++, specifying the include path for STK header files and linking against the STK library. This is useful when header files are not in a standard system path. ```bash g++ -Wall -D__LITTLE_ENDIAN__ -I/usr/include/stk -o sineosc sineosc.cpp -lstk ``` -------------------------------- ### Compile Example Projects (CMake) Source: https://github.com/thestk/stk/blob/master/CMakeLists.txt Conditionally compiles various example projects associated with the STK library. This block is executed if the COMPILE_PROJECTS flag is enabled in CMake. ```cmake if(COMPILE_PROJECTS) message("COMPILE PROJECTS!") add_subdirectory(projects/examples) add_subdirectory(projects/eguitar) add_subdirectory(projects/demo) add_subdirectory(projects/effects) add_subdirectory(projects/ragamatic) endif() ``` -------------------------------- ### Example SKINI Data Assignment Source: https://github.com/thestk/stk/blob/master/doc/doxygen/skini.txt Shows the syntax for assigning values to a SKINI structure, including the message string, type, and data fields. ```text MessageStr$ ,type, data2, data3, ``` -------------------------------- ### SKINI Scorefile Example - Text-Based Control Protocol Source: https://github.com/thestk/stk/blob/master/doc/doxygen/control.txt An example of a SKINI (Synthesis ToolKit Instrument Input) scorefile. SKINI is a text-based protocol that extends MIDI, using human-readable messages and floating-point numbers. Each message includes a type, time specification, channel, and optional field values. ```text NoteOn 0.000082 2 55.0 82.3 NoteOff 1.000000 2 55.0 64.0 NoteOn 0.000082 2 69.0 82.8 StringDetune 0.100000 2 10.0 StringDetune 0.100000 2 30.0 StringDetune 0.100000 2 50.0 StringDetune 0.100000 2 40.0 StringDetune 0.100000 2 22.0 StringDetune 0.100000 2 12.0 NoteOff 1.000000 2 69.0 64.0 ``` -------------------------------- ### STK Demo Tcl/Tk GUI Control Source: https://github.com/thestk/stk/blob/master/doc/doxygen/usage.txt This example demonstrates controlling STK instruments in realtime using a Tcl/Tk graphical user interface. The Tcl script's output is piped to the stk-demo program for audio synthesis. ```bash wish < tcl/Physical.tcl | stk-demo Clarinet -or -ip ``` -------------------------------- ### Create STK Resonance Filter with BiQuad (Single Sample) Source: https://github.com/thestk/stk/blob/master/doc/doxygen/filtering.txt This example demonstrates creating a resonance filter using the stk::BiQuad class. It shows how to set the resonance frequency and gain, and then apply it to a noise generator on a sample-by-sample basis. The `setResonance` function can normalize for unity peak gain. ```cpp #include "BiQuad.h" #include "Noise.h" using namespace stk; int main() { StkFrames output( 20, 1 ); // initialize StkFrames to 20 frames and 1 channel (default: interleaved) Noise noise; BiQuad biquad; biquad.setResonance( 440.0, 0.98, true ); // automatically normalize for unity peak gain for ( unsigned int i=0; i numerator( 5, 0.1 ); // create and initialize numerator coefficients std::vector denominator; // create empty denominator coefficients denominator.push_back( 1.0 ); // populate our denomintor values denominator.push_back( 0.3 ); denominator.push_back( -0.5 ); Iir filter( numerator, denominator ); filter.tick( output ); for ( unsigned int i=0; itick() ); } tempDouble3 = message.floatValues[1] * NORM_MIDI; if ( message.type == __SK_NoteOn_ ) { if ( tempDouble3 == 0.0 ) { tempDouble3 = 0.5; instrument->noteOff( tempDouble3 ); } else { tempLong = message.intValues[0]; tempDouble2 = Midi2Pitch[tempLong]; instrument->noteOn( tempDouble2, tempDouble3 ); } } else if ( message.type == __SK_NoteOff_ ) { instrument->noteOff( tempDouble3 ); } else if ( message.type == __SK_ControlChange_ ) { tempLong = message.intValues[0]; instrument->controlChange( tempLong, tempDouble3 ); } } ``` -------------------------------- ### Generate Multiple Sine Waves and Output to WAV File Source: https://context7.com/thestk/stk/llms.txt This C++ example demonstrates generating audio from multiple SineWave oscillators with varying frequencies and writing the combined output to a WAV file using FileWvOut. It handles setting the sample rate, preparing an StkFrames buffer, and includes error handling for file operations. ```cpp #include "SineWave.h" #include "FileWvOut.h" #include using namespace stk; int main(int argc, char* argv[]) { float baseFreq = 220.0; int channels = 3; double time = 5.0; // 5 seconds double sampleRate = 44100.0; // Set global sample rate BEFORE creating objects Stk::setSampleRate(sampleRate); // Create sine wave oscillators SineWave** oscs = new SineWave*[channels]; for (int i = 0; i < channels; i++) { oscs[i] = new SineWave(); oscs[i]->setFrequency(baseFreq + i * 45.0); } // Prepare output buffer long nFrames = (long)(time * Stk::sampleRate()); StkFrames frames(nFrames, channels); // Generate audio (all samples at once per channel) for (int i = 0; i < channels; i++) { oscs[i]->tick(frames, i); } // Write to file FileWvOut output; try { // Supported types: FILE_WAV, FILE_SND, FILE_AIF, FILE_MAT, FILE_RAW // Supported formats: STK_SINT8, STK_SINT16, STK_INT24, STK_SINT32, // STK_FLOAT32, STK_FLOAT64 output.openFile("output.wav", channels, FileWrite::FILE_WAV, Stk::STK_SINT16); output.tick(frames); output.closeFile(); } catch (StkError& error) { error.printMessage(); } // Cleanup for (int i = 0; i < channels; i++) { delete oscs[i]; } delete[] oscs; return 0; } ``` -------------------------------- ### STK Dynamic RAWWAVE Path Setting (C++) Source: https://github.com/thestk/stk/blob/master/INSTALL.md Dynamically change the RAWWAVE path at runtime within a C++ project using the STK library. This function allows flexibility in specifying the location of raw wave data files. ```cpp Stk::setRawwavePath("/new/path/to/rawwaves/"); ``` -------------------------------- ### CMake Project Setup and C++ Standard Source: https://github.com/thestk/stk/blob/master/CMakeLists.txt Initializes the CMake build system for the STK project, setting the minimum required version and the C++ standard to C++11. It also configures the module path for CMake modules. ```cmake cmake_minimum_required(VERSION 3.1) project(STK VERSION 4.6.1) set (CMAKE_CXX_STANDARD 11) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) ``` -------------------------------- ### STK Demo Polyphony Control Source: https://github.com/thestk/stk/blob/master/doc/doxygen/usage.txt This example shows how to configure the stk-demo program to support multiple voices (polyphony). The -n flag specifies the number of simultaneous instruments to play, allowing for richer textures. ```bash stk-demo BeeThree -n 8 -or -im ``` -------------------------------- ### Record Real-Time Audio to File with STK Source: https://context7.com/thestk/stk/llms.txt This C++ example shows how to record audio input from the default audio device in real-time and save it to a WAV file. It uses RtAudio for audio stream management and FileWvOut for writing to the file. The recording duration is set to 10 seconds. ```cpp #include "RtAudio.h" #include "FileWvOut.h" using namespace stk; struct RecordData { FileWvOut* output; unsigned long frameCounter; unsigned long totalFrames; bool done; RecordData() : output(0), frameCounter(0), totalFrames(0), done(false) {} }; int record(void* outputBuffer, void* inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void* userData) { RecordData* data = (RecordData*)userData; StkFloat* samples = (StkFloat*)inputBuffer; if (data->frameCounter + nBufferFrames > data->totalFrames) { nBufferFrames = data->totalFrames - data->frameCounter; data->done = true; } // Write frames to file for (unsigned int i = 0; i < nBufferFrames; i++) { data->output->tick(*samples++); // Mono } data->frameCounter += nBufferFrames; return 0; } int main() { Stk::setSampleRate(44100.0); RecordData data; data.totalFrames = 44100 * 10; // Record 10 seconds try { // Open output file FileWvOut output; output.openFile("recording.wav", 1, FileWrite::FILE_WAV, Stk::STK_SINT16); data.output = &output; // Setup audio input RtAudio adc; RtAudio::StreamParameters parameters; parameters.deviceId = adc.getDefaultInputDevice(); parameters.nChannels = 1; RtAudioFormat format = (sizeof(StkFloat) == 8) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32; unsigned int bufferFrames = RT_BUFFER_SIZE; if (adc.openStream(NULL, ¶meters, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &record, (void*)&data)) { std::cout << adc.getErrorText() << std::endl; return 1; } if (adc.startStream()) { std::cout << adc.getErrorText() << std::endl; return 1; } std::cout << "Recording..." << std::endl; // Wait until recording is done while (!data.done) { Stk::sleep(100); } adc.closeStream(); output.closeFile(); std::cout << "Recording complete!" << std::endl; } catch (StkError& error) { error.printMessage(); return 1; } return 0; } ``` -------------------------------- ### Audio Effects Processing with STK and RtAudio in C++ Source: https://context7.com/thestk/stk/llms.txt Implements a framework for applying various audio effects (Echo, Pitch Shifting, Chorus, Reverb) using STK and processing them through an RtAudio stream. This example sets up and configures effects, then integrates them into an audio callback function for real-time processing. It requires STK and RtAudio libraries. ```cpp #include "FreeVerb.h" #include "JCRev.h" #include "Echo.h" #include "Chorus.h" #include "PitShift.h" #include "RtAudio.h" using namespace stk; struct EffectsData { unsigned int effectId; // 0=Echo, 1=PitShift, 2=Chorus, 3=FreeVerb Echo echo; PitShift shifter; Chorus chorus; FreeVerb reverb; EffectsData() : effectId(0) {} }; int tick(void* outputBuffer, void* inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void* dataPointer) { EffectsData* data = (EffectsData*)dataPointer; StkFloat* oSamples = (StkFloat*)outputBuffer; StkFloat* iSamples = (StkFloat*)inputBuffer; for (unsigned int i = 0; i < nBufferFrames; i++) { StkFloat input = *iSamples++; StkFloat output; switch (data->effectId) { case 0: // Echo output = data->echo.tick(input); *oSamples++ = output; *oSamples++ = output; break; case 1: // Pitch Shift output = data->shifter.tick(input); *oSamples++ = output; *oSamples++ = output; break; case 2: // Chorus (stereo) data->chorus.tick(input); *oSamples++ = data->chorus.lastOut(0); *oSamples++ = data->chorus.lastOut(1); break; case 3: // FreeVerb (stereo) data->reverb.tick(input); *oSamples++ = data->reverb.lastOut(0); *oSamples++ = data->reverb.lastOut(1); break; } } return 0; } int main() { Stk::setSampleRate(48000.0); EffectsData data; // Configure effects data.echo.setDelay(22050); // 0.46 second delay at 48kHz data.echo.setEffectMix(0.5); // 50% wet/dry mix data.shifter.setShift(1.5); // Shift up by 1.5x data.shifter.setEffectMix(0.7); data.chorus.setModFrequency(2.0); // 2 Hz modulation data.chorus.setModDepth(0.1); data.chorus.setEffectMix(0.5); data.reverb.setRoomSize(0.8); // Large room data.reverb.setDamping(0.5); // Medium damping data.reverb.setEffectMix(0.3); // 30% reverb // Setup duplex audio stream (input and output) RtAudio adac; RtAudioFormat format = (sizeof(StkFloat) == 8) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32; RtAudio::StreamParameters oparams, iparams; oparams.deviceId = adac.getDefaultOutputDevice(); oparams.nChannels = 2; // Stereo output iparams.deviceId = adac.getDefaultInputDevice(); iparams.nChannels = 1; // Mono input unsigned int bufferFrames = RT_BUFFER_SIZE; if (adac.openStream(&oparams, &iparams, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick, (void*)&data)) { std::cout << adac.getErrorText() << std::endl; return 1; } if (adac.startStream()) { std::cout << adac.getErrorText() << std::endl; return 1; } std::cout << "Processing audio... press Enter to quit" << std::endl; std::cin.get(); adac.closeStream(); return 0; } ``` -------------------------------- ### C++ Control Input Handling with stk::Messager Source: https://github.com/thestk/stk/blob/master/doc/doxygen/control.txt A C++ code snippet demonstrating the use of the stk::Messager class to handle control input. This example modifies a program to accept SKINI messages from a file, showcasing asynchronous message acquisition and retrieval using popMessage(). ```cpp #include "stk/Messager.h" #include "stk/Skini.h" #include "SineWave.h" #include #include // Assume SineWave and other necessary STK classes are defined elsewhere // For demonstration purposes, let's create a placeholder class SineWave { public: void tick() { /* placeholder */ } void noteOn(int note, float velocity) { /* placeholder */ } void noteOff(int note) { /* placeholder */ } void setFrequency(float freq) { /* placeholder */ } }; const int DELTA_CONTROL_TICKS = 10; int main(int argc, char **argv) { SineWave s; stk::Messager messager; if (argc < 2) { std::cerr << "Usage: " << argv[0] << " \n"; return 1; } // Start input from a SKINI scorefile messager.startScoreFile(argv[1]); stk::Skini::Message msg; int tickCount = 0; // Main control loop while (true) { // Check for new messages msg = messager.popMessage(); if (msg.type != 0) { // Process the message switch (msg.type) { case stk::Skini::NoteOn: s.noteOn(msg.id, msg.value); break; case stk::Skini::NoteOff: s.noteOff(msg.id); break; case stk::Skini::ControlChange: // Example: set frequency based on control change if (msg.id == 1) { // Assuming control change 1 controls frequency // Convert MIDI note number to frequency float freq = stk::midi2Frequency(msg.value); s.setFrequency(freq); } break; // Add more cases for other SKINI message types as needed default: // Ignore unknown message types break; } tickCount = 0; // Reset tick counter when a message is processed } else { // No message available, increment tick counter tickCount++; if (tickCount >= DELTA_CONTROL_TICKS) { // Periodically tick the instrument even if no control message is available // This is a simple way to keep the sound going or allow for timed events // In a real application, you might tick based on time rather than count s.tick(); tickCount = 0; } } // In a real application, you would also call s.tick() here to generate audio // and potentially check for other non-control related events. // For simplicity, audio generation is omitted. // A mechanism to break the loop would be needed in a real application, // e.g., checking for a specific end-of-score message or a user interrupt. // For this example, we'll assume the scorefile will eventually end and popMessage will return 0 indefinitely. // A more robust loop termination condition is recommended. } return 0; } ``` -------------------------------- ### Compile Sine Oscillator on Linux (Little-Endian) Source: https://github.com/thestk/stk/blob/master/doc/doxygen/compile.txt This example demonstrates compiling a simple program (sineosc.cpp) that does not use realtime audio or MIDI. It requires including STK class files and is intended for little-endian systems like a PC running Linux. The compilation uses g++ with specific flags to enable warnings and define the endianness. ```bash g++ -Wall -D__LITTLE_ENDIAN__ -o sineosc Stk.cpp FileRead.cpp FileWrite.cpp FileWvIn.cpp FileLoop.cpp FileWvOut.cpp sineosc.cpp ``` -------------------------------- ### Installing Headers Source: https://github.com/thestk/stk/blob/master/CMakeLists.txt This CMake snippet conditionally installs header files from the 'include' directory to the 'include/stk' destination. The installation is controlled by the `INSTALL_HEADERS` option, ensuring headers are only installed when this option is enabled. ```cmake if(INSTALL_HEADERS) file(GLOB STK_HEADERS "include/*.h") install(FILES ${STK_HEADERS} DESTINATION include/stk) endif() ``` -------------------------------- ### STK Demo Program Usage Help Source: https://github.com/thestk/stk/blob/master/doc/doxygen/usage.txt Invoking the stk-demo program without any arguments will display a comprehensive usage description, listing all available instruments and command-line flags. ```bash stk-demo ``` -------------------------------- ### Configure Global STK Settings and Initialize Source: https://context7.com/thestk/stk/llms.txt Sets the global sample rate and rawwave path before creating any STK objects. It also demonstrates how to query the current sample rate and includes basic error handling for STK exceptions. ```cpp #include "Stk.h" using namespace stk; int main() { // IMPORTANT: Set sample rate BEFORE creating any STK objects Stk::setSampleRate(44100.0); // Set the path to rawwave files (required for some instruments) Stk::setRawwavePath("../../rawwaves/"); // Query the current sample rate StkFloat currentRate = Stk::sampleRate(); try { // Create STK objects here... } catch (StkError& error) { error.printMessage(); return 1; } return 0; } ``` -------------------------------- ### Create STK Resonance Filter with BiQuad (Vector) Source: https://github.com/thestk/stk/blob/master/doc/doxygen/filtering.txt This snippet illustrates how to use the stk::BiQuad class for resonance filtering in a vector-based manner. It's a modification of the single-sample example, showing how to process multiple frames at once for efficiency. The filter is initialized with a specific resonance frequency and gain. ```cpp #include "BiQuad.h" #include "Noise.h" using namespace stk; int main() { StkFrames output( 20, 1 ); // initialize StkFrames to 20 frames and 1 channel (default: interleaved) Noise noise; BiQuad biquad; biquad.setResonance( 440.0, 0.98, true ); // automatically normalize for unity peak gain biquad.tick( noise.tick( output ) ); // vector-based computations for ( unsigned int i=0; i #include int main() { // Set the global sample rate stk::Stk::setSampleRate(44100.0); // Create a Voicer to manage three voices stk::Voicer voicer; voicer.setVoiceCount(3); // Create three BeeThree instruments and add them to the Voicer for (int i = 0; i < 3; i++) { stk::BeeThree *bee = new stk::BeeThree; voicer.addVoice(bee); } // Set up SKINI for parsing score files stk::SKINI skini; skini.open("scores/bachfugue.ski"); // Process score file events while (skini.tick()) { // If a SKINI event is ready, pass it to the Voicer if (skini.isNoteOn()) voicer.noteOn(skini.getNoteNumber(), skini.getVelocity()); else if (skini.isNoteOff()) voicer.noteOff(skini.getNoteNumber()); else if (skini.isPitchBend()) voicer.pitchBend(skini.getPitchBend()); else if (skini.isControlChange()) voicer.controlChange(skini.getControllerNumber(), skini.getControlValue()); // Get the summed output from the Voicer std::vector samples(voicer.getSamplesPerBlock()); voicer.tick(samples.data()); // In a real application, you would output these samples to an audio device // For this example, we'll just print a message indicating processing // std::cout << "."; // std::cout.flush(); } std::cout << std::endl; // Clean up instruments (Voicer does not own them) for (int i = 0; i < 3; i++) { delete voicer.voices()[i]; } return 0; } ``` -------------------------------- ### Finding JACK Audio Library with PkgConfig and Fallback Source: https://github.com/thestk/stk/blob/master/CMakeLists.txt This snippet demonstrates how to find the JACK audio library using PkgConfig. If PkgConfig is not found or fails, it falls back to searching common system locations for the JACK headers and libraries. It sets up necessary include directories and libraries if JACK is found. ```cmake find_package(PkgConfig QUIET) if(PkgConfig_FOUND) # PkgConfig is available, use it pkg_check_modules(JACK QUIET jack) endif() if(NOT JACK_FOUND) # PkgConfig was not found or Jack was not found through it, try a fallback message(STATUS "PkgConfig not found or failed to find Jack, attempting fallback") # Fallback: Search in common locations find_path(JACK_INCLUDE_DIR NAMES jack/jack.h HINTS ENV JACK_ROOT "$ENV{ProgramFiles}/Jack" /usr/local/include /usr/include ) find_library(JACK_LIBRARY NAMES jack HINTS ENV JACK_ROOT "$ENV{ProgramFiles}/Jack" /usr/local/lib /usr/lib ) # Check if the fallback was successful if(JACK_INCLUDE_DIR AND JACK_LIBRARY) set(JACK_FOUND TRUE) set(JACK_INCLUDE_DIRS ${JACK_INCLUDE_DIR}) set(JACK_LIBRARIES ${JACK_LIBRARY}) message(STATUS "Found Jack (fallback):") message(STATUS " Includes: ${JACK_INCLUDE_DIRS}") message(STATUS " Libraries: ${JACK_LIBRARIES}") else() message(WARNING "Failed to find Jack library even with fallback. Please install Jack development package or ensure it is in a standard location.") endif() endif() if(JACK_FOUND) include_directories(${JACK_INCLUDE_DIRS}) link_libraries(${JACK_LIBRARIES}) add_definitions(-D__UNIX_JACK__) endif() ``` -------------------------------- ### Sine Wave Oscillator using STK FileLoop and FileWvOut (C++) Source: https://github.com/thestk/stk/blob/master/doc/doxygen/hello.txt This C++ code snippet demonstrates how to create a sine wave oscillator using the STK library. It utilizes FileLoop to load a sine wave from a raw file and FileWvOut to write the generated audio to a WAV file. The global sample rate must be set before creating STK class instances. ```cpp // sineosc.cpp #include "FileLoop.h" #include "FileWvOut.h" using namespace stk; int main() { // Set the global sample rate before creating class instances. Stk::setSampleRate( 44100.0 ); FileLoop input; FileWvOut output; // Load the sine wave file. input.openFile( "rawwaves/sinewave.raw", true ); // Open a 16-bit, one-channel WAV formatted output file output.openFile( "hellosine.wav", 1, FileWrite::FILE_WAV, Stk::STK_SINT16 ); input.setFrequency( 440.0 ); // Run the oscillator for 40000 samples, writing to the output file for ( int i=0; i<40000; i++ ) output.tick( input.tick() ); return 0; } ``` -------------------------------- ### Linux ALSA Audio Support Configuration Source: https://github.com/thestk/stk/blob/master/CMakeLists.txt This CMake snippet configures support for the ALSA (Advanced Linux Sound Architecture) audio API on Linux systems. It requires the ALSA development package to be installed and uses `find_package` to locate its components, subsequently including directories and linking libraries. ```cmake if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) message("Linux DETECTED!") if(ENABLE_ALSA) find_package(ALSA REQUIRED) if(ALSA_FOUND) include_directories(${ALSA_INCLUDE_DIRS}) link_libraries(${ALSA_LIBRARIES}) add_definitions(-D__LINUX_ALSA__) endif() endif() endif() ```