Mailing Lists: Apple Mailing Lists
Image of Mac OS face in stamp
Playing a sound from a command-line app
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Playing a sound from a command-line app



I have the requirement to play a single predefined sound (AIFF) from a command-line application. I'd prefer to use Cocoa, but will use the Carbon APIs if necessary.

I'm having problems in delaying quitting the application until the sound has finished playing.

I'm using Mac OS X 10.2.5.

If I use the following, the sound doesn't play. I'm guessing it's because the sound playing is asynchronous, and the app finishes before the sound plays.

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(@"Starting sound");
NSSound *sound =[[NSSound alloc] initWithContentsOfFile: @"/System/Library/Sounds/Glass.aiff" byReference: true];
[sound play];
NSLog(@"finished in main");
[pool release];
return 0;
}

This prints:
Started sound
finished in main

But, there's no sound.


I tried adding a condition lock (as suggested by Chris Kane in Mac OS X dev list
(http://www.omnigroup.com/mailman/archive/macosx-dev/2001-April/ 014145.html)


NSConditionLock *gSoundLock = nil; // global variable

@interface X: NSObject
- (void) sound: (NSSound *) s didFinishPlaying: (BOOL) didFinish;
@end
@implementation X
- (void) sound: (NSSound *) s didFinishPlaying: (BOOL) didFinish
{
NSLog(@"sound finished playing");
[gSoundLock unlockWithCondition:42];
}
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
gSoundLock = [[NSConditionLock alloc] initWithCondition:17];
NSLog(@"Starting sound");
NSSound *sound =[[NSSound alloc] initWithContentsOfFile: @"/System/Library/Sounds/Glass.aiff" byReference: true];
[sound setDelegate: [[X alloc] init]];
[gSoundLock lockWhenCondition:17];
[sound play];
[gSoundLock lockWhenCondition:42];
NSLog(@"finished in main");
[pool release];
return 0;
}

The sound plays, but the program prints:
Starting sound

And then, the app never finishes.
Apparently, the delegate's callback isn't being called.

Another approach I've tried is running a run loop, and stopping the run loop from the delegate's callback:
@interface X: NSObject
- (void) sound: (NSSound *) s didFinishPlaying: (BOOL) didFinish;
@end
@implementation X
- (void) sound: (NSSound *) s didFinishPlaying: (BOOL) didFinish
{
NSLog(@"sound finished playing");
CFRunLoopStop(CFRunLoopGetCurrent()); // NSRunLoop doesn't have a stop method
}
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(@"Starting sound");
NSSound *sound =[[NSSound alloc] initWithContentsOfFile: @"/System/Library/Sounds/Glass.aiff" byReference: true];
[sound setDelegate: [[X alloc] init]];
[sound play];
[[NSRunLoop currentRunLoop] run];
NSLog(@"finished in main");
[pool release];
return 0;
}
The sound plays, and the program prints:
Starting sound
sound finished playing

The app never finishes. Apparently, the run loop is never stopping.

Any suggestions for the right way to approach this?


Thanks,

Neil

--
Neil Rhodes
Palm OS Certified Developer
Co-author: Palm Programming: the Developer's Guide
Available for contract programming
email@hidden _______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.


Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2011 Apple Inc. All rights reserved.