spessasynth_lib 3.25.12 → 3.25.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/midi_parser/basic_midi.js +30 -1
- package/midi_parser/midi_sequence.js +1 -1
- package/package.json +1 -1
- package/sequencer/default_sequencer_options.js +8 -0
- package/sequencer/sequencer.js +2 -10
- package/sequencer/worklet_sequencer/events.js +1 -1
- package/sequencer/worklet_sequencer/worklet_sequencer.js +3 -4
- package/soundfont/dls/read_instrument.js +2 -2
- package/synthetizer/synth_constants.js +1 -0
- package/synthetizer/synthetizer.js +12 -1
- package/synthetizer/worklet_processor.min.js +9 -9
- package/synthetizer/worklet_system/main_processor.js +13 -0
- package/utils/fill_with_defaults.js +21 -0
- package/utils/other.js +0 -17
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MIDISequenceData } from "./midi_sequence.js";
|
|
2
2
|
import { getStringBytes, readBytesAsString } from "../utils/byte_functions/string.js";
|
|
3
|
-
import { messageTypes } from "./midi_message.js";
|
|
3
|
+
import { messageTypes, MIDIMessage } from "./midi_message.js";
|
|
4
4
|
import { readBytesAsUintBigEndian } from "../utils/byte_functions/big_endian.js";
|
|
5
5
|
import { SpessaSynthGroup, SpessaSynthGroupEnd, SpessaSynthInfo } from "../utils/loggin.js";
|
|
6
6
|
import { consoleColors, formatTitle, sanitizeKarLyrics } from "../utils/other.js";
|
|
@@ -8,6 +8,7 @@ import { writeMIDI } from "./midi_writer.js";
|
|
|
8
8
|
import { applySnapshotToMIDI, modifyMIDI } from "./midi_editor.js";
|
|
9
9
|
import { writeRMIDI } from "./rmidi_writer.js";
|
|
10
10
|
import { getUsedProgramsAndKeys } from "./used_keys_loaded.js";
|
|
11
|
+
import { IndexedByteArray } from "../utils/indexed_array.js";
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* BasicMIDI is the base of a complete MIDI file, used by the sequencer internally.
|
|
@@ -98,6 +99,9 @@ class BasicMIDI extends MIDISequenceData
|
|
|
98
99
|
|
|
99
100
|
for (let i = 0; i < this.tracks.length; i++)
|
|
100
101
|
{
|
|
102
|
+
/**
|
|
103
|
+
* @type {MIDIMessage[]}
|
|
104
|
+
*/
|
|
101
105
|
const track = this.tracks[i];
|
|
102
106
|
const usedChannels = new Set();
|
|
103
107
|
let trackHasVoiceMessages = false;
|
|
@@ -306,6 +310,31 @@ class BasicMIDI extends MIDISequenceData
|
|
|
306
310
|
copyrightComponents.push(name);
|
|
307
311
|
}
|
|
308
312
|
}
|
|
313
|
+
|
|
314
|
+
// if the first event is not at 0 ticks, add a track name
|
|
315
|
+
// https://github.com/spessasus/SpessaSynth/issues/145
|
|
316
|
+
if (track[0].ticks > 0)
|
|
317
|
+
{
|
|
318
|
+
const name = this.trackNames[i];
|
|
319
|
+
if (name.length > 0)
|
|
320
|
+
{
|
|
321
|
+
// can copy
|
|
322
|
+
track.unshift(new MIDIMessage(
|
|
323
|
+
0,
|
|
324
|
+
messageTypes.trackName,
|
|
325
|
+
getStringBytes(name)
|
|
326
|
+
));
|
|
327
|
+
}
|
|
328
|
+
else
|
|
329
|
+
{
|
|
330
|
+
// sequence number
|
|
331
|
+
track.unshift(new MIDIMessage(
|
|
332
|
+
0,
|
|
333
|
+
messageTypes.sequenceNumber,
|
|
334
|
+
new IndexedByteArray([0x0, 0x0]) // two bytes
|
|
335
|
+
));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
309
338
|
}
|
|
310
339
|
|
|
311
340
|
// reverse the tempo changes
|
package/package.json
CHANGED
package/sequencer/sequencer.js
CHANGED
|
@@ -11,6 +11,7 @@ import { DUMMY_MIDI_DATA, MIDIData } from "../midi_parser/midi_data.js";
|
|
|
11
11
|
import { BasicMIDI } from "../midi_parser/basic_midi.js";
|
|
12
12
|
import { readBytesAsUintBigEndian } from "../utils/byte_functions/big_endian.js";
|
|
13
13
|
import { IndexedByteArray } from "../utils/indexed_array.js";
|
|
14
|
+
import { DEFAULT_SEQUENCER_OPTIONS } from "./default_sequencer_options.js";
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* sequencer.js
|
|
@@ -38,15 +39,6 @@ import { IndexedByteArray } from "../utils/indexed_array.js";
|
|
|
38
39
|
* the sequencer will stay paused when seeking or changing the playback rate
|
|
39
40
|
*/
|
|
40
41
|
|
|
41
|
-
/**
|
|
42
|
-
* @type {SequencerOptions}
|
|
43
|
-
*/
|
|
44
|
-
const DEFAULT_OPTIONS = {
|
|
45
|
-
skipToFirstNoteOn: true,
|
|
46
|
-
autoPlay: true,
|
|
47
|
-
preservePlaybackState: false
|
|
48
|
-
};
|
|
49
|
-
|
|
50
42
|
// noinspection JSUnusedGlobalSymbols
|
|
51
43
|
export class Sequencer
|
|
52
44
|
{
|
|
@@ -153,7 +145,7 @@ export class Sequencer
|
|
|
153
145
|
* @param synth {Synthetizer} synth to send events to
|
|
154
146
|
* @param options {SequencerOptions} the sequencer's options
|
|
155
147
|
*/
|
|
156
|
-
constructor(midiBinaries, synth, options =
|
|
148
|
+
constructor(midiBinaries, synth, options = DEFAULT_SEQUENCER_OPTIONS)
|
|
157
149
|
{
|
|
158
150
|
this.ignoreEvents = false;
|
|
159
151
|
this.synth = synth;
|
|
@@ -95,7 +95,7 @@ export function processMessage(messageType, messageData)
|
|
|
95
95
|
break;
|
|
96
96
|
|
|
97
97
|
case WorkletSequencerMessageType.setSkipToFirstNote:
|
|
98
|
-
this.
|
|
98
|
+
this.skipToFirstNoteOn = messageData;
|
|
99
99
|
break;
|
|
100
100
|
|
|
101
101
|
case WorkletSequencerMessageType.setPreservePlaybackState:
|
|
@@ -127,9 +127,8 @@ class WorkletSequencer
|
|
|
127
127
|
|
|
128
128
|
/**
|
|
129
129
|
* @type {boolean}
|
|
130
|
-
* @private
|
|
131
130
|
*/
|
|
132
|
-
|
|
131
|
+
skipToFirstNoteOn = true;
|
|
133
132
|
|
|
134
133
|
/**
|
|
135
134
|
* If true, seq will stay paused when seeking or changing the playback rate
|
|
@@ -178,7 +177,7 @@ class WorkletSequencer
|
|
|
178
177
|
if (time > this.duration || time < 0)
|
|
179
178
|
{
|
|
180
179
|
// time is 0
|
|
181
|
-
if (this.
|
|
180
|
+
if (this.skipToFirstNoteOn)
|
|
182
181
|
{
|
|
183
182
|
this.setTimeTicks(this.midiData.firstNoteOn - 1);
|
|
184
183
|
}
|
|
@@ -188,7 +187,7 @@ class WorkletSequencer
|
|
|
188
187
|
}
|
|
189
188
|
return;
|
|
190
189
|
}
|
|
191
|
-
if (this.
|
|
190
|
+
if (this.skipToFirstNoteOn)
|
|
192
191
|
{
|
|
193
192
|
if (time < this.firstNoteTime)
|
|
194
193
|
{
|
|
@@ -2,7 +2,7 @@ import { readBytesAsString } from "../../utils/byte_functions/string.js";
|
|
|
2
2
|
import { readLittleEndian } from "../../utils/byte_functions/little_endian.js";
|
|
3
3
|
import { DLSPreset } from "./dls_preset.js";
|
|
4
4
|
import { findRIFFListType, readRIFFChunk } from "../basic_soundfont/riff_chunk.js";
|
|
5
|
-
import {
|
|
5
|
+
import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd } from "../../utils/loggin.js";
|
|
6
6
|
import { BasicInstrumentZone } from "../basic_soundfont/basic_zones.js";
|
|
7
7
|
import { consoleColors } from "../../utils/other.js";
|
|
8
8
|
import { generatorLimits, generatorTypes } from "../basic_soundfont/generator.js";
|
|
@@ -54,7 +54,7 @@ export function readDLSInstrument(chunk)
|
|
|
54
54
|
}
|
|
55
55
|
preset.presetName = presetName;
|
|
56
56
|
preset.DLSInstrument.instrumentName = presetName;
|
|
57
|
-
|
|
57
|
+
SpessaSynthGroupCollapsed(
|
|
58
58
|
`%cParsing %c"${presetName}"%c...`,
|
|
59
59
|
consoleColors.info,
|
|
60
60
|
consoleColors.recognized,
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* @property {boolean|undefined} oneOutput - if synth should use one output with 32 channels (2 audio channels for each midi channel).
|
|
6
6
|
* this disabled chorus and reverb.
|
|
7
7
|
* @property {number|undefined} loopCount - the times to loop the song
|
|
8
|
+
* @property {SequencerOptions} sequencerOptions - the options to pass to the sequencer
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
export const WORKLET_PROCESSOR_NAME = "spessasynth-worklet-system";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IndexedByteArray } from "../utils/indexed_array.js";
|
|
2
|
-
import { consoleColors
|
|
2
|
+
import { consoleColors } from "../utils/other.js";
|
|
3
3
|
import { getEvent, messageTypes, midiControllers } from "../midi_parser/midi_message.js";
|
|
4
4
|
import { EventHandler } from "./synth_event_handler.js";
|
|
5
5
|
import { FancyChorus } from "./audio_effects/fancy_chorus.js";
|
|
@@ -23,6 +23,8 @@ import {
|
|
|
23
23
|
WORKLET_PROCESSOR_NAME
|
|
24
24
|
} from "./synth_constants.js";
|
|
25
25
|
import { BasicMIDI } from "../midi_parser/basic_midi.js";
|
|
26
|
+
import { fillWithDefaults } from "../utils/fill_with_defaults.js";
|
|
27
|
+
import { DEFAULT_SEQUENCER_OPTIONS } from "../sequencer/default_sequencer_options.js";
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
/**
|
|
@@ -150,6 +152,15 @@ export class Synthetizer
|
|
|
150
152
|
}
|
|
151
153
|
sequencerRenderingData.snapshot = snapshot;
|
|
152
154
|
}
|
|
155
|
+
if (startRenderingData?.sequencerOptions)
|
|
156
|
+
{
|
|
157
|
+
// sequencer options
|
|
158
|
+
sequencerRenderingData.sequencerOptions = fillWithDefaults(
|
|
159
|
+
startRenderingData.sequencerOptions,
|
|
160
|
+
DEFAULT_SEQUENCER_OPTIONS
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
153
164
|
sequencerRenderingData.loopCount = startRenderingData?.loopCount ?? 0;
|
|
154
165
|
}
|
|
155
166
|
|