@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,394 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BWF (Broadcast Wave Format) metadata handler.
|
|
3
|
+
*
|
|
4
|
+
* Ardour reference: libs/ardour/broadcast_info.cc
|
|
5
|
+
*
|
|
6
|
+
* BWF extends standard WAV with a 'bext' chunk containing:
|
|
7
|
+
* - Description (256 chars)
|
|
8
|
+
* - Originator (32 chars)
|
|
9
|
+
* - OriginatorReference (32 chars)
|
|
10
|
+
* - OriginationDate (10 chars, YYYY-MM-DD)
|
|
11
|
+
* - OriginationTime (8 chars, HH:MM:SS)
|
|
12
|
+
* - TimeReference (64-bit sample count)
|
|
13
|
+
* - Version (2 bytes)
|
|
14
|
+
* - UMID (64 bytes)
|
|
15
|
+
* - LoudnessValue, LoudnessRange, MaxTruePeakLevel, etc.
|
|
16
|
+
* - CodingHistory (variable length)
|
|
17
|
+
*
|
|
18
|
+
* Specification: EBU Tech 3285 (v2)
|
|
19
|
+
*/
|
|
20
|
+
// ---------------------------------------------------------------
|
|
21
|
+
// Fixed field sizes within the bext chunk (EBU Tech 3285 v2)
|
|
22
|
+
// ---------------------------------------------------------------
|
|
23
|
+
/** Total byte size of the fixed-length portion of the bext chunk. */
|
|
24
|
+
const BEXT_FIXED_SIZE = 602;
|
|
25
|
+
// Field offsets (relative to the start of the bext chunk data, *after* the
|
|
26
|
+
// 8-byte chunk header).
|
|
27
|
+
const OFF_DESCRIPTION = 0;
|
|
28
|
+
const LEN_DESCRIPTION = 256;
|
|
29
|
+
const OFF_ORIGINATOR = 256;
|
|
30
|
+
const LEN_ORIGINATOR = 32;
|
|
31
|
+
const OFF_ORIGINATOR_REF = 288;
|
|
32
|
+
const LEN_ORIGINATOR_REF = 32;
|
|
33
|
+
const OFF_ORIGINATION_DATE = 320;
|
|
34
|
+
const LEN_ORIGINATION_DATE = 10;
|
|
35
|
+
const OFF_ORIGINATION_TIME = 330;
|
|
36
|
+
const LEN_ORIGINATION_TIME = 8;
|
|
37
|
+
const OFF_TIME_REF_LOW = 338;
|
|
38
|
+
const OFF_TIME_REF_HIGH = 342;
|
|
39
|
+
const OFF_VERSION = 346;
|
|
40
|
+
const OFF_UMID = 348;
|
|
41
|
+
const LEN_UMID = 64;
|
|
42
|
+
const OFF_LOUDNESS_VALUE = 412;
|
|
43
|
+
const OFF_LOUDNESS_RANGE = 414;
|
|
44
|
+
const OFF_MAX_TRUE_PEAK = 416;
|
|
45
|
+
const OFF_MAX_MOMENTARY = 418;
|
|
46
|
+
const OFF_MAX_SHORT_TERM = 420;
|
|
47
|
+
// 180 bytes reserved (offsets 422 .. 601)
|
|
48
|
+
const OFF_RESERVED = 422;
|
|
49
|
+
const LEN_RESERVED = 180;
|
|
50
|
+
// CodingHistory begins at offset 602 and extends to the end of the chunk.
|
|
51
|
+
const OFF_CODING_HISTORY = 602;
|
|
52
|
+
export class BWFMetadata {
|
|
53
|
+
// ---------------------------------------------------------------
|
|
54
|
+
// Parse
|
|
55
|
+
// ---------------------------------------------------------------
|
|
56
|
+
/**
|
|
57
|
+
* Parse BWF metadata from a WAV file ArrayBuffer.
|
|
58
|
+
*
|
|
59
|
+
* Scans the RIFF/WAVE structure for a 'bext' chunk and decodes the
|
|
60
|
+
* fields according to EBU Tech 3285 v2. Returns `null` when no bext
|
|
61
|
+
* chunk is found.
|
|
62
|
+
*/
|
|
63
|
+
static parse(wavData) {
|
|
64
|
+
const view = new DataView(wavData);
|
|
65
|
+
const bext = BWFMetadata.findChunk(view, 'bext');
|
|
66
|
+
if (!bext) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const base = bext.offset; // first byte of chunk *data*
|
|
70
|
+
const description = BWFMetadata.readFixedString(view, base + OFF_DESCRIPTION, LEN_DESCRIPTION);
|
|
71
|
+
const originator = BWFMetadata.readFixedString(view, base + OFF_ORIGINATOR, LEN_ORIGINATOR);
|
|
72
|
+
const originatorReference = BWFMetadata.readFixedString(view, base + OFF_ORIGINATOR_REF, LEN_ORIGINATOR_REF);
|
|
73
|
+
const originationDate = BWFMetadata.readFixedString(view, base + OFF_ORIGINATION_DATE, LEN_ORIGINATION_DATE);
|
|
74
|
+
const originationTime = BWFMetadata.readFixedString(view, base + OFF_ORIGINATION_TIME, LEN_ORIGINATION_TIME);
|
|
75
|
+
const timeRefLow = view.getUint32(base + OFF_TIME_REF_LOW, true);
|
|
76
|
+
const timeRefHigh = view.getUint32(base + OFF_TIME_REF_HIGH, true);
|
|
77
|
+
const timeReference = (BigInt(timeRefHigh) << BigInt(32)) | BigInt(timeRefLow);
|
|
78
|
+
const version = view.getUint16(base + OFF_VERSION, true);
|
|
79
|
+
const umid = new Uint8Array(wavData, base + OFF_UMID, LEN_UMID);
|
|
80
|
+
const loudnessValue = view.getInt16(base + OFF_LOUDNESS_VALUE, true);
|
|
81
|
+
const loudnessRange = view.getInt16(base + OFF_LOUDNESS_RANGE, true);
|
|
82
|
+
const maxTruePeakLevel = view.getInt16(base + OFF_MAX_TRUE_PEAK, true);
|
|
83
|
+
const maxMomentaryLoudness = view.getInt16(base + OFF_MAX_MOMENTARY, true);
|
|
84
|
+
const maxShortTermLoudness = view.getInt16(base + OFF_MAX_SHORT_TERM, true);
|
|
85
|
+
let codingHistory = '';
|
|
86
|
+
if (bext.size > BEXT_FIXED_SIZE) {
|
|
87
|
+
const codingLen = bext.size - BEXT_FIXED_SIZE;
|
|
88
|
+
codingHistory = BWFMetadata.readFixedString(view, base + OFF_CODING_HISTORY, codingLen);
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
description,
|
|
92
|
+
originator,
|
|
93
|
+
originatorReference,
|
|
94
|
+
originationDate,
|
|
95
|
+
originationTime,
|
|
96
|
+
timeReference,
|
|
97
|
+
version,
|
|
98
|
+
umid: new Uint8Array(umid), // defensive copy
|
|
99
|
+
loudnessValue,
|
|
100
|
+
loudnessRange,
|
|
101
|
+
maxTruePeakLevel,
|
|
102
|
+
maxMomentaryLoudness,
|
|
103
|
+
maxShortTermLoudness,
|
|
104
|
+
codingHistory,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// ---------------------------------------------------------------
|
|
108
|
+
// Create bext chunk
|
|
109
|
+
// ---------------------------------------------------------------
|
|
110
|
+
/**
|
|
111
|
+
* Serialise {@link BWFData} into a standalone bext chunk (including
|
|
112
|
+
* the 8-byte chunk header: 'bext' + uint32 size).
|
|
113
|
+
*/
|
|
114
|
+
static createBextChunk(data) {
|
|
115
|
+
const codingBytes = BWFMetadata.encodeString(data.codingHistory);
|
|
116
|
+
const dataSize = BEXT_FIXED_SIZE + codingBytes.byteLength;
|
|
117
|
+
// Total chunk = 8-byte header + dataSize (padded to even length per RIFF spec)
|
|
118
|
+
const paddedDataSize = dataSize + (dataSize % 2);
|
|
119
|
+
const chunkBuffer = new ArrayBuffer(8 + paddedDataSize);
|
|
120
|
+
const view = new DataView(chunkBuffer);
|
|
121
|
+
// Chunk header
|
|
122
|
+
BWFMetadata.writeChunkId(view, 0, 'bext');
|
|
123
|
+
view.setUint32(4, dataSize, true);
|
|
124
|
+
const base = 8; // start of chunk data
|
|
125
|
+
BWFMetadata.writeFixedString(view, base + OFF_DESCRIPTION, data.description, LEN_DESCRIPTION);
|
|
126
|
+
BWFMetadata.writeFixedString(view, base + OFF_ORIGINATOR, data.originator, LEN_ORIGINATOR);
|
|
127
|
+
BWFMetadata.writeFixedString(view, base + OFF_ORIGINATOR_REF, data.originatorReference, LEN_ORIGINATOR_REF);
|
|
128
|
+
BWFMetadata.writeFixedString(view, base + OFF_ORIGINATION_DATE, data.originationDate, LEN_ORIGINATION_DATE);
|
|
129
|
+
BWFMetadata.writeFixedString(view, base + OFF_ORIGINATION_TIME, data.originationTime, LEN_ORIGINATION_TIME);
|
|
130
|
+
// TimeReference as two uint32 values (little-endian)
|
|
131
|
+
const mask32 = BigInt('0xFFFFFFFF');
|
|
132
|
+
const low = Number(data.timeReference & mask32);
|
|
133
|
+
const high = Number((data.timeReference >> BigInt(32)) & mask32);
|
|
134
|
+
view.setUint32(base + OFF_TIME_REF_LOW, low, true);
|
|
135
|
+
view.setUint32(base + OFF_TIME_REF_HIGH, high, true);
|
|
136
|
+
view.setUint16(base + OFF_VERSION, data.version, true);
|
|
137
|
+
// UMID
|
|
138
|
+
const umidDst = new Uint8Array(chunkBuffer, base + OFF_UMID, LEN_UMID);
|
|
139
|
+
const umidLen = Math.min(data.umid.byteLength, LEN_UMID);
|
|
140
|
+
umidDst.set(data.umid.subarray(0, umidLen));
|
|
141
|
+
// Loudness fields
|
|
142
|
+
view.setInt16(base + OFF_LOUDNESS_VALUE, data.loudnessValue, true);
|
|
143
|
+
view.setInt16(base + OFF_LOUDNESS_RANGE, data.loudnessRange, true);
|
|
144
|
+
view.setInt16(base + OFF_MAX_TRUE_PEAK, data.maxTruePeakLevel, true);
|
|
145
|
+
view.setInt16(base + OFF_MAX_MOMENTARY, data.maxMomentaryLoudness, true);
|
|
146
|
+
view.setInt16(base + OFF_MAX_SHORT_TERM, data.maxShortTermLoudness, true);
|
|
147
|
+
// Reserved (zero-filled by ArrayBuffer default)
|
|
148
|
+
// CodingHistory
|
|
149
|
+
const codingDst = new Uint8Array(chunkBuffer, base + OFF_CODING_HISTORY, codingBytes.byteLength);
|
|
150
|
+
codingDst.set(codingBytes);
|
|
151
|
+
return chunkBuffer;
|
|
152
|
+
}
|
|
153
|
+
// ---------------------------------------------------------------
|
|
154
|
+
// Inject bext into existing WAV
|
|
155
|
+
// ---------------------------------------------------------------
|
|
156
|
+
/**
|
|
157
|
+
* Inject a bext chunk into an existing WAV file.
|
|
158
|
+
*
|
|
159
|
+
* If the WAV already contains a bext chunk it is replaced.
|
|
160
|
+
* The returned ArrayBuffer is a new, valid RIFF/WAVE file.
|
|
161
|
+
*/
|
|
162
|
+
static injectBWF(wavData, bwfData) {
|
|
163
|
+
const srcView = new DataView(wavData);
|
|
164
|
+
// Validate RIFF header
|
|
165
|
+
if (BWFMetadata.readChunkId(srcView, 0) !== 'RIFF') {
|
|
166
|
+
throw new Error('Not a valid RIFF file');
|
|
167
|
+
}
|
|
168
|
+
if (BWFMetadata.readChunkId(srcView, 8) !== 'WAVE') {
|
|
169
|
+
throw new Error('Not a valid WAVE file');
|
|
170
|
+
}
|
|
171
|
+
const bextChunk = BWFMetadata.createBextChunk(bwfData);
|
|
172
|
+
// Check for existing bext chunk
|
|
173
|
+
const existing = BWFMetadata.findChunkRaw(srcView, 'bext');
|
|
174
|
+
if (existing) {
|
|
175
|
+
// Replace existing bext chunk
|
|
176
|
+
const existingChunkTotal = 8 + existing.size + (existing.size % 2);
|
|
177
|
+
const beforeLen = existing.headerOffset;
|
|
178
|
+
const afterStart = existing.headerOffset + existingChunkTotal;
|
|
179
|
+
const afterLen = wavData.byteLength - afterStart;
|
|
180
|
+
const newSize = beforeLen + bextChunk.byteLength + afterLen;
|
|
181
|
+
const result = new ArrayBuffer(newSize);
|
|
182
|
+
const dst = new Uint8Array(result);
|
|
183
|
+
// Copy everything before the old bext chunk
|
|
184
|
+
dst.set(new Uint8Array(wavData, 0, beforeLen), 0);
|
|
185
|
+
// Insert the new bext chunk
|
|
186
|
+
dst.set(new Uint8Array(bextChunk), beforeLen);
|
|
187
|
+
// Copy everything after the old bext chunk
|
|
188
|
+
dst.set(new Uint8Array(wavData, afterStart, afterLen), beforeLen + bextChunk.byteLength);
|
|
189
|
+
// Update RIFF size field
|
|
190
|
+
const resultView = new DataView(result);
|
|
191
|
+
resultView.setUint32(4, newSize - 8, true);
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
// Insert bext chunk right after the WAVE identifier (offset 12)
|
|
196
|
+
const insertOffset = 12;
|
|
197
|
+
const newSize = wavData.byteLength + bextChunk.byteLength;
|
|
198
|
+
const result = new ArrayBuffer(newSize);
|
|
199
|
+
const dst = new Uint8Array(result);
|
|
200
|
+
// Copy RIFF header + WAVE id
|
|
201
|
+
dst.set(new Uint8Array(wavData, 0, insertOffset), 0);
|
|
202
|
+
// Insert bext chunk
|
|
203
|
+
dst.set(new Uint8Array(bextChunk), insertOffset);
|
|
204
|
+
// Copy remaining chunks
|
|
205
|
+
dst.set(new Uint8Array(wavData, insertOffset, wavData.byteLength - insertOffset), insertOffset + bextChunk.byteLength);
|
|
206
|
+
// Update RIFF size field
|
|
207
|
+
const resultView = new DataView(result);
|
|
208
|
+
resultView.setUint32(4, newSize - 8, true);
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// ---------------------------------------------------------------
|
|
213
|
+
// Factory / defaults
|
|
214
|
+
// ---------------------------------------------------------------
|
|
215
|
+
/**
|
|
216
|
+
* Create default BWF data suitable for a new recording.
|
|
217
|
+
*
|
|
218
|
+
* Populates the origination date/time from the current wall clock and
|
|
219
|
+
* sets all other fields to sensible defaults.
|
|
220
|
+
*/
|
|
221
|
+
static createDefault(options) {
|
|
222
|
+
var _a, _b, _c, _d;
|
|
223
|
+
const now = new Date();
|
|
224
|
+
const pad2 = (n) => n.toString().padStart(2, '0');
|
|
225
|
+
const dateStr = `${now.getFullYear()}-${pad2(now.getMonth() + 1)}-${pad2(now.getDate())}`;
|
|
226
|
+
const timeStr = `${pad2(now.getHours())}:${pad2(now.getMinutes())}:${pad2(now.getSeconds())}`;
|
|
227
|
+
const sr = (_a = options === null || options === void 0 ? void 0 : options.sampleRate) !== null && _a !== void 0 ? _a : 48000;
|
|
228
|
+
const codingHistory = `A=PCM,F=${sr},W=24,M=stereo,T=drop.ai\r\n`;
|
|
229
|
+
return {
|
|
230
|
+
description: (_b = options === null || options === void 0 ? void 0 : options.description) !== null && _b !== void 0 ? _b : '',
|
|
231
|
+
originator: (_c = options === null || options === void 0 ? void 0 : options.originator) !== null && _c !== void 0 ? _c : 'drop.ai',
|
|
232
|
+
originatorReference: BWFMetadata.generateOriginatorReference(),
|
|
233
|
+
originationDate: dateStr,
|
|
234
|
+
originationTime: timeStr,
|
|
235
|
+
timeReference: (_d = options === null || options === void 0 ? void 0 : options.timeReference) !== null && _d !== void 0 ? _d : BigInt(0),
|
|
236
|
+
version: 2,
|
|
237
|
+
umid: new Uint8Array(64),
|
|
238
|
+
loudnessValue: 0,
|
|
239
|
+
loudnessRange: 0,
|
|
240
|
+
maxTruePeakLevel: 0,
|
|
241
|
+
maxMomentaryLoudness: 0,
|
|
242
|
+
maxShortTermLoudness: 0,
|
|
243
|
+
codingHistory,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
// ---------------------------------------------------------------
|
|
247
|
+
// Validation
|
|
248
|
+
// ---------------------------------------------------------------
|
|
249
|
+
/**
|
|
250
|
+
* Validate BWF data according to EBU Tech 3285 constraints.
|
|
251
|
+
*
|
|
252
|
+
* @returns An array of human-readable error strings (empty = valid).
|
|
253
|
+
*/
|
|
254
|
+
static validate(data) {
|
|
255
|
+
const errors = [];
|
|
256
|
+
if (data.description.length > LEN_DESCRIPTION) {
|
|
257
|
+
errors.push(`Description exceeds ${LEN_DESCRIPTION} characters (got ${data.description.length})`);
|
|
258
|
+
}
|
|
259
|
+
if (data.originator.length > LEN_ORIGINATOR) {
|
|
260
|
+
errors.push(`Originator exceeds ${LEN_ORIGINATOR} characters (got ${data.originator.length})`);
|
|
261
|
+
}
|
|
262
|
+
if (data.originatorReference.length > LEN_ORIGINATOR_REF) {
|
|
263
|
+
errors.push(`OriginatorReference exceeds ${LEN_ORIGINATOR_REF} characters (got ${data.originatorReference.length})`);
|
|
264
|
+
}
|
|
265
|
+
// Date format: YYYY-MM-DD (or YYYY:MM:DD per older BWF specs)
|
|
266
|
+
if (data.originationDate.length > 0 && !/^\d{4}[-:]\d{2}[-:]\d{2}$/.test(data.originationDate)) {
|
|
267
|
+
errors.push(`OriginationDate must be in YYYY-MM-DD format (got "${data.originationDate}")`);
|
|
268
|
+
}
|
|
269
|
+
// Time format: HH:MM:SS (or HH.MM.SS)
|
|
270
|
+
if (data.originationTime.length > 0 && !/^\d{2}[:.]\d{2}[:.]\d{2}$/.test(data.originationTime)) {
|
|
271
|
+
errors.push(`OriginationTime must be in HH:MM:SS format (got "${data.originationTime}")`);
|
|
272
|
+
}
|
|
273
|
+
if (data.timeReference < BigInt(0)) {
|
|
274
|
+
errors.push('TimeReference must be non-negative');
|
|
275
|
+
}
|
|
276
|
+
if (data.version < 0 || data.version > 2) {
|
|
277
|
+
errors.push(`Version must be 0, 1, or 2 (got ${data.version})`);
|
|
278
|
+
}
|
|
279
|
+
if (data.umid.byteLength !== 64) {
|
|
280
|
+
errors.push(`UMID must be exactly 64 bytes (got ${data.umid.byteLength})`);
|
|
281
|
+
}
|
|
282
|
+
// Loudness fields are only meaningful for version >= 2
|
|
283
|
+
if (data.version < 2) {
|
|
284
|
+
if (data.loudnessValue !== 0 || data.loudnessRange !== 0 ||
|
|
285
|
+
data.maxTruePeakLevel !== 0 || data.maxMomentaryLoudness !== 0 ||
|
|
286
|
+
data.maxShortTermLoudness !== 0) {
|
|
287
|
+
errors.push('Loudness fields are only valid for BWF version 2');
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return errors;
|
|
291
|
+
}
|
|
292
|
+
// ---------------------------------------------------------------
|
|
293
|
+
// Private helpers — string I/O
|
|
294
|
+
// ---------------------------------------------------------------
|
|
295
|
+
/**
|
|
296
|
+
* Read a fixed-length ASCII string from a DataView, trimming NUL
|
|
297
|
+
* padding from the right.
|
|
298
|
+
*/
|
|
299
|
+
static readFixedString(view, offset, length) {
|
|
300
|
+
const bytes = [];
|
|
301
|
+
for (let i = 0; i < length; i++) {
|
|
302
|
+
const b = view.getUint8(offset + i);
|
|
303
|
+
if (b === 0)
|
|
304
|
+
break; // stop at first NUL
|
|
305
|
+
bytes.push(b);
|
|
306
|
+
}
|
|
307
|
+
return String.fromCharCode(...bytes);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Write a string into a fixed-length field, padding with NUL bytes.
|
|
311
|
+
*/
|
|
312
|
+
static writeFixedString(view, offset, str, length) {
|
|
313
|
+
const toWrite = Math.min(str.length, length);
|
|
314
|
+
for (let i = 0; i < toWrite; i++) {
|
|
315
|
+
view.setUint8(offset + i, str.charCodeAt(i) & 0xFF);
|
|
316
|
+
}
|
|
317
|
+
// Remaining bytes are already zero (ArrayBuffer is zero-initialised)
|
|
318
|
+
}
|
|
319
|
+
// ---------------------------------------------------------------
|
|
320
|
+
// Private helpers — chunk navigation
|
|
321
|
+
// ---------------------------------------------------------------
|
|
322
|
+
/**
|
|
323
|
+
* Locate a RIFF chunk by its four-character ID.
|
|
324
|
+
*
|
|
325
|
+
* Returns the offset of the chunk *data* (after the 8-byte header)
|
|
326
|
+
* and the data size. Returns `null` if the chunk is not found.
|
|
327
|
+
*/
|
|
328
|
+
static findChunk(view, chunkId) {
|
|
329
|
+
const raw = BWFMetadata.findChunkRaw(view, chunkId);
|
|
330
|
+
if (!raw)
|
|
331
|
+
return null;
|
|
332
|
+
return { offset: raw.headerOffset + 8, size: raw.size };
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Internal chunk finder that also returns the header offset (for
|
|
336
|
+
* replacement scenarios in {@link injectBWF}).
|
|
337
|
+
*/
|
|
338
|
+
static findChunkRaw(view, chunkId) {
|
|
339
|
+
// Validate RIFF header
|
|
340
|
+
if (view.byteLength < 12)
|
|
341
|
+
return null;
|
|
342
|
+
if (BWFMetadata.readChunkId(view, 0) !== 'RIFF')
|
|
343
|
+
return null;
|
|
344
|
+
if (BWFMetadata.readChunkId(view, 8) !== 'WAVE')
|
|
345
|
+
return null;
|
|
346
|
+
let pos = 12; // first sub-chunk
|
|
347
|
+
while (pos + 8 <= view.byteLength) {
|
|
348
|
+
const id = BWFMetadata.readChunkId(view, pos);
|
|
349
|
+
const size = view.getUint32(pos + 4, true);
|
|
350
|
+
if (id === chunkId) {
|
|
351
|
+
return { headerOffset: pos, size };
|
|
352
|
+
}
|
|
353
|
+
// Advance to next chunk (size rounded up to even per RIFF spec)
|
|
354
|
+
pos += 8 + size + (size % 2);
|
|
355
|
+
}
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Read a four-character chunk ID from a DataView.
|
|
360
|
+
*/
|
|
361
|
+
static readChunkId(view, offset) {
|
|
362
|
+
return String.fromCharCode(view.getUint8(offset), view.getUint8(offset + 1), view.getUint8(offset + 2), view.getUint8(offset + 3));
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Write a four-character chunk ID into a DataView.
|
|
366
|
+
*/
|
|
367
|
+
static writeChunkId(view, offset, id) {
|
|
368
|
+
for (let i = 0; i < 4; i++) {
|
|
369
|
+
view.setUint8(offset + i, id.charCodeAt(i));
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Encode a string to a Uint8Array using ASCII (Latin-1 subset).
|
|
374
|
+
*/
|
|
375
|
+
static encodeString(str) {
|
|
376
|
+
const arr = new Uint8Array(str.length);
|
|
377
|
+
for (let i = 0; i < str.length; i++) {
|
|
378
|
+
arr[i] = str.charCodeAt(i) & 0xFF;
|
|
379
|
+
}
|
|
380
|
+
return arr;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Generate a unique originator reference string.
|
|
384
|
+
*
|
|
385
|
+
* EBU R99-1999 recommends a format based on country code, org code,
|
|
386
|
+
* and a serial number. We use a simplified random approach.
|
|
387
|
+
*/
|
|
388
|
+
static generateOriginatorReference() {
|
|
389
|
+
const now = Date.now().toString(36);
|
|
390
|
+
const rand = Math.random().toString(36).substring(2, 10);
|
|
391
|
+
return `DROPAI${now}${rand}`.substring(0, 32);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
//# sourceMappingURL=BWFMetadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BWFMetadata.js","sourceRoot":"","sources":["../../src/audio/BWFMetadata.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel Splitter
|
|
3
|
+
* Ardour reference: libs/ardour/import.cc (multi-channel handling)
|
|
4
|
+
*
|
|
5
|
+
* Splits N-channel audio into individual mono or stereo pairs.
|
|
6
|
+
*/
|
|
7
|
+
export interface SplitResult {
|
|
8
|
+
/** Channel index (0-based) or "L"/"R" for stereo pairs */
|
|
9
|
+
label: string;
|
|
10
|
+
/** Mono audio data */
|
|
11
|
+
data: Float32Array;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Split a multi-channel AudioBuffer into individual mono channels.
|
|
15
|
+
*
|
|
16
|
+
* @param buffer Multi-channel audio buffer
|
|
17
|
+
* @returns Array of mono channel data with labels
|
|
18
|
+
*/
|
|
19
|
+
export declare function splitToMono(buffer: AudioBuffer): SplitResult[];
|
|
20
|
+
/**
|
|
21
|
+
* Split a multi-channel buffer into stereo pairs.
|
|
22
|
+
* Odd last channel becomes mono.
|
|
23
|
+
*
|
|
24
|
+
* @param buffer Multi-channel audio buffer
|
|
25
|
+
* @returns Array of stereo pairs (or mono for odd last channel)
|
|
26
|
+
*/
|
|
27
|
+
export declare function splitToStereoPairs(buffer: AudioBuffer): {
|
|
28
|
+
label: string;
|
|
29
|
+
left: Float32Array;
|
|
30
|
+
right?: Float32Array;
|
|
31
|
+
}[];
|
|
32
|
+
/**
|
|
33
|
+
* Create a mono buffer by mixing down all channels.
|
|
34
|
+
* Uses equal-power downmix.
|
|
35
|
+
*/
|
|
36
|
+
export declare function mixToMono(buffer: AudioBuffer): Float32Array;
|
|
37
|
+
//# sourceMappingURL=ChannelSplitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChannelSplitter.d.ts","sourceRoot":"","sources":["../../src/audio/ChannelSplitter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,WAAW;IACxB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,IAAI,EAAE,YAAY,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,EAAE,CAsB9D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,CAAC,EAAE,YAAY,CAAA;CAAE,EAAE,CAyBrH;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,YAAY,CAe3D"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel Splitter
|
|
3
|
+
* Ardour reference: libs/ardour/import.cc (multi-channel handling)
|
|
4
|
+
*
|
|
5
|
+
* Splits N-channel audio into individual mono or stereo pairs.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Split a multi-channel AudioBuffer into individual mono channels.
|
|
9
|
+
*
|
|
10
|
+
* @param buffer Multi-channel audio buffer
|
|
11
|
+
* @returns Array of mono channel data with labels
|
|
12
|
+
*/
|
|
13
|
+
export function splitToMono(buffer) {
|
|
14
|
+
const results = [];
|
|
15
|
+
const numChannels = buffer.numberOfChannels;
|
|
16
|
+
for (let ch = 0; ch < numChannels; ch++) {
|
|
17
|
+
const data = new Float32Array(buffer.length);
|
|
18
|
+
const source = buffer.getChannelData(ch);
|
|
19
|
+
data.set(source);
|
|
20
|
+
let label;
|
|
21
|
+
if (numChannels === 1) {
|
|
22
|
+
label = 'Mono';
|
|
23
|
+
}
|
|
24
|
+
else if (numChannels === 2) {
|
|
25
|
+
label = ch === 0 ? 'L' : 'R';
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
label = `Ch${ch + 1}`;
|
|
29
|
+
}
|
|
30
|
+
results.push({ label, data });
|
|
31
|
+
}
|
|
32
|
+
return results;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Split a multi-channel buffer into stereo pairs.
|
|
36
|
+
* Odd last channel becomes mono.
|
|
37
|
+
*
|
|
38
|
+
* @param buffer Multi-channel audio buffer
|
|
39
|
+
* @returns Array of stereo pairs (or mono for odd last channel)
|
|
40
|
+
*/
|
|
41
|
+
export function splitToStereoPairs(buffer) {
|
|
42
|
+
const results = [];
|
|
43
|
+
const numChannels = buffer.numberOfChannels;
|
|
44
|
+
for (let ch = 0; ch < numChannels; ch += 2) {
|
|
45
|
+
const left = new Float32Array(buffer.length);
|
|
46
|
+
left.set(buffer.getChannelData(ch));
|
|
47
|
+
if (ch + 1 < numChannels) {
|
|
48
|
+
const right = new Float32Array(buffer.length);
|
|
49
|
+
right.set(buffer.getChannelData(ch + 1));
|
|
50
|
+
results.push({
|
|
51
|
+
label: `Pair ${Math.floor(ch / 2) + 1}`,
|
|
52
|
+
left,
|
|
53
|
+
right,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
results.push({
|
|
58
|
+
label: `Ch${ch + 1} (Mono)`,
|
|
59
|
+
left,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return results;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Create a mono buffer by mixing down all channels.
|
|
67
|
+
* Uses equal-power downmix.
|
|
68
|
+
*/
|
|
69
|
+
export function mixToMono(buffer) {
|
|
70
|
+
const numChannels = buffer.numberOfChannels;
|
|
71
|
+
const length = buffer.length;
|
|
72
|
+
const result = new Float32Array(length);
|
|
73
|
+
const gain = 1 / Math.sqrt(numChannels); // Equal-power
|
|
74
|
+
for (let ch = 0; ch < numChannels; ch++) {
|
|
75
|
+
const data = buffer.getChannelData(ch);
|
|
76
|
+
for (let i = 0; i < length; i++) {
|
|
77
|
+
result[i] += data[i] * gain;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=ChannelSplitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChannelSplitter.js","sourceRoot":"","sources":["../../src/audio/ChannelSplitter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Export Analyzer — post-export analysis report.
|
|
3
|
+
* Ardour reference: libs/ardour/export_analysis.h
|
|
4
|
+
*
|
|
5
|
+
* Computes: Peak, RMS, LUFS, True Peak, Dynamic Range, DC offset.
|
|
6
|
+
*/
|
|
7
|
+
export interface ExportAnalysisReport {
|
|
8
|
+
/** Duration in seconds */
|
|
9
|
+
duration: number;
|
|
10
|
+
/** Sample rate */
|
|
11
|
+
sampleRate: number;
|
|
12
|
+
/** Number of channels */
|
|
13
|
+
channels: number;
|
|
14
|
+
/** Peak level per channel in dBFS */
|
|
15
|
+
peakLevels: number[];
|
|
16
|
+
/** RMS level per channel in dBFS */
|
|
17
|
+
rmsLevels: number[];
|
|
18
|
+
/** True peak per channel in dBTP */
|
|
19
|
+
truePeakLevels: number[];
|
|
20
|
+
/** Integrated LUFS */
|
|
21
|
+
integratedLufs: number;
|
|
22
|
+
/** Short-term LUFS max */
|
|
23
|
+
shortTermMax: number;
|
|
24
|
+
/** Loudness Range (LRA) in LU */
|
|
25
|
+
loudnessRange: number;
|
|
26
|
+
/** Dynamic range (peak - RMS) in dB */
|
|
27
|
+
dynamicRange: number;
|
|
28
|
+
/** DC offset per channel */
|
|
29
|
+
dcOffset: number[];
|
|
30
|
+
/** Whether clipping was detected */
|
|
31
|
+
clipping: boolean;
|
|
32
|
+
/** Number of clipped samples */
|
|
33
|
+
clippedSamples: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Analyze an AudioBuffer and produce a comprehensive report.
|
|
37
|
+
*/
|
|
38
|
+
export declare function analyzeExport(buffer: AudioBuffer): ExportAnalysisReport;
|
|
39
|
+
//# sourceMappingURL=ExportAnalyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportAnalyzer.d.ts","sourceRoot":"","sources":["../../src/audio/ExportAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,oBAAoB;IACjC,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,oCAAoC;IACpC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oCAAoC;IACpC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,sBAAsB;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,0BAA0B;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,oCAAoC;IACpC,QAAQ,EAAE,OAAO,CAAC;IAClB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,oBAAoB,CA0EvE"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Export Analyzer — post-export analysis report.
|
|
3
|
+
* Ardour reference: libs/ardour/export_analysis.h
|
|
4
|
+
*
|
|
5
|
+
* Computes: Peak, RMS, LUFS, True Peak, Dynamic Range, DC offset.
|
|
6
|
+
*/
|
|
7
|
+
import { measureLUFS } from './LufsNormalizer';
|
|
8
|
+
import { measureTruePeakDbTP } from '../processing/TruePeakLimiter';
|
|
9
|
+
/**
|
|
10
|
+
* Analyze an AudioBuffer and produce a comprehensive report.
|
|
11
|
+
*/
|
|
12
|
+
export function analyzeExport(buffer) {
|
|
13
|
+
const numChannels = buffer.numberOfChannels;
|
|
14
|
+
const length = buffer.length;
|
|
15
|
+
const sampleRate = buffer.sampleRate;
|
|
16
|
+
const peakLevels = [];
|
|
17
|
+
const rmsLevels = [];
|
|
18
|
+
const truePeakLevels = [];
|
|
19
|
+
const dcOffset = [];
|
|
20
|
+
let totalClipped = 0;
|
|
21
|
+
let hasClipping = false;
|
|
22
|
+
for (let ch = 0; ch < numChannels; ch++) {
|
|
23
|
+
const data = buffer.getChannelData(ch);
|
|
24
|
+
let peak = 0;
|
|
25
|
+
let sumSq = 0;
|
|
26
|
+
let sum = 0;
|
|
27
|
+
let clipped = 0;
|
|
28
|
+
for (let i = 0; i < length; i++) {
|
|
29
|
+
const abs = Math.abs(data[i]);
|
|
30
|
+
if (abs > peak)
|
|
31
|
+
peak = abs;
|
|
32
|
+
sumSq += data[i] * data[i];
|
|
33
|
+
sum += data[i];
|
|
34
|
+
if (abs >= 1.0) {
|
|
35
|
+
clipped++;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const rms = Math.sqrt(sumSq / length);
|
|
39
|
+
const dc = sum / length;
|
|
40
|
+
peakLevels.push(peak > 0 ? 20 * Math.log10(peak) : -Infinity);
|
|
41
|
+
rmsLevels.push(rms > 0 ? 20 * Math.log10(rms) : -Infinity);
|
|
42
|
+
truePeakLevels.push(measureTruePeakDbTP(data));
|
|
43
|
+
dcOffset.push(dc);
|
|
44
|
+
totalClipped += clipped;
|
|
45
|
+
if (clipped > 0)
|
|
46
|
+
hasClipping = true;
|
|
47
|
+
}
|
|
48
|
+
// LUFS measurement
|
|
49
|
+
const lufsResult = measureLUFS(buffer);
|
|
50
|
+
// Short-term max
|
|
51
|
+
const shortTermMax = lufsResult.shortTerm.length > 0
|
|
52
|
+
? Math.max(...lufsResult.shortTerm.filter(l => isFinite(l)))
|
|
53
|
+
: -Infinity;
|
|
54
|
+
// Dynamic range (overall peak - overall RMS)
|
|
55
|
+
const overallPeak = Math.max(...peakLevels);
|
|
56
|
+
const overallRms = Math.max(...rmsLevels);
|
|
57
|
+
const dynamicRange = isFinite(overallPeak) && isFinite(overallRms)
|
|
58
|
+
? overallPeak - overallRms
|
|
59
|
+
: 0;
|
|
60
|
+
return {
|
|
61
|
+
duration: length / sampleRate,
|
|
62
|
+
sampleRate,
|
|
63
|
+
channels: numChannels,
|
|
64
|
+
peakLevels,
|
|
65
|
+
rmsLevels,
|
|
66
|
+
truePeakLevels,
|
|
67
|
+
integratedLufs: lufsResult.integrated,
|
|
68
|
+
shortTermMax,
|
|
69
|
+
loudnessRange: lufsResult.range,
|
|
70
|
+
dynamicRange,
|
|
71
|
+
dcOffset,
|
|
72
|
+
clipping: hasClipping,
|
|
73
|
+
clippedSamples: totalClipped,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=ExportAnalyzer.js.map
|