mirror of
https://github.com/thestk/stk
synced 2026-04-22 23:44:36 +00:00
Version 4.4.3
This commit is contained in:
committed by
Stephen Sinclair
parent
baca57040b
commit
0aec39260a
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
138
include/Cubic.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
12
include/FM.h
12
include/FM.h
@@ -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_;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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.
|
||||
/*!
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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). */
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/*********************************************************/
|
||||
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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
158
include/Twang.h
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user