MTG / essentia.js

JavaScript library for music/audio analysis and processing powered by Essentia WebAssembly
https://essentia.upf.edu/essentiajs
GNU Affero General Public License v3.0
628 stars 41 forks source link

Pass all algorithm parameters to JS API as a single JS object #68

Open albincorreya opened 2 years ago

albincorreya commented 2 years ago

Description

Modify JS interface to accept algorithm parameters as a single JS object instead of passing it as different function argument variables.

Why?

Currently, our JS interface allows passing algorithm parameters as function arguments which is similar to the Python bindings of the upstream library. All the algorithms in Essentia have default values for each parameter unless the user specified any custom one.

Since the order of function argument matters in JS. ie. If you want to modify the 5th function argument, you need to provide values for the first 4 function arguments. This cannot be optimal for developer experience since Essentia.js has algorithms that have more than 15 parameters.

Modifying the Typescript wrapper of Essentia.js to pass algorithm parameters as a single JS object will mitigate this issue. ie. Developers can specify algorithm parameters with a JS object with only selected parameters they wanted to modify.

How?

This can be potentially achieved by modifying the code_generator.py script to generate the Typescript wrapper code with the newly modified interface. Note that the code generator for the C++ wrapper doesn't need to change.

For example, in the case of LogSpectrum algorithm, some similar logic like below can be applied to achieve the desired change.


  type ParamsLogSpectrum = {
    binsPerSemitone?: number=3,
    frameSize?: number=1025, 
    rollOn?: number=0,
    sampleRate?: number=44100
  }

  LogSpectrum(spectrum: any, params: ParamsLogSpectrum) {

    // TODO: add logic to modify the values of params according to user input
    // otherwise fallback to default
    return this.algorithms.LogSpectrum(
      spectrum,
      params.binsPerSemitone,
      params.frameSize,
      params.rollOn,
      params.sampleRate
    );
  }

in case we switch to the object-oriented interface (see #64) for algorithms in the future. This change can be defined in its configure method.

jmarcosfer commented 2 years ago

@albincorreya I think when we switch to object-oriented interface, this change should be applied to the class instantiation (i.e. constructor) not the compute method, right? At least that's how I imagined it would be in #64...

albincorreya commented 2 years ago

@jmarcosfer Yes, you are right It was a typo. The change should be on the configure method (which can be called on the constructor).