Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How do you mute a AudioMixerGroup from code?

Discussion in 'Audio & Video' started by jerotas, Mar 10, 2015.

  1. jerotas

    jerotas

    Joined:
    Sep 4, 2011
    Posts:
    5,572
    I typed the following code expecting to see mute, solo and bypassEffects methods or properties, and I see...NONE of it from Intellisense. Where the heck is it hiding? How do you do that?

    Code (csharp):
    1.  
    2. public AudioMixerGroup grp; // assign from Inspector
    3.  
    4. grp. // where are the mute / solo API?
    5.  
     
    MrFuzzzy likes this.
  2. blizzy

    blizzy

    Joined:
    Apr 27, 2014
    Posts:
    775
    You can either use mixer snapshots and transition to one of those snapshots, or you can expose any of the settings (like volume) for code, then use the exposed setting in your code (via AudioMixer.)
     
  3. jerotas

    jerotas

    Joined:
    Sep 4, 2011
    Posts:
    5,572
    Snapshots are overkill. I only want to change the mute status of a couple Groups, nothing more. How do we expose the mute button for a Group and set it from code?

    I don't understand why this needs to be done. I have no idea why they didn't just put the mute and solo switches into the normal API. It would be very useful.
     
    Last edited: Mar 10, 2015
  4. blizzy

    blizzy

    Joined:
    Apr 27, 2014
    Posts:
    775
    Why is a snapshot overkill? You can transition to it with a duration of zero, effectively muting all your desired groups at once. Also, it is nicer to configure the snapshot from the editor than having to hardwire the muting into your code.

    The mute button itself cannot be exposed to scripting, it seems. Instead, you just select any group, then in the inspector, right-click on the "Volume" label, and select "Expose 'Volume ...' to script." Then in your script, you can do this:

    mixer.SetFloat("volume", 0f);
     
  5. jerotas

    jerotas

    Joined:
    Sep 4, 2011
    Posts:
    5,572
    The muting would be far more useful for what I'm trying to do. Since I want to have a separately mutable music volume, SFX volume and ambient volume, that means I'd need to create 2x2x2 = 8 snapshots to get all the mute combinations? Ludicrous.

    Snapshots are great for some things, but the mute control should still be exposed automatically from code. No solution to this?

    I don't necessarily want to set the volume...just mute it. I don't want to lose the volume level previously set.
     
    RomanSpai, Foreman_Dev, cxode and 3 others like this.
  6. sonicviz

    sonicviz

    Joined:
    May 19, 2009
    Posts:
    1,051
    I've come to the same conclusion.
    I'm looking into the mixer for a procedural project (using Master Audio) and while the manual looks great you can't seem to access anything low level.

    How you you control any of the mixer FX from code, for example?
     
  7. gregzo

    gregzo

    Joined:
    Dec 17, 2011
    Posts:
    795
    FX params: right click, select expose parameter, name your param, enjoy. Only floats, only from the main thread.
     
  8. sonicviz

    sonicviz

    Joined:
    May 19, 2009
    Posts:
    1,051
    Last edited: Mar 11, 2015
  9. blizzy

    blizzy

    Joined:
    Apr 27, 2014
    Posts:
    775
    No. Granted, the snapshots are mixer-wide, but you can always create sub-mixers. In your case, you could create separate mixers for music, sfx, and ambient, all of which only have the default "Master" group. Then, you can route those mixers into your main mixer. For the three mixers, you can set up snapshots to mute them separately.

    I agree. I don't think it is possible right now, though.

    I see. It wasn't clear to me you wanted to "keep" the previous volume.
     
    Zelek likes this.
  10. jerotas

    jerotas

    Joined:
    Sep 4, 2011
    Posts:
    5,572
    Ok, thanks. Is there somewhere we can "ask for" this capability to be added?
     
  11. blizzy

    blizzy

    Joined:
    Apr 27, 2014
    Posts:
    775
    I'd say the issue tracker should be a good place.
     
    phobos2077 and jerotas like this.
  12. FlyingHighUp

    FlyingHighUp

    Joined:
    Apr 23, 2012
    Posts:
    16
    Is there performance savings by using the mute vs. setting the volume to 0?
    This was my only motivation for trying to use it.
     
  13. Anjoom

    Anjoom

    Joined:
    May 15, 2017
    Posts:
    3
    Umm... Even exposing the volume parameter isnt working for me. I get an error CS1061 saying
    Type 'UnityEngine.Audii.AudioMixerGroup' doe not contain a definition for 'SetFloat' and no extention method 'SetFloat' of typr 'UnityEngine.Audio.AudioMixerGroup' could be found. Are you missing an assembly reference?
    Sorry for the noob question
     
  14. dylansunkel

    dylansunkel

    Joined:
    Jun 4, 2016
    Posts:
    1
    YourAudioMixerGroup.audioMixer.SetFloat("MyExposedParamName", 0f);
     
  15. PixelLifetime

    PixelLifetime

    Joined:
    Mar 30, 2017
    Posts:
    90
  16. OSMET

    OSMET

    Joined:
    Jun 22, 2017
    Posts:
    2
  17. Starbox

    Starbox

    Joined:
    Sep 17, 2014
    Posts:
    456
    Bumping this.
    Has there been any update concerning the exposure of Solo, Mute and Bypass modes?
    I find myself having the same need as jerotas here with music and sfx, I have combinations of volumes management AND options to entirely mute content. It seemed more intuitive to work with these functions than fiddle with a maze of mixers.

    Nevertheless, using an array of sub-mixers does work, notably by creating snapshots for MSB options, but it is over-engineered and not edit-friendly: I didn't find a way to copy portions of the Groups hierarchy of my main mixer into the new and separate sub-mixers. It's absurd how much time I'm wasting recreating entire parts of the main Groups hierarchy. Right-clicking on any Group doesn't reveal anything useful such as Copy/Paste options!

    Finally, exposing certain variables could really be made much more accessible and obvious in the Inspector.
     
    aydin_khp and DriesVienne like this.
  18. empika

    empika

    Joined:
    Jul 12, 2012
    Posts:
    31
    THIS!

    It's sometimes increadibly frustrating to work with Unity when issues like this have been around for so long. Everything new and shiny gets mostly/half finished before the next big exciting thing comes along, and old core features such as this just get left to rot. This thread is nearly 5 years old and we still can't unmute a mixer channel
     
    DriesVienne, ihgyug, IARI and 3 others like this.
  19. realcosmik

    realcosmik

    Joined:
    Nov 27, 2018
    Posts:
    20
    yeah its a little insane im not gonna lie that they have time to make things as lowlevel as DOTS but take long to expose such API as this
     
    Last edited: Nov 10, 2020
    IARI likes this.
  20. KenjiShiguma

    KenjiShiguma

    Joined:
    Jul 15, 2015
    Posts:
    2
    I agree. Unity is wild for not just exposing the Mute, Solo, and Bypass into the API. It's not complicated... o_O I expect more from them...
     
    IARI likes this.
  21. redarcanastudio

    redarcanastudio

    Joined:
    Jan 5, 2019
    Posts:
    1
    Here try doing this

    Code (CSharp):
    1.  
    2.  public AudioMixer audiomixer;
    3.  private bool musicoff = false;
    4.  
    5. //Expose Parameters by right clicking volume of your audio mixer group in the inspector panel
    6. //I have renamed it to Music
    7.  
    8. void Update {
    9.        if (musicoff == true)
    10.        {
    11.             audiomixer.SetFloat("Music", -80f);
    12.  
    13.         }
    14.  
    15.         else if (musicoff == false)
    16.         {
    17.             audiomixer.SetFloat("Music", 0f);
    18.  
    19.         }
    20.  
    21. //Set these values to the desired decibels
    22. }
    23.  
     
    Last edited: May 10, 2020
  22. KenjiShiguma

    KenjiShiguma

    Joined:
    Jul 15, 2015
    Posts:
    2
    I appreciate your contribution; I don't think the issue is that we don't know how to make mute functionality. The main complaint (or at least mine) is that Unity has the built in functionality to mute specific audio groups in the Editor GUI, but it's not exposed in the code API.

    By the way, while your solution would work, it is very inefficient because you are checking to see if audio should be muted/unmuted every frame. If I had to implement this, I would use an event driven system; OnClick/OnThisEvent -> Toggle the Audio.

    Thank you though!
     
    IARI, MrFuzzzy and PixelLifetime like this.
  23. IARI

    IARI

    Joined:
    May 8, 2014
    Posts:
    70
    I's exactly as empika says - whatever API from Unity you get into, it looks shiny at first and then you discover: Oh, its in reality ... unusable.
    I cannot understand these decisions.
    Why would they do that and not expose mute functionality in the first place.
    This is incredible ... it's insane.
     
    Last edited: Oct 26, 2020
    EZaca, cp-, aydin_khp and 4 others like this.
  24. Daerst

    Daerst

    Joined:
    Jun 16, 2016
    Posts:
    275
    Why do you hate me, Unity?
     
    EZaca, andreyefimov2010 and HarsanyiT like this.
  25. aydin_khp

    aydin_khp

    Joined:
    May 15, 2020
    Posts:
    29
    Other than not exposing the mute functionality in the API, It is also strange that you cannot assign the mute state to snapshots; Either a channel is muted for all the snapshots or it's not for all of them.
     
  26. Grave188

    Grave188

    Joined:
    Dec 13, 2017
    Posts:
    10
    Toggles and volume sliders

    upload_2022-9-15_12-4-22.png
    upload_2022-9-15_12-2-44.png

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using Tools;
    3. using UnityEngine;
    4. using UnityEngine.Audio;
    5.  
    6. namespace Audio
    7. {
    8.     public class AudioManager : Singleton<AudioManager>
    9.     {
    10.  
    11.         [SerializeField] private AudioMixer audioMixer;
    12.  
    13.         private readonly Dictionary<string, float> _mixerParameterVolume = new();
    14.         private readonly Dictionary<string, bool> _mixerParameterIsToggledOn = new();
    15.  
    16.         public void ToggleMasterVolume_Callback(bool isToggledOn)
    17.         {
    18.        
    19.             const string exposedParam = "Master";
    20.             _mixerParameterIsToggledOn[exposedParam] = isToggledOn;
    21.        
    22.             ToggleVolume(exposedParam, isToggledOn);
    23.         }
    24.  
    25.         public void ToggleMusicVolume_Callback(bool isToggledOn)
    26.         {
    27.  
    28.             const string exposedParam = "Music";
    29.             _mixerParameterIsToggledOn[exposedParam] = isToggledOn;
    30.        
    31.             ToggleVolume(exposedParam, isToggledOn);
    32.         }
    33.    
    34.         public void ToggleSoundEffectsVolume_Callback(bool isToggledOn)
    35.         {
    36.  
    37.             const string exposedParam = "SoundEffect";
    38.             _mixerParameterIsToggledOn[exposedParam] = isToggledOn;
    39.        
    40.             ToggleVolume(exposedParam, isToggledOn);
    41.         }
    42.    
    43.         public void SetMasterVolume_Callback(float volume)
    44.         {
    45.  
    46.             SetVolume("Master", volume);
    47.         }
    48.  
    49.         public void SetMusicVolume_Callback(float volume)
    50.         {
    51.        
    52.             SetVolume("Music", volume);
    53.         }
    54.  
    55.         public void SetSoundEffectsVolume_Callback(float volume)
    56.         {
    57.        
    58.             SetVolume("SoundEffect", volume);
    59.         }
    60.    
    61.         private void ToggleVolume(string exposedParam, bool isToggledOn)
    62.         {
    63.  
    64.             if (isToggledOn)
    65.             {
    66.                 // Because default state must be toggled on
    67.                 if (!_mixerParameterVolume.ContainsKey(exposedParam))
    68.                 {
    69.                     return;
    70.                 }
    71.            
    72.                 float volume = _mixerParameterVolume[exposedParam];
    73.                 audioMixer.SetFloat(exposedParam, volume);
    74.             }
    75.             else
    76.             {
    77.                 audioMixer.GetFloat(exposedParam, out float temp);
    78.                 _mixerParameterVolume[exposedParam] = temp;
    79.                 audioMixer.SetFloat(exposedParam, -80f);
    80.             }
    81.         }
    82.    
    83.         private void SetVolume(string mixerParam, float volume)
    84.         {
    85.             // Setting default key if not presented yet
    86.             if (!_mixerParameterIsToggledOn.ContainsKey(mixerParam))
    87.             {
    88.                 _mixerParameterIsToggledOn[mixerParam] = true;
    89.             }
    90.  
    91.             bool isToggledOn = _mixerParameterIsToggledOn[mixerParam];
    92.             if (isToggledOn)
    93.             {
    94.                 float result = CalculateMixerVolume(volume);
    95.                 audioMixer.SetFloat(mixerParam, result);
    96.             }
    97.             else
    98.             {
    99.                 _mixerParameterVolume[mixerParam] = CalculateMixerVolume(volume);
    100.             }
    101.  
    102.             float CalculateMixerVolume(float f)
    103.             {
    104.  
    105.                 return -Mathf.Pow(51f, 1f - f) + 1f;
    106.             }
    107.         }
    108.     }
    109. }
    110.  
    -Mathf.Pow(51f, 1f - f) + 1f is the way to nonlinear normalise sound (1f is 0 dB and 0f is -50 dB)
     
  27. ColtPtrHun

    ColtPtrHun

    Joined:
    Nov 20, 2019
    Posts:
    9
    Not to mention you can only refer to the exposed parameters using string comparison, not hashes (like in Animator). This API is a disaster...
     
  28. KeigoTakamura

    KeigoTakamura

    Joined:
    Mar 8, 2022
    Posts:
    6
    Will it still solve the problem of no Mute flag exposed on the AudioMixerGroup?
    It's not very cool to leave the MuteState and raw Value in the save data, but is it still not good...
     
  29. CWatsonT2

    CWatsonT2

    Joined:
    Jan 9, 2019
    Posts:
    114
    Is there a way to do this while using spatialize on the audio source? I am using snapshots to control the audio the way I want but once I turn on spatialize on the audio source it seems to override all my snapshot settings. I can still see the snapshot settings are applied (all the group volumes are set to -80) but the audio can still be heard playing on the master track. I turn off spatialize and it goes silent like it's supposed to. Thoughts? I have to have spatialize on.
     
  30. JulianNeil

    JulianNeil

    Joined:
    Jun 27, 2022
    Posts:
    78
    I know this is an old thread, but going back to the OPs question - I have found it easiest to implement mute at the AudioSource level by grouping AudioSources under GameObjects and toggling the active state of the GameObject from a script. This has the added benefit of reducing cpu and allowing your mixers to stop using resources when they end up having no audio levels. It also allows you to mute without changing audiogroup volume levels - so it is independent of snapshots.

    This doesn't address some of the other things mentioned in this thread - but it is useful for muting.
     
  31. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    847
    The best workaround I have found so far is adding a dummy group somewhere inbetween, expose its volume and set that to -80f if I want to mute all groups at once while preserving their current volume at the same time.

    upload_2024-1-19_22-17-46.png

    You could of course put that group at the top of the hierarchy but to me if feels the Master group should be the top most.