mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-10 13:29:58 -05:00
drop the PA_SOURCE_CAN_SUSPEND and PA_SINK_CAN_SUSPEND flags, since they were a bad idea in the first place. All sinks/sources are now *required* to handle suspending in one way or another. Luckily all current sink/source implementations handle it fine anyway.
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1894 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
77ed60ce4c
commit
ba322a49e1
12 changed files with 196 additions and 214 deletions
|
|
@ -70,11 +70,11 @@ struct userdata {
|
||||||
pa_core *core;
|
pa_core *core;
|
||||||
pa_module *module;
|
pa_module *module;
|
||||||
pa_sink *sink;
|
pa_sink *sink;
|
||||||
|
|
||||||
pa_thread *thread;
|
pa_thread *thread;
|
||||||
pa_thread_mq thread_mq;
|
pa_thread_mq thread_mq;
|
||||||
pa_rtpoll *rtpoll;
|
pa_rtpoll *rtpoll;
|
||||||
|
|
||||||
snd_pcm_t *pcm_handle;
|
snd_pcm_t *pcm_handle;
|
||||||
|
|
||||||
pa_alsa_fdlist *mixer_fdl;
|
pa_alsa_fdlist *mixer_fdl;
|
||||||
|
|
@ -110,7 +110,7 @@ static const char* const valid_modargs[] = {
|
||||||
|
|
||||||
static int mmap_write(struct userdata *u) {
|
static int mmap_write(struct userdata *u) {
|
||||||
int work_done = 0;
|
int work_done = 0;
|
||||||
|
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
pa_sink_assert_ref(u->sink);
|
pa_sink_assert_ref(u->sink);
|
||||||
|
|
||||||
|
|
@ -121,33 +121,33 @@ static int mmap_write(struct userdata *u) {
|
||||||
int err;
|
int err;
|
||||||
const snd_pcm_channel_area_t *areas;
|
const snd_pcm_channel_area_t *areas;
|
||||||
snd_pcm_uframes_t offset, frames;
|
snd_pcm_uframes_t offset, frames;
|
||||||
|
|
||||||
if ((n = snd_pcm_avail_update(u->pcm_handle)) < 0) {
|
if ((n = snd_pcm_avail_update(u->pcm_handle)) < 0) {
|
||||||
|
|
||||||
if (n == -EPIPE) {
|
if (n == -EPIPE) {
|
||||||
pa_log_debug("snd_pcm_avail_update: Buffer underrun!");
|
pa_log_debug("snd_pcm_avail_update: Buffer underrun!");
|
||||||
u->first = 1;
|
u->first = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0)
|
if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (err == -EAGAIN)
|
if (err == -EAGAIN)
|
||||||
return work_done;
|
return work_done;
|
||||||
|
|
||||||
pa_log("snd_pcm_avail_update: %s", snd_strerror(err));
|
pa_log("snd_pcm_avail_update: %s", snd_strerror(err));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pa_log("Got request for %i samples", (int) n); */
|
/* pa_log("Got request for %i samples", (int) n); */
|
||||||
|
|
||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
return work_done;
|
return work_done;
|
||||||
|
|
||||||
frames = n;
|
frames = n;
|
||||||
|
|
||||||
if ((err = snd_pcm_mmap_begin(u->pcm_handle, &areas, &offset, &frames)) < 0) {
|
if ((err = snd_pcm_mmap_begin(u->pcm_handle, &areas, &offset, &frames)) < 0) {
|
||||||
|
|
||||||
if (err == -EPIPE) {
|
if (err == -EPIPE) {
|
||||||
pa_log_debug("snd_pcm_mmap_begin: Buffer underrun!");
|
pa_log_debug("snd_pcm_mmap_begin: Buffer underrun!");
|
||||||
u->first = 1;
|
u->first = 1;
|
||||||
|
|
@ -172,7 +172,7 @@ static int mmap_write(struct userdata *u) {
|
||||||
pa_assert((areas[0].step >> 3) == u->frame_size);
|
pa_assert((areas[0].step >> 3) == u->frame_size);
|
||||||
|
|
||||||
p = (uint8_t*) areas[0].addr + (offset * u->frame_size);
|
p = (uint8_t*) areas[0].addr + (offset * u->frame_size);
|
||||||
|
|
||||||
chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, 1);
|
chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, 1);
|
||||||
chunk.length = pa_memblock_get_length(chunk.memblock);
|
chunk.length = pa_memblock_get_length(chunk.memblock);
|
||||||
chunk.index = 0;
|
chunk.index = 0;
|
||||||
|
|
@ -189,13 +189,13 @@ static int mmap_write(struct userdata *u) {
|
||||||
pa_log_debug("snd_pcm_mmap_commit: Buffer underrun!");
|
pa_log_debug("snd_pcm_mmap_commit: Buffer underrun!");
|
||||||
u->first = 1;
|
u->first = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0)
|
if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (err == -EAGAIN)
|
if (err == -EAGAIN)
|
||||||
return work_done;
|
return work_done;
|
||||||
|
|
||||||
pa_log("Failed to write data to DSP: %s", snd_strerror(err));
|
pa_log("Failed to write data to DSP: %s", snd_strerror(err));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -204,7 +204,7 @@ static int mmap_write(struct userdata *u) {
|
||||||
|
|
||||||
if (frames >= (snd_pcm_uframes_t) n)
|
if (frames >= (snd_pcm_uframes_t) n)
|
||||||
return work_done;
|
return work_done;
|
||||||
|
|
||||||
/* pa_log("wrote %i samples", (int) frames); */
|
/* pa_log("wrote %i samples", (int) frames); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -214,7 +214,7 @@ static int unix_write(struct userdata *u) {
|
||||||
int work_done = 0;
|
int work_done = 0;
|
||||||
|
|
||||||
snd_pcm_status_alloca(&status);
|
snd_pcm_status_alloca(&status);
|
||||||
|
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
pa_sink_assert_ref(u->sink);
|
pa_sink_assert_ref(u->sink);
|
||||||
|
|
||||||
|
|
@ -223,7 +223,7 @@ static int unix_write(struct userdata *u) {
|
||||||
snd_pcm_sframes_t t;
|
snd_pcm_sframes_t t;
|
||||||
ssize_t l;
|
ssize_t l;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) {
|
if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) {
|
||||||
pa_log("Failed to query DSP status data: %s", snd_strerror(err));
|
pa_log("Failed to query DSP status data: %s", snd_strerror(err));
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -231,32 +231,32 @@ static int unix_write(struct userdata *u) {
|
||||||
|
|
||||||
if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size)
|
if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size)
|
||||||
pa_log_debug("Buffer underrun!");
|
pa_log_debug("Buffer underrun!");
|
||||||
|
|
||||||
l = snd_pcm_status_get_avail(status) * u->frame_size;
|
l = snd_pcm_status_get_avail(status) * u->frame_size;
|
||||||
|
|
||||||
/* pa_log("%u bytes to write", l); */
|
/* pa_log("%u bytes to write", l); */
|
||||||
|
|
||||||
if (l <= 0)
|
if (l <= 0)
|
||||||
return work_done;
|
return work_done;
|
||||||
|
|
||||||
if (u->memchunk.length <= 0)
|
if (u->memchunk.length <= 0)
|
||||||
pa_sink_render(u->sink, l, &u->memchunk);
|
pa_sink_render(u->sink, l, &u->memchunk);
|
||||||
|
|
||||||
pa_assert(u->memchunk.length > 0);
|
pa_assert(u->memchunk.length > 0);
|
||||||
|
|
||||||
p = pa_memblock_acquire(u->memchunk.memblock);
|
p = pa_memblock_acquire(u->memchunk.memblock);
|
||||||
t = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size);
|
t = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, u->memchunk.length / u->frame_size);
|
||||||
pa_memblock_release(u->memchunk.memblock);
|
pa_memblock_release(u->memchunk.memblock);
|
||||||
|
|
||||||
/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */
|
/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */
|
||||||
|
|
||||||
pa_assert(t != 0);
|
pa_assert(t != 0);
|
||||||
|
|
||||||
if (t < 0) {
|
if (t < 0) {
|
||||||
|
|
||||||
if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0)
|
if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (t == -EAGAIN) {
|
if (t == -EAGAIN) {
|
||||||
pa_log_debug("EAGAIN");
|
pa_log_debug("EAGAIN");
|
||||||
return work_done;
|
return work_done;
|
||||||
|
|
@ -265,10 +265,10 @@ static int unix_write(struct userdata *u) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u->memchunk.index += t * u->frame_size;
|
u->memchunk.index += t * u->frame_size;
|
||||||
u->memchunk.length -= t * u->frame_size;
|
u->memchunk.length -= t * u->frame_size;
|
||||||
|
|
||||||
if (u->memchunk.length <= 0) {
|
if (u->memchunk.length <= 0) {
|
||||||
pa_memblock_unref(u->memchunk.memblock);
|
pa_memblock_unref(u->memchunk.memblock);
|
||||||
pa_memchunk_reset(&u->memchunk);
|
pa_memchunk_reset(&u->memchunk);
|
||||||
|
|
@ -278,7 +278,7 @@ static int unix_write(struct userdata *u) {
|
||||||
|
|
||||||
if (t * u->frame_size >= (unsigned) l)
|
if (t * u->frame_size >= (unsigned) l)
|
||||||
return work_done;
|
return work_done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static pa_usec_t sink_get_latency(struct userdata *u) {
|
static pa_usec_t sink_get_latency(struct userdata *u) {
|
||||||
|
|
@ -288,18 +288,18 @@ static pa_usec_t sink_get_latency(struct userdata *u) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
snd_pcm_status_alloca(&status);
|
snd_pcm_status_alloca(&status);
|
||||||
|
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
pa_assert(u->pcm_handle);
|
pa_assert(u->pcm_handle);
|
||||||
|
|
||||||
if ((err = snd_pcm_status(u->pcm_handle, status)) < 0)
|
if ((err = snd_pcm_status(u->pcm_handle, status)) < 0)
|
||||||
pa_log("Failed to get delay: %s", snd_strerror(err));
|
pa_log("Failed to get delay: %s", snd_strerror(err));
|
||||||
else
|
else
|
||||||
frames = snd_pcm_status_get_delay(status);
|
frames = snd_pcm_status_get_delay(status);
|
||||||
|
|
||||||
if (frames > 0)
|
if (frames > 0)
|
||||||
r = pa_bytes_to_usec(frames * u->frame_size, &u->sink->sample_spec);
|
r = pa_bytes_to_usec(frames * u->frame_size, &u->sink->sample_spec);
|
||||||
|
|
||||||
if (u->memchunk.memblock)
|
if (u->memchunk.memblock)
|
||||||
r += pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec);
|
r += pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec);
|
||||||
|
|
||||||
|
|
@ -310,7 +310,7 @@ static int build_pollfd(struct userdata *u) {
|
||||||
int err;
|
int err;
|
||||||
struct pollfd *pollfd;
|
struct pollfd *pollfd;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
pa_assert(u->pcm_handle);
|
pa_assert(u->pcm_handle);
|
||||||
|
|
||||||
|
|
@ -329,7 +329,7 @@ static int build_pollfd(struct userdata *u) {
|
||||||
pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err));
|
pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -338,7 +338,7 @@ static int suspend(struct userdata *u) {
|
||||||
pa_assert(u->pcm_handle);
|
pa_assert(u->pcm_handle);
|
||||||
|
|
||||||
/* Let's suspend */
|
/* Let's suspend */
|
||||||
snd_pcm_drain(u->pcm_handle);
|
snd_pcm_drain(u->pcm_handle);
|
||||||
snd_pcm_close(u->pcm_handle);
|
snd_pcm_close(u->pcm_handle);
|
||||||
u->pcm_handle = NULL;
|
u->pcm_handle = NULL;
|
||||||
|
|
||||||
|
|
@ -346,9 +346,9 @@ static int suspend(struct userdata *u) {
|
||||||
pa_rtpoll_item_free(u->alsa_rtpoll_item);
|
pa_rtpoll_item_free(u->alsa_rtpoll_item);
|
||||||
u->alsa_rtpoll_item = NULL;
|
u->alsa_rtpoll_item = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_log_info("Device suspended...");
|
pa_log_info("Device suspended...");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -373,7 +373,7 @@ static int unsuspend(struct userdata *u) {
|
||||||
nfrags = u->nfragments;
|
nfrags = u->nfragments;
|
||||||
period_size = u->fragment_size / u->frame_size;
|
period_size = u->fragment_size / u->frame_size;
|
||||||
b = u->use_mmap;
|
b = u->use_mmap;
|
||||||
|
|
||||||
if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) {
|
if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) {
|
||||||
pa_log("Failed to set hardware parameters: %s", snd_strerror(err));
|
pa_log("Failed to set hardware parameters: %s", snd_strerror(err));
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -401,11 +401,11 @@ static int unsuspend(struct userdata *u) {
|
||||||
|
|
||||||
if (build_pollfd(u) < 0)
|
if (build_pollfd(u) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* FIXME: We need to reload the volume somehow */
|
/* FIXME: We need to reload the volume somehow */
|
||||||
|
|
||||||
u->first = 1;
|
u->first = 1;
|
||||||
|
|
||||||
pa_log_info("Resumed successfully...");
|
pa_log_info("Resumed successfully...");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -438,13 +438,13 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
|
||||||
case PA_SINK_MESSAGE_SET_STATE:
|
case PA_SINK_MESSAGE_SET_STATE:
|
||||||
|
|
||||||
switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) {
|
switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) {
|
||||||
|
|
||||||
case PA_SINK_SUSPENDED:
|
case PA_SINK_SUSPENDED:
|
||||||
pa_assert(PA_SINK_OPENED(u->sink->thread_info.state));
|
pa_assert(PA_SINK_OPENED(u->sink->thread_info.state));
|
||||||
|
|
||||||
if (suspend(u) < 0)
|
if (suspend(u) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PA_SINK_IDLE:
|
case PA_SINK_IDLE:
|
||||||
|
|
@ -454,14 +454,14 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
|
||||||
if (unsuspend(u) < 0)
|
if (unsuspend(u) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PA_SINK_UNLINKED:
|
case PA_SINK_UNLINKED:
|
||||||
case PA_SINK_INIT:
|
case PA_SINK_INIT:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -512,7 +512,7 @@ static int sink_get_volume_cb(pa_sink *s) {
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
pa_log_error("Unable to read volume: %s", snd_strerror(err));
|
pa_log_error("Unable to read volume: %s", snd_strerror(err));
|
||||||
|
|
||||||
s->get_volume = NULL;
|
s->get_volume = NULL;
|
||||||
s->set_volume = NULL;
|
s->set_volume = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -547,7 +547,7 @@ static int sink_set_volume_cb(pa_sink *s) {
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
pa_log_error("Unable to set volume: %s", snd_strerror(err));
|
pa_log_error("Unable to set volume: %s", snd_strerror(err));
|
||||||
|
|
||||||
s->get_volume = NULL;
|
s->get_volume = NULL;
|
||||||
s->set_volume = NULL;
|
s->set_volume = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -582,7 +582,7 @@ static int sink_set_mute_cb(pa_sink *s) {
|
||||||
|
|
||||||
if ((err = snd_mixer_selem_set_playback_switch_all(u->mixer_elem, !s->muted)) < 0) {
|
if ((err = snd_mixer_selem_set_playback_switch_all(u->mixer_elem, !s->muted)) < 0) {
|
||||||
pa_log_error("Unable to set switch: %s", snd_strerror(err));
|
pa_log_error("Unable to set switch: %s", snd_strerror(err));
|
||||||
|
|
||||||
s->get_mute = NULL;
|
s->get_mute = NULL;
|
||||||
s->set_mute = NULL;
|
s->set_mute = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -593,7 +593,7 @@ static int sink_set_mute_cb(pa_sink *s) {
|
||||||
|
|
||||||
static void thread_func(void *userdata) {
|
static void thread_func(void *userdata) {
|
||||||
struct userdata *u = userdata;
|
struct userdata *u = userdata;
|
||||||
|
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
|
|
||||||
pa_log_debug("Thread starting up");
|
pa_log_debug("Thread starting up");
|
||||||
|
|
@ -603,17 +603,17 @@ static void thread_func(void *userdata) {
|
||||||
|
|
||||||
pa_thread_mq_install(&u->thread_mq);
|
pa_thread_mq_install(&u->thread_mq);
|
||||||
pa_rtpoll_install(u->rtpoll);
|
pa_rtpoll_install(u->rtpoll);
|
||||||
|
|
||||||
if (build_pollfd(u) < 0)
|
if (build_pollfd(u) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Render some data and write it to the dsp */
|
/* Render some data and write it to the dsp */
|
||||||
if (PA_SINK_OPENED(u->sink->thread_info.state)) {
|
if (PA_SINK_OPENED(u->sink->thread_info.state)) {
|
||||||
int work_done = 0;
|
int work_done = 0;
|
||||||
|
|
||||||
if (u->use_mmap) {
|
if (u->use_mmap) {
|
||||||
if ((work_done = mmap_write(u)) < 0)
|
if ((work_done = mmap_write(u)) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -636,7 +636,7 @@ static void thread_func(void *userdata) {
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
/* Tell ALSA about this and process its response */
|
/* Tell ALSA about this and process its response */
|
||||||
if (PA_SINK_OPENED(u->sink->thread_info.state)) {
|
if (PA_SINK_OPENED(u->sink->thread_info.state)) {
|
||||||
struct pollfd *pollfd;
|
struct pollfd *pollfd;
|
||||||
|
|
@ -655,7 +655,7 @@ static void thread_func(void *userdata) {
|
||||||
if (revents & POLLERR)
|
if (revents & POLLERR)
|
||||||
pa_log_warn("Got POLLERR from ALSA");
|
pa_log_warn("Got POLLERR from ALSA");
|
||||||
if (revents & POLLNVAL)
|
if (revents & POLLNVAL)
|
||||||
pa_log_warn("Got POLLNVAL from ALSA");
|
pa_log_warn("Got POLLNVAL from ALSA");
|
||||||
if (revents & POLLHUP)
|
if (revents & POLLHUP)
|
||||||
pa_log_warn("Got POLLHUP from ALSA");
|
pa_log_warn("Got POLLHUP from ALSA");
|
||||||
|
|
||||||
|
|
@ -675,7 +675,7 @@ finish:
|
||||||
}
|
}
|
||||||
|
|
||||||
int pa__init(pa_module*m) {
|
int pa__init(pa_module*m) {
|
||||||
|
|
||||||
pa_modargs *ma = NULL;
|
pa_modargs *ma = NULL;
|
||||||
struct userdata *u = NULL;
|
struct userdata *u = NULL;
|
||||||
char *dev;
|
char *dev;
|
||||||
|
|
@ -693,7 +693,7 @@ int pa__init(pa_module*m) {
|
||||||
int use_mmap = 1, b;
|
int use_mmap = 1, b;
|
||||||
|
|
||||||
snd_pcm_info_alloca(&pcm_info);
|
snd_pcm_info_alloca(&pcm_info);
|
||||||
|
|
||||||
pa_assert(m);
|
pa_assert(m);
|
||||||
|
|
||||||
if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
|
if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
|
||||||
|
|
@ -724,7 +724,7 @@ int pa__init(pa_module*m) {
|
||||||
pa_log("Failed to parse mmap argument.");
|
pa_log("Failed to parse mmap argument.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
u = pa_xnew0(struct userdata, 1);
|
u = pa_xnew0(struct userdata, 1);
|
||||||
u->core = m->core;
|
u->core = m->core;
|
||||||
u->module = m;
|
u->module = m;
|
||||||
|
|
@ -741,19 +741,19 @@ int pa__init(pa_module*m) {
|
||||||
dev = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE));
|
dev = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE));
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if ((err = snd_pcm_open(&u->pcm_handle, dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) {
|
if ((err = snd_pcm_open(&u->pcm_handle, dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) {
|
||||||
pa_log("Error opening PCM device %s: %s", dev, snd_strerror(err));
|
pa_log("Error opening PCM device %s: %s", dev, snd_strerror(err));
|
||||||
pa_xfree(dev);
|
pa_xfree(dev);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
b = use_mmap;
|
b = use_mmap;
|
||||||
if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) {
|
if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) {
|
||||||
|
|
||||||
if (err == -EPERM) {
|
if (err == -EPERM) {
|
||||||
/* Hmm, some hw is very exotic, so we retry with plughw, if hw didn't work */
|
/* Hmm, some hw is very exotic, so we retry with plughw, if hw didn't work */
|
||||||
|
|
||||||
if (pa_startswith(dev, "hw:")) {
|
if (pa_startswith(dev, "hw:")) {
|
||||||
char *d = pa_sprintf_malloc("plughw:%s", dev+3);
|
char *d = pa_sprintf_malloc("plughw:%s", dev+3);
|
||||||
pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", dev, d);
|
pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", dev, d);
|
||||||
|
|
@ -765,7 +765,7 @@ int pa__init(pa_module*m) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_log("Failed to set hardware parameters: %s", snd_strerror(err));
|
pa_log("Failed to set hardware parameters: %s", snd_strerror(err));
|
||||||
pa_xfree(dev);
|
pa_xfree(dev);
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -773,9 +773,9 @@ int pa__init(pa_module*m) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->device_name = dev;
|
u->device_name = dev;
|
||||||
|
|
||||||
if (use_mmap && !b) {
|
if (use_mmap && !b) {
|
||||||
pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
|
pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
|
||||||
u->use_mmap = use_mmap = b;
|
u->use_mmap = use_mmap = b;
|
||||||
|
|
@ -807,7 +807,7 @@ int pa__init(pa_module*m) {
|
||||||
|
|
||||||
if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) ||
|
if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) ||
|
||||||
!(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Master", "PCM"))) {
|
!(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Master", "PCM"))) {
|
||||||
|
|
||||||
snd_mixer_close(u->mixer_handle);
|
snd_mixer_close(u->mixer_handle);
|
||||||
u->mixer_handle = NULL;
|
u->mixer_handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -822,7 +822,7 @@ int pa__init(pa_module*m) {
|
||||||
|
|
||||||
u->sink = pa_sink_new(m->core, __FILE__, name, namereg_fail, &ss, &map);
|
u->sink = pa_sink_new(m->core, __FILE__, name, namereg_fail, &ss, &map);
|
||||||
pa_xfree(name_buf);
|
pa_xfree(name_buf);
|
||||||
|
|
||||||
if (!u->sink) {
|
if (!u->sink) {
|
||||||
pa_log("Failed to create sink object");
|
pa_log("Failed to create sink object");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -840,8 +840,8 @@ int pa__init(pa_module*m) {
|
||||||
snd_pcm_info_get_name(pcm_info),
|
snd_pcm_info_get_name(pcm_info),
|
||||||
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_HW_VOLUME_CTRL|PA_SINK_LATENCY;
|
u->sink->flags = PA_SINK_HARDWARE|PA_SINK_HW_VOLUME_CTRL|PA_SINK_LATENCY;
|
||||||
|
|
||||||
u->frame_size = frame_size;
|
u->frame_size = frame_size;
|
||||||
u->fragment_size = frag_size = period_size * frame_size;
|
u->fragment_size = frag_size = period_size * frame_size;
|
||||||
|
|
@ -854,9 +854,9 @@ int pa__init(pa_module*m) {
|
||||||
|
|
||||||
if (u->mixer_handle) {
|
if (u->mixer_handle) {
|
||||||
/* Initialize mixer code */
|
/* Initialize mixer code */
|
||||||
|
|
||||||
pa_assert(u->mixer_elem);
|
pa_assert(u->mixer_elem);
|
||||||
|
|
||||||
if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) {
|
if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
@ -872,7 +872,7 @@ int pa__init(pa_module*m) {
|
||||||
} else
|
} else
|
||||||
pa_log_info("ALSA device lacks separate volumes controls for all %u channels (%u available), falling back to software volume control.", ss.channels, i+1);
|
pa_log_info("ALSA device lacks separate volumes controls for all %u channels (%u available), falling back to software volume control.", ss.channels, i+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) {
|
if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) {
|
||||||
u->sink->get_mute = sink_get_mute_cb;
|
u->sink->get_mute = sink_get_mute_cb;
|
||||||
u->sink->set_mute = sink_set_mute_cb;
|
u->sink->set_mute = sink_set_mute_cb;
|
||||||
|
|
@ -894,7 +894,7 @@ int pa__init(pa_module*m) {
|
||||||
pa_log("Failed to create thread.");
|
pa_log("Failed to create thread.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get initial mixer settings */
|
/* Get initial mixer settings */
|
||||||
if (u->sink->get_volume)
|
if (u->sink->get_volume)
|
||||||
u->sink->get_volume(u->sink);
|
u->sink->get_volume(u->sink);
|
||||||
|
|
@ -902,11 +902,11 @@ int pa__init(pa_module*m) {
|
||||||
u->sink->get_mute(u->sink);
|
u->sink->get_mute(u->sink);
|
||||||
|
|
||||||
pa_sink_put(u->sink);
|
pa_sink_put(u->sink);
|
||||||
|
|
||||||
pa_modargs_free(ma);
|
pa_modargs_free(ma);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
if (ma)
|
if (ma)
|
||||||
|
|
@ -919,7 +919,7 @@ fail:
|
||||||
|
|
||||||
void pa__done(pa_module*m) {
|
void pa__done(pa_module*m) {
|
||||||
struct userdata *u;
|
struct userdata *u;
|
||||||
|
|
||||||
pa_assert(m);
|
pa_assert(m);
|
||||||
|
|
||||||
if (!(u = m->userdata))
|
if (!(u = m->userdata))
|
||||||
|
|
@ -937,19 +937,19 @@ void pa__done(pa_module*m) {
|
||||||
|
|
||||||
if (u->sink)
|
if (u->sink)
|
||||||
pa_sink_unref(u->sink);
|
pa_sink_unref(u->sink);
|
||||||
|
|
||||||
if (u->memchunk.memblock)
|
if (u->memchunk.memblock)
|
||||||
pa_memblock_unref(u->memchunk.memblock);
|
pa_memblock_unref(u->memchunk.memblock);
|
||||||
|
|
||||||
if (u->alsa_rtpoll_item)
|
if (u->alsa_rtpoll_item)
|
||||||
pa_rtpoll_item_free(u->alsa_rtpoll_item);
|
pa_rtpoll_item_free(u->alsa_rtpoll_item);
|
||||||
|
|
||||||
if (u->rtpoll)
|
if (u->rtpoll)
|
||||||
pa_rtpoll_free(u->rtpoll);
|
pa_rtpoll_free(u->rtpoll);
|
||||||
|
|
||||||
if (u->mixer_fdl)
|
if (u->mixer_fdl)
|
||||||
pa_alsa_fdlist_free(u->mixer_fdl);
|
pa_alsa_fdlist_free(u->mixer_fdl);
|
||||||
|
|
||||||
if (u->mixer_handle)
|
if (u->mixer_handle)
|
||||||
snd_mixer_close(u->mixer_handle);
|
snd_mixer_close(u->mixer_handle);
|
||||||
|
|
||||||
|
|
@ -960,7 +960,6 @@ void pa__done(pa_module*m) {
|
||||||
|
|
||||||
pa_xfree(u->device_name);
|
pa_xfree(u->device_name);
|
||||||
pa_xfree(u);
|
pa_xfree(u);
|
||||||
|
|
||||||
snd_config_update_free_global();
|
snd_config_update_free_global();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ struct userdata {
|
||||||
pa_core *core;
|
pa_core *core;
|
||||||
pa_module *module;
|
pa_module *module;
|
||||||
pa_source *source;
|
pa_source *source;
|
||||||
|
|
||||||
pa_thread *thread;
|
pa_thread *thread;
|
||||||
pa_thread_mq thread_mq;
|
pa_thread_mq thread_mq;
|
||||||
pa_rtpoll *rtpoll;
|
pa_rtpoll *rtpoll;
|
||||||
|
|
@ -108,7 +108,7 @@ static const char* const valid_modargs[] = {
|
||||||
|
|
||||||
static int mmap_read(struct userdata *u) {
|
static int mmap_read(struct userdata *u) {
|
||||||
int work_done = 0;
|
int work_done = 0;
|
||||||
|
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
pa_source_assert_ref(u->source);
|
pa_source_assert_ref(u->source);
|
||||||
|
|
||||||
|
|
@ -119,31 +119,31 @@ static int mmap_read(struct userdata *u) {
|
||||||
snd_pcm_uframes_t offset, frames;
|
snd_pcm_uframes_t offset, frames;
|
||||||
pa_memchunk chunk;
|
pa_memchunk chunk;
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
if ((n = snd_pcm_avail_update(u->pcm_handle)) < 0) {
|
if ((n = snd_pcm_avail_update(u->pcm_handle)) < 0) {
|
||||||
|
|
||||||
if (n == -EPIPE)
|
if (n == -EPIPE)
|
||||||
pa_log_debug("snd_pcm_avail_update: Buffer underrun!");
|
pa_log_debug("snd_pcm_avail_update: Buffer underrun!");
|
||||||
|
|
||||||
if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0)
|
if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (err == -EAGAIN)
|
if (err == -EAGAIN)
|
||||||
return work_done;
|
return work_done;
|
||||||
|
|
||||||
pa_log("snd_pcm_avail_update: %s", snd_strerror(err));
|
pa_log("snd_pcm_avail_update: %s", snd_strerror(err));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pa_log("Got request for %i samples", (int) n); */
|
/* pa_log("Got request for %i samples", (int) n); */
|
||||||
|
|
||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
return work_done;
|
return work_done;
|
||||||
|
|
||||||
frames = n;
|
frames = n;
|
||||||
|
|
||||||
if ((err = snd_pcm_mmap_begin(u->pcm_handle, &areas, &offset, &frames)) < 0) {
|
if ((err = snd_pcm_mmap_begin(u->pcm_handle, &areas, &offset, &frames)) < 0) {
|
||||||
|
|
||||||
if (err == -EPIPE)
|
if (err == -EPIPE)
|
||||||
pa_log_debug("snd_pcm_mmap_begin: Buffer underrun!");
|
pa_log_debug("snd_pcm_mmap_begin: Buffer underrun!");
|
||||||
|
|
||||||
|
|
@ -166,7 +166,7 @@ static int mmap_read(struct userdata *u) {
|
||||||
pa_assert((areas[0].step >> 3) == u->frame_size);
|
pa_assert((areas[0].step >> 3) == u->frame_size);
|
||||||
|
|
||||||
p = (uint8_t*) areas[0].addr + (offset * u->frame_size);
|
p = (uint8_t*) areas[0].addr + (offset * u->frame_size);
|
||||||
|
|
||||||
chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, 1);
|
chunk.memblock = pa_memblock_new_fixed(u->core->mempool, p, frames * u->frame_size, 1);
|
||||||
chunk.length = pa_memblock_get_length(chunk.memblock);
|
chunk.length = pa_memblock_get_length(chunk.memblock);
|
||||||
chunk.index = 0;
|
chunk.index = 0;
|
||||||
|
|
@ -181,13 +181,13 @@ static int mmap_read(struct userdata *u) {
|
||||||
|
|
||||||
if (err == -EPIPE)
|
if (err == -EPIPE)
|
||||||
pa_log_debug("snd_pcm_mmap_commit: Buffer underrun!");
|
pa_log_debug("snd_pcm_mmap_commit: Buffer underrun!");
|
||||||
|
|
||||||
if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0)
|
if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (err == -EAGAIN)
|
if (err == -EAGAIN)
|
||||||
return work_done;
|
return work_done;
|
||||||
|
|
||||||
pa_log("Failed to write data to DSP: %s", snd_strerror(err));
|
pa_log("Failed to write data to DSP: %s", snd_strerror(err));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -213,7 +213,7 @@ static int unix_read(struct userdata *u) {
|
||||||
ssize_t l;
|
ssize_t l;
|
||||||
int err;
|
int err;
|
||||||
pa_memchunk chunk;
|
pa_memchunk chunk;
|
||||||
|
|
||||||
if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) {
|
if ((err = snd_pcm_status(u->pcm_handle, status)) < 0) {
|
||||||
pa_log("Failed to query DSP status data: %s", snd_strerror(err));
|
pa_log("Failed to query DSP status data: %s", snd_strerror(err));
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -221,12 +221,12 @@ static int unix_read(struct userdata *u) {
|
||||||
|
|
||||||
if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size)
|
if (snd_pcm_status_get_avail_max(status)*u->frame_size >= u->hwbuf_size)
|
||||||
pa_log_debug("Buffer overrun!");
|
pa_log_debug("Buffer overrun!");
|
||||||
|
|
||||||
l = snd_pcm_status_get_avail(status) * u->frame_size;
|
l = snd_pcm_status_get_avail(status) * u->frame_size;
|
||||||
|
|
||||||
if (l <= 0)
|
if (l <= 0)
|
||||||
return work_done;
|
return work_done;
|
||||||
|
|
||||||
chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1);
|
chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1);
|
||||||
|
|
||||||
k = pa_memblock_get_length(chunk.memblock);
|
k = pa_memblock_get_length(chunk.memblock);
|
||||||
|
|
@ -239,17 +239,17 @@ static int unix_read(struct userdata *u) {
|
||||||
p = pa_memblock_acquire(chunk.memblock);
|
p = pa_memblock_acquire(chunk.memblock);
|
||||||
t = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, k / u->frame_size);
|
t = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, k / u->frame_size);
|
||||||
pa_memblock_release(chunk.memblock);
|
pa_memblock_release(chunk.memblock);
|
||||||
|
|
||||||
/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */
|
/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size, u->memchunk.length, l); */
|
||||||
|
|
||||||
pa_assert(t != 0);
|
pa_assert(t != 0);
|
||||||
|
|
||||||
if (t < 0) {
|
if (t < 0) {
|
||||||
pa_memblock_unref(chunk.memblock);
|
pa_memblock_unref(chunk.memblock);
|
||||||
|
|
||||||
if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0)
|
if ((t = snd_pcm_recover(u->pcm_handle, t, 1)) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (t == -EAGAIN) {
|
if (t == -EAGAIN) {
|
||||||
pa_log_debug("EAGAIN");
|
pa_log_debug("EAGAIN");
|
||||||
return work_done;
|
return work_done;
|
||||||
|
|
@ -257,14 +257,14 @@ static int unix_read(struct userdata *u) {
|
||||||
pa_log("Failed to read data from DSP: %s", snd_strerror(t));
|
pa_log("Failed to read data from DSP: %s", snd_strerror(t));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chunk.index = 0;
|
chunk.index = 0;
|
||||||
chunk.length = t * u->frame_size;
|
chunk.length = t * u->frame_size;
|
||||||
|
|
||||||
pa_source_post(u->source, &chunk);
|
pa_source_post(u->source, &chunk);
|
||||||
pa_memblock_unref(chunk.memblock);
|
pa_memblock_unref(chunk.memblock);
|
||||||
|
|
||||||
work_done = 1;
|
work_done = 1;
|
||||||
|
|
||||||
if (t * u->frame_size >= (unsigned) l)
|
if (t * u->frame_size >= (unsigned) l)
|
||||||
|
|
@ -279,11 +279,11 @@ static pa_usec_t source_get_latency(struct userdata *u) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
snd_pcm_status_alloca(&status);
|
snd_pcm_status_alloca(&status);
|
||||||
|
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
pa_assert(u->pcm_handle);
|
pa_assert(u->pcm_handle);
|
||||||
|
|
||||||
if ((err = snd_pcm_status(u->pcm_handle, status)) < 0)
|
if ((err = snd_pcm_status(u->pcm_handle, status)) < 0)
|
||||||
pa_log("Failed to get delay: %s", snd_strerror(err));
|
pa_log("Failed to get delay: %s", snd_strerror(err));
|
||||||
else
|
else
|
||||||
frames = snd_pcm_status_get_delay(status);
|
frames = snd_pcm_status_get_delay(status);
|
||||||
|
|
@ -298,7 +298,7 @@ static int build_pollfd(struct userdata *u) {
|
||||||
int err;
|
int err;
|
||||||
struct pollfd *pollfd;
|
struct pollfd *pollfd;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
pa_assert(u->pcm_handle);
|
pa_assert(u->pcm_handle);
|
||||||
|
|
||||||
|
|
@ -312,12 +312,12 @@ static int build_pollfd(struct userdata *u) {
|
||||||
|
|
||||||
u->alsa_rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, n);
|
u->alsa_rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, n);
|
||||||
pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, NULL);
|
pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, NULL);
|
||||||
|
|
||||||
if ((err = snd_pcm_poll_descriptors(u->pcm_handle, pollfd, n)) < 0) {
|
if ((err = snd_pcm_poll_descriptors(u->pcm_handle, pollfd, n)) < 0) {
|
||||||
pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err));
|
pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,9 +333,9 @@ static int suspend(struct userdata *u) {
|
||||||
pa_rtpoll_item_free(u->alsa_rtpoll_item);
|
pa_rtpoll_item_free(u->alsa_rtpoll_item);
|
||||||
u->alsa_rtpoll_item = NULL;
|
u->alsa_rtpoll_item = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_log_info("Device suspended...");
|
pa_log_info("Device suspended...");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -360,7 +360,7 @@ static int unsuspend(struct userdata *u) {
|
||||||
nfrags = u->nfragments;
|
nfrags = u->nfragments;
|
||||||
period_size = u->fragment_size / u->frame_size;
|
period_size = u->fragment_size / u->frame_size;
|
||||||
b = u->use_mmap;
|
b = u->use_mmap;
|
||||||
|
|
||||||
if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) {
|
if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) {
|
||||||
pa_log("Failed to set hardware parameters: %s", snd_strerror(err));
|
pa_log("Failed to set hardware parameters: %s", snd_strerror(err));
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -370,7 +370,7 @@ static int unsuspend(struct userdata *u) {
|
||||||
pa_log_warn("Resume failed, couldn't get original access mode.");
|
pa_log_warn("Resume failed, couldn't get original access mode.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pa_sample_spec_equal(&ss, &u->source->sample_spec)) {
|
if (!pa_sample_spec_equal(&ss, &u->source->sample_spec)) {
|
||||||
pa_log_warn("Resume failed, couldn't restore original sample settings.");
|
pa_log_warn("Resume failed, couldn't restore original sample settings.");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -388,11 +388,11 @@ static int unsuspend(struct userdata *u) {
|
||||||
|
|
||||||
if (build_pollfd(u) < 0)
|
if (build_pollfd(u) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
snd_pcm_start(u->pcm_handle);
|
snd_pcm_start(u->pcm_handle);
|
||||||
|
|
||||||
/* FIXME: We need to reload the volume somehow */
|
/* FIXME: We need to reload the volume somehow */
|
||||||
|
|
||||||
pa_log_info("Resumed successfully...");
|
pa_log_info("Resumed successfully...");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -425,13 +425,13 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
|
||||||
case PA_SOURCE_MESSAGE_SET_STATE:
|
case PA_SOURCE_MESSAGE_SET_STATE:
|
||||||
|
|
||||||
switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
|
switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
|
||||||
|
|
||||||
case PA_SOURCE_SUSPENDED:
|
case PA_SOURCE_SUSPENDED:
|
||||||
pa_assert(PA_SOURCE_OPENED(u->source->thread_info.state));
|
pa_assert(PA_SOURCE_OPENED(u->source->thread_info.state));
|
||||||
|
|
||||||
if (suspend(u) < 0)
|
if (suspend(u) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PA_SOURCE_IDLE:
|
case PA_SOURCE_IDLE:
|
||||||
|
|
@ -441,14 +441,14 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
|
||||||
if (unsuspend(u) < 0)
|
if (unsuspend(u) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PA_SOURCE_UNLINKED:
|
case PA_SOURCE_UNLINKED:
|
||||||
case PA_SOURCE_INIT:
|
case PA_SOURCE_INIT:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -499,7 +499,7 @@ static int source_get_volume_cb(pa_source *s) {
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
pa_log_error("Unable to read volume: %s", snd_strerror(err));
|
pa_log_error("Unable to read volume: %s", snd_strerror(err));
|
||||||
|
|
||||||
s->get_volume = NULL;
|
s->get_volume = NULL;
|
||||||
s->set_volume = NULL;
|
s->set_volume = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -534,7 +534,7 @@ static int source_set_volume_cb(pa_source *s) {
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
pa_log_error("Unable to set volume: %s", snd_strerror(err));
|
pa_log_error("Unable to set volume: %s", snd_strerror(err));
|
||||||
|
|
||||||
s->get_volume = NULL;
|
s->get_volume = NULL;
|
||||||
s->set_volume = NULL;
|
s->set_volume = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -569,7 +569,7 @@ static int source_set_mute_cb(pa_source *s) {
|
||||||
|
|
||||||
if ((err = snd_mixer_selem_set_capture_switch_all(u->mixer_elem, !s->muted)) < 0) {
|
if ((err = snd_mixer_selem_set_capture_switch_all(u->mixer_elem, !s->muted)) < 0) {
|
||||||
pa_log_error("Unable to set switch: %s", snd_strerror(err));
|
pa_log_error("Unable to set switch: %s", snd_strerror(err));
|
||||||
|
|
||||||
s->get_mute = NULL;
|
s->get_mute = NULL;
|
||||||
s->set_mute = NULL;
|
s->set_mute = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -590,18 +590,18 @@ static void thread_func(void *userdata) {
|
||||||
|
|
||||||
pa_thread_mq_install(&u->thread_mq);
|
pa_thread_mq_install(&u->thread_mq);
|
||||||
pa_rtpoll_install(u->rtpoll);
|
pa_rtpoll_install(u->rtpoll);
|
||||||
|
|
||||||
if (build_pollfd(u) < 0)
|
if (build_pollfd(u) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
snd_pcm_start(u->pcm_handle);
|
snd_pcm_start(u->pcm_handle);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Read some data and pass it to the sources */
|
/* Read some data and pass it to the sources */
|
||||||
if (PA_SOURCE_OPENED(u->source->thread_info.state)) {
|
if (PA_SOURCE_OPENED(u->source->thread_info.state)) {
|
||||||
|
|
||||||
if (u->use_mmap) {
|
if (u->use_mmap) {
|
||||||
if (mmap_read(u) < 0)
|
if (mmap_read(u) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -618,7 +618,7 @@ static void thread_func(void *userdata) {
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
/* Tell ALSA about this and process its response */
|
/* Tell ALSA about this and process its response */
|
||||||
if (PA_SOURCE_OPENED(u->source->thread_info.state)) {
|
if (PA_SOURCE_OPENED(u->source->thread_info.state)) {
|
||||||
struct pollfd *pollfd;
|
struct pollfd *pollfd;
|
||||||
|
|
@ -627,7 +627,7 @@ static void thread_func(void *userdata) {
|
||||||
unsigned n;
|
unsigned n;
|
||||||
|
|
||||||
pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, &n);
|
pollfd = pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, &n);
|
||||||
|
|
||||||
if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd, n, &revents)) < 0) {
|
if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd, n, &revents)) < 0) {
|
||||||
pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err));
|
pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err));
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -637,7 +637,7 @@ static void thread_func(void *userdata) {
|
||||||
if (revents & POLLERR)
|
if (revents & POLLERR)
|
||||||
pa_log_warn("Got POLLERR from ALSA");
|
pa_log_warn("Got POLLERR from ALSA");
|
||||||
if (revents & POLLNVAL)
|
if (revents & POLLNVAL)
|
||||||
pa_log_warn("Got POLLNVAL from ALSA");
|
pa_log_warn("Got POLLNVAL from ALSA");
|
||||||
if (revents & POLLHUP)
|
if (revents & POLLHUP)
|
||||||
pa_log_warn("Got POLLHUP from ALSA");
|
pa_log_warn("Got POLLHUP from ALSA");
|
||||||
|
|
||||||
|
|
@ -657,7 +657,7 @@ finish:
|
||||||
}
|
}
|
||||||
|
|
||||||
int pa__init(pa_module*m) {
|
int pa__init(pa_module*m) {
|
||||||
|
|
||||||
pa_modargs *ma = NULL;
|
pa_modargs *ma = NULL;
|
||||||
struct userdata *u = NULL;
|
struct userdata *u = NULL;
|
||||||
char *dev;
|
char *dev;
|
||||||
|
|
@ -677,7 +677,7 @@ int pa__init(pa_module*m) {
|
||||||
snd_pcm_info_alloca(&pcm_info);
|
snd_pcm_info_alloca(&pcm_info);
|
||||||
|
|
||||||
pa_assert(m);
|
pa_assert(m);
|
||||||
|
|
||||||
if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
|
if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
|
||||||
pa_log("Failed to parse module arguments");
|
pa_log("Failed to parse module arguments");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -706,7 +706,7 @@ int pa__init(pa_module*m) {
|
||||||
pa_log("Failed to parse mmap argument.");
|
pa_log("Failed to parse mmap argument.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
u = pa_xnew0(struct userdata, 1);
|
u = pa_xnew0(struct userdata, 1);
|
||||||
u->core = m->core;
|
u->core = m->core;
|
||||||
u->module = m;
|
u->module = m;
|
||||||
|
|
@ -720,9 +720,9 @@ int pa__init(pa_module*m) {
|
||||||
snd_config_update_free_global();
|
snd_config_update_free_global();
|
||||||
|
|
||||||
dev = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE));
|
dev = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE));
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if ((err = snd_pcm_open(&u->pcm_handle, dev, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) {
|
if ((err = snd_pcm_open(&u->pcm_handle, dev, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) {
|
||||||
pa_log("Error opening PCM device %s: %s", dev, snd_strerror(err));
|
pa_log("Error opening PCM device %s: %s", dev, snd_strerror(err));
|
||||||
pa_xfree(dev);
|
pa_xfree(dev);
|
||||||
|
|
@ -734,7 +734,7 @@ int pa__init(pa_module*m) {
|
||||||
|
|
||||||
if (err == -EPERM) {
|
if (err == -EPERM) {
|
||||||
/* Hmm, some hw is very exotic, so we retry with plughw, if hw didn't work */
|
/* Hmm, some hw is very exotic, so we retry with plughw, if hw didn't work */
|
||||||
|
|
||||||
if (pa_startswith(dev, "hw:")) {
|
if (pa_startswith(dev, "hw:")) {
|
||||||
char *d = pa_sprintf_malloc("plughw:%s", dev+3);
|
char *d = pa_sprintf_malloc("plughw:%s", dev+3);
|
||||||
pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", dev, d);
|
pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", dev, d);
|
||||||
|
|
@ -746,7 +746,7 @@ int pa__init(pa_module*m) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_log("Failed to set hardware parameters: %s", snd_strerror(err));
|
pa_log("Failed to set hardware parameters: %s", snd_strerror(err));
|
||||||
pa_xfree(dev);
|
pa_xfree(dev);
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -756,7 +756,7 @@ int pa__init(pa_module*m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
u->device_name = dev;
|
u->device_name = dev;
|
||||||
|
|
||||||
if (use_mmap && !b) {
|
if (use_mmap && !b) {
|
||||||
pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
|
pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
|
||||||
u->use_mmap = use_mmap = b;
|
u->use_mmap = use_mmap = b;
|
||||||
|
|
@ -774,7 +774,7 @@ int pa__init(pa_module*m) {
|
||||||
pa_log("Failed to set software parameters: %s", snd_strerror(err));
|
pa_log("Failed to set software parameters: %s", snd_strerror(err));
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ALSA might tweak the sample spec, so recalculate the frame size */
|
/* ALSA might tweak the sample spec, so recalculate the frame size */
|
||||||
frame_size = pa_frame_size(&ss);
|
frame_size = pa_frame_size(&ss);
|
||||||
|
|
||||||
|
|
@ -785,7 +785,7 @@ int pa__init(pa_module*m) {
|
||||||
if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0)
|
if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0)
|
||||||
pa_log("Error opening mixer: %s", snd_strerror(err));
|
pa_log("Error opening mixer: %s", snd_strerror(err));
|
||||||
else {
|
else {
|
||||||
|
|
||||||
if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) ||
|
if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) ||
|
||||||
!(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Capture", NULL))) {
|
!(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Capture", NULL))) {
|
||||||
snd_mixer_close(u->mixer_handle);
|
snd_mixer_close(u->mixer_handle);
|
||||||
|
|
@ -802,7 +802,7 @@ int pa__init(pa_module*m) {
|
||||||
|
|
||||||
u->source = pa_source_new(m->core, __FILE__, name, namereg_fail, &ss, &map);
|
u->source = pa_source_new(m->core, __FILE__, name, namereg_fail, &ss, &map);
|
||||||
pa_xfree(name_buf);
|
pa_xfree(name_buf);
|
||||||
|
|
||||||
if (!u->source) {
|
if (!u->source) {
|
||||||
pa_log("Failed to create source object");
|
pa_log("Failed to create source object");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -821,7 +821,7 @@ int pa__init(pa_module*m) {
|
||||||
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_LATENCY|PA_SOURCE_HW_VOLUME_CTRL;
|
||||||
|
|
||||||
u->frame_size = frame_size;
|
u->frame_size = frame_size;
|
||||||
u->fragment_size = frag_size = period_size * frame_size;
|
u->fragment_size = frag_size = period_size * frame_size;
|
||||||
|
|
@ -832,7 +832,7 @@ int pa__init(pa_module*m) {
|
||||||
|
|
||||||
if (u->mixer_handle) {
|
if (u->mixer_handle) {
|
||||||
pa_assert(u->mixer_elem);
|
pa_assert(u->mixer_elem);
|
||||||
|
|
||||||
if (snd_mixer_selem_has_capture_volume(u->mixer_elem)) {
|
if (snd_mixer_selem_has_capture_volume(u->mixer_elem)) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
@ -847,19 +847,19 @@ int pa__init(pa_module*m) {
|
||||||
snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max);
|
snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snd_mixer_selem_has_capture_switch(u->mixer_elem)) {
|
if (snd_mixer_selem_has_capture_switch(u->mixer_elem)) {
|
||||||
u->source->get_mute = source_get_mute_cb;
|
u->source->get_mute = source_get_mute_cb;
|
||||||
u->source->set_mute = source_set_mute_cb;
|
u->source->set_mute = source_set_mute_cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
u->mixer_fdl = pa_alsa_fdlist_new();
|
u->mixer_fdl = pa_alsa_fdlist_new();
|
||||||
|
|
||||||
if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, m->core->mainloop) < 0) {
|
if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, m->core->mainloop) < 0) {
|
||||||
pa_log("failed to initialise file descriptor monitoring");
|
pa_log("failed to initialise file descriptor monitoring");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_mixer_elem_set_callback(u->mixer_elem, mixer_callback);
|
snd_mixer_elem_set_callback(u->mixer_elem, mixer_callback);
|
||||||
snd_mixer_elem_set_callback_private(u->mixer_elem, u);
|
snd_mixer_elem_set_callback_private(u->mixer_elem, u);
|
||||||
} else
|
} else
|
||||||
|
|
@ -875,25 +875,25 @@ int pa__init(pa_module*m) {
|
||||||
if (u->source->get_mute)
|
if (u->source->get_mute)
|
||||||
u->source->get_mute(u->source);
|
u->source->get_mute(u->source);
|
||||||
|
|
||||||
pa_source_put(u->source);
|
pa_source_put(u->source);
|
||||||
|
|
||||||
pa_modargs_free(ma);
|
pa_modargs_free(ma);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
if (ma)
|
if (ma)
|
||||||
pa_modargs_free(ma);
|
pa_modargs_free(ma);
|
||||||
|
|
||||||
pa__done(m);
|
pa__done(m);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pa__done(pa_module*m) {
|
void pa__done(pa_module*m) {
|
||||||
struct userdata *u;
|
struct userdata *u;
|
||||||
|
|
||||||
pa_assert(m);
|
pa_assert(m);
|
||||||
|
|
||||||
if (!(u = m->userdata))
|
if (!(u = m->userdata))
|
||||||
|
|
@ -914,10 +914,10 @@ void pa__done(pa_module*m) {
|
||||||
|
|
||||||
if (u->alsa_rtpoll_item)
|
if (u->alsa_rtpoll_item)
|
||||||
pa_rtpoll_item_free(u->alsa_rtpoll_item);
|
pa_rtpoll_item_free(u->alsa_rtpoll_item);
|
||||||
|
|
||||||
if (u->rtpoll)
|
if (u->rtpoll)
|
||||||
pa_rtpoll_free(u->rtpoll);
|
pa_rtpoll_free(u->rtpoll);
|
||||||
|
|
||||||
if (u->mixer_fdl)
|
if (u->mixer_fdl)
|
||||||
pa_alsa_fdlist_free(u->mixer_fdl);
|
pa_alsa_fdlist_free(u->mixer_fdl);
|
||||||
|
|
||||||
|
|
@ -934,4 +934,3 @@ void pa__done(pa_module*m) {
|
||||||
|
|
||||||
snd_config_update_free_global();
|
snd_config_update_free_global();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1134,7 +1134,7 @@ int pa__init(pa_module*m) {
|
||||||
u->sink->set_state = sink_set_state;
|
u->sink->set_state = sink_set_state;
|
||||||
u->sink->userdata = u;
|
u->sink->userdata = u;
|
||||||
|
|
||||||
u->sink->flags = PA_SINK_CAN_SUSPEND|PA_SINK_LATENCY;
|
u->sink->flags = PA_SINK_LATENCY;
|
||||||
pa_sink_set_module(u->sink, m);
|
pa_sink_set_module(u->sink, m);
|
||||||
pa_sink_set_description(u->sink, "Simultaneous output");
|
pa_sink_set_description(u->sink, "Simultaneous output");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -568,7 +568,7 @@ int pa__init(pa_module*m) {
|
||||||
u->sink->parent.process_msg = sink_process_msg;
|
u->sink->parent.process_msg = sink_process_msg;
|
||||||
u->sink->set_state = sink_set_state;
|
u->sink->set_state = sink_set_state;
|
||||||
u->sink->userdata = u;
|
u->sink->userdata = u;
|
||||||
u->sink->flags = PA_SINK_LATENCY|PA_SINK_CAN_SUSPEND;
|
u->sink->flags = PA_SINK_LATENCY;
|
||||||
|
|
||||||
pa_sink_set_module(u->sink, m);
|
pa_sink_set_module(u->sink, m);
|
||||||
pa_sink_set_description(u->sink, t = pa_sprintf_malloc("LADSPA plugin '%s' on '%s'", label, master->description));
|
pa_sink_set_description(u->sink, t = pa_sprintf_malloc("LADSPA plugin '%s' on '%s'", label, master->description));
|
||||||
|
|
|
||||||
|
|
@ -1243,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;
|
u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY;
|
||||||
u->source->refresh_volume = 1;
|
u->source->refresh_volume = 1;
|
||||||
|
|
||||||
if (use_mmap)
|
if (use_mmap)
|
||||||
|
|
@ -1298,7 +1298,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->sink->flags = PA_SINK_HARDWARE|PA_SINK_CAN_SUSPEND|PA_SINK_LATENCY;
|
u->sink->flags = PA_SINK_HARDWARE|PA_SINK_LATENCY;
|
||||||
u->sink->refresh_volume = 1;
|
u->sink->refresh_volume = 1;
|
||||||
|
|
||||||
if (use_mmap)
|
if (use_mmap)
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ int pa__init(pa_module*m) {
|
||||||
u->sink->parent.process_msg = sink_process_msg;
|
u->sink->parent.process_msg = sink_process_msg;
|
||||||
u->sink->set_state = sink_set_state;
|
u->sink->set_state = sink_set_state;
|
||||||
u->sink->userdata = u;
|
u->sink->userdata = u;
|
||||||
u->sink->flags = PA_SINK_LATENCY|PA_SINK_CAN_SUSPEND;
|
u->sink->flags = PA_SINK_LATENCY;
|
||||||
|
|
||||||
pa_sink_set_module(u->sink, m);
|
pa_sink_set_module(u->sink, m);
|
||||||
pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Remapped %s", master->description));
|
pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Remapped %s", master->description));
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ struct userdata {
|
||||||
*source_unlink_slot,
|
*source_unlink_slot,
|
||||||
*sink_state_changed_slot,
|
*sink_state_changed_slot,
|
||||||
*source_state_changed_slot;
|
*source_state_changed_slot;
|
||||||
|
|
||||||
pa_hook_slot
|
pa_hook_slot
|
||||||
*sink_input_new_slot,
|
*sink_input_new_slot,
|
||||||
*source_output_new_slot,
|
*source_output_new_slot,
|
||||||
|
|
@ -83,7 +83,7 @@ static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval
|
||||||
pa_assert(d);
|
pa_assert(d);
|
||||||
|
|
||||||
d->userdata->core->mainloop->time_restart(d->time_event, NULL);
|
d->userdata->core->mainloop->time_restart(d->time_event, NULL);
|
||||||
|
|
||||||
if (d->sink && pa_sink_used_by(d->sink) <= 0 && pa_sink_get_state(d->sink) != PA_SINK_SUSPENDED) {
|
if (d->sink && pa_sink_used_by(d->sink) <= 0 && pa_sink_get_state(d->sink) != PA_SINK_SUSPENDED) {
|
||||||
pa_log_info("Sink %s idle for too long, suspending ...", d->sink->name);
|
pa_log_info("Sink %s idle for too long, suspending ...", d->sink->name);
|
||||||
pa_sink_suspend(d->sink, 1);
|
pa_sink_suspend(d->sink, 1);
|
||||||
|
|
@ -119,7 +119,7 @@ static void resume(struct device_info *d) {
|
||||||
if (d->sink) {
|
if (d->sink) {
|
||||||
pa_sink_suspend(d->sink, 0);
|
pa_sink_suspend(d->sink, 0);
|
||||||
pa_source_suspend(d->sink->monitor_source, 0);
|
pa_source_suspend(d->sink->monitor_source, 0);
|
||||||
|
|
||||||
pa_log_debug("Sink %s becomes busy.", d->sink->name);
|
pa_log_debug("Sink %s becomes busy.", d->sink->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,14 +134,14 @@ static void resume(struct device_info *d) {
|
||||||
|
|
||||||
static pa_hook_result_t sink_input_new_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) {
|
static pa_hook_result_t sink_input_new_hook_cb(pa_core *c, pa_sink_input *s, struct userdata *u) {
|
||||||
struct device_info *d;
|
struct device_info *d;
|
||||||
|
|
||||||
pa_assert(c);
|
pa_assert(c);
|
||||||
pa_sink_input_assert_ref(s);
|
pa_sink_input_assert_ref(s);
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
|
|
||||||
if ((d = pa_hashmap_get(u->device_infos, s->sink)))
|
if ((d = pa_hashmap_get(u->device_infos, s->sink)))
|
||||||
resume(d);
|
resume(d);
|
||||||
|
|
||||||
return PA_HOOK_OK;
|
return PA_HOOK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,10 +151,10 @@ static pa_hook_result_t source_output_new_hook_cb(pa_core *c, pa_source_output *
|
||||||
pa_assert(c);
|
pa_assert(c);
|
||||||
pa_source_output_assert_ref(s);
|
pa_source_output_assert_ref(s);
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
|
|
||||||
if ((d = pa_hashmap_get(u->device_infos, s->source)))
|
if ((d = pa_hashmap_get(u->device_infos, s->source)))
|
||||||
resume(d);
|
resume(d);
|
||||||
|
|
||||||
return PA_HOOK_OK;
|
return PA_HOOK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,7 +168,7 @@ static pa_hook_result_t sink_input_unlink_hook_cb(pa_core *c, pa_sink_input *s,
|
||||||
if ((d = pa_hashmap_get(u->device_infos, s->sink)))
|
if ((d = pa_hashmap_get(u->device_infos, s->sink)))
|
||||||
restart(d);
|
restart(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PA_HOOK_OK;
|
return PA_HOOK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -182,7 +182,7 @@ static pa_hook_result_t source_output_unlink_hook_cb(pa_core *c, pa_source_outpu
|
||||||
if ((d = pa_hashmap_get(u->device_infos, s->source)))
|
if ((d = pa_hashmap_get(u->device_infos, s->source)))
|
||||||
restart(d);
|
restart(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PA_HOOK_OK;
|
return PA_HOOK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,7 +196,7 @@ static pa_hook_result_t sink_input_move_hook_cb(pa_core *c, pa_sink_input *s, st
|
||||||
if ((d = pa_hashmap_get(u->device_infos, s->sink)))
|
if ((d = pa_hashmap_get(u->device_infos, s->sink)))
|
||||||
restart(d);
|
restart(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PA_HOOK_OK;
|
return PA_HOOK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,7 +208,7 @@ static pa_hook_result_t sink_input_move_post_hook_cb(pa_core *c, pa_sink_input *
|
||||||
|
|
||||||
if ((d = pa_hashmap_get(u->device_infos, s->sink)))
|
if ((d = pa_hashmap_get(u->device_infos, s->sink)))
|
||||||
resume(d);
|
resume(d);
|
||||||
|
|
||||||
return PA_HOOK_OK;
|
return PA_HOOK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,7 +223,7 @@ static pa_hook_result_t source_output_move_hook_cb(pa_core *c, pa_source_output
|
||||||
if ((d = pa_hashmap_get(u->device_infos, s->source)))
|
if ((d = pa_hashmap_get(u->device_infos, s->source)))
|
||||||
restart(d);
|
restart(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PA_HOOK_OK;
|
return PA_HOOK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,7 +235,7 @@ static pa_hook_result_t source_output_move_post_hook_cb(pa_core *c, pa_source_ou
|
||||||
|
|
||||||
if ((d = pa_hashmap_get(u->device_infos, s->source)))
|
if ((d = pa_hashmap_get(u->device_infos, s->source)))
|
||||||
resume(d);
|
resume(d);
|
||||||
|
|
||||||
return PA_HOOK_OK;
|
return PA_HOOK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -243,7 +243,7 @@ static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct user
|
||||||
struct device_info *d;
|
struct device_info *d;
|
||||||
pa_source *source;
|
pa_source *source;
|
||||||
pa_sink *sink;
|
pa_sink *sink;
|
||||||
|
|
||||||
pa_assert(c);
|
pa_assert(c);
|
||||||
pa_object_assert_ref(o);
|
pa_object_assert_ref(o);
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
|
|
@ -252,12 +252,6 @@ static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct user
|
||||||
sink = pa_sink_isinstance(o) ? PA_SINK(o) : NULL;
|
sink = pa_sink_isinstance(o) ? PA_SINK(o) : NULL;
|
||||||
|
|
||||||
pa_assert(source || sink);
|
pa_assert(source || sink);
|
||||||
|
|
||||||
if (source && !(source->flags & PA_SOURCE_CAN_SUSPEND))
|
|
||||||
return PA_HOOK_OK;
|
|
||||||
|
|
||||||
if (sink && !(sink->flags & PA_SINK_CAN_SUSPEND))
|
|
||||||
return PA_HOOK_OK;
|
|
||||||
|
|
||||||
d = pa_xnew(struct device_info, 1);
|
d = pa_xnew(struct device_info, 1);
|
||||||
d->userdata = u;
|
d->userdata = u;
|
||||||
|
|
@ -275,20 +269,20 @@ static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct user
|
||||||
|
|
||||||
static void device_info_free(struct device_info *d) {
|
static void device_info_free(struct device_info *d) {
|
||||||
pa_assert(d);
|
pa_assert(d);
|
||||||
|
|
||||||
if (d->source)
|
if (d->source)
|
||||||
pa_source_unref(d->source);
|
pa_source_unref(d->source);
|
||||||
if (d->sink)
|
if (d->sink)
|
||||||
pa_sink_unref(d->sink);
|
pa_sink_unref(d->sink);
|
||||||
|
|
||||||
d->userdata->core->mainloop->time_free(d->time_event);
|
d->userdata->core->mainloop->time_free(d->time_event);
|
||||||
|
|
||||||
pa_xfree(d);
|
pa_xfree(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
static pa_hook_result_t device_unlink_hook_cb(pa_core *c, pa_object *o, struct userdata *u) {
|
static pa_hook_result_t device_unlink_hook_cb(pa_core *c, pa_object *o, struct userdata *u) {
|
||||||
struct device_info *d;
|
struct device_info *d;
|
||||||
|
|
||||||
pa_assert(c);
|
pa_assert(c);
|
||||||
pa_object_assert_ref(o);
|
pa_object_assert_ref(o);
|
||||||
pa_assert(u);
|
pa_assert(u);
|
||||||
|
|
@ -311,14 +305,14 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s
|
||||||
|
|
||||||
if (pa_sink_isinstance(o)) {
|
if (pa_sink_isinstance(o)) {
|
||||||
pa_sink *s = PA_SINK(o);
|
pa_sink *s = PA_SINK(o);
|
||||||
|
|
||||||
if (pa_sink_used_by(s) <= 0) {
|
if (pa_sink_used_by(s) <= 0) {
|
||||||
pa_sink_state_t state = pa_sink_get_state(s);
|
pa_sink_state_t state = pa_sink_get_state(s);
|
||||||
|
|
||||||
if (state == PA_SINK_RUNNING || state == PA_SINK_IDLE)
|
if (state == PA_SINK_RUNNING || state == PA_SINK_IDLE)
|
||||||
restart(d);
|
restart(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (pa_source_isinstance(o)) {
|
} else if (pa_source_isinstance(o)) {
|
||||||
pa_source *s = PA_SOURCE(o);
|
pa_source *s = PA_SOURCE(o);
|
||||||
|
|
||||||
|
|
@ -329,7 +323,7 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s
|
||||||
restart(d);
|
restart(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PA_HOOK_OK;
|
return PA_HOOK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -352,7 +346,7 @@ int pa__init(pa_module*m) {
|
||||||
pa_log("Failed to parse timeout value.");
|
pa_log("Failed to parse timeout value.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->userdata = u = pa_xnew(struct userdata, 1);
|
m->userdata = u = pa_xnew(struct userdata, 1);
|
||||||
u->core = m->core;
|
u->core = m->core;
|
||||||
u->timeout = timeout;
|
u->timeout = timeout;
|
||||||
|
|
@ -380,29 +374,29 @@ int pa__init(pa_module*m) {
|
||||||
u->sink_input_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_POST], (pa_hook_cb_t) sink_input_move_post_hook_cb, u);
|
u->sink_input_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_POST], (pa_hook_cb_t) sink_input_move_post_hook_cb, u);
|
||||||
u->source_output_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_POST], (pa_hook_cb_t) source_output_move_post_hook_cb, u);
|
u->source_output_move_post_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_POST], (pa_hook_cb_t) source_output_move_post_hook_cb, u);
|
||||||
|
|
||||||
|
|
||||||
pa_modargs_free(ma);
|
pa_modargs_free(ma);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
||||||
if (ma)
|
if (ma)
|
||||||
pa_modargs_free(ma);
|
pa_modargs_free(ma);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pa__done(pa_module*m) {
|
void pa__done(pa_module*m) {
|
||||||
struct userdata *u;
|
struct userdata *u;
|
||||||
struct device_info *d;
|
struct device_info *d;
|
||||||
|
|
||||||
pa_assert(m);
|
pa_assert(m);
|
||||||
|
|
||||||
if (!m->userdata)
|
if (!m->userdata)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u = m->userdata;
|
u = m->userdata;
|
||||||
|
|
||||||
if (u->sink_new_slot)
|
if (u->sink_new_slot)
|
||||||
pa_hook_slot_free(u->sink_new_slot);
|
pa_hook_slot_free(u->sink_new_slot);
|
||||||
if (u->sink_unlink_slot)
|
if (u->sink_unlink_slot)
|
||||||
|
|
@ -439,6 +433,6 @@ void pa__done(pa_module*m) {
|
||||||
device_info_free(d);
|
device_info_free(d);
|
||||||
|
|
||||||
pa_hashmap_free(u->device_infos, NULL, NULL);
|
pa_hashmap_free(u->device_infos, NULL, NULL);
|
||||||
|
|
||||||
pa_xfree(u);
|
pa_xfree(u);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -300,16 +300,14 @@ typedef enum pa_seek_mode {
|
||||||
typedef enum pa_sink_flags {
|
typedef enum pa_sink_flags {
|
||||||
PA_SINK_HW_VOLUME_CTRL = 1, /**< Supports hardware volume control */
|
PA_SINK_HW_VOLUME_CTRL = 1, /**< Supports hardware volume control */
|
||||||
PA_SINK_LATENCY = 2, /**< Supports latency querying */
|
PA_SINK_LATENCY = 2, /**< Supports latency querying */
|
||||||
PA_SINK_HARDWARE = 4, /**< Is a hardware sink of some kind, in contrast to "virtual"/software sinks \since 0.9.3 */
|
PA_SINK_HARDWARE = 4 /**< Is a hardware sink of some kind, in contrast to "virtual"/software sinks \since 0.9.3 */
|
||||||
PA_SINK_CAN_SUSPEND = 8 /**< Can suspend \since 0.9.7 */
|
|
||||||
} pa_sink_flags_t;
|
} pa_sink_flags_t;
|
||||||
|
|
||||||
/** Special source flags. \since 0.8 */
|
/** Special source flags. \since 0.8 */
|
||||||
typedef enum pa_source_flags {
|
typedef enum pa_source_flags {
|
||||||
PA_SOURCE_HW_VOLUME_CTRL = 1, /**< Supports hardware volume control */
|
PA_SOURCE_HW_VOLUME_CTRL = 1, /**< Supports hardware volume control */
|
||||||
PA_SOURCE_LATENCY = 2, /**< Supports latency querying */
|
PA_SOURCE_LATENCY = 2, /**< Supports latency querying */
|
||||||
PA_SOURCE_HARDWARE = 4, /**< Is a hardware source of some kind, in contrast to "virtual"/software source \since 0.9.3 */
|
PA_SOURCE_HARDWARE = 4 /**< Is a hardware source of some kind, in contrast to "virtual"/software source \since 0.9.3 */
|
||||||
PA_SOURCE_CAN_SUSPEND = 8 /**< Can suspend \since 0.9.7 */
|
|
||||||
} pa_source_flags_t;
|
} pa_source_flags_t;
|
||||||
|
|
||||||
/** A generic free() like callback prototype */
|
/** A generic free() like callback prototype */
|
||||||
|
|
|
||||||
|
|
@ -423,7 +423,7 @@ static void create_stream_complete(pa_stream *s) {
|
||||||
tv.tv_usec += LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */
|
tv.tv_usec += LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */
|
||||||
pa_assert(!s->auto_timing_update_event);
|
pa_assert(!s->auto_timing_update_event);
|
||||||
s->auto_timing_update_event = s->mainloop->time_new(s->mainloop, &tv, &auto_timing_update_callback, s);
|
s->auto_timing_update_event = s->mainloop->time_new(s->mainloop, &tv, &auto_timing_update_callback, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
|
void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
|
||||||
|
|
@ -497,7 +497,7 @@ void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED
|
||||||
s->state = PA_STREAM_READY;
|
s->state = PA_STREAM_READY;
|
||||||
request_auto_timing_update(s, 1);
|
request_auto_timing_update(s, 1);
|
||||||
s->state = PA_STREAM_CREATING;
|
s->state = PA_STREAM_CREATING;
|
||||||
|
|
||||||
} else
|
} else
|
||||||
create_stream_complete(s);
|
create_stream_complete(s);
|
||||||
|
|
||||||
|
|
@ -540,12 +540,12 @@ static int create_stream(
|
||||||
if (attr)
|
if (attr)
|
||||||
s->buffer_attr = *attr;
|
s->buffer_attr = *attr;
|
||||||
else {
|
else {
|
||||||
/* half a second */
|
/* half a second, with minimum request of 10 ms */
|
||||||
s->buffer_attr.tlength = pa_bytes_per_second(&s->sample_spec)/2;
|
s->buffer_attr.tlength = pa_bytes_per_second(&s->sample_spec)/2;
|
||||||
s->buffer_attr.maxlength = (s->buffer_attr.tlength*3)/2;
|
s->buffer_attr.maxlength = (s->buffer_attr.tlength*3)/2;
|
||||||
s->buffer_attr.minreq = s->buffer_attr.tlength/100;
|
s->buffer_attr.minreq = s->buffer_attr.tlength/50;
|
||||||
s->buffer_attr.prebuf = s->buffer_attr.tlength - s->buffer_attr.minreq;
|
s->buffer_attr.prebuf = s->buffer_attr.tlength - s->buffer_attr.minreq;
|
||||||
s->buffer_attr.fragsize = s->buffer_attr.tlength/100;
|
s->buffer_attr.fragsize = s->buffer_attr.tlength/50;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dev)
|
if (!dev)
|
||||||
|
|
@ -921,7 +921,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First, let's complete the initialization, if necessary. */
|
/* First, let's complete the initialization, if necessary. */
|
||||||
if (o->stream->state == PA_STREAM_CREATING)
|
if (o->stream->state == PA_STREAM_CREATING)
|
||||||
create_stream_complete(o->stream);
|
create_stream_complete(o->stream);
|
||||||
|
|
||||||
if (o->stream->latency_update_callback)
|
if (o->stream->latency_update_callback)
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ char *pa_sink_list_to_string(pa_core *c) {
|
||||||
" %c index: %u\n"
|
" %c index: %u\n"
|
||||||
"\tname: <%s>\n"
|
"\tname: <%s>\n"
|
||||||
"\tdriver: <%s>\n"
|
"\tdriver: <%s>\n"
|
||||||
"\tflags: %s%s%s%s\n"
|
"\tflags: %s%s%s\n"
|
||||||
"\tstate: %s\n"
|
"\tstate: %s\n"
|
||||||
"\tvolume: <%s>\n"
|
"\tvolume: <%s>\n"
|
||||||
"\tmute: <%i>\n"
|
"\tmute: <%i>\n"
|
||||||
|
|
@ -119,7 +119,7 @@ char *pa_sink_list_to_string(pa_core *c) {
|
||||||
"\tmonitor source: <%u>\n"
|
"\tmonitor source: <%u>\n"
|
||||||
"\tsample spec: <%s>\n"
|
"\tsample spec: <%s>\n"
|
||||||
"\tchannel map: <%s>\n"
|
"\tchannel map: <%s>\n"
|
||||||
"\tused by: <%u>\n",
|
"\tused by: <%u>\n",
|
||||||
c->default_sink_name && !strcmp(sink->name, c->default_sink_name) ? '*' : ' ',
|
c->default_sink_name && !strcmp(sink->name, c->default_sink_name) ? '*' : ' ',
|
||||||
sink->index,
|
sink->index,
|
||||||
sink->name,
|
sink->name,
|
||||||
|
|
@ -127,7 +127,6 @@ char *pa_sink_list_to_string(pa_core *c) {
|
||||||
sink->flags & PA_SINK_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
|
sink->flags & PA_SINK_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
|
||||||
sink->flags & PA_SINK_LATENCY ? "LATENCY " : "",
|
sink->flags & PA_SINK_LATENCY ? "LATENCY " : "",
|
||||||
sink->flags & PA_SINK_HARDWARE ? "HARDWARE " : "",
|
sink->flags & PA_SINK_HARDWARE ? "HARDWARE " : "",
|
||||||
sink->flags & PA_SINK_CAN_SUSPEND ? "CAN_SUSPEND " : "",
|
|
||||||
state_table[pa_sink_get_state(sink)],
|
state_table[pa_sink_get_state(sink)],
|
||||||
pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink)),
|
pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink)),
|
||||||
!!pa_sink_get_mute(sink),
|
!!pa_sink_get_mute(sink),
|
||||||
|
|
@ -171,7 +170,7 @@ char *pa_source_list_to_string(pa_core *c) {
|
||||||
" %c index: %u\n"
|
" %c index: %u\n"
|
||||||
"\tname: <%s>\n"
|
"\tname: <%s>\n"
|
||||||
"\tdriver: <%s>\n"
|
"\tdriver: <%s>\n"
|
||||||
"\tflags: %s%s%s%s\n"
|
"\tflags: %s%s%s\n"
|
||||||
"\tstate: %s\n"
|
"\tstate: %s\n"
|
||||||
"\tvolume: <%s>\n"
|
"\tvolume: <%s>\n"
|
||||||
"\tmute: <%u>\n"
|
"\tmute: <%u>\n"
|
||||||
|
|
@ -186,7 +185,6 @@ char *pa_source_list_to_string(pa_core *c) {
|
||||||
source->flags & PA_SOURCE_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
|
source->flags & PA_SOURCE_HW_VOLUME_CTRL ? "HW_VOLUME_CTRL " : "",
|
||||||
source->flags & PA_SOURCE_LATENCY ? "LATENCY " : "",
|
source->flags & PA_SOURCE_LATENCY ? "LATENCY " : "",
|
||||||
source->flags & PA_SOURCE_HARDWARE ? "HARDWARE " : "",
|
source->flags & PA_SOURCE_HARDWARE ? "HARDWARE " : "",
|
||||||
source->flags & PA_SOURCE_CAN_SUSPEND ? "CAN_SUSPEND " : "",
|
|
||||||
state_table[pa_source_get_state(source)],
|
state_table[pa_source_get_state(source)],
|
||||||
pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source)),
|
pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source)),
|
||||||
!!pa_source_get_mute(source),
|
!!pa_source_get_mute(source),
|
||||||
|
|
|
||||||
|
|
@ -170,9 +170,6 @@ static int sink_set_state(pa_sink *s, pa_sink_state_t state) {
|
||||||
if (s->state == state)
|
if (s->state == state)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (state == PA_SINK_SUSPENDED && !(s->flags & PA_SINK_CAN_SUSPEND))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((s->state == PA_SINK_SUSPENDED && PA_SINK_OPENED(state)) ||
|
if ((s->state == PA_SINK_SUSPENDED && PA_SINK_OPENED(state)) ||
|
||||||
(PA_SINK_OPENED(s->state) && state == PA_SINK_SUSPENDED)) {
|
(PA_SINK_OPENED(s->state) && state == PA_SINK_SUSPENDED)) {
|
||||||
pa_sink_input *i;
|
pa_sink_input *i;
|
||||||
|
|
|
||||||
|
|
@ -145,9 +145,6 @@ static int source_set_state(pa_source *s, pa_source_state_t state) {
|
||||||
if (s->state == state)
|
if (s->state == state)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (state == PA_SOURCE_SUSPENDED && !(s->flags & PA_SOURCE_CAN_SUSPEND))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((s->state == PA_SOURCE_SUSPENDED && PA_SOURCE_OPENED(state)) ||
|
if ((s->state == PA_SOURCE_SUSPENDED && PA_SOURCE_OPENED(state)) ||
|
||||||
(PA_SOURCE_OPENED(s->state) && state == PA_SOURCE_SUSPENDED)) {
|
(PA_SOURCE_OPENED(s->state) && state == PA_SOURCE_SUSPENDED)) {
|
||||||
pa_source_output *o;
|
pa_source_output *o;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue