This commit is contained in:
2023-09-26 20:02:03 +03:00
3 changed files with 80 additions and 62 deletions

View File

@ -33,6 +33,7 @@ export async function loadSamples() {
registerZZFXSounds(), registerZZFXSounds(),
samples("github:Bubobubobubobubo/Dough-Samples/main"), samples("github:Bubobubobubobubo/Dough-Samples/main"),
samples("github:Bubobubobubobubo/Dough-Amiga/main"), samples("github:Bubobubobubobubo/Dough-Amiga/main"),
samples("github:Bubobubobubobubo/Dough-Amen/main"),
samples("github:Bubobubobubobubo/Dough-Waveforms/main"), samples("github:Bubobubobubobubo/Dough-Waveforms/main"),
]); ]);
} }

View File

@ -235,25 +235,25 @@ export class SoundEvent extends AudibleEvent {
// Frequency management // Frequency management
public sound = (value: string) => this.updateValue("s", value); public sound = (value: string) => this.updateValue("s", value);
public chord = (value: string|object[]|number[]|number,...kwargs: number[]) => { public chord = (value: string | object[] | number[] | number, ...kwargs: number[]) => {
if(typeof value === "string") { if (typeof value === "string") {
const chord = parseChord(value); const chord = parseChord(value);
value = chord.map((note: number) => { return {note: note, freq: midiToFreq(note) } }); value = chord.map((note: number) => { return { note: note, freq: midiToFreq(note) } });
} else if(value instanceof Array && typeof value[0] === "number") { } else if (value instanceof Array && typeof value[0] === "number") {
value = (value as number[]).map((note: number) => { return {note: note, freq: midiToFreq(note) } }); value = (value as number[]).map((note: number) => { return { note: note, freq: midiToFreq(note) } });
} else if (typeof value === "number" && kwargs.length > 0) { } else if (typeof value === "number" && kwargs.length > 0) {
value = [value, ...kwargs].map((note: number) => { return {note: note, freq: midiToFreq(note) } }); value = [value, ...kwargs].map((note: number) => { return { note: note, freq: midiToFreq(note) } });
} }
return this.updateValue("chord", value); return this.updateValue("chord", value);
} }
public invert = (howMany: number = 0) => { public invert = (howMany: number = 0) => {
if(this.values.chord) { if (this.values.chord) {
let notes = this.values.chord.map((obj: { [key: string]: number }) => obj.note); let notes = this.values.chord.map((obj: { [key: string]: number }) => obj.note);
notes = howMany < 0 ? [...notes].reverse() : notes; notes = howMany < 0 ? [...notes].reverse() : notes;
for (let i = 0; i < Math.abs(howMany); i++) { for (let i = 0; i < Math.abs(howMany); i++) {
notes[i % notes.length] += howMany <= 0 ? -12 : 12; notes[i % notes.length] += howMany <= 0 ? -12 : 12;
} }
const chord = notes.map((note: number) => { return {note: note, freq: midiToFreq(note) } }); const chord = notes.map((note: number) => { return { note: note, freq: midiToFreq(note) } });
return this.updateValue("chord", chord); return this.updateValue("chord", chord);
} else { } else {
return this; return this;
@ -264,8 +264,8 @@ export class SoundEvent extends AudibleEvent {
public cut = (value: number) => this.updateValue("cut", value); public cut = (value: number) => this.updateValue("cut", value);
public clip = (value: number) => this.updateValue("clip", value); public clip = (value: number) => this.updateValue("clip", value);
public n = (value: number) => this.updateValue("n", value); public n = (value: number) => this.updateValue("n", value);
public note = (value: number|string) => { public note = (value: number | string) => {
if(typeof value === "string") { if (typeof value === "string") {
return this.updateValue("note", noteNameToMidi(value)); return this.updateValue("note", noteNameToMidi(value));
} else { } else {
return this.updateValue("note", value); return this.updateValue("note", value);
@ -300,6 +300,13 @@ export class SoundEvent extends AudibleEvent {
public size = (value: number) => this.updateValue("size", value); public size = (value: number) => this.updateValue("size", value);
public sz = this.size; public sz = this.size;
// Unit
public stretch = (beat: number) => {
this.updateValue("unit", "c");
this.updateValue("speed", 2 / beat)
return this;
}
// ================================================================================ // ================================================================================
// AbstactEvent overrides // AbstactEvent overrides
// ================================================================================ // ================================================================================

View File

@ -19,7 +19,7 @@ beat(1) && sound('bd').out()
beat(0.5) && sound('hh').out() beat(0.5) && sound('hh').out()
`, `,
true true
)} )}
In plain english, this translates to: In plain english, this translates to:
@ -35,7 +35,7 @@ beat(1) && sound('bd').coarse(0.25).room(0.5).orbit(2).out();
beat(0.5) && sound('hh').delay(0.25).delaytime(0.125).out(); beat(0.5) && sound('hh').delay(0.25).delaytime(0.125).out();
`, `,
true true
)} )}
Now, it reads as follow: Now, it reads as follow:
@ -60,7 +60,7 @@ beat(1) :: sound('pad')
.velocity(0.25) .velocity(0.25)
.pan(usine()).release(2).out()`, .pan(usine()).release(2).out()`,
true true
)} )}
## Audio Sample Folders / Sample Files ## Audio Sample Folders / Sample Files
@ -89,7 +89,7 @@ ${makeExample(
beat(1) && sound('kick').n([1,2,3,4,5,6,7,8].pick()).out() beat(1) && sound('kick').n([1,2,3,4,5,6,7,8].pick()).out()
`, `,
true true
)} )}
Don't worry about the number. If it gets too big, it will be automatically wrapped to the number of samples in the folder. You can type any number, it will always fall on a sample. Let's use our mouse to select a sample number in a folder: Don't worry about the number. If it gets too big, it will be automatically wrapped to the number of samples in the folder. You can type any number, it will always fall on a sample. Let's use our mouse to select a sample number in a folder:
@ -99,7 +99,7 @@ ${makeExample(
// Move your mouse to change the sample being used! // Move your mouse to change the sample being used!
beat(.25) && sound('numbers').n(Math.floor(mouseX())).out()`, beat(.25) && sound('numbers').n(Math.floor(mouseX())).out()`,
true true
)} )}
**Note:** the <ic>sound</ic> function can also be used to play synthesizers (see the **Synthesizers** page). In that case, the <ic>.n(n: number)</ic> becomes totally useless! **Note:** the <ic>sound</ic> function can also be used to play synthesizers (see the **Synthesizers** page). In that case, the <ic>.n(n: number)</ic> becomes totally useless!
@ -116,7 +116,7 @@ beat(0.25) && sound('jvbass')
.cutoff(usine(2) * 5000) .cutoff(usine(2) * 5000)
.out()`, .out()`,
true true
)} )}
There are many possible arguments that you can add to your sounds. Learning them can take a long time but it will open up a lot of possibilities. Let's try to make it through all of them. They can all be used both with synthesizers and audio samples, which is kind of unconventional with normal / standard electronic music softwares. There are many possible arguments that you can add to your sounds. Learning them can take a long time but it will open up a lot of possibilities. Let's try to make it through all of them. They can all be used both with synthesizers and audio samples, which is kind of unconventional with normal / standard electronic music softwares.
@ -149,7 +149,7 @@ ${makeExample(
` `
beat(.5)::snd('cp').vel($(1)%10 / 10).out()`, beat(.5)::snd('cp').vel($(1)%10 / 10).out()`,
true true
)} )}
## Amplitude Enveloppe ## Amplitude Enveloppe
@ -174,7 +174,7 @@ beat(.25)::sound('sawtooth').note([50,57,62].pick() + [12, 24, 0].beat(2))
.cutoff(5000).sustain(0.5).release(0.1).gain(0.25).out() .cutoff(5000).sustain(0.5).release(0.1).gain(0.25).out()
`, `,
true true
)}; )};
## Sample Controls ## Sample Controls
@ -188,6 +188,7 @@ There are some basic controls over the playback of each sample. This allows you
| loopBegin | | Beginning of the loop section (between <ic>0</ic> and <ic>1</ic>) | | loopBegin | | Beginning of the loop section (between <ic>0</ic> and <ic>1</ic>) |
| loopEnd | | End of the loop section (between <ic>0</ic> and <ic>1</ic>) | | loopEnd | | End of the loop section (between <ic>0</ic> and <ic>1</ic>) |
| loop | | Whether to loop or not the audio sample | | loop | | Whether to loop or not the audio sample |
| stretch | | Stretches the audio playback rate of a sample over <ic>n</ic> beats |
| speed | | Playback speed (<ic>2</ic> = twice as fast) | | speed | | Playback speed (<ic>2</ic> = twice as fast) |
| cut | | Set with <ic>0</ic> or <ic>1</ic>. Will cut the sample as soon as another sample is played on the same bus | | cut | | Set with <ic>0</ic> or <ic>1</ic>. 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 | | clip | | Multiply the duration of the sample with the given number |
@ -205,8 +206,17 @@ beat(.5)::snd('pad').begin(0.2)
.clip(1).out() .clip(1).out()
`, `,
true true
)}; )};
${makeExample(
"Playing an amen break",
`
// Note that stretch has the same value as beat
beat(4) :: sound('breaks165').stretch(4).out()
beat(0.25) :: sound('hh').out()
beat(1, 4, 8) :: sound('bd').out()`,
true,
)};
## Filters ## Filters
@ -231,7 +241,7 @@ beat(.5) && snd('sawtooth')
.out() .out()
`, `,
true true
)}; )};
## Reverb ## Reverb
@ -248,7 +258,7 @@ ${makeExample(
beat(2)::snd('cp').room(1).size(0.9).out() beat(2)::snd('cp').room(1).size(0.9).out()
`, `,
true true
)}; )};
## Delay ## Delay
@ -269,7 +279,7 @@ beat(4)::snd('snare').out()
beat(1)::snd('kick').out() beat(1)::snd('kick').out()
`, `,
true true
)}; )};
## Distorsion, saturation, destruction ## Distorsion, saturation, destruction
@ -287,6 +297,6 @@ beat(.5)::snd('pad').coarse($(1) % 16).clip(.5).out(); // Comment me
beat(.5)::snd('pad').crush([16, 8, 4].beat(2)).clip(.5).out() beat(.5)::snd('pad').crush([16, 8, 4].beat(2)).clip(.5).out()
`, `,
true true
)}; )};
`; `;
}; };