@mcptoolshop/ai_jam_session 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 (246) hide show
  1. package/LICENSE +21 -0
  2. package/README.es.md +212 -0
  3. package/README.fr.md +212 -0
  4. package/README.hi.md +212 -0
  5. package/README.it.md +212 -0
  6. package/README.ja.md +214 -0
  7. package/README.md +214 -0
  8. package/README.pt-BR.md +212 -0
  9. package/dist/audio-engine.d.ts +9 -0
  10. package/dist/audio-engine.d.ts.map +1 -0
  11. package/dist/audio-engine.js +422 -0
  12. package/dist/audio-engine.js.map +1 -0
  13. package/dist/cli.d.ts +3 -0
  14. package/dist/cli.d.ts.map +1 -0
  15. package/dist/cli.js +551 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/index.d.ts +32 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +41 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/mcp-server.d.ts +3 -0
  22. package/dist/mcp-server.d.ts.map +1 -0
  23. package/dist/mcp-server.js +903 -0
  24. package/dist/mcp-server.js.map +1 -0
  25. package/dist/midi/parser.d.ts +16 -0
  26. package/dist/midi/parser.d.ts.map +1 -0
  27. package/dist/midi/parser.js +192 -0
  28. package/dist/midi/parser.js.map +1 -0
  29. package/dist/midi/types.d.ts +44 -0
  30. package/dist/midi/types.d.ts.map +1 -0
  31. package/dist/midi/types.js +8 -0
  32. package/dist/midi/types.js.map +1 -0
  33. package/dist/note-parser.d.ts +105 -0
  34. package/dist/note-parser.d.ts.map +1 -0
  35. package/dist/note-parser.js +278 -0
  36. package/dist/note-parser.js.map +1 -0
  37. package/dist/playback/controls.d.ts +124 -0
  38. package/dist/playback/controls.d.ts.map +1 -0
  39. package/dist/playback/controls.js +252 -0
  40. package/dist/playback/controls.js.map +1 -0
  41. package/dist/playback/midi-engine.d.ts +68 -0
  42. package/dist/playback/midi-engine.d.ts.map +1 -0
  43. package/dist/playback/midi-engine.js +227 -0
  44. package/dist/playback/midi-engine.js.map +1 -0
  45. package/dist/playback/position.d.ts +95 -0
  46. package/dist/playback/position.d.ts.map +1 -0
  47. package/dist/playback/position.js +223 -0
  48. package/dist/playback/position.js.map +1 -0
  49. package/dist/playback/timing.d.ts +31 -0
  50. package/dist/playback/timing.d.ts.map +1 -0
  51. package/dist/playback/timing.js +57 -0
  52. package/dist/playback/timing.js.map +1 -0
  53. package/dist/sample-engine.d.ts +17 -0
  54. package/dist/sample-engine.d.ts.map +1 -0
  55. package/dist/sample-engine.js +428 -0
  56. package/dist/sample-engine.js.map +1 -0
  57. package/dist/schemas.d.ts +40 -0
  58. package/dist/schemas.d.ts.map +1 -0
  59. package/dist/schemas.js +42 -0
  60. package/dist/schemas.js.map +1 -0
  61. package/dist/session.d.ts +106 -0
  62. package/dist/session.d.ts.map +1 -0
  63. package/dist/session.js +361 -0
  64. package/dist/session.js.map +1 -0
  65. package/dist/sfz-parser.d.ts +36 -0
  66. package/dist/sfz-parser.d.ts.map +1 -0
  67. package/dist/sfz-parser.js +95 -0
  68. package/dist/sfz-parser.js.map +1 -0
  69. package/dist/smoke.d.ts +2 -0
  70. package/dist/smoke.d.ts.map +1 -0
  71. package/dist/smoke.js +512 -0
  72. package/dist/smoke.js.map +1 -0
  73. package/dist/songs/config/loader.d.ts +14 -0
  74. package/dist/songs/config/loader.d.ts.map +1 -0
  75. package/dist/songs/config/loader.js +53 -0
  76. package/dist/songs/config/loader.js.map +1 -0
  77. package/dist/songs/config/schema.d.ts +70 -0
  78. package/dist/songs/config/schema.d.ts.map +1 -0
  79. package/dist/songs/config/schema.js +53 -0
  80. package/dist/songs/config/schema.js.map +1 -0
  81. package/dist/songs/index.d.ts +16 -0
  82. package/dist/songs/index.d.ts.map +1 -0
  83. package/dist/songs/index.js +20 -0
  84. package/dist/songs/index.js.map +1 -0
  85. package/dist/songs/jam.d.ts +48 -0
  86. package/dist/songs/jam.d.ts.map +1 -0
  87. package/dist/songs/jam.js +324 -0
  88. package/dist/songs/jam.js.map +1 -0
  89. package/dist/songs/loader.d.ts +27 -0
  90. package/dist/songs/loader.d.ts.map +1 -0
  91. package/dist/songs/loader.js +90 -0
  92. package/dist/songs/loader.js.map +1 -0
  93. package/dist/songs/midi/hands.d.ts +46 -0
  94. package/dist/songs/midi/hands.d.ts.map +1 -0
  95. package/dist/songs/midi/hands.js +134 -0
  96. package/dist/songs/midi/hands.js.map +1 -0
  97. package/dist/songs/midi/ingest.d.ts +8 -0
  98. package/dist/songs/midi/ingest.d.ts.map +1 -0
  99. package/dist/songs/midi/ingest.js +191 -0
  100. package/dist/songs/midi/ingest.js.map +1 -0
  101. package/dist/songs/midi/measures.d.ts +41 -0
  102. package/dist/songs/midi/measures.d.ts.map +1 -0
  103. package/dist/songs/midi/measures.js +64 -0
  104. package/dist/songs/midi/measures.js.map +1 -0
  105. package/dist/songs/midi/types.d.ts +25 -0
  106. package/dist/songs/midi/types.d.ts.map +1 -0
  107. package/dist/songs/midi/types.js +8 -0
  108. package/dist/songs/midi/types.js.map +1 -0
  109. package/dist/songs/registry.d.ts +37 -0
  110. package/dist/songs/registry.d.ts.map +1 -0
  111. package/dist/songs/registry.js +197 -0
  112. package/dist/songs/registry.js.map +1 -0
  113. package/dist/songs/types.d.ts +99 -0
  114. package/dist/songs/types.d.ts.map +1 -0
  115. package/dist/songs/types.js +27 -0
  116. package/dist/songs/types.js.map +1 -0
  117. package/dist/teaching/live-midi-feedback.d.ts +36 -0
  118. package/dist/teaching/live-midi-feedback.d.ts.map +1 -0
  119. package/dist/teaching/live-midi-feedback.js +259 -0
  120. package/dist/teaching/live-midi-feedback.js.map +1 -0
  121. package/dist/teaching/midi-feedback.d.ts +33 -0
  122. package/dist/teaching/midi-feedback.d.ts.map +1 -0
  123. package/dist/teaching/midi-feedback.js +208 -0
  124. package/dist/teaching/midi-feedback.js.map +1 -0
  125. package/dist/teaching/sing-on-midi.d.ts +77 -0
  126. package/dist/teaching/sing-on-midi.d.ts.map +1 -0
  127. package/dist/teaching/sing-on-midi.js +186 -0
  128. package/dist/teaching/sing-on-midi.js.map +1 -0
  129. package/dist/teaching.d.ts +148 -0
  130. package/dist/teaching.d.ts.map +1 -0
  131. package/dist/teaching.js +453 -0
  132. package/dist/teaching.js.map +1 -0
  133. package/dist/test-sound.d.ts +3 -0
  134. package/dist/test-sound.d.ts.map +1 -0
  135. package/dist/test-sound.js +41 -0
  136. package/dist/test-sound.js.map +1 -0
  137. package/dist/types.d.ts +229 -0
  138. package/dist/types.d.ts.map +1 -0
  139. package/dist/types.js +22 -0
  140. package/dist/types.js.map +1 -0
  141. package/dist/vmpk.d.ts +23 -0
  142. package/dist/vmpk.d.ts.map +1 -0
  143. package/dist/vmpk.js +236 -0
  144. package/dist/vmpk.js.map +1 -0
  145. package/logo.png +0 -0
  146. package/package.json +70 -0
  147. package/songs/builtin/a-change-is-gonna-come.json +95 -0
  148. package/songs/builtin/a-thousand-years.json +93 -0
  149. package/songs/builtin/aint-no-sunshine.json +98 -0
  150. package/songs/builtin/all-blues.json +92 -0
  151. package/songs/builtin/autumn-leaves.json +100 -0
  152. package/songs/builtin/baba-oriley.json +91 -0
  153. package/songs/builtin/bach-invention-no1.json +70 -0
  154. package/songs/builtin/bach-prelude-c-major-bwv846.json +1282 -0
  155. package/songs/builtin/basic-12-bar-blues.json +119 -0
  156. package/songs/builtin/beethoven-waldstein-mvt1.json +7766 -0
  157. package/songs/builtin/bennie-and-the-jets.json +92 -0
  158. package/songs/builtin/besame-mucho.json +93 -0
  159. package/songs/builtin/black-orpheus.json +92 -0
  160. package/songs/builtin/blue-bossa.json +94 -0
  161. package/songs/builtin/blues-in-g.json +92 -0
  162. package/songs/builtin/bohemian-rhapsody-intro.json +94 -0
  163. package/songs/builtin/boogie-woogie-basics.json +93 -0
  164. package/songs/builtin/bossa-nova-basic.json +95 -0
  165. package/songs/builtin/chopin-nocturne-op9-no2.json +70 -0
  166. package/songs/builtin/cinema-paradiso.json +94 -0
  167. package/songs/builtin/clair-de-lune.json +11511 -0
  168. package/songs/builtin/clocks.json +91 -0
  169. package/songs/builtin/crystal-stream.json +70 -0
  170. package/songs/builtin/desafinado.json +93 -0
  171. package/songs/builtin/dont-stop-believin.json +91 -0
  172. package/songs/builtin/dream-on.json +100 -0
  173. package/songs/builtin/easy-winners.json +70 -0
  174. package/songs/builtin/el-condor-pasa.json +93 -0
  175. package/songs/builtin/elite-syncopations.json +70 -0
  176. package/songs/builtin/evening-calm.json +70 -0
  177. package/songs/builtin/everyday-blues.json +93 -0
  178. package/songs/builtin/fly-me-to-the-moon.json +91 -0
  179. package/songs/builtin/forrest-gump-suite.json +93 -0
  180. package/songs/builtin/fur-elise.json +20094 -0
  181. package/songs/builtin/georgia-on-my-mind.json +93 -0
  182. package/songs/builtin/girl-from-ipanema.json +92 -0
  183. package/songs/builtin/gladiolus-rag.json +70 -0
  184. package/songs/builtin/great-balls-of-fire.json +92 -0
  185. package/songs/builtin/guantanamera.json +92 -0
  186. package/songs/builtin/hallelujah.json +92 -0
  187. package/songs/builtin/hedwigs-theme.json +93 -0
  188. package/songs/builtin/hotel-california.json +92 -0
  189. package/songs/builtin/imagine.json +92 -0
  190. package/songs/builtin/just-the-two-of-us.json +92 -0
  191. package/songs/builtin/la-bamba.json +92 -0
  192. package/songs/builtin/layla-piano-coda.json +93 -0
  193. package/songs/builtin/lean-on-me.json +91 -0
  194. package/songs/builtin/let-it-be.json +101 -0
  195. package/songs/builtin/lets-stay-together.json +93 -0
  196. package/songs/builtin/magnetic-rag.json +70 -0
  197. package/songs/builtin/maple-leaf-rag.json +99 -0
  198. package/songs/builtin/mia-and-sebastians-theme.json +93 -0
  199. package/songs/builtin/minor-blues-in-a.json +94 -0
  200. package/songs/builtin/misty.json +94 -0
  201. package/songs/builtin/moon-river.json +93 -0
  202. package/songs/builtin/moonlight-sonata-mvt1.json +101 -0
  203. package/songs/builtin/morning-light.json +70 -0
  204. package/songs/builtin/mountain-dawn.json +70 -0
  205. package/songs/builtin/mozart-k545-mvt1.json +2956 -0
  206. package/songs/builtin/my-girl.json +92 -0
  207. package/songs/builtin/night-train.json +92 -0
  208. package/songs/builtin/november-rain.json +93 -0
  209. package/songs/builtin/ocean-waves.json +70 -0
  210. package/songs/builtin/over-the-rainbow.json +93 -0
  211. package/songs/builtin/oye-como-va.json +93 -0
  212. package/songs/builtin/peacherine-rag.json +70 -0
  213. package/songs/builtin/piano-man.json +92 -0
  214. package/songs/builtin/pineapple-rag.json +70 -0
  215. package/songs/builtin/pink-panther.json +94 -0
  216. package/songs/builtin/ragtime-dance.json +70 -0
  217. package/songs/builtin/river-flows-in-you.json +102 -0
  218. package/songs/builtin/rocket-man.json +92 -0
  219. package/songs/builtin/satie-gymnopedie-no1.json +70 -0
  220. package/songs/builtin/satin-doll.json +93 -0
  221. package/songs/builtin/schindlers-list.json +96 -0
  222. package/songs/builtin/schumann-traumerei.json +70 -0
  223. package/songs/builtin/sitting-on-the-dock.json +91 -0
  224. package/songs/builtin/slow-blues-in-bb.json +98 -0
  225. package/songs/builtin/snowfall.json +70 -0
  226. package/songs/builtin/so-what.json +92 -0
  227. package/songs/builtin/solace.json +70 -0
  228. package/songs/builtin/someone-like-you.json +92 -0
  229. package/songs/builtin/spirited-away.json +94 -0
  230. package/songs/builtin/st-louis-blues.json +93 -0
  231. package/songs/builtin/stairway-intro.json +93 -0
  232. package/songs/builtin/starlight-waltz.json +70 -0
  233. package/songs/builtin/stay-with-me.json +93 -0
  234. package/songs/builtin/stormy-monday.json +94 -0
  235. package/songs/builtin/superstition.json +93 -0
  236. package/songs/builtin/sweet-home-chicago.json +93 -0
  237. package/songs/builtin/take-five.json +92 -0
  238. package/songs/builtin/take-the-a-train.json +93 -0
  239. package/songs/builtin/the-entertainer.json +98 -0
  240. package/songs/builtin/the-godfather-waltz.json +93 -0
  241. package/songs/builtin/thrill-is-gone.json +94 -0
  242. package/songs/builtin/twilight-garden.json +70 -0
  243. package/songs/builtin/watermark.json +70 -0
  244. package/songs/builtin/wave.json +93 -0
  245. package/songs/builtin/whats-going-on.json +93 -0
  246. package/songs/builtin/yesterday.json +92 -0
@@ -0,0 +1,212 @@
1
+ <p align="center"><a href="README.md">English</a> | <a href="README.ja.md">日本語</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <strong>Português</strong></p>
2
+
3
+ <p align="center">
4
+ <img src="logo.png" alt="Logo do PianoAI" width="180" />
5
+ </p>
6
+
7
+ <h1 align="center">PianoAI</h1>
8
+
9
+ <p align="center">
10
+ Piano com IA com motor de audio integrado e biblioteca de 100 musicas. Servidor MCP para o Claude, CLI para humanos.
11
+ </p>
12
+
13
+ [![MCP Tools](https://img.shields.io/badge/MCP_tools-15-purple)](https://github.com/mcp-tool-shop-org/ai_jam_session)
14
+ [![Songs](https://img.shields.io/badge/songs-100_built--in-blue)](https://github.com/mcp-tool-shop-org/ai_jam_session)
15
+ [![Tests](https://img.shields.io/badge/tests-passing-brightgreen)](https://github.com/mcp-tool-shop-org/ai_jam_session)
16
+
17
+ ## O que e isto?
18
+
19
+ Um piano que o Claude consegue tocar. PianoAI e um servidor MCP com motor de audio integrado — toca diretamente pelas suas caixas de som, sem necessidade de software externo. O Claude navega por uma biblioteca de 100 musicas em 10 generos, escolhe musicas, ensina e improvisa sobre elas. Tambem funciona como CLI independente.
20
+
21
+ ## Funcionalidades
22
+
23
+ - **Motor de piano integrado** — audio baseado em amostras via `node-web-audio-api`, toca pelas caixas de som
24
+ - **Biblioteca de 100 musicas** — classico, jazz, pop, blues, rock, R&B, latin, cinema, ragtime, new-age
25
+ - **AI Jam Session** — o Claude analisa os acordes e a melodia de uma musica e cria a sua propria interpretacao
26
+ - **Suporte a arquivos MIDI** — toque qualquer arquivo `.mid`: `pianoai play song.mid`
27
+ - **Sistema de ensino** — notas de ensino por compasso, descricoes em linguagem musical, recomendacoes de pratica
28
+ - **4 modos de reproducao** — completo, compasso a compasso, maos separadas, loop
29
+ - **Controle de velocidade** — 0.5x para pratica lenta ate 4x rapido
30
+ - **Controles em tempo real** — pausar, retomar, alterar velocidade durante a reproducao
31
+ - **15 ferramentas MCP** — tocar, navegar, ensinar, improvisar, importar — tudo pelo protocolo MCP
32
+ - **Adicione suas proprias musicas** — a ferramenta `add_song` aceita JSON SongEntry, `import_midi` converte arquivos MIDI
33
+ - **Saida MIDI opcional** — encaminhe para software externo via flag `--midi` (requer loopMIDI + VMPK)
34
+
35
+ ## Instalacao
36
+
37
+ ```bash
38
+ npm install -g @mcptoolshop/ai_jam_session
39
+ ```
40
+
41
+ Requer **Node.js 18+**. So isso — sem drivers MIDI, sem portas virtuais, sem software externo.
42
+
43
+ ## Inicio Rapido
44
+
45
+ ```bash
46
+ # Tocar uma musica da biblioteca
47
+ ai-jam-session play let-it-be
48
+
49
+ # Tocar um arquivo MIDI
50
+ ai-jam-session play path/to/song.mid
51
+
52
+ # Pratica em meia velocidade
53
+ ai-jam-session play moonlight-sonata-mvt1 --speed 0.5
54
+
55
+ # Listar todas as musicas da biblioteca
56
+ ai-jam-session list
57
+
58
+ # Mostrar detalhes da musica + notas de ensino
59
+ ai-jam-session info autumn-leaves
60
+ ```
61
+
62
+ ### Opcoes de Reproducao
63
+
64
+ | Flag | Descricao |
65
+ |------|-----------|
66
+ | `--speed <mult>` | Multiplicador de velocidade: 0.5 = metade, 1.0 = normal, 2.0 = dobro |
67
+ | `--tempo <bpm>` | Substituir o andamento padrao da musica (10-400 BPM) |
68
+ | `--mode <mode>` | Modo de reproducao: `full`, `measure`, `hands`, `loop` |
69
+ | `--midi` | Encaminhar para software MIDI externo em vez do motor integrado |
70
+
71
+ ## Servidor MCP
72
+
73
+ O servidor MCP disponibiliza 15 ferramentas para integracao com LLMs:
74
+
75
+ | Ferramenta | Descricao |
76
+ |------------|-----------|
77
+ | `list_songs` | Navegar/buscar musicas por genero, dificuldade ou consulta |
78
+ | `song_info` | Linguagem musical completa, objetivos de ensino, sugestoes de pratica |
79
+ | `registry_stats` | Contagem de musicas por genero e dificuldade |
80
+ | `teaching_note` | Nota de ensino por compasso, dedilhado, dinamica |
81
+ | `suggest_song` | Recomendacao baseada em criterios |
82
+ | `list_measures` | Visao geral dos compassos com notas de ensino |
83
+ | `practice_setup` | Sugerir velocidade, modo e configuracoes para uma musica |
84
+ | `sing_along` | Texto cantavel (nomes de notas, solfejo, contorno) por compasso |
85
+ | `play_song` | Tocar uma musica ou arquivo MIDI pelas caixas de som |
86
+ | `pause_playback` | Pausar ou retomar a musica em reproducao |
87
+ | `set_speed` | Alterar a velocidade durante a reproducao |
88
+ | `stop_playback` | Parar a musica em reproducao |
89
+ | `ai_jam_session` | Obter um resumo para jam — acordes, melodia, orientacao de estilo — para improvisacao |
90
+ | `add_song` | Adicionar uma nova musica (JSON SongEntry) a biblioteca |
91
+ | `import_midi` | Converter um arquivo MIDI em SongEntry e registra-lo |
92
+
93
+ ### AI Jam Session
94
+
95
+ A ferramenta `ai_jam_session` extrai um "resumo de jam" estruturado de qualquer musica: progressao de acordes, contorno melodico e orientacao de estilo especifica do genero. O Claude usa o resumo para criar a sua propria interpretacao.
96
+
97
+ Dois modos:
98
+ - **Musica especifica:** `ai_jam_session({ songId: "autumn-leaves", style: "blues" })` — improvisar sobre Autumn Leaves, estilo blues
99
+ - **Escolha aleatoria por genero:** `ai_jam_session({ genre: "jazz" })` — escolher uma musica de jazz aleatoria e improvisar
100
+
101
+ Parametros opcionais: `mood` (animado, melancolico, sonhador, etc.), `difficulty`, `measures` (intervalo como "1-8").
102
+
103
+ ### Configuracao Claude Desktop / Claude Code
104
+
105
+ ```json
106
+ {
107
+ "mcpServers": {
108
+ "pianoai": {
109
+ "command": "npx",
110
+ "args": ["-y", "-p", "@mcptoolshop/ai_jam_session", "ai-jam-session-mcp"]
111
+ }
112
+ }
113
+ }
114
+ ```
115
+
116
+ ### Plugin para Claude Code
117
+
118
+ O PianoAI inclui um plugin para Claude Code que adiciona comandos de barra e personalidades de agente:
119
+
120
+ | Comando | Descricao |
121
+ |---------|-----------|
122
+ | `/pianoai:teach <song>` | Iniciar uma sessao de ensino estruturada |
123
+ | `/pianoai:practice <song>` | Obter um plano de pratica com recomendacoes de velocidade/modo |
124
+ | `/pianoai:explore [query]` | Navegar pela biblioteca de musicas por genero, dificuldade ou palavra-chave |
125
+ | `/pianoai:jam <song or genre>` | Iniciar uma sessao de jam — o Claude cria a sua propria interpretacao |
126
+
127
+ Duas personalidades de agente:
128
+ - **Professor de Piano** — paciente, pedagogico, encontra o aluno no nivel em que ele esta
129
+ - **Musico de Jam** — clima descontraido de jam band, groove em primeiro lugar, incentiva a experimentacao
130
+
131
+ ## Biblioteca de Musicas
132
+
133
+ 100 musicas integradas em 10 generos, 3 niveis de dificuldade:
134
+
135
+ | Genero | Musicas | Exemplos |
136
+ |--------|---------|----------|
137
+ | Classico | 10 | Fur Elise, Clair de Lune, Moonlight Sonata, Bach Prelude in C |
138
+ | Jazz | 10 | Autumn Leaves, Take Five, So What, Misty |
139
+ | Pop | 10 | Imagine, Hallelujah, Piano Man, Bohemian Rhapsody |
140
+ | Blues | 10 | Basic 12-Bar, St. Louis Blues, Stormy Monday, Thrill Is Gone |
141
+ | Rock | 10 | Stairway Intro, Hotel California, Rocket Man, Layla Coda |
142
+ | R&B | 10 | Superstition, Georgia On My Mind, Lean On Me, My Girl |
143
+ | Latin | 10 | Girl from Ipanema, Besame Mucho, Oye Como Va, Wave |
144
+ | Cinema | 11 | Cinema Paradiso, Moon River, Hedwig's Theme, Spirited Away |
145
+ | Ragtime | 9 | The Entertainer, Maple Leaf Rag, Elite Syncopations |
146
+ | New-Age | 10 | River Flows in You, Snowfall, Crystal Stream, Evening Calm |
147
+
148
+ ## API Programatica
149
+
150
+ ```typescript
151
+ import { createAudioEngine, parseMidiFile, PlaybackController } from "@mcptoolshop/ai_jam_session";
152
+
153
+ const connector = createAudioEngine();
154
+ await connector.connect();
155
+
156
+ const midi = await parseMidiFile("song.mid");
157
+ const controller = new PlaybackController(connector, midi);
158
+
159
+ controller.on("noteOn", (e) => console.log(`Note: ${e.noteName}`));
160
+ await controller.play({ speed: 0.75 });
161
+
162
+ controller.pause();
163
+ controller.setSpeed(1.5);
164
+ await controller.resume();
165
+
166
+ await connector.disconnect();
167
+ ```
168
+
169
+ ### Tocar uma musica da biblioteca
170
+
171
+ ```typescript
172
+ import { getSong, createSession, createAudioEngine } from "@mcptoolshop/ai_jam_session";
173
+
174
+ const connector = createAudioEngine();
175
+ await connector.connect();
176
+
177
+ const song = getSong("autumn-leaves")!;
178
+ const session = createSession(song, connector, {
179
+ mode: "full",
180
+ speed: 0.75,
181
+ });
182
+
183
+ await session.play();
184
+ await connector.disconnect();
185
+ ```
186
+
187
+ ## Arquitetura
188
+
189
+ ```
190
+ MIDI files (.mid) Built-in song library (JSON)
191
+ | |
192
+ v v
193
+ MIDI Parser ──────────────── Note Parser
194
+ | |
195
+ v v
196
+ MidiPlaybackEngine SessionController
197
+ | |
198
+ └──────── PlaybackController ──┘
199
+ (real-time events, hooks)
200
+ |
201
+ ┌─────────────┼─────────────┐
202
+ v v v
203
+ AudioEngine Teaching Hooks Progress
204
+ (speakers) (per-measure) (callbacks)
205
+ |
206
+ v
207
+ node-web-audio-api (Rust DSP)
208
+ ```
209
+
210
+ ## Licenca
211
+
212
+ MIT
@@ -0,0 +1,9 @@
1
+ import type { VmpkConnector } from "./types.js";
2
+ /**
3
+ * Create the built-in piano engine.
4
+ *
5
+ * Implements VmpkConnector so it's a drop-in replacement anywhere
6
+ * the codebase uses a connector (sessions, CLI, MCP server).
7
+ */
8
+ export declare function createAudioEngine(): VmpkConnector;
9
+ //# sourceMappingURL=audio-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-engine.d.ts","sourceRoot":"","sources":["../src/audio-engine.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,aAAa,EAAwB,MAAM,YAAY,CAAC;AAqItE;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,aAAa,CAgUjD"}
@@ -0,0 +1,422 @@
1
+ // ─── pianoai: Built-in Piano Engine ──────────────────────────────────────────
2
+ //
3
+ // Quality multi-harmonic piano synthesis using node-web-audio-api.
4
+ // No external software required — npm install gives you everything.
5
+ //
6
+ // Piano model features:
7
+ // - 12 sine partials per voice with inharmonic frequency stretching
8
+ // - Per-partial amplitude envelopes (higher harmonics decay faster)
9
+ // - Velocity-dependent timbre (harder = brighter, more harmonics)
10
+ // - Hammer noise transient (bandpass-filtered noise burst on attack)
11
+ // - Duplex stringing simulation (subtle random detuning per partial)
12
+ // - Stereo imaging (low notes left, high notes right)
13
+ // - DynamicsCompressor for polyphony safety
14
+ // - 48-voice polyphony with LRU voice stealing
15
+ //
16
+ // Usage:
17
+ // const piano = createAudioEngine();
18
+ // await piano.connect();
19
+ // piano.noteOn(60, 100); // middle C, forte
20
+ // piano.noteOff(60);
21
+ // await piano.disconnect();
22
+ // ─────────────────────────────────────────────────────────────────────────────
23
+ // ─── Lazy Import ────────────────────────────────────────────────────────────
24
+ // Don't load the native binary until the engine is actually used.
25
+ let _AudioContext = null;
26
+ async function loadAudioContext() {
27
+ if (!_AudioContext) {
28
+ const mod = await import("node-web-audio-api");
29
+ _AudioContext = mod.AudioContext;
30
+ }
31
+ return _AudioContext;
32
+ }
33
+ // ─── Piano Physics ──────────────────────────────────────────────────────────
34
+ /** Max partials per voice (bass notes get all, treble gets fewer). */
35
+ const MAX_PARTIALS = 12;
36
+ /** Maximum simultaneous voices before stealing. */
37
+ const MAX_POLYPHONY = 48;
38
+ /** MIDI note → frequency (A4 = 440 Hz). */
39
+ function midiToFreq(note) {
40
+ return 440 * Math.pow(2, (note - 69) / 12);
41
+ }
42
+ /** MIDI note → octave (0–8). */
43
+ function midiToOctave(note) {
44
+ return Math.max(0, Math.min(8, Math.floor(note / 12) - 1));
45
+ }
46
+ /**
47
+ * Stereo pan: low notes left, high notes right.
48
+ * Mimics sitting at a piano — bass on the left, treble on the right.
49
+ */
50
+ function noteToPan(note) {
51
+ return Math.max(-0.7, Math.min(0.7, ((note - 21) / 87) * 1.4 - 0.7));
52
+ }
53
+ /**
54
+ * Inharmonicity coefficient by octave.
55
+ *
56
+ * Piano strings are stiff, not ideal — partials are stretched above
57
+ * pure harmonics. This gives pianos their characteristic shimmer.
58
+ *
59
+ * f_n = n × f₀ × √(1 + B × n²)
60
+ */
61
+ const B_COEFF = [
62
+ 0.00012, // octave 0 (A0 area) — highest inharmonicity
63
+ 0.00008, // octave 1
64
+ 0.00004, // octave 2
65
+ 0.00002, // octave 3
66
+ 0.00001, // octave 4 (middle C)
67
+ 0.000006, // octave 5
68
+ 0.000004, // octave 6
69
+ 0.000003, // octave 7
70
+ 0.000002, // octave 8
71
+ ];
72
+ /** Compute stretched partial frequency with inharmonicity. */
73
+ function partialFreq(fundamental, n, B) {
74
+ return n * fundamental * Math.sqrt(1 + B * n * n);
75
+ }
76
+ /**
77
+ * How many partials to use for this note.
78
+ * Bass notes have richer harmonic content; treble is simpler.
79
+ */
80
+ function partialsForNote(midiNote) {
81
+ if (midiNote > 90)
82
+ return 5; // High treble
83
+ if (midiNote > 72)
84
+ return 8; // Upper register
85
+ if (midiNote > 54)
86
+ return 10; // Middle register
87
+ return MAX_PARTIALS; // Bass — full harmonic series
88
+ }
89
+ /**
90
+ * Amplitude for the nth partial (1-based).
91
+ *
92
+ * Base amplitude follows ~1/n^0.7 with exponential rolloff.
93
+ * Velocity controls brightness: soft = warm, hard = bright.
94
+ */
95
+ function partialAmplitude(n, velocity01) {
96
+ const base = Math.pow(n, -0.7) * Math.exp(-0.08 * n);
97
+ // Velocity-dependent brightness: high partials only appear at higher velocity
98
+ if (n <= 3)
99
+ return base;
100
+ const brightnessGate = Math.pow(velocity01, 0.3 + (n - 3) * 0.12);
101
+ return base * brightnessGate;
102
+ }
103
+ /**
104
+ * Decay time constant (seconds) for the nth partial at a given MIDI note.
105
+ *
106
+ * Higher partials decay much faster than the fundamental.
107
+ * Lower notes ring longer than higher notes.
108
+ */
109
+ function partialDecayTime(n, midiNote) {
110
+ // Base decay for fundamental: 3s (treble) to 15s (bass)
111
+ const registerFactor = 1.0 - (midiNote - 21) / 87;
112
+ const baseFundamental = 3 + registerFactor * 12;
113
+ // Higher partials: decay ∝ 1/n^0.8
114
+ return baseFundamental * Math.pow(n, -0.8);
115
+ }
116
+ /**
117
+ * Attack time based on velocity.
118
+ * Harder strikes = shorter hammer pulse = sharper attack.
119
+ */
120
+ function attackTime(velocity01) {
121
+ return 0.002 + (1 - velocity01) * 0.008; // 2ms (ff) to 10ms (pp)
122
+ }
123
+ // ─── Engine ─────────────────────────────────────────────────────────────────
124
+ /**
125
+ * Create the built-in piano engine.
126
+ *
127
+ * Implements VmpkConnector so it's a drop-in replacement anywhere
128
+ * the codebase uses a connector (sessions, CLI, MCP server).
129
+ */
130
+ export function createAudioEngine() {
131
+ let ctx = null;
132
+ let currentStatus = "disconnected";
133
+ let compressor = null;
134
+ let master = null;
135
+ const activeVoices = new Map();
136
+ const voiceOrder = []; // LRU tracking for voice stealing
137
+ // ── Noise buffer (shared across all voices) ──
138
+ let hammerNoiseBuffer = null;
139
+ function ensureConnected() {
140
+ if (!ctx || currentStatus !== "connected") {
141
+ throw new Error("Piano engine not connected");
142
+ }
143
+ }
144
+ /** Create a reusable noise buffer for hammer transients. */
145
+ function createHammerNoiseBuffer() {
146
+ const durationMs = 40;
147
+ const length = Math.ceil((durationMs / 1000) * ctx.sampleRate);
148
+ hammerNoiseBuffer = ctx.createBuffer(1, length, ctx.sampleRate);
149
+ const data = new Float32Array(length);
150
+ for (let i = 0; i < length; i++) {
151
+ data[i] = Math.random() * 2 - 1;
152
+ }
153
+ hammerNoiseBuffer.copyToChannel(data, 0);
154
+ }
155
+ /** Synthesize a single piano voice. */
156
+ function createVoice(note, velocity) {
157
+ const velocity01 = Math.max(0.01, Math.min(1.0, velocity / 127));
158
+ const freq = midiToFreq(note);
159
+ const octave = midiToOctave(note);
160
+ const B = B_COEFF[octave] ?? 0.000003;
161
+ const now = ctx.currentTime;
162
+ const attack = attackTime(velocity01);
163
+ const numPartials = partialsForNote(note);
164
+ // ── Master gain: constant volume (per-partial gains shape the envelope) ──
165
+ const voiceMaster = ctx.createGain();
166
+ voiceMaster.gain.value = velocity01 * 0.25;
167
+ // ── Stereo panner ──
168
+ const panner = ctx.createStereoPanner();
169
+ panner.pan.value = noteToPan(note);
170
+ voiceMaster.connect(panner);
171
+ panner.connect(compressor);
172
+ // ── Sine partials with per-partial envelopes ──
173
+ const oscillators = [];
174
+ const partialGains = [];
175
+ for (let n = 1; n <= numPartials; n++) {
176
+ const pFreq = partialFreq(freq, n, B);
177
+ if (pFreq > 18000)
178
+ break; // Near hearing limit
179
+ const osc = ctx.createOscillator();
180
+ osc.type = "sine";
181
+ osc.frequency.value = pFreq;
182
+ // Duplex stringing: subtle random detuning for warmth
183
+ osc.detune.value = (Math.random() - 0.5) * 3; // ±1.5 cents
184
+ const gain = ctx.createGain();
185
+ const amp = partialAmplitude(n, velocity01);
186
+ const decay = partialDecayTime(n, note);
187
+ // Envelope: silence → attack → exponential decay
188
+ gain.gain.setValueAtTime(0, now);
189
+ gain.gain.linearRampToValueAtTime(amp, now + attack);
190
+ // Exponential decay toward near-zero
191
+ gain.gain.setTargetAtTime(0.0001, now + attack, decay);
192
+ osc.connect(gain);
193
+ gain.connect(voiceMaster);
194
+ osc.start(now);
195
+ oscillators.push(osc);
196
+ partialGains.push(gain);
197
+ }
198
+ // ── Hammer noise transient ──
199
+ let noiseSource = null;
200
+ if (hammerNoiseBuffer) {
201
+ noiseSource = ctx.createBufferSource();
202
+ noiseSource.buffer = hammerNoiseBuffer;
203
+ // Bandpass near note frequency — gives the attack a tonal character
204
+ const noiseFilter = ctx.createBiquadFilter();
205
+ noiseFilter.type = "bandpass";
206
+ noiseFilter.frequency.value = Math.min(freq * 2.5, 10000);
207
+ noiseFilter.Q.value = 0.5 + velocity01 * 2.5;
208
+ // Quick envelope: burst then silence
209
+ const noiseGain = ctx.createGain();
210
+ const noiseAmp = velocity01 * 0.2;
211
+ noiseGain.gain.setValueAtTime(noiseAmp, now);
212
+ noiseGain.gain.exponentialRampToValueAtTime(0.001, now + 0.025);
213
+ noiseSource.connect(noiseFilter);
214
+ noiseFilter.connect(noiseGain);
215
+ noiseGain.connect(voiceMaster);
216
+ noiseSource.start(now);
217
+ }
218
+ return {
219
+ note,
220
+ oscillators,
221
+ partialGains,
222
+ masterGain: voiceMaster,
223
+ panner,
224
+ noiseSource,
225
+ startTime: now,
226
+ released: false,
227
+ cleanupTimer: null,
228
+ };
229
+ }
230
+ /** Release a voice (damper engages — fast fade out). */
231
+ function releaseVoice(voice) {
232
+ if (voice.released)
233
+ return;
234
+ voice.released = true;
235
+ const now = ctx.currentTime;
236
+ const releaseTime = 0.12; // 120ms damper release
237
+ // Cancel ongoing scheduled values and fade to silence
238
+ for (const g of voice.partialGains) {
239
+ g.gain.cancelScheduledValues(now);
240
+ g.gain.setValueAtTime(g.gain.value, now);
241
+ g.gain.linearRampToValueAtTime(0, now + releaseTime);
242
+ }
243
+ // Schedule full cleanup after release completes
244
+ voice.cleanupTimer = setTimeout(() => killVoice(voice), (releaseTime + 0.05) * 1000);
245
+ }
246
+ /** Immediately destroy a voice and free resources. */
247
+ function killVoice(voice) {
248
+ if (voice.cleanupTimer) {
249
+ clearTimeout(voice.cleanupTimer);
250
+ voice.cleanupTimer = null;
251
+ }
252
+ for (const osc of voice.oscillators) {
253
+ try {
254
+ osc.stop();
255
+ osc.disconnect();
256
+ }
257
+ catch {
258
+ /* already stopped */
259
+ }
260
+ }
261
+ for (const g of voice.partialGains) {
262
+ try {
263
+ g.disconnect();
264
+ }
265
+ catch {
266
+ /* ok */
267
+ }
268
+ }
269
+ if (voice.noiseSource) {
270
+ try {
271
+ voice.noiseSource.stop();
272
+ voice.noiseSource.disconnect();
273
+ }
274
+ catch {
275
+ /* ok */
276
+ }
277
+ }
278
+ try {
279
+ voice.masterGain.disconnect();
280
+ }
281
+ catch {
282
+ /* ok */
283
+ }
284
+ try {
285
+ voice.panner.disconnect();
286
+ }
287
+ catch {
288
+ /* ok */
289
+ }
290
+ }
291
+ /** Steal the oldest voice when at max polyphony. */
292
+ function stealOldest() {
293
+ if (voiceOrder.length === 0)
294
+ return;
295
+ const oldestNote = voiceOrder.shift();
296
+ const voice = activeVoices.get(oldestNote);
297
+ if (voice) {
298
+ killVoice(voice);
299
+ activeVoices.delete(oldestNote);
300
+ }
301
+ }
302
+ /** Remove a note from the LRU order. */
303
+ function removeFromOrder(note) {
304
+ const idx = voiceOrder.indexOf(note);
305
+ if (idx >= 0)
306
+ voiceOrder.splice(idx, 1);
307
+ }
308
+ // ── VmpkConnector Implementation ──
309
+ return {
310
+ async connect() {
311
+ if (currentStatus === "connected")
312
+ return;
313
+ currentStatus = "connecting";
314
+ try {
315
+ const AC = await loadAudioContext();
316
+ ctx = new AC({ latencyHint: "playback" });
317
+ // Master chain: compressor → gain → speakers
318
+ compressor = ctx.createDynamicsCompressor();
319
+ compressor.threshold.value = -15;
320
+ compressor.knee.value = 12;
321
+ compressor.ratio.value = 6;
322
+ compressor.attack.value = 0.003;
323
+ compressor.release.value = 0.2;
324
+ master = ctx.createGain();
325
+ master.gain.value = 0.85;
326
+ compressor.connect(master);
327
+ master.connect(ctx.destination);
328
+ // Pre-generate shared noise buffer
329
+ createHammerNoiseBuffer();
330
+ currentStatus = "connected";
331
+ console.error("Piano engine connected (built-in audio)");
332
+ }
333
+ catch (err) {
334
+ currentStatus = "error";
335
+ throw new Error(`Failed to start piano engine: ${err instanceof Error ? err.message : String(err)}`);
336
+ }
337
+ },
338
+ async disconnect() {
339
+ // Kill all active voices
340
+ for (const [, voice] of activeVoices) {
341
+ try {
342
+ killVoice(voice);
343
+ }
344
+ catch {
345
+ /* ok */
346
+ }
347
+ }
348
+ activeVoices.clear();
349
+ voiceOrder.length = 0;
350
+ if (ctx) {
351
+ try {
352
+ await ctx.close();
353
+ }
354
+ catch {
355
+ /* ok */
356
+ }
357
+ ctx = null;
358
+ compressor = null;
359
+ master = null;
360
+ hammerNoiseBuffer = null;
361
+ }
362
+ currentStatus = "disconnected";
363
+ },
364
+ status() {
365
+ return currentStatus;
366
+ },
367
+ listPorts() {
368
+ return ["Built-in Piano"];
369
+ },
370
+ noteOn(note, velocity, channel) {
371
+ ensureConnected();
372
+ // Kill existing voice on same note (retrigger)
373
+ const existing = activeVoices.get(note);
374
+ if (existing) {
375
+ killVoice(existing);
376
+ activeVoices.delete(note);
377
+ removeFromOrder(note);
378
+ }
379
+ // Voice stealing if at capacity
380
+ while (activeVoices.size >= MAX_POLYPHONY) {
381
+ stealOldest();
382
+ }
383
+ const voice = createVoice(note, velocity);
384
+ activeVoices.set(note, voice);
385
+ voiceOrder.push(note);
386
+ },
387
+ noteOff(note, channel) {
388
+ if (!ctx || currentStatus !== "connected")
389
+ return;
390
+ const voice = activeVoices.get(note);
391
+ if (voice) {
392
+ releaseVoice(voice);
393
+ activeVoices.delete(note);
394
+ removeFromOrder(note);
395
+ }
396
+ },
397
+ allNotesOff(channel) {
398
+ if (!ctx)
399
+ return;
400
+ for (const [, voice] of activeVoices) {
401
+ killVoice(voice);
402
+ }
403
+ activeVoices.clear();
404
+ voiceOrder.length = 0;
405
+ },
406
+ async playNote(midiNote) {
407
+ if (midiNote.note < 0) {
408
+ // Rest — just wait
409
+ await sleep(midiNote.durationMs);
410
+ return;
411
+ }
412
+ this.noteOn(midiNote.note, midiNote.velocity, midiNote.channel);
413
+ await sleep(midiNote.durationMs);
414
+ this.noteOff(midiNote.note, midiNote.channel);
415
+ },
416
+ };
417
+ }
418
+ // ─── Helpers ────────────────────────────────────────────────────────────────
419
+ function sleep(ms) {
420
+ return new Promise((resolve) => setTimeout(resolve, ms));
421
+ }
422
+ //# sourceMappingURL=audio-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-engine.js","sourceRoot":"","sources":["../src/audio-engine.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}