Programming Etude #3

Pkmazarakis
8 min readFeb 28, 2023

--

Orchestra v1

noises?

Had to try it out

For the orchestra I wanted to add a background beat made by chuck, so I coded piano chords and made them run in a loop in the background. Then I added a shaker and found the type that suited the piano the best and attached it to the OSC which altered the frequency and gain of the shaker. The OSC was trained on visionOSC. There were 67 elements when hands are detected. The first is the width of the frame, the second is the height. The third how many hands and the next 64 were various positions on the hand. I extracted the values that correlated with the x and y axis and attached those to gain and frequency. The higher it rose, the higher the gain and frequency of the shaker would reach. I made sure to only use one hand in these data sets because I wanted last final conductor boom with two hands that would trigger the rizz finale.

The other two were just experiments to getting familiar with the tech and playing around with wav files and manipulations of sound.

matt just had to start the rizz trend. Couldn’t not hop on the wagon.

Only help was from Ge and the example code we were given.

What I really wanted to do was attach the rizz code to an arduino box I built that is covered in rgb neopixels. It would smoothly go through all the colors but anytime you made the rizz face it would change to dark red. The problem was the arduino uno I built it on was not connected to the internet and you need internet for the OSC to transmit, so I spent a day trying to figure out workarounds like using slipserial and other wifi arduino packages. Overall, I got ****** by this idea haha but, maybe ill give it a go when the time isn’t 3 hours past the deadline. Here’s the code!

//----------------------------------------------------------------------------
/* 5-parameter FM synth by Jeff Snyder
wekinator mod by Rebecca Fiebrink (2009-2015)
updated by Ge Wang (2023)

USAGE: This example receives Wekinator "/wek/outputs/" messages
over OSC and maps incoming parameters to musical parameters;
This example is designed to run with a sender, which can be:
1) the Wekinator application, OR
2) another Chuck/ChAI program containing a Wekinator object

This example expects to receive 5 continuous parameters in the
range [0,1]; these parameters are mapped to musical parameters
in map2sound().

SOUND: this uses FM synthesis:
* generates a sawtooth wave (carrier)
* which is frequency-modulated by a sine wave (modulator)
* which then gets put through a low-pass filter
* and has an amplitude envelope

This example is "always on" -- no note triggering with keyboard

expected parameters for this class are:
0 = midinote pitch of Sawtooth oscillator (carrier freq)
1 = lowpass filter cutoff frequency
2 = Master gain (carrier gain)
3 = fm oscillator midinote pitch (modulator freq)
4 = fm oscillator index (modulator index) */
//----------------------------------------------------------------------------

// create our OSC receiver
OscIn oscin;
// a thing to retrieve message contents
OscMsg msg;
// use port 12000 (default Wekinator output port)
12000 => oscin.port;

// listen for "/wek/output" message with 5 floats coming in
oscin.addAddress( "/wek/outputs, fffff" );
// print
<<< "listening for OSC message from Wekinator on port 12000...", "" >>>;
<<< " |- expecting \"/wek/outputs\" with 5 continuous parameters...", "" >>>;

// synthesis patch
Shakers shake => NRev r => dac;
FrencHrn horn => r;
SndBuf buffer => r;

me.dir() + "weekndRizz.wav" => buffer.read;

.05 => r.mix;
2 => shake.which;

// set to do FM synthesis
//2 => s.sync;
// low pass filter param
//2000 => lpf.freq;
// set envelope duration
//5::ms => vol.duration;
// set carrier frequency
//50 => Std.mtof => s.freq;

// expecting 5 output dimensions
5 => int NUM_PARAMS;
float myParams[NUM_PARAMS];
500::ms => dur Q;

// envelopes for smoothing parameters
// (alternately, can use slewing interpolators; SEE:
// https://chuck.stanford.edu/doc/examples/vector/interpolate.ck)
Envelope envs[NUM_PARAMS];
for( 0 => int i; i < NUM_PARAMS; i++ )
{
envs[i] => blackhole;
.5 => envs[i].value;
10::ms => envs[i].duration;
}
spork ~ hornPlayer();

1.0 => float chord;
1 => int play;

// set the latest parameters as targets
// NOTE: we rely on map2sound() to actually interpret these parameters musically
fun void setParams( float params[] )
{
// make sure we have enough
if( params.size() >= NUM_PARAMS )
{
// adjust the synthesis accordingly
0.0 => float x;
for( 0 => int i; i < NUM_PARAMS; i++ )
{
// get value
params[i] => x;
// clamp it
if( x < 0 ) 0 => x;
if( x > 1 ) 1 => x;
// set as target of envelope (for smoothing)
x => envs[i].target;
// remember
x => myParams[i];
}
}
}

fun void hornPlayer()
{
while( play == 1 )
{
if (chord == 1) {
playNote(horn, 62, .4, Q);
playNote(horn, 67, .7, Q);
playNote(horn, 71, 1, Q);
playNote(horn, 74, 1, Q);
chord + 1 => chord;

}
if (chord == 2) {
playNote(horn, 64, .4, Q);
playNote(horn, 67, .7, Q);
playNote(horn, 71, 1, Q);
playNote(horn, 76, 1, Q);
chord + 1 => chord;

}
if (chord == 3) {
playNote(horn, 64, .4, Q);
playNote(horn, 67, .7, Q);
playNote(horn, 72, 1, Q);
playNote(horn, 76, 1, Q);
chord + 1 => chord;

}
if (chord == 4) {
playNote(horn, 60, .4, Q);
playNote(horn, 64, .7, Q);
playNote(horn, 67, 1, Q);
playNote(horn, 72, 1, Q);
1.0 => chord;

}
else {
}

<<< chord >>>;

}
}

fun void playNote( StkInstrument ins, float pitch, float velocity, dur T )
{
pitch => Std.mtof => ins.freq;
velocity => ins.noteOn;
.8*T => now;
1 => ins.noteOff;
.2*T => now;
}

// function to map incoming parameters to musical parameters
fun void map2sound()
{
// time loop
while( true )
{
// FYI envs[i] are used for smoothing param values
if (envs[2].value() > 0.5) {
1 => buffer.gain;
0 => play;


} else {
0 => buffer.gain;

envs[0].value()*1 => shake.gain;
envs[1].value()*100 => shake.freq;
Math.random2f( 0.8, 1.3 ) => shake.noteOn;
1 => play;
}


//envs[2].value() * .5 => s.gain;
//envs[3].value() * 100 + 20 => Std.mtof => fmosc.freq;
//envs[4].value() * 400 => fmosc.gain;
// time
10::ms => now;
}
}

// turn volume off!
fun void soundOff()
{
//r.keyOff();
}

// turn volume on!
fun void soundOn()
{
//<<< "SOUUUUUUUND">>>;
//r.keyOn();
}

fun void waitForEvent()
{
// array to hold params
float p[NUM_PARAMS];

// infinite event loop
while( true )
{
// wait for OSC message to arrive
oscin => now;

// grab the next message from the queue.
while( oscin.recv(msg) )
{
// print stuff
cherr <= msg.address <= " ";

// unpack our 5 floats into our array p
for( int i; i < NUM_PARAMS; i++ )
{
// put into array
msg.getFloat(i) => p[i];
// print
cherr <= p[i] <= " ";
}

// print
cherr <= IO.newline();

// set the parameters
setParams( p );
}
}
}

// spork osc receiver loop
spork ~waitForEvent();
// spork mapping function
spork ~ map2sound();
// turn on sound
soundOn();

// time loop to keep everything going
while( true ) 1::second => now;
//----------------------------------------------------------------------------
/* 5-parameter FM synth by Jeff Snyder
wekinator mod by Rebecca Fiebrink (2009-2015)
updated by Ge Wang (2023)

USAGE: This example receives Wekinator "/wek/outputs/" messages
over OSC and maps incoming parameters to musical parameters;
This example is designed to run with a sender, which can be:
1) the Wekinator application, OR
2) another Chuck/ChAI program containing a Wekinator object

This example expects to receive 5 continuous parameters in the
range [0,1]; these parameters are mapped to musical parameters
in map2sound().

SOUND: this uses FM synthesis:
* generates a sawtooth wave (carrier)
* which is frequency-modulated by a sine wave (modulator)
* which then gets put through a low-pass filter
* and has an amplitude envelope

This example is "always on" -- no note triggering with keyboard

expected parameters for this class are:
0 = midinote pitch of Sawtooth oscillator (carrier freq)
1 = lowpass filter cutoff frequency
2 = Master gain (carrier gain)
3 = fm oscillator midinote pitch (modulator freq)
4 = fm oscillator index (modulator index) */
//----------------------------------------------------------------------------

// create our OSC receiver
OscIn oscin;
// a thing to retrieve message contents
OscMsg msg;
// use port 12000 (default Wekinator output port)
12000 => oscin.port;

// listen for "/wek/output" message with 5 floats coming in
oscin.addAddress( "/wek/outputs, fffff" );
// print
<<< "listening for OSC message from Wekinator on port 12000...", "" >>>;
<<< " |- expecting \"/wek/outputs\" with 5 continuous parameters...", "" >>>;

// synthesis patch
SndBuf buffer => dac;

me.dir() + "rizz2.wav" => buffer.read;
// set to do FM synthesis
//2 => s.sync;
// low pass filter param
//2000 => lpf.freq;
// set envelope duration
//5::ms => vol.duration;
// set carrier frequency
//50 => Std.mtof => s.freq;

// expecting 5 output dimensions
5 => int NUM_PARAMS;
float myParams[NUM_PARAMS];

// envelopes for smoothing parameters
// (alternately, can use slewing interpolators; SEE:
// https://chuck.stanford.edu/doc/examples/vector/interpolate.ck)
Envelope envs[NUM_PARAMS];
for( 0 => int i; i < NUM_PARAMS; i++ )
{
envs[i] => blackhole;
.5 => envs[i].value;
10::ms => envs[i].duration;
}

// set the latest parameters as targets
// NOTE: we rely on map2sound() to actually interpret these parameters musically
fun void setParams( float params[] )
{
// make sure we have enough
if( params.size() >= NUM_PARAMS )
{
// adjust the synthesis accordingly
0.0 => float x;
for( 0 => int i; i < NUM_PARAMS; i++ )
{
// get value
params[i] => x;
// clamp it
if( x < 0 ) 0 => x;
if( x > 1 ) 1 => x;
// set as target of envelope (for smoothing)
x => envs[i].target;
// remember
x => myParams[i];
}
}
}

// function to map incoming parameters to musical parameters
fun void map2sound()
{
// time loop
while( true )
{
// FYI envs[i] are used for smoothing param values
if (envs[0].value() > .5) {
<<<envs[0].value()>>>;
envs[0].value() => buffer.rate;

} else {
0=> buffer.rate;

}
//envs[1].value() => buffer.gain;

// envs[1].value() /100 => buffer.freq;
//envs[2].value() * .5 => s.gain;
//envs[3].value() * 100 + 20 => Std.mtof => fmosc.freq;
//envs[4].value() * 400 => fmosc.gain;
// time
10::ms => now;
}
}

// turn volume off!
fun void soundOff()
{
//vol.keyOff();
}

// turn volume on!
fun void soundOn()
{
//<<< "SOUUUUUUUND">>>;
// vol.keyOn();
}

fun void waitForEvent()
{
// array to hold params
float p[NUM_PARAMS];

// infinite event loop
while( true )
{
// wait for OSC message to arrive
oscin => now;

// grab the next message from the queue.
while( oscin.recv(msg) )
{
// print stuff
cherr <= msg.address <= " ";

// unpack our 5 floats into our array p
for( int i; i < NUM_PARAMS; i++ )
{
// put into array
msg.getFloat(i) => p[i];
// print
cherr <= p[i] <= " ";
}

// print
cherr <= IO.newline();

// set the parameters
setParams( p );
}
}
}

// spork osc receiver loop
spork ~waitForEvent();
// spork mapping function
spork ~ map2sound();
// turn on sound
soundOn();

// time loop to keep everything going
while( true ) 1::second => now;
Unlisted

--

--