Skip to content

Commit ebb09b6

Browse files
committed
Made vibrato an optional effect for all instruments.
1 parent 4131860 commit ebb09b6

File tree

3 files changed

+116
-99
lines changed

3 files changed

+116
-99
lines changed

editor/SongEditor.ts

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright (C) 2021 John Nesky, distributed under the MIT license.
22

3-
import {InstrumentType, EffectType, Config, getPulseWidthRatio, effectsIncludePitchShift, effectsIncludeDetune, effectsIncludeNoteFilter, effectsIncludeDistortion, effectsIncludeBitcrusher, effectsIncludePanning, effectsIncludeEcho, effectsIncludeReverb} from "../synth/SynthConfig";
3+
import {InstrumentType, EffectType, Config, getPulseWidthRatio, effectsIncludePitchShift, effectsIncludeDetune, effectsIncludeVibrato, effectsIncludeNoteFilter, effectsIncludeDistortion, effectsIncludeBitcrusher, effectsIncludePanning, effectsIncludeEcho, effectsIncludeReverb} from "../synth/SynthConfig";
44
import {Preset, PresetCategory, EditorConfig, isMobile, prettyNumber} from "./EditorConfig";
55
import {ColorConfig} from "./ColorConfig";
66
import {Layout} from "./Layout";
@@ -251,7 +251,6 @@ export class SongEditor {
251251
this._eqFilterRow,
252252
this._transitionRow,
253253
this._chordSelectRow,
254-
this._vibratoSelectRow,
255254
this._chipWaveSelectRow,
256255
this._chipNoiseSelectRow,
257256
this._algorithmSelectRow,
@@ -270,6 +269,7 @@ export class SongEditor {
270269
),
271270
this._pitchShiftRow,
272271
this._detuneRow,
272+
this._vibratoSelectRow,
273273
this._noteFilterRow,
274274
this._distortionRow,
275275
this._bitcrusherQuantizationRow,
@@ -780,6 +780,13 @@ export class SongEditor {
780780
this._detuneRow.style.display = "none";
781781
}
782782

783+
if (effectsIncludeVibrato(instrument.effects)) {
784+
this._vibratoSelectRow.style.display = "";
785+
setSelectedValue(this._vibratoSelect, instrument.vibrato);
786+
} else {
787+
this._vibratoSelectRow.style.display = "none";
788+
}
789+
783790
if (effectsIncludeNoteFilter(instrument.effects)) {
784791
this._noteFilterRow.style.display = "";
785792
this._noteFilterEditor.render();
@@ -829,32 +836,11 @@ export class SongEditor {
829836
this._reverbRow.style.display = "none";
830837
}
831838

832-
if (instrument.type == InstrumentType.noise) {
833-
this._vibratoSelectRow.style.display = "none";
834-
this._unisonSelectRow.style.display = "none";
835-
} else if (instrument.type == InstrumentType.spectrum) {
836-
this._vibratoSelectRow.style.display = "none";
837-
this._unisonSelectRow.style.display = "none";
838-
} else if (instrument.type == InstrumentType.drumset) {
839-
this._vibratoSelectRow.style.display = "none";
840-
this._unisonSelectRow.style.display = "none";
841-
} else if (instrument.type == InstrumentType.chip) {
842-
this._vibratoSelectRow.style.display = "";
843-
this._unisonSelectRow.style.display = "";
844-
} else if (instrument.type == InstrumentType.fm) {
845-
this._vibratoSelectRow.style.display = "";
846-
this._unisonSelectRow.style.display = "none";
847-
} else if (instrument.type == InstrumentType.harmonics) {
848-
this._vibratoSelectRow.style.display = "";
839+
if (instrument.type == InstrumentType.chip || instrument.type == InstrumentType.harmonics) {
849840
this._unisonSelectRow.style.display = "";
850-
} else if (instrument.type == InstrumentType.pwm) {
851-
this._vibratoSelectRow.style.display = "";
852-
this._unisonSelectRow.style.display = "none";
853-
} else if (instrument.type == InstrumentType.pickedString) {
854-
this._vibratoSelectRow.style.display = "";
855-
this._unisonSelectRow.style.display = "none";
841+
setSelectedValue(this._unisonSelect, instrument.unison);
856842
} else {
857-
throw new Error("Unrecognized instrument type: " + instrument.type);
843+
this._unisonSelectRow.style.display = "none";
858844
}
859845

860846
this._envelopeEditor.render();
@@ -887,8 +873,6 @@ export class SongEditor {
887873

888874
this._eqFilterEditor.render();
889875
setSelectedValue(this._transitionSelect, instrument.transition);
890-
setSelectedValue(this._vibratoSelect, instrument.vibrato);
891-
setSelectedValue(this._unisonSelect, instrument.unison);
892876
setSelectedValue(this._chordSelect, instrument.chord);
893877
this._instrumentVolumeSlider.updateValue(-instrument.volume);
894878
setSelectedValue(this._instrumentSelect, instrumentIndex);

synth/SynthConfig.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,24 @@ export const enum EffectType {
6969
echo,
7070
pitchShift,
7171
detune,
72+
vibrato,
7273
length,
7374
}
7475

7576
export const enum NoteAutomationIndex {
7677
noteVolume,
7778
noteFilterAllFreqs,
78-
noteFilterFreq0, noteFilterFreq1, noteFilterFreq2, noteFilterFreq3, noteFilterFreq4, noteFilterFreq5, noteFilterFreq6, noteFilterFreq7,
79-
noteFilterPeak0, noteFilterPeak1, noteFilterPeak2, noteFilterPeak3, noteFilterPeak4, noteFilterPeak5, noteFilterPeak6, noteFilterPeak7,
80-
pitchShift,
81-
detune,
82-
vibratoDepth,
8379
unison,
8480
pulseWidth,
8581
stringSustain,
8682
operatorFrequency0, operatorFrequency1, operatorFrequency2, operatorFrequency3,
8783
operatorAmplitude0, operatorAmplitude1, operatorAmplitude2, operatorAmplitude3,
8884
feedbackAmplitude,
85+
pitchShift,
86+
detune,
87+
vibratoDepth,
88+
noteFilterFreq0, noteFilterFreq1, noteFilterFreq2, noteFilterFreq3, noteFilterFreq4, noteFilterFreq5, noteFilterFreq6, noteFilterFreq7,
89+
noteFilterPeak0, noteFilterPeak1, noteFilterPeak2, noteFilterPeak3, noteFilterPeak4, noteFilterPeak5, noteFilterPeak6, noteFilterPeak7,
8990
length,
9091
}
9192

@@ -333,8 +334,8 @@ export class Config {
333334
{name: "bowed", spread: 0.02, offset: 0.0, expression: 1.0, sign:-1.0},
334335
{name: "piano", spread: 0.01, offset: 0.0, expression: 1.0, sign: 0.7},
335336
]);
336-
public static readonly effectsNames: ReadonlyArray<string> = ["reverb", "chorus", "panning", "distortion", "bitcrusher", "note filter", "echo", "pitch shift", "detune"];
337-
public static readonly effectOrder: ReadonlyArray<EffectType> = [EffectType.pitchShift, EffectType.detune, EffectType.noteFilter, EffectType.distortion, EffectType.bitcrusher, EffectType.panning, EffectType.chorus, EffectType.echo, EffectType.reverb];
337+
public static readonly effectsNames: ReadonlyArray<string> = ["reverb", "chorus", "panning", "distortion", "bitcrusher", "note filter", "echo", "pitch shift", "detune", "vibrato"];
338+
public static readonly effectOrder: ReadonlyArray<EffectType> = [EffectType.pitchShift, EffectType.detune, EffectType.vibrato, EffectType.noteFilter, EffectType.distortion, EffectType.bitcrusher, EffectType.panning, EffectType.chorus, EffectType.echo, EffectType.reverb];
338339
public static readonly noteSizeMax: number = 3;
339340
public static readonly volumeRange: number = 8;
340341
public static readonly volumeLogScale: number = -0.5;
@@ -490,10 +491,6 @@ export class Config {
490491
{name: "eqFilterAllFreqs", computeIndex: InstrumentAutomationIndex.eqFilterAllFreqs, displayName: "eqfilter* freqs", perNote: false, interleave: false, isFilter: true, range: null, maxCount: 1, effect: null, compatibleInstruments: null},
491492
{name: "eqFilterFreq", computeIndex: InstrumentAutomationIndex.eqFilterFreq0, displayName: "eqfilter# freq", perNote: false, interleave: true, isFilter: true, range: Config.filterFreqRange, maxCount: Config.filterMaxPoints, effect: null, compatibleInstruments: null},
492493
{name: "eqFilterPeak", computeIndex: InstrumentAutomationIndex.eqFilterPeak0, displayName: "eqfilter# peak", perNote: false, interleave: false, isFilter: true, range: Config.filterGainRange, maxCount: Config.filterMaxPoints, effect: null, compatibleInstruments: null}, // symmetrical, centered on "neutral"?
493-
{name: "noteFilterAllFreqs", computeIndex: NoteAutomationIndex.noteFilterAllFreqs, displayName: "n.filter* freqs", perNote: true, interleave: false, isFilter: true, range: null, maxCount: 1, effect: EffectType.noteFilter, compatibleInstruments: null},
494-
{name: "noteFilterFreq", computeIndex: NoteAutomationIndex.noteFilterFreq0, displayName: "n.filter# freq", perNote: true, interleave: true, isFilter: true, range: Config.filterFreqRange, maxCount: Config.filterMaxPoints, effect: EffectType.noteFilter, compatibleInstruments: null},
495-
{name: "noteFilterPeak", computeIndex: NoteAutomationIndex.noteFilterPeak0, displayName: "n.filter# peak", perNote: true, interleave: false, isFilter: true, range: Config.filterGainRange, maxCount: Config.filterMaxPoints, effect: EffectType.noteFilter, compatibleInstruments: null}, // symmetrical, centered on "neutral"?
496-
{name: "vibratoDepth", computeIndex: NoteAutomationIndex.vibratoDepth, displayName: "vibrato range", perNote: true, interleave: false, isFilter: false, range: Config.defaultAutomationRange, maxCount: 1, effect: null, compatibleInstruments: [InstrumentType.chip, InstrumentType.fm, InstrumentType.harmonics, InstrumentType.pwm, InstrumentType.pickedString]},
497494
{name: "unison", computeIndex: NoteAutomationIndex.unison, displayName: "unison", perNote: true, interleave: false, isFilter: false, range: Config.defaultAutomationRange, maxCount: 1, effect: null, compatibleInstruments: [InstrumentType.chip, InstrumentType.harmonics]},
498495
{name: "pulseWidth", computeIndex: NoteAutomationIndex.pulseWidth, displayName: "pulse width", perNote: true, interleave: false, isFilter: false, range: Config.pulseWidthRange, maxCount: 1, effect: null, compatibleInstruments: [InstrumentType.pwm]},
499496
{name: "stringSustain", computeIndex: NoteAutomationIndex.stringSustain, displayName: "sustain", perNote: true, interleave: false, isFilter: false, range: Config.stringSustainRange, maxCount: 1, effect: null, compatibleInstruments: [InstrumentType.pickedString]},
@@ -502,6 +499,10 @@ export class Config {
502499
{name: "feedbackAmplitude", computeIndex: NoteAutomationIndex.feedbackAmplitude, displayName: "fm feedback", perNote: true, interleave: false, isFilter: false, range: Config.operatorAmplitudeMax + 1, maxCount: 1, effect: null, compatibleInstruments: [InstrumentType.fm]},
503500
{name: "pitchShift", computeIndex: NoteAutomationIndex.pitchShift, displayName: "pitch shift", perNote: true, interleave: false, isFilter: false, range: Config.pitchShiftRange, maxCount: 1, effect: EffectType.pitchShift, compatibleInstruments: null},
504501
{name: "detune", computeIndex: NoteAutomationIndex.detune, displayName: "detune", perNote: true, interleave: false, isFilter: false, range: Config.detuneMax + 1, maxCount: 1, effect: EffectType.detune, compatibleInstruments: null},
502+
{name: "vibratoDepth", computeIndex: NoteAutomationIndex.vibratoDepth, displayName: "vibrato range", perNote: true, interleave: false, isFilter: false, range: Config.defaultAutomationRange, maxCount: 1, effect: EffectType.vibrato, compatibleInstruments: null},
503+
{name: "noteFilterAllFreqs", computeIndex: NoteAutomationIndex.noteFilterAllFreqs, displayName: "n.filter* freqs", perNote: true, interleave: false, isFilter: true, range: null, maxCount: 1, effect: EffectType.noteFilter, compatibleInstruments: null},
504+
{name: "noteFilterFreq", computeIndex: NoteAutomationIndex.noteFilterFreq0, displayName: "n.filter# freq", perNote: true, interleave: true, isFilter: true, range: Config.filterFreqRange, maxCount: Config.filterMaxPoints, effect: EffectType.noteFilter, compatibleInstruments: null},
505+
{name: "noteFilterPeak", computeIndex: NoteAutomationIndex.noteFilterPeak0, displayName: "n.filter# peak", perNote: true, interleave: false, isFilter: true, range: Config.filterGainRange, maxCount: Config.filterMaxPoints, effect: EffectType.noteFilter, compatibleInstruments: null}, // symmetrical, centered on "neutral"?
505506
{name: "distortion", computeIndex: InstrumentAutomationIndex.distortion, displayName: "distortion", perNote: false, interleave: false, isFilter: false, range: Config.distortionRange, maxCount: 1, effect: EffectType.distortion, compatibleInstruments: null},
506507
{name: "bitcrusherQuantization", computeIndex: InstrumentAutomationIndex.bitcrusherQuantization, displayName: "bit crush", perNote: false, interleave: false, isFilter: false, range: Config.bitcrusherQuantizationRange, maxCount: 1, effect: EffectType.bitcrusher, compatibleInstruments: null},
507508
{name: "bitcrusherFrequency", computeIndex: InstrumentAutomationIndex.bitcrusherFrequency, displayName: "freq crush", perNote: false, interleave: false, isFilter: false, range: Config.bitcrusherFreqRange, maxCount: 1, effect: EffectType.bitcrusher, compatibleInstruments: null},
@@ -672,6 +673,9 @@ export function effectsIncludePitchShift(effects: number): boolean {
672673
export function effectsIncludeDetune(effects: number): boolean {
673674
return (effects & (1 << EffectType.detune)) != 0;
674675
}
676+
export function effectsIncludeVibrato(effects: number): boolean {
677+
return (effects & (1 << EffectType.vibrato)) != 0;
678+
}
675679
export function effectsIncludeNoteFilter(effects: number): boolean {
676680
return (effects & (1 << EffectType.noteFilter)) != 0;
677681
}

0 commit comments

Comments
 (0)