mirror of
https://github.com/thestk/stk
synced 2026-02-07 01:36:16 +00:00
Version 3.1
This commit is contained in:
committed by
Stephen Sinclair
parent
868787a5f9
commit
4b6500d3de
@@ -7,10 +7,11 @@
|
||||
|
||||
BowTabl :: BowTabl()
|
||||
{
|
||||
offSet = (MY_FLOAT) 0.0; /* offset is a bias, really not needed unless */
|
||||
/* friction is different in each direction */
|
||||
slope = (MY_FLOAT) 0.1; /* controls width of friction pulse, */
|
||||
/* related to bowForce */
|
||||
/* offset is a bias, really not needed unless */
|
||||
/* friction is different in each direction */
|
||||
offSet = (MY_FLOAT) 0.0;
|
||||
slope = (MY_FLOAT) 0.1; /* controls width of friction pulse, */
|
||||
/* related to bowForce */
|
||||
}
|
||||
|
||||
BowTabl :: ~BowTabl()
|
||||
@@ -19,28 +20,33 @@ BowTabl :: ~BowTabl()
|
||||
|
||||
void BowTabl :: setOffset(MY_FLOAT aValue)
|
||||
{
|
||||
offSet = aValue;
|
||||
offSet = aValue;
|
||||
}
|
||||
|
||||
void BowTabl :: setSlope(MY_FLOAT aValue)
|
||||
{
|
||||
slope = aValue;
|
||||
slope = aValue;
|
||||
}
|
||||
|
||||
MY_FLOAT BowTabl :: lookup(MY_FLOAT sample) /* Perform Table Lookup */
|
||||
{ /* sample is differential */
|
||||
/* string vs. bow velocity */
|
||||
MY_FLOAT input;
|
||||
input = sample + offSet; /* add bias to sample */
|
||||
input *= slope; /* scale it */
|
||||
lastOutput = (MY_FLOAT) fabs((double) input) + (MY_FLOAT) 0.75; /* below min delta, friction = 1 */
|
||||
lastOutput = (MY_FLOAT) pow(lastOutput,(MY_FLOAT) -4.0);
|
||||
// if (lastOutput < 0.0 ) lastOutput = 0.0; /* minimum friction is 0.0 */
|
||||
if (lastOutput > 1.0 ) lastOutput = (MY_FLOAT) 1.0; /* maximum friction is 1.0 */
|
||||
return lastOutput;
|
||||
MY_FLOAT BowTabl :: lookup(MY_FLOAT sample)
|
||||
{
|
||||
return this->tick(sample);
|
||||
}
|
||||
|
||||
MY_FLOAT BowTabl :: tick(MY_FLOAT sample) /* Perform Table Lookup */
|
||||
{ /* sample is differential */
|
||||
/* string vs. bow velocity */
|
||||
MY_FLOAT input;
|
||||
input = sample + offSet; /* add bias to sample */
|
||||
input *= slope; /* scale it */
|
||||
lastOutput = (MY_FLOAT) fabs((double) input) + (MY_FLOAT) 0.75; /* below min delta, friction = 1 */
|
||||
lastOutput = (MY_FLOAT) pow(lastOutput,(MY_FLOAT) -4.0);
|
||||
// if (lastOutput < 0.0 ) lastOutput = 0.0; /* minimum friction is 0.0 */
|
||||
if (lastOutput > 1.0 ) lastOutput = (MY_FLOAT) 1.0; /* maximum friction is 1.0 */
|
||||
return lastOutput;
|
||||
}
|
||||
|
||||
MY_FLOAT BowTabl :: lastOut()
|
||||
{
|
||||
return lastOutput;
|
||||
return lastOutput;
|
||||
}
|
||||
|
||||
@@ -10,17 +10,18 @@
|
||||
|
||||
class BowTabl : public Object
|
||||
{
|
||||
protected:
|
||||
MY_FLOAT offSet;
|
||||
MY_FLOAT slope;
|
||||
MY_FLOAT lastOutput;
|
||||
public:
|
||||
BowTabl();
|
||||
~BowTabl();
|
||||
void setOffset(MY_FLOAT aValue);
|
||||
void setSlope(MY_FLOAT aValue);
|
||||
MY_FLOAT lookup(MY_FLOAT sample);
|
||||
MY_FLOAT lastOut();
|
||||
protected:
|
||||
MY_FLOAT offSet;
|
||||
MY_FLOAT slope;
|
||||
MY_FLOAT lastOutput;
|
||||
public:
|
||||
BowTabl();
|
||||
~BowTabl();
|
||||
void setOffset(MY_FLOAT aValue);
|
||||
void setSlope(MY_FLOAT aValue);
|
||||
MY_FLOAT lookup(MY_FLOAT sample);
|
||||
MY_FLOAT tick(MY_FLOAT sample);
|
||||
MY_FLOAT lastOut();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -61,7 +61,7 @@ void DLineA :: setDelay(MY_FLOAT lag)
|
||||
if (lag > length-1) { // if delay is too big,
|
||||
printf("DLineA: Delay length too big.\n");
|
||||
printf("Setting to maximum length of %ld.\n",length-1);
|
||||
outPointer = inPoint - 18.0; // force delay to max_length
|
||||
outPointer = inPoint + 1.0; // force delay to max_length
|
||||
}
|
||||
else if (lag < 0.1) {
|
||||
printf("DLineA: Delays < 0.1 not possible with current structure.\n");
|
||||
|
||||
@@ -58,8 +58,8 @@ extern char phonemes[32][4];
|
||||
|
||||
void FMVoices :: setFreq(MY_FLOAT frequency)
|
||||
{
|
||||
MY_FLOAT temp,temp2;
|
||||
int tempi,tempi2;
|
||||
MY_FLOAT temp, temp2 = 0.0;
|
||||
int tempi, tempi2 = 0;
|
||||
|
||||
if (currentVowel < 32) {
|
||||
tempi2 = currentVowel;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* This is based on some of the famous */
|
||||
/* Stanford CCRMA reverbs (NRev, KipRev) */
|
||||
/* all based on the the Chowning/Moorer/ */
|
||||
/* all based on the Chowning/Moorer/ */
|
||||
/* Schroeder reverberators, which use */
|
||||
/* networks of simple allpass and comb */
|
||||
/* delay filters. This particular */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* This is based on some of the famous */
|
||||
/* Stanford CCRMA reverbs (NRev, KipRev) */
|
||||
/* all based on the the Chowning/Moorer/ */
|
||||
/* all based on the Chowning/Moorer/ */
|
||||
/* Schroeder reverberators, which use */
|
||||
/* networks of simple allpass and comb */
|
||||
/* delay filters. This particular */
|
||||
|
||||
@@ -11,26 +11,33 @@
|
||||
|
||||
JetTabl :: JetTabl()
|
||||
{
|
||||
lastOutput = (MY_FLOAT) 0.0;
|
||||
lastOutput = (MY_FLOAT) 0.0;
|
||||
}
|
||||
|
||||
JetTabl :: ~JetTabl()
|
||||
{
|
||||
}
|
||||
|
||||
MY_FLOAT JetTabl :: lookup(MY_FLOAT sample) /* Perform "Table Lookup" */
|
||||
{ /* By Polynomial Calculation */
|
||||
lastOutput = sample *
|
||||
(sample*sample - (MY_FLOAT) 1.0); /* (x^3 - x) approximates sigmoid of jet */
|
||||
if (lastOutput > 1.0)
|
||||
lastOutput = (MY_FLOAT) 1.0; /* Saturation at +/- 1.0 */
|
||||
if (lastOutput < -1.0)
|
||||
lastOutput = (MY_FLOAT) -1.0;
|
||||
return lastOutput;
|
||||
MY_FLOAT JetTabl :: lookup(MY_FLOAT sample)
|
||||
{
|
||||
return this->tick(sample);
|
||||
}
|
||||
|
||||
MY_FLOAT JetTabl :: tick(MY_FLOAT sample)
|
||||
// Perform "Table Lookup"
|
||||
// By Polynomial Calculation
|
||||
{
|
||||
// (x^3 - x) approximates sigmoid of jet
|
||||
lastOutput = sample * (sample*sample - (MY_FLOAT) 1.0);
|
||||
if (lastOutput > 1.0)
|
||||
lastOutput = (MY_FLOAT) 1.0; // Saturation at +/- 1.0
|
||||
if (lastOutput < -1.0)
|
||||
lastOutput = (MY_FLOAT) -1.0;
|
||||
return lastOutput;
|
||||
}
|
||||
|
||||
MY_FLOAT JetTabl :: lastOut()
|
||||
{
|
||||
return lastOutput;
|
||||
return lastOutput;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,13 +14,14 @@
|
||||
|
||||
class JetTabl : public Object
|
||||
{
|
||||
protected:
|
||||
MY_FLOAT lastOutput;
|
||||
public:
|
||||
JetTabl();
|
||||
~JetTabl();
|
||||
MY_FLOAT lookup(MY_FLOAT deltaP);
|
||||
MY_FLOAT lastOut();
|
||||
protected:
|
||||
MY_FLOAT lastOutput;
|
||||
public:
|
||||
JetTabl();
|
||||
~JetTabl();
|
||||
MY_FLOAT lookup(MY_FLOAT deltaP);
|
||||
MY_FLOAT tick(MY_FLOAT deltaP);
|
||||
MY_FLOAT lastOut();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,67 +1,65 @@
|
||||
/**********************************************/
|
||||
/* Lip Filter Object by Perry R. Cook, 1995-96*/
|
||||
/* The lip of the brass player has dynamics */
|
||||
/* which are controlled by the mass, spring */
|
||||
/* constant, and damping of the lip. This */
|
||||
/* filter simulates that behavior and the */
|
||||
/* transmission/reflection properties as */
|
||||
/* well. See Cook TBone and HosePlayer */
|
||||
/* instruments and articles. */
|
||||
/**********************************************/
|
||||
/************************************************/
|
||||
/* Lip Filter Object by Perry R. Cook, 1995-96 */
|
||||
/* The lip of the brass player has dynamics */
|
||||
/* which are controlled by the mass, spring */
|
||||
/* constant, and damping of the lip. This */
|
||||
/* filter simulates that behavior and the */
|
||||
/* transmission/reflection properties as */
|
||||
/* well. See Cook TBone and HosePlayer */
|
||||
/* instruments and articles. */
|
||||
/************************************************/
|
||||
|
||||
#include "LipFilt.h"
|
||||
|
||||
LipFilt :: LipFilt()
|
||||
{
|
||||
MY_FLOAT coeffs[2];
|
||||
filter = new BiQuad;
|
||||
coeffs[0] = (MY_FLOAT) 0.0;
|
||||
coeffs[1] = (MY_FLOAT) 0.0;
|
||||
filter->setZeroCoeffs(coeffs);
|
||||
this->clear();
|
||||
MY_FLOAT coeffs[2];
|
||||
filter = new BiQuad;
|
||||
coeffs[0] = (MY_FLOAT) 0.0;
|
||||
coeffs[1] = (MY_FLOAT) 0.0;
|
||||
filter->setZeroCoeffs(coeffs);
|
||||
this->clear();
|
||||
}
|
||||
|
||||
LipFilt :: ~LipFilt()
|
||||
{
|
||||
delete filter;
|
||||
delete filter;
|
||||
}
|
||||
|
||||
void LipFilt :: clear()
|
||||
{
|
||||
filter->clear();
|
||||
lastOutput = (MY_FLOAT) 0.0;
|
||||
filter->clear();
|
||||
lastOutput = (MY_FLOAT) 0.0;
|
||||
}
|
||||
|
||||
void LipFilt :: setFreq(MY_FLOAT frequency)
|
||||
{
|
||||
MY_FLOAT coeffs[2];
|
||||
coeffs[0] = (MY_FLOAT) 2.0 * (MY_FLOAT) 0.997 *
|
||||
MY_FLOAT coeffs[2];
|
||||
coeffs[0] = (MY_FLOAT) 2.0 * (MY_FLOAT) 0.997 *
|
||||
(MY_FLOAT) cos(TWO_PI * frequency / SRATE); /* damping should change with */
|
||||
coeffs[1] = (MY_FLOAT) (-0.997 * 0.997); /* lip parameters, but not yet.*/
|
||||
filter->setPoleCoeffs(coeffs);
|
||||
filter->setGain((MY_FLOAT) 0.03);
|
||||
coeffs[1] = (MY_FLOAT) (-0.997 * 0.997); /* lip parameters, but not yet.*/
|
||||
filter->setPoleCoeffs(coeffs);
|
||||
filter->setGain((MY_FLOAT) 0.03);
|
||||
}
|
||||
|
||||
/* NOTE: Here we should add lip tension */
|
||||
/* settings based on Mass/Spring/Damping */
|
||||
/* Maybe in TookKit97 */
|
||||
/* NOTE: Here we should add lip tension */
|
||||
/* settings based on Mass/Spring/Damping */
|
||||
|
||||
MY_FLOAT LipFilt :: tick(MY_FLOAT mouthSample,MY_FLOAT boreSample)
|
||||
/* Perform "Table Lookup" By Polynomial Calculation */
|
||||
{
|
||||
MY_FLOAT temp;
|
||||
temp = mouthSample - boreSample; /* Differential pressure */
|
||||
temp = filter->tick(temp); /* Force -> position */
|
||||
temp = temp*temp; /* Simple position to area mapping */
|
||||
if (temp > 1.0) temp = (MY_FLOAT) 1.0; /* Saturation at + 1.0 */
|
||||
lastOutput = temp * mouthSample; /* Assume mouth input = area */
|
||||
lastOutput += ((MY_FLOAT) 1.0 - temp)
|
||||
* boreSample; /* and Bore reflection is compliment. */
|
||||
return lastOutput;
|
||||
MY_FLOAT temp;
|
||||
temp = mouthSample - boreSample; /* Differential pressure */
|
||||
temp = filter->tick(temp); /* Force -> position */
|
||||
temp = temp*temp; /* Simple position to area mapping */
|
||||
if (temp > 1.0) temp = (MY_FLOAT) 1.0; /* Saturation at + 1.0 */
|
||||
lastOutput = temp * mouthSample; /* Assume mouth input = area */
|
||||
lastOutput += ((MY_FLOAT) 1.0 - temp) * boreSample; /* and Bore reflection is compliment. */
|
||||
return lastOutput;
|
||||
}
|
||||
|
||||
MY_FLOAT LipFilt :: lastOut()
|
||||
{
|
||||
return lastOutput;
|
||||
return lastOutput;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
/**********************************************/
|
||||
/* Lip Filter Object by Perry R. Cook, 1995-96*/
|
||||
/* The lip of the brass player has dynamics */
|
||||
/* which are controlled by the mass, spring */
|
||||
/* constant, and damping of the lip. This */
|
||||
/* filter simulates that behavior and the */
|
||||
/* transmission/reflection properties as */
|
||||
/* well. See Cook TBone and HosePlayer */
|
||||
/* instruments and articles. */
|
||||
/**********************************************/
|
||||
/************************************************/
|
||||
/* Lip Filter Object by Perry R. Cook, 1995-96 */
|
||||
/* The lip of the brass player has dynamics */
|
||||
/* which are controlled by the mass, spring */
|
||||
/* constant, and damping of the lip. This */
|
||||
/* filter simulates that behavior and the */
|
||||
/* transmission/reflection properties as */
|
||||
/* well. See Cook TBone and HosePlayer */
|
||||
/* instruments and articles. */
|
||||
/************************************************/
|
||||
|
||||
#include "Object.h"
|
||||
#include "BiQuad.h"
|
||||
|
||||
class LipFilt : public Object
|
||||
{
|
||||
protected:
|
||||
BiQuad *filter;
|
||||
MY_FLOAT lastOutput;
|
||||
public:
|
||||
LipFilt();
|
||||
~LipFilt();
|
||||
void clear();
|
||||
void setFreq(MY_FLOAT frequency);
|
||||
MY_FLOAT tick(MY_FLOAT mouthSample,MY_FLOAT boreSample);
|
||||
MY_FLOAT lastOut();
|
||||
protected:
|
||||
BiQuad *filter;
|
||||
MY_FLOAT lastOutput;
|
||||
public:
|
||||
LipFilt();
|
||||
~LipFilt();
|
||||
void clear();
|
||||
void setFreq(MY_FLOAT frequency);
|
||||
MY_FLOAT tick(MY_FLOAT mouthSample,MY_FLOAT boreSample);
|
||||
MY_FLOAT lastOut();
|
||||
};
|
||||
|
||||
|
||||
@@ -18,26 +18,14 @@
|
||||
int outAHere = 0;
|
||||
|
||||
// Do OS dependent declarations and includes
|
||||
#if defined(__OS_IRIX_)
|
||||
|
||||
#if (defined(__OS_IRIX_) || defined(__OS_Linux_))
|
||||
#include <sys/types.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pid_t exit_thread;
|
||||
|
||||
#elif defined(__OS_Linux_)
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
|
||||
pthread_t exit_thread;
|
||||
|
||||
@@ -50,13 +38,9 @@ unsigned long exit_thread;
|
||||
|
||||
#endif
|
||||
|
||||
// The thread function definition protocols are slightly
|
||||
// different under Irix, Linux, and Windoze.
|
||||
#if defined(__OS_IRIX_)
|
||||
|
||||
void monitorStdin(void *)
|
||||
|
||||
#elif defined(__OS_Linux_)
|
||||
// The thread function protocols are slightly different
|
||||
// under Windoze ... but of course!
|
||||
#if (defined(__OS_IRIX_) || defined(__OS_Linux_))
|
||||
|
||||
void *monitorStdin(void *)
|
||||
|
||||
@@ -80,10 +64,17 @@ void monitorStdin(void *)
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined(__OS_IRIX_) || defined(__OS_Linux_))
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
#elif defined(__OS_Win_)
|
||||
_endthread();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void errorf(void) {
|
||||
void usage(void) {
|
||||
printf("useage: MD2SKINI <flag(s)>\n\n");
|
||||
printf(" With no arguments, MD2SKINI converts MIDI input to SKINI\n");
|
||||
printf(" format and sends the output directly to stdout.\n");
|
||||
@@ -95,23 +86,24 @@ void errorf(void) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void main(int argc,char *argv[])
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
long j, i = 1;
|
||||
MY_FLOAT byte2, byte3;
|
||||
int channel;
|
||||
int firstMessage = 1;
|
||||
int writeFileOut = 0;
|
||||
FILE *fileOut;
|
||||
FILE *fileOut = NULL;
|
||||
MIDIIO *controller;
|
||||
char hostName[256];
|
||||
char fileName[256];
|
||||
int useSocket = 0;
|
||||
int theSocket;
|
||||
int theSocket = 0;
|
||||
struct sockaddr_in saServer;
|
||||
static struct timeval timeout = {0, 10000}; // ten millisecond
|
||||
|
||||
if (argc>5) {
|
||||
errorf();
|
||||
usage();
|
||||
}
|
||||
|
||||
// Parse the command-line arguments.
|
||||
@@ -140,11 +132,11 @@ void main(int argc,char *argv[])
|
||||
break;
|
||||
|
||||
default:
|
||||
errorf();
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else errorf();
|
||||
else usage();
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -198,22 +190,14 @@ void main(int argc,char *argv[])
|
||||
}
|
||||
|
||||
// Setup the exit thread.
|
||||
#if defined(__OS_IRIX_)
|
||||
exit_thread = sproc(monitorStdin, PR_SALL);
|
||||
if (exit_thread == -1) {
|
||||
fprintf(stderr, "Unable to create exit thread ... aborting.\n");
|
||||
exit(0);
|
||||
}
|
||||
#elif defined(__OS_Linux_)
|
||||
int err = 0;
|
||||
err = pthread_create(&exit_thread, NULL, monitorStdin, NULL);
|
||||
if (err) {
|
||||
#if (defined(__OS_IRIX_) || defined(__OS_Linux_))
|
||||
if (pthread_create(&exit_thread, NULL, monitorStdin, NULL)) {
|
||||
fprintf(stderr, "Unable to create exit thread ... aborting.\n");
|
||||
exit(0);
|
||||
}
|
||||
#elif defined(__OS_Win_)
|
||||
exit_thread = _beginthread(monitorStdin, 0, NULL);
|
||||
if (exit_thread == -1) {
|
||||
if (exit_thread == -1) {
|
||||
fprintf(stderr, "Unable to create exit thread ... aborting.\n");
|
||||
exit(0);
|
||||
}
|
||||
@@ -380,11 +364,19 @@ void main(int argc,char *argv[])
|
||||
fflush(stdout);
|
||||
}
|
||||
memset(s, 0, sizeof(s));
|
||||
} else {
|
||||
// With Irix 5.3, you can no longer use the usleep()
|
||||
// function. And in Windoze, you can't use the select()
|
||||
// function to do timings. I love supporting multiple
|
||||
// platforms!
|
||||
#if defined(__OS_Win_)
|
||||
} else Sleep ( (DWORD) 2);
|
||||
Sleep ( (DWORD) 5);
|
||||
#else
|
||||
} else usleep( (unsigned long) 2000);
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 10000; // 0.01 seconds
|
||||
select(0, NULL, NULL, NULL, &timeout);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(s,"Exiting MD2SKINI process ... bye!\n");
|
||||
@@ -406,6 +398,7 @@ void main(int argc,char *argv[])
|
||||
fclose(fileOut);
|
||||
}
|
||||
delete controller;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,18 +33,18 @@ int readOffset;
|
||||
/* SGI MIDI INPUT */
|
||||
/*************************************/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <dmedia/midi.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <signal.h>
|
||||
|
||||
MDport inport;
|
||||
|
||||
MDevent *midiBuffer;
|
||||
|
||||
pid_t midi_input_pid;
|
||||
pthread_t midi_input_thread;
|
||||
|
||||
void midiInputThread(void *)
|
||||
void *midiInputThread(void *)
|
||||
{
|
||||
MDevent newMessage;
|
||||
int status;
|
||||
@@ -53,8 +53,9 @@ void midiInputThread(void *)
|
||||
mdReceive(inport, &newMessage, 1);
|
||||
status = (newMessage.msg[0] & MD_STATUSMASK);
|
||||
|
||||
// Ignore Active Sensing messages
|
||||
if (!((status & 0xff) == 0xfe || (status & 0xff) == 0xf8)) {
|
||||
// Ignore all system messages
|
||||
//if (!((status & 0xff) == 0xfe || (status & 0xff) == 0xf8)) {
|
||||
if (status != 0xf0) {
|
||||
midiBuffer[writeOffset] = newMessage;
|
||||
writeOffset++;
|
||||
|
||||
@@ -83,16 +84,15 @@ MIDIIO :: MIDIIO()
|
||||
readOffset = 0;
|
||||
writeOffset = 0;
|
||||
|
||||
midi_input_pid = sproc(midiInputThread, PR_SALL);
|
||||
if (midi_input_pid == -1) {
|
||||
fprintf(stderr, "unable to create MIDI input thread...aborting.\n");
|
||||
if (pthread_create(&midi_input_thread, NULL, midiInputThread, NULL)) {
|
||||
fprintf(stderr, "unable to create MIDI input thread ... aborting.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
MIDIIO :: ~MIDIIO()
|
||||
{
|
||||
kill (midi_input_pid, SIGKILL);
|
||||
pthread_cancel(midi_input_thread);
|
||||
mdClosePort(inport);
|
||||
delete [] midiBuffer;
|
||||
}
|
||||
|
||||
@@ -93,6 +93,8 @@ MY_FLOAT NRev :: lastOutputR()
|
||||
|
||||
MY_FLOAT NRev :: tick(MY_FLOAT input)
|
||||
{
|
||||
// FPU underflow checks seem to make things much
|
||||
// worse here, so I won't do them.
|
||||
MY_FLOAT temp,temp0,temp1,temp2,temp3;
|
||||
int i;
|
||||
|
||||
|
||||
@@ -9,12 +9,6 @@
|
||||
#include <libc.h>
|
||||
#endif
|
||||
|
||||
#if defined(__OS_Win_) /* For Windoze */
|
||||
#define ONE_OVER_RANDLIMIT 0.00006103516
|
||||
#else /* This is for Linux, NeXT and SGI */
|
||||
#define ONE_OVER_RANDLIMIT 0.00000000093132258
|
||||
#endif
|
||||
|
||||
Noise :: Noise() : Object()
|
||||
{
|
||||
lastOutput = (MY_FLOAT) 0.0;
|
||||
@@ -27,9 +21,9 @@ Noise :: ~Noise()
|
||||
MY_FLOAT Noise :: tick()
|
||||
{
|
||||
#if defined(__OS_Win_) /* For Windoze */
|
||||
lastOutput = (MY_FLOAT) (rand() - 16383);
|
||||
lastOutput = (MY_FLOAT) (rand() - (int)RANDLIMIT_OVER_TWO);
|
||||
#else /* This is for Linux, NeXT and SGI */
|
||||
lastOutput = (MY_FLOAT) random() - 1073741823.0;
|
||||
lastOutput = (MY_FLOAT) (random() - (int)RANDLIMIT_OVER_TWO);
|
||||
#endif
|
||||
|
||||
lastOutput *= (MY_FLOAT) ONE_OVER_RANDLIMIT;
|
||||
@@ -41,12 +35,3 @@ MY_FLOAT Noise :: lastOut()
|
||||
return lastOutput;
|
||||
}
|
||||
|
||||
/************ Test Main ************************/
|
||||
/*
|
||||
void main()
|
||||
{
|
||||
long i;
|
||||
Noise test;
|
||||
for (i=0;i<20;i++) printf("%lf\n",test.tick());
|
||||
}
|
||||
*/
|
||||
|
||||
40
STK/Object.h
40
STK/Object.h
@@ -26,27 +26,34 @@ class Object
|
||||
/* The OS type definitions are made in the Makefile */
|
||||
|
||||
#if defined(__OS_NeXT_) /* For NeXTStep - Black or White Hardware */
|
||||
// No special defines at this time
|
||||
#define RANDLIMIT 2147483647
|
||||
#elif defined(__OS_IRIX_) /* For SGI */
|
||||
#define __STK_REALTIME_
|
||||
#define RANDLIMIT 2147483647
|
||||
#elif defined(__OS_Linux_) /* For Linux */
|
||||
#define __STK_REALTIME_
|
||||
#define __OSS_API_ /* Use OSS API */
|
||||
#define __LITTLE_ENDIAN__
|
||||
#define RANDLIMIT 2147483647
|
||||
#elif defined(__OS_Win_) /* For WindowsXX or NT */
|
||||
#define __STK_REALTIME_
|
||||
#define __WINDS_API_ /* For DirectSound API */
|
||||
// #define __WINMM_API_ /* For Win MM API */
|
||||
#define __LITTLE_ENDIAN__
|
||||
#define RANDLIMIT 32767
|
||||
#endif
|
||||
|
||||
/* Real-time output buffer size. If clicks are occuring in the
|
||||
* output sound stream, a larger buffer size may help. Larger
|
||||
* buffer sizes, however, produce more latency between input and
|
||||
* output.
|
||||
* NOTE FOR WINDOZE USERS: Given inherent delays in the sound
|
||||
* output mechanism under Windoze, there is a trade-off between
|
||||
* smoothness of fast SKINI parameter updates and input/output
|
||||
/* Real-time audio input and output buffer size. The value of
|
||||
* this buffer should be an integer multiple of the number of
|
||||
* channels your application plans to support, in order that
|
||||
* multi-channel data is not split across multiple buffers. If
|
||||
* clicks are occuring in the input or output sound stream, a
|
||||
* larger buffer size may help. Larger buffer sizes, however,
|
||||
* produce more latency between input and output.
|
||||
*
|
||||
* NOTE FOR WINDOZE USERS: Given inherent delays in the audio
|
||||
* input and output mechanism under Windoze, there is a trade-off
|
||||
* between smoothness of fast SKINI parameter updates and input/output
|
||||
* latency as discussed above. You can use buffer sizes as low
|
||||
* as 100 (maybe lower) for delay critical applications, but in
|
||||
* this case SKINI parameter updates will be clumped together
|
||||
@@ -93,6 +100,23 @@ class Object
|
||||
#define ONE_OVER_TWO_PI (MY_FLOAT) 0.15915494309
|
||||
#define SQRT_TWO 1.414213562
|
||||
|
||||
/* Useful random number generator values */
|
||||
#define ONE_OVER_RANDLIMIT (1.0/RANDLIMIT)
|
||||
#define RANDLIMIT_OVER_TWO (int)(RANDLIMIT/2)
|
||||
|
||||
/* FPU Underflow Limit
|
||||
* The IEEE specification doesn't call for automatic
|
||||
* zeroing of floating-point values when they reach
|
||||
* their numerical limits. Instead, most processors
|
||||
* switch to a much more computation-intensive mode
|
||||
* when a FPU underflow occurs. We set a lower limit
|
||||
* here for our own (not so efficient) checks. Here's
|
||||
* a useful macro for limiting MY_FLOATs. At this time,
|
||||
* no FPU underflow checks are being performed.
|
||||
*/
|
||||
#define FPU_UFLOW_LIMIT 0.0000000001
|
||||
#define LIMIT_MY_FLOAT(j) ((((j)<(MY_FLOAT)FPU_UFLOW_LIMIT)&&((j)>(MY_FLOAT)-FPU_UFLOW_LIMIT))?(MY_FLOAT)0.0:(j))
|
||||
|
||||
/* States for Envelopes, etc. */
|
||||
#define ATTACK 0
|
||||
#define DECAY 1
|
||||
|
||||
@@ -49,10 +49,11 @@ void Plucked :: pluck(MY_FLOAT amplitude)
|
||||
long i;
|
||||
pickFilt->setPole((MY_FLOAT) 0.999 - (amplitude * (MY_FLOAT) 0.15));
|
||||
pickFilt->setGain(amplitude * (MY_FLOAT) 0.5);
|
||||
for (i=0;i<length;i++)
|
||||
delayLine->tick(delayLine->lastOut() * (MY_FLOAT) 0.6 /* fill delay with noise */
|
||||
+ pickFilt->tick(noise->tick())); /* additively with current */
|
||||
/* contents */
|
||||
for (i=0;i<length;i++)
|
||||
// fill delay with noise additively with current contents
|
||||
delayLine->tick(delayLine->lastOut() * (MY_FLOAT) 0.6
|
||||
+ pickFilt->tick(noise->tick()));
|
||||
|
||||
}
|
||||
|
||||
void Plucked :: noteOn(MY_FLOAT freq, MY_FLOAT amp)
|
||||
|
||||
@@ -21,8 +21,9 @@ class RTDuplex : public Object
|
||||
{
|
||||
protected:
|
||||
RTSoundIO *soundIO;
|
||||
short indata[RT_BUFFER_SIZE];
|
||||
short outdata[RT_BUFFER_SIZE];
|
||||
// Add an extra 10 samples to indata[] and outdata[] just to be safe
|
||||
short indata[RT_BUFFER_SIZE+10];
|
||||
short outdata[RT_BUFFER_SIZE+10];
|
||||
long readCounter;
|
||||
long writeCounter;
|
||||
int channels;
|
||||
|
||||
@@ -382,6 +382,8 @@ int RTSoundIO :: recordBuffer(short *buf, int bufsize)
|
||||
* capabilities.
|
||||
*/
|
||||
|
||||
#define DS_WRITE_METHOD 1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
RTSoundIO :: RTSoundIO(MY_FLOAT srate, int channels, char *mode)
|
||||
@@ -414,8 +416,8 @@ RTSoundIO :: RTSoundIO(MY_FLOAT srate, int channels, char *mode)
|
||||
// Define a maximum distance that the write pointer is
|
||||
// allowed to lead safePos. The size of this zone is
|
||||
// fairly critical to the behavior of this scheme. The
|
||||
// value below is set for a 10 millisecond region.
|
||||
zoneSize = (DWORD) (0.01 * srate * sizeof(short)); // bytes
|
||||
// value below is set for a 15 millisecond region.
|
||||
zoneSize = (DWORD) (0.015 * srate * sizeof(short)); // bytes
|
||||
|
||||
// Create the DS object
|
||||
if ((result = DirectSoundCreate(NULL, &lpDirectSound, NULL)) != DS_OK) {
|
||||
@@ -651,110 +653,110 @@ int RTSoundIO :: playBuffer(short *buf, int bufsize)
|
||||
hr = lpDSBuffer->GetCurrentPosition(&playPos, &safePos);
|
||||
if (hr != DS_OK) return -1;
|
||||
|
||||
// METHOD 1: Keep write pointer in front of read pointer.
|
||||
//
|
||||
// Microsloth says that the safePos is about 15 ms ahead of
|
||||
// playPos. I think this figure is somewhat hardware related,
|
||||
// especially if you are writing to the primary buffer. With
|
||||
// my shit-blaster 16, I found the safePos to be about 10 ms
|
||||
// ahead of playPos. If you really need to reduce delay, you
|
||||
// can try moving your "safePos" closer to the play pointer.
|
||||
// You'll be treading on dangerous ground, but then again,
|
||||
// you're obviously using Windoze so you're already familiar
|
||||
// with such uncertainty! I've been able to lop off 2-5 ms
|
||||
// in some circumstances.
|
||||
//static DWORD backup = (DWORD) (0.005 * SRATE * sizeof(short));
|
||||
//safePos = (safePos + dwDSBufSize - backup) % dwDSBufSize;
|
||||
// METHOD 1: Keep write pointer in front of read pointer.
|
||||
//
|
||||
// Microsloth says that the safePos is about 15 ms ahead of
|
||||
// playPos. I think this figure is somewhat hardware related,
|
||||
// especially if you are writing to the primary buffer. With
|
||||
// my shit-blaster 16, I found the safePos to be about 10 ms
|
||||
// ahead of playPos. If you really need to reduce delay, you
|
||||
// can try moving your "safePos" closer to the play pointer.
|
||||
// You'll be treading on dangerous ground, but then again,
|
||||
// you're obviously using Windoze so you're already familiar
|
||||
// with such uncertainty! I've been able to lop off 2-5 ms
|
||||
// in some circumstances.
|
||||
//static DWORD backup = (DWORD) (0.005 * SRATE * sizeof(short));
|
||||
//safePos = (safePos + dwDSBufSize - backup) % dwDSBufSize;
|
||||
|
||||
// Assume that the next write position is always in front
|
||||
// of safePos. If not, the write pointer must have wrapped.
|
||||
// NOTE: If safePos somehow gets ahead of the write pointer,
|
||||
// then an underrun has occurred and there's not much we can
|
||||
// do anyway.
|
||||
DWORD deltaPos;
|
||||
if( safePos > nextWritePos )
|
||||
deltaPos = nextWritePos + dwDSBufSize - safePos;
|
||||
else
|
||||
deltaPos = nextWritePos - safePos;
|
||||
// Assume that the next write position is always in front
|
||||
// of safePos. If not, the write pointer must have wrapped.
|
||||
// NOTE: If safePos somehow gets ahead of the write pointer,
|
||||
// then an underrun has occurred and there's not much we can
|
||||
// do anyway.
|
||||
DWORD deltaPos;
|
||||
if( safePos > nextWritePos )
|
||||
deltaPos = nextWritePos + dwDSBufSize - safePos;
|
||||
else
|
||||
deltaPos = nextWritePos - safePos;
|
||||
|
||||
// Check whether the write pointer is in the allowed region.
|
||||
while ( deltaPos > zoneSize ) {
|
||||
// If we are here, then we must wait until the write pointer
|
||||
// is in the allowed region. For this, we can either
|
||||
// continuously check the pointer positions until they are
|
||||
// OK or we can use the Sleep() function to pause operations
|
||||
// for a certain amount of time. Use of the Sleep() function
|
||||
// would seem to be the better choice, however, there are
|
||||
// reports that Sleep() often "sleeps" for much longer than
|
||||
// requested. I'll let you choose which method to use.
|
||||
static int sleep = 1; // 1 = sleep, 0 = don't sleep
|
||||
// Check whether the write pointer is in the allowed region.
|
||||
while ( deltaPos > zoneSize ) {
|
||||
// If we are here, then we must wait until the write pointer
|
||||
// is in the allowed region. For this, we can either
|
||||
// continuously check the pointer positions until they are
|
||||
// OK or we can use the Sleep() function to pause operations
|
||||
// for a certain amount of time. Use of the Sleep() function
|
||||
// would seem to be the better choice, however, there are
|
||||
// reports that Sleep() often "sleeps" for much longer than
|
||||
// requested. I'll let you choose which method to use.
|
||||
static int sleep = 1; // 1 = sleep, 0 = don't sleep
|
||||
|
||||
if (sleep) {
|
||||
// Sleep until safePos catches up. Calculate number of
|
||||
// milliseconds to wait as:
|
||||
// time = distance * (milliseconds/second) * fudgefactor /
|
||||
// ((bytes/sample) * (samples/second))
|
||||
// A "fudgefactor" less than 1 is used because it was found
|
||||
// that sleeping too long was MUCH worse than sleeping for
|
||||
// several shorter periods.
|
||||
DWORD millis = (DWORD) ((deltaPos * 200.0) / ( sizeof(short) * SRATE));
|
||||
if (sleep) {
|
||||
// Sleep until safePos catches up. Calculate number of
|
||||
// milliseconds to wait as:
|
||||
// time = distance * (milliseconds/second) * fudgefactor /
|
||||
// ((bytes/sample) * (samples/second))
|
||||
// A "fudgefactor" less than 1 is used because it was found
|
||||
// that sleeping too long was MUCH worse than sleeping for
|
||||
// several shorter periods.
|
||||
DWORD millis = (DWORD) ((deltaPos * 200.0) / ( sizeof(short) * SRATE));
|
||||
|
||||
// Sleep for that long
|
||||
Sleep( millis );
|
||||
}
|
||||
// Sleep for that long
|
||||
Sleep( millis );
|
||||
}
|
||||
|
||||
// Wake up, find out where we are now
|
||||
hr = lpDSBuffer->GetCurrentPosition( &playPos, &safePos );
|
||||
if( hr != DS_OK ) return -1;
|
||||
// Wake up, find out where we are now
|
||||
hr = lpDSBuffer->GetCurrentPosition( &playPos, &safePos );
|
||||
if( hr != DS_OK ) return -1;
|
||||
|
||||
// Backup safePos? (See above)
|
||||
//safePos = (safePos + dwDSBufSize - backup) % dwDSBufSize;
|
||||
// Backup safePos? (See above)
|
||||
//safePos = (safePos + dwDSBufSize - backup) % dwDSBufSize;
|
||||
|
||||
if( safePos > nextWritePos )
|
||||
deltaPos = nextWritePos + dwDSBufSize - safePos;
|
||||
else
|
||||
deltaPos = nextWritePos - safePos;
|
||||
}
|
||||
// End of Method 1
|
||||
if( safePos > nextWritePos )
|
||||
deltaPos = nextWritePos + dwDSBufSize - safePos;
|
||||
else
|
||||
deltaPos = nextWritePos - safePos;
|
||||
}
|
||||
// End of Method 1
|
||||
|
||||
/*
|
||||
// METHOD 2: Keep write region behind of play pointer.
|
||||
if( playPos < nextWritePos ) playPos += dwDSBufSize; // unwrap offset
|
||||
DWORD endWrite = nextWritePos + bufsize * sizeof(short);
|
||||
/*
|
||||
// METHOD 2: Keep write region behind of play pointer.
|
||||
if( playPos < nextWritePos ) playPos += dwDSBufSize; // unwrap offset
|
||||
DWORD endWrite = nextWritePos + bufsize * sizeof(short);
|
||||
|
||||
// Check whether the write region is behind the play pointer.
|
||||
while ( playPos < endWrite ) {
|
||||
// If we are here, then we must wait until the play pointer
|
||||
// gets beyond the write region. For this, we can either
|
||||
// continuously check the pointer positions until they are
|
||||
// OK or we can use the Sleep() function to pause operations
|
||||
// for a certain amount of time. Use of the Sleep() function
|
||||
// would seem to be the better choice, however, there are
|
||||
// reports that Sleep() often "sleeps" for much longer than
|
||||
// requested. I'll let you choose which method to use.
|
||||
static int sleep = 1; // 1 = sleep, 0 = don't sleep
|
||||
// Check whether the write region is behind the play pointer.
|
||||
while ( playPos < endWrite ) {
|
||||
// If we are here, then we must wait until the play pointer
|
||||
// gets beyond the write region. For this, we can either
|
||||
// continuously check the pointer positions until they are
|
||||
// OK or we can use the Sleep() function to pause operations
|
||||
// for a certain amount of time. Use of the Sleep() function
|
||||
// would seem to be the better choice, however, there are
|
||||
// reports that Sleep() often "sleeps" for much longer than
|
||||
// requested. I'll let you choose which method to use.
|
||||
static int sleep = 1; // 1 = sleep, 0 = don't sleep
|
||||
|
||||
if (sleep) {
|
||||
// Sleep until safePos catches up. Calculate number of
|
||||
// milliseconds to wait as:
|
||||
// time = distance * (milliseconds/second) * fudgefactor /
|
||||
// ((bytes/sample) * (samples/second))
|
||||
// A "fudgefactor" less than 1 is used because it was found
|
||||
// that sleeping too long was MUCH worse than sleeping for
|
||||
// several shorter periods.
|
||||
DWORD millis = (DWORD) (((endWrite - playPos) * 200.0) / ( sizeof(short) * SRATE));
|
||||
if (sleep) {
|
||||
// Sleep until safePos catches up. Calculate number of
|
||||
// milliseconds to wait as:
|
||||
// time = distance * (milliseconds/second) * fudgefactor /
|
||||
// ((bytes/sample) * (samples/second))
|
||||
// A "fudgefactor" less than 1 is used because it was found
|
||||
// that sleeping too long was MUCH worse than sleeping for
|
||||
// several shorter periods.
|
||||
DWORD millis = (DWORD) (((endWrite - playPos) * 200.0) / ( sizeof(short) * SRATE));
|
||||
|
||||
// Sleep for that long
|
||||
Sleep( millis );
|
||||
}
|
||||
// Sleep for that long
|
||||
Sleep( millis );
|
||||
}
|
||||
|
||||
// Wake up, find out where we are now
|
||||
hr = lpDSBuffer->GetCurrentPosition( &playPos, &safePos );
|
||||
if( hr != DS_OK ) return -1;
|
||||
if( playPos < nextWritePos ) playPos += dwDSBufSize; // unwrap offset
|
||||
}
|
||||
// End of Method 2.
|
||||
*/
|
||||
// Wake up, find out where we are now
|
||||
hr = lpDSBuffer->GetCurrentPosition( &playPos, &safePos );
|
||||
if( hr != DS_OK ) return -1;
|
||||
if( playPos < nextWritePos ) playPos += dwDSBufSize; // unwrap offset
|
||||
}
|
||||
// End of Method 2.
|
||||
*/
|
||||
|
||||
// Lock free space in the DS
|
||||
hr = lpDSBuffer->Lock (nextWritePos, bufsize * sizeof(short), &lpbuf1, &dwsize1, &lpbuf2, &dwsize2, 0);
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
RTWvIn :: RTWvIn(MY_FLOAT srate, short chans)
|
||||
{
|
||||
soundIO = new RTSoundIO(srate, chans, "record");
|
||||
length = RT_BUFFER_SIZE;
|
||||
channels = chans;
|
||||
length = RT_BUFFER_SIZE/channels;
|
||||
data = 0;
|
||||
rtdata = (short *) new short[channels*(RT_BUFFER_SIZE+1)];
|
||||
rtdata = (short *) new short[RT_BUFFER_SIZE+channels];
|
||||
|
||||
this->getMoreData();
|
||||
|
||||
@@ -78,8 +78,8 @@ void RTWvIn :: setLooping(int aLoopStatus)
|
||||
|
||||
void RTWvIn :: getMoreData()
|
||||
{
|
||||
soundIO->recordBuffer(rtdata,(RT_BUFFER_SIZE)*channels);
|
||||
long temp = channels*(RT_BUFFER_SIZE);
|
||||
soundIO->recordBuffer(rtdata,RT_BUFFER_SIZE);
|
||||
long temp = RT_BUFFER_SIZE;
|
||||
for (int i=0;i<channels;i++) {
|
||||
rtdata[temp] = rtdata[temp-channels];
|
||||
temp++;
|
||||
|
||||
@@ -19,7 +19,8 @@ class RTWvOut : public WvOut
|
||||
{
|
||||
protected:
|
||||
RTSoundIO *soundIO;
|
||||
short data[RT_BUFFER_SIZE];
|
||||
// Add an extra 10 samples to data[] just to be safe
|
||||
short data[RT_BUFFER_SIZE+10];
|
||||
long counter;
|
||||
int channels;
|
||||
public:
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
ReedTabl :: ReedTabl() : Object()
|
||||
{
|
||||
offSet = (MY_FLOAT) 0.6; /* Offset is a bias, related to reed rest position */
|
||||
slope = (MY_FLOAT) -0.8; /* Slope corresponds loosely to reed stiffness */
|
||||
offSet = (MY_FLOAT) 0.6; /* Offset is a bias, related to reed rest position */
|
||||
slope = (MY_FLOAT) -0.8; /* Slope corresponds loosely to reed stiffness */
|
||||
}
|
||||
|
||||
ReedTabl :: ~ReedTabl()
|
||||
@@ -21,22 +21,27 @@ ReedTabl :: ~ReedTabl()
|
||||
|
||||
void ReedTabl :: setOffset(MY_FLOAT aValue)
|
||||
{
|
||||
offSet = aValue; /* Offset is a bias, related to reed rest position */
|
||||
offSet = aValue; /* Offset is a bias, related to reed rest position */
|
||||
}
|
||||
|
||||
void ReedTabl :: setSlope(MY_FLOAT aValue)
|
||||
{
|
||||
slope = aValue; /* Slope corresponds loosely to reed stiffness */
|
||||
slope = aValue; /* Slope corresponds loosely to reed stiffness */
|
||||
}
|
||||
|
||||
MY_FLOAT ReedTabl :: lookup(MY_FLOAT deltaP)
|
||||
{
|
||||
return this->tick(deltaP);
|
||||
}
|
||||
|
||||
MY_FLOAT ReedTabl :: tick(MY_FLOAT deltaP)
|
||||
/* Perform "Table Lookup" by direct clipped */
|
||||
/* linear function calculation */
|
||||
{ /* deltaP is differential reed pressure */
|
||||
lastOutput = offSet + (slope * deltaP); /* compute basic non-linearity */
|
||||
if (lastOutput > 1.0) lastOutput = (MY_FLOAT) 1.0; /* if other way, reed slams shut */
|
||||
if (lastOutput < -1.0) lastOutput = (MY_FLOAT) -1.0; /* if all the way open, acts like open end */
|
||||
return lastOutput;
|
||||
lastOutput = offSet + (slope * deltaP); /* compute basic non-linearity */
|
||||
if (lastOutput > 1.0) lastOutput = (MY_FLOAT) 1.0; /* if other way, reed slams shut */
|
||||
if (lastOutput < -1.0) lastOutput = (MY_FLOAT) -1.0; /* if all the way open, acts like open end */
|
||||
return lastOutput;
|
||||
}
|
||||
|
||||
MY_FLOAT ReedTabl :: lastOut()
|
||||
|
||||
@@ -13,17 +13,18 @@
|
||||
|
||||
class ReedTabl : public Object
|
||||
{
|
||||
protected:
|
||||
MY_FLOAT offSet;
|
||||
MY_FLOAT slope;
|
||||
MY_FLOAT lastOutput;
|
||||
public:
|
||||
ReedTabl();
|
||||
~ReedTabl();
|
||||
void setOffset(MY_FLOAT aValue);
|
||||
void setSlope(MY_FLOAT aValue);
|
||||
MY_FLOAT lookup(MY_FLOAT deltaP);
|
||||
MY_FLOAT lastOut();
|
||||
protected:
|
||||
MY_FLOAT offSet;
|
||||
MY_FLOAT slope;
|
||||
MY_FLOAT lastOutput;
|
||||
public:
|
||||
ReedTabl();
|
||||
~ReedTabl();
|
||||
void setOffset(MY_FLOAT aValue);
|
||||
void setSlope(MY_FLOAT aValue);
|
||||
MY_FLOAT lookup(MY_FLOAT deltaP);
|
||||
MY_FLOAT tick(MY_FLOAT deltaP);
|
||||
MY_FLOAT lastOut();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,10 @@ Reverb :: Reverb()
|
||||
{
|
||||
}
|
||||
|
||||
Reverb :: ~Reverb()
|
||||
{
|
||||
}
|
||||
|
||||
MY_FLOAT Reverb :: tick(MY_FLOAT sample)
|
||||
{
|
||||
printf("Warning: Using virtual function Reverb :: tick()\n");
|
||||
|
||||
@@ -14,10 +14,11 @@
|
||||
class Reverb : public Object
|
||||
{
|
||||
public:
|
||||
Reverb();
|
||||
Reverb();
|
||||
virtual ~Reverb();
|
||||
virtual MY_FLOAT tick(MY_FLOAT sample);
|
||||
virtual void setEffectMix(MY_FLOAT mix);
|
||||
int isprime(int val);
|
||||
int isprime(int val);
|
||||
};
|
||||
|
||||
#endif // defined(__Reverb_h)
|
||||
|
||||
@@ -140,7 +140,7 @@ long SKINI11 :: parseThis(char* aString)
|
||||
int somePointrs[__SK_MAX_FIELDS_];
|
||||
|
||||
temp = nextChar(aString);
|
||||
if (which = ignore(aString[temp])) {
|
||||
if ((which = ignore(aString[temp]))) {
|
||||
if (which == 2) printf("// CommentLine: %s\n",aString);
|
||||
messageType = 0;
|
||||
return messageType;
|
||||
|
||||
153
STK/Shakers.cpp
153
STK/Shakers.cpp
@@ -60,34 +60,39 @@ MY_FLOAT noise_tick() // Return random MY_FLOAT float between -1.0 and 1.0
|
||||
/************************* MARACA *****************************/
|
||||
#define MARA_SOUND_DECAY 0.95
|
||||
#define MARA_SYSTEM_DECAY 0.999
|
||||
#define MARA_GAIN 25.0
|
||||
//#define MARA_GAIN 25.0
|
||||
#define MARA_GAIN 20.0
|
||||
#define MARA_NUM_BEANS 25
|
||||
#define MARA_CENTER_FREQ 3200.0
|
||||
#define MARA_RESON 0.96
|
||||
/*********************** SEKERE *****************************/
|
||||
#define SEKE_SOUND_DECAY 0.96
|
||||
#define SEKE_SYSTEM_DECAY 0.999
|
||||
#define SEKE_GAIN 30.0
|
||||
//#define SEKE_GAIN 30.0
|
||||
#define SEKE_GAIN 20.0
|
||||
#define SEKE_NUM_BEANS 64
|
||||
#define SEKE_CENTER_FREQ 5500.0
|
||||
#define SEKE_RESON 0.6
|
||||
/*********************** SANDPAPER **************************/
|
||||
#define SANDPAPR_SOUND_DECAY 0.999
|
||||
#define SANDPAPR_SYSTEM_DECAY 0.999
|
||||
#define SANDPAPR_GAIN 1.0
|
||||
//#define SANDPAPR_GAIN 1.0
|
||||
#define SANDPAPR_GAIN 0.5
|
||||
#define SANDPAPR_NUM_GRAINS 128
|
||||
#define SANDPAPR_CENTER_FREQ 4500.0
|
||||
#define SANDPAPR_RESON 0.6
|
||||
/************************ CABASA *****************************/
|
||||
#define CABA_SOUND_DECAY 0.96
|
||||
#define CABA_SYSTEM_DECAY 0.997
|
||||
#define CABA_GAIN 150.0
|
||||
//#define CABA_GAIN 150.0
|
||||
#define CABA_GAIN 40.0
|
||||
#define CABA_NUM_BEADS 512
|
||||
#define CABA_CENTER_FREQ 3000.0
|
||||
#define CABA_RESON 0.7
|
||||
/************************ Bamboo Wind Chimes *****************/
|
||||
#define BAMB_SOUND_DECAY 0.95
|
||||
#define BAMB_SYSTEM_DECAY 0.99995
|
||||
//#define BAMB_SYSTEM_DECAY 0.99995
|
||||
#define BAMB_SYSTEM_DECAY 0.9999
|
||||
#define BAMB_GAIN 2.0
|
||||
#define BAMB_NUM_TUBES 1.25
|
||||
#define BAMB_CENTER_FREQ0 2800.0
|
||||
@@ -96,9 +101,11 @@ MY_FLOAT noise_tick() // Return random MY_FLOAT float between -1.0 and 1.0
|
||||
#define BAMB_RESON 0.995
|
||||
/******************* Water Drops ****************************/
|
||||
#define WUTR_SOUND_DECAY 0.95
|
||||
#define WUTR_SYSTEM_DECAY 0.999
|
||||
//#define WUTR_SYSTEM_DECAY 0.999
|
||||
#define WUTR_SYSTEM_DECAY 0.996
|
||||
#define WUTR_GAIN 1.0
|
||||
#define WUTR_NUM_SOURCES 4
|
||||
//#define WUTR_NUM_SOURCES 4
|
||||
#define WUTR_NUM_SOURCES 10
|
||||
#define WUTR_CENTER_FREQ0 450.0
|
||||
#define WUTR_CENTER_FREQ1 600.0
|
||||
#define WUTR_CENTER_FREQ2 750.0
|
||||
@@ -107,7 +114,8 @@ MY_FLOAT noise_tick() // Return random MY_FLOAT float between -1.0 and 1.0
|
||||
/****************** TAMBOURINE *****************************/
|
||||
#define TAMB_SOUND_DECAY 0.95
|
||||
#define TAMB_SYSTEM_DECAY 0.9985
|
||||
#define TAMB_GAIN 10.0
|
||||
//#define TAMB_GAIN 10.0
|
||||
#define TAMB_GAIN 5.0
|
||||
#define TAMB_NUM_TIMBRELS 32
|
||||
#define TAMB_SHELL_FREQ 2300
|
||||
#define TAMB_SHELL_GAIN 0.1
|
||||
@@ -118,7 +126,8 @@ MY_FLOAT noise_tick() // Return random MY_FLOAT float between -1.0 and 1.0
|
||||
/********************** SLEIGHBELLS *************************/
|
||||
#define SLEI_SOUND_DECAY 0.97
|
||||
#define SLEI_SYSTEM_DECAY 0.9994
|
||||
#define SLEI_GAIN 2.0
|
||||
//#define SLEI_GAIN 2.0
|
||||
#define SLEI_GAIN 1.0
|
||||
#define SLEI_NUM_BELLS 32
|
||||
#define SLEI_CYMB_FREQ0 2500
|
||||
#define SLEI_CYMB_FREQ1 5300
|
||||
@@ -145,7 +154,8 @@ MY_FLOAT noise_tick() // Return random MY_FLOAT float between -1.0 and 1.0
|
||||
/************************ COKECAN **************************/
|
||||
#define COKECAN_SOUND_DECAY 0.97
|
||||
#define COKECAN_SYSTEM_DECAY 0.999
|
||||
#define COKECAN_GAIN 1.0
|
||||
//#define COKECAN_GAIN 1.0
|
||||
#define COKECAN_GAIN 0.8
|
||||
#define COKECAN_NUM_PARTS 48
|
||||
#define COKECAN_HELMFREQ 370
|
||||
#define COKECAN_HELM_RES 0.99
|
||||
@@ -169,7 +179,8 @@ MY_FLOAT noise_tick() // Return random MY_FLOAT float between -1.0 and 1.0
|
||||
/************************ Crunch1 ***************************/
|
||||
#define CRUNCH1_SOUND_DECAY 0.95
|
||||
#define CRUNCH1_SYSTEM_DECAY 0.99806
|
||||
#define CRUNCH1_GAIN 30.0
|
||||
//#define CRUNCH1_GAIN 30.0
|
||||
#define CRUNCH1_GAIN 20.0
|
||||
#define CRUNCH1_NUM_BEADS 7
|
||||
#define CRUNCH1_CENTER_FREQ 800.0
|
||||
#define CRUNCH1_RESON 0.95
|
||||
@@ -270,12 +281,16 @@ int Shakers :: setFreqAndReson(int which, MY_FLOAT freq, MY_FLOAT reson) {
|
||||
|
||||
int Shakers :: setupNum(int inst)
|
||||
{
|
||||
int i;
|
||||
int i, rv = 0;
|
||||
MY_FLOAT temp;
|
||||
|
||||
if (inst==1) { // cabasa_setup();
|
||||
rv = inst;
|
||||
num_objects = CABA_NUM_BEADS;
|
||||
defObjs[inst] = CABA_NUM_BEADS;
|
||||
setDecays(CABA_SOUND_DECAY, CABA_SYSTEM_DECAY);
|
||||
defDecays[inst] = CABA_SYSTEM_DECAY;
|
||||
decayScale[inst] = 0.97;
|
||||
num_freqs = 1;
|
||||
baseGain = CABA_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -285,8 +300,12 @@ int Shakers :: setupNum(int inst)
|
||||
setFinalZs(1.0,-1.0,0.0);
|
||||
}
|
||||
else if (inst==2) { // sekere_setup();
|
||||
rv = inst;
|
||||
num_objects = SEKE_NUM_BEANS;
|
||||
defObjs[inst] = SEKE_NUM_BEANS;
|
||||
this->setDecays(SEKE_SOUND_DECAY,SEKE_SYSTEM_DECAY);
|
||||
defDecays[inst] = SEKE_SYSTEM_DECAY;
|
||||
decayScale[inst] = 0.94;
|
||||
num_freqs = 1;
|
||||
baseGain = SEKE_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -296,8 +315,12 @@ int Shakers :: setupNum(int inst)
|
||||
this->setFinalZs(1.0, 0.0, -1.0);
|
||||
}
|
||||
else if (inst==3) { // guiro_setup();
|
||||
rv = inst;
|
||||
num_objects = GUIR_NUM_PARTS;
|
||||
defObjs[inst] = GUIR_NUM_PARTS;
|
||||
setDecays(GUIR_SOUND_DECAY,1.0);
|
||||
defDecays[inst] = 0.9999;
|
||||
decayScale[inst] = 1.0;
|
||||
num_freqs = 2;
|
||||
baseGain = GUIR_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -313,8 +336,12 @@ int Shakers :: setupNum(int inst)
|
||||
ratchetPos = 10;
|
||||
}
|
||||
else if (inst==4) { // wuter_setup();
|
||||
rv = inst;
|
||||
num_objects = WUTR_NUM_SOURCES;
|
||||
defObjs[inst] = WUTR_NUM_SOURCES;
|
||||
setDecays(WUTR_SOUND_DECAY,WUTR_SYSTEM_DECAY);
|
||||
defDecays[inst] = WUTR_SYSTEM_DECAY;
|
||||
decayScale[inst] = 0.8;
|
||||
num_freqs = 3;
|
||||
baseGain = WUTR_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -333,8 +360,12 @@ int Shakers :: setupNum(int inst)
|
||||
setFinalZs(1.0,0.0,0.0);
|
||||
}
|
||||
else if (inst==5) { // bamboo_setup();
|
||||
rv = inst;
|
||||
num_objects = BAMB_NUM_TUBES;
|
||||
defObjs[inst] = BAMB_NUM_TUBES;
|
||||
setDecays(BAMB_SOUND_DECAY, BAMB_SYSTEM_DECAY);
|
||||
defDecays[inst] = BAMB_SYSTEM_DECAY;
|
||||
decayScale[inst] = 0.7;
|
||||
num_freqs = 3;
|
||||
baseGain = BAMB_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -353,8 +384,12 @@ int Shakers :: setupNum(int inst)
|
||||
setFinalZs(1.0,0.0,0.0);
|
||||
}
|
||||
else if (inst==6) { // tambourine_setup();
|
||||
rv = inst;
|
||||
num_objects = TAMB_NUM_TIMBRELS;
|
||||
defObjs[inst] = TAMB_NUM_TIMBRELS;
|
||||
setDecays(TAMB_SOUND_DECAY,TAMB_SYSTEM_DECAY);
|
||||
defDecays[inst] = TAMB_SYSTEM_DECAY;
|
||||
decayScale[inst] = 0.95;
|
||||
num_freqs = 3;
|
||||
baseGain = TAMB_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -373,8 +408,12 @@ int Shakers :: setupNum(int inst)
|
||||
setFinalZs(1.0,0.0,-1.0);
|
||||
}
|
||||
else if (inst==7) { // sleighbell_setup();
|
||||
rv = inst;
|
||||
num_objects = SLEI_NUM_BELLS;
|
||||
defObjs[inst] = SLEI_NUM_BELLS;
|
||||
setDecays(SLEI_SOUND_DECAY,SLEI_SYSTEM_DECAY);
|
||||
defDecays[inst] = SLEI_SYSTEM_DECAY;
|
||||
decayScale[inst] = 0.9;
|
||||
num_freqs = 5;
|
||||
baseGain = SLEI_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -395,8 +434,12 @@ int Shakers :: setupNum(int inst)
|
||||
setFinalZs(1.0,0.0,-1.0);
|
||||
}
|
||||
else if (inst==8) { // stix1_setup();
|
||||
rv = inst;
|
||||
num_objects = STIX1_NUM_BEANS;
|
||||
defObjs[inst] = STIX1_NUM_BEANS;
|
||||
setDecays(STIX1_SOUND_DECAY,STIX1_SYSTEM_DECAY);
|
||||
defDecays[inst] = STIX1_SYSTEM_DECAY;
|
||||
decayScale[inst] = 0.96;
|
||||
num_freqs = 1;
|
||||
baseGain = STIX1_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -406,8 +449,12 @@ int Shakers :: setupNum(int inst)
|
||||
setFinalZs(1.0,0.0,-1.0);
|
||||
}
|
||||
else if (inst==9) { // crunch1_setup();
|
||||
rv = inst;
|
||||
num_objects = CRUNCH1_NUM_BEADS;
|
||||
defObjs[inst] = CRUNCH1_NUM_BEADS;
|
||||
setDecays(CRUNCH1_SOUND_DECAY,CRUNCH1_SYSTEM_DECAY);
|
||||
defDecays[inst] = CRUNCH1_SYSTEM_DECAY;
|
||||
decayScale[inst] = 0.96;
|
||||
num_freqs = 1;
|
||||
baseGain = CRUNCH1_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -417,8 +464,12 @@ int Shakers :: setupNum(int inst)
|
||||
setFinalZs(1.0,-1.0,0.0);
|
||||
}
|
||||
else if (inst==10) { // wrench_setup();
|
||||
rv = inst;
|
||||
num_objects = WRENCH_NUM_PARTS;
|
||||
defObjs[inst] = WRENCH_NUM_PARTS;
|
||||
setDecays(WRENCH_SOUND_DECAY,1.0);
|
||||
defDecays[inst] = 0.9999;
|
||||
decayScale[inst] = 0.98;
|
||||
num_freqs = 2;
|
||||
baseGain = WRENCH_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -434,8 +485,12 @@ int Shakers :: setupNum(int inst)
|
||||
ratchetPos = 10;
|
||||
}
|
||||
else if (inst==11) { // sandpapr_setup();
|
||||
rv = inst;
|
||||
num_objects = SANDPAPR_NUM_GRAINS;
|
||||
defObjs[inst] = SANDPAPR_NUM_GRAINS;
|
||||
this->setDecays(SANDPAPR_SOUND_DECAY,SANDPAPR_SYSTEM_DECAY);
|
||||
defDecays[inst] = SANDPAPR_SYSTEM_DECAY;
|
||||
decayScale[inst] = 0.97;
|
||||
num_freqs = 1;
|
||||
baseGain = SANDPAPR_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -445,8 +500,12 @@ int Shakers :: setupNum(int inst)
|
||||
this->setFinalZs(1.0, 0.0, -1.0);
|
||||
}
|
||||
else if (inst==12) { // cokecan_setup();
|
||||
rv = inst;
|
||||
num_objects = COKECAN_NUM_PARTS;
|
||||
defObjs[inst] = COKECAN_NUM_PARTS;
|
||||
setDecays(COKECAN_SOUND_DECAY,COKECAN_SYSTEM_DECAY);
|
||||
defDecays[inst] = COKECAN_SYSTEM_DECAY;
|
||||
decayScale[inst] = 0.95;
|
||||
num_freqs = 5;
|
||||
baseGain = COKECAN_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -469,7 +528,10 @@ int Shakers :: setupNum(int inst)
|
||||
}
|
||||
else { // maraca_setup(); inst == 0 or other
|
||||
num_objects = MARA_NUM_BEANS;
|
||||
defObjs[0] = MARA_NUM_BEANS;
|
||||
setDecays(MARA_SOUND_DECAY,MARA_SYSTEM_DECAY);
|
||||
defDecays[0] = MARA_SYSTEM_DECAY;
|
||||
decayScale[inst] = 0.9;
|
||||
num_freqs = 1;
|
||||
baseGain = MARA_GAIN;
|
||||
temp = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
@@ -478,7 +540,7 @@ int Shakers :: setupNum(int inst)
|
||||
setFreqAndReson(0,MARA_CENTER_FREQ,MARA_RESON);
|
||||
setFinalZs(1.0,-1.0,0.0);
|
||||
}
|
||||
return inst;
|
||||
return rv;
|
||||
}
|
||||
|
||||
void Shakers :: noteOn(MY_FLOAT freq, MY_FLOAT amp)
|
||||
@@ -486,7 +548,8 @@ void Shakers :: noteOn(MY_FLOAT freq, MY_FLOAT amp)
|
||||
// Yep ... pretty kludgey, but it works!
|
||||
int noteNum = (int) ((12*log(freq/220)/log(2)) + 57.01) % 32;
|
||||
if (instType != noteNum) instType = this->setupNum(noteNum);
|
||||
shakeEnergy = amp * MAX_SHAKE * 0.1;
|
||||
//shakeEnergy = amp * MAX_SHAKE * 0.1;
|
||||
shakeEnergy += amp * MAX_SHAKE * 0.1;
|
||||
if (shakeEnergy > MAX_SHAKE) shakeEnergy = MAX_SHAKE;
|
||||
if (instType==10 || instType==3) ratchetPos += 1;
|
||||
#if defined(_debug_)
|
||||
@@ -497,6 +560,7 @@ void Shakers :: noteOn(MY_FLOAT freq, MY_FLOAT amp)
|
||||
void Shakers :: noteOff(MY_FLOAT amp)
|
||||
{
|
||||
shakeEnergy = 0.0;
|
||||
if (instType==10 || instType==3) ratchetPos = 0;
|
||||
}
|
||||
|
||||
#define MIN_ENERGY 0.3
|
||||
@@ -510,6 +574,7 @@ MY_FLOAT Shakers :: tick()
|
||||
if (instType==4) {
|
||||
if (shakeEnergy > MIN_ENERGY) {
|
||||
lastOutput = wuter_tick();
|
||||
lastOutput *= 0.0001;
|
||||
}
|
||||
else {
|
||||
lastOutput = 0.0;
|
||||
@@ -524,6 +589,7 @@ MY_FLOAT Shakers :: tick()
|
||||
}
|
||||
totalEnergy = ratchet;
|
||||
lastOutput = ratchet_tick();
|
||||
lastOutput *= 0.0001;
|
||||
}
|
||||
else lastOutput = 0.0;
|
||||
}
|
||||
@@ -560,13 +626,11 @@ MY_FLOAT Shakers :: tick()
|
||||
data += finalZCoeffs[2] * finalZ[2]; // Extra zero(s) for shape
|
||||
if (data > 10000.0) data = 10000.0;
|
||||
if (data < -10000.0) data = -10000.0;
|
||||
lastOutput = data;
|
||||
lastOutput = data * 0.0001;
|
||||
}
|
||||
else lastOutput = 0.0;
|
||||
}
|
||||
|
||||
lastOutput *= 0.0001;
|
||||
|
||||
return lastOutput;
|
||||
}
|
||||
|
||||
@@ -593,23 +657,64 @@ void Shakers :: controlChange(int number, MY_FLOAT value)
|
||||
#if defined(_debug_)
|
||||
printf("setting decay\n");
|
||||
#endif
|
||||
systemDecay = 0.998 + (value * NORM_7 * 0.002);
|
||||
//systemDecay = 0.998 + (value * NORM_7 * 0.002);
|
||||
if (instType != 3 && instType != 10) {
|
||||
systemDecay = defDecays[instType] + ((value - 64.0) * decayScale[instType] * (1.0 - defDecays[instType]) / 64.0 );
|
||||
gains[0] = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
for (i=1;i<num_freqs;i++) gains[i] = gains[0];
|
||||
if (instType == 6) { // tambourine
|
||||
gains[0] *= TAMB_SHELL_GAIN;
|
||||
gains[1] *= 0.8;
|
||||
}
|
||||
else if (instType == 7) { // sleighbell
|
||||
gains[3] *= 0.5;
|
||||
gains[4] *= 0.3;
|
||||
}
|
||||
else if (instType == 12) { // cokecan
|
||||
for (i=1;i<num_freqs;i++) gains[i] *= 1.8;
|
||||
}
|
||||
for (i=0;i<num_freqs;i++) gains[i] *= ((128-value)/100.0 + 0.36);
|
||||
}
|
||||
}
|
||||
else if (number == __SK_ModFrequency_) { // control_change #11
|
||||
#if defined(_debug_)
|
||||
printf("setting number of objects\n");
|
||||
#endif
|
||||
if (instType==5) num_objects = (MY_FLOAT) (value/32.0) + 1;
|
||||
else num_objects = (MY_FLOAT) value + 1;
|
||||
if (instType == 5) // bamboo
|
||||
num_objects = (MY_FLOAT) (value * defObjs[instType] / 64.0) + 0.3;
|
||||
else
|
||||
num_objects = (MY_FLOAT) (value * defObjs[instType] / 64.0) + 1.1;
|
||||
gains[0] = log(num_objects) * baseGain / (MY_FLOAT) num_objects;
|
||||
for (i=1;i<num_freqs;i++) gains[i] = gains[0];
|
||||
if (instType == 6) { // tambourine
|
||||
gains[0] *= TAMB_SHELL_GAIN;
|
||||
gains[1] *= 0.8;
|
||||
}
|
||||
else if (instType == 7) { // sleighbell
|
||||
gains[3] *= 0.5;
|
||||
gains[4] *= 0.3;
|
||||
}
|
||||
else if (instType == 12) { // cokecan
|
||||
for (i=1;i<num_freqs;i++) gains[i] *= 1.8;
|
||||
}
|
||||
if (instType != 3 && instType != 10) {
|
||||
// reverse calculate decay setting
|
||||
float temp = 64.0 * (systemDecay-defDecays[instType])/(decayScale[instType]*(1-defDecays[instType])) + 64.0;
|
||||
// scale gains by decay setting
|
||||
for (i=0;i<num_freqs;i++) gains[i] *= ((128-temp)/100.0 + 0.36);
|
||||
}
|
||||
}
|
||||
else if (number == __SK_ModWheel_) { // control_change #1
|
||||
#if defined(_debug_)
|
||||
printf("setting resonance %i freq. to %f\n",i,temp);
|
||||
#endif
|
||||
for (i=0;i<num_freqs;i++) {
|
||||
temp = center_freqs[i] * pow (1.015,value-64);
|
||||
if (instType == 6 || instType == 2 || instType == 7) // limit range a bit for tambourine
|
||||
temp = center_freqs[i] * pow (1.008,value-64);
|
||||
else
|
||||
temp = center_freqs[i] * pow (1.015,value-64);
|
||||
t_center_freqs[i] = temp;
|
||||
#if defined(_debug_)
|
||||
printf("setting resonance %i freq. to %f\n",i,temp);
|
||||
#endif
|
||||
|
||||
coeffs[i][0] = -resons[i] * 2.0 * cos(temp * TWO_PI / SRATE);
|
||||
coeffs[i][1] = resons[i]*resons[i];
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "Instrmnt.h"
|
||||
|
||||
#define MAX_FREQS 8
|
||||
#define NUM_INSTR 13
|
||||
|
||||
class Shakers : public Instrmnt
|
||||
{
|
||||
@@ -59,6 +60,9 @@ class Shakers : public Instrmnt
|
||||
void setFinalZs(MY_FLOAT z0, MY_FLOAT z1, MY_FLOAT z2);
|
||||
MY_FLOAT wuter_tick();
|
||||
MY_FLOAT ratchet_tick();
|
||||
MY_FLOAT defObjs[NUM_INSTR];
|
||||
MY_FLOAT defDecays[NUM_INSTR];
|
||||
MY_FLOAT decayScale[NUM_INSTR];
|
||||
public:
|
||||
Shakers();
|
||||
~Shakers();
|
||||
|
||||
@@ -30,7 +30,7 @@ class Simple : public Instrmnt
|
||||
MY_FLOAT loopGain;
|
||||
public:
|
||||
Simple();
|
||||
~Simple();
|
||||
virtual ~Simple();
|
||||
void clear();
|
||||
virtual void setFreq(MY_FLOAT frequency);
|
||||
void keyOn();
|
||||
|
||||
@@ -180,9 +180,6 @@ MY_FLOAT VoicForm :: tick()
|
||||
|
||||
void VoicForm :: controlChange(int number, MY_FLOAT value)
|
||||
{
|
||||
MY_FLOAT temp;
|
||||
int tempi;
|
||||
|
||||
#if defined(_debug_)
|
||||
printf("VoicForm : ControlChange: Number=%i Value=%f\n",number,value);
|
||||
#endif
|
||||
@@ -191,7 +188,8 @@ void VoicForm :: controlChange(int number, MY_FLOAT value)
|
||||
this->setUnVoiced((MY_FLOAT) 0.01 * value * (MY_FLOAT) NORM_7);
|
||||
}
|
||||
else if (number == __SK_FootControl_) {
|
||||
tempi = (int) value;
|
||||
MY_FLOAT temp = 0.0;
|
||||
int tempi = (int) value;
|
||||
if (tempi < 32) {
|
||||
tempi = tempi;
|
||||
temp = (MY_FLOAT) 0.9;
|
||||
|
||||
@@ -28,7 +28,7 @@ class WvIn : public Object
|
||||
MY_FLOAT *lastOutput;
|
||||
public:
|
||||
WvIn();
|
||||
~WvIn();
|
||||
virtual ~WvIn();
|
||||
void reset();
|
||||
void normalize();
|
||||
void normalize(MY_FLOAT newPeak);
|
||||
|
||||
@@ -15,25 +15,25 @@
|
||||
|
||||
class MandPlyr : public Instrmnt
|
||||
{
|
||||
protected:
|
||||
VoicMang *strings;
|
||||
Noise *noise;
|
||||
short strumming;
|
||||
long strumRate;
|
||||
long strumCount;
|
||||
MY_FLOAT skill;
|
||||
short nums[NUM_STRINGS]; // For Now Integer Note Nums
|
||||
MY_FLOAT amps[NUM_STRINGS];
|
||||
long tags[NUM_STRINGS];
|
||||
public:
|
||||
MandPlyr();
|
||||
~MandPlyr();
|
||||
virtual void noteOnN(short num, MY_FLOAT amp);
|
||||
virtual void noteOffN(short num, MY_FLOAT amp);
|
||||
virtual MY_FLOAT tick();
|
||||
MY_FLOAT special_tick();
|
||||
virtual void controlChange(int number, MY_FLOAT value);
|
||||
virtual void playChord(MY_FLOAT amp, char* chordString);
|
||||
protected:
|
||||
VoicMang *strings;
|
||||
Noise *noise;
|
||||
short strumming;
|
||||
long strumRate;
|
||||
long strumCount;
|
||||
MY_FLOAT skill;
|
||||
short nums[NUM_STRINGS]; // For Now Integer Note Nums
|
||||
MY_FLOAT amps[NUM_STRINGS];
|
||||
long tags[NUM_STRINGS];
|
||||
public:
|
||||
MandPlyr();
|
||||
~MandPlyr();
|
||||
virtual void noteOnN(short num, MY_FLOAT amp);
|
||||
virtual void noteOffN(short num, MY_FLOAT amp);
|
||||
virtual MY_FLOAT tick();
|
||||
MY_FLOAT special_tick();
|
||||
virtual void controlChange(int number, MY_FLOAT value);
|
||||
virtual void playChord(MY_FLOAT amp, char* chordString);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user