diff --git a/src/documentation/synths.ts b/src/documentation/synths.ts index 93b0aae..63c0702 100644 --- a/src/documentation/synths.ts +++ b/src/documentation/synths.ts @@ -13,40 +13,40 @@ Topos comes by default with a forever-increasing number of synthesis capabilitie The sound function can take the name of a synthesizer or waveform as first argument. This has for effect to turn the sampler we all know and love into a synthesizer. sine, sawtooth,triangle, square are the names used to select classic oscillator waveforms. Note that you can also make use of filters and envelopes to shape the sound to your liking. ${makeExample( - "Listening to the different waveforms from the sweetest to the harshest", - ` + "Listening to the different waveforms from the sweetest to the harshest", + ` beat(.5) && snd(['sine', 'triangle', 'sawtooth', 'square'].beat()).freq(100).out() `, - true -)} + true + )} Two functions are primarily used to control the frequency of the synthesizer: - freq(hz: number): sets the frequency of the oscillator. - note(note: number): sets the MIDI note of the oscillator (MIDI note converted to hertz). ${makeExample( - "Selecting a pitch or note", - ` + "Selecting a pitch or note", + ` beat(.5) && snd('triangle').freq([100,200,400].beat(2)).out() `, - true -)} + true + )} ## Vibrato You can also add some amount of vibrato to the sound using the vib and vibmod methods. These can turn any oscillator into something more lively and/or into a sound effect when used with a high amount of modulation. ${makeExample( - "Different vibrato settings", - ` + "Different vibrato settings", + ` bpm(140); beat(1) :: sound('triangle') .freq(400).release(0.2) .vib([1/2, 1, 2, 4].beat()) .vibmod([1,2,4,8].beat(2)) .out()`, - true -)} + true + )} ## Controlling the amplitude @@ -55,16 +55,16 @@ Controlling the amplitude and duration of the sound can be done using various te - velocity(velocity: number): sets the velocity of the oscillator (velocity is a multiple of gain). ${makeExample( - "Setting the gain", - `beat(0.25) :: sound('sawtooth').gain([0.0, 1/8, 1/4, 1/2, 1].beat(0.5)).out()`, - true -)} + "Setting the gain", + `beat(0.25) :: sound('sawtooth').gain([0.0, 1/8, 1/4, 1/2, 1].beat(0.5)).out()`, + true + )} ${makeExample( - "Setting the velocity", - `beat(0.25) :: sound('sawtooth').velocity([0.0, 1/8, 1/4, 1/2, 1].beat(0.5)).out()`, - true -)} + "Setting the velocity", + `beat(0.25) :: sound('sawtooth').velocity([0.0, 1/8, 1/4, 1/2, 1].beat(0.5)).out()`, + true + )}
@@ -77,31 +77,31 @@ ${makeExample( - release(release: number) / rel(rel: number): sets the release time of the envelope. ${makeExample( - "Using decay and sustain to set the ADSR envelope", - ` + "Using decay and sustain to set the ADSR envelope", + ` beat(0.5) :: sound('wt_piano') .cutoff(1000 + usine() * 4000) .freq(100).decay(.2) .sustain([0.1,0.5].beat(4)) .out()`, - true -)} + true + )} This ADSR envelope design is important to know because it is used for other aspects of the synthesis engine such as the filters that we are now going to talk about. But wait, I've kept the best for the end. The adsr() combines all the parameters together. It is a shortcut for setting the ADSR envelope: - adsr(attack: number, decay: number, sustain: number, release: number): sets the ADSR envelope. ${makeExample( - "Replacing the previous example with the adsr() method", - ` + "Replacing the previous example with the adsr() method", + ` beat(0.5) :: sound('wt_piano') .cutoff(1000 + usine() * 4000) .freq(100) .adsr(0, .2, [0.1,0.5].beat(4), 0) .out() `, - true -)} + true + )} ## Substractive synthesis using filters @@ -113,10 +113,10 @@ The most basic synthesis technique used since the 1970s is called substractive s - **bandpass filter**: filters the low and high frequencies around a frequency band, keeping what's in the middle. ${makeExample( - "Filtering the high frequencies of an oscillator", - `beat(.5) :: sound('sawtooth').cutoff(50 + usine(1/8) * 2000).out()`, - true -)} + "Filtering the high frequencies of an oscillator", + `beat(.5) :: sound('sawtooth').cutoff(50 + usine(1/8) * 2000).out()`, + true + )} These filters all come with their own set of parameters. Note that we are describing the parameters of the three different filter types here. Choose the right parameters depending on the filter type you are using: @@ -129,10 +129,10 @@ These filters all come with their own set of parameters. Note that we are descri | resonance | lpq | resonance of the lowpass filter | ${makeExample( - "Filtering a bass", - `beat(.5) :: sound('jvbass').lpf([250,1000,8000].beat()).out()`, - true -)} + "Filtering a bass", + `beat(.5) :: sound('jvbass').lpf([250,1000,8000].beat()).out()`, + true + )} ### Highpass filter @@ -142,10 +142,10 @@ ${makeExample( | hresonance | hpq | resonance of the highpass filter | ${makeExample( - "Filtering a noise source", - `beat(.5) :: sound('gtr').hpf([250,1000, 2000, 3000, 4000].beat()).end(0.5).out()`, - true -)} + "Filtering a noise source", + `beat(.5) :: sound('gtr').hpf([250,1000, 2000, 3000, 4000].beat()).end(0.5).out()`, + true + )} ### Bandpass filter @@ -155,10 +155,10 @@ ${makeExample( | bandq | bpq | resonance of the bandpass filter | ${makeExample( - "Sweeping the filter on the same guitar sample", - `beat(.5) :: sound('gtr').bandf(100 + usine(1/8) * 4000).end(0.5).out()`, - true -)} + "Sweeping the filter on the same guitar sample", + `beat(.5) :: sound('gtr').bandf(100 + usine(1/8) * 4000).end(0.5).out()`, + true + )} ## Filter order (type) @@ -167,38 +167,38 @@ You can also use the ftype method to change the filter type (order). Th - ftype(type: string): sets the filter type (order), either 12db or 24db. ${makeExample( - "Filtering a bass", - `beat(.5) :: sound('jvbass').ftype(['12db', '24db'].beat(4)).lpf([250,1000,8000].beat()).out()`, - true -)} + "Filtering a bass", + `beat(.5) :: sound('jvbass').ftype(['12db', '24db'].beat(4)).lpf([250,1000,8000].beat()).out()`, + true + )} I also encourage you to study these simple examples to get more familiar with the construction of basic substractive synthesizers: ${makeExample( - "Simple synthesizer voice with filter", - ` + "Simple synthesizer voice with filter", + ` beat(.5) && snd('sawtooth') .cutoff([2000,500].pick() + usine(.5) * 4000) .resonance(0.9).freq([100,150].pick()) .out() `, - true -)} + true + )} ${makeExample( - "Blessed by the square wave", - ` + "Blessed by the square wave", + ` beat(4) :: [100,101].forEach((freq) => sound('square').freq(freq).sustain(0.1).out()) beat(.5) :: [100,101].forEach((freq) => sound('square').freq(freq*2).sustain(0.01).out()) beat([.5, .75, 2].beat()) :: [100,101].forEach((freq) => sound('square') .freq(freq*4 + usquare(2) * 200).sustain(0.125).out()) beat(.25) :: sound('square').freq(100*[1,2,4,8].beat()).sustain(0.1).out()`, - false -)} + false + )} ${makeExample( - "Ghost carillon (move your mouse!)", - ` + "Ghost carillon (move your mouse!)", + ` beat(1/8)::sound('sine') .velocity(rand(0.0, 1.0)) .delay(0.75).delayt(.5) @@ -207,8 +207,8 @@ beat(1/8)::sound('sine') .freq(mouseX()) .gain(0.25) .out()`, - false -)} + false + )} ## Filter envelopes @@ -223,14 +223,16 @@ The examples we have studied so far are static. They filter the sound around a f | lpdecay | lpd | decay of the lowpass filter | | lpsustain | lps | sustain of the lowpass filter | | lprelease | lpr | release of the lowpass filter | +| lpadsr | | (**takes five arguments**) set all the parameters | + ${makeExample( - "Filtering a sawtooth wave dynamically", - `beat(.5) :: sound('sawtooth').note([48,60].beat()) + "Filtering a sawtooth wave dynamically", + `beat(.5) :: sound('sawtooth').note([48,60].beat()) .cutoff(5000).lpa([0.05, 0.25, 0.5].beat(2)) .lpenv(-8).lpq(10).out()`, - true -)} + true + )} ### Highpass envelope @@ -241,14 +243,16 @@ ${makeExample( | hpdecay | hpd | decay of the highpass filter | | hpsustain | hps | sustain of the highpass filter | | hprelease | hpr | release of the highpass filter | +| hpadsr | | (**takes five arguments**) set all the parameters | + ${makeExample( - "Let's use another filter using the same example", - `beat(.5) :: sound('sawtooth').note([48,60].beat()) + "Let's use another filter using the same example", + `beat(.5) :: sound('sawtooth').note([48,60].beat()) .hcutoff(1000).hpa([0.05, 0.25, 0.5].beat(2)) .hpenv(8).hpq(10).out()`, - true -)} + true + )} ### Bandpass envelope @@ -259,16 +263,18 @@ ${makeExample( | bpdecay | bpd | decay of the bandpass filter | | bpsustain | bps | sustain of the bandpass filter | | bprelease | bpr | release of the bandpass filter | +| bpadsr | | (**takes five arguments**) set all the parameters | + ${makeExample( - "And the bandpass filter, just for fun", - `beat(.5) :: sound('sawtooth').note([48,60].beat()) + "And the bandpass filter, just for fun", + `beat(.5) :: sound('sawtooth').note([48,60].beat()) .bandf([500,1000,2000].beat(2)) .bpa([0.25, 0.125, 0.5].beat(2) * 4) .bpenv(-4).release(2).out() `, - true -)} + true + )} ## Wavetable synthesis @@ -276,8 +282,8 @@ ${makeExample( Topos can also do wavetable synthesis. Wavetable synthesis allows you to use any sound file as a source to build an oscillator. By default, Topos comes with more than 1000 waveforms thanks to the awesome [AKWF](https://www.adventurekid.se/akrt/waveforms/adventure-kid-waveforms/) pack made by Kristoffer Ekstrand. Any sample name that contains wt_ as a prefix will be interpreted by the sampler as a wavetable and thus as an oscillator. See for yourself: ${makeExample( - "Acidity test", - ` + "Acidity test", + ` beat(.25) :: sound('wt_symetric:8').note([50,55,57,60].beat(.25) - [12,0] .pick()).ftype('12db').adsr(0.05/4, 1/16, 0.25/4, 0) .cutoff(1500 + usine(1/8) * 5000).lpadsr(16, 0.2, 0.2, 0.125/2, 0) @@ -285,15 +291,15 @@ beat(.25) :: sound('wt_symetric:8').note([50,55,57,60].beat(.25) - [12,0] beat(1) :: sound('kick').n(4).out() beat(2) :: sound('snare').out() beat(.5) :: sound('hh').out()`, - true -)} + true + )} Let's explore the galaxy of possible waveforms. It can be hard to explore them all, there is a **lot** of them: ${makeExample( - "Let's explore some wavetables", - ` + "Let's explore some wavetables", + ` // Exploring a vast galaxy of waveforms let collection = [ 'wt_sinharm', 'wt_linear', 'wt_bw_sawrounded', @@ -303,8 +309,8 @@ beat(2) :: v('selec', irand(1, 100)) beat(2) :: v('swave', collection.pick()) beat(0.5) :: sound(v('swave')).n(v('selec')).out() `, - true -)} + true + )} You can work with them just like with any other waveform. Having so many of them makes them also very useful for generating sound effects, percussive, sounds, etc... @@ -319,8 +325,8 @@ Another really useful technique to know about is FM synthesis, FM standing for _ There is also an additional parameter, fm that combines fmi and fmh using strings: fm('2:4'). Think of it as a static shortcut for getting some timbres more quickly. ${makeExample( - "80s nostalgia", - ` + "80s nostalgia", + ` beat([.5, 1].beat(8)) && snd('triangle').adsr(0.02, 0.5, 0.5, 0.25) .fmi(2).fmh(1.5).note([60,55, 60, 63].beat() - 12) .pan(noise()).out() @@ -329,23 +335,23 @@ beat(.25) && snd('triangle').adsr(0.02, 0.1, 0.1, 0.1) .pan(noise()).note([60,55, 60, 63].beat() + [0, 7].pick()).out() beat(2) :: sound('cp').room(1).sz(1).out() `, - true -)} + true + )} ${makeExample( - "Giving some love to ugly inharmonic sounds", - ` + "Giving some love to ugly inharmonic sounds", + ` beat([.5, .25].bar()) :: sound('sine').fm('2.2183:3.18293').sustain(0.05).out() beat([4].bar()) :: sound('sine').fm('5.2183:4.5').sustain(0.05).out() beat(.5) :: sound('sine') .fmh([1, 1.75].beat()) .fmi($(1) % 30).orbit(2).room(0.5).out()`, - true -)} + true + )} ${makeExample( - "Peace and serenity through FM synthesis", - ` + "Peace and serenity through FM synthesis", + ` beat(0.25) :: sound('sine') .note([60, 67, 70, 72, 77].beat() - [0,12].bar()) .attack(0.2).release(0.5).gain(0.25) @@ -354,8 +360,8 @@ beat(0.25) :: sound('sine') .cutoff(1500).delay(0.5).delayt(0.125) .delayfb(0.8).fmh(Math.floor(usine(.5) * 4)) .out()`, - true -)} + true + )} **Note:** you can also set the _modulation index_ and the _harmonic ratio_ with the fm argument. You will have to feed both as a string: fm('2:4'). If you only feed one number, only the _modulation index_ will be updated. @@ -366,8 +372,8 @@ There is also a more advanced set of parameters you can use to control the envel - fmrelease / fmrel: release time of the modulator envelope. ${makeExample( - "FM Synthesis with envelope control", - ` + "FM Synthesis with envelope control", + ` beat(.5) :: sound('sine') .note([50,53,55,57].beat(.5) - 12) .fmi(0.5 + usine(.25) * 1.5) @@ -375,8 +381,8 @@ beat(.5) :: sound('sine') .fmwave('triangle') .fmsus(0).fmdec(0.2).out() `, - true -)} + true + )} ## ZzFX @@ -385,15 +391,15 @@ beat(.5) :: sound('sine') ZZfX can be triggered by picking a default ZZfX waveform in the following list: z_sine, z_triangle, z_sawtooth, z_tan, z_noise. ${makeExample( - "Picking a waveform", - ` + "Picking a waveform", + ` beat(.5) :: sound(['z_sine', 'z_triangle', 'z_sawtooth', 'z_tan', 'z_noise'].beat()).out() `, - true -)} + true + )} ${makeExample( - "Minimalist chiptune", - ` + "Minimalist chiptune", + ` beat(.5) :: sound('z_triangle') .note([60, 67, 72, 63, 65, 70].beat(.5)) .zrand(0).curve([1,2,3,4].beat(1)) @@ -403,8 +409,8 @@ beat(.5) :: sound('z_triangle') .room(0.5).size(0.9) .pitchJumpTime(0.01).out() `, - true -)} + true + )} It comes with a set of parameters that can be used to tweak the sound. Don't underestimate this synth! It is very powerful for generating anything ranging from chaotic noise sources to lush pads: @@ -430,8 +436,8 @@ It comes with a set of parameters that can be used to tweak the sound. Don't und |duration|| Total sound duration (overrides envelope) | ${makeExample( - "Chaotic Noise source", - ` + "Chaotic Noise source", + ` beat(.25) :: sound('z_tan') .note(40).noise(rand(0.0, 1.0)) .pitchJump(84).pitchJumpTime(rand(0.0, 1.0)) @@ -441,21 +447,21 @@ beat(.25) :: sound('z_tan') .sustain(0).decay([0.2, 0.1].pick()) .out() `, - true -)} + true + )} ${makeExample( - "What is happening to me?", - ` + "What is happening to me?", + ` beat(1) :: snd('zzfx').zzfx([ [4.77,,25,,.15,.2,3,.21,,2.4,,,,,,,.23,.35], [1.12,,97,.11,.16,.01,4,.77,,,30,.17,,,-1.9,,.01,.67,.2] ].beat()).out() `, - false -)} + false + )} ${makeExample( - "Les voitures dans le futur", - ` + "Les voitures dans le futur", + ` beat(1) :: sound(['z_triangle', 'z_sine'].pick()) .note([60,63,72,75].pick()).tremolo(16) .zmod([0, 1/2, 1/8].div(2).pick()) @@ -463,18 +469,18 @@ beat(1) :: sound(['z_triangle', 'z_sine'].pick()) .room(0.9).size(0.9) .delayt(0.75).delayfb(0.5).out() `, - false -)} + false + )} Note that you can also design sounds [on this website](https://killedbyapixel.github.io/ZzFX/) and copy the generated code in Topos. To do so, please use the zzfx method with the generated array: ${makeExample( - "Designing a sound on the ZzFX website", - ` + "Designing a sound on the ZzFX website", + ` beat(2) :: sound('zzfx').zzfx([3.62,,452,.16,.1,.21,,2.5,,,403,.05,.29,,,,.17,.34,.22,.68]).out() `, - true -)} + true + )} # Speech synthesis @@ -489,35 +495,35 @@ Topos can also speak using the [Web Speech API](https://developer.mozilla.org/en - volume(number): speaking volume, from 0.0 to 1.0. ${makeExample( - "Hello world!", - ` + "Hello world!", + ` beat(4) :: speak("Hello world!") `, - true -)} + true + )} ${makeExample( - "Let's hear people talking about Topos", - ` + "Let's hear people talking about Topos", + ` beat(2) :: speak("Topos!","fr",irand(0,5)) `, - true -)} + true + )} You can also use speech by chaining methods to a string: ${makeExample( - "Foobaba is the real deal", - ` + "Foobaba is the real deal", + ` onbeat(4) :: "Foobaba".voice(irand(0,10)).speak() `, - true -)} + true + )} ${makeExample( - "Building string and chaining", - ` + "Building string and chaining", + ` const subject = ["coder","user","loser"].pick() const verb = ["is", "was", "isnt"].pick() const object = ["happy","sad","tired"].pick() @@ -525,12 +531,12 @@ ${makeExample( beat(6) :: sentence.pitch(0).rate(0).voice([0,2].pick()).speak() `, - true -)} + true + )} ${makeExample( - "Live coded poetry with array and string chaining", - ` + "Live coded poetry with array and string chaining", + ` bpm(70) const croissant = [ @@ -545,7 +551,7 @@ ${makeExample( .rate(rand(.4,.6)) .speak(); `, - true -)} + true + )} `; }; diff --git a/src/examples/excerpts.ts b/src/examples/excerpts.ts index 2d66099..8c916de 100644 --- a/src/examples/excerpts.ts +++ b/src/examples/excerpts.ts @@ -13,24 +13,26 @@ beat(.5) :: sound('hh').out()`, `// Entering the secret room - Bubobubobubo let frequencies = [200,400,600,800,1000,2000].beat(2); beat(2) :: sound('sine').freq(frequencies) - .delay(0.5).delayt(usine(.5)).delayfb(0.8).size(0.9).room(0.9).out() + .delay(0.25).delayt(usine(.25)).delayfb(0.25).size(0.9).room(0.9).out() beat(2) :: app.hydra.osc(frequencies/100, 0.25, 0.5) .posterize([32,4,8,16].beat(2)).rotate(cpulse()) .kaleid([1,2,3].beat()).out()`, `// The real internet of things - Bubobubobubo beat(.5) :: sound('STA6').cut(1).vel(0.4) .orbit(2).room(0.5).size(0.5).n(irand(1,4)) - .speed([0.15, 0.30].beat()).out() + .speed([0.15, 0.30].beat() * 1.5).loop([1,0] + .beat(.125)).loopEnd([1,0.5].beat(2)).out() binrhythm(.5, 50) :: sound('shaker').out() binrhythm(.5, 52) :: sound('808bd').n(3).out() rhythm(.25, 6, 8) :: sound('808sd').out()`, `// Numerology - Bubobubobubo +bpm(130); let mel = [ "0.125 _ (0 3 7 0 3 5 0 3 9)+(0 2)", "0.125 (0 7 0 10 0 5)+(0 3)", "0.125 (0 3 7 0 3 5 0 3 9)+(0 2)", "0.125 (0 2 4 5 9 10)+(0 2)", ].beat(4); z0(mel) - .scale('minor').sound('square').cutoff(800 + usine(.5) * 5000) + .scale('minor').sound('wt_piano').cutoff(800 + usine(.5) * 5000) .fmi([2, 4, 8].beat(2)).fmh(flip(2) ? 2 : 4) .delay(bpm() / 60 / 9).delayt(0.25).delayfb(0.5) .fmsus(0.3).fmrel(0.3).rel(rand(0.5,0.8)) @@ -42,34 +44,35 @@ beat([.25, .5].beat(4)) :: flip(6) && sound('dr') `// Harmonic Leaps and Gaps -- Bubobubobubo let oscillation = quant(usine(.25) * 20, [35, 40, 38, 50, 55]); let tonal = [0, 5, 0, 0, 7].palindrome().bar() + 40 - 24; -[tonal, tonal + 7, tonal + [12,3].bar()].forEach((e) => { - flip(2) :: beat(.5) :: sound('square').fmi(2) - .cutoff(500 + usine(1/2)).n(irand(1,10)) +[tonal, tonal + 7, tonal + [12, 3, 24].bar()].forEach((e) => { + flip(2) :: beat(.5) :: sound('square').fmi(1.5).fmh(0.99) + .cutoff(500 + usine(1/2)).n($(1) % 20).cut(.1) .note(e + oscillation + [0, 5].beat(.5)).out() - !flip(2) :: beat(.5) :: sound('sawtooth').fmi(2) - .cutoff(500 + usine(1/2) * 5000).n(irand(1,10)) + !flip(2) :: beat(.5) :: sound('sawtooth').fmi(1.49).fmh(1.01) + .cutoff(500 + usine(1/2) * 5000).n(irand(1,10)).cut(.1) .note(e + oscillation + [0, 5].beat(.5)).out() }); -oncount([2, 3.5, [5,0].pick()], 6) :: sound('snare').out() - `, +oncount([2, 4, 4.5], 6) :: sound('snare').n(4).out() +rhythm(.25, 6, 8) :: sound('shaker').end(0.25).out() +rhythm(.5,4,8) :: sound('bd').out()`, `// Computer Music Classroom, Monday (8AM) -- Bubobubobubo -let ur = [0, 12, 7].beat(24), +let ur = [0, 5, 12, 7, 5].beat(24), fundamental = [0, 5, 10, 8, 6].repeatAll(4).bar(); -beat(.25) :: sound('square') - .note(ur + fundamental + 40).n(1 + $(1) % 8) +beat(.25) :: sound('triangle') + .note(ur + fundamental + 40).n(1 + $(1) % 16) .atk(0.05).sustain(0.1).release(0.1) - .room(0.9).size(0.9) + .room(0.9).size(0.9).vib(2).vibmod(0.125) .out() -beat(.25) :: sound('sawtooth') - .note(ur + fundamental + 47).n(1 + $(2) % 8) +beat(.25) :: sound('triangle') + .note(ur + fundamental + 47).n(1 + $(2) % 16) .atk(0.05).sustain(0.1).release(0.1) - .room(0.9).size(0.9) + .room(0.9).size(0.9).vib(4).vibmod(0.125) .out() beat(.25) :: sound(['sawtooth', 'square'].bar()) - .note(ur + fundamental + 40+[10,12].bar()).n(1 + $(3) % 8) - .atk(0.05).sustain(0.1).release(0.1) - .room(0.9).size(0.9).out() - `, + .note(ur + fundamental + 40+[10,12].bar()).n(1 + $(3) % 16) + .atk(0.05).sustain(0.1).release(0.1).vib([0, 0, 0, 0.5]) + .vibmod(often() ? 1 : [16,8,4].pick()) + .room(0.9).size(0.9).out()`, `// Lamento for Digital Harpists -- Bubobubobubo beat(4) :: sound('triangle') .note(60).fmwave('triangle').fmi(3.95) @@ -92,21 +95,18 @@ beat([4, 2, 8].pick() / [2,1].bar()) :: sound('triangle') let melody = [30,30,34,35,37].palindrome() .beat() + [0, -12].repeatAll(2).beat(2) if (flip(8, 75)) { - log('first section') - rhythm(.5, 4, 8) :: sound('ST12').n([0,1,2].beat(0.5)).speed(0.5).out() - rhythm(.5, 6, 8) :: sound('ST20').n([0,1,2].beat(0.5) + 20) + rhythm(.5, 4, 8) :: sound('ST12').n([0,1,2].beat(0.5)).speed(0.5).gain(0.4).out() + rhythm(.5, 6, 8) :: sound('ST20').n([0,1,2].beat(0.5) + 20).gain(0.4) .speed(0.25).end(0.1).orbit(2).room(0.5).size(0.5).out() - beat(.5) :: sound('ST01').note(melody) + beat(.5) :: sound('ST01').note(melody).gain(0.4) .n($(1)).speed(0.5).room(0.5).size(0.5).out() } else { - log('second section') rhythm(.5, 2, 8) :: sound('ST20') - .n([0,1,2].beat(0.5)).speed(0.5) + .n([0,1,2].beat(0.5)).speed(0.5).gain(0.4) .end(0.1).out() - beat(.5) :: sound('ST01').note(melody).n($(1)).speed(0.5).end(0.1).out() - beat(1) :: sound('ST02').note(melody).n($(1)).speed(0.5).end(0.1).out() -} - `, + beat(.5) :: sound('ST01').note(melody).n($(1)).speed(0.5).gain(0.4).end(0.1).out() + beat(1) :: sound('ST02').note(melody).n($(1)).speed(0.5).gain(0.4).end(0.1).out() +}`, `// Race day - Bubobubobubo bpm(125); beat(.5) :: sound('STB6') @@ -173,6 +173,7 @@ beat(0.25) :: snd('hh').out(); beat(2) :: snd('square') .cutoff(500).note(50-12).resonance(20).sustain(0.2).out() beat(1/4)::snd(['sawtooth', 'triangle', 'square'].beat(1)) + .vib(2).vibmod(0.5) .note([50, 53, 55, 50, 50, 52, 58, 50+12, 50+15].beat(4) + [0, 12, 24].beat(0.5)) .cutoff(usine(.5)*10000).resonance([10,20].beat(2)) .fmi($(1) % 10).fmh($(2) % 5) @@ -183,17 +184,20 @@ beat(1/4)::snd(['sawtooth', 'triangle', 'square'].beat(1)) beat(4)::snd('amencutup').n($(19)).cut(1).orbit(2).pan(rand(0.0,1.0)).out()`, `// Crazy arpeggios - Bubobubobubo bpm(110) -beat(0.125) && sound('sawtooth') +beat([0.25, 0.5].beat(4)) && sound('sawtooth') .note([60, 62, 63, 67, 70].beat(.125) + [-12,0,12].beat() + [0, 0, 5, 7].bar()) .sustain(0.1).fmi(0.25).fmh(2).room(0.9) - .gain(0.75).cutoff(500 + usine(8) * [500, 1000, 2000].bar()) - .delay(0.5).delayt(0.25).delayfb(0.25) + .gain(0.75).cutoff([500,1000].beat(2)) + .lpadsr([6,8].beat(), 1/16, .125, 0, 0) + .delay(0.5).delayt(0.25) + .delayfb(0.25) .out(); -beat(1) && snd('kick').out(); -beat(2) && snd('snare').out(); -beat(.5) && snd('hat').out(); -`, +binrhythm([.25, .5].beat(), 11) :: often() :: sound('dr') + .n([0, 1].beat()).gain(0.4).out() +binrhythm([.5, .25, .5, .5, .25].beat(), 122) :: often() :: sound('dr') + .n([9, 24].beat()).gain(0.4).out() +rhythm([.5, .25, 1].beat(2), 4, 8) :: sound('kick').gain(0.6).out()`, `// Obscure Shenanigans - Bubobubobubo beat([1/4,1/8,1/16].beat(8)):: sound('sine') .freq([100,50].beat(16) + 50 * ($(1)%10)) @@ -205,15 +209,14 @@ flip(3) :: beat([.25,.5].beat(.5)) :: sound('dr') .n([8,9].pick()).gain([.8,.5,.25,.1,.0].beat(.25)).out() `, `// Resonance bliss - Bubobubobubo -beat(.25)::snd('arpy') - .note(30 + [0,3,7,10].beat()) - .cutoff(usine(.5) * 5000).resonance(10).gain(0.3) - .end(0.8).room(0.9).size(0.9).n(0).out(); -beat([.25,.125].beat(2))::snd('arpy') - .note(30 + [0,3,7,10].beat()) - .cutoff(usine(.5) * 5000).resonance(20).gain(0.3) - .end(0.8).room(0.9).size(0.9).n(3).out(); -beat(.5) :: snd('arpy').note( - [30, 33, 35].repeatAll(4).beat(1) - [12,0].beat(0.5)).out() -`, +beat([.25,.125].beat(4))::snd('arpy:4') + .note(30 + [0,3,7,10, 12, 5, 7].beat()).speed(0.999).pan(0) + .cutoff(1000 + usine(1/8) * 400).lpadsr(8, 1/8, 1/16, 0, 0) + .resonance(1).gain(0.4).end(0.8).room(0.9).size(0.9).n(0).out(); +beat([.25,.125, .5].beat(4))::snd('arpy:4') + .note(30 + [0,3,7,10, 12, 5, 7].beat()).speed(1.001).pan(1) + .cutoff(100 + usine(1/8) * 800).lpadsr(5, 0, [1/8, 1.16].beat(), 0, 0) + .resonance(5).gain(0.4).end(0.8).room(0.9).size(0.9).n(3).out(); +beat(.5) :: snd('arpy').note([30, 33, 35].repeatAll(4).beat(1) - [24,12].beat(0.5)) + .cutoff(500).lpadsr(8, 0.05, .125, 0, 0).out()`, ];