@drop-ai/core 0.2.0 → 0.3.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 (301) hide show
  1. package/README.md +655 -237
  2. package/dist/actions/ActionRegistry.d.ts.map +1 -1
  3. package/dist/actions/ActionRegistry.js +7 -2
  4. package/dist/actions/ActionRegistry.js.map +1 -1
  5. package/dist/actions/types.d.ts +7 -1
  6. package/dist/actions/types.d.ts.map +1 -1
  7. package/dist/analysis/AudioAnalyzer.d.ts +71 -0
  8. package/dist/analysis/AudioAnalyzer.d.ts.map +1 -0
  9. package/dist/analysis/AudioAnalyzer.js +569 -0
  10. package/dist/analysis/AudioAnalyzer.js.map +1 -0
  11. package/dist/audio/AudioEngine.d.ts +14 -1
  12. package/dist/audio/AudioEngine.d.ts.map +1 -1
  13. package/dist/audio/AudioEngine.js +115 -35
  14. package/dist/audio/AudioEngine.js.map +1 -1
  15. package/dist/audio/Auditioner.d.ts +104 -0
  16. package/dist/audio/Auditioner.d.ts.map +1 -0
  17. package/dist/audio/Auditioner.js +239 -0
  18. package/dist/audio/Auditioner.js.map +1 -0
  19. package/dist/audio/BWFMetadata.d.ts +116 -0
  20. package/dist/audio/BWFMetadata.d.ts.map +1 -0
  21. package/dist/audio/BWFMetadata.js +394 -0
  22. package/dist/audio/BWFMetadata.js.map +1 -0
  23. package/dist/audio/ChannelSplitter.d.ts +37 -0
  24. package/dist/audio/ChannelSplitter.d.ts.map +1 -0
  25. package/dist/audio/ChannelSplitter.js +82 -0
  26. package/dist/audio/ChannelSplitter.js.map +1 -0
  27. package/dist/audio/ExportAnalyzer.d.ts +39 -0
  28. package/dist/audio/ExportAnalyzer.d.ts.map +1 -0
  29. package/dist/audio/ExportAnalyzer.js +76 -0
  30. package/dist/audio/ExportAnalyzer.js.map +1 -0
  31. package/dist/audio/LufsNormalizer.d.ts +37 -0
  32. package/dist/audio/LufsNormalizer.d.ts.map +1 -0
  33. package/dist/audio/LufsNormalizer.js +217 -0
  34. package/dist/audio/LufsNormalizer.js.map +1 -0
  35. package/dist/audio/OfflineExporter.d.ts +1 -6
  36. package/dist/audio/OfflineExporter.d.ts.map +1 -1
  37. package/dist/audio/OfflineExporter.js +31 -10
  38. package/dist/audio/OfflineExporter.js.map +1 -1
  39. package/dist/audio/RoutingGraph.d.ts +134 -0
  40. package/dist/audio/RoutingGraph.d.ts.map +1 -0
  41. package/dist/audio/RoutingGraph.js +547 -0
  42. package/dist/audio/RoutingGraph.js.map +1 -0
  43. package/dist/audio/SampleRateConverter.d.ts +21 -0
  44. package/dist/audio/SampleRateConverter.d.ts.map +1 -0
  45. package/dist/audio/SampleRateConverter.js +84 -0
  46. package/dist/audio/SampleRateConverter.js.map +1 -0
  47. package/dist/audio/SilencePadding.d.ts +29 -0
  48. package/dist/audio/SilencePadding.d.ts.map +1 -0
  49. package/dist/audio/SilencePadding.js +86 -0
  50. package/dist/audio/SilencePadding.js.map +1 -0
  51. package/dist/audio/SourceCache.d.ts +13 -16
  52. package/dist/audio/SourceCache.d.ts.map +1 -1
  53. package/dist/audio/SourceCache.js +21 -33
  54. package/dist/audio/SourceCache.js.map +1 -1
  55. package/dist/audio/engine/Declick.d.ts +98 -0
  56. package/dist/audio/engine/Declick.d.ts.map +1 -0
  57. package/dist/audio/engine/Declick.js +204 -0
  58. package/dist/audio/engine/Declick.js.map +1 -0
  59. package/dist/audio/engine/DiskIO.d.ts +172 -0
  60. package/dist/audio/engine/DiskIO.d.ts.map +1 -0
  61. package/dist/audio/engine/DiskIO.js +384 -0
  62. package/dist/audio/engine/DiskIO.js.map +1 -0
  63. package/dist/audio/engine/LatencyCompensator.d.ts +46 -0
  64. package/dist/audio/engine/LatencyCompensator.d.ts.map +1 -0
  65. package/dist/audio/engine/LatencyCompensator.js +84 -0
  66. package/dist/audio/engine/LatencyCompensator.js.map +1 -0
  67. package/dist/audio/engine/MultiTrackRecorder.d.ts +146 -0
  68. package/dist/audio/engine/MultiTrackRecorder.d.ts.map +1 -0
  69. package/dist/audio/engine/MultiTrackRecorder.js +359 -0
  70. package/dist/audio/engine/MultiTrackRecorder.js.map +1 -0
  71. package/dist/audio/engine/PlaylistEngine.d.ts.map +1 -1
  72. package/dist/audio/engine/PlaylistEngine.js +9 -2
  73. package/dist/audio/engine/PlaylistEngine.js.map +1 -1
  74. package/dist/audio/engine/PunchRecordManager.d.ts +113 -0
  75. package/dist/audio/engine/PunchRecordManager.d.ts.map +1 -0
  76. package/dist/audio/engine/PunchRecordManager.js +191 -0
  77. package/dist/audio/engine/PunchRecordManager.js.map +1 -0
  78. package/dist/audio/engine/RoutingGraph.d.ts +135 -0
  79. package/dist/audio/engine/RoutingGraph.d.ts.map +1 -0
  80. package/dist/audio/engine/RoutingGraph.js +436 -0
  81. package/dist/audio/engine/RoutingGraph.js.map +1 -0
  82. package/dist/audio/engine/SidechainRouter.d.ts +139 -0
  83. package/dist/audio/engine/SidechainRouter.d.ts.map +1 -0
  84. package/dist/audio/engine/SidechainRouter.js +292 -0
  85. package/dist/audio/engine/SidechainRouter.js.map +1 -0
  86. package/dist/audio/engine/XrunTracker.d.ts +71 -0
  87. package/dist/audio/engine/XrunTracker.d.ts.map +1 -0
  88. package/dist/audio/engine/XrunTracker.js +118 -0
  89. package/dist/audio/engine/XrunTracker.js.map +1 -0
  90. package/dist/audio/export/CDMarkerExporter.d.ts +62 -0
  91. package/dist/audio/export/CDMarkerExporter.d.ts.map +1 -0
  92. package/dist/audio/export/CDMarkerExporter.js +164 -0
  93. package/dist/audio/export/CDMarkerExporter.js.map +1 -0
  94. package/dist/audio/export/ExportGraphBuilder.d.ts +121 -0
  95. package/dist/audio/export/ExportGraphBuilder.d.ts.map +1 -0
  96. package/dist/audio/export/ExportGraphBuilder.js +522 -0
  97. package/dist/audio/export/ExportGraphBuilder.js.map +1 -0
  98. package/dist/audio/export/ExportPresetManager.d.ts +87 -0
  99. package/dist/audio/export/ExportPresetManager.d.ts.map +1 -0
  100. package/dist/audio/export/ExportPresetManager.js +306 -0
  101. package/dist/audio/export/ExportPresetManager.js.map +1 -0
  102. package/dist/commands/handlers/RegionHandler.d.ts.map +1 -1
  103. package/dist/commands/handlers/RegionHandler.js +25 -1
  104. package/dist/commands/handlers/RegionHandler.js.map +1 -1
  105. package/dist/commands/handlers/TrackHandler.js +1 -1
  106. package/dist/commands/handlers/TrackHandler.js.map +1 -1
  107. package/dist/commands/impl/FreezeTrackCommand.d.ts.map +1 -1
  108. package/dist/commands/impl/FreezeTrackCommand.js +37 -36
  109. package/dist/commands/impl/FreezeTrackCommand.js.map +1 -1
  110. package/dist/commands/impl/SetRegionTimeDomainCommand.d.ts.map +1 -1
  111. package/dist/commands/impl/SetRegionTimeDomainCommand.js +3 -3
  112. package/dist/commands/impl/SetRegionTimeDomainCommand.js.map +1 -1
  113. package/dist/commands/impl/ToggleLoopCommand.d.ts +1 -0
  114. package/dist/commands/impl/ToggleLoopCommand.d.ts.map +1 -1
  115. package/dist/commands/impl/ToggleLoopCommand.js +10 -0
  116. package/dist/commands/impl/ToggleLoopCommand.js.map +1 -1
  117. package/dist/commands/impl/TrimRegionCommand.d.ts +14 -1
  118. package/dist/commands/impl/TrimRegionCommand.d.ts.map +1 -1
  119. package/dist/commands/impl/TrimRegionCommand.js +138 -33
  120. package/dist/commands/impl/TrimRegionCommand.js.map +1 -1
  121. package/dist/commands/impl/TrimRegionToPlayheadCommand.d.ts +27 -0
  122. package/dist/commands/impl/TrimRegionToPlayheadCommand.d.ts.map +1 -0
  123. package/dist/commands/impl/TrimRegionToPlayheadCommand.js +69 -0
  124. package/dist/commands/impl/TrimRegionToPlayheadCommand.js.map +1 -0
  125. package/dist/commands/impl/TrimRegionToRangeCommand.d.ts +28 -0
  126. package/dist/commands/impl/TrimRegionToRangeCommand.d.ts.map +1 -0
  127. package/dist/commands/impl/TrimRegionToRangeCommand.js +69 -0
  128. package/dist/commands/impl/TrimRegionToRangeCommand.js.map +1 -0
  129. package/dist/commands/impl/TrimToAdjacentRegionCommand.d.ts +27 -0
  130. package/dist/commands/impl/TrimToAdjacentRegionCommand.d.ts.map +1 -0
  131. package/dist/commands/impl/TrimToAdjacentRegionCommand.js +77 -0
  132. package/dist/commands/impl/TrimToAdjacentRegionCommand.js.map +1 -0
  133. package/dist/commands/types.d.ts +19 -0
  134. package/dist/commands/types.d.ts.map +1 -1
  135. package/dist/commands/types.js +21 -0
  136. package/dist/commands/types.js.map +1 -1
  137. package/dist/domain/Crossfade.d.ts +78 -0
  138. package/dist/domain/Crossfade.d.ts.map +1 -0
  139. package/dist/domain/Crossfade.js +216 -0
  140. package/dist/domain/Crossfade.js.map +1 -0
  141. package/dist/domain/ExportConfig.d.ts +98 -1
  142. package/dist/domain/ExportConfig.d.ts.map +1 -1
  143. package/dist/domain/ExportConfig.js +154 -1
  144. package/dist/domain/ExportConfig.js.map +1 -1
  145. package/dist/domain/ExportPreset.d.ts +62 -0
  146. package/dist/domain/ExportPreset.d.ts.map +1 -0
  147. package/dist/domain/ExportPreset.js +79 -0
  148. package/dist/domain/ExportPreset.js.map +1 -0
  149. package/dist/domain/ImportStatus.d.ts +40 -0
  150. package/dist/domain/ImportStatus.d.ts.map +1 -0
  151. package/dist/domain/ImportStatus.js +86 -0
  152. package/dist/domain/ImportStatus.js.map +1 -0
  153. package/dist/domain/Playlist.d.ts +72 -0
  154. package/dist/domain/Playlist.d.ts.map +1 -1
  155. package/dist/domain/Playlist.js +231 -6
  156. package/dist/domain/Playlist.js.map +1 -1
  157. package/dist/domain/Region.d.ts +76 -0
  158. package/dist/domain/Region.d.ts.map +1 -1
  159. package/dist/domain/Region.js +234 -1
  160. package/dist/domain/Region.js.map +1 -1
  161. package/dist/domain/Route.d.ts +43 -3
  162. package/dist/domain/Route.d.ts.map +1 -1
  163. package/dist/domain/Route.js +92 -6
  164. package/dist/domain/Route.js.map +1 -1
  165. package/dist/domain/Session.d.ts +31 -0
  166. package/dist/domain/Session.d.ts.map +1 -1
  167. package/dist/domain/Session.js +70 -0
  168. package/dist/domain/Session.js.map +1 -1
  169. package/dist/domain/Source.d.ts +145 -1
  170. package/dist/domain/Source.d.ts.map +1 -1
  171. package/dist/domain/Source.js +144 -1
  172. package/dist/domain/Source.js.map +1 -1
  173. package/dist/domain/ThawList.d.ts +37 -0
  174. package/dist/domain/ThawList.d.ts.map +1 -0
  175. package/dist/domain/ThawList.js +73 -0
  176. package/dist/domain/ThawList.js.map +1 -0
  177. package/dist/domain/Track.d.ts +93 -1
  178. package/dist/domain/Track.d.ts.map +1 -1
  179. package/dist/domain/Track.js +136 -0
  180. package/dist/domain/Track.js.map +1 -1
  181. package/dist/domain/TriggerBox.d.ts +123 -0
  182. package/dist/domain/TriggerBox.d.ts.map +1 -0
  183. package/dist/domain/TriggerBox.js +430 -0
  184. package/dist/domain/TriggerBox.js.map +1 -0
  185. package/dist/domain/VCATrack.d.ts +64 -1
  186. package/dist/domain/VCATrack.d.ts.map +1 -1
  187. package/dist/domain/VCATrack.js +128 -1
  188. package/dist/domain/VCATrack.js.map +1 -1
  189. package/dist/domain/VideoExportConfig.d.ts +117 -0
  190. package/dist/domain/VideoExportConfig.d.ts.map +1 -0
  191. package/dist/domain/VideoExportConfig.js +244 -0
  192. package/dist/domain/VideoExportConfig.js.map +1 -0
  193. package/dist/domain/VideoExportStatus.d.ts +89 -0
  194. package/dist/domain/VideoExportStatus.d.ts.map +1 -0
  195. package/dist/domain/VideoExportStatus.js +192 -0
  196. package/dist/domain/VideoExportStatus.js.map +1 -0
  197. package/dist/domain/VideoMetadata.d.ts +46 -0
  198. package/dist/domain/VideoMetadata.d.ts.map +1 -0
  199. package/dist/domain/VideoMetadata.js +2 -0
  200. package/dist/domain/VideoMetadata.js.map +1 -0
  201. package/dist/domain/index.d.ts +5 -0
  202. package/dist/domain/index.d.ts.map +1 -1
  203. package/dist/domain/index.js +5 -0
  204. package/dist/domain/index.js.map +1 -1
  205. package/dist/domain/temporal/TempoMap.d.ts +199 -2
  206. package/dist/domain/temporal/TempoMap.d.ts.map +1 -1
  207. package/dist/domain/temporal/TempoMap.js +464 -30
  208. package/dist/domain/temporal/TempoMap.js.map +1 -1
  209. package/dist/index.d.ts +43 -1
  210. package/dist/index.d.ts.map +1 -1
  211. package/dist/index.js +32 -1
  212. package/dist/index.js.map +1 -1
  213. package/dist/lib/ThawList.d.ts +100 -0
  214. package/dist/lib/ThawList.d.ts.map +1 -0
  215. package/dist/lib/ThawList.js +153 -0
  216. package/dist/lib/ThawList.js.map +1 -0
  217. package/dist/midi/MidiFileParser.d.ts +33 -0
  218. package/dist/midi/MidiFileParser.d.ts.map +1 -0
  219. package/dist/midi/MidiFileParser.js +246 -0
  220. package/dist/midi/MidiFileParser.js.map +1 -0
  221. package/dist/midi/MidiFileWriter.d.ts +31 -0
  222. package/dist/midi/MidiFileWriter.d.ts.map +1 -0
  223. package/dist/midi/MidiFileWriter.js +160 -0
  224. package/dist/midi/MidiFileWriter.js.map +1 -0
  225. package/dist/midi/MidiImporter.d.ts +37 -0
  226. package/dist/midi/MidiImporter.d.ts.map +1 -0
  227. package/dist/midi/MidiImporter.js +62 -0
  228. package/dist/midi/MidiImporter.js.map +1 -0
  229. package/dist/plugins/PluginPresetManager.d.ts +86 -0
  230. package/dist/plugins/PluginPresetManager.d.ts.map +1 -0
  231. package/dist/plugins/PluginPresetManager.js +140 -0
  232. package/dist/plugins/PluginPresetManager.js.map +1 -0
  233. package/dist/processing/IO.d.ts +15 -1
  234. package/dist/processing/IO.d.ts.map +1 -1
  235. package/dist/processing/IO.js +29 -1
  236. package/dist/processing/IO.js.map +1 -1
  237. package/dist/processing/InternalSend.d.ts +104 -0
  238. package/dist/processing/InternalSend.d.ts.map +1 -0
  239. package/dist/processing/InternalSend.js +175 -0
  240. package/dist/processing/InternalSend.js.map +1 -0
  241. package/dist/processing/MeterDSP.d.ts +166 -0
  242. package/dist/processing/MeterDSP.d.ts.map +1 -0
  243. package/dist/processing/MeterDSP.js +754 -0
  244. package/dist/processing/MeterDSP.js.map +1 -0
  245. package/dist/processing/Panner.d.ts +145 -0
  246. package/dist/processing/Panner.d.ts.map +1 -0
  247. package/dist/processing/Panner.js +281 -0
  248. package/dist/processing/Panner.js.map +1 -0
  249. package/dist/processing/PluginInsert.d.ts +56 -1
  250. package/dist/processing/PluginInsert.d.ts.map +1 -1
  251. package/dist/processing/PluginInsert.js +180 -2
  252. package/dist/processing/PluginInsert.js.map +1 -1
  253. package/dist/processing/Processor.d.ts +38 -0
  254. package/dist/processing/Processor.d.ts.map +1 -1
  255. package/dist/processing/Processor.js +60 -1
  256. package/dist/processing/Processor.js.map +1 -1
  257. package/dist/processing/SurroundPanner.d.ts +122 -0
  258. package/dist/processing/SurroundPanner.d.ts.map +1 -0
  259. package/dist/processing/SurroundPanner.js +376 -0
  260. package/dist/processing/SurroundPanner.js.map +1 -0
  261. package/dist/processing/TruePeakLimiter.d.ts +34 -0
  262. package/dist/processing/TruePeakLimiter.d.ts.map +1 -0
  263. package/dist/processing/TruePeakLimiter.js +144 -0
  264. package/dist/processing/TruePeakLimiter.js.map +1 -0
  265. package/dist/storage/ExportPresetStorage.d.ts +33 -0
  266. package/dist/storage/ExportPresetStorage.d.ts.map +1 -0
  267. package/dist/storage/ExportPresetStorage.js +121 -0
  268. package/dist/storage/ExportPresetStorage.js.map +1 -0
  269. package/dist/storage/SessionArchive.d.ts +73 -0
  270. package/dist/storage/SessionArchive.d.ts.map +1 -0
  271. package/dist/storage/SessionArchive.js +211 -0
  272. package/dist/storage/SessionArchive.js.map +1 -0
  273. package/dist/storage/SessionTemplate.d.ts +74 -5
  274. package/dist/storage/SessionTemplate.d.ts.map +1 -1
  275. package/dist/storage/SessionTemplate.js +247 -53
  276. package/dist/storage/SessionTemplate.js.map +1 -1
  277. package/dist/utils/BwfMetadataWriter.d.ts +42 -0
  278. package/dist/utils/BwfMetadataWriter.d.ts.map +1 -0
  279. package/dist/utils/BwfMetadataWriter.js +131 -0
  280. package/dist/utils/BwfMetadataWriter.js.map +1 -0
  281. package/dist/utils/FilenameTemplate.d.ts +40 -0
  282. package/dist/utils/FilenameTemplate.d.ts.map +1 -0
  283. package/dist/utils/FilenameTemplate.js +78 -0
  284. package/dist/utils/FilenameTemplate.js.map +1 -0
  285. package/dist/utils/Logger.d.ts +28 -0
  286. package/dist/utils/Logger.d.ts.map +1 -0
  287. package/dist/utils/Logger.js +46 -0
  288. package/dist/utils/Logger.js.map +1 -0
  289. package/dist/utils/Mp4ChapterGenerator.d.ts +17 -0
  290. package/dist/utils/Mp4ChapterGenerator.d.ts.map +1 -0
  291. package/dist/utils/Mp4ChapterGenerator.js +33 -0
  292. package/dist/utils/Mp4ChapterGenerator.js.map +1 -0
  293. package/dist/utils/OggEncoder.d.ts +20 -20
  294. package/dist/utils/OggEncoder.d.ts.map +1 -1
  295. package/dist/utils/OggEncoder.js +114 -50
  296. package/dist/utils/OggEncoder.js.map +1 -1
  297. package/dist/utils/TocGenerator.d.ts +17 -0
  298. package/dist/utils/TocGenerator.d.ts.map +1 -0
  299. package/dist/utils/TocGenerator.js +47 -0
  300. package/dist/utils/TocGenerator.js.map +1 -0
  301. package/package.json +7 -8
@@ -0,0 +1,146 @@
1
+ import { Signal } from '../../lib/Signal';
2
+ import { TrackId, FrameCount } from '../../domain/types';
3
+ /**
4
+ * MultiTrackRecorder manages simultaneous recording on multiple tracks.
5
+ *
6
+ * Ardour reference: libs/ardour/disk_writer.cc
7
+ *
8
+ * In the Web Audio context, each armed track can record from:
9
+ * - A specific audio input channel (via Web Audio MediaStreamSource)
10
+ * - A MIDI input device
11
+ *
12
+ * The recorder manages:
13
+ * - Per-track input assignment (which input channel -> which track)
14
+ * - Simultaneous recording start/stop across all armed tracks
15
+ * - Per-track audio buffer accumulation
16
+ * - Take numbering and management
17
+ */
18
+ export interface InputAssignment {
19
+ trackId: TrackId;
20
+ inputType: 'audio' | 'midi';
21
+ channelIndex: number;
22
+ deviceId?: string;
23
+ }
24
+ export interface RecordingResult {
25
+ trackId: TrackId;
26
+ blob: Blob;
27
+ startFrame: FrameCount;
28
+ durationFrames: FrameCount;
29
+ takeNumber: number;
30
+ peakLevel: number;
31
+ hasClipped: boolean;
32
+ }
33
+ interface AudioInputInfo {
34
+ deviceId: string;
35
+ label: string;
36
+ channelCount: number;
37
+ }
38
+ export declare class MultiTrackRecorder {
39
+ private _assignments;
40
+ private _activeRecordings;
41
+ private _takeCounters;
42
+ private _isRecording;
43
+ private _sampleRate;
44
+ /** Emitted when recording starts on a set of tracks. */
45
+ readonly recordingStarted: Signal<string[]>;
46
+ /** Emitted when recording stops, with results for each track. */
47
+ readonly recordingStopped: Signal<RecordingResult[]>;
48
+ /** Emitted periodically with per-track level updates during recording. */
49
+ readonly levelUpdate: Signal<{
50
+ trackId: TrackId;
51
+ level: number;
52
+ }>;
53
+ /** Emitted when clipping is detected on a track. */
54
+ readonly clipDetected: Signal<string>;
55
+ /**
56
+ * @param sampleRate - Audio sample rate for WAV encoding. Defaults to 44100.
57
+ */
58
+ constructor(sampleRate?: number);
59
+ /**
60
+ * Assign an input source to a track.
61
+ * Defines which audio input channel or MIDI device feeds this track.
62
+ */
63
+ assignInput(assignment: InputAssignment): void;
64
+ /**
65
+ * Remove an input assignment from a track.
66
+ */
67
+ removeAssignment(trackId: TrackId): void;
68
+ /**
69
+ * Get the input assignment for a specific track.
70
+ */
71
+ getAssignment(trackId: TrackId): InputAssignment | undefined;
72
+ /**
73
+ * Get all current input assignments.
74
+ */
75
+ getAllAssignments(): InputAssignment[];
76
+ /**
77
+ * Start recording on all assigned and armed tracks simultaneously.
78
+ * Only tracks that appear in both armedTrackIds AND have an input assignment
79
+ * will begin recording.
80
+ *
81
+ * @param armedTrackIds - List of track IDs that are armed for recording
82
+ * @param startFrame - The session frame at which recording begins
83
+ */
84
+ startRecording(armedTrackIds: TrackId[], startFrame: FrameCount): void;
85
+ /**
86
+ * Stop recording on all tracks and return results.
87
+ * Each result contains the accumulated audio as a WAV blob, duration,
88
+ * peak level, and clipping information.
89
+ */
90
+ stopRecording(): RecordingResult[];
91
+ /**
92
+ * Stop recording on a specific track while other tracks continue.
93
+ * Returns the result for that track, or null if the track was not recording.
94
+ */
95
+ stopTrackRecording(trackId: TrackId): RecordingResult | null;
96
+ /**
97
+ * Feed audio data for a specific track during recording.
98
+ * Called from the audio processing callback for each block of samples.
99
+ *
100
+ * Accumulates chunks, tracks peak levels, and detects clipping.
101
+ *
102
+ * @param trackId - The track receiving the audio
103
+ * @param data - Per-channel audio data (e.g. [leftChannel, rightChannel])
104
+ * @param blockSize - Number of frames in this block
105
+ */
106
+ feedAudio(trackId: TrackId, data: Float32Array[], blockSize: number): void;
107
+ /**
108
+ * Query the browser for available audio input devices.
109
+ * Returns a list of input devices with their capabilities.
110
+ */
111
+ static getAvailableInputs(): Promise<AudioInputInfo[]>;
112
+ /**
113
+ * Whether the recorder is currently recording on any track.
114
+ */
115
+ get isRecording(): boolean;
116
+ /**
117
+ * Get the list of track IDs that are currently being recorded.
118
+ */
119
+ getActiveTrackIds(): TrackId[];
120
+ /**
121
+ * Reset all state: clear active recordings, assignments, and take counters.
122
+ */
123
+ reset(): void;
124
+ /**
125
+ * Finalize a recording: merge accumulated chunks into a WAV blob
126
+ * and produce a RecordingResult.
127
+ */
128
+ private _finalizeRecording;
129
+ /**
130
+ * Encode per-channel Float32Array data into a WAV file Blob.
131
+ *
132
+ * Produces a standard RIFF/WAVE file with IEEE Float32 audio format.
133
+ * Header layout follows the canonical WAV specification.
134
+ *
135
+ * @param channels - Per-channel audio data arrays (all same length)
136
+ * @param sampleRate - Sample rate in Hz
137
+ * @param numChannels - Number of audio channels
138
+ */
139
+ private static _encodeWav;
140
+ /**
141
+ * Write an ASCII string into a DataView at the given byte offset.
142
+ */
143
+ private static _writeString;
144
+ }
145
+ export {};
146
+ //# sourceMappingURL=MultiTrackRecorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultiTrackRecorder.d.ts","sourceRoot":"","sources":["../../../src/audio/engine/MultiTrackRecorder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,UAAU,CAAC;IACvB,cAAc,EAAE,UAAU,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;CACvB;AAWD,UAAU,cAAc;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACxB;AAQD,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,YAAY,CAA4C;IAChE,OAAO,CAAC,iBAAiB,CAA4C;IACrE,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,WAAW,CAAS;IAE5B,wDAAwD;IACxD,SAAgB,gBAAgB,mBAA2B;IAE3D,iEAAiE;IACjE,SAAgB,gBAAgB,4BAAmC;IAEnE,0EAA0E;IAC1E,SAAgB,WAAW;iBAAyB,OAAO;eAAS,MAAM;OAAM;IAEhF,oDAAoD;IACpD,SAAgB,YAAY,iBAAyB;IAErD;;OAEG;gBACS,UAAU,CAAC,EAAE,MAAM;IAM/B;;;OAGG;IACH,WAAW,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI;IAI9C;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIxC;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS;IAK5D;;OAEG;IACH,iBAAiB,IAAI,eAAe,EAAE;IAMtC;;;;;;;OAOG;IACH,cAAc,CAAC,aAAa,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI;IAmCtE;;;;OAIG;IACH,aAAa,IAAI,eAAe,EAAE;IAoBlC;;;OAGG;IACH,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI;IAmB5D;;;;;;;;;OASG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAwD1E;;;OAGG;WACU,kBAAkB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAiD5D;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACH,iBAAiB,IAAI,OAAO,EAAE;IAI9B;;OAEG;IACH,KAAK,IAAI,IAAI;IASb;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAqD1B;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAC,UAAU;IAmDzB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;CAK9B"}
@@ -0,0 +1,359 @@
1
+ import { Signal } from '../../lib/Signal';
2
+ /** Default sample rate used when encoding WAV if none is specified. */
3
+ const DEFAULT_SAMPLE_RATE = 44100;
4
+ /** Clip threshold — signals at or above 1.0 are considered clipped. */
5
+ const CLIP_THRESHOLD = 1.0;
6
+ export class MultiTrackRecorder {
7
+ /**
8
+ * @param sampleRate - Audio sample rate for WAV encoding. Defaults to 44100.
9
+ */
10
+ constructor(sampleRate) {
11
+ this._assignments = new Map();
12
+ this._activeRecordings = new Map();
13
+ this._takeCounters = new Map();
14
+ this._isRecording = false;
15
+ /** Emitted when recording starts on a set of tracks. */
16
+ this.recordingStarted = new Signal();
17
+ /** Emitted when recording stops, with results for each track. */
18
+ this.recordingStopped = new Signal();
19
+ /** Emitted periodically with per-track level updates during recording. */
20
+ this.levelUpdate = new Signal();
21
+ /** Emitted when clipping is detected on a track. */
22
+ this.clipDetected = new Signal();
23
+ this._sampleRate = sampleRate !== null && sampleRate !== void 0 ? sampleRate : DEFAULT_SAMPLE_RATE;
24
+ }
25
+ // ─── Input Assignment ───────────────────────────────────────────────
26
+ /**
27
+ * Assign an input source to a track.
28
+ * Defines which audio input channel or MIDI device feeds this track.
29
+ */
30
+ assignInput(assignment) {
31
+ this._assignments.set(assignment.trackId, Object.assign({}, assignment));
32
+ }
33
+ /**
34
+ * Remove an input assignment from a track.
35
+ */
36
+ removeAssignment(trackId) {
37
+ this._assignments.delete(trackId);
38
+ }
39
+ /**
40
+ * Get the input assignment for a specific track.
41
+ */
42
+ getAssignment(trackId) {
43
+ const assignment = this._assignments.get(trackId);
44
+ return assignment ? Object.assign({}, assignment) : undefined;
45
+ }
46
+ /**
47
+ * Get all current input assignments.
48
+ */
49
+ getAllAssignments() {
50
+ return Array.from(this._assignments.values()).map(a => (Object.assign({}, a)));
51
+ }
52
+ // ─── Recording Control ──────────────────────────────────────────────
53
+ /**
54
+ * Start recording on all assigned and armed tracks simultaneously.
55
+ * Only tracks that appear in both armedTrackIds AND have an input assignment
56
+ * will begin recording.
57
+ *
58
+ * @param armedTrackIds - List of track IDs that are armed for recording
59
+ * @param startFrame - The session frame at which recording begins
60
+ */
61
+ startRecording(armedTrackIds, startFrame) {
62
+ var _a;
63
+ if (this._isRecording) {
64
+ return;
65
+ }
66
+ const tracksToRecord = [];
67
+ for (const trackId of armedTrackIds) {
68
+ if (!this._assignments.has(trackId)) {
69
+ continue;
70
+ }
71
+ // Increment take counter for this track
72
+ const currentTake = ((_a = this._takeCounters.get(trackId)) !== null && _a !== void 0 ? _a : 0) + 1;
73
+ this._takeCounters.set(trackId, currentTake);
74
+ const recording = {
75
+ trackId,
76
+ startFrame,
77
+ chunks: [],
78
+ peakLevel: 0,
79
+ hasClipped: false,
80
+ takeNumber: currentTake,
81
+ };
82
+ this._activeRecordings.set(trackId, recording);
83
+ tracksToRecord.push(trackId);
84
+ }
85
+ if (tracksToRecord.length > 0) {
86
+ this._isRecording = true;
87
+ this.recordingStarted.emit(tracksToRecord);
88
+ }
89
+ }
90
+ /**
91
+ * Stop recording on all tracks and return results.
92
+ * Each result contains the accumulated audio as a WAV blob, duration,
93
+ * peak level, and clipping information.
94
+ */
95
+ stopRecording() {
96
+ if (!this._isRecording) {
97
+ return [];
98
+ }
99
+ const results = [];
100
+ for (const [trackId, recording] of this._activeRecordings) {
101
+ const result = this._finalizeRecording(recording);
102
+ if (result) {
103
+ results.push(result);
104
+ }
105
+ }
106
+ this._activeRecordings.clear();
107
+ this._isRecording = false;
108
+ this.recordingStopped.emit(results);
109
+ return results;
110
+ }
111
+ /**
112
+ * Stop recording on a specific track while other tracks continue.
113
+ * Returns the result for that track, or null if the track was not recording.
114
+ */
115
+ stopTrackRecording(trackId) {
116
+ const recording = this._activeRecordings.get(trackId);
117
+ if (!recording) {
118
+ return null;
119
+ }
120
+ const result = this._finalizeRecording(recording);
121
+ this._activeRecordings.delete(trackId);
122
+ // If no more active recordings remain, mark as not recording
123
+ if (this._activeRecordings.size === 0) {
124
+ this._isRecording = false;
125
+ }
126
+ return result;
127
+ }
128
+ // ─── Audio Data Feed ────────────────────────────────────────────────
129
+ /**
130
+ * Feed audio data for a specific track during recording.
131
+ * Called from the audio processing callback for each block of samples.
132
+ *
133
+ * Accumulates chunks, tracks peak levels, and detects clipping.
134
+ *
135
+ * @param trackId - The track receiving the audio
136
+ * @param data - Per-channel audio data (e.g. [leftChannel, rightChannel])
137
+ * @param blockSize - Number of frames in this block
138
+ */
139
+ feedAudio(trackId, data, blockSize) {
140
+ const recording = this._activeRecordings.get(trackId);
141
+ if (!recording) {
142
+ return;
143
+ }
144
+ // Copy the incoming data so we own the buffers
145
+ // (callers may reuse the same arrays each cycle)
146
+ const chunk = [];
147
+ for (let ch = 0; ch < data.length; ch++) {
148
+ const copy = new Float32Array(blockSize);
149
+ // Copy only the relevant portion (blockSize may be less than data[ch].length)
150
+ const srcLen = Math.min(blockSize, data[ch].length);
151
+ for (let i = 0; i < srcLen; i++) {
152
+ copy[i] = data[ch][i];
153
+ }
154
+ chunk.push(copy);
155
+ }
156
+ recording.chunks.push(chunk);
157
+ // Compute peak level and detect clipping for this block
158
+ let blockPeak = 0;
159
+ let clippedInBlock = false;
160
+ for (let ch = 0; ch < data.length; ch++) {
161
+ const channelData = data[ch];
162
+ const len = Math.min(blockSize, channelData.length);
163
+ for (let i = 0; i < len; i++) {
164
+ const abs = Math.abs(channelData[i]);
165
+ if (abs > blockPeak) {
166
+ blockPeak = abs;
167
+ }
168
+ if (abs >= CLIP_THRESHOLD) {
169
+ clippedInBlock = true;
170
+ }
171
+ }
172
+ }
173
+ // Update recording peak
174
+ if (blockPeak > recording.peakLevel) {
175
+ recording.peakLevel = blockPeak;
176
+ }
177
+ // Detect clipping
178
+ if (clippedInBlock && !recording.hasClipped) {
179
+ recording.hasClipped = true;
180
+ this.clipDetected.emit(trackId);
181
+ }
182
+ // Emit level update for metering
183
+ this.levelUpdate.emit({ trackId, level: blockPeak });
184
+ }
185
+ // ─── Available Inputs ───────────────────────────────────────────────
186
+ /**
187
+ * Query the browser for available audio input devices.
188
+ * Returns a list of input devices with their capabilities.
189
+ */
190
+ static async getAvailableInputs() {
191
+ var _a, _b, _c;
192
+ // Check if the MediaDevices API is available (browser environment)
193
+ if (typeof navigator === 'undefined' || !navigator.mediaDevices) {
194
+ return [];
195
+ }
196
+ try {
197
+ // Request permission to enumerate devices with labels
198
+ // Some browsers require an active stream before labels are visible
199
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
200
+ const devices = await navigator.mediaDevices.enumerateDevices();
201
+ const audioInputs = [];
202
+ for (const device of devices) {
203
+ if (device.kind === 'audioinput') {
204
+ // Determine channel count from device capabilities if available
205
+ let channelCount = 2; // Default to stereo
206
+ try {
207
+ const capabilities = (_b = (_a = device).getCapabilities) === null || _b === void 0 ? void 0 : _b.call(_a);
208
+ if ((_c = capabilities === null || capabilities === void 0 ? void 0 : capabilities.channelCount) === null || _c === void 0 ? void 0 : _c.max) {
209
+ channelCount = capabilities.channelCount.max;
210
+ }
211
+ }
212
+ catch (_d) {
213
+ // getCapabilities not supported — use default
214
+ }
215
+ audioInputs.push({
216
+ deviceId: device.deviceId,
217
+ label: device.label || `Input ${audioInputs.length + 1}`,
218
+ channelCount,
219
+ });
220
+ }
221
+ }
222
+ // Stop the temporary stream
223
+ for (const track of stream.getTracks()) {
224
+ track.stop();
225
+ }
226
+ return audioInputs;
227
+ }
228
+ catch (_e) {
229
+ // Permission denied or no audio input available
230
+ return [];
231
+ }
232
+ }
233
+ // ─── State Queries ──────────────────────────────────────────────────
234
+ /**
235
+ * Whether the recorder is currently recording on any track.
236
+ */
237
+ get isRecording() {
238
+ return this._isRecording;
239
+ }
240
+ /**
241
+ * Get the list of track IDs that are currently being recorded.
242
+ */
243
+ getActiveTrackIds() {
244
+ return Array.from(this._activeRecordings.keys());
245
+ }
246
+ /**
247
+ * Reset all state: clear active recordings, assignments, and take counters.
248
+ */
249
+ reset() {
250
+ this._activeRecordings.clear();
251
+ this._assignments.clear();
252
+ this._takeCounters.clear();
253
+ this._isRecording = false;
254
+ }
255
+ // ─── Private helpers ────────────────────────────────────────────────
256
+ /**
257
+ * Finalize a recording: merge accumulated chunks into a WAV blob
258
+ * and produce a RecordingResult.
259
+ */
260
+ _finalizeRecording(recording) {
261
+ if (recording.chunks.length === 0) {
262
+ return null;
263
+ }
264
+ // Determine channel count from the first chunk
265
+ const numChannels = recording.chunks[0].length;
266
+ // Calculate total number of frames across all chunks
267
+ let totalFrames = 0;
268
+ for (const chunk of recording.chunks) {
269
+ totalFrames += chunk[0].length;
270
+ }
271
+ if (totalFrames === 0) {
272
+ return null;
273
+ }
274
+ // Merge all chunks into per-channel Float32Arrays
275
+ const mergedChannels = [];
276
+ for (let ch = 0; ch < numChannels; ch++) {
277
+ const merged = new Float32Array(totalFrames);
278
+ let writePos = 0;
279
+ for (const chunk of recording.chunks) {
280
+ if (ch < chunk.length) {
281
+ merged.set(chunk[ch], writePos);
282
+ writePos += chunk[ch].length;
283
+ }
284
+ else {
285
+ // If this chunk has fewer channels, fill with silence
286
+ writePos += chunk[0].length;
287
+ }
288
+ }
289
+ mergedChannels.push(merged);
290
+ }
291
+ // Encode to WAV
292
+ const blob = MultiTrackRecorder._encodeWav(mergedChannels, this._sampleRate, numChannels);
293
+ return {
294
+ trackId: recording.trackId,
295
+ blob,
296
+ startFrame: recording.startFrame,
297
+ durationFrames: totalFrames,
298
+ takeNumber: recording.takeNumber,
299
+ peakLevel: recording.peakLevel,
300
+ hasClipped: recording.hasClipped,
301
+ };
302
+ }
303
+ /**
304
+ * Encode per-channel Float32Array data into a WAV file Blob.
305
+ *
306
+ * Produces a standard RIFF/WAVE file with IEEE Float32 audio format.
307
+ * Header layout follows the canonical WAV specification.
308
+ *
309
+ * @param channels - Per-channel audio data arrays (all same length)
310
+ * @param sampleRate - Sample rate in Hz
311
+ * @param numChannels - Number of audio channels
312
+ */
313
+ static _encodeWav(channels, sampleRate, numChannels) {
314
+ const totalFrames = channels[0].length;
315
+ const bitsPerSample = 32;
316
+ const bytesPerSample = bitsPerSample / 8;
317
+ const blockAlign = numChannels * bytesPerSample;
318
+ const byteRate = sampleRate * blockAlign;
319
+ const dataSize = totalFrames * blockAlign;
320
+ // Interleave channels: [L0, R0, L1, R1, ...]
321
+ const interleaved = new Float32Array(totalFrames * numChannels);
322
+ for (let frame = 0; frame < totalFrames; frame++) {
323
+ for (let ch = 0; ch < numChannels; ch++) {
324
+ interleaved[frame * numChannels + ch] = channels[ch][frame];
325
+ }
326
+ }
327
+ // Build WAV header (44 bytes)
328
+ const headerSize = 44;
329
+ const header = new ArrayBuffer(headerSize);
330
+ const view = new DataView(header);
331
+ // RIFF chunk descriptor
332
+ MultiTrackRecorder._writeString(view, 0, 'RIFF');
333
+ view.setUint32(4, 36 + dataSize, true); // ChunkSize
334
+ MultiTrackRecorder._writeString(view, 8, 'WAVE');
335
+ // fmt sub-chunk
336
+ MultiTrackRecorder._writeString(view, 12, 'fmt ');
337
+ view.setUint32(16, 16, true); // Subchunk1Size (16 for PCM/Float)
338
+ view.setUint16(20, 3, true); // AudioFormat: 3 = IEEE float
339
+ view.setUint16(22, numChannels, true); // NumChannels
340
+ view.setUint32(24, sampleRate, true); // SampleRate
341
+ view.setUint32(28, byteRate, true); // ByteRate
342
+ view.setUint16(32, blockAlign, true); // BlockAlign
343
+ view.setUint16(34, bitsPerSample, true); // BitsPerSample
344
+ // data sub-chunk
345
+ MultiTrackRecorder._writeString(view, 36, 'data');
346
+ view.setUint32(40, dataSize, true); // Subchunk2Size
347
+ // Combine header + interleaved sample data
348
+ return new Blob([header, interleaved.buffer], { type: 'audio/wav' });
349
+ }
350
+ /**
351
+ * Write an ASCII string into a DataView at the given byte offset.
352
+ */
353
+ static _writeString(view, offset, str) {
354
+ for (let i = 0; i < str.length; i++) {
355
+ view.setUint8(offset + i, str.charCodeAt(i));
356
+ }
357
+ }
358
+ }
359
+ //# sourceMappingURL=MultiTrackRecorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MultiTrackRecorder.js","sourceRoot":"","sources":["../../../src/audio/engine/MultiTrackRecorder.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PlaylistEngine.d.ts","sourceRoot":"","sources":["../../../src/audio/engine/PlaylistEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,qDAAqD;AACrD,0BAAkB,SAAS;IACvB,MAAM,IAAI;IACV,UAAU,IAAI;IACd,WAAW,IAAI;CAClB;AAED,qBAAa,cAAc;IACvB;;;;;OAKG;IACI,MAAM,CACT,UAAU,EAAE,YAAY,EACxB,WAAW,EAAE,YAAY,EACzB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,SAAS,EAAE,EACpB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,GAC/C,IAAI;IAwBP,OAAO,CAAC,YAAY;CAqEvB"}
1
+ {"version":3,"file":"PlaylistEngine.d.ts","sourceRoot":"","sources":["../../../src/audio/engine/PlaylistEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,qDAAqD;AACrD,0BAAkB,SAAS;IACvB,MAAM,IAAI;IACV,UAAU,IAAI;IACd,WAAW,IAAI;CAClB;AAED,qBAAa,cAAc;IACvB;;;;;OAKG;IACI,MAAM,CACT,UAAU,EAAE,YAAY,EACxB,WAAW,EAAE,YAAY,EACzB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,SAAS,EAAE,EACpB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,GAC/C,IAAI;IAwBP,OAAO,CAAC,YAAY;CA6EvB"}
@@ -41,7 +41,14 @@ export class PlaylistEngine {
41
41
  const outOffset = renderStart - startFrame;
42
42
  const length = renderEnd - renderStart;
43
43
  const playbackRate = region.playbackRate || 1.0;
44
- for (let i = 0; i < length; i++) {
44
+ // When playbackRate != 1, the source consumes samples faster/slower.
45
+ // Clamp the render length so we never read past the source buffer.
46
+ const maxSourceFrames = bufferDataL.length - 1 - regionOffset;
47
+ const maxOutputFrames = playbackRate > 0
48
+ ? Math.ceil(maxSourceFrames / playbackRate)
49
+ : length;
50
+ const clampedLength = Math.min(length, maxOutputFrames);
51
+ for (let i = 0; i < clampedLength; i++) {
45
52
  const outIdx = outOffset + i;
46
53
  // Skip positions already covered by a higher-layer region
47
54
  if (covered[outIdx])
@@ -50,7 +57,7 @@ export class PlaylistEngine {
50
57
  const sourcePosition = regionOffset + (i * playbackRate);
51
58
  const sampleIdx = Math.floor(sourcePosition);
52
59
  const frac = sourcePosition - sampleIdx;
53
- if (sampleIdx >= bufferDataL.length - 1)
60
+ if (sampleIdx < 0 || sampleIdx >= bufferDataL.length - 1)
54
61
  break;
55
62
  // Linear interpolation for resampling
56
63
  const sampleL0 = bufferDataL[sampleIdx];
@@ -1 +1 @@
1
- {"version":3,"file":"PlaylistEngine.js","sourceRoot":"","sources":["../../../src/audio/engine/PlaylistEngine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PlaylistEngine.js","sourceRoot":"","sources":["../../../src/audio/engine/PlaylistEngine.ts"],"names":[],"mappings":"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"}