Hi, I'd like to use https://github.com/adamstark/Gist in a Bela project but I'm having trouble getting it to build.

Minimal example:

#include <Bela.h>
#include "Gist.h"

bool setup(BelaContext context, void userData)
{
int frameSize = 512;
Gist<float> gist (frameSize, context->audioSampleRate);
return true;
}

etc...

...upon building produces the linker error:

/root/Bela/projects/gist/build/render.o: In function setup':/root/Bela/projects/gist/render.cpp:(.text+0x20): undefined reference toGist::Gist(int, int, WindowType)'/root/Bela/projects/gist/render.cpp🙁.text+0x28): undefined reference to `Gist::~Gist()'

It's not clear to me why this is, because at the end of Gist.cpp we have the explicit instantiation:

template class Gist<float>;

Any advice would be greatly appreciated.
Thank you,

-Elbow

Did you include any of the .cpp files from the library? The header files (.h) contain the declaration of the classes, but the implementation is normally in one (or more!) .cpp file(s). I see that Gist doesnt' come with installation documentation (or Makefile), but it should be as straightforward as the classic "keep the folder structure, compile all the cpp files to the corresponding .o file and then link them all together". In fact this issue seems to suggest exactly that. Unfortunately, this approach does not really go well with the Bela IDE (as you currently cannot upload folders and subfolders), and even if you were able to recreate the folder structure on the board, it would not go well with the Bela build system (as it does not - by default - build the .cpp files inside subfolders).

First off, download the Gist repo on your computer. Commands below are to be run from a terminal.
In the commands below, replace /path/to/Gist with the actual folder to which you have downloaded Gist on your computer.
Additionally, add the line

#include <stddef.h>

at the top of the file src/mfcc/MFCC.h. This is probably a bug in the library.

So, two approaches:

First approach, a bit hacky, good as a starting point and if you only need Gist in one project (as you'd have to repeat the procedure for any new project (or just Save as the current project if you need to start another one)), but also the only one that is working properly currently.

  • Create a Bela project gistproject. This will need its render.cpp file in place.
  • Copy the whole content of the Gist/src/ folder as it is (and the kiss_fft130 one, too) to the Bela project :
    scp -r /path/to/Gist/src/* /path/to/Gist/libs/kiss_fft130/* root@192.168.7.2:Bela/projects/gistproject/ 
  • create a link from each of the files in the subfolders to the project's folder. Run on your computer:
     ssh root@192.168.7.2 "cd Bela/projects/gistproject && find * -type f -exec ln -s {} \; && rm Accelerate*"
    (this will print a few warnings but that is fine)
  • add #include "Gist.h" at the top of your render.cpp file and then put your Gist code in the rest of the file
  • add CPPFLAGS=-DUSE_KISS_FFT to the Make parameters in the IDE
  • Build the project as normal.
  • Success!

Second approach, supposedly "proper": build Gist as a shared library and reuse it easily in any project. However, this errors at runtime. Not sure why.

  • Copy the whole content of the gist/src/ folder to your board : download the gist repo on your computer (let's say in /path/to/gist (replace it below with the actual path on your computer)) and run from a terminal :
    scp /path/to/Gist/src/ root@192.168.7.2:Gist
  • Log into the board:
    ssh root@192.168.7.2
    the following commands are to be run on the board
    cd Gist
    # build the object files
    mkdir build
    for file in libs/kiss_fft130/kiss_fft.c `find . -name "*.cpp" | grep -v "Accelerate\|test\|Python"`; do clang $file -c -o build/`basename $file`.o -DUSE_KISS_FFT -Ilibs/kiss_fft130/ -O3  -march=armv7-a -mtune=cortex-a8 -mfloat-abi=hard -mfpu=neon -ftree-vectorize -ffast-math -DNDEBUG -fPIC; done
    # create the library and copy it to /usr/local/lib
    clang++ -shared -Wl,-soname,libgist.so  -o /usr/local/lib/libgist.so build/*
    # refresh the list of installed library for the dynamic linker
    ldconfig /usr/local/lib/libgist.so
    # install the header files
    mkdir -p /usr/local/include/Gist
    cd src
    find . -type d -exec mkdir -p /usr/local/include/Gist/{} \;
    find . -name "*.h" -exec cp {} /usr/local/include/Gist/{} \;
    cp ../libs/kiss_fft130/kiss_fft.h /usr/local/include/Gist
  • now hopefully you should be able to follow the instructions in here : simply add LDLIBS=-lgist to your Make parameters in the IDE for any project that wants to use gist, and use #include <Gist/Gist.h>.
  • For an unknown reason, as mentioned, you get a Segmentation fault at runtime when running your code above. If you use new instead of creating the object on the stack, the code runs but when you stop the program, you get corrupted size vs. prev_size: 0x01691e68 ***.

Thank you very much for the thorough and detailed help! (I'm now worried I've forgotten so much after a long hiatus and using only python!)
It's building just fine now using either Kiss FFT or FFTW. I'm guessing I could squeeze a bit more performance by incorporating the Ne10 FFT into Gist.

Thank you again!

2 years later

@elbow-macaroni now after an even longer hiatus, I'm curious if you got anywhere with this. I'm not a c++ person but I'm looking around for examples of implementing spectral audio descriptors such as MFCC in bela.