From 8686aad50775b7a0c770ea501a57eb727d1d7dc9 Mon Sep 17 00:00:00 2001
From: "NGnius (Graham)" <ngniusness@gmail.com>
Date: Mon, 16 Dec 2019 21:31:03 -0500
Subject: [PATCH] Add audio volume tools

---
 .../Tests/GamecraftModdingAPIPluginTest.cs    |  2 +
 GamecraftModdingAPI/Utility/AudioTools.cs     | 82 +++++++++++++++++++
 2 files changed, 84 insertions(+)
 create mode 100644 GamecraftModdingAPI/Utility/AudioTools.cs

diff --git a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs
index cdafb76..7c0e7df 100644
--- a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs
+++ b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs
@@ -42,6 +42,8 @@ namespace GamecraftModdingAPI.Tests
             //SteamInitPatch.ForcePassSteamCheck = true;
             // in case running in a VM
             //MinimumSpecsCheckPatch.ForcePassMinimumSpecCheck = true;
+            // disable background music
+            AudioTools.SetVolume(0.0f, "Music");
 
             // debug/test handlers
             EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("App Inited event!"); }, () => { },
diff --git a/GamecraftModdingAPI/Utility/AudioTools.cs b/GamecraftModdingAPI/Utility/AudioTools.cs
new file mode 100644
index 0000000..4d4af0d
--- /dev/null
+++ b/GamecraftModdingAPI/Utility/AudioTools.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using FMODUnity;
+using FMOD.Studio;
+
+namespace GamecraftModdingAPI.Utility
+{
+    /// <summary>
+    /// Common operations on audio objects
+    /// </summary>
+    public static class AudioTools
+    {
+        /// <summary>
+        /// Retrieve the list of mixers (aka VCAs)
+        /// </summary>
+        /// <returns>The names of the mixers (without "vca:/")</returns>
+        public static string[] GetMixers()
+        {
+            Bank masterBank;
+            RuntimeManager.StudioSystem.getBank("bank:/Master Bank", out masterBank);
+            VCA[] masterVCAs;
+            int count;
+            masterBank.getVCAList(out masterVCAs);
+            masterBank.getVCACount(out count);
+            string[] result = new string[count];
+            string path;
+            for (int i = 0; i < count; i++)
+            {
+                masterVCAs[i].getPath(out path);
+                result[i] = path.Replace("vca:/", "");
+            }
+            return result;
+        }
+
+        /// <summary>
+        /// Get the volume of an audio mixer
+        /// </summary>
+        /// <param name="mixer">The name of the mixer</param>
+        /// <returns>The volume</returns>
+        public static float GetVolume(string mixer)
+        {
+            float volume, finalVolume;
+            RuntimeManager.GetVCA($"vca:/{mixer}").getVolume(out volume, out finalVolume);
+            return volume;
+        }
+
+        /// <summary>
+        /// Get the volume of an audio mixer at output time (this is influenced by the mixer volume and master volume)
+        /// </summary>
+        /// <param name="mixer">The name of the mixer</param>
+        /// <returns>The final volume</returns>
+        public static float GetVolumeOutput(string mixer)
+        {
+            float volume, finalVolume;
+            RuntimeManager.GetVCA($"vca:/{mixer}").getVolume(out volume, out finalVolume);
+            return finalVolume;
+        }
+
+        /// <summary>
+        /// Set the volume of an audio mixer (like a VCA aka Voltage-Controlled Amplifier)
+        /// </summary>
+        /// <param name="volume">The volume from 0.0 to 1.0 (1.0+ is valid too)</param>
+        /// <param name="mixer">The name of the mixer, as retrieved from GetMixers()</param>
+        public static void SetVolume(float volume, string mixer)
+        {
+            RuntimeManager.GetVCA($"vca:/{mixer}").setVolume(volume);
+        }
+
+        /// <summary>
+        /// Set the volume for all future audio
+        /// </summary>
+        /// <param name="volume">The volume from 0.0 to 1.0 (1.0+ is valid too)</param>
+        public static void SetVolumeMaster(float volume)
+        {
+            RuntimeManager.GetBus("bus:/").setVolume(volume);
+        }
+    }
+}