Files
stk/include/Shakers.h
Gary Scavone 0aec39260a Version 4.4.3
2013-09-29 23:21:29 +02:00

169 lines
4.7 KiB
C++

#ifndef STK_SHAKERS_H
#define STK_SHAKERS_H
#include "Instrmnt.h"
namespace stk {
/***************************************************/
/*! \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, 1995-2011.
*/
/***************************************************/
const int MAX_FREQS = 8;
const int NUM_INSTR = 24;
class Shakers : public Instrmnt
{
public:
//! Class constructor.
Shakers( void );
//! Class destructor.
~Shakers( void );
//! Start a note with the given instrument and amplitude.
/*!
Use the instrument numbers above, converted to frequency values
as if MIDI note numbers, to select a particular instrument.
*/
void noteOn( StkFloat instrument, StkFloat amplitude );
//! Stop a note with the given amplitude (speed of decay).
void noteOff( StkFloat amplitude );
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
void controlChange( int number, StkFloat value );
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
int setupName( char* instr );
int setupNum( int inst );
int setFreqAndReson( int which, StkFloat freq, StkFloat reson );
void setDecays( StkFloat sndDecay, StkFloat sysDecay );
void setFinalZs( StkFloat z0, StkFloat z1, StkFloat z2 );
StkFloat wuter_tick( void );
StkFloat tbamb_tick( void );
StkFloat ratchet_tick( void );
int instType_;
int ratchetPos_, lastRatchetPos_;
StkFloat shakeEnergy_;
StkFloat inputs_[MAX_FREQS];
StkFloat outputs_[MAX_FREQS][2];
StkFloat coeffs_[MAX_FREQS][2];
StkFloat sndLevel_;
StkFloat baseGain_;
StkFloat gains_[MAX_FREQS];
int nFreqs_;
StkFloat t_center_freqs_[MAX_FREQS];
StkFloat center_freqs_[MAX_FREQS];
StkFloat resons_[MAX_FREQS];
StkFloat freq_rand_[MAX_FREQS];
int freqalloc_[MAX_FREQS];
StkFloat soundDecay_;
StkFloat systemDecay_;
StkFloat nObjects_;
StkFloat totalEnergy_;
StkFloat ratchet_, ratchetDelta_;
StkFloat finalZ_[3];
StkFloat finalZCoeffs_[3];
StkFloat defObjs_[NUM_INSTR];
StkFloat defDecays_[NUM_INSTR];
StkFloat decayScale_[NUM_INSTR];
};
inline StkFrames& Shakers :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Shakers::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif