diff --git a/index.html b/index.html index 3c473a0..305b2c1 100644 --- a/index.html +++ b/index.html @@ -165,7 +165,8 @@

Amplitude

Sampler

Synths

-

Effects

+

Filters

+

Effects

@@ -174,7 +175,6 @@ Samples

List of samples

-

Controlling samples

External samples

diff --git a/src/Documentation.ts b/src/Documentation.ts index 08ffe14..cfd6a9d 100644 --- a/src/Documentation.ts +++ b/src/Documentation.ts @@ -3,12 +3,11 @@ import { type Editor } from "./main"; import { introduction } from "./documentation/basics/welcome"; import { loading_samples } from "./documentation/learning/samples/loading_samples"; import { amplitude } from "./documentation/learning/audio_engine/amplitude"; -import { reverb } from "./documentation/learning/audio_engine/reverb_delay"; +import { effects } from "./documentation/learning/audio_engine/effects"; import { sampler } from "./documentation/learning/audio_engine/sampler"; import { sample_banks } from "./documentation/learning/samples/sample_banks"; import { audio_basics } from "./documentation/learning/audio_engine/audio_basics"; import { sample_list } from "./documentation/learning/samples/sample_list"; -import { sample_controls } from "./documentation/learning/samples/sample_controls"; import { software_interface } from "./documentation/basics/interface"; import { shortcuts } from "./documentation/basics/keyboard"; import { code } from "./documentation/basics/code"; @@ -44,6 +43,7 @@ import { synths } from "./documentation/learning/audio_engine/synths"; import showdown from "showdown"; import showdownHighlight from "showdown-highlight"; import { createDocumentationStyle } from "./DomElements"; +import { filters } from "./documentation/learning/audio_engine/filters"; showdown.setFlavor("github"); export const key_shortcut = (shortcut: string): string => { @@ -94,6 +94,7 @@ export const documentation_factory = (application: Editor) => { cyclic: cyclical_time(application), longform: long_forms(application), synths: synths(application), + filters: filters(application), chaining: chaining(application), patterns: patterns(application), ziffers_basics: ziffers_basics(application), @@ -109,7 +110,7 @@ export const documentation_factory = (application: Editor) => { functions: functions(application), shortcuts: shortcuts(application), amplitude: amplitude(application), - reverb_delay: reverb(application), + effects: effects(application), sampler: sampler(application), mouse: mouse(application), oscilloscope: oscilloscope(application), @@ -118,7 +119,6 @@ export const documentation_factory = (application: Editor) => { bonus: bonus(application), sample_list: sample_list(application), sample_banks: sample_banks(application), - sample_controls: sample_controls(application), loading_samples: loading_samples(application), about: about(), }; diff --git a/src/InterfaceLogic.ts b/src/InterfaceLogic.ts index 88c9da5..6e4df61 100644 --- a/src/InterfaceLogic.ts +++ b/src/InterfaceLogic.ts @@ -491,7 +491,8 @@ export const installInterfaceLogic = (app: Editor) => { "sampler", "amplitude", "audio_basics", - "reverb_delay", + "filters", + "effects", "interface", "interaction", "code", @@ -521,7 +522,6 @@ export const installInterfaceLogic = (app: Editor) => { "oscilloscope", "sample_list", "loading_samples", - "sample_controls", ].forEach((e) => { let name = `docs_` + e; document.getElementById(name)!.addEventListener("click", async () => { diff --git a/src/classes/SoundEvent.ts b/src/classes/SoundEvent.ts index 13ec682..68dda78 100644 --- a/src/classes/SoundEvent.ts +++ b/src/classes/SoundEvent.ts @@ -311,7 +311,7 @@ export class SoundEvent extends AudibleEvent { self.updateValue("roomsize", value); return self; }, - comp: ["compressor", "cmp"], + comp: ["comp","compressor", "cmp"], ratio: function (self: SoundEvent, value: number) { self.updateValue("compressorRatio", value); return self; diff --git a/src/documentation/inlineHelp.ts b/src/documentation/inlineHelp.ts index 35a9484..2c0a8bd 100644 --- a/src/documentation/inlineHelp.ts +++ b/src/documentation/inlineHelp.ts @@ -898,12 +898,6 @@ const completionDatabase: CompletionDatabase = { description: "Detects if the Alt key is pressed", example: "fill() ? 1 : 0.5", }, - comp: { - name: "comp", - category: "synthesis", - description: "Compressor threshold (dB)", - example: "sound('sine').comp(-4).out()", - }, ratio: { name: "ratio", category: "synthesis", diff --git a/src/documentation/learning/audio_engine/amplitude.ts b/src/documentation/learning/audio_engine/amplitude.ts index 3d0aec2..e59109e 100644 --- a/src/documentation/learning/audio_engine/amplitude.ts +++ b/src/documentation/learning/audio_engine/amplitude.ts @@ -33,42 +33,43 @@ beat(.5)::snd('cp').vel($(1)%10 / 10).out()`, | decay | dec | Decay value (time to decay to sustain level) | | sustain | sus | Sustain value (gain when sound is held) | | release | rel | Release value (time for the sound to die off) | +| adsr | | Shortcut that combines all the parameters together | Note that the **sustain** value is not a duration but an amplitude value (how loud). The other values are the time for each stage to take place. Here is a fairly complete example using the sawtooth basic waveform. ${makeExample( "Simple synthesizer", ` -let smooth = (sound) => { - return sound.cutoff(r(100,500)) - .lpadsr(usaw(1/8) * 8, 0.05, .125, 0, 0) - .gain(r(0.25, 0.4)).adsr(0, r(.2,.4), r(0,0.5), 0) - .room(0.9).size(2).o(2).vib(r(2,8)).vibmod(0.125) -} -beat(.25)::smooth(sound('sawtooth') - .note([50,57,55,60].beat(1))).out(); -beat(.25)::smooth(sound('sawtooth') - .note([50,57,55,60].add(12).beat(1.5))).out(); +register("smooth", x => x.cutoff(r(100,500)) + .lpadsr(usaw(1/8) * 8, 0.05, .125, 0, 0) + .gain(r(0.25, 0.4)).adsr(0, r(.2,.4), r(0,0.5), 0) + .room(0.9).size(2).o(2).vib(r(2,8)).vibmod(0.125)) +beat(.25)::sound('sawtooth') +.note([50,57,55,60].beat(1)) +.smooth().out(); +beat(.25)::sound('sawtooth') +.note([50,57,55,60].add(12).beat(1.5)) +.smooth().out(); `, true, )}; - + Sometimes, using a full ADSR envelope is a bit overkill. There are other simpler controls to manipulate the envelope like the .ad method: ${makeExample( "Replacing .adsr by .ad", ` -let smooth = (sound) => { - return sound.cutoff(r(100,500)) - .lpadsr(usaw(1/8) * 8, 0.05, .125, 0, 0) - .gain(r(0.25, 0.4)).ad(0, .25) - .room(0.9).size(2).o(2).vib(r(2,8)).vibmod(0.125) -} -beat(.25)::smooth(sound('sawtooth') - .note([50,57,55,60].beat(1))).out(); -beat(.25)::smooth(sound('sawtooth') - .note([50,57,55,60].add(12).beat(1.5))).out(); +register("smooth", x => x.cutoff(r(100,500)) + .lpadsr(usaw(1/8) * 8, 0.05, .125, 0, 0) + .gain(r(0.25, 0.4)).ad(0, 0.25) + .room(0.9).size(2).o(2).vib(r(2,8)).vibmod(0.125)) +beat(.25)::sound('sawtooth') +.note([50,57,55,60].beat(1)) +.smooth().out(); +beat(.25)::sound('sawtooth') +.note([50,57,55,60].add(12).beat(1.5)) +.smooth().out(); `, true, )}; diff --git a/src/documentation/learning/audio_engine/reverb_delay.ts b/src/documentation/learning/audio_engine/effects.ts similarity index 71% rename from src/documentation/learning/audio_engine/reverb_delay.ts rename to src/documentation/learning/audio_engine/effects.ts index 8ef6ccd..658bf58 100644 --- a/src/documentation/learning/audio_engine/reverb_delay.ts +++ b/src/documentation/learning/audio_engine/effects.ts @@ -1,7 +1,7 @@ import { type Editor } from "../../../main"; import { makeExampleFactory } from "../../../Documentation"; -export const reverb = (application: Editor): string => { +export const effects = (application: Editor): string => { // @ts-ignore const makeExample = makeExampleFactory(application); return ` @@ -90,5 +90,34 @@ beat(.5)::snd('pad').crush([16, 8, 4].beat(2)).clip(.5).out() `, 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", + ` +tempo(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, +)} + +## Compression + +This effect is leveraging the basic WebAudio compressor. More information can be found about it on the [DynamicsCompressorNode](https://developer.mozilla.org/en-US/docs/Web/API/DynamicsCompressorNode?retiredLocale=de#instance_properties) page. This can be come quite complex :) + +| Method | Alias | Description | +|------------|-----------|---------------------------------| +| comp | cmp | Compressor threshold value (dB) over which compressor operates | +| ratio | rt | Compressor ratio: input amount in dB needed for 1dB change in the output | +| knee | kn | dB value defining the range over which the signal transitions to compressed section | +| compAttack | cmpa | In seconds, time to decrease the gain by 10db | +| compRelease | cmpr | In seconds, time to increase the gain by 10db | + `; }; diff --git a/src/documentation/learning/audio_engine/filters.ts b/src/documentation/learning/audio_engine/filters.ts new file mode 100644 index 0000000..5c8988e --- /dev/null +++ b/src/documentation/learning/audio_engine/filters.ts @@ -0,0 +1,145 @@ +import { type Editor } from "../../../main"; +import { makeExampleFactory } from "../../../Documentation"; + +export const filters = (application: Editor): string => { + const makeExample = makeExampleFactory(application); + return ` +# Filters + +Filters can be applied to both synthesizers and samples. They are used to shape the sound by removing or emphasizing certain frequencies. They are also used to create movement in the sound by modulating the cutoff frequency of the filter over time. + +- **lowpass filter**: filters the high frequencies, keeping the low frequencies. +- **highpass filter**: filtering the low frequencies, keeping the high frequencies. +- **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, +)} + +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: + + +### Lowpass filter + +| Method | Alias | Description | +|------------|-----------|---------------------------------| +| cutoff | lpf | cutoff frequency of the lowpass filter | +| resonance | lpq | resonance of the lowpass filter (0-1) | + +${makeExample( + "Filtering a bass", + `beat(.5) :: sound('jvbass').lpf([250,1000,8000].beat()).out()`, + true, +)} + +### Highpass filter + +| Method | Alias | Description | +|------------|-----------|---------------------------------| +| hcutoff | hpf | cutoff frequency of the highpass filter | +| hresonance | hpq | resonance of the highpass filter (0-1) | + +${makeExample( + "Filtering a noise source", + `beat(.5) :: sound('gtr').hpf([250,1000, 2000, 3000, 4000].beat()).end(0.5).out()`, + true, +)} + +### Bandpass filter + +| Method | Alias | Description | +|------------|-----------|---------------------------------| +| bandf | bpf | cutoff frequency of the bandpass filter | +| bandq | bpq | resonance of the bandpass filter (0-1) | + +${makeExample( + "Sweeping the filter on the same guitar sample", + `beat(.5) :: sound('gtr').bandf(100 + usine(1/8) * 4000).end(0.5).out()`, + true, +)} + +Alternatively, lpf, hpf and bpf can take a second argument, the **resonance**. + +## Filter order (type) + +You can also use the ftype method to change the filter type (order). There are two types by default, 12db for a gentle slope or 24db for a really steep filtering slope. The 24db type is particularly useful for substractive synthesis if you are trying to emulate some of the Moog or Prophet sounds: + +- 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, +)} + +## Filter envelopes + +The examples we have studied so far are static. They filter the sound around a fixed cutoff frequency. To make the sound more interesting, you can use the ADSR filter envelopes to shape the filter cutoff frequency over time. You will always find amplitude and filter envelopes on most commercial synthesizers. This is done using the following methods: + +### Lowpass envelope + +| Method | Alias | Description | +|------------|-----------|---------------------------------| +| lpenv | lpe | lowpass frequency modulation amount (negative or positive) | +| lpattack | lpa | attack of the lowpass filter | +| 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()) + .cutoff(5000).lpa([0.05, 0.25, 0.5].beat(2)) + .lpenv(-8).lpq(10).out()`, + true, +)} + +### Highpass envelope + +| Method | Alias | Description | +|------------|-----------|---------------------------------| +| hpenv | hpe | highpass frequency modulation amount (negative or positive) | +| hpattack | hpa | attack of the highpass filter | +| 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()) + .hcutoff(1000).hpa([0.05, 0.25, 0.5].beat(2)) + .hpenv(8).hpq(10).out()`, + true, +)} + +### Bandpass envelope + +| Method | Alias | Description | +|------------|-----------|---------------------------------| +| bpenv | bpe | bandpass frequency modulation amount (negative or positive) | +| bpattack | bpa | attack of the bandpass filter | +| 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()) + .bandf([500,1000,2000].beat(2)) + .bpa([0.25, 0.125, 0.5].beat(2) * 4) + .bpenv(-4).release(2).out() + `, + true, +)} + + +`; +}; diff --git a/src/documentation/learning/audio_engine/synths.ts b/src/documentation/learning/audio_engine/synths.ts index 220fc50..d821123 100644 --- a/src/documentation/learning/audio_engine/synths.ts +++ b/src/documentation/learning/audio_engine/synths.ts @@ -22,7 +22,6 @@ beat(.5) && snd(['sine', 'triangle', 'sawtooth', 'square'].beat()).freq(100).out Note that you can also use noise if you do not want to use a periodic oscillator: - ${makeExample( "Listening to the different types of noise", ` @@ -69,43 +68,9 @@ ${makeExample( beat(.5) && snd('triangle').chord(60,64,67,72).invert([1,-3,4,-5].pick()).adsr(0,.2).out() `, 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", - ` -tempo(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, )} -## Noise - -A certain amount of brown noise can be added by using the .noise key: - -${makeExample( - "Different vibrato settings", - ` -tempo(140); -beat(1) :: sound('triangle') - .freq(400).release(0.2) - .noise([0.2,0.4,0.5].bar()) - .vib([1/2, 1, 2, 4].beat()) - .vibmod([1,2,4,8].beat(2)) - .out()`, - true, -)} - - -## Controlling the amplitude +# Controlling amplitude Controlling the amplitude and duration of the sound can be done using various techniques. The most important thing to learn is probably how set the amplitude (volume) of your synthesizer: - gain(gain: number): sets the gain of the oscillator. @@ -123,6 +88,8 @@ ${makeExample( true, )} +## Envelopes +
Synthesizers typically come with an amplitude envelope that can help you to shape the sound with a slow attack or long release. This is done in Topos using the amplitude envelope, composed of four parameters: attack, decay, sustain and release: @@ -178,9 +145,7 @@ beat(0.5) :: sound('wt_piano') The most basic synthesis technique used since the 1970s is called substractive synthesis. This technique is based on the use of rich sound sources (oscillators) as a base to build rich and moving timbres. Because rich sources contain a lot of different harmonics, you might want to filter some of them to obtain the timbre you are looking for. To do so, Topos comes with a set of basic filters that can be used to shape the sound exactly to your liking. There are three filter types by defaut, with more to be added in the future: -- **lowpass filter**: filters the high frequencies, keeping the low frequencies. -- **highpass filter**: filtering the low frequencies, keeping the high frequencies. -- **bandpass filter**: filters the low and high frequencies around a frequency band, keeping what's in the middle. +See the Filters page for details on lowpass, highpass and bandpass filters. I also encourage you to study these simple examples to get more familiar with the construction of basic substractive synthesizers: ${makeExample( "Filtering the high frequencies of an oscillator", @@ -188,64 +153,6 @@ ${makeExample( 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: - - -### Lowpass filter - -| Method | Alias | Description | -|------------|-----------|---------------------------------| -| cutoff | lpf | cutoff frequency of the lowpass filter | -| resonance | lpq | resonance of the lowpass filter (0-1) | - -${makeExample( - "Filtering a bass", - `beat(.5) :: sound('jvbass').lpf([250,1000,8000].beat()).out()`, - true, -)} - -### Highpass filter - -| Method | Alias | Description | -|------------|-----------|---------------------------------| -| hcutoff | hpf | cutoff frequency of the highpass filter | -| hresonance | hpq | resonance of the highpass filter (0-1) | - -${makeExample( - "Filtering a noise source", - `beat(.5) :: sound('gtr').hpf([250,1000, 2000, 3000, 4000].beat()).end(0.5).out()`, - true, -)} - -### Bandpass filter - -| Method | Alias | Description | -|------------|-----------|---------------------------------| -| bandf | bpf | cutoff frequency of the bandpass filter | -| bandq | bpq | resonance of the bandpass filter (0-1) | - -${makeExample( - "Sweeping the filter on the same guitar sample", - `beat(.5) :: sound('gtr').bandf(100 + usine(1/8) * 4000).end(0.5).out()`, - true, -)} - -Alternatively, lpf, hpf and bpf can take a second argument, the **resonance**. - -## Filter order (type) - -You can also use the ftype method to change the filter type (order). There are two types by default, 12db for a gentle slope or 24db for a really steep filtering slope. The 24db type is particularly useful for substractive synthesis if you are trying to emulate some of the Moog or Prophet sounds: - -- 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, -)} - -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", ` @@ -282,73 +189,23 @@ beat(1/8)::sound('sine') false, )} -## Filter envelopes - -The examples we have studied so far are static. They filter the sound around a fixed cutoff frequency. To make the sound more interesting, you can use the ADSR filter envelopes to shape the filter cutoff frequency over time. You will always find amplitude and filter envelopes on most commercial synthesizers. This is done using the following methods: - -### Lowpass envelope - -| Method | Alias | Description | -|------------|-----------|---------------------------------| -| lpenv | lpe | lowpass frequency modulation amount (negative or positive) | -| lpattack | lpa | attack of the lowpass filter | -| 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 | +## Noise +A certain amount of brown noise can be added by using the .noise key: ${makeExample( - "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()`, + "Different vibrato settings", + ` +tempo(140); +beat(1) :: sound('triangle') + .freq(400).release(0.2) + .noise([0.2,0.4,0.5].bar()) + .vib([1/2, 1, 2, 4].beat()) + .vibmod([1,2,4,8].beat(2)) + .out()`, true, )} -### Highpass envelope - -| Method | Alias | Description | -|------------|-----------|---------------------------------| -| hpenv | hpe | highpass frequency modulation amount (negative or positive) | -| hpattack | hpa | attack of the highpass filter | -| 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()) - .hcutoff(1000).hpa([0.05, 0.25, 0.5].beat(2)) - .hpenv(8).hpq(10).out()`, - true, -)} - -### Bandpass envelope - -| Method | Alias | Description | -|------------|-----------|---------------------------------| -| bpenv | bpe | bandpass frequency modulation amount (negative or positive) | -| bpattack | bpa | attack of the bandpass filter | -| 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()) - .bandf([500,1000,2000].beat(2)) - .bpa([0.25, 0.125, 0.5].beat(2) * 4) - .bpenv(-4).release(2).out() - `, - true, -)} - - ## Wavetable synthesis 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: diff --git a/src/documentation/learning/samples/sample_controls.ts b/src/documentation/learning/samples/sample_controls.ts deleted file mode 100644 index 8d15891..0000000 --- a/src/documentation/learning/samples/sample_controls.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { type Editor } from "../../../main"; -import { makeExampleFactory } from "../../../Documentation"; - -export const sample_controls = (application: Editor): string => { - const makeExample = makeExampleFactory(application); - return ` - - -## Sample Controls - -There are some basic controls over the playback of each sample. This allows you to get into more serious sampling if you take the time to really work with your audio materials. - -| Method | Alias | Description | -|---------|-------|--------------------------------------------------------| -| n | | Select a sample in the current folder (from 0 to infinity) | -| begin | | Beginning of the sample playback (between 0 and 1) | -| end | | End of the sample (between 0 and 1) | -| loopBegin | | Beginning of the loop section (between 0 and 1) | -| loopEnd | | End of the loop section (between 0 and 1) | -| loop | | Whether to loop or not the audio sample | -| stretch | | Stretches the audio playback rate of a sample over n beats | -| speed | | Playback speed (2 = twice as fast) | -| cut | | Set with 0 or 1. Will cut the sample as soon as another sample is played on the same bus | -| clip | | Multiply the duration of the sample with the given number | -| pan | | Stereo position of the audio playback (0 = left, 1 = right)| - -${makeExample( - "Complex sampling duties", - ` -// Using some of the modifiers described above :) -beat(.5)::snd('pad').begin(0.2) - .speed([1, 0.9, 0.8].beat(4)) - .n(2).pan(usine(.5)) - .end(rand(0.3,0.8)) - .room(0.8).size(0.5) - .clip(1).out() - `, - true, -)}; - -${makeExample( - "Playing an amen break", - ` -// Note that stretch has the same value as beat -beat(4) :: sound('amen1').n(11).stretch(4).out() -beat(1) :: sound('kick').shape(0.35).out()`, - true, -)}; - - -## Filters - -There are three basic filters: a _lowpass_, _highpass_ and _bandpass_ filters with rather soft slope. Each of them can take up to two arguments. You can also use only the _cutoff_ frequency and the resonance will stay to its default nominal value. You will learn more about the usage of filters in the synths page! - -| Method | Alias | Description | -|------------|-------|-----------------------------------------| -| cutoff | lpf | Cutoff frequency of the lowpass filter | -| resonance | lpq | Resonance of the lowpass filter | -| hcutoff | hpf | Cutoff frequency of the highpass filter | -| hresonance | hpq | Resonance of the highpass filter | -| bandf | bpf | Cutoff frequency of the bandpass filter | -| bandq | bpq | Resonance of the bandpass filter | -| vowel | | Formant filter with (vocal quality) | - -${makeExample( - "Filter sweep using a low frequency oscillator", - ` -beat(.5) && snd('sawtooth') - .cutoff([2000,500].pick() + usine(.5) * 4000) - .resonance(0.9).freq([100,150].pick()) - .out() - `, - true, -)}; - - -## Compression - -This effect is leveraging the basic WebAudio compressor. More information can be found about it on the [DynamicsCompressorNode](https://developer.mozilla.org/en-US/docs/Web/API/DynamicsCompressorNode?retiredLocale=de#instance_properties) page. This can be come quite complex :) - -| Method | Alias | Description | -|------------|-----------|---------------------------------| -| comp | cmp | Compressor threshold value (dB) over which compressor operates | -| ratio | rt | Compressor ratio: input amount in dB needed for 1dB change in the output | -| knee | kn | dB value defining the range over which the signal transitions to compressed section | -| compAttack | cmpa | In seconds, time to decrease the gain by 10db | -| compRelease | cmpr | In seconds, time to increase the gain by 10db | - - -`; -};