@opendaw/studio-core 0.0.84 → 0.0.85
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/EffectFactories.d.ts +0 -2
- package/dist/EffectFactories.d.ts.map +1 -1
- package/dist/EffectFactories.js +1 -1
- package/dist/Engine.d.ts +2 -1
- package/dist/Engine.d.ts.map +1 -1
- package/dist/EngineFacade.d.ts +2 -1
- package/dist/EngineFacade.d.ts.map +1 -1
- package/dist/EngineFacade.js +3 -1
- package/dist/EngineWorklet.d.ts +2 -1
- package/dist/EngineWorklet.d.ts.map +1 -1
- package/dist/EngineWorklet.js +5 -2
- package/dist/Preferences.d.ts +2 -0
- package/dist/Preferences.d.ts.map +1 -1
- package/dist/Preferences.js +1 -0
- package/dist/Storage.d.ts.map +1 -1
- package/dist/Storage.js +14 -5
- package/dist/capture/Capture.d.ts +4 -1
- package/dist/capture/Capture.d.ts.map +1 -1
- package/dist/capture/Capture.js +4 -0
- package/dist/capture/RecordAudio.d.ts.map +1 -1
- package/dist/capture/RecordAudio.js +4 -2
- package/dist/capture/RecordMidi.d.ts.map +1 -1
- package/dist/capture/RecordMidi.js +1 -0
- package/dist/capture/Recording.d.ts.map +1 -1
- package/dist/capture/Recording.js +1 -0
- package/dist/midi/MIDILearning.d.ts.map +1 -1
- package/dist/midi/MIDILearning.js +0 -1
- package/dist/processors.js +14 -14
- package/dist/processors.js.map +4 -4
- package/dist/project/Project.d.ts +2 -2
- package/dist/project/Project.d.ts.map +1 -1
- package/dist/project/Project.js +15 -9
- package/dist/project/ProjectApi.js +2 -2
- package/dist/project/ProjectBundle.d.ts.map +1 -1
- package/dist/project/ProjectBundle.js +4 -3
- package/dist/project/ProjectMigration.d.ts.map +1 -1
- package/dist/project/ProjectMigration.js +16 -1
- package/dist/project/audio/AudioContentModifier.d.ts.map +1 -1
- package/dist/project/audio/AudioContentModifier.js +15 -2
- package/dist/samples/DefaultSampleLoader.d.ts.map +1 -1
- package/dist/samples/DefaultSampleLoader.js +8 -4
- package/dist/samples/DefaultSampleLoaderManager.js +1 -1
- package/dist/soundfont/DefaultSoundfontLoader.d.ts.map +1 -1
- package/dist/soundfont/DefaultSoundfontLoader.js +8 -4
- package/dist/ui/RegionClipResolver.d.ts.map +1 -1
- package/dist/ui/RegionClipResolver.js +15 -6
- package/dist/ui/RegionModifyStrategies.js +3 -3
- package/dist/ui/TimeGrid.d.ts +2 -1
- package/dist/ui/TimeGrid.d.ts.map +1 -1
- package/dist/ui/TimeGrid.js +28 -14
- package/dist/workers-main.js +1 -1
- package/dist/workers-main.js.map +3 -3
- package/package.json +16 -16
|
@@ -10,7 +10,7 @@ import { CaptureDevices } from "../capture";
|
|
|
10
10
|
import { EngineFacade } from "../EngineFacade";
|
|
11
11
|
import { EngineWorklet } from "../EngineWorklet";
|
|
12
12
|
import { MIDILearning } from "../midi";
|
|
13
|
-
import {
|
|
13
|
+
import { TempoMap } from "@opendaw/lib-dsp";
|
|
14
14
|
export type RestartWorklet = {
|
|
15
15
|
unload: Func<unknown, Promise<unknown>>;
|
|
16
16
|
load: Procedure<EngineWorklet>;
|
|
@@ -58,10 +58,10 @@ export declare class Project implements BoxAdaptersContext, Terminable, Terminab
|
|
|
58
58
|
get isAudioContext(): boolean;
|
|
59
59
|
get isMainThread(): boolean;
|
|
60
60
|
get liveStreamBroadcaster(): LiveStreamBroadcaster;
|
|
61
|
-
get signatureDuration(): ppqn;
|
|
62
61
|
get skeleton(): ProjectSkeleton;
|
|
63
62
|
receivedMIDIFromEngine(midiDeviceId: string, data: Uint8Array, relativeTimeInMs: number): void;
|
|
64
63
|
collectSampleUUIDs(): ReadonlyArray<UUID.Bytes>;
|
|
64
|
+
restartRecording(): void;
|
|
65
65
|
toArrayBuffer(): ArrayBufferLike;
|
|
66
66
|
copy(env?: Partial<ProjectEnv>): Project;
|
|
67
67
|
invalid(): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Project.d.ts","sourceRoot":"","sources":["../../src/project/Project.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,IAAI,EAEJ,SAAS,EAET,UAAU,EACV,eAAe,EACf,UAAU,EACV,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AACrD,OAAO,EACH,WAAW,EAGX,YAAY,EACZ,KAAK,EAEL,OAAO,EACP,WAAW,EAEX,gBAAgB,EACnB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACH,WAAW,EACX,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,gBAAgB,EAEhB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAElB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"Project.d.ts","sourceRoot":"","sources":["../../src/project/Project.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,IAAI,EAEJ,SAAS,EAET,UAAU,EACV,eAAe,EACf,UAAU,EACV,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,UAAU,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AACrD,OAAO,EACH,WAAW,EAGX,YAAY,EACZ,KAAK,EAEL,OAAO,EACP,WAAW,EAEX,gBAAgB,EACnB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACH,WAAW,EACX,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,gBAAgB,EAEhB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAElB,kBAAkB,EAElB,eAAe,EAClB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,qBAAqB,EAAE,kBAAkB,EAAC,MAAM,qBAAqB,CAAA;AAC7E,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AACvC,OAAO,EAAC,KAAK,EAAC,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AAEvC,OAAO,EAAC,cAAc,EAAY,MAAM,YAAY,CAAA;AACpD,OAAO,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAc,YAAY,EAAC,MAAM,SAAS,CAAA;AAGjD,OAAO,EAAC,QAAQ,EAAW,MAAM,kBAAkB,CAAA;AAGnD,MAAM,MAAM,cAAc,GAAG;IAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC,aAAa,CAAC,CAAA;CAAE,CAAA;AAExG,MAAM,MAAM,oBAAoB,GAAG;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAA;CAC1B,CAAA;AAGD,qBAAa,OAAQ,YAAW,kBAAkB,EAAE,UAAU,EAAE,eAAe;;IAC3E,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO;IAYpE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO;WAIlD,cAAc,CAAC,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAOxF,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,GAAE,OAAc,GAAG,OAAO;IAUzG,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAE1C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,kBAAkB,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAA;IAC5D,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAA;IAClC,QAAQ,CAAC,eAAe,EAAE,YAAY,CAAA;IACtC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IAEjC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAA;IACxB,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAA;IACvC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAA;IACnC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAA;IAC/C,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB,CAAA;IACvD,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAA;IAC/C,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAA;IACnC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,MAAM,eAAqB;IAEpC,OAAO;IAmCP,iBAAiB,CAAC,OAAO,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,aAAa;IAoBtF,cAAc,CAAC,OAAO,GAAE,OAAc;IAMtC,MAAM,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI;IAMnC,GAAG,CAAC,CAAC,SAAS,UAAU,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC;IAC3C,MAAM,CAAC,CAAC,SAAS,UAAU,EAAE,GAAG,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI;IAC5D,KAAK,IAAI,UAAU;IAEnB,IAAI,GAAG,IAAI,UAAU,CAAmB;IACxC,IAAI,cAAc,IAAI,cAAc,CAAmE;IACvG,IAAI,kBAAkB,IAAI,kBAAkB,CAA2E;IACvH,IAAI,aAAa,IAAI,mBAAmB,CAAiC;IACzE,IAAI,gBAAgB,IAAI,sBAAsB,CAAoC;IAClF,IAAI,cAAc,IAAI,cAAc,CAAkD;IACtF,IAAI,cAAc,IAAI,OAAO,CAAe;IAC5C,IAAI,YAAY,IAAI,OAAO,CAAc;IACzC,IAAI,qBAAqB,IAAI,qBAAqB,CAAkD;IAEpG,IAAI,QAAQ,IAAI,eAAe,CAW9B;IAED,sBAAsB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI;IAe9F,kBAAkB,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;IAM/C,gBAAgB,IAAI,IAAI;IAaxB,aAAa,IAAI,eAAe;IAEhC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO;IAIxC,OAAO,IAAI,OAAO;IAmBlB,SAAS,IAAI,IAAI;CAIpB"}
|
package/dist/project/Project.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Arrays, panic, safeExecute, Terminator } from "@opendaw/lib-std";
|
|
2
2
|
import { BoxEditing } from "@opendaw/lib-box";
|
|
3
3
|
import { AudioRegionBox } from "@opendaw/studio-boxes";
|
|
4
|
-
import { BoxAdapters, ParameterFieldAdapters, ProjectSkeleton, RootBoxAdapter, TimelineBoxAdapter, UnionBoxTypes, UserEditingManager, VertexSelection } from "@opendaw/studio-adapters";
|
|
4
|
+
import { BoxAdapters, ParameterFieldAdapters, ProjectSkeleton, RootBoxAdapter, TimelineBoxAdapter, UnionBoxTypes, UserEditingManager, VaryingTempoMap, VertexSelection } from "@opendaw/studio-adapters";
|
|
5
5
|
import { LiveStreamReceiver } from "@opendaw/lib-fusion";
|
|
6
6
|
import { Mixer } from "../Mixer";
|
|
7
7
|
import { ProjectApi } from "./ProjectApi";
|
|
@@ -11,7 +11,7 @@ import { EngineFacade } from "../EngineFacade";
|
|
|
11
11
|
import { MidiDevices, MIDILearning } from "../midi";
|
|
12
12
|
import { ProjectValidation } from "./ProjectValidation";
|
|
13
13
|
import { Preferences } from "../Preferences";
|
|
14
|
-
import {
|
|
14
|
+
import { TimeBase } from "@opendaw/lib-dsp";
|
|
15
15
|
import { MidiData } from "@opendaw/lib-midi";
|
|
16
16
|
// Main Entry Point for a Project
|
|
17
17
|
export class Project {
|
|
@@ -77,8 +77,8 @@ export class Project {
|
|
|
77
77
|
this.editing = new BoxEditing(this.boxGraph);
|
|
78
78
|
this.selection = new VertexSelection(this.editing, this.boxGraph);
|
|
79
79
|
this.parameterFieldAdapters = new ParameterFieldAdapters();
|
|
80
|
-
this.tempoMap = new ConstantTempoMap(this.timelineBox.bpm);
|
|
81
80
|
this.boxAdapters = this.#terminator.own(new BoxAdapters(this));
|
|
81
|
+
this.tempoMap = new VaryingTempoMap(this.timelineBoxAdapter);
|
|
82
82
|
this.userEditingManager = new UserEditingManager(this.editing);
|
|
83
83
|
this.liveStreamReceiver = this.#terminator.own(new LiveStreamReceiver());
|
|
84
84
|
this.midiLearning = this.#terminator.own(new MIDILearning(this));
|
|
@@ -133,10 +133,6 @@ export class Project {
|
|
|
133
133
|
get isAudioContext() { return false; }
|
|
134
134
|
get isMainThread() { return true; }
|
|
135
135
|
get liveStreamBroadcaster() { return panic("Only available in audio context"); }
|
|
136
|
-
get signatureDuration() {
|
|
137
|
-
const { nominator, denominator } = this.timelineBox.signature;
|
|
138
|
-
return PPQN.fromSignature(nominator.getValue(), denominator.getValue());
|
|
139
|
-
}
|
|
140
136
|
get skeleton() {
|
|
141
137
|
return {
|
|
142
138
|
boxGraph: this.boxGraph,
|
|
@@ -169,9 +165,19 @@ export class Project {
|
|
|
169
165
|
.filter(box => box.accept({ visitAudioFileBox: (_box) => true }))
|
|
170
166
|
.map(box => box.address.uuid);
|
|
171
167
|
}
|
|
172
|
-
|
|
173
|
-
|
|
168
|
+
restartRecording() {
|
|
169
|
+
if (this.engine.isRecording.getValue()) {
|
|
170
|
+
this.engine.stopRecording();
|
|
171
|
+
this.editing.modify(() => this.captureDevices.filterArmed()
|
|
172
|
+
.forEach(capture => {
|
|
173
|
+
capture.recordedRegions().forEach(region => region.box.delete());
|
|
174
|
+
capture.clearRecordedRegions();
|
|
175
|
+
}), false);
|
|
176
|
+
this.engine.stop(true);
|
|
177
|
+
setTimeout(() => this.startRecording(true), 100);
|
|
178
|
+
}
|
|
174
179
|
}
|
|
180
|
+
toArrayBuffer() { return ProjectSkeleton.encode(this.boxGraph); }
|
|
175
181
|
copy(env) {
|
|
176
182
|
return Project.load({ ...this.#env, ...env }, this.toArrayBuffer());
|
|
177
183
|
}
|
|
@@ -176,7 +176,7 @@ export class ProjectApi {
|
|
|
176
176
|
box.hue.setValue(hue ?? ColorCodes.forTrackType(type));
|
|
177
177
|
box.mute.setValue(false);
|
|
178
178
|
box.duration.setValue(duration);
|
|
179
|
-
box.loopDuration.setValue(
|
|
179
|
+
box.loopDuration.setValue(duration);
|
|
180
180
|
box.events.refer(events.owners);
|
|
181
181
|
box.regions.refer(trackBox.regions);
|
|
182
182
|
}));
|
|
@@ -189,7 +189,7 @@ export class ProjectApi {
|
|
|
189
189
|
box.hue.setValue(hue ?? ColorCodes.forTrackType(type));
|
|
190
190
|
box.mute.setValue(false);
|
|
191
191
|
box.duration.setValue(duration);
|
|
192
|
-
box.loopDuration.setValue(
|
|
192
|
+
box.loopDuration.setValue(duration);
|
|
193
193
|
box.events.refer(events.owners);
|
|
194
194
|
box.regions.refer(trackBox.regions);
|
|
195
195
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectBundle.d.ts","sourceRoot":"","sources":["../../src/project/ProjectBundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,QAAQ,EAAmB,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAI3G,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AAEvC,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAA;AAO/C,yBAAiB,aAAa,CAAC;IACpB,MAAM,MAAM,GAAU,gCAA8B,cAAc,EAC5C,UAAU,QAAQ,CAAC,OAAO,KAAG,OAAO,CAAC,WAAW,CA2C5E,CAAA;IAEM,MAAM,MAAM,GAAU,KAAK,UAAU,EACf,aAAa,WAAW,EACxB,kBAAkB,IAAI,CAAC,KAAK,KAAG,OAAO,CAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"ProjectBundle.d.ts","sourceRoot":"","sources":["../../src/project/ProjectBundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4C,QAAQ,EAAmB,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAI3G,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AAEvC,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAA;AAO/C,yBAAiB,aAAa,CAAC;IACpB,MAAM,MAAM,GAAU,gCAA8B,cAAc,EAC5C,UAAU,QAAQ,CAAC,OAAO,KAAG,OAAO,CAAC,WAAW,CA2C5E,CAAA;IAEM,MAAM,MAAM,GAAU,KAAK,UAAU,EACf,aAAa,WAAW,EACxB,kBAAkB,IAAI,CAAC,KAAK,KAAG,OAAO,CAAC,cAAc,CA6CjF,CAAA;CAgDJ"}
|
|
@@ -94,7 +94,8 @@ export var ProjectBundle;
|
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
await Promise.all(promises);
|
|
97
|
-
const
|
|
97
|
+
const projectData = await asDefined(zip.file(ProjectPaths.ProjectFile)).async("arraybuffer");
|
|
98
|
+
const project = await Project.loadAnyVersion(env, projectData);
|
|
98
99
|
const meta = JSON.parse(await asDefined(zip.file(ProjectPaths.ProjectMetaFile)).async("text"));
|
|
99
100
|
const coverFile = zip.file(ProjectPaths.ProjectCoverFile);
|
|
100
101
|
const cover = Option.wrap(await coverFile?.async("arraybuffer"));
|
|
@@ -118,7 +119,7 @@ export var ProjectBundle;
|
|
|
118
119
|
subscription.terminate();
|
|
119
120
|
}
|
|
120
121
|
else if (state.type === "error") {
|
|
121
|
-
reject(state.reason);
|
|
122
|
+
reject(new Error(state.reason));
|
|
122
123
|
subscription.terminate();
|
|
123
124
|
}
|
|
124
125
|
});
|
|
@@ -142,7 +143,7 @@ export var ProjectBundle;
|
|
|
142
143
|
subscription.terminate();
|
|
143
144
|
}
|
|
144
145
|
else if (state.type === "error") {
|
|
145
|
-
reject(state.reason);
|
|
146
|
+
reject(new Error(state.reason));
|
|
146
147
|
subscription.terminate();
|
|
147
148
|
}
|
|
148
149
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectMigration.d.ts","sourceRoot":"","sources":["../../src/project/ProjectMigration.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProjectMigration.d.ts","sourceRoot":"","sources":["../../src/project/ProjectMigration.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAA;AAIxD,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AASvC,qBAAa,gBAAgB;WACZ,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,EAAC,QAAQ,EAAE,cAAc,EAAC,EAAE,eAAe;CAuPpF"}
|
|
@@ -34,11 +34,18 @@ export class ProjectMigration {
|
|
|
34
34
|
}
|
|
35
35
|
else if (state.type === "error") {
|
|
36
36
|
queueMicrotask(() => subscription.terminate());
|
|
37
|
-
reject(state.reason);
|
|
37
|
+
reject(new Error(state.reason));
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
return promise;
|
|
41
41
|
};
|
|
42
|
+
const orphans = boxGraph.findOrphans(rootBox);
|
|
43
|
+
if (orphans.length > 0) {
|
|
44
|
+
console.debug("Migrate remove orphaned boxes: ", orphans.length);
|
|
45
|
+
boxGraph.beginTransaction();
|
|
46
|
+
orphans.forEach(orphan => orphan.delete());
|
|
47
|
+
boxGraph.endTransaction();
|
|
48
|
+
}
|
|
42
49
|
// 1st pass (2nd pass might rely on those changes)
|
|
43
50
|
for (const box of boxGraph.boxes()) {
|
|
44
51
|
await box.accept({
|
|
@@ -131,6 +138,14 @@ export class ProjectMigration {
|
|
|
131
138
|
boxGraph.endTransaction();
|
|
132
139
|
}
|
|
133
140
|
},
|
|
141
|
+
visitTimelineBox: (timelineBox) => {
|
|
142
|
+
if (timelineBox.tempoTrack.events.isEmpty()) {
|
|
143
|
+
console.debug("Migrate 'TimelineBox' to have a ValueEventCollectionBox for tempo events");
|
|
144
|
+
boxGraph.beginTransaction();
|
|
145
|
+
ValueEventCollectionBox.create(boxGraph, UUID.generate(), box => timelineBox.tempoTrack.events.refer(box.owners));
|
|
146
|
+
boxGraph.endTransaction();
|
|
147
|
+
}
|
|
148
|
+
},
|
|
134
149
|
visitMIDIOutputDeviceBox: (deviceBox) => {
|
|
135
150
|
const id = deviceBox.deprecatedDevice.id.getValue();
|
|
136
151
|
const label = deviceBox.deprecatedDevice.label.getValue();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioContentModifier.d.ts","sourceRoot":"","sources":["../../../src/project/audio/AudioContentModifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,IAAI,EAAgC,MAAM,kBAAkB,CAAA;AAS/E,OAAO,EAAC,sBAAsB,EAAwB,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"AudioContentModifier.d.ts","sourceRoot":"","sources":["../../../src/project/audio/AudioContentModifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,IAAI,EAAgC,MAAM,kBAAkB,CAAA;AAS/E,OAAO,EAAC,sBAAsB,EAAwB,MAAM,0BAA0B,CAAA;AAKtF,yBAAiB,oBAAoB,CAAC;IAC3B,MAAM,cAAc,GAAU,UAAU,aAAa,CAAC,sBAAsB,CAAC,KAAG,OAAO,CAAC,IAAI,CAalG,CAAA;IAEM,MAAM,cAAc,GAAU,UAAU,aAAa,CAAC,sBAAsB,CAAC,KAAG,OAAO,CAAC,IAAI,CA4BlG,CAAA;IAEM,MAAM,aAAa,GAAU,UAAU,aAAa,CAAC,sBAAsB,CAAC,KAAG,OAAO,CAAC,IAAI,CA4CjG,CAAA;CA2BJ"}
|
|
@@ -4,6 +4,7 @@ import { AudioPitchStretchBox, AudioTimeStretchBox, TransientMarkerBox, WarpMark
|
|
|
4
4
|
import { AudioRegionBoxAdapter } from "@opendaw/studio-adapters";
|
|
5
5
|
import { AudioContentHelpers } from "./AudioContentHelpers";
|
|
6
6
|
import { Workers } from "../../Workers";
|
|
7
|
+
import { Pointers } from "@opendaw/studio-enums";
|
|
7
8
|
export var AudioContentModifier;
|
|
8
9
|
(function (AudioContentModifier) {
|
|
9
10
|
AudioContentModifier.toNotStretched = async (adapters) => {
|
|
@@ -13,6 +14,16 @@ export var AudioContentModifier;
|
|
|
13
14
|
}
|
|
14
15
|
return () => audioAdapters.forEach((adapter) => {
|
|
15
16
|
adapter.box.playMode.defer();
|
|
17
|
+
adapter.asPlayModeTimeStretch.ifSome(({ box }) => {
|
|
18
|
+
if (box.pointerHub.filter(Pointers.AudioPlayMode).length === 0) {
|
|
19
|
+
box.delete();
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
adapter.asPlayModePitchStretch.ifSome(({ box }) => {
|
|
23
|
+
if (box.pointerHub.filter(Pointers.AudioPlayMode).length === 0) {
|
|
24
|
+
box.delete();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
16
27
|
switchTimeBaseToSeconds(adapter);
|
|
17
28
|
});
|
|
18
29
|
};
|
|
@@ -28,7 +39,8 @@ export var AudioContentModifier;
|
|
|
28
39
|
adapter.box.playMode.refer(pitchStretch);
|
|
29
40
|
if (optTimeStretch.nonEmpty()) {
|
|
30
41
|
const timeStretch = optTimeStretch.unwrap();
|
|
31
|
-
|
|
42
|
+
const numPointers = timeStretch.box.pointerHub.filter(Pointers.AudioPlayMode).length;
|
|
43
|
+
if (numPointers === 0) {
|
|
32
44
|
timeStretch.warpMarkers.asArray()
|
|
33
45
|
.forEach(({ box: { owner } }) => owner.refer(pitchStretch.warpMarkers));
|
|
34
46
|
timeStretch.box.delete();
|
|
@@ -69,7 +81,8 @@ export var AudioContentModifier;
|
|
|
69
81
|
adapter.box.playMode.refer(timeStretch);
|
|
70
82
|
if (optPitchStretch.nonEmpty()) {
|
|
71
83
|
const pitchStretch = optPitchStretch.unwrap();
|
|
72
|
-
|
|
84
|
+
const numPointers = pitchStretch.box.pointerHub.filter(Pointers.AudioPlayMode).length;
|
|
85
|
+
if (numPointers === 0) {
|
|
73
86
|
pitchStretch.warpMarkers.asArray()
|
|
74
87
|
.forEach(({ box: { owner } }) => owner.refer(timeStretch.warpMarkers));
|
|
75
88
|
pitchStretch.box.delete();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultSampleLoader.d.ts","sourceRoot":"","sources":["../../src/samples/DefaultSampleLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,QAAQ,EACR,MAAM,EAEN,YAAY,EAEZ,IAAI,EACP,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAC,KAAK,EAAc,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAC,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAC,MAAM,0BAA0B,CAAA;AAExF,OAAO,EAAC,0BAA0B,EAAC,MAAM,8BAA8B,CAAA;AAEvE,OAAO,EAAC,SAAS,EAAC,MAAM,kBAAkB,CAAA;AAE1C,qBAAa,mBAAoB,YAAW,YAAY;;gBAYxC,OAAO,EAAE,0BAA0B,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK;IAQjE,UAAU,IAAI,IAAI;IASlB,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,YAAY;IAQ9D,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,CAAoB;IAC1C,IAAI,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,CAAoB;IACjD,IAAI,IAAI,IAAI,MAAM,CAAC,cAAc,CAAC,CAAoB;IACtD,IAAI,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAqB;IAC/C,IAAI,KAAK,IAAI,iBAAiB,CAAqB;IAEnD,QAAQ,IAAI,MAAM;
|
|
1
|
+
{"version":3,"file":"DefaultSampleLoader.d.ts","sourceRoot":"","sources":["../../src/samples/DefaultSampleLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,QAAQ,EACR,MAAM,EAEN,YAAY,EAEZ,IAAI,EACP,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAC,KAAK,EAAc,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAC,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAC,MAAM,0BAA0B,CAAA;AAExF,OAAO,EAAC,0BAA0B,EAAC,MAAM,8BAA8B,CAAA;AAEvE,OAAO,EAAC,SAAS,EAAC,MAAM,kBAAkB,CAAA;AAE1C,qBAAa,mBAAoB,YAAW,YAAY;;gBAYxC,OAAO,EAAE,0BAA0B,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK;IAQjE,UAAU,IAAI,IAAI;IASlB,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,YAAY;IAQ9D,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,CAAoB;IAC1C,IAAI,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,CAAoB;IACjD,IAAI,IAAI,IAAI,MAAM,CAAC,cAAc,CAAC,CAAoB;IACtD,IAAI,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAqB;IAC/C,IAAI,KAAK,IAAI,iBAAiB,CAAqB;IAEnD,QAAQ,IAAI,MAAM;CAuErB"}
|
|
@@ -75,8 +75,10 @@ export class DefaultSampleLoader {
|
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
77
|
if (fetchResult.status === "rejected") {
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
const error = fetchResult.error;
|
|
79
|
+
console.warn(error);
|
|
80
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
81
|
+
this.#setState({ type: "error", reason });
|
|
80
82
|
return;
|
|
81
83
|
}
|
|
82
84
|
const [audio, meta] = fetchResult.value;
|
|
@@ -98,8 +100,10 @@ export class DefaultSampleLoader {
|
|
|
98
100
|
this.#setState({ type: "loaded" });
|
|
99
101
|
}
|
|
100
102
|
else {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
const error = storeResult.error;
|
|
104
|
+
console.warn(error);
|
|
105
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
106
|
+
this.#setState({ type: "error", reason });
|
|
103
107
|
}
|
|
104
108
|
}
|
|
105
109
|
}
|
|
@@ -23,7 +23,7 @@ export class DefaultSampleLoaderManager {
|
|
|
23
23
|
subscription = loader.subscribe(state => {
|
|
24
24
|
if (state.type === "error") {
|
|
25
25
|
queueMicrotask(() => subscription.terminate());
|
|
26
|
-
reject(state.reason);
|
|
26
|
+
reject(new Error(state.reason));
|
|
27
27
|
}
|
|
28
28
|
else if (loader.data.nonEmpty()) {
|
|
29
29
|
queueMicrotask(() => subscription.terminate());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultSoundfontLoader.d.ts","sourceRoot":"","sources":["../../src/soundfont/DefaultSoundfontLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,QAAQ,EAAE,MAAM,EAAY,YAAY,EAAc,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAErG,OAAO,EAAC,eAAe,EAAE,oBAAoB,EAAE,iBAAiB,EAAC,MAAM,0BAA0B,CAAA;AACjG,OAAO,EAAC,6BAA6B,EAAC,MAAM,iCAAiC,CAAA;AAE7E,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AAG1C,qBAAa,sBAAuB,YAAW,eAAe;;gBAU9C,OAAO,EAAE,6BAA6B,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK;IAQpE,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,YAAY;IAQjE,UAAU,IAAI,IAAI;IAOlB,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,CAAoB;IAC1C,IAAI,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC,CAAyB;IAC5D,IAAI,IAAI,IAAI,MAAM,CAAC,iBAAiB,CAAC,CAAoB;IACzD,IAAI,KAAK,IAAI,oBAAoB,CAAqB;IAEtD,QAAQ,IAAI,MAAM;
|
|
1
|
+
{"version":3,"file":"DefaultSoundfontLoader.d.ts","sourceRoot":"","sources":["../../src/soundfont/DefaultSoundfontLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,QAAQ,EAAE,MAAM,EAAY,YAAY,EAAc,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAErG,OAAO,EAAC,eAAe,EAAE,oBAAoB,EAAE,iBAAiB,EAAC,MAAM,0BAA0B,CAAA;AACjG,OAAO,EAAC,6BAA6B,EAAC,MAAM,iCAAiC,CAAA;AAE7E,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,YAAY,CAAA;AAG1C,qBAAa,sBAAuB,YAAW,eAAe;;gBAU9C,OAAO,EAAE,6BAA6B,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK;IAQpE,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,YAAY;IAQjE,UAAU,IAAI,IAAI;IAOlB,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,CAAoB;IAC1C,IAAI,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC,CAAyB;IAC5D,IAAI,IAAI,IAAI,MAAM,CAAC,iBAAiB,CAAC,CAAoB;IACzD,IAAI,KAAK,IAAI,oBAAoB,CAAqB;IAEtD,QAAQ,IAAI,MAAM;CAkDrB"}
|
|
@@ -59,8 +59,10 @@ export class DefaultSoundfontLoader {
|
|
|
59
59
|
const fetchProgress = progress => this.#setState({ type: "progress", progress });
|
|
60
60
|
const fetchResult = await Promises.tryCatch(this.#manager.fetch(this.#uuid, fetchProgress));
|
|
61
61
|
if (fetchResult.status === "rejected") {
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
const error = fetchResult.error;
|
|
63
|
+
console.warn(error);
|
|
64
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
65
|
+
this.#setState({ type: "error", reason });
|
|
64
66
|
return;
|
|
65
67
|
}
|
|
66
68
|
const [file, meta] = fetchResult.value;
|
|
@@ -74,8 +76,10 @@ export class DefaultSoundfontLoader {
|
|
|
74
76
|
this.#setState({ type: "loaded" });
|
|
75
77
|
}
|
|
76
78
|
else {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
const error = storeResult.error;
|
|
80
|
+
console.warn(error);
|
|
81
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
82
|
+
this.#setState({ type: "error", reason });
|
|
79
83
|
}
|
|
80
84
|
}
|
|
81
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegionClipResolver.d.ts","sourceRoot":"","sources":["../../src/ui/RegionClipResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,IAAI,EAAE,GAAG,EAAa,MAAM,kBAAkB,CAAA;AACzE,OAAO,EAAC,KAAK,EAAmB,IAAI,EAAW,MAAM,kBAAkB,CAAA;AACvE,OAAO,EACH,mBAAmB,EAGnB,eAAe,EAGlB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAA;AAE/D,MAAM,MAAM,QAAQ,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAA;IACd,MAAM,EAAE,mBAAmB,CAAA;CAC9B,GAAG;IACA,IAAI,EAAE,UAAU,CAAA;IAChB,MAAM,EAAE,mBAAmB,CAAA;IAC3B,KAAK,EAAE,IAAI,CAAA;IACX,GAAG,EAAE,IAAI,CAAA;CACZ,GAAG;IACA,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,mBAAmB,CAAA;IAC3B,QAAQ,EAAE,IAAI,CAAA;CACjB,GAAG;IACA,IAAI,EAAE,UAAU,CAAA;IAChB,MAAM,EAAE,mBAAmB,CAAA;IAC3B,QAAQ,EAAE,IAAI,CAAA;CACjB,CAAA;AAED,UAAU,IAAK,SAAQ,KAAK;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAC;AAO7C,qBAAa,kBAAkB;;IAC3B,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,EACtC,QAAQ,EAAE,aAAa,CAAC,mBAAmB,CAAC,EAC5C,QAAQ,EAAE,sBAAsB,EAChC,UAAU,GAAE,GAAO,GAAG,IAAI;IAY/C,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,GAAG,IAAI;IAO9E,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,IAAI;IAInE,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAuBlD,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC;gBAuC5D,QAAQ,EAAE,sBAAsB,EAAE,MAAM,EAAE,eAAe;IAMrE,OAAO,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAK1C,YAAY,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"RegionClipResolver.d.ts","sourceRoot":"","sources":["../../src/ui/RegionClipResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,IAAI,EAAE,GAAG,EAAa,MAAM,kBAAkB,CAAA;AACzE,OAAO,EAAC,KAAK,EAAmB,IAAI,EAAW,MAAM,kBAAkB,CAAA;AACvE,OAAO,EACH,mBAAmB,EAGnB,eAAe,EAGlB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAA;AAE/D,MAAM,MAAM,QAAQ,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAA;IACd,MAAM,EAAE,mBAAmB,CAAA;CAC9B,GAAG;IACA,IAAI,EAAE,UAAU,CAAA;IAChB,MAAM,EAAE,mBAAmB,CAAA;IAC3B,KAAK,EAAE,IAAI,CAAA;IACX,GAAG,EAAE,IAAI,CAAA;CACZ,GAAG;IACA,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,mBAAmB,CAAA;IAC3B,QAAQ,EAAE,IAAI,CAAA;CACjB,GAAG;IACA,IAAI,EAAE,UAAU,CAAA;IAChB,MAAM,EAAE,mBAAmB,CAAA;IAC3B,QAAQ,EAAE,IAAI,CAAA;CACjB,CAAA;AAED,UAAU,IAAK,SAAQ,KAAK;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAC;AAO7C,qBAAa,kBAAkB;;IAC3B,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,EACtC,QAAQ,EAAE,aAAa,CAAC,mBAAmB,CAAC,EAC5C,QAAQ,EAAE,sBAAsB,EAChC,UAAU,GAAE,GAAO,GAAG,IAAI;IAY/C,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,GAAG,IAAI;IAO9E,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,IAAI;IAInE,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAuBlD,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC;gBAuC5D,QAAQ,EAAE,sBAAsB,EAAE,MAAM,EAAE,eAAe;IAMrE,OAAO,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAK1C,YAAY,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,GAAG,IAAI;CA+ErD"}
|
|
@@ -106,16 +106,21 @@ export class RegionClipResolver {
|
|
|
106
106
|
#createTasksFromMasks(masks) {
|
|
107
107
|
const tasks = [];
|
|
108
108
|
masks.forEach(({ position, complete }) => {
|
|
109
|
-
|
|
109
|
+
// Iterate from 0 to find all regions that OVERLAP with [position, complete],
|
|
110
|
+
// not just regions that START within that range
|
|
111
|
+
for (const region of this.#ground.regions.collection.iterateRange(0, complete)) {
|
|
112
|
+
if (region.position >= complete) {
|
|
113
|
+
break;
|
|
114
|
+
} // past the mask, done
|
|
115
|
+
if (region.complete <= position) {
|
|
116
|
+
continue;
|
|
117
|
+
} // ends before mask, skip
|
|
110
118
|
if (region.isSelected && !this.#strategy.showOrigin()) {
|
|
111
119
|
continue;
|
|
112
120
|
}
|
|
113
121
|
else if (region.duration <= 0) {
|
|
114
122
|
return panic(`Invalid duration(${region.duration})`);
|
|
115
123
|
}
|
|
116
|
-
else if (region.complete <= position || region.position >= complete) {
|
|
117
|
-
return panic("Not overlapping");
|
|
118
|
-
}
|
|
119
124
|
const positionIn = region.position >= position;
|
|
120
125
|
const completeIn = region.complete <= complete;
|
|
121
126
|
if (positionIn && completeIn) {
|
|
@@ -154,9 +159,13 @@ export class RegionClipResolver {
|
|
|
154
159
|
case "start":
|
|
155
160
|
if (UnionAdapterTypes.isLoopableRegion(region)) {
|
|
156
161
|
const delta = task.position - region.position;
|
|
162
|
+
// Capture old values BEFORE changing position (they depend on position for TimeBase.Seconds)
|
|
163
|
+
const oldDuration = region.duration;
|
|
164
|
+
const oldLoopOffset = region.loopOffset;
|
|
165
|
+
const oldLoopDuration = region.loopDuration;
|
|
157
166
|
region.position = region.position + delta;
|
|
158
|
-
region.duration =
|
|
159
|
-
region.loopOffset = mod(
|
|
167
|
+
region.duration = oldDuration - delta;
|
|
168
|
+
region.loopOffset = mod(oldLoopOffset + delta, oldLoopDuration);
|
|
160
169
|
}
|
|
161
170
|
else {
|
|
162
171
|
return panic("Not yet implemented");
|
|
@@ -15,9 +15,9 @@ export var RegionModifyStrategy;
|
|
|
15
15
|
(function (RegionModifyStrategy) {
|
|
16
16
|
RegionModifyStrategy.Identity = Object.freeze({
|
|
17
17
|
readPosition: (region) => region.position,
|
|
18
|
-
readComplete: (region) => region.
|
|
19
|
-
readLoopOffset: (region) => region.
|
|
20
|
-
readLoopDuration: (region) => region.
|
|
18
|
+
readComplete: (region) => region.resolveComplete(region.position),
|
|
19
|
+
readLoopOffset: (region) => region.resolveLoopOffset(region.position),
|
|
20
|
+
readLoopDuration: (region) => region.resolveLoopDuration(region.position),
|
|
21
21
|
readMirror: (region) => region.isMirrowed,
|
|
22
22
|
translateTrackIndex: (value) => value,
|
|
23
23
|
iterateRange: (regions, from, to) => regions.iterateRange(from, to)
|
package/dist/ui/TimeGrid.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { int } from "@opendaw/lib-std";
|
|
2
2
|
import { TimelineRange } from "./TimelineRange";
|
|
3
|
+
import { SignatureTrackAdapter } from "@opendaw/studio-adapters";
|
|
3
4
|
export declare namespace TimeGrid {
|
|
4
5
|
type Signature = [int, int];
|
|
5
6
|
type Options = {
|
|
@@ -14,6 +15,6 @@ export declare namespace TimeGrid {
|
|
|
14
15
|
pulse: number;
|
|
15
16
|
};
|
|
16
17
|
type Designer = (fragment: Fragment) => void;
|
|
17
|
-
const fragment: (
|
|
18
|
+
const fragment: (signatureTrack: SignatureTrackAdapter, range: TimelineRange, designer: Designer, options?: Options) => void;
|
|
18
19
|
}
|
|
19
20
|
//# sourceMappingURL=TimeGrid.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeGrid.d.ts","sourceRoot":"","sources":["../../src/ui/TimeGrid.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"TimeGrid.d.ts","sourceRoot":"","sources":["../../src/ui/TimeGrid.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAuB,MAAM,kBAAkB,CAAA;AAC1D,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAC,qBAAqB,EAAC,MAAM,0BAA0B,CAAA;AAE9D,yBAAiB,QAAQ,CAAC;IACtB,KAAY,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAClC,KAAY,OAAO,GAAG;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5C,KAAY,QAAQ,GAAG;QAAE,IAAI,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5G,KAAY,QAAQ,GAAG,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAA;IA8C5C,MAAM,QAAQ,GAAI,gBAAgB,qBAAqB,EACrC,OAAO,aAAa,EAAE,UAAU,QAAQ,EAAE,UAAU,OAAO,KAAG,IAmBtF,CAAA;CACJ"}
|
package/dist/ui/TimeGrid.js
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import { PPQN } from "@opendaw/lib-dsp";
|
|
2
|
-
import {
|
|
2
|
+
import { isDefined, Iterables } from "@opendaw/lib-std";
|
|
3
3
|
export var TimeGrid;
|
|
4
4
|
(function (TimeGrid) {
|
|
5
|
-
|
|
6
|
-
const unitsPerPixel = range.unitsPerPixel;
|
|
7
|
-
if (unitsPerPixel <= 0) {
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
5
|
+
const computeInterval = (nominator, denominator, unitsPerPixel, minLength) => {
|
|
10
6
|
const barPulses = PPQN.fromSignature(nominator, denominator);
|
|
11
7
|
const beatPulses = PPQN.fromSignature(1, denominator);
|
|
12
|
-
const minLength = options?.minLength ?? 48;
|
|
13
8
|
let interval = barPulses;
|
|
14
9
|
let pixel = interval / unitsPerPixel;
|
|
15
10
|
if (pixel > minLength) {
|
|
@@ -62,13 +57,32 @@ export var TimeGrid;
|
|
|
62
57
|
pixel = interval / unitsPerPixel;
|
|
63
58
|
}
|
|
64
59
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
60
|
+
return interval;
|
|
61
|
+
};
|
|
62
|
+
TimeGrid.fragment = (signatureTrack, range, designer, options) => {
|
|
63
|
+
const unitsPerPixel = range.unitsPerPixel;
|
|
64
|
+
if (unitsPerPixel <= 0) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const minLength = options?.minLength ?? 48;
|
|
68
|
+
for (const [prev, next] of Iterables.pairWise(signatureTrack.iterateAll())) {
|
|
69
|
+
const { accumulatedPpqn, accumulatedBars, nominator, denominator } = prev;
|
|
70
|
+
const interval = computeInterval(prev.nominator, prev.denominator, unitsPerPixel, minLength);
|
|
71
|
+
const barDuration = PPQN.fromSignature(nominator, denominator);
|
|
72
|
+
const p0 = accumulatedPpqn;
|
|
73
|
+
const p1 = isDefined(next) ? next.accumulatedPpqn : range.unitMax;
|
|
74
|
+
for (let pulse = p0; pulse < p1; pulse += interval) {
|
|
75
|
+
if (pulse < range.unitMin - barDuration) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (pulse >= range.unitMax) {
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
const { bars, beats, semiquavers, ticks } = PPQN.toParts(pulse - accumulatedPpqn, nominator, denominator);
|
|
82
|
+
const isBeat = ticks === 0 && semiquavers === 0;
|
|
83
|
+
const isBar = isBeat && beats === 0;
|
|
84
|
+
designer({ bars: bars + accumulatedBars, beats, ticks, isBar, isBeat, pulse });
|
|
85
|
+
}
|
|
72
86
|
}
|
|
73
87
|
};
|
|
74
88
|
})(TimeGrid || (TimeGrid = {}));
|