NSSound

I’m wrapping up development on a little app this evening but something is sticking out as unfinished. There is PopupMenu to allow the user to choose a System Sound that plays when an NSUserNotification fires. This works great, thanks to macoslib. But I’d like the user to hear a preview of the sound, when they select it in the prefs window, much like System Preferences does.

In Xcode/Cocoa, I would do something like this:

NSSound *notificationSound = [NSSound soundNamed:@"Frog"]; // NSSound doesn't require a path, just the name [notificationSound play];

There’s nothing in macoslib for NSSound - has anyone got a little Declare for NSSound?

I recorded my steps as I put this together :slight_smile:

search google: nssound
this is the doc…
https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/Classes/NSSound_Class/Reference/Reference.html

Framework is “AppKit.framework” but “Cocoa.framework” works too. (maybe not always?)

translate code
NSSound *notificationSound = [NSSound soundNamed:@“Frog”];
[notificationSound play];

there’s two methods
soundNamed is Shared (because of the + prefix).

  • (id)soundNamed:(NSString *)soundName

play is instance (because - prefix)

  • (BOOL)play

for Shared methods you need to first get the Class pointer
looked this up from reference project
getting Class pointer…
const CocoaLib = “Cocoa.framework”
soft declare function NSClassFromString lib CocoaLib (aClassName as CFStringRef) as Ptr
dim NSSoundClassPtr As Ptr = NSClassFromString(“NSSound”)

now you can call soundNamed. NSString -> CFStringRef. Add “:” if any parameters.

soft declare function soundNamed lib CocoaLib selector “soundNamed:” (ClsPtr As Ptr, soundName As CFStringRef) as Ptr
dim notificationSound As Ptr = soundNamed(NSSoundClassPtr, “Frog”)

and play is…
soft declare function play lib CocoaLib selector “play” (instPtr As Ptr) as Boolean
call play(notificationSound)

all together

[code]const CocoaLib = “Cocoa.framework”
soft declare function NSClassFromString lib CocoaLib (aClassName as CFStringRef) as Ptr
soft declare function soundNamed lib CocoaLib selector “soundNamed:” (ClsPtr As Ptr, name As CFStringRef) as Ptr
soft declare function play lib CocoaLib selector “play” (instPtr As Ptr) as Boolean

dim NSSoundClassPtr As Ptr = NSClassFromString(“NSSound”)
dim notificationSound As Ptr = soundNamed(NSSoundClassPtr, “Frog”)
call play(notificationSound)[/code]

some tidbits

doc for NSClassFromString Foundation_Functions

Library functions don’t use a selector
Class functions require that first pointer. The Class pointer for Shared methods, an instance pointer for regular methods.

You may also need to retain and release pointers. And what I’ve said may not be entirely accurate :slight_smile: still learning the caveats.

Stuart, thank you sir, much appreciate the effort. I’m going to try this later on today. I’ll also use it to finally learn how to create Declares properly. I’ve actually many years of Xcode/Cocoa development behind me, but the couple of times I’ve tried creating Declares have tied my brain in knots. Thanks again.