@opendaw/studio-core 0.0.91 → 0.0.93
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/AudioDevices.d.ts +2 -0
- package/dist/AudioDevices.d.ts.map +1 -1
- package/dist/AudioDevices.js +3 -0
- package/dist/AudioOfflineRenderer.d.ts +2 -0
- package/dist/AudioOfflineRenderer.d.ts.map +1 -1
- package/dist/AudioOfflineRenderer.js +2 -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 -0
- package/dist/EngineWorklet.d.ts +2 -1
- package/dist/EngineWorklet.d.ts.map +1 -1
- package/dist/EngineWorklet.js +8 -2
- package/dist/OfflineEngineRenderer.d.ts +16 -5
- package/dist/OfflineEngineRenderer.d.ts.map +1 -1
- package/dist/OfflineEngineRenderer.js +85 -38
- package/dist/OpenDAWHeaders.d.ts.map +1 -1
- package/dist/OpenDAWHeaders.js +1 -2
- package/dist/RecordingWorklet.d.ts.map +1 -1
- package/dist/RecordingWorklet.js +0 -1
- package/dist/StudioPreferences.d.ts +22 -12
- package/dist/StudioPreferences.d.ts.map +1 -1
- package/dist/StudioSettings.d.ts +22 -12
- package/dist/StudioSettings.d.ts.map +1 -1
- package/dist/StudioSettings.js +41 -12
- package/dist/WavFile.d.ts.map +1 -1
- package/dist/WavFile.js +33 -9
- package/dist/capture/CaptureAudio.js +4 -4
- package/dist/capture/RecordAudio.d.ts.map +1 -1
- package/dist/capture/RecordAudio.js +49 -12
- package/dist/capture/RecordMidi.d.ts.map +1 -1
- package/dist/capture/RecordMidi.js +44 -8
- package/dist/capture/Recording.d.ts +2 -0
- package/dist/capture/Recording.d.ts.map +1 -1
- package/dist/capture/Recording.js +6 -2
- package/dist/midi/MIDIReceiver.d.ts +2 -2
- package/dist/midi/MIDIReceiver.d.ts.map +1 -1
- package/dist/midi/MIDIReceiver.js +2 -7
- package/dist/midi/index.d.ts +1 -0
- package/dist/midi/index.d.ts.map +1 -1
- package/dist/midi/index.js +1 -0
- package/dist/offline-engine.js +1 -1
- package/dist/offline-engine.js.map +3 -3
- package/dist/processors.js +15 -15
- package/dist/processors.js.map +4 -4
- package/dist/project/Project.d.ts +2 -1
- package/dist/project/Project.d.ts.map +1 -1
- package/dist/project/Project.js +18 -3
- package/dist/project/ProjectMigration.d.ts.map +1 -1
- package/dist/project/ProjectMigration.js +18 -251
- package/dist/project/migration/MigrateAudioClipBox.d.ts +4 -0
- package/dist/project/migration/MigrateAudioClipBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateAudioClipBox.js +32 -0
- package/dist/project/migration/MigrateAudioFileBox.d.ts +5 -0
- package/dist/project/migration/MigrateAudioFileBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateAudioFileBox.js +13 -0
- package/dist/project/migration/MigrateAudioRegionBox.d.ts +4 -0
- package/dist/project/migration/MigrateAudioRegionBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateAudioRegionBox.js +54 -0
- package/dist/project/migration/MigrateAudioUnitBox.d.ts +4 -0
- package/dist/project/migration/MigrateAudioUnitBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateAudioUnitBox.js +19 -0
- package/dist/project/migration/MigrateDelayDeviceBox.d.ts +4 -0
- package/dist/project/migration/MigrateDelayDeviceBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateDelayDeviceBox.js +36 -0
- package/dist/project/migration/MigrateMIDIOutputDeviceBox.d.ts +4 -0
- package/dist/project/migration/MigrateMIDIOutputDeviceBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateMIDIOutputDeviceBox.js +20 -0
- package/dist/project/migration/MigrateRevampDeviceBox.d.ts +4 -0
- package/dist/project/migration/MigrateRevampDeviceBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateRevampDeviceBox.js +7 -0
- package/dist/project/migration/MigrateTimelineBox.d.ts +4 -0
- package/dist/project/migration/MigrateTimelineBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateTimelineBox.js +10 -0
- package/dist/project/migration/MigrateValueEventBox.d.ts +4 -0
- package/dist/project/migration/MigrateValueEventBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateValueEventBox.js +32 -0
- package/dist/project/migration/MigrateValueEventCollection.d.ts +4 -0
- package/dist/project/migration/MigrateValueEventCollection.d.ts.map +1 -0
- package/dist/project/migration/MigrateValueEventCollection.js +59 -0
- package/dist/project/migration/MigrateValueEventCollection.test.d.ts +2 -0
- package/dist/project/migration/MigrateValueEventCollection.test.d.ts.map +1 -0
- package/dist/project/migration/MigrateValueEventCollection.test.js +199 -0
- package/dist/project/migration/MigrateVaporisateurDeviceBox.d.ts +4 -0
- package/dist/project/migration/MigrateVaporisateurDeviceBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateVaporisateurDeviceBox.js +28 -0
- package/dist/project/migration/MigrateZeitgeistDeviceBox.d.ts +4 -0
- package/dist/project/migration/MigrateZeitgeistDeviceBox.d.ts.map +1 -0
- package/dist/project/migration/MigrateZeitgeistDeviceBox.js +8 -0
- package/dist/project/migration/index.d.ts +13 -0
- package/dist/project/migration/index.d.ts.map +1 -0
- package/dist/project/migration/index.js +12 -0
- package/dist/samples/OpenSampleAPI.d.ts.map +1 -1
- package/dist/samples/OpenSampleAPI.js +3 -0
- package/dist/ui/generic/ClipboardManager.js +1 -1
- package/dist/ui/generic/ContextMenu.d.ts +1 -1
- package/dist/ui/generic/ContextMenu.js +1 -1
- package/dist/ui/generic/{menu-item.d.ts → MenuItems.d.ts} +1 -1
- package/dist/ui/generic/{menu-item.d.ts.map → MenuItems.d.ts.map} +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/workers-main.js +1 -1
- package/dist/workers-main.js.map +3 -3
- package/dist/ysync/YMapper.d.ts.map +1 -1
- package/dist/ysync/YMapper.js +7 -3
- package/package.json +15 -15
- /package/dist/ui/generic/{menu-item.js → MenuItems.js} +0 -0
package/dist/WavFile.js
CHANGED
|
@@ -30,25 +30,49 @@ export var WavFile;
|
|
|
30
30
|
if (fmtOffset < 0 || dataOffset < 0) {
|
|
31
31
|
return panic("Missing fmt or data chunk");
|
|
32
32
|
}
|
|
33
|
-
const audioFormat = view.getUint16(fmtOffset, true); // 3 = IEEE float
|
|
33
|
+
const audioFormat = view.getUint16(fmtOffset, true); // 1 = PCM, 3 = IEEE float
|
|
34
34
|
const numberOfChannels = view.getUint16(fmtOffset + 2, true);
|
|
35
35
|
const sampleRate = view.getUint32(fmtOffset + 4, true);
|
|
36
36
|
const blockAlign = view.getUint16(fmtOffset + 12, true);
|
|
37
37
|
const bitsPerSample = view.getUint16(fmtOffset + 14, true);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
if (blockAlign !== numberOfChannels * 4) {
|
|
38
|
+
const bytesPerSample = bitsPerSample / 8;
|
|
39
|
+
if (blockAlign !== numberOfChannels * bytesPerSample) {
|
|
42
40
|
return panic("Invalid block alignment");
|
|
43
41
|
}
|
|
44
42
|
const numberOfFrames = Math.floor(dataSize / blockAlign);
|
|
45
|
-
const interleaved = new Float32Array(buffer, dataOffset, numberOfFrames * numberOfChannels);
|
|
46
43
|
const audioData = AudioData.create(sampleRate, numberOfFrames, numberOfChannels);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
if (audioFormat === 3 && bitsPerSample === 32) {
|
|
45
|
+
// 32-bit float
|
|
46
|
+
const interleaved = new Float32Array(buffer, dataOffset, numberOfFrames * numberOfChannels);
|
|
47
|
+
for (let i = 0, w = 0; i < numberOfFrames; i++) {
|
|
48
|
+
for (let c = 0; c < numberOfChannels; c++) {
|
|
49
|
+
audioData.frames[c][i] = interleaved[w++];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (audioFormat === 1 && bitsPerSample === 16) {
|
|
54
|
+
// 16-bit PCM
|
|
55
|
+
for (let i = 0, offset = dataOffset; i < numberOfFrames; i++) {
|
|
56
|
+
for (let c = 0; c < numberOfChannels; c++) {
|
|
57
|
+
audioData.frames[c][i] = view.getInt16(offset, true) / 32768;
|
|
58
|
+
offset += 2;
|
|
59
|
+
}
|
|
50
60
|
}
|
|
51
61
|
}
|
|
62
|
+
else if (audioFormat === 1 && bitsPerSample === 24) {
|
|
63
|
+
// 24-bit PCM
|
|
64
|
+
for (let i = 0, offset = dataOffset; i < numberOfFrames; i++) {
|
|
65
|
+
for (let c = 0; c < numberOfChannels; c++) {
|
|
66
|
+
const low = view.getUint16(offset, true);
|
|
67
|
+
const high = view.getInt8(offset + 2);
|
|
68
|
+
audioData.frames[c][i] = (high * 65536 + low) / 8388608;
|
|
69
|
+
offset += 3;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
return panic(`Unsupported WAV format: ${audioFormat}, ${bitsPerSample}-bit`);
|
|
75
|
+
}
|
|
52
76
|
return audioData;
|
|
53
77
|
};
|
|
54
78
|
WavFile.encodeFloats = (audio, maxLength = Number.MAX_SAFE_INTEGER) => {
|
|
@@ -90,10 +90,10 @@ export class CaptureAudio extends Capture {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
this.#stopStream();
|
|
93
|
-
const deviceId = this.deviceId.getValue().
|
|
93
|
+
const deviceId = this.deviceId.getValue().unwrapOrUndefined() ?? AudioDevices.defaultInput?.deviceId;
|
|
94
94
|
const channelCount = this.#requestChannels.unwrapOrElse(1);
|
|
95
95
|
return AudioDevices.requestStream({
|
|
96
|
-
deviceId: { exact: deviceId },
|
|
96
|
+
deviceId: isDefined(deviceId) ? { exact: deviceId } : undefined,
|
|
97
97
|
echoCancellation: false,
|
|
98
98
|
noiseSuppression: false,
|
|
99
99
|
autoGainControl: false,
|
|
@@ -103,8 +103,8 @@ export class CaptureAudio extends Capture {
|
|
|
103
103
|
const track = tracks.at(0);
|
|
104
104
|
const settings = track?.getSettings();
|
|
105
105
|
const gotDeviceId = settings?.deviceId;
|
|
106
|
-
console.debug(`new stream. device requested: ${deviceId}, got: ${gotDeviceId ?? "unknown"}. channelCount requested: ${channelCount}, got: ${settings?.channelCount}`);
|
|
107
|
-
if (deviceId
|
|
106
|
+
console.debug(`new stream. device requested: ${deviceId ?? "default"}, got: ${gotDeviceId ?? "unknown"}. channelCount requested: ${channelCount}, got: ${settings?.channelCount}`);
|
|
107
|
+
if (isUndefined(deviceId) || deviceId === gotDeviceId) {
|
|
108
108
|
this.#stream.wrap(stream);
|
|
109
109
|
}
|
|
110
110
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecordAudio.d.ts","sourceRoot":"","sources":["../../src/capture/RecordAudio.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"RecordAudio.d.ts","sourceRoot":"","sources":["../../src/capture/RecordAudio.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2C,UAAU,EAAmB,MAAM,kBAAkB,CAAA;AAUvG,OAAO,EAAa,mBAAmB,EAA2B,MAAM,0BAA0B,CAAA;AAClG,OAAO,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AAClC,OAAO,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAGjC,yBAAiB,WAAW,CAAC;IACzB,KAAK,kBAAkB,GAAG;QACtB,gBAAgB,EAAE,gBAAgB,CAAA;QAClC,WAAW,EAAE,WAAW,CAAA;QACxB,aAAa,EAAE,mBAAmB,CAAA;QAClC,YAAY,EAAE,YAAY,CAAA;QAC1B,OAAO,EAAE,OAAO,CAAA;QAChB,OAAO,EAAE,OAAO,CAAA;QAChB,MAAM,EAAE,MAAM,CAAA;QACd,aAAa,EAAE,MAAM,CAAA;KACxB,CAAA;IAQD,MAAM,CAAC,MAAM,KAAK,GACd,yGASG,kBAAkB,KACnB,UAyKL,CAAA;;CACJ"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Option, quantizeFloor, Terminable, Terminator, UUID } from "@opendaw/lib-std";
|
|
1
|
+
import { asInstanceOf, Option, quantizeFloor, Terminable, Terminator, UUID } from "@opendaw/lib-std";
|
|
2
2
|
import { dbToGain, PPQN, TimeBase } from "@opendaw/lib-dsp";
|
|
3
|
-
import { AudioFileBox, AudioPitchStretchBox, AudioRegionBox, ValueEventCollectionBox, WarpMarkerBox } from "@opendaw/studio-boxes";
|
|
4
|
-
import { ColorCodes, TrackType } from "@opendaw/studio-adapters";
|
|
3
|
+
import { AudioFileBox, AudioPitchStretchBox, AudioRegionBox, TrackBox, ValueEventCollectionBox, WarpMarkerBox } from "@opendaw/studio-boxes";
|
|
4
|
+
import { ColorCodes, TrackType, UnionBoxTypes } from "@opendaw/studio-adapters";
|
|
5
5
|
import { RecordTrack } from "./RecordTrack";
|
|
6
6
|
export var RecordAudio;
|
|
7
7
|
(function (RecordAudio) {
|
|
@@ -24,7 +24,7 @@ export var RecordAudio;
|
|
|
24
24
|
let lastPosition = 0;
|
|
25
25
|
let currentWaveformOffset = outputLatency;
|
|
26
26
|
let takeNumber = 0;
|
|
27
|
-
const { tempoMap, env: { audioContext: { sampleRate } } } = project;
|
|
27
|
+
const { tempoMap, env: { audioContext: { sampleRate } }, engine: { preferences: { settings: { recording } } } } = project;
|
|
28
28
|
const { loopArea } = timelineBox;
|
|
29
29
|
const createFileBox = () => {
|
|
30
30
|
const fileDateString = new Date()
|
|
@@ -67,8 +67,43 @@ export var RecordAudio;
|
|
|
67
67
|
warpMarkerBox.position.setValue(loopDurationPPQN);
|
|
68
68
|
warpMarkerBox.seconds.setValue(seconds);
|
|
69
69
|
}
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
const { olderTakeAction, olderTakeScope } = recording;
|
|
71
|
+
if (olderTakeScope === "all") {
|
|
72
|
+
for (const track of capture.audioUnitBox.tracks.pointerHub.incoming()
|
|
73
|
+
.map(({ box }) => asInstanceOf(box, TrackBox))) {
|
|
74
|
+
const trackType = track.type.getValue();
|
|
75
|
+
if (trackType === TrackType.Value || trackType === TrackType.Undefined) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (track === trackBox) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (olderTakeAction === "disable-track") {
|
|
82
|
+
if (track.isAttached()) {
|
|
83
|
+
track.enabled.setValue(false);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
for (const region of track.regions.pointerHub.incoming()
|
|
88
|
+
.map(({ box }) => UnionBoxTypes.asRegionBox(box))) {
|
|
89
|
+
if (region.isAttached()) {
|
|
90
|
+
region.mute.setValue(true);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
if (olderTakeAction === "disable-track") {
|
|
98
|
+
if (trackBox.isAttached()) {
|
|
99
|
+
trackBox.enabled.setValue(false);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
if (regionBox.isAttached()) {
|
|
104
|
+
regionBox.mute.setValue(true);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
72
107
|
}
|
|
73
108
|
};
|
|
74
109
|
const startNewTake = (position) => {
|
|
@@ -94,12 +129,14 @@ export var RecordAudio;
|
|
|
94
129
|
const loopEnabled = loopArea.enabled.getValue();
|
|
95
130
|
const loopFrom = loopArea.from.getValue();
|
|
96
131
|
const loopTo = loopArea.to.getValue();
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
if (loopEnabled && currentTake.nonEmpty() && currentPosition < lastPosition) {
|
|
132
|
+
const allowTakes = project.engine.preferences.settings.recording.allowTakes;
|
|
133
|
+
if (loopEnabled && allowTakes && currentTake.nonEmpty() && currentPosition < lastPosition) {
|
|
100
134
|
editing.modify(() => {
|
|
101
|
-
currentTake.ifSome(take =>
|
|
102
|
-
|
|
135
|
+
currentTake.ifSome(take => {
|
|
136
|
+
const actualDurationPPQN = take.regionBox.duration.getValue();
|
|
137
|
+
finalizeTake(take, actualDurationPPQN);
|
|
138
|
+
currentWaveformOffset += tempoMap.intervalToSeconds(0, actualDurationPPQN);
|
|
139
|
+
});
|
|
103
140
|
startNewTake(loopFrom);
|
|
104
141
|
}, false);
|
|
105
142
|
}
|
|
@@ -116,7 +153,7 @@ export var RecordAudio;
|
|
|
116
153
|
editing.modify(() => {
|
|
117
154
|
if (regionBox.isAttached()) {
|
|
118
155
|
const { duration, loopDuration } = regionBox;
|
|
119
|
-
const maxDuration = loopEnabled ? loopTo - regionBox.position.getValue() : Infinity;
|
|
156
|
+
const maxDuration = loopEnabled && allowTakes ? loopTo - regionBox.position.getValue() : Infinity;
|
|
120
157
|
const distanceInPPQN = Math.min(maxDuration, Math.floor(currentPosition - regionBox.position.getValue()));
|
|
121
158
|
duration.setValue(distanceInPPQN);
|
|
122
159
|
loopDuration.setValue(distanceInPPQN);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecordMidi.d.ts","sourceRoot":"","sources":["../../src/capture/RecordMidi.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"RecordMidi.d.ts","sourceRoot":"","sources":["../../src/capture/RecordMidi.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,QAAQ,EAAuC,UAAU,EAAmB,MAAM,kBAAkB,CAAA;AAGrI,OAAO,EAAa,UAAU,EAA2B,MAAM,0BAA0B,CAAA;AACzF,OAAO,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AAClC,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAGjC,yBAAiB,UAAU,CAAC;IACxB,KAAK,iBAAiB,GAAG;QACrB,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC/B,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,OAAO,CAAA;KACnB,CAAA;IAgBD,MAAM,CAAC,MAAM,KAAK,GAAI,gCAA8B,iBAAiB,KAAG,UAgJvE,CAAA;;CACJ"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Option, quantizeCeil, quantizeFloor, Terminator, UUID } from "@opendaw/lib-std";
|
|
1
|
+
import { asInstanceOf, Option, quantizeCeil, quantizeFloor, Terminator, UUID } from "@opendaw/lib-std";
|
|
2
2
|
import { PPQN } from "@opendaw/lib-dsp";
|
|
3
|
-
import { NoteEventBox, NoteEventCollectionBox, NoteRegionBox } from "@opendaw/studio-boxes";
|
|
4
|
-
import { ColorCodes, NoteSignal, TrackType } from "@opendaw/studio-adapters";
|
|
3
|
+
import { NoteEventBox, NoteEventCollectionBox, NoteRegionBox, TrackBox } from "@opendaw/studio-boxes";
|
|
4
|
+
import { ColorCodes, NoteSignal, TrackType, UnionBoxTypes } from "@opendaw/studio-adapters";
|
|
5
5
|
import { RecordTrack } from "./RecordTrack";
|
|
6
6
|
export var RecordMidi;
|
|
7
7
|
(function (RecordMidi) {
|
|
@@ -9,7 +9,7 @@ export var RecordMidi;
|
|
|
9
9
|
RecordMidi.start = ({ notifier, project, capture }) => {
|
|
10
10
|
const beats = PPQN.fromSignature(1, project.timelineBox.signature.denominator.getValue());
|
|
11
11
|
const { editing, boxGraph, engine, env: { audioContext }, timelineBox } = project;
|
|
12
|
-
const { position, isRecording } = engine;
|
|
12
|
+
const { position, isRecording, preferences: { settings: { recording } } } = engine;
|
|
13
13
|
const { loopArea } = timelineBox;
|
|
14
14
|
const terminator = new Terminator();
|
|
15
15
|
const activeNotes = new Map();
|
|
@@ -40,8 +40,43 @@ export var RecordMidi;
|
|
|
40
40
|
regionBox.duration.setValue(loopDurationPPQN);
|
|
41
41
|
regionBox.loopDuration.setValue(loopDurationPPQN);
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
const { olderTakeAction, olderTakeScope } = recording;
|
|
44
|
+
if (olderTakeScope === "all") {
|
|
45
|
+
for (const track of capture.audioUnitBox.tracks.pointerHub.incoming()
|
|
46
|
+
.map(({ box }) => asInstanceOf(box, TrackBox))) {
|
|
47
|
+
const trackType = track.type.getValue();
|
|
48
|
+
if (trackType === TrackType.Value || trackType === TrackType.Undefined) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (track === trackBox) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (olderTakeAction === "disable-track") {
|
|
55
|
+
if (track.isAttached()) {
|
|
56
|
+
track.enabled.setValue(false);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
for (const region of track.regions.pointerHub.incoming()
|
|
61
|
+
.map(({ box }) => UnionBoxTypes.asRegionBox(box))) {
|
|
62
|
+
if (region.isAttached()) {
|
|
63
|
+
region.mute.setValue(true);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
if (olderTakeAction === "disable-track") {
|
|
71
|
+
if (trackBox.isAttached()) {
|
|
72
|
+
trackBox.enabled.setValue(false);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
if (regionBox.isAttached()) {
|
|
77
|
+
regionBox.mute.setValue(true);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
45
80
|
}
|
|
46
81
|
};
|
|
47
82
|
const startNewTake = (position) => {
|
|
@@ -57,7 +92,8 @@ export var RecordMidi;
|
|
|
57
92
|
const loopFrom = loopArea.from.getValue();
|
|
58
93
|
const loopTo = loopArea.to.getValue();
|
|
59
94
|
const loopDurationPPQN = loopTo - loopFrom;
|
|
60
|
-
|
|
95
|
+
const allowTakes = project.engine.preferences.settings.recording.allowTakes;
|
|
96
|
+
if (loopEnabled && allowTakes && currentTake.nonEmpty() && currentPosition < lastPosition) {
|
|
61
97
|
positionOffset += loopDurationPPQN;
|
|
62
98
|
editing.modify(() => {
|
|
63
99
|
currentTake.ifSome(take => finalizeTake(take, loopDurationPPQN));
|
|
@@ -75,7 +111,7 @@ export var RecordMidi;
|
|
|
75
111
|
editing.modify(() => {
|
|
76
112
|
if (regionBox.isAttached() && collection.isAttached()) {
|
|
77
113
|
const { position: regionPosition, duration, loopDuration } = regionBox;
|
|
78
|
-
const maxDuration = loopEnabled ? loopTo - regionPosition.getValue() : Infinity;
|
|
114
|
+
const maxDuration = loopEnabled && allowTakes ? loopTo - regionPosition.getValue() : Infinity;
|
|
79
115
|
const newDuration = Math.min(maxDuration, quantizeCeil(writePosition, beats) - regionPosition.getValue());
|
|
80
116
|
duration.setValue(newDuration);
|
|
81
117
|
loopDuration.setValue(newDuration);
|
|
@@ -2,8 +2,10 @@ import { Terminable } from "@opendaw/lib-std";
|
|
|
2
2
|
import { Project } from "../project";
|
|
3
3
|
export declare class Recording {
|
|
4
4
|
#private;
|
|
5
|
+
readonly countIn: boolean;
|
|
5
6
|
static get isRecording(): boolean;
|
|
6
7
|
static start(project: Project, countIn: boolean): Promise<Terminable>;
|
|
8
|
+
static wasCountingIn(): boolean;
|
|
7
9
|
private constructor();
|
|
8
10
|
}
|
|
9
11
|
//# sourceMappingURL=Recording.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Recording.d.ts","sourceRoot":"","sources":["../../src/capture/Recording.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,UAAU,EAAa,MAAM,kBAAkB,CAAA;AAK7F,OAAO,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AAElC,qBAAa,SAAS;;
|
|
1
|
+
{"version":3,"file":"Recording.d.ts","sourceRoot":"","sources":["../../src/capture/Recording.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,UAAU,EAAa,MAAM,kBAAkB,CAAA;AAK7F,OAAO,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AAElC,qBAAa,SAAS;;IAmEE,QAAQ,CAAC,OAAO,EAAE,OAAO;IAlE7C,MAAM,KAAK,WAAW,IAAI,OAAO,CAA2B;WAE/C,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IA8D3E,MAAM,CAAC,aAAa,IAAI,OAAO;IAE/B,OAAO;CACV"}
|
|
@@ -4,6 +4,7 @@ import { AudioUnitType } from "@opendaw/studio-enums";
|
|
|
4
4
|
import { AudioUnitBox } from "@opendaw/studio-boxes";
|
|
5
5
|
import { InstrumentFactories } from "@opendaw/studio-adapters";
|
|
6
6
|
export class Recording {
|
|
7
|
+
countIn;
|
|
7
8
|
static get isRecording() { return this.#isRecording; }
|
|
8
9
|
static async start(project, countIn) {
|
|
9
10
|
if (this.#isRecording) {
|
|
@@ -36,7 +37,7 @@ export class Recording {
|
|
|
36
37
|
this.#isRecording = false;
|
|
37
38
|
};
|
|
38
39
|
terminator.ownAll(engine.isRecording.subscribe(stop), engine.isCountingIn.subscribe(stop), Terminable.create(() => Recording.#instance = Option.None));
|
|
39
|
-
this.#instance = Option.wrap(new Recording());
|
|
40
|
+
this.#instance = Option.wrap(new Recording(countIn));
|
|
40
41
|
return terminator;
|
|
41
42
|
}
|
|
42
43
|
static #prepare({ api, captureDevices, editing, rootBox, userEditingManager }) {
|
|
@@ -60,5 +61,8 @@ export class Recording {
|
|
|
60
61
|
}
|
|
61
62
|
static #isRecording = false;
|
|
62
63
|
static #instance = Option.None;
|
|
63
|
-
|
|
64
|
+
static wasCountingIn() { return this.#instance.mapOr(recording => recording.countIn, () => false); }
|
|
65
|
+
constructor(countIn) {
|
|
66
|
+
this.countIn = countIn;
|
|
67
|
+
}
|
|
64
68
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { int, Terminable } from "@opendaw/lib-std";
|
|
1
|
+
import { int, Provider, Terminable } from "@opendaw/lib-std";
|
|
2
2
|
type MIDIMessageCallback = (deviceId: string, data: Uint8Array, timeMs: int) => void;
|
|
3
3
|
export declare class MIDIReceiver implements Terminable {
|
|
4
4
|
#private;
|
|
5
|
-
static create(
|
|
5
|
+
static create(outputLatencyProvider: Provider<number>, callback: MIDIMessageCallback): MIDIReceiver;
|
|
6
6
|
private constructor();
|
|
7
7
|
get sab(): SharedArrayBuffer;
|
|
8
8
|
get port(): MessagePort;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MIDIReceiver.d.ts","sourceRoot":"","sources":["../../src/midi/MIDIReceiver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAE,UAAU,EAAC,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"MIDIReceiver.d.ts","sourceRoot":"","sources":["../../src/midi/MIDIReceiver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAC,MAAM,kBAAkB,CAAA;AAE1D,KAAK,mBAAmB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,CAAA;AAEpF,qBAAa,YAAa,YAAW,UAAU;;IAC3C,MAAM,CAAC,MAAM,CAAC,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,mBAAmB,GAAG,YAAY;IAiBnG,OAAO;IAgBP,IAAI,GAAG,IAAI,iBAAiB,CAAmB;IAC/C,IAAI,IAAI,IAAI,WAAW,CAA6B;IAEpD,SAAS,IAAI,IAAI;CAwBpB"}
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
export class MIDIReceiver {
|
|
2
|
-
static create(
|
|
2
|
+
static create(outputLatencyProvider, callback) {
|
|
3
3
|
const MIDI_RING_SIZE = 2048;
|
|
4
4
|
const sab = new SharedArrayBuffer(MIDI_RING_SIZE * 2 * 4 + 8);
|
|
5
5
|
const channel = new MessageChannel();
|
|
6
|
-
const hasOutputLatency = context instanceof AudioContext;
|
|
7
6
|
return new MIDIReceiver(sab, channel, (deviceId, data, relativeTimeInMs) => {
|
|
8
|
-
|
|
9
|
-
if (hasOutputLatency) {
|
|
10
|
-
delay = context.outputLatency / 1000.0;
|
|
11
|
-
}
|
|
12
|
-
callback(deviceId, data, relativeTimeInMs + delay);
|
|
7
|
+
callback(deviceId, data, relativeTimeInMs + outputLatencyProvider());
|
|
13
8
|
});
|
|
14
9
|
}
|
|
15
10
|
#sab;
|
package/dist/midi/index.d.ts
CHANGED
package/dist/midi/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/midi/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/midi/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA"}
|
package/dist/midi/index.js
CHANGED
package/dist/offline-engine.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var h=n=>n!=null;var x=(n,e="asDefined failed")=>n??p(U(e));var U=n=>n instanceof Function?n():n;var z=n=>{throw new Error(`Unhandled ${n}`)},p=n=>{throw typeof n=="string"?new Error(n):n},q=(n,e)=>n?void 0:p(U(e));var G=n=>new Proxy({},{get(){return p(n)}});var F=class{value;status="success";constructor(e){this.value=e}error=G("Cannot access error when succeeded")},_=class{error;status="failure";constructor(e){this.error=e}value=G("Cannot access value when failed")},V=n=>{try{return new F(n())}catch(e){return new _(e)}};var Y=()=>{};var N;(function(n){n[n.Ascending=1]="Ascending",n[n.Descending=-1]="Descending"})(N||(N={}));var b=class{static#e=Object.freeze(new Array(0));static empty=()=>this.#e;static clear=e=>{e.length=0};static replace=(e,t)=>{e.length=0,e.push(...t)};static consume=(e,t)=>{for(let s=0;s<e.length;)t(e[s])?e.splice(s,1):s++};static peekFirst=e=>e.at(0)??null;static peekLast=e=>e.at(-1)??null;static getFirst=(e,t)=>x(e.at(0),t);static getLast=(e,t)=>x(e.at(-1),t);static getPrev=(e,t)=>{let s=e.indexOf(t);return s===-1?p(`${t} not found in ${e}`):x(e.at((s-1)%e.length),"Internal Error")};static getNext=(e,t)=>{let s=e.indexOf(t);return s===-1?p(`${t} not found in ${e}`):x(e.at((s+1)%e.length),"Internal Error")};static removeLast=(e,t)=>x(e.pop(),t);static create=(e,t)=>{let s=new Array(t);for(let r=0;r<t;r++)s[r]=e(r);return s};static equals=(e,t)=>{if(e.length!==t.length)return!1;for(let s=0;s<e.length;s++)if(e[s]!==t[s])return!1;return!0};static satisfy=(e,t)=>{if(e.length<2)return!0;let s=e[0];for(let r=1;r<e.length;r++)if(!t(s,e[r]))return!1;return!0};static remove=(e,t)=>{let s=e.indexOf(t);if(s===-1)return p(`${t} not found in ${e}`);e.splice(s,1)};static removeIf=(e,t)=>{for(let s=e.length-1;s>=0;s--)t(e[s])&&e.splice(s,1)};static removeOpt=(e,t)=>{let s=e.indexOf(t);return s===-1?!1:(e.splice(s,1),!0)};static hasDuplicates=e=>new Set(e).size<e.length;static removeDuplicates=e=>{let t=0,s=new Set;for(let r of e)s.has(r)||(s.add(r),e[t++]=r);return e.length=t,e};static removeDuplicateKeys=(e,t)=>{let s=0,r=new Set;for(let o of e){let i=o[t];r.has(i)||(r.add(i),e[s++]=o)}return e.length=s,e};static subtract(e,t,s){return e.filter(r=>!t.some(o=>s(r,o)))}static intersect(e,t,s){return e.filter(r=>t.some(o=>s(r,o)))}static merge(e,t,s){return[...e.filter(r=>!t.some(o=>s(r,o))),...t]}static*iterate(e){for(let t=0;t<e.length;t++)yield e[t]}static*iterateReverse(e){for(let t=e.length-1;t>=0;t--)yield e[t]}static*iterateStateFull(e){let t=e.length-1;for(let s=0;s<=t;s++)yield{value:e[s],isFirst:s===0,isLast:s===t}}static*iterateAdjacent(e){if(!(e.length<=1))for(let t=1,s=e[0];t<e.length;t++){let r=e[t];yield[s,r],s=r}}static isSorted(e,t=N.Ascending){if(e.length<2)return!0;let s=e[0];for(let r=1;r<e.length;r++){let o=e[r];if(Math.sign(s-o)===t)return!1;s=o}return!0}static toRecord(e,t){return e.reduce((s,r)=>(s[t(r)]=r,s),{})}static concatArrayBuffers(e,t){let s=new ArrayBuffer(e.byteLength+t.byteLength),r=new Uint8Array(s);return r.set(new Uint8Array(e),0),r.set(new Uint8Array(t),e.byteLength),s}};var I=class{static*empty(){}static one(e){return[e]}static count(e){let t=0;for(let s of e)t++;return t}static some(e,t){for(let s of e)if(t(s))return!0;return!1}static every(e,t){for(let s of e)if(!t(s))return!1;return!0}static reduce(e,t,s){let r=s,o=0;for(let i of e)r=t(r,i,o++);return r}static includes(e,t){for(let s of e)if(s===t)return!0;return!1}static forEach(e,t){for(let s of e)t(s)}static*map(e,t){let s=0;for(let r of e)yield t(r,s++)}static*take(e,t){let s=0;for(let r of e){if(s++>=t)return;yield r}}static filter(e,t){let s=[];for(let r of e)t(r)&&s.push(r);return s}static filterMap(e,t){let s=[];for(let r of e){let o=t(r);h(o)&&s.push(o)}return s}static reverse(e){let t=[];for(let s of e)t.push(s);return t.reverse()}static*pairWise(e){let t=e[Symbol.iterator](),{done:s,value:r}=t.next(),o=r;if(s!==!0)for(;;){let{done:i,value:a}=t.next();if(i===!0){yield[o,null];return}yield[o,a],o=a}}};var K=Object.freeze({Empty:{terminate:Y},create:n=>({terminate:n}),many:(...n)=>({terminate:()=>{for(;n.length>0;)n.pop().terminate()}})});var E=class{static subscribeMany(e,...t){return K.many(...t.map(s=>s.subscribe(()=>e(s))))}#e=new Set;subscribe(e){return this.#e.add(e),{terminate:()=>this.#e.delete(e)}}isEmpty(){return this.#e.size===0}notify(e){this.#e.forEach(t=>t(e))}observers(){return this.#e}terminate(){this.#e.clear()}};var T=class n{static POSITIVE_INFINITY=new n(Number.POSITIVE_INFINITY);static millis=e=>new n(e);static seconds=e=>new n(e*n.#e);static minutes=e=>new n(e*n.#t);static hours=e=>new n(e*n.#r);static days=e=>new n(e*n.#o);static toHHMMSS=e=>((e/3600|0)+100).toString().slice(1)+":"+((e/60|0)%60+100).toString().slice(1)+":"+(e%60+100).toString().slice(1);static#e=1e3;static#t=6e4;static#r=36e5;static#o=864e5;#s;constructor(e){this.#s=e}millis(){return this.#s}absSeconds(){return Math.abs(this.#s)/n.#e}absMinutes(){return Math.abs(this.#s)/n.#t}absHours(){return Math.abs(this.#s)/n.#r}absDays(){return Math.abs(this.#s)/n.#o}split(){return{d:Math.floor(this.absDays()),h:Math.floor(this.absHours())%24,m:Math.floor(this.absMinutes())%60,s:Math.floor(this.absSeconds())%60}}isNow(){return this.#s===0}isPast(){return this.#s<0}isFuture(){return this.#s>0}toUnitString(){let e,t,s=Math.floor(Math.abs(this.#s)/1e3),r=Math.floor(s/60),o=Math.floor(r/60),i=Math.floor(o/24);return s<60?(e=s,t="second"):r<60?(e=r,t="minute"):o<24?(e=o,t="hour"):(e=i,t="day"),new Intl.RelativeTimeFormat("en",{numeric:"auto",style:"long"}).format(e*Math.sign(this.#s),t)}toString(){if(isNaN(this.#s))return"NaN";if(!isFinite(this.#s))return"\u221E";let{d:e,h:t,m:s,s:r}=this.split();return e>0?[n.#n("d",e),n.#n("h",t),n.#n("m",s),n.#n("s",r)].join(", "):t>0?[n.#n("h",t),n.#n("m",s),n.#n("s",r)].join(", "):s>0?[n.#n("m",s),n.#n("s",r)].join(", "):r>0?n.#n("s",r):"now"}static#n=(e,t)=>{switch(e){case"d":return`${t} ${t<2?"day":"days"}`;case"h":return`${t} ${t<2?"hour":"hours"}`;case"m":return`${t} ${t<2?"minute":"minutes"}`;case"s":return`${t} ${t<2?"second":"seconds"}`;default:return z(e)}}};var $;(function(n){n.sender=(r,o)=>o(new t(r)),n.executor=(r,o)=>new s(r,o);let e=r=>{let o=[];for(let i of r)i instanceof MessagePort&&o.push(i),typeof ImageBitmap<"u"&&i instanceof ImageBitmap&&o.push(i),typeof OffscreenCanvas<"u"&&i instanceof OffscreenCanvas&&o.push(i);return o};class t{#e;#t=new Map;#r;#o=0;constructor(o){this.#e=o,this.#r=o.subscribe(this.#s)}terminate(){this.#r.terminate()}dispatchAndForget=(o,...i)=>{let a=e(i);this.#e.send({type:"send",returnId:!1,func:o.name,args:Array.from(I.map(i,c=>({value:c})))},a)};dispatchAndReturn=(o,...i)=>new Promise((a,c)=>{let l=I.reduce(i,(u,v,d)=>(typeof v=="function"&&u.push([d,v]),u),[]);this.#t.set(this.#o,{executorTuple:{resolve:a,reject:c},callbacks:new Map(l)});let f=e(i);this.#e.send({type:"send",returnId:this.#o,func:o.name,args:Array.from(I.map(i,(u,v)=>typeof u=="function"?{callback:v}:{value:u}))},f),this.#o++});#s=o=>{let i=this.#t.get(o.returnId);h(i)?o.type==="resolve"?(i.executorTuple.resolve(o.resolve),this.#t.delete(o.returnId)):o.type==="reject"?(i.executorTuple.reject(o.reject),this.#t.delete(o.returnId)):o.type==="callback"&&i.callbacks?.get(o.funcAt).apply(this,o.args):p(`Promise has already been resolved. ${JSON.stringify(o)}`)}}class s{#e;#t;#r;constructor(o,i){this.#e=o,this.#t=i,this.#r=o.subscribe(this.#o)}terminate(){this.#r.terminate()}#o=o=>{q(o.type==="send",()=>"Message type must be 'send'");let i=Object.getPrototypeOf(this.#t)===Object.getPrototypeOf({})?this.#t:Object.getPrototypeOf(this.#t),a=x(i[o.func],`${o.func.toString()} does not exists on ${this.#t}`),c=o.returnId;if(c===!1)a.apply(this.#t,o.args.map(l=>"value"in l?l.value:p(`${o.func.toString()} has no promise.`)));else try{a.apply(this.#t,o.args.map(f=>"callback"in f?(...u)=>this.#i(c,f.callback,u):f.value)).then(f=>{try{this.#s(c,f)}catch(u){this.#n(c,u)}},f=>this.#n(c,f))}catch(l){this.#n(c,l)}};#s=(o,i)=>this.#e.send({type:"resolve",returnId:o,resolve:i});#n=(o,i)=>this.#e.send({type:"reject",returnId:o,reject:i});#i=(o,i,a)=>this.#e.send({type:"callback",returnId:o,funcAt:i,args:a})}n.Executor=s})($||($={}));var W={for:n=>new D(n)},re=[],D=class{#e;#t=new E;constructor(e){if(this.#e=e,h(e.onmessage)||h(e.onmessageerror))throw console.error(e),new Error(`${e} is already wrapped.`);e.onmessage=t=>this.#t.notify(t.data),e.onmessageerror=t=>{throw new Error(t.type)}}send(e,t){this.#e.postMessage(e,t??re)}channel(e){return new k(this,e)}subscribe(e){return this.#t.subscribe(e)}terminate(){this.#t.terminate(),this.#e.onmessage=null,this.#e.onmessageerror=null}},k=class n{#e;#t;#r=new E;#o;constructor(e,t){this.#e=e,this.#t=t,this.#o=e.subscribe(s=>{"__id__"in s&&s.__id__==="42"&&"message"in s&&"channel"in s&&s.channel===t&&this.#r.notify(s.message)})}send(e,t){this.#e.send({__id__:"42",channel:this.#t,message:e},t)}channel(e){return new n(this,e)}subscribe(e){return this.#r.subscribe(e)}terminate(){this.#o.terminate(),this.#r.terminate()}};var A;(function(n){n.frame=()=>new Promise(e=>requestAnimationFrame(()=>e())),n.frames=e=>new Promise(t=>{let s=e,r=()=>{--s<=0?t():requestAnimationFrame(r)};requestAnimationFrame(r)}),n.timeSpan=(e,...t)=>new Promise(s=>setTimeout(s,e.millis(),...t)),n.event=(e,t)=>new Promise(s=>e.addEventListener(t,s,{once:!0})),n.observable=e=>new Promise(t=>{let s=e.subscribe(()=>{s.terminate(),t()})}),n.complete=e=>new Promise((t,s)=>{let r=setInterval(()=>{let{status:o,value:i,error:a}=V(()=>e.next());if(o==="success"){let{done:c,value:l}=i;c&&(clearInterval(r),t(l))}else clearInterval(r),s(a)},0)})})(A||(A={}));var C=(n,e)=>Math.floor(3840/e)*n,Z=(n,e=4,t=4)=>{let s=C(1,t),r=Math.floor(n/s),o=Math.floor(r/e),a=(Math.floor(n)-C(o*e,t))%s,c=Math.floor(a/240),l=a%240;return{bars:o,beats:r-o*e,semiquavers:c,ticks:l}},J=(n,e)=>n*e/60*960,X=(n,e)=>n*60/960/e,oe=(n,e)=>e*60/960/n,ie=(n,e,t)=>J(n/t,e),ae=(n,e,t)=>X(n,e)*t,ee={Bar:3840,Quarter:960,SemiQuaver:240,fromSignature:C,toParts:Z,secondsToPulses:J,pulsesToSeconds:X,secondsToBpm:oe,samplesToPulses:ie,pulsesToSamples:ae,toString:(n,e=4,t=4)=>{let{bars:s,beats:r,semiquavers:o,ticks:i}=Z(n|0,e,t);return`${s+1}.${r+1}.${o+1}:${i}`}};var P=128,Te=ee.fromSignature(1,48);var ce=Math.log(10)/20;var te=n=>Math.exp(n*ce);var L=class{port;constructor(){this.port=globalThis.__workletPort__}};function se(n){let e=globalThis;e.sampleRate=n.sampleRate,e.currentFrame=0,e.currentTime=0,e.AudioWorkletProcessor=L,e.registerProcessor=(t,s)=>{e.__registeredProcessors__=e.__registeredProcessors__||{},e.__registeredProcessors__[t]=s}}function R(n,e){let t=globalThis;t.currentFrame=n,t.currentTime=n/e}var B=null,Q=null,y=48e3,w=2,j=!1,m=0;$.executor(W.for(self).channel("offline-engine"),{async initialize(n,e,t){y=t.sampleRate,w=t.numberOfChannels,Q=e,m=0,se({sampleRate:y}),globalThis.__workletPort__=n,await import(t.processorsUrl);let s=globalThis.__registeredProcessors__["engine-processor"];B=new s({processorOptions:{syncStreamBuffer:t.syncStreamBuffer,controlFlagsBuffer:t.controlFlagsBuffer,project:t.project,exportConfiguration:t.exportConfiguration}})},async step(n){let e=b.create(()=>new Float32Array(n),w),t=b.create(()=>new Float32Array(P),w),s=0;for(;s<n;){let r=[t];R(m,y),B.process([[]],r),m+=P;let o=n-s,i=Math.min(o,P);for(let a=0;a<w;a++)e[a].set(r[0][a].subarray(0,i),s);s+=i}return e},async render(n){let{silenceThresholdDb:e,silenceDurationSeconds:t,maxDurationSeconds:s}=n,r=te(e??-72),o=Math.ceil((t??10)*y),i=h(s)?Math.ceil(s*y):1/0,a=b.create(()=>[],w),c=0,l=!1,f=0;for(j=!0,await A.timeSpan(T.seconds(0));j&&m<i;){let d=[b.create(()=>new Float32Array(P),w)];R(m,y);let S=B.process([[]],d),M=0;for(let g of d[0])for(let ne of g){let H=Math.abs(ne);H>M&&(M=H)}let O=M<=r;if(M>r&&(l=!0),O&&l){if(c+=P,c>=o)break}else c=0;for(let g=0;g<w;g++)a[g].push(d[0][g].slice());if(m+=P,!S)break;m-f>=y&&(f=m,h(Q)&&Q.postMessage({frames:m}),await new Promise(g=>setTimeout(g,0)))}let u=m-c+Math.min(y/4,c);return b.create(v=>{let d=new Float32Array(u),S=0;for(let M of a[v]){if(S>=u)break;let O=Math.min(M.length,u-S);d.set(M.subarray(0,O),S),S+=O}return d},w)},stop(){j=!1}});
|
|
1
|
+
var h=n=>n!=null;var x=(n,t="asDefined failed")=>n??p(U(t));var U=n=>n instanceof Function?n():n;var z=n=>{throw new Error(`Unhandled ${n}`)},p=n=>{throw typeof n=="string"?new Error(n):n},q=(n,t)=>n?void 0:p(U(t));var V=n=>new Proxy({},{get(){return p(n)}});var $=class{value;status="success";constructor(t){this.value=t}error=V("Cannot access error when succeeded")},A=class{error;status="failure";constructor(t){this.error=t}value=V("Cannot access value when failed")},G=n=>{try{return new $(n())}catch(t){return new A(t)}};var Y=()=>{};var _;(function(n){n[n.Ascending=1]="Ascending",n[n.Descending=-1]="Descending"})(_||(_={}));var b=class{static#t=Object.freeze(new Array(0));static empty=()=>this.#t;static clear=t=>{t.length=0};static replace=(t,e)=>{t.length=0,t.push(...e)};static consume=(t,e)=>{for(let s=0;s<t.length;)e(t[s])?t.splice(s,1):s++};static peekFirst=t=>t.at(0)??null;static peekLast=t=>t.at(-1)??null;static getFirst=(t,e)=>x(t.at(0),e);static getLast=(t,e)=>x(t.at(-1),e);static getPrev=(t,e)=>{let s=t.indexOf(e);return s===-1?p(`${e} not found in ${t}`):x(t.at((s-1)%t.length),"Internal Error")};static getNext=(t,e)=>{let s=t.indexOf(e);return s===-1?p(`${e} not found in ${t}`):x(t.at((s+1)%t.length),"Internal Error")};static removeLast=(t,e)=>x(t.pop(),e);static create=(t,e)=>{let s=new Array(e);for(let r=0;r<e;r++)s[r]=t(r);return s};static equals=(t,e)=>{if(t.length!==e.length)return!1;for(let s=0;s<t.length;s++)if(t[s]!==e[s])return!1;return!0};static satisfy=(t,e)=>{if(t.length<2)return!0;let s=t[0];for(let r=1;r<t.length;r++)if(!e(s,t[r]))return!1;return!0};static remove=(t,e)=>{let s=t.indexOf(e);if(s===-1)return p(`${e} not found in ${t}`);t.splice(s,1)};static removeIf=(t,e)=>{for(let s=t.length-1;s>=0;s--)e(t[s])&&t.splice(s,1)};static removeOpt=(t,e)=>{let s=t.indexOf(e);return s===-1?!1:(t.splice(s,1),!0)};static hasDuplicates=t=>new Set(t).size<t.length;static removeDuplicates=t=>{let e=0,s=new Set;for(let r of t)s.has(r)||(s.add(r),t[e++]=r);return t.length=e,t};static removeDuplicateKeys=(t,e)=>{let s=0,r=new Set;for(let o of t){let i=o[e];r.has(i)||(r.add(i),t[s++]=o)}return t.length=s,t};static subtract(t,e,s){return t.filter(r=>!e.some(o=>s(r,o)))}static intersect(t,e,s){return t.filter(r=>e.some(o=>s(r,o)))}static merge(t,e,s){return[...t.filter(r=>!e.some(o=>s(r,o))),...e]}static*iterate(t){for(let e=0;e<t.length;e++)yield t[e]}static*iterateReverse(t){for(let e=t.length-1;e>=0;e--)yield t[e]}static*iterateStateFull(t){let e=t.length-1;for(let s=0;s<=e;s++)yield{value:t[s],isFirst:s===0,isLast:s===e}}static*iterateAdjacent(t){if(!(t.length<=1))for(let e=1,s=t[0];e<t.length;e++){let r=t[e];yield[s,r],s=r}}static isSorted(t,e=_.Ascending){if(t.length<2)return!0;let s=t[0];for(let r=1;r<t.length;r++){let o=t[r];if(Math.sign(s-o)===e)return!1;s=o}return!0}static toRecord(t,e){return t.reduce((s,r)=>(s[e(r)]=r,s),{})}static concatArrayBuffers(t,e){let s=new ArrayBuffer(t.byteLength+e.byteLength),r=new Uint8Array(s);return r.set(new Uint8Array(t),0),r.set(new Uint8Array(e),t.byteLength),s}};var S=class{static*empty(){}static one(t){return[t]}static count(t){let e=0;for(let s of t)e++;return e}static some(t,e){for(let s of t)if(e(s))return!0;return!1}static every(t,e){for(let s of t)if(!e(s))return!1;return!0}static reduce(t,e,s){let r=s,o=0;for(let i of t)r=e(r,i,o++);return r}static includes(t,e){for(let s of t)if(s===e)return!0;return!1}static forEach(t,e){for(let s of t)e(s)}static*map(t,e){let s=0;for(let r of t)yield e(r,s++)}static*take(t,e){let s=0;for(let r of t){if(s++>=e)return;yield r}}static filter(t,e){let s=[];for(let r of t)e(r)&&s.push(r);return s}static filterMap(t,e){let s=[];for(let r of t){let o=e(r);h(o)&&s.push(o)}return s}static reverse(t){let e=[];for(let s of t)e.push(s);return e.reverse()}static*pairWise(t){let e=t[Symbol.iterator](),{done:s,value:r}=e.next(),o=r;if(s!==!0)for(;;){let{done:i,value:a}=e.next();if(i===!0){yield[o,null];return}yield[o,a],o=a}}};var K=Object.freeze({Empty:{terminate:Y},create:n=>({terminate:n}),many:(...n)=>({terminate:()=>{for(;n.length>0;)n.pop().terminate()}})});var T=class{static subscribeMany(t,...e){return K.many(...e.map(s=>s.subscribe(()=>t(s))))}#t=new Set;subscribe(t){return this.#t.add(t),{terminate:()=>this.#t.delete(t)}}isEmpty(){return this.#t.size===0}notify(t){this.#t.forEach(e=>e(t))}observers(){return this.#t}terminate(){this.#t.clear()}};var O=class n{static createEstimator=()=>{let t=performance.now(),e=n.millis(Number.POSITIVE_INFINITY),s=0;return r=>{if(r===0)return n.POSITIVE_INFINITY;if(r>=1)return n.millis(0);let o=performance.now()-t;return o>s*1e3&&(e=n.millis(o/r-o),s++),e}};static POSITIVE_INFINITY=new n(Number.POSITIVE_INFINITY);static millis=t=>new n(t);static seconds=t=>new n(t*n.#t);static minutes=t=>new n(t*n.#e);static hours=t=>new n(t*n.#r);static days=t=>new n(t*n.#o);static toHHMMSS=t=>((t/3600|0)+100).toString().slice(1)+":"+((t/60|0)%60+100).toString().slice(1)+":"+(t%60+100).toString().slice(1);static#t=1e3;static#e=6e4;static#r=36e5;static#o=864e5;#s;constructor(t){this.#s=t}millis(){return this.#s}absSeconds(){return Math.abs(this.#s)/n.#t}absMinutes(){return Math.abs(this.#s)/n.#e}absHours(){return Math.abs(this.#s)/n.#r}absDays(){return Math.abs(this.#s)/n.#o}split(){return{d:Math.floor(this.absDays()),h:Math.floor(this.absHours())%24,m:Math.floor(this.absMinutes())%60,s:Math.floor(this.absSeconds())%60}}isNow(){return this.#s===0}isPast(){return this.#s<0}isFuture(){return this.#s>0}toUnitString(){let t,e,s=Math.floor(Math.abs(this.#s)/1e3),r=Math.floor(s/60),o=Math.floor(r/60),i=Math.floor(o/24);return s<60?(t=s,e="second"):r<60?(t=r,e="minute"):o<24?(t=o,e="hour"):(t=i,e="day"),new Intl.RelativeTimeFormat("en",{numeric:"auto",style:"long"}).format(t*Math.sign(this.#s),e)}toString(){if(isNaN(this.#s))return"NaN";if(!isFinite(this.#s))return"\u221E";let{d:t,h:e,m:s,s:r}=this.split();return t>0?[n.#n("d",t),n.#n("h",e),n.#n("m",s),n.#n("s",r)].join(", "):e>0?[n.#n("h",e),n.#n("m",s),n.#n("s",r)].join(", "):s>0?[n.#n("m",s),n.#n("s",r)].join(", "):r>0?n.#n("s",r):"now"}static#n=(t,e)=>{switch(t){case"d":return`${e} ${e<2?"day":"days"}`;case"h":return`${e} ${e<2?"hour":"hours"}`;case"m":return`${e} ${e<2?"minute":"minutes"}`;case"s":return`${e} ${e<2?"second":"seconds"}`;default:return z(t)}}};var F;(function(n){n.sender=(r,o)=>o(new e(r)),n.executor=(r,o)=>new s(r,o);let t=r=>{let o=[];for(let i of r)i instanceof MessagePort&&o.push(i),typeof ImageBitmap<"u"&&i instanceof ImageBitmap&&o.push(i),typeof OffscreenCanvas<"u"&&i instanceof OffscreenCanvas&&o.push(i);return o};class e{#t;#e=new Map;#r;#o=0;constructor(o){this.#t=o,this.#r=o.subscribe(this.#s)}terminate(){this.#r.terminate()}dispatchAndForget=(o,...i)=>{let a=t(i);this.#t.send({type:"send",returnId:!1,func:o.name,args:Array.from(S.map(i,c=>({value:c})))},a)};dispatchAndReturn=(o,...i)=>new Promise((a,c)=>{let l=S.reduce(i,(u,v,d)=>(typeof v=="function"&&u.push([d,v]),u),[]);this.#e.set(this.#o,{executorTuple:{resolve:a,reject:c},callbacks:new Map(l)});let f=t(i);this.#t.send({type:"send",returnId:this.#o,func:o.name,args:Array.from(S.map(i,(u,v)=>typeof u=="function"?{callback:v}:{value:u}))},f),this.#o++});#s=o=>{let i=this.#e.get(o.returnId);h(i)?o.type==="resolve"?(i.executorTuple.resolve(o.resolve),this.#e.delete(o.returnId)):o.type==="reject"?(i.executorTuple.reject(o.reject),this.#e.delete(o.returnId)):o.type==="callback"&&i.callbacks?.get(o.funcAt).apply(this,o.args):p(`Promise has already been resolved. ${JSON.stringify(o)}`)}}class s{#t;#e;#r;constructor(o,i){this.#t=o,this.#e=i,this.#r=o.subscribe(this.#o)}terminate(){this.#r.terminate()}#o=o=>{q(o.type==="send",()=>"Message type must be 'send'");let i=Object.getPrototypeOf(this.#e)===Object.getPrototypeOf({})?this.#e:Object.getPrototypeOf(this.#e),a=x(i[o.func],`${o.func.toString()} does not exists on ${this.#e}`),c=o.returnId;if(c===!1)a.apply(this.#e,o.args.map(l=>"value"in l?l.value:p(`${o.func.toString()} has no promise.`)));else try{a.apply(this.#e,o.args.map(f=>"callback"in f?(...u)=>this.#i(c,f.callback,u):f.value)).then(f=>{try{this.#s(c,f)}catch(u){this.#n(c,u)}},f=>this.#n(c,f))}catch(l){this.#n(c,l)}};#s=(o,i)=>this.#t.send({type:"resolve",returnId:o,resolve:i});#n=(o,i)=>this.#t.send({type:"reject",returnId:o,reject:i});#i=(o,i,a)=>this.#t.send({type:"callback",returnId:o,funcAt:i,args:a})}n.Executor=s})(F||(F={}));var W={for:n=>new D(n)},rt=[],D=class{#t;#e=new T;constructor(t){if(this.#t=t,h(t.onmessage)||h(t.onmessageerror))throw console.error(t),new Error(`${t} is already wrapped.`);t.onmessage=e=>this.#e.notify(e.data),t.onmessageerror=e=>{throw new Error(e.type)}}send(t,e){this.#t.postMessage(t,e??rt)}channel(t){return new k(this,t)}subscribe(t){return this.#e.subscribe(t)}terminate(){this.#e.terminate(),this.#t.onmessage=null,this.#t.onmessageerror=null}},k=class n{#t;#e;#r=new T;#o;constructor(t,e){this.#t=t,this.#e=e,this.#o=t.subscribe(s=>{"__id__"in s&&s.__id__==="42"&&"message"in s&&"channel"in s&&s.channel===e&&this.#r.notify(s.message)})}send(t,e){this.#t.send({__id__:"42",channel:this.#e,message:t},e)}channel(t){return new n(this,t)}subscribe(t){return this.#r.subscribe(t)}terminate(){this.#o.terminate(),this.#r.terminate()}};var N;(function(n){n.frame=()=>new Promise(t=>requestAnimationFrame(()=>t())),n.frames=t=>new Promise(e=>{let s=t,r=()=>{--s<=0?e():requestAnimationFrame(r)};requestAnimationFrame(r)}),n.timeSpan=(t,...e)=>new Promise(s=>setTimeout(s,t.millis(),...e)),n.event=(t,e)=>new Promise(s=>t.addEventListener(e,s,{once:!0})),n.observable=t=>new Promise(e=>{let s=t.subscribe(()=>{s.terminate(),e()})}),n.complete=t=>new Promise((e,s)=>{let r=setInterval(()=>{let{status:o,value:i,error:a}=G(()=>t.next());if(o==="success"){let{done:c,value:l}=i;c&&(clearInterval(r),e(l))}else clearInterval(r),s(a)},0)})})(N||(N={}));var C=(n,t)=>Math.floor(3840/t)*n,Z=(n,t=4,e=4)=>{let s=C(1,e),r=Math.floor(n/s),o=Math.floor(r/t),a=(Math.floor(n)-C(o*t,e))%s,c=Math.floor(a/240),l=a%240;return{bars:o,beats:r-o*t,semiquavers:c,ticks:l}},J=(n,t)=>n*t/60*960,X=(n,t)=>n*60/960/t,ot=(n,t)=>t*60/960/n,it=(n,t,e)=>J(n/e,t),at=(n,t,e)=>X(n,t)*e,tt={Bar:3840,Quarter:960,SemiQuaver:240,fromSignature:C,toParts:Z,secondsToPulses:J,pulsesToSeconds:X,secondsToBpm:ot,samplesToPulses:it,pulsesToSamples:at,toString:(n,t=4,e=4)=>{let{bars:s,beats:r,semiquavers:o,ticks:i}=Z(n|0,t,e);return`${s+1}.${r+1}.${o+1}:${i}`}};var I=128,Ot=tt.fromSignature(1,48);var ct=Math.log(10)/20;var et=n=>Math.exp(n*ct);var L=class{port;constructor(){this.port=globalThis.__workletPort__}};function st(n){let t=globalThis;t.sampleRate=n.sampleRate,t.currentFrame=0,t.currentTime=0,t.AudioWorkletProcessor=L,t.registerProcessor=(e,s)=>{t.__registeredProcessors__=t.__registeredProcessors__||{},t.__registeredProcessors__[e]=s}}function R(n,t){let e=globalThis;e.currentFrame=n,e.currentTime=n/t}var B=null,Q=null,y=48e3,w=2,j=!1,m=0;F.executor(W.for(self).channel("offline-engine"),{async initialize(n,t,e){y=e.sampleRate,w=e.numberOfChannels,Q=t,m=0,st({sampleRate:y}),globalThis.__workletPort__=n,await import(e.processorsUrl);let s=globalThis.__registeredProcessors__["engine-processor"];B=new s({processorOptions:{syncStreamBuffer:e.syncStreamBuffer,controlFlagsBuffer:e.controlFlagsBuffer,project:e.project,exportConfiguration:e.exportConfiguration}})},async step(n){let t=b.create(()=>new Float32Array(n),w),e=b.create(()=>new Float32Array(I),w),s=0;for(;s<n;){let r=[e];R(m,y),B.process([[]],r),m+=I;let o=n-s,i=Math.min(o,I);for(let a=0;a<w;a++)t[a].set(r[0][a].subarray(0,i),s);s+=i}return t},async render(n){let{silenceThresholdDb:t,silenceDurationSeconds:e,maxDurationSeconds:s}=n,r=et(t??-72),o=Math.ceil((e??10)*y),i=h(s)?Math.ceil(s*y):1/0,a=b.create(()=>[],w),c=0,l=!1,f=0;for(j=!0,await N.timeSpan(O.seconds(0));j&&m<i;){let d=[b.create(()=>new Float32Array(I),w)];R(m,y);let P=B.process([[]],d),M=0;for(let g of d[0])for(let nt of g){let H=Math.abs(nt);H>M&&(M=H)}let E=M<=r;if(M>r&&(l=!0),E&&l){if(c+=I,c>=o)break}else c=0;for(let g=0;g<w;g++)a[g].push(d[0][g].slice());if(m+=I,!P)break;m-f>=y&&(f=m,h(Q)&&Q.postMessage({frames:m}),await new Promise(g=>setTimeout(g,0)))}let u=m-c+Math.min(y/4,c);return b.create(v=>{let d=new Float32Array(u),P=0;for(let M of a[v]){if(P>=u)break;let E=Math.min(M.length,u-P);d.set(M.subarray(0,E),P),P+=E}return d},w)},stop(){j=!1}});
|
|
2
2
|
//# sourceMappingURL=offline-engine.js.map
|