4

I'm currently using OpenAL to play game music. It works fine, except that it doesn't work with anything except for raw WAV files. This means that I end up with a ~9mb soundtrack.

I'm new to OpenAL, and I'm using code directly from Apple's example (https://developer.apple.com/library/ios/#samplecode/MusicCube/Listings/Classes_MyOpenALSupport_h.html%23//apple_ref/doc/uid/DTS40008978-Classes_MyOpenALSupport_h-DontLinkElementID_9) to get the buffer data.

Question: Is there any way to modify this function so it reads compressed audio and decodes it on the fly?
I'm not so worried about the audio file format, just as long as it can be played and is compressed (like mp3, aac, caf). The only reason I want to do this (obviously) is to reduce file size.

Edit: It seems that the problem is not so much in OpenAL as the method I'm using to get the buffer. The function at https://developer.apple.com/library/ios/#samplecode/MusicCube/Listings/Classes_MyOpenALSupport_h.html%23//apple_ref/doc/uid/DTS40008978-Classes_MyOpenALSupport_h-DontLinkElementID_9 uses AudioFileOpenURL and AudioFileReadBytes. Is there any way to get the framework to decode the audio for me using ExtAudioFileOpenURL and ExtAudioFileRead?

I have tried the code here: https://devforums.apple.com/message/10678#10678, but I don't know what to make of it. The function I use to get the buffer is at https://developer.apple.com/library/ios/#samplecode/MusicCube/Listings/Classes_MyOpenALSupport_h.html%23//apple_ref/doc/uid/DTS40008978-Classes_MyOpenALSupport_h-DontLinkElementID_9, and I haven't really modified it, so that's what I need to build on.

I've started a bounty because I really need this, hopefully someone can point me in the right direction.

Greg
  • 9,068
  • 6
  • 49
  • 91
  • Do you really have to use pure OpenAL to play your sounds? Why don't you use something that works out of the box like CocosDenshion, it would save you tons of worries. http://www.cocos2d-iphone.org/wiki/doku.php/cocosdenshion:faq – Marko Hlebar Jul 23 '11 at 09:50

5 Answers5

4

You'll need to use audio services to load other formats. Bear in mind that OpenAL ONLY supports uncompressed PCM data, so any data you load needs to be uncompressed during load.

Here's some code that will load any format supported by iOS: https://github.com/kstenerud/ObjectAL-for-iPhone/blob/master/ObjectAL/ObjectAL/Support/OALAudioFile.m

If you want to stream compressed soundtrack-type audio, use AVAudioPlayer since it plays compressed audio straight from disk.

Karl
  • 14,434
  • 9
  • 44
  • 61
  • It's my own code. Just leave a link back to the original in a comment in your source and that's enough. – Karl Nov 08 '11 at 23:46
  • And if this source ends up compiled in one of my iPhone Apps on the App Store? – Greg Nov 13 '11 at 05:53
  • It's in the license at the top of the file: "Note: You are NOT required to make the license available from within your iOS application. Including it in your project is sufficient." – Karl Nov 14 '11 at 20:03
  • Finally get round to checking it out. Does exactly what I needed. Thanks! – Greg Dec 16 '11 at 10:06
  • One more question: is there any way I can queue 2 files for background audio, so one starts playing right after the other finishes? – Greg Dec 16 '11 at 10:10
  • Finally figured it out. I ended up using 2 instances of `OALAudioTrack` and calling `playAfterTrack:`. Works perfectly for me, without any latency. I also noticed that `playAfterTrack:` doesn't seem to be documented in the `ObjectAL` documentation... – Greg Dec 16 '11 at 11:34
  • Hey, guys. I want to use compressed audio using OpenAL and this look like you have an answer. But Karl's link does't work (just goes to a github 404 page) anymore so I can't get to the code that seamed to work for @NightLeopard. Any help? – Baza207 May 05 '12 at 13:04
  • Yeah I found it in the end but the file referenced isn't there anymore. Thanks anyway. – Baza207 May 06 '12 at 12:00
3

You don't need any third party library to open archived files. With a little help from AudioToolbox/AudioToolbox.h framework you can open and read the data of a .caf file which is a very good choice by the way (better than mp3 or ogg) in terms of performance (minimal CPU impact during decompression). So ,when the data gets to OpenAL it is already PCM, ready to fill the buffers. Here is some sample code on how you can achieve this:

-(void) prepareFiles:(NSString *) filePath{

    // get the full path of the file
    NSString* fileName = [[NSBundle mainBundle] pathForResource:filePath ofType:@"caf"];    

    // open the file using the custom created methods (see below)
    AudioFileID fileID = [self openAudioFile:fileName];     
    preparedAudioFileSize = [self audioFileSize:fileID];

    if (preparedAudioFile){
        free(preparedAudioFile);
        preparedAudioFile = nil;
    }
    else{
        ;
    }
    preparedAudioFile = malloc(preparedAudioFileSize);

    //read the data from the file into soundOutData var
    AudioFileReadBytes(fileID, false, 0, &preparedAudioFileSize, preparedAudioFile);
    //close the file    
    AudioFileClose(fileID);
}



-(AudioFileID)openAudioFile:(NSString*)filePath
{
    AudioFileID fileID;
    NSURL * url = [NSURL fileURLWithPath:filePath];
    OSStatus result = AudioFileOpenURL((CFURLRef)url, kAudioFileReadPermission, 0, &fileID);

    if (result != noErr) {
        NSLog(@"fail to open: %@",filePath);
    }
    else {
        ;
    }
    return fileID;
}


-(UInt32)audioFileSize:(AudioFileID)fileDescriptor
{
    UInt64 outDataSize = 0;
    UInt32 thePropSize = sizeof(UInt64);
    OSStatus result = AudioFileGetProperty(fileDescriptor, kAudioFilePropertyAudioDataByteCount, &thePropSize, &outDataSize);
    if(result != 0) NSLog(@"cannot find file size");
    return (UInt32)outDataSize;
}
Rad'Val
  • 8,895
  • 9
  • 62
  • 92
1

based on Karl's reply above, I made a minimal single c++ function which opens a file and gives you back a buffer of pcm audio ( suitable for OpenAL ) and all the info you need to create an OpenAL sound ( format, samplerate, buffersize etc ).

the two files you need are here: https://gist.github.com/ofTheo/5171369

hope it helps! theo

0

Try if this works: http://kcat.strangesoft.net/openal-tutorial.html

Vijayendra
  • 1,931
  • 3
  • 20
  • 23
0

You might try to use a third party library to load a mp3-ogg into a char* buffer, and then give this buffer to openAL. That would solve the file size problem.

For ogg, you should find the libraries on their website

For mp3, I honestly don't know where to find a lightweight library which could do that. But that should exist.

Clement Bellot
  • 841
  • 1
  • 7
  • 19