Goto: [ Program Documentation ]
//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Tue Feb 2 16:49:52 PST 1999
// Last Modified: Sun Feb 7 17:53:35 PST 1999
// Filename: ...sig/doc/examples/sig/sigcontrol/batres/batres.cpp
// Syntax: C++; batonImprov; sig
//
// Description: Plays sound through a two-pole resonating filter
// with baton 1 center frequency and bandwidth.
// The filter can be controlled either in the z-plane or s-plane.
//
#include "batonImprov.h"
#include "sig.h"
#include <math.h>
/*----------------- beginning of improvization algorithms ---------------*/
// sound elements
Constant frequency;
Constant bandwidth;
Constant amplitude;
WhiteNoise whitenoise;
Resonator reson;
Multiply mul;
LinuxSoundOut outsound(44100, 2);
Action action;
SigTimer soundTimer;
SigTimer poledisplay;
int poledisplayQ = 1;
#define MODE_Z 0
#define MODE_S 1
int mode = MODE_Z;
/*--------------------- maintenance algorithms --------------------------*/
void description(void) {
cout
<< "Initial test program for live sound with Improv programs\n"
<< "Keyboard commands: \n"
<< " p = toggle position information display\n"
<< " s/z = use either s-plane (rectangular) or z-plane (circular) domains\n"
<< endl;
}
void initialization(void) {
// sound element connections
outsound.connect(mul); // left
outsound.connect(mul); // right
mul.connect(reson);
mul.connect(amplitude);
reson.connect(whitenoise, 0);
reson.connect(frequency, 1);
reson.connect(bandwidth, 2);
action.freezeState(outsound);
soundTimer.setPeriod(1);
poledisplay.setPeriod(200);
eventIdler.setPeriod(0);
}
void finishup(void) { }
/*-------------------- main loop algorithms -----------------------------*/
double getradius(int x, int y) {
double xr = x/125.0 * 2 - 1;
double yr = y/125.0 * 2 - 1;
double output = sqrt(xr*xr + yr*yr);
if (output > 1.0) {
output = 0.9999;
}
// stretch the outer radius values
output = 1 - pow(output - 1, 2);
return output;
}
double getangle(int x, int y) {
double xr = x/127.0 * 2 - 1;
double yr = y/127.0 * 2 - 1;
return atan2(yr,xr);
}
double angle;
double radius;
double amp;
void mainloopalgorithms(void) {
switch (mode) {
case MODE_S:
if (baton.z2p < 63) {
amp = 0;
} else {
amp = (baton.z2p/127.0 - 0.5) * 2;
}
amplitude.setValue(amp);
frequency.setValue(midiscale(baton.x2p, 0, 10000));
bandwidth.setValue(midiscale(baton.y2p, 0, 3000));
break;
case MODE_Z:
angle = getangle(baton.x2p, baton.y2p);
radius = getradius(baton.x2p, baton.y2p);
if (baton.z2p < 63) {
amp = 0;
} else {
amp = (baton.z2p/127.0 - 0.5) * 2;
amp *= (pow(radius, 18) + 0.5) * 10;
}
amplitude.setValue(amp);
frequency.setValue(fabs(angle)*1000);
bandwidth.setValue((1.001-radius)*3000);
break;
}
if (poledisplayQ && poledisplay.expired()) {
switch (mode) {
case MODE_S:
cout << "\rcenter: " << frequency.output(0) << "Hz"
<< " bandwidth: " << bandwidth.output(0)
<< " "
<< flush;
break;
case MODE_Z:
poledisplay.reset();
cout << "\rpole radius: " << radius
<< " angle: " << angle << " "
<< flush;
break;
}
}
if (soundTimer.expired()) {
soundTimer.reset();
action.tickFrozenState(1024);
}
}
/*-------------------- triggered algorithms -----------------------------*/
void stick1trig(void) { }
void stick2trig(void) { }
void b14plustrig(void) { }
void b15plustrig(void) { }
void b14minusuptrig(void) { }
void b14minusdowntrig(void) { }
void b15minusuptrig(void) { }
void b15minusdowntrig(void) { }
void keyboardchar(int key) {
switch (key) {
case 'p':
poledisplayQ = !poledisplayQ;
if (poledisplayQ) {
cout << "Pole position display ON" << endl;
} else {
cout << "\nPole position display OFF" << endl;
}
break;
case 's':
mode = MODE_S;
cout << "\ns-plane mode" << endl;
break;
case 'z':
mode = MODE_Z;
cout << "\nz-plane mode" << endl;
break;
case ' ':
cout << "\nCenter: " << frequency.output(0) << "Hz"
<< " Bandwidth: " << bandwidth.output(0)
<< endl;
break;
}
}
/*------------------ end improvization algorithms -----------------------*/
// md5sum: 36ae3080e64532b5fd4ada961ba0bed1 batres.cpp [20050403]