diff options
author | Steve M. Robbins <smr@debian.org> | 2011-10-22 04:54:51 +0200 |
---|---|---|
committer | Steve M. Robbins <smr@debian.org> | 2011-10-22 04:54:51 +0200 |
commit | dd657ad3f1428b026486db3ec36691df17ddf515 (patch) | |
tree | 6ffb465595479fb5a76c1a6ea3ec992abaa8c1c1 /nyqstk/include |
Import nyquist_3.05.orig.tar.gz
[dgit import orig nyquist_3.05.orig.tar.gz]
Diffstat (limited to 'nyqstk/include')
41 files changed, 3739 insertions, 0 deletions
diff --git a/nyqstk/include/ADSR.h b/nyqstk/include/ADSR.h new file mode 100644 index 0000000..521514d --- /dev/null +++ b/nyqstk/include/ADSR.h @@ -0,0 +1,90 @@ +/***************************************************/ +/*! \class ADSR + \brief STK ADSR envelope class. + + This Envelope subclass implements a + traditional ADSR (Attack, Decay, + Sustain, Release) envelope. It + responds to simple keyOn and keyOff + messages, keeping track of its state. + The \e state = ADSR::DONE after the + envelope value reaches 0.0 in the + ADSR::RELEASE state. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_ADSR_H +#define STK_ADSR_H + +#include "Envelope.h" + +namespace Nyq +{ + +class ADSR : public Envelope +{ + public: + + //! Envelope states. + enum { ATTACK, DECAY, SUSTAIN, RELEASE, DONE }; + + //! Default constructor. + ADSR(void); + + //! Class destructor. + ~ADSR(void); + + //! Set target = 1, state = \e ADSR::ATTACK. + void keyOn(void); + + //! Set target = 0, state = \e ADSR::RELEASE. + void keyOff(void); + + //! Set the attack rate. + void setAttackRate(StkFloat rate); + + //! Set the decay rate. + void setDecayRate(StkFloat rate); + + //! Set the sustain level. + void setSustainLevel(StkFloat level); + + //! Set the release rate. + void setReleaseRate(StkFloat rate); + + //! Set the attack rate based on a time duration. + void setAttackTime(StkFloat time); + + //! Set the decay rate based on a time duration. + void setDecayTime(StkFloat time); + + //! Set the release rate based on a time duration. + void setReleaseTime(StkFloat time); + + //! Set sustain level and attack, decay, and release time durations. + void setAllTimes(StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime); + + //! Set the target value. + void setTarget(StkFloat target); + + //! Return the current envelope \e state (ATTACK, DECAY, SUSTAIN, RELEASE, DONE). + int getState(void) const; + + //! Set to state = ADSR::SUSTAIN with current and target values of \e aValue. + void setValue(StkFloat value); + + protected: + + StkFloat computeSample( void ); + + StkFloat attackRate_; + StkFloat decayRate_; + StkFloat sustainLevel_; + StkFloat releaseRate_; +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/BandedWG.h b/nyqstk/include/BandedWG.h new file mode 100644 index 0000000..9323a3e --- /dev/null +++ b/nyqstk/include/BandedWG.h @@ -0,0 +1,121 @@ +/***************************************************/ +/*! \class BandedWG + \brief Banded waveguide modeling class. + + This class uses banded waveguide techniques to + model a variety of sounds, including bowed + bars, glasses, and bowls. For more + information, see Essl, G. and Cook, P. "Banded + Waveguides: Towards Physical Modelling of Bar + Percussion Instruments", Proceedings of the + 1999 International Computer Music Conference. + + Control Change Numbers: + - Bow Pressure = 2 + - Bow Motion = 4 + - Strike Position = 8 (not implemented) + - Vibrato Frequency = 11 + - Gain = 1 + - Bow Velocity = 128 + - Set Striking = 64 + - Instrument Presets = 16 + - Uniform Bar = 0 + - Tuned Bar = 1 + - Glass Harmonica = 2 + - Tibetan Bowl = 3 + + by Georg Essl, 1999 - 2004. + Modified for Stk 4.0 by Gary Scavone. +*/ +/***************************************************/ + +#ifndef STK_BANDEDWG_H +#define STK_BANDEDWG_H + +namespace Nyq +{ + +const int MAX_BANDED_MODES = 20; + +} // namespace Nyq + +#include "Instrmnt.h" +#include "DelayL.h" +#include "BowTable.h" +#include "ADSR.h" +#include "BiQuad.h" + +namespace Nyq +{ + +class BandedWG : public Instrmnt +{ + public: + //! Class constructor. + BandedWG(); + + //! Class destructor. + ~BandedWG(); + + //! Reset and clear all internal state. + void clear(); + + //! Set strike position (0.0 - 1.0). + void setStrikePosition(StkFloat position); + + //! Select a preset. + void setPreset(int preset); + + //! Set instrument parameters for a particular frequency. + void setFrequency(StkFloat frequency); + + //! Apply bow velocity/pressure to instrument with given amplitude and rate of increase. + void startBowing(StkFloat amplitude, StkFloat rate); + + //! Decrease bow velocity/breath pressure with given rate of decrease. + void stopBowing(StkFloat rate); + + //! Pluck the instrument with given amplitude. + void pluck(StkFloat amp); + + //! Start a note with the given frequency and amplitude. + void noteOn(StkFloat frequency, 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); + + protected: + + StkFloat computeSample( void ); + + bool doPluck_; + bool trackVelocity_; + int nModes_; + int presetModes_; + BowTable bowTable_; + ADSR adsr_; + BiQuad bandpass_[MAX_BANDED_MODES]; + DelayL delay_[MAX_BANDED_MODES]; + StkFloat maxVelocity_; + StkFloat modes_[MAX_BANDED_MODES]; + StkFloat frequency_; + StkFloat baseGain_; + StkFloat gains_[MAX_BANDED_MODES]; + StkFloat basegains_[MAX_BANDED_MODES]; + StkFloat excitation_[MAX_BANDED_MODES]; + StkFloat integrationConstant_; + StkFloat velocityInput_; + StkFloat bowVelocity_; + StkFloat bowTarget_; + StkFloat bowPosition_; + StkFloat strikeAmp_; + int strikePosition_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/BiQuad.h b/nyqstk/include/BiQuad.h new file mode 100644 index 0000000..d4e6cc8 --- /dev/null +++ b/nyqstk/include/BiQuad.h @@ -0,0 +1,117 @@ +/***************************************************/ +/*! \class BiQuad + \brief STK biquad (two-pole, two-zero) filter class. + + This protected Filter subclass implements a + two-pole, two-zero digital filter. A method + is provided for creating a resonance in the + frequency response while maintaining a constant + filter gain. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_BIQUAD_H +#define STK_BIQUAD_H + +#include "Filter.h" + +namespace Nyq +{ + +class BiQuad : protected Filter +{ +public: + + //! Default constructor creates a second-order pass-through filter. + BiQuad(); + + //! Class destructor. + virtual ~BiQuad(); + + //! Clears all internal states of the filter. + void clear(void); + + //! Set the b[0] coefficient value. + void setB0(StkFloat b0); + + //! Set the b[1] coefficient value. + void setB1(StkFloat b1); + + //! Set the b[2] coefficient value. + void setB2(StkFloat b2); + + //! Set the a[1] coefficient value. + void setA1(StkFloat a1); + + //! Set the a[2] coefficient value. + void setA2(StkFloat a2); + + //! Sets the filter coefficients for a resonance at \e frequency (in Hz). + /*! + This method determines the filter coefficients corresponding to + two complex-conjugate poles with the given \e frequency (in Hz) + and \e radius from the z-plane origin. If \e normalize is true, + the filter zeros are placed at z = 1, z = -1, and the coefficients + are then normalized to produce a constant unity peak gain + (independent of the filter \e gain parameter). The resulting + filter frequency response has a resonance at the given \e + frequency. The closer the poles are to the unit-circle (\e radius + close to one), the narrower the resulting resonance width. + */ + void setResonance(StkFloat frequency, StkFloat radius, bool normalize = false); + + //! Set the filter coefficients for a notch at \e frequency (in Hz). + /*! + This method determines the filter coefficients corresponding to + two complex-conjugate zeros with the given \e frequency (in Hz) + and \e radius from the z-plane origin. No filter normalization + is attempted. + */ + void setNotch(StkFloat frequency, StkFloat radius); + + //! Sets the filter zeroes for equal resonance gain. + /*! + When using the filter as a resonator, zeroes places at z = 1, z + = -1 will result in a constant gain at resonance of 1 / (1 - R), + where R is the pole radius setting. + + */ + void setEqualGainZeroes(); + + //! Set the filter gain. + /*! + The gain is applied at the filter input and does not affect the + coefficient values. The default gain value is 1.0. + */ + void setGain(StkFloat gain); + + //! Return the current filter gain. + StkFloat getGain(void) const; + + //! Return the last computed output value. + StkFloat lastOut(void) const; + + //! Input one sample to the filter and return one output. + virtual StkFloat tick(StkFloat sample); + + //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs. + /*! + The \c channel argument should be zero or greater (the first + channel is specified by 0). An StkError will be thrown if the \c + channel argument is equal to or greater than the number of + channels in the StkFrames object. + */ + virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); + + protected: + + // This function must be implemented in all subclasses. It is used + // to get around a C++ problem with overloaded virtual functions. + virtual StkFloat computeSample( StkFloat input ); +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/BowTable.h b/nyqstk/include/BowTable.h new file mode 100644 index 0000000..6604176 --- /dev/null +++ b/nyqstk/include/BowTable.h @@ -0,0 +1,56 @@ +/***************************************************/ +/*! \class BowTable + \brief STK bowed string table class. + + This class implements a simple bowed string + non-linear function, as described by Smith (1986). + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_BOWTABL_H +#define STK_BOWTABL_H + +#include "Function.h" + +namespace Nyq +{ + +class BowTable : public Function +{ +public: + //! Default constructor. + BowTable(); + + //! Class destructor. + ~BowTable(); + + //! Set the table offset value. + /*! + The table offset is a bias which controls the + symmetry of the friction. If you want the + friction to vary with direction, use a non-zero + value for the offset. The default value is zero. + */ + void setOffset(StkFloat offset); + + //! Set the table slope value. + /*! + The table slope controls the width of the friction + pulse, which is related to bow force. + */ + void setSlope(StkFloat slope); + +protected: + + StkFloat computeSample( StkFloat input ); + + StkFloat offset_; + StkFloat slope_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/Bowed.h b/nyqstk/include/Bowed.h new file mode 100644 index 0000000..a4551f7 --- /dev/null +++ b/nyqstk/include/Bowed.h @@ -0,0 +1,91 @@ +/***************************************************/ +/*! \class Bowed + \brief STK bowed string instrument class. + + This class implements a bowed string model, a + la Smith (1986), after McIntyre, Schumacher, + Woodhouse (1983). + + This is a digital waveguide model, making its + use possibly subject to patents held by + Stanford University, Yamaha, and others. + + Control Change Numbers: + - Bow Pressure = 2 + - Bow Position = 4 + - Vibrato Frequency = 11 + - Vibrato Gain = 1 + - Volume = 128 + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_BOWED_H +#define STK_BOWED_H + +#include "Instrmnt.h" +#include "DelayL.h" +#include "BowTable.h" +#include "OnePole.h" +#include "BiQuad.h" +#include "SineWave.h" +#include "ADSR.h" + +namespace Nyq +{ + +class Bowed : public Instrmnt +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + Bowed(StkFloat lowestFrequency); + + //! Class destructor. + ~Bowed(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(StkFloat frequency); + + //! Set vibrato gain. + void setVibrato(StkFloat gain); + + //! Apply breath pressure to instrument with given amplitude and rate of increase. + void startBowing(StkFloat amplitude, StkFloat rate); + + //! Decrease breath pressure with given rate of decrease. + void stopBowing(StkFloat rate); + + //! Start a note with the given frequency and amplitude. + void noteOn(StkFloat frequency, 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); + + protected: + + StkFloat computeSample( void ); + + DelayL neckDelay_; + DelayL bridgeDelay_; + BowTable bowTable_; + OnePole stringFilter_; + BiQuad bodyFilter_; + SineWave vibrato_; + ADSR adsr_; + StkFloat maxVelocity_; + StkFloat baseDelay_; + StkFloat vibratoGain_; + StkFloat betaRatio_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/Chorus.h b/nyqstk/include/Chorus.h new file mode 100644 index 0000000..5da10e1 --- /dev/null +++ b/nyqstk/include/Chorus.h @@ -0,0 +1,56 @@ +/***************************************************/ +/*! \class Chorus + \brief STK chorus effect class. + + This class implements a chorus effect. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_CHORUS_H +#define STK_CHORUS_H + +#include "Effect.h" +#include "DelayL.h" +#include "SineWave.h" + +namespace Nyq +{ + +class Chorus : public Effect +{ + public: + //! Class constructor, taking the median desired delay length. + /*! + An StkError can be thrown if the rawwave path is incorrect. + */ + Chorus( StkFloat baseDelay = 6000 ); + + //! Class destructor. + ~Chorus(); + + //! Reset and clear all internal state. + void clear(); + + //! Set modulation depth. + void setModDepth(StkFloat depth); + + //! Set modulation frequency. + void setModFrequency(StkFloat frequency); + + protected: + + StkFloat computeSample( StkFloat input ); + + DelayL delayLine_[2]; + SineWave mods_[2]; + StkFloat baseLength_; + StkFloat modDepth_; + +}; + +} // namespace Nyq + +#endif + diff --git a/nyqstk/include/Clarinet.h b/nyqstk/include/Clarinet.h new file mode 100644 index 0000000..fb7d43d --- /dev/null +++ b/nyqstk/include/Clarinet.h @@ -0,0 +1,91 @@ +/***************************************************/ +/*! \class Clarinet + \brief STK clarinet physical model class. + + This class implements a simple clarinet + physical model, as discussed by Smith (1986), + McIntyre, Schumacher, Woodhouse (1983), and + others. + + This is a digital waveguide model, making its + use possibly subject to patents held by Stanford + University, Yamaha, and others. + + Control Change Numbers: + - Reed Stiffness = 2 + - Noise Gain = 4 + - Vibrato Frequency = 11 + - Vibrato Gain = 1 + - Breath Pressure = 128 + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_CLARINET_H +#define STK_CLARINET_H + +#include "Instrmnt.h" +#include "DelayL.h" +#include "ReedTable.h" +#include "OneZero.h" +#include "Envelope.h" +#include "Noise.h" +#include "SineWave.h" + +namespace Nyq +{ + +class Clarinet : public Instrmnt +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + /*! + An StkError will be thrown if the rawwave path is incorrectly set. + */ + Clarinet(StkFloat lowestFrequency); + + //! Class destructor. + ~Clarinet(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(StkFloat frequency); + + //! Apply breath pressure to instrument with given amplitude and rate of increase. + void startBlowing(StkFloat amplitude, StkFloat rate); + + //! Decrease breath pressure with given rate of decrease. + void stopBlowing(StkFloat rate); + + //! Start a note with the given frequency and amplitude. + void noteOn(StkFloat frequency, 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); + + protected: + + StkFloat computeSample( void ); + + DelayL delayLine_; + ReedTable reedTable_; + OneZero filter_; + Envelope envelope_; + Noise noise_; + SineWave vibrato_; + long length_; + StkFloat outputGain_; + StkFloat noiseGain_; + StkFloat vibratoGain_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/Delay.h b/nyqstk/include/Delay.h new file mode 100644 index 0000000..413944c --- /dev/null +++ b/nyqstk/include/Delay.h @@ -0,0 +1,115 @@ +/***************************************************/ +/*! \class Delay + \brief STK non-interpolating delay line class. + + This protected Filter subclass implements + a non-interpolating digital delay-line. + A fixed maximum length of 4095 and a delay + of zero is set using the default constructor. + Alternatively, the delay and maximum length + can be set during instantiation with an + overloaded constructor. + + A non-interpolating delay line is typically + used in fixed delay-length applications, such + as for reverberation. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_DELAY_H +#define STK_DELAY_H + +#include "Filter.h" + +namespace Nyq +{ + +class Delay : protected Filter +{ +public: + + //! Default constructor creates a delay-line with maximum length of 4095 samples and zero delay. + Delay(); + + //! Overloaded constructor which specifies the current and maximum delay-line lengths. + /*! + An StkError will be thrown if the delay parameter is less than + zero, the maximum delay parameter is less than one, or the delay + parameter is greater than the maxDelay value. + */ + Delay(unsigned long delay, unsigned long maxDelay); + + //! Class destructor. + virtual ~Delay(); + + //! Clears the internal state of the delay line. + void clear(); + + //! Set the maximum delay-line length. + /*! + This method should generally only be used during initial setup + of the delay line. If it is used between calls to the tick() + function, without a call to clear(), a signal discontinuity will + likely occur. If the current maximum length is greater than the + new length, no change will be made. + */ + void setMaximumDelay(unsigned long delay); + + //! Set the delay-line length. + /*! + The valid range for \e theDelay is from 0 to the maximum delay-line length. + */ + void setDelay(unsigned long delay); + + //! Return the current delay-line length. + unsigned long getDelay(void) const; + + //! Calculate and return the signal energy in the delay-line. + StkFloat energy(void) const; + + //! Return the value at \e tapDelay samples from the delay-line input. + /*! + The tap point is determined modulo the delay-line length and is + relative to the last input value (i.e., a tapDelay of zero returns + the last input value). + */ + StkFloat contentsAt(unsigned long tapDelay); + + //! Return the last computed output value. + StkFloat lastOut(void) const; + + //! Return the value which will be output by the next call to tick(). + /*! + This method is valid only for delay settings greater than zero! + */ + virtual StkFloat nextOut(void); + + //! Input one sample to the filter and return one output. + virtual StkFloat tick(StkFloat sample); + + //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs. + /*! + The \c channel argument should be zero or greater (the first + channel is specified by 0). An StkError will be thrown if the \c + channel argument is equal to or greater than the number of + channels in the StkFrames object. + */ + virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); + +protected: + + // This function must be implemented in all subclasses. It is used + // to get around a C++ problem with overloaded virtual functions. + virtual StkFloat computeSample( StkFloat input ); + + unsigned long inPoint_; + unsigned long outPoint_; + StkFloat delay_; +}; + +} // namespace Nyq + +#endif + diff --git a/nyqstk/include/DelayA.h b/nyqstk/include/DelayA.h new file mode 100644 index 0000000..4f17527 --- /dev/null +++ b/nyqstk/include/DelayA.h @@ -0,0 +1,79 @@ +/***************************************************/ +/*! \class DelayA + \brief STK allpass interpolating delay line class. + + This Delay subclass implements a fractional-length digital + delay-line using a first-order allpass filter. A fixed maximum + length of 4095 and a delay of 0.5 is set using the default + constructor. Alternatively, the delay and maximum length can be + set during instantiation with an overloaded constructor. + + An allpass filter has unity magnitude gain but variable phase + delay properties, making it useful in achieving fractional delays + without affecting a signal's frequency magnitude response. In + order to achieve a maximally flat phase delay response, the + minimum delay possible in this implementation is limited to a + value of 0.5. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_DELAYA_H +#define STK_DELAYA_H + +#include "Delay.h" + +namespace Nyq +{ + +class DelayA : public Delay +{ +public: + + //! Default constructor creates a delay-line with maximum length of 4095 samples and zero delay. + DelayA(); + + //! Overloaded constructor which specifies the current and maximum delay-line lengths. + /*! + An StkError will be thrown if the delay parameter is less than + zero, the maximum delay parameter is less than one, or the delay + parameter is greater than the maxDelay value. + */ + DelayA(StkFloat delay, unsigned long maxDelay); + + //! Class destructor. + ~DelayA(); + + //! Clears the internal state of the delay line. + void clear(); + + //! Set the delay-line length + /*! + The valid range for \e theDelay is from 0.5 to the maximum delay-line length. + */ + void setDelay(StkFloat delay); + + //! Return the current delay-line length. + StkFloat getDelay(void) const; + + //! Return the value which will be output by the next call to tick(). + /*! + This method is valid only for delay settings greater than zero! + */ + StkFloat nextOut(void); + +protected: + + StkFloat computeSample( StkFloat input ); + + StkFloat alpha_; + StkFloat coeff_; + StkFloat apInput_; + StkFloat nextOutput_; + bool doNextOut_; +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/DelayL.h b/nyqstk/include/DelayL.h new file mode 100644 index 0000000..fa97581 --- /dev/null +++ b/nyqstk/include/DelayL.h @@ -0,0 +1,78 @@ +/***************************************************/ +/*! \class DelayL + \brief STK linear interpolating delay line class. + + This Delay subclass implements a fractional- + length digital delay-line using first-order + linear interpolation. A fixed maximum length + of 4095 and a delay of zero is set using the + default constructor. Alternatively, the + delay and maximum length can be set during + instantiation with an overloaded constructor. + + Linear interpolation is an efficient technique + for achieving fractional delay lengths, though + it does introduce high-frequency signal + attenuation to varying degrees depending on the + fractional delay setting. The use of higher + order Lagrange interpolators can typically + improve (minimize) this attenuation characteristic. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_DELAYL_H +#define STK_DELAYL_H + +#include "Delay.h" + +namespace Nyq +{ + +class DelayL : public Delay +{ +public: + + //! Default constructor creates a delay-line with maximum length of 4095 samples and zero delay. + DelayL(); + + //! Overloaded constructor which specifies the current and maximum delay-line lengths. + /*! + An StkError will be thrown if the delay parameter is less than + zero, the maximum delay parameter is less than one, or the delay + parameter is greater than the maxDelay value. + */ + DelayL(StkFloat delay, unsigned long maxDelay); + + //! Class destructor. + ~DelayL(); + + //! Set the delay-line length. + /*! + The valid range for \e theDelay is from 0 to the maximum delay-line length. + */ + void setDelay(StkFloat delay); + + //! Return the current delay-line length. + StkFloat getDelay(void) const; + + //! Return the value which will be output by the next call to tick(). + /*! + This method is valid only for delay settings greater than zero! + */ + StkFloat nextOut(void); + + protected: + + StkFloat computeSample( StkFloat input ); + + StkFloat alpha_; + StkFloat omAlpha_; + StkFloat nextOutput_; + bool doNextOut_; +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/Effect.h b/nyqstk/include/Effect.h new file mode 100644 index 0000000..812e50a --- /dev/null +++ b/nyqstk/include/Effect.h @@ -0,0 +1,74 @@ +/***************************************************/ +/*! \class Effect + \brief STK abstract effects parent class. + + This class provides common functionality for + STK effects subclasses. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#include "Stk.h" + +#ifndef STK_EFFECT_H +#define STK_EFFECT_H + +namespace Nyq +{ + +class Effect : public Stk +{ + public: + //! Class constructor. + Effect(); + + //! Class destructor. + virtual ~Effect(); + + //! Reset and clear all internal state. + virtual void clear() = 0; + + //! Set the mixture of input and "effected" levels in the output (0.0 = input only, 1.0 = reverb only). + void setEffectMix(StkFloat mix); + + //! Return the last output value. + StkFloat lastOut() const; + + //! Return the last left output value. + StkFloat lastOutLeft() const; + + //! Return the last right output value. + StkFloat lastOutRight() const; + + //! Take one sample input and compute one sample of output. + StkFloat tick( StkFloat input ); + + //! Take a channel of the StkFrames object as inputs to the effect and replace with corresponding outputs. + /*! + The \c channel argument should be zero or greater (the first + channel is specified by 0). An StkError will be thrown if the \c + channel argument is equal to or greater than the number of + channels in the StkFrames object. + */ + StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); + + protected: + + // This abstract function must be implemented in all subclasses. + // It is used to get around a C++ problem with overloaded virtual + // functions. + virtual StkFloat computeSample( StkFloat input ) = 0; + + // Returns true if argument value is prime. + bool isPrime( int number ); + + StkFloat lastOutput_[2]; + StkFloat effectMix_; + +}; + +} // namespace Nyq + +#endif + diff --git a/nyqstk/include/Envelope.h b/nyqstk/include/Envelope.h new file mode 100644 index 0000000..a005768 --- /dev/null +++ b/nyqstk/include/Envelope.h @@ -0,0 +1,73 @@ +/***************************************************/ +/*! \class Envelope + \brief STK envelope base class. + + This class implements a simple envelope + generator which is capable of ramping to + a target value by a specified \e rate. + It also responds to simple \e keyOn and + \e keyOff messages, ramping to 1.0 on + keyOn and to 0.0 on keyOff. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_ENVELOPE_H +#define STK_ENVELOPE_H + +#include "Generator.h" + +namespace Nyq +{ + +class Envelope : public Generator +{ + public: + + //! Default constructor. + Envelope(void); + + //! Copy constructor. + Envelope( const Envelope& e ); + + //! Class destructor. + virtual ~Envelope(void); + + //! Assignment operator. + Envelope& operator= ( const Envelope& e ); + + //! Set target = 1. + virtual void keyOn(void); + + //! Set target = 0. + virtual void keyOff(void); + + //! Set the \e rate. + void setRate(StkFloat rate); + + //! Set the \e rate based on a time duration. + void setTime(StkFloat time); + + //! Set the target value. + virtual void setTarget(StkFloat target); + + //! Set current and target values to \e aValue. + virtual void setValue(StkFloat value); + + //! Return the current envelope \e state (0 = at target, 1 otherwise). + virtual int getState(void) const; + + protected: + + virtual StkFloat computeSample( void ); + + StkFloat value_; + StkFloat target_; + StkFloat rate_; + int state_; +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/FileRead.h b/nyqstk/include/FileRead.h new file mode 100644 index 0000000..6ecc7ae --- /dev/null +++ b/nyqstk/include/FileRead.h @@ -0,0 +1,129 @@ +/***************************************************/ +/*! \class FileRead + \brief STK audio file input class. + + This class provides input support for various + audio file formats. Multi-channel (>2) + soundfiles are supported. The file data is + returned via an external StkFrames object + passed to the read() function. This class + does not store its own copy of the file data, + rather the data is read directly from disk. + + FileRead currently supports uncompressed WAV, + AIFF/AIFC, SND (AU), MAT-file (Matlab), and + STK RAW file formats. Signed integer (8-, + 16-, and 32-bit) and floating-point (32- and + 64-bit) data types are supported. Compressed + data types are not supported. + + STK RAW files have no header and are assumed + to contain a monophonic stream of 16-bit + signed integers in big-endian byte order at a + sample rate of 22050 Hz. MAT-file data should + be saved in an array with each data channel + filling a matrix row. The sample rate for + MAT-files is assumed to be 44100 Hz. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_FILEREAD_H +#define STK_FILEREAD_H + +#include "Stk.h" + +namespace Nyq +{ + +class FileRead : public Stk +{ +public: + //! Default constructor. + FileRead(); + + //! Overloaded constructor that opens a file during instantiation. + /*! + An StkError will be thrown if the file is not found or its + format is unknown or unsupported. + */ + FileRead( std::string fileName, bool typeRaw = false ); + + //! Class destructor. + ~FileRead(); + + //! Open the specified file and determine its formatting. + /*! + An StkError will be thrown if the file is not found or its + format is unknown or unsupported. An optional parameter is + provided to specify whether the input file is of type STK RAW + (default = false). + */ + void open( std::string fileName, bool typeRaw = false ); + + //! If a file is open, close it. + void close( void ); + + //! Returns \e true if a file is currently open. + bool isOpen( void ); + + //! Return the file size in sample frames. + unsigned long fileSize( void ) const { return fileSize_; }; + + //! Return the number of audio channels in the file. + unsigned int channels( void ) const { return channels_; }; + + //! Return the file sample rate in Hz. + /*! + WAV, SND, and AIF formatted files specify a sample rate in + their headers. By definition, STK RAW files have a sample rate of + 22050 Hz. MAT-files are assumed to have a rate of 44100 Hz. + */ + StkFloat fileRate( void ) const { return fileRate_; }; + + //! Read sample frames from the file into an StkFrames object. + /*! + The number of sample frames to read will be determined from the + number of frames of the StkFrames argument. If this size is + larger than the available data in the file (given the file size + and starting frame index), the extra frames will be unaffected + (the StkFrames object will not be resized). Optional parameters + are provided to specify the starting sample frame within the file + (default = 0) and whether to normalize the data with respect to + fixed-point limits (default = true). An StkError will be thrown + if a file error occurs or if the number of channels in the + StkFrames argument is not equal to that in the file. + */ + void read( StkFrames& buffer, unsigned long startFrame = 0, bool doNormalize = true ); + +protected: + + // Get STK RAW file information. + bool getRawInfo( const char *fileName ); + + // Get WAV file header information. + bool getWavInfo( const char *fileName ); + + // Get SND (AU) file header information. + bool getSndInfo( const char *fileName ); + + // Get AIFF file header information. + bool getAifInfo( const char *fileName ); + + // Get MAT-file header information. + bool getMatInfo( const char *fileName ); + + FILE *fd_; + bool byteswap_; + bool wavFile_; + unsigned long fileSize_; + unsigned long dataOffset_; + unsigned int channels_; + StkFormat dataType_; + StkFloat fileRate_; +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/FileWvIn.h b/nyqstk/include/FileWvIn.h new file mode 100644 index 0000000..31e0b41 --- /dev/null +++ b/nyqstk/include/FileWvIn.h @@ -0,0 +1,148 @@ +/***************************************************/ +/*! \class FileWvIn + \brief STK audio file input class. + + This class inherits from WvIn. It provides a "tick-level" + interface to the FileRead class. It also provides variable-rate + "playback" functionality. Audio file support is provided by the + FileRead class. Linear interpolation is used for fractional "read + rates". + + FileWvIn supports multi-channel data. It is important to distinguish + the tick() methods, which return samples produced by averaging + across sample frames, from the tickFrame() methods, which return + references to multi-channel sample frames. + + FileWvIn will either load the entire content of an audio file into + local memory or incrementally read file data from disk in chunks. + This behavior is controlled by the optional constructor arguments + \e chunkThreshold and \e chunkSize. File sizes greater than \e + chunkThreshold (in sample frames) will be read incrementally in + chunks of \e chunkSize each (also in sample frames). + + When the file end is reached, subsequent calls to the tick() + functions return zero-valued data and isFinished() returns \e + true. + + See the FileRead class for a description of the supported audio + file formats. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_FILEWVIN_H +#define STK_FILEWVIN_H + +#include "WvIn.h" +#include "FileRead.h" + +namespace Nyq +{ + +class FileWvIn : public WvIn +{ +public: + //! Default constructor. + FileWvIn( unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 ); + + //! Overloaded constructor for file input. + /*! + An StkError will be thrown if the file is not found, its format is + unknown, or a read error occurs. + */ + FileWvIn( std::string fileName, bool raw = false, bool doNormalize = true, + unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 ); + + //! Class destructor. + virtual ~FileWvIn(); + + //! Open the specified file and load its data. + /*! + Data from a previously opened file will be overwritten by this + function. An StkError will be thrown if the file is not found, + its format is unknown, or a read error occurs. If the file data + is to be loaded incrementally from disk and normalization is + specified, a scaling will be applied with respect to fixed-point + limits. If the data format is floating-point, no scaling is + performed. + */ + void openFile( std::string fileName, bool raw = false, bool doNormalize = true ); + + //! Close a file if one is open. + void closeFile( void ); + + //! Clear outputs and reset time (file) pointer to zero. + void reset( void ); + + //! Normalize data to a maximum of +-1.0. + /*! + This function has no effect when data is incrementally loaded + from disk. + */ + void normalize( void ); + + //! Normalize data to a maximum of \e +-peak. + /*! + This function has no effect when data is incrementally loaded + from disk. + */ + void normalize( StkFloat peak ); + + //! Return the file size in sample frames. + unsigned long getSize( void ) const { return data_.frames(); }; + + //! Return the input file sample rate in Hz (not the data read rate). + /*! + WAV, SND, and AIF formatted files specify a sample rate in + their headers. STK RAW files have a sample rate of 22050 Hz + by definition. MAT-files are assumed to have a rate of 44100 Hz. + */ + StkFloat getFileRate( void ) const { return data_.dataRate(); }; + + //! Query whether reading is complete. + bool isFinished( void ) const { return finished_; }; + + //! Set the data read rate in samples. The rate can be negative. + /*! + If the rate value is negative, the data is read in reverse order. + */ + void setRate( StkFloat rate ); + + //! Increment the read pointer by \e time samples. + /*! + Note that this function will not modify the interpolation flag status. + */ + virtual void addTime( StkFloat time ); + + //! Turn linear interpolation on/off. + /*! + Interpolation is automatically off when the read rate is + an integer value. If interpolation is turned off for a + fractional rate, the time index is truncated to an integer + value. + */ + void setInterpolate( bool doInterpolate ) { interpolate_ = doInterpolate; }; + + StkFloat lastOut( void ) const; + +protected: + + virtual void computeFrame( void ); + + FileRead file_; + bool finished_; + bool interpolate_; + bool normalizing_; + bool chunking_; + StkFloat time_; + StkFloat rate_; + unsigned long chunkThreshold_; + unsigned long chunkSize_; + long chunkPointer_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/Filter.h b/nyqstk/include/Filter.h new file mode 100644 index 0000000..b7c8abd --- /dev/null +++ b/nyqstk/include/Filter.h @@ -0,0 +1,127 @@ +/***************************************************/ +/*! \class Filter + \brief STK filter class. + + This class implements a generic structure that + can be used to create a wide range of filters. + It can function independently or be subclassed + to provide more specific controls based on a + particular filter type. + + In particular, this class implements the standard + difference equation: + + a[0]*y[n] = b[0]*x[n] + ... + b[nb]*x[n-nb] - + a[1]*y[n-1] - ... - a[na]*y[n-na] + + If a[0] is not equal to 1, the filter coeffcients + are normalized by a[0]. + + The \e gain parameter is applied at the filter + input and does not affect the coefficient values. + The default gain value is 1.0. This structure + results in one extra multiply per computed sample, + but allows easy control of the overall filter gain. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_FILTER_H +#define STK_FILTER_H + +#include "Stk.h" +#include <vector> + +namespace Nyq +{ + +class Filter : public Stk +{ +public: + //! Default constructor creates a zero-order pass-through "filter". + Filter(void); + + //! Overloaded constructor which takes filter coefficients. + /*! + An StkError can be thrown if either of the coefficient vector + sizes is zero, or if the a[0] coefficient is equal to zero. + */ + Filter( std::vector<StkFloat> &bCoefficients, std::vector<StkFloat> &aCoefficients ); + + //! Class destructor. + virtual ~Filter(void); + + //! Sets all internal states of the filter to zero. + void clear(void); + + //! Set filter coefficients. + /*! + An StkError can be thrown if either of the coefficient vector + sizes is zero, or if the a[0] coefficient is equal to zero. If + a[0] is not equal to 1, the filter coeffcients are normalized by + a[0]. The internal state of the filter is not cleared unless the + \e clearState flag is \c true. + */ + void setCoefficients( std::vector<StkFloat> &bCoefficients, std::vector<StkFloat> &aCoefficients, bool clearState = false ); + + //! Set numerator coefficients. + /*! + An StkError can be thrown if coefficient vector is empty. Any + previously set denominator coefficients are left unaffected. Note + that the default constructor sets the single denominator + coefficient a[0] to 1.0. The internal state of the filter is not + cleared unless the \e clearState flag is \c true. + */ + void setNumerator( std::vector<StkFloat> &bCoefficients, bool clearState = false ); + + //! Set denominator coefficients. + /*! + An StkError can be thrown if the coefficient vector is empty or + if the a[0] coefficient is equal to zero. Previously set + numerator coefficients are unaffected unless a[0] is not equal to + 1, in which case all coeffcients are normalized by a[0]. Note + that the default constructor sets the single numerator coefficient + b[0] to 1.0. The internal state of the filter is not cleared + unless the \e clearState flag is \c true. + */ + void setDenominator( std::vector<StkFloat> &aCoefficients, bool clearState = false ); + + //! Set the filter gain. + /*! + The gain is applied at the filter input and does not affect the + coefficient values. The default gain value is 1.0. + */ + virtual void setGain(StkFloat gain); + + //! Return the current filter gain. + virtual StkFloat getGain(void) const; + + //! Return the last computed output value. + virtual StkFloat lastOut(void) const; + + //! Input one sample to the filter and return one output. + virtual StkFloat tick( StkFloat input ); + + //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs. + /*! + The \c channel argument should be zero or greater (the first + channel is specified by 0). An StkError will be thrown if the \c + channel argument is equal to or greater than the number of + channels in the StkFrames object. + */ + virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); + +protected: + + StkFloat gain_; + std::vector<StkFloat> b_; + std::vector<StkFloat> a_; + std::vector<StkFloat> outputs_; + std::vector<StkFloat> inputs_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/Flute.h b/nyqstk/include/Flute.h new file mode 100644 index 0000000..5b6f3bd --- /dev/null +++ b/nyqstk/include/Flute.h @@ -0,0 +1,108 @@ +/***************************************************/ +/*! \class Flute + \brief STK flute physical model class. + + This class implements a simple flute + physical model, as discussed by Karjalainen, + Smith, Waryznyk, etc. The jet model uses + a polynomial, a la Cook. + + This is a digital waveguide model, making its + use possibly subject to patents held by Stanford + University, Yamaha, and others. + + Control Change Numbers: + - Jet Delay = 2 + - Noise Gain = 4 + - Vibrato Frequency = 11 + - Vibrato Gain = 1 + - Breath Pressure = 128 + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_FLUTE_H +#define STK_FLUTE_H + +#include "Instrmnt.h" +#include "JetTable.h" +#include "DelayL.h" +#include "OnePole.h" +#include "PoleZero.h" +#include "Noise.h" +#include "ADSR.h" +#include "SineWave.h" + +namespace Nyq +{ + +class Flute : public Instrmnt +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + /*! + An StkError will be thrown if the rawwave path is incorrectly set. + */ + Flute(StkFloat lowestFrequency); + + //! Class destructor. + ~Flute(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(StkFloat frequency); + + //! Set the reflection coefficient for the jet delay (-1.0 - 1.0). + void setJetReflection(StkFloat coefficient); + + //! Set the reflection coefficient for the air column delay (-1.0 - 1.0). + void setEndReflection(StkFloat coefficient); + + //! Set the length of the jet delay in terms of a ratio of jet delay to air column delay lengths. + void setJetDelay(StkFloat aRatio); + + //! Apply breath velocity to instrument with given amplitude and rate of increase. + void startBlowing(StkFloat amplitude, StkFloat rate); + + //! Decrease breath velocity with given rate of decrease. + void stopBlowing(StkFloat rate); + + //! Start a note with the given frequency and amplitude. + void noteOn(StkFloat frequency, 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); + + protected: + + StkFloat computeSample( void ); + + DelayL jetDelay_; + DelayL boreDelay_; + JetTable jetTable_; + OnePole filter_; + PoleZero dcBlock_; + Noise noise_; + ADSR adsr_; + SineWave vibrato_; + unsigned long length_; + StkFloat lastFrequency_; + StkFloat maxPressure_; + StkFloat jetReflection_; + StkFloat endReflection_; + StkFloat noiseGain_; + StkFloat vibratoGain_; + StkFloat outputGain_; + StkFloat jetRatio_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/Function.h b/nyqstk/include/Function.h new file mode 100644 index 0000000..2b773c6 --- /dev/null +++ b/nyqstk/include/Function.h @@ -0,0 +1,59 @@ +/***************************************************/ +/*! \class Function + \brief STK abstract function parent class. + + This class provides common functionality for STK classes which + implement tables or other types of input to output function + mappings. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#include "Stk.h" + +#ifndef STK_FUNCTION_H +#define STK_FUNCTION_H + +namespace Nyq +{ + +class Function : public Stk +{ + public: + //! Class constructor. + Function(); + + //! Class destructor. + virtual ~Function(); + + //! Return the last output value. + virtual StkFloat lastOut() const { return lastOutput_; }; + + //! Take one sample input and compute one sample of output. + StkFloat tick( StkFloat input ); + + //! Take a channel of the StkFrames object as inputs to the function and replace with corresponding outputs. + /*! + The \c channel argument should be zero or greater (the first + channel is specified by 0). An StkError will be thrown if the \c + channel argument is equal to or greater than the number of + channels in the StkFrames object. + */ + virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); + + protected: + + // This abstract function must be implemented in all subclasses. + // It is used to get around a C++ problem with overloaded virtual + // functions. + virtual StkFloat computeSample( StkFloat input ) = 0; + + StkFloat lastOutput_; + +}; + +} // namespace Nyq + +#endif + diff --git a/nyqstk/include/Generator.h b/nyqstk/include/Generator.h new file mode 100644 index 0000000..9b91ea6 --- /dev/null +++ b/nyqstk/include/Generator.h @@ -0,0 +1,58 @@ +/***************************************************/ +/*! \class Generator + \brief STK abstract unit generator parent class. + + This class provides common functionality for + STK unit generator sample-source subclasses. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_GENERATOR_H +#define STK_GENERATOR_H + +#include "Stk.h" + +namespace Nyq +{ + +class Generator : public Stk +{ + public: + //! Class constructor. + Generator( void ); + + //! Class destructor. + virtual ~Generator( void ); + + //! Return the last output value. + virtual StkFloat lastOut( void ) const { return lastOutput_; }; + + //! Compute one sample and output. + StkFloat tick( void ); + + //! Fill a channel of the StkFrames object with computed outputs. + /*! + The \c channel argument should be zero or greater (the first + channel is specified by 0). An StkError will be thrown if the \c + channel argument is equal to or greater than the number of + channels in the StkFrames object. + */ + StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); + + protected: + + // This abstract function must be implemented in all subclasses. + // It is used to get around a C++ problem with overloaded virtual + // functions. + virtual StkFloat computeSample( void ) = 0; + + StkFloat lastOutput_; + +}; + +} // namespace Nyq + +#endif + diff --git a/nyqstk/include/Instrmnt.h b/nyqstk/include/Instrmnt.h new file mode 100644 index 0000000..0bc9585 --- /dev/null +++ b/nyqstk/include/Instrmnt.h @@ -0,0 +1,75 @@ +/***************************************************/ +/*! \class Instrmnt + \brief STK instrument abstract base class. + + This class provides a common interface for + all STK instruments. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_INSTRMNT_H +#define STK_INSTRMNT_H + +#include "Stk.h" + +namespace Nyq +{ + +class Instrmnt : public Stk +{ + public: + //! Default constructor. + Instrmnt(); + + //! Class destructor. + virtual ~Instrmnt(); + + //! Start a note with the given frequency and amplitude. + virtual void noteOn(StkFloat frequency, StkFloat amplitude) = 0; + + //! Stop a note with the given amplitude (speed of decay). + virtual void noteOff(StkFloat amplitude) = 0; + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(StkFloat frequency); + + //! Return the last output value. + StkFloat lastOut() const; + + //! Return the last left output value. + StkFloat lastOutLeft() const; + + //! Return the last right output value. + StkFloat lastOutRight() const; + + //! Compute one sample and output. + StkFloat tick( void ); + + //! Fill a channel of the StkFrames object with computed outputs. + /*! + The \c channel argument should be zero or greater (the first + channel is specified by 0). An StkError will be thrown if the \c + channel argument is equal to or greater than the number of + channels in the StkFrames object. + */ + StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + virtual void controlChange(int number, StkFloat value); + + protected: + + // This abstract function must be implemented in all subclasses. + // It is used to get around a C++ problem with overloaded virtual + // functions. + virtual StkFloat computeSample( void ) = 0; + + StkFloat lastOutput_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/JCRev.h b/nyqstk/include/JCRev.h new file mode 100644 index 0000000..92848cf --- /dev/null +++ b/nyqstk/include/JCRev.h @@ -0,0 +1,57 @@ +/***************************************************/ +/*! \class JCRev + \brief John Chowning's reverberator class. + + This class is derived from the CLM JCRev + function, which is based on the use of + networks of simple allpass and comb delay + filters. This class implements three series + allpass units, followed by four parallel comb + filters, and two decorrelation delay lines in + parallel at the output. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_JCREV_H +#define STK_JCREV_H + +#include "Effect.h" +#include "Delay.h" + +namespace Nyq +{ + +class JCRev : public Effect +{ + public: + //! Class constructor taking a T60 decay time argument (one second default value). + JCRev( StkFloat T60 = 1.0 ); + + //! Class destructor. + ~JCRev(); + + //! Reset and clear all internal state. + void clear(); + + //! Set the reverberation T60 decay time. + void setT60( StkFloat T60 ); + + protected: + + StkFloat computeSample( StkFloat input ); + + Delay allpassDelays_[3]; + Delay combDelays_[4]; + Delay outLeftDelay_; + Delay outRightDelay_; + StkFloat allpassCoefficient_; + StkFloat combCoefficient_[4]; + +}; + +} // namespace Nyq + +#endif + diff --git a/nyqstk/include/JetTable.h b/nyqstk/include/JetTable.h new file mode 100644 index 0000000..003a758 --- /dev/null +++ b/nyqstk/include/JetTable.h @@ -0,0 +1,41 @@ +/***************************************************/ +/*! \class JetTable + \brief STK jet table class. + + This class implements a flue jet non-linear + function, computed by a polynomial calculation. + Contrary to the name, this is not a "table". + + Consult Fletcher and Rossing, Karjalainen, + Cook, and others for more information. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_JETTABL_H +#define STK_JETTABL_H + +#include "Function.h" + +namespace Nyq +{ + +class JetTable : public Function +{ +public: + //! Default constructor. + JetTable(); + + //! Class destructor. + ~JetTable(); + +protected: + + StkFloat computeSample( StkFloat input ); + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/Mandolin.h b/nyqstk/include/Mandolin.h new file mode 100644 index 0000000..e619cf9 --- /dev/null +++ b/nyqstk/include/Mandolin.h @@ -0,0 +1,75 @@ +/***************************************************/ +/*! \class Mandolin + \brief STK mandolin instrument model class. + + This class inherits from PluckTwo and uses + "commuted synthesis" techniques to model a + mandolin instrument. + + This is a digital waveguide model, making its + use possibly subject to patents held by + Stanford University, Yamaha, and others. + Commuted Synthesis, in particular, is covered + by patents, granted, pending, and/or + applied-for. All are assigned to the Board of + Trustees, Stanford University. For + information, contact the Office of Technology + Licensing, Stanford University. + + Control Change Numbers: + - Body Size = 2 + - Pluck Position = 4 + - String Sustain = 11 + - String Detuning = 1 + - Microphone Position = 128 + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_MANDOLIN_H +#define STK_MANDOLIN_H + +#include "PluckTwo.h" +#include "FileWvIn.h" + +namespace Nyq +{ + +class Mandolin : public PluckTwo +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + Mandolin(StkFloat lowestFrequency); + + //! Class destructor. + ~Mandolin(); + + //! Pluck the strings with the given amplitude (0.0 - 1.0) using the current frequency. + void pluck(StkFloat amplitude); + + //! Pluck the strings with the given amplitude (0.0 - 1.0) and position (0.0 - 1.0). + void pluck(StkFloat amplitude,StkFloat position); + + //! Start a note with the given frequency and amplitude (0.0 - 1.0). + void noteOn(StkFloat frequency, StkFloat amplitude); + + //! Set the body size (a value of 1.0 produces the "default" size). + void setBodySize(StkFloat size); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, StkFloat value); + + protected: + + StkFloat computeSample( void ); + + FileWvIn *soundfile_[12]; + int mic_; + long dampTime_; + bool waveDone_; +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/Modal.h b/nyqstk/include/Modal.h new file mode 100644 index 0000000..1b5443a --- /dev/null +++ b/nyqstk/include/Modal.h @@ -0,0 +1,96 @@ +/***************************************************/ +/*! \class Modal + \brief STK resonance model instrument. + + This class contains an excitation wavetable, + an envelope, an oscillator, and N resonances + (non-sweeping BiQuad filters), where N is set + during instantiation. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_MODAL_H +#define STK_MODAL_H + +#include "Instrmnt.h" +#include "Envelope.h" +#include "WaveLoop.h" +#include "SineWave.h" +#include "BiQuad.h" +#include "OnePole.h" + +namespace Nyq +{ + +class Modal : public Instrmnt +{ +public: + //! Class constructor, taking the desired number of modes to create. + /*! + An StkError will be thrown if the rawwave path is incorrectly set. + */ + Modal( unsigned int modes = 4 ); + + //! Class destructor. + virtual ~Modal(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(StkFloat frequency); + + //! Set the ratio and radius for a specified mode filter. + void setRatioAndRadius(unsigned int modeIndex, StkFloat ratio, StkFloat radius); + + //! Set the master gain. + void setMasterGain(StkFloat aGain); + + //! Set the direct gain. + void setDirectGain(StkFloat aGain); + + //! Set the gain for a specified mode filter. + void setModeGain(unsigned int modeIndex, StkFloat gain); + + //! Initiate a strike with the given amplitude (0.0 - 1.0). + virtual void strike(StkFloat amplitude); + + //! Damp modes with a given decay factor (0.0 - 1.0). + void damp(StkFloat amplitude); + + //! Start a note with the given frequency and amplitude. + void noteOn(StkFloat frequency, 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). + virtual void controlChange(int number, StkFloat value) = 0; + +protected: + + StkFloat computeSample( void ); + + Envelope envelope_; + FileWvIn *wave_; + BiQuad **filters_; + OnePole onepole_; + SineWave vibrato_; + + unsigned int nModes_; + std::vector<StkFloat> ratios_; + std::vector<StkFloat> radii_; + + StkFloat vibratoGain_; + StkFloat masterGain_; + StkFloat directGain_; + StkFloat stickHardness_; + StkFloat strikePosition_; + StkFloat baseFrequency_; +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/ModalBar.h b/nyqstk/include/ModalBar.h new file mode 100644 index 0000000..2336b29 --- /dev/null +++ b/nyqstk/include/ModalBar.h @@ -0,0 +1,66 @@ +/***************************************************/ +/*! \class ModalBar + \brief STK resonant bar instrument class. + + This class implements a number of different + struck bar instruments. It inherits from the + Modal class. + + Control Change Numbers: + - Stick Hardness = 2 + - Stick Position = 4 + - Vibrato Gain = 1 + - Vibrato Frequency = 11 + - Direct Stick Mix = 8 + - Volume = 128 + - Modal Presets = 16 + - Marimba = 0 + - Vibraphone = 1 + - Agogo = 2 + - Wood1 = 3 + - Reso = 4 + - Wood2 = 5 + - Beats = 6 + - Two Fixed = 7 + - Clump = 8 + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_MODALBAR_H +#define STK_MODALBAR_H + +#include "Modal.h" + +namespace Nyq +{ + +class ModalBar : public Modal +{ +public: + //! Class constructor. + ModalBar(); + + //! Class destructor. + ~ModalBar(); + + //! Set stick hardness (0.0 - 1.0). + void setStickHardness(StkFloat hardness); + + //! Set stick position (0.0 - 1.0). + void setStrikePosition(StkFloat position); + + //! Select a bar preset (currently modulo 9). + void setPreset(int preset); + + //! Set the modulation (vibrato) depth. + void setModulationDepth(StkFloat mDepth); + + //! Perform the control change specified by \e number and \e value (0.0 - 128.0). + void controlChange(int number, StkFloat value); +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/NRev.h b/nyqstk/include/NRev.h new file mode 100644 index 0000000..28031cf --- /dev/null +++ b/nyqstk/include/NRev.h @@ -0,0 +1,58 @@ +/***************************************************/ +/*! \class NRev + \brief CCRMA's NRev reverberator class. + + This class is derived from the CLM NRev + function, which is based on the use of + 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. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_NREV_H +#define STK_NREV_H + +#include "Effect.h" +#include "Delay.h" + +namespace Nyq +{ + +class NRev : public Effect +{ + public: + //! Class constructor taking a T60 decay time argument (one second default value). + NRev( StkFloat T60 = 1.0 ); + + //! Class destructor. + ~NRev(); + + //! Reset and clear all internal state. + void clear(); + + //! Set the reverberation T60 decay time. + void setT60( StkFloat T60 ); + + protected: + + StkFloat computeSample( StkFloat input ); + + Delay allpassDelays_[8]; + Delay combDelays_[6]; + StkFloat allpassCoefficient_; + StkFloat combCoefficient_[6]; + StkFloat lowpassState_; + +}; + +} // namespace Nyq + +#endif + diff --git a/nyqstk/include/Noise.h b/nyqstk/include/Noise.h new file mode 100644 index 0000000..0cbd409 --- /dev/null +++ b/nyqstk/include/Noise.h @@ -0,0 +1,53 @@ +/***************************************************/ +/*! \class Noise + \brief STK noise generator. + + Generic random number generation using the + C rand() function. The quality of the rand() + function varies from one OS to another. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_NOISE_H +#define STK_NOISE_H + +#include "Generator.h" + +namespace Nyq +{ + +class Noise : public Generator +{ +public: + + //! Default constructor which seeds the random number generator with the system time. + Noise(); + + //! Constructor which seeds the random number generator with a given seed. + /*! + If the seed value is zero, the random number generator is + seeded with the system time. + */ + Noise( unsigned int seed ); + + //! Class destructor. + virtual ~Noise(); + + //! Seed the random number generator with a specific seed value. + /*! + If no seed is provided or the seed value is zero, the random + number generator is seeded with the current system time. + */ + void setSeed( unsigned int seed = 0 ); + +protected: + + virtual StkFloat computeSample( void ); + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/OnePole.h b/nyqstk/include/OnePole.h new file mode 100644 index 0000000..a141452 --- /dev/null +++ b/nyqstk/include/OnePole.h @@ -0,0 +1,84 @@ +/***************************************************/ +/*! \class OnePole + \brief STK one-pole filter class. + + This protected Filter subclass implements + a one-pole digital filter. A method is + provided for setting the pole position along + the real axis of the z-plane while maintaining + a constant peak filter gain. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_ONEPOLE_H +#define STK_ONEPOLE_H + +#include "Filter.h" + +namespace Nyq +{ + +class OnePole : protected Filter +{ +public: + + //! Default constructor creates a first-order low-pass filter. + OnePole(); + + //! Overloaded constructor which sets the pole position during instantiation. + OnePole( StkFloat thePole ); + + //! Class destructor. + ~OnePole(); + + //! Clears the internal state of the filter. + void clear(void); + + //! Set the b[0] coefficient value. + void setB0(StkFloat b0); + + //! Set the a[1] coefficient value. + void setA1(StkFloat a1); + + //! Set the pole position in the z-plane. + /*! + This method sets the pole position along the real-axis of the + z-plane and normalizes the coefficients for a maximum gain of one. + A positive pole value produces a low-pass filter, while a negative + pole value produces a high-pass filter. This method does not + affect the filter \e gain value. + */ + void setPole(StkFloat thePole); + + //! Set the filter gain. + /*! + The gain is applied at the filter input and does not affect the + coefficient values. The default gain value is 1.0. + */ + void setGain(StkFloat gain); + + //! Return the current filter gain. + StkFloat getGain(void) const; + + //! Return the last computed output value. + StkFloat lastOut(void) const; + + //! Input one sample to the filter and return one output. + StkFloat tick(StkFloat sample); + + //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs. + /*! + The \c channel argument should be zero or greater (the first + channel is specified by 0). An StkError will be thrown if the \c + channel argument is equal to or greater than the number of + channels in the StkFrames object. + */ + StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/OneZero.h b/nyqstk/include/OneZero.h new file mode 100644 index 0000000..19da171 --- /dev/null +++ b/nyqstk/include/OneZero.h @@ -0,0 +1,84 @@ +/***************************************************/ +/*! \class OneZero + \brief STK one-zero filter class. + + This protected Filter subclass implements + a one-zero digital filter. A method is + provided for setting the zero position + along the real axis of the z-plane while + maintaining a constant filter gain. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_ONEZERO_H +#define STK_ONEZERO_H + +#include "Filter.h" + +namespace Nyq +{ + +class OneZero : protected Filter +{ + public: + + //! Default constructor creates a first-order low-pass filter. + OneZero(); + + //! Overloaded constructor which sets the zero position during instantiation. + OneZero(StkFloat theZero); + + //! Class destructor. + ~OneZero(); + + //! Clears the internal state of the filter. + void clear(void); + + //! Set the b[0] coefficient value. + void setB0(StkFloat b0); + + //! Set the b[1] coefficient value. + void setB1(StkFloat b1); + + //! Set the zero position in the z-plane. + /*! + This method sets the zero position along the real-axis of the + z-plane and normalizes the coefficients for a maximum gain of one. + A positive zero value produces a high-pass filter, while a + negative zero value produces a low-pass filter. This method does + not affect the filter \e gain value. + */ + void setZero(StkFloat theZero); + + //! Set the filter gain. + /*! + The gain is applied at the filter input and does not affect the + coefficient values. The default gain value is 1.0. + */ + void setGain(StkFloat gain); + + //! Return the current filter gain. + StkFloat getGain(void) const; + + //! Return the last computed output value. + StkFloat lastOut(void) const; + + //! Input one sample to the filter and return one output. + StkFloat tick(StkFloat sample); + + //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs. + /*! + The \c channel argument should be zero or greater (the first + channel is specified by 0). An StkError will be thrown if the \c + channel argument is equal to or greater than the number of + channels in the StkFrames object. + */ + StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/PRCRev.h b/nyqstk/include/PRCRev.h new file mode 100644 index 0000000..5ee5c76 --- /dev/null +++ b/nyqstk/include/PRCRev.h @@ -0,0 +1,55 @@ +/***************************************************/ +/*! \class PRCRev + \brief Perry's simple reverberator class. + + This class is based on some of the famous + Stanford/CCRMA reverbs (NRev, KipRev), which + were based on the Chowning/Moorer/Schroeder + reverberators using networks of simple allpass + and comb delay filters. This class implements + two series allpass units and two parallel comb + filters. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_PRCREV_H +#define STK_PRCREV_H + +#include "Effect.h" +#include "Delay.h" + +namespace Nyq +{ + +class PRCRev : public Effect +{ +public: + //! Class constructor taking a T60 decay time argument (one second default value). + PRCRev( StkFloat T60 = 1.0 ); + + //! Class destructor. + ~PRCRev(); + + //! Reset and clear all internal state. + void clear(); + + //! Set the reverberation T60 decay time. + void setT60( StkFloat T60 ); + +protected: + + StkFloat computeSample( StkFloat input ); + + Delay allpassDelays_[2]; + Delay combDelays_[2]; + StkFloat allpassCoefficient_; + StkFloat combCoefficient_[2]; + +}; + +} // namespace Nyq + +#endif + diff --git a/nyqstk/include/PitShift.h b/nyqstk/include/PitShift.h new file mode 100644 index 0000000..775b8e2 --- /dev/null +++ b/nyqstk/include/PitShift.h @@ -0,0 +1,52 @@ +/***************************************************/ +/*! \class PitShift + \brief STK simple pitch shifter effect class. + + This class implements a simple pitch shifter + using delay lines. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_PITSHIFT_H +#define STK_PITSHIFT_H + +#include "Effect.h" +#include "DelayL.h" + +namespace Nyq +{ + +class PitShift : public Effect +{ + public: + //! Class constructor. + PitShift(); + + //! Class destructor. + ~PitShift(); + + //! Reset and clear all internal state. + void clear(); + + //! Set the pitch shift factor (1.0 produces no shift). + void setShift(StkFloat shift); + + protected: + + StkFloat computeSample( StkFloat input ); + + DelayL delayLine_[2]; + StkFloat delay_[2]; + StkFloat env_[2]; + StkFloat rate_; + unsigned long delayLength; + unsigned long halfLength; + +}; + +} // namespace Nyq + +#endif + diff --git a/nyqstk/include/PluckTwo.h b/nyqstk/include/PluckTwo.h new file mode 100644 index 0000000..eabb74d --- /dev/null +++ b/nyqstk/include/PluckTwo.h @@ -0,0 +1,90 @@ +/***************************************************/ +/*! \class PluckTwo + \brief STK enhanced plucked string model class. + + This class implements an enhanced two-string, + plucked physical model, a la Jaffe-Smith, + Smith, and others. + + PluckTwo is an abstract class, with no excitation + specified. Therefore, it can't be directly + instantiated. + + This is a digital waveguide model, making its + use possibly subject to patents held by + Stanford University, Yamaha, and others. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_PLUCKTWO_H +#define STK_PLUCKTWO_H + +#include "Instrmnt.h" +#include "DelayL.h" +#include "DelayA.h" +#include "OneZero.h" + +namespace Nyq +{ + +class PluckTwo : public Instrmnt +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + PluckTwo(StkFloat lowestFrequency); + + //! Class destructor. + virtual ~PluckTwo(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + virtual void setFrequency(StkFloat frequency); + + //! Detune the two strings by the given factor. A value of 1.0 produces unison strings. + void setDetune(StkFloat detune); + + //! Efficient combined setting of frequency and detuning. + void setFreqAndDetune(StkFloat frequency, StkFloat detune); + + //! Set the pluck or "excitation" position along the string (0.0 - 1.0). + void setPluckPosition(StkFloat position); + + //! Set the base loop gain. + /*! + The actual loop gain is set according to the frequency. + Because of high-frequency loop filter roll-off, higher + frequency settings have greater loop gains. + */ + void setBaseLoopGain(StkFloat aGain); + + //! Stop a note with the given amplitude (speed of decay). + virtual void noteOff(StkFloat amplitude); + + protected: + + virtual StkFloat computeSample( void ) = 0; + + DelayA delayLine_; + DelayA delayLine2_; + DelayL combDelay_; + OneZero filter_; + OneZero filter2_; + + unsigned long length_; + StkFloat loopGain_; + StkFloat baseLoopGain_; + StkFloat lastFrequency_; + StkFloat lastLength_; + StkFloat detuning_; + StkFloat pluckAmplitude_; + StkFloat pluckPosition_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/PoleZero.h b/nyqstk/include/PoleZero.h new file mode 100644 index 0000000..5ee5d10 --- /dev/null +++ b/nyqstk/include/PoleZero.h @@ -0,0 +1,91 @@ +/***************************************************/ +/*! \class PoleZero + \brief STK one-pole, one-zero filter class. + + This protected Filter subclass implements + a one-pole, one-zero digital filter. A + method is provided for creating an allpass + filter with a given coefficient. Another + method is provided to create a DC blocking filter. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_POLEZERO_H +#define STK_POLEZERO_H + +#include "Filter.h" + +namespace Nyq +{ + +class PoleZero : protected Filter +{ + public: + + //! Default constructor creates a first-order pass-through filter. + PoleZero(); + + //! Class destructor. + ~PoleZero(); + + //! Clears the internal states of the filter. + void clear(void); + + //! Set the b[0] coefficient value. + void setB0(StkFloat b0); + + //! Set the b[1] coefficient value. + void setB1(StkFloat b1); + + //! Set the a[1] coefficient value. + void setA1(StkFloat a1); + + //! Set the filter for allpass behavior using \e coefficient. + /*! + This method uses \e coefficient to create an allpass filter, + which has unity gain at all frequencies. Note that the \e + coefficient magnitude must be less than one to maintain stability. + */ + void setAllpass(StkFloat coefficient); + + //! Create a DC blocking filter with the given pole position in the z-plane. + /*! + This method sets the given pole position, together with a zero + at z=1, to create a DC blocking filter. \e thePole should be + close to one to minimize low-frequency attenuation. + + */ + void setBlockZero(StkFloat thePole = 0.99); + + //! Set the filter gain. + /*! + The gain is applied at the filter input and does not affect the + coefficient values. The default gain value is 1.0. + */ + void setGain( StkFloat gain ); + + //! Return the current filter gain. + StkFloat getGain( void ) const; + + //! Return the last computed output value. + StkFloat lastOut( void ) const; + + //! Input one sample to the filter and return one output. + StkFloat tick( StkFloat sample ); + + //! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs. + /*! + The \c channel argument should be zero or greater (the first + channel is specified by 0). An StkError will be thrown if the \c + channel argument is equal to or greater than the number of + channels in the StkFrames object. + */ + StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/ReedTabl.h b/nyqstk/include/ReedTabl.h new file mode 100644 index 0000000..e6f97a5 --- /dev/null +++ b/nyqstk/include/ReedTabl.h @@ -0,0 +1,70 @@ +/***************************************************/ +/*! \class ReedTabl + \brief STK reed table class. + + This class implements a simple one breakpoint, + non-linear reed function, as described by + Smith (1986). This function is based on a + memoryless non-linear spring model of the reed + (the reed mass is ignored) which saturates when + the reed collides with the mouthpiece facing. + + See McIntyre, Schumacher, & Woodhouse (1983), + Smith (1986), Hirschman, Cook, Scavone, and + others for more information. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2002. +*/ +/***************************************************/ + +#if !defined(__REEDTABL_H) +#define __REEDTABL_H + +#include "Stk.h" + +class ReedTabl : public Stk +{ +public: + //! Default constructor. + ReedTabl(); + + //! Class destructor. + ~ReedTabl(); + + //! Set the table offset value. + /*! + The table offset roughly corresponds to the size + of the initial reed tip opening (a greater offset + represents a smaller opening). + */ + void setOffset(MY_FLOAT aValue); + + //! Set the table slope value. + /*! + The table slope roughly corresponds to the reed + stiffness (a greater slope represents a harder + reed). + */ + void setSlope(MY_FLOAT aValue); + + //! Return the last output value. + MY_FLOAT lastOut() const; + + //! Return the function value for \e input. + /*! + The function input represents the differential + pressure across the reeds. + */ + MY_FLOAT tick(MY_FLOAT input); + + //! Take \e vectorSize inputs and return the corresponding function values in \e vector. + MY_FLOAT *tick(MY_FLOAT *vector, unsigned int vectorSize); + +protected: + MY_FLOAT offSet; + MY_FLOAT slope; + MY_FLOAT lastOutput; + +}; + +#endif diff --git a/nyqstk/include/ReedTable.h b/nyqstk/include/ReedTable.h new file mode 100644 index 0000000..c7e8744 --- /dev/null +++ b/nyqstk/include/ReedTable.h @@ -0,0 +1,64 @@ +/***************************************************/ +/*! \class ReedTable + \brief STK reed table class. + + This class implements a simple one breakpoint, + non-linear reed function, as described by + Smith (1986). This function is based on a + memoryless non-linear spring model of the reed + (the reed mass is ignored) which saturates when + the reed collides with the mouthpiece facing. + + See McIntyre, Schumacher, & Woodhouse (1983), + Smith (1986), Hirschman, Cook, Scavone, and + others for more information. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_REEDTABLE_H +#define STK_REEDTABLE_H + +#include "Function.h" + +namespace Nyq +{ + +class ReedTable : public Function +{ +public: + //! Default constructor. + ReedTable(); + + //! Class destructor. + ~ReedTable(); + + //! Set the table offset value. + /*! + The table offset roughly corresponds to the size + of the initial reed tip opening (a greater offset + represents a smaller opening). + */ + void setOffset(StkFloat offset); + + //! Set the table slope value. + /*! + The table slope roughly corresponds to the reed + stiffness (a greater slope represents a harder + reed). + */ + void setSlope(StkFloat slope); + +protected: + + StkFloat computeSample( StkFloat input ); + + StkFloat offset_; + StkFloat slope_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/SKINI.msg b/nyqstk/include/SKINI.msg new file mode 100644 index 0000000..5e5fdca --- /dev/null +++ b/nyqstk/include/SKINI.msg @@ -0,0 +1,127 @@ +/*********************************************************/ +/* + Definition of SKINI Message Types and Special Symbols + Synthesis toolKit Instrument Network Interface + + These symbols should have the form __SK_<name>_ + + Where <name> is the string used in the SKINI stream. + + by Perry R. Cook, 1995 - 2002. +*/ +/*********************************************************/ + +namespace Nyq +{ + +/***** MIDI COMPATIBLE MESSAGES *****/ +/***** Status Bytes Have Channel=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_PitchChange_ 249 + +#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_ShakerEnergy_ __SK_Breath_ +#define __SK_ShakerDamping_ __SK_ModFrequency_ +#define __SK_ShakerNumObjects_ __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_ + +} // namespace Nyq diff --git a/nyqstk/include/Saxofony.h b/nyqstk/include/Saxofony.h new file mode 100644 index 0000000..7609d4a --- /dev/null +++ b/nyqstk/include/Saxofony.h @@ -0,0 +1,108 @@ +/***************************************************/ +/*! \class Saxofony + \brief STK faux conical bore reed instrument class. + + This class implements a "hybrid" digital + waveguide instrument that can generate a + variety of wind-like sounds. It has also been + referred to as the "blowed string" model. The + waveguide section is essentially that of a + string, with one rigid and one lossy + termination. The non-linear function is a + reed table. The string can be "blown" at any + point between the terminations, though just as + with strings, it is impossible to excite the + system at either end. If the excitation is + placed at the string mid-point, the sound is + that of a clarinet. At points closer to the + "bridge", the sound is closer to that of a + saxophone. See Scavone (2002) for more details. + + This is a digital waveguide model, making its + use possibly subject to patents held by Stanford + University, Yamaha, and others. + + Control Change Numbers: + - Reed Stiffness = 2 + - Reed Aperture = 26 + - Noise Gain = 4 + - Blow Position = 11 + - Vibrato Frequency = 29 + - Vibrato Gain = 1 + - Breath Pressure = 128 + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_SAXOFONY_H +#define STK_SAXOFONY_H + +#include "Instrmnt.h" +#include "DelayL.h" +#include "ReedTable.h" +#include "OneZero.h" +#include "Envelope.h" +#include "Noise.h" +#include "SineWave.h" + +namespace Nyq +{ + +class Saxofony : public Instrmnt +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + /*! + An StkError will be thrown if the rawwave path is incorrectly set. + */ + Saxofony(StkFloat lowestFrequency); + + //! Class destructor. + ~Saxofony(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(StkFloat frequency); + + //! Set the "blowing" position between the air column terminations (0.0 - 1.0). + void setBlowPosition(StkFloat aPosition); + + //! Apply breath pressure to instrument with given amplitude and rate of increase. + void startBlowing(StkFloat amplitude, StkFloat rate); + + //! Decrease breath pressure with given rate of decrease. + void stopBlowing(StkFloat rate); + + //! Start a note with the given frequency and amplitude. + void noteOn(StkFloat frequency, 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); + + protected: + + StkFloat computeSample( void ); + + DelayL delays_[2]; + ReedTable reedTable_; + OneZero filter_; + Envelope envelope_; + Noise noise_; + SineWave vibrato_; + unsigned long length_; + StkFloat outputGain_; + StkFloat noiseGain_; + StkFloat vibratoGain_; + StkFloat position_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/SineWave.h b/nyqstk/include/SineWave.h new file mode 100644 index 0000000..756570d --- /dev/null +++ b/nyqstk/include/SineWave.h @@ -0,0 +1,90 @@ +/***************************************************/ +/*! \class SineWave + \brief STK sinusoid oscillator class. + + This class computes and saves a static sine "table" that can be + shared by multiple instances. It has an interface similar to the + WaveLoop class but inherits from the Generator class. Output + values are computed using linear interpolation. + + The "table" length, set in SineWave.h, is 2048 samples by default. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_SINEWAVE_H +#define STK_SINEWAVE_H + +namespace Nyq +{ + +const unsigned long TABLE_SIZE = 2048; + +} // namespace Nyq + +#include "Generator.h" + +namespace Nyq +{ + +class SineWave : public Generator +{ +public: + //! Default constructor. + SineWave( void ); + + //! Class destructor. + virtual ~SineWave( void ); + + //! Clear output and reset time pointer to zero. + void reset( void ); + + //! Set the data read rate in samples. The rate can be negative. + /*! + If the rate value is negative, the data is read in reverse order. + */ + void setRate( StkFloat rate ) { rate_ = rate; }; + + //! Set the data interpolation rate based on a looping frequency. + /*! + This function determines the interpolation rate based on the file + size and the current Stk::sampleRate. The \e frequency value + corresponds to file cycles per second. The frequency can be + negative, in which case the loop is read in reverse order. + */ + void setFrequency( StkFloat frequency ); + + //! Increment the read pointer by \e time samples, modulo file size. + void addTime( StkFloat time ); + + //! Increment current read pointer by \e angle, relative to a looping frequency. + /*! + This function increments the read pointer based on the file + size and the current Stk::sampleRate. The \e anAngle value + is a multiple of file size. + */ + void addPhase( StkFloat angle ); + + //! Add a phase offset to the current read pointer. + /*! + This function determines a time offset based on the file + size and the current Stk::sampleRate. The \e angle value + is a multiple of file size. + */ + void addPhaseOffset( StkFloat angle ); + +protected: + + StkFloat computeSample( void ); + + static StkFrames table_; + StkFloat time_; + StkFloat rate_; + StkFloat phaseOffset_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/Sitar.h b/nyqstk/include/Sitar.h new file mode 100644 index 0000000..d2b0bcd --- /dev/null +++ b/nyqstk/include/Sitar.h @@ -0,0 +1,75 @@ +/***************************************************/ +/*! \class Sitar + \brief STK sitar string model class. + + This class implements a sitar plucked string + physical model based on the Karplus-Strong + algorithm. + + This is a digital waveguide model, making its + use possibly subject to patents held by + Stanford University, Yamaha, and others. + There exist at least two patents, assigned to + Stanford, bearing the names of Karplus and/or + Strong. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_SITAR_H +#define STK_SITAR_H + +#include "Instrmnt.h" +#include "DelayA.h" +#include "OneZero.h" +#include "Noise.h" +#include "ADSR.h" + +namespace Nyq +{ + +class Sitar : public Instrmnt +{ + public: + //! Class constructor, taking the lowest desired playing frequency. + Sitar( StkFloat lowestFrequency = 20 ); + + //! Class destructor. + ~Sitar(); + + //! Reset and clear all internal state. + void clear(); + + //! Set instrument parameters for a particular frequency. + void setFrequency(StkFloat frequency); + + //! Pluck the string with the given amplitude using the current frequency. + void pluck(StkFloat amplitude); + + //! Start a note with the given frequency and amplitude. + void noteOn(StkFloat frequency, StkFloat amplitude); + + //! Stop a note with the given amplitude (speed of decay). + void noteOff(StkFloat amplitude); + + protected: + + StkFloat computeSample( void ); + + DelayA delayLine_; + OneZero loopFilter_; + Noise noise_; + ADSR envelope_; + + StkFloat loopGain_; + StkFloat amGain_; + StkFloat delay_; + StkFloat targetDelay_; + +}; + +} // namespace Nyq + +#endif + diff --git a/nyqstk/include/Stk.h b/nyqstk/include/Stk.h new file mode 100644 index 0000000..e81a46c --- /dev/null +++ b/nyqstk/include/Stk.h @@ -0,0 +1,369 @@ +/***************************************************/ +/*! \class Stk + \brief STK base class + + Nearly all STK classes inherit from this class. + The global sample rate and rawwave path variables + can be queried and modified via Stk. In addition, + this class provides error handling and + byte-swapping functions. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_STK_H +#define STK_STK_H + +#include <string> +#include <iostream> +#include <sstream> + +namespace Nyq +{ + +// Most data in STK is passed and calculated with the +// following user-definable floating-point type. You +// can change this to "float" if you prefer or perhaps +// a "long double" in the future. +typedef double StkFloat; + +// The "MY_FLOAT" type was deprecated in STK +// versions higher than 4.1.3 and replaced with the variable +// "StkFloat". +#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) + typedef StkFloat MY_FLOAT; + #pragma deprecated(MY_FLOAT) +#elif defined(__GXX__) + typedef StkFloat MY_FLOAT __attribute__ ((deprecated)); +#else + typedef StkFloat MY_FLOAT; // temporary +#endif + + +//! STK error handling class. +/*! + This is a fairly abstract exception handling class. There could + be sub-classes to take care of more specific error conditions ... or + not. +*/ +class StkError +{ +public: + enum Type { + STATUS, + WARNING, + DEBUG_WARNING, + MEMORY_ALLOCATION, + MEMORY_ACCESS, + FUNCTION_ARGUMENT, + FILE_NOT_FOUND, + FILE_UNKNOWN_FORMAT, + FILE_ERROR, + PROCESS_THREAD, + PROCESS_SOCKET, + PROCESS_SOCKET_IPADDR, + AUDIO_SYSTEM, + MIDI_SYSTEM, + UNSPECIFIED + }; + +protected: + std::string message_; + Type type_; + +public: + //! The constructor. + StkError(const std::string& message, Type type = StkError::UNSPECIFIED) + : message_(message), type_(type) {} + + //! The destructor. + virtual ~StkError(void) {}; + + //! Prints thrown error message to stderr. + virtual void printMessage(void) { std::cerr << '\n' << message_ << "\n\n"; } + + //! Returns the thrown error message type. + virtual const Type& getType(void) { return type_; } + + //! Returns the thrown error message string. + virtual const std::string& getMessage(void) { return message_; } + + //! Returns the thrown error message as a C string. + virtual const char *getMessageCString(void) { return message_.c_str(); } +}; + + +class Stk +{ +public: + + typedef unsigned long StkFormat; + static const StkFormat STK_SINT8; /*!< -128 to +127 */ + static const StkFormat STK_SINT16; /*!< -32768 to +32767 */ + static const StkFormat STK_SINT24; /*!< Upper 3 bytes of 32-bit signed integer. */ + static const StkFormat STK_SINT32; /*!< -2147483648 to +2147483647. */ + static const StkFormat STK_FLOAT32; /*!< Normalized between plus/minus 1.0. */ + static const StkFormat STK_FLOAT64; /*!< Normalized between plus/minus 1.0. */ + + //! Static method which returns the current STK sample rate. + static StkFloat sampleRate(void) { return srate_; } + + //! Static method which sets the STK sample rate. + /*! + The sample rate set using this method is queried by all STK + classes which depend on its value. It is initialized to the + default SRATE set in Stk.h. Many STK classes use the sample rate + during instantiation. Therefore, if you wish to use a rate which + is different from the default rate, it is imperative that it be + set \e BEFORE STK objects are instantiated. + */ + static void setSampleRate(StkFloat rate) { if (rate > 0.0) srate_ = rate; } + + //! Static method which returns the current rawwave path. + static std::string rawwavePath(void) { return rawwavepath_; } + + //! Static method which sets the STK rawwave path. + static void setRawwavePath(std::string path); + + //! Static method which byte-swaps a 16-bit data type. + static void swap16(unsigned char *ptr); + + //! Static method which byte-swaps a 32-bit data type. + static void swap32(unsigned char *ptr); + + //! Static method which byte-swaps a 64-bit data type. + static void swap64(unsigned char *ptr); + + //! Static cross-platform method to sleep for a number of milliseconds. + static void sleep(unsigned long milliseconds); + + //! Static function for error reporting and handling using c-strings. + static void handleError( const char *message, StkError::Type type ); + + //! Static function for error reporting and handling using c++ strings. + static void handleError( std::string message, StkError::Type type ); + + //! Toggle display of WARNING and STATUS messages. + static void showWarnings( bool status ) { showWarnings_ = status; } + + //! Toggle display of error messages before throwing exceptions. + static void printErrors( bool status ) { printErrors_ = status; } + +private: + static StkFloat srate_; + static std::string rawwavepath_; + static bool showWarnings_; + static bool printErrors_; + +protected: + + std::ostringstream errorString_; + + //! Default constructor. + Stk(void); + + //! Class destructor. + virtual ~Stk(void); + + //! Internal function for error reporting which assumes message in \c errorString_ variable. + void handleError( StkError::Type type ); +}; + + +/***************************************************/ +/*! \class StkFrames + \brief An STK class to handle vectorized audio data. + + This class can hold single- or multi-channel audio data in either + interleaved or non-interleaved formats. The data type is always + StkFloat. In an effort to maintain efficiency, no out-of-bounds + checks are performed in this class. + + Possible future improvements in this class could include functions + to inter- or de-interleave the data and to convert to and return + other data types. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +class StkFrames +{ +public: + + //! The default constructor initializes the frame data structure to size zero. + StkFrames( unsigned int nFrames = 0, unsigned int nChannels = 0, bool interleaved = true ); + + //! Overloaded constructor that initializes the frame data to the specified size with \c value. + StkFrames( const StkFloat& value, unsigned int nFrames, unsigned int nChannels, bool interleaved = true ); + + //! The destructor. + ~StkFrames(); + + //! Subscript operator which returns a reference to element \c n of self. + /*! + The result can be used as an lvalue . This reference is valid + until the resize function is called or the array is destroyed. The + index \c n must be between 0 and size less one. No range checking + is performed unless _STK_DEBUG_ is defined. + */ + StkFloat& operator[] ( size_t n ); + + //! Subscript operator that returns the value at element \c n of self. + /*! + The index \c n must be between 0 and size less one. No range + checking is performed unless _STK_DEBUG_ is defined. + */ + StkFloat operator[] ( size_t n ) const; + + //! Channel / frame subscript operator that returns a reference. + /*! + The result can be used as an lvalue. This reference is valid + until the resize function is called or the array is destroyed. The + \c frame index must be between 0 and frames() - 1. The \c channel + index must be between 0 and channels() - 1. No range checking is + performed unless _STK_DEBUG_ is defined. + */ + StkFloat& operator() ( size_t frame, unsigned int channel ); + + //! Channel / frame subscript operator that returns a value. + /*! + The \c frame index must be between 0 and frames() - 1. The \c + channel index must be between 0 and channels() - 1. No range checking + is performed unless _STK_DEBUG_ is defined. + */ + StkFloat operator() ( size_t frame, unsigned int channel ) const; + + //! Return an interpolated value at the fractional frame index and channel. + /*! + This function performs linear interpolation. The \c frame + index must be between 0.0 and frames() - 1. The \c channel index + must be between 0 and channels() - 1. No range checking is + performed unless _STK_DEBUG_ is defined. + */ + StkFloat interpolate( StkFloat frame, unsigned int channel = 0 ) const; + + //! Returns the total number of audio samples represented by the object. + size_t size() const { return size_; }; + + //! Returns \e true if the object size is zero and \e false otherwise. + bool empty() const; + + //! Resize self to represent the specified number of channels and frames. + /*! + Changes the size of self based on the number of frames and + channels. No element assignment is performed. No memory + deallocation occurs if the new size is smaller than the previous + size. Further, no new memory is allocated when the new size is + smaller or equal to a previously allocated size. + */ + void resize( size_t nFrames, unsigned int nChannels = 1 ); + + //! Resize self to represent the specified number of channels and frames and perform element initialization. + /*! + Changes the size of self based on the number of frames and + channels, and assigns \c value to every element. No memory + deallocation occurs if the new size is smaller than the previous + size. Further, no new memory is allocated when the new size is + smaller or equal to a previously allocated size. + */ + void resize( size_t nFrames, unsigned int nChannels, StkFloat value ); + + //! Return the number of channels represented by the data. + unsigned int channels( void ) const { return nChannels_; }; + + //! Return the number of sample frames represented by the data. + unsigned int frames( void ) const { return nFrames_; }; + + //! Set the sample rate associated with the StkFrames data. + /*! + By default, this value is set equal to the current STK sample + rate at the time of instantiation. + */ + void setDataRate( StkFloat rate ) { dataRate_ = rate; }; + + //! Return the sample rate associated with the StkFrames data. + /*! + By default, this value is set equal to the current STK sample + rate at the time of instantiation. + */ + StkFloat dataRate( void ) const { return dataRate_; }; + + //! Returns \c true if the data is in interleaved format, \c false if the data is non-interleaved. + bool interleaved( void ) const { return interleaved_; }; + + //! Set the flag to indicate whether the internal data is in interleaved (\c true) or non-interleaved (\c false) format. + /*! + Note that this function does not modify the internal data order + with respect to the argument value. It simply changes the + indicator flag value. + */ + void setInterleaved( bool isInterleaved ) { interleaved_ = isInterleaved; }; + +private: + + StkFloat *data_; + StkFloat dataRate_; + size_t nFrames_; + unsigned int nChannels_; + size_t size_; + size_t bufferSize_; + bool interleaved_; + +}; + + +// Here are a few other useful typedefs. +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef signed short SINT16; +typedef signed int SINT32; +typedef float FLOAT32; +typedef double FLOAT64; + +// The default sampling rate. +const StkFloat SRATE = 44100.0; + +// The default real-time audio input and output buffer size. If +// clicks are occuring in the input and/or output sound stream, a +// larger buffer size may help. Larger buffer sizes, however, produce +// more latency. +const unsigned int RT_BUFFER_SIZE = 512; + +// The default rawwave path value is set with the preprocessor +// definition RAWWAVE_PATH. This can be specified as an argument to +// the configure script, in an integrated development environment, or +// below. The global STK rawwave path variable can be dynamically set +// with the Stk::setRawwavePath() function. This value is +// concatenated to the beginning of all references to rawwave files in +// the various STK core classes (ex. Clarinet.cpp). If you wish to +// move the rawwaves directory to a different location in your file +// system, you will need to set this path definition appropriately. +#if !defined(RAWWAVE_PATH) + #define RAWWAVE_PATH "../../rawwaves/" +#endif + +const StkFloat PI = 3.14159265358979; +const StkFloat TWO_PI = 2 * PI; +const StkFloat ONE_OVER_128 = 0.0078125; + +#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_MM__) + #define __OS_WINDOWS__ + #define __STK_REALTIME__ +#elif defined(__LINUX_OSS__) || defined(__LINUX_ALSA__) || defined(__LINUX_JACK__) + #define __OS_LINUX__ + #define __STK_REALTIME__ +#elif defined(__IRIX_AL__) + #define __OS_IRIX__ + #define __STK_REALTIME__ +#elif defined(__MACOSX_CORE__) + #define __OS_MACOSX__ + #define __STK_REALTIME__ +#endif + +//#define _STK_DEBUG_ + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/WaveLoop.h b/nyqstk/include/WaveLoop.h new file mode 100644 index 0000000..67d345a --- /dev/null +++ b/nyqstk/include/WaveLoop.h @@ -0,0 +1,97 @@ +/***************************************************/ +/*! \class WaveLoop + \brief STK waveform oscillator class. + + This class inherits from FileWvIn and provides audio file looping + functionality. Any audio file that can be loaded by FileRead can + be looped using this class. + + WaveLoop supports multi-channel data. It is important to + distinguish the tick() methods, which return samples produced by + averaging across sample frames, from the tickFrame() methods, + which return references or pointers to multi-channel sample + frames. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_WAVELOOP_H +#define STK_WAVELOOP_H + +#include "FileWvIn.h" + +namespace Nyq +{ + +class WaveLoop : public FileWvIn +{ +public: + //! Default constructor. + WaveLoop( unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 ); + + //! Class constructor that opens a specified file. + WaveLoop( std::string fileName, bool raw = false, bool doNormalize = true, + unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 ); + + //! Class destructor. + virtual ~WaveLoop(); + + //! Open the specified file and load its data. + /*! + Data from a previously opened file will be overwritten by this + function. An StkError will be thrown if the file is not found, + its format is unknown, or a read error occurs. If the file data + is to be loaded incrementally from disk and normalization is + specified, a scaling will be applied with respect to fixed-point + limits. If the data format is floating-point, no scaling is + performed. + */ + void openFile( std::string fileName, bool raw = false, bool doNormalize = true ); + + //! Set the data read rate in samples. The rate can be negative. + /*! + If the rate value is negative, the data is read in reverse order. + */ + void setRate( StkFloat rate ); + + //! Set the data interpolation rate based on a looping frequency. + /*! + This function determines the interpolation rate based on the file + size and the current Stk::sampleRate. The \e frequency value + corresponds to file cycles per second. The frequency can be + negative, in which case the loop is read in reverse order. + */ + void setFrequency( StkFloat frequency ); + + //! Increment the read pointer by \e time samples, modulo file size. + void addTime( StkFloat time ); + + //! Increment current read pointer by \e angle, relative to a looping frequency. + /*! + This function increments the read pointer based on the file + size and the current Stk::sampleRate. The \e anAngle value + is a multiple of file size. + */ + void addPhase( StkFloat angle ); + + //! Add a phase offset to the current read pointer. + /*! + This function determines a time offset based on the file + size and the current Stk::sampleRate. The \e angle value + is a multiple of file size. + */ + void addPhaseOffset( StkFloat angle ); + +protected: + + virtual void computeFrame( void ); + + StkFrames firstFrame_; + StkFloat phaseOffset_; + +}; + +} // namespace Nyq + +#endif diff --git a/nyqstk/include/WvIn.h b/nyqstk/include/WvIn.h new file mode 100644 index 0000000..a4ee60b --- /dev/null +++ b/nyqstk/include/WvIn.h @@ -0,0 +1,92 @@ +/***************************************************/ +/*! \class WvIn + \brief STK audio input abstract base class. + + This class provides common functionality for a variety of audio + data input subclasses. + + WvIn supports multi-channel data. It is important to distinguish + the tick() methods, which return samples produced by averaging + across sample frames, from the tickFrame() methods, which return + references or pointers to multi-channel sample frames. + + Both interleaved and non-interleaved data is supported via the use + of StkFrames objects. + + by Perry R. Cook and Gary P. Scavone, 1995 - 2005. +*/ +/***************************************************/ + +#ifndef STK_WVIN_H +#define STK_WVIN_H + +#include "Stk.h" +#include <vector> + +namespace Nyq +{ + +class WvIn : public Stk +{ +public: + //! Default constructor. + WvIn(); + + //! Class destructor. + virtual ~WvIn(); + + //! Return the number of audio channels in the data. + unsigned int getChannels( void ) const { return data_.channels(); }; + + //! Return the average across the last output sample frame. + /*! + If no file data is loaded, the returned value is 0.0. + */ + StkFloat lastOut( void ) const; + + //! Return an StkFrames reference to the last output sample frame. + /*! + If no file data is loaded, an empty container is returned. + */ + const StkFrames& lastFrame( void ) const { return lastOutputs_; }; + + //! Read out the average across one sample frame of data. + /*! + If no file data is loaded, the returned value is 0.0. + */ + StkFloat tick( void ); + + //! Fill a channel of the StkFrames object with averaged sample frames. + /*! + The \c channel argument should be zero or greater (the first + channel is specified by 0). An StkError will be thrown if the \c + channel argument is greater than or equal to the number of + channels in the StkFrames object. If no file data is loaded, the + container is filled with zeroes. + */ + StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); + + //! Fill the StkFrames argument with data and return the same reference. + /*! + An StkError will be thrown if there is an incompatability + between the number of channels in the loaded data and that in the + StkFrames argument. If no file data is loaded, the container is + filled with zeroes. + */ + StkFrames& tickFrame( StkFrames& frames ); + +protected: + + // This abstract function must be implemented in all subclasses. + // It is used to get around a C++ problem with overloaded virtual + // functions. + virtual void computeFrame( void ) = 0; + + StkFrames data_; + StkFrames lastOutputs_; + +}; + +} // namespace Nyq + +#endif |