mirror of
https://github.com/thestk/stk
synced 2026-01-18 23:21:53 +00:00
Version 4.0
This commit is contained in:
committed by
Stephen Sinclair
parent
3f126af4e5
commit
81475b04c5
@@ -1,144 +1,147 @@
|
||||
/*******************************************/
|
||||
/* Master Class for Drum Synthesizer */
|
||||
/* by Perry R. Cook, 1995-96 */
|
||||
/* */
|
||||
/* This instrument contains a bunch of */
|
||||
/* RawWvIn objects, run through a bunch */
|
||||
/* of one-pole filters. All the */
|
||||
/* corresponding rawwave files have been */
|
||||
/* sampled at 22050 Hz. Thus, if the */
|
||||
/* compile-time SRATE = 22050, then */
|
||||
/* no interpolation is used. Otherwise, */
|
||||
/* the rawwave data is appropriately */
|
||||
/* interpolated for the current SRATE. */
|
||||
/* You can specify the maximum Polyphony */
|
||||
/* (maximum number of simultaneous voices)*/
|
||||
/* in a #define in the .h file. */
|
||||
/* */
|
||||
/* Modified for RawWvIn class */
|
||||
/* by Gary P. Scavone (4/99) */
|
||||
/*******************************************/
|
||||
/***************************************************/
|
||||
/*! \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) via a #define in the
|
||||
Drummer.h.
|
||||
|
||||
by Perry R. Cook and Gary P. Scavone, 1995 - 2002.
|
||||
*/
|
||||
/***************************************************/
|
||||
|
||||
#include "Tabla.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
Tabla :: Tabla() : Instrmnt()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<TABLA_POLYPHONY;i++) {
|
||||
for (int i=0; i<TABLA_POLYPHONY; i++) {
|
||||
filters[i] = new OnePole;
|
||||
sounding[i] = -1;
|
||||
}
|
||||
/* This counts the number of sounding voices */
|
||||
numSounding = 0;
|
||||
|
||||
/* Print warning about aliasing if SRATE < 22050 */
|
||||
if (SRATE < 22050) {
|
||||
printf("\nWarning: Tabla is designed for sampling rates of\n");
|
||||
printf("22050 Hz or greater. You will likely encounter aliasing\n");
|
||||
printf("at the current sampling rate of %.0f Hz.\n\n", SRATE);
|
||||
}
|
||||
// This counts the number of sounding voices.
|
||||
nSounding = 0;
|
||||
}
|
||||
|
||||
Tabla :: ~Tabla()
|
||||
{
|
||||
int i;
|
||||
for ( i=0; i<numSounding-1; i++ ) delete waves[i];
|
||||
for ( i=0; i<nSounding-1; i++ ) delete waves[i];
|
||||
for ( i=0; i<TABLA_POLYPHONY; i++ ) delete filters[i];
|
||||
}
|
||||
|
||||
void Tabla :: noteOn(MY_FLOAT freq, MY_FLOAT amp)
|
||||
void Tabla :: noteOn(MY_FLOAT instrument, MY_FLOAT amplitude)
|
||||
{
|
||||
int i, notDone;
|
||||
int noteNum;
|
||||
int vel;
|
||||
char tempString[64];
|
||||
RawWvIn *tempWv;
|
||||
OnePole *tempFilt;
|
||||
char waveNames[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"
|
||||
};
|
||||
|
||||
noteNum = (int) freq;
|
||||
vel = (int) (amp * 127);
|
||||
|
||||
#if defined(_debug_)
|
||||
printf("NoteOn: %i vel=%i\n",noteNum,vel);
|
||||
#if defined(_STK_DEBUG_)
|
||||
cerr << "Tabla: NoteOn instrument = " << instrument << ", amplitude = " << amplitude << endl;
|
||||
#endif
|
||||
|
||||
notDone = -1;
|
||||
for (i=0;i<TABLA_POLYPHONY;i++) { /* Check first to see */
|
||||
if (sounding[i] == noteNum) notDone = i; /* if there's already */
|
||||
} /* one like this sounding */
|
||||
MY_FLOAT gain = amplitude;
|
||||
if ( amplitude > 1.0 ) {
|
||||
cerr << "Tabla: noteOn amplitude parameter is greater than 1.0!" << endl;
|
||||
gain = 1.0;
|
||||
}
|
||||
else if ( amplitude < 0.0 ) {
|
||||
cerr << "Tabla: noteOn amplitude parameter is less than 0.0!" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (notDone<0) { /* If not, then */
|
||||
if (numSounding == TABLA_POLYPHONY) { /* If we're already */
|
||||
delete waves[0]; /* at max polyphony, */
|
||||
filters[0]->clear(); /* then */
|
||||
tempWv = waves[0];
|
||||
tempFilt = filters[0];
|
||||
for (i=0;i<TABLA_POLYPHONY-1;i++) { /* preempt oldest */
|
||||
waves[i] = waves[i+1]; /* voice and */
|
||||
filters[i] = filters[i+1]; /* ripple all down */
|
||||
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 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((MY_FLOAT) 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();
|
||||
WvIn *tempWv = waves[0];
|
||||
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];
|
||||
}
|
||||
waves[TABLA_POLYPHONY-1] = tempWv;
|
||||
filters[TABLA_POLYPHONY-1] = tempFilt;
|
||||
} else {
|
||||
numSounding += 1; /* otherwise just add one */
|
||||
}
|
||||
else
|
||||
nSounding += 1;
|
||||
|
||||
sounding[numSounding-1] = noteNum; /* allocate new wave */
|
||||
strcpy(tempString,"rawwaves/");
|
||||
strcat(tempString,waveNames[noteNum]);
|
||||
waves[numSounding-1] = new RawWvIn(tempString, "oneshot");
|
||||
if (SRATE != 22050) {
|
||||
waves[numSounding-1]->setRate((MY_FLOAT) (22050.0/SRATE));
|
||||
}
|
||||
waves[numSounding-1]->normalize((MY_FLOAT) 0.4);
|
||||
filters[numSounding-1]->setPole((MY_FLOAT) 0.999 - ((MY_FLOAT) vel * NORM_7 * 0.6));
|
||||
filters[numSounding-1]->setGain(vel / (MY_FLOAT) 128.0);
|
||||
}
|
||||
else {
|
||||
waves[notDone]->reset();
|
||||
filters[notDone]->setPole((MY_FLOAT) 0.999 - ((MY_FLOAT) vel * NORM_7 * 0.6));
|
||||
filters[notDone]->setGain(vel / (MY_FLOAT) 128.0);
|
||||
sounding[nSounding-1] = noteNum;
|
||||
// Concatenate the STK RAWWAVE_PATH to the rawwave file
|
||||
char path[128];
|
||||
strcpy(path, "rawwaves/");
|
||||
strcat(path, tablaWaves[noteNum]);
|
||||
waves[nSounding-1] = new WvIn(path, TRUE);
|
||||
waves[nSounding-1]->normalize(0.4);
|
||||
filters[nSounding-1]->setPole((MY_FLOAT) 0.999 - (gain * 0.6) );
|
||||
filters[nSounding-1]->setGain( gain );
|
||||
}
|
||||
|
||||
#if defined(_debug_)
|
||||
printf("Number Sounding = %i\n",numSounding);
|
||||
for (i=0;i<numSounding;i++) printf(" %i ",sounding[i]);
|
||||
printf("\n");
|
||||
#if defined(_STK_DEBUG_)
|
||||
cerr << "Number Sounding = " << nSounding << endl;
|
||||
for (i=0; i<nSounding; i++) cerr << sounding[i] << " ";
|
||||
cerr << "\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
void Tabla :: noteOff(MY_FLOAT amplitude)
|
||||
{
|
||||
// Set all sounding wave filter gains low.
|
||||
int i = 0;
|
||||
while(i < nSounding) {
|
||||
filters[i++]->setGain( amplitude * 0.01 );
|
||||
}
|
||||
}
|
||||
|
||||
MY_FLOAT Tabla :: tick()
|
||||
{
|
||||
int j, i = 0;
|
||||
MY_FLOAT output = 0.0;
|
||||
OnePole *tempFilt;
|
||||
|
||||
while (i < numSounding) {
|
||||
output += filters[i]->tick(waves[i]->lastOut());
|
||||
if (waves[i]->informTick() == 1) {
|
||||
int j, i = 0;
|
||||
while (i < nSounding) {
|
||||
if ( waves[i]->isFinished() ) {
|
||||
delete waves[i];
|
||||
tempFilt = filters[i];
|
||||
|
||||
for (j=i;j<numSounding-1;j++) {
|
||||
// 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];
|
||||
@@ -146,10 +149,13 @@ MY_FLOAT Tabla :: tick()
|
||||
filters[j] = tempFilt;
|
||||
filters[j]->clear();
|
||||
sounding[j] = -1;
|
||||
numSounding -= 1;
|
||||
nSounding -= 1;
|
||||
i -= 1;
|
||||
}
|
||||
else
|
||||
output += filters[i]->tick( waves[i]->tick() );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user