libtriple: add support for alternate sound devices to cAudio

This allows to use different audio devices (USB Audio for example)
with internet radio and audioplayer.


Origin commit data
------------------
Branch: master
Commit: 124733ce12
Author: Stefan Seyfried <seife@tuxbox-git.slipkontur.de>
Date: 2012-01-08 (Sun, 08 Jan 2012)



------------------
This commit was generated by Migit
This commit is contained in:
Stefan Seyfried
2012-01-08 00:34:52 +01:00
parent 2e68df0142
commit 21b2b8bcf1
2 changed files with 98 additions and 5 deletions

View File

@@ -20,6 +20,7 @@ cAudio::cAudio(void *, void *, void *)
{ {
fd = -1; fd = -1;
clipfd = -1; clipfd = -1;
mixer_fd = -1;
openDevice(); openDevice();
Muted = false; Muted = false;
} }
@@ -49,6 +50,9 @@ void cAudio::closeDevice(void)
if (clipfd >= 0) if (clipfd >= 0)
close(clipfd); close(clipfd);
clipfd = -1; clipfd = -1;
if (mixer_fd >= 0)
close(mixer_fd);
mixer_fd = -1;
} }
int cAudio::do_mute(bool enable, bool remember) int cAudio::do_mute(bool enable, bool remember)
@@ -60,6 +64,11 @@ int cAudio::do_mute(bool enable, bool remember)
ret = ioctl(fd, MPEG_AUD_SET_MUTE, enable); ret = ioctl(fd, MPEG_AUD_SET_MUTE, enable);
if (ret < 0) if (ret < 0)
lt_info("%s(%d) failed (%m)\n", __FUNCTION__, (int)enable); lt_info("%s(%d) failed (%m)\n", __FUNCTION__, (int)enable);
/* are we using alternative DSP / mixer? */
if (clipfd != -1 || mixer_fd != -1)
setVolume(volume,volume); /* considers "Muted" variable, "remember"
is basically always true in this context */
return ret; return ret;
} }
@@ -80,7 +89,18 @@ int cAudio::setVolume(unsigned int left, unsigned int right)
int ret; int ret;
int vl = map_volume(left); int vl = map_volume(left);
int vr = map_volume(right); int vr = map_volume(right);
int v = map_volume((left + right) / 2); volume = (left + right) / 2;
int v = map_volume(volume);
if (clipfd != -1 && mixer_fd != -1) {
int tmp = 0;
/* not sure if left / right is correct here, but it is always the same anyways ;-) */
if (! Muted)
tmp = left << 8 | right;
ret = ioctl(mixer_fd, MIXER_WRITE(mixer_num), &tmp);
if (ret == -1)
lt_info("%s: MIXER_WRITE(%d),%04x: %m\n", __func__, mixer_num, tmp);
return ret;
}
// if (settings.volume_type == CControld::TYPE_OST || forcetype == (int)CControld::TYPE_OST) // if (settings.volume_type == CControld::TYPE_OST || forcetype == (int)CControld::TYPE_OST)
{ {
AUDVOL vol; AUDVOL vol;
@@ -173,17 +193,38 @@ int cAudio::setChannel(int channel)
int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian) int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
{ {
int fmt; int fmt;
unsigned int devmask, stereo, usable;
const char *dsp_dev = getenv("DSP_DEVICE");
const char *mix_dev = getenv("MIX_DEVICE");
lt_debug("%s ch %d srate %d bits %d le %d\n", __FUNCTION__, ch, srate, bits, little_endian); lt_debug("%s ch %d srate %d bits %d le %d\n", __FUNCTION__, ch, srate, bits, little_endian);
if (clipfd >= 0) { if (clipfd >= 0) {
lt_info("%s: clipfd already opened (%d)\n", __FUNCTION__, clipfd); lt_info("%s: clipfd already opened (%d)\n", __FUNCTION__, clipfd);
return -1; return -1;
} }
/* the dsp driver seems to work only on the second open(). really. */ mixer_num = -1;
clipfd = open("/dev/sound/dsp", O_WRONLY); mixer_fd = -1;
/* a different DSP device can be given with DSP_DEVICE and MIX_DEVICE
* if this device cannot be opened, we fall back to the internal TD OSS device
* Example:
* modprobe ohci-hcd
* modprobe audio
* export DSP_DEVICE=/dev/sound/dsp1
* export MIX_DEVICE=/dev/sound/mixer1
* neutrino
*/
if ((!dsp_dev) || (access(dsp_dev, W_OK))) {
if (dsp_dev)
lt_info("%s: DSP_DEVICE is set (%s) but cannot be opened,"
" fall back to /dev/sound/dsp\n", __func__, dsp_dev);
dsp_dev = "/dev/sound/dsp";
}
lt_info("%s: dsp_dev %s mix_dev %s\n", __func__, dsp_dev, mix_dev); /* NULL mix_dev is ok */
/* the tdoss dsp driver seems to work only on the second open(). really. */
clipfd = open(dsp_dev, O_WRONLY);
close(clipfd); close(clipfd);
clipfd = open("/dev/sound/dsp", O_WRONLY); clipfd = open(dsp_dev, O_WRONLY);
if (clipfd < 0) { if (clipfd < 0) {
lt_info("%s open /dev/sound/dsp: %m\n", __FUNCTION__); lt_info("%s open %s: %m\n", dsp_dev, __FUNCTION__);
return -1; return -1;
} }
fcntl(clipfd, F_SETFD, FD_CLOEXEC); fcntl(clipfd, F_SETFD, FD_CLOEXEC);
@@ -201,6 +242,52 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
if (ioctl(clipfd, SNDCTL_DSP_RESET)) if (ioctl(clipfd, SNDCTL_DSP_RESET))
perror("SNDCTL_DSP_RESET"); perror("SNDCTL_DSP_RESET");
if (!mix_dev)
return 0;
mixer_fd = open(mix_dev, O_RDWR);
if (mixer_fd < 0) {
lt_info("%s: open mixer %s failed (%m)\n", __func__, mix_dev);
/* not a real error */
return 0;
}
if (ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
lt_info("%s: SOUND_MIXER_READ_DEVMASK %m\n", __func__);
devmask = 0;
}
if (ioctl(mixer_fd, SOUND_MIXER_READ_STEREODEVS, &stereo) == -1) {
lt_info("%s: SOUND_MIXER_READ_STEREODEVS %m\n", __func__);
stereo = 0;
}
usable = devmask & stereo;
if (usable == 0) {
lt_info("%s: devmask: %08x stereo: %08x, no usable dev :-(\n",
__func__, devmask, stereo);
close(mixer_fd);
mixer_fd = -1;
return 0; /* TODO: should we treat this as error? */
}
/* __builtin_popcount needs GCC, it counts the set bits... */
if (__builtin_popcount (usable) != 1) {
/* TODO: this code is not yet tested as I have only single-mixer devices... */
lt_info("%s: more than one mixer control: devmask %08x stereo %08x\n"
"%s: querying MIX_NUMBER environment variable...\n",
__func__, devmask, stereo, __func__);
const char *tmp = getenv("MIX_NUMBER");
if (tmp)
mixer_num = atoi(tmp);
lt_info("%s: mixer_num is %d -> device %08x\n",
__func__, (mixer_num >= 0) ? (1 << mixer_num) : 0);
/* no error checking, you'd better know what you are doing... */
} else {
mixer_num = 0;
while (!(usable & 0x01)) {
mixer_num++;
usable >>= 1;
}
}
setVolume(volume, volume);
return 0; return 0;
}; };
@@ -227,6 +314,10 @@ int cAudio::StopClip()
} }
close(clipfd); close(clipfd);
clipfd = -1; clipfd = -1;
if (mixer_fd >= 0)
close(mixer_fd);
mixer_fd = -1;
setVolume(volume, volume);
return 0; return 0;
}; };

View File

@@ -37,6 +37,8 @@ class cAudio
bool Muted; bool Muted;
int clipfd; /* for pcm playback */ int clipfd; /* for pcm playback */
int mixer_fd; /* if we are using the OSS mixer */
int mixer_num; /* oss mixer to use, if any */
AUDIO_FORMAT StreamType; AUDIO_FORMAT StreamType;
AUDIO_SYNC_MODE SyncMode; AUDIO_SYNC_MODE SyncMode;