views:

292

answers:

1

Some MP3 files can't be opened by CoreAudio in OS X and iPhone OS 3.x. This was a bug that I submitted to Apple and has been fixed in 10.6.2. Unfortunately, I must still support iPhone OS 3.x, so I need to test for these files that mess up CoreAudio. I check them with a simple command line tool that tries AudioFileOpenURL and returns > 0 if there's a problem opening it. If there is I use Apple's iTunes encoder to encode the MP3 instead of lame.

I cannot upgrade to 10.6.2 at the moment as my MP3 file checker will now pass files that will not open on iPhone OS 3.x.

Is there any way of building the checking tool against an older version of AudioToolbox/CoreAudio, or some other checking solution?

+2  A: 

If I understand you correctly, you want to link code from obsolete system frameworks.

Statically linking would mean you have to take the dylib apart and create a static library from it, which would be difficult to say the least.

But you can just copy the affected system frameworks from the older (buggy) system to your application wrapper or some other place close to your executable. Then you link your executable against these frameworks.

You can use the terminal to see what libraries you are linking:

$ cd foo-project/build/Debug
$ otool -L foo
foo:
    /System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 123.0.0)

It's very easy to change the load command in the mach-o executable to use another path for a linked framework:

$ install_name_tool -change /System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio @executable_path/CoreAudio.framework/Versions/A/CoreAudio foo
$ otool -L foo
foo:
    @executable_path/CoreAudio.framework/Versions/A/CoreAudio (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 123.0.0)

$ DYLD_PRINT_LIBRARIES=1 ./foo
dyld: loaded: /Users/nikolai/foo-project/build/Debug/./foo
dyld: loaded: /Users/nikolai/foo-project/build/Debug/./CoreAudio.framework/Versions/A/CoreAudio
...

You can prepare the (copied) framework so that when you build the foo executable, it has the right load commands automatically:

$ install_name_tool -id @executable_path/CoreAudio.framework/Versions/A/CoreAudio CoreAudio.framework/Versions/Current/CoreAudio
Nikolai Ruhe
Thanks, this works brilliantly.
coob