@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,319 @@
1
+ // ─── pianoai: Note Parser ────────────────────────────────────────────────────
2
+ //
3
+ // Converts scientific pitch notation (e.g. "C4:q", "F#5:e", "Bb3:h")
4
+ // into MIDI note numbers and durations for playback.
5
+ // ─────────────────────────────────────────────────────────────────────────────
6
+ import { NOTE_OFFSETS, DURATION_MAP } from "./types.js";
7
+ /**
8
+ * Parse a scientific pitch string into a MIDI note number.
9
+ *
10
+ * Examples:
11
+ * "C4" → 60 (middle C)
12
+ * "A4" → 69 (concert A)
13
+ * "F#5" → 78
14
+ * "Bb3" → 58
15
+ * "R" → -1 (rest)
16
+ */
17
+ export function parseNoteToMidi(noteStr) {
18
+ const trimmed = noteStr.trim();
19
+ if (trimmed === "R" || trimmed === "r")
20
+ return -1; // rest
21
+ // Match: letter + optional accidental + octave
22
+ // e.g. "C4", "F#5", "Bb3", "G#4"
23
+ const match = trimmed.match(/^([A-Ga-g])(#|b)?(\d)$/);
24
+ if (!match) {
25
+ throw new Error(`Invalid note: "${noteStr}"`);
26
+ }
27
+ const [, letter, accidental, octaveStr] = match;
28
+ const base = NOTE_OFFSETS[letter.toUpperCase()];
29
+ if (base === undefined) {
30
+ throw new Error(`Unknown note letter: "${letter}"`);
31
+ }
32
+ const octave = parseInt(octaveStr, 10);
33
+ let midi = (octave + 1) * 12 + base;
34
+ if (accidental === "#")
35
+ midi += 1;
36
+ if (accidental === "b")
37
+ midi -= 1;
38
+ if (midi < 0 || midi > 127) {
39
+ throw new Error(`MIDI note out of range: ${midi} (from "${noteStr}")`);
40
+ }
41
+ return midi;
42
+ }
43
+ /**
44
+ * Parse a duration suffix into a multiplier relative to a quarter note.
45
+ *
46
+ * ":w" → 4.0 (whole), ":h" → 2.0 (half), ":q" → 1.0 (quarter),
47
+ * ":e" → 0.5 (eighth), ":s" → 0.25 (sixteenth).
48
+ * Default (no suffix) → 1.0 (quarter).
49
+ */
50
+ export function parseDuration(suffix) {
51
+ const mult = DURATION_MAP[suffix];
52
+ if (mult === undefined) {
53
+ throw new Error(`Unknown duration suffix: "${suffix}"`);
54
+ }
55
+ return mult;
56
+ }
57
+ /**
58
+ * Convert a BPM tempo + duration multiplier → milliseconds.
59
+ *
60
+ * At 120 BPM, a quarter note = 500ms.
61
+ * A half note at 120 BPM = 1000ms.
62
+ */
63
+ export function durationToMs(multiplier, bpm) {
64
+ const quarterMs = 60_000 / bpm;
65
+ return quarterMs * multiplier;
66
+ }
67
+ /**
68
+ * Parse a single note token like "C4:q" or "R:h" into a MidiNote.
69
+ *
70
+ * @param token - e.g. "C4:q", "F#5:e", "Bb3:h", "R:q"
71
+ * @param bpm - tempo in beats per minute
72
+ * @param channel - MIDI channel (0-15)
73
+ * @param velocity - MIDI velocity (0-127)
74
+ */
75
+ export function parseNoteToken(token, bpm, channel = 0, velocity = 80) {
76
+ const trimmed = token.trim();
77
+ const parts = trimmed.split(":");
78
+ const noteStr = parts[0];
79
+ const durationSuffix = parts[1] ?? "q"; // default to quarter note
80
+ const midi = parseNoteToMidi(noteStr);
81
+ const mult = parseDuration(durationSuffix);
82
+ const durationMs = durationToMs(mult, bpm);
83
+ return {
84
+ note: midi,
85
+ velocity: midi === -1 ? 0 : velocity, // rests have 0 velocity
86
+ durationMs,
87
+ channel,
88
+ };
89
+ }
90
+ /**
91
+ * Parse a hand string like "C4:q E4:q G4:q" into an array of Beats.
92
+ *
93
+ * Each space-separated token becomes a sequential beat.
94
+ * Chords use "+" to join simultaneous notes: "C4+E4+G4:q"
95
+ * The duration suffix on the last note applies to all chord tones.
96
+ */
97
+ export function parseHandString(handStr, hand, bpm, channel = 0, velocity = 80) {
98
+ if (!handStr || handStr.trim() === "")
99
+ return [];
100
+ const tokens = handStr.trim().split(/\s+/);
101
+ return tokens.map((token) => {
102
+ if (token.includes("+")) {
103
+ return parseChordToken(token, hand, bpm, channel, velocity);
104
+ }
105
+ return {
106
+ notes: [parseNoteToken(token, bpm, channel, velocity)],
107
+ hand,
108
+ };
109
+ });
110
+ }
111
+ /**
112
+ * Parse a chord token like "C4+E4+G4:q" into a Beat with multiple notes.
113
+ * The duration suffix from the last sub-token applies to all notes.
114
+ */
115
+ function parseChordToken(token, hand, bpm, channel, velocity) {
116
+ const parts = token.split("+");
117
+ // Find the duration from the part that has one (last part has ":dur")
118
+ let sharedDuration = "q";
119
+ for (const part of parts) {
120
+ if (part.includes(":")) {
121
+ sharedDuration = part.split(":")[1];
122
+ }
123
+ }
124
+ const notes = parts.map((part) => {
125
+ if (part.includes(":")) {
126
+ return parseNoteToken(part, bpm, channel, velocity);
127
+ }
128
+ return parseNoteToken(`${part}:${sharedDuration}`, bpm, channel, velocity);
129
+ });
130
+ return { notes, hand };
131
+ }
132
+ /**
133
+ * Parse a full Measure into a PlayableMeasure with MIDI-ready beats.
134
+ */
135
+ export function parseMeasure(measure, bpm, velocity = 80) {
136
+ return {
137
+ source: measure,
138
+ rightBeats: parseHandString(measure.rightHand, "right", bpm, 0, velocity),
139
+ leftBeats: parseHandString(measure.leftHand, "left", bpm, 0, velocity),
140
+ };
141
+ }
142
+ /**
143
+ * Safely parse a note token — returns null on error instead of throwing.
144
+ * Collects a warning in the provided array when parsing fails.
145
+ */
146
+ export function safeParseNoteToken(token, bpm, location, warnings, channel = 0, velocity = 80) {
147
+ try {
148
+ return parseNoteToken(token, bpm, channel, velocity);
149
+ }
150
+ catch (err) {
151
+ warnings.push({
152
+ location,
153
+ token,
154
+ message: err instanceof Error ? err.message : String(err),
155
+ });
156
+ return null;
157
+ }
158
+ }
159
+ /**
160
+ * Safe version of parseHandString — skips bad tokens, collects warnings.
161
+ */
162
+ export function safeParseHandString(handStr, hand, bpm, measureNumber, warnings, channel = 0, velocity = 80) {
163
+ if (!handStr || handStr.trim() === "")
164
+ return [];
165
+ const tokens = handStr.trim().split(/\s+/);
166
+ const beats = [];
167
+ for (const token of tokens) {
168
+ if (token.includes("+")) {
169
+ // Chord token — parse each sub-note
170
+ try {
171
+ beats.push(parseChordToken(token, hand, bpm, channel, velocity));
172
+ }
173
+ catch (err) {
174
+ warnings.push({
175
+ location: `measure ${measureNumber} ${hand} hand`,
176
+ token,
177
+ message: err instanceof Error ? err.message : String(err),
178
+ });
179
+ }
180
+ }
181
+ else {
182
+ const note = safeParseNoteToken(token, bpm, `measure ${measureNumber} ${hand} hand`, warnings, channel, velocity);
183
+ if (note) {
184
+ beats.push({ notes: [note], hand });
185
+ }
186
+ }
187
+ }
188
+ return beats;
189
+ }
190
+ /**
191
+ * Safe version of parseMeasure — skips bad notes, collects warnings.
192
+ */
193
+ export function safeParseMeasure(measure, bpm, warnings, velocity = 80) {
194
+ return {
195
+ source: measure,
196
+ rightBeats: safeParseHandString(measure.rightHand, "right", bpm, measure.number, warnings, 0, velocity),
197
+ leftBeats: safeParseHandString(measure.leftHand, "left", bpm, measure.number, warnings, 0, velocity),
198
+ };
199
+ }
200
+ /**
201
+ * Convert a MIDI note number back to a note name (for display).
202
+ *
203
+ * 60 → "C4", 69 → "A4", 78 → "F#5"
204
+ */
205
+ export function midiToNoteName(midi) {
206
+ if (midi < 0)
207
+ return "R";
208
+ const noteNames = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
209
+ const octave = Math.floor(midi / 12) - 1;
210
+ const noteIndex = midi % 12;
211
+ return `${noteNames[noteIndex]}${octave}`;
212
+ }
213
+ /** Solfege mapping: note name (with optional accidental) → solfege syllable. */
214
+ const SOLFEGE_MAP = {
215
+ C: "Do", "C#": "Di", Db: "Ra",
216
+ D: "Re", "D#": "Ri", Eb: "Me",
217
+ E: "Mi",
218
+ F: "Fa", "F#": "Fi", Gb: "Se",
219
+ G: "Sol", "G#": "Si", Ab: "Le",
220
+ A: "La", "A#": "Li", Bb: "Te",
221
+ B: "Ti",
222
+ };
223
+ /**
224
+ * Convert a single note string (e.g. "C4", "F#5") to a singable syllable.
225
+ *
226
+ * - "note-names": "C", "F sharp", "B flat"
227
+ * - "solfege": "Do", "Fi", "Te"
228
+ * - "syllables": always "da"
229
+ * - "contour": falls back to letter (contour handled at measure level)
230
+ */
231
+ export function noteToSingable(noteStr, mode) {
232
+ const trimmed = noteStr.trim();
233
+ if (trimmed === "R" || trimmed === "r")
234
+ return mode === "syllables" ? "..." : "rest";
235
+ const match = trimmed.match(/^([A-Ga-g])(#|b)?(\d)?$/);
236
+ if (!match)
237
+ return trimmed; // pass through unparseable
238
+ const [, letter, accidental] = match;
239
+ const upperLetter = letter.toUpperCase();
240
+ switch (mode) {
241
+ case "note-names": {
242
+ const acc = accidental === "#" ? " sharp" : accidental === "b" ? " flat" : "";
243
+ return `${upperLetter}${acc}`;
244
+ }
245
+ case "solfege": {
246
+ const key = accidental ? `${upperLetter}${accidental}` : upperLetter;
247
+ return SOLFEGE_MAP[key] ?? upperLetter;
248
+ }
249
+ case "syllables":
250
+ return "da";
251
+ case "contour":
252
+ return upperLetter; // fallback — contour handled at measure level
253
+ }
254
+ }
255
+ /**
256
+ * Convert a hand string (e.g. "C4:q E4:q G4:q") to singable text.
257
+ *
258
+ * For "contour" mode, compares consecutive MIDI pitches and returns
259
+ * direction words: "up", "down", "same".
260
+ *
261
+ * For other modes, maps each note token through noteToSingable and
262
+ * joins with "... " (speech pause).
263
+ */
264
+ export function handToSingableText(handStr, mode) {
265
+ if (!handStr || handStr.trim() === "")
266
+ return "";
267
+ const tokens = handStr.trim().split(/\s+/);
268
+ if (mode === "contour") {
269
+ if (tokens.length <= 1)
270
+ return "hold";
271
+ const midis = tokens.map((t) => {
272
+ const noteStr = t.split(":")[0];
273
+ try {
274
+ return parseNoteToMidi(noteStr);
275
+ }
276
+ catch {
277
+ return -1;
278
+ }
279
+ });
280
+ const dirs = [];
281
+ for (let i = 1; i < midis.length; i++) {
282
+ if (midis[i] < 0 || midis[i - 1] < 0) {
283
+ dirs.push("rest");
284
+ continue;
285
+ }
286
+ const diff = midis[i] - midis[i - 1];
287
+ dirs.push(diff > 0 ? "up" : diff < 0 ? "down" : "same");
288
+ }
289
+ return dirs.join("... ");
290
+ }
291
+ // note-names, solfege, syllables
292
+ const syllables = tokens.map((t) => {
293
+ const noteStr = t.split(":")[0];
294
+ return noteToSingable(noteStr, mode);
295
+ });
296
+ return syllables.join("... ");
297
+ }
298
+ /**
299
+ * Convert a Measure to singable text for voice narration.
300
+ *
301
+ * Returns the singable syllables for the specified hand(s).
302
+ * When hand="both", right hand text comes first, then "Left hand:" prefix.
303
+ */
304
+ export function measureToSingableText(measure, options) {
305
+ const { mode, hand } = options;
306
+ if (hand === "right")
307
+ return handToSingableText(measure.rightHand, mode);
308
+ if (hand === "left")
309
+ return handToSingableText(measure.leftHand, mode);
310
+ // both
311
+ const right = handToSingableText(measure.rightHand, mode);
312
+ const left = handToSingableText(measure.leftHand, mode);
313
+ if (!left)
314
+ return right;
315
+ if (!right)
316
+ return left;
317
+ return `${right}. Left hand: ${left}`;
318
+ }
319
+ //# sourceMappingURL=note-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"note-parser.js","sourceRoot":"","sources":["../src/note-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { SongEntry } from "./songs/types.js";
2
+ export type PianoRollColorMode = "hand" | "pitch-class";
3
+ export interface PianoRollOptions {
4
+ /** First measure to render (1-based). Default: 1 */
5
+ startMeasure?: number;
6
+ /** Last measure to render (1-based). Default: last measure */
7
+ endMeasure?: number;
8
+ /** Horizontal pixels per beat. Default: 60 */
9
+ pixelsPerBeat?: number;
10
+ /** Vertical pixels per semitone row. Default: 10 */
11
+ pitchRowHeight?: number;
12
+ /** Show metronome dots on downbeats. Default: true */
13
+ showMetronome?: boolean;
14
+ /** Show dynamics markings. Default: true */
15
+ showDynamics?: boolean;
16
+ /** Show measure teaching notes as tooltip titles. Default: false */
17
+ showTeachingNotes?: boolean;
18
+ /** Note coloring mode. Default: "hand" (blue RH / coral LH). */
19
+ colorMode?: PianoRollColorMode;
20
+ }
21
+ /**
22
+ * Render a SongEntry as an SVG piano roll string.
23
+ *
24
+ * Returns a complete SVG document as a string — no file I/O,
25
+ * no DOM, no external dependencies.
26
+ */
27
+ export declare function renderPianoRoll(song: SongEntry, options?: PianoRollOptions): string;
28
+ //# sourceMappingURL=piano-roll.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"piano-roll.d.ts","sourceRoot":"","sources":["../src/piano-roll.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAW,MAAM,kBAAkB,CAAC;AAI3D,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,aAAa,CAAC;AAExD,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gEAAgE;IAChE,SAAS,CAAC,EAAE,kBAAkB,CAAC;CAChC;AA2ID;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,EACf,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,CAwNR"}