@mcptoolshop/ai-jam-sessions 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 (408) hide show
  1. package/LICENSE +21 -0
  2. package/README.es.md +177 -0
  3. package/README.fr.md +178 -0
  4. package/README.hi.md +175 -0
  5. package/README.it.md +177 -0
  6. package/README.ja.md +174 -0
  7. package/README.md +174 -0
  8. package/README.pt-BR.md +177 -0
  9. package/README.zh.md +173 -0
  10. package/dist/audio-engine.d.ts +12 -0
  11. package/dist/audio-engine.d.ts.map +1 -0
  12. package/dist/audio-engine.js +422 -0
  13. package/dist/audio-engine.js.map +1 -0
  14. package/dist/chord-detect.d.ts +14 -0
  15. package/dist/chord-detect.d.ts.map +1 -0
  16. package/dist/chord-detect.js +90 -0
  17. package/dist/chord-detect.js.map +1 -0
  18. package/dist/cli.d.ts +3 -0
  19. package/dist/cli.d.ts.map +1 -0
  20. package/dist/cli.js +805 -0
  21. package/dist/cli.js.map +1 -0
  22. package/dist/index.d.ts +32 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +41 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/journal.d.ts +41 -0
  27. package/dist/journal.d.ts.map +1 -0
  28. package/dist/journal.js +149 -0
  29. package/dist/journal.js.map +1 -0
  30. package/dist/mcp-server.d.ts +3 -0
  31. package/dist/mcp-server.d.ts.map +1 -0
  32. package/dist/mcp-server.js +1256 -0
  33. package/dist/mcp-server.js.map +1 -0
  34. package/dist/midi/parser.d.ts +16 -0
  35. package/dist/midi/parser.d.ts.map +1 -0
  36. package/dist/midi/parser.js +192 -0
  37. package/dist/midi/parser.js.map +1 -0
  38. package/dist/midi/types.d.ts +44 -0
  39. package/dist/midi/types.d.ts.map +1 -0
  40. package/dist/midi/types.js +8 -0
  41. package/dist/midi/types.js.map +1 -0
  42. package/dist/note-parser.d.ts +105 -0
  43. package/dist/note-parser.d.ts.map +1 -0
  44. package/dist/note-parser.js +319 -0
  45. package/dist/note-parser.js.map +1 -0
  46. package/dist/piano-roll.d.ts +28 -0
  47. package/dist/piano-roll.d.ts.map +1 -0
  48. package/dist/piano-roll.js +321 -0
  49. package/dist/piano-roll.js.map +1 -0
  50. package/dist/piano-voices.d.ts +90 -0
  51. package/dist/piano-voices.d.ts.map +1 -0
  52. package/dist/piano-voices.js +416 -0
  53. package/dist/piano-voices.js.map +1 -0
  54. package/dist/playback/controls.d.ts +124 -0
  55. package/dist/playback/controls.d.ts.map +1 -0
  56. package/dist/playback/controls.js +252 -0
  57. package/dist/playback/controls.js.map +1 -0
  58. package/dist/playback/midi-engine.d.ts +68 -0
  59. package/dist/playback/midi-engine.d.ts.map +1 -0
  60. package/dist/playback/midi-engine.js +227 -0
  61. package/dist/playback/midi-engine.js.map +1 -0
  62. package/dist/playback/position.d.ts +95 -0
  63. package/dist/playback/position.d.ts.map +1 -0
  64. package/dist/playback/position.js +223 -0
  65. package/dist/playback/position.js.map +1 -0
  66. package/dist/playback/timing.d.ts +31 -0
  67. package/dist/playback/timing.d.ts.map +1 -0
  68. package/dist/playback/timing.js +57 -0
  69. package/dist/playback/timing.js.map +1 -0
  70. package/dist/sample-engine.d.ts +17 -0
  71. package/dist/sample-engine.d.ts.map +1 -0
  72. package/dist/sample-engine.js +428 -0
  73. package/dist/sample-engine.js.map +1 -0
  74. package/dist/schemas.d.ts +40 -0
  75. package/dist/schemas.d.ts.map +1 -0
  76. package/dist/schemas.js +42 -0
  77. package/dist/schemas.js.map +1 -0
  78. package/dist/session.d.ts +106 -0
  79. package/dist/session.d.ts.map +1 -0
  80. package/dist/session.js +361 -0
  81. package/dist/session.js.map +1 -0
  82. package/dist/sfz-parser.d.ts +36 -0
  83. package/dist/sfz-parser.d.ts.map +1 -0
  84. package/dist/sfz-parser.js +95 -0
  85. package/dist/sfz-parser.js.map +1 -0
  86. package/dist/smoke.d.ts +2 -0
  87. package/dist/smoke.d.ts.map +1 -0
  88. package/dist/smoke.js +512 -0
  89. package/dist/smoke.js.map +1 -0
  90. package/dist/songs/config/loader.d.ts +14 -0
  91. package/dist/songs/config/loader.d.ts.map +1 -0
  92. package/dist/songs/config/loader.js +53 -0
  93. package/dist/songs/config/loader.js.map +1 -0
  94. package/dist/songs/config/schema.d.ts +79 -0
  95. package/dist/songs/config/schema.d.ts.map +1 -0
  96. package/dist/songs/config/schema.js +56 -0
  97. package/dist/songs/config/schema.js.map +1 -0
  98. package/dist/songs/index.d.ts +18 -0
  99. package/dist/songs/index.d.ts.map +1 -0
  100. package/dist/songs/index.js +22 -0
  101. package/dist/songs/index.js.map +1 -0
  102. package/dist/songs/jam.d.ts +48 -0
  103. package/dist/songs/jam.d.ts.map +1 -0
  104. package/dist/songs/jam.js +338 -0
  105. package/dist/songs/jam.js.map +1 -0
  106. package/dist/songs/library.d.ts +47 -0
  107. package/dist/songs/library.d.ts.map +1 -0
  108. package/dist/songs/library.js +156 -0
  109. package/dist/songs/library.js.map +1 -0
  110. package/dist/songs/loader.d.ts +27 -0
  111. package/dist/songs/loader.d.ts.map +1 -0
  112. package/dist/songs/loader.js +90 -0
  113. package/dist/songs/loader.js.map +1 -0
  114. package/dist/songs/midi/hands.d.ts +46 -0
  115. package/dist/songs/midi/hands.d.ts.map +1 -0
  116. package/dist/songs/midi/hands.js +134 -0
  117. package/dist/songs/midi/hands.js.map +1 -0
  118. package/dist/songs/midi/ingest.d.ts +8 -0
  119. package/dist/songs/midi/ingest.d.ts.map +1 -0
  120. package/dist/songs/midi/ingest.js +197 -0
  121. package/dist/songs/midi/ingest.js.map +1 -0
  122. package/dist/songs/midi/measures.d.ts +41 -0
  123. package/dist/songs/midi/measures.d.ts.map +1 -0
  124. package/dist/songs/midi/measures.js +64 -0
  125. package/dist/songs/midi/measures.js.map +1 -0
  126. package/dist/songs/midi/types.d.ts +25 -0
  127. package/dist/songs/midi/types.d.ts.map +1 -0
  128. package/dist/songs/midi/types.js +8 -0
  129. package/dist/songs/midi/types.js.map +1 -0
  130. package/dist/songs/registry.d.ts +37 -0
  131. package/dist/songs/registry.d.ts.map +1 -0
  132. package/dist/songs/registry.js +197 -0
  133. package/dist/songs/registry.js.map +1 -0
  134. package/dist/songs/types.d.ts +99 -0
  135. package/dist/songs/types.d.ts.map +1 -0
  136. package/dist/songs/types.js +29 -0
  137. package/dist/songs/types.js.map +1 -0
  138. package/dist/teaching/live-midi-feedback.d.ts +36 -0
  139. package/dist/teaching/live-midi-feedback.d.ts.map +1 -0
  140. package/dist/teaching/live-midi-feedback.js +259 -0
  141. package/dist/teaching/live-midi-feedback.js.map +1 -0
  142. package/dist/teaching/midi-feedback.d.ts +33 -0
  143. package/dist/teaching/midi-feedback.d.ts.map +1 -0
  144. package/dist/teaching/midi-feedback.js +208 -0
  145. package/dist/teaching/midi-feedback.js.map +1 -0
  146. package/dist/teaching/sing-on-midi.d.ts +77 -0
  147. package/dist/teaching/sing-on-midi.d.ts.map +1 -0
  148. package/dist/teaching/sing-on-midi.js +186 -0
  149. package/dist/teaching/sing-on-midi.js.map +1 -0
  150. package/dist/teaching.d.ts +148 -0
  151. package/dist/teaching.d.ts.map +1 -0
  152. package/dist/teaching.js +453 -0
  153. package/dist/teaching.js.map +1 -0
  154. package/dist/test-sound.d.ts +3 -0
  155. package/dist/test-sound.d.ts.map +1 -0
  156. package/dist/test-sound.js +41 -0
  157. package/dist/test-sound.js.map +1 -0
  158. package/dist/types.d.ts +229 -0
  159. package/dist/types.d.ts.map +1 -0
  160. package/dist/types.js +28 -0
  161. package/dist/types.js.map +1 -0
  162. package/dist/vmpk.d.ts +23 -0
  163. package/dist/vmpk.d.ts.map +1 -0
  164. package/dist/vmpk.js +236 -0
  165. package/dist/vmpk.js.map +1 -0
  166. package/docs/fur-elise-m1-8.svg +290 -0
  167. package/logo.png +0 -0
  168. package/package.json +71 -0
  169. package/songs/library/blues/blues-in-the-night.json +14 -0
  170. package/songs/library/blues/blues-in-the-night.mid +0 -0
  171. package/songs/library/blues/born-under-a-bad-sign.json +13 -0
  172. package/songs/library/blues/born-under-a-bad-sign.mid +0 -0
  173. package/songs/library/blues/crossroad-blues.json +14 -0
  174. package/songs/library/blues/crossroad-blues.mid +0 -0
  175. package/songs/library/blues/everyday-i-have-the-blues.json +13 -0
  176. package/songs/library/blues/everyday-i-have-the-blues.mid +0 -0
  177. package/songs/library/blues/hoochie-coochie-man.json +14 -0
  178. package/songs/library/blues/hoochie-coochie-man.mid +0 -0
  179. package/songs/library/blues/red-house.json +14 -0
  180. package/songs/library/blues/red-house.mid +0 -0
  181. package/songs/library/blues/st-louis-blues.json +14 -0
  182. package/songs/library/blues/st-louis-blues.mid +0 -0
  183. package/songs/library/blues/stormy-monday.json +13 -0
  184. package/songs/library/blues/stormy-monday.mid +0 -0
  185. package/songs/library/blues/sweet-home-chicago.json +14 -0
  186. package/songs/library/blues/sweet-home-chicago.mid +0 -0
  187. package/songs/library/blues/the-thrill-is-gone.json +17 -0
  188. package/songs/library/blues/the-thrill-is-gone.mid +0 -0
  189. package/songs/library/classical/bach-prelude-c-major-bwv846.json +37 -0
  190. package/songs/library/classical/bach-prelude-c-major-bwv846.mid +0 -0
  191. package/songs/library/classical/chopin-nocturne-op9-no2.json +36 -0
  192. package/songs/library/classical/chopin-nocturne-op9-no2.mid +0 -0
  193. package/songs/library/classical/chopin-prelude-e-minor.json +35 -0
  194. package/songs/library/classical/chopin-prelude-e-minor.mid +0 -0
  195. package/songs/library/classical/clair-de-lune.json +37 -0
  196. package/songs/library/classical/clair-de-lune.mid +0 -0
  197. package/songs/library/classical/debussy-arabesque-no1.json +35 -0
  198. package/songs/library/classical/debussy-arabesque-no1.mid +0 -0
  199. package/songs/library/classical/fur-elise.json +35 -0
  200. package/songs/library/classical/fur-elise.mid +0 -0
  201. package/songs/library/classical/mozart-k545-mvt1.json +35 -0
  202. package/songs/library/classical/mozart-k545-mvt1.mid +0 -0
  203. package/songs/library/classical/pathetique-mvt2.json +36 -0
  204. package/songs/library/classical/pathetique-mvt2.mid +0 -0
  205. package/songs/library/classical/satie-gymnopedie-no1.json +36 -0
  206. package/songs/library/classical/satie-gymnopedie-no1.mid +0 -0
  207. package/songs/library/classical/schumann-traumerei.json +36 -0
  208. package/songs/library/classical/schumann-traumerei.mid +0 -0
  209. package/songs/library/film/cinema-paradiso.json +14 -0
  210. package/songs/library/film/cinema-paradiso.mid +0 -0
  211. package/songs/library/film/comptine-dun-autre-ete.json +17 -0
  212. package/songs/library/film/comptine-dun-autre-ete.mid +0 -0
  213. package/songs/library/film/forrest-gump.json +14 -0
  214. package/songs/library/film/forrest-gump.mid +0 -0
  215. package/songs/library/film/hedwigs-theme.json +14 -0
  216. package/songs/library/film/hedwigs-theme.mid +0 -0
  217. package/songs/library/film/mia-and-sebastians-theme.json +14 -0
  218. package/songs/library/film/mia-and-sebastians-theme.mid +0 -0
  219. package/songs/library/film/moon-river.json +14 -0
  220. package/songs/library/film/moon-river.mid +0 -0
  221. package/songs/library/film/my-heart-will-go-on.json +14 -0
  222. package/songs/library/film/my-heart-will-go-on.mid +0 -0
  223. package/songs/library/film/nuvole-bianche.json +14 -0
  224. package/songs/library/film/nuvole-bianche.mid +0 -0
  225. package/songs/library/film/pink-panther.json +14 -0
  226. package/songs/library/film/pink-panther.mid +0 -0
  227. package/songs/library/film/schindlers-list-theme.json +14 -0
  228. package/songs/library/film/schindlers-list-theme.mid +0 -0
  229. package/songs/library/folk/amazing-grace.json +14 -0
  230. package/songs/library/folk/amazing-grace.mid +0 -0
  231. package/songs/library/folk/auld-lang-syne.json +14 -0
  232. package/songs/library/folk/auld-lang-syne.mid +0 -0
  233. package/songs/library/folk/danny-boy.json +14 -0
  234. package/songs/library/folk/danny-boy.mid +0 -0
  235. package/songs/library/folk/greensleeves.json +17 -0
  236. package/songs/library/folk/greensleeves.mid +0 -0
  237. package/songs/library/folk/house-of-the-rising-sun.json +14 -0
  238. package/songs/library/folk/house-of-the-rising-sun.mid +0 -0
  239. package/songs/library/folk/sakura-sakura.json +14 -0
  240. package/songs/library/folk/sakura-sakura.mid +0 -0
  241. package/songs/library/folk/scarborough-fair.json +14 -0
  242. package/songs/library/folk/scarborough-fair.mid +0 -0
  243. package/songs/library/folk/shenandoah.json +14 -0
  244. package/songs/library/folk/shenandoah.mid +0 -0
  245. package/songs/library/folk/simple-gifts.json +14 -0
  246. package/songs/library/folk/simple-gifts.mid +0 -0
  247. package/songs/library/folk/the-water-is-wide.json +14 -0
  248. package/songs/library/folk/the-water-is-wide.mid +0 -0
  249. package/songs/library/jazz/all-the-things-you-are.json +13 -0
  250. package/songs/library/jazz/all-the-things-you-are.mid +0 -0
  251. package/songs/library/jazz/autumn-leaves.json +17 -0
  252. package/songs/library/jazz/autumn-leaves.mid +0 -0
  253. package/songs/library/jazz/blue-bossa.json +14 -0
  254. package/songs/library/jazz/blue-bossa.mid +0 -0
  255. package/songs/library/jazz/fly-me-to-the-moon.json +14 -0
  256. package/songs/library/jazz/fly-me-to-the-moon.mid +0 -0
  257. package/songs/library/jazz/georgia-on-my-mind.json +14 -0
  258. package/songs/library/jazz/georgia-on-my-mind.mid +0 -0
  259. package/songs/library/jazz/misty.json +14 -0
  260. package/songs/library/jazz/misty.mid +0 -0
  261. package/songs/library/jazz/my-funny-valentine.json +14 -0
  262. package/songs/library/jazz/my-funny-valentine.mid +0 -0
  263. package/songs/library/jazz/round-midnight.json +14 -0
  264. package/songs/library/jazz/round-midnight.mid +0 -0
  265. package/songs/library/jazz/summertime.json +14 -0
  266. package/songs/library/jazz/summertime.mid +0 -0
  267. package/songs/library/jazz/take-the-a-train.json +14 -0
  268. package/songs/library/jazz/take-the-a-train.mid +0 -0
  269. package/songs/library/latin/agua-de-beber.json +14 -0
  270. package/songs/library/latin/agua-de-beber.mid +0 -0
  271. package/songs/library/latin/besame-mucho.json +14 -0
  272. package/songs/library/latin/besame-mucho.mid +0 -0
  273. package/songs/library/latin/black-orpheus.json +14 -0
  274. package/songs/library/latin/black-orpheus.mid +0 -0
  275. package/songs/library/latin/corcovado.json +14 -0
  276. package/songs/library/latin/corcovado.mid +0 -0
  277. package/songs/library/latin/desafinado.json +14 -0
  278. package/songs/library/latin/desafinado.mid +0 -0
  279. package/songs/library/latin/el-condor-pasa.json +14 -0
  280. package/songs/library/latin/el-condor-pasa.mid +0 -0
  281. package/songs/library/latin/girl-from-ipanema.json +17 -0
  282. package/songs/library/latin/girl-from-ipanema.mid +0 -0
  283. package/songs/library/latin/mas-que-nada.json +14 -0
  284. package/songs/library/latin/mas-que-nada.mid +0 -0
  285. package/songs/library/latin/perfidia.json +14 -0
  286. package/songs/library/latin/perfidia.mid +0 -0
  287. package/songs/library/latin/wave.json +14 -0
  288. package/songs/library/latin/wave.mid +0 -0
  289. package/songs/library/new-age/divenire.json +14 -0
  290. package/songs/library/new-age/divenire.mid +0 -0
  291. package/songs/library/new-age/experience.json +14 -0
  292. package/songs/library/new-age/experience.mid +0 -0
  293. package/songs/library/new-age/kiss-the-rain.json +14 -0
  294. package/songs/library/new-age/kiss-the-rain.mid +0 -0
  295. package/songs/library/new-age/may-be.json +13 -0
  296. package/songs/library/new-age/may-be.mid +0 -0
  297. package/songs/library/new-age/metamorphosis-two.json +14 -0
  298. package/songs/library/new-age/metamorphosis-two.mid +0 -0
  299. package/songs/library/new-age/nuvole-bianche-na.json +14 -0
  300. package/songs/library/new-age/nuvole-bianche-na.mid +0 -0
  301. package/songs/library/new-age/opening-glassworks.json +14 -0
  302. package/songs/library/new-age/opening-glassworks.mid +0 -0
  303. package/songs/library/new-age/river-flows-in-you.json +17 -0
  304. package/songs/library/new-age/river-flows-in-you.mid +0 -0
  305. package/songs/library/new-age/una-mattina.json +14 -0
  306. package/songs/library/new-age/una-mattina.mid +0 -0
  307. package/songs/library/new-age/watermark.json +14 -0
  308. package/songs/library/new-age/watermark.mid +0 -0
  309. package/songs/library/pop/a-thousand-years.json +14 -0
  310. package/songs/library/pop/a-thousand-years.mid +0 -0
  311. package/songs/library/pop/all-of-me.json +14 -0
  312. package/songs/library/pop/all-of-me.mid +0 -0
  313. package/songs/library/pop/bohemian-rhapsody.json +14 -0
  314. package/songs/library/pop/bohemian-rhapsody.mid +0 -0
  315. package/songs/library/pop/clocks.json +14 -0
  316. package/songs/library/pop/clocks.mid +0 -0
  317. package/songs/library/pop/imagine.json +17 -0
  318. package/songs/library/pop/imagine.mid +0 -0
  319. package/songs/library/pop/let-it-be.json +14 -0
  320. package/songs/library/pop/let-it-be.mid +0 -0
  321. package/songs/library/pop/piano-man.json +14 -0
  322. package/songs/library/pop/piano-man.mid +0 -0
  323. package/songs/library/pop/someone-like-you.json +14 -0
  324. package/songs/library/pop/someone-like-you.mid +0 -0
  325. package/songs/library/pop/someone-you-loved.json +14 -0
  326. package/songs/library/pop/someone-you-loved.mid +0 -0
  327. package/songs/library/pop/viva-la-vida.json +14 -0
  328. package/songs/library/pop/viva-la-vida.mid +0 -0
  329. package/songs/library/ragtime/bethena.json +14 -0
  330. package/songs/library/ragtime/bethena.mid +0 -0
  331. package/songs/library/ragtime/elite-syncopations.json +13 -0
  332. package/songs/library/ragtime/elite-syncopations.mid +0 -0
  333. package/songs/library/ragtime/gladiolus-rag.json +13 -0
  334. package/songs/library/ragtime/gladiolus-rag.mid +0 -0
  335. package/songs/library/ragtime/maple-leaf-rag.json +13 -0
  336. package/songs/library/ragtime/maple-leaf-rag.mid +0 -0
  337. package/songs/library/ragtime/peacherine-rag.json +13 -0
  338. package/songs/library/ragtime/peacherine-rag.mid +0 -0
  339. package/songs/library/ragtime/pineapple-rag.json +13 -0
  340. package/songs/library/ragtime/pineapple-rag.mid +0 -0
  341. package/songs/library/ragtime/solace.json +14 -0
  342. package/songs/library/ragtime/solace.mid +0 -0
  343. package/songs/library/ragtime/the-easy-winners.json +13 -0
  344. package/songs/library/ragtime/the-easy-winners.mid +0 -0
  345. package/songs/library/ragtime/the-entertainer.json +17 -0
  346. package/songs/library/ragtime/the-entertainer.mid +0 -0
  347. package/songs/library/ragtime/weeping-willow.json +14 -0
  348. package/songs/library/ragtime/weeping-willow.mid +0 -0
  349. package/songs/library/rnb/fallin.json +17 -0
  350. package/songs/library/rnb/fallin.mid +0 -0
  351. package/songs/library/rnb/halo.json +14 -0
  352. package/songs/library/rnb/halo.mid +0 -0
  353. package/songs/library/rnb/i-will-always-love-you.json +14 -0
  354. package/songs/library/rnb/i-will-always-love-you.mid +0 -0
  355. package/songs/library/rnb/if-i-aint-got-you.json +17 -0
  356. package/songs/library/rnb/if-i-aint-got-you.mid +0 -0
  357. package/songs/library/rnb/isnt-she-lovely.json +17 -0
  358. package/songs/library/rnb/isnt-she-lovely.mid +0 -0
  359. package/songs/library/rnb/killing-me-softly.json +14 -0
  360. package/songs/library/rnb/killing-me-softly.mid +0 -0
  361. package/songs/library/rnb/no-one.json +14 -0
  362. package/songs/library/rnb/no-one.mid +0 -0
  363. package/songs/library/rnb/ordinary-people.json +14 -0
  364. package/songs/library/rnb/ordinary-people.mid +0 -0
  365. package/songs/library/rnb/ribbon-in-the-sky.json +14 -0
  366. package/songs/library/rnb/ribbon-in-the-sky.mid +0 -0
  367. package/songs/library/rnb/superstition.json +17 -0
  368. package/songs/library/rnb/superstition.mid +0 -0
  369. package/songs/library/rock/baba-oriley.json +14 -0
  370. package/songs/library/rock/baba-oriley.mid +0 -0
  371. package/songs/library/rock/bennie-and-the-jets.json +14 -0
  372. package/songs/library/rock/bennie-and-the-jets.mid +0 -0
  373. package/songs/library/rock/dont-stop-believin.json +14 -0
  374. package/songs/library/rock/dont-stop-believin.mid +0 -0
  375. package/songs/library/rock/dream-on.json +14 -0
  376. package/songs/library/rock/dream-on.mid +0 -0
  377. package/songs/library/rock/layla-unplugged.json +14 -0
  378. package/songs/library/rock/layla-unplugged.mid +0 -0
  379. package/songs/library/rock/november-rain.json +15 -0
  380. package/songs/library/rock/november-rain.mid +0 -0
  381. package/songs/library/rock/rocket-man.json +14 -0
  382. package/songs/library/rock/rocket-man.mid +0 -0
  383. package/songs/library/rock/stairway-to-heaven.json +14 -0
  384. package/songs/library/rock/stairway-to-heaven.mid +0 -0
  385. package/songs/library/rock/tiny-dancer.json +14 -0
  386. package/songs/library/rock/tiny-dancer.mid +0 -0
  387. package/songs/library/rock/your-song.json +17 -0
  388. package/songs/library/rock/your-song.mid +0 -0
  389. package/songs/library/soul/a-change-is-gonna-come.json +14 -0
  390. package/songs/library/soul/a-change-is-gonna-come.mid +0 -0
  391. package/songs/library/soul/aint-no-sunshine.json +14 -0
  392. package/songs/library/soul/aint-no-sunshine.mid +0 -0
  393. package/songs/library/soul/dock-of-the-bay.json +13 -0
  394. package/songs/library/soul/dock-of-the-bay.mid +0 -0
  395. package/songs/library/soul/i-got-you.json +14 -0
  396. package/songs/library/soul/i-got-you.mid +0 -0
  397. package/songs/library/soul/lean-on-me.json +17 -0
  398. package/songs/library/soul/lean-on-me.mid +0 -0
  399. package/songs/library/soul/lets-stay-together.json +14 -0
  400. package/songs/library/soul/lets-stay-together.mid +0 -0
  401. package/songs/library/soul/my-girl.json +14 -0
  402. package/songs/library/soul/my-girl.mid +0 -0
  403. package/songs/library/soul/respect.json +14 -0
  404. package/songs/library/soul/respect.mid +0 -0
  405. package/songs/library/soul/stand-by-me.json +14 -0
  406. package/songs/library/soul/stand-by-me.mid +0 -0
  407. package/songs/library/soul/whats-going-on.json +14 -0
  408. package/songs/library/soul/whats-going-on.mid +0 -0
@@ -0,0 +1,428 @@
1
+ // ─── pianoai: Sample-Based Piano Engine ─────────────────────────────────────
2
+ //
3
+ // Plays real piano samples from the Accurate-Salamander Grand Piano library.
4
+ // 480 WAV samples (48kHz/24-bit), 16 velocity layers, 88 keys.
5
+ //
6
+ // This replaces the oscillator-based engine with actual recorded sound.
7
+ //
8
+ // Usage:
9
+ // const piano = createSampleEngine({ samplesDir: "samples/AccurateSalamander" });
10
+ // await piano.connect(); // loads SFZ + WAV files (~1.6GB)
11
+ // piano.noteOn(60, 100); // middle C, forte — real piano sound
12
+ // piano.noteOff(60);
13
+ // await piano.disconnect();
14
+ // ─────────────────────────────────────────────────────────────────────────────
15
+ import { readFileSync } from "node:fs";
16
+ import { join } from "node:path";
17
+ import { parseSfzFile } from "./sfz-parser.js";
18
+ function buildRegionMap(regions) {
19
+ const map = new Map();
20
+ for (const r of regions) {
21
+ for (let key = r.lokey; key <= r.hikey; key++) {
22
+ let slots = map.get(key);
23
+ if (!slots) {
24
+ slots = [];
25
+ map.set(key, slots);
26
+ }
27
+ slots.push({ lovel: r.lovel, hivel: r.hivel, region: r });
28
+ }
29
+ }
30
+ // Sort by lovel for binary search
31
+ for (const [, slots] of map) {
32
+ slots.sort((a, b) => a.lovel - b.lovel);
33
+ }
34
+ return map;
35
+ }
36
+ /** Find the matching region for a given MIDI note + velocity. */
37
+ function findRegion(regionMap, note, velocity) {
38
+ const slots = regionMap.get(note);
39
+ if (!slots || slots.length === 0)
40
+ return null;
41
+ for (const slot of slots) {
42
+ if (velocity >= slot.lovel && velocity <= slot.hivel)
43
+ return slot.region;
44
+ }
45
+ // Fallback: closest velocity
46
+ return slots[slots.length - 1].region;
47
+ }
48
+ // ─── Audio Helpers ──────────────────────────────────────────────────────────
49
+ /** Stereo pan: bass left, treble right (player perspective). */
50
+ function noteToPan(note) {
51
+ return Math.max(-0.7, Math.min(0.7, ((note - 21) / 87) * 1.4 - 0.7));
52
+ }
53
+ /** Convert dB to linear gain. */
54
+ function dbToGain(db) {
55
+ return Math.pow(10, db / 20);
56
+ }
57
+ /** Compute playback rate for pitch shifting: cents from sample's pitch center. */
58
+ function centsToRate(cents) {
59
+ return Math.pow(2, cents / 1200);
60
+ }
61
+ // ─── Lazy Import ────────────────────────────────────────────────────────────
62
+ let _AudioContext = null;
63
+ async function loadAudioContext() {
64
+ if (!_AudioContext) {
65
+ const mod = await import("node-web-audio-api");
66
+ _AudioContext = mod.AudioContext;
67
+ }
68
+ return _AudioContext;
69
+ }
70
+ // ─── Engine ─────────────────────────────────────────────────────────────────
71
+ /**
72
+ * Create a sample-based piano engine using Accurate-Salamander samples.
73
+ *
74
+ * Implements VmpkConnector so it's a drop-in replacement for the old
75
+ * oscillator engine.
76
+ */
77
+ export function createSampleEngine(options) {
78
+ const { samplesDir, sfzProfile = "sfz_minimum", maxPolyphony = 48, } = options;
79
+ let ctx = null;
80
+ let currentStatus = "disconnected";
81
+ let compressor = null;
82
+ let master = null;
83
+ // Sample data
84
+ let sfzData = null;
85
+ let regionMap = null;
86
+ const audioBuffers = new Map(); // sample path → AudioBuffer
87
+ // Voice management
88
+ const activeVoices = new Map();
89
+ const voiceOrder = [];
90
+ // ── WAV Parsing ──
91
+ /**
92
+ * Parse a WAV file into an AudioBuffer manually.
93
+ * Handles 16-bit and 24-bit PCM (the Accurate-Salamander set is 24-bit/48kHz).
94
+ * This avoids needing the async decodeAudioData call for 480+ files.
95
+ */
96
+ function parseWavToAudioBuffer(filePath) {
97
+ const fileData = readFileSync(filePath);
98
+ const view = new DataView(fileData.buffer, fileData.byteOffset, fileData.byteLength);
99
+ // ── Find 'fmt ' chunk ──
100
+ let offset = 12; // skip RIFF header (4 RIFF + 4 size + 4 WAVE)
101
+ let fmtOffset = -1;
102
+ let dataOffset = -1;
103
+ let dataSize = 0;
104
+ while (offset < view.byteLength - 8) {
105
+ const chunkId = String.fromCharCode(view.getUint8(offset)) +
106
+ String.fromCharCode(view.getUint8(offset + 1)) +
107
+ String.fromCharCode(view.getUint8(offset + 2)) +
108
+ String.fromCharCode(view.getUint8(offset + 3));
109
+ const chunkSize = view.getUint32(offset + 4, true);
110
+ if (chunkId === "fmt ") {
111
+ fmtOffset = offset + 8;
112
+ }
113
+ else if (chunkId === "data") {
114
+ dataOffset = offset + 8;
115
+ dataSize = chunkSize;
116
+ }
117
+ if (fmtOffset >= 0 && dataOffset >= 0)
118
+ break;
119
+ // Next chunk (aligned to 2 bytes)
120
+ offset += 8 + chunkSize + (chunkSize % 2);
121
+ }
122
+ if (fmtOffset < 0)
123
+ throw new Error(`No 'fmt ' chunk in ${filePath}`);
124
+ if (dataOffset < 0)
125
+ throw new Error(`No 'data' chunk in ${filePath}`);
126
+ // ── Parse format ──
127
+ let audioFormat = view.getUint16(fmtOffset, true);
128
+ const numChannels = view.getUint16(fmtOffset + 2, true);
129
+ const sampleRate = view.getUint32(fmtOffset + 4, true);
130
+ let bitsPerSample = view.getUint16(fmtOffset + 14, true);
131
+ // WAVE_FORMAT_EXTENSIBLE (0xFFFE / 65534): real format is in SubFormat GUID
132
+ if (audioFormat === 0xFFFE) {
133
+ // cbSize at offset 16 (should be 22), wValidBitsPerSample at offset 18
134
+ const validBits = view.getUint16(fmtOffset + 18, true);
135
+ if (validBits > 0)
136
+ bitsPerSample = validBits;
137
+ // SubFormat GUID starts at offset 24, first 2 bytes = actual format tag
138
+ audioFormat = view.getUint16(fmtOffset + 24, true);
139
+ }
140
+ if (audioFormat !== 1 && audioFormat !== 3) {
141
+ throw new Error(`Unsupported WAV format ${audioFormat} (need PCM=1 or IEEE_FLOAT=3) in ${filePath}`);
142
+ }
143
+ const isFloat = audioFormat === 3;
144
+ const bytesPerSample = bitsPerSample / 8;
145
+ const numFrames = Math.floor(dataSize / (numChannels * bytesPerSample));
146
+ // ── Create AudioBuffer ──
147
+ const audioBuffer = ctx.createBuffer(numChannels, numFrames, sampleRate);
148
+ // ── Decode PCM data into Float32 channel arrays ──
149
+ for (let ch = 0; ch < numChannels; ch++) {
150
+ const channelData = new Float32Array(numFrames);
151
+ for (let i = 0; i < numFrames; i++) {
152
+ const sampleOffset = dataOffset + (i * numChannels + ch) * bytesPerSample;
153
+ let sample;
154
+ if (isFloat && bitsPerSample === 32) {
155
+ // 32-bit IEEE float — already -1..1
156
+ sample = view.getFloat32(sampleOffset, true);
157
+ }
158
+ else if (isFloat && bitsPerSample === 64) {
159
+ // 64-bit IEEE float
160
+ sample = view.getFloat64(sampleOffset, true);
161
+ }
162
+ else if (bitsPerSample === 24) {
163
+ // 24-bit signed little-endian → float
164
+ const b0 = view.getUint8(sampleOffset);
165
+ const b1 = view.getUint8(sampleOffset + 1);
166
+ const b2 = view.getUint8(sampleOffset + 2);
167
+ const raw = b0 | (b1 << 8) | (b2 << 16);
168
+ // Sign extend from 24-bit
169
+ sample = (raw > 0x7FFFFF ? raw - 0x1000000 : raw) / 8388608; // 2^23
170
+ }
171
+ else if (bitsPerSample === 16) {
172
+ // 16-bit signed little-endian → float
173
+ sample = view.getInt16(sampleOffset, true) / 32768; // 2^15
174
+ }
175
+ else {
176
+ throw new Error(`Unsupported bit depth ${bitsPerSample} in ${filePath}`);
177
+ }
178
+ channelData[i] = sample;
179
+ }
180
+ audioBuffer.copyToChannel(channelData, ch);
181
+ }
182
+ return audioBuffer;
183
+ }
184
+ // ── Sample Loading ──
185
+ /** Load all unique sample files referenced by the SFZ regions. */
186
+ function loadSamples() {
187
+ if (!sfzData)
188
+ return;
189
+ const sfzDir = join(samplesDir, sfzProfile);
190
+ const uniqueSamples = new Set();
191
+ for (const r of sfzData.regions) {
192
+ uniqueSamples.add(r.sample);
193
+ }
194
+ console.error(`Loading ${uniqueSamples.size} piano samples...`);
195
+ const startTime = Date.now();
196
+ let loaded = 0;
197
+ for (const samplePath of uniqueSamples) {
198
+ // Resolve relative path from SFZ file location
199
+ const fullPath = join(sfzDir, samplePath);
200
+ try {
201
+ const audioBuffer = parseWavToAudioBuffer(fullPath);
202
+ audioBuffers.set(samplePath, audioBuffer);
203
+ loaded++;
204
+ if (loaded % 50 === 0) {
205
+ console.error(` ${loaded}/${uniqueSamples.size} samples loaded`);
206
+ }
207
+ }
208
+ catch (err) {
209
+ console.error(` SKIP ${samplePath}: ${err instanceof Error ? err.message : String(err)}`);
210
+ }
211
+ }
212
+ const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
213
+ console.error(`Loaded ${loaded}/${uniqueSamples.size} samples in ${elapsed}s`);
214
+ }
215
+ // ── Voice Management ──
216
+ function stealOldest() {
217
+ if (voiceOrder.length === 0)
218
+ return;
219
+ const oldestNote = voiceOrder.shift();
220
+ const voice = activeVoices.get(oldestNote);
221
+ if (voice) {
222
+ killVoice(voice);
223
+ activeVoices.delete(oldestNote);
224
+ }
225
+ }
226
+ function removeFromOrder(note) {
227
+ const idx = voiceOrder.indexOf(note);
228
+ if (idx >= 0)
229
+ voiceOrder.splice(idx, 1);
230
+ }
231
+ function killVoice(voice) {
232
+ if (voice.cleanupTimer) {
233
+ clearTimeout(voice.cleanupTimer);
234
+ voice.cleanupTimer = null;
235
+ }
236
+ try {
237
+ voice.source.stop();
238
+ }
239
+ catch { /* already stopped */ }
240
+ try {
241
+ voice.source.disconnect();
242
+ }
243
+ catch { /* ok */ }
244
+ try {
245
+ voice.gain.disconnect();
246
+ }
247
+ catch { /* ok */ }
248
+ try {
249
+ voice.panner.disconnect();
250
+ }
251
+ catch { /* ok */ }
252
+ }
253
+ function releaseVoice(voice) {
254
+ if (voice.released)
255
+ return;
256
+ voice.released = true;
257
+ const now = ctx.currentTime;
258
+ const releaseTime = sfzData?.ampegRelease ?? 1.0;
259
+ // Fade out over release time
260
+ voice.gain.gain.cancelScheduledValues(now);
261
+ voice.gain.gain.setValueAtTime(voice.gain.gain.value, now);
262
+ voice.gain.gain.exponentialRampToValueAtTime(0.001, now + releaseTime);
263
+ // Cleanup after release
264
+ voice.cleanupTimer = setTimeout(() => killVoice(voice), (releaseTime + 0.1) * 1000);
265
+ }
266
+ // ── VmpkConnector Implementation ──
267
+ return {
268
+ async connect() {
269
+ if (currentStatus === "connected")
270
+ return;
271
+ currentStatus = "connecting";
272
+ try {
273
+ // 1. Create audio context
274
+ const AC = await loadAudioContext();
275
+ ctx = new AC({ sampleRate: 48000, latencyHint: "playback" });
276
+ // 2. Master chain: compressor → gain → speakers
277
+ compressor = ctx.createDynamicsCompressor();
278
+ compressor.threshold.value = -12;
279
+ compressor.knee.value = 10;
280
+ compressor.ratio.value = 4;
281
+ compressor.attack.value = 0.003;
282
+ compressor.release.value = 0.25;
283
+ master = ctx.createGain();
284
+ master.gain.value = 0.85;
285
+ compressor.connect(master);
286
+ master.connect(ctx.destination);
287
+ // 3. Parse SFZ
288
+ const sfzFile = join(samplesDir, sfzProfile, sfzProfile === "sfz_minimum"
289
+ ? "Accurate-SalamanderGrandPiano_flat.Recommended.sfz"
290
+ : sfzProfile === "sfz_daw"
291
+ ? "Accurate-SalamanderGrandPiano_flat.Recommended.sfz"
292
+ : "Accurate-SalamanderGrandPiano_flat.Recommended.sfz");
293
+ sfzData = parseSfzFile(sfzFile);
294
+ regionMap = buildRegionMap(sfzData.regions);
295
+ // 4. Load all WAV samples
296
+ loadSamples();
297
+ currentStatus = "connected";
298
+ console.error(`Piano engine connected (sample-based, ${audioBuffers.size} samples)`);
299
+ }
300
+ catch (err) {
301
+ currentStatus = "error";
302
+ throw new Error(`Failed to start sample engine: ${err instanceof Error ? err.message : String(err)}`);
303
+ }
304
+ },
305
+ async disconnect() {
306
+ for (const [, voice] of activeVoices) {
307
+ try {
308
+ killVoice(voice);
309
+ }
310
+ catch { /* ok */ }
311
+ }
312
+ activeVoices.clear();
313
+ voiceOrder.length = 0;
314
+ audioBuffers.clear();
315
+ sfzData = null;
316
+ regionMap = null;
317
+ if (ctx) {
318
+ try {
319
+ await ctx.close();
320
+ }
321
+ catch { /* ok */ }
322
+ ctx = null;
323
+ compressor = null;
324
+ master = null;
325
+ }
326
+ currentStatus = "disconnected";
327
+ },
328
+ status() {
329
+ return currentStatus;
330
+ },
331
+ listPorts() {
332
+ return ["Accurate-Salamander Grand Piano"];
333
+ },
334
+ noteOn(note, velocity, channel) {
335
+ if (!ctx || currentStatus !== "connected" || !regionMap)
336
+ return;
337
+ // Clamp
338
+ velocity = Math.max(1, Math.min(127, velocity));
339
+ note = Math.max(21, Math.min(108, note));
340
+ // Kill existing voice on same note (retrigger)
341
+ const existing = activeVoices.get(note);
342
+ if (existing) {
343
+ killVoice(existing);
344
+ activeVoices.delete(note);
345
+ removeFromOrder(note);
346
+ }
347
+ // Voice stealing
348
+ while (activeVoices.size >= maxPolyphony) {
349
+ stealOldest();
350
+ }
351
+ // Find the right sample
352
+ const region = findRegion(regionMap, note, velocity);
353
+ if (!region)
354
+ return;
355
+ const audioBuffer = audioBuffers.get(region.sample);
356
+ if (!audioBuffer)
357
+ return;
358
+ const now = ctx.currentTime;
359
+ // Create buffer source
360
+ const source = ctx.createBufferSource();
361
+ source.buffer = audioBuffer;
362
+ // Pitch shift: difference between target note and sample's recorded pitch
363
+ const semitoneDiff = note - region.pitchKeycenter;
364
+ const tuneCents = region.tune; // additional fine tuning from SFZ
365
+ const totalCents = semitoneDiff * 100 + tuneCents;
366
+ source.playbackRate.value = centsToRate(totalCents);
367
+ // Volume: SFZ volume offset + velocity scaling
368
+ const velocity01 = velocity / 127;
369
+ const velTrack = (sfzData?.ampVeltrack ?? 97) / 100;
370
+ // SFZ velocity tracking: gain = (1 - velTrack) + velTrack * velocity01
371
+ const velGain = (1 - velTrack) + velTrack * velocity01;
372
+ const volumeGain = dbToGain(region.volume);
373
+ const gain = ctx.createGain();
374
+ gain.gain.value = velGain * volumeGain * 0.5; // 0.5 = headroom factor
375
+ // Stereo position
376
+ const panner = ctx.createStereoPanner();
377
+ panner.pan.value = noteToPan(note);
378
+ // Connect: source → gain → panner → compressor → master → speakers
379
+ source.connect(gain);
380
+ gain.connect(panner);
381
+ panner.connect(compressor);
382
+ source.start(now);
383
+ const voice = {
384
+ note,
385
+ source,
386
+ gain,
387
+ panner,
388
+ released: false,
389
+ cleanupTimer: null,
390
+ };
391
+ activeVoices.set(note, voice);
392
+ voiceOrder.push(note);
393
+ },
394
+ noteOff(note, channel) {
395
+ if (!ctx || currentStatus !== "connected")
396
+ return;
397
+ const voice = activeVoices.get(note);
398
+ if (voice) {
399
+ releaseVoice(voice);
400
+ activeVoices.delete(note);
401
+ removeFromOrder(note);
402
+ }
403
+ },
404
+ allNotesOff(channel) {
405
+ if (!ctx)
406
+ return;
407
+ for (const [, voice] of activeVoices) {
408
+ killVoice(voice);
409
+ }
410
+ activeVoices.clear();
411
+ voiceOrder.length = 0;
412
+ },
413
+ async playNote(midiNote) {
414
+ if (midiNote.note < 0) {
415
+ await sleep(midiNote.durationMs);
416
+ return;
417
+ }
418
+ this.noteOn(midiNote.note, midiNote.velocity, midiNote.channel);
419
+ await sleep(midiNote.durationMs);
420
+ this.noteOff(midiNote.note, midiNote.channel);
421
+ },
422
+ };
423
+ }
424
+ // ─── Helpers ────────────────────────────────────────────────────────────────
425
+ function sleep(ms) {
426
+ return new Promise((resolve) => setTimeout(resolve, ms));
427
+ }
428
+ //# sourceMappingURL=sample-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sample-engine.js","sourceRoot":"","sources":["../src/sample-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { z } from "zod";
2
+ /** Play a song from the built-in library by ID. */
3
+ export declare const LibraryPlaySchema: z.ZodObject<{
4
+ songId: z.ZodString;
5
+ }, z.core.$strip>;
6
+ /** Play a local MIDI file. */
7
+ export declare const FilePlaySchema: z.ZodObject<{
8
+ midiPath: z.ZodString;
9
+ }, z.core.$strip>;
10
+ /** Play a remote MIDI file by URL. */
11
+ export declare const UrlPlaySchema: z.ZodObject<{
12
+ midiUrl: z.ZodString;
13
+ }, z.core.$strip>;
14
+ /**
15
+ * Unified play source — one of: library song, local file, or remote URL.
16
+ */
17
+ export declare const PlaySourceSchema: z.ZodUnion<readonly [z.ZodObject<{
18
+ songId: z.ZodString;
19
+ }, z.core.$strip>, z.ZodObject<{
20
+ midiPath: z.ZodString;
21
+ }, z.core.$strip>, z.ZodObject<{
22
+ midiUrl: z.ZodString;
23
+ }, z.core.$strip>]>;
24
+ /** Infer the TypeScript type. */
25
+ export type PlaySource = z.infer<typeof PlaySourceSchema>;
26
+ /** Shared playback options (apply to all sources). */
27
+ export declare const PlaybackOptionsSchema: z.ZodObject<{
28
+ speed: z.ZodOptional<z.ZodNumber>;
29
+ tempo: z.ZodOptional<z.ZodNumber>;
30
+ mode: z.ZodOptional<z.ZodEnum<{
31
+ full: "full";
32
+ measure: "measure";
33
+ hands: "hands";
34
+ loop: "loop";
35
+ }>>;
36
+ startMeasure: z.ZodOptional<z.ZodNumber>;
37
+ endMeasure: z.ZodOptional<z.ZodNumber>;
38
+ }, z.core.$strip>;
39
+ export type PlaybackOptions = z.infer<typeof PlaybackOptionsSchema>;
40
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,mDAAmD;AACnD,eAAO,MAAM,iBAAiB;;iBAE5B,CAAC;AAEH,8BAA8B;AAC9B,eAAO,MAAM,cAAc;;iBAEzB,CAAC;AAEH,sCAAsC;AACtC,eAAO,MAAM,aAAa;;iBAExB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;mBAI3B,CAAC;AAEH,iCAAiC;AACjC,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,sDAAsD;AACtD,eAAO,MAAM,qBAAqB;;;;;;;;;;;iBAWhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
@@ -0,0 +1,42 @@
1
+ // ─── Playback Schemas ───────────────────────────────────────────────────────
2
+ //
3
+ // Zod schemas for play_song input. Supports three playback sources:
4
+ // 1. songId — play from the built-in song library
5
+ // 2. midiPath — play a local .mid file
6
+ // 3. midiUrl — play a remote .mid file (downloaded on demand)
7
+ // ─────────────────────────────────────────────────────────────────────────────
8
+ import { z } from "zod";
9
+ /** Play a song from the built-in library by ID. */
10
+ export const LibraryPlaySchema = z.object({
11
+ songId: z.string().describe("Song ID from the built-in library (e.g. 'autumn-leaves')"),
12
+ });
13
+ /** Play a local MIDI file. */
14
+ export const FilePlaySchema = z.object({
15
+ midiPath: z.string().describe("Absolute path to a local .mid file"),
16
+ });
17
+ /** Play a remote MIDI file by URL. */
18
+ export const UrlPlaySchema = z.object({
19
+ midiUrl: z.string().url().describe("URL to a .mid file (downloaded on demand)"),
20
+ });
21
+ /**
22
+ * Unified play source — one of: library song, local file, or remote URL.
23
+ */
24
+ export const PlaySourceSchema = z.union([
25
+ LibraryPlaySchema,
26
+ FilePlaySchema,
27
+ UrlPlaySchema,
28
+ ]);
29
+ /** Shared playback options (apply to all sources). */
30
+ export const PlaybackOptionsSchema = z.object({
31
+ speed: z.number().min(0.1).max(4).optional()
32
+ .describe("Speed multiplier (0.5 = half, 1.0 = normal, 2.0 = double)"),
33
+ tempo: z.number().int().min(10).max(400).optional()
34
+ .describe("Override tempo in BPM (10-400)"),
35
+ mode: z.enum(["full", "measure", "hands", "loop"]).optional()
36
+ .describe("Playback mode"),
37
+ startMeasure: z.number().int().min(1).optional()
38
+ .describe("Start measure for loop mode (1-based)"),
39
+ endMeasure: z.number().int().min(1).optional()
40
+ .describe("End measure for loop mode (1-based)"),
41
+ });
42
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,oEAAoE;AACpE,qDAAqD;AACrD,yCAAyC;AACzC,iEAAiE;AACjE,gFAAgF;AAEhF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,mDAAmD;AACnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0DAA0D,CAAC;CACxF,CAAC,CAAC;AAEH,8BAA8B;AAC9B,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;CACpE,CAAC,CAAC;AAEH,sCAAsC;AACtC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;CAChF,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC;IACtC,iBAAiB;IACjB,cAAc;IACd,aAAa;CACd,CAAC,CAAC;AAKH,sDAAsD;AACtD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;SACzC,QAAQ,CAAC,2DAA2D,CAAC;IACxE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;SAChD,QAAQ,CAAC,gCAAgC,CAAC;IAC7C,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;SAC1D,QAAQ,CAAC,eAAe,CAAC;IAC5B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;SAC7C,QAAQ,CAAC,uCAAuC,CAAC;IACpD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;SAC3C,QAAQ,CAAC,qCAAqC,CAAC;CACnD,CAAC,CAAC"}
@@ -0,0 +1,106 @@
1
+ import type { SongEntry } from "./songs/types.js";
2
+ import type { Session, SessionOptions, SessionState, ProgressCallback, ParseWarning, VmpkConnector, TeachingHook } from "./types.js";
3
+ /**
4
+ * Create a new practice session for a song.
5
+ */
6
+ export declare function createSession(song: SongEntry, connector: VmpkConnector, options?: SessionOptions): SessionController;
7
+ /**
8
+ * Session controller — the main runtime interface for a practice session.
9
+ *
10
+ * Holds the session state + connector + teaching hook.
11
+ * Provides play/pause/stop/skip methods.
12
+ */
13
+ export declare class SessionController {
14
+ readonly session: Session;
15
+ private readonly connector;
16
+ private readonly teachingHook;
17
+ private abortController;
18
+ private playableMeasures;
19
+ private playStartedAt;
20
+ private lastProgressMilestone;
21
+ private readonly onProgress?;
22
+ private readonly progressInterval;
23
+ /** Parse warnings collected during measure parsing (bad notes skipped). */
24
+ readonly parseWarnings: ParseWarning[];
25
+ constructor(session: Session, connector: VmpkConnector, teachingHook: TeachingHook, onProgress?: ProgressCallback, progressInterval?: number);
26
+ /**
27
+ * Re-parse all measures with current effective tempo.
28
+ * Uses safe parser — collects warnings instead of throwing.
29
+ */
30
+ private reParseMeasures;
31
+ /**
32
+ * Effective tempo — base tempo (override or song default) * speed multiplier.
33
+ * This is the actual BPM used for playback timing.
34
+ */
35
+ effectiveTempo(): number;
36
+ /**
37
+ * Base tempo — override or song default, without speed multiplier.
38
+ * Useful for display ("Playing at 60 BPM × 0.5 speed").
39
+ */
40
+ baseTempo(): number;
41
+ /** Get current state. */
42
+ get state(): SessionState;
43
+ /** Get the current measure (1-based for display). */
44
+ get currentMeasureDisplay(): number;
45
+ /** Total measures in the song. */
46
+ get totalMeasures(): number;
47
+ /**
48
+ * Play the session from the current position.
49
+ *
50
+ * In "full" mode: plays all remaining measures.
51
+ * In "measure" mode: plays one measure and pauses.
52
+ * In "loop" mode: loops the specified range.
53
+ * In "hands" mode: plays RH, then LH, then both for each measure.
54
+ */
55
+ play(): Promise<void>;
56
+ /** Pause playback. */
57
+ pause(): void;
58
+ /** Stop playback and reset to beginning. */
59
+ stop(): void;
60
+ /** Skip to next measure (in measure/hands mode). */
61
+ next(): void;
62
+ /** Go back to previous measure. */
63
+ prev(): void;
64
+ /** Jump to a specific measure (1-based). */
65
+ goTo(measureNumber: number): void;
66
+ /** Set tempo override (10–400 BPM). */
67
+ setTempo(bpm: number): void;
68
+ /**
69
+ * Set speed multiplier (0.5 = half speed, 1.0 = normal, 2.0 = double).
70
+ * Re-parses all measures with the new effective tempo.
71
+ */
72
+ setSpeed(speed: number): void;
73
+ /** Get a summary of the current session state. */
74
+ summary(): string;
75
+ /** Build a PlaybackProgress snapshot. */
76
+ private buildProgress;
77
+ /**
78
+ * Emit a progress notification if we've crossed the next milestone.
79
+ * With progressInterval 0.1, fires at 10%, 20%, 30%, … 100%.
80
+ * With progressInterval 0, fires after every measure.
81
+ */
82
+ private emitProgress;
83
+ /**
84
+ * Play a range of measures (inclusive, 0-based indices).
85
+ * Fires teaching hooks at measure boundaries and key moments.
86
+ *
87
+ * In "concurrent" syncMode: voice and piano play simultaneously (duet feel).
88
+ * In "before" syncMode: voice speaks before piano plays (lecture style).
89
+ * Key moments always fire before playback in both modes (instructional).
90
+ */
91
+ private playRange;
92
+ /**
93
+ * Play a single measure — both hands in parallel.
94
+ */
95
+ private playMeasure;
96
+ /**
97
+ * Play a sequence of beats serially.
98
+ */
99
+ private playBeats;
100
+ /**
101
+ * Play hands separately then together (for "hands" mode).
102
+ * Respects syncMode: concurrent voice plays alongside the first hand pass.
103
+ */
104
+ private playHandsSeparate;
105
+ }
106
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,YAAY,EAIZ,gBAAgB,EAChB,YAAY,EAEZ,aAAa,EACb,YAAY,EACb,MAAM,YAAY,CAAC;AAMpB;;GAEG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,EACf,SAAS,EAAE,aAAa,EACxB,OAAO,GAAE,cAAmB,GAC3B,iBAAiB,CAgCnB;AAED;;;;;GAKG;AACH,qBAAa,iBAAiB;aAYV,OAAO,EAAE,OAAO;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAb/B,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,qBAAqB,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAmB;IAC/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,2EAA2E;IAC3E,QAAQ,CAAC,aAAa,EAAE,YAAY,EAAE,CAAM;gBAG1B,OAAO,EAAE,OAAO,EACf,SAAS,EAAE,aAAa,EACxB,YAAY,EAAE,YAAY,EAC3C,UAAU,CAAC,EAAE,gBAAgB,EAC7B,gBAAgB,CAAC,EAAE,MAAM;IAS3B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAQvB;;;OAGG;IACH,cAAc,IAAI,MAAM;IAKxB;;;OAGG;IACH,SAAS,IAAI,MAAM;IAInB,yBAAyB;IACzB,IAAI,KAAK,IAAI,YAAY,CAExB;IAED,qDAAqD;IACrD,IAAI,qBAAqB,IAAI,MAAM,CAElC;IAED,kCAAkC;IAClC,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;;;;;;OAOG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsE3B,sBAAsB;IACtB,KAAK,IAAI,IAAI;IAOb,4CAA4C;IAC5C,IAAI,IAAI,IAAI;IAOZ,oDAAoD;IACpD,IAAI,IAAI,IAAI;IAMZ,mCAAmC;IACnC,IAAI,IAAI,IAAI;IAMZ,4CAA4C;IAC5C,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAOjC,uCAAuC;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQ3B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ7B,kDAAkD;IAClD,OAAO,IAAI,MAAM;IAcjB,yCAAyC;IACzC,OAAO,CAAC,aAAa;IAarB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAqBpB;;;;;;;OAOG;YACW,SAAS;IA+CvB;;OAEG;YACW,WAAW;IAWzB;;OAEG;YACW,SAAS;IAavB;;;OAGG;YACW,iBAAiB;CA2ChC"}