@ugfoundation/swaralipi-js 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{batch-QPSHVNDS.js → batch-TVEIT2OJ.js} +4 -4
- package/dist/{batch-QPSHVNDS.js.map → batch-TVEIT2OJ.js.map} +1 -1
- package/dist/{chunk-VCRWS3F3.js → chunk-HDN3YZ6K.js} +3 -3
- package/dist/{chunk-VCRWS3F3.js.map → chunk-HDN3YZ6K.js.map} +1 -1
- package/dist/{chunk-4YTOLN3C.js → chunk-WBSIKYWB.js} +3 -3
- package/dist/{chunk-4YTOLN3C.js.map → chunk-WBSIKYWB.js.map} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/convert/index.cjs +1 -1
- package/dist/convert/index.cjs.map +1 -1
- package/dist/convert/index.js +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/player/index.cjs +59 -18
- package/dist/player/index.cjs.map +1 -1
- package/dist/player/index.d.cts +15 -9
- package/dist/player/index.d.ts +15 -9
- package/dist/player/index.js +60 -19
- package/dist/player/index.js.map +1 -1
- package/dist/{schedule-PTHUONrA.d.ts → schedule-BhiP_maG.d.ts} +1 -1
- package/dist/{schedule-DhO_Xzz4.d.cts → schedule-Dsb2paUE.d.cts} +1 -1
- package/dist/spec/index.cjs +1 -1
- package/dist/spec/index.cjs.map +1 -1
- package/dist/spec/index.d.cts +1 -1
- package/dist/spec/index.d.ts +1 -1
- package/dist/spec/index.js +1 -1
- package/dist/viewer/index.cjs +1 -1
- package/dist/viewer/index.cjs.map +1 -1
- package/dist/viewer/index.d.cts +1 -1
- package/dist/viewer/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/player/index.cjs
CHANGED
|
@@ -1066,34 +1066,72 @@ function utf8(s) {
|
|
|
1066
1066
|
function u32be(n) {
|
|
1067
1067
|
return [n >>> 24 & 255, n >>> 16 & 255, n >>> 8 & 255, n & 255];
|
|
1068
1068
|
}
|
|
1069
|
+
var DRUM_NOTE = {
|
|
1070
|
+
kick: 36,
|
|
1071
|
+
snare: 38,
|
|
1072
|
+
hihat: 42,
|
|
1073
|
+
// closed hi-hat
|
|
1074
|
+
tom1: 48,
|
|
1075
|
+
tom2: 45,
|
|
1076
|
+
tom3: 41
|
|
1077
|
+
};
|
|
1078
|
+
function trackChunk(raw, head) {
|
|
1079
|
+
raw.sort((a, b) => a.tick - b.tick || Number(a.on) - Number(b.on));
|
|
1080
|
+
const track = [...head];
|
|
1081
|
+
let last = 0;
|
|
1082
|
+
for (const e of raw) {
|
|
1083
|
+
const status = (e.on ? 144 : 128) | e.ch & 15;
|
|
1084
|
+
track.push(...vlq(e.tick - last), status, e.note & 127, e.vel & 127);
|
|
1085
|
+
last = e.tick;
|
|
1086
|
+
}
|
|
1087
|
+
track.push(...vlq(0), 255, 47, 0);
|
|
1088
|
+
return [77, 84, 114, 107, ...u32be(track.length), ...track];
|
|
1089
|
+
}
|
|
1069
1090
|
function encodeMidi(schedule, opts) {
|
|
1070
|
-
const
|
|
1091
|
+
const melody = [];
|
|
1071
1092
|
for (const ev of schedule.events) {
|
|
1072
1093
|
if (ev.midi === null) continue;
|
|
1073
1094
|
const start = Math.round(ev.beat * PPQ);
|
|
1074
1095
|
const end = Math.max(Math.round((ev.beat + ev.durationBeats) * PPQ), start + 1);
|
|
1075
1096
|
if (ev.kan !== null) {
|
|
1076
1097
|
const kOn = Math.max(start - Math.round(0.12 * PPQ), 0);
|
|
1077
|
-
|
|
1078
|
-
|
|
1098
|
+
melody.push({ tick: kOn, on: true, note: ev.kan, vel: 70, ch: 0 });
|
|
1099
|
+
melody.push({ tick: start, on: false, note: ev.kan, vel: 0, ch: 0 });
|
|
1079
1100
|
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1101
|
+
melody.push({ tick: start, on: true, note: ev.midi, vel: 100, ch: 0 });
|
|
1102
|
+
melody.push({ tick: end, on: false, note: ev.midi, vel: 0, ch: 0 });
|
|
1082
1103
|
}
|
|
1083
|
-
raw.sort((a, b) => a.tick - b.tick || Number(a.on) - Number(b.on));
|
|
1084
|
-
const track = [];
|
|
1085
|
-
if (opts.name) track.push(...vlq(0), 255, 3, ...vlq(utf8(opts.name).length), ...utf8(opts.name));
|
|
1086
1104
|
const usPerBeat = Math.round(6e7 / opts.bpm);
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1105
|
+
const head = [];
|
|
1106
|
+
if (opts.name) head.push(...vlq(0), 255, 3, ...vlq(utf8(opts.name).length), ...utf8(opts.name));
|
|
1107
|
+
head.push(...vlq(0), 255, 81, 3, usPerBeat >> 16 & 255, usPerBeat >> 8 & 255, usPerBeat & 255);
|
|
1108
|
+
const chunks = [trackChunk(melody, head)];
|
|
1109
|
+
if (opts.drums && opts.drums.length > 0) {
|
|
1110
|
+
const drum = [];
|
|
1111
|
+
const totalBeats = Math.ceil(schedule.totalBeats);
|
|
1112
|
+
for (let beat = 0; beat < totalBeats; beat++) {
|
|
1113
|
+
const note = DRUM_NOTE[opts.drums[beat % opts.drums.length]];
|
|
1114
|
+
const t = beat * PPQ;
|
|
1115
|
+
drum.push({ tick: t, on: true, note, vel: 100, ch: 9 });
|
|
1116
|
+
drum.push({ tick: t + Math.round(PPQ / 4), on: false, note, vel: 0, ch: 9 });
|
|
1117
|
+
}
|
|
1118
|
+
chunks.push(trackChunk(drum, [...vlq(0), 255, 3, ...vlq(5), 68, 114, 117, 109, 115]));
|
|
1092
1119
|
}
|
|
1093
|
-
|
|
1094
|
-
const header = [
|
|
1095
|
-
|
|
1096
|
-
|
|
1120
|
+
const format = chunks.length > 1 ? 1 : 0;
|
|
1121
|
+
const header = [
|
|
1122
|
+
77,
|
|
1123
|
+
84,
|
|
1124
|
+
104,
|
|
1125
|
+
100,
|
|
1126
|
+
...u32be(6),
|
|
1127
|
+
0,
|
|
1128
|
+
format,
|
|
1129
|
+
chunks.length >> 8 & 255,
|
|
1130
|
+
chunks.length & 255,
|
|
1131
|
+
PPQ >> 8 & 255,
|
|
1132
|
+
PPQ & 255
|
|
1133
|
+
];
|
|
1134
|
+
return new Uint8Array([...header, ...chunks.flat()]);
|
|
1097
1135
|
}
|
|
1098
1136
|
function safeName2(title) {
|
|
1099
1137
|
return (title ?? "").replace(/[\\/:*?"<>|]+/g, "").trim() || "swaralipi";
|
|
@@ -1101,7 +1139,10 @@ function safeName2(title) {
|
|
|
1101
1139
|
function exportMidi(doc, options = {}) {
|
|
1102
1140
|
const schedule = buildSchedule(doc, { tonic: options.tonic, baseOctave: options.baseOctave });
|
|
1103
1141
|
const bpm = options.bpm ?? doc.meta.bpm ?? 90;
|
|
1104
|
-
const
|
|
1142
|
+
const taalId = doc.meta.taal?.id;
|
|
1143
|
+
const taal = taalId !== void 0 && taalId in TAALS ? TAALS[taalId] : { numBeats: 4, sam: 0 };
|
|
1144
|
+
const drums = options.drums ? drumPattern(taal) : void 0;
|
|
1145
|
+
const bytes = encodeMidi(schedule, { bpm, name: options.name ?? doc.meta.title, drums });
|
|
1105
1146
|
return {
|
|
1106
1147
|
blob: new Blob([bytes], { type: "audio/midi" }),
|
|
1107
1148
|
filename: `${safeName2(doc.meta.title)}.mid`,
|