@libraz/libsonare 1.5.5 → 1.7.0

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 (80) hide show
  1. package/README.md +109 -20
  2. package/dist/analysis.d.ts +5809 -0
  3. package/dist/analysis.js +2574 -0
  4. package/dist/analysis.js.map +1 -0
  5. package/dist/index.d.ts +884 -55
  6. package/dist/index.js +1302 -292
  7. package/dist/index.js.map +1 -1
  8. package/dist/schemas/realtime-voice-changer-preset-pack.schema.json +27 -0
  9. package/dist/schemas/realtime-voice-changer-preset.schema.json +140 -0
  10. package/dist/sonare-analysis.js +2 -0
  11. package/dist/sonare-analysis.wasm +0 -0
  12. package/dist/sonare.js +1 -1
  13. package/dist/sonare.wasm +0 -0
  14. package/dist/worker.d.ts +65 -0
  15. package/dist/worker.js +734 -0
  16. package/dist/worker.js.map +1 -0
  17. package/dist/worklet.d.ts +628 -88
  18. package/dist/worklet.js +1816 -266
  19. package/dist/worklet.js.map +1 -1
  20. package/package.json +23 -11
  21. package/src/_chain_config.ts +5 -3
  22. package/src/analysis.ts +137 -0
  23. package/src/analysis_helpers.ts +40 -29
  24. package/src/audio.ts +7 -2
  25. package/src/clip_page_streamer.ts +62 -8
  26. package/src/codes.ts +87 -64
  27. package/src/effects_mastering.ts +1 -0
  28. package/src/effects_transform.ts +179 -10
  29. package/src/errors.ts +1 -0
  30. package/src/feature_core.ts +140 -2
  31. package/src/feature_music.ts +25 -3
  32. package/src/feature_pitch.ts +70 -1
  33. package/src/feature_spectral.ts +295 -7
  34. package/src/feature_spectrogram.ts +203 -3
  35. package/src/features.ts +16 -1
  36. package/src/index.ts +120 -8
  37. package/src/mastering_chain.ts +20 -8
  38. package/src/mastering_core.ts +5 -0
  39. package/src/mastering_dynamics.ts +7 -1
  40. package/src/metering.ts +6 -1
  41. package/src/mixer.ts +3 -3
  42. package/src/opfs_clip_pages.ts +26 -1
  43. package/src/project.ts +13 -0
  44. package/src/project_class.ts +204 -23
  45. package/src/project_internal.ts +38 -34
  46. package/src/project_types.ts +114 -11
  47. package/src/public_types.ts +68 -0
  48. package/src/public_types_mastering.ts +22 -0
  49. package/src/public_types_mixing.ts +27 -2
  50. package/src/public_types_music.ts +9 -0
  51. package/src/public_types_realtime.ts +23 -5
  52. package/src/public_types_spectral.ts +33 -0
  53. package/src/quick_analysis.ts +46 -10
  54. package/src/realtime_engine.ts +167 -6
  55. package/src/realtime_voice_changer.ts +51 -77
  56. package/src/sonare-analysis.js.d.ts +8 -0
  57. package/src/sonare.js.d.ts +340 -6
  58. package/src/stream_analyzer.ts +6 -1
  59. package/src/streaming_processors.ts +15 -0
  60. package/src/web_midi.ts +46 -11
  61. package/src/worker.ts +196 -0
  62. package/src/worker_client.ts +352 -0
  63. package/src/worker_protocol.ts +59 -0
  64. package/src/worklet/engine-automation.ts +2 -1
  65. package/src/worklet/engine-capture-facade.ts +13 -4
  66. package/src/worklet/engine-clips.ts +12 -3
  67. package/src/worklet/engine-node.ts +264 -21
  68. package/src/worklet/engine-offline.ts +7 -2
  69. package/src/worklet/engine-parameter-facade.ts +55 -5
  70. package/src/worklet/engine-processor.ts +435 -62
  71. package/src/worklet/engine-register.ts +9 -1
  72. package/src/worklet/engine-strips.ts +19 -3
  73. package/src/worklet/engine-sync.ts +2 -6
  74. package/src/worklet/engine-tempo-facade.ts +8 -6
  75. package/src/worklet/engine.ts +390 -13
  76. package/src/worklet/guards.ts +121 -8
  77. package/src/worklet/messages.ts +166 -8
  78. package/src/worklet/protocol.ts +305 -17
  79. package/src/worklet/voice-changer-processor.ts +12 -15
  80. package/src/worklet.ts +20 -1
@@ -24,6 +24,7 @@ export function registerSonareRealtimeEngineWorkletProcessor(
24
24
  class RegisteredSonareRealtimeEngineWorkletProcessor extends Base {
25
25
  private bridge?: SonareRealtimeEngineWorkletProcessor;
26
26
  private readonly pendingMessages: unknown[] = [];
27
+ private pendingMessagesOverflowed = false;
27
28
  readonly port?: WorkletPort;
28
29
 
29
30
  constructor(options?: { processorOptions?: SonareRealtimeEngineWorkletProcessorOptions }) {
@@ -35,6 +36,10 @@ export function registerSonareRealtimeEngineWorkletProcessor(
35
36
  if (!this.bridge) {
36
37
  if (this.pendingMessages.length < 1024) {
37
38
  this.pendingMessages.push(event.data);
39
+ } else {
40
+ // A long sync before embind initialization must fail visibly rather
41
+ // than drop a provider/page/commit message and leave silent audio.
42
+ this.pendingMessagesOverflowed = true;
38
43
  }
39
44
  return;
40
45
  }
@@ -112,8 +117,11 @@ export function registerSonareRealtimeEngineWorkletProcessor(
112
117
  moduleFactory,
113
118
  });
114
119
  }
120
+ if (this.pendingMessagesOverflowed) {
121
+ throw new Error('AudioWorklet initialization message buffer overflowed.');
122
+ }
115
123
  this.bridge = new SonareRealtimeEngineWorkletProcessor(options, {
116
- postMessage: (message) => port?.postMessage?.(message),
124
+ postMessage: (message, transfer) => port?.postMessage?.(message, transfer),
117
125
  onMeter: (meter) => port?.postMessage?.(meter),
118
126
  });
119
127
  for (const message of options.initialSyncMessages ?? []) {
@@ -1,5 +1,5 @@
1
1
  import { panLawCode, panModeCode } from '../codes';
2
- import type { EqBand, PanLaw, PanMode, RealtimeEngine } from '../index';
2
+ import type { EqBand, PanLawInput, PanMode, RealtimeEngine } from '../index';
3
3
  import type { SonareEngineInstrumentSyncMessage, SonareEngineSyncMessage } from './messages';
4
4
 
5
5
  /**
@@ -85,7 +85,7 @@ export function setTrackStripPan(
85
85
  export function setTrackStripPanLaw(
86
86
  ctx: EngineStripContext,
87
87
  target: string | number,
88
- panLaw: PanLaw | number,
88
+ panLaw: PanLawInput,
89
89
  ): void {
90
90
  const trackId = trackIdFor(ctx, target);
91
91
  const code = panLawCode(panLaw);
@@ -232,6 +232,17 @@ export function pushMidiCc(
232
232
  });
233
233
  }
234
234
 
235
+ export function pushMidiUmp(
236
+ ctx: EngineStripContext,
237
+ trackId: string | number,
238
+ word0: number,
239
+ renderFrame: number,
240
+ ): void {
241
+ const destinationId = ctx.resolveTargetId(trackId);
242
+ ctx.offlineEngine.pushMidiUmp(destinationId, word0, renderFrame);
243
+ ctx.postSync({ type: 'syncMidiUmp', destinationId, word0, renderFrame });
244
+ }
245
+
235
246
  export function setBuiltinInstrument(
236
247
  ctx: EngineStripContext,
237
248
  trackId: string | number,
@@ -260,7 +271,12 @@ export function loadSoundFont(ctx: EngineStripContext, data: Uint8Array): void {
260
271
  export function setSf2Instrument(
261
272
  ctx: EngineStripContext,
262
273
  trackId: string | number,
263
- config: { destinationId?: number; gain?: number; polyphony?: number },
274
+ config: {
275
+ destinationId?: number;
276
+ gain?: number;
277
+ polyphony?: number;
278
+ preferModelForModeledFamilies?: boolean;
279
+ },
264
280
  ): void {
265
281
  const destinationId = ctx.resolveTargetId(trackId);
266
282
  ctx.offlineEngine.setSf2Instrument(config, destinationId);
@@ -65,11 +65,7 @@ export function resolveTargetId(target: string | number): number {
65
65
  return Number.isFinite(parsed) ? parsed : 0;
66
66
  }
67
67
 
68
- /**
69
- * Resolves a parameter id from a name or numeric id. Numeric params pass
70
- * through; named params are matched against the parameter list, then fall back
71
- * to a target-id resolution of the name (or the node id).
72
- */
68
+ /** Resolves a registered parameter name or passes through a numeric id. */
73
69
  export function resolveParamId(
74
70
  parameters: readonly EngineParameterInfo[],
75
71
  nodeId: string,
@@ -82,7 +78,7 @@ export function resolveParamId(
82
78
  if (byName) {
83
79
  return byName.id;
84
80
  }
85
- return resolveTargetId(param || nodeId);
81
+ throw new RangeError(`Unknown engine parameter ${JSON.stringify(param)} for node ${nodeId}`);
86
82
  }
87
83
 
88
84
  /** Encodes an automation curve descriptor to the engine's numeric curve code. */
@@ -24,6 +24,13 @@ interface TimeSignature {
24
24
  export interface EngineTempoContext {
25
25
  readonly offlineEngine: RealtimeEngine;
26
26
  readonly realtimeNode: SonareRealtimeEngineNode;
27
+ sendCommand(command: {
28
+ type: SonareEngineCommandType;
29
+ targetId?: number;
30
+ sampleTime?: number;
31
+ argFloat?: number;
32
+ argInt?: number;
33
+ }): boolean;
27
34
  postSync(message: SonareEngineSyncMessage): void;
28
35
  getTempoBpm(): number;
29
36
  setTempoBpm(bpm: number): void;
@@ -54,11 +61,6 @@ export function setTempo(ctx: EngineTempoContext, bpm: number): void {
54
61
  ctx.setTempoSegments([{ startPpq: 0, bpm }]);
55
62
  ctx.offlineEngine.setTempo(bpm);
56
63
  postTempoSync(ctx);
57
- ctx.realtimeNode.sendCommand({
58
- type: SonareEngineCommandType.SetTempoMap,
59
- sampleTime: -1,
60
- argFloat: bpm,
61
- });
62
64
  }
63
65
 
64
66
  export function setTempoSegments(
@@ -113,7 +115,7 @@ export function setLoop(
113
115
  // while loop STARTS and the offline path stay exact. This is intentional:
114
116
  // the record has no second free Float64 lane, and a micro-PPQ grid on the
115
117
  // loop end is well below audible/sample-accurate resolution at any tempo.
116
- return ctx.realtimeNode.sendCommand({
118
+ return ctx.sendCommand({
117
119
  type: SonareEngineCommandType.SetLoop,
118
120
  targetId: enabled ? 1 : 0,
119
121
  sampleTime: -1,