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

Erik Auerswald auerswal at unix-ag.uni-kl.de
Thu Jul 27 01:11:29 MDT 2006


Hi,

On Wed, Jul 26, 2006 at 04:10:54AM +0200, Erik Auerswald wrote:
> On Tue, Jul 25, 2006 at 06:31:06PM -0600, Jon Trulson wrote:
> > On Tue, 25 Jul 2006, Paul Fox wrote:
> > >erik wrote:
> > >> On Mon, Jul 24, 2006 at 11:12:18PM -0400, Paul Fox wrote:
> > >> >     - i want nas to always use *and report* the current mixer settings.
> > >> > 	if another app uses and adjusts the mixer, i want nas to notice
> > >> > 	that, so that clients can see that it's happened.
> > >>
> > >> The only way to achieve this is to keep the mixer device open. I would
> > >> be happy with this as well since then NAS mixer changes would immediatly
> > >> affect the audio hardware. The setting of last used values on reopen
> > >> would then not be necessary.
> > >>
> > >> Several programs can use the mixer device at the same time so this
> > >> should not be problematic.
> > >
> > >ah.  i think this was the missing piece, for me -- that while only
> > >one program can have the pcm device open, more than one can have the
> > >mixer open.
> > >
> > >do you think it even needs to be configurable?  any reason not to
> > >just leave the mixer open all the time (assuming we're not configured
> > >to never use it at all)?  if configurable, it seems like it should
> > >be a boolean, separate from the mixerinit options being discussed.
> 
> I'd say it does not need to be configurable. I've just checked the OSS
> programming manual and it's official that several programms can open the
> mixer device at the same time. And I agree that a seperate boolean
> should be used if it should be configurable nevertheless.

There was already a variable to control this (but no code did use it).
The attached patch implements this config variable for the voxware
server.

> >         If this can be done (track mixer changes), and mixer usage is
> >         configured to be allowed, then it should 'just work', no
> >         option neccessary.  IMO of course.
> 
> That can be done. In the getPhysical* functions the mixer can be
> queried. We would not need the last* variables any more (I think). I've
> already tested this for the output gain and can come up with a patch.
> I'll wait for the re-indentation patch first. ;-)

The patch is attached to this mail. It is not without issues, though:
When reading the IGain value from the mixer the ioctl returns -1 with
errno == 0 (success) most of the time. The value was read correctly
every time I tested this regardless of error reported. I have no idea
why this happens. The patch works for me, it justs spams the logfiles
with lots of error: success messages. I was using aupanel to control the
NAS mixer, I did not check if auctl behaves the same (it should).

Erik
-------------- next part --------------
Index: server/nasd.conf.eg
===================================================================
--- server/nasd.conf.eg	(revision 168)
+++ server/nasd.conf.eg	(working copy)
@@ -18,6 +18,11 @@
 # Only the voxware, hpux, and sun servers understand this for now.
 ReleaseDevice "yes"
 
+# set this to "yes" or "no" to indicate whether nasd should keep the mixer
+#  device open when releasing the audio device.
+# Only the voxware server understands this for now.
+KeepMixer "yes"
+
 # init the mixer on startup? Voxware only.
 MixerInit	"yes"			
 
Index: server/nasd.conf.man
===================================================================
--- server/nasd.conf.man	(revision 168)
+++ server/nasd.conf.man	(working copy)
@@ -32,6 +32,10 @@
 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 KeepMixer "YES" | "NO"
+Set to "YES" or "NO". Defines whether the server should keep the mixer open
+when releasing the audio device. (voxware)
+.PP
 .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
Index: server/dda/voxware/auvoxware.c
===================================================================
--- server/dda/voxware/auvoxware.c	(revision 168)
+++ server/dda/voxware/auvoxware.c	(working copy)
@@ -225,19 +225,12 @@
 static AuBool leave_mixer = 0;
 static AuBool share_in_out = 0;
 
-static int lastPhysicalOutputGain;      /* output gain */
-static int lastPhysicalInputGain;       /* input gain */
-static int lastPhysicalInputLineMode;   /* input line mode */
 static int recControlMode = 0;  /* how to control recording level */
-static int level[100];
 static int mixerfd = -1;        /* The mixer device */
 static int devmask = 0;         /* Bitmask for supported mixer devices */
-static int recsrc = 0;          /* Currently selected recording sources */
 static int recmask = 0;         /* Supported recording sources */
 static int stereodevs = 0;      /* Channels supporting stereo */
 
-static char *labels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
-
 int VOXMixerInit = TRUE;        /* overridden by nasd.conf */
 
 /* end of VOXware driver mixer control variables */
@@ -357,6 +350,125 @@
 #endif /* sco */
 
 static int
+readMixerOutputGain(void)
+{
+    int pcm_level = 0;
+
+    if (mixerfd != -1) {
+        if (ioctl(mixerfd, MIXER_READ(SOUND_MIXER_PCM), &pcm_level) == -1) {
+            osLogMsg("readMixerOutputGain: "
+                     "%s: ioctl(%d, MIXER_READ(SOUND_MIXER_PCM)) failed: %s\n",
+                     sndStatOut.mixer, mixerfd, strerror(errno));
+        }
+        pcm_level = pcm_level >> 8;
+    } else {
+        pcm_level = sndStatOut.gain;
+    }
+
+    return pcm_level;
+}
+
+static int
+readMixerInputMode(void)
+{
+    int input_mode = 0;
+
+    if (mixerfd != -1) {
+        if (ioctl(mixerfd, MIXER_READ(SOUND_MIXER_RECSRC), &input_mode) == -1) {
+            osLogMsg("readMixerInputMode: "
+                     "%s: ioctl(%d, MIXER_READ(SOUND_MIXER_RECSRC)) failed: "
+                     "%s\n", sndStatOut.mixer, mixerfd, strerror(errno));
+        }
+        if (!(input_mode & (SOUND_MASK_MIC | SOUND_MIXER_LINE))) {
+            input_mode = 1<<SOUND_MIXER_LINE;
+        }
+    } else {
+        input_mode = 1<<SOUND_MIXER_LINE;
+    }
+
+    return input_mode;
+}
+
+static int
+readMixerInputGain(void)
+{
+    int in_level = 0;
+    int recsrc = 0;
+    
+    recsrc = readMixerInputMode();
+
+    if (mixerfd != -1) {
+        switch (recControlMode) {
+        case useMixerIGain:
+            if (ioctl(mixerfd, MIXER_READ(SOUND_MIXER_IGAIN),&in_level) != -1) {
+                osLogMsg("readMixerInputGain: %s: "
+                         "ioctl(MIXER_READ(SOUND_MIXER_IGAIN)) failed: %s\n",
+                         sndStatOut.mixer, strerror(errno));
+            }
+            in_level = in_level >> 8;
+            break;
+
+        case useMixerRecLev:
+            if (ioctl(mixerfd, MIXER_READ(SOUND_MIXER_RECLEV),&in_level) != -1){
+                osLogMsg("readMixerInputGain: "
+                         "%s: ioctl(%d, MIXER_READ(SOUND_MIXER_RECLEV)) failed:"
+                         " %s\n", sndStatOut.mixer, mixerfd, strerror(errno));
+            }
+            in_level = in_level >> 8;
+            break;
+
+        case useMixerLineMic:
+            if (recsrc & SOUND_MASK_LINE) {
+                if (ioctl(mixerfd, MIXER_READ(SOUND_MIXER_LINE), &in_level)
+                    != -1) {
+                    osLogMsg("readMixerInputGain: "
+                             "%s: ioctl(%d, MIXER_READ(SOUND_MIXER_LINE)) "
+                             "failed: %s\n",
+                             sndStatOut.mixer, mixerfd, strerror(errno));
+                }
+                in_level = in_level >> 8;
+            } else if (recsrc & SOUND_MASK_MIC) {
+                if (ioctl(mixerfd, MIXER_READ(SOUND_MIXER_MIC), &in_level)
+                    != -1) {
+                    osLogMsg("readMixerInputGain: "
+                             "%s: ioctl(%d, MIXER_READ(SOUND_MIXER_MIC)) "
+                             "failed: %s\n",
+                             sndStatOut.mixer, mixerfd, strerror(errno));
+                }
+                in_level = in_level >> 8;
+            } else {
+                in_level = sndStatIn.gain;
+            }
+            break;
+
+        default:
+            osLogMsg("readMixerInputGain: "
+                     "unknown value %d of recControlMode\n", recControlMode);
+        }
+    } else {
+        in_level = sndStatIn.gain;
+    }
+
+    return in_level;
+}
+
+static AuInt8
+mixerInputModeToNAS(int input_mode)
+{
+    if (input_mode & SOUND_MASK_MIC)
+        return AuDeviceInputModeMicrophone;
+
+    if (input_mode & SOUND_MASK_LINE)
+        return AuDeviceInputModeLineIn;
+
+    if (NasConfig.DoDebug)
+        osLogMsg("mixerInputModeToNAS: input mode %d is neither LINE (%d) "
+                 "nor MIC (%d)\n", input_mode, SOUND_MASK_LINE, SOUND_MASK_MIC);
+
+    return AuDeviceInputModeNone;
+}
+
+static int
 createServerComponents(AuUint32 * auServerDeviceListSize,
                        AuUint32 * auServerBucketListSize,
                        AuUint32 * auServerRadioListSize,
@@ -500,38 +612,7 @@
 
     if (!initialized) {
         initialized = AuTrue;
-        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 {
+        if (!leave_mixer) {
             setPhysicalOutputGain(auDefaultOutputGain);
             setPhysicalInputGainAndLineMode(auDefaultInputGain,
                                             AuDeviceLineModeLow);
@@ -700,9 +781,10 @@
         osLogMsg("openDevice\n");
     }
 
-    if (NasConfig.DoDebug)
+    if (NasConfig.DoDebug) {
         osLogMsg("openDevice OUT %s mode %d\n",
                  sndStatOut.device, sndStatOut.howToOpen);
+    }
 
 
     if (sndStatOut.fd == -1) {
@@ -750,11 +832,13 @@
         }
     }
 
-    if (mixerfd == -1)
-        while ((mixerfd = open(sndStatOut.mixer, O_RDONLY | extramode,
+    if (mixerfd == -1) {
+        while ((mixerfd = open(sndStatOut.mixer, O_RDWR | extramode,
                                0666)) == -1 && wait) {
             osLogMsg("openDevice: waiting on mixer device\n");
             sleep(1);
+        }
+        osLogMsg("openDevice: opened mixer %s\n", sndStatOut.mixer);
     } else {
         if (NasConfig.DoDebug) {
             osLogMsg("openDevice: mixer device already open\n");
@@ -848,6 +932,9 @@
             osLogMsg("closeDevice: waiting on mixer device\n");
             sleep(1);
         }
+        if (NasConfig.DoDebug) {
+            osLogMsg("closeDevice: closed mixer device\n");
+        }
         mixerfd = -1;
     }
 
@@ -954,12 +1041,10 @@
     AuInt32 g = AuFixedPointIntegralAddend(gain);
     AuInt32 gusvolume;
 
-
     if (g > 100)
         g = 100;
     if (g < 0)
         g = 0;
-    lastPhysicalOutputGain = g;
 
     if (sndStatOut.gainScale) {
         g *= sndStatOut.gainScale;
@@ -969,17 +1054,15 @@
     gusvolume = g | (g << 8);
     if (mixerfd != -1)
         if (ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_PCM), &gusvolume) == -1)
-            osLogMsg("%s: ioctl(MIXER_WRITE(SOUND_MIXER_PCM)) failed: %s\n", sndStatOut.mixer, strerror(errno));
+            osLogMsg("setPhysicalOutputGain: "
+                     "%s: ioctl(MIXER_WRITE(SOUND_MIXER_PCM)) failed: %s\n",
+                     sndStatOut.mixer, strerror(errno));
 }
 
 static AuFixedPoint
 getPhysicalOutputGain(void)
 {
-    AuInt16 outputGain;
-
-    outputGain = lastPhysicalOutputGain;
-
-    return AuFixedPointFromSum(outputGain, 0);
+    return AuFixedPointFromSum(readMixerOutputGain(), 0);
 }
 
 static void
@@ -988,19 +1071,21 @@
     AuInt16 g = AuFixedPointIntegralAddend(gain);
     AuInt16 inputAttenuation;
     AuInt16 zero = 0;
+    int recsrc;
 
     if (g < 100)
         inputAttenuation = g;
     else
         inputAttenuation = 100;
 
-    lastPhysicalInputGain = inputAttenuation;
-    lastPhysicalInputLineMode = lineMode;
-
     if (lineMode == AuDeviceLineModeHigh) {
         recsrc = SOUND_MASK_MIC & recmask;
     } else if (lineMode == AuDeviceLineModeLow) {
         recsrc = SOUND_MASK_LINE & recmask;
+    } else {
+        osLogMsg("setPhysicalInputGainAndLineMode: illegal lineMode %d\n",
+                 lineMode);
+        recsrc = readMixerInputMode();
     }
 
     inputAttenuation = inputAttenuation << 8 | inputAttenuation;
@@ -1014,65 +1099,71 @@
             if (ioctl
                 (mixerfd, MIXER_WRITE(SOUND_MIXER_IGAIN),
                  &inputAttenuation) == -1)
-                osLogMsg("%s: ioctl(MIXER_WRITE(SOUND_MIXER_IGAIN)) failed: %s\n", sndStatOut.mixer, strerror(errno));
+                osLogMsg("setPhysicalInputGainAndLineMode: "
+                         "%s: ioctl(MIXER_WRITE(SOUND_MIXER_IGAIN)) failed: "
+                         "%s\n", sndStatOut.mixer, strerror(errno));
             break;
 
         case useMixerRecLev:
             if (ioctl
                 (mixerfd, MIXER_WRITE(SOUND_MIXER_RECLEV),
                  &inputAttenuation) == -1)
-                osLogMsg("%s: ioctl(MIXER_WRITE(SOUND_MIXER_RECLEV)) failed: %s\n", sndStatOut.mixer, strerror(errno));
+                osLogMsg("setPhysicalInputGainAndLineMode: "
+                         "%s: ioctl(MIXER_WRITE(SOUND_MIXER_RECLEV)) failed: "
+                         "%s\n", sndStatOut.mixer, strerror(errno));
             break;
 
         case useMixerLineMic:
             if (lineMode == AuDeviceLineModeHigh) {
                 if (ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_LINE), &zero) ==
                     -1)
-                    osLogMsg("%s: ioctl(MIXER_WRITE(SOUND_MIXER_LINE)) failed: %s\n", sndStatOut.mixer, strerror(errno));
+                    osLogMsg("setPhysicalInputGainAndLineMode: "
+                             "%s: ioctl(MIXER_WRITE(SOUND_MIXER_LINE)) failed: "
+                             "%s\n", sndStatOut.mixer, strerror(errno));
                 if (ioctl
                     (mixerfd, MIXER_WRITE(SOUND_MIXER_MIC),
                      &inputAttenuation) == -1)
-                    osLogMsg("%s: ioctl(MIXER_WRITE(SOUND_MIXER_MIC)) failed: %s\n", sndStatOut.mixer, strerror(errno));
+                    osLogMsg("setPhysicalInputGainAndLineMode: "
+                             "%s: ioctl(MIXER_WRITE(SOUND_MIXER_MIC)) failed: "
+                             "%s\n", sndStatOut.mixer, strerror(errno));
             } else if (lineMode == AuDeviceLineModeLow) {
                 if (ioctl
                     (mixerfd, MIXER_WRITE(SOUND_MIXER_LINE),
                      &inputAttenuation) == -1)
-                    osLogMsg("%s: ioctl(MIXER_WRITE(SOUND_MIXER_LINE)) failed: %s\n", sndStatOut.mixer, strerror(errno));
+                    osLogMsg("setPhysicalInputGainAndLineMode: "
+                             "%s: ioctl(MIXER_WRITE(SOUND_MIXER_LINE)) failed: "
+                             "%s\n", sndStatOut.mixer, strerror(errno));
                 if (ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_MIC), &zero) ==
                     -1)
-                    osLogMsg("%s: ioctl(MIXER_WRITE(SOUND_MIXER_MIC)) failed: %s\n", sndStatOut.mixer, strerror(errno));
+                    osLogMsg("setPhysicalInputGainAndLineMode: "
+                             "%s: ioctl(MIXER_WRITE(SOUND_MIXER_MIC)) failed: "
+                             "%s\n", sndStatOut.mixer, strerror(errno));
             }
             break;
 
         default:
-            osLogMsg("unknown value %d of recControlMode\n",
-                     recControlMode);
+            osLogMsg("setPhysicalInputGainAndLineMode: "
+                     "unknown value %d of recControlMode\n", recControlMode);
             break;
         }
 
         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));
+            osLogMsg("setPhysicalInputGainAndLineMode: "
+                     "%s: ioctl(MIXER_WRITE(SOUND_MIXER_RECSRC)) failed: %s\n",
+                     sndStatOut.mixer, strerror(errno));
     }
 }
 
 static AuFixedPoint
 getPhysicalInputGain(void)
 {
-    AuInt16 inputGain;
-
-    inputGain = lastPhysicalInputGain;
-
-    return AuFixedPointFromSum(inputGain, 0);
+    return AuFixedPointFromSum(readMixerInputGain(), 0);
 }
 
 static AuInt8
 getPhysicalInputLineMode(void)
 {
-    AuInt8 lineMode;
-
-    lineMode = lastPhysicalInputLineMode;
-
-    return lineMode;
+    return mixerInputModeToNAS(readMixerInputMode());
 }
 
 static void
@@ -1086,9 +1177,6 @@
 
     if (relinquish_device) {
         openDevice(AuTrue);
-        setPhysicalOutputGain(getPhysicalOutputGain());
-        setPhysicalInputGainAndLineMode(getPhysicalInputGain(),
-                                        getPhysicalInputLineMode());
     }
 #ifdef sco
     if (!processFlowEnabled) {
@@ -1519,13 +1607,22 @@
     extramode = O_CREAT;
 #endif
 
-    if ((mixerfd = open(sndStatOut.mixer, O_RDONLY | extramode,
+    if ((mixerfd = open(sndStatOut.mixer, O_RDWR | extramode,
                         0666)) == -1) {
         UNIDENTMSG;
+        osLogMsg("initMixer: could not open mixer device %s: %s\n",
+                 sndStatOut.mixer, strerror(errno));
         return AuFalse;
     }
 
+    if (NasConfig.DoDebug)
+        osLogMsg("initMixer: opened mixer device %s\n",
+                 sndStatOut.mixer, mixerfd);
+
     if (ioctl(mixerfd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
+        osLogMsg("initMixer: %s: ioctl(SOUND_MIXER_READ_DEVMASK) failed: %s\n",
+                 sndStatOut.mixer, strerror(errno));
+        osLogMsg("initMixer: closing mixer device\n");
         close(mixerfd);
         mixerfd = -1;
     } else {
@@ -1538,49 +1635,26 @@
             recControlMode = useMixerLineMic;
         } else {
             recControlMode = useMixerNone;
-            osLogMsg("%s: can't control recording level\n",
+            osLogMsg("initMixer: %s: can't control recording level\n",
                      sndStatOut.mixer);
         }
-        osLogMsg("%s: using recording level control method %d\n",
-                 sndStatOut.mixer, recControlMode);
 
+        if (NasConfig.DoDebug)
+            osLogMsg("initMixer: %s: using recording level control method %d\n",
+                     sndStatOut.mixer, recControlMode);
+
         if (ioctl(mixerfd, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
+            osLogMsg("initMixer: %s: ioctl(SOUND_MIXER_READ_RECMASK) failed: "
+                     "%s\n", sndStatOut.mixer, strerror(errno));
             return AuFalse;
         }
 
-        if (ioctl(mixerfd, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) {
-            UNIDENTMSG;
-            osLogMsg("%s: ioctl(SOUND_MIXER_READ_RECSRC) failed: %s\n",
-                     sndStatOut.mixer, 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) {
             UNIDENTMSG;
-            osLogMsg("%s: ioctl(SOUND_MIXER_READ_STEREODEVS) failed: %s\n",
-                     sndStatOut.mixer, strerror(errno));
+            osLogMsg("initMixer: %s: ioctl(SOUND_MIXER_READ_STEREODEVS) failed:"
+                     " %s\n", sndStatOut.mixer, strerror(errno));
             return AuFalse;
         }
-
-        /* get all sound levels */
-        for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-            if ((1 << i) & devmask) {
-
-                if (ioctl(mixerfd, MIXER_READ(i), &level[i]) == -1) {
-                    UNIDENTMSG;
-                    osLogMsg("%s: ioctl(MIXER_READ(%d)) failed: %s\n",
-                             sndStatOut.mixer, i, strerror(errno));
-                    return AuFalse;
-                }
-            }
-        }
     }
     return AuTrue;
 }
@@ -1620,6 +1694,16 @@
             osLogMsg("Init: will open device exclusivly.\n");
     }
 
+    if (NasConfig.DoKeepMixer) {
+        if (NasConfig.DoDebug) {
+            osLogMsg("Init: will keep mixer device open.\n");
+        }
+    } else {
+        if (NasConfig.DoDebug) {
+            osLogMsg("Init: will close mixer device when closing audio device.\n");
+        }
+    }
+
     if (VOXMixerInit) {
         leave_mixer = AuFalse;
         if (NasConfig.DoDebug)
@@ -1641,14 +1725,14 @@
 
         if (sndStatOut.autoOpen) {
             if (NasConfig.DoDebug)
-                osLogMsg("openDevice OUT %s mode %d\n",
+                osLogMsg("Init: openDevice OUT %s mode %d\n",
                          sndStatOut.device, sndStatOut.howToOpen);
 
             if ((fd = open(sndStatOut.device,
                            sndStatOut.howToOpen | O_SYNC | extramode,
                            0)) == -1) {
                 UNIDENTMSG;
-                osLogMsg("Output open(%s) failed: %s\n",
+                osLogMsg("Init: Output open(%s) failed: %s\n",
                          sndStatOut.device, strerror(errno));
                 return AuFalse;
             }
@@ -1672,7 +1756,7 @@
         if (sndStatIn.autoOpen) {
 
             if (NasConfig.DoDebug)
-                osLogMsg("openDevice(1) IN %s mode %d\n",
+                osLogMsg("Init: openDevice(1) IN %s mode %d\n",
                          sndStatIn.device, sndStatIn.howToOpen);
 
             if ((fd =
@@ -1682,7 +1766,7 @@
             else {
                 sndStatIn.fd = sndStatOut.fd;
                 share_in_out = AuTrue;
-                osLogMsg("Input open(%s) failed: %s, using output device\n", sndStatIn.device, strerror(errno));
+                osLogMsg("Init: Input open(%s) failed: %s, using output device\n", sndStatIn.device, strerror(errno));
             }
         }
 
@@ -1691,9 +1775,16 @@
             setupSoundcard(&sndStatIn);
 
         if (!sndStatOut.isPCSpeaker) {
-            if (initMixer() == AuFalse && mixerfd != -1) {
-                close(mixerfd);
-                mixerfd = -1;
+            if (initMixer() == AuFalse) {
+                osLogMsg("Init: initMixer failed\n");
+                if (mixerfd != -1) {
+                    osLogMsg("Init: closing mixer devcie\n");
+                    close(mixerfd);
+                    mixerfd = -1;
+                }
+            } else {
+                if (NasConfig.DoDebug)
+                    osLogMsg("Init: initMixer was successful\n");
             }
         }
     }
Index: server/dia/lex.l
===================================================================
--- server/dia/lex.l	(revision 168)
+++ server/dia/lex.l	(working copy)
@@ -17,6 +17,7 @@
 [Dd][Ee][Bb][Uu][Gg]                    { return CDEBUG; }
 [Vv][Ee][Rr][Bb][Oo][Ss][Ee]            { return VERBOSE; }
 [Rr][Ee][Ll][Ee][Aa][Ss][Ee][Dd][Ee][Vv][Ii][Cc][Ee]   { return RELEASEDEVICE;}
+[Kk][Ee][Ee][Pp][Mm][Ii][Xx][Ee][Rr]    { return KEEPMIXER; }
 [Ii][Nn][Pp][Uu][Tt][Ss][Ee][Cc][Tt][Ii][Oo][Nn] { return INPUTSECTION; }
 [Oo][Uu][Tt][Pp][Uu][Tt][Ss][Ee][Cc][Tt][Ii][Oo][Nn] { return OUTPUTSECTION; }
 [Ee][Nn][Dd]                            { return ENDSECTION; }
Index: server/dia/gram.y
===================================================================
--- server/dia/gram.y	(revision 168)
+++ server/dia/gram.y	(working copy)
@@ -29,7 +29,7 @@
 %token <num> MINFRAGS MAXRATE MINRATE NUMCHANS MIXER DEVICE NUMBER 
 %token <num> CDEBUG VERBOSE
 %token <num> READWRITE FORCERATE AUTOOPEN GAIN GAINSCALE
-%token <num> RELEASEDEVICE OUTDEVTYPE MIXERINIT
+%token <num> RELEASEDEVICE KEEPMIXER OUTDEVTYPE MIXERINIT
 %token <ptr> STRING 
 
 %type <ptr> string
@@ -58,8 +58,19 @@
                                 /* error - default to no */
                               NasConfig.DoDeviceRelease = FALSE;
                           } else 
-                            NasConfig.DoDeviceRelease = j; 
+                              NasConfig.DoDeviceRelease = j; 
                         }
+                | KEEPMIXER string
+                        {
+                          int j;
+
+                          j = parsebool($2);
+                          if (j == -1) {
+                                /* error - default to yes */
+                              NasConfig.DoKeepMixer = TRUE;
+                          } else 
+                              NasConfig.DoKeepMixer = j; 
+                        }
                 | MIXERINIT string
                         { ddaSetConfig(MIXERINIT, (void *)parsebool($2)); }  
                 | OUTDEVTYPE string
Index: server/dia/nasconf.c
===================================================================
--- server/dia/nasconf.c	(revision 168)
+++ server/dia/nasconf.c	(working copy)
@@ -21,6 +21,7 @@
     NasConfig.DoDebug = FALSE;
     NasConfig.DoVerbose = FALSE;
     NasConfig.DoDeviceRelease = TRUE;
+    NasConfig.DoKeepMixer = TRUE;
     NasConfig.DoDaemon = FALSE;
     NasConfig.LocalOnly = FALSE;        /* allow only local connections */
     NasConfig.AllowAny = FALSE; /* allow any host to connect w/o


More information about the Nas mailing list