Adding documentation about synthesizers

This commit is contained in:
2023-08-24 09:06:24 +02:00
parent 3da6a905f3
commit 6ad5bb7fa9
4 changed files with 256 additions and 198 deletions

View File

@ -99,6 +99,8 @@
<p rel="noopener noreferrer" id="docs_time" class="pl-2 pr-2 lg:text-xl text-sm hover:bg-neutral-800 py-1 my-1 rounded-lg">Time</p>
<p rel="noopener noreferrer" id="docs_sound" class="pl-2 pr-2 lg:text-xl text-sm hover:bg-neutral-800 py-1 my-1 rounded-lg">Sound</p>
<p rel="noopener noreferrer" id="docs_samples" class="pl-2 pr-2 lg:text-xl text-sm hover:bg-neutral-800 py-1 my-1 rounded-lg">Samples</p>
<p rel="noopener noreferrer" id="docs_synths" class="pl-2 pr-2 lg:text-xl text-sm hover:bg-neutral-800 py-1 my-1 rounded-lg">Synths</p>
<p rel="noopener noreferrer" id="docs_midi" class="pl-2 pr-2 lg:text-xl text-sm hover:bg-neutral-800 py-1 my-1 rounded-lg">MIDI</p>
<p rel="noopener noreferrer" id="docs_functions" class="pl-2 pr-2 lg:text-xl text-sm hover:bg-neutral-800 py-1 my-1 rounded-lg">Functions</p>
<p rel="noopener noreferrer" id="docs_shortcuts" class="pl-2 pr-2 lg:text-xl text-sm hover:bg-neutral-800 py-1 my-1 rounded-lg">Shortcuts</p>

View File

@ -355,6 +355,51 @@ ${injectAvailableSamples()}
`;
const synths: string = `
# Synthesizers
Topos comes with a small number of basic synthesizers. These synths are based on a basic [WebAudio](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) design. For heavy synthesis duties, please use MIDI and speak to more complex instruments.
# Substractive Synthesis
The <icode>sound</icode> function can take the name of a synthesizer as first argument.
- <icode>sine</icode>, <icode>sawtooth</icode>,<icode>triangle</icode>, <icode>square</icode> for the waveform selection.
- <icode>cutoff</icode> and <icode>resonance</icode> for adding a low-pass filter with cutoff frequency and filter resonance.
- <icode>hcutoff</icode> or <icode>bandf</icode> to switch to a high-pass or bandpass filter.
- <icode>hresonance</icode> and <icode>bandq</icode> for the resonance parameter of these filters.
Here is a simple example of a substractive synth:
\`\`\`javascript
mod(.5) && snd('sawtooth')
.cutoff(pick(2000,500)) + usine(.5) * 4000)
.resonance(0.9).freq(pick(100,150))
.out()
\`\`\`
# Frequency Modulation Synthesis (FM)
The same basic waveforms can take additional methods to switch to a basic two operators FM synth design (with _carrier_ and _modulator_). FM Synthesis is a complex topic but take this advice: simple ratios will yield stable and harmonic sounds, complex ratios will generate noises, percussions and gritty sounds.
- <icode>fmi</icode> (_frequency modulation index_): a floating point value between <icode>1</icode> and <icode>n</icode>.
- <icode>fmh</icode> (_frequency modulation harmonic ratio_): a floating point value between <icode>1</icode> and <icode>n</icode>.
And here is a simple example:
\`\`\`javascript
mod(.25) && snd('sine')
.fmi(pick(1,2,4,8))
.fmh(divseq(2, 1,2,4,8))
.freq(pick(100,150))
.sustain(0.1)
.out()
\`\`\`
**Note::** you can also set the _modulation index_ and the _harmonic ratio_ with the <icode>fm</icode> argument. You will have to feed both as a string: <icode>fm('2:4')</icode>. If you only feed one number, only the _modulation index_ will be updated.
`;
const about: string = `
# About Topos
@ -570,6 +615,7 @@ export const documentation = {
time: time,
sound: sound,
samples: samples,
synths: synths,
midi: midi,
functions: functions,
reference: reference,

View File

@ -1,6 +1,6 @@
import { type Editor } from '../main';
import { SoundEvent } from './Event';
import { midiToFreq, noteFromPc } from 'zifferjs';
import { type Editor } from "../main";
import { SoundEvent } from "./Event";
import { midiToFreq, noteFromPc } from "zifferjs";
import {
superdough,
@ -8,10 +8,9 @@ import {
} from "superdough";
export class Sound extends SoundEvent {
constructor(sound: string|object, public app: Editor) {
constructor(sound: string | object, public app: Editor) {
super(app);
if (typeof sound === 'string') this.values = { 's': sound, 'dur': 0.5 };
if (typeof sound === "string") this.values = { s: sound, dur: 0.5 };
else this.values = sound;
}
@ -55,7 +54,7 @@ export class Sound extends SoundEvent {
};
sound = (value: string): this => {
this.values['s'] = value
this.values["s"] = value;
return this;
};
@ -211,7 +210,7 @@ export class Sound extends SoundEvent {
modify = (func: Function): this => {
const funcResult = func(this);
if(funcResult instanceof Object) return funcResult;
if (funcResult instanceof Object) return funcResult;
else {
func(this.values);
return this;
@ -223,13 +222,24 @@ export class Sound extends SoundEvent {
this.values["dur"] = value;
return this;
};
sus = this.sustain;
update = (): void => {
if(this.values.key && this.values.pitch && this.values.parsedScale && this.values.octave) {
const [note,_] = noteFromPc(this.values.key, this.values.pitch, this.values.parsedScale, this.values.octave);
if (
this.values.key &&
this.values.pitch &&
this.values.parsedScale &&
this.values.octave
) {
const [note, _] = noteFromPc(
this.values.key,
this.values.pitch,
this.values.parsedScale,
this.values.octave
);
this.values.freq = midiToFreq(note);
}
}
};
out = (): object => {
return superdough(
@ -238,5 +248,4 @@ export class Sound extends SoundEvent {
this.values.dur
);
};
}

View File

@ -559,6 +559,7 @@ export class Editor {
"time",
"sound",
"samples",
"synths",
"midi",
"functions",
"reference",