mirror of
https://github.com/thestk/stk
synced 2026-01-19 07:31:52 +00:00
Version 4.4.3
This commit is contained in:
committed by
Stephen Sinclair
parent
baca57040b
commit
0aec39260a
115
src/ADSR.cpp
115
src/ADSR.cpp
@@ -2,12 +2,14 @@
|
||||
/*! \class ADSR
|
||||
\brief STK ADSR envelope class.
|
||||
|
||||
This class implements a traditional ADSR (Attack, Decay, Sustain,
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -22,8 +24,9 @@ ADSR :: ADSR( void )
|
||||
attackRate_ = 0.001;
|
||||
decayRate_ = 0.001;
|
||||
releaseRate_ = 0.005;
|
||||
releaseTime_ = -1.0;
|
||||
sustainLevel_ = 0.5;
|
||||
state_ = ATTACK;
|
||||
state_ = IDLE;
|
||||
Stk::addSampleRateAlert( this );
|
||||
}
|
||||
|
||||
@@ -42,7 +45,7 @@ void ADSR :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
|
||||
|
||||
void ADSR :: keyOn()
|
||||
{
|
||||
target_ = 1.0;
|
||||
if ( target_ <= 0.0 ) target_ = 1.0;
|
||||
state_ = ATTACK;
|
||||
}
|
||||
|
||||
@@ -50,76 +53,97 @@ void ADSR :: keyOff()
|
||||
{
|
||||
target_ = 0.0;
|
||||
state_ = RELEASE;
|
||||
|
||||
// FIXED October 2010 - Nick Donaldson
|
||||
// Need to make release rate relative to current value!!
|
||||
// Only update if we have set a TIME rather than a RATE,
|
||||
// in which case releaseTime_ will be -1
|
||||
if ( releaseTime_ > 0.0 )
|
||||
releaseRate_ = value_ / ( releaseTime_ * Stk::sampleRate() );
|
||||
}
|
||||
|
||||
void ADSR :: setAttackRate( StkFloat rate )
|
||||
{
|
||||
if ( rate < 0.0 ) {
|
||||
errorString_ << "ADSR::setAttackRate: negative rates not allowed ... correcting!";
|
||||
handleError( StkError::WARNING );
|
||||
attackRate_ = -rate;
|
||||
oStream_ << "ADSR::setAttackRate: argument must be >= 0.0!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else attackRate_ = rate;
|
||||
|
||||
attackRate_ = rate;
|
||||
}
|
||||
|
||||
void ADSR :: setAttackTarget( StkFloat target )
|
||||
{
|
||||
if ( target < 0.0 ) {
|
||||
oStream_ << "ADSR::setAttackTarget: negative target not allowed!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
target_ = target;
|
||||
}
|
||||
|
||||
void ADSR :: setDecayRate( StkFloat rate )
|
||||
{
|
||||
if ( rate < 0.0 ) {
|
||||
errorString_ << "ADSR::setDecayRate: negative rates not allowed ... correcting!";
|
||||
handleError( StkError::WARNING );
|
||||
decayRate_ = -rate;
|
||||
oStream_ << "ADSR::setDecayRate: negative rates not allowed!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else decayRate_ = rate;
|
||||
|
||||
decayRate_ = rate;
|
||||
}
|
||||
|
||||
void ADSR :: setSustainLevel( StkFloat level )
|
||||
{
|
||||
if ( level < 0.0 ) {
|
||||
errorString_ << "ADSR::setSustainLevel: level out of range ... correcting!";
|
||||
handleError( StkError::WARNING );
|
||||
sustainLevel_ = 0.0;
|
||||
oStream_ << "ADSR::setSustainLevel: negative level not allowed!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else sustainLevel_ = level;
|
||||
|
||||
sustainLevel_ = level;
|
||||
}
|
||||
|
||||
void ADSR :: setReleaseRate( StkFloat rate )
|
||||
{
|
||||
if ( rate < 0.0 ) {
|
||||
errorString_ << "ADSR::setReleaseRate: negative rates not allowed ... correcting!";
|
||||
handleError( StkError::WARNING );
|
||||
releaseRate_ = -rate;
|
||||
oStream_ << "ADSR::setReleaseRate: negative rates not allowed!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else releaseRate_ = rate;
|
||||
|
||||
releaseRate_ = rate;
|
||||
|
||||
// Set to negative value so we don't update the release rate on keyOff()
|
||||
releaseTime_ = -1.0;
|
||||
}
|
||||
|
||||
void ADSR :: setAttackTime( StkFloat time )
|
||||
{
|
||||
if ( time < 0.0 ) {
|
||||
errorString_ << "ADSR::setAttackTime: negative times not allowed ... correcting!";
|
||||
handleError( StkError::WARNING );
|
||||
attackRate_ = 1.0 / ( -time * Stk::sampleRate() );
|
||||
if ( time <= 0.0 ) {
|
||||
oStream_ << "ADSR::setAttackTime: negative or zero times not allowed!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else attackRate_ = 1.0 / ( time * Stk::sampleRate() );
|
||||
|
||||
attackRate_ = 1.0 / ( time * Stk::sampleRate() );
|
||||
}
|
||||
|
||||
void ADSR :: setDecayTime( StkFloat time )
|
||||
{
|
||||
if ( time < 0.0 ) {
|
||||
errorString_ << "ADSR::setDecayTime: negative times not allowed ... correcting!";
|
||||
handleError( StkError::WARNING );
|
||||
decayRate_ = 1.0 / ( -time * Stk::sampleRate() );
|
||||
if ( time <= 0.0 ) {
|
||||
oStream_ << "ADSR::setDecayTime: negative or zero times not allowed!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else decayRate_ = 1.0 / ( time * Stk::sampleRate() );
|
||||
|
||||
decayRate_ = (1.0 - sustainLevel_) / ( time * Stk::sampleRate() );
|
||||
}
|
||||
|
||||
void ADSR :: setReleaseTime( StkFloat time )
|
||||
{
|
||||
if ( time < 0.0 ) {
|
||||
errorString_ << "ADSR::setReleaseTime: negative times not allowed ... correcting!";
|
||||
handleError( StkError::WARNING );
|
||||
releaseRate_ = sustainLevel_ / ( -time * Stk::sampleRate() );
|
||||
if ( time <= 0.0 ) {
|
||||
oStream_ << "ADSR::setReleaseTime: negative or zero times not allowed!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else releaseRate_ = sustainLevel_ / ( time * Stk::sampleRate() );
|
||||
|
||||
releaseRate_ = sustainLevel_ / ( time * Stk::sampleRate() );
|
||||
releaseTime_ = time;
|
||||
}
|
||||
|
||||
void ADSR :: setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFloat rTime )
|
||||
@@ -132,15 +156,16 @@ void ADSR :: setAllTimes( StkFloat aTime, StkFloat dTime, StkFloat sLevel, StkFl
|
||||
|
||||
void ADSR :: setTarget( StkFloat target )
|
||||
{
|
||||
if ( target < 0.0 ) {
|
||||
oStream_ << "ADSR::setTarget: negative target not allowed!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
target_ = target;
|
||||
if ( value_ < target_ ) {
|
||||
state_ = ATTACK;
|
||||
this->setSustainLevel( target_ );
|
||||
}
|
||||
if ( value_ > target_ ) {
|
||||
this->setSustainLevel( target_ );
|
||||
state_ = DECAY;
|
||||
}
|
||||
|
||||
this->setSustainLevel( target_ );
|
||||
if ( value_ < target_ ) state_ = ATTACK;
|
||||
if ( value_ > target_ ) state_ = DECAY;
|
||||
}
|
||||
|
||||
void ADSR :: setValue( StkFloat value )
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -63,9 +63,8 @@ void Asymp :: keyOff( void )
|
||||
void Asymp :: setTau( StkFloat tau )
|
||||
{
|
||||
if ( tau <= 0.0 ) {
|
||||
errorString_ << "Asymp::setTau: negative or zero tau not allowed ... ignoring!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
oStream_ << "Asymp::setTau: negative or zero tau not allowed!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
factor_ = std::exp( -1.0 / ( tau * Stk::sampleRate() ) );
|
||||
@@ -75,9 +74,8 @@ void Asymp :: setTau( StkFloat tau )
|
||||
void Asymp :: setTime( StkFloat time )
|
||||
{
|
||||
if ( time <= 0.0 ) {
|
||||
errorString_ << "Asymp::setTime: negative or zero times not allowed ... ignoring!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
oStream_ << "Asymp::setTime: negative or zero times not allowed!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
StkFloat tau = -time / std::log( TARGET_THRESHOLD );
|
||||
@@ -85,6 +83,16 @@ void Asymp :: setTime( StkFloat time )
|
||||
constant_ = ( 1.0 - factor_ ) * target_;
|
||||
}
|
||||
|
||||
void Asymp :: setT60( StkFloat t60 )
|
||||
{
|
||||
if ( t60 <= 0.0 ) {
|
||||
oStream_ << "Asymp::setT60: negative or zero t60 not allowed!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
setTau( t60 / 6.91 );
|
||||
}
|
||||
|
||||
void Asymp :: setTarget( StkFloat target )
|
||||
{
|
||||
target_ = target;
|
||||
|
||||
@@ -40,13 +40,13 @@ BandedWG :: BandedWG( void )
|
||||
doPluck_ = true;
|
||||
|
||||
bowTable_.setSlope( 3.0 );
|
||||
adsr_.setAllTimes( 0.02, 0.005, 0.9, 0.01);
|
||||
adsr_.setAllTimes( 0.02, 0.005, 0.9, 0.01 );
|
||||
|
||||
frequency_ = 220.0;
|
||||
this->setPreset(0);
|
||||
|
||||
bowPosition_ = 0;
|
||||
baseGain_ = (StkFloat) 0.999;
|
||||
baseGain_ = 0.999;
|
||||
|
||||
integrationConstant_ = 0.0;
|
||||
trackVelocity_ = false;
|
||||
@@ -171,16 +171,17 @@ void BandedWG :: setPreset( int preset )
|
||||
|
||||
void BandedWG :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
frequency_ = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "BandedWG::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
frequency_ = 220.0;
|
||||
oStream_ << "BandedWG::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
if (frequency_ > 1568.0) frequency_ = 1568.0;
|
||||
#endif
|
||||
|
||||
if (frequency > 1568.0) frequency = 1568.0;
|
||||
|
||||
StkFloat radius;
|
||||
StkFloat base = Stk::sampleRate() / frequency_;
|
||||
StkFloat base = Stk::sampleRate() / frequency;
|
||||
StkFloat length;
|
||||
for (int i=0; i<presetModes_; i++) {
|
||||
// Calculate the delay line lengths for each mode.
|
||||
@@ -200,7 +201,7 @@ void BandedWG :: setFrequency( StkFloat frequency )
|
||||
// Set the bandpass filter resonances
|
||||
radius = 1.0 - PI * 32 / Stk::sampleRate(); //frequency_ * modes_[i] / Stk::sampleRate()/32;
|
||||
if ( radius < 0.0 ) radius = 0.0;
|
||||
bandpass_[i].setResonance(frequency_ * modes_[i], radius, true);
|
||||
bandpass_[i].setResonance(frequency * modes_[i], radius, true);
|
||||
|
||||
delay_[i].clear();
|
||||
bandpass_[i].clear();
|
||||
@@ -241,28 +242,18 @@ void BandedWG :: pluck( StkFloat amplitude )
|
||||
|
||||
void BandedWG :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
{
|
||||
this->setFrequency(frequency);
|
||||
this->setFrequency( frequency );
|
||||
|
||||
if ( doPluck_ )
|
||||
this->pluck(amplitude);
|
||||
this->pluck( amplitude );
|
||||
else
|
||||
this->startBowing(amplitude, amplitude * 0.001);
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BandedWG::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
this->startBowing( amplitude, amplitude * 0.001 );
|
||||
}
|
||||
|
||||
void BandedWG :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
if ( !doPluck_ )
|
||||
this->stopBowing((1.0 - amplitude) * 0.005);
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BandedWG::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
this->stopBowing( (1.0 - amplitude) * 0.005 );
|
||||
}
|
||||
|
||||
StkFloat BandedWG :: tick( unsigned int )
|
||||
@@ -311,51 +302,47 @@ StkFloat BandedWG :: tick( unsigned int )
|
||||
|
||||
void BandedWG :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "BandedWG::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "BandedWG::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( value < 0 || ( number != 101 && value > 128.0 ) ) {
|
||||
oStream_ << "BandedWG::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_BowPressure_) { // 2
|
||||
if ( norm == 0.0 )
|
||||
if ( normalizedValue == 0.0 )
|
||||
doPluck_ = true;
|
||||
else {
|
||||
doPluck_ = false;
|
||||
bowTable_.setSlope( 10.0 - (9.0 * norm));
|
||||
bowTable_.setSlope( 10.0 - (9.0 * normalizedValue));
|
||||
}
|
||||
}
|
||||
else if (number == 4) { // 4
|
||||
if ( !trackVelocity_ ) trackVelocity_ = true;
|
||||
bowTarget_ += 0.005 * (norm - bowPosition_);
|
||||
bowPosition_ = norm;
|
||||
bowTarget_ += 0.005 * (normalizedValue - bowPosition_);
|
||||
bowPosition_ = normalizedValue;
|
||||
//adsr_.setTarget(bowPosition_);
|
||||
}
|
||||
else if (number == 8) // 8
|
||||
this->setStrikePosition( norm );
|
||||
this->setStrikePosition( normalizedValue );
|
||||
else if (number == __SK_AfterTouch_Cont_) { // 128
|
||||
//bowTarget_ += 0.02 * (norm - bowPosition_);
|
||||
//bowPosition_ = norm;
|
||||
//bowTarget_ += 0.02 * (normalizedValue - bowPosition_);
|
||||
//bowPosition_ = normalizedValue;
|
||||
if ( trackVelocity_ ) trackVelocity_ = false;
|
||||
maxVelocity_ = 0.13 * norm;
|
||||
adsr_.setTarget(norm);
|
||||
maxVelocity_ = 0.13 * normalizedValue;
|
||||
adsr_.setTarget(normalizedValue);
|
||||
}
|
||||
else if (number == __SK_ModWheel_) { // 1
|
||||
// baseGain_ = 0.9989999999 + (0.001 * norm );
|
||||
baseGain_ = 0.8999999999999999 + (0.1 * norm);
|
||||
// baseGain_ = 0.9989999999 + (0.001 * normalizedValue );
|
||||
baseGain_ = 0.8999999999999999 + (0.1 * normalizedValue);
|
||||
// std::cerr << "Yuck!" << std::endl;
|
||||
for (int i=0; i<nModes_; i++)
|
||||
gains_[i]=(StkFloat) basegains_[i]*baseGain_;
|
||||
// gains_[i]=(StkFloat) pow(baseGain_, (int)((StkFloat)delay_[i].getDelay()+i));
|
||||
}
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
integrationConstant_ = norm;
|
||||
integrationConstant_ = normalizedValue;
|
||||
else if (number == __SK_Sustain_) { // 64
|
||||
if (value < 65) doPluck_ = true;
|
||||
else doPluck_ = false;
|
||||
@@ -365,15 +352,12 @@ void BandedWG :: controlChange( int number, StkFloat value )
|
||||
else trackVelocity_ = true;
|
||||
}
|
||||
else if (number == __SK_ProphesyRibbon_) // 16
|
||||
this->setPreset((int) value);
|
||||
this->setPreset((int) value);
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
errorString_ << "BandedWG::controlChange: undefined control number (" << number << ")!";
|
||||
oStream_ << "BandedWG::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BandedWG::controlChange: number = " << number << ", value = " << value << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -74,11 +74,6 @@ void BeeThree :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
gains_[3] = amplitude * fmGains_[95];
|
||||
this->setFrequency( frequency );
|
||||
this->keyOn();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BeeThree::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -46,13 +46,24 @@ void BiQuad :: setCoefficients( StkFloat b0, StkFloat b1, StkFloat b2, StkFloat
|
||||
void BiQuad :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
|
||||
{
|
||||
if ( !ignoreSampleRateChange_ ) {
|
||||
errorString_ << "BiQuad::sampleRateChanged: you may need to recompute filter coefficients!";
|
||||
oStream_ << "BiQuad::sampleRateChanged: you may need to recompute filter coefficients!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
}
|
||||
|
||||
void BiQuad :: setResonance(StkFloat frequency, StkFloat radius, bool normalize)
|
||||
void BiQuad :: setResonance( StkFloat frequency, StkFloat radius, bool normalize )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
|
||||
oStream_ << "BiQuad::setResonance: frequency argument (" << frequency << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
if ( radius < 0.0 || radius >= 1.0 ) {
|
||||
oStream_ << "BiQuad::setResonance: radius argument (" << radius << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
a_[2] = radius * radius;
|
||||
a_[1] = -2.0 * radius * cos( TWO_PI * frequency / Stk::sampleRate() );
|
||||
|
||||
@@ -64,14 +75,25 @@ void BiQuad :: setResonance(StkFloat frequency, StkFloat radius, bool normalize)
|
||||
}
|
||||
}
|
||||
|
||||
void BiQuad :: setNotch(StkFloat frequency, StkFloat radius)
|
||||
void BiQuad :: setNotch( StkFloat frequency, StkFloat radius )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
|
||||
oStream_ << "BiQuad::setNotch: frequency argument (" << frequency << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
if ( radius < 0.0 ) {
|
||||
oStream_ << "BiQuad::setNotch: radius argument (" << radius << ") is negative!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// This method does not attempt to normalize the filter gain.
|
||||
b_[2] = radius * radius;
|
||||
b_[1] = (StkFloat) -2.0 * radius * cos( TWO_PI * (double) frequency / Stk::sampleRate() );
|
||||
}
|
||||
|
||||
void BiQuad :: setEqualGainZeroes()
|
||||
void BiQuad :: setEqualGainZeroes( void )
|
||||
{
|
||||
b_[0] = 1.0;
|
||||
b_[1] = 0.0;
|
||||
|
||||
18
src/Blit.cpp
18
src/Blit.cpp
@@ -27,6 +27,11 @@ namespace stk {
|
||||
|
||||
Blit:: Blit( StkFloat frequency )
|
||||
{
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "Blit::Blit: argument (" << frequency << ") must be positive!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
nHarmonics_ = 0;
|
||||
this->setFrequency( frequency );
|
||||
this->reset();
|
||||
@@ -44,10 +49,10 @@ void Blit :: reset()
|
||||
|
||||
void Blit :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Blit::setFrequency: frequency = " << frequency << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "Blit::setFrequency: argument (" << frequency << ") must be positive!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
p_ = Stk::sampleRate() / frequency;
|
||||
rate_ = PI / p_;
|
||||
@@ -68,11 +73,6 @@ void Blit :: updateHarmonics( void )
|
||||
}
|
||||
else
|
||||
m_ = 2 * nHarmonics_ + 1;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Blit::updateHarmonics: nHarmonics_ = " << nHarmonics_ << ", m_ = " << m_ << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -25,6 +25,11 @@ namespace stk {
|
||||
|
||||
BlitSaw:: BlitSaw( StkFloat frequency )
|
||||
{
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "BlitSaw::BlitSaw: argument (" << frequency << ") must be positive!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
nHarmonics_ = 0;
|
||||
this->reset();
|
||||
this->setFrequency( frequency );
|
||||
@@ -43,10 +48,10 @@ void BlitSaw :: reset()
|
||||
|
||||
void BlitSaw :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BlitSaw::setFrequency: frequency = " << frequency << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "BlitSaw::setFrequency: argument (" << frequency << ") must be positive!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
p_ = Stk::sampleRate() / frequency;
|
||||
C2_ = 1 / p_;
|
||||
@@ -81,11 +86,6 @@ void BlitSaw :: updateHarmonics( void )
|
||||
m_ = 2 * nHarmonics_ + 1;
|
||||
|
||||
a_ = m_ / p_;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BlitSaw::updateHarmonics: nHarmonics_ = " << nHarmonics_ << ", m_ = " << m_ << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -36,6 +36,11 @@ namespace stk {
|
||||
|
||||
BlitSquare:: BlitSquare( StkFloat frequency )
|
||||
{
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "BlitSquare::BlitSquare: argument (" << frequency << ") must be positive!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
nHarmonics_ = 0;
|
||||
this->setFrequency( frequency );
|
||||
this->reset();
|
||||
@@ -55,10 +60,10 @@ void BlitSquare :: reset()
|
||||
|
||||
void BlitSquare :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BlitSquare::setFrequency: frequency = " << frequency << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "BlitSquare::setFrequency: argument (" << frequency << ") must be positive!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
// By using an even value of the parameter M, we get a bipolar blit
|
||||
// waveform at half the blit frequency. Thus, we need to scale the
|
||||
@@ -85,11 +90,6 @@ void BlitSquare :: updateHarmonics( void )
|
||||
m_ = 2 * (nHarmonics_ + 1);
|
||||
|
||||
a_ = m_ / p_;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BlitSquare::updateHarmonics: nHarmonics_ = " << nHarmonics_ << ", m_ = " << m_ << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -30,11 +30,11 @@ BlowBotl :: BlowBotl( void )
|
||||
vibrato_.setFrequency( 5.925 );
|
||||
vibratoGain_ = 0.0;
|
||||
|
||||
resonator_.setResonance(500.0, __BOTTLE_RADIUS_, true);
|
||||
adsr_.setAllTimes( 0.005, 0.01, 0.8, 0.010);
|
||||
resonator_.setResonance( 500.0, __BOTTLE_RADIUS_, true );
|
||||
adsr_.setAllTimes( 0.005, 0.01, 0.8, 0.010 );
|
||||
|
||||
noiseGain_ = 20.0;
|
||||
maxPressure_ = (StkFloat) 0.0;
|
||||
maxPressure_ = 0.0;
|
||||
}
|
||||
|
||||
BlowBotl :: ~BlowBotl( void )
|
||||
@@ -48,81 +48,74 @@ void BlowBotl :: clear( void )
|
||||
|
||||
void BlowBotl :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
StkFloat freakency = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "BlowBotl::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
freakency = 220.0;
|
||||
oStream_ << "BlowBotl::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
resonator_.setResonance( freakency, __BOTTLE_RADIUS_, true );
|
||||
resonator_.setResonance( frequency, __BOTTLE_RADIUS_, true );
|
||||
}
|
||||
|
||||
void BlowBotl :: startBlowing( StkFloat amplitude, StkFloat rate )
|
||||
{
|
||||
adsr_.setAttackRate(rate);
|
||||
if ( amplitude <= 0.0 || rate <= 0.0 ) {
|
||||
oStream_ << "BlowBotl::startBowing: one or more arguments is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
adsr_.setAttackRate( rate );
|
||||
maxPressure_ = amplitude;
|
||||
adsr_.keyOn();
|
||||
}
|
||||
|
||||
void BlowBotl :: stopBlowing( StkFloat rate )
|
||||
{
|
||||
adsr_.setReleaseRate(rate);
|
||||
if ( rate <= 0.0 ) {
|
||||
oStream_ << "BlowBotl::stopBowing: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
adsr_.setReleaseRate( rate );
|
||||
adsr_.keyOff();
|
||||
}
|
||||
|
||||
void BlowBotl :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
{
|
||||
this->setFrequency(frequency);
|
||||
this->setFrequency( frequency );
|
||||
startBlowing( 1.1 + (amplitude * 0.20), amplitude * 0.02);
|
||||
outputGain_ = amplitude + 0.001;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BlowBotl::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void BlowBotl :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
this->stopBlowing(amplitude * 0.02);
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BlowBotl::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
this->stopBlowing( amplitude * 0.02 );
|
||||
}
|
||||
|
||||
void BlowBotl :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "BlowBotl::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "BlowBotl::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
if (number == __SK_NoiseLevel_) // 4
|
||||
noiseGain_ = norm * 30.0;
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
vibrato_.setFrequency( norm * 12.0 );
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
vibratoGain_ = norm * 0.4;
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
adsr_.setTarget( norm );
|
||||
else {
|
||||
errorString_ << "BlowBotl::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BlowBotl::controlChange: number = " << number << ", value = " << value << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
if ( value < 0 || ( number != 101 && value > 128.0 ) ) {
|
||||
oStream_ << "BlowBotl::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_NoiseLevel_) // 4
|
||||
noiseGain_ = normalizedValue * 30.0;
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
vibrato_.setFrequency( normalizedValue * 12.0 );
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
vibratoGain_ = normalizedValue * 0.4;
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
adsr_.setTarget( normalizedValue );
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
oStream_ << "BlowBotl::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
120
src/BlowHole.cpp
120
src/BlowHole.cpp
@@ -29,7 +29,7 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -41,12 +41,17 @@ namespace stk {
|
||||
|
||||
BlowHole :: BlowHole( StkFloat lowestFrequency )
|
||||
{
|
||||
length_ = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
|
||||
if ( lowestFrequency <= 0.0 ) {
|
||||
oStream_ << "BlowHole::BlowHole: argument is less than or equal to zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
unsigned long nDelays = (unsigned long) ( 0.5 * Stk::sampleRate() / lowestFrequency );
|
||||
|
||||
// delays[0] is the delay line between the reed and the register vent.
|
||||
delays_[0].setDelay( 5.0 * Stk::sampleRate() / 22050.0 );
|
||||
// delays[1] is the delay line between the register vent and the tonehole.
|
||||
delays_[1].setMaximumDelay( length_ );
|
||||
delays_[1].setDelay( length_ >> 1 );
|
||||
delays_[1].setMaximumDelay( nDelays + 1 );
|
||||
// delays[2] is the delay line between the tonehole and the end of the bore.
|
||||
delays_[2].setDelay( 4.0 * Stk::sampleRate() / 22050.0 );
|
||||
|
||||
@@ -61,9 +66,9 @@ BlowHole :: BlowHole( StkFloat lowestFrequency )
|
||||
// Calculate tonehole coefficients and set for initially open.
|
||||
StkFloat te = 1.4 * rth; // effective length of the open hole
|
||||
thCoeff_ = (te*2*Stk::sampleRate() - 347.23) / (te*2*Stk::sampleRate() + 347.23);
|
||||
tonehole_.setA1(-thCoeff_);
|
||||
tonehole_.setB0(thCoeff_);
|
||||
tonehole_.setB1(-1.0);
|
||||
tonehole_.setA1( -thCoeff_ );
|
||||
tonehole_.setB0( thCoeff_ );
|
||||
tonehole_.setB1( -1.0 );
|
||||
|
||||
// Calculate register hole filter coefficients
|
||||
double r_rh = 0.0015; // register vent radius
|
||||
@@ -74,15 +79,18 @@ BlowHole :: BlowHole( StkFloat lowestFrequency )
|
||||
StkFloat rhCoeff = (zeta - 2 * Stk::sampleRate() * psi) / (zeta + 2 * Stk::sampleRate() * psi);
|
||||
rhGain_ = -347.23 / (zeta + 2 * Stk::sampleRate() * psi);
|
||||
vent_.setA1( rhCoeff );
|
||||
vent_.setB0(1.0);
|
||||
vent_.setB1(1.0);
|
||||
vent_.setB0( 1.0 );
|
||||
vent_.setB1( 1.0 );
|
||||
// Start with register vent closed
|
||||
vent_.setGain(0.0);
|
||||
vent_.setGain( 0.0 );
|
||||
|
||||
vibrato_.setFrequency((StkFloat) 5.735);
|
||||
outputGain_ = 1.0;
|
||||
noiseGain_ = 0.2;
|
||||
vibratoGain_ = 0.01;
|
||||
|
||||
this->setFrequency( 220.0 );
|
||||
this->clear();
|
||||
}
|
||||
|
||||
BlowHole :: ~BlowHole( void )
|
||||
@@ -101,19 +109,18 @@ void BlowHole :: clear( void )
|
||||
|
||||
void BlowHole :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
StkFloat freakency = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
std::cerr << "BlowHole: setFrequency parameter is less than or equal to zero!" << std::endl;
|
||||
freakency = 220.0;
|
||||
oStream_ << "BlowHole::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Delay = length - approximate filter delay.
|
||||
StkFloat delay = (Stk::sampleRate() / freakency) * 0.5 - 3.5;
|
||||
// Account for approximate filter delays and one sample "lastOut" delay.
|
||||
StkFloat delay = ( Stk::sampleRate() / frequency ) * 0.5 - 3.5;
|
||||
delay -= delays_[0].getDelay() + delays_[2].getDelay();
|
||||
|
||||
if (delay <= 0.0) delay = 0.3;
|
||||
else if (delay > length_) delay = length_;
|
||||
delays_[1].setDelay(delay);
|
||||
delays_[1].setDelay( delay );
|
||||
}
|
||||
|
||||
void BlowHole :: setVent( StkFloat newValue )
|
||||
@@ -124,9 +131,9 @@ void BlowHole :: setVent( StkFloat newValue )
|
||||
|
||||
StkFloat gain;
|
||||
|
||||
if (newValue <= 0.0)
|
||||
if ( newValue <= 0.0 )
|
||||
gain = 0.0;
|
||||
else if (newValue >= 1.0)
|
||||
else if ( newValue >= 1.0 )
|
||||
gain = rhGain_;
|
||||
else
|
||||
gain = newValue * rhGain_;
|
||||
@@ -146,7 +153,7 @@ void BlowHole :: setTonehole( StkFloat newValue )
|
||||
else if ( newValue >= 1.0 )
|
||||
new_coeff = thCoeff_;
|
||||
else
|
||||
new_coeff = (newValue * (thCoeff_ - 0.9995)) + 0.9995;
|
||||
new_coeff = ( newValue * (thCoeff_ - 0.9995) ) + 0.9995;
|
||||
|
||||
tonehole_.setA1( -new_coeff );
|
||||
tonehole_.setB0( new_coeff );
|
||||
@@ -154,12 +161,22 @@ void BlowHole :: setTonehole( StkFloat newValue )
|
||||
|
||||
void BlowHole :: startBlowing( StkFloat amplitude, StkFloat rate )
|
||||
{
|
||||
if ( amplitude <= 0.0 || rate <= 0.0 ) {
|
||||
oStream_ << "BlowHole::startBlowing: one or more arguments is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
envelope_.setRate( rate );
|
||||
envelope_.setTarget( amplitude );
|
||||
}
|
||||
|
||||
void BlowHole :: stopBlowing( StkFloat rate )
|
||||
{
|
||||
if ( rate <= 0.0 ) {
|
||||
oStream_ << "BlowHole::stopBlowing: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
envelope_.setRate( rate );
|
||||
envelope_.setTarget( 0.0 );
|
||||
}
|
||||
@@ -169,55 +186,38 @@ void BlowHole :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
this->setFrequency( frequency );
|
||||
this->startBlowing( 0.55 + (amplitude * 0.30), amplitude * 0.005 );
|
||||
outputGain_ = amplitude + 0.001;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BlowHole::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void BlowHole :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
this->stopBlowing( amplitude * 0.01 );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BlowHole::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void BlowHole :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "BlowHole::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "BlowHole::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
if (number == __SK_ReedStiffness_) // 2
|
||||
reedTable_.setSlope( -0.44 + (0.26 * norm) );
|
||||
else if (number == __SK_NoiseLevel_) // 4
|
||||
noiseGain_ = ( norm * 0.4);
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
this->setTonehole( norm );
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
this->setVent( norm );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
envelope_.setValue( norm );
|
||||
else {
|
||||
errorString_ << "BlowHole::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "BlowHole::controlChange: number = " << number << ", value = " << value << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "BlowHole::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_ReedStiffness_) // 2
|
||||
reedTable_.setSlope( -0.44 + (0.26 * normalizedValue) );
|
||||
else if (number == __SK_NoiseLevel_) // 4
|
||||
noiseGain_ = ( normalizedValue * 0.4);
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
this->setTonehole( normalizedValue );
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
this->setVent( normalizedValue );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
envelope_.setValue( normalizedValue );
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
oStream_ << "BlowHole::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
128
src/Bowed.cpp
128
src/Bowed.cpp
@@ -15,9 +15,12 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -28,25 +31,41 @@ namespace stk {
|
||||
|
||||
Bowed :: Bowed( StkFloat lowestFrequency )
|
||||
{
|
||||
unsigned long length;
|
||||
length = (long) ( Stk::sampleRate() / lowestFrequency + 1 );
|
||||
neckDelay_.setMaximumDelay( length );
|
||||
if ( lowestFrequency <= 0.0 ) {
|
||||
oStream_ << "Bowed::Bowed: argument is less than or equal to zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
unsigned long nDelays = (unsigned long) ( Stk::sampleRate() / lowestFrequency );
|
||||
|
||||
neckDelay_.setMaximumDelay( nDelays + 1 );
|
||||
neckDelay_.setDelay( 100.0 );
|
||||
|
||||
length >>= 1;
|
||||
bridgeDelay_.setMaximumDelay( length );
|
||||
bridgeDelay_.setMaximumDelay( nDelays + 1 );
|
||||
bridgeDelay_.setDelay( 29.0 );
|
||||
|
||||
bowTable_.setSlope(3.0 );
|
||||
bowTable_.setSlope( 3.0 );
|
||||
bowTable_.setOffset( 0.001);
|
||||
bowDown_ = false;
|
||||
maxVelocity_ = 0.25;
|
||||
|
||||
vibrato_.setFrequency( 6.12723 );
|
||||
vibratoGain_ = 0.0;
|
||||
|
||||
stringFilter_.setPole( 0.6 - (0.1 * 22050.0 / Stk::sampleRate()) );
|
||||
stringFilter_.setPole( 0.75 - (0.2 * 22050.0 / Stk::sampleRate()) );
|
||||
stringFilter_.setGain( 0.95 );
|
||||
|
||||
bodyFilter_.setResonance( 500.0, 0.85, true );
|
||||
bodyFilter_.setGain( 0.2 );
|
||||
// Old single body filter
|
||||
//bodyFilter_.setResonance( 500.0, 0.85, true );
|
||||
//bodyFilter_.setGain( 0.2 );
|
||||
|
||||
// New body filter provided by Esteban Maestre (cascade of second-order sections)
|
||||
bodyFilters_[0].setCoefficients( 1.0, 1.5667, 0.3133, -0.5509, -0.3925 );
|
||||
bodyFilters_[1].setCoefficients( 1.0, -1.9537, 0.9542, -1.6357, 0.8697 );
|
||||
bodyFilters_[2].setCoefficients( 1.0, -1.6683, 0.8852, -1.7674, 0.8735 );
|
||||
bodyFilters_[3].setCoefficients( 1.0, -1.8585, 0.9653, -1.8498, 0.9516 );
|
||||
bodyFilters_[4].setCoefficients( 1.0, -1.9299, 0.9621, -1.9354, 0.9590 );
|
||||
bodyFilters_[5].setCoefficients( 1.0, -1.9800, 0.9888, -1.9867, 0.9923 );
|
||||
|
||||
adsr_.setAllTimes( 0.02, 0.005, 0.9, 0.01 );
|
||||
|
||||
@@ -54,6 +73,7 @@ Bowed :: Bowed( StkFloat lowestFrequency )
|
||||
|
||||
// Necessary to initialize internal variables.
|
||||
this->setFrequency( 220.0 );
|
||||
this->clear();
|
||||
}
|
||||
|
||||
Bowed :: ~Bowed( void )
|
||||
@@ -64,19 +84,21 @@ void Bowed :: clear( void )
|
||||
{
|
||||
neckDelay_.clear();
|
||||
bridgeDelay_.clear();
|
||||
stringFilter_.clear();
|
||||
for ( int i=0; i<6; i++ ) bodyFilters_[i].clear();
|
||||
}
|
||||
|
||||
void Bowed :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
StkFloat freakency = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "Bowed::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
freakency = 220.0;
|
||||
oStream_ << "Bowed::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Delay = length - approximate filter delay.
|
||||
baseDelay_ = Stk::sampleRate() / freakency - 4.0;
|
||||
baseDelay_ = Stk::sampleRate() / frequency - 4.0;
|
||||
if ( baseDelay_ <= 0.0 ) baseDelay_ = 0.3;
|
||||
bridgeDelay_.setDelay( baseDelay_ * betaRatio_ ); // bow to bridge length
|
||||
neckDelay_.setDelay( baseDelay_ * (1.0 - betaRatio_) ); // bow to nut (finger) length
|
||||
@@ -84,13 +106,24 @@ void Bowed :: setFrequency( StkFloat frequency )
|
||||
|
||||
void Bowed :: startBowing( StkFloat amplitude, StkFloat rate )
|
||||
{
|
||||
if ( amplitude <= 0.0 || rate <= 0.0 ) {
|
||||
oStream_ << "Bowed::startBowing: one or more arguments is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
adsr_.setAttackRate( rate );
|
||||
adsr_.keyOn();
|
||||
maxVelocity_ = 0.03 + ( 0.2 * amplitude );
|
||||
maxVelocity_ = 0.03 + ( 0.2 * amplitude );
|
||||
bowDown_ = true;
|
||||
}
|
||||
|
||||
void Bowed :: stopBowing( StkFloat rate )
|
||||
{
|
||||
if ( rate <= 0.0 ) {
|
||||
oStream_ << "Bowed::stopBowing: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
adsr_.setReleaseRate( rate );
|
||||
adsr_.keyOff();
|
||||
}
|
||||
@@ -99,63 +132,48 @@ void Bowed :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
{
|
||||
this->startBowing( amplitude, amplitude * 0.001 );
|
||||
this->setFrequency( frequency );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Bowed::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Bowed :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
this->stopBowing( (1.0 - amplitude) * 0.005 );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Bowed::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Bowed :: setVibrato( StkFloat gain )
|
||||
{
|
||||
vibratoGain_ = gain;
|
||||
}
|
||||
|
||||
void Bowed :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "Bowed::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "Bowed::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( value < 0 || ( number != 101 && value > 128.0 ) ) {
|
||||
oStream_ << "Bowed::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (number == __SK_BowPressure_) // 2
|
||||
bowTable_.setSlope( 5.0 - (4.0 * norm) );
|
||||
else if (number == __SK_BowPosition_) { // 4
|
||||
betaRatio_ = 0.027236 + (0.2 * norm);
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if ( number == __SK_BowPressure_ ) { // 2
|
||||
if ( normalizedValue > 0.0 ) bowDown_ = true;
|
||||
else bowDown_ = false;
|
||||
bowTable_.setSlope( 5.0 - (4.0 * normalizedValue) );
|
||||
}
|
||||
else if ( number == __SK_BowPosition_ ) { // 4
|
||||
betaRatio_ = normalizedValue;
|
||||
bridgeDelay_.setDelay( baseDelay_ * betaRatio_ );
|
||||
neckDelay_.setDelay( baseDelay_ * (1.0 - betaRatio_) );
|
||||
}
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
vibrato_.setFrequency( norm * 12.0 );
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
vibratoGain_ = ( norm * 0.4 );
|
||||
else if ( number == __SK_ModFrequency_ ) // 11
|
||||
vibrato_.setFrequency( normalizedValue * 12.0 );
|
||||
else if ( number == __SK_ModWheel_ ) // 1
|
||||
vibratoGain_ = ( normalizedValue * 0.4 );
|
||||
else if ( number == 100 ) // 100: set instantaneous bow velocity
|
||||
adsr_.setTarget( normalizedValue );
|
||||
else if ( number == 101 ) // 101: set instantaneous value of frequency
|
||||
this->setFrequency( value );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
adsr_.setTarget(norm);
|
||||
adsr_.setTarget( normalizedValue );
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
errorString_ << "Bowed::controlChange: undefined control number (" << number << ")!";
|
||||
oStream_ << "Bowed::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Bowed::controlChange: number = " << number << ", value = " << value << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -28,22 +28,25 @@ namespace stk {
|
||||
|
||||
Brass :: Brass( StkFloat lowestFrequency )
|
||||
{
|
||||
length_ = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
|
||||
delayLine_.setMaximumDelay( length_ );
|
||||
delayLine_.setDelay( 0.5 * length_ );
|
||||
if ( lowestFrequency <= 0.0 ) {
|
||||
oStream_ << "Brass::Brass: argument is less than or equal to zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
unsigned long nDelays = (unsigned long) ( Stk::sampleRate() / lowestFrequency );
|
||||
delayLine_.setMaximumDelay( nDelays + 1 );
|
||||
|
||||
lipFilter_.setGain( 0.03 );
|
||||
dcBlock_.setBlockZero();
|
||||
|
||||
adsr_.setAllTimes( 0.005, 0.001, 1.0, 0.010 );
|
||||
|
||||
vibrato_.setFrequency( 6.137 );
|
||||
vibratoGain_ = 0.0;
|
||||
|
||||
this->clear();
|
||||
maxPressure_ = 0.0;
|
||||
lipTarget_ = 0.0;
|
||||
|
||||
this->clear();
|
||||
|
||||
// This is necessary to initialize variables.
|
||||
this->setFrequency( 220.0 );
|
||||
}
|
||||
@@ -61,35 +64,40 @@ void Brass :: clear( void )
|
||||
|
||||
void Brass :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
StkFloat freakency = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "Brass::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
freakency = 220.0;
|
||||
oStream_ << "Brass::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fudge correction for filter delays.
|
||||
slideTarget_ = (Stk::sampleRate() / freakency * 2.0) + 3.0;
|
||||
slideTarget_ = ( Stk::sampleRate() / frequency * 2.0 ) + 3.0;
|
||||
delayLine_.setDelay( slideTarget_ ); // play a harmonic
|
||||
|
||||
lipTarget_ = freakency;
|
||||
lipFilter_.setResonance( freakency, 0.997 );
|
||||
lipTarget_ = frequency;
|
||||
lipFilter_.setResonance( frequency, 0.997 );
|
||||
}
|
||||
|
||||
void Brass :: setLip( StkFloat frequency )
|
||||
{
|
||||
StkFloat freakency = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "Brass::setLip: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
freakency = 220.0;
|
||||
oStream_ << "Brass::setLip: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
lipFilter_.setResonance( freakency, 0.997 );
|
||||
lipFilter_.setResonance( frequency, 0.997 );
|
||||
}
|
||||
|
||||
void Brass :: startBlowing( StkFloat amplitude, StkFloat rate )
|
||||
{
|
||||
if ( amplitude <= 0.0 || rate <= 0.0 ) {
|
||||
oStream_ << "Brass::startBlowing: one or more arguments is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
adsr_.setAttackRate( rate );
|
||||
maxPressure_ = amplitude;
|
||||
adsr_.keyOn();
|
||||
@@ -97,6 +105,11 @@ void Brass :: startBlowing( StkFloat amplitude, StkFloat rate )
|
||||
|
||||
void Brass :: stopBlowing( StkFloat rate )
|
||||
{
|
||||
if ( rate <= 0.0 ) {
|
||||
oStream_ << "Brass::stopBlowing: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
adsr_.setReleaseRate( rate );
|
||||
adsr_.keyOff();
|
||||
}
|
||||
@@ -105,57 +118,40 @@ void Brass :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
{
|
||||
this->setFrequency( frequency );
|
||||
this->startBlowing( amplitude, amplitude * 0.001 );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Brass::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Brass :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
this->stopBlowing( amplitude * 0.005 );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Brass::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Brass :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "Brass::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "Brass::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Brass::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_LipTension_) { // 2
|
||||
StkFloat temp = lipTarget_ * pow( 4.0, (2.0 * norm) - 1.0 );
|
||||
this->setLip(temp);
|
||||
StkFloat temp = lipTarget_ * pow( 4.0, (2.0 * normalizedValue) - 1.0 );
|
||||
this->setLip( temp );
|
||||
}
|
||||
else if (number == __SK_SlideLength_) // 4
|
||||
delayLine_.setDelay( slideTarget_ * (0.5 + norm) );
|
||||
delayLine_.setDelay( slideTarget_ * (0.5 + normalizedValue) );
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
vibrato_.setFrequency( norm * 12.0 );
|
||||
vibrato_.setFrequency( normalizedValue * 12.0 );
|
||||
else if (number == __SK_ModWheel_ ) // 1
|
||||
vibratoGain_ = norm * 0.4;
|
||||
vibratoGain_ = normalizedValue * 0.4;
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
adsr_.setTarget( norm );
|
||||
adsr_.setTarget( normalizedValue );
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
errorString_ << "Brass::controlChange: undefined control number (" << number << ")!";
|
||||
oStream_ << "Brass::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Brass::controlChange: number = " << number << ", value = " << value << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -37,6 +37,16 @@ void Chorus :: clear( void )
|
||||
lastFrame_[1] = 0.0;
|
||||
}
|
||||
|
||||
void Chorus :: setModDepth( StkFloat depth )
|
||||
{
|
||||
if ( depth < 0.0 || depth > 1.0 ) {
|
||||
oStream_ << "Chorus::setModDepth(): depth argument must be between 0.0 - 1.0!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
modDepth_ = depth;
|
||||
};
|
||||
|
||||
void Chorus :: setModFrequency( StkFloat frequency )
|
||||
{
|
||||
mods_[0].setFrequency( frequency );
|
||||
|
||||
129
src/Clarinet.cpp
129
src/Clarinet.cpp
@@ -18,7 +18,7 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -29,16 +29,24 @@ namespace stk {
|
||||
|
||||
Clarinet :: Clarinet( StkFloat lowestFrequency )
|
||||
{
|
||||
length_ = (long) (Stk::sampleRate() / lowestFrequency + 1);
|
||||
delayLine_.setMaximumDelay( length_ );
|
||||
delayLine_.setDelay( length_ / 2.0 );
|
||||
reedTable_.setOffset((StkFloat) 0.7);
|
||||
reedTable_.setSlope((StkFloat) -0.3);
|
||||
if ( lowestFrequency <= 0.0 ) {
|
||||
oStream_ << "Clarinet::Clarinet: argument is less than or equal to zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
vibrato_.setFrequency((StkFloat) 5.735);
|
||||
outputGain_ = (StkFloat) 1.0;
|
||||
noiseGain_ = (StkFloat) 0.2;
|
||||
vibratoGain_ = (StkFloat) 0.1;
|
||||
unsigned long nDelays = (unsigned long) ( 0.5 * Stk::sampleRate() / lowestFrequency );
|
||||
delayLine_.setMaximumDelay( nDelays + 1 );
|
||||
|
||||
reedTable_.setOffset( 0.7 );
|
||||
reedTable_.setSlope( -0.3 );
|
||||
|
||||
vibrato_.setFrequency( 5.735 );
|
||||
outputGain_ = 1.0;
|
||||
noiseGain_ = 0.2;
|
||||
vibratoGain_ = 0.1;
|
||||
|
||||
this->setFrequency( 220.0 );
|
||||
this->clear();
|
||||
}
|
||||
|
||||
Clarinet :: ~Clarinet( void )
|
||||
@@ -53,86 +61,77 @@ void Clarinet :: clear( void )
|
||||
|
||||
void Clarinet :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
StkFloat freakency = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "Clarinet::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
freakency = 220.0;
|
||||
oStream_ << "Clarinet::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Delay = length - approximate filter delay.
|
||||
StkFloat delay = (Stk::sampleRate() / freakency) * 0.5 - 1.5;
|
||||
if (delay <= 0.0) delay = 0.3;
|
||||
else if (delay > length_) delay = length_;
|
||||
delayLine_.setDelay(delay);
|
||||
// Account for filter delay and one sample "lastOut" delay.
|
||||
StkFloat delay = ( Stk::sampleRate() / frequency ) * 0.5 - filter_.phaseDelay( frequency ) - 1.0;
|
||||
delayLine_.setDelay( delay );
|
||||
}
|
||||
|
||||
void Clarinet :: startBlowing( StkFloat amplitude, StkFloat rate )
|
||||
{
|
||||
envelope_.setRate(rate);
|
||||
envelope_.setTarget(amplitude);
|
||||
if ( amplitude <= 0.0 || rate <= 0.0 ) {
|
||||
oStream_ << "Clarinet::startBlowing: one or more arguments is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
envelope_.setRate( rate );
|
||||
envelope_.setTarget( amplitude );
|
||||
}
|
||||
|
||||
void Clarinet :: stopBlowing( StkFloat rate )
|
||||
{
|
||||
envelope_.setRate(rate);
|
||||
envelope_.setTarget((StkFloat) 0.0);
|
||||
if ( rate <= 0.0 ) {
|
||||
oStream_ << "Clarinet::stopBlowing: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
envelope_.setRate( rate );
|
||||
envelope_.setTarget( 0.0 );
|
||||
}
|
||||
|
||||
void Clarinet :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
{
|
||||
this->setFrequency(frequency);
|
||||
this->startBlowing((StkFloat) 0.55 + (amplitude * (StkFloat) 0.30), amplitude * (StkFloat) 0.005);
|
||||
outputGain_ = amplitude + (StkFloat) 0.001;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Clarinet::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
this->setFrequency( frequency );
|
||||
this->startBlowing( 0.55 + (amplitude * 0.30), amplitude * 0.005 );
|
||||
outputGain_ = amplitude + 0.001;
|
||||
}
|
||||
|
||||
void Clarinet :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
this->stopBlowing( amplitude * 0.01 );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Clarinet::NoteOff: amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Clarinet :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "Clarinet::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "Clarinet::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
if (number == __SK_ReedStiffness_) // 2
|
||||
reedTable_.setSlope((StkFloat) -0.44 + ( (StkFloat) 0.26 * norm ));
|
||||
else if (number == __SK_NoiseLevel_) // 4
|
||||
noiseGain_ = (norm * (StkFloat) 0.4);
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
vibrato_.setFrequency((norm * (StkFloat) 12.0));
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
vibratoGain_ = (norm * (StkFloat) 0.5);
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
envelope_.setValue(norm);
|
||||
else {
|
||||
errorString_ << "Clarinet::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Clarinet::controlChange: number = " << number << ", value = " << value << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Clarinet::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if ( number == __SK_ReedStiffness_ ) // 2
|
||||
reedTable_.setSlope( -0.44 + ( 0.26 * normalizedValue ) );
|
||||
else if ( number == __SK_NoiseLevel_ ) // 4
|
||||
noiseGain_ = ( normalizedValue * 0.4 );
|
||||
else if ( number == __SK_ModFrequency_ ) // 11
|
||||
vibrato_.setFrequency( normalizedValue * 12.0 );
|
||||
else if ( number == __SK_ModWheel_ ) // 1
|
||||
vibratoGain_ = ( normalizedValue * 0.5 );
|
||||
else if ( number == __SK_AfterTouch_Cont_ ) // 128
|
||||
envelope_.setValue( normalizedValue );
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
oStream_ << "Clarinet::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -23,13 +23,8 @@ Delay :: Delay( unsigned long delay, unsigned long maxDelay )
|
||||
// Writing before reading allows delays from 0 to length-1.
|
||||
// If we want to allow a delay of maxDelay, we need a
|
||||
// delay-line of length = maxDelay+1.
|
||||
if ( maxDelay < 1 ) {
|
||||
errorString_ << "Delay::Delay: maxDelay must be > 0!\n";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
if ( delay > maxDelay ) {
|
||||
errorString_ << "Delay::Delay: maxDelay must be > than delay argument!\n";
|
||||
oStream_ << "Delay::Delay: maxDelay must be > than delay argument!\n";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -47,44 +42,25 @@ Delay :: ~Delay()
|
||||
void Delay :: setMaximumDelay( unsigned long delay )
|
||||
{
|
||||
if ( delay < inputs_.size() ) return;
|
||||
|
||||
if ( delay < 0 ) {
|
||||
errorString_ << "Delay::setMaximumDelay: argument (" << delay << ") less than zero!\n";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
}
|
||||
else if ( delay < delay_ ) {
|
||||
errorString_ << "Delay::setMaximumDelay: argument (" << delay << ") less than current delay setting (" << delay_ << ")!\n";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
}
|
||||
|
||||
inputs_.resize( delay + 1 );
|
||||
}
|
||||
|
||||
void Delay :: setDelay( unsigned long delay )
|
||||
{
|
||||
if ( delay > inputs_.size() - 1 ) { // The value is too big.
|
||||
errorString_ << "Delay::setDelay: argument (" << delay << ") too big ... setting to maximum!\n";
|
||||
handleError( StkError::WARNING );
|
||||
oStream_ << "Delay::setDelay: argument (" << delay << ") greater than maximum!\n";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
// Force delay to maximum length.
|
||||
outPoint_ = inPoint_ + 1;
|
||||
if ( outPoint_ == inputs_.size() ) outPoint_ = 0;
|
||||
delay_ = inputs_.size() - 1;
|
||||
if ( delay < 0 ) {
|
||||
oStream_ << "Delay::setDelay: argument (" << delay << ") less than zero!\n";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else if ( delay < 0 ) {
|
||||
errorString_ << "Delay::setDelay: argument (" << delay << ") less than zero ... setting to zero!\n";
|
||||
handleError( StkError::WARNING );
|
||||
|
||||
outPoint_ = inPoint_;
|
||||
delay_ = 0;
|
||||
}
|
||||
else { // read chases write
|
||||
if ( inPoint_ >= delay ) outPoint_ = inPoint_ - delay;
|
||||
else outPoint_ = inputs_.size() + inPoint_ - delay;
|
||||
delay_ = delay;
|
||||
}
|
||||
// read chases write
|
||||
if ( inPoint_ >= delay ) outPoint_ = inPoint_ - delay;
|
||||
else outPoint_ = inputs_.size() + inPoint_ - delay;
|
||||
delay_ = delay;
|
||||
}
|
||||
|
||||
StkFloat Delay :: energy( void ) const
|
||||
@@ -109,7 +85,7 @@ StkFloat Delay :: energy( void ) const
|
||||
return e;
|
||||
}
|
||||
|
||||
StkFloat Delay :: contentsAt( unsigned long tapDelay )
|
||||
StkFloat Delay :: tapOut( unsigned long tapDelay )
|
||||
{
|
||||
long tap = inPoint_ - tapDelay - 1;
|
||||
while ( tap < 0 ) // Check for wraparound.
|
||||
@@ -118,7 +94,16 @@ StkFloat Delay :: contentsAt( unsigned long tapDelay )
|
||||
return inputs_[tap];
|
||||
}
|
||||
|
||||
StkFloat Delay :: addTo( unsigned long tapDelay, StkFloat value )
|
||||
void Delay :: tapIn( StkFloat value, unsigned long tapDelay )
|
||||
{
|
||||
long tap = inPoint_ - tapDelay - 1;
|
||||
while ( tap < 0 ) // Check for wraparound.
|
||||
tap += inputs_.size();
|
||||
|
||||
inputs_[tap] = value;
|
||||
}
|
||||
|
||||
StkFloat Delay :: addTo( StkFloat value, unsigned long tapDelay )
|
||||
{
|
||||
long tap = inPoint_ - tapDelay - 1;
|
||||
while ( tap < 0 ) // Check for wraparound.
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -24,13 +24,13 @@ namespace stk {
|
||||
|
||||
DelayA :: DelayA( StkFloat delay, unsigned long maxDelay )
|
||||
{
|
||||
if ( delay < 0.5 || maxDelay < 1 ) {
|
||||
errorString_ << "DelayA::DelayA: delay must be >= 0.5, maxDelay must be > 0!";
|
||||
if ( delay < 0.5 ) {
|
||||
oStream_ << "DelayA::DelayA: delay must be >= 0.5!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
if ( delay > (StkFloat) maxDelay ) {
|
||||
errorString_ << "DelayA::DelayA: maxDelay must be > than delay argument!";
|
||||
oStream_ << "DelayA::DelayA: maxDelay must be > than delay argument!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -59,45 +59,24 @@ void DelayA :: clear()
|
||||
void DelayA :: setMaximumDelay( unsigned long delay )
|
||||
{
|
||||
if ( delay < inputs_.size() ) return;
|
||||
|
||||
if ( delay < 0 ) {
|
||||
errorString_ << "DelayA::setMaximumDelay: argument (" << delay << ") less than zero!\n";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
}
|
||||
else if ( delay < delay_ ) {
|
||||
errorString_ << "DelayA::setMaximumDelay: argument (" << delay << ") less than current delay setting (" << delay_ << ")!\n";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
}
|
||||
|
||||
inputs_.resize( delay + 1 );
|
||||
}
|
||||
|
||||
void DelayA :: setDelay( StkFloat delay )
|
||||
{
|
||||
StkFloat outPointer;
|
||||
unsigned long length = inputs_.size();
|
||||
|
||||
if ( delay + 1 > length ) { // The value is too big.
|
||||
errorString_ << "DelayA::setDelay: argument (" << delay << ") too big ... setting to maximum!";
|
||||
handleError( StkError::WARNING );
|
||||
oStream_ << "DelayA::setDelay: argument (" << delay << ") greater than maximum!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
// Force delay to maxLength
|
||||
outPointer = inPoint_ + 1.0;
|
||||
delay_ = length - 1;
|
||||
}
|
||||
else if ( delay < 0.5 ) {
|
||||
errorString_ << "DelayA::setDelay: argument (" << delay << ") less than 0.5 not possible!";
|
||||
if ( delay < 0.5 ) {
|
||||
oStream_ << "DelayA::setDelay: argument (" << delay << ") less than 0.5 not possible!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
outPointer = inPoint_ + 0.4999999999;
|
||||
delay_ = 0.5;
|
||||
}
|
||||
else {
|
||||
outPointer = inPoint_ - delay + 1.0; // outPoint chases inpoint
|
||||
delay_ = delay;
|
||||
}
|
||||
StkFloat outPointer = inPoint_ - delay + 1.0; // outPoint chases inpoint
|
||||
delay_ = delay;
|
||||
|
||||
while ( outPointer < 0 )
|
||||
outPointer += length; // modulo maximum length
|
||||
@@ -110,15 +89,14 @@ void DelayA :: setDelay( StkFloat delay )
|
||||
// The optimal range for alpha is about 0.5 - 1.5 in order to
|
||||
// achieve the flattest phase delay response.
|
||||
outPoint_ += 1;
|
||||
if (outPoint_ >= length) outPoint_ -= length;
|
||||
if ( outPoint_ >= length ) outPoint_ -= length;
|
||||
alpha_ += (StkFloat) 1.0;
|
||||
}
|
||||
|
||||
coeff_ = ((StkFloat) 1.0 - alpha_) /
|
||||
((StkFloat) 1.0 + alpha_); // coefficient for all pass
|
||||
coeff_ = (1.0 - alpha_) / (1.0 + alpha_); // coefficient for allpass
|
||||
}
|
||||
|
||||
StkFloat DelayA :: contentsAt( unsigned long tapDelay )
|
||||
StkFloat DelayA :: tapOut( unsigned long tapDelay )
|
||||
{
|
||||
long tap = inPoint_ - tapDelay - 1;
|
||||
while ( tap < 0 ) // Check for wraparound.
|
||||
@@ -127,4 +105,13 @@ StkFloat DelayA :: contentsAt( unsigned long tapDelay )
|
||||
return inputs_[tap];
|
||||
}
|
||||
|
||||
void DelayA :: tapIn( StkFloat value, unsigned long tapDelay )
|
||||
{
|
||||
long tap = inPoint_ - tapDelay - 1;
|
||||
while ( tap < 0 ) // Check for wraparound.
|
||||
tap += inputs_.size();
|
||||
|
||||
inputs_[tap] = value;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -23,13 +23,13 @@ namespace stk {
|
||||
|
||||
DelayL :: DelayL( StkFloat delay, unsigned long maxDelay )
|
||||
{
|
||||
if ( delay < 0.0 || maxDelay < 1 ) {
|
||||
errorString_ << "DelayL::DelayL: delay must be >= 0.0, maxDelay must be > 0!";
|
||||
if ( delay < 0.0 ) {
|
||||
oStream_ << "DelayL::DelayL: delay must be >= 0.0!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
if ( delay > (StkFloat) maxDelay ) {
|
||||
errorString_ << "DelayL::DelayL: maxDelay must be > than delay argument!";
|
||||
oStream_ << "DelayL::DelayL: maxDelay must be > than delay argument!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -49,46 +49,25 @@ DelayL :: ~DelayL()
|
||||
void DelayL :: setMaximumDelay( unsigned long delay )
|
||||
{
|
||||
if ( delay < inputs_.size() ) return;
|
||||
|
||||
if ( delay < 0 ) {
|
||||
errorString_ << "DelayL::setMaximumDelay: argument (" << delay << ") less than zero!\n";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
}
|
||||
else if ( delay < delay_ ) {
|
||||
errorString_ << "DelayL::setMaximumDelay: argument (" << delay << ") less than current delay setting (" << delay_ << ")!\n";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
}
|
||||
|
||||
inputs_.resize( delay + 1 );
|
||||
}
|
||||
|
||||
void DelayL :: setDelay( StkFloat delay )
|
||||
{
|
||||
StkFloat outPointer;
|
||||
|
||||
if ( delay + 1 > inputs_.size() ) { // The value is too big.
|
||||
errorString_ << "DelayL::setDelay: argument (" << delay << ") too big ... setting to maximum!";
|
||||
handleError( StkError::WARNING );
|
||||
|
||||
// Force delay to maxLength
|
||||
outPointer = inPoint_ + 1.0;
|
||||
delay_ = inputs_.size() - 1;
|
||||
}
|
||||
else if (delay < 0 ) {
|
||||
errorString_ << "DelayL::setDelay: argument (" << delay << ") less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
|
||||
outPointer = inPoint_;
|
||||
delay_ = 0;
|
||||
}
|
||||
else {
|
||||
outPointer = inPoint_ - delay; // read chases write
|
||||
delay_ = delay;
|
||||
oStream_ << "DelayL::setDelay: argument (" << delay << ") greater than maximum!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
while (outPointer < 0)
|
||||
if (delay < 0 ) {
|
||||
oStream_ << "DelayL::setDelay: argument (" << delay << ") less than zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
StkFloat outPointer = inPoint_ - delay; // read chases write
|
||||
delay_ = delay;
|
||||
|
||||
while ( outPointer < 0 )
|
||||
outPointer += inputs_.size(); // modulo maximum length
|
||||
|
||||
outPoint_ = (long) outPointer; // integer part
|
||||
@@ -97,7 +76,7 @@ void DelayL :: setDelay( StkFloat delay )
|
||||
omAlpha_ = (StkFloat) 1.0 - alpha_;
|
||||
}
|
||||
|
||||
StkFloat DelayL :: contentsAt( unsigned long tapDelay )
|
||||
StkFloat DelayL :: tapOut( unsigned long tapDelay )
|
||||
{
|
||||
long tap = inPoint_ - tapDelay - 1;
|
||||
while ( tap < 0 ) // Check for wraparound.
|
||||
@@ -106,4 +85,13 @@ StkFloat DelayL :: contentsAt( unsigned long tapDelay )
|
||||
return inputs_[tap];
|
||||
}
|
||||
|
||||
void DelayL :: tapIn( StkFloat value, unsigned long tapDelay )
|
||||
{
|
||||
long tap = inPoint_ - tapDelay - 1;
|
||||
while ( tap < 0 ) // Check for wraparound.
|
||||
tap += inputs_.size();
|
||||
|
||||
inputs_[tap] = value;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -69,21 +69,9 @@ Drummer :: ~Drummer( void )
|
||||
|
||||
void Drummer :: noteOn( StkFloat instrument, StkFloat amplitude )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Drummer::NoteOn: instrument = " << instrument << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
|
||||
StkFloat gain = amplitude;
|
||||
if ( amplitude > 1.0 ) {
|
||||
errorString_ << "Drummer::noteOn: amplitude parameter is greater than 1.0 ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 1.0;
|
||||
}
|
||||
else if ( amplitude < 0.0 ) {
|
||||
errorString_ << "Drummer::noteOn: amplitude parameter is less than 0.0 ... doing nothing!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
if ( amplitude < 0.0 || amplitude > 1.0 ) {
|
||||
oStream_ << "Drummer::noteOn: amplitude parameter is out of bounds!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
// Yes, this is tres kludgey.
|
||||
@@ -100,8 +88,8 @@ void Drummer :: noteOn( StkFloat instrument, StkFloat amplitude )
|
||||
nSounding_++;
|
||||
}
|
||||
waves_[iWave].reset();
|
||||
filters_[iWave].setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[iWave].setGain( gain );
|
||||
filters_[iWave].setPole( 0.999 - (amplitude * 0.6) );
|
||||
filters_[iWave].setGain( amplitude );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -123,22 +111,24 @@ void Drummer :: noteOn( StkFloat instrument, StkFloat amplitude )
|
||||
}
|
||||
soundOrder_[iWave] = nSounding_ - 1;
|
||||
soundNumber_[iWave] = noteNumber;
|
||||
std::cout << "iWave = " << iWave << ", nSounding = " << nSounding_ << ", soundOrder[] = " << soundOrder_[iWave] << std::endl;
|
||||
//std::cout << "iWave = " << iWave << ", nSounding = " << nSounding_ << ", soundOrder[] = " << soundOrder_[iWave] << std::endl;
|
||||
|
||||
// Concatenate the STK rawwave path to the rawwave file
|
||||
waves_[iWave].openFile( (Stk::rawwavePath() + waveNames[ genMIDIMap[ noteNumber ] ]).c_str(), true );
|
||||
if ( Stk::sampleRate() != 22050.0 )
|
||||
waves_[iWave].setRate( 22050.0 / Stk::sampleRate() );
|
||||
filters_[iWave].setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[iWave].setGain( gain );
|
||||
filters_[iWave].setPole( 0.999 - (amplitude * 0.6) );
|
||||
filters_[iWave].setGain( amplitude );
|
||||
}
|
||||
|
||||
/*
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Drummer::noteOn: number sounding = " << nSounding_ << ", notes: ";
|
||||
for ( int i=0; i<nSounding_; i++ ) errorString_ << soundNumber_[i] << " ";
|
||||
errorString_ << '\n';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
oStream_ << "Drummer::noteOn: number sounding = " << nSounding_ << ", notes: ";
|
||||
for ( int i=0; i<nSounding_; i++ ) oStream_ << soundNumber_[i] << " ";
|
||||
oStream_ << '\n';
|
||||
handleError( StkError::WARNING );
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
void Drummer :: noteOff( StkFloat amplitude )
|
||||
|
||||
18
src/Echo.cpp
18
src/Echo.cpp
@@ -4,7 +4,7 @@
|
||||
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -29,26 +29,22 @@ void Echo :: clear( void )
|
||||
|
||||
void Echo :: setMaximumDelay( unsigned long delay )
|
||||
{
|
||||
length_ = delay;
|
||||
if ( delay == 0 ) {
|
||||
errorString_ << "Echo::setMaximumDelay: parameter cannot be zero ... setting to 10!";
|
||||
handleError( StkError::WARNING );
|
||||
length_ = 10;
|
||||
oStream_ << "Echo::setMaximumDelay: parameter cannot be zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
delayLine_.setMaximumDelay( length_ );
|
||||
delayLine_.setMaximumDelay( delay );
|
||||
}
|
||||
|
||||
void Echo :: setDelay( unsigned long delay )
|
||||
{
|
||||
unsigned long size = delay;
|
||||
if ( delay > length_ ) {
|
||||
errorString_ << "Echo::setDelay: parameter is greater than maximum delay length ... setting to max!";
|
||||
handleError( StkError::WARNING );
|
||||
size = length_;
|
||||
oStream_ << "Echo::setDelay: parameter is greater than maximum delay length!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
delayLine_.setDelay( size );
|
||||
delayLine_.setDelay( delay );
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -47,4 +47,38 @@ void Envelope :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
|
||||
rate_ = oldRate * rate_ / newRate;
|
||||
}
|
||||
|
||||
void Envelope :: setRate( StkFloat rate )
|
||||
{
|
||||
if ( rate < 0.0 ) {
|
||||
oStream_ << "Envelope::setRate: argument must be >= 0.0!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
rate_ = rate;
|
||||
}
|
||||
|
||||
void Envelope :: setTime( StkFloat time )
|
||||
{
|
||||
if ( time <= 0.0 ) {
|
||||
oStream_ << "Envelope::setTime: argument must be > 0.0!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
rate_ = 1.0 / ( time * Stk::sampleRate() );
|
||||
}
|
||||
|
||||
void Envelope :: setTarget( StkFloat target )
|
||||
{
|
||||
target_ = target;
|
||||
if ( value_ != target_ ) state_ = 1;
|
||||
}
|
||||
|
||||
void Envelope :: setValue( StkFloat value )
|
||||
{
|
||||
state_ = 0;
|
||||
target_ = value;
|
||||
value_ = value;
|
||||
lastFrame_[0] = value_;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
96
src/FM.cpp
96
src/FM.cpp
@@ -19,7 +19,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -32,7 +32,7 @@ FM :: FM( unsigned int operators )
|
||||
: nOperators_(operators)
|
||||
{
|
||||
if ( nOperators_ == 0 ) {
|
||||
errorString_ << "FM: Invalid number of operators (" << operators << ") argument to constructor!";
|
||||
oStream_ << "FM::FM: Number of operators must be greater than zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -91,8 +91,14 @@ void FM :: loadWaves( const char **filenames )
|
||||
|
||||
void FM :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
baseFrequency_ = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "FM::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
baseFrequency_ = frequency;
|
||||
for ( unsigned int i=0; i<nOperators_; i++ )
|
||||
waves_[i]->setFrequency( baseFrequency_ * ratios_[i] );
|
||||
}
|
||||
@@ -100,14 +106,12 @@ void FM :: setFrequency( StkFloat frequency )
|
||||
void FM :: setRatio( unsigned int waveIndex, StkFloat ratio )
|
||||
{
|
||||
if ( waveIndex < 0 ) {
|
||||
errorString_ << "FM::setRatio: waveIndex parameter is less than zero!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
oStream_ << "FM::setRatio: waveIndex parameter is less than zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else if ( waveIndex >= nOperators_ ) {
|
||||
errorString_ << "FM:setRatio: waveIndex parameter is greater than the number of operators!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
oStream_ << "FM:setRatio: waveIndex parameter is greater than the number of operators!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
ratios_[waveIndex] = ratio;
|
||||
@@ -120,14 +124,12 @@ void FM :: setRatio( unsigned int waveIndex, StkFloat ratio )
|
||||
void FM :: setGain( unsigned int waveIndex, StkFloat gain )
|
||||
{
|
||||
if ( waveIndex < 0 ) {
|
||||
errorString_ << "FM::setGain: waveIndex parameter is less than zero!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
oStream_ << "FM::setGain: waveIndex parameter is less than zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else if ( waveIndex >= nOperators_ ) {
|
||||
errorString_ << "FM::setGain: waveIndex parameter is greater than the number of operators!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
oStream_ << "FM::setGain: waveIndex parameter is greater than the number of operators!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
gains_[waveIndex] = gain;
|
||||
@@ -148,49 +150,37 @@ void FM :: keyOff( void )
|
||||
void FM :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
this->keyOff();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "FM::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void FM :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "FM::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "FM::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
if (number == __SK_Breath_) // 2
|
||||
this->setControl1( norm );
|
||||
else if (number == __SK_FootControl_) // 4
|
||||
this->setControl2( norm );
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
this->setModulationSpeed( norm * 12.0);
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
this->setModulationDepth( norm );
|
||||
else if (number == __SK_AfterTouch_Cont_) { // 128
|
||||
//adsr_[0]->setTarget( norm );
|
||||
adsr_[1]->setTarget( norm );
|
||||
//adsr_[2]->setTarget( norm );
|
||||
adsr_[3]->setTarget( norm );
|
||||
}
|
||||
else {
|
||||
errorString_ << "FM::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "FM::controlChange: number = " << number << ", value = " << value << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "FM::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_Breath_) // 2
|
||||
this->setControl1( normalizedValue );
|
||||
else if (number == __SK_FootControl_) // 4
|
||||
this->setControl2( normalizedValue );
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
this->setModulationSpeed( normalizedValue * 12.0);
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
this->setModulationDepth( normalizedValue );
|
||||
else if (number == __SK_AfterTouch_Cont_) { // 128
|
||||
//adsr_[0]->setTarget( normalizedValue );
|
||||
adsr_[1]->setTarget( normalizedValue );
|
||||
//adsr_[2]->setTarget( normalizedValue );
|
||||
adsr_[3]->setTarget( normalizedValue );
|
||||
}
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
oStream_ << "FM::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -75,6 +75,13 @@ FMVoices :: ~FMVoices( void )
|
||||
|
||||
void FMVoices :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "FMVoices::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat temp, temp2 = 0.0;
|
||||
int tempi = 0;
|
||||
unsigned int i = 0;
|
||||
@@ -118,51 +125,38 @@ void FMVoices :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
tilt_[1] = amplitude * amplitude;
|
||||
tilt_[2] = tilt_[1] * amplitude;
|
||||
this->keyOn();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "FMVoices::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void FMVoices :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "FMVoices::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "FMVoices::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "FMVoices::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_Breath_) // 2
|
||||
gains_[3] = fmGains_[(int) ( norm * 99.9 )];
|
||||
gains_[3] = fmGains_[(int) ( normalizedValue * 99.9 )];
|
||||
else if (number == __SK_FootControl_) { // 4
|
||||
currentVowel_ = (int) (norm * 128.0);
|
||||
currentVowel_ = (int) (normalizedValue * 128.0);
|
||||
this->setFrequency(baseFrequency_);
|
||||
}
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
this->setModulationSpeed( norm * 12.0);
|
||||
this->setModulationSpeed( normalizedValue * 12.0);
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
this->setModulationDepth( norm );
|
||||
this->setModulationDepth( normalizedValue );
|
||||
else if (number == __SK_AfterTouch_Cont_) { // 128
|
||||
tilt_[0] = norm;
|
||||
tilt_[1] = norm * norm;
|
||||
tilt_[2] = tilt_[1] * norm;
|
||||
tilt_[0] = normalizedValue;
|
||||
tilt_[1] = normalizedValue * normalizedValue;
|
||||
tilt_[2] = tilt_[1] * normalizedValue;
|
||||
}
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
errorString_ << "FMVoices::controlChange: undefined control number (" << number << ")!";
|
||||
oStream_ << "FMVoices::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "FMVoices::controlChange: number = " << number << ", value = " << value << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -127,7 +127,7 @@ StkFloat FileLoop :: tick( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= data_.channels() ) {
|
||||
errorString_ << "FileLoop::tick(): channel argument and soundfile data are incompatible!";
|
||||
oStream_ << "FileLoop::tick(): channel argument and soundfile data are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
@@ -197,7 +197,7 @@ StkFrames& FileLoop :: tick( StkFrames& frames )
|
||||
{
|
||||
if ( !file_.isOpen() ) {
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "FileLoop::tick(): no file data is loaded!";
|
||||
oStream_ << "FileLoop::tick(): no file data is loaded!";
|
||||
handleError( StkError::WARNING );
|
||||
#endif
|
||||
return frames;
|
||||
@@ -206,7 +206,7 @@ StkFrames& FileLoop :: tick( StkFrames& frames )
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( nChannels != frames.channels() ) {
|
||||
errorString_ << "FileLoop::tick(): StkFrames argument is incompatible with file data!";
|
||||
oStream_ << "FileLoop::tick(): StkFrames argument is incompatible with file data!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
375
src/FileRead.cpp
375
src/FileRead.cpp
@@ -13,17 +13,19 @@
|
||||
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 - 2007.
|
||||
*/
|
||||
@@ -39,7 +41,7 @@
|
||||
namespace stk {
|
||||
|
||||
FileRead :: FileRead()
|
||||
: fd_(0)
|
||||
: fd_(0), fileSize_(0), channels_(0), dataType_(0), fileRate_(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -61,6 +63,10 @@ void FileRead :: close( void )
|
||||
if ( fd_ ) fclose( fd_ );
|
||||
fd_ = 0;
|
||||
wavFile_ = false;
|
||||
fileSize_ = 0;
|
||||
channels_ = 0;
|
||||
dataType_ = 0;
|
||||
fileRate_ = 0.0;
|
||||
}
|
||||
|
||||
bool FileRead :: isOpen( void )
|
||||
@@ -78,7 +84,7 @@ void FileRead :: open( std::string fileName, bool typeRaw, unsigned int nChannel
|
||||
// Try to open the file.
|
||||
fd_ = fopen( fileName.c_str(), "rb" );
|
||||
if ( !fd_ ) {
|
||||
errorString_ << "FileRead::open: could not open or find file (" << fileName << ")!";
|
||||
oStream_ << "FileRead::open: could not open or find file (" << fileName << ")!";
|
||||
handleError( StkError::FILE_NOT_FOUND );
|
||||
}
|
||||
|
||||
@@ -104,7 +110,7 @@ void FileRead :: open( std::string fileName, bool typeRaw, unsigned int nChannel
|
||||
!strncmp( header, "IM", 2 ) )
|
||||
result = getMatInfo( fileName.c_str() );
|
||||
else {
|
||||
errorString_ << "FileRead::open: file (" << fileName << ") format unknown.";
|
||||
oStream_ << "FileRead::open: file (" << fileName << ") format unknown.";
|
||||
handleError( StkError::FILE_UNKNOWN_FORMAT );
|
||||
}
|
||||
}
|
||||
@@ -116,14 +122,14 @@ void FileRead :: open( std::string fileName, bool typeRaw, unsigned int nChannel
|
||||
|
||||
// Check for empty files.
|
||||
if ( fileSize_ == 0 ) {
|
||||
errorString_ << "FileRead::open: file (" << fileName << ") data size is zero!";
|
||||
oStream_ << "FileRead::open: file (" << fileName << ") data size is zero!";
|
||||
handleError( StkError::FILE_ERROR );
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
errorString_ << "FileRead::open: error reading file (" << fileName << ")!";
|
||||
oStream_ << "FileRead::open: error reading file (" << fileName << ")!";
|
||||
handleError( StkError::FILE_ERROR );
|
||||
}
|
||||
|
||||
@@ -132,7 +138,7 @@ bool FileRead :: getRawInfo( const char *fileName, unsigned int nChannels, StkFo
|
||||
// Use the system call "stat" to determine the file length.
|
||||
struct stat filestat;
|
||||
if ( stat(fileName, &filestat) == -1 ) {
|
||||
errorString_ << "FileRead: Could not stat RAW file (" << fileName << ").";
|
||||
oStream_ << "FileRead: Could not stat RAW file (" << fileName << ").";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -199,8 +205,8 @@ bool FileRead :: getWavInfo( const char *fileName )
|
||||
#endif
|
||||
if ( fseek(fd_, dataOffset_, SEEK_SET) == -1 ) goto error;
|
||||
}
|
||||
if (format_tag != 1 && format_tag != 3 ) { // PCM = 1, FLOAT = 3
|
||||
errorString_ << "FileRead: "<< fileName << " contains an unsupported data format type (" << format_tag << ").";
|
||||
if ( format_tag != 1 && format_tag != 3 ) { // PCM = 1, FLOAT = 3
|
||||
oStream_ << "FileRead: "<< fileName << " contains an unsupported data format type (" << format_tag << ").";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -228,21 +234,23 @@ bool FileRead :: getWavInfo( const char *fileName )
|
||||
swap16((unsigned char *)&temp);
|
||||
#endif
|
||||
if ( format_tag == 1 ) {
|
||||
if (temp == 8)
|
||||
if ( temp == 8 )
|
||||
dataType_ = STK_SINT8;
|
||||
else if (temp == 16)
|
||||
else if ( temp == 16 )
|
||||
dataType_ = STK_SINT16;
|
||||
else if (temp == 32)
|
||||
else if ( temp == 24 )
|
||||
dataType_ = STK_SINT24;
|
||||
else if ( temp == 32 )
|
||||
dataType_ = STK_SINT32;
|
||||
}
|
||||
else if ( format_tag == 3 ) {
|
||||
if (temp == 32)
|
||||
if ( temp == 32 )
|
||||
dataType_ = STK_FLOAT32;
|
||||
else if (temp == 64)
|
||||
else if ( temp == 64 )
|
||||
dataType_ = STK_FLOAT64;
|
||||
}
|
||||
if ( dataType_ == 0 ) {
|
||||
errorString_ << "FileRead: " << temp << " bits per sample with data format " << format_tag << " are not supported (" << fileName << ").";
|
||||
oStream_ << "FileRead: " << temp << " bits per sample with data format " << format_tag << " are not supported (" << fileName << ").";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -268,7 +276,8 @@ bool FileRead :: getWavInfo( const char *fileName )
|
||||
#ifndef __LITTLE_ENDIAN__
|
||||
swap32((unsigned char *)&bytes);
|
||||
#endif
|
||||
fileSize_ = 8 * bytes / temp / channels_; // sample frames
|
||||
fileSize_ = bytes / temp / channels_; // sample frames
|
||||
fileSize_ *= 8; // sample frames
|
||||
|
||||
dataOffset_ = ftell(fd_);
|
||||
byteswap_ = false;
|
||||
@@ -280,7 +289,7 @@ bool FileRead :: getWavInfo( const char *fileName )
|
||||
return true;
|
||||
|
||||
error:
|
||||
errorString_ << "FileRead: error reading WAV file (" << fileName << ").";
|
||||
oStream_ << "FileRead: error reading WAV file (" << fileName << ").";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -293,6 +302,7 @@ bool FileRead :: getSndInfo( const char *fileName )
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
swap32((unsigned char *)&format);
|
||||
#endif
|
||||
|
||||
if (format == 2) dataType_ = STK_SINT8;
|
||||
else if (format == 3) dataType_ = STK_SINT16;
|
||||
else if (format == 4) dataType_ = STK_SINT24;
|
||||
@@ -300,7 +310,7 @@ bool FileRead :: getSndInfo( const char *fileName )
|
||||
else if (format == 6) dataType_ = STK_FLOAT32;
|
||||
else if (format == 7) dataType_ = STK_FLOAT64;
|
||||
else {
|
||||
errorString_ << "FileRead: data format in file " << fileName << " is not supported.";
|
||||
oStream_ << "FileRead: data format in file " << fileName << " is not supported.";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -320,11 +330,13 @@ bool FileRead :: getSndInfo( const char *fileName )
|
||||
#endif
|
||||
channels_ = chans;
|
||||
|
||||
UINT32 offset;
|
||||
if ( fseek(fd_, 4, SEEK_SET) == -1 ) goto error;
|
||||
if ( fread(&dataOffset_, 4, 1, fd_) != 1 ) goto error;
|
||||
if ( fread(&offset, 4, 1, fd_) != 1 ) goto error;
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
swap32((unsigned char *)&dataOffset_);
|
||||
swap32((unsigned char *)&offset);
|
||||
#endif
|
||||
dataOffset_ = offset;
|
||||
|
||||
// Get length of data from the header.
|
||||
if ( fread(&fileSize_, 4, 1, fd_) != 1 ) goto error;
|
||||
@@ -351,7 +363,7 @@ bool FileRead :: getSndInfo( const char *fileName )
|
||||
return true;
|
||||
|
||||
error:
|
||||
errorString_ << "FileRead: Error reading SND file (" << fileName << ").";
|
||||
oStream_ << "FileRead: Error reading SND file (" << fileName << ").";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -442,7 +454,7 @@ bool FileRead :: getAifInfo( const char *fileName )
|
||||
else if ( (!strncmp(id, "fl64", 4) || !strncmp(id, "FL64", 4)) && temp == 64 ) dataType_ = STK_FLOAT64;
|
||||
}
|
||||
if ( dataType_ == 0 ) {
|
||||
errorString_ << "FileRead: AIFF/AIFC file (" << fileName << ") has unsupported data type (" << id << ").";
|
||||
oStream_ << "FileRead: AIFF/AIFC file (" << fileName << ") has unsupported data type (" << id << ").";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -473,10 +485,44 @@ bool FileRead :: getAifInfo( const char *fileName )
|
||||
return true;
|
||||
|
||||
error:
|
||||
errorString_ << "FileRead: Error reading AIFF file (" << fileName << ").";
|
||||
oStream_ << "FileRead: Error reading AIFF file (" << fileName << ").";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileRead :: findNextMatArray( SINT32 *chunkSize, SINT32 *rows, SINT32 *columns, SINT32 *nametype )
|
||||
{
|
||||
// Look for the next data array element. The file pointer should be
|
||||
// at the data element type when this function is called.
|
||||
SINT32 datatype;
|
||||
*chunkSize = 0;
|
||||
do {
|
||||
if ( fseek(fd_, *chunkSize, SEEK_CUR) == -1 ) return false;
|
||||
if ( fread(&datatype, 4, 1, fd_) != 1 ) return false;
|
||||
if ( byteswap_ ) swap32((unsigned char *)&datatype);
|
||||
if ( fread(chunkSize, 4, 1, fd_) != 1 ) return false;
|
||||
if ( byteswap_ ) swap32((unsigned char *)chunkSize);
|
||||
} while ( datatype != 14 );
|
||||
|
||||
// Check dimension subelement size to make sure 2D
|
||||
if ( fseek(fd_, 20, SEEK_CUR) == -1 ) return false;
|
||||
SINT32 size;
|
||||
if ( fread(&size, 4, 1, fd_) != 1 ) return false;
|
||||
if ( byteswap_ ) swap32((unsigned char *)&size);
|
||||
if ( size != 8 ) return false;
|
||||
|
||||
// Read dimensions data
|
||||
if ( fread(rows, 4, 1, fd_) != 1 ) return false;
|
||||
if ( byteswap_ ) swap32((unsigned char *)rows);
|
||||
if ( fread(columns, 4, 1, fd_) != 1 ) return false;
|
||||
if ( byteswap_ ) swap32((unsigned char *)columns);
|
||||
|
||||
// Read array name subelement type
|
||||
if ( fread(nametype, 4, 1, fd_) != 1 ) return false;
|
||||
if ( byteswap_ ) swap32((unsigned char *)nametype);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileRead :: getMatInfo( const char *fileName )
|
||||
{
|
||||
// MAT-file formatting information is available at:
|
||||
@@ -490,7 +536,7 @@ bool FileRead :: getMatInfo( const char *fileName )
|
||||
// a Version 4 MAT-file.
|
||||
head[4] = '\0';
|
||||
if ( strstr(head, "0") ) {
|
||||
errorString_ << "FileRead: " << fileName << " appears to be a Version 4 MAT-file, which is not currently supported.";
|
||||
oStream_ << "FileRead: " << fileName << " appears to be a Version 4 MAT-file, which is not currently supported.";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -510,79 +556,164 @@ bool FileRead :: getMatInfo( const char *fileName )
|
||||
else if ( strncmp(mi, "MI", 2) ) goto error;
|
||||
#endif
|
||||
|
||||
// Check the data element type
|
||||
SINT32 datatype;
|
||||
if ( fread(&datatype, 4, 1, fd_) != 1 ) goto error;
|
||||
if ( byteswap_ ) swap32((unsigned char *)&datatype);
|
||||
if (datatype != 14) {
|
||||
errorString_ << "FileRead: The file does not contain a single Matlab array (or matrix) data element.";
|
||||
return false;
|
||||
}
|
||||
// We are expecting a data element containing the audio data and an
|
||||
// optional data element containing the sample rate (with an array
|
||||
// name of "fs"). Both elements should be stored as a Matlab array
|
||||
// type (14).
|
||||
|
||||
// Determine the array data type.
|
||||
SINT32 tmp;
|
||||
SINT32 size;
|
||||
if ( fseek(fd_, 168, SEEK_SET) == -1 ) goto error;
|
||||
if ( fread(&tmp, 4, 1, fd_) != 1 ) goto error;
|
||||
if (byteswap_) swap32((unsigned char *)&tmp);
|
||||
if (tmp == 1) { // array name > 4 characters
|
||||
if ( fread(&tmp, 4, 1, fd_) != 1 ) goto error; // get array name length
|
||||
if (byteswap_) swap32((unsigned char *)&tmp);
|
||||
size = (SINT32) ceil((float)tmp / 8);
|
||||
if ( fseek(fd_, size*8, SEEK_CUR) == -1 ) goto error; // jump over array name
|
||||
}
|
||||
else { // array name <= 4 characters, compressed data element
|
||||
if ( fseek(fd_, 4, SEEK_CUR) == -1 ) goto error;
|
||||
}
|
||||
if ( fread(&tmp, 4, 1, fd_) != 1 ) goto error;
|
||||
if (byteswap_) swap32((unsigned char *)&tmp);
|
||||
if ( tmp == 1 ) dataType_ = STK_SINT8;
|
||||
else if ( tmp == 3 ) dataType_ = STK_SINT16;
|
||||
else if ( tmp == 5 ) dataType_ = STK_SINT32;
|
||||
else if ( tmp == 7 ) dataType_ = STK_FLOAT32;
|
||||
else if ( tmp == 9 ) dataType_ = STK_FLOAT64;
|
||||
else {
|
||||
errorString_ << "FileRead: The MAT-file array data format (" << tmp << ") is not supported.";
|
||||
return false;
|
||||
}
|
||||
bool doneParsing, haveData, haveSampleRate;
|
||||
SINT32 chunkSize, rows, columns, nametype;
|
||||
int dataoffset;
|
||||
doneParsing = false;
|
||||
haveData = false;
|
||||
haveSampleRate = false;
|
||||
while ( !doneParsing ) {
|
||||
|
||||
// Get number of rows from the header.
|
||||
SINT32 rows;
|
||||
if ( fseek(fd_, 160, SEEK_SET) == -1 ) goto error;
|
||||
if ( fread(&rows, 4, 1, fd_) != 1 ) goto error;
|
||||
if (byteswap_) swap32((unsigned char *)&rows);
|
||||
dataoffset = ftell( fd_ ); // save location in file
|
||||
if ( findNextMatArray( &chunkSize, &rows, &columns, &nametype ) == false ) {
|
||||
// No more Matlab array type chunks found.
|
||||
if ( !haveData ) {
|
||||
oStream_ << "FileRead: No audio data found in MAT-file (" << fileName << ").";
|
||||
return false;
|
||||
}
|
||||
else if ( !haveSampleRate ) {
|
||||
fileRate_ = 44100.0;
|
||||
oStream_ << "FileRead: No sample rate found ... assuming 44100.0";
|
||||
handleError( StkError::WARNING );
|
||||
return true;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
|
||||
// Get number of columns from the header.
|
||||
SINT32 columns;
|
||||
if ( fread(&columns, 4, 1, fd_) != 1 ) goto error;
|
||||
if (byteswap_) swap32((unsigned char *)&columns);
|
||||
if ( !haveSampleRate && rows == 1 && columns == 1 ) { // Parse for sample rate.
|
||||
|
||||
// Assume channels = smaller of rows or columns.
|
||||
if (rows < columns) {
|
||||
channels_ = rows;
|
||||
fileSize_ = columns;
|
||||
SINT32 namesize = 4;
|
||||
if ( nametype == 1 ) { // array name > 4 characters
|
||||
if ( fread(&namesize, 4, 1, fd_) != 1 ) goto error;
|
||||
if ( byteswap_ ) swap32((unsigned char *)namesize);
|
||||
if ( namesize != 2 ) goto tryagain; // expecting name = "fs"
|
||||
namesize = 8; // field must be padded to multiple of 8 bytes
|
||||
}
|
||||
char name[3]; name[2] = '\0';
|
||||
if ( fread(&name, 2, 1, fd_) != 1) goto error;
|
||||
if ( strncmp(name, "fs", 2) ) goto tryagain;
|
||||
|
||||
// Jump to real part data subelement, which is likely to be in a
|
||||
// small data format.
|
||||
if ( fseek(fd_, namesize-2, SEEK_CUR) == -1 ) goto error;
|
||||
UINT32 type;
|
||||
StkFloat srate;
|
||||
if ( fread(&type, 4, 1, fd_) != 1 ) goto error;
|
||||
if ( byteswap_ ) swap32((unsigned char *)&type);
|
||||
if ( (type & 0xffff0000) != 0 ) // small data format
|
||||
type = (type & 0x0000ffff);
|
||||
else
|
||||
if ( fseek(fd_, 4, SEEK_CUR) == -1 ) goto error;
|
||||
if ( type == 1 ) { // SINT8
|
||||
signed char rate;
|
||||
if ( fread(&rate, 1, 1, fd_) != 1 ) goto error;
|
||||
srate = (StkFloat) rate;
|
||||
}
|
||||
if ( type == 2 ) { // UINT8
|
||||
unsigned char rate;
|
||||
if ( fread(&rate, 1, 1, fd_) != 1 ) goto error;
|
||||
srate = (StkFloat) rate;
|
||||
}
|
||||
else if ( type == 3 ) { // SINT16
|
||||
SINT16 rate;
|
||||
if ( fread(&rate, 2, 1, fd_) != 1 ) goto error;
|
||||
if ( byteswap_ ) swap16((unsigned char *)&rate);
|
||||
srate = (StkFloat) rate;
|
||||
}
|
||||
else if ( type == 4 ) { // UINT16
|
||||
UINT16 rate;
|
||||
if ( fread(&rate, 2, 1, fd_) != 1 ) goto error;
|
||||
if ( byteswap_ ) swap16((unsigned char *)&rate);
|
||||
srate = (StkFloat) rate;
|
||||
}
|
||||
else if ( type == 5 ) { // SINT32
|
||||
SINT32 rate;
|
||||
if ( fread(&rate, 4, 1, fd_) != 1 ) goto error;
|
||||
if ( byteswap_ ) swap32((unsigned char *)&rate);
|
||||
srate = (StkFloat) rate;
|
||||
}
|
||||
else if ( type == 6 ) { // UINT32
|
||||
UINT32 rate;
|
||||
if ( fread(&rate, 4, 1, fd_) != 1 ) goto error;
|
||||
if ( byteswap_ ) swap32((unsigned char *)&rate);
|
||||
srate = (StkFloat) rate;
|
||||
}
|
||||
else if ( type == 7 ) { // FLOAT32
|
||||
FLOAT32 rate;
|
||||
if ( fread(&rate, 4, 1, fd_) != 1 ) goto error;
|
||||
if ( byteswap_ ) swap32((unsigned char *)&rate);
|
||||
srate = (StkFloat) rate;
|
||||
}
|
||||
else if ( type == 9 ) { // FLOAT64
|
||||
FLOAT64 rate;
|
||||
if ( fread(&rate, 8, 1, fd_) != 1 ) goto error;
|
||||
if ( byteswap_ ) swap64((unsigned char *)&rate);
|
||||
srate = (StkFloat) rate;
|
||||
}
|
||||
else
|
||||
goto tryagain;
|
||||
|
||||
if ( srate > 0 ) fileRate_ = srate;
|
||||
haveSampleRate = true;
|
||||
}
|
||||
else if ( !haveData ) { // Parse for data.
|
||||
|
||||
// Assume channels = smaller of rows or columns.
|
||||
if ( rows < columns ) {
|
||||
channels_ = rows;
|
||||
fileSize_ = columns;
|
||||
}
|
||||
else {
|
||||
oStream_ << "FileRead: Transpose the MAT-file array so that audio channels fill matrix rows (not columns).";
|
||||
return false;
|
||||
}
|
||||
|
||||
SINT32 namesize = 4;
|
||||
if ( nametype == 1 ) { // array name > 4 characters
|
||||
if ( fread(&namesize, 4, 1, fd_) != 1 ) goto error;
|
||||
if ( byteswap_ ) swap32((unsigned char *)namesize);
|
||||
namesize = (SINT32) ceil((float)namesize / 8);
|
||||
if ( fseek( fd_, namesize*8, SEEK_CUR) == -1 ) goto error; // jump over array name
|
||||
}
|
||||
else {
|
||||
if ( fseek( fd_, 4, SEEK_CUR ) == -1 ) goto error;
|
||||
}
|
||||
|
||||
// Now at real part data subelement
|
||||
SINT32 type;
|
||||
if ( fread(&type, 4, 1, fd_) != 1 ) goto error;
|
||||
if ( byteswap_ ) swap32((unsigned char *)&type);
|
||||
if ( type == 1 ) dataType_ = STK_SINT8;
|
||||
else if ( type == 3 ) dataType_ = STK_SINT16;
|
||||
else if ( type == 5 ) dataType_ = STK_SINT32;
|
||||
else if ( type == 7 ) dataType_ = STK_FLOAT32;
|
||||
else if ( type == 9 ) dataType_ = STK_FLOAT64;
|
||||
else {
|
||||
oStream_ << "FileRead: The MAT-file array data format (" << type << ") is not supported.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Jump to the data.
|
||||
if ( fseek(fd_, 4, SEEK_CUR) == -1 ) goto error;
|
||||
dataOffset_ = ftell(fd_);
|
||||
haveData = true;
|
||||
}
|
||||
|
||||
tryagain:
|
||||
if ( haveData && haveSampleRate ) doneParsing = true;
|
||||
else // jump to end of data element and keep trying
|
||||
if ( fseek( fd_, dataoffset+chunkSize+8, SEEK_SET) == -1 ) goto error;
|
||||
}
|
||||
else {
|
||||
errorString_ << "FileRead: Transpose the MAT-file array so that audio channels fill matrix rows (not columns).";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Move read pointer to the data in the file.
|
||||
SINT32 headsize;
|
||||
if ( fseek(fd_, 132, SEEK_SET) == -1 ) goto error;
|
||||
if ( fread(&headsize, 4, 1, fd_) != 1 ) goto error; // file size from 132nd byte
|
||||
if (byteswap_) swap32((unsigned char *)&headsize);
|
||||
headsize -= fileSize_ * 8 * channels_;
|
||||
if ( fseek(fd_, headsize, SEEK_CUR) == -1 ) goto error;
|
||||
dataOffset_ = ftell(fd_);
|
||||
|
||||
// Assume MAT-files have 44100 Hz sample rate.
|
||||
fileRate_ = 44100.0;
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
errorString_ << "FileRead: Error reading MAT-file (" << fileName << ").";
|
||||
oStream_ << "FileRead: Error reading MAT-file (" << fileName << ") header.";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -590,21 +721,19 @@ void FileRead :: read( StkFrames& buffer, unsigned long startFrame, bool doNorma
|
||||
{
|
||||
// Make sure we have an open file.
|
||||
if ( fd_ == 0 ) {
|
||||
errorString_ << "FileRead::read: a file is not open!";
|
||||
Stk::handleError( StkError::WARNING );
|
||||
return;
|
||||
oStream_ << "FileRead::read: a file is not open!";
|
||||
Stk::handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
// Check the buffer size.
|
||||
unsigned int nFrames = buffer.frames();
|
||||
if ( nFrames == 0 ) {
|
||||
errorString_ << "FileRead::read: StkFrames buffer size is zero ... no data read!";
|
||||
Stk::handleError( StkError::WARNING );
|
||||
return;
|
||||
oStream_ << "FileRead::read: StkFrames buffer size is zero ... no data read!";
|
||||
Stk::handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
if ( buffer.channels() != channels_ ) {
|
||||
errorString_ << "FileRead::read: StkFrames argument has incompatible number of channels!";
|
||||
oStream_ << "FileRead::read: StkFrames argument has incompatible number of channels!";
|
||||
Stk::handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -709,19 +838,39 @@ void FileRead :: read( StkFrames& buffer, unsigned long startFrame, bool doNorma
|
||||
else if ( dataType_ == STK_SINT24 ) {
|
||||
// 24-bit values are harder to import efficiently since there is
|
||||
// no native 24-bit type. The following routine works but is much
|
||||
// less efficient that that used for the other data types.
|
||||
SINT32 buf;
|
||||
StkFloat gain = 1.0 / 8388608.0;
|
||||
// less efficient than that used for the other data types.
|
||||
SINT32 temp;
|
||||
unsigned char *ptr = (unsigned char *) &temp;
|
||||
StkFloat gain = 1.0 / 2147483648.0;
|
||||
if ( fseek(fd_, dataOffset_+(offset*3), SEEK_SET ) == -1 ) goto error;
|
||||
for ( i=0; i<nSamples; i++ ) {
|
||||
if ( fread( &buf, 3, 1, fd_ ) != 1 ) goto error;
|
||||
buf >>= 8;
|
||||
if ( byteswap_ )
|
||||
swap32( (unsigned char *) &buf );
|
||||
if ( doNormalize )
|
||||
buffer[i] = buf * gain;
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
if ( byteswap_ ) {
|
||||
if ( fread( ptr, 3, 1, fd_ ) != 1 ) goto error;
|
||||
temp &= 0x00ffffff;
|
||||
swap32( (unsigned char *) ptr );
|
||||
}
|
||||
else {
|
||||
if ( fread( ptr+1, 3, 1, fd_ ) != 1 ) goto error;
|
||||
temp &= 0xffffff00;
|
||||
}
|
||||
#else
|
||||
if ( byteswap_ ) {
|
||||
if ( fread( ptr+1, 3, 1, fd_ ) != 1 ) goto error;
|
||||
temp &= 0xffffff00;
|
||||
swap32( (unsigned char *) ptr );
|
||||
}
|
||||
else {
|
||||
if ( fread( ptr, 3, 1, fd_ ) != 1 ) goto error;
|
||||
temp &= 0x00ffffff;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( doNormalize ) {
|
||||
buffer[i] = (StkFloat) temp * gain; // "gain" also includes 1 / 256 factor.
|
||||
}
|
||||
else
|
||||
buffer[i] = buf;
|
||||
buffer[i] = (StkFloat) temp / 256; // right shift without affecting the sign bit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -730,7 +879,7 @@ void FileRead :: read( StkFrames& buffer, unsigned long startFrame, bool doNorma
|
||||
return;
|
||||
|
||||
error:
|
||||
errorString_ << "FileRead: Error reading file data.";
|
||||
oStream_ << "FileRead: Error reading file data.";
|
||||
handleError( StkError::FILE_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,20 +10,21 @@
|
||||
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "FileWrite.h"
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
namespace stk {
|
||||
@@ -36,58 +37,64 @@ const FileWrite::FILE_TYPE FileWrite :: FILE_MAT = 5;
|
||||
|
||||
// WAV header structure. See ftp://ftp.isi.edu/in-notes/rfc2361.txt
|
||||
// for information regarding format codes.
|
||||
struct wavhdr {
|
||||
struct WaveHeader {
|
||||
char riff[4]; // "RIFF"
|
||||
SINT32 file_size; // in bytes
|
||||
SINT32 fileSize; // in bytes
|
||||
char wave[4]; // "WAVE"
|
||||
char fmt[4]; // "fmt "
|
||||
SINT32 chunk_size; // in bytes (16 for PCM)
|
||||
SINT16 format_tag; // 1=PCM, 2=ADPCM, 3=IEEE float, 6=A-Law, 7=Mu-Law
|
||||
SINT16 num_chans; // 1=mono, 2=stereo
|
||||
SINT32 sample_rate;
|
||||
SINT32 bytes_per_sec;
|
||||
SINT16 bytes_per_samp; // 2=16-bit mono, 4=16-bit stereo
|
||||
SINT16 bits_per_samp;
|
||||
char data[4]; // "data"
|
||||
SINT32 data_length; // in bytes
|
||||
SINT32 chunkSize; // in bytes (16 for PCM)
|
||||
SINT16 formatCode; // 1=PCM, 2=ADPCM, 3=IEEE float, 6=A-Law, 7=Mu-Law
|
||||
SINT16 nChannels; // 1=mono, 2=stereo
|
||||
SINT32 sampleRate;
|
||||
SINT32 bytesPerSecond;
|
||||
SINT16 bytesPerSample; // 2=16-bit mono, 4=16-bit stereo
|
||||
SINT16 bitsPerSample;
|
||||
SINT16 cbSize; // size of extension
|
||||
SINT16 validBits; // valid bits per sample
|
||||
SINT32 channelMask; // speaker position mask
|
||||
char subformat[16]; // format code and GUID
|
||||
char fact[4]; // "fact"
|
||||
SINT32 factSize; // fact chunk size
|
||||
SINT32 frames; // sample frames
|
||||
};
|
||||
|
||||
// SND (AU) header structure (NeXT and Sun).
|
||||
struct sndhdr {
|
||||
struct SndHeader {
|
||||
char pref[4];
|
||||
SINT32 hdr_length;
|
||||
SINT32 data_length;
|
||||
SINT32 headerBytes;
|
||||
SINT32 dataBytes;
|
||||
SINT32 format;
|
||||
SINT32 sample_rate;
|
||||
SINT32 num_channels;
|
||||
SINT32 sampleRate;
|
||||
SINT32 nChannels;
|
||||
char comment[16];
|
||||
};
|
||||
|
||||
// AIFF/AIFC header structure ... only the part common to both
|
||||
// formats.
|
||||
struct aifhdr {
|
||||
struct AifHeader {
|
||||
char form[4]; // "FORM"
|
||||
SINT32 form_size; // in bytes
|
||||
SINT32 formSize; // in bytes
|
||||
char aiff[4]; // "AIFF" or "AIFC"
|
||||
char comm[4]; // "COMM"
|
||||
SINT32 comm_size; // "COMM" chunk size (18 for AIFF, 24 for AIFC)
|
||||
SINT16 num_chans; // number of channels
|
||||
unsigned long sample_frames; // sample frames of audio data
|
||||
SINT16 sample_size; // in bits
|
||||
SINT32 commSize; // "COMM" chunk size (18 for AIFF, 24 for AIFC)
|
||||
SINT16 nChannels; // number of channels
|
||||
unsigned long sampleFrames; // sample frames of audio data
|
||||
SINT16 sampleSize; // in bits
|
||||
unsigned char srate[10]; // IEEE 754 floating point format
|
||||
};
|
||||
|
||||
struct aifssnd {
|
||||
struct AifSsnd {
|
||||
char ssnd[4]; // "SSND"
|
||||
SINT32 ssnd_size; // "SSND" chunk size
|
||||
SINT32 ssndSize; // "SSND" chunk size
|
||||
unsigned long offset; // data offset in data block (should be 0)
|
||||
unsigned long block_size; // not used by STK (should be 0)
|
||||
unsigned long blockSize; // not used by STK (should be 0)
|
||||
};
|
||||
|
||||
// MAT-file 5 header structure.
|
||||
struct mathdr {
|
||||
struct MatHeader {
|
||||
char heading[124]; // Header text field
|
||||
SINT16 hff[2]; // Header flag fields
|
||||
SINT32 fs[16]; // Sample rate data element
|
||||
SINT32 adf[11]; // Array data format fields
|
||||
// There's more, but it's of variable length
|
||||
};
|
||||
@@ -138,7 +145,7 @@ void FileWrite :: open( std::string fileName, unsigned int nChannels, FileWrite:
|
||||
this->close();
|
||||
|
||||
if ( nChannels < 1 ) {
|
||||
errorString_ << "FileWrite::open: then channels argument must be greater than zero!";
|
||||
oStream_ << "FileWrite::open: then channels argument must be greater than zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -146,9 +153,9 @@ void FileWrite :: open( std::string fileName, unsigned int nChannels, FileWrite:
|
||||
fileType_ = type;
|
||||
|
||||
if ( format != STK_SINT8 && format != STK_SINT16 &&
|
||||
format != STK_SINT32 && format != STK_FLOAT32 &&
|
||||
format != STK_FLOAT64 ) {
|
||||
errorString_ << "FileWrite::open: unknown data type (" << format << ") specified!";
|
||||
format != STK_SINT24 && format != STK_SINT32 &&
|
||||
format != STK_FLOAT32 && format != STK_FLOAT64 ) {
|
||||
oStream_ << "FileWrite::open: unknown data type (" << format << ") specified!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
dataType_ = format;
|
||||
@@ -156,21 +163,21 @@ void FileWrite :: open( std::string fileName, unsigned int nChannels, FileWrite:
|
||||
bool result = false;
|
||||
if ( fileType_ == FILE_RAW ) {
|
||||
if ( channels_ != 1 ) {
|
||||
errorString_ << "FileWrite::open: STK RAW files are, by definition, always monaural (channels = " << nChannels << " not supported)!";
|
||||
oStream_ << "FileWrite::open: STK RAW files are, by definition, always monaural (channels = " << nChannels << " not supported)!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
result = setRawFile( fileName.c_str() );
|
||||
result = setRawFile( fileName );
|
||||
}
|
||||
else if ( fileType_ == FILE_WAV )
|
||||
result = setWavFile( fileName.c_str() );
|
||||
result = setWavFile( fileName );
|
||||
else if ( fileType_ == FILE_SND )
|
||||
result = setSndFile( fileName.c_str() );
|
||||
result = setSndFile( fileName );
|
||||
else if ( fileType_ == FILE_AIF )
|
||||
result = setAifFile( fileName.c_str() );
|
||||
result = setAifFile( fileName );
|
||||
else if ( fileType_ == FILE_MAT )
|
||||
result = setMatFile( fileName.c_str() );
|
||||
result = setMatFile( fileName );
|
||||
else {
|
||||
errorString_ << "FileWrite::open: unknown file type (" << fileType_ << ") specified!";
|
||||
oStream_ << "FileWrite::open: unknown file type (" << fileType_ << ") specified!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -180,21 +187,19 @@ void FileWrite :: open( std::string fileName, unsigned int nChannels, FileWrite:
|
||||
frameCounter_ = 0;
|
||||
}
|
||||
|
||||
bool FileWrite :: setRawFile( const char *fileName )
|
||||
bool FileWrite :: setRawFile( std::string fileName )
|
||||
{
|
||||
char name[8192];
|
||||
strncpy(name, fileName, 8192);
|
||||
if ( strstr(name, ".raw") == NULL) strcat(name, ".raw");
|
||||
fd_ = fopen(name, "wb");
|
||||
if ( fileName.find( ".raw" ) == std::string::npos ) fileName += ".raw";
|
||||
fd_ = fopen( fileName.c_str(), "wb" );
|
||||
if ( !fd_ ) {
|
||||
errorString_ << "FileWrite: could not create RAW file: " << name << '.';
|
||||
oStream_ << "FileWrite: could not create RAW file: " << fileName << '.';
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( dataType_ != STK_SINT16 ) {
|
||||
dataType_ = STK_SINT16;
|
||||
errorString_ << "FileWrite: using 16-bit signed integer data format for file " << name << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
oStream_ << "FileWrite: using 16-bit signed integer data format for file " << fileName << '.';
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
byteswap_ = false;
|
||||
@@ -202,113 +207,160 @@ bool FileWrite :: setRawFile( const char *fileName )
|
||||
byteswap_ = true;
|
||||
#endif
|
||||
|
||||
errorString_ << "FileWrite: creating RAW file: " << name;
|
||||
oStream_ << "FileWrite: creating RAW file: " << fileName;
|
||||
handleError( StkError::STATUS );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileWrite :: setWavFile( const char *fileName )
|
||||
bool FileWrite :: setWavFile( std::string fileName )
|
||||
{
|
||||
char name[8192];
|
||||
strncpy(name, fileName, 8192);
|
||||
if ( strstr(name, ".wav") == NULL) strcat(name, ".wav");
|
||||
fd_ = fopen(name, "wb");
|
||||
std::string name( fileName );
|
||||
if ( fileName.find( ".wav" ) == std::string::npos ) fileName += ".wav";
|
||||
fd_ = fopen( fileName.c_str(), "wb" );
|
||||
if ( !fd_ ) {
|
||||
errorString_ << "FileWrite: could not create WAV file: " << name;
|
||||
oStream_ << "FileWrite: could not create WAV file: " << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct wavhdr hdr = {"RIF", 44, "WAV", "fmt", 16, 1, 1,
|
||||
(SINT32) Stk::sampleRate(), 0, 2, 16, "dat", 0};
|
||||
hdr.riff[3] = 'F';
|
||||
hdr.wave[3] = 'E';
|
||||
hdr.fmt[3] = ' ';
|
||||
hdr.data[3] = 'a';
|
||||
hdr.num_chans = (SINT16) channels_;
|
||||
struct WaveHeader hdr = { {'R','I','F','F'}, 44, {'W','A','V','E'}, {'f','m','t',' '}, 16, 1, 1,
|
||||
(SINT32) Stk::sampleRate(), 0, 2, 16, 0, 0, 0,
|
||||
{'\x01','\x00','\x00','\x00','\x00','\x00','\x10','\x00','\x80','\x00','\x00','\xAA','\x00','\x38','\x9B','\x71'},
|
||||
{'f','a','c','t'}, 4, 0 };
|
||||
hdr.nChannels = (SINT16) channels_;
|
||||
if ( dataType_ == STK_SINT8 )
|
||||
hdr.bits_per_samp = 8;
|
||||
hdr.bitsPerSample = 8;
|
||||
else if ( dataType_ == STK_SINT16 )
|
||||
hdr.bits_per_samp = 16;
|
||||
hdr.bitsPerSample = 16;
|
||||
else if ( dataType_ == STK_SINT24 )
|
||||
hdr.bitsPerSample = 24;
|
||||
else if ( dataType_ == STK_SINT32 )
|
||||
hdr.bits_per_samp = 32;
|
||||
hdr.bitsPerSample = 32;
|
||||
else if ( dataType_ == STK_FLOAT32 ) {
|
||||
hdr.format_tag = 3;
|
||||
hdr.bits_per_samp = 32;
|
||||
hdr.formatCode = 3;
|
||||
hdr.bitsPerSample = 32;
|
||||
}
|
||||
else if ( dataType_ == STK_FLOAT64 ) {
|
||||
hdr.format_tag = 3;
|
||||
hdr.bits_per_samp = 64;
|
||||
hdr.formatCode = 3;
|
||||
hdr.bitsPerSample = 64;
|
||||
}
|
||||
hdr.bytesPerSample = (SINT16) (channels_ * hdr.bitsPerSample / 8);
|
||||
hdr.bytesPerSecond = (SINT32) (hdr.sampleRate * hdr.bytesPerSample);
|
||||
|
||||
unsigned int bytesToWrite = 36;
|
||||
bool useExtensible = false;
|
||||
if ( channels_ > 2 || hdr.bitsPerSample > 16 ) { // use extensible format
|
||||
useExtensible = true;
|
||||
bytesToWrite = 72;
|
||||
hdr.chunkSize += 24;
|
||||
hdr.formatCode = 0xFFFE;
|
||||
hdr.cbSize = 22;
|
||||
hdr.validBits = hdr.bitsPerSample;
|
||||
SINT16 *subFormat = (SINT16 *)&hdr.subformat[0];
|
||||
if ( dataType_ == STK_FLOAT32 || dataType_ == STK_FLOAT64 )
|
||||
*subFormat = 3;
|
||||
else *subFormat = 1;
|
||||
}
|
||||
hdr.bytes_per_samp = (SINT16) (channels_ * hdr.bits_per_samp / 8);
|
||||
hdr.bytes_per_sec = (SINT32) (hdr.sample_rate * hdr.bytes_per_samp);
|
||||
|
||||
byteswap_ = false;
|
||||
#ifndef __LITTLE_ENDIAN__
|
||||
byteswap_ = true;
|
||||
swap32((unsigned char *)&hdr.file_size);
|
||||
swap32((unsigned char *)&hdr.chunk_size);
|
||||
swap16((unsigned char *)&hdr.format_tag);
|
||||
swap16((unsigned char *)&hdr.num_chans);
|
||||
swap32((unsigned char *)&hdr.sample_rate);
|
||||
swap32((unsigned char *)&hdr.bytes_per_sec);
|
||||
swap16((unsigned char *)&hdr.bytes_per_samp);
|
||||
swap16((unsigned char *)&hdr.bits_per_samp);
|
||||
swap32((unsigned char *)&hdr.chunkSize);
|
||||
swap16((unsigned char *)&hdr.formatCode);
|
||||
swap16((unsigned char *)&hdr.nChannels);
|
||||
swap32((unsigned char *)&hdr.sampleRate);
|
||||
swap32((unsigned char *)&hdr.bytesPerSecond);
|
||||
swap16((unsigned char *)&hdr.bytesPerSample);
|
||||
swap16((unsigned char *)&hdr.bitsPerSample);
|
||||
swap16((unsigned char *)&hdr.cbSize);
|
||||
swap16((unsigned char *)&hdr.validBits);
|
||||
swap16((unsigned char *)&hdr.subformat[0]);
|
||||
swap32((unsigned char *)&hdr.factSize);
|
||||
#endif
|
||||
|
||||
if ( fwrite(&hdr, 4, 11, fd_) != 11 ) {
|
||||
errorString_ << "FileWrite: could not write WAV header for file " << name << '.';
|
||||
return false;
|
||||
}
|
||||
char data[4] = {'d','a','t','a'};
|
||||
SINT32 dataSize = 0;
|
||||
if ( fwrite(&hdr, 1, bytesToWrite, fd_) != bytesToWrite ) goto error;
|
||||
if ( fwrite(&data, 4, 1, fd_) != 1 ) goto error;
|
||||
if ( fwrite(&dataSize, 4, 1, fd_) != 1 ) goto error;
|
||||
|
||||
errorString_ << "FileWrite: creating WAV file: " << name;
|
||||
oStream_ << "FileWrite: creating WAV file: " << fileName;
|
||||
handleError( StkError::STATUS );
|
||||
return true;
|
||||
|
||||
error:
|
||||
oStream_ << "FileWrite: could not write WAV header for file: " << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileWrite :: closeWavFile( void )
|
||||
{
|
||||
int bytes_per_sample = 1;
|
||||
int bytesPerSample = 1;
|
||||
if ( dataType_ == STK_SINT16 )
|
||||
bytes_per_sample = 2;
|
||||
bytesPerSample = 2;
|
||||
else if ( dataType_ == STK_SINT24 )
|
||||
bytesPerSample = 3;
|
||||
else if ( dataType_ == STK_SINT32 || dataType_ == STK_FLOAT32 )
|
||||
bytes_per_sample = 4;
|
||||
bytesPerSample = 4;
|
||||
else if ( dataType_ == STK_FLOAT64 )
|
||||
bytes_per_sample = 8;
|
||||
bytesPerSample = 8;
|
||||
|
||||
SINT32 bytes = frameCounter_ * channels_ * bytes_per_sample;
|
||||
bool useExtensible = false;
|
||||
int dataLocation = 40;
|
||||
if ( bytesPerSample > 2 || channels_ > 2 ) {
|
||||
useExtensible = true;
|
||||
dataLocation = 76;
|
||||
}
|
||||
|
||||
SINT32 bytes = frameCounter_ * channels_ * bytesPerSample;
|
||||
if ( bytes % 2 ) { // pad extra byte if odd
|
||||
signed char sample = 0;
|
||||
fwrite( &sample, 1, 1, fd_ );
|
||||
}
|
||||
#ifndef __LITTLE_ENDIAN__
|
||||
swap32((unsigned char *)&bytes);
|
||||
#endif
|
||||
fseek(fd_, 40, SEEK_SET); // jump to data length
|
||||
fwrite(&bytes, 4, 1, fd_);
|
||||
fseek( fd_, dataLocation, SEEK_SET ); // jump to data length
|
||||
fwrite( &bytes, 4, 1, fd_ );
|
||||
|
||||
bytes = frameCounter_ * channels_ * bytes_per_sample + 44;
|
||||
bytes = frameCounter_ * channels_ * bytesPerSample + 44;
|
||||
if ( useExtensible ) bytes += 36;
|
||||
#ifndef __LITTLE_ENDIAN__
|
||||
swap32((unsigned char *)&bytes);
|
||||
#endif
|
||||
fseek(fd_, 4, SEEK_SET); // jump to file size
|
||||
fwrite(&bytes, 4, 1, fd_);
|
||||
fseek( fd_, 4, SEEK_SET ); // jump to file size
|
||||
fwrite( &bytes, 4, 1, fd_ );
|
||||
|
||||
if ( useExtensible ) { // fill in the "fact" chunk frames value
|
||||
bytes = frameCounter_;
|
||||
#ifndef __LITTLE_ENDIAN__
|
||||
swap32((unsigned char *)&bytes);
|
||||
#endif
|
||||
fseek( fd_, 68, SEEK_SET );
|
||||
fwrite( &bytes, 4, 1, fd_ );
|
||||
}
|
||||
|
||||
fclose( fd_ );
|
||||
}
|
||||
|
||||
bool FileWrite :: setSndFile( const char *fileName )
|
||||
bool FileWrite :: setSndFile( std::string fileName )
|
||||
{
|
||||
char name[8192];
|
||||
strncpy(name, fileName, 8192);
|
||||
if ( strstr(name, ".snd") == NULL) strcat(name, ".snd");
|
||||
fd_ = fopen(name, "wb");
|
||||
std::string name( fileName );
|
||||
if ( fileName.find( ".snd" ) == std::string::npos ) fileName += ".snd";
|
||||
fd_ = fopen( fileName.c_str(), "wb" );
|
||||
if ( !fd_ ) {
|
||||
errorString_ << "FileWrite: could not create SND file: " << name;
|
||||
oStream_ << "FileWrite: could not create SND file: " << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sndhdr hdr = {".sn", 40, 0, 3, (SINT32) Stk::sampleRate(), 1, "Created by STK"};
|
||||
struct SndHeader hdr = {".sn", 40, 0, 3, (SINT32) Stk::sampleRate(), 1, "Created by STK"};
|
||||
hdr.pref[3] = 'd';
|
||||
hdr.num_channels = channels_;
|
||||
hdr.nChannels = channels_;
|
||||
if ( dataType_ == STK_SINT8 )
|
||||
hdr.format = 2;
|
||||
else if ( dataType_ == STK_SINT16 )
|
||||
hdr.format = 3;
|
||||
else if ( dataType_ == STK_SINT24 )
|
||||
hdr.format = 4;
|
||||
else if ( dataType_ == STK_SINT32 )
|
||||
hdr.format = 5;
|
||||
else if ( dataType_ == STK_FLOAT32 )
|
||||
@@ -319,35 +371,37 @@ bool FileWrite :: setSndFile( const char *fileName )
|
||||
byteswap_ = false;
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
byteswap_ = true;
|
||||
swap32 ((unsigned char *)&hdr.hdr_length);
|
||||
swap32 ((unsigned char *)&hdr.headerBytes);
|
||||
swap32 ((unsigned char *)&hdr.format);
|
||||
swap32 ((unsigned char *)&hdr.sample_rate);
|
||||
swap32 ((unsigned char *)&hdr.num_channels);
|
||||
swap32 ((unsigned char *)&hdr.sampleRate);
|
||||
swap32 ((unsigned char *)&hdr.nChannels);
|
||||
#endif
|
||||
|
||||
if ( fwrite(&hdr, 4, 10, fd_) != 10 ) {
|
||||
errorString_ << "FileWrite: Could not write SND header for file " << name << '.';
|
||||
oStream_ << "FileWrite: Could not write SND header for file " << fileName << '.';
|
||||
return false;
|
||||
}
|
||||
|
||||
errorString_ << "FileWrite: creating SND file: " << name;
|
||||
oStream_ << "FileWrite: creating SND file: " << fileName;
|
||||
handleError( StkError::STATUS );
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileWrite :: closeSndFile( void )
|
||||
{
|
||||
int bytes_per_sample = 1;
|
||||
int bytesPerSample = 1;
|
||||
if ( dataType_ == STK_SINT16 )
|
||||
bytes_per_sample = 2;
|
||||
bytesPerSample = 2;
|
||||
else if ( dataType_ == STK_SINT24 )
|
||||
bytesPerSample = 3;
|
||||
else if ( dataType_ == STK_SINT32 )
|
||||
bytes_per_sample = 4;
|
||||
bytesPerSample = 4;
|
||||
else if ( dataType_ == STK_FLOAT32 )
|
||||
bytes_per_sample = 4;
|
||||
bytesPerSample = 4;
|
||||
else if ( dataType_ == STK_FLOAT64 )
|
||||
bytes_per_sample = 8;
|
||||
bytesPerSample = 8;
|
||||
|
||||
SINT32 bytes = frameCounter_ * bytes_per_sample * channels_;
|
||||
SINT32 bytes = frameCounter_ * bytesPerSample * channels_;
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
swap32 ((unsigned char *)&bytes);
|
||||
#endif
|
||||
@@ -356,40 +410,37 @@ void FileWrite :: closeSndFile( void )
|
||||
fclose(fd_);
|
||||
}
|
||||
|
||||
bool FileWrite :: setAifFile( const char *fileName )
|
||||
bool FileWrite :: setAifFile( std::string fileName )
|
||||
{
|
||||
char name[8192];
|
||||
strncpy(name, fileName, 8192);
|
||||
if ( strstr(name, ".aif") == NULL) strcat(name, ".aif");
|
||||
fd_ = fopen(name, "wb");
|
||||
std::string name( fileName );
|
||||
if ( fileName.find( ".aif" ) == std::string::npos ) fileName += ".aif";
|
||||
fd_ = fopen( fileName.c_str(), "wb" );
|
||||
if ( !fd_ ) {
|
||||
errorString_ << "FileWrite: could not create AIF file: " << name;
|
||||
oStream_ << "FileWrite: could not create AIF file: " << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Common parts of AIFF/AIFC header.
|
||||
struct aifhdr hdr = {"FOR", 46, "AIF", "COM", 18, 0, 0, 16, "0"};
|
||||
struct aifssnd ssnd = {"SSN", 8, 0, 0};
|
||||
hdr.form[3] = 'M';
|
||||
hdr.aiff[3] = 'F';
|
||||
hdr.comm[3] = 'M';
|
||||
ssnd.ssnd[3] = 'D';
|
||||
hdr.num_chans = channels_;
|
||||
struct AifHeader hdr = {{'F','O','R','M'}, 46, {'A','I','F','F'}, {'C','O','M','M'}, 18, 0, 0, 16, "0"};
|
||||
struct AifSsnd ssnd = {{'S','S','N','D'}, 8, 0, 0};
|
||||
hdr.nChannels = channels_;
|
||||
if ( dataType_ == STK_SINT8 )
|
||||
hdr.sample_size = 8;
|
||||
hdr.sampleSize = 8;
|
||||
else if ( dataType_ == STK_SINT16 )
|
||||
hdr.sample_size = 16;
|
||||
hdr.sampleSize = 16;
|
||||
else if ( dataType_ == STK_SINT24 )
|
||||
hdr.sampleSize = 24;
|
||||
else if ( dataType_ == STK_SINT32 )
|
||||
hdr.sample_size = 32;
|
||||
hdr.sampleSize = 32;
|
||||
else if ( dataType_ == STK_FLOAT32 ) {
|
||||
hdr.aiff[3] = 'C';
|
||||
hdr.sample_size = 32;
|
||||
hdr.comm_size = 24;
|
||||
hdr.sampleSize = 32;
|
||||
hdr.commSize = 24;
|
||||
}
|
||||
else if ( dataType_ == STK_FLOAT64 ) {
|
||||
hdr.aiff[3] = 'C';
|
||||
hdr.sample_size = 64;
|
||||
hdr.comm_size = 24;
|
||||
hdr.sampleSize = 64;
|
||||
hdr.commSize = 24;
|
||||
}
|
||||
|
||||
// For AIFF files, the sample rate is stored in a 10-byte,
|
||||
@@ -398,11 +449,11 @@ bool FileWrite :: setAifFile( const char *fileName )
|
||||
SINT16 i;
|
||||
unsigned long exp;
|
||||
unsigned long rate = (unsigned long) Stk::sampleRate();
|
||||
memset(hdr.srate, 0, 10);
|
||||
memset( hdr.srate, 0, 10 );
|
||||
exp = rate;
|
||||
for (i=0; i<32; i++) {
|
||||
for ( i=0; i<32; i++ ) {
|
||||
exp >>= 1;
|
||||
if (!exp) break;
|
||||
if ( !exp ) break;
|
||||
}
|
||||
i += 16383;
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
@@ -410,8 +461,8 @@ bool FileWrite :: setAifFile( const char *fileName )
|
||||
#endif
|
||||
*(SINT16 *)(hdr.srate) = (SINT16) i;
|
||||
|
||||
for (i=32; i; i--) {
|
||||
if (rate & 0x80000000) break;
|
||||
for ( i=32; i; i-- ) {
|
||||
if ( rate & 0x80000000 ) break;
|
||||
rate <<= 1;
|
||||
}
|
||||
|
||||
@@ -423,20 +474,20 @@ bool FileWrite :: setAifFile( const char *fileName )
|
||||
byteswap_ = false;
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
byteswap_ = true;
|
||||
swap32((unsigned char *)&hdr.form_size);
|
||||
swap32((unsigned char *)&hdr.comm_size);
|
||||
swap16((unsigned char *)&hdr.num_chans);
|
||||
swap16((unsigned char *)&hdr.sample_size);
|
||||
swap32((unsigned char *)&ssnd.ssnd_size);
|
||||
swap32((unsigned char *)&hdr.formSize);
|
||||
swap32((unsigned char *)&hdr.commSize);
|
||||
swap16((unsigned char *)&hdr.nChannels);
|
||||
swap16((unsigned char *)&hdr.sampleSize);
|
||||
swap32((unsigned char *)&ssnd.ssndSize);
|
||||
swap32((unsigned char *)&ssnd.offset);
|
||||
swap32((unsigned char *)&ssnd.block_size);
|
||||
swap32((unsigned char *)&ssnd.blockSize);
|
||||
#endif
|
||||
|
||||
// The structure boundaries don't allow a single write of 54 bytes.
|
||||
if ( fwrite(&hdr, 4, 5, fd_) != 5 ) goto error;
|
||||
if ( fwrite(&hdr.num_chans, 2, 1, fd_) != 1 ) goto error;
|
||||
if ( fwrite(&hdr.sample_frames, 4, 1, fd_) != 1 ) goto error;
|
||||
if ( fwrite(&hdr.sample_size, 2, 1, fd_) != 1 ) goto error;
|
||||
if ( fwrite(&hdr.nChannels, 2, 1, fd_) != 1 ) goto error;
|
||||
if ( fwrite(&hdr.sampleFrames, 4, 1, fd_) != 1 ) goto error;
|
||||
if ( fwrite(&hdr.sampleSize, 2, 1, fd_) != 1 ) goto error;
|
||||
if ( fwrite(&hdr.srate, 10, 1, fd_) != 1 ) goto error;
|
||||
|
||||
if ( dataType_ == STK_FLOAT32 ) {
|
||||
@@ -454,12 +505,12 @@ bool FileWrite :: setAifFile( const char *fileName )
|
||||
|
||||
if ( fwrite(&ssnd, 4, 4, fd_) != 4 ) goto error;
|
||||
|
||||
errorString_ << "FileWrite: creating AIF file: " << name;
|
||||
oStream_ << "FileWrite: creating AIF file: " << fileName;
|
||||
handleError( StkError::STATUS );
|
||||
return true;
|
||||
|
||||
error:
|
||||
errorString_ << "FileWrite: could not write AIF header for file: " << name;
|
||||
oStream_ << "FileWrite: could not write AIF header for file: " << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -469,18 +520,20 @@ void FileWrite :: closeAifFile( void )
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
swap32((unsigned char *)&frames);
|
||||
#endif
|
||||
fseek(fd_, 22, SEEK_SET); // jump to "COMM" sample_frames
|
||||
fseek(fd_, 22, SEEK_SET); // jump to "COMM" sampleFrames
|
||||
fwrite(&frames, 4, 1, fd_);
|
||||
|
||||
int bytes_per_sample = 1;
|
||||
int bytesPerSample = 1;
|
||||
if ( dataType_ == STK_SINT16 )
|
||||
bytes_per_sample = 2;
|
||||
bytesPerSample = 2;
|
||||
if ( dataType_ == STK_SINT24 )
|
||||
bytesPerSample = 3;
|
||||
else if ( dataType_ == STK_SINT32 || dataType_ == STK_FLOAT32 )
|
||||
bytes_per_sample = 4;
|
||||
bytesPerSample = 4;
|
||||
else if ( dataType_ == STK_FLOAT64 )
|
||||
bytes_per_sample = 8;
|
||||
bytesPerSample = 8;
|
||||
|
||||
unsigned long bytes = frameCounter_ * bytes_per_sample * channels_ + 46;
|
||||
unsigned long bytes = frameCounter_ * bytesPerSample * channels_ + 46;
|
||||
if ( dataType_ == STK_FLOAT32 || dataType_ == STK_FLOAT64 ) bytes += 6;
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
swap32((unsigned char *)&bytes);
|
||||
@@ -488,7 +541,7 @@ void FileWrite :: closeAifFile( void )
|
||||
fseek(fd_, 4, SEEK_SET); // jump to file size
|
||||
fwrite(&bytes, 4, 1, fd_);
|
||||
|
||||
bytes = frameCounter_ * bytes_per_sample * channels_ + 8;
|
||||
bytes = frameCounter_ * bytesPerSample * channels_ + 8;
|
||||
if ( dataType_ == STK_FLOAT32 || dataType_ == STK_FLOAT64 ) bytes += 6;
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
swap32((unsigned char *)&bytes);
|
||||
@@ -502,28 +555,24 @@ void FileWrite :: closeAifFile( void )
|
||||
fclose( fd_ );
|
||||
}
|
||||
|
||||
bool FileWrite :: setMatFile( const char *fileName )
|
||||
bool FileWrite :: setMatFile( std::string fileName )
|
||||
{
|
||||
char name[8192];
|
||||
strncpy(name, fileName, 8192);
|
||||
if ( strstr(name, ".mat") == NULL) strcat(name, ".mat");
|
||||
fd_ = fopen(name, "w+b");
|
||||
if ( fileName.find( ".mat" ) == std::string::npos ) fileName += ".mat";
|
||||
fd_ = fopen( fileName.c_str(), "w+b" );
|
||||
if ( !fd_ ) {
|
||||
errorString_ << "FileWrite: could not create MAT file: " << name;
|
||||
oStream_ << "FileWrite: could not create MAT file: " << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( dataType_ != STK_FLOAT64 ) {
|
||||
dataType_ = STK_FLOAT64;
|
||||
errorString_ << "FileWrite: using 64-bit floating-point data format for file " << name << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
oStream_ << "FileWrite: using 64-bit floating-point data format for file " << fileName << '.';
|
||||
handleError( StkError::DEBUG_PRINT );
|
||||
}
|
||||
|
||||
struct mathdr hdr;
|
||||
strcpy(hdr.heading,"MATLAB 5.0 MAT-file, Generated using the Synthesis ToolKit in C++ (STK). By Perry R. Cook and Gary P. Scavone.");
|
||||
|
||||
int i;
|
||||
for (i=strlen(hdr.heading);i<124;i++) hdr.heading[i] = ' ';
|
||||
struct MatHeader hdr;
|
||||
strcpy( hdr.heading,"MATLAB 5.0 MAT-file, Generated using the Synthesis ToolKit in C++ (STK). By Perry R. Cook and Gary P. Scavone." );
|
||||
for ( int i=strlen(hdr.heading); i<124; i++ ) hdr.heading[i] = ' ';
|
||||
|
||||
// Header Flag Fields
|
||||
hdr.hff[0] = (SINT16) 0x0100; // Version field
|
||||
@@ -531,9 +580,34 @@ bool FileWrite :: setMatFile( const char *fileName )
|
||||
hdr.hff[1] <<= 8;
|
||||
hdr.hff[1] += 'I';
|
||||
|
||||
// Write sample rate in array data element
|
||||
hdr.fs[0] = (SINT32) 14; // Matlab array data type value
|
||||
hdr.fs[1] = (SINT32) 56; // Size of data element to follow (in bytes)
|
||||
|
||||
// Numeric Array Subelements (4):
|
||||
// 1. Array Flags
|
||||
hdr.fs[2] = (SINT32) 6; // Matlab 32-bit unsigned integer data type value
|
||||
hdr.fs[3] = (SINT32) 8; // 8 bytes of data to follow
|
||||
hdr.fs[4] = (SINT32) 6; // Double-precision array, no array flags set
|
||||
hdr.fs[5] = (SINT32) 0; // 4 bytes undefined
|
||||
// 2. Array Dimensions
|
||||
hdr.fs[6] = (SINT32) 5; // Matlab 32-bit signed integer data type value
|
||||
hdr.fs[7] = (SINT32) 8; // 8 bytes of data to follow (2D array)
|
||||
hdr.fs[8] = (SINT32) 1; // 1 row
|
||||
hdr.fs[9] = (SINT32) 1; // 1 column
|
||||
// 3. Array Name (small data format element)
|
||||
hdr.fs[10] = 0x00020001;
|
||||
hdr.fs[11] = 's' << 8;
|
||||
hdr.fs[11] += 'f';
|
||||
// 4. Real Part
|
||||
hdr.fs[12] = 9; // Matlab IEEE 754 double data type
|
||||
hdr.fs[13] = 8; // 8 bytes of data to follow
|
||||
FLOAT64 *sampleRate = (FLOAT64 *)&hdr.fs[14];
|
||||
*sampleRate = (FLOAT64) Stk::sampleRate();
|
||||
|
||||
// Write audio samples in array data element
|
||||
hdr.adf[0] = (SINT32) 14; // Matlab array data type value
|
||||
hdr.adf[1] = (SINT32) 0; // Size of file after this point to end (in bytes)
|
||||
// Don't know size yet.
|
||||
|
||||
// Numeric Array Subelements (4):
|
||||
// 1. Array Flags
|
||||
@@ -547,82 +621,83 @@ bool FileWrite :: setMatFile( const char *fileName )
|
||||
hdr.adf[8] = (SINT32) channels_; // This is the number of rows
|
||||
hdr.adf[9] = (SINT32) 0; // This is the number of columns
|
||||
|
||||
// 3. Array Name
|
||||
// We'll use fileName for the matlab array name (as well as the file name).
|
||||
// If fileName is 4 characters or less, we have to use a compressed data element
|
||||
// format for the array name data element. Otherwise, the array name must
|
||||
// be formatted in 8-byte increments (up to 31 characters + NULL).
|
||||
SINT32 namelength = (SINT32) strlen(fileName);
|
||||
if (strstr(fileName, ".mat")) namelength -= 4;
|
||||
if (namelength > 31) namelength = 31; // Truncate name to 31 characters.
|
||||
char arrayName[64];
|
||||
strncpy(arrayName, fileName, namelength);
|
||||
arrayName[namelength] = '\0';
|
||||
if (namelength > 4) {
|
||||
// 3. Array Name We'll use fileName for the matlab array name (as
|
||||
// well as the file name), though we might need to strip off a
|
||||
// leading directory path. If fileName is 4 characters or less, we
|
||||
// have to use a small data format element for the array name data
|
||||
// element. Otherwise, the array name must be formatted in 8-byte
|
||||
// increments (up to 31 characters + NULL).
|
||||
std::string name = fileName;
|
||||
size_t found;
|
||||
found = name.find_last_of("/\\");
|
||||
name = name.substr(found+1);
|
||||
SINT32 namelength = (SINT32) name.size() - 4; // strip off the ".mat" extension
|
||||
if ( namelength > 31 ) namelength = 31; // Truncate name to 31 characters.
|
||||
if ( namelength > 4 ) {
|
||||
hdr.adf[10] = (SINT32) 1; // Matlab 8-bit signed integer data type value
|
||||
}
|
||||
else { // Compressed data element format
|
||||
hdr.adf[10] = namelength;
|
||||
hdr.adf[10] <<= 16;
|
||||
hdr.adf[10] += 1;
|
||||
hdr.adf[10] = (namelength << 16) + 1;
|
||||
}
|
||||
SINT32 headsize = 40; // Number of bytes in data element so far.
|
||||
|
||||
SINT32 headsize = 40; // Number of bytes in audio data element so far.
|
||||
|
||||
// Write the fixed portion of the header
|
||||
if ( fwrite(&hdr, 172, 1, fd_) != 1 ) goto error;
|
||||
if ( fwrite(&hdr, 236, 1, fd_) != 1 ) goto error;
|
||||
|
||||
// Write MATLAB array name
|
||||
SINT32 tmp;
|
||||
if (namelength > 4) {
|
||||
if ( namelength > 4 ) {
|
||||
if ( fwrite(&namelength, 4, 1, fd_) != 1) goto error;
|
||||
if ( fwrite(arrayName, namelength, 1, fd_) != 1 ) goto error;
|
||||
if ( fwrite(name.c_str(), namelength, 1, fd_) != 1 ) goto error;
|
||||
tmp = (SINT32) ceil((float)namelength / 8);
|
||||
if ( fseek(fd_, tmp*8-namelength, SEEK_CUR) == -1 ) goto error;
|
||||
headsize += tmp * 8;
|
||||
}
|
||||
else { // Compressed data element format
|
||||
if ( fwrite(arrayName, namelength, 1, fd_) != 1 ) goto error;
|
||||
if ( fwrite(name.c_str(), namelength, 1, fd_) != 1 ) goto error;
|
||||
tmp = 4 - namelength;
|
||||
if ( fseek(fd_, tmp, SEEK_CUR) == -1 ) goto error;
|
||||
}
|
||||
|
||||
// Finish writing known header information
|
||||
//4. Real Part
|
||||
tmp = 9; // Matlab IEEE 754 double data type
|
||||
if ( fwrite(&tmp, 4, 1, fd_) != 1 ) goto error;
|
||||
tmp = 0; // Size of real part subelement in bytes (8 per sample)
|
||||
if ( fwrite(&tmp, 4, 1, fd_) != 1 ) goto error;
|
||||
headsize += 8; // Total number of bytes in data element so far
|
||||
|
||||
if ( fseek(fd_, 132, SEEK_SET) == -1 ) goto error;
|
||||
if ( fseek(fd_, 196, SEEK_SET) == -1 ) goto error;
|
||||
if ( fwrite(&headsize, 4, 1, fd_) != 1 ) goto error; // Write header size ... will update at end
|
||||
if ( fseek(fd_, 0, SEEK_END) == -1 ) goto error;
|
||||
|
||||
byteswap_ = false;
|
||||
errorString_ << "FileWrite: creating MAT-file (" << name << ") containing MATLAB array: " << arrayName;
|
||||
oStream_ << "FileWrite: creating MAT-file: " << fileName;
|
||||
handleError( StkError::STATUS );
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
errorString_ << "FileWrite: could not write MAT-file header for file " << name << '.';
|
||||
oStream_ << "FileWrite: could not write MAT-file header for file " << fileName << '.';
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileWrite :: closeMatFile( void )
|
||||
{
|
||||
fseek(fd_, 164, SEEK_SET); // jump to number of columns
|
||||
fseek(fd_, 228, SEEK_SET); // jump to number of columns
|
||||
fwrite(&frameCounter_, 4, 1, fd_);
|
||||
|
||||
SINT32 headsize, temp;
|
||||
fseek(fd_, 132, SEEK_SET); // jump to header size
|
||||
fseek(fd_, 196, SEEK_SET); // jump to header size
|
||||
fread(&headsize, 4, 1, fd_);
|
||||
temp = headsize;
|
||||
headsize += (SINT32) (frameCounter_ * 8 * channels_);
|
||||
fseek(fd_, 132, SEEK_SET);
|
||||
fseek(fd_, 196, SEEK_SET);
|
||||
// Write file size (minus some header info)
|
||||
fwrite(&headsize, 4, 1, fd_);
|
||||
|
||||
fseek(fd_, temp+132, SEEK_SET); // jumpt to data size (in bytes)
|
||||
fseek(fd_, temp+196, SEEK_SET); // jumpt to data size (in bytes)
|
||||
temp = frameCounter_ * 8 * channels_;
|
||||
fwrite(&temp, 4, 1, fd_);
|
||||
|
||||
@@ -632,13 +707,13 @@ void FileWrite :: closeMatFile( void )
|
||||
void FileWrite :: write( StkFrames& buffer )
|
||||
{
|
||||
if ( fd_ == 0 ) {
|
||||
errorString_ << "FileWrite::write(): a file has not yet been opened!";
|
||||
oStream_ << "FileWrite::write(): a file has not yet been opened!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( buffer.channels() != channels_ ) {
|
||||
errorString_ << "FileWrite::write(): number of channels in the StkFrames argument does not match that specified to open() function!";
|
||||
oStream_ << "FileWrite::write(): number of channels in the StkFrames argument does not match that specified to open() function!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
return;
|
||||
}
|
||||
@@ -695,12 +770,25 @@ void FileWrite :: write( StkFrames& buffer )
|
||||
if ( fwrite(&sample, 8, 1, fd_) != 1 ) goto error;
|
||||
}
|
||||
}
|
||||
else if ( dataType_ == STK_SINT24 ) {
|
||||
SINT32 sample;
|
||||
for ( unsigned long k=0; k<nSamples; k++ ) {
|
||||
sample = (SINT32) (buffer[k] * 8388607.0);
|
||||
if ( byteswap_ ) {
|
||||
swap32( (unsigned char *)&sample );
|
||||
unsigned char *ptr = (unsigned char *) &sample;
|
||||
if ( fwrite(ptr+1, 3, 1, fd_) != 1 ) goto error;
|
||||
}
|
||||
else
|
||||
if ( fwrite(&sample, 3, 1, fd_) != 1 ) goto error;
|
||||
}
|
||||
}
|
||||
|
||||
frameCounter_ += buffer.frames();
|
||||
return;
|
||||
|
||||
error:
|
||||
errorString_ << "FileWrite::write(): error writing data to file!";
|
||||
oStream_ << "FileWrite::write(): error writing data to file!";
|
||||
handleError( StkError::FILE_ERROR );
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
namespace stk {
|
||||
|
||||
FileWvIn :: FileWvIn( unsigned long chunkThreshold, unsigned long chunkSize )
|
||||
: finished_(true), interpolate_(false), time_(0.0),
|
||||
: finished_(true), interpolate_(false), time_(0.0), rate_(0.0),
|
||||
chunkThreshold_(chunkThreshold), chunkSize_(chunkSize)
|
||||
{
|
||||
Stk::addSampleRateAlert( this );
|
||||
@@ -45,7 +45,7 @@ FileWvIn :: FileWvIn( unsigned long chunkThreshold, unsigned long chunkSize )
|
||||
|
||||
FileWvIn :: FileWvIn( std::string fileName, bool raw, bool doNormalize,
|
||||
unsigned long chunkThreshold, unsigned long chunkSize )
|
||||
: finished_(true), interpolate_(false), time_(0.0),
|
||||
: finished_(true), interpolate_(false), time_(0.0), rate_(0.0),
|
||||
chunkThreshold_(chunkThreshold), chunkSize_(chunkSize)
|
||||
{
|
||||
openFile( fileName, raw, doNormalize );
|
||||
@@ -142,11 +142,6 @@ void FileWvIn :: normalize( StkFloat peak )
|
||||
|
||||
void FileWvIn :: setRate( StkFloat rate )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "FileWvIn::setRate: changing file read rate from " << rate_ << " to " << rate << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
|
||||
rate_ = rate;
|
||||
|
||||
// If negative rate and at beginning of sound, move pointer to end
|
||||
@@ -174,7 +169,7 @@ StkFloat FileWvIn :: tick( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= data_.channels() ) {
|
||||
errorString_ << "FileWvIn::tick(): channel argument and soundfile data are incompatible!";
|
||||
oStream_ << "FileWvIn::tick(): channel argument and soundfile data are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
@@ -231,8 +226,8 @@ StkFrames& FileWvIn :: tick( StkFrames& frames )
|
||||
{
|
||||
if ( !file_.isOpen() ) {
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "FileWvIn::tick(): no file data is loaded!";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
oStream_ << "FileWvIn::tick(): no file data is loaded!";
|
||||
handleError( StkError::DEBUG_PRINT );
|
||||
#endif
|
||||
return frames;
|
||||
}
|
||||
@@ -240,7 +235,7 @@ StkFrames& FileWvIn :: tick( StkFrames& frames )
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( nChannels != frames.channels() ) {
|
||||
errorString_ << "FileWvIn::tick(): StkFrames argument is incompatible with file data!";
|
||||
oStream_ << "FileWvIn::tick(): StkFrames argument is incompatible with file data!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -64,7 +64,7 @@ void FileWvOut :: openFile( std::string fileName,
|
||||
closeFile();
|
||||
|
||||
if ( nChannels < 1 ) {
|
||||
errorString_ << "FileWvOut::openFile: the channels argument must be greater than zero!";
|
||||
oStream_ << "FileWvOut::openFile: the channels argument must be greater than zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ void FileWvOut :: tick( const StkFloat sample )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( !file_.isOpen() ) {
|
||||
errorString_ << "FileWvOut::tick(): no file open!";
|
||||
oStream_ << "FileWvOut::tick(): no file open!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
}
|
||||
@@ -113,13 +113,13 @@ void FileWvOut :: tick( const StkFrames& frames )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( !file_.isOpen() ) {
|
||||
errorString_ << "FileWvOut::tick(): no file open!";
|
||||
oStream_ << "FileWvOut::tick(): no file open!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( data_.channels() != frames.channels() ) {
|
||||
errorString_ << "FileWvOut::tick(): incompatible channel value in StkFrames argument!";
|
||||
oStream_ << "FileWvOut::tick(): incompatible channel value in StkFrames argument!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "Fir.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace stk {
|
||||
|
||||
@@ -36,7 +37,7 @@ Fir :: Fir( std::vector<StkFloat> &coefficients )
|
||||
{
|
||||
// Check the arguments.
|
||||
if ( coefficients.size() == 0 ) {
|
||||
errorString_ << "Fir: coefficient vector must have size > 0!";
|
||||
oStream_ << "Fir: coefficient vector must have size > 0!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -55,7 +56,7 @@ void Fir :: setCoefficients( std::vector<StkFloat> &coefficients, bool clearStat
|
||||
{
|
||||
// Check the argument.
|
||||
if ( coefficients.size() == 0 ) {
|
||||
errorString_ << "Fir::setCoefficients: coefficient vector must have size > 0!";
|
||||
oStream_ << "Fir::setCoefficients: coefficient vector must have size > 0!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
|
||||
145
src/Flute.cpp
145
src/Flute.cpp
@@ -1,5 +1,5 @@
|
||||
/***************************************************/
|
||||
/*! \class Flute
|
||||
/*! \Class Flute
|
||||
\brief STK flute physical model class.
|
||||
|
||||
This class implements a simple flute
|
||||
@@ -18,7 +18,7 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -29,23 +29,22 @@ namespace stk {
|
||||
|
||||
Flute :: Flute( StkFloat lowestFrequency )
|
||||
{
|
||||
length_ = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
|
||||
boreDelay_.setMaximumDelay( length_ );
|
||||
boreDelay_.setDelay( 100.0 );
|
||||
if ( lowestFrequency <= 0.0 ) {
|
||||
oStream_ << "Flute::Flute: argument is less than or equal to zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
jetDelay_.setMaximumDelay( length_ );
|
||||
unsigned long nDelays = (unsigned long) ( Stk::sampleRate() / lowestFrequency );
|
||||
boreDelay_.setMaximumDelay( nDelays + 1 );
|
||||
|
||||
jetDelay_.setMaximumDelay( nDelays + 1 );
|
||||
jetDelay_.setDelay( 49.0 );
|
||||
|
||||
vibrato_.setFrequency( 5.925 );
|
||||
|
||||
this->clear();
|
||||
|
||||
filter_.setPole( 0.7 - ((StkFloat) 0.1 * 22050.0 / Stk::sampleRate() ) );
|
||||
filter_.setGain( -1.0 );
|
||||
|
||||
filter_.setPole( 0.7 - ( 0.1 * 22050.0 / Stk::sampleRate() ) );
|
||||
dcBlock_.setBlockZero();
|
||||
|
||||
adsr_.setAllTimes( 0.005, 0.01, 0.8, 0.010);
|
||||
adsr_.setAllTimes( 0.005, 0.01, 0.8, 0.010 );
|
||||
endReflection_ = 0.5;
|
||||
jetReflection_ = 0.5;
|
||||
noiseGain_ = 0.15; // Breath pressure random component.
|
||||
@@ -53,7 +52,8 @@ Flute :: Flute( StkFloat lowestFrequency )
|
||||
jetRatio_ = 0.32;
|
||||
|
||||
maxPressure_ = 0.0;
|
||||
lastFrequency_ = 220.0;
|
||||
this->clear();
|
||||
this->setFrequency( 220.0 );
|
||||
}
|
||||
|
||||
Flute :: ~Flute( void )
|
||||
@@ -70,27 +70,39 @@ void Flute :: clear( void )
|
||||
|
||||
void Flute :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
lastFrequency_ = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "Flute::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
lastFrequency_ = 220.0;
|
||||
oStream_ << "Flute::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// We're overblowing here.
|
||||
lastFrequency_ *= 0.66666;
|
||||
lastFrequency_ = frequency * 0.66666;
|
||||
|
||||
// delay = length - approximate filter delay.
|
||||
StkFloat delay = Stk::sampleRate() / lastFrequency_ - (StkFloat) 2.0;
|
||||
if ( delay <= 0.0 ) delay = 0.3;
|
||||
else if ( delay > length_ ) delay = length_;
|
||||
// Account for filter delay and one sample "lastOut" delay
|
||||
// (previously approximated as 2.0 samples). The tuning is still
|
||||
// not perfect but I'm not sure why. Also, we are not accounting
|
||||
// for the dc blocking filter delay.
|
||||
StkFloat delay = Stk::sampleRate() / lastFrequency_ - filter_.phaseDelay( lastFrequency_ ) - 1.0;
|
||||
|
||||
boreDelay_.setDelay(delay);
|
||||
jetDelay_.setDelay(delay * jetRatio_);
|
||||
boreDelay_.setDelay( delay );
|
||||
jetDelay_.setDelay( delay * jetRatio_ );
|
||||
}
|
||||
|
||||
void Flute :: setJetDelay( StkFloat aRatio )
|
||||
{
|
||||
jetRatio_ = aRatio;
|
||||
jetDelay_.setDelay( boreDelay_.getDelay() * aRatio ); // Scaled by ratio.
|
||||
}
|
||||
|
||||
void Flute :: startBlowing( StkFloat amplitude, StkFloat rate )
|
||||
{
|
||||
if ( amplitude <= 0.0 || rate <= 0.0 ) {
|
||||
oStream_ << "Flute::startBlowing: one or more arguments is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
adsr_.setAttackRate( rate );
|
||||
maxPressure_ = amplitude / (StkFloat) 0.8;
|
||||
adsr_.keyOn();
|
||||
@@ -98,6 +110,11 @@ void Flute :: startBlowing( StkFloat amplitude, StkFloat rate )
|
||||
|
||||
void Flute :: stopBlowing( StkFloat rate )
|
||||
{
|
||||
if ( rate <= 0.0 ) {
|
||||
oStream_ << "Flute::stopBlowing: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
adsr_.setReleaseRate( rate );
|
||||
adsr_.keyOff();
|
||||
}
|
||||
@@ -107,73 +124,39 @@ void Flute :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
this->setFrequency( frequency );
|
||||
this->startBlowing( 1.1 + (amplitude * 0.20), amplitude * 0.02 );
|
||||
outputGain_ = amplitude + 0.001;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Flute::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Flute :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
this->stopBlowing( amplitude * 0.02 );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Flute::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Flute :: setJetReflection( StkFloat coefficient )
|
||||
{
|
||||
jetReflection_ = coefficient;
|
||||
}
|
||||
|
||||
void Flute :: setEndReflection( StkFloat coefficient )
|
||||
{
|
||||
endReflection_ = coefficient;
|
||||
}
|
||||
|
||||
void Flute :: setJetDelay( StkFloat aRatio )
|
||||
{
|
||||
// Delay = length - approximate filter delay.
|
||||
StkFloat temp = Stk::sampleRate() / lastFrequency_ - (StkFloat) 2.0;
|
||||
jetRatio_ = aRatio;
|
||||
jetDelay_.setDelay(temp * aRatio); // Scaled by ratio.
|
||||
}
|
||||
|
||||
void Flute :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "Flute::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "Flute::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
if (number == __SK_JetDelay_) // 2
|
||||
this->setJetDelay( (StkFloat) (0.08 + (0.48 * norm)) );
|
||||
else if (number == __SK_NoiseLevel_) // 4
|
||||
noiseGain_ = ( norm * 0.4);
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
vibrato_.setFrequency( norm * 12.0);
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
vibratoGain_ = ( norm * 0.4 );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
adsr_.setTarget( norm );
|
||||
else {
|
||||
errorString_ << "Flute::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Flute::controlChange: number = " << number << ", value = " << value << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Flute::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_JetDelay_) // 2
|
||||
this->setJetDelay( (StkFloat) (0.08 + (0.48 * normalizedValue)) );
|
||||
else if (number == __SK_NoiseLevel_) // 4
|
||||
noiseGain_ = ( normalizedValue * 0.4);
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
vibrato_.setFrequency( normalizedValue * 12.0);
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
vibratoGain_ = ( normalizedValue * 0.4 );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
adsr_.setTarget( normalizedValue );
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
oStream_ << "Flute::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -46,13 +46,24 @@ FormSwep :: ~FormSwep()
|
||||
void FormSwep :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
|
||||
{
|
||||
if ( !ignoreSampleRateChange_ ) {
|
||||
errorString_ << "FormSwep::sampleRateChanged: you may need to recompute filter coefficients!";
|
||||
oStream_ << "FormSwep::sampleRateChanged: you may need to recompute filter coefficients!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
}
|
||||
|
||||
void FormSwep :: setResonance( StkFloat frequency, StkFloat radius )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
|
||||
oStream_ << "FormSwep::setResonance: frequency argument (" << frequency << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
if ( radius < 0.0 || radius >= 1.0 ) {
|
||||
oStream_ << "FormSwep::setResonance: radius argument (" << radius << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
radius_ = radius;
|
||||
frequency_ = frequency;
|
||||
|
||||
@@ -80,6 +91,15 @@ void FormSwep :: setStates( StkFloat frequency, StkFloat radius, StkFloat gain )
|
||||
|
||||
void FormSwep :: setTargets( StkFloat frequency, StkFloat radius, StkFloat gain )
|
||||
{
|
||||
if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
|
||||
oStream_ << "FormSwep::setTargets: frequency argument (" << frequency << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
if ( radius < 0.0 || radius >= 1.0 ) {
|
||||
oStream_ << "FormSwep::setTargets: radius argument (" << radius << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
dirty_ = true;
|
||||
startFrequency_ = frequency_;
|
||||
startRadius_ = radius_;
|
||||
@@ -95,16 +115,22 @@ void FormSwep :: setTargets( StkFloat frequency, StkFloat radius, StkFloat gain
|
||||
|
||||
void FormSwep :: setSweepRate( StkFloat rate )
|
||||
{
|
||||
if ( rate < 0.0 || rate > 1.0 ) {
|
||||
oStream_ << "FormSwep::setSweepRate: argument (" << rate << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
sweepRate_ = rate;
|
||||
if ( sweepRate_ > 1.0 ) sweepRate_ = 1.0;
|
||||
if ( sweepRate_ < 0.0 ) sweepRate_ = 0.0;
|
||||
}
|
||||
|
||||
void FormSwep :: setSweepTime( StkFloat time )
|
||||
{
|
||||
sweepRate_ = 1.0 / ( time * Stk::sampleRate() );
|
||||
if ( sweepRate_ > 1.0 ) sweepRate_ = 1.0;
|
||||
if ( sweepRate_ < 0.0 ) sweepRate_ = 0.0;
|
||||
if ( time <= 0.0 ) {
|
||||
oStream_ << "FormSwep::setSweepTime: argument (" << time << ") must be > 0.0!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
this->setSweepRate( 1.0 / ( time * Stk::sampleRate() ) );
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -60,14 +60,14 @@ void Granulate :: setGrainParameters( unsigned int duration, unsigned int rampPe
|
||||
gDuration_ = duration;
|
||||
if ( gDuration_ == 0 ) {
|
||||
gDuration_ = 1;
|
||||
errorString_ << "Granulate::setGrainParameters: duration argument cannot be zero ... setting to 1 millisecond.";
|
||||
oStream_ << "Granulate::setGrainParameters: duration argument cannot be zero ... setting to 1 millisecond.";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
gRampPercent_ = rampPercent;
|
||||
if ( gRampPercent_ > 100 ) {
|
||||
gRampPercent_ = 100;
|
||||
errorString_ << "Granulate::setGrainParameters: rampPercent argument cannot be greater than 100 ... setting to 100.";
|
||||
oStream_ << "Granulate::setGrainParameters: rampPercent argument cannot be greater than 100 ... setting to 100.";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
@@ -94,8 +94,9 @@ void Granulate :: openFile( std::string fileName, bool typeRaw )
|
||||
this->reset();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Granulate::openFile: file = " << fileName << ", file frames = " << file.fileSize() << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
std::ostringstream message;
|
||||
message << "Granulate::openFile: file = " << fileName << ", file frames = " << file.fileSize() << '.';
|
||||
handleError( message.str(), StkError::DEBUG_PRINT );
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -120,8 +121,9 @@ void Granulate :: reset( void )
|
||||
void Granulate :: setVoices( unsigned int nVoices )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Granulate::setVoices: nVoices = " << nVoices << ", existing voices = " << grains_.size() << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
std::ostringstream message;
|
||||
message << "Granulate::setVoices: nVoices = " << nVoices << ", existing voices = " << grains_.size() << '.';
|
||||
handleError( message.str(), StkError::DEBUG_PRINT );
|
||||
#endif
|
||||
|
||||
unsigned int oldSize = grains_.size();
|
||||
@@ -203,7 +205,7 @@ StkFloat Granulate :: tick( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= data_.channels() ) {
|
||||
errorString_ << "Granulate::tick(): channel argument and soundfile data are incompatible!";
|
||||
oStream_ << "Granulate::tick(): channel argument and soundfile data are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -70,11 +70,6 @@ void HevyMetl :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
gains_[3] = amplitude * fmGains_[68];
|
||||
this->setFrequency( frequency );
|
||||
this->keyOn();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "HevyMetl::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
12
src/Iir.cpp
12
src/Iir.cpp
@@ -20,7 +20,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -42,12 +42,12 @@ Iir :: Iir( std::vector<StkFloat> &bCoefficients, std::vector<StkFloat> &aCoeffi
|
||||
{
|
||||
// Check the arguments.
|
||||
if ( bCoefficients.size() == 0 || aCoefficients.size() == 0 ) {
|
||||
errorString_ << "Iir: a and b coefficient vectors must both have size > 0!";
|
||||
oStream_ << "Iir: a and b coefficient vectors must both have size > 0!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
if ( aCoefficients[0] == 0.0 ) {
|
||||
errorString_ << "Iir: a[0] coefficient cannot == 0!";
|
||||
oStream_ << "Iir: a[0] coefficient cannot == 0!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ void Iir :: setNumerator( std::vector<StkFloat> &bCoefficients, bool clearState
|
||||
{
|
||||
// Check the argument.
|
||||
if ( bCoefficients.size() == 0 ) {
|
||||
errorString_ << "Iir::setNumerator: coefficient vector must have size > 0!";
|
||||
oStream_ << "Iir::setNumerator: coefficient vector must have size > 0!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -95,12 +95,12 @@ void Iir :: setDenominator( std::vector<StkFloat> &aCoefficients, bool clearStat
|
||||
{
|
||||
// Check the argument.
|
||||
if ( aCoefficients.size() == 0 ) {
|
||||
errorString_ << "Iir::setDenominator: coefficient vector must have size > 0!";
|
||||
oStream_ << "Iir::setDenominator: coefficient vector must have size > 0!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
if ( aCoefficients[0] == 0.0 ) {
|
||||
errorString_ << "Iir::setDenominator: a[0] coefficient cannot == 0!";
|
||||
oStream_ << "Iir::setDenominator: a[0] coefficient cannot == 0!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "InetWvIn.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace stk {
|
||||
|
||||
@@ -47,7 +48,7 @@ InetWvIn :: InetWvIn( unsigned long bufferFrames, unsigned int nBuffers )
|
||||
|
||||
// Start the input thread.
|
||||
if ( !thread_.start( &inputThread, &threadInfo_ ) ) {
|
||||
errorString_ << "InetWvIn(): unable to start input thread in constructor!";
|
||||
oStream_ << "InetWvIn(): unable to start input thread in constructor!";
|
||||
handleError( StkError::PROCESS_THREAD );
|
||||
}
|
||||
}
|
||||
@@ -70,7 +71,7 @@ void InetWvIn :: listen( int port, unsigned int nChannels,
|
||||
if ( connected_ ) delete soket_;
|
||||
|
||||
if ( nChannels < 1 ) {
|
||||
errorString_ << "InetWvIn()::listen(): the channel argument (" << nChannels << ") must be greater than zero.";
|
||||
oStream_ << "InetWvIn()::listen(): the channel argument must be greater than zero.";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ void InetWvIn :: listen( int port, unsigned int nChannels,
|
||||
else if ( format == STK_FLOAT64 ) dataBytes_ = 8;
|
||||
else if ( format == STK_SINT8 ) dataBytes_ = 1;
|
||||
else {
|
||||
errorString_ << "InetWvIn(): unknown data type specified (" << format << ").";
|
||||
oStream_ << "InetWvIn(): unknown data type specified!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
dataType_ = format;
|
||||
@@ -101,14 +102,14 @@ void InetWvIn :: listen( int port, unsigned int nChannels,
|
||||
|
||||
if ( protocol == Socket::PROTO_TCP ) {
|
||||
TcpServer *socket = new TcpServer( port );
|
||||
errorString_ << "InetWvIn:listen(): waiting for TCP connection on port " << socket->port() << " ... ";
|
||||
oStream_ << "InetWvIn:listen(): waiting for TCP connection on port " << socket->port() << " ... ";
|
||||
handleError( StkError::STATUS );
|
||||
fd_ = socket->accept();
|
||||
if ( fd_ < 0) {
|
||||
errorString_ << "InetWvIn::listen(): Error accepting TCP connection request!";
|
||||
oStream_ << "InetWvIn::listen(): Error accepting TCP connection request!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
errorString_ << "InetWvIn::listen(): TCP socket connection made!";
|
||||
oStream_ << "InetWvIn::listen(): TCP socket connection made!";
|
||||
handleError( StkError::STATUS );
|
||||
soket_ = (Socket *) socket;
|
||||
}
|
||||
@@ -146,7 +147,7 @@ void InetWvIn :: receive( void )
|
||||
int i = soket_->readBuffer( fd_, (void *)&buffer_[writePoint_], unfilled, 0 );
|
||||
//int i = Socket::readBuffer( fd_, (void *)&buffer_[writePoint_], unfilled, 0 );
|
||||
if ( i <= 0 ) {
|
||||
errorString_ << "InetWvIn::receive(): the remote InetWvIn socket has closed.";
|
||||
oStream_ << "InetWvIn::receive(): the remote InetWvIn socket has closed.";
|
||||
handleError( StkError::STATUS );
|
||||
connected_ = false;
|
||||
mutex_.unlock();
|
||||
@@ -261,15 +262,15 @@ StkFloat InetWvIn :: tick( unsigned int channel )
|
||||
// If no connection and we've output all samples in the queue, return 0.0.
|
||||
if ( !connected_ && bytesFilled_ == 0 && bufferCounter_ == 0 ) {
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "InetWvIn::tick(): a valid socket connection does not exist!";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
oStream_ << "InetWvIn::tick(): a valid socket connection does not exist!";
|
||||
handleError( StkError::DEBUG_PRINT );
|
||||
#endif
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= data_.channels() ) {
|
||||
errorString_ << "InetWvIn::tick(): channel argument is incompatible with data stream!";
|
||||
oStream_ << "InetWvIn::tick(): channel argument is incompatible with data stream!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
@@ -293,7 +294,7 @@ StkFrames& InetWvIn :: tick( StkFrames& frames )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( data_.channels() != frames.channels() ) {
|
||||
errorString_ << "InetWvIn::tick(): StkFrames argument is incompatible with streamed channels!";
|
||||
oStream_ << "InetWvIn::tick(): StkFrames argument is incompatible with streamed channels!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
@@ -301,8 +302,8 @@ StkFrames& InetWvIn :: tick( StkFrames& frames )
|
||||
// If no connection and we've output all samples in the queue, return.
|
||||
if ( !connected_ && bytesFilled_ == 0 && bufferCounter_ == 0 ) {
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "InetWvIn::tick(): a valid socket connection does not exist!";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
oStream_ << "InetWvIn::tick(): a valid socket connection does not exist!";
|
||||
handleError( StkError::DEBUG_PRINT );
|
||||
#endif
|
||||
return frames;
|
||||
}
|
||||
|
||||
@@ -17,13 +17,14 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "InetWvOut.h"
|
||||
#include "TcpClient.h"
|
||||
#include "UdpSocket.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace stk {
|
||||
|
||||
@@ -53,7 +54,7 @@ void InetWvOut :: connect( int port, Socket::ProtocolType protocol, std::string
|
||||
disconnect();
|
||||
|
||||
if ( nChannels == 0 ) {
|
||||
errorString_ << "InetWvOut::connect: the channel argument (" << nChannels << ") must be greater than zero!";
|
||||
oStream_ << "InetWvOut::connect: the channel argument must be greater than zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -62,7 +63,7 @@ void InetWvOut :: connect( int port, Socket::ProtocolType protocol, std::string
|
||||
else if ( format == STK_SINT32 || format == STK_FLOAT32 ) dataBytes_ = 4;
|
||||
else if ( format == STK_FLOAT64 ) dataBytes_ = 8;
|
||||
else {
|
||||
errorString_ << "InetWvOut::connect: unknown data type specified (" << format << ").";
|
||||
oStream_ << "InetWvOut::connect: unknown data type specified.";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
dataType_ = format;
|
||||
@@ -161,7 +162,7 @@ void InetWvOut :: writeData( unsigned long frames )
|
||||
|
||||
long bytes = dataBytes_ * samples;
|
||||
if ( soket_->writeBuffer( (const void *)buffer_, bytes, 0 ) < 0 ) {
|
||||
errorString_ << "InetWvOut: connection to socket server failed!";
|
||||
oStream_ << "InetWvOut: connection to socket server failed!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
}
|
||||
@@ -182,8 +183,8 @@ void InetWvOut :: tick( const StkFloat sample )
|
||||
{
|
||||
if ( !soket_ || !soket_->isValid( soket_->id() ) ) {
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "InetWvOut::tick(): a valid socket connection does not exist!";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
oStream_ << "InetWvOut::tick(): a valid socket connection does not exist!";
|
||||
handleError( StkError::DEBUG_PRINT );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -201,15 +202,15 @@ void InetWvOut :: tick( const StkFrames& frames )
|
||||
{
|
||||
if ( !soket_ || !soket_->isValid( soket_->id() ) ) {
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "InetWvOut::tick(): a valid socket connection does not exist!";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
oStream_ << "InetWvOut::tick(): a valid socket connection does not exist!";
|
||||
handleError( StkError::DEBUG_PRINT );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( data_.channels() != frames.channels() ) {
|
||||
errorString_ << "InetWvOut::tick(): incompatible channel value in StkFrames argument!";
|
||||
oStream_ << "InetWvOut::tick(): incompatible channel value in StkFrames argument!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2,14 +2,20 @@
|
||||
/*! \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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -20,10 +26,16 @@ namespace stk {
|
||||
|
||||
JCRev :: JCRev( StkFloat T60 )
|
||||
{
|
||||
if ( T60 <= 0.0 ) {
|
||||
oStream_ << "JCRev::JCRev: argument (" << T60 << ") must be positive!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
lastFrame_.resize( 1, 2, 0.0 ); // resize lastFrame_ for stereo output
|
||||
|
||||
// Delay lengths for 44100 Hz sample rate.
|
||||
int lengths[9] = {1777, 1847, 1993, 2137, 389, 127, 43, 211, 179};
|
||||
// {1116, 1188, 1356, 1277, 1422, 1491, 1617, 1557} // FreeVerb comb delays
|
||||
int lengths[9] = {1116, 1356, 1422, 1617, 225, 341, 441, 211, 179};
|
||||
double scaler = Stk::sampleRate() / 44100.0;
|
||||
|
||||
int delay, i;
|
||||
@@ -44,6 +56,7 @@ JCRev :: JCRev( StkFloat T60 )
|
||||
for ( i=0; i<4; i++ ) {
|
||||
combDelays_[i].setMaximumDelay( lengths[i] );
|
||||
combDelays_[i].setDelay( lengths[i] );
|
||||
combFilters_[i].setPole( 0.2 );
|
||||
}
|
||||
|
||||
this->setT60( T60 );
|
||||
@@ -73,6 +86,11 @@ void JCRev :: clear()
|
||||
|
||||
void JCRev :: setT60( StkFloat T60 )
|
||||
{
|
||||
if ( T60 <= 0.0 ) {
|
||||
oStream_ << "JCRev::setT60: argument (" << T60 << ") must be positive!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
for ( int i=0; i<4; i++ )
|
||||
combCoefficient_[i] = pow(10.0, (-3.0 * combDelays_[i].getDelay() / (T60 * Stk::sampleRate())));
|
||||
}
|
||||
@@ -81,7 +99,7 @@ StkFrames& JCRev :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() - 1 ) {
|
||||
errorString_ << "JCRev::tick(): channel and StkFrames arguments are incompatible!";
|
||||
oStream_ << "JCRev::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
@@ -90,8 +108,7 @@ StkFrames& JCRev :: tick( StkFrames& frames, unsigned int channel )
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples = tick( *samples );
|
||||
*samples++;
|
||||
*samples = lastFrame_[1];
|
||||
*(samples+1) = lastFrame_[1];
|
||||
}
|
||||
|
||||
return frames;
|
||||
@@ -101,7 +118,7 @@ StkFrames& JCRev :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int i
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
|
||||
errorString_ << "JCRev::tick(): channel and StkFrames arguments are incompatible!";
|
||||
oStream_ << "JCRev::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
@@ -110,8 +127,8 @@ StkFrames& JCRev :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int i
|
||||
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 );
|
||||
*oSamples = lastFrame_[1];
|
||||
*oSamples = tick( *iSamples );
|
||||
*(oSamples+1) = lastFrame_[1];
|
||||
}
|
||||
|
||||
return iFrames;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
### Do not edit -- Generated by 'configure --with-whatever' from Makefile.in
|
||||
### libstk Makefile - for various flavors of unix
|
||||
|
||||
LIBRARY = libstk.a
|
||||
SHAREDLIB = libstk.so
|
||||
STATICLIB = libstk.a
|
||||
SHAREDLIB = @sharedlib@
|
||||
MAJOR = 4
|
||||
RELEASE = 4.4.2
|
||||
RELEASE = 4.4.3
|
||||
|
||||
AR = ar -rsc
|
||||
RM = /bin/rm
|
||||
@@ -20,11 +20,11 @@ OBJECTS = Stk.o Generator.o Noise.o Blit.o BlitSaw.o BlitSquare.o Granulate.o \
|
||||
\
|
||||
Effect.o PRCRev.o JCRev.o NRev.o \
|
||||
Chorus.o Echo.o PitShift.o LentPitShift.o \
|
||||
Function.o ReedTable.o JetTable.o BowTable.o \
|
||||
Voicer.o Vector3D.o Sphere.o \
|
||||
Function.o ReedTable.o JetTable.o BowTable.o Cubic.o \
|
||||
Voicer.o Vector3D.o Sphere.o Twang.o \
|
||||
\
|
||||
Instrmnt.o Clarinet.o BlowHole.o Saxofony.o Flute.o Brass.o BlowBotl.o \
|
||||
Bowed.o Plucked.o StifKarp.o Sitar.o PluckTwo.o Mandolin.o Mesh2D.o \
|
||||
Bowed.o Plucked.o StifKarp.o Sitar.o Mandolin.o Mesh2D.o \
|
||||
FM.o Rhodey.o Wurley.o TubeBell.o HevyMetl.o PercFlut.o BeeThree.o FMVoices.o \
|
||||
Sampler.o Moog.o Simple.o Drummer.o Shakers.o \
|
||||
Modal.o ModalBar.o BandedWG.o Resonate.o VoicForm.o Phonemes.o Whistle.o \
|
||||
@@ -64,25 +64,24 @@ DEFS += -DRAWWAVE_PATH=\"$(RAWWAVES)\"
|
||||
%.o : ../src/include/%.cpp
|
||||
$(CC) $(CFLAGS) $(DEFS) -c $(<) -o $(OBJECT_PATH)/$@
|
||||
|
||||
all : $(LIBRARY)
|
||||
all : $(STATICLIB)
|
||||
|
||||
$(LIBRARY) : $(OBJECTS)
|
||||
$(RM) -f $(LIBRARY)
|
||||
$(AR) $(LIBRARY) $(OBJECT_PATH)/*.o
|
||||
$(STATICLIB) : $(OBJECTS)
|
||||
$(RM) -f $(STATICLIB)
|
||||
$(AR) $(STATICLIB) $(OBJECT_PATH)/*.o
|
||||
|
||||
$(SHAREDLIB).$(RELEASE) : $(OBJECTS)
|
||||
$(SHAREDLIB) : $(OBJECTS)
|
||||
$(RM) -f $(@) $(SHAREDLIB).$(MAJOR) $(SHAREDLIB)
|
||||
$(CC) $(LDFLAGS) -fPIC -shared -o $(@) $(OBJECT_PATH)/*.o $(LIBS)
|
||||
$(LN) -s $(SHAREDLIB).$(RELEASE) $(SHAREDLIB).$(MAJOR)
|
||||
$(LN) -s $(SHAREDLIB).$(RELEASE) $(SHAREDLIB)
|
||||
# $(CC) $(LDFLAGS) -fPIC -shared -Wl,-soname,$(SHAREDLIB).$(MAJOR) -o $(@) $(OBJECT_PATH)/*.o $(LIBS)
|
||||
$(CC) $(LDFLAGS) -fPIC @libflags@ $(OBJECT_PATH)/*.o $(LIBS)
|
||||
$(LN) -s @sharedname@ $(SHAREDLIB)
|
||||
# $(LN) -s @sharedname@ $(SHAREDLIB).$(MAJOR)
|
||||
|
||||
$(OBJECTS) : Stk.h
|
||||
|
||||
clean :
|
||||
$(RM) -f $(OBJECT_PATH)/*.o
|
||||
$(RM) -f $(LIBRARY)
|
||||
$(RM) -f $(SHAREDLIB)*
|
||||
$(RM) -f $(STATICLIB)
|
||||
$(RM) -f $(SHAREDLIB)* @sharedname@
|
||||
$(RM) -f *~
|
||||
$(RM) -fR *.dSYM
|
||||
|
||||
|
||||
228
src/Mandolin.cpp
228
src/Mandolin.cpp
@@ -2,19 +2,18 @@
|
||||
/*! \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
|
||||
@@ -23,7 +22,7 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -33,85 +32,66 @@
|
||||
namespace stk {
|
||||
|
||||
Mandolin :: Mandolin( StkFloat lowestFrequency )
|
||||
: PluckTwo( lowestFrequency )
|
||||
{
|
||||
if ( lowestFrequency <= 0.0 ) {
|
||||
oStream_ << "Mandolin::Mandolin: argument is less than or equal to zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
// Concatenate the STK rawwave path to the rawwave files
|
||||
soundfile_[0] = new FileWvIn( (Stk::rawwavePath() + "mand1.raw").c_str(), true );
|
||||
soundfile_[1] = new FileWvIn( (Stk::rawwavePath() + "mand2.raw").c_str(), true );
|
||||
soundfile_[2] = new FileWvIn( (Stk::rawwavePath() + "mand3.raw").c_str(), true );
|
||||
soundfile_[3] = new FileWvIn( (Stk::rawwavePath() + "mand4.raw").c_str(), true );
|
||||
soundfile_[4] = new FileWvIn( (Stk::rawwavePath() + "mand5.raw").c_str(), true );
|
||||
soundfile_[5] = new FileWvIn( (Stk::rawwavePath() + "mand6.raw").c_str(), true );
|
||||
soundfile_[6] = new FileWvIn( (Stk::rawwavePath() + "mand7.raw").c_str(), true );
|
||||
soundfile_[7] = new FileWvIn( (Stk::rawwavePath() + "mand8.raw").c_str(), true );
|
||||
soundfile_[8] = new FileWvIn( (Stk::rawwavePath() + "mand9.raw").c_str(), true );
|
||||
soundfile_[9] = new FileWvIn( (Stk::rawwavePath() + "mand10.raw").c_str(), true );
|
||||
soundfile_[10] = new FileWvIn( (Stk::rawwavePath() + "mand11.raw").c_str(), true );
|
||||
soundfile_[11] = new FileWvIn( (Stk::rawwavePath() + "mand12.raw").c_str(), true );
|
||||
soundfile_[0].openFile( (Stk::rawwavePath() + "mand1.raw").c_str(), true );
|
||||
soundfile_[1].openFile( (Stk::rawwavePath() + "mand2.raw").c_str(), true );
|
||||
soundfile_[2].openFile( (Stk::rawwavePath() + "mand3.raw").c_str(), true );
|
||||
soundfile_[3].openFile( (Stk::rawwavePath() + "mand4.raw").c_str(), true );
|
||||
soundfile_[4].openFile( (Stk::rawwavePath() + "mand5.raw").c_str(), true );
|
||||
soundfile_[5].openFile( (Stk::rawwavePath() + "mand6.raw").c_str(), true );
|
||||
soundfile_[6].openFile( (Stk::rawwavePath() + "mand7.raw").c_str(), true );
|
||||
soundfile_[7].openFile( (Stk::rawwavePath() + "mand8.raw").c_str(), true );
|
||||
soundfile_[8].openFile( (Stk::rawwavePath() + "mand9.raw").c_str(), true );
|
||||
soundfile_[9].openFile( (Stk::rawwavePath() + "mand10.raw").c_str(), true );
|
||||
soundfile_[10].openFile( (Stk::rawwavePath() + "mand11.raw").c_str(), true );
|
||||
soundfile_[11].openFile( (Stk::rawwavePath() + "mand12.raw").c_str(), true );
|
||||
|
||||
mic_ = 0;
|
||||
dampTime_ = 0;
|
||||
waveDone_ = soundfile_[mic_]->isFinished();
|
||||
detuning_ = 0.995;
|
||||
pluckAmplitude_ = 0.5;
|
||||
|
||||
strings_[0].setLowestFrequency( lowestFrequency );
|
||||
strings_[1].setLowestFrequency( lowestFrequency );
|
||||
this->setFrequency( 220.0 );
|
||||
this->setPluckPosition( 0.4 );
|
||||
}
|
||||
|
||||
Mandolin :: ~Mandolin( void )
|
||||
{
|
||||
for ( int i=0; i<12; i++ )
|
||||
delete soundfile_[i];
|
||||
}
|
||||
|
||||
void Mandolin :: pluck( StkFloat amplitude )
|
||||
void Mandolin :: clear( void )
|
||||
{
|
||||
// This function gets interesting, because pluck
|
||||
// may be longer than string length, so we just
|
||||
// reset the soundfile and add in the pluck in
|
||||
// the tick method.
|
||||
soundfile_[mic_]->reset();
|
||||
waveDone_ = false;
|
||||
pluckAmplitude_ = amplitude;
|
||||
if ( amplitude < 0.0 ) {
|
||||
errorString_ << "Mandolin::pluck: amplitude parameter less than zero ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
pluckAmplitude_ = 0.0;
|
||||
}
|
||||
else if ( amplitude > 1.0 ) {
|
||||
errorString_ << "Mandolin::pluck: amplitude parameter greater than one ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
pluckAmplitude_ = 1.0;
|
||||
}
|
||||
|
||||
// Set the pick position, which puts zeroes at position * length.
|
||||
combDelay_.setDelay( 0.5 * pluckPosition_ * lastLength_ );
|
||||
dampTime_ = (long) lastLength_; // See tick method below.
|
||||
strings_[0].clear();
|
||||
strings_[1].clear();
|
||||
}
|
||||
|
||||
void Mandolin :: pluck( StkFloat amplitude, StkFloat position )
|
||||
void Mandolin :: setPluckPosition( StkFloat position )
|
||||
{
|
||||
// Pluck position puts zeroes at position * length.
|
||||
pluckPosition_ = position;
|
||||
if ( position < 0.0 ) {
|
||||
std::cerr << "Mandolin::pluck: position parameter less than zero ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
pluckPosition_ = 0.0;
|
||||
}
|
||||
else if ( position > 1.0 ) {
|
||||
errorString_ << "Mandolin::pluck: amplitude parameter greater than one ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
pluckPosition_ = 1.0;
|
||||
if ( position < 0.0 || position > 1.0 ) {
|
||||
std::cerr << "Mandolin::setPluckPosition: position parameter out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
this->pluck( amplitude );
|
||||
strings_[0].setPluckPosition( position );
|
||||
strings_[1].setPluckPosition( position );
|
||||
}
|
||||
|
||||
void Mandolin :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
void Mandolin :: setDetune( StkFloat detune )
|
||||
{
|
||||
this->setFrequency( frequency );
|
||||
this->pluck( amplitude );
|
||||
if ( detune <= 0.0 ) {
|
||||
oStream_ << "Mandolin::setDeturn: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Mandolin::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
detuning_ = detune;
|
||||
strings_[1].setFrequency( frequency_ * detuning_ );
|
||||
}
|
||||
|
||||
void Mandolin :: setBodySize( StkFloat size )
|
||||
@@ -119,41 +99,87 @@ void Mandolin :: setBodySize( StkFloat size )
|
||||
// Scale the commuted body response by its sample rate (22050).
|
||||
StkFloat rate = size * 22050.0 / Stk::sampleRate();
|
||||
for ( int i=0; i<12; i++ )
|
||||
soundfile_[i]->setRate( rate );
|
||||
soundfile_[i].setRate( rate );
|
||||
}
|
||||
|
||||
void Mandolin :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "Mandolin::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
frequency_ = frequency;
|
||||
strings_[0].setFrequency( frequency_ );
|
||||
strings_[1].setFrequency( frequency_ * detuning_ );
|
||||
}
|
||||
|
||||
void Mandolin :: pluck( StkFloat amplitude )
|
||||
{
|
||||
if ( amplitude < 0.0 || amplitude > 1.0 ) {
|
||||
oStream_ << "Mandolin::pluck: amplitude parameter out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
soundfile_[mic_].reset();
|
||||
pluckAmplitude_ = amplitude;
|
||||
|
||||
//strings_[0].setLoopGain( 0.97 + pluckAmplitude_ * 0.03 );
|
||||
//strings_[1].setLoopGain( 0.97 + pluckAmplitude_ * 0.03 );
|
||||
}
|
||||
|
||||
void Mandolin :: pluck( StkFloat amplitude, StkFloat position )
|
||||
{
|
||||
this->setPluckPosition( position );
|
||||
this->pluck( amplitude );
|
||||
}
|
||||
|
||||
void Mandolin :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
{
|
||||
this->setFrequency( frequency );
|
||||
this->pluck( amplitude );
|
||||
}
|
||||
|
||||
void Mandolin :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
if ( amplitude < 0.0 || amplitude > 1.0 ) {
|
||||
oStream_ << "Mandolin::noteOff: amplitude is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
//strings_[0].setLoopGain( 0.97 + (1 - amplitude) * 0.03 );
|
||||
//strings_[1].setLoopGain( 0.97 + (1 - amplitude) * 0.03 );
|
||||
}
|
||||
|
||||
void Mandolin :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "Mandolin::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "Mandolin::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
if (number == __SK_BodySize_) // 2
|
||||
this->setBodySize( norm * 2.0 );
|
||||
else if (number == __SK_PickPosition_) // 4
|
||||
this->setPluckPosition( norm );
|
||||
else if (number == __SK_StringDamping_) // 11
|
||||
this->setBaseLoopGain( 0.97 + (norm * 0.03));
|
||||
else if (number == __SK_StringDetune_) // 1
|
||||
this->setDetune( 1.0 - (norm * 0.1) );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
mic_ = (int) (norm * 11.0);
|
||||
else {
|
||||
errorString_ << "Mandolin::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Mandolin::controlChange: number = " << number << ", value = " << value << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Mandolin::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if ( number == __SK_BodySize_ ) // 2
|
||||
this->setBodySize( normalizedValue * 2.0 );
|
||||
else if ( number == __SK_PickPosition_ ) // 4
|
||||
this->setPluckPosition( normalizedValue );
|
||||
else if ( number == __SK_StringDamping_ ) { // 11
|
||||
strings_[0].setLoopGain( 0.97 + (normalizedValue * 0.03) );
|
||||
strings_[1].setLoopGain( 0.97 + (normalizedValue * 0.03) );
|
||||
}
|
||||
else if ( number == __SK_StringDetune_ ) // 1
|
||||
this->setDetune( 1.0 - (normalizedValue * 0.1) );
|
||||
else if ( number == __SK_AfterTouch_Cont_ ) // 128
|
||||
mic_ = (int) (normalizedValue * 11.0);
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
oStream_ << "Mandolin::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
183
src/Mesh2D.cpp
183
src/Mesh2D.cpp
@@ -29,27 +29,31 @@
|
||||
|
||||
namespace stk {
|
||||
|
||||
Mesh2D :: Mesh2D( short nX, short nY )
|
||||
Mesh2D :: Mesh2D( unsigned short nX, unsigned short nY )
|
||||
{
|
||||
this->setNX(nX);
|
||||
this->setNY(nY);
|
||||
if ( nX == 0.0 || nY == 0.0 ) {
|
||||
oStream_ << "Mesh2D::Mesh2D: one or more argument is equal to zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
this->setNX( nX );
|
||||
this->setNY( nY );
|
||||
|
||||
StkFloat pole = 0.05;
|
||||
|
||||
short i;
|
||||
for (i=0; i<NYMAX; i++) {
|
||||
unsigned short i;
|
||||
for ( i=0; i<NYMAX; i++ ) {
|
||||
filterY_[i].setPole( pole );
|
||||
filterY_[i].setGain( 0.99 );
|
||||
}
|
||||
|
||||
for (i=0; i<NXMAX; i++) {
|
||||
for ( i=0; i<NXMAX; i++ ) {
|
||||
filterX_[i].setPole( pole );
|
||||
filterX_[i].setGain( 0.99 );
|
||||
}
|
||||
|
||||
this->clearMesh();
|
||||
|
||||
counter_=0;
|
||||
counter_ = 0;
|
||||
xInput_ = 0;
|
||||
yInput_ = 0;
|
||||
}
|
||||
@@ -62,26 +66,26 @@ void Mesh2D :: clear( void )
|
||||
{
|
||||
this->clearMesh();
|
||||
|
||||
short i;
|
||||
for (i=0; i<NY_; i++)
|
||||
unsigned short i;
|
||||
for ( i=0; i<NY_; i++ )
|
||||
filterY_[i].clear();
|
||||
|
||||
for (i=0; i<NX_; i++)
|
||||
for ( i=0; i<NX_; i++ )
|
||||
filterX_[i].clear();
|
||||
|
||||
counter_=0;
|
||||
counter_ = 0;
|
||||
}
|
||||
|
||||
void Mesh2D :: clearMesh( void )
|
||||
{
|
||||
int x, y;
|
||||
for (x=0; x<NXMAX-1; x++) {
|
||||
for (y=0; y<NYMAX-1; y++) {
|
||||
for ( x=0; x<NXMAX-1; x++ ) {
|
||||
for ( y=0; y<NYMAX-1; y++ ) {
|
||||
v_[x][y] = 0;
|
||||
}
|
||||
}
|
||||
for (x=0; x<NXMAX; x++) {
|
||||
for (y=0; y<NYMAX; y++) {
|
||||
for ( x=0; x<NXMAX; x++ ) {
|
||||
for ( y=0; y<NYMAX; y++ ) {
|
||||
|
||||
vxp_[x][y] = 0;
|
||||
vxm_[x][y] = 0;
|
||||
@@ -105,8 +109,8 @@ StkFloat Mesh2D :: energy( void )
|
||||
StkFloat t;
|
||||
StkFloat e = 0;
|
||||
if ( counter_ & 1 ) { // Ready for Mesh2D::tick1() to be called.
|
||||
for (x=0; x<NX_; x++) {
|
||||
for (y=0; y<NY_; y++) {
|
||||
for ( x=0; x<NX_; x++ ) {
|
||||
for ( y=0; y<NY_; y++ ) {
|
||||
t = vxp1_[x][y];
|
||||
e += t*t;
|
||||
t = vxm1_[x][y];
|
||||
@@ -119,8 +123,8 @@ StkFloat Mesh2D :: energy( void )
|
||||
}
|
||||
}
|
||||
else { // Ready for Mesh2D::tick0() to be called.
|
||||
for (x=0; x<NX_; x++) {
|
||||
for (y=0; y<NY_; y++) {
|
||||
for ( x=0; x<NX_; x++ ) {
|
||||
for ( y=0; y<NY_; y++ ) {
|
||||
t = vxp_[x][y];
|
||||
e += t*t;
|
||||
t = vxm_[x][y];
|
||||
@@ -133,88 +137,66 @@ StkFloat Mesh2D :: energy( void )
|
||||
}
|
||||
}
|
||||
|
||||
return(e);
|
||||
return e;
|
||||
}
|
||||
|
||||
void Mesh2D :: setNX( short lenX )
|
||||
void Mesh2D :: setNX( unsigned short lenX )
|
||||
{
|
||||
NX_ = lenX;
|
||||
if ( lenX < 2 ) {
|
||||
errorString_ << "Mesh2D::setNX(" << lenX << "): Minimum length is 2!";
|
||||
handleError( StkError::WARNING );
|
||||
NX_ = 2;
|
||||
oStream_ << "Mesh2D::setNX(" << lenX << "): Minimum length is 2!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else if ( lenX > NXMAX ) {
|
||||
errorString_ << "Mesh2D::setNX(" << lenX << "): Maximum length is " << NXMAX << '!';;
|
||||
handleError( StkError::WARNING );
|
||||
NX_ = NXMAX;
|
||||
oStream_ << "Mesh2D::setNX(" << lenX << "): Maximum length is " << NXMAX << '!';
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
NX_ = lenX;
|
||||
}
|
||||
|
||||
void Mesh2D :: setNY( short lenY )
|
||||
void Mesh2D :: setNY( unsigned short lenY )
|
||||
{
|
||||
NY_ = lenY;
|
||||
if ( lenY < 2 ) {
|
||||
errorString_ << "Mesh2D::setNY(" << lenY << "): Minimum length is 2!";
|
||||
handleError( StkError::WARNING );
|
||||
NY_ = 2;
|
||||
oStream_ << "Mesh2D::setNY(" << lenY << "): Minimum length is 2!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else if ( lenY > NYMAX ) {
|
||||
errorString_ << "Mesh2D::setNY(" << lenY << "): Maximum length is " << NXMAX << '!';;
|
||||
handleError( StkError::WARNING );
|
||||
NY_ = NYMAX;
|
||||
oStream_ << "Mesh2D::setNY(" << lenY << "): Maximum length is " << NXMAX << '!';
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
NY_ = lenY;
|
||||
}
|
||||
|
||||
void Mesh2D :: setDecay( StkFloat decayFactor )
|
||||
{
|
||||
StkFloat gain = decayFactor;
|
||||
if ( decayFactor < 0.0 ) {
|
||||
errorString_ << "Mesh2D::setDecay: decayFactor value is less than 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 0.0;
|
||||
}
|
||||
else if ( decayFactor > 1.0 ) {
|
||||
errorString_ << "Mesh2D::setDecay decayFactor value is greater than 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 1.0;
|
||||
if ( decayFactor < 0.0 || decayFactor > 1.0 ) {
|
||||
oStream_ << "Mesh2D::setDecay: decayFactor is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i=0; i<NYMAX; i++)
|
||||
filterY_[i].setGain( gain );
|
||||
for ( i=0; i<NYMAX; i++ )
|
||||
filterY_[i].setGain( decayFactor );
|
||||
|
||||
for (i=0; i<NXMAX; i++)
|
||||
filterX_[i].setGain( gain );
|
||||
filterX_[i].setGain( decayFactor );
|
||||
}
|
||||
|
||||
void Mesh2D :: setInputPosition( StkFloat xFactor, StkFloat yFactor )
|
||||
{
|
||||
if ( xFactor < 0.0 ) {
|
||||
errorString_ << "Mesh2D::setInputPosition xFactor value is less than 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
xInput_ = 0;
|
||||
if ( xFactor < 0.0 || xFactor > 1.0 ) {
|
||||
oStream_ << "Mesh2D::setInputPosition xFactor value is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else if ( xFactor > 1.0 ) {
|
||||
errorString_ << "Mesh2D::setInputPosition xFactor value is greater than 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
xInput_ = NX_ - 1;
|
||||
}
|
||||
else
|
||||
xInput_ = (short) (xFactor * (NX_ - 1));
|
||||
|
||||
if ( yFactor < 0.0 ) {
|
||||
errorString_ << "Mesh2D::setInputPosition yFactor value is less than 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
yInput_ = 0;
|
||||
if ( yFactor < 0.0 || yFactor > 1.0 ) {
|
||||
oStream_ << "Mesh2D::setInputPosition yFactor value is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else if ( yFactor > 1.0 ) {
|
||||
errorString_ << "Mesh2D::setInputPosition yFactor value is greater than 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
yInput_ = NY_ - 1;
|
||||
}
|
||||
else
|
||||
yInput_ = (short) (yFactor * (NY_ - 1));
|
||||
|
||||
xInput_ = (unsigned short) (xFactor * (NX_ - 1));
|
||||
yInput_ = (unsigned short) (yFactor * (NY_ - 1));
|
||||
}
|
||||
|
||||
void Mesh2D :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
@@ -228,19 +210,11 @@ void Mesh2D :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
vxp_[xInput_][yInput_] += amplitude;
|
||||
vyp_[xInput_][yInput_] += amplitude;
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Mesh2D::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Mesh2D :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Mesh2D::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
StkFloat Mesh2D :: inputTick( StkFloat input )
|
||||
@@ -366,34 +340,27 @@ StkFloat Mesh2D :: tick1( void )
|
||||
|
||||
void Mesh2D :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "Mesh2D::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "Mesh2D::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
if (number == 2) // 2
|
||||
this->setNX( (short) (norm * (NXMAX-2) + 2) );
|
||||
else if (number == 4) // 4
|
||||
this->setNY( (short) (norm * (NYMAX-2) + 2) );
|
||||
else if (number == 11) // 11
|
||||
this->setDecay( 0.9 + (norm * 0.1) );
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
this->setInputPosition( norm, norm );
|
||||
else {
|
||||
errorString_ << "Mesh2D::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Mesh2D::controlChange: number = " << number << ", value = " << value << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Mesh2D::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if ( number == 2 ) // 2
|
||||
this->setNX( (unsigned short) (normalizedValue * (NXMAX-2) + 2) );
|
||||
else if ( number == 4 ) // 4
|
||||
this->setNY( (unsigned short) (normalizedValue * (NYMAX-2) + 2) );
|
||||
else if ( number == 11 ) // 11
|
||||
this->setDecay( 0.9 + (normalizedValue * 0.1) );
|
||||
else if ( number == __SK_ModWheel_ ) // 1
|
||||
this->setInputPosition( normalizedValue, normalizedValue );
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
oStream_ << "Mesh2D::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -85,11 +85,11 @@ bool Messager :: setScoreFile( const char* filename )
|
||||
{
|
||||
if ( data_.sources ) {
|
||||
if ( data_.sources == STK_FILE ) {
|
||||
errorString_ << "Messager::setScoreFile: already reading a scorefile!";
|
||||
oStream_ << "Messager::setScoreFile: already reading a scorefile!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else {
|
||||
errorString_ << "Messager::setScoreFile: already reading realtime control input ... cannot do scorefile input too!";
|
||||
oStream_ << "Messager::setScoreFile: already reading realtime control input ... cannot do scorefile input too!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
return false;
|
||||
@@ -141,20 +141,20 @@ void Messager :: pushMessage( Skini::Message& message )
|
||||
bool Messager :: startStdInput()
|
||||
{
|
||||
if ( data_.sources == STK_FILE ) {
|
||||
errorString_ << "Messager::startStdInput: already reading a scorefile ... cannot do realtime control input too!";
|
||||
oStream_ << "Messager::startStdInput: already reading a scorefile ... cannot do realtime control input too!";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( data_.sources & STK_STDIN ) {
|
||||
errorString_ << "Messager::startStdInput: stdin input thread already started.";
|
||||
oStream_ << "Messager::startStdInput: stdin input thread already started.";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start the stdin input thread.
|
||||
if ( !stdinThread_.start( (THREAD_FUNCTION)&stdinHandler, &data_ ) ) {
|
||||
errorString_ << "Messager::startStdInput: unable to start stdin input thread!";
|
||||
oStream_ << "Messager::startStdInput: unable to start stdin input thread!";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
@@ -208,7 +208,13 @@ void midiHandler( double timeStamp, std::vector<unsigned char> *bytes, void *ptr
|
||||
if ( ( message.type != 0xC0 ) && ( message.type != 0xD0 ) ) {
|
||||
if ( bytes->size() < 3 ) return;
|
||||
message.intValues[1] = bytes->at(2);
|
||||
message.floatValues[1] = (StkFloat) message.intValues[1];
|
||||
if ( message.type == 0xE0 ) { // combine pithbend into single "14-bit" value
|
||||
message.intValues[0] += message.intValues[1] <<= 7;
|
||||
message.floatValues[0] = (StkFloat) message.intValues[0];
|
||||
message.intValues[1] = 0;
|
||||
}
|
||||
else
|
||||
message.floatValues[1] = (StkFloat) message.intValues[1];
|
||||
}
|
||||
|
||||
while ( data->queue.size() >= data->queueLimit ) Stk::sleep( 50 );
|
||||
@@ -221,13 +227,13 @@ void midiHandler( double timeStamp, std::vector<unsigned char> *bytes, void *ptr
|
||||
bool Messager :: startMidiInput( int port )
|
||||
{
|
||||
if ( data_.sources == STK_FILE ) {
|
||||
errorString_ << "Messager::startMidiInput: already reading a scorefile ... cannot do realtime control input too!";
|
||||
oStream_ << "Messager::startMidiInput: already reading a scorefile ... cannot do realtime control input too!";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( data_.sources & STK_MIDI ) {
|
||||
errorString_ << "Messager::startMidiInput: MIDI input already started.";
|
||||
oStream_ << "Messager::startMidiInput: MIDI input already started.";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
@@ -236,7 +242,7 @@ bool Messager :: startMidiInput( int port )
|
||||
// (to allow the user to exit).
|
||||
if ( !( data_.sources & STK_STDIN ) ) {
|
||||
if ( this->startStdInput() == false ) {
|
||||
errorString_ << "Messager::startMidiInput: unable to start input from stdin.";
|
||||
oStream_ << "Messager::startMidiInput: unable to start input from stdin.";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
@@ -249,7 +255,7 @@ bool Messager :: startMidiInput( int port )
|
||||
else data_.midi->openPort( (unsigned int)port );
|
||||
}
|
||||
catch ( RtError &error ) {
|
||||
errorString_ << "Messager::startMidiInput: error creating RtMidiIn instance (" << error.getMessage() << ").";
|
||||
oStream_ << "Messager::startMidiInput: error creating RtMidiIn instance (" << error.getMessage() << ").";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
@@ -261,13 +267,13 @@ bool Messager :: startMidiInput( int port )
|
||||
bool Messager :: startSocketInput( int port )
|
||||
{
|
||||
if ( data_.sources == STK_FILE ) {
|
||||
errorString_ << "Messager::startSocketInput: already reading a scorefile ... cannot do realtime control input too!";
|
||||
oStream_ << "Messager::startSocketInput: already reading a scorefile ... cannot do realtime control input too!";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( data_.sources & STK_SOCKET ) {
|
||||
errorString_ << "Messager::startSocketInput: socket input thread already started.";
|
||||
oStream_ << "Messager::startSocketInput: socket input thread already started.";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
@@ -280,7 +286,7 @@ bool Messager :: startSocketInput( int port )
|
||||
return false;
|
||||
}
|
||||
|
||||
errorString_ << "Socket server listening for connection(s) on port " << port << "...";
|
||||
oStream_ << "Socket server listening for connection(s) on port " << port << "...";
|
||||
handleError( StkError::STATUS );
|
||||
|
||||
// Initialize socket descriptor information.
|
||||
@@ -291,7 +297,7 @@ bool Messager :: startSocketInput( int port )
|
||||
|
||||
// Start the socket thread.
|
||||
if ( !socketThread_.start( (THREAD_FUNCTION)&socketHandler, &data_ ) ) {
|
||||
errorString_ << "Messager::startSocketInput: unable to start socket input thread!";
|
||||
oStream_ << "Messager::startSocketInput: unable to start socket input thread!";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ MidiFileIn :: MidiFileIn( std::string fileName )
|
||||
// Attempt to open the file.
|
||||
file_.open( fileName.c_str(), std::ios::in | std::ios::binary );
|
||||
if ( !file_ ) {
|
||||
errorString_ << "MidiFileIn: error opening or finding file (" << fileName << ").";
|
||||
oStream_ << "MidiFileIn: error opening or finding file (" << fileName << ").";
|
||||
handleError( StkError::FILE_NOT_FOUND );
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ MidiFileIn :: MidiFileIn( std::string fileName )
|
||||
#endif
|
||||
length = (SINT32 *) &buffer;
|
||||
if ( strncmp( chunkType, "MThd", 4 ) || ( *length != 6 ) ) {
|
||||
errorString_ << "MidiFileIn: file (" << fileName << ") does not appear to be a MIDI file!";
|
||||
oStream_ << "MidiFileIn: file (" << fileName << ") does not appear to be a MIDI file!";
|
||||
handleError( StkError::FILE_UNKNOWN_FORMAT );
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ MidiFileIn :: MidiFileIn( std::string fileName )
|
||||
#endif
|
||||
data = (SINT16 *) &buffer;
|
||||
if ( *data < 0 || *data > 2 ) {
|
||||
errorString_ << "MidiFileIn: the file (" << fileName << ") format is invalid!";
|
||||
oStream_ << "MidiFileIn: the file (" << fileName << ") format is invalid!";
|
||||
handleError( StkError::FILE_ERROR );
|
||||
}
|
||||
format_ = *data;
|
||||
@@ -64,7 +64,7 @@ MidiFileIn :: MidiFileIn( std::string fileName )
|
||||
swap16((unsigned char *)&buffer);
|
||||
#endif
|
||||
if ( format_ == 0 && *data != 1 ) {
|
||||
errorString_ << "MidiFileIn: invalid number of tracks (>1) for a file format = 0!";
|
||||
oStream_ << "MidiFileIn: invalid number of tracks (>1) for a file format = 0!";
|
||||
handleError( StkError::FILE_ERROR );
|
||||
}
|
||||
nTracks_ = *data;
|
||||
@@ -153,7 +153,7 @@ MidiFileIn :: MidiFileIn( std::string fileName )
|
||||
return;
|
||||
|
||||
error:
|
||||
errorString_ << "MidiFileIn: error reading from file (" << fileName << ").";
|
||||
oStream_ << "MidiFileIn: error reading from file (" << fileName << ").";
|
||||
handleError( StkError::FILE_ERROR );
|
||||
}
|
||||
|
||||
@@ -164,26 +164,11 @@ MidiFileIn :: ~MidiFileIn()
|
||||
file_.close();
|
||||
}
|
||||
|
||||
int MidiFileIn :: getFileFormat() const
|
||||
{
|
||||
return format_;
|
||||
}
|
||||
|
||||
unsigned int MidiFileIn :: getNumberOfTracks() const
|
||||
{
|
||||
return nTracks_;
|
||||
}
|
||||
|
||||
int MidiFileIn :: getDivision() const
|
||||
{
|
||||
return division_;
|
||||
}
|
||||
|
||||
void MidiFileIn :: rewindTrack( unsigned int track )
|
||||
{
|
||||
if ( track >= nTracks_ ) {
|
||||
errorString_ << "MidiFileIn::getNextEvent: invalid track argument (" << track << ").";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
oStream_ << "MidiFileIn::getNextEvent: invalid track argument (" << track << ").";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
trackPointers_[track] = trackOffsets_[track];
|
||||
@@ -195,8 +180,8 @@ double MidiFileIn :: getTickSeconds( unsigned int track )
|
||||
{
|
||||
// Return the current tick value in seconds for the given track.
|
||||
if ( track >= nTracks_ ) {
|
||||
errorString_ << "MidiFileIn::getTickSeconds: invalid track argument (" << track << ").";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
oStream_ << "MidiFileIn::getTickSeconds: invalid track argument (" << track << ").";
|
||||
handleError( StkError::WARNING ); return 0.0;
|
||||
}
|
||||
|
||||
return tickSeconds_[track];
|
||||
@@ -218,12 +203,12 @@ unsigned long MidiFileIn :: getNextEvent( std::vector<unsigned char> *event, uns
|
||||
// running sum of ticks for each track and update the tickSeconds_
|
||||
// parameter as needed based on the stored tempo map.
|
||||
|
||||
event->clear();
|
||||
if ( track >= nTracks_ ) {
|
||||
errorString_ << "MidiFileIn::getNextEvent: invalid track argument (" << track << ").";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
oStream_ << "MidiFileIn::getNextEvent: invalid track argument (" << track << ").";
|
||||
handleError( StkError::WARNING ); return 0;
|
||||
}
|
||||
|
||||
event->clear();
|
||||
// Check for the end of the track.
|
||||
if ( (trackPointers_[track] - trackOffsets_[track]) >= trackLengths_[track] )
|
||||
return 0;
|
||||
@@ -314,7 +299,7 @@ unsigned long MidiFileIn :: getNextEvent( std::vector<unsigned char> *event, uns
|
||||
return ticks;
|
||||
|
||||
error:
|
||||
errorString_ << "MidiFileIn::getNextEvent: file read error!";
|
||||
oStream_ << "MidiFileIn::getNextEvent: file read error!";
|
||||
handleError( StkError::FILE_ERROR );
|
||||
return 0;
|
||||
}
|
||||
@@ -325,8 +310,8 @@ unsigned long MidiFileIn :: getNextMidiEvent( std::vector<unsigned char> *midiEv
|
||||
// specified track (default = 0) and return the event delta time in
|
||||
// ticks. Meta-Events preceeding this event are skipped and ignored.
|
||||
if ( track >= nTracks_ ) {
|
||||
errorString_ << "MidiFileIn::getNextMidiEvent: invalid track argument (" << track << ").";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
oStream_ << "MidiFileIn::getNextMidiEvent: invalid track argument (" << track << ").";
|
||||
handleError( StkError::WARNING ); return 0;
|
||||
}
|
||||
|
||||
unsigned long ticks = getNextEvent( midiEvent, track );
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
(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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -20,7 +20,7 @@ Modal :: Modal( unsigned int modes )
|
||||
: nModes_(modes)
|
||||
{
|
||||
if ( nModes_ == 0 ) {
|
||||
errorString_ << "Modal: 'modes' argument to constructor is zero!";
|
||||
oStream_ << "Modal: 'modes' argument to constructor is zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
@@ -65,6 +65,13 @@ void Modal :: clear( void )
|
||||
|
||||
void Modal :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "Modal::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
baseFrequency_ = frequency;
|
||||
for ( unsigned int i=0; i<nModes_; i++ )
|
||||
this->setRatioAndRadius( i, ratios_[i], radii_[i] );
|
||||
@@ -73,9 +80,8 @@ void Modal :: setFrequency( StkFloat frequency )
|
||||
void Modal :: setRatioAndRadius( unsigned int modeIndex, StkFloat ratio, StkFloat radius )
|
||||
{
|
||||
if ( modeIndex >= nModes_ ) {
|
||||
errorString_ << "Modal::setRatioAndRadius: modeIndex parameter is greater than number of modes!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
oStream_ << "Modal::setRatioAndRadius: modeIndex parameter is greater than number of modes!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
StkFloat nyquist = Stk::sampleRate() / 2.0;
|
||||
@@ -89,8 +95,8 @@ void Modal :: setRatioAndRadius( unsigned int modeIndex, StkFloat ratio, StkFloa
|
||||
while (temp * baseFrequency_ > nyquist) temp *= 0.5;
|
||||
ratios_[modeIndex] = temp;
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Modal::setRatioAndRadius: aliasing would occur here ... correcting.";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
oStream_ << "Modal::setRatioAndRadius: aliasing would occur here ... correcting.";
|
||||
handleError( StkError::DEBUG_PRINT );
|
||||
#endif
|
||||
}
|
||||
radii_[modeIndex] = radius;
|
||||
@@ -105,9 +111,8 @@ void Modal :: setRatioAndRadius( unsigned int modeIndex, StkFloat ratio, StkFloa
|
||||
void Modal :: setModeGain( unsigned int modeIndex, StkFloat gain )
|
||||
{
|
||||
if ( modeIndex >= nModes_ ) {
|
||||
errorString_ << "Modal::setModeGain: modeIndex parameter is greater than number of modes!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
oStream_ << "Modal::setModeGain: modeIndex parameter is greater than number of modes!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
filters_[modeIndex]->setGain( gain );
|
||||
@@ -115,21 +120,14 @@ void Modal :: setModeGain( unsigned int modeIndex, StkFloat gain )
|
||||
|
||||
void Modal :: strike( StkFloat amplitude )
|
||||
{
|
||||
StkFloat gain = amplitude;
|
||||
if ( amplitude < 0.0 ) {
|
||||
errorString_ << "Modal::strike: amplitude is less than zero ... setting to zero!";
|
||||
if ( amplitude < 0.0 || amplitude > 1.0 ) {
|
||||
oStream_ << "Modal::strike: amplitude is out of range!";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 0.0;
|
||||
}
|
||||
else if ( amplitude > 1.0 ) {
|
||||
errorString_ << "Modal::strike: amplitude is greater than one ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 1.0;
|
||||
}
|
||||
|
||||
envelope_.setRate( 1.0 );
|
||||
envelope_.setTarget( gain );
|
||||
onepole_.setPole( 1.0 - gain );
|
||||
envelope_.setTarget( amplitude );
|
||||
onepole_.setPole( 1.0 - amplitude );
|
||||
envelope_.tick();
|
||||
wave_->reset();
|
||||
|
||||
@@ -145,13 +143,8 @@ void Modal :: strike( StkFloat amplitude )
|
||||
|
||||
void Modal :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
{
|
||||
this->strike(amplitude);
|
||||
this->setFrequency(frequency);
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Modal::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
this->strike( amplitude );
|
||||
this->setFrequency( frequency );
|
||||
}
|
||||
|
||||
void Modal :: noteOff( StkFloat amplitude )
|
||||
@@ -159,11 +152,6 @@ void Modal :: noteOff( StkFloat amplitude )
|
||||
// This calls damp, but inverts the meaning of amplitude (high
|
||||
// amplitude means fast damping).
|
||||
this->damp( 1.0 - (amplitude * 0.03) );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Modal::NoteOff: amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Modal :: damp( StkFloat amplitude )
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -52,35 +52,24 @@ ModalBar :: ~ModalBar( void )
|
||||
|
||||
void ModalBar :: setStickHardness( StkFloat hardness )
|
||||
{
|
||||
stickHardness_ = hardness;
|
||||
if ( hardness < 0.0 ) {
|
||||
errorString_ << "ModalBar::setStickHardness: parameter is less than zero ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
stickHardness_ = 0.0;
|
||||
}
|
||||
else if ( hardness > 1.0 ) {
|
||||
errorString_ << "ModalBar::setStickHarness: parameter is greater than one ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
stickHardness_ = 1.0;
|
||||
if ( hardness < 0.0 || hardness > 1.0 ) {
|
||||
oStream_ << "ModalBar::setStickHardness: parameter is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
stickHardness_ = hardness;
|
||||
wave_->setRate( (0.25 * pow(4.0, stickHardness_) ) );
|
||||
masterGain_ = 0.1 + (1.8 * stickHardness_);
|
||||
}
|
||||
|
||||
void ModalBar :: setStrikePosition( StkFloat position )
|
||||
{
|
||||
if ( position < 0.0 || position > 1.0 ) {
|
||||
oStream_ << "ModalBar::setStrikePosition: parameter is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
strikePosition_ = position;
|
||||
if ( position < 0.0 ) {
|
||||
errorString_ << "ModalBar::setStrikePosition: parameter is less than zero ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
strikePosition_ = 0.0;
|
||||
}
|
||||
else if ( position > 1.0 ) {
|
||||
errorString_ << "ModalBar::setStrikePosition: parameter is greater than one ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
strikePosition_ = 1.0;
|
||||
}
|
||||
|
||||
// Hack only first three modes.
|
||||
StkFloat temp2 = position * PI;
|
||||
@@ -160,40 +149,33 @@ void ModalBar :: setPreset( int preset )
|
||||
|
||||
void ModalBar :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "ModalBar::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "ModalBar::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "ModalBar::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_StickHardness_) // 2
|
||||
this->setStickHardness( norm );
|
||||
this->setStickHardness( normalizedValue );
|
||||
else if (number == __SK_StrikePosition_) // 4
|
||||
this->setStrikePosition( norm );
|
||||
this->setStrikePosition( normalizedValue );
|
||||
else if (number == __SK_ProphesyRibbon_) // 16
|
||||
this->setPreset((int) value);
|
||||
else if (number == __SK_Balance_) // 8
|
||||
vibratoGain_ = norm * 0.3;
|
||||
vibratoGain_ = normalizedValue * 0.3;
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
directGain_ = norm;
|
||||
directGain_ = normalizedValue;
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
vibrato_.setFrequency( norm * 12.0 );
|
||||
vibrato_.setFrequency( normalizedValue * 12.0 );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
envelope_.setTarget( norm );
|
||||
envelope_.setTarget( normalizedValue );
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
errorString_ << "ModalBar::controlChange: undefined control number (" << number << ")!";
|
||||
oStream_ << "ModalBar::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "ModalBar::controlChange: number = " << number << ", value = " << value << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
67
src/Moog.cpp
67
src/Moog.cpp
@@ -14,7 +14,7 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -46,13 +46,14 @@ Moog :: ~Moog( void )
|
||||
|
||||
void Moog :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
baseFrequency_ = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "Moog::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
baseFrequency_ = 220.0;
|
||||
oStream_ << "Moog::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
baseFrequency_ = frequency;
|
||||
StkFloat rate = attacks_[0]->getSize() * 0.01 * baseFrequency_ / Stk::sampleRate();
|
||||
attacks_[0]->setRate( rate );
|
||||
loops_[0]->setFrequency( baseFrequency_ );
|
||||
@@ -77,45 +78,33 @@ void Moog :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
|
||||
filters_[0].setSweepRate( filterRate_ * 22050.0 / Stk::sampleRate() );
|
||||
filters_[1].setSweepRate( filterRate_ * 22050.0 / Stk::sampleRate() );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Moog::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Moog :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "Moog::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "Moog::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
if (number == __SK_FilterQ_) // 2
|
||||
filterQ_ = 0.80 + ( 0.1 * norm );
|
||||
else if (number == __SK_FilterSweepRate_) // 4
|
||||
filterRate_ = norm * 0.0002;
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
this->setModulationSpeed( norm * 12.0 );
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
this->setModulationDepth( norm );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
adsr_.setTarget( norm );
|
||||
else {
|
||||
errorString_ << "Moog::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Moog::controlChange: number = " << number << ", value = " << value << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Moog::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_FilterQ_) // 2
|
||||
filterQ_ = 0.80 + ( 0.1 * normalizedValue );
|
||||
else if (number == __SK_FilterSweepRate_) // 4
|
||||
filterRate_ = normalizedValue * 0.0002;
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
this->setModulationSpeed( normalizedValue * 12.0 );
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
this->setModulationDepth( normalizedValue );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
adsr_.setTarget( normalizedValue );
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
oStream_ << "Moog::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
23
src/NRev.cpp
23
src/NRev.cpp
@@ -10,7 +10,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -21,6 +21,11 @@ namespace stk {
|
||||
|
||||
NRev :: NRev( StkFloat T60 )
|
||||
{
|
||||
if ( T60 <= 0.0 ) {
|
||||
oStream_ << "NRev::NRev: argument (" << T60 << ") must be positive!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
lastFrame_.resize( 1, 2, 0.0 ); // resize lastFrame_ for stereo output
|
||||
|
||||
int lengths[15] = {1433, 1601, 1867, 2053, 2251, 2399, 347, 113, 37, 59, 53, 43, 37, 29, 19};
|
||||
@@ -63,6 +68,11 @@ void NRev :: clear()
|
||||
|
||||
void NRev :: setT60( StkFloat T60 )
|
||||
{
|
||||
if ( T60 <= 0.0 ) {
|
||||
oStream_ << "NRev::setT60: argument (" << T60 << ") must be positive!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
for ( int i=0; i<6; i++ )
|
||||
combCoefficient_[i] = pow(10.0, (-3.0 * combDelays_[i].getDelay() / (T60 * Stk::sampleRate())));
|
||||
}
|
||||
@@ -71,7 +81,7 @@ StkFrames& NRev :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() - 1 ) {
|
||||
errorString_ << "NRev::tick(): channel and StkFrames arguments are incompatible!";
|
||||
oStream_ << "NRev::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
@@ -80,8 +90,7 @@ StkFrames& NRev :: tick( StkFrames& frames, unsigned int channel )
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples = tick( *samples );
|
||||
samples++;
|
||||
*samples = lastFrame_[1];
|
||||
*(samples+1) = lastFrame_[1];
|
||||
}
|
||||
|
||||
return frames;
|
||||
@@ -91,7 +100,7 @@ StkFrames& NRev :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iC
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
|
||||
errorString_ << "NRev::tick(): channel and StkFrames arguments are incompatible!";
|
||||
oStream_ << "NRev::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
@@ -100,8 +109,8 @@ StkFrames& NRev :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iC
|
||||
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 );
|
||||
*oSamples = lastFrame_[1];
|
||||
*oSamples = tick( *iSamples );
|
||||
*(oSamples+1) = lastFrame_[1];
|
||||
}
|
||||
|
||||
return iFrames;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -18,6 +18,7 @@ OnePole :: OnePole( StkFloat thePole )
|
||||
{
|
||||
b_.resize( 1 );
|
||||
a_.resize( 2 );
|
||||
a_[0] = 1.0;
|
||||
inputs_.resize( 1, 1, 0.0 );
|
||||
outputs_.resize( 2, 1, 0.0 );
|
||||
|
||||
@@ -30,6 +31,11 @@ OnePole :: ~OnePole()
|
||||
|
||||
void OnePole :: setPole( StkFloat thePole )
|
||||
{
|
||||
if ( std::abs( thePole ) >= 1.0 ) {
|
||||
oStream_ << "OnePole::setPole: argument (" << thePole << ") should be less than 1.0!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
// Normalize coefficients for peak unity gain.
|
||||
if ( thePole > 0.0 )
|
||||
b_[0] = (StkFloat) (1.0 - thePole);
|
||||
@@ -41,6 +47,11 @@ void OnePole :: setPole( StkFloat thePole )
|
||||
|
||||
void OnePole :: setCoefficients( StkFloat b0, StkFloat a1, bool clearState )
|
||||
{
|
||||
if ( std::abs( a1 ) >= 1.0 ) {
|
||||
oStream_ << "OnePole::setCoefficients: a1 argument (" << a1 << ") should be less than 1.0!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
b_[0] = b0;
|
||||
a_[1] = a1;
|
||||
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "OneZero.h"
|
||||
#include <cmath>
|
||||
|
||||
namespace stk {
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -21,10 +21,15 @@ namespace stk {
|
||||
|
||||
PRCRev :: PRCRev( StkFloat T60 )
|
||||
{
|
||||
if ( T60 <= 0.0 ) {
|
||||
oStream_ << "PRCRev::PRCRev: argument (" << T60 << ") must be positive!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
lastFrame_.resize( 1, 2, 0.0 ); // resize lastFrame_ for stereo output
|
||||
|
||||
// Delay lengths for 44100 Hz sample rate.
|
||||
int lengths[4]= {353, 1097, 1777, 2137};
|
||||
int lengths[4]= {341, 613, 1557, 2137};
|
||||
double scaler = Stk::sampleRate() / 44100.0;
|
||||
|
||||
// Scale the delay lengths if necessary.
|
||||
@@ -64,6 +69,11 @@ void PRCRev :: clear( void )
|
||||
|
||||
void PRCRev :: setT60( StkFloat T60 )
|
||||
{
|
||||
if ( T60 <= 0.0 ) {
|
||||
oStream_ << "PRCRev::setT60: argument (" << T60 << ") must be positive!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
combCoefficient_[0] = pow(10.0, (-3.0 * combDelays_[0].getDelay() / (T60 * Stk::sampleRate())));
|
||||
combCoefficient_[1] = pow(10.0, (-3.0 * combDelays_[1].getDelay() / (T60 * Stk::sampleRate())));
|
||||
}
|
||||
@@ -72,7 +82,7 @@ StkFrames& PRCRev :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() - 1 ) {
|
||||
errorString_ << "PRCRev::tick(): channel and StkFrames arguments are incompatible!";
|
||||
oStream_ << "PRCRev::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
@@ -81,8 +91,7 @@ StkFrames& PRCRev :: tick( StkFrames& frames, unsigned int channel )
|
||||
unsigned int hop = frames.channels();
|
||||
for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
|
||||
*samples = tick( *samples );
|
||||
*samples++;
|
||||
*samples = lastFrame_[1];
|
||||
*(samples+1) = lastFrame_[1];
|
||||
}
|
||||
|
||||
return frames;
|
||||
@@ -92,7 +101,7 @@ StkFrames& PRCRev :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
|
||||
errorString_ << "PRCRev::tick(): channel and StkFrames arguments are incompatible!";
|
||||
oStream_ << "PRCRev::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
@@ -101,8 +110,8 @@ StkFrames& PRCRev :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int
|
||||
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 );
|
||||
*oSamples = lastFrame_[1];
|
||||
*oSamples = tick( *iSamples );
|
||||
*(oSamples+1) = lastFrame_[1];
|
||||
}
|
||||
|
||||
return iFrames;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -62,6 +62,13 @@ PercFlut :: ~PercFlut( void )
|
||||
|
||||
void PercFlut :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "PercFlut::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
baseFrequency_ = frequency;
|
||||
}
|
||||
|
||||
@@ -73,11 +80,6 @@ void PercFlut :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
gains_[3] = amplitude * fmGains_[85] * 0.5;
|
||||
this->setFrequency( frequency );
|
||||
this->keyOn();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "PercFlut::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -217,9 +217,8 @@ Phonemes :: ~Phonemes(void)
|
||||
const char *Phonemes :: name( unsigned int index )
|
||||
{
|
||||
if ( index > 31 ) {
|
||||
std::ostringstream error;
|
||||
error << "Phonemes::name: index is greater than 31!";
|
||||
handleError( error.str(), StkError::WARNING );
|
||||
oStream_ << "Phonemes::name: index is greater than 31!";
|
||||
handleError( oStream_.str(), StkError::WARNING );
|
||||
return 0;
|
||||
}
|
||||
return phonemeNames[index];
|
||||
@@ -228,9 +227,8 @@ const char *Phonemes :: name( unsigned int index )
|
||||
StkFloat Phonemes :: voiceGain( unsigned int index )
|
||||
{
|
||||
if ( index > 31 ) {
|
||||
std::ostringstream error;
|
||||
error << "Phonemes::voiceGain: index is greater than 31!";
|
||||
handleError( error.str(), StkError::WARNING );
|
||||
oStream_ << "Phonemes::voiceGain: index is greater than 31!";
|
||||
handleError( oStream_.str(), StkError::WARNING );
|
||||
return 0.0;
|
||||
}
|
||||
return phonemeGains[index][0];
|
||||
@@ -239,9 +237,8 @@ StkFloat Phonemes :: voiceGain( unsigned int index )
|
||||
StkFloat Phonemes :: noiseGain( unsigned int index )
|
||||
{
|
||||
if ( index > 31 ) {
|
||||
std::ostringstream error;
|
||||
error << "Phonemes::noiseGain: index is greater than 31!";
|
||||
handleError( error.str(), StkError::WARNING );
|
||||
oStream_ << "Phonemes::noiseGain: index is greater than 31!";
|
||||
handleError( oStream_.str(), StkError::WARNING );
|
||||
return 0.0;
|
||||
}
|
||||
return phonemeGains[index][1];
|
||||
@@ -249,15 +246,14 @@ StkFloat Phonemes :: noiseGain( unsigned int index )
|
||||
|
||||
StkFloat Phonemes :: formantFrequency( unsigned int index, unsigned int partial )
|
||||
{
|
||||
std::ostringstream error;
|
||||
if ( index > 31 ) {
|
||||
error << "Phonemes::formantFrequency: index is greater than 31!";
|
||||
handleError( error.str(), StkError::WARNING );
|
||||
oStream_ << "Phonemes::formantFrequency: index is greater than 31!";
|
||||
handleError( oStream_.str(), StkError::WARNING );
|
||||
return 0.0;
|
||||
}
|
||||
if ( partial > 3 ) {
|
||||
error << "Phonemes::formantFrequency: partial is greater than 3!";
|
||||
handleError( error.str(), StkError::WARNING );
|
||||
oStream_ << "Phonemes::formantFrequency: partial is greater than 3!";
|
||||
handleError( oStream_.str(), StkError::WARNING );
|
||||
return 0.0;
|
||||
}
|
||||
return phonemeParameters[index][partial][0];
|
||||
@@ -265,15 +261,14 @@ StkFloat Phonemes :: formantFrequency( unsigned int index, unsigned int partial
|
||||
|
||||
StkFloat Phonemes :: formantRadius( unsigned int index, unsigned int partial )
|
||||
{
|
||||
std::ostringstream error;
|
||||
if ( index > 31 ) {
|
||||
error << "Phonemes::formantRadius: index is greater than 31!";
|
||||
handleError( error.str(), StkError::WARNING );
|
||||
oStream_ << "Phonemes::formantRadius: index is greater than 31!";
|
||||
handleError( oStream_.str(), StkError::WARNING );
|
||||
return 0.0;
|
||||
}
|
||||
if ( partial > 3 ) {
|
||||
error << "Phonemes::formantRadius: partial is greater than 3!";
|
||||
handleError( error.str(), StkError::WARNING );
|
||||
oStream_ << "Phonemes::formantRadius: partial is greater than 3!";
|
||||
handleError( oStream_.str(), StkError::WARNING );
|
||||
return 0.0;
|
||||
}
|
||||
return phonemeParameters[index][partial][1];
|
||||
@@ -281,15 +276,14 @@ StkFloat Phonemes :: formantRadius( unsigned int index, unsigned int partial )
|
||||
|
||||
StkFloat Phonemes :: formantGain( unsigned int index, unsigned int partial )
|
||||
{
|
||||
std::ostringstream error;
|
||||
if ( index > 31 ) {
|
||||
error << "Phonemes::formantGain: index is greater than 31!";
|
||||
handleError( error.str(), StkError::WARNING );
|
||||
oStream_ << "Phonemes::formantGain: index is greater than 31!";
|
||||
handleError( oStream_.str(), StkError::WARNING );
|
||||
return 0.0;
|
||||
}
|
||||
if ( partial > 3 ) {
|
||||
error << "Phonemes::formantGain: partial is greater than 3!";
|
||||
handleError( error.str(), StkError::WARNING );
|
||||
oStream_ << "Phonemes::formantGain: partial is greater than 3!";
|
||||
handleError( oStream_.str(), StkError::WARNING );
|
||||
return 0.0;
|
||||
}
|
||||
return phonemeParameters[index][partial][2];
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -54,7 +54,7 @@ StkFrames& PitShift :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= frames.channels() ) {
|
||||
errorString_ << "PitShift::tick(): channel and StkFrames arguments are incompatible!";
|
||||
oStream_ << "PitShift::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
@@ -71,7 +71,7 @@ StkFrames& PitShift :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned in
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
|
||||
errorString_ << "PitShift::tick(): channel and StkFrames arguments are incompatible!";
|
||||
oStream_ << "PitShift::tick(): channel and StkFrames arguments are incompatible!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
132
src/PluckTwo.cpp
132
src/PluckTwo.cpp
@@ -1,132 +0,0 @@
|
||||
/***************************************************/
|
||||
/*! \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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "PluckTwo.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
PluckTwo :: PluckTwo( StkFloat lowestFrequency )
|
||||
{
|
||||
length_ = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
|
||||
lastLength_ = length_ * 0.5;
|
||||
delayLine_.setMaximumDelay( length_ );
|
||||
delayLine_.setDelay( lastLength_ );
|
||||
delayLine2_.setMaximumDelay( length_ );
|
||||
delayLine2_.setDelay( lastLength_ );
|
||||
combDelay_.setMaximumDelay( length_ );
|
||||
combDelay_.setDelay( lastLength_ );
|
||||
|
||||
baseLoopGain_ = 0.995;
|
||||
loopGain_ = 0.999;
|
||||
pluckAmplitude_ = 0.3;
|
||||
pluckPosition_ = 0.4;
|
||||
detuning_ = 0.995;
|
||||
lastFrequency_ = lowestFrequency * 2.0;
|
||||
}
|
||||
|
||||
PluckTwo :: ~PluckTwo( void )
|
||||
{
|
||||
}
|
||||
|
||||
void PluckTwo :: clear( void )
|
||||
{
|
||||
delayLine_.clear();
|
||||
delayLine2_.clear();
|
||||
combDelay_.clear();
|
||||
filter_.clear();
|
||||
filter2_.clear();
|
||||
}
|
||||
|
||||
void PluckTwo :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
lastFrequency_ = frequency;
|
||||
if ( lastFrequency_ <= 0.0 ) {
|
||||
errorString_ << "Clarinet::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
lastFrequency_ = 220.0;
|
||||
}
|
||||
|
||||
// Delay = length - approximate filter delay.
|
||||
lastLength_ = Stk::sampleRate() / lastFrequency_;
|
||||
StkFloat delay = (lastLength_ / detuning_) - 0.5;
|
||||
if ( delay <= 0.0 ) delay = 0.3;
|
||||
else if ( delay > length_ ) delay = length_;
|
||||
delayLine_.setDelay( delay );
|
||||
|
||||
delay = (lastLength_ * detuning_) - 0.5;
|
||||
if ( delay <= 0.0 ) delay = 0.3;
|
||||
else if ( delay > length_ ) delay = length_;
|
||||
delayLine2_.setDelay( delay );
|
||||
|
||||
loopGain_ = baseLoopGain_ + (frequency * 0.000005);
|
||||
if ( loopGain_ > 1.0 ) loopGain_ = 0.99999;
|
||||
}
|
||||
|
||||
void PluckTwo :: setDetune( StkFloat detune )
|
||||
{
|
||||
detuning_ = detune;
|
||||
if ( detuning_ <= 0.0 ) {
|
||||
errorString_ << "Clarinet::setDeturn: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
detuning_ = 0.1;
|
||||
}
|
||||
delayLine_.setDelay(( lastLength_ / detuning_) - 0.5);
|
||||
delayLine2_.setDelay( (lastLength_ * detuning_) - 0.5);
|
||||
}
|
||||
|
||||
void PluckTwo :: setFreqAndDetune( StkFloat frequency, StkFloat detune )
|
||||
{
|
||||
detuning_ = detune;
|
||||
this->setFrequency( frequency );
|
||||
}
|
||||
|
||||
void PluckTwo :: setPluckPosition( StkFloat position )
|
||||
{
|
||||
pluckPosition_ = position;
|
||||
if ( position < 0.0 ) {
|
||||
errorString_ << "PluckTwo::setPluckPosition: parameter is less than zero ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
pluckPosition_ = 0.0;
|
||||
}
|
||||
else if ( position > 1.0 ) {
|
||||
errorString_ << "PluckTwo::setPluckPosition: parameter is greater than one ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
pluckPosition_ = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
void PluckTwo :: setBaseLoopGain( StkFloat aGain )
|
||||
{
|
||||
baseLoopGain_ = aGain;
|
||||
loopGain_ = baseLoopGain_ + (lastFrequency_ * 0.000005);
|
||||
if ( loopGain_ > 0.99999 ) loopGain_ = 0.99999;
|
||||
}
|
||||
|
||||
void PluckTwo :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
loopGain_ = (1.0 - amplitude) * 0.5;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "PluckTwo::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
@@ -1,11 +1,14 @@
|
||||
/***************************************************/
|
||||
/*! \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.
|
||||
@@ -13,7 +16,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -23,11 +26,15 @@ namespace stk {
|
||||
|
||||
Plucked :: Plucked( StkFloat lowestFrequency )
|
||||
{
|
||||
length_ = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
|
||||
loopGain_ = 0.999;
|
||||
delayLine_.setMaximumDelay( length_ );
|
||||
delayLine_.setDelay( 0.5 * length_ );
|
||||
this->clear();
|
||||
if ( lowestFrequency <= 0.0 ) {
|
||||
oStream_ << "Plucked::Plucked: argument is less than or equal to zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
unsigned long delays = (unsigned long) ( Stk::sampleRate() / lowestFrequency );
|
||||
delayLine_.setMaximumDelay( delays + 1 );
|
||||
|
||||
this->setFrequency( 220.0 );
|
||||
}
|
||||
|
||||
Plucked :: ~Plucked( void )
|
||||
@@ -43,42 +50,31 @@ void Plucked :: clear( void )
|
||||
|
||||
void Plucked :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
StkFloat freakency = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "Plucked::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
freakency = 220.0;
|
||||
oStream_ << "Plucked::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Delay = length - approximate filter delay.
|
||||
StkFloat delay = (Stk::sampleRate() / freakency) - 0.5;
|
||||
if ( delay <= 0.0 )
|
||||
delay = 0.3;
|
||||
else if ( delay > length_ )
|
||||
delay = length_;
|
||||
// Delay = length - filter delay.
|
||||
StkFloat delay = ( Stk::sampleRate() / frequency ) - loopFilter_.phaseDelay( frequency );
|
||||
delayLine_.setDelay( delay );
|
||||
|
||||
loopGain_ = 0.995 + (freakency * 0.000005);
|
||||
loopGain_ = 0.995 + (frequency * 0.000005);
|
||||
if ( loopGain_ >= 1.0 ) loopGain_ = 0.99999;
|
||||
}
|
||||
|
||||
void Plucked :: pluck( StkFloat amplitude )
|
||||
{
|
||||
StkFloat gain = amplitude;
|
||||
if ( gain > 1.0 ) {
|
||||
errorString_ << "Plucked::pluck: amplitude is greater than 1.0 ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 1.0;
|
||||
}
|
||||
else if ( gain < 0.0 ) {
|
||||
errorString_ << "Plucked::pluck: amplitude is < 0.0 ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 0.0;
|
||||
if ( amplitude < 0.0 || amplitude > 1.0 ) {
|
||||
oStream_ << "Plucked::pluck: amplitude is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
pickFilter_.setPole( 0.999 - (gain * 0.15) );
|
||||
pickFilter_.setGain( gain * 0.5 );
|
||||
for (unsigned long i=0; i<length_; i++)
|
||||
pickFilter_.setPole( 0.999 - (amplitude * 0.15) );
|
||||
pickFilter_.setGain( amplitude * 0.5 );
|
||||
for ( unsigned long i=0; i<delayLine_.getDelay(); i++ )
|
||||
// Fill delay with noise additively with current contents.
|
||||
delayLine_.tick( 0.6 * delayLine_.lastOut() + pickFilter_.tick( noise_.tick() ) );
|
||||
}
|
||||
@@ -87,31 +83,16 @@ void Plucked :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
{
|
||||
this->setFrequency( frequency );
|
||||
this->pluck( amplitude );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Plucked::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Plucked :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
loopGain_ = 1.0 - amplitude;
|
||||
if ( loopGain_ < 0.0 ) {
|
||||
errorString_ << "Plucked::noteOff: amplitude is greater than 1.0 ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
loopGain_ = 0.0;
|
||||
}
|
||||
else if ( loopGain_ > 1.0 ) {
|
||||
errorString_ << "Plucked::noteOff: amplitude is < 0.0 ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
loopGain_ = (StkFloat) 0.99999;
|
||||
if ( amplitude < 0.0 || amplitude > 1.0 ) {
|
||||
oStream_ << "Plucked::noteOff: amplitude is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Plucked::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
loopGain_ = 1.0 - amplitude;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -32,6 +32,11 @@ PoleZero :: ~PoleZero()
|
||||
|
||||
void PoleZero :: setCoefficients( StkFloat b0, StkFloat b1, StkFloat a1, bool clearState )
|
||||
{
|
||||
if ( std::abs( a1 ) >= 1.0 ) {
|
||||
oStream_ << "PoleZero::setCoefficients: a1 argument (" << a1 << ") should be less than 1.0!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
b_[0] = b0;
|
||||
b_[1] = b1;
|
||||
a_[1] = a1;
|
||||
@@ -41,6 +46,11 @@ void PoleZero :: setCoefficients( StkFloat b0, StkFloat b1, StkFloat a1, bool cl
|
||||
|
||||
void PoleZero :: setAllpass( StkFloat coefficient )
|
||||
{
|
||||
if ( std::abs( coefficient ) >= 1.0 ) {
|
||||
oStream_ << "PoleZero::setAllpass: argument (" << coefficient << ") makes filter unstable!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
b_[0] = coefficient;
|
||||
b_[1] = 1.0;
|
||||
a_[0] = 1.0; // just in case
|
||||
@@ -49,6 +59,11 @@ void PoleZero :: setAllpass( StkFloat coefficient )
|
||||
|
||||
void PoleZero :: setBlockZero( StkFloat thePole )
|
||||
{
|
||||
if ( std::abs( thePole ) >= 1.0 ) {
|
||||
oStream_ << "PoleZero::setBlockZero: argument (" << thePole << ") makes filter unstable!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
b_[0] = 1.0;
|
||||
b_[1] = -1.0;
|
||||
a_[0] = 1.0; // just in case
|
||||
|
||||
102
src/Resonate.cpp
102
src/Resonate.cpp
@@ -13,7 +13,7 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -41,96 +41,72 @@ void Resonate :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
adsr_.setTarget( amplitude );
|
||||
this->keyOn();
|
||||
this->setResonance( frequency, poleRadius_ );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Resonate::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Resonate :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
this->keyOff();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Resonate::NoteOff: amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Resonate :: setResonance( StkFloat frequency, StkFloat radius )
|
||||
{
|
||||
poleFrequency_ = frequency;
|
||||
if ( frequency < 0.0 ) {
|
||||
errorString_ << "Resonate::setResonance: frequency parameter is less than zero ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
poleFrequency_ = 0.0;
|
||||
oStream_ << "Resonate::setResonance: frequency parameter is less than zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
if ( radius < 0.0 || radius >= 1.0 ) {
|
||||
std::cerr << "Resonate::setResonance: radius parameter is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
poleFrequency_ = frequency;
|
||||
poleRadius_ = radius;
|
||||
if ( radius < 0.0 ) {
|
||||
std::cerr << "Resonate::setResonance: radius parameter is less than 0.0 ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
poleRadius_ = 0.0;
|
||||
}
|
||||
else if ( radius >= 1.0 ) {
|
||||
errorString_ << "Resonate::setResonance: radius parameter is greater than or equal to 1.0, which is unstable ... correcting!";
|
||||
handleError( StkError::WARNING );
|
||||
poleRadius_ = 0.9999;
|
||||
}
|
||||
filter_.setResonance( poleFrequency_, poleRadius_, true );
|
||||
}
|
||||
|
||||
void Resonate :: setNotch( StkFloat frequency, StkFloat radius )
|
||||
{
|
||||
zeroFrequency_ = frequency;
|
||||
if ( frequency < 0.0 ) {
|
||||
errorString_ << "Resonate::setNotch: frequency parameter is less than zero ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
zeroFrequency_ = 0.0;
|
||||
oStream_ << "Resonate::setNotch: frequency parameter is less than zero ... setting to 0.0!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
zeroRadius_ = radius;
|
||||
if ( radius < 0.0 ) {
|
||||
errorString_ << "Resonate::setNotch: radius parameter is less than 0.0 ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
zeroRadius_ = 0.0;
|
||||
oStream_ << "Resonate::setNotch: radius parameter is less than 0.0!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
|
||||
zeroFrequency_ = frequency;
|
||||
zeroRadius_ = radius;
|
||||
filter_.setNotch( zeroFrequency_, zeroRadius_ );
|
||||
}
|
||||
|
||||
void Resonate :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "Resonate::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "Resonate::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
if (number == 2) // 2
|
||||
setResonance( norm * Stk::sampleRate() * 0.5, poleRadius_ );
|
||||
else if (number == 4) // 4
|
||||
setResonance( poleFrequency_, norm*0.9999 );
|
||||
else if (number == 11) // 11
|
||||
this->setNotch( norm * Stk::sampleRate() * 0.5, zeroRadius_ );
|
||||
else if (number == 1)
|
||||
this->setNotch( zeroFrequency_, norm );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
adsr_.setTarget( norm );
|
||||
else {
|
||||
errorString_ << "Resonate::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Resonate::controlChange: number = " << number << ", value = " << value << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Resonate::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == 2) // 2
|
||||
setResonance( normalizedValue * Stk::sampleRate() * 0.5, poleRadius_ );
|
||||
else if (number == 4) // 4
|
||||
setResonance( poleFrequency_, normalizedValue * 0.9999 );
|
||||
else if (number == 11) // 11
|
||||
this->setNotch( normalizedValue * Stk::sampleRate() * 0.5, zeroRadius_ );
|
||||
else if (number == 1)
|
||||
this->setNotch( zeroFrequency_, normalizedValue );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
adsr_.setTarget( normalizedValue );
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
oStream_ << "Resonate::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -66,6 +66,13 @@ Rhodey :: ~Rhodey( void )
|
||||
|
||||
void Rhodey :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "Rhodey::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
baseFrequency_ = frequency * 2.0;
|
||||
|
||||
for (unsigned int i=0; i<nOperators_; i++ )
|
||||
@@ -80,11 +87,6 @@ void Rhodey :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
gains_[3] = amplitude * fmGains_[67];
|
||||
this->setFrequency( frequency );
|
||||
this->keyOn();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Rhodey::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
15891
src/RtAudio.cpp
15891
src/RtAudio.cpp
File diff suppressed because it is too large
Load Diff
825
src/RtMidi.cpp
825
src/RtMidi.cpp
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -65,7 +65,7 @@ void RtWvIn :: fillBuffer( void *buffer, unsigned int nFrames )
|
||||
mutex_.unlock();
|
||||
if ( framesFilled_ > data_.frames() ) {
|
||||
framesFilled_ = data_.frames();
|
||||
errorString_ << "RtWvIn: audio buffer overrun!";
|
||||
oStream_ << "RtWvIn: audio buffer overrun!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
}
|
||||
@@ -121,7 +121,7 @@ StkFloat RtWvIn :: tick( unsigned int channel )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( channel >= data_.channels() ) {
|
||||
errorString_ << "RtWvIn::tick(): channel argument is incompatible with streamed channels!";
|
||||
oStream_ << "RtWvIn::tick(): channel argument is incompatible with streamed channels!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
@@ -150,7 +150,7 @@ StkFrames& RtWvIn :: tick( StkFrames& frames )
|
||||
unsigned int nChannels = lastFrame_.channels();
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( nChannels != frames.channels() ) {
|
||||
errorString_ << "RtWvIn::tick(): StkFrames argument is incompatible with adc channels!";
|
||||
oStream_ << "RtWvIn::tick(): StkFrames argument is incompatible with adc channels!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -82,7 +82,7 @@ int RtWvOut :: readBuffer( void *buffer, unsigned int frameCount )
|
||||
if ( framesFilled_ < 0 ) {
|
||||
framesFilled_ = 0;
|
||||
// writeIndex_ = readIndex_;
|
||||
errorString_ << "RtWvOut: audio buffer underrun!";
|
||||
oStream_ << "RtWvOut: audio buffer underrun!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ void RtWvOut :: tick( const StkFrames& frames )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( data_.channels() != frames.channels() ) {
|
||||
errorString_ << "RtWvOut::tick(): incompatible channel value in StkFrames argument!";
|
||||
oStream_ << "RtWvOut::tick(): incompatible channel value in StkFrames argument!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -48,11 +48,6 @@ void Sampler :: keyOff( void )
|
||||
void Sampler :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
this->keyOff();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Sampler::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
116
src/Saxofony.cpp
116
src/Saxofony.cpp
@@ -31,7 +31,7 @@
|
||||
- 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,22 +42,29 @@ namespace stk {
|
||||
|
||||
Saxofony :: Saxofony( StkFloat lowestFrequency )
|
||||
{
|
||||
length_ = (unsigned long) (Stk::sampleRate() / lowestFrequency + 1);
|
||||
// Initialize blowing position to 0.2 of length / 2.
|
||||
if ( lowestFrequency <= 0.0 ) {
|
||||
oStream_ << "Saxofony::Saxofony: argument is less than or equal to zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
unsigned long nDelays = (unsigned long) ( Stk::sampleRate() / lowestFrequency );
|
||||
delays_[0].setMaximumDelay( nDelays + 1 );
|
||||
delays_[1].setMaximumDelay( nDelays + 1 );
|
||||
|
||||
// Initialize blowing position to 0.2 of length.
|
||||
position_ = 0.2;
|
||||
delays_[0].setMaximumDelay( length_ );
|
||||
delays_[0].setDelay( (1.0-position_) * (length_ >> 1) );
|
||||
delays_[1].setMaximumDelay( length_ );
|
||||
delays_[1].setDelay( (1.0-position_) * (length_ >> 1) );
|
||||
|
||||
reedTable_.setOffset( 0.7 );
|
||||
reedTable_.setSlope( 0.3 );
|
||||
|
||||
vibrato_.setFrequency((StkFloat) 5.735);
|
||||
vibrato_.setFrequency( 5.735 );
|
||||
|
||||
outputGain_ = 0.3;
|
||||
noiseGain_ = 0.2;
|
||||
vibratoGain_ = 0.1;
|
||||
|
||||
this->setFrequency( 220.0 );
|
||||
this->clear();
|
||||
}
|
||||
|
||||
Saxofony :: ~Saxofony( void )
|
||||
@@ -73,17 +80,15 @@ void Saxofony :: clear( void )
|
||||
|
||||
void Saxofony :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
StkFloat freakency = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "Saxofony::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
freakency = 220.0;
|
||||
oStream_ << "Saxofony::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat delay = (Stk::sampleRate() / freakency) - (StkFloat) 3.0;
|
||||
if (delay <= 0.0) delay = 0.3;
|
||||
else if (delay > length_) delay = length_;
|
||||
|
||||
// Account for filter delay and one sample "lastOut" delay.
|
||||
StkFloat delay = ( Stk::sampleRate() / frequency ) - filter_.phaseDelay( frequency ) - 1.0;
|
||||
delays_[0].setDelay( (1.0-position_) * delay );
|
||||
delays_[1].setDelay( position_ * delay );
|
||||
}
|
||||
@@ -105,12 +110,22 @@ void Saxofony :: setBlowPosition( StkFloat position )
|
||||
|
||||
void Saxofony :: startBlowing( StkFloat amplitude, StkFloat rate )
|
||||
{
|
||||
if ( amplitude <= 0.0 || rate <= 0.0 ) {
|
||||
oStream_ << "Saxofony::startBlowing: one or more arguments is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
envelope_.setRate( rate );
|
||||
envelope_.setTarget( amplitude );
|
||||
}
|
||||
|
||||
void Saxofony :: stopBlowing( StkFloat rate )
|
||||
{
|
||||
if ( rate <= 0.0 ) {
|
||||
oStream_ << "Saxofony::stopBlowing: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
envelope_.setRate( rate );
|
||||
envelope_.setTarget( 0.0 );
|
||||
}
|
||||
@@ -120,59 +135,42 @@ void Saxofony :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
this->setFrequency( frequency );
|
||||
this->startBlowing( 0.55 + (amplitude * 0.30), amplitude * 0.005 );
|
||||
outputGain_ = amplitude + 0.001;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Saxofony::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Saxofony :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
this->stopBlowing( amplitude * 0.01 );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Saxofony::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Saxofony :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "Saxofony::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "Saxofony::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
if (number == __SK_ReedStiffness_) // 2
|
||||
reedTable_.setSlope( 0.1 + (0.4 * norm) );
|
||||
else if (number == __SK_NoiseLevel_) // 4
|
||||
noiseGain_ = ( norm * 0.4 );
|
||||
else if (number == 29) // 29
|
||||
vibrato_.setFrequency( norm * 12.0 );
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
vibratoGain_ = ( norm * 0.5 );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
envelope_.setValue( norm );
|
||||
else if (number == 11) // 11
|
||||
this->setBlowPosition( norm );
|
||||
else if (number == 26) // reed table offset
|
||||
reedTable_.setOffset(0.4 + ( norm * 0.6));
|
||||
else {
|
||||
errorString_ << "Saxofony::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Saxofony::controlChange: number = " << number << ", value = " << value << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Saxofony::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_ReedStiffness_) // 2
|
||||
reedTable_.setSlope( 0.1 + (0.4 * normalizedValue) );
|
||||
else if (number == __SK_NoiseLevel_) // 4
|
||||
noiseGain_ = ( normalizedValue * 0.4 );
|
||||
else if (number == 29) // 29
|
||||
vibrato_.setFrequency( normalizedValue * 12.0 );
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
vibratoGain_ = ( normalizedValue * 0.5 );
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
envelope_.setValue( normalizedValue );
|
||||
else if (number == 11) // 11
|
||||
this->setBlowPosition( normalizedValue );
|
||||
else if (number == 26) // reed table offset
|
||||
reedTable_.setOffset(0.4 + ( normalizedValue * 0.6));
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
oStream_ << "Saxofony::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
- Little Rocks = 21
|
||||
- Tuned Bamboo Chimes = 22
|
||||
|
||||
by Perry R. Cook, 1996 - 2010.
|
||||
by Perry R. Cook, 1995-2011.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -337,17 +337,12 @@ int Shakers :: setupName( char* instr )
|
||||
{
|
||||
int which = 0;
|
||||
|
||||
for (int i=0;i<NUM_INSTR;i++) {
|
||||
for ( int i=0; i<NUM_INSTR; i++ ) {
|
||||
if ( !strcmp(instr,instrs[i]) )
|
||||
which = i;
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Shakers::setupName: setting instrument to " << instrs[which] << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
|
||||
return this->setupNum(which);
|
||||
return this->setupNum( which );
|
||||
}
|
||||
|
||||
void Shakers :: setFinalZs( StkFloat z0, StkFloat z1, StkFloat z2 )
|
||||
@@ -800,14 +795,10 @@ void Shakers :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
// Yep ... pretty kludgey, but it works!
|
||||
int noteNum = (int) ((12*log(frequency/220.0)/log(2.0)) + 57.01) % 32;
|
||||
if (instType_ != noteNum) instType_ = this->setupNum(noteNum);
|
||||
|
||||
shakeEnergy_ += amplitude * MAX_SHAKE * 0.1;
|
||||
if (shakeEnergy_ > MAX_SHAKE) shakeEnergy_ = MAX_SHAKE;
|
||||
if (instType_==10 || instType_==3) ratchetPos_ += 1;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Shakers::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Shakers :: noteOff( StkFloat amplitude )
|
||||
@@ -891,23 +882,18 @@ StkFloat Shakers :: tick( unsigned int )
|
||||
|
||||
void Shakers :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "Shakers::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "Shakers::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Shakers::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat temp;
|
||||
int i;
|
||||
|
||||
StkFloat temp;
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_Breath_) { // 2 ... energy
|
||||
shakeEnergy_ += norm * MAX_SHAKE * 0.1;
|
||||
shakeEnergy_ += normalizedValue * MAX_SHAKE * 0.1;
|
||||
if (shakeEnergy_ > MAX_SHAKE) shakeEnergy_ = MAX_SHAKE;
|
||||
if (instType_==10 || instType_==3) {
|
||||
ratchetPos_ = (int) fabs(value - lastRatchetPos_);
|
||||
@@ -974,7 +960,7 @@ void Shakers :: controlChange( int number, StkFloat value )
|
||||
}
|
||||
}
|
||||
else if (number == __SK_AfterTouch_Cont_) { // 128
|
||||
shakeEnergy_ += norm * MAX_SHAKE * 0.1;
|
||||
shakeEnergy_ += normalizedValue * MAX_SHAKE * 0.1;
|
||||
if (shakeEnergy_ > MAX_SHAKE) shakeEnergy_ = MAX_SHAKE;
|
||||
if (instType_==10 || instType_==3) {
|
||||
ratchetPos_ = (int) fabs(value - lastRatchetPos_);
|
||||
@@ -985,15 +971,12 @@ void Shakers :: controlChange( int number, StkFloat value )
|
||||
else if (number == __SK_ShakerInst_) { // 1071
|
||||
instType_ = (int) (value + 0.5); // Just to be safe
|
||||
this->setupNum(instType_);
|
||||
}
|
||||
}
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
errorString_ << "Shakers::controlChange: undefined control number (" << number << ")!";
|
||||
oStream_ << "Shakers::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Shakers::controlChange: number = " << number << ", value = " << value << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -53,62 +53,52 @@ void Simple :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
this->keyOn();
|
||||
this->setFrequency( frequency );
|
||||
filter_.setGain( amplitude );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Simple::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
void Simple :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
this->keyOff();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Simple::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Simple :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "Simple::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
biquad_.setResonance( frequency, 0.98, true );
|
||||
loop_->setFrequency( frequency );
|
||||
}
|
||||
|
||||
void Simple :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "Simple::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "Simple::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Simple::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_Breath_) // 2
|
||||
filter_.setPole( 0.99 * (1.0 - (norm * 2.0)) );
|
||||
filter_.setPole( 0.99 * (1.0 - (normalizedValue * 2.0)) );
|
||||
else if (number == __SK_NoiseLevel_) // 4
|
||||
loopGain_ = norm;
|
||||
loopGain_ = normalizedValue;
|
||||
else if (number == __SK_ModFrequency_) { // 11
|
||||
norm /= 0.2 * Stk::sampleRate();
|
||||
adsr_.setAttackRate( norm );
|
||||
adsr_.setDecayRate( norm );
|
||||
adsr_.setReleaseRate( norm );
|
||||
normalizedValue /= 0.2 * Stk::sampleRate();
|
||||
adsr_.setAttackRate( normalizedValue );
|
||||
adsr_.setDecayRate( normalizedValue );
|
||||
adsr_.setReleaseRate( normalizedValue );
|
||||
}
|
||||
else if (number == __SK_AfterTouch_Cont_) // 128
|
||||
adsr_.setTarget( norm );
|
||||
adsr_.setTarget( normalizedValue );
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
errorString_ << "Simple::controlChange: undefined control number (" << number << ")!";
|
||||
oStream_ << "Simple::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Simple::controlChange: number = " << number << ", value = " << value << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
The "table" length, set in SineWave.h, is 2048 samples by default.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995-2011.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -23,16 +23,21 @@ namespace stk {
|
||||
|
||||
Sitar :: Sitar( StkFloat lowestFrequency )
|
||||
{
|
||||
if ( lowestFrequency <= 0.0 ) {
|
||||
oStream_ << "Sitar::Sitar: argument is less than or equal to zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
unsigned long length = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
|
||||
delayLine_.setMaximumDelay( length );
|
||||
delay_ = 0.5 * length;
|
||||
delayLine_.setDelay( delay_ );
|
||||
targetDelay_ = delay_;
|
||||
|
||||
loopFilter_.setZero(0.01);
|
||||
loopFilter_.setZero( 0.01 );
|
||||
loopGain_ = 0.999;
|
||||
|
||||
envelope_.setAllTimes(0.001, 0.04, 0.0, 0.5);
|
||||
envelope_.setAllTimes( 0.001, 0.04, 0.0, 0.5 );
|
||||
this->clear();
|
||||
}
|
||||
|
||||
@@ -48,17 +53,17 @@ void Sitar :: clear( void )
|
||||
|
||||
void Sitar :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
StkFloat freakency = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "Sitar::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
freakency = 220.0;
|
||||
oStream_ << "Sitar::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
targetDelay_ = (Stk::sampleRate() / freakency);
|
||||
targetDelay_ = (Stk::sampleRate() / frequency);
|
||||
delay_ = targetDelay_ * (1.0 + (0.05 * noise_.tick()));
|
||||
delayLine_.setDelay( delay_ );
|
||||
loopGain_ = 0.995 + (freakency * 0.0000005);
|
||||
loopGain_ = 0.995 + (frequency * 0.0000005);
|
||||
if ( loopGain_ > 0.9995 ) loopGain_ = 0.9995;
|
||||
}
|
||||
|
||||
@@ -72,31 +77,16 @@ void Sitar :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
this->setFrequency( frequency );
|
||||
this->pluck( amplitude );
|
||||
amGain_ = 0.1 * amplitude;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Sitar::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Sitar :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
loopGain_ = (StkFloat) 1.0 - amplitude;
|
||||
if ( loopGain_ < 0.0 ) {
|
||||
errorString_ << "Sitar::noteOff: amplitude is greater than 1.0 ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
loopGain_ = 0.0;
|
||||
}
|
||||
else if ( loopGain_ > 1.0 ) {
|
||||
errorString_ << "Sitar::noteOff: amplitude is < 0.0 ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
loopGain_ = 0.99999;
|
||||
if ( amplitude < 0.0 || amplitude > 1.0 ) {
|
||||
oStream_ << "Sitar::noteOff: amplitude is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Sitar::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
loopGain_ = (StkFloat) 1.0 - amplitude;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
|
||||
See also SKINI.txt.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995-2011.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "Skini.h"
|
||||
#include "SKINI.tbl"
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
||||
namespace stk {
|
||||
|
||||
@@ -40,14 +41,14 @@ Skini :: ~Skini()
|
||||
bool Skini :: setFile( std::string fileName )
|
||||
{
|
||||
if ( file_.is_open() ) {
|
||||
errorString_ << "Skini::setFile: already reaading a file!";
|
||||
oStream_ << "Skini::setFile: already reaading a file!";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
|
||||
file_.open( fileName.c_str() );
|
||||
if ( !file_ ) {
|
||||
errorString_ << "Skini::setFile: unable to open file (" << fileName << ")";
|
||||
oStream_ << "Skini::setFile: unable to open file (" << fileName << ")";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
@@ -65,7 +66,7 @@ long Skini :: nextMessage( Message& message )
|
||||
|
||||
// Read a line from the file and skip over invalid messages.
|
||||
if ( std::getline( file_, line ).eof() ) {
|
||||
errorString_ << "// End of Score. Thanks for using SKINI!!";
|
||||
oStream_ << "// End of Score. Thanks for using SKINI!!";
|
||||
handleError( StkError::STATUS );
|
||||
file_.close();
|
||||
message.type = 0;
|
||||
@@ -105,7 +106,7 @@ long Skini :: parseString( std::string& line, Message& message )
|
||||
std::string::size_type lastPos = line.find_first_not_of(" ,\t", 0);
|
||||
std::string::size_type pos = line.find_first_of("/", lastPos);
|
||||
if ( std::string::npos != pos ) {
|
||||
errorString_ << "// Comment Line: " << line;
|
||||
oStream_ << "// Comment Line: " << line;
|
||||
handleError( StkError::STATUS );
|
||||
return message.type;
|
||||
}
|
||||
@@ -126,7 +127,7 @@ long Skini :: parseString( std::string& line, Message& message )
|
||||
}
|
||||
|
||||
if ( iSkini >= __SK_MaxMsgTypes_ ) {
|
||||
errorString_ << "Skini::parseString: couldn't parse this line:\n " << line;
|
||||
oStream_ << "Skini::parseString: couldn't parse this line:\n " << line;
|
||||
handleError( StkError::WARNING );
|
||||
return message.type;
|
||||
}
|
||||
@@ -138,7 +139,7 @@ long Skini :: parseString( std::string& line, Message& message )
|
||||
if ( tokens[1][0] == '=' ) {
|
||||
tokens[1].erase( tokens[1].begin() );
|
||||
if ( tokens[1].empty() ) {
|
||||
errorString_ << "Skini::parseString: couldn't parse time field in line:\n " << line;
|
||||
oStream_ << "Skini::parseString: couldn't parse time field in line:\n " << line;
|
||||
handleError( StkError::WARNING );
|
||||
return message.type = 0;
|
||||
}
|
||||
@@ -156,7 +157,7 @@ long Skini :: parseString( std::string& line, Message& message )
|
||||
while ( dataType != NOPE ) {
|
||||
|
||||
if ( tokens.size() <= (unsigned int) (iValue+3) ) {
|
||||
errorString_ << "Skini::parseString: inconsistency between type table and parsed line:\n " << line;
|
||||
oStream_ << "Skini::parseString: inconsistency between type table and parsed line:\n " << line;
|
||||
handleError( StkError::WARNING );
|
||||
return message.type = 0;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
This class provides common functionality for TCP and UDP internet
|
||||
socket server and client subclasses.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2010.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995-2011.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
|
||||
133
src/StifKarp.cpp
133
src/StifKarp.cpp
@@ -17,7 +17,7 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -29,21 +29,24 @@ namespace stk {
|
||||
|
||||
StifKarp :: StifKarp( StkFloat lowestFrequency )
|
||||
{
|
||||
length_ = (unsigned long) ( Stk::sampleRate() / lowestFrequency + 1 );
|
||||
delayLine_.setMaximumDelay( length_ );
|
||||
delayLine_.setDelay( 0.5 * length_ );
|
||||
combDelay_.setMaximumDelay( length_ );
|
||||
combDelay_.setDelay( 0.2 * length_ );
|
||||
if ( lowestFrequency <= 0.0 ) {
|
||||
oStream_ << "StifKarp::StifKarp: argument is less than or equal to zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
unsigned long nDelays = (unsigned long) ( Stk::sampleRate() / lowestFrequency );
|
||||
delayLine_.setMaximumDelay( nDelays + 1 );
|
||||
combDelay_.setMaximumDelay( nDelays + 1 );
|
||||
|
||||
pluckAmplitude_ = 0.3;
|
||||
pickupPosition_ = 0.4;
|
||||
lastFrequency_ = lowestFrequency * 2.0;
|
||||
lastLength_ = length_ * 0.5;
|
||||
|
||||
stretching_ = 0.9999;
|
||||
baseLoopGain_ = 0.995;
|
||||
loopGain_ = 0.999;
|
||||
|
||||
this->clear();
|
||||
this->setFrequency( 220.0 );
|
||||
}
|
||||
|
||||
StifKarp :: ~StifKarp( void )
|
||||
@@ -59,19 +62,16 @@ void StifKarp :: clear( void )
|
||||
|
||||
void StifKarp :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
lastFrequency_ = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "StifKarp::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
lastFrequency_ = 220.0;
|
||||
oStream_ << "StifKarp::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
lastFrequency_ = frequency;
|
||||
lastLength_ = Stk::sampleRate() / lastFrequency_;
|
||||
StkFloat delay = lastLength_ - 0.5;
|
||||
if (delay <= 0.0)
|
||||
delay = 0.3;
|
||||
else if (delay > length_)
|
||||
delay = length_;
|
||||
delayLine_.setDelay( delay );
|
||||
|
||||
loopGain_ = baseLoopGain_ + (frequency * 0.000005);
|
||||
@@ -89,8 +89,8 @@ void StifKarp :: setStretch( StkFloat stretch )
|
||||
StkFloat freq = lastFrequency_ * 2.0;
|
||||
StkFloat dFreq = ( (0.5 * Stk::sampleRate()) - freq ) * 0.25;
|
||||
StkFloat temp = 0.5 + (stretch * 0.5);
|
||||
if (temp > 0.9999) temp = 0.9999;
|
||||
for (int i=0; i<4; i++) {
|
||||
if ( temp > 0.9999 ) temp = 0.9999;
|
||||
for ( int i=0; i<4; i++ ) {
|
||||
coefficient = temp * temp;
|
||||
biquad_[i].setA2( coefficient );
|
||||
biquad_[i].setB0( coefficient );
|
||||
@@ -105,19 +105,14 @@ void StifKarp :: setStretch( StkFloat stretch )
|
||||
}
|
||||
|
||||
void StifKarp :: setPickupPosition( StkFloat position ) {
|
||||
pickupPosition_ = position;
|
||||
if ( position < 0.0 ) {
|
||||
errorString_ << "StifKarp::setPickupPosition: parameter is less than zero ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
pickupPosition_ = 0.0;
|
||||
}
|
||||
else if ( position > 1.0 ) {
|
||||
errorString_ << "StifKarp::setPickupPosition: parameter is greater than 1.0 ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
pickupPosition_ = 1.0;
|
||||
|
||||
if ( position < 0.0 || position > 1.0 ) {
|
||||
oStream_ << "StifKarp::setPickupPosition: parameter is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
// Set the pick position, which puts zeroes at position * length.
|
||||
pickupPosition_ = position;
|
||||
combDelay_.setDelay( 0.5 * pickupPosition_ * lastLength_ );
|
||||
}
|
||||
|
||||
@@ -130,20 +125,13 @@ void StifKarp :: setBaseLoopGain( StkFloat aGain )
|
||||
|
||||
void StifKarp :: pluck( StkFloat amplitude )
|
||||
{
|
||||
StkFloat gain = amplitude;
|
||||
if ( gain > 1.0 ) {
|
||||
errorString_ << "StifKarp::pluck: amplitude is greater than 1.0 ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 1.0;
|
||||
}
|
||||
else if ( gain < 0.0 ) {
|
||||
errorString_ << "StifKarp::pluck: amplitude is less than zero ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 0.0;
|
||||
if ( amplitude < 0.0 || amplitude > 1.0 ) {
|
||||
oStream_ << "StifKarp::pluck: amplitude is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
pluckAmplitude_ = amplitude;
|
||||
for (unsigned long i=0; i<length_; i++) {
|
||||
for ( unsigned long i=0; i<length_; i++ ) {
|
||||
// Fill delay with noise additively with current contents.
|
||||
delayLine_.tick( (delayLine_.lastOut() * 0.6) + 0.4 * noise_.tick() * pluckAmplitude_ );
|
||||
//delayLine_.tick( combDelay_.tick((delayLine_.lastOut() * 0.6) + 0.4 * noise->tick() * pluckAmplitude_) );
|
||||
@@ -154,62 +142,39 @@ void StifKarp :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
{
|
||||
this->setFrequency( frequency );
|
||||
this->pluck( amplitude );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "StifKarp::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void StifKarp :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
StkFloat gain = amplitude;
|
||||
if ( gain > 1.0 ) {
|
||||
errorString_ << "StifKarp::noteOff: amplitude is greater than 1.0 ... setting to 1.0!";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 1.0;
|
||||
if ( amplitude < 0.0 || amplitude > 1.0 ) {
|
||||
oStream_ << "StifKarp::noteOff: amplitude is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
else if ( gain < 0.0 ) {
|
||||
errorString_ << "StifKarp::noteOff: amplitude is < 0.0 ... setting to 0.0!";
|
||||
handleError( StkError::WARNING );
|
||||
gain = 0.0;
|
||||
}
|
||||
loopGain_ = (1.0 - gain) * 0.5;
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "StifKarp::NoteOff: amplitude = " << amplitude << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
loopGain_ = (1.0 - amplitude) * 0.5;
|
||||
}
|
||||
|
||||
void StifKarp :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "StifKarp::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "StifKarp::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
if (number == __SK_PickPosition_) // 4
|
||||
this->setPickupPosition( norm );
|
||||
else if (number == __SK_StringDamping_) // 11
|
||||
this->setBaseLoopGain( 0.97 + (norm * 0.03) );
|
||||
else if (number == __SK_StringDetune_) // 1
|
||||
this->setStretch( 0.9 + (0.1 * (1.0 - norm)) );
|
||||
else {
|
||||
errorString_ << "StifKarp::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "StifKarp::controlChange: number = " << number << ", value = " << value << ".";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Clarinet::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_PickPosition_) // 4
|
||||
this->setPickupPosition( normalizedValue );
|
||||
else if (number == __SK_StringDamping_) // 11
|
||||
this->setBaseLoopGain( 0.97 + (normalizedValue * 0.03) );
|
||||
else if (number == __SK_StringDetune_) // 1
|
||||
this->setStretch( 0.9 + (0.1 * (1.0 - normalizedValue)) );
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
oStream_ << "StifKarp::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
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
|
||||
@@ -65,6 +65,7 @@ const Stk::StkFormat Stk :: STK_FLOAT64 = 0x20;
|
||||
bool Stk :: showWarnings_ = true;
|
||||
bool Stk :: printErrors_ = true;
|
||||
std::vector<Stk *> Stk :: alertList_;
|
||||
std::ostringstream Stk :: oStream_;
|
||||
|
||||
Stk :: Stk( void )
|
||||
: ignoreSampleRateChange_(false)
|
||||
@@ -192,8 +193,8 @@ void Stk :: sleep(unsigned long milliseconds)
|
||||
|
||||
void Stk :: handleError( StkError::Type type )
|
||||
{
|
||||
handleError( errorString_.str(), type );
|
||||
errorString_.str( std::string() ); // reset the ostringstream buffer
|
||||
handleError( oStream_.str(), type );
|
||||
oStream_.str( std::string() ); // reset the ostringstream buffer
|
||||
}
|
||||
|
||||
void Stk :: handleError( const char *message, StkError::Type type )
|
||||
@@ -208,7 +209,7 @@ void Stk :: handleError( std::string message, StkError::Type type )
|
||||
if ( !showWarnings_ ) return;
|
||||
std::cerr << '\n' << message << '\n' << std::endl;
|
||||
}
|
||||
else if (type == StkError::DEBUG_WARNING) {
|
||||
else if (type == StkError::DEBUG_PRINT) {
|
||||
#if defined(_STK_DEBUG_)
|
||||
std::cerr << '\n' << message << '\n' << std::endl;
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -24,13 +24,13 @@ TapDelay :: TapDelay( std::vector<unsigned long> taps, unsigned long maxDelay )
|
||||
// If we want to allow a delay of maxDelay, we need a
|
||||
// delayline of length = maxDelay+1.
|
||||
if ( maxDelay < 1 ) {
|
||||
errorString_ << "TapDelay::TapDelay: maxDelay must be > 0!\n";
|
||||
oStream_ << "TapDelay::TapDelay: maxDelay must be > 0!\n";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
for ( unsigned int i=0; i<taps.size(); i++ ) {
|
||||
if ( taps[i] > maxDelay ) {
|
||||
errorString_ << "TapDelay::TapDelay: maxDelay must be > than all tap delay values!\n";
|
||||
oStream_ << "TapDelay::TapDelay: maxDelay must be > than all tap delay values!\n";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
}
|
||||
@@ -50,17 +50,10 @@ void TapDelay :: setMaximumDelay( unsigned long delay )
|
||||
{
|
||||
if ( delay < inputs_.size() ) return;
|
||||
|
||||
if ( delay < 0 ) {
|
||||
errorString_ << "TapDelay::setMaximumDelay: argument (" << delay << ") less than zero!\n";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
}
|
||||
|
||||
for ( unsigned int i=0; i<delays_.size(); i++ ) {
|
||||
if ( delay < delays_[i] ) {
|
||||
errorString_ << "TapDelay::setMaximumDelay: argument (" << delay << ") less than a current tap delay setting (" << delays_[i] << ")!\n";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
oStream_ << "TapDelay::setMaximumDelay: argument (" << delay << ") less than a current tap delay setting (" << delays_[i] << ")!\n";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +62,18 @@ void TapDelay :: setMaximumDelay( unsigned long delay )
|
||||
|
||||
void TapDelay :: setTapDelays( std::vector<unsigned long> taps )
|
||||
{
|
||||
for ( unsigned int i=0; i<taps.size(); i++ ) {
|
||||
if ( taps[i] > inputs_.size() - 1 ) { // The value is too big.
|
||||
oStream_ << "TapDelay::setTapDelay: argument (" << taps[i] << ") greater than maximum!\n";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
if ( taps[i] < 0 ) {
|
||||
error << "TapDelay::setDelay: argument (" << taps[i] << ") less than zero!\n";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( taps.size() != outPoint_.size() ) {
|
||||
outPoint_.resize( taps.size() );
|
||||
delays_.resize( taps.size() );
|
||||
@@ -76,27 +81,10 @@ void TapDelay :: setTapDelays( std::vector<unsigned long> taps )
|
||||
}
|
||||
|
||||
for ( unsigned int i=0; i<taps.size(); i++ ) {
|
||||
if ( taps[i] > inputs_.size() - 1 ) { // The value is too big.
|
||||
errorString_ << "TapDelay::setTapDelay: argument (" << taps[i] << ") too big ... setting to maximum!\n";
|
||||
handleError( StkError::WARNING );
|
||||
|
||||
// Force delay to maximum length.
|
||||
outPoint_[i] = inPoint_ + 1;
|
||||
if ( outPoint_[i] == inputs_.size() ) outPoint_[i] = 0;
|
||||
delays_[i] = inputs_.size() - 1;
|
||||
}
|
||||
else if ( taps[i] < 0 ) {
|
||||
errorString_ << "TapDelay::setDelay: argument (" << taps[i] << ") less than zero ... setting to zero!\n";
|
||||
handleError( StkError::WARNING );
|
||||
|
||||
outPoint_[i] = inPoint_;
|
||||
delays_[i] = 0;
|
||||
}
|
||||
else { // read chases write
|
||||
if ( inPoint_ >= taps[i] ) outPoint_[i] = inPoint_ - taps[i];
|
||||
else outPoint_[i] = inputs_.size() + inPoint_ - taps[i];
|
||||
delays_[i] = taps[i];
|
||||
}
|
||||
// read chases write
|
||||
if ( inPoint_ >= taps[i] ) outPoint_[i] = inPoint_ - taps[i];
|
||||
else outPoint_[i] = inputs_.size() + inPoint_ - taps[i];
|
||||
delays_[i] = taps[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,12 +19,13 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "TcpClient.h"
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
||||
namespace stk {
|
||||
|
||||
@@ -36,7 +37,7 @@ TcpClient :: TcpClient( int port, std::string hostname )
|
||||
|
||||
WSAStartup( wVersionRequested, &wsaData );
|
||||
if ( wsaData.wVersion != wVersionRequested ) {
|
||||
errorString_ << "TcpClient: Incompatible Windows socket library version!";
|
||||
oStream_ << "TcpClient: Incompatible Windows socket library version!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
#endif
|
||||
@@ -57,20 +58,20 @@ int TcpClient :: connect( int port, std::string hostname )
|
||||
// Create the client-side socket
|
||||
soket_ = ::socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
|
||||
if ( soket_ < 0 ) {
|
||||
errorString_ << "TcpClient: Couldn't create socket client!";
|
||||
oStream_ << "TcpClient: Couldn't create socket client!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
|
||||
int flag = 1;
|
||||
int result = setsockopt( soket_, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int) );
|
||||
if ( result < 0 ) {
|
||||
errorString_ << "TcpClient: Error setting socket options!";
|
||||
oStream_ << "TcpClient: Error setting socket options!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
|
||||
struct hostent *hostp;
|
||||
if ( ( hostp = gethostbyname( hostname.c_str() ) ) == 0 ) {
|
||||
errorString_ << "TcpClient: unknown host (" << hostname << ")!";
|
||||
oStream_ << "TcpClient: unknown host (" << hostname << ")!";
|
||||
handleError( StkError::PROCESS_SOCKET_IPADDR );
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ int TcpClient :: connect( int port, std::string hostname )
|
||||
|
||||
// Connect to the server
|
||||
if ( ::connect( soket_, (struct sockaddr *)&server_address, sizeof(server_address) ) < 0 ) {
|
||||
errorString_ << "TcpClient: Couldn't connect to socket server!";
|
||||
oStream_ << "TcpClient: Couldn't connect to socket server!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -36,7 +36,7 @@ TcpServer :: TcpServer( int port )
|
||||
|
||||
WSAStartup(wVersionRequested, &wsaData);
|
||||
if (wsaData.wVersion != wVersionRequested) {
|
||||
errorString_ << "TcpServer: Incompatible Windows socket library version!";
|
||||
oStream_ << "TcpServer: Incompatible Windows socket library version!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
#endif
|
||||
@@ -44,14 +44,14 @@ TcpServer :: TcpServer( int port )
|
||||
// Create the server-side socket
|
||||
soket_ = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (soket_ < 0) {
|
||||
errorString_ << "TcpServer: Couldn't create socket server!";
|
||||
oStream_ << "TcpServer: Couldn't create socket server!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
|
||||
int flag = 1;
|
||||
int result = setsockopt( soket_, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int) );
|
||||
if (result < 0) {
|
||||
errorString_ << "TcpServer: Error setting socket options!";
|
||||
oStream_ << "TcpServer: Error setting socket options!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
|
||||
@@ -62,13 +62,13 @@ TcpServer :: TcpServer( int port )
|
||||
|
||||
// Bind socket to the appropriate port and interface (INADDR_ANY)
|
||||
if ( bind( soket_, (struct sockaddr *)&address, sizeof(address) ) < 0 ) {
|
||||
errorString_ << "TcpServer: Couldn't bind socket!";
|
||||
oStream_ << "TcpServer: Couldn't bind socket!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
|
||||
// Listen for incoming connection(s)
|
||||
if ( listen( soket_, 1 ) < 0 ) {
|
||||
errorString_ << "TcpServer: Couldn't start server listening!";
|
||||
oStream_ << "TcpServer: Couldn't start server listening!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -36,7 +36,7 @@ Thread :: ~Thread()
|
||||
bool Thread :: start( THREAD_FUNCTION routine, void * ptr )
|
||||
{
|
||||
if ( thread_ ) {
|
||||
errorString_ << "Thread:: a thread is already running!";
|
||||
oStream_ << "Thread:: a thread is already running!";
|
||||
handleError( StkError::WARNING );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -73,11 +73,6 @@ void TubeBell :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
gains_[3] = amplitude * fmGains_[71];
|
||||
this->setFrequency( frequency );
|
||||
this->keyOn();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "TubeBell::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
108
src/Twang.cpp
Normal file
108
src/Twang.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
/***************************************************/
|
||||
/*! \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) 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "Twang.h"
|
||||
|
||||
namespace stk {
|
||||
|
||||
Twang :: Twang( StkFloat lowestFrequency )
|
||||
{
|
||||
if ( lowestFrequency <= 0.0 ) {
|
||||
oStream_ << "Twang::Twang: argument is less than or equal to zero!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
this->setLowestFrequency( lowestFrequency );
|
||||
|
||||
std::vector<StkFloat> coefficients( 2, 0.5 );
|
||||
loopFilter_.setCoefficients( coefficients );
|
||||
|
||||
lastFrame_.resize( 1, 1, 0.0 );
|
||||
|
||||
loopGain_ = 0.995;
|
||||
pluckPosition_ = 0.4;
|
||||
this->setFrequency( 220.0 );
|
||||
}
|
||||
|
||||
Twang :: ~Twang( void )
|
||||
{
|
||||
}
|
||||
|
||||
void Twang :: clear( void )
|
||||
{
|
||||
delayLine_.clear();
|
||||
combDelay_.clear();
|
||||
loopFilter_.clear();
|
||||
lastFrame_[0] = 0.0;
|
||||
}
|
||||
|
||||
void Twang :: setLowestFrequency( StkFloat frequency )
|
||||
{
|
||||
unsigned long nDelays = (unsigned long) ( Stk::sampleRate() / frequency );
|
||||
delayLine_.setMaximumDelay( nDelays + 1 );
|
||||
combDelay_.setMaximumDelay( nDelays + 1 );
|
||||
}
|
||||
|
||||
void Twang :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "Twang::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Delay = length - filter delay.
|
||||
StkFloat delay = ( Stk::sampleRate() / frequency ) - loopFilter_.phaseDelay( frequency );
|
||||
delayLine_.setDelay( delay );
|
||||
|
||||
this->setLoopGain( loopGain_ );
|
||||
|
||||
// Set the pluck position, which puts zeroes at position * length.
|
||||
combDelay_.setDelay( 0.5 * pluckPosition_ * delay );
|
||||
}
|
||||
|
||||
void Twang :: setLoopGain( StkFloat loopGain )
|
||||
{
|
||||
if ( loopGain < 0.0 || loopGain >= 1.0 ) {
|
||||
oStream_ << "Twang::setLoopGain: parameter is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
loopGain_ = loopGain;
|
||||
StkFloat gain = loopGain_ + (frequency_ * 0.000005);
|
||||
if ( gain >= 1.0 ) gain = 0.99999;
|
||||
loopFilter_.setGain( gain );
|
||||
}
|
||||
|
||||
void Twang :: setPluckPosition( StkFloat position )
|
||||
{
|
||||
if ( position < 0.0 || position > 1.0 ) {
|
||||
oStream_ << "Twang::setPluckPosition: argument (" << position << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
pluckPosition_ = position;
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
@@ -6,7 +6,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -35,13 +35,24 @@ TwoPole :: ~TwoPole()
|
||||
void TwoPole :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
|
||||
{
|
||||
if ( !ignoreSampleRateChange_ ) {
|
||||
errorString_ << "TwoPole::sampleRateChanged: you may need to recompute filter coefficients!";
|
||||
oStream_ << "TwoPole::sampleRateChanged: you may need to recompute filter coefficients!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
}
|
||||
|
||||
void TwoPole :: setResonance( StkFloat frequency, StkFloat radius, bool normalize )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
|
||||
oStream_ << "TwoPole::setResonance: frequency argument (" << frequency << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
if ( radius < 0.0 || radius >= 1.0 ) {
|
||||
oStream_ << "TwoPole::setResonance: radius argument (" << radius << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
a_[2] = radius * radius;
|
||||
a_[1] = (StkFloat) -2.0 * radius * cos(TWO_PI * frequency / Stk::sampleRate());
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -32,7 +32,7 @@ TwoZero :: ~TwoZero()
|
||||
void TwoZero :: sampleRateChanged( StkFloat newRate, StkFloat oldRate )
|
||||
{
|
||||
if ( !ignoreSampleRateChange_ ) {
|
||||
errorString_ << "TwoZero::sampleRateChanged: you may need to recompute filter coefficients!";
|
||||
oStream_ << "TwoZero::sampleRateChanged: you may need to recompute filter coefficients!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
}
|
||||
@@ -48,8 +48,19 @@ void TwoZero :: setCoefficients( StkFloat b0, StkFloat b1, StkFloat b2, bool cle
|
||||
|
||||
void TwoZero :: setNotch( StkFloat frequency, StkFloat radius )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency < 0.0 || frequency > 0.5 * Stk::sampleRate() ) {
|
||||
oStream_ << "TwoZero::setNotch: frequency argument (" << frequency << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
if ( radius < 0.0 ) {
|
||||
oStream_ << "TwoZero::setNotch: radius argument (" << radius << ") is negative!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
b_[2] = radius * radius;
|
||||
b_[1] = (StkFloat) -2.0 * radius * cos(TWO_PI * (double) frequency / Stk::sampleRate());
|
||||
b_[1] = -2.0 * radius * cos(TWO_PI * frequency / Stk::sampleRate());
|
||||
|
||||
// Normalize the filter gain.
|
||||
if ( b_[1] > 0.0 ) // Maximum at z = 0.
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "UdpSocket.h"
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
||||
namespace stk {
|
||||
|
||||
@@ -36,7 +37,7 @@ UdpSocket :: UdpSocket(int port )
|
||||
|
||||
WSAStartup(wVersionRequested, &wsaData);
|
||||
if (wsaData.wVersion != wVersionRequested) {
|
||||
errorString_ << "UdpSocket: Incompatible Windows socket library version!";
|
||||
oStream_ << "UdpSocket: Incompatible Windows socket library version!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
#endif
|
||||
@@ -44,7 +45,7 @@ UdpSocket :: UdpSocket(int port )
|
||||
// Create the UDP socket
|
||||
soket_ = ::socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
|
||||
if ( soket_ < 0 ) {
|
||||
errorString_ << "UdpSocket: Couldn't create UDP socket!";
|
||||
oStream_ << "UdpSocket: Couldn't create UDP socket!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
|
||||
@@ -55,7 +56,7 @@ UdpSocket :: UdpSocket(int port )
|
||||
|
||||
// Bind socket to the appropriate port and interface (INADDR_ANY)
|
||||
if ( bind(soket_, (struct sockaddr *)&address, sizeof(address)) < 0 ) {
|
||||
errorString_ << "UdpSocket: Couldn't bind socket in constructor!";
|
||||
oStream_ << "UdpSocket: Couldn't bind socket in constructor!";
|
||||
handleError( StkError::PROCESS_SOCKET );
|
||||
}
|
||||
|
||||
@@ -76,7 +77,7 @@ void UdpSocket :: setAddress( struct sockaddr_in *address, int port, std::string
|
||||
{
|
||||
struct hostent *hostp;
|
||||
if ( (hostp = gethostbyname( hostname.c_str() )) == 0 ) {
|
||||
errorString_ << "UdpSocket::setAddress: unknown host (" << hostname << ")!";
|
||||
oStream_ << "UdpSocket::setAddress: unknown host (" << hostname << ")!";
|
||||
handleError( StkError::PROCESS_SOCKET_IPADDR );
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
- 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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -69,14 +69,14 @@ void VoicForm :: clear( void )
|
||||
|
||||
void VoicForm :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
StkFloat freakency = frequency;
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "VoicForm::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
freakency = 220.0;
|
||||
oStream_ << "VoicForm::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
voiced_->setFrequency( freakency );
|
||||
voiced_->setFrequency( frequency );
|
||||
}
|
||||
|
||||
bool VoicForm :: setPhoneme( const char *phoneme )
|
||||
@@ -92,16 +92,12 @@ bool VoicForm :: setPhoneme( const char *phoneme )
|
||||
filters_[3].setTargets( Phonemes::formantFrequency(i, 3), Phonemes::formantRadius(i, 3), pow(10.0, Phonemes::formantGain(i, 3 ) / 20.0) );
|
||||
this->setVoiced( Phonemes::voiceGain( i ) );
|
||||
this->setUnVoiced( Phonemes::noiseGain( i ) );
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "VoicForm::setPhoneme: found formant " << phoneme << " (number " << i << ").";
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if ( !found ) {
|
||||
errorString_ << "VoicForm::setPhoneme: phoneme " << phoneme << " not found!";
|
||||
oStream_ << "VoicForm::setPhoneme: phoneme " << phoneme << " not found!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
@@ -111,9 +107,8 @@ bool VoicForm :: setPhoneme( const char *phoneme )
|
||||
void VoicForm :: setFilterSweepRate( unsigned int whichOne, StkFloat rate )
|
||||
{
|
||||
if ( whichOne < 0 || whichOne > 3 ) {
|
||||
errorString_ << "VoicForm::setFilterSweepRate: filter select argument outside range 0-3!";
|
||||
handleError( StkError::WARNING );
|
||||
return;
|
||||
oStream_ << "VoicForm::setFilterSweepRate: filter select argument outside range 0-3!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
filters_[whichOne].setSweepRate(rate);
|
||||
@@ -134,21 +129,17 @@ void VoicForm :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
|
||||
void VoicForm :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "VoicForm::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "VoicForm::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Clarinet::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if (number == __SK_Breath_) { // 2
|
||||
this->setVoiced( 1.0 - norm );
|
||||
this->setUnVoiced( 0.01 * norm );
|
||||
this->setVoiced( 1.0 - normalizedValue );
|
||||
this->setUnVoiced( 0.01 * normalizedValue );
|
||||
}
|
||||
else if (number == __SK_FootControl_) { // 4
|
||||
StkFloat temp = 0.0;
|
||||
@@ -180,21 +171,18 @@ void VoicForm :: controlChange( int number, StkFloat value )
|
||||
this->setUnVoiced( Phonemes::noiseGain( i ) );
|
||||
}
|
||||
else if (number == __SK_ModFrequency_) // 11
|
||||
voiced_->setVibratoRate( norm * 12.0); // 0 to 12 Hz
|
||||
voiced_->setVibratoRate( normalizedValue * 12.0); // 0 to 12 Hz
|
||||
else if (number == __SK_ModWheel_) // 1
|
||||
voiced_->setVibratoGain( norm * 0.2);
|
||||
voiced_->setVibratoGain( normalizedValue * 0.2);
|
||||
else if (number == __SK_AfterTouch_Cont_) { // 128
|
||||
this->setVoiced( norm );
|
||||
onepole_.setPole( 0.97 - ( norm * 0.2) );
|
||||
this->setVoiced( normalizedValue );
|
||||
onepole_.setPole( 0.97 - ( normalizedValue * 0.2) );
|
||||
}
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
errorString_ << "VoicForm::controlChange: undefined control number (" << number << ")!";
|
||||
oStream_ << "VoicForm::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "VoicForm::controlChange: number = " << number << ", value = " << value << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -30,6 +30,11 @@ namespace stk {
|
||||
|
||||
Voicer :: Voicer( StkFloat decayTime )
|
||||
{
|
||||
if ( decayTime < 0.0 ) {
|
||||
oStream_ << "Voicer::Voicer: argument (" << decayTime << ") must be positive!";
|
||||
handleError( StkError::FUNCTION_ARGUMENT );
|
||||
}
|
||||
|
||||
tags_ = 23456;
|
||||
muteTime_ = (int) ( decayTime * Stk::sampleRate() );
|
||||
lastFrame_.resize( 1, 1, 0.0 );
|
||||
@@ -73,7 +78,7 @@ void Voicer :: removeInstrument( Instrmnt *instrument )
|
||||
lastFrame_.resize( 1, maxChannels );
|
||||
}
|
||||
else {
|
||||
errorString_ << "Voicer::removeInstrument: instrument pointer not found in current voices!";
|
||||
oStream_ << "Voicer::removeInstrument: instrument pointer not found in current voices!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***************************************************/
|
||||
/*! \class Whistle
|
||||
/*! \Class Whistle
|
||||
\brief STK police/referee whistle instrument class.
|
||||
|
||||
This class implements a hybrid physical/spectral
|
||||
@@ -12,7 +12,7 @@
|
||||
- Blowing Frequency Modulation = 2
|
||||
- Volume = 128
|
||||
|
||||
by Perry R. Cook 1996 - 2010.
|
||||
by Perry R. Cook 1995-2011.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -82,24 +82,34 @@ void Whistle :: clear( void )
|
||||
|
||||
void Whistle :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
StkFloat freakency = frequency * 4; // the whistle is a transposing instrument
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
errorString_ << "Whistle::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
freakency = 220.0;
|
||||
oStream_ << "Whistle::setFrequency: parameter is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
baseFrequency_ = freakency;
|
||||
baseFrequency_ = frequency * 4; // the whistle is a transposing instrument
|
||||
}
|
||||
|
||||
void Whistle :: startBlowing( StkFloat amplitude, StkFloat rate )
|
||||
{
|
||||
if ( amplitude <= 0.0 || rate <= 0.0 ) {
|
||||
oStream_ << "Whistle::startBlowing: one or more arguments is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
envelope_.setRate( ENV_RATE );
|
||||
envelope_.setTarget( amplitude );
|
||||
}
|
||||
|
||||
void Whistle :: stopBlowing( StkFloat rate )
|
||||
{
|
||||
if ( rate <= 0.0 ) {
|
||||
oStream_ << "Whistle::stopBlowing: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
|
||||
envelope_.setRate( rate );
|
||||
envelope_.keyOff();
|
||||
}
|
||||
@@ -108,20 +118,11 @@ void Whistle :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
{
|
||||
this->setFrequency( frequency );
|
||||
this->startBlowing( amplitude*2.0 ,amplitude * 0.2 );
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Whistle::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Whistle :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
this->stopBlowing( amplitude * 0.02 );
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Whistle::NoteOff: amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
int frameCount = 0;
|
||||
@@ -221,41 +222,34 @@ StkFloat Whistle :: tick( unsigned int )
|
||||
|
||||
void Whistle :: controlChange( int number, StkFloat value )
|
||||
{
|
||||
StkFloat norm = value * ONE_OVER_128;
|
||||
if ( norm < 0 ) {
|
||||
norm = 0.0;
|
||||
errorString_ << "Whistle::controlChange: control value less than zero ... setting to zero!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
else if ( norm > 1.0 ) {
|
||||
norm = 1.0;
|
||||
errorString_ << "Whistle::controlChange: control value greater than 128.0 ... setting to 128.0!";
|
||||
handleError( StkError::WARNING );
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( Stk::inRange( value, 0.0, 128.0 ) == false ) {
|
||||
oStream_ << "Whistle::controlChange: value (" << value << ") is out of range!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
StkFloat normalizedValue = value * ONE_OVER_128;
|
||||
if ( number == __SK_NoiseLevel_ ) // 4
|
||||
noiseGain_ = 0.25 * norm;
|
||||
noiseGain_ = 0.25 * normalizedValue;
|
||||
else if ( number == __SK_ModFrequency_ ) // 11
|
||||
fippleFreqMod_ = norm;
|
||||
fippleFreqMod_ = normalizedValue;
|
||||
else if ( number == __SK_ModWheel_ ) // 1
|
||||
fippleGainMod_ = norm;
|
||||
fippleGainMod_ = normalizedValue;
|
||||
else if ( number == __SK_AfterTouch_Cont_ ) // 128
|
||||
envelope_.setTarget( norm * 2.0 );
|
||||
envelope_.setTarget( normalizedValue * 2.0 );
|
||||
else if ( number == __SK_Breath_ ) // 2
|
||||
blowFreqMod_ = norm * 0.5;
|
||||
blowFreqMod_ = normalizedValue * 0.5;
|
||||
else if ( number == __SK_Sustain_ ) { // 64
|
||||
subSample_ = (int) value;
|
||||
if ( subSample_ < 1.0 ) subSample_ = 1;
|
||||
envelope_.setRate( ENV_RATE / subSample_ );
|
||||
}
|
||||
#if defined(_STK_DEBUG_)
|
||||
else {
|
||||
errorString_ << "Whistle::controlChange: undefined control number (" << number << ")!";
|
||||
oStream_ << "Whistle::controlChange: undefined control number (" << number << ")!";
|
||||
handleError( StkError::WARNING );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Whistle::controlChange: number = " << number << ", value = " << value << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
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.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -66,7 +66,14 @@ Wurley :: ~Wurley( void )
|
||||
}
|
||||
|
||||
void Wurley :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
if ( frequency <= 0.0 ) {
|
||||
oStream_ << "Wurley::setFrequency: argument is less than or equal to zero!";
|
||||
handleError( StkError::WARNING ); return;
|
||||
}
|
||||
#endif
|
||||
|
||||
baseFrequency_ = frequency;
|
||||
waves_[0]->setFrequency( baseFrequency_ * ratios_[0]);
|
||||
waves_[1]->setFrequency( baseFrequency_ * ratios_[1]);
|
||||
@@ -82,11 +89,6 @@ void Wurley :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
gains_[3] = amplitude * fmGains_[68];
|
||||
this->setFrequency( frequency );
|
||||
this->keyOn();
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Wurley::NoteOn: frequency = " << frequency << ", amplitude = " << amplitude << '.';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
}
|
||||
|
||||
} // stk namespace
|
||||
|
||||
Reference in New Issue
Block a user