Wavetable wave4 = Waves.randomNHarms(4); Wavetable wave8 = Waves.randomNHarms(8); Wavetable wave16 = Waves.randomNHarms(16); Wavetable wave32 = Waves.randomNHarms(32); Waveform[] waveforms = new Waveform[] { Waves.SINE, Waves.TRIANGLE, Waves.SAW, Waves.SQUARE, Waves.QUARTERPULSE, wave4, wave8, wave16, wave32 }; void kick( float time ) { mainOut.playNote( time, 0.3f, new Kick() ); } void snare( float time, float amp ) { mainOut.playNote( time, 0.3f, new Snare(amp) ); } void hat( float time, float amp ) { mainOut.playNote( time, 0.5f, new Hat(amp) ); } void tone( Summer bus, float time, Waveform wave, float freq, float amp, float dur, float pan ) { mainOut.playNote( time, dur, new Tone(bus, wave, freq, amp, pan) ); } int prevNoteIndex = 0; void generateMeasure( Summer bus, Waveform wave, float[] probs, int[][] notes, int lowOctave, int hiOctave, float panRange ) { int scaleKey = int(currentKey.value()); for( int i = 0; i < probs.length; ++i ) { if ( random(1.f) < probs[i] ) { int[] prevNoteList = notes[prevNoteIndex]; int nextNoteIndex = prevNoteList[int(random(1,prevNoteList.length))]; int baseNote = notes[nextNoteIndex][0] + scaleKey; int octave = int(random(lowOctave,hiOctave)); int note = baseNote + octave * 12; // println("With PrevNoteIndex(" + prevNoteIndex + "), NextNodeIndex(" + nextNoteIndex + "), Queueing midi note " + note); float freq = Frequency.ofMidiNote( note ).asHz(); float amp = random(0.9f, 1.f); float dura = random(0.15f, 0.25f); float pan = 0.f; if ( panRange != 0.f ) { pan = random(panRange) + 0.2f; if ( random(1.f) < 0.5f ) { pan *= -1.f; } } float time = i * 0.25f; // shuffle odd notes if ( i % 2 != 0 ) { time += 0.08f * Shuffle; } tone( bus, time, wave, freq, amp, dura, random(-pan,pan) ); prevNoteIndex = nextNoteIndex; } } } // This instrument gives us a way to continually generate a measure of note data based // on the current settings of our UI. We start the loop by cueing a Looper at 0 with // a duration of one measure and then when that Looper gets its noteOff it will // queue another Looper. class Looper implements Instrument { void noteOn( float dur ) { int scaleIndex = int(currentScale.value()); generateMeasure( melodyBus, waveforms[ int(melodyWave.value()) ], noteProb, Scales[scaleIndex], 5, 7, 0.8 ); generateMeasure( bassBus, waveforms[ int(bassWave.value()) ], bassProb, Scales[scaleIndex], 2, 4, 0.f ); if ( Kick ) { kick( 0.f ); kick( 1.f ); kick( 2.f ); kick( 3.f ); } if ( Snare ) { snare( 1.f, 1.0 ); snare( 2.75 + 0.08f * Shuffle, 1.5 ); snare( 3.5, 1.0 ); } if ( Hat ) { hat( 0.5f, 0.5f ); hat( 1.5f, 0.5f ); hat( 1.75f + 0.08 * Shuffle, 0.25f ); hat( 2.5f, 0.5f ); hat( 3.25f + 0.08 * Shuffle, 0.25f ); hat( 3.75f + 0.08 * Shuffle, 0.5f ); } } void noteOff() { mainOut.setTempo( Tempo ); mainOut.playNote( 0.f, 4.0, new Looper() ); } } class Kick implements Instrument { Line freqSweep; Line ampSweep; Oscil osc; Kick() { osc = new Oscil( 80.f, 1.f, Waves.SINE ); freqSweep = new Line( 0.1f, 120.f, 20.f ); ampSweep = new Line( 0.1f, 0.7f, 0.f ); freqSweep.patch( osc.frequency ); ampSweep.patch( osc.amplitude ); } void noteOn( float dur ) { ampSweep.activate(); freqSweep.activate(); osc.patch( mainOut ); } void noteOff() { osc.unpatch( mainOut ); } } class Snare implements Instrument { Noise noize; Multiplier noizeAmp; Line ampSweep; BandPass filt; Snare( float amp ) { noize = new Noise( amp, Noise.Tint.WHITE ); noizeAmp = new Multiplier( 1.f ); ampSweep = new Line( 0.05f ); filt = new BandPass( 200.f, 200.f, mainOut.sampleRate() ); noize.patch( noizeAmp ).patch( filt ); ampSweep.patch( noizeAmp.amplitude ); } void noteOn( float dur ) { ampSweep.activate(); filt.patch( mainOut ); } void noteOff() { filt.unpatch( mainOut ); } } class Hat implements Instrument { Noise noize; Multiplier noizeAmp; Line ampSweep; HighPassSP filt; Hat( float amp ) { noize = new Noise( amp * 0.8f, Noise.Tint.WHITE ); noizeAmp = new Multiplier( 1.f ); ampSweep = new Line( 0.01, 1.f, 0.f ); filt = new HighPassSP( 10000, mainOut.sampleRate() ); noize.patch( noizeAmp ).patch( filt ); ampSweep.patch( noizeAmp.amplitude ); } void noteOn( float dur ) { ampSweep.activate(); filt.patch( mainOut ); } void noteOff() { filt.unpatch( mainOut ); } } class Tone implements Instrument { Summer out; Oscil wave; ADSR adsr; Pan panner; Tone( Summer bus, Waveform inwave, float freq, float amp, float pan ) { out = bus; wave = new Oscil( freq, amp, inwave ); panner = new Pan( pan ); adsr = new ADSR( amp, 0.01f, 0.01f, amp * 0.7f, 0.2f ); adsr.setAudioChannelCount( 2 ); wave.patch( panner ).patch( adsr ); } void noteOn( float dur ) { adsr.patch( out ); adsr.noteOn(); } void noteOff() { adsr.noteOff(); adsr.unpatchAfterRelease( out ); } }