Hi, I have downloaded and compiled the essentia library (https://essentia.upf.edu/installing.html#compiling-essentia) in the folder usr/local/include. I don't know much about cmake but I couldn't find any *.so files in the library, only *.cpp/h.

I have now added it to my render.cpp file:

#include <essentia/algorithmfactory.h>
#include <essentia/pool.h>

and I have tried to compile using (from ~/Bela/)

 make PROJECT=project-name CPPFLAGS=-I/usr/local/include/essentia-2.1_beta5/ run

but I get this error:

fatal error: 'essentia/algorithmfactory.h' file not found

That file is in /usr/local/include/essentia-2.1_beta5/src/essentia/. I have also tried to run the make command passing that path as the CPPFLAGS=-Ipath but with no success.

How can I add the library to my project? what am I doing wrong?
Thanks!

I tried this and got somewhere.

Prerequisites

First: get yourself a bela image v0.5.0alpha2 or higher from https://github.com/BelaPlatform/bela-image-builder/releases
It may be that things work the same on earlier images, but why bother?

Second: you need to have your board connected to the internet in order to install dependencies. This is most easily done plugging the BeagleBone's ethernet port into a home router. If that is not possible (e.g.: you have a BelaMini), other solutions can be found (e.g.: internet sharing from host computer, wifi dongles etc).

Start here

(all commands below to be run on the board)

# install dependencies. This is a subset of all dependencies. You may want to add more if you need more features
apt-get install -y libyaml-dev libfftw3-dev libtag1-dev libeigen3-dev libsamplerate0-dev
# if the board is not connected to the internet, the above command will fail. Fix it and repeat till it goes through.

cd /root
git clone --recursive git@github.com:MTG/essentia.git
cd essentia
# configure project with minimal options
python3 waf configure --build-static

this gives me the following:

================================ CONFIGURATION SUMMARY ================================
- using FFTW for FFT

- fftw detected!
- FFmpeg (or LibAv on debian/ubuntu) seems to be missing.
  The following algorithms will be ignored: ['AudioLoader', 'MonoLoader', 'EqloudLoader', 'EasyLoader', 'MonoWriter', 'AudioWriter']

- libsamplerate (SRC) detected!
  The following algorithms will be included: ['Resample']

- TagLib detected!
  The following algorithms will be included: ['MetadataReader', 'MusicExtractor', 'FreesoundExtractor']

- libyaml detected!
  The following algorithms will be included: ['YamlInput', 'YamlOutput']

- Essentia is configured without Gaia2.
  The following algorithms will be ignored: ['GaiaTransform', 'MusicExtractorSVM']
  Examples requiring Gaia2 will be ignored

- Essentia is configured without Chromaprint.
  The following algorithms will be ignored: ['Chromaprinter']
- Essentia is configured without Tensorflow.
  The following algorithms will be ignored: ['TensorflowPredict', 'TensorflowPredictMusiCNN', 'TensorflowPredictVGGish', 'TensorflowPredictTempoCNN', 'TensorflowPredictCREPE', 'PitchCREPE', 'TempoCNN', 'TensorflowPredictEffnetDiscogs']
Building all the algorithms
Ignoring the following algorithms: EasyLoader, MusicExtractorSVM, AudioWriter, Chromaprinter, IFFTKComplex, IFFTAComplex, TensorflowPredictVGGish, IFFTA, EqloudLoader, FFTK, FFTA, MonoWriter, TensorflowPredictCREPE, FFTAComplex, TempoCNN, GaiaTransform, FFTKComplex, TensorflowPredictEffnetDiscogs, TensorflowPredictTempoCNN, AudioLoader, IFFTK, MonoLoader, TensorflowPredict, TensorflowPredictMusiCNN, PitchCREPE
Created algorithms registration file

I guess not installing tensorflow means we are missing out on some features ... if you need those, then look for how to install tensorflow.

Now you can build

python3 waf

this will take a while.

Once done, bring up the Bela IDE, select or create a suitable project and put the following in render.cpp:

#include <Bela.h>
#include <essentia/algorithmfactory.h>
#include <essentia/pool.h>

bool setup(BelaContext *context, void *userData)
{
        return true;
}

void render(BelaContext *context, void *userData)
{
}

void cleanup(BelaContext *context, void *userData)
{
}

If you run the project as is, it will fail with a similar error to the one you had. This is because the compiler (the C preprocessor, actually) needs to know where to find the essentia/algorithmfactory.h file. This is located in /root/essentia/src, so you need to pass -I /root/essentia/src to the preprocessor, where -I stands for: add this path to the search path. To pass options to the C preprocessor, you need to add CPPFLAGS=-I/root/essentia/src to the Make parameters box in the project settings in the IDE. This will fail again with

In file /root/essentia/src/essentia/types.h: 'unsupported/Eigen/CXX11/Tensor' file not found column: 10, line: 33

Despite the confusing unsupported in there, this is the same class of errors as above and it means that there is another include folder missing. This is harder to locate, because it's not within /root/essentia. As it turns out, this path is from one of the dependencies. You can find it with e.g.: apt-file search Tensor | grep Eigen or - assuming it's already installed as Essentia was built correctly - find /usr/include /usr/local/include -name Tensor -type f. The file is in /usr/include/eigen3/unsupported/Eigen/CXX11/Tensor, so again we need to add another -I, this time with /usr/include/eigen3. Update the Make parameters box with CPPFLAGS=-I/root/essentia/src -I/usr/include/eigen3 and rebuild. This will now build successfully.

Note that the moment you start using some of the Essentia-provided classes/functions, you will get a link time error. We need to tell the linker to link in libessentia. Given how we built with --build-static, we didn't get a .so dynamic file, but a .a static file. find /root/essentia/build -name "*.a" reveals it to be /root/essentia/build/src/libessentia.a. The easiest way to add this to our project is to pass another parameter to make: LDLIBS=/root/essentia/build/src/libessentia.a.

All in all, your project's make parameters box should look like this:

CPPFLAGS=-I/root/essentia/src -I/usr/include/eigen3;LDLIBS=/root/essentia/build/src/libessentia.a

(note the awkward quotes-less with-semicolon syntax)

If you are building from the command line on the board, you should use something like this instead:

make -C ~/Bela PROJECT=yourproject CPPFLAGS="-I/root/essentia/src -I/usr/include/eigen3" LDLIBS=/root/essentia/build/src/libessentia.a

If you are building from a remote host via the build_project.sh script, then you can pass these options via the -m switch and careful use of quotes, e.g.:

./build_project.sh .... -m 'CPPFLAGS="-I/root/essentia/src -I/usr/include/eigen3" LDLIBS=/root/essentia/build/src/libessentia.a'

At some point you may decide to simplify this a bit. Per the essentia documentation, you can run python3 waf install from within /root/essentia to install the library. This generates:

+ install /usr/local/lib/libessentia.a (from build/src/libessentia.a)
+ install /usr/local/lib/pkgconfig/essentia.pc (from build/essentia.pc)
+ install /usr/local/include/essentia/algorithm.h (from src/essentia/algorithm.h)
+ install /usr/local/include/essentia/algorithmfactory.h (from src/essentia/algorithmfactory.h)
+ install /usr/local/include/essentia/algorithmfactory_impl.h (from src/essentia/algorithmfactory_impl.h)
+ install /usr/local/include/essentia/config.h (from src/essentia/config.h)
...
...
...
+ install /usr/local/include/essentia/utils/tnt/tnt_version.h (from src/essentia/utils/tnt/tnt_version.h)
+ install /usr/local/include/essentia/utils/yamlast.h (from src/essentia/utils/yamlast.h)
+ install /usr/local/include/essentia/version.h (from src/version.h)
+ install /usr/local/lib/pkgconfig/essentia.pc (from build/essentia.pc)

which shows that libessentia.a is now in /usr/local/lib and the essentia/ includes have been copied to /usr/local/include/. Both of these are standard system folders, which means:

  • the preprocessor can find the includes in /usr/local/include and you no longer need to specify -I/root/essentia/src/
  • the linker can find libessentia.a by passing it -lessentia instead of the full path to the .a file

So, with essentia installed on your system, you could simplify your flags above as follows:

In the IDE's make parameters:

CPPFLAGS=-I/usr/include/eigen3;LDLIBS=-lessentia

Building locally:

make -C ~/Bela PROJECT=yourproject CPPFLAGS=-I/usr/include/eigen3 LDLIBS=-lessentia

Building via build_project.sh:

./build_project.sh .... -m 'CPPFLAGS=-I/usr/include/eigen3 LDLIBS=/root/essentia/build/src/libessentia.a'