mirror of
https://github.com/thestk/stk
synced 2026-04-19 22:16:54 +00:00
Version 4.2.0
This commit is contained in:
committed by
Stephen Sinclair
parent
cf06b7598b
commit
a6381b9d38
1
projects/demo/Drums
Executable file
1
projects/demo/Drums
Executable file
@@ -0,0 +1 @@
|
||||
wish < tcl/Drums.tcl | ./demo Drummer -or -ip
|
||||
@@ -6,14 +6,14 @@ SRC_PATH = ../../src
|
||||
OBJECT_PATH = @object_path@
|
||||
vpath %.o $(OBJECT_PATH)
|
||||
|
||||
OBJECTS = Stk.o Noise.o SubNoise.o Envelope.o ADSR.o \
|
||||
OBJECTS = Stk.o Generator.o Noise.o SubNoise.o Envelope.o ADSR.o \
|
||||
Modulate.o SingWave.o \
|
||||
WvIn.o WaveLoop.o WvOut.o \
|
||||
Filter.o OneZero.o OnePole.o PoleZero.o TwoZero.o \
|
||||
BiQuad.o FormSwep.o Delay.o DelayL.o DelayA.o \
|
||||
ReedTabl.o JetTabl.o BowTabl.o \
|
||||
Reverb.o PRCRev.o \
|
||||
Modulate.o SingWave.o Voicer.o \
|
||||
Vector3D.o Sphere.o \
|
||||
Function.o ReedTable.o JetTable.o BowTable.o \
|
||||
Effect.o PRCRev.o \
|
||||
Voicer.o Vector3D.o Sphere.o \
|
||||
\
|
||||
Instrmnt.o Clarinet.o BlowHole.o Saxofony.o Flute.o Brass.o BlowBotl.o \
|
||||
Bowed.o Plucked.o StifKarp.o Sitar.o PluckTwo.o Mandolin.o Mesh2D.o \
|
||||
@@ -21,7 +21,7 @@ OBJECTS = Stk.o Noise.o SubNoise.o Envelope.o ADSR.o \
|
||||
Sampler.o Moog.o Simple.o Drummer.o Shakers.o \
|
||||
Modal.o ModalBar.o BandedWG.o Resonate.o VoicForm.o Phonemes.o Whistle.o \
|
||||
\
|
||||
Messager.o SKINI.o utilities.o
|
||||
Messager.o Skini.o utilities.o
|
||||
|
||||
INCLUDE = @include@
|
||||
ifeq ($(strip $(INCLUDE)), )
|
||||
@@ -39,9 +39,8 @@ LIBRARY += @frameworks@
|
||||
|
||||
REALTIME = @realtime@
|
||||
ifeq ($(REALTIME),yes)
|
||||
OBJECTS += RtMidi.o RtAudio.o RtWvOut.o Thread.o Socket.o
|
||||
OBJECTS += RtMidi.o RtAudio.o Thread.o Mutex.o Socket.o
|
||||
DEFS += @audio_apis@
|
||||
DEFS += @midiator@
|
||||
endif
|
||||
|
||||
RAWWAVES = @rawwaves@
|
||||
@@ -58,8 +57,14 @@ all : $(PROGRAMS)
|
||||
demo: demo.cpp $(OBJECTS)
|
||||
$(CC) $(CFLAGS) $(DEFS) -o demo demo.cpp $(OBJECT_PATH)/*.o $(LIBRARY)
|
||||
|
||||
Md2Skini: Md2Skini.cpp Stk.o RtMidi.o Thread.o Socket.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o Md2Skini Md2Skini.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/RtMidi.o $(OBJECT_PATH)/Thread.o $(OBJECT_PATH)/Socket.o $(LIBRARY)
|
||||
libdemo: demo.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -o demo utilities.cpp demo.cpp -L../../src $(LIBRARY) -lstk
|
||||
|
||||
Md2Skini: Md2Skini.cpp Stk.o RtMidi.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o Md2Skini Md2Skini.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
|
||||
|
||||
libMd2Skini: Md2Skini.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -o Md2Skini Md2Skini.cpp -L../../src $(LIBRARY) -lstk
|
||||
|
||||
$(OBJECTS) : Stk.h
|
||||
|
||||
|
||||
@@ -6,71 +6,171 @@
|
||||
(via the RtMidi class), parses it, and turns it
|
||||
into SKINI messages.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "RtMidi.h"
|
||||
#include "Thread.h"
|
||||
#include "Socket.h"
|
||||
#include "SKINI.msg"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Exit thread declaration.
|
||||
extern "C" THREAD_RETURN THREAD_TYPE stdinMonitor(void * ptr);
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
void usage(void) {
|
||||
printf("\nuseage: Md2Skini <flag(s)>\n\n");
|
||||
printf(" With no arguments, Md2Skini converts MIDI input to SKINI\n");
|
||||
printf(" format and sends the output directly to stdout.\n");
|
||||
printf(" With flag = -s <hostname>, the output is sent over a socket\n");
|
||||
printf(" connection (port 2001) to the optional hostname (default = localhost).\n");
|
||||
printf(" With flag = -f <filename>, the output stream is simultaneously\n");
|
||||
printf(" written to the file specified by the optional <filename>\n");
|
||||
printf(" (default = test.ski).\n\n");
|
||||
std::cout << "\nuseage: Md2Skini <flag(s)>\n\n";
|
||||
std::cout << " With no arguments, Md2Skini converts MIDI input to SKINI\n";
|
||||
std::cout << " format and sends the output directly to stdout.\n";
|
||||
std::cout << " With flag = -f <filename>, the output stream is simultaneously\n";
|
||||
std::cout << " written to the file specified by the optional <filename>\n";
|
||||
std::cout << " (default = test.ski).\n";
|
||||
std::cout << " A MIDI input port can be specified with flag = -p portNumber.\n" << std::endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
void midiCallback( double deltatime, std::vector< unsigned char > *bytes, void *userData )
|
||||
{
|
||||
bool done = false, firstMessage = true, writeFile = false, useSocket = false;
|
||||
FILE *file = NULL;
|
||||
char fileName[256];
|
||||
char hostName[128];
|
||||
RtMidi *rtmidi = 0;
|
||||
Socket *soket = 0;
|
||||
Thread *thread = 0;
|
||||
if ( bytes->size() < 2 ) return;
|
||||
|
||||
if ( argc>5 ) {
|
||||
usage();
|
||||
// Parse the MIDI bytes ... only keep MIDI channel messages.
|
||||
if ( bytes->at(0) > 239 ) return;
|
||||
|
||||
register long type = bytes->at(0) & 0xF0;
|
||||
register long channel = bytes->at(0) & 0x0F;
|
||||
register long databyte1 = bytes->at(1);
|
||||
register long databyte2 = 0;
|
||||
if ( ( type != 0xC0 ) && ( type != 0xD0 ) ) {
|
||||
if ( bytes->size() < 3 ) return;
|
||||
databyte2 = bytes->at(2);
|
||||
}
|
||||
|
||||
std::string typeName;
|
||||
switch( type ) {
|
||||
case __SK_NoteOn_:
|
||||
if ( databyte2 == 0 ) {
|
||||
typeName = "NoteOff\t\t";
|
||||
databyte2 = 64;
|
||||
}
|
||||
else typeName = "NoteOn\t\t";
|
||||
break;
|
||||
|
||||
case __SK_NoteOff_:
|
||||
typeName = "NoteOff\t\t";
|
||||
break;
|
||||
|
||||
case __SK_PolyPressure_:
|
||||
typeName = "PolyPressure\t";
|
||||
break;
|
||||
|
||||
case __SK_ProgramChange_:
|
||||
typeName = "ProgramChange\t";
|
||||
break;
|
||||
|
||||
case __SK_ChannelPressure_:
|
||||
typeName = "ChannelPressure\t";
|
||||
break;
|
||||
|
||||
case __SK_PitchBend_:
|
||||
typeName = "PitchBend\t";
|
||||
break;
|
||||
|
||||
case __SK_ControlChange_:
|
||||
|
||||
switch( databyte1 ) {
|
||||
case __SK_PitchChange_:
|
||||
typeName = "PitchChange\t";
|
||||
break;
|
||||
|
||||
case __SK_Volume_:
|
||||
typeName = "Volume\t";
|
||||
break;
|
||||
|
||||
case __SK_ModWheel_:
|
||||
typeName = "ModWheel\t";
|
||||
break;
|
||||
|
||||
case __SK_Breath_:
|
||||
typeName = "Breath\t\t";
|
||||
break;
|
||||
|
||||
case __SK_FootControl_:
|
||||
typeName = "FootControl\t";
|
||||
break;
|
||||
|
||||
case __SK_Portamento_:
|
||||
typeName = "Portamento\t";
|
||||
break;
|
||||
|
||||
case __SK_Balance_:
|
||||
typeName = "Balance\t";
|
||||
break;
|
||||
|
||||
case __SK_Pan_:
|
||||
typeName = "Pan\t\t";
|
||||
break;
|
||||
|
||||
case __SK_Sustain_:
|
||||
typeName = "Sustain\t";
|
||||
break;
|
||||
|
||||
case __SK_Expression_:
|
||||
typeName = "Expression\t";
|
||||
break;
|
||||
|
||||
default:
|
||||
typeName = "ControlChange\t";
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
typeName = "Unknown\t";
|
||||
}
|
||||
|
||||
FILE *file = (FILE *) userData;
|
||||
if ( type == 0xC0 || type == 0xD0 || type == 0xE0 ) { // program change, channel pressure, or pitchbend
|
||||
fprintf( stdout, "%s %.3f %d %.1f\n", typeName.c_str(), 0.0, channel, (float)databyte1 );
|
||||
if ( file != NULL )
|
||||
fprintf( file, "%s %.3f %d %.1f\n", typeName.c_str(), deltatime, channel, (float)databyte1 );
|
||||
}
|
||||
else if ( type == 0xB0 ) { // control change
|
||||
fprintf( stdout, "%s %.3f %d %.1f\n", typeName.c_str(), 0.0, channel, (float)databyte2 );
|
||||
if ( file != NULL )
|
||||
fprintf( file, "%s %.3f %d %.1f\n", typeName.c_str(), deltatime, channel, (float)databyte2 );
|
||||
}
|
||||
else { // noteon, noteoff, aftertouch, and unknown
|
||||
fprintf( stdout, "%s %.3f %d %.1f %.1f\n", typeName.c_str(), 0.0, channel, (float)databyte1, (float)databyte2 );
|
||||
if ( file != NULL )
|
||||
fprintf( file, "%s %.3f %d %.1f %.1f\n", typeName.c_str(), deltatime, channel, (float)databyte1, (float)databyte2 );
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc,char *argv[] )
|
||||
{
|
||||
FILE *file = NULL;
|
||||
std::string fileName;
|
||||
RtMidiIn *midiin = 0;
|
||||
unsigned int port = 0;
|
||||
|
||||
if ( argc > 5 ) usage();
|
||||
|
||||
// Parse the command-line arguments.
|
||||
int i = 1;
|
||||
while (i < argc) {
|
||||
while ( i < argc ) {
|
||||
if (argv[i][0] == '-') {
|
||||
switch(argv[i][1]) {
|
||||
|
||||
case 's':
|
||||
if ((i+1 < argc) && argv[i+1][0] != '-') {
|
||||
i++;
|
||||
strncpy(hostName, argv[i], 128);
|
||||
}
|
||||
else strcpy(hostName, "localhost");
|
||||
useSocket = true;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if ((i+1 < argc) && argv[i+1][0] != '-') {
|
||||
if ( (i+1 < argc) && argv[i+1][0] != '-' ) {
|
||||
i++;
|
||||
strncpy(fileName, argv[i], 252);
|
||||
if ( strstr(fileName,".ski") == NULL ) strcat(fileName, ".ski");
|
||||
fileName = argv[i];
|
||||
if ( fileName.find( ".ski" ) == std::string::npos ) fileName.append( ".ski" );
|
||||
}
|
||||
else strcpy(fileName, "test.ski");
|
||||
file = fopen(fileName,"wb");
|
||||
writeFile = true;
|
||||
else fileName = "test.ski";
|
||||
file = fopen( fileName.c_str(), "wb" );
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if ( i++ >= argc) usage();
|
||||
port = (unsigned int) atoi( argv[i] );
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -82,234 +182,51 @@ int main(int argc,char *argv[])
|
||||
i++;
|
||||
}
|
||||
|
||||
MY_FLOAT dt=0.0;
|
||||
try {
|
||||
rtmidi = new RtMidi();
|
||||
midiin = new RtMidiIn();
|
||||
}
|
||||
catch (StkError &) {
|
||||
exit(0);
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
if ( file != NULL ) fclose( file );
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// If using sockets, setup the client socket
|
||||
if (useSocket) {
|
||||
try {
|
||||
soket = new Socket( 2001, hostName );
|
||||
}
|
||||
catch (StkError &) {
|
||||
exit(0);
|
||||
}
|
||||
// Check available ports vs. specified.
|
||||
unsigned int nPorts = midiin->getPortCount();
|
||||
if ( nPorts == 0 ) {
|
||||
std::cout << "No MIDI ports available!\n";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Start the "exit" thread.
|
||||
thread = new Thread();
|
||||
if ( !thread->start( (THREAD_FUNCTION)&stdinMonitor, (void *) &done ) ) {
|
||||
fprintf(stderr, "Unable to create exit thread ... aborting.\n");
|
||||
else if ( port >= nPorts ) {
|
||||
std::cout << "Invalid port specifier!\n";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Write SKINI messages to buffer 's'. This is the easiest way to
|
||||
// allow this single executable to work for both socketing and
|
||||
// printf's to stdout.
|
||||
char s[128];
|
||||
int channel, j;
|
||||
MY_FLOAT byte2, byte3;
|
||||
while ( !done ) {
|
||||
if (rtmidi->nextMessage() > 0) {
|
||||
byte3 = rtmidi->getByteThree();
|
||||
byte2 = rtmidi->getByteTwo();
|
||||
channel = rtmidi->getChannel();
|
||||
if (writeFile) dt = rtmidi->getDeltaTime();
|
||||
if (firstMessage) { // first MIDI message time stamp is meaningless
|
||||
dt = 0.0;
|
||||
firstMessage = false;
|
||||
}
|
||||
|
||||
switch(rtmidi->getType()) {
|
||||
case __SK_NoteOn_:
|
||||
if (byte3 < 1.0) {
|
||||
sprintf(s,"NoteOff\t\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,64.0);
|
||||
if (writeFile) {
|
||||
fprintf(file,"NoteOff\t\t%.3f %d %.1f %.1f\n",dt,channel,byte2,64.0);
|
||||
}
|
||||
} else {
|
||||
sprintf(s,"NoteOn\t\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"NoteOn\t\t%.3f %d %.1f %.1f\n",dt,channel,byte2,byte3);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case __SK_NoteOff_:
|
||||
if (byte3 < 2.0) byte3 = 64.0;
|
||||
sprintf(s,"NoteOff\t\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"NoteOff\t\t%.3f %d %.1f %.1f\n",dt,channel,byte2,byte3);
|
||||
}
|
||||
break;
|
||||
|
||||
case __SK_PolyPressure_:
|
||||
sprintf(s,"PolyPressure\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"PolyPressure\t%.3f %d %.1f %.1f\n",dt,channel,byte2,byte3);
|
||||
}
|
||||
break;
|
||||
|
||||
case __SK_ControlChange_:
|
||||
j = (int) byte2;
|
||||
switch(j) {
|
||||
case __SK_PitchChange_:
|
||||
sprintf(s,"PitchChange\t%.3f %d %.1f\n",0.0,channel,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"PitchChange\t%.3f %d %.1f\n",dt,channel,byte3);
|
||||
}
|
||||
break;
|
||||
case __SK_Volume_:
|
||||
sprintf(s,"Volume\t%.3f %d %.1f\n",0.0,channel,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"Volume\t%.3f %d %.1f\n",dt,channel,byte3);
|
||||
}
|
||||
break;
|
||||
case __SK_ModWheel_:
|
||||
sprintf(s,"ModWheel\t%.3f %d %.1f\n",0.0,channel,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"ModWheel\t%.3f %d %.1f\n",dt,channel,byte3);
|
||||
}
|
||||
break;
|
||||
case __SK_Breath_:
|
||||
sprintf(s,"Breath\t\t%.3f %d %.1f\n",0.0,channel,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"Breath\t\t%.3f %d %.1f\n",dt,channel,byte3);
|
||||
}
|
||||
break;
|
||||
case __SK_FootControl_:
|
||||
sprintf(s,"FootControl\t%.3f %d %.1f\n",0.0,channel,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"FootControl\t%.3f %d %.1f\n",dt,channel,byte3);
|
||||
}
|
||||
break;
|
||||
case __SK_Portamento_:
|
||||
sprintf(s,"Portamento\t%.3f %d %.1f\n",0.0,channel,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"Portamento\t%.3f %d %.1f\n",dt,channel,byte3);
|
||||
}
|
||||
break;
|
||||
case __SK_Balance_:
|
||||
sprintf(s,"Balance\t%.3f %d %.1f\n",0.0,channel,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"Balance\t%.3f %d %.1f\n",dt,channel,byte3);
|
||||
}
|
||||
break;
|
||||
case __SK_Pan_:
|
||||
sprintf(s,"Pan\t\t%.3f %d %.1f\n",0.0,channel,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"Pan\t\t%.3f %d %.1f\n",dt,channel,byte3);
|
||||
}
|
||||
break;
|
||||
case __SK_Sustain_:
|
||||
sprintf(s,"Sustain\t%.3f %d %.1f\n",0.0,channel,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"Sustain\t%.3f %d %.1f\n",dt,channel,byte3);
|
||||
}
|
||||
break;
|
||||
case __SK_Expression_:
|
||||
sprintf(s,"Expression\t%.3f %d %.1f\n",0.0,channel,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"Expression\t%.3f %d %.1f\n",dt,channel,byte3);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sprintf(s,"ControlChange\t%.3f %d %d %.1f\n",0.0,channel,j,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"ControlChange\t%.3f %d %d %.1f\n",dt,channel,j,byte3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case __SK_ProgramChange_:
|
||||
j = (int) byte2;
|
||||
sprintf(s,"ProgramChange\t%.3f %d %d\n",0.0,channel,j);
|
||||
if (writeFile) {
|
||||
fprintf(file,"ProgramChange\t%.3f %d %d\n",dt,channel,j);
|
||||
}
|
||||
break;
|
||||
|
||||
case __SK_ChannelPressure_:
|
||||
sprintf(s,"ChannelPressure\t%.3f %d %.1f\n",0.0,channel,byte2);
|
||||
if (writeFile) {
|
||||
fprintf(file,"ChannelPressure\t%.3f %d %.1f\n",dt,channel,byte2);
|
||||
}
|
||||
break;
|
||||
|
||||
case __SK_PitchBend_:
|
||||
sprintf(s,"PitchBend\t%.3f %d %f\n",0.0,channel,byte2);
|
||||
if (writeFile) {
|
||||
fprintf(file,"PitchBend\t%.3f %d %f\n",dt,channel,byte2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(s,"// Unknown\t%.3f %d %f %f\n",0.0,channel,byte2,byte3);
|
||||
if (writeFile) {
|
||||
fprintf(file,"// Unknown\t\t%.3f %d %f %f\n",dt,channel,byte2,byte3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (useSocket) {
|
||||
if ( soket->writeBuffer( s, strlen(s), 0 ) < 0 ) {
|
||||
fprintf(stderr,"Socket connection failed ... aborting.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("%s", s);
|
||||
fflush(stdout);
|
||||
}
|
||||
memset(s, 0, sizeof(s));
|
||||
} else {
|
||||
// Sleep for 10 milliseconds
|
||||
Stk::sleep( 10 );
|
||||
}
|
||||
// Open the port.
|
||||
try {
|
||||
midiin->openPort( port );
|
||||
}
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sprintf(s, "Exiting Md2Skini process ... bye!\n");
|
||||
if (useSocket)
|
||||
soket->writeBuffer( s, strlen(s), 0 );
|
||||
else {
|
||||
printf("%s", s);
|
||||
fflush(stdout);
|
||||
}
|
||||
// Set our callback function. This should be done immediately after
|
||||
// opening the port to avoid having incoming messages written to the
|
||||
// queue instead of sent to the callback function.
|
||||
midiin->setCallback( &midiCallback, file );
|
||||
|
||||
if (writeFile) {
|
||||
printf("Wrote SKINI output to file %s.\n", fileName);
|
||||
fclose(file);
|
||||
}
|
||||
// We'll ignore sysex, timing, and active sensing messages.
|
||||
midiin->ignoreTypes( true, true, true );
|
||||
|
||||
std::cout << "\nReading MIDI input ... press <enter> to quit.\n";
|
||||
char input;
|
||||
std::cin.get(input);
|
||||
|
||||
cleanup:
|
||||
done = true;
|
||||
delete rtmidi;
|
||||
delete soket;
|
||||
delete thread;
|
||||
delete midiin;
|
||||
if ( file != NULL ) fclose( file );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
THREAD_RETURN THREAD_TYPE stdinMonitor(void * ptr)
|
||||
{
|
||||
bool *done = (bool *) ptr;
|
||||
char inputString[128];
|
||||
printf("Type 'Exit<cr>' to quit.\n");
|
||||
while ( !*done ) {
|
||||
fgets(inputString, 128, stdin);
|
||||
if (inputString[3] == 't' && inputString[1] == 'x'
|
||||
&& inputString[2] == 'i' && inputString[0] == 'E') {
|
||||
*done = true;
|
||||
}
|
||||
else {
|
||||
printf(inputString);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
std::cout << "Md2Skini finished ... bye!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /Od /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /Od /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -66,7 +66,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__WINDOWS_MM__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -99,16 +99,8 @@ SOURCE=..\..\src\SKINI.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Socket.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Stk.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Thread.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
@@ -123,16 +115,8 @@ SOURCE=..\..\include\SKINI.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Socket.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Stk.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Thread.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
|
||||
1
projects/demo/Modal
Executable file
1
projects/demo/Modal
Executable file
@@ -0,0 +1 @@
|
||||
wish < tcl/Modal.tcl | ./demo ModalBar -or -ip
|
||||
@@ -1 +1 @@
|
||||
wish < tcl/Modal.tcl | ./demo ModalBar -or -ip
|
||||
wish < tcl/Modal.tcl | demo ModalBar -or -ip
|
||||
1
projects/demo/Physical
Executable file
1
projects/demo/Physical
Executable file
@@ -0,0 +1 @@
|
||||
wish < tcl/Physical.tcl | ./demo Clarinet -or -ip
|
||||
@@ -1 +1 @@
|
||||
wish < tcl/Physical.tcl | ./demo Clarinet -or -ip
|
||||
wish < tcl/Physical.tcl | demo Clarinet -or -ip
|
||||
1
projects/demo/Shakers
Executable file
1
projects/demo/Shakers
Executable file
@@ -0,0 +1 @@
|
||||
wish < tcl/Shakers.tcl | ./demo Shakers -or -ip
|
||||
1
projects/demo/StkDemo
Executable file
1
projects/demo/StkDemo
Executable file
@@ -0,0 +1 @@
|
||||
wish < tcl/Demo.tcl | ./demo Clarinet -or -ip
|
||||
@@ -1 +1 @@
|
||||
wish < tcl/Demo.tcl | ./demo Clarinet -or -ip
|
||||
wish < tcl/Demo.tcl | demo Clarinet -or -ip
|
||||
|
||||
1
projects/demo/Voice
Executable file
1
projects/demo/Voice
Executable file
@@ -0,0 +1 @@
|
||||
wish < tcl/Voice.tcl | ./demo FMVoices -or -ip
|
||||
@@ -1 +1 @@
|
||||
wish < tcl/Voice.tcl | ./demo FMVoices -or -ip
|
||||
wish < tcl/Voice.tcl | demo FMVoices -or -ip
|
||||
@@ -1,35 +1,193 @@
|
||||
// demo.cpp
|
||||
//
|
||||
// An example STK program for voice playback and control.
|
||||
// An example STK program that allows voice playback and control of
|
||||
// most of the STK instruments.
|
||||
|
||||
#include "SKINI.msg"
|
||||
#include "WvOut.h"
|
||||
#include "Instrmnt.h"
|
||||
#include "PRCRev.h"
|
||||
#include "Voicer.h"
|
||||
#include "Skini.h"
|
||||
|
||||
#if defined(__STK_REALTIME__)
|
||||
#include "RtAudio.h"
|
||||
#include "Mutex.h"
|
||||
#endif
|
||||
|
||||
// Miscellaneous command-line parsing and instrument allocation
|
||||
// functions are defined in utilites.cpp ... specific to this program.
|
||||
#include "utilities.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#if !defined(__OS_WINDOWS__) // Windoze bogosity for VC++ 6.0
|
||||
using std::min;
|
||||
#endif
|
||||
|
||||
bool done;
|
||||
static void finish(int ignore){ done = true; }
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
// The TickData structure holds all the class instances and data that
|
||||
// are shared by the various processing functions.
|
||||
struct TickData {
|
||||
WvOut **wvout;
|
||||
Instrmnt **instrument;
|
||||
Voicer *voicer;
|
||||
Effect *reverb;
|
||||
Messager messager;
|
||||
Skini::Message message;
|
||||
StkFloat volume;
|
||||
StkFloat t60;
|
||||
unsigned int nWvOuts;
|
||||
int nVoices;
|
||||
int currentVoice;
|
||||
int channels;
|
||||
int counter;
|
||||
bool realtime;
|
||||
bool settling;
|
||||
bool haveMessage;
|
||||
|
||||
// Default constructor.
|
||||
TickData()
|
||||
: wvout(0), instrument(0), voicer(0), reverb(0), volume(1.0), t60(1.0),
|
||||
nWvOuts(0), nVoices(1), currentVoice(0), channels(2), counter(0),
|
||||
realtime( false ), settling( false ), haveMessage( false ) {}
|
||||
};
|
||||
|
||||
#define DELTA_CONTROL_TICKS 64 // default sample frames between control input checks
|
||||
|
||||
// The processMessage() function encapsulates the handling of control
|
||||
// messages. It can be easily relocated within a program structure
|
||||
// depending on the desired scheduling scheme.
|
||||
void processMessage( TickData* data )
|
||||
{
|
||||
Instrmnt **instrument = 0;
|
||||
WvOut **output = 0;
|
||||
Messager *messager = 0;
|
||||
Reverb *reverb = 0;
|
||||
Voicer *voicer = 0;
|
||||
int i, nVoices = 1;
|
||||
MY_FLOAT volume = 1.0;
|
||||
MY_FLOAT t60 = 1.0; // in seconds
|
||||
register StkFloat value1 = data->message.floatValues[0];
|
||||
register StkFloat value2 = data->message.floatValues[1];
|
||||
|
||||
switch( data->message.type ) {
|
||||
|
||||
case __SK_Exit_:
|
||||
if ( data->settling == false ) goto settle;
|
||||
done = true;
|
||||
return;
|
||||
|
||||
case __SK_NoteOn_:
|
||||
if ( value2 == 0.0 ) // velocity is zero ... really a NoteOff
|
||||
data->voicer->noteOff( value1, 64.0 );
|
||||
else // a NoteOn
|
||||
data->voicer->noteOn( value1, value2 );
|
||||
break;
|
||||
|
||||
case __SK_NoteOff_:
|
||||
data->voicer->noteOff( value1, value2 );
|
||||
break;
|
||||
|
||||
case __SK_ControlChange_:
|
||||
if (value1 == 44.0)
|
||||
data->reverb->setEffectMix(value2 * ONE_OVER_128);
|
||||
else if (value1 == 7.0)
|
||||
data->volume = value2 * ONE_OVER_128;
|
||||
else if (value1 == 49.0)
|
||||
data->voicer->setFrequency( value2 );
|
||||
else
|
||||
data->voicer->controlChange( (int) value1, value2 );
|
||||
break;
|
||||
|
||||
case __SK_AfterTouch_:
|
||||
data->voicer->controlChange( 128, value1 );
|
||||
break;
|
||||
|
||||
case __SK_PitchChange_:
|
||||
data->voicer->setFrequency( value1 );
|
||||
break;
|
||||
|
||||
case __SK_PitchBend_:
|
||||
data->voicer->pitchBend( value1 );
|
||||
break;
|
||||
|
||||
case __SK_Volume_:
|
||||
data->volume = value1 * ONE_OVER_128;
|
||||
break;
|
||||
|
||||
case __SK_ProgramChange_:
|
||||
if ( data->currentVoice == (int) value1 ) break;
|
||||
|
||||
// Two-stage program change process.
|
||||
if ( data->settling == false ) goto settle;
|
||||
|
||||
// Stage 2: delete and reallocate new voice(s)
|
||||
for ( int i=0; i<data->nVoices; i++ ) {
|
||||
data->voicer->removeInstrument( data->instrument[i] );
|
||||
delete data->instrument[i];
|
||||
data->currentVoice = voiceByNumber( (int)value1, &data->instrument[i] );
|
||||
if ( data->currentVoice < 0 )
|
||||
data->currentVoice = voiceByNumber( 0, &data->instrument[i] );
|
||||
data->voicer->addInstrument( data->instrument[i] );
|
||||
data->settling = false;
|
||||
}
|
||||
|
||||
} // end of switch
|
||||
|
||||
data->haveMessage = false;
|
||||
return;
|
||||
|
||||
settle:
|
||||
// Exit and program change messages are preceeded with a short settling period.
|
||||
data->voicer->silence();
|
||||
data->counter = (int) (0.3 * data->t60 * Stk::sampleRate());
|
||||
data->settling = true;
|
||||
}
|
||||
|
||||
|
||||
// The tick() function handles sample computation and scheduling of
|
||||
// control updates. If doing realtime audio output, it will be called
|
||||
// automatically when the system needs a new buffer of audio samples.
|
||||
int tick(char *buffer, int bufferSize, void *dataPointer)
|
||||
{
|
||||
TickData *data = (TickData *) dataPointer;
|
||||
register StkFloat sample, *samples = (StkFloat *) buffer;
|
||||
int counter, nTicks = bufferSize;
|
||||
|
||||
while ( nTicks > 0 && !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++ ) {
|
||||
sample = data->volume * data->reverb->tick( data->voicer->tick() );
|
||||
for ( unsigned int j=0; j<data->nWvOuts; j++ ) data->wvout[j]->tick(sample);
|
||||
if ( data->realtime )
|
||||
for ( int k=0; k<data->channels; k++ ) *samples++ = sample;
|
||||
nTicks--;
|
||||
}
|
||||
if ( nTicks == 0 ) break;
|
||||
|
||||
// Process control messages.
|
||||
if ( data->haveMessage ) processMessage( data );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
TickData data;
|
||||
int i;
|
||||
|
||||
#if defined(__STK_REALTIME__)
|
||||
RtAudio *dac = 0;
|
||||
#endif
|
||||
|
||||
// If you want to change the default sample rate (set in Stk.h), do
|
||||
// it before instantiating any objects! If the sample rate is
|
||||
@@ -38,151 +196,110 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Check the command-line arguments for errors and to determine
|
||||
// the number of WvOut objects to be instantiated (in utilities.cpp).
|
||||
int nOutputs = checkArgs(argc, argv);
|
||||
output = (WvOut **) calloc(nOutputs, sizeof(WvOut *));
|
||||
data.nWvOuts = checkArgs(argc, argv);
|
||||
data.wvout = (WvOut **) calloc(data.nWvOuts, sizeof(WvOut *));
|
||||
|
||||
// Instantiate the instrument(s) type from the command-line argument
|
||||
// (in utilities.cpp).
|
||||
nVoices = countVoices(argc, argv);
|
||||
instrument = (Instrmnt **) calloc(nVoices, sizeof(Instrmnt *));
|
||||
int voice = voiceByName(argv[1], &instrument[0]);
|
||||
if ( voice < 0 ) {
|
||||
free( output );
|
||||
free( instrument );
|
||||
data.nVoices = countVoices(argc, argv);
|
||||
data.instrument = (Instrmnt **) calloc(data.nVoices, sizeof(Instrmnt *));
|
||||
data.currentVoice = voiceByName(argv[1], &data.instrument[0]);
|
||||
if ( data.currentVoice < 0 ) {
|
||||
free( data.wvout );
|
||||
free( data.instrument );
|
||||
usage(argv[0]);
|
||||
}
|
||||
// If there was no error allocating the first voice, we should be fine for more.
|
||||
for ( i=1; i<nVoices; i++ )
|
||||
voiceByName(argv[1], &instrument[i]);
|
||||
for ( i=1; i<data.nVoices; i++ )
|
||||
voiceByName(argv[1], &data.instrument[i]);
|
||||
|
||||
voicer = (Voicer *) new Voicer(nVoices);
|
||||
for ( i=0; i<nVoices; i++ )
|
||||
voicer->addInstrument( instrument[i] );
|
||||
data.voicer = (Voicer *) new Voicer( data.nVoices );
|
||||
for ( i=0; i<data.nVoices; i++ )
|
||||
data.voicer->addInstrument( data.instrument[i] );
|
||||
|
||||
// Parse the command-line flags, instantiate WvOut objects, and
|
||||
// instantiate the input message controller (in utilities.cpp).
|
||||
try {
|
||||
parseArgs(argc, argv, output, &messager);
|
||||
data.realtime = parseArgs(argc, argv, data.wvout, data.messager);
|
||||
}
|
||||
catch (StkError &) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Set the number of ticks between realtime messages (default =
|
||||
// RT_BUFFER_SIZE).
|
||||
messager->setRtDelta( 64 );
|
||||
// If realtime output, allocate the dac here.
|
||||
#if defined(__STK_REALTIME__)
|
||||
if ( data.realtime ) {
|
||||
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
|
||||
int bufferSize = RT_BUFFER_SIZE;
|
||||
try {
|
||||
dac = new RtAudio(0, data.channels, 0, 0, format, (int)Stk::sampleRate(), &bufferSize, 4);
|
||||
}
|
||||
catch (RtError& error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set the reverb parameters.
|
||||
reverb = new PRCRev( t60 );
|
||||
reverb->setEffectMix(0.2);
|
||||
data.reverb = new PRCRev( data.t60 );
|
||||
data.reverb->setEffectMix(0.2);
|
||||
|
||||
// Install an interrupt handler function.
|
||||
(void) signal(SIGINT, finish);
|
||||
|
||||
// The runtime loop begins here:
|
||||
done = FALSE;
|
||||
int nTicks, type, j;
|
||||
MY_FLOAT byte2, byte3, sample;
|
||||
while (!done) {
|
||||
|
||||
// Look for new messages and return a delta time (in samples).
|
||||
type = messager->nextMessage();
|
||||
if (type < 0)
|
||||
done = TRUE;
|
||||
|
||||
nTicks = messager->getDelta();
|
||||
for ( i=0; i<nTicks; i++ ) {
|
||||
sample = volume * reverb->tick( voicer->tick() );
|
||||
for ( j=0; j<nOutputs; j++ ) output[j]->tick(sample);
|
||||
// If realtime output, set our callback function and start the dac.
|
||||
#if defined(__STK_REALTIME__)
|
||||
if ( data.realtime ) {
|
||||
try {
|
||||
dac->setStreamCallback(&tick, (void *)&data);
|
||||
dac->startStream();
|
||||
}
|
||||
|
||||
if ( type > 0 ) {
|
||||
// Process the new control message.
|
||||
byte2 = messager->getByteTwo();
|
||||
byte3 = messager->getByteThree();
|
||||
|
||||
switch(type) {
|
||||
|
||||
case __SK_NoteOn_:
|
||||
if (byte3 == 0.0) // velocity is zero ... really a NoteOff
|
||||
voicer->noteOff( byte2, 64.0 );
|
||||
else // a NoteOn
|
||||
voicer->noteOn( byte2, byte3 );
|
||||
break;
|
||||
|
||||
case __SK_NoteOff_:
|
||||
voicer->noteOff( byte2, byte3 );
|
||||
break;
|
||||
|
||||
case __SK_ControlChange_:
|
||||
if (byte2 == 44.0)
|
||||
reverb->setEffectMix(byte3 * ONE_OVER_128);
|
||||
else if (byte2 == 7.0)
|
||||
volume = byte3 * ONE_OVER_128;
|
||||
else if (byte2 == 49.0)
|
||||
voicer->setFrequency( byte3 );
|
||||
else
|
||||
voicer->controlChange( (int) byte2, byte3 );
|
||||
break;
|
||||
|
||||
case __SK_AfterTouch_:
|
||||
voicer->controlChange( 128, byte2 );
|
||||
break;
|
||||
|
||||
case __SK_PitchChange_:
|
||||
voicer->setFrequency( byte2 );
|
||||
break;
|
||||
|
||||
case __SK_PitchBend_:
|
||||
voicer->pitchBend( byte2 );
|
||||
break;
|
||||
|
||||
case __SK_Volume_:
|
||||
volume = byte2 * ONE_OVER_128;
|
||||
break;
|
||||
|
||||
case __SK_ProgramChange_:
|
||||
if ( voice != (int) byte2 ) {
|
||||
voicer->silence();
|
||||
// Let the instrument(s) settle a bit.
|
||||
for ( i=0; i<4096; i++ ) {
|
||||
sample = reverb->tick( voicer->tick() );
|
||||
for ( j=0; j<nOutputs; j++ ) output[j]->tick(sample);
|
||||
}
|
||||
for ( i=0; i<nVoices; i++ ) {
|
||||
voicer->removeInstrument( instrument[i] );
|
||||
delete instrument[i];
|
||||
voice = voiceByNumber( (int)byte2, &instrument[i] );
|
||||
if ( voice < 0 )
|
||||
voice = voiceByNumber( 0, &instrument[i] );
|
||||
voicer->addInstrument( instrument[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Let the reverb settle a bit.
|
||||
nTicks = (long) (t60 * Stk::sampleRate());
|
||||
for ( i=0; i<nTicks; i++) {
|
||||
sample = reverb->tick( voicer->tick() );
|
||||
for ( j=0; j<nOutputs; j++ ) output[j]->tick(sample);
|
||||
// Setup finished.
|
||||
while ( !done ) {
|
||||
#if defined(__STK_REALTIME__)
|
||||
if ( data.realtime )
|
||||
// Periodically check "done" status.
|
||||
Stk::sleep( 200 );
|
||||
else
|
||||
#endif
|
||||
// Call the "tick" function to process data.
|
||||
tick( NULL, 256, (void *)&data );
|
||||
}
|
||||
|
||||
// Shut down the callback and output stream.
|
||||
#if defined(__STK_REALTIME__)
|
||||
try {
|
||||
dac->cancelStreamCallback();
|
||||
dac->closeStream();
|
||||
}
|
||||
catch (RtError& error) {
|
||||
error.printMessage();
|
||||
}
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
|
||||
for ( i=0; i<nOutputs; i++ ) delete output[i];
|
||||
free(output);
|
||||
for ( i=0; i<(int)data.nWvOuts; i++ ) delete data.wvout[i];
|
||||
free( data.wvout );
|
||||
|
||||
delete messager;
|
||||
delete reverb;
|
||||
delete voicer;
|
||||
#if defined(__STK_REALTIME__)
|
||||
delete dac;
|
||||
#endif
|
||||
delete data.reverb;
|
||||
delete data.voicer;
|
||||
|
||||
for ( i=0; i<nVoices; i++ ) delete instrument[i];
|
||||
free(instrument);
|
||||
for ( i=0; i<data.nVoices; i++ ) delete data.instrument[i];
|
||||
free( data.instrument );
|
||||
|
||||
std::cout << "\nStk demo finished ... goodbye.\n" << std::endl;
|
||||
std::cout << "\nStk demo finished ... goodbye.\n\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -66,7 +66,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_DS__" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -91,6 +91,10 @@ SOURCE=..\..\src\ADSR.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Asymp.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\BandedWG.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -115,7 +119,7 @@ SOURCE=..\..\src\Bowed.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\BowTabl.cpp
|
||||
SOURCE=..\..\src\BowTable.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -147,6 +151,10 @@ SOURCE=..\..\src\Drummer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Effect.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Envelope.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -171,6 +179,14 @@ SOURCE=..\..\src\FormSwep.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Function.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Generator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\HevyMetl.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -183,7 +199,7 @@ SOURCE=..\..\src\JCRev.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\JetTabl.cpp
|
||||
SOURCE=..\..\src\JetTable.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -215,6 +231,10 @@ SOURCE=..\..\src\Moog.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Mutex.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Noise.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -255,7 +275,7 @@ SOURCE=..\..\src\PRCRev.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\ReedTabl.cpp
|
||||
SOURCE=..\..\src\ReedTable.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -263,10 +283,6 @@ SOURCE=..\..\src\Resonate.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Reverb.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Rhodey.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -399,6 +415,10 @@ SOURCE=..\..\include\ADSR.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Asymp.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\BandedWG.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -423,7 +443,7 @@ SOURCE=..\..\include\Bowed.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\BowTabl.h
|
||||
SOURCE=..\..\include\BowTable.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -451,6 +471,10 @@ SOURCE=..\..\include\Drummer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Effect.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Envelope.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -475,6 +499,14 @@ SOURCE=..\..\include\FormSwep.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Function.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Generator.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\HevyMetl.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -487,7 +519,7 @@ SOURCE=..\..\include\JCRev.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\JetTabl.h
|
||||
SOURCE=..\..\include\JetTable.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -519,6 +551,10 @@ SOURCE=..\..\include\Moog.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Mutex.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Noise.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -559,7 +595,7 @@ SOURCE=..\..\include\PRCRev.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\ReedTabl.h
|
||||
SOURCE=..\..\include\ReedTable.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -567,10 +603,6 @@ SOURCE=..\..\include\Resonate.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Reverb.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Rhodey.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -755,7 +755,7 @@ proc printWhatz {tag value1 value2 } {
|
||||
|
||||
proc changePress {value} {
|
||||
global outID patchnum
|
||||
if { $patchnum<700 || $patchnum>900 } {
|
||||
if { $patchnum<700 || ($patchnum>900 && $patchnum<2500) || $patchnum>=2600 } {
|
||||
puts $outID [format "AfterTouch 0.0 1 %3.2f" $value]
|
||||
flush $outID
|
||||
}
|
||||
|
||||
@@ -36,10 +36,6 @@
|
||||
#include "Resonate.h"
|
||||
#include "Whistle.h"
|
||||
|
||||
#if defined(__STK_REALTIME__)
|
||||
#include "RtWvOut.h"
|
||||
#endif
|
||||
|
||||
#define NUM_INSTS 28
|
||||
|
||||
// The order of the following list is important. The location of a particular
|
||||
@@ -123,12 +119,13 @@ void usage(char *function) {
|
||||
printf(" -os <file name> for .snd audio output file,\n");
|
||||
printf(" -om <file name> for .mat audio output file,\n");
|
||||
printf(" -oa <file name> for .aif audio output file,\n");
|
||||
printf(" -if <file name> to read control input from SKINI file,\n");
|
||||
#if defined(__STK_REALTIME__)
|
||||
printf(" -or for realtime audio output,\n");
|
||||
printf(" -ip for realtime control input by pipe,\n");
|
||||
printf(" (won't work under Win95/98),\n");
|
||||
printf(" -is <port> for realtime control input by socket,\n");
|
||||
printf(" -im for realtime control input by MIDI,\n");
|
||||
printf(" -im <port> for realtime control input by MIDI (virtual port = 0, default = 1),\n");
|
||||
#endif
|
||||
printf(" and Instrument = one of these:\n");
|
||||
for (i=0;i<NUM_INSTS;i+=8) {
|
||||
@@ -150,24 +147,25 @@ void usage(char *function) {
|
||||
int checkArgs(int numArgs, char *args[])
|
||||
{
|
||||
int w, i = 2, j = 0;
|
||||
int numOutputs = 0;
|
||||
int nWvOuts = 0;
|
||||
char flags[2][50] = {""};
|
||||
bool realtime = false;
|
||||
|
||||
if (numArgs < 3 || numArgs > 17) usage(args[0]);
|
||||
if (numArgs < 3 || numArgs > 22) usage(args[0]);
|
||||
|
||||
while (i < numArgs) {
|
||||
if (args[i][0] == '-') {
|
||||
if (args[i][1] == 'o') {
|
||||
if ( (args[i][2] == 'r') || (args[i][2] == 's') ||
|
||||
(args[i][2] == 'w') || (args[i][2] == 'm')
|
||||
|| (args[i][2] == 'a') )
|
||||
numOutputs++;
|
||||
if ( args[i][2] == 'r' ) realtime = true;
|
||||
if ( (args[i][2] == 's') || (args[i][2] == 'w') ||
|
||||
(args[i][2] == 'm') || (args[i][2] == 'a') )
|
||||
nWvOuts++;
|
||||
flags[0][j] = 'o';
|
||||
flags[1][j++] = args[i][2];
|
||||
}
|
||||
else if (args[i][1] == 'i') {
|
||||
if ( (args[i][2] != 's') && (args[i][2] != 'p') &&
|
||||
(args[i][2] != 'm') ) usage(args[0]);
|
||||
(args[i][2] != 'm') && (args[i][2] != 'f') ) usage(args[0]);
|
||||
flags[0][j] = 'i';
|
||||
flags[1][j++] = args[i][2];
|
||||
}
|
||||
@@ -196,9 +194,9 @@ int checkArgs(int numArgs, char *args[])
|
||||
}
|
||||
|
||||
// Make sure we have at least one output type
|
||||
if (numOutputs < 1) usage(args[0]);
|
||||
if ( nWvOuts < 1 && !realtime ) usage(args[0]);
|
||||
|
||||
return numOutputs;
|
||||
return nWvOuts;
|
||||
}
|
||||
|
||||
int countVoices(int nArgs, char *args[])
|
||||
@@ -218,20 +216,24 @@ int countVoices(int nArgs, char *args[])
|
||||
return nInstruments;
|
||||
}
|
||||
|
||||
void parseArgs(int numArgs, char *args[], WvOut **output, Messager **messager)
|
||||
bool parseArgs(int numArgs, char *args[], WvOut **output, Messager& messager)
|
||||
{
|
||||
int i = 2, j = 0;
|
||||
int inputMask = 0;
|
||||
int port = -1;
|
||||
bool realtime = false;
|
||||
char fileName[256];
|
||||
|
||||
while (i < numArgs) {
|
||||
if ( (args[i][0] == '-') && (args[i][1] == 'i') ) {
|
||||
switch(args[i][2]) {
|
||||
|
||||
case 'f':
|
||||
strcpy(fileName,args[++i]);
|
||||
if ( !messager.setScoreFile( fileName ) ) usage(args[0]);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
#if defined(__STK_REALTIME__)
|
||||
inputMask |= STK_PIPE;
|
||||
if ( !messager.startStdInput() ) usage(args[0]);
|
||||
break;
|
||||
#else
|
||||
usage(args[0]);
|
||||
@@ -239,10 +241,12 @@ void parseArgs(int numArgs, char *args[], WvOut **output, Messager **messager)
|
||||
|
||||
case 's':
|
||||
#if defined(__STK_REALTIME__)
|
||||
inputMask |= STK_SOCKET;
|
||||
// Check for an optional socket port argument.
|
||||
if ((i+1 < numArgs) && args[i+1][0] != '-')
|
||||
port = atoi(args[++i]);
|
||||
if ((i+1 < numArgs) && args[i+1][0] != '-') {
|
||||
int port = atoi(args[++i]);
|
||||
if ( !messager.startSocketInput( port ) ) usage(args[0]);
|
||||
}
|
||||
else if ( !messager.startSocketInput() ) usage(args[0]);
|
||||
break;
|
||||
#else
|
||||
usage(args[0]);
|
||||
@@ -250,7 +254,12 @@ void parseArgs(int numArgs, char *args[], WvOut **output, Messager **messager)
|
||||
|
||||
case 'm':
|
||||
#if defined(__STK_REALTIME__)
|
||||
inputMask |= STK_MIDI;
|
||||
// Check for an optional MIDI port argument.
|
||||
if ((i+1 < numArgs) && args[i+1][0] != '-') {
|
||||
int port = atoi(args[++i]);
|
||||
if ( !messager.startMidiInput( port-1 ) ) usage(args[0]);
|
||||
}
|
||||
else if ( !messager.startMidiInput() ) usage(args[0]);
|
||||
break;
|
||||
#else
|
||||
usage(args[0]);
|
||||
@@ -266,8 +275,7 @@ void parseArgs(int numArgs, char *args[], WvOut **output, Messager **messager)
|
||||
|
||||
case 'r':
|
||||
#if defined(__STK_REALTIME__)
|
||||
output[j] = (WvOut *) new RtWvOut(2);
|
||||
j++;
|
||||
realtime = true;
|
||||
break;
|
||||
#else
|
||||
usage(args[0]);
|
||||
@@ -321,10 +329,5 @@ void parseArgs(int numArgs, char *args[], WvOut **output, Messager **messager)
|
||||
i++;
|
||||
}
|
||||
|
||||
// Instantiate the messager.
|
||||
if ( inputMask & STK_SOCKET && port >= 0 )
|
||||
*messager = new Messager( inputMask, port );
|
||||
else
|
||||
*messager = new Messager( inputMask );
|
||||
|
||||
return realtime;
|
||||
}
|
||||
|
||||
@@ -16,4 +16,4 @@ int checkArgs(int numArgs, char *args[]);
|
||||
|
||||
int countVoices(int nArgs, char *args[]);
|
||||
|
||||
void parseArgs(int numArgs, char *args[], WvOut **output, Messager **messager);
|
||||
bool parseArgs(int numArgs, char *args[], WvOut **output, Messager& messager);
|
||||
|
||||
1
projects/effects/Effects
Executable file
1
projects/effects/Effects
Executable file
@@ -0,0 +1 @@
|
||||
wish < tcl/Effects.tcl | ./effects -ip
|
||||
@@ -1 +1 @@
|
||||
wish < tcl/Effects.tcl | ./effects -ip
|
||||
wish < tcl/Effects.tcl | effects -ip
|
||||
|
||||
@@ -6,11 +6,11 @@ SRC_PATH = ../../src
|
||||
OBJECT_PATH = @object_path@
|
||||
vpath %.o $(OBJECT_PATH)
|
||||
|
||||
OBJECTS = Stk.o Reverb.o PRCRev.o JCRev.o \
|
||||
NRev.o Delay.o Filter.o \
|
||||
SKINI.o Envelope.o Echo.o \
|
||||
PitShift.o DelayL.o Chorus.o \
|
||||
WvIn.o WaveLoop.o Messager.o
|
||||
OBJECTS = Stk.o Generator.o Envelope.o \
|
||||
Filter.o Delay.o DelayL.o \
|
||||
Effect.o Echo.o PitShift.o Chorus.o \
|
||||
PRCRev.o JCRev.o NRev.o \
|
||||
WvIn.o WaveLoop.o Skini.o Messager.o
|
||||
|
||||
INCLUDE = @include@
|
||||
ifeq ($(strip $(INCLUDE)), )
|
||||
@@ -28,9 +28,8 @@ LIBRARY += @frameworks@
|
||||
|
||||
REALTIME = @realtime@
|
||||
ifeq ($(REALTIME),yes)
|
||||
OBJECTS += RtMidi.o RtAudio.o RtDuplex.o Thread.o Socket.o
|
||||
OBJECTS += RtMidi.o RtAudio.o Thread.o Mutex.o Socket.o
|
||||
DEFS += @audio_apis@
|
||||
DEFS += @midiator@
|
||||
endif
|
||||
|
||||
RAWWAVES = @rawwaves@
|
||||
@@ -47,6 +46,9 @@ all : $(PROGRAMS)
|
||||
effects: effects.cpp $(OBJECTS)
|
||||
$(CC) $(CFLAGS) $(DEFS) -o effects effects.cpp $(OBJECT_PATH)/*.o $(LIBRARY)
|
||||
|
||||
libeffects: effects.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -o effects effects.cpp -L../../src $(LIBRARY) -lstk
|
||||
|
||||
$(OBJECTS) : Stk.h
|
||||
|
||||
clean :
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/************** Effects Program *********************/
|
||||
|
||||
#include "RtDuplex.h"
|
||||
#include "SKINI.h"
|
||||
#include "Skini.h"
|
||||
#include "SKINI.msg"
|
||||
#include "Envelope.h"
|
||||
#include "PRCRev.h"
|
||||
@@ -10,183 +9,256 @@
|
||||
#include "Echo.h"
|
||||
#include "PitShift.h"
|
||||
#include "Chorus.h"
|
||||
|
||||
// The input control handler.
|
||||
#include "Messager.h"
|
||||
#include "RtAudio.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#if !defined(__OS_WINDOWS__) // Windoze bogosity for VC++ 6.0
|
||||
using std::min;
|
||||
#endif
|
||||
|
||||
void usage(void) {
|
||||
/* Error function in case of incorrect command-line argument specifications */
|
||||
printf("\nuseage: effects flags \n");
|
||||
printf(" where flag = -s RATE to specify a sample rate,\n");
|
||||
printf(" flag = -ip for realtime SKINI input by pipe\n");
|
||||
printf(" (won't work under Win95/98),\n");
|
||||
printf(" and flag = -is <port> for realtime SKINI input by socket.\n");
|
||||
// Error function in case of incorrect command-line argument specifications
|
||||
std::cout << "\nuseage: effects flags \n";
|
||||
std::cout << " where flag = -s RATE to specify a sample rate,\n";
|
||||
std::cout << " flag = -ip for realtime SKINI input by pipe\n";
|
||||
std::cout << " (won't work under Win95/98),\n";
|
||||
std::cout << " and flag = -is <port> for realtime SKINI input by socket.\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
bool done;
|
||||
static void finish(int ignore){ done = true; }
|
||||
|
||||
// The TickData structure holds all the class instances and data that
|
||||
// are shared by the various processing functions.
|
||||
struct TickData {
|
||||
Effect *effect;
|
||||
PRCRev prcrev;
|
||||
JCRev jcrev;
|
||||
NRev nrev;
|
||||
Echo echo;
|
||||
PitShift shifter;
|
||||
Chorus chorus;
|
||||
Envelope envelope;
|
||||
Messager messager;
|
||||
Skini::Message message;
|
||||
StkFloat lastSample;
|
||||
StkFloat t60;
|
||||
int counter;
|
||||
bool settling;
|
||||
bool haveMessage;
|
||||
|
||||
// Default constructor.
|
||||
TickData()
|
||||
: effect(0), t60(1.0), counter(0),
|
||||
settling( false ), haveMessage( false ) {}
|
||||
};
|
||||
|
||||
#define DELTA_CONTROL_TICKS 64 // default sample frames between control input checks
|
||||
|
||||
// The processMessage() function encapsulates the handling of control
|
||||
// messages. It can be easily relocated within a program structure
|
||||
// depending on the desired scheduling scheme.
|
||||
void processMessage( TickData* data )
|
||||
{
|
||||
register unsigned int value1 = data->message.intValues[0];
|
||||
register StkFloat value2 = data->message.floatValues[1];
|
||||
register StkFloat temp = value2 * ONE_OVER_128;
|
||||
|
||||
switch( data->message.type ) {
|
||||
|
||||
case __SK_Exit_:
|
||||
if ( data->settling == false ) goto settle;
|
||||
done = true;
|
||||
return;
|
||||
|
||||
case __SK_NoteOn_:
|
||||
if ( value2 == 0.0 ) // velocity is zero ... really a NoteOff
|
||||
data->envelope.setTarget( 0.0 );
|
||||
else // a NoteOn
|
||||
data->envelope.setTarget( 1.0 );
|
||||
break;
|
||||
|
||||
case __SK_NoteOff_:
|
||||
data->envelope.setTarget( 0.0 );
|
||||
break;
|
||||
|
||||
case __SK_ControlChange_:
|
||||
// Change all effect values so they are "synched" to the interface.
|
||||
switch ( value1 ) {
|
||||
|
||||
case 20: { // effect type change
|
||||
int type = data->message.intValues[1];
|
||||
if ( type == 0 )
|
||||
data->effect = &(data->echo);
|
||||
else if ( type == 1 )
|
||||
data->effect = &(data->shifter);
|
||||
else if ( type == 2 )
|
||||
data->effect = &(data->chorus);
|
||||
else if ( type == 3 )
|
||||
data->effect = &(data->prcrev);
|
||||
else if ( type == 4 )
|
||||
data->effect = &(data->jcrev);
|
||||
else if ( type == 5 )
|
||||
data->effect = &(data->nrev);
|
||||
break;
|
||||
}
|
||||
|
||||
case 22: // effect parameter change 1
|
||||
data->echo.setDelay( (unsigned long) (temp * Stk::sampleRate() * 0.95) );
|
||||
// data->shifter.setShift( temp * 3 + 0.25);
|
||||
data->shifter.setShift( 1.4 * temp + 0.3);
|
||||
data->chorus.setModFrequency( temp );
|
||||
data->prcrev.setT60( temp * 10.0 );
|
||||
data->jcrev.setT60( temp * 10.0 );
|
||||
data->nrev.setT60( temp * 10.0 );
|
||||
break;
|
||||
|
||||
case 23: // effect parameter change 2
|
||||
data->chorus.setModDepth( temp * 0.2 );
|
||||
break;
|
||||
|
||||
case 44: // effect mix
|
||||
data->echo.setEffectMix( temp );
|
||||
data->shifter.setEffectMix( temp );
|
||||
data->chorus.setEffectMix( temp );
|
||||
data->prcrev.setEffectMix( temp );
|
||||
data->jcrev.setEffectMix( temp );
|
||||
data->nrev.setEffectMix( temp );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} // end of type switch
|
||||
|
||||
data->haveMessage = false;
|
||||
return;
|
||||
|
||||
settle:
|
||||
// Exit and program change messages are preceeded with a short settling period.
|
||||
data->envelope.setTarget( 0.0 );
|
||||
data->counter = (int) (0.3 * data->t60 * Stk::sampleRate());
|
||||
data->settling = true;
|
||||
}
|
||||
|
||||
// The tick() function handles sample computation and scheduling of
|
||||
// control updates. It will be called automatically by RtAudio when
|
||||
// the system needs a new buffer of audio samples.
|
||||
int tick(char *buffer, int bufferSize, void *dataPointer)
|
||||
{
|
||||
TickData *data = (TickData *) dataPointer;
|
||||
register StkFloat sample, *samples = (StkFloat *) buffer;
|
||||
int i, counter, nTicks = bufferSize;
|
||||
|
||||
while ( nTicks > 0 && !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 ( i=0; i<counter; i++ ) {
|
||||
sample = data->envelope.tick() * data->effect->tick( *samples );
|
||||
*samples++ = sample; // two channels interleaved
|
||||
*samples++ = sample;
|
||||
nTicks--;
|
||||
}
|
||||
if ( nTicks == 0 ) break;
|
||||
|
||||
// Process control messages.
|
||||
if ( data->haveMessage ) processMessage( data );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
TickData data;
|
||||
RtAudio *adac = 0;
|
||||
int i;
|
||||
|
||||
if (argc < 2 || argc > 6) usage();
|
||||
|
||||
// If you want to change the default sample rate (set in Stk.h), do
|
||||
// it before instantiating any objects! If the sample rate is
|
||||
// specified in the command line, it will override this setting.
|
||||
Stk::setSampleRate(22050.0);
|
||||
Stk::setSampleRate( 44100.0 );
|
||||
|
||||
int port = -1;
|
||||
int controlMask = 0;
|
||||
for (int k=1; k<argc; k++ ) {
|
||||
if (!strcmp(argv[k],"-is") ) {
|
||||
controlMask |= STK_SOCKET;
|
||||
if (k+1 < argc && argv[k+1][0] != '-' ) port = atoi(argv[++k]);
|
||||
// Parse the command-line arguments.
|
||||
unsigned int port = 2001;
|
||||
for ( i=1; i<argc; i++ ) {
|
||||
if ( !strcmp( argv[i], "-is" ) ) {
|
||||
if ( i+1 < argc && argv[i+1][0] != '-' ) port = atoi(argv[++i]);
|
||||
data.messager.startSocketInput( port );
|
||||
}
|
||||
else if (!strcmp(argv[k],"-ip") )
|
||||
controlMask |= STK_PIPE;
|
||||
else if (!strcmp(argv[k],"-s") && (k+1 < argc) && argv[k+1][0] != '-')
|
||||
Stk::setSampleRate( atoi(argv[++k]) );
|
||||
else if (!strcmp( argv[i], "-ip" ) )
|
||||
data.messager.startStdInput();
|
||||
else if ( !strcmp( argv[i], "-s" ) && ( i+1 < argc ) && argv[i+1][0] != '-')
|
||||
Stk::setSampleRate( atoi(argv[++i]) );
|
||||
else
|
||||
usage();
|
||||
}
|
||||
|
||||
bool done;
|
||||
int effect = 0;
|
||||
MY_FLOAT lastSample, inSample;
|
||||
Envelope *envelope = new Envelope;
|
||||
PRCRev *prcrev = new PRCRev(2.0);
|
||||
JCRev *jcrev = new JCRev(2.0);
|
||||
NRev *nrev = new NRev(2.0);
|
||||
Echo *echo = new Echo( (long) Stk::sampleRate() ); // one second delay
|
||||
PitShift *shifter = new PitShift();
|
||||
Chorus *chorus = new Chorus(5000.0);
|
||||
SKINI *score = new SKINI();
|
||||
Messager *messager = 0;
|
||||
RtDuplex *inout = 0;
|
||||
|
||||
// Allocate the adac here.
|
||||
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
|
||||
int bufferSize = RT_BUFFER_SIZE;
|
||||
try {
|
||||
// Change the nBuffers parameter to a smaller number to get better input/output latency.
|
||||
inout = new RtDuplex(1, Stk::sampleRate(), 0, RT_BUFFER_SIZE, 10);
|
||||
|
||||
// Instantiate the input message controller.
|
||||
if ( controlMask & STK_SOCKET && port >= 0 )
|
||||
messager = new Messager( controlMask, port );
|
||||
else
|
||||
messager = new Messager( controlMask );
|
||||
adac = new RtAudio(0, 2, 0, 2, format, (int)Stk::sampleRate(), &bufferSize, 4);
|
||||
}
|
||||
catch (StkError &) {
|
||||
catch (RtError& error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// The runtime loop begins here:
|
||||
long i, nTicks;
|
||||
int type;
|
||||
lastSample = 0.0;
|
||||
inSample = 0.0;
|
||||
MY_FLOAT byte2, byte3;
|
||||
done = FALSE;
|
||||
while (!done) {
|
||||
data.envelope.setRate( 0.001 );
|
||||
data.effect = &(data.echo);
|
||||
|
||||
// Look for new messages and return a delta time (in samples).
|
||||
type = messager->nextMessage();
|
||||
if (type < 0)
|
||||
done = TRUE;
|
||||
// Install an interrupt handler function.
|
||||
(void) signal( SIGINT, finish );
|
||||
|
||||
nTicks = messager->getDelta();
|
||||
|
||||
for (i=0; i<nTicks; i++) {
|
||||
if (effect == 0)
|
||||
inSample = inout->tick(envelope->tick() * echo->tick(lastSample));
|
||||
else if (effect == 1)
|
||||
inSample = inout->tick(envelope->tick() * shifter->tick(lastSample));
|
||||
else if (effect == 2)
|
||||
inSample = inout->tick(envelope->tick() * chorus->tick(lastSample));
|
||||
else if (effect == 3)
|
||||
inSample = inout->tick(envelope->tick() * prcrev->tick(lastSample));
|
||||
else if (effect == 4)
|
||||
inSample = inout->tick(envelope->tick() * jcrev->tick(lastSample));
|
||||
else if (effect == 5)
|
||||
inSample = inout->tick(envelope->tick() * nrev->tick(lastSample));
|
||||
lastSample = inSample;
|
||||
}
|
||||
|
||||
if (type > 0) {
|
||||
// parse the input control message
|
||||
|
||||
byte2 = messager->getByteTwo();
|
||||
byte3 = messager->getByteThree();
|
||||
|
||||
switch(type) {
|
||||
|
||||
case __SK_NoteOn_:
|
||||
if (byte3 == 0) { // velocity is zero ... really a NoteOff
|
||||
envelope->setRate(0.001);
|
||||
envelope->setTarget(0.0);
|
||||
}
|
||||
else { // really a NoteOn
|
||||
envelope->setRate(0.001);
|
||||
envelope->setTarget(1.0);
|
||||
}
|
||||
break;
|
||||
|
||||
case __SK_NoteOff_:
|
||||
envelope->setRate(0.001);
|
||||
envelope->setTarget(0.0);
|
||||
break;
|
||||
|
||||
case __SK_ControlChange_:
|
||||
if (byte2 == 20) effect = (int) byte3; // effect change
|
||||
else if (byte2 == 44) { // effects mix
|
||||
echo->setEffectMix(byte3*ONE_OVER_128);
|
||||
shifter->setEffectMix(byte3*ONE_OVER_128);
|
||||
chorus->setEffectMix(byte3*ONE_OVER_128);
|
||||
prcrev->setEffectMix(byte3*ONE_OVER_128);
|
||||
jcrev->setEffectMix(byte3*ONE_OVER_128);
|
||||
nrev->setEffectMix(byte3*ONE_OVER_128);
|
||||
}
|
||||
else if (byte2 == 22) { // effect1 parameter change
|
||||
echo->setDelay(byte3*ONE_OVER_128*Stk::sampleRate()*0.95);
|
||||
shifter->setShift(byte3*ONE_OVER_128*3 + 0.25);
|
||||
chorus->setModFrequency(byte3*ONE_OVER_128);
|
||||
}
|
||||
else if (byte2 == 23) { // effect1 parameter change
|
||||
chorus->setModDepth(byte3*ONE_OVER_128*0.2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If realtime output, set our callback function and start the dac.
|
||||
try {
|
||||
adac->setStreamCallback( &tick, (void *)&data );
|
||||
adac->startStream();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
envelope->setRate(0.001);
|
||||
envelope->setTarget(0.0);
|
||||
nTicks = (long) Stk::sampleRate();
|
||||
for (i=0; i<nTicks; i++) { // let the sound settle a bit
|
||||
if (effect == 0)
|
||||
inSample = inout->tick(envelope->tick() * echo->tick(lastSample));
|
||||
else if (effect == 1)
|
||||
inSample = inout->tick(envelope->tick() * shifter->tick(lastSample));
|
||||
else if (effect == 2)
|
||||
inSample = inout->tick(envelope->tick() * chorus->tick(lastSample));
|
||||
else if (effect == 3)
|
||||
inSample = inout->tick(envelope->tick() * prcrev->tick(lastSample));
|
||||
else if (effect == 4)
|
||||
inSample = inout->tick(envelope->tick() * jcrev->tick(lastSample));
|
||||
else if (effect == 5)
|
||||
inSample = inout->tick(envelope->tick() * nrev->tick(lastSample));
|
||||
lastSample = inSample;
|
||||
// Setup finished.
|
||||
while ( !done ) {
|
||||
// Periodically check "done" status.
|
||||
Stk::sleep( 50 );
|
||||
}
|
||||
|
||||
delete echo;
|
||||
delete shifter;
|
||||
delete chorus;
|
||||
delete prcrev;
|
||||
delete jcrev;
|
||||
delete nrev;
|
||||
delete score;
|
||||
delete envelope;
|
||||
// Shut down the callback and output stream.
|
||||
try {
|
||||
adac->cancelStreamCallback();
|
||||
adac->closeStream();
|
||||
}
|
||||
catch (RtError& error) {
|
||||
error.printMessage();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
delete messager;
|
||||
delete inout;
|
||||
|
||||
printf("effects finished ... goodbye.\n");
|
||||
delete adac;
|
||||
|
||||
std::cout << "\neffects finished ... goodbye.\n\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -67,7 +67,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -118,6 +118,14 @@ SOURCE=..\..\include\Echo.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Effect.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Effect.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\effects.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -138,6 +146,14 @@ SOURCE=..\..\include\Filter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Generator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Generator.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\JCRev.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -154,6 +170,14 @@ SOURCE=..\..\include\Messager.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Mutex.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Mutex.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\NRev.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -178,14 +202,6 @@ SOURCE=..\..\include\PRCRev.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Reverb.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Reverb.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\RtAudio.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -194,14 +210,6 @@ SOURCE=..\..\include\RtAudio.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\RtDuplex.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\RtDuplex.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\RtMidi.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -26,7 +26,7 @@ label .title -text "STK Effects Controller" \
|
||||
-font {Times 14 bold} -background white \
|
||||
-foreground darkred -relief raised
|
||||
|
||||
label .title2 -text "by Gary P. Scavone\n Center for Computer Research in Music & Acoustics (CCRMA) \n Stanford University" \
|
||||
label .title2 -text "by Gary P. Scavone\n Music Technology, McGill University" \
|
||||
-font {Times 12 bold} -background white \
|
||||
-foreground darkred -relief raised
|
||||
|
||||
@@ -50,7 +50,7 @@ frame .left -bg black
|
||||
|
||||
scale .left.effectsmix -from 0 -to 127 -length 400 \
|
||||
-command {printWhatz "ControlChange 0.0 1 " 44} \
|
||||
-orient horizontal -label "Effects Mix" \
|
||||
-orient horizontal -label "Effects Mix (0% effect - 100% effect)" \
|
||||
-tickinterval 32 -showvalue true -bg grey66 \
|
||||
-variable mixlevel
|
||||
|
||||
@@ -132,7 +132,7 @@ proc changeEffect {tag value1 value2 } {
|
||||
.left.effect2 config -state disabled -label "Disabled"
|
||||
}
|
||||
if ($value2==1) {
|
||||
.left.effect1 config -state normal -label "Pitch Shift Amount"
|
||||
.left.effect1 config -state normal -label "Pitch Shift Amount (center = no shift)"
|
||||
.left.effect2 config -state disabled -label "Disabled"
|
||||
}
|
||||
if ($value2==2) {
|
||||
@@ -140,7 +140,7 @@ proc changeEffect {tag value1 value2 } {
|
||||
.left.effect2 config -state normal -label "Chorus Modulation Depth"
|
||||
}
|
||||
if {$value2>=3 && $value2<=5} {
|
||||
.left.effect1 config -state disabled -label "Disabled"
|
||||
.left.effect1 config -state normal -label "T60 Decay Time ( 0 - 10 seconds)"
|
||||
.left.effect2 config -state disabled -label "Disabled"
|
||||
}
|
||||
puts $outID [format "%s %i %f" $tag $value1 $value2]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
### STK examples Makefile - for various flavors of unix
|
||||
|
||||
PROGRAMS = sine play record io tcpIn tcpOut sineosc rtsine bethree controlbee foursine threebees
|
||||
PROGRAMS = sine play record io tcpIn tcpOut sineosc rtsine crtsine bethree controlbee foursine threebees playsmf
|
||||
RM = /bin/rm
|
||||
SRC_PATH = ../../src
|
||||
OBJECT_PATH = @object_path@
|
||||
@@ -23,7 +23,6 @@ LIBRARY += @frameworks@
|
||||
REALTIME = @realtime@
|
||||
ifeq ($(REALTIME),yes)
|
||||
DEFS += @audio_apis@
|
||||
DEFS += @midiator@
|
||||
endif
|
||||
|
||||
RAWWAVES = @rawwaves@
|
||||
@@ -46,8 +45,8 @@ clean :
|
||||
strip :
|
||||
strip $(PROGRAMS)
|
||||
|
||||
play: play.cpp Stk.o WvIn.o WvOut.o RtWvOut.o RtAudio.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o play play.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WvOut.o $(OBJECT_PATH)/RtWvOut.o $(OBJECT_PATH)/RtAudio.o $(LIBRARY)
|
||||
play: play.cpp Stk.o WvIn.o RtAudio.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o play play.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/RtAudio.o $(LIBRARY)
|
||||
|
||||
record: record.cpp Stk.o WvIn.o WvOut.o RtWvIn.o RtAudio.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o record record.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WvOut.o $(OBJECT_PATH)/RtWvIn.o $(OBJECT_PATH)/RtAudio.o $(LIBRARY)
|
||||
@@ -58,11 +57,11 @@ sine: sine.cpp Stk.o WvIn.o WvOut.o WaveLoop.o
|
||||
io: io.cpp Stk.o RtAudio.o RtDuplex.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o io io.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/RtAudio.o $(OBJECT_PATH)/RtDuplex.o $(LIBRARY)
|
||||
|
||||
tcpIn: tcpIn.cpp Stk.o WvIn.o TcpWvIn.o WvOut.o RtWvOut.o RtAudio.o Socket.o Thread.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o tcpIn tcpIn.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/Socket.o $(OBJECT_PATH)/Thread.o $(OBJECT_PATH)/TcpWvIn.o $(OBJECT_PATH)/WvOut.o $(OBJECT_PATH)/RtWvOut.o $(OBJECT_PATH)/RtAudio.o $(LIBRARY)
|
||||
tcpIn: tcpIn.cpp Stk.o WvIn.o TcpWvIn.o WvOut.o RtWvOut.o RtAudio.o Socket.o Thread.o Mutex.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o tcpIn tcpIn.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/Socket.o $(OBJECT_PATH)/Thread.o $(OBJECT_PATH)/Mutex.o $(OBJECT_PATH)/TcpWvIn.o $(OBJECT_PATH)/WvOut.o $(OBJECT_PATH)/RtWvOut.o $(OBJECT_PATH)/RtAudio.o $(LIBRARY)
|
||||
|
||||
tcpOut: tcpOut.cpp Stk.o WvIn.o WvOut.o TcpWvOut.o Socket.o Thread.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o tcpOut tcpOut.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WvOut.o $(OBJECT_PATH)/Socket.o $(OBJECT_PATH)/Thread.o $(OBJECT_PATH)/TcpWvOut.o $(LIBRARY)
|
||||
tcpOut: tcpOut.cpp Stk.o WvIn.o WvOut.o TcpWvOut.o Socket.o Thread.o Mutex.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o tcpOut tcpOut.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WvOut.o $(OBJECT_PATH)/Socket.o $(OBJECT_PATH)/Thread.o $(OBJECT_PATH)/Mutex.o $(OBJECT_PATH)/TcpWvOut.o $(LIBRARY)
|
||||
|
||||
sineosc: sineosc.cpp Stk.o WvIn.o WvOut.o WaveLoop.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o sineosc sineosc.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WvOut.o $(OBJECT_PATH)/WaveLoop.o $(LIBRARY)
|
||||
@@ -70,14 +69,20 @@ sineosc: sineosc.cpp Stk.o WvIn.o WvOut.o WaveLoop.o
|
||||
rtsine: rtsine.cpp Stk.o WvIn.o WaveLoop.o WvOut.o RtWvOut.o RtAudio.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o rtsine rtsine.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WaveLoop.o $(OBJECT_PATH)/WvOut.o $(OBJECT_PATH)/RtWvOut.o $(OBJECT_PATH)/RtAudio.o $(LIBRARY)
|
||||
|
||||
bethree: bethree.cpp Stk.o WvIn.o WaveLoop.o FM.o WvOut.o RtWvOut.o RtAudio.o Instrmnt.o Filter.o TwoZero.o Envelope.o ADSR.o BeeThree.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o bethree bethree.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WaveLoop.o $(OBJECT_PATH)/FM.o $(OBJECT_PATH)/WvOut.o $(OBJECT_PATH)/RtWvOut.o $(OBJECT_PATH)/RtAudio.o $(OBJECT_PATH)/Instrmnt.o $(OBJECT_PATH)/Filter.o $(OBJECT_PATH)/TwoZero.o $(OBJECT_PATH)/Envelope.o $(OBJECT_PATH)/ADSR.o $(OBJECT_PATH)/BeeThree.o $(LIBRARY)
|
||||
crtsine: crtsine.cpp Stk.o WvIn.o WaveLoop.o RtAudio.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o crtsine crtsine.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WaveLoop.o $(OBJECT_PATH)/RtAudio.o $(LIBRARY)
|
||||
|
||||
controlbee: controlbee.cpp Stk.o WvIn.o WaveLoop.o FM.o WvOut.o RtWvOut.o RtAudio.o Instrmnt.o Filter.o TwoZero.o Envelope.o ADSR.o BeeThree.o Messager.o RtMidi.o Socket.o Thread.o SKINI.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o controlbee controlbee.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WaveLoop.o $(OBJECT_PATH)/FM.o $(OBJECT_PATH)/WvOut.o $(OBJECT_PATH)/RtWvOut.o $(OBJECT_PATH)/RtAudio.o $(OBJECT_PATH)/Instrmnt.o $(OBJECT_PATH)/Filter.o $(OBJECT_PATH)/TwoZero.o $(OBJECT_PATH)/Envelope.o $(OBJECT_PATH)/ADSR.o $(OBJECT_PATH)/BeeThree.o $(OBJECT_PATH)/Messager.o $(OBJECT_PATH)/RtMidi.o $(OBJECT_PATH)/Socket.o $(OBJECT_PATH)/Thread.o $(OBJECT_PATH)/SKINI.o $(LIBRARY)
|
||||
bethree: bethree.cpp Stk.o WvIn.o WaveLoop.o FM.o RtAudio.o Instrmnt.o Filter.o TwoZero.o Generator.o Envelope.o ADSR.o BeeThree.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o bethree bethree.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WaveLoop.o $(OBJECT_PATH)/FM.o $(OBJECT_PATH)/RtAudio.o $(OBJECT_PATH)/Instrmnt.o $(OBJECT_PATH)/Filter.o $(OBJECT_PATH)/TwoZero.o $(OBJECT_PATH)/Generator.o $(OBJECT_PATH)/Envelope.o $(OBJECT_PATH)/ADSR.o $(OBJECT_PATH)/BeeThree.o $(LIBRARY)
|
||||
|
||||
controlbee: controlbee.cpp Stk.o WvIn.o WaveLoop.o FM.o RtAudio.o Instrmnt.o Filter.o TwoZero.o Generator.o Envelope.o ADSR.o BeeThree.o Messager.o RtMidi.o Socket.o Thread.o Mutex.o Skini.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o controlbee controlbee.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WaveLoop.o $(OBJECT_PATH)/FM.o $(OBJECT_PATH)/RtAudio.o $(OBJECT_PATH)/Instrmnt.o $(OBJECT_PATH)/Filter.o $(OBJECT_PATH)/TwoZero.o $(OBJECT_PATH)/Generator.o $(OBJECT_PATH)/Envelope.o $(OBJECT_PATH)/ADSR.o $(OBJECT_PATH)/BeeThree.o $(OBJECT_PATH)/Messager.o $(OBJECT_PATH)/RtMidi.o $(OBJECT_PATH)/Socket.o $(OBJECT_PATH)/Thread.o $(OBJECT_PATH)/Mutex.o $(OBJECT_PATH)/Skini.o $(LIBRARY)
|
||||
|
||||
foursine: foursine.cpp Stk.o WvIn.o WvOut.o WaveLoop.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o foursine foursine.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WvOut.o $(OBJECT_PATH)/WaveLoop.o $(LIBRARY)
|
||||
|
||||
threebees: threebees.cpp Stk.o WvIn.o WaveLoop.o FM.o WvOut.o RtWvOut.o RtAudio.o Instrmnt.o Filter.o TwoZero.o Envelope.o ADSR.o BeeThree.o Messager.o RtMidi.o Socket.o Thread.o SKINI.o Voicer.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o threebees threebees.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WaveLoop.o $(OBJECT_PATH)/FM.o $(OBJECT_PATH)/WvOut.o $(OBJECT_PATH)/RtWvOut.o $(OBJECT_PATH)/RtAudio.o $(OBJECT_PATH)/Instrmnt.o $(OBJECT_PATH)/Filter.o $(OBJECT_PATH)/TwoZero.o $(OBJECT_PATH)/Envelope.o $(OBJECT_PATH)/ADSR.o $(OBJECT_PATH)/BeeThree.o $(OBJECT_PATH)/Messager.o $(OBJECT_PATH)/RtMidi.o $(OBJECT_PATH)/Socket.o $(OBJECT_PATH)/Thread.o $(OBJECT_PATH)/SKINI.o $(OBJECT_PATH)/Voicer.o $(LIBRARY)
|
||||
threebees: threebees.cpp Stk.o WvIn.o WaveLoop.o FM.o RtAudio.o Instrmnt.o Filter.o TwoZero.o Generator.o Envelope.o ADSR.o BeeThree.o Messager.o RtMidi.o Socket.o Thread.o Mutex.o Skini.o Voicer.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o threebees threebees.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/WvIn.o $(OBJECT_PATH)/WaveLoop.o $(OBJECT_PATH)/FM.o $(OBJECT_PATH)/RtAudio.o $(OBJECT_PATH)/Instrmnt.o $(OBJECT_PATH)/Filter.o $(OBJECT_PATH)/TwoZero.o $(OBJECT_PATH)/Generator.o $(OBJECT_PATH)/Envelope.o $(OBJECT_PATH)/ADSR.o $(OBJECT_PATH)/BeeThree.o $(OBJECT_PATH)/Messager.o $(OBJECT_PATH)/RtMidi.o $(OBJECT_PATH)/Socket.o $(OBJECT_PATH)/Thread.o $(OBJECT_PATH)/Mutex.o $(OBJECT_PATH)/Skini.o $(OBJECT_PATH)/Voicer.o $(LIBRARY)
|
||||
|
||||
playsmf: playsmf.cpp Stk.o MidiFileIn.o RtMidi.o
|
||||
$(CC) $(CFLAGS) $(DEFS) -o playsmf playsmf.cpp $(OBJECT_PATH)/Stk.o $(OBJECT_PATH)/MidiFileIn.o $(OBJECT_PATH)/RtMidi.o $(LIBRARY)
|
||||
|
||||
@@ -1,7 +1,43 @@
|
||||
// bethree.cpp STK tutorial program
|
||||
|
||||
#include "BeeThree.h"
|
||||
#include "RtWvOut.h"
|
||||
#include "RtAudio.h"
|
||||
|
||||
// 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(char *buffer, int bufferSize, void *dataPointer)
|
||||
{
|
||||
TickData *data = (TickData *) dataPointer;
|
||||
register StkFloat *samples = (StkFloat *) buffer;
|
||||
|
||||
for ( int i=0; i<bufferSize; 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()
|
||||
{
|
||||
@@ -9,50 +45,56 @@ int main()
|
||||
Stk::setSampleRate( 44100.0 );
|
||||
Stk::setRawwavePath( "../../rawwaves/" );
|
||||
|
||||
Instrmnt *instrument = 0;
|
||||
RtWvOut *output = 0;
|
||||
MY_FLOAT frequency, amplitude, scaler;
|
||||
long counter, i;
|
||||
TickData data;
|
||||
RtAudio *dac = 0;
|
||||
|
||||
// Figure out how many bytes in an StkFloat and setup the RtAudio object.
|
||||
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
|
||||
int bufferSize = RT_BUFFER_SIZE;
|
||||
try {
|
||||
dac = new RtAudio(0, 1, 0, 0, format, (int)Stk::sampleRate(), &bufferSize, 4);
|
||||
}
|
||||
catch (RtError& error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
try {
|
||||
// Define and load the BeeThree instrument
|
||||
instrument = new BeeThree();
|
||||
|
||||
// Define and open the default realtime output device for one-channel playback
|
||||
output = new RtWvOut(1);
|
||||
data.instrument = new BeeThree();
|
||||
}
|
||||
catch (StkError &) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
scaler = 1.0;
|
||||
frequency = 220.0;
|
||||
amplitude = 0.5;
|
||||
instrument->noteOn( frequency, amplitude );
|
||||
data.frequency = 220.0;
|
||||
data.instrument->noteOn( data.frequency, 0.5 );
|
||||
|
||||
// Play the instrument for 80000 samples, changing the frequency every 2000 samples
|
||||
counter = 0;
|
||||
while ( counter < 80000 ) {
|
||||
for ( i=0; i<2000; i++ ) {
|
||||
try {
|
||||
output->tick( instrument->tick() );
|
||||
}
|
||||
catch (StkError &) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
counter += 2000;
|
||||
scaler += 0.025;
|
||||
instrument->setFrequency( frequency * scaler );
|
||||
try {
|
||||
dac->setStreamCallback(&tick, (void *)&data);
|
||||
dac->startStream();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Turn the instrument off with maximum decay envelope.
|
||||
instrument->noteOff( 1.0 );
|
||||
// Block waiting until callback signals done.
|
||||
while ( !data.done )
|
||||
Stk::sleep( 100 );
|
||||
|
||||
// Shut down the callback and output stream.
|
||||
try {
|
||||
dac->cancelStreamCallback();
|
||||
dac->closeStream();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
delete instrument;
|
||||
delete output;
|
||||
delete data.instrument;
|
||||
delete dac;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -42,14 +42,14 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_DS__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "bethree - Win32 Debug"
|
||||
@@ -65,15 +65,15 @@ LINK32=link.exe
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_DS__" /YX /FD /GZ /c
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
@@ -111,6 +111,10 @@ SOURCE=..\..\src\FM.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Generator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Instrmnt.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -167,6 +171,10 @@ SOURCE=..\..\include\FM.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Generator.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Instrmnt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -1,91 +1,175 @@
|
||||
// controlbee.cpp STK tutorial program
|
||||
|
||||
#include "BeeThree.h"
|
||||
#include "RtWvOut.h"
|
||||
#include "RtAudio.h"
|
||||
#include "Messager.h"
|
||||
#include "SKINI.msg"
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
#if !defined(__OS_WINDOWS__) // Windoze bogosity for VC++ 6.0
|
||||
using std::min;
|
||||
#endif
|
||||
|
||||
int main()
|
||||
void usage(void) {
|
||||
// Error function in case of incorrect command-line
|
||||
// argument specifications.
|
||||
std::cout << "\nuseage: controlbee file\n";
|
||||
std::cout << " where file = a SKINI scorefile.\n\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// The TickData structure holds all the class instances and data that
|
||||
// are shared by the various processing functions.
|
||||
struct TickData {
|
||||
Instrmnt *instrument;
|
||||
Messager messager;
|
||||
Skini::Message message;
|
||||
int counter;
|
||||
bool haveMessage;
|
||||
bool done;
|
||||
|
||||
// Default constructor.
|
||||
TickData()
|
||||
: instrument(0), counter(0), haveMessage(false), done( false ) {}
|
||||
};
|
||||
|
||||
#define DELTA_CONTROL_TICKS 64 // default sample frames between control input checks
|
||||
|
||||
// The processMessage() function encapsulates the handling of control
|
||||
// messages. It can be easily relocated within a program structure
|
||||
// depending on the desired scheduling scheme.
|
||||
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 ) // velocity is zero ... really a NoteOff
|
||||
data->instrument->noteOff( 0.5 );
|
||||
else { // a NoteOn
|
||||
StkFloat frequency = 220.0 * pow( 2.0, (value1 - 57.0) / 12.0 );
|
||||
data->instrument->noteOn( frequency, value2 * ONE_OVER_128 );
|
||||
}
|
||||
break;
|
||||
|
||||
case __SK_NoteOff_:
|
||||
data->instrument->noteOff( value2 * ONE_OVER_128 );
|
||||
break;
|
||||
|
||||
case __SK_ControlChange_:
|
||||
data->instrument->controlChange( (int) value1, value2 );
|
||||
break;
|
||||
|
||||
case __SK_AfterTouch_:
|
||||
data->instrument->controlChange( 128, value1 );
|
||||
|
||||
} // end of switch
|
||||
|
||||
data->haveMessage = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// This tick() function handles sample computation and scheduling of
|
||||
// control updates. It will be called automatically when the system
|
||||
// needs a new buffer of audio samples.
|
||||
int tick(char *buffer, int bufferSize, void *dataPointer)
|
||||
{
|
||||
TickData *data = (TickData *) dataPointer;
|
||||
register StkFloat *samples = (StkFloat *) buffer;
|
||||
int counter, nTicks = bufferSize;
|
||||
|
||||
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->instrument->tick();
|
||||
nTicks--;
|
||||
}
|
||||
if ( nTicks == 0 ) break;
|
||||
|
||||
// Process control messages.
|
||||
if ( data->haveMessage ) processMessage( data );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
if ( argc != 2 ) usage();
|
||||
|
||||
// Set the global sample rate and rawwave path before creating class instances.
|
||||
Stk::setSampleRate( 44100.0 );
|
||||
Stk::setRawwavePath( "../../rawwaves/" );
|
||||
|
||||
Instrmnt *instrument = 0;
|
||||
RtWvOut *output = 0;
|
||||
Messager *messager = 0;
|
||||
bool done = FALSE;
|
||||
TickData data;
|
||||
RtAudio *dac = 0;
|
||||
|
||||
// Figure out how many bytes in an StkFloat and setup the RtAudio object.
|
||||
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
|
||||
int bufferSize = RT_BUFFER_SIZE;
|
||||
try {
|
||||
dac = new RtAudio(0, 1, 0, 0, format, (int)Stk::sampleRate(), &bufferSize, 4);
|
||||
}
|
||||
catch (RtError& error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
try {
|
||||
// Define and load the BeeThree instrument
|
||||
instrument = new BeeThree();
|
||||
|
||||
// Define and open the default realtime output device for one-channel playback
|
||||
output = new RtWvOut(1);
|
||||
data.instrument = new BeeThree();
|
||||
}
|
||||
catch (StkError &) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ( data.messager.setScoreFile( argv[1] ) == false )
|
||||
goto cleanup;
|
||||
|
||||
try {
|
||||
// Create a Messager instance to read from a redirected SKINI scorefile.
|
||||
messager = new Messager();
|
||||
dac->setStreamCallback(&tick, (void *)&data);
|
||||
dac->startStream();
|
||||
}
|
||||
catch (StkError &) {
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Play the instrument until the end of the scorefile.
|
||||
int i, nTicks, type;
|
||||
MY_FLOAT byte2, byte3, frequency;
|
||||
while (!done) {
|
||||
|
||||
// Look for new messages and return a delta time (in samples).
|
||||
type = messager->nextMessage();
|
||||
if (type < 0)
|
||||
done = TRUE;
|
||||
|
||||
nTicks = messager->getDelta();
|
||||
try {
|
||||
for ( i=0; i<nTicks; i++ )
|
||||
output->tick( instrument->tick() );
|
||||
}
|
||||
catch (StkError &) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ( type > 0 ) {
|
||||
// Process the new control message.
|
||||
byte2 = messager->getByteTwo();
|
||||
byte3 = messager->getByteThree();
|
||||
|
||||
switch(type) {
|
||||
|
||||
case __SK_NoteOn_:
|
||||
frequency = (MY_FLOAT) 220.0 * pow( 2.0, (byte2 - 57.0) / 12.0 );
|
||||
instrument->noteOn( frequency, byte3 * ONE_OVER_128 );
|
||||
break;
|
||||
|
||||
case __SK_NoteOff_:
|
||||
instrument->noteOff( byte3 * ONE_OVER_128 );
|
||||
break;
|
||||
|
||||
case __SK_ControlChange_:
|
||||
instrument->controlChange( (int) byte2, byte3 );
|
||||
break;
|
||||
|
||||
case __SK_AfterTouch_:
|
||||
instrument->controlChange( 128, byte2 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Block waiting until callback signals done.
|
||||
while ( !data.done )
|
||||
Stk::sleep( 100 );
|
||||
|
||||
// Shut down the callback and output stream.
|
||||
try {
|
||||
dac->cancelStreamCallback();
|
||||
dac->closeStream();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
delete instrument;
|
||||
delete output;
|
||||
delete messager;
|
||||
delete data.instrument;
|
||||
delete dac;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_DS__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -67,7 +67,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_DS__" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -112,6 +112,10 @@ SOURCE=..\..\src\FM.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Generator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Instrmnt.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -120,6 +124,10 @@ SOURCE=..\..\src\Messager.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Mutex.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\RtAudio.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -196,6 +204,10 @@ SOURCE=..\..\include\Messager.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Mutex.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\RtAudio.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
78
projects/examples/crtsine.cpp
Normal file
78
projects/examples/crtsine.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
// crtsine.cpp STK tutorial program
|
||||
|
||||
#include "WaveLoop.h"
|
||||
#include "RtAudio.h"
|
||||
|
||||
// This tick() function handles sample computation only. It will be
|
||||
// called automatically when the system needs a new buffer of audio
|
||||
// samples.
|
||||
int tick(char *buffer, int bufferSize, void *dataPointer)
|
||||
{
|
||||
WaveLoop *sine = (WaveLoop *) dataPointer;
|
||||
register StkFloat *samples = (StkFloat *) buffer;
|
||||
|
||||
for ( int i=0; i<bufferSize; i++ )
|
||||
*samples++ = sine->tick();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// Set the global sample rate before creating class instances.
|
||||
Stk::setSampleRate( 44100.0 );
|
||||
|
||||
WaveLoop *sine = 0;
|
||||
RtAudio *dac = 0;
|
||||
|
||||
// Figure out how many bytes in an StkFloat and setup the RtAudio object.
|
||||
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
|
||||
int bufferSize = RT_BUFFER_SIZE;
|
||||
try {
|
||||
dac = new RtAudio(0, 1, 0, 0, format, (int)Stk::sampleRate(), &bufferSize, 4);
|
||||
}
|
||||
catch (RtError& error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
try {
|
||||
// Define and load the sine wave file
|
||||
sine = new WaveLoop( "rawwaves/sinewave.raw", true );
|
||||
}
|
||||
catch (StkError &) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sine->setFrequency(440.0);
|
||||
|
||||
try {
|
||||
dac->setStreamCallback(&tick, (void *)sine);
|
||||
dac->startStream();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Block waiting here.
|
||||
char keyhit;
|
||||
std::cout << "\nPlaying ... press <enter> to quit.\n";
|
||||
std::cin.get(keyhit);
|
||||
|
||||
// Shut down the callback and output stream.
|
||||
try {
|
||||
dac->cancelStreamCallback();
|
||||
dac->closeStream();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
delete sine;
|
||||
delete dac;
|
||||
|
||||
return 0;
|
||||
}
|
||||
134
projects/examples/crtsine.dsp
Executable file
134
projects/examples/crtsine.dsp
Executable file
@@ -0,0 +1,134 @@
|
||||
# Microsoft Developer Studio Project File - Name="crtsine" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=crtsine - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "crtsine.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "crtsine.mak" CFG="crtsine - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "crtsine - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "crtsine - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "crtsine - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "crtsine___Win32_Release"
|
||||
# PROP BASE Intermediate_Dir "crtsine___Win32_Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir ""
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_DS__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "crtsine - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "crtsine___Win32_Debug"
|
||||
# PROP BASE Intermediate_Dir "crtsine___Win32_Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir ""
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_DS__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "crtsine - Win32 Release"
|
||||
# Name "crtsine - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\crtsine.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\RtAudio.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Stk.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\WaveLoop.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\WvIn.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\RtAudio.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Stk.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\WaveLoop.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\WvIn.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -27,6 +27,18 @@ Package=<4>
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "crtsine"=".\crtsine.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "foursine"=".\foursine.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
|
||||
@@ -16,7 +16,7 @@ int main()
|
||||
// Define and load the sine waves
|
||||
try {
|
||||
for ( i=0; i<4; i++ ) {
|
||||
inputs[i] = new WaveLoop( "rawwaves/sinewave.raw", TRUE );
|
||||
inputs[i] = new WaveLoop( "rawwaves/sinewave.raw", true );
|
||||
inputs[i]->setFrequency( 220.0 * (i+1) );
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ int main()
|
||||
}
|
||||
|
||||
// Write two seconds of four sines to the output file
|
||||
MY_FLOAT frame[4];
|
||||
StkFloat frame[4];
|
||||
for ( j=0; j<88200; j++ ) {
|
||||
for ( i=0; i<4; i++ )
|
||||
frame[i] = inputs[i]->tick();
|
||||
|
||||
@@ -41,15 +41,15 @@ RSC=rc.exe
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /D "__WINDOWS_DS__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "foursine - Win32 Debug"
|
||||
|
||||
@@ -63,16 +63,16 @@ LINK32=link.exe
|
||||
# PROP Output_Dir ""
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /D "__WINDOWS_DS__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
/******************************************/
|
||||
/*
|
||||
Example program for realtime input/output
|
||||
by Gary P. Scavone, 2000
|
||||
by Gary P. Scavone, 2000.
|
||||
|
||||
This program reads N channels of realtime
|
||||
audio input for a specified amount of time
|
||||
and immediately play them back in realtime
|
||||
(duplex mode). This program also demonstrates
|
||||
the use of FIFO scheduling priority. To be
|
||||
run with such priority, the program must be
|
||||
set suid (chmod +s) and owned by root.
|
||||
NOTE: This program makes use of blocking audio
|
||||
input/output routines. On systems where the
|
||||
underlying audio API is based on a callback scheme
|
||||
(Macintosh OS-X, Windows ASIO, and Linux JACK), these
|
||||
routines are not fully robust (over/underruns can
|
||||
happen with some frequency). See the STK tutorial
|
||||
for example programs using callback schemes and/or
|
||||
visit the RtAudio tutorial page
|
||||
(http://music.mcgill.ca/~gary/rtaudio/) for more
|
||||
information.
|
||||
|
||||
This program reads N channels of realtime audio input
|
||||
for a specified amount of time and immediately play
|
||||
them back in realtime (duplex mode). This program
|
||||
also demonstrates the use of FIFO scheduling
|
||||
priority. To be run with such priority, the program
|
||||
must be set suid (chmod +s) and owned by root.
|
||||
*/
|
||||
/******************************************/
|
||||
|
||||
@@ -37,7 +47,7 @@ main(int argc, char *argv[])
|
||||
if (argc != 3) usage();
|
||||
|
||||
unsigned int channels = (unsigned int) atoi(argv[1]);
|
||||
float time = atof(argv[2]);
|
||||
double time = atof(argv[2]);
|
||||
|
||||
// If you want to change the default sample rate (set in Stk.h), do
|
||||
// it before instantiating any objects! If the sample rate is
|
||||
@@ -72,8 +82,8 @@ main(int argc, char *argv[])
|
||||
|
||||
// Here's the runtime loop
|
||||
unsigned long i, counter = 0;
|
||||
MY_FLOAT *newFrame = new MY_FLOAT[channels];
|
||||
const MY_FLOAT *lastFrame = inout->lastFrame();
|
||||
StkFloat *newFrame = new StkFloat[channels];
|
||||
const StkFloat *lastFrame = inout->lastFrame();
|
||||
unsigned long samples = (unsigned long) (time * Stk::sampleRate());
|
||||
while ( counter < samples ) {
|
||||
for ( i=0; i<channels; i++ )
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -66,7 +66,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
### STK examples Makefile - for various flavors of unix
|
||||
|
||||
PROGRAMS = sine play record io tcpIn tcpOut sineosc rtsine bethree controlbee foursine threebees
|
||||
PROGRAMS = sine play record io tcpIn tcpOut sineosc rtsine crtsine bethree controlbee foursine threebees playsmf
|
||||
RM = /bin/rm
|
||||
|
||||
INCLUDE = @include@
|
||||
@@ -64,6 +64,9 @@ sineosc: sineosc.cpp
|
||||
rtsine: rtsine.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -o rtsine rtsine.cpp -L../../src $(LIBRARY) -lstk
|
||||
|
||||
crtsine: crtsine.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -o crtsine crtsine.cpp -L../../src $(LIBRARY) -lstk
|
||||
|
||||
bethree: bethree.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -o bethree bethree.cpp -L../../src $(LIBRARY) -lstk
|
||||
|
||||
@@ -75,3 +78,7 @@ foursine: foursine.cpp
|
||||
|
||||
threebees: threebees.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -o threebees threebees.cpp -L../../src $(LIBRARY) -lstk
|
||||
|
||||
playsmf: playsmf.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -o playsmf playsmf.cpp -L../../src $(LIBRARY) -lstk
|
||||
|
||||
|
||||
BIN
projects/examples/midifiles/bwv772.mid
Normal file
BIN
projects/examples/midifiles/bwv772.mid
Normal file
Binary file not shown.
BIN
projects/examples/midifiles/jesu.mid
Normal file
BIN
projects/examples/midifiles/jesu.mid
Normal file
Binary file not shown.
BIN
projects/examples/midifiles/tango.mid
Normal file
BIN
projects/examples/midifiles/tango.mid
Normal file
Binary file not shown.
@@ -9,31 +9,62 @@
|
||||
the number of channels or sample rate of
|
||||
the soundfile, the program will stop.
|
||||
|
||||
By Gary P. Scavone, 2000 - 2002.
|
||||
By Gary P. Scavone, 2000 - 2004.
|
||||
*/
|
||||
/******************************************/
|
||||
|
||||
#include "RtWvOut.h"
|
||||
#include "WvIn.h"
|
||||
#include <stdlib.h>
|
||||
#include "RtAudio.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <iostream>
|
||||
|
||||
// Eewww ... global variables! :-)
|
||||
bool done;
|
||||
StkFrames frames;
|
||||
static void finish(int ignore){ done = true; }
|
||||
|
||||
void usage(void) {
|
||||
// Error function in case of incorrect command-line
|
||||
// argument specifications.
|
||||
printf("\nuseage: play file <rate>\n");
|
||||
printf(" where file = the file to play,\n");
|
||||
printf(" and rate = an optional playback rate.\n");
|
||||
printf(" (default = 1.0, can be negative)\n\n");
|
||||
std::cout << "\nuseage: play file sr <rate>\n";
|
||||
std::cout << " where file = the file to play,\n";
|
||||
std::cout << " where sr = sample rate,\n";
|
||||
std::cout << " and rate = an optional playback rate.\n";
|
||||
std::cout << " (default = 1.0, can be negative)\n\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// This tick() function handles sample computation only. It will be
|
||||
// called automatically when the system needs a new buffer of audio
|
||||
// samples.
|
||||
int tick(char *buffer, int bufferSize, void *dataPointer)
|
||||
{
|
||||
WvIn *input = (WvIn *) dataPointer;
|
||||
register StkFloat *samples = (StkFloat *) buffer;
|
||||
|
||||
input->tickFrame( frames );
|
||||
for ( unsigned int i=0; i<frames.size(); i++ )
|
||||
*samples++ = frames[i];
|
||||
|
||||
if ( input->isFinished() ) {
|
||||
done = true;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Minimal command-line checking.
|
||||
if (argc < 2 || argc > 3) usage();
|
||||
if (argc < 3 || argc > 4) usage();
|
||||
|
||||
// Initialize our WvIn/WvOut pointers.
|
||||
RtWvOut *output = 0;
|
||||
// Set the global sample rate before creating class instances.
|
||||
Stk::setSampleRate( (StkFloat) atof(argv[2]) );
|
||||
|
||||
// Initialize our WvIn and RtAudio pointers.
|
||||
RtAudio *dac = 0;
|
||||
WvIn *input = 0;
|
||||
|
||||
// Try to load the soundfile.
|
||||
@@ -45,29 +76,57 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// Set input read rate based on the default STK sample rate.
|
||||
float rate = 1.0;
|
||||
double rate = 1.0;
|
||||
rate = input->getFileRate() / Stk::sampleRate();
|
||||
if ( argc == 3 ) rate *= atof(argv[2]);
|
||||
if ( argc == 4 ) rate *= atof(argv[3]);
|
||||
input->setRate( rate );
|
||||
|
||||
// Find out how many channels we have.
|
||||
int channels = input->getChannels();
|
||||
|
||||
// Define and open the realtime output device
|
||||
// Define and open the realtime output device.
|
||||
// Figure out how many bytes in an StkFloat and setup the RtAudio object.
|
||||
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
|
||||
int bufferSize = RT_BUFFER_SIZE;
|
||||
try {
|
||||
output = new RtWvOut( channels, Stk::sampleRate(), 0, RT_BUFFER_SIZE, 4 );
|
||||
dac = new RtAudio(0, channels, 0, 0, format, (int)Stk::sampleRate(), &bufferSize, 4);
|
||||
}
|
||||
catch (StkError &) {
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Here's the runtime loop.
|
||||
while (!input->isFinished()) {
|
||||
output->tickFrame( input->tickFrame() );
|
||||
// Install an interrupt handler function.
|
||||
(void) signal(SIGINT, finish);
|
||||
|
||||
// Resize the StkFrames object appropriately.
|
||||
frames.resize( bufferSize, channels );
|
||||
|
||||
try {
|
||||
dac->setStreamCallback(&tick, (void *)input);
|
||||
dac->startStream();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Block waiting until callback signals done.
|
||||
while ( !done )
|
||||
Stk::sleep( 100 );
|
||||
|
||||
// By returning a non-zero value in the callback above, the stream
|
||||
// is automatically stopped. But we should still close it.
|
||||
try {
|
||||
dac->cancelStreamCallback();
|
||||
dac->closeStream();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
delete input;
|
||||
delete output;
|
||||
delete dac;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -66,7 +66,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
||||
122
projects/examples/playsmf.cpp
Normal file
122
projects/examples/playsmf.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
// playsmf.cpp
|
||||
//
|
||||
// Simple program to test the MidiFileIn class by reading and playing
|
||||
// a single track from a given Standard MIDI file.
|
||||
//
|
||||
// by Gary Scavone, 2003.
|
||||
|
||||
#include "MidiFileIn.h"
|
||||
#include "RtMidi.h"
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
bool done = false;
|
||||
static void finish(int ignore){ done = true; }
|
||||
|
||||
void usage(void) {
|
||||
// Error function in case of incorrect command-line
|
||||
// argument specifications.
|
||||
std::cout << "\nusage: playsmf file track <port>\n";
|
||||
std::cout << " where file = a standard MIDI file,\n";
|
||||
std::cout << " track = the track to play (0 = 1st track),\n";
|
||||
std::cout << " and an optional port integer identifier can be specified\n";
|
||||
std::cout << " (default = 0) or a value of -1 to use a virtual MIDI output port.\n\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
RtMidiOut *midiout = 0;
|
||||
|
||||
if ( argc < 3 || argc > 4 ) usage();
|
||||
|
||||
// Attempt to instantiate MIDI output class.
|
||||
try {
|
||||
midiout = new RtMidiOut();
|
||||
}
|
||||
catch ( RtError& error ) {
|
||||
error.printMessage();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Check command-line arguments.
|
||||
int port = 0;
|
||||
if ( argc == 4 ) port = atoi( argv[3] );
|
||||
if ( port == -1 ) {
|
||||
try {
|
||||
midiout->openVirtualPort();
|
||||
}
|
||||
catch ( RtError& error ) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
std::cout << "\nVirtual port open.\n\n";
|
||||
}
|
||||
else {
|
||||
if ( midiout->getPortCount() < 1 ) {
|
||||
std::cout << "\nThere are no MIDI output destinations available!\n\n";
|
||||
goto cleanup;
|
||||
}
|
||||
try {
|
||||
midiout->openPort( port );
|
||||
}
|
||||
catch ( RtError& error ) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// Install an interrupt handler function. Type "ctrl-c" to quit the
|
||||
// program.
|
||||
(void) signal(SIGINT, finish);
|
||||
|
||||
try {
|
||||
MidiFileIn midiFile( argv[1] );
|
||||
|
||||
// Print a little information about the file.
|
||||
std::cout << "\nThe MIDI file (" << argv[1] << ") information:\n";
|
||||
std::cout << " - format = " << midiFile.getFileFormat() << "\n";
|
||||
std::cout << " - tracks = " << midiFile.getNumberOfTracks() << "\n";
|
||||
std::cout << " - seconds / ticks = " << midiFile.getTickSeconds() << "\n";
|
||||
|
||||
unsigned int track = (unsigned int) atoi( argv[2] );
|
||||
if ( midiFile.getNumberOfTracks() <= track ) {
|
||||
std::cout << "\nInvalid track number ... playing track 0.\n";
|
||||
track = 0;
|
||||
}
|
||||
|
||||
std::cout << "\nPress <enter> to start reading/playing.\n";
|
||||
char input;
|
||||
std::cin.get(input);
|
||||
|
||||
std::vector<unsigned char> event;
|
||||
unsigned long ticks = midiFile.getNextMidiEvent( &event, track );
|
||||
while ( !done && event.size() ) {
|
||||
|
||||
// Pause for the MIDI event delta time.
|
||||
Stk::sleep( (unsigned long) (ticks * midiFile.getTickSeconds() * 1000 ) );
|
||||
|
||||
midiout->sendMessage( &event );
|
||||
|
||||
// Get a new event.
|
||||
ticks = midiFile.getNextMidiEvent( &event, track );
|
||||
}
|
||||
|
||||
// Send a "all notes off" to the synthesizer.
|
||||
event.clear();
|
||||
event.push_back( 0xb0 );
|
||||
event.push_back( 0x7b );
|
||||
event.push_back( 0x0 );
|
||||
midiout->sendMessage( &event );
|
||||
}
|
||||
catch ( StkError & ) {
|
||||
// You might want to do something more useful here.
|
||||
std::cout << "\nAborting program!\n";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
delete midiout;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3,6 +3,17 @@
|
||||
Example program to record N channels of data
|
||||
by Gary P. Scavone, 2000
|
||||
|
||||
NOTE: This program makes use of blocking audio
|
||||
input/output routines. On systems where the
|
||||
underlying audio API is based on a callback scheme
|
||||
(Macintosh OS-X, Windows ASIO, and Linux JACK), these
|
||||
routines are not fully robust (over/underruns can
|
||||
happen with some frequency). See the STK tutorial
|
||||
for example programs using callback schemes and/or
|
||||
visit the RtAudio tutorial page
|
||||
(http://music.mcgill.ca/~gary/rtaudio/) for more
|
||||
information.
|
||||
|
||||
This program is currently written to read
|
||||
from a realtime audio input device and to
|
||||
write to a WAV output file. However, it
|
||||
@@ -31,8 +42,8 @@ int main(int argc, char *argv[])
|
||||
if (argc != 5) usage();
|
||||
|
||||
int channels = (int) atoi(argv[1]);
|
||||
float sample_rate = atof(argv[4]);
|
||||
float time = atof(argv[3]);
|
||||
double sample_rate = atof(argv[4]);
|
||||
double time = atof(argv[3]);
|
||||
long samples, i;
|
||||
|
||||
// Set the global sample rate.
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# SUBTRACT CPP /Fr
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
@@ -68,7 +68,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
||||
@@ -8,27 +8,27 @@ int main()
|
||||
// Set the global sample rate before creating class instances.
|
||||
Stk::setSampleRate( 44100.0 );
|
||||
|
||||
WaveLoop *input = 0;
|
||||
RtWvOut *output = 0;
|
||||
WaveLoop *sine = 0;
|
||||
RtWvOut *dac = 0;
|
||||
|
||||
try {
|
||||
// Define and load the sine wave file
|
||||
input = new WaveLoop( "rawwaves/sinewave.raw", TRUE );
|
||||
sine = new WaveLoop( "rawwaves/sinewave.raw", true );
|
||||
|
||||
// Define and open the default realtime output device for one-channel playback
|
||||
output = new RtWvOut(1);
|
||||
dac = new RtWvOut(1);
|
||||
}
|
||||
catch (StkError &) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
input->setFrequency(440.0);
|
||||
sine->setFrequency(440.0);
|
||||
|
||||
// Play the oscillator for 40000 samples
|
||||
int i;
|
||||
for ( i=0; i<40000; i++ ) {
|
||||
try {
|
||||
output->tick(input->tick());
|
||||
dac->tick( sine->tick() );
|
||||
}
|
||||
catch (StkError &) {
|
||||
goto cleanup;
|
||||
@@ -36,8 +36,8 @@ int main()
|
||||
}
|
||||
|
||||
cleanup:
|
||||
delete input;
|
||||
delete output;
|
||||
delete sine;
|
||||
delete dac;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -42,14 +42,14 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_DS__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "rtsine - Win32 Debug"
|
||||
@@ -65,15 +65,15 @@ LINK32=link.exe
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
@@ -43,7 +43,7 @@ main(int argc, char *argv[])
|
||||
|
||||
// Initialize our object and data pointers.
|
||||
WvOut *output = 0;
|
||||
MY_FLOAT *vector = 0;
|
||||
StkFloat *vector = 0;
|
||||
WaveLoop **oscs = (WaveLoop **) malloc( channels * sizeof(WaveLoop *) );
|
||||
for (i=0; i<channels; i++) oscs[i] = 0;
|
||||
|
||||
@@ -54,7 +54,7 @@ main(int argc, char *argv[])
|
||||
// Define and load the rawwave file(s) ... the path is critical.
|
||||
try {
|
||||
for (i=0; i<channels; i++)
|
||||
oscs[i] = new WaveLoop( "../../rawwaves/sinewave.raw", TRUE );
|
||||
oscs[i] = new WaveLoop( "../../rawwaves/sinewave.raw", true );
|
||||
}
|
||||
catch (StkError &) {
|
||||
goto cleanup;
|
||||
@@ -67,7 +67,7 @@ main(int argc, char *argv[])
|
||||
// Define and open the soundfile for output. Other file
|
||||
// format options include: WVOUT_SND, WVOUT_AIF, WVOUT_MAT,
|
||||
// and WVOUT_RAW. Other data type options include:
|
||||
// STK_SINT8, STK_SINT32, MY_FLOAT32, and MY_FLOAT64.
|
||||
// STK_SINT8, STK_SINT32, StkFloat32, and StkFloat64.
|
||||
try {
|
||||
output = new WvOut( argv[2], channels, WvOut::WVOUT_WAV, Stk::STK_SINT16 );
|
||||
}
|
||||
@@ -77,7 +77,7 @@ main(int argc, char *argv[])
|
||||
|
||||
// Here's the runtime loop
|
||||
samples = (int) ( time * Stk::sampleRate() );
|
||||
vector = (MY_FLOAT *) new MY_FLOAT[channels];
|
||||
vector = (StkFloat *) new StkFloat[channels];
|
||||
for ( i=0; i<samples; i++ ) {
|
||||
for (int j=0; j<channels; j++) {
|
||||
vector[j] = oscs[j]->tick();
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /D "__WINDOWS_DS__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -66,7 +66,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /D "__WINDOWS_DS__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
||||
@@ -13,7 +13,7 @@ int main()
|
||||
|
||||
try {
|
||||
// Define and load the sine wave file
|
||||
input = new WaveLoop( "rawwaves/sinewave.raw", TRUE );
|
||||
input = new WaveLoop( "rawwaves/sinewave.raw", true );
|
||||
|
||||
// Define and open a 16-bit, one-channel WAV formatted output file
|
||||
output = new WvOut( "hellosine.wav", 1, WvOut::WVOUT_WAV, Stk::STK_SINT16 );
|
||||
|
||||
@@ -41,7 +41,7 @@ RSC=rc.exe
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /D "__WINDOWS_DS__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -65,7 +65,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "_AFXDLL" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "_AFXDLL" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /D "__WINDOWS_DS__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
|
||||
BSC32=bscmake.exe
|
||||
|
||||
@@ -6,6 +6,17 @@
|
||||
|
||||
by Gary P. Scavone, 2000
|
||||
|
||||
NOTE: This program makes use of blocking audio
|
||||
input/output routines. On systems where the
|
||||
underlying audio API is based on a callback scheme
|
||||
(Macintosh OS-X, Windows ASIO, and Linux JACK), these
|
||||
routines are not fully robust (over/underruns can
|
||||
happen with some frequency). See the STK tutorial
|
||||
for example programs using callback schemes and/or
|
||||
visit the RtAudio tutorial page
|
||||
(http://music.mcgill.ca/~gary/rtaudio/) for more
|
||||
information.
|
||||
|
||||
This program is currently written to play
|
||||
the input data in realtime. However, it
|
||||
is simple to replace the instance of
|
||||
@@ -15,7 +26,7 @@
|
||||
The streamed data format is assumed to be
|
||||
signed 16-bit integers. However, both
|
||||
TcpWvIn and TcpWvOut can be initialized
|
||||
to read/write any of the defined STK_FORMATs.
|
||||
to read/write any of the defined StkFormats.
|
||||
|
||||
The class TcpWvIn sets up a socket server
|
||||
and waits for a connection. Therefore,
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -66,7 +66,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -87,6 +87,10 @@ LINK32=link.exe
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Mutex.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\RtAudio.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
file. The output data format is set for
|
||||
signed 16-bit integers. However, it is
|
||||
easy to change the TcpWvOut setting to
|
||||
any of the other defined STK_FORMATs.
|
||||
any of the other defined StkFormats.
|
||||
If using tcpIn, it will be necessary to
|
||||
change the expected data format there
|
||||
as well.
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -66,7 +66,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
||||
@@ -1,11 +1,116 @@
|
||||
// threebees.cpp STK tutorial program
|
||||
|
||||
#include "BeeThree.h"
|
||||
#include "RtWvOut.h"
|
||||
#include "RtAudio.h"
|
||||
#include "Messager.h"
|
||||
#include "Voicer.h"
|
||||
#include "SKINI.msg"
|
||||
|
||||
#include <algorithm>
|
||||
#if !defined(__OS_WINDOWS__) // Windoze bogosity for VC++ 6.0
|
||||
using std::min;
|
||||
#endif
|
||||
|
||||
// The TickData structure holds all the class instances and data that
|
||||
// are shared by the various processing functions.
|
||||
struct TickData {
|
||||
Voicer voicer;
|
||||
Messager messager;
|
||||
Skini::Message message;
|
||||
int counter;
|
||||
bool haveMessage;
|
||||
bool done;
|
||||
|
||||
// Default constructor.
|
||||
TickData()
|
||||
: counter(0), haveMessage(false), done( false ) {}
|
||||
};
|
||||
|
||||
#define DELTA_CONTROL_TICKS 64 // default sample frames between control input checks
|
||||
|
||||
// The processMessage() function encapsulates the handling of control
|
||||
// messages. It can be easily relocated within a program structure
|
||||
// depending on the desired scheduling scheme.
|
||||
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 ) // velocity is zero ... really a NoteOff
|
||||
data->voicer.noteOff( value1, 64.0 );
|
||||
else { // a NoteOn
|
||||
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 );
|
||||
|
||||
} // end of switch
|
||||
|
||||
data->haveMessage = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// This tick() function handles sample computation and scheduling of
|
||||
// control updates. It will be called automatically when the system
|
||||
// needs a new buffer of audio samples.
|
||||
int tick(char *buffer, int bufferSize, void *dataPointer)
|
||||
{
|
||||
TickData *data = (TickData *) dataPointer;
|
||||
register StkFloat *samples = (StkFloat *) buffer;
|
||||
int counter, nTicks = bufferSize;
|
||||
|
||||
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;
|
||||
|
||||
// Process control messages.
|
||||
if ( data->haveMessage ) processMessage( data );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// Set the global sample rate and rawwave path before creating class instances.
|
||||
@@ -13,88 +118,63 @@ int main()
|
||||
Stk::setRawwavePath( "../../rawwaves/" );
|
||||
|
||||
int i;
|
||||
RtWvOut *output = 0;
|
||||
Messager *messager = 0;
|
||||
Voicer *voicer = 0;
|
||||
bool done = FALSE;
|
||||
TickData data;
|
||||
RtAudio *dac = 0;
|
||||
Instrmnt *instrument[3];
|
||||
for ( i=0; i<3; i++ ) instrument[i] = 0;
|
||||
|
||||
// Figure out how many bytes in an StkFloat and setup the RtAudio object.
|
||||
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
|
||||
int bufferSize = RT_BUFFER_SIZE;
|
||||
try {
|
||||
dac = new RtAudio(0, 1, 0, 0, format, (int)Stk::sampleRate(), &bufferSize, 4);
|
||||
}
|
||||
catch (RtError& error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
try {
|
||||
// Define and load the BeeThree instruments
|
||||
for ( i=0; i<3; i++ )
|
||||
instrument[i] = new BeeThree();
|
||||
|
||||
// Define and open the default realtime output device for one-channel playback
|
||||
output = new RtWvOut(1);
|
||||
}
|
||||
catch (StkError &) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// "Add" the instruments to the voicer.
|
||||
for ( i=0; i<3; i++ )
|
||||
data.voicer.addInstrument( instrument[i] );
|
||||
|
||||
if ( data.messager.startStdInput() == false )
|
||||
goto cleanup;
|
||||
|
||||
try {
|
||||
// Create a Messager instance to read from a redirected SKINI scorefile.
|
||||
messager = new Messager();
|
||||
dac->setStreamCallback(&tick, (void *)&data);
|
||||
dac->startStream();
|
||||
}
|
||||
catch (StkError &) {
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Instantiate the voicer for a maximum of three voices.
|
||||
voicer = new Voicer( 3 );
|
||||
for ( i=0; i<3; i++ )
|
||||
voicer->addInstrument( instrument[i] );
|
||||
|
||||
// Play the instrument until the end of the scorefile.
|
||||
int nTicks, type;
|
||||
MY_FLOAT byte2, byte3;
|
||||
while (!done) {
|
||||
|
||||
// Look for new messages and return a delta time (in samples).
|
||||
type = messager->nextMessage();
|
||||
if (type < 0)
|
||||
done = TRUE;
|
||||
|
||||
nTicks = messager->getDelta();
|
||||
try {
|
||||
for ( i=0; i<nTicks; i++ )
|
||||
output->tick( voicer->tick() );
|
||||
}
|
||||
catch (StkError &) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ( type > 0 ) {
|
||||
// Process the new control message.
|
||||
byte2 = messager->getByteTwo();
|
||||
byte3 = messager->getByteThree();
|
||||
|
||||
switch(type) {
|
||||
|
||||
case __SK_NoteOn_:
|
||||
voicer->noteOn( byte2, byte3 );
|
||||
break;
|
||||
|
||||
case __SK_NoteOff_:
|
||||
voicer->noteOff( byte2, byte3 );
|
||||
break;
|
||||
|
||||
case __SK_ControlChange_:
|
||||
voicer->controlChange( (int) byte2, byte3 );
|
||||
break;
|
||||
|
||||
case __SK_AfterTouch_:
|
||||
voicer->controlChange( 128, byte2 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Block waiting until callback signals done.
|
||||
while ( !data.done )
|
||||
Stk::sleep( 100 );
|
||||
|
||||
// Shut down the callback and output stream.
|
||||
try {
|
||||
dac->cancelStreamCallback();
|
||||
dac->closeStream();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
for ( i=0; i<3; i++ ) delete instrument[i];
|
||||
delete output;
|
||||
delete messager;
|
||||
delete voicer;
|
||||
delete dac;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -42,14 +42,14 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_DS__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib winmm.lib dsound.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "threebees - Win32 Debug"
|
||||
@@ -65,15 +65,15 @@ LINK32=link.exe
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_DS__" /YX /FD /GZ /c
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "_DEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Wsock32.lib winmm.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
@@ -107,6 +107,10 @@ SOURCE=..\..\src\FM.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Generator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Instrmnt.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -115,6 +119,10 @@ SOURCE=..\..\src\Messager.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Mutex.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\RtAudio.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -13,90 +13,101 @@
|
||||
Stanford, bearing the names of Karplus and/or
|
||||
Strong.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "Drone.h"
|
||||
|
||||
Drone :: Drone(MY_FLOAT lowestFrequency)
|
||||
Drone :: Drone(StkFloat lowestFrequency)
|
||||
{
|
||||
length = (long) (Stk::sampleRate() / lowestFrequency + 1);
|
||||
loopGain = (MY_FLOAT) 0.999;
|
||||
delayLine = new DelayA( (MY_FLOAT)(length / 2.0), length );
|
||||
loopFilter = new OneZero;
|
||||
noise = new Noise;
|
||||
envelope = new ADSR();
|
||||
envelope->setAllTimes(2.0, 0.5, 0.0, 0.5);
|
||||
length_ = (unsigned long) (Stk::sampleRate() / lowestFrequency + 1);
|
||||
loopGain_ = 0.999;
|
||||
delayLine_.setMaximumDelay( length_ );
|
||||
delayLine_.setDelay( 0.5 * length_ );
|
||||
envelope_.setAllTimes( 2.0, 0.5, 0.0, 0.5 );
|
||||
this->clear();
|
||||
}
|
||||
|
||||
Drone :: ~Drone()
|
||||
{
|
||||
delete delayLine;
|
||||
delete loopFilter;
|
||||
delete envelope;
|
||||
delete noise;
|
||||
}
|
||||
|
||||
void Drone :: clear()
|
||||
{
|
||||
delayLine->clear();
|
||||
loopFilter->clear();
|
||||
delayLine_.clear();
|
||||
loopFilter_.clear();
|
||||
}
|
||||
|
||||
void Drone :: setFrequency(MY_FLOAT frequency)
|
||||
void Drone :: setFrequency(StkFloat frequency)
|
||||
{
|
||||
MY_FLOAT freakency = frequency;
|
||||
StkFloat freakency = frequency;
|
||||
if ( frequency <= 0.0 ) {
|
||||
std::cerr << "Drone: setFrequency parameter is less than or equal to zero!" << std::endl;
|
||||
errorString_ << "Drone::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
freakency = 220.0;
|
||||
}
|
||||
|
||||
// Delay = length - approximate filter delay.
|
||||
MY_FLOAT delay = (Stk::sampleRate() / freakency) - (MY_FLOAT) 0.5;
|
||||
if (delay <= 0.0) delay = 0.3;
|
||||
else if (delay > length) delay = length;
|
||||
delayLine->setDelay(delay);
|
||||
loopGain = 0.997 + (freakency * 0.000002);
|
||||
if ( loopGain >= 1.0 ) loopGain = (MY_FLOAT) 0.99999;
|
||||
StkFloat delay = (Stk::sampleRate() / freakency) - 0.5;
|
||||
if ( delay <= 0.0 )
|
||||
delay = 0.3;
|
||||
else if (delay > length_)
|
||||
delay = length_;
|
||||
delayLine_.setDelay( delay );
|
||||
loopGain_ = 0.997 + (freakency * 0.000002);
|
||||
if ( loopGain_ >= 1.0 ) loopGain_ = 0.99999;
|
||||
}
|
||||
|
||||
void Drone :: pluck(MY_FLOAT amplitude)
|
||||
void Drone :: pluck(StkFloat amplitude)
|
||||
{
|
||||
envelope->keyOn();
|
||||
envelope_.keyOn();
|
||||
}
|
||||
|
||||
void Drone :: noteOn(MY_FLOAT frequency, MY_FLOAT amplitude)
|
||||
void Drone :: noteOn(StkFloat frequency, StkFloat amplitude)
|
||||
{
|
||||
this->setFrequency(frequency);
|
||||
this->pluck(amplitude);
|
||||
this->setFrequency( frequency );
|
||||
this->pluck( amplitude );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
std::cerr << "Drone: NoteOn frequency = " << frequency << ", amplitude = " << amplitude << std::endl;
|
||||
errorString_ << "Drone::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Drone :: noteOff(MY_FLOAT amplitude)
|
||||
void Drone :: noteOff(StkFloat amplitude)
|
||||
{
|
||||
loopGain = (MY_FLOAT) 1.0 - amplitude;
|
||||
if ( loopGain < 0.0 ) {
|
||||
std::cerr << "Drone: noteOff amplitude greater than 1.0!" << std::endl;
|
||||
loopGain = 0.0;
|
||||
loopGain_ = 1.0 - amplitude;
|
||||
if ( loopGain_ < 0.0 ) {
|
||||
errorString_ << "Drone::noteOff: amplitude is greater than 1.0 ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
loopGain_ = 0.0;
|
||||
}
|
||||
else if ( loopGain > 1.0 ) {
|
||||
std::cerr << "Drone: noteOff amplitude less than or zero!" << std::endl;
|
||||
loopGain = (MY_FLOAT) 0.99999;
|
||||
else if ( loopGain_ > 1.0 ) {
|
||||
errorString_ << "Drone::noteOff: amplitude is < 0.0 ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
loopGain_ = 0.99999;
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
std::cerr << "Drone: NoteOff amplitude = " << amplitude << std::endl;
|
||||
errorString_ << "Drone::noteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
MY_FLOAT Drone :: tick()
|
||||
StkFloat Drone :: tick()
|
||||
{
|
||||
// Here's the whole inner loop of the instrument!!
|
||||
lastOutput = delayLine->tick( loopFilter->tick( delayLine->lastOut() * loopGain ) + (0.005 * envelope->tick() * noise->tick()));
|
||||
return lastOutput;
|
||||
lastOutput_ = delayLine_.tick( loopFilter_.tick( delayLine_.lastOut() * loopGain_ ) + (0.005 * envelope_.tick() * noise_.tick()));
|
||||
return lastOutput_;
|
||||
}
|
||||
|
||||
StkFloat *Drone :: tick(StkFloat *vector, unsigned int vectorSize)
|
||||
{
|
||||
return Instrmnt::tick( vector, vectorSize );
|
||||
}
|
||||
|
||||
StkFrames& Drone :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
return Instrmnt::tick( frames, channel );
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
Stanford, bearing the names of Karplus and/or
|
||||
Strong.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#if !defined(__DRONE_H)
|
||||
#define __DRONE_H
|
||||
#ifndef STK_DRONE_H
|
||||
#define STK_DRONE_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayA.h"
|
||||
@@ -30,7 +30,7 @@ class Drone : public Instrmnt
|
||||
{
|
||||
public:
|
||||
//! Class constructor, taking the lowest desired playing frequency.
|
||||
Drone(MY_FLOAT lowestFrequency);
|
||||
Drone( StkFloat lowestFrequency = 20 );
|
||||
|
||||
//! Class destructor.
|
||||
~Drone();
|
||||
@@ -39,27 +39,39 @@ class Drone : public Instrmnt
|
||||
void clear();
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
virtual void setFrequency(MY_FLOAT frequency);
|
||||
virtual void setFrequency(StkFloat frequency);
|
||||
|
||||
//! Pluck the string with the given amplitude using the current frequency.
|
||||
void pluck(MY_FLOAT amplitude);
|
||||
void pluck(StkFloat amplitude);
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
virtual void noteOn(MY_FLOAT frequency, MY_FLOAT amplitude);
|
||||
virtual void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
virtual void noteOff(MY_FLOAT amplitude);
|
||||
virtual void noteOff(StkFloat amplitude);
|
||||
|
||||
//! Compute one output sample.
|
||||
virtual MY_FLOAT tick();
|
||||
virtual StkFloat tick();
|
||||
|
||||
//! Computer \e vectorSize outputs and return them in \e vector.
|
||||
virtual StkFloat *tick(StkFloat *vector, unsigned int vectorSize);
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument should be one or greater (the first
|
||||
channel is specified by 1). An StkError will be thrown if the \c
|
||||
channel argument is zero or it is greater than the number of
|
||||
channels in the StkFrames object.
|
||||
*/
|
||||
virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 1 );
|
||||
|
||||
protected:
|
||||
DelayA *delayLine;
|
||||
OneZero *loopFilter;
|
||||
ADSR *envelope;
|
||||
Noise *noise;
|
||||
long length;
|
||||
MY_FLOAT loopGain;
|
||||
DelayA delayLine_;
|
||||
OneZero loopFilter_;
|
||||
ADSR envelope_;
|
||||
Noise noise_;
|
||||
StkFloat loopGain_;
|
||||
unsigned long length_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@ SRC_PATH = ../../src
|
||||
OBJECT_PATH = @object_path@
|
||||
vpath %.o $(OBJECT_PATH)
|
||||
|
||||
OBJECTS = Stk.o Envelope.o ADSR.o Noise.o \
|
||||
OBJECTS = Stk.o Generator.o Noise.o Envelope.o ADSR.o \
|
||||
Filter.o DelayA.o Delay.o \
|
||||
OnePole.o OneZero.o SKINI.o \
|
||||
OnePole.o OneZero.o Skini.o \
|
||||
Tabla.o Instrmnt.o Sitar.o \
|
||||
Drone.o VoicDrum.o WvOut.o WvIn.o \
|
||||
Reverb.o JCRev.o Messager.o
|
||||
Effect.o JCRev.o Messager.o
|
||||
|
||||
INCLUDE = @include@
|
||||
ifeq ($(strip $(INCLUDE)), )
|
||||
@@ -29,9 +29,8 @@ LIBRARY += @frameworks@
|
||||
|
||||
REALTIME = @realtime@
|
||||
ifeq ($(REALTIME),yes)
|
||||
OBJECTS += RtMidi.o RtAudio.o RtWvOut.o Thread.o Socket.o
|
||||
OBJECTS += RtMidi.o RtAudio.o RtWvOut.o Thread.o Mutex.o Socket.o
|
||||
DEFS += @audio_apis@
|
||||
DEFS += @midiator@
|
||||
endif
|
||||
|
||||
RAWWAVES = @rawwaves@
|
||||
@@ -48,6 +47,9 @@ all : $(PROGRAMS)
|
||||
ragamat: ragamat.cpp $(OBJECTS)
|
||||
$(CC) $(CFLAGS) $(DEFS) -o ragamat ragamat.cpp $(OBJECT_PATH)/*.o $(LIBRARY)
|
||||
|
||||
libragamat: ragamat.cpp Tabla.cpp Drone.cpp VoicDrum.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -o ragamat Tabla.cpp Drone.cpp VoicDrum.cpp ragamat.cpp -L../../src $(LIBRARY) -lstk
|
||||
|
||||
$(OBJECTS) : Stk.h
|
||||
|
||||
clean :
|
||||
|
||||
1
projects/ragamatic/Raga
Executable file
1
projects/ragamatic/Raga
Executable file
@@ -0,0 +1 @@
|
||||
wish < tcl/Raga.tcl | ./ragamat -ip
|
||||
@@ -1 +1 @@
|
||||
wish < tcl/Raga.tcl | ./ragamat -ip
|
||||
wish < tcl/Raga.tcl | ragamat -ip
|
||||
|
||||
@@ -8,48 +8,49 @@
|
||||
at 22050 Hz, but will be appropriately
|
||||
interpolated for other sample rates. You can
|
||||
specify the maximum polyphony (maximum number
|
||||
of simultaneous voices) via a #define in the
|
||||
Drummer.h.
|
||||
of simultaneous voices) in Drummer.h.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "Tabla.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
Tabla :: Tabla() : Instrmnt()
|
||||
{
|
||||
for (int i=0; i<TABLA_POLYPHONY; i++) {
|
||||
filters[i] = new OnePole;
|
||||
sounding[i] = -1;
|
||||
for ( int i=0; i<TABLA_POLYPHONY; i++ ) {
|
||||
filters_[i] = new OnePole;
|
||||
sounding_[i] = -1;
|
||||
}
|
||||
|
||||
// This counts the number of sounding voices.
|
||||
nSounding = 0;
|
||||
nSounding_ = 0;
|
||||
}
|
||||
|
||||
Tabla :: ~Tabla()
|
||||
{
|
||||
int i;
|
||||
for ( i=0; i<nSounding-1; i++ ) delete waves[i];
|
||||
for ( i=0; i<TABLA_POLYPHONY; i++ ) delete filters[i];
|
||||
for ( i=0; i<nSounding_; i++ ) delete waves_[i];
|
||||
for ( i=0; i<TABLA_POLYPHONY; i++ ) delete filters_[i];
|
||||
}
|
||||
|
||||
void Tabla :: noteOn(MY_FLOAT instrument, MY_FLOAT amplitude)
|
||||
void Tabla :: noteOn(StkFloat instrument, StkFloat amplitude)
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
std::cerr << "Tabla: NoteOn instrument = " << instrument << ", amplitude = " << amplitude << std::endl;
|
||||
errorString_ << "Tabla::noteOn: instrument = " << instrument << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
|
||||
MY_FLOAT gain = amplitude;
|
||||
StkFloat gain = amplitude;
|
||||
if ( amplitude > 1.0 ) {
|
||||
std::cerr << "Tabla: noteOn amplitude parameter is greater than 1.0!" << std::endl;
|
||||
errorString_ << "Tabla::noteOn: amplitude parameter is greater than 1.0 ... setting to 1.0.";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 1.0;
|
||||
}
|
||||
else if ( amplitude < 0.0 ) {
|
||||
std::cerr << "Tabla: noteOn amplitude parameter is less than 0.0!" << std::endl;
|
||||
errorString_ << "Tabla::noteOn: amplitude parameter is less than 0.0 ... doing nothing.";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -71,91 +72,99 @@ void Tabla :: noteOn(MY_FLOAT instrument, MY_FLOAT amplitude)
|
||||
"DrTak2.raw"
|
||||
};
|
||||
|
||||
int noteNum = ((int) instrument) % 16;
|
||||
int noteNum = ( (int) instrument ) % 16;
|
||||
|
||||
// Check first to see if there's already one like this sounding.
|
||||
int i, waveIndex = -1;
|
||||
for (i=0; i<TABLA_POLYPHONY; i++) {
|
||||
if (sounding[i] == noteNum) waveIndex = i;
|
||||
for ( i=0; i<TABLA_POLYPHONY; i++ ) {
|
||||
if ( sounding_[i] == noteNum ) waveIndex = i;
|
||||
}
|
||||
|
||||
if ( waveIndex >= 0 ) {
|
||||
// Reset this sound.
|
||||
waves[waveIndex]->reset();
|
||||
filters[waveIndex]->setPole((MY_FLOAT) 0.999 - (gain * 0.6));
|
||||
filters[waveIndex]->setGain(gain);
|
||||
waves_[waveIndex]->reset();
|
||||
filters_[waveIndex]->setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[waveIndex]->setGain( gain );
|
||||
}
|
||||
else {
|
||||
if (nSounding == TABLA_POLYPHONY) {
|
||||
if ( nSounding_ == TABLA_POLYPHONY ) {
|
||||
// If we're already at maximum polyphony, then preempt the oldest voice.
|
||||
delete waves[0];
|
||||
filters[0]->clear();
|
||||
WvIn *tempWv = waves[0];
|
||||
OnePole *tempFilt = filters[0];
|
||||
delete waves_[0];
|
||||
filters_[0]->clear();
|
||||
OnePole *tempFilt = filters_[0];
|
||||
// Re-order the list.
|
||||
for (i=0; i<TABLA_POLYPHONY-1; i++) {
|
||||
waves[i] = waves[i+1];
|
||||
filters[i] = filters[i+1];
|
||||
for ( i=0; i<TABLA_POLYPHONY-1; i++ ) {
|
||||
waves_[i] = waves_[i+1];
|
||||
filters_[i] = filters_[i+1];
|
||||
}
|
||||
waves[TABLA_POLYPHONY-1] = tempWv;
|
||||
filters[TABLA_POLYPHONY-1] = tempFilt;
|
||||
waves_[TABLA_POLYPHONY-1] = 0;
|
||||
filters_[TABLA_POLYPHONY-1] = tempFilt;
|
||||
}
|
||||
else
|
||||
nSounding += 1;
|
||||
nSounding_ += 1;
|
||||
|
||||
sounding[nSounding-1] = noteNum;
|
||||
// Concatenate the STK RAWWAVE_PATH to the rawwave file
|
||||
char path[128];
|
||||
strcpy(path, "rawwaves/");
|
||||
strcat(path, tablaWaves[noteNum]);
|
||||
waves[nSounding-1] = new WvIn(path, TRUE);
|
||||
waves[nSounding-1]->normalize(0.4);
|
||||
filters[nSounding-1]->setPole((MY_FLOAT) 0.999 - (gain * 0.6) );
|
||||
filters[nSounding-1]->setGain( gain );
|
||||
sounding_[nSounding_-1] = noteNum;
|
||||
// Concatenate the rawwave path to the file name.
|
||||
waves_[nSounding_-1] = new WvIn( (std::string("rawwaves/") + tablaWaves[noteNum]).c_str(), true );
|
||||
waves_[nSounding_-1]->normalize(0.4);
|
||||
if ( Stk::sampleRate() != 22050.0 )
|
||||
waves_[nSounding_-1]->setRate( 22050.0 / Stk::sampleRate() );
|
||||
filters_[nSounding_-1]->setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[nSounding_-1]->setGain( gain );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
std::cerr << "Number Sounding = " << nSounding << std::endl;
|
||||
for (i=0; i<nSounding; i++) std::cerr << sounding[i] << " ";
|
||||
std::cerr << "\n";
|
||||
errorString_ << "Tabla::noteOn: number sounding = " << nSounding_ << '\n';
|
||||
for (i=0; i<nSounding_; i++) errorString_ << sounding_[i] << " ";
|
||||
errorString_ << '\n';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Tabla :: noteOff(MY_FLOAT amplitude)
|
||||
void Tabla :: noteOff(StkFloat amplitude)
|
||||
{
|
||||
// Set all sounding wave filter gains low.
|
||||
int i = 0;
|
||||
while(i < nSounding) {
|
||||
filters[i++]->setGain( amplitude * 0.01 );
|
||||
}
|
||||
while ( i < nSounding_ )
|
||||
filters_[i++]->setGain( amplitude * 0.01 );
|
||||
}
|
||||
|
||||
MY_FLOAT Tabla :: tick()
|
||||
StkFloat Tabla :: tick()
|
||||
{
|
||||
MY_FLOAT output = 0.0;
|
||||
OnePole *tempFilt;
|
||||
|
||||
int j, i = 0;
|
||||
while (i < nSounding) {
|
||||
if ( waves[i]->isFinished() ) {
|
||||
delete waves[i];
|
||||
tempFilt = filters[i];
|
||||
lastOutput_ = 0.0;
|
||||
while ( i < nSounding_ ) {
|
||||
if ( waves_[i]->isFinished() ) {
|
||||
delete waves_[i];
|
||||
tempFilt = filters_[i];
|
||||
// Re-order the list.
|
||||
for (j=i; j<nSounding-1; j++) {
|
||||
sounding[j] = sounding[j+1];
|
||||
waves[j] = waves[j+1];
|
||||
filters[j] = filters[j+1];
|
||||
for ( j=i; j<nSounding_-1; j++ ) {
|
||||
sounding_[j] = sounding_[j+1];
|
||||
waves_[j] = waves_[j+1];
|
||||
filters_[j] = filters_[j+1];
|
||||
}
|
||||
filters[j] = tempFilt;
|
||||
filters[j]->clear();
|
||||
sounding[j] = -1;
|
||||
nSounding -= 1;
|
||||
filters_[j] = tempFilt;
|
||||
filters_[j]->clear();
|
||||
sounding_[j] = -1;
|
||||
nSounding_ -= 1;
|
||||
i -= 1;
|
||||
}
|
||||
else
|
||||
output += filters[i]->tick( waves[i]->tick() );
|
||||
lastOutput_ += filters_[i]->tick( waves_[i]->tick() );
|
||||
i++;
|
||||
}
|
||||
|
||||
return output;
|
||||
return lastOutput_;
|
||||
}
|
||||
|
||||
StkFloat *Tabla :: tick(StkFloat *vector, unsigned int vectorSize)
|
||||
{
|
||||
return Instrmnt::tick( vector, vectorSize );
|
||||
}
|
||||
|
||||
StkFrames& Tabla :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
return Instrmnt::tick( frames, channel );
|
||||
}
|
||||
|
||||
@@ -8,22 +8,21 @@
|
||||
at 22050 Hz, but will be appropriately
|
||||
interpolated for other sample rates. You can
|
||||
specify the maximum polyphony (maximum number
|
||||
of simultaneous voices) via a #define in the
|
||||
Drummer.h.
|
||||
of simultaneous voices) in Drummer.h.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#if !defined(__TABLA_H)
|
||||
#define __TABLA_H
|
||||
#ifndef STK_TABLA_H
|
||||
#define STK_TABLA_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "WvIn.h"
|
||||
#include "OnePole.h"
|
||||
|
||||
#define TABLA_NUMWAVES 15
|
||||
#define TABLA_POLYPHONY 4
|
||||
const int TABLA_NUMWAVES = 15;
|
||||
const int TABLA_POLYPHONY = 4;
|
||||
|
||||
class Tabla : public Instrmnt
|
||||
{
|
||||
@@ -35,19 +34,31 @@ class Tabla : public Instrmnt
|
||||
~Tabla();
|
||||
|
||||
//! Start a note with the given drum type and amplitude.
|
||||
void noteOn(MY_FLOAT instrument, MY_FLOAT amplitude);
|
||||
void noteOn(StkFloat instrument, StkFloat amplitude);
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(MY_FLOAT amplitude);
|
||||
void noteOff(StkFloat amplitude);
|
||||
|
||||
//! Compute one output sample.
|
||||
MY_FLOAT tick();
|
||||
StkFloat tick();
|
||||
|
||||
//! Computer \e vectorSize outputs and return them in \e vector.
|
||||
StkFloat *tick(StkFloat *vector, unsigned int vectorSize);
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument should be one or greater (the first
|
||||
channel is specified by 1). An StkError will be thrown if the \c
|
||||
channel argument is zero or it is greater than the number of
|
||||
channels in the StkFrames object.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 1 );
|
||||
|
||||
protected:
|
||||
WvIn *waves[TABLA_POLYPHONY];
|
||||
OnePole *filters[TABLA_POLYPHONY];
|
||||
int sounding[TABLA_POLYPHONY];
|
||||
int nSounding;
|
||||
WvIn *waves_[TABLA_POLYPHONY];
|
||||
OnePole *filters_[TABLA_POLYPHONY];
|
||||
int sounding_[TABLA_POLYPHONY];
|
||||
int nSounding_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -8,48 +8,49 @@
|
||||
at 22050 Hz, but will be appropriately
|
||||
interpolated for other sample rates. You can
|
||||
specify the maximum polyphony (maximum number
|
||||
of simultaneous voices) via a #define in the
|
||||
Drummer.h.
|
||||
of simultaneous voices) in Drummer.h.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "VoicDrum.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
VoicDrum :: VoicDrum() : Instrmnt()
|
||||
{
|
||||
for (int i=0; i<VOICE_POLYPHONY; i++) {
|
||||
filters[i] = new OnePole;
|
||||
sounding[i] = -1;
|
||||
for ( int i=0; i<VOICE_POLYPHONY; i++ ) {
|
||||
filters_[i] = new OnePole;
|
||||
sounding_[i] = -1;
|
||||
}
|
||||
|
||||
// This counts the number of sounding voices.
|
||||
nSounding = 0;
|
||||
nSounding_ = 0;
|
||||
}
|
||||
|
||||
VoicDrum :: ~VoicDrum()
|
||||
{
|
||||
int i;
|
||||
for ( i=0; i<nSounding-1; i++ ) delete waves[i];
|
||||
for ( i=0; i<VOICE_POLYPHONY; i++ ) delete filters[i];
|
||||
for ( i=0; i<nSounding_; i++ ) delete waves_[i];
|
||||
for ( i=0; i<VOICE_POLYPHONY; i++ ) delete filters_[i];
|
||||
}
|
||||
|
||||
void VoicDrum :: noteOn(MY_FLOAT instrument, MY_FLOAT amplitude)
|
||||
void VoicDrum :: noteOn( StkFloat instrument, StkFloat amplitude )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
std::cerr << "VoicDrum: NoteOn instrument = " << instrument << ", amplitude = " << amplitude << std::endl;
|
||||
errorString_ << "VoicDrum::noteOn: instrument = " << instrument << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
|
||||
MY_FLOAT gain = amplitude;
|
||||
StkFloat gain = amplitude;
|
||||
if ( amplitude > 1.0 ) {
|
||||
std::cerr << "VoicDrum: noteOn amplitude parameter is greater than 1.0!" << std::endl;
|
||||
errorString_ << "VoicDrum::noteOn: amplitude parameter is greater than 1.0 ... setting to 1.0.";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 1.0;
|
||||
}
|
||||
else if ( amplitude < 0.0 ) {
|
||||
std::cerr << "VoicDrum: noteOn amplitude parameter is less than 0.0!" << std::endl;
|
||||
errorString_ << "VoicDrum::noteOn: amplitude parameter is less than 0.0 ... doing nothing.";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -68,91 +69,98 @@ void VoicDrum :: noteOn(MY_FLOAT instrument, MY_FLOAT amplitude)
|
||||
"tak4.raw"
|
||||
};
|
||||
|
||||
int noteNum = ((int) instrument) % 11;
|
||||
int noteNum = ( (int) instrument ) % 11;
|
||||
|
||||
// Check first to see if there's already one like this sounding.
|
||||
int i, waveIndex = -1;
|
||||
for (i=0; i<VOICE_POLYPHONY; i++) {
|
||||
if (sounding[i] == noteNum) waveIndex = i;
|
||||
for ( i=0; i<VOICE_POLYPHONY; i++ ) {
|
||||
if ( sounding_[i] == noteNum ) waveIndex = i;
|
||||
}
|
||||
|
||||
if ( waveIndex >= 0 ) {
|
||||
// Reset this sound.
|
||||
waves[waveIndex]->reset();
|
||||
filters[waveIndex]->setPole((MY_FLOAT) 0.999 - (gain * 0.6));
|
||||
filters[waveIndex]->setGain(gain);
|
||||
waves_[waveIndex]->reset();
|
||||
filters_[waveIndex]->setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[waveIndex]->setGain( gain );
|
||||
}
|
||||
else {
|
||||
if (nSounding == VOICE_POLYPHONY) {
|
||||
if ( nSounding_ == VOICE_POLYPHONY ) {
|
||||
// If we're already at maximum polyphony, then preempt the oldest voice.
|
||||
delete waves[0];
|
||||
filters[0]->clear();
|
||||
WvIn *tempWv = waves[0];
|
||||
OnePole *tempFilt = filters[0];
|
||||
delete waves_[0];
|
||||
filters_[0]->clear();
|
||||
OnePole *tempFilt = filters_[0];
|
||||
// Re-order the list.
|
||||
for (i=0; i<VOICE_POLYPHONY-1; i++) {
|
||||
waves[i] = waves[i+1];
|
||||
filters[i] = filters[i+1];
|
||||
for ( i=0; i<VOICE_POLYPHONY-1; i++ ) {
|
||||
waves_[i] = waves_[i+1];
|
||||
filters_[i] = filters_[i+1];
|
||||
}
|
||||
waves[VOICE_POLYPHONY-1] = tempWv;
|
||||
filters[VOICE_POLYPHONY-1] = tempFilt;
|
||||
waves_[VOICE_POLYPHONY-1] = 0;
|
||||
filters_[VOICE_POLYPHONY-1] = tempFilt;
|
||||
}
|
||||
else
|
||||
nSounding += 1;
|
||||
nSounding_ += 1;
|
||||
|
||||
sounding[nSounding-1] = noteNum;
|
||||
// Concatenate the STK RAWWAVE_PATH to the rawwave file
|
||||
char path[128];
|
||||
strcpy(path, "rawwaves/");
|
||||
strcat(path, voiceNames[noteNum]);
|
||||
waves[nSounding-1] = new WvIn(path, TRUE);
|
||||
waves[nSounding-1]->normalize(0.4);
|
||||
filters[nSounding-1]->setPole((MY_FLOAT) 0.999 - (gain * 0.6) );
|
||||
filters[nSounding-1]->setGain( gain );
|
||||
sounding_[nSounding_-1] = noteNum;
|
||||
// Concatenate the rawwave path to the file name.
|
||||
waves_[nSounding_-1] = new WvIn( (std::string("rawwaves/") + voiceNames[noteNum]).c_str(), true );
|
||||
waves_[nSounding_-1]->normalize(0.4);
|
||||
if (Stk::sampleRate() != 22050.0)
|
||||
waves_[nSounding_-1]->setRate( 22050.0 / Stk::sampleRate() );
|
||||
filters_[nSounding_-1]->setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[nSounding_-1]->setGain( gain );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
std::cerr << "Number Sounding = " << nSounding << std::endl;
|
||||
for (i=0; i<nSounding; i++) std::cerr << sounding[i] << " ";
|
||||
std::cerr << "\n";
|
||||
errorString_ << "VoicDrum::noteOn: number sounding = " << nSounding_ << '\n';
|
||||
for (i=0; i<nSounding_; i++) errorString_ << sounding_[i] << " ";
|
||||
errorString_ << '\n';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void VoicDrum :: noteOff(MY_FLOAT amplitude)
|
||||
void VoicDrum :: noteOff(StkFloat amplitude)
|
||||
{
|
||||
// Set all sounding wave filter gains low.
|
||||
int i = 0;
|
||||
while(i < nSounding) {
|
||||
filters[i++]->setGain( amplitude * 0.01 );
|
||||
}
|
||||
while ( i < nSounding_ ) filters_[i++]->setGain( amplitude * 0.01 );
|
||||
}
|
||||
|
||||
MY_FLOAT VoicDrum :: tick()
|
||||
StkFloat VoicDrum :: tick()
|
||||
{
|
||||
MY_FLOAT output = 0.0;
|
||||
OnePole *tempFilt;
|
||||
|
||||
int j, i = 0;
|
||||
while (i < nSounding) {
|
||||
if ( waves[i]->isFinished() ) {
|
||||
delete waves[i];
|
||||
tempFilt = filters[i];
|
||||
lastOutput_ = 0.0;
|
||||
while ( i < nSounding_ ) {
|
||||
if ( waves_[i]->isFinished() ) {
|
||||
delete waves_[i];
|
||||
tempFilt = filters_[i];
|
||||
// Re-order the list.
|
||||
for (j=i; j<nSounding-1; j++) {
|
||||
sounding[j] = sounding[j+1];
|
||||
waves[j] = waves[j+1];
|
||||
filters[j] = filters[j+1];
|
||||
for ( j=i; j<nSounding_-1; j++ ) {
|
||||
sounding_[j] = sounding_[j+1];
|
||||
waves_[j] = waves_[j+1];
|
||||
filters_[j] = filters_[j+1];
|
||||
}
|
||||
filters[j] = tempFilt;
|
||||
filters[j]->clear();
|
||||
sounding[j] = -1;
|
||||
nSounding -= 1;
|
||||
filters_[j] = tempFilt;
|
||||
filters_[j]->clear();
|
||||
sounding_[j] = -1;
|
||||
nSounding_ -= 1;
|
||||
i -= 1;
|
||||
}
|
||||
else
|
||||
output += filters[i]->tick( waves[i]->tick() );
|
||||
lastOutput_ += filters_[i]->tick( waves_[i]->tick() );
|
||||
i++;
|
||||
}
|
||||
|
||||
return output;
|
||||
return lastOutput_;
|
||||
}
|
||||
|
||||
StkFloat *VoicDrum :: tick(StkFloat *vector, unsigned int vectorSize)
|
||||
{
|
||||
return Instrmnt::tick( vector, vectorSize );
|
||||
}
|
||||
|
||||
StkFrames& VoicDrum :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
return Instrmnt::tick( frames, channel );
|
||||
}
|
||||
|
||||
@@ -8,22 +8,21 @@
|
||||
at 22050 Hz, but will be appropriately
|
||||
interpolated for other sample rates. You can
|
||||
specify the maximum polyphony (maximum number
|
||||
of simultaneous voices) via a #define in the
|
||||
Drummer.h.
|
||||
of simultaneous voices) in Drummer.h.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#if !defined(__VOICDRUM_H)
|
||||
#define __VOICDRUM_H
|
||||
#ifndef STK_VOICDRUM_H
|
||||
#define STK_VOICDRUM_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "WvIn.h"
|
||||
#include "OnePole.h"
|
||||
|
||||
#define VOICE_NUMWAVES 11
|
||||
#define VOICE_POLYPHONY 4
|
||||
const int VOICE_NUMWAVES = 11;
|
||||
const int VOICE_POLYPHONY = 4;
|
||||
|
||||
class VoicDrum : public Instrmnt
|
||||
{
|
||||
@@ -35,19 +34,31 @@ class VoicDrum : public Instrmnt
|
||||
~VoicDrum();
|
||||
|
||||
//! Start a note with the given drum type and amplitude.
|
||||
void noteOn(MY_FLOAT instrument, MY_FLOAT amplitude);
|
||||
void noteOn(StkFloat instrument, StkFloat amplitude);
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(MY_FLOAT amplitude);
|
||||
void noteOff(StkFloat amplitude);
|
||||
|
||||
//! Compute one output sample.
|
||||
MY_FLOAT tick();
|
||||
StkFloat tick();
|
||||
|
||||
//! Computer \e vectorSize outputs and return them in \e vector.
|
||||
StkFloat *tick(StkFloat *vector, unsigned int vectorSize);
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument should be one or greater (the first
|
||||
channel is specified by 1). An StkError will be thrown if the \c
|
||||
channel argument is zero or it is greater than the number of
|
||||
channels in the StkFrames object.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 1 );
|
||||
|
||||
protected:
|
||||
WvIn *waves[VOICE_POLYPHONY];
|
||||
OnePole *filters[VOICE_POLYPHONY];
|
||||
int sounding[VOICE_POLYPHONY];
|
||||
int nSounding;
|
||||
WvIn *waves_[VOICE_POLYPHONY];
|
||||
OnePole *filters_[VOICE_POLYPHONY];
|
||||
int sounding_[VOICE_POLYPHONY];
|
||||
int nSounding_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,272 +1,342 @@
|
||||
/************** Test Main Program Individual Voice *********************/
|
||||
|
||||
#include "RtWvOut.h"
|
||||
#include "SKINI.msg"
|
||||
#include "Instrmnt.h"
|
||||
#include "Reverb.h"
|
||||
#include "JCRev.h"
|
||||
#include "Drone.h"
|
||||
#include "Sitar.h"
|
||||
#include "Tabla.h"
|
||||
#include "VoicDrum.h"
|
||||
|
||||
// The input control handler.
|
||||
#include "Messager.h"
|
||||
#include "RtAudio.h"
|
||||
|
||||
MY_FLOAT float_random(MY_FLOAT max) // Return random float between 0.0 and max
|
||||
#include <signal.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#if !defined(__OS_WINDOWS__) // Windoze bogosity for VC++ 6.0
|
||||
using std::min;
|
||||
#endif
|
||||
|
||||
StkFloat float_random(StkFloat max) // Return random float between 0.0 and max
|
||||
{
|
||||
MY_FLOAT temp = (MY_FLOAT) (max * rand() / (RAND_MAX + 1.0) );
|
||||
StkFloat temp = (StkFloat) (max * rand() / (RAND_MAX + 1.0) );
|
||||
return temp;
|
||||
}
|
||||
|
||||
void usage(void) {
|
||||
/* Error function in case of incorrect command-line argument specifications */
|
||||
printf("\nuseage: ragamat flags \n");
|
||||
printf(" where flag = -s RATE to specify a sample rate,\n");
|
||||
printf(" flag = -ip for realtime SKINI input by pipe\n");
|
||||
printf(" (won't work under Win95/98),\n");
|
||||
printf(" and flag = -is <port> for realtime SKINI input by socket.\n");
|
||||
// Error function in case of incorrect command-line argument specifications.
|
||||
std::cout << "\nuseage: ragamat flags \n";
|
||||
std::cout << " where flag = -s RATE to specify a sample rate,\n";
|
||||
std::cout << " flag = -ip for realtime SKINI input by pipe\n";
|
||||
std::cout << " (won't work under Win95/98),\n";
|
||||
std::cout << " and flag = -is <port> for realtime SKINI input by socket.\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
bool done;
|
||||
RtWvOut *output;
|
||||
Instrmnt *drones[3];
|
||||
Instrmnt *sitar;
|
||||
Instrmnt *voicDrums;
|
||||
Instrmnt *tabla;
|
||||
Reverb *reverbs[2];
|
||||
SKINI *score;
|
||||
Messager *messager;
|
||||
MY_FLOAT t60 = 4.0; // in seconds
|
||||
bool done;
|
||||
static void finish(int ignore){ done = true; }
|
||||
|
||||
MY_FLOAT drone_prob = 0.01, note_prob = 0.0;
|
||||
MY_FLOAT drum_prob = 0.0, voic_prob = 0.0;
|
||||
MY_FLOAT droneFreqs[3] = {55.0,82.5,220.0};
|
||||
int tempo = 3000;
|
||||
int counter = 3000;
|
||||
int key = 0;
|
||||
int ragaStep, ragaPoint = 6, voicNote;
|
||||
int ragaUp[2][13] = {{57, 60, 62, 64, 65, 68, 69, 71, 72, 76, 77, 81},
|
||||
{52, 54, 55, 57, 59, 60, 63, 64, 66, 67, 71, 72}};
|
||||
int ragaDown[2][13] = {{57, 60, 62, 64, 65, 67, 69, 71, 72, 76, 79, 81},
|
||||
{48, 52, 53, 55, 57, 59, 60, 64, 66, 68, 70, 72}};
|
||||
// The TickData structure holds all the class instances and data that
|
||||
// are shared by the various processing functions.
|
||||
struct TickData {
|
||||
JCRev reverbs[2];
|
||||
Drone drones[3];
|
||||
Sitar sitar;
|
||||
VoicDrum voicDrums;
|
||||
Tabla tabla;
|
||||
Messager messager;
|
||||
Skini::Message message;
|
||||
StkFloat lastSample;
|
||||
StkFloat t60;
|
||||
int counter;
|
||||
bool settling;
|
||||
bool haveMessage;
|
||||
StkFloat droneChance, noteChance;
|
||||
StkFloat drumChance, voiceChance;
|
||||
int tempo;
|
||||
int chanceCounter;
|
||||
int key;
|
||||
int ragaStep;
|
||||
int ragaPoint;
|
||||
int endPhase;
|
||||
StkFloat rateScaler;
|
||||
|
||||
// Default constructor.
|
||||
TickData()
|
||||
: t60(4.0), counter(0),
|
||||
settling( false ), haveMessage( false ), droneChance(0.01), noteChance(0.01),
|
||||
drumChance(0.0), voiceChance(0.0), tempo(3000), chanceCounter(3000), key(0), ragaPoint(6), endPhase(0) {}
|
||||
};
|
||||
|
||||
// Raga key numbers and drone frequencies.
|
||||
const int ragaUp[2][13] = {{57, 60, 62, 64, 65, 68, 69, 71, 72, 76, 77, 81},
|
||||
{52, 54, 55, 57, 59, 60, 63, 64, 66, 67, 71, 72}};
|
||||
|
||||
const int ragaDown[2][13] = {{57, 60, 62, 64, 65, 67, 69, 71, 72, 76, 79, 81},
|
||||
{48, 52, 53, 55, 57, 59, 60, 64, 66, 68, 70, 72}};
|
||||
|
||||
StkFloat droneFreqs[3] = { 55.0, 82.5, 220.0 };
|
||||
|
||||
#define DELTA_CONTROL_TICKS 64 // default sample frames between control input checks
|
||||
|
||||
// The processMessage() function encapsulates the handling of control
|
||||
// messages. It can be easily relocated within a program structure
|
||||
// depending on the desired scheduling scheme.
|
||||
void processMessage( TickData* data )
|
||||
{
|
||||
register unsigned int value1 = data->message.intValues[0];
|
||||
register StkFloat value2 = data->message.floatValues[1];
|
||||
register StkFloat temp = value2 * ONE_OVER_128;
|
||||
|
||||
switch( data->message.type ) {
|
||||
|
||||
case __SK_Exit_:
|
||||
if ( data->settling == false ) goto settle;
|
||||
if ( data->endPhase < 5 ) return;
|
||||
done = true;
|
||||
return;
|
||||
|
||||
case __SK_ControlChange_:
|
||||
|
||||
switch ( value1 ) {
|
||||
|
||||
case 1:
|
||||
data->droneChance = temp;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
data->noteChance = temp;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
data->voiceChance = temp;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
data->tempo = (int) (11025 - value2 * 70.0 );
|
||||
break;
|
||||
|
||||
case 11:
|
||||
data->drumChance = temp;
|
||||
break;
|
||||
|
||||
case 64:
|
||||
if ( value2 == 0.0 ) {
|
||||
data->key = 1;
|
||||
droneFreqs[0] = 55.0;
|
||||
droneFreqs[1] = 82.5;
|
||||
droneFreqs[2] = 220.0;
|
||||
}
|
||||
else {
|
||||
data->key = 0;
|
||||
droneFreqs[0] = 82.5;
|
||||
droneFreqs[1] = 123.5;
|
||||
droneFreqs[2] = 330.0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} // end of type switch
|
||||
|
||||
data->haveMessage = false;
|
||||
return;
|
||||
|
||||
settle:
|
||||
// Exit and program change messages are preceeded with a short settling period.
|
||||
data->counter = (int) (data->t60 * Stk::sampleRate());
|
||||
data->drones[1].noteOn( droneFreqs[1], 0.1 );
|
||||
data->settling = true;
|
||||
std::cout << "What Need Have I for This?\n";
|
||||
}
|
||||
|
||||
// The tick() function handles sample computation and scheduling of
|
||||
// control updates. It will be called automatically by RtAudio when
|
||||
// the system needs a new buffer of audio samples.
|
||||
int tick(char *buffer, int bufferSize, void *dataPointer)
|
||||
{
|
||||
TickData *data = (TickData *) dataPointer;
|
||||
register StkFloat temp, outs[2], *samples = (StkFloat *) buffer;
|
||||
int i, voiceNote, counter, nTicks = bufferSize;
|
||||
|
||||
while ( nTicks > 0 && !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 ( i=0; i<counter; i++ ) {
|
||||
outs[0] = data->reverbs[0].tick( data->drones[0].tick() + data->drones[2].tick()
|
||||
+ data->sitar.tick() );
|
||||
outs[1] = data->reverbs[1].tick( 1.5 * data->drones[1].tick() + 0.5 * data->voicDrums.tick()
|
||||
+ 0.5 * data->tabla.tick() );
|
||||
// Mix a little left to right and back.
|
||||
*samples++ = outs[0] + 0.3 * outs[1];
|
||||
*samples++ = outs[1] + 0.3 * outs[0];
|
||||
nTicks--;
|
||||
|
||||
// Do a bunch of random controls unless settling down to end.
|
||||
if ( data->settling ) {
|
||||
if ( data->counter == 0 ) {
|
||||
if ( data->endPhase++ == 0 ) {
|
||||
data->counter = (int) (data->t60 * Stk::sampleRate());
|
||||
data->drones[2].noteOn( droneFreqs[2], 0.1 );
|
||||
std::cout << "What Need Have I for This?\n";
|
||||
}
|
||||
else if ( data->endPhase == 1 ) {
|
||||
data->counter = (int) (data->t60 * Stk::sampleRate());
|
||||
data->drones[0].noteOn( droneFreqs[0], 0.1 );
|
||||
std::cout << "RagaMatic finished ... \n";
|
||||
}
|
||||
else if ( data->endPhase == 2 ) {
|
||||
data->counter = (int) (data->t60 * Stk::sampleRate());
|
||||
std::cout << "All is Bliss ...\n";
|
||||
}
|
||||
else if ( data->endPhase == 3 ) {
|
||||
std::cout << "All is Bliss ...\n";
|
||||
data->counter = (int) (data->t60 * Stk::sampleRate());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
data->chanceCounter--;
|
||||
if (data->chanceCounter == 0) {
|
||||
data->chanceCounter = (int) ( data->tempo / data->rateScaler );
|
||||
if ( float_random(1.0) < data->droneChance )
|
||||
data->drones[0].noteOn( droneFreqs[0], 0.1 );
|
||||
if ( float_random(1.0) < data->droneChance )
|
||||
data->drones[1].noteOn( droneFreqs[1], 0.1 );
|
||||
if ( float_random(1.0) < data->droneChance )
|
||||
data->drones[2].noteOn( droneFreqs[2], 0.1 );
|
||||
if ( float_random(1.0) < data->noteChance ) {
|
||||
temp = float_random(1.0);
|
||||
if ( temp < 0.1) data->ragaStep = 0;
|
||||
else if (temp < 0.5) data->ragaStep = 1;
|
||||
else data->ragaStep = -1;
|
||||
data->ragaPoint += data->ragaStep;
|
||||
if ( data->ragaPoint < 0 )
|
||||
data->ragaPoint -= ( 2 * data->ragaStep );
|
||||
if ( data->ragaPoint > 11 ) data->ragaPoint = 11;
|
||||
if ( data->ragaStep > 0 )
|
||||
data->sitar.noteOn( Midi2Pitch[ragaUp[data->key][data->ragaPoint]],
|
||||
0.05 + float_random(0.3) );
|
||||
else
|
||||
data->sitar.noteOn( Midi2Pitch[ragaDown[data->key][data->ragaPoint]],
|
||||
0.05 + float_random(0.3) );
|
||||
}
|
||||
if ( float_random(1.0) < data->voiceChance ) {
|
||||
voiceNote = (int) float_random(11);
|
||||
data->voicDrums.noteOn( voiceNote, 0.3 + (0.4 * data->drumChance) +
|
||||
float_random(0.3 * data->voiceChance));
|
||||
}
|
||||
if ( float_random(1.0) < data->drumChance ) {
|
||||
voiceNote = (int) float_random(TABLA_NUMWAVES);
|
||||
data->tabla.noteOn( voiceNote, 0.2 + (0.2 * data->drumChance) +
|
||||
float_random(0.6 * data->drumChance));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( nTicks == 0 ) break;
|
||||
|
||||
// Process control messages.
|
||||
if ( data->haveMessage ) processMessage( data );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
TickData data;
|
||||
RtAudio *dac = 0;
|
||||
int i;
|
||||
|
||||
if (argc < 2 || argc > 6) usage();
|
||||
|
||||
// If you want to change the default sample rate (set in Stk.h), do
|
||||
// it before instantiating any objects! If the sample rate is
|
||||
// specified in the command line, it will override this setting.
|
||||
Stk::setSampleRate(22050.0);
|
||||
Stk::setSampleRate( 44100.0 );
|
||||
|
||||
if (argc < 2 || argc > 6) usage();
|
||||
|
||||
int port = -1;
|
||||
int i, controlMask = 0;
|
||||
// Parse the command-line arguments.
|
||||
unsigned int port = 2001;
|
||||
for ( i=1; i<argc; i++ ) {
|
||||
if (!strcmp(argv[i],"-is") ) {
|
||||
controlMask |= STK_SOCKET;
|
||||
if (i+1 < argc && argv[i+1][0] != '-' ) port = atoi(argv[++i]);
|
||||
if ( !strcmp( argv[i], "-is" ) ) {
|
||||
if ( i+1 < argc && argv[i+1][0] != '-' ) port = atoi(argv[++i]);
|
||||
data.messager.startSocketInput( port );
|
||||
}
|
||||
else if (!strcmp(argv[i],"-ip") )
|
||||
controlMask |= STK_PIPE;
|
||||
else if (!strcmp(argv[i],"-s") && (i+1 < argc) && argv[i+1][0] != '-')
|
||||
else if (!strcmp( argv[i], "-ip" ) )
|
||||
data.messager.startStdInput();
|
||||
else if ( !strcmp( argv[i], "-s" ) && ( i+1 < argc ) && argv[i+1][0] != '-')
|
||||
Stk::setSampleRate( atoi(argv[++i]) );
|
||||
else
|
||||
usage();
|
||||
}
|
||||
|
||||
|
||||
// Allocate the dac here.
|
||||
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
|
||||
int bufferSize = RT_BUFFER_SIZE;
|
||||
try {
|
||||
output = new RtWvOut(2);
|
||||
|
||||
// Instantiate the input message controller.
|
||||
if ( controlMask & STK_SOCKET && port >= 0 )
|
||||
messager = new Messager( controlMask, port );
|
||||
else
|
||||
messager = new Messager( controlMask );
|
||||
dac = new RtAudio(0, 2, 0, 0, format, (int)Stk::sampleRate(), &bufferSize, 4);
|
||||
}
|
||||
catch (StkError &) {
|
||||
exit(0);
|
||||
catch (RtError& error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
drones[0] = new Drone(50.0);
|
||||
drones[1] = new Drone(50.0);
|
||||
drones[2] = new Drone(50.0);
|
||||
sitar = new Sitar(50.0);
|
||||
voicDrums = new VoicDrum();
|
||||
tabla = new Tabla();
|
||||
data.reverbs[0].setT60( data.t60 );
|
||||
data.reverbs[0].setEffectMix( 0.5 );
|
||||
data.reverbs[1].setT60( 2.0 );
|
||||
data.reverbs[1].setEffectMix( 0.2 );
|
||||
|
||||
score = new SKINI();
|
||||
reverbs[0] = new JCRev(t60);
|
||||
reverbs[0]->setEffectMix(0.5);
|
||||
reverbs[1] = new JCRev(2.0);
|
||||
reverbs[1]->setEffectMix(0.2);
|
||||
data.drones[0].noteOn( droneFreqs[0], 0.1 );
|
||||
data.drones[1].noteOn( droneFreqs[1], 0.1 );
|
||||
data.drones[2].noteOn( droneFreqs[2], 0.1 );
|
||||
|
||||
drones[0]->noteOn(droneFreqs[0],0.1);
|
||||
drones[1]->noteOn(droneFreqs[1],0.1);
|
||||
drones[2]->noteOn(droneFreqs[2],0.1);
|
||||
data.rateScaler = 22050.0 / Stk::sampleRate();
|
||||
|
||||
MY_FLOAT outSamples[2];
|
||||
for (i=0;i<Stk::sampleRate();i++) { /* warm everybody up a little */
|
||||
outSamples[0] = reverbs[0]->tick(drones[0]->tick() + drones[2]->tick());
|
||||
outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick());
|
||||
output->tickFrame(outSamples);
|
||||
// Install an interrupt handler function.
|
||||
(void) signal( SIGINT, finish );
|
||||
|
||||
// If realtime output, set our callback function and start the dac.
|
||||
try {
|
||||
dac->setStreamCallback( &tick, (void *)&data );
|
||||
dac->startStream();
|
||||
}
|
||||
catch (RtError &error) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// The runtime loop begins here:
|
||||
done = FALSE;
|
||||
MY_FLOAT rateScaler = 22050.0 / Stk::sampleRate();
|
||||
int nTicks, type;
|
||||
MY_FLOAT temp, byte2, byte3;
|
||||
while (!done) {
|
||||
|
||||
type = messager->nextMessage();
|
||||
if (type < 0)
|
||||
done = TRUE;
|
||||
|
||||
nTicks = messager->getDelta();
|
||||
|
||||
for (i=0; i<nTicks; i++) {
|
||||
outSamples[0] = reverbs[0]->tick(drones[0]->tick() + drones[2]->tick()
|
||||
+ sitar->tick());
|
||||
outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick() + 0.5 * voicDrums->tick()
|
||||
+ 0.5 * tabla->tick());
|
||||
// mix a little left to right and back
|
||||
temp = outSamples[0];
|
||||
outSamples[0] += 0.3 * outSamples[1];
|
||||
outSamples[1] += 0.3 * temp;
|
||||
output->tickFrame(outSamples);
|
||||
|
||||
counter -= 1;
|
||||
if (counter == 0) {
|
||||
counter = (int) (tempo / rateScaler);
|
||||
if (float_random(1.0) < drone_prob)
|
||||
drones[0]->noteOn(droneFreqs[0], 0.1);
|
||||
if (float_random(1.0) < drone_prob)
|
||||
drones[1]->noteOn(droneFreqs[1], 0.1);
|
||||
if (float_random(1.0) < drone_prob)
|
||||
drones[2]->noteOn(droneFreqs[2], 0.1);
|
||||
if (float_random(1.0) < note_prob) {
|
||||
if ((temp = float_random(1.0)) < 0.1)
|
||||
ragaStep = 0;
|
||||
else if (temp < 0.5)
|
||||
ragaStep = 1;
|
||||
else
|
||||
ragaStep = -1;
|
||||
ragaPoint += ragaStep;
|
||||
if (ragaPoint < 0)
|
||||
ragaPoint -= (2*ragaStep);
|
||||
if (ragaPoint > 11)
|
||||
ragaPoint = 11;
|
||||
if (ragaStep > 0)
|
||||
sitar->noteOn(Midi2Pitch[ragaUp[key][ragaPoint]],
|
||||
0.05 + float_random(0.3));
|
||||
else
|
||||
sitar->noteOn(Midi2Pitch[ragaDown[key][ragaPoint]],
|
||||
0.05 + float_random(0.3));
|
||||
}
|
||||
if (float_random(1.0) < voic_prob) {
|
||||
voicNote = (int) float_random(11);
|
||||
voicDrums->noteOn(voicNote, 0.3 + (0.4 * drum_prob) +
|
||||
float_random(0.3 * voic_prob));
|
||||
}
|
||||
if (float_random(1.0) < drum_prob) {
|
||||
voicNote = (int) float_random(TABLA_NUMWAVES);
|
||||
tabla->noteOn(voicNote, 0.2 + (0.2 * drum_prob) +
|
||||
float_random(0.6 * drum_prob));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( type > 0 ) {
|
||||
// parse the input control message
|
||||
|
||||
byte2 = messager->getByteTwo();
|
||||
byte3 = messager->getByteThree();
|
||||
|
||||
switch(type) {
|
||||
|
||||
case __SK_ControlChange_:
|
||||
if (byte2 == 1) {
|
||||
drone_prob = byte3 * ONE_OVER_128;
|
||||
}
|
||||
else if (byte2 == 2) {
|
||||
note_prob = byte3 * ONE_OVER_128;
|
||||
}
|
||||
else if (byte2 == 4) {
|
||||
voic_prob = byte3 * ONE_OVER_128;
|
||||
}
|
||||
else if (byte2 == 11) {
|
||||
drum_prob = byte3 * ONE_OVER_128;
|
||||
}
|
||||
else if (byte2 == 7) {
|
||||
tempo = (int) (11025 - (byte3 * 70));
|
||||
}
|
||||
else if (byte2 == 64) {
|
||||
if (byte3 == 0) {
|
||||
key = 1;
|
||||
droneFreqs[0] = 55.0;
|
||||
droneFreqs[1] = 82.5;
|
||||
droneFreqs[2] = 220.0;
|
||||
}
|
||||
else {
|
||||
key = 0;
|
||||
droneFreqs[0] = 82.5;
|
||||
droneFreqs[1] = 123.5;
|
||||
droneFreqs[2] = 330.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Setup finished.
|
||||
while ( !done ) {
|
||||
// Periodically check "done" status.
|
||||
Stk::sleep( 50 );
|
||||
}
|
||||
|
||||
nTicks = (long) (t60 * Stk::sampleRate());
|
||||
|
||||
printf("What Need Have I for This?\n");
|
||||
drones[1]->noteOn(droneFreqs[1],0.1);
|
||||
for (i=0; i<nTicks; i++) { // Calm down a little
|
||||
outSamples[0] = reverbs[0]->tick(drones[0]->tick() + drones[2]->tick());
|
||||
outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick());
|
||||
output->tickFrame(outSamples);
|
||||
// Shut down the output stream.
|
||||
try {
|
||||
dac->cancelStreamCallback();
|
||||
dac->closeStream();
|
||||
}
|
||||
printf("What Need Have I for This?\n");
|
||||
drones[2]->noteOn(droneFreqs[2],0.1);
|
||||
for (i=0; i<nTicks; i++) { // and a little more
|
||||
outSamples[0] = reverbs[0]->tick(drones[0]->tick() + drones[2]->tick());
|
||||
outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick());
|
||||
output->tickFrame(outSamples);
|
||||
}
|
||||
printf("RagaMatic finished ... \n");
|
||||
drones[0]->noteOn(droneFreqs[0],0.1);
|
||||
for (i=0; i<nTicks; i++) { // almost ready to think about ending
|
||||
outSamples[0] = reverbs[0]->tick(drones[0]->tick() + drones[2]->tick());
|
||||
outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick());
|
||||
output->tickFrame(outSamples);
|
||||
}
|
||||
printf("All is Bliss ...\n");
|
||||
for (i=0; i<nTicks; i++) { // nearly finished now
|
||||
outSamples[0] = reverbs[0]->tick(drones[0]->tick() + drones[2]->tick());
|
||||
outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick());
|
||||
output->tickFrame(outSamples);
|
||||
}
|
||||
printf("All is Bliss ...\n");
|
||||
for (i=0; i<nTicks; i++) { // all is bliss....
|
||||
outSamples[0] = reverbs[0]->tick(drones[0]->tick() + drones[2]->tick());
|
||||
outSamples[1] = reverbs[1]->tick(1.5 * drones[1]->tick());
|
||||
output->tickFrame(outSamples);
|
||||
catch (RtError& error) {
|
||||
error.printMessage();
|
||||
}
|
||||
|
||||
delete output;
|
||||
delete score;
|
||||
delete drones[0];
|
||||
delete drones[1];
|
||||
delete drones[2];
|
||||
delete sitar;
|
||||
delete tabla;
|
||||
delete voicDrums;
|
||||
delete reverbs[0];
|
||||
delete reverbs[1];
|
||||
delete messager;
|
||||
cleanup:
|
||||
|
||||
delete dac;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -66,7 +66,7 @@ LINK32=link.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /YX /FD /c
|
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_DS__" /D "__LITTLE_ENDIAN__" /D "__WINDOWS_MM__" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -124,6 +124,14 @@ SOURCE=.\Drone.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Effect.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Effect.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Envelope.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -140,6 +148,14 @@ SOURCE=..\..\include\Filter.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Generator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Generator.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Instrmnt.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -164,6 +180,14 @@ SOURCE=..\..\include\Messager.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Mutex.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Mutex.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Noise.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -192,14 +216,6 @@ SOURCE=.\ragamat.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Reverb.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Reverb.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\RtAudio.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -216,14 +232,6 @@ SOURCE=..\..\include\RtMidi.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\RtWvOut.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\RtWvOut.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Sitar.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
Reference in New Issue
Block a user