spessasynth_core 3.27.8 → 4.0.0

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 +17188 -0
  4. package/dist/index.js.map +1 -0
  5. package/package.json +23 -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,154 +0,0 @@
1
- import { findRIFFListType, readRIFFChunk } from "../basic_soundfont/riff_chunk.js";
2
- import { readBytesAsString } from "../../utils/byte_functions/string.js";
3
- import {
4
- SpessaSynthGroupCollapsed,
5
- SpessaSynthGroupEnd,
6
- SpessaSynthInfo,
7
- SpessaSynthWarn
8
- } from "../../utils/loggin.js";
9
- import { consoleColors } from "../../utils/other.js";
10
- import { readLittleEndian, signedInt16 } from "../../utils/byte_functions/little_endian.js";
11
- import { DLSSample } from "./dls_sample.js";
12
-
13
-
14
- /**
15
- * @this {DLSSoundFont}
16
- * @param waveListChunk {RiffChunk}
17
- */
18
- export function readDLSSamples(waveListChunk)
19
- {
20
- SpessaSynthGroupCollapsed(
21
- "%cLoading Wave samples...",
22
- consoleColors.recognized
23
- );
24
- let sampleID = 0;
25
- while (waveListChunk.chunkData.currentIndex < waveListChunk.chunkData.length)
26
- {
27
- const waveChunk = readRIFFChunk(waveListChunk.chunkData);
28
- this.verifyHeader(waveChunk, "LIST");
29
- this.verifyText(readBytesAsString(waveChunk.chunkData, 4), "wave");
30
-
31
- /**
32
- * @type {RiffChunk[]}
33
- */
34
- const waveChunks = [];
35
- while (waveChunk.chunkData.currentIndex < waveChunk.chunkData.length)
36
- {
37
- waveChunks.push(readRIFFChunk(waveChunk.chunkData));
38
- }
39
-
40
- const fmtChunk = waveChunks.find(c => c.header === "fmt ");
41
- if (!fmtChunk)
42
- {
43
- throw new Error("No fmt chunk in the wave file!");
44
- }
45
- // https://github.com/tpn/winsdk-10/blob/9b69fd26ac0c7d0b83d378dba01080e93349c2ed/Include/10.0.14393.0/shared/mmreg.h#L2108
46
- const wFormatTag = readLittleEndian(fmtChunk.chunkData, 2);
47
- const channelsAmount = readLittleEndian(fmtChunk.chunkData, 2);
48
- if (channelsAmount !== 1)
49
- {
50
- throw new Error(`Only mono samples are supported. Fmt reports ${channelsAmount} channels`);
51
- }
52
- const sampleRate = readLittleEndian(fmtChunk.chunkData, 4);
53
- // skip avg bytes
54
- readLittleEndian(fmtChunk.chunkData, 4);
55
- // blockAlign
56
- readLittleEndian(fmtChunk.chunkData, 2);
57
- // it's bits per sample because one channel
58
- const wBitsPerSample = readLittleEndian(fmtChunk.chunkData, 2);
59
- const bytesPerSample = wBitsPerSample / 8;
60
-
61
- const dataChunk = waveChunks.find(c => c.header === "data");
62
- if (!dataChunk)
63
- {
64
- this.parsingError("No data chunk in the WAVE chunk!");
65
- }
66
-
67
- // read sample name
68
- const waveInfo = findRIFFListType(waveChunks, "INFO");
69
- let sampleName = `Unnamed ${sampleID}`;
70
- if (waveInfo)
71
- {
72
- let infoChunk = readRIFFChunk(waveInfo.chunkData);
73
- while (infoChunk.header !== "INAM" && waveInfo.chunkData.currentIndex < waveInfo.chunkData.length)
74
- {
75
- infoChunk = readRIFFChunk(waveInfo.chunkData);
76
- }
77
- if (infoChunk.header === "INAM")
78
- {
79
- sampleName = readBytesAsString(infoChunk.chunkData, infoChunk.size).trim();
80
- }
81
- }
82
-
83
- // correct defaults
84
- let sampleKey = 60;
85
- let samplePitch = 0;
86
- let sampleLoopStart = 0;
87
- const sampleLength = dataChunk.size / bytesPerSample;
88
- let sampleLoopEnd = sampleLength - 1;
89
- let sampleDbAttenuation = 0;
90
-
91
- // read wsmp
92
- const wsmpChunk = waveChunks.find(c => c.header === "wsmp");
93
- if (wsmpChunk)
94
- {
95
- // skip cbsize
96
- readLittleEndian(wsmpChunk.chunkData, 4);
97
- sampleKey = readLittleEndian(wsmpChunk.chunkData, 2);
98
- // section 1.14.2: Each relative pitch unit represents 1/65536 cents.
99
- // but that doesn't seem true for this one: it's just cents.
100
- samplePitch = signedInt16(
101
- wsmpChunk.chunkData[wsmpChunk.chunkData.currentIndex++],
102
- wsmpChunk.chunkData[wsmpChunk.chunkData.currentIndex++]
103
- );
104
-
105
- // pitch correction: convert hundreds to the root key
106
- const samplePitchSemitones = Math.trunc(samplePitch / 100);
107
- sampleKey += samplePitchSemitones;
108
- samplePitch -= samplePitchSemitones * 100;
109
-
110
-
111
- // gain is applied it manually here (literally multiplying the samples)
112
- const gainCorrection = readLittleEndian(wsmpChunk.chunkData, 4);
113
- // convert to signed and turn into decibels
114
- sampleDbAttenuation = (gainCorrection | 0) / -655360;
115
- // no idea about ful options
116
- readLittleEndian(wsmpChunk.chunkData, 4);
117
- const loopsAmount = readLittleEndian(wsmpChunk.chunkData, 4);
118
- if (loopsAmount === 1)
119
- {
120
- // skip size and type
121
- readLittleEndian(wsmpChunk.chunkData, 8);
122
- sampleLoopStart = readLittleEndian(wsmpChunk.chunkData, 4);
123
- const loopSize = readLittleEndian(wsmpChunk.chunkData, 4);
124
- sampleLoopEnd = sampleLoopStart + loopSize;
125
- }
126
- }
127
- else
128
- {
129
- SpessaSynthWarn("No wsmp chunk in wave... using sane defaults.");
130
- }
131
-
132
- this.samples.push(new DLSSample(
133
- sampleName,
134
- sampleRate,
135
- sampleKey,
136
- samplePitch,
137
- sampleLoopStart,
138
- sampleLoopEnd,
139
- sampleDbAttenuation,
140
- dataChunk,
141
- wFormatTag,
142
- bytesPerSample
143
- ));
144
-
145
-
146
- sampleID++;
147
- SpessaSynthInfo(
148
- `%cLoaded sample %c${sampleName}`,
149
- consoleColors.info,
150
- consoleColors.recognized
151
- );
152
- }
153
- SpessaSynthGroupEnd();
154
- }
@@ -1,21 +0,0 @@
1
- import { IndexedByteArray } from "../utils/indexed_array.js";
2
- import { readBytesAsString } from "../utils/byte_functions/string.js";
3
- import { DLSSoundFont } from "./dls/dls_soundfont.js";
4
- import { SoundFont2 } from "./read_sf2/soundfont.js";
5
-
6
- /**
7
- * Loads a soundfont or dls file
8
- * @param buffer {ArrayBuffer} the binary file to load
9
- * @returns {BasicSoundBank}
10
- */
11
- export function loadSoundFont(buffer)
12
- {
13
- const check = buffer.slice(8, 12);
14
- const a = new IndexedByteArray(check);
15
- const id = readBytesAsString(a, 4, false).toLowerCase();
16
- if (id === "dls ")
17
- {
18
- return new DLSSoundFont(buffer);
19
- }
20
- return new SoundFont2(buffer, false);
21
- }
@@ -1,43 +0,0 @@
1
- import { IndexedByteArray } from "../../utils/indexed_array.js";
2
- import { RiffChunk } from "../basic_soundfont/riff_chunk.js";
3
- import { signedInt16 } from "../../utils/byte_functions/little_endian.js";
4
- import { Generator } from "../basic_soundfont/generator.js";
5
-
6
-
7
- export class ReadGenerator extends Generator
8
- {
9
- /**
10
- * Creates a generator
11
- * @param dataArray {IndexedByteArray}
12
- */
13
- constructor(dataArray)
14
- {
15
- super();
16
- // 4 bytes:
17
- // type, type, type, value
18
- const i = dataArray.currentIndex;
19
- /**
20
- * @type {generatorTypes|number}
21
- */
22
- this.generatorType = (dataArray[i + 1] << 8) | dataArray[i];
23
- this.generatorValue = signedInt16(dataArray[i + 2], dataArray[i + 3]);
24
- dataArray.currentIndex += 4;
25
- }
26
- }
27
-
28
- /**
29
- * Reads the generator read
30
- * @param generatorChunk {RiffChunk}
31
- * @returns {Generator[]}
32
- */
33
- export function readGenerators(generatorChunk)
34
- {
35
- let gens = [];
36
- while (generatorChunk.chunkData.length > generatorChunk.chunkData.currentIndex)
37
- {
38
- gens.push(new ReadGenerator(generatorChunk.chunkData));
39
- }
40
- // remove terminal
41
- gens.pop();
42
- return gens;
43
- }
@@ -1,75 +0,0 @@
1
- /**
2
- * instrument_zones.js
3
- * purpose: reads instrument zones from soundfont and gets their respective samples and generators and modulators
4
- */
5
- import { BasicInstrumentZone } from "../basic_soundfont/basic_instrument_zone.js";
6
- import { generatorTypes } from "../basic_soundfont/generator_types.js";
7
-
8
- export class InstrumentZone extends BasicInstrumentZone
9
- {
10
- /**
11
- * Creates a zone (instrument)
12
- * @param inst {Instrument}
13
- */
14
- constructor(inst)
15
- {
16
- super(inst);
17
- }
18
-
19
- /**
20
- * Loads the zone's sample
21
- * @param samples {BasicSample[]}
22
- */
23
- getSample(samples)
24
- {
25
- let sampleID = this.generators.find(g => g.generatorType === generatorTypes.sampleID);
26
- if (sampleID)
27
- {
28
- this.setSample(samples[sampleID.generatorValue]);
29
- }
30
- }
31
- }
32
-
33
- /**
34
- * Reads the given instrument zone
35
- * @param indexes {{mod: number[], gen: number[]}}
36
- * @param instrumentGenerators {Generator[]}
37
- * @param instrumentModulators {Modulator[]}
38
- * @param samples {BasicSample[]}
39
- * @param instruments {Instrument[]}
40
- */
41
- export function applyInstrumentZones(indexes, instrumentGenerators, instrumentModulators, samples, instruments)
42
- {
43
- const genStartIndexes = indexes.gen;
44
- const modStartIndexes = indexes.mod;
45
-
46
- let modIndex = 0;
47
- let genIndex = 0;
48
- for (const instrument of instruments)
49
- {
50
- for (let i = 0; i < instrument.zonesCount; i++)
51
- {
52
- const gensStart = genStartIndexes[genIndex++];
53
- const gensEnd = genStartIndexes[genIndex];
54
- const gens = instrumentGenerators.slice(gensStart, gensEnd);
55
- const modsStart = modStartIndexes[modIndex++];
56
- const modsEnd = modStartIndexes[modIndex];
57
- const mods = instrumentModulators.slice(modsStart, modsEnd);
58
- // check for global zone
59
- if (gens.find(g => g.generatorType === generatorTypes.sampleID))
60
- {
61
- // regular zone
62
- const zone = instrument.createZone();
63
- zone.addGenerators(...gens);
64
- zone.addModulators(...mods);
65
- zone.getSample(samples);
66
- }
67
- else
68
- {
69
- // global zone
70
- instrument.globalZone.addGenerators(...gens);
71
- instrument.globalZone.addModulators(...mods);
72
- }
73
- }
74
- }
75
- }
@@ -1,71 +0,0 @@
1
- import { RiffChunk } from "../basic_soundfont/riff_chunk.js";
2
- import { readLittleEndian } from "../../utils/byte_functions/little_endian.js";
3
- import { readBytesAsString } from "../../utils/byte_functions/string.js";
4
- import { BasicInstrument } from "../basic_soundfont/basic_instrument.js";
5
-
6
- import { InstrumentZone } from "./instrument_zones.js";
7
-
8
- /**
9
- * instrument.js
10
- * purpose: parses soundfont instrument and stores them as a class
11
- */
12
-
13
- export class Instrument extends BasicInstrument
14
- {
15
- /**
16
- * @type {number}
17
- */
18
- zoneStartIndex;
19
- /**
20
- * @type {number}
21
- */
22
- zonesCount = 0;
23
-
24
- /**
25
- * Creates an instrument
26
- * @param instrumentChunk {RiffChunk}
27
- */
28
- constructor(instrumentChunk)
29
- {
30
- super();
31
- this.instrumentName = readBytesAsString(instrumentChunk.chunkData, 20);
32
- this.zoneStartIndex = readLittleEndian(instrumentChunk.chunkData, 2);
33
- }
34
-
35
- /**
36
- * @returns {InstrumentZone}
37
- */
38
- createZone()
39
- {
40
- const z = new InstrumentZone(this);
41
- this.instrumentZones.push(z);
42
- return z;
43
- }
44
- }
45
-
46
- /**
47
- * Reads the instruments
48
- * @param instrumentChunk {RiffChunk}
49
- * @returns {Instrument[]}
50
- */
51
- export function readInstruments(instrumentChunk)
52
- {
53
- /**
54
- * @type {Instrument[]}
55
- */
56
- let instruments = [];
57
- while (instrumentChunk.chunkData.length > instrumentChunk.chunkData.currentIndex)
58
- {
59
- let instrument = new Instrument(instrumentChunk);
60
-
61
- if (instruments.length > 0)
62
- {
63
- const previous = instruments[instruments.length - 1];
64
- previous.zonesCount = instrument.zoneStartIndex - previous.zoneStartIndex;
65
- }
66
- instruments.push(instrument);
67
- }
68
- // remove EOI
69
- instruments.pop();
70
- return instruments;
71
- }
@@ -1,25 +0,0 @@
1
- import { readLittleEndian, signedInt16 } from "../../utils/byte_functions/little_endian.js";
2
- import { DecodedModulator, Modulator } from "../basic_soundfont/modulator.js";
3
-
4
- /**
5
- * Reads the modulator read
6
- * @param modulatorChunk {RiffChunk}
7
- * @returns {Modulator[]}
8
- */
9
- export function readModulators(modulatorChunk)
10
- {
11
- let mods = [];
12
- while (modulatorChunk.chunkData.length > modulatorChunk.chunkData.currentIndex)
13
- {
14
- const dataArray = modulatorChunk.chunkData;
15
- const sourceEnum = readLittleEndian(dataArray, 2);
16
- const destination = readLittleEndian(dataArray, 2);
17
- const amount = signedInt16(dataArray[dataArray.currentIndex++], dataArray[dataArray.currentIndex++]);
18
- const secondarySourceEnum = readLittleEndian(dataArray, 2);
19
- const transformType = readLittleEndian(dataArray, 2);
20
- mods.push(new DecodedModulator(sourceEnum, secondarySourceEnum, destination, amount, transformType));
21
- }
22
- // remove terminal
23
- mods.pop();
24
- return mods;
25
- }
@@ -1,79 +0,0 @@
1
- import { BasicPresetZone } from "../basic_soundfont/basic_preset_zone.js";
2
- import { Generator } from "../basic_soundfont/generator.js";
3
- import { Modulator } from "../basic_soundfont/modulator.js";
4
- import { generatorTypes } from "../basic_soundfont/generator_types.js";
5
-
6
- /**
7
- * preset_zones.js
8
- * purpose: reads preset zones from soundfont and gets their respective samples and generators and modulators
9
- */
10
-
11
- export class PresetZone extends BasicPresetZone
12
- {
13
- /**
14
- * Creates a zone (preset)
15
- * @param preset {BasicPreset}
16
- */
17
- constructor(preset)
18
- {
19
- super(preset);
20
- }
21
-
22
- /**
23
- * grab the instrument
24
- * @param instruments {BasicInstrument[]}
25
- */
26
- getInstrument(instruments)
27
- {
28
- let instrumentID = this.generators.find(g => g.generatorType === generatorTypes.instrument);
29
- if (instrumentID)
30
- {
31
- this.setInstrument(instruments[instrumentID.generatorValue]);
32
- }
33
- }
34
- }
35
-
36
-
37
- /**
38
- * Reads the given preset zone
39
- * @param indexes {{mod: number[], gen: number[]}}
40
- * @param presetGens {Generator[]}
41
- * @param instruments {BasicInstrument[]}
42
- * @param presetMods {Modulator[]}
43
- * @param presets {Preset[]}
44
- */
45
- export function applyPresetZones(indexes, presetGens, presetMods, instruments, presets)
46
- {
47
- const genStartIndexes = indexes.gen;
48
- const modStartIndexes = indexes.mod;
49
-
50
- let modIndex = 0;
51
- let genIndex = 0;
52
- for (const preset of presets)
53
- {
54
- for (let i = 0; i < preset.zonesCount; i++)
55
- {
56
- const gensStart = genStartIndexes[genIndex++];
57
- const gensEnd = genStartIndexes[genIndex];
58
- const gens = presetGens.slice(gensStart, gensEnd);
59
- const modsStart = modStartIndexes[modIndex++];
60
- const modsEnd = modStartIndexes[modIndex];
61
- const mods = presetMods.slice(modsStart, modsEnd);
62
- // check for global zone
63
- if (gens.find(g => g.generatorType === generatorTypes.instrument) !== undefined)
64
- {
65
- // regular zone
66
- const zone = preset.createZone();
67
- zone.addGenerators(...gens);
68
- zone.addModulators(...mods);
69
- zone.getInstrument(instruments);
70
- }
71
- else
72
- {
73
- // global zone
74
- preset.globalZone.addGenerators(...gens);
75
- preset.globalZone.addModulators(...mods);
76
- }
77
- }
78
- }
79
- }
@@ -1,80 +0,0 @@
1
- import { RiffChunk } from "../basic_soundfont/riff_chunk.js";
2
- import { readLittleEndian } from "../../utils/byte_functions/little_endian.js";
3
- import { readBytesAsString } from "../../utils/byte_functions/string.js";
4
- import { BasicPreset } from "../basic_soundfont/basic_preset.js";
5
- import { PresetZone } from "./preset_zones.js";
6
-
7
- /**
8
- * parses soundfont presets, also includes function for getting the generators and samples from midi note and velocity
9
- */
10
-
11
- export class Preset extends BasicPreset
12
- {
13
-
14
- /**
15
- * @type {number}
16
- */
17
- zoneStartIndex;
18
- /**
19
- * @type {number}
20
- */
21
- zonesCount = 0;
22
-
23
- /**
24
- * Creates a preset
25
- * @param presetChunk {RiffChunk}
26
- * @param sf2 {BasicSoundBank}
27
- */
28
- constructor(presetChunk, sf2)
29
- {
30
- super(sf2);
31
- this.presetName = readBytesAsString(presetChunk.chunkData, 20)
32
- .replace(/\d{3}:\d{3}/, ""); // remove those pesky "000:001"
33
-
34
- this.program = readLittleEndian(presetChunk.chunkData, 2);
35
- this.bank = readLittleEndian(presetChunk.chunkData, 2);
36
- this.zoneStartIndex = readLittleEndian(presetChunk.chunkData, 2);
37
-
38
- // read the dword
39
- this.library = readLittleEndian(presetChunk.chunkData, 4);
40
- this.genre = readLittleEndian(presetChunk.chunkData, 4);
41
- this.morphology = readLittleEndian(presetChunk.chunkData, 4);
42
- }
43
-
44
- /**
45
- * @returns {PresetZone}
46
- */
47
- createZone()
48
- {
49
- const z = new PresetZone(this);
50
- this.presetZones.push(z);
51
- return z;
52
- }
53
- }
54
-
55
- /**
56
- * Reads the presets
57
- * @param presetChunk {RiffChunk}
58
- * @param parent {BasicSoundBank}
59
- * @returns {Preset[]}
60
- */
61
- export function readPresets(presetChunk, parent)
62
- {
63
- /**
64
- * @type {Preset[]}
65
- */
66
- let presets = [];
67
- while (presetChunk.chunkData.length > presetChunk.chunkData.currentIndex)
68
- {
69
- let preset = new Preset(presetChunk, parent);
70
- if (presets.length > 0)
71
- {
72
- const previous = presets[presets.length - 1];
73
- previous.zonesCount = preset.zoneStartIndex - previous.zoneStartIndex;
74
- }
75
- presets.push(preset);
76
- }
77
- // remove EOP
78
- presets.pop();
79
- return presets;
80
- }