[nas] [PATCH] changed method of setting the input gain

Erik Auerswald auerswal at unix-ag.uni-kl.de
Mon Jul 24 19:40:20 MDT 2006


Hi,

On Mon, Jul 24, 2006 at 07:16:18PM -0600, Jon Trulson wrote:
> On Tue, 25 Jul 2006, Erik Auerswald wrote:
> >On Mon, Jul 24, 2006 at 02:59:06PM -0400, Paul Fox wrote:
> >>i wrote:
> >>> erik wrote:
> >>> > On Sun, Jul 23, 2006 at 10:29:07PM -0600, Jon Trulson wrote:
> [...]
> >>> >>         opens the device, shouldn't it?
> >>> >
> >>> > I don't think so. The defaults should be applied the first time the
> >>> > device is opened. After that the last set values should be activated
> >>> > (what is done now to keep the changes made while the device was
> >>> > released).
> >>>
> >>> but isn't the point of releasing the device that you want to play
> >>> well with other users of the device?  in that case, shouldn't you
> >>> touch nothing at all on a re-acquire of the device?  seems to me
> >
> >IMHO the NAS server should keep it's settings even if after releasing
> >the sound device. I'd want to allow other programs to use (and change
> >the settings of) the sound device when NAS is not using it, but I would
> >not want this to screw up the settings of the NAS server.
> 
>         I agree here.

:-)

> >If you want to be very polite you could save the current settings and
> >restore them just before releasing the device again.
> 
>   Looks like a new option: MixerRestore :)
> 
> >
> >>> the server should query the device for current settings when it
> >>> re-opens, and start from there.
> >
> >The "mixerinit" option will keep the current mixer settings when first
> >opening the device. The "nomixer" option will always keep the mixer
> >settings and never change them.
> >
> 
>         So NAS clients would not be able to alter their gains for
>         instance?

That's the idea. NAS would not use the mixer at all as if there was no
mixer.

> >My "consistent gain setting" patches had the reason that I wanted to be
> >able to control the NAS settings even if the device is currently
> >released. This is very useful if the last NAS user left the gain at 100
> >from watching a DVD and my music should be played with gain 30. If the
> >NAS server did not change the settings of a reopened device I would have
> >to endure some much too loud music for the time I need to react to the
> >starting playback.
> 
>   You mean non-nas application setting the gain at 100, right?

I mean a NAS application setting the gain to 100. I wanted to be able to
change this setting without first starting the way too loud playback.

>   From what the code does (and what I see), if a nas app sets output
>   gain to 100, then that is what will be used for the next nas app as
>   well.
> 
>   If I use a NAS app (xmms with NAS pluggin) to set the gain to 100
>   then the next nas app, gets the too high gain.  This is why I'd
>   prefer option 2.  It's annoying when festival screams at me from
>   across the living room, after I've used NAS xmms at too loud a
>   volume :)

The RestoreMixer option could indeed help here. ;-)

> >>looking at the code (for other reasons) i see that this is
> >>complicated by the fact that auvoxware.c goes out of its way to
> >>never ever read the current mixer settings.  it only writes to
> >>them.  seems to me that if the device is being shared with other
> >>applications, that nas should be sharing the levels as well.
> >
> >Well, it actually reads the levels in initMixer(), but never uses them.
> >This is to be changed by the reworked "mixerinit" option.
> >
> 
>         I like the idea of saving/restoring settings.
> 
> [...]
> >>i can also do a patch to eliminate the use of (the recently
> >>renamed :-) "lastPhysicalOutput" variable, in favor of actually
> >>reading the device.
> >
> >As stated above I would not like this.
> 
>   Yeah, lets discuss the mixer init stuff and find something we can
>   all be happy with :)

I've attached a patch that does what I think "mixerinit = no" should do
(and keeps the current behaviour for "mixerinit = yes").

At startup the mixer settings are queried and the server values set to
them if "mixerinit" is set to "no". Any NAS client can change the mixer
settings later.

Please take a look at it and tell me what you all think.

Erik
-------------- next part --------------
Index: server/nasd.conf.man
===================================================================
--- server/nasd.conf.man	(revision 162)
+++ server/nasd.conf.man	(working copy)
@@ -28,11 +28,16 @@
 on stderr.  Set <num> to 0 to disable debug messages, 99 for *alot* of
 debug messages.
 .PP
-.B mixerinit "YES"|"NO"
-Set to "YES" to "NO".  Defines whether the server will init the mixer
-device on startup. (voxware)
+.B ReleaseDevice "YES" | "NO"
+Set to "YES" or "NO". Defines whether the server should release the audio
+device when finished playing or recording a sound. (voxware, hpux, sun)
 .PP
-.B OutDevType "EXT"|"INT"
+.B MixerInit "YES" | "NO"
+Set to "YES" or "NO".  Defines whether the server will init the mixer
+device on startup. Later changes of gain or input mode will change the
+mixer settings. (voxware)
+.PP
+.B OutDevType "EXT" | "INT"
 For HPUX servers, define to "EXT" to use the external output device
 (headphone/speakers) or "INT" for the internal output device (internal
 speaker).  Defaults to external.
Index: server/dda/voxware/auvoxware.c
===================================================================
--- server/dda/voxware/auvoxware.c	(revision 162)
+++ server/dda/voxware/auvoxware.c	(working copy)
@@ -475,7 +475,6 @@
   d->location = AuDeviceLocationRightMask | AuDeviceLocationLeftMask
                 | AuDeviceLocationExternalMask;
   d->numChildren = 0;
-  d->gain = auDefaultInputGain;
   d->minibuf = auInput;
   d->minibufSize = d->numTracks * bytesPerSampleIn * auMinibufSamples;
   d->physicalDeviceMask = (sndStatIn.isStereo) ? PhysicalInputStereo
@@ -502,9 +501,41 @@
 
   if (!initialized) {
     initialized = AuTrue;
-    setPhysicalOutputGain(auDefaultOutputGain);
-    setPhysicalInputGainAndLineMode(auDefaultInputGain, 0);
+    if (leave_mixer) {
+      lastPhysicalOutputGain = stereoOutputDevice->gain = monoOutputDevice->gain
+                             = level[SOUND_MIXER_PCM] >> 8;
 
+      switch (recControlMode) {
+        case useMixerIGain:
+          stereoInputDevice->gain = monoInputDevice->gain
+                                  = level[SOUND_MIXER_IGAIN] >> 8;
+          break;
+
+        case useMixerRecLev:
+          stereoInputDevice->gain = monoInputDevice->gain
+                                  = level[SOUND_MIXER_RECLEV] >> 8;
+          break;
+
+        case useMixerLineMic:
+          if (recsrc && (recsrc & SOUND_MASK_LINE))
+            stereoInputDevice->gain = monoInputDevice->gain
+                                    = level[SOUND_MIXER_LINE] >> 8;
+          if (recsrc && (recsrc & SOUND_MASK_MIC))
+            stereoInputDevice->gain = monoInputDevice->gain
+                                    = level[SOUND_MIXER_MIC] >> 8;
+          break;
+
+        default:
+          osLogMsg("%s: can't read current recording level\n",sndStatOut.mixer);
+          stereoInputDevice->gain = monoInputDevice->gain = 0;
+          break;
+      }
+      lastPhysicalInputGain = stereoInputDevice->gain;
+    } else {
+      setPhysicalOutputGain(auDefaultOutputGain);
+      setPhysicalInputGainAndLineMode(auDefaultInputGain, AuDeviceLineModeLow);
+    }
+
     /* JET - close the device if requested... only needs to happen
        here during first time init as diasableProcessFlow will handle
        it from here on out. */
@@ -1036,10 +1067,9 @@
         break;
     }
 
-    if (!leave_mixer)
-      if (ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_RECSRC), &recsrc) == -1)
-        osLogMsg("%s: ioctl(MIXER_WRITE(SOUND_MIXER_RECSRC)) failed: %s\n",
-                 sndStatOut.mixer, strerror(errno));
+    if (ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_RECSRC), &recsrc) == -1)
+      osLogMsg("%s: ioctl(MIXER_WRITE(SOUND_MIXER_RECSRC)) failed: %s\n",
+               sndStatOut.mixer, strerror(errno));
   }
 }
 
@@ -1533,6 +1563,12 @@
                  strerror(errno));
       recsrc = 0;
       /* 	  return AuFalse; - let's not be too hasty */
+    } else {
+      if (recsrc == SOUND_MASK_MIC) {
+        lastPhysicalInputLineMode = AuDeviceLineModeHigh;
+      } else {
+        lastPhysicalInputLineMode = AuDeviceLineModeLow;
+      }
     }
   
     if (ioctl(mixerfd, SOUND_MIXER_READ_STEREODEVS, &stereodevs) == -1) {
@@ -1733,6 +1769,8 @@
   AuRegisterCallback(AuGetPhysicalOutputGainCB, getPhysicalOutputGain);
   AuRegisterCallback(AuSetPhysicalInputGainAndLineModeCB,
 		     setPhysicalInputGainAndLineMode);
+  AuRegisterCallback(AuGetPhysicalInputGainCB, getPhysicalInputGain);
+  AuRegisterCallback(AuGetPhysicalInputModeCB, getPhysicalInputLineMode);
   AuRegisterCallback(AuEnableProcessFlowCB, enableProcessFlow);
   AuRegisterCallback(AuDisableProcessFlowCB, disableProcessFlow);
   AuRegisterCallback(AuReadPhysicalInputsCB, readPhysicalInputs);


More information about the Nas mailing list