spessasynth_lib 3.23.11 → 3.23.13
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/@types/index.d.ts +8 -1
- package/@types/midi_parser/basic_midi.d.ts +7 -116
- package/@types/midi_parser/midi_builder.d.ts +3 -0
- package/@types/midi_parser/midi_data.d.ts +27 -118
- package/@types/midi_parser/midi_editor.d.ts +71 -27
- package/@types/midi_parser/midi_loader.d.ts +4 -0
- package/@types/midi_parser/midi_sequence.d.ts +124 -0
- package/@types/midi_parser/midi_writer.d.ts +1 -1
- package/@types/midi_parser/rmidi_writer.d.ts +1 -0
- package/@types/sequencer/sequencer.d.ts +3 -1
- package/@types/soundfont/basic_soundfont/basic_sample.d.ts +9 -8
- package/@types/soundfont/read_sf2/samples.d.ts +1 -1
- package/index.js +17 -3
- package/midi_parser/basic_midi.js +7 -124
- package/midi_parser/midi_builder.js +3 -0
- package/midi_parser/midi_data.js +11 -127
- package/midi_parser/midi_editor.js +32 -18
- package/midi_parser/midi_loader.js +5 -0
- package/midi_parser/midi_sequence.js +133 -0
- package/midi_parser/midi_writer.js +5 -1
- package/midi_parser/rmidi_writer.js +6 -1
- package/package.json +1 -1
- package/sequencer/sequencer.js +3 -6
- package/sequencer/worklet_sequencer/process_event.js +12 -1
- package/sequencer/worklet_sequencer/sequencer_message.js +1 -1
- package/sequencer/worklet_sequencer/worklet_sequencer.js +0 -1
- package/soundfont/basic_soundfont/basic_sample.js +38 -10
- package/soundfont/basic_soundfont/write_sf2/sdta.js +5 -2
- package/soundfont/read_sf2/samples.js +6 -3
- package/synthetizer/worklet_processor.min.js +11 -11
- package/synthetizer/worklet_system/main_processor.js +1 -1
- package/synthetizer/worklet_system/snapshot/snapshot.js +311 -0
- package/synthetizer/worklet_system/worklet_methods/data_entry.js +0 -14
- package/synthetizer/worklet_system/worklet_methods/note_off.js +1 -1
- package/synthetizer/worklet_system/worklet_methods/snapshot.js +0 -145
|
@@ -35,7 +35,7 @@ export const WorkletSequencerMessageType = {
|
|
|
35
35
|
export const WorkletSequencerReturnMessageType = {
|
|
36
36
|
midiEvent: 0, // [...midiEventBytes<number>]
|
|
37
37
|
songChange: 1, // [midiData<MidiData>, songIndex<number>, isAutoPlayed<boolean>]
|
|
38
|
-
textEvent: 2, // [messageData<number[]>, statusByte<number]
|
|
38
|
+
textEvent: 2, // [messageData<number[]>, statusByte<number>, lyricsIndex<number>]
|
|
39
39
|
timeChange: 3, // newAbsoluteTime<number>
|
|
40
40
|
pause: 4, // no data
|
|
41
41
|
getMIDI: 5, // midiData<MIDI>
|
|
@@ -5,18 +5,21 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { SpessaSynthWarn } from "../../utils/loggin.js";
|
|
7
7
|
|
|
8
|
+
// should be reasonable for most cases
|
|
9
|
+
const RESAMPLE_RATE = 48000;
|
|
10
|
+
|
|
8
11
|
export class BasicSample
|
|
9
12
|
{
|
|
10
13
|
/**
|
|
11
14
|
* The basic representation of a soundfont sample
|
|
12
|
-
* @param sampleName {string}
|
|
13
|
-
* @param sampleRate {number}
|
|
14
|
-
* @param samplePitch {number}
|
|
15
|
-
* @param samplePitchCorrection {number}
|
|
16
|
-
* @param sampleLink {number}
|
|
17
|
-
* @param sampleType {number}
|
|
18
|
-
* @param loopStart {number} relative to sample start
|
|
19
|
-
* @param loopEnd {number} relative to sample start
|
|
15
|
+
* @param sampleName {string} The sample's name
|
|
16
|
+
* @param sampleRate {number} The sample's rate in Hz
|
|
17
|
+
* @param samplePitch {number} The sample's pitch as a MIDI note number
|
|
18
|
+
* @param samplePitchCorrection {number} The sample's pitch correction in cents
|
|
19
|
+
* @param sampleLink {number} The sample's link, currently unused
|
|
20
|
+
* @param sampleType {number} The sample's type, an enum
|
|
21
|
+
* @param loopStart {number} The sample's loop start relative to the sample start in sample points
|
|
22
|
+
* @param loopEnd {number} The sample's loop end relative to the sample start in sample points
|
|
20
23
|
*/
|
|
21
24
|
constructor(
|
|
22
25
|
sampleName,
|
|
@@ -110,6 +113,23 @@ export class BasicSample
|
|
|
110
113
|
return uint8;
|
|
111
114
|
}
|
|
112
115
|
|
|
116
|
+
resampleData(newSampleRate)
|
|
117
|
+
{
|
|
118
|
+
let audioData = this.getAudioData();
|
|
119
|
+
const ratio = newSampleRate / this.sampleRate;
|
|
120
|
+
const resampled = new Float32Array(Math.floor(audioData.length * ratio));
|
|
121
|
+
for (let i = 0; i < resampled.length; i++)
|
|
122
|
+
{
|
|
123
|
+
resampled[i] = audioData[Math.floor(i * (1 / ratio))];
|
|
124
|
+
}
|
|
125
|
+
audioData = resampled;
|
|
126
|
+
this.sampleRate = newSampleRate;
|
|
127
|
+
// adjust loop points
|
|
128
|
+
this.sampleLoopStartIndex = Math.floor(this.sampleLoopStartIndex * ratio);
|
|
129
|
+
this.sampleLoopEndIndex = Math.floor(this.sampleLoopEndIndex * ratio);
|
|
130
|
+
this.sampleData = audioData;
|
|
131
|
+
}
|
|
132
|
+
|
|
113
133
|
/**
|
|
114
134
|
* @param quality {number}
|
|
115
135
|
* @param encodeVorbis {EncodeVorbisFunction}
|
|
@@ -124,7 +144,14 @@ export class BasicSample
|
|
|
124
144
|
// compress, always mono!
|
|
125
145
|
try
|
|
126
146
|
{
|
|
127
|
-
|
|
147
|
+
// if the sample rate is too low or too high, resample
|
|
148
|
+
let audioData = this.getAudioData();
|
|
149
|
+
if (this.sampleRate < 8000 || this.sampleRate > 96000)
|
|
150
|
+
{
|
|
151
|
+
this.resampleData(RESAMPLE_RATE);
|
|
152
|
+
audioData = this.getAudioData();
|
|
153
|
+
}
|
|
154
|
+
this.compressedData = encodeVorbis([audioData], 1, this.sampleRate, quality);
|
|
128
155
|
// flag as compressed
|
|
129
156
|
this.sampleType |= 0x10;
|
|
130
157
|
this.isCompressed = true;
|
|
@@ -134,7 +161,8 @@ export class BasicSample
|
|
|
134
161
|
SpessaSynthWarn(`Failed to compress ${this.sampleName}. Leaving as uncompressed!`);
|
|
135
162
|
this.isCompressed = false;
|
|
136
163
|
this.compressedData = undefined;
|
|
137
|
-
|
|
164
|
+
// flag as uncompressed
|
|
165
|
+
this.sampleType &= 0xEF;
|
|
138
166
|
}
|
|
139
167
|
|
|
140
168
|
}
|
|
@@ -24,11 +24,14 @@ export function getSDTA(smplStartOffsets, smplEndOffsets, compress, quality, vor
|
|
|
24
24
|
}
|
|
25
25
|
const r = s.getRawData();
|
|
26
26
|
SpessaSynthInfo(
|
|
27
|
-
`%cEncoded sample %c${i}. ${s.sampleName}%c of %c${this.samples.length}
|
|
27
|
+
`%cEncoded sample %c${i}. ${s.sampleName}%c of %c${this.samples.length}%c. Compressed: %c${s.isCompressed}%c.`,
|
|
28
28
|
consoleColors.info,
|
|
29
29
|
consoleColors.recognized,
|
|
30
30
|
consoleColors.info,
|
|
31
|
-
consoleColors.recognized
|
|
31
|
+
consoleColors.recognized,
|
|
32
|
+
consoleColors.info,
|
|
33
|
+
s.isCompressed ? consoleColors.recognized : consoleColors.unrecognized,
|
|
34
|
+
consoleColors.info
|
|
32
35
|
);
|
|
33
36
|
return r;
|
|
34
37
|
});
|
|
@@ -72,7 +72,7 @@ export class LoadedSample extends BasicSample
|
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* Get raw data, whether it's compressed or not as we simply write it to the file
|
|
75
|
-
* @return {Uint8Array}
|
|
75
|
+
* @return {Uint8Array} either s16 or vorbis data
|
|
76
76
|
*/
|
|
77
77
|
getRawData()
|
|
78
78
|
{
|
|
@@ -90,7 +90,8 @@ export class LoadedSample extends BasicSample
|
|
|
90
90
|
{
|
|
91
91
|
if (!this.isDataRaw)
|
|
92
92
|
{
|
|
93
|
-
|
|
93
|
+
// encode the f32 into s16 manually
|
|
94
|
+
super.getRawData();
|
|
94
95
|
}
|
|
95
96
|
const dataStartIndex = smplArr.currentIndex;
|
|
96
97
|
return smplArr.slice(dataStartIndex + this.sampleStartIndex, dataStartIndex + this.sampleEndIndex);
|
|
@@ -123,7 +124,9 @@ export class LoadedSample extends BasicSample
|
|
|
123
124
|
}
|
|
124
125
|
catch (e)
|
|
125
126
|
{
|
|
126
|
-
|
|
127
|
+
// do not error out, fill with silence
|
|
128
|
+
SpessaSynthWarn(`Error decoding sample ${this.sampleName}: ${e}`);
|
|
129
|
+
this.sampleData = new Float32Array(this.sampleLoopEndIndex + 1);
|
|
127
130
|
}
|
|
128
131
|
}
|
|
129
132
|
|