spessasynth_lib 3.13.0 → 3.14.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.
- package/@types/index.d.ts +2 -1
- package/@types/sequencer/sequencer.d.ts +5 -0
- package/@types/synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.d.ts +5 -0
- package/@types/utils/encode_vorbis.d.ts +10 -0
- package/README.md +23 -13
- package/index.js +2 -2
- package/midi_parser/rmidi_writer.js +1 -1
- package/package.json +1 -1
- package/sequencer/sequencer.js +8 -0
- package/synthetizer/worklet_processor.min.js +6 -6
- package/synthetizer/worklet_system/combine_class.js +104 -0
- package/synthetizer/worklet_system/main_processor.js +13 -109
- package/synthetizer/worklet_system/worklet_methods/program_control.js +6 -0
- package/synthetizer/worklet_system/worklet_methods/reset_controllers.js +2 -0
- package/synthetizer/worklet_system/worklet_methods/snapshot.js +3 -0
- package/synthetizer/worklet_system/worklet_methods/system_exclusive.js +219 -82
- package/synthetizer/worklet_system/worklet_methods/tuning_control.js +15 -0
- package/synthetizer/worklet_system/worklet_methods/voice_control.js +2 -1
- package/synthetizer/worklet_system/worklet_processor.js +1 -1
- package/synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.js +2 -0
package/@types/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { VOICE_CAP } from './synthetizer/synthetizer.js';
|
|
|
5
5
|
import { SoundFont2 } from './soundfont/soundfont.js';
|
|
6
6
|
import { trimSoundfont } from './soundfont/write/soundfont_trimmer.js';
|
|
7
7
|
import { modulatorSources } from './soundfont/read/modulators.js';
|
|
8
|
+
import { encodeVorbis } from "./utils/encode_vorbis.js";
|
|
8
9
|
import { MIDI } from './midi_parser/midi_loader.js';
|
|
9
10
|
import { IndexedByteArray } from './utils/indexed_array.js';
|
|
10
11
|
import { writeMIDIFile } from './midi_parser/midi_writer.js';
|
|
@@ -31,4 +32,4 @@ import { readBytesAsUintBigEndian } from './utils/byte_functions/big_endian.js';
|
|
|
31
32
|
import { NON_CC_INDEX_OFFSET } from './synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.js';
|
|
32
33
|
import { ALL_CHANNELS_OR_DIFFERENT_ACTION } from './synthetizer/worklet_system/message_protocol/worklet_message.js';
|
|
33
34
|
import { WORKLET_URL_ABSOLUTE } from './synthetizer/worklet_url.js';
|
|
34
|
-
export { Sequencer, Synthetizer, DEFAULT_PERCUSSION, VOICE_CAP, SoundFont2, trimSoundfont, modulatorSources,
|
|
35
|
+
export { Sequencer, Synthetizer, DEFAULT_PERCUSSION, VOICE_CAP, SoundFont2, trimSoundfont, modulatorSources, encodeVorbis, MIDI, IndexedByteArray, writeMIDIFile, writeRMIDI, applySnapshotToMIDI, modifyMIDI, audioBufferToWav, SpessaSynthLogging, SpessaSynthGroup, SpessaSynthTable, SpessaSynthGroupEnd, SpessaSynthInfo, SpessaSynthWarn, SpessaSynthGroupCollapsed, midiControllers, messageTypes, MIDIDeviceHandler, WebMidiLinkHandler, arrayToHexString, consoleColors, formatTitle, formatTime, readBytesAsUintBigEndian, NON_CC_INDEX_OFFSET, ALL_CHANNELS_OR_DIFFERENT_ACTION, WORKLET_URL_ABSOLUTE };
|
|
@@ -25,6 +25,11 @@ export class Sequencer {
|
|
|
25
25
|
*/
|
|
26
26
|
_playbackRate: number;
|
|
27
27
|
songIndex: number;
|
|
28
|
+
/**
|
|
29
|
+
* Indicates if the current midiData property has dummy data in it (not yet loaded)
|
|
30
|
+
* @type {boolean}
|
|
31
|
+
*/
|
|
32
|
+
hasDummyData: boolean;
|
|
28
33
|
_loop: boolean;
|
|
29
34
|
/**
|
|
30
35
|
* Indicates whether the sequencer has finished playing a sequence
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* @property {Float32Array} customControllers - array of custom (not sf2) control values such as RPN pitch tuning, transpose, modulation depth, etc.
|
|
6
6
|
*
|
|
7
7
|
* @property {number} channelTransposeKeyShift - key shift of the channel
|
|
8
|
+
* @property {Int8Array} channelOctaveTuning - the tuning for octave on this channel
|
|
8
9
|
* @property {boolean} holdPedal - indicates whether the hold pedal is active
|
|
9
10
|
* @property {boolean} drumChannel - indicates whether the channel is a drum channel
|
|
10
11
|
*
|
|
@@ -72,6 +73,10 @@ export type WorkletProcessorChannel = {
|
|
|
72
73
|
* - key shift of the channel
|
|
73
74
|
*/
|
|
74
75
|
channelTransposeKeyShift: number;
|
|
76
|
+
/**
|
|
77
|
+
* - the tuning for octave on this channel
|
|
78
|
+
*/
|
|
79
|
+
channelOctaveTuning: Int8Array;
|
|
75
80
|
/**
|
|
76
81
|
* - indicates whether the hold pedal is active
|
|
77
82
|
*/
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {function} EncodeVorbisFunction
|
|
3
|
+
* @param channelAudioData {Float32Array[]}
|
|
4
|
+
* @param sampleRate {number}
|
|
5
|
+
* @param channels {number}
|
|
6
|
+
* @param quality {number} -0.1 to 1
|
|
7
|
+
* @returns {Uint8Array}
|
|
8
|
+
*/
|
|
9
|
+
export function encodeVorbis(channelAudioData: Float32Array[], channels: number, sampleRate: number, quality: number): Uint8Array;
|
|
10
|
+
export type EncodeVorbisFunction = Function;
|
package/README.md
CHANGED
|
@@ -26,6 +26,7 @@ document.getElementById("button").onclick = async () => {
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
## Current Features
|
|
29
|
+
|
|
29
30
|
### Easy Integration
|
|
30
31
|
- **Modular design:** Easy integration into other projects (load what you need)
|
|
31
32
|
- **[Detailed documentation:](https://github.com/spessasus/SpessaSynth/wiki/Home)** With [examples!](https://github.com/spessasus/SpessaSynth/wiki/Usage-As-Library#examples)
|
|
@@ -35,32 +36,38 @@ document.getElementById("button").onclick = async () => {
|
|
|
35
36
|
### Powerful SoundFont Synthesizer
|
|
36
37
|
- Suitable for both **real-time** and **offline** synthesis
|
|
37
38
|
- **Excellent SoundFont support:**
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
39
|
+
- **Generator Support**
|
|
40
|
+
- **Modulator Support:** _First (to my knowledge) JavaScript SoundFont synth with that feature!_
|
|
41
|
+
- **SoundFont3 Support:** Play compressed SoundFonts!
|
|
42
|
+
- **Can load very large SoundFonts:** up to 4GB! _Note: Only Firefox handles this well; Chromium has a hard-coded memory limit_
|
|
42
43
|
- **Reverb and chorus support:** [customizable!](https://github.com/spessasus/SpessaSynth/wiki/Synthetizer-Class#effects-configuration-object)
|
|
43
44
|
- **Export audio files** using [OfflineAudioContext](https://developer.mozilla.org/en-US/docs/Web/API/OfflineAudioContext)
|
|
44
45
|
- **[Custom modulators for additional controllers](https://github.com/spessasus/SpessaSynth/wiki/Modulator-Class#default-modulators):** Why not?
|
|
45
|
-
- **Written using AudioWorklets:**
|
|
46
|
+
- **Written using AudioWorklets:**
|
|
47
|
+
- Runs in a **separate thread** for maximum performance
|
|
48
|
+
- Supported by all modern browsers
|
|
46
49
|
- **Unlimited channel count:** Your CPU is the limit!
|
|
47
50
|
- **Various MIDI Standards Support:**
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
+
- **MIDI Controller Support:** Default supported controllers [here](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-controllers)
|
|
52
|
+
- **MIDI Tuning Standard Support:** [more info here](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#midi-tuning-standard)
|
|
53
|
+
- [Full **RPN** and limited **NRPN** support](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-registered-parameters)
|
|
54
|
+
- Supports some [**Roland GS** and **Yamaha XG** system exclusives](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-system-exclusives)
|
|
55
|
+
|
|
51
56
|
- **High-performance mode:** Play Rush E! _note: may kill your browser ;)_
|
|
52
|
-
- **Written in pure JavaScript using the WebAudio API:** Supported by all modern browsers!
|
|
53
57
|
|
|
54
58
|
### Built-in Powerful and Fast Sequencer
|
|
55
59
|
- **Supports MIDI formats 0, 1, and 2:** _note: format 2 support is experimental as it's very, very rare_
|
|
56
60
|
- **[Multi-Port MIDI](https://github.com/spessasus/SpessaSynth/wiki/About-Multi-Port) support:** More than 16 channels!
|
|
57
61
|
- **Smart preloading:** Only preloads the samples used in the MIDI file for smooth playback (down to key and velocity!)
|
|
58
62
|
- **Lyrics support:** Add karaoke to your program!
|
|
59
|
-
- **Raw lyrics available:** Decode in any encoding! (Kanji? No problem!)
|
|
63
|
+
- **Raw lyrics available:** Decode in any encoding! *(Kanji? No problem!)*
|
|
64
|
+
- **Runs in Audio Thread as well:** Never blocks the main thread
|
|
65
|
+
- **Loop points support:** Ensures seamless loops
|
|
60
66
|
|
|
61
67
|
### Read and Write SoundFont and MIDI Files with Ease
|
|
62
68
|
#### Read and write MIDI files
|
|
63
69
|
- **Smart name detection:** Handles incorrectly formatted and non-standard track names
|
|
70
|
+
- **Raw name available:** Decode in any encoding! *(Kanji? No problem!)*
|
|
64
71
|
- **Port detection during load time:** Manage ports and channels easily!
|
|
65
72
|
- **Used channels on track:** Quickly determine which channels are used
|
|
66
73
|
- **Key range detection:** Detect the key range of the MIDI
|
|
@@ -70,15 +77,18 @@ document.getElementById("button").onclick = async () => {
|
|
|
70
77
|
- **Easy saving:** Save with just [one function!](https://github.com/spessasus/SpessaSynth/wiki/Writing-MIDI-Files#writemidifile)
|
|
71
78
|
#### Read and write [RMID files with embedded SF2 soundfonts](https://github.com/spessasus/SpessaSynth/wiki/About-RMIDI)
|
|
72
79
|
- **Compression and trimming support:** Reduce a MIDI file with a 1GB soundfont to **as small as 5MB**!
|
|
80
|
+
- **Automatic bank shifting and validation:** Every soundfont *just works!*
|
|
81
|
+
- **Metadata support:** Add title, artist, album name and cover and more! And of course read them too! *(In any encoding!)*
|
|
82
|
+
- **Compatible with [Falcosoft Midi Player 6!](https://falcosoft.hu/softwares.html#midiplayer)**
|
|
73
83
|
- **Easy saving:** [As simple as saving a MIDI file!](https://github.com/spessasus/SpessaSynth/wiki/Writing-MIDI-Files#writermidi)
|
|
74
84
|
#### Read and write SoundFont2 files
|
|
75
|
-
- **
|
|
76
|
-
- **
|
|
85
|
+
- **Easy info access:** Just an [object of strings!](https://github.com/spessasus/SpessaSynth/wiki/SoundFont2-Class#soundfontinfo)
|
|
86
|
+
- **Smart trimming:** Trim the SoundFont to only include samples used in the MIDI *(down to key and velocity!)*
|
|
87
|
+
- **sf3 conversion:** Compress SoundFont2 files to SoundFont3 with variable quality!
|
|
77
88
|
- **Easy saving:** Also just [one function!](https://github.com/spessasus/SpessaSynth/wiki/SoundFont2-Class#write)
|
|
78
89
|
#### Read and write SoundFont3 files
|
|
79
90
|
- Same features as SoundFont2 but with now with **Ogg Vorbis compression!**
|
|
80
91
|
- **Variable compression quality:** You choose between file size and quality!
|
|
81
92
|
- **Compression preserving:** Avoid decompressing and recompressing uncompressed samples for minimal quality loss!
|
|
82
|
-
|
|
83
93
|
## License
|
|
84
94
|
MIT License, except for the stbvorbis_sync.js in the `externals` folder which is licensed under the Apache-2.0 license.
|
package/index.js
CHANGED
|
@@ -26,8 +26,8 @@ import { NON_CC_INDEX_OFFSET } from './synthetizer/worklet_system/worklet_utilit
|
|
|
26
26
|
import { modulatorSources } from './soundfont/read/modulators.js';
|
|
27
27
|
import { ALL_CHANNELS_OR_DIFFERENT_ACTION } from './synthetizer/worklet_system/message_protocol/worklet_message.js';
|
|
28
28
|
import { trimSoundfont } from './soundfont/write/soundfont_trimmer.js';
|
|
29
|
-
import { OggVorbisEncoder } from './externals/libvorbis/OggVorbisEncoder.min.js';
|
|
30
29
|
import { WORKLET_URL_ABSOLUTE } from './synthetizer/worklet_url.js'
|
|
30
|
+
import { encodeVorbis} from "./utils/encode_vorbis.js";
|
|
31
31
|
|
|
32
32
|
// Export modules
|
|
33
33
|
export {
|
|
@@ -41,7 +41,7 @@ export {
|
|
|
41
41
|
SoundFont2,
|
|
42
42
|
trimSoundfont,
|
|
43
43
|
modulatorSources,
|
|
44
|
-
|
|
44
|
+
encodeVorbis,
|
|
45
45
|
|
|
46
46
|
// MIDI
|
|
47
47
|
MIDI,
|
package/package.json
CHANGED
package/sequencer/sequencer.js
CHANGED
|
@@ -69,6 +69,12 @@ export class Sequencer
|
|
|
69
69
|
|
|
70
70
|
this.songIndex = 0;
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Indicates if the current midiData property has dummy data in it (not yet loaded)
|
|
74
|
+
* @type {boolean}
|
|
75
|
+
*/
|
|
76
|
+
this.hasDummyData = true;
|
|
77
|
+
|
|
72
78
|
this._loop = true;
|
|
73
79
|
|
|
74
80
|
/**
|
|
@@ -206,6 +212,7 @@ export class Sequencer
|
|
|
206
212
|
let songChangeData = messageData[0];
|
|
207
213
|
this.songIndex = messageData[1];
|
|
208
214
|
this.midiData = songChangeData;
|
|
215
|
+
this.hasDummyData = false;
|
|
209
216
|
this.absoluteStartTime = 0;
|
|
210
217
|
this.duration = this.midiData.duration;
|
|
211
218
|
Object.entries(this.onSongChange).forEach((callback) => callback[1](songChangeData));
|
|
@@ -327,6 +334,7 @@ export class Sequencer
|
|
|
327
334
|
this.pause();
|
|
328
335
|
// add some dummy data
|
|
329
336
|
this.midiData = DUMMY_MIDI_DATA;
|
|
337
|
+
this.hasDummyData = true;
|
|
330
338
|
this.duration = 99999;
|
|
331
339
|
this._sendMessage(WorkletSequencerMessageType.loadNewSongList, midiBuffers);
|
|
332
340
|
this.songIndex = 0;
|