mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-06 13:29:56 -05:00
instead of using the mixer ioctl()s on the dsp fd, open a seperate fd for the mixer. This allows us the keep the mixer fd open while closing the dsp device while suspending.
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1893 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
fc00eaf1d4
commit
77ed60ce4c
3 changed files with 292 additions and 194 deletions
|
|
@ -36,8 +36,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* TODO: handle restoring of volume after suspend */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -115,14 +113,14 @@ struct userdata {
|
||||||
int use_getospace, use_getispace;
|
int use_getospace, use_getispace;
|
||||||
int use_getodelay;
|
int use_getodelay;
|
||||||
|
|
||||||
int use_pcm_volume;
|
|
||||||
int use_input_volume;
|
|
||||||
|
|
||||||
int sink_suspended, source_suspended;
|
int sink_suspended, source_suspended;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
int mode;
|
int mode;
|
||||||
|
|
||||||
|
int mixer_fd;
|
||||||
|
int mixer_devmask;
|
||||||
|
|
||||||
int nfrags, frag_size;
|
int nfrags, frag_size;
|
||||||
|
|
||||||
int use_mmap;
|
int use_mmap;
|
||||||
|
|
@ -583,6 +581,11 @@ static int unsuspend(struct userdata *u) {
|
||||||
pollfd->events = 0;
|
pollfd->events = 0;
|
||||||
pollfd->revents = 0;
|
pollfd->revents = 0;
|
||||||
|
|
||||||
|
if (u->sink)
|
||||||
|
pa_sink_get_volume(u->sink);
|
||||||
|
if (u->source)
|
||||||
|
pa_source_get_volume(u->source);
|
||||||
|
|
||||||
pa_log_info("Resumed successfully...");
|
pa_log_info("Resumed successfully...");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -659,31 +662,6 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PA_SINK_MESSAGE_SET_VOLUME:
|
|
||||||
|
|
||||||
if (u->use_pcm_volume && u->fd >= 0) {
|
|
||||||
|
|
||||||
if (pa_oss_set_pcm_volume(u->fd, &u->sink->sample_spec, ((pa_cvolume*) data)) < 0) {
|
|
||||||
pa_log_info("Device doesn't support setting mixer settings: %s", pa_cstrerror(errno));
|
|
||||||
u->use_pcm_volume = 0;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PA_SINK_MESSAGE_GET_VOLUME:
|
|
||||||
|
|
||||||
if (u->use_pcm_volume && u->fd >= 0) {
|
|
||||||
|
|
||||||
if (pa_oss_get_pcm_volume(u->fd, &u->sink->sample_spec, ((pa_cvolume*) data)) < 0) {
|
|
||||||
pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno));
|
|
||||||
u->use_pcm_volume = 0;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pa_sink_process_msg(o, code, data, offset, chunk);
|
ret = pa_sink_process_msg(o, code, data, offset, chunk);
|
||||||
|
|
@ -757,31 +735,6 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PA_SOURCE_MESSAGE_SET_VOLUME:
|
|
||||||
|
|
||||||
if (u->use_input_volume && u->fd >= 0) {
|
|
||||||
|
|
||||||
if (pa_oss_set_input_volume(u->fd, &u->source->sample_spec, ((pa_cvolume*) data)) < 0) {
|
|
||||||
pa_log_info("Device doesn't support setting mixer settings: %s", pa_cstrerror(errno));
|
|
||||||
u->use_input_volume = 0;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PA_SOURCE_MESSAGE_GET_VOLUME:
|
|
||||||
|
|
||||||
if (u->use_input_volume && u->fd >= 0) {
|
|
||||||
|
|
||||||
if (pa_oss_get_input_volume(u->fd, &u->source->sample_spec, ((pa_cvolume*) data)) < 0) {
|
|
||||||
pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno));
|
|
||||||
u->use_input_volume = 0;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pa_source_process_msg(o, code, data, offset, chunk);
|
ret = pa_source_process_msg(o, code, data, offset, chunk);
|
||||||
|
|
@ -792,6 +745,86 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sink_get_volume(pa_sink *s) {
|
||||||
|
struct userdata *u;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
pa_assert_se(u = s->userdata);
|
||||||
|
|
||||||
|
pa_assert(u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM));
|
||||||
|
|
||||||
|
if (u->mixer_devmask & SOUND_MASK_VOLUME)
|
||||||
|
if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_VOLUME, &s->sample_spec, &s->volume)) >= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (u->mixer_devmask & SOUND_MASK_PCM)
|
||||||
|
if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_PCM, &s->sample_spec, &s->volume)) >= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sink_set_volume(pa_sink *s) {
|
||||||
|
struct userdata *u;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
pa_assert_se(u = s->userdata);
|
||||||
|
|
||||||
|
pa_assert(u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM));
|
||||||
|
|
||||||
|
if (u->mixer_devmask & SOUND_MASK_VOLUME)
|
||||||
|
if ((r = pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_VOLUME, &s->sample_spec, &s->volume)) >= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (u->mixer_devmask & SOUND_MASK_PCM)
|
||||||
|
if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_WRITE_PCM, &s->sample_spec, &s->volume)) >= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
pa_log_info("Device doesn't support writing mixer settings: %s", pa_cstrerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int source_get_volume(pa_source *s) {
|
||||||
|
struct userdata *u;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
pa_assert_se(u = s->userdata);
|
||||||
|
|
||||||
|
pa_assert(u->mixer_devmask & (SOUND_MASK_IGAIN|SOUND_MASK_RECLEV));
|
||||||
|
|
||||||
|
if (u->mixer_devmask & SOUND_MASK_IGAIN)
|
||||||
|
if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_IGAIN, &s->sample_spec, &s->volume)) >= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (u->mixer_devmask & SOUND_MASK_RECLEV)
|
||||||
|
if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_RECLEV, &s->sample_spec, &s->volume)) >= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int source_set_volume(pa_source *s) {
|
||||||
|
struct userdata *u;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
pa_assert_se(u = s->userdata);
|
||||||
|
|
||||||
|
pa_assert(u->mixer_devmask & (SOUND_MASK_IGAIN|SOUND_MASK_RECLEV));
|
||||||
|
|
||||||
|
if (u->mixer_devmask & SOUND_MASK_IGAIN)
|
||||||
|
if ((r = pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_IGAIN, &s->sample_spec, &s->volume)) >= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (u->mixer_devmask & SOUND_MASK_RECLEV)
|
||||||
|
if ((r = pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_WRITE_RECLEV, &s->sample_spec, &s->volume)) >= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
pa_log_info("Device doesn't support writing mixer settings: %s", pa_cstrerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static void thread_func(void *userdata) {
|
static void thread_func(void *userdata) {
|
||||||
struct userdata *u = userdata;
|
struct userdata *u = userdata;
|
||||||
int write_type = 0, read_type = 0;
|
int write_type = 0, read_type = 0;
|
||||||
|
|
@ -1135,9 +1168,9 @@ int pa__init(pa_module*m) {
|
||||||
u->module = m;
|
u->module = m;
|
||||||
m->userdata = u;
|
m->userdata = u;
|
||||||
u->fd = fd;
|
u->fd = fd;
|
||||||
|
u->mixer_fd = -1;
|
||||||
u->use_getospace = u->use_getispace = 1;
|
u->use_getospace = u->use_getispace = 1;
|
||||||
u->use_getodelay = 1;
|
u->use_getodelay = 1;
|
||||||
u->use_input_volume = u->use_pcm_volume = 1;
|
|
||||||
u->mode = mode;
|
u->mode = mode;
|
||||||
u->frame_size = pa_frame_size(&ss);
|
u->frame_size = pa_frame_size(&ss);
|
||||||
u->device_name = pa_xstrdup(dev);
|
u->device_name = pa_xstrdup(dev);
|
||||||
|
|
@ -1210,7 +1243,7 @@ int pa__init(pa_module*m) {
|
||||||
hwdesc[0] ? ")" : "",
|
hwdesc[0] ? ")" : "",
|
||||||
use_mmap ? " via DMA" : ""));
|
use_mmap ? " via DMA" : ""));
|
||||||
pa_xfree(t);
|
pa_xfree(t);
|
||||||
u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_CAN_SUSPEND|PA_SOURCE_LATENCY|PA_SOURCE_HW_VOLUME_CTRL;
|
u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_CAN_SUSPEND|PA_SOURCE_LATENCY;
|
||||||
u->source->refresh_volume = 1;
|
u->source->refresh_volume = 1;
|
||||||
|
|
||||||
if (use_mmap)
|
if (use_mmap)
|
||||||
|
|
@ -1265,13 +1298,44 @@ int pa__init(pa_module*m) {
|
||||||
hwdesc[0] ? ")" : "",
|
hwdesc[0] ? ")" : "",
|
||||||
use_mmap ? " via DMA" : ""));
|
use_mmap ? " via DMA" : ""));
|
||||||
pa_xfree(t);
|
pa_xfree(t);
|
||||||
u->sink->flags = PA_SINK_HARDWARE|PA_SINK_CAN_SUSPEND|PA_SINK_LATENCY|PA_SINK_HW_VOLUME_CTRL;
|
u->sink->flags = PA_SINK_HARDWARE|PA_SINK_CAN_SUSPEND|PA_SINK_LATENCY;
|
||||||
u->sink->refresh_volume = 1;
|
u->sink->refresh_volume = 1;
|
||||||
|
|
||||||
if (use_mmap)
|
if (use_mmap)
|
||||||
u->out_mmap_memblocks = pa_xnew0(pa_memblock*, u->out_nfrags);
|
u->out_mmap_memblocks = pa_xnew0(pa_memblock*, u->out_nfrags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((u->mixer_fd = pa_oss_open_mixer_for_device(u->device_name)) >= 0) {
|
||||||
|
int do_close = 1;
|
||||||
|
u->mixer_devmask = 0;
|
||||||
|
|
||||||
|
if (ioctl(fd, SOUND_MIXER_READ_DEVMASK, &u->mixer_devmask) < 0)
|
||||||
|
pa_log_warn("SOUND_MIXER_READ_DEVMASK failed: %s", pa_cstrerror(errno));
|
||||||
|
|
||||||
|
else {
|
||||||
|
if (u->sink && (u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM))) {
|
||||||
|
pa_log_debug("Found hardware mixer track for playback.");
|
||||||
|
u->sink->flags |= PA_SINK_HW_VOLUME_CTRL;
|
||||||
|
u->sink->get_volume = sink_get_volume;
|
||||||
|
u->sink->set_volume = sink_set_volume;
|
||||||
|
do_close = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u->source && (u->mixer_devmask & (SOUND_MASK_RECLEV|SOUND_MASK_IGAIN))) {
|
||||||
|
pa_log_debug("Found hardware mixer track for recording.");
|
||||||
|
u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL;
|
||||||
|
u->source->get_volume = source_get_volume;
|
||||||
|
u->source->set_volume = source_set_volume;
|
||||||
|
do_close = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (do_close) {
|
||||||
|
pa_close(u->mixer_fd);
|
||||||
|
u->mixer_fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
go_on:
|
go_on:
|
||||||
|
|
||||||
pa_assert(u->source || u->sink);
|
pa_assert(u->source || u->sink);
|
||||||
|
|
@ -1284,10 +1348,10 @@ go_on:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read mixer settings */
|
/* Read mixer settings */
|
||||||
if (u->source)
|
if (u->sink && u->sink->get_volume)
|
||||||
pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, 0, NULL);
|
sink_get_volume(u->sink);
|
||||||
if (u->sink)
|
if (u->source && u->source->get_volume)
|
||||||
pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, 0, NULL);
|
source_get_volume(u->source);
|
||||||
|
|
||||||
if (u->sink)
|
if (u->sink)
|
||||||
pa_sink_put(u->sink);
|
pa_sink_put(u->sink);
|
||||||
|
|
@ -1372,6 +1436,9 @@ void pa__done(pa_module*m) {
|
||||||
if (u->fd >= 0)
|
if (u->fd >= 0)
|
||||||
pa_close(u->fd);
|
pa_close(u->fd);
|
||||||
|
|
||||||
|
if (u->mixer_fd >= 0)
|
||||||
|
pa_close(u->mixer_fd);
|
||||||
|
|
||||||
pa_xfree(u->device_name);
|
pa_xfree(u->device_name);
|
||||||
|
|
||||||
pa_xfree(u);
|
pa_xfree(u);
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <pulse/xmalloc.h>
|
||||||
#include <pulsecore/core-error.h>
|
#include <pulsecore/core-error.h>
|
||||||
#include <pulsecore/core-util.h>
|
#include <pulsecore/core-util.h>
|
||||||
#include <pulsecore/log.h>
|
#include <pulsecore/log.h>
|
||||||
|
|
@ -248,7 +249,7 @@ int pa_oss_set_fragments(int fd, int nfrags, int frag_size) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pa_oss_get_volume(int fd, int mixer, const pa_sample_spec *ss, pa_cvolume *volume) {
|
int pa_oss_get_volume(int fd, int mixer, const pa_sample_spec *ss, pa_cvolume *volume) {
|
||||||
char cv[PA_CVOLUME_SNPRINT_MAX];
|
char cv[PA_CVOLUME_SNPRINT_MAX];
|
||||||
unsigned vol;
|
unsigned vol;
|
||||||
|
|
||||||
|
|
@ -259,16 +260,18 @@ static int pa_oss_get_volume(int fd, int mixer, const pa_sample_spec *ss, pa_cvo
|
||||||
if (ioctl(fd, mixer, &vol) < 0)
|
if (ioctl(fd, mixer, &vol) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
pa_cvolume_reset(volume, ss->channels);
|
||||||
|
|
||||||
volume->values[0] = ((vol & 0xFF) * PA_VOLUME_NORM) / 100;
|
volume->values[0] = ((vol & 0xFF) * PA_VOLUME_NORM) / 100;
|
||||||
|
|
||||||
if ((volume->channels = ss->channels) >= 2)
|
if (volume->channels >= 2)
|
||||||
volume->values[1] = (((vol >> 8) & 0xFF) * PA_VOLUME_NORM) / 100;
|
volume->values[1] = (((vol >> 8) & 0xFF) * PA_VOLUME_NORM) / 100;
|
||||||
|
|
||||||
pa_log_debug("Read mixer settings: %s", pa_cvolume_snprint(cv, sizeof(cv), volume));
|
pa_log_debug("Read mixer settings: %s", pa_cvolume_snprint(cv, sizeof(cv), volume));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pa_oss_set_volume(int fd, long mixer, const pa_sample_spec *ss, const pa_cvolume *volume) {
|
int pa_oss_set_volume(int fd, long mixer, const pa_sample_spec *ss, const pa_cvolume *volume) {
|
||||||
char cv[PA_CVOLUME_SNPRINT_MAX];
|
char cv[PA_CVOLUME_SNPRINT_MAX];
|
||||||
unsigned vol;
|
unsigned vol;
|
||||||
pa_volume_t l, r;
|
pa_volume_t l, r;
|
||||||
|
|
@ -289,40 +292,38 @@ static int pa_oss_set_volume(int fd, long mixer, const pa_sample_spec *ss, const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pa_oss_get_pcm_volume(int fd, const pa_sample_spec *ss, pa_cvolume *volume) {
|
static int get_device_number(const char *dev) {
|
||||||
return pa_oss_get_volume(fd, SOUND_MIXER_READ_PCM, ss, volume);
|
char buf[PATH_MAX];
|
||||||
}
|
const char *p, *e;
|
||||||
|
|
||||||
int pa_oss_set_pcm_volume(int fd, const pa_sample_spec *ss, const pa_cvolume *volume) {
|
if (readlink(dev, buf, sizeof(buf)) < 0) {
|
||||||
return pa_oss_set_volume(fd, SOUND_MIXER_WRITE_PCM, ss, volume);
|
if (errno != EINVAL && errno != ENOLINK)
|
||||||
}
|
return -1;
|
||||||
|
|
||||||
int pa_oss_get_input_volume(int fd, const pa_sample_spec *ss, pa_cvolume *volume) {
|
p = dev;
|
||||||
return pa_oss_get_volume(fd, SOUND_MIXER_READ_IGAIN, ss, volume);
|
} else
|
||||||
}
|
p = buf;
|
||||||
|
|
||||||
int pa_oss_set_input_volume(int fd, const pa_sample_spec *ss, const pa_cvolume *volume) {
|
if ((e = strrchr(p, '/')))
|
||||||
return pa_oss_set_volume(fd, SOUND_MIXER_WRITE_IGAIN, ss, volume);
|
p = e+1;
|
||||||
|
|
||||||
|
if (p == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
p = strchr(p, 0) -1;
|
||||||
|
|
||||||
|
if (*p >= '0' && *p <= '9')
|
||||||
|
return *p - '0';
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pa_oss_get_hw_description(const char *dev, char *name, size_t l) {
|
int pa_oss_get_hw_description(const char *dev, char *name, size_t l) {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
const char *e = NULL;
|
|
||||||
int n, r = -1;
|
int n, r = -1;
|
||||||
int b = 0;
|
int b = 0;
|
||||||
|
|
||||||
if (strncmp(dev, "/dev/dsp", 8) == 0)
|
if ((n = get_device_number(dev)) < 0)
|
||||||
e = dev+8;
|
|
||||||
else if (strncmp(dev, "/dev/adsp", 9) == 0)
|
|
||||||
e = dev+9;
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (*e == 0)
|
|
||||||
n = 0;
|
|
||||||
else if (*e >= '0' && *e <= '9' && *(e+1) == 0)
|
|
||||||
n = *e - '0';
|
|
||||||
else
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!(f = fopen("/dev/sndstat", "r")) &&
|
if (!(f = fopen("/dev/sndstat", "r")) &&
|
||||||
|
|
@ -373,3 +374,34 @@ int pa_oss_get_hw_description(const char *dev, char *name, size_t l) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int open_mixer(const char *mixer) {
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if ((fd = open(mixer, O_RDWR|O_NDELAY|O_NOCTTY)) >= 0)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pa_oss_open_mixer_for_device(const char *device) {
|
||||||
|
int n;
|
||||||
|
char *fn;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if ((n = get_device_number(device)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
if ((fd = open_mixer("/dev/mixer")) >= 0)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
fn = pa_sprintf_malloc("/dev/mixer%i", n);
|
||||||
|
fd = open_mixer(fn);
|
||||||
|
pa_xfree(fn);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
pa_log_warn("Failed to open mixer '%s': %s", device, pa_cstrerror(errno));
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,11 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss);
|
||||||
|
|
||||||
int pa_oss_set_fragments(int fd, int frags, int frag_size);
|
int pa_oss_set_fragments(int fd, int frags, int frag_size);
|
||||||
|
|
||||||
int pa_oss_get_pcm_volume(int fd, const pa_sample_spec *ss, pa_cvolume *volume);
|
int pa_oss_set_volume(int fd, long mixer, const pa_sample_spec *ss, const pa_cvolume *volume);
|
||||||
int pa_oss_set_pcm_volume(int fd, const pa_sample_spec *ss, const pa_cvolume *volume);
|
int pa_oss_get_volume(int fd, int mixer, const pa_sample_spec *ss, pa_cvolume *volume);
|
||||||
|
|
||||||
int pa_oss_get_input_volume(int fd, const pa_sample_spec *ss, pa_cvolume *volume);
|
|
||||||
int pa_oss_set_input_volume(int fd, const pa_sample_spec *ss, const pa_cvolume *volume);
|
|
||||||
|
|
||||||
int pa_oss_get_hw_description(const char *dev, char *name, size_t l);
|
int pa_oss_get_hw_description(const char *dev, char *name, size_t l);
|
||||||
|
|
||||||
|
int pa_oss_open_mixer_for_device(const char *device);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue