Homework 2 is about synthesizing an auditory streaming illusion using FM tones.

FM demo -- algorithmic control of parameters

This page plays little 4-note riffs from a mouse click. See FMdemo, FMdemo2, FMdemo3 for the timbre space used here. Mouse position moves around in it.
Uses MIDI keynum values to specify pitch with the built-in function Std.mtof()

////////////////////////////////////////////////////
suggestions for longer riffs and increasing loudness
for (0 => int i; i < 40; i++) Std.dbtorms( 60 + i ) => c.gain; // function to convert dB to amplitude
////////////////////////////////////////////////////
live code
global int mouseX, mouseY; global Event playRiff; SinOsc c => ADSR cEnv => dac; //...as an inline modifier of a signal SinOsc m => blackhole; Step unity => ADSR mEnv => blackhole; //...as a separate signal 440 => float cf; 550 => float mf => m.freq; 200 => float index; // set A, D, S, and R // (note: A, D, R are durations; S is a number between 0 and 1) cEnv.set( 100::ms, 8::ms, .25, 300::ms ); mEnv.set( 20::ms, 80::ms, .17, 200::ms ); fun void runFM() { while( true ) { cf + (mEnv.last() * index * m.last()) => c.freq; 1::samp => now; } } spork ~ runFM(); fun void riffPlay() { for (0 => int i; i < 4; i++) { Std.mtof( 60 + i ) => cf; cEnv.keyOn(); mEnv.keyOn(); .1::second => now; cEnv.keyOff(); mEnv.keyOff(); .1::second => now; } } fun void mousePlay() { while (true) { playRiff => now; spork ~ riffPlay(); } } spork ~ mousePlay(); fun void RespondToMouseMovement() { while( true ) { mouseX*0.5 => m.freq; mouseY*0.5 => index; 10::ms => now; } } spork ~ RespondToMouseMovement(); 1::week => now;