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.
Files changed (34) hide show
  1. package/README.md +0 -1
  2. package/package.json +1 -1
  3. package/src/midi/midi_tools/rmidi_writer.js +34 -35
  4. package/src/soundfont/basic_soundfont/basic_preset.js +1 -4
  5. package/src/soundfont/basic_soundfont/basic_sample.js +13 -3
  6. package/src/soundfont/basic_soundfont/basic_soundbank.js +9 -1
  7. package/src/soundfont/basic_soundfont/riff_chunk.js +85 -42
  8. package/src/soundfont/basic_soundfont/write_dls/art2.js +4 -4
  9. package/src/soundfont/basic_soundfont/write_dls/ins.js +14 -18
  10. package/src/soundfont/basic_soundfont/write_dls/lins.js +3 -6
  11. package/src/soundfont/basic_soundfont/write_dls/rgn2.js +8 -9
  12. package/src/soundfont/basic_soundfont/write_dls/wave.js +12 -35
  13. package/src/soundfont/basic_soundfont/write_dls/write_dls.js +18 -29
  14. package/src/soundfont/basic_soundfont/write_dls/wsmp.js +2 -2
  15. package/src/soundfont/basic_soundfont/write_dls/wvpl.js +3 -5
  16. package/src/soundfont/basic_soundfont/write_sf2/ibag.js +3 -11
  17. package/src/soundfont/basic_soundfont/write_sf2/igen.js +3 -11
  18. package/src/soundfont/basic_soundfont/write_sf2/imod.js +3 -11
  19. package/src/soundfont/basic_soundfont/write_sf2/inst.js +3 -12
  20. package/src/soundfont/basic_soundfont/write_sf2/pbag.js +3 -11
  21. package/src/soundfont/basic_soundfont/write_sf2/pgen.js +4 -11
  22. package/src/soundfont/basic_soundfont/write_sf2/phdr.js +3 -11
  23. package/src/soundfont/basic_soundfont/write_sf2/pmod.js +3 -11
  24. package/src/soundfont/basic_soundfont/write_sf2/sdta.js +56 -26
  25. package/src/soundfont/basic_soundfont/write_sf2/shdr.js +3 -11
  26. package/src/soundfont/basic_soundfont/write_sf2/write.js +23 -52
  27. package/src/soundfont/dls/dls_soundfont.js +1 -3
  28. package/src/soundfont/dls/read_instrument.js +7 -3
  29. package/src/soundfont/dls/read_region.js +11 -3
  30. package/src/soundfont/read_sf2/samples.js +10 -4
  31. package/src/soundfont/read_sf2/soundfont.js +1 -1
  32. package/src/utils/buffer_to_wav.js +12 -15
  33. package/src/utils/byte_functions/string.js +7 -2
  34. package/src/utils/indexed_array.js +0 -18
@@ -1,6 +1,6 @@
1
- import { combineArrays, IndexedByteArray } from "../../../utils/indexed_array.js";
1
+ import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
2
  import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
3
- import { writeRIFFOddSize } from "../riff_chunk.js";
3
+ import { writeRIFFChunkParts, writeRIFFChunkRaw } from "../riff_chunk.js";
4
4
  import { writeWavesample } from "./wsmp.js";
5
5
  import { SpessaSynthInfo } from "../../../utils/loggin.js";
6
6
  import { consoleColors } from "../../../utils/other.js";
@@ -19,7 +19,7 @@ export function writeDLSSample(sample)
19
19
  writeDword(fmtData, sample.sampleRate * 2); // 16-bit samples
20
20
  writeWord(fmtData, 2); // wBlockAlign
21
21
  writeWord(fmtData, 16); // wBitsPerSample
22
- const fmt = writeRIFFOddSize(
22
+ const fmt = writeRIFFChunkRaw(
23
23
  "fmt ",
24
24
  fmtData
25
25
  );
@@ -37,38 +37,16 @@ export function writeDLSSample(sample)
37
37
  sample.sampleLoopEndIndex,
38
38
  loop
39
39
  );
40
- const audio = sample.getAudioData();
41
- let data;
42
- // if sample is compressed, getRawData cannot be used
43
- if (sample.isCompressed)
44
- {
45
- const data16 = new Int16Array(audio.length);
46
-
47
- for (let i = 0; i < audio.length; i++)
48
- {
49
- // 32,767, as 32,768 may cause overflow (because vorbis can go above 1 sometimes)
50
- data16[i] = audio[i] * 32767;
51
- }
52
-
53
-
54
- data = writeRIFFOddSize(
55
- "data",
56
- new IndexedByteArray(data16.buffer)
57
- );
58
- }
59
- else
60
- {
61
- data = writeRIFFOddSize(
62
- "data",
63
- sample.getRawData(false) // no vorbis allowed
64
- );
65
- }
40
+ let data = writeRIFFChunkRaw(
41
+ "data",
42
+ sample.getRawData(false) // no vorbis allowed
43
+ );
66
44
 
67
- const inam = writeRIFFOddSize(
45
+ const inam = writeRIFFChunkRaw(
68
46
  "INAM",
69
47
  getStringBytes(sample.sampleName, true)
70
48
  );
71
- const info = writeRIFFOddSize(
49
+ const info = writeRIFFChunkRaw(
72
50
  "INFO",
73
51
  inam,
74
52
  false,
@@ -80,15 +58,14 @@ export function writeDLSSample(sample)
80
58
  consoleColors.value,
81
59
  consoleColors.recognized
82
60
  );
83
- return writeRIFFOddSize(
61
+ return writeRIFFChunkParts(
84
62
  "wave",
85
- combineArrays([
63
+ [
86
64
  fmt,
87
65
  wsmp,
88
66
  data,
89
67
  info
90
- ]),
91
- false,
68
+ ],
92
69
  true
93
70
  );
94
71
  }
@@ -1,8 +1,8 @@
1
- import { writeRIFFOddSize } from "../riff_chunk.js";
1
+ import { writeRIFFChunkParts, writeRIFFChunkRaw } from "../riff_chunk.js";
2
2
  import { writeDword } from "../../../utils/byte_functions/little_endian.js";
3
- import { combineArrays, IndexedByteArray } from "../../../utils/indexed_array.js";
3
+ import { IndexedByteArray } from "../../../utils/indexed_array.js";
4
4
  import { writeLins } from "./lins.js";
5
- import { getStringBytes, writeStringAsBytes } from "../../../utils/byte_functions/string.js";
5
+ import { getStringBytes } from "../../../utils/byte_functions/string.js";
6
6
  import { writeWavePool } from "./wvpl.js";
7
7
  import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd, SpessaSynthInfo } from "../../../utils/loggin.js";
8
8
  import { consoleColors } from "../../../utils/other.js";
@@ -21,7 +21,7 @@ export function writeDLS()
21
21
  // write colh
22
22
  const colhNum = new IndexedByteArray(4);
23
23
  writeDword(colhNum, this.presets.length);
24
- const colh = writeRIFFOddSize(
24
+ const colh = writeRIFFChunkRaw(
25
25
  "colh",
26
26
  colhNum
27
27
  );
@@ -54,7 +54,7 @@ export function writeDLS()
54
54
  {
55
55
  writeDword(ptblData, offset);
56
56
  }
57
- const ptbl = writeRIFFOddSize(
57
+ const ptbl = writeRIFFChunkRaw(
58
58
  "ptbl",
59
59
  ptblData
60
60
  );
@@ -78,42 +78,31 @@ export function writeDLS()
78
78
  continue;
79
79
  }
80
80
  infos.push(
81
- writeRIFFOddSize(
81
+ writeRIFFChunkRaw(
82
82
  info,
83
- getStringBytes(data, true),
84
- true
83
+ getStringBytes(data, true)
85
84
  )
86
85
  );
87
86
  }
88
- const info = writeRIFFOddSize(
87
+ const info = writeRIFFChunkParts(
89
88
  "INFO",
90
- combineArrays(infos),
91
- false,
89
+ infos,
92
90
  true
93
91
  );
94
-
95
- const out = new IndexedByteArray(
96
- colh.length
97
- + lins.length
98
- + ptbl.length
99
- + wvpl.length
100
- + info.length
101
- + 4);
102
- writeStringAsBytes(out, "DLS ");
103
- out.set(combineArrays([
104
- colh,
105
- lins,
106
- ptbl,
107
- wvpl,
108
- info
109
- ]), 4);
110
92
  SpessaSynthInfo(
111
93
  "%cSaved succesfully!",
112
94
  consoleColors.recognized
113
95
  );
114
96
  SpessaSynthGroupEnd();
115
- return writeRIFFOddSize(
97
+ return writeRIFFChunkParts(
116
98
  "RIFF",
117
- out
99
+ [
100
+ getStringBytes("DLS "),
101
+ colh,
102
+ lins,
103
+ ptbl,
104
+ wvpl,
105
+ info
106
+ ]
118
107
  );
119
108
  }
@@ -1,6 +1,6 @@
1
1
  import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
2
2
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
3
- import { writeRIFFOddSize } from "../riff_chunk.js";
3
+ import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
4
 
5
5
  const WSMP_SIZE = 20;
6
6
 
@@ -71,7 +71,7 @@ export function writeWavesample(
71
71
  writeDword(wsmpData, loopStart);
72
72
  writeDword(wsmpData, loopSize);
73
73
  }
74
- return writeRIFFOddSize(
74
+ return writeRIFFChunkRaw(
75
75
  "wsmp",
76
76
  wsmpData
77
77
  );
@@ -1,6 +1,5 @@
1
1
  import { writeDLSSample } from "./wave.js";
2
- import { writeRIFFOddSize } from "../riff_chunk.js";
3
- import { combineArrays } from "../../../utils/indexed_array.js";
2
+ import { writeRIFFChunkParts } from "../riff_chunk.js";
4
3
 
5
4
  /**
6
5
  * @this {BasicSoundBank}
@@ -21,10 +20,9 @@ export function writeWavePool()
21
20
  return out;
22
21
  });
23
22
  return {
24
- data: writeRIFFOddSize(
23
+ data: writeRIFFChunkParts(
25
24
  "wvpl",
26
- combineArrays(samples),
27
- false,
25
+ samples,
28
26
  true
29
27
  ),
30
28
  indexes: offsets
@@ -1,6 +1,6 @@
1
1
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
2
  import { writeWord } from "../../../utils/byte_functions/little_endian.js";
3
- import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
3
+ import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
4
 
5
5
  const BAG_SIZE = 4;
6
6
 
@@ -50,16 +50,8 @@ export function getIBAG()
50
50
  writeWord(ibagData, modulatorIndex & 0xFFFF);
51
51
  writeWord(xibagData, generatorIndex >> 16);
52
52
  writeWord(xibagData, modulatorIndex >> 16);
53
- const ibag = writeRIFFChunk(new RiffChunk(
54
- "ibag",
55
- ibagData.length,
56
- ibagData
57
- ));
58
- const xibag = writeRIFFChunk(new RiffChunk(
59
- "ibag",
60
- xibagData.length,
61
- xibagData
62
- ));
53
+ const ibag = writeRIFFChunkRaw("ibag", ibagData);
54
+ const xibag = writeRIFFChunkRaw("ibag", xibagData);
63
55
  return {
64
56
  pdta: ibag,
65
57
  xdta: xibag,
@@ -1,6 +1,6 @@
1
1
  import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
2
2
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
3
- import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
3
+ import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
4
  import { GEN_BYTE_SIZE, Generator } from "../generator.js";
5
5
  import { generatorTypes } from "../generator_types.js";
6
6
 
@@ -81,16 +81,8 @@ export function getIGEN()
81
81
  const xigenData = new IndexedByteArray(GEN_BYTE_SIZE);
82
82
  writeDword(xigenData, 0);
83
83
 
84
- const igen = writeRIFFChunk(new RiffChunk(
85
- "igen",
86
- igenData.length,
87
- igenData
88
- ));
89
- const xigen = writeRIFFChunk(new RiffChunk(
90
- "igen",
91
- xigenData.length,
92
- xigenData
93
- ));
84
+ const igen = writeRIFFChunkRaw("igen", igenData);
85
+ const xigen = writeRIFFChunkRaw("igen", xigenData);
94
86
  return {
95
87
  pdta: igen,
96
88
  xdta: xigen,
@@ -1,6 +1,6 @@
1
1
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
2
  import { writeLittleEndian, writeWord } from "../../../utils/byte_functions/little_endian.js";
3
- import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
3
+ import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
4
  import { MOD_BYTE_SIZE } from "../modulator.js";
5
5
 
6
6
  /**
@@ -52,16 +52,8 @@ export function getIMOD()
52
52
  const ximodData = new IndexedByteArray(MOD_BYTE_SIZE);
53
53
  writeLittleEndian(ximodData, 0, MOD_BYTE_SIZE);
54
54
 
55
- const imod = writeRIFFChunk(new RiffChunk(
56
- "imod",
57
- imodData.length,
58
- imodData
59
- ));
60
- const ximod = writeRIFFChunk(new RiffChunk(
61
- "imod",
62
- ximodData.length,
63
- ximodData
64
- ));
55
+ const imod = writeRIFFChunkRaw("imod", imodData);
56
+ const ximod = writeRIFFChunkRaw("imod", ximodData);
65
57
  return {
66
58
  pdta: imod,
67
59
  xdta: ximod,
@@ -1,7 +1,7 @@
1
1
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
2
  import { writeStringAsBytes } from "../../../utils/byte_functions/string.js";
3
3
  import { writeWord } from "../../../utils/byte_functions/little_endian.js";
4
- import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
+ import { writeRIFFChunkRaw } from "../riff_chunk.js";
5
5
 
6
6
  const INST_SIZE = 22;
7
7
 
@@ -31,17 +31,8 @@ export function getINST()
31
31
  writeWord(instData, instrumentStart & 0xFFFF);
32
32
  writeWord(xinstData, instrumentStart >> 16);
33
33
 
34
- const inst = writeRIFFChunk(new RiffChunk(
35
- "inst",
36
- instData.length,
37
- instData
38
- ));
39
-
40
- const xinst = writeRIFFChunk(new RiffChunk(
41
- "inst",
42
- xinstData.length,
43
- xinstData
44
- ));
34
+ const inst = writeRIFFChunkRaw("inst", instData);
35
+ const xinst = writeRIFFChunkRaw("inst", xinstData);
45
36
 
46
37
  return {
47
38
  pdta: inst,
@@ -1,6 +1,6 @@
1
1
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
2
  import { writeWord } from "../../../utils/byte_functions/little_endian.js";
3
- import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
3
+ import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
4
 
5
5
  const BAG_SIZE = 4;
6
6
 
@@ -47,16 +47,8 @@ export function getPBAG()
47
47
  writeWord(pbagData, modulatorIndex);
48
48
  writeWord(xpbagData, generatorIndex);
49
49
  writeWord(xpbagData, modulatorIndex);
50
- const pbag = writeRIFFChunk(new RiffChunk(
51
- "pbag",
52
- pbagData.length,
53
- pbagData
54
- ));
55
- const xbag = writeRIFFChunk(new RiffChunk(
56
- "pbag",
57
- xpbagData.length,
58
- xpbagData
59
- ));
50
+ const pbag = writeRIFFChunkRaw("pbag", pbagData);
51
+ const xbag = writeRIFFChunkRaw("pbag", xpbagData);
60
52
  return {
61
53
  pdta: pbag,
62
54
  xdta: xbag,
@@ -1,6 +1,6 @@
1
1
  import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
2
2
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
3
- import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
3
+ import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
4
 
5
5
  import { GEN_BYTE_SIZE, Generator } from "../generator.js";
6
6
  import { generatorTypes } from "../generator_types.js";
@@ -81,16 +81,9 @@ export function getPGEN()
81
81
  const xpgenData = new IndexedByteArray(GEN_BYTE_SIZE);
82
82
  writeDword(xpgenData, 0);
83
83
 
84
- const pgen = writeRIFFChunk(new RiffChunk(
85
- "pgen",
86
- pgenData.length,
87
- pgenData
88
- ));
89
- const xpgen = writeRIFFChunk(new RiffChunk(
90
- "pgen",
91
- xpgenData.length,
92
- xpgenData
93
- ));
84
+ const pgen = writeRIFFChunkRaw("pgen", pgenData);
85
+
86
+ const xpgen = writeRIFFChunkRaw("pgen", xpgenData);
94
87
  return {
95
88
  pdta: pgen,
96
89
  xdta: xpgen,
@@ -1,7 +1,7 @@
1
1
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
2
  import { writeStringAsBytes } from "../../../utils/byte_functions/string.js";
3
3
  import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
4
- import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
+ import { writeRIFFChunkRaw } from "../riff_chunk.js";
5
5
 
6
6
  const PHDR_SIZE = 38;
7
7
 
@@ -49,17 +49,9 @@ export function getPHDR()
49
49
  writeWord(xphdrData, presetStart >> 16);
50
50
  xphdrData.currentIndex += 12;// library, genre, morphology
51
51
 
52
- const phdr = writeRIFFChunk(new RiffChunk(
53
- "phdr",
54
- phdrData.length,
55
- phdrData
56
- ));
52
+ const phdr = writeRIFFChunkRaw("phdr", phdrData);
57
53
 
58
- const xphdr = writeRIFFChunk(new RiffChunk(
59
- "phdr",
60
- xphdrData.length,
61
- xphdrData
62
- ));
54
+ const xphdr = writeRIFFChunkRaw("phdr", xphdrData);
63
55
 
64
56
  return {
65
57
  pdta: phdr,
@@ -1,6 +1,6 @@
1
1
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
2
  import { writeLittleEndian, writeWord } from "../../../utils/byte_functions/little_endian.js";
3
- import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
3
+ import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
4
  import { MOD_BYTE_SIZE } from "../modulator.js";
5
5
 
6
6
  /**
@@ -52,16 +52,8 @@ export function getPMOD()
52
52
  const xpmodData = new IndexedByteArray(MOD_BYTE_SIZE);
53
53
  writeLittleEndian(xpmodData, 0, MOD_BYTE_SIZE);
54
54
 
55
- const pmod = writeRIFFChunk(new RiffChunk(
56
- "pmod",
57
- pmodData.length,
58
- pmodData
59
- ));
60
- const xpmod = writeRIFFChunk(new RiffChunk(
61
- "pmod",
62
- xpmodData.length,
63
- xpmodData
64
- ));
55
+ const pmod = writeRIFFChunkRaw("pmod", pmodData);
56
+ const xpmod = writeRIFFChunkRaw("pmod", xpmodData);
65
57
  return {
66
58
  pdta: pmod,
67
59
  xdta: xpmod,
@@ -1,7 +1,25 @@
1
- import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
2
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
3
1
  import { SpessaSynthInfo } from "../../../utils/loggin.js";
4
2
  import { consoleColors } from "../../../utils/other.js";
3
+ import { IndexedByteArray } from "../../../utils/indexed_array.js";
4
+ import { writeStringAsBytes } from "../../../utils/byte_functions/string.js";
5
+ import { writeLittleEndian } from "../../../utils/byte_functions/little_endian.js";
6
+
7
+ /*
8
+ Sdta structure:
9
+
10
+ LIST chunk
11
+ - "sdta" ASCII string
12
+ - smpl chunk
13
+ - - raw data
14
+ */
15
+
16
+ // in bytes, from the start of sdta-LIST to the first actual sample
17
+ const SDTA_TO_DATA_OFFSET =
18
+ 4 + // "LIST"
19
+ 4 + // sdta size
20
+ 4 + // "sdta"
21
+ 4 + // "smpl"
22
+ 4; // smpl size
5
23
 
6
24
  /**
7
25
  * @this {BasicSoundBank}
@@ -10,18 +28,20 @@ import { consoleColors } from "../../../utils/other.js";
10
28
  * @param compress {boolean}
11
29
  * @param quality {number}
12
30
  * @param vorbisFunc {EncodeVorbisFunction}
13
- * @returns {IndexedByteArray}
31
+ * @returns {Uint8Array}
14
32
  */
15
33
  export function getSDTA(smplStartOffsets, smplEndOffsets, compress, quality, vorbisFunc)
16
34
  {
17
35
  // write smpl: write int16 data of each sample linearly
18
36
  // get size (calling getAudioData twice doesn't matter since it gets cached)
37
+ let smplChunkSize = 0;
19
38
  const sampleDatas = this.samples.map((s, i) =>
20
39
  {
21
40
  if (compress)
22
41
  {
23
42
  s.compressSample(quality, vorbisFunc);
24
43
  }
44
+ // raw data: either copy s16le or encoded vorbis or encode manually if overridden
25
45
  const r = s.getRawData();
26
46
  SpessaSynthInfo(
27
47
  `%cEncoded sample %c${i}. ${s.sampleName}%c of %c${this.samples.length}%c. Compressed: %c${s.isCompressed}%c.`,
@@ -33,48 +53,58 @@ export function getSDTA(smplStartOffsets, smplEndOffsets, compress, quality, vor
33
53
  s.isCompressed ? consoleColors.recognized : consoleColors.unrecognized,
34
54
  consoleColors.info
35
55
  );
56
+ /* 6.1 Sample Data Format in the smpl Sub-chunk
57
+ Each sample is followed by a minimum of forty-six zero
58
+ valued sample data points. These zero valued data points are necessary to guarantee that any reasonable upward pitch shift
59
+ using any reasonable interpolator can loop on zero data at the end of the sound.
60
+ This doesn't apply to sf3 tho
61
+ */
62
+ smplChunkSize += r.length + (s.isCompressed ? 0 : 92); // 92 = 46 sample data points
36
63
  return r;
37
64
  });
38
- const smplSize = this.samples.reduce((total, s, i) =>
65
+
66
+ if (smplChunkSize % 2 !== 0)
39
67
  {
40
- return total + sampleDatas[i].length + 46;
41
- }, 0);
42
- const smplData = new IndexedByteArray(smplSize);
43
- // resample to int16 and write out
68
+ smplChunkSize++;
69
+ }
70
+
71
+ const sdta = new IndexedByteArray(smplChunkSize + SDTA_TO_DATA_OFFSET);
72
+
73
+ // avoid using writeRIFFChunk for performance
74
+ // sdta chunk
75
+ writeStringAsBytes(sdta, "LIST");
76
+ // "sdta" + full smpl length
77
+ writeLittleEndian(sdta, smplChunkSize + SDTA_TO_DATA_OFFSET - 8, 4);
78
+ writeStringAsBytes(sdta, "sdta");
79
+ writeStringAsBytes(sdta, "smpl");
80
+ writeLittleEndian(sdta, smplChunkSize, 4);
81
+
82
+ let offset = 0;
83
+ // write out
44
84
  this.samples.forEach((sample, i) =>
45
85
  {
46
86
  const data = sampleDatas[i];
87
+ sdta.set(data, offset + SDTA_TO_DATA_OFFSET);
47
88
  let startOffset;
48
89
  let endOffset;
49
- let jump = data.length;
50
90
  if (sample.isCompressed)
51
91
  {
52
92
  // sf3 offset is in bytes
53
- startOffset = smplData.currentIndex;
93
+ startOffset = offset;
54
94
  endOffset = startOffset + data.length;
55
95
  }
56
96
  else
57
97
  {
58
98
  // sf2 in sample data points
59
- startOffset = smplData.currentIndex / 2;
60
- endOffset = startOffset + data.length / 2;
61
- jump += 46;
99
+ startOffset = offset / 2; // inclusive
100
+ endOffset = startOffset + data.length / 2; // exclusive
101
+ offset += 92; // 46 sample data points
62
102
  }
103
+ offset += data.length;
63
104
  smplStartOffsets.push(startOffset);
64
- smplData.set(data, smplData.currentIndex);
65
- smplData.currentIndex += jump;
105
+
66
106
  smplEndOffsets.push(endOffset);
67
107
  });
68
108
 
69
- const smplChunk = writeRIFFChunk(new RiffChunk(
70
- "smpl",
71
- smplData.length,
72
- smplData
73
- ), new IndexedByteArray([115, 100, 116, 97])); // `sdta`
74
-
75
- return writeRIFFChunk(new RiffChunk(
76
- "LIST",
77
- smplChunk.length,
78
- smplChunk
79
- ));
109
+ return sdta;
80
110
  }
@@ -1,7 +1,7 @@
1
1
  import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
2
  import { writeStringAsBytes } from "../../../utils/byte_functions/string.js";
3
3
  import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
4
- import { RiffChunk, writeRIFFChunk } from "../riff_chunk.js";
4
+ import { writeRIFFChunkRaw } from "../riff_chunk.js";
5
5
  import { SF3_BIT_FLIT } from "../../read_sf2/samples.js";
6
6
 
7
7
  /**
@@ -67,16 +67,8 @@ export function getSHDR(smplStartOffsets, smplEndOffsets)
67
67
  // write EOS and zero everything else
68
68
  writeStringAsBytes(shdrData, "EOS", sampleLength);
69
69
  writeStringAsBytes(xshdrData, "EOS", sampleLength);
70
- const shdr = writeRIFFChunk(new RiffChunk(
71
- "shdr",
72
- shdrData.length,
73
- shdrData
74
- ));
75
- const xshdr = writeRIFFChunk(new RiffChunk(
76
- "shdr",
77
- xshdrData.length,
78
- xshdrData
79
- ));
70
+ const shdr = writeRIFFChunkRaw("shdr", shdrData);
71
+ const xshdr = writeRIFFChunkRaw("shdr", xshdrData);
80
72
  return {
81
73
  pdta: shdr,
82
74
  xdta: xshdr,