Version 4.4.3

This commit is contained in:
Gary Scavone
2013-09-29 23:21:29 +02:00
committed by Stephen Sinclair
parent baca57040b
commit 0aec39260a
223 changed files with 26190 additions and 11130 deletions

View File

@@ -11,10 +11,12 @@ namespace stk {
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.
messages, keeping track of its state. The \e state = ADSR::IDLE
before being triggered and after the envelope value reaches 0.0 in
the ADSR::RELEASE state. All rate, target and level settings must
be non-negative. All time settings must be positive.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -28,7 +30,7 @@ class ADSR : public Generator
DECAY, /*!< Decay */
SUSTAIN, /*!< Sustain */
RELEASE, /*!< Release */
DONE /*!< End of release */
IDLE /*!< Before attack / after release */
};
//! Default constructor.
@@ -46,6 +48,9 @@ class ADSR : public Generator
//! Set the attack rate.
void setAttackRate( StkFloat rate );
//! Set the target value for the attack (default = 1.0).
void setAttackTarget( StkFloat target );
//! Set the decay rate.
void setDecayRate( StkFloat rate );
@@ -58,19 +63,19 @@ class ADSR : public Generator
//! Set the attack rate based on a time duration.
void setAttackTime( StkFloat time );
//! Set the decay rate based on a time duration.
//! Set the decay rate based on a time duration (seconds).
void setDecayTime( StkFloat time );
//! Set the release rate based on a time duration.
//! Set the release rate based on a time duration (seconds).
void setReleaseTime( StkFloat time );
//! Set sustain level and attack, decay, and release time durations.
void setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime );
//! Set the target value.
//! Set a sustain target value and attack or decay from current value to target.
void setTarget( StkFloat target );
//! Return the current envelope \e state (ATTACK, DECAY, SUSTAIN, RELEASE, DONE).
//! Return the current envelope \e state (ATTACK, DECAY, SUSTAIN, RELEASE, IDLE).
int getState( void ) const { return state_; };
//! Set to state = ADSR::SUSTAIN with current and target values of \e value.
@@ -102,6 +107,7 @@ class ADSR : public Generator
StkFloat attackRate_;
StkFloat decayRate_;
StkFloat releaseRate_;
StkFloat releaseTime_;
StkFloat sustainLevel_;
};
@@ -120,10 +126,19 @@ inline StkFloat ADSR :: tick( void )
break;
case DECAY:
value_ -= decayRate_;
if ( value_ <= sustainLevel_ ) {
value_ = sustainLevel_;
state_ = SUSTAIN;
if ( value_ > sustainLevel_ ) {
value_ -= decayRate_;
if ( value_ <= sustainLevel_ ) {
value_ = sustainLevel_;
state_ = SUSTAIN;
}
}
else {
value_ += decayRate_; // attack target < sustain level
if ( value_ >= sustainLevel_ ) {
value_ = sustainLevel_;
state_ = SUSTAIN;
}
}
lastFrame_[0] = value_;
break;
@@ -131,8 +146,8 @@ inline StkFloat ADSR :: tick( void )
case RELEASE:
value_ -= releaseRate_;
if ( value_ <= 0.0 ) {
value_ = (StkFloat) 0.0;
state_ = DONE;
value_ = 0.0;
state_ = IDLE;
}
lastFrame_[0] = value_;
@@ -145,7 +160,7 @@ 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!";
oStream_ << "ADSR::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -26,7 +26,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -60,6 +60,9 @@ class Asymp : public Generator
//! Set the asymptotic rate based on a time duration (must be > 0).
void setTime( StkFloat time );
//! Set the asymptotic rate such that the target value is perceptually reached (to within -60dB of the target) in \e t60 seconds.
void setT60( StkFloat t60 );
//! Set the target value.
void setTarget( StkFloat target );
@@ -125,7 +128,7 @@ 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!";
oStream_ << "Asymp::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -84,6 +84,16 @@ class BandedWG : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
bool doPluck_;
@@ -111,6 +121,33 @@ class BandedWG : public Instrmnt
};
inline StkFrames& BandedWG :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "BandedWG::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -35,7 +35,7 @@ namespace stk {
type who should worry about this (making
money) worry away.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -57,6 +57,16 @@ class BeeThree : public FM
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
};
@@ -85,6 +95,33 @@ inline StkFloat BeeThree :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& BeeThree :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "BeeThree::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -13,7 +13,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -59,6 +59,8 @@ public:
filter frequency response has a resonance at the given \e
frequency. The closer the poles are to the unit-circle (\e radius
close to one), the narrower the resulting resonance width.
An unstable filter will result for \e radius >= 1.0. The
\e frequency value should be between zero and half the sample rate.
*/
void setResonance( StkFloat frequency, StkFloat radius, bool normalize = false );
@@ -66,8 +68,9 @@ public:
/*!
This method determines the filter coefficients corresponding to
two complex-conjugate zeros with the given \e frequency (in Hz)
and \e radius from the z-plane origin. No filter normalization
is attempted.
and \e radius from the z-plane origin. No filter normalization is
attempted. The \e frequency value should be between zero and half
the sample rate. The \e radius value should be positive.
*/
void setNotch( StkFloat frequency, StkFloat radius );
@@ -130,7 +133,7 @@ inline StkFrames& BiQuad :: tick( StkFrames& frames, unsigned int channel )
{
#if defined(_STK_DEBUG_)
if ( channel >= frames.channels() ) {
errorString_ << "BiQuad::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "BiQuad::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -155,7 +158,7 @@ inline StkFrames& BiQuad :: tick( StkFrames& iFrames, StkFrames& oFrames, unsign
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "BiQuad::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "BiQuad::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -133,7 +133,7 @@ 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!";
oStream_ << "Blit::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -129,7 +129,7 @@ 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!";
oStream_ << "BlitSaw::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -152,7 +152,7 @@ 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!";
oStream_ << "BlitSquare::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -25,7 +25,7 @@ namespace stk {
- Vibrato Gain = 1
- Volume = 128
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -65,6 +65,16 @@ class BlowBotl : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
JetTable jetTable_;
@@ -102,6 +112,33 @@ inline StkFloat BlowBotl :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& BlowBotl :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "BlowBotl::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -43,7 +43,7 @@ namespace stk {
- Register State = 1
- Breath Pressure = 128
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -89,6 +89,16 @@ class BlowHole : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
DelayL delays_[3];
@@ -98,15 +108,14 @@ class BlowHole : public Instrmnt
PoleZero vent_;
Envelope envelope_;
Noise noise_;
SineWave vibrato_;
unsigned long length_;
SineWave vibrato_;
StkFloat scatter_;
StkFloat thCoeff_;
StkFloat rhGain_;
StkFloat outputGain_;
StkFloat noiseGain_;
StkFloat vibratoGain_;
};
inline StkFloat BlowHole :: tick( unsigned int )
@@ -144,6 +153,33 @@ class BlowHole : public Instrmnt
return lastFrame_[0];
}
inline StkFrames& BlowHole :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "BlowHole::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -11,9 +11,11 @@ namespace stk {
\brief STK bowed string table class.
This class implements a simple bowed string
non-linear function, as described by Smith (1986).
non-linear function, as described by Smith
(1986). The output is an instantaneous
reflection coefficient value.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -21,7 +23,7 @@ class BowTable : public Function
{
public:
//! Default constructor.
BowTable( void ) : offset_(0.0), slope_(0.1) {};
BowTable( void ) : offset_(0.0), slope_(0.1), minOutput_(0.01), maxOutput_(0.98) {};
//! Set the table offset value.
/*!
@@ -39,6 +41,12 @@ public:
*/
void setSlope( StkFloat slope ) { slope_ = slope; };
//! Set the minimum table output value (0.0 - 1.0).
void setMinOutput( StkFloat minimum ) { minOutput_ = minimum; };
//! Set the maximum table output value (0.0 - 1.0).
void setMaxOutput( StkFloat maximum ) { maxOutput_ = maximum; };
//! Take one sample input and map to one sample of output.
StkFloat tick( StkFloat input );
@@ -68,6 +76,8 @@ protected:
StkFloat offset_;
StkFloat slope_;
StkFloat minOutput_;
StkFloat maxOutput_;
};
@@ -79,11 +89,11 @@ inline StkFloat BowTable :: tick( StkFloat input )
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 minimum threshold
if ( lastFrame_[0] < minOutput_ ) lastFrame_[0] = minOutput_;
// Set maximum friction to 1.0.
if ( lastFrame_[0] > 1.0 ) lastFrame_[0] = (StkFloat) 1.0;
// Set maximum threshold
if ( lastFrame_[0] > maxOutput_ ) lastFrame_[0] = maxOutput_;
return lastFrame_[0];
}
@@ -92,7 +102,7 @@ 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!";
oStream_ << "BowTable::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -115,7 +125,7 @@ inline StkFrames& BowTable :: tick( StkFrames& iFrames, StkFrames& oFrames, unsi
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "BowTable::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "BowTable::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -28,9 +28,12 @@ namespace stk {
- Bow Position = 4
- Vibrato Frequency = 11
- Vibrato Gain = 1
- Bow Velocity = 100
- Frequency = 101
- Volume = 128
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
Contributions by Esteban Maestre, 2011.
*/
/***************************************************/
@@ -38,7 +41,7 @@ class Bowed : public Instrmnt
{
public:
//! Class constructor, taking the lowest desired playing frequency.
Bowed( StkFloat lowestFrequency );
Bowed( StkFloat lowestFrequency = 8.0 );
//! Class destructor.
~Bowed( void );
@@ -50,7 +53,7 @@ class Bowed : public Instrmnt
void setFrequency( StkFloat frequency );
//! Set vibrato gain.
void setVibrato( StkFloat gain );
void setVibrato( StkFloat gain ) { vibratoGain_ = gain; };
//! Apply breath pressure to instrument with given amplitude and rate of increase.
void startBowing( StkFloat amplitude, StkFloat rate );
@@ -70,15 +73,27 @@ class Bowed : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
DelayL neckDelay_;
DelayL bridgeDelay_;
BowTable bowTable_;
OnePole stringFilter_;
BiQuad bodyFilter_;
BiQuad bodyFilters_[6];
SineWave vibrato_;
ADSR adsr_;
bool bowDown_;
StkFloat maxVelocity_;
StkFloat baseDelay_;
StkFloat vibratoGain_;
@@ -89,24 +104,54 @@ 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);
StkFloat bridgeReflection = -stringFilter_.tick( bridgeDelay_.lastOut() );
StkFloat nutReflection = -neckDelay_.lastOut();
StkFloat stringVelocity = bridgeReflection + nutReflection;
StkFloat deltaV = bowVelocity - stringVelocity; // Differential velocity
StkFloat newVelocity = 0.0;
if ( bowDown_ )
newVelocity = deltaV * bowTable_.tick( deltaV ); // Non-Linear bow function
neckDelay_.tick( bridgeReflection + newVelocity); // Do string propagations
bridgeDelay_.tick(nutReflection + newVelocity);
if ( vibratoGain_ > 0.0 ) {
neckDelay_.setDelay( (baseDelay_ * (1.0 - betaRatio_) ) +
(baseDelay_ * vibratoGain_ * vibrato_.tick()) );
}
lastFrame_[0] = bodyFilter_.tick( bridgeDelay_.lastOut() );
lastFrame_[0] = 0.1248 * bodyFilters_[5].tick( bodyFilters_[4].tick( bodyFilters_[3].tick( bodyFilters_[2].tick( bodyFilters_[1].tick( bodyFilters_[0].tick( bridgeDelay_.lastOut() ) ) ) ) ) );
return lastFrame_[0];
}
inline StkFrames& Bowed :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Bowed::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -28,7 +28,7 @@ namespace stk {
- Vibrato Gain = 1
- Volume = 128
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -39,7 +39,7 @@ class Brass: public Instrmnt
/*!
An StkError will be thrown if the rawwave path is incorrectly set.
*/
Brass( StkFloat lowestFrequency );
Brass( StkFloat lowestFrequency = 8.0 );
//! Class destructor.
~Brass( );
@@ -71,6 +71,16 @@ class Brass: public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
DelayA delayLine_;
@@ -78,7 +88,7 @@ class Brass: public Instrmnt
PoleZero dcBlock_;
ADSR adsr_;
SineWave vibrato_;
unsigned long length_;
StkFloat lipTarget_;
StkFloat slideTarget_;
StkFloat vibratoGain_;
@@ -105,6 +115,33 @@ inline StkFloat Brass :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& Brass :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Brass::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -14,7 +14,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -30,8 +30,8 @@ class Chorus : public Effect
//! Reset and clear all internal state.
void clear( void );
//! Set modulation depth.
void setModDepth( StkFloat depth ) { modDepth_ = depth; };
//! Set modulation depth in range 0.0 - 1.0.
void setModDepth( StkFloat depth );
//! Set modulation frequency.
void setModFrequency( StkFloat frequency );
@@ -94,7 +94,7 @@ inline StkFloat Chorus :: lastOut( unsigned int channel )
{
#if defined(_STK_DEBUG_)
if ( channel > 1 ) {
errorString_ << "Chorus::lastOut(): channel argument must be less than 2!";
oStream_ << "Chorus::lastOut(): channel argument must be less than 2!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -106,7 +106,7 @@ 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!";
oStream_ << "Chorus::tick(): channel argument must be less than 2!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -122,7 +122,7 @@ 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!";
oStream_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -130,6 +130,8 @@ inline StkFrames& Chorus :: tick( StkFrames& frames, unsigned int channel )
StkFloat *samples = &frames[channel];
unsigned int hop = frames.channels() - 1;
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
delayLine_[1].setDelay( baseLength_ * 0.5 * ( 1.0 - modDepth_ * mods_[1].tick() ) );
*samples = effectMix_ * ( delayLine_[0].tick( *samples ) - *samples ) + *samples;
samples++;
*samples = effectMix_ * ( delayLine_[1].tick( *samples ) - *samples ) + *samples;
@@ -144,7 +146,7 @@ inline StkFrames& Chorus :: tick( StkFrames& iFrames, StkFrames& oFrames, unsign
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
errorString_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -153,8 +155,10 @@ inline StkFrames& Chorus :: tick( StkFrames& iFrames, StkFrames& oFrames, unsign
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;
delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
delayLine_[1].setDelay( baseLength_ * 0.5 * ( 1.0 - modDepth_ * mods_[1].tick() ) );
*oSamples = effectMix_ * ( delayLine_[0].tick( *iSamples ) - *iSamples ) + *iSamples;
*(oSamples+1) = effectMix_ * ( delayLine_[1].tick( *iSamples ) - *iSamples ) + *iSamples;
}
lastFrame_[0] = *(oSamples-oHop);

View File

@@ -31,7 +31,7 @@ namespace stk {
- Vibrato Gain = 1
- Breath Pressure = 128
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -42,7 +42,7 @@ class Clarinet : public Instrmnt
/*!
An StkError will be thrown if the rawwave path is incorrectly set.
*/
Clarinet( StkFloat lowestFrequency );
Clarinet( StkFloat lowestFrequency = 8.0 );
//! Class destructor.
~Clarinet( void );
@@ -71,6 +71,16 @@ class Clarinet : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
DelayL delayLine_;
@@ -79,11 +89,10 @@ class Clarinet : public Instrmnt
Envelope envelope_;
Noise noise_;
SineWave vibrato_;
long length_;
StkFloat outputGain_;
StkFloat noiseGain_;
StkFloat vibratoGain_;
};
inline StkFloat Clarinet :: tick( unsigned int )
@@ -111,6 +120,33 @@ inline StkFloat Clarinet :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& Clarinet :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Clarinet::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

138
include/Cubic.h Normal file
View File

@@ -0,0 +1,138 @@
#ifndef STK_CUBIC_H
#define STK_CUBIC_H
#include "Function.h"
#include <cmath>
namespace stk {
/***************************************************/
/*! \class Cubic
\brief STK cubic non-linearity class.
This class implements the cubic non-linearity
that was used in SynthBuilder.
The formula implemented is:
\code
output = gain * (a1 * input + a2 * input^2 + a3 * input^3)
\endcode
followed by a limiter for values outside +-threshold.
Ported to STK by Nick Porcaro, 2007. Updated for inclusion
in STK distribution by Gary Scavone, 2011.
*/
/***************************************************/
class Cubic : public Function
{
public:
//! Default constructor.
Cubic( void ) : a1_(0.5), a2_(0.5), a3_(0.5), gain_(1.0), threshold_(1.0) {};
//! Set the a1 coefficient value.
void setA1( StkFloat a1 ) { a1_ = a1; };
//! Set the a2 coefficient value.
void setA2( StkFloat a2 ) { a2_ = a2; };
//! Set the a3 coefficient value.
void setA3( StkFloat a3 ) { a3_ = a3; };
//! Set the gain value.
void setGain( StkFloat gain ) { gain_ = gain; };
//! Set the threshold value.
void setThreshold( StkFloat threshold ) { threshold_ = threshold; };
//! Input one sample to the function and return one output.
StkFloat tick( StkFloat input );
//! Take a channel of the StkFrames object as inputs to the function 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 function 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 a1_;
StkFloat a2_;
StkFloat a3_;
StkFloat gain_;
StkFloat threshold_;
};
inline StkFloat Cubic :: tick( StkFloat input )
{
StkFloat inSquared = input * input;
StkFloat inCubed = inSquared * input;
lastFrame_[0] = gain_ * (a1_ * input + a2_ * inSquared + a3_ * inCubed);
// Apply threshold if we are out of range.
if ( fabs( lastFrame_[0] ) > threshold_ ) {
lastFrame_[0] = ( lastFrame_[0] < 0 ? -threshold_ : threshold_ );
}
return lastFrame_[0];
}
inline StkFrames& Cubic :: tick( StkFrames& frames, unsigned int channel )
{
#if defined(_STK_DEBUG_)
if ( channel >= frames.channels() ) {
oStream_ << "Cubic::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 );
lastFrame_[0] = *(samples-hop);
return frames;
}
inline StkFrames& Cubic :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
oStream_ << "Cubic::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 );
lastFrame_[0] = *(oSamples-oHop);
return iFrames;
}
} // stk namespace
#endif

View File

@@ -17,7 +17,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -36,13 +36,16 @@ public:
//! Class destructor.
~Delay();
//! Get the maximum delay-line length.
unsigned long getMaximumDelay( void ) { return inputs_.size() - 1; };
//! 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.
new length, no memory allocation change is made.
*/
void setMaximumDelay( unsigned long delay );
@@ -61,15 +64,18 @@ public:
relative to the last input value (i.e., a tapDelay of zero returns
the last input value).
*/
StkFloat contentsAt( unsigned long tapDelay );
StkFloat tapOut( unsigned long tapDelay );
//! Sum the provided value into the delay line at \e tapDelay samples from the input.
//! Set the \e value at \e tapDelay samples from the delay-line input.
void tapIn( StkFloat value, unsigned long tapDelay );
//! Sum the provided \e value into the delay line at \e tapDelay samples from the input.
/*!
The new value is returned. The tap point is determined modulo
the delay-line length and is relative to the last input value
(i.e., a tapDelay of zero sums into the last input value).
*/
StkFloat addTo( unsigned long tapDelay, StkFloat value );
StkFloat addTo( StkFloat value, unsigned long tapDelay );
//! Return the last computed output value.
StkFloat lastOut( void ) const { return lastFrame_[0]; };
@@ -136,7 +142,7 @@ 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!";
oStream_ << "Delay::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -158,7 +164,7 @@ inline StkFrames& Delay :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigne
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "Delay::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "Delay::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -21,7 +21,7 @@ namespace stk {
minimum delay possible in this implementation is limited to a
value of 0.5.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -42,6 +42,9 @@ public:
//! Clears all internal states of the delay line.
void clear( void );
//! Get the maximum delay-line length.
unsigned long getMaximumDelay( void ) { return inputs_.size() - 1; };
//! Set the maximum delay-line length.
/*!
@@ -49,7 +52,7 @@ public:
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.
new length, no memory allocation change is made.
*/
void setMaximumDelay( unsigned long delay );
@@ -68,7 +71,10 @@ public:
relative to the last input value (i.e., a tapDelay of zero returns
the last input value).
*/
StkFloat contentsAt( unsigned long tapDelay );
StkFloat tapOut( unsigned long tapDelay );
//! Set the \e value at \e tapDelay samples from the delay-line input.
void tapIn( StkFloat value, unsigned long tapDelay );
//! Return the last computed output value.
StkFloat lastOut( void ) const { return lastFrame_[0]; };
@@ -151,7 +157,7 @@ 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!";
oStream_ << "DelayA::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -175,7 +181,7 @@ inline StkFrames& DelayA :: tick( StkFrames& iFrames, StkFrames& oFrames, unsign
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "DelayA::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "DelayA::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -20,7 +20,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -39,13 +39,16 @@ public:
//! Class destructor.
~DelayL();
//! Get the maximum delay-line length.
unsigned long getMaximumDelay( void ) { return inputs_.size() - 1; };
//! 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.
new length, no memory allocation change is made.
*/
void setMaximumDelay( unsigned long delay );
@@ -64,7 +67,10 @@ public:
relative to the last input value (i.e., a tapDelay of zero returns
the last input value).
*/
StkFloat contentsAt( unsigned long tapDelay );
StkFloat tapOut( unsigned long tapDelay );
//! Set the \e value at \e tapDelay samples from the delay-line input.
void tapIn( StkFloat value, unsigned long tapDelay );
//! Return the last computed output value.
StkFloat lastOut( void ) const { return lastFrame_[0]; };
@@ -149,7 +155,7 @@ 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!";
oStream_ << "DelayL::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -172,7 +178,7 @@ inline StkFrames& DelayL :: tick( StkFrames& iFrames, StkFrames& oFrames, unsign
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "DelayL::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "DelayL::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -20,7 +20,7 @@ namespace stk {
of simultaneous voices) via a #define in the
Drummer.h.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -54,6 +54,16 @@ class Drummer : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
FileWvIn waves_[DRUM_POLYPHONY];
@@ -87,6 +97,34 @@ inline StkFloat Drummer :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& Drummer :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Drummer::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -12,7 +12,7 @@ namespace stk {
This class implements an echo effect.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -79,7 +79,7 @@ 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!";
oStream_ << "Echo::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -98,7 +98,7 @@ inline StkFrames& Echo :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "Echo::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "Echo::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -14,7 +14,7 @@ namespace stk {
subclasses. It is general enough to support both monophonic and
polyphonic input/output classes.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -49,12 +49,12 @@ class Effect : public Stk
inline void Effect :: setEffectMix( StkFloat mix )
{
if ( mix < 0.0 ) {
errorString_ << "Effect::setEffectMix: mix parameter is less than zero ... setting to zero!";
oStream_ << "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!";
oStream_ << "Effect::setEffectMix: mix parameter is greater than 1.0 ... setting to one!";
handleError( StkError::WARNING );
effectMix_ = 1.0;
}

View File

@@ -14,7 +14,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -38,9 +38,16 @@ class Envelope : public Generator
void keyOff( void ) { this->setTarget( 0.0 ); };
//! Set the \e rate.
/*!
The \e rate must be positive (though a value of 0.0 is allowed).
*/
void setRate( StkFloat rate );
//! Set the \e rate based on a time duration.
//! Set the \e rate based on a positive time duration (seconds).
/*!
The \e rate is calculated such that the envelope will ramp from
a value of 0.0 to 1.0 in the specified time duration.
*/
void setTime( StkFloat time );
//! Set the target value.
@@ -78,45 +85,6 @@ 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_ ) {
@@ -144,7 +112,7 @@ 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!";
oStream_ << "Envelope::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -30,7 +30,7 @@ namespace stk {
type who should worry about this (making
money) worry away.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -88,6 +88,16 @@ class FM : public Instrmnt
//! Compute and return one output sample.
virtual StkFloat tick( unsigned int ) = 0;
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ) = 0;
protected:
std::vector<ADSR *> adsr_;

View File

@@ -33,7 +33,7 @@ namespace stk {
type who should worry about this (making
money) worry away.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -61,6 +61,16 @@ class FMVoices : public FM
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
int currentVowel_;
@@ -93,6 +103,33 @@ inline StkFloat FMVoices :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& FMVoices :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "FMVoices::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -19,7 +19,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -54,6 +54,9 @@ class FileLoop : protected FileWvIn
//! Clear outputs and reset time (file) pointer to zero.
void reset( void ) { FileWvIn::reset(); };
//! Return the number of audio channels in the data or stream.
unsigned int channelsOut( void ) const { return data_.channels(); };
//! Normalize data to a maximum of +-1.0.
/*!
This function has no effect when data is incrementally loaded

View File

@@ -20,19 +20,21 @@ namespace stk {
FileRead currently supports uncompressed WAV,
AIFF/AIFC, SND (AU), MAT-file (Matlab), and
STK RAW file formats. Signed integer (8-,
16-, and 32-bit) and floating-point (32- and
16-, 24-, and 32-bit) and floating-point (32- and
64-bit) data types are supported. Compressed
data types are not supported.
STK RAW files have no header and are assumed
to contain a monophonic stream of 16-bit
signed integers in big-endian byte order at a
sample rate of 22050 Hz. MAT-file data should
be saved in an array with each data channel
filling a matrix row. The sample rate for
MAT-files is assumed to be 44100 Hz.
STK RAW files have no header and are assumed to
contain a monophonic stream of 16-bit signed
integers in big-endian byte order at a sample
rate of 22050 Hz. MAT-file data should be saved
in an array with each data channel filling a
matrix row. The sample rate for MAT-files should
be specified in a variable named "fs". If no
such variable is found, the sample rate is
assumed to be 44100 Hz.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -77,6 +79,9 @@ public:
//! Return the number of audio channels in the file.
unsigned int channels( void ) const { return channels_; };
//! Return the data format of the file.
StkFormat format( void ) const { return dataType_; };
//! Return the file sample rate in Hz.
/*!
WAV, SND, and AIF formatted files specify a sample rate in
@@ -118,6 +123,9 @@ protected:
// Get MAT-file header information.
bool getMatInfo( const char *fileName );
// Helper function for MAT-file parsing.
bool findNextMatArray( SINT32 *chunkSize, SINT32 *rows, SINT32 *columns, SINT32 *nametype );
FILE *fd_;
bool byteswap_;
bool wavFile_;

View File

@@ -17,14 +17,14 @@ namespace stk {
FileWrite currently supports uncompressed WAV, AIFF, AIFC, SND
(AU), MAT-file (Matlab), and STK RAW file formats. Signed integer
(8-, 16-, and 32-bit) and floating- point (32- and 64-bit) data
types are supported. STK RAW files use 16-bit integers by
(8-, 16-, 24-, and 32-bit) and floating- point (32- and 64-bit)
data types are supported. STK RAW files use 16-bit integers by
definition. MAT-files will always be written as 64-bit floats.
If a data type specification does not match the specified file
type, the data type will automatically be modified. Compressed
data types are not supported.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -76,28 +76,28 @@ class FileWrite : public Stk
protected:
// Write STK RAW file header.
bool setRawFile( const char *fileName );
bool setRawFile( std::string fileName );
// Write WAV file header.
bool setWavFile( const char *fileName );
bool setWavFile( std::string fileName );
// Close WAV file, updating the header.
void closeWavFile( void );
// Write SND (AU) file header.
bool setSndFile( const char *fileName );
bool setSndFile( std::string fileName );
// Close SND file, updating the header.
void closeSndFile( void );
// Write AIFF file header.
bool setAifFile( const char *fileName );
bool setAifFile( std::string fileName );
// Close AIFF file, updating the header.
void closeAifFile( void );
// Write MAT-file header.
bool setMatFile( const char *fileName );
bool setMatFile( std::string fileName );
// Close MAT-file, updating the header.
void closeMatFile( void );

View File

@@ -35,7 +35,7 @@ namespace stk {
See the FileRead class for a description of the supported audio
file formats.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -99,6 +99,9 @@ public:
*/
virtual StkFloat getFileRate( void ) const { return data_.dataRate(); };
//! Query whether a file is open.
bool isOpen( void ) { return file_.isOpen(); };
//! Query whether reading is complete.
bool isFinished( void ) const { return finished_; };
@@ -179,7 +182,7 @@ 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!";
oStream_ << "FileWvIn::lastOut(): channel argument and soundfile data are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -25,7 +25,7 @@ namespace stk {
Currently, FileWvOut is non-interpolating and the output rate is
always Stk::sampleRate().
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -3,6 +3,7 @@
#include "Stk.h"
#include <vector>
#include <cmath>
namespace stk {
@@ -14,7 +15,7 @@ namespace stk {
filter subclasses. It is general enough to support both
monophonic and polyphonic input/output classes.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -43,6 +44,14 @@ public:
//! Return the current filter gain.
StkFloat getGain( void ) const { return gain_; };
//! Return the filter phase delay at the specified frequency.
/*!
Note that the phase delay calculation accounts for the filter
gain. The frequency value should be greater than 0.0 and less
than or equal to one-half the sample rate.
*/
StkFloat phaseDelay( StkFloat frequency );
//! Return an StkFrames reference to the last output sample frame.
const StkFrames& lastFrame( void ) const { return lastFrame_; };
@@ -59,10 +68,10 @@ public:
protected:
StkFloat gain_;
unsigned int channelsIn_;
StkFrames lastFrame_;
StkFloat gain_;
std::vector<StkFloat> b_;
std::vector<StkFloat> a_;
StkFrames outputs_;
@@ -81,6 +90,35 @@ inline void Filter :: clear( void )
lastFrame_[i] = 0.0;
}
inline StkFloat Filter :: phaseDelay( StkFloat frequency )
{
if ( frequency <= 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
oStream_ << "Filter::phaseDelay: argument (" << frequency << ") is out of range!";
handleError( StkError::WARNING ); return 0.0;
}
StkFloat omegaT = 2 * M_PI * frequency / Stk::sampleRate();
StkFloat real = 0.0, imag = 0.0;
for ( unsigned int i=0; i<b_.size(); i++ ) {
real += b_[i] * std::cos( i * omegaT );
imag -= b_[i] * std::sin( i * omegaT );
}
real *= gain_;
imag *= gain_;
StkFloat phase = atan2( imag, real );
real = 0.0, imag = 0.0;
for ( unsigned int i=0; i<a_.size(); i++ ) {
real += a_[i] * std::cos( i * omegaT );
imag -= a_[i] * std::sin( i * omegaT );
}
phase -= std::atan2( imag, real );
phase = std::fmod( -phase, 2 * M_PI );
return phase / omegaT;
}
} // stk namespace
#endif

View File

@@ -23,7 +23,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -101,7 +101,7 @@ 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!";
oStream_ << "Fir::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -127,7 +127,7 @@ inline StkFrames& Fir :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "Fir::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "Fir::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -32,7 +32,7 @@ namespace stk {
- Vibrato Gain = 1
- Breath Pressure = 128
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -55,10 +55,10 @@ class Flute : public Instrmnt
void setFrequency( StkFloat frequency );
//! Set the reflection coefficient for the jet delay (-1.0 - 1.0).
void setJetReflection( StkFloat coefficient );
void setJetReflection( StkFloat coefficient ) { jetReflection_ = coefficient; };
//! Set the reflection coefficient for the air column delay (-1.0 - 1.0).
void setEndReflection( StkFloat coefficient );
void setEndReflection( StkFloat coefficient ) { endReflection_ = 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 );
@@ -81,6 +81,16 @@ class Flute : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
DelayL jetDelay_;
@@ -91,7 +101,7 @@ class Flute : public Instrmnt
Noise noise_;
ADSR adsr_;
SineWave vibrato_;
unsigned long length_;
StkFloat lastFrequency_;
StkFloat maxPressure_;
StkFloat jetReflection_;
@@ -112,7 +122,7 @@ inline StkFloat Flute :: tick( unsigned int )
breathPressure = maxPressure_ * adsr_.tick();
breathPressure += breathPressure * ( noiseGain_ * noise_.tick() + vibratoGain_ * vibrato_.tick() );
StkFloat temp = filter_.tick( boreDelay_.lastOut() );
StkFloat temp = -filter_.tick( boreDelay_.lastOut() );
temp = dcBlock_.tick( temp ); // Block DC on reflection.
pressureDiff = breathPressure - (jetReflection_ * temp);
@@ -124,6 +134,33 @@ inline StkFloat Flute :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& Flute :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Flute::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -13,7 +13,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -35,12 +35,14 @@ class FormSwep : public Filter
This method determines the filter coefficients corresponding to
two complex-conjugate poles with the given \e frequency (in Hz)
and \e radius from the z-plane origin. The filter zeros are
placed at z = 1, z = -1, and the coefficients are then normalized to
produce a constant unity gain (independent of the filter \e gain
parameter). The resulting filter frequency response has a
placed at z = 1, z = -1, and the coefficients are then normalized
to produce a constant unity gain (independent of the filter \e
gain parameter). The resulting filter frequency response has a
resonance at the given \e frequency. The closer the poles are to
the unit-circle (\e radius close to one), the narrower the
resulting resonance width.
resulting resonance width. An unstable filter will result for \e
radius >= 1.0. The \e frequency value should be between zero and
half the sample rate.
*/
void setResonance( StkFloat frequency, StkFloat radius );
@@ -152,7 +154,7 @@ 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!";
oStream_ << "FormSwep::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -169,7 +171,7 @@ inline StkFrames& FormSwep :: tick( StkFrames& iFrames, StkFrames& oFrames, unsi
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "FormSwep::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "FormSwep::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -13,7 +13,7 @@ namespace stk {
implement tables or other types of input to output function
mappings.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -13,7 +13,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -175,7 +175,7 @@ inline StkFloat Granulate :: lastOut( unsigned int channel )
{
#if defined(_STK_DEBUG_)
if ( channel >= lastFrame_.channels() ) {
errorString_ << "Granulate::lastOut(): channel argument is invalid!";
oStream_ << "Granulate::lastOut(): channel argument is invalid!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -188,7 +188,7 @@ 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!";
oStream_ << "Granulate::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -31,7 +31,7 @@ namespace stk {
type who should worry about this (making
money) worry away.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -53,6 +53,16 @@ class HevyMetl : public FM
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
};
@@ -84,6 +94,33 @@ inline StkFloat HevyMetl :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& HevyMetl :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "HevyMetl::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -27,7 +27,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -136,7 +136,7 @@ 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!";
oStream_ << "Iir::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -168,7 +168,7 @@ inline StkFrames& Iir :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "Iir::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "Iir::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -31,7 +31,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -141,7 +141,7 @@ 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!";
oStream_ << "InetWvIn::lastOut(): channel argument and data stream are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -25,7 +25,7 @@ namespace stk {
data type is signed 16-bit integers but any of the defined
StkFormats are permissible.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -12,7 +12,7 @@ namespace stk {
This class provides a common interface for
all STK instruments.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -65,7 +65,7 @@ class Instrmnt : public Stk
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:
@@ -73,9 +73,9 @@ class Instrmnt : public Stk
};
inline void Instrmnt :: setFrequency(StkFloat frequency)
inline void Instrmnt :: setFrequency( StkFloat frequency )
{
errorString_ << "Instrmnt::setFrequency: virtual setFrequency function call!";
oStream_ << "Instrmnt::setFrequency: virtual setFrequency function call!";
handleError( StkError::WARNING );
}
@@ -83,7 +83,7 @@ inline StkFloat Instrmnt :: lastOut( unsigned int channel )
{
#if defined(_STK_DEBUG_)
if ( channel >= lastFrame_.channels() ) {
errorString_ << "Instrmnt::lastOut(): channel argument is invalid!";
oStream_ << "Instrmnt::lastOut(): channel argument is invalid!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -91,36 +91,9 @@ inline StkFloat Instrmnt :: lastOut( unsigned int channel )
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!";
oStream_ << "Instrmnt::controlChange: virtual function call!";
handleError( StkError::WARNING );
}

View File

@@ -3,6 +3,7 @@
#include "Effect.h"
#include "Delay.h"
#include "OnePole.h"
namespace stk {
@@ -10,14 +11,20 @@ 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.
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 - 2010.
Although not in the original JC reverberator,
one-pole lowpass filters have been added inside
the feedback comb filters.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -82,6 +89,7 @@ class JCRev : public Effect
Delay allpassDelays_[3];
Delay combDelays_[4];
OnePole combFilters_[4];
Delay outLeftDelay_;
Delay outRightDelay_;
StkFloat allpassCoefficient_;
@@ -93,7 +101,7 @@ inline StkFloat JCRev :: lastOut( unsigned int channel )
{
#if defined(_STK_DEBUG_)
if ( channel > 1 ) {
errorString_ << "JCRev::lastOut(): channel argument must be less than 2!";
oStream_ << "JCRev::lastOut(): channel argument must be less than 2!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -105,7 +113,7 @@ 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!";
oStream_ << "JCRev::tick(): channel argument must be less than 2!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -131,10 +139,10 @@ inline StkFloat JCRev :: tick( StkFloat input, unsigned int channel )
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());
temp3 = temp2 + ( combFilters_[0].tick( combCoefficient_[0] * combDelays_[0].lastOut() ) );
temp4 = temp2 + ( combFilters_[1].tick( combCoefficient_[1] * combDelays_[1].lastOut() ) );
temp5 = temp2 + ( combFilters_[2].tick( combCoefficient_[2] * combDelays_[2].lastOut() ) );
temp6 = temp2 + ( combFilters_[3].tick( combCoefficient_[3] * combDelays_[3].lastOut() ) );
combDelays_[0].tick(temp3);
combDelays_[1].tick(temp4);
@@ -149,7 +157,7 @@ inline StkFloat JCRev :: tick( StkFloat input, unsigned int channel )
lastFrame_[0] += temp;
lastFrame_[1] += temp;
return lastFrame_[channel];
return 0.7 * lastFrame_[channel];
}
} // stk namespace

View File

@@ -16,7 +16,7 @@ namespace stk {
Consult Fletcher and Rossing, Karjalainen,
Cook, and others for more information.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -68,7 +68,7 @@ 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!";
oStream_ << "JetTable::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -89,7 +89,7 @@ inline StkFrames& JetTable :: tick( StkFrames& iFrames, StkFrames& oFrames, unsi
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "JetTable::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "JetTable::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -134,7 +134,7 @@ inline void LentPitShift::process()
for ( n=0; n<inputFrames.size(); n++ ) {
x_t = inputLine_.tick( inputFrames[ n ] );
for ( delay_=1; delay_<= tMax_; delay_++ ) {
x_t_T = inputLine_.contentsAt( delay_ );
x_t_T = inputLine_.tapOut( delay_ );
coeff = x_t - x_t_T;
dt[delay_] += coeff * coeff;
}
@@ -193,7 +193,7 @@ inline void LentPitShift::process()
M = tMax_ - inputPtr + lastPeriod_ - 1; // New reading pointer
N = 2*tMax_ - (unsigned long)floor(outputPtr + tMax_) + lastPeriod_ - 1; // New writing pointer
for ( unsigned int j=0; j<2*lastPeriod_; j++,M--,N-- ) {
sample = inputLine_.contentsAt(M) * window[j] / 2.;
sample = inputLine_.tapOut(M) * window[j] / 2.;
// Linear interpolation
outputLine_.addTo(N, env[0] * sample);
outputLine_.addTo(N-1, env[1] * sample);
@@ -228,7 +228,7 @@ inline StkFrames& LentPitShift :: tick( StkFrames& frames, unsigned int channel
{
#if defined(_STK_DEBUG_)
if ( channel >= frames.channels() ) {
errorString_ << "LentPitShift::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "LentPitShift::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -246,7 +246,7 @@ inline StkFrames& LentPitShift :: tick( StkFrames& iFrames, StkFrames& oFrames,
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "LentPitShift::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "LentPitShift::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -1,7 +1,8 @@
#ifndef STK_MANDOLIN_H
#define STK_MANDOLIN_H
#include "PluckTwo.h"
#include "Instrmnt.h"
#include "Twang.h"
#include "FileWvIn.h"
namespace stk {
@@ -10,19 +11,18 @@ namespace stk {
/*! \class Mandolin
\brief STK mandolin instrument model class.
This class inherits from PluckTwo and uses
"commuted synthesis" techniques to model a
mandolin instrument.
This class uses two "twang" models and "commuted
synthesis" techniques to model a mandolin
instrument.
This is a digital waveguide model, making its
use possibly subject to patents held by
Stanford University, Yamaha, and others.
Commuted Synthesis, in particular, is covered
by patents, granted, pending, and/or
applied-for. All are assigned to the Board of
Trustees, Stanford University. For
information, contact the Office of Technology
Licensing, Stanford University.
use possibly subject to patents held by Stanford
University, Yamaha, and others. Commuted
Synthesis, in particular, is covered by patents,
granted, pending, and/or applied-for. All are
assigned to the Board of Trustees, Stanford
University. For information, contact the Office
of Technology Licensing, Stanford University.
Control Change Numbers:
- Body Size = 2
@@ -31,11 +31,11 @@ namespace stk {
- String Detuning = 1
- Microphone Position = 128
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
class Mandolin : public PluckTwo
class Mandolin : public Instrmnt
{
public:
//! Class constructor, taking the lowest desired playing frequency.
@@ -44,6 +44,21 @@ class Mandolin : public PluckTwo
//! Class destructor.
~Mandolin( void );
//! Reset and clear all internal state.
void clear( void );
//! Detune the two strings by the given factor. A value of 1.0 produces unison strings.
void setDetune( StkFloat detune );
//! Set the body size (a value of 1.0 produces the "default" size).
void setBodySize( StkFloat size );
//! Set the pluck or "excitation" position along the string (0.0 - 1.0).
void setPluckPosition( StkFloat position );
//! Set instrument parameters for a particular frequency.
void setFrequency( StkFloat frequency );
//! Pluck the strings with the given amplitude (0.0 - 1.0) using the current frequency.
void pluck( StkFloat amplitude );
@@ -53,8 +68,8 @@ class Mandolin : public PluckTwo
//! Start a note with the given frequency and amplitude (0.0 - 1.0).
void noteOn( StkFloat frequency, StkFloat amplitude );
//! Set the body size (a value of 1.0 produces the "default" size).
void setBodySize( StkFloat size );
//! Stop a note with the given amplitude (speed of decay).
void noteOff( StkFloat amplitude );
//! Perform the control change specified by \e number and \e value (0.0 - 128.0).
void controlChange( int number, StkFloat value );
@@ -62,44 +77,67 @@ class Mandolin : public PluckTwo
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
FileWvIn *soundfile_[12];
Twang strings_[2];
FileWvIn soundfile_[12];
int mic_;
long dampTime_;
bool waveDone_;
StkFloat detuning_;
StkFloat frequency_;
StkFloat pluckAmplitude_;
};
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();
}
if ( !soundfile_[mic_].isFinished() )
temp = soundfile_[mic_].tick() * pluckAmplitude_;
// 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] = strings_[0].tick( temp );
lastFrame_[0] += strings_[1].tick( temp );
lastFrame_[0] *= 0.2;
lastFrame_[0] *= 0.3;
return lastFrame_[0];
}
inline StkFrames& Mandolin :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Mandolin::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -32,14 +32,14 @@ namespace stk {
*/
/***************************************************/
const short NXMAX = 12;
const short NYMAX = 12;
const unsigned short NXMAX = 12;
const unsigned short NYMAX = 12;
class Mesh2D : public Instrmnt
{
public:
//! Class constructor, taking the x and y dimensions in samples.
Mesh2D( short nX, short nY );
Mesh2D( unsigned short nX, unsigned short nY );
//! Class destructor.
~Mesh2D( void );
@@ -48,10 +48,10 @@ class Mesh2D : public Instrmnt
void clear( void );
//! Set the x dimension size in samples.
void setNX( short lenX );
void setNX( unsigned short lenX );
//! Set the y dimension size in samples.
void setNY( short lenY );
void setNY( unsigned short lenY );
//! Set the x, y input position on a 0.0 - 1.0 scale.
void setInputPosition( StkFloat xFactor, StkFloat yFactor );
@@ -77,14 +77,24 @@ class Mesh2D : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
StkFloat tick0();
StkFloat tick1();
void clearMesh();
short NX_, NY_;
short xInput_, yInput_;
unsigned short NX_, NY_;
unsigned short xInput_, yInput_;
OnePole filterX_[NXMAX];
OnePole filterY_[NYMAX];
StkFloat v_[NXMAX-1][NYMAX-1]; // junction velocities
@@ -102,6 +112,33 @@ class Mesh2D : public Instrmnt
int counter_; // time in samples
};
inline StkFrames& Mesh2D :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Mesh2D::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -46,7 +46,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -40,10 +40,10 @@ class MidiFileIn : public Stk
~MidiFileIn();
//! Return the MIDI file format (0, 1, or 2).
int getFileFormat() const;
int getFileFormat() const { return format_; };
//! Return the number of tracks in the MIDI file.
unsigned int getNumberOfTracks() const;
unsigned int getNumberOfTracks() const { return nTracks_; };
//! Return the MIDI file division value from the file header.
/*!
@@ -51,7 +51,7 @@ class MidiFileIn : public Stk
MIDI File Specification. In particular, if the MSB is set, the
file uses time-code representations for delta-time values.
*/
int getDivision() const;
int getDivision() const { return division_; };
//! Move the specified track event reader to the beginning of its track.
/*!

View File

@@ -19,7 +19,7 @@ namespace stk {
(non-sweeping BiQuad filters), where N is set
during instantiation.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -71,6 +71,16 @@ public:
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
Envelope envelope_;
@@ -112,6 +122,33 @@ inline StkFloat Modal :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& Modal :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Modal::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -31,7 +31,7 @@ namespace stk {
- Two Fixed = 7
- Clump = 8
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -16,7 +16,7 @@ namespace stk {
modulations to give a nice, natural human
modulation function.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -90,7 +90,7 @@ 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!";
oStream_ << "Modulate::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -22,7 +22,7 @@ namespace stk {
- Vibrato Gain = 1
- Gain = 128
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -56,6 +56,16 @@ class Moog : public Sampler
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
FormSwep filters_[2];
@@ -83,6 +93,33 @@ inline StkFloat Moog :: tick( unsigned int )
return lastFrame_[0] * 6.0;
}
inline StkFrames& Moog :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Moog::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -29,7 +29,7 @@ namespace stk {
systems, the pthread library is used. Under
Windows, critical sections are used.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -18,7 +18,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -93,7 +93,7 @@ inline StkFloat NRev :: lastOut( unsigned int channel )
{
#if defined(_STK_DEBUG_)
if ( channel > 1 ) {
errorString_ << "NRev::lastOut(): channel argument must be less than 2!";
oStream_ << "NRev::lastOut(): channel argument must be less than 2!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -105,7 +105,7 @@ 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!";
oStream_ << "NRev::tick(): channel argument must be less than 2!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -13,7 +13,7 @@ namespace stk {
C rand() function. The quality of the rand()
function varies from one OS to another.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -64,7 +64,7 @@ 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!";
oStream_ << "Noise::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -13,7 +13,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -42,7 +42,8 @@ public:
z-plane and normalizes the coefficients for a maximum gain of one.
A positive pole value produces a low-pass filter, while a negative
pole value produces a high-pass filter. This method does not
affect the filter \e gain value.
affect the filter \e gain value. The argument magnitude should be
less than one to maintain filter stability.
*/
void setPole( StkFloat thePole );
@@ -89,7 +90,7 @@ 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!";
oStream_ << "OnePole::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -110,7 +111,7 @@ inline StkFrames& OnePole :: tick( StkFrames& iFrames, StkFrames& oFrames, unsig
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "OnePole::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "OnePole::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -13,7 +13,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -89,7 +89,7 @@ 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!";
oStream_ << "OneZero::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -110,7 +110,7 @@ inline StkFrames& OneZero :: tick( StkFrames& iFrames, StkFrames& oFrames, unsig
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "OneZero::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "OneZero::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -17,7 +17,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -80,8 +80,8 @@ public:
protected:
Delay allpassDelays_[2];
Delay combDelays_[2];
Delay allpassDelays_[2];
Delay combDelays_[2];
StkFloat allpassCoefficient_;
StkFloat combCoefficient_[2];
@@ -91,7 +91,7 @@ inline StkFloat PRCRev :: lastOut( unsigned int channel )
{
#if defined(_STK_DEBUG_)
if ( channel > 1 ) {
errorString_ << "PRCRev::lastOut(): channel argument must be less than 2!";
oStream_ << "PRCRev::lastOut(): channel argument must be less than 2!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -103,7 +103,7 @@ inline StkFloat PRCRev :: lastOut( unsigned int channel )
{
#if defined(_STK_DEBUG_)
if ( channel > 1 ) {
errorString_ << "PRCRev::tick(): channel argument must be less than 2!";
oStream_ << "PRCRev::tick(): channel argument must be less than 2!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -122,8 +122,8 @@ inline StkFloat PRCRev :: lastOut( unsigned int channel )
allpassDelays_[1].tick(temp1);
temp1 = -(allpassCoefficient_ * temp1) + temp;
temp2 = temp1 + (combCoefficient_[0] * combDelays_[0].lastOut());
temp3 = temp1 + (combCoefficient_[1] * combDelays_[1].lastOut());
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));

View File

@@ -29,7 +29,7 @@ namespace stk {
type who should worry about this (making
money) worry away.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -54,6 +54,16 @@ class PercFlut : public FM
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
};
@@ -85,6 +95,33 @@ inline StkFloat PercFlut :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& PercFlut :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "PercFlut::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -13,7 +13,7 @@ namespace stk {
set of 32 static phoneme formant parameters
and provide access to those values.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -21,8 +21,9 @@ class Phonemes : public Stk
{
public:
Phonemes(void);
~Phonemes(void);
Phonemes( void );
~Phonemes( void );
//! Returns the phoneme name for the given index (0-31).
static const char *name( unsigned int index );

View File

@@ -13,7 +13,7 @@ namespace stk {
This class implements a simple pitch shifter
using delay lines.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -1,89 +0,0 @@
#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.
This class implements an enhanced two-string,
plucked physical model, a la Jaffe-Smith,
Smith, and others.
PluckTwo is an abstract class, with no excitation
specified. Therefore, it can't be directly
instantiated.
This is a digital waveguide model, making its
use possibly subject to patents held by
Stanford University, Yamaha, and others.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
*/
/***************************************************/
class PluckTwo : public Instrmnt
{
public:
//! Class constructor, taking the lowest desired playing frequency.
PluckTwo( StkFloat lowestFrequency );
//! Class destructor.
virtual ~PluckTwo( void );
//! Reset and clear all internal state.
void clear( void );
//! Set instrument parameters for a particular frequency.
virtual void setFrequency( StkFloat frequency );
//! Detune the two strings by the given factor. A value of 1.0 produces unison strings.
void setDetune( StkFloat detune );
//! Efficient combined setting of frequency and detuning.
void setFreqAndDetune( StkFloat frequency, StkFloat detune );
//! Set the pluck or "excitation" position along the string (0.0 - 1.0).
void setPluckPosition( StkFloat position );
//! Set the base loop gain.
/*!
The actual loop gain is set according to the frequency.
Because of high-frequency loop filter roll-off, higher
frequency settings have greater loop gains.
*/
void setBaseLoopGain( StkFloat aGain );
//! Stop a note with the given amplitude (speed of decay).
virtual void noteOff( StkFloat amplitude );
virtual StkFloat tick( unsigned int channel = 0 ) = 0;
protected:
DelayA delayLine_;
DelayA delayLine2_;
DelayL combDelay_;
OneZero filter_;
OneZero filter2_;
unsigned long length_;
StkFloat loopGain_;
StkFloat baseLoopGain_;
StkFloat lastFrequency_;
StkFloat lastLength_;
StkFloat detuning_;
StkFloat pluckAmplitude_;
StkFloat pluckPosition_;
};
} // stk namespace
#endif

View File

@@ -11,12 +11,15 @@ namespace stk {
/***************************************************/
/*! \class Plucked
\brief STK plucked string model class.
\brief STK basic plucked string class.
This class implements a simple plucked string
physical model based on the Karplus-Strong
algorithm.
For a more advanced plucked string implementation,
see the stk::Twang class.
This is a digital waveguide model, making its
use possibly subject to patents held by
Stanford University, Yamaha, and others.
@@ -24,7 +27,7 @@ namespace stk {
Stanford, bearing the names of Karplus and/or
Strong.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -32,7 +35,7 @@ class Plucked : public Instrmnt
{
public:
//! Class constructor, taking the lowest desired playing frequency.
Plucked( StkFloat lowestFrequency );
Plucked( StkFloat lowestFrequency = 10.0 );
//! Class destructor.
~Plucked( void );
@@ -55,15 +58,24 @@ class Plucked : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
DelayA delayLine_;
OneZero loopFilter_;
OnePole pickFilter_;
Noise noise_;
StkFloat loopGain_;
unsigned long length_;
StkFloat loopGain_;
};
inline StkFloat Plucked :: tick( unsigned int )
@@ -72,6 +84,33 @@ inline StkFloat Plucked :: tick( unsigned int )
return lastFrame_[0] = 3.0 * delayLine_.tick( loopFilter_.tick( delayLine_.lastOut() * loopGain_ ) );
}
inline StkFrames& Plucked :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Plucked::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -14,7 +14,7 @@ namespace stk {
coefficient. Another method is provided to create a DC blocking
filter.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -43,17 +43,18 @@ class PoleZero : public Filter
//! Set the filter for allpass behavior using \e coefficient.
/*!
This method uses \e coefficient to create an allpass filter,
which has unity gain at all frequencies. Note that the \e
coefficient magnitude must be less than one to maintain stability.
which has unity gain at all frequencies. Note that the
\e coefficient magnitude must be less than one to maintain
filter stability.
*/
void setAllpass( StkFloat coefficient );
//! Create a DC blocking filter with the given pole position in the z-plane.
/*!
This method sets the given pole position, together with a zero
at z=1, to create a DC blocking filter. \e thePole should be
close to one to minimize low-frequency attenuation.
at z=1, to create a DC blocking filter. The argument magnitude
should be close to (but less than) one to minimize low-frequency
attenuation.
*/
void setBlockZero( StkFloat thePole = 0.99 );
@@ -89,7 +90,7 @@ 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!";
oStream_ << "PoleZero::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -20,7 +20,7 @@ namespace stk {
Smith (1986), Hirschman, Cook, Scavone, and
others for more information.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -99,7 +99,7 @@ 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!";
oStream_ << "ReedTable::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -120,7 +120,7 @@ inline StkFrames& ReedTable :: tick( StkFrames& iFrames, StkFrames& oFrames, uns
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "ReedTable::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "ReedTable::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -23,7 +23,7 @@ namespace stk {
- Zero Radii = 1
- Envelope Gain = 128
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -66,6 +66,16 @@ class Resonate : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
ADSR adsr_;
@@ -85,6 +95,33 @@ inline StkFloat Resonate :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& Resonate :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Resonate::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -33,7 +33,7 @@ namespace stk {
type who should worry about this (making
money) worry away.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -58,6 +58,16 @@ class Rhodey : public FM
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
};
@@ -86,6 +96,33 @@ inline StkFloat Rhodey :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& Rhodey :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Rhodey::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -10,7 +10,7 @@
RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
RtAudio: realtime audio i/o C++ classes
Copyright (c) 2001-2010 Gary P. Scavone
Copyright (c) 2001-2011 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.7
// RtAudio: Version 4.0.10
#ifndef __RTAUDIO_H
#define __RTAUDIO_H
@@ -59,10 +59,12 @@
internal routines will automatically take care of any necessary
byte-swapping between the host format and the soundcard. Thus,
endian-ness is not a concern in the following format definitions.
Note that 24-bit data is expected to be encapsulated in a 32-bit
format.
- \e RTAUDIO_SINT8: 8-bit signed integer.
- \e RTAUDIO_SINT16: 16-bit signed integer.
- \e RTAUDIO_SINT24: Upper 3 bytes of 32-bit signed integer.
- \e RTAUDIO_SINT24: Lower 3 bytes of 32-bit signed integer.
- \e RTAUDIO_SINT32: 32-bit signed integer.
- \e RTAUDIO_FLOAT32: Normalized between plus/minus 1.0.
- \e RTAUDIO_FLOAT64: Normalized between plus/minus 1.0.
@@ -84,6 +86,7 @@ static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/mi
- \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_ALSA_USE_DEFAULT: Use the "default" PCM device (ALSA only).
By default, RtAudio streams pass and receive audio data from the
client in an interleaved format. By passing the
@@ -111,12 +114,17 @@ static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/mi
If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt
to select realtime scheduling (round-robin) for the callback thread.
If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to
open the "default" PCM device when using the ALSA API. Note that this
will override any specified input or output device id.
*/
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.
static const RtAudioStreamFlags RTAUDIO_ALSA_USE_DEFAULT = 0x10; // Use the "default" PCM device (ALSA only).
/*! \typedef typedef unsigned long RtAudioStreamStatus;
\brief RtAudio stream status (over- or underflow) flags.
@@ -248,6 +256,7 @@ class RtAudio
- \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.
- \e RTAUDIO_ALSA_USE_DEFAULT: Use the "default" PCM device (ALSA only).
By default, RtAudio streams pass and receive audio data from the
client in an interleaved format. By passing the
@@ -276,7 +285,11 @@ class RtAudio
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.
flag is set. It defines the thread's realtime priority.
If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to
open the "default" PCM device when using the ALSA API. Note that this
will override any specified input or output device id.
The \c numberOfBuffers parameter can be used to control stream
latency in the Windows DirectSound, Linux OSS, and Linux Alsa APIs
@@ -292,7 +305,7 @@ class RtAudio
RtAudio with Jack, each instance must have a unique client name.
*/
struct StreamOptions {
RtAudioStreamFlags flags; /*!< A bit-mask of stream flags (RTAUDIO_NONINTERLEAVED, RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE). */
RtAudioStreamFlags flags; /*!< A bit-mask of stream flags (RTAUDIO_NONINTERLEAVED, RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE, RTAUDIO_ALSA_USE_DEFAULT). */
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). */

View File

@@ -41,13 +41,13 @@ class RtError : public std::exception
virtual ~RtError( void ) throw() {}
//! Prints thrown error message to stderr.
virtual void printMessage( void ) throw() { std::cerr << '\n' << message_ << "\n\n"; }
virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; }
//! Returns the thrown error message type.
virtual const Type& getType(void) throw() { return type_; }
virtual const Type& getType(void) const throw() { return type_; }
//! Returns the thrown error message string.
virtual const std::string& getMessage(void) throw() { return message_; }
virtual const std::string& getMessage(void) const throw() { return message_; }
//! Returns the thrown error message as a c-style string.
virtual const char* what( void ) const throw() { return message_.c_str(); }

View File

@@ -8,7 +8,7 @@
RtMidi WWW site: http://music.mcgill.ca/~gary/rtmidi/
RtMidi: realtime MIDI i/o C++ classes
Copyright (c) 2003-2010 Gary P. Scavone
Copyright (c) 2003-2011 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.11
// RtMidi: Version 1.0.15
#ifndef RTMIDI_H
#define RTMIDI_H
@@ -96,7 +96,6 @@ class RtMidi
/**********************************************************************/
#include <vector>
#include <queue>
class RtMidiIn : public RtMidi
{
@@ -105,11 +104,15 @@ class RtMidiIn : public RtMidi
//! User callback function type definition.
typedef void (*RtMidiCallback)( double timeStamp, std::vector<unsigned char> *message, void *userData);
//! Default constructor that allows an optional client name.
//! Default constructor that allows an optional client name and queue size.
/*!
An exception will be thrown if a MIDI system initialization error occurs.
An exception will be thrown if a MIDI system initialization
error occurs. The queue size defines the maximum number of
messages that can be held in the MIDI queue (when not using a
callback function). If the queue size limit is reached,
incoming messages will be ignored.
*/
RtMidiIn( const std::string clientName = std::string( "RtMidi Input Client") );
RtMidiIn( const std::string clientName = std::string( "RtMidi Input Client"), unsigned int queueSizeLimit = 100 );
//! If a MIDI connection is still open, it will be closed by the destructor.
~RtMidiIn();
@@ -154,20 +157,13 @@ class RtMidiIn : public RtMidi
//! Return a string identifier for the specified MIDI input port number.
/*!
An exception is thrown if an invalid port specifier is provided.
An empty string is returned if an invalid port specifier is provided.
*/
std::string getPortName( unsigned int portNumber = 0 );
//! Set the maximum number of MIDI messages to be saved in the queue.
/*!
If the queue size limit is reached, incoming messages will be
ignored. The default limit is 1024.
*/
void setQueueSizeLimit( unsigned int queueSize );
//! Specify whether certain MIDI message types should be queued or ignored during input.
/*!
By default, MIDI timing and active sensing messages are ignored
o By default, MIDI timing and active sensing messages are ignored
during message input because of their relative high data rates.
MIDI sysex messages are ignored by default as well. Variable
values of "true" imply that the respective message type will be
@@ -193,15 +189,26 @@ class RtMidiIn : public RtMidi
// Default constructor.
MidiMessage()
:bytes(3), timeStamp(0.0) {}
:bytes(0), timeStamp(0.0) {}
};
struct MidiQueue {
unsigned int front;
unsigned int back;
unsigned int size;
unsigned int ringSize;
MidiMessage *ring;
// Default constructor.
MidiQueue()
:front(0), back(0), size(0), ringSize(0) {}
};
// The RtMidiInData structure is used to pass private class data to
// the MIDI input handling function or thread.
struct RtMidiInData {
std::queue<MidiMessage> queue;
MidiQueue queue;
MidiMessage message;
unsigned int queueLimit;
unsigned char ignoreFlags;
bool doInput;
bool firstMessage;
@@ -213,7 +220,7 @@ class RtMidiIn : public RtMidi
// Default constructor.
RtMidiInData()
: queueLimit(1024), ignoreFlags(7), doInput(false), firstMessage(true),
: ignoreFlags(7), doInput(false), firstMessage(true),
apiData(0), usingCallback(false), userCallback(0), userData(0),
continueSysex(false) {}
};
@@ -280,7 +287,7 @@ class RtMidiOut : public RtMidi
//! Return a string identifier for the specified MIDI port type and number.
/*!
An exception is thrown if an invalid port specifier is provided.
An empty string is returned if an invalid port specifier is provided.
*/
std::string getPortName( unsigned int portNumber = 0 );

View File

@@ -24,7 +24,7 @@ namespace stk {
that takes an StkFrames object for multi-channel and/or
multi-frame data.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -112,7 +112,7 @@ 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!";
oStream_ << "RtWvIn::lastOut(): channel argument and audio stream are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -23,7 +23,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -9,7 +9,7 @@
where <name> is the string used in the SKINI stream.
by Perry R. Cook, 1995 - 2010.
by Perry R. Cook, 1995-2011.
*/
/*********************************************************/

View File

@@ -15,7 +15,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -49,6 +49,16 @@ class Sampler : public Instrmnt
//! Compute and return one output sample.
virtual StkFloat tick( unsigned int channel = 0 ) = 0;
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ) = 0;
protected:
ADSR adsr_;

View File

@@ -44,7 +44,7 @@ namespace stk {
- Vibrato Gain = 1
- Breath Pressure = 128
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -87,6 +87,16 @@ class Saxofony : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
DelayL delays_[2];
@@ -95,7 +105,7 @@ class Saxofony : public Instrmnt
Envelope envelope_;
Noise noise_;
SineWave vibrato_;
unsigned long length_;
StkFloat outputGain_;
StkFloat noiseGain_;
StkFloat vibratoGain_;
@@ -124,6 +134,33 @@ inline StkFloat Saxofony :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& Saxofony :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Saxofony::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -55,7 +55,7 @@ namespace stk {
- Little Rocks = 21
- Tuned Bamboo Chimes = 22
by Perry R. Cook, 1996 - 2010.
by Perry R. Cook, 1995-2011.
*/
/***************************************************/
@@ -87,6 +87,16 @@ class Shakers : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
int setupName( char* instr );
@@ -126,6 +136,33 @@ class Shakers : public Instrmnt
};
inline StkFrames& Shakers :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Shakers::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -25,7 +25,7 @@ namespace stk {
- Envelope Rate = 11
- Gain = 128
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -65,6 +65,16 @@ class Simple : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
ADSR adsr_;
@@ -87,6 +97,33 @@ inline StkFloat Simple :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& Simple :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Simple::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -18,7 +18,7 @@ namespace stk {
The "table" length, set in SineWave.h, is 2048 samples by default.
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -121,7 +121,7 @@ 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!";
oStream_ << "SineWave::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -18,7 +18,7 @@ namespace stk {
Within STK, it is used as an excitation source for other
instruments.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -118,7 +118,7 @@ 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!";
oStream_ << "SingWave::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -25,7 +25,7 @@ namespace stk {
Stanford, bearing the names of Karplus and/or
Strong.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -33,7 +33,7 @@ class Sitar : public Instrmnt
{
public:
//! Class constructor, taking the lowest desired playing frequency.
Sitar( StkFloat lowestFrequency = 20 );
Sitar( StkFloat lowestFrequency = 8.0 );
//! Class destructor.
~Sitar( void );
@@ -56,6 +56,16 @@ class Sitar : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
DelayA delayLine_;
@@ -86,6 +96,33 @@ inline StkFloat Sitar :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& Sitar :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Sitar::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -31,7 +31,7 @@ namespace stk {
\sa \ref skini
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -95,24 +95,25 @@ class Skini : public Stk
std::ifstream file_;
};
//! A static table of equal-tempered MIDI to frequency (Hz) values.
static const double Midi2Pitch[129] = {
8.18,8.66,9.18,9.72,10.30,10.91,11.56,12.25,
12.98,13.75,14.57,15.43,16.35,17.32,18.35,19.45,
20.60,21.83,23.12,24.50,25.96,27.50,29.14,30.87,
32.70,34.65,36.71,38.89,41.20,43.65,46.25,49.00,
51.91,55.00,58.27,61.74,65.41,69.30,73.42,77.78,
82.41,87.31,92.50,98.00,103.83,110.00,116.54,123.47,
130.81,138.59,146.83,155.56,164.81,174.61,185.00,196.00,
207.65,220.00,233.08,246.94,261.63,277.18,293.66,311.13,
329.63,349.23,369.99,392.00,415.30,440.00,466.16,493.88,
523.25,554.37,587.33,622.25,659.26,698.46,739.99,783.99,
830.61,880.00,932.33,987.77,1046.50,1108.73,1174.66,1244.51,
1318.51,1396.91,1479.98,1567.98,1661.22,1760.00,1864.66,1975.53,
2093.00,2217.46,2349.32,2489.02,2637.02,2793.83,2959.96,3135.96,
3322.44,3520.00,3729.31,3951.07,4186.01,4434.92,4698.64,4978.03,
5274.04,5587.65,5919.91,6271.93,6644.88,7040.00,7458.62,7902.13,
8372.02,8869.84,9397.27,9956.06,10548.08,11175.30,11839.82,12543.85,
13289.75};
8.176, 8.662, 9.177, 9.723, 10.301, 10.913, 11.562, 12.25,
12.978, 13.75, 14.568, 15.434, 16.352, 17.324, 18.354, 19.445,
20.602, 21.827, 23.125, 24.50, 25.957, 27.50, 29.135, 30.868,
32.703, 34.648, 36.708, 38.891, 41.203, 43.654, 46.249, 49.0,
51.913, 55.0, 58.271, 61.735, 65.406, 69.296, 73.416, 77.782,
82.407, 87.307, 92.499, 97.999, 103.826, 110.0, 116.541, 123.471,
130.813, 138.591, 146.832, 155.563, 164.814, 174.614, 184.997, 195.998,
207.652, 220.0, 233.082, 246.942, 261.626, 277.183, 293.665, 311.127,
329.628, 349.228, 369.994, 391.995, 415.305, 440.0, 466.164, 493.883,
523.251, 554.365, 587.33, 622.254, 659.255, 698.456, 739.989, 783.991,
830.609, 880.0, 932.328, 987.767, 1046.502, 1108.731, 1174.659, 1244.508,
1318.51, 1396.913, 1479.978, 1567.982, 1661.219, 1760.0, 1864.655, 1975.533,
2093.005, 2217.461, 2349.318, 2489.016, 2637.02, 2793.826, 2959.955, 3135.963,
3322.438, 3520.0, 3729.31, 3951.066, 4186.009, 4434.922, 4698.636, 4978.032,
5274.041, 5587.652, 5919.911, 6271.927, 6644.875, 7040.0, 7458.62, 7902.133,
8372.018, 8869.844, 9397.273, 9956.063, 10548.082, 11175.303, 11839.822, 12543.854,
13289.75};
} // stk namespace

View File

@@ -31,7 +31,7 @@ namespace stk {
number of static functions for use with external socket
descriptors.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -13,7 +13,7 @@ namespace stk {
This class implements a spherical ball with
radius, mass, position, and velocity parameters.
by Perry R. Cook, 1995 - 2010.
by Perry R. Cook, 1995-2011.
*/
/***************************************************/

View File

@@ -29,7 +29,7 @@ namespace stk {
- String Sustain = 11
- String Stretch = 1
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -37,7 +37,7 @@ class StifKarp : public Instrmnt
{
public:
//! Class constructor, taking the lowest desired playing frequency.
StifKarp( StkFloat lowestFrequency );
StifKarp( StkFloat lowestFrequency = 8.0 );
//! Class destructor.
~StifKarp( void );
@@ -77,6 +77,16 @@ class StifKarp : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
DelayA delayLine_;
@@ -112,6 +122,33 @@ inline StkFloat StifKarp :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& StifKarp :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "StifKarp::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -39,7 +39,7 @@ namespace stk {
STK WWW site: http://ccrma.stanford.edu/software/stk/
The Synthesis ToolKit in C++ (STK)
Copyright (c) 1995-2010 Perry R. Cook and Gary P. Scavone
Copyright (c) 1995-2011 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
@@ -87,7 +87,7 @@ public:
enum Type {
STATUS,
WARNING,
DEBUG_WARNING,
DEBUG_PRINT,
MEMORY_ALLOCATION,
MEMORY_ACCESS,
FUNCTION_ARGUMENT,
@@ -135,7 +135,7 @@ public:
typedef unsigned long StkFormat;
static const StkFormat STK_SINT8; /*!< -128 to +127 */
static const StkFormat STK_SINT16; /*!< -32768 to +32767 */
static const StkFormat STK_SINT24; /*!< Upper 3 bytes of 32-bit signed integer. */
static const StkFormat STK_SINT24; /*!< Lower 3 bytes of 32-bit signed integer. */
static const StkFormat STK_SINT32; /*!< -2147483648 to +2147483647. */
static const StkFormat STK_FLOAT32; /*!< Normalized between plus/minus 1.0. */
static const StkFormat STK_FLOAT64; /*!< Normalized between plus/minus 1.0. */
@@ -189,6 +189,13 @@ public:
//! Static cross-platform method to sleep for a number of milliseconds.
static void sleep( unsigned long milliseconds );
//! Static method to check whether a value is within a specified range.
static bool inRange( StkFloat value, StkFloat min, StkFloat max ) {
if ( value < min ) return false;
else if ( value > max ) return false;
else return true;
}
//! Static function for error reporting and handling using c-strings.
static void handleError( const char *message, StkError::Type type );
@@ -210,7 +217,7 @@ private:
protected:
std::ostringstream errorString_;
static std::ostringstream oStream_;
bool ignoreSampleRateChange_;
//! Default constructor.
@@ -228,7 +235,7 @@ protected:
//! Remove class pointer from list for sample rate change notification.
void removeSampleRateAlert( Stk *ptr );
//! Internal function for error reporting that assumes message in \c errorString_ variable.
//! Internal function for error reporting that assumes message in \c oStream_ variable.
void handleError( StkError::Type type );
};
@@ -251,10 +258,13 @@ protected:
StkFloat* ptr = &myStkFrames[0];
Note that this class can also be used as a table with interpolating
lookup.
Possible future improvements in this class could include functions
to convert to and return other data types.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -17,7 +17,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -116,7 +116,7 @@ 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!";
oStream_ << "TapDelay::lastOut(): tap argument and number of taps are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -128,7 +128,7 @@ 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!";
oStream_ << "TapDelay::tick(): number of taps > channels in StkFrames argument!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -155,11 +155,11 @@ 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!";
oStream_ << "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!";
oStream_ << "TapDelay::tick(): number of taps > channels in StkFrames argument!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -185,11 +185,11 @@ inline StkFrames& TapDelay :: tick( StkFrames& iFrames, StkFrames& oFrames, unsi
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() ) {
errorString_ << "TapDelay::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "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!";
oStream_ << "TapDelay::tick(): number of taps > channels in output StkFrames argument!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -26,7 +26,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -26,7 +26,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -42,7 +42,7 @@ namespace stk {
THREAD_RETURN THREAD_TYPE thread_function(void *ptr)
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -33,7 +33,7 @@ namespace stk {
type who should worry about this (making
money) worry away.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -55,6 +55,16 @@ class TubeBell : public FM
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
};
@@ -83,6 +93,33 @@ inline StkFloat TubeBell :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& TubeBell :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "TubeBell::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

158
include/Twang.h Normal file
View File

@@ -0,0 +1,158 @@
#ifndef STK_TWANG_H
#define STK_TWANG_H
#include "Stk.h"
#include "DelayA.h"
#include "DelayL.h"
#include "Fir.h"
namespace stk {
/***************************************************/
/*! \class Twang
\brief STK enhanced plucked string class.
This class implements an enhanced plucked-string
physical model, a la Jaffe-Smith, Smith,
Karjalainen and others. It includes a comb
filter to simulate pluck position. The tick()
function takes an input sample, which is added
to the delayline input. This can be used to
implement commuted synthesis (if the input
samples are derived from the impulse response of
a body filter) and/or feedback (as in an electric
guitar model).
This is a digital waveguide model, making its
use possibly subject to patents held by Stanford
University, Yamaha, and others.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
class Twang : public Stk
{
public:
//! Class constructor, taking the lowest desired playing frequency.
Twang( StkFloat lowestFrequency = 50.0 );
//! Class destructor.
~Twang( void );
//! Reset and clear all internal state.
void clear( void );
//! Set the delayline parameters to allow frequencies as low as specified.
void setLowestFrequency( StkFloat frequency );
//! Set the delayline parameters for a particular frequency.
void setFrequency( StkFloat frequency );
//! Set the pluck or "excitation" position along the string (0.0 - 1.0).
void setPluckPosition( StkFloat position );
//! Set the nominal loop gain.
/*!
The actual loop gain is based on the value set with this
function, but scaled slightly according to the frequency. Higher
frequency settings have greater loop gains because of
high-frequency loop-filter roll-off.
*/
void setLoopGain( StkFloat loopGain );
//! Set the loop filter coefficients.
/*!
The loop filter can be any arbitrary FIR filter. By default,
the coefficients are set for a first-order lowpass filter with
coefficients b = [0.5 0.5].
*/
void setLoopFilter( std::vector<StkFloat> coefficients );
//! Return an StkFrames reference to the last output sample frame.
const StkFrames& lastFrame( void ) const { return lastFrame_; };
//! Compute and return one output sample.
StkFloat tick( StkFloat input );
//! Take a channel of the \c iFrames object as inputs to the class 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& 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:
DelayA delayLine_;
DelayL combDelay_;
Fir loopFilter_;
StkFrames lastFrame_;
StkFloat frequency_;
StkFloat loopGain_;
StkFloat pluckPosition_;
};
inline StkFloat Twang :: tick( StkFloat input )
{
lastFrame_[0] = delayLine_.tick( input + loopFilter_.tick( delayLine_.lastOut() ) );
lastFrame_[0] -= combDelay_.tick( lastFrame_[0] ); // comb filtering on output
return lastFrame_[0] * 0.5;
}
inline StkFrames& Twang :: tick( StkFrames& frames, unsigned int channel )
{
#if defined(_STK_DEBUG_)
if ( channel >= frames.channels() ) {
oStream_ << "Twang::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& Twang :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
oStream_ << "Twang::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

View File

@@ -13,7 +13,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -53,8 +53,10 @@ class TwoPole : public Filter
resulting filter frequency response has a resonance at the given
\e frequency. The closer the poles are to the unit-circle (\e
radius close to one), the narrower the resulting resonance width.
An unstable filter will result for \e radius >= 1.0. For a better
resonance filter, use a BiQuad filter. \sa BiQuad filter class
An unstable filter will result for \e radius >= 1.0. The
\e frequency value should be between zero and half the sample rate.
For a better resonance filter, use a BiQuad filter. \sa BiQuad
filter class
*/
void setResonance(StkFloat frequency, StkFloat radius, bool normalize = false);
@@ -105,7 +107,7 @@ 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!";
oStream_ << "TwoPole::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -127,7 +129,7 @@ inline StkFrames& TwoPole :: tick( StkFrames& iFrames, StkFrames& oFrames, unsig
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "TwoPole::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "TwoPole::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -13,7 +13,7 @@ namespace stk {
provided for creating a "notch" in the frequency response while
maintaining a constant filter gain.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -51,6 +51,8 @@ class TwoZero : public Filter
response has a "notch" or anti-resonance at the given \e
frequency. The closer the zeros are to the unit-circle (\e radius
close to or equal to one), the narrower the resulting notch width.
The \e frequency value should be between zero and half the sample
rate. The \e radius value should be positive.
*/
void setNotch( StkFloat frequency, StkFloat radius );
@@ -101,7 +103,7 @@ 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!";
oStream_ << "TwoZero::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -123,7 +125,7 @@ inline StkFrames& TwoZero :: tick( StkFrames& iFrames, StkFrames& oFrames, unsig
{
#if defined(_STK_DEBUG_)
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
errorString_ << "TwoZero::tick(): channel and StkFrames arguments are incompatible!";
oStream_ << "TwoZero::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -24,7 +24,7 @@ namespace stk {
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 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/

View File

@@ -12,7 +12,7 @@ namespace stk {
This class implements a three-dimensional vector.
by Perry R. Cook, 1995 - 2010.
by Perry R. Cook, 1995-2011.
*/
/***************************************************/

View File

@@ -34,7 +34,7 @@ namespace stk {
- Vibrato Gain = 1
- Loudness (Spectral Tilt) = 128
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -89,6 +89,16 @@ class VoicForm : public Instrmnt
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
SingWave *voiced_;
@@ -119,6 +129,33 @@ inline StkFloat VoicForm :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& VoicForm :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "VoicForm::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -27,7 +27,7 @@ namespace stk {
Alternately, control changes can be sent to all voices in a given
group.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -166,7 +166,7 @@ inline StkFloat Voicer :: lastOut( unsigned int channel )
{
#if defined(_STK_DEBUG_)
if ( channel >= lastFrame_.channels() ) {
errorString_ << "Voicer::lastOut(): channel argument is invalid!";
oStream_ << "Voicer::lastOut(): channel argument is invalid!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
@@ -198,7 +198,7 @@ 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!";
oStream_ << "Voicer::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif

View File

@@ -25,7 +25,7 @@ namespace stk {
- Blowing Frequency Modulation = 2
- Volume = 128
by Perry R. Cook 1996 - 2010.
by Perry R. Cook 1995-2011.
*/
/***************************************************/
@@ -65,6 +65,16 @@ public:
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
Vector3D *tempVectorP_;
@@ -87,5 +97,32 @@ protected:
int subSample_, subSampCount_;
};
inline StkFrames& Whistle :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Whistle::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

View File

@@ -33,7 +33,7 @@ namespace stk {
type who should worry about this (making
money) worry away.
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
by Perry R. Cook and Gary P. Scavone, 1995-2011.
*/
/***************************************************/
@@ -58,6 +58,16 @@ class Wurley : public FM
//! Compute and return one output sample.
StkFloat tick( unsigned int channel = 0 );
//! Fill a channel of the StkFrames object with computed outputs.
/*!
The \c channel argument must be less than the number of
channels in the StkFrames argument (the first channel is specified
by 0). However, range checking is only performed if _STK_DEBUG_
is defined during compilation, in which case an out-of-range value
will trigger an StkError exception.
*/
StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
protected:
};
@@ -86,6 +96,33 @@ inline StkFloat Wurley :: tick( unsigned int )
return lastFrame_[0];
}
inline StkFrames& Wurley :: tick( StkFrames& frames, unsigned int channel )
{
unsigned int nChannels = lastFrame_.channels();
#if defined(_STK_DEBUG_)
if ( channel > frames.channels() - nChannels ) {
oStream_ << "Wurley::tick(): channel and StkFrames arguments are incompatible!";
handleError( StkError::FUNCTION_ARGUMENT );
}
#endif
StkFloat *samples = &frames[channel];
unsigned int j, hop = frames.channels() - nChannels;
if ( nChannels == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
*samples++ = tick();
}
else {
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
*samples++ = tick();
for ( j=1; j<nChannels; j++ )
*samples++ = lastFrame_[j];
}
}
return frames;
}
} // stk namespace
#endif

Some files were not shown because too many files have changed in this diff Show More