Comparing version 1.0.1 to 1.1.0
# Changelog | ||
## v1.1.0 | ||
- Add APIs for player status and seekings (`seekPlayer` etc.) | ||
- Add APIs for 'sequencer' processings | ||
- Add 'waitForReady' API | ||
## v1.0.0 | ||
- Initial version (using [fluidsynth-emscripten v2.0.1-em](https://github.com/jet2jet/fluidsynth-emscripten/releases/tag/v2.0.1-em)) |
/*! | ||
fluid-js version 1.0.0 | ||
fluid-js version 1.1.0 | ||
@@ -141,5 +141,5 @@ @license | ||
/*!***************************************!*\ | ||
!*** ./src/main/index.ts + 2 modules ***! | ||
!*** ./src/main/index.ts + 7 modules ***! | ||
\***************************************/ | ||
/*! exports provided: Constants, Synthesizer, AudioWorkletNodeSynthesizer */ | ||
/*! exports provided: Constants, Synthesizer, waitForReady, AudioWorkletNodeSynthesizer */ | ||
/***/ (function(module, __webpack_exports__, __webpack_require__) { | ||
@@ -152,12 +152,181 @@ | ||
// CONCATENATED MODULE: ./src/main/Synthesizer.ts | ||
// CONCATENATED MODULE: ./src/main/PointerType.ts | ||
const INVALID_POINTER = 0; | ||
// CONCATENATED MODULE: ./src/main/Sequencer.ts | ||
const _module = typeof AudioWorkletGlobalScope !== 'undefined' ? | ||
AudioWorkletGlobalScope.wasmModule : Module; | ||
const _fs = _module.FS; | ||
function makeEvent(event) { | ||
const ev = _module._new_fluid_event(); | ||
switch (event.type) { | ||
case 1 /* Note */: | ||
case 'note': | ||
_module._fluid_event_note(ev, event.channel, event.key, event.vel, event.duration); | ||
break; | ||
case 2 /* NoteOn */: | ||
case 'noteon': | ||
case 'note-on': | ||
_module._fluid_event_noteon(ev, event.channel, event.key, event.vel); | ||
break; | ||
case 3 /* NoteOff */: | ||
case 'noteoff': | ||
case 'note-off': | ||
_module._fluid_event_noteoff(ev, event.channel, event.key); | ||
break; | ||
case 4 /* AllSoundsOff */: | ||
case 'allsoundsoff': | ||
case 'all-sounds-off': | ||
_module._fluid_event_all_sounds_off(ev, event.channel); | ||
break; | ||
case 5 /* AllNotesOff */: | ||
case 'allnotesoff': | ||
case 'all-notes-off': | ||
_module._fluid_event_all_notes_off(ev, event.channel); | ||
break; | ||
case 6 /* BankSelect */: | ||
case 'bankselect': | ||
case 'bank-select': | ||
_module._fluid_event_bank_select(ev, event.channel, event.bank); | ||
break; | ||
case 7 /* ProgramChange */: | ||
case 'programchange': | ||
case 'program-change': | ||
_module._fluid_event_program_change(ev, event.channel, event.preset); | ||
break; | ||
case 8 /* ProgramSelect */: | ||
case 'programselect': | ||
case 'program-select': | ||
_module._fluid_event_program_select(ev, event.channel, event.sfontId, event.bank, event.preset); | ||
break; | ||
case 9 /* ControlChange */: | ||
case 'controlchange': | ||
case 'control-change': | ||
_module._fluid_event_control_change(ev, event.channel, event.control, event.value); | ||
break; | ||
case 10 /* PitchBend */: | ||
case 'pitchbend': | ||
case 'pitch-bend': | ||
_module._fluid_event_pitch_bend(ev, event.channel, event.value); | ||
break; | ||
case 11 /* PitchWheelSensitivity */: | ||
case 'pitchwheelsens': | ||
case 'pitchwheelsensitivity': | ||
case 'pitch-wheel-sens': | ||
case 'pitch-wheel-sensitivity': | ||
_module._fluid_event_pitch_wheelsens(ev, event.channel, event.value); | ||
break; | ||
case 12 /* Modulation */: | ||
case 'modulation': | ||
_module._fluid_event_modulation(ev, event.channel, event.value); | ||
break; | ||
case 13 /* Sustain */: | ||
case 'sustain': | ||
_module._fluid_event_sustain(ev, event.channel, event.value); | ||
break; | ||
case 14 /* Pan */: | ||
case 'pan': | ||
_module._fluid_event_pan(ev, event.channel, event.value); | ||
break; | ||
case 15 /* Volume */: | ||
case 'volume': | ||
_module._fluid_event_volume(ev, event.channel, event.value); | ||
break; | ||
case 16 /* ReverbSend */: | ||
case 'reverb': | ||
case 'reverbsend': | ||
case 'reverb-send': | ||
_module._fluid_event_reverb_send(ev, event.channel, event.value); | ||
break; | ||
case 17 /* ChorusSend */: | ||
case 'chorus': | ||
case 'chorussend': | ||
case 'chorus-send': | ||
_module._fluid_event_chorus_send(ev, event.channel, event.value); | ||
break; | ||
case 18 /* KeyPressure */: | ||
case 'keypressure': | ||
case 'key-pressure': | ||
case 'aftertouch': | ||
_module._fluid_event_key_pressure(ev, event.channel, event.key, event.value); | ||
break; | ||
case 19 /* ChannelPressure */: | ||
case 'channelpressure': | ||
case 'channel-pressure': | ||
case 'channel-aftertouch': | ||
_module._fluid_event_channel_pressure(ev, event.channel, event.value); | ||
break; | ||
case 20 /* SystemReset */: | ||
case 'systemreset': | ||
case 'system-reset': | ||
_module._fluid_event_system_reset(ev); | ||
break; | ||
default: | ||
// 'typeof event' must be 'never' | ||
_module._delete_fluid_event(ev); | ||
return null; | ||
} | ||
return ev; | ||
} | ||
/** @internal */ | ||
class Sequencer_Sequencer { | ||
constructor() { | ||
this._seq = INVALID_POINTER; | ||
} | ||
/** @internal */ | ||
_initialize() { | ||
this.close(); | ||
this._seq = _module._new_fluid_sequencer2(0); | ||
return Promise.resolve(); | ||
} | ||
close() { | ||
if (this._seq !== INVALID_POINTER) { | ||
_module._delete_fluid_sequencer(this._seq); | ||
this._seq = INVALID_POINTER; | ||
} | ||
} | ||
registerSynthesizer(synth) { | ||
let val; | ||
if (typeof synth === 'number') { | ||
val = synth; | ||
} | ||
else if (synth instanceof Synthesizer_Synthesizer) { | ||
val = synth.getRawSynthesizer(); | ||
} | ||
else { | ||
return Promise.reject(new TypeError('\'synth\' is not a compatible type instance')); | ||
} | ||
_module._fluid_sequencer_register_fluidsynth(this._seq, val); | ||
return Promise.resolve(); | ||
} | ||
setTimeScale(scale) { | ||
_module._fluid_sequencer_set_time_scale(this._seq, scale); | ||
} | ||
getTimeScale() { | ||
return Promise.resolve(_module._fluid_sequencer_get_time_scale(this._seq)); | ||
} | ||
getTick() { | ||
return Promise.resolve(_module._fluid_sequencer_get_tick(this._seq)); | ||
} | ||
sendEventAt(event, tick, isAbsolute) { | ||
const ev = makeEvent(event); | ||
if (ev !== null) { | ||
_module._fluid_sequencer_send_at(this._seq, ev, tick, isAbsolute ? 1 : 0); | ||
_module._delete_fluid_event(ev); | ||
} | ||
} | ||
} | ||
// CONCATENATED MODULE: ./src/main/Synthesizer.ts | ||
const Synthesizer_module = typeof AudioWorkletGlobalScope !== 'undefined' ? | ||
AudioWorkletGlobalScope.wasmModule : Module; | ||
const _fs = Synthesizer_module.FS; | ||
// wrapper to use String type | ||
const fluid_synth_error = _module.cwrap('fluid_synth_error', 'string', ['number']); | ||
const fluid_synth_sfload = _module.cwrap('fluid_synth_sfload', 'number', ['number', 'string', 'number']); | ||
const malloc = _module._malloc.bind(_module); | ||
const free = _module._free.bind(_module); | ||
const fluid_synth_error = Synthesizer_module.cwrap('fluid_synth_error', 'string', ['number']); | ||
const fluid_synth_sfload = Synthesizer_module.cwrap('fluid_synth_sfload', 'number', ['number', 'string', 'number']); | ||
const malloc = Synthesizer_module._malloc.bind(Synthesizer_module); | ||
const free = Synthesizer_module._free.bind(Synthesizer_module); | ||
function makeRandomFileName(type, ext) { | ||
@@ -167,5 +336,5 @@ return `/${type}-r${Math.random() * 65535}-${Math.random() * 65535}${ext}`; | ||
/** Default implementation of ISynthesizer */ | ||
class Synthesizer { | ||
class Synthesizer_Synthesizer { | ||
constructor() { | ||
this._settings = _module._new_fluid_settings(); | ||
this._settings = Synthesizer_module._new_fluid_settings(); | ||
this._synth = INVALID_POINTER; | ||
@@ -194,5 +363,5 @@ this._player = INVALID_POINTER; | ||
this.close(); | ||
this._synth = _module._new_fluid_synth(this._settings); | ||
_module._fluid_synth_set_gain(this._synth, this._gain); | ||
_module._fluid_synth_set_sample_rate(this._synth, sampleRate); | ||
this._synth = Synthesizer_module._new_fluid_synth(this._settings); | ||
Synthesizer_module._fluid_synth_set_gain(this._synth, this._gain); | ||
Synthesizer_module._fluid_synth_set_sample_rate(this._synth, sampleRate); | ||
this._initPlayer(); | ||
@@ -205,3 +374,3 @@ } | ||
this._closePlayer(); | ||
_module._delete_fluid_synth(this._synth); | ||
Synthesizer_module._delete_fluid_synth(this._synth); | ||
this._synth = INVALID_POINTER; | ||
@@ -211,3 +380,3 @@ } | ||
return this._synth !== INVALID_POINTER && | ||
_module._fluid_synth_get_active_voice_count(this._synth) > 0; | ||
Synthesizer_module._fluid_synth_get_active_voice_count(this._synth) > 0; | ||
} | ||
@@ -219,3 +388,3 @@ setInterpolation(value, channel) { | ||
} | ||
_module._fluid_synth_set_interp_method(this._synth, channel, value); | ||
Synthesizer_module._fluid_synth_set_interp_method(this._synth, channel, value); | ||
} | ||
@@ -227,4 +396,4 @@ getGain() { | ||
this.ensureInitialized(); | ||
_module._fluid_synth_set_gain(this._synth, gain); | ||
this._gain = _module._fluid_synth_get_gain(this._synth); | ||
Synthesizer_module._fluid_synth_set_gain(this._synth, gain); | ||
this._gain = Synthesizer_module._fluid_synth_get_gain(this._synth); | ||
} | ||
@@ -249,3 +418,3 @@ waitForVoicesStopped() { | ||
this.flushFramesSync(); | ||
_module._fluid_synth_sfunload(this._synth, id, 1); | ||
Synthesizer_module._fluid_synth_sfunload(this._synth, id, 1); | ||
} | ||
@@ -257,3 +426,3 @@ unloadSFontAsync(id) { | ||
return this.flushFramesAsync().then(() => { | ||
_module._fluid_synth_sfunload(this._synth, id, 1); | ||
Synthesizer_module._fluid_synth_sfunload(this._synth, id, 1); | ||
}); | ||
@@ -263,7 +432,7 @@ } | ||
this.ensureInitialized(); | ||
return Promise.resolve(_module._fluid_synth_get_bank_offset(this._synth, id)); | ||
return Promise.resolve(Synthesizer_module._fluid_synth_get_bank_offset(this._synth, id)); | ||
} | ||
setSFontBankOffset(id, offset) { | ||
this.ensureInitialized(); | ||
_module._fluid_synth_set_bank_offset(this._synth, id, offset); | ||
Synthesizer_module._fluid_synth_set_bank_offset(this._synth, id, offset); | ||
} | ||
@@ -285,4 +454,4 @@ render(outBuffer) { | ||
this.renderRaw(memLeft, memRight, frameCount); | ||
const aLeft = new Float32Array(_module.HEAPU8.buffer, memLeft, frameCount); | ||
const aRight = channels >= 2 ? new Float32Array(_module.HEAPU8.buffer, memRight, frameCount) : null; | ||
const aLeft = new Float32Array(Synthesizer_module.HEAPU8.buffer, memLeft, frameCount); | ||
const aRight = channels >= 2 ? new Float32Array(Synthesizer_module.HEAPU8.buffer, memRight, frameCount) : null; | ||
if ('numberOfChannels' in outBuffer) { | ||
@@ -304,21 +473,21 @@ outBuffer.copyToChannel(aLeft, 0, 0); | ||
midiNoteOn(chan, key, vel) { | ||
_module._fluid_synth_noteon(this._synth, chan, key, vel); | ||
Synthesizer_module._fluid_synth_noteon(this._synth, chan, key, vel); | ||
} | ||
midiNoteOff(chan, key) { | ||
_module._fluid_synth_noteoff(this._synth, chan, key); | ||
Synthesizer_module._fluid_synth_noteoff(this._synth, chan, key); | ||
} | ||
midiKeyPressure(chan, key, val) { | ||
_module._fluid_synth_key_pressure(this._synth, chan, key, val); | ||
Synthesizer_module._fluid_synth_key_pressure(this._synth, chan, key, val); | ||
} | ||
midiControl(chan, ctrl, val) { | ||
_module._fluid_synth_cc(this._synth, chan, ctrl, val); | ||
Synthesizer_module._fluid_synth_cc(this._synth, chan, ctrl, val); | ||
} | ||
midiProgramChange(chan, prognum) { | ||
_module._fluid_synth_program_change(this._synth, chan, prognum); | ||
Synthesizer_module._fluid_synth_program_change(this._synth, chan, prognum); | ||
} | ||
midiChannelPressure(chan, val) { | ||
_module._fluid_synth_channel_pressure(this._synth, chan, val); | ||
Synthesizer_module._fluid_synth_channel_pressure(this._synth, chan, val); | ||
} | ||
midiPitchBend(chan, val) { | ||
_module._fluid_synth_pitch_bend(this._synth, chan, val); | ||
Synthesizer_module._fluid_synth_pitch_bend(this._synth, chan, val); | ||
} | ||
@@ -328,28 +497,28 @@ midiSysEx(data) { | ||
const mem = malloc(len); | ||
_module.HEAPU8.set(data, mem); | ||
_module._fluid_synth_sysex(this._synth, mem, len, INVALID_POINTER, INVALID_POINTER, INVALID_POINTER, 0); | ||
Synthesizer_module.HEAPU8.set(data, mem); | ||
Synthesizer_module._fluid_synth_sysex(this._synth, mem, len, INVALID_POINTER, INVALID_POINTER, INVALID_POINTER, 0); | ||
} | ||
midiPitchWheelSensitivity(chan, val) { | ||
_module._fluid_synth_pitch_wheel_sens(this._synth, chan, val); | ||
Synthesizer_module._fluid_synth_pitch_wheel_sens(this._synth, chan, val); | ||
} | ||
midiBankSelect(chan, bank) { | ||
_module._fluid_synth_bank_select(this._synth, chan, bank); | ||
Synthesizer_module._fluid_synth_bank_select(this._synth, chan, bank); | ||
} | ||
midiSFontSelect(chan, sfontId) { | ||
_module._fluid_synth_sfont_select(this._synth, chan, sfontId); | ||
Synthesizer_module._fluid_synth_sfont_select(this._synth, chan, sfontId); | ||
} | ||
midiUnsetProgram(chan) { | ||
_module._fluid_synth_unset_program(this._synth, chan); | ||
Synthesizer_module._fluid_synth_unset_program(this._synth, chan); | ||
} | ||
midiProgramReset() { | ||
_module._fluid_synth_program_reset(this._synth); | ||
Synthesizer_module._fluid_synth_program_reset(this._synth); | ||
} | ||
midiSystemReset() { | ||
_module._fluid_synth_system_reset(this._synth); | ||
Synthesizer_module._fluid_synth_system_reset(this._synth); | ||
} | ||
midiAllNotesOff(chan) { | ||
_module._fluid_synth_all_notes_off(this._synth, typeof chan === 'undefined' ? -1 : chan); | ||
Synthesizer_module._fluid_synth_all_notes_off(this._synth, typeof chan === 'undefined' ? -1 : chan); | ||
} | ||
midiAllSoundsOff(chan) { | ||
_module._fluid_synth_all_sounds_off(this._synth, typeof chan === 'undefined' ? -1 : chan); | ||
Synthesizer_module._fluid_synth_all_sounds_off(this._synth, typeof chan === 'undefined' ? -1 : chan); | ||
} | ||
@@ -359,3 +528,3 @@ midiSetChannelType(chan, isDrum) { | ||
// CHANNEL_TYPE_DRUM = 1 | ||
_module._fluid_synth_set_channel_type(this._synth, chan, isDrum ? 1 : 0); | ||
Synthesizer_module._fluid_synth_set_channel_type(this._synth, chan, isDrum ? 1 : 0); | ||
} | ||
@@ -367,3 +536,3 @@ resetPlayer() { | ||
this._closePlayer(); | ||
this._player = _module._new_fluid_player(this._synth); | ||
this._player = Synthesizer_module._new_fluid_player(this._synth); | ||
return this._player !== INVALID_POINTER ? Promise.resolve() : | ||
@@ -378,3 +547,3 @@ Promise.reject(new Error('Out of memory')); | ||
this.stopPlayer(); | ||
_module._delete_fluid_player(p); | ||
Synthesizer_module._delete_fluid_player(p); | ||
this._player = INVALID_POINTER; | ||
@@ -384,3 +553,3 @@ } | ||
if (this._playerPlaying) { | ||
const status = _module._fluid_player_get_status(this._player); | ||
const status = Synthesizer_module._fluid_player_get_status(this._player); | ||
if (status === 1 /*FLUID_PLAYER_PLAYING*/) { | ||
@@ -397,4 +566,4 @@ return true; | ||
const mem = malloc(len); | ||
_module.HEAPU8.set(new Uint8Array(bin), mem); | ||
const r = _module._fluid_player_add_mem(this._player, mem, len); | ||
Synthesizer_module.HEAPU8.set(new Uint8Array(bin), mem); | ||
const r = Synthesizer_module._fluid_player_add_mem(this._player, mem, len); | ||
free(mem); | ||
@@ -408,3 +577,3 @@ return r !== -1 ? Promise.resolve() : Promise.reject(new Error(fluid_synth_error(this._synth))); | ||
} | ||
if (_module._fluid_player_play(this._player) === -1) { | ||
if (Synthesizer_module._fluid_player_play(this._player) === -1) { | ||
return Promise.reject(new Error(fluid_synth_error(this._synth))); | ||
@@ -428,5 +597,5 @@ } | ||
} | ||
_module._fluid_player_stop(p); | ||
_module._fluid_player_join(p); | ||
_module._fluid_synth_all_sounds_off(this._synth, -1); | ||
Synthesizer_module._fluid_player_stop(p); | ||
Synthesizer_module._fluid_player_join(p); | ||
Synthesizer_module._fluid_synth_all_sounds_off(this._synth, -1); | ||
if (this._playerDefer) { | ||
@@ -438,2 +607,22 @@ this._playerDefer.resolve(); | ||
} | ||
retrievePlayerCurrentTick() { | ||
this.ensurePlayerInitialized(); | ||
return Promise.resolve(Synthesizer_module._fluid_player_get_current_tick(this._player)); | ||
} | ||
retrievePlayerTotalTicks() { | ||
this.ensurePlayerInitialized(); | ||
return Promise.resolve(Synthesizer_module._fluid_player_get_total_ticks(this._player)); | ||
} | ||
retrievePlayerBpm() { | ||
this.ensurePlayerInitialized(); | ||
return Promise.resolve(Synthesizer_module._fluid_player_get_bpm(this._player)); | ||
} | ||
retrievePlayerMIDITempo() { | ||
this.ensurePlayerInitialized(); | ||
return Promise.resolve(Synthesizer_module._fluid_player_get_midi_tempo(this._player)); | ||
} | ||
seekPlayer(ticks) { | ||
this.ensurePlayerInitialized(); | ||
Synthesizer_module._fluid_player_seek(this._player, ticks); | ||
} | ||
/** @internal */ | ||
@@ -454,3 +643,3 @@ ensureInitialized() { | ||
renderRaw(memLeft, memRight, frameCount) { | ||
_module._fluid_synth_write_float(this._synth, frameCount, memLeft, 0, 1, memRight, 0, 1); | ||
Synthesizer_module._fluid_synth_write_float(this._synth, frameCount, memLeft, 0, 1, memRight, 0, 1); | ||
} | ||
@@ -503,62 +692,221 @@ /** @internal */ | ||
} | ||
/** | ||
* Create the sequencer object for this class. | ||
*/ | ||
static createSequencer() { | ||
const seq = new Sequencer_Sequencer(); | ||
return seq._initialize().then(() => seq); | ||
} | ||
} | ||
// CONCATENATED MODULE: ./src/main/AudioWorkletNodeSynthesizer.ts | ||
/** An synthesizer object with AudioWorkletNode */ | ||
class AudioWorkletNodeSynthesizer { | ||
constructor() { | ||
this._status = { | ||
playing: false, | ||
playerPlaying: false | ||
// CONCATENATED MODULE: ./src/main/waitForReady.ts | ||
const waitForReady_module = typeof AudioWorkletGlobalScope !== 'undefined' ? | ||
AudioWorkletGlobalScope.wasmModule : Module; | ||
const promiseWasmInitialized = new Promise((resolve) => { | ||
if (waitForReady_module.calledRun) { | ||
resolve(); | ||
} | ||
else { | ||
const fn = waitForReady_module.onRuntimeInitialized; | ||
waitForReady_module.onRuntimeInitialized = () => { | ||
resolve(); | ||
if (fn) { | ||
fn(); | ||
} | ||
}; | ||
this._defers = {}; | ||
this._deferId = 0; | ||
this._port = null; | ||
this._node = null; | ||
this._gain = 0.5 /* Gain */; | ||
} | ||
/** @internal */ | ||
onMessage(ev) { | ||
const data = ev.data; | ||
if (data.method === "updateStatus" /* UpdateStatus */) { | ||
this._status = data.val; | ||
}); | ||
/** | ||
* Returns the Promise object which resolves when the synthesizer engine is ready. | ||
*/ | ||
function waitForReady() { | ||
return promiseWasmInitialized; | ||
} | ||
// CONCATENATED MODULE: ./src/main/MethodMessaging.ts | ||
/** @internal */ | ||
function initializeCallPort(port, hookMessage) { | ||
const instance = { | ||
port: port, | ||
defers: {}, | ||
deferId: 0 | ||
}; | ||
port.addEventListener('message', (e) => processReturnMessage(instance.defers, hookMessage, e)); | ||
port.start(); | ||
return instance; | ||
} | ||
function processReturnMessage(defers, hook, e) { | ||
const data = e.data; | ||
if (!data) { | ||
return; | ||
} | ||
if (hook && hook(data)) { | ||
return; | ||
} | ||
const defer = defers[data.id]; | ||
if (defer) { | ||
delete defers[data.id]; | ||
if ('error' in data) { | ||
defer.reject(data.error); | ||
} | ||
else { | ||
const defer = this._defers[data.id]; | ||
if (defer) { | ||
delete this._defers[data.id]; | ||
if ('error' in data) { | ||
defer.reject(data.error); | ||
} | ||
else { | ||
defer.resolve(data.val); | ||
} | ||
defer.resolve(data.val); | ||
} | ||
} | ||
else { | ||
if ('error' in data) { | ||
throw data.error; | ||
} | ||
} | ||
} | ||
/** @internal */ | ||
function postCall({ port }, method, args) { | ||
port.postMessage({ | ||
id: -1, method, args | ||
}); | ||
} | ||
/** @internal */ | ||
function postCallWithPromise(instance, method, args) { | ||
const id = instance.deferId++; | ||
if (instance.deferId === Infinity || instance.deferId < 0) { | ||
instance.deferId = 0; | ||
} | ||
const promise = new Promise((resolve, reject) => { | ||
instance.defers[id] = { resolve, reject }; | ||
}); | ||
instance.port.postMessage({ | ||
id, method, args | ||
}); | ||
return promise; | ||
} | ||
/** @internal */ | ||
function initializeReturnPort(port, promiseInitialized, targetObjectHolder, hookMessage) { | ||
const instance = { | ||
port: port | ||
}; | ||
if (promiseInitialized) { | ||
port.addEventListener('message', (e) => { | ||
const data = e.data; | ||
if (!data) { | ||
return; | ||
} | ||
else { | ||
if ('error' in data) { | ||
throw data.error; | ||
} | ||
promiseInitialized.then(() => processCallMessage(instance.port, data, targetObjectHolder, hookMessage)); | ||
}); | ||
} | ||
else { | ||
port.addEventListener('message', (e) => { | ||
const data = e.data; | ||
if (!data) { | ||
return; | ||
} | ||
processCallMessage(instance.port, data, targetObjectHolder, hookMessage); | ||
}); | ||
} | ||
port.start(); | ||
return instance; | ||
} | ||
function processCallMessage(port, data, targetObjectHolder, hook) { | ||
if (hook && hook(data)) { | ||
return; | ||
} | ||
const target = targetObjectHolder(); | ||
if (!target[data.method]) { | ||
postReturnError(port, data.id, data.method, new Error('Not implemented')); | ||
} | ||
else { | ||
try { | ||
postReturnImpl(port, data.id, data.method, target[data.method].apply(target, data.args)); | ||
} | ||
catch (e) { | ||
postReturnError(port, data.id, data.method, e); | ||
} | ||
} | ||
/** @internal */ | ||
postCall(method, args) { | ||
this._port.postMessage({ | ||
id: -1, method, args | ||
} | ||
/** @internal */ | ||
function postReturn(instance, id, method, value) { | ||
postReturnImpl(instance.port, id, method, value); | ||
} | ||
function postReturnImpl(port, id, method, value) { | ||
if (value instanceof Promise) { | ||
value.then((v) => { | ||
if (id >= 0) { | ||
port.postMessage({ | ||
id, | ||
method, | ||
val: v | ||
}); | ||
} | ||
}, (error) => { | ||
port.postMessage({ | ||
id, | ||
method, | ||
error | ||
}); | ||
}); | ||
} | ||
/** @internal */ | ||
postCallWithPromise(method, args) { | ||
const id = this._deferId++; | ||
if (this._deferId === Infinity || this._deferId < 0) { | ||
this._deferId = 0; | ||
} | ||
const promise = new Promise((resolve, reject) => { | ||
this._defers[id] = { resolve, reject }; | ||
else { | ||
port.postMessage({ | ||
id, | ||
method, | ||
val: value | ||
}); | ||
this._port.postMessage({ | ||
id, method, args | ||
}); | ||
return promise; | ||
} | ||
} | ||
function postReturnError(port, id, method, error) { | ||
port.postMessage({ | ||
id, | ||
method, | ||
error | ||
}); | ||
} | ||
// CONCATENATED MODULE: ./src/main/WorkletSequencer.ts | ||
/** @internal */ | ||
class WorkletSequencer_WorkletSequencer { | ||
constructor(port) { | ||
this._messaging = initializeCallPort(port); | ||
} | ||
close() { | ||
postCall(this._messaging, 'close', []); | ||
} | ||
registerSynthesizer(synth) { | ||
let val; | ||
if (synth instanceof AudioWorkletNodeSynthesizer_AudioWorkletNodeSynthesizer) { | ||
val = synth._getRawSynthesizer(); | ||
} | ||
else { | ||
return Promise.reject(new TypeError('\'synth\' is not a compatible type instance')); | ||
} | ||
return val.then((v) => postCallWithPromise(this._messaging, 'registerSynthesizer', [v])); | ||
} | ||
setTimeScale(scale) { | ||
postCall(this._messaging, 'setTimeScale', [scale]); | ||
} | ||
getTimeScale() { | ||
return postCallWithPromise(this._messaging, 'getTimeScale', []); | ||
} | ||
getTick() { | ||
return postCallWithPromise(this._messaging, 'getTick', []); | ||
} | ||
sendEventAt(event, tick, isAbsolute) { | ||
postCall(this._messaging, 'sendEventAt', [event, tick, isAbsolute]); | ||
} | ||
} | ||
// CONCATENATED MODULE: ./src/main/AudioWorkletNodeSynthesizer.ts | ||
/** An synthesizer object with AudioWorkletNode */ | ||
class AudioWorkletNodeSynthesizer_AudioWorkletNodeSynthesizer { | ||
constructor() { | ||
this._status = { | ||
playing: false, | ||
playerPlaying: false | ||
}; | ||
this._messaging = null; | ||
this._node = null; | ||
this._gain = 0.5 /* Gain */; | ||
} | ||
/** Audio node for this synthesizer */ | ||
@@ -576,10 +924,13 @@ get node() { | ||
this._node = node; | ||
const port = node.port; | ||
this._port = port; | ||
port.addEventListener('message', this.onMessage.bind(this)); | ||
port.start(); | ||
this._messaging = initializeCallPort(node.port, (data) => { | ||
if (data.method === "updateStatus" /* UpdateStatus */) { | ||
this._status = data.val; | ||
return true; | ||
} | ||
return false; | ||
}); | ||
return node; | ||
} | ||
isInitialized() { | ||
return this._port !== null; | ||
return this._messaging !== null; | ||
} | ||
@@ -590,3 +941,3 @@ init(_sampleRate) { | ||
// call init instead of close | ||
this.postCall('init', [0]); | ||
postCall(this._messaging, 'init', [0]); | ||
} | ||
@@ -597,3 +948,3 @@ isPlaying() { | ||
setInterpolation(value, channel) { | ||
this.postCall('setInterpolation', [value, channel]); | ||
postCall(this._messaging, 'setInterpolation', [value, channel]); | ||
} | ||
@@ -605,4 +956,4 @@ getGain() { | ||
this._gain = gain; | ||
this.postCallWithPromise('setGain', [gain]).then(() => { | ||
return this.postCallWithPromise('getGain', []); | ||
postCallWithPromise(this._messaging, 'setGain', [gain]).then(() => { | ||
return postCallWithPromise(this._messaging, 'getGain', []); | ||
}).then((value) => { | ||
@@ -613,18 +964,18 @@ this._gain = value; | ||
waitForVoicesStopped() { | ||
return this.postCallWithPromise('waitForVoicesStopped', []); | ||
return postCallWithPromise(this._messaging, 'waitForVoicesStopped', []); | ||
} | ||
loadSFont(bin) { | ||
return this.postCallWithPromise('loadSFont', [bin]); | ||
return postCallWithPromise(this._messaging, 'loadSFont', [bin]); | ||
} | ||
unloadSFont(id) { | ||
this.postCall('unloadSFont', [id]); | ||
postCall(this._messaging, 'unloadSFont', [id]); | ||
} | ||
unloadSFontAsync(id) { | ||
return this.postCallWithPromise('unloadSFont', [id]); | ||
return postCallWithPromise(this._messaging, 'unloadSFont', [id]); | ||
} | ||
getSFontBankOffset(id) { | ||
return this.postCallWithPromise('getSFontBankOffset', [id]); | ||
return postCallWithPromise(this._messaging, 'getSFontBankOffset', [id]); | ||
} | ||
setSFontBankOffset(id, offset) { | ||
this.postCall('setSFontBankOffset', [id, offset]); | ||
postCall(this._messaging, 'setSFontBankOffset', [id, offset]); | ||
} | ||
@@ -635,54 +986,54 @@ render() { | ||
midiNoteOn(chan, key, vel) { | ||
this.postCall('midiNoteOn', [chan, key, vel]); | ||
postCall(this._messaging, 'midiNoteOn', [chan, key, vel]); | ||
} | ||
midiNoteOff(chan, key) { | ||
this.postCall('midiNoteOff', [chan, key]); | ||
postCall(this._messaging, 'midiNoteOff', [chan, key]); | ||
} | ||
midiKeyPressure(chan, key, val) { | ||
this.postCall('midiKeyPressure', [chan, key, val]); | ||
postCall(this._messaging, 'midiKeyPressure', [chan, key, val]); | ||
} | ||
midiControl(chan, ctrl, val) { | ||
this.postCall('midiControl', [chan, ctrl, val]); | ||
postCall(this._messaging, 'midiControl', [chan, ctrl, val]); | ||
} | ||
midiProgramChange(chan, prognum) { | ||
this.postCall('midiProgramChange', [chan, prognum]); | ||
postCall(this._messaging, 'midiProgramChange', [chan, prognum]); | ||
} | ||
midiChannelPressure(chan, val) { | ||
this.postCall('midiChannelPressure', [chan, val]); | ||
postCall(this._messaging, 'midiChannelPressure', [chan, val]); | ||
} | ||
midiPitchBend(chan, val) { | ||
this.postCall('midiPitchBend', [chan, val]); | ||
postCall(this._messaging, 'midiPitchBend', [chan, val]); | ||
} | ||
midiSysEx(data) { | ||
this.postCall('midiSysEx', [data]); | ||
postCall(this._messaging, 'midiSysEx', [data]); | ||
} | ||
midiPitchWheelSensitivity(chan, val) { | ||
this.postCall('midiPitchWheelSensitivity', [chan, val]); | ||
postCall(this._messaging, 'midiPitchWheelSensitivity', [chan, val]); | ||
} | ||
midiBankSelect(chan, bank) { | ||
this.postCall('midiBankSelect', [chan, bank]); | ||
postCall(this._messaging, 'midiBankSelect', [chan, bank]); | ||
} | ||
midiSFontSelect(chan, sfontId) { | ||
this.postCall('midiSFontSelect', [chan, sfontId]); | ||
postCall(this._messaging, 'midiSFontSelect', [chan, sfontId]); | ||
} | ||
midiUnsetProgram(chan) { | ||
this.postCall('midiUnsetProgram', [chan]); | ||
postCall(this._messaging, 'midiUnsetProgram', [chan]); | ||
} | ||
midiProgramReset() { | ||
this.postCall('midiProgramReset', []); | ||
postCall(this._messaging, 'midiProgramReset', []); | ||
} | ||
midiSystemReset() { | ||
this.postCall('midiSystemReset', []); | ||
postCall(this._messaging, 'midiSystemReset', []); | ||
} | ||
midiAllNotesOff(chan) { | ||
this.postCall('midiAllNotesOff', [chan]); | ||
postCall(this._messaging, 'midiAllNotesOff', [chan]); | ||
} | ||
midiAllSoundsOff(chan) { | ||
this.postCall('midiAllSoundsOff', [chan]); | ||
postCall(this._messaging, 'midiAllSoundsOff', [chan]); | ||
} | ||
midiSetChannelType(chan, isDrum) { | ||
this.postCall('midiSetChannelType', [chan, isDrum]); | ||
postCall(this._messaging, 'midiSetChannelType', [chan, isDrum]); | ||
} | ||
resetPlayer() { | ||
return this.postCallWithPromise('resetPlayer', []); | ||
return postCallWithPromise(this._messaging, 'resetPlayer', []); | ||
} | ||
@@ -693,13 +1044,41 @@ isPlayerPlaying() { | ||
addSMFDataToPlayer(bin) { | ||
return this.postCallWithPromise('addSMFDataToPlayer', [bin]); | ||
return postCallWithPromise(this._messaging, 'addSMFDataToPlayer', [bin]); | ||
} | ||
playPlayer() { | ||
return this.postCallWithPromise('playPlayer', []); | ||
return postCallWithPromise(this._messaging, 'playPlayer', []); | ||
} | ||
stopPlayer() { | ||
this.postCall('stopPlayer', []); | ||
postCall(this._messaging, 'stopPlayer', []); | ||
} | ||
retrievePlayerCurrentTick() { | ||
return postCallWithPromise(this._messaging, 'retrievePlayerCurrentTick', []); | ||
} | ||
retrievePlayerTotalTicks() { | ||
return postCallWithPromise(this._messaging, 'retrievePlayerTotalTicks', []); | ||
} | ||
retrievePlayerBpm() { | ||
return postCallWithPromise(this._messaging, 'retrievePlayerBpm', []); | ||
} | ||
retrievePlayerMIDITempo() { | ||
return postCallWithPromise(this._messaging, 'retrievePlayerMIDITempo', []); | ||
} | ||
seekPlayer(ticks) { | ||
postCall(this._messaging, 'seekPlayer', [ticks]); | ||
} | ||
waitForPlayerStopped() { | ||
return this.postCallWithPromise('waitForPlayerStopped', []); | ||
return postCallWithPromise(this._messaging, 'waitForPlayerStopped', []); | ||
} | ||
/** | ||
* Creates a sequencer instance associated with this worklet node. | ||
*/ | ||
createSequencer() { | ||
const channel = new MessageChannel(); | ||
return postCallWithPromise(this._messaging, 'createSequencer', [channel.port2]).then(() => { | ||
return new WorkletSequencer_WorkletSequencer(channel.port1); | ||
}); | ||
} | ||
/** @internal */ | ||
_getRawSynthesizer() { | ||
return postCallWithPromise(this._messaging, 'getRawSynthesizer', []); | ||
} | ||
} | ||
@@ -709,4 +1088,5 @@ | ||
/* concated harmony reexport Constants */__webpack_require__.d(__webpack_exports__, "Constants", function() { return Constants; }); | ||
/* concated harmony reexport Synthesizer */__webpack_require__.d(__webpack_exports__, "Synthesizer", function() { return Synthesizer; }); | ||
/* concated harmony reexport AudioWorkletNodeSynthesizer */__webpack_require__.d(__webpack_exports__, "AudioWorkletNodeSynthesizer", function() { return AudioWorkletNodeSynthesizer; }); | ||
/* concated harmony reexport Synthesizer */__webpack_require__.d(__webpack_exports__, "Synthesizer", function() { return Synthesizer_Synthesizer; }); | ||
/* concated harmony reexport waitForReady */__webpack_require__.d(__webpack_exports__, "waitForReady", function() { return waitForReady; }); | ||
/* concated harmony reexport AudioWorkletNodeSynthesizer */__webpack_require__.d(__webpack_exports__, "AudioWorkletNodeSynthesizer", function() { return AudioWorkletNodeSynthesizer_AudioWorkletNodeSynthesizer; }); | ||
@@ -718,2 +1098,3 @@ | ||
/***/ }) | ||
@@ -720,0 +1101,0 @@ /******/ ]); |
/*! | ||
fluid-js version 1.0.0 | ||
fluid-js version 1.1.0 | ||
@@ -30,3 +30,3 @@ @license | ||
*/ | ||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports["fluid-js"]=e():t.Fluid=e()}(this,function(){return function(t){var e={};function i(s){if(e[s])return e[s].exports;var n=e[s]={i:s,l:!1,exports:{}};return t[s].call(n.exports,n,n.exports,i),n.l=!0,n.exports}return i.m=t,i.c=e,i.d=function(t,e,s){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:s})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var s=Object.create(null);if(i.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)i.d(s,n,function(e){return t[e]}.bind(null,n));return s},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=1)}([function(t,e){},function(t,e,i){"use strict";i.r(e);var s=i(0);const n=0,r="undefined"!=typeof AudioWorkletGlobalScope?AudioWorkletGlobalScope.wasmModule:Module,l=r.FS,o=r.cwrap("fluid_synth_error","string",["number"]),h=r.cwrap("fluid_synth_sfload","number",["number","string","number"]),a=r._malloc.bind(r),_=r._free.bind(r);class d{constructor(){this._settings=r._new_fluid_settings(),this._synth=n,this._player=n,this._playerPlaying=!1,this._buffer=n,this._bufferSize=0,this._gain=.5}isInitialized(){return this._synth!==n}getRawSynthesizer(){return this._synth}createAudioNode(t,e){const i=t.createScriptProcessor(e,0,2);return i.addEventListener("audioprocess",t=>{this.render(t.outputBuffer)}),i}init(t){this.close(),this._synth=r._new_fluid_synth(this._settings),r._fluid_synth_set_gain(this._synth,this._gain),r._fluid_synth_set_sample_rate(this._synth,t),this._initPlayer()}close(){this._synth!==n&&(this._closePlayer(),r._delete_fluid_synth(this._synth),this._synth=n)}isPlaying(){return this._synth!==n&&r._fluid_synth_get_active_voice_count(this._synth)>0}setInterpolation(t,e){this.ensureInitialized(),void 0===e&&(e=-1),r._fluid_synth_set_interp_method(this._synth,e,t)}getGain(){return this._gain}setGain(t){this.ensureInitialized(),r._fluid_synth_set_gain(this._synth,t),this._gain=r._fluid_synth_get_gain(this._synth)}waitForVoicesStopped(){return this.flushFramesAsync()}loadSFont(t){this.ensureInitialized();const e=function(t,e){return`/${t}-r${65535*Math.random()}-${65535*Math.random()}${e}`}("sfont",".sf2"),i=new Uint8Array(t);l.writeFile(e,i);const s=h(this._synth,e,1);return l.unlink(e),-1===s?Promise.reject(new Error(o(this._synth))):Promise.resolve(s)}unloadSFont(t){this.ensureInitialized(),this.stopPlayer(),this.flushFramesSync(),r._fluid_synth_sfunload(this._synth,t,1)}unloadSFontAsync(t){return this.ensureInitialized(),this.stopPlayer(),this.flushFramesAsync().then(()=>{r._fluid_synth_sfunload(this._synth,t,1)})}getSFontBankOffset(t){return this.ensureInitialized(),Promise.resolve(r._fluid_synth_get_bank_offset(this._synth,t))}setSFontBankOffset(t,e){this.ensureInitialized(),r._fluid_synth_set_bank_offset(this._synth,t,e)}render(t){const e="numberOfChannels"in t?t.length:t[0].length,i="numberOfChannels"in t?t.numberOfChannels:t.length,s=4*e,l=2*s;this._bufferSize<l&&(this._buffer!==n&&_(this._buffer),this._buffer=a(l),this._bufferSize=l);const o=this._buffer,h=this._buffer+s;this.renderRaw(o,h,e);const d=new Float32Array(r.HEAPU8.buffer,o,e),u=i>=2?new Float32Array(r.HEAPU8.buffer,h,e):null;"numberOfChannels"in t?(t.copyToChannel(d,0,0),u&&t.copyToChannel(u,1,0)):(t[0].set(d),u&&t[1].set(u)),this.isPlayerPlaying()}midiNoteOn(t,e,i){r._fluid_synth_noteon(this._synth,t,e,i)}midiNoteOff(t,e){r._fluid_synth_noteoff(this._synth,t,e)}midiKeyPressure(t,e,i){r._fluid_synth_key_pressure(this._synth,t,e,i)}midiControl(t,e,i){r._fluid_synth_cc(this._synth,t,e,i)}midiProgramChange(t,e){r._fluid_synth_program_change(this._synth,t,e)}midiChannelPressure(t,e){r._fluid_synth_channel_pressure(this._synth,t,e)}midiPitchBend(t,e){r._fluid_synth_pitch_bend(this._synth,t,e)}midiSysEx(t){const e=t.byteLength,i=a(e);r.HEAPU8.set(t,i),r._fluid_synth_sysex(this._synth,i,e,n,n,n,0)}midiPitchWheelSensitivity(t,e){r._fluid_synth_pitch_wheel_sens(this._synth,t,e)}midiBankSelect(t,e){r._fluid_synth_bank_select(this._synth,t,e)}midiSFontSelect(t,e){r._fluid_synth_sfont_select(this._synth,t,e)}midiUnsetProgram(t){r._fluid_synth_unset_program(this._synth,t)}midiProgramReset(){r._fluid_synth_program_reset(this._synth)}midiSystemReset(){r._fluid_synth_system_reset(this._synth)}midiAllNotesOff(t){r._fluid_synth_all_notes_off(this._synth,void 0===t?-1:t)}midiAllSoundsOff(t){r._fluid_synth_all_sounds_off(this._synth,void 0===t?-1:t)}midiSetChannelType(t,e){r._fluid_synth_set_channel_type(this._synth,t,e?1:0)}resetPlayer(){return this._initPlayer()}_initPlayer(){return this._closePlayer(),this._player=r._new_fluid_player(this._synth),this._player!==n?Promise.resolve():Promise.reject(new Error("Out of memory"))}_closePlayer(){const t=this._player;t!==n&&(this.stopPlayer(),r._delete_fluid_player(t),this._player=n)}isPlayerPlaying(){if(this._playerPlaying){if(1===r._fluid_player_get_status(this._player))return!0;this.stopPlayer()}return!1}addSMFDataToPlayer(t){this.ensurePlayerInitialized();const e=t.byteLength,i=a(e);r.HEAPU8.set(new Uint8Array(t),i);const s=r._fluid_player_add_mem(this._player,i,e);return _(i),-1!==s?Promise.resolve():Promise.reject(new Error(o(this._synth)))}playPlayer(){if(this.ensurePlayerInitialized(),this._playerPlaying&&this.stopPlayer(),-1===r._fluid_player_play(this._player))return Promise.reject(new Error(o(this._synth)));this._playerPlaying=!0;let t=()=>{};const e=new Promise(e=>{t=e});return this._playerDefer={promise:e,resolve:t},Promise.resolve()}stopPlayer(){const t=this._player;t!==n&&this._playerPlaying&&(r._fluid_player_stop(t),r._fluid_player_join(t),r._fluid_synth_all_sounds_off(this._synth,-1),this._playerDefer&&(this._playerDefer.resolve(),this._playerDefer=void 0),this._playerPlaying=!1)}ensureInitialized(){if(this._synth===n)throw new Error("Synthesizer is not initialized")}ensurePlayerInitialized(){if(this.ensureInitialized(),this._player===n)throw new Error("Player is not initialized")}renderRaw(t,e,i){r._fluid_synth_write_float(this._synth,i,t,0,1,e,0,1)}flushFramesSync(){const t=a(524288),e=t,i=t+262144;for(;this.isPlaying();)this.renderRaw(e,i,65536);_(t)}flushFramesAsync(){if(!this.isPlaying())return Promise.resolve();const t=65536,e=4*t,i=a(2*e),s=i,n=i+e,r="undefined"!=typeof setTimeout?()=>new Promise(t=>setTimeout(t,0)):()=>Promise.resolve();function l(){return r().then(h)}const o=this;function h(){return o.isPlaying()?(o.renderRaw(s,n,t),l()):(_(i),Promise.resolve())}return l()}waitForPlayerStopped(){return this._playerDefer?this._playerDefer.promise:Promise.resolve()}}class u{constructor(){this._status={playing:!1,playerPlaying:!1},this._defers={},this._deferId=0,this._port=null,this._node=null,this._gain=.5}onMessage(t){const e=t.data;if("updateStatus"===e.method)this._status=e.val;else{const t=this._defers[e.id];if(t)delete this._defers[e.id],"error"in e?t.reject(e.error):t.resolve(e.val);else if("error"in e)throw e.error}}postCall(t,e){this._port.postMessage({id:-1,method:t,args:e})}postCallWithPromise(t,e){const i=this._deferId++;(this._deferId===1/0||this._deferId<0)&&(this._deferId=0);const s=new Promise((t,e)=>{this._defers[i]={resolve:t,reject:e}});return this._port.postMessage({id:i,method:t,args:e}),s}get node(){return this._node}createAudioNode(t){const e=new AudioWorkletNode(t,"fluid-js",{numberOfInputs:0,numberOfOutputs:1,channelCount:2,outputChannelCount:[2]});this._node=e;const i=e.port;return this._port=i,i.addEventListener("message",this.onMessage.bind(this)),i.start(),e}isInitialized(){return null!==this._port}init(t){}close(){this.postCall("init",[0])}isPlaying(){return this._status.playing}setInterpolation(t,e){this.postCall("setInterpolation",[t,e])}getGain(){return this._gain}setGain(t){this._gain=t,this.postCallWithPromise("setGain",[t]).then(()=>this.postCallWithPromise("getGain",[])).then(t=>{this._gain=t})}waitForVoicesStopped(){return this.postCallWithPromise("waitForVoicesStopped",[])}loadSFont(t){return this.postCallWithPromise("loadSFont",[t])}unloadSFont(t){this.postCall("unloadSFont",[t])}unloadSFontAsync(t){return this.postCallWithPromise("unloadSFont",[t])}getSFontBankOffset(t){return this.postCallWithPromise("getSFontBankOffset",[t])}setSFontBankOffset(t,e){this.postCall("setSFontBankOffset",[t,e])}render(){throw new Error("Unexpected call")}midiNoteOn(t,e,i){this.postCall("midiNoteOn",[t,e,i])}midiNoteOff(t,e){this.postCall("midiNoteOff",[t,e])}midiKeyPressure(t,e,i){this.postCall("midiKeyPressure",[t,e,i])}midiControl(t,e,i){this.postCall("midiControl",[t,e,i])}midiProgramChange(t,e){this.postCall("midiProgramChange",[t,e])}midiChannelPressure(t,e){this.postCall("midiChannelPressure",[t,e])}midiPitchBend(t,e){this.postCall("midiPitchBend",[t,e])}midiSysEx(t){this.postCall("midiSysEx",[t])}midiPitchWheelSensitivity(t,e){this.postCall("midiPitchWheelSensitivity",[t,e])}midiBankSelect(t,e){this.postCall("midiBankSelect",[t,e])}midiSFontSelect(t,e){this.postCall("midiSFontSelect",[t,e])}midiUnsetProgram(t){this.postCall("midiUnsetProgram",[t])}midiProgramReset(){this.postCall("midiProgramReset",[])}midiSystemReset(){this.postCall("midiSystemReset",[])}midiAllNotesOff(t){this.postCall("midiAllNotesOff",[t])}midiAllSoundsOff(t){this.postCall("midiAllSoundsOff",[t])}midiSetChannelType(t,e){this.postCall("midiSetChannelType",[t,e])}resetPlayer(){return this.postCallWithPromise("resetPlayer",[])}isPlayerPlaying(){return this._status.playerPlaying}addSMFDataToPlayer(t){return this.postCallWithPromise("addSMFDataToPlayer",[t])}playPlayer(){return this.postCallWithPromise("playPlayer",[])}stopPlayer(){this.postCall("stopPlayer",[])}waitForPlayerStopped(){return this.postCallWithPromise("waitForPlayerStopped",[])}}i.d(e,"Constants",function(){return s}),i.d(e,"Synthesizer",function(){return d}),i.d(e,"AudioWorkletNodeSynthesizer",function(){return u})}])}); | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["fluid-js"]=t():e.Fluid=t()}(this,function(){return function(e){var t={};function s(i){if(t[i])return t[i].exports;var n=t[i]={i:i,l:!1,exports:{}};return e[i].call(n.exports,n,n.exports,s),n.l=!0,n.exports}return s.m=e,s.c=t,s.d=function(e,t,i){s.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},s.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},s.t=function(e,t){if(1&t&&(e=s(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(s.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)s.d(i,n,function(t){return e[t]}.bind(null,n));return i},s.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return s.d(t,"a",t),t},s.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},s.p="",s(s.s=1)}([function(e,t){},function(e,t,s){"use strict";s.r(t);var i=s(0);const n=0,r="undefined"!=typeof AudioWorkletGlobalScope?AudioWorkletGlobalScope.wasmModule:Module;class a{constructor(){this._seq=n}_initialize(){return this.close(),this._seq=r._new_fluid_sequencer2(0),Promise.resolve()}close(){this._seq!==n&&(r._delete_fluid_sequencer(this._seq),this._seq=n)}registerSynthesizer(e){let t;if("number"==typeof e)t=e;else{if(!(e instanceof c))return Promise.reject(new TypeError("'synth' is not a compatible type instance"));t=e.getRawSynthesizer()}return r._fluid_sequencer_register_fluidsynth(this._seq,t),Promise.resolve()}setTimeScale(e){r._fluid_sequencer_set_time_scale(this._seq,e)}getTimeScale(){return Promise.resolve(r._fluid_sequencer_get_time_scale(this._seq))}getTick(){return Promise.resolve(r._fluid_sequencer_get_tick(this._seq))}sendEventAt(e,t,s){const i=function(e){const t=r._new_fluid_event();switch(e.type){case 1:case"note":r._fluid_event_note(t,e.channel,e.key,e.vel,e.duration);break;case 2:case"noteon":case"note-on":r._fluid_event_noteon(t,e.channel,e.key,e.vel);break;case 3:case"noteoff":case"note-off":r._fluid_event_noteoff(t,e.channel,e.key);break;case 4:case"allsoundsoff":case"all-sounds-off":r._fluid_event_all_sounds_off(t,e.channel);break;case 5:case"allnotesoff":case"all-notes-off":r._fluid_event_all_notes_off(t,e.channel);break;case 6:case"bankselect":case"bank-select":r._fluid_event_bank_select(t,e.channel,e.bank);break;case 7:case"programchange":case"program-change":r._fluid_event_program_change(t,e.channel,e.preset);break;case 8:case"programselect":case"program-select":r._fluid_event_program_select(t,e.channel,e.sfontId,e.bank,e.preset);break;case 9:case"controlchange":case"control-change":r._fluid_event_control_change(t,e.channel,e.control,e.value);break;case 10:case"pitchbend":case"pitch-bend":r._fluid_event_pitch_bend(t,e.channel,e.value);break;case 11:case"pitchwheelsens":case"pitchwheelsensitivity":case"pitch-wheel-sens":case"pitch-wheel-sensitivity":r._fluid_event_pitch_wheelsens(t,e.channel,e.value);break;case 12:case"modulation":r._fluid_event_modulation(t,e.channel,e.value);break;case 13:case"sustain":r._fluid_event_sustain(t,e.channel,e.value);break;case 14:case"pan":r._fluid_event_pan(t,e.channel,e.value);break;case 15:case"volume":r._fluid_event_volume(t,e.channel,e.value);break;case 16:case"reverb":case"reverbsend":case"reverb-send":r._fluid_event_reverb_send(t,e.channel,e.value);break;case 17:case"chorus":case"chorussend":case"chorus-send":r._fluid_event_chorus_send(t,e.channel,e.value);break;case 18:case"keypressure":case"key-pressure":case"aftertouch":r._fluid_event_key_pressure(t,e.channel,e.key,e.value);break;case 19:case"channelpressure":case"channel-pressure":case"channel-aftertouch":r._fluid_event_channel_pressure(t,e.channel,e.value);break;case 20:case"systemreset":case"system-reset":r._fluid_event_system_reset(t);break;default:return r._delete_fluid_event(t),null}return t}(e);null!==i&&(r._fluid_sequencer_send_at(this._seq,i,t,s?1:0),r._delete_fluid_event(i))}}const l="undefined"!=typeof AudioWorkletGlobalScope?AudioWorkletGlobalScope.wasmModule:Module,_=l.FS,o=l.cwrap("fluid_synth_error","string",["number"]),h=l.cwrap("fluid_synth_sfload","number",["number","string","number"]),u=l._malloc.bind(l),d=l._free.bind(l);class c{constructor(){this._settings=l._new_fluid_settings(),this._synth=n,this._player=n,this._playerPlaying=!1,this._buffer=n,this._bufferSize=0,this._gain=.5}isInitialized(){return this._synth!==n}getRawSynthesizer(){return this._synth}createAudioNode(e,t){const s=e.createScriptProcessor(t,0,2);return s.addEventListener("audioprocess",e=>{this.render(e.outputBuffer)}),s}init(e){this.close(),this._synth=l._new_fluid_synth(this._settings),l._fluid_synth_set_gain(this._synth,this._gain),l._fluid_synth_set_sample_rate(this._synth,e),this._initPlayer()}close(){this._synth!==n&&(this._closePlayer(),l._delete_fluid_synth(this._synth),this._synth=n)}isPlaying(){return this._synth!==n&&l._fluid_synth_get_active_voice_count(this._synth)>0}setInterpolation(e,t){this.ensureInitialized(),void 0===t&&(t=-1),l._fluid_synth_set_interp_method(this._synth,t,e)}getGain(){return this._gain}setGain(e){this.ensureInitialized(),l._fluid_synth_set_gain(this._synth,e),this._gain=l._fluid_synth_get_gain(this._synth)}waitForVoicesStopped(){return this.flushFramesAsync()}loadSFont(e){this.ensureInitialized();const t=function(e,t){return`/${e}-r${65535*Math.random()}-${65535*Math.random()}${t}`}("sfont",".sf2"),s=new Uint8Array(e);_.writeFile(t,s);const i=h(this._synth,t,1);return _.unlink(t),-1===i?Promise.reject(new Error(o(this._synth))):Promise.resolve(i)}unloadSFont(e){this.ensureInitialized(),this.stopPlayer(),this.flushFramesSync(),l._fluid_synth_sfunload(this._synth,e,1)}unloadSFontAsync(e){return this.ensureInitialized(),this.stopPlayer(),this.flushFramesAsync().then(()=>{l._fluid_synth_sfunload(this._synth,e,1)})}getSFontBankOffset(e){return this.ensureInitialized(),Promise.resolve(l._fluid_synth_get_bank_offset(this._synth,e))}setSFontBankOffset(e,t){this.ensureInitialized(),l._fluid_synth_set_bank_offset(this._synth,e,t)}render(e){const t="numberOfChannels"in e?e.length:e[0].length,s="numberOfChannels"in e?e.numberOfChannels:e.length,i=4*t,r=2*i;this._bufferSize<r&&(this._buffer!==n&&d(this._buffer),this._buffer=u(r),this._bufferSize=r);const a=this._buffer,_=this._buffer+i;this.renderRaw(a,_,t);const o=new Float32Array(l.HEAPU8.buffer,a,t),h=s>=2?new Float32Array(l.HEAPU8.buffer,_,t):null;"numberOfChannels"in e?(e.copyToChannel(o,0,0),h&&e.copyToChannel(h,1,0)):(e[0].set(o),h&&e[1].set(h)),this.isPlayerPlaying()}midiNoteOn(e,t,s){l._fluid_synth_noteon(this._synth,e,t,s)}midiNoteOff(e,t){l._fluid_synth_noteoff(this._synth,e,t)}midiKeyPressure(e,t,s){l._fluid_synth_key_pressure(this._synth,e,t,s)}midiControl(e,t,s){l._fluid_synth_cc(this._synth,e,t,s)}midiProgramChange(e,t){l._fluid_synth_program_change(this._synth,e,t)}midiChannelPressure(e,t){l._fluid_synth_channel_pressure(this._synth,e,t)}midiPitchBend(e,t){l._fluid_synth_pitch_bend(this._synth,e,t)}midiSysEx(e){const t=e.byteLength,s=u(t);l.HEAPU8.set(e,s),l._fluid_synth_sysex(this._synth,s,t,n,n,n,0)}midiPitchWheelSensitivity(e,t){l._fluid_synth_pitch_wheel_sens(this._synth,e,t)}midiBankSelect(e,t){l._fluid_synth_bank_select(this._synth,e,t)}midiSFontSelect(e,t){l._fluid_synth_sfont_select(this._synth,e,t)}midiUnsetProgram(e){l._fluid_synth_unset_program(this._synth,e)}midiProgramReset(){l._fluid_synth_program_reset(this._synth)}midiSystemReset(){l._fluid_synth_system_reset(this._synth)}midiAllNotesOff(e){l._fluid_synth_all_notes_off(this._synth,void 0===e?-1:e)}midiAllSoundsOff(e){l._fluid_synth_all_sounds_off(this._synth,void 0===e?-1:e)}midiSetChannelType(e,t){l._fluid_synth_set_channel_type(this._synth,e,t?1:0)}resetPlayer(){return this._initPlayer()}_initPlayer(){return this._closePlayer(),this._player=l._new_fluid_player(this._synth),this._player!==n?Promise.resolve():Promise.reject(new Error("Out of memory"))}_closePlayer(){const e=this._player;e!==n&&(this.stopPlayer(),l._delete_fluid_player(e),this._player=n)}isPlayerPlaying(){if(this._playerPlaying){if(1===l._fluid_player_get_status(this._player))return!0;this.stopPlayer()}return!1}addSMFDataToPlayer(e){this.ensurePlayerInitialized();const t=e.byteLength,s=u(t);l.HEAPU8.set(new Uint8Array(e),s);const i=l._fluid_player_add_mem(this._player,s,t);return d(s),-1!==i?Promise.resolve():Promise.reject(new Error(o(this._synth)))}playPlayer(){if(this.ensurePlayerInitialized(),this._playerPlaying&&this.stopPlayer(),-1===l._fluid_player_play(this._player))return Promise.reject(new Error(o(this._synth)));this._playerPlaying=!0;let e=()=>{};const t=new Promise(t=>{e=t});return this._playerDefer={promise:t,resolve:e},Promise.resolve()}stopPlayer(){const e=this._player;e!==n&&this._playerPlaying&&(l._fluid_player_stop(e),l._fluid_player_join(e),l._fluid_synth_all_sounds_off(this._synth,-1),this._playerDefer&&(this._playerDefer.resolve(),this._playerDefer=void 0),this._playerPlaying=!1)}retrievePlayerCurrentTick(){return this.ensurePlayerInitialized(),Promise.resolve(l._fluid_player_get_current_tick(this._player))}retrievePlayerTotalTicks(){return this.ensurePlayerInitialized(),Promise.resolve(l._fluid_player_get_total_ticks(this._player))}retrievePlayerBpm(){return this.ensurePlayerInitialized(),Promise.resolve(l._fluid_player_get_bpm(this._player))}retrievePlayerMIDITempo(){return this.ensurePlayerInitialized(),Promise.resolve(l._fluid_player_get_midi_tempo(this._player))}seekPlayer(e){this.ensurePlayerInitialized(),l._fluid_player_seek(this._player,e)}ensureInitialized(){if(this._synth===n)throw new Error("Synthesizer is not initialized")}ensurePlayerInitialized(){if(this.ensureInitialized(),this._player===n)throw new Error("Player is not initialized")}renderRaw(e,t,s){l._fluid_synth_write_float(this._synth,s,e,0,1,t,0,1)}flushFramesSync(){const e=u(524288),t=e,s=e+262144;for(;this.isPlaying();)this.renderRaw(t,s,65536);d(e)}flushFramesAsync(){if(!this.isPlaying())return Promise.resolve();const e=65536,t=4*e,s=u(2*t),i=s,n=s+t,r="undefined"!=typeof setTimeout?()=>new Promise(e=>setTimeout(e,0)):()=>Promise.resolve();function a(){return r().then(_)}const l=this;function _(){return l.isPlaying()?(l.renderRaw(i,n,e),a()):(d(s),Promise.resolve())}return a()}waitForPlayerStopped(){return this._playerDefer?this._playerDefer.promise:Promise.resolve()}static createSequencer(){const e=new a;return e._initialize().then(()=>e)}}const y="undefined"!=typeof AudioWorkletGlobalScope?AudioWorkletGlobalScope.wasmModule:Module,f=new Promise(e=>{if(y.calledRun)e();else{const t=y.onRuntimeInitialized;y.onRuntimeInitialized=(()=>{e(),t&&t()})}});function m(){return f}function g(e,t){const s={port:e,defers:{},deferId:0};return e.addEventListener("message",e=>(function(e,t,s){const i=s.data;if(!i)return;if(t&&t(i))return;const n=e[i.id];if(n)delete e[i.id],"error"in i?n.reject(i.error):n.resolve(i.val);else if("error"in i)throw i.error})(s.defers,t,e)),e.start(),s}function p({port:e},t,s){e.postMessage({id:-1,method:t,args:s})}function P(e,t,s){const i=e.deferId++;(e.deferId===1/0||e.deferId<0)&&(e.deferId=0);const n=new Promise((t,s)=>{e.defers[i]={resolve:t,reject:s}});return e.port.postMessage({id:i,method:t,args:s}),n}class v{constructor(e){this._messaging=g(e)}close(){p(this._messaging,"close",[])}registerSynthesizer(e){let t;return e instanceof b?(t=e._getRawSynthesizer()).then(e=>P(this._messaging,"registerSynthesizer",[e])):Promise.reject(new TypeError("'synth' is not a compatible type instance"))}setTimeScale(e){p(this._messaging,"setTimeScale",[e])}getTimeScale(){return P(this._messaging,"getTimeScale",[])}getTick(){return P(this._messaging,"getTick",[])}sendEventAt(e,t,s){p(this._messaging,"sendEventAt",[e,t,s])}}class b{constructor(){this._status={playing:!1,playerPlaying:!1},this._messaging=null,this._node=null,this._gain=.5}get node(){return this._node}createAudioNode(e){const t=new AudioWorkletNode(e,"fluid-js",{numberOfInputs:0,numberOfOutputs:1,channelCount:2,outputChannelCount:[2]});return this._node=t,this._messaging=g(t.port,e=>"updateStatus"===e.method&&(this._status=e.val,!0)),t}isInitialized(){return null!==this._messaging}init(e){}close(){p(this._messaging,"init",[0])}isPlaying(){return this._status.playing}setInterpolation(e,t){p(this._messaging,"setInterpolation",[e,t])}getGain(){return this._gain}setGain(e){this._gain=e,P(this._messaging,"setGain",[e]).then(()=>P(this._messaging,"getGain",[])).then(e=>{this._gain=e})}waitForVoicesStopped(){return P(this._messaging,"waitForVoicesStopped",[])}loadSFont(e){return P(this._messaging,"loadSFont",[e])}unloadSFont(e){p(this._messaging,"unloadSFont",[e])}unloadSFontAsync(e){return P(this._messaging,"unloadSFont",[e])}getSFontBankOffset(e){return P(this._messaging,"getSFontBankOffset",[e])}setSFontBankOffset(e,t){p(this._messaging,"setSFontBankOffset",[e,t])}render(){throw new Error("Unexpected call")}midiNoteOn(e,t,s){p(this._messaging,"midiNoteOn",[e,t,s])}midiNoteOff(e,t){p(this._messaging,"midiNoteOff",[e,t])}midiKeyPressure(e,t,s){p(this._messaging,"midiKeyPressure",[e,t,s])}midiControl(e,t,s){p(this._messaging,"midiControl",[e,t,s])}midiProgramChange(e,t){p(this._messaging,"midiProgramChange",[e,t])}midiChannelPressure(e,t){p(this._messaging,"midiChannelPressure",[e,t])}midiPitchBend(e,t){p(this._messaging,"midiPitchBend",[e,t])}midiSysEx(e){p(this._messaging,"midiSysEx",[e])}midiPitchWheelSensitivity(e,t){p(this._messaging,"midiPitchWheelSensitivity",[e,t])}midiBankSelect(e,t){p(this._messaging,"midiBankSelect",[e,t])}midiSFontSelect(e,t){p(this._messaging,"midiSFontSelect",[e,t])}midiUnsetProgram(e){p(this._messaging,"midiUnsetProgram",[e])}midiProgramReset(){p(this._messaging,"midiProgramReset",[])}midiSystemReset(){p(this._messaging,"midiSystemReset",[])}midiAllNotesOff(e){p(this._messaging,"midiAllNotesOff",[e])}midiAllSoundsOff(e){p(this._messaging,"midiAllSoundsOff",[e])}midiSetChannelType(e,t){p(this._messaging,"midiSetChannelType",[e,t])}resetPlayer(){return P(this._messaging,"resetPlayer",[])}isPlayerPlaying(){return this._status.playerPlaying}addSMFDataToPlayer(e){return P(this._messaging,"addSMFDataToPlayer",[e])}playPlayer(){return P(this._messaging,"playPlayer",[])}stopPlayer(){p(this._messaging,"stopPlayer",[])}retrievePlayerCurrentTick(){return P(this._messaging,"retrievePlayerCurrentTick",[])}retrievePlayerTotalTicks(){return P(this._messaging,"retrievePlayerTotalTicks",[])}retrievePlayerBpm(){return P(this._messaging,"retrievePlayerBpm",[])}retrievePlayerMIDITempo(){return P(this._messaging,"retrievePlayerMIDITempo",[])}seekPlayer(e){p(this._messaging,"seekPlayer",[e])}waitForPlayerStopped(){return P(this._messaging,"waitForPlayerStopped",[])}createSequencer(){const e=new MessageChannel;return P(this._messaging,"createSequencer",[e.port2]).then(()=>new v(e.port1))}_getRawSynthesizer(){return P(this._messaging,"getRawSynthesizer",[])}}s.d(t,"Constants",function(){return i}),s.d(t,"Synthesizer",function(){return c}),s.d(t,"waitForReady",function(){return m}),s.d(t,"AudioWorkletNodeSynthesizer",function(){return b})}])}); | ||
//# sourceMappingURL=fluid.min.js.map |
/*! | ||
fluid-js version 1.0.0 | ||
fluid-js version 1.1.0 | ||
@@ -120,3 +120,3 @@ @license | ||
/*!**********************************************!*\ | ||
!*** ./src/main/workletEntry.ts + 2 modules ***! | ||
!*** ./src/main/workletEntry.ts + 6 modules ***! | ||
\**********************************************/ | ||
@@ -128,12 +128,181 @@ /*! no exports provided */ | ||
// CONCATENATED MODULE: ./src/main/Synthesizer.ts | ||
// CONCATENATED MODULE: ./src/main/PointerType.ts | ||
const INVALID_POINTER = 0; | ||
// CONCATENATED MODULE: ./src/main/Sequencer.ts | ||
const _module = typeof AudioWorkletGlobalScope !== 'undefined' ? | ||
AudioWorkletGlobalScope.wasmModule : Module; | ||
const _fs = _module.FS; | ||
function makeEvent(event) { | ||
const ev = _module._new_fluid_event(); | ||
switch (event.type) { | ||
case 1 /* Note */: | ||
case 'note': | ||
_module._fluid_event_note(ev, event.channel, event.key, event.vel, event.duration); | ||
break; | ||
case 2 /* NoteOn */: | ||
case 'noteon': | ||
case 'note-on': | ||
_module._fluid_event_noteon(ev, event.channel, event.key, event.vel); | ||
break; | ||
case 3 /* NoteOff */: | ||
case 'noteoff': | ||
case 'note-off': | ||
_module._fluid_event_noteoff(ev, event.channel, event.key); | ||
break; | ||
case 4 /* AllSoundsOff */: | ||
case 'allsoundsoff': | ||
case 'all-sounds-off': | ||
_module._fluid_event_all_sounds_off(ev, event.channel); | ||
break; | ||
case 5 /* AllNotesOff */: | ||
case 'allnotesoff': | ||
case 'all-notes-off': | ||
_module._fluid_event_all_notes_off(ev, event.channel); | ||
break; | ||
case 6 /* BankSelect */: | ||
case 'bankselect': | ||
case 'bank-select': | ||
_module._fluid_event_bank_select(ev, event.channel, event.bank); | ||
break; | ||
case 7 /* ProgramChange */: | ||
case 'programchange': | ||
case 'program-change': | ||
_module._fluid_event_program_change(ev, event.channel, event.preset); | ||
break; | ||
case 8 /* ProgramSelect */: | ||
case 'programselect': | ||
case 'program-select': | ||
_module._fluid_event_program_select(ev, event.channel, event.sfontId, event.bank, event.preset); | ||
break; | ||
case 9 /* ControlChange */: | ||
case 'controlchange': | ||
case 'control-change': | ||
_module._fluid_event_control_change(ev, event.channel, event.control, event.value); | ||
break; | ||
case 10 /* PitchBend */: | ||
case 'pitchbend': | ||
case 'pitch-bend': | ||
_module._fluid_event_pitch_bend(ev, event.channel, event.value); | ||
break; | ||
case 11 /* PitchWheelSensitivity */: | ||
case 'pitchwheelsens': | ||
case 'pitchwheelsensitivity': | ||
case 'pitch-wheel-sens': | ||
case 'pitch-wheel-sensitivity': | ||
_module._fluid_event_pitch_wheelsens(ev, event.channel, event.value); | ||
break; | ||
case 12 /* Modulation */: | ||
case 'modulation': | ||
_module._fluid_event_modulation(ev, event.channel, event.value); | ||
break; | ||
case 13 /* Sustain */: | ||
case 'sustain': | ||
_module._fluid_event_sustain(ev, event.channel, event.value); | ||
break; | ||
case 14 /* Pan */: | ||
case 'pan': | ||
_module._fluid_event_pan(ev, event.channel, event.value); | ||
break; | ||
case 15 /* Volume */: | ||
case 'volume': | ||
_module._fluid_event_volume(ev, event.channel, event.value); | ||
break; | ||
case 16 /* ReverbSend */: | ||
case 'reverb': | ||
case 'reverbsend': | ||
case 'reverb-send': | ||
_module._fluid_event_reverb_send(ev, event.channel, event.value); | ||
break; | ||
case 17 /* ChorusSend */: | ||
case 'chorus': | ||
case 'chorussend': | ||
case 'chorus-send': | ||
_module._fluid_event_chorus_send(ev, event.channel, event.value); | ||
break; | ||
case 18 /* KeyPressure */: | ||
case 'keypressure': | ||
case 'key-pressure': | ||
case 'aftertouch': | ||
_module._fluid_event_key_pressure(ev, event.channel, event.key, event.value); | ||
break; | ||
case 19 /* ChannelPressure */: | ||
case 'channelpressure': | ||
case 'channel-pressure': | ||
case 'channel-aftertouch': | ||
_module._fluid_event_channel_pressure(ev, event.channel, event.value); | ||
break; | ||
case 20 /* SystemReset */: | ||
case 'systemreset': | ||
case 'system-reset': | ||
_module._fluid_event_system_reset(ev); | ||
break; | ||
default: | ||
// 'typeof event' must be 'never' | ||
_module._delete_fluid_event(ev); | ||
return null; | ||
} | ||
return ev; | ||
} | ||
/** @internal */ | ||
class Sequencer_Sequencer { | ||
constructor() { | ||
this._seq = INVALID_POINTER; | ||
} | ||
/** @internal */ | ||
_initialize() { | ||
this.close(); | ||
this._seq = _module._new_fluid_sequencer2(0); | ||
return Promise.resolve(); | ||
} | ||
close() { | ||
if (this._seq !== INVALID_POINTER) { | ||
_module._delete_fluid_sequencer(this._seq); | ||
this._seq = INVALID_POINTER; | ||
} | ||
} | ||
registerSynthesizer(synth) { | ||
let val; | ||
if (typeof synth === 'number') { | ||
val = synth; | ||
} | ||
else if (synth instanceof Synthesizer_Synthesizer) { | ||
val = synth.getRawSynthesizer(); | ||
} | ||
else { | ||
return Promise.reject(new TypeError('\'synth\' is not a compatible type instance')); | ||
} | ||
_module._fluid_sequencer_register_fluidsynth(this._seq, val); | ||
return Promise.resolve(); | ||
} | ||
setTimeScale(scale) { | ||
_module._fluid_sequencer_set_time_scale(this._seq, scale); | ||
} | ||
getTimeScale() { | ||
return Promise.resolve(_module._fluid_sequencer_get_time_scale(this._seq)); | ||
} | ||
getTick() { | ||
return Promise.resolve(_module._fluid_sequencer_get_tick(this._seq)); | ||
} | ||
sendEventAt(event, tick, isAbsolute) { | ||
const ev = makeEvent(event); | ||
if (ev !== null) { | ||
_module._fluid_sequencer_send_at(this._seq, ev, tick, isAbsolute ? 1 : 0); | ||
_module._delete_fluid_event(ev); | ||
} | ||
} | ||
} | ||
// CONCATENATED MODULE: ./src/main/Synthesizer.ts | ||
const Synthesizer_module = typeof AudioWorkletGlobalScope !== 'undefined' ? | ||
AudioWorkletGlobalScope.wasmModule : Module; | ||
const _fs = Synthesizer_module.FS; | ||
// wrapper to use String type | ||
const fluid_synth_error = _module.cwrap('fluid_synth_error', 'string', ['number']); | ||
const fluid_synth_sfload = _module.cwrap('fluid_synth_sfload', 'number', ['number', 'string', 'number']); | ||
const malloc = _module._malloc.bind(_module); | ||
const free = _module._free.bind(_module); | ||
const fluid_synth_error = Synthesizer_module.cwrap('fluid_synth_error', 'string', ['number']); | ||
const fluid_synth_sfload = Synthesizer_module.cwrap('fluid_synth_sfload', 'number', ['number', 'string', 'number']); | ||
const malloc = Synthesizer_module._malloc.bind(Synthesizer_module); | ||
const free = Synthesizer_module._free.bind(Synthesizer_module); | ||
function makeRandomFileName(type, ext) { | ||
@@ -143,5 +312,5 @@ return `/${type}-r${Math.random() * 65535}-${Math.random() * 65535}${ext}`; | ||
/** Default implementation of ISynthesizer */ | ||
class Synthesizer { | ||
class Synthesizer_Synthesizer { | ||
constructor() { | ||
this._settings = _module._new_fluid_settings(); | ||
this._settings = Synthesizer_module._new_fluid_settings(); | ||
this._synth = INVALID_POINTER; | ||
@@ -170,5 +339,5 @@ this._player = INVALID_POINTER; | ||
this.close(); | ||
this._synth = _module._new_fluid_synth(this._settings); | ||
_module._fluid_synth_set_gain(this._synth, this._gain); | ||
_module._fluid_synth_set_sample_rate(this._synth, sampleRate); | ||
this._synth = Synthesizer_module._new_fluid_synth(this._settings); | ||
Synthesizer_module._fluid_synth_set_gain(this._synth, this._gain); | ||
Synthesizer_module._fluid_synth_set_sample_rate(this._synth, sampleRate); | ||
this._initPlayer(); | ||
@@ -181,3 +350,3 @@ } | ||
this._closePlayer(); | ||
_module._delete_fluid_synth(this._synth); | ||
Synthesizer_module._delete_fluid_synth(this._synth); | ||
this._synth = INVALID_POINTER; | ||
@@ -187,3 +356,3 @@ } | ||
return this._synth !== INVALID_POINTER && | ||
_module._fluid_synth_get_active_voice_count(this._synth) > 0; | ||
Synthesizer_module._fluid_synth_get_active_voice_count(this._synth) > 0; | ||
} | ||
@@ -195,3 +364,3 @@ setInterpolation(value, channel) { | ||
} | ||
_module._fluid_synth_set_interp_method(this._synth, channel, value); | ||
Synthesizer_module._fluid_synth_set_interp_method(this._synth, channel, value); | ||
} | ||
@@ -203,4 +372,4 @@ getGain() { | ||
this.ensureInitialized(); | ||
_module._fluid_synth_set_gain(this._synth, gain); | ||
this._gain = _module._fluid_synth_get_gain(this._synth); | ||
Synthesizer_module._fluid_synth_set_gain(this._synth, gain); | ||
this._gain = Synthesizer_module._fluid_synth_get_gain(this._synth); | ||
} | ||
@@ -225,3 +394,3 @@ waitForVoicesStopped() { | ||
this.flushFramesSync(); | ||
_module._fluid_synth_sfunload(this._synth, id, 1); | ||
Synthesizer_module._fluid_synth_sfunload(this._synth, id, 1); | ||
} | ||
@@ -233,3 +402,3 @@ unloadSFontAsync(id) { | ||
return this.flushFramesAsync().then(() => { | ||
_module._fluid_synth_sfunload(this._synth, id, 1); | ||
Synthesizer_module._fluid_synth_sfunload(this._synth, id, 1); | ||
}); | ||
@@ -239,7 +408,7 @@ } | ||
this.ensureInitialized(); | ||
return Promise.resolve(_module._fluid_synth_get_bank_offset(this._synth, id)); | ||
return Promise.resolve(Synthesizer_module._fluid_synth_get_bank_offset(this._synth, id)); | ||
} | ||
setSFontBankOffset(id, offset) { | ||
this.ensureInitialized(); | ||
_module._fluid_synth_set_bank_offset(this._synth, id, offset); | ||
Synthesizer_module._fluid_synth_set_bank_offset(this._synth, id, offset); | ||
} | ||
@@ -261,4 +430,4 @@ render(outBuffer) { | ||
this.renderRaw(memLeft, memRight, frameCount); | ||
const aLeft = new Float32Array(_module.HEAPU8.buffer, memLeft, frameCount); | ||
const aRight = channels >= 2 ? new Float32Array(_module.HEAPU8.buffer, memRight, frameCount) : null; | ||
const aLeft = new Float32Array(Synthesizer_module.HEAPU8.buffer, memLeft, frameCount); | ||
const aRight = channels >= 2 ? new Float32Array(Synthesizer_module.HEAPU8.buffer, memRight, frameCount) : null; | ||
if ('numberOfChannels' in outBuffer) { | ||
@@ -280,21 +449,21 @@ outBuffer.copyToChannel(aLeft, 0, 0); | ||
midiNoteOn(chan, key, vel) { | ||
_module._fluid_synth_noteon(this._synth, chan, key, vel); | ||
Synthesizer_module._fluid_synth_noteon(this._synth, chan, key, vel); | ||
} | ||
midiNoteOff(chan, key) { | ||
_module._fluid_synth_noteoff(this._synth, chan, key); | ||
Synthesizer_module._fluid_synth_noteoff(this._synth, chan, key); | ||
} | ||
midiKeyPressure(chan, key, val) { | ||
_module._fluid_synth_key_pressure(this._synth, chan, key, val); | ||
Synthesizer_module._fluid_synth_key_pressure(this._synth, chan, key, val); | ||
} | ||
midiControl(chan, ctrl, val) { | ||
_module._fluid_synth_cc(this._synth, chan, ctrl, val); | ||
Synthesizer_module._fluid_synth_cc(this._synth, chan, ctrl, val); | ||
} | ||
midiProgramChange(chan, prognum) { | ||
_module._fluid_synth_program_change(this._synth, chan, prognum); | ||
Synthesizer_module._fluid_synth_program_change(this._synth, chan, prognum); | ||
} | ||
midiChannelPressure(chan, val) { | ||
_module._fluid_synth_channel_pressure(this._synth, chan, val); | ||
Synthesizer_module._fluid_synth_channel_pressure(this._synth, chan, val); | ||
} | ||
midiPitchBend(chan, val) { | ||
_module._fluid_synth_pitch_bend(this._synth, chan, val); | ||
Synthesizer_module._fluid_synth_pitch_bend(this._synth, chan, val); | ||
} | ||
@@ -304,28 +473,28 @@ midiSysEx(data) { | ||
const mem = malloc(len); | ||
_module.HEAPU8.set(data, mem); | ||
_module._fluid_synth_sysex(this._synth, mem, len, INVALID_POINTER, INVALID_POINTER, INVALID_POINTER, 0); | ||
Synthesizer_module.HEAPU8.set(data, mem); | ||
Synthesizer_module._fluid_synth_sysex(this._synth, mem, len, INVALID_POINTER, INVALID_POINTER, INVALID_POINTER, 0); | ||
} | ||
midiPitchWheelSensitivity(chan, val) { | ||
_module._fluid_synth_pitch_wheel_sens(this._synth, chan, val); | ||
Synthesizer_module._fluid_synth_pitch_wheel_sens(this._synth, chan, val); | ||
} | ||
midiBankSelect(chan, bank) { | ||
_module._fluid_synth_bank_select(this._synth, chan, bank); | ||
Synthesizer_module._fluid_synth_bank_select(this._synth, chan, bank); | ||
} | ||
midiSFontSelect(chan, sfontId) { | ||
_module._fluid_synth_sfont_select(this._synth, chan, sfontId); | ||
Synthesizer_module._fluid_synth_sfont_select(this._synth, chan, sfontId); | ||
} | ||
midiUnsetProgram(chan) { | ||
_module._fluid_synth_unset_program(this._synth, chan); | ||
Synthesizer_module._fluid_synth_unset_program(this._synth, chan); | ||
} | ||
midiProgramReset() { | ||
_module._fluid_synth_program_reset(this._synth); | ||
Synthesizer_module._fluid_synth_program_reset(this._synth); | ||
} | ||
midiSystemReset() { | ||
_module._fluid_synth_system_reset(this._synth); | ||
Synthesizer_module._fluid_synth_system_reset(this._synth); | ||
} | ||
midiAllNotesOff(chan) { | ||
_module._fluid_synth_all_notes_off(this._synth, typeof chan === 'undefined' ? -1 : chan); | ||
Synthesizer_module._fluid_synth_all_notes_off(this._synth, typeof chan === 'undefined' ? -1 : chan); | ||
} | ||
midiAllSoundsOff(chan) { | ||
_module._fluid_synth_all_sounds_off(this._synth, typeof chan === 'undefined' ? -1 : chan); | ||
Synthesizer_module._fluid_synth_all_sounds_off(this._synth, typeof chan === 'undefined' ? -1 : chan); | ||
} | ||
@@ -335,3 +504,3 @@ midiSetChannelType(chan, isDrum) { | ||
// CHANNEL_TYPE_DRUM = 1 | ||
_module._fluid_synth_set_channel_type(this._synth, chan, isDrum ? 1 : 0); | ||
Synthesizer_module._fluid_synth_set_channel_type(this._synth, chan, isDrum ? 1 : 0); | ||
} | ||
@@ -343,3 +512,3 @@ resetPlayer() { | ||
this._closePlayer(); | ||
this._player = _module._new_fluid_player(this._synth); | ||
this._player = Synthesizer_module._new_fluid_player(this._synth); | ||
return this._player !== INVALID_POINTER ? Promise.resolve() : | ||
@@ -354,3 +523,3 @@ Promise.reject(new Error('Out of memory')); | ||
this.stopPlayer(); | ||
_module._delete_fluid_player(p); | ||
Synthesizer_module._delete_fluid_player(p); | ||
this._player = INVALID_POINTER; | ||
@@ -360,3 +529,3 @@ } | ||
if (this._playerPlaying) { | ||
const status = _module._fluid_player_get_status(this._player); | ||
const status = Synthesizer_module._fluid_player_get_status(this._player); | ||
if (status === 1 /*FLUID_PLAYER_PLAYING*/) { | ||
@@ -373,4 +542,4 @@ return true; | ||
const mem = malloc(len); | ||
_module.HEAPU8.set(new Uint8Array(bin), mem); | ||
const r = _module._fluid_player_add_mem(this._player, mem, len); | ||
Synthesizer_module.HEAPU8.set(new Uint8Array(bin), mem); | ||
const r = Synthesizer_module._fluid_player_add_mem(this._player, mem, len); | ||
free(mem); | ||
@@ -384,3 +553,3 @@ return r !== -1 ? Promise.resolve() : Promise.reject(new Error(fluid_synth_error(this._synth))); | ||
} | ||
if (_module._fluid_player_play(this._player) === -1) { | ||
if (Synthesizer_module._fluid_player_play(this._player) === -1) { | ||
return Promise.reject(new Error(fluid_synth_error(this._synth))); | ||
@@ -404,5 +573,5 @@ } | ||
} | ||
_module._fluid_player_stop(p); | ||
_module._fluid_player_join(p); | ||
_module._fluid_synth_all_sounds_off(this._synth, -1); | ||
Synthesizer_module._fluid_player_stop(p); | ||
Synthesizer_module._fluid_player_join(p); | ||
Synthesizer_module._fluid_synth_all_sounds_off(this._synth, -1); | ||
if (this._playerDefer) { | ||
@@ -414,2 +583,22 @@ this._playerDefer.resolve(); | ||
} | ||
retrievePlayerCurrentTick() { | ||
this.ensurePlayerInitialized(); | ||
return Promise.resolve(Synthesizer_module._fluid_player_get_current_tick(this._player)); | ||
} | ||
retrievePlayerTotalTicks() { | ||
this.ensurePlayerInitialized(); | ||
return Promise.resolve(Synthesizer_module._fluid_player_get_total_ticks(this._player)); | ||
} | ||
retrievePlayerBpm() { | ||
this.ensurePlayerInitialized(); | ||
return Promise.resolve(Synthesizer_module._fluid_player_get_bpm(this._player)); | ||
} | ||
retrievePlayerMIDITempo() { | ||
this.ensurePlayerInitialized(); | ||
return Promise.resolve(Synthesizer_module._fluid_player_get_midi_tempo(this._player)); | ||
} | ||
seekPlayer(ticks) { | ||
this.ensurePlayerInitialized(); | ||
Synthesizer_module._fluid_player_seek(this._player, ticks); | ||
} | ||
/** @internal */ | ||
@@ -430,3 +619,3 @@ ensureInitialized() { | ||
renderRaw(memLeft, memRight, frameCount) { | ||
_module._fluid_synth_write_float(this._synth, frameCount, memLeft, 0, 1, memRight, 0, 1); | ||
Synthesizer_module._fluid_synth_write_float(this._synth, frameCount, memLeft, 0, 1, memRight, 0, 1); | ||
} | ||
@@ -479,22 +668,21 @@ /** @internal */ | ||
} | ||
/** | ||
* Create the sequencer object for this class. | ||
*/ | ||
static createSequencer() { | ||
const seq = new Sequencer_Sequencer(); | ||
return seq._initialize().then(() => seq); | ||
} | ||
} | ||
// CONCATENATED MODULE: ./src/main/registerAudioWorkletProcessor.ts | ||
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
const registerAudioWorkletProcessor_module = AudioWorkletGlobalScope.wasmModule; | ||
// CONCATENATED MODULE: ./src/main/waitForReady.ts | ||
const waitForReady_module = typeof AudioWorkletGlobalScope !== 'undefined' ? | ||
AudioWorkletGlobalScope.wasmModule : Module; | ||
const promiseWasmInitialized = new Promise((resolve) => { | ||
if (registerAudioWorkletProcessor_module.calledRun) { | ||
if (waitForReady_module.calledRun) { | ||
resolve(); | ||
} | ||
else { | ||
const fn = registerAudioWorkletProcessor_module.onRuntimeInitialized; | ||
registerAudioWorkletProcessor_module.onRuntimeInitialized = () => { | ||
const fn = waitForReady_module.onRuntimeInitialized; | ||
waitForReady_module.onRuntimeInitialized = () => { | ||
resolve(); | ||
@@ -507,2 +695,159 @@ if (fn) { | ||
}); | ||
/** | ||
* Returns the Promise object which resolves when the synthesizer engine is ready. | ||
*/ | ||
function waitForReady() { | ||
return promiseWasmInitialized; | ||
} | ||
// CONCATENATED MODULE: ./src/main/MethodMessaging.ts | ||
/** @internal */ | ||
function initializeCallPort(port, hookMessage) { | ||
const instance = { | ||
port: port, | ||
defers: {}, | ||
deferId: 0 | ||
}; | ||
port.addEventListener('message', (e) => processReturnMessage(instance.defers, hookMessage, e)); | ||
port.start(); | ||
return instance; | ||
} | ||
function processReturnMessage(defers, hook, e) { | ||
const data = e.data; | ||
if (!data) { | ||
return; | ||
} | ||
if (hook && hook(data)) { | ||
return; | ||
} | ||
const defer = defers[data.id]; | ||
if (defer) { | ||
delete defers[data.id]; | ||
if ('error' in data) { | ||
defer.reject(data.error); | ||
} | ||
else { | ||
defer.resolve(data.val); | ||
} | ||
} | ||
else { | ||
if ('error' in data) { | ||
throw data.error; | ||
} | ||
} | ||
} | ||
/** @internal */ | ||
function postCall({ port }, method, args) { | ||
port.postMessage({ | ||
id: -1, method, args | ||
}); | ||
} | ||
/** @internal */ | ||
function postCallWithPromise(instance, method, args) { | ||
const id = instance.deferId++; | ||
if (instance.deferId === Infinity || instance.deferId < 0) { | ||
instance.deferId = 0; | ||
} | ||
const promise = new Promise((resolve, reject) => { | ||
instance.defers[id] = { resolve, reject }; | ||
}); | ||
instance.port.postMessage({ | ||
id, method, args | ||
}); | ||
return promise; | ||
} | ||
/** @internal */ | ||
function initializeReturnPort(port, promiseInitialized, targetObjectHolder, hookMessage) { | ||
const instance = { | ||
port: port | ||
}; | ||
if (promiseInitialized) { | ||
port.addEventListener('message', (e) => { | ||
const data = e.data; | ||
if (!data) { | ||
return; | ||
} | ||
promiseInitialized.then(() => processCallMessage(instance.port, data, targetObjectHolder, hookMessage)); | ||
}); | ||
} | ||
else { | ||
port.addEventListener('message', (e) => { | ||
const data = e.data; | ||
if (!data) { | ||
return; | ||
} | ||
processCallMessage(instance.port, data, targetObjectHolder, hookMessage); | ||
}); | ||
} | ||
port.start(); | ||
return instance; | ||
} | ||
function processCallMessage(port, data, targetObjectHolder, hook) { | ||
if (hook && hook(data)) { | ||
return; | ||
} | ||
const target = targetObjectHolder(); | ||
if (!target[data.method]) { | ||
postReturnError(port, data.id, data.method, new Error('Not implemented')); | ||
} | ||
else { | ||
try { | ||
postReturnImpl(port, data.id, data.method, target[data.method].apply(target, data.args)); | ||
} | ||
catch (e) { | ||
postReturnError(port, data.id, data.method, e); | ||
} | ||
} | ||
} | ||
/** @internal */ | ||
function postReturn(instance, id, method, value) { | ||
postReturnImpl(instance.port, id, method, value); | ||
} | ||
function postReturnImpl(port, id, method, value) { | ||
if (value instanceof Promise) { | ||
value.then((v) => { | ||
if (id >= 0) { | ||
port.postMessage({ | ||
id, | ||
method, | ||
val: v | ||
}); | ||
} | ||
}, (error) => { | ||
port.postMessage({ | ||
id, | ||
method, | ||
error | ||
}); | ||
}); | ||
} | ||
else { | ||
port.postMessage({ | ||
id, | ||
method, | ||
val: value | ||
}); | ||
} | ||
} | ||
function postReturnError(port, id, method, error) { | ||
port.postMessage({ | ||
id, | ||
method, | ||
error | ||
}); | ||
} | ||
// CONCATENATED MODULE: ./src/main/registerAudioWorkletProcessor.ts | ||
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
const registerAudioWorkletProcessor_promiseWasmInitialized = waitForReady(); | ||
/** Registers processor using Synthesizer for AudioWorklet. */ | ||
@@ -516,13 +861,29 @@ function registerAudioWorkletProcessor() { | ||
super(options); | ||
this.port.onmessage = this.onMessage.bind(this); | ||
this.port.start(); | ||
this.promiseInitialized = this.doInit(); | ||
const promiseInitialized = this.doInit(); | ||
this._messaging = initializeReturnPort(this.port, promiseInitialized, () => this.synth, (data) => { | ||
if (data.method === 'init') { | ||
this.synth.init(sampleRate); | ||
return true; | ||
} | ||
else if (data.method === 'createSequencer') { | ||
this.doCreateSequencer(data.args[0]).then(() => { | ||
postReturn(this._messaging, data.id, data.method, void (0)); | ||
}); | ||
return true; | ||
} | ||
return false; | ||
}); | ||
} | ||
doInit() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield promiseWasmInitialized; | ||
this.synth = new Synthesizer(); | ||
yield registerAudioWorkletProcessor_promiseWasmInitialized; | ||
this.synth = new Synthesizer_Synthesizer(); | ||
this.synth.init(sampleRate); | ||
}); | ||
} | ||
doCreateSequencer(port) { | ||
return Synthesizer_Synthesizer.createSequencer().then((seq) => { | ||
initializeReturnPort(port, null, () => seq); | ||
}); | ||
} | ||
process(_inputs, outputs) { | ||
@@ -534,3 +895,3 @@ if (!this.synth) { | ||
syn.render(outputs[0]); | ||
this.post(-1, "updateStatus" /* UpdateStatus */, { | ||
postReturn(this._messaging, -1, "updateStatus" /* UpdateStatus */, { | ||
playing: syn.isPlaying(), | ||
@@ -541,56 +902,2 @@ playerPlaying: syn.isPlayerPlaying() | ||
} | ||
post(id, method, value) { | ||
if (value instanceof Promise) { | ||
value.then((v) => { | ||
if (id >= 0) { | ||
this.port.postMessage({ | ||
id, | ||
method, | ||
val: v | ||
}); | ||
} | ||
}, (error) => { | ||
this.port.postMessage({ | ||
id, | ||
method, | ||
error | ||
}); | ||
}); | ||
} | ||
else if (id >= 0) { | ||
this.port.postMessage({ | ||
id, | ||
method, | ||
val: value | ||
}); | ||
} | ||
} | ||
postError(id, method, error) { | ||
// always post even if id < 0 | ||
this.port.postMessage({ | ||
id, | ||
method, | ||
error | ||
}); | ||
} | ||
onMessage(ev) { | ||
const data = ev.data; | ||
this.promiseInitialized.then(() => { | ||
const syn = this.synth; | ||
if (data.method === 'init') { | ||
syn.init(sampleRate); | ||
} | ||
else if (!syn[data.method]) { | ||
this.postError(data.id, data.method, new Error('Not implemented')); | ||
} | ||
else { | ||
try { | ||
this.post(data.id, data.method, syn[data.method].apply(syn, data.args)); | ||
} | ||
catch (e) { | ||
this.postError(data.id, data.method, e); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
@@ -597,0 +904,0 @@ registerProcessor("fluid-js" /* ProcessorName */, Processor); |
/*! | ||
fluid-js version 1.0.0 | ||
fluid-js version 1.1.0 | ||
@@ -29,3 +29,3 @@ @license | ||
OF SUCH DAMAGE. | ||
*/!function(t){var e={};function s(i){if(e[i])return e[i].exports;var n=e[i]={i:i,l:!1,exports:{}};return t[i].call(n.exports,n,n.exports,s),n.l=!0,n.exports}s.m=t,s.c=e,s.d=function(t,e,i){s.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},s.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},s.t=function(t,e){if(1&e&&(t=s(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(s.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)s.d(i,n,function(e){return t[e]}.bind(null,n));return i},s.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return s.d(e,"a",e),e},s.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},s.p="",s(s.s=0)}([function(t,e,s){"use strict";s.r(e);const i=0,n="undefined"!=typeof AudioWorkletGlobalScope?AudioWorkletGlobalScope.wasmModule:Module,r=n.FS,o=n.cwrap("fluid_synth_error","string",["number"]),h=n.cwrap("fluid_synth_sfload","number",["number","string","number"]),l=n._malloc.bind(n),_=n._free.bind(n);class a{constructor(){this._settings=n._new_fluid_settings(),this._synth=i,this._player=i,this._playerPlaying=!1,this._buffer=i,this._bufferSize=0,this._gain=.5}isInitialized(){return this._synth!==i}getRawSynthesizer(){return this._synth}createAudioNode(t,e){const s=t.createScriptProcessor(e,0,2);return s.addEventListener("audioprocess",t=>{this.render(t.outputBuffer)}),s}init(t){this.close(),this._synth=n._new_fluid_synth(this._settings),n._fluid_synth_set_gain(this._synth,this._gain),n._fluid_synth_set_sample_rate(this._synth,t),this._initPlayer()}close(){this._synth!==i&&(this._closePlayer(),n._delete_fluid_synth(this._synth),this._synth=i)}isPlaying(){return this._synth!==i&&n._fluid_synth_get_active_voice_count(this._synth)>0}setInterpolation(t,e){this.ensureInitialized(),void 0===e&&(e=-1),n._fluid_synth_set_interp_method(this._synth,e,t)}getGain(){return this._gain}setGain(t){this.ensureInitialized(),n._fluid_synth_set_gain(this._synth,t),this._gain=n._fluid_synth_get_gain(this._synth)}waitForVoicesStopped(){return this.flushFramesAsync()}loadSFont(t){this.ensureInitialized();const e=function(t,e){return`/${t}-r${65535*Math.random()}-${65535*Math.random()}${e}`}("sfont",".sf2"),s=new Uint8Array(t);r.writeFile(e,s);const i=h(this._synth,e,1);return r.unlink(e),-1===i?Promise.reject(new Error(o(this._synth))):Promise.resolve(i)}unloadSFont(t){this.ensureInitialized(),this.stopPlayer(),this.flushFramesSync(),n._fluid_synth_sfunload(this._synth,t,1)}unloadSFontAsync(t){return this.ensureInitialized(),this.stopPlayer(),this.flushFramesAsync().then(()=>{n._fluid_synth_sfunload(this._synth,t,1)})}getSFontBankOffset(t){return this.ensureInitialized(),Promise.resolve(n._fluid_synth_get_bank_offset(this._synth,t))}setSFontBankOffset(t,e){this.ensureInitialized(),n._fluid_synth_set_bank_offset(this._synth,t,e)}render(t){const e="numberOfChannels"in t?t.length:t[0].length,s="numberOfChannels"in t?t.numberOfChannels:t.length,r=4*e,o=2*r;this._bufferSize<o&&(this._buffer!==i&&_(this._buffer),this._buffer=l(o),this._bufferSize=o);const h=this._buffer,a=this._buffer+r;this.renderRaw(h,a,e);const y=new Float32Array(n.HEAPU8.buffer,h,e),u=s>=2?new Float32Array(n.HEAPU8.buffer,a,e):null;"numberOfChannels"in t?(t.copyToChannel(y,0,0),u&&t.copyToChannel(u,1,0)):(t[0].set(y),u&&t[1].set(u)),this.isPlayerPlaying()}midiNoteOn(t,e,s){n._fluid_synth_noteon(this._synth,t,e,s)}midiNoteOff(t,e){n._fluid_synth_noteoff(this._synth,t,e)}midiKeyPressure(t,e,s){n._fluid_synth_key_pressure(this._synth,t,e,s)}midiControl(t,e,s){n._fluid_synth_cc(this._synth,t,e,s)}midiProgramChange(t,e){n._fluid_synth_program_change(this._synth,t,e)}midiChannelPressure(t,e){n._fluid_synth_channel_pressure(this._synth,t,e)}midiPitchBend(t,e){n._fluid_synth_pitch_bend(this._synth,t,e)}midiSysEx(t){const e=t.byteLength,s=l(e);n.HEAPU8.set(t,s),n._fluid_synth_sysex(this._synth,s,e,i,i,i,0)}midiPitchWheelSensitivity(t,e){n._fluid_synth_pitch_wheel_sens(this._synth,t,e)}midiBankSelect(t,e){n._fluid_synth_bank_select(this._synth,t,e)}midiSFontSelect(t,e){n._fluid_synth_sfont_select(this._synth,t,e)}midiUnsetProgram(t){n._fluid_synth_unset_program(this._synth,t)}midiProgramReset(){n._fluid_synth_program_reset(this._synth)}midiSystemReset(){n._fluid_synth_system_reset(this._synth)}midiAllNotesOff(t){n._fluid_synth_all_notes_off(this._synth,void 0===t?-1:t)}midiAllSoundsOff(t){n._fluid_synth_all_sounds_off(this._synth,void 0===t?-1:t)}midiSetChannelType(t,e){n._fluid_synth_set_channel_type(this._synth,t,e?1:0)}resetPlayer(){return this._initPlayer()}_initPlayer(){return this._closePlayer(),this._player=n._new_fluid_player(this._synth),this._player!==i?Promise.resolve():Promise.reject(new Error("Out of memory"))}_closePlayer(){const t=this._player;t!==i&&(this.stopPlayer(),n._delete_fluid_player(t),this._player=i)}isPlayerPlaying(){if(this._playerPlaying){if(1===n._fluid_player_get_status(this._player))return!0;this.stopPlayer()}return!1}addSMFDataToPlayer(t){this.ensurePlayerInitialized();const e=t.byteLength,s=l(e);n.HEAPU8.set(new Uint8Array(t),s);const i=n._fluid_player_add_mem(this._player,s,e);return _(s),-1!==i?Promise.resolve():Promise.reject(new Error(o(this._synth)))}playPlayer(){if(this.ensurePlayerInitialized(),this._playerPlaying&&this.stopPlayer(),-1===n._fluid_player_play(this._player))return Promise.reject(new Error(o(this._synth)));this._playerPlaying=!0;let t=()=>{};const e=new Promise(e=>{t=e});return this._playerDefer={promise:e,resolve:t},Promise.resolve()}stopPlayer(){const t=this._player;t!==i&&this._playerPlaying&&(n._fluid_player_stop(t),n._fluid_player_join(t),n._fluid_synth_all_sounds_off(this._synth,-1),this._playerDefer&&(this._playerDefer.resolve(),this._playerDefer=void 0),this._playerPlaying=!1)}ensureInitialized(){if(this._synth===i)throw new Error("Synthesizer is not initialized")}ensurePlayerInitialized(){if(this.ensureInitialized(),this._player===i)throw new Error("Player is not initialized")}renderRaw(t,e,s){n._fluid_synth_write_float(this._synth,s,t,0,1,e,0,1)}flushFramesSync(){const t=l(524288),e=t,s=t+262144;for(;this.isPlaying();)this.renderRaw(e,s,65536);_(t)}flushFramesAsync(){if(!this.isPlaying())return Promise.resolve();const t=65536,e=4*t,s=l(2*e),i=s,n=s+e,r="undefined"!=typeof setTimeout?()=>new Promise(t=>setTimeout(t,0)):()=>Promise.resolve();function o(){return r().then(a)}const h=this;function a(){return h.isPlaying()?(h.renderRaw(i,n,t),o()):(_(s),Promise.resolve())}return o()}waitForPlayerStopped(){return this._playerDefer?this._playerDefer.promise:Promise.resolve()}}var y=function(t,e,s,i){return new(s||(s=Promise))(function(n,r){function o(t){try{l(i.next(t))}catch(t){r(t)}}function h(t){try{l(i.throw(t))}catch(t){r(t)}}function l(t){t.done?n(t.value):new s(function(e){e(t.value)}).then(o,h)}l((i=i.apply(t,e||[])).next())})};const u=AudioWorkletGlobalScope.wasmModule,d=new Promise(t=>{if(u.calledRun)t();else{const e=u.onRuntimeInitialized;u.onRuntimeInitialized=(()=>{t(),e&&e()})}});registerProcessor("fluid-js",class extends AudioWorkletProcessor{constructor(t){super(t),this.port.onmessage=this.onMessage.bind(this),this.port.start(),this.promiseInitialized=this.doInit()}doInit(){return y(this,void 0,void 0,function*(){yield d,this.synth=new a,this.synth.init(sampleRate)})}process(t,e){if(!this.synth)return!0;const s=this.synth;return s.render(e[0]),this.post(-1,"updateStatus",{playing:s.isPlaying(),playerPlaying:s.isPlayerPlaying()}),!0}post(t,e,s){s instanceof Promise?s.then(s=>{t>=0&&this.port.postMessage({id:t,method:e,val:s})},s=>{this.port.postMessage({id:t,method:e,error:s})}):t>=0&&this.port.postMessage({id:t,method:e,val:s})}postError(t,e,s){this.port.postMessage({id:t,method:e,error:s})}onMessage(t){const e=t.data;this.promiseInitialized.then(()=>{const t=this.synth;if("init"===e.method)t.init(sampleRate);else if(t[e.method])try{this.post(e.id,e.method,t[e.method].apply(t,e.args))}catch(t){this.postError(e.id,e.method,t)}else this.postError(e.id,e.method,new Error("Not implemented"))})}})}]); | ||
*/!function(e){var t={};function s(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,s),i.l=!0,i.exports}s.m=e,s.c=t,s.d=function(e,t,n){s.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},s.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},s.t=function(e,t){if(1&t&&(e=s(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(s.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)s.d(n,i,function(t){return e[t]}.bind(null,i));return n},s.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return s.d(t,"a",t),t},s.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},s.p="",s(s.s=0)}([function(e,t,s){"use strict";s.r(t);const n=0,i="undefined"!=typeof AudioWorkletGlobalScope?AudioWorkletGlobalScope.wasmModule:Module;class r{constructor(){this._seq=n}_initialize(){return this.close(),this._seq=i._new_fluid_sequencer2(0),Promise.resolve()}close(){this._seq!==n&&(i._delete_fluid_sequencer(this._seq),this._seq=n)}registerSynthesizer(e){let t;if("number"==typeof e)t=e;else{if(!(e instanceof c))return Promise.reject(new TypeError("'synth' is not a compatible type instance"));t=e.getRawSynthesizer()}return i._fluid_sequencer_register_fluidsynth(this._seq,t),Promise.resolve()}setTimeScale(e){i._fluid_sequencer_set_time_scale(this._seq,e)}getTimeScale(){return Promise.resolve(i._fluid_sequencer_get_time_scale(this._seq))}getTick(){return Promise.resolve(i._fluid_sequencer_get_tick(this._seq))}sendEventAt(e,t,s){const n=function(e){const t=i._new_fluid_event();switch(e.type){case 1:case"note":i._fluid_event_note(t,e.channel,e.key,e.vel,e.duration);break;case 2:case"noteon":case"note-on":i._fluid_event_noteon(t,e.channel,e.key,e.vel);break;case 3:case"noteoff":case"note-off":i._fluid_event_noteoff(t,e.channel,e.key);break;case 4:case"allsoundsoff":case"all-sounds-off":i._fluid_event_all_sounds_off(t,e.channel);break;case 5:case"allnotesoff":case"all-notes-off":i._fluid_event_all_notes_off(t,e.channel);break;case 6:case"bankselect":case"bank-select":i._fluid_event_bank_select(t,e.channel,e.bank);break;case 7:case"programchange":case"program-change":i._fluid_event_program_change(t,e.channel,e.preset);break;case 8:case"programselect":case"program-select":i._fluid_event_program_select(t,e.channel,e.sfontId,e.bank,e.preset);break;case 9:case"controlchange":case"control-change":i._fluid_event_control_change(t,e.channel,e.control,e.value);break;case 10:case"pitchbend":case"pitch-bend":i._fluid_event_pitch_bend(t,e.channel,e.value);break;case 11:case"pitchwheelsens":case"pitchwheelsensitivity":case"pitch-wheel-sens":case"pitch-wheel-sensitivity":i._fluid_event_pitch_wheelsens(t,e.channel,e.value);break;case 12:case"modulation":i._fluid_event_modulation(t,e.channel,e.value);break;case 13:case"sustain":i._fluid_event_sustain(t,e.channel,e.value);break;case 14:case"pan":i._fluid_event_pan(t,e.channel,e.value);break;case 15:case"volume":i._fluid_event_volume(t,e.channel,e.value);break;case 16:case"reverb":case"reverbsend":case"reverb-send":i._fluid_event_reverb_send(t,e.channel,e.value);break;case 17:case"chorus":case"chorussend":case"chorus-send":i._fluid_event_chorus_send(t,e.channel,e.value);break;case 18:case"keypressure":case"key-pressure":case"aftertouch":i._fluid_event_key_pressure(t,e.channel,e.key,e.value);break;case 19:case"channelpressure":case"channel-pressure":case"channel-aftertouch":i._fluid_event_channel_pressure(t,e.channel,e.value);break;case 20:case"systemreset":case"system-reset":i._fluid_event_system_reset(t);break;default:return i._delete_fluid_event(t),null}return t}(e);null!==n&&(i._fluid_sequencer_send_at(this._seq,n,t,s?1:0),i._delete_fluid_event(n))}}const a="undefined"!=typeof AudioWorkletGlobalScope?AudioWorkletGlobalScope.wasmModule:Module,l=a.FS,_=a.cwrap("fluid_synth_error","string",["number"]),o=a.cwrap("fluid_synth_sfload","number",["number","string","number"]),h=a._malloc.bind(a),u=a._free.bind(a);class c{constructor(){this._settings=a._new_fluid_settings(),this._synth=n,this._player=n,this._playerPlaying=!1,this._buffer=n,this._bufferSize=0,this._gain=.5}isInitialized(){return this._synth!==n}getRawSynthesizer(){return this._synth}createAudioNode(e,t){const s=e.createScriptProcessor(t,0,2);return s.addEventListener("audioprocess",e=>{this.render(e.outputBuffer)}),s}init(e){this.close(),this._synth=a._new_fluid_synth(this._settings),a._fluid_synth_set_gain(this._synth,this._gain),a._fluid_synth_set_sample_rate(this._synth,e),this._initPlayer()}close(){this._synth!==n&&(this._closePlayer(),a._delete_fluid_synth(this._synth),this._synth=n)}isPlaying(){return this._synth!==n&&a._fluid_synth_get_active_voice_count(this._synth)>0}setInterpolation(e,t){this.ensureInitialized(),void 0===t&&(t=-1),a._fluid_synth_set_interp_method(this._synth,t,e)}getGain(){return this._gain}setGain(e){this.ensureInitialized(),a._fluid_synth_set_gain(this._synth,e),this._gain=a._fluid_synth_get_gain(this._synth)}waitForVoicesStopped(){return this.flushFramesAsync()}loadSFont(e){this.ensureInitialized();const t=function(e,t){return`/${e}-r${65535*Math.random()}-${65535*Math.random()}${t}`}("sfont",".sf2"),s=new Uint8Array(e);l.writeFile(t,s);const n=o(this._synth,t,1);return l.unlink(t),-1===n?Promise.reject(new Error(_(this._synth))):Promise.resolve(n)}unloadSFont(e){this.ensureInitialized(),this.stopPlayer(),this.flushFramesSync(),a._fluid_synth_sfunload(this._synth,e,1)}unloadSFontAsync(e){return this.ensureInitialized(),this.stopPlayer(),this.flushFramesAsync().then(()=>{a._fluid_synth_sfunload(this._synth,e,1)})}getSFontBankOffset(e){return this.ensureInitialized(),Promise.resolve(a._fluid_synth_get_bank_offset(this._synth,e))}setSFontBankOffset(e,t){this.ensureInitialized(),a._fluid_synth_set_bank_offset(this._synth,e,t)}render(e){const t="numberOfChannels"in e?e.length:e[0].length,s="numberOfChannels"in e?e.numberOfChannels:e.length,i=4*t,r=2*i;this._bufferSize<r&&(this._buffer!==n&&u(this._buffer),this._buffer=h(r),this._bufferSize=r);const l=this._buffer,_=this._buffer+i;this.renderRaw(l,_,t);const o=new Float32Array(a.HEAPU8.buffer,l,t),c=s>=2?new Float32Array(a.HEAPU8.buffer,_,t):null;"numberOfChannels"in e?(e.copyToChannel(o,0,0),c&&e.copyToChannel(c,1,0)):(e[0].set(o),c&&e[1].set(c)),this.isPlayerPlaying()}midiNoteOn(e,t,s){a._fluid_synth_noteon(this._synth,e,t,s)}midiNoteOff(e,t){a._fluid_synth_noteoff(this._synth,e,t)}midiKeyPressure(e,t,s){a._fluid_synth_key_pressure(this._synth,e,t,s)}midiControl(e,t,s){a._fluid_synth_cc(this._synth,e,t,s)}midiProgramChange(e,t){a._fluid_synth_program_change(this._synth,e,t)}midiChannelPressure(e,t){a._fluid_synth_channel_pressure(this._synth,e,t)}midiPitchBend(e,t){a._fluid_synth_pitch_bend(this._synth,e,t)}midiSysEx(e){const t=e.byteLength,s=h(t);a.HEAPU8.set(e,s),a._fluid_synth_sysex(this._synth,s,t,n,n,n,0)}midiPitchWheelSensitivity(e,t){a._fluid_synth_pitch_wheel_sens(this._synth,e,t)}midiBankSelect(e,t){a._fluid_synth_bank_select(this._synth,e,t)}midiSFontSelect(e,t){a._fluid_synth_sfont_select(this._synth,e,t)}midiUnsetProgram(e){a._fluid_synth_unset_program(this._synth,e)}midiProgramReset(){a._fluid_synth_program_reset(this._synth)}midiSystemReset(){a._fluid_synth_system_reset(this._synth)}midiAllNotesOff(e){a._fluid_synth_all_notes_off(this._synth,void 0===e?-1:e)}midiAllSoundsOff(e){a._fluid_synth_all_sounds_off(this._synth,void 0===e?-1:e)}midiSetChannelType(e,t){a._fluid_synth_set_channel_type(this._synth,e,t?1:0)}resetPlayer(){return this._initPlayer()}_initPlayer(){return this._closePlayer(),this._player=a._new_fluid_player(this._synth),this._player!==n?Promise.resolve():Promise.reject(new Error("Out of memory"))}_closePlayer(){const e=this._player;e!==n&&(this.stopPlayer(),a._delete_fluid_player(e),this._player=n)}isPlayerPlaying(){if(this._playerPlaying){if(1===a._fluid_player_get_status(this._player))return!0;this.stopPlayer()}return!1}addSMFDataToPlayer(e){this.ensurePlayerInitialized();const t=e.byteLength,s=h(t);a.HEAPU8.set(new Uint8Array(e),s);const n=a._fluid_player_add_mem(this._player,s,t);return u(s),-1!==n?Promise.resolve():Promise.reject(new Error(_(this._synth)))}playPlayer(){if(this.ensurePlayerInitialized(),this._playerPlaying&&this.stopPlayer(),-1===a._fluid_player_play(this._player))return Promise.reject(new Error(_(this._synth)));this._playerPlaying=!0;let e=()=>{};const t=new Promise(t=>{e=t});return this._playerDefer={promise:t,resolve:e},Promise.resolve()}stopPlayer(){const e=this._player;e!==n&&this._playerPlaying&&(a._fluid_player_stop(e),a._fluid_player_join(e),a._fluid_synth_all_sounds_off(this._synth,-1),this._playerDefer&&(this._playerDefer.resolve(),this._playerDefer=void 0),this._playerPlaying=!1)}retrievePlayerCurrentTick(){return this.ensurePlayerInitialized(),Promise.resolve(a._fluid_player_get_current_tick(this._player))}retrievePlayerTotalTicks(){return this.ensurePlayerInitialized(),Promise.resolve(a._fluid_player_get_total_ticks(this._player))}retrievePlayerBpm(){return this.ensurePlayerInitialized(),Promise.resolve(a._fluid_player_get_bpm(this._player))}retrievePlayerMIDITempo(){return this.ensurePlayerInitialized(),Promise.resolve(a._fluid_player_get_midi_tempo(this._player))}seekPlayer(e){this.ensurePlayerInitialized(),a._fluid_player_seek(this._player,e)}ensureInitialized(){if(this._synth===n)throw new Error("Synthesizer is not initialized")}ensurePlayerInitialized(){if(this.ensureInitialized(),this._player===n)throw new Error("Player is not initialized")}renderRaw(e,t,s){a._fluid_synth_write_float(this._synth,s,e,0,1,t,0,1)}flushFramesSync(){const e=h(524288),t=e,s=e+262144;for(;this.isPlaying();)this.renderRaw(t,s,65536);u(e)}flushFramesAsync(){if(!this.isPlaying())return Promise.resolve();const e=65536,t=4*e,s=h(2*t),n=s,i=s+t,r="undefined"!=typeof setTimeout?()=>new Promise(e=>setTimeout(e,0)):()=>Promise.resolve();function a(){return r().then(_)}const l=this;function _(){return l.isPlaying()?(l.renderRaw(n,i,e),a()):(u(s),Promise.resolve())}return a()}waitForPlayerStopped(){return this._playerDefer?this._playerDefer.promise:Promise.resolve()}static createSequencer(){const e=new r;return e._initialize().then(()=>e)}}const d="undefined"!=typeof AudioWorkletGlobalScope?AudioWorkletGlobalScope.wasmModule:Module;function y(e,t,s,n){const i={port:e};return t?e.addEventListener("message",e=>{const r=e.data;r&&t.then(()=>f(i.port,r,s,n))}):e.addEventListener("message",e=>{const t=e.data;t&&f(i.port,t,s,n)}),e.start(),i}function f(e,t,s,n){if(n&&n(t))return;const i=s();if(i[t.method])try{m(e,t.id,t.method,i[t.method].apply(i,t.args))}catch(s){v(e,t.id,t.method,s)}else v(e,t.id,t.method,new Error("Not implemented"))}function p(e,t,s,n){m(e.port,t,s,n)}function m(e,t,s,n){n instanceof Promise?n.then(n=>{t>=0&&e.postMessage({id:t,method:s,val:n})},n=>{e.postMessage({id:t,method:s,error:n})}):e.postMessage({id:t,method:s,val:n})}function v(e,t,s,n){e.postMessage({id:t,method:s,error:n})}var P=function(e,t,s,n){return new(s||(s=Promise))(function(i,r){function a(e){try{_(n.next(e))}catch(e){r(e)}}function l(e){try{_(n.throw(e))}catch(e){r(e)}}function _(e){e.done?i(e.value):new s(function(t){t(e.value)}).then(a,l)}_((n=n.apply(e,t||[])).next())})};const g=new Promise(e=>{if(d.calledRun)e();else{const t=d.onRuntimeInitialized;d.onRuntimeInitialized=(()=>{e(),t&&t()})}});registerProcessor("fluid-js",class extends AudioWorkletProcessor{constructor(e){super(e);const t=this.doInit();this._messaging=y(this.port,t,()=>this.synth,e=>"init"===e.method?(this.synth.init(sampleRate),!0):"createSequencer"===e.method&&(this.doCreateSequencer(e.args[0]).then(()=>{p(this._messaging,e.id,e.method,void 0)}),!0))}doInit(){return P(this,void 0,void 0,function*(){yield g,this.synth=new c,this.synth.init(sampleRate)})}doCreateSequencer(e){return c.createSequencer().then(t=>{y(e,null,()=>t)})}process(e,t){if(!this.synth)return!0;const s=this.synth;return s.render(t[0]),p(this._messaging,-1,"updateStatus",{playing:s.isPlaying(),playerPlaying:s.isPlayerPlaying()}),!0}})}]); | ||
//# sourceMappingURL=fluid.worklet.min.js.map |
import { InterpolationValues } from './Constants'; | ||
import ISequencer from './ISequencer'; | ||
import ISynthesizer from './ISynthesizer'; | ||
@@ -45,3 +46,12 @@ /** An synthesizer object with AudioWorkletNode */ | ||
stopPlayer(): void; | ||
retrievePlayerCurrentTick(): Promise<number>; | ||
retrievePlayerTotalTicks(): Promise<number>; | ||
retrievePlayerBpm(): Promise<number>; | ||
retrievePlayerMIDITempo(): Promise<number>; | ||
seekPlayer(ticks: number): void; | ||
waitForPlayerStopped(): Promise<void>; | ||
/** | ||
* Creates a sequencer instance associated with this worklet node. | ||
*/ | ||
createSequencer(): Promise<ISequencer>; | ||
} |
@@ -0,1 +1,3 @@ | ||
import WorkletSequencer from './WorkletSequencer'; | ||
import * as MethodMessaging from './MethodMessaging'; | ||
/** An synthesizer object with AudioWorkletNode */ | ||
@@ -8,52 +10,6 @@ export default class AudioWorkletNodeSynthesizer { | ||
}; | ||
this._defers = {}; | ||
this._deferId = 0; | ||
this._port = null; | ||
this._messaging = null; | ||
this._node = null; | ||
this._gain = 0.5 /* Gain */; | ||
} | ||
/** @internal */ | ||
onMessage(ev) { | ||
const data = ev.data; | ||
if (data.method === "updateStatus" /* UpdateStatus */) { | ||
this._status = data.val; | ||
} | ||
else { | ||
const defer = this._defers[data.id]; | ||
if (defer) { | ||
delete this._defers[data.id]; | ||
if ('error' in data) { | ||
defer.reject(data.error); | ||
} | ||
else { | ||
defer.resolve(data.val); | ||
} | ||
} | ||
else { | ||
if ('error' in data) { | ||
throw data.error; | ||
} | ||
} | ||
} | ||
} | ||
/** @internal */ | ||
postCall(method, args) { | ||
this._port.postMessage({ | ||
id: -1, method, args | ||
}); | ||
} | ||
/** @internal */ | ||
postCallWithPromise(method, args) { | ||
const id = this._deferId++; | ||
if (this._deferId === Infinity || this._deferId < 0) { | ||
this._deferId = 0; | ||
} | ||
const promise = new Promise((resolve, reject) => { | ||
this._defers[id] = { resolve, reject }; | ||
}); | ||
this._port.postMessage({ | ||
id, method, args | ||
}); | ||
return promise; | ||
} | ||
/** Audio node for this synthesizer */ | ||
@@ -71,10 +27,13 @@ get node() { | ||
this._node = node; | ||
const port = node.port; | ||
this._port = port; | ||
port.addEventListener('message', this.onMessage.bind(this)); | ||
port.start(); | ||
this._messaging = MethodMessaging.initializeCallPort(node.port, (data) => { | ||
if (data.method === "updateStatus" /* UpdateStatus */) { | ||
this._status = data.val; | ||
return true; | ||
} | ||
return false; | ||
}); | ||
return node; | ||
} | ||
isInitialized() { | ||
return this._port !== null; | ||
return this._messaging !== null; | ||
} | ||
@@ -85,3 +44,3 @@ init(_sampleRate) { | ||
// call init instead of close | ||
this.postCall('init', [0]); | ||
MethodMessaging.postCall(this._messaging, 'init', [0]); | ||
} | ||
@@ -92,3 +51,3 @@ isPlaying() { | ||
setInterpolation(value, channel) { | ||
this.postCall('setInterpolation', [value, channel]); | ||
MethodMessaging.postCall(this._messaging, 'setInterpolation', [value, channel]); | ||
} | ||
@@ -100,4 +59,4 @@ getGain() { | ||
this._gain = gain; | ||
this.postCallWithPromise('setGain', [gain]).then(() => { | ||
return this.postCallWithPromise('getGain', []); | ||
MethodMessaging.postCallWithPromise(this._messaging, 'setGain', [gain]).then(() => { | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'getGain', []); | ||
}).then((value) => { | ||
@@ -108,18 +67,18 @@ this._gain = value; | ||
waitForVoicesStopped() { | ||
return this.postCallWithPromise('waitForVoicesStopped', []); | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'waitForVoicesStopped', []); | ||
} | ||
loadSFont(bin) { | ||
return this.postCallWithPromise('loadSFont', [bin]); | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'loadSFont', [bin]); | ||
} | ||
unloadSFont(id) { | ||
this.postCall('unloadSFont', [id]); | ||
MethodMessaging.postCall(this._messaging, 'unloadSFont', [id]); | ||
} | ||
unloadSFontAsync(id) { | ||
return this.postCallWithPromise('unloadSFont', [id]); | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'unloadSFont', [id]); | ||
} | ||
getSFontBankOffset(id) { | ||
return this.postCallWithPromise('getSFontBankOffset', [id]); | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'getSFontBankOffset', [id]); | ||
} | ||
setSFontBankOffset(id, offset) { | ||
this.postCall('setSFontBankOffset', [id, offset]); | ||
MethodMessaging.postCall(this._messaging, 'setSFontBankOffset', [id, offset]); | ||
} | ||
@@ -130,54 +89,54 @@ render() { | ||
midiNoteOn(chan, key, vel) { | ||
this.postCall('midiNoteOn', [chan, key, vel]); | ||
MethodMessaging.postCall(this._messaging, 'midiNoteOn', [chan, key, vel]); | ||
} | ||
midiNoteOff(chan, key) { | ||
this.postCall('midiNoteOff', [chan, key]); | ||
MethodMessaging.postCall(this._messaging, 'midiNoteOff', [chan, key]); | ||
} | ||
midiKeyPressure(chan, key, val) { | ||
this.postCall('midiKeyPressure', [chan, key, val]); | ||
MethodMessaging.postCall(this._messaging, 'midiKeyPressure', [chan, key, val]); | ||
} | ||
midiControl(chan, ctrl, val) { | ||
this.postCall('midiControl', [chan, ctrl, val]); | ||
MethodMessaging.postCall(this._messaging, 'midiControl', [chan, ctrl, val]); | ||
} | ||
midiProgramChange(chan, prognum) { | ||
this.postCall('midiProgramChange', [chan, prognum]); | ||
MethodMessaging.postCall(this._messaging, 'midiProgramChange', [chan, prognum]); | ||
} | ||
midiChannelPressure(chan, val) { | ||
this.postCall('midiChannelPressure', [chan, val]); | ||
MethodMessaging.postCall(this._messaging, 'midiChannelPressure', [chan, val]); | ||
} | ||
midiPitchBend(chan, val) { | ||
this.postCall('midiPitchBend', [chan, val]); | ||
MethodMessaging.postCall(this._messaging, 'midiPitchBend', [chan, val]); | ||
} | ||
midiSysEx(data) { | ||
this.postCall('midiSysEx', [data]); | ||
MethodMessaging.postCall(this._messaging, 'midiSysEx', [data]); | ||
} | ||
midiPitchWheelSensitivity(chan, val) { | ||
this.postCall('midiPitchWheelSensitivity', [chan, val]); | ||
MethodMessaging.postCall(this._messaging, 'midiPitchWheelSensitivity', [chan, val]); | ||
} | ||
midiBankSelect(chan, bank) { | ||
this.postCall('midiBankSelect', [chan, bank]); | ||
MethodMessaging.postCall(this._messaging, 'midiBankSelect', [chan, bank]); | ||
} | ||
midiSFontSelect(chan, sfontId) { | ||
this.postCall('midiSFontSelect', [chan, sfontId]); | ||
MethodMessaging.postCall(this._messaging, 'midiSFontSelect', [chan, sfontId]); | ||
} | ||
midiUnsetProgram(chan) { | ||
this.postCall('midiUnsetProgram', [chan]); | ||
MethodMessaging.postCall(this._messaging, 'midiUnsetProgram', [chan]); | ||
} | ||
midiProgramReset() { | ||
this.postCall('midiProgramReset', []); | ||
MethodMessaging.postCall(this._messaging, 'midiProgramReset', []); | ||
} | ||
midiSystemReset() { | ||
this.postCall('midiSystemReset', []); | ||
MethodMessaging.postCall(this._messaging, 'midiSystemReset', []); | ||
} | ||
midiAllNotesOff(chan) { | ||
this.postCall('midiAllNotesOff', [chan]); | ||
MethodMessaging.postCall(this._messaging, 'midiAllNotesOff', [chan]); | ||
} | ||
midiAllSoundsOff(chan) { | ||
this.postCall('midiAllSoundsOff', [chan]); | ||
MethodMessaging.postCall(this._messaging, 'midiAllSoundsOff', [chan]); | ||
} | ||
midiSetChannelType(chan, isDrum) { | ||
this.postCall('midiSetChannelType', [chan, isDrum]); | ||
MethodMessaging.postCall(this._messaging, 'midiSetChannelType', [chan, isDrum]); | ||
} | ||
resetPlayer() { | ||
return this.postCallWithPromise('resetPlayer', []); | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'resetPlayer', []); | ||
} | ||
@@ -188,14 +147,42 @@ isPlayerPlaying() { | ||
addSMFDataToPlayer(bin) { | ||
return this.postCallWithPromise('addSMFDataToPlayer', [bin]); | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'addSMFDataToPlayer', [bin]); | ||
} | ||
playPlayer() { | ||
return this.postCallWithPromise('playPlayer', []); | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'playPlayer', []); | ||
} | ||
stopPlayer() { | ||
this.postCall('stopPlayer', []); | ||
MethodMessaging.postCall(this._messaging, 'stopPlayer', []); | ||
} | ||
retrievePlayerCurrentTick() { | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'retrievePlayerCurrentTick', []); | ||
} | ||
retrievePlayerTotalTicks() { | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'retrievePlayerTotalTicks', []); | ||
} | ||
retrievePlayerBpm() { | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'retrievePlayerBpm', []); | ||
} | ||
retrievePlayerMIDITempo() { | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'retrievePlayerMIDITempo', []); | ||
} | ||
seekPlayer(ticks) { | ||
MethodMessaging.postCall(this._messaging, 'seekPlayer', [ticks]); | ||
} | ||
waitForPlayerStopped() { | ||
return this.postCallWithPromise('waitForPlayerStopped', []); | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'waitForPlayerStopped', []); | ||
} | ||
/** | ||
* Creates a sequencer instance associated with this worklet node. | ||
*/ | ||
createSequencer() { | ||
const channel = new MessageChannel(); | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'createSequencer', [channel.port2]).then(() => { | ||
return new WorkletSequencer(channel.port1); | ||
}); | ||
} | ||
/** @internal */ | ||
_getRawSynthesizer() { | ||
return MethodMessaging.postCallWithPromise(this._messaging, 'getRawSynthesizer', []); | ||
} | ||
} | ||
//# sourceMappingURL=AudioWorkletNodeSynthesizer.js.map |
import * as Constants from './Constants'; | ||
import ISequencer from './ISequencer'; | ||
import ISynthesizer from './ISynthesizer'; | ||
import Synthesizer from './Synthesizer'; | ||
import waitForReady from './waitForReady'; | ||
import AudioWorkletNodeSynthesizer from './AudioWorkletNodeSynthesizer'; | ||
export { Constants, ISynthesizer, Synthesizer, AudioWorkletNodeSynthesizer }; | ||
export { Constants, ISequencer, ISynthesizer, Synthesizer, waitForReady, AudioWorkletNodeSynthesizer }; |
import * as Constants from './Constants'; | ||
import Synthesizer from './Synthesizer'; | ||
import waitForReady from './waitForReady'; | ||
import AudioWorkletNodeSynthesizer from './AudioWorkletNodeSynthesizer'; | ||
export { Constants, Synthesizer, AudioWorkletNodeSynthesizer }; | ||
export { Constants, Synthesizer, waitForReady, AudioWorkletNodeSynthesizer }; | ||
//# sourceMappingURL=index.js.map |
@@ -184,2 +184,33 @@ import { InterpolationValues } from './Constants'; | ||
/** | ||
* Retrieve current (timing that method called) tick value of the player. | ||
* initPlayer() must be called before calling this method. | ||
* @return resolved with the tick value | ||
*/ | ||
retrievePlayerCurrentTick(): Promise<number>; | ||
/** | ||
* Retrieve tick value of the last event timing of current playing data. | ||
* initPlayer() must be called before calling this method. | ||
* @return resolved with the tick value | ||
*/ | ||
retrievePlayerTotalTicks(): Promise<number>; | ||
/** | ||
* Retrieve current (timing that method called) BPM value of the player. | ||
* The BPM value is calculated by dividing 60000000 by the MIDI tempo value. | ||
* initPlayer() must be called before calling this method. | ||
* @return resolved with the BPM value | ||
*/ | ||
retrievePlayerBpm(): Promise<number>; | ||
/** | ||
* Retrieve current (timing that method called) MIDI tempo value of the player. | ||
* initPlayer() must be called before calling this method. | ||
* @return resolved with the MIDI tempo value | ||
*/ | ||
retrievePlayerMIDITempo(): Promise<number>; | ||
/** | ||
* Seeks the playing point of the player. | ||
* initPlayer() must be called before calling this method. | ||
* @param ticks the absolute tick value to seek (0 refers the first position) | ||
*/ | ||
seekPlayer(ticks: number): void; | ||
/** | ||
* Wait for finishing player process. | ||
@@ -186,0 +217,0 @@ * Note that even if resolved, some voices may still be playing. |
@@ -10,17 +10,5 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import Synthesizer from './Synthesizer'; | ||
const _module = AudioWorkletGlobalScope.wasmModule; | ||
const promiseWasmInitialized = new Promise((resolve) => { | ||
if (_module.calledRun) { | ||
resolve(); | ||
} | ||
else { | ||
const fn = _module.onRuntimeInitialized; | ||
_module.onRuntimeInitialized = () => { | ||
resolve(); | ||
if (fn) { | ||
fn(); | ||
} | ||
}; | ||
} | ||
}); | ||
import waitForReady from './waitForReady'; | ||
import { initializeReturnPort, postReturn } from './MethodMessaging'; | ||
const promiseWasmInitialized = waitForReady(); | ||
/** Registers processor using Synthesizer for AudioWorklet. */ | ||
@@ -34,5 +22,16 @@ export default function registerAudioWorkletProcessor() { | ||
super(options); | ||
this.port.onmessage = this.onMessage.bind(this); | ||
this.port.start(); | ||
this.promiseInitialized = this.doInit(); | ||
const promiseInitialized = this.doInit(); | ||
this._messaging = initializeReturnPort(this.port, promiseInitialized, () => this.synth, (data) => { | ||
if (data.method === 'init') { | ||
this.synth.init(sampleRate); | ||
return true; | ||
} | ||
else if (data.method === 'createSequencer') { | ||
this.doCreateSequencer(data.args[0]).then(() => { | ||
postReturn(this._messaging, data.id, data.method, void (0)); | ||
}); | ||
return true; | ||
} | ||
return false; | ||
}); | ||
} | ||
@@ -46,2 +45,7 @@ doInit() { | ||
} | ||
doCreateSequencer(port) { | ||
return Synthesizer.createSequencer().then((seq) => { | ||
initializeReturnPort(port, null, () => seq); | ||
}); | ||
} | ||
process(_inputs, outputs) { | ||
@@ -53,3 +57,3 @@ if (!this.synth) { | ||
syn.render(outputs[0]); | ||
this.post(-1, "updateStatus" /* UpdateStatus */, { | ||
postReturn(this._messaging, -1, "updateStatus" /* UpdateStatus */, { | ||
playing: syn.isPlaying(), | ||
@@ -60,56 +64,2 @@ playerPlaying: syn.isPlayerPlaying() | ||
} | ||
post(id, method, value) { | ||
if (value instanceof Promise) { | ||
value.then((v) => { | ||
if (id >= 0) { | ||
this.port.postMessage({ | ||
id, | ||
method, | ||
val: v | ||
}); | ||
} | ||
}, (error) => { | ||
this.port.postMessage({ | ||
id, | ||
method, | ||
error | ||
}); | ||
}); | ||
} | ||
else if (id >= 0) { | ||
this.port.postMessage({ | ||
id, | ||
method, | ||
val: value | ||
}); | ||
} | ||
} | ||
postError(id, method, error) { | ||
// always post even if id < 0 | ||
this.port.postMessage({ | ||
id, | ||
method, | ||
error | ||
}); | ||
} | ||
onMessage(ev) { | ||
const data = ev.data; | ||
this.promiseInitialized.then(() => { | ||
const syn = this.synth; | ||
if (data.method === 'init') { | ||
syn.init(sampleRate); | ||
} | ||
else if (!syn[data.method]) { | ||
this.postError(data.id, data.method, new Error('Not implemented')); | ||
} | ||
else { | ||
try { | ||
this.post(data.id, data.method, syn[data.method].apply(syn, data.args)); | ||
} | ||
catch (e) { | ||
this.postError(data.id, data.method, e); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
@@ -116,0 +66,0 @@ registerProcessor("fluid-js" /* ProcessorName */, Processor); |
import { InterpolationValues } from './Constants'; | ||
import ISequencer from './ISequencer'; | ||
import ISynthesizer from './ISynthesizer'; | ||
@@ -48,3 +49,12 @@ /** Default implementation of ISynthesizer */ | ||
stopPlayer(): void; | ||
retrievePlayerCurrentTick(): Promise<number>; | ||
retrievePlayerTotalTicks(): Promise<number>; | ||
retrievePlayerBpm(): Promise<number>; | ||
retrievePlayerMIDITempo(): Promise<number>; | ||
seekPlayer(ticks: number): void; | ||
waitForPlayerStopped(): Promise<void>; | ||
/** | ||
* Create the sequencer object for this class. | ||
*/ | ||
static createSequencer(): Promise<ISequencer>; | ||
} |
@@ -1,2 +0,3 @@ | ||
const INVALID_POINTER = 0; | ||
import { INVALID_POINTER } from './PointerType'; | ||
import Sequencer from './Sequencer'; | ||
const _module = typeof AudioWorkletGlobalScope !== 'undefined' ? | ||
@@ -266,2 +267,22 @@ AudioWorkletGlobalScope.wasmModule : Module; | ||
} | ||
retrievePlayerCurrentTick() { | ||
this.ensurePlayerInitialized(); | ||
return Promise.resolve(_module._fluid_player_get_current_tick(this._player)); | ||
} | ||
retrievePlayerTotalTicks() { | ||
this.ensurePlayerInitialized(); | ||
return Promise.resolve(_module._fluid_player_get_total_ticks(this._player)); | ||
} | ||
retrievePlayerBpm() { | ||
this.ensurePlayerInitialized(); | ||
return Promise.resolve(_module._fluid_player_get_bpm(this._player)); | ||
} | ||
retrievePlayerMIDITempo() { | ||
this.ensurePlayerInitialized(); | ||
return Promise.resolve(_module._fluid_player_get_midi_tempo(this._player)); | ||
} | ||
seekPlayer(ticks) { | ||
this.ensurePlayerInitialized(); | ||
_module._fluid_player_seek(this._player, ticks); | ||
} | ||
/** @internal */ | ||
@@ -330,3 +351,10 @@ ensureInitialized() { | ||
} | ||
/** | ||
* Create the sequencer object for this class. | ||
*/ | ||
static createSequencer() { | ||
const seq = new Sequencer(); | ||
return seq._initialize().then(() => seq); | ||
} | ||
} | ||
//# sourceMappingURL=Synthesizer.js.map |
@@ -48,3 +48,3 @@ { | ||
"types": "./dist/lib/index.d.ts", | ||
"version": "1.0.1" | ||
"version": "1.1.0" | ||
} |
@@ -67,2 +67,3 @@ [![NPM version](https://badge.fury.io/js/fluid-js.svg)](https://www.npmjs.com/package/fluid-js) | ||
* `fluid.js` intends the ES2015-supported environment. If you need to run the script without errors on non-ES2015 environment such as IE11 (to notify 'unsupported'), you should load those scripts dynamically, or use transpiler such as babel. | ||
* When just after the scripts loaded, some APIs may fail since libfluidsynth is not ready. To avoid this, you can use the Promise object returned by `Fluid.waitForReady`. | ||
* libfluidsynth JS file is not `import`-able and its license (LGPL v2.1) is differ from fluid-js's (BSD-3-Clause). | ||
@@ -100,2 +101,22 @@ | ||
### With Web Worker | ||
fluid-js and libfluidsynth can be executed on a Web Worker. Executing on a Web Worker prevents from blocking main thread while rendering. | ||
To use fluid-js on a Web Worker, simply call `importScripts` as followings: | ||
```js | ||
self.importScripts('libfluidsynth-2.0.1.js'); | ||
self.importScripts('fluid.js'); | ||
``` | ||
(You can also load fluid-js as an ES Module from the Web Worker.) | ||
Note that since the Web Audio is not supported on the Web Worker, the APIs/methods related to the Web Audio will not work. If you want to use both Web Worker and AudioWorklet, you should implement AudioWorkletProcessor manually as followings: | ||
* main thread -- create AudioWorkletNode and establish connections between Web Worker and AudioWorklet | ||
* You must transfer rendered audio frames from Web Worker to AudioWorklet because AudioWorklet environment does not support creating Web Worker. By creating `MessageChannel` and sending its port instances to Web Worker and AudioWorklet, they can communicate each other directly. | ||
* Web Worker thread -- render audio frames into raw buffers and send it for AudioWorklet thread | ||
* AudioWorklet thread -- receive audio frames and 'render' it in the `process` method | ||
## API | ||
@@ -111,3 +132,21 @@ | ||
* Creates the synthesizer instance communicating AudioWorklet (see above). No parameters are available. | ||
* You must call `createAudioNode` method to use other instance methods. | ||
### Creation of Sequencer instance | ||
The `Sequencer` instance is created only via following methods: | ||
* `Fluid.Synthesizer.createSequencer` (static method) | ||
* Returns the Promise object that resolves with `Fluid.ISequencer` instance. The instance can be used with `Fluid.Synthesizer` instances. | ||
* `Fluid.AudioWorkletNodeSynthesizer.prototype.createSequencer` (instance method) | ||
* Returns the Promise object that resolves with `Fluid.ISequencer` instance. The instance can be used with `Fluid.AudioWorkletNodeSynthesizer` instances which handled `createSequencer` calls. | ||
### `Fluid` methods | ||
#### `waitForReady` | ||
Can be used to wait for the synthesizer engine's ready. | ||
Return: `Promise` object (resolves when the synthesizer engine (libfluidsynth) is ready) | ||
### `Fluid.ISynthesizer` methods | ||
@@ -114,0 +153,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
1067455
57
10323
157