@grame/faustwasm 0.15.6 → 0.16.1

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.
@@ -736,6 +736,26 @@ export interface IFaustBaseWebAudioDsp {
736
736
  * event: Pick<DeviceOrientationEvent, "alpha" | "beta" | "gamma">
737
737
  */
738
738
  propagateGyr(event: Pick<DeviceOrientationEvent, "alpha" | "beta" | "gamma">): void;
739
+ /**
740
+ * Reinitialize the DSP using its configured sample rate.
741
+ */
742
+ init(): void;
743
+ /**
744
+ * Reinitialize the DSP instance state using its configured sample rate.
745
+ */
746
+ instanceInit(): void;
747
+ /**
748
+ * Clear the DSP instance state.
749
+ */
750
+ instanceClear(): void;
751
+ /**
752
+ * Reinitialize the DSP instance constants using its configured sample rate.
753
+ */
754
+ instanceConstants(): void;
755
+ /**
756
+ * Reset DSP user interface parameters to their default values.
757
+ */
758
+ instanceResetUserInterface(): void;
739
759
  /**
740
760
  * Start the DSP audio processing.
741
761
  */
@@ -910,6 +930,11 @@ export declare class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
910
930
  hasSoundfiles(): boolean;
911
931
  startSensors(): void;
912
932
  stopSensors(): void;
933
+ init(): void;
934
+ instanceInit(): void;
935
+ instanceClear(): void;
936
+ instanceConstants(): void;
937
+ instanceResetUserInterface(): void;
913
938
  start(): void;
914
939
  stop(): void;
915
940
  destroy(): void;
@@ -917,7 +942,13 @@ export declare class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
917
942
  export declare class FaustMonoWebAudioDsp extends FaustBaseWebAudioDsp implements IFaustMonoWebAudioDsp {
918
943
  private fInstance;
919
944
  private fDSP;
945
+ private fSampleRate;
920
946
  constructor(instance: FaustMonoDspInstance, sampleRate: number, sampleSize: number, bufferSize: number, soundfiles: LooseFaustDspFactory["soundfiles"]);
947
+ init(): void;
948
+ instanceInit(): void;
949
+ instanceClear(): void;
950
+ instanceConstants(): void;
951
+ instanceResetUserInterface(): void;
921
952
  private initMemory;
922
953
  toString(): string;
923
954
  compute(input: Float32Array[] | ((input: Float32Array[] | Float64Array[]) => any), output: Float32Array[] | ((output: Float32Array[] | Float64Array[]) => any)): boolean;
@@ -945,6 +976,7 @@ export declare class FaustWebAudioDspVoice {
945
976
  private fVelLabel;
946
977
  private fDSP;
947
978
  private fAPI;
979
+ private fSampleRate;
948
980
  fCurNote: number;
949
981
  fNextNote: number;
950
982
  fNextVel: number;
@@ -955,6 +987,11 @@ export declare class FaustWebAudioDspVoice {
955
987
  }, sampleRate: number);
956
988
  static midiToFreq(note: number): number;
957
989
  static normalizeVelocity(velocity: number): number;
990
+ init(sampleRate: number): void;
991
+ instanceInit(): void;
992
+ instanceClear(): void;
993
+ instanceConstants(): void;
994
+ instanceResetUserInterface(): void;
958
995
  private extractPaths;
959
996
  keyOn(pitch: number, velocity: number, legato?: boolean): void;
960
997
  keyOff(hard?: boolean): void;
@@ -970,7 +1007,13 @@ export declare class FaustPolyWebAudioDsp extends FaustBaseWebAudioDsp implement
970
1007
  private fAudioMixing;
971
1008
  private fAudioMixingHalf;
972
1009
  private fVoiceTable;
1010
+ private fSampleRate;
973
1011
  constructor(instance: FaustPolyDspInstance, sampleRate: number, sampleSize: number, bufferSize: number, soundfiles: LooseFaustDspFactory["soundfiles"]);
1012
+ init(): void;
1013
+ instanceInit(): void;
1014
+ instanceClear(): void;
1015
+ instanceConstants(): void;
1016
+ instanceResetUserInterface(): void;
974
1017
  private initMemory;
975
1018
  toString(): string;
976
1019
  private allocVoice;
@@ -1265,6 +1308,11 @@ export declare class FaustOfflineProcessor<Poly extends boolean = false> {
1265
1308
  getJSON(): string;
1266
1309
  getDescriptors(): FaustUIInputItem[];
1267
1310
  getUI(): FaustUIDescriptor;
1311
+ init(): void;
1312
+ instanceInit(): void;
1313
+ instanceClear(): void;
1314
+ instanceConstants(): void;
1315
+ instanceResetUserInterface(): void;
1268
1316
  start(): void;
1269
1317
  stop(): void;
1270
1318
  destroy(): void;
@@ -1385,13 +1433,6 @@ export declare class SoundfileReader {
1385
1433
  * @returns : the URLs
1386
1434
  */
1387
1435
  static findSoundfilesFromMeta(dspMeta: FaustDspMeta): LooseFaustDspFactory["soundfiles"];
1388
- /**
1389
- * Check if the file exists.
1390
- *
1391
- * @param url : the url of the file to check
1392
- * @returns : true if the file exists, otherwise false
1393
- */
1394
- private static checkFileExists;
1395
1436
  /**
1396
1437
  * Fetch the soundfile.
1397
1438
  *
@@ -1477,6 +1518,11 @@ export declare class FaustAudioWorkletNode<Poly extends boolean = false> extends
1477
1518
  getJSON(): string;
1478
1519
  getUI(): FaustUIDescriptor;
1479
1520
  getDescriptors(): FaustUIInputItem[];
1521
+ init(): void;
1522
+ instanceInit(): void;
1523
+ instanceClear(): void;
1524
+ instanceConstants(): void;
1525
+ instanceResetUserInterface(): void;
1480
1526
  start(): void;
1481
1527
  stop(): void;
1482
1528
  destroy(): void;
@@ -1515,7 +1561,12 @@ export declare class FaustScriptProcessorNode<Poly extends boolean = false> exte
1515
1561
  protected fOutputs: Float32Array[];
1516
1562
  protected handleDeviceMotion: any;
1517
1563
  protected handleDeviceOrientation: any;
1518
- init(instance: Poly extends true ? FaustPolyWebAudioDsp : FaustMonoWebAudioDsp): void;
1564
+ setupNode(instance: Poly extends true ? FaustPolyWebAudioDsp : FaustMonoWebAudioDsp): void;
1565
+ init(): void;
1566
+ instanceInit(): void;
1567
+ instanceClear(): void;
1568
+ instanceConstants(): void;
1569
+ instanceResetUserInterface(): void;
1519
1570
  /** Start accelerometer and gyroscope handlers */
1520
1571
  startSensors(): Promise<void>;
1521
1572
  /** Stop accelerometer and gyroscope handlers */
@@ -6053,6 +6053,26 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
6053
6053
  this.setupWamEventHandler();
6054
6054
  break;
6055
6055
  }
6056
+ case "init": {
6057
+ this.fDSPCode.init();
6058
+ break;
6059
+ }
6060
+ case "instanceInit": {
6061
+ this.fDSPCode.instanceInit();
6062
+ break;
6063
+ }
6064
+ case "instanceClear": {
6065
+ this.fDSPCode.instanceClear();
6066
+ break;
6067
+ }
6068
+ case "instanceConstants": {
6069
+ this.fDSPCode.instanceConstants();
6070
+ break;
6071
+ }
6072
+ case "instanceResetUserInterface": {
6073
+ this.fDSPCode.instanceResetUserInterface();
6074
+ break;
6075
+ }
6056
6076
  case "start": {
6057
6077
  this.fDSPCode.start();
6058
6078
  break;
@@ -8546,7 +8566,7 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
8546
8566
  const trimmed = input.replace(/^\{|\}$/g, "");
8547
8567
  return trimmed.split(";").map(
8548
8568
  (str) => str.length <= 2 ? "" : str.substring(1, str.length - 1)
8549
- );
8569
+ ).map((str) => str.trim()).filter((str) => str.length > 0);
8550
8570
  }
8551
8571
  get hasAccInput() {
8552
8572
  return this.fAcc.x.length + this.fAcc.y.length + this.fAcc.z.length > 0;
@@ -8960,6 +8980,16 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
8960
8980
  stopSensors() {
8961
8981
  this.stopSensors();
8962
8982
  }
8983
+ init() {
8984
+ }
8985
+ instanceInit() {
8986
+ }
8987
+ instanceClear() {
8988
+ }
8989
+ instanceConstants() {
8990
+ }
8991
+ instanceResetUserInterface() {
8992
+ }
8963
8993
  start() {
8964
8994
  this.fProcessing = true;
8965
8995
  }
@@ -8978,6 +9008,7 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
8978
9008
  constructor(instance, sampleRate, sampleSize, bufferSize, soundfiles) {
8979
9009
  super(sampleSize, bufferSize, soundfiles);
8980
9010
  this.fInstance = instance;
9011
+ this.fSampleRate = sampleRate;
8981
9012
  console.log(`sampleSize: ${sampleSize} bufferSize: ${bufferSize}`);
8982
9013
  this.fJSONDsp = JSON.parse(this.fInstance.json);
8983
9014
  FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
@@ -8991,6 +9022,21 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
8991
9022
  this.initSoundfileMemory(allocator, this.fDSP);
8992
9023
  }
8993
9024
  }
9025
+ init() {
9026
+ this.fInstance.api.init(this.fDSP, this.fSampleRate);
9027
+ }
9028
+ instanceInit() {
9029
+ this.fInstance.api.instanceInit(this.fDSP, this.fSampleRate);
9030
+ }
9031
+ instanceClear() {
9032
+ this.fInstance.api.instanceClear(this.fDSP);
9033
+ }
9034
+ instanceConstants() {
9035
+ this.fInstance.api.instanceConstants(this.fDSP, this.fSampleRate);
9036
+ }
9037
+ instanceResetUserInterface() {
9038
+ this.fInstance.api.instanceResetUserInterface(this.fDSP);
9039
+ }
8994
9040
  initMemory() {
8995
9041
  this.fDSP = 0;
8996
9042
  const $audio = this.fJSONDsp.size;
@@ -9140,7 +9186,6 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
9140
9186
  this.fGainLabel = [];
9141
9187
  this.fKeyLabel = [];
9142
9188
  this.fVelLabel = [];
9143
- // Voice DSP code
9144
9189
  // Accessed by PolyDSPImp class
9145
9190
  this.fCurNote = _FaustWebAudioDspVoice.kFreeVoice;
9146
9191
  this.fNextNote = -1;
@@ -9149,7 +9194,8 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
9149
9194
  this.fLevel = 0;
9150
9195
  this.fDSP = $dsp;
9151
9196
  this.fAPI = api;
9152
- this.fAPI.init(this.fDSP, sampleRate);
9197
+ this.fSampleRate = sampleRate;
9198
+ this.init(sampleRate);
9153
9199
  this.extractPaths(inputItems, pathTable);
9154
9200
  }
9155
9201
  // Voice state
@@ -9177,6 +9223,21 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
9177
9223
  static normalizeVelocity(velocity) {
9178
9224
  return velocity / 127;
9179
9225
  }
9226
+ init(sampleRate) {
9227
+ this.fAPI.init(this.fDSP, sampleRate);
9228
+ }
9229
+ instanceInit() {
9230
+ this.fAPI.instanceInit(this.fDSP, this.fSampleRate);
9231
+ }
9232
+ instanceClear() {
9233
+ this.fAPI.instanceClear(this.fDSP);
9234
+ }
9235
+ instanceConstants() {
9236
+ this.fAPI.instanceConstants(this.fDSP, this.fSampleRate);
9237
+ }
9238
+ instanceResetUserInterface() {
9239
+ this.fAPI.instanceResetUserInterface(this.fDSP);
9240
+ }
9180
9241
  extractPaths(inputItems, pathTable) {
9181
9242
  inputItems.forEach((item) => {
9182
9243
  if (item.endsWith("/gate")) {
@@ -9257,6 +9318,7 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
9257
9318
  constructor(instance, sampleRate, sampleSize, bufferSize, soundfiles) {
9258
9319
  super(sampleSize, bufferSize, soundfiles);
9259
9320
  this.fInstance = instance;
9321
+ this.fSampleRate = sampleRate;
9260
9322
  console.log(`sampleSize: ${sampleSize} bufferSize: ${bufferSize}`);
9261
9323
  this.fJSONDsp = JSON.parse(this.fInstance.voiceJSON);
9262
9324
  this.fJSONEffect = this.fInstance.effectAPI && this.fInstance.effectJSON ? JSON.parse(this.fInstance.effectJSON) : null;
@@ -9288,6 +9350,37 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
9288
9350
  }
9289
9351
  }
9290
9352
  }
9353
+ init() {
9354
+ this.fVoiceTable.forEach((voice) => voice.init(this.fSampleRate));
9355
+ if (this.fInstance.effectAPI)
9356
+ this.fInstance.effectAPI.init(this.fEffect, this.fSampleRate);
9357
+ }
9358
+ instanceInit() {
9359
+ this.fVoiceTable.forEach((voice) => voice.instanceInit());
9360
+ if (this.fInstance.effectAPI)
9361
+ this.fInstance.effectAPI.instanceInit(
9362
+ this.fEffect,
9363
+ this.fSampleRate
9364
+ );
9365
+ }
9366
+ instanceClear() {
9367
+ this.fVoiceTable.forEach((voice) => voice.instanceClear());
9368
+ if (this.fInstance.effectAPI)
9369
+ this.fInstance.effectAPI.instanceClear(this.fEffect);
9370
+ }
9371
+ instanceConstants() {
9372
+ this.fVoiceTable.forEach((voice) => voice.instanceConstants());
9373
+ if (this.fInstance.effectAPI)
9374
+ this.fInstance.effectAPI.instanceConstants(
9375
+ this.fEffect,
9376
+ this.fSampleRate
9377
+ );
9378
+ }
9379
+ instanceResetUserInterface() {
9380
+ this.fVoiceTable.forEach((voice) => voice.instanceResetUserInterface());
9381
+ if (this.fInstance.effectAPI)
9382
+ this.fInstance.effectAPI.instanceResetUserInterface(this.fEffect);
9383
+ }
9291
9384
  initMemory() {
9292
9385
  this.fEffect = this.fJSONDsp.size * this.fInstance.voices;
9293
9386
  const $audio = this.fEffect + (this.fJSONEffect ? this.fJSONEffect.size : 0);
@@ -9744,6 +9837,21 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
9744
9837
  getUI() {
9745
9838
  return this.fDSPCode.getUI();
9746
9839
  }
9840
+ init() {
9841
+ this.fDSPCode.init();
9842
+ }
9843
+ instanceInit() {
9844
+ this.fDSPCode.instanceInit();
9845
+ }
9846
+ instanceClear() {
9847
+ this.fDSPCode.instanceClear();
9848
+ }
9849
+ instanceConstants() {
9850
+ this.fDSPCode.instanceConstants();
9851
+ }
9852
+ instanceResetUserInterface() {
9853
+ this.fDSPCode.instanceResetUserInterface();
9854
+ }
9747
9855
  start() {
9748
9856
  this.fDSPCode.start();
9749
9857
  }
@@ -9807,7 +9915,7 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
9807
9915
  outputs[i].set(output, l);
9808
9916
  }
9809
9917
  }
9810
- l += this.fBufferSize;
9918
+ l += sliceLength;
9811
9919
  onUpdate == null ? void 0 : onUpdate(l);
9812
9920
  }
9813
9921
  this.fDSPCode.stop();
@@ -10356,29 +10464,12 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
10356
10464
  const callback = (item) => {
10357
10465
  if (item.type === "soundfile") {
10358
10466
  const urls = FaustBaseWebAudioDsp.splitSoundfileNames(item.url);
10359
- urls.forEach((url) => soundfiles[url] = null);
10467
+ urls.filter((url) => url.trim().length > 0).forEach((url) => soundfiles[url] = null);
10360
10468
  }
10361
10469
  };
10362
10470
  FaustBaseWebAudioDsp.parseUI(dspMeta.ui, callback);
10363
10471
  return soundfiles;
10364
10472
  }
10365
- /**
10366
- * Check if the file exists.
10367
- *
10368
- * @param url : the url of the file to check
10369
- * @returns : true if the file exists, otherwise false
10370
- */
10371
- static async checkFileExists(url) {
10372
- try {
10373
- console.log(`"checkFileExists" url: ${url}`);
10374
- const response = await fetch(url);
10375
- console.log(`"checkFileExists" response.ok: ${response.ok}`);
10376
- return response.ok;
10377
- } catch (error) {
10378
- console.error("Fetch error:", error);
10379
- return false;
10380
- }
10381
- }
10382
10473
  /**
10383
10474
  * Fetch the soundfile.
10384
10475
  *
@@ -10413,17 +10504,20 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
10413
10504
  (path) => new URL(filename, path.endsWith("/") ? path : `${path}/`).href
10414
10505
  )
10415
10506
  ];
10416
- const checkResults = await Promise.all(
10417
- urlsToCheck.map((url) => this.checkFileExists(url))
10418
- );
10419
- const successIndex = checkResults.findIndex((r) => !!r);
10420
- if (successIndex === -1)
10421
- throw new Error(
10422
- `Failed to load sound file ${filename}, all check failed.`
10423
- );
10424
- soundfiles[filename] = await this.fetchSoundfile(
10425
- urlsToCheck[successIndex],
10426
- audioCtx
10507
+ let lastError = null;
10508
+ for (const url of urlsToCheck) {
10509
+ try {
10510
+ soundfiles[filename] = await this.fetchSoundfile(
10511
+ url,
10512
+ audioCtx
10513
+ );
10514
+ return;
10515
+ } catch (error) {
10516
+ lastError = error;
10517
+ }
10518
+ }
10519
+ throw new Error(
10520
+ `Failed to load sound file ${filename}, all check failed. Last error: ${String(lastError)}`
10427
10521
  );
10428
10522
  }
10429
10523
  /**
@@ -10801,7 +10895,10 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
10801
10895
  }
10802
10896
  setParamValue(path, value) {
10803
10897
  const resolved = this.fParamAliases[path] || path;
10804
- this.port.postMessage({ type: "param", data: { path: resolved, value } });
10898
+ this.port.postMessage({
10899
+ type: "param",
10900
+ data: { path: resolved, value }
10901
+ });
10805
10902
  const param = this.parameters.get(resolved);
10806
10903
  if (param) param.setValueAtTime(value, this.context.currentTime);
10807
10904
  }
@@ -10825,6 +10922,21 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
10825
10922
  getDescriptors() {
10826
10923
  return this.fDescriptor;
10827
10924
  }
10925
+ init() {
10926
+ this.port.postMessage({ type: "init" });
10927
+ }
10928
+ instanceInit() {
10929
+ this.port.postMessage({ type: "instanceInit" });
10930
+ }
10931
+ instanceClear() {
10932
+ this.port.postMessage({ type: "instanceClear" });
10933
+ }
10934
+ instanceConstants() {
10935
+ this.port.postMessage({ type: "instanceConstants" });
10936
+ }
10937
+ instanceResetUserInterface() {
10938
+ this.port.postMessage({ type: "instanceResetUserInterface" });
10939
+ }
10828
10940
  start() {
10829
10941
  this.port.postMessage({ type: "start" });
10830
10942
  }
@@ -10921,7 +11033,7 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
10921
11033
  this.handleDeviceMotion = void 0;
10922
11034
  this.handleDeviceOrientation = void 0;
10923
11035
  }
10924
- init(instance) {
11036
+ setupNode(instance) {
10925
11037
  this.fDSPCode = instance;
10926
11038
  this.fInputs = new Array(this.fDSPCode.getNumInputs());
10927
11039
  this.fOutputs = new Array(this.fDSPCode.getNumOutputs());
@@ -10951,6 +11063,21 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
10951
11063
  };
10952
11064
  this.start();
10953
11065
  }
11066
+ init() {
11067
+ this.fDSPCode.init();
11068
+ }
11069
+ instanceInit() {
11070
+ this.fDSPCode.instanceInit();
11071
+ }
11072
+ instanceClear() {
11073
+ this.fDSPCode.instanceClear();
11074
+ }
11075
+ instanceConstants() {
11076
+ this.fDSPCode.instanceConstants();
11077
+ }
11078
+ instanceResetUserInterface() {
11079
+ this.fDSPCode.instanceResetUserInterface();
11080
+ }
10954
11081
  // Public API
10955
11082
  /** Start accelerometer and gyroscope handlers */
10956
11083
  async startSensors() {
@@ -11168,7 +11295,7 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
11168
11295
  monoDsp.getNumOutputs()
11169
11296
  );
11170
11297
  Object.setPrototypeOf(sp2, FaustMonoScriptProcessorNode.prototype);
11171
- sp2.init(monoDsp);
11298
+ sp2.setupNode(monoDsp);
11172
11299
  return sp2;
11173
11300
  } else {
11174
11301
  if (!_FaustMonoDspGenerator.gWorkletProcessors.has(context))
@@ -11552,7 +11679,7 @@ process = adaptorIns(dsp_code.process) : dsp_code.effect : adaptorOuts;
11552
11679
  polyDsp.getNumOutputs()
11553
11680
  );
11554
11681
  Object.setPrototypeOf(sp2, FaustPolyScriptProcessorNode.prototype);
11555
- sp2.init(polyDsp);
11682
+ sp2.setupNode(polyDsp);
11556
11683
  return sp2;
11557
11684
  } else {
11558
11685
  if (!_FaustPolyDspGenerator.gWorkletProcessors.has(context))