/***************************************************/ /*! \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 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; isetupNum(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;isetupNum(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;isetDecays(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 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 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 10000.0) data = 10000.0; if (data < -10000.0) data = -10000.0; data = data * 0.0001; } else data = 0.0; return data; }