mirror of
https://github.com/thestk/stk
synced 2026-01-17 06:41:51 +00:00
Version 4.2.1
This commit is contained in:
committed by
Stephen Sinclair
parent
a6381b9d38
commit
2cbce2d8bd
@@ -13,13 +13,13 @@
|
||||
Stanford, bearing the names of Karplus and/or
|
||||
Strong.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2005.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "Drone.h"
|
||||
|
||||
Drone :: Drone(StkFloat lowestFrequency)
|
||||
Drone :: Drone( StkFloat lowestFrequency )
|
||||
{
|
||||
length_ = (unsigned long) (Stk::sampleRate() / lowestFrequency + 1);
|
||||
loopGain_ = 0.999;
|
||||
@@ -39,7 +39,7 @@ void Drone :: clear()
|
||||
loopFilter_.clear();
|
||||
}
|
||||
|
||||
void Drone :: setFrequency(StkFloat frequency)
|
||||
void Drone :: setFrequency( StkFloat frequency )
|
||||
{
|
||||
StkFloat freakency = frequency;
|
||||
if ( frequency <= 0.0 ) {
|
||||
@@ -59,12 +59,12 @@ void Drone :: setFrequency(StkFloat frequency)
|
||||
if ( loopGain_ >= 1.0 ) loopGain_ = 0.99999;
|
||||
}
|
||||
|
||||
void Drone :: pluck(StkFloat amplitude)
|
||||
void Drone :: pluck( StkFloat amplitude )
|
||||
{
|
||||
envelope_.keyOn();
|
||||
}
|
||||
|
||||
void Drone :: noteOn(StkFloat frequency, StkFloat amplitude)
|
||||
void Drone :: noteOn( StkFloat frequency, StkFloat amplitude )
|
||||
{
|
||||
this->setFrequency( frequency );
|
||||
this->pluck( amplitude );
|
||||
@@ -75,7 +75,7 @@ void Drone :: noteOn(StkFloat frequency, StkFloat amplitude)
|
||||
#endif
|
||||
}
|
||||
|
||||
void Drone :: noteOff(StkFloat amplitude)
|
||||
void Drone :: noteOff( StkFloat amplitude )
|
||||
{
|
||||
loopGain_ = 1.0 - amplitude;
|
||||
if ( loopGain_ < 0.0 ) {
|
||||
@@ -95,19 +95,11 @@ void Drone :: noteOff(StkFloat amplitude)
|
||||
#endif
|
||||
}
|
||||
|
||||
StkFloat Drone :: tick()
|
||||
StkFloat Drone :: computeSample()
|
||||
{
|
||||
// Here's the whole inner loop of the instrument!!
|
||||
lastOutput_ = delayLine_.tick( loopFilter_.tick( delayLine_.lastOut() * loopGain_ ) + (0.005 * envelope_.tick() * noise_.tick()));
|
||||
lastOutput_ = delayLine_.tick( loopFilter_.tick( delayLine_.lastOut() * loopGain_ )
|
||||
+ (0.005 * envelope_.tick() * noise_.tick()));
|
||||
return lastOutput_;
|
||||
}
|
||||
|
||||
StkFloat *Drone :: tick(StkFloat *vector, unsigned int vectorSize)
|
||||
{
|
||||
return Instrmnt::tick( vector, vectorSize );
|
||||
}
|
||||
|
||||
StkFrames& Drone :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
return Instrmnt::tick( frames, channel );
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
Stanford, bearing the names of Karplus and/or
|
||||
Strong.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2005.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -50,22 +50,10 @@ class Drone : public Instrmnt
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
virtual void noteOff(StkFloat amplitude);
|
||||
|
||||
//! Compute one output sample.
|
||||
virtual StkFloat tick();
|
||||
protected:
|
||||
|
||||
//! Computer \e vectorSize outputs and return them in \e vector.
|
||||
virtual StkFloat *tick(StkFloat *vector, unsigned int vectorSize);
|
||||
StkFloat computeSample( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument should be one or greater (the first
|
||||
channel is specified by 1). An StkError will be thrown if the \c
|
||||
channel argument is zero or it is greater than the number of
|
||||
channels in the StkFrames object.
|
||||
*/
|
||||
virtual StkFrames& tick( StkFrames& frames, unsigned int channel = 1 );
|
||||
|
||||
protected:
|
||||
DelayA delayLine_;
|
||||
OneZero loopFilter_;
|
||||
ADSR envelope_;
|
||||
|
||||
@@ -10,7 +10,7 @@ OBJECTS = Stk.o Generator.o Noise.o Envelope.o ADSR.o \
|
||||
Filter.o DelayA.o Delay.o \
|
||||
OnePole.o OneZero.o Skini.o \
|
||||
Tabla.o Instrmnt.o Sitar.o \
|
||||
Drone.o VoicDrum.o WvOut.o WvIn.o \
|
||||
Drone.o VoicDrum.o FileRead.o WvOut.o WvIn.o FileWvIn.o \
|
||||
Effect.o JCRev.o Messager.o
|
||||
|
||||
INCLUDE = @include@
|
||||
@@ -29,7 +29,7 @@ LIBRARY += @frameworks@
|
||||
|
||||
REALTIME = @realtime@
|
||||
ifeq ($(REALTIME),yes)
|
||||
OBJECTS += RtMidi.o RtAudio.o RtWvOut.o Thread.o Mutex.o Socket.o
|
||||
OBJECTS += RtMidi.o RtAudio.o RtWvOut.o Thread.o Mutex.o Socket.o TcpServer.o
|
||||
DEFS += @audio_apis@
|
||||
endif
|
||||
|
||||
|
||||
@@ -2,39 +2,49 @@
|
||||
/*! \class Tabla
|
||||
\brief STK tabla drum class.
|
||||
|
||||
This class implements a drum sampling
|
||||
synthesizer using WvIn objects and one-pole
|
||||
filters. The drum rawwave files are sampled
|
||||
at 22050 Hz, but will be appropriately
|
||||
interpolated for other sample rates. You can
|
||||
specify the maximum polyphony (maximum number
|
||||
of simultaneous voices) in Drummer.h.
|
||||
This class implements a drum sampling synthesizer using FileWvIn
|
||||
objects and one-pole filters. The drum rawwave files are sampled
|
||||
at 22050 Hz, but will be appropriately interpolated for other
|
||||
sample rates. You can specify the maximum polyphony (maximum
|
||||
number of simultaneous voices) in Tabla.h.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2005.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "Tabla.h"
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
|
||||
Tabla :: Tabla() : Instrmnt()
|
||||
{
|
||||
for ( int i=0; i<TABLA_POLYPHONY; i++ ) {
|
||||
filters_[i] = new OnePole;
|
||||
sounding_[i] = -1;
|
||||
}
|
||||
|
||||
// This counts the number of sounding voices.
|
||||
nSounding_ = 0;
|
||||
soundOrder_ = std::vector<int> (TABLA_POLYPHONY, -1);
|
||||
soundNumber_ = std::vector<int> (TABLA_POLYPHONY, -1);
|
||||
}
|
||||
|
||||
Tabla :: ~Tabla()
|
||||
{
|
||||
int i;
|
||||
for ( i=0; i<nSounding_; i++ ) delete waves_[i];
|
||||
for ( i=0; i<TABLA_POLYPHONY; i++ ) delete filters_[i];
|
||||
}
|
||||
|
||||
static char tablaWaves[TABLA_NUMWAVES][16] =
|
||||
{ "Drdak2.raw",
|
||||
"Drdak3.raw",
|
||||
"Drdak4.raw",
|
||||
"Drddak1.raw",
|
||||
"Drdee1.raw",
|
||||
"Drdee2.raw",
|
||||
"Drdoo1.raw",
|
||||
"Drdoo2.raw",
|
||||
"Drdoo3.raw",
|
||||
"Drjun1.raw",
|
||||
"Drjun2.raw",
|
||||
"DrDoi1.raw",
|
||||
"DrDoi2.raw",
|
||||
"DrTak1.raw",
|
||||
"DrTak2.raw"
|
||||
};
|
||||
|
||||
void Tabla :: noteOn(StkFloat instrument, StkFloat amplitude)
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
@@ -54,68 +64,54 @@ void Tabla :: noteOn(StkFloat instrument, StkFloat amplitude)
|
||||
return;
|
||||
}
|
||||
|
||||
static char tablaWaves[TABLA_NUMWAVES][16] =
|
||||
{ "Drdak2.raw",
|
||||
"Drdak3.raw",
|
||||
"Drdak4.raw",
|
||||
"Drddak1.raw",
|
||||
"Drdee1.raw",
|
||||
"Drdee2.raw",
|
||||
"Drdoo1.raw",
|
||||
"Drdoo2.raw",
|
||||
"Drdoo3.raw",
|
||||
"Drjun1.raw",
|
||||
"Drjun2.raw",
|
||||
"DrDoi1.raw",
|
||||
"DrDoi2.raw",
|
||||
"DrTak1.raw",
|
||||
"DrTak2.raw"
|
||||
};
|
||||
int noteNumber = ( (int) instrument ) % 16;
|
||||
|
||||
int noteNum = ( (int) instrument ) % 16;
|
||||
|
||||
// Check first to see if there's already one like this sounding.
|
||||
int i, waveIndex = -1;
|
||||
for ( i=0; i<TABLA_POLYPHONY; i++ ) {
|
||||
if ( sounding_[i] == noteNum ) waveIndex = i;
|
||||
}
|
||||
|
||||
if ( waveIndex >= 0 ) {
|
||||
// Reset this sound.
|
||||
waves_[waveIndex]->reset();
|
||||
filters_[waveIndex]->setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[waveIndex]->setGain( gain );
|
||||
}
|
||||
else {
|
||||
if ( nSounding_ == TABLA_POLYPHONY ) {
|
||||
// If we're already at maximum polyphony, then preempt the oldest voice.
|
||||
delete waves_[0];
|
||||
filters_[0]->clear();
|
||||
OnePole *tempFilt = filters_[0];
|
||||
// Re-order the list.
|
||||
for ( i=0; i<TABLA_POLYPHONY-1; i++ ) {
|
||||
waves_[i] = waves_[i+1];
|
||||
filters_[i] = filters_[i+1];
|
||||
// If we already have a wave of this note number loaded, just reset
|
||||
// it. Otherwise, look first for an unused wave or preempt the
|
||||
// oldest if already at maximum polyphony.
|
||||
int iWave;
|
||||
for ( iWave=0; iWave<TABLA_POLYPHONY; iWave++ ) {
|
||||
if ( soundNumber_[iWave] == noteNumber ) {
|
||||
if ( waves_[iWave].isFinished() ) {
|
||||
soundOrder_[iWave] = nSounding_;
|
||||
nSounding_++;
|
||||
}
|
||||
waves_[TABLA_POLYPHONY-1] = 0;
|
||||
filters_[TABLA_POLYPHONY-1] = tempFilt;
|
||||
waves_[iWave].reset();
|
||||
filters_[iWave].setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[iWave].setGain( gain );
|
||||
break;
|
||||
}
|
||||
else
|
||||
nSounding_ += 1;
|
||||
}
|
||||
|
||||
sounding_[nSounding_-1] = noteNum;
|
||||
// Concatenate the rawwave path to the file name.
|
||||
waves_[nSounding_-1] = new WvIn( (std::string("rawwaves/") + tablaWaves[noteNum]).c_str(), true );
|
||||
waves_[nSounding_-1]->normalize(0.4);
|
||||
if ( iWave == TABLA_POLYPHONY ) { // This note number is not currently loaded.
|
||||
if ( nSounding_ < TABLA_POLYPHONY ) {
|
||||
for ( iWave=0; iWave<TABLA_POLYPHONY; iWave++ )
|
||||
if ( soundOrder_[iWave] < 0 ) break;
|
||||
nSounding_ += 1;
|
||||
}
|
||||
else {
|
||||
for ( iWave=0; iWave<TABLA_POLYPHONY; iWave++ )
|
||||
if ( soundOrder_[iWave] == 0 ) break;
|
||||
// Re-order the list.
|
||||
for ( int j=0; j<TABLA_POLYPHONY; j++ ) {
|
||||
if ( soundOrder_[j] > soundOrder_[iWave] )
|
||||
soundOrder_[j] -= 1;
|
||||
}
|
||||
}
|
||||
soundOrder_[iWave] = nSounding_ - 1;
|
||||
soundNumber_[iWave] = noteNumber;
|
||||
|
||||
// Concatenate the rawwave path to the rawwave file
|
||||
waves_[iWave].openFile( (std::string("rawwaves/") + tablaWaves[ noteNumber ]).c_str(), true );
|
||||
if ( Stk::sampleRate() != 22050.0 )
|
||||
waves_[nSounding_-1]->setRate( 22050.0 / Stk::sampleRate() );
|
||||
filters_[nSounding_-1]->setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[nSounding_-1]->setGain( gain );
|
||||
waves_[iWave].setRate( 22050.0 / Stk::sampleRate() );
|
||||
filters_[iWave].setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[iWave].setGain( gain );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "Tabla::noteOn: number sounding = " << nSounding_ << '\n';
|
||||
for (i=0; i<nSounding_; i++) errorString_ << sounding_[i] << " ";
|
||||
for (i=0; i<nSounding_; i++) errorString_ << soundNumber_[i] << " ";
|
||||
errorString_ << '\n';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
@@ -125,46 +121,30 @@ void Tabla :: noteOff(StkFloat amplitude)
|
||||
{
|
||||
// Set all sounding wave filter gains low.
|
||||
int i = 0;
|
||||
while ( i < nSounding_ )
|
||||
filters_[i++]->setGain( amplitude * 0.01 );
|
||||
while ( i < nSounding_ ) filters_[i++].setGain( amplitude * 0.01 );
|
||||
}
|
||||
|
||||
StkFloat Tabla :: tick()
|
||||
StkFloat Tabla :: computeSample()
|
||||
{
|
||||
OnePole *tempFilt;
|
||||
|
||||
int j, i = 0;
|
||||
lastOutput_ = 0.0;
|
||||
while ( i < nSounding_ ) {
|
||||
if ( waves_[i]->isFinished() ) {
|
||||
delete waves_[i];
|
||||
tempFilt = filters_[i];
|
||||
// Re-order the list.
|
||||
for ( j=i; j<nSounding_-1; j++ ) {
|
||||
sounding_[j] = sounding_[j+1];
|
||||
waves_[j] = waves_[j+1];
|
||||
filters_[j] = filters_[j+1];
|
||||
if ( nSounding_ == 0 ) return lastOutput_;
|
||||
|
||||
for ( int i=0; i<TABLA_POLYPHONY; i++ ) {
|
||||
if ( soundOrder_[i] >= 0 ) {
|
||||
if ( waves_[i].isFinished() ) {
|
||||
// Re-order the list.
|
||||
for ( int j=0; j<TABLA_POLYPHONY; j++ ) {
|
||||
if ( soundOrder_[j] > soundOrder_[i] )
|
||||
soundOrder_[j] -= 1;
|
||||
}
|
||||
soundOrder_[i] = -1;
|
||||
nSounding_--;
|
||||
}
|
||||
filters_[j] = tempFilt;
|
||||
filters_[j]->clear();
|
||||
sounding_[j] = -1;
|
||||
nSounding_ -= 1;
|
||||
i -= 1;
|
||||
else
|
||||
lastOutput_ += filters_[i].tick( waves_[i].tick() );
|
||||
}
|
||||
else
|
||||
lastOutput_ += filters_[i]->tick( waves_[i]->tick() );
|
||||
i++;
|
||||
}
|
||||
|
||||
return lastOutput_;
|
||||
}
|
||||
|
||||
StkFloat *Tabla :: tick(StkFloat *vector, unsigned int vectorSize)
|
||||
{
|
||||
return Instrmnt::tick( vector, vectorSize );
|
||||
}
|
||||
|
||||
StkFrames& Tabla :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
return Instrmnt::tick( frames, channel );
|
||||
}
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
/*! \class Tabla
|
||||
\brief STK tabla drum class.
|
||||
|
||||
This class implements a drum sampling
|
||||
synthesizer using WvIn objects and one-pole
|
||||
filters. The drum rawwave files are sampled
|
||||
at 22050 Hz, but will be appropriately
|
||||
interpolated for other sample rates. You can
|
||||
specify the maximum polyphony (maximum number
|
||||
of simultaneous voices) in Drummer.h.
|
||||
This class implements a drum sampling synthesizer using FileWvIn
|
||||
objects and one-pole filters. The drum rawwave files are sampled
|
||||
at 22050 Hz, but will be appropriately interpolated for other
|
||||
sample rates. You can specify the maximum polyphony (maximum
|
||||
number of simultaneous voices) in Tabla.h.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2005.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -18,7 +16,7 @@
|
||||
#define STK_TABLA_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "WvIn.h"
|
||||
#include "FileWvIn.h"
|
||||
#include "OnePole.h"
|
||||
|
||||
const int TABLA_NUMWAVES = 15;
|
||||
@@ -39,25 +37,14 @@ class Tabla : public Instrmnt
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
|
||||
//! Compute one output sample.
|
||||
StkFloat tick();
|
||||
protected:
|
||||
|
||||
//! Computer \e vectorSize outputs and return them in \e vector.
|
||||
StkFloat *tick(StkFloat *vector, unsigned int vectorSize);
|
||||
StkFloat computeSample( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument should be one or greater (the first
|
||||
channel is specified by 1). An StkError will be thrown if the \c
|
||||
channel argument is zero or it is greater than the number of
|
||||
channels in the StkFrames object.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 1 );
|
||||
|
||||
protected:
|
||||
WvIn *waves_[TABLA_POLYPHONY];
|
||||
OnePole *filters_[TABLA_POLYPHONY];
|
||||
int sounding_[TABLA_POLYPHONY];
|
||||
FileWvIn waves_[TABLA_POLYPHONY];
|
||||
OnePole filters_[TABLA_POLYPHONY];
|
||||
std::vector<int> soundOrder_;
|
||||
std::vector<int> soundNumber_;
|
||||
int nSounding_;
|
||||
|
||||
};
|
||||
|
||||
@@ -2,39 +2,46 @@
|
||||
/*! \class VoicDrum
|
||||
\brief STK vocal drum sample player class.
|
||||
|
||||
This class implements a drum sampling
|
||||
synthesizer using WvIn objects and one-pole
|
||||
filters. The drum rawwave files are sampled
|
||||
at 22050 Hz, but will be appropriately
|
||||
interpolated for other sample rates. You can
|
||||
specify the maximum polyphony (maximum number
|
||||
of simultaneous voices) in Drummer.h.
|
||||
This class implements a drum sampling synthesizer using FileWvIn
|
||||
objects and one-pole filters. The drum rawwave files are sampled
|
||||
at 22050 Hz, but will be appropriately interpolated for other
|
||||
sample rates. You can specify the maximum polyphony (maximum
|
||||
number of simultaneous voices) in VoicDrum.h.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2005.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "VoicDrum.h"
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
|
||||
VoicDrum :: VoicDrum() : Instrmnt()
|
||||
{
|
||||
for ( int i=0; i<VOICE_POLYPHONY; i++ ) {
|
||||
filters_[i] = new OnePole;
|
||||
sounding_[i] = -1;
|
||||
}
|
||||
|
||||
// This counts the number of sounding voices.
|
||||
nSounding_ = 0;
|
||||
soundOrder_ = std::vector<int> (VOICE_POLYPHONY, -1);
|
||||
soundNumber_ = std::vector<int> (VOICE_POLYPHONY, -1);
|
||||
}
|
||||
|
||||
VoicDrum :: ~VoicDrum()
|
||||
{
|
||||
int i;
|
||||
for ( i=0; i<nSounding_; i++ ) delete waves_[i];
|
||||
for ( i=0; i<VOICE_POLYPHONY; i++ ) delete filters_[i];
|
||||
}
|
||||
|
||||
char voiceNames[VOICE_NUMWAVES][11] =
|
||||
{
|
||||
"tak2.raw",
|
||||
"tak1.raw",
|
||||
"bee1.raw",
|
||||
"dee1.raw",
|
||||
"dee2.raw",
|
||||
"din1.raw",
|
||||
"gun1.raw",
|
||||
"jun1.raw",
|
||||
"jun2.raw",
|
||||
"tak3.raw",
|
||||
"tak4.raw"
|
||||
};
|
||||
|
||||
void VoicDrum :: noteOn( StkFloat instrument, StkFloat amplitude )
|
||||
{
|
||||
#if defined(_STK_DEBUG_)
|
||||
@@ -54,65 +61,54 @@ void VoicDrum :: noteOn( StkFloat instrument, StkFloat amplitude )
|
||||
return;
|
||||
}
|
||||
|
||||
char voiceNames[VOICE_NUMWAVES][11] =
|
||||
{
|
||||
"tak2.raw",
|
||||
"tak1.raw",
|
||||
"bee1.raw",
|
||||
"dee1.raw",
|
||||
"dee2.raw",
|
||||
"din1.raw",
|
||||
"gun1.raw",
|
||||
"jun1.raw",
|
||||
"jun2.raw",
|
||||
"tak3.raw",
|
||||
"tak4.raw"
|
||||
};
|
||||
int noteNumber = ( (int) instrument ) % 11;
|
||||
|
||||
int noteNum = ( (int) instrument ) % 11;
|
||||
|
||||
// Check first to see if there's already one like this sounding.
|
||||
int i, waveIndex = -1;
|
||||
for ( i=0; i<VOICE_POLYPHONY; i++ ) {
|
||||
if ( sounding_[i] == noteNum ) waveIndex = i;
|
||||
}
|
||||
|
||||
if ( waveIndex >= 0 ) {
|
||||
// Reset this sound.
|
||||
waves_[waveIndex]->reset();
|
||||
filters_[waveIndex]->setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[waveIndex]->setGain( gain );
|
||||
}
|
||||
else {
|
||||
if ( nSounding_ == VOICE_POLYPHONY ) {
|
||||
// If we're already at maximum polyphony, then preempt the oldest voice.
|
||||
delete waves_[0];
|
||||
filters_[0]->clear();
|
||||
OnePole *tempFilt = filters_[0];
|
||||
// Re-order the list.
|
||||
for ( i=0; i<VOICE_POLYPHONY-1; i++ ) {
|
||||
waves_[i] = waves_[i+1];
|
||||
filters_[i] = filters_[i+1];
|
||||
// If we already have a wave of this note number loaded, just reset
|
||||
// it. Otherwise, look first for an unused wave or preempt the
|
||||
// oldest if already at maximum polyphony.
|
||||
int iWave;
|
||||
for ( iWave=0; iWave<VOICE_POLYPHONY; iWave++ ) {
|
||||
if ( soundNumber_[iWave] == noteNumber ) {
|
||||
if ( waves_[iWave].isFinished() ) {
|
||||
soundOrder_[iWave] = nSounding_;
|
||||
nSounding_++;
|
||||
}
|
||||
waves_[VOICE_POLYPHONY-1] = 0;
|
||||
filters_[VOICE_POLYPHONY-1] = tempFilt;
|
||||
waves_[iWave].reset();
|
||||
filters_[iWave].setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[iWave].setGain( gain );
|
||||
break;
|
||||
}
|
||||
else
|
||||
nSounding_ += 1;
|
||||
}
|
||||
|
||||
sounding_[nSounding_-1] = noteNum;
|
||||
// Concatenate the rawwave path to the file name.
|
||||
waves_[nSounding_-1] = new WvIn( (std::string("rawwaves/") + voiceNames[noteNum]).c_str(), true );
|
||||
waves_[nSounding_-1]->normalize(0.4);
|
||||
if (Stk::sampleRate() != 22050.0)
|
||||
waves_[nSounding_-1]->setRate( 22050.0 / Stk::sampleRate() );
|
||||
filters_[nSounding_-1]->setPole( 0.999 - (gain * 0.6) );
|
||||
filters_[nSounding_-1]->setGain( gain );
|
||||
if ( iWave == VOICE_POLYPHONY ) { // This note number is not currently loaded.
|
||||
if ( nSounding_ < VOICE_POLYPHONY ) {
|
||||
for ( iWave=0; iWave<VOICE_POLYPHONY; iWave++ )
|
||||
if ( soundOrder_[iWave] < 0 ) break;
|
||||
nSounding_ += 1;
|
||||
}
|
||||
else {
|
||||
for ( iWave=0; iWave<VOICE_POLYPHONY; iWave++ )
|
||||
if ( soundOrder_[iWave] == 0 ) break;
|
||||
// Re-order the list.
|
||||
for ( int j=0; j<VOICE_POLYPHONY; j++ ) {
|
||||
if ( soundOrder_[j] > soundOrder_[iWave] )
|
||||
soundOrder_[j] -= 1;
|
||||
}
|
||||
}
|
||||
soundOrder_[iWave] = nSounding_ - 1;
|
||||
soundNumber_[iWave] = noteNumber;
|
||||
|
||||
// Concatenate the rawwave path to the rawwave file
|
||||
waves_[iWave].openFile( (std::string("rawwaves/") + voiceNames[ 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 );
|
||||
}
|
||||
|
||||
#if defined(_STK_DEBUG_)
|
||||
errorString_ << "VoicDrum::noteOn: number sounding = " << nSounding_ << '\n';
|
||||
for (i=0; i<nSounding_; i++) errorString_ << sounding_[i] << " ";
|
||||
for (i=0; i<nSounding_; i++) errorString_ << soundNumber_[i] << " ";
|
||||
errorString_ << '\n';
|
||||
handleError( StkError::DEBUG_WARNING );
|
||||
#endif
|
||||
@@ -122,45 +118,29 @@ void VoicDrum :: noteOff(StkFloat amplitude)
|
||||
{
|
||||
// Set all sounding wave filter gains low.
|
||||
int i = 0;
|
||||
while ( i < nSounding_ ) filters_[i++]->setGain( amplitude * 0.01 );
|
||||
while ( i < nSounding_ ) filters_[i++].setGain( amplitude * 0.01 );
|
||||
}
|
||||
|
||||
StkFloat VoicDrum :: tick()
|
||||
StkFloat VoicDrum :: computeSample()
|
||||
{
|
||||
OnePole *tempFilt;
|
||||
|
||||
int j, i = 0;
|
||||
lastOutput_ = 0.0;
|
||||
while ( i < nSounding_ ) {
|
||||
if ( waves_[i]->isFinished() ) {
|
||||
delete waves_[i];
|
||||
tempFilt = filters_[i];
|
||||
// Re-order the list.
|
||||
for ( j=i; j<nSounding_-1; j++ ) {
|
||||
sounding_[j] = sounding_[j+1];
|
||||
waves_[j] = waves_[j+1];
|
||||
filters_[j] = filters_[j+1];
|
||||
if ( nSounding_ == 0 ) return lastOutput_;
|
||||
|
||||
for ( int i=0; i<VOICE_POLYPHONY; i++ ) {
|
||||
if ( soundOrder_[i] >= 0 ) {
|
||||
if ( waves_[i].isFinished() ) {
|
||||
// Re-order the list.
|
||||
for ( int j=0; j<VOICE_POLYPHONY; j++ ) {
|
||||
if ( soundOrder_[j] > soundOrder_[i] )
|
||||
soundOrder_[j] -= 1;
|
||||
}
|
||||
soundOrder_[i] = -1;
|
||||
nSounding_--;
|
||||
}
|
||||
filters_[j] = tempFilt;
|
||||
filters_[j]->clear();
|
||||
sounding_[j] = -1;
|
||||
nSounding_ -= 1;
|
||||
i -= 1;
|
||||
else
|
||||
lastOutput_ += filters_[i].tick( waves_[i].tick() );
|
||||
}
|
||||
else
|
||||
lastOutput_ += filters_[i]->tick( waves_[i]->tick() );
|
||||
i++;
|
||||
}
|
||||
|
||||
return lastOutput_;
|
||||
}
|
||||
|
||||
StkFloat *VoicDrum :: tick(StkFloat *vector, unsigned int vectorSize)
|
||||
{
|
||||
return Instrmnt::tick( vector, vectorSize );
|
||||
}
|
||||
|
||||
StkFrames& VoicDrum :: tick( StkFrames& frames, unsigned int channel )
|
||||
{
|
||||
return Instrmnt::tick( frames, channel );
|
||||
}
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
/*! \class VoicDrum
|
||||
\brief STK vocal drum sample player class.
|
||||
|
||||
This class implements a drum sampling
|
||||
synthesizer using WvIn objects and one-pole
|
||||
filters. The drum rawwave files are sampled
|
||||
at 22050 Hz, but will be appropriately
|
||||
interpolated for other sample rates. You can
|
||||
specify the maximum polyphony (maximum number
|
||||
of simultaneous voices) in Drummer.h.
|
||||
This class implements a drum sampling synthesizer using FileWvIn
|
||||
objects and one-pole filters. The drum rawwave files are sampled
|
||||
at 22050 Hz, but will be appropriately interpolated for other
|
||||
sample rates. You can specify the maximum polyphony (maximum
|
||||
number of simultaneous voices) in VoicDrum.h.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2004.
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2005.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
@@ -18,7 +16,7 @@
|
||||
#define STK_VOICDRUM_H
|
||||
|
||||
#include "Instrmnt.h"
|
||||
#include "WvIn.h"
|
||||
#include "FileWvIn.h"
|
||||
#include "OnePole.h"
|
||||
|
||||
const int VOICE_NUMWAVES = 11;
|
||||
@@ -39,25 +37,14 @@ class VoicDrum : public Instrmnt
|
||||
//! Stop a note with the given amplitude (speed of decay).
|
||||
void noteOff(StkFloat amplitude);
|
||||
|
||||
//! Compute one output sample.
|
||||
StkFloat tick();
|
||||
protected:
|
||||
|
||||
//! Computer \e vectorSize outputs and return them in \e vector.
|
||||
StkFloat *tick(StkFloat *vector, unsigned int vectorSize);
|
||||
StkFloat computeSample( void );
|
||||
|
||||
//! Fill a channel of the StkFrames object with computed outputs.
|
||||
/*!
|
||||
The \c channel argument should be one or greater (the first
|
||||
channel is specified by 1). An StkError will be thrown if the \c
|
||||
channel argument is zero or it is greater than the number of
|
||||
channels in the StkFrames object.
|
||||
*/
|
||||
StkFrames& tick( StkFrames& frames, unsigned int channel = 1 );
|
||||
|
||||
protected:
|
||||
WvIn *waves_[VOICE_POLYPHONY];
|
||||
OnePole *filters_[VOICE_POLYPHONY];
|
||||
int sounding_[VOICE_POLYPHONY];
|
||||
FileWvIn waves_[VOICE_POLYPHONY];
|
||||
OnePole filters_[VOICE_POLYPHONY];
|
||||
std::vector<int> soundOrder_;
|
||||
std::vector<int> soundNumber_;
|
||||
int nSounding_;
|
||||
|
||||
};
|
||||
|
||||
@@ -188,24 +188,22 @@ int tick(char *buffer, int bufferSize, void *dataPointer)
|
||||
// Do a bunch of random controls unless settling down to end.
|
||||
if ( data->settling ) {
|
||||
if ( data->counter == 0 ) {
|
||||
if ( data->endPhase++ == 0 ) {
|
||||
data->counter = (int) (data->t60 * Stk::sampleRate());
|
||||
data->counter = (int) (data->t60 * Stk::sampleRate());
|
||||
if ( data->endPhase == 0 ) {
|
||||
data->drones[2].noteOn( droneFreqs[2], 0.1 );
|
||||
std::cout << "What Need Have I for This?\n";
|
||||
}
|
||||
else if ( data->endPhase == 1 ) {
|
||||
data->counter = (int) (data->t60 * Stk::sampleRate());
|
||||
data->drones[0].noteOn( droneFreqs[0], 0.1 );
|
||||
std::cout << "RagaMatic finished ... \n";
|
||||
}
|
||||
else if ( data->endPhase == 2 ) {
|
||||
data->counter = (int) (data->t60 * Stk::sampleRate());
|
||||
std::cout << "All is Bliss ...\n";
|
||||
}
|
||||
else if ( data->endPhase == 3 ) {
|
||||
std::cout << "All is Bliss ...\n";
|
||||
data->counter = (int) (data->t60 * Stk::sampleRate());
|
||||
}
|
||||
data->endPhase++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -140,6 +140,22 @@ SOURCE=..\..\include\Envelope.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\FileRead.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\FileRead.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\FileWvIn.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\FileWvIn.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Filter.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -272,6 +288,14 @@ SOURCE=.\Tabla.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\TcpServer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\include\TcpServer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\Thread.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
Reference in New Issue
Block a user