mirror of
https://github.com/thestk/stk
synced 2026-04-19 14:06:55 +00:00
Version 4.4.0
This commit is contained in:
committed by
Stephen Sinclair
parent
d199342e86
commit
eccd8c9981
147
include/ADSR.h
147
include/ADSR.h
@@ -1,86 +1,163 @@
|
||||
#ifndef STK_ADSR_H
|
||||
#define STK_ADSR_H
|
||||
|
||||
#include "Generator.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \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.
|
||||
This class 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 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_ADSR_H
|
||||
#define STK_ADSR_H
|
||||
|
||||
#include "Envelope.h"
|
||||
|
||||
class ADSR : public Envelope
|
||||
class ADSR : public Generator
|
||||
{
|
||||
public:
|
||||
|
||||
//! Envelope states.
|
||||
enum { ATTACK, DECAY, SUSTAIN, RELEASE, DONE };
|
||||
//! ADSR envelope states.
|
||||
enum {
|
||||
ATTACK, /*!< Attack */
|
||||
DECAY, /*!< Decay */
|
||||
SUSTAIN, /*!< Sustain */
|
||||
RELEASE, /*!< Release */
|
||||
DONE /*!< End of release */
|
||||
};
|
||||
|
||||
//! Default constructor.
|
||||
ADSR(void);
|
||||
ADSR( void );
|
||||
|
||||
//! Class destructor.
|
||||
~ADSR(void);
|
||||
~ADSR( void );
|
||||
|
||||
//! Set target = 1, state = \e ADSR::ATTACK.
|
||||
void keyOn(void);
|
||||
void keyOn( void );
|
||||
|
||||
//! Set target = 0, state = \e ADSR::RELEASE.
|
||||
void keyOff(void);
|
||||
void keyOff( void );
|
||||
|
||||
//! Set the attack rate.
|
||||
void setAttackRate(StkFloat rate);
|
||||
void setAttackRate( StkFloat rate );
|
||||
|
||||
//! Set the decay rate.
|
||||
void setDecayRate(StkFloat rate);
|
||||
void setDecayRate( StkFloat rate );
|
||||
|
||||
//! Set the sustain level.
|
||||
void setSustainLevel(StkFloat level);
|
||||
void setSustainLevel( StkFloat level );
|
||||
|
||||
//! Set the release rate.
|
||||
void setReleaseRate(StkFloat rate);
|
||||
void setReleaseRate( StkFloat rate );
|
||||
|
||||
//! Set the attack rate based on a time duration.
|
||||
void setAttackTime(StkFloat time);
|
||||
void setAttackTime( StkFloat time );
|
||||
|
||||
//! Set the decay rate based on a time duration.
|
||||
void setDecayTime(StkFloat time);
|
||||
void setDecayTime( StkFloat time );
|
||||
|
||||
//! Set the release rate based on a time duration.
|
||||
void setReleaseTime(StkFloat time);
|
||||
void setReleaseTime( StkFloat time );
|
||||
|
||||
//! Set sustain level and attack, decay, and release time durations.
|
||||
void setAllTimes(StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime);
|
||||
void setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime );
|
||||
|
||||
//! Set the target value.
|
||||
void setTarget(StkFloat target);
|
||||
void setTarget( StkFloat target );
|
||||
|
||||
//! Return the current envelope \e state (ATTACK, DECAY, SUSTAIN, RELEASE, DONE).
|
||||
int getState(void) const;
|
||||
int getState( void ) const { return state_; };
|
||||
|
||||
//! Set to state = ADSR::SUSTAIN with current and target values of \e aValue.
|
||||
void setValue(StkFloat value);
|
||||
//! Set to state = ADSR::SUSTAIN with current and target values of \e value.
|
||||
void setValue( StkFloat value );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
|
||||
int state_;
|
||||
StkFloat value_;
|
||||
StkFloat target_;
|
||||
StkFloat attackRate_;
|
||||
StkFloat decayRate_;
|
||||
StkFloat sustainLevel_;
|
||||
StkFloat releaseRate_;
|
||||
StkFloat sustainLevel_;
|
||||
};
|
||||
|
||||
inline StkFloat ADSR :: tick( void )
|
||||
{
|
||||
switch ( state_ ) {
|
||||
|
||||
case ATTACK:
|
||||
value_ += attackRate_;
|
||||
if ( value_ >= target_ ) {
|
||||
value_ = target_;
|
||||
target_ = sustainLevel_;
|
||||
state_ = DECAY;
|
||||
}
|
||||
lastFrame_[0] = value_;
|
||||
break;
|
||||
|
||||
case DECAY:
|
||||
value_ -= decayRate_;
|
||||
if ( value_ <= sustainLevel_ ) {
|
||||
value_ = sustainLevel_;
|
||||
state_ = SUSTAIN;
|
||||
}
|
||||
lastFrame_[0] = value_;
|
||||
break;
|
||||
|
||||
case RELEASE:
|
||||
value_ -= releaseRate_;
|
||||
if ( value_ <= 0.0 ) {
|
||||
value_ = (StkFloat) 0.0;
|
||||
state_ = DONE;
|
||||
}
|
||||
lastFrame_[0] = value_;
|
||||
|
||||
}
|
||||
|
||||
return value_;
|
||||
}
|
||||
|
||||
inline StkFrames& ADSR :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "ADSR::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = ADSR::tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
102
include/Asymp.h
102
include/Asymp.h
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_ASYMP_H
|
||||
#define STK_ASYMP_H
|
||||
|
||||
#include "Generator.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Asymp
|
||||
\brief STK asymptotic curve envelope class
|
||||
@@ -6,7 +13,7 @@
|
||||
which asymptotically approaches a target value.
|
||||
The algorithm used is of the form:
|
||||
|
||||
x[n] = a x[n-1] + (1-a) target,
|
||||
y[n] = a y[n-1] + (1-a) target,
|
||||
|
||||
where a = exp(-T/tau), T is the sample period, and
|
||||
tau is a time constant. The user can set the time
|
||||
@@ -19,32 +26,27 @@
|
||||
to \e keyOn and \e keyOff messages by ramping to
|
||||
1.0 on keyOn and to 0.0 on keyOff.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_ASYMP_H
|
||||
#define STK_ASYMP_H
|
||||
|
||||
#include "Envelope.h"
|
||||
|
||||
const StkFloat TARGET_THRESHOLD = 0.000001;
|
||||
|
||||
class Asymp : public Envelope
|
||||
class Asymp : public Generator
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor.
|
||||
Asymp(void);
|
||||
Asymp( void );
|
||||
|
||||
//! Class destructor.
|
||||
~Asymp(void);
|
||||
~Asymp( void );
|
||||
|
||||
//! Set target = 1.
|
||||
void keyOn(void);
|
||||
void keyOn( void );
|
||||
|
||||
//! Set target = 0.
|
||||
void keyOff(void);
|
||||
void keyOff( void );
|
||||
|
||||
//! Set the asymptotic rate via the time factor \e tau (must be > 0).
|
||||
/*!
|
||||
@@ -53,21 +55,89 @@ class Asymp : public Envelope
|
||||
fast approach rates, while values greater than 1.0 produce rather
|
||||
slow rates.
|
||||
*/
|
||||
void setTau(StkFloat tau);
|
||||
void setTau( StkFloat tau );
|
||||
|
||||
//! Set the asymptotic rate based on a time duration (must be > 0).
|
||||
void setTime(StkFloat time);
|
||||
void setTime( StkFloat time );
|
||||
|
||||
//! Set the target value.
|
||||
void setTarget(StkFloat target);
|
||||
void setTarget( StkFloat target );
|
||||
|
||||
//! Set current and target values to \e value.
|
||||
void setValue( StkFloat value );
|
||||
|
||||
//! Return the current envelope \e state (0 = at target, 1 otherwise).
|
||||
int getState( void ) const { return state_; };
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
|
||||
StkFloat value_;
|
||||
StkFloat target_;
|
||||
StkFloat factor_;
|
||||
StkFloat constant_;
|
||||
int state_;
|
||||
};
|
||||
|
||||
inline StkFloat Asymp :: tick( void )
|
||||
{
|
||||
if ( state_ ) {
|
||||
|
||||
value_ = factor_ * value_ + constant_;
|
||||
|
||||
// Check threshold.
|
||||
if ( target_ > value_ ) {
|
||||
if ( target_ - value_ <= TARGET_THRESHOLD ) {
|
||||
value_ = target_;
|
||||
state_ = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( value_ - target_ <= TARGET_THRESHOLD ) {
|
||||
value_ = target_;
|
||||
state_ = 0;
|
||||
}
|
||||
}
|
||||
lastFrame_[0] = value_;
|
||||
}
|
||||
|
||||
return value_;
|
||||
}
|
||||
|
||||
inline StkFrames& Asymp :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "Asymp::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = Asymp::tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
#ifndef STK_BANDEDWG_H
|
||||
#define STK_BANDEDWG_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayL.h"
|
||||
#include "BowTable.h"
|
||||
#include "ADSR.h"
|
||||
#include "BiQuad.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BandedWG
|
||||
\brief Banded waveguide modeling class.
|
||||
@@ -25,64 +36,56 @@
|
||||
- Tibetan Bowl = 3
|
||||
|
||||
by Georg Essl, 1999 - 2004.
|
||||
Modified for Stk 4.0 by Gary Scavone.
|
||||
Modified for STK 4.0 by Gary Scavone.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_BANDEDWG_H
|
||||
#define STK_BANDEDWG_H
|
||||
|
||||
const int MAX_BANDED_MODES = 20;
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayL.h"
|
||||
#include "BowTable.h"
|
||||
#include "ADSR.h"
|
||||
#include "BiQuad.h"
|
||||
|
||||
class BandedWG : public Instrmnt
|
||||
{
|
||||
public:
|
||||
//! Class constructor.
|
||||
BandedWG();
|
||||
BandedWG( void );
|
||||
|
||||
//! Class destructor.
|
||||
~BandedWG();
|
||||
~BandedWG( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set strike position (0.0 - 1.0).
|
||||
void setStrikePosition(StkFloat position);
|
||||
void setStrikePosition( StkFloat position );
|
||||
|
||||
//! Select a preset.
|
||||
void setPreset(int preset);
|
||||
void setPreset( int preset );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Apply bow velocity/pressure to instrument with given amplitude and rate of increase.
|
||||
void startBowing(StkFloat amplitude, StkFloat rate);
|
||||
void startBowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease bow velocity/breath pressure with given rate of decrease.
|
||||
void stopBowing(StkFloat rate);
|
||||
void stopBowing( StkFloat rate );
|
||||
|
||||
//! Pluck the instrument with given amplitude.
|
||||
void pluck(StkFloat amp);
|
||||
void pluck( StkFloat amp );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
bool doPluck_;
|
||||
bool trackVelocity_;
|
||||
int nModes_;
|
||||
@@ -108,4 +111,6 @@ class BandedWG : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_BEETHREE_H
|
||||
#define STK_BEETHREE_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BeeThree
|
||||
\brief STK Hammond-oid organ FM synthesis instrument.
|
||||
@@ -28,15 +35,10 @@
|
||||
type who should worry about this (making
|
||||
money) worry away.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_BEETHREE_H
|
||||
#define STK_BEETHREE_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
class BeeThree : public FM
|
||||
{
|
||||
public:
|
||||
@@ -44,17 +46,45 @@ class BeeThree : public FM
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
BeeThree();
|
||||
BeeThree( void );
|
||||
|
||||
//! Class destructor.
|
||||
~BeeThree();
|
||||
~BeeThree( void );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
};
|
||||
|
||||
inline StkFloat BeeThree :: tick( unsigned int )
|
||||
{
|
||||
register StkFloat temp;
|
||||
|
||||
if ( modDepth_ > 0.0 ) {
|
||||
temp = 1.0 + ( modDepth_ * vibrato_.tick() * 0.1 );
|
||||
waves_[0]->setFrequency( baseFrequency_ * temp * ratios_[0] );
|
||||
waves_[1]->setFrequency( baseFrequency_ * temp * ratios_[1] );
|
||||
waves_[2]->setFrequency( baseFrequency_ * temp * ratios_[2] );
|
||||
waves_[3]->setFrequency( baseFrequency_ * temp * ratios_[3] );
|
||||
}
|
||||
|
||||
waves_[3]->addPhaseOffset( twozero_.lastOut() );
|
||||
temp = control1_ * 2.0 * gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
|
||||
twozero_.tick( temp );
|
||||
|
||||
temp += control2_ * 2.0 * gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
|
||||
temp += gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
|
||||
temp += gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
|
||||
|
||||
lastFrame_[0] = temp * 0.125;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
160
include/BiQuad.h
160
include/BiQuad.h
@@ -1,23 +1,23 @@
|
||||
/***************************************************/
|
||||
/*! \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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_BIQUAD_H
|
||||
#define STK_BIQUAD_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
class BiQuad : protected Filter
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BiQuad
|
||||
\brief STK biquad (two-pole, two-zero) filter class.
|
||||
|
||||
This class implements a two-pole, two-zero digital filter.
|
||||
Methods are provided for creating a resonance or notch in the
|
||||
frequency response while maintaining a constant filter gain.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class BiQuad : public Filter
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -25,28 +25,28 @@ public:
|
||||
BiQuad();
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~BiQuad();
|
||||
~BiQuad();
|
||||
|
||||
//! A function to enable/disable the automatic updating of class data when the STK sample rate changes.
|
||||
void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; };
|
||||
|
||||
//! Clears all internal states of the filter.
|
||||
void clear(void);
|
||||
//! Set all filter coefficients.
|
||||
void setCoefficients( StkFloat b0, StkFloat b1, StkFloat b2, StkFloat a1, StkFloat a2, bool clearState = false );
|
||||
|
||||
//! Set the b[0] coefficient value.
|
||||
void setB0(StkFloat b0);
|
||||
void setB0( StkFloat b0 ) { b_[0] = b0; };
|
||||
|
||||
//! Set the b[1] coefficient value.
|
||||
void setB1(StkFloat b1);
|
||||
void setB1( StkFloat b1 ) { b_[1] = b1; };
|
||||
|
||||
//! Set the b[2] coefficient value.
|
||||
void setB2(StkFloat b2);
|
||||
void setB2( StkFloat b2 ) { b_[2] = b2; };
|
||||
|
||||
//! Set the a[1] coefficient value.
|
||||
void setA1(StkFloat a1);
|
||||
void setA1( StkFloat a1 ) { a_[1] = a1; };
|
||||
|
||||
//! Set the a[2] coefficient value.
|
||||
void setA2(StkFloat a2);
|
||||
void setA2( StkFloat a2 ) { a_[2] = a2; };
|
||||
|
||||
//! Sets the filter coefficients for a resonance at \e frequency (in Hz).
|
||||
/*!
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
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);
|
||||
void setResonance( StkFloat frequency, StkFloat radius, bool normalize = false );
|
||||
|
||||
//! Set the filter coefficients for a notch at \e frequency (in Hz).
|
||||
/*!
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
and \e radius from the z-plane origin. No filter normalization
|
||||
is attempted.
|
||||
*/
|
||||
void setNotch(StkFloat frequency, StkFloat radius);
|
||||
void setNotch( StkFloat frequency, StkFloat radius );
|
||||
|
||||
//! Sets the filter zeroes for equal resonance gain.
|
||||
/*!
|
||||
@@ -78,62 +78,106 @@ public:
|
||||
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;
|
||||
void setEqualGainZeroes( void );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut(void) const;
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Input one sample to the filter and return one output.
|
||||
virtual StkFloat tick(StkFloat sample);
|
||||
//! Input one sample to the filter and return a reference to one output.
|
||||
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.
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 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 );
|
||||
virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
};
|
||||
|
||||
inline StkFloat BiQuad :: computeSample( StkFloat input )
|
||||
inline StkFloat BiQuad :: tick( StkFloat input )
|
||||
{
|
||||
inputs_[0] = gain_ * input;
|
||||
outputs_[0] = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
|
||||
outputs_[0] -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
|
||||
lastFrame_[0] = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
|
||||
lastFrame_[0] -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
|
||||
inputs_[2] = inputs_[1];
|
||||
inputs_[1] = inputs_[0];
|
||||
outputs_[2] = outputs_[1];
|
||||
outputs_[1] = outputs_[0];
|
||||
outputs_[1] = lastFrame_[0];
|
||||
|
||||
return outputs_[0];
|
||||
}
|
||||
|
||||
inline StkFloat BiQuad :: tick( StkFloat input )
|
||||
{
|
||||
return this->computeSample( input );
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& BiQuad :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
return Filter::tick( frames, channel );
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "BiQuad::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
inputs_[0] = gain_ * *samples;
|
||||
*samples = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
|
||||
*samples -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
|
||||
inputs_[2] = inputs_[1];
|
||||
inputs_[1] = inputs_[0];
|
||||
outputs_[2] = outputs_[1];
|
||||
outputs_[1] = *samples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = outputs_[1];
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& BiQuad :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "BiQuad::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
inputs_[0] = gain_ * *iSamples;
|
||||
*oSamples = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
|
||||
*oSamples -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
|
||||
inputs_[2] = inputs_[1];
|
||||
inputs_[1] = inputs_[0];
|
||||
outputs_[2] = outputs_[1];
|
||||
outputs_[1] = *oSamples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = outputs_[1];
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
#ifndef STK_BLIT_H
|
||||
#define STK_BLIT_H
|
||||
|
||||
#include "Generator.h"
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Blit
|
||||
\brief STK band-limited impulse train class.
|
||||
@@ -21,11 +30,6 @@
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_BLIT_H
|
||||
#define STK_BLIT_H
|
||||
|
||||
#include "Generator.h"
|
||||
|
||||
class Blit: public Generator
|
||||
{
|
||||
public:
|
||||
@@ -68,10 +72,25 @@ class Blit: public Generator
|
||||
*/
|
||||
void setHarmonics( unsigned int nHarmonics = 0 );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
void updateHarmonics( void );
|
||||
StkFloat computeSample( void );
|
||||
|
||||
unsigned int nHarmonics_;
|
||||
unsigned int m_;
|
||||
@@ -81,4 +100,52 @@ class Blit: public Generator
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Blit :: tick( void )
|
||||
{
|
||||
// The code below implements the SincM algorithm of Stilson and
|
||||
// Smith with an additional scale factor of P / M applied to
|
||||
// normalize the output.
|
||||
|
||||
// A fully optimized version of this code would replace the two sin
|
||||
// calls with a pair of fast sin oscillators, for which stable fast
|
||||
// two-multiply algorithms are well known. In the spirit of STK,
|
||||
// which favors clarity over performance, the optimization has not
|
||||
// been made here.
|
||||
|
||||
// Avoid a divide by zero at the sinc peak, which has a limiting
|
||||
// value of 1.0.
|
||||
StkFloat tmp, denominator = sin( phase_ );
|
||||
if ( denominator <= std::numeric_limits<StkFloat>::epsilon() )
|
||||
tmp = 1.0;
|
||||
else {
|
||||
tmp = sin( m_ * phase_ );
|
||||
tmp /= m_ * denominator;
|
||||
}
|
||||
|
||||
phase_ += rate_;
|
||||
if ( phase_ >= PI ) phase_ -= PI;
|
||||
|
||||
lastFrame_[0] = tmp;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& Blit :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "Blit::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = Blit::tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
#ifndef STK_BLITSAW_H
|
||||
#define STK_BLITSAW_H
|
||||
|
||||
#include "Generator.h"
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BlitSaw
|
||||
\brief STK band-limited sawtooth wave class.
|
||||
@@ -19,11 +28,6 @@
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_BLITSAW_H
|
||||
#define STK_BLITSAW_H
|
||||
|
||||
#include "Generator.h"
|
||||
|
||||
class BlitSaw: public Generator
|
||||
{
|
||||
public:
|
||||
@@ -54,10 +58,25 @@ class BlitSaw: public Generator
|
||||
*/
|
||||
void setHarmonics( unsigned int nHarmonics = 0 );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
void updateHarmonics( void );
|
||||
StkFloat computeSample( void );
|
||||
|
||||
unsigned int nHarmonics_;
|
||||
unsigned int m_;
|
||||
@@ -70,4 +89,60 @@ class BlitSaw: public Generator
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat BlitSaw :: tick( void )
|
||||
{
|
||||
// The code below implements the BLIT algorithm of Stilson and
|
||||
// Smith, followed by a summation and filtering operation to produce
|
||||
// a sawtooth waveform. After experimenting with various approaches
|
||||
// to calculate the average value of the BLIT over one period, I
|
||||
// found that an estimate of C2_ = 1.0 / period (in samples) worked
|
||||
// most consistently. A "leaky integrator" is then applied to the
|
||||
// difference of the BLIT output and C2_. (GPS - 1 October 2005)
|
||||
|
||||
// A fully optimized version of this code would replace the two sin
|
||||
// calls with a pair of fast sin oscillators, for which stable fast
|
||||
// two-multiply algorithms are well known. In the spirit of STK,
|
||||
// which favors clarity over performance, the optimization has
|
||||
// not been made here.
|
||||
|
||||
// Avoid a divide by zero, or use of a denormalized divisor
|
||||
// at the sinc peak, which has a limiting value of m_ / p_.
|
||||
StkFloat tmp, denominator = sin( phase_ );
|
||||
if ( fabs(denominator) <= std::numeric_limits<StkFloat>::epsilon() )
|
||||
tmp = a_;
|
||||
else {
|
||||
tmp = sin( m_ * phase_ );
|
||||
tmp /= p_ * denominator;
|
||||
}
|
||||
|
||||
tmp += state_ - C2_;
|
||||
state_ = tmp * 0.995;
|
||||
|
||||
phase_ += rate_;
|
||||
if ( phase_ >= PI ) phase_ -= PI;
|
||||
|
||||
lastFrame_[0] = tmp;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& BlitSaw :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "BlitSaw::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = BlitSaw::tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
#ifndef STK_BLITSQUARE_H
|
||||
#define STK_BLITSQUARE_H
|
||||
|
||||
#include "Generator.h"
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BlitSquare
|
||||
\brief STK band-limited square wave class.
|
||||
@@ -30,11 +39,6 @@
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_BLITSQUARE_H
|
||||
#define STK_BLITSQUARE_H
|
||||
|
||||
#include "Generator.h"
|
||||
|
||||
class BlitSquare: public Generator
|
||||
{
|
||||
public:
|
||||
@@ -77,10 +81,25 @@ class BlitSquare: public Generator
|
||||
*/
|
||||
void setHarmonics( unsigned int nHarmonics = 0 );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
void updateHarmonics( void );
|
||||
StkFloat computeSample( void );
|
||||
|
||||
unsigned int nHarmonics_;
|
||||
unsigned int m_;
|
||||
@@ -92,4 +111,60 @@ class BlitSquare: public Generator
|
||||
StkFloat dcbState_;
|
||||
};
|
||||
|
||||
inline StkFloat BlitSquare :: tick( void )
|
||||
{
|
||||
StkFloat temp = lastBlitOutput_;
|
||||
|
||||
// A fully optimized version of this would replace the two sin calls
|
||||
// with a pair of fast sin oscillators, for which stable fast
|
||||
// two-multiply algorithms are well known. In the spirit of STK,
|
||||
// which favors clarity over performance, the optimization has
|
||||
// not been made here.
|
||||
|
||||
// Avoid a divide by zero, or use of a denomralized divisor
|
||||
// at the sinc peak, which has a limiting value of 1.0.
|
||||
StkFloat denominator = sin( phase_ );
|
||||
if ( fabs( denominator ) < std::numeric_limits<StkFloat>::epsilon() ) {
|
||||
// Inexact comparison safely distinguishes betwen *close to zero*, and *close to PI*.
|
||||
if ( phase_ < 0.1f || phase_ > TWO_PI - 0.1f )
|
||||
lastBlitOutput_ = a_;
|
||||
else
|
||||
lastBlitOutput_ = -a_;
|
||||
}
|
||||
else {
|
||||
lastBlitOutput_ = sin( m_ * phase_ );
|
||||
lastBlitOutput_ /= p_ * denominator;
|
||||
}
|
||||
|
||||
lastBlitOutput_ += temp;
|
||||
|
||||
// Now apply DC blocker.
|
||||
lastFrame_[0] = lastBlitOutput_ - dcbState_ + 0.999 * lastFrame_[0];
|
||||
dcbState_ = lastBlitOutput_;
|
||||
|
||||
phase_ += rate_;
|
||||
if ( phase_ >= TWO_PI ) phase_ -= TWO_PI;
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& BlitSquare :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "BlitSquare::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = BlitSquare::tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
#ifndef STK_BLOWBOTL_H
|
||||
#define STK_BLOWBOTL_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "JetTable.h"
|
||||
#include "BiQuad.h"
|
||||
#include "PoleZero.h"
|
||||
#include "Noise.h"
|
||||
#include "ADSR.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BlowBotl
|
||||
\brief STK blown bottle instrument class.
|
||||
@@ -12,21 +25,10 @@
|
||||
- Vibrato Gain = 1
|
||||
- Volume = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_BLOWBOTL_H
|
||||
#define STK_BLOWBOTL_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "JetTable.h"
|
||||
#include "BiQuad.h"
|
||||
#include "PoleZero.h"
|
||||
#include "Noise.h"
|
||||
#include "ADSR.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
class BlowBotl : public Instrmnt
|
||||
{
|
||||
public:
|
||||
@@ -34,36 +36,37 @@ class BlowBotl : public Instrmnt
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
BlowBotl();
|
||||
BlowBotl( void );
|
||||
|
||||
//! Class destructor.
|
||||
~BlowBotl();
|
||||
~BlowBotl( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Apply breath velocity to instrument with given amplitude and rate of increase.
|
||||
void startBlowing(StkFloat amplitude, StkFloat rate);
|
||||
void startBlowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath velocity with given rate of decrease.
|
||||
void stopBlowing(StkFloat rate);
|
||||
void stopBlowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
JetTable jetTable_;
|
||||
BiQuad resonator_;
|
||||
PoleZero dcBlock_;
|
||||
@@ -77,4 +80,28 @@ class BlowBotl : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat BlowBotl :: tick( unsigned int )
|
||||
{
|
||||
StkFloat breathPressure;
|
||||
StkFloat randPressure;
|
||||
StkFloat pressureDiff;
|
||||
|
||||
// Calculate the breath pressure (envelope + vibrato)
|
||||
breathPressure = maxPressure_ * adsr_.tick();
|
||||
breathPressure += vibratoGain_ * vibrato_.tick();
|
||||
|
||||
pressureDiff = breathPressure - resonator_.lastOut();
|
||||
|
||||
randPressure = noiseGain_ * noise_.tick();
|
||||
randPressure *= breathPressure;
|
||||
randPressure *= (1.0 + pressureDiff);
|
||||
|
||||
resonator_.tick( breathPressure + randPressure - ( jetTable_.tick( pressureDiff ) * pressureDiff ) );
|
||||
lastFrame_[0] = 0.2 * outputGain_ * dcBlock_.tick( pressureDiff );
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
#ifndef STK_BLOWHOLE_H
|
||||
#define STK_BLOWHOLE_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayL.h"
|
||||
#include "ReedTable.h"
|
||||
#include "OneZero.h"
|
||||
#include "PoleZero.h"
|
||||
#include "Envelope.h"
|
||||
#include "Noise.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BlowHole
|
||||
\brief STK clarinet physical model with one
|
||||
@@ -29,22 +43,10 @@
|
||||
- Register State = 1
|
||||
- Breath Pressure = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_BLOWHOLE_H
|
||||
#define STK_BLOWHOLE_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayL.h"
|
||||
#include "ReedTable.h"
|
||||
#include "OneZero.h"
|
||||
#include "PoleZero.h"
|
||||
#include "Envelope.h"
|
||||
#include "Noise.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
class BlowHole : public Instrmnt
|
||||
{
|
||||
public:
|
||||
@@ -52,42 +54,43 @@ class BlowHole : public Instrmnt
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
BlowHole(StkFloat lowestFrequency);
|
||||
BlowHole( StkFloat lowestFrequency );
|
||||
|
||||
//! Class destructor.
|
||||
~BlowHole();
|
||||
~BlowHole( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set the tonehole state (0.0 = closed, 1.0 = fully open).
|
||||
void setTonehole(StkFloat newValue);
|
||||
void setTonehole( StkFloat newValue );
|
||||
|
||||
//! Set the register hole state (0.0 = closed, 1.0 = fully open).
|
||||
void setVent(StkFloat newValue);
|
||||
void setVent( StkFloat newValue );
|
||||
|
||||
//! Apply breath pressure to instrument with given amplitude and rate of increase.
|
||||
void startBlowing(StkFloat amplitude, StkFloat rate);
|
||||
void startBlowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath pressure with given rate of decrease.
|
||||
void stopBlowing(StkFloat rate);
|
||||
void stopBlowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
DelayL delays_[3];
|
||||
ReedTable reedTable_;
|
||||
OneZero filter_;
|
||||
@@ -106,4 +109,41 @@ class BlowHole : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat BlowHole :: tick( unsigned int )
|
||||
{
|
||||
StkFloat pressureDiff;
|
||||
StkFloat breathPressure;
|
||||
StkFloat temp;
|
||||
|
||||
// Calculate the breath pressure (envelope + noise + vibrato)
|
||||
breathPressure = envelope_.tick();
|
||||
breathPressure += breathPressure * noiseGain_ * noise_.tick();
|
||||
breathPressure += breathPressure * vibratoGain_ * vibrato_.tick();
|
||||
|
||||
// Calculate the differential pressure = reflected - mouthpiece pressures
|
||||
pressureDiff = delays_[0].lastOut() - breathPressure;
|
||||
|
||||
// Do two-port junction scattering for register vent
|
||||
StkFloat pa = breathPressure + pressureDiff * reedTable_.tick( pressureDiff );
|
||||
StkFloat pb = delays_[1].lastOut();
|
||||
vent_.tick( pa+pb );
|
||||
|
||||
lastFrame_[0] = delays_[0].tick( vent_.lastOut()+pb );
|
||||
lastFrame_[0] *= outputGain_;
|
||||
|
||||
// Do three-port junction scattering (under tonehole)
|
||||
pa += vent_.lastOut();
|
||||
pb = delays_[2].lastOut();
|
||||
StkFloat pth = tonehole_.lastOut();
|
||||
temp = scatter_ * (pa + pb - 2 * pth);
|
||||
|
||||
delays_[2].tick( filter_.tick(pa + temp) * -0.95 );
|
||||
delays_[1].tick( pb + temp );
|
||||
tonehole_.tick( pa + pb - pth + temp );
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
#ifndef STK_BOWTABL_H
|
||||
#define STK_BOWTABL_H
|
||||
|
||||
#include "Function.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class BowTable
|
||||
\brief STK bowed string table class.
|
||||
@@ -5,23 +13,15 @@
|
||||
This class implements a simple bowed string
|
||||
non-linear function, as described by Smith (1986).
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_BOWTABL_H
|
||||
#define STK_BOWTABL_H
|
||||
|
||||
#include "Function.h"
|
||||
|
||||
class BowTable : public Function
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
BowTable();
|
||||
|
||||
//! Class destructor.
|
||||
~BowTable();
|
||||
BowTable( void ) : offset_(0.0), slope_(0.1) {};
|
||||
|
||||
//! Set the table offset value.
|
||||
/*!
|
||||
@@ -30,22 +30,111 @@ public:
|
||||
friction to vary with direction, use a non-zero
|
||||
value for the offset. The default value is zero.
|
||||
*/
|
||||
void setOffset(StkFloat offset);
|
||||
void setOffset( StkFloat offset ) { offset_ = 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);
|
||||
void setSlope( StkFloat slope ) { slope_ = slope; };
|
||||
|
||||
//! Take one sample input and map to one sample of output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the table and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the table and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( StkFloat input );
|
||||
|
||||
StkFloat offset_;
|
||||
StkFloat slope_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat BowTable :: tick( StkFloat input )
|
||||
{
|
||||
// The input represents differential string vs. bow velocity.
|
||||
StkFloat sample = input + offset_; // add bias to input
|
||||
sample *= slope_; // then scale it
|
||||
lastFrame_[0] = (StkFloat) fabs( (double) sample ) + (StkFloat) 0.75;
|
||||
lastFrame_[0] = (StkFloat) pow( lastFrame_[0], (StkFloat) -4.0 );
|
||||
|
||||
// Set minimum friction to 0.0
|
||||
// if ( lastFrame_[0] < 0.0 ) lastFrame_[0] = 0.0;
|
||||
|
||||
// Set maximum friction to 1.0.
|
||||
if ( lastFrame_[0] > 1.0 ) lastFrame_[0] = (StkFloat) 1.0;
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& BowTable :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "BowTable::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples = *samples + offset_;
|
||||
*samples *= slope_;
|
||||
*samples = (StkFloat) fabs( (double) *samples ) + 0.75;
|
||||
*samples = (StkFloat) pow( *samples, (StkFloat) -4.0 );
|
||||
if ( *samples > 1.0) *samples = 1.0;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& BowTable :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "BowTable::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
*oSamples = *iSamples + offset_;
|
||||
*oSamples *= slope_;
|
||||
*oSamples = (StkFloat) fabs( (double) *oSamples ) + 0.75;
|
||||
*oSamples = (StkFloat) pow( *oSamples, (StkFloat) -4.0 );
|
||||
if ( *oSamples > 1.0) *oSamples = 1.0;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
#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 stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Bowed
|
||||
\brief STK bowed string instrument class.
|
||||
@@ -17,58 +30,48 @@
|
||||
- Vibrato Gain = 1
|
||||
- Volume = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#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"
|
||||
|
||||
class Bowed : public Instrmnt
|
||||
{
|
||||
public:
|
||||
//! Class constructor, taking the lowest desired playing frequency.
|
||||
Bowed(StkFloat lowestFrequency);
|
||||
Bowed( StkFloat lowestFrequency );
|
||||
|
||||
//! Class destructor.
|
||||
~Bowed();
|
||||
~Bowed( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set vibrato gain.
|
||||
void setVibrato(StkFloat gain);
|
||||
void setVibrato( StkFloat gain );
|
||||
|
||||
//! Apply breath pressure to instrument with given amplitude and rate of increase.
|
||||
void startBowing(StkFloat amplitude, StkFloat rate);
|
||||
void startBowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath pressure with given rate of decrease.
|
||||
void stopBowing(StkFloat rate);
|
||||
void stopBowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
DelayL neckDelay_;
|
||||
DelayL bridgeDelay_;
|
||||
BowTable bowTable_;
|
||||
@@ -83,4 +86,27 @@ class Bowed : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Bowed :: tick( unsigned int )
|
||||
{
|
||||
StkFloat bowVelocity = maxVelocity_ * adsr_.tick();
|
||||
StkFloat bridgeRefl = -stringFilter_.tick( bridgeDelay_.lastOut() );
|
||||
StkFloat nutRefl = -neckDelay_.lastOut();
|
||||
StkFloat stringVel = bridgeRefl + nutRefl; // Sum is string velocity
|
||||
StkFloat velDiff = bowVelocity - stringVel; // Differential velocity
|
||||
StkFloat newVel = velDiff * bowTable_.tick( velDiff ); // Non-Linear bow function
|
||||
neckDelay_.tick(bridgeRefl + newVel); // Do string propagations
|
||||
bridgeDelay_.tick(nutRefl + newVel);
|
||||
|
||||
if ( vibratoGain_ > 0.0 ) {
|
||||
neckDelay_.setDelay( (baseDelay_ * (1.0 - betaRatio_) ) +
|
||||
(baseDelay_ * vibratoGain_ * vibrato_.tick()) );
|
||||
}
|
||||
|
||||
lastFrame_[0] = bodyFilter_.tick( bridgeDelay_.lastOut() );
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
#ifndef STK_BRASS_H
|
||||
#define STK_BRASS_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayA.h"
|
||||
#include "BiQuad.h"
|
||||
#include "PoleZero.h"
|
||||
#include "ADSR.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Brass
|
||||
\brief STK simple brass instrument class.
|
||||
@@ -16,20 +28,10 @@
|
||||
- Vibrato Gain = 1
|
||||
- Volume = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_BRASS_H
|
||||
#define STK_BRASS_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayA.h"
|
||||
#include "BiQuad.h"
|
||||
#include "PoleZero.h"
|
||||
#include "ADSR.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
class Brass: public Instrmnt
|
||||
{
|
||||
public:
|
||||
@@ -37,39 +39,40 @@ class Brass: public Instrmnt
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
Brass(StkFloat lowestFrequency);
|
||||
Brass( StkFloat lowestFrequency );
|
||||
|
||||
//! Class destructor.
|
||||
~Brass();
|
||||
~Brass( );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set the lips frequency.
|
||||
void setLip(StkFloat frequency);
|
||||
void setLip( StkFloat frequency );
|
||||
|
||||
//! Apply breath pressure to instrument with given amplitude and rate of increase.
|
||||
void startBlowing(StkFloat amplitude, StkFloat rate);
|
||||
void startBlowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath pressure with given rate of decrease.
|
||||
void stopBlowing(StkFloat rate);
|
||||
void stopBlowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
DelayA delayLine_;
|
||||
BiQuad lipFilter_;
|
||||
PoleZero dcBlock_;
|
||||
@@ -83,4 +86,25 @@ class Brass: public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Brass :: tick( unsigned int )
|
||||
{
|
||||
StkFloat breathPressure = maxPressure_ * adsr_.tick();
|
||||
breathPressure += vibratoGain_ * vibrato_.tick();
|
||||
|
||||
StkFloat mouthPressure = 0.3 * breathPressure;
|
||||
StkFloat borePressure = 0.85 * delayLine_.lastOut();
|
||||
StkFloat deltaPressure = mouthPressure - borePressure; // Differential pressure.
|
||||
deltaPressure = lipFilter_.tick( deltaPressure ); // Force - > position.
|
||||
deltaPressure *= deltaPressure; // Basic position to area mapping.
|
||||
if ( deltaPressure > 1.0 ) deltaPressure = 1.0; // Non-linear saturation.
|
||||
|
||||
// The following input scattering assumes the mouthPressure = area.
|
||||
lastFrame_[0] = deltaPressure * mouthPressure + ( 1.0 - deltaPressure) * borePressure;
|
||||
lastFrame_[0] = delayLine_.tick( dcBlock_.tick( lastFrame_[0] ) );
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
151
include/Chorus.h
151
include/Chorus.h
@@ -1,20 +1,23 @@
|
||||
#ifndef STK_CHORUS_H
|
||||
#define STK_CHORUS_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "DelayL.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Chorus
|
||||
\brief STK chorus effect class.
|
||||
|
||||
This class implements a chorus effect.
|
||||
This class implements a chorus effect. It takes a monophonic
|
||||
input signal and produces a stereo output signal.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_CHORUS_H
|
||||
#define STK_CHORUS_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "DelayL.h"
|
||||
#include "SineWave.h"
|
||||
|
||||
class Chorus : public Effect
|
||||
{
|
||||
public:
|
||||
@@ -24,22 +27,62 @@ class Chorus : public Effect
|
||||
*/
|
||||
Chorus( StkFloat baseDelay = 6000 );
|
||||
|
||||
//! Class destructor.
|
||||
~Chorus();
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set modulation depth.
|
||||
void setModDepth(StkFloat depth);
|
||||
void setModDepth( StkFloat depth ) { modDepth_ = depth; };
|
||||
|
||||
//! Set modulation frequency.
|
||||
void setModFrequency(StkFloat frequency);
|
||||
void setModFrequency( StkFloat frequency );
|
||||
|
||||
//! Return the specified channel value of the last computed stereo frame.
|
||||
/*!
|
||||
Use the lastFrame() function to get both values of the last
|
||||
computed stereo frame. The \c channel argument must be 0 or 1
|
||||
(the first channel is specified by 0). However, range checking is
|
||||
only performed if _STK_DEBUG_ is defined during compilation, in
|
||||
which case an out-of-range value will trigger an StkError
|
||||
exception.
|
||||
*/
|
||||
StkFloat lastOut( unsigned int channel = 0 );
|
||||
|
||||
//! Input one sample to the effect and return the specified \c channel value of the computed stereo frame.
|
||||
/*!
|
||||
Use the lastFrame() function to get both values of the computed
|
||||
stereo output frame. The \c channel argument must be 0 or 1 (the
|
||||
first channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFloat tick( StkFloat input, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the effect and replace with stereo outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The stereo
|
||||
outputs are written to the StkFrames argument starting at the
|
||||
specified \c channel. Therefore, the \c channel argument must be
|
||||
less than ( channels() - 1 ) of the StkFrames argument (the first
|
||||
channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the effect and write stereo outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. The \c iChannel
|
||||
argument must be less than the number of channels in the \c
|
||||
iFrames argument (the first channel is specified by 0). The \c
|
||||
oChannel argument must be less than ( channels() - 1 ) of the \c
|
||||
oFrames argument. However, range checking is only performed if
|
||||
_STK_DEBUG_ is defined during compilation, in which case an
|
||||
out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( StkFloat input );
|
||||
|
||||
DelayL delayLine_[2];
|
||||
SineWave mods_[2];
|
||||
StkFloat baseLength_;
|
||||
@@ -47,5 +90,79 @@ class Chorus : public Effect
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Chorus :: lastOut( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > 1 ) {
|
||||
errorString_ << "Chorus::lastOut(): channel argument must be less than 2!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
inline StkFloat Chorus :: tick( StkFloat input, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > 1 ) {
|
||||
errorString_ << "Chorus::tick(): channel argument must be less than 2!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
|
||||
delayLine_[1].setDelay( baseLength_ * 0.5 * ( 1.0 - modDepth_ * mods_[1].tick() ) );
|
||||
lastFrame_[0] = effectMix_ * ( delayLine_[0].tick( input ) - input ) + input;
|
||||
lastFrame_[1] = effectMix_ * ( delayLine_[1].tick( input ) - input ) + input;
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
inline StkFrames& Chorus :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() - 1 ) {
|
||||
errorString_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels() - 1;
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples = effectMix_ * ( delayLine_[0].tick( *samples ) - *samples ) + *samples;
|
||||
samples++;
|
||||
*samples = effectMix_ * ( delayLine_[1].tick( *samples ) - *samples ) + *samples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
lastFrame_[1] = *(samples-hop+1);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& Chorus :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
|
||||
errorString_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
*oSamples++ = effectMix_ * ( delayLine_[0].tick( *iSamples ) - *iSamples ) + *iSamples;
|
||||
*oSamples = effectMix_ * ( delayLine_[1].tick( *iSamples ) - *iSamples ) + *iSamples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
lastFrame_[1] = *(oSamples-oHop+1);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
#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 stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Clarinet
|
||||
\brief STK clarinet physical model class.
|
||||
@@ -18,21 +31,10 @@
|
||||
- Vibrato Gain = 1
|
||||
- Breath Pressure = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#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"
|
||||
|
||||
class Clarinet : public Instrmnt
|
||||
{
|
||||
public:
|
||||
@@ -40,36 +42,37 @@ class Clarinet : public Instrmnt
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
Clarinet(StkFloat lowestFrequency);
|
||||
Clarinet( StkFloat lowestFrequency );
|
||||
|
||||
//! Class destructor.
|
||||
~Clarinet();
|
||||
~Clarinet( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Apply breath pressure to instrument with given amplitude and rate of increase.
|
||||
void startBlowing(StkFloat amplitude, StkFloat rate);
|
||||
void startBlowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath pressure with given rate of decrease.
|
||||
void stopBlowing(StkFloat rate);
|
||||
void stopBlowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
DelayL delayLine_;
|
||||
ReedTable reedTable_;
|
||||
OneZero filter_;
|
||||
@@ -83,4 +86,31 @@ class Clarinet : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Clarinet :: tick( unsigned int )
|
||||
{
|
||||
StkFloat pressureDiff;
|
||||
StkFloat breathPressure;
|
||||
|
||||
// Calculate the breath pressure (envelope + noise + vibrato)
|
||||
breathPressure = envelope_.tick();
|
||||
breathPressure += breathPressure * noiseGain_ * noise_.tick();
|
||||
breathPressure += breathPressure * vibratoGain_ * vibrato_.tick();
|
||||
|
||||
// Perform commuted loss filtering.
|
||||
pressureDiff = -0.95 * filter_.tick( delayLine_.lastOut() );
|
||||
|
||||
// Calculate pressure difference of reflected and mouthpiece pressures.
|
||||
pressureDiff = pressureDiff - breathPressure;
|
||||
|
||||
// Perform non-linear scattering using pressure difference in reed function.
|
||||
lastFrame_[0] = delayLine_.tick(breathPressure + pressureDiff * reedTable_.tick(pressureDiff));
|
||||
|
||||
// Apply output gain.
|
||||
lastFrame_[0] *= outputGain_;
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
168
include/Delay.h
168
include/Delay.h
@@ -1,48 +1,40 @@
|
||||
/***************************************************/
|
||||
/*! \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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_DELAY_H
|
||||
#define STK_DELAY_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
class Delay : protected Filter
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Delay
|
||||
\brief STK non-interpolating delay line class.
|
||||
|
||||
This class implements a non-interpolating digital delay-line. If
|
||||
the delay and maximum length are not specified during
|
||||
instantiation, a fixed maximum length of 4095 and a delay of zero
|
||||
is set.
|
||||
|
||||
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 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Delay : public 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.
|
||||
//! The default constructor creates a delay-line with maximum length of 4095 samples and zero delay.
|
||||
/*!
|
||||
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);
|
||||
Delay( unsigned long delay = 0, unsigned long maxDelay = 4095 );
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~Delay();
|
||||
|
||||
//! Clears the internal state of the delay line.
|
||||
void clear();
|
||||
~Delay();
|
||||
|
||||
//! Set the maximum delay-line length.
|
||||
/*!
|
||||
@@ -52,19 +44,16 @@ public:
|
||||
likely occur. If the current maximum length is greater than the
|
||||
new length, no change will be made.
|
||||
*/
|
||||
void setMaximumDelay(unsigned long delay);
|
||||
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.
|
||||
The valid range for \e delay is from 0 to the maximum delay-line length.
|
||||
*/
|
||||
void setDelay(unsigned long delay);
|
||||
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;
|
||||
unsigned long getDelay( void ) const { return delay_; };
|
||||
|
||||
//! Return the value at \e tapDelay samples from the delay-line input.
|
||||
/*!
|
||||
@@ -72,39 +61,114 @@ public:
|
||||
relative to the last input value (i.e., a tapDelay of zero returns
|
||||
the last input value).
|
||||
*/
|
||||
StkFloat contentsAt(unsigned long tapDelay);
|
||||
StkFloat contentsAt( unsigned long tapDelay );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut(void) const;
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Return the value which will be output by the next call to tick().
|
||||
//! Return the value that will be output by the next call to tick().
|
||||
/*!
|
||||
This method is valid only for delay settings greater than zero!
|
||||
*/
|
||||
virtual StkFloat nextOut(void);
|
||||
StkFloat nextOut( void ) { return inputs_[outPoint_]; };
|
||||
|
||||
//! Calculate and return the signal energy in the delay-line.
|
||||
StkFloat energy( void ) const;
|
||||
|
||||
//! Input one sample to the filter and return one output.
|
||||
virtual StkFloat tick(StkFloat sample);
|
||||
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.
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 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_;
|
||||
unsigned long delay_;
|
||||
};
|
||||
|
||||
inline StkFloat Delay :: tick( StkFloat input )
|
||||
{
|
||||
inputs_[inPoint_++] = input * gain_;
|
||||
|
||||
// Check for end condition
|
||||
if ( inPoint_ == inputs_.size() )
|
||||
inPoint_ = 0;
|
||||
|
||||
// Read out next value
|
||||
lastFrame_[0] = inputs_[outPoint_++];
|
||||
|
||||
if ( outPoint_ == inputs_.size() )
|
||||
outPoint_ = 0;
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& Delay :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "Delay::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
inputs_[inPoint_++] = *samples * gain_;
|
||||
if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
|
||||
*samples = inputs_[outPoint_++];
|
||||
if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& Delay :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "Delay::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
inputs_[inPoint_++] = *iSamples * gain_;
|
||||
if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
|
||||
*oSamples = inputs_[outPoint_++];
|
||||
if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
177
include/DelayA.h
177
include/DelayA.h
@@ -1,12 +1,18 @@
|
||||
#ifndef STK_DELAYA_H
|
||||
#define STK_DELAYA_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \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.
|
||||
This class implements a fractional-length digital delay-line using
|
||||
a first-order allpass filter. If the delay and maximum length are
|
||||
not specified during instantiation, a fixed maximum length of 4095
|
||||
and a delay of 0.5 is set.
|
||||
|
||||
An allpass filter has unity magnitude gain but variable phase
|
||||
delay properties, making it useful in achieving fractional delays
|
||||
@@ -15,55 +21,94 @@
|
||||
minimum delay possible in this implementation is limited to a
|
||||
value of 0.5.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_DELAYA_H
|
||||
#define STK_DELAYA_H
|
||||
|
||||
#include "Delay.h"
|
||||
|
||||
class DelayA : public Delay
|
||||
class DelayA : public Filter
|
||||
{
|
||||
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.
|
||||
//! Default constructor creates a delay-line with maximum length of 4095 samples and delay = 0.5.
|
||||
/*!
|
||||
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);
|
||||
DelayA( StkFloat delay = 0.5, unsigned long maxDelay = 4095 );
|
||||
|
||||
//! Class destructor.
|
||||
~DelayA();
|
||||
|
||||
//! Clears the internal state of the delay line.
|
||||
void clear();
|
||||
//! Clears all internal states of the delay line.
|
||||
void clear( void );
|
||||
|
||||
//! 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.5 to the maximum delay-line length.
|
||||
The valid range for \e delay is from 0.5 to the maximum delay-line length.
|
||||
*/
|
||||
void setDelay(StkFloat delay);
|
||||
void setDelay( StkFloat delay );
|
||||
|
||||
//! Return the current delay-line length.
|
||||
StkFloat getDelay(void) const;
|
||||
StkFloat getDelay( void ) const { return delay_; };
|
||||
|
||||
//! 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 lastFrame_[0]; };
|
||||
|
||||
//! 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);
|
||||
StkFloat nextOut( void );
|
||||
|
||||
//! Input one sample to the filter and return one output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( StkFloat input );
|
||||
|
||||
unsigned long inPoint_;
|
||||
unsigned long outPoint_;
|
||||
StkFloat delay_;
|
||||
StkFloat alpha_;
|
||||
StkFloat coeff_;
|
||||
StkFloat apInput_;
|
||||
@@ -71,4 +116,86 @@ protected:
|
||||
bool doNextOut_;
|
||||
};
|
||||
|
||||
inline StkFloat DelayA :: nextOut( void )
|
||||
{
|
||||
if ( doNextOut_ ) {
|
||||
// Do allpass interpolation delay.
|
||||
nextOutput_ = -coeff_ * lastFrame_[0];
|
||||
nextOutput_ += apInput_ + ( coeff_ * inputs_[outPoint_] );
|
||||
doNextOut_ = false;
|
||||
}
|
||||
|
||||
return nextOutput_;
|
||||
}
|
||||
|
||||
inline StkFloat DelayA :: tick( StkFloat input )
|
||||
{
|
||||
inputs_[inPoint_++] = input * gain_;
|
||||
|
||||
// Increment input pointer modulo length.
|
||||
if ( inPoint_ == inputs_.size() )
|
||||
inPoint_ = 0;
|
||||
|
||||
lastFrame_[0] = nextOut();
|
||||
doNextOut_ = true;
|
||||
|
||||
// Save the allpass input and increment modulo length.
|
||||
apInput_ = inputs_[outPoint_++];
|
||||
if ( outPoint_ == inputs_.size() )
|
||||
outPoint_ = 0;
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& DelayA :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "DelayA::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
inputs_[inPoint_++] = *samples * gain_;
|
||||
if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
|
||||
*samples = nextOut();
|
||||
lastFrame_[0] = *samples;
|
||||
doNextOut_ = true;
|
||||
apInput_ = inputs_[outPoint_++];
|
||||
if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& DelayA :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "DelayA::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
inputs_[inPoint_++] = *iSamples * gain_;
|
||||
if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
|
||||
*oSamples = nextOut();
|
||||
lastFrame_[0] = *oSamples;
|
||||
doNextOut_ = true;
|
||||
apInput_ = inputs_[outPoint_++];
|
||||
if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
|
||||
}
|
||||
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
194
include/DelayL.h
194
include/DelayL.h
@@ -1,73 +1,197 @@
|
||||
/***************************************************/
|
||||
/*! \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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_DELAYL_H
|
||||
#define STK_DELAYL_H
|
||||
|
||||
#include "Delay.h"
|
||||
|
||||
class DelayL : public Delay
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class DelayL
|
||||
\brief STK linear interpolating delay line class.
|
||||
|
||||
This class implements a fractional-length digital delay-line using
|
||||
first-order linear interpolation. If the delay and maximum length
|
||||
are not specified during instantiation, a fixed maximum length of
|
||||
4095 and a delay of zero is set.
|
||||
|
||||
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 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class DelayL : public Filter
|
||||
{
|
||||
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);
|
||||
DelayL( StkFloat delay = 0.0, unsigned long maxDelay = 4095 );
|
||||
|
||||
//! Class destructor.
|
||||
~DelayL();
|
||||
|
||||
//! 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.
|
||||
The valid range for \e delay is from 0 to the maximum delay-line length.
|
||||
*/
|
||||
void setDelay(StkFloat delay);
|
||||
void setDelay( StkFloat delay );
|
||||
|
||||
//! Return the current delay-line length.
|
||||
StkFloat getDelay(void) const;
|
||||
StkFloat getDelay( void ) const { return delay_; };
|
||||
|
||||
//! 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 lastFrame_[0]; };
|
||||
|
||||
//! 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);
|
||||
StkFloat nextOut( void );
|
||||
|
||||
//! Input one sample to the filter and return one output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( StkFloat input );
|
||||
|
||||
unsigned long inPoint_;
|
||||
unsigned long outPoint_;
|
||||
StkFloat delay_;
|
||||
StkFloat alpha_;
|
||||
StkFloat omAlpha_;
|
||||
StkFloat nextOutput_;
|
||||
bool doNextOut_;
|
||||
};
|
||||
|
||||
inline StkFloat DelayL :: nextOut( void )
|
||||
{
|
||||
if ( doNextOut_ ) {
|
||||
// First 1/2 of interpolation
|
||||
nextOutput_ = inputs_[outPoint_] * omAlpha_;
|
||||
// Second 1/2 of interpolation
|
||||
if (outPoint_+1 < inputs_.size())
|
||||
nextOutput_ += inputs_[outPoint_+1] * alpha_;
|
||||
else
|
||||
nextOutput_ += inputs_[0] * alpha_;
|
||||
doNextOut_ = false;
|
||||
}
|
||||
|
||||
return nextOutput_;
|
||||
}
|
||||
|
||||
inline StkFloat DelayL :: tick( StkFloat input )
|
||||
{
|
||||
inputs_[inPoint_++] = input * gain_;
|
||||
|
||||
// Increment input pointer modulo length.
|
||||
if ( inPoint_ == inputs_.size() )
|
||||
inPoint_ = 0;
|
||||
|
||||
lastFrame_[0] = nextOut();
|
||||
doNextOut_ = true;
|
||||
|
||||
// Increment output pointer modulo length.
|
||||
if ( ++outPoint_ == inputs_.size() )
|
||||
outPoint_ = 0;
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& DelayL :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "DelayL::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
inputs_[inPoint_++] = *samples * gain_;
|
||||
if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
|
||||
*samples = nextOut();
|
||||
doNextOut_ = true;
|
||||
if ( ++outPoint_ == inputs_.size() ) outPoint_ = 0;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& DelayL :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "DelayL::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
inputs_[inPoint_++] = *iSamples * gain_;
|
||||
if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
|
||||
*oSamples = nextOut();
|
||||
doNextOut_ = true;
|
||||
if ( ++outPoint_ == inputs_.size() ) outPoint_ = 0;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
#ifndef STK_DRUMMER_H
|
||||
#define STK_DRUMMER_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "FileWvIn.h"
|
||||
#include "OnePole.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Drummer
|
||||
\brief STK drum sample player class.
|
||||
@@ -11,17 +20,10 @@
|
||||
of simultaneous voices) via a #define in the
|
||||
Drummer.h.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_DRUMMER_H
|
||||
#define STK_DRUMMER_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "FileWvIn.h"
|
||||
#include "OnePole.h"
|
||||
|
||||
const int DRUM_NUMWAVES = 11;
|
||||
const int DRUM_POLYPHONY = 4;
|
||||
|
||||
@@ -32,10 +34,10 @@ class Drummer : public Instrmnt
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
Drummer();
|
||||
Drummer( void );
|
||||
|
||||
//! Class destructor.
|
||||
~Drummer();
|
||||
~Drummer( void );
|
||||
|
||||
//! Start a note with the given drum type and amplitude.
|
||||
/*!
|
||||
@@ -44,15 +46,16 @@ class Drummer : public Instrmnt
|
||||
instrument. An StkError will be thrown if the rawwave path is
|
||||
incorrectly set.
|
||||
*/
|
||||
void noteOn(StkFloat instrument, StkFloat amplitude);
|
||||
void noteOn( StkFloat instrument, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
void noteOff( StkFloat amplitude );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
FileWvIn waves_[DRUM_POLYPHONY];
|
||||
OnePole filters_[DRUM_POLYPHONY];
|
||||
std::vector<int> soundOrder_;
|
||||
@@ -60,4 +63,30 @@ class Drummer : public Instrmnt
|
||||
int nSounding_;
|
||||
};
|
||||
|
||||
inline StkFloat Drummer :: tick( unsigned int )
|
||||
{
|
||||
lastFrame_[0] = 0.0;
|
||||
if ( nSounding_ == 0 ) return lastFrame_[0];
|
||||
|
||||
for ( int i=0; i<DRUM_POLYPHONY; i++ ) {
|
||||
if ( soundOrder_[i] >= 0 ) {
|
||||
if ( waves_[i].isFinished() ) {
|
||||
// Re-order the list.
|
||||
for ( int j=0; j<DRUM_POLYPHONY; j++ ) {
|
||||
if ( soundOrder_[j] > soundOrder_[i] )
|
||||
soundOrder_[j] -= 1;
|
||||
}
|
||||
soundOrder_[i] = -1;
|
||||
nSounding_--;
|
||||
}
|
||||
else
|
||||
lastFrame_[0] += filters_[i].tick( waves_[i].tick() );
|
||||
}
|
||||
}
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
#ifndef STK_ECHO_H
|
||||
#define STK_ECHO_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "Delay.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Echo
|
||||
\brief STK echo effect class.
|
||||
|
||||
This class implements an echo effect.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_ECHO_H
|
||||
#define STK_ECHO_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "Delay.h"
|
||||
|
||||
class Echo : public Effect
|
||||
{
|
||||
public:
|
||||
@@ -23,9 +25,6 @@ class Echo : public Effect
|
||||
*/
|
||||
Echo( unsigned long maximumDelay = (unsigned long) Stk::sampleRate() );
|
||||
|
||||
//! Class destructor.
|
||||
~Echo();
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
|
||||
@@ -35,14 +34,87 @@ class Echo : public Effect
|
||||
//! Set the delay line length in samples.
|
||||
void setDelay( unsigned long delay );
|
||||
|
||||
protected:
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
StkFloat computeSample( StkFloat input );
|
||||
//! Input one sample to the effect and return one output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the effect and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the effect and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
Delay delayLine_;
|
||||
unsigned long length_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Echo :: tick( StkFloat input )
|
||||
{
|
||||
lastFrame_[0] = effectMix_ * ( delayLine_.tick( input ) - input ) + input;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& Echo :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "Echo::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples = effectMix_ * ( delayLine_.tick( *samples ) - *samples ) + *samples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& Echo :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "Echo::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
*oSamples = effectMix_ * ( delayLine_.tick( *iSamples ) - *iSamples ) + *iSamples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,69 +1,79 @@
|
||||
#ifndef STK_EFFECT_H
|
||||
#define STK_EFFECT_H
|
||||
|
||||
#include "Stk.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Effect
|
||||
\brief STK abstract effects parent class.
|
||||
|
||||
This class provides common functionality for
|
||||
STK effects subclasses.
|
||||
This class provides common functionality for STK effects
|
||||
subclasses. It is general enough to support both monophonic and
|
||||
polyphonic input/output classes.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
#ifndef STK_EFFECT_H
|
||||
#define STK_EFFECT_H
|
||||
|
||||
class Effect : public Stk
|
||||
{
|
||||
public:
|
||||
//! Class constructor.
|
||||
Effect();
|
||||
Effect( void ) { lastFrame_.resize( 1, 1, 0.0 ); };
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~Effect();
|
||||
//! Return the number of output channels for the class.
|
||||
unsigned int channelsOut( void ) const { return lastFrame_.channels(); };
|
||||
|
||||
//! Return an StkFrames reference to the last output sample frame.
|
||||
const StkFrames& lastFrame( void ) const { return lastFrame_; };
|
||||
|
||||
//! 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 );
|
||||
//! Set the mixture of input and "effected" levels in the output (0.0 = input only, 1.0 = effect only).
|
||||
void setEffectMix( StkFloat mix );
|
||||
|
||||
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 );
|
||||
bool isPrime( unsigned int number );
|
||||
|
||||
StkFloat lastOutput_[2];
|
||||
StkFrames lastFrame_;
|
||||
StkFloat effectMix_;
|
||||
|
||||
};
|
||||
|
||||
inline void Effect :: setEffectMix( StkFloat mix )
|
||||
{
|
||||
if ( mix < 0.0 ) {
|
||||
errorString_ << "Effect::setEffectMix: mix parameter is less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
effectMix_ = 0.0;
|
||||
}
|
||||
else if ( mix > 1.0 ) {
|
||||
errorString_ << "Effect::setEffectMix: mix parameter is greater than 1.0 ... setting to one!";
|
||||
handleError( StkError::WARNING );
|
||||
effectMix_ = 1.0;
|
||||
}
|
||||
else
|
||||
effectMix_ = mix;
|
||||
}
|
||||
|
||||
inline bool Effect :: isPrime( unsigned int number )
|
||||
{
|
||||
if ( number == 2 ) return true;
|
||||
if ( number & 1 ) {
|
||||
for ( int i=3; i<(int)sqrt((double)number)+1; i+=2 )
|
||||
if ( (number % i) == 0 ) return false;
|
||||
return true; // prime
|
||||
}
|
||||
else return false; // even
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,64 +1,76 @@
|
||||
/***************************************************/
|
||||
/*! \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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_ENVELOPE_H
|
||||
#define STK_ENVELOPE_H
|
||||
|
||||
#include "Generator.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Envelope
|
||||
\brief STK linear line envelope class.
|
||||
|
||||
This class implements a simple linear line envelope generator
|
||||
which is capable of ramping to an arbitrary 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 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Envelope : public Generator
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor.
|
||||
Envelope(void);
|
||||
|
||||
//! Copy constructor.
|
||||
Envelope( const Envelope& e );
|
||||
Envelope( void );
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~Envelope(void);
|
||||
~Envelope( void );
|
||||
|
||||
//! Assignment operator.
|
||||
Envelope& operator= ( const Envelope& e );
|
||||
|
||||
//! Set target = 1.
|
||||
virtual void keyOn(void);
|
||||
void keyOn( void ) { this->setTarget( 1.0 ); };
|
||||
|
||||
//! Set target = 0.
|
||||
virtual void keyOff(void);
|
||||
void keyOff( void ) { this->setTarget( 0.0 ); };
|
||||
|
||||
//! Set the \e rate.
|
||||
void setRate(StkFloat rate);
|
||||
void setRate( StkFloat rate );
|
||||
|
||||
//! Set the \e rate based on a time duration.
|
||||
void setTime(StkFloat time);
|
||||
void setTime( StkFloat time );
|
||||
|
||||
//! Set the target value.
|
||||
virtual void setTarget(StkFloat target);
|
||||
void setTarget( StkFloat target );
|
||||
|
||||
//! Set current and target values to \e aValue.
|
||||
virtual void setValue(StkFloat value);
|
||||
//! Set current and target values to \e value.
|
||||
void setValue( StkFloat value );
|
||||
|
||||
//! Return the current envelope \e state (0 = at target, 1 otherwise).
|
||||
virtual int getState(void) const;
|
||||
int getState( void ) const { return state_; };
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
virtual StkFloat computeSample( void );
|
||||
virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
|
||||
StkFloat value_;
|
||||
StkFloat target_;
|
||||
@@ -66,4 +78,85 @@ class Envelope : public Generator
|
||||
int state_;
|
||||
};
|
||||
|
||||
inline void Envelope :: setRate( StkFloat rate )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( rate < 0.0 ) {
|
||||
errorString_ << "Envelope::setRate: negative rates not allowed ... correcting!";
|
||||
handleError( StkError::WARNING );
|
||||
rate_ = -rate;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
rate_ = rate;
|
||||
}
|
||||
|
||||
inline void Envelope :: setTime( StkFloat time )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( time < 0.0 ) {
|
||||
errorString_ << "Envelope::setTime: negative times not allowed ... correcting!";
|
||||
handleError( StkError::WARNING );
|
||||
rate_ = 1.0 / ( -time * Stk::sampleRate() );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
rate_ = 1.0 / ( time * Stk::sampleRate() );
|
||||
}
|
||||
|
||||
inline void Envelope :: setTarget( StkFloat target )
|
||||
{
|
||||
target_ = target;
|
||||
if ( value_ != target_ ) state_ = 1;
|
||||
}
|
||||
|
||||
inline void Envelope :: setValue( StkFloat value )
|
||||
{
|
||||
state_ = 0;
|
||||
target_ = value;
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
inline StkFloat Envelope :: tick( void )
|
||||
{
|
||||
if ( state_ ) {
|
||||
if ( target_ > value_ ) {
|
||||
value_ += rate_;
|
||||
if ( value_ >= target_ ) {
|
||||
value_ = target_;
|
||||
state_ = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
value_ -= rate_;
|
||||
if ( value_ <= target_ ) {
|
||||
value_ = target_;
|
||||
state_ = 0;
|
||||
}
|
||||
}
|
||||
lastFrame_[0] = value_;
|
||||
}
|
||||
|
||||
return value_;
|
||||
}
|
||||
|
||||
inline StkFrames& Envelope :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "Envelope::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
59
include/FM.h
59
include/FM.h
@@ -1,3 +1,14 @@
|
||||
#ifndef STK_FM_H
|
||||
#define STK_FM_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "ADSR.h"
|
||||
#include "FileLoop.h"
|
||||
#include "SineWave.h"
|
||||
#include "TwoZero.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class FM
|
||||
\brief STK abstract FM synthesis base class.
|
||||
@@ -19,19 +30,10 @@
|
||||
type who should worry about this (making
|
||||
money) worry away.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_FM_H
|
||||
#define STK_FM_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "ADSR.h"
|
||||
#include "WaveLoop.h"
|
||||
#include "SineWave.h"
|
||||
#include "TwoZero.h"
|
||||
|
||||
class FM : public Instrmnt
|
||||
{
|
||||
public:
|
||||
@@ -42,53 +44,54 @@ class FM : public Instrmnt
|
||||
FM( unsigned int operators = 4 );
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~FM();
|
||||
virtual ~FM( void );
|
||||
|
||||
//! Reset and clear all wave and envelope states.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Load the rawwave filenames in waves.
|
||||
void loadWaves(const char **filenames);
|
||||
void loadWaves( const char **filenames );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
virtual void setFrequency(StkFloat frequency);
|
||||
virtual void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set the frequency ratio for the specified wave.
|
||||
void setRatio(unsigned int waveIndex, StkFloat ratio);
|
||||
void setRatio( unsigned int waveIndex, StkFloat ratio );
|
||||
|
||||
//! Set the gain for the specified wave.
|
||||
void setGain(unsigned int waveIndex, StkFloat gain);
|
||||
void setGain( unsigned int waveIndex, StkFloat gain );
|
||||
|
||||
//! Set the modulation speed in Hz.
|
||||
void setModulationSpeed(StkFloat mSpeed);
|
||||
void setModulationSpeed( StkFloat mSpeed ) { vibrato_.setFrequency( mSpeed ); };
|
||||
|
||||
//! Set the modulation depth.
|
||||
void setModulationDepth(StkFloat mDepth);
|
||||
void setModulationDepth( StkFloat mDepth ) { modDepth_ = mDepth; };
|
||||
|
||||
//! Set the value of control1.
|
||||
void setControl1(StkFloat cVal);
|
||||
void setControl1( StkFloat cVal ) { control1_ = cVal * 2.0; };
|
||||
|
||||
//! Set the value of control1.
|
||||
void setControl2(StkFloat cVal);
|
||||
void setControl2( StkFloat cVal ) { control2_ = cVal * 2.0; };
|
||||
|
||||
//! Start envelopes toward "on" targets.
|
||||
void keyOn();
|
||||
void keyOn( void );
|
||||
|
||||
//! Start envelopes toward "off" targets.
|
||||
void keyOff();
|
||||
void keyOff( void );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
virtual void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
virtual StkFloat tick( unsigned int ) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
virtual StkFloat computeSample( void ) = 0;
|
||||
|
||||
std::vector<ADSR *> adsr_;
|
||||
std::vector<WaveLoop *> waves_;
|
||||
std::vector<FileLoop *> waves_;
|
||||
SineWave vibrato_;
|
||||
TwoZero twozero_;
|
||||
unsigned int nOperators_;
|
||||
@@ -104,4 +107,6 @@ class FM : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_FMVOICES_H
|
||||
#define STK_FMVOICES_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class FMVoices
|
||||
\brief STK singing FM synthesis instrument.
|
||||
@@ -26,15 +33,10 @@
|
||||
type who should worry about this (making
|
||||
money) worry away.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_FMVOICES_H
|
||||
#define STK_FMVOICES_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
class FMVoices : public FM
|
||||
{
|
||||
public:
|
||||
@@ -42,27 +44,55 @@ class FMVoices : public FM
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
FMVoices();
|
||||
FMVoices( void );
|
||||
|
||||
//! Class destructor.
|
||||
~FMVoices();
|
||||
~FMVoices( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
virtual void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
|
||||
virtual void controlChange(int number, StkFloat value);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
int currentVowel_;
|
||||
StkFloat tilt_[3];
|
||||
StkFloat mods_[3];
|
||||
};
|
||||
|
||||
inline StkFloat FMVoices :: tick( unsigned int )
|
||||
{
|
||||
register StkFloat temp, temp2;
|
||||
|
||||
temp = gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
|
||||
temp2 = vibrato_.tick() * modDepth_ * 0.1;
|
||||
|
||||
waves_[0]->setFrequency(baseFrequency_ * (1.0 + temp2) * ratios_[0]);
|
||||
waves_[1]->setFrequency(baseFrequency_ * (1.0 + temp2) * ratios_[1]);
|
||||
waves_[2]->setFrequency(baseFrequency_ * (1.0 + temp2) * ratios_[2]);
|
||||
waves_[3]->setFrequency(baseFrequency_ * (1.0 + temp2) * ratios_[3]);
|
||||
|
||||
waves_[0]->addPhaseOffset(temp * mods_[0]);
|
||||
waves_[1]->addPhaseOffset(temp * mods_[1]);
|
||||
waves_[2]->addPhaseOffset(temp * mods_[2]);
|
||||
waves_[3]->addPhaseOffset( twozero_.lastOut() );
|
||||
twozero_.tick( temp );
|
||||
temp = gains_[0] * tilt_[0] * adsr_[0]->tick() * waves_[0]->tick();
|
||||
temp += gains_[1] * tilt_[1] * adsr_[1]->tick() * waves_[1]->tick();
|
||||
temp += gains_[2] * tilt_[2] * adsr_[2]->tick() * waves_[2]->tick();
|
||||
|
||||
lastFrame_[0] = temp * 0.33;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
161
include/FileLoop.h
Normal file
161
include/FileLoop.h
Normal file
@@ -0,0 +1,161 @@
|
||||
#ifndef STK_FILELOOP_H
|
||||
#define STK_FILELOOP_H
|
||||
|
||||
#include "FileWvIn.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class FileLoop
|
||||
\brief STK file looping / oscillator class.
|
||||
|
||||
This class provides audio file looping functionality. Any audio
|
||||
file that can be loaded by FileRead can be looped using this
|
||||
class.
|
||||
|
||||
FileLoop supports multi-channel data. It is important to
|
||||
distinguish the tick() method that computes a single frame (and
|
||||
returns only the specified sample of a multi-channel frame) from
|
||||
the overloaded one that takes an StkFrames object for
|
||||
multi-channel and/or multi-frame data.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class FileLoop : protected FileWvIn
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
FileLoop( unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 );
|
||||
|
||||
//! Class constructor that opens a specified file.
|
||||
FileLoop( std::string fileName, bool raw = false, bool doNormalize = true,
|
||||
unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 );
|
||||
|
||||
//! Class destructor.
|
||||
~FileLoop( void );
|
||||
|
||||
//! 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 ) { FileWvIn::closeFile(); };
|
||||
|
||||
//! Clear outputs and reset time (file) pointer to zero.
|
||||
void reset( void ) { FileWvIn::reset(); };
|
||||
|
||||
//! Normalize data to a maximum of +-1.0.
|
||||
/*!
|
||||
This function has no effect when data is incrementally loaded
|
||||
from disk.
|
||||
*/
|
||||
void normalize( void ) { FileWvIn::normalize( 1.0 ); };
|
||||
|
||||
//! Normalize data to a maximum of \e +-peak.
|
||||
/*!
|
||||
This function has no effect when data is incrementally loaded
|
||||
from disk.
|
||||
*/
|
||||
void normalize( StkFloat peak ) { FileWvIn::normalize( 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(); };
|
||||
|
||||
//! 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 ) { this->setRate( file_.fileSize() * frequency / Stk::sampleRate() ); };
|
||||
|
||||
//! 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 );
|
||||
|
||||
//! Return the specified channel value of the last computed frame.
|
||||
/*!
|
||||
For multi-channel files, use the lastFrame() function to get
|
||||
all values from the last computed frame. If no file data is
|
||||
loaded, the returned value is 0.0. The \c channel argument must
|
||||
be less than the number of channels in the file data (the first
|
||||
channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFloat lastOut( unsigned int channel = 0 ) { return FileWvIn::lastOut( channel ); };
|
||||
|
||||
//! Compute a sample frame and return the specified \c channel value.
|
||||
/*!
|
||||
For multi-channel files, use the lastFrame() function to get
|
||||
all values from the computed frame. If no file data is loaded,
|
||||
the returned value is 0.0. The \c channel argument must be less
|
||||
than the number of channels in the file data (the first channel is
|
||||
specified by 0). However, range checking is only performed if
|
||||
_STK_DEBUG_ is defined during compilation, in which case an
|
||||
out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Fill the StkFrames argument with computed frames and return the same reference.
|
||||
/*!
|
||||
The number of channels in the StkFrames argument should equal
|
||||
the number of channels in the file data. However, this is only
|
||||
checked if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an incompatibility will trigger an StkError exception. If no
|
||||
file data is loaded, the function does nothing (a warning will be
|
||||
issued if _STK_DEBUG_ is defined during compilation and
|
||||
Stk::showWarnings() has been set to \e true).
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames );
|
||||
|
||||
protected:
|
||||
|
||||
StkFrames firstFrame_;
|
||||
StkFloat phaseOffset_;
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_FILEREAD_H
|
||||
#define STK_FILEREAD_H
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class FileRead
|
||||
\brief STK audio file input class.
|
||||
@@ -25,20 +32,15 @@
|
||||
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 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_FILEREAD_H
|
||||
#define STK_FILEREAD_H
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
class FileRead : public Stk
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
FileRead();
|
||||
FileRead( void );
|
||||
|
||||
//! Overloaded constructor that opens a file during instantiation.
|
||||
/*!
|
||||
@@ -51,7 +53,7 @@ public:
|
||||
StkFormat format = STK_SINT16, StkFloat rate = 22050.0 );
|
||||
|
||||
//! Class destructor.
|
||||
~FileRead();
|
||||
~FileRead( void );
|
||||
|
||||
//! Open the specified file and determine its formatting.
|
||||
/*!
|
||||
@@ -126,4 +128,6 @@ protected:
|
||||
StkFloat fileRate_;
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_FILEWRITE_H
|
||||
#define STK_FILEWRITE_H
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class FileWrite
|
||||
\brief STK audio file output class.
|
||||
@@ -17,15 +24,10 @@
|
||||
type, the data type will automatically be modified. Compressed
|
||||
data types are not supported.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_FILEWRITE_H
|
||||
#define STK_FILEWRITE_H
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
class FileWrite : public Stk
|
||||
{
|
||||
public:
|
||||
@@ -39,7 +41,7 @@ class FileWrite : public Stk
|
||||
static const FILE_TYPE FILE_MAT; /*!< Matlab MAT-file type. */
|
||||
|
||||
//! Default constructor.
|
||||
FileWrite();
|
||||
FileWrite( void );
|
||||
|
||||
//! Overloaded constructor used to specify a file name, type, and data format with this object.
|
||||
/*!
|
||||
@@ -109,4 +111,6 @@ class FileWrite : public Stk
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
#ifndef STK_FILEWVIN_H
|
||||
#define STK_FILEWVIN_H
|
||||
|
||||
#include "WvIn.h"
|
||||
#include "FileRead.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \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".
|
||||
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 supports multi-channel data. It is important to
|
||||
distinguish the tick() method that computes a single frame (and
|
||||
returns only the specified sample of a multi-channel frame) from
|
||||
the overloaded one that takes an StkFrames object for
|
||||
multi-channel and/or multi-frame data.
|
||||
|
||||
FileWvIn will either load the entire content of an audio file into
|
||||
local memory or incrementally read file data from disk in chunks.
|
||||
@@ -21,22 +30,15 @@
|
||||
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.
|
||||
functions return zeros 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 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_FILEWVIN_H
|
||||
#define STK_FILEWVIN_H
|
||||
|
||||
#include "WvIn.h"
|
||||
#include "FileRead.h"
|
||||
|
||||
class FileWvIn : public WvIn
|
||||
{
|
||||
public:
|
||||
@@ -52,7 +54,7 @@ public:
|
||||
unsigned long chunkThreshold = 1000000, unsigned long chunkSize = 1024 );
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~FileWvIn();
|
||||
~FileWvIn( void );
|
||||
|
||||
//! Open the specified file and load its data.
|
||||
/*!
|
||||
@@ -64,30 +66,30 @@ public:
|
||||
limits. If the data format is floating-point, no scaling is
|
||||
performed.
|
||||
*/
|
||||
void openFile( std::string fileName, bool raw = false, bool doNormalize = true );
|
||||
virtual void openFile( std::string fileName, bool raw = false, bool doNormalize = true );
|
||||
|
||||
//! Close a file if one is open.
|
||||
void closeFile( void );
|
||||
virtual void closeFile( void );
|
||||
|
||||
//! Clear outputs and reset time (file) pointer to zero.
|
||||
void reset( void );
|
||||
virtual 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 );
|
||||
virtual 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 );
|
||||
virtual void normalize( StkFloat peak );
|
||||
|
||||
//! Return the file size in sample frames.
|
||||
unsigned long getSize( void ) const { return data_.frames(); };
|
||||
virtual unsigned long getSize( void ) const { return data_.frames(); };
|
||||
|
||||
//! Return the input file sample rate in Hz (not the data read rate).
|
||||
/*!
|
||||
@@ -95,7 +97,7 @@ public:
|
||||
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(); };
|
||||
virtual StkFloat getFileRate( void ) const { return data_.dataRate(); };
|
||||
|
||||
//! Query whether reading is complete.
|
||||
bool isFinished( void ) const { return finished_; };
|
||||
@@ -104,7 +106,7 @@ public:
|
||||
/*!
|
||||
If the rate value is negative, the data is read in reverse order.
|
||||
*/
|
||||
void setRate( StkFloat rate );
|
||||
virtual void setRate( StkFloat rate );
|
||||
|
||||
//! Increment the read pointer by \e time samples.
|
||||
/*!
|
||||
@@ -121,12 +123,44 @@ public:
|
||||
*/
|
||||
void setInterpolate( bool doInterpolate ) { interpolate_ = doInterpolate; };
|
||||
|
||||
StkFloat lastOut( void ) const;
|
||||
//! Return the specified channel value of the last computed frame.
|
||||
/*!
|
||||
If no file is loaded, the returned value is 0.0. The \c
|
||||
channel argument must be less than the number of output channels,
|
||||
which can be determined with the channelsOut() function (the first
|
||||
channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception. \sa
|
||||
lastFrame()
|
||||
*/
|
||||
StkFloat lastOut( unsigned int channel = 0 );
|
||||
|
||||
//! Compute a sample frame and return the specified \c channel value.
|
||||
/*!
|
||||
For multi-channel files, use the lastFrame() function to get
|
||||
all values from the computed frame. If no file data is loaded,
|
||||
the returned value is 0.0. The \c channel argument must be less
|
||||
than the number of channels in the file data (the first channel is
|
||||
specified by 0). However, range checking is only performed if
|
||||
_STK_DEBUG_ is defined during compilation, in which case an
|
||||
out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
virtual StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Fill the StkFrames argument with computed frames and return the same reference.
|
||||
/*!
|
||||
The number of channels in the StkFrames argument must equal
|
||||
the number of channels in the file data. However, this is only
|
||||
checked if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an incompatibility will trigger an StkError exception. If no
|
||||
file data is loaded, the function does nothing (a warning will be
|
||||
issued if _STK_DEBUG_ is defined during compilation).
|
||||
*/
|
||||
virtual StkFrames& tick( StkFrames& frames );
|
||||
|
||||
protected:
|
||||
|
||||
virtual void computeFrame( void );
|
||||
virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
|
||||
FileRead file_;
|
||||
bool finished_;
|
||||
@@ -141,4 +175,19 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat FileWvIn :: lastOut( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= data_.channels() ) {
|
||||
errorString_ << "FileWvIn::lastOut(): channel argument and soundfile data are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( finished_ ) return 0.0;
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
#ifndef STK_FILEWVOUT_H
|
||||
#define STK_FILEWVOUT_H
|
||||
|
||||
#include "WvOut.h"
|
||||
#include "FileWrite.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class FileWvOut
|
||||
\brief STK audio file output class.
|
||||
@@ -7,9 +15,9 @@
|
||||
|
||||
FileWvOut writes samples to an audio file and supports
|
||||
multi-channel data. It is important to distinguish the tick()
|
||||
methods, which output single samples to all channels in a sample
|
||||
frame, from the tickFrame() methods, which take a pointer or
|
||||
reference to multi-channel sample frame data.
|
||||
method that outputs a single sample to all channels in a sample
|
||||
frame from the overloaded one that takes a reference to an
|
||||
StkFrames object for multi-channel and/or multi-frame data.
|
||||
|
||||
See the FileWrite class for a description of the supported audio
|
||||
file formats.
|
||||
@@ -17,16 +25,10 @@
|
||||
Currently, FileWvOut is non-interpolating and the output rate is
|
||||
always Stk::sampleRate().
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_FILEWVOUT_H
|
||||
#define STK_FILEWVOUT_H
|
||||
|
||||
#include "WvOut.h"
|
||||
#include "FileWrite.h"
|
||||
|
||||
class FileWvOut : public WvOut
|
||||
{
|
||||
public:
|
||||
@@ -69,12 +71,23 @@ class FileWvOut : public WvOut
|
||||
*/
|
||||
void closeFile( void );
|
||||
|
||||
//! Output a single sample to all channels in a sample frame.
|
||||
/*!
|
||||
An StkError is thrown if an output error occurs.
|
||||
*/
|
||||
void tick( const StkFloat sample );
|
||||
|
||||
//! Output the StkFrames data.
|
||||
/*!
|
||||
An StkError will be thrown if an output error occurs. An
|
||||
StkError will also be thrown if _STK_DEBUG_ is defined during
|
||||
compilation and there is an incompatability between the number of
|
||||
channels in the FileWvOut object and that in the StkFrames object.
|
||||
*/
|
||||
void tick( const StkFrames& frames );
|
||||
|
||||
protected:
|
||||
|
||||
void computeSample( const StkFloat sample );
|
||||
|
||||
void computeFrames( const StkFrames& frames );
|
||||
|
||||
void incrementFrame( void );
|
||||
|
||||
FileWrite file_;
|
||||
@@ -84,4 +97,6 @@ class FileWvOut : public WvOut
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
138
include/Filter.h
138
include/Filter.h
@@ -1,122 +1,86 @@
|
||||
/***************************************************/
|
||||
/*! \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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_FILTER_H
|
||||
#define STK_FILTER_H
|
||||
|
||||
#include "Stk.h"
|
||||
#include <vector>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Filter
|
||||
\brief STK abstract filter class.
|
||||
|
||||
This class provides limited common functionality for STK digital
|
||||
filter subclasses. It is general enough to support both
|
||||
monophonic and polyphonic input/output classes.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Filter : public Stk
|
||||
{
|
||||
public:
|
||||
//! Default constructor creates a zero-order pass-through "filter".
|
||||
Filter(void);
|
||||
//! Class constructor.
|
||||
Filter( void ) { gain_ = 1.0; channelsIn_ = 1; lastFrame_.resize( 1, 1, 0.0 ); };
|
||||
|
||||
//! 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 );
|
||||
//! Return the number of input channels for the class.
|
||||
unsigned int channelsIn( void ) const { return channelsIn_; };
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~Filter(void);
|
||||
//! Return the number of output channels for the class.
|
||||
unsigned int channelsOut( void ) const { return lastFrame_.channels(); };
|
||||
|
||||
//! 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 );
|
||||
//! Clears all internal states of the filter.
|
||||
virtual void clear( void );
|
||||
|
||||
//! 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);
|
||||
void setGain( StkFloat gain ) { gain_ = gain; };
|
||||
|
||||
//! Return the current filter gain.
|
||||
virtual StkFloat getGain(void) const;
|
||||
StkFloat getGain( void ) const { return gain_; };
|
||||
|
||||
//! 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 );
|
||||
//! Return an StkFrames reference to the last output sample frame.
|
||||
const StkFrames& lastFrame( void ) const { return lastFrame_; };
|
||||
|
||||
//! 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.
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
unsigned int channelsIn_;
|
||||
StkFrames lastFrame_;
|
||||
|
||||
StkFloat gain_;
|
||||
std::vector<StkFloat> b_;
|
||||
std::vector<StkFloat> a_;
|
||||
std::vector<StkFloat> outputs_;
|
||||
std::vector<StkFloat> inputs_;
|
||||
StkFrames outputs_;
|
||||
StkFrames inputs_;
|
||||
|
||||
};
|
||||
|
||||
inline void Filter :: clear( void )
|
||||
{
|
||||
unsigned int i;
|
||||
for ( i=0; i<inputs_.size(); i++ )
|
||||
inputs_[i] = 0.0;
|
||||
for ( i=0; i<outputs_.size(); i++ )
|
||||
outputs_[i] = 0.0;
|
||||
for ( i=0; i<lastFrame_.size(); i++ )
|
||||
lastFrame_[i] = 0.0;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
155
include/Fir.h
Normal file
155
include/Fir.h
Normal file
@@ -0,0 +1,155 @@
|
||||
#ifndef STK_FIR_H
|
||||
#define STK_FIR_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Fir
|
||||
\brief STK general finite impulse response filter class.
|
||||
|
||||
This class provides a generic digital filter structure that can be
|
||||
used to implement FIR filters. For filters with feedback terms,
|
||||
the Iir class should be used.
|
||||
|
||||
In particular, this class implements the standard difference
|
||||
equation:
|
||||
|
||||
y[n] = b[0]*x[n] + ... + b[nb]*x[n-nb]
|
||||
|
||||
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 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Fir : public Filter
|
||||
{
|
||||
public:
|
||||
//! Default constructor creates a zero-order pass-through "filter".
|
||||
Fir( void );
|
||||
|
||||
//! Overloaded constructor which takes filter coefficients.
|
||||
/*!
|
||||
An StkError can be thrown if the coefficient vector size is
|
||||
zero.
|
||||
*/
|
||||
Fir( std::vector<StkFloat> &coefficients );
|
||||
|
||||
//! Class destructor.
|
||||
~Fir( void );
|
||||
|
||||
//! Set filter coefficients.
|
||||
/*!
|
||||
An StkError can be thrown if the coefficient vector size is
|
||||
zero. The internal state of the filter is not cleared unless the
|
||||
\e clearState flag is \c true.
|
||||
*/
|
||||
void setCoefficients( std::vector<StkFloat> &coefficients, bool clearState = false );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Input one sample to the filter and return one output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Fir :: tick( StkFloat input )
|
||||
{
|
||||
lastFrame_[0] = 0.0;
|
||||
inputs_[0] = gain_ * input;
|
||||
|
||||
for ( unsigned int i=b_.size()-1; i>0; i-- ) {
|
||||
lastFrame_[0] += b_[i] * inputs_[i];
|
||||
inputs_[i] = inputs_[i-1];
|
||||
}
|
||||
lastFrame_[0] += b_[0] * inputs_[0];
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& Fir :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "Fir::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int i, hop = frames.channels();
|
||||
for ( unsigned int j=0; j<frames.frames(); j++, samples += hop ) {
|
||||
inputs_[0] = gain_ * *samples;
|
||||
*samples = 0.0;
|
||||
|
||||
for ( i=b_.size()-1; i>0; i-- ) {
|
||||
*samples += b_[i] * inputs_[i];
|
||||
inputs_[i] = inputs_[i-1];
|
||||
}
|
||||
*samples += b_[0] * inputs_[0];
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& Fir :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "Fir::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int i, iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int j=0; j<iFrames.frames(); j++, iSamples += iHop, oSamples += oHop ) {
|
||||
inputs_[0] = gain_ * *iSamples;
|
||||
*oSamples = 0.0;
|
||||
|
||||
for ( i=b_.size()-1; i>0; i-- ) {
|
||||
*oSamples += b_[i] * inputs_[i];
|
||||
inputs_[i] = inputs_[i-1];
|
||||
}
|
||||
*oSamples += b_[0] * inputs_[0];
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,17 @@
|
||||
#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 stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Flute
|
||||
\brief STK flute physical model class.
|
||||
@@ -18,22 +32,10 @@
|
||||
- Vibrato Gain = 1
|
||||
- Breath Pressure = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#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"
|
||||
|
||||
class Flute : public Instrmnt
|
||||
{
|
||||
public:
|
||||
@@ -41,45 +43,46 @@ class Flute : public Instrmnt
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
Flute(StkFloat lowestFrequency);
|
||||
Flute( StkFloat lowestFrequency );
|
||||
|
||||
//! Class destructor.
|
||||
~Flute();
|
||||
~Flute( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set the reflection coefficient for the jet delay (-1.0 - 1.0).
|
||||
void setJetReflection(StkFloat coefficient);
|
||||
void setJetReflection( StkFloat coefficient );
|
||||
|
||||
//! Set the reflection coefficient for the air column delay (-1.0 - 1.0).
|
||||
void setEndReflection(StkFloat coefficient);
|
||||
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);
|
||||
void setJetDelay( StkFloat aRatio );
|
||||
|
||||
//! Apply breath velocity to instrument with given amplitude and rate of increase.
|
||||
void startBlowing(StkFloat amplitude, StkFloat rate);
|
||||
void startBlowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath velocity with given rate of decrease.
|
||||
void stopBlowing(StkFloat rate);
|
||||
void stopBlowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
DelayL jetDelay_;
|
||||
DelayL boreDelay_;
|
||||
JetTable jetTable_;
|
||||
@@ -100,4 +103,27 @@ class Flute : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Flute :: tick( unsigned int )
|
||||
{
|
||||
StkFloat pressureDiff;
|
||||
StkFloat breathPressure;
|
||||
|
||||
// Calculate the breath pressure (envelope + noise + vibrato)
|
||||
breathPressure = maxPressure_ * adsr_.tick();
|
||||
breathPressure += breathPressure * ( noiseGain_ * noise_.tick() + vibratoGain_ * vibrato_.tick() );
|
||||
|
||||
StkFloat temp = filter_.tick( boreDelay_.lastOut() );
|
||||
temp = dcBlock_.tick( temp ); // Block DC on reflection.
|
||||
|
||||
pressureDiff = breathPressure - (jetReflection_ * temp);
|
||||
pressureDiff = jetDelay_.tick( pressureDiff );
|
||||
pressureDiff = jetTable_.tick( pressureDiff ) + (endReflection_ * temp);
|
||||
lastFrame_[0] = (StkFloat) 0.3 * boreDelay_.tick( pressureDiff );
|
||||
|
||||
lastFrame_[0] *= outputGain_;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,32 +1,35 @@
|
||||
#ifndef STK_FORMSWEP_H
|
||||
#define STK_FORMSWEP_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class FormSwep
|
||||
\brief STK sweepable formant filter class.
|
||||
|
||||
This public BiQuad filter subclass implements
|
||||
a formant (resonance) which can be "swept"
|
||||
over time from one frequency setting to another.
|
||||
It provides methods for controlling the sweep
|
||||
rate and target frequency.
|
||||
This class implements a formant (resonance) which can be "swept"
|
||||
over time from one frequency setting to another. It provides
|
||||
methods for controlling the sweep rate and target frequency.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_FORMSWEP_H
|
||||
#define STK_FORMSWEP_H
|
||||
|
||||
#include "BiQuad.h"
|
||||
|
||||
class FormSwep : public BiQuad
|
||||
class FormSwep : public Filter
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor creates a second-order pass-through filter.
|
||||
FormSwep();
|
||||
FormSwep( void );
|
||||
|
||||
//! Class destructor.
|
||||
~FormSwep();
|
||||
|
||||
//! A function to enable/disable the automatic updating of class data when the STK sample rate changes.
|
||||
void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; };
|
||||
|
||||
//! Sets the filter coefficients for a resonance at \e frequency (in Hz).
|
||||
/*!
|
||||
This method determines the filter coefficients corresponding to
|
||||
@@ -39,13 +42,13 @@ class FormSwep : public BiQuad
|
||||
the unit-circle (\e radius close to one), the narrower the
|
||||
resulting resonance width.
|
||||
*/
|
||||
void setResonance(StkFloat frequency, StkFloat radius);
|
||||
void setResonance( StkFloat frequency, StkFloat radius );
|
||||
|
||||
//! Set both the current and target resonance parameters.
|
||||
void setStates(StkFloat frequency, StkFloat radius, StkFloat gain = 1.0);
|
||||
void setStates( StkFloat frequency, StkFloat radius, StkFloat gain = 1.0 );
|
||||
|
||||
//! Set target resonance parameters.
|
||||
void setTargets(StkFloat frequency, StkFloat radius, StkFloat gain = 1.0);
|
||||
void setTargets( StkFloat frequency, StkFloat radius, StkFloat gain = 1.0 );
|
||||
|
||||
//! Set the sweep rate (between 0.0 - 1.0).
|
||||
/*!
|
||||
@@ -56,7 +59,7 @@ class FormSwep : public BiQuad
|
||||
target values. A sweep rate of 0.0 will produce no
|
||||
change in resonance parameters.
|
||||
*/
|
||||
void setSweepRate(StkFloat rate);
|
||||
void setSweepRate( StkFloat rate );
|
||||
|
||||
//! Set the sweep rate in terms of a time value in seconds.
|
||||
/*!
|
||||
@@ -64,11 +67,39 @@ class FormSwep : public BiQuad
|
||||
given time for the formant parameters to reach
|
||||
their target values.
|
||||
*/
|
||||
void setSweepTime(StkFloat time);
|
||||
void setSweepTime( StkFloat time );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Input one sample to the filter and return a reference to one output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( StkFloat input );
|
||||
virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
|
||||
bool dirty_;
|
||||
StkFloat frequency_;
|
||||
@@ -87,4 +118,71 @@ class FormSwep : public BiQuad
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat FormSwep :: tick( StkFloat input )
|
||||
{
|
||||
if ( dirty_ ) {
|
||||
sweepState_ += sweepRate_;
|
||||
if ( sweepState_ >= 1.0 ) {
|
||||
sweepState_ = 1.0;
|
||||
dirty_ = false;
|
||||
radius_ = targetRadius_;
|
||||
frequency_ = targetFrequency_;
|
||||
gain_ = targetGain_;
|
||||
}
|
||||
else {
|
||||
radius_ = startRadius_ + (deltaRadius_ * sweepState_);
|
||||
frequency_ = startFrequency_ + (deltaFrequency_ * sweepState_);
|
||||
gain_ = startGain_ + (deltaGain_ * sweepState_);
|
||||
}
|
||||
this->setResonance( frequency_, radius_ );
|
||||
}
|
||||
|
||||
inputs_[0] = gain_ * input;
|
||||
lastFrame_[0] = b_[0] * inputs_[0] + b_[1] * inputs_[1] + b_[2] * inputs_[2];
|
||||
lastFrame_[0] -= a_[2] * outputs_[2] + a_[1] * outputs_[1];
|
||||
inputs_[2] = inputs_[1];
|
||||
inputs_[1] = inputs_[0];
|
||||
outputs_[2] = outputs_[1];
|
||||
outputs_[1] = lastFrame_[0];
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& FormSwep :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "FormSwep::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = tick( *samples );
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& FormSwep :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "FormSwep::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop )
|
||||
*oSamples = tick( *iSamples );
|
||||
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,54 +1,41 @@
|
||||
#ifndef STK_FUNCTION_H
|
||||
#define STK_FUNCTION_H
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Function
|
||||
\brief STK abstract function parent class.
|
||||
|
||||
This class provides common functionality for STK classes which
|
||||
This class provides common functionality for STK classes that
|
||||
implement tables or other types of input to output function
|
||||
mappings.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
#ifndef STK_FUNCTION_H
|
||||
#define STK_FUNCTION_H
|
||||
|
||||
class Function : public Stk
|
||||
{
|
||||
public:
|
||||
//! Class constructor.
|
||||
Function();
|
||||
Function( void ) { lastFrame_.resize( 1, 1, 0.0 ); };
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~Function();
|
||||
|
||||
//! Return the last output value.
|
||||
virtual StkFloat lastOut() const { return lastOutput_; };
|
||||
//! Return the last computed output sample.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! 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 );
|
||||
virtual StkFloat tick( StkFloat input ) = 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_;
|
||||
StkFrames lastFrame_;
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,53 +1,50 @@
|
||||
/***************************************************/
|
||||
/*! \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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_GENERATOR_H
|
||||
#define STK_GENERATOR_H
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Generator
|
||||
\brief STK abstract unit generator parent class.
|
||||
|
||||
This class provides limited common functionality for STK unit
|
||||
generator sample-source subclasses. It is general enough to
|
||||
support both monophonic and polyphonic output classes.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Generator : public Stk
|
||||
{
|
||||
public:
|
||||
|
||||
//! Class constructor.
|
||||
Generator( void );
|
||||
Generator( void ) { lastFrame_.resize( 1, 1, 0.0 ); };
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~Generator( void );
|
||||
//! Return the number of output channels for the class.
|
||||
unsigned int channelsOut( void ) const { return lastFrame_.channels(); };
|
||||
|
||||
//! Return the last output value.
|
||||
virtual StkFloat lastOut( void ) const { return lastOutput_; };
|
||||
//! Return an StkFrames reference to the last output sample frame.
|
||||
const StkFrames& lastFrame( void ) const { return lastFrame_; };
|
||||
|
||||
//! Compute one sample and output.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
//! Fill the StkFrames object with computed sample frames, starting at the specified channel.
|
||||
/*!
|
||||
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.
|
||||
The \c channel argument plus the number of output channels must
|
||||
be less than the number of channels in the StkFrames argument (the
|
||||
first channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ) = 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_;
|
||||
protected:
|
||||
|
||||
StkFrames lastFrame_;
|
||||
};
|
||||
|
||||
#endif
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,20 +1,3 @@
|
||||
/***************************************************/
|
||||
/*! \class Granulate
|
||||
\brief STK granular synthesis class.
|
||||
|
||||
This class implements a real-time granular synthesis algorithm
|
||||
that operates on an input soundfile. Currently, only monophonic
|
||||
files are supported. Various functions are provided to allow
|
||||
control over voice and grain parameters.
|
||||
|
||||
The functionality of this class is based on the program MacPod by
|
||||
Chris Rolfe and Damian Keller, though there are likely to be a
|
||||
number of differences in the actual implementation.
|
||||
|
||||
by Gary Scavone, 2005.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_GRANULATE_H
|
||||
#define STK_GRANULATE_H
|
||||
|
||||
@@ -23,6 +6,25 @@
|
||||
#include "Envelope.h"
|
||||
#include "Noise.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Granulate
|
||||
\brief STK granular synthesis class.
|
||||
|
||||
This class implements a real-time granular synthesis algorithm
|
||||
that operates on an input soundfile. Multi-channel files are
|
||||
supported. Various functions are provided to allow control over
|
||||
voice and grain parameters.
|
||||
|
||||
The functionality of this class is based on the program MacPod by
|
||||
Chris Rolfe and Damian Keller, though there are likely to be a
|
||||
number of differences in the actual implementation.
|
||||
|
||||
by Gary Scavone, 2005 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Granulate: public Generator
|
||||
{
|
||||
public:
|
||||
@@ -33,7 +35,7 @@ class Granulate: public Generator
|
||||
Granulate( unsigned int nVoices, std::string fileName, bool typeRaw = false );
|
||||
|
||||
//! Class destructor.
|
||||
~Granulate();
|
||||
~Granulate( void );
|
||||
|
||||
//! Load a monophonic soundfile to be "granulated".
|
||||
/*!
|
||||
@@ -47,7 +49,7 @@ class Granulate: public Generator
|
||||
Multiple grains are offset from one another in time by grain
|
||||
duration / nVoices.
|
||||
*/
|
||||
void reset();
|
||||
void reset( void );
|
||||
|
||||
//! Set the number of simultaneous grain "voices" to use.
|
||||
/*!
|
||||
@@ -96,6 +98,30 @@ class Granulate: public Generator
|
||||
*/
|
||||
void setRandomFactor( StkFloat randomness = 0.1 );
|
||||
|
||||
//! Return the specified channel value of the last computed frame.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of output
|
||||
channels, which can be determined with the channelsOut() function
|
||||
(the first channel is specified by 0). However, range checking is
|
||||
only performed if _STK_DEBUG_ is defined during compilation, in
|
||||
which case an out-of-range value will trigger an StkError
|
||||
exception. \sa lastFrame()
|
||||
*/
|
||||
StkFloat lastOut( unsigned int channel = 0 );
|
||||
|
||||
//! Compute one sample frame and return the specified \c channel value.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Fill the StkFrames object with computed sample frames, starting at the specified channel.
|
||||
/*!
|
||||
The \c channel argument plus the number of output channels must
|
||||
be less than the number of channels in the StkFrames argument (the
|
||||
first channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
enum GrainState {
|
||||
GRAIN_STOPPED,
|
||||
GRAIN_FADEIN,
|
||||
@@ -124,7 +150,6 @@ class Granulate: public Generator
|
||||
delayCount(0), counter(0), pointer(0), startPointer(0), repeats(0), state(GRAIN_STOPPED) {}
|
||||
};
|
||||
|
||||
StkFloat computeSample( void );
|
||||
void calculateGrain( Granulate::Grain& grain );
|
||||
|
||||
StkFrames data_;
|
||||
@@ -144,4 +169,39 @@ class Granulate: public Generator
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Granulate :: lastOut( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= lastFrame_.channels() ) {
|
||||
errorString_ << "Granulate::lastOut(): channel argument is invalid!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
inline StkFrames& Granulate :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > frames.channels() - nChannels ) {
|
||||
errorString_ << "Granulate::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int j, hop = frames.channels() - nChannels;
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples++ = tick();
|
||||
for ( j=1; j<nChannels; j++ )
|
||||
*samples++ = lastFrame_[j];
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_HEVYMETL_H
|
||||
#define STK_HEVYMETL_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class HevyMetl
|
||||
\brief STK heavy metal FM synthesis instrument.
|
||||
@@ -24,15 +31,10 @@
|
||||
type who should worry about this (making
|
||||
money) worry away.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_HEVYMETL_H
|
||||
#define STK_HEVYMETL_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
class HevyMetl : public FM
|
||||
{
|
||||
public:
|
||||
@@ -40,17 +42,48 @@ class HevyMetl : public FM
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
HevyMetl();
|
||||
HevyMetl( void );
|
||||
|
||||
//! Class destructor.
|
||||
~HevyMetl();
|
||||
~HevyMetl( void );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
};
|
||||
|
||||
inline StkFloat HevyMetl :: tick( unsigned int )
|
||||
{
|
||||
register StkFloat temp;
|
||||
|
||||
temp = vibrato_.tick() * modDepth_ * 0.2;
|
||||
waves_[0]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[0]);
|
||||
waves_[1]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[1]);
|
||||
waves_[2]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[2]);
|
||||
waves_[3]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[3]);
|
||||
|
||||
temp = gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
|
||||
waves_[1]->addPhaseOffset( temp );
|
||||
|
||||
waves_[3]->addPhaseOffset( twozero_.lastOut() );
|
||||
temp = (1.0 - (control2_ * 0.5)) * gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
|
||||
twozero_.tick(temp);
|
||||
|
||||
temp += control2_ * 0.5 * gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
|
||||
temp = temp * control1_;
|
||||
|
||||
waves_[0]->addPhaseOffset( temp );
|
||||
temp = gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
|
||||
|
||||
lastFrame_[0] = temp * 0.5;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
202
include/Iir.h
Normal file
202
include/Iir.h
Normal file
@@ -0,0 +1,202 @@
|
||||
#ifndef STK_IIR_H
|
||||
#define STK_IIR_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Iir
|
||||
\brief STK general infinite impulse response filter class.
|
||||
|
||||
This class provides a generic digital filter structure that can be
|
||||
used to implement IIR filters. For filters containing only
|
||||
feedforward terms, the Fir class is slightly more efficient.
|
||||
|
||||
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 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Iir : public Filter
|
||||
{
|
||||
public:
|
||||
//! Default constructor creates a zero-order pass-through "filter".
|
||||
Iir( 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.
|
||||
*/
|
||||
Iir( std::vector<StkFloat> &bCoefficients, std::vector<StkFloat> &aCoefficients );
|
||||
|
||||
//! Class destructor.
|
||||
~Iir( 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 );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Input one sample to the filter and return one output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the filter and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Iir :: tick( StkFloat input )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
outputs_[0] = 0.0;
|
||||
inputs_[0] = gain_ * input;
|
||||
for ( i=b_.size()-1; i>0; i-- ) {
|
||||
outputs_[0] += b_[i] * inputs_[i];
|
||||
inputs_[i] = inputs_[i-1];
|
||||
}
|
||||
outputs_[0] += b_[0] * inputs_[0];
|
||||
|
||||
for ( i=a_.size()-1; i>0; i-- ) {
|
||||
outputs_[0] += -a_[i] * outputs_[i];
|
||||
outputs_[i] = outputs_[i-1];
|
||||
}
|
||||
|
||||
lastFrame_[0] = outputs_[0];
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& Iir :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "Iir::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int i, hop = frames.channels();
|
||||
for ( unsigned int j=0; j<frames.frames(); j++, samples += hop ) {
|
||||
outputs_[0] = 0.0;
|
||||
inputs_[0] = gain_ * *samples;
|
||||
for ( i=b_.size()-1; i>0; i-- ) {
|
||||
outputs_[0] += b_[i] * inputs_[i];
|
||||
inputs_[i] = inputs_[i-1];
|
||||
}
|
||||
outputs_[0] += b_[0] * inputs_[0];
|
||||
|
||||
for ( i=a_.size()-1; i>0; i-- ) {
|
||||
outputs_[0] += -a_[i] * outputs_[i];
|
||||
outputs_[i] = outputs_[i-1];
|
||||
}
|
||||
|
||||
*samples = outputs_[0];
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& Iir :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "Iir::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int i, iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int j=0; j<iFrames.frames(); j++, iSamples += iHop, oSamples += oHop ) {
|
||||
outputs_[0] = 0.0;
|
||||
inputs_[0] = gain_ * *iSamples;
|
||||
for ( i=b_.size()-1; i>0; i-- ) {
|
||||
outputs_[0] += b_[i] * inputs_[i];
|
||||
inputs_[i] = inputs_[i-1];
|
||||
}
|
||||
outputs_[0] += b_[0] * inputs_[0];
|
||||
|
||||
for ( i=a_.size()-1; i>0; i-- ) {
|
||||
outputs_[0] += -a_[i] * outputs_[i];
|
||||
outputs_[i] = outputs_[i-1];
|
||||
}
|
||||
|
||||
*oSamples = outputs_[0];
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,14 @@
|
||||
#ifndef STK_INETWVIN_H
|
||||
#define STK_INETWVIN_H
|
||||
|
||||
#include "WvIn.h"
|
||||
#include "TcpServer.h"
|
||||
#include "UdpSocket.h"
|
||||
#include "Thread.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class InetWvIn
|
||||
\brief STK internet streaming input class.
|
||||
@@ -8,10 +19,10 @@
|
||||
supported.
|
||||
|
||||
InetWvIn 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.
|
||||
distinguish the tick() method that computes a single frame (and
|
||||
returns only the specified sample of a multi-channel frame) from
|
||||
the overloaded one that takes an StkFrames object for
|
||||
multi-channel and/or multi-frame data.
|
||||
|
||||
This class implements a socket server. When using the TCP
|
||||
protocol, the server "listens" for a single remote connection
|
||||
@@ -20,19 +31,10 @@
|
||||
data type for the incoming stream is signed 16-bit integers,
|
||||
though any of the defined StkFormats are permissible.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_INETWVIN_H
|
||||
#define STK_INETWVIN_H
|
||||
|
||||
#include "WvIn.h"
|
||||
#include "TcpServer.h"
|
||||
#include "UdpSocket.h"
|
||||
#include "Thread.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
typedef struct {
|
||||
bool finished;
|
||||
void *object;
|
||||
@@ -69,9 +71,46 @@ public:
|
||||
*/
|
||||
bool isConnected( void );
|
||||
|
||||
//! Return the specified channel value of the last computed frame.
|
||||
/*!
|
||||
For multi-channel files, use the lastFrame() function to get
|
||||
all values from the last computed frame. If no connection exists,
|
||||
the returned value is 0.0. The \c channel argument must be less
|
||||
than the number of channels in the data stream (the first channel
|
||||
is specified by 0). However, range checking is only performed if
|
||||
_STK_DEBUG_ is defined during compilation, in which case an
|
||||
out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFloat lastOut( unsigned int channel = 0 );
|
||||
|
||||
//! Compute a sample frame and return the specified \c channel value.
|
||||
/*!
|
||||
For multi-channel files, use the lastFrame() function to get
|
||||
all values from the computed frame. If no connection exists, the
|
||||
returned value is 0.0 (and a warning will be issued if _STK_DEBUG_
|
||||
is defined during compilation). The \c channel argument must be
|
||||
less than the number of channels in the data stream (the first
|
||||
channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Fill the StkFrames argument with computed frames and return the same reference.
|
||||
/*!
|
||||
The number of channels in the StkFrames argument must equal the
|
||||
number of channels specified in the listen() function. However,
|
||||
this is only checked if _STK_DEBUG_ is defined during compilation,
|
||||
in which case an incompatibility will trigger an StkError
|
||||
exception. If no connection exists, the function does
|
||||
nothing (a warning will be issued if _STK_DEBUG_ is defined during
|
||||
compilation).
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames );
|
||||
|
||||
// Called by the thread routine to receive data via the socket connection
|
||||
// and fill the socket buffer. This is not intended for general use but
|
||||
// had to be made public for access from the thread.
|
||||
// must be public for access from the thread.
|
||||
void receive( void );
|
||||
|
||||
protected:
|
||||
@@ -79,8 +118,6 @@ protected:
|
||||
// Read buffered socket data into the data buffer ... will block if none available.
|
||||
int readData( void );
|
||||
|
||||
void computeFrame( void );
|
||||
|
||||
Socket *soket_;
|
||||
Thread thread_;
|
||||
Mutex mutex_;
|
||||
@@ -100,4 +137,21 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat InetWvIn :: lastOut( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= data_.channels() ) {
|
||||
errorString_ << "InetWvIn::lastOut(): channel argument and data stream are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
// If no connection and we've output all samples in the queue, return.
|
||||
if ( !connected_ && bytesFilled_ == 0 && bufferCounter_ == 0 ) return 0.0;
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
#ifndef STK_INETWVOUT_H
|
||||
#define STK_INETWVOUT_H
|
||||
|
||||
#include "WvOut.h"
|
||||
#include "Socket.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class InetWvOut
|
||||
\brief STK internet streaming output class.
|
||||
@@ -7,25 +15,20 @@
|
||||
order, if necessary, before being transmitted.
|
||||
|
||||
InetWvOut supports multi-channel data. It is important to
|
||||
distinguish the tick() methods, which output single samples to all
|
||||
channels in a sample frame, from the tickFrame() method, which
|
||||
takes a reference to multi-channel sample frame data.
|
||||
distinguish the tick() method that outputs a single sample to all
|
||||
channels in a sample frame from the overloaded one that takes a
|
||||
reference to an StkFrames object for multi-channel and/or
|
||||
multi-frame data.
|
||||
|
||||
This class connects to a socket server, the port and IP address of
|
||||
which must be specified as constructor arguments. The default
|
||||
data type is signed 16-bit integers but any of the defined
|
||||
StkFormats are permissible.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_INETWVOUT_H
|
||||
#define STK_INETWVOUT_H
|
||||
|
||||
#include "WvOut.h"
|
||||
#include "Socket.h"
|
||||
|
||||
class InetWvOut : public WvOut
|
||||
{
|
||||
public:
|
||||
@@ -51,14 +54,30 @@ class InetWvOut : public WvOut
|
||||
std::string hostname = "localhost", unsigned int nChannels = 1, Stk::StkFormat format = STK_SINT16 );
|
||||
|
||||
//! If a connection is open, write out remaining samples in the queue and then disconnect.
|
||||
void disconnect(void);
|
||||
void disconnect( void );
|
||||
|
||||
//! Output a single sample to all channels in a sample frame.
|
||||
/*!
|
||||
An StkError is thrown if an output error occurs. If a socket
|
||||
connection does not exist, the function does nothing (a warning
|
||||
will be issued if _STK_DEBUG_ is defined during compilation).
|
||||
*/
|
||||
void tick( const StkFloat sample );
|
||||
|
||||
//! Output the StkFrames data.
|
||||
/*!
|
||||
An StkError will be thrown if an output error occurs. An
|
||||
StkError will also be thrown if _STK_DEBUG_ is defined during
|
||||
compilation and there is an incompatability between the number of
|
||||
channels in the FileWvOut object and that in the StkFrames object.
|
||||
If a socket connection does not exist, the function does nothing
|
||||
(a warning will be issued if _STK_DEBUG_ is defined during
|
||||
compilation).
|
||||
*/
|
||||
void tick( const StkFrames& frames );
|
||||
|
||||
protected:
|
||||
|
||||
void computeSample( const StkFloat sample );
|
||||
|
||||
void computeFrames( const StkFrames& frames );
|
||||
|
||||
void incrementFrame( void );
|
||||
|
||||
// Write a buffer of length frames via the socket connection.
|
||||
@@ -74,4 +93,6 @@ class InetWvOut : public WvOut
|
||||
Stk::StkFormat dataType_;
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,70 +1,129 @@
|
||||
/***************************************************/
|
||||
/*! \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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_INSTRMNT_H
|
||||
#define STK_INSTRMNT_H
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \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 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Instrmnt : public Stk
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
Instrmnt();
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~Instrmnt();
|
||||
//! Class constructor.
|
||||
Instrmnt( void ) { lastFrame_.resize( 1, 1, 0.0 ); };
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
virtual void noteOn(StkFloat frequency, StkFloat amplitude) = 0;
|
||||
virtual void noteOn( StkFloat frequency, StkFloat amplitude ) = 0;
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
virtual void noteOff(StkFloat amplitude) = 0;
|
||||
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 );
|
||||
virtual void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
|
||||
virtual void controlChange(int number, StkFloat value);
|
||||
|
||||
//! Return the number of output channels for the class.
|
||||
unsigned int channelsOut( void ) const { return lastFrame_.channels(); };
|
||||
|
||||
//! Return an StkFrames reference to the last output sample frame.
|
||||
const StkFrames& lastFrame( void ) const { return lastFrame_; };
|
||||
|
||||
//! Return the specified channel value of the last computed frame.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of output
|
||||
channels, which can be determined with the channelsOut() function
|
||||
(the first channel is specified by 0). However, range checking is
|
||||
only performed if _STK_DEBUG_ is defined during compilation, in
|
||||
which case an out-of-range value will trigger an StkError
|
||||
exception. \sa lastFrame()
|
||||
*/
|
||||
StkFloat lastOut( unsigned int channel = 0 );
|
||||
|
||||
//! Compute one sample frame and return the specified \c channel value.
|
||||
/*!
|
||||
For monophonic instruments, the \c channel argument is ignored.
|
||||
*/
|
||||
virtual StkFloat tick( unsigned int channel = 0 ) = 0;
|
||||
|
||||
//! Fill the StkFrames object with computed sample frames, starting at the specified channel.
|
||||
/*!
|
||||
The \c channel argument plus the number of output channels must
|
||||
be less than the number of channels in the StkFrames argument (the
|
||||
first channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
// 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_;
|
||||
StkFrames lastFrame_;
|
||||
|
||||
};
|
||||
|
||||
inline void Instrmnt :: setFrequency(StkFloat frequency)
|
||||
{
|
||||
errorString_ << "Instrmnt::setFrequency: virtual setFrequency function call!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
inline StkFloat Instrmnt :: lastOut( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= lastFrame_.channels() ) {
|
||||
errorString_ << "Instrmnt::lastOut(): channel argument is invalid!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
inline StkFrames& Instrmnt :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > frames.channels() - nChannels ) {
|
||||
errorString_ << "Instrmnt::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int j, hop = frames.channels() - nChannels;
|
||||
if ( nChannels == 1 ) {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples++ = tick();
|
||||
}
|
||||
else {
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples++ = tick();
|
||||
for ( j=1; j<nChannels; j++ )
|
||||
*samples++ = lastFrame_[j];
|
||||
}
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline void Instrmnt :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
errorString_ << "Instrmnt::controlChange: virtual function call!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
152
include/JCRev.h
152
include/JCRev.h
@@ -1,24 +1,25 @@
|
||||
/***************************************************/
|
||||
/*! \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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_JCREV_H
|
||||
#define STK_JCREV_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "Delay.h"
|
||||
#include "Delay.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class JCRev
|
||||
\brief John Chowning's reverberator class.
|
||||
|
||||
This class takes a monophonic input signal and produces a stereo
|
||||
output signal. It 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 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class JCRev : public Effect
|
||||
{
|
||||
@@ -26,18 +27,58 @@ class JCRev : public Effect
|
||||
//! 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();
|
||||
void clear( void );
|
||||
|
||||
//! Set the reverberation T60 decay time.
|
||||
void setT60( StkFloat T60 );
|
||||
|
||||
protected:
|
||||
//! Return the specified channel value of the last computed stereo frame.
|
||||
/*!
|
||||
Use the lastFrame() function to get both values of the last
|
||||
computed stereo frame. The \c channel argument must be 0 or 1
|
||||
(the first channel is specified by 0). However, range checking is
|
||||
only performed if _STK_DEBUG_ is defined during compilation, in
|
||||
which case an out-of-range value will trigger an StkError
|
||||
exception.
|
||||
*/
|
||||
StkFloat lastOut( unsigned int channel = 0 );
|
||||
|
||||
StkFloat computeSample( StkFloat input );
|
||||
//! Input one sample to the effect and return the specified \c channel value of the computed stereo frame.
|
||||
/*!
|
||||
Use the lastFrame() function to get both values of the computed
|
||||
stereo output frame. The \c channel argument must be 0 or 1 (the
|
||||
first channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFloat tick( StkFloat input, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the effect and replace with stereo outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The stereo
|
||||
outputs are written to the StkFrames argument starting at the
|
||||
specified \c channel. Therefore, the \c channel argument must be
|
||||
less than ( channels() - 1 ) of the StkFrames argument (the first
|
||||
channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the effect and write stereo outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. The \c iChannel
|
||||
argument must be less than the number of channels in the \c
|
||||
iFrames argument (the first channel is specified by 0). The \c
|
||||
oChannel argument must be less than ( channels() - 1 ) of the \c
|
||||
oFrames argument. However, range checking is only performed if
|
||||
_STK_DEBUG_ is defined during compilation, in which case an
|
||||
out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
Delay allpassDelays_[3];
|
||||
Delay combDelays_[4];
|
||||
@@ -48,5 +89,70 @@ class JCRev : public Effect
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat JCRev :: lastOut( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > 1 ) {
|
||||
errorString_ << "JCRev::lastOut(): channel argument must be less than 2!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
inline StkFloat JCRev :: tick( StkFloat input, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > 1 ) {
|
||||
errorString_ << "JCRev::tick(): channel argument must be less than 2!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat temp, temp0, temp1, temp2, temp3, temp4, temp5, temp6;
|
||||
StkFloat filtout;
|
||||
|
||||
temp = allpassDelays_[0].lastOut();
|
||||
temp0 = allpassCoefficient_ * temp;
|
||||
temp0 += input;
|
||||
allpassDelays_[0].tick(temp0);
|
||||
temp0 = -(allpassCoefficient_ * temp0) + temp;
|
||||
|
||||
temp = allpassDelays_[1].lastOut();
|
||||
temp1 = allpassCoefficient_ * temp;
|
||||
temp1 += temp0;
|
||||
allpassDelays_[1].tick(temp1);
|
||||
temp1 = -(allpassCoefficient_ * temp1) + temp;
|
||||
|
||||
temp = allpassDelays_[2].lastOut();
|
||||
temp2 = allpassCoefficient_ * temp;
|
||||
temp2 += temp1;
|
||||
allpassDelays_[2].tick(temp2);
|
||||
temp2 = -(allpassCoefficient_ * temp2) + temp;
|
||||
|
||||
temp3 = temp2 + (combCoefficient_[0] * combDelays_[0].lastOut());
|
||||
temp4 = temp2 + (combCoefficient_[1] * combDelays_[1].lastOut());
|
||||
temp5 = temp2 + (combCoefficient_[2] * combDelays_[2].lastOut());
|
||||
temp6 = temp2 + (combCoefficient_[3] * combDelays_[3].lastOut());
|
||||
|
||||
combDelays_[0].tick(temp3);
|
||||
combDelays_[1].tick(temp4);
|
||||
combDelays_[2].tick(temp5);
|
||||
combDelays_[3].tick(temp6);
|
||||
|
||||
filtout = temp3 + temp4 + temp5 + temp6;
|
||||
|
||||
lastFrame_[0] = effectMix_ * (outLeftDelay_.tick(filtout));
|
||||
lastFrame_[1] = effectMix_ * (outRightDelay_.tick(filtout));
|
||||
temp = (1.0 - effectMix_) * input;
|
||||
lastFrame_[0] += temp;
|
||||
lastFrame_[1] += temp;
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_JETTABL_H
|
||||
#define STK_JETTABL_H
|
||||
|
||||
#include "Function.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class JetTable
|
||||
\brief STK jet table class.
|
||||
@@ -9,28 +16,97 @@
|
||||
Consult Fletcher and Rossing, Karjalainen,
|
||||
Cook, and others for more information.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_JETTABL_H
|
||||
#define STK_JETTABL_H
|
||||
|
||||
#include "Function.h"
|
||||
|
||||
class JetTable : public Function
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
JetTable();
|
||||
|
||||
//! Class destructor.
|
||||
~JetTable();
|
||||
//! Take one sample input and map to one sample of output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
protected:
|
||||
//! Take a channel of the StkFrames object as inputs to the table and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
StkFloat computeSample( StkFloat input );
|
||||
//! Take a channel of the \c iFrames object as inputs to the table and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat JetTable :: tick( StkFloat input )
|
||||
{
|
||||
// Perform "table lookup" using a polynomial
|
||||
// calculation (x^3 - x), which approximates
|
||||
// the jet sigmoid behavior.
|
||||
lastFrame_[0] = input * (input * input - 1.0);
|
||||
|
||||
// Saturate at +/- 1.0.
|
||||
if ( lastFrame_[0] > 1.0 ) lastFrame_[0] = 1.0;
|
||||
if ( lastFrame_[0] < -1.0 ) lastFrame_[0] = -1.0;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& JetTable :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "JetTable::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples = *samples * (*samples * *samples - 1.0);
|
||||
if ( *samples > 1.0) *samples = 1.0;
|
||||
if ( *samples < -1.0) *samples = -1.0;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& JetTable :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "JetTable::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
*oSamples = *oSamples * (*oSamples * *oSamples - 1.0);
|
||||
if ( *oSamples > 1.0) *oSamples = 1.0;
|
||||
if ( *oSamples < -1.0) *oSamples = -1.0;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
#ifndef STK_MANDOLIN_H
|
||||
#define STK_MANDOLIN_H
|
||||
|
||||
#include "PluckTwo.h"
|
||||
#include "FileWvIn.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Mandolin
|
||||
\brief STK mandolin instrument model class.
|
||||
@@ -23,48 +31,75 @@
|
||||
- String Detuning = 1
|
||||
- Microphone Position = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_MANDOLIN_H
|
||||
#define STK_MANDOLIN_H
|
||||
|
||||
#include "PluckTwo.h"
|
||||
#include "FileWvIn.h"
|
||||
|
||||
class Mandolin : public PluckTwo
|
||||
{
|
||||
public:
|
||||
//! Class constructor, taking the lowest desired playing frequency.
|
||||
Mandolin(StkFloat lowestFrequency);
|
||||
Mandolin( StkFloat lowestFrequency );
|
||||
|
||||
//! Class destructor.
|
||||
~Mandolin();
|
||||
~Mandolin( void );
|
||||
|
||||
//! Pluck the strings with the given amplitude (0.0 - 1.0) using the current frequency.
|
||||
void pluck(StkFloat amplitude);
|
||||
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);
|
||||
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);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Set the body size (a value of 1.0 produces the "default" size).
|
||||
void setBodySize(StkFloat 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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
FileWvIn *soundfile_[12];
|
||||
int mic_;
|
||||
long dampTime_;
|
||||
bool waveDone_;
|
||||
};
|
||||
|
||||
inline StkFloat Mandolin :: tick( unsigned int )
|
||||
{
|
||||
StkFloat temp = 0.0;
|
||||
if ( !waveDone_ ) {
|
||||
// Scale the pluck excitation with comb
|
||||
// filtering for the duration of the file.
|
||||
temp = soundfile_[mic_]->tick() * pluckAmplitude_;
|
||||
temp = temp - combDelay_.tick(temp);
|
||||
waveDone_ = soundfile_[mic_]->isFinished();
|
||||
}
|
||||
|
||||
// Damping hack to help avoid overflow on re-plucking.
|
||||
if ( dampTime_ >=0 ) {
|
||||
dampTime_ -= 1;
|
||||
// Calculate 1st delay filtered reflection plus pluck excitation.
|
||||
lastFrame_[0] = delayLine_.tick( filter_.tick( temp + (delayLine_.lastOut() * 0.7) ) );
|
||||
// Calculate 2nd delay just like the 1st.
|
||||
lastFrame_[0] += delayLine2_.tick( filter2_.tick( temp + (delayLine2_.lastOut() * 0.7) ) );
|
||||
}
|
||||
else { // No damping hack after 1 period.
|
||||
// Calculate 1st delay filtered reflection plus pluck excitation.
|
||||
lastFrame_[0] = delayLine_.tick( filter_.tick( temp + (delayLine_.lastOut() * loopGain_) ) );
|
||||
// Calculate 2nd delay just like the 1st.
|
||||
lastFrame_[0] += delayLine2_.tick( filter2_.tick( temp + (delayLine2_.lastOut() * loopGain_) ) );
|
||||
}
|
||||
|
||||
lastFrame_[0] *= 0.3;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
#ifndef STK_MESH2D_H
|
||||
#define STK_MESH2D_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "OnePole.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Mesh2D
|
||||
\brief Two-dimensional rectilinear waveguide mesh class.
|
||||
@@ -24,12 +32,6 @@
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_MESH2D_H
|
||||
#define STK_MESH2D_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "OnePole.h"
|
||||
|
||||
const short NXMAX = 12;
|
||||
const short NYMAX = 12;
|
||||
|
||||
@@ -37,45 +39,46 @@ class Mesh2D : public Instrmnt
|
||||
{
|
||||
public:
|
||||
//! Class constructor, taking the x and y dimensions in samples.
|
||||
Mesh2D(short nX, short nY);
|
||||
Mesh2D( short nX, short nY );
|
||||
|
||||
//! Class destructor.
|
||||
~Mesh2D();
|
||||
~Mesh2D( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set the x dimension size in samples.
|
||||
void setNX(short lenX);
|
||||
void setNX( short lenX );
|
||||
|
||||
//! Set the y dimension size in samples.
|
||||
void setNY(short lenY);
|
||||
void setNY( short lenY );
|
||||
|
||||
//! Set the x, y input position on a 0.0 - 1.0 scale.
|
||||
void setInputPosition(StkFloat xFactor, StkFloat yFactor);
|
||||
void setInputPosition( StkFloat xFactor, StkFloat yFactor );
|
||||
|
||||
//! Set the loss filters gains (0.0 - 1.0).
|
||||
void setDecay(StkFloat decayFactor);
|
||||
void setDecay( StkFloat decayFactor );
|
||||
|
||||
//! Impulse the mesh with the given amplitude (frequency ignored).
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay) ... currently ignored.
|
||||
void noteOff(StkFloat amplitude);
|
||||
void noteOff( StkFloat amplitude );
|
||||
|
||||
//! Calculate and return the signal energy stored in the mesh.
|
||||
StkFloat energy();
|
||||
StkFloat energy( void );
|
||||
|
||||
//! Input a sample to the mesh and compute one output sample.
|
||||
StkFloat inputTick( StkFloat input );
|
||||
|
||||
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
|
||||
void controlChange(int number, StkFloat value);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
StkFloat tick0();
|
||||
StkFloat tick1();
|
||||
void clearMesh();
|
||||
@@ -99,4 +102,6 @@ class Mesh2D : public Instrmnt
|
||||
int counter_; // time in samples
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
#ifndef STK_MESSAGER_H
|
||||
#define STK_MESSAGER_H
|
||||
|
||||
#include "Stk.h"
|
||||
#include "Skini.h"
|
||||
#include <queue>
|
||||
|
||||
#if defined(__STK_REALTIME__)
|
||||
|
||||
#include "Mutex.h"
|
||||
#include "Thread.h"
|
||||
#include "TcpServer.h"
|
||||
#include "RtMidi.h"
|
||||
|
||||
#endif // __STK_REALTIME__
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Messager
|
||||
\brief STK input control message parser.
|
||||
@@ -28,32 +46,12 @@
|
||||
This class is primarily for use in STK example programs but it is
|
||||
generic enough to work in many other contexts.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_MESSAGER_H
|
||||
#define STK_MESSAGER_H
|
||||
|
||||
#include "Stk.h"
|
||||
#include "Skini.h"
|
||||
#include <queue>
|
||||
|
||||
const int DEFAULT_QUEUE_LIMIT = 200;
|
||||
|
||||
#if defined(__STK_REALTIME__)
|
||||
|
||||
#include "Mutex.h"
|
||||
#include "Thread.h"
|
||||
#include "TcpServer.h"
|
||||
#include "RtMidi.h"
|
||||
|
||||
extern "C" THREAD_RETURN THREAD_TYPE stdinHandler(void * ptr);
|
||||
|
||||
extern "C" THREAD_RETURN THREAD_TYPE socketHandler(void * ptr);
|
||||
|
||||
#endif // __STK_REALTIME__
|
||||
|
||||
class Messager : public Stk
|
||||
{
|
||||
public:
|
||||
@@ -163,4 +161,6 @@ class Messager : public Stk
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
#ifndef STK_MIDIFILEIN_H
|
||||
#define STK_MIDIFILEIN_H
|
||||
|
||||
#include "Stk.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/**********************************************************************/
|
||||
/*! \class MidiFileIn
|
||||
\brief A standard MIDI file reading/parsing class.
|
||||
@@ -11,19 +22,10 @@
|
||||
Tempo changes are internally tracked by the class and reflected in
|
||||
the values returned by the function getTickSeconds().
|
||||
|
||||
by Gary P. Scavone, 2003.
|
||||
by Gary P. Scavone, 2003 - 2009.
|
||||
*/
|
||||
/**********************************************************************/
|
||||
|
||||
#ifndef STK_MIDIFILEIN_H
|
||||
#define STK_MIDIFILEIN_H
|
||||
|
||||
#include "Stk.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
class MidiFileIn : public Stk
|
||||
{
|
||||
public:
|
||||
@@ -128,4 +130,6 @@ class MidiFileIn : public Stk
|
||||
std::vector<unsigned int> trackTempoIndex_;
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
#ifndef STK_MODAL_H
|
||||
#define STK_MODAL_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "Envelope.h"
|
||||
#include "FileLoop.h"
|
||||
#include "SineWave.h"
|
||||
#include "BiQuad.h"
|
||||
#include "OnePole.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Modal
|
||||
\brief STK resonance model instrument.
|
||||
\brief STK resonance model abstract base class.
|
||||
|
||||
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 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#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"
|
||||
|
||||
class Modal : public Instrmnt
|
||||
{
|
||||
public:
|
||||
@@ -31,45 +33,46 @@ public:
|
||||
Modal( unsigned int modes = 4 );
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~Modal();
|
||||
virtual ~Modal( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
virtual void setFrequency(StkFloat 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);
|
||||
void setRatioAndRadius( unsigned int modeIndex, StkFloat ratio, StkFloat radius );
|
||||
|
||||
//! Set the master gain.
|
||||
void setMasterGain(StkFloat aGain);
|
||||
void setMasterGain( StkFloat aGain ) { masterGain_ = aGain; };
|
||||
|
||||
//! Set the direct gain.
|
||||
void setDirectGain(StkFloat aGain);
|
||||
void setDirectGain( StkFloat aGain ) { directGain_ = aGain; };
|
||||
|
||||
//! Set the gain for a specified mode filter.
|
||||
void setModeGain(unsigned int modeIndex, StkFloat gain);
|
||||
void setModeGain( unsigned int modeIndex, StkFloat gain );
|
||||
|
||||
//! Initiate a strike with the given amplitude (0.0 - 1.0).
|
||||
virtual void strike(StkFloat amplitude);
|
||||
virtual void strike( StkFloat amplitude );
|
||||
|
||||
//! Damp modes with a given decay factor (0.0 - 1.0).
|
||||
void damp(StkFloat amplitude);
|
||||
void damp( StkFloat amplitude );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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;
|
||||
virtual void controlChange( int number, StkFloat value ) = 0;
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
Envelope envelope_;
|
||||
FileWvIn *wave_;
|
||||
BiQuad **filters_;
|
||||
@@ -88,4 +91,27 @@ protected:
|
||||
StkFloat baseFrequency_;
|
||||
};
|
||||
|
||||
inline StkFloat Modal :: tick( unsigned int )
|
||||
{
|
||||
StkFloat temp = masterGain_ * onepole_.tick( wave_->tick() * envelope_.tick() );
|
||||
|
||||
StkFloat temp2 = 0.0;
|
||||
for ( unsigned int i=0; i<nModes_; i++ )
|
||||
temp2 += filters_[i]->tick(temp);
|
||||
|
||||
temp2 -= temp2 * directGain_;
|
||||
temp2 += directGain_ * temp;
|
||||
|
||||
if ( vibratoGain_ != 0.0 ) {
|
||||
// Calculate AM and apply to master out
|
||||
temp = 1.0 + ( vibrato_.tick() * vibratoGain_ );
|
||||
temp2 = temp * temp2;
|
||||
}
|
||||
|
||||
lastFrame_[0] = temp2;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_MODALBAR_H
|
||||
#define STK_MODALBAR_H
|
||||
|
||||
#include "Modal.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class ModalBar
|
||||
\brief STK resonant bar instrument class.
|
||||
@@ -24,38 +31,35 @@
|
||||
- Two Fixed = 7
|
||||
- Clump = 8
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_MODALBAR_H
|
||||
#define STK_MODALBAR_H
|
||||
|
||||
#include "Modal.h"
|
||||
|
||||
class ModalBar : public Modal
|
||||
{
|
||||
public:
|
||||
//! Class constructor.
|
||||
ModalBar();
|
||||
ModalBar( void );
|
||||
|
||||
//! Class destructor.
|
||||
~ModalBar();
|
||||
~ModalBar( void );
|
||||
|
||||
//! Set stick hardness (0.0 - 1.0).
|
||||
void setStickHardness(StkFloat hardness);
|
||||
void setStickHardness( StkFloat hardness );
|
||||
|
||||
//! Set stick position (0.0 - 1.0).
|
||||
void setStrikePosition(StkFloat position);
|
||||
void setStrikePosition( StkFloat position );
|
||||
|
||||
//! Select a bar preset (currently modulo 9).
|
||||
void setPreset(int preset);
|
||||
void setPreset( int preset );
|
||||
|
||||
//! Set the modulation (vibrato) depth.
|
||||
void setModulationDepth(StkFloat mDepth);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
#ifndef STK_MODULATE_H
|
||||
#define STK_MODULATE_H
|
||||
|
||||
#include "Generator.h"
|
||||
#include "SineWave.h"
|
||||
#include "Noise.h"
|
||||
#include "OnePole.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Modulate
|
||||
\brief STK periodic/random modulator.
|
||||
@@ -6,18 +16,10 @@
|
||||
modulations to give a nice, natural human
|
||||
modulation function.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_MODULATE_H
|
||||
#define STK_MODULATE_H
|
||||
|
||||
#include "Generator.h"
|
||||
#include "SineWave.h"
|
||||
#include "SubNoise.h"
|
||||
#include "OnePole.h"
|
||||
|
||||
class Modulate : public Generator
|
||||
{
|
||||
public:
|
||||
@@ -25,33 +27,82 @@ class Modulate : public Generator
|
||||
/*!
|
||||
An StkError can be thrown if the rawwave path is incorrect.
|
||||
*/
|
||||
Modulate();
|
||||
Modulate( void );
|
||||
|
||||
//! Class destructor.
|
||||
~Modulate();
|
||||
~Modulate( void );
|
||||
|
||||
//! Reset internal state.
|
||||
void reset();
|
||||
void reset( void ) { lastFrame_[0] = 0.0; };
|
||||
|
||||
//! Set the periodic (vibrato) rate or frequency in Hz.
|
||||
void setVibratoRate(StkFloat rate);
|
||||
void setVibratoRate( StkFloat rate ) { vibrato_.setFrequency( rate ); };
|
||||
|
||||
//! Set the periodic (vibrato) gain.
|
||||
void setVibratoGain(StkFloat gain);
|
||||
void setVibratoGain( StkFloat gain ) { vibratoGain_ = gain; };
|
||||
|
||||
//! Set the random modulation gain.
|
||||
void setRandomGain(StkFloat gain);
|
||||
void setRandomGain( StkFloat gain );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
|
||||
SineWave vibrato_;
|
||||
SubNoise noise_;
|
||||
Noise noise_;
|
||||
OnePole filter_;
|
||||
StkFloat vibratoGain_;
|
||||
StkFloat randomGain_;
|
||||
unsigned int noiseRate_;
|
||||
unsigned int noiseCounter_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Modulate :: tick( void )
|
||||
{
|
||||
// Compute periodic and random modulations.
|
||||
lastFrame_[0] = vibratoGain_ * vibrato_.tick();
|
||||
if ( noiseCounter_++ >= noiseRate_ ) {
|
||||
noise_.tick();
|
||||
noiseCounter_ = 0;
|
||||
}
|
||||
lastFrame_[0] += filter_.tick( noise_.lastOut() );
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& Modulate :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "Modulate::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = Modulate::tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
#ifndef STK_MOOG_H
|
||||
#define STK_MOOG_H
|
||||
|
||||
#include "Sampler.h"
|
||||
#include "FormSwep.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Moog
|
||||
\brief STK moog-like swept filter sampling synthesis class.
|
||||
@@ -14,16 +22,10 @@
|
||||
- Vibrato Gain = 1
|
||||
- Gain = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_MOOG_H
|
||||
#define STK_MOOG_H
|
||||
|
||||
#include "Sampler.h"
|
||||
#include "FormSwep.h"
|
||||
|
||||
class Moog : public Sampler
|
||||
{
|
||||
public:
|
||||
@@ -31,30 +33,31 @@ class Moog : public Sampler
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
Moog();
|
||||
Moog( void );
|
||||
|
||||
//! Class destructor.
|
||||
~Moog();
|
||||
~Moog( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Set the modulation (vibrato) speed in Hz.
|
||||
void setModulationSpeed(StkFloat mSpeed);
|
||||
void setModulationSpeed( StkFloat mSpeed ) { loops_[1]->setFrequency( mSpeed ); };
|
||||
|
||||
//! Set the modulation (vibrato) depth.
|
||||
void setModulationDepth(StkFloat mDepth);
|
||||
void setModulationDepth( StkFloat mDepth ) { modDepth_ = mDepth * 0.5; };
|
||||
|
||||
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
|
||||
void controlChange(int number, StkFloat value);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
FormSwep filters_[2];
|
||||
StkFloat modDepth_;
|
||||
StkFloat filterQ_;
|
||||
@@ -62,4 +65,24 @@ class Moog : public Sampler
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Moog :: tick( unsigned int )
|
||||
{
|
||||
StkFloat temp;
|
||||
|
||||
if ( modDepth_ != 0.0 ) {
|
||||
temp = loops_[1]->tick() * modDepth_;
|
||||
loops_[0]->setFrequency( baseFrequency_ * (1.0 + temp) );
|
||||
}
|
||||
|
||||
temp = attackGain_ * attacks_[0]->tick();
|
||||
temp += loopGain_ * loops_[0]->tick();
|
||||
temp = filter_.tick( temp );
|
||||
temp *= adsr_.tick();
|
||||
temp = filters_[0].tick( temp );
|
||||
lastFrame_[0] = filters_[1].tick( temp );
|
||||
return lastFrame_[0] * 6.0;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,16 +1,3 @@
|
||||
/***************************************************/
|
||||
/*! \class Mutex
|
||||
\brief STK mutex class.
|
||||
|
||||
This class provides a uniform interface for
|
||||
cross-platform mutex use. On Linux and IRIX
|
||||
systems, the pthread library is used. Under
|
||||
Windows, critical sections are used.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_MUTEX_H
|
||||
#define STK_MUTEX_H
|
||||
|
||||
@@ -31,6 +18,21 @@
|
||||
|
||||
#endif
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Mutex
|
||||
\brief STK mutex class.
|
||||
|
||||
This class provides a uniform interface for
|
||||
cross-platform mutex use. On Linux and IRIX
|
||||
systems, the pthread library is used. Under
|
||||
Windows, critical sections are used.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Mutex : public Stk
|
||||
{
|
||||
public:
|
||||
@@ -67,4 +69,6 @@ class Mutex : public Stk
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
151
include/NRev.h
151
include/NRev.h
@@ -1,45 +1,85 @@
|
||||
#ifndef STK_NREV_H
|
||||
#define STK_NREV_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "Delay.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \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.
|
||||
This class takes a monophonic input signal and produces a stereo
|
||||
output signal. It 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 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_NREV_H
|
||||
#define STK_NREV_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "Delay.h"
|
||||
|
||||
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();
|
||||
void clear( void );
|
||||
|
||||
//! Set the reverberation T60 decay time.
|
||||
void setT60( StkFloat T60 );
|
||||
|
||||
protected:
|
||||
//! Return the specified channel value of the last computed stereo frame.
|
||||
/*!
|
||||
Use the lastFrame() function to get both values of the last
|
||||
computed stereo frame. The \c channel argument must be 0 or 1
|
||||
(the first channel is specified by 0). However, range checking is
|
||||
only performed if _STK_DEBUG_ is defined during compilation, in
|
||||
which case an out-of-range value will trigger an StkError
|
||||
exception.
|
||||
*/
|
||||
StkFloat lastOut( unsigned int channel = 0 );
|
||||
|
||||
StkFloat computeSample( StkFloat input );
|
||||
//! Input one sample to the effect and return the specified \c channel value of the computed stereo frame.
|
||||
/*!
|
||||
Use the lastFrame() function to get both values of the computed
|
||||
stereo output frame. The \c channel argument must be 0 or 1 (the
|
||||
first channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFloat tick( StkFloat input, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the effect and replace with stereo outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The stereo
|
||||
outputs are written to the StkFrames argument starting at the
|
||||
specified \c channel. Therefore, the \c channel argument must be
|
||||
less than ( channels() - 1 ) of the StkFrames argument (the first
|
||||
channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the effect and write stereo outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. The \c iChannel
|
||||
argument must be less than the number of channels in the \c
|
||||
iFrames argument (the first channel is specified by 0). The \c
|
||||
oChannel argument must be less than ( channels() - 1 ) of the \c
|
||||
oFrames argument. However, range checking is only performed if
|
||||
_STK_DEBUG_ is defined during compilation, in which case an
|
||||
out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
Delay allpassDelays_[8];
|
||||
Delay combDelays_[6];
|
||||
@@ -49,5 +89,72 @@ class NRev : public Effect
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat NRev :: lastOut( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > 1 ) {
|
||||
errorString_ << "NRev::lastOut(): channel argument must be less than 2!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
inline StkFloat NRev :: tick( StkFloat input, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > 1 ) {
|
||||
errorString_ << "NRev::tick(): channel argument must be less than 2!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat temp, temp0, temp1, temp2, temp3;
|
||||
int i;
|
||||
|
||||
temp0 = 0.0;
|
||||
for ( i=0; i<6; i++ ) {
|
||||
temp = input + (combCoefficient_[i] * combDelays_[i].lastOut());
|
||||
temp0 += combDelays_[i].tick(temp);
|
||||
}
|
||||
|
||||
for ( i=0; i<3; i++ ) {
|
||||
temp = allpassDelays_[i].lastOut();
|
||||
temp1 = allpassCoefficient_ * temp;
|
||||
temp1 += temp0;
|
||||
allpassDelays_[i].tick(temp1);
|
||||
temp0 = -(allpassCoefficient_ * temp1) + temp;
|
||||
}
|
||||
|
||||
// One-pole lowpass filter.
|
||||
lowpassState_ = 0.7 * lowpassState_ + 0.3 * temp0;
|
||||
temp = allpassDelays_[3].lastOut();
|
||||
temp1 = allpassCoefficient_ * temp;
|
||||
temp1 += lowpassState_;
|
||||
allpassDelays_[3].tick( temp1 );
|
||||
temp1 = -( allpassCoefficient_ * temp1 ) + temp;
|
||||
|
||||
temp = allpassDelays_[4].lastOut();
|
||||
temp2 = allpassCoefficient_ * temp;
|
||||
temp2 += temp1;
|
||||
allpassDelays_[4].tick( temp2 );
|
||||
lastFrame_[0] = effectMix_*( -( allpassCoefficient_ * temp2 ) + temp );
|
||||
|
||||
temp = allpassDelays_[5].lastOut();
|
||||
temp3 = allpassCoefficient_ * temp;
|
||||
temp3 += temp1;
|
||||
allpassDelays_[5].tick( temp3 );
|
||||
lastFrame_[1] = effectMix_*( - ( allpassCoefficient_ * temp3 ) + temp );
|
||||
|
||||
temp = ( 1.0 - effectMix_ ) * input;
|
||||
lastFrame_[0] += temp;
|
||||
lastFrame_[1] += temp;
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_NOISE_H
|
||||
#define STK_NOISE_H
|
||||
|
||||
#include "Generator.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Noise
|
||||
\brief STK noise generator.
|
||||
@@ -6,31 +13,20 @@
|
||||
C rand() function. The quality of the rand()
|
||||
function varies from one OS to another.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_NOISE_H
|
||||
#define STK_NOISE_H
|
||||
|
||||
#include "Generator.h"
|
||||
|
||||
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.
|
||||
//! Default constructor that can also take a specific seed value.
|
||||
/*!
|
||||
If the seed value is zero, the random number generator is
|
||||
If the seed value is zero (the default value), the random number generator is
|
||||
seeded with the system time.
|
||||
*/
|
||||
Noise( unsigned int seed );
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~Noise();
|
||||
Noise( unsigned int seed = 0 );
|
||||
|
||||
//! Seed the random number generator with a specific seed value.
|
||||
/*!
|
||||
@@ -39,10 +35,49 @@ public:
|
||||
*/
|
||||
void setSeed( unsigned int seed = 0 );
|
||||
|
||||
protected:
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
virtual StkFloat computeSample( void );
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Noise :: tick( void )
|
||||
{
|
||||
return lastFrame_[0] = (StkFloat) ( 2.0 * rand() / (RAND_MAX + 1.0) - 1.0 );
|
||||
}
|
||||
|
||||
inline StkFrames& Noise :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "Noise::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = (StkFloat) ( 2.0 * rand() / (RAND_MAX + 1.0) - 1.0 );
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,43 +1,40 @@
|
||||
/***************************************************/
|
||||
/*! \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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_ONEPOLE_H
|
||||
#define STK_ONEPOLE_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
class OnePole : protected Filter
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class OnePole
|
||||
\brief STK one-pole filter class.
|
||||
|
||||
This class 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 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class OnePole : public Filter
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor creates a first-order low-pass filter.
|
||||
OnePole();
|
||||
|
||||
//! Overloaded constructor which sets the pole position during instantiation.
|
||||
OnePole( StkFloat thePole );
|
||||
//! The default constructor creates a low-pass filter (pole at z = 0.9).
|
||||
OnePole( StkFloat thePole = 0.9 );
|
||||
|
||||
//! Class destructor.
|
||||
~OnePole();
|
||||
|
||||
//! Clears the internal state of the filter.
|
||||
void clear(void);
|
||||
|
||||
//! Set the b[0] coefficient value.
|
||||
void setB0(StkFloat b0);
|
||||
void setB0( StkFloat b0 ) { b_[0] = b0; };
|
||||
|
||||
//! Set the a[1] coefficient value.
|
||||
void setA1(StkFloat a1);
|
||||
void setA1( StkFloat a1 ) { a_[1] = a1; };
|
||||
|
||||
//! Set all filter coefficients.
|
||||
void setCoefficients( StkFloat b0, StkFloat a1, bool clearState = false );
|
||||
|
||||
//! Set the pole position in the z-plane.
|
||||
/*!
|
||||
@@ -47,33 +44,90 @@ public:
|
||||
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;
|
||||
void setPole( StkFloat thePole );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut(void) const;
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Input one sample to the filter and return one output.
|
||||
StkFloat tick(StkFloat sample);
|
||||
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.
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat OnePole :: tick( StkFloat input )
|
||||
{
|
||||
inputs_[0] = gain_ * input;
|
||||
lastFrame_[0] = b_[0] * inputs_[0] - a_[1] * outputs_[1];
|
||||
outputs_[1] = lastFrame_[0];
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& OnePole :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "OnePole::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
inputs_[0] = gain_ * *samples;
|
||||
*samples = b_[0] * inputs_[0] - a_[1] * outputs_[1];
|
||||
outputs_[1] = *samples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = outputs_[1];
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& OnePole :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "OnePole::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
inputs_[0] = gain_ * *iSamples;
|
||||
*oSamples = b_[0] * inputs_[0] - a_[1] * outputs_[1];
|
||||
outputs_[1] = *oSamples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = outputs_[1];
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,43 +1,40 @@
|
||||
/***************************************************/
|
||||
/*! \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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_ONEZERO_H
|
||||
#define STK_ONEZERO_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
class OneZero : protected Filter
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class OneZero
|
||||
\brief STK one-zero filter class.
|
||||
|
||||
This class 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 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class OneZero : public Filter
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor creates a first-order low-pass filter.
|
||||
OneZero();
|
||||
|
||||
//! Overloaded constructor which sets the zero position during instantiation.
|
||||
OneZero(StkFloat theZero);
|
||||
//! The default constructor creates a low-pass filter (zero at z = -1.0).
|
||||
OneZero( StkFloat theZero = -1.0 );
|
||||
|
||||
//! Class destructor.
|
||||
~OneZero();
|
||||
|
||||
//! Clears the internal state of the filter.
|
||||
void clear(void);
|
||||
|
||||
//! Set the b[0] coefficient value.
|
||||
void setB0(StkFloat b0);
|
||||
void setB0( StkFloat b0 ) { b_[0] = b0; };
|
||||
|
||||
//! Set the b[1] coefficient value.
|
||||
void setB1(StkFloat b1);
|
||||
void setB1( StkFloat b1 ) { b_[1] = b1; };
|
||||
|
||||
//! Set all filter coefficients.
|
||||
void setCoefficients( StkFloat b0, StkFloat b1, bool clearState = false );
|
||||
|
||||
//! Set the zero position in the z-plane.
|
||||
/*!
|
||||
@@ -47,33 +44,91 @@ class OneZero : protected Filter
|
||||
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;
|
||||
void setZero( StkFloat theZero );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut(void) const;
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Input one sample to the filter and return one output.
|
||||
StkFloat tick(StkFloat sample);
|
||||
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.
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat OneZero :: tick( StkFloat input )
|
||||
{
|
||||
inputs_[0] = gain_ * input;
|
||||
lastFrame_[0] = b_[1] * inputs_[1] + b_[0] * inputs_[0];
|
||||
inputs_[1] = inputs_[0];
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& OneZero :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "OneZero::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
inputs_[0] = gain_ * *samples;
|
||||
*samples = b_[1] * inputs_[1] + b_[0] * inputs_[0];
|
||||
inputs_[1] = inputs_[0];
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& OneZero :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "OneZero::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
inputs_[0] = gain_ * *iSamples;
|
||||
*oSamples = b_[1] * inputs_[1] + b_[0] * inputs_[0];
|
||||
inputs_[1] = inputs_[0];
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
130
include/PRCRev.h
130
include/PRCRev.h
@@ -1,43 +1,84 @@
|
||||
#ifndef STK_PRCREV_H
|
||||
#define STK_PRCREV_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "Delay.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \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.
|
||||
This class takes a monophonic input signal and produces a stereo
|
||||
output signal. It 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 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_PRCREV_H
|
||||
#define STK_PRCREV_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "Delay.h"
|
||||
|
||||
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();
|
||||
void clear( void );
|
||||
|
||||
//! Set the reverberation T60 decay time.
|
||||
void setT60( StkFloat T60 );
|
||||
|
||||
protected:
|
||||
//! Return the specified channel value of the last computed stereo frame.
|
||||
/*!
|
||||
Use the lastFrame() function to get both values of the last
|
||||
computed stereo frame. The \c channel argument must be 0 or 1
|
||||
(the first channel is specified by 0). However, range checking is
|
||||
only performed if _STK_DEBUG_ is defined during compilation, in
|
||||
which case an out-of-range value will trigger an StkError
|
||||
exception.
|
||||
*/
|
||||
StkFloat lastOut( unsigned int channel = 0 );
|
||||
|
||||
StkFloat computeSample( StkFloat input );
|
||||
//! Input one sample to the effect and return the specified \c channel value of the computed stereo frame.
|
||||
/*!
|
||||
Use the lastFrame() function to get both values of the computed
|
||||
stereo output frame. The \c channel argument must be 0 or 1 (the
|
||||
first channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFloat tick( StkFloat input, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the effect and replace with stereo outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The stereo
|
||||
outputs are written to the StkFrames argument starting at the
|
||||
specified \c channel. Therefore, the \c channel argument must be
|
||||
less than ( channels() - 1 ) of the StkFrames argument (the first
|
||||
channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the effect and write stereo outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. The \c iChannel
|
||||
argument must be less than the number of channels in the \c
|
||||
iFrames argument (the first channel is specified by 0). The \c
|
||||
oChannel argument must be less than ( channels() - 1 ) of the \c
|
||||
oFrames argument. However, range checking is only performed if
|
||||
_STK_DEBUG_ is defined during compilation, in which case an
|
||||
out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
Delay allpassDelays_[2];
|
||||
Delay combDelays_[2];
|
||||
@@ -46,5 +87,54 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat PRCRev :: lastOut( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > 1 ) {
|
||||
errorString_ << "PRCRev::lastOut(): channel argument must be less than 2!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
inline StkFloat PRCRev :: tick( StkFloat input, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > 1 ) {
|
||||
errorString_ << "PRCRev::tick(): channel argument must be less than 2!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat temp, temp0, temp1, temp2, temp3;
|
||||
|
||||
temp = allpassDelays_[0].lastOut();
|
||||
temp0 = allpassCoefficient_ * temp;
|
||||
temp0 += input;
|
||||
allpassDelays_[0].tick(temp0);
|
||||
temp0 = -(allpassCoefficient_ * temp0) + temp;
|
||||
|
||||
temp = allpassDelays_[1].lastOut();
|
||||
temp1 = allpassCoefficient_ * temp;
|
||||
temp1 += temp0;
|
||||
allpassDelays_[1].tick(temp1);
|
||||
temp1 = -(allpassCoefficient_ * temp1) + temp;
|
||||
|
||||
temp2 = temp1 + (combCoefficient_[0] * combDelays_[0].lastOut());
|
||||
temp3 = temp1 + (combCoefficient_[1] * combDelays_[1].lastOut());
|
||||
|
||||
lastFrame_[0] = effectMix_ * (combDelays_[0].tick(temp2));
|
||||
lastFrame_[1] = effectMix_ * (combDelays_[1].tick(temp3));
|
||||
temp = (1.0 - effectMix_) * input;
|
||||
lastFrame_[0] += temp;
|
||||
lastFrame_[1] += temp;
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_PERCFLUT_H
|
||||
#define STK_PERCFLUT_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class PercFlut
|
||||
\brief STK percussive flute FM synthesis instrument.
|
||||
@@ -22,15 +29,10 @@
|
||||
type who should worry about this (making
|
||||
money) worry away.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_PERCFLUT_H
|
||||
#define STK_PERCFLUT_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
class PercFlut : public FM
|
||||
{
|
||||
public:
|
||||
@@ -38,20 +40,51 @@ class PercFlut : public FM
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
PercFlut();
|
||||
PercFlut( void );
|
||||
|
||||
//! Class destructor.
|
||||
~PercFlut();
|
||||
~PercFlut( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
};
|
||||
|
||||
inline StkFloat PercFlut :: tick( unsigned int )
|
||||
{
|
||||
register StkFloat temp;
|
||||
|
||||
temp = vibrato_.tick() * modDepth_ * 0.2;
|
||||
waves_[0]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[0]);
|
||||
waves_[1]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[1]);
|
||||
waves_[2]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[2]);
|
||||
waves_[3]->setFrequency(baseFrequency_ * (1.0 + temp) * ratios_[3]);
|
||||
|
||||
waves_[3]->addPhaseOffset( twozero_.lastOut() );
|
||||
temp = gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
|
||||
|
||||
twozero_.tick(temp);
|
||||
waves_[2]->addPhaseOffset( temp );
|
||||
temp = (1.0 - (control2_ * 0.5)) * gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
|
||||
|
||||
temp += control2_ * 0.5 * gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
|
||||
temp = temp * control1_;
|
||||
|
||||
waves_[0]->addPhaseOffset(temp);
|
||||
temp = gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
|
||||
|
||||
lastFrame_[0] = temp * 0.5;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_PHONEMES_H
|
||||
#define STK_PHONEMES_H
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Phonemes
|
||||
\brief STK phonemes table.
|
||||
@@ -6,15 +13,10 @@
|
||||
set of 32 static phoneme formant parameters
|
||||
and provide access to those values.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_PHONEMES_H
|
||||
#define STK_PHONEMES_H
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
class Phonemes : public Stk
|
||||
{
|
||||
public:
|
||||
@@ -47,4 +49,6 @@ private:
|
||||
static const StkFloat phonemeParameters[][4][3];
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
#ifndef STK_PITSHIFT_H
|
||||
#define STK_PITSHIFT_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "DelayL.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class PitShift
|
||||
\brief STK simple pitch shifter effect class.
|
||||
@@ -5,43 +13,95 @@
|
||||
This class implements a simple pitch shifter
|
||||
using delay lines.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_PITSHIFT_H
|
||||
#define STK_PITSHIFT_H
|
||||
|
||||
#include "Effect.h"
|
||||
#include "DelayL.h"
|
||||
const int maxDelay = 5024;
|
||||
|
||||
class PitShift : public Effect
|
||||
{
|
||||
public:
|
||||
//! Class constructor.
|
||||
PitShift();
|
||||
|
||||
//! Class destructor.
|
||||
~PitShift();
|
||||
PitShift( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set the pitch shift factor (1.0 produces no shift).
|
||||
void setShift(StkFloat shift);
|
||||
void setShift( StkFloat shift );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Input one sample to the effect and return one output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the effect and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the effect and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( StkFloat input );
|
||||
|
||||
DelayL delayLine_[2];
|
||||
StkFloat delay_[2];
|
||||
StkFloat env_[2];
|
||||
StkFloat rate_;
|
||||
unsigned long delayLength;
|
||||
unsigned long halfLength;
|
||||
unsigned long delayLength_;
|
||||
unsigned long halfLength_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat PitShift :: tick( StkFloat input )
|
||||
{
|
||||
// Calculate the two delay length values, keeping them within the
|
||||
// range 12 to maxDelay-12.
|
||||
delay_[0] += rate_;
|
||||
while ( delay_[0] > maxDelay-12 ) delay_[0] -= delayLength_;
|
||||
while ( delay_[0] < 12 ) delay_[0] += delayLength_;
|
||||
|
||||
delay_[1] = delay_[0] + halfLength_;
|
||||
while ( delay_[1] > maxDelay-12 ) delay_[1] -= delayLength_;
|
||||
while ( delay_[1] < 12 ) delay_[1] += delayLength_;
|
||||
|
||||
// Set the new delay line lengths.
|
||||
delayLine_[0].setDelay( delay_[0] );
|
||||
delayLine_[1].setDelay( delay_[1] );
|
||||
|
||||
// Calculate a triangular envelope.
|
||||
env_[1] = fabs( ( delay_[0] - halfLength_ + 12 ) * ( 1.0 / (halfLength_ + 12 ) ) );
|
||||
env_[0] = 1.0 - env_[1];
|
||||
|
||||
// Delay input and apply envelope.
|
||||
lastFrame_[0] = env_[0] * delayLine_[0].tick( input );
|
||||
lastFrame_[0] += env_[1] * delayLine_[1].tick( input );
|
||||
|
||||
// Compute effect mix and output.
|
||||
lastFrame_[0] *= effectMix_;
|
||||
lastFrame_[0] += ( 1.0 - effectMix_ ) * input;
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
#ifndef STK_PLUCKTWO_H
|
||||
#define STK_PLUCKTWO_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayL.h"
|
||||
#include "DelayA.h"
|
||||
#include "OneZero.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class PluckTwo
|
||||
\brief STK enhanced plucked string model class.
|
||||
@@ -14,41 +24,33 @@
|
||||
use possibly subject to patents held by
|
||||
Stanford University, Yamaha, and others.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_PLUCKTWO_H
|
||||
#define STK_PLUCKTWO_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayL.h"
|
||||
#include "DelayA.h"
|
||||
#include "OneZero.h"
|
||||
|
||||
class PluckTwo : public Instrmnt
|
||||
{
|
||||
public:
|
||||
//! Class constructor, taking the lowest desired playing frequency.
|
||||
PluckTwo(StkFloat lowestFrequency);
|
||||
PluckTwo( StkFloat lowestFrequency );
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~PluckTwo();
|
||||
virtual ~PluckTwo( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
virtual void setFrequency(StkFloat 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);
|
||||
void setDetune( StkFloat detune );
|
||||
|
||||
//! Efficient combined setting of frequency and detuning.
|
||||
void setFreqAndDetune(StkFloat frequency, StkFloat detune);
|
||||
void setFreqAndDetune( StkFloat frequency, StkFloat detune );
|
||||
|
||||
//! Set the pluck or "excitation" position along the string (0.0 - 1.0).
|
||||
void setPluckPosition(StkFloat position);
|
||||
void setPluckPosition( StkFloat position );
|
||||
|
||||
//! Set the base loop gain.
|
||||
/*!
|
||||
@@ -56,15 +58,15 @@ class PluckTwo : public Instrmnt
|
||||
Because of high-frequency loop filter roll-off, higher
|
||||
frequency settings have greater loop gains.
|
||||
*/
|
||||
void setBaseLoopGain(StkFloat aGain);
|
||||
void setBaseLoopGain( StkFloat aGain );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
virtual void noteOff(StkFloat amplitude);
|
||||
virtual void noteOff( StkFloat amplitude );
|
||||
|
||||
virtual StkFloat tick( unsigned int channel = 0 ) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
virtual StkFloat computeSample( void ) = 0;
|
||||
|
||||
DelayA delayLine_;
|
||||
DelayA delayLine2_;
|
||||
DelayL combDelay_;
|
||||
@@ -82,4 +84,6 @@ class PluckTwo : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
#ifndef STK_PLUCKED_H
|
||||
#define STK_PLUCKED_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayA.h"
|
||||
#include "OneZero.h"
|
||||
#include "OnePole.h"
|
||||
#include "Noise.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Plucked
|
||||
\brief STK plucked string model class.
|
||||
@@ -13,47 +24,39 @@
|
||||
Stanford, bearing the names of Karplus and/or
|
||||
Strong.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_PLUCKED_H
|
||||
#define STK_PLUCKED_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayA.h"
|
||||
#include "OneZero.h"
|
||||
#include "OnePole.h"
|
||||
#include "Noise.h"
|
||||
|
||||
class Plucked : public Instrmnt
|
||||
{
|
||||
public:
|
||||
//! Class constructor, taking the lowest desired playing frequency.
|
||||
Plucked(StkFloat lowestFrequency);
|
||||
Plucked( StkFloat lowestFrequency );
|
||||
|
||||
//! Class destructor.
|
||||
~Plucked();
|
||||
~Plucked( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
virtual void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Pluck the string with the given amplitude using the current frequency.
|
||||
void pluck(StkFloat amplitude);
|
||||
void pluck( StkFloat amplitude );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
virtual void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
virtual void noteOff(StkFloat amplitude);
|
||||
void noteOff( StkFloat amplitude );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
DelayA delayLine_;
|
||||
OneZero loopFilter_;
|
||||
OnePole pickFilter_;
|
||||
@@ -63,5 +66,13 @@ class Plucked : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Plucked :: tick( unsigned int )
|
||||
{
|
||||
// Here's the whole inner loop of the instrument!!
|
||||
return lastFrame_[0] = 3.0 * delayLine_.tick( loopFilter_.tick( delayLine_.lastOut() * loopGain_ ) );
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
/***************************************************/
|
||||
/*! \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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_POLEZERO_H
|
||||
#define STK_POLEZERO_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
class PoleZero : protected Filter
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class PoleZero
|
||||
\brief STK one-pole, one-zero filter class.
|
||||
|
||||
This class 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 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class PoleZero : public Filter
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -27,17 +28,17 @@ class PoleZero : protected Filter
|
||||
//! Class destructor.
|
||||
~PoleZero();
|
||||
|
||||
//! Clears the internal states of the filter.
|
||||
void clear(void);
|
||||
|
||||
//! Set the b[0] coefficient value.
|
||||
void setB0(StkFloat b0);
|
||||
void setB0( StkFloat b0 ) { b_[0] = b0; };
|
||||
|
||||
//! Set the b[1] coefficient value.
|
||||
void setB1(StkFloat b1);
|
||||
void setB1( StkFloat b1 ) { b_[1] = b1; };
|
||||
|
||||
//! Set the a[1] coefficient value.
|
||||
void setA1(StkFloat a1);
|
||||
void setA1( StkFloat a1 ) { a_[1] = a1; };
|
||||
|
||||
//! Set all filter coefficients.
|
||||
void setCoefficients( StkFloat b0, StkFloat b1, StkFloat a1, bool clearState = false );
|
||||
|
||||
//! Set the filter for allpass behavior using \e coefficient.
|
||||
/*!
|
||||
@@ -45,7 +46,7 @@ class PoleZero : protected 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);
|
||||
void setAllpass( StkFloat coefficient );
|
||||
|
||||
//! Create a DC blocking filter with the given pole position in the z-plane.
|
||||
/*!
|
||||
@@ -54,33 +55,58 @@ class PoleZero : protected Filter
|
||||
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;
|
||||
void setBlockZero( StkFloat thePole = 0.99 );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const;
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Input one sample to the filter and return one output.
|
||||
StkFloat tick( StkFloat sample );
|
||||
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.
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat PoleZero :: tick( StkFloat input )
|
||||
{
|
||||
inputs_[0] = gain_ * input;
|
||||
lastFrame_[0] = b_[0] * inputs_[0] + b_[1] * inputs_[1] - a_[1] * outputs_[1];
|
||||
inputs_[1] = inputs_[0];
|
||||
outputs_[1] = lastFrame_[0];
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& PoleZero :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "PoleZero::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
inputs_[0] = gain_ * *samples;
|
||||
*samples = b_[0] * inputs_[0] + b_[1] * inputs_[1] - a_[1] * outputs_[1];
|
||||
inputs_[1] = inputs_[0];
|
||||
outputs_[1] = *samples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = outputs_[1];
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_REEDTABLE_H
|
||||
#define STK_REEDTABLE_H
|
||||
|
||||
#include "Function.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class ReedTable
|
||||
\brief STK reed table class.
|
||||
@@ -13,23 +20,15 @@
|
||||
Smith (1986), Hirschman, Cook, Scavone, and
|
||||
others for more information.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_REEDTABLE_H
|
||||
#define STK_REEDTABLE_H
|
||||
|
||||
#include "Function.h"
|
||||
|
||||
class ReedTable : public Function
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
ReedTable();
|
||||
|
||||
//! Class destructor.
|
||||
~ReedTable();
|
||||
ReedTable( void ) : offset_(0.6), slope_(-0.8) {};
|
||||
|
||||
//! Set the table offset value.
|
||||
/*!
|
||||
@@ -37,7 +36,7 @@ public:
|
||||
of the initial reed tip opening (a greater offset
|
||||
represents a smaller opening).
|
||||
*/
|
||||
void setOffset(StkFloat offset);
|
||||
void setOffset( StkFloat offset ) { offset_ = offset; };
|
||||
|
||||
//! Set the table slope value.
|
||||
/*!
|
||||
@@ -45,15 +44,100 @@ public:
|
||||
stiffness (a greater slope represents a harder
|
||||
reed).
|
||||
*/
|
||||
void setSlope(StkFloat slope);
|
||||
void setSlope( StkFloat slope ) { slope_ = slope; };
|
||||
|
||||
//! Take one sample input and map to one sample of output.
|
||||
StkFloat tick( StkFloat input );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the table and replace with corresponding outputs.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the table and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( StkFloat input );
|
||||
|
||||
StkFloat offset_;
|
||||
StkFloat slope_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat ReedTable :: tick( StkFloat input )
|
||||
{
|
||||
// The input is differential pressure across the reed.
|
||||
lastFrame_[0] = offset_ + (slope_ * input);
|
||||
|
||||
// If output is > 1, the reed has slammed shut and the
|
||||
// reflection function value saturates at 1.0.
|
||||
if ( lastFrame_[0] > 1.0) lastFrame_[0] = (StkFloat) 1.0;
|
||||
|
||||
// This is nearly impossible in a physical system, but
|
||||
// a reflection function value of -1.0 corresponds to
|
||||
// an open end (and no discontinuity in bore profile).
|
||||
if ( lastFrame_[0] < -1.0) lastFrame_[0] = (StkFloat) -1.0;
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& ReedTable :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "ReedTable::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples = offset_ + (slope_ * *samples);
|
||||
if ( *samples > 1.0) *samples = 1.0;
|
||||
if ( *samples < -1.0) *samples = -1.0;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& ReedTable :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "ReedTable::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
*oSamples = offset_ + (slope_ * *iSamples);
|
||||
if ( *oSamples > 1.0) *oSamples = 1.0;
|
||||
if ( *oSamples < -1.0) *oSamples = -1.0;
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
#ifndef STK_RESONATE_H
|
||||
#define STK_RESONATE_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "ADSR.h"
|
||||
#include "BiQuad.h"
|
||||
#include "Noise.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Resonate
|
||||
\brief STK noise driven formant filter.
|
||||
@@ -13,58 +23,51 @@
|
||||
- Zero Radii = 1
|
||||
- Envelope Gain = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_RESONATE_H
|
||||
#define STK_RESONATE_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "ADSR.h"
|
||||
#include "BiQuad.h"
|
||||
#include "Noise.h"
|
||||
|
||||
class Resonate : public Instrmnt
|
||||
{
|
||||
public:
|
||||
//! Class constructor.
|
||||
Resonate();
|
||||
Resonate( void );
|
||||
|
||||
//! Class destructor.
|
||||
~Resonate();
|
||||
~Resonate( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set the filter for a resonance at the given frequency (Hz) and radius.
|
||||
void setResonance(StkFloat frequency, StkFloat radius);
|
||||
void setResonance( StkFloat frequency, StkFloat radius );
|
||||
|
||||
//! Set the filter for a notch at the given frequency (Hz) and radius.
|
||||
void setNotch(StkFloat frequency, StkFloat radius);
|
||||
void setNotch( StkFloat frequency, StkFloat radius );
|
||||
|
||||
//! Set the filter zero coefficients for contant resonance gain.
|
||||
void setEqualGainZeroes();
|
||||
void setEqualGainZeroes( void ) { filter_.setEqualGainZeroes(); };
|
||||
|
||||
//! Initiate the envelope with a key-on event.
|
||||
void keyOn();
|
||||
void keyOn( void ) { adsr_.keyOn(); };
|
||||
|
||||
//! Signal a key-off event to the envelope.
|
||||
void keyOff();
|
||||
void keyOff( void ) { adsr_.keyOff(); };
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
ADSR adsr_;
|
||||
BiQuad filter_;
|
||||
Noise noise_;
|
||||
@@ -75,4 +78,13 @@ class Resonate : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Resonate :: tick( unsigned int )
|
||||
{
|
||||
lastFrame_[0] = filter_.tick( noise_.tick() );
|
||||
lastFrame_[0] *= adsr_.tick();
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_RHODEY_H
|
||||
#define STK_RHODEY_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Rhodey
|
||||
\brief STK Fender Rhodes electric piano FM
|
||||
@@ -26,15 +33,10 @@
|
||||
type who should worry about this (making
|
||||
money) worry away.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_RHODEY_H
|
||||
#define STK_RHODEY_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
class Rhodey : public FM
|
||||
{
|
||||
public:
|
||||
@@ -42,20 +44,48 @@ class Rhodey : public FM
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
Rhodey();
|
||||
Rhodey( void );
|
||||
|
||||
//! Class destructor.
|
||||
~Rhodey();
|
||||
~Rhodey( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
};
|
||||
|
||||
inline StkFloat Rhodey :: tick( unsigned int )
|
||||
{
|
||||
StkFloat temp, temp2;
|
||||
|
||||
temp = gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
|
||||
temp = temp * control1_;
|
||||
|
||||
waves_[0]->addPhaseOffset( temp );
|
||||
waves_[3]->addPhaseOffset( twozero_.lastOut() );
|
||||
temp = gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
|
||||
twozero_.tick(temp);
|
||||
|
||||
waves_[2]->addPhaseOffset( temp );
|
||||
temp = ( 1.0 - (control2_ * 0.5)) * gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
|
||||
temp += control2_ * 0.5 * gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
|
||||
|
||||
// Calculate amplitude modulation and apply it to output.
|
||||
temp2 = vibrato_.tick() * modDepth_;
|
||||
temp = temp * (1.0 + temp2);
|
||||
|
||||
lastFrame_[0] = temp * 0.5;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
RtAudio provides a common API (Application Programming Interface)
|
||||
for realtime audio input/output across Linux (native ALSA, Jack,
|
||||
and OSS), SGI, Macintosh OS X (CoreAudio and Jack), and Windows
|
||||
and OSS), Macintosh OS X (CoreAudio and Jack), and Windows
|
||||
(DirectSound and ASIO) operating systems.
|
||||
|
||||
RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
|
||||
|
||||
RtAudio: realtime audio i/o C++ classes
|
||||
Copyright (c) 2001-2007 Gary P. Scavone
|
||||
Copyright (c) 2001-2009 Gary P. Scavone
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
@@ -42,7 +42,7 @@
|
||||
\file RtAudio.h
|
||||
*/
|
||||
|
||||
// RtAudio: Version 4.0.3
|
||||
// RtAudio: Version 4.0.5
|
||||
|
||||
#ifndef __RTAUDIO_H
|
||||
#define __RTAUDIO_H
|
||||
@@ -108,11 +108,15 @@ static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/mi
|
||||
If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
|
||||
open the input and/or output stream device(s) for exclusive use.
|
||||
Note that this is not possible with all supported audio APIs.
|
||||
|
||||
If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt
|
||||
to select realtime scheduling (round-robin) for the callback thread.
|
||||
*/
|
||||
typedef unsigned int RtAudioStreamFlags;
|
||||
static const RtAudioStreamFlags RTAUDIO_NONINTERLEAVED = 0x1; // Use non-interleaved buffers (default = interleaved).
|
||||
static const RtAudioStreamFlags RTAUDIO_MINIMIZE_LATENCY = 0x2; // Attempt to set stream parameters for lowest possible latency.
|
||||
static const RtAudioStreamFlags RTAUDIO_HOG_DEVICE = 0x4; // Attempt grab device and prevent use by others.
|
||||
static const RtAudioStreamFlags RTAUDIO_SCHEDULE_REALTIME = 0x8; // Try to select realtime scheduling for callback thread.
|
||||
|
||||
/*! \typedef typedef unsigned long RtAudioStreamStatus;
|
||||
\brief RtAudio stream status (over- or underflow) flags.
|
||||
@@ -240,9 +244,10 @@ class RtAudio
|
||||
The following flags can be OR'ed together to allow a client to
|
||||
make changes to the default stream behavior:
|
||||
|
||||
- \e RTAUDIO_NONINTERLEAVED: Use non-interleaved buffers (default = interleaved).
|
||||
- \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
|
||||
- \e RTAUDIO_HOG_DEVICE: Attempt grab device for exclusive use.
|
||||
- \e RTAUDIO_NONINTERLEAVED: Use non-interleaved buffers (default = interleaved).
|
||||
- \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
|
||||
- \e RTAUDIO_HOG_DEVICE: Attempt grab device for exclusive use.
|
||||
- \e RTAUDIO_SCHEDULE_REALTIME: Attempt to select realtime scheduling for callback thread.
|
||||
|
||||
By default, RtAudio streams pass and receive audio data from the
|
||||
client in an interleaved format. By passing the
|
||||
@@ -268,6 +273,11 @@ class RtAudio
|
||||
open the input and/or output stream device(s) for exclusive use.
|
||||
Note that this is not possible with all supported audio APIs.
|
||||
|
||||
If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt
|
||||
to select realtime scheduling (round-robin) for the callback thread.
|
||||
The \c priority parameter will only be used if the RTAUDIO_SCHEDULE_REALTIME
|
||||
flag is set. It defines the thread's realtime priority.
|
||||
|
||||
The \c numberOfBuffers parameter can be used to control stream
|
||||
latency in the Windows DirectSound, Linux OSS, and Linux Alsa APIs
|
||||
only. A value of two is usually the smallest allowed. Larger
|
||||
@@ -285,10 +295,11 @@ class RtAudio
|
||||
RtAudioStreamFlags flags; /*!< A bit-mask of stream flags (RTAUDIO_NONINTERLEAVED, RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE). */
|
||||
unsigned int numberOfBuffers; /*!< Number of stream buffers. */
|
||||
std::string streamName; /*!< A stream name (currently used only in Jack). */
|
||||
int priority; /*!< Scheduling priority of callback thread (only used with flag RTAUDIO_SCHEDULE_REALTIME). */
|
||||
|
||||
// Default constructor.
|
||||
StreamOptions()
|
||||
: flags(0), numberOfBuffers(0) {}
|
||||
: flags(0), numberOfBuffers(0), priority(0) {}
|
||||
};
|
||||
|
||||
//! A static function to determine the available compiled audio APIs.
|
||||
@@ -440,10 +451,10 @@ class RtAudio
|
||||
void abortStream( void );
|
||||
|
||||
//! Returns true if a stream is open and false if not.
|
||||
bool isStreamOpen( void ) throw();
|
||||
bool isStreamOpen( void ) const throw();
|
||||
|
||||
//! Returns true if the stream is running and false if it is stopped or not open.
|
||||
bool isStreamRunning( void ) throw();
|
||||
bool isStreamRunning( void ) const throw();
|
||||
|
||||
//! Returns the number of elapsed seconds since the stream was started.
|
||||
/*!
|
||||
@@ -462,6 +473,14 @@ class RtAudio
|
||||
*/
|
||||
long getStreamLatency( void );
|
||||
|
||||
//! Returns actual sample rate in use by the stream.
|
||||
/*!
|
||||
On some systems, the sample rate used may be slightly different
|
||||
than that specified in the stream parameters. If a stream is not
|
||||
open, an RtError (type = INVALID_USE) will be thrown.
|
||||
*/
|
||||
unsigned int getStreamSampleRate( void );
|
||||
|
||||
//! Specify whether warning messages should be printed to stderr.
|
||||
void showWarnings( bool value = true ) throw();
|
||||
|
||||
@@ -551,9 +570,10 @@ public:
|
||||
virtual void stopStream( void ) = 0;
|
||||
virtual void abortStream( void ) = 0;
|
||||
long getStreamLatency( void );
|
||||
unsigned int getStreamSampleRate( void );
|
||||
virtual double getStreamTime( void );
|
||||
bool isStreamOpen( void ) { return stream_.state != STREAM_CLOSED; };
|
||||
bool isStreamRunning( void ) { return stream_.state == STREAM_RUNNING; };
|
||||
bool isStreamOpen( void ) const { return stream_.state != STREAM_CLOSED; };
|
||||
bool isStreamRunning( void ) const { return stream_.state == STREAM_RUNNING; };
|
||||
void showWarnings( bool value ) { showWarnings_ = value; };
|
||||
|
||||
|
||||
@@ -617,7 +637,7 @@ protected:
|
||||
#endif
|
||||
|
||||
RtApiStream()
|
||||
:apiHandle(0), deviceBuffer(0) {}
|
||||
:apiHandle(0), deviceBuffer(0) { device[0] = 11111; device[1] = 11111; }
|
||||
};
|
||||
|
||||
typedef signed short Int16;
|
||||
@@ -688,9 +708,10 @@ inline void RtAudio :: closeStream( void ) throw() { return rtapi_->closeStream(
|
||||
inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); }
|
||||
inline void RtAudio :: stopStream( void ) { return rtapi_->stopStream(); }
|
||||
inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
|
||||
inline bool RtAudio :: isStreamOpen( void ) throw() { return rtapi_->isStreamOpen(); }
|
||||
inline bool RtAudio :: isStreamRunning( void ) throw() { return rtapi_->isStreamRunning(); }
|
||||
inline bool RtAudio :: isStreamOpen( void ) const throw() { return rtapi_->isStreamOpen(); }
|
||||
inline bool RtAudio :: isStreamRunning( void ) const throw() { return rtapi_->isStreamRunning(); }
|
||||
inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); }
|
||||
inline unsigned int RtAudio :: getStreamSampleRate( void ) { return rtapi_->getStreamSampleRate(); };
|
||||
inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); }
|
||||
inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings( value ); }
|
||||
|
||||
@@ -867,6 +888,8 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
std::vector<RtAudio::DeviceInfo> devices_;
|
||||
void saveDeviceInfo( void );
|
||||
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
|
||||
unsigned int firstChannel, unsigned int sampleRate,
|
||||
RtAudioFormat format, unsigned int *bufferSize,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
|
||||
|
||||
RtMidi: realtime MIDI i/o C++ classes
|
||||
Copyright (c) 2003-2007 Gary P. Scavone
|
||||
Copyright (c) 2003-2009 Gary P. Scavone
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
@@ -35,7 +35,7 @@
|
||||
*/
|
||||
/**********************************************************************/
|
||||
|
||||
// RtMidi: Version 1.0.7
|
||||
// RtMidi: Version 1.0.9
|
||||
|
||||
#ifndef RTMIDI_H
|
||||
#define RTMIDI_H
|
||||
@@ -48,7 +48,7 @@ class RtMidi
|
||||
public:
|
||||
|
||||
//! Pure virtual openPort() function.
|
||||
virtual void openPort( unsigned int portNumber = 0 ) = 0;
|
||||
virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0;
|
||||
|
||||
//! Pure virtual openVirtualPort() function.
|
||||
virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0;
|
||||
@@ -91,7 +91,7 @@ class RtMidi
|
||||
to open a virtual input port to which other MIDI software clients
|
||||
can connect.
|
||||
|
||||
by Gary P. Scavone, 2003-2004.
|
||||
by Gary P. Scavone, 2003-2008.
|
||||
*/
|
||||
/**********************************************************************/
|
||||
|
||||
@@ -105,11 +105,11 @@ class RtMidiIn : public RtMidi
|
||||
//! User callback function type definition.
|
||||
typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData);
|
||||
|
||||
//! Default constructor.
|
||||
//! Default constructor that allows an optional client name.
|
||||
/*!
|
||||
An exception will be thrown if a MIDI system initialization error occurs.
|
||||
*/
|
||||
RtMidiIn();
|
||||
RtMidiIn( const std::string clientName = std::string( "RtMidi Input Client") );
|
||||
|
||||
//! If a MIDI connection is still open, it will be closed by the destructor.
|
||||
~RtMidiIn();
|
||||
@@ -119,7 +119,7 @@ class RtMidiIn : public RtMidi
|
||||
An optional port number greater than 0 can be specified.
|
||||
Otherwise, the default or first port found is opened.
|
||||
*/
|
||||
void openPort( unsigned int portNumber = 0 );
|
||||
void openPort( unsigned int portNumber = 0, const std::string Portname = std::string( "RtMidi Input" ) );
|
||||
|
||||
//! Create a virtual input port, with optional name, to allow software connections (OS X and ALSA only).
|
||||
/*!
|
||||
@@ -200,6 +200,7 @@ class RtMidiIn : public RtMidi
|
||||
// the MIDI input handling function or thread.
|
||||
struct RtMidiInData {
|
||||
std::queue<MidiMessage> queue;
|
||||
MidiMessage message;
|
||||
unsigned int queueLimit;
|
||||
unsigned char ignoreFlags;
|
||||
bool doInput;
|
||||
@@ -208,16 +209,18 @@ class RtMidiIn : public RtMidi
|
||||
bool usingCallback;
|
||||
void *userCallback;
|
||||
void *userData;
|
||||
bool continueSysex;
|
||||
|
||||
// Default constructor.
|
||||
RtMidiInData()
|
||||
: queueLimit(1024), ignoreFlags(7), doInput(false), firstMessage(true),
|
||||
apiData(0), usingCallback(false), userCallback(0), userData(0) {}
|
||||
apiData(0), usingCallback(false), userCallback(0), userData(0),
|
||||
continueSysex(false) {}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
void initialize( void );
|
||||
void initialize( const std::string& clientName );
|
||||
RtMidiInData inputData_;
|
||||
|
||||
};
|
||||
@@ -232,7 +235,7 @@ class RtMidiIn : public RtMidi
|
||||
the connection. Create multiple instances of this class to
|
||||
connect to more than one MIDI device at the same time.
|
||||
|
||||
by Gary P. Scavone, 2003-2004.
|
||||
by Gary P. Scavone, 2003-2008.
|
||||
*/
|
||||
/**********************************************************************/
|
||||
|
||||
@@ -240,11 +243,11 @@ class RtMidiOut : public RtMidi
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor.
|
||||
//! Default constructor that allows an optional client name.
|
||||
/*!
|
||||
An exception will be thrown if a MIDI system initialization error occurs.
|
||||
*/
|
||||
RtMidiOut();
|
||||
RtMidiOut( const std::string clientName = std::string( "RtMidi Output Client" ) );
|
||||
|
||||
//! The destructor closes any open MIDI connections.
|
||||
~RtMidiOut();
|
||||
@@ -256,7 +259,7 @@ class RtMidiOut : public RtMidi
|
||||
exception is thrown if an error occurs while attempting to make
|
||||
the port connection.
|
||||
*/
|
||||
void openPort( unsigned int portNumber = 0 );
|
||||
void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Output" ) );
|
||||
|
||||
//! Close an open MIDI connection (if one exists).
|
||||
void closePort();
|
||||
@@ -290,7 +293,7 @@ class RtMidiOut : public RtMidi
|
||||
|
||||
private:
|
||||
|
||||
void initialize( void );
|
||||
void initialize( const std::string& clientName );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
#ifndef STK_RTWVIN_H
|
||||
#define STK_RTWVIN_H
|
||||
|
||||
#include "WvIn.h"
|
||||
#include "RtAudio.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class RtWvIn
|
||||
\brief STK realtime audio (blocking) input class.
|
||||
@@ -10,36 +19,28 @@
|
||||
|
||||
RtWvIn supports multi-channel data in both interleaved and
|
||||
non-interleaved formats. 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.
|
||||
tick() method that computes a single frame (and returns only the
|
||||
specified sample of a multi-channel frame) from the overloaded one
|
||||
that takes an StkFrames object for multi-channel and/or
|
||||
multi-frame data.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_RTWVIN_H
|
||||
#define STK_RTWVIN_H
|
||||
|
||||
#include "WvIn.h"
|
||||
#include "RtAudio.h"
|
||||
|
||||
class RtWvIn : public WvIn
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
/*!
|
||||
The \e device argument is passed to RtAudio during
|
||||
instantiation. The default value (zero) will select the default
|
||||
device on your system or the first device found meeting the
|
||||
specified parameters. On systems with multiple
|
||||
soundcards/devices, values greater than zero can be specified in
|
||||
accordance with the order that the devices are enumerated by the
|
||||
underlying audio API. The default buffer size of RT_BUFFER_SIZE
|
||||
is defined in Stk.h. An StkError will be thrown if an error
|
||||
occurs duing instantiation.
|
||||
The default \e device argument value (zero) will select the
|
||||
default input device on your system. The first device enumerated
|
||||
by the underlying audio API is specified with a value of one. The
|
||||
default buffer size of RT_BUFFER_SIZE is defined in Stk.h. An
|
||||
StkError will be thrown if an error occurs duing instantiation.
|
||||
*/
|
||||
RtWvIn( unsigned int nChannels = 1, StkFloat sampleRate = Stk::sampleRate(), int device = 0, int bufferFrames = RT_BUFFER_SIZE, int nBuffers = 20 );
|
||||
RtWvIn( unsigned int nChannels = 1, StkFloat sampleRate = Stk::sampleRate(),
|
||||
int device = 0, int bufferFrames = RT_BUFFER_SIZE, int nBuffers = 20 );
|
||||
|
||||
//! Class destructor.
|
||||
~RtWvIn();
|
||||
@@ -58,15 +59,48 @@ public:
|
||||
*/
|
||||
void stop( void );
|
||||
|
||||
// This function is not intended for general use but had to be made
|
||||
//! Return the specified channel value of the last computed frame.
|
||||
/*!
|
||||
For multi-channel files, use the lastFrame() function to get
|
||||
all values from the last computed frame. If the device is
|
||||
stopped, the returned value is 0.0. The \c channel argument must
|
||||
be less than the number of channels in the audio stream (the first
|
||||
channel is specified by 0). However, range checking is only
|
||||
performed if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFloat lastOut( unsigned int channel = 0 );
|
||||
|
||||
//! Compute a sample frame and return the specified \c channel value.
|
||||
/*!
|
||||
For multi-channel files, use the lastFrame() function to get
|
||||
all values from the computed frame. If the device is "stopped",
|
||||
it is "started". The \c channel argument must be less than the
|
||||
number of channels in the audio stream (the first channel is
|
||||
specified by 0). However, range checking is only performed if
|
||||
_STK_DEBUG_ is defined during compilation, in which case an
|
||||
out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Fill the StkFrames argument with computed frames and return the same reference.
|
||||
/*!
|
||||
If the device is "stopped", it is "started". The number of
|
||||
channels in the StkFrames argument must equal the number of
|
||||
channels specified during instantiation. However, this is only
|
||||
checked if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an incompatibility will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames );
|
||||
|
||||
// This function is not intended for general use but must be
|
||||
// public for access from the audio callback function.
|
||||
void fillBuffer( void *buffer, unsigned int nFrames );
|
||||
|
||||
protected:
|
||||
|
||||
void computeFrame( void );
|
||||
|
||||
RtAudio adc_;
|
||||
Mutex mutex_;
|
||||
bool stopped_;
|
||||
unsigned int readIndex_;
|
||||
unsigned int writeIndex_;
|
||||
@@ -74,4 +108,18 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat RtWvIn :: lastOut( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= data_.channels() ) {
|
||||
errorString_ << "RtWvIn::lastOut(): channel argument and audio stream are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
#ifndef STK_RTWVOUT_H
|
||||
#define STK_RTWVOUT_H
|
||||
|
||||
#include "WvOut.h"
|
||||
#include "RtAudio.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class RtWvOut
|
||||
\brief STK realtime audio (blocking) output class.
|
||||
@@ -9,35 +18,26 @@
|
||||
low-latency is desired.
|
||||
|
||||
RtWvOut supports multi-channel data in interleaved format. It is
|
||||
important to distinguish the tick() methods, which output single
|
||||
samples to all channels in a sample frame, from the tickFrame()
|
||||
method, which take a pointer or reference to multi-channel sample
|
||||
frame data.
|
||||
important to distinguish the tick() method that outputs a single
|
||||
sample to all channels in a sample frame from the overloaded one
|
||||
that takes a reference to an StkFrames object for multi-channel
|
||||
and/or multi-frame data.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_RTWVOUT_H
|
||||
#define STK_RTWVOUT_H
|
||||
|
||||
#include "WvOut.h"
|
||||
#include "RtAudio.h"
|
||||
|
||||
class RtWvOut : public WvOut
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor.
|
||||
/*!
|
||||
The \e device argument is passed to RtAudio during
|
||||
instantiation. The default value (zero) will select the default
|
||||
device on your system. On systems with multiple
|
||||
soundcards/devices, values greater than zero can be specified in
|
||||
accordance with the order that the devices are enumerated by the
|
||||
underlying audio API. The default buffer size of RT_BUFFER_SIZE
|
||||
is defined in Stk.h. An StkError will be thrown if an error
|
||||
occurs duing instantiation.
|
||||
The default \e device argument value (zero) will select the
|
||||
default output device on your system. The first device enumerated
|
||||
by the underlying audio API is specified with a value of one. The
|
||||
default buffer size of RT_BUFFER_SIZE is defined in Stk.h. An
|
||||
StkError will be thrown if an error occurs duing instantiation.
|
||||
*/
|
||||
RtWvOut( unsigned int nChannels = 1, StkFloat sampleRate = Stk::sampleRate(),
|
||||
int device = 0, int bufferFrames = RT_BUFFER_SIZE, int nBuffers = 20 );
|
||||
@@ -48,7 +48,7 @@ class RtWvOut : public WvOut
|
||||
//! Start the audio output stream.
|
||||
/*!
|
||||
The stream is started automatically, if necessary, when a
|
||||
tick() or tickFrame method is called.
|
||||
tick() method is called.
|
||||
*/
|
||||
void start( void );
|
||||
|
||||
@@ -59,16 +59,30 @@ class RtWvOut : public WvOut
|
||||
*/
|
||||
void stop( void );
|
||||
|
||||
// This function is not intended for general use but had to be made
|
||||
//! Output a single sample to all channels in a sample frame.
|
||||
/*!
|
||||
If the device is "stopped", it is "started".
|
||||
*/
|
||||
void tick( const StkFloat sample );
|
||||
|
||||
//! Output the StkFrames data.
|
||||
/*!
|
||||
If the device is "stopped", it is "started". The number of
|
||||
channels in the StkFrames argument must equal the number of
|
||||
channels specified during instantiation. However, this is only
|
||||
checked if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an incompatibility will trigger an StkError exception.
|
||||
*/
|
||||
void tick( StkFrames& frames );
|
||||
|
||||
// This function is not intended for general use but must be
|
||||
// public for access from the audio callback function.
|
||||
int readBuffer( void *buffer, unsigned int frameCount );
|
||||
|
||||
protected:
|
||||
|
||||
void computeSample( const StkFloat sample );
|
||||
void computeFrames( const StkFrames& frames );
|
||||
|
||||
RtAudio dac_;
|
||||
Mutex mutex_;
|
||||
bool stopped_;
|
||||
unsigned int readIndex_;
|
||||
unsigned int writeIndex_;
|
||||
@@ -77,4 +91,6 @@ class RtWvOut : public WvOut
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,10 +9,12 @@
|
||||
|
||||
where <name> is the string used in the SKINI stream.
|
||||
|
||||
by Perry R. Cook, 1995 - 2004.
|
||||
by Perry R. Cook, 1995 - 2009.
|
||||
*/
|
||||
/*********************************************************/
|
||||
|
||||
namespace stk {
|
||||
|
||||
#define NOPE -32767
|
||||
#define YEP 1
|
||||
#define SK_DBL -32766
|
||||
@@ -124,4 +126,4 @@
|
||||
#define __SK_SINGER_RndVibAmt_ 3008
|
||||
#define __SK_SINGER_VibFreq_ __SK_Expression_
|
||||
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
|
||||
#include "SKINI.msg"
|
||||
|
||||
namespace stk {
|
||||
|
||||
#define __SK_MaxMsgTypes_ 80
|
||||
|
||||
struct SkiniSpec { char messageString[32];
|
||||
@@ -129,3 +131,5 @@ struct SkiniSpec skini_msgs[__SK_MaxMsgTypes_] =
|
||||
/* message. */
|
||||
/* */
|
||||
/*************************************************************************/
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -1,56 +1,59 @@
|
||||
/***************************************************/
|
||||
/*! \class Sampler
|
||||
\brief STK sampling synthesis abstract base class.
|
||||
|
||||
This instrument provides an ADSR envelope, a one-pole filter, and
|
||||
structures for an arbitrary number of attack and loop waves.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_SAMPLER_H
|
||||
#define STK_SAMPLER_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "ADSR.h"
|
||||
#include "WaveLoop.h"
|
||||
#include "FileLoop.h"
|
||||
#include "OnePole.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Sampler
|
||||
\brief STK sampling synthesis abstract base class.
|
||||
|
||||
This instrument provides an ADSR envelope, a one-pole filter, and
|
||||
structures for an arbitrary number of attack and looped files.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Sampler : public Instrmnt
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
Sampler();
|
||||
Sampler( void );
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~Sampler();
|
||||
virtual ~Sampler( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
virtual void setFrequency(StkFloat frequency) = 0;
|
||||
virtual void setFrequency( StkFloat frequency ) = 0;
|
||||
|
||||
//! Initiate the envelopes with a key-on event and reset the attack waves.
|
||||
void keyOn();
|
||||
void keyOn( void );
|
||||
|
||||
//! Signal a key-off event to the envelopes.
|
||||
void keyOff();
|
||||
void keyOff( void );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
virtual void noteOff(StkFloat amplitude);
|
||||
virtual 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;
|
||||
virtual void controlChange( int number, StkFloat value ) = 0;
|
||||
|
||||
//! Compute and return one output sample.
|
||||
virtual StkFloat tick( unsigned int channel = 0 ) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
virtual StkFloat computeSample( void ) = 0;
|
||||
|
||||
ADSR adsr_;
|
||||
std::vector<FileWvIn *> attacks_;
|
||||
std::vector<WaveLoop *> loops_;
|
||||
std::vector<FileLoop *> loops_;
|
||||
OnePole filter_;
|
||||
StkFloat baseFrequency_;
|
||||
std::vector<StkFloat> attackRatios_;
|
||||
@@ -60,4 +63,6 @@ class Sampler : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
#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 stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Saxofony
|
||||
\brief STK faux conical bore reed instrument class.
|
||||
@@ -31,21 +44,10 @@
|
||||
- Vibrato Gain = 1
|
||||
- Breath Pressure = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#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"
|
||||
|
||||
class Saxofony : public Instrmnt
|
||||
{
|
||||
public:
|
||||
@@ -53,39 +55,40 @@ class Saxofony : public Instrmnt
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
Saxofony(StkFloat lowestFrequency);
|
||||
Saxofony( StkFloat lowestFrequency );
|
||||
|
||||
//! Class destructor.
|
||||
~Saxofony();
|
||||
~Saxofony( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set the "blowing" position between the air column terminations (0.0 - 1.0).
|
||||
void setBlowPosition(StkFloat aPosition);
|
||||
void setBlowPosition( StkFloat aPosition );
|
||||
|
||||
//! Apply breath pressure to instrument with given amplitude and rate of increase.
|
||||
void startBlowing(StkFloat amplitude, StkFloat rate);
|
||||
void startBlowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath pressure with given rate of decrease.
|
||||
void stopBlowing(StkFloat rate);
|
||||
void stopBlowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
DelayL delays_[2];
|
||||
ReedTable reedTable_;
|
||||
OneZero filter_;
|
||||
@@ -100,4 +103,27 @@ class Saxofony : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Saxofony :: tick( unsigned int )
|
||||
{
|
||||
StkFloat pressureDiff;
|
||||
StkFloat breathPressure;
|
||||
StkFloat temp;
|
||||
|
||||
// Calculate the breath pressure (envelope + noise + vibrato)
|
||||
breathPressure = envelope_.tick();
|
||||
breathPressure += breathPressure * noiseGain_ * noise_.tick();
|
||||
breathPressure += breathPressure * vibratoGain_ * vibrato_.tick();
|
||||
|
||||
temp = -0.95 * filter_.tick( delays_[0].lastOut() );
|
||||
lastFrame_[0] = temp - delays_[1].lastOut();
|
||||
pressureDiff = breathPressure - lastFrame_[0];
|
||||
delays_[1].tick( temp );
|
||||
delays_[0].tick( breathPressure - (pressureDiff * reedTable_.tick(pressureDiff)) - temp );
|
||||
|
||||
lastFrame_[0] *= outputGain_;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_SHAKERS_H
|
||||
#define STK_SHAKERS_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Shakers
|
||||
\brief PhISEM and PhOLIES class.
|
||||
@@ -48,15 +55,10 @@
|
||||
- Little Rocks = 21
|
||||
- Tuned Bamboo Chimes = 22
|
||||
|
||||
by Perry R. Cook, 1996 - 2004.
|
||||
by Perry R. Cook, 1996 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_SHAKERS_H
|
||||
#define STK_SHAKERS_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
|
||||
const int MAX_FREQS = 8;
|
||||
const int NUM_INSTR = 24;
|
||||
|
||||
@@ -64,35 +66,37 @@ class Shakers : public Instrmnt
|
||||
{
|
||||
public:
|
||||
//! Class constructor.
|
||||
Shakers();
|
||||
Shakers( void );
|
||||
|
||||
//! Class destructor.
|
||||
~Shakers();
|
||||
~Shakers( void );
|
||||
|
||||
//! Start a note with the given instrument and amplitude.
|
||||
/*!
|
||||
Use the instrument numbers above, converted to frequency values
|
||||
as if MIDI note numbers, to select a particular instrument.
|
||||
*/
|
||||
void noteOn(StkFloat instrument, StkFloat amplitude);
|
||||
void noteOn( StkFloat instrument, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
int setupName(char* instr);
|
||||
int setupNum(int inst);
|
||||
int setFreqAndReson(int which, StkFloat freq, StkFloat reson);
|
||||
void setDecays(StkFloat sndDecay, StkFloat sysDecay);
|
||||
void setFinalZs(StkFloat z0, StkFloat z1, StkFloat z2);
|
||||
StkFloat wuter_tick();
|
||||
StkFloat tbamb_tick();
|
||||
StkFloat ratchet_tick();
|
||||
int setupName( char* instr );
|
||||
int setupNum( int inst );
|
||||
int setFreqAndReson( int which, StkFloat freq, StkFloat reson );
|
||||
void setDecays( StkFloat sndDecay, StkFloat sysDecay );
|
||||
void setFinalZs( StkFloat z0, StkFloat z1, StkFloat z2 );
|
||||
StkFloat wuter_tick( void );
|
||||
StkFloat tbamb_tick( void );
|
||||
StkFloat ratchet_tick( void );
|
||||
|
||||
int instType_;
|
||||
int ratchetPos_, lastRatchetPos_;
|
||||
@@ -122,4 +126,6 @@ class Shakers : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
#ifndef STK_SIMPLE_H
|
||||
#define STK_SIMPLE_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "ADSR.h"
|
||||
#include "FileLoop.h"
|
||||
#include "OnePole.h"
|
||||
#include "BiQuad.h"
|
||||
#include "Noise.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Simple
|
||||
\brief STK wavetable/noise instrument.
|
||||
@@ -13,20 +25,10 @@
|
||||
- Envelope Rate = 11
|
||||
- Gain = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_SIMPLE_H
|
||||
#define STK_SIMPLE_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "ADSR.h"
|
||||
#include "WaveLoop.h"
|
||||
#include "OnePole.h"
|
||||
#include "BiQuad.h"
|
||||
#include "Noise.h"
|
||||
|
||||
class Simple : public Instrmnt
|
||||
{
|
||||
public:
|
||||
@@ -34,38 +36,39 @@ class Simple : public Instrmnt
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
Simple();
|
||||
Simple( void );
|
||||
|
||||
//! Class destructor.
|
||||
~Simple();
|
||||
~Simple( void );
|
||||
|
||||
//! Clear internal states.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Start envelope toward "on" target.
|
||||
void keyOn();
|
||||
void keyOn( void );
|
||||
|
||||
//! Start envelope toward "off" target.
|
||||
void keyOff();
|
||||
void keyOff( void );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
ADSR adsr_;
|
||||
WaveLoop *loop_;
|
||||
FileLoop *loop_;
|
||||
OnePole filter_;
|
||||
BiQuad biquad_;
|
||||
Noise noise_;
|
||||
@@ -74,4 +77,16 @@ class Simple : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Simple :: tick( unsigned int )
|
||||
{
|
||||
lastFrame_[0] = loopGain_ * loop_->tick();
|
||||
biquad_.tick( noise_.tick() );
|
||||
lastFrame_[0] += (1.0 - loopGain_) * biquad_.lastOut();
|
||||
lastFrame_[0] = filter_.tick( lastFrame_[0] );
|
||||
lastFrame_[0] *= adsr_.tick();
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
#ifndef STK_SINEWAVE_H
|
||||
#define STK_SINEWAVE_H
|
||||
|
||||
const unsigned long TABLE_SIZE = 2048;
|
||||
|
||||
#include "Generator.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class SineWave
|
||||
\brief STK sinusoid oscillator class.
|
||||
@@ -13,13 +22,6 @@
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_SINEWAVE_H
|
||||
#define STK_SINEWAVE_H
|
||||
|
||||
const unsigned long TABLE_SIZE = 2048;
|
||||
|
||||
#include "Generator.h"
|
||||
|
||||
class SineWave : public Generator
|
||||
{
|
||||
public:
|
||||
@@ -27,7 +29,7 @@ public:
|
||||
SineWave( void );
|
||||
|
||||
//! Class destructor.
|
||||
virtual ~SineWave( void );
|
||||
~SineWave( void );
|
||||
|
||||
//! Clear output and reset time pointer to zero.
|
||||
void reset( void );
|
||||
@@ -47,35 +49,111 @@ public:
|
||||
*/
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Increment the read pointer by \e time samples, modulo file size.
|
||||
//! Increment the read pointer by \e time in samples, modulo the table size.
|
||||
void addTime( StkFloat time );
|
||||
|
||||
//! Increment current read pointer by \e angle, relative to a looping frequency.
|
||||
//! Increment the read pointer by a normalized \e phase value.
|
||||
/*!
|
||||
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.
|
||||
This function increments the read pointer by a normalized phase
|
||||
value, such that \e phase = 1.0 corresponds to a 360 degree phase
|
||||
shift. Positive or negative values are possible.
|
||||
*/
|
||||
void addPhase( StkFloat angle );
|
||||
void addPhase( StkFloat phase );
|
||||
|
||||
//! Add a phase offset to the current read pointer.
|
||||
//! Add a normalized phase offset to the 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.
|
||||
A \e phaseOffset = 1.0 corresponds to a 360 degree phase
|
||||
offset. Positive or negative values are possible.
|
||||
*/
|
||||
void addPhaseOffset( StkFloat angle );
|
||||
void addPhaseOffset( StkFloat phaseOffset );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
|
||||
static StkFrames table_;
|
||||
StkFloat time_;
|
||||
StkFloat rate_;
|
||||
StkFloat phaseOffset_;
|
||||
unsigned int iIndex_;
|
||||
StkFloat alpha_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat SineWave :: tick( void )
|
||||
{
|
||||
// Check limits of time address ... if necessary, recalculate modulo
|
||||
// TABLE_SIZE.
|
||||
while ( time_ < 0.0 )
|
||||
time_ += TABLE_SIZE;
|
||||
while ( time_ >= TABLE_SIZE )
|
||||
time_ -= TABLE_SIZE;
|
||||
|
||||
iIndex_ = (unsigned int) time_;
|
||||
alpha_ = time_ - iIndex_;
|
||||
StkFloat tmp = table_[ iIndex_ ];
|
||||
tmp += ( alpha_ * ( table_[ iIndex_ + 1 ] - tmp ) );
|
||||
|
||||
// Increment time, which can be negative.
|
||||
time_ += rate_;
|
||||
|
||||
lastFrame_[0] = tmp;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& SineWave :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "SineWave::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
StkFloat tmp = 0.0;
|
||||
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
|
||||
// Check limits of time address ... if necessary, recalculate modulo
|
||||
// TABLE_SIZE.
|
||||
while ( time_ < 0.0 )
|
||||
time_ += TABLE_SIZE;
|
||||
while ( time_ >= TABLE_SIZE )
|
||||
time_ -= TABLE_SIZE;
|
||||
|
||||
iIndex_ = (unsigned int) time_;
|
||||
alpha_ = time_ - iIndex_;
|
||||
tmp = table_[ iIndex_ ];
|
||||
tmp += ( alpha_ * ( table_[ iIndex_ + 1 ] - tmp ) );
|
||||
*samples = tmp;
|
||||
|
||||
// Increment time, which can be negative.
|
||||
time_ += rate_;
|
||||
}
|
||||
|
||||
lastFrame_[0] = tmp;
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,79 +1,98 @@
|
||||
#ifndef STK_SINGWAVE_H
|
||||
#define STK_SINGWAVE_H
|
||||
|
||||
#include "FileLoop.h"
|
||||
#include "Modulate.h"
|
||||
#include "Envelope.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class SingWave
|
||||
\brief STK "singing" looped soundfile class.
|
||||
|
||||
This class contains all that is needed to make
|
||||
a pitched musical sound, like a simple voice
|
||||
or violin. In general, it will not be used
|
||||
alone because of munchkinification effects
|
||||
from pitch shifting. It will be used as an
|
||||
excitation source for other instruments.
|
||||
This class loops a specified soundfile and modulates it both
|
||||
periodically and randomly to produce a pitched musical sound, like
|
||||
a simple voice or violin. In general, it is not be used alone
|
||||
because of "munchkinification" effects from pitch shifting.
|
||||
Within STK, it is used as an excitation source for other
|
||||
instruments.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_SINGWAVE_H
|
||||
#define STK_SINGWAVE_H
|
||||
|
||||
#include "WaveLoop.h"
|
||||
#include "Modulate.h"
|
||||
#include "Envelope.h"
|
||||
|
||||
class SingWave : public Generator
|
||||
{
|
||||
public:
|
||||
//! Class constructor taking filename argument.
|
||||
/*!
|
||||
An StkError will be thrown if the file is not found, its format is
|
||||
unknown, a read error occurs, or the rawwave path is incorrectly set.
|
||||
An StkError will be thrown if the file is not found, its format
|
||||
is unknown, or a read error occurs. If the soundfile has no
|
||||
header, the second argument should be \e true and the file data
|
||||
will be assumed to consist of 16-bit signed integers in big-endian
|
||||
byte order at a sample rate of 22050 Hz.
|
||||
*/
|
||||
SingWave( std::string fileName, bool raw = false);
|
||||
SingWave( std::string fileName, bool raw = false );
|
||||
|
||||
//! Class destructor.
|
||||
~SingWave();
|
||||
~SingWave( void );
|
||||
|
||||
//! Reset file to beginning.
|
||||
void reset();
|
||||
void reset( void ) { wave_.reset(); lastFrame_[0] = 0.0; };
|
||||
|
||||
//! Normalize the file to a maximum of +-1.0.
|
||||
void normalize();
|
||||
void normalize( void ) { wave_.normalize(); };
|
||||
|
||||
//! Normalize the file to a maximum of \e +- peak.
|
||||
void normalize(StkFloat peak);
|
||||
void normalize( StkFloat peak ) { wave_.normalize( peak ); };
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
//! Set looping parameters for a particular frequency.
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set the vibrato frequency in Hz.
|
||||
void setVibratoRate(StkFloat rate);
|
||||
void setVibratoRate( StkFloat rate ) { modulator_.setVibratoRate( rate ); };
|
||||
|
||||
//! Set the vibrato gain.
|
||||
void setVibratoGain(StkFloat gain);
|
||||
void setVibratoGain( StkFloat gain ) { modulator_.setVibratoGain( gain ); };
|
||||
|
||||
//! Set the random-ness amount.
|
||||
void setRandomGain(StkFloat gain);
|
||||
void setRandomGain( StkFloat gain ) { modulator_.setRandomGain( gain ); };
|
||||
|
||||
//! Set the sweep rate.
|
||||
void setSweepRate(StkFloat rate);
|
||||
void setSweepRate( StkFloat rate ) { sweepRate_ = rate; };
|
||||
|
||||
//! Set the gain rate.
|
||||
void setGainRate(StkFloat rate);
|
||||
void setGainRate( StkFloat rate ) { envelope_.setRate( rate ); };
|
||||
|
||||
//! Set the gain target value.
|
||||
void setGainTarget(StkFloat target);
|
||||
void setGainTarget( StkFloat target ) { envelope_.setTarget( target ); };
|
||||
|
||||
//! Start a note.
|
||||
void noteOn();
|
||||
void noteOn( void ) { envelope_.keyOn(); };
|
||||
|
||||
//! Stop a note.
|
||||
void noteOff();
|
||||
void noteOff( void ) { envelope_.keyOff(); };
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of
|
||||
channels in the StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
WaveLoop *wave_;
|
||||
FileLoop wave_;
|
||||
Modulate modulator_;
|
||||
Envelope envelope_;
|
||||
Envelope pitchEnvelope_;
|
||||
@@ -82,4 +101,36 @@ class SingWave : public Generator
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat SingWave :: tick( void )
|
||||
{
|
||||
// Set the wave rate.
|
||||
StkFloat newRate = pitchEnvelope_.tick();
|
||||
newRate += newRate * modulator_.tick();
|
||||
wave_.setRate( newRate );
|
||||
|
||||
lastFrame_[0] = wave_.tick();
|
||||
lastFrame_[0] *= envelope_.tick();
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& SingWave :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "SingWave::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
|
||||
*samples = SingWave::tick();
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
#ifndef STK_SITAR_H
|
||||
#define STK_SITAR_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayA.h"
|
||||
#include "OneZero.h"
|
||||
#include "Noise.h"
|
||||
#include "ADSR.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Sitar
|
||||
\brief STK sitar string model class.
|
||||
@@ -13,19 +25,10 @@
|
||||
Stanford, bearing the names of Karplus and/or
|
||||
Strong.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_SITAR_H
|
||||
#define STK_SITAR_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayA.h"
|
||||
#include "OneZero.h"
|
||||
#include "Noise.h"
|
||||
#include "ADSR.h"
|
||||
|
||||
class Sitar : public Instrmnt
|
||||
{
|
||||
public:
|
||||
@@ -33,27 +36,28 @@ class Sitar : public Instrmnt
|
||||
Sitar( StkFloat lowestFrequency = 20 );
|
||||
|
||||
//! Class destructor.
|
||||
~Sitar();
|
||||
~Sitar( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Pluck the string with the given amplitude using the current frequency.
|
||||
void pluck(StkFloat amplitude);
|
||||
void pluck( StkFloat amplitude );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
void noteOff( StkFloat amplitude );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
DelayA delayLine_;
|
||||
OneZero loopFilter_;
|
||||
Noise noise_;
|
||||
@@ -66,5 +70,23 @@ class Sitar : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat Sitar :: tick( unsigned int )
|
||||
{
|
||||
if ( fabs(targetDelay_ - delay_) > 0.001 ) {
|
||||
if ( targetDelay_ < delay_ )
|
||||
delay_ *= 0.99999;
|
||||
else
|
||||
delay_ *= 1.00001;
|
||||
delayLine_.setDelay( delay_ );
|
||||
}
|
||||
|
||||
lastFrame_[0] = delayLine_.tick( loopFilter_.tick( delayLine_.lastOut() * loopGain_ ) +
|
||||
(amGain_ * envelope_.tick() * noise_.tick()));
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
#ifndef STK_SKINI_H
|
||||
#define STK_SKINI_H
|
||||
|
||||
#include "Stk.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Skini
|
||||
\brief STK SKINI parsing class
|
||||
@@ -21,18 +31,10 @@
|
||||
|
||||
\sa \ref skini
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_SKINI_H
|
||||
#define STK_SKINI_H
|
||||
|
||||
#include "Stk.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
class Skini : public Stk
|
||||
{
|
||||
public:
|
||||
@@ -112,6 +114,8 @@ static const double Midi2Pitch[129] = {
|
||||
8372.02,8869.84,9397.27,9956.06,10548.08,11175.30,11839.82,12543.85,
|
||||
13289.75};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,16 +1,3 @@
|
||||
/***************************************************/
|
||||
/*! \class Socket
|
||||
\brief STK internet socket abstract base class.
|
||||
|
||||
This class provides common functionality for TCP and UDP internet
|
||||
socket server and client subclasses. This class also provides a
|
||||
number of static functions for use with external socket
|
||||
descriptors.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_SOCKET_H
|
||||
#define STK_SOCKET_H
|
||||
|
||||
@@ -33,6 +20,21 @@
|
||||
|
||||
#endif
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Socket
|
||||
\brief STK internet socket abstract base class.
|
||||
|
||||
This class provides common functionality for TCP and UDP internet
|
||||
socket server and client subclasses. This class also provides a
|
||||
number of static functions for use with external socket
|
||||
descriptors.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Socket : public Stk
|
||||
{
|
||||
public:
|
||||
@@ -52,13 +54,13 @@ class Socket : public Stk
|
||||
static void close( int socket );
|
||||
|
||||
//! Return the socket descriptor.
|
||||
int id( void ) const;
|
||||
int id( void ) const { return soket_; };
|
||||
|
||||
//! Return the socket port number.
|
||||
int port( void ) const;
|
||||
int port( void ) const { return port_; };
|
||||
|
||||
//! Returns true if the socket descriptor is valid.
|
||||
static bool isValid( int socket );
|
||||
static bool isValid( int socket ) { return socket != -1; };
|
||||
|
||||
//! If enable = false, the socket is set to non-blocking mode. When first created, sockets are by default in blocking mode.
|
||||
static void setBlocking( int socket, bool enable );
|
||||
@@ -82,4 +84,6 @@ class Socket : public Stk
|
||||
|
||||
};
|
||||
|
||||
#endif // defined(STK_SOCKET_H)
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
#ifndef STK_SPHERE_H
|
||||
#define STK_SPHERE_H
|
||||
|
||||
#include "Stk.h"
|
||||
#include "Vector3D.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Sphere
|
||||
\brief STK sphere class.
|
||||
@@ -5,60 +13,51 @@
|
||||
This class implements a spherical ball with
|
||||
radius, mass, position, and velocity parameters.
|
||||
|
||||
by Perry R. Cook, 1995 - 2004.
|
||||
by Perry R. Cook, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_SPHERE_H
|
||||
#define STK_SPHERE_H
|
||||
|
||||
#include "Stk.h"
|
||||
#include "Vector3D.h"
|
||||
|
||||
class Sphere : public Stk
|
||||
{
|
||||
public:
|
||||
//! Constructor taking an initial radius value.
|
||||
Sphere(StkFloat radius = 1.0 );
|
||||
|
||||
//! Class destructor.
|
||||
~Sphere();
|
||||
Sphere( StkFloat radius = 1.0 ) { radius_ = radius; mass_ = 1.0; };
|
||||
|
||||
//! Set the 3D center position of the sphere.
|
||||
void setPosition(StkFloat x, StkFloat y, StkFloat z);
|
||||
void setPosition( StkFloat x, StkFloat y, StkFloat z ) { position_.setXYZ(x, y, z); };
|
||||
|
||||
//! Set the 3D velocity of the sphere.
|
||||
void setVelocity(StkFloat x, StkFloat y, StkFloat z);
|
||||
void setVelocity( StkFloat x, StkFloat y, StkFloat z ) { velocity_.setXYZ(x, y, z); };
|
||||
|
||||
//! Set the radius of the sphere.
|
||||
void setRadius(StkFloat radius);
|
||||
void setRadius( StkFloat radius ) { radius_ = radius; };
|
||||
|
||||
//! Set the mass of the sphere.
|
||||
void setMass(StkFloat mass);
|
||||
void setMass( StkFloat mass ) { mass_ = mass; };
|
||||
|
||||
//! Get the current position of the sphere as a 3D vector.
|
||||
Vector3D* getPosition();
|
||||
Vector3D* getPosition( void ) { return &position_; };
|
||||
|
||||
//! Get the relative position of the given point to the sphere as a 3D vector.
|
||||
Vector3D* getRelativePosition(Vector3D *position);
|
||||
Vector3D* getRelativePosition( Vector3D *position );
|
||||
|
||||
//! Set the velcoity of the sphere as a 3D vector.
|
||||
StkFloat getVelocity(Vector3D* velocity);
|
||||
StkFloat getVelocity( Vector3D* velocity );
|
||||
|
||||
//! Returns the distance from the sphere boundary to the given position (< 0 if inside).
|
||||
StkFloat isInside(Vector3D *position);
|
||||
StkFloat isInside( Vector3D *position );
|
||||
|
||||
//! Get the current sphere radius.
|
||||
StkFloat getRadius();
|
||||
StkFloat getRadius( void ) { return radius_; };
|
||||
|
||||
//! Get the current sphere mass.
|
||||
StkFloat getMass();
|
||||
StkFloat getMass( void ) { return mass_; };
|
||||
|
||||
//! Increase the current sphere velocity by the given 3D components.
|
||||
void addVelocity(StkFloat x, StkFloat y, StkFloat z);
|
||||
void addVelocity( StkFloat x, StkFloat y, StkFloat z );
|
||||
|
||||
//! Move the sphere for the given time increment.
|
||||
void tick(StkFloat timeIncrement);
|
||||
void tick( StkFloat timeIncrement );
|
||||
|
||||
private:
|
||||
Vector3D position_;
|
||||
@@ -68,4 +67,13 @@ private:
|
||||
StkFloat mass_;
|
||||
};
|
||||
|
||||
inline void Sphere::tick( StkFloat timeIncrement )
|
||||
{
|
||||
position_.setX(position_.getX() + (timeIncrement * velocity_.getX()));
|
||||
position_.setY(position_.getY() + (timeIncrement * velocity_.getY()));
|
||||
position_.setZ(position_.getZ() + (timeIncrement * velocity_.getZ()));
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
#ifndef STK_STIFKARP_H
|
||||
#define STK_STIFKARP_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayL.h"
|
||||
#include "DelayA.h"
|
||||
#include "OneZero.h"
|
||||
#include "Noise.h"
|
||||
#include "BiQuad.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class StifKarp
|
||||
\brief STK plucked stiff string instrument.
|
||||
@@ -17,40 +29,30 @@
|
||||
- String Sustain = 11
|
||||
- String Stretch = 1
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_STIFKARP_H
|
||||
#define STK_STIFKARP_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "DelayL.h"
|
||||
#include "DelayA.h"
|
||||
#include "OneZero.h"
|
||||
#include "Noise.h"
|
||||
#include "BiQuad.h"
|
||||
|
||||
class StifKarp : public Instrmnt
|
||||
{
|
||||
public:
|
||||
//! Class constructor, taking the lowest desired playing frequency.
|
||||
StifKarp(StkFloat lowestFrequency);
|
||||
StifKarp( StkFloat lowestFrequency );
|
||||
|
||||
//! Class destructor.
|
||||
~StifKarp();
|
||||
~StifKarp( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set the stretch "factor" of the string (0.0 - 1.0).
|
||||
void setStretch(StkFloat stretch);
|
||||
void setStretch( StkFloat stretch );
|
||||
|
||||
//! Set the pluck or "excitation" position along the string (0.0 - 1.0).
|
||||
void setPickupPosition(StkFloat position);
|
||||
void setPickupPosition( StkFloat position );
|
||||
|
||||
//! Set the base loop gain.
|
||||
/*!
|
||||
@@ -58,24 +60,25 @@ class StifKarp : public Instrmnt
|
||||
Because of high-frequency loop filter roll-off, higher
|
||||
frequency settings have greater loop gains.
|
||||
*/
|
||||
void setBaseLoopGain(StkFloat aGain);
|
||||
void setBaseLoopGain( StkFloat aGain );
|
||||
|
||||
//! Pluck the string with the given amplitude using the current frequency.
|
||||
void pluck(StkFloat amplitude);
|
||||
void pluck( StkFloat amplitude );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
DelayA delayLine_;
|
||||
DelayL combDelay_;
|
||||
OneZero filter_;
|
||||
@@ -93,4 +96,22 @@ class StifKarp : public Instrmnt
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat StifKarp :: tick( unsigned int )
|
||||
{
|
||||
StkFloat temp = delayLine_.lastOut() * loopGain_;
|
||||
|
||||
// Calculate allpass stretching.
|
||||
for (int i=0; i<4; i++)
|
||||
temp = biquad_[i].tick(temp);
|
||||
|
||||
// Moving average filter.
|
||||
temp = filter_.tick(temp);
|
||||
|
||||
lastFrame_[0] = delayLine_.tick(temp);
|
||||
lastFrame_[0] = lastFrame_[0] - combDelay_.tick( lastFrame_[0] );
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
200
include/Stk.h
200
include/Stk.h
@@ -1,3 +1,20 @@
|
||||
#ifndef STK_STK_H
|
||||
#define STK_STK_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*! \namespace stk
|
||||
\brief The STK namespace.
|
||||
|
||||
Most Stk classes are defined within the STK namespace. Exceptions
|
||||
to this include the classes RtAudio, RtMidi, and RtError.
|
||||
*/
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Stk
|
||||
\brief STK base class
|
||||
@@ -22,7 +39,7 @@
|
||||
STK WWW site: http://ccrma.stanford.edu/software/stk/
|
||||
|
||||
The Synthesis ToolKit in C++ (STK)
|
||||
Copyright (c) 1995-2007 Perry R. Cook and Gary P. Scavone
|
||||
Copyright (c) 1995-2009 Perry R. Cook and Gary P. Scavone
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
@@ -50,13 +67,7 @@
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_STK_H
|
||||
#define STK_STK_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
//#define _STK_DEBUG_
|
||||
|
||||
// Most data in STK is passed and calculated with the
|
||||
// following user-definable floating-point type. You
|
||||
@@ -129,15 +140,15 @@ public:
|
||||
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 method that returns the current STK sample rate.
|
||||
static StkFloat sampleRate( void ) { return srate_; }
|
||||
|
||||
//! Static method that 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
|
||||
classes that 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
|
||||
during instantiation. Therefore, if you wish to use a rate that
|
||||
is different from the default rate, it is imperative that it be
|
||||
set \e BEFORE STK objects are instantiated. A few classes that
|
||||
make use of the global STK sample rate are automatically notified
|
||||
@@ -160,19 +171,19 @@ public:
|
||||
*/
|
||||
void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; };
|
||||
|
||||
//! Static method which returns the current rawwave path.
|
||||
//! Static method that returns the current rawwave path.
|
||||
static std::string rawwavePath(void) { return rawwavepath_; }
|
||||
|
||||
//! Static method which sets the STK rawwave path.
|
||||
//! Static method that sets the STK rawwave path.
|
||||
static void setRawwavePath( std::string path );
|
||||
|
||||
//! Static method which byte-swaps a 16-bit data type.
|
||||
//! Static method that byte-swaps a 16-bit data type.
|
||||
static void swap16( unsigned char *ptr );
|
||||
|
||||
//! Static method which byte-swaps a 32-bit data type.
|
||||
//! Static method that byte-swaps a 32-bit data type.
|
||||
static void swap32( unsigned char *ptr );
|
||||
|
||||
//! Static method which byte-swaps a 64-bit data type.
|
||||
//! Static method that byte-swaps a 64-bit data type.
|
||||
static void swap64( unsigned char *ptr );
|
||||
|
||||
//! Static cross-platform method to sleep for a number of milliseconds.
|
||||
@@ -217,7 +228,7 @@ protected:
|
||||
//! Remove class pointer from list for sample rate change notification.
|
||||
void removeSampleRateAlert( Stk *ptr );
|
||||
|
||||
//! Internal function for error reporting which assumes message in \c errorString_ variable.
|
||||
//! Internal function for error reporting that assumes message in \c errorString_ variable.
|
||||
void handleError( StkError::Type type );
|
||||
};
|
||||
|
||||
@@ -226,16 +237,24 @@ protected:
|
||||
/*! \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.
|
||||
This class can hold single- or multi-channel audio data. The data
|
||||
type is always StkFloat and the channel format is always
|
||||
interleaved. In an effort to maintain efficiency, no
|
||||
out-of-bounds checks are performed in this class unless
|
||||
_STK_DEBUG_ is defined.
|
||||
|
||||
Internally, the data is stored in a one-dimensional C array. An
|
||||
indexing operator is available to set and retrieve data values.
|
||||
Alternately, one can use pointers to access the data, using the
|
||||
index operator to get an address for a particular location in the
|
||||
data:
|
||||
|
||||
StkFloat* ptr = &myStkFrames[0];
|
||||
|
||||
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.
|
||||
to convert to and return other data types.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -244,17 +263,23 @@ 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 );
|
||||
StkFrames( unsigned int nFrames = 0, unsigned int nChannels = 0 );
|
||||
|
||||
//! 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 );
|
||||
StkFrames( const StkFloat& value, unsigned int nFrames, unsigned int nChannels );
|
||||
|
||||
//! The destructor.
|
||||
~StkFrames();
|
||||
|
||||
//! Subscript operator which returns a reference to element \c n of self.
|
||||
// A copy constructor.
|
||||
StkFrames( const StkFrames& f );
|
||||
|
||||
// Assignment operator that returns a reference to self.
|
||||
StkFrames& operator= ( const StkFrames& f );
|
||||
|
||||
//! Subscript operator that returns a reference to element \c n of self.
|
||||
/*!
|
||||
The result can be used as an lvalue . This reference is valid
|
||||
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.
|
||||
@@ -268,6 +293,22 @@ public:
|
||||
*/
|
||||
StkFloat operator[] ( size_t n ) const;
|
||||
|
||||
//! Assignment by sum operator into self.
|
||||
/*!
|
||||
The dimensions of the argument are expected to be the same as
|
||||
self. No range checking is performed unless _STK_DEBUG_ is
|
||||
defined.
|
||||
*/
|
||||
void operator+= ( StkFrames& f );
|
||||
|
||||
//! Assignment by product operator into self.
|
||||
/*!
|
||||
The dimensions of the argument are expected to be the same as
|
||||
self. No range checking is performed unless _STK_DEBUG_ is
|
||||
defined.
|
||||
*/
|
||||
void operator*= ( StkFrames& f );
|
||||
|
||||
//! Channel / frame subscript operator that returns a reference.
|
||||
/*!
|
||||
The result can be used as an lvalue. This reference is valid
|
||||
@@ -341,17 +382,6 @@ public:
|
||||
*/
|
||||
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_;
|
||||
@@ -360,10 +390,98 @@ private:
|
||||
unsigned int nChannels_;
|
||||
size_t size_;
|
||||
size_t bufferSize_;
|
||||
bool interleaved_;
|
||||
|
||||
};
|
||||
|
||||
inline bool StkFrames :: empty() const
|
||||
{
|
||||
if ( size_ > 0 ) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
inline StkFloat& StkFrames :: operator[] ( size_t n )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( n >= size_ ) {
|
||||
std::ostringstream error;
|
||||
error << "StkFrames::operator[]: invalid index (" << n << ") value!";
|
||||
Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
|
||||
}
|
||||
#endif
|
||||
|
||||
return data_[n];
|
||||
}
|
||||
|
||||
inline StkFloat StkFrames :: operator[] ( size_t n ) const
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( n >= size_ ) {
|
||||
std::ostringstream error;
|
||||
error << "StkFrames::operator[]: invalid index (" << n << ") value!";
|
||||
Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
|
||||
}
|
||||
#endif
|
||||
|
||||
return data_[n];
|
||||
}
|
||||
|
||||
inline StkFloat& StkFrames :: operator() ( size_t frame, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frame >= nFrames_ || channel >= nChannels_ ) {
|
||||
std::ostringstream error;
|
||||
error << "StkFrames::operator(): invalid frame (" << frame << ") or channel (" << channel << ") value!";
|
||||
Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
|
||||
}
|
||||
#endif
|
||||
|
||||
return data_[ frame * nChannels_ + channel ];
|
||||
}
|
||||
|
||||
inline StkFloat StkFrames :: operator() ( size_t frame, unsigned int channel ) const
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frame >= nFrames_ || channel >= nChannels_ ) {
|
||||
std::ostringstream error;
|
||||
error << "StkFrames::operator(): invalid frame (" << frame << ") or channel (" << channel << ") value!";
|
||||
Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
|
||||
}
|
||||
#endif
|
||||
|
||||
return data_[ frame * nChannels_ + channel ];
|
||||
}
|
||||
|
||||
inline void StkFrames :: operator+= ( StkFrames& f )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( f.frames() != nFrames_ || f.channels() != nChannels_ ) {
|
||||
std::ostringstream error;
|
||||
error << "StkFrames::operator+=: frames argument must be of equal dimensions!";
|
||||
Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *fptr = &f[0];
|
||||
StkFloat *dptr = data_;
|
||||
for ( unsigned int i=0; i<size_; i++ )
|
||||
*dptr++ += *fptr++;
|
||||
}
|
||||
|
||||
inline void StkFrames :: operator*= ( StkFrames& f )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( f.frames() != nFrames_ || f.channels() != nChannels_ ) {
|
||||
std::ostringstream error;
|
||||
error << "StkFrames::operator*=: frames argument must be of equal dimensions!";
|
||||
Stk::handleError( error.str(), StkError::MEMORY_ACCESS );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *fptr = &f[0];
|
||||
StkFloat *dptr = data_;
|
||||
for ( unsigned int i=0; i<size_; i++ )
|
||||
*dptr++ *= *fptr++;
|
||||
}
|
||||
|
||||
// Here are a few other useful typedefs.
|
||||
typedef unsigned short UINT16;
|
||||
@@ -412,6 +530,6 @@ const StkFloat ONE_OVER_128 = 0.0078125;
|
||||
#define __STK_REALTIME__
|
||||
#endif
|
||||
|
||||
//#define _STK_DEBUG_
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/***************************************************/
|
||||
/*! \class SubNoise
|
||||
\brief STK sub-sampled noise generator.
|
||||
|
||||
Generates a new random number every "rate" ticks
|
||||
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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_SUBNOISE_H
|
||||
#define STK_SUBNOISE_H
|
||||
|
||||
#include "Noise.h"
|
||||
|
||||
class SubNoise : public Noise
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor sets sub-sample rate to 16.
|
||||
SubNoise( int subRate = 16 );
|
||||
|
||||
//! Class destructor.
|
||||
~SubNoise();
|
||||
|
||||
//! Return the current sub-sampling rate.
|
||||
int subRate( void ) const { return rate_; };
|
||||
|
||||
//! Set the sub-sampling rate.
|
||||
void setRate( int subRate );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
int counter_;
|
||||
int rate_;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
216
include/TapDelay.h
Normal file
216
include/TapDelay.h
Normal file
@@ -0,0 +1,216 @@
|
||||
#ifndef STK_TAPDELAY_H
|
||||
#define STK_TAPDELAY_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class TapDelay
|
||||
\brief STK non-interpolating tapped delay line class.
|
||||
|
||||
This class implements a non-interpolating digital delay-line with
|
||||
an arbitrary number of output "taps". If the maximum length and
|
||||
tap delays are not specified during instantiation, a fixed maximum
|
||||
length of 4095 and a single tap delay of zero is set.
|
||||
|
||||
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 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class TapDelay : public Filter
|
||||
{
|
||||
public:
|
||||
|
||||
//! The default constructor creates a delay-line with maximum length of 4095 samples and a single tap at delay = 0.
|
||||
/*!
|
||||
An StkError will be thrown if any tap delay parameter is less
|
||||
than zero, the maximum delay parameter is less than one, or any
|
||||
tap delay parameter is greater than the maxDelay value.
|
||||
*/
|
||||
TapDelay( std::vector<unsigned long> taps = std::vector<unsigned long>( 1, 0 ), unsigned long maxDelay = 4095 );
|
||||
|
||||
//! Class destructor.
|
||||
~TapDelay();
|
||||
|
||||
//! 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 tap lengths.
|
||||
/*!
|
||||
The valid range for each tap length is from 0 to the maximum delay-line length.
|
||||
*/
|
||||
void setTapDelays( std::vector<unsigned long> taps );
|
||||
|
||||
//! Return the current delay-line length.
|
||||
std::vector<unsigned long> getTapDelays( void ) const { return delays_; };
|
||||
|
||||
//! Return the specified tap value of the last computed frame.
|
||||
/*!
|
||||
Use the lastFrame() function to get all tap values from the
|
||||
last computed frame. The \c tap argument must be less than the
|
||||
number of delayline taps (the first tap is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFloat lastOut( unsigned int tap = 0 ) const;
|
||||
|
||||
//! Input one sample to the delayline and return outputs at all tap positions.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The output
|
||||
values are ordered according to the tap positions set using the
|
||||
setTapDelays() function (no sorting is performed). The StkFrames
|
||||
argument must contain at least as many channels as the number of
|
||||
taps. However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFloat input, StkFrames& outputs );
|
||||
|
||||
//! Take a channel of the StkFrames object as inputs to the filter and write outputs back to the same object.
|
||||
/*!
|
||||
The StkFrames argument reference is returned. The output
|
||||
values are ordered according to the tap positions set using the
|
||||
setTapDelays() function (no sorting is performed). The StkFrames
|
||||
argument must contain at least as many channels as the number of
|
||||
taps. However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. The output values
|
||||
are ordered according to the tap positions set using the
|
||||
setTapDelays() function (no sorting is performed). The \c
|
||||
iChannel argument must be less than the number of channels in
|
||||
the \c iFrames argument (the first channel is specified by 0).
|
||||
The \c oFrames argument must contain at least as many channels as
|
||||
the number of taps. However, range checking is only performed if
|
||||
_STK_DEBUG_ is defined during compilation, in which case an
|
||||
out-of-range value will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
unsigned long inPoint_;
|
||||
std::vector<unsigned long> outPoint_;
|
||||
std::vector<unsigned long> delays_;
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat TapDelay :: lastOut( unsigned int tap ) const
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( tap >= lastFrame_.size() ) ) {
|
||||
errorString_ << "TapDelay::lastOut(): tap argument and number of taps are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
return lastFrame_[tap];
|
||||
}
|
||||
|
||||
inline StkFrames& TapDelay :: tick( StkFloat input, StkFrames& outputs )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( outputs.channels() < outPoint_.size() ) {
|
||||
errorString_ << "TapDelay::tick(): number of taps > channels in StkFrames argument!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
inputs_[inPoint_++] = input * gain_;
|
||||
|
||||
// Check for end condition
|
||||
if ( inPoint_ == inputs_.size() )
|
||||
inPoint_ = 0;
|
||||
|
||||
// Read out next values
|
||||
StkFloat *outs = &outputs[0];
|
||||
for ( unsigned int i=0; i<outPoint_.size(); i++ ) {
|
||||
*outs++ = inputs_[outPoint_[i]];
|
||||
lastFrame_[i] = *outs;
|
||||
if ( ++outPoint_[i] == inputs_.size() )
|
||||
outPoint_[i] = 0;
|
||||
}
|
||||
|
||||
return outputs;
|
||||
}
|
||||
|
||||
inline StkFrames& TapDelay :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "TapDelay::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
if ( frames.channels() < outPoint_.size() ) {
|
||||
errorString_ << "TapDelay::tick(): number of taps > channels in StkFrames argument!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &frames[channel];
|
||||
StkFloat *oSamples = &frames[0];
|
||||
unsigned int j, iHop = frames.channels(), oHop = frames.channels() - outPoint_.size();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
inputs_[inPoint_++] = *iSamples * gain_;
|
||||
if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
|
||||
for ( j=0; j<outPoint_.size(); j++ ) {
|
||||
*oSamples++ = inputs_[outPoint_[j]];
|
||||
if ( ++outPoint_[j] == inputs_.size() ) outPoint_[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
oSamples -= frames.channels();
|
||||
for ( j=0; j<outPoint_.size(); j++ ) lastFrame_[j] = *oSamples++;
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& TapDelay :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() ) {
|
||||
errorString_ << "TapDelay::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
if ( oFrames.channels() < outPoint_.size() ) {
|
||||
errorString_ << "TapDelay::tick(): number of taps > channels in output StkFrames argument!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[0];
|
||||
unsigned int j, iHop = iFrames.channels(), oHop = oFrames.channels() - outPoint_.size();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
inputs_[inPoint_++] = *iSamples * gain_;
|
||||
if ( inPoint_ == inputs_.size() ) inPoint_ = 0;
|
||||
for ( j=0; j<outPoint_.size(); j++ ) {
|
||||
*oSamples++ = inputs_[outPoint_[j]];
|
||||
if ( ++outPoint_[j] == inputs_.size() ) outPoint_[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
oSamples -= oFrames.channels();
|
||||
for ( j=0; j<outPoint_.size(); j++ ) lastFrame_[j] = *oSamples++;
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // stk namespace
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_TCPCLIENT_H
|
||||
#define STK_TCPCLIENT_H
|
||||
|
||||
#include "Socket.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class TcpClient
|
||||
\brief STK TCP socket client class.
|
||||
@@ -19,15 +26,10 @@
|
||||
less than or equal to zero indicate a closed
|
||||
or lost connection or the occurence of an error.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_TCPCLIENT_H
|
||||
#define STK_TCPCLIENT_H
|
||||
|
||||
#include "Socket.h"
|
||||
|
||||
class TcpClient : public Socket
|
||||
{
|
||||
public:
|
||||
@@ -58,4 +60,6 @@ class TcpClient : public Socket
|
||||
|
||||
};
|
||||
|
||||
#endif // defined(STK_TCPCLIENT_H)
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_TCPSERVER_H
|
||||
#define STK_TCPSERVER_H
|
||||
|
||||
#include "Socket.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class TcpServer
|
||||
\brief STK TCP socket server class.
|
||||
@@ -19,15 +26,10 @@
|
||||
less than or equal to zero indicate a closed
|
||||
or lost connection or the occurence of an error.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_TCPSERVER_H
|
||||
#define STK_TCPSERVER_H
|
||||
|
||||
#include "Socket.h"
|
||||
|
||||
class TcpServer : public Socket
|
||||
{
|
||||
public:
|
||||
@@ -58,4 +60,6 @@ class TcpServer : public Socket
|
||||
|
||||
};
|
||||
|
||||
#endif // defined(STK_TCPSERVER_H)
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,25 +1,3 @@
|
||||
/***************************************************/
|
||||
/*! \class Thread
|
||||
\brief STK thread class.
|
||||
|
||||
This class provides a uniform interface for cross-platform
|
||||
threads. On unix systems, the pthread library is used. Under
|
||||
Windows, the C runtime threadex functions are used.
|
||||
|
||||
Each instance of the Thread class can be used to control a single
|
||||
thread process. Routines are provided to signal cancelation
|
||||
and/or joining with a thread, though it is not possible for this
|
||||
class to know the running status of a thread once it is started.
|
||||
|
||||
For cross-platform compatability, thread functions should be
|
||||
declared as follows:
|
||||
|
||||
THREAD_RETURN THREAD_TYPE thread_function(void *ptr)
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_THREAD_H
|
||||
#define STK_THREAD_H
|
||||
|
||||
@@ -44,6 +22,30 @@
|
||||
|
||||
#endif
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Thread
|
||||
\brief STK thread class.
|
||||
|
||||
This class provides a uniform interface for cross-platform
|
||||
threads. On unix systems, the pthread library is used. Under
|
||||
Windows, the C runtime threadex functions are used.
|
||||
|
||||
Each instance of the Thread class can be used to control a single
|
||||
thread process. Routines are provided to signal cancelation
|
||||
and/or joining with a thread, though it is not possible for this
|
||||
class to know the running status of a thread once it is started.
|
||||
|
||||
For cross-platform compatability, thread functions should be
|
||||
declared as follows:
|
||||
|
||||
THREAD_RETURN THREAD_TYPE thread_function(void *ptr)
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Thread : public Stk
|
||||
{
|
||||
public:
|
||||
@@ -91,4 +93,6 @@ class Thread : public Stk
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_TUBEBELL_H
|
||||
#define STK_TUBEBELL_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class TubeBell
|
||||
\brief STK tubular bell (orchestral chime) FM
|
||||
@@ -26,15 +33,10 @@
|
||||
type who should worry about this (making
|
||||
money) worry away.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_TUBEBELL_H
|
||||
#define STK_TUBEBELL_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
class TubeBell : public FM
|
||||
{
|
||||
public:
|
||||
@@ -42,17 +44,45 @@ class TubeBell : public FM
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
TubeBell();
|
||||
TubeBell( void );
|
||||
|
||||
//! Class destructor.
|
||||
~TubeBell();
|
||||
~TubeBell( void );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
};
|
||||
|
||||
inline StkFloat TubeBell :: tick( unsigned int )
|
||||
{
|
||||
StkFloat temp, temp2;
|
||||
|
||||
temp = gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
|
||||
temp = temp * control1_;
|
||||
|
||||
waves_[0]->addPhaseOffset( temp );
|
||||
waves_[3]->addPhaseOffset( twozero_.lastOut() );
|
||||
temp = gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
|
||||
twozero_.tick( temp );
|
||||
|
||||
waves_[2]->addPhaseOffset( temp );
|
||||
temp = ( 1.0 - (control2_ * 0.5)) * gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
|
||||
temp += control2_ * 0.5 * gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
|
||||
|
||||
// Calculate amplitude modulation and apply it to output.
|
||||
temp2 = vibrato_.tick() * modDepth_;
|
||||
temp = temp * (1.0 + temp2);
|
||||
|
||||
lastFrame_[0] = temp * 0.5;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
/***************************************************/
|
||||
/*! \class TwoPole
|
||||
\brief STK two-pole filter class.
|
||||
|
||||
This protected Filter subclass implements
|
||||
a two-pole digital filter. A method is
|
||||
provided for creating a resonance in the
|
||||
frequency response while maintaining a nearly
|
||||
constant filter gain.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_TWOPOLE_H
|
||||
#define STK_TWOPOLE_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
class TwoPole : protected Filter
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class TwoPole
|
||||
\brief STK two-pole filter class.
|
||||
|
||||
This class implements a two-pole digital filter. A method is
|
||||
provided for creating a resonance in the frequency response while
|
||||
maintaining a nearly constant filter gain.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class TwoPole : public Filter
|
||||
{
|
||||
public:
|
||||
|
||||
//! Default constructor creates a second-order pass-through filter.
|
||||
TwoPole();
|
||||
TwoPole( void );
|
||||
|
||||
//! Class destructor.
|
||||
~TwoPole();
|
||||
@@ -30,17 +30,17 @@ class TwoPole : protected Filter
|
||||
//! A function to enable/disable the automatic updating of class data when the STK sample rate changes.
|
||||
void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; };
|
||||
|
||||
//! Clears the internal states of the filter.
|
||||
void clear(void);
|
||||
|
||||
//! Set the b[0] coefficient value.
|
||||
void setB0(StkFloat b0);
|
||||
void setB0( StkFloat b0 ) { b_[0] = b0; };
|
||||
|
||||
//! Set the a[1] coefficient value.
|
||||
void setA1(StkFloat a1);
|
||||
void setA1( StkFloat a1 ) { a_[1] = a1; };
|
||||
|
||||
//! Set the a[2] coefficient value.
|
||||
void setA2(StkFloat a2);
|
||||
void setA2( StkFloat a2 ) { a_[2] = a2; };
|
||||
|
||||
//! Set all filter coefficients.
|
||||
void setCoefficients( StkFloat b0, StkFloat a1, StkFloat a2, bool clearState = false );
|
||||
|
||||
//! Sets the filter coefficients for a resonance at \e frequency (in Hz).
|
||||
/*!
|
||||
@@ -58,34 +58,94 @@ class TwoPole : protected Filter
|
||||
*/
|
||||
void setResonance(StkFloat frequency, StkFloat radius, bool normalize = 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.
|
||||
*/
|
||||
void setGain(StkFloat gain);
|
||||
|
||||
//! Return the current filter gain.
|
||||
StkFloat getGain(void) const;
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut(void) const;
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Input one sample to the filter and return one output.
|
||||
StkFloat tick(StkFloat sample);
|
||||
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.
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
};
|
||||
|
||||
inline StkFloat TwoPole :: tick( StkFloat input )
|
||||
{
|
||||
inputs_[0] = gain_ * input;
|
||||
lastFrame_[0] = b_[0] * inputs_[0] - a_[1] * outputs_[1] - a_[2] * outputs_[2];
|
||||
outputs_[2] = outputs_[1];
|
||||
outputs_[1] = lastFrame_[0];
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& TwoPole :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "TwoPole::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
inputs_[0] = gain_ * *samples;
|
||||
*samples = b_[0] * inputs_[0] - a_[1] * outputs_[1] - a_[2] * outputs_[2];
|
||||
outputs_[2] = outputs_[1];
|
||||
outputs_[1] = *samples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = outputs_[1];
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& TwoPole :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "TwoPole::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
inputs_[0] = gain_ * *iSamples;
|
||||
*oSamples = b_[0] * inputs_[0] - a_[1] * outputs_[1] - a_[2] * outputs_[2];
|
||||
outputs_[2] = outputs_[1];
|
||||
outputs_[1] = *oSamples;
|
||||
}
|
||||
|
||||
lastFrame_[0] = outputs_[1];
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
/***************************************************/
|
||||
/*! \class TwoZero
|
||||
\brief STK two-zero filter class.
|
||||
|
||||
This protected Filter subclass implements
|
||||
a two-zero digital filter. A method is
|
||||
provided for creating a "notch" in the
|
||||
frequency response while maintaining a
|
||||
constant filter gain.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_TWOZERO_H
|
||||
#define STK_TWOZERO_H
|
||||
|
||||
#include "Filter.h"
|
||||
|
||||
class TwoZero : protected Filter
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class TwoZero
|
||||
\brief STK two-zero filter class.
|
||||
|
||||
This class implements a two-zero digital filter. A method is
|
||||
provided for creating a "notch" in the frequency response while
|
||||
maintaining a constant filter gain.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class TwoZero : public Filter
|
||||
{
|
||||
public:
|
||||
//! Default constructor creates a second-order pass-through filter.
|
||||
@@ -29,17 +29,17 @@ class TwoZero : protected Filter
|
||||
//! A function to enable/disable the automatic updating of class data when the STK sample rate changes.
|
||||
void ignoreSampleRateChange( bool ignore = true ) { ignoreSampleRateChange_ = ignore; };
|
||||
|
||||
//! Clears the internal states of the filter.
|
||||
void clear(void);
|
||||
|
||||
//! Set the b[0] coefficient value.
|
||||
void setB0(StkFloat b0);
|
||||
void setB0( StkFloat b0 ) { b_[0] = b0; };
|
||||
|
||||
//! Set the b[1] coefficient value.
|
||||
void setB1(StkFloat b1);
|
||||
void setB1( StkFloat b1 ) { b_[1] = b1; };
|
||||
|
||||
//! Set the b[2] coefficient value.
|
||||
void setB2(StkFloat b2);
|
||||
void setB2( StkFloat b2 ) { b_[2] = b2; };
|
||||
|
||||
//! Set all filter coefficients.
|
||||
void setCoefficients( StkFloat b0, StkFloat b1, StkFloat b2, bool clearState = false );
|
||||
|
||||
//! Sets the filter coefficients for a "notch" at \e frequency (in Hz).
|
||||
/*!
|
||||
@@ -52,36 +52,96 @@ class TwoZero : protected Filter
|
||||
frequency. The closer the zeros are to the unit-circle (\e radius
|
||||
close to or equal to one), the narrower the resulting notch width.
|
||||
*/
|
||||
void setNotch(StkFloat frequency, StkFloat radius);
|
||||
|
||||
//! 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;
|
||||
void setNotch( StkFloat frequency, StkFloat radius );
|
||||
|
||||
//! Return the last computed output value.
|
||||
StkFloat lastOut(void) const;
|
||||
StkFloat lastOut( void ) const { return lastFrame_[0]; };
|
||||
|
||||
//! Input one sample to the filter and return one output.
|
||||
StkFloat tick(StkFloat sample);
|
||||
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.
|
||||
The StkFrames argument reference is returned. The \c channel
|
||||
argument must be less than the number of channels in the
|
||||
StkFrames argument (the first channel is specified by 0).
|
||||
However, range checking is only performed if _STK_DEBUG_ is
|
||||
defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Take a channel of the \c iFrames object as inputs to the filter and write outputs to the \c oFrames object.
|
||||
/*!
|
||||
The \c iFrames object reference is returned. Each channel
|
||||
argument must be less than the number of channels in the
|
||||
corresponding StkFrames argument (the first channel is specified
|
||||
by 0). However, range checking is only performed if _STK_DEBUG_
|
||||
is defined during compilation, in which case an out-of-range value
|
||||
will trigger an StkError exception.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
};
|
||||
|
||||
inline StkFloat TwoZero :: tick( StkFloat input )
|
||||
{
|
||||
inputs_[0] = gain_ * input;
|
||||
lastFrame_[0] = b_[2] * inputs_[2] + b_[1] * inputs_[1] + b_[0] * inputs_[0];
|
||||
inputs_[2] = inputs_[1];
|
||||
inputs_[1] = inputs_[0];
|
||||
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
inline StkFrames& TwoZero :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "TwoZero::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
inputs_[0] = gain_ * *samples;
|
||||
*samples = b_[2] * inputs_[2] + b_[1] * inputs_[1] + b_[0] * inputs_[0];
|
||||
inputs_[2] = inputs_[1];
|
||||
inputs_[1] = inputs_[0];
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(samples-hop);
|
||||
return frames;
|
||||
}
|
||||
|
||||
inline StkFrames& TwoZero :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "TwoZero::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *iSamples = &iFrames[iChannel];
|
||||
StkFloat *oSamples = &oFrames[oChannel];
|
||||
unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
|
||||
for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
|
||||
inputs_[0] = gain_ * *iSamples;
|
||||
*oSamples = b_[2] * inputs_[2] + b_[1] * inputs_[1] + b_[0] * inputs_[0];
|
||||
inputs_[2] = inputs_[1];
|
||||
inputs_[1] = inputs_[0];
|
||||
}
|
||||
|
||||
lastFrame_[0] = *(oSamples-oHop);
|
||||
return iFrames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_UDPSOCKET_H
|
||||
#define STK_UDPSOCKET_H
|
||||
|
||||
#include "Socket.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class UdpSocket
|
||||
\brief STK UDP socket server/client class.
|
||||
@@ -17,15 +24,10 @@
|
||||
read/write methods. Values less than or equal to zero indicate
|
||||
the occurence of an error.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_UDPSOCKET_H
|
||||
#define STK_UDPSOCKET_H
|
||||
|
||||
#include "Socket.h"
|
||||
|
||||
class UdpSocket : public Socket
|
||||
{
|
||||
public:
|
||||
@@ -69,4 +71,6 @@ class UdpSocket : public Socket
|
||||
|
||||
};
|
||||
|
||||
#endif // defined(STK_UDPSOCKET_H)
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,56 +1,68 @@
|
||||
#ifndef STK_VECTOR3D_H
|
||||
#define STK_VECTOR3D_H
|
||||
|
||||
#include "Stk.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Vector3D
|
||||
\brief STK 3D vector class.
|
||||
|
||||
This class implements a three-dimensional vector.
|
||||
|
||||
by Perry R. Cook, 1995 - 2004.
|
||||
by Perry R. Cook, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_VECTOR3D_H
|
||||
#define STK_VECTOR3D_H
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
class Vector3D : public Stk
|
||||
{
|
||||
|
||||
public:
|
||||
//! Default constructor taking optional initial X, Y, and Z values.
|
||||
Vector3D(StkFloat initX=0.0, StkFloat initY=0.0, StkFloat initZ=0.0);
|
||||
|
||||
//! Class destructor.
|
||||
~Vector3D();
|
||||
Vector3D( StkFloat x = 0.0, StkFloat y = 0.0, StkFloat z = 0.0 ) { setXYZ( x, y, z ); };
|
||||
|
||||
//! Get the current X value.
|
||||
StkFloat getX();
|
||||
StkFloat getX( void ) { return X_; };
|
||||
|
||||
//! Get the current Y value.
|
||||
StkFloat getY();
|
||||
StkFloat getY( void ) { return Y_; };
|
||||
|
||||
//! Get the current Z value.
|
||||
StkFloat getZ();
|
||||
StkFloat getZ( void ) { return Z_; };
|
||||
|
||||
//! Calculate the vector length.
|
||||
StkFloat getLength();
|
||||
StkFloat getLength( void );
|
||||
|
||||
//! Set the X, Y, and Z values simultaniously.
|
||||
void setXYZ(StkFloat x, StkFloat y, StkFloat z);
|
||||
void setXYZ( StkFloat x, StkFloat y, StkFloat z ) { X_ = x; Y_ = y; Z_ = z; };
|
||||
|
||||
//! Set the X value.
|
||||
void setX(StkFloat x);
|
||||
void setX( StkFloat x ) { X_ = x; };
|
||||
|
||||
//! Set the Y value.
|
||||
void setY(StkFloat y);
|
||||
void setY( StkFloat y ) { Y_ = y; };
|
||||
|
||||
//! Set the Z value.
|
||||
void setZ(StkFloat z);
|
||||
void setZ( StkFloat z ) { Z_ = z; };
|
||||
|
||||
protected:
|
||||
StkFloat myX_;
|
||||
StkFloat myY_;
|
||||
StkFloat myZ_;
|
||||
StkFloat X_;
|
||||
StkFloat Y_;
|
||||
StkFloat Z_;
|
||||
};
|
||||
|
||||
inline StkFloat Vector3D :: getLength( void )
|
||||
{
|
||||
StkFloat temp;
|
||||
temp = X_ * X_;
|
||||
temp += Y_ * Y_;
|
||||
temp += Z_ * Z_;
|
||||
temp = sqrt( temp );
|
||||
return temp;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
#ifndef STK_VOICFORM_H
|
||||
#define STK_VOICFORM_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "Envelope.h"
|
||||
#include "Noise.h"
|
||||
#include "SingWave.h"
|
||||
#include "FormSwep.h"
|
||||
#include "OnePole.h"
|
||||
#include "OneZero.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class VoicForm
|
||||
\brief Four formant synthesis instrument.
|
||||
@@ -21,21 +34,10 @@
|
||||
- Vibrato Gain = 1
|
||||
- Loudness (Spectral Tilt) = 128
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_VOICFORM_H
|
||||
#define STK_VOICFORM_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "Envelope.h"
|
||||
#include "Noise.h"
|
||||
#include "SingWave.h"
|
||||
#include "FormSwep.h"
|
||||
#include "OnePole.h"
|
||||
#include "OneZero.h"
|
||||
|
||||
class VoicForm : public Instrmnt
|
||||
{
|
||||
public:
|
||||
@@ -43,51 +45,52 @@ class VoicForm : public Instrmnt
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
VoicForm();
|
||||
VoicForm( void );
|
||||
|
||||
//! Class destructor.
|
||||
~VoicForm();
|
||||
~VoicForm( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Set instrument parameters for the given phoneme. Returns false if phoneme not found.
|
||||
bool setPhoneme(const char* phoneme);
|
||||
bool setPhoneme( const char* phoneme );
|
||||
|
||||
//! Set the voiced component gain.
|
||||
void setVoiced(StkFloat vGain);
|
||||
void setVoiced( StkFloat vGain ) { voiced_->setGainTarget(vGain); };
|
||||
|
||||
//! Set the unvoiced component gain.
|
||||
void setUnVoiced(StkFloat nGain);
|
||||
void setUnVoiced( StkFloat nGain ) { noiseEnv_.setTarget(nGain); };
|
||||
|
||||
//! Set the sweep rate for a particular formant filter (0-3).
|
||||
void setFilterSweepRate(unsigned int whichOne, StkFloat rate);
|
||||
void setFilterSweepRate( unsigned int whichOne, StkFloat rate );
|
||||
|
||||
//! Set voiced component pitch sweep rate.
|
||||
void setPitchSweepRate(StkFloat rate);
|
||||
void setPitchSweepRate( StkFloat rate ) { voiced_->setSweepRate(rate); };
|
||||
|
||||
//! Start the voice.
|
||||
void speak();
|
||||
void speak( void ) { voiced_->noteOn(); };
|
||||
|
||||
//! Stop the voice.
|
||||
void quiet();
|
||||
void quiet( void );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
void noteOff( StkFloat amplitude ) { this->quiet(); };
|
||||
|
||||
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
|
||||
void controlChange(int number, StkFloat value);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
SingWave *voiced_;
|
||||
Noise noise_;
|
||||
Envelope noiseEnv_;
|
||||
@@ -97,4 +100,25 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
inline StkFloat VoicForm :: tick( unsigned int )
|
||||
{
|
||||
StkFloat temp;
|
||||
temp = onepole_.tick( onezero_.tick( voiced_->tick() ) );
|
||||
temp += noiseEnv_.tick() * noise_.tick();
|
||||
lastFrame_[0] = filters_[0].tick(temp);
|
||||
lastFrame_[0] += filters_[1].tick(temp);
|
||||
lastFrame_[0] += filters_[2].tick(temp);
|
||||
lastFrame_[0] += filters_[3].tick(temp);
|
||||
/*
|
||||
temp += noiseEnv_.tick() * noise_.tick();
|
||||
lastFrame_[0] = filters_[0].tick(temp);
|
||||
lastFrame_[0] = filters_[1].tick(lastFrame_[0]);
|
||||
lastFrame_[0] = filters_[2].tick(lastFrame_[0]);
|
||||
lastFrame_[0] = filters_[3].tick(lastFrame_[0]);
|
||||
*/
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
218
include/Voicer.h
218
include/Voicer.h
@@ -1,80 +1,73 @@
|
||||
/***************************************************/
|
||||
/*! \class Voicer
|
||||
\brief STK voice manager class.
|
||||
|
||||
This class can be used to manage a group of
|
||||
STK instrument classes. Individual voices can
|
||||
be controlled via unique note tags.
|
||||
Instrument groups can be controlled by channel
|
||||
number.
|
||||
|
||||
A previously constructed STK instrument class
|
||||
is linked with a voice manager using the
|
||||
addInstrument() function. An optional channel
|
||||
number argument can be specified to the
|
||||
addInstrument() function as well (default
|
||||
channel = 0). The voice manager does not
|
||||
delete any instrument instances ... it is the
|
||||
responsibility of the user to allocate and
|
||||
deallocate all instruments.
|
||||
|
||||
The tick() function returns the mix of all
|
||||
sounding voices. Each noteOn returns a unique
|
||||
tag (credits to the NeXT MusicKit), so you can
|
||||
send control changes to specific voices within
|
||||
an ensemble. Alternately, control changes can
|
||||
be sent to all voices on a given channel.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_VOICER_H
|
||||
#define STK_VOICER_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include <vector>
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Voicer
|
||||
\brief STK voice manager class.
|
||||
|
||||
This class can be used to manage a group of STK instrument
|
||||
classes. Individual voices can be controlled via unique note
|
||||
tags. Instrument groups can be controlled by group number.
|
||||
|
||||
A previously constructed STK instrument class is linked with a
|
||||
voice manager using the addInstrument() function. An optional
|
||||
group number argument can be specified to the addInstrument()
|
||||
function as well (default group = 0). The voice manager does not
|
||||
delete any instrument instances ... it is the responsibility of
|
||||
the user to allocate and deallocate all instruments.
|
||||
|
||||
The tick() function returns the mix of all sounding voices. Each
|
||||
noteOn returns a unique tag (credits to the NeXT MusicKit), so you
|
||||
can send control changes to specific voices within an ensemble.
|
||||
Alternately, control changes can be sent to all voices in a given
|
||||
group.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
class Voicer : public Stk
|
||||
{
|
||||
public:
|
||||
public:
|
||||
//! Class constructor taking an optional note decay time (in seconds).
|
||||
Voicer( StkFloat decayTime=0.2 );
|
||||
Voicer( StkFloat decayTime = 0.2 );
|
||||
|
||||
//! Class destructor.
|
||||
~Voicer();
|
||||
|
||||
//! Add an instrument with an optional channel number to the voice manager.
|
||||
//! Add an instrument with an optional group number to the voice manager.
|
||||
/*!
|
||||
A set of instruments can be grouped by channel number and
|
||||
controlled via the functions which take a channel number argument.
|
||||
A set of instruments can be grouped by group number and
|
||||
controlled via the functions that take a group number argument.
|
||||
*/
|
||||
void addInstrument( Instrmnt *instrument, int channel=0 );
|
||||
void addInstrument( Instrmnt *instrument, int group=0 );
|
||||
|
||||
//! Remove the given instrument pointer from the voice manager's control.
|
||||
/*!
|
||||
It is important that any instruments which are to be deleted by
|
||||
the user while the voice manager is running be first removed from
|
||||
the manager's control via this function!!
|
||||
*/
|
||||
*/
|
||||
void removeInstrument( Instrmnt *instrument );
|
||||
|
||||
//! Initiate a noteOn event with the given note number and amplitude and return a unique note tag.
|
||||
/*!
|
||||
Send the noteOn message to the first available unused voice.
|
||||
If all voices are sounding, the oldest voice is interrupted and
|
||||
sent the noteOn message. If the optional channel argument is
|
||||
non-zero, only voices on that channel are used. If no voices are
|
||||
found for a specified non-zero channel value, the function returns
|
||||
sent the noteOn message. If the optional group argument is
|
||||
non-zero, only voices in that group are used. If no voices are
|
||||
found for a specified non-zero group value, the function returns
|
||||
-1. The amplitude value should be in the range 0.0 - 128.0.
|
||||
*/
|
||||
long noteOn( StkFloat noteNumber, StkFloat amplitude, int channel=0 );
|
||||
long noteOn( StkFloat noteNumber, StkFloat amplitude, int group=0 );
|
||||
|
||||
//! Send a noteOff to all voices having the given noteNumber and optional channel (default channel = 0).
|
||||
//! Send a noteOff to all voices having the given noteNumber and optional group (default group = 0).
|
||||
/*!
|
||||
The amplitude value should be in the range 0.0 - 128.0.
|
||||
*/
|
||||
void noteOff( StkFloat noteNumber, StkFloat amplitude, int channel=0 );
|
||||
void noteOff( StkFloat noteNumber, StkFloat amplitude, int group=0 );
|
||||
|
||||
//! Send a noteOff to the voice with the given note tag.
|
||||
/*!
|
||||
@@ -82,26 +75,26 @@ public:
|
||||
*/
|
||||
void noteOff( long tag, StkFloat amplitude );
|
||||
|
||||
//! Send a frequency update message to all voices assigned to the optional channel argument (default channel = 0).
|
||||
//! Send a frequency update message to all voices assigned to the optional group argument (default group = 0).
|
||||
/*!
|
||||
The \e noteNumber argument corresponds to a MIDI note number, though it is a floating-point value and can range beyond the normal 0-127 range.
|
||||
*/
|
||||
void setFrequency( StkFloat noteNumber, int channel=0 );
|
||||
*/
|
||||
void setFrequency( StkFloat noteNumber, int group=0 );
|
||||
|
||||
//! Send a frequency update message to the voice with the given note tag.
|
||||
/*!
|
||||
The \e noteNumber argument corresponds to a MIDI note number, though it is a floating-point value and can range beyond the normal 0-127 range.
|
||||
*/
|
||||
*/
|
||||
void setFrequency( long tag, StkFloat noteNumber );
|
||||
|
||||
//! Send a pitchBend message to all voices assigned to the optional channel argument (default channel = 0).
|
||||
void pitchBend( StkFloat value, int channel=0 );
|
||||
//! Send a pitchBend message to all voices assigned to the optional group argument (default group = 0).
|
||||
void pitchBend( StkFloat value, int group=0 );
|
||||
|
||||
//! Send a pitchBend message to the voice with the given note tag.
|
||||
void pitchBend( long tag, StkFloat value );
|
||||
|
||||
//! Send a controlChange to all instruments assigned to the optional channel argument (default channel = 0).
|
||||
void controlChange( int number, StkFloat value, int channel=0 );
|
||||
//! Send a controlChange to all instruments assigned to the optional group argument (default group = 0).
|
||||
void controlChange( int number, StkFloat value, int group=0 );
|
||||
|
||||
//! Send a controlChange to the voice with the given note tag.
|
||||
void controlChange( long tag, int number, StkFloat value );
|
||||
@@ -109,31 +102,46 @@ public:
|
||||
//! Send a noteOff message to all existing voices.
|
||||
void silence( void );
|
||||
|
||||
//! Mix the output for all sounding voices.
|
||||
StkFloat tick();
|
||||
//! Return the current number of output channels.
|
||||
unsigned int channelsOut( void ) const { return lastFrame_.channels(); };
|
||||
|
||||
//! Compute \e vectorSize output mixes and return them in \e vector.
|
||||
StkFloat *tick(StkFloat *vector, unsigned int vectorSize);
|
||||
//! Return an StkFrames reference to the last output sample frame.
|
||||
const StkFrames& lastFrame( void ) const { return lastFrame_; };
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
//! Return the specified channel value of the last computed frame.
|
||||
/*!
|
||||
The \c channel argument should be one or greater (the first
|
||||
channel is specified by 1). An StkError will be thrown if the \c
|
||||
channel argument is zero or it is greater than the number of
|
||||
channels in the StkFrames object.
|
||||
The \c channel argument must be less than the number of output
|
||||
channels, which can be determined with the channelsOut() function
|
||||
(the first channel is specified by 0). However, range checking is
|
||||
only performed if _STK_DEBUG_ is defined during compilation, in
|
||||
which case an out-of-range value will trigger an StkError
|
||||
exception. \sa lastFrame()
|
||||
*/
|
||||
virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 1 );
|
||||
StkFloat lastOut( unsigned int channel = 0 );
|
||||
|
||||
//! Return the last output value.
|
||||
StkFloat lastOut() const;
|
||||
//! Mix one sample frame of all sounding voices and return the specified \c channel value.
|
||||
/*!
|
||||
The \c channel argument must be less than the number of output
|
||||
channels, which can be determined with the channelsOut() function
|
||||
(the first channel is specified by 0). However, range checking is
|
||||
only performed if _STK_DEBUG_ is defined during compilation, in
|
||||
which case an out-of-range value will trigger an StkError
|
||||
exception.
|
||||
*/
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
//! Return the last left output value.
|
||||
StkFloat lastOutLeft() const;
|
||||
//! Fill the StkFrames argument with computed frames and return the same reference.
|
||||
/*!
|
||||
The number of channels in the StkFrames argument must equal
|
||||
the number of channels in the file data. However, this is only
|
||||
checked if _STK_DEBUG_ is defined during compilation, in which
|
||||
case an incompatibility will trigger an StkError exception. If no
|
||||
file data is loaded, the function does nothing (a warning will be
|
||||
issued if _STK_DEBUG_ is defined during compilation).
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
|
||||
|
||||
//! Return the last right output value.
|
||||
StkFloat lastOutRight() const;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
|
||||
struct Voice {
|
||||
Instrmnt *instrument;
|
||||
@@ -141,20 +149,72 @@ protected:
|
||||
StkFloat noteNumber;
|
||||
StkFloat frequency;
|
||||
int sounding;
|
||||
int channel;
|
||||
int group;
|
||||
|
||||
// Default constructor.
|
||||
Voice()
|
||||
:instrument(0), tag(0), noteNumber(-1.0), frequency(0.0),
|
||||
sounding(0), channel(0) {}
|
||||
:instrument(0), tag(0), noteNumber(-1.0), frequency(0.0), sounding(0), group(0) {}
|
||||
};
|
||||
|
||||
std::vector<Voice> voices_;
|
||||
long tags_;
|
||||
int muteTime_;
|
||||
StkFloat lastOutput_;
|
||||
StkFloat lastOutputLeft_;
|
||||
StkFloat lastOutputRight_;
|
||||
StkFrames lastFrame_;
|
||||
};
|
||||
|
||||
inline StkFloat Voicer :: lastOut( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= lastFrame_.channels() ) {
|
||||
errorString_ << "Voicer::lastOut(): channel argument is invalid!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
|
||||
inline StkFloat Voicer :: tick( unsigned int channel )
|
||||
{
|
||||
unsigned int j;
|
||||
for ( j=0; j<lastFrame_.channels(); j++ ) lastFrame_[j] = 0.0;
|
||||
for ( unsigned int i=0; i<voices_.size(); i++ ) {
|
||||
if ( voices_[i].sounding != 0 ) {
|
||||
voices_[i].instrument->tick();
|
||||
for ( j=0; j<voices_[i].instrument->channelsOut(); j++ ) lastFrame_[j] += voices_[i].instrument->lastOut( j );
|
||||
}
|
||||
if ( voices_[i].sounding < 0 ) {
|
||||
voices_[i].sounding++;
|
||||
if ( voices_[i].sounding == 0 )
|
||||
voices_[i].noteNumber = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return lastFrame_[channel];
|
||||
}
|
||||
|
||||
inline StkFrames& Voicer :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel > frames.channels() - nChannels ) {
|
||||
errorString_ << "Voicer::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat *samples = &frames[channel];
|
||||
unsigned int j, hop = frames.channels() - nChannels;
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
tick();
|
||||
for ( j=0; j<nChannels; j++ )
|
||||
*samples++ = lastFrame_[j];
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/***************************************************/
|
||||
/*! \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 - 2007.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_WAVELOOP_H
|
||||
#define STK_WAVELOOP_H
|
||||
|
||||
#include "FileWvIn.h"
|
||||
|
||||
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 );
|
||||
virtual void sampleRateChanged( StkFloat newRate, StkFloat oldRate );
|
||||
|
||||
StkFrames firstFrame_;
|
||||
StkFloat phaseOffset_;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,3 +1,16 @@
|
||||
#ifndef STK_WHISTLE_H
|
||||
#define STK_WHISTLE_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "Sphere.h"
|
||||
#include "Vector3D.h"
|
||||
#include "Noise.h"
|
||||
#include "SineWave.h"
|
||||
#include "OnePole.h"
|
||||
#include "Envelope.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Whistle
|
||||
\brief STK police/referee whistle instrument class.
|
||||
@@ -12,21 +25,10 @@
|
||||
- Blowing Frequency Modulation = 2
|
||||
- Volume = 128
|
||||
|
||||
by Perry R. Cook 1996 - 2004.
|
||||
by Perry R. Cook 1996 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_WHISTLE_H
|
||||
#define STK_WHISTLE_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "Sphere.h"
|
||||
#include "Vector3D.h"
|
||||
#include "Noise.h"
|
||||
#include "SineWave.h"
|
||||
#include "OnePole.h"
|
||||
#include "Envelope.h"
|
||||
|
||||
class Whistle : public Instrmnt
|
||||
{
|
||||
public:
|
||||
@@ -34,36 +36,37 @@ public:
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
Whistle();
|
||||
Whistle( void );
|
||||
|
||||
//! Class destructor.
|
||||
~Whistle();
|
||||
~Whistle( void );
|
||||
|
||||
//! Reset and clear all internal state.
|
||||
void clear();
|
||||
void clear( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Apply breath velocity to instrument with given amplitude and rate of increase.
|
||||
void startBlowing(StkFloat amplitude, StkFloat rate);
|
||||
void startBlowing( StkFloat amplitude, StkFloat rate );
|
||||
|
||||
//! Decrease breath velocity with given rate of decrease.
|
||||
void stopBlowing(StkFloat rate);
|
||||
void stopBlowing( StkFloat rate );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
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);
|
||||
void controlChange( int number, StkFloat value );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
|
||||
Vector3D *tempVectorP_;
|
||||
Vector3D tempVector_;
|
||||
OnePole onepole_;
|
||||
@@ -84,4 +87,5 @@ protected:
|
||||
int subSample_, subSampCount_;
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_WURLEY_H
|
||||
#define STK_WURLEY_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class Wurley
|
||||
\brief STK Wurlitzer electric piano FM
|
||||
@@ -26,15 +33,10 @@
|
||||
type who should worry about this (making
|
||||
money) worry away.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_WURLEY_H
|
||||
#define STK_WURLEY_H
|
||||
|
||||
#include "FM.h"
|
||||
|
||||
class Wurley : public FM
|
||||
{
|
||||
public:
|
||||
@@ -42,20 +44,48 @@ class Wurley : public FM
|
||||
/*!
|
||||
An StkError will be thrown if the rawwave path is incorrectly set.
|
||||
*/
|
||||
Wurley();
|
||||
Wurley( void );
|
||||
|
||||
//! Class destructor.
|
||||
~Wurley();
|
||||
~Wurley( void );
|
||||
|
||||
//! Set instrument parameters for a particular frequency.
|
||||
void setFrequency(StkFloat frequency);
|
||||
void setFrequency( StkFloat frequency );
|
||||
|
||||
//! Start a note with the given frequency and amplitude.
|
||||
void noteOn(StkFloat frequency, StkFloat amplitude);
|
||||
void noteOn( StkFloat frequency, StkFloat amplitude );
|
||||
|
||||
//! Compute and return one output sample.
|
||||
StkFloat tick( unsigned int channel = 0 );
|
||||
|
||||
protected:
|
||||
|
||||
StkFloat computeSample( void );
|
||||
};
|
||||
|
||||
inline StkFloat Wurley :: tick( unsigned int )
|
||||
{
|
||||
StkFloat temp, temp2;
|
||||
|
||||
temp = gains_[1] * adsr_[1]->tick() * waves_[1]->tick();
|
||||
temp = temp * control1_;
|
||||
|
||||
waves_[0]->addPhaseOffset( temp );
|
||||
waves_[3]->addPhaseOffset( twozero_.lastOut() );
|
||||
temp = gains_[3] * adsr_[3]->tick() * waves_[3]->tick();
|
||||
twozero_.tick(temp);
|
||||
|
||||
waves_[2]->addPhaseOffset( temp );
|
||||
temp = ( 1.0 - (control2_ * 0.5)) * gains_[0] * adsr_[0]->tick() * waves_[0]->tick();
|
||||
temp += control2_ * 0.5 * gains_[2] * adsr_[2]->tick() * waves_[2]->tick();
|
||||
|
||||
// Calculate amplitude modulation and apply it to output.
|
||||
temp2 = vibrato_.tick() * modDepth_;
|
||||
temp = temp * (1.0 + temp2);
|
||||
|
||||
lastFrame_[0] = temp * 0.5;
|
||||
return lastFrame_[0];
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#ifndef STK_WVIN_H
|
||||
#define STK_WVIN_H
|
||||
|
||||
#include "Stk.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
/***************************************************/
|
||||
/*! \class WvIn
|
||||
\brief STK audio input abstract base class.
|
||||
@@ -5,83 +12,32 @@
|
||||
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 - 2007.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#ifndef STK_WVIN_H
|
||||
#define STK_WVIN_H
|
||||
|
||||
#include "Stk.h"
|
||||
#include <vector>
|
||||
|
||||
class WvIn : public Stk
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
WvIn();
|
||||
//! Return the number of audio channels in the data or stream.
|
||||
unsigned int channelsOut( void ) const { return data_.channels(); };
|
||||
|
||||
//! 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.
|
||||
//! Return an StkFrames reference to the last computed sample frame.
|
||||
/*!
|
||||
If no file data is loaded, an empty container is returned.
|
||||
*/
|
||||
const StkFrames& lastFrame( void ) const { return lastOutputs_; };
|
||||
const StkFrames& lastFrame( void ) const { return lastFrame_; };
|
||||
|
||||
//! 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 );
|
||||
//! Compute one sample frame and return the specified \c channel value.
|
||||
virtual StkFloat tick( unsigned int channel = 0 ) = 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 void computeFrame( void ) = 0;
|
||||
|
||||
StkFrames data_;
|
||||
StkFrames lastOutputs_;
|
||||
StkFrames lastFrame_;
|
||||
|
||||
};
|
||||
|
||||
} // stk namespace
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user