@opendaw/studio-core 0.0.43 → 0.0.45

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.
Files changed (104) hide show
  1. package/dist/AssetService.d.ts +12 -2
  2. package/dist/AssetService.d.ts.map +1 -1
  3. package/dist/AssetService.js +46 -1
  4. package/dist/AudioOfflineRenderer.d.ts +1 -2
  5. package/dist/AudioOfflineRenderer.d.ts.map +1 -1
  6. package/dist/AudioOfflineRenderer.js +10 -3
  7. package/dist/EffectBox.d.ts +2 -2
  8. package/dist/EffectBox.d.ts.map +1 -1
  9. package/dist/EffectFactories.d.ts +6 -0
  10. package/dist/EffectFactories.d.ts.map +1 -1
  11. package/dist/EffectFactories.js +29 -24
  12. package/dist/EffectFactory.d.ts +1 -1
  13. package/dist/EffectFactory.d.ts.map +1 -1
  14. package/dist/EffectParameterDefaults.d.ts +5 -0
  15. package/dist/EffectParameterDefaults.d.ts.map +1 -0
  16. package/dist/EffectParameterDefaults.js +27 -0
  17. package/dist/Engine.d.ts +1 -1
  18. package/dist/Engine.d.ts.map +1 -1
  19. package/dist/EngineFacade.d.ts +1 -1
  20. package/dist/EngineFacade.d.ts.map +1 -1
  21. package/dist/EngineFacade.js +1 -1
  22. package/dist/EngineWorklet.d.ts +2 -2
  23. package/dist/EngineWorklet.d.ts.map +1 -1
  24. package/dist/EngineWorklet.js +3 -2
  25. package/dist/Preferences.d.ts +20 -0
  26. package/dist/Preferences.d.ts.map +1 -0
  27. package/dist/Preferences.js +46 -0
  28. package/dist/capture/CaptureDevices.js +3 -3
  29. package/dist/capture/RecordTrack.d.ts +2 -2
  30. package/dist/capture/RecordTrack.d.ts.map +1 -1
  31. package/dist/capture/Recording.d.ts +1 -1
  32. package/dist/capture/Recording.d.ts.map +1 -1
  33. package/dist/capture/Recording.js +1 -1
  34. package/dist/cloud/CloudAuthManager.d.ts +6 -2
  35. package/dist/cloud/CloudAuthManager.d.ts.map +1 -1
  36. package/dist/cloud/CloudAuthManager.js +12 -12
  37. package/dist/cloud/CloudBackup.js +1 -1
  38. package/dist/cloud/{CloudBackupSoundfont.d.ts → CloudBackupSoundfonts.d.ts} +1 -1
  39. package/dist/cloud/CloudBackupSoundfonts.d.ts.map +1 -0
  40. package/dist/cloud/{CloudBackupSoundfont.js → CloudBackupSoundfonts.js} +1 -1
  41. package/dist/dawproject/BuiltinDevices.d.ts.map +1 -1
  42. package/dist/dawproject/BuiltinDevices.js +3 -2
  43. package/dist/dawproject/{DawProjectImport.d.ts → DawProjectImporter.d.ts} +1 -1
  44. package/dist/dawproject/DawProjectImporter.d.ts.map +1 -0
  45. package/dist/dawproject/{DawProjectImport.js → DawProjectImporter.js} +17 -5
  46. package/dist/dawproject/DawProjectImporter.test.d.ts +2 -0
  47. package/dist/dawproject/DawProjectImporter.test.d.ts.map +1 -0
  48. package/dist/dawproject/{DawProjectImport.test.js → DawProjectImporter.test.js} +1 -1
  49. package/dist/dawproject/DawProjectService.js +1 -1
  50. package/dist/dawproject/index.d.ts +1 -1
  51. package/dist/dawproject/index.d.ts.map +1 -1
  52. package/dist/dawproject/index.js +1 -1
  53. package/dist/index.d.ts +1 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +1 -0
  56. package/dist/midi/MIDILearning.d.ts +1 -1
  57. package/dist/midi/MIDILearning.d.ts.map +1 -1
  58. package/dist/midi/MIDILearning.js +22 -3
  59. package/dist/processors.js +27 -5
  60. package/dist/processors.js.map +4 -4
  61. package/dist/project/Project.d.ts +12 -8
  62. package/dist/project/Project.d.ts.map +1 -1
  63. package/dist/project/Project.js +45 -33
  64. package/dist/project/ProjectMigration.d.ts.map +1 -1
  65. package/dist/project/ProjectMigration.js +10 -1
  66. package/dist/project/Recovery.d.ts +9 -0
  67. package/dist/project/Recovery.d.ts.map +1 -0
  68. package/dist/project/Recovery.js +49 -0
  69. package/dist/project/index.d.ts +1 -0
  70. package/dist/project/index.d.ts.map +1 -1
  71. package/dist/project/index.js +1 -0
  72. package/dist/samples/OpenSampleAPI.d.ts.map +1 -1
  73. package/dist/samples/OpenSampleAPI.js +5 -3
  74. package/dist/samples/SampleService.d.ts +5 -2
  75. package/dist/samples/SampleService.d.ts.map +1 -1
  76. package/dist/samples/SampleService.js +12 -4
  77. package/dist/samples/SampleStorage.d.ts +1 -1
  78. package/dist/samples/SampleStorage.d.ts.map +1 -1
  79. package/dist/samples/SampleStorage.js +1 -1
  80. package/dist/soundfont/DefaultSoundfontLoader.d.ts +2 -1
  81. package/dist/soundfont/DefaultSoundfontLoader.d.ts.map +1 -1
  82. package/dist/soundfont/DefaultSoundfontLoader.js +14 -4
  83. package/dist/soundfont/DefaultSoundfontLoaderManager.d.ts +2 -1
  84. package/dist/soundfont/DefaultSoundfontLoaderManager.d.ts.map +1 -1
  85. package/dist/soundfont/DefaultSoundfontLoaderManager.js +1 -0
  86. package/dist/soundfont/OpenSoundfontAPI.d.ts.map +1 -1
  87. package/dist/soundfont/OpenSoundfontAPI.js +6 -4
  88. package/dist/soundfont/SoundfontService.d.ts +5 -2
  89. package/dist/soundfont/SoundfontService.d.ts.map +1 -1
  90. package/dist/soundfont/SoundfontService.js +18 -8
  91. package/dist/workers-main.js +2 -2
  92. package/dist/workers-main.js.map +4 -4
  93. package/dist/ysync/YService.d.ts.map +1 -1
  94. package/dist/ysync/YService.js +4 -2
  95. package/dist/ysync/YSync.d.ts.map +1 -1
  96. package/dist/ysync/YSync.js +79 -51
  97. package/package.json +49 -48
  98. package/dist/cloud/CloudBackupSoundfont.d.ts.map +0 -1
  99. package/dist/dawproject/DawProjectImport.d.ts.map +0 -1
  100. package/dist/dawproject/DawProjectImport.test.d.ts +0 -2
  101. package/dist/dawproject/DawProjectImport.test.d.ts.map +0 -1
  102. package/dist/env.d.ts +0 -6
  103. package/dist/env.d.ts.map +0 -1
  104. package/dist/env.js +0 -9
@@ -2,9 +2,8 @@ import { asDefined, Errors, isDefined, isNull, Maps, panic, RuntimeNotifier, Tim
2
2
  import { Promises } from "@opendaw/lib-runtime";
3
3
  import { DropboxHandler } from "./DropboxHandler";
4
4
  import { GoogleDriveHandler } from "./GoogleDriveHandler";
5
- import { VITE_DROPBOX_CLIENT_ID, VITE_GOOGLE_CLIENT_ID } from "../env";
6
5
  export class CloudAuthManager {
7
- static create() { return new CloudAuthManager(); }
6
+ static create(clientIds) { return new CloudAuthManager(clientIds); }
8
7
  static async #createCodes() {
9
8
  const array = new Uint8Array(32);
10
9
  crypto.getRandomValues(array);
@@ -21,10 +20,9 @@ export class CloudAuthManager {
21
20
  .replace(/=/g, "");
22
21
  return { codeVerifier, codeChallenge };
23
22
  }
24
- static #ID = 0;
25
- id = CloudAuthManager.#ID++;
23
+ #clientIds;
26
24
  #memoizedHandlers = new Map();
27
- constructor() { }
25
+ constructor(clientIds) { this.#clientIds = clientIds; }
28
26
  async getHandler(service) {
29
27
  const memo = Maps.createIfAbsent(this.#memoizedHandlers, service, service => {
30
28
  switch (service) {
@@ -39,10 +37,12 @@ export class CloudAuthManager {
39
37
  }
40
38
  });
41
39
  const handler = await memo();
42
- const { status } = await Promises.tryCatch(handler.alive());
40
+ const { status, error } = await Promises.tryCatch(handler.alive());
43
41
  if (status === "rejected") {
42
+ // Do not auto-retry here to avoid reopening the OAuth popup in a loop.
43
+ // Instead, clear the memoized handler and surface the error to the caller.
44
44
  this.#memoizedHandlers.delete(service);
45
- return this.getHandler(service);
45
+ return Promise.reject(error);
46
46
  }
47
47
  console.debug(`Handler for '${service}' is alive`);
48
48
  return handler;
@@ -75,7 +75,7 @@ export class CloudAuthManager {
75
75
  let handled = false;
76
76
  channel.onmessage = async (event) => {
77
77
  const data = asDefined(event.data, "No data");
78
- console.debug("[CloudAuth] Received via BroadcastChannel:", this.id, data);
78
+ console.debug("[CloudAuth] Received via BroadcastChannel");
79
79
  if (data.type === "auth-callback" && isDefined(data.code)) {
80
80
  if (handled) {
81
81
  return;
@@ -99,7 +99,7 @@ export class CloudAuthManager {
99
99
  if (!response.ok) {
100
100
  const errorText = await response.text();
101
101
  console.error("[CloudAuth] Token exchange error:", errorText);
102
- return panic(`Token exchange failed: ${response.statusText}`);
102
+ return panic(`Token exchange failed: ${errorText}`);
103
103
  }
104
104
  const dataJson = await response.json();
105
105
  const accessToken = dataJson.access_token;
@@ -131,7 +131,7 @@ export class CloudAuthManager {
131
131
  async #oauthDropbox() {
132
132
  return this.#oauthPkceFlow({
133
133
  service: "dropbox",
134
- clientId: asDefined(VITE_DROPBOX_CLIENT_ID, "Missing VITE_DROPBOX_CLIENT_ID"),
134
+ clientId: this.#clientIds.Dropbox,
135
135
  authUrlBase: "https://www.dropbox.com/oauth2/authorize",
136
136
  tokenUrl: "https://api.dropboxapi.com/oauth2/token",
137
137
  scope: "", // Dropbox scope is optional
@@ -141,7 +141,7 @@ export class CloudAuthManager {
141
141
  });
142
142
  }
143
143
  async #oauthGoogle() {
144
- const clientId = asDefined(VITE_GOOGLE_CLIENT_ID, "Missing VITE_GOOGLE_CLIENT_ID");
144
+ const clientId = this.#clientIds.GoogleDrive;
145
145
  const scope = "https://www.googleapis.com/auth/drive.appdata";
146
146
  const redirectUri = `${location.origin}/auth-callback.html`;
147
147
  const params = new URLSearchParams({
@@ -167,7 +167,7 @@ export class CloudAuthManager {
167
167
  });
168
168
  channel.onmessage = async (event) => {
169
169
  const data = asDefined(event.data, "No data");
170
- console.debug("[CloudAuth] Received via BroadcastChannel:", this.id, data);
170
+ console.debug("[CloudAuth] Received via BroadcastChannel:", data);
171
171
  if (data.type === "auth-callback" && isDefined(data.access_token)) {
172
172
  try {
173
173
  const accessToken = data.access_token;
@@ -3,7 +3,7 @@ import { Browser } from "@opendaw/lib-dom";
3
3
  import { Promises } from "@opendaw/lib-runtime";
4
4
  import { CloudBackupSamples } from "./CloudBackupSamples";
5
5
  import { CloudBackupProjects } from "./CloudBackupProjects";
6
- import { CloudBackupSoundfonts } from "./CloudBackupSoundfont";
6
+ import { CloudBackupSoundfonts } from "./CloudBackupSoundfonts";
7
7
  import { ProjectSignals } from "../project";
8
8
  export var CloudBackup;
9
9
  (function (CloudBackup) {
@@ -10,4 +10,4 @@ export declare class CloudBackupSoundfonts {
10
10
  static start(cloudHandler: CloudHandler, progress: Progress.Handler, log: Procedure<string>): Promise<void>;
11
11
  private constructor();
12
12
  }
13
- //# sourceMappingURL=CloudBackupSoundfont.d.ts.map
13
+ //# sourceMappingURL=CloudBackupSoundfonts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CloudBackupSoundfonts.d.ts","sourceRoot":"","sources":["../../src/cloud/CloudBackupSoundfonts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,SAAS,EAAE,QAAQ,EAAmB,IAAI,EAAC,MAAM,kBAAkB,CAAA;AAElG,OAAO,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAA;AAK3C,qBAAa,qBAAqB;;IAC9B,MAAM,CAAC,QAAQ,CAAC,UAAU,gBAAe;IACzC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,SAAkC;IACnE,MAAM,CAAC,QAAQ,CAAC,kBAAkB,GAAI,aAAW,SAAS,EAAE,aAAW,SAAS,aAAY;IAE5F,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,MAAM;WAE5B,KAAK,CAAC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAC1B,GAAG,EAAE,SAAS,CAAC,MAAM,CAAC;IAgBzC,OAAO;CA2GV"}
@@ -104,7 +104,7 @@ export class CloudBackupSoundfonts {
104
104
  await SoundfontStorage.get().save({
105
105
  uuid: UUID.parse(soundfont.uuid),
106
106
  file: buffer,
107
- meta: soundfont
107
+ meta: { ...soundfont, size: buffer.byteLength }
108
108
  });
109
109
  return soundfont;
110
110
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"BuiltinDevices.d.ts","sourceRoot":"","sources":["../../src/dawproject/BuiltinDevices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,eAAe,EAAmB,MAAM,yBAAyB,CAAA;AACjG,OAAO,EAAC,eAAe,EAA0B,MAAM,uBAAuB,CAAA;AAC9E,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAY,GAAG,EAAO,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAG9C,yBAAiB,cAAc,CAAC;IACrB,MAAM,SAAS,GAAI,UAAU,QAAQ,EAClB,WAAW,eAAe,EAC1B,OAAO,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,EACvE,OAAO,GAAG,KAAG,eA4DtC,CAAA;CACJ"}
1
+ {"version":3,"file":"BuiltinDevices.d.ts","sourceRoot":"","sources":["../../src/dawproject/BuiltinDevices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,eAAe,EAAmB,MAAM,yBAAyB,CAAA;AACjG,OAAO,EAAC,eAAe,EAA0B,MAAM,uBAAuB,CAAA;AAC9E,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAY,GAAG,EAAO,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAG9C,yBAAiB,cAAc,CAAC;IACrB,MAAM,SAAS,GAAI,UAAU,QAAQ,EAClB,WAAW,eAAe,EAC1B,OAAO,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,EACvE,OAAO,GAAG,KAAG,eA6DtC,CAAA;CACJ"}
@@ -1,7 +1,7 @@
1
1
  import { EqBandType, ParameterDecoder } from "@opendaw/lib-dawproject";
2
2
  import { RevampDeviceBox } from "@opendaw/studio-boxes";
3
3
  import { ifDefined, UUID } from "@opendaw/lib-std";
4
- import { semitoneToHz } from "@opendaw/lib-dsp";
4
+ import { EffectParameterDefaults } from "../EffectParameterDefaults";
5
5
  export var BuiltinDevices;
6
6
  (function (BuiltinDevices) {
7
7
  BuiltinDevices.equalizer = (boxGraph, equalizer, field, index) => {
@@ -23,7 +23,7 @@ export var BuiltinDevices;
23
23
  const readPass = (schema, pass) => {
24
24
  const { order, frequency, q, enabled } = pass;
25
25
  order.setValue(mapOrder(schema.order));
26
- frequency.setValue(semitoneToHz(schema.freq.value));
26
+ frequency.setValue(ParameterDecoder.readValue(schema.freq));
27
27
  ifDefined(schema.Q?.value, value => q.setValue(value));
28
28
  ifDefined(schema.enabled?.value, value => enabled.setValue(value));
29
29
  };
@@ -34,6 +34,7 @@ export var BuiltinDevices;
34
34
  ifDefined(schema.enabled?.value, value => enabled.setValue(value));
35
35
  };
36
36
  return RevampDeviceBox.create(boxGraph, UUID.generate(), box => {
37
+ EffectParameterDefaults.defaultRevampDeviceBox(box);
37
38
  box.host.refer(field);
38
39
  box.index.setValue(index);
39
40
  box.label.setValue(equalizer.deviceName ?? "Revamp");
@@ -9,4 +9,4 @@ export declare namespace DawProjectImport {
9
9
  };
10
10
  const read: (schema: ProjectSchema, resources: DawProject.ResourceProvider) => Promise<Result>;
11
11
  }
12
- //# sourceMappingURL=DawProjectImport.d.ts.map
12
+ //# sourceMappingURL=DawProjectImporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DawProjectImporter.d.ts","sourceRoot":"","sources":["../../src/dawproject/DawProjectImporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAiBH,IAAI,EAEP,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAcH,aAAa,EAOhB,MAAM,yBAAyB,CAAA;AAuBhC,OAAO,EAAyC,eAAe,EAAY,MAAM,0BAA0B,CAAA;AAC3G,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAA;AAQvC,yBAAiB,gBAAgB,CAAC;IAW9B,KAAY,MAAM,GAAG;QACjB,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,QAAQ,EAAE,eAAe,CAAA;KAC5B,CAAA;IAOM,MAAM,IAAI,GAAU,QAAQ,aAAa,EAAE,WAAW,UAAU,CAAC,gBAAgB,KAAG,OAAO,CAAC,MAAM,CA2XxG,CAAA;CAaJ"}
@@ -251,7 +251,7 @@ export var DawProjectImport;
251
251
  }
252
252
  else if (isInstanceOf(timeline, PointsSchema)) {
253
253
  // TODO How to get the actual parameter?
254
- console.debug(timeline.target?.parameter);
254
+ // console.debug(timeline.target?.parameter)
255
255
  }
256
256
  }) ?? []);
257
257
  };
@@ -340,7 +340,13 @@ export var DawProjectImport;
340
340
  .map(readLane) ?? []);
341
341
  };
342
342
  await ifDefined(schema.arrangement, arrangement => readArrangement(arrangement));
343
- outputPointers.forEach(({ target, pointer }) => pointer.refer(asDefined(audioBusses.get(target), `${target} cannot be found.`).input));
343
+ outputPointers.forEach(({ target, pointer }) => {
344
+ const value = audioBusses.get(target);
345
+ // https://github.com/andremichelle/openDAW/issues/25
346
+ if (isDefined(value)) {
347
+ pointer.refer(value.input);
348
+ }
349
+ });
344
350
  rootBox.audioUnits.pointerHub.incoming().forEach(({ box }) => {
345
351
  const audioUnitBox = asInstanceOf(box, AudioUnitBox);
346
352
  if (audioUnitBox.type.getValue() !== AudioUnitType.Output
@@ -369,12 +375,18 @@ export var DawProjectImport;
369
375
  }
370
376
  boxGraph.endTransaction();
371
377
  boxGraph.verifyPointers();
372
- const { audioBusBox: masterBusBox, audioUnitBox: masterAudioUnit } = primaryAudioBusUnitOption.unwrap("Did not find a primary output");
378
+ const { audioBusBox: primaryAudioBus, audioUnitBox: primaryAudioOutputUnit } = primaryAudioBusUnitOption.unwrap("Did not find a primary output");
373
379
  return {
374
380
  audioIds: audioIdSet.values(),
375
381
  skeleton: {
376
382
  boxGraph,
377
- mandatoryBoxes: { rootBox, timelineBox, masterBusBox, masterAudioUnit, userInterfaceBox }
383
+ mandatoryBoxes: {
384
+ rootBox,
385
+ timelineBox,
386
+ primaryAudioBus,
387
+ primaryAudioOutputUnit,
388
+ userInterfaceBoxes: [userInterfaceBox]
389
+ }
378
390
  }
379
391
  };
380
392
  };
@@ -386,7 +398,7 @@ export var DawProjectImport;
386
398
  visitTapeDeviceBox: () => TrackType.Audio,
387
399
  visitNanoDeviceBox: () => TrackType.Notes,
388
400
  visitPlayfieldDeviceBox: () => TrackType.Notes,
389
- visitVaporisateurDeviceBox: () => TrackType.Notes
401
+ visitVaporisateurDeviceBox: () => TrackType.Notes,
390
402
  }) ?? TrackType.Undefined;
391
403
  };
392
404
  })(DawProjectImport || (DawProjectImport = {}));
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=DawProjectImporter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DawProjectImporter.test.d.ts","sourceRoot":"","sources":["../../src/dawproject/DawProjectImporter.test.ts"],"names":[],"mappings":""}
@@ -3,7 +3,7 @@ import { fileURLToPath } from "url";
3
3
  import * as path from "node:path";
4
4
  import * as fs from "node:fs";
5
5
  import { DawProject } from "./DawProject";
6
- import { DawProjectImport } from "./DawProjectImport";
6
+ import { DawProjectImport } from "./DawProjectImporter";
7
7
  describe("DawProjectImport", () => {
8
8
  it("import", async () => {
9
9
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -5,7 +5,7 @@ import { Xml } from "@opendaw/lib-xml";
5
5
  import { MetaDataSchema } from "@opendaw/lib-dawproject";
6
6
  import { DawProject } from "./DawProject";
7
7
  import { FilePickerAcceptTypes } from "../FilePickerAcceptTypes";
8
- import { DawProjectImport } from "./DawProjectImport";
8
+ import { DawProjectImport } from "./DawProjectImporter";
9
9
  export class DawProjectService {
10
10
  sampleService;
11
11
  constructor(sampleService) {
@@ -1,5 +1,5 @@
1
1
  export * from "./DawProject";
2
2
  export * from "./DawProjectExporter";
3
- export * from "./DawProjectImport";
3
+ export * from "./DawProjectImporter";
4
4
  export * from "./DawProjectService";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dawproject/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dawproject/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,qBAAqB,CAAA"}
@@ -1,4 +1,4 @@
1
1
  export * from "./DawProject";
2
2
  export * from "./DawProjectExporter";
3
- export * from "./DawProjectImport";
3
+ export * from "./DawProjectImporter";
4
4
  export * from "./DawProjectService";
package/dist/index.d.ts CHANGED
@@ -29,6 +29,7 @@ export * from "./InstrumentProduct";
29
29
  export * from "./MeterWorklet";
30
30
  export * from "./Mixer";
31
31
  export * from "./PeaksWriter";
32
+ export * from "./Preferences";
32
33
  export * from "./RenderQuantum";
33
34
  export * from "./WavFile";
34
35
  export * from "./Workers";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,QAAQ,CAAA;AACtB,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,MAAM,CAAA;AACpB,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA;AAEvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA;AACjC,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,QAAQ,CAAA;AACtB,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,MAAM,CAAA;AACpB,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA;AAEvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,wBAAwB,CAAA;AACtC,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA;AACjC,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,eAAe,CAAA;AAC7B,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA"}
package/dist/index.js CHANGED
@@ -29,6 +29,7 @@ export * from "./InstrumentProduct";
29
29
  export * from "./MeterWorklet";
30
30
  export * from "./Mixer";
31
31
  export * from "./PeaksWriter";
32
+ export * from "./Preferences";
32
33
  export * from "./RenderQuantum";
33
34
  export * from "./WavFile";
34
35
  export * from "./Workers";
@@ -1,7 +1,7 @@
1
1
  import { byte, JSONValue, Provider, Terminable } from "@opendaw/lib-std";
2
2
  import { Address, AddressJSON, PrimitiveField, PrimitiveValues } from "@opendaw/lib-box";
3
3
  import { Pointers } from "@opendaw/studio-enums";
4
- import { Project } from "../project/Project";
4
+ import { Project } from "../project";
5
5
  export type MIDIConnectionJSON = ({
6
6
  type: "control";
7
7
  controlId: byte;
@@ -1 +1 @@
1
- {"version":3,"file":"MIDILearning.d.ts","sourceRoot":"","sources":["../../src/midi/MIDILearning.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,IAAI,EAGJ,SAAS,EAET,QAAQ,EAGR,UAAU,EAEb,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAA;AAEtF,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAE9C,OAAO,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAA;AAG1C,MAAM,MAAM,kBAAkB,GAAG,CAAC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAE,CAAC,GACjE;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GACvC,SAAS,CAAA;AAEf,MAAM,WAAW,cAAe,SAAQ,UAAU;IAC9C,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IACvB,MAAM,IAAI,kBAAkB,CAAA;CAC/B;AAID,qBAAa,YAAa,YAAW,UAAU;;gBAM/B,OAAO,EAAE,OAAO;IAK5B,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAC5C,oBAAoB,CAAC,OAAO,EAAE,OAAO;IAE/B,iBAAiB,CAAC,KAAK,EAAE,cAAc,CAAC,eAAe,EAAE,QAAQ,CAAC,WAAW,GAAG,QAAQ,CAAC;IAsB/F,MAAM,IAAI,aAAa,CAAC,kBAAkB,CAAC;IAI3C,SAAS,IAAI,IAAI;CAgDpB"}
1
+ {"version":3,"file":"MIDILearning.d.ts","sourceRoot":"","sources":["../../src/midi/MIDILearning.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,IAAI,EAIJ,SAAS,EAGT,QAAQ,EAGR,UAAU,EAEb,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAA;AAEtF,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAA;AAE9C,OAAO,EAAC,OAAO,EAAC,MAAM,YAAY,CAAA;AAIlC,MAAM,MAAM,kBAAkB,GAAG,CAAC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAE,CAAC,GACjE;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GACvC,SAAS,CAAA;AAEf,MAAM,WAAW,cAAe,SAAQ,UAAU;IAC9C,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IACvB,MAAM,IAAI,kBAAkB,CAAA;CAC/B;AAID,qBAAa,YAAa,YAAW,UAAU;;gBAM/B,OAAO,EAAE,OAAO;IAK5B,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAC5C,oBAAoB,CAAC,OAAO,EAAE,OAAO;IAE/B,iBAAiB,CAAC,KAAK,EAAE,cAAc,CAAC,eAAe,EAAE,QAAQ,CAAC,WAAW,GAAG,QAAQ,CAAC;IAsB/F,MAAM,IAAI,aAAa,CAAC,kBAAkB,CAAC;IAI3C,SAAS,IAAI,IAAI;CAiEpB"}
@@ -1,7 +1,8 @@
1
- import { Errors, isDefined, RuntimeNotifier, Terminator } from "@opendaw/lib-std";
1
+ import { Errors, isDefined, isNotNull, RuntimeNotifier, Terminator } from "@opendaw/lib-std";
2
2
  import { Address } from "@opendaw/lib-box";
3
3
  import { MidiData } from "@opendaw/lib-midi";
4
4
  import { MidiDevices } from "./MidiDevices";
5
+ import { AnimationFrame } from "@opendaw/lib-dom";
5
6
  export class MIDILearning {
6
7
  #terminator = new Terminator();
7
8
  #project;
@@ -72,6 +73,8 @@ export class MIDILearning {
72
73
  }
73
74
  #createMidiControlObserver(project, adapter, controlId) {
74
75
  const registration = adapter.registerMidiControl();
76
+ let pendingValue = null;
77
+ const update = (value) => project.editing.modify(() => adapter.setValue(adapter.valueMapping.y(value)), false);
75
78
  return {
76
79
  observer: (event) => {
77
80
  const data = event.data;
@@ -79,10 +82,26 @@ export class MIDILearning {
79
82
  return;
80
83
  }
81
84
  if (MidiData.isController(data) && MidiData.readParam1(data) === controlId) {
82
- project.editing.modify(() => adapter.setValue(adapter.valueMapping.y(MidiData.asValue(data))), false);
85
+ const value = MidiData.asValue(data);
86
+ if (pendingValue === null) {
87
+ update(value);
88
+ pendingValue = value;
89
+ AnimationFrame.once(() => {
90
+ if (isNotNull(pendingValue)) {
91
+ update(pendingValue);
92
+ pendingValue = null;
93
+ }
94
+ });
95
+ }
96
+ else {
97
+ pendingValue = value;
98
+ }
83
99
  }
84
100
  },
85
- terminate: () => registration.terminate()
101
+ terminate: () => {
102
+ pendingValue = null;
103
+ registration.terminate();
104
+ }
86
105
  };
87
106
  }
88
107
  }