@sudobility/music_player 0.1.0 → 0.1.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 (159) hide show
  1. package/CLAUDE.md +335 -0
  2. package/dist/core.d.ts +33 -0
  3. package/dist/core.d.ts.map +1 -0
  4. package/dist/core.js +33 -0
  5. package/dist/core.js.map +1 -0
  6. package/dist/engine.d.ts +103 -0
  7. package/dist/engine.d.ts.map +1 -0
  8. package/dist/engine.js +2 -0
  9. package/dist/engine.js.map +1 -0
  10. package/dist/mocks/index.d.ts +46 -0
  11. package/dist/mocks/index.d.ts.map +1 -0
  12. package/dist/mocks/index.js +93 -0
  13. package/dist/mocks/index.js.map +1 -0
  14. package/dist/player.d.ts +81 -0
  15. package/dist/player.d.ts.map +1 -0
  16. package/dist/player.js +209 -0
  17. package/dist/player.js.map +1 -0
  18. package/dist/rn/audio/offline-render.d.ts +29 -0
  19. package/dist/rn/audio/offline-render.d.ts.map +1 -0
  20. package/dist/rn/audio/offline-render.js +134 -0
  21. package/dist/rn/audio/offline-render.js.map +1 -0
  22. package/dist/rn/index.d.ts +50 -0
  23. package/dist/rn/index.d.ts.map +1 -0
  24. package/dist/rn/index.js +39 -0
  25. package/dist/rn/index.js.map +1 -0
  26. package/dist/rn/playback/audio-api.d.ts +93 -0
  27. package/dist/rn/playback/audio-api.d.ts.map +1 -0
  28. package/dist/rn/playback/audio-api.js +24 -0
  29. package/dist/rn/playback/audio-api.js.map +1 -0
  30. package/dist/rn/playback/expression-table.d.ts +22 -0
  31. package/dist/rn/playback/expression-table.d.ts.map +1 -0
  32. package/dist/rn/playback/expression-table.js +926 -0
  33. package/dist/rn/playback/expression-table.js.map +1 -0
  34. package/dist/rn/playback/expression.d.ts +48 -0
  35. package/dist/rn/playback/expression.d.ts.map +1 -0
  36. package/dist/rn/playback/expression.js +120 -0
  37. package/dist/rn/playback/expression.js.map +1 -0
  38. package/dist/rn/playback/gm-pack-name.d.ts +40 -0
  39. package/dist/rn/playback/gm-pack-name.d.ts.map +1 -0
  40. package/dist/rn/playback/gm-pack-name.js +61 -0
  41. package/dist/rn/playback/gm-pack-name.js.map +1 -0
  42. package/dist/rn/playback/pack-library.d.ts +44 -0
  43. package/dist/rn/playback/pack-library.d.ts.map +1 -0
  44. package/dist/rn/playback/pack-library.js +85 -0
  45. package/dist/rn/playback/pack-library.js.map +1 -0
  46. package/dist/rn/playback/pack-names.json +130 -0
  47. package/dist/rn/playback/sample-engine.d.ts +216 -0
  48. package/dist/rn/playback/sample-engine.d.ts.map +1 -0
  49. package/dist/rn/playback/sample-engine.js +669 -0
  50. package/dist/rn/playback/sample-engine.js.map +1 -0
  51. package/dist/rn/playback/sample-pack.d.ts +71 -0
  52. package/dist/rn/playback/sample-pack.d.ts.map +1 -0
  53. package/dist/rn/playback/sample-pack.js +112 -0
  54. package/dist/rn/playback/sample-pack.js.map +1 -0
  55. package/dist/rn/playback/sustain-loop.d.ts +24 -0
  56. package/dist/rn/playback/sustain-loop.d.ts.map +1 -0
  57. package/dist/rn/playback/sustain-loop.js +111 -0
  58. package/dist/rn/playback/sustain-loop.js.map +1 -0
  59. package/dist/rn/playback/voice-plan.d.ts +60 -0
  60. package/dist/rn/playback/voice-plan.d.ts.map +1 -0
  61. package/dist/rn/playback/voice-plan.js +38 -0
  62. package/dist/rn/playback/voice-plan.js.map +1 -0
  63. package/dist/shared/bus.d.ts +73 -0
  64. package/dist/shared/bus.d.ts.map +1 -0
  65. package/dist/shared/bus.js +83 -0
  66. package/dist/shared/bus.js.map +1 -0
  67. package/dist/shared/midi.d.ts +18 -0
  68. package/dist/shared/midi.d.ts.map +1 -0
  69. package/dist/shared/midi.js +25 -0
  70. package/dist/shared/midi.js.map +1 -0
  71. package/dist/shared/mix.d.ts +75 -0
  72. package/dist/shared/mix.d.ts.map +1 -0
  73. package/dist/shared/mix.js +115 -0
  74. package/dist/shared/mix.js.map +1 -0
  75. package/dist/shared/note-queue.d.ts +43 -0
  76. package/dist/shared/note-queue.d.ts.map +1 -0
  77. package/dist/shared/note-queue.js +54 -0
  78. package/dist/shared/note-queue.js.map +1 -0
  79. package/dist/shared/plan.d.ts +34 -0
  80. package/dist/shared/plan.d.ts.map +1 -0
  81. package/dist/shared/plan.js +134 -0
  82. package/dist/shared/plan.js.map +1 -0
  83. package/dist/shared/pump-window.d.ts +38 -0
  84. package/dist/shared/pump-window.d.ts.map +1 -0
  85. package/dist/shared/pump-window.js +13 -0
  86. package/dist/shared/pump-window.js.map +1 -0
  87. package/dist/shared/render-events.d.ts +25 -0
  88. package/dist/shared/render-events.d.ts.map +1 -0
  89. package/dist/shared/render-events.js +79 -0
  90. package/dist/shared/render-events.js.map +1 -0
  91. package/dist/shared/sounding-set.d.ts +45 -0
  92. package/dist/shared/sounding-set.d.ts.map +1 -0
  93. package/dist/shared/sounding-set.js +81 -0
  94. package/dist/shared/sounding-set.js.map +1 -0
  95. package/dist/shared/test-plan.d.ts +36 -0
  96. package/dist/shared/test-plan.d.ts.map +1 -0
  97. package/dist/shared/test-plan.js +83 -0
  98. package/dist/shared/test-plan.js.map +1 -0
  99. package/dist/singleton.d.ts +23 -0
  100. package/dist/singleton.d.ts.map +1 -0
  101. package/dist/singleton.js +26 -0
  102. package/dist/singleton.js.map +1 -0
  103. package/dist/types.d.ts +84 -0
  104. package/dist/types.d.ts.map +1 -0
  105. package/dist/types.js +2 -0
  106. package/dist/types.js.map +1 -0
  107. package/dist/web/audio/offline-synth.d.ts +24 -0
  108. package/dist/web/audio/offline-synth.d.ts.map +1 -0
  109. package/dist/web/audio/offline-synth.js +92 -0
  110. package/dist/web/audio/offline-synth.js.map +1 -0
  111. package/dist/web/audio/soundfont-render.d.ts +31 -0
  112. package/dist/web/audio/soundfont-render.d.ts.map +1 -0
  113. package/dist/web/audio/soundfont-render.js +130 -0
  114. package/dist/web/audio/soundfont-render.js.map +1 -0
  115. package/dist/web/audio/synth-types.d.ts +24 -0
  116. package/dist/web/audio/synth-types.d.ts.map +1 -0
  117. package/dist/web/audio/synth-types.js +2 -0
  118. package/dist/web/audio/synth-types.js.map +1 -0
  119. package/dist/web/index.d.ts +40 -0
  120. package/dist/web/index.d.ts.map +1 -0
  121. package/dist/web/index.js +59 -0
  122. package/dist/web/index.js.map +1 -0
  123. package/dist/web/playback/channel-allocator.d.ts +54 -0
  124. package/dist/web/playback/channel-allocator.d.ts.map +1 -0
  125. package/dist/web/playback/channel-allocator.js +72 -0
  126. package/dist/web/playback/channel-allocator.js.map +1 -0
  127. package/dist/web/playback/click.d.ts +9 -0
  128. package/dist/web/playback/click.d.ts.map +1 -0
  129. package/dist/web/playback/click.js +61 -0
  130. package/dist/web/playback/click.js.map +1 -0
  131. package/dist/web/playback/clock.d.ts +36 -0
  132. package/dist/web/playback/clock.d.ts.map +1 -0
  133. package/dist/web/playback/clock.js +64 -0
  134. package/dist/web/playback/clock.js.map +1 -0
  135. package/dist/web/playback/governor.d.ts +45 -0
  136. package/dist/web/playback/governor.d.ts.map +1 -0
  137. package/dist/web/playback/governor.js +33 -0
  138. package/dist/web/playback/governor.js.map +1 -0
  139. package/dist/web/playback/quiet-stub-notices.d.ts +55 -0
  140. package/dist/web/playback/quiet-stub-notices.d.ts.map +1 -0
  141. package/dist/web/playback/quiet-stub-notices.js +93 -0
  142. package/dist/web/playback/quiet-stub-notices.js.map +1 -0
  143. package/dist/web/playback/soundfont-engine.d.ts +281 -0
  144. package/dist/web/playback/soundfont-engine.d.ts.map +1 -0
  145. package/dist/web/playback/soundfont-engine.js +735 -0
  146. package/dist/web/playback/soundfont-engine.js.map +1 -0
  147. package/dist/web/playback/soundfont-loader.d.ts +30 -0
  148. package/dist/web/playback/soundfont-loader.d.ts.map +1 -0
  149. package/dist/web/playback/soundfont-loader.js +68 -0
  150. package/dist/web/playback/soundfont-loader.js.map +1 -0
  151. package/dist/web/playback/synth-host.d.ts +142 -0
  152. package/dist/web/playback/synth-host.d.ts.map +1 -0
  153. package/dist/web/playback/synth-host.js +293 -0
  154. package/dist/web/playback/synth-host.js.map +1 -0
  155. package/package.json +18 -3
  156. package/dist/index.d.ts +0 -14
  157. package/dist/index.d.ts.map +0 -1
  158. package/dist/index.js +0 -2
  159. package/dist/index.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sample-engine.js","sourceRoot":"","sources":["../../../src/rn/playback/sample-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * FluidR3 sample packs: locating them, reading them, and choosing which sample
3
+ * plays a given note.
4
+ *
5
+ * All pure. The audio nodes are `sample-engine.ts`'s problem; everything here
6
+ * is string and number work, which is what makes the part of this engine most
7
+ * likely to be subtly wrong — pitch selection — testable without a device.
8
+ *
9
+ * The packs are Benjamin Gleitzman's pre-renderings of **FluidR3_GM.sf2**, the
10
+ * same font the web engine plays as `FluidR3Mono_GM.sf3`. That is the whole
11
+ * reason for choosing this route over synthesising something: React Native
12
+ * plays the same recordings the browser does, rather than an approximation of
13
+ * them.
14
+ *
15
+ * Each pack is a MIDI.js-era JavaScript file assigning an object of note name
16
+ * to base64 mp3 data URI:
17
+ *
18
+ * MIDI.Soundfont.violin = { "A0": "data:audio/mp3;base64,...", ... }
19
+ *
20
+ * It is parsed rather than evaluated. Running fetched JavaScript to read a
21
+ * lookup table would be an arbitrary-code-execution hole for a data file.
22
+ */
23
+ export type SamplePack = {
24
+ instrument: string;
25
+ /** MIDI note number -> base64 `data:audio/mp3` URI. Sparse: ~52 of 88 keys. */
26
+ samples: Map<number, string>;
27
+ };
28
+ export type SampleChoice = {
29
+ /** The sampled note actually played. */
30
+ midi: number;
31
+ uri: string;
32
+ /** How far to bend it to reach the requested note. 100 cents per semitone. */
33
+ detuneCents: number;
34
+ };
35
+ /**
36
+ * Where a GM instrument's pack lives. `base` lets an app self-host rather than
37
+ * depend on a third-party CDN at runtime — the packs are CC-BY 3.0, so copying
38
+ * them is allowed, and a music app that stops working when someone else's
39
+ * GitHub Pages does is not a good trade.
40
+ */
41
+ export declare function sampleUrlFor(instrument: string, base?: string): string;
42
+ /** `"F#4"` / `"Bb3"` / `"A0"` -> MIDI number, or null if it is not a note name. */
43
+ export declare function noteNameToMidi(name: string): number | null;
44
+ /**
45
+ * Reads a pack body. Throws rather than returning an empty pack: a 404 page
46
+ * parses to zero samples, and an instrument with no samples is silent playback
47
+ * with nothing reporting a problem.
48
+ */
49
+ export declare function parseSamplePack(body: string): SamplePack;
50
+ /**
51
+ * The sample to play `midi` with, and how far to bend it.
52
+ *
53
+ * Closest sample in either direction, not the greatest one at or below. The
54
+ * obvious downward-only rule stretches a sample by up to an octave near the top
55
+ * of each zone, which on a sustained note is plainly audible; picking the
56
+ * nearest halves the worst-case bend. Packs cover roughly every third key, so
57
+ * the usual bend is one or two semitones.
58
+ */
59
+ export declare function nearestSample(pack: SamplePack, midi: number): SampleChoice | null;
60
+ /**
61
+ * The sample for `midi` **only if the pack has that exact note**, never bent.
62
+ *
63
+ * For percussion. In a drum pack a note number names a *different instrument*,
64
+ * not a different pitch — 38 is a snare and 42 a closed hi-hat — so
65
+ * `nearestSample`'s whole premise is wrong here: reaching for the closest one
66
+ * would answer a missing cowbell with a detuned tom, confidently. A kit that
67
+ * does not define a slot must play nothing, which is what a real drum machine
68
+ * does too.
69
+ */
70
+ export declare function exactSample(pack: SamplePack, midi: number): SampleChoice | null;
71
+ //# sourceMappingURL=sample-pack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sample-pack.d.ts","sourceRoot":"","sources":["../../../src/rn/playback/sample-pack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAeH,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,MAAqB,GAAG,MAAM,CAGpF;AAED,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS1D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAiBxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAOjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAG/E"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * FluidR3 sample packs: locating them, reading them, and choosing which sample
3
+ * plays a given note.
4
+ *
5
+ * All pure. The audio nodes are `sample-engine.ts`'s problem; everything here
6
+ * is string and number work, which is what makes the part of this engine most
7
+ * likely to be subtly wrong — pitch selection — testable without a device.
8
+ *
9
+ * The packs are Benjamin Gleitzman's pre-renderings of **FluidR3_GM.sf2**, the
10
+ * same font the web engine plays as `FluidR3Mono_GM.sf3`. That is the whole
11
+ * reason for choosing this route over synthesising something: React Native
12
+ * plays the same recordings the browser does, rather than an approximation of
13
+ * them.
14
+ *
15
+ * Each pack is a MIDI.js-era JavaScript file assigning an object of note name
16
+ * to base64 mp3 data URI:
17
+ *
18
+ * MIDI.Soundfont.violin = { "A0": "data:audio/mp3;base64,...", ... }
19
+ *
20
+ * It is parsed rather than evaluated. Running fetched JavaScript to read a
21
+ * lookup table would be an arbitrary-code-execution hole for a data file.
22
+ */
23
+ const DEFAULT_BASE = 'https://gleitz.github.io/midi-js-soundfonts/FluidR3_GM/';
24
+ /** Semitone offset of each pitch class from C. */
25
+ const PITCH_CLASS = {
26
+ C: 0,
27
+ D: 2,
28
+ E: 4,
29
+ F: 5,
30
+ G: 7,
31
+ A: 9,
32
+ B: 11,
33
+ };
34
+ /**
35
+ * Where a GM instrument's pack lives. `base` lets an app self-host rather than
36
+ * depend on a third-party CDN at runtime — the packs are CC-BY 3.0, so copying
37
+ * them is allowed, and a music app that stops working when someone else's
38
+ * GitHub Pages does is not a good trade.
39
+ */
40
+ export function sampleUrlFor(instrument, base = DEFAULT_BASE) {
41
+ const root = base.endsWith('/') ? base : `${base}/`;
42
+ return `${root}${instrument}-mp3.js`;
43
+ }
44
+ /** `"F#4"` / `"Bb3"` / `"A0"` -> MIDI number, or null if it is not a note name. */
45
+ export function noteNameToMidi(name) {
46
+ const match = /^([A-Ga-g])([#b]?)(-?\d+)$/.exec(name);
47
+ if (!match)
48
+ return null;
49
+ const [, letter, accidental, octave] = match;
50
+ const base = PITCH_CLASS[letter.toUpperCase()];
51
+ if (base === undefined)
52
+ return null;
53
+ const shift = accidental === '#' ? 1 : accidental === 'b' ? -1 : 0;
54
+ // MIDI 60 is C4, so C-1 is 0 — hence the +1 on the octave.
55
+ return (Number(octave) + 1) * 12 + base + shift;
56
+ }
57
+ /**
58
+ * Reads a pack body. Throws rather than returning an empty pack: a 404 page
59
+ * parses to zero samples, and an instrument with no samples is silent playback
60
+ * with nothing reporting a problem.
61
+ */
62
+ export function parseSamplePack(body) {
63
+ const header = /MIDI\.Soundfont\.([A-Za-z0-9_]+)\s*=/.exec(body);
64
+ if (!header) {
65
+ throw new Error('Response is not a MIDI.js sample pack: no `MIDI.Soundfont.<instrument> =` found.');
66
+ }
67
+ const samples = new Map();
68
+ const entry = /"([A-Ga-g][#b]?-?\d+)"\s*:\s*"(data:audio\/[^"]+)"/g;
69
+ for (const [, name, uri] of body.matchAll(entry)) {
70
+ const midi = noteNameToMidi(name);
71
+ if (midi !== null)
72
+ samples.set(midi, uri);
73
+ }
74
+ if (samples.size === 0) {
75
+ throw new Error('Response is not a MIDI.js sample pack: no note entries found.');
76
+ }
77
+ return { instrument: header[1], samples };
78
+ }
79
+ /**
80
+ * The sample to play `midi` with, and how far to bend it.
81
+ *
82
+ * Closest sample in either direction, not the greatest one at or below. The
83
+ * obvious downward-only rule stretches a sample by up to an octave near the top
84
+ * of each zone, which on a sustained note is plainly audible; picking the
85
+ * nearest halves the worst-case bend. Packs cover roughly every third key, so
86
+ * the usual bend is one or two semitones.
87
+ */
88
+ export function nearestSample(pack, midi) {
89
+ let best = null;
90
+ for (const sampled of pack.samples.keys()) {
91
+ if (best === null || Math.abs(sampled - midi) < Math.abs(best - midi))
92
+ best = sampled;
93
+ }
94
+ if (best === null)
95
+ return null;
96
+ return { midi: best, uri: pack.samples.get(best), detuneCents: (midi - best) * 100 };
97
+ }
98
+ /**
99
+ * The sample for `midi` **only if the pack has that exact note**, never bent.
100
+ *
101
+ * For percussion. In a drum pack a note number names a *different instrument*,
102
+ * not a different pitch — 38 is a snare and 42 a closed hi-hat — so
103
+ * `nearestSample`'s whole premise is wrong here: reaching for the closest one
104
+ * would answer a missing cowbell with a detuned tom, confidently. A kit that
105
+ * does not define a slot must play nothing, which is what a real drum machine
106
+ * does too.
107
+ */
108
+ export function exactSample(pack, midi) {
109
+ const uri = pack.samples.get(midi);
110
+ return uri ? { midi, uri, detuneCents: 0 } : null;
111
+ }
112
+ //# sourceMappingURL=sample-pack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sample-pack.js","sourceRoot":"","sources":["../../../src/rn/playback/sample-pack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { RNAudioBuffer, RNBufferSource } from './audio-api.js';
2
+ /**
3
+ * Points a source at a loop inside its own sustain, if it needs one and one fits.
4
+ *
5
+ * Returns whether looping was applied — false when the note is short enough to
6
+ * play straight through, or the recording too short to find a window in.
7
+ *
8
+ * **The loop spans a whole number of periods of the note being played.** That
9
+ * is what makes the seam quiet. Aligning both ends to rising zero crossings, as
10
+ * the first version did, removes the step discontinuity but not the *phase*
11
+ * one: an arbitrary-length window ends part-way through a cycle, so the
12
+ * waveform jumps back mid-period and every partial above the fundamental
13
+ * restarts out of phase. Rounding the window to whole periods lands the end of
14
+ * the loop at the same point in the cycle as its start, so the fundamental and
15
+ * its harmonics all continue smoothly.
16
+ *
17
+ * The sampled note is known — it is the pack entry being played — so its
18
+ * fundamental is known, and no pitch detection is needed. `sampleMidi` is the
19
+ * *sampled* note rather than the sounding one: the buffer holds the recording
20
+ * as rendered, and `detune` bends it afterwards, so the period in the buffer
21
+ * belongs to the sample.
22
+ */
23
+ export declare function applySustainLoop(source: RNBufferSource, buffer: RNAudioBuffer, neededSeconds: number, sampleMidi?: number): boolean;
24
+ //# sourceMappingURL=sustain-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sustain-loop.d.ts","sourceRoot":"","sources":["../../../src/rn/playback/sustain-loop.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAcpE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,aAAa,EACrB,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAwBT"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Holding a note for longer than the recording lasts.
3
+ *
4
+ * Every FluidR3 sample pack entry is **3.13 seconds**, whatever the instrument.
5
+ * That is not a limit of the format, just how they were rendered — but it means
6
+ * a note written longer than that simply stops sounding partway through. A whole
7
+ * note at 60bpm is four seconds. A tied pad across a phrase is many. Those went
8
+ * silent, with the gain envelope still dutifully holding a level over nothing.
9
+ *
10
+ * SF2 solves this with loop points, and the packs lost them along with
11
+ * everything else in the `sdta` chunk. What survives is the audio, and for an
12
+ * instrument that *holds* its level — measured per instrument by
13
+ * `scripts/measure-expression.mjs` — a window inside its steady portion can be
14
+ * looped to sustain it indefinitely.
15
+ *
16
+ * Only for those instruments. Looping a piano's tail would hold a note that is
17
+ * supposed to die away, which is a worse and more obvious error than the
18
+ * truncation it fixes.
19
+ */
20
+ import { midiToHertz } from '../../shared/midi.js';
21
+ /** Kept clear of the end, which holds the rendered note's own release. */
22
+ const TAIL_GUARD_SECONDS = 0.35;
23
+ /**
24
+ * Longest loop window worth taking.
25
+ *
26
+ * Long enough that any period mismatch at the seam recurs rarely, short enough
27
+ * to sit inside the steady portion of a 3.13s recording.
28
+ */
29
+ const MAX_LOOP_SECONDS = 1.0;
30
+ /** Shorter than this and the seam recurs often enough to be heard as a pitch. */
31
+ const MIN_LOOP_SECONDS = 0.25;
32
+ /**
33
+ * Points a source at a loop inside its own sustain, if it needs one and one fits.
34
+ *
35
+ * Returns whether looping was applied — false when the note is short enough to
36
+ * play straight through, or the recording too short to find a window in.
37
+ *
38
+ * **The loop spans a whole number of periods of the note being played.** That
39
+ * is what makes the seam quiet. Aligning both ends to rising zero crossings, as
40
+ * the first version did, removes the step discontinuity but not the *phase*
41
+ * one: an arbitrary-length window ends part-way through a cycle, so the
42
+ * waveform jumps back mid-period and every partial above the fundamental
43
+ * restarts out of phase. Rounding the window to whole periods lands the end of
44
+ * the loop at the same point in the cycle as its start, so the fundamental and
45
+ * its harmonics all continue smoothly.
46
+ *
47
+ * The sampled note is known — it is the pack entry being played — so its
48
+ * fundamental is known, and no pitch detection is needed. `sampleMidi` is the
49
+ * *sampled* note rather than the sounding one: the buffer holds the recording
50
+ * as rendered, and `detune` bends it afterwards, so the period in the buffer
51
+ * belongs to the sample.
52
+ */
53
+ export function applySustainLoop(source, buffer, neededSeconds, sampleMidi) {
54
+ const duration = buffer.duration;
55
+ if (neededSeconds <= duration)
56
+ return false;
57
+ const end = duration - TAIL_GUARD_SECONDS;
58
+ const target = Math.min(MAX_LOOP_SECONDS, end / 2);
59
+ if (end <= 0 || target < MIN_LOOP_SECONDS)
60
+ return false;
61
+ const channel = buffer.getChannelData(0);
62
+ const rate = buffer.sampleRate;
63
+ const endSample = nearestRisingZero(channel, Math.floor(end * rate), rate);
64
+ const lengthSamples = wholePeriods(target * rate, sampleMidi, rate);
65
+ const startSample = endSample - lengthSamples;
66
+ if (startSample <= 0)
67
+ return false;
68
+ const loopStart = startSample / rate;
69
+ const loopEnd = endSample / rate;
70
+ if (!(loopEnd > loopStart) || loopEnd - loopStart < MIN_LOOP_SECONDS)
71
+ return false;
72
+ source.loop = true;
73
+ source.loopStart = loopStart;
74
+ source.loopEnd = loopEnd;
75
+ return true;
76
+ }
77
+ /**
78
+ * `targetSamples` rounded to a whole number of periods of `sampleMidi`.
79
+ *
80
+ * Returned unchanged when the note is unknown — a caller with no pitch (a test,
81
+ * a future non-melodic use) still gets a working loop, just one whose seam is
82
+ * only zero-crossing-aligned.
83
+ */
84
+ function wholePeriods(targetSamples, sampleMidi, sampleRate) {
85
+ if (sampleMidi === undefined)
86
+ return Math.round(targetSamples);
87
+ const period = sampleRate / midiToHertz(sampleMidi);
88
+ const periods = Math.max(1, Math.round(targetSamples / period));
89
+ return Math.round(periods * period);
90
+ }
91
+ /**
92
+ * The nearest sample index where the waveform crosses zero going upward.
93
+ *
94
+ * Searched within a few milliseconds either way — far enough to find a crossing
95
+ * at any musical pitch, near enough not to move the loop bound audibly.
96
+ */
97
+ function nearestRisingZero(channel, at, sampleRate) {
98
+ const reach = Math.floor(0.005 * sampleRate);
99
+ const lo = Math.max(1, at - reach);
100
+ const hi = Math.min(channel.length - 1, at + reach);
101
+ for (let offset = 0; offset <= reach; offset += 1) {
102
+ for (const index of [at - offset, at + offset]) {
103
+ if (index <= lo || index >= hi)
104
+ continue;
105
+ if (channel[index - 1] <= 0 && channel[index] > 0)
106
+ return index;
107
+ }
108
+ }
109
+ return at;
110
+ }
111
+ //# sourceMappingURL=sustain-loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sustain-loop.js","sourceRoot":"","sources":["../../../src/rn/playback/sustain-loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * When one sampled note starts, how loud it is, and when it lets go.
3
+ *
4
+ * Pure, so the arithmetic that decides whether a note is audible at all can be
5
+ * tested without an audio device.
6
+ *
7
+ * There is no attack or decay stage here, deliberately. These samples are
8
+ * recordings of real instruments, so the attack is already *in* the audio — a
9
+ * synthesised attack ramp on top would smear the very transient that makes a
10
+ * plucked or struck note recognisable. What the envelope does provide is a
11
+ * release, because cutting a sample off at full amplitude produces a click.
12
+ */
13
+ import type { SampleChoice } from './sample-pack.js';
14
+ /**
15
+ * Fallback fade-out, for a voice with no instrument context (the metronome, a
16
+ * test). Real notes use the instrument's own measured release via
17
+ * `expression.ts` — this engine used to apply this 80ms to *everything*, which
18
+ * is about seven times too short against the measured median of 0.56s and
19
+ * chopped every released chord.
20
+ */
21
+ export declare const RELEASE_SECONDS = 0.08;
22
+ /**
23
+ * Floor on how long a voice sounds before it starts releasing.
24
+ *
25
+ * A note can arrive with a zero duration — a grace note, or something
26
+ * quantized down to nothing — and scheduling the release at the same instant
27
+ * as the start plays silence. This is short enough to still read as a grace
28
+ * note.
29
+ */
30
+ export declare const MIN_VOICE_SECONDS = 0.05;
31
+ export type VoicePlan = {
32
+ /** Low-pass corner reproducing this velocity's timbre, or null to leave it open. */
33
+ cutoffHz: number | null;
34
+ /** Context time to start the source node. */
35
+ startAt: number;
36
+ /** Context time the release ramp begins — the end of the written duration. */
37
+ releaseAt: number;
38
+ /** Context time the source node stops. */
39
+ endAt: number;
40
+ /** Peak linear gain, velocity and track level combined. */
41
+ gain: number;
42
+ /** Sample to play and how far to bend it. */
43
+ uri: string;
44
+ detuneCents: number;
45
+ sampleMidi: number;
46
+ };
47
+ export declare function planVoice({ atSeconds, durationSeconds, velocity, trackGain, choice, program, }: {
48
+ atSeconds: number;
49
+ durationSeconds: number;
50
+ velocity: number;
51
+ trackGain: number;
52
+ choice: SampleChoice;
53
+ /**
54
+ * GM program, for the instrument's own release and velocity-to-brightness.
55
+ * Omitted by callers with no instrument (the metronome), which fall back to
56
+ * the flat constants.
57
+ */
58
+ program?: number;
59
+ }): VoicePlan;
60
+ //# sourceMappingURL=voice-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-plan.d.ts","sourceRoot":"","sources":["../../../src/rn/playback/voice-plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAEtC,MAAM,MAAM,SAAS,GAAG;IACtB,oFAAoF;IACpF,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,eAAe,EACf,QAAQ,EACR,SAAS,EACT,MAAM,EACN,OAAO,GACR,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;IACrB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,SAAS,CAmBZ"}
@@ -0,0 +1,38 @@
1
+ import { cutoffFor, releaseFor, velocityGain } from './expression.js';
2
+ /**
3
+ * Fallback fade-out, for a voice with no instrument context (the metronome, a
4
+ * test). Real notes use the instrument's own measured release via
5
+ * `expression.ts` — this engine used to apply this 80ms to *everything*, which
6
+ * is about seven times too short against the measured median of 0.56s and
7
+ * chopped every released chord.
8
+ */
9
+ export const RELEASE_SECONDS = 0.08;
10
+ /**
11
+ * Floor on how long a voice sounds before it starts releasing.
12
+ *
13
+ * A note can arrive with a zero duration — a grace note, or something
14
+ * quantized down to nothing — and scheduling the release at the same instant
15
+ * as the start plays silence. This is short enough to still read as a grace
16
+ * note.
17
+ */
18
+ export const MIN_VOICE_SECONDS = 0.05;
19
+ export function planVoice({ atSeconds, durationSeconds, velocity, trackGain, choice, program, }) {
20
+ // Never behind the context clock: a source node rejects a start time in the
21
+ // past, and `planDispatch` has already dropped anything genuinely late.
22
+ const startAt = Math.max(0, atSeconds);
23
+ const held = Math.max(MIN_VOICE_SECONDS, durationSeconds);
24
+ const releaseAt = startAt + held;
25
+ const release = program === undefined ? RELEASE_SECONDS : releaseFor(program);
26
+ return {
27
+ startAt,
28
+ releaseAt,
29
+ endAt: releaseAt + release,
30
+ // SF2's concave velocity curve, not a linear one — see `velocityGain`.
31
+ gain: velocityGain(velocity) * trackGain,
32
+ cutoffHz: program === undefined ? null : cutoffFor(program, velocity),
33
+ uri: choice.uri,
34
+ detuneCents: choice.detuneCents,
35
+ sampleMidi: choice.midi,
36
+ };
37
+ }
38
+ //# sourceMappingURL=voice-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-plan.js","sourceRoot":"","sources":["../../../src/rn/playback/voice-plan.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEtE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AAEpC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAmBtC,MAAM,UAAU,SAAS,CAAC,EACxB,SAAS,EACT,eAAe,EACf,QAAQ,EACR,SAAS,EACT,MAAM,EACN,OAAO,GAaR;IACC,4EAA4E;IAC5E,wEAAwE;IACxE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,OAAO,GAAG,IAAI,CAAC;IACjC,MAAM,OAAO,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAE9E,OAAO;QACL,OAAO;QACP,SAAS;QACT,KAAK,EAAE,SAAS,GAAG,OAAO;QAC1B,uEAAuE;QACvE,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,SAAS;QACxC,QAAQ,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC;QACrE,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,MAAM,CAAC,IAAI;KACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The high-frequency half of playback, kept out of the store.
3
+ *
4
+ * Position arrives ~30 times a second and the sounding set changes on every
5
+ * note boundary. Routing either through Zustand means every subscriber in the
6
+ * app is notified at that rate, which is why the editor grew five separately
7
+ * isolated readout components and a rule in CLAUDE.md reminding everyone not to
8
+ * read those fields at a component's top level. The rule was correct and
9
+ * enforced by memory: one `store((s) => s.positionTick)` in the wrong place
10
+ * silently cost twenty renders a second.
11
+ *
12
+ * Here the fields simply are not in the store, so that subscription cannot be
13
+ * written. What remains in Zustand is the low-frequency state — transport
14
+ * state, loop, tempo, metronome, volume, load progress — which behaves like
15
+ * ordinary React state because it is.
16
+ *
17
+ * Three separate channels rather than one "playback changed" event: a
18
+ * subscriber that cares about position must not wake when a note starts, and
19
+ * the caret and the piano keyboard genuinely care about different things.
20
+ */
21
+ import type { SoundingNote, TransportPlaybackState } from '@sudobility/music_types';
22
+ export type Unsubscribe = () => void;
23
+ export declare class PlaybackBus {
24
+ private readonly positionListeners;
25
+ private readonly soundingListeners;
26
+ private readonly transportListeners;
27
+ /** The last values published, so a subscriber joining mid-playback is not blind until the next event. */
28
+ private lastSounding;
29
+ private lastTransport;
30
+ onPosition(listener: (tick: number) => void): Unsubscribe;
31
+ onSounding(listener: (notes: readonly SoundingNote[]) => void): Unsubscribe;
32
+ onTransport(listener: (state: TransportPlaybackState) => void): Unsubscribe;
33
+ /**
34
+ * Every caret move in the app arrives here — the engine's position reports,
35
+ * a seek, a click on the staff, an arrow key — which is what makes this the
36
+ * one place that has to tell `IMusicPosition` about it. Reporting from the
37
+ * controller's report handler instead would have covered playback only, and
38
+ * left the shared position stale the moment somebody moved the caret by
39
+ * hand.
40
+ *
41
+ * The anchor is stamped **here**, inside the engine's own callback, rather
42
+ * than wherever a React subscriber eventually runs: that is the difference
43
+ * between measuring from the audio clock and measuring from event-loop
44
+ * latency, and it is why the caret used to drift away from the highlights
45
+ * and the keyboard under load.
46
+ */
47
+ publishPosition(tick: number): void;
48
+ /**
49
+ * The engine already emits only on change (`SoundingSet`), so this does not
50
+ * filter again — doing so would hide a deliberate re-publish after a seek.
51
+ */
52
+ publishSounding(notes: readonly SoundingNote[]): void;
53
+ publishTransport(state: TransportPlaybackState): void;
54
+ /**
55
+ * Where playback last reported it was. Read once on subscribe; do not poll
56
+ * this.
57
+ *
58
+ * Delegated to the playhead rather than kept here. The bus used to store its
59
+ * own copy of the reported tick beside the one `IMusicPositionSource` holds,
60
+ * which made two objects each own the same fact — and they duly came apart:
61
+ * when the engine's throttle stopped reporting, the playhead went on
62
+ * projecting while this copy stayed where it was, so the caret glided the
63
+ * length of the score with the scroll and the readouts still at bar one.
64
+ * Reading through means the smoothed position and the reported one are two
65
+ * views of one state, which is what the interface promises.
66
+ */
67
+ get positionTick(): number;
68
+ get sounding(): readonly SoundingNote[];
69
+ get transport(): TransportPlaybackState;
70
+ /** Drops every listener. For teardown; a live app never calls this. */
71
+ clear(): void;
72
+ }
73
+ //# sourceMappingURL=bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../../src/shared/bus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EACV,YAAY,EACZ,sBAAsB,EACvB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAIrC,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqC;IACvE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAE9B;IACJ,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAE/B;IAEJ,yGAAyG;IACzG,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,aAAa,CAAqC;IAE1D,UAAU,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,WAAW;IAKzD,UAAU,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,KAAK,IAAI,GAAG,WAAW;IAK3E,WAAW,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,GAAG,WAAW;IAK3E;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKnC;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI;IAKrD,gBAAgB,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI;IAKrD;;;;;;;;;;;;OAYG;IACH,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,QAAQ,IAAI,SAAS,YAAY,EAAE,CAEtC;IAED,IAAI,SAAS,IAAI,sBAAsB,CAEtC;IAED,uEAAuE;IACvE,KAAK,IAAI,IAAI;CAKd"}