polyphon 0.0.0-stage → 0.1.0

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 (174) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +374 -2
  3. package/README.zh-TW.md +375 -0
  4. package/dist/engine/automation.d.ts +24 -0
  5. package/dist/engine/automation.d.ts.map +1 -0
  6. package/dist/engine/automation.js +55 -0
  7. package/dist/engine/automation.js.map +1 -0
  8. package/dist/engine/compile.d.ts +36 -0
  9. package/dist/engine/compile.d.ts.map +1 -0
  10. package/dist/engine/compile.js +103 -0
  11. package/dist/engine/compile.js.map +1 -0
  12. package/dist/engine/jukebox.d.ts +113 -0
  13. package/dist/engine/jukebox.d.ts.map +1 -0
  14. package/dist/engine/jukebox.js +287 -0
  15. package/dist/engine/jukebox.js.map +1 -0
  16. package/dist/engine/mixer.d.ts +29 -0
  17. package/dist/engine/mixer.d.ts.map +1 -0
  18. package/dist/engine/mixer.js +141 -0
  19. package/dist/engine/mixer.js.map +1 -0
  20. package/dist/engine/output.d.ts +14 -0
  21. package/dist/engine/output.d.ts.map +1 -0
  22. package/dist/engine/output.js +51 -0
  23. package/dist/engine/output.js.map +1 -0
  24. package/dist/engine/playback.d.ts +97 -0
  25. package/dist/engine/playback.d.ts.map +1 -0
  26. package/dist/engine/playback.js +311 -0
  27. package/dist/engine/playback.js.map +1 -0
  28. package/dist/engine/prepare.d.ts +6 -0
  29. package/dist/engine/prepare.d.ts.map +1 -0
  30. package/dist/engine/prepare.js +12 -0
  31. package/dist/engine/prepare.js.map +1 -0
  32. package/dist/engine/render.d.ts +14 -0
  33. package/dist/engine/render.d.ts.map +1 -0
  34. package/dist/engine/render.js +60 -0
  35. package/dist/engine/render.js.map +1 -0
  36. package/dist/index.d.ts +17 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +25 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/instruments/bowed.d.ts +357 -0
  41. package/dist/instruments/bowed.d.ts.map +1 -0
  42. package/dist/instruments/bowed.js +502 -0
  43. package/dist/instruments/bowed.js.map +1 -0
  44. package/dist/instruments/builtin.d.ts +261 -0
  45. package/dist/instruments/builtin.d.ts.map +1 -0
  46. package/dist/instruments/builtin.js +160 -0
  47. package/dist/instruments/builtin.js.map +1 -0
  48. package/dist/instruments/definition.d.ts +46 -0
  49. package/dist/instruments/definition.d.ts.map +1 -0
  50. package/dist/instruments/definition.js +5 -0
  51. package/dist/instruments/definition.js.map +1 -0
  52. package/dist/instruments/dsp/ambience.d.ts +17 -0
  53. package/dist/instruments/dsp/ambience.d.ts.map +1 -0
  54. package/dist/instruments/dsp/ambience.js +146 -0
  55. package/dist/instruments/dsp/ambience.js.map +1 -0
  56. package/dist/instruments/dsp/core.d.ts +22 -0
  57. package/dist/instruments/dsp/core.d.ts.map +1 -0
  58. package/dist/instruments/dsp/core.js +100 -0
  59. package/dist/instruments/dsp/core.js.map +1 -0
  60. package/dist/instruments/dsp/drums.d.ts +112 -0
  61. package/dist/instruments/dsp/drums.d.ts.map +1 -0
  62. package/dist/instruments/dsp/drums.js +566 -0
  63. package/dist/instruments/dsp/drums.js.map +1 -0
  64. package/dist/instruments/dsp/modal.d.ts +30 -0
  65. package/dist/instruments/dsp/modal.d.ts.map +1 -0
  66. package/dist/instruments/dsp/modal.js +54 -0
  67. package/dist/instruments/dsp/modal.js.map +1 -0
  68. package/dist/instruments/dsp/piano.d.ts +9 -0
  69. package/dist/instruments/dsp/piano.d.ts.map +1 -0
  70. package/dist/instruments/dsp/piano.js +230 -0
  71. package/dist/instruments/dsp/piano.js.map +1 -0
  72. package/dist/instruments/dsp/pluck.d.ts +53 -0
  73. package/dist/instruments/dsp/pluck.d.ts.map +1 -0
  74. package/dist/instruments/dsp/pluck.js +195 -0
  75. package/dist/instruments/dsp/pluck.js.map +1 -0
  76. package/dist/instruments/dsp/reverb.d.ts +16 -0
  77. package/dist/instruments/dsp/reverb.d.ts.map +1 -0
  78. package/dist/instruments/dsp/reverb.js +47 -0
  79. package/dist/instruments/dsp/reverb.js.map +1 -0
  80. package/dist/instruments/dsp/staccato.d.ts +18 -0
  81. package/dist/instruments/dsp/staccato.d.ts.map +1 -0
  82. package/dist/instruments/dsp/staccato.js +147 -0
  83. package/dist/instruments/dsp/staccato.js.map +1 -0
  84. package/dist/instruments/play.d.ts +21 -0
  85. package/dist/instruments/play.d.ts.map +1 -0
  86. package/dist/instruments/play.js +140 -0
  87. package/dist/instruments/play.js.map +1 -0
  88. package/dist/instruments/registry.d.ts +63 -0
  89. package/dist/instruments/registry.d.ts.map +1 -0
  90. package/dist/instruments/registry.js +50 -0
  91. package/dist/instruments/registry.js.map +1 -0
  92. package/dist/instruments/samples.d.ts +30 -0
  93. package/dist/instruments/samples.d.ts.map +1 -0
  94. package/dist/instruments/samples.js +109 -0
  95. package/dist/instruments/samples.js.map +1 -0
  96. package/dist/instruments/voices.d.ts +76 -0
  97. package/dist/instruments/voices.d.ts.map +1 -0
  98. package/dist/instruments/voices.js +1061 -0
  99. package/dist/instruments/voices.js.map +1 -0
  100. package/dist/midi.d.ts +15 -0
  101. package/dist/midi.d.ts.map +1 -0
  102. package/dist/midi.js +280 -0
  103. package/dist/midi.js.map +1 -0
  104. package/dist/notation/format.d.ts +12 -0
  105. package/dist/notation/format.d.ts.map +1 -0
  106. package/dist/notation/format.js +102 -0
  107. package/dist/notation/format.js.map +1 -0
  108. package/dist/notation/harmony.d.ts +83 -0
  109. package/dist/notation/harmony.d.ts.map +1 -0
  110. package/dist/notation/harmony.js +191 -0
  111. package/dist/notation/harmony.js.map +1 -0
  112. package/dist/notation/melody.d.ts +25 -0
  113. package/dist/notation/melody.d.ts.map +1 -0
  114. package/dist/notation/melody.js +138 -0
  115. package/dist/notation/melody.js.map +1 -0
  116. package/dist/notation/part.d.ts +34 -0
  117. package/dist/notation/part.d.ts.map +1 -0
  118. package/dist/notation/part.js +15 -0
  119. package/dist/notation/part.js.map +1 -0
  120. package/dist/notation/transform.d.ts +28 -0
  121. package/dist/notation/transform.d.ts.map +1 -0
  122. package/dist/notation/transform.js +67 -0
  123. package/dist/notation/transform.js.map +1 -0
  124. package/dist/song.d.ts +140 -0
  125. package/dist/song.d.ts.map +1 -0
  126. package/dist/song.js +45 -0
  127. package/dist/song.js.map +1 -0
  128. package/dist/tempo.d.ts +36 -0
  129. package/dist/tempo.d.ts.map +1 -0
  130. package/dist/tempo.js +81 -0
  131. package/dist/tempo.js.map +1 -0
  132. package/dist/theory.d.ts +70 -0
  133. package/dist/theory.d.ts.map +1 -0
  134. package/dist/theory.js +183 -0
  135. package/dist/theory.js.map +1 -0
  136. package/dist/transcribe.d.ts +81 -0
  137. package/dist/transcribe.d.ts.map +1 -0
  138. package/dist/transcribe.js +433 -0
  139. package/dist/transcribe.js.map +1 -0
  140. package/package.json +57 -4
  141. package/src/engine/automation.ts +65 -0
  142. package/src/engine/compile.ts +124 -0
  143. package/src/engine/jukebox.ts +322 -0
  144. package/src/engine/mixer.ts +166 -0
  145. package/src/engine/output.ts +59 -0
  146. package/src/engine/playback.ts +349 -0
  147. package/src/engine/prepare.ts +15 -0
  148. package/src/engine/render.ts +71 -0
  149. package/src/index.ts +28 -0
  150. package/src/instruments/bowed.ts +660 -0
  151. package/src/instruments/builtin.ts +180 -0
  152. package/src/instruments/definition.ts +52 -0
  153. package/src/instruments/dsp/ambience.ts +142 -0
  154. package/src/instruments/dsp/core.ts +97 -0
  155. package/src/instruments/dsp/drums.ts +565 -0
  156. package/src/instruments/dsp/modal.ts +76 -0
  157. package/src/instruments/dsp/piano.ts +226 -0
  158. package/src/instruments/dsp/pluck.ts +240 -0
  159. package/src/instruments/dsp/reverb.ts +56 -0
  160. package/src/instruments/dsp/staccato.ts +141 -0
  161. package/src/instruments/play.ts +151 -0
  162. package/src/instruments/registry.ts +100 -0
  163. package/src/instruments/samples.ts +119 -0
  164. package/src/instruments/voices.ts +1168 -0
  165. package/src/midi.ts +285 -0
  166. package/src/notation/format.ts +96 -0
  167. package/src/notation/harmony.ts +233 -0
  168. package/src/notation/melody.ts +133 -0
  169. package/src/notation/part.ts +42 -0
  170. package/src/notation/transform.ts +78 -0
  171. package/src/song.ts +170 -0
  172. package/src/tempo.ts +108 -0
  173. package/src/theory.ts +208 -0
  174. package/src/transcribe.ts +487 -0
@@ -0,0 +1,81 @@
1
+ import { type Meter, type Part } from './notation/part.ts';
2
+ /** The pitch heard over a few hundredths of a second */
3
+ export interface PitchFrame {
4
+ /** Seconds from the first sample pushed, at the middle of the frame */
5
+ time: number;
6
+ /** MIDI pitch, fractional (69.2 is A4 a little sharp); null when no steady pitch was heard */
7
+ pitch: number | null;
8
+ /** How periodic the sound is, 0-1 (a held vowel is above 0.9, breath and clicks well below) */
9
+ clarity: number;
10
+ /** Loudness in dB (0 is full scale) */
11
+ level: number;
12
+ }
13
+ /**
14
+ * Follows the pitch of one voice through audio pushed to it in pieces of any size, as a microphone delivers them, every 10 ms.
15
+ *
16
+ * @example
17
+ * const tracker = new PitchTracker(context.sampleRate);
18
+ * worklet.port.onmessage = ({ data }) => draw(tracker.push(data));
19
+ */
20
+ export declare class PitchTracker {
21
+ /** Every frame so far */
22
+ readonly frames: PitchFrame[];
23
+ /** Input samples averaged into each tracked one */
24
+ private readonly factor;
25
+ private readonly rate;
26
+ /** Samples in YIN's integration window, the longest period, and between frames */
27
+ private readonly window;
28
+ private readonly maxLag;
29
+ private readonly minLag;
30
+ private readonly hop;
31
+ /** Tracked samples not yet passed by the frames, the first of them sample number `base` */
32
+ private buffer;
33
+ private length;
34
+ private base;
35
+ /** The first sample of the next frame */
36
+ private next;
37
+ /** The input samples being averaged into the next tracked one */
38
+ private sum;
39
+ private count;
40
+ private readonly difference;
41
+ constructor(sampleRate: number);
42
+ /** Add samples; returns the frames they completed */
43
+ push(samples: Float32Array): PitchFrame[];
44
+ private analyse;
45
+ }
46
+ export interface TranscribeOptions {
47
+ /** The tempo the melody was sung at: the metronome's. Left out, it is found from the notes themselves (singing without a click). */
48
+ bpm?: number;
49
+ /** Time signature (default '4/4') */
50
+ meter?: Meter;
51
+ /** When a bar starts, in seconds on the frames' clock: the metronome's first downbeat (found with the tempo when that is left out) */
52
+ start?: number;
53
+ /** The shortest note written, in steps: 1 for sixteenths (default), 2 for eighths */
54
+ grid?: number;
55
+ }
56
+ export interface Transcription {
57
+ /** The notes on the beat grid, from the start of the first bar sung in */
58
+ part: Part;
59
+ /** The part written as a melody string, spelled in its key */
60
+ melody: string;
61
+ /** The tempo: as given, or as found */
62
+ bpm: number;
63
+ /** Where the part's first step falls, in seconds on the frames' clock (to line the notes up with what was heard) */
64
+ start: number;
65
+ /** The key the notes suggest, such as 'G major' or 'E minor' (empty when nothing was heard) */
66
+ key: string;
67
+ /** How far the singing sat from concert pitch, in cents (+20: a little sharp). The notes are corrected for it. */
68
+ tuning: number;
69
+ }
70
+ /**
71
+ * Write a sung melody as notes. The pitches are corrected for a voice that sits sharp or flat (or drifts) and rounded to the key where
72
+ * a note falls between two. The timing is put on the grid of a metronome at `bpm` whose bars start at `start`, or of the tempo the
73
+ * notes themselves keep; a note between two grid lines leans to the stronger beat, and runs on to the next note unless a clear rest
74
+ * is left between them.
75
+ *
76
+ * @example
77
+ * transcribe(tracker.frames, { bpm: 90, start: 2.67 }).melody; // 'r:12 G4:2 G4 | A4:4 G4 C5 B4 | ...'
78
+ * transcribe(tracker.frames).bpm; // 96.8, found from the notes
79
+ */
80
+ export declare function transcribe(frames: readonly PitchFrame[], options?: TranscribeOptions): Transcription;
81
+ //# sourceMappingURL=transcribe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcribe.d.ts","sourceRoot":"","sources":["../src/transcribe.ts"],"names":[],"mappings":"AAKA,OAAO,EAAyB,KAAK,KAAK,EAAa,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE7F,wDAAwD;AACxD,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,8FAA8F;IAC9F,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,+FAA+F;IAC/F,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;CACf;AAYD;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,yBAAyB;IACzB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,CAAM;IACnC,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,kFAAkF;IAClF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,2FAA2F;IAC3F,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,IAAI,CAAK;IACjB,yCAAyC;IACzC,OAAO,CAAC,IAAI,CAAK;IACjB,iEAAiE;IACjE,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAE1C,YAAY,UAAU,EAAE,MAAM,EAQ7B;IAED,qDAAqD;IACrD,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,UAAU,EAAE,CAyBxC;IAED,OAAO,CAAC,OAAO;CAqChB;AAED,MAAM,WAAW,iBAAiB;IAChC,oIAAoI;IACpI,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,sIAAsI;IACtI,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,IAAI,EAAE,IAAI,CAAC;IACX,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,oHAAoH;IACpH,KAAK,EAAE,MAAM,CAAC;IACd,+FAA+F;IAC/F,GAAG,EAAE,MAAM,CAAC;IACZ,kHAAkH;IAClH,MAAM,EAAE,MAAM,CAAC;CAChB;AAaD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,EAAE,OAAO,GAAE,iBAAsB,GAAG,aAAa,CAuBxG"}
@@ -0,0 +1,433 @@
1
+ // Melodies by ear: a pitch tracker for one voice (singing, humming, whistling) and a transcriber that writes what it heard as notes
2
+ // on the beat grid. Clean singing needs no trained model: a voice's pitch shows in the sound's own periodicity (the YIN method), and
3
+ // a metronome fixes where the beats are, so the rhythm comes down to rounding to the grid.
4
+ import { formatMelody } from './notation/format.js';
5
+ import { stepsPerBar, VELOCITY } from './notation/part.js';
6
+ /** Voices are tracked at about this rate: fundamentals up to C6 with room to spare, at a third of the work of 48 kHz */
7
+ const TRACKING_RATE = 16000;
8
+ /** The pitch range tracked, in Hz: a low bass hum to a high whistle */
9
+ const LOWEST = 55;
10
+ const HIGHEST = 1400;
11
+ /** YIN's threshold on the normalized difference: the first dip under it is the period */
12
+ const THRESHOLD = 0.15;
13
+ /** Frames less periodic than this have no pitch */
14
+ const MIN_CLARITY = 0.6;
15
+ /**
16
+ * Follows the pitch of one voice through audio pushed to it in pieces of any size, as a microphone delivers them, every 10 ms.
17
+ *
18
+ * @example
19
+ * const tracker = new PitchTracker(context.sampleRate);
20
+ * worklet.port.onmessage = ({ data }) => draw(tracker.push(data));
21
+ */
22
+ export class PitchTracker {
23
+ /** Every frame so far */
24
+ frames = [];
25
+ /** Input samples averaged into each tracked one */
26
+ factor;
27
+ rate;
28
+ /** Samples in YIN's integration window, the longest period, and between frames */
29
+ window;
30
+ maxLag;
31
+ minLag;
32
+ hop;
33
+ /** Tracked samples not yet passed by the frames, the first of them sample number `base` */
34
+ buffer = new Float32Array(4096);
35
+ length = 0;
36
+ base = 0;
37
+ /** The first sample of the next frame */
38
+ next = 0;
39
+ /** The input samples being averaged into the next tracked one */
40
+ sum = 0;
41
+ count = 0;
42
+ difference;
43
+ constructor(sampleRate) {
44
+ this.factor = Math.max(1, Math.floor(sampleRate / TRACKING_RATE));
45
+ this.rate = sampleRate / this.factor;
46
+ this.window = Math.round(0.032 * this.rate);
47
+ this.maxLag = Math.ceil(this.rate / LOWEST);
48
+ this.minLag = Math.floor(this.rate / HIGHEST);
49
+ this.hop = Math.round(0.01 * this.rate);
50
+ this.difference = new Float64Array(this.maxLag + 1);
51
+ }
52
+ /** Add samples; returns the frames they completed */
53
+ push(samples) {
54
+ for (const sample of samples) {
55
+ this.sum += sample;
56
+ if (++this.count < this.factor)
57
+ continue;
58
+ if (this.length === this.buffer.length) {
59
+ const grown = new Float32Array(this.buffer.length * 2);
60
+ grown.set(this.buffer);
61
+ this.buffer = grown;
62
+ }
63
+ this.buffer[this.length++] = this.sum / this.factor;
64
+ this.sum = this.count = 0;
65
+ }
66
+ const added = [];
67
+ const span = this.window + this.maxLag;
68
+ while (this.next + span <= this.base + this.length) {
69
+ const start = this.next - this.base;
70
+ added.push(this.analyse(this.buffer.subarray(start, start + span), (this.next + this.window / 2) / this.rate));
71
+ this.next += this.hop;
72
+ }
73
+ const passed = this.next - this.base;
74
+ this.buffer.copyWithin(0, passed, this.length);
75
+ this.length -= passed;
76
+ this.base = this.next;
77
+ this.frames.push(...added);
78
+ return added;
79
+ }
80
+ analyse(x, time) {
81
+ const { window, minLag, maxLag, difference: d } = this;
82
+ let energy = 0;
83
+ for (let j = 0; j < window; j++)
84
+ energy += x[j] * x[j];
85
+ const level = 10 * Math.log10(energy / window + 1e-12);
86
+ // The difference between the signal and itself delayed by each lag, normalized by its running mean
87
+ d[0] = 1;
88
+ let running = 0;
89
+ for (let lag = 1; lag <= maxLag; lag++) {
90
+ let sum = 0;
91
+ for (let j = 0; j < window; j++) {
92
+ const delta = x[j] - x[j + lag];
93
+ sum += delta * delta;
94
+ }
95
+ running += sum;
96
+ d[lag] = running > 0 ? (sum * lag) / running : 1;
97
+ }
98
+ // The first dip under the threshold (at its lowest point), else the deepest dip there is
99
+ let lag = -1;
100
+ for (let l = minLag; l < maxLag; l++) {
101
+ if (d[l] >= THRESHOLD)
102
+ continue;
103
+ while (l + 1 < maxLag && d[l + 1] < d[l])
104
+ l++;
105
+ lag = l;
106
+ break;
107
+ }
108
+ if (lag < 0) {
109
+ lag = minLag;
110
+ for (let l = minLag + 1; l < maxLag; l++)
111
+ if (d[l] < d[lag])
112
+ lag = l;
113
+ }
114
+ const clarity = Math.min(1, Math.max(0, 1 - d[lag]));
115
+ if (clarity < MIN_CLARITY)
116
+ return { time, pitch: null, clarity, level };
117
+ // A parabola through the dip and its neighbours finds the period between samples
118
+ const [a, b, c] = [d[lag - 1], d[lag], d[lag + 1]];
119
+ const bend = a - 2 * b + c;
120
+ const period = lag + (bend > 0 ? (a - c) / (2 * bend) : 0);
121
+ return { time, pitch: 69 + 12 * Math.log2(this.rate / period / 440), clarity, level };
122
+ }
123
+ }
124
+ /**
125
+ * Write a sung melody as notes. The pitches are corrected for a voice that sits sharp or flat (or drifts) and rounded to the key where
126
+ * a note falls between two. The timing is put on the grid of a metronome at `bpm` whose bars start at `start`, or of the tempo the
127
+ * notes themselves keep; a note between two grid lines leans to the stronger beat, and runs on to the next note unless a clear rest
128
+ * is left between them.
129
+ *
130
+ * @example
131
+ * transcribe(tracker.frames, { bpm: 90, start: 2.67 }).melody; // 'r:12 G4:2 G4 | A4:4 G4 C5 B4 | ...'
132
+ * transcribe(tracker.frames).bpm; // 96.8, found from the notes
133
+ */
134
+ export function transcribe(frames, options = {}) {
135
+ const { meter, grid = 1 } = options;
136
+ const bar = stepsPerBar(meter);
137
+ // A slide into a note shorter than this belongs to the note, not one of its own
138
+ const slide = options.bpm ? Math.min(0.09, (0.6 * 15) / options.bpm) : 0.08;
139
+ const heard = listen(frames, slide);
140
+ if (!heard.length)
141
+ return { part: { notes: [], duration: 0 }, melody: '', bpm: options.bpm ?? 0, start: options.start ?? 0, key: '', tuning: 0 };
142
+ const { pitches, key, tuning } = tune(heard);
143
+ // Pieces of one note heard apart (the voice wavered past the band between them) are one note again
144
+ const sung = [];
145
+ heard.forEach((h, i) => {
146
+ const previous = sung[sung.length - 1];
147
+ if (previous && h.tied && previous.pitch === pitches[i])
148
+ previous.end = h.end;
149
+ else
150
+ sung.push({ ...h, pitch: pitches[i] });
151
+ });
152
+ const { bpm, start } = options.bpm ? { bpm: options.bpm, start: options.start ?? 0 } : findTempo(sung, bar);
153
+ const { timed, shift } = align(sung, bpm, start, grid, bar);
154
+ // From the bar the first note falls in, which may be a bar before the first downbeat (a pickup in the count-in)
155
+ const origin = Math.floor(timed[0].start / bar) * bar;
156
+ const notes = timed.map(({ start, end, index }) => ({ time: start - origin, duration: end - start, pitches: [sung[index].pitch], velocity: VELOCITY.normal }));
157
+ const last = notes[notes.length - 1];
158
+ const part = { notes, duration: Math.ceil((last.time + last.duration) / bar) * bar };
159
+ return { part, melody: formatMelody(part, meter, key), bpm, start: start + ((origin + shift) * 15) / bpm, key, tuning };
160
+ }
161
+ /** Steady stretches of pitch: voiced runs, split where the pitch moves to a new note or the same note starts again */
162
+ function listen(frames, slide) {
163
+ if (frames.length < 2)
164
+ return [];
165
+ const hop = frames[1].time - frames[0].time;
166
+ const sorted = frames.flatMap((f) => (f.pitch === null ? [] : [f.level])).sort((a, b) => a - b);
167
+ if (!sorted.length)
168
+ return [];
169
+ const loudest = sorted[Math.floor(sorted.length * 0.98)];
170
+ // Quieter than this is the room, or the metronome leaking in, not the voice
171
+ const floor = Math.max(loudest - 35, -70);
172
+ const voiced = (f) => f.pitch !== null && f.level >= floor;
173
+ const heard = [];
174
+ for (let i = 0; i < frames.length;) {
175
+ if (!voiced(frames[i])) {
176
+ i++;
177
+ continue;
178
+ }
179
+ let j = i;
180
+ while (j < frames.length && voiced(frames[j]))
181
+ j++;
182
+ heard.push(...notesIn(frames.slice(i, j), hop, Math.round(slide / hop)));
183
+ i = j;
184
+ }
185
+ return heard;
186
+ }
187
+ /** The shortest stretch of voice taken for a note, in frames */
188
+ const MIN_FRAMES = 4;
189
+ /** The notes in one unbroken run of voice; `slide` is the most frames a slide into or out of a note lasts */
190
+ function notesIn(run, hop, slide) {
191
+ // A median of five steadies the line and removes single frames an octave out
192
+ const pitch = run.map((_, i) => median(run.slice(Math.max(0, i - 2), i + 3).map((f) => f.pitch)));
193
+ const level = run.map((_, i) => mean(run.slice(Math.max(0, i - 1), i + 2).map((f) => f.level)));
194
+ // Steady frames: the pitch is not sliding from one note to another (vibrato stays well under this)
195
+ const steady = pitch.map((_, i) => Math.abs(pitch[Math.min(i + 1, pitch.length - 1)] - pitch[Math.max(i - 1, 0)]) / 2 < 0.3);
196
+ const length = (s) => s.to - s.from;
197
+ // A note's pitch is where the voice settles: its first frames may still be scooping up to it
198
+ const at = (s) => median(pitch.slice(s.from + Math.floor(0.3 * (s.to - s.from)), s.to));
199
+ const notes = [];
200
+ // Each new start of the voice (a dip and a rise, or a sudden attack) begins a note; within one, the pitch may still move on
201
+ for (const [first, last] of articulations(run, level, Math.max(MIN_FRAMES, slide))) {
202
+ // Segments of steady frames within a semitone's band of their own median
203
+ let segments = [];
204
+ let from = -1;
205
+ let members = [];
206
+ const close = (to) => {
207
+ if (from >= 0 && to - from >= MIN_FRAMES)
208
+ segments.push({ from, to });
209
+ from = -1;
210
+ members = [];
211
+ };
212
+ for (let i = first; i < last; i++) {
213
+ if (!steady[i]) {
214
+ close(i);
215
+ continue;
216
+ }
217
+ if (from >= 0 && Math.abs(pitch[i] - median(members)) > 0.6)
218
+ close(i);
219
+ if (from < 0)
220
+ from = i;
221
+ members.push(pitch[i]);
222
+ }
223
+ close(last);
224
+ // A segment no longer than a slide is the voice moving between notes, unless there is nothing longer; at the start a scoop up
225
+ // to the note, and at the end a fall from it, can last twice as long
226
+ const longest = Math.max(0, ...segments.map(length));
227
+ segments = segments.filter((s) => length(s) > slide || length(s) === longest);
228
+ for (const [end, next] of [[0, 1], [segments.length - 1, segments.length - 2]]) {
229
+ const [a, b] = [segments[end], segments[next]];
230
+ if (a && b && length(a) <= 2 * slide && length(a) < length(b) && Math.abs(at(a) - at(b)) < 2.5)
231
+ segments.splice(end, 1);
232
+ }
233
+ if (!segments.length && last - first >= MIN_FRAMES)
234
+ segments = [{ from: first, to: last }];
235
+ // Neighbours at the same pitch are one note: a vibrato wider than the band can split one
236
+ for (let k = segments.length - 1; k > 0; k--) {
237
+ if (Math.abs(at(segments[k - 1]) - at(segments[k])) < 0.5) {
238
+ segments[k - 1].to = segments[k].to;
239
+ segments.splice(k, 1);
240
+ }
241
+ }
242
+ // Notes change halfway through the slide between them; the first starts with the voice and the last ends with it
243
+ segments.forEach((segment, k) => {
244
+ const start = k === 0 ? first : Math.round((segments[k - 1].to + segment.from) / 2);
245
+ const end = k === segments.length - 1 ? last : Math.round((segment.to + segments[k + 1].from) / 2);
246
+ notes.push({ start: run[start].time - hop / 2, end: run[end - 1].time + hop / 2, pitch: at(segment), tied: k > 0 });
247
+ });
248
+ }
249
+ return notes;
250
+ }
251
+ /**
252
+ * Where the same pitch starts again without a break: the voice dips by 6 dB and comes back ("da da"), or the sound jumps up by
253
+ * 3 dB within 40 ms and stays up (a new attack, the way an instrument strikes a repeated note; a voice swells far more slowly).
254
+ * `level` is smoothed; the attack is read from the frames' own levels, as smoothing blunts it.
255
+ */
256
+ function articulations(run, level, shortest) {
257
+ const parts = [];
258
+ let start = 0;
259
+ for (let i = shortest; i < run.length - shortest; i++) {
260
+ const before = Math.max(...level.slice(Math.max(start, i - 12), i));
261
+ const after = Math.max(...level.slice(i + 1, i + 13));
262
+ const dip = level[i] <= level[i - 1] && level[i] <= level[i + 1] && level[i] < before - 6 && level[i] < after - 6;
263
+ const raw = run[i].level;
264
+ const ahead = run.slice(i + 1, i + 9).map((f) => f.level);
265
+ const attack = raw <= run[i - 1].level && Math.max(...ahead.slice(0, 4)) - raw >= 3 && mean(ahead) - raw >= 2;
266
+ if (!dip && !attack)
267
+ continue;
268
+ parts.push([start, i]);
269
+ start = dip ? i + 1 : i;
270
+ i += shortest - 1;
271
+ }
272
+ parts.push([start, run.length]);
273
+ return parts;
274
+ }
275
+ const MAJOR = [6.35, 2.23, 3.48, 2.33, 4.38, 4.09, 2.52, 5.19, 2.39, 3.66, 2.29, 2.88];
276
+ const MINOR = [6.33, 2.68, 3.52, 5.38, 2.6, 3.53, 2.54, 4.75, 3.98, 2.69, 3.34, 3.17];
277
+ const MAJOR_TONICS = ['C', 'Db', 'D', 'Eb', 'E', 'F', 'F#', 'G', 'Ab', 'A', 'Bb', 'B'];
278
+ const MINOR_TONICS = ['C', 'C#', 'D', 'Eb', 'E', 'F', 'F#', 'G', 'G#', 'A', 'Bb', 'B'];
279
+ /** The notes of each mode, relative to the tonic (minor with both its sixths and sevenths) */
280
+ const SCALES = { major: [0, 2, 4, 5, 7, 9, 11], minor: [0, 2, 3, 5, 7, 8, 9, 10, 11] };
281
+ /**
282
+ * Settle each note on a semitone. The voice's offset from concert pitch is measured around each note (over its neighbours, so a
283
+ * voice that drifts flat is followed), and a note that still falls between two semitones takes the one in the key.
284
+ */
285
+ function tune(heard) {
286
+ const offsets = heard.map((_, i) => {
287
+ let [x, y] = [0, 0];
288
+ for (let j = Math.max(0, i - 4); j <= Math.min(heard.length - 1, i + 4); j++) {
289
+ const weight = heard[j].end - heard[j].start;
290
+ const angle = 2 * Math.PI * (heard[j].pitch - Math.round(heard[j].pitch));
291
+ x += weight * Math.cos(angle);
292
+ y += weight * Math.sin(angle);
293
+ }
294
+ return Math.atan2(y, x) / (2 * Math.PI);
295
+ });
296
+ const corrected = heard.map((h, i) => h.pitch - offsets[i]);
297
+ // The key whose profile best matches how long each pitch class sounds (Krumhansl and Kessler's)
298
+ const weights = new Array(12).fill(0);
299
+ corrected.forEach((p, i) => (weights[((Math.round(p) % 12) + 12) % 12] += heard[i].end - heard[i].start));
300
+ let best = { score: -Infinity, tonic: 0, mode: 'major' };
301
+ for (let tonic = 0; tonic < 12; tonic++) {
302
+ for (const [mode, profile] of [['major', MAJOR], ['minor', MINOR]]) {
303
+ const score = correlation(weights, profile.map((_, k) => profile[(k - tonic + 12) % 12]));
304
+ if (score > best.score)
305
+ best = { score, tonic, mode };
306
+ }
307
+ }
308
+ const inKey = (p) => SCALES[best.mode].includes((((p - best.tonic) % 12) + 12) % 12);
309
+ const pitches = corrected.map((p) => {
310
+ const [low, high] = [Math.floor(p), Math.ceil(p)];
311
+ const between = Math.abs(p - Math.round(p)) > 0.3;
312
+ if (between && inKey(low) !== inKey(high))
313
+ return inKey(low) ? low : high;
314
+ return Math.round(p);
315
+ });
316
+ const key = `${(best.mode === 'major' ? MAJOR_TONICS : MINOR_TONICS)[best.tonic]} ${best.mode}`;
317
+ return { pitches, key, tuning: Math.round(100 * median(offsets)) };
318
+ }
319
+ /**
320
+ * The tempo and a downbeat of notes sung without a click. The tempo is the sixteenth-note grid (between 70 and 140 beats a minute)
321
+ * the starts fit best, favouring grids on which the notes last whole eighths; the downbeat is the grid line that puts the longest
322
+ * notes on the strongest beats.
323
+ */
324
+ function findTempo(heard, bar) {
325
+ const onsets = heard.map((h) => h.start);
326
+ /** How closely the starts sit on a grid `step` seconds apart (0-1), and where its lines fall */
327
+ const fit = (step) => {
328
+ let [x, y] = [0, 0];
329
+ for (const t of onsets) {
330
+ x += Math.cos((2 * Math.PI * t) / step);
331
+ y += Math.sin((2 * Math.PI * t) / step);
332
+ }
333
+ return { closeness: Math.hypot(x, y) / onsets.length, phase: ((Math.atan2(y, x) / (2 * Math.PI)) * step + step) % step };
334
+ };
335
+ const evens = (step) => onsets.slice(1).filter((t, i) => Math.round((t - onsets[i]) / step) % 2 === 0).length / Math.max(1, onsets.length - 1);
336
+ const score = (step) => fit(step).closeness + 0.25 * evens(step);
337
+ // Coarsely across the range, then finely around the best: over a minute of singing, a tenth of a percent is a sixteenth adrift
338
+ let best = 15 / 140;
339
+ for (let step = best; step <= 15 / 70; step *= 1.001)
340
+ if (score(step) > score(best))
341
+ best = step;
342
+ for (let step = best / 1.001, around = best; step <= around * 1.001; step *= 1.00002)
343
+ if (fit(step).closeness > fit(best).closeness)
344
+ best = step;
345
+ const { phase } = fit(best);
346
+ // Where each note starts on the grid, and how long it lasts
347
+ const notes = heard.map((h) => ({ at: Math.round((h.start - phase) / best), length: h.end - h.start }));
348
+ const strength = (position) => (position === 0 ? 1 : position * 2 === bar ? 0.6 : position % 4 === 0 ? 0.4 : position % 2 === 0 ? 0.15 : 0);
349
+ let downbeat = 0;
350
+ let strongest = -Infinity;
351
+ for (let line = 0; line < bar; line++) {
352
+ const total = notes.reduce((sum, n) => sum + n.length * strength((((n.at - line) % bar) + bar) % bar), 0);
353
+ if (total > strongest)
354
+ [downbeat, strongest] = [line, total];
355
+ }
356
+ return { bpm: 15 / best, start: phase + downbeat * best };
357
+ }
358
+ /** How weak a place in the beat is: a beat, an eighth off it, a sixteenth off it */
359
+ const weakness = (step) => [0, 0.12, 0.06, 0.12][((step % 4) + 4) % 4];
360
+ /** The grid line a start goes to: the nearer of the two around it, weighed against how weak a place each is */
361
+ function snap(position, grid) {
362
+ const below = Math.floor(position / grid) * grid;
363
+ const cost = (at) => Math.abs(position - at) + weakness(at);
364
+ return cost(below) <= cost(below + grid) ? below : below + grid;
365
+ }
366
+ /**
367
+ * Put the notes on the grid. A steady lead or lag behind the beat (the singer's, or the audio hardware's) is taken out first: the
368
+ * shift, up to a step either way, that brings the starts nearest the grid and the strongest beats. A note lasts until the next one
369
+ * unless the silence before that is a rest worth writing.
370
+ */
371
+ function align(heard, bpm, start, grid, bar) {
372
+ const step = 15 / bpm;
373
+ const raw = heard.map((h) => ({ start: (h.start - start) / step, end: (h.end - start) / step }));
374
+ const cost = (shift) => raw.reduce((sum, n) => {
375
+ const at = snap(n.start - shift, grid);
376
+ return sum + Math.abs(n.start - shift - at) + weakness(at);
377
+ }, 0.02 * raw.length * Math.abs(shift));
378
+ let shift = 0;
379
+ for (let s = -1; s <= 1; s += 0.02)
380
+ if (cost(s) < cost(shift))
381
+ shift = s;
382
+ const timed = [];
383
+ raw.forEach(({ start: s, end: e }, index) => {
384
+ const at = snap(s - shift, grid);
385
+ const previous = timed[timed.length - 1];
386
+ if (previous && at <= previous.start) {
387
+ // Two notes on one grid line: the shorter was a slip of the voice
388
+ if (e - s <= previous.end - previous.start)
389
+ return;
390
+ timed.pop();
391
+ }
392
+ timed.push({ start: at, end: e - shift, index });
393
+ });
394
+ const eighths = Math.max(grid, 2);
395
+ timed.forEach((note, i) => {
396
+ // Where a note let go ends: on the beat it was let go up to half a beat before, or else in the eighth it was let go in (voices
397
+ // let go a little early, and fade a little late)
398
+ const beat = Math.ceil(note.end / 4) * 4;
399
+ const released = Math.max(note.start + grid, beat - note.end <= 2 ? beat : Math.ceil((note.end - 0.6) / eighths) * eighths);
400
+ const next = timed[i + 1]?.start;
401
+ if (next === undefined) {
402
+ // The last note rings on to the bar line if it gets within three sixteenths of it
403
+ const barline = Math.ceil(note.end / bar) * bar;
404
+ note.end = barline - note.end <= 3 ? barline : released;
405
+ return;
406
+ }
407
+ // A rest is written for a silence of half a beat and a third of a second, as long as a beat or two fifths of the time from
408
+ // one note to the next
409
+ const silence = next - note.end;
410
+ const rest = silence >= 2 && silence * step >= 1 / 3 && (silence >= 4 || silence >= 0.4 * (next - note.start));
411
+ note.end = rest ? Math.min(released, next) : next;
412
+ });
413
+ return { timed, shift };
414
+ }
415
+ function median(values) {
416
+ const sorted = [...values].sort((a, b) => a - b);
417
+ const mid = sorted.length >> 1;
418
+ return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
419
+ }
420
+ function mean(values) {
421
+ return values.reduce((a, b) => a + b, 0) / values.length;
422
+ }
423
+ function correlation(a, b) {
424
+ const [ma, mb] = [mean(a), mean(b)];
425
+ let [ab, aa, bb] = [0, 0, 0];
426
+ for (let i = 0; i < a.length; i++) {
427
+ ab += (a[i] - ma) * (b[i] - mb);
428
+ aa += (a[i] - ma) ** 2;
429
+ bb += (b[i] - mb) ** 2;
430
+ }
431
+ return aa && bb ? ab / Math.sqrt(aa * bb) : 0;
432
+ }
433
+ //# sourceMappingURL=transcribe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcribe.js","sourceRoot":"","sources":["../src/transcribe.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,59 @@
1
1
  {
2
2
  "name": "polyphon",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Music for the browser, written as code: a score notation, a synthesized orchestra and a scheduler on top of the Web Audio API. No audio files.",
5
+ "license": "MIT",
6
+ "author": "Yu Lun Hsu",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/alan890104/polyphon.git"
10
+ },
11
+ "keywords": [
12
+ "music",
13
+ "web-audio",
14
+ "synthesizer",
15
+ "game-audio",
16
+ "soundtrack",
17
+ "sequencer",
18
+ "notation"
19
+ ],
20
+ "type": "module",
21
+ "sideEffects": false,
22
+ "exports": {
23
+ ".": {
24
+ "polyphon-source": "./src/index.ts",
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
27
+ }
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "src"
32
+ ],
33
+ "engines": {
34
+ "node": ">=22.18"
35
+ },
36
+ "scripts": {
37
+ "dev": "vite --config player/vite.config.ts",
38
+ "build": "tsc -p tsconfig.build.json",
39
+ "prepare": "npm run build",
40
+ "build:player": "vite build --config player/vite.config.ts",
41
+ "preview": "vite preview --config player/vite.config.ts",
42
+ "test": "node --conditions=polyphon-source --test \"test/**/*.test.ts\"",
43
+ "typecheck": "tsc --noEmit -p . && tsc --noEmit -p player",
44
+ "prepublishOnly": "npm run typecheck && npm test && npm run build"
45
+ },
46
+ "devDependencies": {
47
+ "@breezystack/lamejs": "^1.2.7",
48
+ "@types/node": "^22.20.4",
49
+ "@types/react": "^19.3.0",
50
+ "@types/react-dom": "^19.3.0",
51
+ "@types/three": "0.186.0",
52
+ "@vitejs/plugin-react": "^6.1.1",
53
+ "react": "^19.3.0",
54
+ "react-dom": "^19.3.0",
55
+ "three": "0.186.1",
56
+ "typescript": "^7.0.2",
57
+ "vite": "^8.3.1"
58
+ }
59
+ }