@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.
- package/README.md +655 -237
- package/dist/actions/ActionRegistry.d.ts.map +1 -1
- package/dist/actions/ActionRegistry.js +7 -2
- package/dist/actions/ActionRegistry.js.map +1 -1
- package/dist/actions/types.d.ts +7 -1
- package/dist/actions/types.d.ts.map +1 -1
- package/dist/analysis/AudioAnalyzer.d.ts +71 -0
- package/dist/analysis/AudioAnalyzer.d.ts.map +1 -0
- package/dist/analysis/AudioAnalyzer.js +569 -0
- package/dist/analysis/AudioAnalyzer.js.map +1 -0
- package/dist/audio/AudioEngine.d.ts +14 -1
- package/dist/audio/AudioEngine.d.ts.map +1 -1
- package/dist/audio/AudioEngine.js +115 -35
- package/dist/audio/AudioEngine.js.map +1 -1
- package/dist/audio/Auditioner.d.ts +104 -0
- package/dist/audio/Auditioner.d.ts.map +1 -0
- package/dist/audio/Auditioner.js +239 -0
- package/dist/audio/Auditioner.js.map +1 -0
- package/dist/audio/BWFMetadata.d.ts +116 -0
- package/dist/audio/BWFMetadata.d.ts.map +1 -0
- package/dist/audio/BWFMetadata.js +394 -0
- package/dist/audio/BWFMetadata.js.map +1 -0
- package/dist/audio/ChannelSplitter.d.ts +37 -0
- package/dist/audio/ChannelSplitter.d.ts.map +1 -0
- package/dist/audio/ChannelSplitter.js +82 -0
- package/dist/audio/ChannelSplitter.js.map +1 -0
- package/dist/audio/ExportAnalyzer.d.ts +39 -0
- package/dist/audio/ExportAnalyzer.d.ts.map +1 -0
- package/dist/audio/ExportAnalyzer.js +76 -0
- package/dist/audio/ExportAnalyzer.js.map +1 -0
- package/dist/audio/LufsNormalizer.d.ts +37 -0
- package/dist/audio/LufsNormalizer.d.ts.map +1 -0
- package/dist/audio/LufsNormalizer.js +217 -0
- package/dist/audio/LufsNormalizer.js.map +1 -0
- package/dist/audio/OfflineExporter.d.ts +1 -6
- package/dist/audio/OfflineExporter.d.ts.map +1 -1
- package/dist/audio/OfflineExporter.js +31 -10
- package/dist/audio/OfflineExporter.js.map +1 -1
- package/dist/audio/RoutingGraph.d.ts +134 -0
- package/dist/audio/RoutingGraph.d.ts.map +1 -0
- package/dist/audio/RoutingGraph.js +547 -0
- package/dist/audio/RoutingGraph.js.map +1 -0
- package/dist/audio/SampleRateConverter.d.ts +21 -0
- package/dist/audio/SampleRateConverter.d.ts.map +1 -0
- package/dist/audio/SampleRateConverter.js +84 -0
- package/dist/audio/SampleRateConverter.js.map +1 -0
- package/dist/audio/SilencePadding.d.ts +29 -0
- package/dist/audio/SilencePadding.d.ts.map +1 -0
- package/dist/audio/SilencePadding.js +86 -0
- package/dist/audio/SilencePadding.js.map +1 -0
- package/dist/audio/SourceCache.d.ts +13 -16
- package/dist/audio/SourceCache.d.ts.map +1 -1
- package/dist/audio/SourceCache.js +21 -33
- package/dist/audio/SourceCache.js.map +1 -1
- package/dist/audio/engine/Declick.d.ts +98 -0
- package/dist/audio/engine/Declick.d.ts.map +1 -0
- package/dist/audio/engine/Declick.js +204 -0
- package/dist/audio/engine/Declick.js.map +1 -0
- package/dist/audio/engine/DiskIO.d.ts +172 -0
- package/dist/audio/engine/DiskIO.d.ts.map +1 -0
- package/dist/audio/engine/DiskIO.js +384 -0
- package/dist/audio/engine/DiskIO.js.map +1 -0
- package/dist/audio/engine/LatencyCompensator.d.ts +46 -0
- package/dist/audio/engine/LatencyCompensator.d.ts.map +1 -0
- package/dist/audio/engine/LatencyCompensator.js +84 -0
- package/dist/audio/engine/LatencyCompensator.js.map +1 -0
- package/dist/audio/engine/MultiTrackRecorder.d.ts +146 -0
- package/dist/audio/engine/MultiTrackRecorder.d.ts.map +1 -0
- package/dist/audio/engine/MultiTrackRecorder.js +359 -0
- package/dist/audio/engine/MultiTrackRecorder.js.map +1 -0
- package/dist/audio/engine/PlaylistEngine.d.ts.map +1 -1
- package/dist/audio/engine/PlaylistEngine.js +9 -2
- package/dist/audio/engine/PlaylistEngine.js.map +1 -1
- package/dist/audio/engine/PunchRecordManager.d.ts +113 -0
- package/dist/audio/engine/PunchRecordManager.d.ts.map +1 -0
- package/dist/audio/engine/PunchRecordManager.js +191 -0
- package/dist/audio/engine/PunchRecordManager.js.map +1 -0
- package/dist/audio/engine/RoutingGraph.d.ts +135 -0
- package/dist/audio/engine/RoutingGraph.d.ts.map +1 -0
- package/dist/audio/engine/RoutingGraph.js +436 -0
- package/dist/audio/engine/RoutingGraph.js.map +1 -0
- package/dist/audio/engine/SidechainRouter.d.ts +139 -0
- package/dist/audio/engine/SidechainRouter.d.ts.map +1 -0
- package/dist/audio/engine/SidechainRouter.js +292 -0
- package/dist/audio/engine/SidechainRouter.js.map +1 -0
- package/dist/audio/engine/XrunTracker.d.ts +71 -0
- package/dist/audio/engine/XrunTracker.d.ts.map +1 -0
- package/dist/audio/engine/XrunTracker.js +118 -0
- package/dist/audio/engine/XrunTracker.js.map +1 -0
- package/dist/audio/export/CDMarkerExporter.d.ts +62 -0
- package/dist/audio/export/CDMarkerExporter.d.ts.map +1 -0
- package/dist/audio/export/CDMarkerExporter.js +164 -0
- package/dist/audio/export/CDMarkerExporter.js.map +1 -0
- package/dist/audio/export/ExportGraphBuilder.d.ts +121 -0
- package/dist/audio/export/ExportGraphBuilder.d.ts.map +1 -0
- package/dist/audio/export/ExportGraphBuilder.js +522 -0
- package/dist/audio/export/ExportGraphBuilder.js.map +1 -0
- package/dist/audio/export/ExportPresetManager.d.ts +87 -0
- package/dist/audio/export/ExportPresetManager.d.ts.map +1 -0
- package/dist/audio/export/ExportPresetManager.js +306 -0
- package/dist/audio/export/ExportPresetManager.js.map +1 -0
- package/dist/commands/handlers/RegionHandler.d.ts.map +1 -1
- package/dist/commands/handlers/RegionHandler.js +25 -1
- package/dist/commands/handlers/RegionHandler.js.map +1 -1
- package/dist/commands/handlers/TrackHandler.js +1 -1
- package/dist/commands/handlers/TrackHandler.js.map +1 -1
- package/dist/commands/impl/FreezeTrackCommand.d.ts.map +1 -1
- package/dist/commands/impl/FreezeTrackCommand.js +37 -36
- package/dist/commands/impl/FreezeTrackCommand.js.map +1 -1
- package/dist/commands/impl/SetRegionTimeDomainCommand.d.ts.map +1 -1
- package/dist/commands/impl/SetRegionTimeDomainCommand.js +3 -3
- package/dist/commands/impl/SetRegionTimeDomainCommand.js.map +1 -1
- package/dist/commands/impl/ToggleLoopCommand.d.ts +1 -0
- package/dist/commands/impl/ToggleLoopCommand.d.ts.map +1 -1
- package/dist/commands/impl/ToggleLoopCommand.js +10 -0
- package/dist/commands/impl/ToggleLoopCommand.js.map +1 -1
- package/dist/commands/impl/TrimRegionCommand.d.ts +14 -1
- package/dist/commands/impl/TrimRegionCommand.d.ts.map +1 -1
- package/dist/commands/impl/TrimRegionCommand.js +138 -33
- package/dist/commands/impl/TrimRegionCommand.js.map +1 -1
- package/dist/commands/impl/TrimRegionToPlayheadCommand.d.ts +27 -0
- package/dist/commands/impl/TrimRegionToPlayheadCommand.d.ts.map +1 -0
- package/dist/commands/impl/TrimRegionToPlayheadCommand.js +69 -0
- package/dist/commands/impl/TrimRegionToPlayheadCommand.js.map +1 -0
- package/dist/commands/impl/TrimRegionToRangeCommand.d.ts +28 -0
- package/dist/commands/impl/TrimRegionToRangeCommand.d.ts.map +1 -0
- package/dist/commands/impl/TrimRegionToRangeCommand.js +69 -0
- package/dist/commands/impl/TrimRegionToRangeCommand.js.map +1 -0
- package/dist/commands/impl/TrimToAdjacentRegionCommand.d.ts +27 -0
- package/dist/commands/impl/TrimToAdjacentRegionCommand.d.ts.map +1 -0
- package/dist/commands/impl/TrimToAdjacentRegionCommand.js +77 -0
- package/dist/commands/impl/TrimToAdjacentRegionCommand.js.map +1 -0
- package/dist/commands/types.d.ts +19 -0
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js +21 -0
- package/dist/commands/types.js.map +1 -1
- package/dist/domain/Crossfade.d.ts +78 -0
- package/dist/domain/Crossfade.d.ts.map +1 -0
- package/dist/domain/Crossfade.js +216 -0
- package/dist/domain/Crossfade.js.map +1 -0
- package/dist/domain/ExportConfig.d.ts +98 -1
- package/dist/domain/ExportConfig.d.ts.map +1 -1
- package/dist/domain/ExportConfig.js +154 -1
- package/dist/domain/ExportConfig.js.map +1 -1
- package/dist/domain/ExportPreset.d.ts +62 -0
- package/dist/domain/ExportPreset.d.ts.map +1 -0
- package/dist/domain/ExportPreset.js +79 -0
- package/dist/domain/ExportPreset.js.map +1 -0
- package/dist/domain/ImportStatus.d.ts +40 -0
- package/dist/domain/ImportStatus.d.ts.map +1 -0
- package/dist/domain/ImportStatus.js +86 -0
- package/dist/domain/ImportStatus.js.map +1 -0
- package/dist/domain/Playlist.d.ts +72 -0
- package/dist/domain/Playlist.d.ts.map +1 -1
- package/dist/domain/Playlist.js +231 -6
- package/dist/domain/Playlist.js.map +1 -1
- package/dist/domain/Region.d.ts +76 -0
- package/dist/domain/Region.d.ts.map +1 -1
- package/dist/domain/Region.js +234 -1
- package/dist/domain/Region.js.map +1 -1
- package/dist/domain/Route.d.ts +43 -3
- package/dist/domain/Route.d.ts.map +1 -1
- package/dist/domain/Route.js +92 -6
- package/dist/domain/Route.js.map +1 -1
- package/dist/domain/Session.d.ts +31 -0
- package/dist/domain/Session.d.ts.map +1 -1
- package/dist/domain/Session.js +70 -0
- package/dist/domain/Session.js.map +1 -1
- package/dist/domain/Source.d.ts +145 -1
- package/dist/domain/Source.d.ts.map +1 -1
- package/dist/domain/Source.js +144 -1
- package/dist/domain/Source.js.map +1 -1
- package/dist/domain/ThawList.d.ts +37 -0
- package/dist/domain/ThawList.d.ts.map +1 -0
- package/dist/domain/ThawList.js +73 -0
- package/dist/domain/ThawList.js.map +1 -0
- package/dist/domain/Track.d.ts +93 -1
- package/dist/domain/Track.d.ts.map +1 -1
- package/dist/domain/Track.js +136 -0
- package/dist/domain/Track.js.map +1 -1
- package/dist/domain/TriggerBox.d.ts +123 -0
- package/dist/domain/TriggerBox.d.ts.map +1 -0
- package/dist/domain/TriggerBox.js +430 -0
- package/dist/domain/TriggerBox.js.map +1 -0
- package/dist/domain/VCATrack.d.ts +64 -1
- package/dist/domain/VCATrack.d.ts.map +1 -1
- package/dist/domain/VCATrack.js +128 -1
- package/dist/domain/VCATrack.js.map +1 -1
- package/dist/domain/VideoExportConfig.d.ts +117 -0
- package/dist/domain/VideoExportConfig.d.ts.map +1 -0
- package/dist/domain/VideoExportConfig.js +244 -0
- package/dist/domain/VideoExportConfig.js.map +1 -0
- package/dist/domain/VideoExportStatus.d.ts +89 -0
- package/dist/domain/VideoExportStatus.d.ts.map +1 -0
- package/dist/domain/VideoExportStatus.js +192 -0
- package/dist/domain/VideoExportStatus.js.map +1 -0
- package/dist/domain/VideoMetadata.d.ts +46 -0
- package/dist/domain/VideoMetadata.d.ts.map +1 -0
- package/dist/domain/VideoMetadata.js +2 -0
- package/dist/domain/VideoMetadata.js.map +1 -0
- package/dist/domain/index.d.ts +5 -0
- package/dist/domain/index.d.ts.map +1 -1
- package/dist/domain/index.js +5 -0
- package/dist/domain/index.js.map +1 -1
- package/dist/domain/temporal/TempoMap.d.ts +199 -2
- package/dist/domain/temporal/TempoMap.d.ts.map +1 -1
- package/dist/domain/temporal/TempoMap.js +464 -30
- package/dist/domain/temporal/TempoMap.js.map +1 -1
- package/dist/index.d.ts +43 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/ThawList.d.ts +100 -0
- package/dist/lib/ThawList.d.ts.map +1 -0
- package/dist/lib/ThawList.js +153 -0
- package/dist/lib/ThawList.js.map +1 -0
- package/dist/midi/MidiFileParser.d.ts +33 -0
- package/dist/midi/MidiFileParser.d.ts.map +1 -0
- package/dist/midi/MidiFileParser.js +246 -0
- package/dist/midi/MidiFileParser.js.map +1 -0
- package/dist/midi/MidiFileWriter.d.ts +31 -0
- package/dist/midi/MidiFileWriter.d.ts.map +1 -0
- package/dist/midi/MidiFileWriter.js +160 -0
- package/dist/midi/MidiFileWriter.js.map +1 -0
- package/dist/midi/MidiImporter.d.ts +37 -0
- package/dist/midi/MidiImporter.d.ts.map +1 -0
- package/dist/midi/MidiImporter.js +62 -0
- package/dist/midi/MidiImporter.js.map +1 -0
- package/dist/plugins/PluginPresetManager.d.ts +86 -0
- package/dist/plugins/PluginPresetManager.d.ts.map +1 -0
- package/dist/plugins/PluginPresetManager.js +140 -0
- package/dist/plugins/PluginPresetManager.js.map +1 -0
- package/dist/processing/IO.d.ts +15 -1
- package/dist/processing/IO.d.ts.map +1 -1
- package/dist/processing/IO.js +29 -1
- package/dist/processing/IO.js.map +1 -1
- package/dist/processing/InternalSend.d.ts +104 -0
- package/dist/processing/InternalSend.d.ts.map +1 -0
- package/dist/processing/InternalSend.js +175 -0
- package/dist/processing/InternalSend.js.map +1 -0
- package/dist/processing/MeterDSP.d.ts +166 -0
- package/dist/processing/MeterDSP.d.ts.map +1 -0
- package/dist/processing/MeterDSP.js +754 -0
- package/dist/processing/MeterDSP.js.map +1 -0
- package/dist/processing/Panner.d.ts +145 -0
- package/dist/processing/Panner.d.ts.map +1 -0
- package/dist/processing/Panner.js +281 -0
- package/dist/processing/Panner.js.map +1 -0
- package/dist/processing/PluginInsert.d.ts +56 -1
- package/dist/processing/PluginInsert.d.ts.map +1 -1
- package/dist/processing/PluginInsert.js +180 -2
- package/dist/processing/PluginInsert.js.map +1 -1
- package/dist/processing/Processor.d.ts +38 -0
- package/dist/processing/Processor.d.ts.map +1 -1
- package/dist/processing/Processor.js +60 -1
- package/dist/processing/Processor.js.map +1 -1
- package/dist/processing/SurroundPanner.d.ts +122 -0
- package/dist/processing/SurroundPanner.d.ts.map +1 -0
- package/dist/processing/SurroundPanner.js +376 -0
- package/dist/processing/SurroundPanner.js.map +1 -0
- package/dist/processing/TruePeakLimiter.d.ts +34 -0
- package/dist/processing/TruePeakLimiter.d.ts.map +1 -0
- package/dist/processing/TruePeakLimiter.js +144 -0
- package/dist/processing/TruePeakLimiter.js.map +1 -0
- package/dist/storage/ExportPresetStorage.d.ts +33 -0
- package/dist/storage/ExportPresetStorage.d.ts.map +1 -0
- package/dist/storage/ExportPresetStorage.js +121 -0
- package/dist/storage/ExportPresetStorage.js.map +1 -0
- package/dist/storage/SessionArchive.d.ts +73 -0
- package/dist/storage/SessionArchive.d.ts.map +1 -0
- package/dist/storage/SessionArchive.js +211 -0
- package/dist/storage/SessionArchive.js.map +1 -0
- package/dist/storage/SessionTemplate.d.ts +74 -5
- package/dist/storage/SessionTemplate.d.ts.map +1 -1
- package/dist/storage/SessionTemplate.js +247 -53
- package/dist/storage/SessionTemplate.js.map +1 -1
- package/dist/utils/BwfMetadataWriter.d.ts +42 -0
- package/dist/utils/BwfMetadataWriter.d.ts.map +1 -0
- package/dist/utils/BwfMetadataWriter.js +131 -0
- package/dist/utils/BwfMetadataWriter.js.map +1 -0
- package/dist/utils/FilenameTemplate.d.ts +40 -0
- package/dist/utils/FilenameTemplate.d.ts.map +1 -0
- package/dist/utils/FilenameTemplate.js +78 -0
- package/dist/utils/FilenameTemplate.js.map +1 -0
- package/dist/utils/Logger.d.ts +28 -0
- package/dist/utils/Logger.d.ts.map +1 -0
- package/dist/utils/Logger.js +46 -0
- package/dist/utils/Logger.js.map +1 -0
- package/dist/utils/Mp4ChapterGenerator.d.ts +17 -0
- package/dist/utils/Mp4ChapterGenerator.d.ts.map +1 -0
- package/dist/utils/Mp4ChapterGenerator.js +33 -0
- package/dist/utils/Mp4ChapterGenerator.js.map +1 -0
- package/dist/utils/OggEncoder.d.ts +20 -20
- package/dist/utils/OggEncoder.d.ts.map +1 -1
- package/dist/utils/OggEncoder.js +114 -50
- package/dist/utils/OggEncoder.js.map +1 -1
- package/dist/utils/TocGenerator.d.ts +17 -0
- package/dist/utils/TocGenerator.d.ts.map +1 -0
- package/dist/utils/TocGenerator.js +47 -0
- package/dist/utils/TocGenerator.js.map +1 -0
- package/package.json +7 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportPreset.d.ts","sourceRoot":"","sources":["../../src/domain/ExportPreset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,YAAY,EAAE,kBAAkB,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IAEzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;IACxC,WAAW,EAAE,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,qBAAa,YAAY;IACrB,SAAgB,EAAE,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACpB,SAAgB,OAAO,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,kBAAkB,CAAC;IAElC,SAAgB,OAAO,uBAA8B;gBAEzC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,GAAE,OAAe;IAOnF,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAO3B,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,IAAI;IAKvD,MAAM,IAAI,oBAAoB;WASvB,QAAQ,CAAC,IAAI,EAAE,oBAAoB,GAAG,YAAY;CAGnE;AAED,MAAM,WAAW,oBAAoB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,kBAAkB,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,kBAAkB,CAuBxD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,YAAY,EAAE,CA2DlD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Signal } from '../lib/Signal';
|
|
2
|
+
import { ExportFormat, ExportSampleFormat } from './ExportConfig';
|
|
3
|
+
import { DitherType } from '../utils/DitherProcessor';
|
|
4
|
+
/**
|
|
5
|
+
* Export Preset — a saved configuration snapshot for quick recall.
|
|
6
|
+
* Ardour reference: libs/ardour/ardour/export_preset.h
|
|
7
|
+
*/
|
|
8
|
+
export class ExportPreset {
|
|
9
|
+
constructor(id, name, config, builtIn = false) {
|
|
10
|
+
this.changed = new Signal();
|
|
11
|
+
this.id = id;
|
|
12
|
+
this.name = name;
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.builtIn = builtIn;
|
|
15
|
+
}
|
|
16
|
+
setName(name) {
|
|
17
|
+
if (this.name !== name) {
|
|
18
|
+
this.name = name;
|
|
19
|
+
this.changed.emit(this);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
updateConfig(config) {
|
|
23
|
+
this.config = Object.assign(Object.assign({}, this.config), config);
|
|
24
|
+
this.changed.emit(this);
|
|
25
|
+
}
|
|
26
|
+
toJSON() {
|
|
27
|
+
return {
|
|
28
|
+
id: this.id,
|
|
29
|
+
name: this.name,
|
|
30
|
+
builtIn: this.builtIn,
|
|
31
|
+
config: Object.assign({}, this.config),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
static fromJSON(data) {
|
|
35
|
+
return new ExportPreset(data.id, data.name, data.config, data.builtIn);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Default preset configuration values.
|
|
40
|
+
*/
|
|
41
|
+
export function defaultPresetConfig() {
|
|
42
|
+
return {
|
|
43
|
+
format: ExportFormat.WAV,
|
|
44
|
+
sampleFormat: ExportSampleFormat.FLOAT32,
|
|
45
|
+
sampleRate: 44100,
|
|
46
|
+
ditherType: DitherType.NONE,
|
|
47
|
+
normalize: false,
|
|
48
|
+
normalizeMode: 'peak',
|
|
49
|
+
targetPeakDb: -1,
|
|
50
|
+
targetLufs: -14,
|
|
51
|
+
truePeakLimit: false,
|
|
52
|
+
truePeakCeiling: -1.0,
|
|
53
|
+
exportMasterOnly: true,
|
|
54
|
+
stemExport: false,
|
|
55
|
+
splitMono: false,
|
|
56
|
+
filenameTemplate: '%s',
|
|
57
|
+
silencePaddingStart: 0,
|
|
58
|
+
silencePaddingEnd: 0,
|
|
59
|
+
trimSilence: false,
|
|
60
|
+
exportCdMarkers: false,
|
|
61
|
+
cdMarkerFormat: 'cue',
|
|
62
|
+
bwfMetadata: false,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Built-in presets matching common professional workflows.
|
|
67
|
+
* Ardour reference: share/export/*.preset (15+ presets)
|
|
68
|
+
*/
|
|
69
|
+
export function getBuiltInPresets() {
|
|
70
|
+
return [
|
|
71
|
+
new ExportPreset('builtin-cd-quality', 'CD Quality (WAV 16-bit 44.1kHz)', Object.assign(Object.assign({}, defaultPresetConfig()), { format: ExportFormat.WAV, sampleFormat: ExportSampleFormat.INT16, sampleRate: 44100, ditherType: DitherType.TPDF, filenameTemplate: '%s' }), true),
|
|
72
|
+
new ExportPreset('builtin-high-quality', 'High Quality (WAV 24-bit 48kHz)', Object.assign(Object.assign({}, defaultPresetConfig()), { format: ExportFormat.WAV, sampleFormat: ExportSampleFormat.INT24, sampleRate: 48000, filenameTemplate: '%s' }), true),
|
|
73
|
+
new ExportPreset('builtin-mp3-320', 'MP3 320kbps', Object.assign(Object.assign({}, defaultPresetConfig()), { format: ExportFormat.MP3, sampleRate: 44100, bitrate: 320, filenameTemplate: '%s' }), true),
|
|
74
|
+
new ExportPreset('builtin-streaming', 'Streaming (MP3 192kbps)', Object.assign(Object.assign({}, defaultPresetConfig()), { format: ExportFormat.MP3, sampleRate: 44100, bitrate: 192, normalize: true, normalizeMode: 'lufs', targetLufs: -14, truePeakLimit: true, truePeakCeiling: -1.0, filenameTemplate: '%s' }), true),
|
|
75
|
+
new ExportPreset('builtin-flac-archive', 'FLAC Archive (24-bit 96kHz)', Object.assign(Object.assign({}, defaultPresetConfig()), { format: ExportFormat.FLAC, sampleFormat: ExportSampleFormat.INT24, sampleRate: 96000, filenameTemplate: '%s_%d' }), true),
|
|
76
|
+
new ExportPreset('builtin-ogg-podcast', 'OGG Vorbis (Podcast)', Object.assign(Object.assign({}, defaultPresetConfig()), { format: ExportFormat.OGG, sampleRate: 44100, quality: 0.6, normalize: true, normalizeMode: 'lufs', targetLufs: -16, filenameTemplate: '%s' }), true),
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=ExportPreset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportPreset.js","sourceRoot":"","sources":["../../src/domain/ExportPreset.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Signal } from '../lib/Signal';
|
|
2
|
+
/**
|
|
3
|
+
* Import Status — mirrors ExportStatus for import operations.
|
|
4
|
+
* Tracks progress of multi-file import operations.
|
|
5
|
+
*/
|
|
6
|
+
export declare enum ImportProgress {
|
|
7
|
+
IDLE = "idle",
|
|
8
|
+
LOADING = "loading",
|
|
9
|
+
DECODING = "decoding",
|
|
10
|
+
RESAMPLING = "resampling",
|
|
11
|
+
SPLITTING = "splitting",
|
|
12
|
+
COMPLETE = "complete",
|
|
13
|
+
FAILED = "failed"
|
|
14
|
+
}
|
|
15
|
+
export declare class ImportStatus {
|
|
16
|
+
private _progress;
|
|
17
|
+
private _running;
|
|
18
|
+
totalFiles: number;
|
|
19
|
+
completedFiles: number;
|
|
20
|
+
currentFilename: string;
|
|
21
|
+
errorMessage: string;
|
|
22
|
+
readonly progressChanged: Signal<ImportProgress>;
|
|
23
|
+
readonly fileCompleted: Signal<{
|
|
24
|
+
index: number;
|
|
25
|
+
filename: string;
|
|
26
|
+
}>;
|
|
27
|
+
readonly finished: Signal<boolean>;
|
|
28
|
+
readonly errorOccurred: Signal<string>;
|
|
29
|
+
get progress(): ImportProgress;
|
|
30
|
+
get running(): boolean;
|
|
31
|
+
get percentComplete(): number;
|
|
32
|
+
init(totalFiles: number): void;
|
|
33
|
+
setProgress(progress: ImportProgress): void;
|
|
34
|
+
setCurrentFile(filename: string): void;
|
|
35
|
+
completeFile(filename: string): void;
|
|
36
|
+
complete(): void;
|
|
37
|
+
setError(message: string): void;
|
|
38
|
+
reset(): void;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=ImportStatus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImportStatus.d.ts","sourceRoot":"","sources":["../../src/domain/ImportStatus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC;;;GAGG;AACH,oBAAY,cAAc;IACtB,IAAI,SAAS;IACb,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,UAAU,eAAe;IACzB,SAAS,cAAc;IACvB,QAAQ,aAAa;IACrB,MAAM,WAAW;CACpB;AAED,qBAAa,YAAY;IACrB,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,QAAQ,CAAkB;IAE3B,UAAU,EAAE,MAAM,CAAK;IACvB,cAAc,EAAE,MAAM,CAAK;IAC3B,eAAe,EAAE,MAAM,CAAM;IAC7B,YAAY,EAAE,MAAM,CAAM;IAGjC,SAAgB,eAAe,yBAAgC;IAC/D,SAAgB,aAAa;eAAuB,MAAM;kBAAY,MAAM;OAAM;IAClF,SAAgB,QAAQ,kBAAyB;IACjD,SAAgB,aAAa,iBAAwB;IAErD,IAAW,QAAQ,IAAI,cAAc,CAEpC;IAED,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED,IAAW,eAAe,IAAI,MAAM,CAGnC;IAEM,IAAI,CAAC,UAAU,EAAE,MAAM;IAUvB,WAAW,CAAC,QAAQ,EAAE,cAAc;IAOpC,cAAc,CAAC,QAAQ,EAAE,MAAM;IAI/B,YAAY,CAAC,QAAQ,EAAE,MAAM;IAK7B,QAAQ;IAOR,QAAQ,CAAC,OAAO,EAAE,MAAM;IASxB,KAAK;CAQf"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Signal } from '../lib/Signal';
|
|
2
|
+
/**
|
|
3
|
+
* Import Status — mirrors ExportStatus for import operations.
|
|
4
|
+
* Tracks progress of multi-file import operations.
|
|
5
|
+
*/
|
|
6
|
+
export var ImportProgress;
|
|
7
|
+
(function (ImportProgress) {
|
|
8
|
+
ImportProgress["IDLE"] = "idle";
|
|
9
|
+
ImportProgress["LOADING"] = "loading";
|
|
10
|
+
ImportProgress["DECODING"] = "decoding";
|
|
11
|
+
ImportProgress["RESAMPLING"] = "resampling";
|
|
12
|
+
ImportProgress["SPLITTING"] = "splitting";
|
|
13
|
+
ImportProgress["COMPLETE"] = "complete";
|
|
14
|
+
ImportProgress["FAILED"] = "failed";
|
|
15
|
+
})(ImportProgress || (ImportProgress = {}));
|
|
16
|
+
export class ImportStatus {
|
|
17
|
+
constructor() {
|
|
18
|
+
this._progress = ImportProgress.IDLE;
|
|
19
|
+
this._running = false;
|
|
20
|
+
this.totalFiles = 0;
|
|
21
|
+
this.completedFiles = 0;
|
|
22
|
+
this.currentFilename = '';
|
|
23
|
+
this.errorMessage = '';
|
|
24
|
+
// Signals
|
|
25
|
+
this.progressChanged = new Signal();
|
|
26
|
+
this.fileCompleted = new Signal();
|
|
27
|
+
this.finished = new Signal();
|
|
28
|
+
this.errorOccurred = new Signal();
|
|
29
|
+
}
|
|
30
|
+
get progress() {
|
|
31
|
+
return this._progress;
|
|
32
|
+
}
|
|
33
|
+
get running() {
|
|
34
|
+
return this._running;
|
|
35
|
+
}
|
|
36
|
+
get percentComplete() {
|
|
37
|
+
if (this.totalFiles === 0)
|
|
38
|
+
return 0;
|
|
39
|
+
return (this.completedFiles / this.totalFiles) * 100;
|
|
40
|
+
}
|
|
41
|
+
init(totalFiles) {
|
|
42
|
+
this._progress = ImportProgress.LOADING;
|
|
43
|
+
this._running = true;
|
|
44
|
+
this.totalFiles = totalFiles;
|
|
45
|
+
this.completedFiles = 0;
|
|
46
|
+
this.currentFilename = '';
|
|
47
|
+
this.errorMessage = '';
|
|
48
|
+
this.progressChanged.emit(this._progress);
|
|
49
|
+
}
|
|
50
|
+
setProgress(progress) {
|
|
51
|
+
if (this._progress !== progress) {
|
|
52
|
+
this._progress = progress;
|
|
53
|
+
this.progressChanged.emit(progress);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
setCurrentFile(filename) {
|
|
57
|
+
this.currentFilename = filename;
|
|
58
|
+
}
|
|
59
|
+
completeFile(filename) {
|
|
60
|
+
this.completedFiles++;
|
|
61
|
+
this.fileCompleted.emit({ index: this.completedFiles, filename });
|
|
62
|
+
}
|
|
63
|
+
complete() {
|
|
64
|
+
this._progress = ImportProgress.COMPLETE;
|
|
65
|
+
this._running = false;
|
|
66
|
+
this.progressChanged.emit(this._progress);
|
|
67
|
+
this.finished.emit(true);
|
|
68
|
+
}
|
|
69
|
+
setError(message) {
|
|
70
|
+
this._progress = ImportProgress.FAILED;
|
|
71
|
+
this._running = false;
|
|
72
|
+
this.errorMessage = message;
|
|
73
|
+
this.progressChanged.emit(this._progress);
|
|
74
|
+
this.errorOccurred.emit(message);
|
|
75
|
+
this.finished.emit(false);
|
|
76
|
+
}
|
|
77
|
+
reset() {
|
|
78
|
+
this._progress = ImportProgress.IDLE;
|
|
79
|
+
this._running = false;
|
|
80
|
+
this.totalFiles = 0;
|
|
81
|
+
this.completedFiles = 0;
|
|
82
|
+
this.currentFilename = '';
|
|
83
|
+
this.errorMessage = '';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=ImportStatus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImportStatus.js","sourceRoot":"","sources":["../../src/domain/ImportStatus.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Region } from './Region';
|
|
2
2
|
import { MidiRegion } from './MidiRegion';
|
|
3
|
+
import { Crossfade, CrossfadeId } from './Crossfade';
|
|
3
4
|
import { RegionId, FrameCount } from './types';
|
|
4
5
|
import { Signal } from '../lib/Signal';
|
|
5
6
|
export declare class Playlist {
|
|
@@ -7,12 +8,17 @@ export declare class Playlist {
|
|
|
7
8
|
name: string;
|
|
8
9
|
private regions;
|
|
9
10
|
private midiRegions;
|
|
11
|
+
private _crossfades;
|
|
12
|
+
private _thawList;
|
|
10
13
|
readonly regionAdded: Signal<Region>;
|
|
11
14
|
readonly regionRemoved: Signal<string>;
|
|
12
15
|
readonly regionChanged: Signal<Region>;
|
|
13
16
|
readonly midiRegionAdded: Signal<MidiRegion>;
|
|
14
17
|
readonly midiRegionRemoved: Signal<string>;
|
|
15
18
|
readonly midiRegionChanged: Signal<MidiRegion>;
|
|
19
|
+
readonly crossfadeAdded: Signal<Crossfade>;
|
|
20
|
+
readonly crossfadeRemoved: Signal<string>;
|
|
21
|
+
readonly crossfadeChanged: Signal<Crossfade>;
|
|
16
22
|
constructor(id: string, name: string);
|
|
17
23
|
addRegion(region: Region): void;
|
|
18
24
|
removeRegion(regionId: RegionId): void;
|
|
@@ -79,5 +85,71 @@ export declare class Playlist {
|
|
|
79
85
|
start: FrameCount;
|
|
80
86
|
end: FrameCount;
|
|
81
87
|
};
|
|
88
|
+
/**
|
|
89
|
+
* Add a crossfade to the playlist. Subscribes to its changed signal
|
|
90
|
+
* so the playlist can re-emit crossfadeChanged.
|
|
91
|
+
*/
|
|
92
|
+
addCrossfade(crossfade: Crossfade): void;
|
|
93
|
+
/**
|
|
94
|
+
* Remove a crossfade by its ID.
|
|
95
|
+
*/
|
|
96
|
+
removeCrossfade(id: CrossfadeId): void;
|
|
97
|
+
/**
|
|
98
|
+
* Get a crossfade by its ID.
|
|
99
|
+
*/
|
|
100
|
+
getCrossfade(id: CrossfadeId): Crossfade | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* Get all crossfades in the playlist.
|
|
103
|
+
*/
|
|
104
|
+
getCrossfades(): ReadonlyArray<Crossfade>;
|
|
105
|
+
/**
|
|
106
|
+
* Get all crossfades that involve the given region (as either the
|
|
107
|
+
* fade-in or fade-out side).
|
|
108
|
+
*/
|
|
109
|
+
getCrossfadesForRegion(regionId: RegionId): Crossfade[];
|
|
110
|
+
/**
|
|
111
|
+
* Auto-detect the overlap between two regions and create a crossfade if
|
|
112
|
+
* they overlap. Returns the created crossfade, or null if there is no
|
|
113
|
+
* overlap.
|
|
114
|
+
*
|
|
115
|
+
* @param regionA First region.
|
|
116
|
+
* @param regionB Second region.
|
|
117
|
+
* @param defaultLength Optional: override the crossfade length instead of
|
|
118
|
+
* using the actual overlap length.
|
|
119
|
+
*/
|
|
120
|
+
autoCreateCrossfade(regionA: Region, regionB: Region, defaultLength?: FrameCount): Crossfade | null;
|
|
121
|
+
/**
|
|
122
|
+
* Recalculate all crossfades that involve a given region. Call this after
|
|
123
|
+
* a region is moved, resized, or trimmed so that the crossfade positions
|
|
124
|
+
* and lengths stay in sync with the actual overlap.
|
|
125
|
+
*
|
|
126
|
+
* Crossfades whose regions no longer overlap are automatically removed.
|
|
127
|
+
*/
|
|
128
|
+
updateCrossfadesForRegion(regionId: RegionId): void;
|
|
129
|
+
/** Freeze signal emissions; all signals are queued until thaw(). */
|
|
130
|
+
freeze(): void;
|
|
131
|
+
/** Thaw and emit all queued signals. */
|
|
132
|
+
thaw(): void;
|
|
133
|
+
/**
|
|
134
|
+
* Split all regions at a given frame position.
|
|
135
|
+
* Regions that span the frame are split into two: one ending at the frame
|
|
136
|
+
* and one starting at the frame. Regions that don't cover the frame are
|
|
137
|
+
* left untouched.
|
|
138
|
+
*/
|
|
139
|
+
partition(frame: number): void;
|
|
140
|
+
/**
|
|
141
|
+
* Duplicate a single region with a time offset.
|
|
142
|
+
* Returns the new region, or null if the source region was not found.
|
|
143
|
+
*/
|
|
144
|
+
duplicateRegion(regionId: string, offset: number): Region | null;
|
|
145
|
+
/**
|
|
146
|
+
* Duplicate multiple regions with a time offset.
|
|
147
|
+
* Returns an array of the newly created regions.
|
|
148
|
+
*/
|
|
149
|
+
duplicateRegions(regionIds: string[], offset: number): Region[];
|
|
150
|
+
/** Nudge all regions by the given number of frames (positive or negative). */
|
|
151
|
+
nudge(frames: number): void;
|
|
152
|
+
/** Nudge a single region by the given number of frames. */
|
|
153
|
+
nudgeRegion(regionId: string, frames: number): void;
|
|
82
154
|
}
|
|
83
155
|
//# sourceMappingURL=Playlist.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Playlist.d.ts","sourceRoot":"","sources":["../../src/domain/Playlist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"Playlist.d.ts","sourceRoot":"","sources":["../../src/domain/Playlist.ts"],"names":[],"mappings":"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"}
|
package/dist/domain/Playlist.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import { Region } from './Region';
|
|
2
|
+
import { Crossfade, CrossfadeType, FadeCurve } from './Crossfade';
|
|
1
3
|
import { Signal } from '../lib/Signal';
|
|
4
|
+
import { ThawList } from './ThawList';
|
|
2
5
|
export class Playlist {
|
|
3
6
|
constructor(id, name) {
|
|
4
7
|
this.regions = [];
|
|
5
8
|
this.midiRegions = [];
|
|
9
|
+
this._crossfades = new Map();
|
|
10
|
+
this._thawList = new ThawList();
|
|
6
11
|
// Signals (Audio Regions)
|
|
7
12
|
this.regionAdded = new Signal();
|
|
8
13
|
this.regionRemoved = new Signal();
|
|
@@ -11,18 +16,33 @@ export class Playlist {
|
|
|
11
16
|
this.midiRegionAdded = new Signal();
|
|
12
17
|
this.midiRegionRemoved = new Signal();
|
|
13
18
|
this.midiRegionChanged = new Signal();
|
|
19
|
+
// Signals (Crossfades)
|
|
20
|
+
this.crossfadeAdded = new Signal();
|
|
21
|
+
this.crossfadeRemoved = new Signal();
|
|
22
|
+
this.crossfadeChanged = new Signal();
|
|
14
23
|
this.id = id;
|
|
15
24
|
this.name = name;
|
|
16
25
|
}
|
|
17
26
|
addRegion(region) {
|
|
18
|
-
// TODO: Handle overlaps (layers or crossfades)
|
|
19
27
|
this.regions.push(region);
|
|
20
28
|
this.sortRegions();
|
|
21
|
-
this.
|
|
29
|
+
this._thawList.queueEmission(this.regionAdded, region);
|
|
30
|
+
// Auto-create crossfades for overlapping regions on the same layer
|
|
31
|
+
const overlapping = this.getOverlappingRegions(region);
|
|
32
|
+
for (const other of overlapping) {
|
|
33
|
+
if (other.layer === region.layer) {
|
|
34
|
+
this.autoCreateCrossfade(region, other);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
22
37
|
}
|
|
23
38
|
removeRegion(regionId) {
|
|
39
|
+
// Remove any crossfades associated with this region
|
|
40
|
+
const relatedCrossfades = this.getCrossfadesForRegion(regionId);
|
|
41
|
+
for (const xfade of relatedCrossfades) {
|
|
42
|
+
this.removeCrossfade(xfade.id);
|
|
43
|
+
}
|
|
24
44
|
this.regions = this.regions.filter(r => r.id !== regionId);
|
|
25
|
-
this.
|
|
45
|
+
this._thawList.queueEmission(this.regionRemoved, regionId);
|
|
26
46
|
}
|
|
27
47
|
getRegions() {
|
|
28
48
|
return this.regions;
|
|
@@ -42,7 +62,7 @@ export class Playlist {
|
|
|
42
62
|
if (region.start >= afterFrame) {
|
|
43
63
|
const newStart = Math.max(0, region.start + deltaFrames);
|
|
44
64
|
region.move(newStart);
|
|
45
|
-
this.
|
|
65
|
+
this._thawList.queueEmission(this.regionChanged, region);
|
|
46
66
|
}
|
|
47
67
|
}
|
|
48
68
|
this.sortRegions();
|
|
@@ -54,11 +74,11 @@ export class Playlist {
|
|
|
54
74
|
addMidiRegion(region) {
|
|
55
75
|
this.midiRegions.push(region);
|
|
56
76
|
this.sortMidiRegions();
|
|
57
|
-
this.
|
|
77
|
+
this._thawList.queueEmission(this.midiRegionAdded, region);
|
|
58
78
|
}
|
|
59
79
|
removeMidiRegion(regionId) {
|
|
60
80
|
this.midiRegions = this.midiRegions.filter(r => r.id !== regionId);
|
|
61
|
-
this.
|
|
81
|
+
this._thawList.queueEmission(this.midiRegionRemoved, regionId);
|
|
62
82
|
}
|
|
63
83
|
getMidiRegions() {
|
|
64
84
|
return this.midiRegions;
|
|
@@ -201,5 +221,210 @@ export class Playlist {
|
|
|
201
221
|
}
|
|
202
222
|
return { start: earliest, end: latest };
|
|
203
223
|
}
|
|
224
|
+
// ─── Crossfade Management ────────────────────────────────────────────────
|
|
225
|
+
/**
|
|
226
|
+
* Add a crossfade to the playlist. Subscribes to its changed signal
|
|
227
|
+
* so the playlist can re-emit crossfadeChanged.
|
|
228
|
+
*/
|
|
229
|
+
addCrossfade(crossfade) {
|
|
230
|
+
this._crossfades.set(crossfade.id, crossfade);
|
|
231
|
+
crossfade.changed.connect(() => {
|
|
232
|
+
this._thawList.queueEmission(this.crossfadeChanged, crossfade);
|
|
233
|
+
});
|
|
234
|
+
this._thawList.queueEmission(this.crossfadeAdded, crossfade);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Remove a crossfade by its ID.
|
|
238
|
+
*/
|
|
239
|
+
removeCrossfade(id) {
|
|
240
|
+
const crossfade = this._crossfades.get(id);
|
|
241
|
+
if (!crossfade)
|
|
242
|
+
return;
|
|
243
|
+
crossfade.changed.clear();
|
|
244
|
+
this._crossfades.delete(id);
|
|
245
|
+
this._thawList.queueEmission(this.crossfadeRemoved, id);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Get a crossfade by its ID.
|
|
249
|
+
*/
|
|
250
|
+
getCrossfade(id) {
|
|
251
|
+
return this._crossfades.get(id);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Get all crossfades in the playlist.
|
|
255
|
+
*/
|
|
256
|
+
getCrossfades() {
|
|
257
|
+
return Array.from(this._crossfades.values());
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Get all crossfades that involve the given region (as either the
|
|
261
|
+
* fade-in or fade-out side).
|
|
262
|
+
*/
|
|
263
|
+
getCrossfadesForRegion(regionId) {
|
|
264
|
+
const result = [];
|
|
265
|
+
for (const xfade of this._crossfades.values()) {
|
|
266
|
+
if (xfade.inRegionId === regionId || xfade.outRegionId === regionId) {
|
|
267
|
+
result.push(xfade);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return result;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Auto-detect the overlap between two regions and create a crossfade if
|
|
274
|
+
* they overlap. Returns the created crossfade, or null if there is no
|
|
275
|
+
* overlap.
|
|
276
|
+
*
|
|
277
|
+
* @param regionA First region.
|
|
278
|
+
* @param regionB Second region.
|
|
279
|
+
* @param defaultLength Optional: override the crossfade length instead of
|
|
280
|
+
* using the actual overlap length.
|
|
281
|
+
*/
|
|
282
|
+
autoCreateCrossfade(regionA, regionB, defaultLength) {
|
|
283
|
+
const overlap = Crossfade.calculateOverlap(regionA, regionB);
|
|
284
|
+
if (!overlap)
|
|
285
|
+
return null;
|
|
286
|
+
// Check if a crossfade already exists between these two regions
|
|
287
|
+
for (const xfade of this._crossfades.values()) {
|
|
288
|
+
const ids = [xfade.inRegionId, xfade.outRegionId];
|
|
289
|
+
if (ids.includes(regionA.id) && ids.includes(regionB.id)) {
|
|
290
|
+
// Update the existing crossfade instead of creating a duplicate
|
|
291
|
+
xfade.setPosition(overlap.position);
|
|
292
|
+
xfade.setLength(defaultLength !== null && defaultLength !== void 0 ? defaultLength : overlap.length);
|
|
293
|
+
return xfade;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
const length = defaultLength !== null && defaultLength !== void 0 ? defaultLength : overlap.length;
|
|
297
|
+
const id = crypto.randomUUID();
|
|
298
|
+
const crossfade = new Crossfade(id, overlap.inRegionId, overlap.outRegionId, overlap.position, length, CrossfadeType.FULL, FadeCurve.EQUAL_POWER, FadeCurve.EQUAL_POWER);
|
|
299
|
+
this.addCrossfade(crossfade);
|
|
300
|
+
return crossfade;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Recalculate all crossfades that involve a given region. Call this after
|
|
304
|
+
* a region is moved, resized, or trimmed so that the crossfade positions
|
|
305
|
+
* and lengths stay in sync with the actual overlap.
|
|
306
|
+
*
|
|
307
|
+
* Crossfades whose regions no longer overlap are automatically removed.
|
|
308
|
+
*/
|
|
309
|
+
updateCrossfadesForRegion(regionId) {
|
|
310
|
+
const region = this.getRegion(regionId);
|
|
311
|
+
if (!region)
|
|
312
|
+
return;
|
|
313
|
+
const relatedCrossfades = this.getCrossfadesForRegion(regionId);
|
|
314
|
+
for (const xfade of relatedCrossfades) {
|
|
315
|
+
const otherRegionId = xfade.inRegionId === regionId ? xfade.outRegionId : xfade.inRegionId;
|
|
316
|
+
const otherRegion = this.getRegion(otherRegionId);
|
|
317
|
+
if (!otherRegion) {
|
|
318
|
+
// Other region no longer exists; remove the crossfade
|
|
319
|
+
this.removeCrossfade(xfade.id);
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
const overlap = Crossfade.calculateOverlap(region, otherRegion);
|
|
323
|
+
if (!overlap) {
|
|
324
|
+
// No longer overlapping; remove the crossfade
|
|
325
|
+
this.removeCrossfade(xfade.id);
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
// Update position and length to match the new overlap
|
|
329
|
+
xfade.setPosition(overlap.position);
|
|
330
|
+
xfade.setLength(overlap.length);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// ─── Batch Editing (ThawList Integration) ───────────────────────────────
|
|
335
|
+
/** Freeze signal emissions; all signals are queued until thaw(). */
|
|
336
|
+
freeze() {
|
|
337
|
+
this._thawList.freeze();
|
|
338
|
+
}
|
|
339
|
+
/** Thaw and emit all queued signals. */
|
|
340
|
+
thaw() {
|
|
341
|
+
this._thawList.thaw();
|
|
342
|
+
}
|
|
343
|
+
// ─── Partition ──────────────────────────────────────────────────────────
|
|
344
|
+
/**
|
|
345
|
+
* Split all regions at a given frame position.
|
|
346
|
+
* Regions that span the frame are split into two: one ending at the frame
|
|
347
|
+
* and one starting at the frame. Regions that don't cover the frame are
|
|
348
|
+
* left untouched.
|
|
349
|
+
*/
|
|
350
|
+
partition(frame) {
|
|
351
|
+
const toSplit = this.regions.filter(r => r.covers(frame) && r.start !== frame);
|
|
352
|
+
for (const region of toSplit) {
|
|
353
|
+
const originalEnd = region.end;
|
|
354
|
+
const originalSourceStart = region.sourceStart;
|
|
355
|
+
const offsetIntoRegion = frame - region.start;
|
|
356
|
+
// Shrink the original region to end at the split point
|
|
357
|
+
region.resize(offsetIntoRegion);
|
|
358
|
+
this._thawList.queueEmission(this.regionChanged, region);
|
|
359
|
+
// Create the right-side region
|
|
360
|
+
const rightId = crypto.randomUUID();
|
|
361
|
+
const rightLength = originalEnd - frame;
|
|
362
|
+
const rightSourceStart = originalSourceStart + offsetIntoRegion;
|
|
363
|
+
const rightRegion = new Region(rightId, region.sourceId, frame, rightLength, rightSourceStart, region.name + '-R', region.layer);
|
|
364
|
+
rightRegion.gain = region.gain;
|
|
365
|
+
rightRegion.muted = region.muted;
|
|
366
|
+
rightRegion.fadeOut = region.fadeOut;
|
|
367
|
+
rightRegion.fadeOutShape = region.fadeOutShape;
|
|
368
|
+
// Clear the original's fade-out (it's now at the split boundary)
|
|
369
|
+
region.fadeOut = 0;
|
|
370
|
+
this.addRegion(rightRegion);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// ─── Duplicate ──────────────────────────────────────────────────────────
|
|
374
|
+
/**
|
|
375
|
+
* Duplicate a single region with a time offset.
|
|
376
|
+
* Returns the new region, or null if the source region was not found.
|
|
377
|
+
*/
|
|
378
|
+
duplicateRegion(regionId, offset) {
|
|
379
|
+
const source = this.getRegion(regionId);
|
|
380
|
+
if (!source)
|
|
381
|
+
return null;
|
|
382
|
+
const newId = crypto.randomUUID();
|
|
383
|
+
const newRegion = new Region(newId, source.sourceId, source.start + offset, source.length, source.sourceStart, source.name + ' (copy)', source.layer);
|
|
384
|
+
newRegion.gain = source.gain;
|
|
385
|
+
newRegion.muted = source.muted;
|
|
386
|
+
newRegion.fadeIn = source.fadeIn;
|
|
387
|
+
newRegion.fadeOut = source.fadeOut;
|
|
388
|
+
newRegion.fadeInShape = source.fadeInShape;
|
|
389
|
+
newRegion.fadeOutShape = source.fadeOutShape;
|
|
390
|
+
newRegion.playbackRate = source.playbackRate;
|
|
391
|
+
newRegion.stretch = source.stretch;
|
|
392
|
+
newRegion.pitchSemitones = source.pitchSemitones;
|
|
393
|
+
this.addRegion(newRegion);
|
|
394
|
+
return newRegion;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Duplicate multiple regions with a time offset.
|
|
398
|
+
* Returns an array of the newly created regions.
|
|
399
|
+
*/
|
|
400
|
+
duplicateRegions(regionIds, offset) {
|
|
401
|
+
const results = [];
|
|
402
|
+
for (const id of regionIds) {
|
|
403
|
+
const dup = this.duplicateRegion(id, offset);
|
|
404
|
+
if (dup)
|
|
405
|
+
results.push(dup);
|
|
406
|
+
}
|
|
407
|
+
return results;
|
|
408
|
+
}
|
|
409
|
+
// ─── Nudge ──────────────────────────────────────────────────────────────
|
|
410
|
+
/** Nudge all regions by the given number of frames (positive or negative). */
|
|
411
|
+
nudge(frames) {
|
|
412
|
+
for (const region of this.regions) {
|
|
413
|
+
const newStart = Math.max(0, region.start + frames);
|
|
414
|
+
region.move(newStart);
|
|
415
|
+
this._thawList.queueEmission(this.regionChanged, region);
|
|
416
|
+
}
|
|
417
|
+
this.sortRegions();
|
|
418
|
+
}
|
|
419
|
+
/** Nudge a single region by the given number of frames. */
|
|
420
|
+
nudgeRegion(regionId, frames) {
|
|
421
|
+
const region = this.getRegion(regionId);
|
|
422
|
+
if (!region)
|
|
423
|
+
return;
|
|
424
|
+
const newStart = Math.max(0, region.start + frames);
|
|
425
|
+
region.move(newStart);
|
|
426
|
+
this._thawList.queueEmission(this.regionChanged, region);
|
|
427
|
+
this.sortRegions();
|
|
428
|
+
}
|
|
204
429
|
}
|
|
205
430
|
//# sourceMappingURL=Playlist.js.map
|