From e3976248161c11e21331291a41dce073500d50b3 Mon Sep 17 00:00:00 2001
From: Jeffrey Lee <jlee@gitlab.riscosopen.org>
Date: Sat, 21 Jan 2012 19:31:20 +0000
Subject: [PATCH] Adjust volume slider min/max values to match range supported
 by hardware

Detail:
  c/main, c/sound, h/sound - Now uses the additional gain data returned by SoundCtrl_ExamineMixer to alter the volume slider min, max and step values.
  If SoundCtrl_ExamineMixer doesn't return any additional gain data, the sliders will have properties that match those of previous versions of the plugin.
Admin:
  Tested on Iyonix & BB-xM, both with and without the new gain data being available.
  Note that a bug in previous versions of SndSetup will cause it to crash/malfunction if it encounters the new gain data (i.e. SoundCtrl 1.01+ used with a mixer device which implements HAL mixer API 0.1+)


Version 2.04. Tagged as 'SndSetup-2_04'
---
 VersionNum | 20 ++++++++++----------
 c/main     |  1 +
 c/sound    | 53 ++++++++++++++++++++++++++++++++++++++++++++++-------
 h/sound    |  3 +++
 4 files changed, 60 insertions(+), 17 deletions(-)

diff --git a/VersionNum b/VersionNum
index 622538e..0299445 100644
--- a/VersionNum
+++ b/VersionNum
@@ -1,23 +1,23 @@
-/* (2.03)
+/* (2.04)
  *
  * This file is automatically maintained by srccommit, do not edit manually.
  * Last processed by srccommit version: 1.1.
  *
  */
-#define Module_MajorVersion_CMHG        2.03
+#define Module_MajorVersion_CMHG        2.04
 #define Module_MinorVersion_CMHG        
-#define Module_Date_CMHG                14 Jan 2012
+#define Module_Date_CMHG                21 Jan 2012
 
-#define Module_MajorVersion             "2.03"
-#define Module_Version                  203
+#define Module_MajorVersion             "2.04"
+#define Module_Version                  204
 #define Module_MinorVersion             ""
-#define Module_Date                     "14 Jan 2012"
+#define Module_Date                     "21 Jan 2012"
 
-#define Module_ApplicationDate          "14-Jan-12"
+#define Module_ApplicationDate          "21-Jan-12"
 
 #define Module_ComponentName            "SndSetup"
 #define Module_ComponentPath            "castle/RiscOS/Sources/SystemRes/Configure2/PlugIns/SndSetup"
 
-#define Module_FullVersion              "2.03"
-#define Module_HelpVersion              "2.03 (14 Jan 2012)"
-#define Module_LibraryVersionInfo       "2:3"
+#define Module_FullVersion              "2.04"
+#define Module_HelpVersion              "2.04 (21 Jan 2012)"
+#define Module_LibraryVersionInfo       "2:4"
diff --git a/c/main b/c/main
index 85af950..2454795 100644
--- a/c/main
+++ b/c/main
@@ -289,6 +289,7 @@ static void open_configure_window(int at_x, int at_y)
         ((Gadget *)gadget)->hdr.flags |= (channel[i].category >= 0 ? 10 : 11) << Slider_BarColourShift;
         if (channel[i].fixed) ((Gadget *)gadget)->hdr.flags |= Gadget_Faded;
         error_trap(window_add_gadget(0, config_window_id, (Gadget *)gadget, NULL), 0);
+        error_trap(slider_set_bounds(7, config_window_id, 2+i*4, channel[i].mingain, channel[i].maxgain, channel[i].step), 0);
     }
 
     memcpy(gadget, gadget_template[3], gadget_template_size[3]);
diff --git a/c/sound b/c/sound
index 1168128..d0d2c34 100644
--- a/c/sound
+++ b/c/sound
@@ -47,6 +47,15 @@ unsigned int nchannels;
 static int   menu_to_voice_map[16];
 static int   cmos_voice, cmos_volume;
 
+typedef struct
+{
+    unsigned short flags;
+    signed short category;
+    int mingain;
+    int maxgain;
+    int step;
+} mixer_features;
+
 /*---------------------------------------------------------------------------*
  * sound_read_channel_info                                                   *
  *                                                                           *
@@ -65,19 +74,49 @@ void sound_read_channel_info(void)
                      &block_size), 1);
     nchannels = -space_needed / block_size;
     if (nchannels > MAX_CHANNELS) nchannels = MAX_CHANNELS;
-    struct { unsigned short flags; signed short category; } info[nchannels];
+    char buffer[nchannels*block_size];
     error_trap(_swix(SoundCtrl_ExamineMixer, _INR(0,2)|_OUT(4),
                      0,
-                     info,
-                     sizeof info,
+                     buffer,
+                     sizeof buffer,
                      &nchannels), 1);
     for (int i = 0; i < nchannels; i++)
     {
-        channel[i].category = info[i].category;
+        mixer_features *info = (mixer_features *) (buffer+(block_size*i));
+        channel[i].category = info->category;
         channel[i].index = -1;
-        channel[i].muted_by_default = info[i].flags & 4;
-        channel[i].fixed = info[i].flags & 1;
-        channel[i].mono = info[i].flags & 2;
+        channel[i].muted_by_default = info->flags & 4;
+        channel[i].fixed = info->flags & 1;
+        channel[i].mono = info->flags & 2;
+        if (block_size >= 16)
+        {
+            channel[i].mingain = info->mingain;
+            channel[i].maxgain = info->maxgain;
+            channel[i].step = info->step;
+        }
+        else
+        {
+            /* Use old limits of +0/-34.5, step 24 */
+            channel[i].mingain = (int) (-34.5*16);
+            channel[i].maxgain = 0;
+            channel[i].step = 24;
+        }
+        if (channel[i].step <= 0)
+            channel[i].step = 1;
+        /* Limit minimum gain to arbitrarily chosen value of -40dB
+           This is to avoid too much of the bar being taken up by negative
+           values if the mixer is capable of high attenuation (e.g. OMAP3 can
+           go from -80 to +24, but the +ve range is the one we're interested in
+           since it's a quiet system overall) */
+        if (channel[i].mingain < -40*16)
+        {
+            /* Ensure new value is still a multiple of the step size */
+            int steps = (40*16+channel[i].step-1)/channel[i].step;
+            channel[i].mingain = -steps*channel[i].step;
+        }
+        /* Sanity check */
+        if (channel[i].mingain >= channel[i].maxgain)
+            channel[i].mingain = channel[i].maxgain-16;
     }
     while (nchannels > 0)
     {
diff --git a/h/sound b/h/sound
index 3f4620f..7d75350 100644
--- a/h/sound
+++ b/h/sound
@@ -38,6 +38,9 @@ extern struct channel
   bool fixed;
   bool mono;
   bool muted_by_default;
+  int mingain;
+  int maxgain;
+  int step;
 }
 channel[MAX_CHANNELS];
 
-- 
GitLab