spessasynth_lib 3.16.1 → 3.16.3
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/@types/index.d.ts +0 -2
- package/@types/soundfont/basic_soundfont/basic_instrument.d.ts +29 -0
- package/@types/soundfont/basic_soundfont/basic_preset.d.ts +76 -0
- package/@types/soundfont/basic_soundfont/basic_sample.d.ts +82 -0
- package/@types/soundfont/basic_soundfont/basic_soundfont.d.ts +80 -0
- package/@types/soundfont/basic_soundfont/basic_zone.d.ts +42 -0
- package/@types/soundfont/basic_soundfont/basic_zones.d.ts +18 -0
- package/@types/soundfont/{read → basic_soundfont}/riff_chunk.d.ts +2 -1
- package/@types/soundfont/basic_soundfont/write_sf2/ibag.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/igen.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/imod.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/inst.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/pbag.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/pgen.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/phdr.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/pmod.d.ts +6 -0
- package/@types/soundfont/basic_soundfont/write_sf2/sdta.d.ts +11 -0
- package/@types/soundfont/basic_soundfont/write_sf2/shdr.d.ts +8 -0
- package/@types/soundfont/{write → basic_soundfont/write_sf2}/write.d.ts +2 -2
- package/@types/soundfont/{read → read_sf2}/generators.d.ts +2 -1
- package/@types/soundfont/{read → read_sf2}/instruments.d.ts +3 -24
- package/@types/soundfont/read_sf2/presets.d.ts +28 -0
- package/@types/soundfont/read_sf2/samples.d.ts +56 -0
- package/@types/soundfont/{read → read_sf2}/zones.d.ts +11 -53
- package/@types/soundfont/soundfont.d.ts +6 -67
- package/midi_parser/midi_loader.js +1 -1
- package/midi_parser/rmidi_writer.js +11 -11
- package/midi_parser/used_keys_loaded.js +1 -1
- package/package.json +1 -1
- package/sequencer/worklet_sequencer/song_control.js +1 -1
- package/soundfont/basic_soundfont/basic_instrument.js +73 -0
- package/soundfont/{read/presets.js → basic_soundfont/basic_preset.js} +54 -87
- package/soundfont/basic_soundfont/basic_sample.js +132 -0
- package/soundfont/basic_soundfont/basic_soundfont.js +193 -0
- package/soundfont/basic_soundfont/basic_zone.js +39 -0
- package/soundfont/basic_soundfont/basic_zones.js +47 -0
- package/soundfont/{read → basic_soundfont}/riff_chunk.js +8 -1
- package/soundfont/{write → basic_soundfont/write_sf2}/ibag.js +4 -4
- package/soundfont/{write → basic_soundfont/write_sf2}/igen.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/imod.js +4 -4
- package/soundfont/{write → basic_soundfont/write_sf2}/inst.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/pbag.js +4 -4
- package/soundfont/{write → basic_soundfont/write_sf2}/pgen.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/phdr.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/pmod.js +4 -4
- package/soundfont/{write → basic_soundfont/write_sf2}/sdta.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/shdr.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/soundfont_trimmer.js +5 -5
- package/soundfont/{write → basic_soundfont/write_sf2}/write.js +8 -9
- package/soundfont/{read → read_sf2}/generators.js +2 -1
- package/soundfont/{read → read_sf2}/instruments.js +4 -63
- package/soundfont/{read → read_sf2}/modulators.js +1 -1
- package/soundfont/read_sf2/presets.js +78 -0
- package/soundfont/{read → read_sf2}/samples.js +4 -138
- package/soundfont/{read → read_sf2}/zones.js +14 -60
- package/soundfont/soundfont.js +21 -188
- package/synthetizer/worklet_processor.min.js +6 -6
- package/synthetizer/worklet_system/message_protocol/message_sending.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/data_entry.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/note_off.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/note_on.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/program_control.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/reset_controllers.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/tuning_control.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/voice_control.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/worklet_soundfont_manager/worklet_soundfont_manager.js +1 -1
- package/synthetizer/worklet_system/worklet_utilities/lowpass_filter.js +1 -1
- package/synthetizer/worklet_system/worklet_utilities/modulation_envelope.js +2 -2
- package/synthetizer/worklet_system/worklet_utilities/modulator_curves.js +1 -1
- package/synthetizer/worklet_system/worklet_utilities/volume_envelope.js +4 -4
- package/synthetizer/worklet_system/worklet_utilities/worklet_modulator.js +2 -2
- package/synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.js +1 -1
- package/synthetizer/worklet_system/worklet_utilities/worklet_voice.js +1 -1
- package/utils/buffer_to_wav.js +6 -6
- package/@types/midi_parser/used_keys_loaded.d.ts +0 -10
- package/@types/soundfont/read/presets.d.ts +0 -88
- package/@types/soundfont/read/samples.d.ts +0 -138
- package/@types/soundfont/write/ibag.d.ts +0 -6
- package/@types/soundfont/write/igen.d.ts +0 -6
- package/@types/soundfont/write/imod.d.ts +0 -6
- package/@types/soundfont/write/inst.d.ts +0 -6
- package/@types/soundfont/write/pbag.d.ts +0 -6
- package/@types/soundfont/write/pgen.d.ts +0 -6
- package/@types/soundfont/write/phdr.d.ts +0 -6
- package/@types/soundfont/write/pmod.d.ts +0 -6
- package/@types/soundfont/write/sdta.d.ts +0 -11
- package/@types/soundfont/write/shdr.d.ts +0 -8
- package/@types/soundfont/write/soundfont_trimmer.d.ts +0 -6
- /package/@types/soundfont/{read → read_sf2}/modulators.d.ts +0 -0
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* @param zonesChunk {RiffChunk}
|
|
4
4
|
* @param instrumentGenerators {Generator[]}
|
|
5
5
|
* @param instrumentModulators {Modulator[]}
|
|
6
|
-
* @param instrumentSamples {
|
|
6
|
+
* @param instrumentSamples {BasicSample[]}
|
|
7
7
|
* @returns {InstrumentZone[]}
|
|
8
8
|
*/
|
|
9
|
-
export function readInstrumentZones(zonesChunk: RiffChunk, instrumentGenerators: Generator[], instrumentModulators: Modulator[], instrumentSamples:
|
|
9
|
+
export function readInstrumentZones(zonesChunk: RiffChunk, instrumentGenerators: Generator[], instrumentModulators: Modulator[], instrumentSamples: BasicSample[]): InstrumentZone[];
|
|
10
10
|
/**
|
|
11
11
|
* Reads the given preset zone read
|
|
12
12
|
* @param zonesChunk {RiffChunk}
|
|
@@ -20,37 +20,16 @@ export function readPresetZones(zonesChunk: RiffChunk, presetGenerators: Generat
|
|
|
20
20
|
* zones.js
|
|
21
21
|
* purpose: reads instrumend and preset zones from soundfont and gets their respective samples and generators and modulators
|
|
22
22
|
*/
|
|
23
|
-
export class InstrumentZone {
|
|
23
|
+
export class InstrumentZone extends BasicInstrumentZone {
|
|
24
24
|
/**
|
|
25
25
|
* Creates a zone (instrument)
|
|
26
26
|
* @param dataArray {IndexedByteArray}
|
|
27
|
-
* @param index {number}
|
|
28
27
|
*/
|
|
29
|
-
constructor(dataArray: IndexedByteArray
|
|
28
|
+
constructor(dataArray: IndexedByteArray);
|
|
30
29
|
generatorZoneStartIndex: number;
|
|
31
30
|
modulatorZoneStartIndex: number;
|
|
32
31
|
modulatorZoneSize: number;
|
|
33
32
|
generatorZoneSize: number;
|
|
34
|
-
zoneID: number;
|
|
35
|
-
keyRange: {
|
|
36
|
-
min: number;
|
|
37
|
-
max: number;
|
|
38
|
-
};
|
|
39
|
-
velRange: {
|
|
40
|
-
min: number;
|
|
41
|
-
max: number;
|
|
42
|
-
};
|
|
43
|
-
isGlobal: boolean;
|
|
44
|
-
useCount: number;
|
|
45
|
-
/**
|
|
46
|
-
* @type {Generator[]}
|
|
47
|
-
*/
|
|
48
|
-
generators: Generator[];
|
|
49
|
-
/**
|
|
50
|
-
* @type {Modulator[]}
|
|
51
|
-
*/
|
|
52
|
-
modulators: Modulator[];
|
|
53
|
-
deleteZone(): void;
|
|
54
33
|
setZoneSize(modulatorZoneSize: any, generatorZoneSize: any): void;
|
|
55
34
|
/**
|
|
56
35
|
* grab the generators
|
|
@@ -64,10 +43,9 @@ export class InstrumentZone {
|
|
|
64
43
|
getModulators(modulators: Modulator[]): void;
|
|
65
44
|
/**
|
|
66
45
|
* Loads the zone's sample
|
|
67
|
-
* @param samples {
|
|
46
|
+
* @param samples {BasicSample[]}
|
|
68
47
|
*/
|
|
69
|
-
getSample(samples:
|
|
70
|
-
sample: LoadedSample;
|
|
48
|
+
getSample(samples: BasicSample[]): void;
|
|
71
49
|
/**
|
|
72
50
|
* Reads the keyRange of the zone
|
|
73
51
|
*/
|
|
@@ -77,37 +55,17 @@ export class InstrumentZone {
|
|
|
77
55
|
*/
|
|
78
56
|
getVelRange(): void;
|
|
79
57
|
}
|
|
80
|
-
export class PresetZone {
|
|
58
|
+
export class PresetZone extends BasicPresetZone {
|
|
81
59
|
/**
|
|
82
60
|
* Creates a zone (preset)
|
|
83
61
|
* @param dataArray {IndexedByteArray}
|
|
84
|
-
* @param index {number}
|
|
85
62
|
*/
|
|
86
|
-
constructor(dataArray: IndexedByteArray
|
|
63
|
+
constructor(dataArray: IndexedByteArray);
|
|
87
64
|
generatorZoneStartIndex: number;
|
|
88
65
|
modulatorZoneStartIndex: number;
|
|
89
66
|
modulatorZoneSize: number;
|
|
90
67
|
generatorZoneSize: number;
|
|
91
|
-
zoneID: number;
|
|
92
|
-
keyRange: {
|
|
93
|
-
min: number;
|
|
94
|
-
max: number;
|
|
95
|
-
};
|
|
96
|
-
velRange: {
|
|
97
|
-
min: number;
|
|
98
|
-
max: number;
|
|
99
|
-
};
|
|
100
|
-
isGlobal: boolean;
|
|
101
|
-
/**
|
|
102
|
-
* @type {Generator[]}
|
|
103
|
-
*/
|
|
104
|
-
generators: Generator[];
|
|
105
|
-
/**
|
|
106
|
-
* @type {Modulator[]}
|
|
107
|
-
*/
|
|
108
|
-
modulators: Modulator[];
|
|
109
68
|
setZoneSize(modulatorZoneSize: any, generatorZoneSize: any): void;
|
|
110
|
-
deleteZone(): void;
|
|
111
69
|
/**
|
|
112
70
|
* grab the generators
|
|
113
71
|
* @param generators {Generator[]}
|
|
@@ -123,7 +81,6 @@ export class PresetZone {
|
|
|
123
81
|
* @param instruments {Instrument[]}
|
|
124
82
|
*/
|
|
125
83
|
getInstrument(instruments: Instrument[]): void;
|
|
126
|
-
instrument: Instrument;
|
|
127
84
|
/**
|
|
128
85
|
* Reads the keyRange of the zone
|
|
129
86
|
*/
|
|
@@ -133,9 +90,10 @@ export class PresetZone {
|
|
|
133
90
|
*/
|
|
134
91
|
getVelRange(): void;
|
|
135
92
|
}
|
|
136
|
-
import { RiffChunk } from "
|
|
93
|
+
import { RiffChunk } from "../basic_soundfont/riff_chunk.js";
|
|
137
94
|
import { Generator } from "./generators.js";
|
|
138
95
|
import { Modulator } from "./modulators.js";
|
|
139
|
-
import { LoadedSample } from "./samples.js";
|
|
140
96
|
import { Instrument } from "./instruments.js";
|
|
97
|
+
import { BasicInstrumentZone } from '../basic_soundfont/basic_zones.js';
|
|
141
98
|
import { IndexedByteArray } from "../../utils/indexed_array.js";
|
|
99
|
+
import { BasicPresetZone } from '../basic_soundfont/basic_zones.js';
|
|
@@ -2,48 +2,15 @@
|
|
|
2
2
|
* soundfont.js
|
|
3
3
|
* purpose: parses a soundfont2 file
|
|
4
4
|
*/
|
|
5
|
-
export class SoundFont2 {
|
|
6
|
-
/**
|
|
7
|
-
* Merges soundfonts with the given order. Keep in mind that the info read is copied from the first one
|
|
8
|
-
* @param soundfonts {...SoundFont2} the soundfonts to merge, the first overwrites the last
|
|
9
|
-
* @returns {SoundFont2}
|
|
10
|
-
*/
|
|
11
|
-
static mergeSoundfonts(...soundfonts: SoundFont2[]): SoundFont2;
|
|
5
|
+
export class SoundFont2 extends BasicSoundFont {
|
|
12
6
|
/**
|
|
13
7
|
* Initializes a new SoundFont2 Parser and parses the given data array
|
|
14
|
-
* @param arrayBuffer {ArrayBuffer
|
|
8
|
+
* @param arrayBuffer {ArrayBuffer}
|
|
15
9
|
*/
|
|
16
|
-
constructor(arrayBuffer: ArrayBuffer
|
|
17
|
-
presets: Preset[];
|
|
18
|
-
info: {
|
|
19
|
-
[x: string]: string;
|
|
20
|
-
};
|
|
21
|
-
});
|
|
22
|
-
presets: Preset[];
|
|
23
|
-
soundFontInfo: {
|
|
24
|
-
[x: string]: string;
|
|
25
|
-
};
|
|
10
|
+
constructor(arrayBuffer: ArrayBuffer);
|
|
26
11
|
dataArray: IndexedByteArray;
|
|
27
12
|
sampleDataStartIndex: number;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* read all the instruments
|
|
31
|
-
* @type {Instrument[]}
|
|
32
|
-
*/
|
|
33
|
-
instruments: Instrument[];
|
|
34
|
-
removeUnusedElements(): void;
|
|
35
|
-
/**
|
|
36
|
-
* @param instrument {Instrument}
|
|
37
|
-
*/
|
|
38
|
-
deleteInstrument(instrument: Instrument): void;
|
|
39
|
-
/**
|
|
40
|
-
* @param sample {LoadedSample}
|
|
41
|
-
*/
|
|
42
|
-
deleteSample(sample: LoadedSample): void;
|
|
43
|
-
/**
|
|
44
|
-
* @param preset {Preset}
|
|
45
|
-
*/
|
|
46
|
-
deletePreset(preset: Preset): void;
|
|
13
|
+
instruments: import("./read_sf2/instruments.js").Instrument[];
|
|
47
14
|
/**
|
|
48
15
|
* @param chunk {RiffChunk}
|
|
49
16
|
* @param expected {string}
|
|
@@ -54,35 +21,7 @@ export class SoundFont2 {
|
|
|
54
21
|
* @param expected {string}
|
|
55
22
|
*/
|
|
56
23
|
verifyText(text: string, expected: string): void;
|
|
57
|
-
/**
|
|
58
|
-
* Get the appropriate preset, undefined if not foun d
|
|
59
|
-
* @param bankNr {number}
|
|
60
|
-
* @param presetNr {number}
|
|
61
|
-
* @return {Preset}
|
|
62
|
-
*/
|
|
63
|
-
getPresetNoFallback(bankNr: number, presetNr: number): Preset;
|
|
64
|
-
/**
|
|
65
|
-
* To avoid overlapping on multiple desfonts
|
|
66
|
-
* @param offset {number}
|
|
67
|
-
*/
|
|
68
|
-
setSampleIDOffset(offset: number): void;
|
|
69
|
-
/**
|
|
70
|
-
* Get the appropriate preset
|
|
71
|
-
* @param bankNr {number}
|
|
72
|
-
* @param presetNr {number}
|
|
73
|
-
* @returns {Preset}
|
|
74
|
-
*/
|
|
75
|
-
getPreset(bankNr: number, presetNr: number): Preset;
|
|
76
|
-
/**
|
|
77
|
-
* gets preset by name
|
|
78
|
-
* @param presetName {string}
|
|
79
|
-
* @returns {Preset}
|
|
80
|
-
*/
|
|
81
|
-
getPresetByName(presetName: string): Preset;
|
|
82
|
-
write: typeof write;
|
|
83
24
|
}
|
|
84
|
-
import {
|
|
25
|
+
import { BasicSoundFont } from './basic_soundfont/basic_soundfont.js';
|
|
85
26
|
import { IndexedByteArray } from '../utils/indexed_array.js';
|
|
86
|
-
import {
|
|
87
|
-
import { RiffChunk } from './read/riff_chunk.js';
|
|
88
|
-
import { write } from './write/write.js';
|
|
27
|
+
import { RiffChunk } from './basic_soundfont/riff_chunk.js';
|
|
@@ -2,7 +2,7 @@ import { dataBytesAmount, getChannel, messageTypes, MidiMessage } from './midi_m
|
|
|
2
2
|
import { IndexedByteArray } from '../utils/indexed_array.js'
|
|
3
3
|
import { arrayToHexString, consoleColors, formatTitle } from '../utils/other.js'
|
|
4
4
|
import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd, SpessaSynthInfo } from '../utils/loggin.js'
|
|
5
|
-
import { readRIFFChunk } from '../soundfont/
|
|
5
|
+
import { readRIFFChunk } from '../soundfont/basic_soundfont/riff_chunk.js'
|
|
6
6
|
import { readVariableLengthQuantity } from '../utils/byte_functions/variable_length_quantity.js'
|
|
7
7
|
import { readBytesAsUintBigEndian } from '../utils/byte_functions/big_endian.js'
|
|
8
8
|
import { readBytesAsString } from '../utils/byte_functions/string.js'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { combineArrays, IndexedByteArray } from '../utils/indexed_array.js'
|
|
2
2
|
import { writeMIDIFile } from './midi_writer.js'
|
|
3
|
-
import { writeRIFFOddSize } from '../soundfont/
|
|
3
|
+
import { writeRIFFOddSize } from '../soundfont/basic_soundfont/riff_chunk.js'
|
|
4
4
|
import { getStringBytes } from '../utils/byte_functions/string.js'
|
|
5
5
|
import { messageTypes, midiControllers, MidiMessage } from './midi_message.js'
|
|
6
6
|
import { DEFAULT_PERCUSSION } from '../synthetizer/synthetizer.js'
|
|
@@ -340,21 +340,21 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
|
|
|
340
340
|
const encoder = new TextEncoder();
|
|
341
341
|
// software
|
|
342
342
|
infoContent.push(
|
|
343
|
-
writeRIFFOddSize(RMIDINFOChunks.software, encoder.encode("SpessaSynth"))
|
|
343
|
+
writeRIFFOddSize(RMIDINFOChunks.software, encoder.encode("SpessaSynth"), true)
|
|
344
344
|
);
|
|
345
345
|
// name
|
|
346
346
|
if(metadata.name !== undefined)
|
|
347
347
|
{
|
|
348
348
|
|
|
349
349
|
infoContent.push(
|
|
350
|
-
writeRIFFOddSize(RMIDINFOChunks.name, encoder.encode(metadata.name))
|
|
350
|
+
writeRIFFOddSize(RMIDINFOChunks.name, encoder.encode(metadata.name), true)
|
|
351
351
|
);
|
|
352
352
|
encoding = FORCED_ENCODING;
|
|
353
353
|
}
|
|
354
354
|
else
|
|
355
355
|
{
|
|
356
356
|
infoContent.push(
|
|
357
|
-
writeRIFFOddSize(RMIDINFOChunks.name, mid.rawMidiName)
|
|
357
|
+
writeRIFFOddSize(RMIDINFOChunks.name, mid.rawMidiName, true)
|
|
358
358
|
);
|
|
359
359
|
}
|
|
360
360
|
// creation date
|
|
@@ -362,7 +362,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
|
|
|
362
362
|
{
|
|
363
363
|
encoding = FORCED_ENCODING;
|
|
364
364
|
infoContent.push(
|
|
365
|
-
writeRIFFOddSize(RMIDINFOChunks.creationDate, encoder.encode(metadata.creationDate))
|
|
365
|
+
writeRIFFOddSize(RMIDINFOChunks.creationDate, encoder.encode(metadata.creationDate), true)
|
|
366
366
|
);
|
|
367
367
|
}
|
|
368
368
|
else
|
|
@@ -376,7 +376,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
|
|
|
376
376
|
minute: "numeric"
|
|
377
377
|
});
|
|
378
378
|
infoContent.push(
|
|
379
|
-
writeRIFFOddSize(RMIDINFOChunks.creationDate, getStringBytes(today))
|
|
379
|
+
writeRIFFOddSize(RMIDINFOChunks.creationDate, getStringBytes(today), true)
|
|
380
380
|
);
|
|
381
381
|
}
|
|
382
382
|
// comment
|
|
@@ -391,7 +391,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
|
|
|
391
391
|
if(metadata.engineer !== undefined)
|
|
392
392
|
{
|
|
393
393
|
infoContent.push(
|
|
394
|
-
writeRIFFOddSize(RMIDINFOChunks.engineer, encoder.encode(metadata.engineer))
|
|
394
|
+
writeRIFFOddSize(RMIDINFOChunks.engineer, encoder.encode(metadata.engineer), true)
|
|
395
395
|
)
|
|
396
396
|
}
|
|
397
397
|
// album
|
|
@@ -399,7 +399,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
|
|
|
399
399
|
{
|
|
400
400
|
encoding = FORCED_ENCODING;
|
|
401
401
|
infoContent.push(
|
|
402
|
-
writeRIFFOddSize(RMIDINFOChunks.album, encoder.encode(metadata.album))
|
|
402
|
+
writeRIFFOddSize(RMIDINFOChunks.album, encoder.encode(metadata.album), true)
|
|
403
403
|
);
|
|
404
404
|
}
|
|
405
405
|
// artist
|
|
@@ -407,7 +407,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
|
|
|
407
407
|
{
|
|
408
408
|
encoding = FORCED_ENCODING;
|
|
409
409
|
infoContent.push(
|
|
410
|
-
writeRIFFOddSize(RMIDINFOChunks.artist, encoder.encode(metadata.artist))
|
|
410
|
+
writeRIFFOddSize(RMIDINFOChunks.artist, encoder.encode(metadata.artist), true)
|
|
411
411
|
);
|
|
412
412
|
}
|
|
413
413
|
// genre
|
|
@@ -415,7 +415,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
|
|
|
415
415
|
{
|
|
416
416
|
encoding = FORCED_ENCODING;
|
|
417
417
|
infoContent.push(
|
|
418
|
-
writeRIFFOddSize(RMIDINFOChunks.genre, encoder.encode(metadata.genre))
|
|
418
|
+
writeRIFFOddSize(RMIDINFOChunks.genre, encoder.encode(metadata.genre), true)
|
|
419
419
|
);
|
|
420
420
|
}
|
|
421
421
|
// picture
|
|
@@ -430,7 +430,7 @@ export function writeRMIDI(soundfontBinary, mid, soundfont, bankOffset = 0, enco
|
|
|
430
430
|
{
|
|
431
431
|
encoding = FORCED_ENCODING;
|
|
432
432
|
infoContent.push(
|
|
433
|
-
writeRIFFOddSize(RMIDINFOChunks.copyright, encoder.encode(metadata.copyright))
|
|
433
|
+
writeRIFFOddSize(RMIDINFOChunks.copyright, encoder.encode(metadata.copyright), true)
|
|
434
434
|
);
|
|
435
435
|
}
|
|
436
436
|
else
|
|
@@ -5,7 +5,7 @@ import { messageTypes, midiControllers } from './midi_message.js'
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @param mid {MIDI}
|
|
8
|
-
* @param soundfont {{getPreset: function(number, number):
|
|
8
|
+
* @param soundfont {{getPreset: function(number, number): BasicPreset}}
|
|
9
9
|
* @returns {Object<string, Set<string>>}
|
|
10
10
|
*/
|
|
11
11
|
export function getUsedProgramsAndKeys(mid, soundfont)
|
package/package.json
CHANGED
|
@@ -68,7 +68,7 @@ export function loadNewSequence(parsedMidi)
|
|
|
68
68
|
if(this.synth.overrideSoundfont)
|
|
69
69
|
{
|
|
70
70
|
// clean up the embedded soundfont
|
|
71
|
-
this.synth.clearSoundFont();
|
|
71
|
+
this.synth.clearSoundFont(true, true);
|
|
72
72
|
}
|
|
73
73
|
SpessaSynthGroupCollapsed("%cPreloading samples...", consoleColors.info);
|
|
74
74
|
// smart preloading: load only samples used in the midi!
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export class BasicInstrument
|
|
2
|
+
{
|
|
3
|
+
constructor()
|
|
4
|
+
{
|
|
5
|
+
/**
|
|
6
|
+
* The instrument's name
|
|
7
|
+
* @type {string}
|
|
8
|
+
*/
|
|
9
|
+
this.instrumentName = "";
|
|
10
|
+
/**
|
|
11
|
+
* The instrument's zones
|
|
12
|
+
* @type {BasicInstrumentZone[]}
|
|
13
|
+
*/
|
|
14
|
+
this.instrumentZones = [];
|
|
15
|
+
this._useCount = 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
addUseCount()
|
|
19
|
+
{
|
|
20
|
+
this._useCount++;
|
|
21
|
+
this.instrumentZones.forEach(z => z.useCount++);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
removeUseCount()
|
|
25
|
+
{
|
|
26
|
+
this._useCount--;
|
|
27
|
+
for(let i = 0; i < this.instrumentZones.length; i++)
|
|
28
|
+
{
|
|
29
|
+
if(this.safeDeleteZone(i))
|
|
30
|
+
{
|
|
31
|
+
i--;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @returns {number}
|
|
38
|
+
*/
|
|
39
|
+
get useCount()
|
|
40
|
+
{
|
|
41
|
+
return this._useCount;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
deleteInstrument()
|
|
45
|
+
{
|
|
46
|
+
this.instrumentZones.forEach(z => z.deleteZone());
|
|
47
|
+
this.instrumentZones.length = 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param index {number}
|
|
52
|
+
* @returns {boolean} is the zone has been deleted
|
|
53
|
+
*/
|
|
54
|
+
safeDeleteZone(index)
|
|
55
|
+
{
|
|
56
|
+
this.instrumentZones[index].useCount--;
|
|
57
|
+
if(this.instrumentZones[index].useCount < 1)
|
|
58
|
+
{
|
|
59
|
+
this.deleteZone(index);
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @param index {number}
|
|
67
|
+
*/
|
|
68
|
+
deleteZone(index)
|
|
69
|
+
{
|
|
70
|
+
this.instrumentZones[index].deleteZone();
|
|
71
|
+
this.instrumentZones.splice(index, 1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -1,35 +1,45 @@
|
|
|
1
|
-
import {RiffChunk} from "./riff_chunk.js";
|
|
2
|
-
import {PresetZone} from "./zones.js";
|
|
3
|
-
import {readBytesAsUintLittleEndian} from "../../utils/byte_functions/little_endian.js";
|
|
4
|
-
import {LoadedSample} from "./samples.js";
|
|
5
|
-
import { Generator, generatorTypes } from './generators.js'
|
|
6
|
-
import { defaultModulators } from './modulators.js'
|
|
7
|
-
import { readBytesAsString } from '../../utils/byte_functions/string.js'
|
|
8
|
-
|
|
9
1
|
/**
|
|
10
|
-
*
|
|
2
|
+
* @typedef {{
|
|
3
|
+
* instrumentGenerators: Generator[],
|
|
4
|
+
* presetGenerators: Generator[],
|
|
5
|
+
* modulators: Modulator[],
|
|
6
|
+
* sample: BasicSample,
|
|
7
|
+
* sampleID: number,
|
|
8
|
+
* }} SampleAndGenerators
|
|
11
9
|
*/
|
|
10
|
+
import { defaultModulators } from '../read_sf2/modulators.js'
|
|
11
|
+
import { generatorTypes } from '../read_sf2/generators.js'
|
|
12
12
|
|
|
13
|
-
export class
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
* @param presetChunk {RiffChunk}
|
|
17
|
-
*/
|
|
18
|
-
constructor(presetChunk)
|
|
13
|
+
export class BasicPreset
|
|
14
|
+
{
|
|
15
|
+
constructor()
|
|
19
16
|
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
/**
|
|
18
|
+
* The preset's name
|
|
19
|
+
* @type {string}
|
|
20
|
+
*/
|
|
21
|
+
this.presetName = "";
|
|
22
|
+
/**
|
|
23
|
+
* The preset's MIDI program number
|
|
24
|
+
* @type {number}
|
|
25
|
+
*/
|
|
26
|
+
this.program = 0;
|
|
27
|
+
/**
|
|
28
|
+
* The preset's MIDI bank number
|
|
29
|
+
* @type {number}
|
|
30
|
+
*/
|
|
31
|
+
this.bank = 0;
|
|
23
32
|
|
|
24
|
-
this.program = readBytesAsUintLittleEndian(presetChunk.chunkData, 2);
|
|
25
|
-
this.bank = readBytesAsUintLittleEndian(presetChunk.chunkData, 2);
|
|
26
|
-
this.presetZoneStartIndex = readBytesAsUintLittleEndian(presetChunk.chunkData, 2);
|
|
27
|
-
this.presetZonesAmount = 0;
|
|
28
33
|
/**
|
|
29
|
-
*
|
|
34
|
+
* The preset's zones
|
|
35
|
+
* @type {BasicPresetZone[]}
|
|
30
36
|
*/
|
|
31
37
|
this.presetZones = [];
|
|
32
38
|
|
|
39
|
+
/**
|
|
40
|
+
* SampleID offset for this preset
|
|
41
|
+
* @type {number}
|
|
42
|
+
*/
|
|
33
43
|
this.sampleIDOffset = 0;
|
|
34
44
|
|
|
35
45
|
/**
|
|
@@ -42,24 +52,21 @@ export class Preset {
|
|
|
42
52
|
this.foundSamplesAndGenerators[i] = [];
|
|
43
53
|
}
|
|
44
54
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
this.presetZones.push(zones[i]);
|
|
62
|
-
}
|
|
55
|
+
/**
|
|
56
|
+
* unused metadata
|
|
57
|
+
* @type {number}
|
|
58
|
+
*/
|
|
59
|
+
this.library = 0;
|
|
60
|
+
/**
|
|
61
|
+
* unused metadata
|
|
62
|
+
* @type {number}
|
|
63
|
+
*/
|
|
64
|
+
this.genre = 0;
|
|
65
|
+
/**
|
|
66
|
+
* unused metadata
|
|
67
|
+
* @type {number}
|
|
68
|
+
*/
|
|
69
|
+
this.morphology = 0;
|
|
63
70
|
}
|
|
64
71
|
|
|
65
72
|
deletePreset()
|
|
@@ -111,16 +118,6 @@ export class Preset {
|
|
|
111
118
|
})
|
|
112
119
|
}
|
|
113
120
|
|
|
114
|
-
/**
|
|
115
|
-
* @typedef {{
|
|
116
|
-
* instrumentGenerators: Generator[],
|
|
117
|
-
* presetGenerators: Generator[],
|
|
118
|
-
* modulators: Modulator[],
|
|
119
|
-
* sample: LoadedSample,
|
|
120
|
-
* sampleID: number,
|
|
121
|
-
* }} SampleAndGenerators
|
|
122
|
-
*/
|
|
123
|
-
|
|
124
121
|
/**
|
|
125
122
|
* Returns generatorTranslator and generators for given note
|
|
126
123
|
* @param midiNote {number}
|
|
@@ -215,12 +212,12 @@ export class Preset {
|
|
|
215
212
|
.filter(currentZone =>
|
|
216
213
|
(
|
|
217
214
|
isInRange(currentZone.keyRange.min,
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
215
|
+
currentZone.keyRange.max,
|
|
216
|
+
midiNote)
|
|
217
|
+
&&
|
|
218
|
+
isInRange(currentZone.velRange.min,
|
|
219
|
+
currentZone.velRange.max,
|
|
220
|
+
velocity)
|
|
224
221
|
) && !currentZone.isGlobal
|
|
225
222
|
);
|
|
226
223
|
|
|
@@ -278,34 +275,4 @@ export class Preset {
|
|
|
278
275
|
this.foundSamplesAndGenerators[midiNote][velocity] = parsedGeneratorsAndSamples;
|
|
279
276
|
return parsedGeneratorsAndSamples;
|
|
280
277
|
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Reads the presets
|
|
285
|
-
* @param presetChunk {RiffChunk}
|
|
286
|
-
* @param presetZones {PresetZone[]}
|
|
287
|
-
* @returns {Preset[]}
|
|
288
|
-
*/
|
|
289
|
-
export function readPresets(presetChunk, presetZones)
|
|
290
|
-
{
|
|
291
|
-
/**
|
|
292
|
-
* @type {Preset[]}
|
|
293
|
-
*/
|
|
294
|
-
let presets = [];
|
|
295
|
-
while(presetChunk.chunkData.length > presetChunk.chunkData.currentIndex)
|
|
296
|
-
{
|
|
297
|
-
let preset = new Preset(presetChunk);
|
|
298
|
-
if(presets.length > 0)
|
|
299
|
-
{
|
|
300
|
-
let presetZonesAmount = preset.presetZoneStartIndex - presets[presets.length - 1].presetZoneStartIndex;
|
|
301
|
-
presets[presets.length - 1].getPresetZones(presetZonesAmount, presetZones);
|
|
302
|
-
}
|
|
303
|
-
presets.push(preset);
|
|
304
|
-
}
|
|
305
|
-
// remove EOP
|
|
306
|
-
if (presets.length > 1)
|
|
307
|
-
{
|
|
308
|
-
presets.pop();
|
|
309
|
-
}
|
|
310
|
-
return presets;
|
|
311
278
|
}
|