mirror of
https://github.com/thestk/stk
synced 2026-01-12 12:31:53 +00:00
1142 lines
35 KiB
C++
1142 lines
35 KiB
C++
/***************************************************/
|
|
/*! \class Shakers
|
|
\brief PhISEM and PhOLIES class.
|
|
|
|
PhISEM (Physically Informed Stochastic Event
|
|
Modeling) is an algorithmic approach for
|
|
simulating collisions of multiple independent
|
|
sound producing objects. This class is a
|
|
meta-model that can simulate a Maraca, Sekere,
|
|
Cabasa, Bamboo Wind Chimes, Water Drops,
|
|
Tambourine, Sleighbells, and a Guiro.
|
|
|
|
PhOLIES (Physically-Oriented Library of
|
|
Imitated Environmental Sounds) is a similar
|
|
approach for the synthesis of environmental
|
|
sounds. This class implements simulations of
|
|
breaking sticks, crunchy snow (or not), a
|
|
wrench, sandpaper, and more.
|
|
|
|
Control Change Numbers:
|
|
- Shake Energy = 2
|
|
- System Decay = 4
|
|
- Number Of Objects = 11
|
|
- Resonance Frequency = 1
|
|
- Shake Energy = 128
|
|
- Instrument Selection = 1071
|
|
- Maraca = 0
|
|
- Cabasa = 1
|
|
- Sekere = 2
|
|
- Guiro = 3
|
|
- Water Drops = 4
|
|
- Bamboo Chimes = 5
|
|
- Tambourine = 6
|
|
- Sleigh Bells = 7
|
|
- Sticks = 8
|
|
- Crunch = 9
|
|
- Wrench = 10
|
|
- Sand Paper = 11
|
|
- Coke Can = 12
|
|
- Next Mug = 13
|
|
- Penny + Mug = 14
|
|
- Nickle + Mug = 15
|
|
- Dime + Mug = 16
|
|
- Quarter + Mug = 17
|
|
- Franc + Mug = 18
|
|
- Peso + Mug = 19
|
|
- Big Rocks = 20
|
|
- Little Rocks = 21
|
|
- Tuned Bamboo Chimes = 22
|
|
|
|
by Perry R. Cook, 1996 - 2004.
|
|
*/
|
|
/***************************************************/
|
|
|
|
#include "Stk.h"
|
|
#include <math.h>
|
|
|
|
int my_random(int max) // Return Random Int Between 0 and max
|
|
{
|
|
int temp = (int) ((float)max * rand() / (RAND_MAX + 1.0) );
|
|
return temp;
|
|
}
|
|
|
|
StkFloat float_random(StkFloat max) // Return random float between 0.0 and max
|
|
{
|
|
StkFloat temp = (StkFloat) (max * rand() / (RAND_MAX + 1.0) );
|
|
return temp;
|
|
}
|
|
|
|
StkFloat noise_tick() // Return random StkFloat float between -1.0 and 1.0
|
|
{
|
|
StkFloat temp = (StkFloat) (2.0 * rand() / (RAND_MAX + 1.0) );
|
|
temp -= 1.0;
|
|
return temp;
|
|
}
|
|
|
|
// Maraca
|
|
const StkFloat MARA_SOUND_DECAY = 0.95;
|
|
const StkFloat MARA_SYSTEM_DECAY = 0.999;
|
|
const StkFloat MARA_GAIN = 20.0;
|
|
const StkFloat MARA_NUM_BEANS = 25;
|
|
const StkFloat MARA_CENTER_FREQ = 3200.0;
|
|
const StkFloat MARA_RESON = 0.96;
|
|
|
|
// Sekere
|
|
const StkFloat SEKE_SOUND_DECAY = 0.96;
|
|
const StkFloat SEKE_SYSTEM_DECAY = 0.999;
|
|
const StkFloat SEKE_GAIN = 20.0;
|
|
const StkFloat SEKE_NUM_BEANS = 64;
|
|
const StkFloat SEKE_CENTER_FREQ = 5500.0;
|
|
const StkFloat SEKE_RESON = 0.6;
|
|
|
|
// Sandpaper
|
|
const StkFloat SANDPAPR_SOUND_DECAY = 0.999;
|
|
const StkFloat SANDPAPR_SYSTEM_DECAY = 0.999;
|
|
const StkFloat SANDPAPR_GAIN = 0.5;
|
|
const StkFloat SANDPAPR_NUM_GRAINS = 128;
|
|
const StkFloat SANDPAPR_CENTER_FREQ = 4500.0;
|
|
const StkFloat SANDPAPR_RESON = 0.6;
|
|
|
|
// Cabasa
|
|
const StkFloat CABA_SOUND_DECAY = 0.96;
|
|
const StkFloat CABA_SYSTEM_DECAY = 0.997;
|
|
const StkFloat CABA_GAIN = 40.0;
|
|
const StkFloat CABA_NUM_BEADS = 512;
|
|
const StkFloat CABA_CENTER_FREQ = 3000.0;
|
|
const StkFloat CABA_RESON = 0.7;
|
|
|
|
// Bamboo Wind Chimes
|
|
const StkFloat BAMB_SOUND_DECAY = 0.95;
|
|
const StkFloat BAMB_SYSTEM_DECAY = 0.9999;
|
|
const StkFloat BAMB_GAIN = 2.0;
|
|
const StkFloat BAMB_NUM_TUBES = 1.25;
|
|
const StkFloat BAMB_CENTER_FREQ0 = 2800.0;
|
|
const StkFloat BAMB_CENTER_FREQ1 = 0.8 * 2800.0;
|
|
const StkFloat BAMB_CENTER_FREQ2 = 1.2 * 2800.0;
|
|
const StkFloat BAMB_RESON = 0.995;
|
|
|
|
// Tuned Bamboo Wind Chimes (Anklung)
|
|
const StkFloat TBAMB_SOUND_DECAY = 0.95;
|
|
const StkFloat TBAMB_SYSTEM_DECAY = 0.9999;
|
|
const StkFloat TBAMB_GAIN = 1.0;
|
|
const StkFloat TBAMB_NUM_TUBES = 1.25;
|
|
const StkFloat TBAMB_CENTER_FREQ0 = 1046.6;
|
|
const StkFloat TBAMB_CENTER_FREQ1 = 1174.8;
|
|
const StkFloat TBAMB_CENTER_FREQ2 = 1397.0;
|
|
const StkFloat TBAMB_CENTER_FREQ3 = 1568.0;
|
|
const StkFloat TBAMB_CENTER_FREQ4 = 1760.0;
|
|
const StkFloat TBAMB_CENTER_FREQ5 = 2093.3;
|
|
const StkFloat TBAMB_CENTER_FREQ6 = 2350.0;
|
|
const StkFloat TBAMB_RESON = 0.996;
|
|
|
|
// Water Drops
|
|
const StkFloat WUTR_SOUND_DECAY = 0.95;
|
|
const StkFloat WUTR_SYSTEM_DECAY = 0.996;
|
|
const StkFloat WUTR_GAIN = 1.0;
|
|
const StkFloat WUTR_NUM_SOURCES = 10;
|
|
const StkFloat WUTR_CENTER_FREQ0 = 450.0;
|
|
const StkFloat WUTR_CENTER_FREQ1 = 600.0;
|
|
const StkFloat WUTR_CENTER_FREQ2 = 750.0;
|
|
const StkFloat WUTR_RESON = 0.9985;
|
|
const StkFloat WUTR_FREQ_SWEEP = 1.0001;
|
|
|
|
// Tambourine
|
|
const StkFloat TAMB_SOUND_DECAY = 0.95;
|
|
const StkFloat TAMB_SYSTEM_DECAY = 0.9985;
|
|
const StkFloat TAMB_GAIN = 5.0;
|
|
const StkFloat TAMB_NUM_TIMBRELS = 32;
|
|
const StkFloat TAMB_SHELL_FREQ = 2300;
|
|
const StkFloat TAMB_SHELL_GAIN = 0.1;
|
|
const StkFloat TAMB_SHELL_RESON = 0.96;
|
|
const StkFloat TAMB_CYMB_FREQ1 = 5600;
|
|
const StkFloat TAMB_CYMB_FREQ2 = 8100;
|
|
const StkFloat TAMB_CYMB_RESON = 0.99;
|
|
|
|
// Sleighbells
|
|
const StkFloat SLEI_SOUND_DECAY = 0.97;
|
|
const StkFloat SLEI_SYSTEM_DECAY = 0.9994;
|
|
const StkFloat SLEI_GAIN = 1.0;
|
|
const StkFloat SLEI_NUM_BELLS = 32;
|
|
const StkFloat SLEI_CYMB_FREQ0 = 2500;
|
|
const StkFloat SLEI_CYMB_FREQ1 = 5300;
|
|
const StkFloat SLEI_CYMB_FREQ2 = 6500;
|
|
const StkFloat SLEI_CYMB_FREQ3 = 8300;
|
|
const StkFloat SLEI_CYMB_FREQ4 = 9800;
|
|
const StkFloat SLEI_CYMB_RESON = 0.99;
|
|
|
|
// Guiro
|
|
const StkFloat GUIR_SOUND_DECAY = 0.95;
|
|
const StkFloat GUIR_GAIN = 10.0;
|
|
const StkFloat GUIR_NUM_PARTS = 128;
|
|
const StkFloat GUIR_GOURD_FREQ = 2500.0;
|
|
const StkFloat GUIR_GOURD_RESON = 0.97;
|
|
const StkFloat GUIR_GOURD_FREQ2 = 4000.0;
|
|
const StkFloat GUIR_GOURD_RESON2 = 0.97;
|
|
|
|
// Wrench
|
|
const StkFloat WRENCH_SOUND_DECAY = 0.95;
|
|
const StkFloat WRENCH_GAIN = 5;
|
|
const StkFloat WRENCH_NUM_PARTS = 128;
|
|
const StkFloat WRENCH_FREQ = 3200.0;
|
|
const StkFloat WRENCH_RESON = 0.99;
|
|
const StkFloat WRENCH_FREQ2 = 8000.0;
|
|
const StkFloat WRENCH_RESON2 = 0.992;
|
|
|
|
// Cokecan
|
|
const StkFloat COKECAN_SOUND_DECAY = 0.97;
|
|
const StkFloat COKECAN_SYSTEM_DECAY = 0.999;
|
|
const StkFloat COKECAN_GAIN = 0.8;
|
|
const StkFloat COKECAN_NUM_PARTS = 48;
|
|
const StkFloat COKECAN_HELMFREQ = 370;
|
|
const StkFloat COKECAN_HELM_RES = 0.99;
|
|
const StkFloat COKECAN_METLFREQ0 = 1025;
|
|
const StkFloat COKECAN_METLFREQ1 = 1424;
|
|
const StkFloat COKECAN_METLFREQ2 = 2149;
|
|
const StkFloat COKECAN_METLFREQ3 = 3596;
|
|
const StkFloat COKECAN_METL_RES = 0.992;
|
|
|
|
// PhOLIES (Physically-Oriented Library of Imitated Environmental
|
|
// Sounds), Perry Cook, 1997-8
|
|
|
|
// Stix1
|
|
const StkFloat STIX1_SOUND_DECAY = 0.96;
|
|
const StkFloat STIX1_SYSTEM_DECAY = 0.998;
|
|
const StkFloat STIX1_GAIN = 30.0;
|
|
const StkFloat STIX1_NUM_BEANS = 2;
|
|
const StkFloat STIX1_CENTER_FREQ = 5500.0;
|
|
const StkFloat STIX1_RESON = 0.6;
|
|
|
|
// Crunch1
|
|
const StkFloat CRUNCH1_SOUND_DECAY = 0.95;
|
|
const StkFloat CRUNCH1_SYSTEM_DECAY = 0.99806;
|
|
const StkFloat CRUNCH1_GAIN = 20.0;
|
|
const StkFloat CRUNCH1_NUM_BEADS = 7;
|
|
const StkFloat CRUNCH1_CENTER_FREQ = 800.0;
|
|
const StkFloat CRUNCH1_RESON = 0.95;
|
|
|
|
// Nextmug
|
|
const StkFloat NEXTMUG_SOUND_DECAY = 0.97;
|
|
const StkFloat NEXTMUG_SYSTEM_DECAY = 0.9995;
|
|
const StkFloat NEXTMUG_GAIN = 0.8;
|
|
const StkFloat NEXTMUG_NUM_PARTS = 3;
|
|
const StkFloat NEXTMUG_FREQ0 = 2123;
|
|
const StkFloat NEXTMUG_FREQ1 = 4518;
|
|
const StkFloat NEXTMUG_FREQ2 = 8856;
|
|
const StkFloat NEXTMUG_FREQ3 = 10753;
|
|
const StkFloat NEXTMUG_RES = 0.997;
|
|
|
|
const StkFloat PENNY_FREQ0 = 11000;
|
|
const StkFloat PENNY_FREQ1 = 5200;
|
|
const StkFloat PENNY_FREQ2 = 3835;
|
|
const StkFloat PENNY_RES = 0.999;
|
|
|
|
const StkFloat NICKEL_FREQ0 = 5583;
|
|
const StkFloat NICKEL_FREQ1 = 9255;
|
|
const StkFloat NICKEL_FREQ2 = 9805;
|
|
const StkFloat NICKEL_RES = 0.9992;
|
|
|
|
const StkFloat DIME_FREQ0 = 4450;
|
|
const StkFloat DIME_FREQ1 = 4974;
|
|
const StkFloat DIME_FREQ2 = 9945;
|
|
const StkFloat DIME_RES = 0.9993;
|
|
|
|
const StkFloat QUARTER_FREQ0 = 1708;
|
|
const StkFloat QUARTER_FREQ1 = 8863;
|
|
const StkFloat QUARTER_FREQ2 = 9045;
|
|
const StkFloat QUARTER_RES = 0.9995;
|
|
|
|
const StkFloat FRANC_FREQ0 = 5583;
|
|
const StkFloat FRANC_FREQ1 = 11010;
|
|
const StkFloat FRANC_FREQ2 = 1917;
|
|
const StkFloat FRANC_RES = 0.9995;
|
|
|
|
const StkFloat PESO_FREQ0 = 7250;
|
|
const StkFloat PESO_FREQ1 = 8150;
|
|
const StkFloat PESO_FREQ2 = 10060;
|
|
const StkFloat PESO_RES = 0.9996;
|
|
|
|
// Big Gravel
|
|
const StkFloat BIGROCKS_SOUND_DECAY = 0.98;
|
|
const StkFloat BIGROCKS_SYSTEM_DECAY = 0.9965;
|
|
const StkFloat BIGROCKS_GAIN = 20.0;
|
|
const StkFloat BIGROCKS_NUM_PARTS = 23;
|
|
const StkFloat BIGROCKS_FREQ = 6460;
|
|
const StkFloat BIGROCKS_RES = 0.932;
|
|
|
|
// Little Gravel
|
|
const StkFloat LITLROCKS_SOUND_DECAY = 0.98;
|
|
const StkFloat LITLROCKS_SYSTEM_DECAY = 0.99586;
|
|
const StkFloat LITLROCKS_GAIN = 20.0;
|
|
const StkFloat LITLROCKS_NUM_PARTS = 1600;
|
|
const StkFloat LITLROCKS_FREQ = 9000;
|
|
const StkFloat LITLROCKS_RES = 0.843;
|
|
|
|
// Finally ... the class code!
|
|
|
|
#include "Shakers.h"
|
|
#include "SKINI.msg"
|
|
|
|
Shakers :: Shakers()
|
|
{
|
|
int i;
|
|
|
|
instType_ = 0;
|
|
shakeEnergy_ = 0.0;
|
|
nFreqs_ = 0;
|
|
sndLevel_ = 0.0;
|
|
|
|
for ( i=0; i<MAX_FREQS; i++ ) {
|
|
inputs_[i] = 0.0;
|
|
outputs_[i][0] = 0.0;
|
|
outputs_[i][1] = 0.0;
|
|
coeffs_[i][0] = 0.0;
|
|
coeffs_[i][1] = 0.0;
|
|
gains_[i] = 0.0;
|
|
center_freqs_[i] = 0.0;
|
|
resons_[i] = 0.0;
|
|
freq_rand_[i] = 0.0;
|
|
freqalloc_[i] = 0;
|
|
}
|
|
|
|
soundDecay_ = 0.0;
|
|
systemDecay_ = 0.0;
|
|
nObjects_ = 0.0;
|
|
totalEnergy_ = 0.0;
|
|
ratchet_ = 0.0;
|
|
ratchetDelta_ = 0.0005;
|
|
lastRatchetPos_ = 0;
|
|
finalZ_[0] = 0.0;
|
|
finalZ_[1] = 0.0;
|
|
finalZ_[2] = 0.0;
|
|
finalZCoeffs_[0] = 1.0;
|
|
finalZCoeffs_[1] = 0.0;
|
|
finalZCoeffs_[2] = 0.0;
|
|
|
|
this->setupNum(instType_);
|
|
}
|
|
|
|
Shakers :: ~Shakers()
|
|
{
|
|
}
|
|
|
|
const StkFloat MAX_SHAKE = 2000.0;
|
|
|
|
char instrs[NUM_INSTR][10] = {
|
|
"Maraca", "Cabasa", "Sekere", "Guiro",
|
|
"Waterdrp", "Bamboo", "Tambourn", "Sleighbl",
|
|
"Stix1", "Crunch1", "Wrench", "SandPapr",
|
|
"CokeCan", "NextMug", "PennyMug", "NicklMug",
|
|
"DimeMug", "QuartMug", "FrancMug", "PesoMug",
|
|
"BigRocks", "LitlRoks", "TBamboo"
|
|
};
|
|
|
|
int Shakers :: setupName(char* instr)
|
|
{
|
|
int which = 0;
|
|
|
|
for (int i=0;i<NUM_INSTR;i++) {
|
|
if ( !strcmp(instr,instrs[i]) )
|
|
which = i;
|
|
}
|
|
|
|
#if defined(_STK_DEBUG_)
|
|
errorString_ << "Shakers::setupName: setting instrument to " << instrs[which] << '.';
|
|
handleError( StkError::DEBUG_WARNING );
|
|
#endif
|
|
|
|
return this->setupNum(which);
|
|
}
|
|
|
|
void Shakers :: setFinalZs(StkFloat z0, StkFloat z1, StkFloat z2)
|
|
{
|
|
finalZCoeffs_[0] = z0;
|
|
finalZCoeffs_[1] = z1;
|
|
finalZCoeffs_[2] = z2;
|
|
}
|
|
|
|
void Shakers :: setDecays(StkFloat sndDecay_, StkFloat sysDecay_)
|
|
{
|
|
soundDecay_ = sndDecay_;
|
|
systemDecay_ = sysDecay_;
|
|
}
|
|
|
|
int Shakers :: setFreqAndReson(int which, StkFloat freq, StkFloat reson)
|
|
{
|
|
if (which < MAX_FREQS) {
|
|
resons_[which] = reson;
|
|
center_freqs_[which] = freq;
|
|
t_center_freqs_[which] = freq;
|
|
coeffs_[which][1] = reson * reson;
|
|
coeffs_[which][0] = -reson * 2.0 * cos(freq * TWO_PI / Stk::sampleRate());
|
|
return 1;
|
|
}
|
|
else return 0;
|
|
}
|
|
|
|
int Shakers :: setupNum(int inst)
|
|
{
|
|
int i, rv = 0;
|
|
StkFloat temp;
|
|
|
|
if (inst == 1) { // Cabasa
|
|
rv = inst;
|
|
nObjects_ = CABA_NUM_BEADS;
|
|
defObjs_[inst] = CABA_NUM_BEADS;
|
|
setDecays(CABA_SOUND_DECAY, CABA_SYSTEM_DECAY);
|
|
defDecays_[inst] = CABA_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.97;
|
|
nFreqs_ = 1;
|
|
baseGain_ = CABA_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0] = temp;
|
|
freqalloc_[0] = 0;
|
|
setFreqAndReson(0,CABA_CENTER_FREQ,CABA_RESON);
|
|
setFinalZs(1.0,-1.0,0.0);
|
|
}
|
|
else if (inst == 2) { // Sekere
|
|
rv = inst;
|
|
nObjects_ = SEKE_NUM_BEANS;
|
|
defObjs_[inst] = SEKE_NUM_BEANS;
|
|
this->setDecays(SEKE_SOUND_DECAY,SEKE_SYSTEM_DECAY);
|
|
defDecays_[inst] = SEKE_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.94;
|
|
nFreqs_ = 1;
|
|
baseGain_ = SEKE_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0] = temp;
|
|
freqalloc_[0] = 0;
|
|
this->setFreqAndReson(0,SEKE_CENTER_FREQ,SEKE_RESON);
|
|
this->setFinalZs(1.0, 0.0, -1.0);
|
|
}
|
|
else if (inst == 3) { // Guiro
|
|
rv = inst;
|
|
nObjects_ = GUIR_NUM_PARTS;
|
|
defObjs_[inst] = GUIR_NUM_PARTS;
|
|
setDecays(GUIR_SOUND_DECAY,1.0);
|
|
defDecays_[inst] = 0.9999;
|
|
decayScale_[inst] = 1.0;
|
|
nFreqs_ = 2;
|
|
baseGain_ = GUIR_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
gains_[1]=temp;
|
|
freqalloc_[0] = 0;
|
|
freqalloc_[1] = 0;
|
|
freq_rand_[0] = 0.0;
|
|
freq_rand_[1] = 0.0;
|
|
setFreqAndReson(0,GUIR_GOURD_FREQ,GUIR_GOURD_RESON);
|
|
setFreqAndReson(1,GUIR_GOURD_FREQ2,GUIR_GOURD_RESON2);
|
|
ratchet_ = 0;
|
|
ratchetPos_ = 10;
|
|
}
|
|
else if (inst == 4) { // Water Drops
|
|
rv = inst;
|
|
nObjects_ = WUTR_NUM_SOURCES;
|
|
defObjs_[inst] = WUTR_NUM_SOURCES;
|
|
setDecays(WUTR_SOUND_DECAY,WUTR_SYSTEM_DECAY);
|
|
defDecays_[inst] = WUTR_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.8;
|
|
nFreqs_ = 3;
|
|
baseGain_ = WUTR_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
gains_[1]=temp;
|
|
gains_[2]=temp;
|
|
freqalloc_[0] = 1;
|
|
freqalloc_[1] = 1;
|
|
freqalloc_[2] = 1;
|
|
freq_rand_[0] = 0.2;
|
|
freq_rand_[1] = 0.2;
|
|
freq_rand_[2] = 0.2;
|
|
setFreqAndReson(0,WUTR_CENTER_FREQ0,WUTR_RESON);
|
|
setFreqAndReson(1,WUTR_CENTER_FREQ0,WUTR_RESON);
|
|
setFreqAndReson(2,WUTR_CENTER_FREQ0,WUTR_RESON);
|
|
setFinalZs(1.0,0.0,0.0);
|
|
}
|
|
else if (inst == 5) { // Bamboo
|
|
rv = inst;
|
|
nObjects_ = BAMB_NUM_TUBES;
|
|
defObjs_[inst] = BAMB_NUM_TUBES;
|
|
setDecays(BAMB_SOUND_DECAY, BAMB_SYSTEM_DECAY);
|
|
defDecays_[inst] = BAMB_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.7;
|
|
nFreqs_ = 3;
|
|
baseGain_ = BAMB_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
gains_[1]=temp;
|
|
gains_[2]=temp;
|
|
freqalloc_[0] = 1;
|
|
freqalloc_[1] = 1;
|
|
freqalloc_[2] = 1;
|
|
freq_rand_[0] = 0.2;
|
|
freq_rand_[1] = 0.2;
|
|
freq_rand_[2] = 0.2;
|
|
setFreqAndReson(0,BAMB_CENTER_FREQ0,BAMB_RESON);
|
|
setFreqAndReson(1,BAMB_CENTER_FREQ1,BAMB_RESON);
|
|
setFreqAndReson(2,BAMB_CENTER_FREQ2,BAMB_RESON);
|
|
setFinalZs(1.0,0.0,0.0);
|
|
}
|
|
else if (inst == 6) { // Tambourine
|
|
rv = inst;
|
|
nObjects_ = TAMB_NUM_TIMBRELS;
|
|
defObjs_[inst] = TAMB_NUM_TIMBRELS;
|
|
setDecays(TAMB_SOUND_DECAY,TAMB_SYSTEM_DECAY);
|
|
defDecays_[inst] = TAMB_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.95;
|
|
nFreqs_ = 3;
|
|
baseGain_ = TAMB_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp*TAMB_SHELL_GAIN;
|
|
gains_[1]=temp*0.8;
|
|
gains_[2]=temp;
|
|
freqalloc_[0] = 0;
|
|
freqalloc_[1] = 1;
|
|
freqalloc_[2] = 1;
|
|
freq_rand_[0] = 0.0;
|
|
freq_rand_[1] = 0.05;
|
|
freq_rand_[2] = 0.05;
|
|
setFreqAndReson(0,TAMB_SHELL_FREQ,TAMB_SHELL_RESON);
|
|
setFreqAndReson(1,TAMB_CYMB_FREQ1,TAMB_CYMB_RESON);
|
|
setFreqAndReson(2,TAMB_CYMB_FREQ2,TAMB_CYMB_RESON);
|
|
setFinalZs(1.0,0.0,-1.0);
|
|
}
|
|
else if (inst == 7) { // Sleighbell
|
|
rv = inst;
|
|
nObjects_ = SLEI_NUM_BELLS;
|
|
defObjs_[inst] = SLEI_NUM_BELLS;
|
|
setDecays(SLEI_SOUND_DECAY,SLEI_SYSTEM_DECAY);
|
|
defDecays_[inst] = SLEI_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.9;
|
|
nFreqs_ = 5;
|
|
baseGain_ = SLEI_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
gains_[1]=temp;
|
|
gains_[2]=temp;
|
|
gains_[3]=temp*0.5;
|
|
gains_[4]=temp*0.3;
|
|
for (i=0;i<nFreqs_;i++) {
|
|
freqalloc_[i] = 1;
|
|
freq_rand_[i] = 0.03;
|
|
}
|
|
setFreqAndReson(0,SLEI_CYMB_FREQ0,SLEI_CYMB_RESON);
|
|
setFreqAndReson(1,SLEI_CYMB_FREQ1,SLEI_CYMB_RESON);
|
|
setFreqAndReson(2,SLEI_CYMB_FREQ2,SLEI_CYMB_RESON);
|
|
setFreqAndReson(3,SLEI_CYMB_FREQ3,SLEI_CYMB_RESON);
|
|
setFreqAndReson(4,SLEI_CYMB_FREQ4,SLEI_CYMB_RESON);
|
|
setFinalZs(1.0,0.0,-1.0);
|
|
}
|
|
else if (inst == 8) { // Stix1
|
|
rv = inst;
|
|
nObjects_ = STIX1_NUM_BEANS;
|
|
defObjs_[inst] = STIX1_NUM_BEANS;
|
|
setDecays(STIX1_SOUND_DECAY,STIX1_SYSTEM_DECAY);
|
|
defDecays_[inst] = STIX1_SYSTEM_DECAY;
|
|
|
|
decayScale_[inst] = 0.96;
|
|
nFreqs_ = 1;
|
|
baseGain_ = STIX1_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
freqalloc_[0] = 0;
|
|
setFreqAndReson(0,STIX1_CENTER_FREQ,STIX1_RESON);
|
|
setFinalZs(1.0,0.0,-1.0);
|
|
}
|
|
else if (inst == 9) { // Crunch1
|
|
rv = inst;
|
|
nObjects_ = CRUNCH1_NUM_BEADS;
|
|
defObjs_[inst] = CRUNCH1_NUM_BEADS;
|
|
setDecays(CRUNCH1_SOUND_DECAY,CRUNCH1_SYSTEM_DECAY);
|
|
defDecays_[inst] = CRUNCH1_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.96;
|
|
nFreqs_ = 1;
|
|
baseGain_ = CRUNCH1_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
freqalloc_[0] = 0;
|
|
setFreqAndReson(0,CRUNCH1_CENTER_FREQ,CRUNCH1_RESON);
|
|
setFinalZs(1.0,-1.0,0.0);
|
|
}
|
|
else if (inst == 10) { // Wrench
|
|
rv = inst;
|
|
nObjects_ = WRENCH_NUM_PARTS;
|
|
defObjs_[inst] = WRENCH_NUM_PARTS;
|
|
setDecays(WRENCH_SOUND_DECAY,1.0);
|
|
defDecays_[inst] = 0.9999;
|
|
decayScale_[inst] = 0.98;
|
|
nFreqs_ = 2;
|
|
baseGain_ = WRENCH_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
gains_[1]=temp;
|
|
freqalloc_[0] = 0;
|
|
freqalloc_[1] = 0;
|
|
freq_rand_[0] = 0.0;
|
|
freq_rand_[1] = 0.0;
|
|
setFreqAndReson(0,WRENCH_FREQ,WRENCH_RESON);
|
|
setFreqAndReson(1,WRENCH_FREQ2,WRENCH_RESON2);
|
|
ratchet_ = 0;
|
|
ratchetPos_ = 10;
|
|
}
|
|
else if (inst == 11) { // Sandpapr
|
|
rv = inst;
|
|
nObjects_ = SANDPAPR_NUM_GRAINS;
|
|
defObjs_[inst] = SANDPAPR_NUM_GRAINS;
|
|
this->setDecays(SANDPAPR_SOUND_DECAY,SANDPAPR_SYSTEM_DECAY);
|
|
defDecays_[inst] = SANDPAPR_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.97;
|
|
nFreqs_ = 1;
|
|
baseGain_ = SANDPAPR_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0] = temp;
|
|
freqalloc_[0] = 0;
|
|
this->setFreqAndReson(0,SANDPAPR_CENTER_FREQ,SANDPAPR_RESON);
|
|
this->setFinalZs(1.0, 0.0, -1.0);
|
|
}
|
|
else if (inst == 12) { // Cokecan
|
|
rv = inst;
|
|
nObjects_ = COKECAN_NUM_PARTS;
|
|
defObjs_[inst] = COKECAN_NUM_PARTS;
|
|
setDecays(COKECAN_SOUND_DECAY,COKECAN_SYSTEM_DECAY);
|
|
defDecays_[inst] = COKECAN_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.95;
|
|
nFreqs_ = 5;
|
|
baseGain_ = COKECAN_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
gains_[1]=temp*1.8;
|
|
gains_[2]=temp*1.8;
|
|
gains_[3]=temp*1.8;
|
|
gains_[4]=temp*1.8;
|
|
freqalloc_[0] = 0;
|
|
freqalloc_[1] = 0;
|
|
freqalloc_[2] = 0;
|
|
freqalloc_[3] = 0;
|
|
freqalloc_[4] = 0;
|
|
setFreqAndReson(0,COKECAN_HELMFREQ,COKECAN_HELM_RES);
|
|
setFreqAndReson(1,COKECAN_METLFREQ0,COKECAN_METL_RES);
|
|
setFreqAndReson(2,COKECAN_METLFREQ1,COKECAN_METL_RES);
|
|
setFreqAndReson(3,COKECAN_METLFREQ2,COKECAN_METL_RES);
|
|
setFreqAndReson(4,COKECAN_METLFREQ3,COKECAN_METL_RES);
|
|
setFinalZs(1.0,0.0,-1.0);
|
|
}
|
|
else if (inst>12 && inst<20) { // Nextmug
|
|
rv = inst;
|
|
nObjects_ = NEXTMUG_NUM_PARTS;
|
|
defObjs_[inst] = NEXTMUG_NUM_PARTS;
|
|
setDecays(NEXTMUG_SOUND_DECAY,NEXTMUG_SYSTEM_DECAY);
|
|
defDecays_[inst] = NEXTMUG_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.95;
|
|
nFreqs_ = 4;
|
|
baseGain_ = NEXTMUG_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
gains_[1]=temp*0.8;
|
|
gains_[2]=temp*0.6;
|
|
gains_[3]=temp*0.4;
|
|
freqalloc_[0] = 0;
|
|
freqalloc_[1] = 0;
|
|
freqalloc_[2] = 0;
|
|
freqalloc_[3] = 0;
|
|
freqalloc_[4] = 0;
|
|
freqalloc_[5] = 0;
|
|
setFreqAndReson(0,NEXTMUG_FREQ0,NEXTMUG_RES);
|
|
setFreqAndReson(1,NEXTMUG_FREQ1,NEXTMUG_RES);
|
|
setFreqAndReson(2,NEXTMUG_FREQ2,NEXTMUG_RES);
|
|
setFreqAndReson(3,NEXTMUG_FREQ3,NEXTMUG_RES);
|
|
setFinalZs(1.0,0.0,-1.0);
|
|
|
|
if (inst == 14) { // Mug + Penny
|
|
nFreqs_ = 7;
|
|
gains_[4] = temp;
|
|
gains_[5] = temp*0.8;
|
|
gains_[6] = temp*0.5;
|
|
setFreqAndReson(4,PENNY_FREQ0,PENNY_RES);
|
|
setFreqAndReson(5,PENNY_FREQ1,PENNY_RES);
|
|
setFreqAndReson(6,PENNY_FREQ2,PENNY_RES);
|
|
}
|
|
else if (inst == 15) { // Mug + Nickel
|
|
nFreqs_ = 6;
|
|
gains_[4] = temp;
|
|
gains_[5] = temp*0.8;
|
|
gains_[6] = temp*0.5;
|
|
setFreqAndReson(4,NICKEL_FREQ0,NICKEL_RES);
|
|
setFreqAndReson(5,NICKEL_FREQ1,NICKEL_RES);
|
|
setFreqAndReson(6,NICKEL_FREQ2,NICKEL_RES);
|
|
}
|
|
else if (inst == 16) { // Mug + Dime
|
|
nFreqs_ = 6;
|
|
gains_[4] = temp;
|
|
gains_[5] = temp*0.8;
|
|
gains_[6] = temp*0.5;
|
|
setFreqAndReson(4,DIME_FREQ0,DIME_RES);
|
|
setFreqAndReson(5,DIME_FREQ1,DIME_RES);
|
|
setFreqAndReson(6,DIME_FREQ2,DIME_RES);
|
|
}
|
|
else if (inst == 17) { // Mug + Quarter
|
|
nFreqs_ = 6;
|
|
gains_[4] = temp*1.3;
|
|
gains_[5] = temp*1.0;
|
|
gains_[6] = temp*0.8;
|
|
setFreqAndReson(4,QUARTER_FREQ0,QUARTER_RES);
|
|
setFreqAndReson(5,QUARTER_FREQ1,QUARTER_RES);
|
|
setFreqAndReson(6,QUARTER_FREQ2,QUARTER_RES);
|
|
}
|
|
else if (inst == 18) { // Mug + Franc
|
|
nFreqs_ = 6;
|
|
gains_[4] = temp*0.7;
|
|
gains_[5] = temp*0.4;
|
|
gains_[6] = temp*0.3;
|
|
setFreqAndReson(4,FRANC_FREQ0,FRANC_RES);
|
|
setFreqAndReson(5,FRANC_FREQ1,FRANC_RES);
|
|
setFreqAndReson(6,FRANC_FREQ2,FRANC_RES);
|
|
}
|
|
else if (inst == 19) { // Mug + Peso
|
|
nFreqs_ = 6;
|
|
gains_[4] = temp;
|
|
gains_[5] = temp*1.2;
|
|
gains_[6] = temp*0.7;
|
|
setFreqAndReson(4,PESO_FREQ0,PESO_RES);
|
|
setFreqAndReson(5,PESO_FREQ1,PESO_RES);
|
|
setFreqAndReson(6,PESO_FREQ2,PESO_RES);
|
|
}
|
|
}
|
|
else if (inst == 20) { // Big Rocks
|
|
nFreqs_ = 1;
|
|
rv = inst;
|
|
nObjects_ = BIGROCKS_NUM_PARTS;
|
|
defObjs_[inst] = BIGROCKS_NUM_PARTS;
|
|
setDecays(BIGROCKS_SOUND_DECAY,BIGROCKS_SYSTEM_DECAY);
|
|
defDecays_[inst] = BIGROCKS_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.95;
|
|
baseGain_ = BIGROCKS_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
freqalloc_[0] = 1;
|
|
freq_rand_[0] = 0.11;
|
|
setFreqAndReson(0,BIGROCKS_FREQ,BIGROCKS_RES);
|
|
setFinalZs(1.0,0.0,-1.0);
|
|
}
|
|
else if (inst == 21) { // Little Rocks
|
|
nFreqs_ = 1;
|
|
rv = inst;
|
|
nObjects_ = LITLROCKS_NUM_PARTS;
|
|
defObjs_[inst] = LITLROCKS_NUM_PARTS;
|
|
setDecays(LITLROCKS_SOUND_DECAY,LITLROCKS_SYSTEM_DECAY);
|
|
defDecays_[inst] = LITLROCKS_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.95;
|
|
baseGain_ = LITLROCKS_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
freqalloc_[0] = 1;
|
|
freq_rand_[0] = 0.18;
|
|
setFreqAndReson(0,LITLROCKS_FREQ,LITLROCKS_RES);
|
|
setFinalZs(1.0,0.0,-1.0);
|
|
}
|
|
else if (inst == 22) { // Tuned Bamboo
|
|
rv = inst;
|
|
nObjects_ = TBAMB_NUM_TUBES;
|
|
defObjs_[inst] = TBAMB_NUM_TUBES;
|
|
setDecays(TBAMB_SOUND_DECAY, TBAMB_SYSTEM_DECAY);
|
|
defDecays_[inst] = TBAMB_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.7;
|
|
nFreqs_ = 7;
|
|
baseGain_ = TBAMB_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
gains_[1]=temp;
|
|
gains_[2]=temp;
|
|
gains_[3]=temp;
|
|
gains_[4]=temp;
|
|
gains_[5]=temp;
|
|
gains_[6]=temp;
|
|
freqalloc_[0] = 0;
|
|
freqalloc_[1] = 0;
|
|
freqalloc_[2] = 0;
|
|
freqalloc_[3] = 0;
|
|
freqalloc_[4] = 0;
|
|
freqalloc_[5] = 0;
|
|
freqalloc_[6] = 0;
|
|
freq_rand_[0] = 0.0;
|
|
freq_rand_[1] = 0.0;
|
|
freq_rand_[2] = 0.0;
|
|
freq_rand_[3] = 0.0;
|
|
freq_rand_[4] = 0.0;
|
|
freq_rand_[5] = 0.0;
|
|
freq_rand_[6] = 0.0;
|
|
setFreqAndReson(0,TBAMB_CENTER_FREQ0,TBAMB_RESON);
|
|
setFreqAndReson(1,TBAMB_CENTER_FREQ1,TBAMB_RESON);
|
|
setFreqAndReson(2,TBAMB_CENTER_FREQ2,TBAMB_RESON);
|
|
setFreqAndReson(3,TBAMB_CENTER_FREQ3,TBAMB_RESON);
|
|
setFreqAndReson(4,TBAMB_CENTER_FREQ4,TBAMB_RESON);
|
|
setFreqAndReson(5,TBAMB_CENTER_FREQ5,TBAMB_RESON);
|
|
setFreqAndReson(6,TBAMB_CENTER_FREQ6,TBAMB_RESON);
|
|
setFinalZs(1.0,0.0,-1.0);
|
|
}
|
|
else { // Maraca (inst == 0) or default
|
|
rv = 0;
|
|
nObjects_ = MARA_NUM_BEANS;
|
|
defObjs_[0] = MARA_NUM_BEANS;
|
|
setDecays(MARA_SOUND_DECAY,MARA_SYSTEM_DECAY);
|
|
defDecays_[0] = MARA_SYSTEM_DECAY;
|
|
decayScale_[inst] = 0.9;
|
|
nFreqs_ = 1;
|
|
baseGain_ = MARA_GAIN;
|
|
temp = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
gains_[0]=temp;
|
|
freqalloc_[0] = 0;
|
|
setFreqAndReson(0,MARA_CENTER_FREQ,MARA_RESON);
|
|
setFinalZs(1.0,-1.0,0.0);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
void Shakers :: noteOn(StkFloat frequency, StkFloat amplitude)
|
|
{
|
|
// Yep ... pretty kludgey, but it works!
|
|
int noteNum = (int) ((12*log(frequency/220.0)/log(2.0)) + 57.01) % 32;
|
|
if (instType_ != noteNum) instType_ = this->setupNum(noteNum);
|
|
shakeEnergy_ += amplitude * MAX_SHAKE * 0.1;
|
|
if (shakeEnergy_ > MAX_SHAKE) shakeEnergy_ = MAX_SHAKE;
|
|
if (instType_==10 || instType_==3) ratchetPos_ += 1;
|
|
|
|
#if defined(_STK_DEBUG_)
|
|
errorString_ << "Shakers::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
|
handleError( StkError::DEBUG_WARNING );
|
|
#endif
|
|
}
|
|
|
|
void Shakers :: noteOff(StkFloat amplitude)
|
|
{
|
|
shakeEnergy_ = 0.0;
|
|
if (instType_==10 || instType_==3) ratchetPos_ = 0;
|
|
}
|
|
|
|
const StkFloat MIN_ENERGY = 0.3;
|
|
|
|
StkFloat Shakers :: tick()
|
|
{
|
|
StkFloat data;
|
|
StkFloat temp_rand;
|
|
int i;
|
|
|
|
if (instType_ == 4) {
|
|
if (shakeEnergy_ > MIN_ENERGY) {
|
|
lastOutput_ = wuter_tick();
|
|
lastOutput_ *= 0.0001;
|
|
}
|
|
else {
|
|
lastOutput_ = 0.0;
|
|
}
|
|
}
|
|
else if (instType_ == 22) {
|
|
lastOutput_ = tbamb_tick();
|
|
}
|
|
else if (instType_ == 10 || instType_ == 3) {
|
|
if (ratchetPos_ > 0) {
|
|
ratchet_ -= (ratchetDelta_ + (0.002*totalEnergy_));
|
|
if (ratchet_ < 0.0) {
|
|
ratchet_ = 1.0;
|
|
ratchetPos_ -= 1;
|
|
}
|
|
totalEnergy_ = ratchet_;
|
|
lastOutput_ = ratchet_tick();
|
|
lastOutput_ *= 0.0001;
|
|
}
|
|
else lastOutput_ = 0.0;
|
|
}
|
|
else { // generic_tick()
|
|
if (shakeEnergy_ > MIN_ENERGY) {
|
|
shakeEnergy_ *= systemDecay_; // Exponential system decay
|
|
if (float_random(1024.0) < nObjects_) {
|
|
sndLevel_ += shakeEnergy_;
|
|
for (i=0;i<nFreqs_;i++) {
|
|
if (freqalloc_[i]) {
|
|
temp_rand = t_center_freqs_[i] * (1.0 + (freq_rand_[i] * noise_tick()));
|
|
coeffs_[i][0] = -resons_[i] * 2.0 * cos(temp_rand * TWO_PI / Stk::sampleRate());
|
|
}
|
|
}
|
|
}
|
|
inputs_[0] = sndLevel_ * noise_tick(); // Actual Sound is Random
|
|
for (i=1; i<nFreqs_; i++) {
|
|
inputs_[i] = inputs_[0];
|
|
}
|
|
sndLevel_ *= soundDecay_; // Exponential Sound decay
|
|
finalZ_[2] = finalZ_[1];
|
|
finalZ_[1] = finalZ_[0];
|
|
finalZ_[0] = 0;
|
|
for (i=0;i<nFreqs_;i++) {
|
|
inputs_[i] -= outputs_[i][0]*coeffs_[i][0]; // Do
|
|
inputs_[i] -= outputs_[i][1]*coeffs_[i][1]; // resonant
|
|
outputs_[i][1] = outputs_[i][0]; // filter
|
|
outputs_[i][0] = inputs_[i]; // calculations
|
|
finalZ_[0] += gains_[i] * outputs_[i][1];
|
|
}
|
|
data = finalZCoeffs_[0] * finalZ_[0]; // Extra zero(s) for shape
|
|
data += finalZCoeffs_[1] * finalZ_[1]; // Extra zero(s) for shape
|
|
data += finalZCoeffs_[2] * finalZ_[2]; // Extra zero(s) for shape
|
|
if (data > 10000.0) data = 10000.0;
|
|
if (data < -10000.0) data = -10000.0;
|
|
lastOutput_ = data * 0.0001;
|
|
}
|
|
else lastOutput_ = 0.0;
|
|
}
|
|
|
|
return lastOutput_;
|
|
}
|
|
|
|
StkFloat *Shakers :: tick(StkFloat *vector, unsigned int vectorSize)
|
|
{
|
|
return Instrmnt::tick( vector, vectorSize );
|
|
}
|
|
|
|
StkFrames& Shakers :: tick( StkFrames& frames, unsigned int channel )
|
|
{
|
|
return Instrmnt::tick( frames, channel );
|
|
}
|
|
|
|
void Shakers :: controlChange(int number, StkFloat value)
|
|
{
|
|
StkFloat norm = value * ONE_OVER_128;
|
|
if ( norm < 0 ) {
|
|
norm = 0.0;
|
|
errorString_ << "Shakers::controlChange: control value less than zero ... setting to zero!";
|
|
handleError( StkError::WARNING );
|
|
}
|
|
else if ( norm > 1.0 ) {
|
|
norm = 1.0;
|
|
errorString_ << "Shakers::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
|
handleError( StkError::WARNING );
|
|
}
|
|
|
|
StkFloat temp;
|
|
int i;
|
|
|
|
if (number == __SK_Breath_) { // 2 ... energy
|
|
shakeEnergy_ += norm * MAX_SHAKE * 0.1;
|
|
if (shakeEnergy_ > MAX_SHAKE) shakeEnergy_ = MAX_SHAKE;
|
|
if (instType_==10 || instType_==3) {
|
|
ratchetPos_ = (int) fabs(value - lastRatchetPos_);
|
|
ratchetDelta_ = 0.0002 * ratchetPos_;
|
|
lastRatchetPos_ = (int) value;
|
|
}
|
|
}
|
|
else if (number == __SK_ModFrequency_) { // 4 ... decay
|
|
if (instType_ != 3 && instType_ != 10) {
|
|
systemDecay_ = defDecays_[instType_] + ((value - 64.0) *
|
|
decayScale_[instType_] *
|
|
(1.0 - defDecays_[instType_]) / 64.0 );
|
|
gains_[0] = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
for (i=1;i<nFreqs_;i++) gains_[i] = gains_[0];
|
|
if (instType_ == 6) { // tambourine
|
|
gains_[0] *= TAMB_SHELL_GAIN;
|
|
gains_[1] *= 0.8;
|
|
}
|
|
else if (instType_ == 7) { // sleighbell
|
|
gains_[3] *= 0.5;
|
|
gains_[4] *= 0.3;
|
|
}
|
|
else if (instType_ == 12) { // cokecan
|
|
for (i=1;i<nFreqs_;i++) gains_[i] *= 1.8;
|
|
}
|
|
for (i=0;i<nFreqs_;i++) gains_[i] *= ((128-value)/100.0 + 0.36);
|
|
}
|
|
}
|
|
else if (number == __SK_FootControl_) { // 11 ... number of objects
|
|
if (instType_ == 5) // bamboo
|
|
nObjects_ = (StkFloat) (value * defObjs_[instType_] / 64.0) + 0.3;
|
|
else
|
|
nObjects_ = (StkFloat) (value * defObjs_[instType_] / 64.0) + 1.1;
|
|
gains_[0] = log(nObjects_) * baseGain_ / (StkFloat) nObjects_;
|
|
for (i=1;i<nFreqs_;i++) gains_[i] = gains_[0];
|
|
if (instType_ == 6) { // tambourine
|
|
gains_[0] *= TAMB_SHELL_GAIN;
|
|
gains_[1] *= 0.8;
|
|
}
|
|
else if (instType_ == 7) { // sleighbell
|
|
gains_[3] *= 0.5;
|
|
gains_[4] *= 0.3;
|
|
}
|
|
else if (instType_ == 12) { // cokecan
|
|
for (i=1;i<nFreqs_;i++) gains_[i] *= 1.8;
|
|
}
|
|
if (instType_ != 3 && instType_ != 10) {
|
|
// reverse calculate decay setting
|
|
double temp = (double) (64.0 * (systemDecay_-defDecays_[instType_])/(decayScale_[instType_]*(1-defDecays_[instType_])) + 64.0);
|
|
// scale gains_ by decay setting
|
|
for (i=0;i<nFreqs_;i++) gains_[i] *= ((128-temp)/100.0 + 0.36);
|
|
}
|
|
}
|
|
else if (number == __SK_ModWheel_) { // 1 ... resonance frequency
|
|
for (i=0; i<nFreqs_; i++) {
|
|
if (instType_ == 6 || instType_ == 2 || instType_ == 7) // limit range a bit for tambourine
|
|
temp = center_freqs_[i] * pow (1.008,value-64);
|
|
else
|
|
temp = center_freqs_[i] * pow (1.015,value-64);
|
|
t_center_freqs_[i] = temp;
|
|
|
|
coeffs_[i][0] = -resons_[i] * 2.0 * cos(temp * TWO_PI / Stk::sampleRate());
|
|
coeffs_[i][1] = resons_[i]*resons_[i];
|
|
}
|
|
}
|
|
else if (number == __SK_AfterTouch_Cont_) { // 128
|
|
shakeEnergy_ += norm * MAX_SHAKE * 0.1;
|
|
if (shakeEnergy_ > MAX_SHAKE) shakeEnergy_ = MAX_SHAKE;
|
|
if (instType_==10 || instType_==3) {
|
|
ratchetPos_ = (int) fabs(value - lastRatchetPos_);
|
|
ratchetDelta_ = 0.0002 * ratchetPos_;
|
|
lastRatchetPos_ = (int) value;
|
|
}
|
|
}
|
|
else if (number == __SK_ShakerInst_) { // 1071
|
|
instType_ = (int) (value + 0.5); // Just to be safe
|
|
this->setupNum(instType_);
|
|
}
|
|
else {
|
|
errorString_ << "Shakers::controlChange: undefined control number (" << number << ")!";
|
|
handleError( StkError::WARNING );
|
|
}
|
|
|
|
#if defined(_STK_DEBUG_)
|
|
errorString_ << "Shakers::controlChange: number = " << number << ", value = " << value << '.';
|
|
handleError( StkError::DEBUG_WARNING );
|
|
#endif
|
|
}
|
|
|
|
// KLUDGE-O-MATIC-O-RAMA
|
|
|
|
StkFloat Shakers :: wuter_tick() {
|
|
StkFloat data;
|
|
int j;
|
|
shakeEnergy_ *= systemDecay_; // Exponential system decay
|
|
if (my_random(32767) < nObjects_) {
|
|
sndLevel_ = shakeEnergy_;
|
|
j = my_random(3);
|
|
if (j == 0) {
|
|
center_freqs_[0] = WUTR_CENTER_FREQ1 * (0.75 + (0.25 * noise_tick()));
|
|
gains_[0] = fabs(noise_tick());
|
|
}
|
|
else if (j == 1) {
|
|
center_freqs_[1] = WUTR_CENTER_FREQ1 * (1.0 + (0.25 * noise_tick()));
|
|
gains_[1] = fabs(noise_tick());
|
|
}
|
|
else {
|
|
center_freqs_[2] = WUTR_CENTER_FREQ1 * (1.25 + (0.25 * noise_tick()));
|
|
gains_[2] = fabs(noise_tick());
|
|
}
|
|
}
|
|
|
|
gains_[0] *= resons_[0];
|
|
if (gains_[0] > 0.001) {
|
|
center_freqs_[0] *= WUTR_FREQ_SWEEP;
|
|
coeffs_[0][0] = -resons_[0] * 2.0 *
|
|
cos(center_freqs_[0] * TWO_PI / Stk::sampleRate());
|
|
}
|
|
gains_[1] *= resons_[1];
|
|
if (gains_[1] > 0.001) {
|
|
center_freqs_[1] *= WUTR_FREQ_SWEEP;
|
|
coeffs_[1][0] = -resons_[1] * 2.0 *
|
|
cos(center_freqs_[1] * TWO_PI / Stk::sampleRate());
|
|
}
|
|
gains_[2] *= resons_[2];
|
|
if (gains_[2] > 0.001) {
|
|
center_freqs_[2] *= WUTR_FREQ_SWEEP;
|
|
coeffs_[2][0] = -resons_[2] * 2.0 *
|
|
cos(center_freqs_[2] * TWO_PI / Stk::sampleRate());
|
|
}
|
|
|
|
sndLevel_ *= soundDecay_; // Each (all) event(s)
|
|
// decay(s) exponentially
|
|
inputs_[0] = sndLevel_;
|
|
inputs_[0] *= noise_tick(); // Actual Sound is Random
|
|
inputs_[1] = inputs_[0] * gains_[1];
|
|
inputs_[2] = inputs_[0] * gains_[2];
|
|
inputs_[0] *= gains_[0];
|
|
inputs_[0] -= outputs_[0][0]*coeffs_[0][0];
|
|
inputs_[0] -= outputs_[0][1]*coeffs_[0][1];
|
|
outputs_[0][1] = outputs_[0][0];
|
|
outputs_[0][0] = inputs_[0];
|
|
data = gains_[0]*outputs_[0][0];
|
|
inputs_[1] -= outputs_[1][0]*coeffs_[1][0];
|
|
inputs_[1] -= outputs_[1][1]*coeffs_[1][1];
|
|
outputs_[1][1] = outputs_[1][0];
|
|
outputs_[1][0] = inputs_[1];
|
|
data += gains_[1]*outputs_[1][0];
|
|
inputs_[2] -= outputs_[2][0]*coeffs_[2][0];
|
|
inputs_[2] -= outputs_[2][1]*coeffs_[2][1];
|
|
outputs_[2][1] = outputs_[2][0];
|
|
outputs_[2][0] = inputs_[2];
|
|
data += gains_[2]*outputs_[2][0];
|
|
|
|
finalZ_[2] = finalZ_[1];
|
|
finalZ_[1] = finalZ_[0];
|
|
finalZ_[0] = data * 4;
|
|
|
|
data = finalZ_[2] - finalZ_[0];
|
|
return data;
|
|
}
|
|
|
|
StkFloat Shakers :: ratchet_tick() {
|
|
StkFloat data;
|
|
if (my_random(1024) < nObjects_) {
|
|
sndLevel_ += 512 * ratchet_ * totalEnergy_;
|
|
}
|
|
inputs_[0] = sndLevel_;
|
|
inputs_[0] *= noise_tick() * ratchet_;
|
|
sndLevel_ *= soundDecay_;
|
|
|
|
inputs_[1] = inputs_[0];
|
|
inputs_[0] -= outputs_[0][0]*coeffs_[0][0];
|
|
inputs_[0] -= outputs_[0][1]*coeffs_[0][1];
|
|
outputs_[0][1] = outputs_[0][0];
|
|
outputs_[0][0] = inputs_[0];
|
|
inputs_[1] -= outputs_[1][0]*coeffs_[1][0];
|
|
inputs_[1] -= outputs_[1][1]*coeffs_[1][1];
|
|
outputs_[1][1] = outputs_[1][0];
|
|
outputs_[1][0] = inputs_[1];
|
|
|
|
finalZ_[2] = finalZ_[1];
|
|
finalZ_[1] = finalZ_[0];
|
|
finalZ_[0] = gains_[0]*outputs_[0][1] + gains_[1]*outputs_[1][1];
|
|
data = finalZ_[0] - finalZ_[2];
|
|
return data;
|
|
}
|
|
|
|
StkFloat Shakers :: tbamb_tick() {
|
|
StkFloat data, temp;
|
|
static int which = 0;
|
|
int i;
|
|
|
|
if (shakeEnergy_ > MIN_ENERGY) {
|
|
shakeEnergy_ *= systemDecay_; // Exponential system decay
|
|
if (float_random(1024.0) < nObjects_) {
|
|
sndLevel_ += shakeEnergy_;
|
|
which = my_random(7);
|
|
}
|
|
temp = sndLevel_ * noise_tick(); // Actual Sound is Random
|
|
for (i=0;i<nFreqs_;i++) inputs_[i] = 0;
|
|
inputs_[which] = temp;
|
|
sndLevel_ *= soundDecay_; // Exponential Sound decay
|
|
finalZ_[2] = finalZ_[1];
|
|
finalZ_[1] = finalZ_[0];
|
|
finalZ_[0] = 0;
|
|
for (i=0;i<nFreqs_;i++) {
|
|
inputs_[i] -= outputs_[i][0]*coeffs_[i][0]; // Do
|
|
inputs_[i] -= outputs_[i][1]*coeffs_[i][1]; // resonant
|
|
outputs_[i][1] = outputs_[i][0]; // filter
|
|
outputs_[i][0] = inputs_[i]; // calculations
|
|
finalZ_[0] += gains_[i] * outputs_[i][1];
|
|
}
|
|
data = finalZCoeffs_[0] * finalZ_[0]; // Extra zero(s) for shape
|
|
data += finalZCoeffs_[1] * finalZ_[1]; // Extra zero(s) for shape
|
|
data += finalZCoeffs_[2] * finalZ_[2]; // Extra zero(s) for shape
|
|
if (data > 10000.0) data = 10000.0;
|
|
if (data < -10000.0) data = -10000.0;
|
|
data = data * 0.0001;
|
|
}
|
|
else data = 0.0;
|
|
return data;
|
|
}
|