@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
|
@@ -1,17 +1,78 @@
|
|
|
1
|
-
import { Beats, TimeDomain } from './types';
|
|
1
|
+
import { Beats, TimeDomain, TICKS_PER_BEAT } from './types';
|
|
2
2
|
import { Signal } from '../../lib/Signal';
|
|
3
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
4
|
+
/**
|
|
5
|
+
* Binary search: find the index of the last element whose `frame` is <= the target frame.
|
|
6
|
+
* Returns -1 if no element satisfies the condition.
|
|
7
|
+
*/
|
|
8
|
+
function findSegmentIndex(events, frame) {
|
|
9
|
+
let lo = 0;
|
|
10
|
+
let hi = events.length - 1;
|
|
11
|
+
let result = -1;
|
|
12
|
+
while (lo <= hi) {
|
|
13
|
+
const mid = (lo + hi) >>> 1;
|
|
14
|
+
if (events[mid].frame <= frame) {
|
|
15
|
+
result = mid;
|
|
16
|
+
lo = mid + 1;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
hi = mid - 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Binary search: find the index of an element with exactly the given frame.
|
|
26
|
+
* Returns -1 if not found.
|
|
27
|
+
*/
|
|
28
|
+
function findExactIndex(events, frame) {
|
|
29
|
+
let lo = 0;
|
|
30
|
+
let hi = events.length - 1;
|
|
31
|
+
while (lo <= hi) {
|
|
32
|
+
const mid = (lo + hi) >>> 1;
|
|
33
|
+
if (events[mid].frame === frame) {
|
|
34
|
+
return mid;
|
|
35
|
+
}
|
|
36
|
+
else if (events[mid].frame < frame) {
|
|
37
|
+
lo = mid + 1;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
hi = mid - 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return -1;
|
|
44
|
+
}
|
|
45
|
+
// ─── TempoMap ────────────────────────────────────────────────────────────────
|
|
3
46
|
/**
|
|
4
47
|
* TempoMap handles conversion between AudioTime (samples/frames) and BeatTime (beats/ticks).
|
|
5
|
-
* Supports multiple tempo changes over the timeline (Ardour-style tempo map).
|
|
48
|
+
* Supports multiple tempo and meter changes over the timeline (Ardour-style tempo map).
|
|
49
|
+
*
|
|
50
|
+
* Features:
|
|
51
|
+
* - Dual domain support (AudioTime / BeatTime)
|
|
52
|
+
* - Independent tempo and meter event lists
|
|
53
|
+
* - Bar/Beat/Tick (BBT) conversions with 1920 ticks-per-beat resolution
|
|
54
|
+
* - Grid point generation with subdivision and swing support
|
|
55
|
+
* - Region repositioning on tempo change
|
|
56
|
+
* - Binary search for efficient segment lookup
|
|
6
57
|
*/
|
|
7
58
|
export class TempoMap {
|
|
8
59
|
constructor(sampleRate = 44100) {
|
|
9
60
|
this.sampleRate = sampleRate;
|
|
10
61
|
this.events = [];
|
|
62
|
+
this._meterEvents = [];
|
|
63
|
+
/** Fires after any modification to the tempo map (add/remove tempo or meter changes). */
|
|
11
64
|
this.changed = new Signal();
|
|
65
|
+
/**
|
|
66
|
+
* Fires after a tempo value has been modified, providing the frame at which the change occurred.
|
|
67
|
+
* Useful for repositioning regions or cursors after a tempo edit.
|
|
68
|
+
*/
|
|
69
|
+
this.onTempoChanged = new Signal();
|
|
12
70
|
// Initialize with default 120 BPM at frame 0
|
|
13
71
|
this.events.push({ frame: 0, bpm: 120, timeSigNum: 4, timeSigDen: 4 });
|
|
72
|
+
// Initialize with default 4/4 meter at frame 0
|
|
73
|
+
this._meterEvents.push({ frame: 0, beatsPerBar: 4, beatValue: 4 });
|
|
14
74
|
}
|
|
75
|
+
// ─── Tempo Events ────────────────────────────────────────────────────────
|
|
15
76
|
/**
|
|
16
77
|
* Add or update a tempo change at the given frame position.
|
|
17
78
|
* If a tempo change already exists at the exact frame, it is updated.
|
|
@@ -19,19 +80,25 @@ export class TempoMap {
|
|
|
19
80
|
addTempoChange(frame, bpm, timeSigNum, timeSigDen) {
|
|
20
81
|
if (bpm <= 0)
|
|
21
82
|
return;
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
24
|
-
|
|
83
|
+
const idx = findExactIndex(this.events, frame);
|
|
84
|
+
if (idx !== -1) {
|
|
85
|
+
const oldBpm = this.events[idx].bpm;
|
|
86
|
+
this.events[idx].bpm = bpm;
|
|
25
87
|
if (timeSigNum !== undefined)
|
|
26
|
-
|
|
88
|
+
this.events[idx].timeSigNum = timeSigNum;
|
|
27
89
|
if (timeSigDen !== undefined)
|
|
28
|
-
|
|
90
|
+
this.events[idx].timeSigDen = timeSigDen;
|
|
91
|
+
this.changed.emit();
|
|
92
|
+
if (oldBpm !== bpm) {
|
|
93
|
+
this.onTempoChanged.emit({ frame, oldBpm, newBpm: bpm });
|
|
94
|
+
}
|
|
29
95
|
}
|
|
30
96
|
else {
|
|
31
97
|
this.events.push({ frame, bpm, timeSigNum, timeSigDen });
|
|
32
98
|
this.events.sort((a, b) => a.frame - b.frame);
|
|
99
|
+
this.changed.emit();
|
|
100
|
+
this.onTempoChanged.emit({ frame, oldBpm: this.getTempoAtFrame(frame), newBpm: bpm });
|
|
33
101
|
}
|
|
34
|
-
this.changed.emit();
|
|
35
102
|
}
|
|
36
103
|
/**
|
|
37
104
|
* Remove a tempo change at the given frame.
|
|
@@ -40,7 +107,7 @@ export class TempoMap {
|
|
|
40
107
|
removeTempoChange(frame) {
|
|
41
108
|
if (frame === 0)
|
|
42
109
|
return; // Cannot remove the initial tempo event
|
|
43
|
-
const index = this.events
|
|
110
|
+
const index = findExactIndex(this.events, frame);
|
|
44
111
|
if (index !== -1) {
|
|
45
112
|
this.events.splice(index, 1);
|
|
46
113
|
this.changed.emit();
|
|
@@ -48,37 +115,27 @@ export class TempoMap {
|
|
|
48
115
|
}
|
|
49
116
|
/**
|
|
50
117
|
* Get the tempo (BPM) at a given frame position.
|
|
51
|
-
*
|
|
118
|
+
* Uses binary search for efficient lookup.
|
|
52
119
|
*/
|
|
53
120
|
getTempoAtFrame(frame) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (event.frame <= frame) {
|
|
57
|
-
bpm = event.bpm;
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
break;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return bpm;
|
|
121
|
+
const idx = findSegmentIndex(this.events, frame);
|
|
122
|
+
return idx >= 0 ? this.events[idx].bpm : this.events[0].bpm;
|
|
64
123
|
}
|
|
65
124
|
/**
|
|
66
125
|
* Get the time signature at a given frame position.
|
|
67
126
|
* Returns [numerator, denominator].
|
|
127
|
+
* Walks through tempo events that carry time signature overrides.
|
|
68
128
|
*/
|
|
69
129
|
getTimeSignatureAtFrame(frame) {
|
|
70
130
|
let num = 4;
|
|
71
131
|
let den = 4;
|
|
72
|
-
for
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
else {
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
132
|
+
// Walk tempo events for legacy time signature info
|
|
133
|
+
const idx = findSegmentIndex(this.events, frame);
|
|
134
|
+
for (let i = 0; i <= idx; i++) {
|
|
135
|
+
if (this.events[i].timeSigNum !== undefined)
|
|
136
|
+
num = this.events[i].timeSigNum;
|
|
137
|
+
if (this.events[i].timeSigDen !== undefined)
|
|
138
|
+
den = this.events[i].timeSigDen;
|
|
82
139
|
}
|
|
83
140
|
return [num, den];
|
|
84
141
|
}
|
|
@@ -88,6 +145,81 @@ export class TempoMap {
|
|
|
88
145
|
getAllEvents() {
|
|
89
146
|
return [...this.events];
|
|
90
147
|
}
|
|
148
|
+
// ─── Meter Events ────────────────────────────────────────────────────────
|
|
149
|
+
/**
|
|
150
|
+
* Add or update a meter (time signature) change at the given frame position.
|
|
151
|
+
* If a meter change already exists at the exact frame, it is updated.
|
|
152
|
+
*
|
|
153
|
+
* @param frame - Frame position of the meter change
|
|
154
|
+
* @param beatsPerBar - Number of beats per bar (time signature numerator)
|
|
155
|
+
* @param beatValue - Note value that gets one beat (time signature denominator, e.g. 4 = quarter)
|
|
156
|
+
*/
|
|
157
|
+
addMeterChange(frame, beatsPerBar, beatValue) {
|
|
158
|
+
if (beatsPerBar <= 0 || beatValue <= 0)
|
|
159
|
+
return;
|
|
160
|
+
const idx = findExactIndex(this._meterEvents, frame);
|
|
161
|
+
if (idx !== -1) {
|
|
162
|
+
this._meterEvents[idx].beatsPerBar = beatsPerBar;
|
|
163
|
+
this._meterEvents[idx].beatValue = beatValue;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
this._meterEvents.push({ frame, beatsPerBar, beatValue });
|
|
167
|
+
this._meterEvents.sort((a, b) => a.frame - b.frame);
|
|
168
|
+
}
|
|
169
|
+
this.changed.emit();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Remove a meter change at the given frame.
|
|
173
|
+
* The initial meter event at frame 0 cannot be removed.
|
|
174
|
+
*
|
|
175
|
+
* @param frame - Frame position of the meter change to remove
|
|
176
|
+
*/
|
|
177
|
+
removeMeterChange(frame) {
|
|
178
|
+
if (frame === 0)
|
|
179
|
+
return;
|
|
180
|
+
const idx = findExactIndex(this._meterEvents, frame);
|
|
181
|
+
if (idx !== -1) {
|
|
182
|
+
this._meterEvents.splice(idx, 1);
|
|
183
|
+
this.changed.emit();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Get the meter (time signature) at a given frame position.
|
|
188
|
+
* Uses binary search for efficient lookup.
|
|
189
|
+
*
|
|
190
|
+
* @param frame - Frame position to query
|
|
191
|
+
* @returns The active MeterEvent at the given frame
|
|
192
|
+
*/
|
|
193
|
+
getMeterAt(frame) {
|
|
194
|
+
const idx = findSegmentIndex(this._meterEvents, frame);
|
|
195
|
+
if (idx >= 0) {
|
|
196
|
+
return Object.assign({}, this._meterEvents[idx]);
|
|
197
|
+
}
|
|
198
|
+
return Object.assign({}, this._meterEvents[0]);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Get all meter events, sorted by frame.
|
|
202
|
+
*/
|
|
203
|
+
getAllMeterEvents() {
|
|
204
|
+
return [...this._meterEvents];
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get combined tempo and meter information at a given frame position.
|
|
208
|
+
* Convenience method that returns both BPM and time signature data.
|
|
209
|
+
*
|
|
210
|
+
* @param frame - Frame position to query
|
|
211
|
+
* @returns Combined tempo and meter data
|
|
212
|
+
*/
|
|
213
|
+
getTempoAndMeterAt(frame) {
|
|
214
|
+
const bpm = this.getTempoAtFrame(frame);
|
|
215
|
+
const meter = this.getMeterAt(frame);
|
|
216
|
+
return {
|
|
217
|
+
bpm,
|
|
218
|
+
beatsPerBar: meter.beatsPerBar,
|
|
219
|
+
beatValue: meter.beatValue,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
// ─── Frame / Seconds Conversion ──────────────────────────────────────────
|
|
91
223
|
/**
|
|
92
224
|
* Convert frames to seconds, accounting for tempo changes across the timeline.
|
|
93
225
|
* Integrates the duration of each tempo segment.
|
|
@@ -117,6 +249,308 @@ export class TempoMap {
|
|
|
117
249
|
const sr = sampleRate !== null && sampleRate !== void 0 ? sampleRate : this.sampleRate;
|
|
118
250
|
return Math.round(seconds * sr);
|
|
119
251
|
}
|
|
252
|
+
// ─── Absolute Beat / Frame Conversion ────────────────────────────────────
|
|
253
|
+
/**
|
|
254
|
+
* Convert a frame position to an absolute beat count from the start of the timeline,
|
|
255
|
+
* accounting for ALL tempo changes along the way.
|
|
256
|
+
*
|
|
257
|
+
* For each tempo segment, the number of beats is calculated as:
|
|
258
|
+
* beats = (segmentFrames / sampleRate) * (bpm / 60)
|
|
259
|
+
*
|
|
260
|
+
* @param frame - Frame position to convert
|
|
261
|
+
* @param sampleRate - Sample rate override (defaults to constructor value)
|
|
262
|
+
* @returns Absolute beat count from frame 0
|
|
263
|
+
*/
|
|
264
|
+
framesToBeatsAbsolute(frame, sampleRate) {
|
|
265
|
+
const sr = sampleRate !== null && sampleRate !== void 0 ? sampleRate : this.sampleRate;
|
|
266
|
+
let remaining = frame;
|
|
267
|
+
let totalBeats = 0;
|
|
268
|
+
for (let i = 0; i < this.events.length && remaining > 0; i++) {
|
|
269
|
+
const segmentEnd = i + 1 < this.events.length
|
|
270
|
+
? this.events[i + 1].frame - this.events[i].frame
|
|
271
|
+
: Infinity;
|
|
272
|
+
const segmentFrames = Math.min(remaining, segmentEnd);
|
|
273
|
+
if (segmentFrames <= 0)
|
|
274
|
+
continue;
|
|
275
|
+
const bpm = this.events[i].bpm;
|
|
276
|
+
const segmentSeconds = segmentFrames / sr;
|
|
277
|
+
totalBeats += segmentSeconds * (bpm / 60);
|
|
278
|
+
remaining -= segmentFrames;
|
|
279
|
+
}
|
|
280
|
+
return totalBeats;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Convert an absolute beat count from the start of the timeline to a frame position,
|
|
284
|
+
* accounting for ALL tempo changes along the way.
|
|
285
|
+
*
|
|
286
|
+
* Inverse of `framesToBeatsAbsolute`.
|
|
287
|
+
*
|
|
288
|
+
* @param beats - Absolute beat count from the start
|
|
289
|
+
* @param sampleRate - Sample rate override (defaults to constructor value)
|
|
290
|
+
* @returns Frame position
|
|
291
|
+
*/
|
|
292
|
+
beatsToFramesAbsolute(beats, sampleRate) {
|
|
293
|
+
const sr = sampleRate !== null && sampleRate !== void 0 ? sampleRate : this.sampleRate;
|
|
294
|
+
let remainingBeats = beats;
|
|
295
|
+
let totalFrames = 0;
|
|
296
|
+
for (let i = 0; i < this.events.length && remainingBeats > 0; i++) {
|
|
297
|
+
const bpm = this.events[i].bpm;
|
|
298
|
+
const segmentEnd = i + 1 < this.events.length
|
|
299
|
+
? this.events[i + 1].frame - this.events[i].frame
|
|
300
|
+
: Infinity;
|
|
301
|
+
// Max beats this segment can accommodate
|
|
302
|
+
const segmentMaxBeats = (segmentEnd / sr) * (bpm / 60);
|
|
303
|
+
const beatsInSegment = Math.min(remainingBeats, segmentMaxBeats);
|
|
304
|
+
const framesForBeats = (beatsInSegment / (bpm / 60)) * sr;
|
|
305
|
+
totalFrames += framesForBeats;
|
|
306
|
+
remainingBeats -= beatsInSegment;
|
|
307
|
+
}
|
|
308
|
+
return Math.round(totalFrames);
|
|
309
|
+
}
|
|
310
|
+
// ─── BBT (Bar/Beat/Tick) Conversion ──────────────────────────────────────
|
|
311
|
+
/**
|
|
312
|
+
* Convert a frame position to Bar/Beat/Tick notation.
|
|
313
|
+
*
|
|
314
|
+
* Walks through tempo and meter segments to calculate the cumulative
|
|
315
|
+
* bar, beat, and tick position. Uses 1920 ticks per beat (matching Ardour).
|
|
316
|
+
*
|
|
317
|
+
* @param frame - Frame position to convert
|
|
318
|
+
* @param sampleRate - Sample rate override (defaults to constructor value)
|
|
319
|
+
* @returns BBT position (bars and beats are 1-based, ticks are 0-based)
|
|
320
|
+
*/
|
|
321
|
+
framesToBBT(frame, sampleRate) {
|
|
322
|
+
const sr = sampleRate !== null && sampleRate !== void 0 ? sampleRate : this.sampleRate;
|
|
323
|
+
const totalBeats = this.framesToBeatsAbsolute(frame, sr);
|
|
324
|
+
// Walk through meter events to convert absolute beats to BBT.
|
|
325
|
+
// We need to figure out how many beats fall in each meter segment.
|
|
326
|
+
let remainingBeats = totalBeats;
|
|
327
|
+
let bar = 1;
|
|
328
|
+
// Compute beat boundaries for meter segments
|
|
329
|
+
// Each meter segment starts at a certain absolute beat count
|
|
330
|
+
const meterBeatStarts = this._computeMeterBeatStarts(sr);
|
|
331
|
+
for (let i = 0; i < this._meterEvents.length; i++) {
|
|
332
|
+
const meter = this._meterEvents[i];
|
|
333
|
+
const meterStart = meterBeatStarts[i];
|
|
334
|
+
const meterEnd = i + 1 < meterBeatStarts.length ? meterBeatStarts[i + 1] : Infinity;
|
|
335
|
+
// Effective beats per bar, adjusted for beat value.
|
|
336
|
+
// If beatValue = 8 (eighth notes), each "beat" in the bar is half a quarter note.
|
|
337
|
+
// We normalize to quarter-note beats: beatsPerBar * (4 / beatValue)
|
|
338
|
+
const quarterBeatsPerBar = meter.beatsPerBar * (4 / meter.beatValue);
|
|
339
|
+
const beatsInThisSegment = Math.min(remainingBeats, meterEnd - meterStart);
|
|
340
|
+
if (beatsInThisSegment <= 0)
|
|
341
|
+
continue;
|
|
342
|
+
const fullBars = Math.floor(beatsInThisSegment / quarterBeatsPerBar);
|
|
343
|
+
const leftover = beatsInThisSegment - fullBars * quarterBeatsPerBar;
|
|
344
|
+
if (remainingBeats <= meterEnd - meterStart) {
|
|
345
|
+
// We land in this segment
|
|
346
|
+
bar += fullBars;
|
|
347
|
+
// leftover is fractional beats within the current bar
|
|
348
|
+
const beatInBar = Math.floor(leftover) + 1;
|
|
349
|
+
const fractionalBeat = leftover - Math.floor(leftover);
|
|
350
|
+
const tick = Math.round(fractionalBeat * TICKS_PER_BEAT);
|
|
351
|
+
return { bar, beat: beatInBar, tick };
|
|
352
|
+
}
|
|
353
|
+
bar += fullBars;
|
|
354
|
+
// If there's leftover when moving to next segment, it means incomplete bar
|
|
355
|
+
// For simplicity, we only add full bars and carry the remainder
|
|
356
|
+
remainingBeats -= beatsInThisSegment;
|
|
357
|
+
}
|
|
358
|
+
// Fallback: should not normally reach here
|
|
359
|
+
return { bar: 1, beat: 1, tick: 0 };
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Convert Bar/Beat/Tick notation to a frame position.
|
|
363
|
+
*
|
|
364
|
+
* @param bar - Bar number (1-based)
|
|
365
|
+
* @param beat - Beat within bar (1-based)
|
|
366
|
+
* @param tick - Tick within beat (0-based, 0..1919)
|
|
367
|
+
* @param sampleRate - Sample rate override (defaults to constructor value)
|
|
368
|
+
* @returns Frame position
|
|
369
|
+
*/
|
|
370
|
+
bbtToFrames(bar, beat, tick, sampleRate) {
|
|
371
|
+
const sr = sampleRate !== null && sampleRate !== void 0 ? sampleRate : this.sampleRate;
|
|
372
|
+
// Convert BBT to absolute beats, then to frames
|
|
373
|
+
const meterBeatStarts = this._computeMeterBeatStarts(sr);
|
|
374
|
+
let targetBeats = 0;
|
|
375
|
+
// Walk meters to accumulate beats up to the requested bar/beat/tick
|
|
376
|
+
let currentBar = 1;
|
|
377
|
+
for (let i = 0; i < this._meterEvents.length; i++) {
|
|
378
|
+
const meter = this._meterEvents[i];
|
|
379
|
+
const meterEnd = i + 1 < meterBeatStarts.length ? meterBeatStarts[i + 1] : Infinity;
|
|
380
|
+
const segmentBeats = meterEnd - meterBeatStarts[i];
|
|
381
|
+
const quarterBeatsPerBar = meter.beatsPerBar * (4 / meter.beatValue);
|
|
382
|
+
// How many full bars fit in this meter segment
|
|
383
|
+
const fullBarsInSegment = isFinite(segmentBeats)
|
|
384
|
+
? Math.floor(segmentBeats / quarterBeatsPerBar)
|
|
385
|
+
: Infinity;
|
|
386
|
+
const barsNeeded = bar - currentBar;
|
|
387
|
+
if (barsNeeded < fullBarsInSegment || !isFinite(fullBarsInSegment)) {
|
|
388
|
+
// Target bar is within this meter segment
|
|
389
|
+
targetBeats = meterBeatStarts[i] + barsNeeded * quarterBeatsPerBar + (beat - 1) + tick / TICKS_PER_BEAT;
|
|
390
|
+
return this.beatsToFramesAbsolute(targetBeats, sr);
|
|
391
|
+
}
|
|
392
|
+
// Skip past this meter segment
|
|
393
|
+
currentBar += fullBarsInSegment;
|
|
394
|
+
targetBeats = meterBeatStarts[i] + fullBarsInSegment * quarterBeatsPerBar;
|
|
395
|
+
}
|
|
396
|
+
// Fallback
|
|
397
|
+
return this.beatsToFramesAbsolute(targetBeats, sr);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Compute the absolute beat position at which each meter event begins.
|
|
401
|
+
* This integrates tempo across the timeline to find beat offsets for each meter point.
|
|
402
|
+
*/
|
|
403
|
+
_computeMeterBeatStarts(sr) {
|
|
404
|
+
const starts = [];
|
|
405
|
+
for (let i = 0; i < this._meterEvents.length; i++) {
|
|
406
|
+
starts.push(this.framesToBeatsAbsolute(this._meterEvents[i].frame, sr));
|
|
407
|
+
}
|
|
408
|
+
return starts;
|
|
409
|
+
}
|
|
410
|
+
// ─── Grid Points & Snapping ──────────────────────────────────────────────
|
|
411
|
+
/**
|
|
412
|
+
* Returns the number of quarter-note beats per subdivision unit.
|
|
413
|
+
* For example, 'eighth' = 0.5 beats, 'bar' depends on current meter.
|
|
414
|
+
*/
|
|
415
|
+
_subdivisionToBeats(subdivisionType, beatsPerBar, beatValue) {
|
|
416
|
+
const quarterBeatsPerBar = beatsPerBar * (4 / beatValue);
|
|
417
|
+
switch (subdivisionType) {
|
|
418
|
+
case 'bar': return quarterBeatsPerBar;
|
|
419
|
+
case 'beat': return 1;
|
|
420
|
+
case 'half': return 2;
|
|
421
|
+
case 'quarter': return 1;
|
|
422
|
+
case 'eighth': return 0.5;
|
|
423
|
+
case 'sixteenth': return 0.25;
|
|
424
|
+
case 'triplet': return 1 / 3;
|
|
425
|
+
case 'dotted': return 1.5;
|
|
426
|
+
default: return 1;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Generate grid points between two frame positions for a given subdivision type.
|
|
431
|
+
*
|
|
432
|
+
* Walks through tempo and meter segments, generating evenly spaced grid points
|
|
433
|
+
* according to the active tempo and subdivision at each point.
|
|
434
|
+
*
|
|
435
|
+
* @param startFrame - Start of the range (inclusive)
|
|
436
|
+
* @param endFrame - End of the range (inclusive)
|
|
437
|
+
* @param subdivisionType - Grid subdivision type
|
|
438
|
+
* @param sampleRate - Sample rate override (defaults to constructor value)
|
|
439
|
+
* @returns Array of frame positions for grid points within the range
|
|
440
|
+
*/
|
|
441
|
+
getGridPoints(startFrame, endFrame, subdivisionType, sampleRate) {
|
|
442
|
+
const sr = sampleRate !== null && sampleRate !== void 0 ? sampleRate : this.sampleRate;
|
|
443
|
+
const points = [];
|
|
444
|
+
if (startFrame >= endFrame)
|
|
445
|
+
return points;
|
|
446
|
+
// Convert start to absolute beats, quantize to subdivision, then walk forward
|
|
447
|
+
const startBeats = this.framesToBeatsAbsolute(startFrame, sr);
|
|
448
|
+
const meter = this.getMeterAt(startFrame);
|
|
449
|
+
const subBeats = this._subdivisionToBeats(subdivisionType, meter.beatsPerBar, meter.beatValue);
|
|
450
|
+
// Quantize start to the nearest grid line at or before startFrame
|
|
451
|
+
const firstGridBeat = Math.ceil(startBeats / subBeats) * subBeats;
|
|
452
|
+
let currentBeat = firstGridBeat;
|
|
453
|
+
// Safety limit: avoid infinite loops
|
|
454
|
+
const maxIterations = 1000000;
|
|
455
|
+
let iterations = 0;
|
|
456
|
+
while (iterations++ < maxIterations) {
|
|
457
|
+
const frame = this.beatsToFramesAbsolute(currentBeat, sr);
|
|
458
|
+
if (frame > endFrame)
|
|
459
|
+
break;
|
|
460
|
+
if (frame >= startFrame) {
|
|
461
|
+
points.push(frame);
|
|
462
|
+
}
|
|
463
|
+
// Get meter at current frame to determine subdivision size
|
|
464
|
+
const currentMeter = this.getMeterAt(frame);
|
|
465
|
+
const currentSubBeats = this._subdivisionToBeats(subdivisionType, currentMeter.beatsPerBar, currentMeter.beatValue);
|
|
466
|
+
currentBeat += currentSubBeats;
|
|
467
|
+
}
|
|
468
|
+
return points;
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Snap a frame position to the nearest grid point for the given subdivision type.
|
|
472
|
+
*
|
|
473
|
+
* @param frame - Frame position to snap
|
|
474
|
+
* @param subdivisionType - Grid subdivision type
|
|
475
|
+
* @param sampleRate - Sample rate override (defaults to constructor value)
|
|
476
|
+
* @returns The nearest grid-aligned frame position
|
|
477
|
+
*/
|
|
478
|
+
snapToGrid(frame, subdivisionType, sampleRate) {
|
|
479
|
+
const sr = sampleRate !== null && sampleRate !== void 0 ? sampleRate : this.sampleRate;
|
|
480
|
+
const meter = this.getMeterAt(frame);
|
|
481
|
+
const subBeats = this._subdivisionToBeats(subdivisionType, meter.beatsPerBar, meter.beatValue);
|
|
482
|
+
const beats = this.framesToBeatsAbsolute(frame, sr);
|
|
483
|
+
const snappedBeats = Math.round(beats / subBeats) * subBeats;
|
|
484
|
+
return this.beatsToFramesAbsolute(snappedBeats, sr);
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Generate a swing grid between two frame positions.
|
|
488
|
+
*
|
|
489
|
+
* Swing offsets every other grid point by shifting it forward in time.
|
|
490
|
+
* A `swingAmount` of 0 produces a straight grid; 1 pushes the off-beat
|
|
491
|
+
* to the maximum position (the next grid point).
|
|
492
|
+
*
|
|
493
|
+
* @param startFrame - Start of the range (inclusive)
|
|
494
|
+
* @param endFrame - End of the range (inclusive)
|
|
495
|
+
* @param subdivision - Grid subdivision type
|
|
496
|
+
* @param swingAmount - Swing amount between 0 (straight) and 1 (max swing)
|
|
497
|
+
* @param sampleRate - Sample rate override (defaults to constructor value)
|
|
498
|
+
* @returns Array of frame positions for the swing-adjusted grid
|
|
499
|
+
*/
|
|
500
|
+
getSwingGrid(startFrame, endFrame, subdivision, swingAmount, sampleRate) {
|
|
501
|
+
const sr = sampleRate !== null && sampleRate !== void 0 ? sampleRate : this.sampleRate;
|
|
502
|
+
const clampedSwing = Math.max(0, Math.min(1, swingAmount));
|
|
503
|
+
const straightPoints = this.getGridPoints(startFrame, endFrame, subdivision, sr);
|
|
504
|
+
if (clampedSwing === 0 || straightPoints.length < 2) {
|
|
505
|
+
return straightPoints;
|
|
506
|
+
}
|
|
507
|
+
const result = [];
|
|
508
|
+
for (let i = 0; i < straightPoints.length; i++) {
|
|
509
|
+
if (i % 2 === 0) {
|
|
510
|
+
// On-beat: unchanged
|
|
511
|
+
result.push(straightPoints[i]);
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
// Off-beat: shift toward next on-beat
|
|
515
|
+
const prev = straightPoints[i - 1];
|
|
516
|
+
const next = i + 1 < straightPoints.length ? straightPoints[i + 1] : straightPoints[i] + (straightPoints[i] - prev);
|
|
517
|
+
const interval = next - prev;
|
|
518
|
+
// Normal position is at 50% of interval; swing shifts it toward next
|
|
519
|
+
const swungOffset = (0.5 + clampedSwing * 0.5) * interval;
|
|
520
|
+
const swungFrame = Math.round(prev + swungOffset);
|
|
521
|
+
// Clamp to not exceed endFrame
|
|
522
|
+
result.push(Math.min(swungFrame, endFrame));
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
return result;
|
|
526
|
+
}
|
|
527
|
+
// ─── Region Repositioning ────────────────────────────────────────────────
|
|
528
|
+
/**
|
|
529
|
+
* Recalculate a frame position after a tempo change, preserving its musical position.
|
|
530
|
+
*
|
|
531
|
+
* When tempo changes from `oldTempo` to `newTempo`, a region that was at a certain
|
|
532
|
+
* beat position should move to maintain the same musical position. This method
|
|
533
|
+
* calculates the new frame position.
|
|
534
|
+
*
|
|
535
|
+
* @param frame - Original frame position
|
|
536
|
+
* @param oldTempo - Previous tempo in BPM
|
|
537
|
+
* @param newTempo - New tempo in BPM
|
|
538
|
+
* @param sampleRate - Sample rate override (defaults to constructor value)
|
|
539
|
+
* @returns Recalculated frame position
|
|
540
|
+
*/
|
|
541
|
+
repositionFrameForTempoChange(frame, oldTempo, newTempo, sampleRate) {
|
|
542
|
+
if (oldTempo <= 0 || newTempo <= 0)
|
|
543
|
+
return frame;
|
|
544
|
+
const sr = sampleRate !== null && sampleRate !== void 0 ? sampleRate : this.sampleRate;
|
|
545
|
+
// The frame represents a musical position. At oldTempo, that frame
|
|
546
|
+
// corresponds to a certain number of beats. At newTempo, those same
|
|
547
|
+
// beats take a different number of frames.
|
|
548
|
+
const seconds = frame / sr;
|
|
549
|
+
const beats = (seconds * oldTempo) / 60;
|
|
550
|
+
const newSeconds = (beats * 60) / newTempo;
|
|
551
|
+
return Math.round(newSeconds * sr);
|
|
552
|
+
}
|
|
553
|
+
// ─── Frame / Seconds (Legacy) ────────────────────────────────────────────
|
|
120
554
|
// ─── Legacy API (backward-compatible with constant-tempo callers) ─────────
|
|
121
555
|
/** Convert beats to frames at given BPM */
|
|
122
556
|
beatsToFrames(beats, bpm) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TempoMap.js","sourceRoot":"","sources":["../../../src/domain/temporal/TempoMap.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TempoMap.js","sourceRoot":"","sources":["../../../src/domain/temporal/TempoMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAgB,cAAc,EAAE,MAAM,SAAS,CAAC;AAE1E,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAkE1C,gFAAgF;AAEhF;;;GAGG;AACH,SAAS,gBAAgB,CAA8B,MAAW,EAAE,KAAa;IAC7E,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,IAAI,EAAE,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3B,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC;IAChB,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,CAAC;YACb,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;QACjB,CAAC;aAAM,CAAC;YACJ,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;QACjB,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAA8B,MAAW,EAAE,KAAa;IAC3E,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,IAAI,EAAE,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3B,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YAC9B,OAAO,GAAG,CAAC;QACf,CAAC;aAAM,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,KAAK,EAAE,CAAC;YACnC,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;QACjB,CAAC;aAAM,CAAC;YACJ,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;QACjB,CAAC;IACL,CAAC;IACD,OAAO,CAAC,CAAC,CAAC;AACd,CAAC;AAED,gFAAgF;AAEhF;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,QAAQ;IAajB,YACY,aAAqB,KAAK;QAA1B,eAAU,GAAV,UAAU,CAAgB;QAb9B,WAAM,GAAiB,EAAE,CAAC;QAC1B,iBAAY,GAAiB,EAAE,CAAC;QAExC,yFAAyF;QACzE,YAAO,GAAG,IAAI,MAAM,EAAQ,CAAC;QAE7C;;;WAGG;QACa,mBAAc,GAAG,IAAI,MAAM,EAAqD,CAAC;QAK7F,6CAA6C;QAC7C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QACvE,+CAA+C;QAC/C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,4EAA4E;IAE5E;;;OAGG;IACH,cAAc,CAAC,KAAa,EAAE,GAAW,EAAE,UAAmB,EAAE,UAAmB;QAC/E,IAAI,GAAG,IAAI,CAAC;YAAE,OAAO;QAErB,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC/C,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC;YAC3B,IAAI,UAAU,KAAK,SAAS;gBAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,GAAG,UAAU,CAAC;YACvE,IAAI,UAAU,KAAK,SAAS;gBAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,GAAG,UAAU,CAAC;YACvE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpB,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;gBACjB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YAC7D,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;YACzD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;YAC9C,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1F,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,iBAAiB,CAAC,KAAa;QAC3B,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,CAAC,wCAAwC;QACjE,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACjD,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACxB,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,KAAa;QACzB,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACjD,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAChE,CAAC;IAED;;;;OAIG;IACH,uBAAuB,CAAC,KAAa;QACjC,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,mDAAmD;QACnD,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS;gBAAE,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAW,CAAC;YAC9E,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS;gBAAE,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAW,CAAC;QAClF,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,YAAY;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,4EAA4E;IAE5E;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,WAAmB,EAAE,SAAiB;QAChE,IAAI,WAAW,IAAI,CAAC,IAAI,SAAS,IAAI,CAAC;YAAE,OAAO;QAE/C,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QACrD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACb,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,GAAG,WAAW,CAAC;YACjD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC;QACjD,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;YAC1D,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC;IAED;;;;;OAKG;IACH,iBAAiB,CAAC,KAAa;QAC3B,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO;QACxB,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QACrD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACb,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACxB,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CAAC,KAAa;QACpB,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QACvD,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACX,yBAAY,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAG;QACzC,CAAC;QACD,yBAAY,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAG;IACvC,CAAC;IAED;;OAEG;IACH,iBAAiB;QACb,OAAO,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;IAClC,CAAC;IAED;;;;;;OAMG;IACH,kBAAkB,CAAC,KAAa;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACrC,OAAO;YACH,GAAG;YACH,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;SAC7B,CAAC;IACN,CAAC;IAED,4EAA4E;IAE5E;;;OAGG;IACH,eAAe,CAAC,MAAkB,EAAE,UAAmB;QACnD,MAAM,EAAE,GAAG,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,IAAI,CAAC,UAAU,CAAC;QACzC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,MAAM,GAAG,EAAE,CAAC;QACvB,CAAC;QAED,IAAI,SAAS,GAAG,MAAM,CAAC;QACvB,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3D,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC1C,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;YACpF,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,GAAG,YAAY,CAAC,CAAC;YAErE,IAAI,aAAa,IAAI,CAAC;gBAAE,SAAS;YAEjC,OAAO,IAAI,aAAa,GAAG,EAAE,CAAC;YAC9B,SAAS,IAAI,aAAa,CAAC;QAC/B,CAAC;QAED,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,OAAe,EAAE,UAAmB;QAChD,MAAM,EAAE,GAAG,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,IAAI,CAAC,UAAU,CAAC;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,4EAA4E;IAE5E;;;;;;;;;;OAUG;IACH,qBAAqB,CAAC,KAAa,EAAE,UAAmB;QACpD,MAAM,EAAE,GAAG,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,IAAI,CAAC,UAAU,CAAC;QACzC,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3D,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM;gBACzC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;gBACjD,CAAC,CAAC,QAAQ,CAAC;YACf,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YACtD,IAAI,aAAa,IAAI,CAAC;gBAAE,SAAS;YAEjC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAC/B,MAAM,cAAc,GAAG,aAAa,GAAG,EAAE,CAAC;YAC1C,UAAU,IAAI,cAAc,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;YAC1C,SAAS,IAAI,aAAa,CAAC;QAC/B,CAAC;QAED,OAAO,UAAU,CAAC;IACtB,CAAC;IAED;;;;;;;;;OASG;IACH,qBAAqB,CAAC,KAAa,EAAE,UAAmB;QACpD,MAAM,EAAE,GAAG,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,IAAI,CAAC,UAAU,CAAC;QACzC,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAChE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAC/B,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM;gBACzC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;gBACjD,CAAC,CAAC,QAAQ,CAAC;YAEf,yCAAyC;YACzC,MAAM,eAAe,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;YACvD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;YACjE,MAAM,cAAc,GAAG,CAAC,cAAc,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;YAE1D,WAAW,IAAI,cAAc,CAAC;YAC9B,cAAc,IAAI,cAAc,CAAC;QACrC,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IAED,4EAA4E;IAE5E;;;;;;;;;OASG;IACH,WAAW,CAAC,KAAa,EAAE,UAAmB;QAC1C,MAAM,EAAE,GAAG,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,IAAI,CAAC,UAAU,CAAC;QACzC,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAEzD,8DAA8D;QAC9D,mEAAmE;QACnE,IAAI,cAAc,GAAG,UAAU,CAAC;QAChC,IAAI,GAAG,GAAG,CAAC,CAAC;QAEZ,6CAA6C;QAC7C,6DAA6D;QAC7D,MAAM,eAAe,GAAG,IAAI,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC;QAEzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YAEpF,oDAAoD;YACpD,kFAAkF;YAClF,oEAAoE;YACpE,MAAM,kBAAkB,GAAG,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;YAErE,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,QAAQ,GAAG,UAAU,CAAC,CAAC;YAC3E,IAAI,kBAAkB,IAAI,CAAC;gBAAE,SAAS;YAEtC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,GAAG,kBAAkB,CAAC,CAAC;YACrE,MAAM,QAAQ,GAAG,kBAAkB,GAAG,QAAQ,GAAG,kBAAkB,CAAC;YAEpE,IAAI,cAAc,IAAI,QAAQ,GAAG,UAAU,EAAE,CAAC;gBAC1C,0BAA0B;gBAC1B,GAAG,IAAI,QAAQ,CAAC;gBAChB,sDAAsD;gBACtD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC3C,MAAM,cAAc,GAAG,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACvD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,cAAc,CAAC,CAAC;gBACzD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;YAC1C,CAAC;YAED,GAAG,IAAI,QAAQ,CAAC;YAChB,2EAA2E;YAC3E,gEAAgE;YAChE,cAAc,IAAI,kBAAkB,CAAC;QACzC,CAAC;QAED,2CAA2C;QAC3C,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACxC,CAAC;IAED;;;;;;;;OAQG;IACH,WAAW,CAAC,GAAW,EAAE,IAAY,EAAE,IAAY,EAAE,UAAmB;QACpE,MAAM,EAAE,GAAG,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,IAAI,CAAC,UAAU,CAAC;QAEzC,gDAAgD;QAChD,MAAM,eAAe,GAAG,IAAI,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC;QACzD,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,oEAAoE;QACpE,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YACpF,MAAM,YAAY,GAAG,QAAQ,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;YAEnD,MAAM,kBAAkB,GAAG,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;YAErE,+CAA+C;YAC/C,MAAM,iBAAiB,GAAG,QAAQ,CAAC,YAAY,CAAC;gBAC5C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,kBAAkB,CAAC;gBAC/C,CAAC,CAAC,QAAQ,CAAC;YAEf,MAAM,UAAU,GAAG,GAAG,GAAG,UAAU,CAAC;YAEpC,IAAI,UAAU,GAAG,iBAAiB,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACjE,0CAA0C;gBAC1C,WAAW,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,UAAU,GAAG,kBAAkB,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,cAAc,CAAC;gBACxG,OAAO,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YACvD,CAAC;YAED,+BAA+B;YAC/B,UAAU,IAAI,iBAAiB,CAAC;YAChC,WAAW,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;QAC9E,CAAC;QAED,WAAW;QACX,OAAO,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACK,uBAAuB,CAAC,EAAU;QACtC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,4EAA4E;IAE5E;;;OAGG;IACK,mBAAmB,CAAC,eAAgC,EAAE,WAAmB,EAAE,SAAiB;QAChG,MAAM,kBAAkB,GAAG,WAAW,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;QACzD,QAAQ,eAAe,EAAE,CAAC;YACtB,KAAK,KAAK,CAAC,CAAO,OAAO,kBAAkB,CAAC;YAC5C,KAAK,MAAM,CAAC,CAAM,OAAO,CAAC,CAAC;YAC3B,KAAK,MAAM,CAAC,CAAM,OAAO,CAAC,CAAC;YAC3B,KAAK,SAAS,CAAC,CAAG,OAAO,CAAC,CAAC;YAC3B,KAAK,QAAQ,CAAC,CAAI,OAAO,GAAG,CAAC;YAC7B,KAAK,WAAW,CAAC,CAAC,OAAO,IAAI,CAAC;YAC9B,KAAK,SAAS,CAAC,CAAG,OAAO,CAAC,GAAG,CAAC,CAAC;YAC/B,KAAK,QAAQ,CAAC,CAAI,OAAO,GAAG,CAAC;YAC7B,OAAO,CAAC,CAAU,OAAO,CAAC,CAAC;QAC/B,CAAC;IACL,CAAC;IAED;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,UAAkB,EAAE,QAAgB,EAAE,eAAgC,EAAE,UAAmB;QACrG,MAAM,EAAE,GAAG,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,IAAI,CAAC,UAAU,CAAC;QACzC,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,IAAI,UAAU,IAAI,QAAQ;YAAE,OAAO,MAAM,CAAC;QAE1C,8EAA8E;QAC9E,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,eAAe,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAE/F,kEAAkE;QAClE,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC;QAElE,IAAI,WAAW,GAAG,aAAa,CAAC;QAChC,qCAAqC;QACrC,MAAM,aAAa,GAAG,OAAS,CAAC;QAChC,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,OAAO,UAAU,EAAE,GAAG,aAAa,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAC1D,IAAI,KAAK,GAAG,QAAQ;gBAAE,MAAM;YAC5B,IAAI,KAAK,IAAI,UAAU,EAAE,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;YAED,2DAA2D;YAC3D,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAC5C,MAAM,eAAe,GAAG,IAAI,CAAC,mBAAmB,CAAC,eAAe,EAAE,YAAY,CAAC,WAAW,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;YACpH,WAAW,IAAI,eAAe,CAAC;QACnC,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,KAAa,EAAE,eAAgC,EAAE,UAAmB;QAC3E,MAAM,EAAE,GAAG,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,IAAI,CAAC,UAAU,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,eAAe,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAE/F,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACpD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC;QAC7D,OAAO,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACxD,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,UAAkB,EAAE,QAAgB,EAAE,WAA4B,EAAE,WAAmB,EAAE,UAAmB;QACrH,MAAM,EAAE,GAAG,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,IAAI,CAAC,UAAU,CAAC;QACzC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;QAC3D,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;QAEjF,IAAI,YAAY,KAAK,CAAC,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,OAAO,cAAc,CAAC;QAC1B,CAAC;QAED,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACd,qBAAqB;gBACrB,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACJ,sCAAsC;gBACtC,MAAM,IAAI,GAAG,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBACnC,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;gBACpH,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC;gBAC7B,qEAAqE;gBACrE,MAAM,WAAW,GAAG,CAAC,GAAG,GAAG,YAAY,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC;gBAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,WAAW,CAAC,CAAC;gBAClD,+BAA+B;gBAC/B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;YAChD,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,4EAA4E;IAE5E;;;;;;;;;;;;OAYG;IACH,6BAA6B,CAAC,KAAa,EAAE,QAAgB,EAAE,QAAgB,EAAE,UAAmB;QAChG,IAAI,QAAQ,IAAI,CAAC,IAAI,QAAQ,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACjD,MAAM,EAAE,GAAG,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,IAAI,CAAC,UAAU,CAAC;QACzC,mEAAmE;QACnE,oEAAoE;QACpE,2CAA2C;QAC3C,MAAM,OAAO,GAAG,KAAK,GAAG,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC;QACxC,MAAM,UAAU,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC;QAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,4EAA4E;IAE5E,6EAA6E;IAE7E,2CAA2C;IAC3C,aAAa,CAAC,KAAY,EAAE,GAAW;QACnC,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC;IAED,2CAA2C;IAC3C,aAAa,CAAC,MAAkB,EAAE,GAAW;QACzC,MAAM,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;QACzC,MAAM,SAAS,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC;QACvC,OAAO,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED,qCAAqC;IACrC,QAAQ,CAAC,GAAiB,EAAE,GAAW;QACnC,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,SAAS,EAAE,CAAC;YACtC,OAAO,GAAG,CAAC,KAAK,CAAC;QACrB,CAAC;aAAM,CAAC;YACJ,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/D,CAAC;IACL,CAAC;IAED,oCAAoC;IACpC,OAAO,CAAC,GAAiB,EAAE,GAAW;QAClC,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,QAAQ,EAAE,CAAC;YACrC,OAAO,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACJ,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;IACL,CAAC;CACJ"}
|