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
627 stars 41 forks source link

Where is vectorFloat defined/documented? #96

Closed Oortone closed 2 years ago

Oortone commented 2 years ago

What is the issue about?

What part(s) of Essentia.js is involved?

Description

Essentia uses it's own class for data: vectorFloat, but I can't find where it's documented. I managed to figure out the method .size() by myself but surely it's documented somewhere? I searched this repository and also looked at the class documentation: (https://mtg.github.io/essentia.js/docs/api/Essentia.html)

Steps to reproduce / Code snippets / Screenshots

-

System info

not related to my system, Essentia.js 0.1.3

ljoglar commented 2 years ago

Hi Oortone,

I am not sure if this will help you. I don't think there is a documentation of the vectorFloat in essentia.js as this is C++ type. But here you have the documentation of two functions that allow to convert from (and to) vectorFloat to js array.

https://mtg.github.io/essentia.js/docs/api/Essentia.html#vectorToArray

https://mtg.github.io/essentia.js/docs/api/Essentia.html#arrayToVector

If this is not what you need, please let us know and we'll try to help you.

Luis.

albincorreya commented 2 years ago

Adding to what @ljoglar said, VectorFloat is a convenient template wrapper around std:vector<T> C++ types from Emcripten's Embind. Check here for more details.

But thanks for the feedback, we will improve the documentation on next iteration.

Oortone commented 2 years ago

OK, I see. I don't know much about the Emscripten side of this. So does that mean that all methods described in std::vector will normally also work in Javascript in this case?

Is there some way to know when a type used in Essentia is in fact C++ so I should look in C++ documentation there for usage details?

albincorreya commented 2 years ago

Yes, and this is not Essentia.js specific. It is how Embind interfaces C++ code to JS so that we can C++ algorithms from JS. This section describes an example with C++ and JS code to show how it is mapped.

Check this line to see the types exposed on the JS front using the Embind bindings for the Essentia WASM build. This is taken care of by Emscripten.

For example, the following shows a mapping between JS, C++, and types defined in the Essentia upstream documentation.

 VectorFloat (JS side) -> std::vector<float> (C++) -> VectorReal (Essentia upstream documentation)

Probably a good idea that we create a table of mapping between these types in the Essentia.js documentation as well for clarity.

Hope it helps for now!

Oortone commented 2 years ago

Yes, that helps, thanks.

Oortone commented 2 years ago

Still, it seems i don't get this. A lot of the usual C++ std::vector methods are not available for my VectorFloat from an Essentia call to MelBands; like [], at(), front(), clear().

Methods get() and set() works as a replacement for [] but these are not in the std::vector documentation.

Seems I'm still missing the link here between C++ and Javascript. Where do I go to find where the correspondance between types like std::vector<float> and VectorFloat is described and especially additional methods like get() and set() which are hard to guess?

Oortone commented 2 years ago

OK, I found the answer somehow. It's in the emscripten bind.h source file in the declaration of register_vector it's possible from this to figure out what methods are implemented for VectorFloat, VectorInt e.t.c. Not so many:

template<typename T>
class_<std::vector<T>> register_vector(const char* name) {
    typedef std::vector<T> VecType;

    void (VecType::*push_back)(const T&) = &VecType::push_back;
    void (VecType::*resize)(const size_t, const T&) = &VecType::resize;
    size_t (VecType::*size)() const = &VecType::size;
    return class_<std::vector<T>>(name)
        .template constructor<>()
        .function("push_back", push_back)
        .function("resize", resize)
        .function("size", size)
        .function("get", &internal::VectorAccess<VecType>::get)
        .function("set", &internal::VectorAccess<VecType>::set)
        ;
}

The bind.h documentation says "under construction" and the information is not present there. Maybe some day...

Hope this can be of help to others failing to find the Emscripten information easily.