This week I discovered audioconverter.js which is basically an ffmpeg audio converted translated to javascript using emscripten emscripten.

I was so amazed that I decided to spend some time trying to port a small library to javascript, and learn a little more how it works.

For who like me before, don't know what emscripten is there is a really complete wiki on the github wiki page. Basically you compile using llvm (a compiler like gcc) but instead to create machine code you specify to create bytecode, which is a internal data structure to do all the optimizations before translating the bytecode to asm. Once the bytecode is created emscripten translates it to asm.js (which is a subset of javascript with basic operations like asm, but I don't really understand how it works)

To port a c library to javascript is not a easy task, and at first I was really lost, until I found this tutorial where alon zakai shows how to port the library.

You can find the final code on my github with some samples and the scripts to compile the library.

Some tips I learned during this toy project..

  • try to compile the library with clang before using emscripten, and patch everything to make it compile. Much of libraries are made to compile with gcc and not tested with other compilers, so possibly you may have to patch some lines of code.  Here is my patch. basically disable float stuff and warning on configure script file
  • You have to path to convert the C code to javascript
  • convert directly some executable and just throw the command line inside your javascript wrapper. Which is really nice because is so easy to integrate as calling with the same parameters of the command line, but also is really slow. I just ported img2txt executable, and almost last for 2 or 3 seconds to dump the image to text.
  • convert the library itself and use it on your js code, that is much faster than the previous approach but you will have to manage with memory allocations and need a better understanding of how emscripten and memory works. 

Finally here is my notes, with a bit more detail of how it was done and the problems on the way. libcaca.js - raw notes