spessasynth_core 3.26.30 → 3.26.32
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/README.md +0 -1
- package/package.json +1 -1
- package/src/midi/midi_tools/rmidi_writer.js +34 -35
- package/src/soundfont/basic_soundfont/basic_preset.js +1 -4
- package/src/soundfont/basic_soundfont/basic_sample.js +13 -3
- package/src/soundfont/basic_soundfont/basic_soundbank.js +9 -1
- package/src/soundfont/basic_soundfont/riff_chunk.js +85 -42
- package/src/soundfont/basic_soundfont/write_dls/art2.js +4 -4
- package/src/soundfont/basic_soundfont/write_dls/ins.js +14 -18
- package/src/soundfont/basic_soundfont/write_dls/lins.js +3 -6
- package/src/soundfont/basic_soundfont/write_dls/rgn2.js +8 -9
- package/src/soundfont/basic_soundfont/write_dls/wave.js +12 -35
- package/src/soundfont/basic_soundfont/write_dls/write_dls.js +18 -29
- package/src/soundfont/basic_soundfont/write_dls/wsmp.js +2 -2
- package/src/soundfont/basic_soundfont/write_dls/wvpl.js +3 -5
- package/src/soundfont/basic_soundfont/write_sf2/ibag.js +3 -11
- package/src/soundfont/basic_soundfont/write_sf2/igen.js +3 -11
- package/src/soundfont/basic_soundfont/write_sf2/imod.js +3 -11
- package/src/soundfont/basic_soundfont/write_sf2/inst.js +3 -12
- package/src/soundfont/basic_soundfont/write_sf2/pbag.js +3 -11
- package/src/soundfont/basic_soundfont/write_sf2/pgen.js +4 -11
- package/src/soundfont/basic_soundfont/write_sf2/phdr.js +3 -11
- package/src/soundfont/basic_soundfont/write_sf2/pmod.js +3 -11
- package/src/soundfont/basic_soundfont/write_sf2/sdta.js +56 -26
- package/src/soundfont/basic_soundfont/write_sf2/shdr.js +3 -11
- package/src/soundfont/basic_soundfont/write_sf2/write.js +23 -52
- package/src/soundfont/dls/dls_soundfont.js +1 -3
- package/src/soundfont/dls/read_instrument.js +7 -3
- package/src/soundfont/dls/read_region.js +11 -3
- package/src/soundfont/read_sf2/samples.js +10 -4
- package/src/soundfont/read_sf2/soundfont.js +1 -1
- package/src/utils/buffer_to_wav.js +12 -15
- package/src/utils/byte_functions/string.js +7 -2
- package/src/utils/indexed_array.js +0 -18
package/README.md
CHANGED
|
@@ -37,7 +37,6 @@ npm install --save spessasynth_core
|
|
|
37
37
|
|
|
38
38
|
### Easy Integration
|
|
39
39
|
- **Modular design:** *Easy integration into other projects (load what you need)*
|
|
40
|
-
- **[Detailed documentation:](https://github.com/spessasus/spessasynth_core/wiki/Home)** *With [examples!](https://github.com/spessasus/spessasynth_core/wiki/Getting-Started#examples)*
|
|
41
40
|
- **Flexible:** *It's not just a MIDI player!*
|
|
42
41
|
- **Easy to Use:** *Basic setup is just [two lines of code!](https://github.com/spessasus/spessasynth_core/wiki/Getting-Started#minimal-setup)*
|
|
43
42
|
- **No dependencies:** *Batteries included!*
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { IndexedByteArray } from "../../utils/indexed_array.js";
|
|
2
|
+
import { writeRIFFChunkParts, writeRIFFChunkRaw } from "../../soundfont/basic_soundfont/riff_chunk.js";
|
|
3
3
|
import { getStringBytes } from "../../utils/byte_functions/string.js";
|
|
4
4
|
import { messageTypes, midiControllers, MIDIMessage } from "../midi_message.js";
|
|
5
5
|
import { getGsOn } from "./midi_editor.js";
|
|
@@ -419,25 +419,25 @@ export function writeRMIDI(
|
|
|
419
419
|
/**
|
|
420
420
|
* @type {Uint8Array[]}
|
|
421
421
|
*/
|
|
422
|
-
const infoContent = [
|
|
422
|
+
const infoContent = [];
|
|
423
423
|
const encoder = new TextEncoder();
|
|
424
424
|
// software (SpessaSynth)
|
|
425
425
|
infoContent.push(
|
|
426
|
-
|
|
426
|
+
writeRIFFChunkRaw(RMIDINFOChunks.software, encoder.encode("SpessaSynth"), true)
|
|
427
427
|
);
|
|
428
428
|
// name
|
|
429
429
|
if (metadata.name !== undefined)
|
|
430
430
|
{
|
|
431
431
|
|
|
432
432
|
infoContent.push(
|
|
433
|
-
|
|
433
|
+
writeRIFFChunkRaw(RMIDINFOChunks.name, encoder.encode(metadata.name), true)
|
|
434
434
|
);
|
|
435
435
|
encoding = FORCED_ENCODING;
|
|
436
436
|
}
|
|
437
437
|
else
|
|
438
438
|
{
|
|
439
439
|
infoContent.push(
|
|
440
|
-
|
|
440
|
+
writeRIFFChunkRaw(RMIDINFOChunks.name, mid.rawMidiName, true)
|
|
441
441
|
);
|
|
442
442
|
}
|
|
443
443
|
// creation date
|
|
@@ -445,7 +445,7 @@ export function writeRMIDI(
|
|
|
445
445
|
{
|
|
446
446
|
encoding = FORCED_ENCODING;
|
|
447
447
|
infoContent.push(
|
|
448
|
-
|
|
448
|
+
writeRIFFChunkRaw(RMIDINFOChunks.creationDate, encoder.encode(metadata.creationDate), true)
|
|
449
449
|
);
|
|
450
450
|
}
|
|
451
451
|
else
|
|
@@ -459,7 +459,7 @@ export function writeRMIDI(
|
|
|
459
459
|
minute: "numeric"
|
|
460
460
|
});
|
|
461
461
|
infoContent.push(
|
|
462
|
-
|
|
462
|
+
writeRIFFChunkRaw(RMIDINFOChunks.creationDate, getStringBytes(today, true), true)
|
|
463
463
|
);
|
|
464
464
|
}
|
|
465
465
|
// comment
|
|
@@ -467,14 +467,14 @@ export function writeRMIDI(
|
|
|
467
467
|
{
|
|
468
468
|
encoding = FORCED_ENCODING;
|
|
469
469
|
infoContent.push(
|
|
470
|
-
|
|
470
|
+
writeRIFFChunkRaw(RMIDINFOChunks.comment, encoder.encode(metadata.comment))
|
|
471
471
|
);
|
|
472
472
|
}
|
|
473
473
|
// engineer
|
|
474
474
|
if (metadata.engineer !== undefined)
|
|
475
475
|
{
|
|
476
476
|
infoContent.push(
|
|
477
|
-
|
|
477
|
+
writeRIFFChunkRaw(RMIDINFOChunks.engineer, encoder.encode(metadata.engineer), true)
|
|
478
478
|
);
|
|
479
479
|
}
|
|
480
480
|
// album
|
|
@@ -483,10 +483,10 @@ export function writeRMIDI(
|
|
|
483
483
|
// note that there are two album chunks: IPRD and IALB
|
|
484
484
|
encoding = FORCED_ENCODING;
|
|
485
485
|
infoContent.push(
|
|
486
|
-
|
|
486
|
+
writeRIFFChunkRaw(RMIDINFOChunks.album, encoder.encode(metadata.album), true)
|
|
487
487
|
);
|
|
488
488
|
infoContent.push(
|
|
489
|
-
|
|
489
|
+
writeRIFFChunkRaw(RMIDINFOChunks.album2, encoder.encode(metadata.album), true)
|
|
490
490
|
);
|
|
491
491
|
}
|
|
492
492
|
// artist
|
|
@@ -494,7 +494,7 @@ export function writeRMIDI(
|
|
|
494
494
|
{
|
|
495
495
|
encoding = FORCED_ENCODING;
|
|
496
496
|
infoContent.push(
|
|
497
|
-
|
|
497
|
+
writeRIFFChunkRaw(RMIDINFOChunks.artist, encoder.encode(metadata.artist), true)
|
|
498
498
|
);
|
|
499
499
|
}
|
|
500
500
|
// genre
|
|
@@ -502,14 +502,14 @@ export function writeRMIDI(
|
|
|
502
502
|
{
|
|
503
503
|
encoding = FORCED_ENCODING;
|
|
504
504
|
infoContent.push(
|
|
505
|
-
|
|
505
|
+
writeRIFFChunkRaw(RMIDINFOChunks.genre, encoder.encode(metadata.genre), true)
|
|
506
506
|
);
|
|
507
507
|
}
|
|
508
508
|
// picture
|
|
509
509
|
if (metadata.picture !== undefined)
|
|
510
510
|
{
|
|
511
511
|
infoContent.push(
|
|
512
|
-
|
|
512
|
+
writeRIFFChunkRaw(RMIDINFOChunks.picture, new Uint8Array(metadata.picture))
|
|
513
513
|
);
|
|
514
514
|
}
|
|
515
515
|
// copyright
|
|
@@ -517,7 +517,7 @@ export function writeRMIDI(
|
|
|
517
517
|
{
|
|
518
518
|
encoding = FORCED_ENCODING;
|
|
519
519
|
infoContent.push(
|
|
520
|
-
|
|
520
|
+
writeRIFFChunkRaw(RMIDINFOChunks.copyright, encoder.encode(metadata.copyright), true)
|
|
521
521
|
);
|
|
522
522
|
}
|
|
523
523
|
else
|
|
@@ -525,43 +525,42 @@ export function writeRMIDI(
|
|
|
525
525
|
// use midi copyright if possible
|
|
526
526
|
const copyright = mid.copyright.length > 0 ? mid.copyright : DEFAULT_COPYRIGHT;
|
|
527
527
|
infoContent.push(
|
|
528
|
-
|
|
528
|
+
writeRIFFChunkRaw(RMIDINFOChunks.copyright, getStringBytes(copyright, true))
|
|
529
529
|
);
|
|
530
530
|
}
|
|
531
531
|
|
|
532
532
|
// bank offset
|
|
533
533
|
const DBNK = new IndexedByteArray(2);
|
|
534
534
|
writeLittleEndian(DBNK, bankOffset, 2);
|
|
535
|
-
infoContent.push(
|
|
535
|
+
infoContent.push(writeRIFFChunkRaw(RMIDINFOChunks.bankOffset, DBNK));
|
|
536
536
|
// midi encoding
|
|
537
537
|
if (metadata.midiEncoding !== undefined)
|
|
538
538
|
{
|
|
539
539
|
infoContent.push(
|
|
540
|
-
|
|
540
|
+
writeRIFFChunkRaw(RMIDINFOChunks.midiEncoding, encoder.encode(metadata.midiEncoding))
|
|
541
541
|
);
|
|
542
542
|
encoding = FORCED_ENCODING;
|
|
543
543
|
}
|
|
544
544
|
// encoding
|
|
545
|
-
infoContent.push(
|
|
545
|
+
infoContent.push(writeRIFFChunkRaw(RMIDINFOChunks.encoding, getStringBytes(encoding, true)));
|
|
546
546
|
|
|
547
547
|
// combine and write out
|
|
548
|
-
const infodata = combineArrays(infoContent);
|
|
549
|
-
const rmiddata = combineArrays([
|
|
550
|
-
getStringBytes("RMID"),
|
|
551
|
-
writeRIFFOddSize(
|
|
552
|
-
"data",
|
|
553
|
-
newMid
|
|
554
|
-
),
|
|
555
|
-
writeRIFFOddSize(
|
|
556
|
-
"LIST",
|
|
557
|
-
infodata
|
|
558
|
-
),
|
|
559
|
-
soundfontBinary
|
|
560
|
-
]);
|
|
561
548
|
SpessaSynthInfo("%cFinished!", consoleColors.info);
|
|
562
549
|
SpessaSynthGroupEnd();
|
|
563
|
-
return
|
|
550
|
+
return writeRIFFChunkParts(
|
|
564
551
|
"RIFF",
|
|
565
|
-
|
|
552
|
+
[
|
|
553
|
+
getStringBytes("RMID"),
|
|
554
|
+
writeRIFFChunkRaw(
|
|
555
|
+
"data",
|
|
556
|
+
newMid
|
|
557
|
+
),
|
|
558
|
+
writeRIFFChunkParts(
|
|
559
|
+
"INFO",
|
|
560
|
+
infoContent,
|
|
561
|
+
true
|
|
562
|
+
),
|
|
563
|
+
soundfontBinary
|
|
564
|
+
]
|
|
566
565
|
);
|
|
567
566
|
}
|
|
@@ -128,10 +128,7 @@ export class BasicPreset
|
|
|
128
128
|
{
|
|
129
129
|
this.getSamplesAndGenerators(key, velocity).forEach(samandgen =>
|
|
130
130
|
{
|
|
131
|
-
|
|
132
|
-
{
|
|
133
|
-
samandgen.sample.getAudioData();
|
|
134
|
-
}
|
|
131
|
+
samandgen.sample.getAudioData();
|
|
135
132
|
});
|
|
136
133
|
}
|
|
137
134
|
}
|
|
@@ -341,10 +341,20 @@ export class BasicSample
|
|
|
341
341
|
{
|
|
342
342
|
const data = this.getAudioData();
|
|
343
343
|
const data16 = new Int16Array(data.length);
|
|
344
|
-
|
|
345
|
-
for (let i = 0; i <
|
|
344
|
+
const len = data.length;
|
|
345
|
+
for (let i = 0; i < len; i++)
|
|
346
346
|
{
|
|
347
|
-
|
|
347
|
+
let sample = data[i] * 32768;
|
|
348
|
+
// Clamp for safety (do not use Math.max/Math.min here)
|
|
349
|
+
if (sample > 32767)
|
|
350
|
+
{
|
|
351
|
+
sample = 32767;
|
|
352
|
+
}
|
|
353
|
+
else if (sample < -32768)
|
|
354
|
+
{
|
|
355
|
+
sample = -32768;
|
|
356
|
+
}
|
|
357
|
+
data16[i] = sample;
|
|
348
358
|
}
|
|
349
359
|
return new IndexedByteArray(data16.buffer);
|
|
350
360
|
}
|
|
@@ -16,12 +16,20 @@ import { BasicPreset } from "./basic_preset.js";
|
|
|
16
16
|
import { isXGDrums } from "../../utils/xg_hacks.js";
|
|
17
17
|
import { generatorTypes } from "./generator_types.js";
|
|
18
18
|
import { BasicGlobalZone } from "./basic_global_zone.js";
|
|
19
|
+
import { stbvorbis } from "../../externals/stbvorbis_sync/stbvorbis_sync.min.js";
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Represents a single sound bank, be it DLS or SF2.
|
|
22
23
|
*/
|
|
23
24
|
class BasicSoundBank
|
|
24
25
|
{
|
|
26
|
+
/**
|
|
27
|
+
* Indicates if the SF3/SF2Pack decoder is ready.
|
|
28
|
+
* @type {Promise<boolean>}
|
|
29
|
+
* @static
|
|
30
|
+
*/
|
|
31
|
+
static isSF3DecoderReady = stbvorbis.isInitialized;
|
|
32
|
+
|
|
25
33
|
/**
|
|
26
34
|
* Soundfont's info stored as name: value. ifil and iver are stored as string representation of float (e.g., 2.1)
|
|
27
35
|
* @type {Object<string, string|IndexedByteArray>}
|
|
@@ -187,7 +195,7 @@ class BasicSoundBank
|
|
|
187
195
|
font.addPresets(preset);
|
|
188
196
|
|
|
189
197
|
font.soundFontInfo["ifil"] = "2.1";
|
|
190
|
-
font.soundFontInfo["isng"] = "
|
|
198
|
+
font.soundFontInfo["isng"] = "E-mu 10K2";
|
|
191
199
|
font.soundFontInfo["INAM"] = "Dummy";
|
|
192
200
|
font.flush();
|
|
193
201
|
return font.write().buffer;
|
|
@@ -4,13 +4,31 @@ import { readBytesAsString, writeStringAsBytes } from "../../utils/byte_function
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* riff_chunk.js
|
|
7
|
-
* reads a riff
|
|
7
|
+
* reads a riff chunk and stores it as a class
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
export class RiffChunk
|
|
11
11
|
{
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* The chunks FourCC code
|
|
14
|
+
* @type {string}
|
|
15
|
+
*/
|
|
16
|
+
header;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Chunk's size, in bytes
|
|
20
|
+
* @type {number}
|
|
21
|
+
*/
|
|
22
|
+
size;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Chunk's binary data
|
|
26
|
+
* @type {IndexedByteArray}
|
|
27
|
+
*/
|
|
28
|
+
chunkData;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new RIFF chunk
|
|
14
32
|
* @constructor
|
|
15
33
|
* @param header {string}
|
|
16
34
|
* @param size {number}
|
|
@@ -36,6 +54,13 @@ export function readRIFFChunk(dataArray, readData = true, forceShift = false)
|
|
|
36
54
|
let header = readBytesAsString(dataArray, 4);
|
|
37
55
|
|
|
38
56
|
let size = readLittleEndian(dataArray, 4);
|
|
57
|
+
if (header === "")
|
|
58
|
+
{
|
|
59
|
+
// safeguard against evil DLS files
|
|
60
|
+
// The test case: CrysDLS v1.23.dls
|
|
61
|
+
// https://github.com/spessasus/spessasynth_core/issues/5
|
|
62
|
+
size = 0;
|
|
63
|
+
}
|
|
39
64
|
/**
|
|
40
65
|
* @type {IndexedByteArray}
|
|
41
66
|
*/
|
|
@@ -61,75 +86,93 @@ export function readRIFFChunk(dataArray, readData = true, forceShift = false)
|
|
|
61
86
|
}
|
|
62
87
|
|
|
63
88
|
/**
|
|
64
|
-
*
|
|
65
|
-
* @param
|
|
89
|
+
* Writes a RIFF chunk correctly
|
|
90
|
+
* @param header {string} fourCC
|
|
91
|
+
* @param data {Uint8Array} chunk data
|
|
92
|
+
* @param addZeroByte {boolean} add a zero byte into the chunk size
|
|
93
|
+
* @param isList {boolean} adds "LIST" as the chunk type and writes the actual type at the start of the data
|
|
66
94
|
* @returns {IndexedByteArray}
|
|
67
95
|
*/
|
|
68
|
-
export function
|
|
96
|
+
export function writeRIFFChunkRaw(header, data, addZeroByte = false, isList = false)
|
|
69
97
|
{
|
|
70
|
-
let
|
|
71
|
-
|
|
98
|
+
let dataStartOffset = 8;
|
|
99
|
+
let headerWritten = header;
|
|
100
|
+
let dataLength = data.length;
|
|
101
|
+
if (addZeroByte)
|
|
72
102
|
{
|
|
73
|
-
|
|
103
|
+
dataLength++;
|
|
74
104
|
}
|
|
75
|
-
|
|
105
|
+
let writtenSize = dataLength;
|
|
106
|
+
if (isList)
|
|
76
107
|
{
|
|
77
|
-
|
|
108
|
+
// written header is LIST and the passed header is the first 4 bytes of chunk data
|
|
109
|
+
dataStartOffset += 4;
|
|
110
|
+
writtenSize += 4;
|
|
111
|
+
headerWritten = "LIST";
|
|
78
112
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (prepend)
|
|
113
|
+
let finalSize = dataStartOffset + dataLength;
|
|
114
|
+
if (finalSize % 2 !== 0)
|
|
82
115
|
{
|
|
83
|
-
|
|
84
|
-
|
|
116
|
+
// pad byte does not get included in the size
|
|
117
|
+
finalSize++;
|
|
85
118
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
119
|
+
|
|
120
|
+
const outArray = new IndexedByteArray(finalSize);
|
|
121
|
+
// FourCC ("RIFF", "LIST", "pdta" etc.)
|
|
122
|
+
writeStringAsBytes(outArray, headerWritten);
|
|
123
|
+
// chunk size
|
|
124
|
+
writeDword(outArray, writtenSize);
|
|
125
|
+
if (isList)
|
|
126
|
+
{
|
|
127
|
+
// list type (e.g. "INFO")
|
|
128
|
+
writeStringAsBytes(outArray, header);
|
|
129
|
+
}
|
|
130
|
+
outArray.set(data, dataStartOffset);
|
|
131
|
+
return outArray;
|
|
93
132
|
}
|
|
94
133
|
|
|
95
134
|
/**
|
|
96
|
-
*
|
|
97
|
-
* @param
|
|
98
|
-
* @param
|
|
135
|
+
* Writes RIFF chunk given binary blobs
|
|
136
|
+
* @param header {string} fourCC
|
|
137
|
+
* @param chunks {Uint8Array[]} chunk data parts, it will be combined in order
|
|
99
138
|
* @param isList {boolean} adds "LIST" as the chunk type and writes the actual type at the start of the data
|
|
100
139
|
* @returns {IndexedByteArray}
|
|
101
140
|
*/
|
|
102
|
-
export function
|
|
141
|
+
export function writeRIFFChunkParts(header, chunks, isList = false)
|
|
103
142
|
{
|
|
104
|
-
|
|
105
|
-
{
|
|
106
|
-
const tempData = new Uint8Array(data.length + 1);
|
|
107
|
-
tempData.set(data);
|
|
108
|
-
data = tempData;
|
|
109
|
-
}
|
|
110
|
-
let offset = 8;
|
|
111
|
-
let finalSize = offset + data.length;
|
|
112
|
-
let writtenSize = data.length;
|
|
113
|
-
if (finalSize % 2 !== 0)
|
|
114
|
-
{
|
|
115
|
-
finalSize++;
|
|
116
|
-
}
|
|
143
|
+
let dataOffset = 8;
|
|
117
144
|
let headerWritten = header;
|
|
145
|
+
let dataLength = chunks.reduce((len, c) => c.length + len, 0);
|
|
146
|
+
let writtenSize = dataLength;
|
|
118
147
|
if (isList)
|
|
119
148
|
{
|
|
120
|
-
|
|
149
|
+
// written header is LIST and the passed header is the first 4 bytes of chunk data
|
|
150
|
+
dataOffset += 4;
|
|
121
151
|
writtenSize += 4;
|
|
122
|
-
offset += 4;
|
|
123
152
|
headerWritten = "LIST";
|
|
124
153
|
}
|
|
154
|
+
let finalSize = dataOffset + dataLength;
|
|
155
|
+
if (finalSize % 2 !== 0)
|
|
156
|
+
{
|
|
157
|
+
// pad byte does not get included in the size
|
|
158
|
+
finalSize++;
|
|
159
|
+
}
|
|
160
|
+
|
|
125
161
|
const outArray = new IndexedByteArray(finalSize);
|
|
162
|
+
// fourCC ("RIFF", "LIST", "pdta" etc.)
|
|
126
163
|
writeStringAsBytes(outArray, headerWritten);
|
|
164
|
+
// chunk size
|
|
127
165
|
writeDword(outArray, writtenSize);
|
|
128
166
|
if (isList)
|
|
129
167
|
{
|
|
168
|
+
// list type (e.g. "INFO")
|
|
130
169
|
writeStringAsBytes(outArray, header);
|
|
131
170
|
}
|
|
132
|
-
|
|
171
|
+
chunks.forEach(c =>
|
|
172
|
+
{
|
|
173
|
+
outArray.set(c, dataOffset);
|
|
174
|
+
dataOffset += c.length;
|
|
175
|
+
});
|
|
133
176
|
return outArray;
|
|
134
177
|
}
|
|
135
178
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getDLSArticulatorFromSf2Generator, getDLSArticulatorFromSf2Modulator } from "./modulator_converter.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { writeRIFFChunkParts } from "../riff_chunk.js";
|
|
3
|
+
import { IndexedByteArray } from "../../../utils/indexed_array.js";
|
|
4
4
|
import { Generator } from "../generator.js";
|
|
5
5
|
import { writeDword } from "../../../utils/byte_functions/little_endian.js";
|
|
6
6
|
import { consoleColors } from "../../../utils/other.js";
|
|
@@ -167,8 +167,8 @@ export function writeArticulator(zone)
|
|
|
167
167
|
|
|
168
168
|
|
|
169
169
|
const out = generators.map(a => a.writeArticulator());
|
|
170
|
-
return
|
|
170
|
+
return writeRIFFChunkParts(
|
|
171
171
|
"art2",
|
|
172
|
-
|
|
172
|
+
[art2Data, ...out]
|
|
173
173
|
);
|
|
174
174
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IndexedByteArray } from "../../../utils/indexed_array.js";
|
|
2
2
|
import { combineZones } from "./combine_zones.js";
|
|
3
|
-
import {
|
|
3
|
+
import { writeRIFFChunkParts, writeRIFFChunkRaw } from "../riff_chunk.js";
|
|
4
4
|
import { writeDword } from "../../../utils/byte_functions/little_endian.js";
|
|
5
5
|
import { writeDLSRegion } from "./rgn2.js";
|
|
6
6
|
import { writeArticulator } from "./art2.js";
|
|
@@ -40,14 +40,14 @@ export function writeIns(preset)
|
|
|
40
40
|
writeDword(inshData, ulBank); // ulBank
|
|
41
41
|
writeDword(inshData, preset.program & 127); // ulInstrument
|
|
42
42
|
|
|
43
|
-
const insh =
|
|
43
|
+
const insh = writeRIFFChunkRaw(
|
|
44
44
|
"insh",
|
|
45
45
|
inshData
|
|
46
46
|
);
|
|
47
47
|
|
|
48
48
|
// write global zone
|
|
49
49
|
const art2 = writeArticulator(global);
|
|
50
|
-
let lar2 =
|
|
50
|
+
let lar2 = writeRIFFChunkRaw(
|
|
51
51
|
"lar2",
|
|
52
52
|
art2,
|
|
53
53
|
false,
|
|
@@ -55,24 +55,22 @@ export function writeIns(preset)
|
|
|
55
55
|
);
|
|
56
56
|
|
|
57
57
|
// write the region list
|
|
58
|
-
const
|
|
59
|
-
{
|
|
60
|
-
arrs.push(writeDLSRegion.apply(this, [z, global]));
|
|
61
|
-
return arrs;
|
|
62
|
-
}, []));
|
|
63
|
-
const lrgn = writeRIFFOddSize(
|
|
58
|
+
const lrgn = writeRIFFChunkParts(
|
|
64
59
|
"lrgn",
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
zones.reduce((arrs, z) =>
|
|
61
|
+
{
|
|
62
|
+
arrs.push(writeDLSRegion.apply(this, [z, global]));
|
|
63
|
+
return arrs;
|
|
64
|
+
}, []),
|
|
67
65
|
true
|
|
68
66
|
);
|
|
69
67
|
|
|
70
68
|
// writeINFO
|
|
71
|
-
const inam =
|
|
69
|
+
const inam = writeRIFFChunkRaw(
|
|
72
70
|
"INAM",
|
|
73
71
|
getStringBytes(preset.presetName, true)
|
|
74
72
|
);
|
|
75
|
-
const info =
|
|
73
|
+
const info = writeRIFFChunkRaw(
|
|
76
74
|
"INFO",
|
|
77
75
|
inam,
|
|
78
76
|
false,
|
|
@@ -80,10 +78,8 @@ export function writeIns(preset)
|
|
|
80
78
|
);
|
|
81
79
|
|
|
82
80
|
SpessaSynthGroupEnd();
|
|
83
|
-
return
|
|
84
|
-
"ins ",
|
|
85
|
-
combineArrays([insh, lrgn, lar2, info]),
|
|
86
|
-
false,
|
|
81
|
+
return writeRIFFChunkParts(
|
|
82
|
+
"ins ", [insh, lrgn, lar2, info],
|
|
87
83
|
true
|
|
88
84
|
);
|
|
89
85
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { combineArrays } from "../../../utils/indexed_array.js";
|
|
1
|
+
import { writeRIFFChunkParts } from "../riff_chunk.js";
|
|
3
2
|
import { writeIns } from "./ins.js";
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -8,11 +7,9 @@ import { writeIns } from "./ins.js";
|
|
|
8
7
|
*/
|
|
9
8
|
export function writeLins()
|
|
10
9
|
{
|
|
11
|
-
|
|
12
|
-
return writeRIFFOddSize(
|
|
10
|
+
return writeRIFFChunkParts(
|
|
13
11
|
"lins",
|
|
14
|
-
|
|
15
|
-
false,
|
|
12
|
+
this.presets.map(p => writeIns.apply(this, [p])),
|
|
16
13
|
true
|
|
17
14
|
);
|
|
18
15
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IndexedByteArray } from "../../../utils/indexed_array.js";
|
|
2
2
|
import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
|
|
3
|
-
import {
|
|
3
|
+
import { writeRIFFChunkParts, writeRIFFChunkRaw } from "../riff_chunk.js";
|
|
4
4
|
import { writeWavesample } from "./wsmp.js";
|
|
5
5
|
import { writeArticulator } from "./art2.js";
|
|
6
6
|
import { generatorTypes } from "../generator_types.js";
|
|
@@ -28,7 +28,7 @@ export function writeDLSRegion(zone, globalZone)
|
|
|
28
28
|
writeWord(rgnhData, exclusive);
|
|
29
29
|
// usLayer
|
|
30
30
|
writeWord(rgnhData, 0);
|
|
31
|
-
const rgnh =
|
|
31
|
+
const rgnh = writeRIFFChunkRaw(
|
|
32
32
|
"rgnh",
|
|
33
33
|
rgnhData
|
|
34
34
|
);
|
|
@@ -88,7 +88,7 @@ export function writeDLSRegion(zone, globalZone)
|
|
|
88
88
|
// 1 means that the first bit is on so mono/left
|
|
89
89
|
writeDword(wlnkData, 1); // ulChannel
|
|
90
90
|
writeDword(wlnkData, this.samples.indexOf(zone.sample)); // ulTableIndex
|
|
91
|
-
const wlnk =
|
|
91
|
+
const wlnk = writeRIFFChunkRaw(
|
|
92
92
|
"wlnk",
|
|
93
93
|
wlnkData
|
|
94
94
|
);
|
|
@@ -99,7 +99,7 @@ export function writeDLSRegion(zone, globalZone)
|
|
|
99
99
|
{
|
|
100
100
|
const art2 = writeArticulator(zone);
|
|
101
101
|
|
|
102
|
-
lar2 =
|
|
102
|
+
lar2 = writeRIFFChunkRaw(
|
|
103
103
|
"lar2",
|
|
104
104
|
art2,
|
|
105
105
|
false,
|
|
@@ -107,15 +107,14 @@ export function writeDLSRegion(zone, globalZone)
|
|
|
107
107
|
);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
return
|
|
110
|
+
return writeRIFFChunkParts(
|
|
111
111
|
"rgn2",
|
|
112
|
-
|
|
112
|
+
[
|
|
113
113
|
rgnh,
|
|
114
114
|
wsmp,
|
|
115
115
|
wlnk,
|
|
116
116
|
lar2
|
|
117
|
-
]
|
|
118
|
-
false,
|
|
117
|
+
],
|
|
119
118
|
true
|
|
120
119
|
);
|
|
121
120
|
}
|