From 9eedd512e421faf3e516124f0d9a29d1686cb262 Mon Sep 17 00:00:00 2001 From: Ge Wang Date: Mon, 14 Oct 2024 20:58:56 -0700 Subject: [PATCH] update examples and release notes --- VERSIONS | 24 +++- examples/stk/jacobass-algo1.ck | 131 ++++++++++++++++++ ...keytonk-algo3.ck => nylon-guitar-algo1.ck} | 56 ++++++-- 3 files changed, 199 insertions(+), 12 deletions(-) create mode 100644 examples/stk/jacobass-algo1.ck rename examples/stk/{honkeytonk-algo3.ck => nylon-guitar-algo1.ck} (60%) diff --git a/VERSIONS b/VERSIONS index 67e6f47fe..5d7c4b1f4 100644 --- a/VERSIONS +++ b/VERSIONS @@ -2,28 +2,46 @@ ChucK VERSIONS log ------------------ -1.5.3.2 +1.5.3.2 (October 2024) ======= +*** ChuGL maintanance patch *** +- (updated) backend WebGPU version to wgpu-22.1.0.5 +- (added) OpenGL fallback on machines where modern graphics APIs (vulkan, metal, direct3d) + are not supported +- (fixed) shreds can now exit a GG.nextFrame() loop without hanging the window +- (added) GG.unregisterShred() to manually unregister a graphics shred +- (added) new examples + - deep/particles.ck : musical partical system + - deep/sprite_animation.ck : sprite animation via sprite sheets +- (fixed) race condition on window resize +******************************* - (added) MidiFileIn.bpm() "Same as beatsPerMinute()." - (added) MidiFileIn.ticksPerQuarter(); -- (added) MidiFileIn.tpq(); "Get the ticks per quarter (TPQ) value from the MIDI file header." +- (added) MidiFileIn.tpq(); + "Same as ticksPerQuarter()." - (fixed) documentation for MidiMsg.when: "Duration since the last MidiMsg (only valid for MidiFileIn)." - (fixed, windows) SndBuf issue when compiled with UNICODE (FYI SndBuf is still ANSI, but this averts an error due to char width mismatch) - (changed, developer) chuck global manager getGlobalUGenSamples() now handles multi-channel implications for Chunity support for stereo +- (added) new examples (FM Synthesis) + examples/stk/jacobass-algo1.ck + (such groove, much Algorithm 1) + examples/stk/nylon-guitar-algo1.ck + (updated/renamed from honkeytonk-algo3.ck) 1.5.3.1 (October 2024) +======= *** ChuGL maintanance patch *** - (fixed) crash caused by calling UI functions before calling GG.nextFrame(); now prints a warning with a hint to call GG.nextFrame() - (fixed) CPU and memory spikes when minimizing a ChuGL window - (fixed) crash caused by immediately disconnecting GGen after --> - ***************************** +******************************* - (fixed) ADSR constructors now work correctly - (fixed) compiler now reports line numbers and caret position correctly after a multi-line string literal diff --git a/examples/stk/jacobass-algo1.ck b/examples/stk/jacobass-algo1.ck new file mode 100644 index 000000000..b54bcc133 --- /dev/null +++ b/examples/stk/jacobass-algo1.ck @@ -0,0 +1,131 @@ +// name: JacoBass-algo1.ck +// desc: ALL NEW for 2024! JacoBass 4op FM (TX81Z Algorithm 1) +// This Algorithm can also do many other classic patches +// See honkeytonk-algo1.ck, nylon-guitar-algo1.ck, etc. +// for how to do this +// +// author: Perry R. Cook +// date: June 2024, for Hackathon 2024 +// needs chuck 1.4.1.0 or above + +// to learn more about FM Algorithm 1, uncomment this: +// HnkyTonk.help(); + +public class JacoBass extends Chugraph { + // use Algorithm 1 + HnkyTonk b => Pan2 p => Chorus c => NRev r => outlet; + 0.04 => r.mix; + + [1,1,1,7] @=> int waveForms[]; + // [99,80,81,67] @=> int opGains[]; // from the actual patch, too bright + [99,80,81,37] @=> int opGains[]; + [0.5,0.48,0.52,1.0] @=> float ratios[]; + // [17,16,21,7] @=> int attacks[]; // from the actual patch + [17,21,21,7] @=> int attacks[]; // I like these better + [8,11,11,2] @=> int decays[]; + [11,12,11,15] @=> int sustains[]; + [8,8,8,8] @=> int releases[]; + + for (int op; op < 4; op++) { + // b.setOpWave(op,waveForms[op]); // sine waves all + b.opGain(op,b.getFMTableGain(opGains[op])); + b.opADSR(op, b.getFMTableTime(attacks[op]), + b.getFMTableTime(decays[op]), + b.getFMTableSusLevel(sustains[op]), + b.getFMTableTime(releases[op])); + b.opRatio(op,ratios[op]); + b.lfoDepth(0.1); + } + + fun void freq(float f) { + f => b.freq; + } + + fun void noteOn(int n) { + n => b.noteOn; + } + + fun void noteOff(int n) { + n => b.noteOff; + } +} + +JacoBass b => NRev rev => dac; // solo bass +0.03 => rev.mix; +Noise n => ADSR e => ResonZ rez => Pan2 p => rev; // "hi hat" +0.4 => p.pan; +Impulse imp => ResonZ rez2 => rev; // "kick drum" +9000 => rez.freq; 12 => rez.Q; 3.0 => rez.gain; // hi hat +100 => rez2.freq; 8 => rez2.Q; // kick drum +.5 => rev.gain; // a volume knob + +0.12::second => dur S; +0 => int beat; +0 => int meas; // 0 = flag to start, > 0 = measure# +1 => int notDone; + +Std.mtof(48) => b.freq; // a couple of solo bass notes +1 => b.noteOn; +second/2 => now; +Std.mtof(64) => b.freq; // to start things off +//1 => b.noteOn; +1.3*second => now; + +Std.mtof(60) => b.freq; +// 1 => b.noteOn; 0.12::second; +// 1 => b.noteOn; 3*0.12::second; + +while( notDone ) { + // do drums and keep track of song position + spork ~ teenTown(); + for (1 => int meas; meas < 33; meas++) + { + 300 => imp.next; // kick drum + (0.001,0.12,0.0,0.001) => e.set; // hi hat closed + 1 => e.keyOn; + S => now; + if (maybe) 1 => e.keyOn; + S => now; + (0.001,0.24,0.0,0.001) => e.set; // hi hat open + 1 => e.keyOn; + S => now; + if (beat % 4 == 3) 1 => e.keyOn; + S => now; + beat++; + } +} + +fun void teenTown() { + // transcription of the 1st few bars + [36,48,36,46,36,43,36,39,40,43,45,43,40,38,37,45, + 42,35,35,29,32,33,36,38,36,41,33,43,44,45,48,50, + 51,52,47,45,47,38,38,39,40,43,38,38,35,36,37,45, + 42,36,35,40,37,38,38,36,29,29,36,37,38,40,41,42, + 43,44,45,39] @=> int notes[]; + [0.00, 0.12, 0.23, 0.35, 0.47, 0.59, 0.70, 0.82, + 0.94, 1.05, 1.17, 1.29, 1.41, 1.52, 1.64, 1.88, + 1.99, 2.11, 2.34, 3.75, 3.98, 4.10, 4.22, 4.34, + 4.45, 4.57, 4.69, 4.80, 4.92, 5.04, 5.16, 5.27, + 5.39, 5.51, 5.62, 5.74, 5.86, 5.98, 6.09, 7.85, + 7.97, 8.09, 8.20, 8.44, 9.49, 9.61, 9.73, 9.84, + 9.96, 10.08, 10.20, 10.31, 10.43, 11.60, 11.72, 11.84, + 11.95, 12.29, 13.69, 13.81, 13.93, 14.16, 14.28, 14.40, + 14.63, 14.85, 14.87, 14.95] @=> float ons[]; + + [S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, + S, S, S, 0.23::second, S, S, S, S, S, S, S, S, S, S, S, S, + S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, S, + S, S, S, S, 0.70::second, S, S, S, S, S, S, S, S, S, S, S, + S, S, S, S] @=> dur durs[]; + + 3*S => now; // rests to begin + now => time start; + for (int i; i < notes. cap(); i++) { + Std.mtof(notes[i]+12) => b.freq; + 1 => b.noteOn; + <<< Std.ftoa(now/second,2), i, notes[i] >>>; + durs[i] => now; + 1 => b.noteOff; + while (ons[i] > ((now-start)/second)) ms => now; + } +} diff --git a/examples/stk/honkeytonk-algo3.ck b/examples/stk/nylon-guitar-algo1.ck similarity index 60% rename from examples/stk/honkeytonk-algo3.ck rename to examples/stk/nylon-guitar-algo1.ck index fa0b202e2..2cc061455 100644 --- a/examples/stk/honkeytonk-algo3.ck +++ b/examples/stk/nylon-guitar-algo1.ck @@ -1,15 +1,15 @@ -// name: hevymetl-acoustic-algo3.ck -// desc: how to turn HnkyTonk (Algorithm 3) into an acoustic guitar!! +// name: nylon-guitar-algo1.ck +// desc: how to turn HnkyTonk (Algorithm 1) into an acoustic guitar!! // now you can transcribe almost directly from a TX81 Patch!!! // // author: Perry R. Cook // date: June 2021, for REPAIRATHON 2021 // needs chuck 1.4.1.0 or above -HnkyTonk g; // instance for shorthand, you'll see... +NRev r => dac; // reverb is output mixer +HnkyTonk g => r; // instance for shorthand (you'll see...) , and solo HnkyTonk guit[6]; -NRev r => dac; -0.15 => r.gain; 0.07 => r.mix; +0.1 => r.gain; 0.08 => r.mix; [0,0,0,0] @=> int waveForms[]; [97,71,77,81] @=> int opGains[]; @@ -32,9 +32,17 @@ for( int i; i < 6; i++ ) g.getFMTableSusLevel(sustains[op]), g.getFMTableTime(releases[op]) ); guit[i].opRatio( op,ratios[op] ); - guit[i].lfoDepth( 0.0 ); + g.opWave(op,1); // we do this 6 times, but it's easier + g.opGain( op,g.getFMTableGain(opGains[op]) ); + g.opADSR( op, g.getFMTableTime(attacks[op]), + g.getFMTableTime(decays[op]), + g.getFMTableSusLevel(sustains[op]), + g.getFMTableTime(releases[op]) ); + g.opRatio( op,ratios[op] ); } + guit[i].lfoDepth( 0.0 ); } +g.lfoDepth( 0.0 ); [38,45,50,55,59,64] @=> int DTuning[]; [38,45,50,57,62,66] @=> int DMaj[]; @@ -46,8 +54,12 @@ allOff(); second/2 => now; 0.2::second => dur E; -for( int i; i < 4; i++ ) + +spork ~ solo(); + +for( int i; i < 2; i++ ) { + <<< now/second >>>; spork ~ fastStrum(Emi,1.0); 2*E => now; fastUp(Emi,0.95); E/4 => now; allOff(); 3*E/4 => now; spork ~ fastStrum(Emi,0.97); 2*E => now; @@ -64,6 +76,8 @@ for( int i; i < 4; i++ ) } slowStrum(Emi,0.8); +Std.mtof(76) => g.freq; +1 => g.noteOn; 2*second => now; allOff(); second => now; @@ -84,7 +98,7 @@ fun void fastStrum( int chord[], float vel) { for (int i; i < 6; i++) { Std.mtof(chord[i]) => guit[i].freq; vel => guit[i].noteOn; - Math.random2f(0.005,0.02)::second => now; + Math.random2f(0.005,0.03)::second => now; } } @@ -92,7 +106,31 @@ fun void fastUp( int chord[], float vel) { for (int i; i < 6; i++) { Std.mtof(chord[5-i]) => guit[5-i].freq; vel => guit[5-i].noteOn; - // Math.random2f(0.001,0.005)::second => now; + Math.random2f(0.001,0.01)::second => now; } } +fun void solo() { + [71, 69, 71] @=> int solo1[]; + [71, 72, 74, 72, 71] @=> int solo2[]; + 2*E => now; + Std.mtof(solo1[0]) => g.freq; 1 => g.noteOn; + E/2 => now; + Std.mtof(solo1[1]) => g.freq; 1 => g.noteOn; + E/2 => now; + Std.mtof(solo1[2]) => g.freq; 1 => g.noteOn; + 0.8::second => now; + 1 => g.noteOff; + 2::second => now; + Std.mtof(solo2[0]) => g.freq; 1 => g.noteOn; + E/2 => now; + Std.mtof(solo2[1]) => g.freq; 1 => g.noteOn; + E/2 => now; + Std.mtof(solo2[2]) => g.freq; 1 => g.noteOn; + E/2 => now; + Std.mtof(solo2[3]) => g.freq; 1 => g.noteOn; + E/2 => now; + Std.mtof(solo2[4]) => g.freq; 1 => g.noteOn; + 1::second => now; + 1 => g.noteOff; +}