Version 4.4.0

This commit is contained in:
Gary Scavone
2013-09-29 23:11:39 +02:00
committed by Stephen Sinclair
parent d199342e86
commit eccd8c9981
287 changed files with 11712 additions and 7676 deletions

View File

@@ -2,54 +2,54 @@
/*! \class Voicer
\brief STK voice manager class.
This class can be used to manage a group of
STK instrument classes. Individual voices can
be controlled via unique note tags.
Instrument groups can be controlled by channel
number.
This class can be used to manage a group of STK instrument
classes. Individual voices can be controlled via unique note
tags. Instrument groups can be controlled by group number.
A previously constructed STK instrument class
is linked with a voice manager using the
addInstrument() function. An optional channel
number argument can be specified to the
addInstrument() function as well (default
channel = 0). The voice manager does not
delete any instrument instances ... it is the
responsibility of the user to allocate and
deallocate all instruments.
A previously constructed STK instrument class is linked with a
voice manager using the addInstrument() function. An optional
group number argument can be specified to the addInstrument()
function as well (default group = 0). The voice manager does not
delete any instrument instances ... it is the responsibility of
the user to allocate and deallocate all instruments.
The tick() function returns the mix of all
sounding voices. Each noteOn returns a unique
tag (credits to the NeXT MusicKit), so you can
send control changes to specific voices within
an ensemble. Alternately, control changes can
be sent to all voices on a given channel.
The tick() function returns the mix of all sounding voices. Each
noteOn returns a unique tag (credits to the NeXT MusicKit), so you
can send control changes to specific voices within an ensemble.
Alternately, control changes can be sent to all voices in a given
group.
by Perry R. Cook and Gary P. Scavone, 1995 - 2007.
by Perry R. Cook and Gary P. Scavone, 1995 - 2009.
*/
/***************************************************/
#include "Voicer.h"
#include <stdlib.h>
#include <math.h>
#include <cmath>
namespace stk {
Voicer :: Voicer( StkFloat decayTime )
{
tags_ = 23456;
muteTime_ = (int) ( decayTime * Stk::sampleRate() );
lastFrame_.resize( 1, 1, 0.0 );
}
Voicer :: ~Voicer()
{
}
void Voicer :: addInstrument( Instrmnt *instrument, int channel )
void Voicer :: addInstrument( Instrmnt *instrument, int group )
{
Voicer::Voice voice;
voice.instrument = instrument;
voice.channel = channel;
voice.group = group;
voice.noteNumber = -1;
voices_.push_back( voice );
// Check output channels and resize lastFrame_ if necessary.
if ( instrument->channelsOut() > lastFrame_.channels() ) {
unsigned int startChannel = lastFrame_.channels();
lastFrame_.resize( 1, instrument->channelsOut() );
for ( unsigned int i=startChannel; i<lastFrame_.size(); i++ )
lastFrame_[i] = 0.0;
}
}
void Voicer :: removeInstrument( Instrmnt *instrument )
@@ -63,23 +63,32 @@ void Voicer :: removeInstrument( Instrmnt *instrument )
break;
}
if ( !found ) {
if ( found ) {
// Check output channels and resize lastFrame_ if necessary.
unsigned int maxChannels = 1;
for ( i=voices_.begin(); i!=voices_.end(); ++i ) {
if ( (*i).instrument->channelsOut() > maxChannels ) maxChannels = (*i).instrument->channelsOut();
}
if ( maxChannels < lastFrame_.channels() )
lastFrame_.resize( 1, maxChannels );
}
else {
errorString_ << "Voicer::removeInstrument: instrument pointer not found in current voices!";
handleError( StkError::WARNING );
}
}
long Voicer :: noteOn(StkFloat noteNumber, StkFloat amplitude, int channel )
long Voicer :: noteOn(StkFloat noteNumber, StkFloat amplitude, int group )
{
unsigned int i;
StkFloat frequency = (StkFloat) 220.0 * pow( 2.0, (noteNumber - 57.0) / 12.0 );
for ( i=0; i<voices_.size(); i++ ) {
if (voices_[i].noteNumber < 0 && voices_[i].channel == channel) {
voices_[i].tag = tags_++;
voices_[i].channel = channel;
if (voices_[i].noteNumber < 0 && voices_[i].group == group) {
voices_[i].tag = tags_++;
voices_[i].group = group;
voices_[i].noteNumber = noteNumber;
voices_[i].frequency = frequency;
voices_[i].instrument->noteOn( frequency, amplitude * ONE_OVER_128 );
voices_[i].instrument->noteOn( frequency, amplitude * ONE_OVER_128 );
voices_[i].sounding = 1;
return voices_[i].tag;
}
@@ -88,7 +97,7 @@ long Voicer :: noteOn(StkFloat noteNumber, StkFloat amplitude, int channel )
// All voices are sounding, so interrupt the oldest voice.
int voice = -1;
for ( i=0; i<voices_.size(); i++ ) {
if ( voices_[i].channel == channel ) {
if ( voices_[i].group == group ) {
if ( voice == -1 ) voice = i;
else if ( voices_[i].tag < voices_[voice].tag ) voice = (int) i;
}
@@ -96,7 +105,7 @@ long Voicer :: noteOn(StkFloat noteNumber, StkFloat amplitude, int channel )
if ( voice >= 0 ) {
voices_[voice].tag = tags_++;
voices_[voice].channel = channel;
voices_[voice].group = group;
voices_[voice].noteNumber = noteNumber;
voices_[voice].frequency = frequency;
voices_[voice].instrument->noteOn( frequency, amplitude * ONE_OVER_128 );
@@ -107,10 +116,10 @@ long Voicer :: noteOn(StkFloat noteNumber, StkFloat amplitude, int channel )
return -1;
}
void Voicer :: noteOff( StkFloat noteNumber, StkFloat amplitude, int channel )
void Voicer :: noteOff( StkFloat noteNumber, StkFloat amplitude, int group )
{
for ( unsigned int i=0; i<voices_.size(); i++ ) {
if ( voices_[i].noteNumber == noteNumber && voices_[i].channel == channel ) {
if ( voices_[i].noteNumber == noteNumber && voices_[i].group == group ) {
voices_[i].instrument->noteOff( amplitude * ONE_OVER_128 );
voices_[i].sounding = -muteTime_;
}
@@ -128,11 +137,11 @@ void Voicer :: noteOff( long tag, StkFloat amplitude )
}
}
void Voicer :: setFrequency( StkFloat noteNumber, int channel )
void Voicer :: setFrequency( StkFloat noteNumber, int group )
{
StkFloat frequency = (StkFloat) 220.0 * pow( 2.0, (noteNumber - 57.0) / 12.0 );
for ( unsigned int i=0; i<voices_.size(); i++ ) {
if ( voices_[i].channel == channel ) {
if ( voices_[i].group == group ) {
voices_[i].noteNumber = noteNumber;
voices_[i].frequency = frequency;
voices_[i].instrument->setFrequency( frequency );
@@ -153,7 +162,7 @@ void Voicer :: setFrequency( long tag, StkFloat noteNumber )
}
}
void Voicer :: pitchBend( StkFloat value, int channel )
void Voicer :: pitchBend( StkFloat value, int group )
{
StkFloat pitchScaler;
if ( value < 64.0 )
@@ -161,7 +170,7 @@ void Voicer :: pitchBend( StkFloat value, int channel )
else
pitchScaler = pow(2.0, (value-64.0)/64.0);
for ( unsigned int i=0; i<voices_.size(); i++ ) {
if ( voices_[i].channel == channel )
if ( voices_[i].group == group )
voices_[i].instrument->setFrequency( (StkFloat) (voices_[i].frequency * pitchScaler) );
}
}
@@ -181,10 +190,10 @@ void Voicer :: pitchBend( long tag, StkFloat value )
}
}
void Voicer :: controlChange( int number, StkFloat value, int channel )
void Voicer :: controlChange( int number, StkFloat value, int group )
{
for ( unsigned int i=0; i<voices_.size(); i++ ) {
if ( voices_[i].channel == channel )
if ( voices_[i].group == group )
voices_[i].instrument->controlChange( number, value );
}
}
@@ -207,72 +216,4 @@ void Voicer :: silence( void )
}
}
StkFloat Voicer :: tick()
{
lastOutput_ = lastOutputLeft_ = lastOutputRight_ = 0.0;
for ( unsigned int i=0; i<voices_.size(); i++ ) {
if ( voices_[i].sounding != 0 ) {
lastOutput_ += voices_[i].instrument->tick();
lastOutputLeft_ += voices_[i].instrument->lastOutLeft();
lastOutputRight_ += voices_[i].instrument->lastOutRight();
}
if ( voices_[i].sounding < 0 ) {
voices_[i].sounding++;
if ( voices_[i].sounding == 0 )
voices_[i].noteNumber = -1;
}
}
return lastOutput_ / voices_.size();
}
StkFloat *Voicer :: tick(StkFloat *vector, unsigned int vectorSize)
{
for (unsigned int i=0; i<vectorSize; i++)
vector[i] = tick();
return vector;
}
StkFrames& Voicer :: tick( StkFrames& frames, unsigned int channel )
{
if ( channel == 0 || frames.channels() < channel ) {
errorString_ << "Voicer::tick(): channel argument (" << channel << ") is zero or > channels in StkFrames argument!";
handleError( StkError::FUNCTION_ARGUMENT );
}
if ( frames.channels() == 1 ) {
for ( unsigned int i=0; i<frames.frames(); i++ )
frames[i] = tick();
}
else if ( frames.interleaved() ) {
unsigned int hop = frames.channels();
unsigned int index = channel - 1;
for ( unsigned int i=0; i<frames.frames(); i++ ) {
frames[index] = tick();
index += hop;
}
}
else {
unsigned int iStart = (channel - 1) * frames.frames();
for ( unsigned int i=0; i<frames.frames(); i++ )
frames[iStart + i] = tick();
}
return frames;
}
StkFloat Voicer :: lastOut() const
{
return lastOutput_;
}
StkFloat Voicer :: lastOutLeft() const
{
return lastOutputLeft_;
}
StkFloat Voicer :: lastOutRight() const
{
return lastOutputRight_;
}
} // stk namespace