@opendaw/studio-adapters 0.0.110 → 0.0.112

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.
@@ -1,6 +1,25 @@
1
- import { bpm, ppqn, seconds, TempoMap } from "@opendaw/lib-dsp";
1
+ import { bpm, ppqn, seconds, TempoMap, ValueEvent } from "@opendaw/lib-dsp";
2
2
  import { Observer, Subscription, Terminable } from "@opendaw/lib-std";
3
3
  import { TimelineBoxAdapter } from "./timeline/TimelineBoxAdapter";
4
+ /**
5
+ * Allocation-free cursor that walks the TempoChangeGrid as a step function: tempo is constant within
6
+ * each grid cell and sampled at the cell's grid-aligned start (matching BlockRenderer). Tracks the
7
+ * current segment and the recurrence coefficients m, q so a step of exactly TempoChangeGrid within the
8
+ * same zone resolves as v = m * v + q. Because every cell is sampled at its grid origin, the walk is
9
+ * additive: integrate(a, c) === integrate(a, b) + integrate(b, c) for any b.
10
+ */
11
+ export declare class TempoGridCursor {
12
+ #private;
13
+ /**
14
+ * Integrates the seconds elapsed across [fromPPQN, toPPQN] by stepping the TempoChangeGrid.
15
+ */
16
+ integrate(events: ReadonlyArray<ValueEvent>, fromPPQN: ppqn, toPPQN: ppqn, storageBpm: bpm): seconds;
17
+ /**
18
+ * Walks the TempoChangeGrid forward from fromPPQN, accumulating seconds starting at fromSeconds,
19
+ * until targetSeconds is reached.
20
+ */
21
+ advance(events: ReadonlyArray<ValueEvent>, fromPPQN: ppqn, fromSeconds: seconds, targetSeconds: seconds, storageBpm: bpm): ppqn;
22
+ }
4
23
  /**
5
24
  * TempoMap implementation that handles varying tempo (tempo automation).
6
25
  * Steps through at TempoChangeGrid intervals to match BlockRenderer behavior.
@@ -1 +1 @@
1
- {"version":3,"file":"VaryingTempoMap.d.ts","sourceRoot":"","sources":["../src/VaryingTempoMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAE,IAAI,EAAQ,OAAO,EAAmB,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AACpF,OAAO,EAGH,QAAQ,EAER,YAAY,EACZ,UAAU,EAEb,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,kBAAkB,EAAC,MAAM,+BAA+B,CAAA;AAIhE;;;GAGG;AACH,qBAAa,eAAgB,YAAW,QAAQ,EAAE,UAAU;;gBAM5C,OAAO,EAAE,kBAAkB;IAQvC,SAAS,IAAI,IAAI;IAkCjB,UAAU,CAAC,QAAQ,EAAE,IAAI,GAAG,GAAG;IAQ/B,aAAa,CAAC,QAAQ,EAAE,IAAI,GAAG,OAAO;IAwCtC,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IA6ClC,iBAAiB,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,OAAO;IAIxD,cAAc,CAAC,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI;IAO9D,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,YAAY;CAQxD"}
1
+ {"version":3,"file":"VaryingTempoMap.d.ts","sourceRoot":"","sources":["../src/VaryingTempoMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAE,IAAI,EAAQ,OAAO,EAAmB,QAAQ,EAAE,UAAU,EAAC,MAAM,kBAAkB,CAAA;AAChG,OAAO,EAKH,QAAQ,EAGR,YAAY,EACZ,UAAU,EAEb,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,kBAAkB,EAAC,MAAM,+BAA+B,CAAA;AAIhE;;;;;;GAMG;AACH,qBAAa,eAAe;;IASxB;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,GAAG,OAAO;IAepG;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,EACjC,QAAQ,EAAE,IAAI,EACd,WAAW,EAAE,OAAO,EACpB,aAAa,EAAE,OAAO,EACtB,UAAU,EAAE,GAAG,GAAG,IAAI;CAuFjC;AAED;;;GAGG;AACH,qBAAa,eAAgB,YAAW,QAAQ,EAAE,UAAU;;gBAW5C,OAAO,EAAE,kBAAkB;IAQvC,SAAS,IAAI,IAAI;IA6BjB,UAAU,CAAC,QAAQ,EAAE,IAAI,GAAG,GAAG;IAQ/B,aAAa,CAAC,QAAQ,EAAE,IAAI,GAAG,OAAO;IA+BtC,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IA8BlC,iBAAiB,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,OAAO;IAqBxD,cAAc,CAAC,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI;IAO9D,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,YAAY;CAQxD"}
@@ -1,17 +1,156 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
1
6
  var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
7
  if (kind === "m") throw new TypeError("Private method is not writable");
3
8
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
10
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
11
  };
7
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
- };
12
- var _VaryingTempoMap_instances, _VaryingTempoMap_terminator, _VaryingTempoMap_adapter, _VaryingTempoMap_ppqnCache, _VaryingTempoMap_secondsCache, _VaryingTempoMap_rebuildCache, _VaryingTempoMap_ppqnToSecondsPositive, _VaryingTempoMap_absoluteSecondsToPPQN;
12
+ var _TempoGridCursor_instances, _TempoGridCursor_events, _TempoGridCursor_storageBpm, _TempoGridCursor_segmentIndex, _TempoGridCursor_lastPPQN, _TempoGridCursor_lastBpm, _TempoGridCursor_m, _TempoGridCursor_q, _TempoGridCursor_reset, _TempoGridCursor_bpmAt, _TempoGridCursor_zoneAt, _VaryingTempoMap_instances, _VaryingTempoMap_terminator, _VaryingTempoMap_adapter, _VaryingTempoMap_ppqnCache, _VaryingTempoMap_secondsCache, _VaryingTempoMap_cursor, _VaryingTempoMap_ivFrom, _VaryingTempoMap_ivTo, _VaryingTempoMap_ivSeconds, _VaryingTempoMap_rebuildCache, _VaryingTempoMap_ppqnToSecondsPositive, _VaryingTempoMap_absoluteSecondsToPPQN;
13
13
  import { PPQN, TempoChangeGrid } from "@opendaw/lib-dsp";
14
- import { BinarySearch, NumberComparator, quantizeCeil, Terminator } from "@opendaw/lib-std";
14
+ import { BinarySearch, Curve, NumberComparator, quantizeCeil, quantizeFloor, Terminator } from "@opendaw/lib-std";
15
+ /**
16
+ * Allocation-free cursor that walks the TempoChangeGrid as a step function: tempo is constant within
17
+ * each grid cell and sampled at the cell's grid-aligned start (matching BlockRenderer). Tracks the
18
+ * current segment and the recurrence coefficients m, q so a step of exactly TempoChangeGrid within the
19
+ * same zone resolves as v = m * v + q. Because every cell is sampled at its grid origin, the walk is
20
+ * additive: integrate(a, c) === integrate(a, b) + integrate(b, c) for any b.
21
+ */
22
+ export class TempoGridCursor {
23
+ constructor() {
24
+ _TempoGridCursor_instances.add(this);
25
+ _TempoGridCursor_events.set(this, []);
26
+ _TempoGridCursor_storageBpm.set(this, 0.0);
27
+ _TempoGridCursor_segmentIndex.set(this, -2);
28
+ _TempoGridCursor_lastPPQN.set(this, Number.NEGATIVE_INFINITY);
29
+ _TempoGridCursor_lastBpm.set(this, 0.0);
30
+ _TempoGridCursor_m.set(this, 1.0);
31
+ _TempoGridCursor_q.set(this, 0.0
32
+ /**
33
+ * Integrates the seconds elapsed across [fromPPQN, toPPQN] by stepping the TempoChangeGrid.
34
+ */
35
+ );
36
+ }
37
+ /**
38
+ * Integrates the seconds elapsed across [fromPPQN, toPPQN] by stepping the TempoChangeGrid.
39
+ */
40
+ integrate(events, fromPPQN, toPPQN, storageBpm) {
41
+ __classPrivateFieldGet(this, _TempoGridCursor_instances, "m", _TempoGridCursor_reset).call(this, events, storageBpm);
42
+ let acc = 0.0;
43
+ let current = fromPPQN;
44
+ while (current < toPPQN) {
45
+ const currentBpm = __classPrivateFieldGet(this, _TempoGridCursor_instances, "m", _TempoGridCursor_bpmAt).call(this, quantizeFloor(current, TempoChangeGrid));
46
+ const nextGrid = quantizeCeil(current, TempoChangeGrid);
47
+ const segmentEnd = nextGrid <= current ? nextGrid + TempoChangeGrid : nextGrid;
48
+ const actualEnd = Math.min(segmentEnd, toPPQN);
49
+ acc += PPQN.pulsesToSeconds(actualEnd - current, currentBpm);
50
+ current = actualEnd;
51
+ }
52
+ return acc;
53
+ }
54
+ /**
55
+ * Walks the TempoChangeGrid forward from fromPPQN, accumulating seconds starting at fromSeconds,
56
+ * until targetSeconds is reached.
57
+ */
58
+ advance(events, fromPPQN, fromSeconds, targetSeconds, storageBpm) {
59
+ __classPrivateFieldGet(this, _TempoGridCursor_instances, "m", _TempoGridCursor_reset).call(this, events, storageBpm);
60
+ let accumulatedSeconds = fromSeconds;
61
+ let accumulatedPPQN = fromPPQN;
62
+ while (accumulatedSeconds < targetSeconds) {
63
+ const currentBpm = __classPrivateFieldGet(this, _TempoGridCursor_instances, "m", _TempoGridCursor_bpmAt).call(this, quantizeFloor(accumulatedPPQN, TempoChangeGrid));
64
+ const nextGrid = quantizeCeil(accumulatedPPQN, TempoChangeGrid);
65
+ const segmentEnd = nextGrid <= accumulatedPPQN ? nextGrid + TempoChangeGrid : nextGrid;
66
+ const segmentPPQN = segmentEnd - accumulatedPPQN;
67
+ const segmentSeconds = PPQN.pulsesToSeconds(segmentPPQN, currentBpm);
68
+ if (accumulatedSeconds + segmentSeconds >= targetSeconds) {
69
+ accumulatedPPQN += PPQN.secondsToPulses(targetSeconds - accumulatedSeconds, currentBpm);
70
+ break;
71
+ }
72
+ accumulatedSeconds += segmentSeconds;
73
+ accumulatedPPQN = segmentEnd;
74
+ }
75
+ return accumulatedPPQN;
76
+ }
77
+ }
78
+ _TempoGridCursor_events = new WeakMap(), _TempoGridCursor_storageBpm = new WeakMap(), _TempoGridCursor_segmentIndex = new WeakMap(), _TempoGridCursor_lastPPQN = new WeakMap(), _TempoGridCursor_lastBpm = new WeakMap(), _TempoGridCursor_m = new WeakMap(), _TempoGridCursor_q = new WeakMap(), _TempoGridCursor_instances = new WeakSet(), _TempoGridCursor_reset = function _TempoGridCursor_reset(events, storageBpm) {
79
+ __classPrivateFieldSet(this, _TempoGridCursor_events, events, "f");
80
+ __classPrivateFieldSet(this, _TempoGridCursor_storageBpm, storageBpm, "f");
81
+ __classPrivateFieldSet(this, _TempoGridCursor_segmentIndex, -2, "f");
82
+ __classPrivateFieldSet(this, _TempoGridCursor_lastPPQN, Number.NEGATIVE_INFINITY, "f");
83
+ __classPrivateFieldSet(this, _TempoGridCursor_lastBpm, 0.0, "f");
84
+ __classPrivateFieldSet(this, _TempoGridCursor_m, 1.0, "f");
85
+ __classPrivateFieldSet(this, _TempoGridCursor_q, 0.0, "f");
86
+ }, _TempoGridCursor_bpmAt = function _TempoGridCursor_bpmAt(position) {
87
+ const events = __classPrivateFieldGet(this, _TempoGridCursor_events, "f");
88
+ if (events.length === 0) {
89
+ return __classPrivateFieldGet(this, _TempoGridCursor_storageBpm, "f");
90
+ }
91
+ const zone = __classPrivateFieldGet(this, _TempoGridCursor_instances, "m", _TempoGridCursor_zoneAt).call(this, position);
92
+ if (zone === __classPrivateFieldGet(this, _TempoGridCursor_segmentIndex, "f") && position === __classPrivateFieldGet(this, _TempoGridCursor_lastPPQN, "f") + TempoChangeGrid) {
93
+ __classPrivateFieldSet(this, _TempoGridCursor_lastPPQN, position, "f");
94
+ return __classPrivateFieldSet(this, _TempoGridCursor_lastBpm, __classPrivateFieldGet(this, _TempoGridCursor_m, "f") * __classPrivateFieldGet(this, _TempoGridCursor_lastBpm, "f") + __classPrivateFieldGet(this, _TempoGridCursor_q, "f"), "f");
95
+ }
96
+ __classPrivateFieldSet(this, _TempoGridCursor_segmentIndex, zone, "f");
97
+ __classPrivateFieldSet(this, _TempoGridCursor_lastPPQN, position, "f");
98
+ if (zone < 0) {
99
+ __classPrivateFieldSet(this, _TempoGridCursor_m, 1.0, "f");
100
+ __classPrivateFieldSet(this, _TempoGridCursor_q, 0.0, "f");
101
+ return __classPrivateFieldSet(this, _TempoGridCursor_lastBpm, zone === -1 ? events[0].value : events[events.length - 1].value, "f");
102
+ }
103
+ const a = events[zone];
104
+ const b = events[zone + 1];
105
+ const interpolation = a.interpolation;
106
+ if (interpolation.type === "none") {
107
+ __classPrivateFieldSet(this, _TempoGridCursor_m, 1.0, "f");
108
+ __classPrivateFieldSet(this, _TempoGridCursor_q, 0.0, "f");
109
+ return __classPrivateFieldSet(this, _TempoGridCursor_lastBpm, a.value, "f");
110
+ }
111
+ else if (interpolation.type === "linear") {
112
+ __classPrivateFieldSet(this, _TempoGridCursor_m, 1.0, "f");
113
+ __classPrivateFieldSet(this, _TempoGridCursor_q, (b.value - a.value) * TempoChangeGrid / (b.position - a.position), "f");
114
+ return __classPrivateFieldSet(this, _TempoGridCursor_lastBpm, a.value + (position - a.position) / (b.position - a.position) * (b.value - a.value), "f");
115
+ }
116
+ else {
117
+ const { m, q } = Curve.coefficients({
118
+ slope: interpolation.slope,
119
+ steps: (b.position - a.position) / TempoChangeGrid,
120
+ y0: a.value,
121
+ y1: b.value
122
+ });
123
+ __classPrivateFieldSet(this, _TempoGridCursor_m, m, "f");
124
+ __classPrivateFieldSet(this, _TempoGridCursor_q, q, "f");
125
+ return __classPrivateFieldSet(this, _TempoGridCursor_lastBpm, Curve.valueAt({
126
+ slope: interpolation.slope,
127
+ steps: b.position - a.position,
128
+ y0: a.value,
129
+ y1: b.value
130
+ }, position - a.position), "f");
131
+ }
132
+ }, _TempoGridCursor_zoneAt = function _TempoGridCursor_zoneAt(position) {
133
+ const events = __classPrivateFieldGet(this, _TempoGridCursor_events, "f");
134
+ if (position < events[0].position) {
135
+ return -1;
136
+ }
137
+ const last = events.length - 1;
138
+ if (position >= events[last].position) {
139
+ return -3;
140
+ }
141
+ let low = 0;
142
+ let high = last;
143
+ while (low < high) {
144
+ const mid = (low + high + 1) >> 1;
145
+ if (events[mid].position <= position) {
146
+ low = mid;
147
+ }
148
+ else {
149
+ high = mid - 1;
150
+ }
151
+ }
152
+ return low;
153
+ };
15
154
  /**
16
155
  * TempoMap implementation that handles varying tempo (tempo automation).
17
156
  * Steps through at TempoChangeGrid intervals to match BlockRenderer behavior.
@@ -23,6 +162,10 @@ export class VaryingTempoMap {
23
162
  _VaryingTempoMap_adapter.set(this, void 0);
24
163
  _VaryingTempoMap_ppqnCache.set(this, []);
25
164
  _VaryingTempoMap_secondsCache.set(this, []);
165
+ _VaryingTempoMap_cursor.set(this, new TempoGridCursor());
166
+ _VaryingTempoMap_ivFrom.set(this, Number.NaN);
167
+ _VaryingTempoMap_ivTo.set(this, 0.0);
168
+ _VaryingTempoMap_ivSeconds.set(this, 0.0);
26
169
  __classPrivateFieldSet(this, _VaryingTempoMap_adapter, adapter, "f");
27
170
  __classPrivateFieldGet(this, _VaryingTempoMap_terminator, "f").ownAll(adapter.box.bpm.subscribe(() => __classPrivateFieldGet(this, _VaryingTempoMap_instances, "m", _VaryingTempoMap_rebuildCache).call(this)), adapter.catchupAndSubscribeTempoAutomation(() => __classPrivateFieldGet(this, _VaryingTempoMap_instances, "m", _VaryingTempoMap_rebuildCache).call(this)));
28
171
  }
@@ -43,7 +186,28 @@ export class VaryingTempoMap {
43
186
  return __classPrivateFieldGet(this, _VaryingTempoMap_instances, "m", _VaryingTempoMap_absoluteSecondsToPPQN).call(this, time);
44
187
  }
45
188
  intervalToSeconds(fromPPQN, toPPQN) {
46
- return this.ppqnToSeconds(toPPQN) - this.ppqnToSeconds(fromPPQN);
189
+ if (fromPPQN < 0 || toPPQN < fromPPQN) {
190
+ return this.ppqnToSeconds(toPPQN) - this.ppqnToSeconds(fromPPQN);
191
+ }
192
+ const storageBpm = __classPrivateFieldGet(this, _VaryingTempoMap_adapter, "f").box.bpm.getValue();
193
+ const tempoEvents = __classPrivateFieldGet(this, _VaryingTempoMap_adapter, "f").tempoTrackEvents;
194
+ if (tempoEvents.isEmpty()) {
195
+ return PPQN.pulsesToSeconds(toPPQN - fromPPQN, storageBpm);
196
+ }
197
+ const collection = tempoEvents.unwrap();
198
+ if (collection.events.isEmpty()) {
199
+ return PPQN.pulsesToSeconds(toPPQN - fromPPQN, storageBpm);
200
+ }
201
+ const events = collection.events.asArray();
202
+ if (fromPPQN === __classPrivateFieldGet(this, _VaryingTempoMap_ivFrom, "f") && toPPQN >= __classPrivateFieldGet(this, _VaryingTempoMap_ivTo, "f")) {
203
+ __classPrivateFieldSet(this, _VaryingTempoMap_ivSeconds, __classPrivateFieldGet(this, _VaryingTempoMap_ivSeconds, "f") + __classPrivateFieldGet(this, _VaryingTempoMap_cursor, "f").integrate(events, __classPrivateFieldGet(this, _VaryingTempoMap_ivTo, "f"), toPPQN, storageBpm), "f");
204
+ __classPrivateFieldSet(this, _VaryingTempoMap_ivTo, toPPQN, "f");
205
+ return __classPrivateFieldGet(this, _VaryingTempoMap_ivSeconds, "f");
206
+ }
207
+ __classPrivateFieldSet(this, _VaryingTempoMap_ivFrom, fromPPQN, "f");
208
+ __classPrivateFieldSet(this, _VaryingTempoMap_ivTo, toPPQN, "f");
209
+ __classPrivateFieldSet(this, _VaryingTempoMap_ivSeconds, __classPrivateFieldGet(this, _VaryingTempoMap_cursor, "f").integrate(events, fromPPQN, toPPQN, storageBpm), "f");
210
+ return __classPrivateFieldGet(this, _VaryingTempoMap_ivSeconds, "f");
47
211
  }
48
212
  intervalToPPQN(fromSeconds, toSeconds) {
49
213
  if (fromSeconds >= toSeconds) {
@@ -59,9 +223,10 @@ export class VaryingTempoMap {
59
223
  return terminator;
60
224
  }
61
225
  }
62
- _VaryingTempoMap_terminator = new WeakMap(), _VaryingTempoMap_adapter = new WeakMap(), _VaryingTempoMap_ppqnCache = new WeakMap(), _VaryingTempoMap_secondsCache = new WeakMap(), _VaryingTempoMap_instances = new WeakSet(), _VaryingTempoMap_rebuildCache = function _VaryingTempoMap_rebuildCache() {
226
+ _VaryingTempoMap_terminator = new WeakMap(), _VaryingTempoMap_adapter = new WeakMap(), _VaryingTempoMap_ppqnCache = new WeakMap(), _VaryingTempoMap_secondsCache = new WeakMap(), _VaryingTempoMap_cursor = new WeakMap(), _VaryingTempoMap_ivFrom = new WeakMap(), _VaryingTempoMap_ivTo = new WeakMap(), _VaryingTempoMap_ivSeconds = new WeakMap(), _VaryingTempoMap_instances = new WeakSet(), _VaryingTempoMap_rebuildCache = function _VaryingTempoMap_rebuildCache() {
63
227
  __classPrivateFieldGet(this, _VaryingTempoMap_ppqnCache, "f").length = 0;
64
228
  __classPrivateFieldGet(this, _VaryingTempoMap_secondsCache, "f").length = 0;
229
+ __classPrivateFieldSet(this, _VaryingTempoMap_ivFrom, Number.NaN, "f");
65
230
  const tempoEvents = __classPrivateFieldGet(this, _VaryingTempoMap_adapter, "f").tempoTrackEvents;
66
231
  if (tempoEvents.isEmpty()) {
67
232
  return;
@@ -80,14 +245,8 @@ _VaryingTempoMap_terminator = new WeakMap(), _VaryingTempoMap_adapter = new Weak
80
245
  if (eventPosition <= currentPPQN) {
81
246
  continue;
82
247
  }
83
- while (currentPPQN < eventPosition) {
84
- const currentBpm = collection.valueAt(currentPPQN, storageBpm);
85
- const nextGrid = quantizeCeil(currentPPQN, TempoChangeGrid);
86
- const segmentEnd = nextGrid <= currentPPQN ? nextGrid + TempoChangeGrid : nextGrid;
87
- const actualEnd = Math.min(segmentEnd, eventPosition);
88
- accumulatedSeconds += PPQN.pulsesToSeconds(actualEnd - currentPPQN, currentBpm);
89
- currentPPQN = actualEnd;
90
- }
248
+ accumulatedSeconds += __classPrivateFieldGet(this, _VaryingTempoMap_cursor, "f").integrate(events, currentPPQN, eventPosition, storageBpm);
249
+ currentPPQN = eventPosition;
91
250
  entries.push({ ppqn: eventPosition, seconds: accumulatedSeconds, bpm: collection.valueAt(eventPosition, storageBpm) });
92
251
  }
93
252
  __classPrivateFieldGet(this, _VaryingTempoMap_ppqnCache, "f").push(...entries);
@@ -106,6 +265,7 @@ _VaryingTempoMap_terminator = new WeakMap(), _VaryingTempoMap_adapter = new Weak
106
265
  if (collection.events.isEmpty()) {
107
266
  return PPQN.pulsesToSeconds(position, storageBpm);
108
267
  }
268
+ const events = collection.events.asArray();
109
269
  let startPPQN = 0.0;
110
270
  let startSeconds = 0.0;
111
271
  if (__classPrivateFieldGet(this, _VaryingTempoMap_ppqnCache, "f").length > 0) {
@@ -119,17 +279,7 @@ _VaryingTempoMap_terminator = new WeakMap(), _VaryingTempoMap_adapter = new Weak
119
279
  }
120
280
  }
121
281
  }
122
- let accumulatedSeconds = startSeconds;
123
- let currentPPQN = startPPQN;
124
- while (currentPPQN < position) {
125
- const currentBpm = collection.valueAt(currentPPQN, storageBpm);
126
- const nextGrid = quantizeCeil(currentPPQN, TempoChangeGrid);
127
- const segmentEnd = nextGrid <= currentPPQN ? nextGrid + TempoChangeGrid : nextGrid;
128
- const actualEnd = Math.min(segmentEnd, position);
129
- accumulatedSeconds += PPQN.pulsesToSeconds(actualEnd - currentPPQN, currentBpm);
130
- currentPPQN = actualEnd;
131
- }
132
- return accumulatedSeconds;
282
+ return startSeconds + __classPrivateFieldGet(this, _VaryingTempoMap_cursor, "f").integrate(events, startPPQN, position, storageBpm);
133
283
  }, _VaryingTempoMap_absoluteSecondsToPPQN = function _VaryingTempoMap_absoluteSecondsToPPQN(targetSeconds) {
134
284
  if (targetSeconds <= 0) {
135
285
  return 0.0;
@@ -143,6 +293,7 @@ _VaryingTempoMap_terminator = new WeakMap(), _VaryingTempoMap_adapter = new Weak
143
293
  if (collection.events.isEmpty()) {
144
294
  return PPQN.secondsToPulses(targetSeconds, storageBpm);
145
295
  }
296
+ const events = collection.events.asArray();
146
297
  let startPPQN = 0.0;
147
298
  let startSeconds = 0.0;
148
299
  if (__classPrivateFieldGet(this, _VaryingTempoMap_secondsCache, "f").length > 0) {
@@ -156,21 +307,5 @@ _VaryingTempoMap_terminator = new WeakMap(), _VaryingTempoMap_adapter = new Weak
156
307
  }
157
308
  }
158
309
  }
159
- let accumulatedSeconds = startSeconds;
160
- let accumulatedPPQN = startPPQN;
161
- while (accumulatedSeconds < targetSeconds) {
162
- const currentBpm = collection.valueAt(accumulatedPPQN, storageBpm);
163
- const nextGrid = quantizeCeil(accumulatedPPQN, TempoChangeGrid);
164
- const segmentEnd = nextGrid <= accumulatedPPQN ? nextGrid + TempoChangeGrid : nextGrid;
165
- const segmentPPQN = segmentEnd - accumulatedPPQN;
166
- const segmentSeconds = PPQN.pulsesToSeconds(segmentPPQN, currentBpm);
167
- if (accumulatedSeconds + segmentSeconds >= targetSeconds) {
168
- const remainingSeconds = targetSeconds - accumulatedSeconds;
169
- accumulatedPPQN += PPQN.secondsToPulses(remainingSeconds, currentBpm);
170
- break;
171
- }
172
- accumulatedSeconds += segmentSeconds;
173
- accumulatedPPQN = segmentEnd;
174
- }
175
- return accumulatedPPQN;
310
+ return __classPrivateFieldGet(this, _VaryingTempoMap_cursor, "f").advance(events, startPPQN, startSeconds, targetSeconds, storageBpm);
176
311
  };
@@ -1 +1 @@
1
- {"version":3,"file":"AudioRegionBoxAdapter.d.ts","sourceRoot":"","sources":["../../../src/timeline/region/AudioRegionBoxAdapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AudioRegionBoxAdapter.d.ts","sourceRoot":"","sources":["../../../src/timeline/region/AudioRegionBoxAdapter.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _AudioRegionBoxAdapter_instances, _AudioRegionBoxAdapter_terminator, _AudioRegionBoxAdapter_context, _AudioRegionBoxAdapter_box, _AudioRegionBoxAdapter_durationConverter, _AudioRegionBoxAdapter_loopDurationConverter, _AudioRegionBoxAdapter_playMode, _AudioRegionBoxAdapter_changeNotifier, _AudioRegionBoxAdapter_fadingAdapter, _AudioRegionBoxAdapter_constructing, _AudioRegionBoxAdapter_fileAdapter, _AudioRegionBoxAdapter_fileSubscription, _AudioRegionBoxAdapter_playModeSubscription, _AudioRegionBoxAdapter_tempoSubscription, _AudioRegionBoxAdapter_eventCollectionSubscription, _AudioRegionBoxAdapter_isSelected, _AudioRegionBoxAdapter_dispatchChange;
12
+ var _AudioRegionBoxAdapter_instances, _AudioRegionBoxAdapter_terminator, _AudioRegionBoxAdapter_context, _AudioRegionBoxAdapter_box, _AudioRegionBoxAdapter_durationConverter, _AudioRegionBoxAdapter_loopDurationConverter, _AudioRegionBoxAdapter_playMode, _AudioRegionBoxAdapter_changeNotifier, _AudioRegionBoxAdapter_fadingAdapter, _AudioRegionBoxAdapter_constructing, _AudioRegionBoxAdapter_fileAdapter, _AudioRegionBoxAdapter_fileSubscription, _AudioRegionBoxAdapter_playModeSubscription, _AudioRegionBoxAdapter_tempoSubscription, _AudioRegionBoxAdapter_eventCollectionSubscription, _AudioRegionBoxAdapter_isSelected, _AudioRegionBoxAdapter_cachedDuration, _AudioRegionBoxAdapter_cachedLoopDuration, _AudioRegionBoxAdapter_dispatchChange;
13
13
  import { Arrays, asEnumValue, isInstanceOf, mod, MutableObservableOption, Notifier, Option, safeExecute, Terminable, Terminator, UUID } from "@opendaw/lib-std";
14
14
  import { TimeBase, TimeBaseConverter } from "@opendaw/lib-dsp";
15
15
  import { Propagation } from "@opendaw/lib-box";
@@ -40,6 +40,8 @@ export class AudioRegionBoxAdapter {
40
40
  _AudioRegionBoxAdapter_tempoSubscription.set(this, Terminable.Empty);
41
41
  _AudioRegionBoxAdapter_eventCollectionSubscription.set(this, Terminable.Empty);
42
42
  _AudioRegionBoxAdapter_isSelected.set(this, void 0);
43
+ _AudioRegionBoxAdapter_cachedDuration.set(this, Number.NaN);
44
+ _AudioRegionBoxAdapter_cachedLoopDuration.set(this, Number.NaN);
43
45
  __classPrivateFieldSet(this, _AudioRegionBoxAdapter_context, context, "f");
44
46
  __classPrivateFieldSet(this, _AudioRegionBoxAdapter_box, box, "f");
45
47
  __classPrivateFieldSet(this, _AudioRegionBoxAdapter_terminator, new Terminator(), "f");
@@ -116,10 +118,20 @@ export class AudioRegionBoxAdapter {
116
118
  get uuid() { return __classPrivateFieldGet(this, _AudioRegionBoxAdapter_box, "f").address.uuid; }
117
119
  get address() { return __classPrivateFieldGet(this, _AudioRegionBoxAdapter_box, "f").address; }
118
120
  get position() { return __classPrivateFieldGet(this, _AudioRegionBoxAdapter_box, "f").position.getValue(); }
119
- get duration() { return __classPrivateFieldGet(this, _AudioRegionBoxAdapter_durationConverter, "f").toPPQN(this.position); }
121
+ get duration() {
122
+ if (Number.isNaN(__classPrivateFieldGet(this, _AudioRegionBoxAdapter_cachedDuration, "f"))) {
123
+ __classPrivateFieldSet(this, _AudioRegionBoxAdapter_cachedDuration, __classPrivateFieldGet(this, _AudioRegionBoxAdapter_durationConverter, "f").toPPQN(this.position), "f");
124
+ }
125
+ return __classPrivateFieldGet(this, _AudioRegionBoxAdapter_cachedDuration, "f");
126
+ }
120
127
  get complete() { return this.position + this.duration; }
121
128
  get loopOffset() { return __classPrivateFieldGet(this, _AudioRegionBoxAdapter_box, "f").loopOffset.getValue(); }
122
- get loopDuration() { return __classPrivateFieldGet(this, _AudioRegionBoxAdapter_loopDurationConverter, "f").toPPQN(this.position); }
129
+ get loopDuration() {
130
+ if (Number.isNaN(__classPrivateFieldGet(this, _AudioRegionBoxAdapter_cachedLoopDuration, "f"))) {
131
+ __classPrivateFieldSet(this, _AudioRegionBoxAdapter_cachedLoopDuration, __classPrivateFieldGet(this, _AudioRegionBoxAdapter_loopDurationConverter, "f").toPPQN(this.position), "f");
132
+ }
133
+ return __classPrivateFieldGet(this, _AudioRegionBoxAdapter_cachedLoopDuration, "f");
134
+ }
123
135
  isNoteRegion() { return false; }
124
136
  isAudioRegion() { return true; }
125
137
  isValueRegion() { return false; }
@@ -248,7 +260,9 @@ export class AudioRegionBoxAdapter {
248
260
  }
249
261
  toString() { return `{AudioRegionBoxAdapter ${UUID.toString(__classPrivateFieldGet(this, _AudioRegionBoxAdapter_box, "f").address.uuid)}}`; }
250
262
  }
251
- _AudioRegionBoxAdapter_terminator = new WeakMap(), _AudioRegionBoxAdapter_context = new WeakMap(), _AudioRegionBoxAdapter_box = new WeakMap(), _AudioRegionBoxAdapter_durationConverter = new WeakMap(), _AudioRegionBoxAdapter_loopDurationConverter = new WeakMap(), _AudioRegionBoxAdapter_playMode = new WeakMap(), _AudioRegionBoxAdapter_changeNotifier = new WeakMap(), _AudioRegionBoxAdapter_fadingAdapter = new WeakMap(), _AudioRegionBoxAdapter_constructing = new WeakMap(), _AudioRegionBoxAdapter_fileAdapter = new WeakMap(), _AudioRegionBoxAdapter_fileSubscription = new WeakMap(), _AudioRegionBoxAdapter_playModeSubscription = new WeakMap(), _AudioRegionBoxAdapter_tempoSubscription = new WeakMap(), _AudioRegionBoxAdapter_eventCollectionSubscription = new WeakMap(), _AudioRegionBoxAdapter_isSelected = new WeakMap(), _AudioRegionBoxAdapter_instances = new WeakSet(), _AudioRegionBoxAdapter_dispatchChange = function _AudioRegionBoxAdapter_dispatchChange() {
263
+ _AudioRegionBoxAdapter_terminator = new WeakMap(), _AudioRegionBoxAdapter_context = new WeakMap(), _AudioRegionBoxAdapter_box = new WeakMap(), _AudioRegionBoxAdapter_durationConverter = new WeakMap(), _AudioRegionBoxAdapter_loopDurationConverter = new WeakMap(), _AudioRegionBoxAdapter_playMode = new WeakMap(), _AudioRegionBoxAdapter_changeNotifier = new WeakMap(), _AudioRegionBoxAdapter_fadingAdapter = new WeakMap(), _AudioRegionBoxAdapter_constructing = new WeakMap(), _AudioRegionBoxAdapter_fileAdapter = new WeakMap(), _AudioRegionBoxAdapter_fileSubscription = new WeakMap(), _AudioRegionBoxAdapter_playModeSubscription = new WeakMap(), _AudioRegionBoxAdapter_tempoSubscription = new WeakMap(), _AudioRegionBoxAdapter_eventCollectionSubscription = new WeakMap(), _AudioRegionBoxAdapter_isSelected = new WeakMap(), _AudioRegionBoxAdapter_cachedDuration = new WeakMap(), _AudioRegionBoxAdapter_cachedLoopDuration = new WeakMap(), _AudioRegionBoxAdapter_instances = new WeakSet(), _AudioRegionBoxAdapter_dispatchChange = function _AudioRegionBoxAdapter_dispatchChange() {
264
+ __classPrivateFieldSet(this, _AudioRegionBoxAdapter_cachedDuration, Number.NaN, "f");
265
+ __classPrivateFieldSet(this, _AudioRegionBoxAdapter_cachedLoopDuration, Number.NaN, "f");
252
266
  if (__classPrivateFieldGet(this, _AudioRegionBoxAdapter_constructing, "f")) {
253
267
  return;
254
268
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opendaw/studio-adapters",
3
- "version": "0.0.110",
3
+ "version": "0.0.112",
4
4
  "license": "LGPL-3.0-or-later",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -36,5 +36,5 @@
36
36
  "@opendaw/eslint-config": "^0.0.28",
37
37
  "@opendaw/typescript-config": "^0.0.32"
38
38
  },
39
- "gitHead": "b507627ec60d6992ccbddfb8acc580cea71918d6"
39
+ "gitHead": "ebbc65ad5e1e4553b662913c895afb35210c2ea1"
40
40
  }