// Guitar Riff Lab with MAUI Control Interface // copyright 2008 Les Hall // this software is protected by the GNU General Public License // control variables 2 => int n; // base of count 12 => int num_digits; // number of digits in base-n count 8 => int num_and_terms; // number of and terms 4 => int num_and_pages; // number of pages of and terms 0 => int and_page; // the current and page 0 => int instrument; // the current instrument 5 => int num_instruments; // number of instruments float freq; // the frequency of the next note 0 => int play_note; // 1 to play this note 0 => int and_term; // equal to and_bits if play_note should be true 0 => int and_bits; // number of bits anded in a term int j[num_digits]; // the base-n count int freq_amount[num_instruments][num_digits]; // frequency bit values int and_values[num_instruments][num_and_pages*num_and_terms][num_digits]; // holds current value of buttons [10.0, 100.0, 10.0, 10.0, 50.0] @=> float freq_mult_values[]; // frequency multiplier values [2.0, 2.0, 2.0, 2.0, 2.0] @=> float freq_offset_values[]; // frequency offset values MAUI_View control_view; MAUI_View slider_view; MAUI_Button start_button, record_button, clear_button; MAUI_Button instrument_minus_button, instrument_plus_button, instrument_button; MAUI_Button xor_button; MAUI_Button and_buttons[num_and_terms][num_digits]; MAUI_Button and_plus_button, and_minus_button, and_page_button; MAUI_LED count[num_digits]; MAUI_LED logic[num_and_terms]; MAUI_LED playing_note; MAUI_Button plus_buttons[num_digits]; MAUI_Button minus_buttons[num_digits]; MAUI_Button freq_buttons[num_digits]; MAUI_Slider master_volume; MAUI_Slider base; MAUI_Slider freq_mult, freq_offset; MAUI_Slider notes_per_second; MAUI_Slider reverb, body_size, pluck_pos; MAUI_Slider string_damping, string_detune, after_touch; MAUI_Slider jet_delay, jet_reflection, end_reflection; MAUI_Slider noise_gain, vibrato_freq, vibrato_gain; MAUI_Slider snare_freq, snare_Q, snare_decay, snare_attack; MAUI_Slider drum_freq, drum_pitch_decay, drum_pitch_attack; MAUI_Slider drum_decay, drum_attack, drum_drive_gain; MAUI_Slider drum_filter; MAUI_Slider mandolin_body_size, mandolin_pluck_pos, mandolin_after_touch; MAUI_Slider mandolin_string_damping, mandolin_string_detune; MAUI_Button Guitar, Flute; MAUI_Button Snare, Drum; MAUI_Button Mandolin; MAUI_Slider guitar_gain, flute_gain, snare_gain, drum_gain, mandolin_gain; control_view.size (800, 600); control_view.name ("Boolean Sequencing Guitar Lab - Logic Matrix"); slider_view.size (800, 600); slider_view.name ("Boolean Sequencing Guitar Lab - Instrument_Sliders"); start_button.toggleType (); start_button.size (100, 60); start_button.position (550, 40); start_button.name ("Play"); control_view.addElement (start_button); record_button.toggleType (); record_button.size (100, 60); record_button.position (640, 40); record_button.name ("Record"); control_view.addElement (record_button); clear_button.pushType (); clear_button.size (100, 60); clear_button.position (550, 80); clear_button.name ("Clear"); control_view.addElement (clear_button); xor_button.toggleType (); xor_button.size (100, 60); xor_button.position (640, 80); xor_button.name ("OR"); control_view.addElement (xor_button); instrument_plus_button.pushType (); instrument_plus_button.size (60, 60); instrument_plus_button.position (280, 0); instrument_plus_button.name ("+"); control_view.addElement (instrument_plus_button); instrument_minus_button.pushType (); instrument_minus_button.size (60, 60); instrument_minus_button.position (160, 0); instrument_minus_button.name ("-"); control_view.addElement (instrument_minus_button); instrument_button.pushType (); instrument_button.size (100, 60); instrument_button.position (200, 0); instrument_button.name ("Guitar"); control_view.addElement (instrument_button); and_plus_button.pushType (); and_plus_button.size (60, 60); and_plus_button.position (540, 190); and_plus_button.name ("+"); control_view.addElement (and_plus_button); and_minus_button.pushType (); and_minus_button.size (60, 60); and_minus_button.position (540, 250); and_minus_button.name ("-"); control_view.addElement (and_minus_button); and_page_button.pushType (); and_page_button.size (100, 60); and_page_button.position (520, 220); and_page_button.name ("page "+0); control_view.addElement (and_page_button); for (0 => int a; a < num_and_terms; a++) { for (0 => int b; b < num_digits; b++) { for (0 => int p; p < num_and_pages; p++) { 0 => and_values[instrument][p*num_and_terms+a][b]; } and_buttons[a][b].pushType (); and_buttons[a][b].size (65, 65); and_buttons[a][b].position (40*(num_digits-b-1), 75+40*a); and_buttons[a][b].name (""); control_view.addElement (and_buttons[a][b]); } } for (0 => int b; b < num_digits; b++) { count[b].color (count[b].red); count[b].size (50, 50); count[b].position (8+40*(num_digits-b-1), 42); control_view.addElement (count[b]); } for (0 => int a; a < num_and_terms; a++) { logic[a].color (logic[a].green); logic[a].size (50, 50); logic[a].position (8+40*num_digits, 82+40*a); control_view.addElement (logic[a]); } playing_note.color (playing_note.blue); playing_note.size (50, 50); playing_note.position (8+40*num_digits, 42); control_view.addElement (playing_note); for (0 => int b; b < num_digits; b++) { plus_buttons[b].pushType (); plus_buttons[b].size (60, 60); plus_buttons[b].position (40*(num_digits-b-1)+2, 75+10+40*(num_and_terms+1)); plus_buttons[b].name ("+"); control_view.addElement (plus_buttons[b]); } for (0 => int b; b < num_digits; b++) { minus_buttons[b].pushType (); minus_buttons[b].size (60, 60); minus_buttons[b].position (40*(num_digits-b-1)+2, 75-5+40*(num_and_terms+3)); minus_buttons[b].name ("-"); control_view.addElement (minus_buttons[b]); } for (0 => int b; b < num_digits; b++) { for (0 => int i; i < num_instruments; i++) { 1 => freq_amount[i][b]; } freq_buttons[b].pushType (); freq_buttons[b].size (65, 65); freq_buttons[b].position (40*(num_digits-b-1), 75+40*(num_and_terms+2)); freq_buttons[b].name (""+freq_amount[instrument][b]); control_view.addElement (freq_buttons[b]); } "Volume" => master_volume.name; master_volume.range (0, 100); master_volume.value (20); master_volume.size (200, 75); master_volume.position (550, 300); master_volume.displayFormat (master_volume.integerFormat); control_view.addElement (master_volume); "Base" => base.name; base.range (2, 10); base.value (2); base.size (200, 75); base.position (550, 350); base.displayFormat (base.integerFormat); control_view.addElement (base); "Freq Multiplier" => freq_mult.name; freq_mult.range (1, 100); freq_mult.value (freq_mult_values[instrument]); freq_mult.size (200, 75); freq_mult.position (550, 450); control_view.addElement (freq_mult); "Freq Offset" => freq_offset.name; freq_offset.range (0, 20); freq_offset.value (freq_offset_values[instrument]); freq_offset.size (200, 75); freq_offset.position (550, 500); control_view.addElement (freq_offset); "Notes per Second" => notes_per_second.name; notes_per_second.range (1, 16); notes_per_second.value (6); notes_per_second.size (200, 75); notes_per_second.position (550, 400); notes_per_second.displayFormat (notes_per_second.integerFormat); control_view.addElement (notes_per_second); "Reverb" => reverb.name; reverb.range (0, 1); reverb.value (0.1); reverb.size (200, 75); reverb.position (150, 0); slider_view.addElement (reverb); "Body Size" => body_size.name; body_size.range (0, 1); body_size.value (0.3); body_size.size (200, 75); body_size.position (350, 0); slider_view.addElement (body_size); "Pluck Pos" => pluck_pos.name; pluck_pos.range (0, 1); pluck_pos.value (0.3); pluck_pos.size (200, 75); pluck_pos.position (550, 0); slider_view.addElement (pluck_pos); "String Damping" => string_damping.name; string_damping.range (0, 1); string_damping.value (0.3); string_damping.size (200, 75); string_damping.position (150, 50); slider_view.addElement (string_damping); "String Detune" => string_detune.name; string_detune.range (0, 1); string_detune.value (0.3); string_detune.size (200, 75); string_detune.position (350, 50); slider_view.addElement (string_detune); "After Touch" => after_touch.name; after_touch.range (0, 1); after_touch.value (0.3); after_touch.size (200, 75); after_touch.position (550, 50); slider_view.addElement (after_touch); "Jet Delay" => jet_delay.name; jet_delay.range (0, 1); jet_delay.value (0.3); jet_delay.size (200, 75); jet_delay.position (150, 100); slider_view.addElement (jet_delay); "Jet Reflection" => jet_reflection.name; jet_reflection.range (0, 1); jet_reflection.value (0.9); jet_reflection.size (200, 75); jet_reflection.position (350, 100); slider_view.addElement (jet_reflection); "End Reflection" => end_reflection.name; end_reflection.range (0, 1); end_reflection.value (0.9); end_reflection.size (200, 75); end_reflection.position (550, 100); slider_view.addElement (end_reflection); "Noise Gain" => noise_gain.name; noise_gain.range (0, 1); noise_gain.value (0.3); noise_gain.size (200, 75); noise_gain.position (150, 150); slider_view.addElement (noise_gain); "Vibrato Freq" => vibrato_freq.name; vibrato_freq.range (0, 1000); vibrato_freq.value (500); vibrato_freq.size (200, 75); vibrato_freq.position (350, 150); slider_view.addElement (vibrato_freq); "Vibrato Gain" => vibrato_gain.name; vibrato_gain.range (0, 1); vibrato_gain.value (0.3); vibrato_gain.size (200, 75); vibrato_gain.position (550, 150); slider_view.addElement (vibrato_gain); "Frequency" => snare_freq.name; snare_freq.range (0, 10000); snare_freq.value (3000); snare_freq.size (200, 75); snare_freq.position (150, 200); slider_view.addElement (snare_freq); "Q" => snare_Q.name; snare_Q.range (0, 100); snare_Q.value (10); snare_Q.size (200, 75); snare_Q.position (350, 200); slider_view.addElement (snare_Q); "Decay" => snare_decay.name; snare_decay.range (0, 10000); snare_decay.value (5000); snare_decay.size (200, 75); snare_decay.position (550, 200); slider_view.addElement (snare_decay); "Attack" => snare_attack.name; snare_attack.range (0, 10000); snare_attack.value (2000); snare_attack.size (200, 75); snare_attack.position (150, 250); slider_view.addElement (snare_attack); "Frequency" => drum_freq.name; drum_freq.range (0, 1000); drum_freq.value (100); drum_freq.size (200, 75); drum_freq.position (150, 300); slider_view.addElement (drum_freq); "Pitch Decay" => drum_pitch_decay.name; drum_pitch_decay.range (0.99, 0.9999); drum_pitch_decay.value (0.999); drum_pitch_decay.size (200, 75); drum_pitch_decay.position (350, 300); slider_view.addElement (drum_pitch_decay); "Pitch Attack" => drum_pitch_attack.name; drum_pitch_attack.range (0, 1000); drum_pitch_attack.value (100); drum_pitch_attack.size (200, 75); drum_pitch_attack.position (550, 300); slider_view.addElement (drum_pitch_attack); "Decay" => drum_decay.name; drum_decay.range (0.99, 0.9999); drum_decay.value (0.999); drum_decay.size (200, 75); drum_decay.position (150, 350); slider_view.addElement (drum_decay); "Attack" => drum_attack.name; drum_attack.range (0, 1000); drum_attack.value (100); drum_attack.size (200, 75); drum_attack.position (350, 350); slider_view.addElement (drum_attack); "Drive Gain" => drum_drive_gain.name; drum_drive_gain.range (0, 1); drum_drive_gain.value (0.75); drum_drive_gain.size (200, 75); drum_drive_gain.position (550, 350); slider_view.addElement (drum_drive_gain); "Filter" => drum_filter.name; drum_filter.range (0, 1000); drum_filter.value (500); drum_filter.size (200, 75); drum_filter.position (150, 400); slider_view.addElement (drum_filter); "Body Size" => mandolin_body_size.name; mandolin_body_size.range (0, 1); mandolin_body_size.value (0.3); mandolin_body_size.size (200, 75); mandolin_body_size.position (150, 450); slider_view.addElement (mandolin_body_size); "Pluck Pos" => mandolin_pluck_pos.name; mandolin_pluck_pos.range (0, 1); mandolin_pluck_pos.value (0.3); mandolin_pluck_pos.size (200, 75); mandolin_pluck_pos.position (350, 450); slider_view.addElement (mandolin_pluck_pos); "String Damping" => mandolin_string_damping.name; mandolin_string_damping.range (0, 1); mandolin_string_damping.value (0.3); mandolin_string_damping.size (200, 75); mandolin_string_damping.position (150, 500); slider_view.addElement (mandolin_string_damping); "String Detune" => mandolin_string_detune.name; mandolin_string_detune.range (0, 1); mandolin_string_detune.value (0.3); mandolin_string_detune.size (200, 75); mandolin_string_detune.position (350, 500); slider_view.addElement (mandolin_string_detune); "After Touch" => mandolin_after_touch.name; mandolin_after_touch.range (0, 1); mandolin_after_touch.value (0.3); mandolin_after_touch.size (200, 75); mandolin_after_touch.position (550, 450); slider_view.addElement (mandolin_after_touch); "Gain" => guitar_gain.name; guitar_gain.range (0, 1); guitar_gain.value (0.5); guitar_gain.size (150, 75); guitar_gain.position (0, 35); slider_view.addElement (guitar_gain); "Gain" => flute_gain.name; flute_gain.range (0, 1); flute_gain.value (0.5); flute_gain.size (150, 75); flute_gain.position (0, 135); slider_view.addElement (flute_gain); "Gain" => snare_gain.name; snare_gain.range (0, 1); snare_gain.value (0.5); snare_gain.size (150, 75); snare_gain.position (0, 235); slider_view.addElement (snare_gain); "Gain" => drum_gain.name; drum_gain.range (0, 1); drum_gain.value (0.5); drum_gain.size (150, 75); drum_gain.position (0, 335); slider_view.addElement (drum_gain); "Gain" => mandolin_gain.name; mandolin_gain.range (0, 1); mandolin_gain.value (0.5); mandolin_gain.size (150, 75); mandolin_gain.position (0, 485); slider_view.addElement (mandolin_gain); Guitar.toggleType (); Guitar.size (120, 60); Guitar.position (0, 0); Guitar.name ("Guitar"); Guitar.state (1); slider_view.addElement (Guitar); Flute.toggleType (); Flute.size (120, 60); Flute.position (0, 100); Flute.name ("Flute"); slider_view.addElement (Flute); Snare.toggleType (); Snare.size (120, 60); Snare.position (0, 200); Snare.name ("Snare"); slider_view.addElement (Snare); Drum.toggleType (); Drum.size (120, 60); Drum.position (0, 300); Drum.name ("Drum"); slider_view.addElement (Drum); Mandolin.toggleType (); Mandolin.size (120, 60); Mandolin.position (0, 450); Mandolin.name ("Mandolin"); slider_view.addElement (Mandolin); slider_view.display (); control_view.display (); // many thanks to kijjaz for the mandolin-based Stratocaster guitar sound with overdrive: // Mandolin as the electric guitar test: by kijjaz (kijjaz@yahoo.com) // feel free to use, modify, publish class kjzGuitar101 { Mandolin str[3]; // create mandolin strings SinOsc overdrive => NRev rev => Gain output; // create overdrive to reverb to dac overdrive.sync(1); // make overdrive do Sine waveshaping rev.mix(0.02); // set reverb mix rev.gain(0.6); // set master gain output.gain(1.0); // set output gain // connect strings, set string damping for(int i; i < 3; i++) { str[i] => overdrive; .9 => str[i].stringDamping; 0.5 => str[i].bodySize; } } kjzGuitar101 A; // lead guitar A.output => Gain master => WvOut wave_out => dac; 0 => master.op; master.gain (0.2); Flute B; B => master; // many thanks to kijjaz (kijjaz@yahoo.com) for the snare code examples, rock on kijjaz! // easy white noise snare class kjzSnare101 { // note: connect output to external sources to connect Noise s => Gain s_env => LPF s_f => Gain output; // white noise source Impulse i => Gain g => Gain g_fb => g => LPF g_f => s_env; 3 => s_env.op; // make s envelope a multiplier s_f.set(3000, 4); // set default drum filter g_fb.gain(1.0 - 1.0/3000); // set default drum decay g_f.set(200, 1); // set default drum attack fun void setFilter(float f, float Q) { s_f.set(f, Q); } fun void setDecay(float decay) { g_fb.gain(1.0 - 1.0 / decay); // decay unit: samples! } fun void setAttack(float attack) { g_f.freq(attack); // attack unit: Hz! } fun void hit(float velocity) { velocity => i.next; } } kjzSnare101 C; C.output => master; // simple analog-sounding bass drum with pitch and amp decay and sine overdrive class kjzBD101 { Impulse i; // the attack i => Gain g1 => Gain g1_fb => g1 => LPF g1_f => Gain BDFreq; // BD pitch envelope i => Gain g2 => Gain g2_fb => g2 => LPF g2_f; // BD amp envelope // drum sound oscillator to amp envelope to overdrive to LPF to output BDFreq => SinOsc s => Gain ampenv => SinOsc s_ws => LPF s_f => Gain output; g2_f => ampenv; // amp envelope of the drum sound 3 => ampenv.op; // set ampenv a multiplier 1 => s_ws.sync; // prepare the SinOsc to be used as a waveshaper for overdrive // set default 80.0 => BDFreq.gain; // BD initial pitch: 80 hz 1.0 - 1.0 / 2000 => g1_fb.gain; // BD pitch decay g1_f.set(100, 1); // set BD pitch attack 1.0 - 1.0 / 4000 => g2_fb.gain; // BD amp decay g2_f.set(50, 1); // set BD amp attack .75 => ampenv.gain; // overdrive gain s_f.set(600, 1); // set BD lowpass filter fun void hit(float v) { v => i.next; } fun void setFreq(float f) { f => BDFreq.gain; } fun void setPitchDecay(float f) { f => g1_fb.gain; } fun void setPitchAttack(float f) { f => g1_f.freq; } fun void setDecay(float f) { f => g2_fb.gain; } fun void setAttack(float f) { f => g2_f.freq; } fun void setDriveGain(float g) { g => ampenv.gain; } fun void setFilter(float f) { f => s_f.freq; } } kjzBD101 D; D.output => master; Mandolin E; E => master; E.bodySize(0.35); E.pluckPos(0.70); function void start () { while (true) { // wait for the start button to be pushed start_button.onChange () => now; if (start_button.state ()) { 1 => master.op; start_button.name ("Stop"); } else { 0 => master.op; start_button.name ("Play"); if (record_button.state ()) { record_button.state (0); } } } } function void record () { while (true) { // wait for the start button to be pushed record_button.onChange () => now; if (record_button.state ()) { 1 => master.op; start_button.state (1); "Guitar_Lab.wav" => wave_out.wavFilename; } else { 0 => master.op; start_button.state (0); wave_out.closeFile (); } } } function void clear () { while (true) { // wait for the start button to be pushed clear_button.onChange () => now; for (0 => int b; b < num_digits; b++) { 0 => j[b]; count[b].unlight (); } } } function void or_xor () { while (true) { xor_button.onChange () => now; if (xor_button.state ()) { xor_button.name ("XOR"); } else { xor_button.name ("OR"); } } } function void freq_mult_values_adj () { while (true) { freq_mult.onChange () => now; freq_mult.value () => freq_mult_values[instrument]; } } function void freq_offset_values_adj () { while (true) { freq_offset.onChange () => now; freq_offset.value () => freq_offset_values[instrument]; } } function void instrument_plus () { while (true) { instrument_plus_button.onChange () => now; if (instrument_plus_button.state ()) { (instrument + 1) % num_instruments => instrument; change_current_instrument (); } } } function void instrument_minus () { while (true) { instrument_minus_button.onChange () => now; if (instrument_minus_button.state ()) { if (instrument == 0) { num_instruments => instrument; } (instrument - 1) % num_instruments => instrument; change_current_instrument (); } } } function void and_plus () { while (true) { and_plus_button.onChange () => now; if (and_plus_button.state ()) { (and_page + 1) % num_and_pages => and_page; change_current_instrument (); and_page_button.name ("page "+and_page); } } } function void and_minus () { while (true) { and_minus_button.onChange () => now; if (and_minus_button.state ()) { if (and_page == 0) { num_and_pages => and_page; } (and_page - 1) % num_and_pages => and_page; change_current_instrument (); and_page_button.name ("page "+and_page); } } } function void change_current_instrument () { if (instrument == 0) { instrument_button.name ("Guitar"); } if (instrument == 1) { instrument_button.name ("Flute"); } if (instrument == 2) { instrument_button.name ("Snare"); } if (instrument == 3) { instrument_button.name ("Drum"); } if (instrument == 4) { instrument_button.name ("Mandolin"); } for (0 => int a; a < num_and_terms; a++) { for (0 => int b; b < num_digits; b++) { if (and_values[instrument][and_page*num_and_terms+a][b] == 0) { and_buttons[a][b].name (""); } if (and_values[instrument][and_page*num_and_terms+a][b] == 1) { and_buttons[a][b].name ("&"); } if (and_values[instrument][and_page*num_and_terms+a][b] == 2) { and_buttons[a][b].name ("!"); } if (and_values[instrument][and_page*num_and_terms+a][b] > 2) { 0 => and_values[instrument][a][b]; and_buttons[a][b].name (""); } } } for (0 => int b; b < num_digits; b++) { freq_buttons[b].name (""+freq_amount[instrument][b]); } freq_mult.value (freq_mult_values[instrument]); freq_offset.value (freq_offset_values[instrument]); } function void and_buttons_adj (int a, int b) { while (true) { and_buttons[a][b].onChange () => now; 1 +=> and_values[instrument][and_page*num_and_terms+a][b]; if (and_values[instrument][and_page*num_and_terms+a][b] == 0) { and_buttons[a][b].name (""); } if (and_values[instrument][and_page*num_and_terms+a][b] == 1) { and_buttons[a][b].name ("&"); } if (and_values[instrument][and_page*num_and_terms+a][b] == 2) { and_buttons[a][b].name ("!"); } if (and_values[instrument][and_page*num_and_terms+a][b] > 2) { 0 => and_values[instrument][and_page*num_and_terms+a][b]; and_buttons[a][b].name (""); } and_buttons[a][b].onChange () => now; } } function void plus_buttons_adj (int b) { while (true) { plus_buttons[b].onChange () => now; 1 +=> freq_amount[instrument][b]; freq_buttons[b].name (""+freq_amount[instrument][b]); plus_buttons[b].onChange () => now; } } function void minus_buttons_adj (int b) { while (true) { minus_buttons[b].onChange () => now; 1 -=> freq_amount[instrument][b]; freq_buttons[b].name (""+freq_amount[instrument][b]); minus_buttons[b].onChange () => now; } } function void volume_adj () { while (true) { // wait for the volume slider to be changed master_volume.onChange () => now; master_volume.value () / 100.0 => master.gain; } } function void base_adj () { while (true) { base.onChange () => now; base.value () $ int => n; } } function void reverb_adj () { while (true) { reverb.onChange () => now; reverb.value () => A.rev.mix; } } function void body_size_adj () { while (true) { body_size.onChange () => now; for(int i; i < 3; i++) { body_size.value () => A.str[i].bodySize; } } } function void pluck_pos_adj () { while (true) { pluck_pos.onChange () => now; for(int i; i < 3; i++) { pluck_pos.value () => A.str[i].pluckPos; } } } function void string_damping_adj () { while (true) { string_damping.onChange () => now; for(int i; i < 3; i++) { string_damping.value () => A.str[i].stringDamping; } } } function void string_detune_adj () { while (true) { string_detune.onChange () => now; for(int i; i < 3; i++) { string_detune.value () => A.str[i].stringDetune; } } } function void after_touch_adj () { while (true) { after_touch.onChange () => now; for(int i; i < 3; i++) { after_touch.value () => A.str[i].afterTouch; } } } function void jet_delay_adj () { while (true) { jet_delay.onChange () => now; jet_delay.value () => B.jetDelay; } } function void jet_reflection_adj () { while (true) { jet_reflection.onChange () => now; jet_reflection.value () => B.jetReflection; } } function void end_reflection_adj () { while (true) { end_reflection.onChange () => now; end_reflection.value () => B.endReflection; } } function void noise_gain_adj () { while (true) { noise_gain.onChange () => now; noise_gain.value () => B.noiseGain; } } function void vibrato_freq_adj () { while (true) { vibrato_freq.onChange () => now; vibrato_freq.value () => B.vibratoFreq; } } function void vibrato_gain_adj () { while (true) { vibrato_gain.onChange () => now; vibrato_gain.value () => B.vibratoGain; } } function void snare_freq_adj () { while (true) { snare_freq.onChange () => now; C.setFilter (snare_freq.value (), snare_Q.value()); } } function void snare_Q_adj () { while (true) { snare_Q.onChange () => now; C.setFilter (snare_freq.value (), snare_Q.value()); } } function void snare_decay_adj () { while (true) { snare_decay.onChange () => now; C.setDecay (snare_decay.value ()); } } function void snare_attack_adj () { while (true) { snare_attack.onChange () => now; C.setAttack (snare_attack.value ()); } } function void drum_freq_adj () { while (true) { drum_freq.onChange () => now; D.setFreq (drum_freq.value ()); } } function void drum_pitch_decay_adj () { while (true) { drum_pitch_decay.onChange () => now; D.setPitchDecay (drum_pitch_decay.value ()); } } function void drum_pitch_attack_adj () { while (true) { drum_pitch_attack.onChange () => now; D.setPitchAttack (drum_pitch_attack.value ()); } } function void drum_decay_adj () { while (true) { drum_decay.onChange () => now; D.setDecay (drum_decay.value ()); } } function void drum_attack_adj () { while (true) { drum_attack.onChange () => now; D.setAttack (drum_attack.value ()); } } function void drum_drive_gain_adj () { while (true) { drum_drive_gain.onChange () => now; D.setDriveGain (drum_drive_gain.value ()); } } function void drum_filter_adj () { while (true) { drum_filter.onChange () => now; D.setFilter (drum_filter.value ()); } } function void mandolin_body_size_adj () { while (true) { mandolin_body_size.onChange () => now; E.bodySize (mandolin_body_size.value ()); } } function void mandolin_pluck_pos_adj () { while (true) { mandolin_pluck_pos.onChange () => now; E.pluckPos (mandolin_pluck_pos.value ()); } } function void mandolin_string_damping_adj () { while (true) { mandolin_string_damping.onChange () => now; E.stringDamping (mandolin_string_damping.value ()); } } function void mandolin_string_detune_adj () { while (true) { mandolin_string_detune.onChange () => now; E.stringDetune (mandolin_string_detune.value ()); } } function void mandolin_after_touch_adj () { while (true) { mandolin_after_touch.onChange () => now; E.afterTouch (mandolin_after_touch.value ()); } } function void guitar_gain_adj () { while (true) { guitar_gain.onChange () => now; A.output.gain (guitar_gain.value ()); } } function void flute_gain_adj () { while (true) { flute_gain.onChange () => now; B.gain (flute_gain.value ()); } } function void snare_gain_adj () { while (true) { snare_gain.onChange () => now; C.output.gain (snare_gain.value ()); } } function void drum_gain_adj () { while (true) { drum_gain.onChange () => now; D.output.gain (drum_gain.value ()); } } function void mandolin_gain_adj () { while (true) { mandolin_gain.onChange () => now; E.gain (mandolin_gain.value ()); } } function void flute_adj () { while (true) { Flute.onChange () => now; if (Flute.state ()) { jet_delay.value () => B.jetDelay; jet_reflection.value () => B.jetReflection; end_reflection.value () => B.endReflection; noise_gain.value () => B.noiseGain; vibrato_freq.value () => B.vibratoFreq; vibrato_gain.value () => B.vibratoGain; B.pressure (0.98); B.startBlowing (1); B.noteOn (0.5); flute_gain.value () => B.gain; } else { B.stopBlowing (1); B.noteOff (0); B.gain (0); } } } function void initialize_instruments () { master_volume.value () / 100.0 => master.gain; base.value () $ int => n; reverb.value () => A.rev.mix; for(int i; i < 3; i++) { body_size.value () => A.str[i].bodySize; } for(int i; i < 3; i++) { pluck_pos.value () => A.str[i].pluckPos; } for(int i; i < 3; i++) { string_damping.value () => A.str[i].stringDamping; } for(int i; i < 3; i++) { string_detune.value () => A.str[i].stringDetune; } for(int i; i < 3; i++) { after_touch.value () => A.str[i].afterTouch; } jet_delay.value () => B.jetDelay; jet_reflection.value () => B.jetReflection; end_reflection.value () => B.endReflection; noise_gain.value () => B.noiseGain; vibrato_freq.value () => B.vibratoFreq; vibrato_gain.value () => B.vibratoGain; C.setFilter (snare_freq.value (), snare_Q.value()); C.setFilter (snare_freq.value (), snare_Q.value()); C.setDecay (snare_decay.value ()); C.setAttack (snare_attack.value ()); D.setFreq (drum_freq.value ()); D.setPitchDecay (drum_pitch_decay.value ()); D.setPitchAttack (drum_pitch_attack.value ()); D.setDecay (drum_decay.value ()); D.setAttack (drum_attack.value ()); D.setDriveGain (drum_drive_gain.value ()); D.setFilter (drum_filter.value ()); E.bodySize (mandolin_body_size.value ()); E.pluckPos (mandolin_pluck_pos.value ()); E.stringDamping (mandolin_string_damping.value ()); E.stringDetune (mandolin_string_detune.value ()); E.afterTouch (mandolin_after_touch.value ()); A.output.gain (guitar_gain.value ()); B.gain (flute_gain.value ()); C.output.gain (snare_gain.value ()); D.output.gain (drum_gain.value ()); E.gain (mandolin_gain.value ()); } spork ~ start (); spork ~ record (); spork ~ clear (); spork ~ or_xor (); spork ~ freq_mult_values_adj (); spork ~ freq_offset_values_adj (); spork ~ instrument_plus (); spork ~ instrument_minus (); for (0 => int b; b < num_digits; b++) { spork ~ plus_buttons_adj (b); spork ~ minus_buttons_adj (b); } for (0 => int a; a < num_and_terms; a++) { for (0 => int b; b < num_digits; b++) { spork ~ and_buttons_adj (a, b); } } spork ~ volume_adj (); spork ~ base_adj (); spork ~ and_plus (); spork ~ and_minus (); spork ~ reverb_adj (); spork ~ body_size_adj (); spork ~ pluck_pos_adj (); spork ~ string_damping_adj (); spork ~ string_detune_adj (); spork ~ after_touch_adj (); spork ~ jet_delay_adj (); spork ~ jet_reflection_adj (); spork ~ end_reflection_adj (); spork ~ noise_gain_adj (); spork ~ vibrato_freq_adj (); spork ~ vibrato_gain_adj (); spork ~ snare_freq_adj (); spork ~ snare_Q_adj (); spork ~ snare_decay_adj (); spork ~ snare_attack_adj (); spork ~ drum_freq_adj (); spork ~ drum_pitch_decay_adj (); spork ~ drum_pitch_attack_adj (); spork ~ drum_decay_adj (); spork ~ drum_attack_adj (); spork ~ drum_drive_gain_adj (); spork ~ drum_filter_adj (); spork ~ mandolin_body_size_adj (); spork ~ mandolin_pluck_pos_adj (); spork ~ mandolin_string_damping_adj (); spork ~ mandolin_string_detune_adj (); spork ~ mandolin_after_touch_adj (); spork ~ guitar_gain_adj (); spork ~ flute_gain_adj (); spork ~ snare_gain_adj (); spork ~ drum_gain_adj (); spork ~ mandolin_gain_adj (); spork ~ flute_adj (); // put slider values into instruments initialize_instruments (); while (true) { for (0 => j[11]; j[11] < n; j[11]++) { for (0 => j[10]; j[10] < n; j[10]++) { for (0 => j[9]; j[9] < n; j[9]++) { for (0 => j[8]; j[8] < n; j[8]++) { for (0 => j[7]; j[7] < n; j[7]++) { for (0 => j[6]; j[6] < n; j[6]++) { for (0 => j[5]; j[5] < n; j[5]++) { for (0 => j[4]; j[4] < n; j[4]++) { for (0 => j[3]; j[3] < n; j[3]++) { for (0 => j[2]; j[2] < n; j[2]++) { for (0 => j[1]; j[1] < n; j[1]++) { for (0 => j[0]; j[0] < n; j[0]++) { for (0 => int b; b < num_digits; b++) { if (j[b]) { count[b].light (); } else { count[b].unlight (); } } for (0 => int i; i < num_instruments; i++) { 0 => play_note; for (0 => int p; p < num_and_pages; p++) { for (0 => int a; a < num_and_terms; a++) { 0 => and_term; 0 => and_bits; for (0 => int b; b < num_digits; b++) { if (and_values[i][p*num_and_terms+a][b] == 1) { if (j[b]) { 1 +=> and_term; } 1 +=> and_bits; } if (and_values[i][p*num_and_terms+a][b] == 2) { if (!j[b]) { 1 +=> and_term; } 1 +=> and_bits; } } if ( (and_term == and_bits) && (and_bits > 0) ) { if (xor_button.state ()) { play_note ^ 1 => play_note; } else { 1 => play_note; } if ( (i == instrument) && (p == and_page) ) { logic[a].light (); } } else { if ( (i == instrument) && (p == and_page) ) { logic[a].unlight (); } } } } if (i == instrument) { if (play_note) { playing_note.light (); } else { playing_note.unlight (); } } if (play_note) { 0 => freq; for (0 => int b; b < num_digits; b++) { j[b]*freq_amount[i][b] +=> freq; } freq_mult_values[i] * (freq_offset_values[i] + freq) => freq; if (Guitar.state () && (i == 0)) { for (0 => int i; i < 3; i++) { freq * (i+1) => A.str[i].freq; } for (0 => int i; i < 3; i++) { 0.8 - i/4.0 => A.str[i].pluck; } } if (Flute.state () && (i == 1)) { B.noteOff (0); B.freq (freq); B.noteOn (0.5); } if (Snare.state () && (i == 2)) { C.hit (0.8); } if (Drum.state () && (i == 3)) { D.hit (1.0); } if (Mandolin.state () && (i == 4)) { E.freq (freq); E.pluck (0.5); } } } // advance time while (!start_button.state ()) { 1::second => now; } 1::second / notes_per_second.value () => now; } } } } } } } } } } } } }