spessasynth_core 3.27.8 → 4.0.1

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 (157) hide show
  1. package/README.md +85 -51
  2. package/dist/index.d.ts +4057 -0
  3. package/dist/index.js +17178 -0
  4. package/dist/index.js.map +1 -0
  5. package/package.json +24 -6
  6. package/index.js +0 -132
  7. package/src/externals/README.md +0 -6
  8. package/src/externals/fflate/LICENSE +0 -21
  9. package/src/externals/fflate/fflate.min.js +0 -1
  10. package/src/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +0 -12
  11. package/src/externals/stbvorbis_sync/LICENSE +0 -202
  12. package/src/externals/stbvorbis_sync/NOTICE +0 -6
  13. package/src/externals/stbvorbis_sync/stbvorbis_sync.min.js +0 -1
  14. package/src/midi/README.md +0 -32
  15. package/src/midi/basic_midi.js +0 -587
  16. package/src/midi/midi_builder.js +0 -203
  17. package/src/midi/midi_loader.js +0 -321
  18. package/src/midi/midi_message.js +0 -254
  19. package/src/midi/midi_sequence.js +0 -230
  20. package/src/midi/midi_tools/get_note_times.js +0 -154
  21. package/src/midi/midi_tools/midi_editor.js +0 -611
  22. package/src/midi/midi_tools/midi_writer.js +0 -105
  23. package/src/midi/midi_tools/rmidi_writer.js +0 -566
  24. package/src/midi/midi_tools/used_keys_loaded.js +0 -256
  25. package/src/midi/xmf_loader.js +0 -454
  26. package/src/sequencer/README.md +0 -9
  27. package/src/sequencer/events.js +0 -81
  28. package/src/sequencer/play.js +0 -362
  29. package/src/sequencer/process_event.js +0 -165
  30. package/src/sequencer/process_tick.js +0 -104
  31. package/src/sequencer/sequencer_engine.js +0 -372
  32. package/src/sequencer/song_control.js +0 -196
  33. package/src/soundfont/README.md +0 -11
  34. package/src/soundfont/basic_soundfont/basic_global_zone.js +0 -6
  35. package/src/soundfont/basic_soundfont/basic_instrument.js +0 -115
  36. package/src/soundfont/basic_soundfont/basic_instrument_zone.js +0 -45
  37. package/src/soundfont/basic_soundfont/basic_preset.js +0 -313
  38. package/src/soundfont/basic_soundfont/basic_preset_zone.js +0 -39
  39. package/src/soundfont/basic_soundfont/basic_sample.js +0 -477
  40. package/src/soundfont/basic_soundfont/basic_soundbank.js +0 -740
  41. package/src/soundfont/basic_soundfont/basic_zone.js +0 -145
  42. package/src/soundfont/basic_soundfont/generator.js +0 -76
  43. package/src/soundfont/basic_soundfont/generator_types.js +0 -151
  44. package/src/soundfont/basic_soundfont/modulator.js +0 -581
  45. package/src/soundfont/basic_soundfont/riff_chunk.js +0 -195
  46. package/src/soundfont/basic_soundfont/write_dls/art2.js +0 -174
  47. package/src/soundfont/basic_soundfont/write_dls/articulator.js +0 -49
  48. package/src/soundfont/basic_soundfont/write_dls/combine_zones.js +0 -374
  49. package/src/soundfont/basic_soundfont/write_dls/ins.js +0 -85
  50. package/src/soundfont/basic_soundfont/write_dls/lins.js +0 -15
  51. package/src/soundfont/basic_soundfont/write_dls/modulator_converter.js +0 -330
  52. package/src/soundfont/basic_soundfont/write_dls/rgn2.js +0 -120
  53. package/src/soundfont/basic_soundfont/write_dls/wave.js +0 -71
  54. package/src/soundfont/basic_soundfont/write_dls/write_dls.js +0 -124
  55. package/src/soundfont/basic_soundfont/write_dls/wsmp.js +0 -78
  56. package/src/soundfont/basic_soundfont/write_dls/wvpl.js +0 -35
  57. package/src/soundfont/basic_soundfont/write_sf2/ibag.js +0 -60
  58. package/src/soundfont/basic_soundfont/write_sf2/igen.js +0 -91
  59. package/src/soundfont/basic_soundfont/write_sf2/imod.js +0 -62
  60. package/src/soundfont/basic_soundfont/write_sf2/inst.js +0 -42
  61. package/src/soundfont/basic_soundfont/write_sf2/pbag.js +0 -57
  62. package/src/soundfont/basic_soundfont/write_sf2/pgen.js +0 -92
  63. package/src/soundfont/basic_soundfont/write_sf2/phdr.js +0 -61
  64. package/src/soundfont/basic_soundfont/write_sf2/pmod.js +0 -62
  65. package/src/soundfont/basic_soundfont/write_sf2/sdta.js +0 -131
  66. package/src/soundfont/basic_soundfont/write_sf2/shdr.js +0 -77
  67. package/src/soundfont/basic_soundfont/write_sf2/write.js +0 -287
  68. package/src/soundfont/dls/articulator_converter.js +0 -402
  69. package/src/soundfont/dls/dls_destinations.js +0 -38
  70. package/src/soundfont/dls/dls_instrument.js +0 -20
  71. package/src/soundfont/dls/dls_preset.js +0 -43
  72. package/src/soundfont/dls/dls_sample.js +0 -238
  73. package/src/soundfont/dls/dls_soundfont.js +0 -183
  74. package/src/soundfont/dls/dls_sources.js +0 -63
  75. package/src/soundfont/dls/dls_zone.js +0 -89
  76. package/src/soundfont/dls/read_articulation.js +0 -300
  77. package/src/soundfont/dls/read_instrument.js +0 -118
  78. package/src/soundfont/dls/read_instrument_list.js +0 -17
  79. package/src/soundfont/dls/read_lart.js +0 -35
  80. package/src/soundfont/dls/read_region.js +0 -157
  81. package/src/soundfont/dls/read_samples.js +0 -154
  82. package/src/soundfont/load_soundfont.js +0 -21
  83. package/src/soundfont/read_sf2/generators.js +0 -43
  84. package/src/soundfont/read_sf2/instrument_zones.js +0 -75
  85. package/src/soundfont/read_sf2/instruments.js +0 -71
  86. package/src/soundfont/read_sf2/modulators.js +0 -25
  87. package/src/soundfont/read_sf2/preset_zones.js +0 -79
  88. package/src/soundfont/read_sf2/presets.js +0 -80
  89. package/src/soundfont/read_sf2/samples.js +0 -317
  90. package/src/soundfont/read_sf2/soundfont.js +0 -452
  91. package/src/soundfont/read_sf2/zones.js +0 -28
  92. package/src/synthetizer/README.md +0 -7
  93. package/src/synthetizer/audio_engine/README.md +0 -9
  94. package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +0 -289
  95. package/src/synthetizer/audio_engine/engine_components/controller_tables.js +0 -90
  96. package/src/synthetizer/audio_engine/engine_components/dynamic_modulator_system.js +0 -95
  97. package/src/synthetizer/audio_engine/engine_components/enums.js +0 -18
  98. package/src/synthetizer/audio_engine/engine_components/key_modifier_manager.js +0 -151
  99. package/src/synthetizer/audio_engine/engine_components/lfo.js +0 -26
  100. package/src/synthetizer/audio_engine/engine_components/lowpass_filter.js +0 -282
  101. package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +0 -551
  102. package/src/synthetizer/audio_engine/engine_components/modulation_envelope.js +0 -181
  103. package/src/synthetizer/audio_engine/engine_components/modulator_curves.js +0 -89
  104. package/src/synthetizer/audio_engine/engine_components/soundfont_manager.js +0 -265
  105. package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +0 -124
  106. package/src/synthetizer/audio_engine/engine_components/unit_converter.js +0 -73
  107. package/src/synthetizer/audio_engine/engine_components/voice.js +0 -525
  108. package/src/synthetizer/audio_engine/engine_components/volume_envelope.js +0 -402
  109. package/src/synthetizer/audio_engine/engine_components/wavetable_oscillator.js +0 -274
  110. package/src/synthetizer/audio_engine/engine_methods/controller_control/controller_change.js +0 -159
  111. package/src/synthetizer/audio_engine/engine_methods/controller_control/master_parameters.js +0 -53
  112. package/src/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +0 -254
  113. package/src/synthetizer/audio_engine/engine_methods/create_midi_channel.js +0 -20
  114. package/src/synthetizer/audio_engine/engine_methods/data_entry/awe32.js +0 -198
  115. package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +0 -281
  116. package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_fine.js +0 -109
  117. package/src/synthetizer/audio_engine/engine_methods/mute_channel.js +0 -17
  118. package/src/synthetizer/audio_engine/engine_methods/note_on.js +0 -220
  119. package/src/synthetizer/audio_engine/engine_methods/portamento_time.js +0 -92
  120. package/src/synthetizer/audio_engine/engine_methods/program_change.js +0 -35
  121. package/src/synthetizer/audio_engine/engine_methods/render_voice.js +0 -214
  122. package/src/synthetizer/audio_engine/engine_methods/soundfont_management/embedded_sound_bank.js +0 -42
  123. package/src/synthetizer/audio_engine/engine_methods/soundfont_management/get_preset.js +0 -0
  124. package/src/synthetizer/audio_engine/engine_methods/soundfont_management/update_preset_list.js +0 -19
  125. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +0 -23
  126. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/note_off.js +0 -56
  127. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_channels.js +0 -16
  128. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_notes.js +0 -30
  129. package/src/synthetizer/audio_engine/engine_methods/stopping_notes/voice_killing.js +0 -63
  130. package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +0 -1058
  131. package/src/synthetizer/audio_engine/engine_methods/tuning_control/channel_pressure.js +0 -23
  132. package/src/synthetizer/audio_engine/engine_methods/tuning_control/pitch_wheel.js +0 -31
  133. package/src/synthetizer/audio_engine/engine_methods/tuning_control/poly_pressure.js +0 -29
  134. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_master_tuning.js +0 -15
  135. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_modulation_depth.js +0 -26
  136. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_octave_tuning.js +0 -19
  137. package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_tuning.js +0 -27
  138. package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_all_channels.js +0 -15
  139. package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_channel.js +0 -34
  140. package/src/synthetizer/audio_engine/main_processor.js +0 -817
  141. package/src/synthetizer/audio_engine/snapshot/apply_synthesizer_snapshot.js +0 -16
  142. package/src/synthetizer/audio_engine/snapshot/channel_snapshot.js +0 -175
  143. package/src/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js +0 -116
  144. package/src/synthetizer/audio_engine/synth_processor_options.js +0 -18
  145. package/src/synthetizer/synth_constants.js +0 -26
  146. package/src/utils/README.md +0 -8
  147. package/src/utils/buffer_to_wav.js +0 -197
  148. package/src/utils/byte_functions/big_endian.js +0 -32
  149. package/src/utils/byte_functions/little_endian.js +0 -77
  150. package/src/utils/byte_functions/string.js +0 -92
  151. package/src/utils/byte_functions/variable_length_quantity.js +0 -42
  152. package/src/utils/fill_with_defaults.js +0 -21
  153. package/src/utils/indexed_array.js +0 -34
  154. package/src/utils/loggin.js +0 -71
  155. package/src/utils/other.js +0 -92
  156. package/src/utils/sysex_detector.js +0 -58
  157. package/src/utils/xg_hacks.js +0 -193
@@ -1,78 +0,0 @@
1
- import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
2
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
3
- import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
-
5
- const WSMP_SIZE = 20;
6
-
7
- /**
8
- * @param sample {BasicSample}
9
- * @param rootKey {number}
10
- * @param tuning {number}
11
- * @param attenuationCentibels {number} CENTIBELS, NO CORRECTION
12
- * @param loopStart {number}
13
- * @param loopEnd {number}
14
- * @param loopingMode {number}
15
- * @returns {IndexedByteArray}
16
- */
17
- export function writeWavesample(
18
- sample,
19
- rootKey,
20
- tuning,
21
- attenuationCentibels,
22
- loopStart,
23
- loopEnd,
24
- loopingMode)
25
- {
26
- let loopCount = loopingMode === 0 ? 0 : 1;
27
- const wsmpData = new IndexedByteArray(WSMP_SIZE + loopCount * 16);
28
- writeDword(wsmpData, WSMP_SIZE); // cbSize
29
- // usUnityNote (apply root pitch here)
30
- writeWord(wsmpData, rootKey);
31
- // sFineTune
32
- writeWord(wsmpData, tuning);
33
-
34
- // gain correction, use InitialAttenuation, apply attenuation correction
35
- const attenuationCb = attenuationCentibels * 0.4;
36
-
37
- // gain correction: Each unit of gain represents 1/655360 dB
38
- const lGain = Math.floor(attenuationCb * -65536);
39
- writeDword(wsmpData, lGain);
40
- // fulOptions: has to be 2, according to all DLS files I have
41
- writeDword(wsmpData, 2);
42
-
43
- const loopSize = loopEnd - loopStart;
44
- let ulLoopType = 0;
45
- switch (loopingMode)
46
- {
47
- default:
48
- case 0:
49
- // no loop
50
- loopCount = 0;
51
- break;
52
-
53
- case 1:
54
- // loop
55
- ulLoopType = 0;
56
- loopCount = 1;
57
- break;
58
-
59
- case 3:
60
- // loop and release
61
- ulLoopType = 1;
62
- loopCount = 1;
63
- }
64
-
65
- // cSampleLoops
66
- writeDword(wsmpData, loopCount);
67
- if (loopCount === 1)
68
- {
69
- writeDword(wsmpData, 16); // cbSize
70
- writeDword(wsmpData, ulLoopType);
71
- writeDword(wsmpData, loopStart);
72
- writeDword(wsmpData, loopSize);
73
- }
74
- return writeRIFFChunkRaw(
75
- "wsmp",
76
- wsmpData
77
- );
78
- }
@@ -1,35 +0,0 @@
1
- import { writeDLSSample } from "./wave.js";
2
- import { writeRIFFChunkParts } from "../riff_chunk.js";
3
-
4
- /**
5
- * @this {BasicSoundBank}
6
- * @param {ProgressFunction|undefined} progressFunction
7
- * @returns {Promise<{data: IndexedByteArray, indexes: number[] }>}
8
- */
9
- export async function writeWavePool(progressFunction)
10
- {
11
- let currentIndex = 0;
12
- const offsets = [];
13
- /**
14
- * @type {IndexedByteArray[]}
15
- */
16
- const samples = [];
17
- let written = 0;
18
- for (const s of this.samples)
19
- {
20
- const out = writeDLSSample(s);
21
- await progressFunction?.(s.sampleName, written, this.samples.length);
22
- offsets.push(currentIndex);
23
- currentIndex += out.length;
24
- samples.push(out);
25
- written++;
26
- }
27
- return {
28
- data: writeRIFFChunkParts(
29
- "wvpl",
30
- samples,
31
- true
32
- ),
33
- indexes: offsets
34
- };
35
- }
@@ -1,60 +0,0 @@
1
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
- import { writeWord } from "../../../utils/byte_functions/little_endian.js";
3
- import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
-
5
- const BAG_SIZE = 4;
6
-
7
- /**
8
- * @this {BasicSoundBank}
9
- * @returns {ReturnedExtendedSf2Chunks}
10
- */
11
- export function getIBAG()
12
- {
13
- // write all ibag with their start indexes as they were changed in getIGEN() and getIMOD()
14
- const ibagSize = this.instruments.reduce(
15
- (sum, i) =>
16
- // +1 because global zone
17
- (i.instrumentZones.length + 1) * BAG_SIZE + sum,
18
- BAG_SIZE
19
- );
20
- const ibagData = new IndexedByteArray(ibagSize);
21
- // https://github.com/spessasus/soundfont-proposals/blob/main/extended_limits.md
22
- const xibagData = new IndexedByteArray(ibagSize);
23
- let generatorIndex = 0;
24
- let modulatorIndex = 0;
25
- /**
26
- * @param z {BasicZone}
27
- */
28
- const writeZone = z =>
29
- {
30
- // bottom WORD: regular ibag
31
- writeWord(ibagData, generatorIndex & 0xFFFF);
32
- writeWord(ibagData, modulatorIndex & 0xFFFF);
33
- // top WORD: extended ibag
34
- writeWord(xibagData, generatorIndex >> 16);
35
- writeWord(xibagData, modulatorIndex >> 16);
36
- generatorIndex += z.generators.length;
37
- modulatorIndex += z.modulators.length;
38
- };
39
-
40
- for (const inst of this.instruments)
41
- {
42
- writeZone(inst.globalZone);
43
- for (const ibag of inst.instrumentZones)
44
- {
45
- writeZone(ibag);
46
- }
47
- }
48
- // write the terminal IBAG
49
- writeWord(ibagData, generatorIndex & 0xFFFF);
50
- writeWord(ibagData, modulatorIndex & 0xFFFF);
51
- writeWord(xibagData, generatorIndex >> 16);
52
- writeWord(xibagData, modulatorIndex >> 16);
53
- const ibag = writeRIFFChunkRaw("ibag", ibagData);
54
- const xibag = writeRIFFChunkRaw("ibag", xibagData);
55
- return {
56
- pdta: ibag,
57
- xdta: xibag,
58
- highestIndex: Math.max(generatorIndex, modulatorIndex)
59
- };
60
- }
@@ -1,91 +0,0 @@
1
- import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
2
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
3
- import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
- import { GEN_BYTE_SIZE, Generator } from "../generator.js";
5
- import { generatorTypes } from "../generator_types.js";
6
-
7
- /**
8
- * @this {BasicSoundBank}
9
- * @returns {ReturnedExtendedSf2Chunks}
10
- */
11
- export function getIGEN()
12
- {
13
- // go through all instruments -> zones and write generators sequentially (add 4 for terminal)
14
- let igenSize = GEN_BYTE_SIZE;
15
- for (const inst of this.instruments)
16
- {
17
- igenSize += inst.globalZone.generators.length * GEN_BYTE_SIZE;
18
- igenSize += inst.instrumentZones.reduce((sum, z) =>
19
- {
20
- // clear sample and range generators before determining the size
21
- z.generators = (z.generators.filter(g =>
22
- g.generatorType !== generatorTypes.sampleID &&
23
- g.generatorType !== generatorTypes.keyRange &&
24
- g.generatorType !== generatorTypes.velRange
25
- ));
26
- // add sample and ranges if necessary
27
- // unshift vel then key (to make key first) and the sample is last
28
- if (z.hasVelRange)
29
- {
30
- z.prependGenerator(new Generator(
31
- generatorTypes.velRange,
32
- z.velRange.max << 8 | Math.max(z.velRange.min, 0),
33
- false
34
- ));
35
- }
36
- if (z.hasKeyRange)
37
- {
38
- z.prependGenerator(new Generator(
39
- generatorTypes.keyRange,
40
- z.keyRange.max << 8 | Math.max(z.keyRange.min, 0),
41
- false
42
- ));
43
- }
44
- // add sample id
45
- z.addGenerators(new Generator(
46
- generatorTypes.sampleID,
47
- this.samples.indexOf(z.sample),
48
- false
49
- ));
50
- return z.generators.length * GEN_BYTE_SIZE + sum;
51
- }, 0);
52
- }
53
- const igenData = new IndexedByteArray(igenSize);
54
-
55
- /**
56
- * @param z {BasicZone}
57
- */
58
- const writeZone = z =>
59
- {
60
- for (const gen of z.generators)
61
- {
62
- // name is deceptive, it works on negatives
63
- writeWord(igenData, gen.generatorType);
64
- writeWord(igenData, gen.generatorValue);
65
- }
66
- };
67
-
68
- for (const instrument of this.instruments)
69
- {
70
- // global zone
71
- writeZone(instrument.globalZone);
72
- for (const instrumentZone of instrument.instrumentZones)
73
- {
74
- writeZone(instrumentZone);
75
- }
76
- }
77
- // terminal generator, is zero
78
- writeDword(igenData, 0);
79
-
80
- // https://github.com/spessasus/soundfont-proposals/blob/main/extended_limits.md
81
- const xigenData = new IndexedByteArray(GEN_BYTE_SIZE);
82
- writeDword(xigenData, 0);
83
-
84
- const igen = writeRIFFChunkRaw("igen", igenData);
85
- const xigen = writeRIFFChunkRaw("igen", xigenData);
86
- return {
87
- pdta: igen,
88
- xdta: xigen,
89
- highestIndex: 0 // not applicable
90
- };
91
- }
@@ -1,62 +0,0 @@
1
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
- import { writeLittleEndian, writeWord } from "../../../utils/byte_functions/little_endian.js";
3
- import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
- import { MOD_BYTE_SIZE } from "../modulator.js";
5
-
6
- /**
7
- * @this {BasicSoundBank}
8
- * @returns {ReturnedExtendedSf2Chunks}
9
- */
10
- export function getIMOD()
11
- {
12
- // very similar to igen,
13
- // go through all instruments -> zones and write modulators sequentially
14
- let imodSize = MOD_BYTE_SIZE; // terminal
15
- for (const inst of this.instruments)
16
- {
17
- imodSize += inst.globalZone.modulators.length * MOD_BYTE_SIZE;
18
- // start with one mod for global
19
- imodSize += inst.instrumentZones.reduce((sum, z) => z.modulators.length * MOD_BYTE_SIZE + sum, 0);
20
- }
21
- const imodData = new IndexedByteArray(imodSize);
22
-
23
- /**
24
- * @param z {BasicZone}
25
- */
26
- const writeZone = z =>
27
- {
28
- for (const mod of z.modulators)
29
- {
30
- writeWord(imodData, mod.getSourceEnum());
31
- writeWord(imodData, mod.modulatorDestination);
32
- writeWord(imodData, mod.transformAmount);
33
- writeWord(imodData, mod.getSecSrcEnum());
34
- writeWord(imodData, mod.transformType);
35
- }
36
- };
37
-
38
- for (const inst of this.instruments)
39
- {
40
- // global
41
- writeZone(inst.globalZone);
42
- for (const instrumentZone of inst.instrumentZones)
43
- {
44
- writeZone(instrumentZone);
45
- }
46
- }
47
-
48
- // terminal modulator, is zero
49
- writeLittleEndian(imodData, 0, MOD_BYTE_SIZE);
50
-
51
- // https://github.com/spessasus/soundfont-proposals/blob/main/extended_limits.md
52
- const ximodData = new IndexedByteArray(MOD_BYTE_SIZE);
53
- writeLittleEndian(ximodData, 0, MOD_BYTE_SIZE);
54
-
55
- const imod = writeRIFFChunkRaw("imod", imodData);
56
- const ximod = writeRIFFChunkRaw("imod", ximodData);
57
- return {
58
- pdta: imod,
59
- xdta: ximod,
60
- highestIndex: 0 // not applicable
61
- };
62
- }
@@ -1,42 +0,0 @@
1
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
- import { writeStringAsBytes } from "../../../utils/byte_functions/string.js";
3
- import { writeWord } from "../../../utils/byte_functions/little_endian.js";
4
- import { writeRIFFChunkRaw } from "../riff_chunk.js";
5
-
6
- const INST_SIZE = 22;
7
-
8
- /**
9
- * @this {BasicSoundBank}
10
- * @returns {ReturnedExtendedSf2Chunks}
11
- */
12
- export function getINST()
13
- {
14
- const instSize = this.instruments.length * INST_SIZE + INST_SIZE;
15
- const instData = new IndexedByteArray(instSize);
16
- // https://github.com/spessasus/soundfont-proposals/blob/main/extended_limits.md
17
- const xinstData = new IndexedByteArray(instSize);
18
- // the instrument start index is adjusted in ibag, write it here
19
- let instrumentStart = 0;
20
- for (const inst of this.instruments)
21
- {
22
- writeStringAsBytes(instData, inst.instrumentName.substring(0, 20), 20);
23
- writeStringAsBytes(xinstData, inst.instrumentName.substring(20), 20);
24
- writeWord(instData, instrumentStart & 0xFFFF);
25
- writeWord(xinstData, instrumentStart >> 16);
26
- instrumentStart += inst.instrumentZones.length + 1; // global
27
- }
28
- // write EOI
29
- writeStringAsBytes(instData, "EOI", 20);
30
- writeStringAsBytes(xinstData, "EOI", 20);
31
- writeWord(instData, instrumentStart & 0xFFFF);
32
- writeWord(xinstData, instrumentStart >> 16);
33
-
34
- const inst = writeRIFFChunkRaw("inst", instData);
35
- const xinst = writeRIFFChunkRaw("inst", xinstData);
36
-
37
- return {
38
- pdta: inst,
39
- xdta: xinst,
40
- highestIndex: instrumentStart
41
- };
42
- }
@@ -1,57 +0,0 @@
1
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
- import { writeWord } from "../../../utils/byte_functions/little_endian.js";
3
- import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
-
5
- const BAG_SIZE = 4;
6
-
7
- /**
8
- * @this {BasicSoundBank}
9
- * @returns {ReturnedExtendedSf2Chunks}
10
- */
11
- export function getPBAG()
12
- {
13
- // write all pbag with their start indexes as they were changed in getPGEN() and getPMOD()
14
- const pbagSize = this.presets.reduce((sum, i) =>
15
- // +1 because global zone
16
- (i.presetZones.length + 1) * BAG_SIZE + sum, BAG_SIZE);
17
- const pbagData = new IndexedByteArray(pbagSize);
18
- // https://github.com/spessasus/soundfont-proposals/blob/main/extended_limits.md
19
- const xpbagData = new IndexedByteArray(pbagSize);
20
- let generatorIndex = 0;
21
- let modulatorIndex = 0;
22
-
23
- /**
24
- * @param z {BasicZone}
25
- */
26
- const writeZone = z =>
27
- {
28
- writeWord(pbagData, generatorIndex & 0xFFFF);
29
- writeWord(pbagData, modulatorIndex & 0xFFFF);
30
- writeWord(xpbagData, generatorIndex >> 16);
31
- writeWord(xpbagData, modulatorIndex >> 16);
32
- generatorIndex += z.generators.length;
33
- modulatorIndex += z.modulators.length;
34
- };
35
-
36
- for (const preset of this.presets)
37
- {
38
- // global
39
- writeZone(preset.globalZone);
40
- for (const pbag of preset.presetZones)
41
- {
42
- writeZone(pbag);
43
- }
44
- }
45
- // write the terminal PBAG
46
- writeWord(pbagData, generatorIndex);
47
- writeWord(pbagData, modulatorIndex);
48
- writeWord(xpbagData, generatorIndex);
49
- writeWord(xpbagData, modulatorIndex);
50
- const pbag = writeRIFFChunkRaw("pbag", pbagData);
51
- const xbag = writeRIFFChunkRaw("pbag", xpbagData);
52
- return {
53
- pdta: pbag,
54
- xdta: xbag,
55
- highestIndex: Math.max(generatorIndex, modulatorIndex)
56
- };
57
- }
@@ -1,92 +0,0 @@
1
- import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
2
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
3
- import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
-
5
- import { GEN_BYTE_SIZE, Generator } from "../generator.js";
6
- import { generatorTypes } from "../generator_types.js";
7
-
8
- /**
9
- * @this {BasicSoundBank}
10
- * @returns {ReturnedExtendedSf2Chunks}
11
- */
12
- export function getPGEN()
13
- {
14
- // almost identical to igen, except the correct instrument instead of sample gen
15
- // goes through all preset zones and writes generators sequentially (add 4 for terminal)
16
- let pgenSize = GEN_BYTE_SIZE;
17
- for (const preset of this.presets)
18
- {
19
- pgenSize += preset.globalZone.generators.length * GEN_BYTE_SIZE;
20
- pgenSize += preset.presetZones.reduce((size, z) =>
21
- {
22
- // clear instrument and range generators before determining the size
23
- z.generators = z.generators.filter(g =>
24
- g.generatorType !== generatorTypes.instrument &&
25
- g.generatorType !== generatorTypes.keyRange &&
26
- g.generatorType !== generatorTypes.velRange
27
- );
28
- // unshift vel then key and instrument is last
29
- if (z.hasVelRange)
30
- {
31
- z.prependGenerator(new Generator(
32
- generatorTypes.velRange,
33
- z.velRange.max << 8 | Math.max(z.velRange.min, 0),
34
- false
35
- ));
36
- }
37
- if (z.hasKeyRange)
38
- {
39
- z.prependGenerator(new Generator(
40
- generatorTypes.keyRange,
41
- z.keyRange.max << 8 | Math.max(z.keyRange.min, 0),
42
- false
43
- ));
44
- }
45
- // write the instrument id
46
- z.addGenerators(new Generator(
47
- generatorTypes.instrument,
48
- this.instruments.indexOf(z.instrument),
49
- false
50
- ));
51
- return z.generators.length * GEN_BYTE_SIZE + size;
52
- }, 0);
53
- }
54
- const pgenData = new IndexedByteArray(pgenSize);
55
-
56
- /**
57
- * @param z {BasicZone}
58
- */
59
- const writeZone = z =>
60
- {
61
- for (const gen of z.generators)
62
- {
63
- // name is deceptive, it works on negatives
64
- writeWord(pgenData, gen.generatorType);
65
- writeWord(pgenData, gen.generatorValue);
66
- }
67
- };
68
- for (const preset of this.presets)
69
- {
70
- // global zone
71
- writeZone(preset.globalZone);
72
- for (const zone of preset.presetZones)
73
- {
74
- writeZone(zone);
75
- }
76
- }
77
- // terminal generator, is zero
78
- writeDword(pgenData, 0);
79
-
80
- // https://github.com/spessasus/soundfont-proposals/blob/main/extended_limits.md
81
- const xpgenData = new IndexedByteArray(GEN_BYTE_SIZE);
82
- writeDword(xpgenData, 0);
83
-
84
- const pgen = writeRIFFChunkRaw("pgen", pgenData);
85
-
86
- const xpgen = writeRIFFChunkRaw("pgen", xpgenData);
87
- return {
88
- pdta: pgen,
89
- xdta: xpgen,
90
- highestIndex: 0 // not applicable
91
- };
92
- }
@@ -1,61 +0,0 @@
1
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
- import { writeStringAsBytes } from "../../../utils/byte_functions/string.js";
3
- import { writeDword, writeWord } from "../../../utils/byte_functions/little_endian.js";
4
- import { writeRIFFChunkRaw } from "../riff_chunk.js";
5
-
6
- const PHDR_SIZE = 38;
7
-
8
- /**
9
- * @this {BasicSoundBank}
10
- * @returns {ReturnedExtendedSf2Chunks}
11
- */
12
- export function getPHDR()
13
- {
14
- const phdrSize = this.presets.length * PHDR_SIZE + PHDR_SIZE;
15
- const phdrData = new IndexedByteArray(phdrSize);
16
- // https://github.com/spessasus/soundfont-proposals/blob/main/extended_limits.md
17
- const xphdrData = new IndexedByteArray(phdrSize);
18
- // the preset start is adjusted in pbag, this is only for the terminal preset index
19
- let presetStart = 0;
20
- for (const preset of this.presets)
21
- {
22
- writeStringAsBytes(phdrData, preset.presetName.substring(0, 20), 20);
23
- writeStringAsBytes(xphdrData, preset.presetName.substring(20), 20);
24
-
25
- writeWord(phdrData, preset.program);
26
- writeWord(phdrData, preset.bank);
27
- writeWord(phdrData, presetStart & 0xFFFF);
28
-
29
- xphdrData.currentIndex += 4;
30
- writeWord(xphdrData, presetStart >> 16);
31
-
32
- // 3 unused dword, spec says to keep em so we do
33
- writeDword(phdrData, preset.library);
34
- writeDword(phdrData, preset.genre);
35
- writeDword(phdrData, preset.morphology);
36
-
37
- xphdrData.currentIndex += 12;
38
-
39
- presetStart += preset.presetZones.length + 1; // global
40
- }
41
- // write EOP
42
- writeStringAsBytes(phdrData, "EOP", 20);
43
- phdrData.currentIndex += 4; // program, bank
44
- writeWord(phdrData, presetStart & 0xFFFF);
45
- phdrData.currentIndex += 12;// library, genre, morphology
46
-
47
- writeStringAsBytes(xphdrData, "EOP", 20);
48
- xphdrData.currentIndex += 4; // program, bank
49
- writeWord(xphdrData, presetStart >> 16);
50
- xphdrData.currentIndex += 12;// library, genre, morphology
51
-
52
- const phdr = writeRIFFChunkRaw("phdr", phdrData);
53
-
54
- const xphdr = writeRIFFChunkRaw("phdr", xphdrData);
55
-
56
- return {
57
- pdta: phdr,
58
- xdta: xphdr,
59
- highestIndex: presetStart
60
- };
61
- }
@@ -1,62 +0,0 @@
1
- import { IndexedByteArray } from "../../../utils/indexed_array.js";
2
- import { writeLittleEndian, writeWord } from "../../../utils/byte_functions/little_endian.js";
3
- import { writeRIFFChunkRaw } from "../riff_chunk.js";
4
- import { MOD_BYTE_SIZE } from "../modulator.js";
5
-
6
- /**
7
- * @this {BasicSoundBank}
8
- * @returns {ReturnedExtendedSf2Chunks}
9
- */
10
- export function getPMOD()
11
- {
12
- // very similar to imod,
13
- // go through all presets -> zones and write modulators sequentially
14
- let pmodSize = MOD_BYTE_SIZE;
15
- for (const preset of this.presets)
16
- {
17
- pmodSize += preset.globalZone.modulators.length * MOD_BYTE_SIZE;
18
- pmodSize += preset.presetZones.reduce((sum, z) => z.modulators.length * MOD_BYTE_SIZE + sum, 0);
19
- }
20
- const pmodData = new IndexedByteArray(pmodSize);
21
-
22
- /**
23
- * @param z {BasicZone}
24
- */
25
- const writeZone = z =>
26
- {
27
- for (const mod of z.modulators)
28
- {
29
- writeWord(pmodData, mod.getSourceEnum());
30
- writeWord(pmodData, mod.modulatorDestination);
31
- writeWord(pmodData, mod.transformAmount);
32
- writeWord(pmodData, mod.getSecSrcEnum());
33
- writeWord(pmodData, mod.transformType);
34
- }
35
- };
36
-
37
-
38
- for (const preset of this.presets)
39
- {
40
- // global
41
- writeZone(preset.globalZone);
42
- for (const zone of preset.presetZones)
43
- {
44
- writeZone(zone);
45
- }
46
- }
47
-
48
- // terminal modulator, is zero
49
- writeLittleEndian(pmodData, 0, MOD_BYTE_SIZE);
50
-
51
- // https://github.com/spessasus/soundfont-proposals/blob/main/extended_limits.md
52
- const xpmodData = new IndexedByteArray(MOD_BYTE_SIZE);
53
- writeLittleEndian(xpmodData, 0, MOD_BYTE_SIZE);
54
-
55
- const pmod = writeRIFFChunkRaw("pmod", pmodData);
56
- const xpmod = writeRIFFChunkRaw("pmod", xpmodData);
57
- return {
58
- pdta: pmod,
59
- xdta: xpmod,
60
- highestIndex: 0 // not applicable
61
- };
62
- }