summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2008-06-06 14:44:45 +0000
committerLennart Poettering <lennart@poettering.net>2008-06-06 14:44:45 +0000
commit006cd14be70f8edb77372fc7722acf6baa529935 (patch)
tree963fe2b0e165a49edbc16ec49a183c399a1df53f
parentf7ebce5004aaf038b48f370ffa7ae4e58303e4bd (diff)
make the alsa driver actually work
git-svn-id: file:///home/lennart/svn/public/libcanberra/trunk@55 01b60673-d06a-42c0-afdd-89cb8e0f78ac
-rw-r--r--src/alsa.c43
-rw-r--r--src/test-canberra.c4
2 files changed, 33 insertions, 14 deletions
diff --git a/src/alsa.c b/src/alsa.c
index 0eb7aa3..88f76b9 100644
--- a/src/alsa.c
+++ b/src/alsa.c
@@ -122,6 +122,9 @@ int driver_destroy(ca_context *c) {
/* Tell all player threads to terminate */
for (out = p->outstanding; out; out = out->next) {
+ if (out->dead)
+ continue;
+
out->dead = TRUE;
if (out->callback)
@@ -158,6 +161,8 @@ int driver_destroy(ca_context *c) {
c->private = NULL;
+ snd_config_update_free_global();
+
return CA_SUCCESS;
}
@@ -194,6 +199,8 @@ static int translate_error(int error) {
case -EBUSY:
return CA_ERROR_NOTAVAILABLE;
default:
+ if (ca_debug())
+ fprintf(stderr, "Got unhandled error from ALSA: %s\n", snd_strerror(error));
return CA_ERROR_IO;
}
}
@@ -271,6 +278,7 @@ static void* thread_func(void *userdata) {
pthread_detach(pthread_self());
+ fs = ca_sound_file_frame_size(out->file);
data_size = (BUFSIZE/fs)*fs;
if (!(data = ca_malloc(data_size))) {
@@ -278,8 +286,6 @@ static void* thread_func(void *userdata) {
goto finish;
}
- fs = ca_sound_file_frame_size(out->file);
-
if ((ret = snd_pcm_poll_descriptors_count(out->pcm)) < 0) {
ret = translate_error(ret);
goto finish;
@@ -315,7 +321,7 @@ static void* thread_func(void *userdata) {
if (pfd[0].revents)
break;
- if ((ret = snd_pcm_poll_descriptors_revents(out->pcm, pfd, n_pfd, &revents)) < 0) {
+ if ((ret = snd_pcm_poll_descriptors_revents(out->pcm, pfd+1, n_pfd-1, &revents)) < 0) {
ret = translate_error(ret);
goto finish;
}
@@ -390,10 +396,9 @@ finish:
ca_free(data);
ca_free(pfd);
- if (!out->dead) {
+ if (!out->dead)
if (out->callback)
out->callback(out->context, out->id, ret, out->userdata);
- }
ca_mutex_lock(p->outstanding_mutex);
@@ -402,10 +407,10 @@ finish:
if (!p->outstanding && p->signal_semaphore)
sem_post(&p->semaphore);
- ca_mutex_unlock(p->outstanding_mutex);
-
outstanding_free(out);
+ ca_mutex_unlock(p->outstanding_mutex);
+
return NULL;
}
@@ -433,14 +438,29 @@ int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_cal
out->userdata = userdata;
out->pipe_fd[0] = out->pipe_fd[1] = -1;
+ if (pipe(out->pipe_fd) < 0) {
+ ret = CA_ERROR_SYSTEM;
+ goto finish;
+ }
+
if ((ret = ca_lookup_sound(&out->file, &p->theme, c->props, proplist)) < 0)
goto finish;
if ((ret = open_alsa(c, out)) < 0)
goto finish;
+ /* OK, we're ready to go, so let's add this to our list */
+ ca_mutex_lock(p->outstanding_mutex);
+ CA_LLIST_PREPEND(struct outstanding, p->outstanding, out);
+ ca_mutex_unlock(p->outstanding_mutex);
+
if (pthread_create(&thread, NULL, thread_func, out) < 0) {
ret = CA_ERROR_OOM;
+
+ ca_mutex_lock(p->outstanding_mutex);
+ CA_LLIST_REMOVE(struct outstanding, p->outstanding, out);
+ ca_mutex_unlock(p->outstanding_mutex);
+
goto finish;
}
@@ -449,11 +469,7 @@ int driver_play(ca_context *c, uint32_t id, ca_proplist *proplist, ca_finish_cal
finish:
/* We keep the outstanding struct around if we need clean up later to */
- if (ret == CA_SUCCESS) {
- ca_mutex_lock(p->outstanding_mutex);
- CA_LLIST_PREPEND(struct outstanding, p->outstanding, out);
- ca_mutex_unlock(p->outstanding_mutex);
- } else
+ if (ret != CA_SUCCESS)
outstanding_free(out);
return ret;
@@ -475,6 +491,9 @@ int driver_cancel(ca_context *c, uint32_t id) {
if (out->id != id)
continue;
+ if (out->dead)
+ continue;
+
out->dead = TRUE;
if (out->callback)
diff --git a/src/test-canberra.c b/src/test-canberra.c
index 266e441..db4ad47 100644
--- a/src/test-canberra.c
+++ b/src/test-canberra.c
@@ -71,7 +71,7 @@ int main(int argc, char *argv[]) {
/* Now trigger a sound event, the complex version */
ca_proplist_create(&p);
- ca_proplist_sets(p, CA_PROP_EVENT_ID, "email-message-new");
+ ca_proplist_sets(p, CA_PROP_EVENT_ID, "desktop-logout");
ca_proplist_sets(p, CA_PROP_MEDIA_FILENAME, "/usr/share/sounds/uxknkurz.wav");
ca_proplist_sets(p, CA_PROP_MEDIA_NAME, "New email received");
ca_proplist_setf(p, "test.foo", "%u", 4711);
@@ -84,7 +84,7 @@ int main(int argc, char *argv[]) {
/* Stop one sound */
/* ret = ca_context_cancel(c, 0); */
- fprintf(stderr, "cancel: %s\n", ca_strerror(ret));
+/* fprintf(stderr, "cancel: %s\n", ca_strerror(ret)); */
fprintf(stderr, "Sleep 2s ...\n");
sleep(2);