-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* initial * audio processor added * some changes * poc impl. * changed * testmidi changed * instrument added * different track/instruments impl * note off and velocity impl * testfiles separated * setup test build * missing file added * mario underworld added * * buffered rendering impl * fade out impl * render is async now clean up * velocity exp * velocity back to lin * pitch added * before changing midi parser * midi parser changed pithcbend impl * pitch shifting sound glitches fixed * CC pan/expr impl * IMidiEvent refactoring MidiEventNotification impl. * * generating d.ts files during deployment * build script updated * babel added * missing file added * absolute tick position added to event * package json version updated * using index.d.ts now * missing d.ts file added * ppq was set to public * fixed: volume, expression, pitch values might not be correct * package version increased * forced samplerate in audio context to 44100 * did some polish: * stop event will be triggered after playback is done * fadeout time increased * fixed bug for midi files which have no track id * package moved to organization * readme updated * typo fixed * volume increased * missing files added * webpack setup * my renderer removed * fetch samples impl performCompose called * soundfont generation complete * playback is working ! * depecndecy build script added * removed files readded * build js-synth step added to CI * * CI branch added * player workflow opimized * license changed to matching to js-synthesizer * loading speed of smaples improves * set parcel version fix to 1.12.3 due this bug: parcel-bundler/parcel#5955 * sfcompose version udpated * stop handling improved * dependencies set up as dev dependencies * download last soundfont hack imp * sf issues fixed * * buffer size changable * repo url changable * synth rendering using audioworklet * build process optimized * jsbuild as dev dependency * fixed audioworklet version * * event notification after player play * prerenders the whole file now * repo url changed, blocksize changed * percussion handling changed * rendering via webworker impl * webworker block rendering impl * js-buildsynth replaced by parcel fs * renderer stop behaviour improved * renderer block size options changed to rendererBufferSeconds * jssynth preload optimized * start/stop behaviour improved * early stop bug fixed * test * test 2 * test 3 * merge saved Co-authored-by: samba <samba@manjaro> Co-authored-by: Samba Godschynski <[email protected]>
- Loading branch information
1 parent
283d085
commit 2f759d3
Showing
12 changed files
with
9,033 additions
and
1,205 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,5 @@ | ||
# Just another MIDI player | ||
* instead of triggering note events by a timer, this player prerenders a MIDI file to an [AudioBuffer](https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer). So the result is more precise regarding the timing than other JS MIDI players, but on the other hand the precalculation needs a bit of extra time | ||
* uses [midifile](https://github.com/nfroidure/midifile) for parsing midi data. | ||
* uses [js-synthesizer](https://github.com/jet2jet/js-synthesizer) | ||
* uses [soundfont-server](https://github.com/werckme/soundfont-server) | ||
* uses [midifile](https://github.com/nfroidure/midifile) for parsing midi data. | ||
* used by [werckmeister component](https://github.com/werckme/werckmeister-component) | ||
|
||
|
||
## Supported MIDI events | ||
* Note On | ||
* Note Off | ||
* CC | ||
* experssion | ||
* panorama | ||
* PC | ||
* Pitch Bend | ||
* Meta Events | ||
* Tempo |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
const RendererIdleTimeMillis = 100; | ||
|
||
function getSynth() { | ||
const _synth = new JSSynth.Synthesizer(); | ||
_synth.init(_sampleRate); | ||
return _synth; | ||
} | ||
|
||
const State = { | ||
stopped: 0, | ||
playing: 1, | ||
stopping: 2 | ||
} | ||
|
||
const session = { | ||
state: State.stopped | ||
} | ||
|
||
function render(sessionId, soundFontBff, midiBuffer, audioBufferLength, inBlockSize) { | ||
session.state = State.playing; | ||
session.sesisonId = sessionId; | ||
const synth = getSynth(); | ||
synth.loadSFont(soundFontBff).then(() => { | ||
synth.addSMFDataToPlayer(midiBuffer).then(() => { | ||
synth.playPlayer().then(()=> { | ||
let samplesLeft = audioBufferLength; | ||
function renderBlock() { | ||
if (samplesLeft <= 0 || session.state !== State.playing) { | ||
session.state = State.stopped; | ||
self.postMessage({sessionId, done: true}); | ||
return; | ||
} | ||
const blockSize = Math.min(inBlockSize, samplesLeft); | ||
const audioBuffer = [ | ||
new Float32Array(blockSize), | ||
new Float32Array(blockSize) | ||
]; | ||
synth.render(audioBuffer); | ||
const bffL = audioBuffer[0].buffer; | ||
const bffR = audioBuffer[1].buffer; | ||
const samplePos = audioBufferLength - samplesLeft; | ||
const lastBlock = (samplesLeft - blockSize) <= 0; | ||
self.postMessage({bffL, bffR, blockSize, samplePos, lastBlock, sessionId}, [bffL, bffR]); | ||
samplesLeft -= blockSize; | ||
setTimeout(renderBlock, RendererIdleTimeMillis); // aka. sleep | ||
} | ||
renderBlock(); | ||
}); | ||
}); | ||
}); | ||
} | ||
|
||
self.onmessage = function (msg) { | ||
if(msg.data.stop && session.state === State.playing) { | ||
session.state = State.stopping; | ||
return; | ||
} | ||
if (session.state !== State.stopped) { | ||
return; | ||
} | ||
const {soundFont, midiBuffer, audioBufferLength, blockSize, sampleRate, sessionId} = msg.data; | ||
_sampleRate = sampleRate; | ||
render(sessionId, soundFont, midiBuffer, audioBufferLength, blockSize); | ||
} | ||
|
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.