SoundFileLib

The SoundFileLib is based on libsndfile. The libsndfile library does the heavy lifting of dealing with the bazillion different file formats used for audio. To include support for FLAC, we have to compile libflac, and it depends on libvorbis which depends on libogg. So we have to build all of this stuff into static libraries. Furthermore, the static libraries need to be universal binaries supporting both 32-bit (e.g. for Max) and 64-bit (e.g. for Ruby) architectures.

Issues and Concerns

This section initially culled from http://redmine.jamoma.org/issues/359

This is a not fun task. Here are some options:

As a base option, we can use libsndfile from http://www.mega-nerd.com/libsndfile/
More complicated, but we could use LAME (which uses:), or directly use http://www.mpg123.de/ -- there are a host of complications though. Conflicting versions, dependencies, licensing, etc. And to supporting anything with MP3 we have to be scared about patents and lawyers.
FFmpeg is another option. It is supposed to be a new and improved libsndfile, supporting various media formats. However, check this out: https://roundup.ffmpeg.org/roundup/ffmpeg/issue732 -- I don't think I want to get into this. If we did, examples can be found @ http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html,
gmerlin stuff is GPL, so it's not an option
maybe there is something to research in libSox? http://sox.cvs.sourceforge.net/viewvc/sox/sox/
wrapping Apple's AudioQueue API would be an easy and full-featured on solution on the Mac, but of course is not available on other platforms.
One proposal is to wrap Apple's stuff on the Mac and libsndfile on other platforms. libsndfile supports CAF format, so that could be our 'native' format on both platforms if we wish. Then "only" MP3, AAC, etc. become problems on Windows (but they would be problematic due to licensing anyway).

We also should be thinking in terms both of:

  • importing (e.g. TTBuffer, which already exists, needs to import and export files)
  • streaming (for which we don't currently have a class)

Compiling Ogg

An introduction to Ogg can be found at http://en.wikipedia.org/wiki/Ogg and the official site is http://www.xiph.org/ . For compiling a Universal Binary, I found some information (which didn't work but it got me on the right track) at http://www.expert-sleepers.co.uk/ninjamplugin.html . Here's what I did:

  1. download the latest version (1.2.0)
  2. de-compress and cd into the directory
  3. run the following:
    env CFLAGS="-O -g -arch i386 -arch x86_64" LDFLAGS="-isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5" ./configure --disable-dependency-tracking --enable-static --with-ogg=/usr/local

    make

    sudo make install

    lipo -info /usr/local/lib/libogg.a

That last command is just to verify that I did indeed build a universal binary. It returns the following for me:

Architectures in the fat file: /usr/local/lib/libogg.a are: i386 x86_64

Compiling Vorbis

  1. download the latest version (1.3.1) http://en.wikipedia.org/wiki/Vorbis
  2. de-compress and cd into the directory
  3. run the following:
    env CFLAGS="-O -g -arch i386 -arch x86_64" LDFLAGS="-isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 -arch i386 -arch x86_64" ./configure --disable-dependency-tracking --enable-static --disable-shared --with-ogg=/usr/local

    make

    sudo make install

    lipo -info /usr/local/lib/libvorbis.a

Great -- but this is open source software we are talking about so, things are not right yet. More to do:

sudo rm /usr/local/lib/libogg*dylib
env CFLAGS="-O -g -arch i386 -arch x86_64" LDFLAGS="-isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 -arch i386 -arch x86_64" ./configure --disable-dependency-tracking --enable-static --disable-shared --with-ogg=/usr/local

(yes, we have to run that again)
make clean; make

sudo make install

lipo -info /usr/local/lib/libvorbis.a

Compiling FLAC

  1. download the latest version (1.2.1)
  2. de-compress and cd into the directory
  3. run the following:
    env CFLAGS="-O -g -arch i386 -arch x86_64" LDFLAGS="-isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5" ./configure --disable-dependency-tracking --enable-static --disable-shared --with-ogg=/usr/local

That complains about not having XMMS. Not sure if this is important or not? Ignoring it for now...

make
  • Fails when linking : despite us telling it to use static linking, it is looking for /usr/local/lib/libogg.dylib. I can't find where this is specified in any makefile or other file. So for now we can build with the "--disable-ogg" flag. Not sure if that is bad to do in the long term though?
  • Further problems exist because we can't build libFLAC as a universal binary! We have to build one architecture at a time and manually lipo them together.
  • And then it still doesn't build a 32-bit binary (on a 64-bit machine), giving more internal linker errors!
  • So trying to just run ./configure --enable-static --disable-shared --disable-ogg and then making yields ranlib errors -- but I thought ranlib was obsolete and never needed on the mac anymore? And furthermore, it looks like it produced a 32/64 bit UB!!! Sheesh.

Trying again, now with ogg, it works, except for the bogus(?) ranlib problems. Because of that, we can't do a 'make install'. So...

./configure --enable-static --disable-shared

make

lipo -info src/libFLAC/.libs/libFLAC.a

sudo cp src/libFLAC/.libs/libFLAC.a /usr/local/lib

sudo mkdir /usr/local/include/FLAC

sudo cp include/FLAC/*.h /usr/local/include/FLAC

So -- it turns out that didn't work either. Here is the new attempt:

Build the 64 bit version:

env CFLAGS="-arch x86_64" CPPFLAGS="-arch x86_64" LDFLAGS="-arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5" ./configure --disable-asm-optimizations --enable-static --disable-shared --disable-ogg

make clean; make

cp src/libFLAC/.libs/libFLAC.a ./libFLAC64.a

Build the 32 bit version:

env CFLAGS="-arch i386" CPPFLAGS="-arch i386" LDFLAGS="-arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5" ./configure --disable-asm-optimizations --enable-static --disable-shared --disable-ogg

make clean; make

cp src/libFLAC/.libs/libFLAC.a ./libFLAC32.a

Combine them into a Universal Binary:

lipo libFLAC32.a libFLAC64.a -create -output libFLAC.a

This at least gives the initial appearance that it worked... except, that we really need to add this kind of thing:

-isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5

to the environment variables. Details can be found at http://cocoawithlove.com/2009/09/building-for-earlier-os-versions-in.html . Basically we will get linker errors for fopen().

Compiling libsndfile

libsndfile turns out to be complete disaster thanks to the hard-core FLOSS religion. In fact, there is even code in it to make certain that you can't compile it as a universal binary -- verrrrry impressive! So we have an Xcode project in the SoundfileLib folder and can compile from there.

take a look here: Is it possible to build a Universal Binary on Mac OS X?