mirror of
https://github.com/thestk/stk
synced 2026-01-11 20:11:52 +00:00
Version 4.4.4
This commit is contained in:
committed by
Stephen Sinclair
parent
0aec39260a
commit
fc877b87bf
0
projects/eguitar/Debug/.placeholder
Normal file
0
projects/eguitar/Debug/.placeholder
Normal file
1
projects/eguitar/ElectricGuitar
Executable file
1
projects/eguitar/ElectricGuitar
Executable file
@@ -0,0 +1 @@
|
||||
wish < tcl/EGuitar.tcl | ./eguitar -or -ip
|
||||
1
projects/eguitar/ElectricGuitar.bat
Executable file
1
projects/eguitar/ElectricGuitar.bat
Executable file
@@ -0,0 +1 @@
|
||||
wish < tcl/EGuitar.tcl | eguitar -or -ip
|
||||
71
projects/eguitar/Makefile.in
Normal file
71
projects/eguitar/Makefile.in
Normal file
@@ -0,0 +1,71 @@
|
||||
### Do not edit -- Generated by 'configure --with-whatever' from Makefile.in
|
||||
### STK eguitar Makefile - for various flavors of unix
|
||||
|
||||
PROGRAMS =
|
||||
RM = /bin/rm
|
||||
SRC_PATH = ../../src
|
||||
OBJECT_PATH = @object_path@
|
||||
vpath %.o $(OBJECT_PATH)
|
||||
|
||||
OBJECTS = Stk.o Filter.o Fir.o Delay.o DelayL.o DelayA.o OnePole.o \
|
||||
Effect.o JCRev.o Twang.o \
|
||||
Guitar.o Noise.o Cubic.o \
|
||||
FileRead.o WvIn.o FileWvIn.o FileWrite.o FileWvOut.o \
|
||||
Skini.o Messager.o utilities.o
|
||||
|
||||
INCLUDE = @include@
|
||||
ifeq ($(strip $(INCLUDE)), )
|
||||
INCLUDE = ../../include
|
||||
endif
|
||||
vpath %.h $(INCLUDE)
|
||||
|
||||
CC = @CXX@
|
||||
DEFS = @CPPFLAGS@
|
||||
DEFS += @byte_order@
|
||||
CFLAGS = @CXXFLAGS@
|
||||
CFLAGS += -I$(INCLUDE) -I$(INCLUDE)/../src/include
|
||||
LIBRARY = @LIBS@
|
||||
|
||||
REALTIME = @realtime@
|
||||
ifeq ($(REALTIME),yes)
|
||||
PROGRAMS += eguitar
|
||||
OBJECTS += RtMidi.o RtAudio.o Thread.o Mutex.o Socket.o TcpServer.o @objects@
|
||||
endif
|
||||
|
||||
RAWWAVES = @rawwaves@
|
||||
ifeq ($(strip $(RAWWAVES)), )
|
||||
RAWWAVES = ../../rawwaves/
|
||||
endif
|
||||
DEFS += -DRAWWAVE_PATH=\"$(RAWWAVES)\"
|
||||
|
||||
%.o : $(SRC_PATH)/%.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -c $(<) -o $(OBJECT_PATH)/$@
|
||||
|
||||
%.o : ../../src/include/%.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -c $(<) -o $(OBJECT_PATH)/$@
|
||||
|
||||
all : $(PROGRAMS)
|
||||
|
||||
eguitar: eguitar.cpp $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) $(DEFS) -o eguitar eguitar.cpp $(OBJECT_PATH)/*.o $(LIBRARY)
|
||||
|
||||
libeguitar: eguitar.cpp
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) $(DEFS) -o eguitar utilities.cpp eguitar.cpp -L../../src -lstk $(LIBRARY)
|
||||
|
||||
$(OBJECTS) : Stk.h
|
||||
|
||||
clean :
|
||||
$(RM) -f $(OBJECT_PATH)/*.o
|
||||
$(RM) -f $(PROGRAMS) *.exe
|
||||
$(RM) -fR *~ *.dSYM
|
||||
|
||||
distclean: clean
|
||||
$(RM) Makefile
|
||||
|
||||
strip :
|
||||
strip $(PROGRAMS)
|
||||
|
||||
# Project specific objects:
|
||||
|
||||
utilities.o: utilities.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -c utilities.cpp -o $(OBJECT_PATH)/$@
|
||||
44
projects/eguitar/README-eguitar.txt
Normal file
44
projects/eguitar/README-eguitar.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
This is eguitar by Gary Scavone, McGill University, 2012.
|
||||
|
||||
This is a program to create a simple electric guitar model using
|
||||
the STK Guitar class. The is model is derived in part from an
|
||||
implementation made by Nicholas Donaldson at McGill University in
|
||||
2009. The distortion model is poor, using a simple soft-clipping
|
||||
expression provided by Charles R. Sullivan in "Extending the
|
||||
Karplus-String Algorithm to Synthesize Electric Guitar Timbres with
|
||||
Distortion and Feedback," Computer Music Journal, Vol.14 No.3, Fall
|
||||
1990. Other distortion models would be better, such as that found
|
||||
in Pakarinen and Yeh's "A Review of Digital Techniques for Modeling
|
||||
Vacuum-Tube Guitar Amplifiers," Computer Music Journal, Vol 33
|
||||
No. 2, Summer 2009.
|
||||
|
||||
This program performs simple voice management if all noteOn and
|
||||
noteOff events are on channel 0. Otherwise, channel values > 0 are
|
||||
mapped to specific string numbers. By default, the program creates
|
||||
a 6-string guitar. If the normalized noteOn() velocity is < 0.2, a
|
||||
string is undamped but not plucked (this is implemented in the
|
||||
stk::Guitar class). Thus, you can lightly depress a key on a MIDI
|
||||
keyboard and then experiment with string coupling.
|
||||
|
||||
The Tcl/Tk GUI allows you to experiment with various parameter
|
||||
settings and that can be used in conjunction with a MIDI keyboard
|
||||
as: wish < tcl/EGuitar.tcl | ./eguitar -or -ip -im 1
|
||||
|
||||
For the moment, this program does not support pitch bends.
|
||||
|
||||
In the eguitar directory, type:
|
||||
|
||||
> make
|
||||
|
||||
to compile and then
|
||||
|
||||
> ElectricGuitar.bat
|
||||
|
||||
to run the program with the Tcl/Tk GUI.
|
||||
|
||||
There are many improvements that could be made to this project. In
|
||||
particular, you could record real body responses from different
|
||||
guitars and use those with the Guitar class. As well, you could
|
||||
improve the distortion model and perhaps add some typical electric
|
||||
guitar effects, such as an echo. If you find any bugs, please let me
|
||||
know!
|
||||
0
projects/eguitar/Release/.placeholder
Normal file
0
projects/eguitar/Release/.placeholder
Normal file
381
projects/eguitar/eguitar.cpp
Normal file
381
projects/eguitar/eguitar.cpp
Normal file
@@ -0,0 +1,381 @@
|
||||
// Eguitar.cpp
|
||||
//
|
||||
// This is a program to create a simple electric guitar model using
|
||||
// the STK Guitar class. The is model is derived in part from an
|
||||
// implementation made by Nicholas Donaldson at McGill University in
|
||||
// 2009. The distortion model is poor, using a simple soft-clipping
|
||||
// expression provided by Charles R. Sullivan in "Extending the
|
||||
// Karplus-String Algorithm to Synthesize Electric Guitar Timbres with
|
||||
// Distortion and Feedback," Computer Music Journal, Vol.14 No.3, Fall
|
||||
// 1990. Other distortion models would be better, such as that found
|
||||
// in Pakarinen and Yeh's "A Review of Digital Techniques for Modeling
|
||||
// Vacuum-Tube Guitar Amplifiers," Computer Music Journal, Vol 33
|
||||
// No. 2, Summer 2009.
|
||||
//
|
||||
// This program performs simple voice management if all noteOn and
|
||||
// noteOff events are on channel 0. Otherwise, channel values > 0 are
|
||||
// mapped to specific string numbers. By default, the program creates
|
||||
// a 6-string guitar. If the normalized noteOn() velocity is < 0.2, a
|
||||
// string is undamped but not plucked (this is implemented in the
|
||||
// stk::Guitar class). Thus, you can lightly depress a key on a MIDI
|
||||
// keyboard and then experiment with string coupling.
|
||||
//
|
||||
// The Tcl/Tk GUI allows you to experiment with various parameter
|
||||
// settings and that can be used in conjunction with a MIDI keyboard
|
||||
// as: wish < tcl/EGuitar.tcl | ./eguitar -or -ip -im 1
|
||||
//
|
||||
// For the moment, this program does not support pitch bends.
|
||||
//
|
||||
// Gary P. Scavone, McGill University 2012.
|
||||
|
||||
#include "Guitar.h"
|
||||
#include "SKINI.msg"
|
||||
#include "WvOut.h"
|
||||
#include "JCRev.h"
|
||||
#include "Skini.h"
|
||||
#include "RtAudio.h"
|
||||
#include "Delay.h"
|
||||
#include "Cubic.h"
|
||||
|
||||
// Miscellaneous command-line parsing and instrument allocation
|
||||
// functions are defined in utilites.cpp ... specific to this program.
|
||||
#include "utilities.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
using std::min;
|
||||
|
||||
bool done;
|
||||
static void finish(int ignore){ done = true; }
|
||||
|
||||
using namespace stk;
|
||||
|
||||
const unsigned int nStrings = 6;
|
||||
|
||||
// Data structure for string information.
|
||||
struct StringInfo{
|
||||
bool inUse; // is this string being used?
|
||||
unsigned int iNote; // note number associated with this string
|
||||
|
||||
StringInfo() : inUse(false), iNote(0) {};
|
||||
};
|
||||
|
||||
// The TickData structure holds all the class instances and data that
|
||||
// are shared by the various processing functions.
|
||||
struct TickData {
|
||||
WvOut **wvout;
|
||||
Guitar *guitar;
|
||||
StringInfo voices[nStrings];
|
||||
JCRev reverb;
|
||||
Messager messager;
|
||||
Skini::Message message;
|
||||
StkFloat volume;
|
||||
StkFloat t60;
|
||||
unsigned int nWvOuts;
|
||||
int channels;
|
||||
int counter;
|
||||
bool realtime;
|
||||
bool settling;
|
||||
bool haveMessage;
|
||||
int keysDown;
|
||||
|
||||
StkFloat feedbackGain;
|
||||
StkFloat oldFeedbackGain;
|
||||
StkFloat distortionGain;
|
||||
StkFloat distortionMix;
|
||||
Delay feedbackDelay;
|
||||
Cubic distortion;
|
||||
StkFloat feedbackSample;
|
||||
|
||||
// Default constructor.
|
||||
TickData()
|
||||
: wvout(0), volume(1.0), t60(0.75),
|
||||
nWvOuts(0), channels(2), counter(0),
|
||||
realtime( false ), settling( false ), haveMessage( false ),
|
||||
keysDown(0), feedbackSample( 0.0 ) {}
|
||||
};
|
||||
|
||||
#define DELTA_CONTROL_TICKS 30 // 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];
|
||||
unsigned int channel = (unsigned int) data->message.channel;
|
||||
|
||||
switch( data->message.type ) {
|
||||
|
||||
case __SK_Exit_:
|
||||
if ( data->settling == false ) goto settle;
|
||||
done = true;
|
||||
return;
|
||||
|
||||
case __SK_NoteOn_:
|
||||
if ( value2 > 0.0 ) { // velocity > 0
|
||||
unsigned int iNote = data->message.intValues[0];
|
||||
if ( channel == 0 ) { // do basic voice management
|
||||
unsigned int s;
|
||||
if ( data->keysDown >= (int) nStrings ) break; // ignore extra note on's
|
||||
// Find first unused string
|
||||
for ( s=0; s<nStrings; s++ )
|
||||
if ( !data->voices[s].inUse ) break;
|
||||
if ( s == nStrings ) break;
|
||||
data->voices[s].inUse = true;
|
||||
data->voices[s].iNote = iNote;
|
||||
data->guitar->noteOn( Midi2Pitch[iNote], value2 * ONE_OVER_128, s );
|
||||
data->keysDown++;
|
||||
// If first key down, turn on feedback gain
|
||||
if ( data->keysDown == 1 )
|
||||
data->feedbackGain = data->oldFeedbackGain;
|
||||
}
|
||||
else if ( channel <= nStrings )
|
||||
data->guitar->noteOn( Midi2Pitch[iNote], value2 * ONE_OVER_128, channel-1 );
|
||||
break;
|
||||
}
|
||||
// else a note off, so continue to next case
|
||||
|
||||
case __SK_NoteOff_:
|
||||
if ( channel == 0 ) { // do basic voice management
|
||||
if ( !data->keysDown ) break;
|
||||
// Search for the released note
|
||||
unsigned int s, iNote;
|
||||
iNote = data->message.intValues[0];
|
||||
for ( s=0; s<nStrings; s++ )
|
||||
if ( data->voices[s].inUse && iNote == data->voices[s].iNote )
|
||||
break;
|
||||
if ( s == nStrings ) break;
|
||||
data->voices[s].inUse = false;
|
||||
data->guitar->noteOff( value2 * ONE_OVER_128, s );
|
||||
data->keysDown--;
|
||||
if ( data->keysDown == 0 ) { // turn off feedback gain and clear delay
|
||||
data->feedbackDelay.clear();
|
||||
data->feedbackGain = 0.0;
|
||||
}
|
||||
}
|
||||
else if ( channel <= nStrings )
|
||||
data->guitar->noteOff( value2 * ONE_OVER_128, channel-1 );
|
||||
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 == 27 ) // feedback delay
|
||||
data->feedbackDelay.setDelay( (value2 * Stk::sampleRate() / 127) + 1 );
|
||||
else if ( value1 == 28 ) { // feedback gain
|
||||
//data->oldFeedbackGain = value2 * 0.01 / 127.0;
|
||||
data->oldFeedbackGain = value2 * 0.02 / 127.0;
|
||||
data->feedbackGain = data->oldFeedbackGain;
|
||||
}
|
||||
else if ( value1 == 71 ) // pre-distortion gain
|
||||
data->distortionGain = 2.0 * value2 * ONE_OVER_128;
|
||||
else if ( value1 == 72 ) // distortion mix
|
||||
data->distortionMix = value2 * ONE_OVER_128;
|
||||
else
|
||||
data->guitar->controlChange( (int) value1, value2 );
|
||||
break;
|
||||
case __SK_AfterTouch_:
|
||||
data->guitar->controlChange( 128, value1 );
|
||||
break;
|
||||
|
||||
case __SK_PitchBend_:
|
||||
// Implement me!
|
||||
break;
|
||||
case __SK_Volume_:
|
||||
data->volume = value1 * ONE_OVER_128;
|
||||
break;
|
||||
|
||||
} // end of switch
|
||||
|
||||
data->haveMessage = false;
|
||||
return;
|
||||
|
||||
settle:
|
||||
// Exit and program change messages are preceeded with a short settling period.
|
||||
for ( unsigned int s=0; s<nStrings; s++ )
|
||||
if ( data->voices[s].inUse ) data->guitar->noteOff( 0.6, s );
|
||||
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( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
|
||||
double streamTime, RtAudioStreamStatus status, void *dataPointer )
|
||||
{
|
||||
TickData *data = (TickData *) dataPointer;
|
||||
register StkFloat temp, sample, *samples = (StkFloat *) outputBuffer;
|
||||
int counter, nTicks = (int) nBufferFrames;
|
||||
|
||||
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++ ) {
|
||||
|
||||
// Put the previous distorted sample thru feedback
|
||||
sample = data->feedbackDelay.tick( data->feedbackSample * data->feedbackGain );
|
||||
sample = data->guitar->tick( sample );
|
||||
|
||||
// Apply distortion (x - x^3/3) and mix
|
||||
temp = data->distortionGain * sample;
|
||||
if ( temp > 0.6666667 ) temp = 0.6666667;
|
||||
else if ( temp < -0.6666667 ) temp = -0.6666667;
|
||||
else temp = data->distortion.tick( temp );
|
||||
sample = (data->distortionMix * temp) + ((1 - data->distortionMix) * sample );
|
||||
data->feedbackSample = sample;
|
||||
|
||||
// Tick instrument and apply reverb
|
||||
sample = data->volume * data->reverb.tick( sample );
|
||||
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;
|
||||
#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
|
||||
// specified in the command line, it will override this setting.
|
||||
Stk::setSampleRate( 44100.0 );
|
||||
|
||||
// By default, warning messages are not printed. If we want to see
|
||||
// them, we need to specify that here.
|
||||
Stk::showWarnings( true );
|
||||
|
||||
// Check the command-line arguments for errors and to determine
|
||||
// the number of WvOut objects to be instantiated (in utilities.cpp).
|
||||
data.nWvOuts = checkArgs( argc, argv );
|
||||
data.wvout = (WvOut **) calloc( data.nWvOuts, sizeof(WvOut *) );
|
||||
|
||||
// Parse the command-line flags, instantiate WvOut objects, and
|
||||
// instantiate the input message controller (in utilities.cpp).
|
||||
try {
|
||||
data.realtime = parseArgs( argc, argv, data.wvout, data.messager );
|
||||
}
|
||||
catch (StkError &) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// If realtime output, allocate the dac here.
|
||||
#if defined(__STK_REALTIME__)
|
||||
if ( data.realtime ) {
|
||||
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
|
||||
RtAudio::StreamParameters parameters;
|
||||
parameters.deviceId = dac.getDefaultOutputDevice();
|
||||
parameters.nChannels = data.channels;
|
||||
unsigned int bufferFrames = RT_BUFFER_SIZE;
|
||||
try {
|
||||
dac.openStream( ¶meters, NULL, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick, (void *)&data );
|
||||
}
|
||||
catch ( RtError& error ) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set the reverb parameters.
|
||||
data.reverb.setT60( data.t60 );
|
||||
data.reverb.setEffectMix( 0.2 );
|
||||
|
||||
// Allocate guitar
|
||||
data.guitar = new Guitar( nStrings );
|
||||
|
||||
// Configure distortion and feedback.
|
||||
data.distortion.setThreshold( 2.0 / 3.0 );
|
||||
data.distortion.setA1( 1.0 );
|
||||
data.distortion.setA2( 0.0 );
|
||||
data.distortion.setA3( -1.0 / 3.0 );
|
||||
data.distortionMix = 0.9;
|
||||
data.distortionGain = 1.0;
|
||||
data.feedbackDelay.setMaximumDelay( (unsigned long int)( 1.1 * Stk::sampleRate() ) );
|
||||
data.feedbackDelay.setDelay( 20000 );
|
||||
data.feedbackGain = 0.001;
|
||||
data.oldFeedbackGain = 0.001;
|
||||
|
||||
|
||||
// Install an interrupt handler function.
|
||||
(void) signal(SIGINT, finish);
|
||||
|
||||
// If realtime output, set our callback function and start the dac.
|
||||
#if defined(__STK_REALTIME__)
|
||||
if ( data.realtime ) {
|
||||
try {
|
||||
dac.startStream();
|
||||
}
|
||||
catch ( RtError &error ) {
|
||||
error.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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, NULL, 256, 0, 0, (void *)&data );
|
||||
}
|
||||
|
||||
// Shut down the output stream.
|
||||
#if defined(__STK_REALTIME__)
|
||||
if ( data.realtime ) {
|
||||
try {
|
||||
dac.closeStream();
|
||||
}
|
||||
catch ( RtError& error ) {
|
||||
error.printMessage();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
|
||||
for ( i=0; i<(int)data.nWvOuts; i++ ) delete data.wvout[i];
|
||||
free( data.wvout );
|
||||
delete data.guitar;
|
||||
|
||||
std::cout << "\nStk eguitar finished ... goodbye.\n\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
298
projects/eguitar/eguitar.dsp
Normal file
298
projects/eguitar/eguitar.dsp
Normal file
@@ -0,0 +1,298 @@
|
||||
# Microsoft Developer Studio Project File - Name="eguitar" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=eguitar - 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 "ragamat.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 "ragamat.mak" CFG="eguitar - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "eguitar - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "eguitar - 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)" == "eguitar - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "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 "__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
|
||||
# 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 /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 dsound.lib winmm.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "eguitar - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "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 /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
|
||||
# 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 /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 dsound.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "eguitar - Win32 Release"
|
||||
# Name "eguitar - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Fir.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Fir.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Delay.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Delay.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\DelayA.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\DelayA.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\DelayL.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\DelayL.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Effect.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Twang.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Twang.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Guitar.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Guitar.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\FileRead.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\FileRead.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\FileWrite.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\FileWrite.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\FileWvOut.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\FileWvOut.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\FileWvIn.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\FileWvIn.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Filter.h
|
||||
# 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
|
||||
|
||||
SOURCE=..\..\include\JCRev.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Messager.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
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
|
||||
|
||||
SOURCE=..\..\include\Noise.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Cubic.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\OnePole.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\OnePole.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\eguitar.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\utilities.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\utilities.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\RtAudio.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\RtAudio.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\RtMidi.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\RtMidi.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\SKINI.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\SKINI.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Socket.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Socket.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Stk.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Stk.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\TcpServer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\TcpServer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Thread.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\Thread.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\WvIn.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\WvOut.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
projects/eguitar/eguitar.dsw
Normal file
29
projects/eguitar/eguitar.dsw
Normal file
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "eguitar"=.\eguitar.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
27
projects/eguitar/scores/test.ski
Normal file
27
projects/eguitar/scores/test.ski
Normal file
@@ -0,0 +1,27 @@
|
||||
/* Howdy!! SKINI File, Perry Cook */
|
||||
NoteOn 0.1 0 40 100.000000
|
||||
NoteOn 0.01 0 44 100.000000
|
||||
NoteOn 0.01 0 47 100.000000
|
||||
NoteOn 0.01 0 52 100.000000
|
||||
NoteOff 1.0 0 40 64.000000
|
||||
NoteOff 0.0 0 44 64.000000
|
||||
NoteOff 0.0 0 47 64.000000
|
||||
NoteOff 0.0 0 52 64.000000
|
||||
|
||||
NoteOn 0.3 0 39 100.000000
|
||||
NoteOn 0.01 0 42 100.000000
|
||||
NoteOn 0.01 0 47 100.000000
|
||||
NoteOn 0.01 0 51 100.000000
|
||||
NoteOff 1.0 0 39 64.000000
|
||||
NoteOff 0.0 0 42 64.000000
|
||||
NoteOff 0.0 0 47 64.000000
|
||||
NoteOff 0.0 0 51 64.000000
|
||||
|
||||
NoteOn 0.3 0 40 100.000000
|
||||
NoteOn 0.01 0 44 100.000000
|
||||
NoteOn 0.01 0 47 100.000000
|
||||
NoteOn 0.01 0 52 100.000000
|
||||
NoteOff 2.0 0 40 64.000000
|
||||
NoteOff 0.0 0 44 64.000000
|
||||
NoteOff 0.0 0 47 64.000000
|
||||
NoteOff 0.0 0 52 64.000000
|
||||
264
projects/eguitar/tcl/Eguitar.tcl
Normal file
264
projects/eguitar/tcl/Eguitar.tcl
Normal file
@@ -0,0 +1,264 @@
|
||||
# Tcl/Tk Electric Guitar Model GUI for the Synthesis Toolkit (STK)
|
||||
# by Gary P. Scavone, McGill University, 2012.
|
||||
|
||||
# Set lowest string note numbers and range
|
||||
set stringRange 20
|
||||
array set stringMin {
|
||||
1 40
|
||||
2 45
|
||||
3 50
|
||||
4 55
|
||||
5 59
|
||||
6 64
|
||||
}
|
||||
array set stringNote {
|
||||
1 40
|
||||
2 45
|
||||
3 50
|
||||
4 55
|
||||
5 59
|
||||
6 64
|
||||
}
|
||||
#array set stringAmp { 1 64 2 64 3 64 4 64 5 64 6 64 }
|
||||
array set stringAmp {
|
||||
1 64
|
||||
2 64
|
||||
3 64
|
||||
4 64
|
||||
5 64
|
||||
6 64
|
||||
}
|
||||
|
||||
# Set initial control values
|
||||
set cont2 20.0
|
||||
set cont7 100.0
|
||||
set cont27 64.0
|
||||
set cont28 0.0
|
||||
set cont44 24.0
|
||||
set cont72 64.0
|
||||
set cont128 64.0
|
||||
set velocity 64.0
|
||||
|
||||
# Configure main window
|
||||
wm title . "STK Electric Guitar Model Controller"
|
||||
wm iconname . "guitar"
|
||||
. config -bg white
|
||||
|
||||
# Configure message box
|
||||
label .message -font {Times 14 normal} -background white \
|
||||
-foreground darkred -relief raised \
|
||||
-wraplength 300 -width 60 \
|
||||
-text "Use the spacebar or button to strum all the strings. Use the pulldown menu next to the velocity slider to control the velocity for individual strings."
|
||||
pack .message -padx 5 -pady 10
|
||||
|
||||
# Configure "note on" buttons
|
||||
frame .top
|
||||
button .top.on -text Strum -bg grey66 -command strum
|
||||
button .top.off -text "All Off" -bg grey66 -command allOff
|
||||
button .top.exit -text "Quit" -bg grey66 -command quit
|
||||
pack .top.on -side left -padx 5
|
||||
pack .top.off -side left -padx 5 -pady 10
|
||||
pack .top.exit -side left -padx 5 -pady 10
|
||||
pack .top
|
||||
|
||||
frame .left -borderwidth 5 -relief groove -bg grey88
|
||||
|
||||
scale .left.volume -from 0 -to 128 -length 200 \
|
||||
-command {printWhatz "ControlChange 0.0 1 " 7} \
|
||||
-orient horizontal -label "Volume" \
|
||||
-tickinterval 32 -showvalue true \
|
||||
-variable cont7
|
||||
|
||||
scale .left.reverb -from 0 -to 128 -length 200 \
|
||||
-command {printWhatz "ControlChange 0.0 1 " 44} \
|
||||
-orient horizontal -label "Reverb Mix" \
|
||||
-tickinterval 32 -showvalue true \
|
||||
-variable cont44
|
||||
|
||||
scale .left.bridge -from 0 -to 128 -length 200 \
|
||||
-command {printWhatz "ControlChange 0.0 1 " 2} \
|
||||
-orient horizontal -label "Bridge Coupling Gain" \
|
||||
-tickinterval 32 -showvalue true -variable cont2
|
||||
|
||||
scale .left.fbGain -from 0 -to 128 -length 200 \
|
||||
-command {printWhatz "ControlChange 0.0 1 " 28} \
|
||||
-orient horizontal -label "Feedback Gain" \
|
||||
-tickinterval 32 -showvalue true -variable cont28
|
||||
|
||||
scale .left.fbDelay -from 0 -to 128 -length 200 \
|
||||
-command {printWhatz "ControlChange 0.0 1 " 27} \
|
||||
-orient horizontal -label "Feedback Delay" \
|
||||
-tickinterval 32 -showvalue true -variable cont27
|
||||
|
||||
scale .left.dmix -from 0 -to 128 -length 200 \
|
||||
-command {printWhatz "ControlChange 0.0 1 " 72} \
|
||||
-orient horizontal -label "Distortion Mix" \
|
||||
-tickinterval 32 -showvalue true -variable cont72
|
||||
|
||||
scale .left.pick -from 0 -to 128 -length 200 \
|
||||
-command {printWhatz "ControlChange 0.0 1 " 128} \
|
||||
-orient horizontal -label "Pick Hardness" \
|
||||
-tickinterval 32 -showvalue true -variable cont128
|
||||
|
||||
pack .left.volume -padx 10 -pady 5
|
||||
pack .left.reverb -padx 10 -pady 5
|
||||
pack .left.bridge -padx 10 -pady 5
|
||||
pack .left.fbGain -padx 10 -pady 5
|
||||
pack .left.fbDelay -padx 10 -pady 5
|
||||
pack .left.dmix -padx 10 -pady 5
|
||||
pack .left.pick -padx 10 -pady 10
|
||||
pack .left -side left
|
||||
|
||||
proc quit {} {
|
||||
puts [format "ExitProgram"]
|
||||
flush stdout
|
||||
close stdout
|
||||
exit
|
||||
}
|
||||
|
||||
proc strum {} {
|
||||
global stringNote stringAmp
|
||||
for {set n 1} {$n < 7} {incr n} {
|
||||
puts [format "NoteOn %2.3f %d %3.2f %3.2f" [expr rand()*0.04] $n $stringNote($n) $stringAmp($n)]
|
||||
}
|
||||
flush stdout
|
||||
}
|
||||
|
||||
proc allOff {} {
|
||||
global stringNote stringAmp
|
||||
for {set n 1} {$n < 7} {incr n} {
|
||||
puts [format "NoteOff 0.0 %d %3f %3f" $n $stringNote($n) $stringAmp($n)]
|
||||
}
|
||||
flush stdout
|
||||
}
|
||||
|
||||
# Set bindings
|
||||
bind . <KeyPress> { strum }
|
||||
bind . <Destroy> +quit
|
||||
|
||||
proc printWhatz {tag value1 value2 } {
|
||||
puts [format "%s %2i %3.2f" $tag $value1 $value2]
|
||||
flush stdout
|
||||
}
|
||||
|
||||
proc pluckOne {value} {
|
||||
global stringNote stringAmp
|
||||
puts [format "NoteOn 0.0 %d %3f %3f" $value $stringNote($value) $stringAmp($value)]
|
||||
flush stdout
|
||||
}
|
||||
|
||||
proc setNote {string value} {
|
||||
global stringNote
|
||||
set stringNote($string) $value
|
||||
}
|
||||
|
||||
proc setStringAmp {value} {
|
||||
global stringAmp cbpath
|
||||
set n [$cbpath current]
|
||||
if { $n > 0 } {
|
||||
set stringAmp($n) $value
|
||||
} else {
|
||||
for {set i 1} {$i < 7} {incr i} {
|
||||
set stringAmp($i) $value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frame .strings -bg grey88 -borderwidth 5 -relief groove
|
||||
scale .strings.s1 -from $stringMin(1) -to [expr $stringMin(1)+$stringRange] \
|
||||
-length 350 -orient horizontal -label "String 1: Note Number" \
|
||||
-tickinterval 5 -showvalue true -variable $stringNote(1) \
|
||||
-command {setNote 1}
|
||||
|
||||
scale .strings.s2 -from $stringMin(2) -to [expr $stringMin(2)+$stringRange] \
|
||||
-length 350 -orient horizontal -label "String 2: Note Number" \
|
||||
-tickinterval 5 -showvalue true -variable $stringNote(2) \
|
||||
-command {setNote 2}
|
||||
|
||||
scale .strings.s3 -from $stringMin(3) -to [expr $stringMin(3)+$stringRange] \
|
||||
-length 350 -orient horizontal -label "String 3: Note Number" \
|
||||
-tickinterval 5 -showvalue true -variable $stringNote(3) \
|
||||
-command {setNote 3}
|
||||
|
||||
scale .strings.s4 -from $stringMin(4) -to [expr $stringMin(4)+$stringRange] \
|
||||
-length 350 -orient horizontal -label "String 4: Note Number" \
|
||||
-tickinterval 5 -showvalue true -variable $stringNote(4) \
|
||||
-command {setNote 4}
|
||||
|
||||
scale .strings.s5 -from $stringMin(5) -to [expr $stringMin(5)+$stringRange] \
|
||||
-length 350 -orient horizontal -label "String 5: Note Number" \
|
||||
-tickinterval 5 -showvalue true -variable $stringNote(5) \
|
||||
-command {setNote 5}
|
||||
|
||||
scale .strings.s6 -from $stringMin(6) -to [expr $stringMin(6)+$stringRange] \
|
||||
-length 350 -orient horizontal -label "String 6: Note Number" \
|
||||
-tickinterval 5 -showvalue true -variable $stringNote(6) \
|
||||
-command {setNote 6}
|
||||
|
||||
button .strings.b1 -text Pluck -command { pluckOne 1 }
|
||||
button .strings.b2 -text Pluck -command { pluckOne 2 }
|
||||
button .strings.b3 -text Pluck -command { pluckOne 3 }
|
||||
button .strings.b4 -text Pluck -command { pluckOne 4 }
|
||||
button .strings.b5 -text Pluck -command { pluckOne 5 }
|
||||
button .strings.b6 -text Pluck -command { pluckOne 6 }
|
||||
|
||||
grid .strings -column 0 -row 0
|
||||
grid .strings.b1 -column 1 -row 0 -padx 5 -pady 5
|
||||
grid .strings.b2 -column 1 -row 1
|
||||
grid .strings.b3 -column 1 -row 2
|
||||
grid .strings.b4 -column 1 -row 3
|
||||
grid .strings.b5 -column 1 -row 4
|
||||
grid .strings.b6 -column 1 -row 5
|
||||
|
||||
grid .strings.s1 -column 0 -row 0 -padx 5 -pady 5
|
||||
grid .strings.s2 -column 0 -row 1 -padx 5 -pady 5
|
||||
grid .strings.s3 -column 0 -row 2 -padx 5 -pady 5
|
||||
grid .strings.s4 -column 0 -row 3 -padx 5 -pady 5
|
||||
grid .strings.s5 -column 0 -row 4 -padx 5 -pady 5
|
||||
grid .strings.s6 -column 0 -row 5 -padx 5 -pady 5
|
||||
|
||||
set stringSelect "All"
|
||||
ttk::combobox .strings.combo \
|
||||
-values [ list "All" "String 1" "String 2" "String 3" "String 4" "String 5" "String 6" ] \
|
||||
-width 8 -textvariable stringSelect -justify center
|
||||
|
||||
scale .strings.velocity -from 0 -to 128 -length 350 \
|
||||
-orient horizontal -label "Note Velocity" \
|
||||
-tickinterval 32 -showvalue true -command setStringAmp -variable velocity
|
||||
|
||||
grid .strings.combo -column 1 -row 7
|
||||
grid .strings.velocity -column 0 -row 7 -padx 5 -pady 10
|
||||
|
||||
pack .strings
|
||||
|
||||
set cbpath .strings.combo
|
||||
|
||||
bind . <Configure> { center_the_toplevel %W }
|
||||
proc center_the_toplevel { w } {
|
||||
|
||||
# Callback on the <Configure> event for a toplevel
|
||||
# that should be centered on the screen
|
||||
|
||||
# Make sure that we aren't configuring a child window
|
||||
if { [string equal $w [winfo toplevel $w]] } {
|
||||
|
||||
# Calculate the desired geometry
|
||||
set width [winfo reqwidth $w]
|
||||
set height [winfo reqheight $w]
|
||||
set x [expr { ( [winfo vrootwidth $w] - $width ) / 2 }]
|
||||
set y [expr { ( [winfo vrootheight $w] - $height ) / 2 }]
|
||||
#set y 0
|
||||
|
||||
# Hand the geometry off to the window manager
|
||||
wm geometry $w ${width}x${height}+${x}+${y}
|
||||
|
||||
# Unbind <Configure> so that this procedure is
|
||||
# not called again when the window manager finishes
|
||||
# centering the window. Also, revert geometry management
|
||||
# to internal default for subsequent size changes.
|
||||
bind $w <Configure> {}
|
||||
wm geometry $w ""
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
207
projects/eguitar/utilities.cpp
Normal file
207
projects/eguitar/utilities.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
// Miscellaneous parsing and error functions for use with STK projects.
|
||||
//
|
||||
// Gary P. Scavone, 1999.
|
||||
|
||||
#include "utilities.h"
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(__STK_REALTIME__)
|
||||
#include "RtAudio.h"
|
||||
#endif
|
||||
|
||||
using namespace stk;
|
||||
|
||||
void usage(char *function) {
|
||||
// Error function in case of incorrect command-line argument specifications
|
||||
|
||||
printf("\nusage: %s flag(s)\n", function);
|
||||
printf(" where flag(s) = \n");
|
||||
printf(" -s RATE to specify a sample rate,\n");
|
||||
printf(" -ow <file name> for .wav audio output file,\n");
|
||||
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(" -im <port> for realtime control input by MIDI (virtual port = 0, default = 1).");
|
||||
#endif
|
||||
printf("\n");
|
||||
printf("\n Simultaneous multiple output types are supported.\n");
|
||||
printf(" Likewise, simultaneous control input types are supported.\n");
|
||||
printf(" SKINI formatted scorefiles can be piped or redirected\n");
|
||||
printf(" to %s, though realtime control flags should be omitted\n", function);
|
||||
printf(" when doing so. If the optional <file names> are not\n");
|
||||
printf(" specified, default names will be indicated. Each flag\n");
|
||||
printf(" must include its own '-' sign.\n\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int checkArgs(int nArgs, char *args[])
|
||||
{
|
||||
int w, i = 1, j = 0;
|
||||
int nWvOuts = 0;
|
||||
char flags[2][50] = {""};
|
||||
bool realtime = false;
|
||||
|
||||
if (nArgs < 3 || nArgs > 22) usage(args[0]);
|
||||
|
||||
while (i < nArgs) {
|
||||
if (args[i][0] == '-') {
|
||||
if (args[i][1] == 'o') {
|
||||
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] != 'p') &&
|
||||
(args[i][2] != 'm') && (args[i][2] != 'f') ) usage(args[0]);
|
||||
flags[0][j] = 'i';
|
||||
flags[1][j++] = args[i][2];
|
||||
}
|
||||
else if (args[i][1] == 's' && (i+1 < nArgs) && args[i+1][0] != '-' ) {
|
||||
Stk::setSampleRate( atoi(args[i+1]) );
|
||||
flags[0][j++] = 's';
|
||||
}
|
||||
else usage(args[0]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// Check for multiple flags of the same type
|
||||
for ( i=0; i<=j; i++ ) {
|
||||
w = i+1;
|
||||
while (w <= j ) {
|
||||
if ( flags[0][i] == flags[0][w] && flags[1][i] == flags[1][w] ) {
|
||||
printf("\nError: Multiple command line flags of the same type specified.\n\n");
|
||||
usage(args[0]);
|
||||
}
|
||||
w++;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we have at least one output type
|
||||
if ( nWvOuts < 1 && !realtime ) usage(args[0]);
|
||||
|
||||
return nWvOuts;
|
||||
}
|
||||
|
||||
bool parseArgs(int nArgs, char *args[], WvOut **output, Messager& messager)
|
||||
{
|
||||
int i = 1, j = 0, nWvIns = 0;
|
||||
bool realtime = false;
|
||||
char fileName[256];
|
||||
|
||||
while (i < nArgs) {
|
||||
if ( (args[i][0] == '-') && (args[i][1] == 'i') ) {
|
||||
switch(args[i][2]) {
|
||||
|
||||
case 'f':
|
||||
strcpy(fileName,args[++i]);
|
||||
if ( !messager.setScoreFile( fileName ) ) exit(0);
|
||||
nWvIns++;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
#if defined(__STK_REALTIME__)
|
||||
if ( !messager.startStdInput() ) exit(0);
|
||||
nWvIns++;
|
||||
break;
|
||||
#else
|
||||
usage(args[0]);
|
||||
#endif
|
||||
|
||||
case 'm':
|
||||
#if defined(__STK_REALTIME__)
|
||||
// Check for an optional MIDI port argument.
|
||||
if ((i+1 < nArgs) && args[i+1][0] != '-') {
|
||||
int port = atoi(args[++i]);
|
||||
if ( !messager.startMidiInput( port-1 ) ) exit(0);
|
||||
}
|
||||
else if ( !messager.startMidiInput() ) exit(0);
|
||||
nWvIns++;
|
||||
break;
|
||||
#else
|
||||
usage(args[0]);
|
||||
#endif
|
||||
|
||||
default:
|
||||
usage(args[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( (args[i][0] == '-') && (args[i][1] == 'o') ) {
|
||||
switch(args[i][2]) {
|
||||
|
||||
case 'r':
|
||||
#if defined(__STK_REALTIME__)
|
||||
realtime = true;
|
||||
break;
|
||||
#else
|
||||
usage(args[0]);
|
||||
#endif
|
||||
|
||||
case 'w':
|
||||
if ((i+1 < nArgs) && args[i+1][0] != '-') {
|
||||
i++;
|
||||
strcpy(fileName,args[i]);
|
||||
}
|
||||
else strcpy(fileName,"testwav");
|
||||
output[j] = new FileWvOut(fileName, 1, FileWrite::FILE_WAV );
|
||||
j++;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if ((i+1 < nArgs) && args[i+1][0] != '-') {
|
||||
i++;
|
||||
strcpy(fileName,args[i]);
|
||||
}
|
||||
else strcpy(fileName,"testsnd");
|
||||
output[j] = new FileWvOut(fileName,1, FileWrite::FILE_SND);
|
||||
j++;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if ((i+1 < nArgs) && args[i+1][0] != '-') {
|
||||
i++;
|
||||
strcpy(fileName,args[i]);
|
||||
}
|
||||
else strcpy(fileName,"testmat");
|
||||
output[j] = new FileWvOut(fileName,1, FileWrite::FILE_MAT);
|
||||
j++;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
if ((i+1 < nArgs) && args[i+1][0] != '-') {
|
||||
i++;
|
||||
strcpy(fileName,args[i]);
|
||||
}
|
||||
else strcpy(fileName,"testaif");
|
||||
output[j] = new FileWvOut(fileName,1, FileWrite::FILE_AIF );
|
||||
j++;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(args[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if ( nWvIns == 0 ) {
|
||||
#if defined(__STK_REALTIME__)
|
||||
if ( !messager.startStdInput() ) exit(0);
|
||||
#else
|
||||
printf("\nError: The -if file input flag must be specified for non-realtime use.\n\n");
|
||||
usage(args[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
return realtime;
|
||||
}
|
||||
12
projects/eguitar/utilities.h
Normal file
12
projects/eguitar/utilities.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// Miscellaneous parsing and error functions for use with STK projects.
|
||||
//
|
||||
// Gary P. Scavone, 1999.
|
||||
|
||||
#include "FileWvOut.h"
|
||||
#include "Messager.h"
|
||||
|
||||
void usage(char *function);
|
||||
|
||||
int checkArgs(int numArgs, char *args[]);
|
||||
|
||||
bool parseArgs(int numArgs, char *args[], stk::WvOut **output, stk::Messager& messager);
|
||||
Reference in New Issue
Block a user