Skip to content

Commit e88f0f0

Browse files
committed
Bugfixes: Remove lerp when filter dot types change (caused pop). Fixed note overlap issue when pasting from a selection in mod patterns. Lowered echo mod max to match slider. Fixed vibrato delay storing as a decimal in some cases.
1 parent 5979ac6 commit e88f0f0

File tree

4 files changed

+21
-8
lines changed

4 files changed

+21
-8
lines changed

editor/SongEditor.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,6 @@ export class SongEditor {
10211021
this._detuneSliderInputBox.addEventListener("input", () => { this._doc.record(new ChangeDetune(this._doc, this._doc.song.channels[this._doc.channel].instruments[this._doc.getCurrentInstrument()].detune, Math.min(Config.detuneMax - Config.detuneCenter, Math.max(Config.detuneMin - Config.detuneCenter, Math.round(+this._detuneSliderInputBox.value))))) });
10221022
this._customWaveDraw.addEventListener("input", () => { this._doc.record(new ChangeCustomWave(this._doc, this._customWaveDrawCanvas.newArray)) });
10231023
this._twoNoteArpBox.addEventListener("input", () => { this._doc.record(new ChangeFastTwoNoteArp(this._doc, this._twoNoteArpBox.checked)) });
1024-
//this._tieNoteTransitionBox.addEventListener("input", () => { this._doc.record(new ChangeTieNoteTransition(this._doc, this._tieNoteTransitionBox.checked)) });
10251024
this._clicklessTransitionBox.addEventListener("input", () => { this._doc.record(new ChangeClicklessTransition(this._doc, this._clicklessTransitionBox.checked)) });
10261025
this._aliasingBox.addEventListener("input", () => { this._doc.record(new ChangeAliasing(this._doc, this._aliasingBox.checked)) });
10271026

@@ -1802,12 +1801,12 @@ export class SongEditor {
18021801
this._instrumentVolumeSlider.updateValue(instrument.volume);
18031802
this._instrumentVolumeSliderInputBox.value = "" + (instrument.volume);
18041803
this._vibratoDepthSlider.updateValue(Math.round(instrument.vibratoDepth * 25));
1805-
this._vibratoDelaySlider.updateValue(instrument.vibratoDelay);
1804+
this._vibratoDelaySlider.updateValue(Math.round(instrument.vibratoDelay));
18061805
this._vibratoSpeedSlider.updateValue(instrument.vibratoSpeed);
18071806
setSelectedValue(this._vibratoTypeSelect, instrument.vibratoType);
18081807
this._arpeggioSpeedSlider.updateValue(instrument.arpeggioSpeed);
18091808
this._panDelaySlider.updateValue(instrument.panDelay);
1810-
this._vibratoDelaySlider.input.title = "" + instrument.vibratoDelay;
1809+
this._vibratoDelaySlider.input.title = "" + Math.round(instrument.vibratoDelay);
18111810
this._vibratoDepthSlider.input.title = "" + instrument.vibratoDepth;
18121811
this._vibratoSpeedSlider.input.title = "" + instrument.vibratoSpeed;
18131812
this._panDelaySlider.input.title = "" + instrument.panDelay;

editor/changes.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ function projectNoteIntoBar(oldNote: Note, timeOffset: number, noteStartPart: nu
183183
}
184184
}
185185
}
186-
186+
187187
// Fix from Jummbus: Ensure the first pin's interval is zero, adjust pitches and pins to compensate.
188188
const offsetInterval: number = newNote.pins[0].interval;
189189
for (let pitchIdx: number = 0; pitchIdx < newNote.pitches.length; pitchIdx++) {
@@ -2377,6 +2377,10 @@ export class ChangePaste extends ChangeGroup {
23772377
selectionStart += oldPartDuration;
23782378
}
23792379

2380+
// Need to re-sort the notes by start time as they might change order because of paste.
2381+
if (pattern != null && doc.song.getChannelIsMod(doc.channel)) pattern.notes.sort(function (a, b) { return (a.start == b.start) ? a.pitches[0] - b.pitches[0] : a.start - b.start; });
2382+
2383+
23802384
doc.notifier.changed();
23812385
this._didSomething();
23822386
}

synth/SynthConfig.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ export class Config {
665665
{ name: "note filter", pianoName: "N.Flt", maxRawVol: 10, newNoteVol: 0, forSong: false, convertRealFactor: 0, associatedEffect: EffectType.noteFilter },
666666
{ name: "bit crush", pianoName: "Bitcrush", maxRawVol: Config.bitcrusherQuantizationRange, newNoteVol: Math.round(Config.bitcrusherQuantizationRange / 2), forSong: false, convertRealFactor: 0, associatedEffect: EffectType.bitcrusher },
667667
{ name: "freq crush", pianoName: "Freq Crush", maxRawVol: Config.bitcrusherFreqRange, newNoteVol: Math.round(Config.bitcrusherFreqRange / 2), forSong: false, convertRealFactor: 0, associatedEffect: EffectType.bitcrusher },
668-
{ name: "echo", pianoName: "Echo", maxRawVol: Config.echoSustainRange, newNoteVol: 0, forSong: false, convertRealFactor: 0, associatedEffect: EffectType.echo },
668+
{ name: "echo", pianoName: "Echo", maxRawVol: Config.echoSustainRange-1, newNoteVol: 0, forSong: false, convertRealFactor: 0, associatedEffect: EffectType.echo },
669669
{ name: "echo delay", pianoName: "Echo Delay", maxRawVol: Config.echoDelayRange, newNoteVol: 0, forSong: false, convertRealFactor: 0, associatedEffect: EffectType.length }, // Disabled via associatedEffect and manually in list build in SongEditor, enable and set back to echo after fixing bugginess!
670670
{ name: "chorus", pianoName: "Chorus", maxRawVol: Config.chorusRange, newNoteVol: 0, forSong: false, convertRealFactor: 0, associatedEffect: EffectType.chorus },
671671
{ name: "eq filt cut", pianoName: "EQFlt Cut", maxRawVol: Config.filterSimpleCutRange - 1, newNoteVol: Config.filterSimpleCutRange - 1, forSong: false, convertRealFactor: 0, associatedEffect: EffectType.length },

synth/synth.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2524,7 +2524,7 @@ export class Song {
25242524
if (instrument.vibrato == Config.vibratos.length) {
25252525
buffer.push(base64IntToCharCode[Math.round(instrument.vibratoDepth * 25)]);
25262526
buffer.push(base64IntToCharCode[instrument.vibratoSpeed]);
2527-
buffer.push(base64IntToCharCode[instrument.vibratoDelay]);
2527+
buffer.push(base64IntToCharCode[Math.round(instrument.vibratoDelay)]);
25282528
buffer.push(base64IntToCharCode[instrument.vibratoType]);
25292529
}
25302530
}
@@ -3547,7 +3547,7 @@ export class Song {
35473547
if (vibrato == Config.vibratos.length) {
35483548
instrument.vibratoDepth = clamp(0, Config.modulators.dictionary["vibrato depth"].maxRawVol + 1, base64CharCodeToInt[compressed.charCodeAt(charIndex++)]) / 25;
35493549
instrument.vibratoSpeed = clamp(0, Config.modulators.dictionary["vibrato speed"].maxRawVol + 1, base64CharCodeToInt[compressed.charCodeAt(charIndex++)]);
3550-
instrument.vibratoDelay = clamp(0, Config.modulators.dictionary["vibrato delay"].maxRawVol + 1, base64CharCodeToInt[compressed.charCodeAt(charIndex++)]);
3550+
instrument.vibratoDelay = clamp(0, Config.modulators.dictionary["vibrato delay"].maxRawVol + 1, base64CharCodeToInt[compressed.charCodeAt(charIndex++)]) / 2;
35513551
instrument.vibratoType = clamp(0, Config.vibratoTypes.length, base64CharCodeToInt[compressed.charCodeAt(charIndex++)]);
35523552
instrument.effects |= 1 << EffectType.vibrato;
35533553
}
@@ -5676,6 +5676,11 @@ class InstrumentState {
56765676
let startPoint: FilterControlPoint = eqFilterSettings.controlPoints[i];
56775677
let endPoint: FilterControlPoint = (instrument.tmpEqFilterEnd != null && instrument.tmpEqFilterEnd.controlPoints[i] != null) ? instrument.tmpEqFilterEnd.controlPoints[i] : eqFilterSettings.controlPoints[i];
56785678

5679+
// If switching dot type, do it all at once and do not try to interpolate since no valid interpolation exists.
5680+
if (startPoint.type != endPoint.type) {
5681+
startPoint = endPoint;
5682+
}
5683+
56795684
startPoint.toCoefficients(Synth.tempFilterStartCoefficients, samplesPerSecond, /*eqAllFreqsEnvelopeStart * eqFreqEnvelopeStart*/ 1.0, /*eqPeakEnvelopeStart*/ 1.0);
56805685
endPoint.toCoefficients(Synth.tempFilterEndCoefficients, samplesPerSecond, /*eqAllFreqsEnvelopeEnd * eqFreqEnvelopeEnd*/ 1.0, /*eqPeakEnvelopeEnd*/ 1.0);
56815686
if (this.eqFilters.length <= i) this.eqFilters[i] = new DynamicBiquadFilter();
@@ -8108,9 +8113,14 @@ export class Synth {
81088113
const noteFreqEnvelopeEnd: number = envelopeEnds[NoteAutomationIndex.noteFilterFreq0 + i];
81098114
const notePeakEnvelopeStart: number = envelopeStarts[NoteAutomationIndex.noteFilterGain0 + i];
81108115
const notePeakEnvelopeEnd: number = envelopeEnds[NoteAutomationIndex.noteFilterGain0 + i];
8111-
const startPoint: FilterControlPoint = noteFilterSettings.controlPoints[i];
8116+
let startPoint: FilterControlPoint = noteFilterSettings.controlPoints[i];
81128117
const endPoint: FilterControlPoint = (instrument.tmpNoteFilterEnd != null && instrument.tmpNoteFilterEnd.controlPoints[i] != null) ? instrument.tmpNoteFilterEnd.controlPoints[i] : noteFilterSettings.controlPoints[i];
81138118

8119+
// If switching dot type, do it all at once and do not try to interpolate since no valid interpolation exists.
8120+
if (startPoint.type != endPoint.type) {
8121+
startPoint = endPoint;
8122+
}
8123+
81148124
startPoint.toCoefficients(Synth.tempFilterStartCoefficients, synth.samplesPerSecond, noteAllFreqsEnvelopeStart * noteFreqEnvelopeStart, notePeakEnvelopeStart);
81158125
endPoint.toCoefficients(Synth.tempFilterEndCoefficients, synth.samplesPerSecond, noteAllFreqsEnvelopeEnd * noteFreqEnvelopeEnd, notePeakEnvelopeEnd);
81168126
if (tone.noteFilters.length <= i) tone.noteFilters[i] = new DynamicBiquadFilter();

0 commit comments

Comments
 (0)