@drop-ai/core 0.2.0 → 0.3.1

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 (513) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +734 -316
  3. package/dist/actions/ActionRegistry.d.ts.map +1 -1
  4. package/dist/actions/ActionRegistry.js +7 -2
  5. package/dist/actions/ActionRegistry.js.map +1 -1
  6. package/dist/actions/types.d.ts +7 -1
  7. package/dist/actions/types.d.ts.map +1 -1
  8. package/dist/analysis/AudioAnalyzer.d.ts +69 -0
  9. package/dist/analysis/AudioAnalyzer.d.ts.map +1 -0
  10. package/dist/analysis/AudioAnalyzer.js +567 -0
  11. package/dist/analysis/AudioAnalyzer.js.map +1 -0
  12. package/dist/audio/AudioEngine.d.ts +14 -1
  13. package/dist/audio/AudioEngine.d.ts.map +1 -1
  14. package/dist/audio/AudioEngine.js +115 -35
  15. package/dist/audio/AudioEngine.js.map +1 -1
  16. package/dist/audio/Auditioner.d.ts +102 -0
  17. package/dist/audio/Auditioner.d.ts.map +1 -0
  18. package/dist/audio/Auditioner.js +237 -0
  19. package/dist/audio/Auditioner.js.map +1 -0
  20. package/dist/audio/BWFMetadata.d.ts +114 -0
  21. package/dist/audio/BWFMetadata.d.ts.map +1 -0
  22. package/dist/audio/BWFMetadata.js +392 -0
  23. package/dist/audio/BWFMetadata.js.map +1 -0
  24. package/dist/audio/BufferPool.d.ts +0 -3
  25. package/dist/audio/BufferPool.d.ts.map +1 -1
  26. package/dist/audio/BufferPool.js +0 -3
  27. package/dist/audio/BufferPool.js.map +1 -1
  28. package/dist/audio/ChannelSplitter.d.ts +36 -0
  29. package/dist/audio/ChannelSplitter.d.ts.map +1 -0
  30. package/dist/audio/ChannelSplitter.js +81 -0
  31. package/dist/audio/ChannelSplitter.js.map +1 -0
  32. package/dist/audio/ExportAnalyzer.d.ts +38 -0
  33. package/dist/audio/ExportAnalyzer.d.ts.map +1 -0
  34. package/dist/audio/ExportAnalyzer.js +75 -0
  35. package/dist/audio/ExportAnalyzer.js.map +1 -0
  36. package/dist/audio/LufsNormalizer.d.ts +36 -0
  37. package/dist/audio/LufsNormalizer.d.ts.map +1 -0
  38. package/dist/audio/LufsNormalizer.js +216 -0
  39. package/dist/audio/LufsNormalizer.js.map +1 -0
  40. package/dist/audio/MeterUtils.d.ts +0 -2
  41. package/dist/audio/MeterUtils.d.ts.map +1 -1
  42. package/dist/audio/MeterUtils.js +0 -2
  43. package/dist/audio/MeterUtils.js.map +1 -1
  44. package/dist/audio/OfflineExporter.d.ts +1 -7
  45. package/dist/audio/OfflineExporter.d.ts.map +1 -1
  46. package/dist/audio/OfflineExporter.js +31 -11
  47. package/dist/audio/OfflineExporter.js.map +1 -1
  48. package/dist/audio/ProcessingGraph.d.ts +0 -1
  49. package/dist/audio/ProcessingGraph.d.ts.map +1 -1
  50. package/dist/audio/ProcessingGraph.js +0 -1
  51. package/dist/audio/ProcessingGraph.js.map +1 -1
  52. package/dist/audio/RoutingGraph.d.ts +134 -0
  53. package/dist/audio/RoutingGraph.d.ts.map +1 -0
  54. package/dist/audio/RoutingGraph.js +547 -0
  55. package/dist/audio/RoutingGraph.js.map +1 -0
  56. package/dist/audio/SampleRateConverter.d.ts +20 -0
  57. package/dist/audio/SampleRateConverter.d.ts.map +1 -0
  58. package/dist/audio/SampleRateConverter.js +83 -0
  59. package/dist/audio/SampleRateConverter.js.map +1 -0
  60. package/dist/audio/SilencePadding.d.ts +27 -0
  61. package/dist/audio/SilencePadding.d.ts.map +1 -0
  62. package/dist/audio/SilencePadding.js +84 -0
  63. package/dist/audio/SilencePadding.js.map +1 -0
  64. package/dist/audio/SourceCache.d.ts +13 -19
  65. package/dist/audio/SourceCache.d.ts.map +1 -1
  66. package/dist/audio/SourceCache.js +21 -36
  67. package/dist/audio/SourceCache.js.map +1 -1
  68. package/dist/audio/engine/Declick.d.ts +97 -0
  69. package/dist/audio/engine/Declick.d.ts.map +1 -0
  70. package/dist/audio/engine/Declick.js +203 -0
  71. package/dist/audio/engine/Declick.js.map +1 -0
  72. package/dist/audio/engine/DiskIO.d.ts +170 -0
  73. package/dist/audio/engine/DiskIO.d.ts.map +1 -0
  74. package/dist/audio/engine/DiskIO.js +382 -0
  75. package/dist/audio/engine/DiskIO.js.map +1 -0
  76. package/dist/audio/engine/LatencyCompensator.d.ts +46 -0
  77. package/dist/audio/engine/LatencyCompensator.d.ts.map +1 -0
  78. package/dist/audio/engine/LatencyCompensator.js +84 -0
  79. package/dist/audio/engine/LatencyCompensator.js.map +1 -0
  80. package/dist/audio/engine/MultiTrackRecorder.d.ts +144 -0
  81. package/dist/audio/engine/MultiTrackRecorder.d.ts.map +1 -0
  82. package/dist/audio/engine/MultiTrackRecorder.js +359 -0
  83. package/dist/audio/engine/MultiTrackRecorder.js.map +1 -0
  84. package/dist/audio/engine/PlaylistEngine.d.ts +1 -1
  85. package/dist/audio/engine/PlaylistEngine.d.ts.map +1 -1
  86. package/dist/audio/engine/PlaylistEngine.js +10 -3
  87. package/dist/audio/engine/PlaylistEngine.js.map +1 -1
  88. package/dist/audio/engine/PunchRecordManager.d.ts +111 -0
  89. package/dist/audio/engine/PunchRecordManager.d.ts.map +1 -0
  90. package/dist/audio/engine/PunchRecordManager.js +191 -0
  91. package/dist/audio/engine/PunchRecordManager.js.map +1 -0
  92. package/dist/audio/engine/RoutingGraph.d.ts +133 -0
  93. package/dist/audio/engine/RoutingGraph.d.ts.map +1 -0
  94. package/dist/audio/engine/RoutingGraph.js +436 -0
  95. package/dist/audio/engine/RoutingGraph.js.map +1 -0
  96. package/dist/audio/engine/SidechainRouter.d.ts +137 -0
  97. package/dist/audio/engine/SidechainRouter.d.ts.map +1 -0
  98. package/dist/audio/engine/SidechainRouter.js +290 -0
  99. package/dist/audio/engine/SidechainRouter.js.map +1 -0
  100. package/dist/audio/engine/XrunTracker.d.ts +71 -0
  101. package/dist/audio/engine/XrunTracker.d.ts.map +1 -0
  102. package/dist/audio/engine/XrunTracker.js +118 -0
  103. package/dist/audio/engine/XrunTracker.js.map +1 -0
  104. package/dist/audio/export/CDMarkerExporter.d.ts +60 -0
  105. package/dist/audio/export/CDMarkerExporter.d.ts.map +1 -0
  106. package/dist/audio/export/CDMarkerExporter.js +162 -0
  107. package/dist/audio/export/CDMarkerExporter.js.map +1 -0
  108. package/dist/audio/export/ExportGraphBuilder.d.ts +119 -0
  109. package/dist/audio/export/ExportGraphBuilder.d.ts.map +1 -0
  110. package/dist/audio/export/ExportGraphBuilder.js +520 -0
  111. package/dist/audio/export/ExportGraphBuilder.js.map +1 -0
  112. package/dist/audio/export/ExportPresetManager.d.ts +85 -0
  113. package/dist/audio/export/ExportPresetManager.d.ts.map +1 -0
  114. package/dist/audio/export/ExportPresetManager.js +304 -0
  115. package/dist/audio/export/ExportPresetManager.js.map +1 -0
  116. package/dist/automation/AutomationList.d.ts +0 -1
  117. package/dist/automation/AutomationList.d.ts.map +1 -1
  118. package/dist/automation/AutomationList.js +0 -1
  119. package/dist/automation/AutomationList.js.map +1 -1
  120. package/dist/automation/AutomationMode.d.ts +0 -1
  121. package/dist/automation/AutomationMode.d.ts.map +1 -1
  122. package/dist/automation/AutomationMode.js +0 -1
  123. package/dist/automation/AutomationMode.js.map +1 -1
  124. package/dist/commands/CommandHistory.d.ts +1 -4
  125. package/dist/commands/CommandHistory.d.ts.map +1 -1
  126. package/dist/commands/CommandHistory.js +6 -9
  127. package/dist/commands/CommandHistory.js.map +1 -1
  128. package/dist/commands/CommandRegistry.d.ts +1 -2
  129. package/dist/commands/CommandRegistry.d.ts.map +1 -1
  130. package/dist/commands/CommandRegistry.js +1 -2
  131. package/dist/commands/CommandRegistry.js.map +1 -1
  132. package/dist/commands/UndoTransaction.d.ts +0 -2
  133. package/dist/commands/UndoTransaction.d.ts.map +1 -1
  134. package/dist/commands/UndoTransaction.js +1 -3
  135. package/dist/commands/UndoTransaction.js.map +1 -1
  136. package/dist/commands/handlers/HistoryHandler.d.ts +5 -5
  137. package/dist/commands/handlers/HistoryHandler.js +10 -10
  138. package/dist/commands/handlers/HistoryHandler.js.map +1 -1
  139. package/dist/commands/handlers/MarkerHandler.d.ts +0 -1
  140. package/dist/commands/handlers/MarkerHandler.d.ts.map +1 -1
  141. package/dist/commands/handlers/MarkerHandler.js +0 -1
  142. package/dist/commands/handlers/MarkerHandler.js.map +1 -1
  143. package/dist/commands/handlers/RegionHandler.d.ts.map +1 -1
  144. package/dist/commands/handlers/RegionHandler.js +25 -1
  145. package/dist/commands/handlers/RegionHandler.js.map +1 -1
  146. package/dist/commands/handlers/TrackHandler.js +1 -1
  147. package/dist/commands/handlers/TrackHandler.js.map +1 -1
  148. package/dist/commands/impl/CopyRegionCommand.d.ts +0 -1
  149. package/dist/commands/impl/CopyRegionCommand.d.ts.map +1 -1
  150. package/dist/commands/impl/CopyRegionCommand.js +0 -1
  151. package/dist/commands/impl/CopyRegionCommand.js.map +1 -1
  152. package/dist/commands/impl/DuplicateRegionCommand.d.ts +0 -1
  153. package/dist/commands/impl/DuplicateRegionCommand.d.ts.map +1 -1
  154. package/dist/commands/impl/DuplicateRegionCommand.js +0 -1
  155. package/dist/commands/impl/DuplicateRegionCommand.js.map +1 -1
  156. package/dist/commands/impl/ExportCommand.d.ts +0 -1
  157. package/dist/commands/impl/ExportCommand.d.ts.map +1 -1
  158. package/dist/commands/impl/ExportCommand.js +0 -1
  159. package/dist/commands/impl/ExportCommand.js.map +1 -1
  160. package/dist/commands/impl/FreezeTrackCommand.d.ts +1 -1
  161. package/dist/commands/impl/FreezeTrackCommand.d.ts.map +1 -1
  162. package/dist/commands/impl/FreezeTrackCommand.js +38 -37
  163. package/dist/commands/impl/FreezeTrackCommand.js.map +1 -1
  164. package/dist/commands/impl/PasteRegionCommand.d.ts +0 -1
  165. package/dist/commands/impl/PasteRegionCommand.d.ts.map +1 -1
  166. package/dist/commands/impl/PasteRegionCommand.js +0 -1
  167. package/dist/commands/impl/PasteRegionCommand.js.map +1 -1
  168. package/dist/commands/impl/SaveSnapshotCommand.d.ts +1 -1
  169. package/dist/commands/impl/SaveSnapshotCommand.js +1 -1
  170. package/dist/commands/impl/SetLoopRangeCommand.d.ts +0 -1
  171. package/dist/commands/impl/SetLoopRangeCommand.d.ts.map +1 -1
  172. package/dist/commands/impl/SetLoopRangeCommand.js +0 -1
  173. package/dist/commands/impl/SetLoopRangeCommand.js.map +1 -1
  174. package/dist/commands/impl/SetPunchRangeCommand.d.ts +0 -1
  175. package/dist/commands/impl/SetPunchRangeCommand.d.ts.map +1 -1
  176. package/dist/commands/impl/SetPunchRangeCommand.js +0 -1
  177. package/dist/commands/impl/SetPunchRangeCommand.js.map +1 -1
  178. package/dist/commands/impl/SetRegionTimeDomainCommand.d.ts.map +1 -1
  179. package/dist/commands/impl/SetRegionTimeDomainCommand.js +3 -3
  180. package/dist/commands/impl/SetRegionTimeDomainCommand.js.map +1 -1
  181. package/dist/commands/impl/SplitAtPlayheadCommand.d.ts +0 -2
  182. package/dist/commands/impl/SplitAtPlayheadCommand.d.ts.map +1 -1
  183. package/dist/commands/impl/SplitAtPlayheadCommand.js +0 -2
  184. package/dist/commands/impl/SplitAtPlayheadCommand.js.map +1 -1
  185. package/dist/commands/impl/SplitRegionCommand.d.ts +0 -1
  186. package/dist/commands/impl/SplitRegionCommand.d.ts.map +1 -1
  187. package/dist/commands/impl/SplitRegionCommand.js +0 -1
  188. package/dist/commands/impl/SplitRegionCommand.js.map +1 -1
  189. package/dist/commands/impl/StripSilenceCommand.d.ts +0 -1
  190. package/dist/commands/impl/StripSilenceCommand.d.ts.map +1 -1
  191. package/dist/commands/impl/StripSilenceCommand.js +0 -1
  192. package/dist/commands/impl/StripSilenceCommand.js.map +1 -1
  193. package/dist/commands/impl/TimeStretchRegionCommand.d.ts +1 -2
  194. package/dist/commands/impl/TimeStretchRegionCommand.d.ts.map +1 -1
  195. package/dist/commands/impl/TimeStretchRegionCommand.js +1 -2
  196. package/dist/commands/impl/TimeStretchRegionCommand.js.map +1 -1
  197. package/dist/commands/impl/ToggleLoopCommand.d.ts +1 -0
  198. package/dist/commands/impl/ToggleLoopCommand.d.ts.map +1 -1
  199. package/dist/commands/impl/ToggleLoopCommand.js +10 -0
  200. package/dist/commands/impl/ToggleLoopCommand.js.map +1 -1
  201. package/dist/commands/impl/TrimRegionCommand.d.ts +14 -1
  202. package/dist/commands/impl/TrimRegionCommand.d.ts.map +1 -1
  203. package/dist/commands/impl/TrimRegionCommand.js +138 -33
  204. package/dist/commands/impl/TrimRegionCommand.js.map +1 -1
  205. package/dist/commands/impl/TrimRegionToPlayheadCommand.d.ts +26 -0
  206. package/dist/commands/impl/TrimRegionToPlayheadCommand.d.ts.map +1 -0
  207. package/dist/commands/impl/TrimRegionToPlayheadCommand.js +68 -0
  208. package/dist/commands/impl/TrimRegionToPlayheadCommand.js.map +1 -0
  209. package/dist/commands/impl/TrimRegionToRangeCommand.d.ts +27 -0
  210. package/dist/commands/impl/TrimRegionToRangeCommand.d.ts.map +1 -0
  211. package/dist/commands/impl/TrimRegionToRangeCommand.js +68 -0
  212. package/dist/commands/impl/TrimRegionToRangeCommand.js.map +1 -0
  213. package/dist/commands/impl/TrimToAdjacentRegionCommand.d.ts +26 -0
  214. package/dist/commands/impl/TrimToAdjacentRegionCommand.d.ts.map +1 -0
  215. package/dist/commands/impl/TrimToAdjacentRegionCommand.js +76 -0
  216. package/dist/commands/impl/TrimToAdjacentRegionCommand.js.map +1 -0
  217. package/dist/commands/types.d.ts +19 -0
  218. package/dist/commands/types.d.ts.map +1 -1
  219. package/dist/commands/types.js +21 -0
  220. package/dist/commands/types.js.map +1 -1
  221. package/dist/domain/ABComparison.d.ts +0 -1
  222. package/dist/domain/ABComparison.d.ts.map +1 -1
  223. package/dist/domain/ABComparison.js +0 -1
  224. package/dist/domain/ABComparison.js.map +1 -1
  225. package/dist/domain/CDMarker.d.ts +0 -1
  226. package/dist/domain/CDMarker.d.ts.map +1 -1
  227. package/dist/domain/CDMarker.js +0 -1
  228. package/dist/domain/CDMarker.js.map +1 -1
  229. package/dist/domain/ClockMode.d.ts +0 -1
  230. package/dist/domain/ClockMode.d.ts.map +1 -1
  231. package/dist/domain/ClockMode.js +0 -1
  232. package/dist/domain/ClockMode.js.map +1 -1
  233. package/dist/domain/Crossfade.d.ts +78 -0
  234. package/dist/domain/Crossfade.d.ts.map +1 -0
  235. package/dist/domain/Crossfade.js +216 -0
  236. package/dist/domain/Crossfade.js.map +1 -0
  237. package/dist/domain/DragManager.d.ts +0 -2
  238. package/dist/domain/DragManager.d.ts.map +1 -1
  239. package/dist/domain/DragManager.js +0 -2
  240. package/dist/domain/DragManager.js.map +1 -1
  241. package/dist/domain/EditMode.d.ts +0 -1
  242. package/dist/domain/EditMode.d.ts.map +1 -1
  243. package/dist/domain/EditMode.js +0 -1
  244. package/dist/domain/EditMode.js.map +1 -1
  245. package/dist/domain/ExportConfig.d.ts +98 -2
  246. package/dist/domain/ExportConfig.d.ts.map +1 -1
  247. package/dist/domain/ExportConfig.js +154 -2
  248. package/dist/domain/ExportConfig.js.map +1 -1
  249. package/dist/domain/ExportPreset.d.ts +60 -0
  250. package/dist/domain/ExportPreset.d.ts.map +1 -0
  251. package/dist/domain/ExportPreset.js +77 -0
  252. package/dist/domain/ExportPreset.js.map +1 -0
  253. package/dist/domain/ExportStatus.d.ts +0 -1
  254. package/dist/domain/ExportStatus.d.ts.map +1 -1
  255. package/dist/domain/ExportStatus.js +0 -1
  256. package/dist/domain/ExportStatus.js.map +1 -1
  257. package/dist/domain/GridSettings.d.ts +0 -3
  258. package/dist/domain/GridSettings.d.ts.map +1 -1
  259. package/dist/domain/GridSettings.js +0 -3
  260. package/dist/domain/GridSettings.js.map +1 -1
  261. package/dist/domain/ImportStatus.d.ts +40 -0
  262. package/dist/domain/ImportStatus.d.ts.map +1 -0
  263. package/dist/domain/ImportStatus.js +86 -0
  264. package/dist/domain/ImportStatus.js.map +1 -0
  265. package/dist/domain/Marker.d.ts +0 -1
  266. package/dist/domain/Marker.d.ts.map +1 -1
  267. package/dist/domain/Marker.js +0 -1
  268. package/dist/domain/Marker.js.map +1 -1
  269. package/dist/domain/MeterData.d.ts +0 -2
  270. package/dist/domain/MeterData.d.ts.map +1 -1
  271. package/dist/domain/MeterType.d.ts +0 -2
  272. package/dist/domain/MeterType.d.ts.map +1 -1
  273. package/dist/domain/MeterType.js +0 -2
  274. package/dist/domain/MeterType.js.map +1 -1
  275. package/dist/domain/MonitorMode.d.ts +0 -1
  276. package/dist/domain/MonitorMode.d.ts.map +1 -1
  277. package/dist/domain/MonitorMode.js +0 -1
  278. package/dist/domain/MonitorMode.js.map +1 -1
  279. package/dist/domain/MouseMode.d.ts +0 -1
  280. package/dist/domain/MouseMode.d.ts.map +1 -1
  281. package/dist/domain/MouseMode.js +0 -1
  282. package/dist/domain/MouseMode.js.map +1 -1
  283. package/dist/domain/OverlapType.d.ts +0 -2
  284. package/dist/domain/OverlapType.d.ts.map +1 -1
  285. package/dist/domain/OverlapType.js +0 -2
  286. package/dist/domain/OverlapType.js.map +1 -1
  287. package/dist/domain/Playlist.d.ts +72 -0
  288. package/dist/domain/Playlist.d.ts.map +1 -1
  289. package/dist/domain/Playlist.js +231 -6
  290. package/dist/domain/Playlist.js.map +1 -1
  291. package/dist/domain/Range.d.ts +0 -1
  292. package/dist/domain/Range.d.ts.map +1 -1
  293. package/dist/domain/Range.js +0 -1
  294. package/dist/domain/Range.js.map +1 -1
  295. package/dist/domain/RecordMode.d.ts +0 -1
  296. package/dist/domain/RecordMode.d.ts.map +1 -1
  297. package/dist/domain/RecordMode.js +0 -1
  298. package/dist/domain/RecordMode.js.map +1 -1
  299. package/dist/domain/Region.d.ts +76 -0
  300. package/dist/domain/Region.d.ts.map +1 -1
  301. package/dist/domain/Region.js +234 -1
  302. package/dist/domain/Region.js.map +1 -1
  303. package/dist/domain/RegionClipboard.d.ts +1 -3
  304. package/dist/domain/RegionClipboard.d.ts.map +1 -1
  305. package/dist/domain/RegionClipboard.js +1 -2
  306. package/dist/domain/RegionClipboard.js.map +1 -1
  307. package/dist/domain/Route.d.ts +43 -3
  308. package/dist/domain/Route.d.ts.map +1 -1
  309. package/dist/domain/Route.js +92 -6
  310. package/dist/domain/Route.js.map +1 -1
  311. package/dist/domain/RulerType.d.ts +0 -1
  312. package/dist/domain/RulerType.d.ts.map +1 -1
  313. package/dist/domain/RulerType.js +0 -1
  314. package/dist/domain/RulerType.js.map +1 -1
  315. package/dist/domain/SelectionHistory.d.ts +0 -3
  316. package/dist/domain/SelectionHistory.d.ts.map +1 -1
  317. package/dist/domain/SelectionHistory.js +0 -3
  318. package/dist/domain/SelectionHistory.js.map +1 -1
  319. package/dist/domain/SendBus.d.ts +0 -1
  320. package/dist/domain/SendBus.d.ts.map +1 -1
  321. package/dist/domain/SendBus.js +0 -1
  322. package/dist/domain/SendBus.js.map +1 -1
  323. package/dist/domain/Session.d.ts +31 -0
  324. package/dist/domain/Session.d.ts.map +1 -1
  325. package/dist/domain/Session.js +70 -0
  326. package/dist/domain/Session.js.map +1 -1
  327. package/dist/domain/SidechainConfig.d.ts +0 -1
  328. package/dist/domain/SidechainConfig.d.ts.map +1 -1
  329. package/dist/domain/SidechainConfig.js +0 -1
  330. package/dist/domain/SidechainConfig.js.map +1 -1
  331. package/dist/domain/Source.d.ts +145 -1
  332. package/dist/domain/Source.d.ts.map +1 -1
  333. package/dist/domain/Source.js +144 -1
  334. package/dist/domain/Source.js.map +1 -1
  335. package/dist/domain/Take.d.ts +0 -1
  336. package/dist/domain/Take.d.ts.map +1 -1
  337. package/dist/domain/Take.js +0 -1
  338. package/dist/domain/Take.js.map +1 -1
  339. package/dist/domain/ThawList.d.ts +36 -0
  340. package/dist/domain/ThawList.d.ts.map +1 -0
  341. package/dist/domain/ThawList.js +72 -0
  342. package/dist/domain/ThawList.js.map +1 -0
  343. package/dist/domain/Track.d.ts +93 -1
  344. package/dist/domain/Track.d.ts.map +1 -1
  345. package/dist/domain/Track.js +136 -0
  346. package/dist/domain/Track.js.map +1 -1
  347. package/dist/domain/TrackGroup.d.ts +0 -1
  348. package/dist/domain/TrackGroup.d.ts.map +1 -1
  349. package/dist/domain/TrackGroup.js +0 -1
  350. package/dist/domain/TrackGroup.js.map +1 -1
  351. package/dist/domain/TransportFSM.d.ts +0 -1
  352. package/dist/domain/TransportFSM.d.ts.map +1 -1
  353. package/dist/domain/TransportFSM.js +0 -1
  354. package/dist/domain/TransportFSM.js.map +1 -1
  355. package/dist/domain/TransportMode.d.ts +0 -1
  356. package/dist/domain/TransportMode.d.ts.map +1 -1
  357. package/dist/domain/TransportMode.js +0 -1
  358. package/dist/domain/TransportMode.js.map +1 -1
  359. package/dist/domain/TriggerBox.d.ts +121 -0
  360. package/dist/domain/TriggerBox.d.ts.map +1 -0
  361. package/dist/domain/TriggerBox.js +428 -0
  362. package/dist/domain/TriggerBox.js.map +1 -0
  363. package/dist/domain/VCATrack.d.ts +63 -2
  364. package/dist/domain/VCATrack.d.ts.map +1 -1
  365. package/dist/domain/VCATrack.js +127 -2
  366. package/dist/domain/VCATrack.js.map +1 -1
  367. package/dist/domain/VideoExportConfig.d.ts +116 -0
  368. package/dist/domain/VideoExportConfig.d.ts.map +1 -0
  369. package/dist/domain/VideoExportConfig.js +243 -0
  370. package/dist/domain/VideoExportConfig.js.map +1 -0
  371. package/dist/domain/VideoExportStatus.d.ts +89 -0
  372. package/dist/domain/VideoExportStatus.d.ts.map +1 -0
  373. package/dist/domain/VideoExportStatus.js +192 -0
  374. package/dist/domain/VideoExportStatus.js.map +1 -0
  375. package/dist/domain/VideoMetadata.d.ts +46 -0
  376. package/dist/domain/VideoMetadata.d.ts.map +1 -0
  377. package/dist/domain/VideoMetadata.js +2 -0
  378. package/dist/domain/VideoMetadata.js.map +1 -0
  379. package/dist/domain/ZoomFocus.d.ts +0 -1
  380. package/dist/domain/ZoomFocus.d.ts.map +1 -1
  381. package/dist/domain/ZoomFocus.js +0 -1
  382. package/dist/domain/ZoomFocus.js.map +1 -1
  383. package/dist/domain/index.d.ts +5 -0
  384. package/dist/domain/index.d.ts.map +1 -1
  385. package/dist/domain/index.js +5 -0
  386. package/dist/domain/index.js.map +1 -1
  387. package/dist/domain/temporal/TempoMap.d.ts +198 -2
  388. package/dist/domain/temporal/TempoMap.d.ts.map +1 -1
  389. package/dist/domain/temporal/TempoMap.js +464 -30
  390. package/dist/domain/temporal/TempoMap.js.map +1 -1
  391. package/dist/domain/temporal/types.d.ts +1 -1
  392. package/dist/domain/temporal/types.d.ts.map +1 -1
  393. package/dist/domain/temporal/types.js +1 -1
  394. package/dist/domain/temporal/types.js.map +1 -1
  395. package/dist/index.d.ts +43 -1
  396. package/dist/index.d.ts.map +1 -1
  397. package/dist/index.js +32 -1
  398. package/dist/index.js.map +1 -1
  399. package/dist/lib/Signal.d.ts +1 -1
  400. package/dist/lib/ThawList.d.ts +98 -0
  401. package/dist/lib/ThawList.d.ts.map +1 -0
  402. package/dist/lib/ThawList.js +151 -0
  403. package/dist/lib/ThawList.js.map +1 -0
  404. package/dist/midi/MidiFileParser.d.ts +32 -0
  405. package/dist/midi/MidiFileParser.d.ts.map +1 -0
  406. package/dist/midi/MidiFileParser.js +245 -0
  407. package/dist/midi/MidiFileParser.js.map +1 -0
  408. package/dist/midi/MidiFileWriter.d.ts +30 -0
  409. package/dist/midi/MidiFileWriter.d.ts.map +1 -0
  410. package/dist/midi/MidiFileWriter.js +159 -0
  411. package/dist/midi/MidiFileWriter.js.map +1 -0
  412. package/dist/midi/MidiImporter.d.ts +37 -0
  413. package/dist/midi/MidiImporter.d.ts.map +1 -0
  414. package/dist/midi/MidiImporter.js +62 -0
  415. package/dist/midi/MidiImporter.js.map +1 -0
  416. package/dist/plugins/PluginManager.js +2 -2
  417. package/dist/plugins/PluginManager.js.map +1 -1
  418. package/dist/plugins/PluginPresetManager.d.ts +86 -0
  419. package/dist/plugins/PluginPresetManager.d.ts.map +1 -0
  420. package/dist/plugins/PluginPresetManager.js +140 -0
  421. package/dist/plugins/PluginPresetManager.js.map +1 -0
  422. package/dist/plugins/impl/ExpanderPlugin.d.ts +1 -1
  423. package/dist/plugins/impl/ExpanderPlugin.js +1 -1
  424. package/dist/plugins/impl/ParametricEQPlugin.d.ts +1 -1
  425. package/dist/plugins/impl/ParametricEQPlugin.js +1 -1
  426. package/dist/processing/IO.d.ts +15 -1
  427. package/dist/processing/IO.d.ts.map +1 -1
  428. package/dist/processing/IO.js +29 -1
  429. package/dist/processing/IO.js.map +1 -1
  430. package/dist/processing/InternalSend.d.ts +102 -0
  431. package/dist/processing/InternalSend.d.ts.map +1 -0
  432. package/dist/processing/InternalSend.js +175 -0
  433. package/dist/processing/InternalSend.js.map +1 -0
  434. package/dist/processing/MeterDSP.d.ts +165 -0
  435. package/dist/processing/MeterDSP.d.ts.map +1 -0
  436. package/dist/processing/MeterDSP.js +753 -0
  437. package/dist/processing/MeterDSP.js.map +1 -0
  438. package/dist/processing/MeterProcessor.d.ts +0 -1
  439. package/dist/processing/MeterProcessor.d.ts.map +1 -1
  440. package/dist/processing/MeterProcessor.js +0 -1
  441. package/dist/processing/MeterProcessor.js.map +1 -1
  442. package/dist/processing/Panner.d.ts +144 -0
  443. package/dist/processing/Panner.d.ts.map +1 -0
  444. package/dist/processing/Panner.js +280 -0
  445. package/dist/processing/Panner.js.map +1 -0
  446. package/dist/processing/PluginInsert.d.ts +56 -1
  447. package/dist/processing/PluginInsert.d.ts.map +1 -1
  448. package/dist/processing/PluginInsert.js +180 -2
  449. package/dist/processing/PluginInsert.js.map +1 -1
  450. package/dist/processing/PolarityProcessor.d.ts +1 -1
  451. package/dist/processing/PolarityProcessor.js +1 -1
  452. package/dist/processing/Processor.d.ts +38 -0
  453. package/dist/processing/Processor.d.ts.map +1 -1
  454. package/dist/processing/Processor.js +60 -1
  455. package/dist/processing/Processor.js.map +1 -1
  456. package/dist/processing/SendProcessor.d.ts +0 -1
  457. package/dist/processing/SendProcessor.d.ts.map +1 -1
  458. package/dist/processing/SendProcessor.js +0 -1
  459. package/dist/processing/SendProcessor.js.map +1 -1
  460. package/dist/processing/SurroundPanner.d.ts +120 -0
  461. package/dist/processing/SurroundPanner.d.ts.map +1 -0
  462. package/dist/processing/SurroundPanner.js +374 -0
  463. package/dist/processing/SurroundPanner.js.map +1 -0
  464. package/dist/processing/TruePeakLimiter.d.ts +32 -0
  465. package/dist/processing/TruePeakLimiter.d.ts.map +1 -0
  466. package/dist/processing/TruePeakLimiter.js +142 -0
  467. package/dist/processing/TruePeakLimiter.js.map +1 -0
  468. package/dist/storage/ExportPresetStorage.d.ts +33 -0
  469. package/dist/storage/ExportPresetStorage.d.ts.map +1 -0
  470. package/dist/storage/ExportPresetStorage.js +121 -0
  471. package/dist/storage/ExportPresetStorage.js.map +1 -0
  472. package/dist/storage/SessionArchive.d.ts +73 -0
  473. package/dist/storage/SessionArchive.d.ts.map +1 -0
  474. package/dist/storage/SessionArchive.js +211 -0
  475. package/dist/storage/SessionArchive.js.map +1 -0
  476. package/dist/storage/SessionStorage.d.ts +1 -1
  477. package/dist/storage/SessionTemplate.d.ts +74 -5
  478. package/dist/storage/SessionTemplate.d.ts.map +1 -1
  479. package/dist/storage/SessionTemplate.js +247 -53
  480. package/dist/storage/SessionTemplate.js.map +1 -1
  481. package/dist/utils/BwfMetadataWriter.d.ts +41 -0
  482. package/dist/utils/BwfMetadataWriter.d.ts.map +1 -0
  483. package/dist/utils/BwfMetadataWriter.js +130 -0
  484. package/dist/utils/BwfMetadataWriter.js.map +1 -0
  485. package/dist/utils/DitherProcessor.d.ts +0 -1
  486. package/dist/utils/DitherProcessor.d.ts.map +1 -1
  487. package/dist/utils/DitherProcessor.js +0 -1
  488. package/dist/utils/DitherProcessor.js.map +1 -1
  489. package/dist/utils/FilenameTemplate.d.ts +39 -0
  490. package/dist/utils/FilenameTemplate.d.ts.map +1 -0
  491. package/dist/utils/FilenameTemplate.js +77 -0
  492. package/dist/utils/FilenameTemplate.js.map +1 -0
  493. package/dist/utils/FlacEncoder.d.ts +0 -1
  494. package/dist/utils/FlacEncoder.d.ts.map +1 -1
  495. package/dist/utils/FlacEncoder.js +0 -1
  496. package/dist/utils/FlacEncoder.js.map +1 -1
  497. package/dist/utils/Logger.d.ts +28 -0
  498. package/dist/utils/Logger.d.ts.map +1 -0
  499. package/dist/utils/Logger.js +46 -0
  500. package/dist/utils/Logger.js.map +1 -0
  501. package/dist/utils/Mp4ChapterGenerator.d.ts +16 -0
  502. package/dist/utils/Mp4ChapterGenerator.d.ts.map +1 -0
  503. package/dist/utils/Mp4ChapterGenerator.js +32 -0
  504. package/dist/utils/Mp4ChapterGenerator.js.map +1 -0
  505. package/dist/utils/OggEncoder.d.ts +19 -21
  506. package/dist/utils/OggEncoder.d.ts.map +1 -1
  507. package/dist/utils/OggEncoder.js +113 -51
  508. package/dist/utils/OggEncoder.js.map +1 -1
  509. package/dist/utils/TocGenerator.d.ts +16 -0
  510. package/dist/utils/TocGenerator.d.ts.map +1 -0
  511. package/dist/utils/TocGenerator.js +46 -0
  512. package/dist/utils/TocGenerator.js.map +1 -0
  513. package/package.json +7 -8
package/README.md CHANGED
@@ -1,316 +1,734 @@
1
- # @drop-ai/core
2
-
3
- drop.ai DAW 헤드리스 코어 라이브러리. 오디오 편집 도메인 로직, 커맨드 시스템, 오토메이션, 플러그인, MIDI UI 독립적인 모든 기능을 포함한다.
4
-
5
- ## 왜 분리했는가
6
-
7
- 기존에는 `src/core/`에 있던 코어 로직이 Next.js 앱과 같은 디렉토리에 섞여 있었다. 문제점:
8
-
9
- - **Tone.js 커플링**: `AudioEngine`이 `ToneAudioProvider`를 직접 import하여 브라우저 없이 사용 불가
10
- - **Zustand 커플링**: `EditorHandler`, `defaultActions`, `dawQueryTool`이 `useDAWStore`를 직접 import
11
- - **테스트 격리 불가**: Node.js CLI나 headless 환경에서 코어 로직만 테스트하기 어려움
12
- - **재사용 불가**: 다른 프레임워크(Electron, React Native 등)에서 코어 로직 사용 불가
13
-
14
- 분리 후:
15
-
16
- - `@drop-ai/core`는 **브라우저/프레임워크 의존성 제로**
17
- - Node.js CLI, 테스트, 다른 프레임워크에서 독립적으로 사용 가능
18
- - 향후 npm publish 가능
19
-
20
- ## 아키텍처
21
-
22
- ```
23
- ┌─────────────────────────────────────────────────────────┐
24
- │ Next.js App (src/) │
25
- │ ┌──────────┐ ┌──────────────┐ ┌──────────────────────┐ │
26
- │Components│ │ Stores │ │ App-level modules │ │
27
- │(React) │ │ (Zustand) │ │ - ToneAudioProvider │ │
28
- │ │ │ useDAWStore │ │ - EditorHandler │ │
29
- │ │ │ │ │ - defaultActions │ │
30
- │ │ │ │ │ - dawQueryTool │ │
31
- └────┬─────┘ └──────┬───────┘ └──────────┬───────────┘ │
32
- │ │ │ │ │
33
- │ └──────────────┼─────────────────────┘ │
34
- │ │ │
35
- ├──────────────────────┼───────────────────────────────────┤
36
- │ ▼ │
37
- │ @drop-ai/core (packages/core/) │
38
- │ ┌────────┐ ┌────────┐ ┌──────────┐ ┌────────────────┐ │
39
- │ │Domain │ │Commands│ │Audio │ │Automation │ │
40
- │ │Session │Executor│ │Engine │ │List, Curve, │ │
41
- │ │Track │ │History │ │Backend(I)│ │Mode │ │
42
- │ │Region │ │55 Impls│ │Exporter │ └────────────────┘ │
43
- │ │Playlist│ │15 Hdlrs│ │Meter │ ┌────────────────┐ │
44
- │ │Source │ └────────┘ └──────────┘ │Plugins │ │
45
- │ │Range │ ┌────────┐ ┌──────────┐ │EQ, Reverb, │ │
46
- │ │Marker │ │Lib │ │Processing│ │Compressor, ... │ │
47
- │MIDI │ │Signal │ │Gain, Pan │ └────────────────┘ │
48
- └────────┘ └────────┘ └──────────┘ │
49
- └─────────────────────────────────────────────────────────┘
50
- ```
51
-
52
- ## 모듈 구조 (193 파일)
53
-
54
- ### `domain/` — 도메인 모델 (42 파일)
55
-
56
- DAW의 핵심 데이터 구조. Ardour의 도메인 모델을 참고하여 설계됨.
57
-
58
- | 클래스 | 설명 |
59
- |--------|------|
60
- | `Session` | 프로젝트 루트. 트랙, 소스, 마커, 레인지, 템포맵 관리 |
61
- | `Track` | 오디오/MIDI/Bus/AUX 트랙. Route(IO + 프로세서 체인) 포함 |
62
- | `Region` | 타임라인 위의 오디오 구간. start, length, sourceStart, fades |
63
- | `Playlist` | 트랙 Region 컬렉션. 레이어, 크로스페이드 지원 |
64
- | `Source` | 오디오 파일 참조. URL, duration, sampleRate |
65
- | `Range` | 루프/펀치/선택 범위 (start, end) |
66
- | `Marker` | 타임라인 마커 (위치 + 이름) |
67
- | `MidiNote` / `MidiRegion` | MIDI 데이터 |
68
- | `SendBus` | 센드 버스 (pre/post fader) |
69
- | `GridSettings` | 그리드 타입, 스냅 모드 |
70
- | `TempoMap` | BPM 변경 이벤트 관리 |
71
- | `CrossfadeEngine` | 리전 겹침 시 자동 크로스페이드 계산 |
72
- | `TransportFSM` | 재생/정지/녹음 상태 머신 |
73
- | `MixerScene` | 믹서 스냅샷 저장/불러오기 |
74
-
75
- 모든 도메인 객체는 `Signal` 기반 이벤트를 발행한다:
76
- ```typescript
77
- session.trackAdded.connect((track: Track) => { ... });
78
- session.tempoChanged.connect((bpm: number) => { ... });
79
- track.muteChanged.connect((muted: boolean) => { ... });
80
- ```
81
-
82
- ### `commands/` — 커맨드 시스템 (62 파일)
83
-
84
- Undo/Redo 지원 커맨드 패턴 구현.
85
-
86
- - **`CommandExecutor`**: Zod 스키마 검증 → 핸들러 라우팅 → 실행. 싱글톤.
87
- - **`CommandHistory`**: Undo/Redo 스택 관리. depth 설정 가능.
88
- - **15개 핸들러**: Transport, Track, Region, Range, Automation, Export, IO, SendBus, Session, Marker, Midi, MixerScene, TrackGroup, History + 앱에서 등록하는 EditorHandler
89
- - **55개 커맨드 구현체**: AddTrack, MoveRegion, SplitAtPlayhead, SetTrackVolume 등
90
-
91
- ```typescript
92
- // 커맨드 실행
93
- await CommandExecutor.getInstance().execute({
94
- type: CommandType.ADD_TRACK,
95
- payload: { name: 'Vocals', trackType: 'audio' }
96
- });
97
-
98
- // 앱에서 커스텀 핸들러 등록
99
- CommandExecutor.getInstance().registerHandler(new EditorHandler());
100
- ```
101
-
102
- ### `audio/` — 오디오 엔진 (10 파일)
103
-
104
- - **`AudioEngine`**: 세션과 백엔드를 연결하는 중앙 컨트롤러. 싱글톤.
105
- - 트랜스포트 (play/stop/pause/seek)
106
- - 녹음 (audio + MIDI, 펀치, 루프 레코딩)
107
- - 미터링 (peak/RMS/LUFS)
108
- - 프로세서 체인 동기화
109
- - **`AudioProvider`**: 인터페이스. 실제 오디오 I/O 추상화.
110
- - 앱: `ToneAudioProvider` (Tone.js + Web Audio API)
111
- - CLI: `HeadlessAudioProvider`
112
- - 테스트: `MockAudioProvider`
113
- - **`OfflineExporter`**: WAV/MP3/OGG/FLAC 오프라인 렌더링
114
- - **`PlaylistEngine`**: 샘플 정확도 리전 렌더링 (AudioWorklet용)
115
-
116
- ```typescript
117
- // 백엔드 주입 (Dependency Injection)
118
- const engine = AudioEngine.getInstance(new ToneAudioProvider());
119
-
120
- // 또는 headless 환경
121
- const engine = AudioEngine.getInstance(new HeadlessAudioProvider());
122
- ```
123
-
124
- ### `automation/` — 오토메이션 (6 파일)
125
-
126
- | 클래스 | 설명 |
127
- |--------|------|
128
- | `AutomationList` | 파라미터별 오토메이션 포인트 컬렉션 |
129
- | `AutomationCurve` | 보간 (linear, exponential, s-curve) |
130
- | `AutomationMode` | Read, Write, Touch, Latch |
131
- | `PointThinning` | 실시간 녹음 시 포인트 간소화 |
132
- | `ParameterDescriptor` | 파라미터 메타데이터 (min, max, default) |
133
-
134
- ### `plugins/` — 플러그인 시스템 (16 파일)
135
-
136
- 내장 오디오 플러그인:
137
-
138
- | 플러그인 | 설명 |
139
- |----------|------|
140
- | `ParametricEQPlugin` | 6밴드 파라메트릭 EQ |
141
- | `MultibandCompressorPlugin` | 멀티밴드 컴프레서 |
142
- | `ConvolutionReverbPlugin` | 컨볼루션 리버브 |
143
- | `SyncDelayPlugin` | BPM 동기 딜레이 |
144
- | `TapeSaturationPlugin` | 테이프 새추레이션 |
145
- | `DeEsserPlugin` | 디에서 |
146
- | `ExpanderPlugin` | 익스팬더/게이트 |
147
- | `PhaserPlugin` | 페이저 |
148
- | `TremoloPlugin` | 트레몰로 |
149
- | `VibratoPlugin` | 비브라토 |
150
- | `AutoPanPlugin` | 오토 팬 |
151
-
152
- `PluginManager`로 등록/생성:
153
- ```typescript
154
- const manager = PluginManager.getInstance();
155
- const eq = manager.createPlugin('internal-parametric-eq');
156
- ```
157
-
158
- ### `processing/` 신호 처리 체인 (8 파일)
159
-
160
- Route(트랙 프로세서 체인)를 구성하는 프로세서들:
161
-
162
- - `GainProcessor` (Fader / Trim)
163
- - `PanProcessor` (스테레오 패닝 + 폭 조절)
164
- - `PolarityProcessor` (위상 반전)
165
- - `SendProcessor` (Pre/Post fader 센드)
166
- - `MeterProcessor` (피크/RMS 미터링)
167
- - `PluginInsert` (플러그인 삽입 슬롯)
168
-
169
- ### `lib/` — 유틸리티
170
-
171
- - **`Signal<T>`**: 타입 안전 이벤트 시스템. Qt의 Signal/Slot 패턴.
172
-
173
- ```typescript
174
- const signal = new Signal<number>();
175
- const sub = signal.connect((value) => console.log(value));
176
- signal.emit(42);
177
- sub.dispose(); // 구독 해제
178
- ```
179
-
180
- ### `actions/` — 액션 레지스트리 (2 파일)
181
-
182
- 키보드 단축키 ↔ 커맨드 매핑 시스템.
183
-
184
- - `ActionRegistry`: 액션 등록/조회/실행
185
- - `ActionDefinition`: id, label, category, defaultKey, commandFactory
186
-
187
- ```typescript
188
- const registry = ActionRegistry.getInstance();
189
- registry.registerDefaults(defaultActions); // 앱에서 등록
190
- await registry.execute('transport.togglePlay');
191
- ```
192
-
193
- ### `preferences/` 설정 (3 파일)
194
-
195
- - `Preferences`: 싱글톤. audioBufferSize, sampleRate, theme, gridSubdivision 등
196
- - `KeyBindings`: 커스텀 키 바인딩 오버라이드
197
-
198
- ### `storage/` — 세션 저장 (3 파일)
199
-
200
- - `SessionStorage`: IndexedDB/localStorage 기반 세션 저장/불러오기
201
- - `AutoSave`: 주기적 자동 저장
202
- - `SessionTemplate`: 세션 템플릿
203
-
204
- ### `ai/` AI 에이전트 (5 파일)
205
-
206
- - `DAWAgent`: LLM 기반 DAW 제어 에이전트
207
- - `dawCommandTool`: AI가 커맨드를 실행하는 도구
208
- - `dawSystemPrompt`: DAW 컨텍스트 시스템 프롬프트
209
-
210
- ## 앱에서의 사용법
211
-
212
- ### 부트스트랩 (useDAWStore.init)
213
-
214
- ```typescript
215
- import { AudioEngine } from '@drop-ai/core/audio/AudioEngine';
216
- import { CommandExecutor } from '@drop-ai/core/commands/CommandExecutor';
217
- import { ActionRegistry } from '@drop-ai/core/actions/ActionRegistry';
218
- import { ToneAudioProvider } from '../audio/ToneAudioProvider';
219
- import { EditorHandler } from '../app-commands/EditorHandler';
220
- import { defaultActions } from '../app-actions/defaultActions';
221
-
222
- // 1. 오디오 백엔드 주입
223
- AudioEngine.getInstance(new ToneAudioProvider());
224
-
225
- // 2. 앱 전용 커맨드 핸들러 등록
226
- CommandExecutor.getInstance().registerHandler(new EditorHandler());
227
-
228
- // 3. 기본 액션(키보드 단축키) 등록
229
- ActionRegistry.getInstance().registerDefaults(defaultActions);
230
- ```
231
-
232
- ### Import 패턴
233
-
234
- ```typescript
235
- // barrel import (주요 타입)
236
- import { Session, Track, Region, AudioEngine } from '@drop-ai/core';
237
-
238
- // deep import (특정 모듈)
239
- import { AudioEngine } from '@drop-ai/core/audio/AudioEngine';
240
- import { CommandType } from '@drop-ai/core/commands/types';
241
- import { Signal } from '@drop-ai/core/lib/Signal';
242
- import { TempoMap } from '@drop-ai/core/domain/temporal/TempoMap';
243
- ```
244
-
245
- ## 앱 쪽에 남긴 파일 (7개)
246
-
247
- 브라우저/스토어 의존성 때문에 코어에 포함할 없는 파일들:
248
-
249
- | 파일 | 위치 | 이유 |
250
- |------|------|------|
251
- | `ToneAudioProvider.ts` | `src/audio/` | Tone.js + browser AudioContext |
252
- | `ToneTrack.ts` | `src/audio/` | Tone.js import |
253
- | `TrackProcessor.ts` | `src/audio/worklets/` | AudioWorklet browser API |
254
- | `TimeStretchProcessor.ts` | `src/audio/` | soundtouchjs + OfflineAudioContext |
255
- | `defaultActions.ts` | `src/app-actions/` | useDAWStore import |
256
- | `EditorHandler.ts` | `src/app-commands/` | useDAWStore import |
257
- | `dawQueryTool.ts` | `src/app-ai/` | useDAWStore import |
258
-
259
- ## 디커플링 요약
260
-
261
- | 변경 | Before | After |
262
- |------|--------|-------|
263
- | `AudioEngine` | `ToneAudioProvider` 하드코딩 | 백엔드 주입 필수 (DI) |
264
- | `CommandExecutor` | `EditorHandler` 내장 | `registerHandler()` API |
265
- | `ActionRegistry` | `defaultActions` 자동 로드 | `registerDefaults()` API |
266
- | `KeyBindings` / `Preferences` | `localStorage` 직접 접근 | `typeof localStorage` 가드 |
267
- | `ExportHandler` | `document.createElement` 직접 호출 | `typeof document` 가드 |
268
- | `ai/tools` | `dawQueryTool` 내장 | 앱에서 별도 관리 |
269
-
270
- ## 설정 파일
271
-
272
- ### pnpm-workspace.yaml
273
- ```yaml
274
- packages:
275
- - "packages/*"
276
- ```
277
-
278
- ### 루트 package.json (의존성)
279
- ```json
280
- {
281
- "dependencies": {
282
- "@drop-ai/core": "workspace:*"
283
- }
284
- }
285
- ```
286
-
287
- ### 루트 tsconfig.json (paths)
288
- ```json
289
- {
290
- "paths": {
291
- "@/*": ["./*"],
292
- "@drop-ai/core": ["./packages/core/src"],
293
- "@drop-ai/core/*": ["./packages/core/src/*"]
294
- }
295
- }
296
- ```
297
-
298
- ## 테스트
299
-
300
- ```bash
301
- # 전체 단위 테스트 (308개)
302
- pnpm test
303
-
304
- # 코어 패키지 타입 체크
305
- cd packages/core && npx tsc --noEmit
306
-
307
- # 루트 프로젝트 타입 체크
308
- npx tsc --noEmit
309
- ```
310
-
311
- ## 향후 계획
312
-
313
- - [ ] `packages/core/` 빌드 파이프라인 (`tsc` `dist/`)
314
- - [ ] npm publish (`private: false`)
315
- - [ ] Electron 앱에서 `@drop-ai/core` 재사용
316
- - [ ] 코어 전용 단위 테스트 (`packages/core/test/`)
1
+ # drop-daw
2
+
3
+ Headless DAW (Digital Audio Workstation) engine for TypeScript/JavaScript. Provides domain models, command system, audio engine, automation, plugins, and MIDI all with zero browser or framework dependencies.
4
+
5
+ ```bash
6
+ npm install drop-daw
7
+ ```
8
+
9
+ ## Features
10
+
11
+ - **Headless** No browser, no React, no framework required. Runs in Node.js, Electron, or any JS runtime.
12
+ - **Command Pattern** All mutations go through `CommandExecutor` with built-in Undo/Redo.
13
+ - **Dependency Injection** — Bring your own audio backend via the `AudioProvider` interface.
14
+ - **60+ Commands** — Transport, tracks, regions, automation, plugins, MIDI, markers, ranges, export.
15
+ - **20+ Built-in Plugins** — EQ, compressor, reverb, delay, saturation, de-esser, and more.
16
+ - **Signal-based Events** Type-safe reactive event system (Qt Signal/Slot pattern).
17
+ - **Serialization** Full session save/load with JSON snapshots.
18
+ - **TypeScript-first** Complete type definitions included.
19
+
20
+ ---
21
+
22
+ ## Quick Start
23
+
24
+ ```typescript
25
+ import {
26
+ AudioEngine,
27
+ Session,
28
+ Track,
29
+ TrackType,
30
+ CommandExecutor,
31
+ CommandType,
32
+ } from 'drop-daw';
33
+
34
+ // 1. Implement AudioProvider interface for your platform
35
+ class MyAudioBackend implements AudioProvider {
36
+ // ... implement the interface methods
37
+ }
38
+
39
+ // 2. Initialize the engine with your backend
40
+ const engine = AudioEngine.getInstance(new MyAudioBackend());
41
+
42
+ // 3. Work with the session directly
43
+ const track = engine.session.addTrack('Vocals', TrackType.AUDIO);
44
+
45
+ // 4. Or use the command system (with undo/redo support)
46
+ await CommandExecutor.getInstance().execute({
47
+ type: CommandType.ADD_TRACK,
48
+ payload: { name: 'Guitar', trackType: 'audio' },
49
+ });
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Architecture
55
+
56
+ ```
57
+ ┌──────────────────────────────────────────────────┐
58
+ │ Your App │
59
+ │ (React, Electron, Node.js CLI, etc.) │
60
+ │ │
61
+ │ ┌─────────────┐ ┌────────────────────────────┐
62
+ │ │ UI Layer │ │ AudioProvider (impl) │
63
+ │ │ (optional) │ │ e.g. Web Audio, PortAudio │
64
+ │ └──────┬──────┘ └─────────────┬──────────────┘
65
+ ├─────────┼───────────────────────┼────────────────┤
66
+ │ ▼ ▼ │
67
+ │ ┌─────────────┐ ┌────────────────────────────┐
68
+ │ │ Command │ │ AudioEngine │
69
+ │ │ Executor │ │ (session + backend) │
70
+ │ └──────┬──────┘ └────────────────────────────┘
71
+ │ ▼ │
72
+ │ ┌───────────────────────────────────────┐ │
73
+ │ │ Domain Layer │ │
74
+ │ │ Session → Track → Playlist → Region │ │
75
+ │ │ Automation, Plugins, MIDI, Markers │ │
76
+ │ └───────────────────────────────────────┘ │
77
+ │ │
78
+ │ drop-daw │
79
+ └──────────────────────────────────────────────────┘
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Core Concepts
85
+
86
+ ### Session
87
+
88
+ The root container for a DAW project. Manages tracks, sources, markers, ranges, tempo, and transport state.
89
+
90
+ ```typescript
91
+ import { Session, TrackType } from 'drop-daw';
92
+
93
+ const session = new Session('My Song', undefined, 44100);
94
+
95
+ // Tracks
96
+ const vocal = session.addTrack('Vocals', TrackType.AUDIO);
97
+ const bass = session.addTrack('Bass', TrackType.AUDIO);
98
+ const synth = session.addTrack('Synth', TrackType.MIDI);
99
+ const reverb = session.addAuxTrack('Reverb Bus');
100
+
101
+ // Transport
102
+ session.setTempo(120);
103
+ session.setTimeSignature(4, 4);
104
+
105
+ // Markers
106
+ session.addMarker('Chorus', 44100 * 30); // at 30 seconds
107
+
108
+ // Ranges
109
+ const loopRange = session.addRange('Loop A', 44100 * 10, 44100 * 20);
110
+ session.setLoopRange(loopRange.id);
111
+ session.setLoopEnabled(true);
112
+
113
+ // Serialization
114
+ const snapshot = session.toJSON();
115
+ const restored = Session.fromJSON(snapshot);
116
+ ```
117
+
118
+ ### Track
119
+
120
+ Represents an audio, MIDI, aux, bus, folder, or VCA track. Each track has a `Route` (signal chain) and a `Playlist` (region container).
121
+
122
+ ```typescript
123
+ const track = session.addTrack('Lead Guitar', TrackType.AUDIO);
124
+
125
+ track.setMute(false);
126
+ track.setSolo(true);
127
+ track.setArmed(true);
128
+ track.setColor('#ff6b6b');
129
+ track.setMonitorMode(MonitorMode.AUTO);
130
+
131
+ // React to changes
132
+ track.muteChanged.connect((muted) => console.log('Mute:', muted));
133
+ track.soloChanged.connect((soloed) => console.log('Solo:', soloed));
134
+ ```
135
+
136
+ **Track Types:**
137
+
138
+ | Type | Description |
139
+ |------|-------------|
140
+ | `AUDIO` | Standard audio track with region playback |
141
+ | `MIDI` | MIDI track with note data and virtual instruments |
142
+ | `AUX` | Auxiliary bus for send effects (reverb, delay) |
143
+ | `BUS` | Mix bus for subgroup routing |
144
+ | `FOLDER` | Folder track for organizing child tracks |
145
+ | `VCA` | VCA fader for linked level control |
146
+
147
+ ### Region
148
+
149
+ A segment of audio on the timeline, referencing a `Source`.
150
+
151
+ ```typescript
152
+ import { Region } from 'drop-daw';
153
+
154
+ const region = new Region(
155
+ 'region-1', // id
156
+ 'source-1', // sourceId
157
+ 0, // start (frames)
158
+ 44100 * 10, // length (10 seconds at 44.1kHz)
159
+ 0, // sourceStart
160
+ 'Vocal Take 1' // name
161
+ );
162
+
163
+ region.setFadeIn(4410); // 100ms fade in
164
+ region.setFadeOut(4410); // 100ms fade out
165
+ region.move(44100 * 5); // move to 5 seconds
166
+ region.resize(44100 * 8); // resize to 8 seconds
167
+ ```
168
+
169
+ ### AudioEngine
170
+
171
+ Central controller connecting the session to an audio backend. Uses the singleton pattern with dependency injection.
172
+
173
+ ```typescript
174
+ import { AudioEngine, AudioProvider } from 'drop-daw';
175
+
176
+ // Initialize with your backend implementation
177
+ const engine = AudioEngine.getInstance(myBackend);
178
+ await engine.initialize();
179
+
180
+ // Transport
181
+ await engine.start();
182
+ engine.pause();
183
+ engine.seek(10.5); // seek to 10.5 seconds
184
+ engine.stop();
185
+
186
+ // Metering
187
+ const meter = engine.getMeterData('track-1');
188
+ console.log('Peak:', meter.peak, 'RMS:', meter.rms);
189
+
190
+ // Export
191
+ await engine.exportAudio(engine.getExportConfig(), engine.getExportStatus());
192
+
193
+ // Swap backend at runtime
194
+ engine.setBackend(new DifferentBackend());
195
+ ```
196
+
197
+ ### AudioProvider Interface
198
+
199
+ Implement this interface to connect drop-daw to any audio system.
200
+
201
+ ```typescript
202
+ import { AudioProvider } from 'drop-daw';
203
+
204
+ class WebAudioBackend implements AudioProvider {
205
+ async initialize(): Promise<void> { /* ... */ }
206
+
207
+ // Transport
208
+ start(): void { /* ... */ }
209
+ stop(): void { /* ... */ }
210
+ pause(): void { /* ... */ }
211
+ seek(time: number): void { /* ... */ }
212
+
213
+ // Track management
214
+ createTrack(trackId, name, inputId, outputId): void { /* ... */ }
215
+ deleteTrack(trackId): void { /* ... */ }
216
+
217
+ // Region scheduling
218
+ scheduleRegion(trackId, region): void { /* ... */ }
219
+ updateRegions(trackId, regions): void { /* ... */ }
220
+ removeRegion(trackId, regionId): void { /* ... */ }
221
+
222
+ // Metering
223
+ getMeterData(trackId): MeterData { /* ... */ }
224
+ getMasterMeterData(): MeterData { /* ... */ }
225
+
226
+ // ... and more (see full interface in source)
227
+ }
228
+ ```
229
+
230
+ **Included backend examples (in the drop.ai app, not in this package):**
231
+
232
+ | Backend | Environment | Description |
233
+ |---------|-------------|-------------|
234
+ | `ToneAudioProvider` | Browser | Tone.js + Web Audio API |
235
+ | `HeadlessAudioProvider` | Node.js | No-op backend for CLI/testing |
236
+ | `MockAudioProvider` | Test | Mock backend for unit tests |
237
+
238
+ ---
239
+
240
+ ## Command System
241
+
242
+ All state mutations can go through the command system, providing validation (via Zod), handler routing, and undo/redo support.
243
+
244
+ ### Executing Commands
245
+
246
+ ```typescript
247
+ import { CommandExecutor, CommandType } from 'drop-daw';
248
+
249
+ const executor = CommandExecutor.getInstance();
250
+
251
+ // Add a track
252
+ await executor.execute({
253
+ type: CommandType.ADD_TRACK,
254
+ payload: { name: 'Vocals', trackType: 'audio' },
255
+ });
256
+
257
+ // Set volume
258
+ await executor.execute({
259
+ type: CommandType.SET_VOLUME,
260
+ payload: { trackId: 'track-1', volume: 0.75 },
261
+ });
262
+
263
+ // Split region at playhead
264
+ await executor.execute({
265
+ type: CommandType.SPLIT_AT_PLAYHEAD,
266
+ payload: { trackId: 'track-1', frame: 44100 * 15 },
267
+ });
268
+
269
+ // Add a plugin
270
+ await executor.execute({
271
+ type: CommandType.ADD_PLUGIN,
272
+ payload: { trackId: 'track-1', pluginId: 'internal-eq6' },
273
+ });
274
+ ```
275
+
276
+ ### Undo / Redo
277
+
278
+ ```typescript
279
+ const history = executor.history;
280
+
281
+ await history.undo();
282
+ await history.redo();
283
+ await history.undoMultiple(3); // undo 3 steps
284
+
285
+ console.log(history.canUndo); // true
286
+ console.log(history.nextUndoLabel); // "Add Track"
287
+
288
+ // Transaction: group multiple commands into one undo step
289
+ history.beginTransaction('Move and resize');
290
+ // ... execute multiple commands ...
291
+ await history.commitTransaction();
292
+ ```
293
+
294
+ ### Registering Custom Handlers
295
+
296
+ ```typescript
297
+ import { CommandHandler, CommandResult } from 'drop-daw';
298
+
299
+ class MyCustomHandler implements CommandHandler {
300
+ readonly handledTypes = ['MY_CUSTOM_COMMAND'];
301
+
302
+ async execute(type: string, payload: any): Promise<CommandResult> {
303
+ // your logic here
304
+ return { success: true };
305
+ }
306
+ }
307
+
308
+ CommandExecutor.getInstance().registerHandler(new MyCustomHandler());
309
+ ```
310
+
311
+ ### Command Types
312
+
313
+ **Transport:** `PLAY`, `PAUSE`, `STOP`, `SEEK`, `SET_TEMPO`, `SET_TIME_SIGNATURE`, `TOGGLE_METRONOME`, `START_RECORDING`, `STOP_RECORDING`
314
+
315
+ **Tracks:** `ADD_TRACK`, `REMOVE_TRACK`, `SET_VOLUME`, `SET_PAN`, `MUTE_TRACK`, `SOLO_TRACK`, `ARM_TRACK`, `SET_TRACK_MONITOR`
316
+
317
+ **Regions:** `ADD_REGION`, `REMOVE_REGION`, `MOVE_REGION`, `RESIZE_REGION`, `SPLIT_AT_PLAYHEAD`, `DUPLICATE_REGION`, `COPY_REGION`, `PASTE_REGION`, `MERGE_REGIONS`, `TRIM_REGION`, `SET_REGION_FADES`, `REVERSE_REGION`, `NORMALIZE_REGION`, `STRIP_SILENCE`, `TIME_STRETCH_REGION`, `LOCK_REGION`, `GROUP_REGIONS`, `UNGROUP_REGIONS`
318
+
319
+ **Automation:** `ADD_AUTOMATION`, `MOVE_AUTOMATION_POINT`, `REMOVE_AUTOMATION_POINT`
320
+
321
+ **Plugins:** `ADD_PLUGIN`, `REMOVE_PLUGIN`, `SET_PLUGIN_PARAMETER`
322
+
323
+ **Ranges:** `ADD_RANGE`, `REMOVE_RANGE`, `SET_RANGE`, `SET_LOOP_RANGE`, `SET_PUNCH_RANGE`, `TOGGLE_LOOP`
324
+
325
+ **Markers:** `ADD_MARKER`, `REMOVE_MARKER`, `MOVE_MARKER`
326
+
327
+ **IO/Routing:** `CONNECT_IO`, `DISCONNECT_IO`, `ADD_SEND_BUS`, `REMOVE_SEND_BUS`, `SET_SEND_LEVEL`
328
+
329
+ **Session:** `EXPORT`, `NEW_SESSION`, `LOAD_SESSION`, `SAVE_SESSION`, `SAVE_SNAPSHOT`
330
+
331
+ **History:** `UNDO`, `REDO`, `SELECTION_UNDO`, `SELECTION_REDO`
332
+
333
+ ---
334
+
335
+ ## Plugins
336
+
337
+ 20+ built-in audio effect plugins, managed by `PluginManager`.
338
+
339
+ ```typescript
340
+ import { PluginManager } from 'drop-daw';
341
+
342
+ const manager = PluginManager.getInstance();
343
+
344
+ // List all available plugins
345
+ const plugins = manager.getAvailablePlugins();
346
+ plugins.forEach(p => console.log(p.id, p.name));
347
+
348
+ // Create a plugin instance
349
+ const eq = manager.createPlugin('internal-eq6');
350
+ eq.setParameter('band1-freq', 100);
351
+ eq.setParameter('band1-gain', 3.0);
352
+
353
+ // Get/set full state (presets)
354
+ const state = eq.getState();
355
+ eq.setState(state);
356
+
357
+ // React to parameter changes
358
+ eq.parameterChanged.connect(({ id, value }) => {
359
+ console.log(`${id} changed to ${value}`);
360
+ });
361
+ ```
362
+
363
+ ### Available Plugins
364
+
365
+ | ID | Name | Description |
366
+ |----|------|-------------|
367
+ | `internal-eq6` | Parametric EQ | 6-band parametric equalizer |
368
+ | `internal-compressor` | Compressor | Dynamics compressor |
369
+ | `internal-multiband-comp` | Multiband Compressor | Multi-band dynamics |
370
+ | `internal-expander` | Expander | Expander/gate |
371
+ | `internal-gate` | Gate | Noise gate |
372
+ | `internal-deesser` | De-Esser | Sibilance reduction |
373
+ | `internal-reverb` | Reverb | Algorithmic reverb |
374
+ | `internal-convolver` | Convolution Reverb | IR-based reverb |
375
+ | `internal-delay` | Delay | Simple delay |
376
+ | `internal-sync-delay` | Sync Delay | BPM-synced delay |
377
+ | `internal-chorus` | Chorus | Chorus effect |
378
+ | `internal-phaser` | Phaser | Phaser effect |
379
+ | `internal-tremolo` | Tremolo | Tremolo effect |
380
+ | `internal-vibrato` | Vibrato | Vibrato effect |
381
+ | `internal-autopan` | Auto Pan | Automatic panning |
382
+ | `internal-distortion` | Distortion | Distortion/overdrive |
383
+ | `internal-tape-sat` | Tape Saturation | Analog tape emulation |
384
+ | `internal-filter` | Filter | Multi-mode filter |
385
+ | `internal-eq3` | 3-Band EQ | Simple 3-band EQ |
386
+ | `internal-gain` | Gain | Utility gain |
387
+
388
+ ---
389
+
390
+ ## Automation
391
+
392
+ Per-parameter automation with multiple recording modes.
393
+
394
+ ```typescript
395
+ import { AutomationList, AutomationMode } from 'drop-daw';
396
+
397
+ const automation = new AutomationList();
398
+
399
+ // Add points
400
+ automation.addPoint(0, 0.5); // value 0.5 at time 0
401
+ automation.addPoint(2.0, 1.0); // value 1.0 at time 2s
402
+ automation.addPoint(4.0, 0.0); // value 0.0 at time 4s
403
+
404
+ // Read interpolated value
405
+ const value = automation.getValueAt(1.0); // ~0.75 (linear interpolation)
406
+
407
+ // Modes
408
+ automation.mode = AutomationMode.READ; // playback only
409
+ automation.mode = AutomationMode.WRITE; // overwrite
410
+ automation.mode = AutomationMode.TOUCH; // write while touching, snap back on release
411
+ automation.mode = AutomationMode.LATCH; // write while touching, hold last value
412
+
413
+ // Range operations
414
+ const copied = automation.copy(1.0, 3.0);
415
+ automation.paste(copied, 5.0);
416
+ automation.eraseRange(1.0, 3.0);
417
+ ```
418
+
419
+ ---
420
+
421
+ ## Signal (Event System)
422
+
423
+ Type-safe event emitter inspired by Qt's Signal/Slot pattern. Used throughout the domain layer.
424
+
425
+ ```typescript
426
+ import { Signal } from 'drop-daw';
427
+
428
+ const signal = new Signal<number>();
429
+
430
+ // Subscribe
431
+ const sub = signal.connect((value) => {
432
+ console.log('Received:', value);
433
+ });
434
+
435
+ // Emit
436
+ signal.emit(42); // logs "Received: 42"
437
+
438
+ // Unsubscribe
439
+ sub.dispose();
440
+
441
+ // Or disconnect by reference
442
+ const handler = (v: number) => console.log(v);
443
+ signal.connect(handler);
444
+ signal.disconnect(handler);
445
+
446
+ // Clear all listeners
447
+ signal.clear();
448
+ ```
449
+
450
+ ### Common Signals
451
+
452
+ ```typescript
453
+ // Session
454
+ session.trackAdded.connect((track) => { /* ... */ });
455
+ session.trackRemoved.connect((trackId) => { /* ... */ });
456
+ session.tempoChanged.connect((bpm) => { /* ... */ });
457
+ session.playingChanged.connect((isPlaying) => { /* ... */ });
458
+ session.selectionChanged.connect((selectedIds) => { /* ... */ });
459
+ session.markerAdded.connect((marker) => { /* ... */ });
460
+
461
+ // Track
462
+ track.muteChanged.connect((muted) => { /* ... */ });
463
+ track.soloChanged.connect((soloed) => { /* ... */ });
464
+ track.armChanged.connect((armed) => { /* ... */ });
465
+
466
+ // CommandExecutor
467
+ executor.commandExecuted.connect(({ type, payload }) => { /* ... */ });
468
+
469
+ // CommandHistory
470
+ history.historyChanged.connect(() => { /* ... */ });
471
+ ```
472
+
473
+ ---
474
+
475
+ ## Actions & Key Bindings
476
+
477
+ Map keyboard shortcuts to commands.
478
+
479
+ ```typescript
480
+ import { ActionRegistry, ActionCategory } from 'drop-daw';
481
+
482
+ const registry = ActionRegistry.getInstance();
483
+
484
+ // Register default actions (typically done at app bootstrap)
485
+ registry.registerDefaults([
486
+ {
487
+ id: 'transport.play',
488
+ label: 'Play/Pause',
489
+ category: ActionCategory.TRANSPORT,
490
+ defaultKey: 'Space',
491
+ commandFactory: () => ({ type: CommandType.PLAY, payload: {} }),
492
+ },
493
+ {
494
+ id: 'edit.undo',
495
+ label: 'Undo',
496
+ category: ActionCategory.EDIT,
497
+ defaultKey: 'Ctrl+Z',
498
+ commandFactory: () => ({ type: CommandType.UNDO, payload: {} }),
499
+ },
500
+ ]);
501
+
502
+ // Execute by action ID
503
+ await registry.execute('transport.play');
504
+
505
+ // Query
506
+ const actions = registry.getActionsByCategory();
507
+ const key = registry.getEffectiveKey('transport.play'); // 'Space'
508
+ ```
509
+
510
+ ### Custom Key Bindings
511
+
512
+ ```typescript
513
+ import { KeyBindings } from 'drop-daw';
514
+
515
+ const bindings = KeyBindings.getInstance();
516
+
517
+ bindings.setBinding('transport.play', 'Enter');
518
+ bindings.getBinding('transport.play'); // 'Enter'
519
+ bindings.removeBinding('transport.play'); // back to default
520
+ bindings.resetToDefaults();
521
+ ```
522
+
523
+ ---
524
+
525
+ ## Preferences
526
+
527
+ Persistent settings with defaults.
528
+
529
+ ```typescript
530
+ import { Preferences } from 'drop-daw';
531
+
532
+ const prefs = Preferences.getInstance();
533
+
534
+ prefs.set('sampleRate', 48000);
535
+ prefs.set('audioBufferSize', 256);
536
+ prefs.set('theme', 'dark');
537
+ prefs.set('snapToGrid', true);
538
+ prefs.set('historyDepth', 100);
539
+
540
+ const sr = prefs.get('sampleRate'); // 48000
541
+
542
+ // React to changes
543
+ prefs.preferenceChanged.connect(() => {
544
+ console.log('Settings updated');
545
+ });
546
+
547
+ // Reset
548
+ prefs.resetToDefaults();
549
+ ```
550
+
551
+ **Available Keys:** `audioBufferSize`, `sampleRate`, `theme`, `autoSaveInterval`, `snapToGrid`, `gridSubdivision`, `meterType`, `showMinimap`, `followPlayhead`, `countInBars`, `historyDepth`, `saveHistory`, `saveHistoryDepth`
552
+
553
+ ---
554
+
555
+ ## Storage
556
+
557
+ Session persistence via IndexedDB (browser) or localStorage fallback.
558
+
559
+ ```typescript
560
+ import { SessionStorage } from 'drop-daw';
561
+
562
+ const storage = SessionStorage.getInstance();
563
+
564
+ // Save
565
+ await storage.saveSession(session);
566
+
567
+ // List
568
+ const sessions = await storage.listSessions();
569
+ // [{ id: '...', name: 'My Song', modified: Date }]
570
+
571
+ // Load
572
+ const snapshot = await storage.loadSession(sessions[0].id);
573
+ const restored = Session.fromJSON(snapshot);
574
+
575
+ // Snapshots (named save points)
576
+ const snapId = await storage.saveSnapshot(session.id, 'Before mixing', session.toJSON());
577
+ const snap = await storage.loadSnapshot(snapId);
578
+
579
+ // Delete
580
+ await storage.deleteSession(session.id);
581
+ ```
582
+
583
+ ---
584
+
585
+ ## Processing Chain
586
+
587
+ Each track has a `Route` containing an ordered chain of processors.
588
+
589
+ ```typescript
590
+ import {
591
+ GainProcessor,
592
+ PanProcessor,
593
+ PluginInsert,
594
+ SendProcessor,
595
+ MeterProcessor,
596
+ } from 'drop-daw';
597
+
598
+ // Processor types available in the chain:
599
+ // GainProcessor — Fader / Trim level control
600
+ // PanProcessor — Stereo panning and width
601
+ // PluginInsert — Plugin effect slot
602
+ // SendProcessor — Pre/Post fader send to aux bus
603
+ // MeterProcessor — Peak/RMS metering
604
+ ```
605
+
606
+ ---
607
+
608
+ ## Usage Examples
609
+
610
+ ### Node.js CLI
611
+
612
+ ```typescript
613
+ import { AudioEngine, Session, CommandExecutor, CommandType } from 'drop-daw';
614
+
615
+ // Headless backend (no audio output)
616
+ class HeadlessBackend implements AudioProvider {
617
+ async initialize() {}
618
+ start() {}
619
+ stop() {}
620
+ // ... no-op implementations
621
+ }
622
+
623
+ const engine = AudioEngine.getInstance(new HeadlessBackend());
624
+ const session = engine.session;
625
+
626
+ session.addTrack('Track 1', TrackType.AUDIO);
627
+ console.log('Tracks:', session.tracks.map(t => t.name));
628
+
629
+ const snapshot = session.toJSON();
630
+ // Save to file, process offline, etc.
631
+ ```
632
+
633
+ ### Electron App
634
+
635
+ ```typescript
636
+ import { AudioEngine, AudioProvider } from 'drop-daw';
637
+
638
+ class ElectronAudioBackend implements AudioProvider {
639
+ // Use PortAudio or native audio APIs
640
+ // ...
641
+ }
642
+
643
+ const engine = AudioEngine.getInstance(new ElectronAudioBackend());
644
+ await engine.initialize();
645
+ ```
646
+
647
+ ### React Integration
648
+
649
+ ```typescript
650
+ import { useEffect, useState } from 'react';
651
+ import { AudioEngine, Session } from 'drop-daw';
652
+
653
+ function useDAWEngine(backend: AudioProvider) {
654
+ const [engine] = useState(() => AudioEngine.getInstance(backend));
655
+
656
+ useEffect(() => {
657
+ const sub = engine.session.tempoChanged.connect((bpm) => {
658
+ // update React state
659
+ });
660
+ return () => sub.dispose();
661
+ }, [engine]);
662
+
663
+ return engine;
664
+ }
665
+ ```
666
+
667
+ ---
668
+
669
+ ## API Reference
670
+
671
+ ### Singletons
672
+
673
+ | Class | Access | Description |
674
+ |-------|--------|-------------|
675
+ | `AudioEngine` | `getInstance(backend?)` | Audio engine with session and transport |
676
+ | `CommandExecutor` | `getInstance()` | Command dispatch with validation |
677
+ | `PluginManager` | `getInstance()` | Plugin factory |
678
+ | `ActionRegistry` | `getInstance()` | Keyboard shortcut ↔ command mapping |
679
+ | `Preferences` | `getInstance()` | User settings |
680
+ | `KeyBindings` | `getInstance()` | Custom key binding overrides |
681
+ | `SessionStorage` | `getInstance()` | Session persistence |
682
+
683
+ ### Domain Models
684
+
685
+ | Class | Description |
686
+ |-------|-------------|
687
+ | `Session` | Project root — tracks, sources, markers, ranges, tempo |
688
+ | `Track` | Audio/MIDI/AUX/BUS/FOLDER/VCA track |
689
+ | `Region` | Audio segment on the timeline |
690
+ | `Playlist` | Region collection within a track |
691
+ | `Source` | Audio file reference (URL, duration, sampleRate) |
692
+ | `Range` | Loop/punch/selection range |
693
+ | `Marker` | Timeline marker (position + name) |
694
+ | `MidiNote` | Single MIDI note event |
695
+ | `MidiRegion` | MIDI note collection on the timeline |
696
+ | `SendBus` | Pre/post fader send bus |
697
+ | `Route` | Signal chain (input → processors → output) |
698
+ | `TempoMap` | BPM change events over time |
699
+ | `GridSettings` | Grid type and snap mode |
700
+ | `CrossfadeEngine` | Automatic crossfade calculation |
701
+ | `MixerScene` | Mixer snapshot save/restore |
702
+ | `TrackGroup` | Track grouping for linked control |
703
+
704
+ ### Type Definitions
705
+
706
+ ```typescript
707
+ type FrameCount = number // sample frame position
708
+ type SampleRate = number // e.g. 44100, 48000, 96000
709
+ type Gain = number // 0.0 to 1.0+
710
+ type DB = number // decibels
711
+
712
+ type TrackId = string
713
+ type RegionId = string
714
+ type SourceId = string
715
+ type RangeId = string
716
+ type ProcessorId = string
717
+ type RouteId = string
718
+ ```
719
+
720
+ ---
721
+
722
+ ## Dependencies
723
+
724
+ | Package | Type | Description |
725
+ |---------|------|-------------|
726
+ | `zod` | runtime | Command payload validation |
727
+ | `lamejs` | peer (optional) | MP3 export support |
728
+ | `soundtouchjs` | peer (optional) | Time-stretch / pitch-shift |
729
+
730
+ ---
731
+
732
+ ## License
733
+
734
+ MIT