@opendaw/studio-core 0.0.97 → 0.0.99

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,3 +1,3 @@
1
- import { ArpeggioDeviceBox, MaximizerDeviceBox, CompressorDeviceBox, CrusherDeviceBox, DattorroReverbDeviceBox, DelayDeviceBox, FoldDeviceBox, GateDeviceBox, ModularDeviceBox, PitchDeviceBox, RevampDeviceBox, ReverbDeviceBox, StereoToolDeviceBox, TidalDeviceBox, UnknownAudioEffectDeviceBox, UnknownMidiEffectDeviceBox, VelocityDeviceBox, ZeitgeistDeviceBox } from "@opendaw/studio-boxes";
2
- export type EffectBox = ArpeggioDeviceBox | PitchDeviceBox | VelocityDeviceBox | ZeitgeistDeviceBox | UnknownMidiEffectDeviceBox | MaximizerDeviceBox | DelayDeviceBox | ReverbDeviceBox | RevampDeviceBox | StereoToolDeviceBox | TidalDeviceBox | ModularDeviceBox | UnknownAudioEffectDeviceBox | CompressorDeviceBox | GateDeviceBox | CrusherDeviceBox | FoldDeviceBox | DattorroReverbDeviceBox;
1
+ import { ArpeggioDeviceBox, MaximizerDeviceBox, CompressorDeviceBox, CrusherDeviceBox, DattorroReverbDeviceBox, DelayDeviceBox, FoldDeviceBox, GateDeviceBox, ModularDeviceBox, NeuralAmpDeviceBox, PitchDeviceBox, RevampDeviceBox, ReverbDeviceBox, StereoToolDeviceBox, TidalDeviceBox, UnknownAudioEffectDeviceBox, UnknownMidiEffectDeviceBox, VelocityDeviceBox, ZeitgeistDeviceBox } from "@opendaw/studio-boxes";
2
+ export type EffectBox = ArpeggioDeviceBox | PitchDeviceBox | VelocityDeviceBox | ZeitgeistDeviceBox | UnknownMidiEffectDeviceBox | MaximizerDeviceBox | DelayDeviceBox | ReverbDeviceBox | RevampDeviceBox | StereoToolDeviceBox | TidalDeviceBox | ModularDeviceBox | UnknownAudioEffectDeviceBox | CompressorDeviceBox | GateDeviceBox | CrusherDeviceBox | FoldDeviceBox | DattorroReverbDeviceBox | NeuralAmpDeviceBox;
3
3
  //# sourceMappingURL=EffectBox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EffectBox.d.ts","sourceRoot":"","sources":["../src/EffectBox.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,2BAA2B,EAC3B,0BAA0B,EAC1B,iBAAiB,EACjB,kBAAkB,EACrB,MAAM,uBAAuB,CAAA;AAE9B,MAAM,MAAM,SAAS,GACf,iBAAiB,GAAG,cAAc,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,0BAA0B,GACxG,kBAAkB,GAAG,cAAc,GAAG,eAAe,GAAG,eAAe,GAAG,mBAAmB,GAAG,cAAc,GAC9G,gBAAgB,GAAG,2BAA2B,GAAG,mBAAmB,GAAG,aAAa,GACpF,gBAAgB,GAAG,aAAa,GAAG,uBAAuB,CAAA"}
1
+ {"version":3,"file":"EffectBox.d.ts","sourceRoot":"","sources":["../src/EffectBox.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,2BAA2B,EAC3B,0BAA0B,EAC1B,iBAAiB,EACjB,kBAAkB,EACrB,MAAM,uBAAuB,CAAA;AAE9B,MAAM,MAAM,SAAS,GACf,iBAAiB,GAAG,cAAc,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,0BAA0B,GACxG,kBAAkB,GAAG,cAAc,GAAG,eAAe,GAAG,eAAe,GAAG,mBAAmB,GAAG,cAAc,GAC9G,gBAAgB,GAAG,2BAA2B,GAAG,mBAAmB,GAAG,aAAa,GACpF,gBAAgB,GAAG,aAAa,GAAG,uBAAuB,GAAG,kBAAkB,CAAA"}
@@ -15,6 +15,7 @@ export declare namespace EffectFactories {
15
15
  const Fold: EffectFactory;
16
16
  const Tidal: EffectFactory;
17
17
  const Revamp: EffectFactory;
18
+ const NeuralAmp: EffectFactory;
18
19
  const Modular: EffectFactory;
19
20
  const MidiNamed: {
20
21
  Arpeggio: EffectFactory;
@@ -1 +1 @@
1
- {"version":3,"file":"EffectFactories.d.ts","sourceRoot":"","sources":["../src/EffectFactories.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAG7C,yBAAiB,eAAe,CAAC;IACtB,MAAM,QAAQ,EAAE,aAYtB,CAAA;IAEM,MAAM,KAAK,EAAE,aAYnB,CAAA;IAEM,MAAM,QAAQ,EAAE,aAYtB,CAAA;IAEM,MAAM,SAAS,EAAE,aAsBvB,CAAA;IAEM,MAAM,UAAU,EAAE,aAaxB,CAAA;IAEM,MAAM,KAAK,EAAE,aAcnB,CAAA;IAEM,MAAM,cAAc,EAAE,aAa5B,CAAA;IAEM,MAAM,SAAS,EAAE,aAavB,CAAA;IAEM,MAAM,UAAU,EAAE,aAaxB,CAAA;IAEM,MAAM,IAAI,EAAE,aAalB,CAAA;IAEM,MAAM,MAAM,EAAE,aAcpB,CAAA;IAEM,MAAM,OAAO,EAAE,aAarB,CAAA;IAEM,MAAM,IAAI,EAAE,aAalB,CAAA;IAEM,MAAM,KAAK,EAAE,aAcnB,CAAA;IAEM,MAAM,MAAM,EAAE,aAapB,CAAA;IAEM,MAAM,OAAO,EAAE,aAqCrB,CAAA;IAEM,MAAM,SAAS;;;;;KAAyC,CAAA;IACxD,MAAM,UAAU;;;;;;;;;;;;KAEtB,CAAA;IACM,MAAM,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAA4B,CAAA;IACjF,MAAM,SAAS,EAAE,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAA6B,CAAA;IACnF,MAAM,WAAW;;;;;;;;;;;;;;;;KAAgC,CAAA;IACxD,KAAY,cAAc,GAAG,MAAM,OAAO,SAAS,CAAA;IACnD,KAAY,eAAe,GAAG,MAAM,OAAO,UAAU,CAAA;CACxD"}
1
+ {"version":3,"file":"EffectFactories.d.ts","sourceRoot":"","sources":["../src/EffectFactories.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAG7C,yBAAiB,eAAe,CAAC;IACtB,MAAM,QAAQ,EAAE,aAYtB,CAAA;IAEM,MAAM,KAAK,EAAE,aAYnB,CAAA;IAEM,MAAM,QAAQ,EAAE,aAYtB,CAAA;IAEM,MAAM,SAAS,EAAE,aAsBvB,CAAA;IAEM,MAAM,UAAU,EAAE,aAaxB,CAAA;IAEM,MAAM,KAAK,EAAE,aAcnB,CAAA;IAEM,MAAM,cAAc,EAAE,aAa5B,CAAA;IAEM,MAAM,SAAS,EAAE,aAavB,CAAA;IAEM,MAAM,UAAU,EAAE,aAaxB,CAAA;IAEM,MAAM,IAAI,EAAE,aAalB,CAAA;IAEM,MAAM,MAAM,EAAE,aAcpB,CAAA;IAEM,MAAM,OAAO,EAAE,aAarB,CAAA;IAEM,MAAM,IAAI,EAAE,aAalB,CAAA;IAEM,MAAM,KAAK,EAAE,aAcnB,CAAA;IAEM,MAAM,MAAM,EAAE,aAapB,CAAA;IAEM,MAAM,SAAS,EAAE,aAavB,CAAA;IAEM,MAAM,OAAO,EAAE,aAqCrB,CAAA;IAEM,MAAM,SAAS;;;;;KAAyC,CAAA;IACxD,MAAM,UAAU;;;;;;;;;;;;KAEtB,CAAA;IACM,MAAM,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAA4B,CAAA;IACjF,MAAM,SAAS,EAAE,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAA6B,CAAA;IACnF,MAAM,WAAW;;;;;;;;;;;;;;;;KAAgC,CAAA;IACxD,KAAY,cAAc,GAAG,MAAM,OAAO,SAAS,CAAA;IACnD,KAAY,eAAe,GAAG,MAAM,OAAO,UAAU,CAAA;CACxD"}
@@ -1,5 +1,5 @@
1
1
  import { UUID } from "@opendaw/lib-std";
2
- import { ArpeggioDeviceBox, CompressorDeviceBox, CrusherDeviceBox, DattorroReverbDeviceBox, DelayDeviceBox, FoldDeviceBox, GateDeviceBox, GrooveShuffleBox, MaximizerDeviceBox, ModularAudioInputBox, ModularAudioOutputBox, ModularBox, ModularDeviceBox, ModuleConnectionBox, PitchDeviceBox, RevampDeviceBox, ReverbDeviceBox, StereoToolDeviceBox, TidalDeviceBox, VelocityDeviceBox, ZeitgeistDeviceBox } from "@opendaw/studio-boxes";
2
+ import { ArpeggioDeviceBox, CompressorDeviceBox, CrusherDeviceBox, DattorroReverbDeviceBox, DelayDeviceBox, FoldDeviceBox, GateDeviceBox, GrooveShuffleBox, MaximizerDeviceBox, ModularAudioInputBox, ModularAudioOutputBox, ModularBox, ModularDeviceBox, ModuleConnectionBox, NeuralAmpDeviceBox, PitchDeviceBox, RevampDeviceBox, ReverbDeviceBox, StereoToolDeviceBox, TidalDeviceBox, VelocityDeviceBox, ZeitgeistDeviceBox } from "@opendaw/studio-boxes";
3
3
  import { IconSymbol } from "@opendaw/studio-enums";
4
4
  import { DeviceManualUrls } from "@opendaw/studio-adapters";
5
5
  import { EffectParameterDefaults } from "./EffectParameterDefaults";
@@ -213,6 +213,19 @@ export var EffectFactories;
213
213
  box.host.refer(hostField);
214
214
  })
215
215
  };
216
+ EffectFactories.NeuralAmp = {
217
+ defaultName: "Neural Amp",
218
+ defaultIcon: IconSymbol.NeuralAmp,
219
+ description: "Neural network-based amp modeling using NAM models",
220
+ manualPage: DeviceManualUrls.NeuralAmp,
221
+ separatorBefore: false,
222
+ type: "audio",
223
+ create: ({ boxGraph }, hostField, index) => NeuralAmpDeviceBox.create(boxGraph, UUID.generate(), box => {
224
+ box.label.setValue("Neural Amp");
225
+ box.index.setValue(index);
226
+ box.host.refer(hostField);
227
+ })
228
+ };
216
229
  EffectFactories.Modular = {
217
230
  defaultName: "🔇 Create New Modular Audio Effect (inaudible yet)",
218
231
  defaultIcon: IconSymbol.Box,
@@ -253,7 +266,7 @@ export var EffectFactories;
253
266
  };
254
267
  EffectFactories.MidiNamed = { Arpeggio: EffectFactories.Arpeggio, Pitch: EffectFactories.Pitch, Velocity: EffectFactories.Velocity, Zeitgeist: EffectFactories.Zeitgeist };
255
268
  EffectFactories.AudioNamed = {
256
- StereoTool: EffectFactories.StereoTool, Compressor: EffectFactories.Compressor, Gate: EffectFactories.Gate, Delay: EffectFactories.Delay, Reverb: EffectFactories.Reverb, DattorroReverb: EffectFactories.DattorroReverb, Revamp: EffectFactories.Revamp, Crusher: EffectFactories.Crusher, Fold: EffectFactories.Fold, Tidal: EffectFactories.Tidal, Maximizer: EffectFactories.Maximizer
269
+ StereoTool: EffectFactories.StereoTool, Compressor: EffectFactories.Compressor, Gate: EffectFactories.Gate, Delay: EffectFactories.Delay, Reverb: EffectFactories.Reverb, DattorroReverb: EffectFactories.DattorroReverb, Revamp: EffectFactories.Revamp, Crusher: EffectFactories.Crusher, Fold: EffectFactories.Fold, Tidal: EffectFactories.Tidal, Maximizer: EffectFactories.Maximizer /*NeuralAmp*/
257
270
  };
258
271
  EffectFactories.MidiList = Object.values(EffectFactories.MidiNamed);
259
272
  EffectFactories.AudioList = Object.values(EffectFactories.AudioNamed);
@@ -1 +1 @@
1
- {"version":3,"file":"EngineWorklet.d.ts","sourceRoot":"","sources":["../src/EngineWorklet.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,GAAG,EACH,sBAAsB,EAEtB,QAAQ,EACR,eAAe,EACf,QAAQ,EAER,YAAY,EAGZ,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,SAAS,EAAE,GAAG,EAAE,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAIrD,OAAO,EACH,gBAAgB,EAIhB,cAAc,EAKd,wBAAwB,EACxB,UAAU,EACV,eAAe,EACf,gBAAgB,EACnB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAIjC,qBAAa,aAAc,SAAQ,gBAAiB,YAAW,MAAM;;IACjE,MAAM,CAAC,EAAE,EAAE,GAAG,CAAQ;IAEtB,QAAQ,CAAC,EAAE,SAAqB;gBAsBpB,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,OAAO,EAChB,mBAAmB,CAAC,EAAE,wBAAwB,EAC9C,OAAO,CAAC,EAAE,gBAAgB;IAqItC,IAAI,IAAI,IAAI;IACZ,IAAI,CAAC,KAAK,GAAE,OAAe,GAAG,IAAI;IAClC,WAAW,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI;IACjC,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAC7C,aAAa,IAAI,IAAI;IACrB,KAAK,IAAI,IAAI;IACb,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI;IACZ,cAAc,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAInD,IAAI,SAAS,IAAI,eAAe,CAAC,OAAO,CAAC,CAAyB;IAClE,IAAI,WAAW,IAAI,eAAe,CAAC,OAAO,CAAC,CAA2B;IACtE,IAAI,YAAY,IAAI,eAAe,CAAC,OAAO,CAAC,CAA4B;IACxE,IAAI,qBAAqB,IAAI,eAAe,CAAC,MAAM,CAAC,CAAqC;IACzF,IAAI,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,CAAwB;IAC7D,IAAI,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,CAAmB;IAClD,IAAI,iBAAiB,IAAI,sBAAsB,CAAC,MAAM,CAAC,CAAiC;IACxF,IAAI,WAAW,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAA2B;IAC1F,IAAI,OAAO,IAAI,OAAO,CAAuB;IAC7C,IAAI,WAAW,IAAI,eAAe,CAAC,cAAc,CAAC,CAA2B;IAE7E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IACxB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;IACxC,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IACpC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,YAAY;IAC5D,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI;IACxC,gBAAgB,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI;IAI1D,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI;IAG3D,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,YAAY;IAQ7E,SAAS,IAAI,IAAI;CAKpB"}
1
+ {"version":3,"file":"EngineWorklet.d.ts","sourceRoot":"","sources":["../src/EngineWorklet.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,GAAG,EACH,sBAAsB,EAEtB,QAAQ,EACR,eAAe,EACf,QAAQ,EAER,YAAY,EAGZ,IAAI,EACP,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,SAAS,EAAE,GAAG,EAAE,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAIrD,OAAO,EACH,gBAAgB,EAIhB,cAAc,EAKd,wBAAwB,EACxB,UAAU,EACV,eAAe,EACf,gBAAgB,EACnB,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAA;AAC/B,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAIjC,qBAAa,aAAc,SAAQ,gBAAiB,YAAW,MAAM;;IACjE,MAAM,CAAC,EAAE,EAAE,GAAG,CAAQ;IAEtB,QAAQ,CAAC,EAAE,SAAqB;gBAsBpB,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,OAAO,EAChB,mBAAmB,CAAC,EAAE,wBAAwB,EAC9C,OAAO,CAAC,EAAE,gBAAgB;IA0ItC,IAAI,IAAI,IAAI;IACZ,IAAI,CAAC,KAAK,GAAE,OAAe,GAAG,IAAI;IAClC,WAAW,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI;IACjC,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAC7C,aAAa,IAAI,IAAI;IACrB,KAAK,IAAI,IAAI;IACb,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI;IACZ,cAAc,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAInD,IAAI,SAAS,IAAI,eAAe,CAAC,OAAO,CAAC,CAAyB;IAClE,IAAI,WAAW,IAAI,eAAe,CAAC,OAAO,CAAC,CAA2B;IACtE,IAAI,YAAY,IAAI,eAAe,CAAC,OAAO,CAAC,CAA4B;IACxE,IAAI,qBAAqB,IAAI,eAAe,CAAC,MAAM,CAAC,CAAqC;IACzF,IAAI,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,CAAwB;IAC7D,IAAI,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,CAAmB;IAClD,IAAI,iBAAiB,IAAI,sBAAsB,CAAC,MAAM,CAAC,CAAiC;IACxF,IAAI,WAAW,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAA2B;IAC1F,IAAI,OAAO,IAAI,OAAO,CAAuB;IAC7C,IAAI,WAAW,IAAI,eAAe,CAAC,cAAc,CAAC,CAA2B;IAE7E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IACxB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;IACxC,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IACpC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,YAAY;IAC5D,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,IAAI;IACxC,gBAAgB,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI;IAI1D,gBAAgB,CAAC,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI;IAG3D,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,YAAY;IAQ7E,SAAS,IAAI,IAAI;CAKpB"}
@@ -124,6 +124,11 @@ export class EngineWorklet extends AudioWorkletNode {
124
124
  });
125
125
  });
126
126
  },
127
+ fetchNamWasm: async () => {
128
+ const url = new URL("@opendaw/nam-wasm/nam.wasm", import.meta.url);
129
+ const response = await fetch(url);
130
+ return response.arrayBuffer();
131
+ },
127
132
  notifyClipSequenceChanges: (changes) => {
128
133
  changes.stopped.forEach(uuid => {
129
134
  for (let i = 0; i < this.#playingClips.length; i++) {
@@ -1 +1 @@
1
- {"version":3,"file":"OfflineEngineRenderer.d.ts","sourceRoot":"","sources":["../src/OfflineEngineRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,GAAG,EAAa,MAAM,EAAS,QAAQ,EAAmB,MAAM,kBAAkB,CAAA;AAClG,OAAO,EAAC,SAAS,EAAO,MAAM,kBAAkB,CAAA;AAEhD,OAAO,EAGH,wBAAwB,EAIxB,yBAAyB,EAC5B,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAOjC,qBAAa,qBAAqB;;IAC9B,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKjC,MAAM,CAAC,YAAY,IAAI,MAAM;WAIhB,MAAM,CAAC,MAAM,EAAE,OAAO,EACf,sBAAsB,EAAE,MAAM,CAAC,wBAAwB,CAAC,EACxD,UAAU,GAAE,GAAY,GACzC,OAAO,CAAC,qBAAqB,CAAC;WA8GpB,KAAK,CAAC,MAAM,EAAE,OAAO,EACf,sBAAsB,EAAE,MAAM,CAAC,wBAAwB,CAAC,EACxD,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAC1B,WAAW,CAAC,EAAE,WAAW,EACzB,UAAU,GAAE,GAAY,GACxC,OAAO,CAAC,SAAS,CAAC;IAwBrB,OAAO;IAkBP,IAAI,UAAU,IAAI,GAAG,CAA0B;IAC/C,IAAI,gBAAgB,IAAI,GAAG,CAAgC;IAC3D,IAAI,WAAW,IAAI,GAAG,CAA2B;IAEjD,IAAI,IAAI,IAAI;IAIZ,IAAI,IAAI,IAAI;IAKZ,SAAS,IAAI,IAAI;IAKX,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAM3C,MAAM,CACR,MAAM,EAAE,yBAAyB,EACjC,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAC1B,WAAW,CAAC,EAAE,WAAW,GAC1B,OAAO,CAAC,SAAS,CAAC;CAkCxB"}
1
+ {"version":3,"file":"OfflineEngineRenderer.d.ts","sourceRoot":"","sources":["../src/OfflineEngineRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,GAAG,EAAa,MAAM,EAAS,QAAQ,EAAmB,MAAM,kBAAkB,CAAA;AAClG,OAAO,EAAC,SAAS,EAAO,MAAM,kBAAkB,CAAA;AAEhD,OAAO,EAGH,wBAAwB,EAIxB,yBAAyB,EAC5B,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AAOjC,qBAAa,qBAAqB;;IAC9B,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKjC,MAAM,CAAC,YAAY,IAAI,MAAM;WAIhB,MAAM,CAAC,MAAM,EAAE,OAAO,EACf,sBAAsB,EAAE,MAAM,CAAC,wBAAwB,CAAC,EACxD,UAAU,GAAE,GAAY,GACzC,OAAO,CAAC,qBAAqB,CAAC;WAmHpB,KAAK,CAAC,MAAM,EAAE,OAAO,EACf,sBAAsB,EAAE,MAAM,CAAC,wBAAwB,CAAC,EACxD,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAC1B,WAAW,CAAC,EAAE,WAAW,EACzB,UAAU,GAAE,GAAY,GACxC,OAAO,CAAC,SAAS,CAAC;IAwBrB,OAAO;IAkBP,IAAI,UAAU,IAAI,GAAG,CAA0B;IAC/C,IAAI,gBAAgB,IAAI,GAAG,CAAgC;IAC3D,IAAI,WAAW,IAAI,GAAG,CAA2B;IAEjD,IAAI,IAAI,IAAI;IAIZ,IAAI,IAAI,IAAI;IAKZ,SAAS,IAAI,IAAI;IAKX,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAM3C,MAAM,CACR,MAAM,EAAE,yBAAyB,EACjC,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAC1B,WAAW,CAAC,EAAE,WAAW,GAC1B,OAAO,CAAC,SAAS,CAAC;CAkCxB"}
@@ -69,6 +69,11 @@ export class OfflineEngineRenderer {
69
69
  }
70
70
  });
71
71
  }),
72
+ fetchNamWasm: async () => {
73
+ const url = new URL("@opendaw/nam-wasm/nam.wasm", import.meta.url);
74
+ const response = await fetch(url);
75
+ return response.arrayBuffer();
76
+ },
72
77
  notifyClipSequenceChanges: () => { },
73
78
  switchMarkerState: () => { }
74
79
  });
@@ -1 +1 @@
1
- {"version":3,"file":"CaptureAudio.d.ts","sourceRoot":"","sources":["../../src/capture/CaptureAudio.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,uBAAuB,EAEvB,MAAM,EAEN,UAAU,EACb,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAC,YAAY,EAAE,eAAe,EAAC,MAAM,uBAAuB,CAAA;AACnE,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAA;AAI/C,qBAAa,YAAa,SAAQ,OAAO,CAAC,eAAe,CAAC;;gBAa1C,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe;IAkCjG,IAAI,YAAY,IAAI,OAAO,CAA4B;IACvD,IAAI,YAAY,CAAC,KAAK,EAAE,OAAO,EAS9B;IACD,IAAI,MAAM,IAAI,MAAM,CAAsB;IAC1C,IAAI,eAAe,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAA+B;IACnE,IAAI,eAAe,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAmD;IACnF,IAAI,MAAM,IAAI,uBAAuB,CAAC,WAAW,CAAC,CAAsB;IACxE,IAAI,cAAc,IAAI,MAAM,CAAC,MAAM,CAAC,CAEnC;IACD,IAAI,KAAK,IAAI,MAAM,CAAsE;IACzF,IAAI,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,CAA+D;IAChG,IAAI,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAE/C;IACD,IAAI,UAAU,IAAI,MAAM,CAAC,SAAS,CAAC,CAAiD;IACpF,IAAI,qBAAqB,IAAI,MAAM,CAAsD;IAEnF,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBvC,cAAc,IAAI,UAAU;CAyG/B"}
1
+ {"version":3,"file":"CaptureAudio.d.ts","sourceRoot":"","sources":["../../src/capture/CaptureAudio.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,uBAAuB,EAEvB,MAAM,EAEN,UAAU,EACb,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAC,YAAY,EAAE,eAAe,EAAC,MAAM,uBAAuB,CAAA;AACnE,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAA;AACjC,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAA;AAM/C,qBAAa,YAAa,SAAQ,OAAO,CAAC,eAAe,CAAC;;gBAc1C,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe;IAkCjG,IAAI,YAAY,IAAI,OAAO,CAA4B;IACvD,IAAI,YAAY,CAAC,KAAK,EAAE,OAAO,EAS9B;IACD,IAAI,MAAM,IAAI,MAAM,CAAsB;IAC1C,IAAI,eAAe,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAA+B;IACnE,IAAI,eAAe,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAmD;IACnF,IAAI,MAAM,IAAI,uBAAuB,CAAC,WAAW,CAAC,CAAsB;IACxE,IAAI,cAAc,IAAI,MAAM,CAAC,MAAM,CAAC,CAEnC;IACD,IAAI,KAAK,IAAI,MAAM,CAAsE;IACzF,IAAI,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,CAA+D;IAChG,IAAI,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAE/C;IACD,IAAI,UAAU,IAAI,MAAM,CAAC,SAAS,CAAC,CAAiD;IACpF,IAAI,qBAAqB,IAAI,MAAM,CAAsD;IAEnF,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA2BvC,cAAc,IAAI,UAAU;CAwG/B"}
@@ -4,6 +4,7 @@ import { Promises } from "@opendaw/lib-runtime";
4
4
  import { Capture } from "./Capture";
5
5
  import { RecordAudio } from "./RecordAudio";
6
6
  import { AudioDevices } from "../AudioDevices";
7
+ import { RenderQuantum } from "../RenderQuantum";
7
8
  export class CaptureAudio extends Capture {
8
9
  #stream;
9
10
  #streamGenerator;
@@ -11,6 +12,7 @@ export class CaptureAudio extends Capture {
11
12
  #requestChannels = Option.None;
12
13
  #gainDb = 0.0;
13
14
  #audioChain = null;
15
+ #preparedWorklet = null;
14
16
  constructor(manager, audioUnitBox, captureAudioBox) {
15
17
  super(manager, audioUnitBox, captureAudioBox);
16
18
  this.#stream = new MutableObservableOption();
@@ -68,7 +70,7 @@ export class CaptureAudio extends Capture {
68
70
  get effectiveChannelCount() { return this.#audioChain?.gainNode.channelCount ?? 1; }
69
71
  async prepareRecording() {
70
72
  const { project } = this.manager;
71
- const { env: { audioContext } } = project;
73
+ const { env: { audioContext, audioWorklets, sampleManager } } = project;
72
74
  if (isUndefined(audioContext.outputLatency)) {
73
75
  const approved = RuntimeNotifier.approve({
74
76
  headline: "Warning",
@@ -80,20 +82,29 @@ export class CaptureAudio extends Capture {
80
82
  return Promise.reject("Recording cancelled");
81
83
  }
82
84
  }
83
- return this.#streamGenerator();
85
+ await this.#streamGenerator();
86
+ const audioChain = this.#audioChain;
87
+ if (!isDefined(audioChain)) {
88
+ return Promise.reject("No audio chain available for recording.");
89
+ }
90
+ const { gainNode } = audioChain;
91
+ const channelCount = gainNode.channelCount;
92
+ const recordingWorklet = audioWorklets.createRecording(channelCount, RenderQuantum);
93
+ sampleManager.record(recordingWorklet);
94
+ gainNode.connect(recordingWorklet);
95
+ this.#preparedWorklet = recordingWorklet;
84
96
  }
85
97
  startRecording() {
86
98
  const { project } = this.manager;
87
- const { env: { audioContext, audioWorklets, sampleManager } } = project;
99
+ const { env: { audioContext, sampleManager } } = project;
88
100
  const audioChain = this.#audioChain;
89
- if (!isDefined(audioChain)) {
90
- console.warn("No audio chain available for recording.");
101
+ const recordingWorklet = this.#preparedWorklet;
102
+ if (!isDefined(audioChain) || !isDefined(recordingWorklet)) {
103
+ console.warn("No audio chain or worklet available for recording.");
91
104
  return Terminable.Empty;
92
105
  }
106
+ this.#preparedWorklet = null;
93
107
  const { gainNode } = audioChain;
94
- const channelCount = gainNode.channelCount;
95
- const numChunks = 128;
96
- const recordingWorklet = audioWorklets.createRecording(channelCount, numChunks);
97
108
  return RecordAudio.start({
98
109
  recordingWorklet,
99
110
  sourceNode: gainNode,
@@ -1 +1 @@
1
- {"version":3,"file":"RecordAudio.d.ts","sourceRoot":"","sources":["../../src/capture/RecordAudio.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2C,UAAU,EAAmB,MAAM,kBAAkB,CAAA;AAGvG,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,UAAU,EAAE,SAAS,CAAA;QACrB,aAAa,EAAE,mBAAmB,CAAA;QAClC,OAAO,EAAE,OAAO,CAAA;QAChB,OAAO,EAAE,OAAO,CAAA;QAChB,aAAa,EAAE,MAAM,CAAA;KACxB,CAAA;IAOD,MAAM,CAAC,MAAM,KAAK,GACd,kFAAgF,kBAAkB,KAChG,UAkJL,CAAA;;CACJ"}
1
+ {"version":3,"file":"RecordAudio.d.ts","sourceRoot":"","sources":["../../src/capture/RecordAudio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,UAAU,EAA6B,MAAM,kBAAkB,CAAA;AAG3H,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,UAAU,EAAE,SAAS,CAAA;QACrB,aAAa,EAAE,mBAAmB,CAAA;QAClC,OAAO,EAAE,OAAO,CAAA;QAChB,OAAO,EAAE,OAAO,CAAA;QAChB,aAAa,EAAE,MAAM,CAAA;KACxB,CAAA;IAOD,MAAM,CAAC,MAAM,KAAK,GACd,kFAAgF,kBAAkB,KAChG,UAkKL,CAAA;;CACJ"}
@@ -1,4 +1,4 @@
1
- import { asInstanceOf, Option, quantizeFloor, Terminable, Terminator, UUID } from "@opendaw/lib-std";
1
+ import { asInstanceOf, Option, quantizeFloor, Terminable, Terminator, tryCatch, UUID } from "@opendaw/lib-std";
2
2
  import { PPQN, TimeBase } from "@opendaw/lib-dsp";
3
3
  import { AudioFileBox, AudioRegionBox, TrackBox, ValueEventCollectionBox } from "@opendaw/studio-boxes";
4
4
  import { ColorCodes, TrackType, UnionBoxTypes } from "@opendaw/studio-adapters";
@@ -10,12 +10,13 @@ export var RecordAudio;
10
10
  const beats = PPQN.fromSignature(1, project.timelineBox.signature.denominator.getValue());
11
11
  const { editing, engine, boxGraph, timelineBox } = project;
12
12
  const originalUuid = recordingWorklet.uuid;
13
- sampleManager.record(recordingWorklet);
13
+ // Note: sampleManager.record() and sourceNode.connect() are called in prepareRecording
14
14
  let fileBox = Option.None;
15
15
  let currentTake = Option.None;
16
16
  let lastPosition = 0;
17
17
  let currentWaveformOffset = outputLatency;
18
18
  let takeNumber = 0;
19
+ let hadCountIn = false;
19
20
  const { env: { audioContext: { sampleRate } }, engine: { preferences: { settings: { recording } } } } = project;
20
21
  const { loopArea } = timelineBox;
21
22
  const createFileBox = () => {
@@ -28,9 +29,9 @@ export var RecordAudio;
28
29
  const fileName = `Recording-${fileDateString}`;
29
30
  return AudioFileBox.create(boxGraph, originalUuid, box => box.fileName.setValue(fileName));
30
31
  };
31
- const createTakeRegion = (position, waveformOffset, forceNewTrack) => {
32
+ const createTakeRegion = (position, waveformOffset, excludeTrack) => {
32
33
  takeNumber++;
33
- const trackBox = RecordTrack.findOrCreate(editing, capture.audioUnitBox, TrackType.Audio, forceNewTrack);
34
+ const trackBox = RecordTrack.findOrCreate(editing, capture.audioUnitBox, TrackType.Audio, excludeTrack);
34
35
  const collectionBox = ValueEventCollectionBox.create(boxGraph, UUID.generate());
35
36
  const regionBox = AudioRegionBox.create(boxGraph, UUID.generate(), box => {
36
37
  box.file.refer(fileBox.unwrap());
@@ -92,10 +93,11 @@ export var RecordAudio;
92
93
  }
93
94
  };
94
95
  const startNewTake = (position) => {
95
- currentTake = Option.wrap(createTakeRegion(position, currentWaveformOffset, true));
96
+ const previousTrack = currentTake.mapOr(take => take.trackBox, null);
97
+ currentTake = Option.wrap(createTakeRegion(position, currentWaveformOffset, previousTrack));
96
98
  };
97
99
  terminator.ownAll(Terminable.create(() => {
98
- sourceNode.disconnect(recordingWorklet);
100
+ tryCatch(() => sourceNode.disconnect(recordingWorklet));
99
101
  if (recordingWorklet.numberOfFrames === 0 || fileBox.isEmpty()) {
100
102
  console.debug("Abort recording audio.");
101
103
  sampleManager.remove(originalUuid);
@@ -108,10 +110,18 @@ export var RecordAudio;
108
110
  fileBox.ifSome(fb => fb.endInSeconds.setValue(recordingWorklet.numberOfFrames / sampleRate));
109
111
  }
110
112
  }), engine.position.catchupAndSubscribe(owner => {
111
- if (!engine.isRecording.getValue()) {
113
+ const isCountingIn = engine.isCountingIn.getValue();
114
+ const isRecording = engine.isRecording.getValue();
115
+ if (!isCountingIn && !isRecording) {
112
116
  return;
113
117
  }
114
118
  const currentPosition = owner.getValue();
119
+ // During count-in, just track that we had one
120
+ if (isCountingIn) {
121
+ hadCountIn = true;
122
+ return;
123
+ }
124
+ // From here on, isRecording is true
115
125
  const loopEnabled = loopArea.enabled.getValue();
116
126
  const loopFrom = loopArea.from.getValue();
117
127
  const allowTakes = project.engine.preferences.settings.recording.allowTakes;
@@ -126,13 +136,19 @@ export var RecordAudio;
126
136
  }, false);
127
137
  }
128
138
  lastPosition = currentPosition;
139
+ // Create fileBox and region together when recording starts
129
140
  if (fileBox.isEmpty()) {
130
- sourceNode.connect(recordingWorklet);
141
+ // Capture all frames recorded before actual recording (including count-in)
142
+ const preRecordingFrames = recordingWorklet.numberOfFrames;
143
+ const preRecordingSeconds = preRecordingFrames / sampleRate;
144
+ // If there was count-in, use pre-recording frames as offset; otherwise use outputLatency
145
+ const waveformOffset = hadCountIn ? preRecordingSeconds : outputLatency;
131
146
  editing.modify(() => {
132
147
  fileBox = Option.wrap(createFileBox());
133
148
  const position = quantizeFloor(currentPosition, beats);
134
- currentTake = Option.wrap(createTakeRegion(position, currentWaveformOffset, false));
149
+ currentTake = Option.wrap(createTakeRegion(position, waveformOffset, null));
135
150
  }, false);
151
+ currentWaveformOffset = waveformOffset;
136
152
  }
137
153
  currentTake.ifSome(({ regionBox }) => {
138
154
  editing.modify(() => {
@@ -1 +1 @@
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,UAkJvE,CAAA;;CACJ"}
1
+ {"version":3,"file":"RecordMidi.d.ts","sourceRoot":"","sources":["../../src/capture/RecordMidi.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,QAAQ,EAKR,UAAU,EAGb,MAAM,kBAAkB,CAAA;AAGzB,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,UAmJvE,CAAA;;CACJ"}
@@ -17,17 +17,17 @@ export var RecordMidi;
17
17
  let currentTake = Option.None;
18
18
  let lastPosition = 0;
19
19
  let positionOffset = 0;
20
- let takeNumber = 0;
21
- const createTakeRegion = (position, forceNewTrack) => {
22
- takeNumber++;
23
- const trackBox = RecordTrack.findOrCreate(editing, capture.audioUnitBox, TrackType.Notes, forceNewTrack);
20
+ let takeCount = 0;
21
+ const createTakeRegion = (position, excludeTrack) => {
22
+ takeCount++;
23
+ const trackBox = RecordTrack.findOrCreate(editing, capture.audioUnitBox, TrackType.Notes, excludeTrack);
24
24
  const collection = NoteEventCollectionBox.create(boxGraph, UUID.generate());
25
25
  const regionBox = NoteRegionBox.create(boxGraph, UUID.generate(), box => {
26
26
  box.regions.refer(trackBox.regions);
27
27
  box.events.refer(collection.owners);
28
28
  box.position.setValue(position);
29
29
  box.hue.setValue(ColorCodes.forTrackType(TrackType.Notes));
30
- box.label.setValue(`Take ${takeNumber}`);
30
+ box.label.setValue(`Take ${takeCount}`);
31
31
  });
32
32
  capture.addRecordedRegion(regionBox);
33
33
  project.selection.select(regionBox);
@@ -80,7 +80,8 @@ export var RecordMidi;
80
80
  }
81
81
  };
82
82
  const startNewTake = (position) => {
83
- currentTake = Option.wrap(createTakeRegion(position, true));
83
+ const previousTrack = currentTake.mapOr(take => take.trackBox, null);
84
+ currentTake = Option.wrap(createTakeRegion(position, previousTrack));
84
85
  };
85
86
  terminator.own(position.catchupAndSubscribe(owner => {
86
87
  if (!isRecording.getValue()) {
@@ -106,7 +107,7 @@ export var RecordMidi;
106
107
  if (currentTake.isEmpty()) {
107
108
  editing.modify(() => {
108
109
  const pos = quantizeFloor(currentPosition, beats);
109
- currentTake = Option.wrap(createTakeRegion(pos, false));
110
+ currentTake = Option.wrap(createTakeRegion(pos, null));
110
111
  }, false);
111
112
  }
112
113
  currentTake.ifSome(({ regionBox, collection }) => {
@@ -1,7 +1,8 @@
1
1
  import { AudioUnitBox, TrackBox } from "@opendaw/studio-boxes";
2
+ import { Nullable } from "@opendaw/lib-std";
2
3
  import { TrackType } from "@opendaw/studio-adapters";
3
4
  import { BoxEditing } from "@opendaw/lib-box";
4
5
  export declare namespace RecordTrack {
5
- const findOrCreate: (editing: BoxEditing, audioUnitBox: AudioUnitBox, type: TrackType, forceCreate?: boolean) => TrackBox;
6
+ const findOrCreate: (editing: BoxEditing, audioUnitBox: AudioUnitBox, type: TrackType, excludeTrack?: Nullable<TrackBox>) => TrackBox;
6
7
  }
7
8
  //# sourceMappingURL=RecordTrack.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RecordTrack.d.ts","sourceRoot":"","sources":["../../src/capture/RecordTrack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAE5D,OAAO,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAA;AAE3C,yBAAiB,WAAW,CAAC;IAClB,MAAM,YAAY,GAAI,SAAS,UAAU,EAAE,cAAc,YAAY,EAAE,MAAM,SAAS,EAAE,cAAa,OAAe,KAAG,QAiB7H,CAAA;CACJ"}
1
+ {"version":3,"file":"RecordTrack.d.ts","sourceRoot":"","sources":["../../src/capture/RecordTrack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAC5D,OAAO,EAAoB,QAAQ,EAAO,MAAM,kBAAkB,CAAA;AAClE,OAAO,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAA;AAE3C,yBAAiB,WAAW,CAAC;IAClB,MAAM,YAAY,GAAI,SAAS,UAAU,EACnB,cAAc,YAAY,EAC1B,MAAM,SAAS,EACf,eAAc,QAAQ,CAAC,QAAQ,CAAQ,KAAG,QAmBtE,CAAA;CACJ"}
@@ -2,11 +2,13 @@ import { TrackBox } from "@opendaw/studio-boxes";
2
2
  import { asInstanceOf, UUID } from "@opendaw/lib-std";
3
3
  export var RecordTrack;
4
4
  (function (RecordTrack) {
5
- RecordTrack.findOrCreate = (editing, audioUnitBox, type, forceCreate = false) => {
5
+ RecordTrack.findOrCreate = (editing, audioUnitBox, type, excludeTrack = null) => {
6
6
  let index = 0 | 0;
7
- for (const trackBox of audioUnitBox.tracks.pointerHub.incoming()
8
- .map(({ box }) => asInstanceOf(box, TrackBox))) {
9
- if (!forceCreate) {
7
+ const trackBoxes = audioUnitBox.tracks.pointerHub.incoming()
8
+ .map(({ box }) => asInstanceOf(box, TrackBox))
9
+ .sort((a, b) => a.index.getValue() - b.index.getValue());
10
+ for (const trackBox of trackBoxes) {
11
+ if (trackBox !== excludeTrack) {
10
12
  const hasNoRegions = trackBox.regions.pointerHub.isEmpty();
11
13
  const matchesType = trackBox.type.getValue() === type;
12
14
  if (hasNoRegions && matchesType) {
@@ -1,2 +1,2 @@
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}});
1
+ var d=n=>n!=null;var y=(n,e="asDefined failed")=>n??g(U(e));var U=n=>n instanceof Function?n():n;var z=n=>{throw new Error(`Unhandled ${n}`)},g=n=>{throw typeof n=="string"?new Error(n):n},q=(n,e)=>n?void 0:g(U(e));var V=n=>new Proxy({},{get(){return g(n)}});var N=class{value;status="success";constructor(e){this.value=e}error=V("Cannot access error when succeeded")},$=class{error;status="failure";constructor(e){this.error=e}value=V("Cannot access value when failed")},G=n=>{try{return new N(n())}catch(e){return new $(e)}};var Y=()=>{};var _;(function(n){n[n.Ascending=1]="Ascending",n[n.Descending=-1]="Descending"})(_||(_={}));var v=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)=>y(e.at(0),t);static getLast=(e,t)=>y(e.at(-1),t);static getPrev=(e,t)=>{let s=e.indexOf(t);return s===-1?g(`${t} not found in ${e}`):y(e.at((s-1)%e.length),"Internal Error")};static getNext=(e,t)=>{let s=e.indexOf(t);return s===-1?g(`${t} not found in ${e}`):y(e.at((s+1)%e.length),"Internal Error")};static removeLast=(e,t)=>y(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 g(`${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 i of e){let c=i[t];r.has(c)||(r.add(c),e[s++]=i)}return e.length=s,e};static subtract(e,t,s){return e.filter(r=>!t.some(i=>s(r,i)))}static intersect(e,t,s){return e.filter(r=>t.some(i=>s(r,i)))}static merge(e,t,s){return[...e.filter(r=>!t.some(i=>s(r,i))),...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=_.Ascending){if(e.length<2)return!0;let s=e[0];for(let r=1;r<e.length;r++){let i=e[r];if(Math.sign(s-i)===t)return!1;s=i}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 S=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,i=0;for(let c of e)r=t(r,c,i++);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 i=t(r);d(i)&&s.push(i)}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(),i=r;if(s!==!0)for(;;){let{done:c,value:o}=t.next();if(c===!0){yield[i,null];return}yield[i,o],i=o}}};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(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 O=class n{static createEstimator=()=>{let e=performance.now(),t=n.millis(Number.POSITIVE_INFINITY),s=0;return r=>{if(r===0)return n.POSITIVE_INFINITY;if(r>=1)return n.millis(0);let i=performance.now()-e;return i>s*1e3&&(t=n.millis(i/r-i),s++),t}};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),i=Math.floor(r/60),c=Math.floor(i/24);return s<60?(e=s,t="second"):r<60?(e=r,t="minute"):i<24?(e=i,t="hour"):(e=c,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 A;(function(n){class e{value;constructor(o){this.value=o}}n.Transfer=e,n.makeTransferable=c=>new e(c),n.sender=(c,o)=>o(new r(c)),n.executor=(c,o)=>new i(c,o);let t=c=>{let o=[];for(let a of c)a instanceof e?o.push(a.value):(a instanceof MessagePort||typeof ImageBitmap<"u"&&a instanceof ImageBitmap||typeof OffscreenCanvas<"u"&&a instanceof OffscreenCanvas)&&o.push(a);return o},s=c=>c instanceof e?c.value:c;class r{#e;#t=new Map;#r;#o=0;constructor(o){this.#e=o,this.#r=o.subscribe(this.#s)}terminate(){this.#r.terminate()}dispatchAndForget=(o,...a)=>{let u=t(a);this.#e.send({type:"send",returnId:!1,func:o.name,args:Array.from(S.map(a,f=>({value:s(f)})))},u)};dispatchAndReturn=(o,...a)=>new Promise((u,f)=>{let p=S.reduce(a,(l,m,x)=>(typeof m=="function"&&l.push([x,m]),l),[]);this.#t.set(this.#o,{executorTuple:{resolve:u,reject:f},callbacks:new Map(p)});let h=t(a);this.#e.send({type:"send",returnId:this.#o,func:o.name,args:Array.from(S.map(a,(l,m)=>typeof l=="function"?{callback:m}:{value:s(l)}))},h),this.#o++});#s=o=>{let a=this.#t.get(o.returnId);d(a)?o.type==="resolve"?(a.executorTuple.resolve(o.resolve),this.#t.delete(o.returnId)):o.type==="reject"?(a.executorTuple.reject(o.reject),this.#t.delete(o.returnId)):o.type==="callback"&&a.callbacks?.get(o.funcAt).apply(this,o.args):g(`Promise has already been resolved. ${JSON.stringify(o)}`)}}class i{#e;#t;#r;constructor(o,a){this.#e=o,this.#t=a,this.#r=o.subscribe(this.#o)}terminate(){this.#r.terminate()}#o=o=>{q(o.type==="send",()=>"Message type must be 'send'");let a=Object.getPrototypeOf(this.#t)===Object.getPrototypeOf({})?this.#t:Object.getPrototypeOf(this.#t),u=y(a[o.func],`${o.func.toString()} does not exists on ${this.#t}`),f=o.returnId;if(f===!1)u.apply(this.#t,o.args.map(p=>"value"in p?p.value:g(`${o.func.toString()} has no promise.`)));else try{u.apply(this.#t,o.args.map(h=>"callback"in h?(...l)=>this.#i(f,h.callback,l):h.value)).then(h=>{try{this.#s(f,h)}catch(l){this.#n(f,l)}},h=>this.#n(f,h))}catch(p){this.#n(f,p)}};#s=(o,a)=>this.#e.send({type:"resolve",returnId:o,resolve:a});#n=(o,a)=>this.#e.send({type:"reject",returnId:o,reject:a});#i=(o,a,u)=>this.#e.send({type:"callback",returnId:o,funcAt:a,args:u})}n.Executor=i})(A||(A={}));var W={for:n=>new D(n)},re=[],D=class{#e;#t=new T;constructor(e){if(this.#e=e,d(e.onmessage)||d(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 T;#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 F;(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:i,value:c,error:o}=G(()=>e.next());if(i==="success"){let{done:a,value:u}=c;a&&(clearInterval(r),t(u))}else clearInterval(r),s(o)},0)})})(F||(F={}));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),i=Math.floor(r/e),o=(Math.floor(n)-C(i*e,t))%s,a=Math.floor(o/240),u=o%240;return{bars:i,beats:r-i*e,semiquavers:a,ticks:u}},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:i,ticks:c}=Z(n|0,e,t);return`${s+1}.${r+1}.${i+1}:${c}`}};var P=128,Oe=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,M=48e3,I=2,j=!1,b=0;A.executor(W.for(self).channel("offline-engine"),{async initialize(n,e,t){M=t.sampleRate,I=t.numberOfChannels,Q=e,b=0,se({sampleRate:M}),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=v.create(()=>new Float32Array(n),I),t=v.create(()=>new Float32Array(P),I),s=0;for(;s<n;){let r=[t];R(b,M),B.process([[]],r),b+=P;let i=n-s,c=Math.min(i,P);for(let o=0;o<I;o++)e[o].set(r[0][o].subarray(0,c),s);s+=c}return e},async render(n){let{silenceThresholdDb:e,silenceDurationSeconds:t,maxDurationSeconds:s}=n,r=te(e??-72),i=Math.ceil((t??10)*M),c=d(s)?Math.ceil(s*M):1/0,o=v.create(()=>[],I),a=0,u=!1,f=0;for(j=!0,await F.timeSpan(O.seconds(0));j&&b<c;){let l=[v.create(()=>new Float32Array(P),I)];R(b,M);let m=B.process([[]],l),x=0;for(let w of l[0])for(let ne of w){let H=Math.abs(ne);H>x&&(x=H)}let E=x<=r;if(x>r&&(u=!0),E&&u){if(a+=P,a>=i)break}else a=0;for(let w=0;w<I;w++)o[w].push(l[0][w].slice());if(b+=P,!m)break;b-f>=M&&(f=b,d(Q)&&Q.postMessage({frames:b}),await new Promise(w=>setTimeout(w,0)))}let p=b-a+Math.min(M/4,a);return v.create(h=>{let l=new Float32Array(p),m=0;for(let x of o[h]){if(m>=p)break;let E=Math.min(x.length,p-m);l.set(x.subarray(0,E),m),m+=E}return l},I)},stop(){j=!1}});
2
2
  //# sourceMappingURL=offline-engine.js.map