NSSound setVolume not working

Hi,

Here’s the library script:

use AppleScript version "2.3"
use scripting additions
use framework "Foundation"
use framework "AppKit"

on playSound:theSound
	set aSound to current application's NSSound's soundNamed:theSound
	aSound's setVolume:(1.0)
	aSound's play()
	return ((aSound's |name|()) as text)
end playSound:

And here’s the calling script:

use theLib : script "SoundTest"
use scripting additions

theLib's playSound:"Voltage"

Does anyone know if this is a known issue or something else?

Thanks,
kel

Hi,

don’t mix up Objective-C syntax (colon as parameter separator) with AppleScriptObjC (underscore)

not tested


use AppleScript version "2.3"
use scripting additions
use framework "Foundation"
use framework "AppKit"

on playSound_(theSound)
	set aSound to current application's NSSound's soundNamed_(theSound)
	aSound's setVolume_(1.0)
	aSound's play()
	return ((aSound's |name|()) as text)
end playSound_

Foundation framework is not required, I guess

Hi Stefan,

That worked the same as the posted script. The sound volume still didn’t change from that of the system’s. I’m wonder if I need to somehow initialize the sound for the volume to work.

Thanks,
kel

the system sound is the master control.
If the volume of custom sound is set to 1.0 “ which is the maximum value “ the sound is played with system sound volume level

Hi Stefan,

I tried setting the system volume to maximum. In the library script I set it to 0.5 and the sound’s volume was still maximum. I’ll try that again.

Edited: tried it again and the volume still didn’t change to half the volume. Maybe a bug?

Later,
kel

The ‘say’ command’s volume works:

say "hello" volume 1.0
say "hello" volume 0.75
say "hello" volume 0.5
say "hello" volume 0.25

Edited: I wonder if in order to use the set volume, you need to use alert volume as output with ‘setPlaybackDeviceIdentifier:’ or something and what is the identifier.

If anybody tried running this library item can you tell me if the volume changes or not for you.

Thanks,
kel

But the colon is now the “correct” way for AppleScriptObjC too. Indeed, it’s part of AppleScript generally as of Mavericks.

Hello.

That’s even one more thing they have set straight in this editon! Thank you Apple!

Aside from that, when creating libraries that clearly resembles AppKit, whouldn’t it then be smart to prefix the library name with AppKit for instance: “AppKit_PlaySound”?

My point is, is that one of the biggest deficiencies that at least I have experienced in the past, is the size of compilation units (script libraries); that you tend to include a lot more in the end than you really need. Follow some kind of dot notation scheme, where the dot isn’t necessarily a dot, could make for a more efficient use of libraries, still making that compilation unit easily identifiable within the api through its name.
Of course you need some kind of taxomony.

I suspect with ASObjC-based libraries, you’d be better to keep them smaller.

I’m not sure what you mean about AppKit. Most scripts will probably only need Foundation, and throwing in AppKit shouldn’t make a lot of difference. If I were loading any other frameworks, I’d be inclined to do so in a different library.

Hello.

I think you meant not the length of the library name here, but the size of the compilation unit.

Only bytes knows how much the size of an AppleScript Library adds up to the calling scripts internal table. But I guess it is wise to keep them as small as possible anyway. It makes for easier revision, if not anything else.

In AppleScript-editor and ASObjC Explorer for Mavericks it even auto corrects old syntax :slight_smile:

The downside, though, is that it makes terminology clashes more likely, so you have to use pipes more often. Think about how many methods contain the word error, for example. The underscores had the side-effect of reducing the likelihood of clashes.

Hi everybody,

It has been working. 0.5 of the system volume is too big to notice a change on my machine. Here’s what I’ve got so far:

use AppleScript version "2.3"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property theSender : missing value
property aSound : missing value

on playSound:theRef sender:sender
	set my theSender to sender
	set aSound to current application's NSSound's alloc's initWithContentsOfFile:(theRef) byReference:(false)
	aSound's setDelegate:me
	aSound's play()
	aSound's setVolume:(0.2)
	delay 20
	aSound's |stop|()
	return (aSound's isPlaying)
end playSound:sender:

on |sound|:theSound didFinishPlaying:didPlay
	if didPlay then
		set b to "True"
	else
		set b to "False"
	end if
	display dialog b
end |sound|:didFinishPlaying:

Not sure if I need to deallocate the sound.

Edited: btw you need to send it a file reference. I used:

use theLib : script "SoundTest3"
use scripting additions

theLib's playSound:("/Users/kelhome/Music/iTunes/iTunes Media/Music/Gordon Lightfoot/Complete Greatest Hits/10 Beautiful.m4a") sender:me

Thanks for the examples,
kel