4

On the iPhone I need to get the path for the resource. OK, done that, but when it comes to CFURLCreateFromFileSystemRepresentation thing, I just don't know how to solve this. Why does this error occur? Any solution or workaround would be highly appreciated. Thank you in advance.

I have taken a look at the following examples in order to play audio using AudioQueue on the iPhone: SpeakHere, AudioQueueTools (from the SimpleSDK directory) and AudioQueueTest. I tried do this and that, trying to put the puzzles together. Right now, I am stuck at this. The program crashed because of the exception thrown from the sndFile above.

I am using AVAudioPlayer to play every sound on my iPhone games. On the real iPhone device, it turned out to be very laggy when a sound is to be played, so I decided I need to use AudioQueue.

- (id) initWithFile: (NSString*) argv{

    if (self = [super init]){
        NSString *soundFilePath = [[NSBundle mainBundle]
                                    pathForResource:argv
                                             ofType:@"mp3"];
        int len = [soundFilePath length];
        char* fpath = new char[len];

        //this is for changing NSString into char* to match
        //CFURLCreateFromFileSystemRepresentation function's requirement.
        for (int i = 0; i < [soundFilePath length]; i++){
            fpath[i] = [soundFilePath characterAtIndex:i];
        }

        CFURLRef sndFile = CFURLCreateFromFileSystemRepresentation
                           (NULL, (const UInt8 *)fpath, strlen(fpath), false);
        if (!sndFile) {
            NSLog(@"sndFile error");
            XThrowIfError (!sndFile, "can't parse file path");
        }
}
e.James
  • 116,942
  • 41
  • 177
  • 214
Karl
  • 5,613
  • 13
  • 73
  • 107
  • What are you trying to accomplish. I don't like questions that ask how to use a framework method as opposed to how can I solve this actual problem. Also, what's with the redundant ellipsis? – Brock Woolf Jul 24 '09 at 09:54
  • OK, sorry for that. I was a bit tired. Anyway, I have been trying to follow all the examples for AudioQueue and also have read the Apple document for this. Given that I am not very experienced, I do not know how to deal with CFURLRef properly. All I understand from all of the examples and documents is that I need to use the CFURLCreateFromFileSystemRepresentation to get a CFURLRef so that I can use this CFURLRef as an argument in AudioFileOpenURL method. But I got an error saying : "terminate called after throwing an instance of 'CAXException'". I do not know how to deal with this error. – Karl Jul 24 '09 at 13:12

2 Answers2

11

Why do you need a CFURL?

If you have a method elsewhere that requires a CFURL, you can simply use an NSURL thanks to toll-free bridging. So to create the NSURL, you'd just do:

  NSString * soundFilePath = [[NSBundle mainBundle]
                                 pathForResource:argv
                                          ofType:@"mp3"];

  NSURL *soundURL = [NSURL fileURLWithPath:soundFilePath];

In general, if you find yourself using CF objects you are probably doing something wrong.

Kendall Helmstetter Gelner
  • 74,769
  • 26
  • 128
  • 150
  • What does CF stand for? I feel silly for asking, but there's too many possibilities. – Sneakyness Jul 26 '09 at 06:09
  • Core Foundation, the NS calls are based on top of these lower level calls - usually there's a cleaner, easier way to use an NS method than a CF method. – Kendall Helmstetter Gelner Jul 26 '09 at 08:37
  • Not quite true "In general, if you find yourself using CF objects you are probably doing something wrong." Core Foundation classes can be helpful if: 1)You are trying to read exif/metadata in image 2)If you need for example size of image and you don't want to load big image(map tile) like 2048x2048 into memory. 3)And so on.... – Roman Safin Mar 03 '15 at 14:49
  • 1) You use CG, not CF calls to read image metadata. CoreGraphics calls are a different matter as often there are not really better higher level methods. 2) Are you sure UIImage loads image data into memory before it is accessed? It could be that you can create a UIImage from a file, then check for the size properties without triggering the loading of image data from storage. – Kendall Helmstetter Gelner Mar 05 '15 at 22:25
0

I'm not sure if this will get rid of your exception, but there is a simpler way to convert an NSString to an array of char. Here is how I would write this method:

- (id) initWithFile:(NSString*) argv
{
    if ((self = [super init]) == nil) { return nil; }

    NSString * soundFilePath = [[NSBundle mainBundle]
                                 pathForResource:argv
                                          ofType:@"mp3"];
    CFURLRef sndFile = CFURLCreateFromFileSystemRepresentation
                       (NULL, [soundFilePath UTF8String],
                        [soundFilePath length], NO);

    if (!sndFile) { NSLog(@"sndFile error"); }
    XThrowIfError (!sndFile, "can't parse file path");

    ...
}

Or, since CFURL is "toll-free bridged" with NSURL, you can simply do:

- (id) initWithFile:(NSString*) argv
{
    if ((self = [super init]) == nil) { return nil; }

    NSString * soundFilePath = [[NSBundle mainBundle]
                                 pathForResource:argv
                                          ofType:@"mp3"];
    NSURL * sndFile = [NSURL URLWithString:[soundFilePath
                       stringByAddingPercentEscapesUsingEncoding:
                         NSUTF8StringEncoding]];
    if (!sndFile) { NSLog(@"sndFile error"); }
    XThrowIfError (!sndFile, "can't parse file path");

    ...
}
e.James
  • 116,942
  • 41
  • 177
  • 214