[nas] [PATCH] use the mixer specified in the input section
Erik Auerswald
auerswal at unix-ag.uni-kl.de
Tue Aug 15 21:36:04 MDT 2006
Hi,
the attached patch adds support for a different mixer for the input device
to the voxware server. Without this patch the mixer device specified in
the input section of the config file is not used.
To use the same mixer for input and output just specify the same device
in the input- and output-section of the config file. The empty string ""
can be used to specify no mixer device for the input- or output-section.
This is documented in the nasd.conf man page.
The outputsection keyword is added to the nasd.conf man page by the patch.
While testing this I found a bug in the support of two devices:
If two devices are used and the sample rate of the input device can be
changed the wrong sample size is set by openDevice(). I did not notice
this when testing the digital output because the digital output has
a fixed sample size. This bug is fixed by the patch as well.
The patch removes the unused "stereodevs" variable, too.
I've tested the patch with just one device for input and output, two
devices with seperate mixers, two devices with just one mixer, and two
devices with no mixer for the output, but a mixer for the input device.
Erik
--
It gave some error message, or something.
-- Agustín Cernuda del Río
-------------- next part --------------
Index: server/nasd.conf.man
===================================================================
--- server/nasd.conf.man (revision 178)
+++ server/nasd.conf.man (working copy)
@@ -17,7 +17,7 @@
deals with global options, some of which just turn on verbose messages
when parsing the config file, and setting debug messages on. The
remaining two sections will, if present, adjust various parameters of
-the input and output devices, for those server that undersand them.
+the input and output devices, for those servers that understand them.
.PP
.B verbose
Sets a flag telling the server to report what it's trying to do with each
@@ -55,6 +55,10 @@
(headphone/speakers) or "INT" for the internal output device (internal
speaker). Defaults to external.
.PP
+.B outputsection
+Marks the beginning of the output section, which allows various parameters
+of the output device to be set up.
+.PP
.B inputsection
Marks the beginning of the input section, which allows various parameters
of the input device to be set up.
@@ -67,6 +71,8 @@
.PP
.B mixer "mixername"
Specifies what mixer device is used. An example is \fBmixer "/dev/mixer"\fR.
+If \fBmixername\fR is set to the empty string \fB""\fR no mixer is used in
+this section.
.PP
.B gain number
Specifies the default volume (0-100). The default is 50.
Index: server/dda/voxware/auvoxware.c
===================================================================
--- server/dda/voxware/auvoxware.c (revision 178)
+++ server/dda/voxware/auvoxware.c (working copy)
@@ -224,12 +224,13 @@
static AuBool relinquish_device = 0;
static AuBool leave_mixer = 0;
static AuBool share_in_out = 0;
+static AuBool share_mixer = 0;
static int recControlMode = 0; /* how to control recording level */
-static int mixerfd = -1; /* The mixer device */
+static int outmixerfd = -1; /* The output device mixer device */
+static int inmixerfd = -1; /* The input device mixer device */
static int devmask = 0; /* Bitmask for supported mixer devices */
static int recmask = 0; /* Supported recording sources */
-static int stereodevs = 0; /* Channels supporting stereo */
int VOXMixerInit = TRUE; /* overridden by nasd.conf */
int VOXReInitMixer = FALSE; /* overridden by nasd.conf */
@@ -355,11 +356,11 @@
{
int pcm_level = 0;
- if (mixerfd != -1) {
- if (ioctl(mixerfd, MIXER_READ(SOUND_MIXER_PCM), &pcm_level) == -1) {
+ if (outmixerfd != -1) {
+ if (ioctl(outmixerfd, 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));
+ sndStatOut.mixer, outmixerfd, strerror(errno));
return sndStatOut.gain;
}
} else {
@@ -379,11 +380,11 @@
{
int input_mode = 0;
- if (mixerfd != -1) {
- if (ioctl(mixerfd, MIXER_READ(SOUND_MIXER_RECSRC), &input_mode) == -1) {
+ if (inmixerfd != -1) {
+ if (ioctl(inmixerfd,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));
+ "%s\n", sndStatIn.mixer, inmixerfd, strerror(errno));
return 1<<SOUND_MIXER_LINE;
}
if (!(input_mode & (SOUND_MASK_MIC | SOUND_MIXER_LINE))) {
@@ -404,43 +405,43 @@
recsrc = readMixerInputMode();
- if (mixerfd != -1) {
+ if (inmixerfd != -1) {
switch (recControlMode) {
case useMixerIGain:
- if (ioctl(mixerfd, MIXER_READ(SOUND_MIXER_IGAIN),&in_level) == -1) {
+ if (ioctl(inmixerfd,MIXER_READ(SOUND_MIXER_IGAIN),&in_level) == -1){
osLogMsg("readMixerInputGain: %s: "
"ioctl(MIXER_READ(SOUND_MIXER_IGAIN)) failed: %s\n",
- sndStatOut.mixer, strerror(errno));
+ sndStatIn.mixer, strerror(errno));
return sndStatIn.gain;
}
break;
case useMixerRecLev:
- if (ioctl(mixerfd, MIXER_READ(SOUND_MIXER_RECLEV),&in_level) == -1){
+ if (ioctl(inmixerfd,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));
+ " %s\n", sndStatIn.mixer, inmixerfd, strerror(errno));
return sndStatIn.gain;
}
break;
case useMixerLineMic:
if (recsrc & SOUND_MASK_LINE) {
- if (ioctl(mixerfd, MIXER_READ(SOUND_MIXER_LINE), &in_level)
+ if (ioctl(inmixerfd, 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));
+ sndStatIn.mixer, inmixerfd, strerror(errno));
return sndStatIn.gain;
}
} else if (recsrc & SOUND_MASK_MIC) {
- if (ioctl(mixerfd, MIXER_READ(SOUND_MIXER_MIC), &in_level)
+ if (ioctl(inmixerfd, 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));
+ sndStatIn.mixer, inmixerfd, strerror(errno));
return sndStatIn.gain;
}
} else {
@@ -752,11 +753,15 @@
&(sndStatOut.curSampleRate));
if (sndStatOut.forceRate)
sndStatOut.curSampleRate = rate;
+ if (NasConfig.DoDebug)
+ osLogMsg("setSampleRate(): set output sample rate to %d\n",
+ sndStatOut.curSampleRate);
}
if ((sndStatIn.fd == sndStatOut.fd) && (sndStatIn.fd != -1)) {
sndStatIn = sndStatOut;
- osLogMsg("setSampleRate(): setting sndStatIn = sndStatOut\n");
+ if (NasConfig.DoDebug)
+ osLogMsg("setSampleRate(): setting sndStatIn = sndStatOut\n");
}
else if (sndStatIn.curSampleRate != rate) {
sndStatIn.curSampleRate = rate;
@@ -768,6 +773,9 @@
ioctl(sndStatIn.fd, SNDCTL_DSP_SPEED, &(sndStatIn.curSampleRate));
if (sndStatIn.forceRate)
sndStatIn.curSampleRate = rate;
+ if (NasConfig.DoDebug)
+ osLogMsg("setSampleRate(): set input sample rate to %d\n",
+ sndStatIn.curSampleRate);
}
#if defined(AUDIO_DRAIN)
if (sndStatOut.isPCSpeaker)
@@ -790,6 +798,7 @@
{
unsigned int extramode = 0;
int retries;
+ int curSampleRate;
setTimer(0); /* no timers here */
#if defined(__CYGWIN__) /* we want the file to be created if necc under
@@ -801,7 +810,15 @@
osLogMsg("openDevice\n");
}
+ curSampleRate = sndStatOut.curSampleRate;
if (NasConfig.DoDebug) {
+ osLogMsg("openDevice: current sample rate = %d\n", curSampleRate);
+ if (sndStatOut.curSampleRate != sndStatIn.curSampleRate)
+ osLogMsg("openDevice: sndStatOut.curSampleRate !="
+ " sndStatIn.curSampleRate\n");
+ }
+
+ if (NasConfig.DoDebug) {
osLogMsg("openDevice OUT %s mode %d\n",
sndStatOut.device, sndStatOut.howToOpen);
}
@@ -852,26 +869,58 @@
}
}
- if (mixerfd == -1) {
- while ((mixerfd = open(sndStatOut.mixer, O_RDWR | extramode,
- 0666)) == -1 && wait) {
- if ((errno == EAGAIN) || (errno == EBUSY)) {
- osLogMsg("openDevice: waiting on mixer device %s\n",
- sndStatOut.mixer);
- sleep(1);
- } else {
- osLogMsg("openDevice: could not open mixer device %s: %s\n",
- sndStatOut.mixer, strerror(errno));
- break;
+ if (outmixerfd == -1) {
+ if (sndStatOut.mixer[0] == '\0') {
+ osLogMsg("openDevice: no output mixer device specified\n");
+ } else {
+ while ((outmixerfd = open(sndStatOut.mixer, O_RDWR | extramode,
+ 0666)) == -1 && wait) {
+ if ((errno == EAGAIN) || (errno == EBUSY)) {
+ osLogMsg("openDevice: waiting on mixer device %s\n",
+ sndStatOut.mixer);
+ sleep(1);
+ } else {
+ osLogMsg("openDevice: could not open output mixer device"
+ " %s: %s\n", sndStatOut.mixer, strerror(errno));
+ break;
+ }
}
+ if (outmixerfd != -1)
+ osLogMsg("openDevice: opened mixer %s\n", sndStatOut.mixer);
}
- if (mixerfd != -1)
- osLogMsg("openDevice: opened mixer %s\n", sndStatOut.mixer);
} else {
if (NasConfig.DoDebug) {
- osLogMsg("openDevice: mixer device already open\n");
+ osLogMsg("openDevice: output mixer device already open\n");
}
}
+
+ if ((inmixerfd == -1) && !share_mixer) {
+ if (sndStatIn.mixer[0] != '\0') {
+ osLogMsg("openDevice: no input mixer device specified\n");
+ } else {
+ while ((inmixerfd = open(sndStatIn.mixer, O_RDWR | extramode,
+ 0666)) == -1 && wait) {
+ if ((errno == EAGAIN) || (errno == EBUSY)) {
+ osLogMsg("openDevice: waiting on mixer device %s\n",
+ sndStatIn.mixer);
+ sleep(1);
+ } else {
+ osLogMsg("openDevice: could not open input mixer device"
+ " %s: %s\n", sndStatIn.mixer, strerror(errno));
+ break;
+ }
+ }
+ if (inmixerfd != -1)
+ osLogMsg("openDevice: opened mixer %s\n", sndStatIn.mixer);
+ }
+ } else {
+ if (share_mixer) {
+ inmixerfd = outmixerfd;
+ }
+ if (NasConfig.DoDebug) {
+ osLogMsg("openDevice: input mixer device already open\n");
+ }
+ }
#endif
ioctl(sndStatOut.fd, SNDCTL_DSP_SYNC, NULL);
@@ -888,7 +937,7 @@
if (sndStatOut.fd != sndStatIn.fd) {
ioctl(sndStatIn.fd, SNDCTL_DSP_SYNC, NULL);
#ifndef sco
- rate = sndStatOut.curSampleRate;
+ rate = sndStatIn.curSampleRate;
ioctl(sndStatIn.fd, SNDCTL_DSP_SPEED,
&sndStatIn.curSampleRate);
if (sndStatIn.forceRate)
@@ -897,7 +946,7 @@
}
}
- setSampleRate(sndStatIn.curSampleRate);
+ setSampleRate(curSampleRate);
return AuTrue;
}
@@ -949,21 +998,37 @@
if (NasConfig.DoKeepMixer) {
if (NasConfig.DoDebug) {
- osLogMsg("closeDevice: leaving mixerdevice open\n");
+ osLogMsg("closeDevice: leaving mixer device(s) open\n");
}
- } else if (-1 == mixerfd) {
- if (NasConfig.DoDebug) {
- osLogMsg("closeDevice: mixerdevice already closed\n");
- }
} else {
- while (close(mixerfd)) {
- osLogMsg("closeDevice: waiting on mixer device\n");
- sleep(1);
+ if (-1 == outmixerfd) {
+ if (NasConfig.DoDebug) {
+ osLogMsg("closeDevice: output mixer device already closed\n");
+ }
+ } else {
+ while (close(outmixerfd)) {
+ osLogMsg("closeDevice: waiting on output mixer device\n");
+ sleep(1);
+ }
+ if (NasConfig.DoDebug) {
+ osLogMsg("closeDevice: closed output mixer device\n");
+ }
+ outmixerfd = -1;
}
- if (NasConfig.DoDebug) {
- osLogMsg("closeDevice: closed mixer device\n");
+ if (-1 == inmixerfd) {
+ if (NasConfig.DoDebug) {
+ osLogMsg("closeDevice: input mixer device already closed\n");
+ }
+ } else {
+ while (!share_mixer && close(inmixerfd)) {
+ osLogMsg("closeDevice: waiting on input mixer device\n");
+ sleep(1);
+ }
+ if (NasConfig.DoDebug) {
+ osLogMsg("closeDevice: closed input mixer device\n");
+ }
+ inmixerfd = -1;
}
- mixerfd = -1;
}
sndStatIn.fd = -1;
@@ -1080,8 +1145,8 @@
}
gusvolume = g | (g << 8);
- if (mixerfd != -1)
- if (ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_PCM), &gusvolume) == -1)
+ if (outmixerfd != -1)
+ if (ioctl(outmixerfd, MIXER_WRITE(SOUND_MIXER_PCM), &gusvolume) == -1)
osLogMsg("setPhysicalOutputGain: "
"%s: ioctl(MIXER_WRITE(SOUND_MIXER_PCM)) failed: %s\n",
sndStatOut.mixer, strerror(errno));
@@ -1123,54 +1188,54 @@
inputAttenuation = inputAttenuation << 8 | inputAttenuation;
- if (mixerfd != -1) {
+ if (inmixerfd != -1) {
switch (recControlMode) {
case useMixerNone:
break;
case useMixerIGain:
if (ioctl
- (mixerfd, MIXER_WRITE(SOUND_MIXER_IGAIN),
+ (inmixerfd, MIXER_WRITE(SOUND_MIXER_IGAIN),
&inputAttenuation) == -1)
osLogMsg("setPhysicalInputGainAndLineMode: "
"%s: ioctl(MIXER_WRITE(SOUND_MIXER_IGAIN)) failed: "
- "%s\n", sndStatOut.mixer, strerror(errno));
+ "%s\n", sndStatIn.mixer, strerror(errno));
break;
case useMixerRecLev:
if (ioctl
- (mixerfd, MIXER_WRITE(SOUND_MIXER_RECLEV),
+ (inmixerfd, MIXER_WRITE(SOUND_MIXER_RECLEV),
&inputAttenuation) == -1)
osLogMsg("setPhysicalInputGainAndLineMode: "
"%s: ioctl(MIXER_WRITE(SOUND_MIXER_RECLEV)) failed: "
- "%s\n", sndStatOut.mixer, strerror(errno));
+ "%s\n", sndStatIn.mixer, strerror(errno));
break;
case useMixerLineMic:
if (lineMode == AuDeviceLineModeHigh) {
- if (ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_LINE), &zero) ==
+ if (ioctl(inmixerfd, MIXER_WRITE(SOUND_MIXER_LINE), &zero) ==
-1)
osLogMsg("setPhysicalInputGainAndLineMode: "
"%s: ioctl(MIXER_WRITE(SOUND_MIXER_LINE)) failed: "
- "%s\n", sndStatOut.mixer, strerror(errno));
+ "%s\n", sndStatIn.mixer, strerror(errno));
if (ioctl
- (mixerfd, MIXER_WRITE(SOUND_MIXER_MIC),
+ (inmixerfd, MIXER_WRITE(SOUND_MIXER_MIC),
&inputAttenuation) == -1)
osLogMsg("setPhysicalInputGainAndLineMode: "
"%s: ioctl(MIXER_WRITE(SOUND_MIXER_MIC)) failed: "
- "%s\n", sndStatOut.mixer, strerror(errno));
+ "%s\n", sndStatIn.mixer, strerror(errno));
} else if (lineMode == AuDeviceLineModeLow) {
if (ioctl
- (mixerfd, MIXER_WRITE(SOUND_MIXER_LINE),
+ (inmixerfd, MIXER_WRITE(SOUND_MIXER_LINE),
&inputAttenuation) == -1)
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) ==
+ "%s\n", sndStatIn.mixer, strerror(errno));
+ if (ioctl(inmixerfd, MIXER_WRITE(SOUND_MIXER_MIC), &zero) ==
-1)
osLogMsg("setPhysicalInputGainAndLineMode: "
"%s: ioctl(MIXER_WRITE(SOUND_MIXER_MIC)) failed: "
- "%s\n", sndStatOut.mixer, strerror(errno));
+ "%s\n", sndStatIn.mixer, strerror(errno));
}
break;
@@ -1180,10 +1245,10 @@
break;
}
- if (ioctl(mixerfd, MIXER_WRITE(SOUND_MIXER_RECSRC), &recsrc) == -1)
+ if (ioctl(inmixerfd, MIXER_WRITE(SOUND_MIXER_RECSRC), &recsrc) == -1)
osLogMsg("setPhysicalInputGainAndLineMode: "
"%s: ioctl(MIXER_WRITE(SOUND_MIXER_RECSRC)) failed: %s\n",
- sndStatOut.mixer, strerror(errno));
+ sndStatIn.mixer, strerror(errno));
}
}
@@ -1643,24 +1708,55 @@
extramode = O_CREAT;
#endif
- 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;
+ /* open output mixer device */
+ if (sndStatOut.mixer[0] != '\0') {
+ if ((outmixerfd=open(sndStatOut.mixer, O_RDWR|extramode, 0666)) == -1) {
+ UNIDENTMSG;
+ osLogMsg("initMixer: could not open output mixer device %s: %s\n",
+ sndStatOut.mixer, strerror(errno));
+ return AuFalse;
+ }
+ if (NasConfig.DoDebug)
+ osLogMsg("initMixer: opened output mixer device %s\n",
+ sndStatOut.mixer, outmixerfd);
+ } else {
+ if (NasConfig.DoDebug)
+ osLogMsg("initMixer: no output mixer device specified\n");
}
- if (NasConfig.DoDebug)
- osLogMsg("initMixer: opened mixer device %s\n",
- sndStatOut.mixer, mixerfd);
+ /* open input mixer device */
+ if (sndStatIn.mixer[0] != '\0') {
+ if (strcmp(sndStatIn.mixer, sndStatOut.mixer) != 0) {
+ if ((inmixerfd = open(sndStatIn.mixer, O_RDWR | extramode,
+ 0666)) == -1) {
+ UNIDENTMSG;
+ osLogMsg("initMixer: could not open input mixer device %s: %s\n"
+ , sndStatIn.mixer, strerror(errno));
+ return AuFalse;
+ }
+ } else {
+ share_mixer = AuTrue;
+ inmixerfd = outmixerfd;
+ if (NasConfig.DoDebug)
+ osLogMsg("initMixer: using the same mixer device for"
+ " in- and output\n");
+ }
+ if (NasConfig.DoDebug)
+ osLogMsg("initMixer: opened input mixer device %s\n",
+ sndStatIn.mixer, inmixerfd);
+ } else {
+ if (NasConfig.DoDebug)
+ osLogMsg("initMixer: no input mixer device specified\n");
+ return AuTrue;
+ }
- if (ioctl(mixerfd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
+ /* get recording devices of input mixer */
+ if (ioctl(inmixerfd, 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;
+ sndStatIn.mixer, strerror(errno));
+ osLogMsg("initMixer: closing input mixer device\n");
+ close(inmixerfd);
+ inmixerfd = -1;
} else {
if (devmask & (1 << SOUND_MIXER_IGAIN)) {
recControlMode = useMixerIGain;
@@ -1672,25 +1768,18 @@
} else {
recControlMode = useMixerNone;
osLogMsg("initMixer: %s: can't control recording level\n",
- sndStatOut.mixer);
+ sndStatIn.mixer);
}
if (NasConfig.DoDebug)
osLogMsg("initMixer: %s: using recording level control method %d\n",
- sndStatOut.mixer, recControlMode);
+ sndStatIn.mixer, recControlMode);
- if (ioctl(mixerfd, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
+ if (ioctl(inmixerfd, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
osLogMsg("initMixer: %s: ioctl(SOUND_MIXER_READ_RECMASK) failed: "
- "%s\n", sndStatOut.mixer, strerror(errno));
+ "%s\n", sndStatIn.mixer, strerror(errno));
return AuFalse;
}
-
- if (ioctl(mixerfd, SOUND_MIXER_READ_STEREODEVS, &stereodevs) == -1) {
- UNIDENTMSG;
- osLogMsg("initMixer: %s: ioctl(SOUND_MIXER_READ_STEREODEVS) failed:"
- " %s\n", sndStatOut.mixer, strerror(errno));
- return AuFalse;
- }
}
return AuTrue;
}
@@ -1813,11 +1902,16 @@
if (!sndStatOut.isPCSpeaker) {
if (initMixer() == AuFalse) {
osLogMsg("Init: initMixer failed\n");
- if (mixerfd != -1) {
- osLogMsg("Init: closing mixer devcie\n");
- close(mixerfd);
- mixerfd = -1;
+ if (outmixerfd != -1) {
+ osLogMsg("Init: closing output mixer device\n");
+ close(outmixerfd);
+ outmixerfd = -1;
}
+ if (inmixerfd != -1) {
+ osLogMsg("Init: closing input mixer device\n");
+ close(inmixerfd);
+ inmixerfd = -1;
+ }
} else {
if (NasConfig.DoDebug)
osLogMsg("Init: initMixer was successful\n");
More information about the Nas
mailing list