[nas] [patch] Allow mixeropen to fail
Tobias Diedrich
ranma at tdiedrich.de
Sun Oct 17 04:14:10 MDT 2004
Currently an outputdevice will not work without a mixer device, except
for the specially handled devices /dev/pcaudio and /dev/pcdsp.
For those the config parses sets "isPCSpeaker" to 1, which in turn forces
auvoxware.c to skip mixer initialisation (It also forces the settings
"rate = minrate = maxrate = 8000", nostereo and 8bit wordsize).
This patch allows the mixer initialisation to fail.
With this patch "aoss nasd" works, without it would fail (aoss is the
alsa oss wrapper script, which simply preloads libaoss.so, a wrapper
library similar to libaudiooss).
Combining this with the alsa dmix feature should allow nas to coexist
with other daemons like artsd.
See also
http://alsa.opensrc.org/index.php?page=Dmix+Kde+-+arts%2C+ESD+and+SDL+quick+and+dirty+HOWTO
Example /etc/asound.conf:
pcm.mix {
type dmix
ipc_key 1024
ipc_perm 0666 # I'd love to use perm 0660 and gid audio,
# but there's no gid-support (FIXME?)
slave {
pcm "hw:0,0"
period_time 0
period_size 1024
buffer_size 8192
rate 44100
format "S16_LE"
#periods 128
}
bindings {
0 0 # from 0 => to 0
1 1 # from 1 => to 1
}
}
pcm.!default {
type plug
slave.pcm "mix"
}
pcm.dsp0 pcm.default
#end of /etc/asound.conf
--- nas-1.6e-vanilla/server/dda/voxware/auvoxware.c 2004-09-11 21:23:33.000000000 +0200
+++ nas-1.6e-patched/server/dda/voxware/auvoxware.c 2004-10-17 03:52:01.588978408 +0200
@@ -1422,6 +1422,83 @@
}
#endif /* sco */
+static AuBool initMixer()
+{
+ unsigned int extramode = 0;
+ AuInt32 i;
+
+#if defined(__CYGWIN__) /* we want the file to be created if necc under
+ windows */
+ extramode = O_CREAT;
+#endif
+
+ if ((mixerfd = open(sndStatOut.mixer, O_RDONLY|extramode,
+ 0666)) == -1) {
+ UNIDENTMSG;
+ return AuFalse;
+ }
+
+ if (ioctl(mixerfd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
+ close(mixerfd);
+ mixerfd = -1;
+ } else {
+ if (ioctl(mixerfd, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
+ return AuFalse;
+ }
+
+ {
+ /* Enable all used recording sources ( mic & line ) and
+ * control which is active via level setting later. There
+ * should be a better way to do this!
+ */
+ if (!leave_mixer)
+ {
+ int mask = SOUND_MASK_MIC | SOUND_MASK_LINE; /* enable these */
+ mask &= recmask; /* if supported */
+ if (ioctl(mixerfd, SOUND_MIXER_WRITE_RECSRC, &mask) == -1)
+ {
+ osLogMsg("%s: ioctl(SOUND_MIXER_WRITE_RECSRC) failed: %s\n",
+ sndStatOut.mixer,
+ strerror(errno));
+ /* return AuFalse; - no need to exit here..*/
+ }
+ }
+ }
+
+ 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 */
+ }
+
+ if (ioctl(mixerfd, SOUND_MIXER_READ_STEREODEVS, &stereodevs) == -1) {
+ UNIDENTMSG;
+ osLogMsg("%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;
+ }
+ }
+ }
+ }
+}
+
AuBool AuInitPhysicalDevices()
{
static AuBool AL_initialized = AuFalse;
@@ -1539,71 +1616,10 @@
setupSoundcard(&sndStatIn);
if (!sndStatOut.isPCSpeaker) {
- if ((mixerfd = open(sndStatOut.mixer, O_RDONLY|extramode,
- 0666)) == -1) {
- UNIDENTMSG;
- return AuFalse;
- }
-
- if (ioctl(mixerfd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
+ if (initMixer() == AuFalse &&
+ mixerfd != -1) {
close(mixerfd);
- mixerfd = -1;
- } else {
- if (ioctl(mixerfd, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
- return AuFalse;
- }
-
- {
- /* Enable all used recording sources ( mic & line ) and
- * control which is active via level setting later. There
- * should be a better way to do this!
- */
- if (!leave_mixer)
- {
- int mask = SOUND_MASK_MIC | SOUND_MASK_LINE; /* enable these */
- mask &= recmask; /* if supported */
- if (ioctl(mixerfd, SOUND_MIXER_WRITE_RECSRC, &mask) == -1)
- {
- osLogMsg("%s: ioctl(SOUND_MIXER_WRITE_RECSRC) failed: %s\n",
- sndStatOut.mixer,
- strerror(errno));
- /* return AuFalse; - no need to exit here..*/
- }
- }
- }
-
- 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 */
- }
-
- if (ioctl(mixerfd, SOUND_MIXER_READ_STEREODEVS, &stereodevs) == -1) {
- UNIDENTMSG;
- osLogMsg("%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;
- }
- }
- }
-
+ mixerfd = -1;
}
}
}
--
Tobias _.---._
PGP: http://9ac7e0bc.uguu.de .--"/ _ at _ \`"--.
np: Mutsu Enmei Ryuu Gaiden Shura no Toki Ongaku Hen - Mutsu E( > ~ < )
.-',___.'-. zi.
More information about the Nas
mailing list