midi-json-parser
midi-json-parser copied to clipboard
Fixed to run in Node
This is going to be super for testing that midi files were saved properly.
The code for the converted is very basic - 100 lines tops. Please let me know how you would like to proceed - a fork perhaps? or I can paste in comments?
I'm also horrible at making libraries in javascript, so it's currently just importing the file
import {parseArrayBuffer} from "../../../midi-json-fornof-worker/src/module"
perhaps you can help me fix that? Otherwise it looks hackish but still works.
Issues
I'm mainly going off of this issue that Node isn't supported but it can be ported, but also off of the requests for it to be ported to Node
https://github.com/chrisguttandin/midi-json-parser/issues/371 https://github.com/chrisguttandin/midi-json-parser/issues/378 https://github.com/chrisguttandin/midi-json-parser/issues/371
Solution:
- I converted Buffer to ArrayBuffer
- I used the worker file found in the first issue and built from that.
- I created an import to modules.ts
- I modified the package.json a wee bit - not sure if any of that mattered
- I added a tsconfig.json, not sure if that mattered.
- I imported into my sample music program that writes to midi.
well, here are the files if anyone wants to modify them:
MidiJson.ts
import {parseArrayBuffer} from "../../external/midi-json-fornof-worker/src/module"
// Let's assume there is an ArrayBuffer called arrayBuffer which contains the binary content of a
// MIDI file.
export default class MidiJson{
midiBufferToJson(buffer:Buffer){
return parseArrayBuffer(buffer)
}
}
midi-json-parser-worker : module.ts
import { TWorkerImplementation, createWorker } from 'worker-factory';
import { IMidiJsonParserWorkerCustomDefinition } from './interfaces';
import {parseArrayBuffer} from './midi-file-parser';
export {parserArrayBuffer}
/*
* @todo Explicitly referencing the barrel file seems to be necessary when enabling the
* isolatedModules compiler option.
*/
export * from './interfaces/index';
export * from './types/index';
// createWorker<IMidiJsonParserWorkerCustomDefinition>(self, <TWorkerImplementation<IMidiJsonParserWorkerCustomDefinition>>{
// parse: ({ arrayBuffer }) => {
// const midiFile = parseArrayBuffer(arrayBuffer);
// return { result: midiFile };
// }
// });
midi-json-parser-worker: src/midi-file-parser.ts
//...
function toArrayBuffer(buffer:Buffer) {
const arrayBuffer = new ArrayBuffer(buffer.length);
const view = new Uint8Array(arrayBuffer);
for (let i = 0; i < buffer.length; ++i) {
view[i] = buffer[i];
}
return arrayBuffer;
}
export async function nodeParseArrayBuffer(buffer:Buffer){
return parseArrayBuffer(toArrayBuffer(buffer))
}
k, hope that helps someone.
Hi @fornof, thanks picking this up again. I got inspired and came up with this.
let listener;
let result;
globalThis.self = {
addEventListener: (...args) => listener = args[1],
postMessage: (...args) => ({result} = args[0]),
removeEventListener: () => { }
};
require('midi-json-parser-worker');
delete globalThis.self;
let id = 0;
const parseArrayBuffer = (arrayBuffer) => {
listener({
data: {
id,
method: 'parse',
params: { arrayBuffer }
}
});
id += 1;
return result;
}
const parseBuffer = (buffer) => parseArrayBuffer(buffer.buffer);
module.exports = { parseArrayBuffer, parseBuffer };
It should work as long as you can still use CommonJS in your project and you don't use TypeScript. It's maybe a bit cleaner since you don't have to patch the existing package.
But overall I think supporting Node.js should be possible with a few tweaks these days. I've already created two packages to abstract away the usage of Web Workers. It should be possible to adapt those to work with worker_threads on Node.js, too.