How to use If volume is muted?

Hi there,
I'm doing a marco which has a if then. How to set this if Volume is not muted then ....?
I only find "mounted volume condition" and doesn't know how to use it.....

With the If Then Else a Script Condition checking if the sound output is muted should work.
image

3 Likes

I think this will also work:

2 Likes

Hello @Airy

In maybe some circumstances your suggestion could be helpful … but be aware of that a Sound output level of 0 is not equal to muted. Basically the OP could use it to fine tune the macro doing different stuff on different levels of the output if it is not muted.

But since he needs definitely the muted state there is nothing better than @NaOH‘s Suggestion.

Greetings from Germany

Tobias

Whenever the mute flag is on, the system volume must return zero.

If A = "Mute flag is on."
If B = "System Volume is zero."

In macOS, A -> B (A implies B, Mute flag ON implies system volume is zero.)

Testing for A will always give you the same result as testing for B since A -> B.

Can you think of any occasion where the mute flag could be on but system volume is not zero? I can't think of any. Let me know if you can come up with a situation where A does not imply B.

Just to provide a little extra information... It's understandable this wasn't helpful for checking if the system volume is muted. In this case, the word volume essentially means a disk (internal hard drive, memory stick, etc.), so a mounted volume would be a disk that is connected to the computer and its contents available to the user.

1 Like

First, I think you meant:
If A = "Mute flag is on."
Then B = "System Volume is zero."

Second, as a matter of formal logic, A—>B does not mean B—>A. The question posed by the OP was “is the mute switch on”, so the factual question is whether the following is true:

“If B = "System Volume is zero.
Then A = “Mute switch is on”

I don’t know for a fact whether setting the system volume to zero turns the mute switch on, but that is the proper syllogism to address the OP’s question.

I never once said B->A so don't try to claim that I did. All I said was A->B. So I said you can test for B and always get the exact same result as if you had tested for A, because A->B.

I asked for an example of where the mute flag could be on and yet the system volume could not be zero. That's what you have to answer in order to prove me wrong. I notice that you didn't answer that. Would you like to give it another try? I'm eager to hear of a counter-example. Please provide an example.

You are the one that needs to read more carefully. The question asked was “is the mute flag on”. You said “Testing for A (mute flag is on) ..gives the same result as Testing for B (testing if sound is 0).” I asked whether that was true. I don’t disagree with you at all (and did not disagree in my post) that if mute is on, sound will always be zero, so of course I don’t have a counterexample. That statemtent is true.
And then I asked a question : If the sound is zero, does that always mean the mute flag is on. If not, then your statement that testing for A gives the same result as testing for B is incorrect. I asked the question because I don’t know the answer to it (and am traveling with only my iPad now, so can’t check it on my Mac).

Hello @Airy

I am saying now the same that @rolian said … I didn’t mean that the muted Volume setting is not 0…

And I am also saying that you should read again what I wrote then you will know that i wasn’t speaking of that.

If you want to have a macro that runs in both cases (volume is 0 and also muted) - and you have different routines for the macro you will have to test for the muted flag.

But since you hesitate to understand that it’s the essential thing that was asked here I will tell you again … setting the Volume to zero result in a real or integer Value and a Boolean flag of false for the is muted test on the sound state … and that is not equal to a muted Volume setting - which results in a real or integer with a Boolean flag of true in common for the is muted test on the sound state.

You can of corse test for sound output of zero but it will not tell you if your Mac is muted or not … that was it what I was speaking about and am doing now again.

I’ve maybe less knowledge about programming than you but I am not an idiot …

Greetings from Germany

Tobias

As a footnote, one advantage of reading volume settings in the JavaScript rather than AppleScript flavour of osascript is that we can ask for inspectable JSON:

{
  "outputVolume": 38,
  "inputVolume": 49,
  "alertVolume": 62,
  "outputMuted": true
}

Here are a couple of subroutines (with examples of use)

  • VOLUMES AND MUTED STATES AS JSON
  • AUDIO MUTED STATE TOGGLED

SUBROUTINES Macros.kmmacros (15 KB)

e.g.


Expand disclosure triangle to view JS source for JSON reporting
return JSON.stringify(
    Object.assign(
        Application.currentApplication(),
        {includeStandardAdditions: true}
    )
    .getVolumeSettings(),
    null, 2
);

Expand disclosure triangle to view JS source for Muted State Toggling
const
    sa = Object.assign(
        Application.currentApplication(),
        {includeStandardAdditions: true}
    );

return (
    sa.setVolume(
        null, {
            outputMuted: !sa.getVolumeSettings().outputMuted
        }
    ),
    JSON.stringify(sa.getVolumeSettings(), null, 2)
);
1 Like

You can, unsurprisingly, get the same data with AS:

...although your JSON is probably easier to parse if you know how to parse JSON :wink: (Yes, I'm still sadly lacking in that department...)

As to the rest of the comments in the thread...

Regardless of "logic" or "correctness", %SystemVolume% = 0 is a good proxy for "will sound come out of my computer" -- probably the most frequent use -- and, being KM-native, it should be a tad faster. But note that %SystemVolume% is not the same output volume as returned by AS's get volume settings.

Off the top of my head, the main time you'll get bitten by the difference is when you are using KM's "Increase System Sound Volume" action and its variants. A muted output device still has a volume setting -- the "Increase" action will both unmute the output device and set its volume to previousVolume + 6.5%, while an unmuted-but-0 device will have a new volume setting of 6.5%

1 Like

No need :slight_smile:

( Keyboard Maestro's excellent %JSONValue% token does that for you )


I think the key point about the muted state is that you can toggle it without overwriting the volume settings.

Yes -- but I'm so "sadly lacking" that I don't even know how to use that! :wink:

Yes, but OP was asking about testing for it -- whether %SystemVolume% is a good enough proxy or if they'll have to dig deeper and get the actual mute state really depends on why they are testing.

The difficulty with AppleScript records (at the interface with Keyboard Maestro), is that the promising-looking record-stringification which you show is provided not by AppleScript itself, but by the Script Editor application.

In Keyboard Maestro, or from a shell line like osascript -e "get volume settings"

we do get the perfectly informative

output volume:38, input volume:49, alert volume:62, output muted:true

but this not parseable as JSON, AppleScript source code, or any other format that Keyboard Maestro provides direct support for.

Accessible, of course, to string-munging by splitting, regular expressions, etc etc, but that requires more knowledge, and takes more work.

If development of AppleScript had continued, then making its records as easy to work with as those of Python, JavaScript, (more or less any other scripting language come to that) i.e. (introspectable - what keys have you got ?, and convertible - what would you look like as a list of {key, value} lists ?) would, I think, have been a first priority.


PS at the command line, we can do better, of course with:

osascript -e "get volume settings" -s "s"

and that at least is recompilable, but its parts are still not readily accessible, without further string-munging, to Keyboard Maestro.


And even AppleScript records are not always entirely beyond the reach of introspection, but this particular case doesn't yield its secrets (lists of keys, values) easily ...

Expand disclosure triangle to view AppleScript source
use framework "Foundation"
use scripting additions

-- assocs :: Map k a -> [(k, a)]
on assocs(m)
	script go
		on |λ|(k)
			set mb to lookupDict(k, m)
			if missing value is mb then
				{}
			else
				{{k, mb}}
			end if
		end |λ|
	end script
	concatMap(go, keys(m))
end assocs

-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
	set lng to length of xs
	set acc to {}
	
	tell mReturn(f)
		repeat with i from 1 to lng
			set acc to acc & (|λ|(item i of xs, i, xs))
		end repeat
	end tell
	acc
end concatMap

-- keys :: Dict -> [String]
on keys(rec)
	(current application's NSDictionary's dictionaryWithDictionary:rec)'s allKeys() as list
end keys


-- lookupDict :: a -> Dict -> Maybe b
on lookupDict(k, dct)
	-- Just the value of k in the dictionary,
	-- or Nothing if k is not found.
	set ca to current application
	set v to (ca's NSDictionary's dictionaryWithDictionary:dct)'s objectForKey:k
	if missing value ≠ v then
		item 1 of ((ca's NSArray's arrayWithObject:v) as list)
	else
		v
	end if
end lookupDict

-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
	-- 2nd class handler function lifted into 1st class script wrapper. 
	if script is class of f then
		f
	else
		script
			property |λ| : f
		end script
	end if
end mReturn

on run
	set someRecord to {alpha:1, beta:3, gamma:3}
	-- e.g. this works
	
	keys(someRecord) -->  {"alpha", "beta", "gamma"}
	assocs(someRecord) --> {{"alpha", 1}, {"beta", 3}, {"gamma", 3}}
	
	-- but not directly applicable here:
	-- keys((get volume settings))
	-- assocs((get volume settings))
end run

Whereas in JavaScript we can immediately ask for Object.keys(), Object.values(), Object.entries() etc

So from:

Record introspection.kmmacros (2.0 KB)

we get (each component directly accessible to Keyboard Maestro's %JSONValue% token):

Expand disclosure triangle to view JS source
const
    settings = Object.assign(
        Application.currentApplication(),
        {includeStandardAdditions: true}
    )
    .getVolumeSettings();

return JSON.stringify(
    {
        keys: Object.keys(settings),
        values: Object.values(settings),
        entries: Object.entries(settings)
    },
    null, 2
);

100% agree with all you write. And while Late Night Software's List & Record Tools OSAX, in combination with their LNSOSAX app, still works in Sonoma (at least on Intel machines):

...those are ridiculous hoops to expect people to jump through.

Except that, for me, that's less work than learning enough JavaScript to get to the same end result :wink:

I'll say it again -- this is my failing. When I get the "You do computers -- what's a good first programming language to learn?" question my answer is always "JavaScript, no ifs or buts about it" -- I really should knuckle down and do what I tell others to do!

1 Like

Of course not. But now you're talking about B->A. I never addressed B->A. I can't come up with a single reason why a person would need to know that, and that's why I have always avoided this question. Can you come up with a reason? Even the original poster never provided a reason why that's important. The original poster might be completely satisfied with testing for A, since A->B.

I stand by this statement: "Testing for A will always give you the same result as testing for B since A -> B."

People who ask questions are not always asking the right question. Sometimes we have to ask for clarification.

How do you know that? He never clarified.

I will stop replying to you since I don't like being called an idiot. Is that against this website's policy?

The following types of behavior are unacceptable:

  • Harassment, bullying, threats, and insults

He marked @NaOH‘s suggestion as solution.

I was not calling you an idiot. I was speaking about me and that’s my feelings about were I was put by you the way you replied to me.

If you’re thinking I was going to bully you that was never my intention…

Greetings from Germany

Tobias