// title: Harmo : Harmonic Series modulated by a MultiSlider interface. // author: Dindoléon // description: // MultiSlider plot display allowing to shape a harmonic series. This is a simplification of Bruno Ruviaro's Additive Synthesis GUI Demo 2. // code: ( /* Harmo module, licensed under GNU GPL v3 (), Adapted by Simon Deplat (aka Dindoleon), but mostly written by Bruno Ruviaro in his 'Additive Synthesis GUI DEMO 2' patch (see http://sccode.org/1-4Uv ). This is a standalone module which allows you to shape a continuous tone by modifying the amplitude of its harmonic. The major change with Ruviaro's version is the plot display, rather than bar charts display (see lines 65 - 66), and the over simplification of the interface. This is a good visual tool to introduce the notions of harmonics and timbre, due to its simplicity. Replace the mulstiSlider's 'win' argument by a View to integrate it inside another GUI. */ var win, window_size, synth, spectrum, numharm, ampBus, sndBus, multiSlider, margin, frame_color, fill_color, line_color; window_size = [ 500, 300 ]; margin = 3; frame_color = Color.blue; line_color = Color.new( 0.2, 0.6, 1 ); fill_color = Color.white; numharm = 32; ampBus = Bus.control(s); ampBus.value = 0.1; sndBus = Bus. audio(s, 2); // Routine to add SynthDefs, wait for Server reply, then start Synths { // The SynthDef has been modified to store the harmonic number inside it, allowing to change the root frequency for every harmonic at once. SynthDef("additive-multislider", { arg outbus, freq = 110, amp = 0.01, freq_mul = 1; var snd = SinOsc.ar(freq * freq_mul, 0, Lag.kr(amp, 3)); Out.ar(outbus, snd!2); }).add; SynthDef("continuousOut", { arg inbus, amp = 0.1, gate = 1, att = 0.1, sus = 1, rel = 1; var env = EnvGen.kr(Env.asr(att, sus, rel), gate); Out.ar(0, In.ar(inbus, 2) * amp * env * 0.05); }).add; // Wait for SynthDefs to be added... s.sync; // Now call the Synths: spectrum = Array.fill(numharm, {arg i; Synth("additive-multislider", [\freq, 440, \freq_mul, (i+1), \amp, 0.0, \outbus, sndBus])}); synth = Synth("continuousOut", [\inbus, sndBus, \amp, ampBus.asMap], addAction: \addToTail); }.fork; win = Window("Harmo", Rect(0, 0, window_size[0], window_size[1]), false); win.background_( frame_color ); // Multislider multiSlider = MultiSliderView(win, Rect( margin, margin, window_size[0] - ( margin * 2 ), window_size[1] - ( margin * 2 ) )); multiSlider.value = Array.fill(numharm, {0.0}); multiSlider.isFilled = true; multiSlider.elasticMode_(true); multiSlider.fillColor = fill_color; multiSlider.strokeColor = line_color; multiSlider.gap = 0; multiSlider.drawRects = false; // Display as bar charts multiSlider.drawLines = true; // Display as plot multiSlider.action = {arg multi; var index = multi.index; var value = multi.currentvalue; spectrum[index].set(\amp, value-0.01*2); }; win.front; )