Skip to content

Commit

Permalink
prog
Browse files Browse the repository at this point in the history
  • Loading branch information
Yisheng Jiang committed May 18, 2024
1 parent f71a3ef commit 02bcddf
Show file tree
Hide file tree
Showing 8 changed files with 382 additions and 17 deletions.
178 changes: 178 additions & 0 deletions fifolol/midiread.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
export function readMidi(buffer) {
const reader = bufferReader2(buffer);
const {fgetc, btoa, read32, readVarLength, read16} =
reader;
const chunkType = [btoa(), btoa(), btoa(), btoa()].join("");
const headerLength = read32();

const DEFAULT_TEMPO = {
tempo: 500000, //msqn,
t: 0 //start time
}
const format = read16();
const ntracks = read16();
const division = read16();
const headerInfo = {chunkType, headerLength, format};
const tracks = [];
const DEFAULT_TIMEBASE = {
relative_ts: 4, numerator: 4, denum: 4, ticksPerBeat: division, eigthNotePerBeat: 8
};
const limit = buffer.byteLength;
let lasttype;

const presets = [];
const tempos = [];
let time_base = null;
while (reader.offset < limit) {
console.log(fgetc(), fgetc(), fgetc(), fgetc());
let t = 0;
const mhrkLength = read32();
const endofTrack = reader.offset + mhrkLength;
const track = [];
while (reader.offset < limit && reader.offset < endofTrack) {
const delay = readVarLength();
const nextEvent = readNextEvent();
if (!nextEvent) break;
if (nextEvent.eot) break;
t += delay;
if (nextEvent.relative_ts) {
time_base = nextEvent;
track.push({offset: reader.offset, t, delay, ...nextEvent});
}
if (nextEvent.tempo) {
tempos.push({
t,
delay,
track: track.length,
...nextEvent,
});
const evtObj = {offset: reader.offset, t, delay, ...nextEvent};
track.push(evtObj);
} else if (nextEvent.channel && nextEvent.channel[0] >> 4 === 0x0c) {
presets.push({
t,
channel: nextEvent.channel[0] & 0x0f,
pid: nextEvent.channel[1] & 0x7f,
});
const evtObj = {offset: reader.offset, t, delay, ...nextEvent};
track.push(evtObj);
} else {
const evtObj = {offset: reader.offset, t, delay, ...nextEvent};
track.push(evtObj);
}
}
if (track.length) tracks.push(track);
reader.offset = endofTrack;
}
if (time_base == null) {
time_base = DEFAULT_TIMEBASE
}
if (tempos.length === 0) {
tempos.push(DEFAULT_TEMPO)
}
return {headerInfo, division, tracks, ntracks, presets, tempos, time_base};
function readNextEvent() {
const {fgetc, read24, readString, readVarLength} = reader;
let type = fgetc();
if (type === null) return [];
if ((type & 0xf0) === 0xf0) {
switch (type) {
case 0xff: {
const meta = fgetc();
const len = readVarLength();
switch (meta) {
case 0x21:
return {port: fgetc()};
case 0x51:
return {tempo: read24()};
case 0x58: //0xFF 0x58 0x04 [
// 0x04 0x02 0x18 0x08
const [numerator, denomP2, ticksPerBeat, eigthNotePerBeat] = [fgetc(), fgetc(), fgetc(), fgetc()];
const denum = Math.pow(2, denomP2);
const relative_ts = numerator / denum * 4;
return {relative_ts, numerator, denum, ticksPerBeat, eigthNotePerBeat};
case 0x59:
return {meta, payload: [fgetc(), fgetc()]};
default:
return {meta, payload: readString(len), len};
}
}
case 0xf0:
case 0xf7:
return {sysex: readString(readVarLength())};
default:
return {type, system: readString(readVarLength())};
}
} else {
let param;
if (0 === (type & 0x80)) {
param = type;
type = lasttype;
} else {
param = fgetc();
lasttype = type;
}
switch (type >> 4) {
case 0x0c:
case 0x0d:
return {
ch: type & 0x0f,
cmd: (type >> 4).toString(16),
channel: [type, param, 0],
};
default:
return {
ch: type & 0x0f,
cmd: (type >> 4).toString(16),
channel: [type, param, fgetc()],
};
}
}
}
}
function bufferReader2(bytes) {
let _offset = 0;
const fgetc = () => bytes[_offset++];
const read32 = () =>
(fgetc() << 24) | (fgetc() << 16) | (fgetc() << 8) | fgetc();
const read16 = () => (fgetc() << 8) | fgetc();
const read24 = () => (fgetc() << 16) | (fgetc() << 8) | fgetc();
function readVarLength() {
let v = 0;
let n = fgetc();
v = n & 0x7f;
while (n & 0x80) {
n = fgetc();
v = (v << 7) | (n & 0x7f);
}
return v;
}
function btoa() {
const code = fgetc();
return code >= 32 && code <= 122
? ` !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[~]^_@abcdefghijklmnopqrstuvwxyz`.split(
""
)[code - 32]
: code;
}
const readString = (n) => {
let str = "";
while (n--) str += btoa();
return str;
};
return {
get offset() {
return _offset;
},
set offset(o) {
_offset = o;
},
fgetc,
read32,
read24,
read16,
readVarLength,
readString,
btoa,
};
}
21 changes: 21 additions & 0 deletions fifolol/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions fifolol/package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
{
"name": "grep-fifo",
"type": "module",
"version": "1.0.0",
"description": "ES6 compliant and (typescript friendly) implementation of circular fifo in C99",
"main": "fifo.wasmodule.js",
"scripts": {
"build": "docker run --rm -v `pwd`:/src trzeci/emscripten-slim emcc yofi.c -s EXPORT_ALL=1 -o yofi.js",
"test": "node ./test.js"
"test": "node ./test.mjs"
},
"keywords": [
"pain in the arse",
"allegedly faster than javascript"
],
"author": "",
"license": "ISC"
"license": "ISC",
"dependencies": {
"midi-file": "^1.2.4"
}
}
17 changes: 6 additions & 11 deletions fifolol/src/yofi.c
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
#include <stdint.h>

#define QUEUE_SIZE 1 << 16
#define QUEUE_SIZE 0xffff

typedef struct {
uint16_t head;
uint16_t tail;
char data[QUEUE_SIZE];
uint8_t data[QUEUE_SIZE];
} queue_t;

queue_t instance[1];

queue_t* getInstance() { return instance; }
int queue_count(queue_t* queue) { return queue->head - queue->tail; }
uint8_t queue_read(queue_t* queue) { return queue->data[queue->tail++] & 0xff; }

uint16_t queue_count(queue_t* queue) { return queue->head - queue->tail; }

char queue_read(queue_t* queue) {
if (queue->tail == queue->head) return 0;
return queue->data[queue->tail++];
}

int queue_write(queue_t* queue, char c) {
int queue_write(queue_t* queue, uint8_t c) {
if (queue->tail - queue->head >= QUEUE_SIZE) return 1;
queue->data[queue->head++] = c;
return 0;
}
12 changes: 9 additions & 3 deletions fifolol/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@
}
});
const qq = ll.exports.getInstance();
fetch("song.mid").then(r => r.arrayBuffer).then(ab => {
fetch("song.mid").then(r => r.arrayBuffer()).then(ab => {
const arr = new Uint8Array(ab);
let off = 0;
while (ll.exports.queue_write(qq, arr[off++]));
let off = 0; debugger;
while (off < arr.length) {
while (ll.exports.queue_write(qq, arr[off]) < 1);
while (ll.exports.queue_count(qq) > 1) {
console.log(ll.exports.queue_read(qq));
}
off++;
}

})

Expand Down
Loading

0 comments on commit 02bcddf

Please sign in to comment.