[pulseaudio-commits] r1702 - /branches/lennart/src/modules/module-alsa-sink.c
svnmailer-noreply at 0pointer.de
svnmailer-noreply at 0pointer.de
Wed Aug 22 10:13:08 PDT 2007
Author: lennart
Date: Wed Aug 22 19:13:07 2007
New Revision: 1702
URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=3D1702&root=3Dpulseaudio&vi=
ew=3Drev
Log:
port alsa driver to make use of new pa_rtpoll object
Modified:
branches/lennart/src/modules/module-alsa-sink.c
Modified: branches/lennart/src/modules/module-alsa-sink.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/modules/mo=
dule-alsa-sink.c?rev=3D1702&root=3Dpulseaudio&r1=3D1701&r2=3D1702&view=3Ddi=
ff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- branches/lennart/src/modules/module-alsa-sink.c (original)
+++ branches/lennart/src/modules/module-alsa-sink.c Wed Aug 22 19:13:07 2007
@@ -51,6 +51,7 @@
#include <pulsecore/thread.h>
#include <pulsecore/core-error.h>
#include <pulsecore/thread-mq.h>
+#include <pulsecore/rtpoll.h>
=
#include "alsa-util.h"
#include "module-alsa-sink-symdef.h"
@@ -75,8 +76,10 @@
pa_core *core;
pa_module *module;
pa_sink *sink;
+ =
pa_thread *thread;
pa_thread_mq thread_mq;
+ pa_rtpoll *rtpoll;
=
snd_pcm_t *pcm_handle;
=
@@ -95,13 +98,7 @@
=
int first;
=
- struct pollfd *pollfd;
- int n_alsa_fds;
-};
-
-enum {
- POLLFD_ASYNCQ,
- POLLFD_ALSA_BASE
+ pa_rtpoll_item *alsa_rtpoll_item;
};
=
static const char* const valid_modargs[] =3D {
@@ -118,18 +115,18 @@
};
=
static int mmap_write(struct userdata *u) {
- snd_pcm_sframes_t n;
- int err;
- const snd_pcm_channel_area_t *areas;
- snd_pcm_uframes_t offset, frames;
int work_done =3D 0;
=
pa_assert(u);
- pa_assert(u->sink);
+ pa_sink_assert_ref(u->sink);
=
for (;;) {
pa_memchunk chunk;
void *p;
+ snd_pcm_sframes_t n;
+ int err;
+ const snd_pcm_channel_area_t *areas;
+ snd_pcm_uframes_t offset, frames;
=
if ((n =3D snd_pcm_avail_update(u->pcm_handle)) < 0) {
=
@@ -211,8 +208,83 @@
=
work_done =3D 1;
=
+ if (frames >=3D (snd_pcm_uframes_t) n)
+ return work_done;
+ =
/* pa_log("wrote %i samples", (int) frames); */
}
+}
+
+static int unix_write(struct userdata *u) {
+ snd_pcm_status_t *status;
+ int work_done =3D 0;
+
+ snd_pcm_status_alloca(&status);
+ =
+ pa_assert(u);
+ pa_sink_assert_ref(u->sink);
+
+ for (;;) {
+ void *p;
+ snd_pcm_sframes_t t;
+ ssize_t l;
+ int err;
+ =
+ if ((err =3D snd_pcm_status(u->pcm_handle, status)) < 0) {
+ pa_log("Failed to query DSP status data: %s", snd_strerror(t));
+ return -1;
+ }
+
+ if (snd_pcm_status_get_avail_max(status)*u->frame_size >=3D u->hwb=
uf_size)
+ pa_log_debug("Buffer underrun!");
+ =
+ l =3D snd_pcm_status_get_avail(status) * u->frame_size;
+
+/* pa_log("%u bytes to write", l); */
+ =
+ if (l <=3D 0)
+ return work_done;
+ =
+ if (u->memchunk.length <=3D 0)
+ pa_sink_render(u->sink, l, &u->memchunk);
+ =
+ pa_assert(u->memchunk.length > 0);
+ =
+ p =3D pa_memblock_acquire(u->memchunk.memblock);
+ t =3D snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchu=
nk.index, u->memchunk.length / u->frame_size);
+ pa_memblock_release(u->memchunk.memblock);
+ =
+/* pa_log("wrote %i bytes of %u (%u)", t*u->frame_size=
, u->memchunk.length, l); */
+ =
+ pa_assert(t !=3D 0);
+ =
+ if (t < 0) {
+
+ if ((t =3D snd_pcm_recover(u->pcm_handle, t, 1)) =3D=3D 0)
+ continue;
+ =
+ if (t =3D=3D -EAGAIN) {
+ pa_log_debug("EAGAIN");
+ return work_done;
+ } else {
+ pa_log("Failed to write data to DSP: %s", snd_strerror(t));
+ return -1;
+ }
+ }
+ =
+ u->memchunk.index +=3D t * u->frame_size;
+ u->memchunk.length -=3D t * u->frame_size;
+ =
+ if (u->memchunk.length <=3D 0) {
+ pa_memblock_unref(u->memchunk.memblock);
+ pa_memchunk_reset(&u->memchunk);
+ }
+
+ work_done =3D 1;
+
+ if (t * u->frame_size >=3D (unsigned) l)
+ return work_done;
+ } =
}
=
static pa_usec_t sink_get_latency(struct userdata *u) {
@@ -224,6 +296,7 @@
snd_pcm_status_alloca(&status);
=
pa_assert(u);
+ pa_assert(u->pcm_handle);
=
if ((err =3D snd_pcm_status(u->pcm_handle, status)) < 0) =
pa_log("Failed to get delay: %s", snd_strerror(err));
@@ -241,22 +314,24 @@
=
static int build_pollfd(struct userdata *u) {
int err;
+ struct pollfd *pollfd;
+ int n;
=
pa_assert(u);
pa_assert(u->pcm_handle);
=
- if ((u->n_alsa_fds =3D snd_pcm_poll_descriptors_count(u->pcm_handle)) =
< 0) {
- pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror=
(u->n_alsa_fds));
+ if ((n =3D snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) {
+ pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror=
(n));
return -1;
}
=
- pa_xfree(u->pollfd);
- u->pollfd =3D pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + u->n_alsa_fds=
);
-
- u->pollfd[POLLFD_ASYNCQ].fd =3D pa_asyncmsgq_get_fd(u->thread_mq.inq);
- u->pollfd[POLLFD_ASYNCQ].events =3D POLLIN;
-
- if ((err =3D snd_pcm_poll_descriptors(u->pcm_handle, u->pollfd+POLLFD_=
ALSA_BASE, u->n_alsa_fds)) < 0) {
+ if (u->alsa_rtpoll_item)
+ pa_rtpoll_item_free(u->alsa_rtpoll_item);
+
+ u->alsa_rtpoll_item =3D pa_rtpoll_item_new(u->rtpoll, n);
+ pollfd =3D pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, NULL);
+
+ if ((err =3D snd_pcm_poll_descriptors(u->pcm_handle, pollfd, n)) < 0) {
pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err));
return -1;
}
@@ -272,6 +347,11 @@
snd_pcm_close(u->pcm_handle);
u->pcm_handle =3D NULL;
=
+ if (u->alsa_rtpoll_item) {
+ pa_rtpoll_item_free(u->alsa_rtpoll_item);
+ u->alsa_rtpoll_item =3D NULL;
+ }
+ =
pa_log_debug("Device suspended...");
=
return 0;
@@ -516,14 +596,9 @@
}
=
static void thread_func(void *userdata) {
-
struct userdata *u =3D userdata;
- unsigned short revents =3D 0;
- snd_pcm_status_t *status;
- int err;
- =
- pa_assert(u);
- snd_pcm_status_alloca(&status);
+ =
+ pa_assert(u);
=
pa_log_debug("Thread starting up");
=
@@ -531,6 +606,7 @@
pa_make_realtime();
=
pa_thread_mq_install(&u->thread_mq);
+ pa_rtpoll_install(u->rtpoll);
=
if (build_pollfd(u) < 0)
goto fail;
@@ -541,10 +617,33 @@
void *data;
pa_memchunk chunk;
int64_t offset;
- int r;
=
/* pa_log("loop"); */
=
+ /* Render some data and write it to the dsp */
+ if (PA_SINK_OPENED(u->sink->thread_info.state)) {
+ int work_done =3D 0;
+ =
+ pa_assert(u->pcm_handle);
+
+ if (u->use_mmap) {
+ if ((work_done =3D mmap_write(u)) < 0)
+ goto fail;
+ } else {
+ if ((work_done =3D unix_write(u)) < 0)
+ goto fail;
+ }
+
+ if (work_done && u->first) {
+ pa_log_info("Starting playback.");
+ snd_pcm_start(u->pcm_handle);
+ u->first =3D 0;
+ continue;
+ }
+ }
+
+/* pa_log("loop2"); */
+
/* Check whether there is a message for us to process */
if (pa_asyncmsgq_get(u->thread_mq.inq, &object, &code, &data, &off=
set, &chunk, 0) =3D=3D 0) {
int ret;
@@ -561,122 +660,21 @@
continue;
} =
=
-/* pa_log("loop2"); */
-
- /* Render some data and write it to the dsp */
-
- if (PA_SINK_OPENED(u->sink->thread_info.state) && ((revents & POLL=
OUT) || u->first =3D=3D 1)) {
- int work_done =3D 0;
- pa_assert(u->pcm_handle);
-
- if (u->use_mmap) {
-
- if ((work_done =3D mmap_write(u)) < 0)
- goto fail;
-
- } else {
- =
- for (;;) {
- void *p;
- snd_pcm_sframes_t t;
- ssize_t l;
- =
- if ((err =3D snd_pcm_status(u->pcm_handle, status)) < =
0) {
- pa_log("Failed to query DSP status data: %s", snd_=
strerror(t));
- goto fail;
- }
-
- if (snd_pcm_status_get_avail_max(status)*u->frame_size=
>=3D u->hwbuf_size)
- pa_log_debug("Buffer underrun!");
- =
- l =3D snd_pcm_status_get_avail(status) * u->frame_size;
-
-/* pa_log("%u bytes to write", l); */
- =
- if (l <=3D 0)
- break;
- =
- if (u->memchunk.length <=3D 0)
- pa_sink_render(u->sink, l, &u->memchunk);
- =
- pa_assert(u->memchunk.length > 0);
- =
- p =3D pa_memblock_acquire(u->memchunk.memblock);
- t =3D 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_log("wrote %i bytes of %u (%u)", t*u->frame_size=
, u->memchunk.length, l); */
- =
- pa_assert(t !=3D 0);
- =
- if (t < 0) {
-
- if ((t =3D snd_pcm_recover(u->pcm_handle, t, 1)) =
=3D=3D 0)
- continue;
- =
- if (t =3D=3D -EAGAIN) {
- pa_log_debug("EAGAIN");
- break;
- } else {
- pa_log("Failed to write data to DSP: %s", snd_=
strerror(t));
- goto fail;
- }
- }
- =
- u->memchunk.index +=3D t * u->frame_size;
- u->memchunk.length -=3D t * u->frame_size;
- =
- if (u->memchunk.length <=3D 0) {
- pa_memblock_unref(u->memchunk.memblock);
- pa_memchunk_reset(&u->memchunk);
- }
-
- work_done =3D 1;
-
- if (t * u->frame_size >=3D (unsigned) l)
- break;
- } =
- }
-
- revents &=3D ~POLLOUT;
- =
- if (work_done) {
-
- if (u->first) {
- pa_log_info("Starting playback.");
- snd_pcm_start(u->pcm_handle);
- u->first =3D 0;
- }
- =
- continue;
- }
- }
-
/* Hmm, nothing to do. Let's sleep */
- if (pa_asyncmsgq_before_poll(u->thread_mq.inq) < 0)
- continue;
-
-/* pa_log("polling for %i", POLLFD_ALSA_BASE + (PA_SINK_OPENED(u->=
sink->thread_info.state) ? u->n_alsa_fds : 0)); */
- r =3D poll(u->pollfd, POLLFD_ALSA_BASE + (PA_SINK_OPENED(u->sink->=
thread_info.state) ? u->n_alsa_fds : 0), -1);
-/* pa_log("poll end"); */
-
- pa_asyncmsgq_after_poll(u->thread_mq.inq);
-
- if (r < 0) {
- if (errno =3D=3D EINTR) {
- u->pollfd[POLLFD_ASYNCQ].revents =3D 0;
- revents =3D 0;
- continue;
- }
-
+ if (pa_rtpoll_run(u->rtpoll) < 0) {
pa_log("poll() failed: %s", pa_cstrerror(errno));
goto fail;
}
=
- pa_assert(r > 0);
-
if (PA_SINK_OPENED(u->sink->thread_info.state)) {
- if ((err =3D snd_pcm_poll_descriptors_revents(u->pcm_handle, u=
->pollfd + POLLFD_ALSA_BASE, u->n_alsa_fds, &revents)) < 0) {
+ struct pollfd *pollfd;
+ unsigned short revents =3D 0;
+ int err;
+ unsigned n;
+
+ pollfd =3D pa_rtpoll_item_get_pollfd(u->alsa_rtpoll_item, &n);
+
+ if ((err =3D snd_pcm_poll_descriptors_revents(u->pcm_handle, p=
ollfd, n, &revents)) < 0) {
pa_log("snd_pcm_poll_descriptors_revents() failed: %s", sn=
d_strerror(err));
goto fail;
}
@@ -692,10 +690,8 @@
goto fail;
}
/* pa_log("got alsa event"); */
- } else
- revents =3D 0;
- =
- pa_assert((u->pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) =3D=3D 0);
+ }
+ =
}
=
fail:
@@ -764,9 +760,10 @@
m->userdata =3D u;
u->use_mmap =3D use_mmap;
u->first =3D 1;
- u->n_alsa_fds =3D 0;
- u->pollfd =3D NULL;
pa_thread_mq_init(&u->thread_mq, m->core->mainloop);
+ u->rtpoll =3D pa_rtpoll_new();
+ u->alsa_rtpoll_item =3D NULL;
+ pa_rtpoll_item_new_asyncmsgq(u->rtpoll, u->thread_mq.inq);
=
snd_config_update_free_global();
if ((err =3D snd_pcm_open(&u->pcm_handle, dev =3D pa_modargs_get_value=
(ma, "device", DEFAULT_DEVICE), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK))=
< 0) {
@@ -943,13 +940,19 @@
}
=
pa_thread_mq_done(&u->thread_mq);
- =
+
if (u->sink)
pa_sink_unref(u->sink);
=
if (u->memchunk.memblock)
pa_memblock_unref(u->memchunk.memblock);
=
+ if (u->alsa_rtpoll_item)
+ pa_rtpoll_item_free(u->alsa_rtpoll_item);
+ =
+ if (u->rtpoll)
+ pa_rtpoll_free(u->rtpoll);
+ =
if (u->mixer_fdl)
pa_alsa_fdlist_free(u->mixer_fdl);
=
@@ -961,7 +964,6 @@
snd_pcm_close(u->pcm_handle);
}
=
- pa_xfree(u->pollfd);
pa_xfree(u->device_name);
pa_xfree(u);
=
More information about the pulseaudio-commits
mailing list