@waveform-playlist/browser 12.0.0 → 12.1.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/dist/index.d.mts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +129 -62
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +117 -50
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
package/dist/index.d.mts
CHANGED
|
@@ -54,10 +54,23 @@ interface PlaybackAnimationContextValue {
|
|
|
54
54
|
isPlaying: boolean;
|
|
55
55
|
currentTime: number;
|
|
56
56
|
currentTimeRef: React__default.RefObject<number>;
|
|
57
|
+
/**
|
|
58
|
+
* Visually-aligned playback time (raw engine time minus `outputLatency` and
|
|
59
|
+
* `engine.lookAhead`). Kept current by the animation loop during playback
|
|
60
|
+
* and by pause/seek/stop paths when stopped. Read from this for any visual
|
|
61
|
+
* positioning that should match the audible output.
|
|
62
|
+
*/
|
|
63
|
+
visualTimeRef: React__default.RefObject<number>;
|
|
57
64
|
playbackStartTimeRef: React__default.RefObject<number>;
|
|
58
65
|
audioStartPositionRef: React__default.RefObject<number>;
|
|
59
|
-
/** Returns
|
|
66
|
+
/** Returns raw playback time from engine (auto-wraps at loop boundaries). */
|
|
60
67
|
getPlaybackTime: () => number;
|
|
68
|
+
/**
|
|
69
|
+
* Returns the current adapter scheduler lookahead (Tone ~0.1s, native 0).
|
|
70
|
+
* Use this for any audible-latency calculation that must match the playhead
|
|
71
|
+
* (e.g., recording live-preview peak slicing).
|
|
72
|
+
*/
|
|
73
|
+
getLookAhead: () => number;
|
|
61
74
|
/** Register a per-frame callback driven by the single animation loop. */
|
|
62
75
|
registerFrameCallback: (id: string, cb: (data: FrameData) => void) => void;
|
|
63
76
|
/** Unregister a per-frame callback. */
|
package/dist/index.d.ts
CHANGED
|
@@ -54,10 +54,23 @@ interface PlaybackAnimationContextValue {
|
|
|
54
54
|
isPlaying: boolean;
|
|
55
55
|
currentTime: number;
|
|
56
56
|
currentTimeRef: React__default.RefObject<number>;
|
|
57
|
+
/**
|
|
58
|
+
* Visually-aligned playback time (raw engine time minus `outputLatency` and
|
|
59
|
+
* `engine.lookAhead`). Kept current by the animation loop during playback
|
|
60
|
+
* and by pause/seek/stop paths when stopped. Read from this for any visual
|
|
61
|
+
* positioning that should match the audible output.
|
|
62
|
+
*/
|
|
63
|
+
visualTimeRef: React__default.RefObject<number>;
|
|
57
64
|
playbackStartTimeRef: React__default.RefObject<number>;
|
|
58
65
|
audioStartPositionRef: React__default.RefObject<number>;
|
|
59
|
-
/** Returns
|
|
66
|
+
/** Returns raw playback time from engine (auto-wraps at loop boundaries). */
|
|
60
67
|
getPlaybackTime: () => number;
|
|
68
|
+
/**
|
|
69
|
+
* Returns the current adapter scheduler lookahead (Tone ~0.1s, native 0).
|
|
70
|
+
* Use this for any audible-latency calculation that must match the playhead
|
|
71
|
+
* (e.g., recording live-preview peak slicing).
|
|
72
|
+
*/
|
|
73
|
+
getLookAhead: () => number;
|
|
61
74
|
/** Register a per-frame callback driven by the single animation loop. */
|
|
62
75
|
registerFrameCallback: (id: string, cb: (data: FrameData) => void) => void;
|
|
63
76
|
/** Unregister a per-frame callback. */
|
package/dist/index.js
CHANGED
|
@@ -3692,6 +3692,7 @@ var WaveformPlaylistProvider = ({
|
|
|
3692
3692
|
isPlayingRef.current = isPlaying;
|
|
3693
3693
|
const playStartPositionRef = (0, import_react24.useRef)(0);
|
|
3694
3694
|
const currentTimeRef = (0, import_react24.useRef)(0);
|
|
3695
|
+
const visualTimeRef = (0, import_react24.useRef)(0);
|
|
3695
3696
|
const tracksRef = (0, import_react24.useRef)(tracks);
|
|
3696
3697
|
const soundFontCacheRef = (0, import_react24.useRef)(soundFontCache);
|
|
3697
3698
|
soundFontCacheRef.current = soundFontCache;
|
|
@@ -4162,6 +4163,25 @@ var WaveformPlaylistProvider = ({
|
|
|
4162
4163
|
const elapsed = (0, import_tone4.getContext)().currentTime - ((_a2 = playbackStartTimeRef.current) != null ? _a2 : 0);
|
|
4163
4164
|
return ((_b2 = audioStartPositionRef.current) != null ? _b2 : 0) + elapsed;
|
|
4164
4165
|
}, []);
|
|
4166
|
+
const toVisualTime = (0, import_react24.useCallback)((rawTime) => {
|
|
4167
|
+
var _a2, _b2;
|
|
4168
|
+
const audioCtx = (0, import_playout5.getGlobalAudioContext)();
|
|
4169
|
+
const latency = "outputLatency" in audioCtx ? audioCtx.outputLatency : 0;
|
|
4170
|
+
const lookAhead = (_b2 = (_a2 = engineRef.current) == null ? void 0 : _a2.lookAhead) != null ? _b2 : 0;
|
|
4171
|
+
const visual = rawTime - latency - lookAhead;
|
|
4172
|
+
return Number.isFinite(visual) ? Math.max(0, visual) : 0;
|
|
4173
|
+
}, []);
|
|
4174
|
+
const setCurrentTimeRefs = (0, import_react24.useCallback)(
|
|
4175
|
+
(rawTime) => {
|
|
4176
|
+
currentTimeRef.current = rawTime;
|
|
4177
|
+
visualTimeRef.current = toVisualTime(rawTime);
|
|
4178
|
+
},
|
|
4179
|
+
[toVisualTime]
|
|
4180
|
+
);
|
|
4181
|
+
const getLookAhead = (0, import_react24.useCallback)(() => {
|
|
4182
|
+
var _a2, _b2;
|
|
4183
|
+
return (_b2 = (_a2 = engineRef.current) == null ? void 0 : _a2.lookAhead) != null ? _b2 : 0;
|
|
4184
|
+
}, []);
|
|
4165
4185
|
const registerFrameCallback = (0, import_react24.useCallback)((id, cb) => {
|
|
4166
4186
|
frameCallbacksRef.current.set(id, cb);
|
|
4167
4187
|
}, []);
|
|
@@ -4171,10 +4191,14 @@ var WaveformPlaylistProvider = ({
|
|
|
4171
4191
|
const startAnimationLoop = (0, import_react24.useCallback)(() => {
|
|
4172
4192
|
const audioCtx = (0, import_playout5.getGlobalAudioContext)();
|
|
4173
4193
|
const updateTime = () => {
|
|
4194
|
+
var _a2, _b2;
|
|
4174
4195
|
const time = getPlaybackTime();
|
|
4175
4196
|
currentTimeRef.current = time;
|
|
4176
4197
|
const latency = "outputLatency" in audioCtx ? audioCtx.outputLatency : 0;
|
|
4177
|
-
const
|
|
4198
|
+
const lookAhead = (_b2 = (_a2 = engineRef.current) == null ? void 0 : _a2.lookAhead) != null ? _b2 : 0;
|
|
4199
|
+
const visualRaw = time - latency - lookAhead;
|
|
4200
|
+
const visualTime = Number.isFinite(visualRaw) ? Math.max(0, visualRaw) : 0;
|
|
4201
|
+
visualTimeRef.current = visualTime;
|
|
4178
4202
|
const sr = sampleRateRef.current;
|
|
4179
4203
|
const spp = samplesPerPixelRef.current;
|
|
4180
4204
|
const frameData = {
|
|
@@ -4207,7 +4231,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4207
4231
|
engineRef.current.stop();
|
|
4208
4232
|
}
|
|
4209
4233
|
setIsPlaying(false);
|
|
4210
|
-
|
|
4234
|
+
setCurrentTimeRefs(playStartPositionRef.current);
|
|
4211
4235
|
setCurrentTime(playStartPositionRef.current);
|
|
4212
4236
|
return;
|
|
4213
4237
|
}
|
|
@@ -4230,7 +4254,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4230
4254
|
engineRef.current.stop();
|
|
4231
4255
|
}
|
|
4232
4256
|
setIsPlaying(false);
|
|
4233
|
-
|
|
4257
|
+
setCurrentTimeRefs(playbackEndTimeRef.current);
|
|
4234
4258
|
setCurrentTime(playbackEndTimeRef.current);
|
|
4235
4259
|
playbackEndTimeRef.current = null;
|
|
4236
4260
|
return;
|
|
@@ -4240,7 +4264,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4240
4264
|
engineRef.current.stop();
|
|
4241
4265
|
}
|
|
4242
4266
|
setIsPlaying(false);
|
|
4243
|
-
|
|
4267
|
+
setCurrentTimeRefs(playStartPositionRef.current);
|
|
4244
4268
|
setCurrentTime(playStartPositionRef.current);
|
|
4245
4269
|
setActiveAnnotationId(null);
|
|
4246
4270
|
return;
|
|
@@ -4248,7 +4272,13 @@ var WaveformPlaylistProvider = ({
|
|
|
4248
4272
|
startAnimationFrameLoop(updateTime);
|
|
4249
4273
|
};
|
|
4250
4274
|
startAnimationFrameLoop(updateTime);
|
|
4251
|
-
}, [
|
|
4275
|
+
}, [
|
|
4276
|
+
duration,
|
|
4277
|
+
setActiveAnnotationId,
|
|
4278
|
+
startAnimationFrameLoop,
|
|
4279
|
+
getPlaybackTime,
|
|
4280
|
+
setCurrentTimeRefs
|
|
4281
|
+
]);
|
|
4252
4282
|
const stopAnimationLoop = stopAnimationFrameLoop;
|
|
4253
4283
|
(0, import_react24.useEffect)(() => {
|
|
4254
4284
|
const reschedulePlayback = () => __async(null, null, function* () {
|
|
@@ -4304,7 +4334,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4304
4334
|
if (!engineRef.current) return;
|
|
4305
4335
|
const actualStartTime = startTime != null ? startTime : currentTimeRef.current;
|
|
4306
4336
|
playStartPositionRef.current = actualStartTime;
|
|
4307
|
-
|
|
4337
|
+
setCurrentTimeRefs(actualStartTime);
|
|
4308
4338
|
engineRef.current.stop();
|
|
4309
4339
|
engineRef.current.seek(actualStartTime);
|
|
4310
4340
|
stopAnimationLoop();
|
|
@@ -4328,7 +4358,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4328
4358
|
setIsPlaying(true);
|
|
4329
4359
|
startAnimationLoop();
|
|
4330
4360
|
}),
|
|
4331
|
-
[startAnimationLoop, stopAnimationLoop]
|
|
4361
|
+
[startAnimationLoop, stopAnimationLoop, setCurrentTimeRefs]
|
|
4332
4362
|
);
|
|
4333
4363
|
const pause = (0, import_react24.useCallback)(() => {
|
|
4334
4364
|
if (!engineRef.current) return;
|
|
@@ -4336,28 +4366,28 @@ var WaveformPlaylistProvider = ({
|
|
|
4336
4366
|
engineRef.current.pause();
|
|
4337
4367
|
setIsPlaying(false);
|
|
4338
4368
|
stopAnimationLoop();
|
|
4339
|
-
|
|
4369
|
+
setCurrentTimeRefs(pauseTime);
|
|
4340
4370
|
setCurrentTime(pauseTime);
|
|
4341
|
-
}, [stopAnimationLoop, getPlaybackTime]);
|
|
4371
|
+
}, [stopAnimationLoop, getPlaybackTime, setCurrentTimeRefs]);
|
|
4342
4372
|
const stop = (0, import_react24.useCallback)(() => {
|
|
4343
4373
|
if (!engineRef.current) return;
|
|
4344
4374
|
engineRef.current.stop();
|
|
4345
4375
|
setIsPlaying(false);
|
|
4346
4376
|
stopAnimationLoop();
|
|
4347
|
-
|
|
4377
|
+
setCurrentTimeRefs(playStartPositionRef.current);
|
|
4348
4378
|
setCurrentTime(playStartPositionRef.current);
|
|
4349
4379
|
setActiveAnnotationId(null);
|
|
4350
|
-
}, [stopAnimationLoop, setActiveAnnotationId]);
|
|
4380
|
+
}, [stopAnimationLoop, setActiveAnnotationId, setCurrentTimeRefs]);
|
|
4351
4381
|
const seekTo = (0, import_react24.useCallback)(
|
|
4352
4382
|
(time) => {
|
|
4353
4383
|
const clampedTime = Math.max(0, Math.min(time, duration));
|
|
4354
|
-
|
|
4384
|
+
setCurrentTimeRefs(clampedTime);
|
|
4355
4385
|
setCurrentTime(clampedTime);
|
|
4356
4386
|
if (isPlaying && engineRef.current) {
|
|
4357
4387
|
play(clampedTime);
|
|
4358
4388
|
}
|
|
4359
4389
|
},
|
|
4360
|
-
[duration, isPlaying, play]
|
|
4390
|
+
[duration, isPlaying, play, setCurrentTimeRefs]
|
|
4361
4391
|
);
|
|
4362
4392
|
const setTrackMute = (0, import_react24.useCallback)(
|
|
4363
4393
|
(trackIndex, muted) => {
|
|
@@ -4418,7 +4448,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4418
4448
|
const setSelection = (0, import_react24.useCallback)(
|
|
4419
4449
|
(start, end) => {
|
|
4420
4450
|
setSelectionEngine(start, end);
|
|
4421
|
-
|
|
4451
|
+
setCurrentTimeRefs(start);
|
|
4422
4452
|
setCurrentTime(start);
|
|
4423
4453
|
if (isPlaying && engineRef.current) {
|
|
4424
4454
|
engineRef.current.stop();
|
|
@@ -4426,7 +4456,7 @@ var WaveformPlaylistProvider = ({
|
|
|
4426
4456
|
engineRef.current.play(start);
|
|
4427
4457
|
}
|
|
4428
4458
|
},
|
|
4429
|
-
[isPlaying, setSelectionEngine]
|
|
4459
|
+
[isPlaying, setSelectionEngine, setCurrentTimeRefs]
|
|
4430
4460
|
);
|
|
4431
4461
|
const setScrollContainer = (0, import_react24.useCallback)((element) => {
|
|
4432
4462
|
scrollContainerRef.current = element;
|
|
@@ -4456,9 +4486,11 @@ var WaveformPlaylistProvider = ({
|
|
|
4456
4486
|
isPlaying,
|
|
4457
4487
|
currentTime,
|
|
4458
4488
|
currentTimeRef,
|
|
4489
|
+
visualTimeRef,
|
|
4459
4490
|
playbackStartTimeRef,
|
|
4460
4491
|
audioStartPositionRef,
|
|
4461
4492
|
getPlaybackTime,
|
|
4493
|
+
getLookAhead,
|
|
4462
4494
|
registerFrameCallback,
|
|
4463
4495
|
unregisterFrameCallback
|
|
4464
4496
|
}),
|
|
@@ -4466,9 +4498,11 @@ var WaveformPlaylistProvider = ({
|
|
|
4466
4498
|
isPlaying,
|
|
4467
4499
|
currentTime,
|
|
4468
4500
|
currentTimeRef,
|
|
4501
|
+
visualTimeRef,
|
|
4469
4502
|
playbackStartTimeRef,
|
|
4470
4503
|
audioStartPositionRef,
|
|
4471
4504
|
getPlaybackTime,
|
|
4505
|
+
getLookAhead,
|
|
4472
4506
|
registerFrameCallback,
|
|
4473
4507
|
unregisterFrameCallback
|
|
4474
4508
|
]
|
|
@@ -4511,10 +4545,10 @@ var WaveformPlaylistProvider = ({
|
|
|
4511
4545
|
);
|
|
4512
4546
|
const setCurrentTimeControl = (0, import_react24.useCallback)(
|
|
4513
4547
|
(time) => {
|
|
4514
|
-
|
|
4548
|
+
setCurrentTimeRefs(time);
|
|
4515
4549
|
setCurrentTime(time);
|
|
4516
4550
|
},
|
|
4517
|
-
[
|
|
4551
|
+
[setCurrentTimeRefs]
|
|
4518
4552
|
);
|
|
4519
4553
|
const setAutomaticScrollControl = (0, import_react24.useCallback)((enabled) => {
|
|
4520
4554
|
setIsAutomaticScroll(enabled);
|
|
@@ -5402,6 +5436,7 @@ var import_react_dom = require("react-dom");
|
|
|
5402
5436
|
var import_styled_components6 = __toESM(require("styled-components"));
|
|
5403
5437
|
var import_playout6 = require("@waveform-playlist/playout");
|
|
5404
5438
|
var import_ui_components9 = require("@waveform-playlist/ui-components");
|
|
5439
|
+
var import_core8 = require("@waveform-playlist/core");
|
|
5405
5440
|
|
|
5406
5441
|
// src/components/AnimatedPlayhead.tsx
|
|
5407
5442
|
var import_react30 = require("react");
|
|
@@ -5423,7 +5458,13 @@ var PlayheadLine = import_styled_components4.default.div.attrs((props) => ({
|
|
|
5423
5458
|
`;
|
|
5424
5459
|
var AnimatedPlayhead = ({ color = "#ff0000" }) => {
|
|
5425
5460
|
const playheadRef = (0, import_react30.useRef)(null);
|
|
5426
|
-
const {
|
|
5461
|
+
const {
|
|
5462
|
+
isPlaying,
|
|
5463
|
+
currentTimeRef,
|
|
5464
|
+
visualTimeRef,
|
|
5465
|
+
registerFrameCallback,
|
|
5466
|
+
unregisterFrameCallback
|
|
5467
|
+
} = usePlaybackAnimation();
|
|
5427
5468
|
const { samplesPerPixel, sampleRate, progressBarWidth } = usePlaylistData();
|
|
5428
5469
|
(0, import_react30.useEffect)(() => {
|
|
5429
5470
|
const id = "playhead";
|
|
@@ -5438,9 +5479,9 @@ var AnimatedPlayhead = ({ color = "#ff0000" }) => {
|
|
|
5438
5479
|
return () => unregisterFrameCallback(id);
|
|
5439
5480
|
}, [isPlaying, registerFrameCallback, unregisterFrameCallback]);
|
|
5440
5481
|
(0, import_react30.useEffect)(() => {
|
|
5441
|
-
var _a;
|
|
5482
|
+
var _a, _b;
|
|
5442
5483
|
if (!isPlaying && playheadRef.current) {
|
|
5443
|
-
const time = (_a =
|
|
5484
|
+
const time = (_b = (_a = visualTimeRef.current) != null ? _a : currentTimeRef.current) != null ? _b : 0;
|
|
5444
5485
|
const position = time * sampleRate / samplesPerPixel;
|
|
5445
5486
|
playheadRef.current.style.transform = `translate3d(${position}px, 0, 0)`;
|
|
5446
5487
|
}
|
|
@@ -5511,7 +5552,13 @@ var ChannelWithProgress = (_a) => {
|
|
|
5511
5552
|
const callbackId = (0, import_react31.useId)();
|
|
5512
5553
|
const theme = (0, import_ui_components8.useTheme)();
|
|
5513
5554
|
const { waveHeight } = (0, import_ui_components8.usePlaylistInfo)();
|
|
5514
|
-
const {
|
|
5555
|
+
const {
|
|
5556
|
+
isPlaying,
|
|
5557
|
+
currentTimeRef,
|
|
5558
|
+
visualTimeRef,
|
|
5559
|
+
registerFrameCallback,
|
|
5560
|
+
unregisterFrameCallback
|
|
5561
|
+
} = usePlaybackAnimation();
|
|
5515
5562
|
const { samplesPerPixel, sampleRate } = usePlaylistData();
|
|
5516
5563
|
const progressColor = (theme == null ? void 0 : theme.waveProgressColor) || "rgba(0, 0, 0, 0.1)";
|
|
5517
5564
|
const clipPixelWidth = (0, import_core7.clipPixelWidth)(
|
|
@@ -5548,9 +5595,9 @@ var ChannelWithProgress = (_a) => {
|
|
|
5548
5595
|
unregisterFrameCallback
|
|
5549
5596
|
]);
|
|
5550
5597
|
(0, import_react31.useEffect)(() => {
|
|
5551
|
-
var _a2;
|
|
5598
|
+
var _a2, _b2;
|
|
5552
5599
|
if (!isPlaying && progressRef.current) {
|
|
5553
|
-
const currentTime = (_a2 =
|
|
5600
|
+
const currentTime = (_b2 = (_a2 = visualTimeRef.current) != null ? _a2 : currentTimeRef.current) != null ? _b2 : 0;
|
|
5554
5601
|
const currentSample = currentTime * sampleRate;
|
|
5555
5602
|
const clipEndSample = clipStartSample + clipDurationSamples;
|
|
5556
5603
|
let ratio = 0;
|
|
@@ -5658,25 +5705,28 @@ var ControlSlot = import_styled_components6.default.div.attrs((props) => ({
|
|
|
5658
5705
|
${(props) => props.$isSelected && `background: ${props.theme.selectedTrackControlsBackground};`}
|
|
5659
5706
|
`;
|
|
5660
5707
|
var CustomPlayhead = ({ renderPlayhead, color, samplesPerPixel, sampleRate }) => {
|
|
5661
|
-
var _a;
|
|
5708
|
+
var _a, _b;
|
|
5662
5709
|
const {
|
|
5663
5710
|
isPlaying,
|
|
5664
5711
|
currentTimeRef,
|
|
5712
|
+
visualTimeRef,
|
|
5665
5713
|
playbackStartTimeRef,
|
|
5666
5714
|
audioStartPositionRef,
|
|
5667
5715
|
getPlaybackTime
|
|
5668
5716
|
} = usePlaybackAnimation();
|
|
5717
|
+
const visualTime = (_b = (_a = visualTimeRef.current) != null ? _a : currentTimeRef.current) != null ? _b : 0;
|
|
5669
5718
|
return renderPlayhead({
|
|
5670
|
-
position:
|
|
5719
|
+
position: visualTime * sampleRate / samplesPerPixel,
|
|
5671
5720
|
color,
|
|
5672
5721
|
isPlaying,
|
|
5673
5722
|
currentTimeRef,
|
|
5723
|
+
visualTimeRef,
|
|
5674
5724
|
playbackStartTimeRef,
|
|
5675
5725
|
audioStartPositionRef,
|
|
5676
5726
|
samplesPerPixel,
|
|
5677
5727
|
sampleRate,
|
|
5678
5728
|
controlsOffset: 0,
|
|
5679
|
-
getAudioContextTime: () => (0, import_playout6.
|
|
5729
|
+
getAudioContextTime: () => (0, import_playout6.getGlobalAudioContext)().currentTime,
|
|
5680
5730
|
getPlaybackTime
|
|
5681
5731
|
});
|
|
5682
5732
|
};
|
|
@@ -5701,7 +5751,7 @@ var PlaylistVisualization = ({
|
|
|
5701
5751
|
}) => {
|
|
5702
5752
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
5703
5753
|
const theme = (0, import_ui_components9.useTheme)();
|
|
5704
|
-
const { isPlaying } = usePlaybackAnimation();
|
|
5754
|
+
const { isPlaying, getLookAhead } = usePlaybackAnimation();
|
|
5705
5755
|
const {
|
|
5706
5756
|
selectionStart,
|
|
5707
5757
|
selectionEnd,
|
|
@@ -6160,22 +6210,39 @@ var PlaylistVisualization = ({
|
|
|
6160
6210
|
clip.clipId
|
|
6161
6211
|
);
|
|
6162
6212
|
}),
|
|
6163
|
-
(recordingState == null ? void 0 : recordingState.isRecording) && recordingState.trackId === track.id && ((_d2 = recordingState.peaks[0]) == null ? void 0 : _d2.length) > 0 &&
|
|
6164
|
-
|
|
6165
|
-
|
|
6166
|
-
|
|
6167
|
-
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6213
|
+
(recordingState == null ? void 0 : recordingState.isRecording) && recordingState.trackId === track.id && ((_d2 = recordingState.peaks[0]) == null ? void 0 : _d2.length) > 0 && (() => {
|
|
6214
|
+
const audioCtx = (0, import_playout6.getGlobalAudioContext)();
|
|
6215
|
+
const outputLatency = "outputLatency" in audioCtx ? audioCtx.outputLatency : 0;
|
|
6216
|
+
const lookAhead = getLookAhead();
|
|
6217
|
+
const latencyOffsetSamples = (0, import_core8.audibleLatencySamples)(
|
|
6218
|
+
outputLatency,
|
|
6219
|
+
lookAhead,
|
|
6220
|
+
sampleRate
|
|
6221
|
+
);
|
|
6222
|
+
const latencyPixels = Math.floor(latencyOffsetSamples / samplesPerPixel);
|
|
6223
|
+
const skipPeakElements = latencyPixels * 2;
|
|
6224
|
+
const previewDuration = Math.max(
|
|
6225
|
+
0,
|
|
6226
|
+
recordingState.durationSamples - latencyOffsetSamples
|
|
6227
|
+
);
|
|
6228
|
+
const previewChannels = (mono ? recordingState.peaks.slice(0, 1) : recordingState.peaks).map(
|
|
6229
|
+
(channelPeaks) => skipPeakElements > 0 && skipPeakElements < channelPeaks.length ? channelPeaks.subarray(skipPeakElements) : channelPeaks
|
|
6230
|
+
);
|
|
6231
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
6232
|
+
import_ui_components9.Clip,
|
|
6233
|
+
{
|
|
6234
|
+
clipId: "recording-preview",
|
|
6235
|
+
trackIndex,
|
|
6236
|
+
clipIndex: trackClipPeaks.length,
|
|
6237
|
+
trackName: "Recording...",
|
|
6238
|
+
startSample: recordingState.startSample,
|
|
6239
|
+
durationSamples: previewDuration,
|
|
6240
|
+
samplesPerPixel,
|
|
6241
|
+
showHeader: showClipHeaders,
|
|
6242
|
+
disableHeaderDrag: true,
|
|
6243
|
+
isSelected: track.id === selectedTrackId,
|
|
6244
|
+
trackId: track.id,
|
|
6245
|
+
children: previewChannels.map((channelPeaks, chIdx) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
6179
6246
|
ChannelWithProgress,
|
|
6180
6247
|
{
|
|
6181
6248
|
index: chIdx,
|
|
@@ -6184,14 +6251,14 @@ var PlaylistVisualization = ({
|
|
|
6184
6251
|
length: Math.floor(channelPeaks.length / 2),
|
|
6185
6252
|
isSelected: track.id === selectedTrackId,
|
|
6186
6253
|
clipStartSample: recordingState.startSample,
|
|
6187
|
-
clipDurationSamples:
|
|
6254
|
+
clipDurationSamples: previewDuration
|
|
6188
6255
|
},
|
|
6189
6256
|
`${track.id}-recording-${chIdx}`
|
|
6190
|
-
)
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
)
|
|
6257
|
+
))
|
|
6258
|
+
},
|
|
6259
|
+
`${track.id}-recording`
|
|
6260
|
+
);
|
|
6261
|
+
})()
|
|
6195
6262
|
]
|
|
6196
6263
|
},
|
|
6197
6264
|
track.id
|
|
@@ -7024,7 +7091,7 @@ var KeyboardShortcuts = ({
|
|
|
7024
7091
|
var import_react40 = __toESM(require("react"));
|
|
7025
7092
|
var import_react41 = require("@dnd-kit/react");
|
|
7026
7093
|
var import_modifiers2 = require("@dnd-kit/abstract/modifiers");
|
|
7027
|
-
var
|
|
7094
|
+
var import_core10 = require("@waveform-playlist/core");
|
|
7028
7095
|
var import_ui_components12 = require("@waveform-playlist/ui-components");
|
|
7029
7096
|
|
|
7030
7097
|
// src/modifiers/ClipCollisionModifier.ts
|
|
@@ -7053,7 +7120,7 @@ var ClipCollisionModifier = _ClipCollisionModifier;
|
|
|
7053
7120
|
|
|
7054
7121
|
// src/modifiers/SnapToGridModifier.ts
|
|
7055
7122
|
var import_abstract2 = require("@dnd-kit/abstract");
|
|
7056
|
-
var
|
|
7123
|
+
var import_core9 = require("@waveform-playlist/core");
|
|
7057
7124
|
var _SnapToGridModifier = class _SnapToGridModifier extends import_abstract2.Modifier {
|
|
7058
7125
|
apply(operation) {
|
|
7059
7126
|
const { transform, source } = operation;
|
|
@@ -7074,18 +7141,18 @@ var _SnapToGridModifier = class _SnapToGridModifier extends import_abstract2.Mod
|
|
|
7074
7141
|
}
|
|
7075
7142
|
const { snapTo, bpm, timeSignature, sampleRate } = this.options;
|
|
7076
7143
|
if (snapTo === "off") return transform;
|
|
7077
|
-
const gridTicks = snapTo === "bar" ? (0,
|
|
7144
|
+
const gridTicks = snapTo === "bar" ? (0, import_core9.ticksPerBar)(timeSignature) : (0, import_core9.ticksPerBeat)(timeSignature);
|
|
7078
7145
|
if (startSample !== void 0) {
|
|
7079
7146
|
const proposedSamples = startSample + transform.x * samplesPerPixel;
|
|
7080
|
-
const proposedTicks = (0,
|
|
7081
|
-
const snappedTicks2 = (0,
|
|
7082
|
-
const snappedSamples2 = (0,
|
|
7147
|
+
const proposedTicks = (0, import_core9.samplesToTicks)(proposedSamples, bpm, sampleRate);
|
|
7148
|
+
const snappedTicks2 = (0, import_core9.snapToGrid)(proposedTicks, gridTicks);
|
|
7149
|
+
const snappedSamples2 = (0, import_core9.ticksToSamples)(snappedTicks2, bpm, sampleRate);
|
|
7083
7150
|
return { x: (snappedSamples2 - startSample) / samplesPerPixel, y: 0 };
|
|
7084
7151
|
}
|
|
7085
7152
|
const deltaSamples = transform.x * samplesPerPixel;
|
|
7086
|
-
const deltaTicks = (0,
|
|
7087
|
-
const snappedTicks = (0,
|
|
7088
|
-
const snappedSamples = (0,
|
|
7153
|
+
const deltaTicks = (0, import_core9.samplesToTicks)(deltaSamples, bpm, sampleRate);
|
|
7154
|
+
const snappedTicks = (0, import_core9.snapToGrid)(deltaTicks, gridTicks);
|
|
7155
|
+
const snappedSamples = (0, import_core9.ticksToSamples)(snappedTicks, bpm, sampleRate);
|
|
7089
7156
|
return { x: snappedSamples / samplesPerPixel, y: 0 };
|
|
7090
7157
|
}
|
|
7091
7158
|
};
|
|
@@ -7116,11 +7183,11 @@ var ClipInteractionProvider = ({
|
|
|
7116
7183
|
const snapSamplePosition = (0, import_react40.useMemo)(() => {
|
|
7117
7184
|
if (useBeatsSnap && beatsAndBars) {
|
|
7118
7185
|
const { bpm, timeSignature, snapTo } = beatsAndBars;
|
|
7119
|
-
const gridTicks = snapTo === "bar" ? (0,
|
|
7186
|
+
const gridTicks = snapTo === "bar" ? (0, import_core10.ticksPerBar)(timeSignature) : (0, import_core10.ticksPerBeat)(timeSignature);
|
|
7120
7187
|
return (samplePos) => {
|
|
7121
|
-
const ticks = (0,
|
|
7122
|
-
const snapped = (0,
|
|
7123
|
-
return (0,
|
|
7188
|
+
const ticks = (0, import_core10.samplesToTicks)(samplePos, bpm, sampleRate);
|
|
7189
|
+
const snapped = (0, import_core10.snapToGrid)(ticks, gridTicks);
|
|
7190
|
+
return (0, import_core10.ticksToSamples)(snapped, bpm, sampleRate);
|
|
7124
7191
|
};
|
|
7125
7192
|
}
|
|
7126
7193
|
if (useTimescaleSnap) {
|