diff --git a/ADSR.cpp b/ADSR.cpp index f010ef7..1c60eb3 100644 --- a/ADSR.cpp +++ b/ADSR.cpp @@ -15,143 +15,167 @@ ADSR :: ADSR() : Envelope() { - target = 0.0; - value = 0.0; - attackRate = 0.001; - decayRate = 0.001; - sustainLevel = 0.5; - releaseRate = 0.01; - state = 0; + target = (MY_FLOAT) 0.0; + value = (MY_FLOAT) 0.0; + attackRate = (MY_FLOAT) 0.001; + decayRate = (MY_FLOAT) 0.001; + sustainLevel = (MY_FLOAT) 0.5; + releaseRate = (MY_FLOAT) 0.01; + state = 0; } ADSR :: ~ADSR() { - /* Nothing to do here */ + /* Nothing to do here */ } void ADSR :: keyOn() { - target = 1.0; - rate = attackRate; - state = 0; + target = (MY_FLOAT) 1.0; + rate = attackRate; + state = 0; } void ADSR :: keyOff() { - target = 0.0; - rate = releaseRate; - state = 3; + target = (MY_FLOAT) 0.0; + rate = releaseRate; + state = 3; } void ADSR :: setAttackRate(MY_FLOAT aRate) { - if (aRate < 0.0) { - printf("negative rates not allowed!!, correcting\n"); - attackRate = -aRate; - } - else attackRate = aRate; - attackRate = attackRate * RATE_NORM; /* SEE Object.h */ + if (aRate < 0.0) { + printf("negative rates not allowed!!, correcting\n"); + attackRate = -aRate; + } + else attackRate = aRate; } void ADSR :: setDecayRate(MY_FLOAT aRate) { - if (aRate < 0.0) { - printf("negative rates not allowed!!, correcting\n"); - decayRate = -aRate; - } - else decayRate = aRate; - decayRate = decayRate * RATE_NORM; /* SEE Object.h */ + if (aRate < 0.0) { + printf("negative rates not allowed!!, correcting\n"); + decayRate = -aRate; + } + else decayRate = aRate; } void ADSR :: setSustainLevel(MY_FLOAT aLevel) { - if (aLevel < 0.0 ) { - printf("Sustain level out of range!!, correcting\n"); - sustainLevel = 0.0; - } - else sustainLevel = aLevel; + if (aLevel < 0.0 ) { + printf("Sustain level out of range!!, correcting\n"); + sustainLevel = (MY_FLOAT) 0.0; + } + else sustainLevel = aLevel; } void ADSR :: setReleaseRate(MY_FLOAT aRate) { - if (aRate < 0.0) { - printf("negative rates not allowed!!, correcting\n"); - releaseRate = -aRate; - } - else releaseRate = aRate; - releaseRate = releaseRate * RATE_NORM; /* SEE Object.h */ + if (aRate < 0.0) { + printf("negative rates not allowed!!, correcting\n"); + releaseRate = -aRate; + } + else releaseRate = aRate; } -void ADSR :: setAll(MY_FLOAT attRate, MY_FLOAT decRate, MY_FLOAT susLevel, MY_FLOAT relRate) +void ADSR :: setAttackTime(MY_FLOAT aTime) { - this->setAttackRate(attRate); - this->setDecayRate(decRate); - this->setSustainLevel(susLevel); - this->setReleaseRate(relRate); + if (aTime < 0.0) { + printf("negative times not allowed!!, correcting\n"); + attackRate = ONE_OVER_SRATE / -aTime; + } + else attackRate = ONE_OVER_SRATE / aTime; +} + +void ADSR :: setDecayTime(MY_FLOAT aTime) +{ + if (aTime < 0.0) { + printf("negative times not allowed!!, correcting\n"); + decayRate = ONE_OVER_SRATE / -aTime; + } + else decayRate = ONE_OVER_SRATE / aTime; +} + +void ADSR :: setReleaseTime(MY_FLOAT aTime) +{ + if (aTime < 0.0) { + printf("negative times not allowed!!, correcting\n"); + releaseRate = ONE_OVER_SRATE / -aTime; + } + else releaseRate = ONE_OVER_SRATE / aTime; +} + +void ADSR :: setAllTimes(MY_FLOAT attTime, MY_FLOAT decTime, MY_FLOAT susLevel, MY_FLOAT relTime) +{ + this->setAttackTime(attTime); + this->setDecayTime(decTime); + this->setSustainLevel(susLevel); + this->setReleaseTime(relTime); } void ADSR :: setTarget(MY_FLOAT aTarget) { - target = aTarget; - if (value < target) { - state = ATTACK; - this->setSustainLevel(target); - rate = attackRate; - } - if (value > target) { - this->setSustainLevel(target); - state = DECAY; - rate = decayRate; - } + target = aTarget; + if (value < target) { + state = ATTACK; + this->setSustainLevel(target); + rate = attackRate; + } + if (value > target) { + this->setSustainLevel(target); + state = DECAY; + rate = decayRate; + } } void ADSR :: setValue(MY_FLOAT aValue) { - state = SUSTAIN; - target = aValue; - value = aValue; - this->setSustainLevel(aValue); - rate = 0.0; + state = SUSTAIN; + target = aValue; + value = aValue; + this->setSustainLevel(aValue); + rate = (MY_FLOAT) 0.0; } MY_FLOAT ADSR :: tick() { - if (state==ATTACK) { - value += rate; - if (value >= target) { - value = target; - rate = decayRate; - target = sustainLevel; + if (state==ATTACK) { + value += rate; + if (value >= target) { + value = target; + rate = decayRate; + target = sustainLevel; state = DECAY; - } - } - else if (state==DECAY) { - value -= decayRate; - if (value <= sustainLevel) { - value = sustainLevel; - rate = 0.0; - state = SUSTAIN; - } } - else if (state==RELEASE) { - value -= releaseRate; - if (value <= 0.0) { - value = 0.0; - state = 4; - } + } + else if (state==DECAY) { + value -= decayRate; + if (value <= sustainLevel) { + value = sustainLevel; + rate = (MY_FLOAT) 0.0; + state = SUSTAIN; } - return value; + } + else if (state==RELEASE) { + value -= releaseRate; + if (value <= 0.0) { + value = (MY_FLOAT) 0.0; + state = 4; + } + } + return value; } int ADSR :: informTick() { - this->tick(); - return state; + this->tick(); + return state; } MY_FLOAT ADSR :: lastOut() { - return value; + return value; } /************ Test Main ************************/ diff --git a/ADSR.h b/ADSR.h index 3783904..ee0ec11 100644 --- a/ADSR.h +++ b/ADSR.h @@ -18,26 +18,29 @@ class ADSR : public Envelope { - protected: - MY_FLOAT attackRate; - MY_FLOAT decayRate; - MY_FLOAT sustainLevel; - MY_FLOAT releaseRate; - public: - ADSR(); - ~ADSR(); - void keyOn(); - void keyOff(); - void setAttackRate(MY_FLOAT aRate); - void setDecayRate(MY_FLOAT aRate); - void setSustainLevel(MY_FLOAT aLevel); - void setReleaseRate(MY_FLOAT aRate); - void setAll(MY_FLOAT attRate, MY_FLOAT decRate, MY_FLOAT susLevel, MY_FLOAT relRate); - void setTarget(MY_FLOAT aTarget); - void setValue(MY_FLOAT aValue); - MY_FLOAT tick(); - int informTick(); - MY_FLOAT lastOut(); + protected: + MY_FLOAT attackRate; + MY_FLOAT decayRate; + MY_FLOAT sustainLevel; + MY_FLOAT releaseRate; + public: + ADSR(); + ~ADSR(); + void keyOn(); + void keyOff(); + void setAttackRate(MY_FLOAT aRate); + void setDecayRate(MY_FLOAT aRate); + void setSustainLevel(MY_FLOAT aLevel); + void setReleaseRate(MY_FLOAT aRate); + void setAttackTime(MY_FLOAT aTime); + void setDecayTime(MY_FLOAT aTime); + void setReleaseTime(MY_FLOAT aTime); + void setAllTimes(MY_FLOAT attTime, MY_FLOAT decTime, MY_FLOAT susLevel, MY_FLOAT relTime); + void setTarget(MY_FLOAT aTarget); + void setValue(MY_FLOAT aValue); + MY_FLOAT tick(); + int informTick(); + MY_FLOAT lastOut(); }; #endif diff --git a/AgogoBel.cpp b/AgogoBel.cpp index a777eed..b6dfbc0 100644 --- a/AgogoBel.cpp +++ b/AgogoBel.cpp @@ -12,64 +12,65 @@ /* 360, 1470, 2401, 4600 */ #include "AgogoBel.h" +#include "SKINI11.msg" AgogoBel :: AgogoBel() : Modal4() { - wave = new RawWave("rawwaves/britestk.raw"); - wave->normalize(); - wave->setRate(7.0); /* hardstick */ - this->setRatioAndReson(0, 1.00,0.999); /* Set our */ - this->setRatioAndReson(1, 4.08,0.999); /* resonances */ - this->setRatioAndReson(2,6.669,0.999); /* here */ - this->setRatioAndReson(3,-3725.0,0.999); /* (One fixed) */ - this->setFiltGain(0,0.07); /* And filter */ - this->setFiltGain(1,0.06); /* gains too */ - this->setFiltGain(2,0.04); - this->setFiltGain(3,0.02); - directGain = 0.3; + wave = new RawWave("rawwaves/britestk.raw"); + wave->normalize(); + wave->setRate((MY_FLOAT) 7.0); /* hardstick */ + this->setRatioAndReson(0, (MY_FLOAT) 1.00,(MY_FLOAT) 0.999); /* Set our */ + this->setRatioAndReson(1, (MY_FLOAT) 4.08,(MY_FLOAT) 0.999); /* resonances */ + this->setRatioAndReson(2,(MY_FLOAT) 6.669,(MY_FLOAT) 0.999); /* here */ + this->setRatioAndReson(3,(MY_FLOAT) -3725.0, (MY_FLOAT)0.999); /* (One fixed) */ + this->setFiltGain(0,(MY_FLOAT) 0.06); /* And filter */ + this->setFiltGain(1,(MY_FLOAT) 0.05); /* gains too */ + this->setFiltGain(2,(MY_FLOAT) 0.03); + this->setFiltGain(3,(MY_FLOAT) 0.02); + directGain = (MY_FLOAT) 0.25; } AgogoBel :: ~AgogoBel() { - delete wave; + delete wave; } void AgogoBel :: setStickHardness(MY_FLOAT hardness) { - stickHardness = hardness; /* To an approximation, */ - wave->setRate(3.0 + (8.0 * stickHardness)); /* hardness <-> center */ - masterGain = 1.0; /* freq and amplitude */ + stickHardness = hardness; /* To an approximation, */ + wave->setRate((MY_FLOAT) 3.0 + ((MY_FLOAT) 8.0 * stickHardness)); /* hardness <-> center */ + masterGain = (MY_FLOAT) 1.0; /* freq and amplitude */ } void AgogoBel :: setStrikePosition(MY_FLOAT position) { - MY_FLOAT temp,temp2; - temp2 = position * PI; - strikePosition = position; /* Hack only first */ - temp = sin(0.7 * temp2); /* three modes, */ - this->setFiltGain(0,0.08 * temp); /* leave the other */ - temp = sin(0.1 + (5.0 * temp2)); /* fixed. Why? */ - this->setFiltGain(1,0.07 * temp); /* So it doesn't */ - temp = sin(0.2 + (7.0 * temp2)); /* sound like a */ - this->setFiltGain(2,0.04 * temp); /* sample! */ + MY_FLOAT temp,temp2; + temp2 = position * PI; + strikePosition = position; /* Hack only first */ + temp = (MY_FLOAT) sin(0.7 * temp2); /* three modes, */ + this->setFiltGain(0,(MY_FLOAT) 0.08 * temp); /* leave the other */ + temp = (MY_FLOAT) sin(0.1 + (5.0 * temp2)); /* fixed. Why? */ + this->setFiltGain(1,(MY_FLOAT) 0.07 * temp); /* So it doesn't */ + temp = (MY_FLOAT) sin(0.2 + (7.0 * temp2)); /* sound like a */ + this->setFiltGain(2,(MY_FLOAT) 0.04 * temp); /* sample! */ } void AgogoBel :: controlChange(int number, MY_FLOAT value) { #if defined(_debug_) - printf("AgogoBel : ControlChange: Number=%i Value=%f\n",number,value); + printf("AgogoBel : ControlChange: Number=%i Value=%f\n",number,value); #endif - if (number == MIDI_control1) - this->setStickHardness(value * NORM_7); - else if (number == MIDI_control2) - this->setStrikePosition(value * NORM_7); - else if (number == MIDI_control3) - vibr->setFreq((value * NORM_7 * 12.0)); - else if (number == MIDI_mod_wheel) + if (number == __SK_StickHardness_) + this->setStickHardness(value * NORM_7); + else if (number == __SK_StrikePosition_) + this->setStrikePosition(value * NORM_7); + else if (number == __SK_ModFrequency_) + vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0)); + else if (number == __SK_ModWheel_) vibrGain = (value * NORM_7); - else if (number == MIDI_after_touch) - this->strike(value * NORM_7); - else { - printf("AgogoBel : Undefined Control Number!!\n"); - } + else if (number == __SK_AfterTouch_Cont_) + this->strike(value * NORM_7); + else { + printf("AgogoBel : Undefined Control Number!!\n"); + } } diff --git a/AgogoBel.h b/AgogoBel.h index a8c2656..0d56232 100644 --- a/AgogoBel.h +++ b/AgogoBel.h @@ -2,10 +2,10 @@ /* AgogoBell SubClass of Modal4 Instrument*/ /* by Perry R. Cook, 1995-96 */ /* */ -/* Controls: CONTROL1 = stickHardness */ -/* CONTROL2 = strikePosition*/ -/* CONTROL3 = vibFreq */ -/* MOD_WHEEL= vibAmt */ +/* Controls: CONTROL1 = stickHardness */ +/* CONTROL2 = strikePosition */ +/* CONTROL3 = vibFreq */ +/* MOD_WHEEL= vibAmt */ /*******************************************/ #if !defined(__AgogoBel_h) @@ -15,7 +15,7 @@ class AgogoBel : public Modal4 { - public: + public: AgogoBel(); ~AgogoBel(); void setStickHardness(MY_FLOAT hardness); diff --git a/AllPass1.cpp b/AllPass1.cpp deleted file mode 100644 index 50281ee..0000000 --- a/AllPass1.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*******************************************/ -/* 1st order allpass filter. */ -/* by Perry R. Cook, 1995-96 */ -/* A special case of the one pole */ -/* one zero filter. */ -/*******************************************/ - -#include "AllPass1.h" - -AllPass1 :: AllPass1() -{ - inputs = (MY_FLOAT *) malloc(MY_FLOAT_SIZE); - outputs = (MY_FLOAT *) malloc(MY_FLOAT_SIZE); - this->clear(); - -} - -AllPass1 :: ~AllPass1() -{ - free(inputs); - free(outputs); -} - -void AllPass1 :: clear() -{ - outputs[0] = 0.0; - inputs[0] = 0.0; - lastOutput = 0.0; -} - -MY_FLOAT AllPass1 :: tick(MY_FLOAT sample) -{ - outputs[0] = sample - inputs[0] + (0.99 * outputs[0]); - inputs[0] = sample; - lastOutput = outputs[0]; - return lastOutput; -} - - diff --git a/AllPass1.h b/AllPass1.h deleted file mode 100644 index 164679a..0000000 --- a/AllPass1.h +++ /dev/null @@ -1,24 +0,0 @@ -/*******************************************/ -/* 1st order allpass filter. */ -/* by Perry R. Cook, 1995-96 */ -/* A special case of the one pole */ -/* one zero filter. */ -/*******************************************/ - -#include "Filter.h" - -#if !defined(__AllPass1_h) -#define __AllPass1_h - -#include "Filter.h" - -class AllPass1 : Filter -{ - public: - AllPass1(); - ~AllPass1(); - void clear(); - MY_FLOAT tick(MY_FLOAT sample); -}; - -#endif diff --git a/BeeThree.cpp b/BeeThree.cpp index 374d609..13dae5f 100644 --- a/BeeThree.cpp +++ b/BeeThree.cpp @@ -13,19 +13,19 @@ BeeThree :: BeeThree() : FM4Alg8() "rawwaves/sinewave.raw", "rawwaves/sinewave.raw", "rawwaves/sinewave.raw"); - this->setRatio(0,0.999); - this->setRatio(1,1.997); - this->setRatio(2,3.006); - this->setRatio(3,6.009); + this->setRatio(0,(MY_FLOAT) 0.999); + this->setRatio(1,(MY_FLOAT) 1.997); + this->setRatio(2,(MY_FLOAT) 3.006); + this->setRatio(3,(MY_FLOAT) 6.009); gains[0] = __FM4Op_gains[95]; gains[1] = __FM4Op_gains[95]; gains[2] = __FM4Op_gains[99]; gains[3] = __FM4Op_gains[95]; - adsr[0]->setAll(0.05,0.03,1.0,0.04); - adsr[1]->setAll(0.05,0.03,1.0,0.04); - adsr[2]->setAll(0.05,0.03,1.0,0.04); - adsr[3]->setAll(0.05,0.001,0.4,0.06); - twozero->setGain(0.1); + adsr[0]->setAllTimes((MY_FLOAT) 0.005,(MY_FLOAT) 0.003,(MY_FLOAT) 1.0,(MY_FLOAT) 0.01); + adsr[1]->setAllTimes((MY_FLOAT) 0.005,(MY_FLOAT) 0.003,(MY_FLOAT) 1.0,(MY_FLOAT) 0.01); + adsr[2]->setAllTimes((MY_FLOAT) 0.005,(MY_FLOAT) 0.003,(MY_FLOAT) 1.0,(MY_FLOAT) 0.01); + adsr[3]->setAllTimes((MY_FLOAT) 0.005,(MY_FLOAT) 0.001,(MY_FLOAT) 0.4,(MY_FLOAT) 0.03); + twozero->setGain((MY_FLOAT) 0.1); } BeeThree :: ~BeeThree() @@ -46,7 +46,7 @@ MY_FLOAT BeeThree :: tick() { MY_FLOAT temp; if (modDepth > 0.0) { - temp = 1.0 + (modDepth * vibWave->tick() * 0.1); + temp = (MY_FLOAT) 1.0 + (modDepth * vibWave->tick() * (MY_FLOAT) 0.1); waves[0]->setFreq(baseFreq * ratios[0] * temp); waves[1]->setFreq(baseFreq * ratios[1] * temp); waves[2]->setFreq(baseFreq * ratios[2] * temp); diff --git a/BiQuad.cpp b/BiQuad.cpp index c03137a..a2bddab 100644 --- a/BiQuad.cpp +++ b/BiQuad.cpp @@ -10,71 +10,71 @@ BiQuad :: BiQuad() : Filter() { - inputs = (MY_FLOAT *) malloc(2 * MY_FLOAT_SIZE); - zeroCoeffs[0] = 0.0; - zeroCoeffs[1] = 0.0; - poleCoeffs[0] = 0.0; - poleCoeffs[1] = 0.0; - gain = 1.0; - this->clear(); + inputs = (MY_FLOAT *) malloc(2 * MY_FLOAT_SIZE); + zeroCoeffs[0] = (MY_FLOAT) 0.0; + zeroCoeffs[1] = (MY_FLOAT) 0.0; + poleCoeffs[0] = (MY_FLOAT) 0.0; + poleCoeffs[1] = (MY_FLOAT) 0.0; + gain = (MY_FLOAT) 1.0; + this->clear(); } BiQuad :: ~BiQuad() { - free(inputs); + free(inputs); } void BiQuad :: clear() { - inputs[0] = 0.0; - inputs[1] = 0.0; - lastOutput = 0.0; + inputs[0] = (MY_FLOAT) 0.0; + inputs[1] = (MY_FLOAT) 0.0; + lastOutput = (MY_FLOAT) 0.0; } void BiQuad :: setPoleCoeffs(MY_FLOAT *coeffs) { - poleCoeffs[0] = coeffs[0]; - poleCoeffs[1] = coeffs[1]; + poleCoeffs[0] = coeffs[0]; + poleCoeffs[1] = coeffs[1]; } void BiQuad :: setZeroCoeffs(MY_FLOAT *coeffs) { - zeroCoeffs[0] = coeffs[0]; - zeroCoeffs[1] = coeffs[1]; + zeroCoeffs[0] = coeffs[0]; + zeroCoeffs[1] = coeffs[1]; } void BiQuad :: setFreqAndReson(MY_FLOAT freq, MY_FLOAT reson) { - poleCoeffs[1] = - (reson * reson); - poleCoeffs[0] = 2.0 * reson * cos(TWO_PI * freq / SRATE); + poleCoeffs[1] = - (reson * reson); + poleCoeffs[0] = (MY_FLOAT) 2.0 * reson * (MY_FLOAT) cos(TWO_PI * freq / SRATE); } void BiQuad :: setEqualGainZeroes() { - zeroCoeffs[1] = -1.0; - zeroCoeffs[0] = 0.0; + zeroCoeffs[1] = (MY_FLOAT) -1.0; + zeroCoeffs[0] = (MY_FLOAT) 0.0; } void BiQuad :: setGain(MY_FLOAT aValue) { - gain = aValue; + gain = aValue; } -MY_FLOAT BiQuad :: tick(MY_FLOAT sample) /* Perform Filter Operation */ +MY_FLOAT BiQuad :: tick(MY_FLOAT sample) /* Perform Filter Operation */ { /* Biquad is two pole, two zero filter */ - MY_FLOAT temp; /* Look it up in your favorite DSP text */ + MY_FLOAT temp; /* Look it up in your favorite DSP text */ - temp = sample * gain; /* Here's the math for the */ - temp += inputs[0] * poleCoeffs[0]; /* version which implements */ - temp += inputs[1] * poleCoeffs[1]; /* only 2 state variables. */ + temp = sample * gain; /* Here's the math for the */ + temp += inputs[0] * poleCoeffs[0]; /* version which implements */ + temp += inputs[1] * poleCoeffs[1]; /* only 2 state variables. */ - lastOutput = temp; /* This form takes */ - lastOutput += (inputs[0] * zeroCoeffs[0]); /* 5 multiplies and */ - lastOutput += (inputs[1] * zeroCoeffs[1]); /* 4 adds */ - inputs[1] = inputs[0]; /* and 3 moves */ - inputs[0] = temp; /* like the 2 state-var form*/ + lastOutput = temp; /* This form takes */ + lastOutput += (inputs[0] * zeroCoeffs[0]); /* 5 multiplies and */ + lastOutput += (inputs[1] * zeroCoeffs[1]); /* 4 adds */ + inputs[1] = inputs[0]; /* and 3 moves */ + inputs[0] = temp; /* like the 2 state-var form*/ - return lastOutput; + return lastOutput; } diff --git a/BowTabl.cpp b/BowTabl.cpp index 85538f6..030a484 100644 --- a/BowTabl.cpp +++ b/BowTabl.cpp @@ -7,9 +7,9 @@ BowTabl :: BowTabl() { - offSet = 0.0; /* offset is a bias, really not needed unless */ + offSet = (MY_FLOAT) 0.0; /* offset is a bias, really not needed unless */ /* friction is different in each direction */ - slope = 0.1; /* controls width of friction pulse, */ + slope = (MY_FLOAT) 0.1; /* controls width of friction pulse, */ /* related to bowForce */ } @@ -33,10 +33,10 @@ MY_FLOAT BowTabl :: lookup(MY_FLOAT sample) /* Perform Table Lookup */ MY_FLOAT input; input = sample + offSet; /* add bias to sample */ input *= slope; /* scale it */ - lastOutput = fabs(input) + 0.75; /* below min delta, friction = 1 */ - lastOutput = pow(lastOutput,-4.0); + lastOutput = (MY_FLOAT) fabs((double) input) + (MY_FLOAT) 0.75; /* below min delta, friction = 1 */ + lastOutput = (MY_FLOAT) pow(lastOutput,(MY_FLOAT) -4.0); // if (lastOutput < 0.0 ) lastOutput = 0.0; /* minimum friction is 0.0 */ - if (lastOutput > 1.0 ) lastOutput = 1.0; /* maximum friction is 1.0 */ + if (lastOutput > 1.0 ) lastOutput = (MY_FLOAT) 1.0; /* maximum friction is 1.0 */ return lastOutput; } diff --git a/Bowed.cpp b/Bowed.cpp index 8aeb046..3bee94a 100644 --- a/Bowed.cpp +++ b/Bowed.cpp @@ -15,39 +15,40 @@ /******************************************/ #include "Bowed.h" +#include "SKINI11.msg" Bowed :: Bowed(MY_FLOAT lowestFreq) { long length; length = (long) (SRATE / lowestFreq + 1); neckDelay = new DLineL(length); - length >> 1; + length >>= 1; bridgeDelay = new DLineL(length); bowTabl = new BowTabl; reflFilt = new OnePole; bodyFilt = new BiQuad; vibr = new RawLoop("rawwaves/sinewave.raw"); adsr = new ADSR; - vibrGain = 0.0; + vibrGain = (MY_FLOAT) 0.0; - neckDelay->setDelay(100.0); - bridgeDelay->setDelay(29.0); + neckDelay->setDelay((MY_FLOAT) 100.0); + bridgeDelay->setDelay((MY_FLOAT) 29.0); - bowTabl->setSlope(3.0); + bowTabl->setSlope((MY_FLOAT) 3.0); - reflFilt->setPole(0.6 - (0.1 * RATE_NORM)); - reflFilt->setGain(0.95); + reflFilt->setPole((MY_FLOAT) (0.6 - (0.1 * 22050.0 / SRATE))); + reflFilt->setGain((MY_FLOAT) 0.95); - bodyFilt->setFreqAndReson(500.0, 0.85); + bodyFilt->setFreqAndReson((MY_FLOAT) 500.0, (MY_FLOAT) 0.85); bodyFilt->setEqualGainZeroes(); - bodyFilt->setGain(0.2); + bodyFilt->setGain((MY_FLOAT) 0.2); vibr->normalize(); - vibr->setFreq(6.12723); + vibr->setFreq((MY_FLOAT) 6.12723); - adsr->setAll(0.002,0.01,0.9,0.01); + adsr->setAllTimes((MY_FLOAT) 0.02,(MY_FLOAT) 0.005,(MY_FLOAT) 0.9,(MY_FLOAT) 0.01); - betaRatio = 0.127236; + betaRatio = (MY_FLOAT) 0.127236; } Bowed :: ~Bowed() @@ -69,16 +70,16 @@ void Bowed :: clear() void Bowed :: setFreq(MY_FLOAT frequency) { - baseDelay = (MY_FLOAT) SRATE / frequency - 4.0; /* delay - approx. filter delay */ + baseDelay = SRATE / frequency - (MY_FLOAT) 4.0; /* delay - approx. filter delay */ bridgeDelay->setDelay(baseDelay * betaRatio); /* bow to bridge length */ - neckDelay->setDelay(baseDelay * (1.0 - betaRatio)); /* bow to nut (finger) length */ + neckDelay->setDelay(baseDelay * ((MY_FLOAT) 1.0 - betaRatio)); /* bow to nut (finger) length */ } void Bowed :: startBowing(MY_FLOAT amplitude, MY_FLOAT rate) { adsr->setRate(rate); adsr->keyOn(); - maxVelocity = 0.03 + (0.2 * amplitude); + maxVelocity = (MY_FLOAT) 0.03 + ((MY_FLOAT) 0.2 * amplitude); } void Bowed :: stopBowing(MY_FLOAT rate) @@ -89,7 +90,7 @@ void Bowed :: stopBowing(MY_FLOAT rate) void Bowed :: noteOn(MY_FLOAT freq, MY_FLOAT amp) { - this->startBowing(amp,amp * 0.001); + this->startBowing(amp,amp * (MY_FLOAT) 0.001); this->setFreq(freq); #if defined(_debug_) printf("Bowed : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); @@ -98,7 +99,7 @@ void Bowed :: noteOn(MY_FLOAT freq, MY_FLOAT amp) void Bowed :: noteOff(MY_FLOAT amp) { - this->stopBowing((1.0 - amp) * 0.005); + this->stopBowing(((MY_FLOAT) 1.0 - amp) * (MY_FLOAT) 0.005); #if defined(_debug_) printf("Bowed : NoteOff: Amp=%lf\n",amp); #endif @@ -112,8 +113,8 @@ void Bowed :: setVibrato(MY_FLOAT amount) MY_FLOAT Bowed :: tick() { MY_FLOAT bowVelocity; - MY_FLOAT bridgeRefl=0,nutRefl=0; - MY_FLOAT newVel=0,velDiff=0,stringVel=0; + MY_FLOAT bridgeRefl=(MY_FLOAT) 0,nutRefl=(MY_FLOAT) 0; + MY_FLOAT newVel=(MY_FLOAT) 0,velDiff=(MY_FLOAT) 0,stringVel=(MY_FLOAT) 0; bowVelocity = maxVelocity * adsr->tick(); @@ -127,7 +128,7 @@ MY_FLOAT Bowed :: tick() bridgeDelay->tick(nutRefl + newVel); /* propagations */ if (vibrGain > 0.0) { - neckDelay->setDelay((baseDelay * (1.0 - betaRatio)) + + neckDelay->setDelay((baseDelay * ((MY_FLOAT) 1.0 - betaRatio)) + (baseDelay * vibrGain*vibr->tick())); } @@ -141,19 +142,19 @@ void Bowed :: controlChange(int number, MY_FLOAT value) #if defined(_debug_) printf("Bowed : ControlChange: Number=%i Value=%f\n",number,value); #endif - if (number == MIDI_control1) - bowTabl->setSlope(5.0 - (4.0 * value * NORM_7)); - else if (number == MIDI_control2) { - betaRatio = 0.027236 + (0.2 * value * NORM_7); + if (number == __SK_BowPressure_) + bowTabl->setSlope((MY_FLOAT) 5.0 - ((MY_FLOAT) 4.0 * value * NORM_7)); + else if (number == __SK_BowPosition_) { + betaRatio = (MY_FLOAT) 0.027236 + ((MY_FLOAT) 0.2 * value * NORM_7); bridgeDelay->setDelay(baseDelay * betaRatio); /* bow to bridge length */ - neckDelay->setDelay(baseDelay * (1.0 - betaRatio)); /* bow to nut (finger) length */ + neckDelay->setDelay(baseDelay * ((MY_FLOAT) 1.0 - betaRatio)); /* bow to nut (finger) length */ } - else if (number == MIDI_control3) - vibr->setFreq((value * NORM_7 * 12.0)); - else if (number == MIDI_mod_wheel) - vibrGain = (value * NORM_7 * 0.4); - else if (number == MIDI_after_touch) - adsr->setTarget(value * NORM_7); + else if (number == __SK_ModFrequency_) + vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0)); + else if (number == __SK_ModWheel_) + vibrGain = (value * NORM_7 * (MY_FLOAT) 0.4); + else if (number == __SK_AfterTouch_Cont_) + adsr->setTarget(value * NORM_7); else { printf("Bowed : Undefined Control Number!!\n"); } diff --git a/Brass.cpp b/Brass.cpp index 4f7e318..707c7bc 100644 --- a/Brass.cpp +++ b/Brass.cpp @@ -14,6 +14,7 @@ /******************************************/ #include "Brass.h" +#include "SKINI11.msg" Brass :: Brass(MY_FLOAT lowestFreq) { @@ -22,13 +23,15 @@ Brass :: Brass(MY_FLOAT lowestFreq) lipFilter = new LipFilt; dcBlock = new DCBlock; adsr = new ADSR; - adsr->setAll(0.02, 0.05, 1.0, 0.001); + adsr->setAllTimes((MY_FLOAT) 0.005, (MY_FLOAT) 0.001, (MY_FLOAT) 1.0, (MY_FLOAT) 0.010); vibr = new RawLoop("rawwaves/sinewave.raw"); this->clear(); vibr->normalize(); - vibr->setFreq(6.137); - vibrGain = 0.05; /* breath periodic vibrato component */ + vibr->setFreq((MY_FLOAT) 6.137); + vibrGain = (MY_FLOAT) 0.05; /* breath periodic vibrato component */ + + maxPressure = (MY_FLOAT) 0.0; } Brass :: ~Brass() @@ -45,12 +48,11 @@ void Brass :: clear() delayLine->clear(); lipFilter->clear(); dcBlock->clear(); -/* adsr->reset(); */ } void Brass :: setFreq(MY_FLOAT frequency) { - slideTarget = ((MY_FLOAT) SRATE / frequency * 2.0) + 3.0; + slideTarget = (SRATE / frequency * (MY_FLOAT) 2.0) + (MY_FLOAT) 3.0; /* fudge correction for filter delays */ delayLine->setDelay(slideTarget); /* we'll play a harmonic */ lipTarget = frequency; @@ -78,7 +80,7 @@ void Brass :: stopBlowing(MY_FLOAT rate) void Brass :: noteOn(MY_FLOAT freq, MY_FLOAT amp) { this->setFreq(freq); - this->startBlowing(amp, amp * 0.001); + this->startBlowing(amp, amp * (MY_FLOAT) 0.001); #if defined(_debug_) printf("Brass : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); #endif @@ -86,7 +88,7 @@ void Brass :: noteOn(MY_FLOAT freq, MY_FLOAT amp) void Brass :: noteOff(MY_FLOAT amp) { - this->stopBlowing(amp * 0.005); + this->stopBlowing(amp * (MY_FLOAT) 0.005); #if defined(_debug_) printf("Brass : NoteOff: Amp=%lf\n",amp); #endif @@ -100,8 +102,8 @@ MY_FLOAT Brass :: tick() breathPressure += vibrGain * vibr->tick(); lastOutput = delayLine->tick( /* bore delay */ dcBlock->tick( /* block DC */ - lipFilter->tick(0.3 * breathPressure, /* mouth input */ - 0.85 * delayLine->lastOut()))); /* and bore reflection */ + lipFilter->tick((MY_FLOAT) 0.3 * breathPressure, /* mouth input */ + (MY_FLOAT) 0.85 * delayLine->lastOut()))); /* and bore reflection */ return lastOutput; } @@ -111,17 +113,17 @@ void Brass :: controlChange(int number, MY_FLOAT value) #if defined(_debug_) printf("Brass : ControlChange: Number=%i Value=%f\n",number,value); #endif - if (number == MIDI_control1) { - temp = lipTarget * pow(4.0,(2.0*value*NORM_7) - 1.0); + if (number == __SK_LipTension_) { + temp = lipTarget * (MY_FLOAT) pow(4.0,(2.0*value*NORM_7) - 1.0); this->setLip(temp); } - else if (number == MIDI_control2) - delayLine->setDelay(slideTarget * (0.5 + (value * NORM_7))); - else if (number == MIDI_control3) - vibr->setFreq((value * NORM_7 * 12.0)); - else if (number == MIDI_mod_wheel) - vibrGain = (value * NORM_7 * 0.4); - else if (number == MIDI_after_touch) + else if (number == __SK_SlideLength_) + delayLine->setDelay(slideTarget * ((MY_FLOAT) 0.5 + (value * NORM_7))); + else if (number == __SK_ModFrequency_) + vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0)); + else if (number == __SK_ModWheel_ ) + vibrGain = (value * NORM_7 * (MY_FLOAT) 0.4); + else if (number == __SK_AfterTouch_Cont_) adsr->setTarget(value * NORM_7); else { printf("Brass : Undefined Control Number!!\n"); diff --git a/Clarinet.cpp b/Clarinet.cpp index 8e8df86..4c7baad 100644 --- a/Clarinet.cpp +++ b/Clarinet.cpp @@ -9,117 +9,118 @@ /* */ /* Controls: CONTROL1 = reedStiffns */ /* CONTROL2 = noiseGain */ -/* CONTROL3 = vibFreq */ -/* MOD_WHEEL= vibAmt */ +/* CONTROL3 = vibFreq */ +/* MOD_WHEEL= vibAmt */ /******************************************/ #include "Clarinet.h" +#include "SKINI11.msg" Clarinet :: Clarinet(MY_FLOAT lowestFreq) { - length = (long) (SRATE / lowestFreq + 1); - delayLine = new DLineL(length); - reedTable = new ReedTabl; - reedTable->setOffset(0.7); - reedTable->setSlope(-0.3); - filter = new OneZero; - envelope = new Envelope; - noise = new Noise; - vibr = new RawLoop("rawwaves/sinewave.raw"); - vibr->normalize(); - vibr->setFreq(5.735); - outputGain = 1.0; - noiseGain = 0.2; - vibrGain = 0.1; + length = (long) (SRATE / lowestFreq + 1); + delayLine = new DLineL(length); + reedTable = new ReedTabl; + reedTable->setOffset((MY_FLOAT) 0.7); + reedTable->setSlope((MY_FLOAT) -0.3); + filter = new OneZero; + envelope = new Envelope; + noise = new Noise; + vibr = new RawLoop("rawwaves/sinewave.raw"); + vibr->normalize(); + vibr->setFreq((MY_FLOAT) 5.735); + outputGain = (MY_FLOAT) 1.0; + noiseGain = (MY_FLOAT) 0.2; + vibrGain = (MY_FLOAT) 0.1; } Clarinet :: ~Clarinet() { - delete delayLine; - delete reedTable; - delete filter; - delete envelope; - delete noise; - delete vibr; + delete delayLine; + delete reedTable; + delete filter; + delete envelope; + delete noise; + delete vibr; } void Clarinet :: clear() { - delayLine->clear(); - filter->tick(0.0); + delayLine->clear(); + filter->tick((MY_FLOAT) 0.0); } void Clarinet :: setFreq(MY_FLOAT frequency) { - delayLine->setDelay /* length - approx filter delay */ - ((SRATE / frequency) * 0.5 - 1.5); + delayLine->setDelay /* length - approx filter delay */ + ((SRATE / frequency) * (MY_FLOAT) 0.5 - (MY_FLOAT) 1.5); } void Clarinet :: startBlowing(MY_FLOAT amplitude,MY_FLOAT rate) { - envelope->setRate(rate); - envelope->setTarget(amplitude); + envelope->setRate(rate); + envelope->setTarget(amplitude); } void Clarinet :: stopBlowing(MY_FLOAT rate) { - envelope->setRate(rate); - envelope->setTarget(0.0); + envelope->setRate(rate); + envelope->setTarget((MY_FLOAT) 0.0); } void Clarinet :: noteOn(MY_FLOAT freq, MY_FLOAT amp) { - this->setFreq(freq); - this->startBlowing(0.55 + (amp * 0.30),amp * 0.005); - outputGain = amp + 0.001; + this->setFreq(freq); + this->startBlowing((MY_FLOAT) 0.55 + (amp * (MY_FLOAT) 0.30),amp * (MY_FLOAT) 0.005); + outputGain = amp + (MY_FLOAT) 0.001; #if defined(_debug_) - printf("Clarinet : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); + printf("Clarinet : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); #endif } void Clarinet :: noteOff(MY_FLOAT amp) { - this->stopBlowing(amp * 0.01); + this->stopBlowing(amp * (MY_FLOAT) 0.01); #if defined(_debug_) - printf("Clarinet : NoteOff: Amp=%lf\n",amp); + printf("Clarinet : NoteOff: Amp=%lf\n",amp); #endif } MY_FLOAT Clarinet :: tick() { - MY_FLOAT pressureDiff; - MY_FLOAT breathPressure; + MY_FLOAT pressureDiff; + MY_FLOAT breathPressure; - breathPressure = envelope->tick(); - breathPressure += breathPressure * - noiseGain * noise->tick(); - breathPressure += breathPressure * - vibrGain * vibr->tick(); - pressureDiff = filter->tick(delayLine->lastOut()); /* differential pressure */ - pressureDiff = (pressureDiff * -0.95) - breathPressure; /* of reflected and mouth */ - lastOutput = delayLine->tick(breathPressure + /* perform scattering */ - pressureDiff * reedTable->lookup(pressureDiff)); /* in economical way */ - lastOutput *= outputGain; - return lastOutput; + breathPressure = envelope->tick(); + breathPressure += breathPressure * + noiseGain * noise->tick(); + breathPressure += breathPressure * + vibrGain * vibr->tick(); + pressureDiff = filter->tick(delayLine->lastOut()); /* differential pressure */ + pressureDiff = (pressureDiff * (MY_FLOAT) -0.95) - breathPressure; /* of reflected and mouth */ + lastOutput = delayLine->tick(breathPressure + /* perform scattering */ + pressureDiff * reedTable->lookup(pressureDiff)); /* in economical way */ + lastOutput *= outputGain; + return lastOutput; } void Clarinet :: controlChange(int number, MY_FLOAT value) { #if defined(_debug_) - printf("Clarinet : ControlChange: Number=%i Value=%f\n",number,value); + printf("Clarinet : ControlChange: Number=%i Value=%f\n",number,value); #endif - if (number == MIDI_control1) - reedTable->setSlope(-0.44 + (0.26 * value * NORM_7)); - else if (number == MIDI_control2) - noiseGain = (value * NORM_7 * 0.4); - else if (number == MIDI_control3) - vibr->setFreq((value * NORM_7 * 12.0)); - else if (number == MIDI_mod_wheel) - vibrGain = (value * NORM_7 * 0.5); - else if (number == MIDI_after_touch) { - envelope->setValue(value * NORM_7); - } - else { - printf("Clarinet : Undefined Control Number!!\n"); - } + if (number == __SK_ReedStiffness_) + reedTable->setSlope((MY_FLOAT) -0.44 + ((MY_FLOAT) 0.26 * value * NORM_7)); + else if (number == __SK_NoiseLevel_) + noiseGain = (value * NORM_7 * (MY_FLOAT) 0.4); + else if (number == __SK_ModFrequency_) + vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0)); + else if (number == __SK_ModWheel_) + vibrGain = (value * NORM_7 * (MY_FLOAT) 0.5); + else if (number == __SK_AfterTouch_Cont_) { + envelope->setValue(value * NORM_7); + } + else { + printf("Clarinet : Undefined Control Number!!\n"); + } } diff --git a/Clarinet.h b/Clarinet.h index d64aa3f..fdda6b4 100644 --- a/Clarinet.h +++ b/Clarinet.h @@ -9,8 +9,8 @@ /* */ /* Controls: CONTROL1 = reedStiffns */ /* CONTROL2 = noiseGain */ -/* CONTROL3 = vibFreq */ -/* MOD_WHEEL= vibAmt */ +/* CONTROL3 = vibFreq */ +/* MOD_WHEEL= vibAmt */ /******************************************/ #if !defined(__Clarinet_h) @@ -26,28 +26,28 @@ class Clarinet : public Instrmnt { - protected: - DLineL *delayLine; - ReedTabl *reedTable; - OneZero *filter; - Envelope *envelope; - Noise *noise; - RawLoop *vibr; - long length; - MY_FLOAT outputGain; - MY_FLOAT noiseGain; - MY_FLOAT vibrGain; - public: - Clarinet(MY_FLOAT lowestFreq); - ~Clarinet(); - void clear(); - virtual void setFreq(MY_FLOAT frequency); - void startBlowing(MY_FLOAT amplitude,MY_FLOAT rate); - void stopBlowing(MY_FLOAT rate); - virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); - virtual void noteOff(MY_FLOAT amp); - virtual MY_FLOAT tick(); - virtual void controlChange(int number, MY_FLOAT value); + protected: + DLineL *delayLine; + ReedTabl *reedTable; + OneZero *filter; + Envelope *envelope; + Noise *noise; + RawLoop *vibr; + long length; + MY_FLOAT outputGain; + MY_FLOAT noiseGain; + MY_FLOAT vibrGain; + public: + Clarinet(MY_FLOAT lowestFreq); + ~Clarinet(); + void clear(); + virtual void setFreq(MY_FLOAT frequency); + void startBlowing(MY_FLOAT amplitude,MY_FLOAT rate); + void stopBlowing(MY_FLOAT rate); + virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); + virtual void noteOff(MY_FLOAT amp); + virtual MY_FLOAT tick(); + virtual void controlChange(int number, MY_FLOAT value); }; #endif diff --git a/DCBlock.cpp b/DCBlock.cpp index 6cf5e29..055d305 100644 --- a/DCBlock.cpp +++ b/DCBlock.cpp @@ -26,14 +26,14 @@ DCBlock :: ~DCBlock() void DCBlock :: clear() { - outputs[0] = 0.0; - inputs[0] = 0.0; - lastOutput = 0.0; + outputs[0] = (MY_FLOAT) 0.0; + inputs[0] = (MY_FLOAT) 0.0; + lastOutput = (MY_FLOAT) 0.0; } MY_FLOAT DCBlock :: tick(MY_FLOAT sample) { - outputs[0] = sample - inputs[0] + (0.99 * outputs[0]); + outputs[0] = sample - inputs[0] + ((MY_FLOAT) 0.99 * outputs[0]); inputs[0] = sample; lastOutput = outputs[0]; return lastOutput; diff --git a/DLineA.cpp b/DLineA.cpp index b273803..5c8f631 100644 --- a/DLineA.cpp +++ b/DLineA.cpp @@ -22,7 +22,7 @@ DLineA :: DLineA(long max_length) long i; length = max_length; inputs = (MY_FLOAT *) malloc(length * MY_FLOAT_SIZE); - for (i=0;iclear(); inPoint = 0; outPoint = length >> 1; @@ -36,9 +36,9 @@ DLineA :: ~DLineA() void DLineA :: clear() { long i; - for (i=0;iclear(); - this->setDelay(length * 0.5); + this->setDelay(length * (MY_FLOAT) 0.5); inPoint = 0; outPoint = 0; } @@ -28,8 +28,8 @@ DLineN :: ~DLineN() void DLineN :: clear() { long i; - for (i=0;i +/* Not really General MIDI yet. Coming soon. */ +unsigned char genMIDIMap[128] = { 0,0,0,0,0,0,0,0, // 0-7 + 0,0,0,0,0,0,0,0, // 8-15 + 0,0,0,0,0,0,0,0, // 16-23 + 0,0,0,0,0,0,0,0, // 24-31 + 0,0,0,0,1,0,2,0, // 32-39 + 2,3,6,3,6,4,7,4, // 40-47 + 5,8,5,0,0,0,10,0, // 48-55 + 9,0,0,0,0,0,0,0, // 56-63 + 0,0,0,0,0,0,0,0, // 64-71 + 0,0,0,0,0,0,0,0, // 72-79 + 0,0,0,0,0,0,0,0, // 80-87 + 0,0,0,0,0,0,0,0, // 88-95 + 0,0,0,0,0,0,0,0, // 96-103 + 0,0,0,0,0,0,0,0, // 104-111 + 0,0,0,0,0,0,0,0, // 112-119 + 0,0,0,0,0,0,0,0}; // 120-127 + char waveNames[DRUM_NUMWAVES][16] = { - "bass.raw", - "snar.raw", - "tomlow.raw", - "tommid.raw", - "tomhi.raw", - "hat.raw", - "ride.raw", - "crash.raw", - "cowbell.raw", - "tamb.raw" + "dope.raw", + "bassdrum.raw", + "snardrum.raw", + "tomlowdr.raw", + "tommiddr.raw", + "tomhidrm.raw", + "hihatcym.raw", + "ridecymb.raw", + "crashcym.raw", + "cowbell1.raw", + "tambourn.raw" }; -DrumSynt :: DrumSynt() : Object() +DrumSynt :: DrumSynt() : Instrmnt() { - int i; -/* char temp[64]; */ - -/* for (i=0;ifinish(); */ -/* waves[i]->normalize(0.2); */ -/* } */ + int i; - for (i=0;iclear(); /* then */ - tempWv = waves[0]; - tempFilt = filters[0]; - for (i=0;inormalize(0.2); - filters[numSounding-1]->setPole(0.999 - (vel / 32.0)); - filters[numSounding-1]->setGain(vel / 128.0); - } - else { - waves[notDone]->reset(); - filters[notDone]->setPole(0.999 - (vel / 32.0)); - filters[notDone]->setGain(vel / 128.0); - } + noteNum = (int) ((12*log(freq/220)/log(2)) + 57.01); // Yes I know, this is tres kludgey + vel = (int) (amp * 127); + +#if defined(_debug_) + printf("NoteOn: %s vel=%i\n",waveNames[genMIDIMap[noteNum]],vel); +#endif + + notDone = -1; + for (i=0;iclear(); /* then */ + tempWv = waves[0]; + tempFilt = filters[0]; + for (i=0;inormalize((MY_FLOAT) 0.2); + filters[numSounding-1]->setPole((MY_FLOAT) 0.999 - ((MY_FLOAT) vel * NORM_7 * 0.6)); + filters[numSounding-1]->setGain(vel / (MY_FLOAT) 128.0); + } + else { + waves[notDone]->reset(); + filters[notDone]->setPole((MY_FLOAT) 0.999 - ((MY_FLOAT) vel * NORM_7 * 0.6)); + filters[notDone]->setGain(vel / (MY_FLOAT) 128.0); + } + +#if defined(_debug_) + printf("Number Sounding = %i\n",numSounding); + for (i=0;ilastOut(); + output += filters[i]->tick(waves[i]->lastOut()); - if (waves[i]->informTick() == 1) { - - printf("Wave %i %i down here\n",i,sounding[i]); - - delete waves[i]; + if (waves[i]->informTick() == 1) { +#if defined(_debug_) + printf("Wave %i %i down here\n",i,sounding[i]); +#endif + delete waves[i]; tempFilt = filters[i]; - for (j=i;jclear(); - sounding[j] = -1; - numSounding -= 1; - if (numSounding == 0) notDone = 0; - i -= 1; - } - i++; - } + for (j=i;jclear(); + sounding[j] = -1; + numSounding -= 1; + if (numSounding == 0) notDone = 0; + i -= 1; + } + i++; + } - return output; + return output * 2; } /************** Test Main Program *********************/ - +/* #include "miditabl.h" #include "RawWvOut.h" #include "Reverb.h" #include "Noise.h" -int main() +void main() { long i,j; DrumSynt instrument; RawWvOut output("test.snd"); - Reverb reverb(2137); + Reverb reverb((MY_FLOAT) 2137); Noise noise; for (j=0;j<100;j++) { i = (int) (fabs(noise.tick()) * DRUM_NUMWAVES); - instrument.noteOn(i,127); + instrument.noteOn(i,1.0); for (i=0;i<2000;i++) output.tick(reverb.tick(instrument.tick())); } for (i=0;i<22000;i++) output.tick(reverb.tick(instrument.tick())); } +*/ diff --git a/DrumSynt.h b/DrumSynt.h index ab66517..ac9298a 100644 --- a/DrumSynt.h +++ b/DrumSynt.h @@ -2,7 +2,7 @@ /* Master Class for Drum Synthesizer */ /* by Perry R. Cook, 1995-96 */ /* This instrument contains a bunch of */ -/* RawWvIn objects (Non-Interpolating, */ +/* RawWvIn objects (Non-Interpolating, */ /* 1 shot players), run through a bunch */ /* of one-pole filters. You can specify */ /* the maximum Polyphony (maximum number */ @@ -13,14 +13,14 @@ #if !defined(__DrumSynt_h) #define __DrumSynt_h -#include "Object.h" +#include "Instrmnt.h" #include "RawWvIn.h" #include "OnePole.h" -#define DRUM_NUMWAVES 10 +#define DRUM_NUMWAVES 11 #define DRUM_POLYPHONY 4 -class DrumSynt : public Object +class DrumSynt : public Instrmnt { protected: RawWvIn *waves[DRUM_POLYPHONY]; @@ -30,8 +30,8 @@ class DrumSynt : public Object public: DrumSynt(); /* ~DrumSynt(); */ - void noteOn(int noteNum, int vel); - MY_FLOAT tick(); + virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); + virtual MY_FLOAT tick(); }; #endif diff --git a/Envelope.cpp b/Envelope.cpp index 9dc50c1..31f65cc 100644 --- a/Envelope.cpp +++ b/Envelope.cpp @@ -16,9 +16,9 @@ Envelope :: Envelope() : Object() { - target = 0.0; - value = 0.0; - rate = 0.001; + target = (MY_FLOAT) 0.0; + value = (MY_FLOAT) 0.0; + rate = (MY_FLOAT) 0.001; state = 0; } @@ -28,13 +28,13 @@ Envelope :: ~Envelope() void Envelope :: keyOn() { - target = 1.0; + target = (MY_FLOAT) 1.0; if (value != target) state = 1; } void Envelope :: keyOff() { - target = 0.0; + target = (MY_FLOAT) 0.0; if (value != target) state = 1; } @@ -45,7 +45,15 @@ void Envelope :: setRate(MY_FLOAT aRate) rate = -aRate; } else rate = aRate; - rate = rate * RATE_NORM; /* SEE Object.h */ +} + +void Envelope :: setTime(MY_FLOAT aTime) +{ + if (aTime < 0.0) { + printf("negative times not allowed!!, correcting\n"); + rate = ONE_OVER_SRATE / -aTime ; + } + else rate = ONE_OVER_SRATE / aTime ; } void Envelope :: setTarget(MY_FLOAT aTarget) diff --git a/Envelope.h b/Envelope.h index 8294a0d..44df5dc 100644 --- a/Envelope.h +++ b/Envelope.h @@ -26,10 +26,11 @@ class Envelope : public Object int state; public: Envelope(); - ~Envelope(); + virtual ~Envelope(); void keyOn(); void keyOff(); void setRate(MY_FLOAT aRate); + void setTime(MY_FLOAT aTime); void setTarget(MY_FLOAT aTarget); void setValue(MY_FLOAT aValue); MY_FLOAT tick(); diff --git a/FM4Alg3.cpp b/FM4Alg3.cpp index 93f3433..f7cecb2 100644 --- a/FM4Alg3.cpp +++ b/FM4Alg3.cpp @@ -22,30 +22,35 @@ FM4Alg3 :: FM4Alg3() : FM4Op() /* we still don't know what they will be. */ } +FM4Alg3 :: ~FM4Alg3() +{ +} + MY_FLOAT FM4Alg3 :: tick() { MY_FLOAT temp; - temp = vibWave->tick() * modDepth * 0.2; - waves[0]->setFreq(baseFreq * (1.0 + temp) * ratios[0]); - waves[1]->setFreq(baseFreq * (1.0 + temp) * ratios[1]); - waves[2]->setFreq(baseFreq * (1.0 + temp) * ratios[2]); - waves[3]->setFreq(baseFreq * (1.0 + temp) * ratios[3]); + temp = vibWave->tick() * modDepth * (MY_FLOAT) 0.2; + waves[0]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[0]); + waves[1]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[1]); + waves[2]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[2]); + waves[3]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[3]); temp = gains[2] * adsr[2]->tick() * waves[2]->tick(); waves[1]->addPhaseOffset(temp); waves[3]->addPhaseOffset(twozero->lastOut()); - temp = (1.0 - (control2 * 0.5)) * gains[3] * adsr[3]->tick() * waves[3]->tick(); + temp = ((MY_FLOAT) 1.0 - (control2 * (MY_FLOAT) 0.5)) * + gains[3] * adsr[3]->tick() * waves[3]->tick(); twozero->tick(temp); - temp += control2 * 0.5 * gains[1] * adsr[1]->tick() * waves[1]->tick(); + temp += control2 * (MY_FLOAT) 0.5 * gains[1] * adsr[1]->tick() * waves[1]->tick(); temp = temp * control1; waves[0]->addPhaseOffset(temp); temp = gains[0] * adsr[0]->tick() * waves[0]->tick(); - lastOutput = temp * 0.5; + lastOutput = temp * (MY_FLOAT) 0.5; return lastOutput; } diff --git a/FM4Alg3.h b/FM4Alg3.h index ad8a530..5b2a999 100644 --- a/FM4Alg3.h +++ b/FM4Alg3.h @@ -23,6 +23,7 @@ class FM4Alg3 : public FM4Op { public: FM4Alg3(); + virtual ~FM4Alg3(); MY_FLOAT tick(); }; diff --git a/FM4Alg4.cpp b/FM4Alg4.cpp index 53d3e6b..60f4531 100644 --- a/FM4Alg4.cpp +++ b/FM4Alg4.cpp @@ -22,27 +22,32 @@ FM4Alg4 :: FM4Alg4() : FM4Op() /* we still don't know what they will be. */ } +FM4Alg4 :: ~FM4Alg4() +{ +} + MY_FLOAT FM4Alg4 :: tick() { MY_FLOAT temp; - temp = vibWave->tick() * modDepth * 0.2; - waves[0]->setFreq(baseFreq * (1.0 + temp) * ratios[0]); - waves[1]->setFreq(baseFreq * (1.0 + temp) * ratios[1]); - waves[2]->setFreq(baseFreq * (1.0 + temp) * ratios[2]); - waves[3]->setFreq(baseFreq * (1.0 + temp) * ratios[3]); + temp = vibWave->tick() * modDepth * (MY_FLOAT) 0.2; + waves[0]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[0]); + waves[1]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[1]); + waves[2]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[2]); + waves[3]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp) * ratios[3]); waves[3]->addPhaseOffset(twozero->lastOut()); temp = gains[3] * adsr[3]->tick() * waves[3]->tick(); twozero->tick(temp); waves[2]->addPhaseOffset(temp); - temp = (1.0 - (control2 * 0.5)) * gains[2] * adsr[2]->tick() * waves[2]->tick(); - temp += control2 * 0.5 * gains[1] * adsr[1]->tick() * waves[1]->tick(); + temp = ((MY_FLOAT) 1.0 - (control2 * (MY_FLOAT) 0.5)) * + gains[2] * adsr[2]->tick() * waves[2]->tick(); + temp += control2 * (MY_FLOAT) 0.5 * gains[1] * adsr[1]->tick() * waves[1]->tick(); temp = temp * control1; waves[0]->addPhaseOffset(temp); temp = gains[0] * adsr[0]->tick() * waves[0]->tick(); - lastOutput = temp * 0.5; + lastOutput = temp * (MY_FLOAT) 0.5; return lastOutput; } diff --git a/FM4Alg4.h b/FM4Alg4.h index 6a21da3..4d0848e 100644 --- a/FM4Alg4.h +++ b/FM4Alg4.h @@ -23,6 +23,7 @@ class FM4Alg4 : public FM4Op { public: FM4Alg4(); + virtual ~FM4Alg4(); MY_FLOAT tick(); }; diff --git a/FM4Alg5.cpp b/FM4Alg5.cpp index c6eaca7..9db4709 100644 --- a/FM4Alg5.cpp +++ b/FM4Alg5.cpp @@ -25,6 +25,10 @@ FM4Alg5 :: FM4Alg5() : FM4Op() /* we still don't know what they will be. */ } +FM4Alg5 :: ~FM4Alg5() +{ +} + MY_FLOAT FM4Alg5 :: tick() { MY_FLOAT temp,temp2; @@ -36,13 +40,14 @@ MY_FLOAT FM4Alg5 :: tick() temp = gains[3] * adsr[3]->tick() * waves[3]->tick(); twozero->tick(temp); waves[2]->addPhaseOffset(temp); - temp = (1.0 - (control2 * 0.5)) * gains[0] * adsr[0]->tick() * waves[0]->tick(); - temp += control2 * 0.5 * gains[2] * adsr[2]->tick() * waves[2]->tick(); + temp = ((MY_FLOAT) 1.0 - (control2 * (MY_FLOAT) 0.5)) * + gains[0] * adsr[0]->tick() * waves[0]->tick(); + temp += control2 * (MY_FLOAT) 0.5 * gains[2] * adsr[2]->tick() * waves[2]->tick(); temp2 = vibWave->tick() * modDepth; /* Calculate amplitude mod */ - temp = temp * (1.0 + temp2); /* and apply it to output */ + temp = temp * ((MY_FLOAT) 1.0 + temp2); /* and apply it to output */ - lastOutput = temp * 0.5; + lastOutput = temp * (MY_FLOAT) 0.5; return lastOutput; } diff --git a/FM4Alg5.h b/FM4Alg5.h index 00ad570..bd2dcc7 100644 --- a/FM4Alg5.h +++ b/FM4Alg5.h @@ -26,6 +26,7 @@ class FM4Alg5 : public FM4Op { public: FM4Alg5(); + virtual ~FM4Alg5(); MY_FLOAT tick(); }; diff --git a/FM4Alg6.cpp b/FM4Alg6.cpp index ce071c1..a363cb2 100644 --- a/FM4Alg6.cpp +++ b/FM4Alg6.cpp @@ -24,17 +24,21 @@ FM4Alg6 :: FM4Alg6() : FM4Op() /* we still don't know what they will be. */ } +FM4Alg6 :: ~FM4Alg6() +{ +} + MY_FLOAT FM4Alg6 :: tick() { MY_FLOAT temp,temp2; temp = gains[3] * adsr[3]->tick() * waves[3]->tick(); - temp2 = vibWave->tick() * modDepth * 0.1; /* Calculate frequency mod */ + temp2 = vibWave->tick() * modDepth * (MY_FLOAT) 0.1; /* Calculate frequency mod */ - waves[0]->setFreq(baseFreq * (1.0 + temp2) * ratios[0]); - waves[1]->setFreq(baseFreq * (1.0 + temp2) * ratios[1]); - waves[2]->setFreq(baseFreq * (1.0 + temp2) * ratios[2]); - waves[3]->setFreq(baseFreq * (1.0 + temp2) * ratios[3]); + waves[0]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp2) * ratios[0]); + waves[1]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp2) * ratios[1]); + waves[2]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp2) * ratios[2]); + waves[3]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp2) * ratios[3]); waves[0]->addPhaseOffset(temp * mods[0]); waves[1]->addPhaseOffset(temp * mods[1]); @@ -45,7 +49,7 @@ MY_FLOAT FM4Alg6 :: tick() temp += gains[1] * tilt[1] * adsr[1]->tick() * waves[1]->tick(); temp += gains[2] * tilt[2] * adsr[2]->tick() * waves[2]->tick(); - return temp * 0.33; + return temp * (MY_FLOAT) 0.33; } void FM4Alg6 :: controlChange(int number, MY_FLOAT value) diff --git a/FM4Alg6.h b/FM4Alg6.h index a48f644..e66a33c 100644 --- a/FM4Alg6.h +++ b/FM4Alg6.h @@ -28,6 +28,7 @@ class FM4Alg6 : public FM4Op MY_FLOAT mods[3]; public: FM4Alg6(); + virtual ~FM4Alg6(); MY_FLOAT tick(); virtual void controlChange(int number, MY_FLOAT value); }; diff --git a/FM4Alg8.cpp b/FM4Alg8.cpp index 6743eee..a2ceef2 100644 --- a/FM4Alg8.cpp +++ b/FM4Alg8.cpp @@ -26,18 +26,22 @@ FM4Alg8 :: FM4Alg8() : FM4Op() /* we still don't know what they will be. */ } +FM4Alg8 :: ~FM4Alg8() +{ +} + MY_FLOAT FM4Alg8 :: tick() { MY_FLOAT temp; waves[3]->addPhaseOffset(twozero->lastOut()); - temp = control1 * 2.0 * gains[3] * adsr[3]->tick() * waves[3]->tick(); + temp = control1 * (MY_FLOAT) 2.0 * gains[3] * adsr[3]->tick() * waves[3]->tick(); twozero->tick(temp); - temp += control2 * 2.0 * gains[2] * adsr[2]->tick() * waves[2]->tick(); + temp += control2 * (MY_FLOAT) 2.0 * gains[2] * adsr[2]->tick() * waves[2]->tick(); temp += gains[1] * adsr[1]->tick() * waves[1]->tick(); temp += gains[0] * adsr[0]->tick() * waves[0]->tick(); - lastOutput = temp * 0.125; + lastOutput = temp * (MY_FLOAT) 0.125; return lastOutput; } diff --git a/FM4Alg8.h b/FM4Alg8.h index 864a9d2..02d63ee 100644 --- a/FM4Alg8.h +++ b/FM4Alg8.h @@ -27,6 +27,7 @@ class FM4Alg8 : public FM4Op { public: FM4Alg8(); + virtual ~FM4Alg8(); virtual MY_FLOAT tick(); }; diff --git a/FM4Op.cpp b/FM4Op.cpp index 5c858e3..82b4292 100644 --- a/FM4Op.cpp +++ b/FM4Op.cpp @@ -14,12 +14,13 @@ /*******************************************/ #include "FM4Op.h" +#include "SKINI11.msg" FM4Op :: FM4Op() { int i; MY_FLOAT temp; - MY_FLOAT tempCoeffs[2] = {0.0, -1.0}; + MY_FLOAT tempCoeffs[2] = {(MY_FLOAT) 0.0, (MY_FLOAT) -1.0}; adsr[0] = new ADSR; adsr[1] = new ADSR; adsr[2] = new ADSR; @@ -27,37 +28,37 @@ FM4Op :: FM4Op() twozero = new TwoZero; vibWave = new RawLoop("rawwaves/sinewave.raw"); vibWave->normalize(); - vibWave->setFreq(6.0); /* should make this random?? */ - modDepth = 0.0; + vibWave->setFreq((MY_FLOAT) 6.0); /* should make this random?? */ + modDepth = (MY_FLOAT) 0.0; /* We don't make the waves here yet, because */ /* we don't know what they will be. */ - baseFreq = 440.0; - ratios[0] = 1.0; - ratios[1] = 1.0; - ratios[2] = 1.0; - ratios[3] = 1.0; - gains[0] = 1.0; - gains[1] = 1.0; - gains[2] = 1.0; - gains[3] = 1.0; + baseFreq = (MY_FLOAT) 440.0; + ratios[0] = (MY_FLOAT) 1.0; + ratios[1] = (MY_FLOAT) 1.0; + ratios[2] = (MY_FLOAT) 1.0; + ratios[3] = (MY_FLOAT) 1.0; + gains[0] = (MY_FLOAT) 1.0; + gains[1] = (MY_FLOAT) 1.0; + gains[2] = (MY_FLOAT) 1.0; + gains[3] = (MY_FLOAT) 1.0; twozero->setZeroCoeffs(tempCoeffs); - twozero->setGain(0.0); - control1 = 1.0; - control2 = 1.0; - temp = 1.0; + twozero->setGain((MY_FLOAT) 0.0); + control1 = (MY_FLOAT) 1.0; + control2 = (MY_FLOAT) 1.0; + temp = (MY_FLOAT) 1.0; for (i=99;i>=0;i--) { __FM4Op_gains[i] = temp; - temp *= 0.933033; + temp *= (MY_FLOAT) 0.933033; } - temp = 1.0; + temp = (MY_FLOAT) 1.0; for (i=15;i>=0;i--) { __FM4Op_susLevels[i] = temp; - temp *= 0.707101; + temp *= (MY_FLOAT) 0.707101; } - temp = 8.498186; + temp = (MY_FLOAT) 8.498186; for (i=0;i<32;i++) { __FM4Op_attTimes[i] = temp; - temp *= 0.707101; + temp *= (MY_FLOAT) 0.707101; } } @@ -145,12 +146,12 @@ void FM4Op :: setModulationDepth(MY_FLOAT mDepth) void FM4Op :: setControl1(MY_FLOAT cVal) { - control1 = cVal*2.0; + control1 = cVal * (MY_FLOAT) 2.0; } void FM4Op :: setControl2(MY_FLOAT cVal) { - control2 = cVal*2.0; + control2 = cVal * (MY_FLOAT) 2.0; } void FM4Op :: controlChange(int number, MY_FLOAT value) @@ -158,15 +159,15 @@ void FM4Op :: controlChange(int number, MY_FLOAT value) #if defined(_debug_) printf("FM4Op : ControlChange: Number=%i Value=%f\n",number,value); #endif - if (number == MIDI_control1) + if (number == __SK_Breath_) this->setControl1(value * NORM_7); - else if (number == MIDI_control2) + else if (number == __SK_FootControl_) this->setControl2(value * NORM_7); - else if (number == MIDI_control3) - this->setModulationSpeed(value * NORM_7 * 12.0); /* 0 to 12 Hz */ - else if (number == MIDI_mod_wheel) + else if (number == __SK_ModFrequency_) + this->setModulationSpeed(value * NORM_7 * (MY_FLOAT) 12.0); /* 0 to 12 Hz */ + else if (number == __SK_ModWheel_) this->setModulationDepth(value * NORM_7); - else if (number == MIDI_after_touch) { + else if (number == __SK_AfterTouch_Cont_) { adsr[0]->setTarget(value * NORM_7); adsr[1]->setTarget(value * NORM_7); adsr[2]->setTarget(value * NORM_7); diff --git a/FM4Op.h b/FM4Op.h index 87d56a5..b9dc870 100644 --- a/FM4Op.h +++ b/FM4Op.h @@ -39,7 +39,7 @@ class FM4Op : public Instrmnt MY_FLOAT __FM4Op_attTimes[32]; public: FM4Op(); - ~FM4Op(); + virtual ~FM4Op(); void loadWaves(char* wave1, char* wave2, char* wave3, char* wave4); void clear(); void setFreq(MY_FLOAT frequency); diff --git a/FMVoices.cpp b/FMVoices.cpp index 463e9e5..8e2eb39 100644 --- a/FMVoices.cpp +++ b/FMVoices.cpp @@ -6,113 +6,122 @@ /******************************************/ #include "FMVoices.h" +#include "SKINI11.msg" FMVoices :: FMVoices() : FM4Alg6() { - this->loadWaves("rawwaves/sinewave.raw", - "rawwaves/sinewave.raw", - "rawwaves/sinewave.raw", - "rawwaves/sinewave.raw"); + this->loadWaves("rawwaves/sinewave.raw", + "rawwaves/sinewave.raw", + "rawwaves/sinewave.raw", + "rawwaves/sinewave.raw"); - this->setRatio(0,2.00); - this->setRatio(1,4.00); - this->setRatio(2,12.0); - this->setRatio(3,1.00); - gains[3] = __FM4Op_gains[80]; - adsr[0]->setAll(0.001,0.001,__FM4Op_susLevels[15],0.001); - adsr[1]->setAll(0.001,0.001,__FM4Op_susLevels[15],0.001); - adsr[2]->setAll(0.001,0.001,__FM4Op_susLevels[15],0.001); - adsr[3]->setAll(0.05,0.05,__FM4Op_susLevels[15],0.0001); - twozero->setGain(0.0); - modDepth = 0.005; - currentVowel = 0; - tilt[0] = 1.0; - tilt[1] = 0.5; - tilt[2] = 0.2; - mods[0] = 1.0; - mods[1] = 1.1; - mods[2] = 1.1; - baseFreq = 110.0; - this->setFreq(110.0); + this->setRatio(0,(MY_FLOAT) 2.00); + this->setRatio(1,(MY_FLOAT) 4.00); + this->setRatio(2,(MY_FLOAT) 12.0); + this->setRatio(3,(MY_FLOAT) 1.00); + gains[3] = __FM4Op_gains[80]; + adsr[0]->setAllTimes((MY_FLOAT) 0.050,(MY_FLOAT) 0.050, + __FM4Op_susLevels[15],(MY_FLOAT) 0.050); + adsr[1]->setAllTimes((MY_FLOAT) 0.050,(MY_FLOAT) 0.050, + __FM4Op_susLevels[15],(MY_FLOAT) 0.050); + adsr[2]->setAllTimes((MY_FLOAT) 0.050,(MY_FLOAT) 0.050, + __FM4Op_susLevels[15],(MY_FLOAT) 0.050); + adsr[3]->setAllTimes((MY_FLOAT) 0.010,(MY_FLOAT) 0.010, + __FM4Op_susLevels[15],(MY_FLOAT) 0.500); + twozero->setGain((MY_FLOAT) 0.0); + modDepth = (MY_FLOAT) 0.005; + currentVowel = 0; + tilt[0] = (MY_FLOAT) 1.0; + tilt[1] = (MY_FLOAT) 0.5; + tilt[2] = (MY_FLOAT) 0.2; + mods[0] = (MY_FLOAT) 1.0; + mods[1] = (MY_FLOAT) 1.1; + mods[2] = (MY_FLOAT) 1.1; + baseFreq = (MY_FLOAT) 110.0; + this->setFreq((MY_FLOAT) 110.0); } -#include "phonTabl.h" +/* #include "phonTabl.h" */ + +extern double phonGains[32][2]; +extern double phonParams[32][4][3]; +extern char phonemes[32][4]; void FMVoices :: setFreq(MY_FLOAT frequency) { - MY_FLOAT temp,temp2; - int tempi,tempi2; + MY_FLOAT temp,temp2; + int tempi,tempi2; - if (currentVowel < 16) { - tempi2 = currentVowel; - temp2 = 0.9; - } - else if (currentVowel < 32) { - tempi2 = currentVowel - 16; - temp2 = 1.0; - } - else if (currentVowel < 48) { - tempi2 = currentVowel - 32; - temp2 = 1.1; - } - else if (currentVowel < 64) { - tempi2 = currentVowel - 48; - temp2 = 1.2; - } - baseFreq = frequency; - temp = (temp2 * phonParams[tempi2][0][0] / baseFreq) + 0.5; - tempi = (int) temp; - this->setRatio(0,(MY_FLOAT) tempi); - temp = (temp2 * phonParams[tempi2][1][0] / baseFreq) + 0.5; - tempi = (int) temp; - this->setRatio(1,(MY_FLOAT) tempi); - temp = (temp2 * phonParams[tempi2][2][0] / baseFreq) + 0.5; - tempi = (int) temp; - this->setRatio(2,(MY_FLOAT) tempi); - gains[0] = 1.0; // pow(10.0,phonParams[tempi2][0][2] * 0.05); - gains[1] = 1.0; // pow(10.0,phonParams[tempi2][1][2] * 0.05); - gains[2] = 1.0; // pow(10.0,phonParams[tempi2][2][2] * 0.05); + if (currentVowel < 16) { + tempi2 = currentVowel; + temp2 = (MY_FLOAT) 0.9; + } + else if (currentVowel < 32) { + tempi2 = currentVowel - 16; + temp2 = (MY_FLOAT) 1.0; + } + else if (currentVowel < 48) { + tempi2 = currentVowel - 32; + temp2 = (MY_FLOAT) 1.1; + } + else if (currentVowel <= 64) { + tempi2 = currentVowel - 48; + temp2 = (MY_FLOAT) 1.2; + } + baseFreq = frequency; + temp = (temp2 * (MY_FLOAT) phonParams[tempi2][0][0] / baseFreq) + (MY_FLOAT) 0.5; + tempi = (int) temp; + this->setRatio(0,(MY_FLOAT) tempi); + temp = (temp2 * (MY_FLOAT) phonParams[tempi2][1][0] / baseFreq) + (MY_FLOAT) 0.5; + tempi = (int) temp; + this->setRatio(1,(MY_FLOAT) tempi); + temp = (temp2 * (MY_FLOAT) phonParams[tempi2][2][0] / baseFreq) + (MY_FLOAT) 0.5; + tempi = (int) temp; + this->setRatio(2,(MY_FLOAT) tempi); + gains[0] = (MY_FLOAT) 1.0; // pow(10.0,phonParams[tempi2][0][2] * 0.05); + gains[1] = (MY_FLOAT) 1.0; // pow(10.0,phonParams[tempi2][1][2] * 0.05); + gains[2] = (MY_FLOAT) 1.0; // pow(10.0,phonParams[tempi2][2][2] * 0.05); } void FMVoices :: noteOn(MY_FLOAT freq, MY_FLOAT amp) { - this->setFreq(freq); - tilt[0] = amp; - tilt[1] = amp * amp; - tilt[2] = amp * amp * amp; - this->keyOn(); + this->setFreq(freq); + tilt[0] = amp; + tilt[1] = amp * amp; + tilt[2] = amp * amp * amp; + this->keyOn(); #if defined(_debug_) - printf("FMVoices : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); + printf("FMVoices : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); #endif } void FMVoices :: controlChange(int number, MY_FLOAT value) { - MY_FLOAT temp; - int tempi; + MY_FLOAT temp; + int tempi; #if defined(_debug_) - printf("FM4Op : ControlChange: Number=%i Value=%f\n",number,value); + printf("FM4Op : ControlChange: Number=%i Value=%f\n",number,value); #endif - if (number == MIDI_control1) - gains[3] = __FM4Op_gains[(int) (value * 0.78125)]; - else if (number == MIDI_control2) { - tempi = (int) (value / 2); - currentVowel = tempi; - this->setFreq(baseFreq); - } - else if (number == MIDI_control3) - this->setModulationSpeed(value * NORM_7 * 12.0); /* 0 to 12 Hz */ - else if (number == MIDI_mod_wheel) - this->setModulationDepth(value * NORM_7); - else if (number == MIDI_after_touch) { - temp = value * NORM_7; - tilt[0] = temp; - tilt[1] = temp * temp; - tilt[2] = temp * temp * temp; - } - else { - printf("FM4Op : Undefined Control Number!!\n"); - } + if (number == __SK_Breath_) + gains[3] = __FM4Op_gains[(int) (value * 0.78125)]; + else if (number == __SK_FootControl_) { + tempi = (int) (value / 2); + currentVowel = tempi; + this->setFreq(baseFreq); + } + else if (number == __SK_ModFrequency_) + this->setModulationSpeed(value * NORM_7 * (MY_FLOAT) 12.0); /* 0 to 12 Hz */ + else if (number == __SK_ModWheel_) + this->setModulationDepth(value * NORM_7); + else if (number == __SK_AfterTouch_Cont_) { + temp = value * NORM_7; + tilt[0] = temp; + tilt[1] = temp * temp; + tilt[2] = temp * temp * temp; + } + else { + printf("FM4Op : Undefined Control Number!!\n"); + } } diff --git a/Filter.h b/Filter.h index 727c6f6..623138d 100644 --- a/Filter.h +++ b/Filter.h @@ -21,7 +21,7 @@ class Filter : public Object MY_FLOAT lastOutput; public: Filter(); - ~Filter(); + virtual ~Filter(); MY_FLOAT lastOut(); }; diff --git a/Flute.cpp b/Flute.cpp index 00ec943..023b8af 100644 --- a/Flute.cpp +++ b/Flute.cpp @@ -15,13 +15,14 @@ /******************************************/ #include "Flute.h" +#include "SKINI11.msg" Flute :: Flute(MY_FLOAT lowestFreq) { long length; length = (long) (SRATE / lowestFreq + 1); boreDelay = new DLineL(length); - length >> 1; + length >>= 1; jetDelay = new DLineL(length); jetTable = new JetTabl; filter = new OnePole; @@ -31,19 +32,21 @@ Flute :: Flute(MY_FLOAT lowestFreq) vibr = new RawLoop("rawwaves/sinewave.raw"); this->clear(); - boreDelay->setDelay(100.0); - jetDelay->setDelay(49.0); + boreDelay->setDelay((MY_FLOAT) 100.0); + jetDelay->setDelay((MY_FLOAT) 49.0); - filter->setPole(0.7 - (0.1 * RATE_NORM)); - filter->setGain(-1.0); + filter->setPole((MY_FLOAT) 0.7 - ((MY_FLOAT) 0.1 * (MY_FLOAT) 22050.0 / SRATE)); + filter->setGain((MY_FLOAT) -1.0); vibr->normalize(); - vibr->setFreq(5.925); - adsr->setAll(0.02, 0.05, 0.8, 0.001); - endRefl = 0.5; - jetRefl = 0.5; - noiseGain = 0.15; /* Breath pressure random component */ - vibrGain = 0.05; /* breath periodic vibrato component */ - jetRatio = 0.32; + vibr->setFreq((MY_FLOAT) 5.925); + adsr->setAllTimes((MY_FLOAT) 0.005, (MY_FLOAT) 0.01, (MY_FLOAT) 0.8, (MY_FLOAT) 0.010); + endRefl = (MY_FLOAT) 0.5; + jetRefl = (MY_FLOAT) 0.5; + noiseGain = (MY_FLOAT) 0.15; /* Breath pressure random component */ + vibrGain = (MY_FLOAT) 0.05; /* breath periodic vibrato component */ + jetRatio = (MY_FLOAT) 0.32; + + maxPressure = (MY_FLOAT) 0.0; } Flute :: ~Flute() @@ -70,16 +73,16 @@ void Flute :: clear() void Flute :: setFreq(MY_FLOAT frequency) { MY_FLOAT temp; - lastFreq = frequency * 0.66666; /* we're overblowing here */ - temp = SRATE / lastFreq - 2.0; /* Length - approx. filter delay */ - boreDelay->setDelay(temp); /* Length of bore tube */ - jetDelay->setDelay(temp * jetRatio); /* jet delay shorter */ + lastFreq = frequency * (MY_FLOAT) 0.66666; /* we're overblowing here */ + temp = SRATE / lastFreq - (MY_FLOAT) 2.0; /* Length - approx. filter delay */ + boreDelay->setDelay(temp); /* Length of bore tube */ + jetDelay->setDelay(temp * jetRatio); /* jet delay shorter */ } void Flute :: startBlowing(MY_FLOAT amplitude, MY_FLOAT rate) { adsr->setAttackRate(rate); - maxPressure = amplitude / 0.8; + maxPressure = amplitude / (MY_FLOAT) 0.8; adsr->keyOn(); } @@ -92,8 +95,8 @@ void Flute :: stopBlowing(MY_FLOAT rate) void Flute :: noteOn(MY_FLOAT freq, MY_FLOAT amp) { this->setFreq(freq); - this->startBlowing(1.1 + (amp * 0.20),amp * 0.02); - outputGain = amp + 0.001; + this->startBlowing((MY_FLOAT) 1.1 + (amp * (MY_FLOAT) 0.20),amp * (MY_FLOAT) 0.02); + outputGain = amp + (MY_FLOAT) 0.001; #if defined(_debug_) printf("Flute : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); #endif @@ -101,7 +104,7 @@ void Flute :: noteOn(MY_FLOAT freq, MY_FLOAT amp) void Flute :: noteOff(MY_FLOAT amp) { - this->stopBlowing(amp * 0.02); + this->stopBlowing(amp * (MY_FLOAT) 0.02); #if defined(_debug_) printf("Flute : NoteOff: Amp=%lf\n",amp); #endif @@ -120,7 +123,7 @@ void Flute :: setEndRefl(MY_FLOAT refl) void Flute :: setJetDelay(MY_FLOAT aRatio) { MY_FLOAT temp; - temp = SRATE / lastFreq - 2.0; /* Length - approx. filter delay */ + temp = SRATE / lastFreq - (MY_FLOAT) 2.0; /* Length - approx. filter delay */ jetRatio = aRatio; jetDelay->setDelay(temp * aRatio); /* Scaled by ratio */ } @@ -144,7 +147,7 @@ MY_FLOAT Flute :: tick() pressureDiff = jetDelay->tick(pressureDiff); /* Jet Delay Line */ pressureDiff = jetTable->lookup(pressureDiff) /* Non-Lin Jet + reflected */ + (endRefl * temp); - lastOutput = 0.3 * boreDelay->tick(pressureDiff); /* Bore Delay and "bell" filter */ + lastOutput = (MY_FLOAT) 0.3 * boreDelay->tick(pressureDiff); /* Bore Delay and "bell" filter */ lastOutput *= outputGain; return lastOutput; @@ -156,15 +159,15 @@ void Flute :: controlChange(int number, MY_FLOAT value) #if defined(_debug_) printf("Flute : ControlChange: Number=%i Value=%f\n",number,value); #endif - if (number == MIDI_control1) - this->setJetDelay(0.08 + (0.48 * value * NORM_7)); - else if (number == MIDI_control2) - noiseGain = (value * NORM_7 * 0.4); - else if (number == MIDI_control3) - vibr->setFreq((value * NORM_7 * 12.0)); - else if (number == MIDI_mod_wheel) - vibrGain = (value * NORM_7 * 0.4); - else if (number == MIDI_after_touch) + if (number == __SK_JetDelay_) + this->setJetDelay((MY_FLOAT) 0.08 + ((MY_FLOAT) 0.48 * value * NORM_7)); + else if (number == __SK_NoiseLevel_) + noiseGain = (value * NORM_7 * (MY_FLOAT) 0.4); + else if (number == __SK_ModFrequency_) + vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0)); + else if (number == __SK_ModWheel_) + vibrGain = (value * NORM_7 * (MY_FLOAT) 0.4); + else if (number == __SK_AfterTouch_Cont_) adsr->setTarget(value * NORM_7); else { printf("Flute : Undefined Control Number!!\n"); diff --git a/FormSwep.cpp b/FormSwep.cpp index be1c4d8..0ab6750 100644 --- a/FormSwep.cpp +++ b/FormSwep.cpp @@ -11,22 +11,22 @@ FormSwep :: FormSwep() : Filter() { outputs = (MY_FLOAT *) malloc(2 * MY_FLOAT_SIZE); - poleCoeffs[0] = 0.0; - poleCoeffs[1] = 0.0; - gain = 1.0; - freq = 0.0; - reson = 0.0; - currentGain = 1.0; - currentFreq = 0.0; - currentReson = 0.0; - targetGain = 1.0; - targetFreq = 0.0; - targetReson = 0.0; - deltaGain = 0.0; - deltaFreq = 0.0; - deltaReson = 0.0; - sweepState = 0; - sweepRate = 0.002; + poleCoeffs[0] = (MY_FLOAT) 0.0; + poleCoeffs[1] = (MY_FLOAT) 0.0; + gain = (MY_FLOAT) 1.0; + freq = (MY_FLOAT) 0.0; + reson = (MY_FLOAT) 0.0; + currentGain = (MY_FLOAT) 1.0; + currentFreq = (MY_FLOAT) 0.0; + currentReson = (MY_FLOAT) 0.0; + targetGain = (MY_FLOAT) 1.0; + targetFreq = (MY_FLOAT) 0.0; + targetReson = (MY_FLOAT) 0.0; + deltaGain = (MY_FLOAT) 0.0; + deltaFreq = (MY_FLOAT) 0.0; + deltaReson = (MY_FLOAT) 0.0; + sweepState = (MY_FLOAT) 0.0; + sweepRate = (MY_FLOAT) 0.002; dirty = 0; this->clear(); } @@ -38,8 +38,8 @@ FormSwep :: ~FormSwep() void FormSwep :: clear() { - outputs[0] = 0.0; - outputs[1] = 0.0; + outputs[0] = (MY_FLOAT) 0.0; + outputs[1] = (MY_FLOAT) 0.0; } void FormSwep :: setPoleCoeffs(MY_FLOAT *coeffs) @@ -57,7 +57,7 @@ void FormSwep :: setFreqAndReson(MY_FLOAT aFreq, MY_FLOAT aReson) currentReson = aReson; currentFreq = aFreq; poleCoeffs[1] = - (reson * reson); - poleCoeffs[0] = 2.0 * reson * cos(TWO_PI * freq / SRATE); + poleCoeffs[0] = (MY_FLOAT) 2.0 * reson * (MY_FLOAT) cos(TWO_PI * freq / SRATE); } void FormSwep :: setStates(MY_FLOAT aFreq, MY_FLOAT aReson, MY_FLOAT aGain) @@ -83,7 +83,7 @@ void FormSwep :: setTargets(MY_FLOAT aFreq, MY_FLOAT aReson, MY_FLOAT aGain) deltaFreq = aFreq - currentFreq; deltaReson = aReson - currentReson; deltaGain = aGain - currentGain; - sweepState = 0.0; + sweepState = (MY_FLOAT) 0.0; } void FormSwep :: setSweepRate(MY_FLOAT aRate) @@ -91,6 +91,11 @@ void FormSwep :: setSweepRate(MY_FLOAT aRate) sweepRate = aRate; } +void FormSwep :: setSweepTime(MY_FLOAT aTime) +{ + sweepRate = ONE_OVER_SRATE / aTime; +} + void FormSwep :: setGain(MY_FLOAT aValue) { gain = aValue; @@ -103,7 +108,7 @@ MY_FLOAT FormSwep :: tick(MY_FLOAT sample) /* Perform Filter Operation */ if (dirty) { sweepState += sweepRate; if (sweepState>= 1.0) { - sweepState = 1.0; + sweepState = (MY_FLOAT) 1.0; dirty = 0; currentReson = targetReson; reson = targetReson; @@ -118,7 +123,8 @@ MY_FLOAT FormSwep :: tick(MY_FLOAT sample) /* Perform Filter Operation */ currentGain = gain + (deltaGain * sweepState); } poleCoeffs[1] = - (currentReson * currentReson); - poleCoeffs[0] = 2.0 * currentReson * cos(TWO_PI * currentFreq / SRATE); + poleCoeffs[0] = (MY_FLOAT) 2.0 * currentReson * + (MY_FLOAT) cos(TWO_PI * currentFreq / SRATE); } temp = currentGain * sample; diff --git a/FormSwep.h b/FormSwep.h index 7a46c83..a15d6b1 100644 --- a/FormSwep.h +++ b/FormSwep.h @@ -39,6 +39,7 @@ class FormSwep : public Filter void setStates(MY_FLOAT aFreq, MY_FLOAT aReson, MY_FLOAT aGain); void setTargets(MY_FLOAT aFreq, MY_FLOAT aReson, MY_FLOAT aGain); void setSweepRate(MY_FLOAT aRate); + void setSweepTime(MY_FLOAT aTime); MY_FLOAT tick(MY_FLOAT sample); }; diff --git a/HIERARCH.txt b/HIERARCH.txt deleted file mode 100644 index 6c13687..0000000 --- a/HIERARCH.txt +++ /dev/null @@ -1,125 +0,0 @@ -Brief Descriptions of Classes in TK96CPP -A ToolKit of Sound Synthesis Classes - and Instruments in C++ -Perry Cook, 1995-96, free distribution for -academic, instructional, tutorial, etc. purposes. -Please read README.txt for more information. - -<-----Building Blocks----->|<----------------Instruments------------------> - -SourcSink Filters Non-Lin ModalSyn FM Physical Sampling PhISM - & Formant - -Object---------------------------Instrmnt----------. - | | | | | | -Envelope| Filter BowTabl | .------------------|---------------------. - | | | JetTabl | | | | | | | | | -ADSR | OneZero ReedTabl| Modal4 | FM4Op---.| | | | PhISEM - | OnePole | | | | || | | | | - ._____| TwoZero .____| Marimba | FM4Alg3 || Plucked Sampler | Maracha - | | TwoPole | Vibraphn| | || Clarinet | | Whistle -Noise | DCBlock LipFilt AgogoBel| HeavyMtl|| Brass SamplFlt| VibraSlp - | | BiQuad | || Flute | | Tambourn -SubNoise| AllPass1 .____| .____|| Bowed Moog1 | - | DLineA | | || | - ._____| DLineL VoicForm FM4Alg4 ||____. | - | | DLineN | | | | -RawWave | FormSwep PercFlut| Plucked2 | - | | | | - ._____| .____| Mandolin .____| - | | | | | -RawLoop | FM4Alg5 | DrumSynt - | | | - ._____| Rhodey | - | | Wurley | -NiWave1S| TubeBell | - | .____| - ._____| | | - | | FM4Alg6 | -Modulatr| | | - | FMVoices| - ._____| | - | | .____| -SingWave| | - | FM4Alg8 - ._____| | - | | BeeThree -RawWvOut| - | - ._____| - | | -RawWvIn | - ._____| - | -NIFileIn - -********** Instruments and Algorithms ************** -Each Class will be listed either with all UGs it uses, -or the <> of which it is a flavor. -All inherit from Instrmnt, which inherits from Object. - -Plucked.cpp Basic Plucked String DLineA,OneZero,OnePole,Noise -Plucked2.cpp Not so Basic Pluck DLineL,DlineA,OneZero -Mandolin.cpp My Own Mandolin <> -Bowed.cpp Not Hideous Bowed String DlineL,BowTabl,OnePole,BiQuad,RawWave,ADSR -Brass.cpp Not So Bad Brass Inst. DLineA,LipFilt,DCBlock,ADSR,BiQuad -Clarinet.cpp Pretty Good Clarinet DLineL,ReedTabl,OneZero,Envelope,Noise.h -Flute.cpp Pretty Good Flute JetTabl,DLineL,OnePole,DCBlock,Noise,ADSR,RawWave -Modal4.cpp 4 Resonances Envelope,RawWave,BiQuad,OnePole -Marimba.cpp <> -Vibraphn.cpp <> -Agogobel.cpp <> -FM4Op.cpp 4 Operator FM Master ADSR,RawLoop,TwoZero -FM4Alg3.cpp 3 Cascade w/ FB Mod. <> -FM4Alg4.cpp Like Alg3 but diff. <> -FM4Alg5.cpp 2 Parallel Simple FMs <> -FM4Alg6.cpp 3 Carr. with 1 Mod. <> -FM4Alg8.cpp 4 Osc. Additive <> -HeavyMtl.cpp Distorted Synth <> -PercFlut.cpp Perc. Flute <> -Rhodey.cpp Rhodes-Like Elec. Piano <> -Wurley.cpp Wurlitz. Elec. Piano <> -TubeBell.cpp Classic FM Bell <> -FMVoices.cpp 3-Formant Voice Synth. <> -BeeThree.cpp Cheezy Organ for Paul <> -Sampler.cpp Sampling Synth. 4 each ADSR, RawWave (att), RawWave (loop), OnePole -SamplFlt.cpp Sampler with Swept Filt.<> -Moog1.cpp Swept filter flavor of <> -Voicform.cpp Source/Filter Voice Envelope,Noise,SingWave,FormSwep,OnePole,OneZero -DrumSynt.cpp Drum Synthesizer bunch of NIFileIn, and OnePole - -*********** Basic Unit Generators ************** - -Master Object: Object.cpp for compatibility with Objective C - -Source&Sink: RawWave.cpp Lin-Interp Wavetable, Looped or 1 Shot - NIWave1S.cpp Non-Interp Wavetable, 1 Shot - RawLoop.cpp Lin-Interp Wavetable, Looping - RawWvIn.cpp Lin-Interp Wave In streaming 'device' - NIFileIn.cpp Non-Interp Wave In streamer, closes & opens - RawWvOut.cpp Non-Interp Wave Out streaming 'device' - Envelope.cpp Linearly Goes to Target by Rate, + noteOn/Off - ADSR.cpp ADSR Flavor of Envelope - Noise.cpp Random Number Generator - SubNoise.cpp Random Numbers each N samples - -Filters: Filter.cpp Filter Master Class - OneZero.cpp One Zero Filter - OnePole.cpp One Pole Filter - AllPass1.cpp 1st Order All-Pass (phase) Filter - DCBlock.cpp DC Blocking 1Pole/1Zero Filter - TwoZero.cpp Two Zero Filter - TwoPole.cpp Two Pole Filter - BiQuad.cpp 2Pole/2Zero Filter - FormSwep.cpp Sweepable 2Pole filter, go to target by rate - DLineL.cpp Linearly Interpolating Delay Line - DLineA.cpp AllPass Interpolating Delay Line - DLineN.cpp Non Interpolating Delay Line - -NonLin&Lookup: JetTabl.cpp Cubic Jet NonLinearity - BowTabl.cpp 1/x^3-like Bow NonLinearity - ReedTabl.cpp 1 break point Reed NonLinearity - LipFilt.cpp Pressure Controlled BiQuad with NonLin - -Derived: Modulatr.cpp Per. and Rnd. Vibrato: RawWave,SubNoise,OnePole - SingWave.cpp Looping Wavetable with: Modulatr,Envelope diff --git a/HeavyMtl.cpp b/HeavyMtl.cpp index 230c3c1..ded664c 100644 --- a/HeavyMtl.cpp +++ b/HeavyMtl.cpp @@ -14,21 +14,21 @@ HeavyMtl :: HeavyMtl() : FM4Alg3() "rawwaves/twopeaks.raw", "rawwaves/sinewave.raw"); - this->setRatio(0,1.00 ); - this->setRatio(1,4.00 * 0.999); - this->setRatio(2,3.00 * 1.001); - this->setRatio(3,0.50 * 1.002); + this->setRatio(0,(MY_FLOAT) (1.00 * 1.000)); + this->setRatio(1,(MY_FLOAT) (4.00 * 0.999)); + this->setRatio(2,(MY_FLOAT) (3.00 * 1.001)); + this->setRatio(3,(MY_FLOAT) (0.50 * 1.002)); gains[0] = __FM4Op_gains[92]; gains[1] = __FM4Op_gains[76]; gains[2] = __FM4Op_gains[91]; gains[3] = __FM4Op_gains[68]; - adsr[0]->setAll(0.050,0.0100,1.0,0.001); - adsr[1]->setAll(0.050,0.0010,1.0,0.0001); - adsr[2]->setAll(0.001,0.0020,1.0,0.0002); - adsr[3]->setAll(0.050,0.0010,0.2,0.0002); - twozero->setGain(2.0); - vibWave->setFreq(5.5); - modDepth = 0.00; + adsr[0]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 0.001,(MY_FLOAT) 1.0,(MY_FLOAT) 0.01); + adsr[1]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 0.010,(MY_FLOAT) 1.0,(MY_FLOAT) 0.50); + adsr[2]->setAllTimes((MY_FLOAT) 0.010,(MY_FLOAT) 0.005,(MY_FLOAT) 1.0,(MY_FLOAT) 0.20); + adsr[3]->setAllTimes((MY_FLOAT) 0.030,(MY_FLOAT) 0.010,(MY_FLOAT) 0.2,(MY_FLOAT) 0.20); + twozero->setGain((MY_FLOAT) 2.0); + vibWave->setFreq((MY_FLOAT) 5.5); + modDepth = (MY_FLOAT) 0.00; } HeavyMtl :: ~HeavyMtl() diff --git a/Instrmnt.cpp b/Instrmnt.cpp index 46b59fc..2e95f79 100644 --- a/Instrmnt.cpp +++ b/Instrmnt.cpp @@ -9,20 +9,29 @@ Instrmnt :: Instrmnt() { } +Instrmnt :: ~Instrmnt() +{ +} + void Instrmnt :: noteOn(MY_FLOAT freq, MY_FLOAT amp) { + printf("Warning!! Instrument Class noteOn here!! %f %f\n",freq,amp); } void Instrmnt :: noteOff(MY_FLOAT amp) { + printf("Warning!! Instrument Class noteOff here!! %f\n",amp); } void Instrmnt :: setFreq(MY_FLOAT freq) { + printf("Warning!! Instrument Class setFreq here!! %f\n",freq); } MY_FLOAT Instrmnt :: tick() { + printf("Warning!! Instrument Class tick here!!\n"); + return lastOutput; } MY_FLOAT Instrmnt :: lastOut() @@ -32,4 +41,5 @@ MY_FLOAT Instrmnt :: lastOut() void Instrmnt :: controlChange(int number, MY_FLOAT value) { + printf("Warning!! Instrument Class Control Change here!! %i %f\n",number,value); } diff --git a/Instrmnt.h b/Instrmnt.h index db604d4..ed78a11 100644 --- a/Instrmnt.h +++ b/Instrmnt.h @@ -14,6 +14,7 @@ class Instrmnt : public Object MY_FLOAT lastOutput; public: Instrmnt(); + virtual ~Instrmnt(); MY_FLOAT lastOut(); virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); virtual void noteOff(MY_FLOAT amp); diff --git a/JCRev.cpp b/JCRev.cpp new file mode 100644 index 0000000..fd46e0c --- /dev/null +++ b/JCRev.cpp @@ -0,0 +1,166 @@ +/*******************************************/ +/* JVRev Reverb Subclass */ +/* by Tim Stilson, 1998 */ +/* based on CLM JCRev */ +/* Integrated into STK by Gary Scavone */ +/* */ +/* This is based on some of the famous */ +/* Stanford CCRMA reverbs (NRev, KipRev) */ +/* all based on the the Chowning/Moorer/ */ +/* Schroeder reverberators, which use */ +/* networks of simple allpass and comb */ +/* delay filters. This particular */ +/* arrangement consists of 3 allpass */ +/* filters in series, followed by 4 comb */ +/* filters in parallel, an optional */ +/* lowpass filter, and two decorrelation */ +/* delay lines in parallel at the output. */ +/*******************************************/ + +#include "JCRev.h" + +//#define LOWPASS + +JCRev :: JCRev(MY_FLOAT T60) +{ + /* These are the values from CLM's JCRev.ins ... I found that the + impulse response sounded better with the shorter delay lengths. + --Gary Scavone, 2/1998 + int lens[9] = {4799,4999,5399,5801,1051,337,113,573,487}; + */ + int lens[9] = {1777,1847,1993,2137,389,127,43,211,179}; + int val, i; + + if (SRATE < 44100.0) { + double srscale = SRATE / 44100.0; + for (i=0; i<9; i++) { + val = (int) floor(srscale * lens[i]); + if ((val & 1) == 0) val++; + while (!this->isprime(val)) val += 2; + lens[i] = val; + } + } + + for (i=0; i<3; i++) + { + APdelayLine[i] = new DLineN(lens[i+4] + 2); + APdelayLine[i]->setDelay(lens[i+4]); + } + for (i=0; i<4; i++) + { + CdelayLine[i] = new DLineN(lens[i] + 2); + CdelayLine[i]->setDelay(lens[i]); + combCoeff[i] = pow(10,(-3 * lens[i] / (T60 * SRATE))); + // printf("combCoeff[%d] = %f\n", i, combCoeff[i]); + } + outLdelayLine = new DLineN(lens[7] + 2); + outLdelayLine->setDelay(lens[7]); + outRdelayLine = new DLineN(lens[8] + 2); + outRdelayLine->setDelay(lens[8]); + allPassCoeff = 0.7; + effectMix = 0.3; + this->clear(); +} + +JCRev :: ~JCRev() +{ + delete APdelayLine[0]; + delete APdelayLine[1]; + delete APdelayLine[2]; + delete CdelayLine[0]; + delete CdelayLine[1]; + delete CdelayLine[2]; + delete CdelayLine[3]; + delete outLdelayLine; + delete outRdelayLine; +} + +void JCRev :: clear() +{ + APdelayLine[0]->clear(); + APdelayLine[1]->clear(); + APdelayLine[2]->clear(); + CdelayLine[0]->clear(); + CdelayLine[1]->clear(); + CdelayLine[2]->clear(); + CdelayLine[3]->clear(); + outRdelayLine->clear(); + outLdelayLine->clear(); + lastOutL = 0.0; + lastOutR = 0.0; + combsum1=0.0; + combsum2=0.0; + combsum=0.0; +} + +void JCRev :: setEffectMix(MY_FLOAT mix) +{ + effectMix = mix; +} + +MY_FLOAT JCRev :: lastOutput() +{ + return (lastOutL + lastOutR) * 0.5; +} + +MY_FLOAT JCRev :: lastOutputL() +{ + return lastOutL; +} + +MY_FLOAT JCRev :: lastOutputR() +{ + return lastOutR; +} + +MY_FLOAT JCRev :: tick(MY_FLOAT input) +{ + MY_FLOAT temp,temp0,temp1,temp2,temp3,temp4,temp5,temp6; + MY_FLOAT filtout; + + temp = APdelayLine[0]->lastOut(); + temp0 = allPassCoeff * temp; + temp0 += input; + APdelayLine[0]->tick(temp0); + temp0 = -(allPassCoeff * temp0) + temp; + + temp = APdelayLine[1]->lastOut(); + temp1 = allPassCoeff * temp; + temp1 += temp0; + APdelayLine[1]->tick(temp1); + temp1 = -(allPassCoeff * temp1) + temp; + + temp = APdelayLine[2]->lastOut(); + temp2 = allPassCoeff * temp; + temp2 += temp1; + APdelayLine[2]->tick(temp2); + temp2 = -(allPassCoeff * temp2) + temp; + + temp3 = temp2 + (combCoeff[0] * CdelayLine[0]->lastOut()); + temp4 = temp2 + (combCoeff[1] * CdelayLine[1]->lastOut()); + temp5 = temp2 + (combCoeff[2] * CdelayLine[2]->lastOut()); + temp6 = temp2 + (combCoeff[3] * CdelayLine[3]->lastOut()); + + CdelayLine[0]->tick(temp3); + CdelayLine[1]->tick(temp4); + CdelayLine[2]->tick(temp5); + CdelayLine[3]->tick(temp6); + +#ifdef LOWPASS + combsum2=combsum1; + combsum1=combsum; + combsum = temp3+temp4+temp5+temp6; + filtout= 0.5*combsum1+0.25*(combsum+combsum2); +#else + filtout = temp3+temp4+temp5+temp6; +#endif + + lastOutL = effectMix * (outLdelayLine->tick(filtout)); + lastOutR = effectMix * (outRdelayLine->tick(filtout)); + temp = (1.0 - effectMix) * input; + lastOutL += temp; + lastOutR += temp; + + return (lastOutL + lastOutR) * 0.5; + +} diff --git a/JCRev.h b/JCRev.h new file mode 100644 index 0000000..fa32a5f --- /dev/null +++ b/JCRev.h @@ -0,0 +1,52 @@ +/*******************************************/ +/* JVRev Reverb Subclass */ +/* by Tim Stilson, 1998 */ +/* based on CLM JCRev */ +/* Integrated into STK by Gary Scavone */ +/* */ +/* This is based on some of the famous */ +/* Stanford CCRMA reverbs (NRev, KipRev) */ +/* all based on the the Chowning/Moorer/ */ +/* Schroeder reverberators, which use */ +/* networks of simple allpass and comb */ +/* delay filters. This particular */ +/* arrangement consists of 3 allpass */ +/* filters in series, followed by 4 comb */ +/* filters in parallel, an optional */ +/* lowpass filter, and two decorrelation */ +/* delay lines in parallel at the output. */ +/*******************************************/ + +#if !defined(__JCRev_h) +#define __JCRev_h + +#include "Object.h" +#include "Reverb.h" +#include "DLineN.h" + +class JCRev : public Reverb +{ + protected: + DLineN *APdelayLine[3]; + DLineN *CdelayLine[4]; + DLineN *outLdelayLine; + DLineN *outRdelayLine; + MY_FLOAT allPassCoeff; + MY_FLOAT combCoeff[4]; + MY_FLOAT combsum,combsum1,combsum2; + MY_FLOAT lastOutL; + MY_FLOAT lastOutR; + MY_FLOAT effectMix; + public: + JCRev(MY_FLOAT T60); + ~JCRev(); + void clear(); + void setEffectMix(MY_FLOAT mix); + MY_FLOAT lastOutput(); + MY_FLOAT lastOutputL(); + MY_FLOAT lastOutputR(); + MY_FLOAT tick(MY_FLOAT input); +}; + +#endif + diff --git a/JetTabl.cpp b/JetTabl.cpp index 373f813..99754b3 100644 --- a/JetTabl.cpp +++ b/JetTabl.cpp @@ -11,21 +11,21 @@ JetTabl :: JetTabl() { - lastOutput = 0.0; + lastOutput = (MY_FLOAT) 0.0; } JetTabl :: ~JetTabl() { } -MY_FLOAT JetTabl :: lookup(double sample) /* Perform "Table Lookup" */ +MY_FLOAT JetTabl :: lookup(MY_FLOAT sample) /* Perform "Table Lookup" */ { /* By Polynomial Calculation */ lastOutput = sample * - (sample*sample - 1.0); /* (x^3 - x) approximates sigmoid of jet */ + (sample*sample - (MY_FLOAT) 1.0); /* (x^3 - x) approximates sigmoid of jet */ if (lastOutput > 1.0) - lastOutput = 1.0; /* Saturation at +/- 1.0 */ + lastOutput = (MY_FLOAT) 1.0; /* Saturation at +/- 1.0 */ if (lastOutput < -1.0) - lastOutput = -1.0; + lastOutput = (MY_FLOAT) -1.0; return lastOutput; } diff --git a/JetTabl.h b/JetTabl.h index bb80376..1dd7f0b 100644 --- a/JetTabl.h +++ b/JetTabl.h @@ -12,11 +12,11 @@ class JetTabl : public Object { protected: - double lastOutput; + MY_FLOAT lastOutput; public: JetTabl(); ~JetTabl(); - double lookup(double deltaP); - double lastOut(); + MY_FLOAT lookup(MY_FLOAT deltaP); + MY_FLOAT lastOut(); }; diff --git a/Lacrymosa b/Lacrymosa deleted file mode 100755 index a31dad3..0000000 --- a/Lacrymosa +++ /dev/null @@ -1 +0,0 @@ -time textVoic =100.00 lll ahh ...... =133 .... xxx rrr + + eee .. mmm + ohh ..... sss ahh ..... ddd - eee .. - - ... + + ehh .. + ... sss - - - eee ..... lll =100.0 ahh ....... diff --git a/LipFilt.cpp b/LipFilt.cpp index 3afddb9..a3659ef 100644 --- a/LipFilt.cpp +++ b/LipFilt.cpp @@ -15,8 +15,8 @@ LipFilt :: LipFilt() { MY_FLOAT coeffs[2]; filter = new BiQuad; - coeffs[0] = 0.0; - coeffs[1] = 0.0; + coeffs[0] = (MY_FLOAT) 0.0; + coeffs[1] = (MY_FLOAT) 0.0; filter->setZeroCoeffs(coeffs); this->clear(); } @@ -29,17 +29,17 @@ LipFilt :: ~LipFilt() void LipFilt :: clear() { filter->clear(); - lastOutput = 0.0; + lastOutput = (MY_FLOAT) 0.0; } void LipFilt :: setFreq(MY_FLOAT frequency) { MY_FLOAT coeffs[2]; - coeffs[0] = 2.0 * 0.997 * - cos(TWO_PI * frequency / SRATE); /* damping should change with */ - coeffs[1] = -0.997 * 0.997; /* lip parameters, but not yet.*/ + coeffs[0] = (MY_FLOAT) 2.0 * (MY_FLOAT) 0.997 * + (MY_FLOAT) cos(TWO_PI * frequency / SRATE); /* damping should change with */ + coeffs[1] = (MY_FLOAT) (-0.997 * 0.997); /* lip parameters, but not yet.*/ filter->setPoleCoeffs(coeffs); - filter->setGain(0.03); + filter->setGain((MY_FLOAT) 0.03); } /* NOTE: Here we should add lip tension */ @@ -53,9 +53,10 @@ MY_FLOAT LipFilt :: tick(MY_FLOAT mouthSample,MY_FLOAT boreSample) temp = mouthSample - boreSample; /* Differential pressure */ temp = filter->tick(temp); /* Force -> position */ temp = temp*temp; /* Simple position to area mapping */ - if (temp > 1.0) temp = 1.0; /* Saturation at + 1.0 */ + if (temp > 1.0) temp = (MY_FLOAT) 1.0; /* Saturation at + 1.0 */ lastOutput = temp * mouthSample; /* Assume mouth input = area */ - lastOutput += (1.0 - temp) * boreSample; /* and Bore reflection is compliment. */ + lastOutput += ((MY_FLOAT) 1.0 - temp) + * boreSample; /* and Bore reflection is compliment. */ return lastOutput; } diff --git a/MD2SKINI.cpp b/MD2SKINI.cpp new file mode 100644 index 0000000..aadee39 --- /dev/null +++ b/MD2SKINI.cpp @@ -0,0 +1,378 @@ +/*******************************************/ +/* Simple Realtime MIDI to SKINI Parser */ +/* Gary P. Scavone, February 1998. */ +/* Revised for sockets, May & June 1998. */ +/* */ +/* This object takes MIDI from the input */ +/* stream (via the MIDIIO class), */ +/* parses it, and turns it into SKINI */ +/* messages. */ +/*******************************************/ + +#include "miditabl.h" +#include "MIDIIO.h" +#include "SKINI11.msg" + +int outAHere = 0; + +#if defined(__SGI_REALTIME_) + +#include +#include +#include +#include + +pid_t exit_thread; + +void newString(void *) +{ + char inputString[128]; + printf("Type 'ex' to quit.\n"); + while (!outAHere) { + fgets(inputString, 128, stdin); + if (inputString[0] == 'e' && inputString[1] == 'x') { + outAHere = 1; + } + else printf("Type 'ex' to quit.\n"); + } +} + +#elif defined(__USS_REALTIME_) + +#include + +pthread_t exit_thread; + +void *newString(void *) +{ + char inputString[128]; + printf("Type 'ex' to quit.\n"); + while (!outAHere) { + fgets(inputString, 128, stdin); + if (inputString[0] == 'e' && inputString[1] == 'x') { + outAHere = 1; + } + else printf("Type 'ex' to quit.\n"); + } +} + +#elif (defined(__WINDS_REALTIME_) || defined(__WINMM_REALTIME_) ) + +#include +#include + +unsigned long exit_thread; + +void newString(void *) +{ + char inputString[128]; + printf("Type 'ex' to quit.\n"); + while (!outAHere) { + fgets(inputString, 128, stdin); + if (inputString[0] == 'e' && inputString[1] == 'x') { + outAHere = 1; + } + else printf("Type 'ex' to quit.\n"); + } +} + +#endif + +void errorf(void) { + printf("useage: MD2SKINI \n"); + printf(" where the optional specifies a file\n"); + printf(" to which the SKINI output stream is written.\n"); + printf(" The SKINI output stream is always written to stdout,\n"); + printf(" whether an output file is specified or not.\n"); + exit(0); +} + +void main(int argc,char *argv[]) +{ + long j; + int oneOn = 0; + MY_FLOAT byte2, byte3; + int channel; + int firstMessage = 1; + int writeFileOut = 0; + FILE *fileOut; + MIDIIO *controller; + + if (argc>2) { + errorf(); + } + + if (argc == 2) { + fileOut = fopen(argv[1],"wb"); + writeFileOut = 1; + } + + MY_FLOAT dt=0.0; + + controller = new MIDIIO(); + + /* Setup the exit thread. */ +#if defined(__SGI_REALTIME_) + exit_thread = sproc(newString, PR_SALL); + if (exit_thread == -1) { + fprintf(stderr, "Unable to create exit thread.\n"); + printf("Exiting MD2SKINI process.\n"); + exit(0); + } +#elif defined(__USS_REALTIME_) + int err = 0; + err = pthread_create(&exit_thread, NULL, newString, NULL); + if (err) + { + fprintf(stderr, "Unable to create exit thread.\n"); + printf("Exiting MD2SKINI process.\n"); + exit(0); + } +#elif (defined(__WINDS_REALTIME_) || defined(__WINMM_REALTIME_) ) + exit_thread = _beginthread(newString, 0, NULL); + if (exit_thread == -1) { + fprintf(stderr, "Unable to create exit thread.\n"); + printf("Exiting MD2SKINI process.\n"); + exit(0); + } +#endif + + /* Setup the client socket */ +#if defined(__SOCKET) + + WORD wVersionRequested = MAKEWORD(1,1); + WSADATA wsaData; + SOCKET theSocket; + int nRet; + + nRet = WSAStartup(wVersionRequested, &wsaData); + if (wsaData.wVersion != wVersionRequested) + { + fprintf(stderr,"\n Wrong version\n"); + outAHere = 1; + WSACleanup(); + exit(0); + } + + theSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (theSocket == INVALID_SOCKET) + { + fprintf(stderr,"socket open failed\n"); + outAHere = 1; + WSACleanup(); + exit(0); + } + + /* Fill in the address structure */ + SOCKADDR_IN saServer; + + /* Modified to always use the loopback address of 127.0.0.1 */ + saServer.sin_family = AF_INET; + saServer.sin_port = htons(2001); // Port number from command line + saServer.sin_addr.S_un.S_addr = inet_addr( "127.0.0.1" ); + + /* connect to the server */ + nRet = connect(theSocket, (LPSOCKADDR)&saServer, sizeof(struct sockaddr)); + if (nRet == SOCKET_ERROR) + { + fprintf(stderr,"socket connect failed\n"); + closesocket(theSocket); + outAHere = 1; + WSACleanup(); + exit(0); + } +#endif + + /* 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]; + + while (!outAHere) { + if (controller->nextMessage() > 0) { + byte3 = controller->getByteThree(); + byte2 = controller->getByteTwo(); + channel = controller->getChannel(); + if (writeFileOut) dt = controller->getDeltaTime(); + if (firstMessage) { /* first MIDI message time stamp is meaningless */ + dt = 0.0; + firstMessage = 0; + } + + switch(controller->getType()) { + case __SK_NoteOn_: + if (byte3 < 1.0) { + if (oneOn == 1) { + sprintf(s,"NoteOff\t\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,64.0); + if (writeFileOut) { + fprintf(fileOut,"NoteOff\t\t%.3f %d %.1f %.1f\n",dt,channel,byte2,64.0); + } + } + oneOn -= 1; + } else { + sprintf(s,"NoteOn\t\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,byte3); + if (writeFileOut) { + fprintf(fileOut,"NoteOn\t\t%.3f %d %.1f %.1f\n",dt,channel,byte2,byte3); + } + oneOn += 1; + } + break; + + case __SK_NoteOff_: + if (byte3 < 2.0) byte3 = 64.0; + if (oneOn == 1) { + sprintf(s,"NoteOff\t\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,byte3); + } + if (writeFileOut) { + fprintf(fileOut,"NoteOff\t\t%.3f %d %.1f %.1f\n",dt,channel,byte2,byte3); + } + oneOn -= 1; + break; + + case __SK_PolyPressure_: + sprintf(s,"PolyPressure\t%.3f %d %.1f %.1f\n",0.0,channel,byte2,byte3); + if (writeFileOut) { + fprintf(fileOut,"PolyPressure\t%.3f %d %.1f %.1f\n",dt,channel,byte2,byte3); + } + break; + + case __SK_ControlChange_: + j = (int) byte2; + switch(j) { + case __SK_Volume_: + sprintf(s,"Volume\t%.3f %d %.1f\n",0.0,channel,byte3); + if (writeFileOut) { + fprintf(fileOut,"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 (writeFileOut) { + fprintf(fileOut,"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 (writeFileOut) { + fprintf(fileOut,"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 (writeFileOut) { + fprintf(fileOut,"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 (writeFileOut) { + fprintf(fileOut,"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 (writeFileOut) { + fprintf(fileOut,"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 (writeFileOut) { + fprintf(fileOut,"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 (writeFileOut) { + fprintf(fileOut,"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 (writeFileOut) { + fprintf(fileOut,"Expression\t%.3f %d %.1f\n",dt,channel,byte3); + } + break; + default: + sprintf(s,"ControlChange\t%.3f %d %ld %.1f\n",0.0,channel,j,byte3); + if (writeFileOut) { + fprintf(fileOut,"ControlChange\t%.3f %d %ld %.1f\n",dt,channel,j,byte3); + } + break; + } + break; + + case __SK_ProgramChange_: + j = (int) byte2; + sprintf(s,"ProgramChange\t%.3f %d %ld\n",0.0,channel,j); + if (writeFileOut) { + fprintf(fileOut,"ProgramChange\t%.3f %d %ld\n",dt,channel,j); + } + break; + + case __SK_ChannelPressure_: + sprintf(s,"ChannelPressure\t%.3f %d %.1f\n",0.0,channel,byte2); + if (writeFileOut) { + fprintf(fileOut,"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 (writeFileOut) { + fprintf(fileOut,"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 (writeFileOut) { + fprintf(fileOut,"// Unknown\t\t%.3f %d %f %f\n",dt,channel,byte2,byte3); + } + break; + } + +#if defined(__SOCKET) + nRet = send(theSocket, s, strlen(s), 0); + if (nRet == SOCKET_ERROR) + { + fprintf(stderr,"send failed\n"); + closesocket(theSocket); + outAHere = 1; + WSACleanup(); + exit(0); + } +#else + printf("%s", s); + fflush(stdout); +#endif + memset(s, 0, sizeof(s)); +#if defined(__OS_Win_) + } else Sleep ( (DWORD) 2); +#else + } else usleep( (unsigned long) 2000); +#endif + } + + sprintf(s,"Exiting MD2SKINI process ... bye!\n"); +#if defined(__SOCKET) + nRet = send(theSocket, s, strlen(s), 0); + closesocket(theSocket); + WSACleanup(); +#else + printf("%s", s); + fflush(stdout); +#endif + + if (writeFileOut) { + printf("Wrote SKINI output to file %s.\n", argv[1]); + fclose(fileOut); + } + delete controller; + +#if defined(__SGI_REALTIME_) + kill(exit_thread, SIGKILL); +#endif +} + diff --git a/MIDIIO.cpp b/MIDIIO.cpp new file mode 100644 index 0000000..5aa2123 --- /dev/null +++ b/MIDIIO.cpp @@ -0,0 +1,574 @@ +/******************************************/ +/* MIDIIO.cpp */ +/* Realtime MIDI I/O Object for STK, */ +/* by Gary P. Scavone, 1998. */ +/* Based in part on code by Perry */ +/* Cook (SGI), Paul Leonard (Linux), */ +/* the RoseGarden team (Linux), and */ +/* Bill Putnam (Win95/NT). */ +/* */ +/* At the moment, this object only */ +/* handles MIDI Input, though MIDI */ +/* Output code can go here when someone */ +/* decides they need it (and writes it). */ +/* */ +/* This object opens a MIDI Input device */ +/* and parses MIDI messages into a MIDI */ +/* buffer. Time stamp info is converted */ +/* to deltaTime. MIDI data is stored as */ +/* MY_FLOAT to conform with SKINI. */ +/******************************************/ + +#include "MIDIIO.h" + +#define MIDI_BUFFER_SIZE 1024 +int writeOffset; +int readOffset; + + +#if defined(__SGI_REALTIME_) + +/*************************************/ +/* __SGI_REALTIME_ */ +/*************************************/ + +#include +#include +#include +#include + +MDport inport; + +MDevent *midiBuffer; + +pid_t midi_input_pid; + +void midiInputThread(void *) +{ + MDevent newMessage; + int status; + + while (1) { + mdReceive(inport, &newMessage, 1); + status = (newMessage.msg[0] & MD_STATUSMASK); + + // Ignore Active Sensing messages + if (!((status & 0xff) == 0xfe || (status & 0xff) == 0xf8)) { + midiBuffer[writeOffset] = newMessage; + writeOffset++; + + if( writeOffset >= MIDI_BUFFER_SIZE ) + writeOffset = 0; + } + } +} + +MIDIIO :: MIDIIO() +{ + int nports; + + nports = mdInit(); + printf("%d MIDI devices available\n", nports); + inport = mdOpenInPort(NULL); + if (inport == NULL) { + fprintf(stderr,"Cannot open MIDI device.\n"); + printf("Exiting MIDIIO Process.\n"); + exit(0); + } + mdSetStampMode(inport, MD_NOSTAMP); + + // Set up the circular buffer for the Midi Input Messages + midiBuffer = new MDevent[MIDI_BUFFER_SIZE]; + readOffset = 0; + writeOffset = 0; + + midi_input_pid = sproc(midiInputThread, PR_SALL); + if (midi_input_pid == -1) { + fprintf(stderr, "unable to create MIDI input thread...aborting.\n"); + exit(0); + } +} + +MIDIIO :: ~MIDIIO() +{ + kill (midi_input_pid, SIGKILL); + mdClosePort(inport); + delete [] midiBuffer; +} + +int MIDIIO :: nextMessage() +{ + int status; + int byte1; + int byte2; + MDevent lastEvent; + static unsigned long long lastTimeStamp = 0; + + if ( readOffset == writeOffset ) return 0; + + lastEvent = midiBuffer[readOffset]; + + readOffset++; + if ( readOffset >= MIDI_BUFFER_SIZE ) readOffset = 0; + + status = (lastEvent.msg[0] & MD_STATUSMASK); + byte1 = lastEvent.msg[1]; + byte2 = lastEvent.msg[2]; + channel = (lastEvent.msg[0] & MD_CHANNELMASK); + + if ((status == MD_PROGRAMCHANGE) || + (status == MD_CHANNELPRESSURE)) + { + messageType = status; + byteTwo = (float) byte1; + deltaTime = (MY_FLOAT) ((lastEvent.stamp - lastTimeStamp) * 0.000000001); + lastTimeStamp = lastEvent.stamp; + } + else if ((status == MD_NOTEON) || (status == MD_NOTEOFF) || + (status == MD_CONTROLCHANGE) || (status == MD_POLYKEYPRESSURE)) + { + messageType = status; + byteTwo = (float) byte1; + byteThree = (float) byte2; + deltaTime = (MY_FLOAT) ((lastEvent.stamp - lastTimeStamp) * 0.000000001); + lastTimeStamp = lastEvent.stamp; + } + else if (status == MD_PITCHBENDCHANGE) + { + messageType = status; + byteTwo = (float) byte1 * NORM_7; + byteTwo += (float) byte2; + deltaTime = (MY_FLOAT) ((lastEvent.stamp - lastTimeStamp) * 0.000000001); + lastTimeStamp = lastEvent.stamp; + } + else + { + messageType = -1; + } + + return messageType; +} + + +#elif defined(__USS_REALTIME_) + +/*************************************/ +/* __USS_REALTIME_ */ +/*************************************/ + +#include +#include +#include +#include +#include +#include +#include + +int _seqfd; + +typedef unsigned char byte; + +typedef struct { + byte data[4]; + unsigned long time; +} MIDIMESSAGE; + +MIDIMESSAGE *midiBuffer; + +/* System Messages */ +#define MIDI_SYSTEM_MSG ((byte)0xF0) +#define MessageType(MSG) (byte)((MSG) & ((byte)0xF0)) + +#define SEQUENCER_PATH "/dev/sequencer" + +/* MIDI time code at 100 ticks per second. */ +#define OSS_MIDI_CLOCK_RATE 100 + +pthread_t midi_input_thread; + +void *midiInputThread(void *) +{ + byte NumArgs = 0; + byte ArgsLeft = 0; + unsigned long lastTime = 0; + unsigned long newTime = 0; + byte InBytes[4]; + static MIDIMESSAGE newMessage; + int n; + + while (1) { + if ((n = read(_seqfd, &InBytes, sizeof(InBytes))) == -1) { + fprintf(stderr,"Error reading " SEQUENCER_PATH "\n"); + exit(0); + } + + switch ( InBytes[0] ) + { + case SEQ_WAIT: + /* MIDI clock ticks ... the first MIDI message deltaTime is calculated + * with respect to the start of the MIDI clock. + */ + newTime = ((InBytes[3]<<16)|(InBytes[2]<<8)| InBytes[1]); + break; + + case SEQ_ECHO: + /* no echo events yet defined */ +#ifdef DEBUG + fprintf(stderr,"ECHO EVENT\n"); +#endif + break; + + case SEQ_MIDIPUTC: + /* Determination of a full MIDI message from the input MIDI stream is based + here on the observation that MIDI status bytes and subsequent data bytes + are NOT returned in the same read() call. Rather, they are spread out + over multiple read() returns, with only a single value per return. So, + if we find a status byte, we then determine the number of expected + operands and process that number of subsequent read()s to determine the + complete MIDI message. + */ + if (InBytes[1] & 0x80) { /* Status Byte */ + if (MessageType(InBytes[1]) == MIDI_SYSTEM_MSG) + { + NumArgs = 0; /* no timing info */ +#ifdef DEBUG + fprintf(stderr, "SYSTEM MESSAGE\n"); +#endif + } + else if (MessageType(InBytes[1]) == MIDI_PGM_CHANGE || + MessageType(InBytes[1]) == MIDI_CHN_PRESSURE) + { + NumArgs = 1; + } + else + { + NumArgs = 2; + } + newMessage.data[0] = InBytes[1]; + ArgsLeft = NumArgs; + newMessage.data[1] = 0; + newMessage.data[2] = 0; + } + + if (ArgsLeft && !(InBytes[1] & 0x80)) { /* not a status byte */ + if (ArgsLeft == NumArgs) + newMessage.data[1] = InBytes[1]; + else + { + newMessage.data[2] = InBytes[1]; + } + + --ArgsLeft; + + /* If MIDI message complete, then setup for running status mode + (another event of the same type without status byte). + */ + if ( !ArgsLeft ) { + if (MessageType(newMessage.data[0]) == (int) MIDI_PGM_CHANGE || + MessageType(newMessage.data[0]) == (int) MIDI_CHN_PRESSURE) + { + ArgsLeft = 1; + } + else + { + ArgsLeft = 2; + } + newMessage.time = newTime - lastTime; + lastTime = newTime; + + // Put newMessage in the circular buffer + midiBuffer[writeOffset] = newMessage; + writeOffset++; + + if( writeOffset >= MIDI_BUFFER_SIZE ) + writeOffset = 0; + break; + } + } + + default: + break; + } + } +} + +MIDIIO :: MIDIIO() +{ + int err = 0; + _seqfd = 0; + +#ifdef NONBLOCKING_MIDI + if((_seqfd = open(SEQUENCER_PATH, O_RDONLY+O_NONBLOCK, 0)) == -1) { +#else + if((_seqfd = open(SEQUENCER_PATH, O_RDONLY, 0)) == -1) { +#endif + fprintf(stderr,"Cannot open " SEQUENCER_PATH ". \n"); + printf("Exiting MIDIIO Process.\n"); + exit(0); + } + + // Set up the circular buffer for the Midi Input Messages + midiBuffer = new MIDIMESSAGE[MIDI_BUFFER_SIZE]; + readOffset = 0; + writeOffset = 0; + + err = pthread_create(&midi_input_thread, NULL, midiInputThread, NULL); + if (err) + { + fprintf(stderr, "Unable to create MIDI input thread.\n"); + printf("Exiting MIDIIO Process.\n"); + exit(0); + } +} + +MIDIIO :: ~MIDIIO() +{ + if (_seqfd != 0) close(_seqfd); + delete [] midiBuffer; +} + +int MIDIIO::nextMessage() +{ + MIDIMESSAGE lastEvent; + unsigned long micros = 2000; + + if ( readOffset == writeOffset ) return 0; + + lastEvent = midiBuffer[readOffset]; + + readOffset++; + if ( readOffset >= MIDI_BUFFER_SIZE ) readOffset = 0; + + messageType = (int) (lastEvent.data[0] & 0xf0); + channel = (int) (lastEvent.data[0] & 0x0f); + byteTwo = (float) lastEvent.data[1]; + if (messageType == (int) MIDI_PITCH_BEND) + byteTwo = (float) lastEvent.data[2] + (byteTwo * NORM_7); + else + byteThree = (float) lastEvent.data[2]; + deltaTime = (float) lastEvent.time / OSS_MIDI_CLOCK_RATE; + + return messageType; +} + + +#elif (defined(__WINDS_REALTIME_) || defined(__WINMM_REALTIME_) ) + +/*************************************/ +/* __WIN_REALTIME_ */ +/*************************************/ + +#include +#include "MIDIIO.h" + +#define MIDI_NOTEON 0x90 +#define MIDI_NOTEOFF 0x80 +#define MIDI_POLYKEYPRESSURE 0xA0 +#define MIDI_CHANNELPRESSURE 0xD0 +#define MIDI_PROGRAMCHANGE 0xC0 +#define MIDI_CONTROLCHANGE 0xB0 +#define MIDI_PITCHBEND 0xE0 + +typedef struct { + DWORD data; + DWORD time; +} MIDIMESSAGE; + +MIDIMESSAGE *midiBuffer; + +static void CALLBACK midiInputCallback( HMIDIOUT hmin, UINT inputStatus, + DWORD instancePtr, DWORD midiMessage, DWORD timestamp) +{ + MIDIMESSAGE newMessage; + + switch (inputStatus) { + case MIM_OPEN: +#ifdef TESTING_MIDI_IN + printf("MIM_OPEN\n"); +#endif + break; + + case MIM_CLOSE: +#ifdef TESTING_MIDI_IN + printf("MIM_CLOSE\n"); +#endif + break; + + case MIM_DATA: +#ifdef TESTING_MIDI_IN + printf("MIM_DATA\n"); +#endif + // Ignore Active Sensing messages + if ((midiMessage & 0xff) == 0xfe || (midiMessage & 0xff) == 0xf8) { + break; + } + newMessage.data = midiMessage; + newMessage.time = timestamp; + + // Put newMessage in the circular buffer + midiBuffer[writeOffset] = newMessage; + writeOffset++; + + if( writeOffset >= MIDI_BUFFER_SIZE ) + writeOffset = 0; + break; + + case MIM_ERROR: + fprintf(stderr,"Invalid MIDI message received!\n"); +#ifdef TESTING_MIDI_IN + printf("MIM_ERROR\n"); +#endif + break; + + case MIM_LONGDATA: + /* System exclusive buffer is returned */ + break; + + case MIM_LONGERROR: +#ifdef TESTING_MIDI_IN + printf("MIM_LONGERROR\n"); +#endif + break; + + default: + break; + } +} + +HMIDIIN hMidiIn ; // Handle to Midi Output Device + +MIDIIO :: MIDIIO() +{ + MMRESULT result; + UINT uDeviceID; + MIDIINCAPS deviceCaps; + UINT i; + char inputString[128]; + + uDeviceID = midiInGetNumDevs(); + printf("%i MIDI Input Devices Available.\n",uDeviceID); + if (uDeviceID == 0) { + printf("Exiting MIDIIO Process.\n"); + exit(0); + } + + for (i=0; i 1) { + printf("\nType the MIDI Device to open: "); + fgets(inputString, 128, stdin); + uDeviceID = (UINT) atoi(inputString); + } + else uDeviceID -= 1; + + // Open the port and return any errors + result = midiInOpen(&hMidiIn, uDeviceID, (DWORD)&midiInputCallback, (DWORD)NULL, CALLBACK_FUNCTION); + if (result != MMSYSERR_NOERROR) { + fprintf(stderr,"Cannot open MIDI Input Device %d!\n", uDeviceID); + printf("Exiting MIDIIO Process.\n"); + exit(0); + } + + // Set up the circular buffer for the Midi Input Messages + midiBuffer = new MIDIMESSAGE[MIDI_BUFFER_SIZE]; + readOffset = 0; + writeOffset = 0; + + midiInStart( hMidiIn ); +} + +MIDIIO :: ~MIDIIO() +{ + midiInReset( hMidiIn ); + midiInStop( hMidiIn ); + midiInClose( hMidiIn ); + delete [] midiBuffer; +} + +int MIDIIO :: nextMessage() +{ + int status; + int byte1; + int byte2; + MIDIMESSAGE lastEvent; + static DWORD lastTime = 0; + static DWORD newTime = 0; + + if ( readOffset == writeOffset ) return 0; + + lastEvent = midiBuffer[readOffset]; + + readOffset++; + if ( readOffset >= MIDI_BUFFER_SIZE ) readOffset = 0; + + status = (int) (lastEvent.data & 0xff); + byte1 = (int) (lastEvent.data & 0xff00) >> 8; + byte2 = (int) (lastEvent.data & 0xff0000) >> 16; + channel = (int) (status & 0x0f); + newTime = lastEvent.time; + deltaTime = (float) (newTime - lastTime) * 0.001; + lastTime = newTime; + + if ((status == MIDI_PROGRAMCHANGE) || + (status == MIDI_CHANNELPRESSURE)) + { + messageType = status; + byteTwo = (float) byte1; + } + else if ((status == MIDI_NOTEON) || (status == MIDI_NOTEOFF) || + (status == MIDI_CONTROLCHANGE) || (status == MIDI_POLYKEYPRESSURE)) + { + messageType = status; + byteTwo = (float) byte1; + byteThree = (float) byte2; + } + else if (status == MIDI_PITCHBEND) + { + messageType = status; + byteTwo = (float) (byte1 * NORM_7); + byteTwo += (float) byte2; + } + else + { + messageType = -1; + } + + return messageType; +} + +#endif + +void MIDIIO :: printMessage() +{ + printf("type = %d, channel = %d, byte2 = %f, byte3 = %f\n", + this->getType(), this->getChannel(), this->getByteTwo(), + this->getByteThree()); +} + +int MIDIIO :: getType() +{ + return messageType; +} + +int MIDIIO :: getChannel() +{ + return channel; +} + +MY_FLOAT MIDIIO :: getByteTwo() +{ + return byteTwo; +} + +MY_FLOAT MIDIIO :: getByteThree() +{ + return byteThree; +} + +MY_FLOAT MIDIIO :: getDeltaTime() +{ + return deltaTime; +} diff --git a/MIDIIO.h b/MIDIIO.h new file mode 100644 index 0000000..0e1ab58 --- /dev/null +++ b/MIDIIO.h @@ -0,0 +1,56 @@ +/******************************************/ +/* MIDIIO.h */ +/* Realtime MIDI I/O Object for STK, */ +/* by Gary P. Scavone, 1998. */ +/* Based in part on code by Perry */ +/* Cook (SGI), Paul Leonard (Linux), */ +/* the RoseGarden team (Linux), and */ +/* Bill Putnam (Win95/NT). */ +/* */ +/* At the moment, this object only */ +/* handles MIDI Input, though MIDI */ +/* Output code can go here when someone */ +/* decides they need it (and writes it). */ +/* */ +/* This object opens a MIDI Input device */ +/* and parses MIDI data. Time stamp */ +/* info is converted to deltaTime. */ +/* MIDI data is stored as MY_FLOAT to */ +/* conform with SKINI. */ +/******************************************/ + +#if !defined(__MIDIIO_h) +#define __MIDIIO_h + +#include "Object.h" + +class MIDIIO : public Object +{ + protected: + int messageType; + int channel; + float byteTwo; + float byteThree; + MY_FLOAT deltaTime; + public: + MIDIIO(); + ~MIDIIO(); + void printMessage(); + int nextMessage(); + int getType(); + int getChannel(); + MY_FLOAT getByteTwo(); + MY_FLOAT getByteThree(); + MY_FLOAT getDeltaTime(); +}; + +#if (defined(__WINDS_REALTIME_) || defined(__WINMM_REALTIME_) ) + +#include +#include + +static void CALLBACK midiInputCallback( HMIDIOUT hmin, UINT inputStatus, + DWORD instancePtr, DWORD midiMessage, DWORD timestamp); + +#endif +#endif diff --git a/MIDIInpt.cpp b/MIDIInpt.cpp deleted file mode 100644 index 3cc742e..0000000 --- a/MIDIInpt.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************/ -/* Simple RealTime MIDI Input Object, */ -/* by Perry R. Cook, 1996 */ -/* */ -/* This object takes MIDI from the input */ -/* , parses it, turns it into TSIDI */ -/* messages, and buffers it up for use by*/ -/* any object that asks for it later. */ -/* */ -/* TSIDI (ToolKit Synthesis Instrument */ -/* Digital Interfaceis like MIDI, but */ -/* allows for floating point control */ -/* changes, note numbers, etc. Example: */ -/* noteOn(1,60.01,111.132) plays a sharp */ -/* middle C with a velocity of 111.132 */ -/* */ -/******************************************/ - -#include "MIDIInpt.h" - -int onePending; -MDport inport; -MDevent lastEvent; - - -// void pollMessage(void *) -// { -// int status; -// while (1) { -// while (onePending == 0) { -// mdReceive(inport, &lastEvent, 1); -// status = mdGetStatus(lastEvent.msg); -// if (status==MD_NOTEON || status==MD_NOTEOFF) -// onePending = 1; -// } -// } -// } - -MIDIInpt :: MIDIInpt() -{ - int nports; - nports = mdInit(); - printf("%d MIDI devices available\n", nports); - inport = mdOpenInPort(0); - if (inport == NULL) { - printf("open failed\n"); - exit(0); - } - mdSetStampMode(inport, MD_NOSTAMP); - onePending = 0; -// midi_pid = sproc(pollMessage, PR_SALL); -// if (midi_pid == -1) -// { -// fprintf(stderr, "unable to create midi input thread...aborting.\n"); -// exit(-1); -// } -} - -#define _BSD_SIGNALS -#include - -MIDIInpt :: ~MIDIInpt() -{ - mdClosePort(inport); -// kill(midi_pid, SIGKILL); -} - -/* MIDI File Code - if (byte > 15) { - if (byte == 248) printf("MIDI Clock,"); - else if (byte == 249) printf("Undefined,"); - else if (byte == 250) printf("Song Start,"); - else if (byte == 251) printf("Continue,"); - else if (byte == 252) printf("Song Stop,"); - else if (byte == 253) printf("Undefined,"); - else if (byte == 254) printf("ActiveSen,"); - else if (byte == 255) printf("SystReset,"); - else printf("BEATSME"); - } - else { - if (byte == 8) printf("NoteOff"); - if (byte == 9) printf("NoteOn"); - if (byte == 10) printf("Poly Pressure"); - if (byte == 11) printf("Control Change"); - if (byte == 12) printf("Program Change"); - if (byte == 13) printf("Channel Pressure"); - if (byte == 14) printf("Pitch Wheel"); - } -*/ - -int MIDIInpt :: nextMessage() -{ - int status; - int byte1; - int byte2; - - messageType = -1; - - mdReceive(inport, &lastEvent, 1); - -// if (onePending == 1) { - - status = mdGetStatus(lastEvent.msg); - byte1 = mdGetByte1(lastEvent.msg); - byte2 = mdGetByte2(lastEvent.msg); - channel = mdGetChannel(lastEvent.msg); - - if (status==MD_NOTEON) { - byteTwo = (float) byte1; - byteThree = (float) byte2; - if (byte2==0) - messageType = 8; - else - messageType = 9; - } - else if (status==MD_NOTEOFF) { - byteTwo = (float) byte1; - byteThree = (float) byte2; - messageType = 8; - } - else if (status==MD_CONTROLCHANGE) { - byteTwo = (float) byte1; - byteThree = (float) byte2; - messageType = 11; - } - else if (status==MD_PROGRAMCHANGE) { - byteTwo = (float) byte1; - messageType = 12; - } - else if (status==MD_CHANNELPRESSURE) { - byteTwo = (float) byte1; - messageType = 13; - } - else if (status==MD_PITCHBENDCHANGE) { - byteTwo = (float) byte1; - byteTwo += (float) byte2 * NORM_7; - messageType = 14; - } - else { - messageType = -1; - } -// onePending = 0; - -// } - - return messageType; -} - -void MIDIInpt :: printMessage() -{ - char buffer[128]; - mdPrintEvent(buffer,&lastEvent,1); - printf(buffer); -} - -int MIDIInpt :: getType() -{ - return messageType; -} - -int MIDIInpt :: getChannel() -{ - return channel; -} - -MY_FLOAT MIDIInpt :: getByteTwo() -{ - return byteTwo; -} - -MY_FLOAT MIDIInpt :: getByteThree() -{ - return byteThree; -} - -/************ Test Main Program *****************/ -/* -void main(int argc,char *argv[]) -{ - MIDIInpt testMIDI; - - while(1) { - if (testMIDI.nextMessage() > 0) - testMIDI.printMessage(); - } -} -*/ - diff --git a/MIDIInpt.h b/MIDIInpt.h deleted file mode 100644 index 19d18ab..0000000 --- a/MIDIInpt.h +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************/ -/* Simple MIDI Text File Reader Class, */ -/* by Perry R. Cook, 1996 */ -/* This Object can open a MIDI Text File */ -/* and parse it. The file spec is mine */ -/* and mine alone, but it's all text so */ -/* you should be able to figure it out. */ -/* */ -/* TSIDI (ToolKit Synthesis Instrument */ -/* Digital Interfaceis like MIDI, but */ -/* allows for floating point control */ -/* changes, note numbers, etc. Example: */ -/* noteOn(1,60.01,111.132) plays a sharp */ -/* middle C with a velocity of 111.132 */ -/* */ -/* Warning: Obey column spacing in the */ -/* text file if you try to edit it or */ -/* create your own files. */ -/******************************************/ - -#if !defined(__MIDIInpt_h) -#define __MIDIInpt_h - -#include "Object.h" -#include "dmedia/midi.h" -#include -#include - -class MIDIInpt : public Object -{ - protected: - int midi_pid; - int messageType; - int channel; - float byteTwo; - float byteThree; - public: - MIDIInpt(); - ~MIDIInpt(); - void printMessage(); - int nextMessage(); - int getType(); - int getChannel(); - MY_FLOAT getByteTwo(); - MY_FLOAT getByteThree(); -}; - -#endif diff --git a/MIDIText.cpp b/MIDIText.cpp deleted file mode 100644 index 53cb6dd..0000000 --- a/MIDIText.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************/ -/* Simple MIDI Text File Reader Class, */ -/* by Perry R. Cook, 1996 */ -/* This Object can open a MIDI Text File */ -/* and parse it. The file spec is mine */ -/* and mine alone, but it's all text so */ -/* you should be able to figure it out. */ -/* */ -/* SKINI (Synthesis toolKit Instrument */ -/* Network Interface) is like MIDI, but */ -/* allows for floating point control */ -/* changes, note numbers, etc. Example: */ -/* noteOn 60.01 111.132 plays a sharp */ -/* middle C with a velocity of 111.132 */ -/* See SKINI.txt for more information */ -/* Warning: Obey columns in the text */ -/* file if you try to edit it or create */ -/* your own files. */ -/******************************************/ - -#include "MIDIText.h" - -MIDIText :: MIDIText(char *fileName) -{ - myFile = fopen(fileName,"r"); - this->nextMessage(); -} - -MIDIText :: ~MIDIText() -{ -} - -/* MIDI File Codes - if (byte > 15) { - if (byte == 248) printf("MIDI Clock,"); - else if (byte == 249) printf("Undefined,"); - else if (byte == 250) printf("Song Start,"); - else if (byte == 251) printf("Continue,"); - else if (byte == 252) printf("Song Stop,"); - else if (byte == 253) printf("Undefined,"); - else if (byte == 254) printf("ActiveSen,"); - else if (byte == 255) printf("SystReset,"); - else printf("BEATSME"); - } - else { // these are all nybbles of status bytes // - if (byte == 8) printf("NoteOff"); - if (byte == 9) printf("NoteOn"); - if (byte == 10) printf("Poly Pressure"); - if (byte == 11) printf("Control Change"); - if (byte == 12) printf("Program Change"); - if (byte == 13) printf("Channel Pressure"); - if (byte == 14) printf("Pitch Wheel"); - } -*/ - -int MIDIText :: nextMessage() -{ - int notDone = 1,point; - char inputString[1024]; - char tempString[32]; - - while (notDone) { - notDone = 0; - if (fgets(inputString,1000,myFile)) { - sscanf(inputString,"%s %lf %i %f %f",tempString,&deltaTime,&channel,&byteTwo,&byteThree); - point = 5; - if (tempString[0]=='%') point = 1; - if (tempString[point] == 'n') { // NoteO'n' - messageType = 9; - } - else if (inputString[point] == 'f') { // NoteO'f'f - messageType = 8; - } - else if (inputString[point] == 'B') { // Pitch'B'end - byteThree = byteTwo; - messageType = 14; - } - else if (inputString[point] == 'a') { // Progr'a'mChange - messageType = 12; - } - else if (inputString[point] == 'T') { // After'T'ouch - messageType = 11; - } - else if (inputString[point] == 'o') { // Contr'o'lChange - messageType = 11; - } - else if (inputString[0] == '/' || inputString[0] == ' ') { - notDone = 1; - } - } - else { - messageType = -1; - } - } - return messageType; -} - -int MIDIText :: getType() -{ - return messageType; -} - -int MIDIText :: getChannel() -{ - return channel; -} - -MY_FLOAT MIDIText :: getDelta() -{ - return deltaTime; -} - -MY_FLOAT MIDIText :: getByteTwo() -{ - return byteTwo; -} - -MY_FLOAT MIDIText :: getByteThree() -{ - return byteThree; -} - -/************ Test Main Program *****************/ -/* -void main(int argc,char *argv[]) -{ - MIDIText testFile(argv[1]); - - while(testFile.nextMessage() > 0) ; - -} -*/ - diff --git a/MIDIText.h b/MIDIText.h deleted file mode 100644 index 0a2aabf..0000000 --- a/MIDIText.h +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************/ -/* Simple MIDI Text File Reader Class, */ -/* by Perry R. Cook, 1996 */ -/* This Object can open a MIDI Text File */ -/* and parse it. The file spec is mine */ -/* and mine alone, but it's all text so */ -/* you should be able to figure it out. */ -/* */ -/* SKINI (Synthesis toolKit Instrument */ -/* Network Interface) is like MIDI, but */ -/* allows for floating point control */ -/* changes, note numbers, etc. Example: */ -/* noteOn 60.01 111.132 plays a sharp */ -/* middle C with a velocity of 111.132 */ -/* See SKINI.txt for more information */ -/* Warning: Obey columns in the text */ -/* file if you try to edit it or create */ -/* your own files. */ -/******************************************/ - -#if !defined(__MIDIText_h) -#define __MIDIText_h - -#include "Object.h" - -class MIDIText : public Object -{ - protected: - FILE *myFile; - int messageType; - int channel; - MY_FLOAT deltaTime; - float byteTwo; - float byteThree; - public: - MIDIText(char *fileName); - ~MIDIText(); - int nextMessage(); - int getType(); - int getChannel(); - MY_FLOAT getDelta(); - MY_FLOAT getByteTwo(); - MY_FLOAT getByteThree(); -}; - -#endif diff --git a/Makefile b/Makefile index 7760806..286e3a4 100644 --- a/Makefile +++ b/Makefile @@ -1,244 +1,65 @@ -O_FILES = Object.o Envelope.o ADSR.o Noise.o SubNoise.o RawWave.o RawLoop.o \ - NIWave1S.o Modulatr.o SingWave.o RawWvOut.o RawWvIn.o Filter.o \ - OneZero.o OnePole.o TwoZero.o TwoPole.o DCBlock.o BiQuad.o AllPass1.o \ - DLineA.o DLineL.o DLineN.o FormSwep.o BowTabl.o JetTabl.o ReedTabl.o \ - LipFilt.o Modal4.o FM4Op.o FM4Alg3.o FM4Alg4.o FM4Alg5.o FM4Alg6.o \ - FM4Alg8.o Plucked2.o SamplFlt.o Sampler.o VoicForm.o\ - MIDIText.o Reverb.o VoicMang.o \ - \ - Instrmnt.o Marimba.o Vibraphn.o AgogoBel.o Plucked.o Mandolin.o \ - Clarinet.o Flute.o Brass.o Bowed.o Rhodey.o Wurley.o TubeBell.o \ - HeavyMtl.o PercFlut.o BeeThree.o FMVoices.o Moog1.o +# STK98 Makefile - Global version for Unix systems which have GNU +# Makefile utilities installed. If this Makefile does not work on +# your system, try using the platform specific Makefiles (.sgi, +# .next, and .linux). + +OS = $(shell uname) + +O_FILES = Object.o Envelope.o ADSR.o Noise.o SubNoise.o \ + RawWave.o RawWvIn.o RawLoop.o \ + Modulatr.o Filter.o OneZero.o \ + OnePole.o TwoZero.o TwoPole.o DCBlock.o \ + BiQuad.o DLineA.o DLineL.o DLineN.o VoicMang.o \ + FormSwep.o BowTabl.o JetTabl.o ReedTabl.o \ + LipFilt.o Modal4.o FM4Op.o FM4Alg3.o FM4Alg4.o \ + FM4Alg5.o FM4Alg6.o FM4Alg8.o Plucked2.o \ + SamplFlt.o Sampler.o SKINI11.o Simple.o \ + SingWave.o VoicForm.o FMVoices.o swapstuf.o \ + \ + Instrmnt.o Marimba.o Vibraphn.o AgogoBel.o Shakers.o \ + Plucked.o Mandolin.o Clarinet.o Flute.o Moog1.o \ + Brass.o Bowed.o Rhodey.o Wurley.o TubeBell.o \ + HeavyMtl.o PercFlut.o BeeThree.o DrumSynt.o \ + \ + WvOut.o SndWvOut.o WavWvOut.o MatWvOut.o \ + Reverb.o PRCRev.o JCRev.o NRev.o RM = /bin/rm -# This is for NeXT -# CC = cc -O -# INSTR = testMono testMult DrumSynt textVoic +ifeq ($(OS),NEXTSTEP) # These are for NeXT + CC = cc -arch m68k -arch i386 -Wall + INSTR = syntmono +endif +ifeq ($(OS),IRIX) # These are for SGI + INSTR = MD2SKINI syntmono + CC = CC -O # -g -fullwarn -D__SGI_CC__ + O_FILES += RTWvOut.o RTSoundIO.o MIDIIO.o + LIBRARY = -L/usr/sgitcl/lib -laudio -lmd -lm +endif -# These are for SGI -INSTR = testTextIn testMono testMIDI testMult DrumSynt textVoic - CC = gcc -O - MEDIALINK = -lmd - TCLLIB = /usr/local/lib/libtcl.so.7.4 /usr/local/lib/libtk.so.4.0 /usr/lib/libX11.so - LIBRARY = /usr/lib/libmx.so /usr/lib/libaudio.a +ifeq ($(OS),Linux) # These are for Linux + INSTR = syntmono MD2SKINI + CC = gcc -O3 # -g -pg -O3 + O_FILES += RTWvOut.o RTSoundIO.o MIDIIO.o + LIBRARY = -lpthread -lm +endif -# .cpp.o: -# $(CC) -c $*.cpp +.SUFFIXES: .cpp +.cpp.o: Object.h + $(CC) -c $*.cpp all: $(INSTR) -testTextIn: $(LIBRARY) testTextIn.cpp $(O_FILES) MIDIInpt.o - $(CC) $(MEDIALINK) -o testTextIn testTextIn.cpp $(O_FILES) $(LIBRARY) +syntmono: syntmono.cpp $(O_FILES) + $(CC) $(INCLUDE) -o syntmono syntmono.cpp $(O_FILES) $(LIBRARY) -testMono: $(LIBRARY) testMono.cpp $(O_FILES) - $(CC) $(MEDIALINK) -o testMono testMono.cpp $(O_FILES) $(LIBRARY) - -testMIDI: $(LIBRARY) testMIDI.cpp Object.o MIDIInpt.o - $(CC) $(MEDIALINK) -o testMIDI testMIDI.cpp Object.o MIDIInpt.o $(LIBRARY) /usr/lib/libmidi.so - -testMult: $(LIBRARY) testMult.cpp $(O_FILES) - $(CC) $(MEDIALINK) -o testMult testMult.cpp $(O_FILES) $(LIBRARY) - -textVoic: $(LIBRARY) textVoic.cpp $(O_FILES) - $(CC) $(MEDIALINK) -o textVoic textVoic.cpp $(O_FILES) $(LIBRARY) - -Instrmnt.o: Instrmnt.cpp - $(CC) -c Instrmnt.cpp - -Marimba.o: Marimba.cpp - $(CC) -c Marimba.cpp - -Vibraphn.o: Vibraphn.cpp - $(CC) -c Vibraphn.cpp - -AgogoBel.o: AgogoBel.cpp - $(CC) -c AgogoBel.cpp - -Plucked.o: Plucked.cpp - $(CC) -c Plucked.cpp - -Mandolin.o: Mandolin.cpp - $(CC) -c Mandolin.cpp - -Clarinet.o: Clarinet.cpp - $(CC) -c Clarinet.cpp - -Flute.o: Flute.cpp - $(CC) -c Flute.cpp - -Brass.o: Brass.cpp - $(CC) -c Brass.cpp - -Bowed.o: Bowed.cpp - $(CC) -c Bowed.cpp - -Rhodey.o: Rhodey.cpp - $(CC) -c Rhodey.cpp - -Wurley.o: Wurley.cpp - $(CC) -c Wurley.cpp - -TubeBell.o: TubeBell.cpp - $(CC) -c TubeBell.cpp - -HeavyMtl.o: HeavyMtl.cpp - $(CC) -c HeavyMtl.cpp - -PercFlut.o: PercFlut.cpp - $(CC) -c PercFlut.cpp - -BeeThree.o: BeeThree.cpp - $(CC) -c BeeThree.cpp - -FMVoices.o: FMVoices.cpp - $(CC) -c FMVoices.cpp - -Moog1.o: Moog1.cpp - $(CC) -c Moog1.cpp - -DrumSynt: $(LIBRARY) DrumSynt.cpp $(O_FILES) - $(CC) -o DrumSynt DrumSynt.cpp $(O_FILES) $(LIBRARY) - -testVoic: $(LIBRARY) testVoic.cpp $(O_FILES) - $(CC) -o testVoic testVoic.cpp $(O_FILES) $(LIBRARY) - -# $(O_FILES) : -# $(CC) -c -o $@ $*.cpp - -Object.o : Object.cpp - $(CC) -c Object.cpp - -Envelope.o : Envelope.cpp - $(CC) -c Envelope.cpp - -ADSR.o : ADSR.cpp - $(CC) -c ADSR.cpp - -Noise.o : Noise.cpp - $(CC) -c Noise.cpp - -SubNoise.o : SubNoise.cpp - $(CC) -c SubNoise.cpp - -RawWave.o : RawWave.cpp - $(CC) -c RawWave.cpp - -RawLoop.o : RawLoop.cpp - $(CC) -c RawLoop.cpp - -NIWave1S.o : NIWave1S.cpp - $(CC) -c NIWave1S.cpp - -Modulatr.o : Modulatr.cpp - $(CC) -c Modulatr.cpp - -SingWave.o : SingWave.cpp - $(CC) -c SingWave.cpp - -RawWvOut.o : RawWvOut.cpp - $(CC) -c RawWvOut.cpp - -RawWvIn.o : RawWvIn.cpp - $(CC) -c RawWvIn.cpp - -Filter.o : Filter.cpp - $(CC) -c Filter.cpp - -OneZero.o : OneZero.cpp - $(CC) -c OneZero.cpp - -OnePole.o : OnePole.cpp - $(CC) -c OnePole.cpp - -TwoZero.o : TwoZero.cpp - $(CC) -c TwoZero.cpp - -TwoPole.o : TwoPole.cpp - $(CC) -c TwoPole.cpp - -DCBlock.o : DCBlock.cpp - $(CC) -c DCBlock.cpp - -BiQuad.o : BiQuad.cpp - $(CC) -c BiQuad.cpp - -AllPass1.o : AllPass1.cpp - $(CC) -c AllPass1.cpp - -DLineA.o : DLineA.cpp - $(CC) -c DLineA.cpp - -DLineL.o : DLineL.cpp - $(CC) -c DLineL.cpp - -DLineN.o : DLineN.cpp - $(CC) -c DLineN.cpp - -FormSwep.o : FormSwep.cpp - $(CC) -c FormSwep.cpp - -BowTabl.o : BowTabl.cpp - $(CC) -c BowTabl.cpp - -JetTabl.o : JetTabl.cpp - $(CC) -c JetTabl.cpp - -ReedTabl.o : ReedTabl.cpp - $(CC) -c ReedTabl.cpp - -LipFilt.o : LipFilt.cpp - $(CC) -c LipFilt.cpp - -Modal4.o : Modal4.cpp - $(CC) -c Modal4.cpp - -FM4Op.o : FM4Op.cpp - $(CC) -c FM4Op.cpp - -FM4Alg3.o : FM4Alg3.cpp - $(CC) -c FM4Alg3.cpp - -FM4Alg4.o : FM4Alg4.cpp - $(CC) -c FM4Alg4.cpp - -FM4Alg5.o : FM4Alg5.cpp - $(CC) -c FM4Alg5.cpp - -FM4Alg6.o : FM4Alg6.cpp - $(CC) -c FM4Alg6.cpp - -FM4Alg8.o : FM4Alg8.cpp - $(CC) -c FM4Alg8.cpp - -Plucked2.o : Plucked2.cpp - $(CC) -c Plucked2.cpp - -SamplFlt.o : SamplFlt.cpp - $(CC) -c SamplFlt.cpp - -Sampler.o : Sampler.cpp - $(CC) -c Sampler.cpp - -VoicForm.o : VoicForm.cpp - $(CC) -c VoicForm.cpp - -MIDIText.o : MIDIText.cpp - $(CC) -c MIDIText.cpp - -MIDIInpt.o : MIDIInpt.cpp - $(CC) -c MIDIInpt.cpp - -VoicMang.o : VoicMang.cpp - $(CC) -c VoicMang.cpp - -Reverb.o : Reverb.cpp - $(CC) -c Reverb.cpp +MD2SKINI: MD2SKINI.cpp $(O_FILES) + $(CC) -o MD2SKINI MD2SKINI.cpp $(O_FILES) $(LIBRARY) clean : - rm $(INSTR) rm *.o + rm $(INSTR) cleanIns : rm $(INSTR) diff --git a/Makefile.NeXT b/Makefile.NeXT new file mode 100644 index 0000000..4c9a89c --- /dev/null +++ b/Makefile.NeXT @@ -0,0 +1,47 @@ +# STK98 Makefile - NeXTStep solo version + +O_FILES = Object.o Envelope.o ADSR.o Noise.o SubNoise.o \ + RawWave.o RawWvIn.o RawLoop.o \ + Modulatr.o Filter.o OneZero.o \ + OnePole.o TwoZero.o TwoPole.o DCBlock.o \ + BiQuad.o DLineA.o DLineL.o DLineN.o VoicMang.o \ + FormSwep.o BowTabl.o JetTabl.o ReedTabl.o \ + LipFilt.o Modal4.o FM4Op.o FM4Alg3.o FM4Alg4.o \ + FM4Alg5.o FM4Alg6.o FM4Alg8.o Plucked2.o \ + SamplFlt.o Sampler.o SKINI11.o Simple.o \ + SingWave.o VoicForm.o FMVoices.o swapstuf.o \ + \ + Instrmnt.o Marimba.o Vibraphn.o AgogoBel.o Shakers.o \ + Plucked.o Mandolin.o Clarinet.o Flute.o Moog1.o \ + Brass.o Bowed.o Rhodey.o Wurley.o TubeBell.o \ + HeavyMtl.o PercFlut.o BeeThree.o DrumSynt.o \ + \ + WvOut.o SndWvOut.o WavWvOut.o MatWvOut.o \ + Reverb.o PRCRev.o JCRev.o NRev.o + +RM = /bin/rm + +CC = cc -arch m68k -arch i386 -Wall +INSTR = syntmono + +.SUFFIXES: .cpp +.cpp.o: Object.h + $(CC) -c $*.cpp + +all: $(INSTR) + +syntmono: syntmono.cpp $(O_FILES) + $(CC) $(INCLUDE) -o syntmono syntmono.cpp $(O_FILES) $(LIBRARY) + +MD2SKINI: MD2SKINI.cpp $(O_FILES) + $(CC) -o MD2SKINI MD2SKINI.cpp $(O_FILES) $(LIBRARY) + +clean : + rm *.o + rm $(INSTR) + +cleanIns : + rm $(INSTR) + +strip : + strip $(INSTR) diff --git a/Makefile.all b/Makefile.all new file mode 100644 index 0000000..286e3a4 --- /dev/null +++ b/Makefile.all @@ -0,0 +1,68 @@ +# STK98 Makefile - Global version for Unix systems which have GNU +# Makefile utilities installed. If this Makefile does not work on +# your system, try using the platform specific Makefiles (.sgi, +# .next, and .linux). + +OS = $(shell uname) + +O_FILES = Object.o Envelope.o ADSR.o Noise.o SubNoise.o \ + RawWave.o RawWvIn.o RawLoop.o \ + Modulatr.o Filter.o OneZero.o \ + OnePole.o TwoZero.o TwoPole.o DCBlock.o \ + BiQuad.o DLineA.o DLineL.o DLineN.o VoicMang.o \ + FormSwep.o BowTabl.o JetTabl.o ReedTabl.o \ + LipFilt.o Modal4.o FM4Op.o FM4Alg3.o FM4Alg4.o \ + FM4Alg5.o FM4Alg6.o FM4Alg8.o Plucked2.o \ + SamplFlt.o Sampler.o SKINI11.o Simple.o \ + SingWave.o VoicForm.o FMVoices.o swapstuf.o \ + \ + Instrmnt.o Marimba.o Vibraphn.o AgogoBel.o Shakers.o \ + Plucked.o Mandolin.o Clarinet.o Flute.o Moog1.o \ + Brass.o Bowed.o Rhodey.o Wurley.o TubeBell.o \ + HeavyMtl.o PercFlut.o BeeThree.o DrumSynt.o \ + \ + WvOut.o SndWvOut.o WavWvOut.o MatWvOut.o \ + Reverb.o PRCRev.o JCRev.o NRev.o + +RM = /bin/rm + +ifeq ($(OS),NEXTSTEP) # These are for NeXT + CC = cc -arch m68k -arch i386 -Wall + INSTR = syntmono +endif + +ifeq ($(OS),IRIX) # These are for SGI + INSTR = MD2SKINI syntmono + CC = CC -O # -g -fullwarn -D__SGI_CC__ + O_FILES += RTWvOut.o RTSoundIO.o MIDIIO.o + LIBRARY = -L/usr/sgitcl/lib -laudio -lmd -lm +endif + +ifeq ($(OS),Linux) # These are for Linux + INSTR = syntmono MD2SKINI + CC = gcc -O3 # -g -pg -O3 + O_FILES += RTWvOut.o RTSoundIO.o MIDIIO.o + LIBRARY = -lpthread -lm +endif + +.SUFFIXES: .cpp +.cpp.o: Object.h + $(CC) -c $*.cpp + +all: $(INSTR) + +syntmono: syntmono.cpp $(O_FILES) + $(CC) $(INCLUDE) -o syntmono syntmono.cpp $(O_FILES) $(LIBRARY) + +MD2SKINI: MD2SKINI.cpp $(O_FILES) + $(CC) -o MD2SKINI MD2SKINI.cpp $(O_FILES) $(LIBRARY) + +clean : + rm *.o + rm $(INSTR) + +cleanIns : + rm $(INSTR) + +strip : + strip $(INSTR) diff --git a/Makefile.linux b/Makefile.linux new file mode 100644 index 0000000..abc97ea --- /dev/null +++ b/Makefile.linux @@ -0,0 +1,49 @@ +# STK98 Makefile - Linux solo version + +O_FILES = Object.o Envelope.o ADSR.o Noise.o SubNoise.o \ + RawWave.o RawWvIn.o RawLoop.o \ + Modulatr.o Filter.o OneZero.o \ + OnePole.o TwoZero.o TwoPole.o DCBlock.o \ + BiQuad.o DLineA.o DLineL.o DLineN.o VoicMang.o \ + FormSwep.o BowTabl.o JetTabl.o ReedTabl.o \ + LipFilt.o Modal4.o FM4Op.o FM4Alg3.o FM4Alg4.o \ + FM4Alg5.o FM4Alg6.o FM4Alg8.o Plucked2.o \ + SamplFlt.o Sampler.o SKINI11.o Simple.o \ + SingWave.o VoicForm.o FMVoices.o swapstuf.o \ + \ + Instrmnt.o Marimba.o Vibraphn.o AgogoBel.o Shakers.o \ + Plucked.o Mandolin.o Clarinet.o Flute.o Moog1.o \ + Brass.o Bowed.o Rhodey.o Wurley.o TubeBell.o \ + HeavyMtl.o PercFlut.o BeeThree.o DrumSynt.o \ + \ + WvOut.o SndWvOut.o WavWvOut.o MatWvOut.o \ + Reverb.o PRCRev.o JCRev.o NRev.o \ + RTWvOut.o RTSoundIO.o MIDIIO.o + +RM = /bin/rm + +INSTR = syntmono MD2SKINI +CC = gcc -O3 # -g -pg -O3 +LIBRARY = -lpthread -lm + +.SUFFIXES: .cpp +.cpp.o: Object.h + $(CC) -c $*.cpp + +all: $(INSTR) + +syntmono: syntmono.cpp $(O_FILES) + $(CC) $(INCLUDE) -o syntmono syntmono.cpp $(O_FILES) $(LIBRARY) + +MD2SKINI: MD2SKINI.cpp $(O_FILES) + $(CC) -o MD2SKINI MD2SKINI.cpp $(O_FILES) $(LIBRARY) + +clean : + rm *.o + rm $(INSTR) + +cleanIns : + rm $(INSTR) + +strip : + strip $(INSTR) diff --git a/Makefile.sgi b/Makefile.sgi new file mode 100644 index 0000000..d519d27 --- /dev/null +++ b/Makefile.sgi @@ -0,0 +1,49 @@ +# STK98 Makefile - SGI solo version + +O_FILES = Object.o Envelope.o ADSR.o Noise.o SubNoise.o \ + RawWave.o RawWvIn.o RawLoop.o \ + Modulatr.o Filter.o OneZero.o \ + OnePole.o TwoZero.o TwoPole.o DCBlock.o \ + BiQuad.o DLineA.o DLineL.o DLineN.o VoicMang.o \ + FormSwep.o BowTabl.o JetTabl.o ReedTabl.o \ + LipFilt.o Modal4.o FM4Op.o FM4Alg3.o FM4Alg4.o \ + FM4Alg5.o FM4Alg6.o FM4Alg8.o Plucked2.o \ + SamplFlt.o Sampler.o SKINI11.o Simple.o \ + SingWave.o VoicForm.o FMVoices.o swapstuf.o \ + \ + Instrmnt.o Marimba.o Vibraphn.o AgogoBel.o Shakers.o \ + Plucked.o Mandolin.o Clarinet.o Flute.o Moog1.o \ + Brass.o Bowed.o Rhodey.o Wurley.o TubeBell.o \ + HeavyMtl.o PercFlut.o BeeThree.o DrumSynt.o \ + \ + WvOut.o SndWvOut.o WavWvOut.o MatWvOut.o \ + Reverb.o PRCRev.o JCRev.o NRev.o \ + RTWvOut.o RTSoundIO.o MIDIIO.o + +RM = /bin/rm + +INSTR = MD2SKINI syntmono +CC = CC -O # -g -fullwarn -D__SGI_CC__ +LIBRARY = -L/usr/sgitcl/lib -laudio -lmd -lm + +.SUFFIXES: .cpp +.cpp.o: Object.h + $(CC) -c $*.cpp + +all: $(INSTR) + +syntmono: syntmono.cpp $(O_FILES) + $(CC) $(INCLUDE) -o syntmono syntmono.cpp $(O_FILES) $(LIBRARY) + +MD2SKINI: MD2SKINI.cpp $(O_FILES) + $(CC) -o MD2SKINI MD2SKINI.cpp $(O_FILES) $(LIBRARY) + +clean : + rm *.o + rm $(INSTR) + +cleanIns : + rm $(INSTR) + +strip : + strip $(INSTR) diff --git a/Mandolin.cpp b/Mandolin.cpp index e1cfdc4..d69ec54 100644 --- a/Mandolin.cpp +++ b/Mandolin.cpp @@ -4,8 +4,8 @@ /* by Perry Cook, 1995-96 */ /* Controls: CONTROL1 = bodySize */ /* CONTROL2 = pluckPosition */ -/* CONTROL3 = loopGain */ -/* MOD_WHEEL= deTuning */ +/* CONTROL3 = loopGain */ +/* MOD_WHEEL= deTuning */ /* */ /* Note: Commuted Synthesis, as with many */ /* other WaveGuide techniques, is covered */ @@ -17,24 +17,46 @@ /********************************************/ #include "Mandolin.h" +#include "SKINI11.msg" Mandolin :: Mandolin(MY_FLOAT lowestFreq) : Plucked2(lowestFreq) { - soundfile = new RawWave("rawwaves/mandpluk.raw"); - soundfile->normalize(0.05); /* Empirical hack here */ - soundfile->setLooping(0); + int i; + + soundfile[0] = new RawWave("rawwaves/mand1.raw"); + soundfile[1] = new RawWave("rawwaves/mand2.raw"); + soundfile[2] = new RawWave("rawwaves/mand3.raw"); + soundfile[3] = new RawWave("rawwaves/mand4.raw"); + soundfile[4] = new RawWave("rawwaves/mand5.raw"); + soundfile[5] = new RawWave("rawwaves/mand6.raw"); + soundfile[6] = new RawWave("rawwaves/mand7.raw"); + soundfile[7] = new RawWave("rawwaves/mand8.raw"); + soundfile[8] = new RawWave("rawwaves/mand9.raw"); + soundfile[9] = new RawWave("rawwaves/mand10.raw"); + soundfile[10] = new RawWave("rawwaves/mand11.raw"); + soundfile[11] = new RawWave("rawwaves/mand12.raw"); + for (i=0;i<12;i++) { +// soundfile[i]->normalize((MY_FLOAT) 0.1); /* Empirical hack here */ + soundfile[i]->setLooping(0); + } + directBody = 1.0; + mic = 0; dampTime = 0; waveDone = 1; } +Mandolin :: ~Mandolin() +{ +} + void Mandolin :: pluck(MY_FLOAT amplitude) { /* this function gets interesting here, */ - soundfile->reset(); /* because pluck may be longer than */ + soundfile[mic]->reset(); /* because pluck may be longer than */ pluckAmp = amplitude; /* string length, so we just reset the */ /* soundfile and add in the pluck in */ /* the tick method. */ combDelay->setDelay( - 0.5 * pluckPos * lastLength); /* Set Pick Position */ + (MY_FLOAT) 0.5 * pluckPos * lastLength); /* Set Pick Position */ /* which puts zeroes at pos*length */ dampTime = (long) lastLength; /* See tick method below */ waveDone = 0; @@ -57,15 +79,18 @@ void Mandolin :: noteOn(MY_FLOAT freq, MY_FLOAT amp) void Mandolin :: setBodySize(MY_FLOAT size) { - soundfile->setRate(size); + int i; + for (i=0;i<12;i++) { + soundfile[i]->setRate(size); + } } MY_FLOAT Mandolin :: tick() { - MY_FLOAT temp = 0; + MY_FLOAT temp = (MY_FLOAT) 0; if (!waveDone) { - waveDone = soundfile->informTick(); /* as long as it goes . . . */ - temp = soundfile->lastOut() * pluckAmp; /* scaled pluck excitation */ + waveDone = soundfile[mic]->informTick(); /* as long as it goes . . . */ + temp = soundfile[mic]->lastOut() * pluckAmp; /* scaled pluck excitation */ temp = temp - combDelay->tick(temp); /* with comb filtering */ } if (dampTime>=0) { /* Damping hack to help avoid */ @@ -73,11 +98,11 @@ MY_FLOAT Mandolin :: tick() lastOutput = delayLine->tick( /* Calculate 1st delay */ filter->tick( /* filterered reflection */ temp + /* plus pluck excitation */ - (delayLine->lastOut() * 0.7))); + (delayLine->lastOut() * (MY_FLOAT) 0.7))); lastOutput += delayLine2->tick( /* and 2nd delay */ filter2->tick( /* just like the 1st */ temp + - (delayLine2->lastOut() * 0.7))); /* that's the whole thing!! */ + (delayLine2->lastOut() * (MY_FLOAT) 0.7))); /* that's the whole thing!! */ } else { /* No damping hack after 1 period */ lastOutput = delayLine->tick( /* Calculate 1st delay */ @@ -91,7 +116,7 @@ MY_FLOAT Mandolin :: tick() (delayLine2->lastOut() * loopGain))); } - lastOutput *= 2.0; + lastOutput *= (MY_FLOAT) 0.3 / 32768.0; return lastOutput; } @@ -100,17 +125,20 @@ void Mandolin :: controlChange(int number, MY_FLOAT value) #if defined(_debug_) printf("Mandolin : ControlChange: Number=%i Value=%f\n",number,value); #endif - if (number == MIDI_control1) - this->setBodySize(value * NORM_7 * 2.0); - else if (number == MIDI_control2) - this->setPluckPos(value * NORM_7); - else if (number == MIDI_control3) - this->setBaseLoopGain(0.97 + (value * NORM_7 * 0.03)); - else if (number == MIDI_mod_wheel) - this->setDetune(1.0 - (value * NORM_7 * 0.1)); - else if (number == MIDI_after_touch) - this->pluck(value * NORM_7); + if (number == __SK_BodySize_) + this->setBodySize(value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 2.0); + else if (number == __SK_PickPosition_) + this->setPluckPos(value * (MY_FLOAT) NORM_7); + else if (number == __SK_StringDamping_) + this->setBaseLoopGain((MY_FLOAT) 0.97 + (value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.03)); + else if (number == __SK_StringDetune_) + this->setDetune((MY_FLOAT) 1.0 - (value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.1)); + else if (number == __SK_AfterTouch_) + this->pluck(value * (MY_FLOAT) NORM_7); + else if (number == 411) { + mic = (int) value % 12; + } else { - printf("Mandolin : Undefined Control Number!!\n"); + printf("Mandolin : Undefined Control Number!! %i\n",number); } } diff --git a/Mandolin.h b/Mandolin.h index 77b1d4f..86a46e6 100644 --- a/Mandolin.h +++ b/Mandolin.h @@ -25,11 +25,14 @@ class Mandolin : public Plucked2 { protected: - RawWave *soundfile; + RawWave *soundfile[12]; + MY_FLOAT directBody; + int mic; long dampTime; int waveDone; public: Mandolin(MY_FLOAT lowestFreq); + virtual ~Mandolin(); void pluck(MY_FLOAT amplitude); void pluck(MY_FLOAT amplitude,MY_FLOAT position); virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); diff --git a/Marimba.cpp b/Marimba.cpp index cfa97d1..7146fb6 100644 --- a/Marimba.cpp +++ b/Marimba.cpp @@ -9,33 +9,35 @@ /*******************************************/ #include "Marimba.h" +#include "SKINI11.msg" Marimba :: Marimba() : Modal4() { wave = new RawWave("rawwaves/marmstk1.raw"); wave->normalize(); - wave->setRate(0.5); /* normal stick */ - this->setRatioAndReson(0, 1.00,0.9996); /* Set all 132.0 */ - this->setRatioAndReson(1, 3.99,0.9994); /* of our 523.0 */ - this->setRatioAndReson(2,10.65,0.9994); /* default 1405.0 */ - this->setRatioAndReson(3,-18.50,0.999); /* resonances 2443.0 */ - this->setFiltGain(0,0.08); /* and */ - this->setFiltGain(1,0.02); /* gains */ - this->setFiltGain(2,0.02); /* for each */ - this->setFiltGain(3,0.015); /* resonance */ - directGain = 0.1; + wave->setRate((MY_FLOAT) 0.5); /* normal stick */ + this->setRatioAndReson(0, (MY_FLOAT) 1.00,(MY_FLOAT) 0.9996); /* Set all 132.0 */ + this->setRatioAndReson(1, (MY_FLOAT) 3.99,(MY_FLOAT) 0.9994); /* of our 523.0 */ + this->setRatioAndReson(2,(MY_FLOAT) 10.65,(MY_FLOAT) 0.9994); /* default 1405.0 */ + this->setRatioAndReson(3,-(MY_FLOAT) 2443.0,(MY_FLOAT) 0.999); /* resonances 2443.0 */ + this->setFiltGain(0,(MY_FLOAT) 0.04); /* and */ + this->setFiltGain(1,(MY_FLOAT) 0.01); /* gains */ + this->setFiltGain(2,(MY_FLOAT) 0.01); /* for each */ + this->setFiltGain(3,(MY_FLOAT) 0.008); /* resonance */ + directGain = (MY_FLOAT) 0.1; multiStrike = 0; } Marimba :: ~Marimba() { + delete wave; } void Marimba :: setStickHardness(MY_FLOAT hardness) { stickHardness = hardness; - wave->setRate(0.25 * pow(4.0,stickHardness)); - masterGain = 0.1 + (1.8 * stickHardness); + wave->setRate((MY_FLOAT) (0.25 * (MY_FLOAT) pow(4.0,stickHardness))); + masterGain = (MY_FLOAT) 0.1 + ((MY_FLOAT) 1.8 * stickHardness); } void Marimba :: setStrikePosition(MY_FLOAT position) @@ -43,12 +45,12 @@ void Marimba :: setStrikePosition(MY_FLOAT position) MY_FLOAT temp,temp2; temp2 = position * PI; strikePosition = position; /* Hack only first three modes */ - temp = sin(temp2); - this->setFiltGain(0,0.12 * temp); /* 1st mode function of pos. */ - temp = sin(0.05 + (3.9 * temp2)); - this->setFiltGain(1,-0.03 * temp); /* 2nd mode function of pos. */ - temp = sin(-0.05 + (11 * temp2)); - this->setFiltGain(2,0.11 * temp); /* 3rd mode function of pos. */ + temp = (MY_FLOAT) sin(temp2); + this->setFiltGain(0,(MY_FLOAT) 0.12 * temp); /* 1st mode function of pos. */ + temp = (MY_FLOAT) sin(0.05 + (3.9 * temp2)); + this->setFiltGain(1,(MY_FLOAT) -0.03 * temp); /* 2nd mode function of pos. */ + temp = (MY_FLOAT) sin(-0.05 + (11 * temp2)); + this->setFiltGain(2,(MY_FLOAT) 0.11 * temp); /* 3rd mode function of pos. */ } void Marimba :: setModulationSpeed(MY_FLOAT mSpeed) @@ -63,7 +65,7 @@ void Marimba :: setModulationDepth(MY_FLOAT mDepth) void Marimba :: strike(MY_FLOAT amplitude) { int temp; - temp = random() >> 26; + temp = rand() >> 10; if (temp < 2) { multiStrike = 1; #if defined(_debug_) @@ -85,15 +87,15 @@ void Marimba :: controlChange(int number, MY_FLOAT value) #if defined(_debug_) printf("Marimba : ControlChange: Number=%i Value=%f\n",number,value); #endif - if (number == MIDI_control1) + if (number == __SK_StickHardness_) this->setStickHardness(value * NORM_7); - else if (number == MIDI_control2) + else if (number == __SK_StrikePosition_) this->setStrikePosition(value * NORM_7); - else if (number == MIDI_control3) - vibr->setFreq((value * NORM_7 * 12.0)); - else if (number == MIDI_mod_wheel) - vibrGain = (value * NORM_7); - else if (number == MIDI_after_touch) + else if (number == __SK_ModFrequency_) + vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0)); + else if (number == __SK_ModWheel_) + vibrGain = (value * NORM_7); + else if (number == __SK_AfterTouch_Cont_) this->strike(value * NORM_7); else { printf("Marimba : Undefined Control Number!!\n"); diff --git a/MatWvOut.cpp b/MatWvOut.cpp new file mode 100644 index 0000000..d10a946 --- /dev/null +++ b/MatWvOut.cpp @@ -0,0 +1,214 @@ +/*******************************************/ +/* Matlab MAT File Output Class, */ +/* by Gary P. Scavone, 1998. */ +/* This object creates a Matlab MAT-file */ +/* structure and fills it with buffers of */ +/* samples (doubles). */ +/* */ +/* The Matlab MAT-file format is not */ +/* available to the general public. I */ +/* spent several days reverse-engineering */ +/* the file format to create this class. */ +/* I couldn't figure out what a few of */ +/* the header fields correspond to, but */ +/* for the purposes of STK, this */ +/* shouldn't create any problems. */ +/*******************************************/ + +#include "MatWvOut.h" + +/******** Matlab Matfile Header Struct *******/ +struct matheaderform { + char heading[124]; + short a[2]; + long b[10]; + /* There's more, but it's of variable length */ +}; + +FILE *openMatFile(int chans,char *fileName) { + struct matheaderform hdr; + FILE *fd; + char tempName[128]; + int i, namelen; + long longtmp, headsize; + + strcpy(hdr.heading,"MATLAB 5.0 MAT-file, Generated by STK98. This file format was hacked by Gary P. Scavone, CCRMA, Stanford University, 1998."); + + for (i=strlen(hdr.heading);i<124;i++) hdr.heading[i] = ' '; + + hdr.a[0] = (short) 256; + hdr.a[1] = (short) 'M'; + hdr.a[1] <<= 8; + hdr.a[1] += 'I'; + hdr.b[0] = (long) 14; + hdr.b[1] = (long) 0; /* Size of file after this point to end (in bytes) */ + hdr.b[2] = (long) 6; + hdr.b[3] = (long) 8; + hdr.b[4] = (long) 6; + hdr.b[5] = (long) 0; + hdr.b[6] = (long) 5; + hdr.b[7] = (long) 8; + hdr.b[8] = (long) chans; /* This is the number of rows */ + hdr.b[9] = (long) 0; /* This is the number of columns */ + + strcpy(tempName,fileName); + strcat(tempName,".mat"); + + fd = fopen(tempName,"w+b"); + if (!fd) { + printf("Couldn't create matfile %s !!!!!!!!\n",fileName); + exit(0); + } + + printf("Creating matfile %s.\n", tempName); + fwrite(&hdr,sizeof(char),168,fd); /* Write the fixed portion of the header */ + + /* The next 4 bytes can be viewed as two shorts, but they are byteswapped + as a long. The first short value seems to always be one; the second + short will be the length of the variable name IF IT IS <= 4; if the + variable name length is >4, this short is zero and the length is put + in the next 4 bytes. The variable name length is limited to 31 + characters (32 with a '\n'). The actual variable name then follows. + The variable name is "zero-padded" out to the following minimum + lengths (in bits): 4, 8, 16, 24, 32. + */ + namelen = strlen(fileName); + if (namelen > 31) { /* Check length of variable name (file name) */ + fprintf(stderr, "File name too long ... should be 31 characters or less.\n"); + fclose(fd); + exit(0); + } + + if (namelen > 4) { + longtmp = 1; + fwrite(&longtmp,sizeof(long),1,fd); + fwrite(&namelen,sizeof(long),1,fd); + headsize = 44 + namelen; + } else { + longtmp = namelen; + longtmp <<= 16; + longtmp += 1; + fwrite(&longtmp,sizeof(long),1,fd); + headsize = 40 + namelen; + } + + fwrite(fileName,sizeof(char),namelen,fd); /* Write the variable (file) name */ + if (namelen < 5) + longtmp = 4 - namelen; + else if (namelen < 9) + longtmp = 8 - namelen; + else if (namelen < 17) + longtmp = 16 - namelen; + else if (namelen < 25) + longtmp = 24 - namelen; + else longtmp = 32 - namelen; + + headsize += longtmp + 8; /* Add length (8) of following bytes */ + fseek(fd,longtmp,SEEK_CUR); + + longtmp = 9; + fwrite(&longtmp,sizeof(long),1,fd); + longtmp = 0; /* Size of data in bytes (8 per sample) */ + fwrite(&longtmp,sizeof(long),1,fd); + + fseek(fd,132,SEEK_SET); + fwrite(&headsize,sizeof(long),1,fd); /* Write header size ... will update at end */ + fseek(fd,0,SEEK_END); + + return fd; +} + +MatWvOut :: MatWvOut(char *fileName) +{ + chans = 1; + pan = 0.5; + fd = openMatFile(chans,fileName); + counter = 0; + totalCount = 0; +} + +MatWvOut :: MatWvOut(int channels, char *fileName) +{ + chans = channels; + pan = 0.5; + fd = openMatFile(chans,fileName); + counter = 0; + totalCount = 0; +} + +MatWvOut :: ~MatWvOut() +{ + double temp; + long headsize, temp1; + + fwrite(data,sizeof(double),counter,fd); + temp = (double) totalCount * ONE_OVER_SRATE; + printf("%f Seconds Computed\n",temp); + fseek(fd,164,SEEK_SET); + fwrite(&totalCount,sizeof(long),1,fd); /* Write number of columns */ + fseek(fd,132,SEEK_SET); + fread(&headsize,sizeof(long),1,fd); + temp1 = headsize; + headsize += (long) (totalCount * 8 * 2); + fseek(fd,132,SEEK_SET); + fwrite(&headsize,sizeof(long),1,fd); /* Write file size (minus some header info) */ + fseek(fd,temp1+128,SEEK_SET); + temp1 = totalCount * 8 * 2; + fwrite(&temp1,sizeof(long),1,fd); /* Write data size (in bytes) */ + fclose(fd); +} + +long MatWvOut :: getCounter() +{ + return totalCount; +} + +MY_FLOAT MatWvOut :: getTime() +{ + return (MY_FLOAT) totalCount * ONE_OVER_SRATE; +} + +void MatWvOut :: tick(MY_FLOAT sample) +{ + if (chans==1) { + data[counter++] = (double) (sample); + } + else { + data[counter++] = (double) (sample * (1.0 - pan)); + data[counter++] = (double) (sample * pan); + } + totalCount += 1; + if (counter == MAT_BUFFER_SIZE) { + fwrite(data,sizeof(double),MAT_BUFFER_SIZE,fd); + counter = 0; + } +} + +void MatWvOut :: tick(MY_FLOAT lsamp, MY_FLOAT rsamp) +{ + if (chans==1) { + data[counter++] = (double) (lsamp + rsamp); + } + else { + data[counter++] = (double) (lsamp); + data[counter++] = (double) (rsamp); + } + totalCount += 1; + if (counter == MAT_BUFFER_SIZE) { + fwrite(data,sizeof(double),MAT_BUFFER_SIZE,fd); + counter = 0; + } +} + +void MatWvOut :: setMonoPan(MY_FLOAT aPan) +{ + pan = aPan; + if (aPan < 0.0) { + pan = 0.0; + printf("Pan < 0.0, correcting to 0.0\n"); + } + if (aPan > 1.0) { + pan = 1.0; + printf("Pan > 1.0, correcting to 1.0\n"); + } +} diff --git a/MatWvOut.h b/MatWvOut.h new file mode 100644 index 0000000..643c517 --- /dev/null +++ b/MatWvOut.h @@ -0,0 +1,46 @@ +/*******************************************/ +/* Matlab MAT File Output Class, */ +/* by Gary P. Scavone, 1998. */ +/* This object creates a Matlab MAT-file */ +/* structure and fills it with buffers of */ +/* samples (doubles). */ +/* */ +/* The Matlab MAT-file format is not */ +/* available to the general public. I */ +/* spent several days reverse-engineering */ +/* the file format to create this class. */ +/* I couldn't figure out what a few of */ +/* the header fields correspond to, but */ +/* for the purposes of STK, this */ +/* shouldn't create any problems. */ +/*******************************************/ + +#include "Object.h" +#include "WvOut.h" + +#if !defined(__MatWvOut_h) +#define __MatWvOut_h + +#define MAT_BUFFER_SIZE 1024 + +class MatWvOut : public WvOut +{ + protected: + FILE *fd; + double data[MAT_BUFFER_SIZE]; /* not MY_FLOAT because MAT uses doubles */ + long counter; + long totalCount; + int chans; + MY_FLOAT pan; + public: + MatWvOut(char *infileName); + MatWvOut(int channels, char *infileName); + ~MatWvOut(); + long getCounter(); + MY_FLOAT getTime(); + void setMonoPan(MY_FLOAT aPan); + void tick(MY_FLOAT sample); + void tick(MY_FLOAT lsamp, MY_FLOAT rsamp); +}; + +#endif // defined(__MatWvOut_h) diff --git a/Modal4.cpp b/Modal4.cpp index 1ddd19e..06c160e 100644 --- a/Modal4.cpp +++ b/Modal4.cpp @@ -21,33 +21,32 @@ Modal4 :: Modal4() vibr = new RawLoop("rawwaves/sinewave.raw"); vibr->normalize(); - vibr->setFreq(6.0); - vibrGain = 0.05; + vibr->setFreq((MY_FLOAT) 6.0); + vibrGain = (MY_FLOAT) 0.05; - directGain = 0.0; - masterGain = 1.0; - baseFreq = 440.0; - this->setRatioAndReson(0,1.00,0.9997); /* Set some */ - this->setRatioAndReson(1,1.30,0.9997); /* silly */ - this->setRatioAndReson(2,1.77,0.9997); /* default */ - this->setRatioAndReson(3,2.37,0.9997); /* values here */ - this->setFiltGain(0,0.01); - this->setFiltGain(1,0.01); - this->setFiltGain(2,0.01); - this->setFiltGain(3,0.01); + directGain = (MY_FLOAT) 0.0; + masterGain = (MY_FLOAT) 1.0; + baseFreq = (MY_FLOAT) 440.0; + this->setRatioAndReson(0,(MY_FLOAT) 1.00,(MY_FLOAT) 0.9997); /* Set some */ + this->setRatioAndReson(1,(MY_FLOAT) 1.30,(MY_FLOAT) 0.9997); /* silly */ + this->setRatioAndReson(2,(MY_FLOAT) 1.77,(MY_FLOAT) 0.9997); /* default */ + this->setRatioAndReson(3,(MY_FLOAT) 2.37,(MY_FLOAT) 0.9997); /* values here */ + this->setFiltGain(0,(MY_FLOAT) 0.01); + this->setFiltGain(1,(MY_FLOAT) 0.01); + this->setFiltGain(2,(MY_FLOAT) 0.01); + this->setFiltGain(3,(MY_FLOAT) 0.01); this->clear(); filters[0]->setEqualGainZeroes(); filters[1]->setEqualGainZeroes(); filters[2]->setEqualGainZeroes(); filters[3]->setEqualGainZeroes(); - stickHardness = 0.5; - strikePosition = 0.561; + stickHardness = (MY_FLOAT) 0.5; + strikePosition = (MY_FLOAT) 0.561; } Modal4 :: ~Modal4() { delete envelope; - delete wave; delete filters[0]; delete filters[1]; delete filters[2]; @@ -84,7 +83,7 @@ void Modal4 :: setRatioAndReson(int whichOne, MY_FLOAT ratio,MY_FLOAT reson) } else { temp = ratio; - while (temp*baseFreq > SRATE_OVER_TWO) temp *= 0.5; + while (temp*baseFreq > SRATE_OVER_TWO) temp *= (MY_FLOAT) 0.5; ratios[whichOne] = temp; #if defined(_debug_) printf("Modal4 : Aliasing would occur here, correcting.\n"); @@ -117,9 +116,9 @@ void Modal4 :: strike(MY_FLOAT amplitude) { int i; MY_FLOAT temp; - envelope->setRate(1.0); + envelope->setRate((MY_FLOAT) 1.0); envelope->setTarget(amplitude); - onepole->setPole(1.0 - amplitude); + onepole->setPole((MY_FLOAT) 1.0 - amplitude); envelope->tick(); wave->reset(); for (i=0;i<4;i++) { @@ -142,7 +141,7 @@ void Modal4 :: noteOn(MY_FLOAT freq, MY_FLOAT amp) void Modal4 :: noteOff(MY_FLOAT amp) /* This calls damp, but inverts the */ { /* meaning of amplitude. */ - this->damp(1.0 - (amp * 0.03)); /* (high amplitude means fast damping) */ + this->damp((MY_FLOAT) 1.0 - (amp * (MY_FLOAT) 0.03)); /* (high amplitude means fast damping) */ #if defined(_debug_) printf("Modal4 : NoteOff: Amp=%lf\n",amp); #endif @@ -177,11 +176,11 @@ MY_FLOAT Modal4 :: tick() temp2 += directGain * temp; if (vibrGain != 0.0) { - temp = 1.0 + (vibr->tick() * vibrGain); /* Calculate AM */ + temp = (MY_FLOAT) 1.0 + (vibr->tick() * vibrGain); /* Calculate AM */ temp2 = temp * temp2; /* and apply to master out */ } - lastOutput = temp2 * 2.0; + lastOutput = temp2 * (MY_FLOAT) 2.0; return lastOutput; } diff --git a/Modal4.h b/Modal4.h index 5b6a54a..c684759 100644 --- a/Modal4.h +++ b/Modal4.h @@ -34,7 +34,7 @@ class Modal4 : public Instrmnt MY_FLOAT resons[4]; public: Modal4(); - ~Modal4(); + virtual ~Modal4(); void clear(); virtual void setFreq(MY_FLOAT frequency); void setRatioAndReson(int whichOne, MY_FLOAT ratio, MY_FLOAT reson); diff --git a/Modulatr.cpp b/Modulatr.cpp index 1cbcdfe..9c122df 100644 --- a/Modulatr.cpp +++ b/Modulatr.cpp @@ -5,20 +5,19 @@ /* natural human modulation function. */ /*******************************************/ -#define POLE_POS 0.999 -#define RND_SCALE 10.0 +#define POLE_POS (MY_FLOAT) 0.999 +#define RND_SCALE (MY_FLOAT) 10.0 #include "Modulatr.h" Modulatr :: Modulatr() { - vibwave = new RawWave("rawwaves/sinewave.raw"); + vibwave = new RawLoop("rawwaves/sinewave.raw"); vibwave->normalize(); - vibwave->setFreq(6.0); - vibwave->setLooping(1); - vibAmt = 0.04; + vibwave->setFreq((MY_FLOAT) 6.0); + vibAmt = (MY_FLOAT) 0.04; noise = new SubNoise(330); - rndAmt = 0.005; + rndAmt = (MY_FLOAT) 0.005; onepole = new OnePole; onepole->setPole(POLE_POS); onepole->setGain(rndAmt * RND_SCALE); @@ -33,33 +32,33 @@ Modulatr :: ~Modulatr() void Modulatr :: reset() { - lastOutput = 0.0; + lastOutput = (MY_FLOAT) 0.0; } -void Modulatr :: setVibFreq(double vibFreq) +void Modulatr :: setVibFreq(MY_FLOAT vibFreq) { vibwave->setFreq(vibFreq); } -void Modulatr :: setVibAmt(double vibAmount) +void Modulatr :: setVibAmt(MY_FLOAT vibAmount) { vibAmt = vibAmount; } -void Modulatr :: setRndAmt(double rndAmount) +void Modulatr :: setRndAmt(MY_FLOAT rndAmount) { rndAmt = rndAmount; onepole->setGain(RND_SCALE * rndAmt); } -double Modulatr :: tick() +MY_FLOAT Modulatr :: tick() { lastOutput = vibAmt * vibwave->tick(); /* Compute periodic and */ lastOutput += onepole->tick(noise->tick()); /* random modulations */ return lastOutput; } -double Modulatr :: lastOut() +MY_FLOAT Modulatr :: lastOut() { return lastOutput; } diff --git a/Modulatr.h b/Modulatr.h index a454754..9c4d6d8 100644 --- a/Modulatr.h +++ b/Modulatr.h @@ -9,28 +9,28 @@ #define __Modulatr_h #include "Object.h" -#include "RawWave.h" +#include "RawLoop.h" #include "SubNoise.h" #include "OnePole.h" class Modulatr : public Object { protected: - RawWave *vibwave; + RawLoop *vibwave; SubNoise *noise; OnePole *onepole; - double vibAmt; - double rndAmt; - double lastOutput; + MY_FLOAT vibAmt; + MY_FLOAT rndAmt; + MY_FLOAT lastOutput; public: Modulatr(); ~Modulatr(); void reset(); - void setVibFreq(double vibFreq); - void setVibAmt(double vibAmount); - void setRndAmt(double rndAmount); - double tick(); - double lastOut(); + void setVibFreq(MY_FLOAT vibFreq); + void setVibAmt(MY_FLOAT vibAmount); + void setRndAmt(MY_FLOAT rndAmount); + MY_FLOAT tick(); + MY_FLOAT lastOut(); }; #endif diff --git a/Moog1.cpp b/Moog1.cpp index ce8905b..01b9c9b 100644 --- a/Moog1.cpp +++ b/Moog1.cpp @@ -10,22 +10,21 @@ /******************************************/ #include "Moog1.h" +#include "SKINI11.msg" Moog1 :: Moog1() : SamplFlt() { attacks[0] = new RawWave("rawwaves/mandpluk.raw"); - loops[0] = new RawWave("rawwaves/impuls20.raw"); - loops[1] = new RawWave("rawwaves/sinewave.raw"); /* Steal one for vibrato */ + loops[0] = new RawLoop("rawwaves/impuls20.raw"); + loops[1] = new RawLoop("rawwaves/sinewave.raw"); /* Steal one for vibrato */ attacks[0]->normalize(); loops[0]->normalize(); - loops[0]->setLooping(1); loops[1]->normalize(); - loops[1]->setLooping(1); - loops[1]->setFreq(6.122); - adsr->setAll(0.05,0.00003,0.6,0.0002); - filterQ = 0.85; - filterRate = 0.0001; - modDepth = 0.0; + loops[1]->setFreq((MY_FLOAT) 6.122); + adsr->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.5,(MY_FLOAT) 0.6,(MY_FLOAT) 0.250); + filterQ = (MY_FLOAT) 0.85; + filterRate = (MY_FLOAT) 0.0001; + modDepth = (MY_FLOAT) 0.0; } Moog1 :: ~Moog1() @@ -38,7 +37,7 @@ Moog1 :: ~Moog1() void Moog1 :: setFreq(MY_FLOAT frequency) { baseFreq = frequency; - attacks[0]->setFreq(baseFreq * 0.01); + attacks[0]->setFreq(baseFreq * (MY_FLOAT) 0.01); loops[0]->setFreq(baseFreq); } @@ -48,17 +47,17 @@ void Moog1 :: noteOn(MY_FLOAT freq, MY_FLOAT amp) this->setFreq(freq); this->keyOn(); - attackGain = amp * 0.5; + attackGain = amp * (MY_FLOAT) 0.5; loopGain = amp; - temp = filterQ+0.05; - filters[0]->setStates(2000,temp,2.0 * (1.0 - temp)); - filters[1]->setStates(2000,temp,2.0 * (1.0 - temp)); - temp = filterQ+0.099; - filters[0]->setTargets( 0,temp,2.0 * (1.0 - temp)); - filters[1]->setTargets( 0,temp,2.0 * (1.0 - temp)); - filters[0]->setSweepRate(filterRate * RATE_NORM); - filters[1]->setSweepRate(filterRate * RATE_NORM); + temp = filterQ + (MY_FLOAT) 0.05; + filters[0]->setStates((MY_FLOAT) 2000.0,temp,(MY_FLOAT) 2.0 * ((MY_FLOAT) 1.0 - temp)); + filters[1]->setStates((MY_FLOAT) 2000.0,temp,(MY_FLOAT) 2.0 * ((MY_FLOAT) 1.0 - temp)); + temp = filterQ + (MY_FLOAT) 0.099; + filters[0]->setTargets((MY_FLOAT) freq,temp,(MY_FLOAT) 2.0 * ((MY_FLOAT) 1.0 - temp)); + filters[1]->setTargets((MY_FLOAT) freq,temp,(MY_FLOAT) 2.0 * ((MY_FLOAT) 1.0 - temp)); + filters[0]->setSweepRate(filterRate * (MY_FLOAT) 22050.0 / SRATE); + filters[1]->setSweepRate(filterRate * (MY_FLOAT) 22050.0 / SRATE); #if defined(_debug_) printf("Moog1 : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); #endif @@ -71,7 +70,7 @@ void Moog1 :: setModulationSpeed(MY_FLOAT mSpeed) void Moog1 :: setModulationDepth(MY_FLOAT mDepth) { - modDepth = mDepth * 0.5; + modDepth = mDepth * (MY_FLOAT) 0.5; } void Moog1 :: controlChange(int number, MY_FLOAT value) @@ -79,15 +78,15 @@ void Moog1 :: controlChange(int number, MY_FLOAT value) #if defined(_debug_) printf("Moog1 : ControlChange: Number=%i Value=%f\n",number,value); #endif - if (number == MIDI_control1) - filterQ = 0.80 + (0.1 * value * NORM_7); - else if (number == MIDI_control2) - filterRate = (value * NORM_7 * 0.0002); - else if (number == MIDI_control3) - this->setModulationSpeed(value * NORM_7 * 12.0); - else if (number == MIDI_mod_wheel) + if (number == __SK_FilterQ_) + filterQ = (MY_FLOAT) 0.80 + ((MY_FLOAT) 0.1 * value * NORM_7); + else if (number == __SK_FilterSweepRate_) + filterRate = (value * NORM_7 * (MY_FLOAT) 0.0002); + else if (number == __SK_ModFrequency_) + this->setModulationSpeed(value * NORM_7 * (MY_FLOAT) 12.0); + else if (number == __SK_ModWheel_) this->setModulationDepth(value * NORM_7); - else if (number == MIDI_after_touch) + else if (number == __SK_AfterTouch_Cont_) adsr->setTarget(value * NORM_7); else { printf("Moog1 : Undefined Control Number!!\n"); @@ -100,7 +99,7 @@ MY_FLOAT Moog1 :: tick() if (modDepth!=0.0) { temp = loops[1]->tick() * modDepth; - loops[0]->setFreq(baseFreq * (1.0 + temp)); + loops[0]->setFreq(baseFreq * ((MY_FLOAT) 1.0 + temp)); } lastOutput = SamplFlt :: tick(); return lastOutput; diff --git a/NIFileIn.cpp b/NIFileIn.cpp deleted file mode 100644 index 80a1643..0000000 --- a/NIFileIn.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/*******************************************/ -/* NonInterpolating One-Shot Raw Sound- */ -/* file Class, by Perry R. Cook, 1995-96 */ -/* This Object can open a raw 16bit data */ -/* (signed integers) file, and play back */ -/* the data once, with no interpolation */ -/* on playback. Once finished, it closes */ -/* the file, the file is reopened with */ -/* the reset() method. */ -/* This is useful for small memory model, */ -/* applications, or for streaming from */ -/* disk (and generally non real-time */ -/* applications). */ -/*******************************************/ - -#include "NIFileIn.h" - -NIFileIn :: NIFileIn(char *fileName) -{ - long i; - - strcpy(fileNm,fileName); - - myFile = fopen(fileNm,"rb"); - if (!myFile) { - printf("Couldn't find soundfile %s !!!!!!!!\n",fileName); - exit(0); - } - - i = 0; - while (fread(&data,2,1,myFile)) i++; - length = i; - fseek(myFile,0,0); - time = 0.0; - rate = 1.0; - lastTime = 0; - finished = 0; - gain = 1.0; - lastOutput = 0.0; -} - -NIFileIn :: ~NIFileIn() -{ - this->finish(); -} - -void NIFileIn :: reset() -{ - if (finished) { - myFile = fopen(fileNm,"rb"); - } - fseek(myFile,0,0); - - printf("Resetting\n"); - time = 0.0; - lastTime = 0; - finished = 0; - lastOutput = 0.0; -} - -void NIFileIn :: normalize() -{ - this->normalize(1.0); -} - -void NIFileIn :: normalize(MY_FLOAT newPeak) -{ - long i; - FILE *fd; - - gain = 0.0; - - fd = fopen(fileNm,"rb"); - for (i=0;i gain) - gain = fabs(data); - } - if (gain > 0.0) { - gain = newPeak / gain; - } - fclose(fd); -} - -void NIFileIn :: setRate(MY_FLOAT aRate) -{ - rate = aRate; -} - -void NIFileIn :: finish() -{ - finished = 1; - lastOutput = 0.0; - if (myFile) { - fclose(myFile); - myFile = 0; - } -} - -MY_FLOAT NIFileIn :: tick() -{ - this->informTick(); - return lastOutput; -} - -int NIFileIn :: informTick() -{ - long temp; - - if (!finished) { - - time += rate; /* Update current time */ - - if (time >= length) { /* Check for end of sound */ - time = length - 1; /* stick at end */ - finished = 1; /* Information for one-shot use */ - fclose(myFile); - myFile = 0; - } - else { - temp = (long) time; /* Integer part of time address */ - if (temp > lastTime) { /* If we cross next sample time */ - lastTime = temp; - fread(&data,2,1,myFile); /* Snarf next sample from file */ - lastOutput = data * gain; /* And save as non-interpolated data */ - } - } - } - - return finished; -} - -MY_FLOAT NIFileIn :: lastOut() -{ - return lastOutput; -} - -/************ Test Main Program *****************/ -/* -void main() -{ - NIFileIn oneShot("rawwaves/mandpluk.raw"); - FILE *fd; - short data; - long i; - - fd = fopen("test.raw","wb"); - oneShot.setRate(1.0); - while (!oneShot.informTick()) { - data = oneShot.lastOut(); - fwrite(&data,2,1,fd); - } - - oneShot.reset(); - oneShot.setRate(0.5); - for (i=0;i<16384;i++) { - data = oneShot.tick(); - fwrite(&data,2,1,fd); - } - fclose(fd); -} -*/ - diff --git a/NIFileIn.h b/NIFileIn.h deleted file mode 100644 index 936747a..0000000 --- a/NIFileIn.h +++ /dev/null @@ -1,47 +0,0 @@ -/*******************************************/ -/* NonInterpolating One-Shot Raw Sound- */ -/* file Class, by Perry R. Cook, 1995-96 */ -/* This Object can open a raw 16bit data */ -/* (signed integers) file, and play back */ -/* the data once, with no interpolation */ -/* on playback. Once finished, it closes */ -/* the file, the file is reopened with */ -/* the reset() method. */ -/* This is useful for small memory model, */ -/* applications, or for streaming from */ -/* disk (and generally non real-time */ -/* applications). */ -/*******************************************/ - -#if !defined(__NIFileIn_h) -#define __NIFileIn_h - -#include "Object.h" - -class NIFileIn : public Object -{ - protected: - long length; - long lastTime; - int finished; - short data; - char fileNm[128]; - FILE *myFile; - MY_FLOAT rate; - MY_FLOAT time; - MY_FLOAT gain; - MY_FLOAT lastOutput; - public: - NIFileIn(char *fileName); - ~NIFileIn(); - void reset(); - void normalize(); - void normalize(MY_FLOAT newPeak); - void setRate(MY_FLOAT aRate); - void finish(); - MY_FLOAT tick(); - int informTick(); - MY_FLOAT lastOut(); -}; - -#endif diff --git a/NIWave1S.cpp b/NIWave1S.cpp deleted file mode 100644 index d2a75ee..0000000 --- a/NIWave1S.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/*******************************************/ -/* NonInterpolating One-Shot Raw Sound- */ -/* file Class, by Perry R. Cook, 1995-96 */ -/* This Object can open a raw 16bit data */ -/* (signed integers) file, and play back */ -/* the data once (again when reset), with */ -/* no interpolation on playback. */ -/*******************************************/ - -#include "NIWave1S.h" - -NIWave1S :: NIWave1S(char *fileName) -{ - long i; - short temp; - FILE *fd; - fd = fopen(fileName,"rb"); - if (!fd) { - printf("Couldn't find soundfile %s !!!!!!!!\n",fileName); - exit(0); - } - i = 0; - while (fread(&temp,2,1,fd)) i++; - length = i; - fseek(fd,0,0); - data = (MY_FLOAT *) malloc(MY_FLOAT_SIZE * (length + 1)); - i = 0; - while (fread(&temp,2,1,fd)) { - data[i] = temp; - i++; - } - data[length] = data[length-1]; - fclose(fd); - time = 0.0; - rate = 1.0; -} - -void NIWave1S :: reset() -{ - time = 0.0; - lastOutput = 0.0; -} - -void NIWave1S :: normalize() -{ - this->normalize(1.0); -} - -void NIWave1S :: normalize(MY_FLOAT newPeak) -{ - long i; - MY_FLOAT max = 0.0; - for (i=0;i<=length;i++) - if (fabs(data[i]) > max) - max = fabs(data[i]); - if (max > 0.0) { - max = 1.0 / max; - max *= newPeak; - for (i=0;i<=length;i++) - data[i] *= max; - } -} - -void NIWave1S :: setRate(MY_FLOAT aRate) -{ - rate = aRate; -} - -MY_FLOAT NIWave1S :: tick() -{ - this->informTick(); - return lastOutput; -} - -int NIWave1S :: informTick() -{ - int allDone = 0; - long temp; - - time += rate; /* Update current time */ - - if (time >= length) { /* Check for end of sound */ - time = length-1; /* stick at end */ - allDone = 1; /* Information for one-shot use */ - } - temp = (long) time; /* Integer part of time address */ - lastOutput = data[temp]; /* Get non-interpolated data */ - - return allDone; -} - -MY_FLOAT NIWave1S :: lastOut() -{ - return lastOutput; -} - -/************ Test Main Program *****************/ -/* -void main() -{ - NIWave1S oneShot("rawwaves/mandpluk.raw"); - FILE *fd; - short data; - long i; - - fd = fopen("test.raw","wb"); - for (i=0;i<8192;i++) { - data = oneShot.tick(); - fwrite(&data,2,1,fd); - } - oneShot.reset(); - oneShot.setRate(0.5); - for (i=0;i<16384;i++) { - data = oneShot.tick(); - fwrite(&data,2,1,fd); - } - fclose(fd); -} -*/ diff --git a/NIWave1S.h b/NIWave1S.h deleted file mode 100644 index 298abe1..0000000 --- a/NIWave1S.h +++ /dev/null @@ -1,34 +0,0 @@ -/*******************************************/ -/* NonInterpolating One-Shot Raw Sound- */ -/* file Class, by Perry R. Cook, 1995-96 */ -/* This Object can open a raw 16bit data */ -/* (signed integers) file, and play back */ -/* the data once (again when reset), with */ -/* no interpolation on playback. */ -/*******************************************/ - -#if !defined(__NIWave1S_h) -#define __NIWave1S_h - -#include "Object.h" - -class NIWave1S : public Object -{ - protected: - long length; - MY_FLOAT *data; - MY_FLOAT rate; - MY_FLOAT time; - MY_FLOAT lastOutput; - public: - NIWave1S(char *fileName); - void reset(); - void normalize(); - void normalize(MY_FLOAT newPeak); - void setRate(MY_FLOAT aRate); - MY_FLOAT tick(); - int informTick(); - MY_FLOAT lastOut(); -}; - -#endif diff --git a/NRev.cpp b/NRev.cpp new file mode 100644 index 0000000..7f351ed --- /dev/null +++ b/NRev.cpp @@ -0,0 +1,138 @@ +/******************************************/ +/* NRev Reverb Subclass */ +/* by Tim Stilson, 1998 */ +/* based on CLM NRev */ +/* Integrated into STK by Gary Scavone */ +/* */ +/* This is based on some of the famous */ +/* Stanford CCRMA reverbs (NRev, KipRev) */ +/* all based on the the Chowning/Moorer/ */ +/* Schroeder reverberators, which use */ +/* networks of simple allpass and comb */ +/* delay filters. This particular */ +/* arrangement consists of 6 comb */ +/* filters in parallel, followed by 3 */ +/* allpass filters, a lowpass filter, */ +/* and another allpass in series, */ +/* followed by two allpass filters in */ +/* parallel with corresponding right and */ +/* left outputs. */ +/******************************************/ + +#include "NRev.h" + +NRev :: NRev(MY_FLOAT T60) +{ + int lens[15]={1433,1601,1867,2053,2251,2399,347,113,37,59,53,43,37,29,19}; + double srscale= SRATE / 25641.0; + int val; + int i; + + for (i=0; i<15; i++) + { + val = (int)floor(srscale*lens[i]); + if ((val & 1) == 0) val++; + while (!this->isprime(val)) val+=2; + lens[i]=val; + } + for (i=0; i<6; i++) + { + CdelayLine[i] = new DLineN((long) (lens[i]) + 2); + CdelayLine[i]->setDelay((long) (lens[i])); + combCoef[i] = pow(10,(-3 * lens[i] / (T60 * SRATE))); + } + for (i=0; i<8; i++) + { + APdelayLine[i] = new DLineN((long) (lens[i+6]) + 2); + APdelayLine[i]->setDelay((long) (lens[i+6])); + } + + allPassCoeff = 0.7; + effectMix = 0.3; + this->clear(); +} + +NRev :: ~NRev() +{ + int i; + + for (i=0; i<6; i++) delete CdelayLine[i]; + for (i=0; i<8; i++) delete APdelayLine[i]; +} + +void NRev :: clear() +{ + int i; + + for (i=0; i<6; i++) CdelayLine[i]->clear(); + for (i=0; i<8; i++) APdelayLine[i]->clear(); + lastOutL = 0.0; + lastOutR = 0.0; + lpLastout = 0.0; +} + +void NRev :: setEffectMix(MY_FLOAT mix) +{ + effectMix = mix; +} + +MY_FLOAT NRev :: lastOutput() +{ + return (lastOutL + lastOutR) * 0.5; +} + +MY_FLOAT NRev :: lastOutputL() +{ + return lastOutL; +} + +MY_FLOAT NRev :: lastOutputR() +{ + return lastOutR; +} + +MY_FLOAT NRev :: tick(MY_FLOAT input) +{ + MY_FLOAT temp,temp0,temp1,temp2,temp3; + int i; + + temp0 = 0.0; + for (i=0; i<6; i++) + { + temp = input + (combCoef[i] * CdelayLine[i]->lastOut()); + temp0 += CdelayLine[i]->tick(temp); + } + for (i=0; i<3; i++) + { + temp = APdelayLine[i]->lastOut(); + temp1 = allPassCoeff * temp; + temp1 += temp0; + APdelayLine[i]->tick(temp1); + temp0 = -(allPassCoeff * temp1) + temp; + } + lpLastout = 0.7*lpLastout + 0.3*temp0; // onepole LP filter + temp = APdelayLine[3]->lastOut(); + temp1 = allPassCoeff * temp; + temp1 += lpLastout; + APdelayLine[3]->tick(temp1); + temp1 = -(allPassCoeff * temp1) + temp; + + temp = APdelayLine[4]->lastOut(); + temp2 = allPassCoeff * temp; + temp2 += temp1; + APdelayLine[4]->tick(temp2); + lastOutL = effectMix*(-(allPassCoeff * temp2) + temp); + + temp = APdelayLine[5]->lastOut(); + temp3 = allPassCoeff * temp; + temp3 += temp1; + APdelayLine[5]->tick(temp3); + lastOutR = effectMix*(-(allPassCoeff * temp3) + temp); + + temp = (1.0 - effectMix) * input; + lastOutL += temp; + lastOutR += temp; + + return (lastOutL + lastOutR) * 0.5; + +} diff --git a/NRev.h b/NRev.h new file mode 100644 index 0000000..67164f7 --- /dev/null +++ b/NRev.h @@ -0,0 +1,52 @@ +/******************************************/ +/* NRev Reverb Subclass */ +/* by Tim Stilson, 1998 */ +/* based on CLM NRev */ +/* Integrated into STK by Gary Scavone */ +/* */ +/* This is based on some of the famous */ +/* Stanford CCRMA reverbs (NRev, KipRev) */ +/* all based on the the Chowning/Moorer/ */ +/* Schroeder reverberators, which use */ +/* networks of simple allpass and comb */ +/* delay filters. This particular */ +/* arrangement consists of 6 comb */ +/* filters in parallel, followed by 3 */ +/* allpass filters, a lowpass filter, */ +/* and another allpass in series, */ +/* followed by two allpass filters in */ +/* parallel with corresponding right and */ +/* left outputs. */ +/******************************************/ + +#if !defined(__NRev_h) +#define __NRev_h + +#include "Object.h" +#include "Reverb.h" +#include "DLineN.h" + +class NRev : public Reverb +{ + protected: + DLineN *APdelayLine[8]; + DLineN *CdelayLine[6]; + MY_FLOAT allPassCoeff; + MY_FLOAT combCoef[6]; + MY_FLOAT lpLastout; + MY_FLOAT lastOutL; + MY_FLOAT lastOutR; + MY_FLOAT effectMix; + public: + NRev(MY_FLOAT T60); + ~NRev(); + void clear(); + void setEffectMix(MY_FLOAT mix); + MY_FLOAT lastOutput(); + MY_FLOAT lastOutputL(); + MY_FLOAT lastOutputR(); + MY_FLOAT tick(MY_FLOAT input); +}; + +#endif + diff --git a/Noise.cpp b/Noise.cpp index 25ad571..51daf3f 100644 --- a/Noise.cpp +++ b/Noise.cpp @@ -5,40 +5,41 @@ /*******************************************/ #include "Noise.h" +#ifdef __NeXT_ + #include +#endif + +#if defined(__OS_Win_) /* For Windows95 or NT */ + #define ONE_OVER_RANDLIMIT 0.00006103516 +#else /* This is for Linux, NeXT and SGI */ + #define ONE_OVER_RANDLIMIT 0.00000000093132258 +#endif Noise :: Noise() : Object() { - lastOutput = 0.0; + lastOutput = (MY_FLOAT) 0.0; } Noise :: ~Noise() { - } -/* THIS IS FOR TURBO C */ -/* Constant = 1.0 / 16384.0 */ -/* #define ONE_OVER_RANDLIMIT 0.00006103516 */ - - -/* THIS IS FOR UNIX, NeXT and SGI */ - #define ONE_OVER_RANDLIMIT 0.00000000093132258 - MY_FLOAT Noise :: tick() { -/* THIS ONE IS TURBO C */ -/* lastOutput = (MY_FLOAT) random(32767) - 16384.0; */ +/* THIS ONE IS WIN95 */ +#if defined(__OS_Win_) /* For Windows95 or NT */ + lastOutput = (MY_FLOAT) (rand() - 16383); +#else /* This is for Linux, NeXT and SGI */ + lastOutput = (MY_FLOAT) random() - 1073741823.0; +#endif -/* THIS IS FOR UNIX, NeXT and SGI */ - - lastOutput = (MY_FLOAT) random() - 1073741823.0; - lastOutput *= ONE_OVER_RANDLIMIT; - return lastOutput; + lastOutput *= (MY_FLOAT) ONE_OVER_RANDLIMIT; + return lastOutput; } MY_FLOAT Noise :: lastOut() { - return lastOutput; + return lastOutput; } /************ Test Main ************************/ diff --git a/Noise.h b/Noise.h index 950dc81..bde086e 100644 --- a/Noise.h +++ b/Noise.h @@ -15,8 +15,8 @@ class Noise : public Object MY_FLOAT lastOutput; public: Noise(); - ~Noise(); - virtual MY_FLOAT tick(); + virtual ~Noise(); + MY_FLOAT tick(); MY_FLOAT lastOut(); }; diff --git a/Object.cpp b/Object.cpp index bdb31e8..d2f4b07 100644 --- a/Object.cpp +++ b/Object.cpp @@ -7,20 +7,14 @@ /*******************************************/ #include "Object.h" - +// #include "byteswap.c" /* This is just here for compatibility and convenience, - so there's no need to do any real calculations. + so there's no need to do any real calculations. I do set up some redefinable variables here. */ - Object :: Object() { - MIDI_mod_wheel = 1; /* Controller # 1 */ - MIDI_control1 = 2; /* Breath Pressure */ - MIDI_control2 = 4; /* Foot Control */ - MIDI_control3 = 11; /* Expression Pedal */ - MIDI_after_touch = 128; /* Channel Pressure -> new controller */ } Object :: ~Object() diff --git a/Object.h b/Object.h index f691156..68aa4fb 100644 --- a/Object.h +++ b/Object.h @@ -1,10 +1,10 @@ -/*******************************************/ -/* Object Class, by Perry R. Cook, 1995-96*/ -/* This is mostly here for compatibility */ -/* with Objective C. We'll also stick */ -/* global defines here, so everyone will */ -/* see them. */ -/*******************************************/ +/*********************************************/ +/* Object Class, by Perry R. Cook, 1995-96 */ +/* This is mostly here for compatibility */ +/* with Objective C. We'll also stick */ +/* global defines here, so everyone will */ +/* see them. */ +/*********************************************/ #if !defined(__Object_h) #define __Object_h @@ -17,49 +17,87 @@ class Object { public: - int MIDI_control1; - int MIDI_control2; - int MIDI_control3; - int MIDI_mod_wheel; - int MIDI_after_touch; protected: Object(); - ~Object(); + virtual ~Object(); }; -/* Only use one of __SGI_ __NeXT_ __DOS_ */ -/* And choice of __SGI_REALTIME or not */ +/* #define __OS_NeXT_ */ +#define __OS_IRIX_ +/* #define __OS_Linux_ */ +/* #define __OS_Win_ */ - #define __SGI_ - #define __SGI_REALTIME -/* #define __NeXT_ */ +#if defined(__OS_NeXT_) /* For NeXTStep - Black or White Hardware */ + #define __NeXT_ +#elif defined(__OS_IRIX_) /* For SGI */ + #define __SGI_REALTIME_ + typedef int bool; +#elif defined(__OS_Linux_) /* For Linux */ + #define __USS_REALTIME_ + #define __LITTLE_ENDIAN__ +#elif defined(__OS_Win_) /* For Windows95 or NT */ + #define __WINDS_REALTIME_ /* For Direct Sound API */ +/* #define __WINMM_REALTIME_ */ /* For Win MM API */ + #define __SOCKET + #define __LITTLE_ENDIAN__ +#endif + +/* Real-time output buffer size. If clicks are occuring in the + * output sound stream, a larger buffer size may help. Larger + * buffer sizes, however, produce more latency between input and + * output. +*/ +#define RT_BUFFER_SIZE 256 + +/* This sets the maximum number of simultaneous + * (within a buffer) MIDI messages that can be + * serviced before messages begin to be lost or + * overwritten. It should be a function of + * RT_BUFFER_SIZE + */ +#define MAX_IN_STRINGS 25 /* SRATE here is 44100, others are derived accordingly */ -/* #define SRATE 44100.0 - #define SRATE_OVER_TWO 22050.0 - #define ONE_OVER_SRATE 0.00002267573696 - #define RATE_NORM 0.5 -*/ + +#define SRATE (MY_FLOAT) 44100.0 +#define SRATE_OVER_TWO (MY_FLOAT) 22050.0 +#define ONE_OVER_SRATE (MY_FLOAT) 0.00002267573696 +#define RATE_NORM (MY_FLOAT) 0.5 +#define TWO_PI_OVER_SRATE (MY_FLOAT) 0.0001424758573 /* SRATE here is 22050, others are derived accordingly */ - #define SRATE 22050.0 - #define SRATE_OVER_TWO 11025.0 - #define ONE_OVER_SRATE 0.00004535147392 - #define RATE_NORM 1.0 - +/* +#define SRATE (MY_FLOAT) 22050.0 +#define SRATE_OVER_TWO (MY_FLOAT) 11025.0 +#define ONE_OVER_SRATE (MY_FLOAT) 0.00004535147392 +#define RATE_NORM (MY_FLOAT) 1.0 +#define TWO_PI_OVER_SRATE (MY_FLOAT) 0.0002849517146 +*/ +/* SRATE here is 16000, others are derived accordingly */ +/* +#define SRATE (MY_FLOAT) 16000.0 +#define SRATE_OVER_TWO (MY_FLOAT) 8000.0 +#define ONE_OVER_SRATE (MY_FLOAT) 0.0000625 +#define RATE_NORM (MY_FLOAT) 1.375 +#define TWO_PI_OVER_SRATE (MY_FLOAT) 0.000392699 +*/ /* SRATE here is 8k, others are derived accordingly */ -/* #define SRATE 8000.0 - #define SRATE_OVER_TWO 4000 - #define ONE_OVER_SRATE 0.00012500000000 - #define RATE_NORM 2.75625 +/* +#define SRATE (MY_FLOAT) 8000.0 +#define SRATE_OVER_TWO (MY_FLOAT) 4000 +#define ONE_OVER_SRATE (MY_FLOAT) 0.00012500000000 +#define RATE_NORM (MY_FLOAT) 2.75625 +#define TWO_PI_OVER_SRATE (MY_FLOAT) 0.0002849517146 */ -/* RATE_NORM is 22050 / 8000 */ /* Yer Basic Trigonometric constants */ -#define PI 3.14159265359 -#define TWO_PI 6.28318530718 -#define ONE_OVER_TWO_PI 0.15915494309 +#if !defined(PI) + #define PI (MY_FLOAT) 3.14159265359 +#endif +#define TWO_PI (MY_FLOAT) 6.28318530718 +#define ONE_OVER_TWO_PI (MY_FLOAT) 0.15915494309 +#define SQRT_TWO 1.414213562 /* States for Envelopes, etc. */ @@ -68,24 +106,28 @@ class Object #define SUSTAIN 2 #define RELEASE 3 -/* Machine dependent stuff, possibly useful for optimization */ -/* for example, changing double to float here increases */ -/* performance (speed) by a whopping 4-6% on 486-flavor machines */ -/* BUT!! a change from float to double here increases speed by */ -/* 30% or so on SGI machines */ -/* #define MY_FLOAT float */ -/* #define MY_FLOAT_SIZE 4 */ +/* Machine dependent stuff, possibly useful for optimization. + * For example, changing double to float here increasesf + * performance (speed) by a whopping 4-6% on 486-flavor machines. + * BUT!! a change from float to double here increases speed by + * 30% or so on SGI machines. +*/ #define MY_FLOAT double #define MY_FLOAT_SIZE 8 -/* Debugging define, causes massive printf's to come out. */ -/* Also enables timing calculations in WaveOut class, other stuff. */ +/* +#define MY_FLOAT float +#define MY_FLOAT_SIZE 4 +*/ + +/* Debugging define, causes massive printf's to come out. + * Also enables timing calculations in WaveOut class, other stuff. + */ + /* #define _debug_ 1 */ -#include - -#define NORM_7 0.0078125 -/* this is 1/128 for MIDI normalization*/ - +/* MIDI definitions */ +#define NORM_7 (MY_FLOAT) 0.0078125 /* this is 1/128 */ + #endif diff --git a/OnePole.cpp b/OnePole.cpp index 6b788de..2fdad67 100644 --- a/OnePole.cpp +++ b/OnePole.cpp @@ -17,40 +17,40 @@ OnePole :: OnePole() : Filter() { - poleCoeff = 0.9; - gain = 1.0; - sgain = 0.1; + poleCoeff = (MY_FLOAT) 0.9; + gain = (MY_FLOAT) 1.0; + sgain = (MY_FLOAT) 0.1; outputs = (MY_FLOAT *) malloc(MY_FLOAT_SIZE); - outputs[0] = 0.0; + outputs[0] = (MY_FLOAT) 0.0; } OnePole :: ~OnePole() { - free(outputs); + free(outputs); } void OnePole :: clear() { - outputs[0] = 0.0; - lastOutput = 0.0; + outputs[0] = (MY_FLOAT) 0.0; + lastOutput = (MY_FLOAT) 0.0; } void OnePole :: setPole(MY_FLOAT aValue) { poleCoeff = aValue; if (poleCoeff > 0.0) /* Normalize gain to 1.0 max */ - sgain = gain * (1.0 - poleCoeff); + sgain = gain * ((MY_FLOAT) 1.0 - poleCoeff); else - sgain = gain * (1.0 + poleCoeff); + sgain = gain * ((MY_FLOAT) 1.0 + poleCoeff); } void OnePole :: setGain(MY_FLOAT aValue) { gain = aValue; if (poleCoeff > 0.0) - sgain = gain * (1.0 - poleCoeff); /* Normalize gain to 1.0 max */ + sgain = gain * ((MY_FLOAT) 1.0 - poleCoeff); /* Normalize gain to 1.0 max */ else - sgain = gain * (1.0 + poleCoeff); + sgain = gain * ((MY_FLOAT) 1.0 + poleCoeff); } MY_FLOAT OnePole :: tick(MY_FLOAT sample) /* Perform Filter Operation */ diff --git a/OneZero.cpp b/OneZero.cpp index d648780..ff2475e 100644 --- a/OneZero.cpp +++ b/OneZero.cpp @@ -17,40 +17,40 @@ OneZero :: OneZero() { - gain = 1.0; - zeroCoeff = 1.0; - sgain = 0.5; + gain = (MY_FLOAT) 1.0; + zeroCoeff = (MY_FLOAT) 1.0; + sgain = (MY_FLOAT) 0.5; inputs = (MY_FLOAT *) malloc(MY_FLOAT_SIZE); this->clear(); } OneZero :: ~OneZero() { - free(inputs); + free(inputs); } void OneZero :: clear() { - inputs[0] = 0.0; - lastOutput = 0.0; + inputs[0] = (MY_FLOAT) 0.0; + lastOutput = (MY_FLOAT) 0.0; } void OneZero :: setGain(MY_FLOAT aValue) { gain = aValue; if (zeroCoeff > 0.0) /* Normalize gain to 1.0 max */ - sgain = gain / (1.0 + zeroCoeff); + sgain = gain / ((MY_FLOAT) 1.0 + zeroCoeff); else - sgain = gain / (1.0 - zeroCoeff); + sgain = gain / ((MY_FLOAT) 1.0 - zeroCoeff); } void OneZero :: setCoeff(MY_FLOAT aValue) { zeroCoeff = aValue; if (zeroCoeff > 0.0) /* Normalize gain to 1.0 max */ - sgain = gain / (1.0 + zeroCoeff); + sgain = gain / ((MY_FLOAT) 1.0 + zeroCoeff); else - sgain = gain / (1.0 - zeroCoeff); + sgain = gain / ((MY_FLOAT) 1.0 - zeroCoeff); } MY_FLOAT OneZero :: tick(MY_FLOAT sample) /* Perform Filter Operation */ diff --git a/PRCRev.cpp b/PRCRev.cpp new file mode 100644 index 0000000..e739e2a --- /dev/null +++ b/PRCRev.cpp @@ -0,0 +1,113 @@ +/*******************************************/ +/* PRCRev, a simple reverb unit */ +/* by Perry Cook, 1996. */ +/* Incorporated into the Reverb superclass */ +/* by Gary Scavone, 1998. */ +/* */ +/* This is based on some of the famous */ +/* Stanford CCRMA reverbs (NRev, KipRev) */ +/* all based on the the Chowning/Moorer/ */ +/* Schroeder reverberators, which use */ +/* networks of simple allpass and comb */ +/* delay filters. This particular */ +/* structure consists of 2 allpass units */ +/* in series followed by 2 comb filters in */ +/* parallel. */ +/*******************************************/ + +#include "PRCRev.h" + +PRCRev :: PRCRev(MY_FLOAT T60) +{ + int lens[4]={353,1097,1777,2137}; + double srscale = SRATE / 44100.0; + int val, i; + + if (SRATE < 44100.0) { + for (i=0; i<4; i++) { + val = (int) floor(srscale * lens[i]); + if ((val & 1) == 0) val++; + while (!this->isprime(val)) val += 2; + lens[i] = val; + } + } + for (i=0; i<2; i++) + { + APdelayLine[i] = new DLineN(lens[i] + 2); + APdelayLine[i]->setDelay(lens[i]); + CdelayLine[i] = new DLineN(lens[i+2] + 2); + CdelayLine[i]->setDelay(lens[i+2]); + combCoeff[i] = pow(10,(-3 * lens[i+2] / (T60 * SRATE))); + } + + allPassCoeff = (MY_FLOAT) 0.7; + effectMix = (MY_FLOAT) 0.5; + this->clear(); +} + +PRCRev :: ~PRCRev() +{ + delete APdelayLine[0]; + delete APdelayLine[1]; + delete CdelayLine[0]; + delete CdelayLine[1]; +} + +void PRCRev :: clear() +{ + APdelayLine[0]->clear(); + APdelayLine[1]->clear(); + CdelayLine[0]->clear(); + CdelayLine[1]->clear(); + lastOutL = (MY_FLOAT) 0.0; + lastOutR = (MY_FLOAT) 0.0; +} + +void PRCRev :: setEffectMix(MY_FLOAT mix) +{ + effectMix = mix; +} + +MY_FLOAT PRCRev :: lastOutput() +{ + return (lastOutL + lastOutR) * (MY_FLOAT) 0.5; +} + +MY_FLOAT PRCRev :: lastOutputL() +{ + return lastOutL; +} + +MY_FLOAT PRCRev :: lastOutputR() +{ + return lastOutR; +} + +MY_FLOAT PRCRev :: tick(MY_FLOAT input) +{ + MY_FLOAT temp,temp0,temp1,temp2,temp3; + + temp = APdelayLine[0]->lastOut(); + temp0 = allPassCoeff * temp; + temp0 += input; + APdelayLine[0]->tick(temp0); + temp0 = -(allPassCoeff * temp0) + temp; + + temp = APdelayLine[1]->lastOut(); + temp1 = allPassCoeff * temp; + temp1 += temp0; + APdelayLine[1]->tick(temp1); + temp1 = -(allPassCoeff * temp1) + temp; + + temp2 = temp1 + (combCoeff[0] * CdelayLine[0]->lastOut()); + temp3 = temp1 + (combCoeff[1] * CdelayLine[1]->lastOut()); + + lastOutL = effectMix * (CdelayLine[0]->tick(temp2)); + lastOutR = effectMix * (CdelayLine[1]->tick(temp3)); + temp = (MY_FLOAT) (1.0 - effectMix) * input; + lastOutL += temp; + lastOutR += temp; + + return (lastOutL + lastOutR) * (MY_FLOAT) 0.5; + +} diff --git a/PRCRev.h b/PRCRev.h new file mode 100644 index 0000000..95567c5 --- /dev/null +++ b/PRCRev.h @@ -0,0 +1,43 @@ +/*******************************************/ +/* PRCRev, a simple reverb unit */ +/* by Perry Cook, 1996. */ +/* Incorporated into the Reverb superclass */ +/* by Gary Scavone, 1998. */ +/* */ +/* This is based on some of the famous */ +/* Stanford CCRMA reverbs (NRev, KipRev) */ +/* all based on the the Chowning/Moorer/ */ +/* Schroeder reverberators, which use */ +/* networks of simple allpass and comb */ +/* delay filters. */ +/*******************************************/ + +#if !defined(__PRCRev_h) +#define __PRCRev_h + +#include "Reverb.h" +#include "DLineN.h" + +class PRCRev : public Reverb +{ + protected: + DLineN *APdelayLine[2]; + DLineN *CdelayLine[2]; + MY_FLOAT allPassCoeff; + MY_FLOAT combCoeff[2]; + MY_FLOAT lastOutL; + MY_FLOAT lastOutR; + MY_FLOAT effectMix; + public: + PRCRev(MY_FLOAT T60); + ~PRCRev(); + void clear(); + void setEffectMix(MY_FLOAT mix); + MY_FLOAT lastOutput(); + MY_FLOAT lastOutputL(); + MY_FLOAT lastOutputR(); + MY_FLOAT tick(MY_FLOAT input); +}; + +#endif + diff --git a/PercFlut.cpp b/PercFlut.cpp index ac371fc..4160584 100644 --- a/PercFlut.cpp +++ b/PercFlut.cpp @@ -14,20 +14,24 @@ PercFlut :: PercFlut() : FM4Alg4() "rawwaves/sinewave.raw", "rawwaves/sinewave.raw"); - this->setRatio(0,1.50 ); - this->setRatio(1,3.00 * 0.995); - this->setRatio(2,2.99 * 1.005); - this->setRatio(3,6.00 * 0.997); + this->setRatio(0,(MY_FLOAT) (1.50 * 1.000)); + this->setRatio(1,(MY_FLOAT) (3.00 * 0.995)); + this->setRatio(2,(MY_FLOAT) (2.99 * 1.005)); + this->setRatio(3,(MY_FLOAT) (6.00 * 0.997)); gains[0] = __FM4Op_gains[99]; gains[1] = __FM4Op_gains[71]; gains[2] = __FM4Op_gains[93]; gains[3] = __FM4Op_gains[85]; - adsr[0]->setAll(0.001,0.001,__FM4Op_susLevels[14],0.001); - adsr[1]->setAll(0.05,0.0001,__FM4Op_susLevels[13],0.0001); - adsr[2]->setAll(0.05,0.0020,__FM4Op_susLevels[11],0.001); - adsr[3]->setAll(0.05,0.0010,__FM4Op_susLevels[13],0.005); - twozero->setGain(0.0); - modDepth = 0.005; + adsr[0]->setAllTimes((MY_FLOAT) 0.05,(MY_FLOAT) 0.05, + __FM4Op_susLevels[14],(MY_FLOAT) 0.05); + adsr[1]->setAllTimes((MY_FLOAT) 0.02,(MY_FLOAT) 0.50, + __FM4Op_susLevels[13],(MY_FLOAT) 0.5); + adsr[2]->setAllTimes((MY_FLOAT) 0.02,(MY_FLOAT) 0.30, + __FM4Op_susLevels[11],(MY_FLOAT) 0.05); + adsr[3]->setAllTimes((MY_FLOAT) 0.02,(MY_FLOAT) 0.05, + __FM4Op_susLevels[13],(MY_FLOAT) 0.01); + twozero->setGain((MY_FLOAT) 0.0); + modDepth = (MY_FLOAT) 0.005; } void PercFlut :: setFreq(MY_FLOAT frequency) @@ -37,10 +41,10 @@ void PercFlut :: setFreq(MY_FLOAT frequency) void PercFlut :: noteOn(MY_FLOAT freq, MY_FLOAT amp) { - gains[0] = amp * __FM4Op_gains[99]; - gains[1] = amp * __FM4Op_gains[71]; - gains[2] = amp * __FM4Op_gains[93]; - gains[3] = amp * __FM4Op_gains[85]; + gains[0] = amp * __FM4Op_gains[99] * 0.5; + gains[1] = amp * __FM4Op_gains[71] * 0.5; + gains[2] = amp * __FM4Op_gains[93] * 0.5; + gains[3] = amp * __FM4Op_gains[85] * 0.5; this->setFreq(freq); this->keyOn(); #if defined(_debug_) diff --git a/PhonTabl.h b/PhonTabl.h deleted file mode 100644 index 7ba437e..0000000 --- a/PhonTabl.h +++ /dev/null @@ -1,189 +0,0 @@ -double phonGains[32][2] = - {{1.0,0.0}, // eee - {1.0,0.0}, // ihh - {1.5,0.0}, // ehh - {1.0,0.0}, // aaa - - {0.5,0.0}, // ahh - {0.5,0.0}, // aww - {0.5,0.0}, // ohh - {0.5,0.0}, // uhh - - {0.5,0.0}, // uuu - {0.15,0.0}, // ooo - {0.15,0.0}, // rrr - {6.0,0.0}, // lll - - {1.0,0.0}, // mmm - {1.0,0.0}, // nnn - {1.0,0.0}, // nng - {1.0,0.0}, // ngg - - {0.0,1.0}, // fff - {0.0,1.0}, // sss - {0.0,1.0}, // thh - {0.0,1.0}, // shh - - {0.0,0.2}, // xxx - {0.0,0.003}, // hee - {0.0,0.001}, // hoo - {0.0,0.002}, // hah - - {1.0,0.4}, // bbb - {4.0,0.1}, // ddd - {1.0,0.4}, // jjj - {1.0,0.4}, // ggg - - {1.0,0.1}, // vvv - {1.0,0.1}, // zzz - {1.0,0.1}, // thz - {1.0,0.1} // zhh -}; - -double phonParams[32][4][3] = - {{ { 273,0.996, 0}, // eee (beet) - {2086,0.945, -16}, - {2754,0.979, -12}, - {3270,0.440, -17}}, - { { 385,0.987, 0}, // ihh (bit) - {2056,0.930, -20}, - {2587,0.890, -20}, - {3150,0.400, -20}}, - { { 515,0.977, 0}, // ehh (bet) - {1805,0.810, -10}, - {2526,0.875, -10}, - {3103,0.400, -13}}, - { { 773,0.950, 0}, // aaa (bat) - {1676,0.830, -6}, - {2380,0.880, -20}, - {3027,0.600, -20}}, - - { { 770,0.950, 0}, // ahh (father) - {1153,0.970, -3}, - {2450,0.780, -20}, - {3140,0.800, -32}}, - { { 637,0.910, 0}, // aww (bought) - { 895,0.900, -3}, - {2556,0.950, -17}, - {3070,0.910, -20}}, - { { 637,0.910, 0}, // ohh (bone) NOTE:: same as aww (bought) - { 895,0.900, -3}, - {2556,0.950, -17}, - {3070,0.910, -20}}, - { { 561,0.965, 0}, // uhh (but) - {1084,0.930, -10}, - {2541,0.930, -15}, - {3345,0.900, -20}}, - - { { 515,0.976, 0}, // uuu (foot) - {1031,0.950, -3}, - {2572,0.960, -11}, - {3345,0.960, -20}}, - { { 349,0.986, 0}, // ooo (boot) - { 918,0.940, -10}, - {2350,0.960, -17}, - {2731,0.950, -23}}, - { { 394,0.959, 0}, // rrr (bird) - {1297,0.780, -6}, - {1441,0.980, -6}, - {2754,0.950, -30}}, - { { 462,0.940, 0}, // lll (lull) - {2754,0.900, -30}, - {3406,0.100, -30}, - {3755,0.100, -30}}, - - { { 265,0.987, 0}, // mmm (mom) - {1176,0.940, -22}, - {2352,0.970, -20}, - {3277,0.940, -31}}, - { { 204,0.980, 0}, // nnn (nun) - {1570,0.940, -15}, - {2481,0.980, -12}, - {3133,0.800, -30}}, - { { 204,0.980, 0}, // nng (sang) NOTE:: same as nnn - {1570,0.940, -15}, - {2481,0.980, -12}, - {3133,0.800, -30}}, - { { 204,0.980, 0}, // ngg (bong) NOTE:: same as nnn - {1570,0.940, -15}, - {2481,0.980, -12}, - {3133,0.800, -30}}, - - { {1000,0.300, -10}, // fff - {2800,0.860, -10}, - {7425,0.740, 0}, - {8140,0.860, 0}}, - { {2000,0.700, -20}, // sss - {5257,0.750, -15}, - {7171,0.840, -3}, - {9000,0.900, 0}}, - { { 100,0.900, 0}, // thh - {4000,0.500, -20}, - {5500,0.500, -15}, - {8000,0.400, -20}}, - { {2693,0.940, 0}, // shh - {4000,0.720, -10}, - {6123,0.870, -10}, - {7755,0.750, -18}}, - - { {1000,0.300, -10}, // xxx NOTE:: Not Really Done Yet - {2800,0.860, -10}, - {7425,0.740, 0}, - {8140,0.860, 0}}, - { { 273,0.996, 0}, // hee (beet) (noisy eee) - {2086,0.945, -16}, - {2754,0.979, -12}, - {3270,0.440, -17}}, - { { 349,0.986, 0}, // hoo (boot) (noisy ooo) - { 918,0.940, -10}, - {2350,0.960, -17}, - {2731,0.950, -23}}, - { { 770,0.950, 0}, // hah (father) (noisy ahh) - {1153,0.970, -3}, - {2450,0.780, -20}, - {3140,0.800, -32}}, - - { {2000,0.700, -20}, // bbb NOTE:: Not Really Done Yet - {5257,0.750, -15}, - {7171,0.840, -3}, - {9000,0.900, 0}}, - { { 100,0.900, 0}, // ddd NOTE:: Not Really Done Yet - {4000,0.500, -20}, - {5500,0.500, -15}, - {8000,0.400, -20}}, - { {2693,0.940, 0}, // jjj NOTE:: Not Really Done Yet - {4000,0.720, -10}, - {6123,0.870, -10}, - {7755,0.750, -18}}, - { {2693,0.940, 0}, // ggg NOTE:: Not Really Done Yet - {4000,0.720, -10}, - {6123,0.870, -10}, - {7755,0.750, -18}}, - - { {2000,0.700, -20}, // vvv NOTE:: Not Really Done Yet - {5257,0.750, -15}, - {7171,0.840, -3}, - {9000,0.900, 0}}, - { { 100,0.900, 0}, // zzz NOTE:: Not Really Done Yet - {4000,0.500, -20}, - {5500,0.500, -15}, - {8000,0.400, -20}}, - { {2693,0.940, 0}, // thz NOTE:: Not Really Done Yet - {4000,0.720, -10}, - {6123,0.870, -10}, - {7755,0.750, -18}}, - { {2693,0.940, 0}, // zhh NOTE:: Not Really Done Yet - {4000,0.720, -10}, - {6123,0.870, -10}, - {7755,0.750, -18}} -}; - -char phonemes[32][4] = - {"eee","ihh","ehh","aaa", - "ahh","aww","ohh","uhh", - "uuu","ooo","rrr","lll", - "mmm","nnn","nng","ngg", - "fff","sss","thh","shh", - "xxx","hee","hoo","hah", - "bbb","ddd","jjj","ggg", - "vvv","zzz","thz","zhh"}; diff --git a/Plucked.cpp b/Plucked.cpp index ea3cef0..565f270 100644 --- a/Plucked.cpp +++ b/Plucked.cpp @@ -12,7 +12,7 @@ Plucked :: Plucked(MY_FLOAT lowestFreq) { length = (long) (SRATE / lowestFreq + 1); - loopGain = 0.999; + loopGain = (MY_FLOAT) 0.999; delayLine = new DLineA(length); loopFilt = new OneZero; pickFilt = new OnePole; @@ -38,19 +38,19 @@ void Plucked :: clear() void Plucked :: setFreq(MY_FLOAT frequency) { MY_FLOAT delay; - delay = ((MY_FLOAT) SRATE / frequency) - 0.5; /* length - delays */ + delay = (SRATE / frequency) - (MY_FLOAT) 0.5; /* length - delays */ delayLine->setDelay(delay); - loopGain = 0.995 + (frequency * 0.000005); - if (loopGain>1.0) loopGain = 0.99999; + loopGain = (MY_FLOAT) 0.995 + (frequency * (MY_FLOAT) 0.000005); + if (loopGain>1.0) loopGain = (MY_FLOAT) 0.99999; } void Plucked :: pluck(MY_FLOAT amplitude) { long i; - pickFilt->setPole(0.999 - (amplitude*0.15)); - pickFilt->setGain(amplitude * 0.5); + pickFilt->setPole((MY_FLOAT) 0.999 - (amplitude * (MY_FLOAT) 0.15)); + pickFilt->setGain(amplitude * (MY_FLOAT) 0.5); for (i=0;itick(delayLine->lastOut() * 0.6 /* fill delay with noise */ + delayLine->tick(delayLine->lastOut() * (MY_FLOAT) 0.6 /* fill delay with noise */ + pickFilt->tick(noise->tick())); /* additively with current */ /* contents */ } @@ -66,7 +66,7 @@ void Plucked :: noteOn(MY_FLOAT freq, MY_FLOAT amp) void Plucked :: noteOff(MY_FLOAT amp) { - loopGain = 1.0 - amp; + loopGain = (MY_FLOAT) 1.0 - amp; #if defined(_debug_) printf("Plucked : NoteOff: Amp=%lf\n",amp); #endif @@ -78,7 +78,7 @@ MY_FLOAT Plucked :: tick() loopFilt->tick( /* here's the whole inner */ delayLine->lastOut() /* loop of the instrument!! */ * loopGain)); - lastOutput *= 3.0; + lastOutput *= (MY_FLOAT) 3.0; return lastOutput; } diff --git a/Plucked2.cpp b/Plucked2.cpp index 2ebd171..f3658ac 100644 --- a/Plucked2.cpp +++ b/Plucked2.cpp @@ -12,18 +12,18 @@ Plucked2 :: Plucked2(MY_FLOAT lowestFreq) { length = (long) (SRATE / lowestFreq + 1); - baseLoopGain = 0.995; - loopGain = 0.999; + baseLoopGain = (MY_FLOAT) 0.995; + loopGain = (MY_FLOAT) 0.999; delayLine = new DLineA(length); delayLine2 = new DLineA(length); combDelay = new DLineL(length); filter = new OneZero; filter2 = new OneZero; - pluckAmp = 0.3; - pluckPos = 0.4; - detuning = 0.995; - lastFreq = lowestFreq * 2.0; - lastLength = length * 0.5; + pluckAmp = (MY_FLOAT) 0.3; + pluckPos = (MY_FLOAT) 0.4; + detuning = (MY_FLOAT) 0.995; + lastFreq = lowestFreq * (MY_FLOAT) 2.0; + lastLength = length * (MY_FLOAT) 0.5; } Plucked2 :: ~Plucked2() @@ -48,17 +48,17 @@ void Plucked2 :: setFreq(MY_FLOAT frequency) { lastFreq = frequency; lastLength = ((MY_FLOAT) SRATE / lastFreq); /* length - delays */ - delayLine->setDelay((lastLength / detuning) - 0.5); - delayLine2->setDelay((lastLength * detuning) - 0.5); - loopGain = baseLoopGain + (frequency * 0.000005); - if (loopGain>1.0) loopGain = 0.99999; + delayLine->setDelay((lastLength / detuning) - (MY_FLOAT) 0.5); + delayLine2->setDelay((lastLength * detuning) - (MY_FLOAT) 0.5); + loopGain = baseLoopGain + (frequency * (MY_FLOAT) 0.000005); + if (loopGain>1.0) loopGain = (MY_FLOAT) 0.99999; } void Plucked2 :: setDetune(MY_FLOAT detune) { detuning = detune; - delayLine->setDelay((lastLength / detuning) - 0.5); - delayLine2->setDelay((lastLength * detuning) - 0.5); + delayLine->setDelay((lastLength / detuning) - (MY_FLOAT) 0.5); + delayLine2->setDelay((lastLength * detuning) - (MY_FLOAT) 0.5); } void Plucked2 :: setFreqAndDetune(MY_FLOAT frequency,MY_FLOAT detune) @@ -76,13 +76,13 @@ void Plucked2 :: setPluckPos(MY_FLOAT position) void Plucked2 :: setBaseLoopGain(MY_FLOAT aGain) { baseLoopGain = aGain; - loopGain = baseLoopGain + (lastFreq * 0.000005); - if (loopGain>1.0) loopGain = 0.99999; + loopGain = baseLoopGain + (lastFreq * (MY_FLOAT) 0.000005); + if (loopGain>1.0) loopGain = (MY_FLOAT) 0.99999; } void Plucked2 :: noteOff(MY_FLOAT amp) { - loopGain = (1.0 - amp) * 0.5; + loopGain = ((MY_FLOAT) 1.0 - amp) * (MY_FLOAT) 0.5; #if defined(_debug_) printf("Plucked2 : NoteOff: Amp=%lf\n",amp); #endif diff --git a/Plucked2.h b/Plucked2.h index 2a102e2..d3469d8 100644 --- a/Plucked2.h +++ b/Plucked2.h @@ -33,7 +33,7 @@ class Plucked2 : public Instrmnt MY_FLOAT pluckPos; public: Plucked2(MY_FLOAT lowestFreq); - ~Plucked2(); + virtual ~Plucked2(); void clear(); virtual void setFreq(MY_FLOAT frequency); void setDetune(MY_FLOAT detune); diff --git a/README-Linux.txt b/README-Linux.txt new file mode 100644 index 0000000..75065a5 --- /dev/null +++ b/README-Linux.txt @@ -0,0 +1,42 @@ +STK98v2: A ToolKit of Audio Synthesis Classes and Instruments in C++ + +By Perry R. Cook, 1995-98 +With recent help by Gary P. Scavone + +Please read the file README.txt for more general STK information. + +STK98 for Linux is currently using the OSS sound and MIDI API. The free version of OSS will probably work, though it doesn't work with as many soundcards as the commercial version (costs about $20). + +STK98 should compile without much trouble, after you make the appropriate settings in Object.h and select an appropriate Makefile. Since all Linux systems should come with the GNU makefile utilities, you should be able to use either Makefile.all or Makefile.linux (which should be renamed "Makefile" before using). Typing "make" should initiate the compilation process. + +NOTE REGARDING PTHREADS: The only issue which seems to crop up on different versions of Linux concerns threads. I am using the MIT pthreads API. Under RedHat Linux 4.x, I had to specifically include (the default pthread library didn't work). However, under RedHat Linux 5.0, the default works and the path doesn't exist. I've decided to assume the default works. If you get errors with regard to pthreads when you compile, you'll have to search your system for the MIT pthread distribution and change the appropriate include statements in MIDIIO.cpp, MD2SKINI.cpp, and syntmono.cpp. + +Once everything is compiled, you can use the scripts in "TCLSpecs" to run GUIs or invoke direct MIDI input controls. However, these scripts have been written for Tcl/Tk 8.0 ... they seem to work OK on older versions of Tcl/Tk under Linux, but not under IRIX. Tcl/Tk is free, so you might as well download the newest version. + +Two primary executables are created during compilation - syntmono and MD2SKINI. Syntmono is the core STK synthesis server. All distributed STK instruments are run using syntmono. MD2SKINI takes raw MIDI input, converts it to SKINI format, and outputs the result to stdout or a socket port ID (under Windoze). Control data (in the form of SKINI messages) can be fed to syntmono through three principal means - SKINI scorefiles, MD2SKINI output, and Tcl/Tk GUIs. A variety of SKINI scorefiles are distributed with STK98 and can be found in the "scores" directory. Under all platforms, a scorefile can be piped or redirected to syntmono in the following way: + + more scores/streetsf.ski | syntmono Clarinet -r +or + syntmono Clarinet -r < scores/streetsf.ski + +A number of Tcl/Tk GUIs are provided in the "TCLSpecs" directory, though you will have to install Tcl/Tk on your system to use them. Realtime SKINI control data (via MD2SKINI or GUIs) can be piped to syntmono on Unix platforms in the following way: + + MD2SKINI | syntmono Clarinet -r -i +or + wish < TCLSpecs/TCLPhys.tcl | syntmono Clarinet -r -i + + +/******************************************************/ + +Legal and Ethical: + +This software was designed and created to be made publicly available for free, primarily for academic purposes, so if you use it, pass it on with this documentation, and for free. + +If you make a million dollars with it, give me some. If you make compositions with it, put me in the program notes. + +Some of the concepts are covered by various patents, some known to me and likely others which are unknown. Many of the ones known to me are administered by the Stanford Office of Technology and Licensing. + +The good news is that large hunks of the techniques used here are public domain. To avoid subtle legal issues, I'll not state what's freely useable here, but I'll try to note within the various classes where certain things are likely to be protected by patents. + +/******************************************************/ + diff --git a/README-SGI.txt b/README-SGI.txt new file mode 100644 index 0000000..725c1ed --- /dev/null +++ b/README-SGI.txt @@ -0,0 +1,38 @@ +STK98v2: A ToolKit of Audio Synthesis Classes and Instruments in C++ + +By Perry R. Cook, 1995-98 +With recent help by Gary P. Scavone + +Please read the file README.txt for more general STK information. + +STK98 should compile without much trouble, after you make the appropriate settings in Object.h and select an appropriate Makefile. Apparently, SGI systems are not distributed with the GNU makefile utilities, so your safest bet is to use Makefile.sgi (which should be renamed "Makefile" before using). If you do have the GNU makefile utilities on your system, you could also use Makefile.all (which is convenient if you are on a network with a variety of different computer systems). Typing "make" should initiate the compilation process. + +Once everything is compiled, you can use the scripts in "TCLSpecs" to run GUIs or invoke direct MIDI input controls. + +Two primary executables are created during compilation - syntmono and MD2SKINI. Syntmono is the core STK synthesis server. All distributed STK instruments are run using syntmono. MD2SKINI takes raw MIDI input, converts it to SKINI format, and outputs the result to stdout or a socket port ID (under Windoze). Control data (in the form of SKINI messages) can be fed to syntmono through three principal means - SKINI scorefiles, MD2SKINI output, and Tcl/Tk GUIs. A variety of SKINI scorefiles are distributed with STK98 and can be found in the "scores" directory. Under all platforms, a scorefile can be piped or redirected to syntmono in the following way: + + more scores/streetsf.ski | syntmono Clarinet -r +or + syntmono Clarinet -r < scores/streetsf.ski + +A number of Tcl/Tk GUIs are provided in the "TCLSpecs" directory, though you will have to install Tcl/Tk on your system to use them. Realtime SKINI control data (via MD2SKINI or GUIs) can be piped to syntmono on Unix platforms in the following way: + + MD2SKINI | syntmono Clarinet -r -i +or + wish < TCLSpecs/TCLPhys.tcl | syntmono Clarinet -r -i + + +/******************************************************/ + +Legal and Ethical: + +This software was designed and created to be made publicly available for free, primarily for academic purposes, so if you use it, pass it on with this documentation, and for free. + +If you make a million dollars with it, give me some. If you make compositions with it, put me in the program notes. + +Some of the concepts are covered by various patents, some known to me and likely others which are unknown. Many of the ones known to me are administered by the Stanford Office of Technology and Licensing. + +The good news is that large hunks of the techniques used here are public domain. To avoid subtle legal issues, I'll not state what's freely useable here, but I'll try to note within the various classes where certain things are likely to be protected by patents. + +/******************************************************/ + diff --git a/README-Win.txt b/README-Win.txt new file mode 100644 index 0000000..a25a873 --- /dev/null +++ b/README-Win.txt @@ -0,0 +1,65 @@ +STK98v2: A ToolKit of Audio Synthesis Classes and Instruments in C++ + +By Perry R. Cook, 1995-98 +With recent help by Gary P. Scavone + +Please read the file README.txt for more general STK information. + +Realtime sound output under Win95 is supported using either the Direct Sound (dsound.lib) API or the old WinMM (winmm.lib) API. The Direct Sound version appears to well out-perform the older API. All new versions of Win95/NT come with the Direct Sound library, but early versions did not. If you have trouble running the distributed executables (compiled for Direct Sound API), then you probably don't have Direct Sound installed on your system. You can download the necessary Direct Sound stuff from Microsoft's WWW pages (http://www.microsoft.com/directx/download.asp). If all else fails, you should be able to compile using the winmm.lib routines ... more latency, but at least it will work. + +Realtime MIDI input is supported using the winmm.lib API. + +A Visual C++ workspace has been created for STK98, with two projects - syntmono and MD2SKINI. Everything has already been configured for you. The intermediate .obj files will be written to either the "Release" or "Debug" directories, but the executable files will be written to the main STK98 directory (where they need to be for proper execution). If you should somehow lose or hose the VC++ workspace file (STK98v2.dsw), then you will have to do a LOT of configuring to recreate it ... it's probably easier just to download the distribution again from our WWW sites. Anyway, for your benefit and mine, here is a list of things that need to be added to the various "Project Settings": + +1. Under General: Set "Output files:" to (this will put the executable in the main STK directory. + +2. Under C/C++ > Code Generation: Set "Use run-time library:" to Multithreaded. + +3. Under Link > General: Add winmm.lib, dsound.lib, and Wsock32.lib to the end of the Object/library modules list. + +4. Add all the necessary files to the project. + +NOTE: For some of my personal STK files, I've had trouble compiling in VC++ with the "Optimize Speed" optimization setting (in Project Settings -> C/C++ -> Optimizations:). The files compile, but don't work the way they should when executed. These same files, however, have worked when compiled with the "Default" optimization setting. I've heard that there are bugs with some of these optimization settings. + +Remember that items 1-3 above need to be done for each project and for each configuration. There might be an easy way to make global changes, but I couldn't figure it out. + +To use the Tcl/Tk GUIs, you will have to install Tcl/Tk. I got version 8.0 and it works very well (and installed easily). The distribution is available on the WWW and is free. + +In order for socketing to work, it is necessary to have the TCP protocol installed on your computer. This can be done from the "Network" control panel. + +Finally, to use it all - + +PLAY SKINI SCOREFILES IN REALTIME: + + syntmono Clarinet -r < scores/streetsf.ski + +USE TCL/TK GUIs FOR REALTIME CONTROL: + +1. Open a DOS console window and start syntmono (eg. syntmono Clarinet -r -i). + +2. Double click on a Tcl/Tk file in TCLSpecs (eg. TCLPhys.tcl) from the Windows Explorer to start the GUI. Select the "communications" menu item and "Socket" and make the connection. + +3. Start moving the sliders to control the instrument. + +USE REALTIME MIDI INPUT FOR CONTROL: + +1. Open a DOS console window and start syntmono (eg. syntmono Clarinet -r -i). + +2. Open another DOS console window and start MD2SKINI (assumes you already have + MIDI setup correctly for your computer). + + +/******************************************************/ + +Legal and Ethical: + +This software was designed and created to be made publicly available for free, primarily for academic purposes, so if you use it, pass it on with this documentation, and for free. + +If you make a million dollars with it, give me some. If you make compositions with it, put me in the program notes. + +Some of the concepts are covered by various patents, some known to me and likely others which are unknown. Many of the ones known to me are administered by the Stanford Office of Technology and Licensing. + +The good news is that large hunks of the techniques used here are public domain. To avoid subtle legal issues, I'll not state what's freely useable here, but I'll try to note within the various classes where certain things are likely to be protected by patents. + +/******************************************************/ + diff --git a/README.txt b/README.txt index e883554..368ce5f 100644 --- a/README.txt +++ b/README.txt @@ -1,54 +1,37 @@ -TK96CPP -A ToolKit of Audio Synthesis Classes - and Instruments in C++ -Perry Cook, 1995-96 +STK98v2: A ToolKit of Audio Synthesis Classes and Instruments in C++ -Please read the Legal and Ethical notes at the -bottom of this document. +By Perry R. Cook, 1995-98 +With recent help by Gary P. Scavone -For instant fun, if you get it to compile (see -below) type TestAllNext or TestAllSGIRT. The -former makes sound files of each instrument and -saves them under the instrument name. The latter -plays in real time from a SKINI scorefile. +Please read the Legal and Ethical notes at the bottom of this document. -For even more potential fun, try the GUI and MIDI -interface demos in the directory TCLSpecs. MIDI -is SGI specific for today, look for more support -later. TCL works on SGI, maybe elsewhere, but -you must have and install Tcl/TK. +STK has undergone a large number of revisions, changes, and additions since its initial release in 1996. With this version 2.0 release, it has been completely ported to Linux and Win95 (not tested on WinNT but should work), as well as SGI and NeXTStep (no real time capabilities under NeXTStep). See the individual README's (eg. README-linux) for platform specific information and system requirements. In general, you will have to specify your system type in Object.h and then use either the Makefile (Unix platforms) or the VC++ workspace file (STK98v2.dsw) to compile the code. -For more documentation on this ToolKit, the classes, -etc, read the file HIERARCH.txt and the individual -class definitions. +STK now features realtime sound output and MIDI input under SGI, Linux (OSS), and Win95/NT (Direct Sound and Winmm routines). It is also possible to generate simultaneous .snd, .wav, and .mat (Matlab) output file types, as well as SKINI scorefiles using MD2SKINI. -SGI vs. NeXT vs. Intel vs. the world: -See Object.h and Makefile for machine-specific -items. +Two primary executables are created during compilation - syntmono and MD2SKINI. Syntmono is the core STK synthesis server. All distributed STK instruments are run using syntmono. MD2SKINI takes raw MIDI input, converts it to SKINI format, and outputs the result to stdout or a socket port ID (under Windoze). Control data (in the form of SKINI messages) can be fed to syntmono through three principal means - SKINI scorefiles, MD2SKINI output, and Tcl/Tk GUIs. A variety of SKINI scorefiles are distributed with STK98 and can be found in the "scores" directory. Under all platforms, a scorefile can be piped or redirected to syntmono in the following way: -Initial public release. Some objects still beta. + more scores/streetsf.ski | syntmono Clarinet -r +or + syntmono Clarinet -r < scores/streetsf.ski -This whole world was created with no particular -hardware in mind. These examples are intended -to be tutorial in nature, as a platform for the -continuation of my research, and as a possible -starting point for a software synthesis system. -The basic motivation was to create the necessary -unit generators to do the synthesis, processing, -and control that I want to do and teach about. -Little thought for optimization was given (see -Object.cpp), and therefore improvements, especially -speed enhancements, should be possible with -these classes. It was written with some basic -concepts in mind about how to let compilers -optimize (see Adrian Freed's home page for some -nice experience-based thoughts on that topic). +A number of Tcl/Tk GUIs are provided in the "TCLSpecs" directory, though you will have to install Tcl/Tk version 8.0 or higher on your system to use them (older versions of Tcl/Tk under Linux seem to be more forgiving than under IRIX). Realtime SKINI control data (via MD2SKINI or GUIs) can be piped to syntmono on Unix platforms and perhaps under WinNT in the following way: -Your question at this point might be, "But Perry, -with CMix, CMusic, CSound, CShells, CMonkeys, etc. -already cluttering the landscape, why a new set -of stupid C functions for music synthesis and -processing?" The answers lie below. + MD2SKINI | syntmono Clarinet -r -i +or + wish < TCLSpecs/TCLPhys.tcl | syntmono Clarinet -r -i + +It is not possible to use realtime pipes under Win95, so socket communication is used instead. Perhaps in the future, all STK communications will be conducted using sockets. For socket communication, it is necessary to first start the syntmono socket server. For the time being, a default (hardwired) socket port of 2001 is being used by syntmono. After syntmono is running (and waiting for a socket client connection), either MD2SKINI or a Tcl/Tk GUI can be started. When using the GUI, it is necessary to invoke the "communications" menu item and select "socket" to establish the connection. + +For more documentation on this ToolKit, the classes, etc, read the file HIERARCH.txt and the individual class definitions. Also check the platform specific README's for specific system requirements. + +You probably already guessed this, but just to be sure, we don't guarantee anything works. :-) It's free ... what do you expect? If you find a bug, please let us know and we'll try to correct it. You can also make suggestions, but again, no guarantees. Send email to prc@cs.princeton.edu and gary@ccrma.stanford.edu. + +Perry's comments from the original distribution: + +This whole world was created with no particular hardware in mind. These examples are intended to be tutorial in nature, as a platform for the continuation of my research, and as a possible starting point for a software synthesis system. The basic motivation was to create the necessary unit generators to do the synthesis, processing, and control that I want to do and teach about. Little thought for optimization was given (see Object.cpp), and therefore improvements, especially speed enhancements, should be possible with these classes. It was written with some basic concepts in mind about how to let compilers optimize. + +Your question at this point might be, "But Perry, with CMix, CMusic, CSound, CShells, CMonkeys, etc. already cluttering the landscape, why a new set of stupid C functions for music synthesis and processing?" The answers lie below. 1) I needed to port many of the things I've done into something which is generic enough to port @@ -91,27 +74,18 @@ processing?" The answers lie below. 6) More rationalizations to follow . . . -*********************************************************** + +/******************************************************/ + Legal and Ethical: -This software was designed and created to be -made publicly available for free, primarily for -academic purposes, so if you use it, pass it on -with this documentation, and for free. +This software was designed and created to be made publicly available for free, primarily for academic purposes, so if you use it, pass it on with this documentation, and for free. -If you make a million dollars with it, give me some. -If you make compositions with it, put me in the -program notes. +If you make a million dollars with it, give me some. If you make compositions with it, put me in the program notes. -Some of the concepts are covered by various patents, -some known to me and likely others which are unknown. -Many of the ones known to me are administered by the -Stanford Office of Technology and Licensing. +Some of the concepts are covered by various patents, some known to me and likely others which are unknown. Many of the ones known to me are administered by the Stanford Office of Technology and Licensing. + +The good news is that large hunks of the techniques used here are public domain. To avoid subtle legal issues, I'll not state what's freely useable here, but I'll try to note within the various classes where certain things are likely to be protected by patents. + +/******************************************************/ -The good news is that large hunks of the techniques -used here are public domain. To avoid subtle legal -issues, I'll not state what's freely useable here, -but I'll try to note within the various classes -where certain things are likely to be protected by -patents. -*********************************************************** diff --git a/RTSoundIO.cpp b/RTSoundIO.cpp new file mode 100644 index 0000000..d7f273c --- /dev/null +++ b/RTSoundIO.cpp @@ -0,0 +1,466 @@ +/******************************************/ +/* RTSoundIO.cpp */ +/* Realtime Sound I/O Object for STK, */ +/* by Gary P. Scavone, 1998. */ +/* Based in part on code by Doug */ +/* Scott (SGI), Tim Stilson (Linux), */ +/* Bill Putnam (Win Wav), and */ +/* R. Marsanyi (DirectSound). */ +/* */ +/* At the moment, this object only */ +/* handles realtime sound output, though */ +/* input code can go here when someone */ +/* decides they need it (and writes it). */ +/* */ +/* This object provides a standard API */ +/* across all platforms for STK realtime */ +/* sound output. At the moment, this */ +/* object is only used by RTWvOut. */ +/******************************************/ + +#include "RTSoundIO.h" + +#if defined(__SGI_REALTIME_) + +#include +#include + +RTSoundIO :: RTSoundIO(MY_FLOAT srate, int channels) +{ + ALconfig audio_port_config; + int lookaheadbuffers = 8; // number of lookahead buffers + long pvbuf[2]; + int nbuf, totalBufSize; + + audio_port_config = ALnewconfig(); + if(ALsetchannels(audio_port_config, channels) < 0) { + fprintf(stderr,"Cannot initialize audio port\n"); + exit(0); + } + + /* Size the output queue */ + nbuf = (channels == 2) ? lookaheadbuffers : lookaheadbuffers/2; + totalBufSize = RT_BUFFER_SIZE * nbuf; + if(ALsetqueuesize(audio_port_config, totalBufSize) < 0) { + fprintf(stderr,"Cannot initialize audio port\n"); + exit(0); + } + + if(audio_port) ALcloseport(audio_port); + audio_port = ALopenport("sgi.driver", "w", audio_port_config); + if(!audio_port) { + fprintf(stderr,"Cannot initialize audio port\n"); + exit(0); + } + ALfreeconfig(audio_port_config); + audio_port_config = 0; + + pvbuf[0] = AL_OUTPUT_RATE; + pvbuf[1] = (long) srate; + ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2); /* set output SR */ + /* tell port to accept refill at buffers - 1 */ + ALsetfillpoint(audio_port,RT_BUFFER_SIZE * (lookaheadbuffers - 1)); +} + +RTSoundIO :: ~RTSoundIO() +{ + if(audio_port) ALcloseport(audio_port); + audio_port=0; +} + +int RTSoundIO :: playBuffer(short *buf, int bufsize) +{ + ALwritesamps(audio_port, buf, bufsize); + return 0; +} + +#elif defined(__USS_REALTIME_) + +#define ABS(x) ((x < 0) ? (-x) : (x)) + +#include +#include +#include +#include +#include + +RTSoundIO :: RTSoundIO(MY_FLOAT srate, int channels) +{ + int lookaheadbuffers = 8; // number of lookahead buffers + int nbuf, totalBufSize; + + char DEVICE_NAME[100]; + int format; + int stereo; /* 0=mono, 1=stereo */ + int stereoset; + int speed; + int BUFFER_SIZE_LOG; + int fragsize; + + BUFFER_SIZE_LOG = (int)(log10((double)RT_BUFFER_SIZE)/log10(2.0)); + + if (channels > 2) + { + fprintf(stderr,"Unsupported # of output channels!\n"); + exit(0); + } + + if (channels == 2) stereo = 1; + else stereo = 0; + + strcpy(DEVICE_NAME,"/dev/dspW"); + + if ((audio_fd = open(DEVICE_NAME, O_WRONLY, 0)) == -1) + { /* Opening device failed */ + fprintf(stderr,"Cannot open audio device: %s\n",DEVICE_NAME); + exit(0); + } + + /* Size the output queue */ + nbuf = (channels == 2) ? lookaheadbuffers : lookaheadbuffers/2; + totalBufSize = RT_BUFFER_SIZE * nbuf; + + fragsize = (nbuf << 16) + BUFFER_SIZE_LOG; + if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &fragsize)) + { + close(audio_fd); + fprintf(stderr,"Error setting audio buffer size!\n"); + exit(0); + } + + format = AFMT_S16_LE; + if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format)==-1) + { /* Fatal error */ + close(audio_fd); + fprintf(stderr,"SNDCTL_DSP_SETFMT error\n"); + exit(0); + } + + if (format != AFMT_S16_LE) + { + close(audio_fd); + fprintf(stderr,"Soundcard doesn't support 16-bit signed LE format\n"); + exit(0); + } + + stereoset = stereo; + if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereoset)==-1) + { /* Fatal error */ + close(audio_fd); + fprintf(stderr,"SNDCTL_DSP_STEREO\n"); + exit(0); + } + + if (stereoset != stereo) + { + close(audio_fd); + fprintf(stderr,"The sound card did not set correct stereo mode\n"); + exit(0); + } + + speed = (int)srate; + if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1) + { /* Fatal error */ + close(audio_fd); + fprintf(stderr,"SNDCTL_DSP_SPEED\n"); + exit(0); + } + + if (ABS(speed - srate)>100) + { + close(audio_fd); + fprintf(stderr,"The device doesn't support the requested speed.\n"); + exit(0); + } +} + +RTSoundIO :: ~RTSoundIO() +{ + if(audio_fd) close(audio_fd); + audio_fd=0; +} + +int RTSoundIO :: playBuffer(short *buf, int bufsize) +{ + /* The OSS write() routine takes the buffer size in bytes, thus the + multiplication by two. + */ + int len; + + if ((len = write(audio_fd, buf, 2*bufsize)) == -1) + { + fprintf(stderr,"Audio write error!\n"); + return -1; + } + return 0; +} + +#elif defined(__WINDS_REALTIME_) + +#include + +RTSoundIO :: RTSoundIO(MY_FLOAT srate, int channels) +{ + HRESULT result; + HWND hWnd; + DWORD dwDataLen; + WAVEFORMATEX wfFormat; + DSBUFFERDESC dsbdDesc; + BYTE *pDSBuffData; + + /* Initialize pointers to NULL */ + m_pDirectSound = NULL; + m_pDSBuffer = NULL; + + /* Create the DS object */ + if ((result = DirectSoundCreate(NULL, &m_pDirectSound, NULL)) != DS_OK) + { + fprintf(stderr,"Cannot open default sound device!!\n"); + exit(0); + } + hWnd = GetForegroundWindow(); + if ((result = m_pDirectSound->SetCooperativeLevel(hWnd, DSSCL_EXCLUSIVE)) != DS_OK) + { + fprintf(stderr,"DS Constructor: couldn't set cooperative level!\n"); + exit(0); + } + + /* Initialize the DS buffer */ + + /* Define the wave format structure */ + wfFormat.wFormatTag = WAVE_FORMAT_PCM; + wfFormat.nChannels = channels; + wfFormat.nSamplesPerSec = (unsigned long) srate; + wfFormat.wBitsPerSample = 8 * sizeof(short); + wfFormat.nBlockAlign = wfFormat.nChannels * wfFormat.wBitsPerSample / 8; + wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign; + wfFormat.cbSize = 0; + + /* Setup the DS buffer description */ + m_cbBufSize = RT_BUFFER_SIZE * sizeof(short) * 8; + ZeroMemory(&dsbdDesc, sizeof(DSBUFFERDESC)); + dsbdDesc.dwSize = sizeof(DSBUFFERDESC); + dsbdDesc.dwFlags = DSBCAPS_GLOBALFOCUS; + dsbdDesc.dwBufferBytes = m_cbBufSize; + dsbdDesc.lpwfxFormat = &wfFormat; + + /* Create the DS buffer */ + if ((result = m_pDirectSound->CreateSoundBuffer(&dsbdDesc, + &m_pDSBuffer, NULL)) != DS_OK) + { + fprintf(stderr,"DS Constructor: couldn't create sound buffer!\n"); + exit(0); + } + + /* Lock the DS buffer */ + if ((result = m_pDSBuffer->Lock(0, m_cbBufSize, (LPLPVOID)&pDSBuffData, + &dwDataLen, NULL, NULL, 0)) != DS_OK) + { + fprintf(stderr,"DS Constructor: couldn't lock sound buffer!\n"); + exit(0); + } + + /* Zero the DS buffer */ + ZeroMemory(pDSBuffData, dwDataLen); + + /* Unlock the DS buffer */ + if ((result = m_pDSBuffer->Unlock(pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) + { + fprintf(stderr,"DS Constructor: couldn't unlock sound buffer!\n"); + exit(0); + } + + m_cbBufOffset = 0; // reset last write position to start of buffer + + /* Start the buffer playback */ + if ((result = m_pDSBuffer->Play( 0, 0, DSBPLAY_LOOPING ) != DS_OK)) + { + fprintf(stderr,"DS Constructor: couldn't play sound buffer!\n"); + exit(0); + } +} + +RTSoundIO :: ~RTSoundIO() +{ + // Cleanup the sound buffer + if (m_pDSBuffer) + { + m_pDSBuffer->Stop(); + m_pDSBuffer->Release(); + m_pDSBuffer = NULL; + } + + // Cleanup the DS object + if (m_pDirectSound) + { + m_pDirectSound->Release(); + m_pDirectSound = NULL; + } +} + +int RTSoundIO :: playBuffer(short *buf, int bufsize) +{ + HRESULT hr; + DWORD status; + LPVOID lpbuf1 = NULL; + LPVOID lpbuf2 = NULL; + DWORD dwsize1 = 0; + DWORD dwsize2 = 0; + DWORD playPos, safePos, endWrite; + DWORD millis; + + // Should be playing, right? + hr = m_pDSBuffer->GetStatus( &status ); + if (!(status && DSBSTATUS_PLAYING)) + { + printf("Buffer not playing!\n"); + } + + // Sleep until we have enough room in buffer. + hr = m_pDSBuffer->GetCurrentPosition( &playPos, &safePos ); + if( hr != DS_OK ) return -1; + if( playPos < m_cbBufOffset ) playPos += m_cbBufSize; // unwrap offset + + endWrite = m_cbBufOffset + RT_BUFFER_SIZE * sizeof(short); + while ( playPos < endWrite ) { + // Calculate number of milliseconds until we will have room, as + // time = distance * (milliseconds/second) / ((bytes/sample) * (samples/second)), + // rounded up. + millis = (DWORD) (1.0 + ((endWrite - playPos) * 1000.0) / ( sizeof(short) * SRATE)); + + // Sleep for that long + Sleep( millis ); + + // Wake up, find out where we are now + hr = m_pDSBuffer->GetCurrentPosition( &playPos, &safePos ); + if( hr != DS_OK ) return -1; + if( playPos < m_cbBufOffset ) playPos += m_cbBufSize; // unwrap offset + } + + // Lock free space in the DS + hr = m_pDSBuffer->Lock (m_cbBufOffset, RT_BUFFER_SIZE * sizeof(short), &lpbuf1, &dwsize1, &lpbuf2, &dwsize2, 0); + if (hr == DS_OK) + { + // Copy the buffer into the DS + CopyMemory(lpbuf1, buf, dwsize1); + if(NULL != lpbuf2) CopyMemory(lpbuf2, buf+dwsize1, dwsize2); + + // Update our buffer offset and unlock sound buffer + m_cbBufOffset = (m_cbBufOffset + dwsize1 + dwsize2) % m_cbBufSize; + m_pDSBuffer->Unlock (lpbuf1, dwsize1, lpbuf2, dwsize2); + } + return 0; +} + +#elif defined(__WINMM_REALTIME_) + +#include + +#define FRAMETIME (long) (1000.0 * RT_BUFFER_SIZE / SRATE) + +RTSoundIO :: RTSoundIO(MY_FLOAT srate, int channels) +{ + MMRESULT result; + WAVEFORMATEX wfx; + int bufferSize = RT_BUFFER_SIZE; + + audioPort = NULL; + + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.nChannels = channels; + wfx.nSamplesPerSec = (unsigned long) srate; + wfx.nBlockAlign = sizeof(short) * channels; + wfx.nAvgBytesPerSec = (unsigned long) srate * wfx.nBlockAlign; + wfx.wBitsPerSample = 8 * sizeof(short); + wfx.cbSize = 0; + + /* Open a Wave Out device using the wave mapper to guide us */ + result = waveOutOpen(&audioPort,WAVE_MAPPER,&wfx,(DWORD)NULL,(DWORD)NULL,CALLBACK_NULL); + if (result != MMSYSERR_NOERROR) { + fprintf(stderr,"Cannot open audio port!\n"); + exit(0); + } + + for( outBufNum = 0; outBufNum < (UINT)NUM_OUT_BUFFERS; outBufNum++ ) + { + /* set up a couple of wave headers */ + whOut[outBufNum].lpData = (LPSTR)calloc(channels*bufferSize, sizeof(short)); + if (whOut[outBufNum].lpData == NULL){ + waveOutClose( audioPort ); + fprintf(stderr,"Error initializing audio buffers!\n"); + exit(0); + } + whOut[outBufNum].dwBufferLength = channels*bufferSize*sizeof(short); + whOut[outBufNum].dwBytesRecorded = 0; + whOut[outBufNum].dwUser = 1; + //whOut[outBufNum].dwFlags = 0; + whOut[outBufNum].dwFlags = WHDR_DONE; + whOut[outBufNum].dwLoops = 0; + whOut[outBufNum].lpNext = NULL; + whOut[outBufNum].reserved = 0; + } + + /* Write the first buffer out to get things going */ + outBufNum = 0; + result = waveOutPrepareHeader(audioPort, &whOut[outBufNum],sizeof(WAVEHDR)); + result = waveOutWrite(audioPort, &whOut[outBufNum], sizeof(WAVEHDR)); + + /* Keep track of time so that we know how long we can sleep */ + lastWriteTime = timeGetTime(); +} + +RTSoundIO :: ~RTSoundIO() +{ + MMRESULT result; + long timeToGo; + + /* Close Audio Port */ + if (audioPort != NULL) { + result = waveOutReset(audioPort); + for( outBufNum = 0; outBufNum < (UINT)NUM_OUT_BUFFERS; outBufNum++ ) + { + /* Loop until the next waveheader indicates that we are done */ + while( !(whOut[outBufNum].dwFlags & WHDR_DONE) ) + { + //printf("."); + timeToGo = (long) (FRAMETIME - (timeGetTime()-lastWriteTime)); + if( timeToGo > 0 ) Sleep( (long) timeToGo ); + } + /* Unprepare the header */ + result = waveOutUnprepareHeader(audioPort, &whOut[outBufNum],sizeof(WAVEHDR)); + if (whOut[outBufNum].lpData != NULL) { + free(whOut[outBufNum].lpData); + whOut[outBufNum].lpData = NULL; + } + } + result = waveOutClose(audioPort); + } +} + +int RTSoundIO :: playBuffer(short *buf, int bufsize) +{ + MMRESULT result; + long timeToGo; + + outBufNum++; + if( outBufNum >= (UINT)NUM_OUT_BUFFERS ) outBufNum = 0; + + /* Loop until the next waveheader indicates that we are done */ + while( !(whOut[outBufNum].dwFlags & WHDR_DONE) ) + { + //printf("."); + timeToGo = (long) (FRAMETIME - (timeGetTime()-lastWriteTime)); + //timeToGo = (long) (FRAMETIME * 0.5); + if( timeToGo > 0 ) Sleep( (long) timeToGo ); + } + result = waveOutUnprepareHeader(audioPort, &whOut[outBufNum], sizeof(WAVEHDR)); + + memcpy( whOut[outBufNum].lpData, buf, bufsize*sizeof(short)); + result = waveOutPrepareHeader(audioPort, &whOut[outBufNum], sizeof(WAVEHDR)); + result = waveOutWrite(audioPort, &whOut[outBufNum], sizeof(WAVEHDR)); + lastWriteTime = timeGetTime(); + + return 0; +} + +#endif diff --git a/RTSoundIO.h b/RTSoundIO.h new file mode 100644 index 0000000..5b1a466 --- /dev/null +++ b/RTSoundIO.h @@ -0,0 +1,61 @@ +/******************************************/ +/* RTSoundIO.h */ +/* Realtime Sound I/O Object for STK, */ +/* by Gary P. Scavone, 1998. */ +/* Based in part on code by Doug */ +/* Scott (SGI), Tim Stilson (Linux), */ +/* Bill Putnam (Win Wav), and */ +/* R. Marsanyi (DirectSound). */ +/* */ +/* At the moment, this object only */ +/* handles realtime sound output, though */ +/* input code can go here when someone */ +/* decides they need it (and writes it). */ +/* */ +/* This object provides a standard API */ +/* across all platforms for STK realtime */ +/* sound output. At the moment, this */ +/* object is only used by RTWvOut. */ +/******************************************/ + +#if !defined(__RTSOUNDIO_h) +#define __RTSOUNDIO_h + +#include "Object.h" + +#if defined(__SGI_REALTIME_) + #include +#elif defined(__WINDS_REALTIME_) + #include + #include "include/dsound.h" +#elif defined(__WINMM_REALTIME_) + #include + #include + #define NUM_OUT_BUFFERS 6 +#endif + +class RTSoundIO : public Object +{ + protected: +#if defined(__SGI_REALTIME_) + ALport audio_port; +#elif defined(__USS_REALTIME_) + int audio_fd; +#elif defined(__WINDS_REALTIME_) + LPDIRECTSOUND m_pDirectSound; + LPDIRECTSOUNDBUFFER m_pDSBuffer; + UINT m_cbBufOffset; + UINT m_cbBufSize; +#elif defined(__WINMM_REALTIME_) + HWAVEOUT audioPort; + WAVEHDR whOut[NUM_OUT_BUFFERS]; + UINT outBufNum; + DWORD lastWriteTime; +#endif + public: + RTSoundIO(MY_FLOAT srate, int channels); + ~RTSoundIO(); + int playBuffer(short *buf, int bufsize); +}; + +#endif diff --git a/RTWvOut.cpp b/RTWvOut.cpp new file mode 100644 index 0000000..8e657b5 --- /dev/null +++ b/RTWvOut.cpp @@ -0,0 +1,56 @@ +/*******************************************/ +/* Raw Wave File Output Class, */ +/* by Perry R. Cook, 1995-96 */ +/* This version opens a mono NeXT .snd */ +/* file 16bit data at 22KHz, and */ +/* pokes buffers of samples into it. */ +/*******************************************/ + +/*******************************************/ +/* SGI Real-Time Wave File Output Class, */ +/* by Perry R. Cook, 1996 */ +/* This Object can opens the SGI soundout */ +/* device, and pokes buffers of samples */ +/* into it. The real code that does the */ +/* is from Doug Scott of SGI. */ +/*******************************************/ + +/*******************************************/ +/* USS Real-Time Wave File Output Class, */ +/* by Tim Stilson, 1996 */ +/* based on code by Perry R. Cook, 1996 */ +/* This Object opens the USS sound output */ +/* device, and pokes buffers of samples */ +/* into it. */ +/*******************************************/ + +#include "RTWvOut.h" + +RTWvOut :: RTWvOut() +{ + soundIO = new RTSoundIO(SRATE, 1); + counter = 0; +} + +RTWvOut :: ~RTWvOut() +{ + soundIO->playBuffer(data,counter); + counter = 0; + while (counterplayBuffer(data,counter); + soundIO->playBuffer(data,counter); // Are these extra writes necessary in USS? + soundIO->playBuffer(data,counter); + delete soundIO; +} + +void RTWvOut :: tick(MY_FLOAT sample) +{ + + data[counter++] = (short) (sample * 32000.0); + if (counter >= RT_BUFFER_SIZE) { + soundIO->playBuffer(data,counter); + counter = 0; + } +} diff --git a/RTWvOut.h b/RTWvOut.h new file mode 100644 index 0000000..ab54e31 --- /dev/null +++ b/RTWvOut.h @@ -0,0 +1,46 @@ +/*******************************************/ +/* Real-Time Output Class, */ +/* by Perry R. Cook, 1995-96 */ +/* Separated into just realtime by */ +/* Tim Stilson, 1996 */ +/*******************************************/ + +/*******************************************/ +/* SGI Real-Time Wave File Output Class, */ +/* by Perry R. Cook, 1995-96 */ +/* This Object can opens the SGI soundout */ +/* device, and pokes buffers of samples */ +/* into it. The real code that does the */ +/* is originally from Doug Scott of SGI. */ +/*******************************************/ + +/*******************************************/ +/* USS Real-Time Wave File Output Class, */ +/* by Tim Stilson, 1996 */ +/* based on code by Perry R. Cook, 1996 */ +/* This Object opens the USS sound output */ +/* device, and pokes buffers of samples */ +/* into it. */ +/*******************************************/ + + +#include "Object.h" +#include "WvOut.h" +#include "RTSoundIO.h" + +#if !defined(__RTWvOut_h) +#define __RTWvOut_h + +class RTWvOut : public WvOut +{ + protected: + RTSoundIO *soundIO; + short data[RT_BUFFER_SIZE]; + long counter; + public: + RTWvOut(); + ~RTWvOut(); + void tick(MY_FLOAT sample); +}; + +#endif // defined(__RTWvOut_h) diff --git a/RawLoop.cpp b/RawLoop.cpp index c2c0c5c..19c69d3 100644 --- a/RawLoop.cpp +++ b/RawLoop.cpp @@ -1,3 +1,4 @@ + /*******************************************/ /* Raw Looped Soundfile Class, */ /* by Perry R. Cook, 1995-96 */ @@ -9,6 +10,8 @@ #include "RawLoop.h" +#include "swapstuf.h" + RawLoop :: RawLoop(char *fileName) { long i; @@ -26,14 +29,17 @@ RawLoop :: RawLoop(char *fileName) data = (MY_FLOAT *) malloc(MY_FLOAT_SIZE * (length + 1)); i = 0; while (fread(&temp,2,1,fd)) { + #ifdef __LITTLE_ENDIAN__ + temp = SwapShort (temp); + #endif data[i] = temp; i++; } data[length] = data[0]; fclose(fd); - time = 0.0; - phaseOffset = 0.0; - rate = 1.0; + time = (MY_FLOAT) 0.0; + phaseOffset = (MY_FLOAT) 0.0; + rate = (MY_FLOAT) 1.0; } RawLoop :: ~RawLoop() @@ -43,24 +49,24 @@ RawLoop :: ~RawLoop() void RawLoop :: reset() { - time = 0.0; - lastOutput = 0.0; + time = (MY_FLOAT) 0.0; + lastOutput = (MY_FLOAT) 0.0; } void RawLoop :: normalize() { - this->normalize(1.0); + this->normalize((MY_FLOAT) 1.0); } void RawLoop :: normalize(MY_FLOAT newPeak) { long i; - MY_FLOAT max = 0.0; + MY_FLOAT max = (MY_FLOAT) 0.0; for (i=0;i<=length;i++) if (fabs(data[i]) > max) - max = fabs(data[i]); + max = (MY_FLOAT) fabs((double) data[i]); if (max > 0.0) { - max = 1.0 / max; + max = (MY_FLOAT) 1.0 / max; max *= newPeak; for (i=0;i<=length;i++) data[i] *= max; diff --git a/RawWave.cpp b/RawWave.cpp index e9aa5e4..048cf4c 100644 --- a/RawWave.cpp +++ b/RawWave.cpp @@ -9,6 +9,8 @@ #include "RawWave.h" +#include "swapstuf.h" + RawWave :: RawWave(char *fileName) { long i; @@ -21,21 +23,25 @@ RawWave :: RawWave(char *fileName) } i = 0; while (fread(&temp,2,1,fd)) i++; + length = i; fseek(fd,0,0); data = (MY_FLOAT *) malloc(MY_FLOAT_SIZE * (length + 1)); myData = 1; i = 0; while (fread(&temp,2,1,fd)) { + #ifdef __LITTLE_ENDIAN__ + temp = SwapShort (temp); + #endif data[i] = temp; i++; } data[length] = data[length-1]; fclose(fd); looping = 0; - time = length; - phaseOffset = 0.0; - rate = 1.0; + time = (MY_FLOAT) length; + phaseOffset = (MY_FLOAT) 0.0; + rate = (MY_FLOAT) 1.0; allDone = 0; } @@ -46,9 +52,9 @@ RawWave :: RawWave(MY_FLOAT *someData, long aLength) data = someData; myData = 0; looping = 0; - time = 0.0; - phaseOffset = 0.0; - rate = 1.0; + time = (MY_FLOAT) 0.0; + phaseOffset = (MY_FLOAT) 0.0; + rate = (MY_FLOAT) 1.0; } RawWave :: ~RawWave() @@ -61,25 +67,25 @@ RawWave :: ~RawWave() void RawWave :: reset() { - time = 0.0; - lastOutput = 0.0; + time = (MY_FLOAT) 0.0; + lastOutput = (MY_FLOAT) 0.0; allDone = 0; } void RawWave :: normalize() { - this->normalize(1.0); + this->normalize((MY_FLOAT) 1.0); } void RawWave :: normalize(MY_FLOAT newPeak) { long i; - MY_FLOAT max = 0.0; + MY_FLOAT max = (MY_FLOAT) 0.0; for (i=0;i<=length;i++) if (fabs(data[i]) > max) - max = fabs(data[i]); + max = (MY_FLOAT) fabs(data[i]); if (max > 0.0) { - max = 1.0 / max; + max = (MY_FLOAT) 1.0 / max; max *= newPeak; for (i=0;i<=length;i++) data[i] *= max; @@ -93,7 +99,7 @@ void RawWave :: setRate(MY_FLOAT aRate) void RawWave :: setFreq(MY_FLOAT aFreq) { - rate = length * ONE_OVER_SRATE * aFreq; + rate = length * (MY_FLOAT) ONE_OVER_SRATE * aFreq; } void RawWave :: addTime(MY_FLOAT aTime) /* Add an absolute time */ @@ -113,7 +119,7 @@ void RawWave :: addPhaseOffset(MY_FLOAT anAngle) void RawWave :: setLooping(int aLoopStatus) { - time = 0; + time = (MY_FLOAT) 0; looping = aLoopStatus; if (looping) data[length] = data[0]; } @@ -155,11 +161,11 @@ int RawWave :: informTick() } else { if (time >= length) { /* Check for end of sound */ - time = length-1; /* stick at end */ + time = length-(MY_FLOAT) 1; /* stick at end */ allDone = 1; /* Information for one-shot use */ } else if (time < 0.0) /* Check for end of sound */ - time = 0.0; /* stick at beg */ + time = (MY_FLOAT) 0.0; /* stick at beg */ } temp_time = time; @@ -174,9 +180,9 @@ int RawWave :: informTick() } else { if (temp_time >= length) /* Check for end of sound */ - temp_time = length-1; /* stick at end */ + temp_time = length - (MY_FLOAT) 1; /* stick at end */ else if (temp_time < 0.0) /* check for end of sound */ - temp_time = 0.0; /* stick at beg */ + temp_time = (MY_FLOAT) 0.0; /* stick at beg */ } } diff --git a/RawWvIn.cpp b/RawWvIn.cpp index fa4a36c..8e02693 100644 --- a/RawWvIn.cpp +++ b/RawWvIn.cpp @@ -14,125 +14,140 @@ /*******************************************/ #include "RawWvIn.h" +#include "swapstuf.h" RawWvIn :: RawWvIn(char *fileName) { - long i; + long i; - strcpy(fileNm,fileName); + strcpy(fileNm,fileName); - myFile = fopen(fileNm,"rb"); - if (!myFile) { - printf("Couldn't find soundfile %s !!!!!!!!\n",fileName); - exit(0); - } + myFile = fopen(fileNm,"rb"); + if (!myFile) { + printf("Couldn't find soundfile %s !!!!!!!!\n",fileName); + exit(0); + } - i = 0; - while (fread(&data,2,1,myFile)) i++; - length = i; - fseek(myFile,0,0); - time = 0.0; - rate = 1.0; - lastTime = 0; - finished = 0; - gain = 1.0; - lastOutput = 0.0; + i = 0; + while (fread(&data,2,1,myFile)) i++; + length = i; + fseek(myFile,0,0); + time = (MY_FLOAT) 0.0; + rate = (MY_FLOAT) 1.0; + lastTime = 0; + finished = 0; + gain = (MY_FLOAT) 1.0; + lastOutput = (MY_FLOAT) 0.0; } RawWvIn :: ~RawWvIn() { - this->finish(); + this->finish(); } void RawWvIn :: reset() { - if (finished) { - myFile = fopen(fileNm,"rb"); - } - fseek(myFile,0,0); + if (finished) { + myFile = fopen(fileNm,"rb"); + } + fseek(myFile,0,0); - printf("Resetting\n"); - time = 0.0; - lastTime = 0; - finished = 0; - lastOutput = 0.0; +#if defined(_debug_) + printf("Resetting\n"); +#endif + + time = (MY_FLOAT) 0.0; + lastTime = 0; + finished = 0; + lastOutput = (MY_FLOAT) 0.0; } void RawWvIn :: normalize() { - this->normalize(1.0); + this->normalize((MY_FLOAT) 1.0); } void RawWvIn :: normalize(MY_FLOAT newPeak) { - long i; - FILE *fd; + long i; + FILE *fd; + extern short SwapShort(short); - gain = 0.0; + gain = (MY_FLOAT) 0.0; - fd = fopen(fileNm,"rb"); - for (i=0;i gain) - gain = fabs(data); - } - if (gain > 0.0) { - gain = newPeak / gain; - } - fclose(fd); + fd = fopen(fileNm,"rb"); + for (i=0;i gain) + gain = (MY_FLOAT) fabs((double) data); + } + if (gain > 0.0) { + gain = newPeak / gain; + } + fclose(fd); } void RawWvIn :: setRate(MY_FLOAT aRate) { - rate = aRate; + rate = aRate; } void RawWvIn :: finish() { - finished = 1; - lastOutput = 0.0; - if (myFile) { - fclose(myFile); - myFile = 0; - } + finished = 1; + lastOutput = (MY_FLOAT) 0.0; + if (myFile) { + fclose(myFile); + myFile = 0; + } } MY_FLOAT RawWvIn :: tick() { - this->informTick(); - return lastOutput; + this->informTick(); + return lastOutput; } int RawWvIn :: informTick() { - long temp; - - if (!finished) { - - time += rate; /* Update current time */ - - if (time >= length) { /* Check for end of sound */ - time = length - 1; /* stick at end */ - finished = 1; /* Information for one-shot use */ - fclose(myFile); - myFile = 0; - } - else { - temp = (long) time; /* Integer part of time address */ - if (temp > lastTime) { /* If we cross next sample time */ - lastTime = temp; - fread(&data,2,1,myFile); /* Snarf next sample from file */ - lastOutput = data * gain; /* And save as non-interpolated data */ - } - } - } + long temp; + extern short SwapShort(short); - return finished; + if (!finished) + { + time += rate; /* Update current time */ + + if (time >= length) /* Check for end of sound */ + { + time = (MY_FLOAT) length - 1; /* stick at end */ + finished = 1; /* Information for one-shot use */ + fclose(myFile); + myFile = 0; + } + else + { + temp = (long) time; /* Integer part of time address */ + if (temp > lastTime) /* If we cross next sample time */ + { + lastTime = temp; + fread(&data,2,1,myFile); /* Snarf next sample from file */ +#ifdef __LITTLE_ENDIAN__ + data = SwapShort(data); +#endif + lastOutput = data * gain; /* And save as non-interpolated data */ + } + } + } + + return finished; } MY_FLOAT RawWvIn :: lastOut() { - return lastOutput; + return lastOutput; } /************ Test Main Program *****************/ @@ -160,4 +175,3 @@ void main() fclose(fd); } */ - diff --git a/RawWvOut.cpp b/RawWvOut.cpp deleted file mode 100644 index 3cf49e9..0000000 --- a/RawWvOut.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/*******************************************/ -/* Raw Wave File Output Class, */ -/* by Perry R. Cook, 1995-96 */ -/* This version opens a mono NeXT .snd */ -/* file 16bit data at 22KHz, and */ -/* pokes buffers of samples into it. */ -/*******************************************/ - -#include "RawWvOut.h" - -#if !defined(__SGI_REALTIME) - -/******** NeXT Soundfile Header Struct *******/ -struct headerform { - char pref[4]; - long hdr_length; - long file_length; - long mode; - long samp_rate; - long num_channels; - char comment[1024]; -}; - -RawWvOut :: RawWvOut(char *fileName) -{ - struct headerform hdr = {".sn",28,0,3,(long) SRATE,1,"TK"}; - hdr.pref[3] = 'd'; - - fd = fopen(fileName,"wb"); - if (!fd) { - printf("Couldn't create soundfile %s !!!!!!!!\n",fileName); - exit(0); - } - fwrite(&hdr,4,7,fd); - counter = 0; - totalCount = 0; -} - -RawWvOut :: ~RawWvOut() -{ - MY_FLOAT temp; - fwrite(data,2,counter,fd); - fseek(fd,8,SEEK_SET); - fwrite(&totalCount,4,1,fd); - fclose(fd); - temp = (double) totalCount * ONE_OVER_SRATE; - printf("%f Seconds Computed\n",temp); -} - -long RawWvOut :: getCounter() -{ - return totalCount; -} - -void RawWvOut :: tick(MY_FLOAT sample) -{ - - data[counter++] = (short) (sample * 32000.0); - totalCount += 1; - if (counter == BUFFER_SIZE) { - fwrite(data,2,BUFFER_SIZE,fd); - counter = 0; - } -} - -#else - - -/*******************************************/ -/* SGI Real-Time Wave File Output Class, */ -/* by Perry R. Cook, 1996 */ -/* This Object can opens the SGI soundout */ -/* device, and pokes buffers of samples */ -/* into it. The real code that does the */ -/* is from Doug Scott of SGI. */ -/*******************************************/ - -#include "sgio.C" - -RawWvOut :: RawWvOut(char *fileName) -{ - int fd; - - fd = init_sound(SRATE,1); - if (fd<0) { - printf("Couldn't open SoundOut Device !!!!!!!!\n"); - exit(0); - } - counter = 0; -} - -RawWvOut :: ~RawWvOut() -{ - playbuf(data,counter); - counter = 0; - while (counter 1.0) lastOutput = 1.0; /* if other way, reed slams shut */ - if (lastOutput < -1.0) lastOutput = -1.0; /* if all the way open, acts like open end */ + if (lastOutput > 1.0) lastOutput = (MY_FLOAT) 1.0; /* if other way, reed slams shut */ + if (lastOutput < -1.0) lastOutput = (MY_FLOAT) -1.0; /* if all the way open, acts like open end */ return lastOutput; } diff --git a/ReedTabl.h b/ReedTabl.h index 484cda2..b50d32f 100644 --- a/ReedTabl.h +++ b/ReedTabl.h @@ -17,8 +17,8 @@ class ReedTabl : public Object public: ReedTabl(); ~ReedTabl(); - void setOffset(double aValue); - void setSlope(double aValue); - MY_FLOAT lookup(double deltaP); + void setOffset(MY_FLOAT aValue); + void setSlope(MY_FLOAT aValue); + MY_FLOAT lookup(MY_FLOAT deltaP); MY_FLOAT lastOut(); }; diff --git a/Release/.placeholder b/Release/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/Reverb.cpp b/Reverb.cpp index 0f25713..c42ec36 100644 --- a/Reverb.cpp +++ b/Reverb.cpp @@ -1,187 +1,39 @@ -/******************************************/ -/* Reverb Effect Applied to Soundfile */ -/* by Perry Cook, 1996 */ -/* */ -/* This is based on some of the famous */ -/* Stanford CCRMA reverbs (NRev, KipRev) */ -/* all based on the the Chowning/Moorer/ */ -/* Schroeder reverberators, which use */ -/* networks of simple allpass and comb */ -/* delay filters. */ -/******************************************/ +/********************************************/ +/* Reverb Abstract Class, */ +/* by Tim Stilson, 1998 */ +/* */ +/* Integrated into STK by Gary Scavone */ +/* with T60 argument. */ +/********************************************/ #include "Reverb.h" -Reverb :: Reverb(MY_FLOAT longestDelay) +Reverb :: Reverb() { - delayLine[0] = new DLineN((long) (longestDelay * 0.164631) + 2); - delayLine[1] = new DLineN((long) (longestDelay * 0.513434) + 2); - delayLine[2] = new DLineN((long) (longestDelay * 1.000000) + 2); - delayLine[3] = new DLineN((long) (longestDelay * 0.830484) + 2); - delayLine[0]->setDelay((long) (longestDelay * 0.164631)); - delayLine[1]->setDelay((long) (longestDelay * 0.513434)); - delayLine[2]->setDelay((long) (longestDelay * 1.000000)); - delayLine[3]->setDelay((long) (longestDelay * 0.830484)); - allPassCoeff = 0.7; - combCoeff1 = 0.62; - combCoeff2 = -0.71; - effectMix = 0.5; - this->clear(); } -Reverb :: ~Reverb() +MY_FLOAT Reverb :: tick(MY_FLOAT sample) { - delete delayLine[0]; - delete delayLine[1]; - delete delayLine[2]; - delete delayLine[3]; -} - -void Reverb :: clear() -{ - delayLine[0]->clear(); - delayLine[1]->clear(); - delayLine[2]->clear(); - delayLine[3]->clear(); - lastOutL = 0.0; - lastOutR = 0.0; + printf("Warning: Using virtual function Reverb :: tick()\n"); + return 0; } void Reverb :: setEffectMix(MY_FLOAT mix) { - effectMix = mix; } -MY_FLOAT Reverb :: lastOutput() +int Reverb :: isprime(int val) { - return (lastOutL + lastOutR) * 0.5; -} + int i; -MY_FLOAT Reverb :: lastOutputL() -{ - return lastOutL; -} - -MY_FLOAT Reverb :: lastOutputR() -{ - return lastOutR; -} - -MY_FLOAT Reverb :: tick(MY_FLOAT input) -{ - MY_FLOAT temp,temp0,temp1,temp2,temp3; - - temp = delayLine[0]->lastOut(); - temp0 = allPassCoeff * temp; - temp0 += input; - delayLine[0]->tick(temp0); - temp0 = -(allPassCoeff * temp0) + temp; - - temp = delayLine[1]->lastOut(); - temp1 = allPassCoeff * temp; - temp1 += temp0; - delayLine[1]->tick(temp1); - temp1 = -(allPassCoeff * temp1) + temp; - - temp2 = temp1 + (combCoeff1 * delayLine[2]->lastOut()); - temp3 = temp1 + (combCoeff2 * delayLine[3]->lastOut()); - - lastOutL = effectMix * (delayLine[2]->tick(temp2)); - lastOutR = effectMix * (delayLine[3]->tick(temp3)); - temp = (1.0 - effectMix) * input; - lastOutL += temp; - lastOutR += temp; - - return (lastOutL + lastOutR) * 0.5; - -} - -/************** Test Main Program *********************/ - - -struct headerform { /*** NeXT Soundfile Header Struct ***/ - char pref[4]; - long hdr_length; - long file_length; - long mode; - long samp_rate; - long num_channels; - char comment[1024]; -}; - -/* -int main(int argc, char *argv[]) -{ - FILE *soundIn,*soundOut; - long i,dLength; - short data[2]; - MY_FLOAT temp,efMix; - Reverb *effect; - struct headerform hdr = {".sn",28,0,3,(long) SRATE,1,"TK"}; - hdr.pref[3] = 'd'; - - if (argc==5) { - soundIn = fopen(argv[3],"rb"); - soundOut = fopen(argv[4],"wb"); - if (soundIn && soundOut) { - dLength = atoi(argv[2]); - efMix = atof(argv[1]); - fread(&hdr,4,2,soundIn); - fread(&hdr.file_length,hdr.hdr_length,1,soundIn); - hdr.file_length += 4 * (2 * dLength * hdr.num_channels); - if (hdr.mode != 3) { - fclose(soundIn); - fclose(soundOut); - printf("Only 16 bit linear data supported in this demo"); - exit(0); - } - fwrite(&hdr,1,hdr.hdr_length,soundOut); - effect = new Reverb(dLength); - effect->setEffectMix(1.0); - for (i=0;itick(temp); - data[0] = (short) (temp + (data[0] * (1.0 - efMix))); - data[1] = (short) (temp + (data[1] * (1.0 - efMix))); - } - else { - temp = effect->tick(0); - data[0] = (short) temp; - data[1] = (short) temp; - } - fwrite(data,2,2,soundOut); - i++; - } - else { - if (fread(data,2,1,soundIn)) { - temp = data[0] * efMix; - temp = effect->tick(temp); - data[0] = (short) (temp + (data[0] * (1.0 - efMix))); - } - else { - temp = effect->tick(0); - data[0] = (short) temp; - } - fwrite(data,2,1,soundOut); + if (val == 2) return 1; + if (val & 1) + { + for (i=3; i<(int)sqrt((double)val)+1; i+=2) + { + if ((val%i) == 0) return 0; } - } - delete effect; - fclose(soundIn); - fclose(soundOut); + return 1; /* prime */ } - else { - printf("Can't open one of the files\n"); - } - } - else { - printf("useage: Reverb mix maxDelay soundIn.snd soundOut.snd\n"); - printf("0.0 <= mix <= 1.0\n"); - printf("maxDelay is in samples\n"); - printf("soundfiles are 16 bit linear mono or stereo\n"); - } + else return 0; /* even */ } - -*/ diff --git a/Reverb.h b/Reverb.h index a96cfa5..68a8e78 100644 --- a/Reverb.h +++ b/Reverb.h @@ -1,41 +1,31 @@ -/******************************************/ -/* Reverb Effect Applied to Soundfile */ -/* by Perry Cook, 1996 */ -/* */ -/* This is based on some of the famous */ -/* Stanford CCRMA reverbs (NRev, KipRev) */ -/* all based on the the Chowning/Moorer/ */ -/* Schroeder reverberators, which use */ -/* networks of simple allpass and comb */ -/* delay filters. */ -/******************************************/ +/********************************************/ +/* Reverb Abstract Class, */ +/* by Tim Stilson, 1998 */ +/* */ +/* Integrated into STK by Gary Scavone */ +/* with T60 argument. */ +/********************************************/ + +#include "Object.h" #if !defined(__Reverb_h) #define __Reverb_h -#include "Object.h" -#include "DLineN.h" - class Reverb : public Object { - protected: - DLineN *delayLine[4]; - MY_FLOAT allPassCoeff; - MY_FLOAT combCoeff1; - MY_FLOAT combCoeff2; - MY_FLOAT lastOutL; - MY_FLOAT lastOutR; - MY_FLOAT effectMix; public: - Reverb(MY_FLOAT longestDelay); - ~Reverb(); - void clear(); - void setEffectMix(MY_FLOAT mix); - MY_FLOAT lastOutput(); - MY_FLOAT lastOutputL(); - MY_FLOAT lastOutputR(); - MY_FLOAT tick(MY_FLOAT input); + Reverb(); + virtual MY_FLOAT tick(MY_FLOAT sample); + virtual void setEffectMix(MY_FLOAT mix); + int isprime(int val); }; -#endif +#endif // defined(__Reverb_h) +/* CLM also had JLRev and JLLRev variations on the JCRev: JLRev had + longer combs and alpasses, JLLRev further placed the comb coefs + closer to 1.0. In my modified testMono.cpp, I allowed for a + "JLRev" argument, though JLRev.cpp/.h doesn't exist, testMono + simply uses a JCRev but passes a longer base comb length. I also + have comments in JCRev.cpp for the JLLRev coefs. +*/ diff --git a/Rhodey.cpp b/Rhodey.cpp index 32d6acd..2a8c93d 100644 --- a/Rhodey.cpp +++ b/Rhodey.cpp @@ -13,19 +13,19 @@ Rhodey :: Rhodey() : FM4Alg5() "rawwaves/sinewave.raw", "rawwaves/sinewave.raw", "rawwaves/fwavblnk.raw"); - this->setRatio(0,1.0); - this->setRatio(1,0.5); - this->setRatio(2,1.0); - this->setRatio(3,15.0); + this->setRatio(0,(MY_FLOAT) 1.0); + this->setRatio(1,(MY_FLOAT) 0.5); + this->setRatio(2,(MY_FLOAT) 1.0); + this->setRatio(3,(MY_FLOAT) 15.0); gains[0] = __FM4Op_gains[99]; gains[1] = __FM4Op_gains[90]; gains[2] = __FM4Op_gains[99]; gains[3] = __FM4Op_gains[67]; - adsr[0]->setAll(0.05,0.00003,0.0,0.02); - adsr[1]->setAll(0.05,0.00003,0.0,0.02); - adsr[2]->setAll(0.05,0.00005,0.0,0.02); - adsr[3]->setAll(0.05,0.0002,0.0,0.02); - twozero->setGain(1.0); + adsr[0]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.50,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + adsr[1]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.50,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + adsr[2]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.00,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + adsr[3]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 0.25,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + twozero->setGain((MY_FLOAT) 1.0); } Rhodey :: ~Rhodey() @@ -35,7 +35,7 @@ Rhodey :: ~Rhodey() void Rhodey :: setFreq(MY_FLOAT frequency) { - baseFreq = frequency * 2.0; + baseFreq = frequency * (MY_FLOAT) 2.0; waves[0]->setFreq(baseFreq * ratios[0]); waves[1]->setFreq(baseFreq * ratios[1]); waves[2]->setFreq(baseFreq * ratios[2]); diff --git a/SKINI09.txt b/SKINI09.txt new file mode 100644 index 0000000..762991b --- /dev/null +++ b/SKINI09.txt @@ -0,0 +1,397 @@ +This describes the 0.9 implementation of SKINI: + +Synthesis toolKit Instrument Network Interface + +for the Synthesis Toolkit in C++ by Perry R. Cook 1996. + +********************************* +* Too good to be true? * +* Have control and read it too? * +* A SKINI Haiku. * +********************************* + +Profound thanks to Dan Trueman and Brad Garton for input on +this revision. Thanks also to MIDI, the NeXT MusicKit, ZIPI +and all the creators and modifiers of these for good bases +upon/from which to build and depart. + +1) MIDI Compatibility + + SKINI was designed to be MIDI compatible wherever possible, + and extend MIDI in incremental, then maybe profound ways. + + Differences from MIDI, and motivations, include: + + Text-based messages are used, with meaningful names + wherever possible. This allows any language or system + capable of formatted printing to generate SKINI. + Similarly, any system capable of reading in a string + and turning delimited fields into strings, floats, + and ints can consume SKINI for control. More importantly, + humans can actually read, and even write if they want, + SKINI files and streams. Use an editor and search/ + replace or macros to change a channel or control number. + Load a SKINI score into a spread sheet to apply + transformations to time, control parameters, MIDI + velocities, etc. Put a monkey on a special typewriter + and get your next great work. Life's too short to debug + bit/nybble packed variable length mumble messages. Disk + space gets cheaper, available bandwidth increases, music + takes up so little space and bandwidth compared to video + and grapics. Live a little. + + Floating point numbers are used wherever possible. + Note Numbers, Velocities, Controller Values, and + Delta and Absolute Times are all represented and + scanned as ASCII double-precision floats. MIDI byte + values are preserved, so that incoming MIDI bytes + from an interface can be put directly into SKINI + messages. 60.0 or 60 is middle C, 127.0 or 127 is + maximum velocity etc. But, unlike MIDI, 60.5 can + cause a 50cent sharp middle C to be played. As with + MIDI byte values like velocity, use of the integer and + SKINI-added fractional parts is up to the implementor + of the algorithm being controlled by SKINI messages. + But the extra precision is there to be used or ignored. + +2) WHY SKINI? + + SKINI was designed to be extensable and hackable for a number + of applications: imbedded synthesis in a game or VR simulation, + scoring and mixing tasks, real-time and non-real time applications + which could benefit from a controllable sound synthesis, + JAVA controlled synthesis, or eventually maybe JAVA synthesis, + etc. SKINI is not intended to be "the mother of scorefiles," + but since the entire system is based on text representations + of names, floats, and ints, converters from one scorefile + language to SKINI, or back, should be easily created. + + I am basically a bottom-up designer with an awareness of top- + down design ideas, so SKINI above all reflects the needs of my + particular research and creative projects as they have arisen and + developed. SKINI09 represents a profound advance beyond SKINI08 + (the first version), but it is likely that SKINI1.0x will + reflect some changes. Compatibility with prior scorefiles + will be attempted, but there aren't that many scorefiles out + there yet. The one thing I will attempt to keep in mind is + enough consistency to allow the creation of a SKINI0x to SKINIx0 + file and stream converter object. SKINI09 should be fully + compatible with SKINI08. + +3) SKINI MESSAGES + + A basic SKINI message is a line of text. There are only three + required fields, the message type (an ASCII name), the time (either + delta or absolute), and the channel number. Don't freak out and + think that this is MIDI channel 0-15 (which is supported), because + the channel number is scanned as a long int. Channels could be socket + numbers, machine IDs, serial numbers, or even unique tags for each + event in a synthesis. Other fields might be used, as specified in the + SKINI09.tbl file. This is described in more detail later. + + Fields in a SKINI line are delimited by spaces, commas, or + tabs. The SKINI parser only operates on a line at a time, + so a newline means the message is over. Multiple messages are + NOT allowed directly on a single line (by use of the ; for + example in C). This could be supported, but it isn't in 0.9. + + Message types include standard MIDI types like NoteOn, NoteOff, + ControlChange, etc. MIDI extension message types (messages + which look better than MIDI but actually get turned into + MIDI-like messages) include LipTension, StringDamping, etc. + NonMIDI message types include SetPath (sets a path for file + use later), and OpenReadFile (for streaming, mixing, and applying + effects to soundfiles along with synthesis, for example). + Other NonMIDI message types include Trilling, HammerOn, etc. (these + translate to gestures, behaviors, and contexts for use by + intellegent players and instruments using SKINI). Where possible + I will still use these as MIDI extension messages, so foot + switches, etc. can be used to control them in real time. + + All fields other than type, time, and channel are optional, and the + types and useage of the additional fields is defined in the file + SKINI09.tbl. + + The other important file used by SKINI is SKINI09.msg, which is a + set of #defines to make C code more readable, and to allow reasonably + quick re-mapping of control numbers, etc.. All of these defined + symbols are assigned integer values. For JAVA, the #defines could + be replaced by declaration and assignment statements, preserving + the look and behavior of the rest of the code. + +4) C Files Used To Implement SKINI09 + + SKINI09.cpp is an object which can either open a SKINI file, and + successively read and parse lines of text as SKINI strings, or + accept strings from another object and parse them. The latter + functionality would be used by a socket, pipe, or other connection + receiving SKINI messages a line at a time, usually in real time, + but not restricted to real time. + + SKINI09.msg should be included by anything wanting to use the + SKINI09.cpp object. This is not mandatory, but use of the __SK_blah_ + symbols which are defined in the .msg file will help to ensure + clarity and consistency when messages are added and changed. + + SKINI09.tbl is used only by the SKINI parser object (SKINI09.cpp). + In the file SKINI09.tbl, an array of structures is declared and + assigned values which instruct the parser as to what the message + types are, and what the fields mean for those message types. + This table is compiled and linked into applications using SKINI, but + could be dynamically loaded and changed in a future version of + SKINI. + +5) SKINI Messages and the SKINI Parser: + + The parser isn't all that smart, but neither am I. Here are the + basic rules governing a valid SKINI message: + + a) If the first (non-delimiter (see c)) character in a SKINI + string is '/' that line is treated as a comment and echoed + to stdout. + + b) If there are no characters on a line, that line is treated + as blank and echoed to stdout. Tabs and spaces are treated + as non-characters. + + c) Spaces, commas, and tabs delimit the fields in a SKINI + message line. (We might allow for multiple messages per + line later using the semicolon, but probably not. A series + of lines with deltaTimes of 0.0 denotes simultaneous events. + For Readability, multiple messages per line doesn't help much, + so it's unlikely to be supported later). + + d) The first field must be a SKINI message name. (like NoteOn). + These might become case-insensitive in SKINI09+, so don't plan + on exciting clever overloading of names (like noTeOn being + different from NoTeON). There can be a number of leading + spaces or tabs, but don't exceed 32 or so. + + e) The second field must be a time specification in seconds. + For real-time applications, this field can be 0.0. A time + field can be either delta-time (most common and the only one + supported in SKINI0.8), or absolute time. Absolute time + messages have an '=' appended to the beginning of the floating + point number with no space. So 0.10000 means delta time of + 100ms., while =0.10000 means absolute time of 100 ms. Absolute + time messages make most sense in score files, but could also be + used for (loose) synchronization in a real-time context. Real + time messages should be time-ordered AND time-correct. That is, + if you've sent 100 total delta-time messages of 1.0 seconds, and + then send an absolute time message of =90.0 seconds, or if you + send two absolute time messages of =100.0 and =90.0 in that + order, things will get really fouled up. The SKINI0.9 parser + doesn't know about time, however. The RawWvOut device is the + master time keeper in the Synthesis Toolkit, so it should be + queried to see if absolute time messages are making sense. + There's an example of how to do that later in this document. + Absolute times are returned by the parser as negative numbers + (since negative deltaTimes are not allowed). + + f) The third field must be an integer channel number. Don't go + crazy and think that this is just MIDI channel 0-15 (which is + supported). The channel number is scanned as a long int. Channels + 0-15 are in general to be treated as MIDI channels. After that + it's wide open. Channels could be socket numbers, machine IDs, + serial numbers, or even unique tags for each event in a synthesis. + A -1 channel can be used as don't care, omni, or other functions + depending on your needs and taste. + + g) All remaining fields are specified in the SKINI09.tbl file. + In general, there are maximum two more fields, which are either + SK_INT (long), SK_DBL (double float), or SK_STR (string). The + latter is the mechanism by which more arguments can be specified + on the line, but the object using SKINI must take that string + apart (retrived by using getRemainderString()) and scan it. + Any excess fields are stashed in remainderString. + +6) A Short SKINI File: + + /* Howdy!!! Welcome to SKINI09, by P. Cook 1996 + + NoteOn 0.000082 2 55 82 + NoteOff 1.000000 2 55 0 + NoteOn 0.000082 2 69 82 + StringDetune 0.100000 2 10 + StringDetune 0.100000 2 30 + StringDetune 0.100000 2 50 + NoteOn 0.000000 2 69 82 + StringDetune 0.100000 2 40 + StringDetune 0.100000 2 22 + StringDetune 0.100000 2 12 + // + StringDamping 0.000100 2 0.0 + NoteOn 0.000082 2 55 82 + NoteOn 0.200000 2 62 82 + NoteOn 0.100000 2 71 82 + NoteOn 0.200000 2 79 82 + NoteOff 1.000000 2 55 82 + NoteOff 0.000000 2 62 82 + NoteOff 0.000000 2 71 82 + NoteOff 0.000000 2 79 82 + StringDamping =4.000000 2 0.0 + NoteOn 0.000082 2 55 82 + NoteOn 0.200000 2 62 82 + NoteOn 0.100000 2 71 82 + NoteOn 0.200000 2 79 82 + NoteOff 1.000000 2 55 82 + NoteOff 0.000000 2 62 82 + NoteOff 0.000000 2 71 82 + NoteOff 0.000000 2 79 82 + +7) The SKINI09.tbl File, How Messages are Parsed + + The SKINI09.tbl file contains an array of structures which + are accessed by the parser object SKINI09.cpp. The struct is: + + struct SKINISpec { char messageString[32]; + long type; + long data2; + long data3; + }; + + so an assignment of one of these structs looks like: + + MessageStr$ ,type, data2, data3, + + type is the message type sent back from the SKINI line parser. + data is either + NOPE : field not used, specifically, there aren't going + to be any more fields on this line. So if there + is is NOPE in data2, data3 won't even be checked + SK_INT : byte (actually scanned as 32 bit signed long int) + If it's a MIDI data field which is required to + be an integer, like a controller number, it's + 0-127. Otherwise) get creative with SK_INTs + SK_DBL : double precision floating point. SKINI uses these + in the MIDI context for note numbers with micro + tuning, velocities, controller values, etc. + SK_STR : only valid in final field. This allows (nearly) + arbitrary message types to be supported by simply + scanning the string to EndOfLine and then passing + it to a more intellegent handler. For example, + MIDI SYSEX (system exclusive) messages of up to + 256bytes can be read as space-delimited integers + into the 1K SK_STR buffer. Longer bulk dumps, + soundfiles, etc. should be handled as a new + message type pointing to a FileName, Socket, or + something else stored in the SK_STR field, or + as a new type of multi-line message. + + Here's a couple of lines from the SKINI09.tbl file + + {"NoteOff" , __SK_NoteOff_, SK_DBL, SK_DBL}, + {"NoteOn" , __SK_NoteOn_, SK_DBL, SK_DBL}, + + {"ControlChange" , __SK_ControlChange_, SK_INT, SK_DBL}, + {"Volume" , __SK_ControlChange_, __SK_Volume_ , SK_DBL}, + + {"StringDamping" , __SK_ControlChange_, __SK_StringDamping_ , SK_DBL}, + {"StringDetune" , __SK_ControlChange_, __SK_StringDetune_ , SK_DBL}, + + The first three are basic MIDI messages. The first two would cause the + parser, after recognizing a match of the string "NoteOff" or "NoteOn", + to set the message type to 128 or 144 (__SK_NoteOff_ and __SK_NoteOn_ + are #defined in the file SKINI09.msg to be the MIDI byte value, without + channel, of the actual MIDI messages for NoteOn and NoteOff). The parser + would then set the time or delta time (this is always done and is + therefore not described in the SKINI Message Struct). The next two + fields would be scanned as double-precision floats and assigned to + the byteTwo and byteThree variables of the SKINI parser. The remainder + of the line is stashed in the remainderString variable. + + The ControlChange line is basically the same as NoteOn and NoteOff, but + the second data byte is set to an integer (for checking later as to + what MIDI control is being changed). + + The Volume line is a MIDI Extension message, which behaves like a + ControlChange message with the controller number set explicitly to + the value for MIDI Volume (7). Thus the following two lines would + accomplish the same changing of MIDI volume on channel 2: + + ControlChange 0.000000 2 7 64.1 + Volume 0.000000 2 64.1 + + I like the 2nd line better, thus my motivation for SKINI in the first + place. + + The StringDamping and StringDetune messages behave the same as + the Volume message, but use Control Numbers which aren't specifically + nailed-down in MIDI. Note that these Control Numbers are carried + around as long ints, so we're not limited to 0-127. If, however, + you want to use a MIDI controller to play an instrument, using + controller numbers in the 0-127 range might make sense. + +8) Objects using SKINI + + Here's a simple example of code which uses the SKINI object + to read a SKINI file and control a single instrument. + + instrument = new Mandolin(50.0); + score = new SKINI09(argv[1]); + while(score->getType() > 0) { + tempDouble = score->getDelta(); + if (tempDouble < 0) { + tempDouble = - tempDouble; + tempDouble = tempDouble - output.getTime(); + if (tempDouble < 0) { + printf("Bad News Here!!! Backward Absolute Time Required.\n"); + tempDouble = 0.0; + } + } + tempLong = (long) (tempDouble * SRATE); + for (i=0;itick()); + } + tempDouble3 = score->getByteThree(); + if (score->getType()== __SK_NoteOn_ ) { + tempDouble3 *= NORM_7; + if (score->getByteThree() == 0) { + tempDouble3 = 0.5; + instrument->noteOff(tempDouble3); + } + else { + tempLong = (int) score->getByteTwo(); + tempDouble2 = __MIDI_To_Pitch[tempLong]; + instrument->noteOn(tempDouble2,tempDouble3); + } + } + else if (score->getType() == __SK_NoteOff_) { + tempDouble3 *= NORM_7; + instrument->noteOff(tempDouble3); + } + else if (score->getType() == __SK_ControlChange_) { + tempLong = score->getByteTwoInt(); + instrument->controlChange(tempLong,temp3.0); + } + score->nextMessage(); + } + + When the score (SKINI09 object) object is created from the + filename in argv[1], the first valid command line is read + from the file and parsed. + + The score->getType() retrieves the messageType. If this is + -1, there are no more valid messages in the file and the + synthesis loop terminates. Otherwise, the message type is + returned. + + getDelta() retrieves the deltaTime until the current message + should occur. If this is greater than 0, synthesis occurs + until the deltaTime has elapsed. If deltaTime is less than + zero, the time is interpreted as absolute time and the output + device is queried as to what time it is now. That is used to + form a deltaTime, and if it's positive we synthesize. If + it's negative, we print an error and pretend this never + happened and we hang around hoping to eventually catch up. + + The rest of the code sorts out message types NoteOn, NoteOff + (including NoteOn with velocity 0), and ControlChange. The + code implicitly takes into account the integer type of the + control number, but all other data is treated as double float. + + The last line reads and parses the next message in the file. + + + + diff --git a/SKINI11.cpp b/SKINI11.cpp new file mode 100644 index 0000000..8b8c137 --- /dev/null +++ b/SKINI11.cpp @@ -0,0 +1,345 @@ +/******************************************/ +/* 2nd generation SKINI Text File Reader */ +/* Class, by Perry R. Cook, 1996 */ +/* This Object can open a SKINI File */ +/* and parse it. The file spec is mine */ +/* and mine alone, but it's all text so */ +/* that should help you figuring it out. */ +/* */ +/* SKINI (Synthesis toolKit Instrument */ +/* Network Interface) is like MIDI, but */ +/* allows for floating point control */ +/* changes, note numbers, etc. Example: */ +/* noteOn 60.01 111.132 plays a sharp */ +/* middle C with a velocity of 111.132 */ +/* See SKINI11.txt for more information */ +/* */ +/******************************************/ + +#include "SKINI11.h" + +SKINI11 :: SKINI11(char *fileName) /* Constructor for reading SKINI files */ +{ /* Use nextMessage() method */ + myFile = fopen(fileName,"r"); + if ((int) myFile < 0) printf("SKINI11: Can't open SKINI score file\n"); + this->nextMessage(); +} + +SKINI11 :: SKINI11() /* Constructor to use this object for parsing */ +{ /* SKINI Strings (coming over socket for example */ +} /* Use parseThis() method with string argument */ + +SKINI11 :: ~SKINI11() +{ +} + +/***************** SOME HANDY ROUTINES *******************/ + +#include "SKINI11.tbl" + +#define __SK_MAX_FIELDS_ 5 +#define __SK_MAX_SIZE_ 32 + +short ignore(char aChar) +{ + short ignoreIt = 0; + if (aChar == 0) ignoreIt = 1; // Null String Termination + if (aChar == '\n') ignoreIt = 1; // Carraige Return??? + if (aChar == '/') ignoreIt = 2; // Comment Line + return ignoreIt; +} + +short delimit(char aChar) +{ + if (aChar == ' ' || // Space + aChar == ',' || // Or Comma + aChar == '\t') // Or Tab + return 1; + else + return 0; +} + +short nextChar(char* aString) +{ + int i; + + for (i=0;i<__SK_MAX_SIZE_;i++) { + if ( aString[i] != ' ' && // Space + aString[i] != ',' && // Or Comma + aString[i] != '\t' ) // Or Tab + return i; + } + return 1024; +} + +int subStrings(char *aString, + char someStrings[__SK_MAX_FIELDS_][__SK_MAX_SIZE_], + int somePointrs[__SK_MAX_FIELDS_], + char *remainderString) +{ + int notDone,howMany,point,temp; + notDone = 1; + howMany = 0; + point = 0; + temp = nextChar(aString); + if (temp >= __SK_MAX_SIZE_) { + notDone = 0; + printf("Confusion here: Ignoring this line\n"); + printf("%s\n",aString); + return howMany; + } + point = temp; + somePointrs[howMany] = point; + temp = 0; + while (notDone) { + if (aString[point] == '\n') { + notDone = 0; + } + else { + someStrings[howMany][temp++] = aString[point++]; + if (temp >= __SK_MAX_SIZE_) { + howMany = 0; + return howMany; + } + if (delimit(aString[point]) || aString[point] == '\n') { + someStrings[howMany][temp] = 0; + howMany += 1; + if (howMany < __SK_MAX_FIELDS_) { + temp = nextChar(&aString[point]); + point += temp; + somePointrs[howMany-1] = point; + temp = 0; + } + else { + temp = 0; + somePointrs[howMany-1] = point; + while(aString[point] != '\n') + remainderString[temp++] = aString[point++]; + remainderString[temp] = aString[point]; + } + } + } + } +// printf("Got: %i Strings:\n",howMany); +// for (temp=0;temp 0) + which = 0; + aField = 0; + strcpy(msgTypeString,someStrings[aField]); + while ((which < __SK_MaxMsgTypes_) && + (strcmp(msgTypeString, + skini_msgs[which].messageString))) { + which += 1; + } + if (which >= __SK_MaxMsgTypes_) { + messageType = -1; + printf("Couldn't parse this message field: =%s\n %s\n", + msgTypeString,aString); + return messageType; + } + else { + messageType = skini_msgs[which].type; +// printf("Message Token = %s type = %i\n", +// msgTypeString,messageType); + } + aField += 1; + + if (someStrings[0][0] == '=') { + deltaTime = (MY_FLOAT) atof(&someStrings[aField][1]); + deltaTime = -deltaTime; + } + else { + deltaTime = (MY_FLOAT) atof(someStrings[aField]); + } +// printf("DeltaTime = %f\n",deltaTime); + aField += 1; + + channel = atoi(someStrings[aField]); +// printf("Channel = %i\n",channel); + aField += 1; + + if (skini_msgs[which].data2 != NOPE) { + if (skini_msgs[which].data2 == SK_INT) { + byteTwoInt = atoi(someStrings[aField]); + byteTwo = (MY_FLOAT) byteTwoInt; + } + else if (skini_msgs[which].data2 == SK_DBL) { + byteTwo = (MY_FLOAT) atof(someStrings[aField]); + byteTwoInt = (long) byteTwo; + } + else if (skini_msgs[which].data2 == SK_STR) { + temp = somePointrs[aField-1]; /* Hack Danger Here, Why -1??? */ + temp2 = 0; + while (aString[temp] != '\n') { + remainderString[temp2++] = aString[temp++]; + } + remainderString[temp2] = 0; + } + else { + byteTwoInt = skini_msgs[which].data2; + byteTwo = (MY_FLOAT) byteTwoInt; + aField -= 1; + } + + aField += 1; + if (skini_msgs[which].data3 != NOPE) { + if (skini_msgs[which].data3 == SK_INT) { + byteThreeInt = atoi(someStrings[aField]); + byteThree = (MY_FLOAT) byteThreeInt; + } + else if (skini_msgs[which].data3 == SK_DBL) { + byteThree = (MY_FLOAT) atof(someStrings[aField]); + byteThreeInt = (long) byteThree; + } + else if (skini_msgs[which].data3 == SK_STR) { + temp = somePointrs[aField-1]; /* Hack Danger Here, Why -1??? */ + temp2 = 0; + while (aString[temp] != '\n') { + remainderString[temp2++] = aString[temp++]; + } + remainderString[temp2] = 0; + } + else { + byteThreeInt = skini_msgs[which].data3; + byteThree = (MY_FLOAT) byteThreeInt; + } + } + else { + byteThreeInt = byteTwoInt; + byteThree = byteTwo; + } + } + } + return messageType; +} + +long SKINI11 :: nextMessage() +{ + int notDone; + char inputString[1024]; + + notDone = 1; + while (notDone) { + notDone = 0; + if (!fgets(inputString,1024,myFile)) { + printf("//End of Score. Thanks for using SKINI0.9 Bye Bye!!\n"); + messageType = -1; + return messageType; + } + else if (parseThis(inputString) == 0) { + notDone = 1; + } + } + return messageType; +} + +long SKINI11 :: getType() +{ + return messageType; +} + +long SKINI11 :: getChannel() +{ + return channel; +} + +MY_FLOAT SKINI11 :: getDelta() +{ + return deltaTime; +} + +MY_FLOAT SKINI11 :: getByteTwo() +{ + return byteTwo; +} + +long SKINI11 :: getByteTwoInt() +{ + return byteTwoInt; +} + +MY_FLOAT SKINI11 :: getByteThree() +{ + return byteThree; +} + +long SKINI11 :: getByteThreeInt() +{ + return byteThreeInt; +} + +char* SKINI11 :: getRemainderString() +{ + return remainderString; +} + +char* SKINI11 :: getMessageTypeString() +{ + return msgTypeString; +} + +char sk_tempString[1024]; + +char* SKINI11 :: whatsThisType(long type) +{ + int i = 0; + sk_tempString[0] = 0; + for (i=0;i<__SK_MaxMsgTypes_;i++) { + if (type == skini_msgs[i].type) { + strcat(sk_tempString,skini_msgs[i].messageString); + strcat(sk_tempString,","); + } + } + return sk_tempString; +} + +char* SKINI11 :: whatsThisController(long contNum) +{ + int i = 0; + sk_tempString[0] = 0; + for (i=0;i<__SK_MaxMsgTypes_;i++) { + if (skini_msgs[i].type == __SK_ControlChange_ + && contNum == skini_msgs[i].data2) { + strcat(sk_tempString,skini_msgs[i].messageString); + strcat(sk_tempString,","); + } + } + return sk_tempString; +} + +/************ Test Main Program *****************/ +/* +void main(int argc,char *argv[]) +{ + SKINI11 testFile(argv[1]); + + while(testFile.nextMessage() > 0) ; + +} +*/ + diff --git a/SKINI11.h b/SKINI11.h new file mode 100644 index 0000000..5e2b283 --- /dev/null +++ b/SKINI11.h @@ -0,0 +1,58 @@ +/******************************************/ +/* 3rd generation SKINI Text File Reader */ +/* Class, by Perry R. Cook, 1997 */ +/* This Object can open a SKINI File */ +/* and parse it. The file spec is mine */ +/* and mine alone, but it's all text so */ +/* that should help you figuring it out. */ +/* */ +/* SKINI (Synthesis toolKit Instrument */ +/* Network Interface) is like MIDI, but */ +/* allows for floating point control */ +/* changes, note numbers, etc. Example: */ +/* noteOn 60.01 111.132 plays a sharp */ +/* middle C with a velocity of 111.132 */ +/* See SKINI.txt for more information */ +/* */ +/******************************************/ + +#if !defined(__SKINI11_h) +#define __SKINI11_h + +#include "Object.h" + +class SKINI11 : public Object +{ + protected: + FILE *myFile; + int messageType; + char msgTypeString[64]; + int channel; + MY_FLOAT deltaTime; + MY_FLOAT byteTwo; + MY_FLOAT byteThree; + long byteTwoInt; + long byteThreeInt; + char remainderString[1024]; + public: + SKINI11(char *fileName); + SKINI11(); + ~SKINI11(); + long parseThis(char* aString); + long nextMessage(); + long getType(); + long getChannel(); + MY_FLOAT getDelta(); + MY_FLOAT getByteTwo(); + MY_FLOAT getByteThree(); + long getByteTwoInt(); + long getByteThreeInt(); + char* getRemainderString(); + char* getMessageTypeString(); + char* whatsThisType(long type); + char* whatsThisController(long type); +}; + +#endif + + diff --git a/SKINI11.msg b/SKINI11.msg new file mode 100644 index 0000000..0b4602e --- /dev/null +++ b/SKINI11.msg @@ -0,0 +1,119 @@ +/*************************************************************/ +/* */ +/* DEFINITION of SKINI Message Types and Special Symbols */ +/* Synthesis toolKit Instrument Network Interface */ +/* */ +/* These symbols should have the form __SK__ */ +/* */ +/* Where is the string used in the SKINI stream */ +/*************************************************************/ + +/***** MIDI COMPATIBLE MESSAGES ***/ +/***** STATUS BYTES Have Chan=0 **/ + +#define NOPE -32767 +#define YEP 1 +#define SK_DBL -32766 +#define SK_INT -32765 +#define SK_STR -32764 + +#define __SK_NoteOff_ 128 +#define __SK_NoteOn_ 144 +#define __SK_PolyPressure_ 160 +#define __SK_ControlChange_ 176 +#define __SK_ProgramChange_ 192 +#define __SK_AfterTouch_ 208 +#define __SK_ChannelPressure_ __SK_AfterTouch_ +#define __SK_PitchWheel_ 224 +#define __SK_PitchBend_ __SK_PitchWheel_ + +#define __SK_Clock_ 248 +#define __SK_SongStart_ 250 +#define __SK_Continue_ 251 +#define __SK_SongStop_ 252 +#define __SK_ActiveSensing_ 254 +#define __SK_SystemReset_ 255 + +#define __SK_Volume_ 7 +#define __SK_ModWheel_ 1 +#define __SK_Modulation_ __SK_ModWheel_ +#define __SK_Breath_ 2 +#define __SK_FootControl_ 4 +#define __SK_Portamento_ 65 +#define __SK_Balance_ 8 +#define __SK_Pan_ 10 +#define __SK_Sustain_ 64 +#define __SK_Damper_ __SK_Sustain_ +#define __SK_Expression_ 11 + +#define __SK_AfterTouch_Cont_ 128 +#define __SK_ModFrequency_ __SK_Expression_ + +#define __SK_ProphesyRibbon_ 16 +#define __SK_ProphesyWheelUp_ 2 +#define __SK_ProphesyWheelDown_ 3 +#define __SK_ProphesyPedal_ 18 +#define __SK_ProphesyKnob1_ 21 +#define __SK_ProphesyKnob2_ 22 + +/*** Instrument Family Specific **/ + +#define __SK_NoiseLevel_ __SK_FootControl_ + +#define __SK_PickPosition_ __SK_FootControl_ +#define __SK_StringDamping_ __SK_Expression_ +#define __SK_StringDetune_ __SK_ModWheel_ +#define __SK_BodySize_ __SK_Breath_ +#define __SK_BowPressure_ __SK_Breath_ +#define __SK_BowPosition_ __SK_PickPosition_ +#define __SK_BowBeta_ __SK_BowPosition_ + +#define __SK_ReedStiffness_ __SK_Breath_ +#define __SK_ReedRestPos_ __SK_FootControl_ + +#define __SK_FluteEmbouchure_ __SK_Breath_ +#define __SK_JetDelay_ __SK_FluteEmbouchure_ + +#define __SK_LipTension_ __SK_Breath_ +#define __SK_SlideLength_ __SK_FootControl_ + +#define __SK_StrikePosition_ __SK_PickPosition_ +#define __SK_StickHardness_ __SK_Breath_ + +#define __SK_TrillDepth_ 1051 +#define __SK_TrillSpeed_ 1052 +#define __SK_StrumSpeed_ __SK_TrillSpeed_ +#define __SK_RollSpeed_ __SK_TrillSpeed_ + +#define __SK_FilterQ_ __SK_Breath_ +#define __SK_FilterFreq_ 1062 +#define __SK_FilterSweepRate_ __SK_FootControl_ + +#define __SK_ShakerInst_ 1071 +#define __SK_ShakerDamping_ __SK_Breath_ +#define __SK_ShakerNumBeans_ __SK_FootControl_ + +#define __SK_Strumming_ 1090 +#define __SK_NotStrumming_ 1091 +#define __SK_Trilling_ 1092 +#define __SK_NotTrilling_ 1093 +#define __SK_Rolling_ __SK_Strumming_ +#define __SK_NotRolling_ __SK_NotStrumming_ + +#define __SK_PlayerSkill_ 2001 +#define __SK_Chord_ 2002 +#define __SK_ChordOff_ 2003 + +#define __SK_SINGER_FilePath_ 3000 +#define __SK_SINGER_Frequency_ 3001 +#define __SK_SINGER_NoteName_ 3002 +#define __SK_SINGER_Shape_ 3003 +#define __SK_SINGER_Glot_ 3004 +#define __SK_SINGER_VoicedUnVoiced_ 3005 +#define __SK_SINGER_Synthesize_ 3006 +#define __SK_SINGER_Silence_ 3007 +#define __SK_SINGER_VibratoAmt_ __SK_ModWheel_ +#define __SK_SINGER_RndVibAmt_ 3008 +#define __SK_SINGER_VibFreq_ __SK_Expression_ + + diff --git a/SKINI11.tbl b/SKINI11.tbl new file mode 100644 index 0000000..bac77c5 --- /dev/null +++ b/SKINI11.tbl @@ -0,0 +1,130 @@ + +#include "SKINI11.msg" + +#define __SK_MaxMsgTypes_ 128 + +struct SKINISpec { char messageString[32]; + long type; + long data2; + long data3; + }; + +/* SEE COMMENT BLOCK AT BOTTOM FOR FIELDS AND USES */ +/* MessageString ,type, ch?, data2 , data3 */ + +struct SKINISpec skini_msgs[__SK_MaxMsgTypes_] = +{ + {"NoteOff" , __SK_NoteOff_, SK_DBL, SK_DBL}, + {"NoteOn" , __SK_NoteOn_, SK_DBL, SK_DBL}, + {"PolyPressure" , __SK_PolyPressure_, SK_DBL, SK_DBL}, + {"ControlChange" , __SK_ControlChange_, SK_INT, SK_DBL}, + {"ProgramChange" , __SK_ProgramChange_, SK_DBL, SK_DBL}, + {"AfterTouch" , __SK_AfterTouch_, SK_DBL, NOPE}, + {"ChannelPressure" ,__SK_ChannelPressure_, SK_DBL, NOPE}, + {"PitchWheel" , __SK_PitchWheel_, SK_DBL, NOPE}, + {"PitchBend" , __SK_PitchBend_, SK_DBL, NOPE}, + + {"Clock" , __SK_Clock_, NOPE, NOPE}, + {"Undefined" , 249, NOPE, NOPE}, + {"SongStart" , __SK_SongStart_, NOPE, NOPE}, + {"Continue" , __SK_Continue_, NOPE, NOPE}, + {"SongStop" , __SK_SongStop_, NOPE, NOPE}, + {"Undefined" , 253, NOPE, NOPE}, + {"ActiveSensing" , __SK_ActiveSensing_, NOPE, NOPE}, + {"SystemReset" , __SK_SystemReset_, NOPE, NOPE}, + + {"Volume" , __SK_ControlChange_, __SK_Volume_ , SK_DBL}, + {"ModWheel" , __SK_ControlChange_, __SK_ModWheel_ , SK_DBL}, + {"Modulation" , __SK_ControlChange_, __SK_Modulation_ , SK_DBL}, + {"Breath" , __SK_ControlChange_, __SK_Breath_ , SK_DBL}, + {"FootControl" , __SK_ControlChange_, __SK_FootControl_ , SK_DBL}, + {"Portamento" , __SK_ControlChange_, __SK_Portamento_ , SK_DBL}, + {"Balance" , __SK_ControlChange_, __SK_Balance_ , SK_DBL}, + {"Pan" , __SK_ControlChange_, __SK_Pan_ , SK_DBL}, + {"Sustain" , __SK_ControlChange_, __SK_Sustain_ , SK_DBL}, + {"Damper" , __SK_ControlChange_, __SK_Damper_ , SK_DBL}, + {"Expression" , __SK_ControlChange_, __SK_Expression_ , SK_DBL}, + + {"NoiseLevel" , __SK_ControlChange_, __SK_NoiseLevel_ , SK_DBL}, + {"PickPosition" , __SK_ControlChange_, __SK_PickPosition_ , SK_DBL}, + {"StringDamping" , __SK_ControlChange_, __SK_StringDamping_ , SK_DBL}, + {"StringDetune" , __SK_ControlChange_, __SK_StringDetune_ , SK_DBL}, + {"BodySize" , __SK_ControlChange_, __SK_BodySize_ , SK_DBL}, + {"BowPressure" , __SK_ControlChange_, __SK_BowPressure_ , SK_DBL}, + {"BowPosition" , __SK_ControlChange_, __SK_BowPosition_ , SK_DBL}, + {"BowBeta" , __SK_ControlChange_, __SK_BowBeta_ , SK_DBL}, + + {"ReedStiffness" , __SK_ControlChange_, __SK_ReedStiffness_ , SK_DBL}, + {"ReedRestPos" , __SK_ControlChange_, __SK_ReedRestPos_ , SK_DBL}, + {"FluteEmbouchure" , __SK_ControlChange_, __SK_FluteEmbouchure_, SK_DBL}, + {"LipTension" , __SK_ControlChange_, __SK_LipTension_ , SK_DBL}, + {"StrikePosition" , __SK_ControlChange_, __SK_StrikePosition_, SK_DBL}, + {"StickHardness" , __SK_ControlChange_, __SK_StickHardness_ , SK_DBL}, + + {"TrillDepth" , __SK_ControlChange_, __SK_TrillDepth_ , SK_DBL}, + {"TrillSpeed" , __SK_ControlChange_, __SK_TrillSpeed_ , SK_DBL}, + + {"Strumming" , __SK_ControlChange_, __SK_Strumming_ , 127 }, + {"NotStrumming" , __SK_ControlChange_, __SK_Strumming_ , 0 }, + + {"PlayerSkill" , __SK_ControlChange_, __SK_PlayerSkill_ , SK_DBL}, + + {"Chord" , __SK_Chord_ , SK_DBL , SK_STR }, + {"ChordOff" , __SK_ChordOff_ , SK_DBL , NOPE }, + + {"ShakerInst" , __SK_ControlChange_, __SK_ShakerInst_ , SK_DBL}, + {"Maraca" , __SK_ControlChange_, __SK_ShakerInst_ , 0 }, + {"Sekere" , __SK_ControlChange_, __SK_ShakerInst_ , 1 }, + {"Cabasa" , __SK_ControlChange_, __SK_ShakerInst_ , 2 }, + {"Bamboo" , __SK_ControlChange_, __SK_ShakerInst_ , 3 }, + {"Waterdrp" , __SK_ControlChange_, __SK_ShakerInst_ , 4 }, + {"Tambourn" , __SK_ControlChange_, __SK_ShakerInst_ , 5 }, + {"Sleighbl" , __SK_ControlChange_, __SK_ShakerInst_ , 6 }, + {"Guiro" , __SK_ControlChange_, __SK_ShakerInst_ , 7 }, + + {"OpenFile" , 256, SK_STR , NOPE}, + {"SetPath" , 257, SK_STR , NOPE}, + + {"FilePath" , __SK_SINGER_FilePath_, SK_STR , NOPE}, + {"Frequency" , __SK_SINGER_Frequency_, SK_STR , NOPE}, + {"NoteName" , __SK_SINGER_NoteName_, SK_STR , NOPE}, + {"VocalShape" , __SK_SINGER_Shape_ , SK_STR , NOPE}, + {"Glottis" , __SK_SINGER_Glot_ , SK_STR , NOPE}, + {"VoicedUnVoiced" , __SK_SINGER_VoicedUnVoiced_, SK_DBL , SK_STR}, + {"Synthesize" , __SK_SINGER_Synthesize_, SK_STR , NOPE}, + {"Silence" , __SK_SINGER_Silence_, SK_STR , NOPE}, + {"VibratoAmt" , __SK_ControlChange_ ,__SK_SINGER_VibratoAmt_,SK_DBL}, + {"RndVibAmt" , __SK_SINGER_RndVibAmt_ ,SK_STR, NOPE}, + {"VibFreq" , __SK_ControlChange_ ,__SK_SINGER_VibFreq_ ,SK_DBL} +}; + + +/** FORMAT: *************************************************************/ +/* */ +/* MessageStr$ ,type, data2, data3, */ +/* */ +/* type is the message type sent back from the SKINI line parser. */ +/* data is either */ +/* NOPE : field not used, specifically, there aren't going */ +/* to be any more fields on this line. So if there */ +/* is is NOPE in data2, data3 won't even be checked */ +/* SK_INT : byte (actually scanned as 32 bit signed integer) */ +/* If it's a MIDI data field which is required to */ +/* be an integer, like a controller number, it's */ +/* 0-127. Otherwise) get creative with SK_INTs */ +/* SK_DBL : double precision floating point. SKINI uses these */ +/* in the MIDI context for note numbers with micro */ +/* tuning, velocities, controller values, etc. */ +/* SK_STR : only valid in final field. This allows (nearly) */ +/* arbitrary message types to be supported by simply */ +/* scanning the string to EndOfLine and then passing */ +/* it to a more intellegent handler. For example, */ +/* MIDI SYSEX (system exclusive) messages of up to */ +/* 256bytes can be read as space-delimited integers */ +/* into the 1K SK_STR buffer. Longer bulk dumps, */ +/* soundfiles, etc. should be handled as a new */ +/* message type pointing to a FileName stored in the */ +/* SK_STR field, or as a new type of multi-line */ +/* message. */ +/* */ +/*************************************************************************/ diff --git a/STK98v2.dsw b/STK98v2.dsw new file mode 100644 index 0000000..48ebf3b --- /dev/null +++ b/STK98v2.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "MD2SKINI"=.\MD2SKINI.DSP - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "syntmono"=.\syntmono.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/STK98v2.ncb b/STK98v2.ncb new file mode 100644 index 0000000..d829cd6 Binary files /dev/null and b/STK98v2.ncb differ diff --git a/STK98v2.opt b/STK98v2.opt new file mode 100644 index 0000000..8e12d8b Binary files /dev/null and b/STK98v2.opt differ diff --git a/SamplFlt.cpp b/SamplFlt.cpp index 4704001..bbd58b3 100644 --- a/SamplFlt.cpp +++ b/SamplFlt.cpp @@ -11,17 +11,17 @@ SamplFlt :: SamplFlt() : Sampler() { - MY_FLOAT tempCoeffs[2] = {0.0,-1.0}; + MY_FLOAT tempCoeffs[2] = {(MY_FLOAT) 0.0,(MY_FLOAT) -1.0}; twozeroes[0] = new TwoZero; twozeroes[0]->setZeroCoeffs(tempCoeffs); - twozeroes[0]->setGain(1.0); + twozeroes[0]->setGain((MY_FLOAT) 1.0); twozeroes[1] = new TwoZero; twozeroes[1]->setZeroCoeffs(tempCoeffs); - twozeroes[1]->setGain(1.0); + twozeroes[1]->setGain((MY_FLOAT) 1.0); filters[0] = new FormSwep; - filters[0]->setTargets(0.0,0.7,0.5); + filters[0]->setTargets((MY_FLOAT) 0.0,(MY_FLOAT) 0.7,(MY_FLOAT) 0.5); filters[1] = new FormSwep; - filters[1]->setTargets(0.0,0.7,0.5); + filters[1]->setTargets((MY_FLOAT) 0.0,(MY_FLOAT) 0.7,(MY_FLOAT) 0.5); } SamplFlt :: ~SamplFlt() diff --git a/SamplFlt.h b/SamplFlt.h index fccd355..dd58117 100644 --- a/SamplFlt.h +++ b/SamplFlt.h @@ -21,7 +21,7 @@ class SamplFlt : public Sampler TwoZero *twozeroes[2]; public: SamplFlt(); - ~SamplFlt(); + virtual ~SamplFlt(); virtual MY_FLOAT tick(); virtual void controlChange(int number, MY_FLOAT value); }; diff --git a/Sampler.cpp b/Sampler.cpp index afc1427..3b26df0 100644 --- a/Sampler.cpp +++ b/Sampler.cpp @@ -13,10 +13,10 @@ Sampler :: Sampler() adsr = new ADSR; /* We don't make the waves here yet, because */ /* we don't know what they will be. */ - baseFreq = 440.0; + baseFreq = (MY_FLOAT) 440.0; filter = new OnePole; - attackGain = 0.25; - loopGain = 0.25; + attackGain = (MY_FLOAT) 0.25; + loopGain = (MY_FLOAT) 0.25; whichOne = 0; } diff --git a/Sampler.h b/Sampler.h index f2dd5d6..6017b16 100644 --- a/Sampler.h +++ b/Sampler.h @@ -12,6 +12,7 @@ #include "Instrmnt.h" #include "ADSR.h" #include "RawWave.h" +#include "RawLoop.h" #include "OnePole.h" class Sampler : public Instrmnt @@ -19,7 +20,7 @@ class Sampler : public Instrmnt protected: ADSR *adsr; RawWave *attacks[5]; - RawWave *loops[5]; + RawLoop *loops[5]; OnePole *filter; MY_FLOAT baseFreq; MY_FLOAT attackRatios[5]; @@ -29,7 +30,7 @@ class Sampler : public Instrmnt int whichOne; public: Sampler(); - ~Sampler(); + virtual ~Sampler(); void clear(); virtual void setFreq(MY_FLOAT frequency); void keyOn(); diff --git a/Shakers.cpp b/Shakers.cpp new file mode 100644 index 0000000..c647ad0 --- /dev/null +++ b/Shakers.cpp @@ -0,0 +1,643 @@ +/**********************************************************/ +/* PhISEM (Physically Informed Stochastic Event Modeling */ +/* by Perry R. Cook, Princeton, February 1997 */ +/* Meta-model that simulates all of: */ +/* Maraca Simulation by Perry R. Cook, Princeton, 1996-7 */ +/* Sekere Simulation by Perry R. Cook, Princeton, 1996-7 */ +/* Cabasa Simulation by Perry R. Cook, Princeton, 1996-7 */ +/* Bamboo Windchime Simulation, by Perry R. Cook, 1996-7 */ +/* Water Drops Simulation, by Perry R. Cook, 1996-7 */ +/* Tambourine Simulation, by Perry R. Cook, 1996-7 */ +/* Sleighbells Simulation, by Perry R. Cook, 1996-7 */ +/* Guiro Simulation, by Perry R. Cook, 1996-7 */ +/**********************************************************/ + +#include "Object.h" + +#ifdef __NeXT_ + #include +#endif + +int my_random(int max) { // Return Random Int Between 0 and max + unsigned long temp; + +#if defined(__OS_Linux_) /* RAND_MAX for Linux is 32 bit */ + temp = (unsigned long) rand() >> 16; +#else /* RAND_MAX for everything else is 16 bit */ + temp = (unsigned long) rand(); +#endif + temp *= (unsigned long) max; + temp >>= 15; + return (int) temp; +} + +MY_FLOAT noise_tick() // Return random MY_FLOAT float between -1.0 and 1.0 +{ + MY_FLOAT temp; + temp = (MY_FLOAT) (my_random(32767) - 16384); + temp *= 0.0000610351; + return temp; +} + +MY_FLOAT guiroScrape = 0; +MY_FLOAT shakeEnergy = 0.0; +MY_FLOAT input = 0.0,output[2] = {0.0,0.0}; +MY_FLOAT coeffs[2]; +MY_FLOAT input1 = 0.0,output1[2] = {0.0,0.0}; +MY_FLOAT coeffs1[2]; +MY_FLOAT input2 = 0.0,output2[2] = {0.0,0.0}; +MY_FLOAT coeffs2[2]; +MY_FLOAT input3 = 0.0,output3[2] = {0.0, 0.0}; +MY_FLOAT coeffs3[2]; +MY_FLOAT input4 = 0.0,output4[2] = {0.0, 0.0}; +MY_FLOAT coeffs4[2]; +MY_FLOAT sndLevel = 0.0; +MY_FLOAT gain = 0.0, gain1 = 0, gain2 = 0; +MY_FLOAT freq_rand = 0.0; +MY_FLOAT soundDecay = 0.0; +MY_FLOAT systemDecay = 0.0; +MY_FLOAT cymb_rand = 0.0; +long num_objects; +MY_FLOAT freq, freq1, freq2; + +MY_FLOAT collLikely,scrapeVel = 0.00015; +MY_FLOAT totalEnergy; +MY_FLOAT ratchet=0.0,ratchetDelta=0.0005; +MY_FLOAT finalZ[3] = {0.0, 0.0, 0.0}; + +/************************* MARACA *****************************/ +#define MARA_SOUND_DECAY 0.95 +#define MARA_SYSTEM_DECAY 0.999 +#define MARA_NUM_BEANS 25 + +void maraca_setup() { + num_objects = MARA_NUM_BEANS; + gain = log(num_objects) / log(4.0) * 40.0 / (MY_FLOAT) num_objects; + coeffs[0] = -0.96 * 2.0 * cos(3200.0 * TWO_PI / SRATE); + coeffs[1] = 0.96*0.96; + soundDecay = MARA_SOUND_DECAY; + systemDecay = MARA_SYSTEM_DECAY; +} + +MY_FLOAT maraca_tick() { + MY_FLOAT data; + shakeEnergy *= systemDecay; // Exponential system decay + if (my_random(1024) < num_objects) // If collision + sndLevel += gain * shakeEnergy; // add energy + input = sndLevel * noise_tick(); // Actual Sound is Random + sndLevel *= soundDecay; // Exponential Sound decay + input -= output[0]*coeffs[0]; // Do gourd + input -= output[1]*coeffs[1]; // resonance + output[1] = output[0]; // filter + output[0] = input; // calculations + data = output[0] - output[1]; // Extra zero for shape + return data; +} + +/*********************** SEKERE *****************************/ +#define SEKE_SOUND_DECAY 0.96 +#define SEKE_SYSTEM_DECAY 0.999 +#define SEKE_NUM_BEANS 64 + +void sekere_setup() { + num_objects = SEKE_NUM_BEANS; + gain = log(num_objects) / log(4.0) * 40.0 / (MY_FLOAT) num_objects; + coeffs[0] = -0.6 * 2.0 * cos(5500.0 * TWO_PI / SRATE); + coeffs[1] = 0.6*0.6; + soundDecay = SEKE_SOUND_DECAY; + systemDecay = SEKE_SYSTEM_DECAY; +} + +MY_FLOAT sekere_tick() { + MY_FLOAT data; + shakeEnergy *= systemDecay; // Exponential system decay + if (my_random(1024) < num_objects) // If collision + sndLevel += gain * shakeEnergy; // add energy + input = sndLevel * noise_tick(); // Actual Sound is Random + sndLevel *= soundDecay; // Exponential Sound decay + input -= output[0]*coeffs[0]; // Do gourd + input -= output[1]*coeffs[1]; // resonance + output[1] = output[0]; // filter + output[0] = input; // calculations + finalZ[2] = finalZ[1]; + finalZ[1] = finalZ[0]; + finalZ[0] = output[1]; + data = finalZ[0] - finalZ[2]; + return data * 2; // Normalization hack +} + +/************************ CABASA ***************************/ +#define CABA_SOUND_DECAY 0.95 +#define CABA_SYSTEM_DECAY 0.997 +#define CABA_NUM_BEADS 512 + +void cabasa_setup() { + num_objects = CABA_NUM_BEADS; + gain = log(num_objects) / log(4.0) * 120.0 / (MY_FLOAT) num_objects; + coeffs[0] = -0.7 * 2.0 * cos(3000.0 * TWO_PI / SRATE); + coeffs[1] = 0.7*0.7; + soundDecay = CABA_SOUND_DECAY; + systemDecay = CABA_SYSTEM_DECAY; +} + +MY_FLOAT cabasa_tick() { + MY_FLOAT data; + shakeEnergy *= systemDecay; // Exponential system decay + if (my_random(1024) < num_objects) // If collision + sndLevel += gain * shakeEnergy; // add energy + input = sndLevel * noise_tick(); // Actual Sound is Random + sndLevel *= soundDecay; // Exponential Sound decay + input -= output[0]*coeffs[0]; // Do gourd + input -= output[1]*coeffs[1]; // resonance + output[1] = output[0]; // filter + output[0] = input; // calculations + data = output[0] - output[1]; + return data * 2; // Normalization hack +} + +/************************ Bamboo Wind Chimes *****************/ +#define BAMB_SOUND_DECAY 0.95 +#define BAMB_SYSTEM_DECAY 0.99995 +#define BAMB_NUM_TUBES 5 +#define BAMB_BASE_FREQ 2800 + +void bamboo_setup() { + num_objects = BAMB_NUM_TUBES; + soundDecay = BAMB_SOUND_DECAY; + systemDecay = BAMB_SYSTEM_DECAY; + gain = 4.0 / (MY_FLOAT) num_objects; + coeffs[0] = -0.995 * 2.0 * cos(BAMB_BASE_FREQ * TWO_PI / SRATE); + coeffs[1] = 0.995*0.995; + coeffs1[0] = -0.995 * 2.0 * cos(BAMB_BASE_FREQ * 0.8 * TWO_PI / SRATE); + coeffs1[1] = 0.995*0.995; + coeffs2[0] = -0.995 * 2.0 * cos(BAMB_BASE_FREQ * 1.2 * TWO_PI / SRATE); + coeffs2[1] = 0.995*0.995; +} + +MY_FLOAT bamboo_tick() { + MY_FLOAT data; + shakeEnergy *= systemDecay; // Exponential System Decay + if (my_random(4096) < num_objects) { + sndLevel += gain * shakeEnergy; + freq_rand = BAMB_BASE_FREQ * (1.0 + (0.2 * noise_tick())); + coeffs[0] = -0.995 * 2.0 * + cos(freq_rand * TWO_PI / SRATE); + freq_rand = BAMB_BASE_FREQ * (0.8 + (0.2 * noise_tick())); + coeffs1[0] = -0.995 * 2.0 * + cos(freq_rand * TWO_PI / SRATE); + freq_rand = BAMB_BASE_FREQ * (1.2 + (0.2 * noise_tick())); + coeffs2[0] = -0.995 * 2.0 * + cos(freq_rand * TWO_PI / SRATE); + } + input = sndLevel; + input *= noise_tick(); // Actual Sound is Random + input1 = input; + input2 = input; + + sndLevel *= soundDecay; // Each (all) event(s) + // decay(s) exponentially + input -= output[0]*coeffs[0]; + input -= output[1]*coeffs[1]; + output[1] = output[0]; + output[0] = input; + data = output[0]; + input1 -= output1[0]*coeffs1[0]; + input1 -= output1[1]*coeffs1[1]; + output1[1] = output1[0]; + output1[0] = input1; + data += output1[0]; + input2 -= output2[0]*coeffs2[0]; + input2 -= output2[1]*coeffs2[1]; + output2[1] = output2[0]; + output2[0] = input2; + data += output2[0]; + return data * 0.5; // Normalization hack +} + +/******************* Water Drops ******************************/ +#define WUTR_SOUND_DECAY 0.95 +#define WUTR_NUM_SOURCES 4 +#define WUTR_FILT_POLE 0.9985 +#define WUTR_FREQ_SWEEP 1.0001 +#define WUTR_BASE_FREQ 600 + +void wuter_setup() { + num_objects = WUTR_NUM_SOURCES; + soundDecay = WUTR_SOUND_DECAY; + freq = WUTR_BASE_FREQ * TWO_PI / SRATE; + freq1 = WUTR_BASE_FREQ * 2.0 * TWO_PI / SRATE; + freq2 = WUTR_BASE_FREQ * 3.0 * TWO_PI / SRATE; + coeffs[0] = -WUTR_FILT_POLE * 2.0 * cos(freq); + coeffs[1] = WUTR_FILT_POLE * WUTR_FILT_POLE; + coeffs1[0] = -WUTR_FILT_POLE * 2.0 * cos(freq1); + coeffs1[1] = WUTR_FILT_POLE * WUTR_FILT_POLE; + coeffs2[0] = -WUTR_FILT_POLE * 2.0 * cos(freq2); + coeffs2[1] = WUTR_FILT_POLE * WUTR_FILT_POLE; +} +MY_FLOAT wuter_tick() { + MY_FLOAT data; + int j; + if (my_random(32767) < num_objects) { + sndLevel = shakeEnergy; + j = my_random(3); + if (j == 0) { + freq = WUTR_BASE_FREQ * (0.75 + (0.25 * noise_tick())); + gain = fabs(noise_tick()); + } + else if (j == 1) { + freq1 = WUTR_BASE_FREQ * (1.0 + (0.25 * noise_tick())); + gain1 = fabs(noise_tick()); + } + else { + freq2 = WUTR_BASE_FREQ * (1.25 + (0.25 * noise_tick())); + gain2 = fabs(noise_tick()); + } + } + + gain *= WUTR_FILT_POLE; + if (gain > 0.001) { + freq *= WUTR_FREQ_SWEEP; + coeffs[0] = -WUTR_FILT_POLE * 2.0 * + cos(freq * TWO_PI / SRATE); + } + gain1 *= WUTR_FILT_POLE; + if (gain1 > 0.001) { + freq1 *= WUTR_FREQ_SWEEP; + coeffs1[0] = -WUTR_FILT_POLE * 2.0 * + cos(freq1 * TWO_PI / SRATE); + } + gain2 *= WUTR_FILT_POLE; + if (gain2 > 0.001) { + freq2 *= WUTR_FREQ_SWEEP; + coeffs2[0] = -WUTR_FILT_POLE * 2.0 * + cos(freq2 * TWO_PI / SRATE); + } + + sndLevel *= soundDecay; // Each (all) event(s) + // decay(s) exponentially + input = sndLevel; + input *= noise_tick(); // Actual Sound is Random + input1 = input * gain1; + input2 = input * gain2; + input *= gain; + input -= output[0]*coeffs[0]; + input -= output[1]*coeffs[1]; + output[1] = output[0]; + output[0] = input; + data = output[0]; + input1 -= output1[0]*coeffs1[0]; + input1 -= output1[1]*coeffs1[1]; + output1[1] = output1[0]; + output1[0] = input1; + data += output1[0]; + input2 -= output2[0]*coeffs2[0]; + input2 -= output2[1]*coeffs2[1]; + output2[1] = output2[0]; + output2[0] = input2; + data += output2[0]; + + finalZ[2] = finalZ[1]; + finalZ[1] = finalZ[0]; + finalZ[0] = data * 4; + + data = finalZ[2] - finalZ[0]; + return data; +} + +/****************** TAMBOURINE ******************************/ +#define TAMB_SOUND_DECAY 0.95 +#define TAMB_SYSTEM_DECAY 0.9985 +#define TAMB_NUM_TIMBRELS 32 +#define TAMB_SHELL_FREQ 2300 +#define TAMB_SHELL_GAIN 0.1 +#define TAMB_CYMB_FREQ 5600 +#define TAMB_CYMB_FREQ2 8100 +#define TAMB_CYMB_RESON 0.99 + +void tambourine_setup() { + num_objects = TAMB_NUM_TIMBRELS; + soundDecay = TAMB_SOUND_DECAY; + systemDecay = TAMB_SYSTEM_DECAY; + gain = 24.0 / num_objects; + coeffs[0] = -0.96 * 2.0 * cos(TAMB_SHELL_FREQ * TWO_PI / SRATE); + coeffs[1] = 0.96*0.96; + coeffs1[0] = -TAMB_CYMB_RESON * 2.0 * cos(TAMB_CYMB_FREQ * TWO_PI / SRATE); + coeffs1[1] = TAMB_CYMB_RESON * TAMB_CYMB_RESON; + coeffs2[0] = -TAMB_CYMB_RESON * 2.0 * cos(TAMB_CYMB_FREQ2 * TWO_PI / SRATE); + coeffs2[1] = TAMB_CYMB_RESON * TAMB_CYMB_RESON; +} + +MY_FLOAT tambourine_tick() { + MY_FLOAT data; + shakeEnergy *= systemDecay; // Exponential System Decay + if (my_random(1024) < num_objects) { + sndLevel += gain * shakeEnergy; + cymb_rand = noise_tick() * TAMB_CYMB_FREQ * 0.05; + coeffs1[0] = -TAMB_CYMB_RESON * 2.0 * + cos((TAMB_CYMB_FREQ + cymb_rand) * TWO_PI / SRATE); + cymb_rand = noise_tick() * TAMB_CYMB_FREQ * 0.05; + coeffs2[0] = -TAMB_CYMB_RESON * 2.0 * + cos((TAMB_CYMB_FREQ2 + cymb_rand) * TWO_PI / SRATE); + } + input = sndLevel; + input *= noise_tick(); // Actual Sound is Random + input1 = input * 0.8; + input2 = input; + input *= TAMB_SHELL_GAIN; + + sndLevel *= soundDecay; // Each (all) event(s) + // decay(s) exponentially + input -= output[0]*coeffs[0]; + input -= output[1]*coeffs[1]; + output[1] = output[0]; + output[0] = input; + data = output[0]; + input1 -= output1[0]*coeffs1[0]; + input1 -= output1[1]*coeffs1[1]; + output1[1] = output1[0]; + output1[0] = input1; + data += output1[0]; + input2 -= output2[0]*coeffs2[0]; + input2 -= output2[1]*coeffs2[1]; + output2[1] = output2[0]; + output2[0] = input2; + data += output2[0]; + + finalZ[2] = finalZ[1]; + finalZ[1] = finalZ[0]; + finalZ[0] = data; + data = finalZ[2] - finalZ[0]; + + return data; +} + +/************************ SLEIGHBELLS **************************/ +#define SLEI_SOUND_DECAY 0.97 +#define SLEI_SYSTEM_DECAY 0.9994 +#define SLEI_NUM_BELLS 32 +#define SLEI_CYMB_FREQ0 2500 +#define SLEI_CYMB_FREQ1 5300 +#define SLEI_CYMB_FREQ2 6500 +#define SLEI_CYMB_FREQ3 8300 +#define SLEI_CYMB_FREQ4 9800 +#define SLEI_CYMB_RESON 0.99 + +void sleighbell_setup() { + num_objects = SLEI_NUM_BELLS; + soundDecay = SLEI_SOUND_DECAY; + systemDecay = SLEI_SYSTEM_DECAY; + gain = 8.0 / num_objects; + coeffs[0] = -SLEI_CYMB_RESON * 2.0 * cos(SLEI_CYMB_FREQ0 * TWO_PI / SRATE); + coeffs[1] = SLEI_CYMB_RESON*SLEI_CYMB_RESON; + coeffs1[0] = -SLEI_CYMB_RESON * 2.0 * cos(SLEI_CYMB_FREQ1 * TWO_PI / SRATE); + coeffs1[1] = SLEI_CYMB_RESON*SLEI_CYMB_RESON; + coeffs2[0] = -SLEI_CYMB_RESON * 2.0 * cos(SLEI_CYMB_FREQ2 * TWO_PI / SRATE); + coeffs2[1] = SLEI_CYMB_RESON*SLEI_CYMB_RESON; + coeffs3[0] = -SLEI_CYMB_RESON * 2.0 * cos(SLEI_CYMB_FREQ3 * TWO_PI / SRATE); + coeffs3[1] = SLEI_CYMB_RESON*SLEI_CYMB_RESON; + coeffs4[0] = -SLEI_CYMB_RESON * 2.0 * cos(SLEI_CYMB_FREQ4 * TWO_PI / SRATE); + coeffs4[1] = SLEI_CYMB_RESON*SLEI_CYMB_RESON; +} + +MY_FLOAT sleighbell_tick() { + MY_FLOAT data; + shakeEnergy *= systemDecay; // Exponential System Decay + if (my_random(1024) < num_objects) { + sndLevel += gain * shakeEnergy; + cymb_rand = noise_tick() * SLEI_CYMB_FREQ0 * 0.05; + coeffs[0] = -SLEI_CYMB_RESON * 2.0 * + cos((SLEI_CYMB_FREQ0 + cymb_rand) * TWO_PI / SRATE); + cymb_rand = noise_tick() * SLEI_CYMB_FREQ1 * 0.03; + coeffs1[0] = -SLEI_CYMB_RESON * 2.0 * + cos((SLEI_CYMB_FREQ1 + cymb_rand) * TWO_PI / SRATE); + cymb_rand = noise_tick() * SLEI_CYMB_FREQ2 * 0.03; + coeffs2[0] = -SLEI_CYMB_RESON * 2.0 * + cos((SLEI_CYMB_FREQ2 + cymb_rand) * TWO_PI / SRATE); + cymb_rand = noise_tick() * SLEI_CYMB_FREQ3 * 0.03; + coeffs3[0] = -SLEI_CYMB_RESON * 2.0 * + cos((SLEI_CYMB_FREQ3 + cymb_rand) * TWO_PI / SRATE); + cymb_rand = noise_tick() * SLEI_CYMB_FREQ4 * 0.03; + coeffs4[0] = -SLEI_CYMB_RESON * 2.0 * + cos((SLEI_CYMB_FREQ4 + cymb_rand) * TWO_PI / SRATE); + } + input = sndLevel; + input *= noise_tick(); // Actual Sound is Random + input1 = input; + input2 = input; + input3 = input * 0.5; + input4 = input * 0.3; + + sndLevel *= soundDecay; // Each (all) event(s) + // decay(s) exponentially + input -= output[0]*coeffs[0]; + input -= output[1]*coeffs[1]; + output[1] = output[0]; + output[0] = input; + data = output[0]; + + input1 -= output1[0]*coeffs1[0]; + input1 -= output1[1]*coeffs1[1]; + output1[1] = output1[0]; + output1[0] = input1; + data += output1[0]; + + input2 -= output2[0]*coeffs2[0]; + input2 -= output2[1]*coeffs2[1]; + output2[1] = output2[0]; + output2[0] = input2; + data += output2[0]; + + input3 -= output3[0]*coeffs3[0]; + input3 -= output3[1]*coeffs3[1]; + output3[1] = output3[0]; + output3[0] = input3; + data += output3[0]; + + input4 -= output4[0]*coeffs4[0]; + input4 -= output4[1]*coeffs4[1]; + output4[1] = output4[0]; + output4[0] = input4; + data += output4[0]; + + finalZ[2] = finalZ[1]; + finalZ[1] = finalZ[0]; + finalZ[0] = data; + data = finalZ[2] - finalZ[0]; + + return data; +} + +/**************************** GUIRO ***********************/ +#define GUIR_SOUND_DECAY 0.95 +#define GUIR_NUM_RATCHETS 128 +#define GUIR_GOURD_FREQ 2500.0 +#define GUIR_GOURD_RESON 0.97 +#define GUIR_GOURD_FREQ2 4000.0 +#define GUIR_GOURD_RESON2 0.97 + +void guiro_setup() { + num_objects = GUIR_NUM_RATCHETS; + soundDecay = GUIR_SOUND_DECAY; + coeffs[0] = -GUIR_GOURD_RESON * 2.0 * cos(GUIR_GOURD_FREQ * TWO_PI / SRATE); + coeffs[1] = GUIR_GOURD_RESON*GUIR_GOURD_RESON; + coeffs2[0] = -GUIR_GOURD_RESON2 * 2.0 * cos(GUIR_GOURD_FREQ2 * TWO_PI / SRATE); + coeffs2[1] = GUIR_GOURD_RESON2*GUIR_GOURD_RESON2; + ratchet = 0; + guiroScrape = 0; +} + +MY_FLOAT guiro_tick() { + MY_FLOAT data; + if (my_random(1024) < num_objects) { + sndLevel += 512 * ratchet * totalEnergy; + } + input = sndLevel; + input *= noise_tick() * ratchet; + sndLevel *= soundDecay; + + input2 = input; + input -= output[0]*coeffs[0]; + input -= output[1]*coeffs[1]; + output[1] = output[0]; + output[0] = input; + input2 -= output2[0]*coeffs2[0]; + input2 -= output2[1]*coeffs2[1]; + output2[1] = output2[0]; + output2[0] = input2; + + finalZ[2] = finalZ[1]; + finalZ[1] = finalZ[0]; + finalZ[0] = output[1] + output2[1]; + data = finalZ[0] - finalZ[2]; + return data; +} + +/******************* THE ACTUAL CLASS ITSELF ***********************/ + +#include "Shakers.h" +#include "SKINI11.msg" + +Shakers :: Shakers() : Instrmnt() +{ + instType = 0; +} + +Shakers :: ~Shakers() +{ +} + +#define MAX_SHAKE 2000.0 + +void Shakers :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +{ + shakeEnergy = amp * MAX_SHAKE * 0.1; +#if defined(_debug_) + printf("Shakers : NoteOn: Freq=%lf Amp=%lf\n",freq,amp); +#endif +} + +void Shakers :: noteOff(MY_FLOAT amp) +{ + shakeEnergy = 0.0; +} + +MY_FLOAT Shakers :: tick() +{ + if (instType==0) { + lastOutput = maraca_tick(); + } + else if (instType==1) { + lastOutput = sekere_tick(); + } + else if (instType==2) { + lastOutput = cabasa_tick(); + } + else if (instType==3) { + lastOutput = bamboo_tick(); + } + else if (instType==4) { + lastOutput = wuter_tick(); + } + else if (instType==5) { + lastOutput = tambourine_tick(); + } + else if (instType==6) { + lastOutput = sleighbell_tick(); + } + else if (instType==7) { + if (guiroScrape < 1.0) { + guiroScrape += scrapeVel; + totalEnergy = guiroScrape; + ratchet -= (ratchetDelta + (0.002*totalEnergy)); + if (ratchet<0.0) ratchet = 1.0; + lastOutput = guiro_tick(); + } + else lastOutput = 0.0; + } + + lastOutput *= 0.0001; + + return lastOutput; +} + +void Shakers :: controlChange(int number, MY_FLOAT value) +{ + MY_FLOAT temp; +#if defined(_debug_) + printf("Shakers : ControlChange: Number=%i Value=%f\n",number,value); +#endif + if (number == __SK_Breath_) { +#if defined(_debug_) + printf("shaking \n"); +#endif + shakeEnergy += value * NORM_7 * MAX_SHAKE * 0.1; + if (shakeEnergy > MAX_SHAKE) shakeEnergy = MAX_SHAKE; + } + else if (number == __SK_FootControl_) { +#if defined(_debug_) + printf("setting decay\n"); +#endif + systemDecay = 0.998 + (value * NORM_7 * 0.002); + } + else if (number == __SK_ModFrequency_) { +#if defined(_debug_) + printf("setting number of beans\n"); +#endif + num_objects = (int) value; + gain = log(num_objects) * 30.0 / (MY_FLOAT) num_objects; + } + else if (number == __SK_ModWheel_) { +#if defined(_debug_) + printf("setting resonance freq.\n"); +#endif + temp = 900 * pow (1.015,value); + coeffs[0] = -0.96 * 2.0 * cos(temp * TWO_PI / SRATE); + coeffs[1] = 0.96*0.96; + } + else if (number == __SK_AfterTouch_Cont_) { +#if defined(_debug_) + printf("shaking \n"); +#endif + shakeEnergy += value * NORM_7 * MAX_SHAKE * 0.1; + if (shakeEnergy > MAX_SHAKE) shakeEnergy = MAX_SHAKE; + } + else if (number == __SK_ShakerInst_) { + instType = (int) (value + 0.5); // Just to be safe + if (instType==0) maraca_setup(); + else if (instType==1) sekere_setup(); + else if (instType==2) cabasa_setup(); + else if (instType==3) bamboo_setup(); + else if (instType==4) wuter_setup(); + else if (instType==5) tambourine_setup(); + else if (instType==6) sleighbell_setup(); + else if (instType==7) guiro_setup(); + else { + instType = 0; + maraca_setup(); + } + } + else { + printf("Shakers : Undefined Control Number!!\n"); + } +} + diff --git a/Shakers.h b/Shakers.h new file mode 100644 index 0000000..8a82883 --- /dev/null +++ b/Shakers.h @@ -0,0 +1,35 @@ +/**********************************************************/ +/* PhISEM (Physically Informed Stochastic Event Modeling */ +/* by Perry R. Cook, Princeton, February 1997 */ +/* Meta-model that simulates all of: */ +/* Maraca Simulation by Perry R. Cook, Princeton, 1996-7 */ +/* Sekere Simulation by Perry R. Cook, Princeton, 1996-7 */ +/* Cabasa Simulation by Perry R. Cook, Princeton, 1996-7 */ +/* Bamboo Windchime Simulation, by Perry R. Cook, 1996-7 */ +/* Water Drops Simulation, by Perry R. Cook, 1996-7 */ +/* Tambourine Simulation, by Perry R. Cook, 1996-7 */ +/* Sleighbells Simulation, by Perry R. Cook, 1996-7 */ +/* Guiro Simulation, by Perry R. Cook, 1996-7 */ +/**********************************************************/ + + +#if !defined(__Shakers_h) +#define __Shakers_h + +#include "Instrmnt.h" + + +class Shakers : public Instrmnt +{ + protected: + int instType; + public: + Shakers(); + ~Shakers(); + virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); + virtual void noteOff(MY_FLOAT amp); + MY_FLOAT tick(); + virtual void controlChange(int number, MY_FLOAT value); +}; + +#endif diff --git a/Simple.cpp b/Simple.cpp new file mode 100644 index 0000000..c05b738 --- /dev/null +++ b/Simple.cpp @@ -0,0 +1,111 @@ +/*******************************************/ +/* Master Class for Simple Instrument */ +/* by Perry R. Cook, 1995-96 */ +/* This instrument contains 1 looped */ +/* wave, 1 noise source, 1 biquad filter */ +/* 1 one-pole filter, and 1 ADSR envelope */ +/*******************************************/ + +#include "Simple.h" + +Simple :: Simple() +{ + MY_FLOAT coeffs[2]; + adsr = new ADSR; + baseFreq = (MY_FLOAT) 440.0; + loop = new RawLoop("rawwaves/impuls10.raw"); + loop->normalize(); + filter = new OnePole; + noise = new Noise; + bqpoles = new TwoPole; + bqzeroes = new TwoZero; + coeffs[0] = 0; + coeffs[1] = -1; + bqzeroes->setZeroCoeffs(coeffs); + filter->setPole(0.5); + this->setFreq(baseFreq); + loopGain = 0.5; +} + +Simple :: ~Simple() +{ + delete adsr; + delete loop; + delete filter; + delete bqzeroes; + delete bqpoles; +} + +void Simple :: keyOn() +{ + adsr->keyOn(); +} + +void Simple :: keyOff() +{ + adsr->keyOff(); +} + +void Simple :: noteOn(MY_FLOAT freq, MY_FLOAT amp) +{ + this->keyOn(); + this->setFreq(freq); + filter->setGain(amp); +#if defined(_debug_) + printf("Simple : NoteOn: Freq= %lf, Amp=%lf\n",freq, amp); +#endif +} +void Simple :: noteOff(MY_FLOAT amplitude) +{ + this->keyOff(); +#if defined(_debug_) + printf("Simple : NoteOff: Amp=%lf\n",amplitude); +#endif +} + +void Simple :: setFreq(MY_FLOAT frequency) +{ +#define R 0.98 + + MY_FLOAT coeffs[2]; + coeffs[0] = 2 * R * cos(TWO_PI * ONE_OVER_SRATE * frequency); + coeffs[1] = - R * R; + bqpoles->setPoleCoeffs(coeffs); + bqpoles->setGain(1.0 - R); + loop->setFreq(frequency); +} + +MY_FLOAT Simple :: tick() +{ + lastOutput = loopGain * loop->tick(); + bqzeroes->tick(bqpoles->tick(noise->tick())); + lastOutput += (1.0 - loopGain) * bqzeroes->lastOut(); + lastOutput = filter->tick(lastOutput); + lastOutput *= adsr->tick(); + return lastOutput; +} + +#include "SKINI11.msg" + +void Simple :: controlChange(int number, MY_FLOAT value) +{ +#if defined(_debug_) + printf("Simple : ControlChange: Number=%i Value=%f\n",number,value); +#endif + if (number == __SK_Breath_) + filter->setPole(0.99 * (1.0 - (value * NORM_7 * 2.0))); + else if (number == __SK_NoiseLevel_) + loopGain = 1.0 - (NORM_7 * value); + else if (number == __SK_ModFrequency_) { + adsr->setAttackRate(value * NORM_7); + adsr->setDecayRate(value * NORM_7); + adsr->setReleaseRate(value * NORM_7); + } + else if (number == __SK_ModWheel_) + printf("Mod Wheel Unimplemented\n"); + else if (number == __SK_AfterTouch_Cont_) + adsr->setTarget(value * NORM_7); + else { + printf("Simple : Undefined Control Number!!\n"); + } +} diff --git a/Simple.h b/Simple.h new file mode 100644 index 0000000..3084cbe --- /dev/null +++ b/Simple.h @@ -0,0 +1,44 @@ +/*******************************************/ +/* Master Class for Simple Instrument */ +/* by Perry R. Cook, 1995-96 */ +/* This instrument contains 1 looped */ +/* wave, 1 noise source, 1 biquad filter */ +/* 1 one-pole filter, and 1 ADSR envelope */ +/*******************************************/ + +#if !defined(__Simple_h) +#define __Simple_h + +#include "Instrmnt.h" +#include "ADSR.h" +#include "RawLoop.h" +#include "OnePole.h" +#include "TwoPole.h" +#include "TwoZero.h" +#include "Noise.h" + +class Simple : public Instrmnt +{ + protected: + ADSR *adsr; + RawLoop *loop; + OnePole *filter; + TwoPole *bqpoles; + TwoZero *bqzeroes; + Noise *noise; + MY_FLOAT baseFreq; + MY_FLOAT loopGain; + public: + Simple(); + ~Simple(); + void clear(); + virtual void setFreq(MY_FLOAT frequency); + void keyOn(); + void keyOff(); + virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); + virtual void noteOff(MY_FLOAT amplitude); + virtual MY_FLOAT tick(); + virtual void controlChange(int number, MY_FLOAT value); +}; + +#endif diff --git a/SingWave.cpp b/SingWave.cpp index 5cc6d2a..9109e0e 100644 --- a/SingWave.cpp +++ b/SingWave.cpp @@ -11,169 +11,173 @@ /*******************************************/ #include "SingWave.h" - +#include "swapstuf.h" + SingWave :: SingWave(char *fileName) { - long i; - short temp; - FILE *fd; - fd = fopen(fileName,"rb"); - if (!fd) { - printf("Couldn't find soundfile %s !!!!!!!!\n",fileName); - } - i = 0; - while (fread(&temp,2,1,fd)) i++; - length = i; - fseek(fd,0,0); - data = (MY_FLOAT *) malloc(MY_FLOAT_SIZE * (length + 1)); - i = 0; - while (fread(&temp,2,1,fd)) { - data[i] = temp; - i++; - } - data[length] = data[length-1]; - fclose(fd); - mytime = 0.0; - rate = 1.0; - sweepRate = 0.001; - modulator = new Modulatr; - modulator->setVibFreq(6.0); - modulator->setVibAmt(0.04); - modulator->setRndAmt(0.005); - envelope = new Envelope; - pitchEnvelope = new Envelope; - this->setFreq(75.0); - pitchEnvelope->setRate(1.0); - this->tick(); - this->tick(); - pitchEnvelope->setRate(sweepRate * rate); + long i; + short temp; + FILE *fd; + // extern short SwapShort(short); + + fd = fopen(fileName,"rb"); + if (!fd) { + printf("Couldn't find soundfile %s !!!!!!!!\n",fileName); + } + i = 0; + while (fread(&temp,2,1,fd)) i++; + length = i; + fseek(fd,0,0); + data = (MY_FLOAT *) malloc(MY_FLOAT_SIZE * (length + 1)); + i = 0; + while (fread(&temp,2,1,fd)) { +#ifdef __LITTLE_ENDIAN__ + temp = SwapShort(temp); +#endif + data[i] = temp; + i++; + } + data[length] = data[length-1]; + fclose(fd); + mytime = (MY_FLOAT) 0.0; + rate = (MY_FLOAT) 1.0; + sweepRate = (MY_FLOAT) 0.001; + modulator = new Modulatr; + modulator->setVibFreq((MY_FLOAT) 6.0); + modulator->setVibAmt((MY_FLOAT) 0.04); + modulator->setRndAmt((MY_FLOAT) 0.005); + envelope = new Envelope; + pitchEnvelope = new Envelope; + this->setFreq((MY_FLOAT) 75.0); + pitchEnvelope->setRate((MY_FLOAT) 1.0); + this->tick(); + this->tick(); + pitchEnvelope->setRate(sweepRate * rate); } SingWave :: ~SingWave() { - delete modulator; - delete envelope; - delete pitchEnvelope; - free(data); + delete modulator; + delete envelope; + delete pitchEnvelope; + free(data); } void SingWave :: reset() { - mytime = 0.0; - lastOutput = 0.0; + mytime = (MY_FLOAT) 0.0; + lastOutput = (MY_FLOAT) 0.0; } void SingWave :: normalize() { - long i; - MY_FLOAT max = 0.0; - for (i=0;i<=length;i++) - if (fabs(data[i]) > max) - max = fabs(data[i]); - if (max > 0.0) { - max = 1.0 / max; + long i; + MY_FLOAT max = (MY_FLOAT) 0.0; for (i=0;i<=length;i++) + if (fabs(data[i]) > max) + max = (MY_FLOAT) fabs((double) data[i]); + if (max > 0.0) { + max = (MY_FLOAT) 1.0 / max; + for (i=0;i<=length;i++) data[i] *= max; - } + } } void SingWave :: normalize(MY_FLOAT newPeak) { - long i; - MY_FLOAT max = 0.0; - for (i=0;i<=length;i++) - if (fabs(data[i]) > max) - max = fabs(data[i]); - if (max > 0.0) { - max = 1.0 / max; - max *= newPeak; + long i; + MY_FLOAT max = (MY_FLOAT) 0.0; for (i=0;i<=length;i++) + if (fabs(data[i]) > max) + max = (MY_FLOAT) fabs((double) data[i]); + if (max > 0.0) { + max = (MY_FLOAT) 1.0 / max; + max *= newPeak; + for (i=0;i<=length;i++) data[i] *= max; - } + } } void SingWave :: setFreq(MY_FLOAT aFreq) { - MY_FLOAT temp; - temp = rate; - rate = length * ONE_OVER_SRATE * aFreq; - temp -= rate; - if (temp<0) temp = -temp; - pitchEnvelope->setTarget(rate); - pitchEnvelope->setRate(sweepRate * temp); + MY_FLOAT temp; + temp = rate; + rate = length * ONE_OVER_SRATE * aFreq; + temp -= rate; + if (temp<0) temp = -temp; + pitchEnvelope->setTarget(rate); + pitchEnvelope->setRate(sweepRate * temp); } void SingWave :: setVibFreq(MY_FLOAT vibFreq) { - modulator->setVibFreq(vibFreq); + modulator->setVibFreq(vibFreq); } void SingWave :: setVibAmt(MY_FLOAT vibAmount) { - modulator->setVibAmt(vibAmount); + modulator->setVibAmt(vibAmount); } void SingWave :: setRndAmt(MY_FLOAT rndAmount) { - modulator->setRndAmt(rndAmount); + modulator->setRndAmt(rndAmount); } void SingWave :: setSweepRate(MY_FLOAT swpRate) { - sweepRate = swpRate; + sweepRate = swpRate; } void SingWave :: setGainRate(MY_FLOAT gainRate) { - envelope->setRate(gainRate); + envelope->setRate(gainRate); } void SingWave :: setGainTarget(MY_FLOAT aTarget) { - envelope->setTarget(aTarget); + envelope->setTarget(aTarget); } void SingWave :: noteOn() { - envelope->keyOn(); + envelope->keyOn(); } void SingWave :: noteOff() { - envelope->keyOff(); + envelope->keyOff(); } MY_FLOAT SingWave :: tick() { - long temp; - MY_FLOAT alpha, temp_rate; + long temp; + MY_FLOAT alpha, temp_rate; - temp_rate = pitchEnvelope->tick(); - mytime += temp_rate; /* Update current time */ - mytime += temp_rate * - modulator->tick(); /* Add vibratos */ + temp_rate = pitchEnvelope->tick(); + mytime += temp_rate; /* Update current time */ + mytime += temp_rate * modulator->tick(); /* Add vibratos */ - while (mytime >= length) { /* Check for end of sound */ - mytime -= length; /* loop back to beginning */ - } - while (mytime < 0.0) { /* Check for end of sound */ - mytime += length; /* loop back to beginning */ - } + while (mytime >= length) { /* Check for end of sound */ + mytime -= length; /* loop back to beginning */ + } + while (mytime < 0.0) { /* Check for end of sound */ + mytime += length; /* loop back to beginning */ + } - temp = (long) mytime; /* Integer part of time address */ - alpha = mytime - (MY_FLOAT) temp; /* fractional part of time address*/ + temp = (long) mytime; /* Integer part of time address */ + alpha = mytime - (MY_FLOAT) temp; /* fractional part of time address */ - lastOutput = alpha * data[temp+1]; /* Do linear */ - lastOutput += (1.0 - alpha) * - data[temp]; /* interpolation */ - lastOutput *= envelope->tick(); + lastOutput = alpha * data[temp+1]; /* Do linear */ + lastOutput += ((MY_FLOAT) 1.0 - alpha) * data[temp]; /* interpolation */ + lastOutput *= envelope->tick(); - return lastOutput; + return lastOutput; } MY_FLOAT SingWave :: lastOut() { - return lastOutput; + return lastOutput; } /************ Test Main Program *****************/ diff --git a/SndWvOut.cpp b/SndWvOut.cpp new file mode 100644 index 0000000..0dca7ee --- /dev/null +++ b/SndWvOut.cpp @@ -0,0 +1,168 @@ +/*******************************************/ +/* NeXT Sound File Output Class, */ +/* by Perry R. Cook, 1995-96 */ +/* This version opens a mono NeXT .snd */ +/* file 16bit data at 22KHz, and */ +/* pokes buffers of samples into it. */ +/*******************************************/ + +/*******************************************/ +/* NeXT Soundfile Output Class, Improved */ +/* by Perry R. Cook, 1996 */ +/* This one opens a NeXT .snd file, and */ +/* even knows how to byte-swap! */ +/*******************************************/ + +#include "SndWvOut.h" + +#ifdef __LITTLE_ENDIAN__ + #include "swapstuf.h" +#endif + +/******** NeXT Soundfile Header Struct *******/ +struct headerform { + char pref[4]; + long hdr_length; + long file_length; + long mode; + long samp_rate; + long num_channels; + char comment[16]; +}; + +FILE *openNeXTFile(int chans,char *fileName) { + struct headerform hdr = {".sn",40,0,3,(long) SRATE,1,"STK98"}; + char tempName[128]; + FILE *fd; + + hdr.pref[3] = 'd'; + + strcpy(tempName,fileName); + strcat(tempName,".snd"); + hdr.num_channels = chans; + fd = fopen(tempName,"wb"); + if (!fd) { + printf("Couldn't create soundfile %s !!!!!!!!\n",fileName); + exit(0); + } +#ifdef __LITTLE_ENDIAN__ + hdr.hdr_length = SwapInt (hdr.hdr_length); + hdr.file_length = SwapInt (hdr.file_length); + hdr.mode = SwapInt (hdr.mode); + hdr.samp_rate = SwapInt (hdr.samp_rate); + hdr.num_channels = SwapInt (hdr.num_channels); +#endif + printf("Creating soundfile %s.\n", tempName); + fwrite(&hdr,4,10,fd); + return fd; +} + +SndWvOut :: SndWvOut(char *fileName) +{ + chans = 1; + pan = 0.5; + fd = openNeXTFile(chans,fileName); + counter = 0; + totalCount = 0; +} + +SndWvOut :: SndWvOut(int channels, char *fileName) +{ + chans = channels; + pan = 0.5; + fd = openNeXTFile(chans,fileName); + counter = 0; + totalCount = 0; +} + +SndWvOut :: ~SndWvOut() +{ + double temp; + + fwrite(data,2,counter,fd); + fseek(fd,8,SEEK_SET); + temp = (double) totalCount * ONE_OVER_SRATE; + printf("%f Seconds Computed\n",temp); + totalCount *= 2*chans; +#ifdef __LITTLE_ENDIAN__ + totalCount = SwapInt (totalCount); +#endif + fwrite(&totalCount,4,1,fd); + fclose(fd); +} + +long SndWvOut :: getCounter() +{ + return totalCount; +} + +MY_FLOAT SndWvOut :: getTime() +{ + return (MY_FLOAT) totalCount * ONE_OVER_SRATE; +} + +void SndWvOut :: tick(MY_FLOAT sample) +{ + short isample; + + isample = (short) (sample * 32000.0); + if (chans==1) { + data[counter] = isample; +#ifdef __LITTLE_ENDIAN__ + data[counter] = SwapShort (data[counter]); +#endif + counter += 1; + } + else { + data[counter] = (short) (isample * (1.0 - pan)); + data[counter+1] = (short) (isample * pan); +#ifdef __LITTLE_ENDIAN__ + data[counter] = SwapShort (data[counter]); + data[counter+1] = SwapShort (data[counter+1]); +#endif + counter += 2; + } + totalCount += 1; + if (counter == SND_BUFFER_SIZE) { + fwrite(data,2,SND_BUFFER_SIZE,fd); + counter = 0; + } +} + +void SndWvOut :: tick(MY_FLOAT lsamp, MY_FLOAT rsamp) +{ + if (chans==1) { + data[counter] = (short) ((lsamp + rsamp) * 16000.0); +#ifdef __LITTLE_ENDIAN__ + data[counter] = SwapShort (data[counter]); +#endif + counter += 1; + } + else { + data[counter] = (short) (lsamp * 32000.0); + data[counter+1] = (short) (rsamp * 32000.0); +#ifdef __LITTLE_ENDIAN__ + data[counter] = SwapShort (data[counter]); + data[counter+1] = SwapShort (data[counter+1]); +#endif + counter += 2; + } + totalCount += 1; + if (counter == SND_BUFFER_SIZE) { + fwrite(data,2,SND_BUFFER_SIZE,fd); + counter = 0; + } +} + +void SndWvOut :: setMonoPan(MY_FLOAT aPan) +{ + pan = aPan; + if (aPan < 0.0) { + pan = 0.0; + printf("Pan < 0.0, correcting to 0.0\n"); + } + if (aPan > 1.0) { + pan = 1.0; + printf("Pan > 1.0, correcting to 1.0\n"); + } +} diff --git a/SndWvOut.h b/SndWvOut.h new file mode 100644 index 0000000..4c7f9b7 --- /dev/null +++ b/SndWvOut.h @@ -0,0 +1,44 @@ +/*******************************************/ +/* NeXT Sound File Output Class, */ +/* by Perry R. Cook, 1995-96 */ +/* For now, This Object can open a raw */ +/* 16bit data (signed integers) file, and */ +/* poke buffers of samples into it. */ +/*******************************************/ + +/*******************************************/ +/* NeXT Soundfile Output Class, Improved */ +/* by Perry R. Cook, 1996 */ +/* This one opens a NeXT .snd file, and */ +/* even knows how to byte-swap! */ +/*******************************************/ + +#include "Object.h" +#include "WvOut.h" + +#if !defined(__SndWvOut_h) +#define __SndWvOut_h + +#define SND_BUFFER_SIZE 1024 + +class SndWvOut : public WvOut +{ + protected: + FILE *fd; + short data[SND_BUFFER_SIZE]; + long counter; + long totalCount; + int chans; + MY_FLOAT pan; + public: + SndWvOut(char *fileName); + SndWvOut(int channels, char *fileName); + ~SndWvOut(); + long getCounter(); + MY_FLOAT getTime(); + void setMonoPan(MY_FLOAT aPan); + void tick(MY_FLOAT sample); + void tick(MY_FLOAT lsamp, MY_FLOAT rsamp); +}; + +#endif // defined(__SndWvOut_h) diff --git a/SubNoise.cpp b/SubNoise.cpp index 23dc24c..d426552 100644 --- a/SubNoise.cpp +++ b/SubNoise.cpp @@ -8,7 +8,7 @@ SubNoise :: SubNoise() : Noise() { - lastOutput = 0.0; + lastOutput = (MY_FLOAT) 0.0; howOften = 15; counter = 15; } @@ -20,7 +20,7 @@ SubNoise :: ~SubNoise() SubNoise :: SubNoise(int subSample) : Noise() { - lastOutput = 0.0; + lastOutput = (MY_FLOAT) 0.0; howOften = subSample-1; counter = subSample-1; } diff --git a/TCLSpecs/.swp b/TCLSpecs/.swp new file mode 100644 index 0000000..1bd546b Binary files /dev/null and b/TCLSpecs/.swp differ diff --git a/TCLSpecs/GUIDrums b/TCLSpecs/GUIDrums new file mode 100755 index 0000000..38e1945 --- /dev/null +++ b/TCLSpecs/GUIDrums @@ -0,0 +1,2 @@ +cd .. +wish < TCLSpecs/TCLDrums.tcl | syntmono DrumSynt -r -i diff --git a/TCLSpecs/GUIPhysical b/TCLSpecs/GUIPhysical index 18e408a..159f47b 100755 --- a/TCLSpecs/GUIPhysical +++ b/TCLSpecs/GUIPhysical @@ -1,2 +1,2 @@ cd .. -wish < TCLSpecs/TCLPhys.tcl | testTextIn Clarinet +wish < TCLSpecs/TCLPhys.tcl | syntmono Clarinet -r -i diff --git a/TCLSpecs/GUIPlukStruk b/TCLSpecs/GUIPlukStruk index d1b6bef..963625f 100755 --- a/TCLSpecs/GUIPlukStruk +++ b/TCLSpecs/GUIPlukStruk @@ -1,2 +1,2 @@ cd .. -wish < TCLSpecs/TCLStruk.tcl | testTextIn Mandolin +wish < TCLSpecs/TCLStruk.tcl | syntmono Mandolin -r -i diff --git a/TCLSpecs/GUIShakers b/TCLSpecs/GUIShakers new file mode 100755 index 0000000..4004dcf --- /dev/null +++ b/TCLSpecs/GUIShakers @@ -0,0 +1,2 @@ +cd .. +wish < TCLSpecs/TCLShakers.tcl | syntmono Maraca -r -i diff --git a/TCLSpecs/GUIVoice b/TCLSpecs/GUIVoice index 3952696..3892f2d 100755 --- a/TCLSpecs/GUIVoice +++ b/TCLSpecs/GUIVoice @@ -1,2 +1,2 @@ cd .. -wish < TCLSpecs/TCLVoice.tcl | testTextIn FMVoices +wish < TCLSpecs/TCLVoice.tcl | syntmono FMVoices -r -i diff --git a/TCLSpecs/MIDIPhysical b/TCLSpecs/MIDIPhysical index ff186fe..4f3d085 100755 --- a/TCLSpecs/MIDIPhysical +++ b/TCLSpecs/MIDIPhysical @@ -1,2 +1,2 @@ cd .. -testMIDI | testTextIn Clarinet +MD2SKINI | syntmono Clarinet -r -i diff --git a/TCLSpecs/MIDIPlukStruk b/TCLSpecs/MIDIPlukStruk index a38440c..a053831 100755 --- a/TCLSpecs/MIDIPlukStruk +++ b/TCLSpecs/MIDIPlukStruk @@ -1,2 +1,2 @@ cd .. -testMIDI | testTextIn Mandolin +MD2SKINI | syntmono Mandolin -r -i diff --git a/TCLSpecs/MIDIVoice b/TCLSpecs/MIDIVoice index 9f7b20a..f6ee005 100755 --- a/TCLSpecs/MIDIVoice +++ b/TCLSpecs/MIDIVoice @@ -1,2 +1,2 @@ cd .. -testMIDI | testTextIn FMVoices +MD2SKINI | syntmono FMVoices -r -i diff --git a/TCLSpecs/TCLDrums.tcl b/TCLSpecs/TCLDrums.tcl new file mode 100644 index 0000000..98a3214 --- /dev/null +++ b/TCLSpecs/TCLDrums.tcl @@ -0,0 +1,152 @@ +set press 127 +set outID "stdout" +set commtype "stdout" + +# Configure main window +wm title . "STK Drum Controller" +wm iconname . "drum" +. config -bg black + +# Configure "communications" menu +menu .menu -tearoff 0 +menu .menu.communication -tearoff 0 +.menu add cascade -label "Communication" -menu .menu.communication \ + -underline 0 +.menu.communication add radio -label "Console" -variable commtype \ + -value "stdout" -command { setComm } +.menu.communication add radio -label "Socket" -variable commtype \ + -value "socket" -command { setComm } +. configure -menu .menu + +# Configure slider +scale .bPressure -from 0 -to 128 -length 100 \ +-command {changePress } -variable press\ +-orient horizontal -label "Velocity" \ +-tickinterval 64 -showvalue true -bg grey66 + +pack .bPressure -pady 5 -padx 5 + +# Configure buttons +frame .buttons -bg black +frame .buttons.left -bg black +frame .buttons.right -bg black + +button .buttons.left.bass -text Bass -bg grey66 \ +-command { playDrum 36 } -width 7 +button .buttons.left.snare -text Snare -bg grey66 \ +-command { playDrum 38 } -width 7 +button .buttons.left.tomlo -text LoTom -bg grey66 \ +-command { playDrum 41 } -width 7 +button .buttons.left.tommid -text MidTom -bg grey66 \ +-command { playDrum 45 } -width 7 +button .buttons.left.tomhi -text HiTom -bg grey66 \ +-command { playDrum 50 } -width 7 +button .buttons.left.homer -text Homer -bg grey66 \ +-command { playDrum 90 } -width 7 +button .buttons.right.hat -text Hat -bg grey66 \ +-command { playDrum 42 } -width 7 +button .buttons.right.ride -text Ride -bg grey66 \ +-command { playDrum 46 } -width 7 +button .buttons.right.crash -text Crash -bg grey66 \ +-command { playDrum 49 } -width 7 +button .buttons.right.cowbel -text CowBel -bg grey66 \ +-command { playDrum 56 } -width 7 +button .buttons.right.tamb -text Tamb -bg grey66 \ +-command { playDrum 54 } -width 7 +button .buttons.right.homer -text Homer -bg grey66 \ +-command { playDrum 90 } -width 7 + +pack .buttons.left.bass -pady 5 +pack .buttons.left.snare -pady 5 +pack .buttons.left.tomlo -pady 5 +pack .buttons.left.tommid -pady 5 +pack .buttons.left.tomhi -pady 5 +pack .buttons.left.homer -pady 5 +pack .buttons.right.hat -pady 5 +pack .buttons.right.ride -pady 5 +pack .buttons.right.crash -pady 5 +pack .buttons.right.cowbel -pady 5 +pack .buttons.right.tamb -pady 5 +pack .buttons.right.homer -pady 5 + +pack .buttons.left -side left -pady 5 -padx 5 +pack .buttons.right -side right -pady 5 -padx 5 +pack .buttons -pady 5 -padx 5 + +# Configure exit button +button .exit -text "Exit Program" -bg grey66 -command myExit +pack .exit -side bottom -pady 20 + +proc myExit {} { + global outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} + +proc playDrum {value} { + global press + global outID + puts $outID [format "NoteOn 0.0 1 %i %f" $value $press] + flush $outID +} + +proc changePress {value} { + global press + set press $value +} + +# Socket connection procedure +set d .socketdialog + +proc setComm {} { + global outID + global commtype + global d + if {$commtype == "stdout"} { + if { [string compare "stdout" $outID] } { + set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] + switch $i { + 0 {set commtype "socket"} + 1 {close $outID + set outID "stdout"} + } + } + } elseif { ![string compare "stdout" $outID] } { + set sockport 2001 + toplevel $d + wm title $d "STK Client Socket Connection" + wm resizable $d 0 0 + grab $d + label $d.message -text "Specify a socket port number below (if different than the STK default of 2001) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ + -background white -font {Helvetica 10 bold} \ + -wraplength 3i -justify left + frame $d.sockport + entry $d.sockport.entry -width 6 + label $d.sockport.text -text "Socket Port Number:" \ + -font {Helvetica 10 bold} + pack $d.message -side top -padx 5 -pady 10 + pack $d.sockport.text -side left -padx 1 -pady 10 + pack $d.sockport.entry -side right -padx 5 -pady 10 + pack $d.sockport -side top -padx 5 -pady 10 + $d.sockport.entry insert 0 $sockport + frame $d.buttons + button $d.buttons.cancel -text "Cancel" -bg grey66 \ + -command { set commtype "stdout" + set outID "stdout" + destroy $d } + button $d.buttons.connect -text "Connect" -bg grey66 \ + -command { + set sockport [$d.sockport.entry get] + set err [catch {socket localhost $sockport} outID] + if {$err == 0} { + destroy $d + } else { + tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK + } } + pack $d.buttons.cancel -side left -padx 5 -pady 10 + pack $d.buttons.connect -side right -padx 5 -pady 10 + pack $d.buttons -side bottom -padx 5 -pady 10 + } +} diff --git a/TCLSpecs/TCLPhys.tcl b/TCLSpecs/TCLPhys.tcl index bcd8b34..64e0c06 100644 --- a/TCLSpecs/TCLPhys.tcl +++ b/TCLSpecs/TCLPhys.tcl @@ -1,128 +1,60 @@ set pitch 64.0 set press 64.0 +set cont1 0.0 +set cont2 20.0 +set cont4 64.0 +set cont11 64.0 +set outID "stdout" +set commtype "stdout" +set patchnum 0 -button .pretty -bitmap @TCLSpecs/bitmaps/prcFunny.xbm \ --background white -foreground black -.pretty config -bitmap @TCLSpecs/bitmaps/prc.xbm +# Configure main window +wm title . "STK Physical Model Controller" +wm iconname . "physical" +. config -bg black -proc myExit {} { - puts stdout [format "ExitProgram"] - flush stdout - exit -} - -proc noteOn {pitchVal pressVal} { - puts stdout [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal] - flush stdout -} - -proc noteOff {pitchVal pressVal} { - puts stdout [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal] - flush stdout -} - -proc patchChange {value} { - global .pretty - puts stdout [format "ProgramChange 0.0 1 %i" $value] - if {$value==0} { - .pretty config -bitmap @TCLSpecs/bitmaps/Klar.xbm - } - if {$value==1} { - .pretty config -bitmap @TCLSpecs/bitmaps/KFloot.xbm - } - if {$value==2} { - .pretty config -bitmap @TCLSpecs/bitmaps/KHose.xbm - } - if {$value==3} { - .pretty config -bitmap @TCLSpecs/bitmaps/KFiddl.xbm - } - flush stdout -} - -proc printWhatz {tag value1 value2 } { - puts stdout [format "%s %i %f" $tag $value1 $value2] - flush stdout -} - -proc changePress {value} { - global press - set press $value - puts stdout [format "AfterTouch 0.0 1 %f" $press] - flush stdout -} - -proc changePitch {value} { - global pitch - set pitch $value - puts stdout [format "PitchBend 0.0 1 %f" $pitch] - flush stdout -} - -scale .bPressure -from 0 -to 128 -length 200 \ --command {changePress } \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Breath Pressure" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .pitch -from 0 -to 128 -length 200 \ --command {changePitch } \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "MIDI Note Number" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .cont1 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange 0.0 1 " 2} \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Reed, Emb., Lip., Bow Pres." \ --tickinterval 32 -showvalue true -bg grey66 - -scale .cont2 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange 0.0 1 " 4} \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Noise Amt., Slide Length,Bow Pos." \ --tickinterval 32 -showvalue true -bg grey66 - -scale .cont3 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange 0.0 1 " 11} \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Vibrato Rate" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .vibrato -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange 0.0 1 " 1} \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Vibrato Amount" \ --tickinterval 32 -showvalue true -bg grey66 - -. config -bg grey20 +# Configure "communications" menu +menu .menu -tearoff 0 +menu .menu.communication -tearoff 0 +.menu add cascade -label "Communication" -menu .menu.communication \ + -underline 0 +.menu.communication add radio -label "Console" -variable commtype \ + -value "stdout" -command { setComm } +.menu.communication add radio -label "Socket" -variable commtype \ + -value "socket" -command { setComm } +. configure -menu .menu +# Configure patch change buttons frame .instChoice -bg black -radiobutton .instChoice.clar -text Clarinet -bg grey66 \ --command { patchChange 0 } -radiobutton .instChoice.flut -text Flute -bg grey66 \ --command { patchChange 1 } -radiobutton .instChoice.bras -text Brass -bg grey66 \ --command { patchChange 2 } -radiobutton .instChoice.bowd -text Bowed -bg grey66 \ --command { patchChange 3 } +radiobutton .instChoice.clar -text "Clarinet" -bg grey66 \ + -variable patchnum -value 0 -command { patchChange $patchnum } +radiobutton .instChoice.flut -text "Flute" -bg grey66 \ + -variable patchnum -value 1 -command { patchChange $patchnum } +radiobutton .instChoice.bras -text "Brass" -bg grey66 \ + -variable patchnum -value 2 -command { patchChange $patchnum } +radiobutton .instChoice.bowd -text "Bowed" -bg grey66 \ + -variable patchnum -value 3 -command { patchChange $patchnum } pack .instChoice.clar -side left -padx 5 pack .instChoice.flut -side left -padx 5 pack .instChoice.bras -side left -padx 5 pack .instChoice.bowd -side left -padx 5 -pady 10 -pack .instChoice +pack .instChoice -side top +# Configure bitmap display +if {$tcl_platform(platform) == "windows"} { + set bitmappath bitmaps +} else { + set bitmappath TCLSpecs/bitmaps +} +button .pretty -bitmap @$bitmappath/prcFunny.xbm \ + -background white -foreground black +.pretty config -bitmap @$bitmappath/prc.xbm pack .pretty -padx 5 -pady 10 -pack .bPressure -padx 10 -pady 10 -pack .pitch -padx 10 -pady 10 -pack .vibrato -padx 10 -pady 10 -pack .cont1 -padx 10 -pady 10 -pack .cont2 -padx 10 -pady 10 -pack .cont3 -padx 10 -pady 10 - +# Configure "note-on" buttons frame .noteOn -bg black button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } @@ -134,3 +66,172 @@ pack .noteOn.exit -side left -padx 5 -pady 10 pack .noteOn +# Configure sliders +frame .left -bg black +frame .right -bg black + +scale .left.bPressure -from 0 -to 128 -length 200 \ +-command {changePress } -variable press \ +-orient horizontal -label "Breath Pressure" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.pitch -from 0 -to 128 -length 200 \ +-command {changePitch } -variable pitch \ +-orient horizontal -label "MIDI Note Number" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.cont1 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 2} \ +-orient horizontal -label "Reed, Emb., Lip., Bow Pres." \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont2 + +scale .right.cont2 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 4} \ +-orient horizontal -label "Noise, Slide Len.,Bow Pos." \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont4 + +scale .right.cont3 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 11} \ +-orient horizontal -label "Vibrato Rate" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont11 + +scale .right.vibrato -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 1} \ +-orient horizontal -label "Vibrato Amount" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont1 + +pack .left.bPressure -padx 10 -pady 10 +pack .left.pitch -padx 10 -pady 10 +pack .left.cont1 -padx 10 -pady 10 +pack .right.cont2 -padx 10 -pady 10 +pack .right.cont3 -padx 10 -pady 10 +pack .right.vibrato -padx 10 -pady 10 + +pack .left -side left +pack .right -side right + +proc myExit {} { + global pitch + global outID + puts $outID [format "NoteOff 0.0 1 %f 127" $pitch ] + flush $outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} + +proc noteOn {pitchVal pressVal} { + global outID + puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc noteOff {pitchVal pressVal} { + global outID + puts $outID [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc patchChange {value} { + global outID + global bitmappath + global cont1 + global cont2 + global cont4 + global cont11 + puts $outID [format "ProgramChange 0.0 1 %i" $value] + if {$value==0} { + .pretty config -bitmap @$bitmappath/Klar.xbm + } + if {$value==1} { + .pretty config -bitmap @$bitmappath/KFloot.xbm + } + if {$value==2} { + .pretty config -bitmap @$bitmappath/KHose.xbm + } + if {$value==3} { + .pretty config -bitmap @$bitmappath/KFiddl.xbm + } + flush $outID + set cont1 0.0 + set cont2 20.0 + set cont4 64.0 + set cont11 64.0 +} + +proc printWhatz {tag value1 value2 } { + global outID + puts $outID [format "%s %i %f" $tag $value1 $value2] + flush $outID +} + +proc changePress {value} { + global outID + puts $outID [format "AfterTouch 0.0 1 %f" $value] + flush $outID +} + +proc changePitch {value} { + global outID + puts $outID [format "PitchBend 0.0 1 %.3f" $value] + flush $outID +} + +# Socket connection procedure +set d .socketdialog + +proc setComm {} { + global outID + global commtype + global d + if {$commtype == "stdout"} { + if { [string compare "stdout" $outID] } { + set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] + switch $i { + 0 {set commtype "socket"} + 1 {close $outID + set outID "stdout"} + } + } + } elseif { ![string compare "stdout" $outID] } { + set sockport 2001 + toplevel $d + wm title $d "STK Client Socket Connection" + wm resizable $d 0 0 + grab $d + label $d.message -text "Specify a socket port number below (if different than the STK default of 2001) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ + -background white -font {Helvetica 10 bold} \ + -wraplength 3i -justify left + frame $d.sockport + entry $d.sockport.entry -width 6 + label $d.sockport.text -text "Socket Port Number:" \ + -font {Helvetica 10 bold} + pack $d.message -side top -padx 5 -pady 10 + pack $d.sockport.text -side left -padx 1 -pady 10 + pack $d.sockport.entry -side right -padx 5 -pady 10 + pack $d.sockport -side top -padx 5 -pady 10 + $d.sockport.entry insert 0 $sockport + frame $d.buttons + button $d.buttons.cancel -text "Cancel" -bg grey66 \ + -command { set commtype "stdout" + set outID "stdout" + destroy $d } + button $d.buttons.connect -text "Connect" -bg grey66 \ + -command { + set sockport [$d.sockport.entry get] + set err [catch {socket localhost $sockport} outID] + if {$err == 0} { + destroy $d + } else { + tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK + } } + pack $d.buttons.cancel -side left -padx 5 -pady 10 + pack $d.buttons.connect -side right -padx 5 -pady 10 + pack $d.buttons -side bottom -padx 5 -pady 10 + } +} diff --git a/TCLSpecs/TCLShakers.tcl b/TCLSpecs/TCLShakers.tcl new file mode 100644 index 0000000..6da7b68 --- /dev/null +++ b/TCLSpecs/TCLShakers.tcl @@ -0,0 +1,195 @@ +set press 64.0 +set cont1 64.0 +set cont4 64.0 +set cont11 64.0 +set outID "stdout" +set commtype "stdout" +set patchnum 19 + +# Configure main window +wm title . "STK Shakers Controller" +wm iconname . "shakers" +. config -bg black + +# Configure "communications" menu +menu .menu -tearoff 0 +menu .menu.communication -tearoff 0 +.menu add cascade -label "Communication" -menu .menu.communication \ + -underline 0 +.menu.communication add radio -label "Console" -variable commtype \ + -value "stdout" -command { setComm } +.menu.communication add radio -label "Socket" -variable commtype \ + -value "socket" -command { setComm } +. configure -menu .menu + +# Configure sliders +frame .right -bg black + +scale .right.bPressure -from 0 -to 128 -length 300 \ +-command {changePress } -variable press\ +-orient horizontal -label "Shake Energy" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .right.cont2 -from 0 -to 128 -length 300 \ +-command {printWhatz "ControlChange 0.0 1 " 4} \ +-orient horizontal -label "(<--High) System Damping (Low-->)" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont4 + +scale .right.cont3 -from 0 -to 128 -length 300 \ +-command {printWhatz "ControlChange 0.0 1 " 11} \ +-orient horizontal -label "Number of Objects" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont11 + +scale .right.vibrato -from 0 -to 128 -length 300 \ +-command {printWhatz "ControlChange 0.0 1 " 1} \ +-orient horizontal -label "Resonance Center Freq." \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont1 + +pack .right.bPressure -padx 10 -pady 10 +pack .right.vibrato -padx 10 -pady 10 +pack .right.cont2 -padx 10 -pady 10 +pack .right.cont3 -padx 10 -pady 10 + +pack .right -side right -padx 5 -pady 5 + +# Configure radio buttons +frame .left -bg black + +radiobutton .left.maraca -text Maraca -bg grey66 \ + -command { patchChange 19 } -variable patchnum -width 8 \ + -justify left -value 19 +radiobutton .left.sekere -text Sekere -bg grey66 \ + -command { patchChange 20 } -variable patchnum -width 8 \ + -justify left -value 20 +radiobutton .left.cabasa -text Cabasa -bg grey66 \ + -command { patchChange 21 } -variable patchnum -width 8 \ + -justify left -value 21 +radiobutton .left.bamboo -text Bamboo -bg grey66 \ + -command { patchChange 22 } -variable patchnum -width 8 \ + -justify left -value 22 +radiobutton .left.waterdrp -text Waterdrp -bg grey66 \ + -command { patchChange 23 } -variable patchnum -width 8 \ + -justify left -value 23 +radiobutton .left.tambourn -text Tambourn -bg grey66 \ + -command { patchChange 24 } -variable patchnum -width 8 \ + -justify left -value 24 +radiobutton .left.sleighbl -text Sleighbl -bg grey66 \ + -command { patchChange 25 } -variable patchnum -width 8 \ + -justify left -value 25 +radiobutton .left.guiro -text Guiro -bg grey66 \ + -command { patchChange 26 } -variable patchnum -width 8 \ + -justify left -value 26 + +pack .left.maraca -pady 5 +pack .left.sekere -pady 5 +pack .left.cabasa -pady 5 +pack .left.bamboo -pady 5 +pack .left.waterdrp -pady 5 +pack .left.tambourn -pady 5 +pack .left.sleighbl -pady 5 +pack .left.guiro -pady 5 + +pack .left -side left -padx 10 + +# Configure exit button +button .left.exit -text "Exit Program" -bg grey66 -command myExit +pack .left.exit -pady 10 + +proc myExit {} { + global outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} + +proc patchChange {value} { + global outID + global press + global cont1 + global cont4 + global cont11 + puts $outID [format "ProgramChange 0.0 1 %i" $value] + flush $outID + set cont1 64.0 + set cont4 64.0 + set cont11 64.0 +} + +proc printWhatz {tag value1 value2 } { + global outID + global press + puts $outID [format "%s %i %f" $tag $value1 $value2] + puts $outID [format "AfterTouch 0.0 1 %f" $press] + flush $outID +} + +proc changePress {value} { + global outID + puts $outID [format "AfterTouch 0.0 1 %f" $value] + flush $outID +} + +proc changePitch {value} { + global outID + puts $outID [format "PitchBend 0.0 1 %.3f" $value] + flush $outID +} + +# Socket connection procedure +set d .socketdialog + +proc setComm {} { + global outID + global commtype + global d + if {$commtype == "stdout"} { + if { [string compare "stdout" $outID] } { + set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] + switch $i { + 0 {set commtype "socket"} + 1 {close $outID + set outID "stdout"} + } + } + } elseif { ![string compare "stdout" $outID] } { + set sockport 2001 + toplevel $d + wm title $d "STK Client Socket Connection" + wm resizable $d 0 0 + grab $d + label $d.message -text "Specify a socket port number below (if different than the STK default of 2001) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ + -background white -font {Helvetica 10 bold} \ + -wraplength 3i -justify left + frame $d.sockport + entry $d.sockport.entry -width 6 + label $d.sockport.text -text "Socket Port Number:" \ + -font {Helvetica 10 bold} + pack $d.message -side top -padx 5 -pady 10 + pack $d.sockport.text -side left -padx 1 -pady 10 + pack $d.sockport.entry -side right -padx 5 -pady 10 + pack $d.sockport -side top -padx 5 -pady 10 + $d.sockport.entry insert 0 $sockport + frame $d.buttons + button $d.buttons.cancel -text "Cancel" -bg grey66 \ + -command { set commtype "stdout" + set outID "stdout" + destroy $d } + button $d.buttons.connect -text "Connect" -bg grey66 \ + -command { + set sockport [$d.sockport.entry get] + set err [catch {socket localhost $sockport} outID] + if {$err == 0} { + destroy $d + } else { + tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK + } } + pack $d.buttons.cancel -side left -padx 5 -pady 10 + pack $d.buttons.connect -side right -padx 5 -pady 10 + pack $d.buttons -side bottom -padx 5 -pady 10 + } +} + diff --git a/TCLSpecs/TCLStruk.tcl b/TCLSpecs/TCLStruk.tcl index be84cdd..4fbcdca 100644 --- a/TCLSpecs/TCLStruk.tcl +++ b/TCLSpecs/TCLStruk.tcl @@ -1,129 +1,54 @@ set pitch 64.0 set press 64.0 +set cont1 0.0 +set cont2 64.0 +set cont4 64.0 +set cont11 127.0 +set outID "stdout" +set commtype "stdout" +set patchnum 5 -button .pretty -bitmap @TCLSpecs/bitmaps/prcFunny.xbm \ --background white -foreground black -.pretty config -bitmap @TCLSpecs/bitmaps/prc.xbm +# Configure main window +wm title . "STK Struck-Pluck Model Controller" +wm iconname . "struck" +. config -bg black -proc myExit {} { - puts stdout [format "ExitProgram"] - flush stdout - exit -} - -proc noteOn {pitchVal pressVal} { - puts stdout [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal] - flush stdout -} - -proc noteOff {pitchVal pressVal} { - puts stdout [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal] - flush stdout -} - -proc patchChange {value} { - global .pretty - puts stdout [format "ProgramChange 0.0 1 %i" $value] - if {$value==4} { - .pretty config -bitmap @TCLSpecs/bitmaps/KPluk.xbm - } - if {$value==5} { - .pretty config -bitmap @TCLSpecs/bitmaps/KModal.xbm - } - if {$value==6} { - .pretty config -bitmap @TCLSpecs/bitmaps/KModal.xbm - } - if {$value==7} { - .pretty config -bitmap @TCLSpecs/bitmaps/KModal.xbm - } - if {$value==8} { - .pretty config -bitmap @TCLSpecs/bitmaps/KFMod.xbm - } - if {$value==9} { - .pretty config -bitmap @TCLSpecs/bitmaps/KFMod.xbm - } - if {$value==10} { - .pretty config -bitmap @TCLSpecs/bitmaps/KFMod.xbm - } - flush stdout -} - -proc printWhatz {tag value1 value2 } { - puts stdout [format "%s %i %f" $tag $value1 $value2] - flush stdout -} - -proc changePress {value} { - global press - set press $value - puts stdout [format "AfterTouch 0.0 1 %f" $press] - flush stdout -} - -proc changePitch {value} { - global pitch - set pitch $value - puts stdout [format "PitchBend 0.0 1 %f" $pitch] - flush stdout -} - -scale .bPressure -from 0 -to 128 -length 200 \ --command {changePress } \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Breath Pressure" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .pitch -from 0 -to 128 -length 200 \ --command {changePitch } \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "MIDI Note Number" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .cont1 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange 0.0 1 " 2} \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Stick/Pick Hardness" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .cont2 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange 0.0 1 " 4} \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Strike/Pick Position" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .cont3 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange 0.0 1 " 11} \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Vibrato Rate" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .vibrato -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange 0.0 1 " 1} \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Vibrato Amount" \ --tickinterval 32 -showvalue true -bg grey66 - -. config -bg grey20 +# Configure "communications" menu +menu .menu -tearoff 0 +menu .menu.communication -tearoff 0 +.menu add cascade -label "Communication" -menu .menu.communication \ + -underline 0 +.menu.communication add radio -label "Console" -variable commtype \ + -value "stdout" -command { setComm } +.menu.communication add radio -label "Socket" -variable commtype \ + -value "socket" -command { setComm } +. configure -menu .menu +# Configure patch change buttons +frame .plucked -bg black frame .modal -bg black frame .fm -bg black -radiobutton .mand -text Mandolin -bg grey66 \ --command { patchChange 4 } +radiobutton .plucked.pluk1 -text Plucked -bg grey66 \ + -command { patchChange 4 } -variable patchnum -value 4 +radiobutton .plucked.mand -text Mandolin -bg grey66 \ +-command { patchChange 5 } -variable patchnum -value 5 radiobutton .modal.mari -text Marimba -bg grey66 \ --command { patchChange 5 } +-command { patchChange 6 } -variable patchnum -value 6 radiobutton .modal.vibr -text Vibraphn -bg grey66 \ --command { patchChange 6 } +-command { patchChange 7 } -variable patchnum -value 7 radiobutton .modal.agog -text AgogoBel -bg grey66 \ --command { patchChange 7 } +-command { patchChange 8 } -variable patchnum -value 8 radiobutton .fm.rhod -text Rhodey -bg grey66 \ --command { patchChange 8 } +-command { patchChange 9 } -variable patchnum -value 9 radiobutton .fm.wurl -text Wurley -bg grey66 \ --command { patchChange 9 } +-command { patchChange 10 } -variable patchnum -value 10 radiobutton .fm.tube -text TubeBell -bg grey66 \ --command { patchChange 10 } +-command { patchChange 11 } -variable patchnum -value 11 -pack .mand -padx 5 -pady 10 +pack .plucked.pluk1 -side left -padx 5 +pack .plucked.mand -side left -padx 5 -pady 10 +pack .plucked pack .modal.mari -side left -padx 5 pack .modal.vibr -side left -padx 5 pack .modal.agog -side left -padx 5 -pady 10 @@ -133,15 +58,18 @@ pack .fm.wurl -side left -padx 5 pack .fm.tube -side left -padx 5 -pady 10 pack .fm +# Configure bitmap display +if {$tcl_platform(platform) == "windows"} { + set bitmappath bitmaps +} else { + set bitmappath TCLSpecs/bitmaps +} +button .pretty -bitmap @$bitmappath/prcFunny.xbm \ + -background white -foreground black +.pretty config -bitmap @$bitmappath/prc.xbm pack .pretty -padx 5 -pady 10 -pack .bPressure -padx 10 -pady 10 -pack .pitch -padx 10 -pady 10 -pack .vibrato -padx 10 -pady 10 -pack .cont1 -padx 10 -pady 10 -pack .cont2 -padx 10 -pady 10 -pack .cont3 -padx 10 -pady 10 - +# Configure "note-on" buttons frame .noteOn -bg black button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } @@ -151,9 +79,190 @@ pack .noteOn.on -side left -padx 5 pack .noteOn.off -side left -padx 5 -pady 10 pack .noteOn.exit -side left -padx 5 -pady 10 +pack .noteOn + +# Configure sliders +frame .left -bg black +frame .right -bg black + +scale .left.bPressure -from 0 -to 128 -length 250 \ +-command {changePress } -variable press \ +-orient horizontal -label "Breath Pressure" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.pitch -from 0 -to 128 -length 250 \ +-command {changePitch } -variable pitch \ +-orient horizontal -label "MIDI Note Number" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.cont1 -from 0 -to 128 -length 250 \ +-command {printWhatz "ControlChange 0.0 1 " 2} \ +-orient horizontal -label "Stick/Pick Hardness (Mand Body Size)" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont2 + +scale .right.cont2 -from 0 -to 128 -length 250 \ +-command {printWhatz "ControlChange 0.0 1 " 4} \ +-orient horizontal -label "Strike/Pick Position" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont4 + +scale .right.cont3 -from 0 -to 128 -length 250 \ +-command {printWhatz "ControlChange 0.0 1 " 11} \ +-orient horizontal -label "Vibrato Rate (String Sustain)" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont11 + +scale .right.vibrato -from 0 -to 128 -length 250 \ +-command {printWhatz "ControlChange 0.0 1 " 1} \ +-orient horizontal -label "Vibrato Amount (Mand Detune) " \ +-tickinterval 32 -showvalue true -bg grey66\ +-variable cont1 + +pack .left.bPressure -padx 10 -pady 10 +pack .left.pitch -padx 10 -pady 10 +pack .left.cont1 -padx 10 -pady 10 +pack .right.cont2 -padx 10 -pady 10 +pack .right.cont3 -padx 10 -pady 10 +pack .right.vibrato -padx 10 -pady 10 + +pack .left -side left +pack .right -side right + bind all { noteOn $pitch $press } -pack .noteOn +proc myExit {} { + global pitch + global outID + puts $outID [format "NoteOff 0.0 1 %f 127" $pitch ] + flush $outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} +proc noteOn {pitchVal pressVal} { + global outID + puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc noteOff {pitchVal pressVal} { + global outID + puts $outID [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc patchChange {value} { + global outID + global bitmappath + global cont1 + global cont2 + global cont4 + global cont11 + puts $outID [format "ProgramChange 0.0 1 %i" $value] + if {$value==4} { + .pretty config -bitmap @$bitmappath/KPluk.xbm + } + if {$value==5} { + .pretty config -bitmap @$bitmappath/KPluk.xbm + } + if {$value==6} { + .pretty config -bitmap @$bitmappath/KModal.xbm + } + if {$value==7} { + .pretty config -bitmap @$bitmappath/KModal.xbm + } + if {$value==8} { + .pretty config -bitmap @$bitmappath/KModal.xbm + } + if {$value==9} { + .pretty config -bitmap @$bitmappath/KFMod.xbm + } + if {$value==10} { + .pretty config -bitmap @$bitmappath/KFMod.xbm + } + if {$value==11} { + .pretty config -bitmap @$bitmappath/KFMod.xbm + } + flush $outID + set cont1 0.0 + set cont2 20.0 + set cont4 64.0 + set cont11 64.0 +} + +proc printWhatz {tag value1 value2 } { + global outID + puts $outID [format "%s %i %f" $tag $value1 $value2] + flush $outID +} + +proc changePress {value} { + global outID + puts $outID [format "AfterTouch 0.0 1 %f" $value] + flush $outID +} + +proc changePitch {value} { + global outID + puts $outID [format "PitchBend 0.0 1 %.3f" $value] + flush $outID +} + +# Socket connection procedure +set d .socketdialog + +proc setComm {} { + global outID + global commtype + global d + if {$commtype == "stdout"} { + if { [string compare "stdout" $outID] } { + set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] + switch $i { + 0 {set commtype "socket"} + 1 {close $outID + set outID "stdout"} + } + } + } elseif { ![string compare "stdout" $outID] } { + set sockport 2001 + toplevel $d + wm title $d "STK Client Socket Connection" + wm resizable $d 0 0 + grab $d + label $d.message -text "Specify a socket port number below (if different than the STK default of 2001) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ + -background white -font {Helvetica 10 bold} \ + -wraplength 3i -justify left + frame $d.sockport + entry $d.sockport.entry -width 6 + label $d.sockport.text -text "Socket Port Number:" \ + -font {Helvetica 10 bold} + pack $d.message -side top -padx 5 -pady 10 + pack $d.sockport.text -side left -padx 1 -pady 10 + pack $d.sockport.entry -side right -padx 5 -pady 10 + pack $d.sockport -side top -padx 5 -pady 10 + $d.sockport.entry insert 0 $sockport + frame $d.buttons + button $d.buttons.cancel -text "Cancel" -bg grey66 \ + -command { set commtype "stdout" + set outID "stdout" + destroy $d } + button $d.buttons.connect -text "Connect" -bg grey66 \ + -command { + set sockport [$d.sockport.entry get] + set err [catch {socket localhost $sockport} outID] + if {$err == 0} { + destroy $d + } else { + tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK + } } + pack $d.buttons.cancel -side left -padx 5 -pady 10 + pack $d.buttons.connect -side right -padx 5 -pady 10 + pack $d.buttons -side bottom -padx 5 -pady 10 + } +} diff --git a/TCLSpecs/TCLVoice.tcl b/TCLSpecs/TCLVoice.tcl index 3196efc..e20cc38 100644 --- a/TCLSpecs/TCLVoice.tcl +++ b/TCLSpecs/TCLVoice.tcl @@ -1,116 +1,54 @@ set pitch 64.0 set press 64.0 +set cont1 20.0 +set cont2 64.0 +set cont4 64.0 +set cont11 64.0 +set outID "stdout" +set commtype "stdout" +set patchnum 16 -button .pretty -bitmap @TCLSpecs/bitmaps/prcFunny.xbm \ --background white -foreground black -.pretty config -bitmap @TCLSpecs/bitmaps/prc.xbm +# Configure main window +wm title . "STK Voice Model Controller" +wm iconname . "voice" +. config -bg black -proc myExit {} { - puts stdout [format "ExitProgram"] - flush stdout - exit -} - -proc noteOn {pitchVal pressVal} { - puts stdout [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal] - flush stdout -} - -proc noteOff {pitchVal pressVal} { - puts stdout [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal] - flush stdout -} - -proc patchChange {value} { - global .pretty - puts stdout [format "ProgramChange 0.0 1 %i" $value] - if {$value==11} { - .pretty config -bitmap @TCLSpecs/bitmaps/KVoiceFM.xbm - } - if {$value==12} { - .pretty config -bitmap @TCLSpecs/bitmaps/KVoicForm.xbm - } - flush stdout -} - -proc printWhatz {tag value1 value2 } { - puts stdout [format "%s %i %f" $tag $value1 $value2] - flush stdout -} - -proc changePress {value} { - global press - set press $value - puts stdout [format "AfterTouch 0.0 1 %f" $press] - flush stdout -} - -proc changePitch {value} { - global pitch - set pitch $value - puts stdout [format "PitchBend 0.0 1 %f" $pitch] - flush stdout -} - -scale .bPressure -from 0 -to 128 -length 200 \ --command {changePress } \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Loudness (Spectral Tilt)" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .pitch -from 0 -to 128 -length 200 \ --command {changePitch } \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "MIDI Note Number" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .cont1 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange 0.0 1 " 2} \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Formant Q / Voiced/Un." \ --tickinterval 32 -showvalue true -bg grey66 - -scale .cont2 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange 0.0 1 " 4} \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Vowel (Bass, Tenor, Alto, Sop.)" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .cont3 -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange 0.0 1 " 11} \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Vibrato Rate" \ --tickinterval 32 -showvalue true -bg grey66 - -scale .vibrato -from 0 -to 128 -length 200 \ --command {printWhatz "ControlChange 0.0 1 " 1} \ --activeforeground white -sliderforeground grey80\ --orient horizontal -label "Vibrato Amount" \ --tickinterval 32 -showvalue true -bg grey66 - -. config -bg grey20 +# Configure "communications" menu +menu .menu -tearoff 0 +menu .menu.communication -tearoff 0 +.menu add cascade -label "Communication" -menu .menu.communication \ + -underline 0 +.menu.communication add radio -label "Console" -variable commtype \ + -value "stdout" -command { setComm } +.menu.communication add radio -label "Socket" -variable commtype \ + -value "socket" -command { setComm } +. configure -menu .menu +# Configure patch change buttons frame .instChoice -bg black -radiobutton .instChoice.fm -text FMVoice -bg grey66 \ --command { patchChange 11 } -radiobutton .instChoice.form -text Formant -bg grey66 \ --command { patchChange 12 } +radiobutton .instChoice.fm -text "FMVoice" -bg grey66 \ + -command { patchChange 16 } -value 16 -variable patchnum +radiobutton .instChoice.form -text "Formant" -bg grey66 \ + -command { patchChange 17 } -value 17 -variable patchnum pack .instChoice.fm -side left -padx 5 pack .instChoice.form -side left -padx 5 -pady 10 -pack .instChoice +pack .instChoice -side top +# Configure bitmap display +if {$tcl_platform(platform) == "windows"} { + set bitmappath bitmaps +} else { + set bitmappath TCLSpecs/bitmaps +} +button .pretty -bitmap @$bitmappath/prcFunny.xbm \ + -background white -foreground black +.pretty config -bitmap @$bitmappath/prc.xbm pack .pretty -padx 5 -pady 10 -pack .bPressure -padx 10 -pady 10 -pack .pitch -padx 10 -pady 10 -pack .vibrato -padx 10 -pady 10 -pack .cont1 -padx 10 -pady 10 -pack .cont2 -padx 10 -pady 10 -pack .cont3 -padx 10 -pady 10 - +# Configure "note-on" buttons frame .noteOn -bg black button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch $press } @@ -122,3 +60,166 @@ pack .noteOn.exit -side left -padx 5 -pady 10 pack .noteOn +# Configure sliders +frame .left -bg black +frame .right -bg black + +scale .left.bPressure -from 0 -to 128 -length 200 \ +-command {changePress } -variable press \ +-orient horizontal -label "Loudness (Spectral Tilt)" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.pitch -from 0 -to 128 -length 200 \ +-command {changePitch } -variable pitch \ +-orient horizontal -label "MIDI Note Number" \ +-tickinterval 32 -showvalue true -bg grey66 + +scale .left.cont1 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 2} \ +-orient horizontal -label "Formant Q / Voiced/Un." \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont2 + +scale .right.cont2 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 4} \ +-orient horizontal -label "Vowel (Bass, Tenor, Alto, Sop.)" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont4 + +scale .right.cont3 -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 11} \ +-orient horizontal -label "Vibrato Rate" \ +-tickinterval 32 -showvalue true -bg grey66 \ +-variable cont11 + +scale .right.vibrato -from 0 -to 128 -length 200 \ +-command {printWhatz "ControlChange 0.0 1 " 1} \ +-orient horizontal -label "Vibrato Amount" \ +-tickinterval 32 -showvalue true -bg grey66\ +-variable cont1 + +pack .left.bPressure -padx 10 -pady 10 +pack .left.pitch -padx 10 -pady 10 +pack .left.cont1 -padx 10 -pady 10 +pack .right.cont2 -padx 10 -pady 10 +pack .right.cont3 -padx 10 -pady 10 +pack .right.vibrato -padx 10 -pady 10 + +pack .left -side left +pack .right -side right + +proc myExit {} { + global pitch + global outID + puts $outID [format "NoteOff 0.0 1 %f 127" $pitch ] + flush $outID + puts $outID [format "ExitProgram"] + flush $outID + close $outID + exit +} + +proc noteOn {pitchVal pressVal} { + global outID + puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc noteOff {pitchVal pressVal} { + global outID + puts $outID [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal] + flush $outID +} + +proc patchChange {value} { + global outID + global bitmappath + global cont1 + global cont2 + global cont4 + global cont11 + puts $outID [format "ProgramChange 0.0 1 %i" $value] + if {$value==16} { + .pretty config -bitmap @$bitmappath/KVoiceFM.xbm + } + if {$value==17} { + .pretty config -bitmap @$bitmappath/KVoicForm.xbm + } + flush $outID + set cont1 0.0 + set cont2 20.0 + set cont4 64.0 + set cont11 64.0 +} + +proc printWhatz {tag value1 value2 } { + global outID + puts $outID [format "%s %i %f" $tag $value1 $value2] + flush $outID +} + +proc changePress {value} { + global outID + puts $outID [format "AfterTouch 0.0 1 %f" $value] + flush $outID +} + +proc changePitch {value} { + global outID + puts $outID [format "PitchBend 0.0 1 %.3f" $value] + flush $outID +} + +# Socket connection procedure +set d .socketdialog + +proc setComm {} { + global outID + global commtype + global d + if {$commtype == "stdout"} { + if { [string compare "stdout" $outID] } { + set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK] + switch $i { + 0 {set commtype "socket"} + 1 {close $outID + set outID "stdout"} + } + } + } elseif { ![string compare "stdout" $outID] } { + set sockport 2001 + toplevel $d + wm title $d "STK Client Socket Connection" + wm resizable $d 0 0 + grab $d + label $d.message -text "Specify a socket port number below (if different than the STK default of 2001) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \ + -background white -font {Helvetica 10 bold} \ + -wraplength 3i -justify left + frame $d.sockport + entry $d.sockport.entry -width 6 + label $d.sockport.text -text "Socket Port Number:" \ + -font {Helvetica 10 bold} + pack $d.message -side top -padx 5 -pady 10 + pack $d.sockport.text -side left -padx 1 -pady 10 + pack $d.sockport.entry -side right -padx 5 -pady 10 + pack $d.sockport -side top -padx 5 -pady 10 + $d.sockport.entry insert 0 $sockport + frame $d.buttons + button $d.buttons.cancel -text "Cancel" -bg grey66 \ + -command { set commtype "stdout" + set outID "stdout" + destroy $d } + button $d.buttons.connect -text "Connect" -bg grey66 \ + -command { + set sockport [$d.sockport.entry get] + set err [catch {socket localhost $sockport} outID] + if {$err == 0} { + destroy $d + } else { + tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK + } } + pack $d.buttons.cancel -side left -padx 5 -pady 10 + pack $d.buttons.connect -side right -padx 5 -pady 10 + pack $d.buttons -side bottom -padx 5 -pady 10 + } +} diff --git a/TCLSpecs/bitmaps/KASM.xbm b/TCLSpecs/bitmaps/kasm.xbm similarity index 100% rename from TCLSpecs/bitmaps/KASM.xbm rename to TCLSpecs/bitmaps/kasm.xbm diff --git a/TestAllNext b/TestAllNext deleted file mode 100755 index c20dfec..0000000 --- a/TestAllNext +++ /dev/null @@ -1,65 +0,0 @@ -testMono Plucked scores/duelingb.ski -sndplay test.snd -mv test.snd Plucked.snd - -testMono Mandolin scores/mandtune.ski -sndplay test.snd -mv test.snd MandTune.snd -testMono Mandolin scores/funicula.ski -sndplay test.snd -mv test.snd MandSolo.snd - - -testMono Clarinet scores/simplgft.ski -sndplay test.snd -mv test.snd Clarinet.snd -testMono Flute scores/simplgft.ski -sndplay test.snd -mv test.snd Flute.snd -testMono Brass scores/pictures.ski -sndplay test.snd -mv test.snd Brass.snd -testMono Bowed scores/fiddle.ski -sndplay test.snd -mv test.snd Bowed.snd - -testMono Marimba scores/spain.ski -sndplay test.snd -mv test.snd Marimba.snd -testMono Vibraphn scores/spain.ski -sndplay test.snd -mv test.snd Vibraphn.snd -testMono AgogoBel scores/morazbel.ski -sndplay test.snd -mv test.snd AgogoBel.snd - -testMono Rhodey scores/doogie.ski -sndplay test.snd -mv test.snd Rhodey.snd -testMono Wurley scores/riderson.ski -sndplay test.snd -mv test.snd Wurley.snd -testMono TubeBell scores/tubebell.ski -sndplay test.snd -mv test.snd TubeBell.snd -testMono PercFlut scores/misacrio.ski -sndplay test.snd -mv test.snd PercFlut.snd -testMono HeavyMtl scores/streetsf.ski -sndplay test.snd -mv test.snd HeavyMtl.snd -testMult 0.33 BeeThree scores/organs.ski -sndplay test.snd -mv test.snd BeeThree.snd - -testMono Moog1 scores/thecars.ski -sndplay test.snd -mv test.snd Moog1.snd - -Lacrymosa -mv test.snd Vocaliz.snd - -DrumSynt -sndplay test.snd -mv test.snd DrumSynt.snd - diff --git a/TestAllSGIRT b/TestAllSGIRT deleted file mode 100755 index 6565e4d..0000000 --- a/TestAllSGIRT +++ /dev/null @@ -1,30 +0,0 @@ -testMono Plucked scores/duelingb.ski -testMult 1.0 Mandolin scores/mandtune.ski -testMono Mandolin scores/funicula.ski - -testMono Clarinet scores/simplgft.ski -testMono Flute scores/simplgft.ski -testMono Brass scores/pictures.ski -testMono Bowed scores/fiddle.ski - -testMono Marimba scores/spain.ski -testMono Vibraphn scores/spain.ski -testMono AgogoBel scores/morazbel.ski - -testMono Rhodey scores/doogie.ski -testMono Wurley scores/riderson.ski -testMono TubeBell scores/tubebell.ski -testMono PercFlut scores/misacrio.ski -testMono HeavyMtl scores/streetsf.ski -testMono BeeThree scores/bookert.ski -testMult 0.33 BeeThree scores/organs.ski - -testMono Moog1 scores/thecars.ski - -testMono FMVoices scores/lacrymos.ski -testMono VoicForm scores/lacrymos.ski - -Vocaliz -Lacrymosa - -DrumSynt diff --git a/ToDo.txt b/ToDo.txt deleted file mode 100644 index 304926c..0000000 --- a/ToDo.txt +++ /dev/null @@ -1,116 +0,0 @@ -Need to iron out the differences between RawWvIn, NIWave1S, NIFileIn, etc. -Need to make DrumSyn1 vs. DrumSyn2 - One real-time large memory, one non real-time small memory -***************************************************** -Legend: - -x = done <1 - 9> = How Good? : = by Inheritance N = Not Applicable -Ex = Exists -Cm = Compiles -On = Note On -Of = Note Off -Pt = Pitch (5 octave range) -Vl = Velocity (0-128) -Bn = Pitch Bend -Md = Mod Wheel -C1 = Controller 1, Algorithm Specific -C2 = Controller 2, Algorithm Specific -Lg = Long/Int/Double verification -Op = Optimization pass 1 -Com. = Comments - -FILE/CLASS Ex Cm On Of Pt Vl Bn Md C1 C2 C3 Lg Op Com - -README.TXT x N N N N N N N N N N N N - -OBJECT.H x x N N N N N N N N N x N - -FILTER.H x x N N N N N N N N N x N - -ONEPOLE.H x x N N N N N N N N N x -ONEZERO.H x x N N N N N N N N N x -DCBLOCK.H x x N N N N N N N N N x -BIQUAD.H x x N N N N N N N N N x -TWOZERO.H x x N N N N N N N N N x -TWOPOLE.H x x N N N N N N N N N x -ALLPASS1.H - -FORMSWEP.H x x N N N N N N N N N x - -DLINEA.H x x N N N N N N N N N x -DLINEL.H x x N N N N N N N N N x -DLINEN.H x x N N N N N N N N N x - -RAWWAVE.H x x N N N N N N N N N x -RAWLOOP.H x x N N N N N N N N N x -NIWAVE1S.H -SINGWAVE.H x x N N N N N N N N N x -RAWWVOUT.H x x N N N N N N N N N x -RAWWVIN.H x x N N N N N N N N N x - -REEDTABL.H x x N N N N N N N N N x -JETTABL.H x x N N N N N N N N N x -LIPFILT.H x x N N N N N N N N N x Add Lip Tension Modulation? -BOWTABL.H x x N N N N N N N N N x - -ENVELOPE.H x x N N N N N N N N N x -ADSR.H x x N N N N N N N N N x -NOISE.H x x N N N N N N N N N x -SUBNOISE.H x x N N N N N N N N N x Noise each n samples - -FILE/CLASS Ex Cm On Of Pt Vl Bn Md C1 C2 C3 Lg Op Com - -PLUCKED.H x x x x 7 8 N N N N x tuning funny, allpass approx. -CLARINET.H x x x x 7 5 7 7 7 7 x -FLUTE.H x x x x 7 5 7 7 7 7 x -BRASS.H x x x x 7 5 7 7 7 7 x -BOWED.H x x x x 7 5 7 7 7 7 x Need Better Body Filter - -PLUCKED2.H x x N x N N N N N N x -MANDOLIN.H x x x : 8 8 9 9 9 9 x tuning funny, allpass approx. - -MODAL4.H x x N x N N 7 N N N x -MARIMBA.H x x x : 7 x : 7 7 7 x Check 4 Clipping Mid Range -VIBRAPHN.H x x x : x x : 7 7 7 x AMDept StickHard Pos AMFreq -AGOGOBEL.H x x x : x x : 7 7 7 x StickHard Position - -FM4OP.H x x N x N N N N N x 9 x - -FM4ALG8.H x x N : N N N 9 9 | x -BEETHREE.H x x x : x x 9 : : : x - -FM4ALG5.H x x N : N N N 9 9 : x -RHODEY.H x x x : 8 x 9 : : : x Minor Aliasing High Range -WURLEY.H x x x : 8 x 9 : : : x " " " " -TUBEBELL.H x x x : x x 9 : : : x - -FM4ALG4.H x x N : N N N 9 9 : x -PERCFLUT.H x x x : 8 x 9 : : : x Minor Aliasing High Range - -FM4ALG3.H x x N : N N N 9 9 : x -HEAVYMTL.H x x x : x x 9 : : : x Minor Aliasing High Range - -SAMPLER.H x x N x N -SAMPLFLT.H x x N : N -MOOG1.H x x x : x x - -VOICFORM.H x x ? ? ? ? ? ? ? ? ? x Need much phoneme!! - -DRUMSYNT.H x x x N x N N N N N x Need New Drum Samples - -FILE/CLASS Ex Cm On Of Pt Vl Bn Md C1 C2 C3 Lg Op Com - -Legend: -Es = Exists -Cm = Compiles -On = Note On -Of = Note Off -Pt = Pitch (5 octave range) -Vl = Velocity (0-128) -Bn = Pitch Bend -Md = Mod Wheel -C1 = Controller 1, Algorithm Specific -C2 = Controller 2, Algorithm Specific -Lg = Long/Int/Double verification -Op = Optimization pass 1 -Com. = Comments diff --git a/TubeBell.cpp b/TubeBell.cpp index aaf1cce..ca4c785 100644 --- a/TubeBell.cpp +++ b/TubeBell.cpp @@ -14,20 +14,20 @@ TubeBell :: TubeBell() : FM4Alg5() "rawwaves/sinewave.raw", "rawwaves/sinewave.raw"); - this->setRatio(0,1.0 * 0.995); - this->setRatio(1,1.414 * 0.995); - this->setRatio(2,1.0 * 1.005); - this->setRatio(3,1.414 ); + this->setRatio(0,(MY_FLOAT) (1.0 * 0.995)); + this->setRatio(1,(MY_FLOAT) (1.414 * 0.995)); + this->setRatio(2,(MY_FLOAT) (1.0 * 1.005)); + this->setRatio(3,(MY_FLOAT) (1.414 * 1.000)); gains[0] = __FM4Op_gains[94]; gains[1] = __FM4Op_gains[76]; gains[2] = __FM4Op_gains[99]; gains[3] = __FM4Op_gains[71]; - adsr[0]->setAll(0.03,0.00001,0.0,0.02); - adsr[1]->setAll(0.03,0.00001,0.0,0.02); - adsr[2]->setAll(0.07,0.00002,0.0,0.02); - adsr[3]->setAll(0.04,0.00001,0.0,0.02); - twozero->setGain(0.5); - vibWave->setFreq(2.0); + adsr[0]->setAllTimes((MY_FLOAT) 0.005,(MY_FLOAT) 4.0,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + adsr[1]->setAllTimes((MY_FLOAT) 0.005,(MY_FLOAT) 4.0,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + adsr[2]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 2.0,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + adsr[3]->setAllTimes((MY_FLOAT) 0.004,(MY_FLOAT) 4.0,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + twozero->setGain((MY_FLOAT) 0.5); + vibWave->setFreq((MY_FLOAT) 2.0); } void TubeBell :: setFreq(MY_FLOAT frequency) diff --git a/TwoPole.cpp b/TwoPole.cpp index 362fd5f..b344b48 100644 --- a/TwoPole.cpp +++ b/TwoPole.cpp @@ -11,9 +11,9 @@ TwoPole :: TwoPole() : Filter() { outputs = (MY_FLOAT *) malloc(2 * MY_FLOAT_SIZE); - poleCoeffs[0] = 0.0; - poleCoeffs[1] = 0.0; - gain = 1.0; + poleCoeffs[0] = (MY_FLOAT) 0.0; + poleCoeffs[1] = (MY_FLOAT) 0.0; + gain = (MY_FLOAT) 1.0; this->clear(); } @@ -25,9 +25,9 @@ TwoPole :: ~TwoPole() void TwoPole :: clear() { - outputs[0] = 0.0; - outputs[1] = 0.0; - lastOutput = 0.0; + outputs[0] = (MY_FLOAT) 0.0; + outputs[1] = (MY_FLOAT) 0.0; + lastOutput = (MY_FLOAT) 0.0; } void TwoPole :: setPoleCoeffs(MY_FLOAT *coeffs) @@ -39,7 +39,7 @@ void TwoPole :: setPoleCoeffs(MY_FLOAT *coeffs) void TwoPole :: setFreqAndReson(MY_FLOAT freq, MY_FLOAT reson) { poleCoeffs[1] = - (reson * reson); - poleCoeffs[0] = 2.0 * reson * cos(TWO_PI * freq / SRATE); + poleCoeffs[0] = (MY_FLOAT) 2.0 * reson * cos(TWO_PI * (double) freq / SRATE); } void TwoPole :: setGain(MY_FLOAT aValue) diff --git a/TwoZero.cpp b/TwoZero.cpp index 9c4ad5d..5b9faeb 100644 --- a/TwoZero.cpp +++ b/TwoZero.cpp @@ -11,9 +11,9 @@ TwoZero :: TwoZero() : Filter() { inputs = (MY_FLOAT *) malloc(2 * MY_FLOAT_SIZE); - zeroCoeffs[0] = 0.0; - zeroCoeffs[1] = 0.0; - gain = 1.0; + zeroCoeffs[0] = (MY_FLOAT) 0.0; + zeroCoeffs[1] = (MY_FLOAT) 0.0; + gain = (MY_FLOAT) 1.0; this->clear(); } @@ -24,9 +24,9 @@ TwoZero :: ~TwoZero() void TwoZero :: clear() { - inputs[0] = 0.0; - inputs[1] = 0.0; - lastOutput = 0.0; + inputs[0] = (MY_FLOAT) 0.0; + inputs[1] = (MY_FLOAT) 0.0; + lastOutput = (MY_FLOAT) 0.0; } void TwoZero :: setZeroCoeffs(MY_FLOAT *coeffs) diff --git a/Vibraphn.cpp b/Vibraphn.cpp index f6a922f..af57be6 100644 --- a/Vibraphn.cpp +++ b/Vibraphn.cpp @@ -9,35 +9,37 @@ /*******************************************/ #include "Vibraphn.h" +#include "SKINI11.msg" Vibraphn :: Vibraphn() : Modal4() { wave = new RawWave("rawwaves/marmstk1.raw"); wave->normalize(); - wave->setRate(13.33); - vibr->setFreq(4.0); - onepole->setPole(0.2); - this->setRatioAndReson(0, 1.0,0.99995); /* Set */ - this->setRatioAndReson(1, 2.01,0.99991); /* our */ - this->setRatioAndReson(2, 3.9,0.99992); /* resonance */ - this->setRatioAndReson(3,14.37,0.99990); /* values here */ - this->setFiltGain(0,0.025); - this->setFiltGain(1,0.015); - this->setFiltGain(2,0.015); - this->setFiltGain(3,0.015); - masterGain = 1.0; - directGain = 0.0; - vibrGain = 0.2; + wave->setRate((MY_FLOAT) 13.33); + vibr->setFreq((MY_FLOAT) 4.0); + onepole->setPole((MY_FLOAT) 0.2); + this->setRatioAndReson(0, (MY_FLOAT) 1.0,(MY_FLOAT) 0.99995); /* Set */ + this->setRatioAndReson(1, (MY_FLOAT) 2.01,(MY_FLOAT) 0.99991); /* our */ + this->setRatioAndReson(2, (MY_FLOAT) 3.9,(MY_FLOAT) 0.99992); /* resonance */ + this->setRatioAndReson(3,(MY_FLOAT) 14.37,(MY_FLOAT) 0.99990); /* values here */ + this->setFiltGain(0,(MY_FLOAT) 0.025); + this->setFiltGain(1,(MY_FLOAT) 0.015); + this->setFiltGain(2,(MY_FLOAT) 0.015); + this->setFiltGain(3,(MY_FLOAT) 0.015); + masterGain = (MY_FLOAT) 1.0; + directGain = (MY_FLOAT) 0.0; + vibrGain = (MY_FLOAT) 0.2; } Vibraphn :: ~Vibraphn() { + delete wave; } void Vibraphn :: setStickHardness(MY_FLOAT hardness) { - wave->setRate(2.0 + (22.66 * hardness)); - masterGain = 0.2 + (hardness * 1.6); + wave->setRate((MY_FLOAT) 2.0 + ((MY_FLOAT) 22.66 * hardness)); + masterGain = (MY_FLOAT) 0.2 + (hardness * (MY_FLOAT) 1.6); } void Vibraphn :: setStrikePosition(MY_FLOAT position) @@ -45,12 +47,12 @@ void Vibraphn :: setStrikePosition(MY_FLOAT position) MY_FLOAT temp,temp2; temp2 = position * PI; strikePosition = position; /* Hack only first three modes */ - temp = sin(strikePosition * PI); - this->setFiltGain(0,0.025 * temp); - temp = sin(0.1 + (2.01 * temp2)); - this->setFiltGain(1,0.015 * temp); - temp = sin(3.95 * temp2); - this->setFiltGain(2,0.015 * temp); + temp = (MY_FLOAT) sin(strikePosition * PI); + this->setFiltGain(0,(MY_FLOAT) 0.025 * temp); + temp = (MY_FLOAT) sin(0.1 + (2.01 * temp2)); + this->setFiltGain(1,(MY_FLOAT) 0.015 * temp); + temp = (MY_FLOAT) sin(3.95 * temp2); + this->setFiltGain(2,(MY_FLOAT) 0.015 * temp); } void Vibraphn :: controlChange(int number, MY_FLOAT value) @@ -58,15 +60,15 @@ void Vibraphn :: controlChange(int number, MY_FLOAT value) #if defined(_debug_) printf("Vibraphn : ControlChange: Number=%i Value=%f\n",number,value); #endif - if (number == MIDI_control1) + if (number == __SK_StickHardness_) this->setStickHardness(value * NORM_7); - else if (number == MIDI_control2) + else if (number == __SK_StrikePosition_) this->setStrikePosition(value * NORM_7); - else if (number == MIDI_control3) - vibr->setFreq((value * NORM_7 * 12.0)); - else if (number == MIDI_mod_wheel) - vibrGain = (value * NORM_7); - else if (number == MIDI_after_touch) + else if (number == __SK_ModFrequency_) + vibr->setFreq((value * NORM_7 * (MY_FLOAT) 12.0)); + else if (number == __SK_ModWheel_) + vibrGain = (value * NORM_7); + else if (number == __SK_AfterTouch_Cont_) this->strike(value * NORM_7); else { printf("Vibraphn : Undefined Control Number!!\n"); diff --git a/Vocaliz b/Vocaliz deleted file mode 100755 index 5c04c5d..0000000 --- a/Vocaliz +++ /dev/null @@ -1 +0,0 @@ -time textVoic =100.00 eee ahh .... eee + + + + ahh .... eee + + + ahh . eee - - ahh . eee - ahh . eee - - ahh . eee - - ahh ..... =150.0 ...... =200.0 ...... diff --git a/VoicForm.cpp b/VoicForm.cpp index daa7911..15d769b 100644 --- a/VoicForm.cpp +++ b/VoicForm.cpp @@ -6,14 +6,14 @@ /* random and periodic vibrato, smoothing */ /* on frequency, etc.), excitation noise, */ /* and four sweepable complex resonances. */ -/* */ +/* */ /* Measured Formant data (from me) is */ /* included, and enough data is there to */ /* support either parallel or cascade */ /* synthesis. In the floating point case */ /* cascade synthesis is the most natural */ /* so that's what you'll find here. */ -/* */ +/* */ /* For right now, there's a simple command*/ /* line score interface consisting of 3 */ /* letter symbols for the phonemes, =xx */ @@ -23,206 +23,213 @@ /*******************************************/ #include "VoicForm.h" +#include "SKINI11.msg" VoicForm :: VoicForm() : Instrmnt() { - voiced = new SingWave("rawwaves/impuls40.raw"); - voiced->normalize(); - voiced->setGainRate(0.001); - voiced->setGainTarget(0.0); + voiced = new SingWave("rawwaves/impuls40.raw"); + voiced->normalize(); + voiced->setGainRate((MY_FLOAT) 0.001); + voiced->setGainTarget((MY_FLOAT) 0.0); + + noise = new Noise; + + filters[0] = new FormSwep; + filters[1] = new FormSwep; + filters[2] = new FormSwep; + filters[3] = new FormSwep; + filters[0]->setSweepRate((MY_FLOAT) 0.001); + filters[1]->setSweepRate((MY_FLOAT) 0.001); + filters[2]->setSweepRate((MY_FLOAT) 0.001); + filters[3]->setSweepRate((MY_FLOAT) 0.001); - noise = new Noise; + onezero = new OneZero; + onezero->setCoeff((MY_FLOAT) -0.9); + onepole = new OnePole; + onepole->setPole((MY_FLOAT) 0.9); - filters[0] = new FormSwep; - filters[1] = new FormSwep; - filters[2] = new FormSwep; - filters[3] = new FormSwep; - filters[0]->setSweepRate(0.001); - filters[1]->setSweepRate(0.001); - filters[2]->setSweepRate(0.001); - filters[3]->setSweepRate(0.001); + noiseEnv = new Envelope; + noiseEnv->setRate((MY_FLOAT) 0.001); + noiseEnv->setTarget((MY_FLOAT) 0.0); - onezero = new OneZero; - onezero->setCoeff(-0.9); - onepole = new OnePole; - onepole->setPole(0.9); - - noiseEnv = new Envelope; - noiseEnv->setRate(0.001); - noiseEnv->setTarget(0.0); - - this->setPhoneme("eee"); - this->clear(); + this->setPhoneme("eee"); + this->clear(); } VoicForm :: ~VoicForm() { - delete voiced; - delete noise; - delete filters[0]; - delete filters[1]; - delete filters[2]; - delete filters[3]; - delete onezero; - delete onepole; - delete noiseEnv; + delete voiced; + delete noise; + delete filters[0]; + delete filters[1]; + delete filters[2]; + delete filters[3]; + delete onezero; + delete onepole; + delete noiseEnv; } void VoicForm :: clear() -{ - onepole->clear(); - filters[0]->clear(); - filters[1]->clear(); - filters[2]->clear(); - filters[3]->clear(); -} - -void VoicForm :: setFreq(double frequency) -{ - voiced->setFreq(frequency); -} - -void VoicForm :: setFormantAll(int whichOne, double freq,double reson,double gain) { - filters[whichOne]->setTargets(freq,reson,gain); + onezero->clear(); + onepole->clear(); + filters[0]->clear(); + filters[1]->clear(); + filters[2]->clear(); + filters[3]->clear(); } - extern double phonGains[32][2]; - extern double phonParams[32][4][3]; - extern char phonemes[32][4]; +void VoicForm :: setFreq(MY_FLOAT frequency) +{ + voiced->setFreq(frequency); +} + +void VoicForm :: setFormantAll(int whichOne, MY_FLOAT freq,MY_FLOAT reson,MY_FLOAT gain) +{ + filters[whichOne]->setTargets(freq,reson,gain); +} + +#include "phontabl.h" int VoicForm :: setPhoneme(char *phoneme) { - int i=0,found=0; - - while(i<32 && !found) { - if (!strcmp(phonemes[i],phoneme)) { - found = 1; - this->setFormantAll(0,phonParams[i][0][0],phonParams[i][0][1],pow(10.0,phonParams[i][0][2] / 20.0)); - this->setFormantAll(1,phonParams[i][1][0],phonParams[i][1][1],1.0); - this->setFormantAll(2,phonParams[i][2][0],phonParams[i][2][1],1.0); - this->setFormantAll(3,phonParams[i][3][0],phonParams[i][3][1],1.0); - this->setVoicedUnVoiced(phonGains[i][0],phonGains[i][1]); - printf("Found Formant: %s (number %i)\n",phoneme,i); - } - i++; - } - if (!found) printf("Phoneme %s not found\n",phoneme); - return found; + int i=0,found=0; + + while(i<32 && !found) { + if (!strcmp(phonemes[i],phoneme)) { + found = 1; + this->setFormantAll(0,(MY_FLOAT) phonParams[i][0][0],(MY_FLOAT) phonParams[i][0][1],(MY_FLOAT) pow(10.0,phonParams[i][0][2] / 20.0)); + this->setFormantAll(1,(MY_FLOAT) phonParams[i][1][0],(MY_FLOAT) phonParams[i][1][1],(MY_FLOAT) 1.0); + this->setFormantAll(2,(MY_FLOAT) phonParams[i][2][0],(MY_FLOAT) phonParams[i][2][1],(MY_FLOAT) 1.0); + this->setFormantAll(3,(MY_FLOAT) phonParams[i][3][0],(MY_FLOAT) phonParams[i][3][1],(MY_FLOAT) 1.0); + this->setVoicedUnVoiced((MY_FLOAT) phonGains[i][0],(MY_FLOAT) phonGains[i][1]); + printf("Found Formant: %s (number %i)\n",phoneme,i); + } + i++; + } + if (!found) printf("Phoneme %s not found\n",phoneme); + return found; } -void VoicForm :: setVoiced(double vGain) +void VoicForm :: setVoiced(MY_FLOAT vGain) { - voiced->setGainTarget(vGain); + voiced->setGainTarget(vGain); + //voiced->setGainTarget(vGain*0.5); } -void VoicForm :: setUnVoiced(double nGain) +void VoicForm :: setUnVoiced(MY_FLOAT nGain) { - noiseEnv->setTarget(nGain); + noiseEnv->setTarget(nGain); + //noiseEnv->setTarget(nGain*0.5); } -void VoicForm :: setVoicedUnVoiced(double vGain, double nGain) +void VoicForm :: setVoicedUnVoiced(MY_FLOAT vGain, MY_FLOAT nGain) { - this->setVoiced(vGain); - this->setUnVoiced(nGain); + this->setVoiced(vGain); + //this->setVoiced(vGain*0.5); + this->setUnVoiced(nGain); + //this->setUnVoiced(nGain*0.5); } -void VoicForm :: setFiltSweepRate(int whichOne,double rate) +void VoicForm :: setFiltSweepRate(int whichOne,MY_FLOAT rate) { - filters[whichOne]->setSweepRate(rate); + filters[whichOne]->setSweepRate(rate); } -void VoicForm :: setPitchSweepRate(double rate) +void VoicForm :: setPitchSweepRate(MY_FLOAT rate) { - voiced->setSweepRate(rate); + voiced->setSweepRate(rate); } void VoicForm :: speak() { - voiced->noteOn(); + voiced->noteOn(); } void VoicForm :: quiet() { - voiced->noteOff(); - noiseEnv->setTarget(0.0); + voiced->noteOff(); + noiseEnv->setTarget((MY_FLOAT) 0.0); } void VoicForm :: noteOn(MY_FLOAT freq, MY_FLOAT amp) { - voiced->setGainTarget(amp); - onepole->setPole(0.95 - (amp * NORM_7 * 0.2)); - voiced->setFreq(freq); + voiced->setGainTarget(amp); + //voiced->setGainTarget(amp*0.5); + onepole->setPole((MY_FLOAT) 0.95 - (amp * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2)); + //onepole->setPole((MY_FLOAT) 0.9 - (amp * (MY_FLOAT) 0.2)); + voiced->setFreq(freq); } void VoicForm :: noteOff(MY_FLOAT amp) { - voiced->noteOff(); + voiced->noteOff(); } MY_FLOAT VoicForm :: tick() { - MY_FLOAT temp; - temp = onepole->tick(onezero->tick(voiced->tick())); - temp += noiseEnv->tick() * noise->tick(); - lastOutput = filters[0]->tick(temp); - lastOutput = filters[1]->tick(lastOutput); - lastOutput = filters[2]->tick(lastOutput); - lastOutput = filters[3]->tick(lastOutput); - lastOutput *= 0.02; - return lastOutput; + MY_FLOAT temp; + temp = onepole->tick(onezero->tick(voiced->tick())); + temp += noiseEnv->tick() * noise->tick(); + lastOutput = filters[0]->tick(temp); + lastOutput = filters[1]->tick(lastOutput); + lastOutput = filters[2]->tick(lastOutput); + lastOutput = filters[3]->tick(lastOutput); + //lastOutput *= (MY_FLOAT) 0.02; + lastOutput *= (MY_FLOAT) 0.005; + return lastOutput; } void VoicForm :: controlChange(int number, MY_FLOAT value) { - MY_FLOAT temp; - int tempi; + MY_FLOAT temp; + int tempi; #if defined(_debug_) - printf("VoicForm : ControlChange: Number=%i Value=%f\n",number,value); -#endif - if (number == MIDI_control1) { - this->setVoiced(1.0 - (value*NORM_7)); - this->setUnVoiced(0.01 * value * NORM_7); - } - else if (number == MIDI_control2) { - tempi = (int) (value / 2); - if (tempi < 16) { - tempi = tempi; - temp = 0.9; - } - else if (tempi < 32) { - tempi = tempi - 16; - temp = 1.0; - } - else if (tempi < 48) { - tempi = tempi - 32; - temp = 1.1; - } - else if (tempi < 64) { - tempi = tempi - 48; - temp = 1.2; - } - this->setFormantAll(0,temp*phonParams[tempi][0][0], - phonParams[tempi][0][1], - pow(10.0,phonParams[tempi][0][2] / 20.0)); - this->setFormantAll(1,temp*phonParams[tempi][1][0], - phonParams[tempi][1][1],1.0); - this->setFormantAll(2,temp*phonParams[tempi][2][0], - phonParams[tempi][2][1],1.0); - this->setFormantAll(3,temp*phonParams[tempi][3][0], - phonParams[tempi][3][1],1.0); - } - else if (number == MIDI_control3) - voiced->setVibFreq(value * NORM_7 * 12.0); /* 0 to 12 Hz */ - else if (number == MIDI_mod_wheel) - voiced->setVibAmt(value * NORM_7 * 0.2); - else if (number == MIDI_after_touch) { - this->setVoiced(value*NORM_7); - onepole->setPole(0.99 - (value*NORM_7 * 0.2)); - } - else { - printf("VoicForm : Undefined Control Number!!\n"); - } + printf("VoicForm : ControlChange: Number=%i Value=%f\n",number,value); +#endif + if (number == __SK_Breath_) { + this->setVoiced((MY_FLOAT) 1.0 - (value *(MY_FLOAT) NORM_7)); + this->setUnVoiced((MY_FLOAT) 0.01 * value * (MY_FLOAT) NORM_7); + } + else if (number == __SK_FootControl_) { + tempi = (int) (value / 2); + if (tempi < 16) { + tempi = tempi; + temp = (MY_FLOAT) 0.9; + } + else if (tempi < 32) { + tempi = tempi - 16; + temp = (MY_FLOAT) 1.0; + } + else if (tempi < 48) { + tempi = tempi - 32; + temp = (MY_FLOAT) 1.1; + } + else if (tempi <= 64) { + tempi = tempi - 48; + temp = (MY_FLOAT) 1.2; + } + this->setFormantAll(0,temp*(MY_FLOAT) phonParams[tempi][0][0], + (MY_FLOAT) phonParams[tempi][0][1], + (MY_FLOAT) pow(10.0,phonParams[tempi][0][2] / 20.0)); + this->setFormantAll(1,temp*(MY_FLOAT) phonParams[tempi][1][0], + (MY_FLOAT) phonParams[tempi][1][1],(MY_FLOAT) 1.0); + this->setFormantAll(2,temp*(MY_FLOAT) phonParams[tempi][2][0], + (MY_FLOAT) phonParams[tempi][2][1],(MY_FLOAT) 1.0); + this->setFormantAll(3,temp*(MY_FLOAT) phonParams[tempi][3][0], + (MY_FLOAT) phonParams[tempi][3][1],(MY_FLOAT) 1.0); + } + else if (number == __SK_ModFrequency_) + voiced->setVibFreq(value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 12.0); /* 0 to 12 Hz */ + else if (number == __SK_ModWheel_) + voiced->setVibAmt(value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2); + else if (number == __SK_AfterTouch_Cont_) { + this->setVoiced(value*NORM_7); + onepole->setPole((MY_FLOAT) 0.99 - (value *(MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2)); + //onepole->setPole((MY_FLOAT) 0.5 - (value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2)); + } + else { + printf("VoicForm : Undefined Control Number!!\n"); + } } - diff --git a/VoicForm.h b/VoicForm.h index bba660c..43b3961 100644 --- a/VoicForm.h +++ b/VoicForm.h @@ -46,14 +46,14 @@ class VoicForm : public Instrmnt VoicForm(); ~VoicForm(); void clear(); - void setFreq(double frequency); - void setFormantAll(int whichOne, double freq, double reson, double gain); + void setFreq(MY_FLOAT frequency); + void setFormantAll(int whichOne, MY_FLOAT freq, MY_FLOAT reson, MY_FLOAT gain); int setPhoneme(char* phoneme); - void setVoiced(double vGain); - void setUnVoiced(double nGain); - void setVoicedUnVoiced(double vGain, double nGain); - void setFiltSweepRate(int whichOne,double rate); - void setPitchSweepRate(double rate); + void setVoiced(MY_FLOAT vGain); + void setUnVoiced(MY_FLOAT nGain); + void setVoicedUnVoiced(MY_FLOAT vGain, MY_FLOAT nGain); + void setFiltSweepRate(int whichOne,MY_FLOAT rate); + void setPitchSweepRate(MY_FLOAT rate); void speak(); void quiet(); virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp); diff --git a/VoicMang.cpp b/VoicMang.cpp index 83b095e..3dddba9 100644 --- a/VoicMang.cpp +++ b/VoicMang.cpp @@ -6,7 +6,7 @@ /* Make one of these by telling it the */ /* maximum number of voices you'll want, */ /* and also what flavor instrument */ -/* group it will be mangling. Pipe TSIDI*/ +/* group it will be mangling. Pipe SKINI*/ /* messages into it and it will return */ /* the mixed channel signal each tick. */ /* For multi-channel (multi-timbral), */ @@ -19,21 +19,22 @@ /* unique instances of instruments */ /* within an ensemble. */ /* */ -/* TSIDI (ToolKit Synthesis Instrument */ -/* Digital Interfaceis like MIDI, but */ +/* SKINI (Synthesis toolKit Instrument */ +/* Network Interface) is like MIDI, but */ /* allows for floating point control */ /* changes, note numbers, etc. Example: */ -/* noteOn(1,60.01,111.132) plays a sharp */ +/* noteOn 60.01 111.132 plays a sharp */ /* middle C with a velocity of 111.132 */ +/* See SKINI09.txt for more information */ /* */ /******************************************/ #include "VoicMang.h" +#include "Mandolin.h" #include "Marimba.h" #include "Vibraphn.h" #include "AgogoBel.h" #include "Plucked.h" -#include "Mandolin.h" #include "Clarinet.h" #include "Flute.h" #include "Brass.h" @@ -54,7 +55,12 @@ VoicMang :: VoicMang(int maxVoices, char *instrType) printf("You ask for too many voices, setting to %i\n",__VMang_MAX_); max_voices = __VMang_MAX_; } - if (!strcmp(instrType,"Marimba")) { + if (!strcmp(instrType,"Mandolin")) { + for (i=0;inoteOn(temp,amp); } #define ONE_OVER_12 0.083333 -long VoicMang :: noteOn(MY_FLOAT note_num, MY_FLOAT amp) +long VoicMang :: noteOnN(MY_FLOAT note_num, MY_FLOAT amp) { - int i,gotOne; - int temp1; - long temp2; - MY_FLOAT temp3,temp4; + int i,gotOne; MY_FLOAT freq; - freq = 220.0*pow(2.0,(note_num-57.0) * ONE_OVER_12); + freq = (MY_FLOAT) 220.0 * pow(2.0,(note_num - 57.0) * ONE_OVER_12); gotOne = 0; for (i=0;inoteOn(freq,amp*NORM_7); + notesOn[i] = (int) (note_num + (MY_FLOAT) 0.5); /* Nearest Neighbor MIDI Note# */ + instrument[i]->noteOn(freq,amp*(MY_FLOAT) NORM_7); frequencies[i] = freq; gotOne = 1; i = max_voices; @@ -191,41 +190,39 @@ long VoicMang :: noteOn(MY_FLOAT note_num, MY_FLOAT amp) long VoicMang :: oldestVoice() { int i; - long temp,temp2,gotOne; - temp = newTag; + long temp2,gotOne; + temp2 = newTag; gotOne = -1; for (i=0;i 0 && temp2 < newTag) { - temp = temp2; gotOne = temp2; } } return gotOne; } -int VoicMang :: noteOffN(int note_num, MY_FLOAT amp) +long VoicMang :: noteOffN(int note_num, MY_FLOAT amp) { int i,gotOne; - MY_FLOAT temp; gotOne = -1; for (i=0;inoteOff(amp*NORM_7); - voicesOn[i] = -mute_time; - gotOne = 1; - } + if (notesOn[i]==note_num) { + instrument[i]->noteOff(amp * (MY_FLOAT) NORM_7); + gotOne = voicesOn[i]; + voicesOn[i] = -mute_time - 2; + } } return gotOne; } -void VoicMang :: noteOff(long tag, MY_FLOAT amp) +void VoicMang :: noteOffT(long tag, MY_FLOAT amp) { int i; for (i=0;inoteOff(amp*NORM_7); - voicesOn[i] = -mute_time; + instrument[i]->noteOff(amp * (MY_FLOAT) NORM_7); + voicesOn[i] = -mute_time - 2; } } } @@ -235,7 +232,7 @@ void VoicMang :: kill(long tag) int i; for (i=0;inoteOff(1.0); + instrument[i]->noteOff((MY_FLOAT) 1.0); voicesOn[i] = 0; notesOn[i] = -1; } @@ -252,7 +249,7 @@ void VoicMang :: pitchBend(MY_FLOAT value) } } -void VoicMang :: pitchBend(long tag, MY_FLOAT value) +void VoicMang :: pitchBendT(long tag, MY_FLOAT value) { int i; for (i=0;itick(); } if (voicesOn[i] < 0) { voicesOn[i] += 1; if (voicesOn[i] == 0) { notesOn[i] = -1; - frequencies[i] = 0.0; - freqBases[i] = 1.0; + frequencies[i] = (MY_FLOAT) 0.0; + freqBases[i] = (MY_FLOAT) 1.0; } } } @@ -293,7 +290,7 @@ void VoicMang :: controlChange(int number, MY_FLOAT value) } } -void VoicMang :: controlChange(long tag, int number, MY_FLOAT value) +void VoicMang :: controlChangeT(long tag, int number, MY_FLOAT value) { int i; for (i=0;i 1.0) { + pan = 1.0; + printf("Pan > 1.0, correcting to 1.0\n"); + } +} diff --git a/WavWvOut.h b/WavWvOut.h new file mode 100644 index 0000000..9b68619 --- /dev/null +++ b/WavWvOut.h @@ -0,0 +1,38 @@ +/*******************************************/ +/* Wave file Output Class, */ +/* by Perry R. Cook, 1995-96 */ +/* This Object opens a DOS/Windows .wav */ +/* 16bit data (signed integers) file, and */ +/* poke buffers of samples into it. */ +/*******************************************/ + + +#include "Object.h" +#include "WvOut.h" + +#if !defined(__WavWvOut_h) +#define __WavWvOut_h + +#define WAV_BUFFER_SIZE 1024 + +class WavWvOut : public WvOut +{ + protected: + FILE *fd; + short data[WAV_BUFFER_SIZE]; + long counter; + long totalCount; + int chans; + MY_FLOAT pan; + public: + WavWvOut(char *fileName); + WavWvOut(int channels, char *fileName); + ~WavWvOut(); + long getCounter(); + MY_FLOAT getTime(); + void setMonoPan(MY_FLOAT aPan); + void tick(MY_FLOAT sample); + void tick(MY_FLOAT lsamp, MY_FLOAT rsamp); +}; + +#endif diff --git a/Wurley.cpp b/Wurley.cpp index 5685437..5783acb 100644 --- a/Wurley.cpp +++ b/Wurley.cpp @@ -14,20 +14,20 @@ Wurley :: Wurley() : FM4Alg5() "rawwaves/sinewave.raw", "rawwaves/fwavblnk.raw"); - this->setRatio(0,1.0); - this->setRatio(1,4.0); - this->setRatio(2,-510.0); - this->setRatio(3,-510.0); + this->setRatio(0,(MY_FLOAT) 1.0); + this->setRatio(1,(MY_FLOAT) 4.0); + this->setRatio(2,(MY_FLOAT) -510.0); + this->setRatio(3,(MY_FLOAT) -510.0); gains[0] = __FM4Op_gains[99]; gains[1] = __FM4Op_gains[82]; gains[2] = __FM4Op_gains[92]; gains[3] = __FM4Op_gains[68]; /* Originally 78, but sounded stinky */ - twozero->setGain(2.0); - adsr[0]->setAll(0.05,0.00003,0.0,0.02); - adsr[1]->setAll(0.05,0.00003,0.0,0.02); - adsr[2]->setAll(0.05,0.0002,0.0,0.02); - adsr[3]->setAll(0.05,0.0003,0.0,0.02); - vibWave->setFreq(8.0); + twozero->setGain((MY_FLOAT) 2.0); + adsr[0]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.50,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + adsr[1]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 1.50,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + adsr[2]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 0.25,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + adsr[3]->setAllTimes((MY_FLOAT) 0.001,(MY_FLOAT) 0.15,(MY_FLOAT) 0.0,(MY_FLOAT) 0.04); + vibWave->setFreq((MY_FLOAT) 8.0); } void Wurley :: setFreq(MY_FLOAT frequency) diff --git a/WvOut.cpp b/WvOut.cpp new file mode 100644 index 0000000..996cdac --- /dev/null +++ b/WvOut.cpp @@ -0,0 +1,21 @@ +/*******************************************/ +/* Output Abstract Class, */ +/* by Tim Stilson, 1996 */ +/* based on code by Perry R. Cook, 1995-96*/ +/*******************************************/ + +#include "WvOut.h" +#include + +WvOut :: WvOut() +{ +} + +WvOut :: ~WvOut() +{ +} + +void WvOut :: tick(MY_FLOAT sample) +{ +} + diff --git a/WvOut.h b/WvOut.h new file mode 100644 index 0000000..7b402e6 --- /dev/null +++ b/WvOut.h @@ -0,0 +1,23 @@ +/********************************************/ +/* Output Abstract Class, */ +/* by Tim Stilson, 1996 */ +/* based on code by Perry R. Cook, 1995-96 */ +/********************************************/ + +#include "Object.h" + +#if !defined(__WvOut_h) +#define __WvOut_h + + + +class WvOut : public Object +{ + public: + WvOut(); + virtual ~WvOut(); + virtual void tick(MY_FLOAT sample); +}; + + +#endif // defined(__WvOut_h) diff --git a/hierarch.txt b/hierarch.txt new file mode 100644 index 0000000..9490643 --- /dev/null +++ b/hierarch.txt @@ -0,0 +1,133 @@ +Brief Descriptions of Classes in STK98, ver. 2.01 +A ToolKit of Sound Synthesis Classes + and Instruments in C++ +Perry Cook, 1995-96, free distribution for +academic, instructional, tutorial, etc. purposes. +Please read README.txt for more information. + +<--------Building Blocks---------->|<----------------Instruments------------------> + +SourcSink Filters Reverb Non-Lin ModalSyn FM Physical Sampling PhISM + & Formant + +Object-----------------------------------Instrmnt----------. + | | | | | | | +Envelope| Filter Reverb BowTabl | .------------------|---------------------. + | | | | JetTabl | | | | | | | | | +ADSR | OneZero PRCRev ReedTabl| Modal4 | FM4Op---.| | | | Shakers + | OnePole JCRev | | | | || | | | | + ._____| TwoZero NRev .____| Marimba | FM4Alg3 || Plucked Sampler | Maraca + | | TwoPole | Vibraphn| | || Clarinet | | Sekere +Noise | DCBlock LipFilt AgogoBel| HeavyMtl|| Brass SamplFlt| Cabasa + | | BiQuad | || Flute | | Bamboo +SubNoise| DlineL .____| .____|| Bowed Moog1 | Water Drops + | DLineA | | || | Tambourine + ._____| DLineN VoicForm FM4Alg4 ||____. | SleighBells + | | FormSwep | | | | Guiro +RawWave | PercFlut| Plucked2 | + | | | | + ._____| .____| Mandolin .____| + | | | | | +RawLoop | FM4Alg5 | DrumSynt + | | | + ._____| Rhodey | + | | Wurley | +Modulatr| TubeBell | + | .____| + ._____| | | + | | FM4Alg6 | +SingWave| | | + | FMVoices| + ._____|_____. | + | | | .____| +VoicMang| WvOut | + | | FM4Alg8 + ._____| WavWvOut | + | | SndWvOut BeeThree +RawWvIn | RTWvOut + | MatWvOut + ._____| + | +MIDIInpt + + +********** Instruments and Algorithms ************** +Each Class will be listed either with all UGs it uses, +or the <> of which it is a flavor. +All inherit from Instrmnt, which inherits from Object. + +Plucked.cpp Basic Plucked String DLineA,OneZero,OnePole,Noise +Plucked2.cpp Not so Basic Pluck DLineL,DlineA,OneZero +Mandolin.cpp My Own Mandolin <> +Bowed.cpp Not Hideous Bowed String DlineL,BowTabl,OnePole,BiQuad,RawWave,ADSR +Brass.cpp Not So Bad Brass Inst. DLineA,LipFilt,DCBlock,ADSR,RawLoop +Clarinet.cpp Pretty Good Clarinet DLineL,ReedTabl,OneZero,Envelope,Noise,RawLoop +Flute.cpp Pretty Good Flute JetTabl,DLineL,OnePole,DCBlock,Noise,ADSR,RawLoop +Modal4.cpp 4 Resonances Envelope,RawWave,RawLoop,BiQuad,OnePole +Marimba.cpp <> +Vibraphn.cpp <> +Agogobel.cpp <> +FM4Op.cpp 4 Operator FM Master ADSR,RawLoop,TwoZero +FM4Alg3.cpp 3 Cascade w/ FB Mod. <> +FM4Alg4.cpp Like Alg3 but diff. <> +FM4Alg5.cpp 2 Parallel Simple FMs <> +FM4Alg6.cpp 3 Carr. with 1 Mod. <> +FM4Alg8.cpp 4 Osc. Additive <> +HeavyMtl.cpp Distorted Synth <> +PercFlut.cpp Perc. Flute <> +Rhodey.cpp Rhodes-Like Elec. Piano <> +Wurley.cpp Wurlitz. Elec. Piano <> +TubeBell.cpp Classic FM Bell <> +FMVoices.cpp 3-Formant Voice Synth. <> +BeeThree.cpp Cheezy Organ for Paul <> +Sampler.cpp Sampling Synth. 4 each ADSR, RawWave (att), RawLoop (loop), OnePole +SamplFlt.cpp Sampler with Swept Filter <> +Moog1.cpp Swept filter flavor of <> +VoicForm.cpp Source/Filter Voice Envelope,Noise,SingWave,FormSwep,OnePole,OneZero +DrumSynt.cpp Drum Synthesizer bunch of RawWvIn, and OnePole +Shakers.cpp Stochastic Event Models + +*********** Basic Unit Generators ************** + +Master Object: Object.cpp For compatibility with Objective C + +Source&Sink: RawWave.cpp Lin-Interp Wavetable, Looped or 1 Shot + RawLoop.cpp Lin-Interp Wavetable, Looping + RawWvIn.cpp Lin-Interp Wave In streaming 'device' + Envelope.cpp Linearly Goes to Target by Rate, + noteOn/Off + ADSR.cpp ADSR Flavor of Envelope + Noise.cpp Random Number Generator + SubNoise.cpp Random Numbers each N samples + +Outputs: WvOut.cpp Output Master Class + SndWvOut.cpp .snd Output Class + WavWvOut.cpp .wav Output Class + RTWvOut.cpp Realtime Output Class + MatWvOut.cpp Matlab Matfile Output Class + +Inputs: MIDIInpt.cpp MIDI Stream Parser Class + +Filters: Filter.cpp Filter Master Class + OneZero.cpp One Zero Filter + OnePole.cpp One Pole Filter + DCBlock.cpp DC Blocking 1Pole/1Zero Filter + TwoZero.cpp Two Zero Filter + TwoPole.cpp Two Pole Filter + BiQuad.cpp 2Pole/2Zero Filter + FormSwep.cpp Sweepable 2Pole filter, go to target by rate + DLineL.cpp Linearly Interpolating Delay Line + DLineA.cpp AllPass Interpolating Delay Line + DLineN.cpp Non Interpolating Delay Line + +Reverb: Reverb.cpp Reverb Master Class + PRCRev.cpp 2 series allpass units, 2 parallel comb filters + JCRev.cpp 3 series allpass units, 4 parallel comb filters + NReb.cpp 6 parallel comb filters, 3 series allpass units, ... + +NonLin&Lookup: JetTabl.cpp Cubic Jet NonLinearity + BowTabl.cpp 1/x^3-like Bow NonLinearity + ReedTabl.cpp 1 break point Reed NonLinearity + LipFilt.cpp Pressure Controlled BiQuad with NonLin + +Derived: Modulatr.cpp Per. and Rnd. Vibrato: RawWave,SubNoise,OnePole + SingWave.cpp Looping Wavetable with: Modulatr,Envelope diff --git a/include/dsound.h b/include/dsound.h new file mode 100644 index 0000000..80729b0 --- /dev/null +++ b/include/dsound.h @@ -0,0 +1,863 @@ +/*==========================================================================; + * + * Copyright (C) 1995,1996 Microsoft Corporation. All Rights Reserved. + * + * File: dsound.h + * Content: DirectSound include file + * + **************************************************************************/ + +#ifndef __DSOUND_INCLUDED__ +#define __DSOUND_INCLUDED__ + +#include + +#define COM_NO_WINDOWS_H +#include + +#define _FACDS 0x878 +#define MAKE_DSHRESULT(code) MAKE_HRESULT(1, _FACDS, code) + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// DirectSound Component GUID {47D4D946-62E8-11cf-93BC-444553540000} +DEFINE_GUID(CLSID_DirectSound, 0x47d4d946, 0x62e8, 0x11cf, 0x93, 0xbc, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0); + +// DirectSound Capture Component GUID {B0210780-89CD-11d0-AF08-00A0C925CD16} +DEFINE_GUID(CLSID_DirectSoundCapture, 0xb0210780, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); + +// +// Structures +// + +#ifdef __cplusplus +// 'struct' not 'class' per the way DECLARE_INTERFACE_ is defined +struct IDirectSound; +struct IDirectSoundBuffer; +struct IDirectSound3DListener; +struct IDirectSound3DBuffer; +struct IDirectSoundCapture; +struct IDirectSoundCaptureBuffer; +struct IDirectSoundNotify; +#endif // __cplusplus + +typedef struct IDirectSound *LPDIRECTSOUND; +typedef struct IDirectSoundBuffer *LPDIRECTSOUNDBUFFER; +typedef struct IDirectSound3DListener *LPDIRECTSOUND3DLISTENER; +typedef struct IDirectSound3DBuffer *LPDIRECTSOUND3DBUFFER; +typedef struct IDirectSoundCapture *LPDIRECTSOUNDCAPTURE; +typedef struct IDirectSoundCaptureBuffer *LPDIRECTSOUNDCAPTUREBUFFER; +typedef struct IDirectSoundNotify *LPDIRECTSOUNDNOTIFY; + +typedef struct _DSCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwMinSecondarySampleRate; + DWORD dwMaxSecondarySampleRate; + DWORD dwPrimaryBuffers; + DWORD dwMaxHwMixingAllBuffers; + DWORD dwMaxHwMixingStaticBuffers; + DWORD dwMaxHwMixingStreamingBuffers; + DWORD dwFreeHwMixingAllBuffers; + DWORD dwFreeHwMixingStaticBuffers; + DWORD dwFreeHwMixingStreamingBuffers; + DWORD dwMaxHw3DAllBuffers; + DWORD dwMaxHw3DStaticBuffers; + DWORD dwMaxHw3DStreamingBuffers; + DWORD dwFreeHw3DAllBuffers; + DWORD dwFreeHw3DStaticBuffers; + DWORD dwFreeHw3DStreamingBuffers; + DWORD dwTotalHwMemBytes; + DWORD dwFreeHwMemBytes; + DWORD dwMaxContigFreeHwMemBytes; + DWORD dwUnlockTransferRateHwBuffers; + DWORD dwPlayCpuOverheadSwBuffers; + DWORD dwReserved1; + DWORD dwReserved2; +} DSCAPS, *LPDSCAPS; + +typedef const DSCAPS *LPCDSCAPS; + +typedef struct _DSBCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwUnlockTransferRate; + DWORD dwPlayCpuOverhead; +} DSBCAPS, *LPDSBCAPS; + +typedef const DSBCAPS *LPCDSBCAPS; + +typedef struct _DSBUFFERDESC +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; +} DSBUFFERDESC, *LPDSBUFFERDESC; + +typedef const DSBUFFERDESC *LPCDSBUFFERDESC; + +typedef struct _DS3DBUFFER +{ + DWORD dwSize; + D3DVECTOR vPosition; + D3DVECTOR vVelocity; + DWORD dwInsideConeAngle; + DWORD dwOutsideConeAngle; + D3DVECTOR vConeOrientation; + LONG lConeOutsideVolume; + D3DVALUE flMinDistance; + D3DVALUE flMaxDistance; + DWORD dwMode; +} DS3DBUFFER, *LPDS3DBUFFER; + +typedef const DS3DBUFFER *LPCDS3DBUFFER; + +typedef struct _DS3DLISTENER +{ + DWORD dwSize; + D3DVECTOR vPosition; + D3DVECTOR vVelocity; + D3DVECTOR vOrientFront; + D3DVECTOR vOrientTop; + D3DVALUE flDistanceFactor; + D3DVALUE flRolloffFactor; + D3DVALUE flDopplerFactor; +} DS3DLISTENER, *LPDS3DLISTENER; + +typedef const DS3DLISTENER *LPCDS3DLISTENER; + +typedef struct _DSCCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwFormats; + DWORD dwChannels; +} DSCCAPS, *LPDSCCAPS; + +typedef const DSCCAPS *LPCDSCCAPS; + +typedef struct _DSCBUFFERDESC +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; +} DSCBUFFERDESC, *LPDSCBUFFERDESC; + +typedef const DSCBUFFERDESC *LPCDSCBUFFERDESC; + +typedef struct _DSCBCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; +} DSCBCAPS, *LPDSCBCAPS; + +typedef const DSCBCAPS *LPCDSCBCAPS; + +typedef struct _DSBPOSITIONNOTIFY +{ + DWORD dwOffset; + HANDLE hEventNotify; +} DSBPOSITIONNOTIFY, *LPDSBPOSITIONNOTIFY; + +typedef const DSBPOSITIONNOTIFY *LPCDSBPOSITIONNOTIFY; + +// +// Compatibility typedefs +// + +typedef LPDIRECTSOUND *LPLPDIRECTSOUND; +typedef LPDIRECTSOUNDBUFFER *LPLPDIRECTSOUNDBUFFER; +typedef LPDIRECTSOUND3DLISTENER *LPLPDIRECTSOUND3DLISTENER; +typedef LPDIRECTSOUND3DBUFFER *LPLPDIRECTSOUND3DBUFFER; +typedef LPDIRECTSOUNDCAPTURE *LPLPDIRECTSOUNDCAPTURE; +typedef LPDIRECTSOUNDCAPTUREBUFFER *LPLPDIRECTSOUNDCAPTUREBUFFER; +typedef LPDIRECTSOUNDNOTIFY *LPLPDIRECTSOUNDNOTIFY; +typedef LPVOID *LPLPVOID; +typedef const WAVEFORMATEX *LPCWAVEFORMATEX; + +// +// DirectSound API +// + +typedef BOOL (CALLBACK *LPDSENUMCALLBACKW)(LPGUID, LPCWSTR, LPCWSTR, LPVOID); +typedef BOOL (CALLBACK *LPDSENUMCALLBACKA)(LPGUID, LPCSTR, LPCSTR, LPVOID); + +extern HRESULT WINAPI DirectSoundCreate(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); +extern HRESULT WINAPI DirectSoundEnumerateW(LPDSENUMCALLBACKW, LPVOID); +extern HRESULT WINAPI DirectSoundEnumerateA(LPDSENUMCALLBACKA, LPVOID); + +extern HRESULT WINAPI DirectSoundCaptureCreate(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN); +extern HRESULT WINAPI DirectSoundCaptureEnumerateW(LPDSENUMCALLBACKW, LPVOID); +extern HRESULT WINAPI DirectSoundCaptureEnumerateA(LPDSENUMCALLBACKA, LPVOID); + +#ifdef UNICODE +#define LPDSENUMCALLBACK LPDSENUMCALLBACKW +#define DirectSoundEnumerate DirectSoundEnumerateW +#define DirectSoundCaptureEnumerate DirectSoundCaptureEnumerateW +#else // UNICODE +#define LPDSENUMCALLBACK LPDSENUMCALLBACKA +#define DirectSoundEnumerate DirectSoundEnumerateA +#define DirectSoundCaptureEnumerate DirectSoundCaptureEnumerateA +#endif // UNICODE + +// +// IDirectSound +// + +DEFINE_GUID(IID_IDirectSound, 0x279AFA83, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + +#undef INTERFACE +#define INTERFACE IDirectSound + +DECLARE_INTERFACE_(IDirectSound, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID FAR *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSound methods + STDMETHOD(CreateSoundBuffer) (THIS_ LPCDSBUFFERDESC, LPDIRECTSOUNDBUFFER *, LPUNKNOWN) PURE; + STDMETHOD(GetCaps) (THIS_ LPDSCAPS) PURE; + STDMETHOD(DuplicateSoundBuffer) (THIS_ LPDIRECTSOUNDBUFFER, LPDIRECTSOUNDBUFFER *) PURE; + STDMETHOD(SetCooperativeLevel) (THIS_ HWND, DWORD) PURE; + STDMETHOD(Compact) (THIS) PURE; + STDMETHOD(GetSpeakerConfig) (THIS_ LPDWORD) PURE; + STDMETHOD(SetSpeakerConfig) (THIS_ DWORD) PURE; + STDMETHOD(Initialize) (THIS_ LPGUID) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectSound_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectSound_Release(p) (p)->lpVtbl->Release(p) +#define IDirectSound_CreateSoundBuffer(p,a,b,c) (p)->lpVtbl->CreateSoundBuffer(p,a,b,c) +#define IDirectSound_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSound_DuplicateSoundBuffer(p,a,b) (p)->lpVtbl->DuplicateSoundBuffer(p,a,b) +#define IDirectSound_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b) +#define IDirectSound_Compact(p) (p)->lpVtbl->Compact(p) +#define IDirectSound_GetSpeakerConfig(p,a) (p)->lpVtbl->GetSpeakerConfig(p,a) +#define IDirectSound_SetSpeakerConfig(p,b) (p)->lpVtbl->SetSpeakerConfig(p,b) +#define IDirectSound_Initialize(p,a) (p)->lpVtbl->Initialize(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectSound_AddRef(p) (p)->AddRef() +#define IDirectSound_Release(p) (p)->Release() +#define IDirectSound_CreateSoundBuffer(p,a,b,c) (p)->CreateSoundBuffer(a,b,c) +#define IDirectSound_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSound_DuplicateSoundBuffer(p,a,b) (p)->DuplicateSoundBuffer(a,b) +#define IDirectSound_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b) +#define IDirectSound_Compact(p) (p)->Compact() +#define IDirectSound_GetSpeakerConfig(p,a) (p)->GetSpeakerConfig(a) +#define IDirectSound_SetSpeakerConfig(p,b) (p)->SetSpeakerConfig(b) +#define IDirectSound_Initialize(p,a) (p)->Initialize(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundBuffer +// + +DEFINE_GUID(IID_IDirectSoundBuffer, 0x279AFA85, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + +#undef INTERFACE +#define INTERFACE IDirectSoundBuffer + +DECLARE_INTERFACE_(IDirectSoundBuffer, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID FAR *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundBuffer methods + STDMETHOD(GetCaps) (THIS_ LPDSBCAPS) PURE; + STDMETHOD(GetCurrentPosition) (THIS_ LPDWORD, LPDWORD) PURE; + STDMETHOD(GetFormat) (THIS_ LPWAVEFORMATEX, DWORD, LPDWORD) PURE; + STDMETHOD(GetVolume) (THIS_ LPLONG) PURE; + STDMETHOD(GetPan) (THIS_ LPLONG) PURE; + STDMETHOD(GetFrequency) (THIS_ LPDWORD) PURE; + STDMETHOD(GetStatus) (THIS_ LPDWORD) PURE; + STDMETHOD(Initialize) (THIS_ LPDIRECTSOUND, LPCDSBUFFERDESC) PURE; + STDMETHOD(Lock) (THIS_ DWORD, DWORD, LPVOID *, LPDWORD, LPVOID *, LPDWORD, DWORD) PURE; + STDMETHOD(Play) (THIS_ DWORD, DWORD, DWORD) PURE; + STDMETHOD(SetCurrentPosition) (THIS_ DWORD) PURE; + STDMETHOD(SetFormat) (THIS_ LPCWAVEFORMATEX) PURE; + STDMETHOD(SetVolume) (THIS_ LONG) PURE; + STDMETHOD(SetPan) (THIS_ LONG) PURE; + STDMETHOD(SetFrequency) (THIS_ DWORD) PURE; + STDMETHOD(Stop) (THIS) PURE; + STDMETHOD(Unlock) (THIS_ LPVOID, DWORD, LPVOID, DWORD) PURE; + STDMETHOD(Restore) (THIS) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectSoundBuffer_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectSoundBuffer_Release(p) (p)->lpVtbl->Release(p) +#define IDirectSoundBuffer_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSoundBuffer_GetCurrentPosition(p,a,b) (p)->lpVtbl->GetCurrentPosition(p,a,b) +#define IDirectSoundBuffer_GetFormat(p,a,b,c) (p)->lpVtbl->GetFormat(p,a,b,c) +#define IDirectSoundBuffer_GetVolume(p,a) (p)->lpVtbl->GetVolume(p,a) +#define IDirectSoundBuffer_GetPan(p,a) (p)->lpVtbl->GetPan(p,a) +#define IDirectSoundBuffer_GetFrequency(p,a) (p)->lpVtbl->GetFrequency(p,a) +#define IDirectSoundBuffer_GetStatus(p,a) (p)->lpVtbl->GetStatus(p,a) +#define IDirectSoundBuffer_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDirectSoundBuffer_Lock(p,a,b,c,d,e,f,g) (p)->lpVtbl->Lock(p,a,b,c,d,e,f,g) +#define IDirectSoundBuffer_Play(p,a,b,c) (p)->lpVtbl->Play(p,a,b,c) +#define IDirectSoundBuffer_SetCurrentPosition(p,a) (p)->lpVtbl->SetCurrentPosition(p,a) +#define IDirectSoundBuffer_SetFormat(p,a) (p)->lpVtbl->SetFormat(p,a) +#define IDirectSoundBuffer_SetVolume(p,a) (p)->lpVtbl->SetVolume(p,a) +#define IDirectSoundBuffer_SetPan(p,a) (p)->lpVtbl->SetPan(p,a) +#define IDirectSoundBuffer_SetFrequency(p,a) (p)->lpVtbl->SetFrequency(p,a) +#define IDirectSoundBuffer_Stop(p) (p)->lpVtbl->Stop(p) +#define IDirectSoundBuffer_Unlock(p,a,b,c,d) (p)->lpVtbl->Unlock(p,a,b,c,d) +#define IDirectSoundBuffer_Restore(p) (p)->lpVtbl->Restore(p) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundBuffer_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectSoundBuffer_AddRef(p) (p)->AddRef() +#define IDirectSoundBuffer_Release(p) (p)->Release() +#define IDirectSoundBuffer_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSoundBuffer_GetCurrentPosition(p,a,b) (p)->GetCurrentPosition(a,b) +#define IDirectSoundBuffer_GetFormat(p,a,b,c) (p)->GetFormat(a,b,c) +#define IDirectSoundBuffer_GetVolume(p,a) (p)->GetVolume(a) +#define IDirectSoundBuffer_GetPan(p,a) (p)->GetPan(a) +#define IDirectSoundBuffer_GetFrequency(p,a) (p)->GetFrequency(a) +#define IDirectSoundBuffer_GetStatus(p,a) (p)->GetStatus(a) +#define IDirectSoundBuffer_Initialize(p,a,b) (p)->Initialize(a,b) +#define IDirectSoundBuffer_Lock(p,a,b,c,d,e,f,g) (p)->Lock(a,b,c,d,e,f,g) +#define IDirectSoundBuffer_Play(p,a,b,c) (p)->Play(a,b,c) +#define IDirectSoundBuffer_SetCurrentPosition(p,a) (p)->SetCurrentPosition(a) +#define IDirectSoundBuffer_SetFormat(p,a) (p)->SetFormat(a) +#define IDirectSoundBuffer_SetVolume(p,a) (p)->SetVolume(a) +#define IDirectSoundBuffer_SetPan(p,a) (p)->SetPan(a) +#define IDirectSoundBuffer_SetFrequency(p,a) (p)->SetFrequency(a) +#define IDirectSoundBuffer_Stop(p) (p)->Stop() +#define IDirectSoundBuffer_Unlock(p,a,b,c,d) (p)->Unlock(a,b,c,d) +#define IDirectSoundBuffer_Restore(p) (p)->Restore() +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSound3DListener +// + +DEFINE_GUID(IID_IDirectSound3DListener, 0x279AFA84, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + +#undef INTERFACE +#define INTERFACE IDirectSound3DListener + +DECLARE_INTERFACE_(IDirectSound3DListener, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID FAR *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSound3D methods + STDMETHOD(GetAllParameters) (THIS_ LPDS3DLISTENER) PURE; + STDMETHOD(GetDistanceFactor) (THIS_ LPD3DVALUE) PURE; + STDMETHOD(GetDopplerFactor) (THIS_ LPD3DVALUE) PURE; + STDMETHOD(GetOrientation) (THIS_ LPD3DVECTOR, LPD3DVECTOR) PURE; + STDMETHOD(GetPosition) (THIS_ LPD3DVECTOR) PURE; + STDMETHOD(GetRolloffFactor) (THIS_ LPD3DVALUE) PURE; + STDMETHOD(GetVelocity) (THIS_ LPD3DVECTOR) PURE; + STDMETHOD(SetAllParameters) (THIS_ LPCDS3DLISTENER, DWORD) PURE; + STDMETHOD(SetDistanceFactor) (THIS_ D3DVALUE, DWORD) PURE; + STDMETHOD(SetDopplerFactor) (THIS_ D3DVALUE, DWORD) PURE; + STDMETHOD(SetOrientation) (THIS_ D3DVALUE, D3DVALUE, D3DVALUE, D3DVALUE, D3DVALUE, D3DVALUE, DWORD) PURE; + STDMETHOD(SetPosition) (THIS_ D3DVALUE, D3DVALUE, D3DVALUE, DWORD) PURE; + STDMETHOD(SetRolloffFactor) (THIS_ D3DVALUE, DWORD) PURE; + STDMETHOD(SetVelocity) (THIS_ D3DVALUE, D3DVALUE, D3DVALUE, DWORD) PURE; + STDMETHOD(CommitDeferredSettings) (THIS) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DListener_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectSound3DListener_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectSound3DListener_Release(p) (p)->lpVtbl->Release(p) +#define IDirectSound3DListener_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#define IDirectSound3DListener_GetDistanceFactor(p,a) (p)->lpVtbl->GetDistanceFactor(p,a) +#define IDirectSound3DListener_GetDopplerFactor(p,a) (p)->lpVtbl->GetDopplerFactor(p,a) +#define IDirectSound3DListener_GetOrientation(p,a,b) (p)->lpVtbl->GetOrientation(p,a,b) +#define IDirectSound3DListener_GetPosition(p,a) (p)->lpVtbl->GetPosition(p,a) +#define IDirectSound3DListener_GetRolloffFactor(p,a) (p)->lpVtbl->GetRolloffFactor(p,a) +#define IDirectSound3DListener_GetVelocity(p,a) (p)->lpVtbl->GetVelocity(p,a) +#define IDirectSound3DListener_SetAllParameters(p,a,b) (p)->lpVtbl->SetAllParameters(p,a,b) +#define IDirectSound3DListener_SetDistanceFactor(p,a,b) (p)->lpVtbl->SetDistanceFactor(p,a,b) +#define IDirectSound3DListener_SetDopplerFactor(p,a,b) (p)->lpVtbl->SetDopplerFactor(p,a,b) +#define IDirectSound3DListener_SetOrientation(p,a,b,c,d,e,f,g) (p)->lpVtbl->SetOrientation(p,a,b,c,d,e,f,g) +#define IDirectSound3DListener_SetPosition(p,a,b,c,d) (p)->lpVtbl->SetPosition(p,a,b,c,d) +#define IDirectSound3DListener_SetRolloffFactor(p,a,b) (p)->lpVtbl->SetRolloffFactor(p,a,b) +#define IDirectSound3DListener_SetVelocity(p,a,b,c,d) (p)->lpVtbl->SetVelocity(p,a,b,c,d) +#define IDirectSound3DListener_CommitDeferredSettings(p) (p)->lpVtbl->CommitDeferredSettings(p) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DListener_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectSound3DListener_AddRef(p) (p)->AddRef() +#define IDirectSound3DListener_Release(p) (p)->Release() +#define IDirectSound3DListener_GetAllParameters(p,a) (p)->GetAllParameters(a) +#define IDirectSound3DListener_GetDistanceFactor(p,a) (p)->GetDistanceFactor(a) +#define IDirectSound3DListener_GetDopplerFactor(p,a) (p)->GetDopplerFactor(a) +#define IDirectSound3DListener_GetOrientation(p,a,b) (p)->GetOrientation(a,b) +#define IDirectSound3DListener_GetPosition(p,a) (p)->GetPosition(a) +#define IDirectSound3DListener_GetRolloffFactor(p,a) (p)->GetRolloffFactor(a) +#define IDirectSound3DListener_GetVelocity(p,a) (p)->GetVelocity(a) +#define IDirectSound3DListener_SetAllParameters(p,a,b) (p)->SetAllParameters(a,b) +#define IDirectSound3DListener_SetDistanceFactor(p,a,b) (p)->SetDistanceFactor(a,b) +#define IDirectSound3DListener_SetDopplerFactor(p,a,b) (p)->SetDopplerFactor(a,b) +#define IDirectSound3DListener_SetOrientation(p,a,b,c,d,e,f,g) (p)->SetOrientation(a,b,c,d,e,f,g) +#define IDirectSound3DListener_SetPosition(p,a,b,c,d) (p)->SetPosition(a,b,c,d) +#define IDirectSound3DListener_SetRolloffFactor(p,a,b) (p)->SetRolloffFactor(a,b) +#define IDirectSound3DListener_SetVelocity(p,a,b,c,d) (p)->SetVelocity(a,b,c,d) +#define IDirectSound3DListener_CommitDeferredSettings(p) (p)->CommitDeferredSettings() +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSound3DBuffer +// + +DEFINE_GUID(IID_IDirectSound3DBuffer, 0x279AFA86, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + +#undef INTERFACE +#define INTERFACE IDirectSound3DBuffer + +DECLARE_INTERFACE_(IDirectSound3DBuffer, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundBuffer3D methods + STDMETHOD(GetAllParameters) (THIS_ LPDS3DBUFFER) PURE; + STDMETHOD(GetConeAngles) (THIS_ LPDWORD, LPDWORD) PURE; + STDMETHOD(GetConeOrientation) (THIS_ LPD3DVECTOR) PURE; + STDMETHOD(GetConeOutsideVolume) (THIS_ LPLONG) PURE; + STDMETHOD(GetMaxDistance) (THIS_ LPD3DVALUE) PURE; + STDMETHOD(GetMinDistance) (THIS_ LPD3DVALUE) PURE; + STDMETHOD(GetMode) (THIS_ LPDWORD) PURE; + STDMETHOD(GetPosition) (THIS_ LPD3DVECTOR) PURE; + STDMETHOD(GetVelocity) (THIS_ LPD3DVECTOR) PURE; + STDMETHOD(SetAllParameters) (THIS_ LPCDS3DBUFFER, DWORD) PURE; + STDMETHOD(SetConeAngles) (THIS_ DWORD, DWORD, DWORD) PURE; + STDMETHOD(SetConeOrientation) (THIS_ D3DVALUE, D3DVALUE, D3DVALUE, DWORD) PURE; + STDMETHOD(SetConeOutsideVolume) (THIS_ LONG, DWORD) PURE; + STDMETHOD(SetMaxDistance) (THIS_ D3DVALUE, DWORD) PURE; + STDMETHOD(SetMinDistance) (THIS_ D3DVALUE, DWORD) PURE; + STDMETHOD(SetMode) (THIS_ DWORD, DWORD) PURE; + STDMETHOD(SetPosition) (THIS_ D3DVALUE, D3DVALUE, D3DVALUE, DWORD) PURE; + STDMETHOD(SetVelocity) (THIS_ D3DVALUE, D3DVALUE, D3DVALUE, DWORD) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectSound3DBuffer_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectSound3DBuffer_Release(p) (p)->lpVtbl->Release(p) +#define IDirectSound3DBuffer_GetAllParameters(p,a) (p)->lpVtbl->GetAllParameters(p,a) +#define IDirectSound3DBuffer_GetConeAngles(p,a,b) (p)->lpVtbl->GetConeAngles(p,a,b) +#define IDirectSound3DBuffer_GetConeOrientation(p,a) (p)->lpVtbl->GetConeOrientation(p,a) +#define IDirectSound3DBuffer_GetConeOutsideVolume(p,a) (p)->lpVtbl->GetConeOutsideVolume(p,a) +#define IDirectSound3DBuffer_GetPosition(p,a) (p)->lpVtbl->GetPosition(p,a) +#define IDirectSound3DBuffer_GetMinDistance(p,a) (p)->lpVtbl->GetMinDistance(p,a) +#define IDirectSound3DBuffer_GetMaxDistance(p,a) (p)->lpVtbl->GetMaxDistance(p,a) +#define IDirectSound3DBuffer_GetMode(p,a) (p)->lpVtbl->GetMode(p,a) +#define IDirectSound3DBuffer_GetVelocity(p,a) (p)->lpVtbl->GetVelocity(p,a) +#define IDirectSound3DBuffer_SetAllParameters(p,a,b) (p)->lpVtbl->SetAllParameters(p,a,b) +#define IDirectSound3DBuffer_SetConeAngles(p,a,b,c) (p)->lpVtbl->SetConeAngles(p,a,b,c) +#define IDirectSound3DBuffer_SetConeOrientation(p,a,b,c,d) (p)->lpVtbl->SetConeOrientation(p,a,b,c,d) +#define IDirectSound3DBuffer_SetConeOutsideVolume(p,a,b)(p)->lpVtbl->SetConeOutsideVolume(p,a,b) +#define IDirectSound3DBuffer_SetPosition(p,a,b,c,d) (p)->lpVtbl->SetPosition(p,a,b,c,d) +#define IDirectSound3DBuffer_SetMinDistance(p,a,b) (p)->lpVtbl->SetMinDistance(p,a,b) +#define IDirectSound3DBuffer_SetMaxDistance(p,a,b) (p)->lpVtbl->SetMaxDistance(p,a,b) +#define IDirectSound3DBuffer_SetMode(p,a,b) (p)->lpVtbl->SetMode(p,a,b) +#define IDirectSound3DBuffer_SetVelocity(p,a,b,c,d) (p)->lpVtbl->SetVelocity(p,a,b,c,d) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSound3DBuffer_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectSound3DBuffer_AddRef(p) (p)->AddRef() +#define IDirectSound3DBuffer_Release(p) (p)->Release() +#define IDirectSound3DBuffer_GetAllParameters(p,a) (p)->GetAllParameters(a) +#define IDirectSound3DBuffer_GetConeAngles(p,a,b) (p)->GetConeAngles(a,b) +#define IDirectSound3DBuffer_GetConeOrientation(p,a) (p)->GetConeOrientation(a) +#define IDirectSound3DBuffer_GetConeOutsideVolume(p,a) (p)->GetConeOutsideVolume(a) +#define IDirectSound3DBuffer_GetPosition(p,a) (p)->GetPosition(a) +#define IDirectSound3DBuffer_GetMinDistance(p,a) (p)->GetMinDistance(a) +#define IDirectSound3DBuffer_GetMaxDistance(p,a) (p)->GetMaxDistance(a) +#define IDirectSound3DBuffer_GetMode(p,a) (p)->GetMode(a) +#define IDirectSound3DBuffer_GetVelocity(p,a) (p)->GetVelocity(a) +#define IDirectSound3DBuffer_SetAllParameters(p,a,b) (p)->SetAllParameters(a,b) +#define IDirectSound3DBuffer_SetConeAngles(p,a,b,c) (p)->SetConeAngles(a,b,c) +#define IDirectSound3DBuffer_SetConeOrientation(p,a,b,c,d) (p)->SetConeOrientation(a,b,c,d) +#define IDirectSound3DBuffer_SetConeOutsideVolume(p,a,b)(p)->SetConeOutsideVolume(a,b) +#define IDirectSound3DBuffer_SetPosition(p,a,b,c,d) (p)->SetPosition(a,b,c,d) +#define IDirectSound3DBuffer_SetMinDistance(p,a,b) (p)->SetMinDistance(a,b) +#define IDirectSound3DBuffer_SetMaxDistance(p,a,b) (p)->SetMaxDistance(a,b) +#define IDirectSound3DBuffer_SetMode(p,a,b) (p)->SetMode(a,b) +#define IDirectSound3DBuffer_SetVelocity(p,a,b,c,d) (p)->SetVelocity(a,b,c,d) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundCapture +// + +DEFINE_GUID(IID_IDirectSoundCapture, 0xb0210781, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); + +#undef INTERFACE +#define INTERFACE IDirectSoundCapture + +DECLARE_INTERFACE_(IDirectSoundCapture, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundCapture methods + STDMETHOD(CreateCaptureBuffer) (THIS_ LPCDSCBUFFERDESC, LPDIRECTSOUNDCAPTUREBUFFER *, LPUNKNOWN) PURE; + STDMETHOD(GetCaps) (THIS_ LPDSCCAPS ) PURE; + STDMETHOD(Initialize) (THIS_ LPGUID) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCapture_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectSoundCapture_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectSoundCapture_Release(p) (p)->lpVtbl->Release(p) +#define IDirectSoundCapture_CreateCaptureBuffer(p,a,b,c) (p)->lpVtbl->CreateCaptureBuffer(p,a,b,c) +#define IDirectSoundCapture_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSoundCapture_Initialize(p,a) (p)->lpVtbl->Initialize(p,a) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCapture_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectSoundCapture_AddRef(p) (p)->AddRef() +#define IDirectSoundCapture_Release(p) (p)->Release() +#define IDirectSoundCapture_CreateCaptureBuffer(p,a,b,c) (p)->CreateCaptureBuffer(a,b,c) +#define IDirectSoundCapture_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSoundCapture_Initialize(p,a) (p)->Initialize(a) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundCaptureBuffer +// + +DEFINE_GUID(IID_IDirectSoundCaptureBuffer, 0xb0210782, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); + +#undef INTERFACE +#define INTERFACE IDirectSoundCaptureBuffer + +DECLARE_INTERFACE_(IDirectSoundCaptureBuffer, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundCaptureBuffer methods + STDMETHOD(GetCaps) (THIS_ LPDSCBCAPS ) PURE; + STDMETHOD(GetCurrentPosition) (THIS_ LPDWORD, LPDWORD ) PURE; + STDMETHOD(GetFormat) (THIS_ LPWAVEFORMATEX, DWORD, LPDWORD ) PURE; + STDMETHOD(GetStatus) (THIS_ LPDWORD ) PURE; + STDMETHOD(Initialize) (THIS_ LPDIRECTSOUNDCAPTURE, LPCDSCBUFFERDESC) PURE; + STDMETHOD(Lock) (THIS_ DWORD, DWORD, LPVOID *, LPDWORD, LPVOID *, LPDWORD, DWORD) PURE; + STDMETHOD(Start) (THIS_ DWORD) PURE; + STDMETHOD(Stop) (THIS) PURE; + STDMETHOD(Unlock) (THIS_ LPVOID, DWORD, LPVOID, DWORD) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectSoundCaptureBuffer_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectSoundCaptureBuffer_Release(p) (p)->lpVtbl->Release(p) +#define IDirectSoundCaptureBuffer_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a) +#define IDirectSoundCaptureBuffer_GetCurrentPosition(p,a,b) (p)->lpVtbl->GetCurrentPosition(p,a,b) +#define IDirectSoundCaptureBuffer_GetFormat(p,a,b,c) (p)->lpVtbl->GetFormat(p,a,b,c) +#define IDirectSoundCaptureBuffer_GetStatus(p,a) (p)->lpVtbl->GetStatus(p,a) +#define IDirectSoundCaptureBuffer_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b) +#define IDirectSoundCaptureBuffer_Lock(p,a,b,c,d,e,f,g) (p)->lpVtbl->Lock(p,a,b,c,d,e,f,g) +#define IDirectSoundCaptureBuffer_Start(p,a) (p)->lpVtbl->Start(p,a) +#define IDirectSoundCaptureBuffer_Stop(p) (p)->lpVtbl->Stop(p) +#define IDirectSoundCaptureBuffer_Unlock(p,a,b,c,d) (p)->lpVtbl->Unlock(p,a,b,c,d) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundCaptureBuffer_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectSoundCaptureBuffer_AddRef(p) (p)->AddRef() +#define IDirectSoundCaptureBuffer_Release(p) (p)->Release() +#define IDirectSoundCaptureBuffer_GetCaps(p,a) (p)->GetCaps(a) +#define IDirectSoundCaptureBuffer_GetCurrentPosition(p,a,b) (p)->GetCurrentPosition(a,b) +#define IDirectSoundCaptureBuffer_GetFormat(p,a,b,c) (p)->GetFormat(a,b,c) +#define IDirectSoundCaptureBuffer_GetStatus(p,a) (p)->GetStatus(a) +#define IDirectSoundCaptureBuffer_Initialize(p,a,b) (p)->Initialize(a,b) +#define IDirectSoundCaptureBuffer_Lock(p,a,b,c,d,e,f,g) (p)->Lock(a,b,c,d,e,f,g) +#define IDirectSoundCaptureBuffer_Start(p,a) (p)->Start(a) +#define IDirectSoundCaptureBuffer_Stop(p) (p)->Stop() +#define IDirectSoundCaptureBuffer_Unlock(p,a,b,c,d) (p)->Unlock(a,b,c,d) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IDirectSoundNotify +// + +DEFINE_GUID(IID_IDirectSoundNotify, 0xb0210783, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16); + +#undef INTERFACE +#define INTERFACE IDirectSoundNotify + +DECLARE_INTERFACE_(IDirectSoundNotify, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IDirectSoundNotify methods + STDMETHOD(SetNotificationPositions) (THIS_ DWORD, LPCDSBPOSITIONNOTIFY) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundNotify_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirectSoundNotify_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirectSoundNotify_Release(p) (p)->lpVtbl->Release(p) +#define IDirectSoundNotify_SetNotificationPositions(p,a,b) (p)->lpVtbl->SetNotificationPositions(p,a,b) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IDirectSoundNotify_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirectSoundNotify_AddRef(p) (p)->AddRef() +#define IDirectSoundNotify_Release(p) (p)->Release() +#define IDirectSoundNotify_SetNotificationPositions(p,a,b) (p)->SetNotificationPositions(a,b) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +// +// IKsPropertySet +// + +#ifndef _IKsPropertySet_ +#define _IKsPropertySet_ + +#ifdef __cplusplus +// 'struct' not 'class' per the way DECLARE_INTERFACE_ is defined +struct IKsPropertySet; +#endif // __cplusplus + +typedef struct IKsPropertySet *LPKSPROPERTYSET; + +#define KSPROPERTY_SUPPORT_GET 0x00000001 +#define KSPROPERTY_SUPPORT_SET 0x00000002 + +DEFINE_GUID(IID_IKsPropertySet, 0x31efac30, 0x515c, 0x11d0, 0xa9, 0xaa, 0x00, 0xaa, 0x00, 0x61, 0xbe, 0x93); + +#undef INTERFACE +#define INTERFACE IKsPropertySet + +DECLARE_INTERFACE_(IKsPropertySet, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID *) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IKsPropertySet methods + STDMETHOD(Get) (THIS_ REFGUID, ULONG, LPVOID, ULONG, LPVOID, ULONG, PULONG) PURE; + STDMETHOD(Set) (THIS_ REFGUID, ULONG, LPVOID, ULONG, LPVOID, ULONG) PURE; + STDMETHOD(QuerySupport) (THIS_ REFGUID, ULONG, PULONG) PURE; +}; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IKsPropertySet_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IKsPropertySet_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IKsPropertySet_Release(p) (p)->lpVtbl->Release(p) +#define IKsPropertySet_Get(p,a,b,c,d,e,f,g) (p)->lpVtbl->Get(p,a,b,c,d,e,f,g) +#define IKsPropertySet_Set(p,a,b,c,d,e,f) (p)->lpVtbl->Set(p,a,b,c,d,e,f) +#define IKsPropertySet_QuerySupport(p,a,b,c) (p)->lpVtbl->QuerySupport(p,a,b,c) +#else // !defined(__cplusplus) || defined(CINTERFACE) +#define IKsPropertySet_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IKsPropertySet_AddRef(p) (p)->AddRef() +#define IKsPropertySet_Release(p) (p)->Release() +#define IKsPropertySet_Get(p,a,b,c,d,e,f,g) (p)->Get(a,b,c,d,e,f,g) +#define IKsPropertySet_Set(p,a,b,c,d,e,f) (p)->Set(a,b,c,d,e,f) +#define IKsPropertySet_QuerySupport(p,a,b,c) (p)->QuerySupport(a,b,c) +#endif // !defined(__cplusplus) || defined(CINTERFACE) + +#endif // _IKsPropertySet_ + +// +// Return Codes +// + +#define DS_OK 0 + +// The call failed because resources (such as a priority level) +// were already being used by another caller. +#define DSERR_ALLOCATED MAKE_DSHRESULT(10) + +// The control (vol,pan,etc.) requested by the caller is not available. +#define DSERR_CONTROLUNAVAIL MAKE_DSHRESULT(30) + +// An invalid parameter was passed to the returning function +#define DSERR_INVALIDPARAM E_INVALIDARG + +// This call is not valid for the current state of this object +#define DSERR_INVALIDCALL MAKE_DSHRESULT(50) + +// An undetermined error occured inside the DirectSound subsystem +#define DSERR_GENERIC E_FAIL + +// The caller does not have the priority level required for the function to +// succeed. +#define DSERR_PRIOLEVELNEEDED MAKE_DSHRESULT(70) + +// Not enough free memory is available to complete the operation +#define DSERR_OUTOFMEMORY E_OUTOFMEMORY + +// The specified WAVE format is not supported +#define DSERR_BADFORMAT MAKE_DSHRESULT(100) + +// The function called is not supported at this time +#define DSERR_UNSUPPORTED E_NOTIMPL + +// No sound driver is available for use +#define DSERR_NODRIVER MAKE_DSHRESULT(120) + +// This object is already initialized +#define DSERR_ALREADYINITIALIZED MAKE_DSHRESULT(130) + +// This object does not support aggregation +#define DSERR_NOAGGREGATION CLASS_E_NOAGGREGATION + +// The buffer memory has been lost, and must be restored. +#define DSERR_BUFFERLOST MAKE_DSHRESULT(150) + +// Another app has a higher priority level, preventing this call from +// succeeding. +#define DSERR_OTHERAPPHASPRIO MAKE_DSHRESULT(160) + +// This object has not been initialized +#define DSERR_UNINITIALIZED MAKE_DSHRESULT(170) + +// The requested COM interface is not available +#define DSERR_NOINTERFACE E_NOINTERFACE + +// +// Flags +// + +#define DSCAPS_PRIMARYMONO 0x00000001 +#define DSCAPS_PRIMARYSTEREO 0x00000002 +#define DSCAPS_PRIMARY8BIT 0x00000004 +#define DSCAPS_PRIMARY16BIT 0x00000008 +#define DSCAPS_CONTINUOUSRATE 0x00000010 +#define DSCAPS_EMULDRIVER 0x00000020 +#define DSCAPS_CERTIFIED 0x00000040 +#define DSCAPS_SECONDARYMONO 0x00000100 +#define DSCAPS_SECONDARYSTEREO 0x00000200 +#define DSCAPS_SECONDARY8BIT 0x00000400 +#define DSCAPS_SECONDARY16BIT 0x00000800 + +#define DSBPLAY_LOOPING 0x00000001 + +#define DSBSTATUS_PLAYING 0x00000001 +#define DSBSTATUS_BUFFERLOST 0x00000002 +#define DSBSTATUS_LOOPING 0x00000004 + +#define DSBLOCK_FROMWRITECURSOR 0x00000001 +#define DSBLOCK_ENTIREBUFFER 0x00000002 + +#define DSSCL_NORMAL 0x00000001 +#define DSSCL_PRIORITY 0x00000002 +#define DSSCL_EXCLUSIVE 0x00000003 +#define DSSCL_WRITEPRIMARY 0x00000004 + +#define DS3DMODE_NORMAL 0x00000000 +#define DS3DMODE_HEADRELATIVE 0x00000001 +#define DS3DMODE_DISABLE 0x00000002 + +#define DSBCAPS_PRIMARYBUFFER 0x00000001 +#define DSBCAPS_STATIC 0x00000002 +#define DSBCAPS_LOCHARDWARE 0x00000004 +#define DSBCAPS_LOCSOFTWARE 0x00000008 +#define DSBCAPS_CTRL3D 0x00000010 +#define DSBCAPS_CTRLFREQUENCY 0x00000020 +#define DSBCAPS_CTRLPAN 0x00000040 +#define DSBCAPS_CTRLVOLUME 0x00000080 +#define DSBCAPS_CTRLPOSITIONNOTIFY 0x00000100 +#define DSBCAPS_CTRLDEFAULT 0x000000E0 +#define DSBCAPS_CTRLALL 0x000001F0 +#define DSBCAPS_STICKYFOCUS 0x00004000 +#define DSBCAPS_GLOBALFOCUS 0x00008000 +#define DSBCAPS_GETCURRENTPOSITION2 0x00010000 +#define DSBCAPS_MUTE3DATMAXDISTANCE 0x00020000 + +#define DSCBCAPS_WAVEMAPPED 0x80000000 + +#define DSSPEAKER_HEADPHONE 0x00000001 +#define DSSPEAKER_MONO 0x00000002 +#define DSSPEAKER_QUAD 0x00000003 +#define DSSPEAKER_STEREO 0x00000004 +#define DSSPEAKER_SURROUND 0x00000005 + +#define DSSPEAKER_GEOMETRY_MIN 0x00000005 // 5 degrees +#define DSSPEAKER_GEOMETRY_NARROW 0x0000000A // 10 degrees +#define DSSPEAKER_GEOMETRY_WIDE 0x00000014 // 20 degrees +#define DSSPEAKER_GEOMETRY_MAX 0x000000B4 // 180 degrees + +#define DSSPEAKER_COMBINED(c, g) ((DWORD)(((BYTE)(c)) | ((DWORD)((BYTE)(g))) << 16)) +#define DSSPEAKER_CONFIG(a) ((BYTE)(a)) +#define DSSPEAKER_GEOMETRY(a) ((BYTE)(((DWORD)(a) >> 16) & 0x00FF)) + +#define DSBFREQUENCY_MIN 100 +#define DSBFREQUENCY_MAX 100000 +#define DSBFREQUENCY_ORIGINAL 0 + +#define DSBPAN_LEFT -10000 +#define DSBPAN_CENTER 0 +#define DSBPAN_RIGHT 10000 + +#define DSBVOLUME_MIN -10000 +#define DSBVOLUME_MAX 0 + +#define DSBSIZE_MIN 4 +#define DSBSIZE_MAX 0x0FFFFFFF + +#define DS3D_IMMEDIATE 0x00000000 +#define DS3D_DEFERRED 0x00000001 + +#define DS3D_MINDISTANCEFACTOR FLT_MIN +#define DS3D_MAXDISTANCEFACTOR FLT_MAX +#define DS3D_DEFAULTDISTANCEFACTOR 1.0f + +#define DS3D_MINROLLOFFFACTOR 0.0f +#define DS3D_MAXROLLOFFFACTOR 10.0f +#define DS3D_DEFAULTROLLOFFFACTOR 1.0f + +#define DS3D_MINDOPPLERFACTOR 0.0f +#define DS3D_MAXDOPPLERFACTOR 10.0f +#define DS3D_DEFAULTDOPPLERFACTOR 1.0f + +#define DS3D_DEFAULTMINDISTANCE 1.0f +#define DS3D_DEFAULTMAXDISTANCE 1000000000.0f + +#define DS3D_MINCONEANGLE 0 +#define DS3D_MAXCONEANGLE 360 +#define DS3D_DEFAULTCONEANGLE 360 + +#define DS3D_DEFAULTCONEOUTSIDEVOLUME DSBVOLUME_MAX + +#define DSCCAPS_EMULDRIVER 0x00000020 + +#define DSCBLOCK_ENTIREBUFFER 0x00000001 + +#define DSCBSTATUS_CAPTURING 0x00000001 +#define DSCBSTATUS_LOOPING 0x00000002 + +#define DSCBSTART_LOOPING 0x00000001 + +#define DSBPN_OFFSETSTOP 0xFFFFFFFF + +#ifdef __cplusplus +}; +#endif // __cplusplus + +#endif // __DSOUND_INCLUDED__ diff --git a/mandplyr.cpp b/mandplyr.cpp new file mode 100644 index 0000000..37199ae --- /dev/null +++ b/mandplyr.cpp @@ -0,0 +1,229 @@ +/********************************************/ +/* MandPlyr Player Expert Object to control*/ +/* commuted dual plucked-string model */ +/* by Perry Cook, 1995-96 */ +/********************************************/ + +#include "Instrmnt.h" +#include "Mandolin.h" +#include "mandplyr.h" +#include "VoicMang.h" +#include "Noise.h" +#include "SKINI11.msg" + +MandPlyr :: MandPlyr() : Instrmnt() +{ + short i; + strings = new VoicMang(NUM_STRINGS,"Mandolin"); + noise = new Noise; + strumming = 0; + strumRate = (long) (SRATE * 0.1); // ( 1/(0.1) = 10Hz) + strumCount = 0; + skill = (MY_FLOAT) 0.90; + for (i=0;itick(); + if (errDir < 0) + isErr = -errDir; + else + isErr = errDir; + if (isErr < (0.4 * (1.0 - skill))) { /* Should we err here? */ + error = 1; + if (strumming < 1) { + strumming = 2; + strumCount = strumRate; + } + if (errDir < 0.0) error = -1; /* random error +/- 1/2 step */ + } + + + i = 0; + notDone = 1; + while (notDone && inoteOnN((MY_FLOAT) num + error,amp); + notDone = 0; + if (tags[i]<0) { + printf("Must Reallocate a note\n"); + notDone = 1; + } + } + i++; + } + if (notDone) { + temp = strings->oldestVoice(); + i = 0; + while (notDone && ikill(temp); + nums[i] = num; + amps[i] = amp; + tags[i] = strings->noteOnN((MY_FLOAT) num + error,amp); + notDone = 0; + } + i++; + } + } + if (notDone) printf("Can't allocate a new note\n"); +} + +void MandPlyr :: noteOffN(short num,MY_FLOAT amp) +{ + long temp; + short i; + temp = strings->noteOffN(num,amp); + if (temp>0) { // Usual Case + for (i=0;inoteOffT(num,amp); + tags[i] = -1; + nums[i] = 0; + amps[i] = (MY_FLOAT) 0.0; + } + } + } + if (strumming == 2) strumming = 0; +} + +MY_FLOAT MandPlyr :: tick() +{ + short i; + MY_FLOAT temp2; + if (strumming > 0) { + strumCount -= 1; + if (strumCount <= 0) { + for (i=0;i 0) { + strings->kill(tags[i]); + temp2 = (MY_FLOAT) fabs(noise->tick()); + if (temp2 > 0.2 * (1.0 - skill)) + tags[i] = strings->noteOnN(nums[i],amps[i]); + } + } + strumCount = strumRate; + strumCount = strumCount + + (long) (strumCount * (noise->tick() * (1.0 - skill))); + if (strumming == 2) strumming = 0; + } + } + for (i=0;inoteOnN(nums[i],amps[i]); + } + } + } + lastOutput = strings->tick(); + return lastOutput; +} + + +/* Some very basic Mandolin Chords */ +/* Base Strings: G D A E */ +/* G Chord: G D B G */ +/* C Chord: G E C G */ +/* D Chord: A D A F# */ +/* E Chord: G# E B G# */ +/* A Chord: A E C# A */ +/* B Chord: B D# B F# */ + +#define NUM_CHORDS 6 + +void MandPlyr :: playChord(MY_FLOAT amp, char *chordString) +{ + short i; + char chordStr[NUM_CHORDS+1] = {"GCDEAB"}; + short chords[NUM_CHORDS][4] = { + {55,62,71,79}, + {55,64,72,79}, + {57,62,69,78}, + {56,64,71,80}, + {57,64,73,81}, + {59,63,71,78} }; + short whichChord = -1; + + for (i=0;i<4;i++) + if (tags[i] >= 0) strings->noteOffT(tags[i],amp); + + for (i=0;icontrolChange(number,value); + else if (number == __SK_PickPosition_) + strings->controlChange(number,value); + else if (number == __SK_StringDamping_) + strings->controlChange(number,value); + else if (number == __SK_StringDetune_) + strings->controlChange(number,value); + + else if (number == __SK_Strumming_) { + if (value < 0.5) + strumming = 0; + else + strumming = 1; + } + else if (number == __SK_NotStrumming_) + strumming = 0; + else if (number == __SK_PlayerSkill_) + skill = value * (MY_FLOAT) NORM_7; + else if (number == __SK_StrumSpeed_) + strumRate = (long) (SRATE * value * NORM_7); // (0 - 1Hz.) + else { + printf("MandPlyr : Undefined Control Number!!\n"); + } +} diff --git a/mandplyr.h b/mandplyr.h new file mode 100644 index 0000000..6dc0246 --- /dev/null +++ b/mandplyr.h @@ -0,0 +1,41 @@ +/********************************************/ +/* MandPlyr Player Expert Object to control*/ +/* commuted dual plucked-string model */ +/* by Perry Cook, 1995-96 */ +/********************************************/ + +#if !defined(__MandPlyr_h) +#define __MandPlyr_h + +#include "Instrmnt.h" +#include "VoicMang.h" +#include "Noise.h" + +#define NUM_STRINGS 4 + +class MandPlyr : public Instrmnt +{ + protected: + VoicMang *strings; + Noise *noise; + short strumming; + long strumRate; + long strumCount; + MY_FLOAT skill; + short nums[NUM_STRINGS]; // For Now Integer Note Nums + MY_FLOAT amps[NUM_STRINGS]; + long tags[NUM_STRINGS]; + public: + MandPlyr(); + ~MandPlyr(); + virtual void noteOnN(short num, MY_FLOAT amp); + virtual void noteOffN(short num, MY_FLOAT amp); + virtual MY_FLOAT tick(); + MY_FLOAT special_tick(); + virtual void controlChange(int number, MY_FLOAT value); + virtual void playChord(MY_FLOAT amp, char* chordString); +}; + +#endif + + diff --git a/md2skini.dsp b/md2skini.dsp new file mode 100644 index 0000000..7b75b6f --- /dev/null +++ b/md2skini.dsp @@ -0,0 +1,114 @@ +# Microsoft Developer Studio Project File - Name="MD2SKINI" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=MD2SKINI - 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 "MD2SKINI.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 "MD2SKINI.MAK" CFG="MD2SKINI - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "MD2SKINI - Win32 Release" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "MD2SKINI - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "MD2SKINI - 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 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /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 winmm.lib dsound.lib Wsock32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "MD2SKINI - 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 /MT /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /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 winmm.lib dsound.lib Wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "MD2SKINI - Win32 Release" +# Name "MD2SKINI - Win32 Debug" +# Begin Source File + +SOURCE=.\MD2SKINI.cpp +# End Source File +# Begin Source File + +SOURCE=.\MIDIIO.cpp +# End Source File +# Begin Source File + +SOURCE=.\MIDIIO.h +# End Source File +# Begin Source File + +SOURCE=.\Miditabl.h +# End Source File +# Begin Source File + +SOURCE=.\Object.cpp +# End Source File +# Begin Source File + +SOURCE=.\Object.h +# End Source File +# Begin Source File + +SOURCE=.\SKINI11.msg +# End Source File +# End Target +# End Project diff --git a/md2skini.plg b/md2skini.plg new file mode 100644 index 0000000..3864b57 --- /dev/null +++ b/md2skini.plg @@ -0,0 +1,28 @@ +--------------------Configuration: MD2SKINI - Win32 Release-------------------- +Begining build with project "D:\gary\Research\STK98v2\MD2SKINI.DSP", at root. +Active configuration is Win32 (x86) Console Application (based on Win32 (x86) Console Application) + +Project's tools are: + "32-bit C/C++ Compiler for 80x86" with flags "/nologo /MT /W3 /GX /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"Release/MD2SKINI.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c " + "Win32 Resource Compiler" with flags "/l 0x409 /d "NDEBUG" " + "Browser Database Maker" with flags "/nologo /o"MD2SKINI.bsc" " + "COFF Linker for 80x86" with flags "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib dsound.lib Wsock32.lib /nologo /subsystem:console /incremental:no /pdb:"MD2SKINI.pdb" /machine:I386 /out:"MD2SKINI.exe" " + "Custom Build" with flags "" + "" with flags "" + +Creating temp file "c:\windows\TEMP\RSPD220.TMP" with contents +Creating command line "cl.exe @c:\windows\TEMP\RSPD220.TMP" +Creating temp file "c:\windows\TEMP\RSPD221.TMP" with contents +Creating command line "link.exe @c:\windows\TEMP\RSPD221.TMP" +Compiling... +MD2SKINI.cpp +Linking... + + + +MD2SKINI.exe - 0 error(s), 0 warning(s) diff --git a/miditabl.h b/miditabl.h index 4c2c08f..8240175 100644 --- a/miditabl.h +++ b/miditabl.h @@ -1,3 +1,5 @@ +#include "Object.h" + double __MIDI_To_Pitch[128] = { 8.18,8.66,9.18,9.72,10.30,10.91,11.56,12.25, 12.98,13.75,14.57,15.43,16.35,17.32,18.35,19.45, diff --git a/phonTabl.h b/phontabl.h similarity index 100% rename from phonTabl.h rename to phontabl.h diff --git a/rawwaves/drumwavs/bass.raw b/rawwaves/bassdrum.raw similarity index 100% rename from rawwaves/drumwavs/bass.raw rename to rawwaves/bassdrum.raw diff --git a/rawwaves/drumwavs/cowbell.raw b/rawwaves/cowbell1.raw similarity index 100% rename from rawwaves/drumwavs/cowbell.raw rename to rawwaves/cowbell1.raw diff --git a/rawwaves/drumwavs/crash.raw b/rawwaves/crashcym.raw similarity index 100% rename from rawwaves/drumwavs/crash.raw rename to rawwaves/crashcym.raw diff --git a/rawwaves/dope.raw b/rawwaves/dope.raw new file mode 100644 index 0000000..6a7a1ff Binary files /dev/null and b/rawwaves/dope.raw differ diff --git a/rawwaves/drumwavs/hat.raw b/rawwaves/hihatcym.raw similarity index 100% rename from rawwaves/drumwavs/hat.raw rename to rawwaves/hihatcym.raw diff --git a/rawwaves/MAKEFUNC.C b/rawwaves/makefunc.c similarity index 100% rename from rawwaves/MAKEFUNC.C rename to rawwaves/makefunc.c diff --git a/rawwaves/MAKEMIDI.C b/rawwaves/makemidi.c similarity index 100% rename from rawwaves/MAKEMIDI.C rename to rawwaves/makemidi.c diff --git a/rawwaves/MAKEWAVS.C b/rawwaves/makewavs.c similarity index 100% rename from rawwaves/MAKEWAVS.C rename to rawwaves/makewavs.c diff --git a/rawwaves/mand1.raw b/rawwaves/mand1.raw new file mode 100644 index 0000000..bc04a05 Binary files /dev/null and b/rawwaves/mand1.raw differ diff --git a/rawwaves/mand10.raw b/rawwaves/mand10.raw new file mode 100644 index 0000000..4b35376 Binary files /dev/null and b/rawwaves/mand10.raw differ diff --git a/rawwaves/mand11.raw b/rawwaves/mand11.raw new file mode 100644 index 0000000..94889be Binary files /dev/null and b/rawwaves/mand11.raw differ diff --git a/rawwaves/mand12.raw b/rawwaves/mand12.raw new file mode 100644 index 0000000..a128642 Binary files /dev/null and b/rawwaves/mand12.raw differ diff --git a/rawwaves/mand2.raw b/rawwaves/mand2.raw new file mode 100644 index 0000000..6208008 Binary files /dev/null and b/rawwaves/mand2.raw differ diff --git a/rawwaves/mand3.raw b/rawwaves/mand3.raw new file mode 100644 index 0000000..8857f86 Binary files /dev/null and b/rawwaves/mand3.raw differ diff --git a/rawwaves/mand4.raw b/rawwaves/mand4.raw new file mode 100644 index 0000000..6058eb1 Binary files /dev/null and b/rawwaves/mand4.raw differ diff --git a/rawwaves/mand5.raw b/rawwaves/mand5.raw new file mode 100644 index 0000000..9b308a8 Binary files /dev/null and b/rawwaves/mand5.raw differ diff --git a/rawwaves/mand6.raw b/rawwaves/mand6.raw new file mode 100644 index 0000000..05f083d Binary files /dev/null and b/rawwaves/mand6.raw differ diff --git a/rawwaves/mand7.raw b/rawwaves/mand7.raw new file mode 100644 index 0000000..64941e9 Binary files /dev/null and b/rawwaves/mand7.raw differ diff --git a/rawwaves/mand8.raw b/rawwaves/mand8.raw new file mode 100644 index 0000000..52027bf Binary files /dev/null and b/rawwaves/mand8.raw differ diff --git a/rawwaves/mand9.raw b/rawwaves/mand9.raw new file mode 100644 index 0000000..9e88a0c Binary files /dev/null and b/rawwaves/mand9.raw differ diff --git a/rawwaves/MIDITABL.H b/rawwaves/mditabl.h similarity index 100% rename from rawwaves/MIDITABL.H rename to rawwaves/mditabl.h diff --git a/rawwaves/drumwavs/ride.raw b/rawwaves/ridecymb.raw similarity index 100% rename from rawwaves/drumwavs/ride.raw rename to rawwaves/ridecymb.raw diff --git a/rawwaves/drumwavs/snar.raw b/rawwaves/snardrum.raw similarity index 100% rename from rawwaves/drumwavs/snar.raw rename to rawwaves/snardrum.raw diff --git a/rawwaves/drumwavs/tamb.raw b/rawwaves/tambourn.raw similarity index 100% rename from rawwaves/drumwavs/tamb.raw rename to rawwaves/tambourn.raw diff --git a/rawwaves/drumwavs/tomhi.raw b/rawwaves/tomhidrm.raw similarity index 100% rename from rawwaves/drumwavs/tomhi.raw rename to rawwaves/tomhidrm.raw diff --git a/rawwaves/drumwavs/tomlow.raw b/rawwaves/tomlowdr.raw similarity index 100% rename from rawwaves/drumwavs/tomlow.raw rename to rawwaves/tomlowdr.raw diff --git a/rawwaves/drumwavs/tommid.raw b/rawwaves/tommiddr.raw similarity index 100% rename from rawwaves/drumwavs/tommid.raw rename to rawwaves/tommiddr.raw diff --git a/scores/Instructions b/scores/Instructions deleted file mode 100644 index 7752a16..0000000 --- a/scores/Instructions +++ /dev/null @@ -1,5 +0,0 @@ -useage: testMono Instr file.mtx - where Instr = Marimba Vibraphn AgogoBel Plucked - Mandolin Clarinet Flute Brass Bowed - Rhodey Wurley TubeBell HeavyMtl - PercFlut BeeThree Moog1 diff --git a/scores/capture.ski b/scores/capture.ski new file mode 100644 index 0000000..9087b13 --- /dev/null +++ b/scores/capture.ski @@ -0,0 +1,156 @@ +NoteOn 0.3 1 77.000000 64.000000 +ControlChange 0.3 1 1 5.000000 +ControlChange 0.3 1 2 19.000000 +ControlChange 0.3 1 2 17.000000 +ControlChange 0.3 1 2 16.000000 +ControlChange 0.3 1 2 15.000000 +ControlChange 0.3 1 2 14.000000 +ControlChange 0.3 1 2 13.000000 +ControlChange 0.3 1 2 12.000000 +ControlChange 0.3 1 2 10.300000 +ControlChange 0.3 1 2 9.000000 +ControlChange 0.3 1 2 8.000000 +ControlChange 0.3 1 2 7.000000 +ControlChange 0.3 1 2 6.000000 +ControlChange 0.3 1 2 5.000000 +ControlChange 0.3 1 2 4.000000 +ControlChange 0.3 1 2 3.000000 +ControlChange 0.3 1 2 2.000000 +ControlChange 0.3 1 2 1.000000 +ControlChange 0.3 1 2 2.000000 +ControlChange 0.3 1 2 4.000000 +ControlChange 0.3 1 2 5.000000 +ControlChange 0.3 1 2 7.000000 +ControlChange 0.3 1 2 8.000000 +ControlChange 0.3 1 2 9.000000 +ControlChange 0.3 1 2 10.300000 +ControlChange 0.3 1 2 11.000000 +ControlChange 0.3 1 2 12.000000 +ControlChange 0.3 1 2 13.000000 +ControlChange 0.3 1 2 14.000000 +ControlChange 0.3 1 2 15.000000 +ControlChange 0.3 1 2 16.000000 +ControlChange 0.3 1 2 17.000000 +ControlChange 0.3 1 2 18.000000 +ControlChange 0.3 1 2 19.000000 +ControlChange 0.3 1 2 21.000000 +ControlChange 0.3 1 2 22.000000 +ControlChange 0.3 1 2 24.000000 +ControlChange 0.3 1 2 26.000000 +ControlChange 0.3 1 2 28.000000 +ControlChange 0.3 1 2 31.000000 +ControlChange 0.3 1 2 34.000000 +ControlChange 0.3 1 2 38.000000 +ControlChange 0.3 1 2 42.000000 +ControlChange 0.3 1 2 44.000000 +ControlChange 0.3 1 2 48.000000 +ControlChange 0.3 1 2 52.000000 +ControlChange 0.3 1 2 53.000000 +ControlChange 0.3 1 2 56.000000 +ControlChange 0.3 1 2 57.000000 +ControlChange 0.3 1 2 58.000000 +ControlChange 0.3 1 2 59.000000 +ControlChange 0.3 1 2 60.300000 +ControlChange 0.3 1 2 63.000000 +ControlChange 0.3 1 2 66.000000 +ControlChange 0.3 1 2 70.300000 +ControlChange 0.3 1 2 72.000000 +ControlChange 0.3 1 2 76.000000 +ControlChange 0.3 1 2 79.000000 +ControlChange 0.3 1 2 83.000000 +ControlChange 0.3 1 2 85.000000 +ControlChange 0.3 1 2 86.000000 +ControlChange 0.3 1 2 88.000000 +ControlChange 0.3 1 2 90.300000 +ControlChange 0.3 1 2 91.000000 +ControlChange 0.3 1 2 93.000000 +ControlChange 0.3 1 2 94.000000 +ControlChange 0.3 1 2 96.000000 +ControlChange 0.3 1 2 97.000000 +ControlChange 0.3 1 2 99.000000 +ControlChange 0.3 1 2 100.300000 +ControlChange 0.3 1 2 101.000000 +ControlChange 0.3 1 2 102.000000 +ControlChange 0.3 1 2 104.000000 +ControlChange 0.3 1 2 107.000000 +ControlChange 0.3 1 2 112.000000 +ControlChange 0.3 1 2 114.000000 +ControlChange 0.3 1 2 119.000000 +ControlChange 0.3 1 2 123.000000 +ControlChange 0.3 1 2 128.000000 +ControlChange 0.3 1 2 126.000000 +ControlChange 0.3 1 2 121.000000 +ControlChange 0.3 1 2 120.300000 +ControlChange 0.3 1 2 116.000000 +ControlChange 0.3 1 2 112.000000 +ControlChange 0.3 1 2 111.000000 +ControlChange 0.3 1 2 109.000000 +ControlChange 0.3 1 2 108.000000 +ControlChange 0.3 1 2 107.000000 +ControlChange 0.3 1 2 106.000000 +ControlChange 0.3 1 2 105.000000 +ControlChange 0.3 1 2 103.000000 +ControlChange 0.3 1 2 101.000000 +ControlChange 0.3 1 2 100.300000 +ControlChange 0.3 1 2 98.000000 +ControlChange 0.3 1 2 97.000000 +ControlChange 0.3 1 2 96.000000 +ControlChange 0.3 1 2 93.000000 +ControlChange 0.3 1 2 92.000000 +ControlChange 0.3 1 2 89.000000 +ControlChange 0.3 1 2 86.000000 +ControlChange 0.3 1 2 83.000000 +ControlChange 0.3 1 2 79.000000 +ControlChange 0.3 1 2 76.000000 +ControlChange 0.3 1 2 73.000000 +ControlChange 0.3 1 2 72.000000 +ControlChange 0.3 1 2 69.000000 +ControlChange 0.3 1 2 68.000000 +ControlChange 0.3 1 2 66.000000 +ControlChange 0.3 1 2 65.000000 +ControlChange 0.3 1 2 64.000000 +ControlChange 0.3 1 2 63.000000 +ControlChange 0.3 1 2 62.000000 +ControlChange 0.3 1 2 61.000000 +ControlChange 0.3 1 2 59.000000 +ControlChange 0.3 1 2 58.000000 +ControlChange 0.3 1 2 56.000000 +ControlChange 0.3 1 2 52.000000 +ControlChange 0.3 1 2 50.300000 +ControlChange 0.3 1 2 49.000000 +ControlChange 0.3 1 2 48.000000 +ControlChange 0.3 1 2 45.000000 +ControlChange 0.3 1 2 43.000000 +ControlChange 0.3 1 2 41.000000 +ControlChange 0.3 1 2 40.300000 +ControlChange 0.3 1 2 39.000000 +ControlChange 0.3 1 2 37.000000 +ControlChange 0.3 1 2 35.000000 +ControlChange 0.3 1 2 34.000000 +ControlChange 0.3 1 2 33.000000 +ControlChange 0.3 1 2 32.000000 +ControlChange 0.3 1 2 31.000000 +ControlChange 0.3 1 2 30.300000 +ControlChange 0.3 1 2 29.000000 +ControlChange 0.3 1 2 27.000000 +ControlChange 0.3 1 2 25.000000 +ControlChange 0.3 1 2 24.000000 +ControlChange 0.3 1 2 23.000000 +ControlChange 0.3 1 2 22.000000 +ControlChange 0.3 1 2 20.300000 +ControlChange 0.3 1 2 19.000000 +ControlChange 0.3 1 2 18.000000 +ControlChange 0.3 1 2 16.000000 +ControlChange 0.3 1 2 15.000000 +ControlChange 0.3 1 2 12.000000 +ControlChange 0.3 1 2 10.300000 +ControlChange 0.3 1 2 8.000000 +ControlChange 0.3 1 2 6.000000 +ControlChange 0.3 1 2 5.000000 +ControlChange 0.3 1 2 4.000000 +ControlChange 0.3 1 2 3.000000 +ControlChange 0.3 1 2 2.000000 +ControlChange 0.3 1 2 1.000000 +ControlChange 0.3 1 2 0.300000 +NoteOff 0.3 1 77.000000 127 +ExitProgram diff --git a/scores/chords.ski b/scores/chords.ski new file mode 100644 index 0000000..e2ae786 --- /dev/null +++ b/scores/chords.ski @@ -0,0 +1,112 @@ +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +StringDamping 0.0 2 127 +Chord 0.0 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 C +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 C +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 D +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 D +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 C +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 C +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 D +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.2 2 32 +StringDamping 0.0 2 127 +ChordOff 0.0 2 100 +Chord 0.2 2 100 G +StringDamping 0.1 2 32 +ChordOff 0.1 2 100 + +StringDamping 0.0 2 120 +Strumming 0.0 2 127 +NoteOn 0.1 2 55 60 +NoteOff 0.7 2 55 60 +NoteOn 0.0 2 60 60 +NoteOff 0.4 2 60 60 +NoteOn 0.0 2 62 60 +NoteOff 0.2 2 62 60 +NoteOn 0.0 2 60 60 +NoteOff 0.2 2 60 60 +NoteOn 0.0 2 59 60 +NoteOff 0.4 2 59 60 +NoteOn 0.0 2 57 60 +NoteOff 0.2 2 57 60 +NoteOn 0.0 2 55 60 +NoteOff 0.2 2 55 60 +NoteOn 0.0 2 62 60 +NoteOff 0.8 2 62 60 + +NoteOn 0.1 2 67 100 +NoteOff 0.7 2 67 100 +NoteOn 0.0 2 72 100 +NoteOff 0.4 2 72 100 +NoteOn 0.0 2 74 100 +NoteOff 0.2 2 74 100 +NoteOn 0.0 2 72 100 +NoteOff 0.2 2 72 100 +NotStrumming 0.0 2 0 +NoteOn 0.0 2 71 100 +NoteOff 0.1 2 71 100 +NoteOn 0.0 2 76 100 +NoteOff 0.1 2 76 100 +NoteOn 0.0 2 74 100 +NoteOff 0.1 2 74 100 +NoteOn 0.0 2 70 100 +NoteOff 0.1 2 70 100 +NoteOn 0.0 2 69 100 +NoteOff 0.1 2 69 100 +NoteOn 0.0 2 67 100 +NoteOff 0.1 2 67 100 +NoteOn 0.0 2 64 100 +NoteOff 0.1 2 64 100 +NoteOn 0.0 2 62 100 +NoteOff 0.1 2 62 100 +Chord 0.0 2 64 G +ChordOff 2.0 2 64 diff --git a/scores/drumfunk.ski b/scores/drumfunk.ski new file mode 100644 index 0000000..20ae0b1 --- /dev/null +++ b/scores/drumfunk.ski @@ -0,0 +1,129 @@ +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.000000 1 49 127.000000 +NoteOn 0.000000 1 42 127.000000 +NoteOn 0.400000 1 38 127.000000 +NoteOn 0.300000 1 36 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.000000 1 38 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.100000 1 42 127.000000 + +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 42 127.000000 +NoteOn 0.200000 1 49 127.000000 +NoteOn 0.200000 1 38 127.000000 +NoteOn 0.300000 1 36 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.000000 1 38 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 + +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 49 127.000000 +NoteOn 0.000000 1 42 127.000000 +NoteOn 0.400000 1 38 127.000000 +NoteOn 0.300000 1 36 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.000000 1 38 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 + +NoteOn 0.100000 1 36 60.000000 +NoteOn 0.200000 1 38 80.000000 +NoteOn 0.200000 1 38 90.000000 +NoteOn 0.100000 1 38 100.000000 +NoteOn 0.100000 1 38 105.000000 +NoteOn 0.100000 1 38 110.000000 +NoteOn 0.100000 1 50 127.000000 +NoteOn 0.100000 1 50 127.000000 +NoteOn 0.100000 1 50 127.000000 +NoteOn 0.100000 1 50 127.000000 +NoteOn 0.100000 1 45 127.000000 +NoteOn 0.100000 1 45 127.000000 +NoteOn 0.100000 1 41 127.000000 +NoteOn 0.100000 1 41 127.000000 + +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 49 127.000000 +NoteOn 0.000000 1 42 127.000000 +NoteOn 0.200000 1 56 127.000000 +NoteOn 0.200000 1 38 127.000000 +NoteOn 0.000000 1 56 127.000000 +NoteOn 0.300000 1 36 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.000000 1 38 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.100000 1 54 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.000000 1 54 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 54 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.000000 1 54 127.000000 + +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 49 127.000000 +NoteOn 0.000000 1 42 127.000000 +NoteOn 0.200000 1 56 127.000000 +NoteOn 0.200000 1 38 127.000000 +NoteOn 0.000000 1 56 127.000000 +NoteOn 0.300000 1 36 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.000000 1 38 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.100000 1 54 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 54 127.000000 +NoteOn 0.100000 1 42 127.000000 +NoteOn 0.000000 1 54 127.000000 + +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 49 127.000000 +NoteOn 0.000000 1 42 127.000000 +NoteOn 0.200000 1 56 127.000000 +NoteOn 0.200000 1 38 127.000000 +NoteOn 0.000000 1 56 127.000000 +NoteOn 0.300000 1 36 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.000000 1 38 127.000000 +NoteOn 0.200000 1 36 127.000000 +NoteOn 0.100000 1 54 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.000000 1 36 127.000000 +NoteOn 0.000000 1 54 127.000000 +NoteOn 0.100000 1 36 127.000000 +NoteOn 0.100000 1 42 127.000000 + +NoteOn 0.100000 1 32 127.000000 +NoteOn 0.200000 1 32 127.000000 +NoteOn 0.200000 1 32 127.000000 +NoteOn 0.300000 1 32 127.000000 +NoteOn 0.200000 1 32 127.000000 +NoteOn 0.200000 1 32 127.000000 +NoteOn 0.100000 1 52 127.000000 +NoteOn 0.100000 1 32 127.000000 +NoteOn 0.100000 1 32 127.000000 +NoteOn 0.100000 1 32 127.000000 + +NoteOn 0.100000 1 32 127.000000 +NoteOn 0.000000 1 46 127.000000 +NoteOn 0.000000 1 49 127.000000 +NoteOff 1.000000 1 49 127.000000 + +Exit diff --git a/scores/drumtest.ski b/scores/drumtest.ski new file mode 100644 index 0000000..763eb6a --- /dev/null +++ b/scores/drumtest.ski @@ -0,0 +1,57 @@ +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.300000 1 36 10.000000 +NoteOn 0.300000 1 36 50.000000 +NoteOn 0.300000 1 36 90.000000 +NoteOn 0.300000 1 36 127.000000 + +NoteOn 0.300000 1 38 10.000000 +NoteOn 0.300000 1 38 50.000000 +NoteOn 0.300000 1 38 90.000000 +NoteOn 0.300000 1 38 127.000000 + +NoteOn 0.300000 1 41 10.000000 +NoteOn 0.300000 1 41 50.000000 +NoteOn 0.300000 1 41 90.000000 +NoteOn 0.300000 1 41 127.000000 + +NoteOn 0.300000 1 42 10.000000 +NoteOn 0.300000 1 42 50.000000 +NoteOn 0.300000 1 42 90.000000 +NoteOn 0.300000 1 42 127.000000 + +NoteOn 0.300000 1 45 10.000000 +NoteOn 0.300000 1 45 50.000000 +NoteOn 0.300000 1 45 90.000000 +NoteOn 0.300000 1 45 127.000000 + +NoteOn 0.300000 1 46 10.000000 +NoteOn 0.300000 1 46 50.000000 +NoteOn 0.300000 1 46 90.000000 +NoteOn 0.300000 1 46 127.000000 + +NoteOn 0.300000 1 48 10.000000 +NoteOn 0.300000 1 48 50.000000 +NoteOn 0.300000 1 48 90.000000 +NoteOn 0.300000 1 48 127.000000 + +NoteOn 0.300000 1 49 10.000000 +NoteOn 0.300000 1 49 50.000000 +NoteOn 0.300000 1 49 90.000000 +NoteOn 0.300000 1 49 127.000000 + +NoteOn 0.300000 1 54 10.000000 +NoteOn 0.300000 1 54 50.000000 +NoteOn 0.300000 1 54 90.000000 +NoteOn 0.300000 1 54 127.000000 + +NoteOn 0.300000 1 56 10.000000 +NoteOn 0.300000 1 56 50.000000 +NoteOn 0.300000 1 56 90.000000 +NoteOn 0.300000 1 56 127.000000 + +NoteOn 0.300000 1 57 10.000000 +NoteOn 0.300000 1 57 50.000000 +NoteOn 0.300000 1 57 90.000000 +NoteOn 0.300000 1 57 127.000000 + +Exit diff --git a/scores/flutbach.ski b/scores/flutbach.ski new file mode 100644 index 0000000..c4820eb --- /dev/null +++ b/scores/flutbach.ski @@ -0,0 +1,97 @@ +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoiseLevel 0.000 1 30.0 +NoteOn 0.000 1 79 80.000000 +NoteOff 0.100 1 79 63.500000 +NoteOn 0.100 1 84 90.000000 +NoteOff 0.100 1 84 63.500000 +NoteOn 0.100 1 79 70.000000 +NoteOff 0.100 1 79 63.500000 + +NoteOn 0.100 1 76 120.000000 +NoteOn 0.100 1 77 110.000000 +NoteOn 0.100 1 79 70.000000 +NoteOff 0.100 1 79 70.0 +NoteOn 0.100 1 79 90.000000 +NoteOff 0.150 1 79 63.500000 + +NoteOn 0.050 1 79 80.000000 +NoteOff 0.100 1 79 63.500000 +NoteOn 0.100 1 84 90.000000 +NoteOff 0.100 1 84 63.500000 +NoteOn 0.100 1 79 70.000000 +NoteOff 0.100 1 79 63.500000 + +NoteOn 0.100 1 76 70.000000 +NoteOn 0.100 1 77 70.000000 +NoteOn 0.100 1 79 80.000000 +NoteOff 0.100 1 79 70.0 +NoteOn 0.100 1 79 90.000000 +NoteOff 0.150 1 79 63.500000 + +NoteOn 0.050 1 81 120.000000 +NoteOn 0.100 1 79 110.000000 +NoteOn 0.100 1 77 70.000000 +NoteOn 0.100 1 76 120.000000 +NoteOn 0.100 1 74 110.000000 +NoteOn 0.100 1 72 70.000000 + +NoteOn 0.100 1 81 120.000000 +NoteOn 0.200 1 82 60.000000 +NoteOff 0.100 1 82 64.000000 +NoteOn 0.100 1 81 110.000000 +NoteOn 0.200 1 79 60.000000 +NoteOff 0.100 1 79 64.000000 +NoteOn 0.100 1 77 110.000000 +NoteOn 0.200 1 76 60.000000 +NoteOff 0.100 1 76 64.000000 + +NoteOn 0.100 1 77 120.000000 +NoteOn 0.100 1 76 110.000000 +NoteOn 0.100 1 74 70.000000 +NoteOn 0.100 1 76 120.000000 +NoteOn 0.100 1 77 110.000000 +NoteOff 0.100 1 77 64.000000 + +NoteOn 0.100 1 79 120.000000 +NoteOn 0.100 1 81 110.000000 +NoteOn 0.100 1 79 70.000000 +NoteOn 0.100 1 77 120.000000 +NoteOn 0.100 1 76 110.000000 +NoteOn 0.100 1 74 110.000000 + +NoteOn 0.100 1 79 120.000000 +NoteOn 0.200 1 81 110.000000 +NoteOn 0.200 1 79 70.000000 +NoteOn 0.200 1 77 120.000000 +NoteOn 0.200 1 76 110.000000 +NoteOn 0.200 1 74 110.000000 +NoteOff 0.100 1 74 110.000000 + +NoteOn 0.100 1 76 120.000000 +NoteOn 0.100 1 74 110.000000 +NoteOn 0.100 1 72 70.000000 +NoteOn 0.100 1 74 120.000000 +NoteOff 0.070 1 74 120.000000 + +NoteOn 0.030 1 76 100.000000 +NoteOff 0.070 1 76 120.000000 +NoteOn 0.030 1 77 100.000000 +NoteOff 0.070 1 77 120.000000 +NoteOn 0.030 1 79 100.000000 +NoteOff 0.070 1 79 120.000000 +NoteOn 0.030 1 81 100.000000 +NoteOff 0.070 1 81 120.000000 +NoteOn 0.030 1 82 100.000000 +NoteOff 0.070 1 82 120.000000 +NoteOn 0.030 1 81 100.000000 +NoteOff 0.070 1 81 120.000000 +NoteOn 0.030 1 82 100.000000 +NoteOff 0.070 1 82 120.000000 +NoteOn 0.030 1 79 100.000000 +NoteOff 0.070 1 79 120.000000 + +NoiseLevel 0.000 1 40.0 +Modulation 0.000 1 25.0 +NoteOn 0.030 1 77 120.000000 +NoteOn 1.000 1 89 100.000000 +NoteOff 0.200 1 77 120.000000 diff --git a/scores/funicula.ski b/scores/funicula.ski index db3cd90..e524b5a 100644 --- a/scores/funicula.ski +++ b/scores/funicula.ski @@ -1,125 +1,180 @@ -/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ -NoteOn 0.000082 2 67 82 -NoteOff 0.140886 2 67 0 -NoteOn 0.305337 2 72 79 -NoteOff 0.080216 2 72 0 -NoteOn 0.048436 2 72 79 -NoteOff 0.115150 2 72 0 -NoteOn 0.087273 2 72 61 -NoteOff 0.095581 2 72 0 -NoteOn 0.062224 2 72 64 -NoteOff 0.071268 2 72 0 -NoteOn 0.011048 2 72 71 -NoteOff 0.054365 2 72 0 -NoteOn 0.036463 2 72 67 -NoteOff 0.072383 2 72 0 -NoteOn 0.016123 2 72 87 -NoteOff 0.052007 2 72 0 -NoteOn 0.048044 2 72 73 -NoteOff 0.105738 2 72 0 -NoteOn 0.019929 2 72 82 -NoteOff 0.058088 2 72 0 -NoteOn 0.194576 2 72 73 -NoteOff 0.117156 2 72 0 -NoteOn 0.036714 2 71 82 -NoteOff 0.148275 2 71 0 -NoteOn 0.118834 2 71 73 -NoteOff 0.104514 2 71 0 -NoteOn 0.027705 2 67 73 -NoteOff 0.167850 2 67 0 -NoteOn 0.112339 2 67 76 -NoteOff 0.113962 2 67 0 -NoteOn 0.049442 2 69 69 -NoteOff 0.145742 2 69 0 -NoteOn 0.106986 2 69 64 -NoteOff 0.104200 2 69 0 -NoteOn 0.036729 2 64 71 -NoteOff 0.291474 2 64 0 -NoteOn 0.146391 2 64 64 -NoteOff 0.621362 2 64 0 -NoteOn 0.133873 2 64 64 -NoteOff 0.114315 2 64 0 -NoteOn 0.034539 2 62 69 -NoteOff 0.206432 2 62 0 -NoteOn 0.073508 2 60 76 -NoteOff 0.078316 2 60 0 -NoteOn 0.072519 2 60 76 -NoteOff 1.052123 2 60 0 -NoteOn 0.131235 2 64 73 -NoteOff 0.130818 2 64 0 -NoteOn 0.015857 2 62 71 -NoteOff 0.161832 2 62 0 -NoteOn 0.112407 2 60 69 -NoteOff 0.086130 2 60 0 -NoteOn 0.069561 2 60 71 -NoteOff 0.930785 2 60 0 -NoteOn 0.420947 2 79 73 -NoteOff 0.122952 2 79 0 -NoteOn 0.302022 2 84 76 -NoteOff 0.058912 2 84 0 -NoteOn 0.047375 2 84 56 -NoteOff 0.050983 2 84 0 -NoteOn 0.024451 2 84 47 -NoteOff 0.040568 2 84 0 -NoteOn 0.074005 2 84 62 -NoteOff 0.038271 2 84 0 -NoteOn 0.017685 2 84 82 -NoteOff 0.050108 2 84 0 -NoteOn 0.045103 2 84 64 -NoteOff 0.052211 2 84 0 -NoteOn 0.027262 2 84 87 -NoteOff 0.057449 2 84 0 -NoteOn 0.020874 2 84 69 -NoteOff 0.064807 2 84 0 -NoteOn 0.023156 2 84 87 -NoteOff 0.065025 2 84 0 -NoteOn 0.020085 2 84 95 -NoteOff 0.083250 2 84 0 -NoteOn 0.262523 2 84 69 -NoteOn 0.009998 2 86 67 -NoteOff 0.033427 2 86 0 -NoteOff 0.049865 2 84 0 -NoteOn 0.053153 2 83 95 -NoteOff 0.158687 2 83 0 -NoteOn 0.110118 2 83 63 -NoteOff 0.096582 2 83 0 -NoteOn 0.025733 2 79 69 -NoteOff 0.189179 2 79 0 -NoteOn 0.090774 2 79 61 -NoteOff 0.104030 2 79 0 -NoteOn 0.055448 2 81 82 -NoteOff 0.175048 2 81 0 -NoteOn 0.090141 2 81 61 -NoteOff 0.109698 2 81 0 -NoteOn 0.028956 2 76 82 -NoteOff 0.314368 2 76 0 -NoteOn 0.108070 2 76 82 -NoteOff 0.575279 2 76 0 -NoteOn 0.097466 2 76 67 -NoteOff 0.119284 2 76 0 -NoteOn 0.037984 2 74 82 -NoteOff 0.133603 2 74 0 -NoteOn 0.132143 2 72 67 -NoteOff 0.058172 2 72 0 -NoteOn 0.090606 2 72 73 -NoteOff 0.068605 2 72 0 -NoteOn 0.056346 2 72 67 -NoteOff 0.124718 2 72 0 -NoteOn 0.056027 2 72 62 -NoteOff 0.059034 2 72 0 -NoteOn 0.005466 2 72 67 -NoteOff 0.051338 2 72 0 -NoteOn 0.048824 2 72 69 -NoteOff 0.118099 2 72 0 -NoteOn 0.047326 2 72 69 -NoteOff 0.066170 2 72 0 -NoteOn 0.006492 2 72 76 -NoteOff 0.179860 2 72 0 -NoteOn 0.189600 2 76 87 -NoteOff 0.090606 2 76 0 -NoteOn 0.063909 2 74 82 -NoteOff 0.188171 2 74 0 -NoteOn 0.085969 2 72 71 -NoteOff 0.063885 2 72 0 -NoteOn 0.073370 2 72 79 -NoteOff 1.011060 2 72 0 +NoteOn 0.000315 2 69 69 +NoteOff 0.139851 2 69 0 +NoteOn 0.292059 2 74 79 +NoteOff 0.069197 2 74 0 +NoteOn 0.046664 2 74 71 +NoteOff 0.062959 2 74 0 +NoteOn 0.025777 2 74 47 +NoteOff 0.037024 2 74 0 +NoteOn 0.065524 2 74 63 +NoteOff 0.059605 2 74 0 +NoteOn 0.019622 2 74 47 +NoteOff 0.039886 2 74 0 +NoteOn 0.052080 2 74 67 +NoteOff 0.061615 2 74 0 +NoteOn 0.021743 2 74 53 +NoteOff 0.042091 2 74 0 +NoteOn 0.056058 2 74 69 +NoteOff 0.122627 2 74 0 +NoteOn 0.047608 2 74 87 +NoteOff 0.128503 2 74 0 +NoteOn 0.187575 2 74 79 +NoteOff 0.113216 2 74 0 +NoteOn 0.055912 2 73 82 +NoteOff 0.145445 2 73 0 +NoteOn 0.104378 2 73 73 +NoteOff 0.120442 2 73 0 +NoteOn 0.047541 2 69 73 +NoteOff 0.151890 2 69 0 +NoteOn 0.098655 2 69 64 +NoteOff 0.137789 2 69 0 +NoteOn 0.042621 2 71 76 +NoteOff 0.171097 2 71 0 +NoteOn 0.081635 2 71 61 +NoteOff 0.073859 2 71 0 +NoteOn 0.110418 2 66 69 +NoteOff 0.304332 2 66 0 +NoteOn 0.119942 2 66 69 +NoteOff 0.057357 2 66 0 +NoteOn 0.034674 2 66 60 +NoteOff 0.056795 2 66 0 +NoteOn 0.018853 2 66 76 +NoteOff 0.061343 2 66 0 +NoteOn 0.048614 2 66 67 +NoteOff 0.058950 2 66 0 +NoteOn 0.008595 2 66 63 +NoteOff 0.057296 2 66 0 +NoteOn 0.036486 2 66 67 +NoteOff 0.125570 2 66 0 +NoteOn 0.055182 2 66 82 +NoteOff 0.079954 2 66 0 +NoteOn 0.021852 2 66 64 +NoteOff 0.085418 2 66 0 +NoteOn 0.065201 2 64 79 +NoteOff 0.070529 2 64 0 +NoteOn 0.055850 2 66 76 +NoteOff 0.080037 2 66 0 +NoteOn 0.047400 2 64 73 +NoteOff 0.079393 2 64 0 +NoteOn 0.075934 2 62 76 +NoteOff 0.073956 2 62 0 +NoteOn 0.038639 2 62 69 +NoteOff 0.125310 2 62 0 +NoteOn 0.067131 2 62 67 +NoteOff 0.114670 2 62 0 +NoteOn 0.053501 2 62 62 +NoteOff 0.058095 2 62 0 +NoteOn 0.017163 2 62 47 +NoteOff 0.056632 2 62 0 +NoteOn 0.023810 2 62 64 +NoteOff 0.070499 2 62 0 +NoteOn 0.018403 2 62 64 +NoteOff 0.044563 2 62 0 +NoteOn 0.038905 2 62 64 +NoteOff 0.128219 2 62 0 +NoteOn 0.020654 2 62 79 +NoteOff 0.100199 2 62 0 +NoteOn 0.119351 2 66 69 +NoteOff 0.140313 2 66 0 +NoteOn 0.023378 2 64 67 +NoteOff 0.157359 2 64 0 +NoteOn 0.103959 2 62 69 +NoteOff 0.072433 2 62 0 +NoteOn 0.089338 2 62 63 +NoteOff 0.067472 2 62 0 +NoteOn 0.131003 2 62 63 +NoteOff 0.092003 2 62 0 +NoteOn 0.084592 2 62 64 +NoteOff 0.156367 2 62 0 +NoteOn 0.024942 2 62 69 +NoteOff 0.154966 2 62 0 +NoteOn 0.023168 2 62 67 +NoteOff 0.402274 2 62 0 +NoteOn 0.151088 2 69 82 +NoteOff 0.295762 2 69 0 +NoteOn 0.144298 2 74 67 +NoteOff 0.064684 2 74 0 +NoteOn 0.046916 2 74 61 +NoteOff 0.061961 2 74 0 +NoteOn 0.013175 2 74 58 +NoteOff 0.063742 2 74 0 +NoteOn 0.063079 2 74 64 +NoteOff 0.115461 2 74 0 +NoteOn 0.066345 2 74 64 +NoteOff 0.104482 2 74 0 +NoteOn 0.058225 2 74 69 +NoteOff 0.137897 2 74 0 +NoteOn 0.028045 2 74 82 +NoteOff 0.227867 2 74 0 +NoteOn 0.089793 2 74 73 +NoteOff 0.137043 2 74 0 +NoteOn 0.027024 2 73 64 +NoteOff 0.156746 2 73 0 +NoteOn 0.091269 2 73 73 +NoteOff 0.144116 2 73 0 +NoteOn 0.040937 2 69 76 +NoteOff 0.131683 2 69 0 +NoteOn 0.111516 2 69 63 +NoteOff 0.119809 2 69 0 +NoteOn 0.055603 2 71 69 +NoteOff 0.151398 2 71 0 +NoteOn 0.092930 2 71 61 +NoteOff 0.077496 2 71 0 +NoteOn 0.108207 2 66 73 +NoteOff 0.268736 2 66 0 +NoteOn 0.105231 2 66 82 +NoteOff 0.068718 2 66 0 +NoteOn 0.052997 2 66 69 +NoteOff 0.121595 2 66 0 +NoteOn 0.089177 2 66 58 +NoteOff 0.106939 2 66 0 +NoteOn 0.049675 2 66 67 +NoteOff 0.145059 2 66 0 +NoteOn 0.033535 2 66 24 +NoteOff 0.169419 2 66 0 +NoteOn 0.058897 2 66 63 +NoteOff 0.086285 2 66 0 +NoteOn 0.041606 2 64 76 +NoteOff 0.084153 2 64 0 +NoteOn 0.044987 2 66 69 +NoteOff 0.100239 2 66 0 +NoteOn 0.022854 2 64 76 +NoteOff 0.075048 2 64 0 +NoteOn 0.065983 2 62 67 +NoteOff 0.081468 2 62 0 +NoteOn 0.040989 2 62 71 +NoteOff 0.134240 2 62 0 +NoteOn 0.062401 2 62 61 +NoteOff 0.119152 2 62 0 +NoteOn 0.050401 2 62 64 +NoteOff 0.128506 2 62 0 +NoteOn 0.030134 2 62 64 +NoteOff 0.142160 2 62 0 +NoteOn 0.037510 2 62 79 +NoteOff 0.239364 2 62 0 +NoteOn 0.018231 2 66 73 +NoteOff 0.131528 2 66 0 +NoteOn 0.042607 2 64 76 +NoteOff 0.149396 2 64 0 +NoteOn 0.089318 2 62 73 +NoteOff 0.087485 2 62 0 +NoteOn 0.085324 2 62 73 +NoteOff 0.072863 2 62 0 +NoteOn 0.023103 2 62 73 +NoteOff 0.085817 2 62 0 +NoteOn 0.021983 2 62 64 +NoteOff 0.061305 2 62 0 +NoteOn 0.036091 2 62 61 +NoteOff 0.070809 2 62 0 +NoteOn 0.011382 2 62 58 +NoteOff 0.060215 2 62 0 +NoteOn 0.027180 2 62 61 +NoteOff 0.075393 2 62 0 +NoteOn 0.025560 2 62 29 +NoteOff 0.038858 2 62 0 +NoteOn 0.030691 2 62 64 +NoteOff 0.129305 2 62 0 +NoteOn 0.021792 2 62 76 +NoteOff 0.075593 2 62 0 +NoteOn 0.030875 2 62 95 +NoteOff 0.459440 2 62 0 diff --git a/scores/funskini.ski b/scores/funskini.ski new file mode 100644 index 0000000..161a41c --- /dev/null +++ b/scores/funskini.ski @@ -0,0 +1,105 @@ +/* Howdy!!!! SKINI0.9 Test Score ***********/ + +// First a pretty good player +PlayerSkill 0.000000 2 100 +NoteOn 0.000081 2 69 64 +NoteOff 0.220735 2 69 0 +Strumming 0.000000 2 127 +NoteOn 0.244988 2 74 69 +NoteOff 1.085355 2 74 0 +NotStrumming 0.000000 2 0 +NoteOn 0.133034 2 74 58 +NoteOff 0.121377 2 74 0 +NoteOn 0.025178 2 73 56 +NoteOff 0.204028 2 73 0 +NoteOn 0.070314 2 73 58 +NoteOff 0.150998 2 73 0 +NoteOn 0.029853 2 69 63 +NoteOff 0.152847 2 69 0 +NoteOn 0.097649 2 69 58 +NoteOff 0.140495 2 69 0 +NoteOn 0.052114 2 71 69 +NoteOff 0.177446 2 71 0 +NoteOn 0.084674 2 71 53 +NoteOff 0.084189 2 71 0 +NoteOn 0.107113 2 66 82 +NoteOff 0.345345 2 66 0 +Strumming 0.000000 2 127 +NoteOn 0.114209 2 66 69 +NoteOff 0.638118 2 66 0 +NotStrumming 0.000000 2 0 +NoteOn 0.096405 2 66 61 +NoteOff 0.134993 2 66 0 +NoteOn 0.028328 2 64 67 +NoteOff 0.251752 2 64 0 +NoteOn 0.052434 2 62 64 +NoteOff 0.077954 2 62 0 +Strumming 0.000000 2 127 +NoteOn 0.069474 2 62 69 +NoteOff 1.132502 2 62 0 +NotStrumming 0.000000 2 0 +NoteOn 0.043887 2 66 69 +NoteOff 0.096938 2 66 0 +NoteOn 0.046985 2 64 71 +NoteOff 0.085443 2 64 0 +NoteOn 0.055538 2 66 63 +NoteOff 0.105148 2 66 0 +NoteOn 0.021553 2 64 62 +NoteOff 0.103749 2 64 0 +Strumming 0.000000 2 127 +NoteOn 0.054633 2 62 67 +NoteOff 1.033837 2 62 0 +NotStrumming 0.000000 2 0 + +// Now a really bad player +PlayerSkill 0.000000 2 10 +NoteOn 0.235617 2 69 69 +NoteOff 0.316772 2 69 0 +Strumming 0.000000 2 127 +NoteOn 0.145871 2 74 64 +NoteOff 1.100060 2 74 0 +NotStrumming 0.000000 2 0 +NoteOn 0.115729 2 74 58 +NoteOff 0.166520 2 74 0 +NoteOn 0.007216 2 73 61 +NoteOff 0.192106 2 73 0 +NoteOn 0.067405 2 73 62 +NoteOff 0.160641 2 73 0 +NoteOn 0.015116 2 69 58 +NoteOff 0.176983 2 69 0 +NoteOn 0.083744 2 69 62 +NoteOff 0.155400 2 69 0 +NoteOn 0.020502 2 71 69 +NoteOff 0.187489 2 71 0 +NoteOn 0.076011 2 71 56 +NoteOff 0.094456 2 71 0 +NoteOn 0.094632 2 66 73 +NoteOff 0.303251 2 66 0 +Strumming 0.000000 2 127 +NoteOn 0.136058 2 66 69 +NoteOff 0.601147 2 66 0 +NotStrumming 0.000000 2 0 +NoteOn 0.073985 2 66 56 +NoteOff 0.145772 2 66 0 +NoteOn 0.028922 2 64 64 +NoteOff 0.082327 2 64 0 +NoteOn 0.047864 2 66 61 +NoteOff 0.099460 2 66 0 +NoteOn 0.020486 2 64 40 +NoteOff 0.131447 2 64 0 +Strumming 0.000000 2 127 +NoteOn 0.042691 2 62 71 +NoteOff 1.131626 2 62 0 +NotStrumming 0.000000 2 0 +NoteOn 0.040285 2 66 51 +NoteOff 0.141532 2 66 0 +NoteOn 0.016442 2 64 64 +NoteOff 0.195371 2 64 0 +NoteOn 0.073368 2 62 67 +NoteOff 0.098382 2 62 0 +Strumming 0.000000 2 127 +NoteOn 0.082045 2 62 69 +NoteOff 0.796526 2 62 0 +NotStrumming 0.000000 2 0 +NoteOn 0.079242 2 62 64 +NoteOff 0.473653 2 62 0 diff --git a/scores/marimba2.ski b/scores/marimba2.ski new file mode 100644 index 0000000..4a9d3bf --- /dev/null +++ b/scores/marimba2.ski @@ -0,0 +1,107 @@ +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.001 1 48 88.899998 +NoteOff 0.100 1 48 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 67 88.899998 +NoteOff 0.100 1 67 63.500000 +NoteOn 0.001 1 76 88.899998 +NoteOff 0.100 1 76 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 55 88.899998 +NoteOff 0.100 1 55 63.500000 +NoteOn 0.001 1 91 88.899998 +NoteOff 0.200 1 91 63.500000 + +StickHardness 0.000 1 30 +NoteOn 0.001 1 48 88.899998 +NoteOff 0.100 1 48 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 67 88.899998 +NoteOff 0.100 1 67 63.500000 +NoteOn 0.001 1 76 88.899998 +NoteOff 0.100 1 76 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 55 88.899998 +NoteOff 0.100 1 55 63.500000 +NoteOn 0.001 1 67 88.899998 +NoteOff 0.200 1 67 63.500000 + +StickHardness 0.000 1 120 +NoteOn 0.001 1 48 88.899998 +NoteOff 0.200 1 48 63.500000 +NoteOn 0.001 1 67 88.899998 +NoteOff 0.100 1 67 63.500000 +NoteOn 0.001 1 76 88.899998 +NoteOff 0.100 1 76 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 55 88.899998 +NoteOff 0.100 1 55 63.500000 +NoteOn 0.001 1 67 88.899998 +NoteOff 0.200 1 67 63.500000 + +StickHardness 0.000 1 64 +NoteOn 0.001 1 93 88.899998 +NoteOff 0.100 1 93 63.500000 +NoteOn 0.001 1 91 88.899998 +NoteOff 0.100 1 91 63.500000 +NoteOn 0.001 1 89 88.899998 +NoteOff 0.100 1 89 63.500000 +NoteOn 0.001 1 88 88.899998 +NoteOff 0.100 1 88 63.500000 +NoteOn 0.001 1 86 88.899998 +NoteOff 0.100 1 86 63.500000 +NoteOn 0.001 1 84 88.899998 +NoteOff 0.100 1 84 63.500000 +NoteOn 0.001 1 83 88.899998 +NoteOff 0.100 1 83 63.500000 +NoteOn 0.001 1 79 88.899998 +NoteOff 0.100 1 79 63.500000 + +NoteOn 0.001 1 48 88.899998 +NoteOff 0.100 1 48 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 67 88.899998 +NoteOff 0.100 1 67 63.500000 +NoteOn 0.001 1 76 88.899998 +NoteOff 0.100 1 76 63.500000 +NoteOn 0.001 1 72 88.899998 +NoteOff 0.100 1 72 63.500000 +NoteOn 0.001 1 55 88.899998 +NoteOff 0.100 1 55 63.500000 +NoteOn 0.001 1 91 88.899998 +NoteOff 0.200 1 91 63.500000 + +NoteOn 0.001 1 84 10.0 +NoteOff 0.050 1 84 63.500000 +NoteOn 0.001 1 96 20.0 +NoteOff 0.040 1 96 63.500000 +NoteOn 0.001 1 84 30.0 +NoteOff 0.040 1 84 63.500000 +NoteOn 0.001 1 96 40.0 +NoteOff 0.045 1 96 63.500000 +NoteOn 0.001 1 84 50.0 +NoteOff 0.050 1 84 63.500000 +NoteOn 0.001 1 96 60.0 +NoteOff 0.055 1 96 63.500000 +NoteOn 0.001 1 84 70.0 +NoteOff 0.045 1 84 63.500000 +NoteOn 0.001 1 96 80.0 +NoteOff 0.040 1 96 63.500000 +NoteOn 0.001 1 84 90.0 +NoteOff 0.045 1 84 63.500000 +NoteOn 0.001 1 96 100.0 +NoteOff 0.050 1 96 63.500000 +NoteOn 0.001 1 84 110.0 +NoteOff 0.055 1 84 63.500000 +NoteOn 0.001 1 96 120.0 +NoteOff 0.300 1 96 63.500000 + +StickHardness 0.000 1 64 +NoteOn 0.001 1 48 88.899998 +NoteOff 2.000 1 48 63.500000 diff --git a/scores/marimtst.ski b/scores/marimtst.ski new file mode 100644 index 0000000..4635d93 --- /dev/null +++ b/scores/marimtst.ski @@ -0,0 +1,45 @@ +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +StickHardness 0.000000 1 100 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +StickHardness 0.000000 1 80 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +StickHardness 0.000000 1 60 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +StickHardness 0.000000 1 40 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +StickHardness 0.000000 1 20 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +StickHardness 0.000000 1 10 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 +NoteOn 0.050000 1 32 88.899998 diff --git a/scores/morazbel.ski b/scores/morazbel.ski index c7d9fb3..c46f89a 100644 --- a/scores/morazbel.ski +++ b/scores/morazbel.ski @@ -38,6 +38,48 @@ NoteOn 0.100000 1 52 127.000000 NoteOn 0.200000 1 50 127.000000 NoteOn 0.100000 1 48 127.000000 NoteOn 0.100000 1 50 127.000000 -NoteOn 0.100000 1 32 127.000000 -NoteOn 0.100000 1 36 127.000000 -NoteOff 0.800000 1 36 63.500000 +NoteOn 0.100000 1 69 127.000000 +NoteOn 0.100000 1 72 127.000000 + +NoteOn 0.200000 1 82 127.000000 +NoteOn 0.200000 1 82 127.000000 +NoteOn 0.200000 1 90 100.000000 +NoteOn 0.200000 1 90 100.000000 +NoteOn 0.200000 1 82 110.000000 +NoteOn 0.300000 1 82 110.000000 +NoteOn 0.200000 1 82 100.000000 +NoteOn 0.100000 1 90 100.000000 +NoteOn 0.200000 1 82 100.000000 +NoteOn 0.200000 1 82 90.000000 +NoteOn 0.200000 1 90 80.000000 +NoteOn 0.200000 1 90 80.000000 +NoteOn 0.200000 1 82 80.000000 +NoteOn 0.300000 1 90 80.000000 +NoteOn 0.200000 1 90 80.000000 +NoteOn 0.100000 1 90 70.000000 +NoteOn 0.200000 1 82 70.000000 +NoteOn 0.200000 1 82 70.000000 +NoteOn 0.200000 1 90 70.000000 +NoteOn 0.200000 1 90 70.000000 +NoteOn 0.200000 1 82 60.000000 +NoteOn 0.300000 1 90 60.000000 +NoteOn 0.200000 1 82 60.000000 +NoteOn 0.100000 1 90 60.000000 +NoteOn 0.200000 1 82 50.000000 +NoteOn 0.200000 1 82 50.000000 +NoteOn 0.200000 1 90 50.000000 +NoteOn 0.200000 1 90 50.000000 +NoteOn 0.200000 1 82 50.000000 +NoteOn 0.300000 1 82 40.000000 +NoteOn 0.200000 1 82 40.000000 +NoteOn 0.100000 1 90 40.000000 +NoteOn 0.200000 1 82 40.000000 +NoteOn 0.200000 1 82 30.000000 +NoteOn 0.200000 1 90 30.000000 +NoteOn 0.200000 1 90 30.000000 +NoteOn 0.200000 1 82 20.000000 +NoteOn 0.300000 1 82 20.000000 +NoteOn 0.200000 1 82 20.000000 +NoteOn 0.100000 1 90 10.000000 + +NoteOff 0.800000 1 72 63.500000 diff --git a/scores/pickdamp.ski b/scores/pickdamp.ski new file mode 100644 index 0000000..d2bd7f6 --- /dev/null +++ b/scores/pickdamp.ski @@ -0,0 +1,65 @@ +/* Howdy!!!! SKINI0.9 Test Score ***********/ + +PickPosition 0.0 2 64.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 56.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 48.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 40.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 32.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 24.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 16.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +PickPosition 0.0 2 8.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 1.25 2 55.0 64.0 + +PickPosition 0.0 2 64.0 +BodySize 0.0 2 0.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 16.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 32.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 48.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 60.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 80.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 96.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 127.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 0.25 2 55.0 64.0 +BodySize 0.0 2 64.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 1.25 2 55.0 64.0 + +StringDamping 0.0 2 0.0 +PickPosition 0.0 2 64.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 1.25 2 55.0 64.0 + +StringDamping 0.0 2 128.0 +NoteOn 0.0 2 55.0 64.0 +NoteOff 1.25 2 55.0 64.0 + diff --git a/scores/scales.ski b/scores/scales.ski new file mode 100644 index 0000000..f62af56 --- /dev/null +++ b/scores/scales.ski @@ -0,0 +1,72 @@ +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +PlayerSkill 0.0 2 100 +NoteOn 0.0 2 67 64 +NoteOff 0.5 2 67 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 74 64 +NoteOff 0.5 2 74 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +PlayerSkill 0.0 2 10 +NoteOn 0.0 2 67 64 +NoteOff 0.5 2 67 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 74 64 +NoteOff 0.5 2 74 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +Strumming 0.0 2 127 +PlayerSkill 0.0 2 127 +NoteOn 0.0 2 67 64 +NoteOff 0.5 2 67 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 74 64 +NoteOff 0.5 2 74 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +PlayerSkill 0.0 2 0 +NoteOn 0.0 2 67 64 +NoteOff 0.5 2 67 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 74 64 +NoteOff 0.5 2 74 0 +NoteOn 0.0 2 72 64 +NoteOff 0.5 2 72 0 +NoteOn 0.0 2 71 64 +NoteOff 0.5 2 71 0 +NoteOn 0.0 2 69 64 +NoteOff 0.5 2 69 0 +NoteOn 0.0 2 67 64 +NoteOff 2.0 2 67 0 diff --git a/scores/shaktest.ski b/scores/shaktest.ski new file mode 100644 index 0000000..efc967b --- /dev/null +++ b/scores/shaktest.ski @@ -0,0 +1,64 @@ +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ + +Maraca 0.000000 1 +NoteOn 0.500000 1 80 10.000000 +NoteOn 0.500000 1 80 50.000000 +NoteOn 0.500000 1 80 90.000000 +NoteOn 0.500000 1 80 127.000000 + +ControlChange 0.500000 1 1 1 +NoteOn 0.000000 1 80 64.000000 +ControlChange 0.500000 1 1 40 +NoteOn 0.000000 1 80 64.000000 +ControlChange 0.500000 1 1 80 +NoteOn 0.000000 1 80 64.000000 +ControlChange 0.500000 1 1 120 +NoteOn 0.000000 1 80 64.000000 + +Maraca 0.500000 1 +ControlChange 0.000000 1 4 1 +NoteOn 0.000000 1 80 64.000000 +ControlChange 0.500000 1 4 40 +NoteOn 0.000000 1 80 64.000000 +ControlChange 0.500000 1 4 80 +NoteOn 0.000000 1 80 64.000000 +ControlChange 0.500000 1 4 120 +NoteOn 0.000000 1 80 64.000000 + +Maraca 0.500000 1 +ControlChange 0.000000 1 11 1 +NoteOn 0.000000 1 80 64.000000 +ControlChange 1.000000 1 11 4 +NoteOn 0.000000 1 80 64.000000 +ControlChange 1.000000 1 11 16 +NoteOn 0.000000 1 80 64.000000 +ControlChange 1.000000 1 11 64 +NoteOn 0.000000 1 80 64.000000 +ControlChange 1.000000 1 11 128 +NoteOn 0.000000 1 80 64.000000 + +Cabasa 0.500000 1 +NoteOn 0.000000 1 80 10.000000 +NoteOn 0.500000 1 80 50.000000 +NoteOn 0.500000 1 80 90.000000 +NoteOn 0.500000 1 80 127.000000 + +Sekere 0.500000 1 +NoteOn 0.000000 1 80 10.000000 +NoteOn 0.500000 1 80 50.000000 +NoteOn 0.500000 1 80 90.000000 +NoteOn 0.500000 1 80 127.000000 + +Tambourn 0.500000 1 +NoteOn 0.000000 1 80 10.000000 +NoteOn 0.500000 1 80 50.000000 +NoteOn 0.500000 1 80 90.000000 +NoteOn 0.500000 1 80 127.000000 + +Sleighbl 0.500000 1 +NoteOn 0.000000 1 80 10.000000 +NoteOn 0.500000 1 80 50.000000 +NoteOn 0.500000 1 80 90.000000 +NoteOn 0.500000 1 80 127.000000 + +Exit diff --git a/scores/spain0.ski b/scores/spain0.ski new file mode 100644 index 0000000..462e3b7 --- /dev/null +++ b/scores/spain0.ski @@ -0,0 +1,32 @@ +/* Howdy!! ToolKit96cpp SKINI File, Perry Cook */ +NoteOn 0.000000 1 72 88.899998 +NoteOn 0.300000 1 70 63.500000 +NoteOn 0.300000 1 72 101.600002 +ControlChange 0.500000 1 1 127.000000 +NoteOn 0.700000 1 41 100.0000 +ControlChange 1.000000 1 1 0.000000 +NoteOn 0.000000 1 48 88.899998 +NoteOn 0.200000 1 49 63.500000 +NoteOn 0.200000 1 51 101.600002 +NoteOn 0.300000 1 53 101.600002 +NoteOn 0.100000 1 51 101.600002 +NoteOn 0.900000 1 49 63.500000 +NoteOn 0.200000 1 48 60.000000 +NoteOn 0.200000 1 61 60.000000 +NoteOn 0.150000 1 63 70.000000 +NoteOn 0.100000 1 61 80.000000 +NoteOn 0.100000 1 60 90.000000 +ControlChange 0.000000 1 2 120.0000 +NoteOn 0.200000 1 61 100.000000 +NoteOn 0.300000 1 63 90.000000 +NoteOn 0.200000 1 61 80.000000 +NoteOn 0.300000 1 60 60.000000 +NoteOn 0.300000 1 65 60.000000 +NoteOn 0.400000 1 68 60.000000 +NoteOn 0.500000 1 72 60.000000 +ControlChange 0.000000 1 2 90.0000 +NoteOn 0.600000 1 89 60.000000 +ControlChange 0.000000 1 2 20.0000 +ControlChange 0.500000 1 1 127.000000 +NoteOff 0.400000 1 89 60.000000 +Exit diff --git a/sgio.C b/sgio.C deleted file mode 100644 index 7c0e0a8..0000000 --- a/sgio.C +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include -#include -#include -#define ABS(x) ((x < 0) ? (-x) : (x)) -#define MAX(A,B) ( (A) > (B) ? (A) : (B) ) - -/* - This version of soundio.c is specific for use on an SGI machine. - - -Doug Scott, 10/95 -*/ - -ALconfig audio_port_config; -ALport audio_port; -long bufsize; -int lookaheadbuffers = 8; // number of lookahead buffers -short peakl, peakr; - -int -init_sound(float sr,int chans) - -{ - long pvbuf[2]; - int nbuf; - audio_port_config = ALnewconfig(); - if(ALsetchannels(audio_port_config, chans) < 0) - exit(-1); - /* make output queue twice the size of our buffer */ - nbuf = (chans == 2) ? lookaheadbuffers : lookaheadbuffers/2; - if(ALsetqueuesize(audio_port_config, bufsize=BUFFER_SIZE * nbuf) < 0) - exit(-1); - if(audio_port) ALcloseport(audio_port); - audio_port = ALopenport("sgi.driver", "w", audio_port_config); - if(!audio_port) exit(-1); - ALfreeconfig(audio_port_config); - audio_port_config = 0; - - pvbuf[0] = AL_OUTPUT_RATE; - pvbuf[1] = (long) sr; - ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2); /* set output SR */ - /* tell port to accept refill at buffers - 1 */ - ALsetfillpoint(audio_port,BUFFER_SIZE * (lookaheadbuffers - 1)); - return(0); -} - -int -playbuf(short *buf,int bufsize) -{ - ALwritesamps(audio_port, buf, bufsize); - return(0); -} - -void shuddup() -{ - if(audio_port) ALcloseport(audio_port); - audio_port=0; -} diff --git a/swapstuf.cpp b/swapstuf.cpp new file mode 100644 index 0000000..5495132 --- /dev/null +++ b/swapstuf.cpp @@ -0,0 +1,29 @@ +int SwapInt (int inf) +{ + int o; + unsigned char *inp,*outp; + inp=(unsigned char *)&inf; + outp=(unsigned char *)&o; + outp[0]=inp[3]; outp[1]=inp[2]; outp[2]=inp[1]; outp[3]=inp[0]; + return(o); +} + +short SwapShort (short inf) +{ + short o; + unsigned char *inp,*outp; + inp=(unsigned char *)&inf; + outp=(unsigned char *)&o; + outp[0]=inp[1]; outp[1]=inp[0]; + return(o); +} + +float SwapFloat (float inf) +{ + float o; + unsigned char *inp,*outp; + inp=(unsigned char *)&inf; + outp=(unsigned char *)&o; + outp[0]=inp[3]; outp[1]=inp[2]; outp[2]=inp[1]; outp[3]=inp[0]; + return(o); +} diff --git a/swapstuf.h b/swapstuf.h new file mode 100644 index 0000000..c32380d --- /dev/null +++ b/swapstuf.h @@ -0,0 +1,3 @@ +int SwapInt(int inf); +short SwapShort(short inf); +float SwapFloat(float inf); diff --git a/syntmono.cpp b/syntmono.cpp new file mode 100644 index 0000000..1078d89 --- /dev/null +++ b/syntmono.cpp @@ -0,0 +1,600 @@ +/************** Test Main Program Individual Voice *********************/ + +#include "miditabl.h" +#include "WvOut.h" +#include "SndWvOut.h" +#include "WavWvOut.h" +#include "MatWvOut.h" +#ifndef __NeXT_ +#include "RTWvOut.h" +#endif +#include "SKINI11.h" +#include "Instrmnt.h" +#include "Marimba.h" +#include "Vibraphn.h" +#include "AgogoBel.h" +#include "Plucked.h" +#include "Mandolin.h" +#include "Clarinet.h" +#include "Flute.h" +#include "Brass.h" +#include "Bowed.h" +#include "Rhodey.h" +#include "Wurley.h" +#include "TubeBell.h" +#include "HeavyMtl.h" +#include "PercFlut.h" +#include "BeeThree.h" +#include "FMVoices.h" +#include "VoicForm.h" +#include "Moog1.h" +#include "Simple.h" +#include "DrumSynt.h" +#include "Shakers.h" +#include "Reverb.h" +#include "NRev.h" +#include "PRCRev.h" +#include "JCRev.h" + +#define NUM_INSTS 30 + +char insts[NUM_INSTS][10] = { "Marimba", "Vibraphn", "AgogoBel", "Plucked", + "Mandolin", "Clarinet", "Flute", "Brass", + "Bowed", "Rhodey", "Wurley", "TubeBell", + "HeavyMtl", "PercFlut", "BeeThree", "FMVoices", + "Moog1", "Simple", "VoicForm", "TKSinger", + "Shakers", "Maraca", "Cabasa", "Sekere", + "Guiro", "Waterdrp", "Bamboo", "Tambourn", + "Sleighbl", "DrumSynt"}; + +#include "SKINI11.msg" + +#define INSTR_LEN 60 + +int numStrings = 0; +int notDone = 1; + +#if defined(__SGI_REALTIME_) + +#include +#include +#include + +char inputString[MAX_IN_STRINGS][INSTR_LEN]; +pid_t string_thread; + +void newString(void *) +{ + int inOne = 0; + while (notDone) { + fgets(inputString[inOne],128,stdin); + if (inputString[inOne][0] == 'E' && inputString[inOne][1] == 'x') { + notDone = 0; + } + else { + numStrings++; + if (numStrings > MAX_IN_STRINGS) { + fprintf(stderr,"Losing MIDI data ... try increasing MAX_IN_STRINGS.\n"); + numStrings--; + } + inOne++; + if (inOne == MAX_IN_STRINGS) inOne = 0; + } + } +} + +#elif defined(__USS_REALTIME_) + +#include + +char inputString[MAX_IN_STRINGS][INSTR_LEN]; +pthread_t string_thread; + +void *newString(void *) +{ + int inOne = 0; + while (notDone) { + fgets(inputString[inOne],128,stdin); + if (inputString[inOne][0] == 'E' && inputString[inOne][1] == 'x') { + notDone = 0; + } + else { + numStrings++; + if (numStrings > MAX_IN_STRINGS) { + fprintf(stderr,"Losing MIDI data ... try increasing MAX_IN_STRINGS.\n"); + numStrings--; + } + inOne++; + if (inOne == MAX_IN_STRINGS) inOne = 0; + } + } +} + +#elif (defined(__WINDS_REALTIME_) || defined(__WINMM_REALTIME_) ) + +#include +#include + +char inputString[MAX_IN_STRINGS][INSTR_LEN]; +unsigned long string_thread; + +#define SERVICE_PORT 2001 + +void newString(void *) +{ + int inOne = 0, i=0, m=0, n; + SOCKET soc_id, accept_id; + WSADATA wsaData; + int nRet; + struct sockaddr_in sockname; + WORD wVersionRequested = MAKEWORD(1,1); + char socBuf[INSTR_LEN]; + + nRet = WSAStartup(wVersionRequested, &wsaData); + if (wsaData.wVersion != wVersionRequested) + { + fprintf(stderr,"\n Wrong version\n"); + exit(0); + } + + /* Create the server-side socket */ + soc_id = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); + if(soc_id == INVALID_SOCKET) { + fprintf(stderr,"Couldn't create socket!\n"); + exit(0); + } + + sockname.sin_family=AF_INET; + sockname.sin_addr.s_addr=INADDR_ANY; + sockname.sin_port=htons(SERVICE_PORT); + + /* Bind socket to the appropriate port and interface (INADDR_ANY) */ + if (bind(soc_id,(LPSOCKADDR)&sockname,sizeof(sockname))==SOCKET_ERROR) { + fprintf(stderr,"Couldn't bind socket!\n"); + exit(0); + } + + /* Listen for incoming connections */ + printf("Listening for socket on port %d\n", SERVICE_PORT); + if (listen(soc_id,1)==SOCKET_ERROR) { + fprintf(stderr,"Couldn't set up listen on socket!\n"); + exit(0); + } + + /* Accept and service one incoming connection request */ + accept_id=accept(soc_id,NULL,NULL); + if (accept_id==INVALID_SOCKET) { + fprintf(stderr,"Couldn't accept incoming connection on socket!\n"); + exit(0); + } + + memset(socBuf, 0, sizeof(socBuf)); + + printf("Socket connection made ... ready to receive SKINI messages.\n"); + while (notDone) { + i = recv(accept_id, socBuf, INSTR_LEN, 0); + if (i==0) notDone = 0; + n = 0; + while (n < i) { + inputString[inOne][m++] = socBuf[n]; + if (socBuf[n++] == '\n') { + if (inputString[inOne][0] == 'E' && inputString[inOne][1] == 'x') { + notDone = 0; + n = i; + } + else { + m = 0; + numStrings++; + if (numStrings > MAX_IN_STRINGS) { + fprintf(stderr,"Losing MIDI data ... try increasing MAX_IN_STRINGS.\n"); + numStrings--; + } + inOne++; + if (inOne == MAX_IN_STRINGS) inOne = 0; + } + memset(inputString[inOne], 0, INSTR_LEN); + } + } + } + closesocket(accept_id); + closesocket(soc_id); + WSACleanup(); + printf("Socket connection closed.\n"); +} + +#else +char inputString[1][INSTR_LEN]; +#endif + +/* Error function in case of incorrect command-line argument specifications */ +void errorf(char *func) { + int i,j; + + printf("\nuseage: %s Instr flag(s) \n",func); + printf(" where flag = -s for .snd output file,\n"); + printf(" -w for .wav output file,\n"); + printf(" -m for .mat output file,\n"); +#if !defined(__NeXT_) + printf(" -r for realtime output,\n"); + printf(" -i for realtime input (versus scorefile),\n"); +#endif + printf(" and Instr = one of these:\n"); + for (i=0;i are not specified,\n"); + printf("default names will be indicated. Each flag must\n"); + printf("include its own '-' sign.\n\n"); + exit(0); +} + +void main(int argc,char *argv[]) +{ + long i, j, w, synlength; + int type, rtInput = 0; + int numOuts = 0, outOne = 0; + char *fin; + char flags[15]; + MY_FLOAT reverbTime = 0.5; /* in seconds */ + MY_FLOAT temp, byte3, lastPitch, outSample; + char fileName[256]; + WvOut **output; + Instrmnt *instrument; + Reverb *reverb; + SKINI11 *score; + + /* Check the command-line arguments for errors and to determine + * the number of WvOut objects to be instantiated. + */ + if (argc > 2 && argc < 11) { + i = 2; + j = 0; + while (i < argc) { + if (argv[i][0] == '-') { + if ( (argv[i][1] == 'r') || (argv[i][1] == 's') || + (argv[i][1] == 'w') || (argv[i][1] == 'm') ) + numOuts++; + else if (argv[i][1] != 'i') errorf(argv[0]); + flags[j] = argv[i][1]; + j++; + } + i++; + } + /* Check for multiple flags of the same type */ + for (i=0; i<=j; i++) { + w = i+1; + while (w <= j) { + if (flags[i] == flags[w]) { + printf("\nError: Multiple command line flags of the same type specified.\n\n"); + errorf(argv[0]); + } + w++; + } + } + /* Check number of outputs */ + if (numOuts > 0) output = (WvOut **) malloc(numOuts * sizeof(WvOut *)); + else errorf(argv[0]); + } + else errorf(argv[0]); + + /* Parse the command-line flags and instantiate WvOut objects. */ + i = 2; + j = 0; + while (i < argc) + { + if (argv[i][0] == '-') + { + switch(argv[i][1]) + { + case 'i': +#if !defined(__NeXT_) + rtInput = 1; + break; +#else + errorf(argv[0]); +#endif + + case 'r': +#if !defined(__NeXT_) + output[j] = new RTWvOut(); + j++; + break; +#else + errorf(argv[0]); +#endif + + case 'w': + if ((i+1 < argc) && argv[i+1][0] != '-') + strcpy(fileName,argv[i+1]); + else strcpy(fileName,"testwav"); + output[j] = new WavWvOut(2,fileName); + j++; + break; + + case 's': + if ((i+1 < argc) && argv[i+1][0] != '-') + strcpy(fileName,argv[i+1]); + else strcpy(fileName,"testsnd"); + output[j] = new SndWvOut(2,fileName); + j++; + break; + + case 'm': + if ((i+1 < argc) && argv[i+1][0] != '-') + strcpy(fileName,argv[i+1]); + else strcpy(fileName,"testmat"); + output[j] = new MatWvOut(2,fileName); + j++; + break; + + default: + errorf(argv[0]); + break; + } + } + i++; + } + + /* Parse the Instrument command-line argument. */ + if (!strcmp(argv[1],"Simple")) instrument = new Simple; + else if (!strcmp(argv[1],"Clarinet")) instrument = new Clarinet(50.0); + else if (!strcmp(argv[1],"Flute")) instrument = new Flute(50.0); + else if (!strcmp(argv[1],"Brass")) instrument = new Brass(50.0); + else if (!strcmp(argv[1],"Bowed")) instrument = new Bowed(50.0); + else if (!strcmp(argv[1],"Plucked")) instrument = new Plucked(50.0); + else if (!strcmp(argv[1],"Mandolin")) instrument = new Mandolin(50.0); + else if (!strcmp(argv[1],"Marimba")) instrument = new Marimba; + else if (!strcmp(argv[1],"Vibraphn")) instrument = new Vibraphn; + else if (!strcmp(argv[1],"AgogoBel")) instrument = new AgogoBel; + else if (!strcmp(argv[1],"Rhodey")) instrument = new Rhodey; + else if (!strcmp(argv[1],"Wurley")) instrument = new Wurley; + else if (!strcmp(argv[1],"TubeBell")) instrument = new TubeBell; + else if (!strcmp(argv[1],"HeavyMtl")) instrument = new HeavyMtl; + else if (!strcmp(argv[1],"PercFlut")) instrument = new PercFlut; + else if (!strcmp(argv[1],"BeeThree")) instrument = new BeeThree; + else if (!strcmp(argv[1],"Moog1")) instrument = new Moog1; + else if (!strcmp(argv[1],"FMVoices")) instrument = new FMVoices; + else if (!strcmp(argv[1],"VoicForm")) instrument = new VoicForm; + else if (!strcmp(argv[1],"DrumSynt")) instrument = new DrumSynt; + else if (!strcmp("Shakers",argv[1])) { + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 0); + } + else if (!strcmp("Maraca",argv[1])) { + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 0); + } + else if (!strcmp("Sekere",argv[1])) { + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 1); + } + else if (!strcmp("Cabasa",argv[1])) { + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 2); + } + else if (!strcmp("Bamboo",argv[1])) { + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 3); + } + else if (!strcmp("Waterdrp",argv[1])) { + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 4); + } + else if (!strcmp("Tambourn",argv[1])) { + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 5); + } + else if (!strcmp("Sleighbl",argv[1])) { + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 6); + } + else if (!strcmp("Guiro",argv[1])) { + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 7); + } + else { + errorf(argv[0]); + } + + score = new SKINI11(); + reverb = new PRCRev(reverbTime); + reverb->setEffectMix(0.2); + + /* If using realtime input, setup the input thread. */ +#if defined(__SGI_REALTIME_) + if (rtInput) { + string_thread = sproc(newString, PR_SALL); + if (string_thread == -1) { + fprintf(stderr, "unable to create input thread...aborting.\n"); + exit(-1); + } + instrument->noteOn(200.0,0.1); + } +#elif defined(__USS_REALTIME_) + if (rtInput) { + if (pthread_create(&string_thread, NULL, newString, NULL)) + { + fprintf(stderr, "unable to create input thread...aborting.\n"); + exit(-1); + } + instrument->noteOn(200.0,0.1); + } +#elif (defined(__WINDS_REALTIME_) || defined(__WINMM_REALTIME_) ) + if (rtInput) { + string_thread = _beginthread(newString, 0, NULL); + if (string_thread == -1) { + fprintf(stderr, "Unable to create exit thread.\n"); + printf("Exiting MD2SKINI process.\n"); + exit(0); + } + instrument->noteOn(200.0,0.1); + } +#endif + + /* Finally ... the runtime loop begins! */ + notDone = 1; + while(notDone || numStrings) { + if (rtInput) { + synlength = RT_BUFFER_SIZE; + for ( i=0; i 1) { + outSample = reverb->tick(instrument->tick()); + for ( j=0; jtick(outSample); + } + else output[0]->tick(reverb->tick(instrument->tick())); + } + } + else { + fin = fgets(inputString[0],INSTR_LEN,stdin); + if (fin == NULL) notDone = 0; + else { + numStrings++; + } + } + while (numStrings) { + score->parseThis(inputString[outOne]); + type = score->getType(); + if (type > 0) { + synlength = (long) (score->getDelta() * SRATE); +#if defined(_debug_) + if (!rtInput) printf("Time = %f: ",output.getTime()); +#endif + for ( i=0; i 1) { + outSample = reverb->tick(instrument->tick()); + for ( j=0; jtick(outSample); + } + else output[0]->tick(reverb->tick(instrument->tick())); + } + synlength = 0; + if (type == __SK_NoteOn_ ) { + if (( byte3 = score->getByteThree() ) == 0) + instrument->noteOff(byte3*NORM_7); + else { + j = (int) score->getByteTwo(); + temp = __MIDI_To_Pitch[j]; + lastPitch = temp; + instrument->noteOn(temp,byte3*NORM_7); + } + } + else if (type == __SK_NoteOff_) { + byte3 = score->getByteThree(); + instrument->noteOff(byte3*NORM_7); + } + else if (type == __SK_ControlChange_) { + j = (int) score->getByteTwo(); + byte3 = score->getByteThree(); + instrument->controlChange(j,byte3); + } + else if (type == __SK_AfterTouch_) { + j = (int) score->getByteTwo(); + instrument->controlChange(128,j); + } + else if (type == __SK_PitchBend_) { + temp = score->getByteTwo(); + j = (int) temp; + temp -= j; + lastPitch = __MIDI_To_Pitch[j] * pow(2.0,temp / 12.0) ; + instrument->setFreq(lastPitch); + } + else if (type == __SK_ProgramChange_) { + instrument->noteOff(1.0); + for (i=0;i<4096;i++) { + if (numOuts > 1) { + outSample = reverb->tick(instrument->tick()); + for ( j=0; jtick(outSample); + } + else output[0]->tick(reverb->tick(instrument->tick())); + } + delete instrument; + j = (int) score->getByteTwo(); + if (j==0) instrument = new Clarinet(50.0); + else if (j==1) instrument = new Flute(50.0); + else if (j==2) instrument = new Brass(50.0); + else if (j==3) instrument = new Bowed(50.0); + + else if (j==4) instrument = new Plucked(50.0); + else if (j==5) instrument = new Mandolin(50.0); + else if (j==6) instrument = new Marimba; + else if (j==7) instrument = new Vibraphn; + else if (j==8) instrument = new AgogoBel; + else if (j==9) instrument = new Rhodey; + else if (j==10) instrument = new Wurley; + else if (j==11) instrument = new TubeBell; + + else if (j==12) instrument = new HeavyMtl; + else if (j==13) instrument = new PercFlut; + else if (j==14) instrument = new BeeThree; + else if (j==15) instrument = new Moog1; + + else if (j==16) instrument = new FMVoices; + else if (j==17) instrument = new VoicForm; + + else if (j==18) instrument = new DrumSynt; + + else if (j==19) { /* "Maraca" */ + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 0); + } + else if (j==20) { /* "Sekere" */ + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 1); + } + else if (j==21) { /* "Cabasa" */ + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 2); + } + else if (j==22) { /* "Bamboo" */ + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 3); + } + else if (j==23) { /* "Waterdrp" */ + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 4); + } + else if (j==24) { /* "Tambourn" */ + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 5); + } + else if (j==25) { /* "Sleighbl" */ + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 6); + } + else if (j==26) { /* "Guiro" */ + instrument = new Shakers; + instrument->controlChange(__SK_ShakerInst_, 7); + } + instrument->noteOn(lastPitch, 0.5); + } + } + if (rtInput) { + outOne += 1; + if (outOne == MAX_IN_STRINGS) outOne = 0; + } + numStrings--; + } + } + for (i=0;i<2*reverbTime*SRATE;i++) { /* let the reverb settle a little */ + if (numOuts > 1) { + outSample = reverb->tick(instrument->tick()); + for ( j=0; jtick(outSample); + } + else output[0]->tick(reverb->tick(instrument->tick())); + } + + for ( i=0; i +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=syntmono - 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 "syntmono.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 "syntmono.mak" CFG="syntmono - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "syntmono - Win32 Release" (based on\ + "Win32 (x86) Console Application") +!MESSAGE "syntmono - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "syntmono - 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 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /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 winmm.lib dsound.lib Wsock32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "syntmono - 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 /MT /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /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 winmm.lib dsound.lib Wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "syntmono - Win32 Release" +# Name "syntmono - Win32 Debug" +# Begin Source File + +SOURCE=.\ADSR.cpp +# End Source File +# Begin Source File + +SOURCE=.\ADSR.h +# End Source File +# Begin Source File + +SOURCE=.\AgogoBel.cpp +# End Source File +# Begin Source File + +SOURCE=.\AgogoBel.h +# End Source File +# Begin Source File + +SOURCE=.\BeeThree.cpp +# End Source File +# Begin Source File + +SOURCE=.\BeeThree.h +# End Source File +# Begin Source File + +SOURCE=.\BiQuad.cpp +# End Source File +# Begin Source File + +SOURCE=.\BiQuad.h +# End Source File +# Begin Source File + +SOURCE=.\Bowed.cpp +# End Source File +# Begin Source File + +SOURCE=.\Bowed.h +# End Source File +# Begin Source File + +SOURCE=.\BowTabl.cpp +# End Source File +# Begin Source File + +SOURCE=.\BowTabl.h +# End Source File +# Begin Source File + +SOURCE=.\Brass.cpp +# End Source File +# Begin Source File + +SOURCE=.\Brass.h +# End Source File +# Begin Source File + +SOURCE=.\Clarinet.cpp +# End Source File +# Begin Source File + +SOURCE=.\Clarinet.h +# End Source File +# Begin Source File + +SOURCE=.\DCBlock.cpp +# End Source File +# Begin Source File + +SOURCE=.\DCBlock.h +# End Source File +# Begin Source File + +SOURCE=.\DLineA.cpp +# End Source File +# Begin Source File + +SOURCE=.\DLineA.h +# End Source File +# Begin Source File + +SOURCE=.\DLineL.cpp +# End Source File +# Begin Source File + +SOURCE=.\DLineL.h +# End Source File +# Begin Source File + +SOURCE=.\DLineN.cpp +# End Source File +# Begin Source File + +SOURCE=.\DLineN.h +# End Source File +# Begin Source File + +SOURCE=.\DrumSynt.cpp +# End Source File +# Begin Source File + +SOURCE=.\DrumSynt.h +# End Source File +# Begin Source File + +SOURCE=.\Envelope.cpp +# End Source File +# Begin Source File + +SOURCE=.\Envelope.h +# End Source File +# Begin Source File + +SOURCE=.\Filter.cpp +# End Source File +# Begin Source File + +SOURCE=.\Filter.h +# End Source File +# Begin Source File + +SOURCE=.\Flute.cpp +# End Source File +# Begin Source File + +SOURCE=.\Flute.h +# End Source File +# Begin Source File + +SOURCE=.\FM4Alg3.cpp +# End Source File +# Begin Source File + +SOURCE=.\FM4Alg3.h +# End Source File +# Begin Source File + +SOURCE=.\FM4Alg4.cpp +# End Source File +# Begin Source File + +SOURCE=.\FM4Alg4.h +# End Source File +# Begin Source File + +SOURCE=.\FM4Alg5.cpp +# End Source File +# Begin Source File + +SOURCE=.\FM4Alg5.h +# End Source File +# Begin Source File + +SOURCE=.\FM4Alg6.cpp +# End Source File +# Begin Source File + +SOURCE=.\FM4Alg6.h +# End Source File +# Begin Source File + +SOURCE=.\FM4Alg8.cpp +# End Source File +# Begin Source File + +SOURCE=.\FM4Alg8.h +# End Source File +# Begin Source File + +SOURCE=.\FM4Op.cpp +# End Source File +# Begin Source File + +SOURCE=.\FM4Op.h +# End Source File +# Begin Source File + +SOURCE=.\FMVoices.cpp +# End Source File +# Begin Source File + +SOURCE=.\FMVoices.h +# End Source File +# Begin Source File + +SOURCE=.\FormSwep.cpp +# End Source File +# Begin Source File + +SOURCE=.\FormSwep.h +# End Source File +# Begin Source File + +SOURCE=.\HeavyMtl.cpp +# End Source File +# Begin Source File + +SOURCE=.\HeavyMtl.h +# End Source File +# Begin Source File + +SOURCE=.\Instrmnt.cpp +# End Source File +# Begin Source File + +SOURCE=.\Instrmnt.h +# End Source File +# Begin Source File + +SOURCE=.\JCRev.cpp +# End Source File +# Begin Source File + +SOURCE=.\JCRev.h +# End Source File +# Begin Source File + +SOURCE=.\JetTabl.cpp +# End Source File +# Begin Source File + +SOURCE=.\JetTabl.h +# End Source File +# Begin Source File + +SOURCE=.\LipFilt.cpp +# End Source File +# Begin Source File + +SOURCE=.\LipFilt.h +# End Source File +# Begin Source File + +SOURCE=.\Mandolin.cpp +# End Source File +# Begin Source File + +SOURCE=.\Mandolin.h +# End Source File +# Begin Source File + +SOURCE=.\Mandplyr.cpp +# End Source File +# Begin Source File + +SOURCE=.\Mandplyr.h +# End Source File +# Begin Source File + +SOURCE=.\Marimba.cpp +# End Source File +# Begin Source File + +SOURCE=.\Marimba.h +# End Source File +# Begin Source File + +SOURCE=.\MatWvOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\MatWvOut.h +# End Source File +# Begin Source File + +SOURCE=.\Miditabl.h +# End Source File +# Begin Source File + +SOURCE=.\Modal4.cpp +# End Source File +# Begin Source File + +SOURCE=.\Modal4.h +# End Source File +# Begin Source File + +SOURCE=.\Modulatr.cpp +# End Source File +# Begin Source File + +SOURCE=.\Modulatr.h +# End Source File +# Begin Source File + +SOURCE=.\Moog1.cpp +# End Source File +# Begin Source File + +SOURCE=.\Moog1.h +# End Source File +# Begin Source File + +SOURCE=.\Noise.cpp +# End Source File +# Begin Source File + +SOURCE=.\Noise.h +# End Source File +# Begin Source File + +SOURCE=.\NRev.cpp +# End Source File +# Begin Source File + +SOURCE=.\NRev.h +# End Source File +# Begin Source File + +SOURCE=.\Object.cpp +# End Source File +# Begin Source File + +SOURCE=.\Object.h +# End Source File +# Begin Source File + +SOURCE=.\OnePole.cpp +# End Source File +# Begin Source File + +SOURCE=.\OnePole.h +# End Source File +# Begin Source File + +SOURCE=.\OneZero.cpp +# End Source File +# Begin Source File + +SOURCE=.\OneZero.h +# End Source File +# Begin Source File + +SOURCE=.\PercFlut.cpp +# End Source File +# Begin Source File + +SOURCE=.\PercFlut.h +# End Source File +# Begin Source File + +SOURCE=.\Phontabl.h +# End Source File +# Begin Source File + +SOURCE=.\Plucked.cpp +# End Source File +# Begin Source File + +SOURCE=.\Plucked.h +# End Source File +# Begin Source File + +SOURCE=.\Plucked2.cpp +# End Source File +# Begin Source File + +SOURCE=.\Plucked2.h +# End Source File +# Begin Source File + +SOURCE=.\PRCRev.cpp +# End Source File +# Begin Source File + +SOURCE=.\PRCRev.h +# End Source File +# Begin Source File + +SOURCE=.\RawLoop.cpp +# End Source File +# Begin Source File + +SOURCE=.\RawLoop.h +# End Source File +# Begin Source File + +SOURCE=.\RawWave.cpp +# End Source File +# Begin Source File + +SOURCE=.\RawWave.h +# End Source File +# Begin Source File + +SOURCE=.\RawWvIn.cpp +# End Source File +# Begin Source File + +SOURCE=.\RawWvIn.h +# End Source File +# Begin Source File + +SOURCE=.\ReedTabl.cpp +# End Source File +# Begin Source File + +SOURCE=.\ReedTabl.h +# End Source File +# Begin Source File + +SOURCE=.\Reverb.cpp +# End Source File +# Begin Source File + +SOURCE=.\Reverb.h +# End Source File +# Begin Source File + +SOURCE=.\Rhodey.cpp +# End Source File +# Begin Source File + +SOURCE=.\Rhodey.h +# End Source File +# Begin Source File + +SOURCE=.\RTSoundIO.cpp +# End Source File +# Begin Source File + +SOURCE=.\RTSoundIO.h +# End Source File +# Begin Source File + +SOURCE=.\RTWvOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\RTWvOut.h +# End Source File +# Begin Source File + +SOURCE=.\Sampler.cpp +# End Source File +# Begin Source File + +SOURCE=.\Sampler.h +# End Source File +# Begin Source File + +SOURCE=.\SamplFlt.cpp +# End Source File +# Begin Source File + +SOURCE=.\SamplFlt.h +# End Source File +# Begin Source File + +SOURCE=.\Shakers.cpp +# End Source File +# Begin Source File + +SOURCE=.\Shakers.h +# End Source File +# Begin Source File + +SOURCE=.\Simple.cpp +# End Source File +# Begin Source File + +SOURCE=.\Simple.h +# End Source File +# Begin Source File + +SOURCE=.\SingWave.cpp +# End Source File +# Begin Source File + +SOURCE=.\SingWave.h +# End Source File +# Begin Source File + +SOURCE=.\SKINI11.cpp +# End Source File +# Begin Source File + +SOURCE=.\SKINI11.h +# End Source File +# Begin Source File + +SOURCE=.\SKINI11.msg +# End Source File +# Begin Source File + +SOURCE=.\SKINI11.tbl +# End Source File +# Begin Source File + +SOURCE=.\SndWvOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\SndWvOut.h +# End Source File +# Begin Source File + +SOURCE=.\SubNoise.cpp +# End Source File +# Begin Source File + +SOURCE=.\SubNoise.h +# End Source File +# Begin Source File + +SOURCE=.\Swapstuf.cpp +# End Source File +# Begin Source File + +SOURCE=.\Swapstuf.h +# End Source File +# Begin Source File + +SOURCE=.\Syntmono.cpp +# End Source File +# Begin Source File + +SOURCE=.\TubeBell.cpp +# End Source File +# Begin Source File + +SOURCE=.\TubeBell.h +# End Source File +# Begin Source File + +SOURCE=.\TwoPole.cpp +# End Source File +# Begin Source File + +SOURCE=.\TwoPole.h +# End Source File +# Begin Source File + +SOURCE=.\TwoZero.cpp +# End Source File +# Begin Source File + +SOURCE=.\TwoZero.h +# End Source File +# Begin Source File + +SOURCE=.\Vibraphn.cpp +# End Source File +# Begin Source File + +SOURCE=.\Vibraphn.h +# End Source File +# Begin Source File + +SOURCE=.\VoicForm.cpp +# End Source File +# Begin Source File + +SOURCE=.\VoicForm.h +# End Source File +# Begin Source File + +SOURCE=.\VoicMang.cpp +# End Source File +# Begin Source File + +SOURCE=.\VoicMang.h +# End Source File +# Begin Source File + +SOURCE=.\WavWvOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\WavWvOut.h +# End Source File +# Begin Source File + +SOURCE=.\Wurley.cpp +# End Source File +# Begin Source File + +SOURCE=.\Wurley.h +# End Source File +# Begin Source File + +SOURCE=.\WvOut.cpp +# End Source File +# Begin Source File + +SOURCE=.\WvOut.h +# End Source File +# End Target +# End Project diff --git a/syntmono.plg b/syntmono.plg new file mode 100644 index 0000000..885f5f9 --- /dev/null +++ b/syntmono.plg @@ -0,0 +1,105 @@ +--------------------Configuration: syntmono - Win32 Release-------------------- +Begining build with project "D:\gary\STK98v2\syntmono.dsp", at root. +Active configuration is Win32 (x86) Console Application (based on Win32 (x86) Console Application) + +Project's tools are: + "32-bit C/C++ Compiler for 80x86" with flags "/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"Release/syntmono.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c " + "Win32 Resource Compiler" with flags "/l 0x409 /d "NDEBUG" " + "Browser Database Maker" with flags "/nologo /o"syntmono.bsc" " + "COFF Linker for 80x86" with flags "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib dsound.lib Wsock32.lib /nologo /subsystem:console /incremental:no /pdb:"syntmono.pdb" /machine:I386 /out:"syntmono.exe" " + "Custom Build" with flags "" + "" with flags "" + +Creating temp file "c:\windows\TEMP\RSP8374.TMP" with contents +Creating command line "cl.exe @c:\windows\TEMP\RSP8374.TMP" +Creating temp file "c:\windows\TEMP\RSP8375.TMP" with contents +Creating command line "link.exe @c:\windows\TEMP\RSP8375.TMP" +Compiling... +DrumSynt.cpp +FMVoices.cpp +Noise.cpp +Shakers.cpp +Syntmono.cpp +Linking... + + + +syntmono.exe - 0 error(s), 0 warning(s) diff --git a/testMIDI.cpp b/testMIDI.cpp deleted file mode 100644 index e0f6c60..0000000 --- a/testMIDI.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/************** Test Main Program Individual Voice *********************/ - -#include "miditabl.h" -#include "MIDIInpt.h" - -#define ATOUCHMAX 2 - -int main(int argc,char *argv[]) -{ - long i, j; - int oneOn = 0; - int lastTouch = 0; - int aTouchThin = 0; - MY_FLOAT temp,temp2; - MIDIInpt controller; - - if (argc!=1) { - printf("useage: testMIDI\n"); - exit(0); - } - - while(1) { - if (controller.nextMessage() > 0) { - temp2 = controller.getByteThree(); - temp = controller.getByteTwo(); - if (controller.getType()==9) { - if (temp2 < 1.0) { - if (oneOn == 1) { - printf("NoteOff 0.0 1 %f %f\n",temp,64.0); - } - oneOn -= 1; - } - else { - printf("NoteOn 0.0 1 %f %f\n",temp,temp2); - oneOn += 1; - } - } - else if (controller.getType()==8) { - if (temp2 < 2.0) temp2 = 64.0; - if (oneOn ==1) { - printf("NoteOff 0.0 1 %f %f\n",temp,temp2); - } - oneOn -= 1; - } - else if (controller.getType() == 11) { - j = (int) temp; - printf("ControlChange 0.0 1 %i %f\n",j,temp2); - } - else if (controller.getType() == 13) { -// aTouchThin += 1; -// if (aTouchThin == ATOUCHMAX) { -// temp2 = fabs(temp - lastTouch); -// if (temp2 > 10) { -// printf("AfterTouch 0.0 1 %f\n",temp); -// lastTouch = temp; -// } -// aTouchThin = 0; -// } - } - else if (controller.getType() == 12) { - j = (int) temp; - printf("ProgramChange 0.0 1 %i\n",j); - } - fflush(stdout); - } - } - - -} - - diff --git a/testMono.cpp b/testMono.cpp deleted file mode 100644 index c6f6c52..0000000 --- a/testMono.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/************** Test Main Program Individual Voice *********************/ - -#include "miditabl.h" -#include "RawWvOut.h" -#include "MIDIText.h" -#include "Instrmnt.h" -#include "Marimba.h" -#include "Vibraphn.h" -#include "AgogoBel.h" -#include "Plucked.h" -#include "Mandolin.h" -#include "Clarinet.h" -#include "Flute.h" -#include "Brass.h" -#include "Bowed.h" -#include "Rhodey.h" -#include "Wurley.h" -#include "TubeBell.h" -#include "HeavyMtl.h" -#include "PercFlut.h" -#include "BeeThree.h" -#include "FMVoices.h" -#include "VoicForm.h" -#include "Moog1.h" -#include "Reverb.h" - -int main(int argc,char *argv[]) -{ - long i, j; - MY_FLOAT temp,temp2; - Instrmnt *instrument; - RawWvOut output("test.snd"); - Reverb reverb(2137); - MIDIText *score; - - if (argc<3) { - printf("useage: testMono Instr file.mtx\n"); - printf(" where Instr = Marimba Vibraphn AgogoBel Plucked\n"); - printf(" Mandolin Clarinet Flute Brass Bowed \n"); - printf(" Rhodey Wurley TubeBell HeavyMtl\n"); - printf(" PercFlut BeeThree FMVoices Moog1 VoicForm\n"); - exit(0); - } - if (!strcmp(argv[1],"Marimba")) instrument = new Marimba; - else if (!strcmp(argv[1],"Vibraphn")) instrument = new Vibraphn; - else if (!strcmp(argv[1],"AgogoBel")) instrument = new AgogoBel; - else if (!strcmp(argv[1],"Plucked")) instrument = new Plucked(50.0); - else if (!strcmp(argv[1],"Mandolin")) instrument = new Mandolin(50.0); - else if (!strcmp(argv[1],"Clarinet")) instrument = new Clarinet(50.0); - else if (!strcmp(argv[1],"Flute")) instrument = new Flute(50.0); - else if (!strcmp(argv[1],"Brass")) instrument = new Brass(50.0); - else if (!strcmp(argv[1],"Bowed")) instrument = new Bowed(50.0); - else if (!strcmp(argv[1],"Rhodey")) instrument = new Rhodey; - else if (!strcmp(argv[1],"Wurley")) instrument = new Wurley; - else if (!strcmp(argv[1],"TubeBell")) instrument = new TubeBell; - else if (!strcmp(argv[1],"HeavyMtl")) instrument = new HeavyMtl; - else if (!strcmp(argv[1],"PercFlut")) instrument = new PercFlut; - else if (!strcmp(argv[1],"BeeThree")) instrument = new BeeThree; - else if (!strcmp(argv[1],"FMVoices")) instrument = new FMVoices; - else if (!strcmp(argv[1],"VoicForm")) instrument = new VoicForm; - else if (!strcmp(argv[1],"Moog1")) instrument = new Moog1; - else { - printf("Instrument type must be 1 of:\n"); - printf("Marimba Vibraphn AgogoBel Plucked Mandolin\n"); - printf("Clarinet Flute Brass Bowed Rhodey Wurley TubeBell\n"); - printf("HeavyMtl PercFlut BeeThree FMVoices Moog1 VoicForm\n"); - exit(0); - } - score = new MIDIText(argv[2]); - - reverb.setEffectMix(0.2); - while(score->getType() > 0) { - j = (long) (score->getDelta() * SRATE); -#if defined(_debug_) - printf("%i\n",j); -#endif - if (j > 0) { - for (i=0;itick())); - } - } - temp2 = score->getByteThree()*NORM_7; - if (score->getType()==9) { - if (score->getByteThree() == 0) - instrument->noteOff(temp2); - else { - j = (int) score->getByteTwo(); - temp = __MIDI_To_Pitch[j]; - instrument->noteOn(temp,temp2); - } - } - else if (score->getType() == 8) { - instrument->noteOff(temp2); - } - else if (score->getType() == 11) { - j = (int) score->getByteTwo(); - instrument->controlChange(j,temp2*128.0); - } - score->nextMessage(); - } - for (i=0;i<22000;i++) { /* let the reverb settle a little */ - output.tick(reverb.tick(instrument->tick())); - } - - delete score; - delete instrument; - -} - - diff --git a/testMult.cpp b/testMult.cpp deleted file mode 100644 index d8ccc6a..0000000 --- a/testMult.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/************** Test Main Program Individual Voice *********************/ - -#include "miditabl.h" -#include "RawWvOut.h" -#include "MIDIText.h" -#include "Reverb.h" -#include "VoicMang.h" - -int main(int argc,char *argv[]) -{ - long i, j; - MY_FLOAT temp,temp2; - VoicMang *section; - RawWvOut output("test.snd"); - Reverb reverb(2137); - float gain; - MIDIText *score; - - if (argc<3) { - printf("useage: testMulti Instr file.mtx\n"); - printf(" where Instr = Marimba Vibraphn AgogoBel Plucked\n"); - printf(" Mandolin Clarinet Flute Brass Bowed \n"); - printf(" Rhodey Wurley TubeBell HeavyMtl\n"); - printf(" PercFlut BeeThree Moog1\n"); - exit(0); - } - else if (argc==4) { - gain = atof(argv[1]); - section = new VoicMang(8,argv[2]); - score = new MIDIText(argv[3]); - } - else if (argc==3) { - gain = 0.125; - section = new VoicMang(8,argv[1]); - score = new MIDIText(argv[2]); - } - if (!section) { - printf("section type must be 1 of:\n"); - printf("Marimba Vibraphn AgogoBel Plucked Mandolin\n"); - printf("Clarinet Flute Brass Bowed Rhodey Wurley\n"); - printf("TubeBell HeavyMtl PercFlut BeeThree Moog1\n"); - exit(0); - } - - reverb.setEffectMix(0.2); - while(score->getType() > 0) { - j = long (score->getDelta() * SRATE); -// printf("%i\n",j); - if (j > 0) { - for (i=0;itick())); - } - } - temp = score->getByteTwo(); - temp2 = score->getByteThree(); - if (score->getType()==9) { - if (score->getByteThree() == 0) { - section->noteOffN((int) temp,temp2); - } - else { - j = section->noteOn(temp,temp2); - if (j<0) { - printf("Out of Voices Here\n"); - section->kill(section->oldestVoice()); - section->noteOn(temp,temp2); - } - } - } - else if (score->getType() == 8) { - section->noteOffN((int) temp,temp2); - } - else if (score->getType() == 11) { - j = (int) score->getByteTwo(); - section->controlChange(j,temp2); - } - score->nextMessage(); - } - for (i=0;i<22000;i++) { /* let the reverb settle a little */ - output.tick(reverb.tick(0.125 * section->tick())); - } - - delete score; - delete section; - -} - - diff --git a/testTextIn.cpp b/testTextIn.cpp deleted file mode 100644 index db3f1eb..0000000 --- a/testTextIn.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/************** Test Main Program Individual Voice *********************/ - -#include "miditabl.h" -#include "RawWvOut.h" -#include "Instrmnt.h" -#include "Marimba.h" -#include "Vibraphn.h" -#include "AgogoBel.h" -#include "Plucked.h" -#include "Mandolin.h" -#include "Clarinet.h" -#include "Flute.h" -#include "Brass.h" -#include "Bowed.h" -#include "Rhodey.h" -#include "Wurley.h" -#include "TubeBell.h" -#include "HeavyMtl.h" -#include "PercFlut.h" -#include "BeeThree.h" -#include "FMVoices.h" -#include "Moog1.h" -#include "VoicForm.h" -#include "Reverb.h" - -#include -#include -#define _BSD_SIGNALS -#include - -#define MAX_BUF 16 - -int gotOne = 0; -char inputString[128]; -int test_pid; - -void newString(void *) -{ - while (1) { - fgets(inputString,128,stdin); - gotOne = 1; - } -} - -int main(int argc,char *argv[]) -{ - long i, j; - MY_FLOAT temp,temp2; - Instrmnt *instrument; - RawWvOut output("test.snd"); - Reverb reverb(2137); - int outAHere; - double deltaTime; - int channel; - int point; - char tempString[32]; - float byteTwo,byteThree,lastPitch=100.0; - - if (argc<2) { - printf("useage: testTCL Instr\n"); - printf(" where Instr = Marimba Vibraphn AgogoBel Plucked\n"); - printf(" Mandolin Clarinet Flute Brass Bowed \n"); - printf(" Rhodey Wurley TubeBell HeavyMtl\n"); - printf(" PercFlut BeeThree FMVoices VoicForm Moog1\n"); - exit(0); - } - if (!strcmp(argv[1],"Marimba")) instrument = new Marimba; - else if (!strcmp(argv[1],"Vibraphn")) instrument = new Vibraphn; - else if (!strcmp(argv[1],"AgogoBel")) instrument = new AgogoBel; - else if (!strcmp(argv[1],"Plucked")) instrument = new Plucked(50.0); - else if (!strcmp(argv[1],"Mandolin")) instrument = new Mandolin(50.0); - else if (!strcmp(argv[1],"Clarinet")) instrument = new Clarinet(50.0); - else if (!strcmp(argv[1],"Flute")) instrument = new Flute(50.0); - else if (!strcmp(argv[1],"Brass")) instrument = new Brass(50.0); - else if (!strcmp(argv[1],"Bowed")) instrument = new Bowed(50.0); - else if (!strcmp(argv[1],"Rhodey")) instrument = new Rhodey; - else if (!strcmp(argv[1],"Wurley")) instrument = new Wurley; - else if (!strcmp(argv[1],"TubeBell")) instrument = new TubeBell; - else if (!strcmp(argv[1],"HeavyMtl")) instrument = new HeavyMtl; - else if (!strcmp(argv[1],"PercFlut")) instrument = new PercFlut; - else if (!strcmp(argv[1],"BeeThree")) instrument = new BeeThree; - else if (!strcmp(argv[1],"FMVoices")) instrument = new FMVoices; - else if (!strcmp(argv[1],"VoicForm")) instrument = new VoicForm; - else if (!strcmp(argv[1],"Moog1")) instrument = new Moog1; - else { - printf("Instrument type must be 1 of:\n"); - printf("Marimba Vibraphn AgogoBel Plucked Mandolin\n"); - printf("Clarinet Flute Brass Bowed Rhodey Wurley TubeBell\n"); - printf("HeavyMtl PercFlut BeeThree FMVoices VoicForm Moog1\n"); - exit(0); - } - - reverb.setEffectMix(0.2); - instrument->noteOn(440.0, 0.95); - - test_pid = sproc(newString, PR_SALL); - - if (test_pid == -1) - { - fprintf(stderr, "unable to create input thread...aborting.\n"); - exit(-1); - } - - outAHere = 0; - - while (!outAHere) { - while (gotOne == 0) { - output.tick(reverb.tick(instrument->tick())); - } - if (gotOne > 0) { - sscanf(inputString,"%s %lf %i %f %f",tempString,&deltaTime,&channel,&byteTwo,&byteThree); - gotOne = 0; - point = 5; - if (tempString[0]=='%') point = 1; - if (tempString[point] == 'n') { // NoteO'n' - j = (int) byteTwo; - byteTwo = __MIDI_To_Pitch[j]; - lastPitch = byteTwo; - instrument->noteOn(byteTwo,byteThree*NORM_7); - } - else if (tempString[point] == 'f') { // NoteO'f'f - j = (int) byteTwo; - instrument->noteOff(byteThree*NORM_7); - } - else if (tempString[point] == 'B') { // Pitch'B'end - byteThree = byteTwo; - j = (int) byteThree; - byteThree -= j; - lastPitch = __MIDI_To_Pitch[j] * pow(2.0,byteThree / 12.0) ; - instrument->setFreq(lastPitch); - } - else if (tempString[point] == 'a') { // Progr'a'mChange - instrument->noteOff(1.0); - for (i=0;i<4096;i++) { - output.tick(reverb.tick(instrument->tick())); - } - delete instrument; - if (byteTwo==0) instrument = new Clarinet(50.0); - else if (byteTwo==1) instrument = new Flute(50.0); - else if (byteTwo==2) instrument = new Brass(50.0); - else if (byteTwo==3) instrument = new Bowed(50.0); - - else if (byteTwo==4) instrument = new Mandolin(50.0); - else if (byteTwo==5) instrument = new Marimba; - else if (byteTwo==6) instrument = new Vibraphn; - else if (byteTwo==7) instrument = new AgogoBel; - else if (byteTwo==8) instrument = new Rhodey; - else if (byteTwo==9) instrument = new Wurley; - else if (byteTwo==10) instrument = new TubeBell; - - else if (byteTwo==11) instrument = new FMVoices; - else if (byteTwo==12) instrument = new VoicForm; - - else if (byteTwo==13) instrument = new HeavyMtl; - else if (byteTwo==14) instrument = new PercFlut; - else if (byteTwo==15) instrument = new Moog1; - - instrument->noteOn(lastPitch, 0.95); - } - else if (tempString[point] == 'T') { // After'T'ouch - instrument->controlChange(128,byteTwo); - } - else if (tempString[point] == 'o') { // Contr'o'lChange - j = (long) byteTwo; - instrument->controlChange(j,byteThree); - } - else if (tempString[0] == 'E' && tempString[1] == 'x') { - gotOne = 0; - outAHere = 1; - } - -// else if (tempString[0] == '/') { -// notDone = 1; -// } - - gotOne = 0; - - } - - } - - kill(test_pid, SIGKILL); - delete instrument; - -} - - diff --git a/textVoic.cpp b/textVoic.cpp deleted file mode 100644 index 5707d04..0000000 --- a/textVoic.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* Very simple text input program for formant voice - model. Perry R. Cook 1996 */ - -/************ Test Main Program *****************/ - -#include "VoicForm.h" -#include "RawWvOut.h" -#include "Reverb.h" - -int main(int argc, char *argv[]) -{ - VoicForm instrument; - RawWvOut output("test.snd"); - Reverb reverb(2137); - long i,j,k; - double temp = 110.0; - - if (argc>1) { - - instrument.setPitchSweepRate(0.001); - instrument.setFreq(temp); - reverb.setEffectMix(0.2); - for (j=1;j