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.
- package/README.md +85 -51
- package/dist/index.d.ts +4057 -0
- package/dist/index.js +17178 -0
- package/dist/index.js.map +1 -0
- package/package.json +24 -6
- package/index.js +0 -132
- package/src/externals/README.md +0 -6
- package/src/externals/fflate/LICENSE +0 -21
- package/src/externals/fflate/fflate.min.js +0 -1
- package/src/externals/stbvorbis_sync/@types/stbvorbis_sync.d.ts +0 -12
- package/src/externals/stbvorbis_sync/LICENSE +0 -202
- package/src/externals/stbvorbis_sync/NOTICE +0 -6
- package/src/externals/stbvorbis_sync/stbvorbis_sync.min.js +0 -1
- package/src/midi/README.md +0 -32
- package/src/midi/basic_midi.js +0 -587
- package/src/midi/midi_builder.js +0 -203
- package/src/midi/midi_loader.js +0 -321
- package/src/midi/midi_message.js +0 -254
- package/src/midi/midi_sequence.js +0 -230
- package/src/midi/midi_tools/get_note_times.js +0 -154
- package/src/midi/midi_tools/midi_editor.js +0 -611
- package/src/midi/midi_tools/midi_writer.js +0 -105
- package/src/midi/midi_tools/rmidi_writer.js +0 -566
- package/src/midi/midi_tools/used_keys_loaded.js +0 -256
- package/src/midi/xmf_loader.js +0 -454
- package/src/sequencer/README.md +0 -9
- package/src/sequencer/events.js +0 -81
- package/src/sequencer/play.js +0 -362
- package/src/sequencer/process_event.js +0 -165
- package/src/sequencer/process_tick.js +0 -104
- package/src/sequencer/sequencer_engine.js +0 -372
- package/src/sequencer/song_control.js +0 -196
- package/src/soundfont/README.md +0 -11
- package/src/soundfont/basic_soundfont/basic_global_zone.js +0 -6
- package/src/soundfont/basic_soundfont/basic_instrument.js +0 -115
- package/src/soundfont/basic_soundfont/basic_instrument_zone.js +0 -45
- package/src/soundfont/basic_soundfont/basic_preset.js +0 -313
- package/src/soundfont/basic_soundfont/basic_preset_zone.js +0 -39
- package/src/soundfont/basic_soundfont/basic_sample.js +0 -477
- package/src/soundfont/basic_soundfont/basic_soundbank.js +0 -740
- package/src/soundfont/basic_soundfont/basic_zone.js +0 -145
- package/src/soundfont/basic_soundfont/generator.js +0 -76
- package/src/soundfont/basic_soundfont/generator_types.js +0 -151
- package/src/soundfont/basic_soundfont/modulator.js +0 -581
- package/src/soundfont/basic_soundfont/riff_chunk.js +0 -195
- package/src/soundfont/basic_soundfont/write_dls/art2.js +0 -174
- package/src/soundfont/basic_soundfont/write_dls/articulator.js +0 -49
- package/src/soundfont/basic_soundfont/write_dls/combine_zones.js +0 -374
- package/src/soundfont/basic_soundfont/write_dls/ins.js +0 -85
- package/src/soundfont/basic_soundfont/write_dls/lins.js +0 -15
- package/src/soundfont/basic_soundfont/write_dls/modulator_converter.js +0 -330
- package/src/soundfont/basic_soundfont/write_dls/rgn2.js +0 -120
- package/src/soundfont/basic_soundfont/write_dls/wave.js +0 -71
- package/src/soundfont/basic_soundfont/write_dls/write_dls.js +0 -124
- package/src/soundfont/basic_soundfont/write_dls/wsmp.js +0 -78
- package/src/soundfont/basic_soundfont/write_dls/wvpl.js +0 -35
- package/src/soundfont/basic_soundfont/write_sf2/ibag.js +0 -60
- package/src/soundfont/basic_soundfont/write_sf2/igen.js +0 -91
- package/src/soundfont/basic_soundfont/write_sf2/imod.js +0 -62
- package/src/soundfont/basic_soundfont/write_sf2/inst.js +0 -42
- package/src/soundfont/basic_soundfont/write_sf2/pbag.js +0 -57
- package/src/soundfont/basic_soundfont/write_sf2/pgen.js +0 -92
- package/src/soundfont/basic_soundfont/write_sf2/phdr.js +0 -61
- package/src/soundfont/basic_soundfont/write_sf2/pmod.js +0 -62
- package/src/soundfont/basic_soundfont/write_sf2/sdta.js +0 -131
- package/src/soundfont/basic_soundfont/write_sf2/shdr.js +0 -77
- package/src/soundfont/basic_soundfont/write_sf2/write.js +0 -287
- package/src/soundfont/dls/articulator_converter.js +0 -402
- package/src/soundfont/dls/dls_destinations.js +0 -38
- package/src/soundfont/dls/dls_instrument.js +0 -20
- package/src/soundfont/dls/dls_preset.js +0 -43
- package/src/soundfont/dls/dls_sample.js +0 -238
- package/src/soundfont/dls/dls_soundfont.js +0 -183
- package/src/soundfont/dls/dls_sources.js +0 -63
- package/src/soundfont/dls/dls_zone.js +0 -89
- package/src/soundfont/dls/read_articulation.js +0 -300
- package/src/soundfont/dls/read_instrument.js +0 -118
- package/src/soundfont/dls/read_instrument_list.js +0 -17
- package/src/soundfont/dls/read_lart.js +0 -35
- package/src/soundfont/dls/read_region.js +0 -157
- package/src/soundfont/dls/read_samples.js +0 -154
- package/src/soundfont/load_soundfont.js +0 -21
- package/src/soundfont/read_sf2/generators.js +0 -43
- package/src/soundfont/read_sf2/instrument_zones.js +0 -75
- package/src/soundfont/read_sf2/instruments.js +0 -71
- package/src/soundfont/read_sf2/modulators.js +0 -25
- package/src/soundfont/read_sf2/preset_zones.js +0 -79
- package/src/soundfont/read_sf2/presets.js +0 -80
- package/src/soundfont/read_sf2/samples.js +0 -317
- package/src/soundfont/read_sf2/soundfont.js +0 -452
- package/src/soundfont/read_sf2/zones.js +0 -28
- package/src/synthetizer/README.md +0 -7
- package/src/synthetizer/audio_engine/README.md +0 -9
- package/src/synthetizer/audio_engine/engine_components/compute_modulator.js +0 -289
- package/src/synthetizer/audio_engine/engine_components/controller_tables.js +0 -90
- package/src/synthetizer/audio_engine/engine_components/dynamic_modulator_system.js +0 -95
- package/src/synthetizer/audio_engine/engine_components/enums.js +0 -18
- package/src/synthetizer/audio_engine/engine_components/key_modifier_manager.js +0 -151
- package/src/synthetizer/audio_engine/engine_components/lfo.js +0 -26
- package/src/synthetizer/audio_engine/engine_components/lowpass_filter.js +0 -282
- package/src/synthetizer/audio_engine/engine_components/midi_audio_channel.js +0 -551
- package/src/synthetizer/audio_engine/engine_components/modulation_envelope.js +0 -181
- package/src/synthetizer/audio_engine/engine_components/modulator_curves.js +0 -89
- package/src/synthetizer/audio_engine/engine_components/soundfont_manager.js +0 -265
- package/src/synthetizer/audio_engine/engine_components/stereo_panner.js +0 -124
- package/src/synthetizer/audio_engine/engine_components/unit_converter.js +0 -73
- package/src/synthetizer/audio_engine/engine_components/voice.js +0 -525
- package/src/synthetizer/audio_engine/engine_components/volume_envelope.js +0 -402
- package/src/synthetizer/audio_engine/engine_components/wavetable_oscillator.js +0 -274
- package/src/synthetizer/audio_engine/engine_methods/controller_control/controller_change.js +0 -159
- package/src/synthetizer/audio_engine/engine_methods/controller_control/master_parameters.js +0 -53
- package/src/synthetizer/audio_engine/engine_methods/controller_control/reset_controllers.js +0 -254
- package/src/synthetizer/audio_engine/engine_methods/create_midi_channel.js +0 -20
- package/src/synthetizer/audio_engine/engine_methods/data_entry/awe32.js +0 -198
- package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_coarse.js +0 -281
- package/src/synthetizer/audio_engine/engine_methods/data_entry/data_entry_fine.js +0 -109
- package/src/synthetizer/audio_engine/engine_methods/mute_channel.js +0 -17
- package/src/synthetizer/audio_engine/engine_methods/note_on.js +0 -220
- package/src/synthetizer/audio_engine/engine_methods/portamento_time.js +0 -92
- package/src/synthetizer/audio_engine/engine_methods/program_change.js +0 -35
- package/src/synthetizer/audio_engine/engine_methods/render_voice.js +0 -214
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/embedded_sound_bank.js +0 -42
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/get_preset.js +0 -0
- package/src/synthetizer/audio_engine/engine_methods/soundfont_management/update_preset_list.js +0 -19
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/kill_note.js +0 -23
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/note_off.js +0 -56
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_channels.js +0 -16
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/stop_all_notes.js +0 -30
- package/src/synthetizer/audio_engine/engine_methods/stopping_notes/voice_killing.js +0 -63
- package/src/synthetizer/audio_engine/engine_methods/system_exclusive.js +0 -1058
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/channel_pressure.js +0 -23
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/pitch_wheel.js +0 -31
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/poly_pressure.js +0 -29
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_master_tuning.js +0 -15
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_modulation_depth.js +0 -26
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_octave_tuning.js +0 -19
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/set_tuning.js +0 -27
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_all_channels.js +0 -15
- package/src/synthetizer/audio_engine/engine_methods/tuning_control/transpose_channel.js +0 -34
- package/src/synthetizer/audio_engine/main_processor.js +0 -817
- package/src/synthetizer/audio_engine/snapshot/apply_synthesizer_snapshot.js +0 -16
- package/src/synthetizer/audio_engine/snapshot/channel_snapshot.js +0 -175
- package/src/synthetizer/audio_engine/snapshot/synthesizer_snapshot.js +0 -116
- package/src/synthetizer/audio_engine/synth_processor_options.js +0 -18
- package/src/synthetizer/synth_constants.js +0 -26
- package/src/utils/README.md +0 -8
- package/src/utils/buffer_to_wav.js +0 -197
- package/src/utils/byte_functions/big_endian.js +0 -32
- package/src/utils/byte_functions/little_endian.js +0 -77
- package/src/utils/byte_functions/string.js +0 -92
- package/src/utils/byte_functions/variable_length_quantity.js +0 -42
- package/src/utils/fill_with_defaults.js +0 -21
- package/src/utils/indexed_array.js +0 -34
- package/src/utils/loggin.js +0 -71
- package/src/utils/other.js +0 -92
- package/src/utils/sysex_detector.js +0 -58
- package/src/utils/xg_hacks.js +0 -193
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import { BasicSample, sampleTypes } from "../basic_soundfont/basic_sample.js";
|
|
2
|
-
import { SpessaSynthWarn } from "../../utils/loggin.js";
|
|
3
|
-
import { readLittleEndian } from "../../utils/byte_functions/little_endian.js";
|
|
4
|
-
import { IndexedByteArray } from "../../utils/indexed_array.js";
|
|
5
|
-
|
|
6
|
-
const W_FORMAT_TAG = {
|
|
7
|
-
PCM: 0x01,
|
|
8
|
-
ALAW: 0x6
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @param data {IndexedByteArray}
|
|
14
|
-
* @param bytesPerSample {number}
|
|
15
|
-
* @returns {Float32Array}
|
|
16
|
-
*/
|
|
17
|
-
function readPCM(data, bytesPerSample)
|
|
18
|
-
{
|
|
19
|
-
const maxSampleValue = Math.pow(2, bytesPerSample * 8 - 1); // Max value for the sample
|
|
20
|
-
const maxUnsigned = Math.pow(2, bytesPerSample * 8);
|
|
21
|
-
|
|
22
|
-
let normalizationFactor;
|
|
23
|
-
let isUnsigned = false;
|
|
24
|
-
|
|
25
|
-
if (bytesPerSample === 1)
|
|
26
|
-
{
|
|
27
|
-
normalizationFactor = 255; // For 8-bit normalize from 0-255
|
|
28
|
-
isUnsigned = true;
|
|
29
|
-
}
|
|
30
|
-
else
|
|
31
|
-
{
|
|
32
|
-
normalizationFactor = maxSampleValue; // For 16-bit normalize from -32,768 to 32,767
|
|
33
|
-
}
|
|
34
|
-
const sampleLength = data.length / bytesPerSample;
|
|
35
|
-
const sampleData = new Float32Array(sampleLength);
|
|
36
|
-
if (bytesPerSample === 2)
|
|
37
|
-
{
|
|
38
|
-
// special optimized case for s16 (most common)
|
|
39
|
-
const s16 = new Int16Array(data.buffer);
|
|
40
|
-
for (let i = 0; i < s16.length; i++)
|
|
41
|
-
{
|
|
42
|
-
sampleData[i] = s16[i] / 32768;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
else
|
|
46
|
-
{
|
|
47
|
-
for (let i = 0; i < sampleData.length; i++)
|
|
48
|
-
{
|
|
49
|
-
// read
|
|
50
|
-
let sample = readLittleEndian(data, bytesPerSample);
|
|
51
|
-
// turn into signed
|
|
52
|
-
if (isUnsigned)
|
|
53
|
-
{
|
|
54
|
-
// normalize unsigned 8-bit sample
|
|
55
|
-
sampleData[i] = (sample / normalizationFactor) - 0.5;
|
|
56
|
-
}
|
|
57
|
-
else
|
|
58
|
-
{
|
|
59
|
-
// normalize signed sample
|
|
60
|
-
if (sample >= maxSampleValue)
|
|
61
|
-
{
|
|
62
|
-
sample -= maxUnsigned;
|
|
63
|
-
}
|
|
64
|
-
sampleData[i] = sample / normalizationFactor;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return sampleData;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* @param data {IndexedByteArray}
|
|
73
|
-
* @param bytesPerSample {number}
|
|
74
|
-
* @returns {Float32Array}
|
|
75
|
-
*/
|
|
76
|
-
function readALAW(data, bytesPerSample)
|
|
77
|
-
{
|
|
78
|
-
const sampleLength = data.length / bytesPerSample;
|
|
79
|
-
const sampleData = new Float32Array(sampleLength);
|
|
80
|
-
for (let i = 0; i < sampleData.length; i++)
|
|
81
|
-
{
|
|
82
|
-
// read
|
|
83
|
-
const input = readLittleEndian(data, bytesPerSample);
|
|
84
|
-
|
|
85
|
-
// https://en.wikipedia.org/wiki/G.711#A-law
|
|
86
|
-
// re-toggle toggled bits
|
|
87
|
-
let sample = input ^ 0x55;
|
|
88
|
-
|
|
89
|
-
// remove sign bit
|
|
90
|
-
sample &= 0x7F;
|
|
91
|
-
|
|
92
|
-
// extract exponent
|
|
93
|
-
let exponent = sample >> 4;
|
|
94
|
-
// extract mantissa
|
|
95
|
-
let mantissa = sample & 0xF;
|
|
96
|
-
if (exponent > 0)
|
|
97
|
-
{
|
|
98
|
-
mantissa += 16; // add leading '1', if exponent > 0
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
mantissa = (mantissa << 4) + 0x8;
|
|
102
|
-
if (exponent > 1)
|
|
103
|
-
{
|
|
104
|
-
mantissa = mantissa << (exponent - 1);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const s16sample = input > 127 ? mantissa : -mantissa;
|
|
108
|
-
|
|
109
|
-
// convert to float
|
|
110
|
-
sampleData[i] = s16sample / 32678;
|
|
111
|
-
}
|
|
112
|
-
return sampleData;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export class DLSSample extends BasicSample
|
|
116
|
-
{
|
|
117
|
-
/**
|
|
118
|
-
* in decibels of attenuation, WITHOUT EMU CORRECTION
|
|
119
|
-
* @type {number}
|
|
120
|
-
*/
|
|
121
|
-
sampleDbAttenuation;
|
|
122
|
-
/**
|
|
123
|
-
* @type {Float32Array}
|
|
124
|
-
*/
|
|
125
|
-
sampleData;
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* @type {number}
|
|
129
|
-
*/
|
|
130
|
-
wFormatTag;
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* @type {number}
|
|
134
|
-
*/
|
|
135
|
-
bytesPerSample;
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Sample's raw data before decoding it, for faster writing
|
|
139
|
-
* @type {IndexedByteArray}
|
|
140
|
-
*/
|
|
141
|
-
rawData;
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* @param name {string}
|
|
145
|
-
* @param rate {number}
|
|
146
|
-
* @param pitch {number}
|
|
147
|
-
* @param pitchCorrection {number}
|
|
148
|
-
* @param loopStart {number} sample data points
|
|
149
|
-
* @param loopEnd {number} sample data points
|
|
150
|
-
* @param sampleDbAttenuation {number} in db
|
|
151
|
-
* @param dataChunk {RiffChunk}
|
|
152
|
-
* @param wFormatTag {number}
|
|
153
|
-
* @param bytesPerSample {number}
|
|
154
|
-
*/
|
|
155
|
-
constructor(
|
|
156
|
-
name,
|
|
157
|
-
rate,
|
|
158
|
-
pitch,
|
|
159
|
-
pitchCorrection,
|
|
160
|
-
loopStart,
|
|
161
|
-
loopEnd,
|
|
162
|
-
sampleDbAttenuation,
|
|
163
|
-
dataChunk,
|
|
164
|
-
wFormatTag,
|
|
165
|
-
bytesPerSample
|
|
166
|
-
)
|
|
167
|
-
{
|
|
168
|
-
super(
|
|
169
|
-
name,
|
|
170
|
-
rate,
|
|
171
|
-
pitch,
|
|
172
|
-
pitchCorrection,
|
|
173
|
-
sampleTypes.monoSample,
|
|
174
|
-
loopStart,
|
|
175
|
-
loopEnd
|
|
176
|
-
);
|
|
177
|
-
this.sampleDbAttenuation = sampleDbAttenuation;
|
|
178
|
-
this.dataOverriden = false;
|
|
179
|
-
/**
|
|
180
|
-
* @type {IndexedByteArray}
|
|
181
|
-
*/
|
|
182
|
-
this.rawData = dataChunk.chunkData;
|
|
183
|
-
this.wFormatTag = wFormatTag;
|
|
184
|
-
this.bytesPerSample = bytesPerSample;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
getAudioData()
|
|
188
|
-
{
|
|
189
|
-
if (!(this.rawData instanceof Uint8Array))
|
|
190
|
-
{
|
|
191
|
-
return new Float32Array(0);
|
|
192
|
-
}
|
|
193
|
-
if (!this.sampleData)
|
|
194
|
-
{
|
|
195
|
-
let sampleData;
|
|
196
|
-
switch (this.wFormatTag)
|
|
197
|
-
{
|
|
198
|
-
default:
|
|
199
|
-
SpessaSynthWarn(`Failed to decode sample. Unknown wFormatTag: ${this.wFormatTag}`);
|
|
200
|
-
sampleData = new Float32Array(this.rawData.length / this.bytesPerSample);
|
|
201
|
-
break;
|
|
202
|
-
|
|
203
|
-
case W_FORMAT_TAG.PCM:
|
|
204
|
-
sampleData = readPCM(this.rawData, this.bytesPerSample);
|
|
205
|
-
break;
|
|
206
|
-
|
|
207
|
-
case W_FORMAT_TAG.ALAW:
|
|
208
|
-
sampleData = readALAW(this.rawData, this.bytesPerSample);
|
|
209
|
-
break;
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
this.setAudioData(sampleData);
|
|
213
|
-
}
|
|
214
|
-
return this.sampleData;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* @param audioData {Float32Array}
|
|
219
|
-
*/
|
|
220
|
-
setAudioData(audioData)
|
|
221
|
-
{
|
|
222
|
-
super.setAudioData(audioData);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
getRawData(allowVorbis)
|
|
226
|
-
{
|
|
227
|
-
if (this.dataOverriden || this.isCompressed)
|
|
228
|
-
{
|
|
229
|
-
return super.getRawData(allowVorbis);
|
|
230
|
-
}
|
|
231
|
-
if (this.wFormatTag === W_FORMAT_TAG.PCM && this.bytesPerSample === 2)
|
|
232
|
-
{
|
|
233
|
-
// copy straight away
|
|
234
|
-
return this.rawData;
|
|
235
|
-
}
|
|
236
|
-
return this.encodeS16LE();
|
|
237
|
-
}
|
|
238
|
-
}
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import { BasicSoundBank } from "../basic_soundfont/basic_soundbank.js";
|
|
2
|
-
import { IndexedByteArray } from "../../utils/indexed_array.js";
|
|
3
|
-
import { SpessaSynthGroup, SpessaSynthGroupEnd, SpessaSynthInfo } from "../../utils/loggin.js";
|
|
4
|
-
import { consoleColors } from "../../utils/other.js";
|
|
5
|
-
import { findRIFFListType, readRIFFChunk } from "../basic_soundfont/riff_chunk.js";
|
|
6
|
-
import { readBytesAsString } from "../../utils/byte_functions/string.js";
|
|
7
|
-
import { readLittleEndian } from "../../utils/byte_functions/little_endian.js";
|
|
8
|
-
import { readDLSInstrumentList } from "./read_instrument_list.js";
|
|
9
|
-
import { readDLSInstrument } from "./read_instrument.js";
|
|
10
|
-
import { readLart } from "./read_lart.js";
|
|
11
|
-
import { readDLSSamples } from "./read_samples.js";
|
|
12
|
-
|
|
13
|
-
class DLSSoundFont extends BasicSoundBank
|
|
14
|
-
{
|
|
15
|
-
/**
|
|
16
|
-
* Loads a new DLS (Downloadable sounds) soundfont
|
|
17
|
-
* @param buffer {ArrayBuffer}
|
|
18
|
-
*/
|
|
19
|
-
constructor(buffer)
|
|
20
|
-
{
|
|
21
|
-
super();
|
|
22
|
-
this.dataArray = new IndexedByteArray(buffer);
|
|
23
|
-
SpessaSynthGroup("%cParsing DLS...", consoleColors.info);
|
|
24
|
-
if (!this.dataArray)
|
|
25
|
-
{
|
|
26
|
-
SpessaSynthGroupEnd();
|
|
27
|
-
this.parsingError("No data provided!");
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// read the main chunk
|
|
31
|
-
let firstChunk = readRIFFChunk(this.dataArray, false);
|
|
32
|
-
this.verifyHeader(firstChunk, "riff");
|
|
33
|
-
this.verifyText(readBytesAsString(this.dataArray, 4).toLowerCase(), "dls ");
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Read the list
|
|
37
|
-
* @type {RiffChunk[]}
|
|
38
|
-
*/
|
|
39
|
-
const chunks = [];
|
|
40
|
-
while (this.dataArray.currentIndex < this.dataArray.length)
|
|
41
|
-
{
|
|
42
|
-
chunks.push(readRIFFChunk(this.dataArray));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// mandatory
|
|
46
|
-
this.soundFontInfo["ifil"] = "2.1"; // always for dls
|
|
47
|
-
this.soundFontInfo["isng"] = "E-mu 10K2";
|
|
48
|
-
|
|
49
|
-
// set some defaults
|
|
50
|
-
this.soundFontInfo["INAM"] = "Unnamed DLS";
|
|
51
|
-
this.soundFontInfo["IENG"] = "Unknown";
|
|
52
|
-
this.soundFontInfo["IPRD"] = "SpessaSynth DLS";
|
|
53
|
-
this.soundFontInfo["ICRD"] = new Date().toDateString();
|
|
54
|
-
|
|
55
|
-
// read info
|
|
56
|
-
const infoChunk = findRIFFListType(chunks, "INFO");
|
|
57
|
-
if (infoChunk)
|
|
58
|
-
{
|
|
59
|
-
while (infoChunk.chunkData.currentIndex < infoChunk.chunkData.length)
|
|
60
|
-
{
|
|
61
|
-
const infoPart = readRIFFChunk(infoChunk.chunkData);
|
|
62
|
-
this.soundFontInfo[infoPart.header] = readBytesAsString(infoPart.chunkData, infoPart.size);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
this.soundFontInfo["ICMT"] = this.soundFontInfo["ICMT"] || "(No description)";
|
|
66
|
-
if (this.soundFontInfo["ISBJ"])
|
|
67
|
-
{
|
|
68
|
-
// merge it
|
|
69
|
-
this.soundFontInfo["ICMT"] += "\n" + this.soundFontInfo["ISBJ"];
|
|
70
|
-
delete this.soundFontInfo["ISBJ"];
|
|
71
|
-
}
|
|
72
|
-
this.soundFontInfo["ICMT"] += "\nConverted from DLS to SF2 with SpessaSynth";
|
|
73
|
-
|
|
74
|
-
for (const [info, value] of Object.entries(this.soundFontInfo))
|
|
75
|
-
{
|
|
76
|
-
SpessaSynthInfo(
|
|
77
|
-
`%c"${info}": %c"${value}"`,
|
|
78
|
-
consoleColors.info,
|
|
79
|
-
consoleColors.recognized
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// read "colh"
|
|
84
|
-
let colhChunk = chunks.find(c => c.header === "colh");
|
|
85
|
-
if (!colhChunk)
|
|
86
|
-
{
|
|
87
|
-
SpessaSynthGroupEnd();
|
|
88
|
-
this.parsingError("No colh chunk!");
|
|
89
|
-
}
|
|
90
|
-
this.instrumentAmount = readLittleEndian(colhChunk.chunkData, 4);
|
|
91
|
-
SpessaSynthInfo(
|
|
92
|
-
`%cInstruments amount: %c${this.instrumentAmount}`,
|
|
93
|
-
consoleColors.info,
|
|
94
|
-
consoleColors.recognized
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
// read the wave list
|
|
98
|
-
let waveListChunk = findRIFFListType(chunks, "wvpl");
|
|
99
|
-
if (!waveListChunk)
|
|
100
|
-
{
|
|
101
|
-
SpessaSynthGroupEnd();
|
|
102
|
-
this.parsingError("No wvpl chunk!");
|
|
103
|
-
}
|
|
104
|
-
this.readDLSSamples(waveListChunk);
|
|
105
|
-
|
|
106
|
-
// read the instrument list
|
|
107
|
-
let instrumentListChunk = findRIFFListType(chunks, "lins");
|
|
108
|
-
if (!instrumentListChunk)
|
|
109
|
-
{
|
|
110
|
-
SpessaSynthGroupEnd();
|
|
111
|
-
this.parsingError("No lins chunk!");
|
|
112
|
-
}
|
|
113
|
-
this.readDLSInstrumentList(instrumentListChunk);
|
|
114
|
-
|
|
115
|
-
// sort presets
|
|
116
|
-
this.flush();
|
|
117
|
-
SpessaSynthInfo(
|
|
118
|
-
`%cParsing finished! %c"${this.soundFontInfo["INAM"] || "UNNAMED"}"%c has %c${this.presets.length} %cpresets,
|
|
119
|
-
%c${this.instruments.length}%c instruments and %c${this.samples.length}%c samples.`,
|
|
120
|
-
consoleColors.info,
|
|
121
|
-
consoleColors.recognized,
|
|
122
|
-
consoleColors.info,
|
|
123
|
-
consoleColors.recognized,
|
|
124
|
-
consoleColors.info,
|
|
125
|
-
consoleColors.recognized,
|
|
126
|
-
consoleColors.info,
|
|
127
|
-
consoleColors.recognized,
|
|
128
|
-
consoleColors.info
|
|
129
|
-
);
|
|
130
|
-
SpessaSynthGroupEnd();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* @param chunk {RiffChunk}
|
|
135
|
-
* @param expected {string}
|
|
136
|
-
*/
|
|
137
|
-
verifyHeader(chunk, ...expected)
|
|
138
|
-
{
|
|
139
|
-
for (const expect of expected)
|
|
140
|
-
{
|
|
141
|
-
if (chunk.header.toLowerCase() === expect.toLowerCase())
|
|
142
|
-
{
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
SpessaSynthGroupEnd();
|
|
147
|
-
this.parsingError(`Invalid DLS chunk header! Expected "${expected.toString()}" got "${chunk.header.toLowerCase()}"`);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* @param text {string}
|
|
152
|
-
* @param expected {string}
|
|
153
|
-
*/
|
|
154
|
-
verifyText(text, expected)
|
|
155
|
-
{
|
|
156
|
-
if (text.toLowerCase() !== expected.toLowerCase())
|
|
157
|
-
{
|
|
158
|
-
SpessaSynthGroupEnd();
|
|
159
|
-
this.parsingError(`FourCC error: Expected "${expected.toLowerCase()}" got "${text.toLowerCase()}"`);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* @param error {string}
|
|
165
|
-
*/
|
|
166
|
-
parsingError(error)
|
|
167
|
-
{
|
|
168
|
-
throw new Error(`DLS parse error: ${error} The file may be corrupted.`);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
destroySoundBank()
|
|
172
|
-
{
|
|
173
|
-
super.destroySoundBank();
|
|
174
|
-
delete this.dataArray;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
DLSSoundFont.prototype.readDLSInstrumentList = readDLSInstrumentList;
|
|
179
|
-
DLSSoundFont.prototype.readDLSInstrument = readDLSInstrument;
|
|
180
|
-
DLSSoundFont.prototype.readLart = readLart;
|
|
181
|
-
DLSSoundFont.prototype.readDLSSamples = readDLSSamples;
|
|
182
|
-
|
|
183
|
-
export { DLSSoundFont };
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { DecodedModulator } from "../basic_soundfont/modulator.js";
|
|
2
|
-
|
|
3
|
-
import { generatorTypes } from "../basic_soundfont/generator_types.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @enum {number}
|
|
7
|
-
*/
|
|
8
|
-
export const DLSSources = {
|
|
9
|
-
none: 0x0,
|
|
10
|
-
modLfo: 0x1,
|
|
11
|
-
velocity: 0x2,
|
|
12
|
-
keyNum: 0x3,
|
|
13
|
-
volEnv: 0x4,
|
|
14
|
-
modEnv: 0x5,
|
|
15
|
-
pitchWheel: 0x6,
|
|
16
|
-
polyPressure: 0x7,
|
|
17
|
-
channelPressure: 0x8,
|
|
18
|
-
vibratoLfo: 0x9,
|
|
19
|
-
|
|
20
|
-
modulationWheel: 0x81,
|
|
21
|
-
volume: 0x87,
|
|
22
|
-
pan: 0x8a,
|
|
23
|
-
expression: 0x8b,
|
|
24
|
-
// note: these are flipped unintentionally in DLS2 table 9. Argh!
|
|
25
|
-
chorus: 0xdd,
|
|
26
|
-
reverb: 0xdb,
|
|
27
|
-
|
|
28
|
-
pitchWheelRange: 0x100,
|
|
29
|
-
fineTune: 0x101,
|
|
30
|
-
coarseTune: 0x102
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export const DEFAULT_DLS_REVERB = new DecodedModulator(
|
|
34
|
-
0x00DB,
|
|
35
|
-
0x0,
|
|
36
|
-
generatorTypes.reverbEffectsSend,
|
|
37
|
-
1000,
|
|
38
|
-
0
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
export const DEFAULT_DLS_CHORUS = new DecodedModulator(
|
|
42
|
-
0x00DD,
|
|
43
|
-
0x0,
|
|
44
|
-
generatorTypes.chorusEffectsSend,
|
|
45
|
-
1000,
|
|
46
|
-
0
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
export const DLS_1_NO_VIBRATO_MOD = new DecodedModulator(
|
|
50
|
-
0x0081,
|
|
51
|
-
0x0,
|
|
52
|
-
generatorTypes.vibLfoToPitch,
|
|
53
|
-
0,
|
|
54
|
-
0
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
export const DLS_1_NO_VIBRATO_PRESSURE = new DecodedModulator(
|
|
58
|
-
0x000D,
|
|
59
|
-
0x0,
|
|
60
|
-
generatorTypes.vibLfoToPitch,
|
|
61
|
-
0,
|
|
62
|
-
0
|
|
63
|
-
);
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { Generator } from "../basic_soundfont/generator.js";
|
|
2
|
-
import { generatorTypes } from "../basic_soundfont/generator_types.js";
|
|
3
|
-
import { BasicInstrumentZone } from "../basic_soundfont/basic_instrument_zone.js";
|
|
4
|
-
|
|
5
|
-
export class DLSZone extends BasicInstrumentZone
|
|
6
|
-
{
|
|
7
|
-
/**
|
|
8
|
-
* @param inst {BasicInstrument}
|
|
9
|
-
*/
|
|
10
|
-
constructor(inst)
|
|
11
|
-
{
|
|
12
|
-
super(inst);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @param attenuationCb {number} with EMU correction
|
|
17
|
-
* @param loopingMode {number} the sfont one
|
|
18
|
-
* @param loop {{start: number, end: number}}
|
|
19
|
-
* @param sampleKey {number}
|
|
20
|
-
* @param sample {BasicSample}
|
|
21
|
-
* @param sampleID {number}
|
|
22
|
-
* @param samplePitchCorrection {number} cents
|
|
23
|
-
*/
|
|
24
|
-
setWavesample(
|
|
25
|
-
attenuationCb,
|
|
26
|
-
loopingMode,
|
|
27
|
-
loop,
|
|
28
|
-
sampleKey,
|
|
29
|
-
sample,
|
|
30
|
-
sampleID,
|
|
31
|
-
samplePitchCorrection
|
|
32
|
-
)
|
|
33
|
-
{
|
|
34
|
-
if (loopingMode !== 0)
|
|
35
|
-
{
|
|
36
|
-
this.addGenerators(new Generator(generatorTypes.sampleModes, loopingMode));
|
|
37
|
-
}
|
|
38
|
-
this.addGenerators(new Generator(generatorTypes.initialAttenuation, attenuationCb));
|
|
39
|
-
|
|
40
|
-
// correct tuning if needed
|
|
41
|
-
samplePitchCorrection -= sample.samplePitchCorrection;
|
|
42
|
-
const coarseTune = Math.trunc(samplePitchCorrection / 100);
|
|
43
|
-
if (coarseTune !== 0)
|
|
44
|
-
{
|
|
45
|
-
this.addGenerators(new Generator(generatorTypes.coarseTune, coarseTune));
|
|
46
|
-
}
|
|
47
|
-
const fineTune = samplePitchCorrection - (coarseTune * 100);
|
|
48
|
-
if (fineTune !== 0)
|
|
49
|
-
{
|
|
50
|
-
this.addGenerators(new Generator(generatorTypes.fineTune, fineTune));
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// correct loop if needed
|
|
54
|
-
if (loopingMode !== 0)
|
|
55
|
-
{
|
|
56
|
-
const diffStart = loop.start - sample.sampleLoopStartIndex;
|
|
57
|
-
const diffEnd = loop.end - sample.sampleLoopEndIndex;
|
|
58
|
-
if (diffStart !== 0)
|
|
59
|
-
{
|
|
60
|
-
const fine = diffStart % 32768;
|
|
61
|
-
this.addGenerators(new Generator(generatorTypes.startloopAddrsOffset, fine));
|
|
62
|
-
// coarse generator uses 32768 samples per step
|
|
63
|
-
const coarse = Math.trunc(diffStart / 32768);
|
|
64
|
-
if (coarse !== 0)
|
|
65
|
-
{
|
|
66
|
-
this.addGenerators(new Generator(generatorTypes.startloopAddrsCoarseOffset, coarse));
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
if (diffEnd !== 0)
|
|
70
|
-
{
|
|
71
|
-
const fine = diffEnd % 32768;
|
|
72
|
-
this.addGenerators(new Generator(generatorTypes.endloopAddrsOffset, fine));
|
|
73
|
-
// coarse generator uses 32768 samples per step
|
|
74
|
-
const coarse = Math.trunc(diffEnd / 32768);
|
|
75
|
-
if (coarse !== 0)
|
|
76
|
-
{
|
|
77
|
-
this.addGenerators(new Generator(generatorTypes.endloopAddrsCoarseOffset, coarse));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
// correct the key if needed
|
|
82
|
-
if (sampleKey !== sample.samplePitch)
|
|
83
|
-
{
|
|
84
|
-
this.addGenerators(new Generator(generatorTypes.overridingRootKey, sampleKey));
|
|
85
|
-
}
|
|
86
|
-
// add sample
|
|
87
|
-
this.setSample(sample);
|
|
88
|
-
}
|
|
89
|
-
}
|