aboutsummaryrefslogtreecommitdiffstats
path: root/src/volume.c
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2006-07-16 16:53:04 +0000
committerEric Wong <normalperson@yhbt.net>2006-07-16 16:53:04 +0000
commitb8a0f1ae6d32847270748e92e744606107114737 (patch)
tree649b933f2c3e24761ee7ec0bb228a78fe5bf8486 /src/volume.c
parentea6dc826a1c40047058ab7d86c848b32be3de25e (diff)
downloadmpd-b8a0f1ae6d32847270748e92e744606107114737.tar.gz
mpd-b8a0f1ae6d32847270748e92e744606107114737.tar.xz
mpd-b8a0f1ae6d32847270748e92e744606107114737.zip
OSS: handle device disconnects and reconnects (w/o needing a mpd restart)
Like the ALSA patches, this allows OSS devices to be disconnected during playback and MPD will be able to reopen and reuse them without restarting. git-svn-id: https://svn.musicpd.org/mpd/trunk@4366 09075e82-0dd4-0310-85a5-a0d7c8717e4f
Diffstat (limited to 'src/volume.c')
-rw-r--r--src/volume.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/src/volume.c b/src/volume.c
index 6fd68d778..d398457d3 100644
--- a/src/volume.c
+++ b/src/volume.c
@@ -64,7 +64,7 @@ static char * volume_mixerDevice = VOLUME_MIXER_DEVICE_DEFAULT;
static int volume_softwareSet = 100;
#ifdef HAVE_OSS
-static int volume_ossFd;
+static int volume_ossFd = -1;
static int volume_ossControl = SOUND_MIXER_PCM;
#endif
@@ -77,8 +77,14 @@ static int volume_alsaSet = -1;
#endif
#ifdef HAVE_OSS
+
+static void closeOssMixer(void)
+{
+ while (close(volume_ossFd) && errno == EINTR);
+ volume_ossFd = -1;
+}
+
static int prepOssMixer(char * device) {
- int devmask = 0;
ConfigParam * param;
if((volume_ossFd = open(device,O_RDONLY))<0) {
@@ -92,10 +98,11 @@ static int prepOssMixer(char * device) {
char * labels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
char * dup;
int i,j;
+ int devmask = 0;
if(ioctl(volume_ossFd,SOUND_MIXER_READ_DEVMASK,&devmask)<0) {
WARNING("errors getting read_devmask for oss mixer\n");
- close(volume_ossFd);
+ closeOssMixer();
return -1;
}
@@ -114,13 +121,13 @@ static int prepOssMixer(char * device) {
if(i>=SOUND_MIXER_NRDEVICES) {
WARNING("mixer control \"%s\" not found at line %i\n",
param->value, param->line);
- close(volume_ossFd);
+ closeOssMixer();
return -1;
}
else if(!( ( 1 << i ) & devmask )) {
WARNING("mixer control \"%s\" not usable at line %i\n",
param->value, param->line);
- close(volume_ossFd);
+ closeOssMixer();
return -1;
}
@@ -130,14 +137,21 @@ static int prepOssMixer(char * device) {
return 0;
}
-static void closeOssMixer() {
- close(volume_ossFd);
+static int ensure_oss_open(void)
+{
+ if ((volume_ossFd < 0 && prepOssMixer(volume_mixerDevice) < 0))
+ return -1;
+ return 0;
}
static int getOssVolumeLevel() {
int left, right, level;
+ if (ensure_oss_open() < 0)
+ return -1;
+
if(ioctl(volume_ossFd,MIXER_READ(volume_ossControl),&level) < 0) {
+ closeOssMixer();
WARNING("unable to read volume\n");
return -1;
}
@@ -166,8 +180,11 @@ static int changeOssVolumeLevel(FILE * fp, int change, int rel) {
}
new = current+change;
+ } else {
+ if (ensure_oss_open() < 0)
+ return -1;
+ new = change;
}
- else new = change;
if(new<0) new = 0;
else if(new>100) new = 100;
@@ -175,6 +192,7 @@ static int changeOssVolumeLevel(FILE * fp, int change, int rel) {
level = (new << 8) + new;
if(ioctl(volume_ossFd,MIXER_WRITE(volume_ossControl),&level) < 0) {
+ closeOssMixer();
commandError(fp, ACK_ERROR_SYSTEM, "problems setting volume",
NULL);
return -1;