Monday, July 11, 2011

Installing LibSndFile with xcode + OpenFrameworks

If you're looking to load audio files (wav, aiff, etc.) and process them on a sample-by-sample basis for basic DSP needs, the best option available appears to be the 'libsndfile' library: http://www.mega-nerd.com/libsndfile/

I am not well versed when it comes to the unix terminal, and the notion of building libraries from source gives me the heebie jeebies. If you're like me, the next few paragraphs might be of help.  

To obtain the library, i used macports, but I have it on good authority that homebrew is a better choice for managing your code libraries. Assuming you've installed macports, you should enter the following commands into a terminal window. 

> sudo port - d selfupdate
> sudo port install libsndfile

Aside - If your mac has a Core 2 Duo processor or higher, it's very likely that your machine's architecture is 64-bit or 'X86_64' in the xcode parlance. If this is the case, the above command will build a X86_64 version of the library. This is all well and good, but the OpenFrameworks examples are configured to build for the i386 32-bit architecture. As such, you'll have to execute the following command to make sure the libsndfile library is built to work with the 32-bit OF libraries, and can play nicely with the OpenFrameworks code. Again, this is probably painfully obvious to any C/C++ programmer, but it wasn't immediately obvious to me. If you're encountering a build error along the lines of "libsndfile.dylib is built blah blah blah and not the target architecture i386", try to reinstall libsndfile with the +universal argument as shown below:

> sudo port install libsndfile +universal


Once this is complete you should open your OpenFrameworks project, or copy/paste/rename one of the existing example projects in the OpenFrameworks download. For instance, I used the 'soundPlayerFFTExample' project. In xcode, do the following: 

Project ->add to Project...

Add the following three files:
/your_mac_HD/opt/local/include/sndfile.h (the C header file)
/your_mac_HD/opt/local/include/sndfile.hh (the C++ wrappers for libsndfile)
/your_mac_HD/opt/local/lib/libsndfile.a (the library)

At the top of your main C/C++ file i.e. in 'testApp.cpp' you should add an include statement for the libsndfile library, and then some testing code in the body of the setup() method (Please make sure to actually specify a valid path to a wav file in the declaration of fn):

#include "testApp.h"
#include <sndfile.hh>
#include <stdio.h>


void testApp::setup(){

.
.
.


const char* fn = "/Users/.../test.wav";
SndfileHandle myf = SndfileHandle(fn);
printf ("Opened file '%s'\n", fn) ;
printf ("    Sample rate : %d\n", myf.samplerate ()) ;
printf ("    Channels    : %d\n", myf.channels ()) ;
printf ("    Error       : %s\n", myf.strError());
printf ("    Frames      : %d\n", int(myf.frames())); // frames is essentially samples
puts("");
.
.
.



Build and run your project, open your xcode console (Run -> console), and you should hopefully see something like this:

run
[Switching to process 11816]
Running…
Opened file '/Users/Jack/Documents/coles.wav'
    Sample rate : 44100
    Channels    : 2
    Error : No Error.
    Frames : 161943

If you get meaningful data for the sample rate, number of channels, and frame number, you're in business! If you get bogus values, ensure that the path you specified to the file is correct. Again, this is probably quite trivial for the C/C++ programmers coming to OpenFrameworks, but for the Processing, Flash, Java, and Matlab users, hopefully you'll find this helpful. 



8 comments:

  1. hi Jack,
    i had some problems using libsndfile.a inside OF,
    but i then found this link,
    http://mumble.sourceforge.net/BuildingMacOSX
    which shows how to build a i386 and ppc version of the library and then merge them together into a universal... this process created libsndfile.1.dylib which is working inside OF.

    ReplyDelete
  2. Hey Julapy,

    Thanks for posting this. I'm sure this will be helpful to others with the same problem. Thanks again!

    ReplyDelete
  3. Hey Jack, thanks for your effort, successfully installed it.

    ReplyDelete
  4. How do you add to the project, if I try to "add files to " then when I try to compile I get 68 build errors.

    ReplyDelete
  5. Hey, what kind of build errors are you getting?

    ReplyDelete
  6. In my case, insted of adding libsndfile.a I had to go to frameworks and libraries in Xcode and add libsndfile.dylib there

    ReplyDelete
  7. Hi, having a few problems getting it working with Xcode. With sudo port - d self update: Error: "port d" is ambiguous, but :sudo port install libsndfile= installs. I have the 3 files in the correct folders, but Xcode keeps telling me sniffle.h file not found. Any help would be most appreciated.

    ReplyDelete
  8. Hey Jack,
    Thanks for this post, it is quite helpful. I realised though that you might want to use another variant when installing libsndfile with mac ports:
    sudo port install libsndfile +universal +no_external_libs

    The no_external_libs tells it to not include support for FLAC, ogg, ... which gave me 60+ linking errors in Xcode afterwards. Without those external libs, then it works fine!

    ReplyDelete