@ugfoundation/swaralipi-js 0.3.0 → 0.3.2

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.
Files changed (44) hide show
  1. package/dist/{batch-QPSHVNDS.js → batch-5LFXQ67K.js} +5 -5
  2. package/dist/{batch-QPSHVNDS.js.map → batch-5LFXQ67K.js.map} +1 -1
  3. package/dist/{chunk-V5ZSUJCA.js → chunk-32LOBRC2.js} +3 -3
  4. package/dist/{chunk-V5ZSUJCA.js.map → chunk-32LOBRC2.js.map} +1 -1
  5. package/dist/{chunk-4YTOLN3C.js → chunk-QVNFEWMM.js} +6 -6
  6. package/dist/chunk-QVNFEWMM.js.map +1 -0
  7. package/dist/{chunk-VCRWS3F3.js → chunk-XQYXZPHK.js} +3 -3
  8. package/dist/{chunk-VCRWS3F3.js.map → chunk-XQYXZPHK.js.map} +1 -1
  9. package/dist/{chunk-H6HC44PZ.js → chunk-YE7UVYRY.js} +5 -3
  10. package/dist/chunk-YE7UVYRY.js.map +1 -0
  11. package/dist/cli.cjs +6 -4
  12. package/dist/cli.cjs.map +1 -1
  13. package/dist/cli.js +3 -3
  14. package/dist/convert/index.cjs +6 -4
  15. package/dist/convert/index.cjs.map +1 -1
  16. package/dist/convert/index.js +3 -3
  17. package/dist/index.cjs +4 -2
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +1 -1
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.js +2 -2
  22. package/dist/player/index.cjs +62 -19
  23. package/dist/player/index.cjs.map +1 -1
  24. package/dist/player/index.d.cts +16 -10
  25. package/dist/player/index.d.ts +16 -10
  26. package/dist/player/index.js +63 -22
  27. package/dist/player/index.js.map +1 -1
  28. package/dist/{schedule-PTHUONrA.d.ts → schedule-BaE3JGHe.d.ts} +2 -2
  29. package/dist/{schedule-DhO_Xzz4.d.cts → schedule-CHXz3V6T.d.cts} +2 -2
  30. package/dist/spec/index.cjs +4 -2
  31. package/dist/spec/index.cjs.map +1 -1
  32. package/dist/spec/index.d.cts +2 -2
  33. package/dist/spec/index.d.ts +2 -2
  34. package/dist/spec/index.js +2 -2
  35. package/dist/{taals-FmEulsjY.d.cts → taals-DxJ8wRtF.d.cts} +8 -1
  36. package/dist/{taals-FmEulsjY.d.ts → taals-DxJ8wRtF.d.ts} +8 -1
  37. package/dist/viewer/index.cjs +4 -2
  38. package/dist/viewer/index.cjs.map +1 -1
  39. package/dist/viewer/index.d.cts +2 -2
  40. package/dist/viewer/index.d.ts +2 -2
  41. package/dist/viewer/index.js +2 -2
  42. package/package.json +1 -1
  43. package/dist/chunk-4YTOLN3C.js.map +0 -1
  44. package/dist/chunk-H6HC44PZ.js.map +0 -1
@@ -15,8 +15,10 @@ var TAALS = {
15
15
  teora: { id: "teora", numBeats: 7, bhaags: [3, 2, 2], sam: 0 },
16
16
  // টেওরা
17
17
  teentaal: { id: "teentaal", numBeats: 16, bhaags: [4, 4, 4, 4], sam: 0, khaali: [8] },
18
- aratheka: { id: "aratheka", numBeats: 16, bhaags: [4, 4, 4, 4], sam: 0, khaali: [8] }
18
+ aratheka: { id: "aratheka", numBeats: 16, bhaags: [4, 4, 4, 4], sam: 0, khaali: [8] },
19
19
  // আড়াঠেকা
20
+ jhampak: { id: "jhampak", numBeats: 5, bhaags: [3, 2], sam: 0 }
21
+ // ঝম্পক
20
22
  };
21
23
 
22
24
  // src/player/pitch.ts
@@ -1066,34 +1068,72 @@ function utf8(s) {
1066
1068
  function u32be(n) {
1067
1069
  return [n >>> 24 & 255, n >>> 16 & 255, n >>> 8 & 255, n & 255];
1068
1070
  }
1071
+ var DRUM_NOTE = {
1072
+ kick: 36,
1073
+ snare: 38,
1074
+ hihat: 42,
1075
+ // closed hi-hat
1076
+ tom1: 48,
1077
+ tom2: 45,
1078
+ tom3: 41
1079
+ };
1080
+ function trackChunk(raw, head) {
1081
+ raw.sort((a, b) => a.tick - b.tick || Number(a.on) - Number(b.on));
1082
+ const track = [...head];
1083
+ let last = 0;
1084
+ for (const e of raw) {
1085
+ const status = (e.on ? 144 : 128) | e.ch & 15;
1086
+ track.push(...vlq(e.tick - last), status, e.note & 127, e.vel & 127);
1087
+ last = e.tick;
1088
+ }
1089
+ track.push(...vlq(0), 255, 47, 0);
1090
+ return [77, 84, 114, 107, ...u32be(track.length), ...track];
1091
+ }
1069
1092
  function encodeMidi(schedule, opts) {
1070
- const raw = [];
1093
+ const melody = [];
1071
1094
  for (const ev of schedule.events) {
1072
1095
  if (ev.midi === null) continue;
1073
1096
  const start = Math.round(ev.beat * PPQ);
1074
1097
  const end = Math.max(Math.round((ev.beat + ev.durationBeats) * PPQ), start + 1);
1075
1098
  if (ev.kan !== null) {
1076
1099
  const kOn = Math.max(start - Math.round(0.12 * PPQ), 0);
1077
- raw.push({ tick: kOn, on: true, note: ev.kan, vel: 70 });
1078
- raw.push({ tick: start, on: false, note: ev.kan, vel: 0 });
1100
+ melody.push({ tick: kOn, on: true, note: ev.kan, vel: 70, ch: 0 });
1101
+ melody.push({ tick: start, on: false, note: ev.kan, vel: 0, ch: 0 });
1079
1102
  }
1080
- raw.push({ tick: start, on: true, note: ev.midi, vel: 100 });
1081
- raw.push({ tick: end, on: false, note: ev.midi, vel: 0 });
1103
+ melody.push({ tick: start, on: true, note: ev.midi, vel: 100, ch: 0 });
1104
+ melody.push({ tick: end, on: false, note: ev.midi, vel: 0, ch: 0 });
1082
1105
  }
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
1106
  const usPerBeat = Math.round(6e7 / opts.bpm);
1087
- track.push(...vlq(0), 255, 81, 3, usPerBeat >> 16 & 255, usPerBeat >> 8 & 255, usPerBeat & 255);
1088
- let last = 0;
1089
- for (const e of raw) {
1090
- track.push(...vlq(e.tick - last), e.on ? 144 : 128, e.note & 127, e.vel & 127);
1091
- last = e.tick;
1107
+ const head = [];
1108
+ if (opts.name) head.push(...vlq(0), 255, 3, ...vlq(utf8(opts.name).length), ...utf8(opts.name));
1109
+ head.push(...vlq(0), 255, 81, 3, usPerBeat >> 16 & 255, usPerBeat >> 8 & 255, usPerBeat & 255);
1110
+ const chunks = [trackChunk(melody, head)];
1111
+ if (opts.drums && opts.drums.length > 0) {
1112
+ const drum = [];
1113
+ const totalBeats = Math.ceil(schedule.totalBeats);
1114
+ for (let beat = 0; beat < totalBeats; beat++) {
1115
+ const note = DRUM_NOTE[opts.drums[beat % opts.drums.length]];
1116
+ const t = beat * PPQ;
1117
+ drum.push({ tick: t, on: true, note, vel: 100, ch: 9 });
1118
+ drum.push({ tick: t + Math.round(PPQ / 4), on: false, note, vel: 0, ch: 9 });
1119
+ }
1120
+ chunks.push(trackChunk(drum, [...vlq(0), 255, 3, ...vlq(5), 68, 114, 117, 109, 115]));
1092
1121
  }
1093
- track.push(...vlq(0), 255, 47, 0);
1094
- const header = [77, 84, 104, 100, ...u32be(6), 0, 0, 0, 1, PPQ >> 8 & 255, PPQ & 255];
1095
- const trackChunk = [77, 84, 114, 107, ...u32be(track.length), ...track];
1096
- return new Uint8Array([...header, ...trackChunk]);
1122
+ const format = chunks.length > 1 ? 1 : 0;
1123
+ const header = [
1124
+ 77,
1125
+ 84,
1126
+ 104,
1127
+ 100,
1128
+ ...u32be(6),
1129
+ 0,
1130
+ format,
1131
+ chunks.length >> 8 & 255,
1132
+ chunks.length & 255,
1133
+ PPQ >> 8 & 255,
1134
+ PPQ & 255
1135
+ ];
1136
+ return new Uint8Array([...header, ...chunks.flat()]);
1097
1137
  }
1098
1138
  function safeName2(title) {
1099
1139
  return (title ?? "").replace(/[\\/:*?"<>|]+/g, "").trim() || "swaralipi";
@@ -1101,7 +1141,10 @@ function safeName2(title) {
1101
1141
  function exportMidi(doc, options = {}) {
1102
1142
  const schedule = buildSchedule(doc, { tonic: options.tonic, baseOctave: options.baseOctave });
1103
1143
  const bpm = options.bpm ?? doc.meta.bpm ?? 90;
1104
- const bytes = encodeMidi(schedule, { bpm, name: options.name ?? doc.meta.title });
1144
+ const taalId = doc.meta.taal?.id;
1145
+ const taal = taalId !== void 0 && taalId in TAALS ? TAALS[taalId] : { numBeats: 4, sam: 0 };
1146
+ const drums = options.drums ? drumPattern(taal) : void 0;
1147
+ const bytes = encodeMidi(schedule, { bpm, name: options.name ?? doc.meta.title, drums });
1105
1148
  return {
1106
1149
  blob: new Blob([bytes], { type: "audio/midi" }),
1107
1150
  filename: `${safeName2(doc.meta.title)}.mid`,