summaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests')
l---------src/tests/Makefile1
-rw-r--r--src/tests/asyncmsgq-test.c110
-rw-r--r--src/tests/asyncq-test.c87
-rw-r--r--src/tests/channelmap-test.c33
-rw-r--r--src/tests/cpulimit-test.c93
-rw-r--r--src/tests/envelope-test.c248
-rw-r--r--src/tests/flist-test.c105
-rw-r--r--src/tests/get-binary-name-test.c36
-rw-r--r--src/tests/hook-list-test.c39
-rw-r--r--src/tests/interpol-test.c169
-rw-r--r--src/tests/ipacl-test.c136
-rw-r--r--src/tests/mainloop-test.c126
-rw-r--r--src/tests/mcalign-test.c112
-rw-r--r--src/tests/memblock-test.c176
-rw-r--r--src/tests/memblockq-test.c153
-rw-r--r--src/tests/mix-test.c261
-rw-r--r--src/tests/pacat-simple.c119
-rw-r--r--src/tests/parec-simple.c100
-rw-r--r--src/tests/proplist-test.c61
-rw-r--r--src/tests/queue-test.c69
-rw-r--r--src/tests/remix-test.c91
-rw-r--r--src/tests/resampler-test.c254
-rw-r--r--src/tests/rtpoll-test.c93
-rw-r--r--src/tests/sig2str-test.c39
-rw-r--r--src/tests/smoother-test.c80
-rw-r--r--src/tests/strlist-test.c42
-rw-r--r--src/tests/sync-playback.c192
-rw-r--r--src/tests/thread-mainloop-test.c79
-rw-r--r--src/tests/thread-test.c144
-rw-r--r--src/tests/utf8-test.c26
-rw-r--r--src/tests/voltest.c22
31 files changed, 3296 insertions, 0 deletions
diff --git a/src/tests/Makefile b/src/tests/Makefile
new file mode 120000
index 00000000..c110232d
--- /dev/null
+++ b/src/tests/Makefile
@@ -0,0 +1 @@
+../pulse/Makefile \ No newline at end of file
diff --git a/src/tests/asyncmsgq-test.c b/src/tests/asyncmsgq-test.c
new file mode 100644
index 00000000..380c5e7f
--- /dev/null
+++ b/src/tests/asyncmsgq-test.c
@@ -0,0 +1,110 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <pulse/util.h>
+#include <pulse/xmalloc.h>
+#include <pulsecore/asyncmsgq.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/log.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/macro.h>
+
+enum {
+ OPERATION_A,
+ OPERATION_B,
+ OPERATION_C,
+ QUIT
+};
+
+static void the_thread(void *_q) {
+ pa_asyncmsgq *q = _q;
+ int quit = 0;
+
+ do {
+ int code = 0;
+
+ pa_assert_se(pa_asyncmsgq_get(q, NULL, &code, NULL, NULL, NULL, 1) == 0);
+
+ switch (code) {
+
+ case OPERATION_A:
+ printf("Operation A\n");
+ break;
+
+ case OPERATION_B:
+ printf("Operation B\n");
+ break;
+
+ case OPERATION_C:
+ printf("Operation C\n");
+ break;
+
+ case QUIT:
+ printf("quit\n");
+ quit = 1;
+ break;
+ }
+
+ pa_asyncmsgq_done(q, 0);
+
+ } while (!quit);
+}
+
+int main(int argc, char *argv[]) {
+ pa_asyncmsgq *q;
+ pa_thread *t;
+
+ pa_assert_se(q = pa_asyncmsgq_new(0));
+
+ pa_assert_se(t = pa_thread_new(the_thread, q));
+
+ printf("Operation A post\n");
+ pa_asyncmsgq_post(q, NULL, OPERATION_A, NULL, 0, NULL, NULL);
+
+ pa_thread_yield();
+
+ printf("Operation B post\n");
+ pa_asyncmsgq_post(q, NULL, OPERATION_B, NULL, 0, NULL, NULL);
+
+ pa_thread_yield();
+
+ printf("Operation C send\n");
+ pa_asyncmsgq_send(q, NULL, OPERATION_C, NULL, 0, NULL);
+
+ pa_thread_yield();
+
+ printf("Quit post\n");
+ pa_asyncmsgq_post(q, NULL, QUIT, NULL, 0, NULL, NULL);
+
+ pa_thread_free(t);
+
+ pa_asyncmsgq_unref(q);
+
+ return 0;
+}
diff --git a/src/tests/asyncq-test.c b/src/tests/asyncq-test.c
new file mode 100644
index 00000000..09b20047
--- /dev/null
+++ b/src/tests/asyncq-test.c
@@ -0,0 +1,87 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <pulse/util.h>
+#include <pulse/xmalloc.h>
+#include <pulsecore/asyncq.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/log.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/macro.h>
+
+static void producer(void *_q) {
+ pa_asyncq *q = _q;
+ int i;
+
+ for (i = 0; i < 1000; i++) {
+ printf("pushing %i\n", i);
+ pa_asyncq_push(q, PA_UINT_TO_PTR(i+1), 1);
+ }
+
+ pa_asyncq_push(q, PA_UINT_TO_PTR(-1), 1);
+ printf("pushed end\n");
+}
+
+static void consumer(void *_q) {
+ pa_asyncq *q = _q;
+ void *p;
+ int i;
+
+ sleep(1);
+
+ for (i = 0;; i++) {
+ p = pa_asyncq_pop(q, 1);
+
+ if (p == PA_UINT_TO_PTR(-1))
+ break;
+
+ pa_assert(p == PA_UINT_TO_PTR(i+1));
+
+ printf("popped %i\n", i);
+ }
+
+ printf("popped end\n");
+}
+
+int main(int argc, char *argv[]) {
+ pa_asyncq *q;
+ pa_thread *t1, *t2;
+
+ pa_assert_se(q = pa_asyncq_new(0));
+
+ pa_assert_se(t1 = pa_thread_new(producer, q));
+ pa_assert_se(t2 = pa_thread_new(consumer, q));
+
+ pa_thread_free(t1);
+ pa_thread_free(t2);
+
+ pa_asyncq_free(q, NULL);
+
+ return 0;
+}
diff --git a/src/tests/channelmap-test.c b/src/tests/channelmap-test.c
new file mode 100644
index 00000000..98f36b61
--- /dev/null
+++ b/src/tests/channelmap-test.c
@@ -0,0 +1,33 @@
+/* $Id$ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include <pulse/channelmap.h>
+#include <pulsecore/gccmacro.h>
+
+int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
+ char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
+ pa_channel_map map, map2;
+
+ pa_channel_map_init_auto(&map, 6, PA_CHANNEL_MAP_AIFF);
+
+ fprintf(stderr, "map: <%s>\n", pa_channel_map_snprint(cm, sizeof(cm), &map));
+
+ pa_channel_map_init_auto(&map, 6, PA_CHANNEL_MAP_AUX);
+
+ fprintf(stderr, "map: <%s>\n", pa_channel_map_snprint(cm, sizeof(cm), &map));
+
+ pa_channel_map_init_auto(&map, 6, PA_CHANNEL_MAP_ALSA);
+
+ fprintf(stderr, "map: <%s>\n", pa_channel_map_snprint(cm, sizeof(cm), &map));
+
+ pa_channel_map_parse(&map2, cm);
+
+ assert(pa_channel_map_equal(&map, &map2));
+
+ pa_channel_map_parse(&map2, "left,test");
+
+
+ return 0;
+}
diff --git a/src/tests/cpulimit-test.c b/src/tests/cpulimit-test.c
new file mode 100644
index 00000000..d582e9c5
--- /dev/null
+++ b/src/tests/cpulimit-test.c
@@ -0,0 +1,93 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+
+#include <pulse/mainloop.h>
+#include <pulsecore/gccmacro.h>
+
+#ifdef TEST2
+#include <pulse/mainloop-signal.h>
+#endif
+
+#include "../daemon/cpulimit.h"
+
+/* A simple example for testing the cpulimit subsystem */
+
+static time_t start;
+
+#ifdef TEST2
+
+static void func(pa_mainloop_api *m, PA_GCC_UNUSED pa_signal_event *e, PA_GCC_UNUSED int sig, PA_GCC_UNUSED void *userdata) {
+ time_t now;
+ time(&now);
+
+ if ((now - start) >= 30) {
+ m->quit(m, 1);
+ fprintf(stderr, "Test failed\n");
+ } else
+ raise(SIGUSR1);
+}
+
+#endif
+
+int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
+ pa_mainloop *m;
+
+ m = pa_mainloop_new();
+ assert(m);
+
+ pa_cpu_limit_init(pa_mainloop_get_api(m));
+
+ time(&start);
+
+#ifdef TEST2
+ pa_signal_init(pa_mainloop_get_api(m));
+ pa_signal_new(SIGUSR1, func, NULL);
+ raise(SIGUSR1);
+ pa_mainloop_run(m, NULL);
+ pa_signal_done();
+#else
+ for (;;) {
+ time_t now;
+ time(&now);
+
+ if ((now - start) >= 30) {
+ fprintf(stderr, "Test failed\n");
+ break;
+ }
+ }
+#endif
+
+ pa_cpu_limit_done();
+
+ pa_mainloop_free(m);
+
+ return 0;
+}
diff --git a/src/tests/envelope-test.c b/src/tests/envelope-test.c
new file mode 100644
index 00000000..240747d7
--- /dev/null
+++ b/src/tests/envelope-test.c
@@ -0,0 +1,248 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <pulse/sample.h>
+#include <pulse/volume.h>
+#include <pulse/timeval.h>
+
+#include <pulsecore/envelope.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/endianmacros.h>
+#include <pulsecore/memblock.h>
+#include <pulsecore/sample-util.h>
+
+#include <liboil/liboil.h>
+
+const pa_envelope_def ramp_down = {
+ .n_points = 2,
+ .points_x = { 100*PA_USEC_PER_MSEC, 300*PA_USEC_PER_MSEC },
+ .points_y = {
+ .f = { 1.0, 0.2 },
+ .i = { 0x10000, 0x10000/5 }
+ }
+};
+
+const pa_envelope_def ramp_up = {
+ .n_points = 2,
+ .points_x = { 100*PA_USEC_PER_MSEC, 300*PA_USEC_PER_MSEC },
+ .points_y = {
+ .f = { 0.2, 1.0 },
+ .i = { 0x10000/5, 0x10000 }
+ }
+};
+
+const pa_envelope_def ramp_down2 = {
+ .n_points = 2,
+ .points_x = { 50*PA_USEC_PER_MSEC, 900*PA_USEC_PER_MSEC },
+ .points_y = {
+ .f = { 0.8, 0.7 },
+ .i = { 0x10000*4/5, 0x10000*7/10 }
+ }
+};
+
+const pa_envelope_def ramp_up2 = {
+ .n_points = 2,
+ .points_x = { 50*PA_USEC_PER_MSEC, 900*PA_USEC_PER_MSEC },
+ .points_y = {
+ .f = { 0.7, 0.9 },
+ .i = { 0x10000*7/10, 0x10000*9/10 }
+ }
+};
+
+static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) {
+ void *d;
+ unsigned i;
+
+ static unsigned j = 0;
+
+ d = pa_memblock_acquire(chunk->memblock);
+
+ switch (ss->format) {
+
+ case PA_SAMPLE_U8:
+ case PA_SAMPLE_ULAW:
+ case PA_SAMPLE_ALAW: {
+ uint8_t *u = d;
+
+ for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
+ printf("0x%02x ", *(u++));
+
+ break;
+ }
+
+ case PA_SAMPLE_S16NE:
+ case PA_SAMPLE_S16RE: {
+ int16_t *u = d;
+
+ for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
+ printf("%i\t%i\n", j++, *(u++));
+
+ break;
+ }
+
+ case PA_SAMPLE_S32NE:
+ case PA_SAMPLE_S32RE: {
+ int32_t *u = d;
+
+ for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
+ printf("%i\t%i\n", j++, *(u++));
+
+ break;
+ }
+
+ case PA_SAMPLE_FLOAT32NE:
+ case PA_SAMPLE_FLOAT32RE: {
+ float *u = d;
+
+ for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+ printf("%i\t%1.3g\n", j++, PA_MAYBE_FLOAT32_SWAP(ss->format == PA_SAMPLE_FLOAT32RE, *u));
+ u++;
+ }
+
+ break;
+ }
+
+ default:
+ pa_assert_not_reached();
+ }
+
+ printf("\n");
+
+ pa_memblock_release(chunk->memblock);
+}
+
+static pa_memblock * generate_block(pa_mempool *pool, const pa_sample_spec *ss) {
+ pa_memblock *block;
+ void *d;
+ unsigned n_samples;
+
+ block = pa_memblock_new(pool, pa_bytes_per_second(ss));
+ n_samples = pa_memblock_get_length(block) / pa_sample_size(ss);
+
+ d = pa_memblock_acquire(block);
+
+ switch (ss->format) {
+
+ case PA_SAMPLE_S16NE:
+ case PA_SAMPLE_S16RE: {
+ int16_t *i;
+
+ for (i = d; n_samples > 0; n_samples--, i++)
+ *i = 0x7FFF;
+
+ break;
+ }
+
+ case PA_SAMPLE_S32NE:
+ case PA_SAMPLE_S32RE: {
+ int32_t *i;
+
+ for (i = d; n_samples > 0; n_samples--, i++)
+ *i = 0x7FFFFFFF;
+
+ break;
+ }
+
+ case PA_SAMPLE_FLOAT32RE:
+ case PA_SAMPLE_FLOAT32NE: {
+ float *f;
+
+ for (f = d; n_samples > 0; n_samples--, f++)
+ *f = PA_MAYBE_FLOAT32_SWAP(ss->format == PA_SAMPLE_FLOAT32RE, 1.0);
+
+ break;
+ }
+
+ default:
+ pa_assert_not_reached();
+ }
+
+ pa_memblock_release(block);
+ return block;
+}
+
+int main(int argc, char *argv[]) {
+ pa_mempool *pool;
+ pa_memblock *block;
+ pa_memchunk chunk;
+ pa_envelope *envelope;
+ pa_envelope_item *item1, *item2;
+
+ const pa_sample_spec ss = {
+ .format = PA_SAMPLE_S16NE,
+ .channels = 1,
+ .rate = 200
+ };
+
+ const pa_cvolume v = {
+ .channels = 1,
+ .values = { PA_VOLUME_NORM, PA_VOLUME_NORM/2 }
+ };
+
+ oil_init();
+ pa_log_set_maximal_level(PA_LOG_DEBUG);
+
+ pa_assert_se(pool = pa_mempool_new(FALSE));
+ pa_assert_se(envelope = pa_envelope_new(&ss));
+
+ block = generate_block(pool, &ss);
+
+ chunk.memblock = pa_memblock_ref(block);
+ chunk.length = pa_memblock_get_length(block);
+ chunk.index = 0;
+
+ pa_volume_memchunk(&chunk, &ss, &v);
+
+ item1 = pa_envelope_add(envelope, &ramp_down);
+ item2 = pa_envelope_add(envelope, &ramp_down2);
+ pa_envelope_apply(envelope, &chunk);
+ dump_block(&ss, &chunk);
+
+ pa_memblock_unref(chunk.memblock);
+
+ chunk.memblock = pa_memblock_ref(block);
+ chunk.length = pa_memblock_get_length(block);
+ chunk.index = 0;
+
+ item1 = pa_envelope_replace(envelope, item1, &ramp_up);
+ item2 = pa_envelope_replace(envelope, item2, &ramp_up2);
+ pa_envelope_apply(envelope, &chunk);
+ dump_block(&ss, &chunk);
+
+ pa_memblock_unref(chunk.memblock);
+
+ pa_envelope_remove(envelope, item1);
+ pa_envelope_remove(envelope, item2);
+ pa_envelope_free(envelope);
+
+ pa_memblock_unref(block);
+
+ pa_mempool_free(pool);
+
+ return 0;
+}
diff --git a/src/tests/flist-test.c b/src/tests/flist-test.c
new file mode 100644
index 00000000..7e54454e
--- /dev/null
+++ b/src/tests/flist-test.c
@@ -0,0 +1,105 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <pulse/util.h>
+#include <pulse/xmalloc.h>
+#include <pulsecore/flist.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/log.h>
+#include <pulsecore/core-util.h>
+
+#define THREADS_MAX 20
+
+static pa_flist *flist;
+static int quit = 0;
+
+static void spin(void) {
+ int k;
+
+ /* Spin a little */
+ k = rand() % 10000;
+ for (; k > 0; k--)
+ pa_thread_yield();
+}
+
+static void thread_func(void *data) {
+ char *s = data;
+ int n = 0;
+ int b = 1;
+
+ while (!quit) {
+ char *text;
+
+ /* Allocate some memory, if possible take it from the flist */
+ if (b && (text = pa_flist_pop(flist)))
+ pa_log("%s: popped '%s'", s, text);
+ else {
+ text = pa_sprintf_malloc("Block %i, allocated by %s", n++, s);
+ pa_log("%s: allocated '%s'", s, text);
+ }
+
+ b = !b;
+
+ spin();
+
+ /* Give it back to the flist if possible */
+ if (pa_flist_push(flist, text) < 0) {
+ pa_log("%s: failed to push back '%s'", s, text);
+ pa_xfree(text);
+ } else
+ pa_log("%s: pushed", s);
+
+ spin();
+ }
+
+ if (pa_flist_push(flist, s) < 0)
+ pa_xfree(s);
+}
+
+int main(int argc, char* argv[]) {
+ pa_thread *threads[THREADS_MAX];
+ int i;
+
+ flist = pa_flist_new(0);
+
+ for (i = 0; i < THREADS_MAX; i++) {
+ threads[i] = pa_thread_new(thread_func, pa_sprintf_malloc("Thread #%i", i+1));
+ assert(threads[i]);
+ }
+
+ pa_msleep(60000);
+ quit = 1;
+
+ for (i = 0; i < THREADS_MAX; i++)
+ pa_thread_free(threads[i]);
+
+ pa_flist_free(flist, pa_xfree);
+
+ return 0;
+}
diff --git a/src/tests/get-binary-name-test.c b/src/tests/get-binary-name-test.c
new file mode 100644
index 00000000..29ebbe22
--- /dev/null
+++ b/src/tests/get-binary-name-test.c
@@ -0,0 +1,36 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <limits.h>
+#include <stdio.h>
+
+#include <pulse/util.h>
+
+int main(int argc, char *argv[]) {
+ char exename[PATH_MAX];
+
+ printf("%s\n", pa_get_binary_name(exename, sizeof(exename)));
+ return 0;
+}
diff --git a/src/tests/hook-list-test.c b/src/tests/hook-list-test.c
new file mode 100644
index 00000000..8628f521
--- /dev/null
+++ b/src/tests/hook-list-test.c
@@ -0,0 +1,39 @@
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/hook-list.h>
+#include <pulsecore/log.h>
+
+static pa_hook_result_t func1(const char*hook_data, const char*call_data, const char*slot_data) {
+ pa_log("(func1) hook=%s call=%s slot=%s", hook_data, call_data, slot_data);
+ return PA_HOOK_OK;
+}
+
+static pa_hook_result_t func2(const char*hook_data, const char*call_data, const char*slot_data) {
+ pa_log("(func2) hook=%s call=%s slot=%s", hook_data, call_data, slot_data);
+ return PA_HOOK_OK;
+}
+
+int main(int argc, char *argv[]) {
+ pa_hook hook;
+ pa_hook_slot *slot;
+
+ pa_hook_init(&hook, (void*) "hook");
+
+ pa_hook_connect(&hook, (pa_hook_cb_t) func1, (void*) "slot1");
+ slot = pa_hook_connect(&hook, (pa_hook_cb_t) func2, (void*) "slot2");
+ pa_hook_connect(&hook, (pa_hook_cb_t) func1, (void*) "slot3");
+
+ pa_hook_fire(&hook, (void*) "call1");
+
+ pa_hook_slot_free(slot);
+
+ pa_hook_fire(&hook, (void*) "call2");
+
+ pa_hook_free(&hook);
+
+ return 0;
+}
diff --git a/src/tests/interpol-test.c b/src/tests/interpol-test.c
new file mode 100644
index 00000000..85a509d4
--- /dev/null
+++ b/src/tests/interpol-test.c
@@ -0,0 +1,169 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <math.h>
+
+#include <pulse/pulseaudio.h>
+#include <pulse/mainloop.h>
+
+#include <pulsecore/thread.h>
+
+static pa_context *context = NULL;
+static pa_stream *stream = NULL;
+static pa_mainloop_api *mainloop_api = NULL;
+
+static void stream_write_cb(pa_stream *p, size_t length, void *userdata) {
+
+ /* Just some silence */
+ pa_stream_write(p, pa_xmalloc0(length), length, pa_xfree, 0, PA_SEEK_RELATIVE);
+}
+
+/* This is called whenever the context status changes */
+static void context_state_callback(pa_context *c, void *userdata) {
+ assert(c);
+
+ switch (pa_context_get_state(c)) {
+ case PA_CONTEXT_CONNECTING:
+ case PA_CONTEXT_AUTHORIZING:
+ case PA_CONTEXT_SETTING_NAME:
+ break;
+
+ case PA_CONTEXT_READY: {
+
+ static const pa_sample_spec ss = {
+ .format = PA_SAMPLE_S16LE,
+ .rate = 44100,
+ .channels = 1
+ };
+
+ fprintf(stderr, "Connection established.\n");
+
+ stream = pa_stream_new(c, "interpol-test", &ss, NULL);
+ assert(stream);
+
+ pa_stream_connect_playback(stream, NULL, NULL, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
+ pa_stream_set_write_callback(stream, stream_write_cb, NULL);
+
+ break;
+ }
+
+ case PA_CONTEXT_TERMINATED:
+ break;
+
+ case PA_CONTEXT_FAILED:
+ default:
+ fprintf(stderr, "Context error: %s\n", pa_strerror(pa_context_errno(c)));
+ abort();
+ }
+}
+
+int main(int argc, char *argv[]) {
+ pa_threaded_mainloop* m = NULL;
+ int k, r;
+ struct timeval start, last_info = { 0, 0 };
+ pa_usec_t old_t = 0, old_rtc = 0;
+
+ /* Set up a new main loop */
+ m = pa_threaded_mainloop_new();
+ assert(m);
+
+ mainloop_api = pa_threaded_mainloop_get_api(m);
+
+ context = pa_context_new(mainloop_api, argv[0]);
+ assert(context);
+
+ pa_context_set_state_callback(context, context_state_callback, NULL);
+
+ r = pa_context_connect(context, NULL, 0, NULL);
+ assert(r >= 0);
+
+ pa_gettimeofday(&start);
+
+ pa_threaded_mainloop_start(m);
+
+ for (k = 0; k < 5000; k++) {
+ int success = 0, changed = 0;
+ pa_usec_t t, rtc;
+ struct timeval now, tv;
+
+ pa_threaded_mainloop_lock(m);
+
+ if (stream) {
+ const pa_timing_info *info;
+
+ if (pa_stream_get_time(stream, &t) >= 0)
+ success = 1;
+
+ if ((info = pa_stream_get_timing_info(stream)))
+ if (last_info.tv_usec != info->timestamp.tv_usec || last_info.tv_sec != info->timestamp.tv_sec) {
+ changed = 1;
+ last_info = info->timestamp;
+ }
+ }
+
+ pa_threaded_mainloop_unlock(m);
+
+ if (success) {
+ pa_gettimeofday(&now);
+
+ rtc = pa_timeval_diff(&now, &start);
+ printf("%i\t%llu\t%llu\t%llu\t%llu\t%u\n", k, (unsigned long long) rtc, (unsigned long long) t, (unsigned long long) (rtc-old_rtc), (unsigned long long) (t-old_t), changed);
+ old_t = t;
+ old_rtc = rtc;
+ }
+
+ /* Spin loop, ugly but normal usleep() is just too badly grained */
+
+ tv = now;
+ while (pa_timeval_diff(pa_gettimeofday(&now), &tv) < 1000)
+ pa_thread_yield();
+ }
+
+ if (m)
+ pa_threaded_mainloop_stop(m);
+
+ if (stream) {
+ pa_stream_disconnect(stream);
+ pa_stream_unref(stream);
+ }
+
+ if (context) {
+ pa_context_disconnect(context);
+ pa_context_unref(context);
+ }
+
+ if (m)
+ pa_threaded_mainloop_free(m);
+
+ return 0;
+}
diff --git a/src/tests/ipacl-test.c b/src/tests/ipacl-test.c
new file mode 100644
index 00000000..d1bcb3e3
--- /dev/null
+++ b/src/tests/ipacl-test.c
@@ -0,0 +1,136 @@
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+#ifdef HAVE_NETINET_IP_H
+#include <netinet/ip.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "../pulsecore/winsock.h"
+
+#include <pulsecore/ipacl.h>
+
+int main(int argc, char *argv[]) {
+ struct sockaddr_in sa;
+ struct sockaddr_in6 sa6;
+ int fd;
+ int r;
+ pa_ip_acl *acl;
+
+ fd = socket(PF_INET, SOCK_STREAM, 0);
+ assert(fd >= 0);
+
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons(22);
+ sa.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ r = connect(fd, (struct sockaddr*) &sa, sizeof(sa));
+ assert(r >= 0);
+
+ acl = pa_ip_acl_new("127.0.0.1");
+ assert(acl);
+ printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ acl = pa_ip_acl_new("127.0.0.2/0");
+ assert(acl);
+ printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ acl = pa_ip_acl_new("127.0.0.1/32");
+ assert(acl);
+ printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ acl = pa_ip_acl_new("127.0.0.1/7");
+ assert(acl);
+ printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ acl = pa_ip_acl_new("127.0.0.2");
+ assert(acl);
+ printf("result=%u (should be 0)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ acl = pa_ip_acl_new("127.0.0.0/8;0.0.0.0/32");
+ assert(acl);
+ printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ acl = pa_ip_acl_new("128.0.0.2/9");
+ assert(acl);
+ printf("result=%u (should be 0)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ acl = pa_ip_acl_new("::1/9");
+ assert(acl);
+ printf("result=%u (should be 0)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ close(fd);
+
+ fd = socket(PF_INET6, SOCK_STREAM, 0);
+ assert(fd >= 0);
+
+ memset(&sa6, 0, sizeof(sa6));
+ sa6.sin6_family = AF_INET6;
+ sa6.sin6_port = htons(22);
+ inet_pton(AF_INET6, "::1", &sa6.sin6_addr);
+
+ r = connect(fd, (struct sockaddr*) &sa6, sizeof(sa6));
+ assert(r >= 0);
+
+ acl = pa_ip_acl_new("::1");
+ assert(acl);
+ printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ acl = pa_ip_acl_new("::1/9");
+ assert(acl);
+ printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ acl = pa_ip_acl_new("::/0");
+ assert(acl);
+ printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ acl = pa_ip_acl_new("::2/128");
+ assert(acl);
+ printf("result=%u (should be 0)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ acl = pa_ip_acl_new("::2/127");
+ assert(acl);
+ printf("result=%u (should be 0)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ acl = pa_ip_acl_new("::2/126");
+ assert(acl);
+ printf("result=%u (should be 1)\n", pa_ip_acl_check(acl, fd));
+ pa_ip_acl_free(acl);
+
+ close(fd);
+
+ return 0;
+}
diff --git a/src/tests/mainloop-test.c b/src/tests/mainloop-test.c
new file mode 100644
index 00000000..c386251c
--- /dev/null
+++ b/src/tests/mainloop-test.c
@@ -0,0 +1,126 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <assert.h>
+
+#include <pulse/timeval.h>
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/gccmacro.h>
+
+#ifdef GLIB_MAIN_LOOP
+
+#include <glib.h>
+#include <pulse/glib-mainloop.h>
+
+static GMainLoop* glib_main_loop = NULL;
+
+#else /* GLIB_MAIN_LOOP */
+#include <pulse/mainloop.h>
+#endif /* GLIB_MAIN_LOOP */
+
+static pa_defer_event *de;
+
+static void iocb(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
+ unsigned char c;
+ read(fd, &c, sizeof(c));
+ fprintf(stderr, "IO EVENT: %c\n", c < 32 ? '.' : c);
+ a->defer_enable(de, 1);
+}
+
+static void dcb(pa_mainloop_api*a, pa_defer_event *e, void *userdata) {
+ fprintf(stderr, "DEFER EVENT\n");
+ a->defer_enable(e, 0);
+}
+
+static void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, void *userdata) {
+ fprintf(stderr, "TIME EVENT\n");
+
+#if defined(GLIB_MAIN_LOOP)
+ g_main_loop_quit(glib_main_loop);
+#else
+ a->quit(a, 0);
+#endif
+}
+
+int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
+ pa_mainloop_api *a;
+ pa_io_event *ioe;
+ pa_time_event *te;
+ struct timeval tv;
+
+#ifdef GLIB_MAIN_LOOP
+ pa_glib_mainloop *g;
+
+ glib_main_loop = g_main_loop_new(NULL, FALSE);
+ assert(glib_main_loop);
+
+ g = pa_glib_mainloop_new(NULL);
+ assert(g);
+
+ a = pa_glib_mainloop_get_api(g);
+ assert(a);
+#else /* GLIB_MAIN_LOOP */
+ pa_mainloop *m;
+
+ m = pa_mainloop_new();
+ assert(m);
+
+ a = pa_mainloop_get_api(m);
+ assert(a);
+#endif /* GLIB_MAIN_LOOP */
+
+ ioe = a->io_new(a, 0, PA_IO_EVENT_INPUT, iocb, NULL);
+ assert(ioe);
+
+ de = a->defer_new(a, dcb, NULL);
+ assert(de);
+
+ pa_gettimeofday(&tv);
+ tv.tv_sec += 10;
+ te = a->time_new(a, &tv, tcb, NULL);
+
+#if defined(GLIB_MAIN_LOOP)
+ g_main_loop_run(glib_main_loop);
+#else
+ pa_mainloop_run(m, NULL);
+#endif
+
+ a->time_free(te);
+ a->defer_free(de);
+ a->io_free(ioe);
+
+#ifdef GLIB_MAIN_LOOP
+ pa_glib_mainloop_free(g);
+ g_main_loop_unref(glib_main_loop);
+#else
+ pa_mainloop_free(m);
+#endif
+
+ return 0;
+}
diff --git a/src/tests/mcalign-test.c b/src/tests/mcalign-test.c
new file mode 100644
index 00000000..d1013118
--- /dev/null
+++ b/src/tests/mcalign-test.c
@@ -0,0 +1,112 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <pulsecore/core-util.h>
+#include <pulsecore/mcalign.h>
+#include <pulsecore/gccmacro.h>
+
+/* A simple program for testing pa_mcalign */
+
+int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
+ pa_mempool *p;
+ pa_mcalign *a;
+ pa_memchunk c;
+
+ p = pa_mempool_new(0);
+
+ a = pa_mcalign_new(11);
+
+ pa_memchunk_reset(&c);
+
+ srand(time(NULL));
+
+ for (;;) {
+ ssize_t r;
+ size_t l;
+
+ if (!c.memblock) {
+ c.memblock = pa_memblock_new(p, 2048);
+ c.index = c.length = 0;
+ }
+
+ assert(c.index < pa_memblock_get_length(c.memblock));
+
+ l = pa_memblock_get_length(c.memblock) - c.index;
+
+ l = l <= 1 ? l : rand() % (l-1) +1 ;
+
+ p = pa_memblock_acquire(c.memblock);
+
+ if ((r = read(STDIN_FILENO, (uint8_t*) p + c.index, l)) <= 0) {
+ pa_memblock_release(c.memblock);
+ fprintf(stderr, "read() failed: %s\n", r < 0 ? strerror(errno) : "EOF");
+ break;
+ }
+
+ pa_memblock_release(c.memblock);
+
+ c.length = r;
+ pa_mcalign_push(a, &c);
+ fprintf(stderr, "Read %ld bytes\n", (long)r);
+
+ c.index += r;
+
+ if (c.index >= pa_memblock_get_length(c.memblock)) {
+ pa_memblock_unref(c.memblock);
+ pa_memchunk_reset(&c);
+ }
+
+ for (;;) {
+ pa_memchunk t;
+
+ if (pa_mcalign_pop(a, &t) < 0)
+ break;
+
+ p = pa_memblock_acquire(t.memblock);
+ pa_loop_write(STDOUT_FILENO, (uint8_t*) p + t.index, t.length, NULL);
+ pa_memblock_release(t.memblock);
+ fprintf(stderr, "Wrote %lu bytes.\n", (unsigned long) t.length);
+
+ pa_memblock_unref(t.memblock);
+ }
+ }
+
+ pa_mcalign_free(a);
+
+ if (c.memblock)
+ pa_memblock_unref(c.memblock);
+
+ pa_mempool_free(p);
+
+ return 0;
+}
diff --git a/src/tests/memblock-test.c b/src/tests/memblock-test.c
new file mode 100644
index 00000000..2b9d3401
--- /dev/null
+++ b/src/tests/memblock-test.c
@@ -0,0 +1,176 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <pulsecore/memblock.h>
+#include <pulsecore/macro.h>
+#include <pulse/xmalloc.h>
+
+static void release_cb(pa_memimport *i, uint32_t block_id, void *userdata) {
+ printf("%s: Imported block %u is released.\n", (char*) userdata, block_id);
+}
+
+static void revoke_cb(pa_memexport *e, uint32_t block_id, void *userdata) {
+ printf("%s: Exported block %u is revoked.\n", (char*) userdata, block_id);
+}
+
+static void print_stats(pa_mempool *p, const char *text) {
+ const pa_mempool_stat*s = pa_mempool_get_stat(p);
+
+ printf("%s = {\n"
+ "n_allocated = %u\n"
+ "n_accumulated = %u\n"
+ "n_imported = %u\n"
+ "n_exported = %u\n"
+ "allocated_size = %u\n"
+ "accumulated_size = %u\n"
+ "imported_size = %u\n"
+ "exported_size = %u\n"
+ "n_too_large_for_pool = %u\n"
+ "n_pool_full = %u\n"
+ "}\n",
+ text,
+ (unsigned) pa_atomic_load(&s->n_allocated),
+ (unsigned) pa_atomic_load(&s->n_accumulated),
+ (unsigned) pa_atomic_load(&s->n_imported),
+ (unsigned) pa_atomic_load(&s->n_exported),
+ (unsigned) pa_atomic_load(&s->allocated_size),
+ (unsigned) pa_atomic_load(&s->accumulated_size),
+ (unsigned) pa_atomic_load(&s->imported_size),
+ (unsigned) pa_atomic_load(&s->exported_size),
+ (unsigned) pa_atomic_load(&s->n_too_large_for_pool),
+ (unsigned) pa_atomic_load(&s->n_pool_full));
+}
+
+int main(int argc, char *argv[]) {
+ pa_mempool *pool_a, *pool_b, *pool_c;
+ unsigned id_a, id_b, id_c;
+ pa_memexport *export_a, *export_b;
+ pa_memimport *import_b, *import_c;
+ pa_memblock *mb_a, *mb_b, *mb_c;
+ int r, i;
+ pa_memblock* blocks[5];
+ uint32_t id, shm_id;
+ size_t offset, size;
+ char *x;
+
+ const char txt[] = "This is a test!";
+
+ pool_a = pa_mempool_new(1);
+ pool_b = pa_mempool_new(1);
+ pool_c = pa_mempool_new(1);
+
+ pa_mempool_get_shm_id(pool_a, &id_a);
+ pa_mempool_get_shm_id(pool_b, &id_b);
+ pa_mempool_get_shm_id(pool_c, &id_c);
+
+ pa_assert(pool_a && pool_b && pool_c);
+
+ blocks[0] = pa_memblock_new_fixed(pool_a, (void*) txt, sizeof(txt), 1);
+
+ blocks[1] = pa_memblock_new(pool_a, sizeof(txt));
+ x = pa_memblock_acquire(blocks[1]);
+ snprintf(x, pa_memblock_get_length(blocks[1]), "%s", txt);
+ pa_memblock_release(blocks[1]);
+
+ blocks[2] = pa_memblock_new_pool(pool_a, sizeof(txt));
+ x = pa_memblock_acquire(blocks[2]);
+ snprintf(x, pa_memblock_get_length(blocks[2]), "%s", txt);
+ pa_memblock_release(blocks[2]);
+
+ blocks[3] = pa_memblock_new_malloced(pool_a, pa_xstrdup(txt), sizeof(txt));
+ blocks[4] = NULL;
+
+ for (i = 0; blocks[i]; i++) {
+ printf("Memory block %u\n", i);
+
+ mb_a = blocks[i];
+ pa_assert(mb_a);
+
+ export_a = pa_memexport_new(pool_a, revoke_cb, (void*) "A");
+ export_b = pa_memexport_new(pool_b, revoke_cb, (void*) "B");
+
+ pa_assert(export_a && export_b);
+
+ import_b = pa_memimport_new(pool_b, release_cb, (void*) "B");
+ import_c = pa_memimport_new(pool_c, release_cb, (void*) "C");
+
+ pa_assert(import_b && import_c);
+
+ r = pa_memexport_put(export_a, mb_a, &id, &shm_id, &offset, &size);
+ pa_assert(r >= 0);
+ pa_assert(shm_id == id_a);
+
+ printf("A: Memory block exported as %u\n", id);
+
+ mb_b = pa_memimport_get(import_b, id, shm_id, offset, size);
+ pa_assert(mb_b);
+ r = pa_memexport_put(export_b, mb_b, &id, &shm_id, &offset, &size);
+ pa_assert(r >= 0);
+ pa_assert(shm_id == id_a || shm_id == id_b);
+ pa_memblock_unref(mb_b);
+
+ printf("B: Memory block exported as %u\n", id);
+
+ mb_c = pa_memimport_get(import_c, id, shm_id, offset, size);
+ pa_assert(mb_c);
+ x = pa_memblock_acquire(mb_c);
+ printf("1 data=%s\n", x);
+ pa_memblock_release(mb_c);
+
+ print_stats(pool_a, "A");
+ print_stats(pool_b, "B");
+ print_stats(pool_c, "C");
+
+ pa_memexport_free(export_b);
+ x = pa_memblock_acquire(mb_c);
+ printf("2 data=%s\n", x);
+ pa_memblock_release(mb_c);
+ pa_memblock_unref(mb_c);
+
+ pa_memimport_free(import_b);
+
+ pa_memblock_unref(mb_a);
+
+ pa_memimport_free(import_c);
+ pa_memexport_free(export_a);
+ }
+
+ printf("vaccuuming...\n");
+
+ pa_mempool_vacuum(pool_a);
+ pa_mempool_vacuum(pool_b);
+ pa_mempool_vacuum(pool_c);
+
+ printf("vaccuuming done...\n");
+
+ pa_mempool_free(pool_a);
+ pa_mempool_free(pool_b);
+ pa_mempool_free(pool_c);
+
+ return 0;
+}
diff --git a/src/tests/memblockq-test.c b/src/tests/memblockq-test.c
new file mode 100644
index 00000000..25ea399b
--- /dev/null
+++ b/src/tests/memblockq-test.c
@@ -0,0 +1,153 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <signal.h>
+
+#include <pulsecore/memblockq.h>
+#include <pulsecore/log.h>
+
+int main(int argc, char *argv[]) {
+ int ret;
+
+ pa_mempool *p;
+ pa_memblockq *bq;
+ pa_memchunk chunk1, chunk2, chunk3, chunk4;
+ pa_memblock *silence;
+
+ pa_log_set_maximal_level(PA_LOG_DEBUG);
+
+ p = pa_mempool_new(0);
+
+ silence = pa_memblock_new_fixed(p, (char*) "__", 2, 1);
+ assert(silence);
+
+ bq = pa_memblockq_new(0, 40, 10, 2, 4, 4, silence);
+ assert(bq);
+
+ chunk1.memblock = pa_memblock_new_fixed(p, (char*) "11", 2, 1);
+ chunk1.index = 0;
+ chunk1.length = 2;
+ assert(chunk1.memblock);
+
+ chunk2.memblock = pa_memblock_new_fixed(p, (char*) "XX22", 4, 1);
+ chunk2.index = 2;
+ chunk2.length = 2;
+ assert(chunk2.memblock);
+
+ chunk3.memblock = pa_memblock_new_fixed(p, (char*) "3333", 4, 1);
+ chunk3.index = 0;
+ chunk3.length = 4;
+ assert(chunk3.memblock);
+
+ chunk4.memblock = pa_memblock_new_fixed(p, (char*) "44444444", 8, 1);
+ chunk4.index = 0;
+ chunk4.length = 8;
+ assert(chunk4.memblock);
+
+ ret = pa_memblockq_push(bq, &chunk1);
+ assert(ret == 0);
+
+ ret = pa_memblockq_push(bq, &chunk1);
+ assert(ret == 0);
+
+ ret = pa_memblockq_push(bq, &chunk2);
+ assert(ret == 0);
+
+ ret = pa_memblockq_push(bq, &chunk2);
+ assert(ret == 0);
+
+ pa_memblockq_seek(bq, -6, 0);
+ ret = pa_memblockq_push(bq, &chunk3);
+ assert(ret == 0);
+
+ pa_memblockq_seek(bq, -2, 0);
+ ret = pa_memblockq_push(bq, &chunk3);
+ assert(ret == 0);
+
+ pa_memblockq_seek(bq, -10, 0);
+ ret = pa_memblockq_push(bq, &chunk4);
+ assert(ret == 0);
+
+ pa_memblockq_seek(bq, 10, 0);
+
+ ret = pa_memblockq_push(bq, &chunk1);
+ assert(ret == 0);
+
+ pa_memblockq_seek(bq, -6, 0);
+ ret = pa_memblockq_push(bq, &chunk2);
+ assert(ret == 0);
+
+ /* Test splitting */
+ pa_memblockq_seek(bq, -12, 0);
+ ret = pa_memblockq_push(bq, &chunk1);
+ assert(ret == 0);
+
+ pa_memblockq_seek(bq, 20, 0);
+
+ /* Test merging */
+ ret = pa_memblockq_push(bq, &chunk3);
+ assert(ret == 0);
+ pa_memblockq_seek(bq, -2, 0);
+
+ chunk3.index += 2;
+ chunk3.length -= 2;
+ ret = pa_memblockq_push(bq, &chunk3);
+ assert(ret == 0);
+
+ pa_memblockq_shorten(bq, pa_memblockq_get_length(bq)-2);
+
+ printf(">");
+
+ for (;;) {
+ pa_memchunk out;
+ char *e;
+ size_t n;
+
+ if (pa_memblockq_peek(bq, &out) < 0)
+ break;
+
+ p = pa_memblock_acquire(out.memblock);
+ for (e = (char*) p + out.index, n = 0; n < out.length; n++)
+ printf("%c", *e);
+ pa_memblock_release(out.memblock);
+
+ pa_memblock_unref(out.memblock);
+ pa_memblockq_drop(bq, out.length);
+ }
+
+ printf("<\n");
+
+ pa_memblockq_free(bq);
+ pa_memblock_unref(silence);
+ pa_memblock_unref(chunk1.memblock);
+ pa_memblock_unref(chunk2.memblock);
+ pa_memblock_unref(chunk3.memblock);
+ pa_memblock_unref(chunk4.memblock);
+
+ return 0;
+}
diff --git a/src/tests/mix-test.c b/src/tests/mix-test.c
new file mode 100644
index 00000000..d07b1b0c
--- /dev/null
+++ b/src/tests/mix-test.c
@@ -0,0 +1,261 @@
+/* $Id: resampler-test.c 2037 2007-11-09 02:45:07Z lennart $ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <pulse/sample.h>
+#include <pulse/volume.h>
+
+#include <pulsecore/resampler.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/endianmacros.h>
+#include <pulsecore/memblock.h>
+#include <pulsecore/sample-util.h>
+
+#include <liboil/liboil.h>
+
+static float swap_float(float a) {
+ uint32_t *b = (uint32_t*) &a;
+ *b = PA_UINT32_SWAP(*b);
+ return a;
+}
+
+static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) {
+ void *d;
+ unsigned i;
+
+ d = pa_memblock_acquire(chunk->memblock);
+
+ switch (ss->format) {
+
+ case PA_SAMPLE_U8:
+ case PA_SAMPLE_ULAW:
+ case PA_SAMPLE_ALAW: {
+ uint8_t *u = d;
+
+ for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
+ printf("0x%02x ", *(u++));
+
+ break;
+ }
+
+ case PA_SAMPLE_S16NE:
+ case PA_SAMPLE_S16RE: {
+ uint16_t *u = d;
+
+ for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
+ printf("0x%04x ", *(u++));
+
+ break;
+ }
+
+ case PA_SAMPLE_S32NE:
+ case PA_SAMPLE_S32RE: {
+ uint32_t *u = d;
+
+ for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
+ printf("0x%08x ", *(u++));
+
+ break;
+ }
+
+ case PA_SAMPLE_FLOAT32NE:
+ case PA_SAMPLE_FLOAT32RE: {
+ float *u = d;
+
+ for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+ printf("%1.5f ", ss->format == PA_SAMPLE_FLOAT32NE ? *u : swap_float(*u));
+ u++;
+ }
+
+ break;
+ }
+
+ default:
+ pa_assert_not_reached();
+ }
+
+ printf("\n");
+
+ pa_memblock_release(chunk->memblock);
+}
+
+static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) {
+ pa_memblock *r;
+ void *d;
+ unsigned i;
+
+ pa_assert_se(r = pa_memblock_new(pool, pa_frame_size(ss) * 10));
+ d = pa_memblock_acquire(r);
+
+ switch (ss->format) {
+
+ case PA_SAMPLE_U8:
+ case PA_SAMPLE_ULAW:
+ case PA_SAMPLE_ALAW: {
+ uint8_t *u = d;
+
+ u[0] = 0x00;
+ u[1] = 0xFF;
+ u[2] = 0x7F;
+ u[3] = 0x80;
+ u[4] = 0x9f;
+ u[5] = 0x3f;
+ u[6] = 0x1;
+ u[7] = 0xF0;
+ u[8] = 0x20;
+ u[9] = 0x21;
+ break;
+ }
+
+ case PA_SAMPLE_S16NE:
+ case PA_SAMPLE_S16RE: {
+ uint16_t *u = d;
+
+ u[0] = 0x0000;
+ u[1] = 0xFFFF;
+ u[2] = 0x7FFF;
+ u[3] = 0x8000;
+ u[4] = 0x9fff;
+ u[5] = 0x3fff;
+ u[6] = 0x1;
+ u[7] = 0xF000;
+ u[8] = 0x20;
+ u[9] = 0x21;
+ break;
+ }
+
+ case PA_SAMPLE_S32NE:
+ case PA_SAMPLE_S32RE: {
+ uint32_t *u = d;
+
+ u[0] = 0x00000001;
+ u[1] = 0xFFFF0002;
+ u[2] = 0x7FFF0003;
+ u[3] = 0x80000004;
+ u[4] = 0x9fff0005;
+ u[5] = 0x3fff0006;
+ u[6] = 0x10007;
+ u[7] = 0xF0000008;
+ u[8] = 0x200009;
+ u[9] = 0x21000A;
+ break;
+ }
+
+ case PA_SAMPLE_FLOAT32NE:
+ case PA_SAMPLE_FLOAT32RE: {
+ float *u = d;
+
+ u[0] = 0.0;
+ u[1] = -1.0;
+ u[2] = 1.0;
+ u[3] = 4711;
+ u[4] = 0.222;
+ u[5] = 0.33;
+ u[6] = -.3;
+ u[7] = 99;
+ u[8] = -0.555;
+ u[9] = -.123;
+
+ if (ss->format == PA_SAMPLE_FLOAT32RE)
+ for (i = 0; i < 10; i++)
+ u[i] = swap_float(u[i]);
+
+ break;
+ }
+
+ default:
+ pa_assert_not_reached();
+ }
+
+ pa_memblock_release(r);
+
+ return r;
+}
+
+int main(int argc, char *argv[]) {
+ pa_mempool *pool;
+ pa_sample_spec a;
+ pa_cvolume v;
+
+ oil_init();
+ pa_log_set_maximal_level(PA_LOG_DEBUG);
+
+ pa_assert_se(pool = pa_mempool_new(FALSE));
+
+ a.channels = 1;
+ a.rate = 44100;
+
+ v.channels = a.channels;
+ v.values[0] = pa_sw_volume_from_linear(0.9);
+
+ for (a.format = 0; a.format < PA_SAMPLE_MAX; a.format ++) {
+ pa_memchunk i, j, k;
+ pa_mix_info m[2];
+ void *ptr;
+
+ printf("=== mixing: %s\n", pa_sample_format_to_string(a.format));
+
+ /* Generate block */
+ i.memblock = generate_block(pool, &a);
+ i.length = pa_memblock_get_length(i.memblock);
+ i.index = 0;
+
+ /* Make a copy */
+ j = i;
+ pa_memblock_ref(j.memblock);
+ pa_memchunk_make_writable(&j, 0);
+
+ /* Adjust volume of the copy */
+ pa_volume_memchunk(&j, &a, &v);
+
+ m[0].chunk = i;
+ m[0].volume.values[0] = PA_VOLUME_NORM;
+ m[0].volume.channels = a.channels;
+ m[1].chunk = j;
+ m[1].volume.values[0] = PA_VOLUME_NORM;
+ m[1].volume.channels = a.channels;
+
+ k.memblock = pa_memblock_new(pool, i.length);
+ k.length = i.length;
+ k.index = 0;
+
+ ptr = (uint8_t*) pa_memblock_acquire(k.memblock) + k.index;
+ pa_mix(m, 2, ptr, k.length, &a, NULL, FALSE);
+ pa_memblock_release(k.memblock);
+
+ dump_block(&a, &i);
+ dump_block(&a, &j);
+ dump_block(&a, &k);
+
+ pa_memblock_unref(i.memblock);
+ pa_memblock_unref(j.memblock);
+ pa_memblock_unref(k.memblock);
+ }
+
+ pa_mempool_free(pool);
+
+ return 0;
+}
diff --git a/src/tests/pacat-simple.c b/src/tests/pacat-simple.c
new file mode 100644
index 00000000..2da67c1a
--- /dev/null
+++ b/src/tests/pacat-simple.c
@@ -0,0 +1,119 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <pulse/simple.h>
+#include <pulse/error.h>
+#include <pulsecore/gccmacro.h>
+
+#define BUFSIZE 1024
+
+int main(PA_GCC_UNUSED int argc, char*argv[]) {
+
+ /* The Sample format to use */
+ static const pa_sample_spec ss = {
+ .format = PA_SAMPLE_S16LE,
+ .rate = 44100,
+ .channels = 2
+ };
+
+ pa_simple *s = NULL;
+ int ret = 1;
+ int error;
+
+ /* replace STDIN with the specified file if needed */
+ if (argc > 1) {
+ int fd;
+
+ if ((fd = open(argv[1], O_RDONLY)) < 0) {
+ fprintf(stderr, __FILE__": open() failed: %s\n", strerror(errno));
+ goto finish;
+ }
+
+ if (dup2(fd, STDIN_FILENO) < 0) {
+ fprintf(stderr, __FILE__": dup2() failed: %s\n", strerror(errno));
+ goto finish;
+ }
+
+ close(fd);
+ }
+
+ /* Create a new playback stream */
+ if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error))) {
+ fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
+ goto finish;
+ }
+
+ for (;;) {
+ uint8_t buf[BUFSIZE];
+ ssize_t r;
+
+#if 0
+ pa_usec_t latency;
+
+ if ((latency = pa_simple_get_latency(s, &error)) == (pa_usec_t) -1) {
+ fprintf(stderr, __FILE__": pa_simple_get_latency() failed: %s\n", pa_strerror(error));
+ goto finish;
+ }
+
+ fprintf(stderr, "%0.0f usec \r", (float)latency);
+#endif
+
+ /* Read some data ... */
+ if ((r = read(STDIN_FILENO, buf, sizeof(buf))) <= 0) {
+ if (r == 0) /* EOF */
+ break;
+
+ fprintf(stderr, __FILE__": read() failed: %s\n", strerror(errno));
+ goto finish;
+ }
+
+ /* ... and play it */
+ if (pa_simple_write(s, buf, r, &error) < 0) {
+ fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error));
+ goto finish;
+ }
+ }
+
+ /* Make sure that every single sample was played */
+ if (pa_simple_drain(s, &error) < 0) {
+ fprintf(stderr, __FILE__": pa_simple_drain() failed: %s\n", pa_strerror(error));
+ goto finish;
+ }
+
+ ret = 0;
+
+finish:
+
+ if (s)
+ pa_simple_free(s);
+
+ return ret;
+}
diff --git a/src/tests/parec-simple.c b/src/tests/parec-simple.c
new file mode 100644
index 00000000..d7d88360
--- /dev/null
+++ b/src/tests/parec-simple.c
@@ -0,0 +1,100 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <pulse/simple.h>
+#include <pulse/error.h>
+#include <pulsecore/gccmacro.h>
+
+#define BUFSIZE 1024
+
+/* A simple routine calling UNIX write() in a loop */
+static ssize_t loop_write(int fd, const void*data, size_t size) {
+ ssize_t ret = 0;
+
+ while (size > 0) {
+ ssize_t r;
+
+ if ((r = write(fd, data, size)) < 0)
+ return r;
+
+ if (r == 0)
+ break;
+
+ ret += r;
+ data = (const uint8_t*) data + r;
+ size -= r;
+ }
+
+ return ret;
+}
+
+int main(PA_GCC_UNUSED int argc, char*argv[]) {
+ /* The sample type to use */
+ static const pa_sample_spec ss = {
+ .format = PA_SAMPLE_S16LE,
+ .rate = 44100,
+ .channels = 2
+ };
+ pa_simple *s = NULL;
+ int ret = 1;
+ int error;
+
+ /* Create the recording stream */
+ if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error))) {
+ fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
+ goto finish;
+ }
+
+ for (;;) {
+ uint8_t buf[BUFSIZE];
+ ssize_t r;
+
+ /* Record some data ... */
+ if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) {
+ fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n", pa_strerror(error));
+ goto finish;
+ }
+
+ /* And write it to STDOUT */
+ if ((r = loop_write(STDOUT_FILENO, buf, sizeof(buf))) <= 0) {
+ fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno));
+ goto finish;
+ }
+ }
+
+ ret = 0;
+
+finish:
+
+ if (s)
+ pa_simple_free(s);
+
+ return ret;
+}
diff --git a/src/tests/proplist-test.c b/src/tests/proplist-test.c
new file mode 100644
index 00000000..b88f4e5e
--- /dev/null
+++ b/src/tests/proplist-test.c
@@ -0,0 +1,61 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <pulse/proplist.h>
+#include <pulse/xmalloc.h>
+#include <pulsecore/macro.h>
+
+int main(int argc, char*argv[]) {
+ pa_proplist *a, *b;
+ char *s, *t;
+
+ a = pa_proplist_new();
+ pa_assert_se(pa_proplist_puts(a, PA_PROP_MEDIA_TITLE, "Brandenburgische Konzerte") == 0);
+ pa_assert_se(pa_proplist_puts(a, PA_PROP_MEDIA_ARTIST, "Johann Sebastian Bach") == 0);
+
+ b = pa_proplist_new();
+ pa_assert_se(pa_proplist_puts(b, PA_PROP_MEDIA_TITLE, "Goldbergvariationen") == 0);
+ pa_assert_se(pa_proplist_put(b, PA_PROP_MEDIA_ICON, "\0\1\2\3\4\5\6\7", 8) == 0);
+
+ pa_proplist_merge(a, b);
+
+ pa_assert_se(!pa_proplist_gets(a, PA_PROP_MEDIA_ICON));
+
+ printf("%s\n", pa_strnull(pa_proplist_gets(a, PA_PROP_MEDIA_TITLE)));
+ pa_assert_se(pa_proplist_remove(b, PA_PROP_MEDIA_TITLE) == 0);
+
+ s = pa_proplist_to_string(a);
+ t = pa_proplist_to_string(b);
+ printf("---\n%s---\n%s", s, t);
+ pa_xfree(s);
+ pa_xfree(t);
+
+ pa_proplist_free(a);
+ pa_proplist_free(b);
+
+ return 0;
+}
diff --git a/src/tests/queue-test.c b/src/tests/queue-test.c
new file mode 100644
index 00000000..b357ab10
--- /dev/null
+++ b/src/tests/queue-test.c
@@ -0,0 +1,69 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <pulse/util.h>
+#include <pulse/xmalloc.h>
+#include <pulsecore/queue.h>
+#include <pulsecore/log.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/macro.h>
+
+int main(int argc, char *argv[]) {
+ pa_queue *q;
+
+ pa_assert_se(q = pa_queue_new());
+
+ pa_assert(pa_queue_is_empty(q));
+
+ pa_queue_push(q, (void*) "eins");
+ pa_log("%s\n", (char*) pa_queue_pop(q));
+
+ pa_assert(pa_queue_is_empty(q));
+
+ pa_queue_push(q, (void*) "zwei");
+ pa_queue_push(q, (void*) "drei");
+ pa_queue_push(q, (void*) "vier");
+
+ pa_log("%s\n", (char*) pa_queue_pop(q));
+ pa_log("%s\n", (char*) pa_queue_pop(q));
+
+ pa_queue_push(q, (void*) "fuenf");
+
+ pa_log("%s\n", (char*) pa_queue_pop(q));
+ pa_log("%s\n", (char*) pa_queue_pop(q));
+
+ pa_assert(pa_queue_is_empty(q));
+
+ pa_queue_push(q, (void*) "sechs");
+ pa_queue_push(q, (void*) "sieben");
+
+ pa_queue_free(q, NULL, NULL);
+
+ return 0;
+}
diff --git a/src/tests/remix-test.c b/src/tests/remix-test.c
new file mode 100644
index 00000000..d2fa6943
--- /dev/null
+++ b/src/tests/remix-test.c
@@ -0,0 +1,91 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <pulse/sample.h>
+#include <pulse/volume.h>
+
+#include <pulsecore/resampler.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/endianmacros.h>
+#include <pulsecore/memblock.h>
+#include <pulsecore/sample-util.h>
+
+#include <liboil/liboil.h>
+
+int main(int argc, char *argv[]) {
+
+ static const pa_channel_map maps[] = {
+ { 1, { PA_CHANNEL_POSITION_MONO } },
+ { 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } },
+ { 3, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, PA_CHANNEL_POSITION_CENTER } },
+ { 3, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, PA_CHANNEL_POSITION_LFE } },
+ { 3, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, PA_CHANNEL_POSITION_REAR_CENTER } },
+ { 4, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, PA_CHANNEL_POSITION_CENTER, PA_CHANNEL_POSITION_LFE } },
+ { 4, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, PA_CHANNEL_POSITION_CENTER, PA_CHANNEL_POSITION_REAR_CENTER } },
+ { 4, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT } },
+ { 5, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_CENTER } },
+ { 5, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_LFE } },
+ { 6, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_LFE, PA_CHANNEL_POSITION_CENTER } },
+ { 8, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT, PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, PA_CHANNEL_POSITION_LFE, PA_CHANNEL_POSITION_CENTER, PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT } },
+ { 0, { 0 } }
+ };
+
+ unsigned i, j;
+ pa_mempool *pool;
+
+ oil_init();
+ pa_log_set_maximal_level(PA_LOG_DEBUG);
+
+ pa_assert_se(pool = pa_mempool_new(FALSE));
+
+ for (i = 0; maps[i].channels > 0; i++)
+ for (j = 0; maps[j].channels > 0; j++) {
+ char a[PA_CHANNEL_MAP_SNPRINT_MAX], b[PA_CHANNEL_MAP_SNPRINT_MAX];
+ pa_resampler *r;
+ pa_sample_spec ss1, ss2;
+
+ pa_log_info("Converting from '%s' to '%s'.\n", pa_channel_map_snprint(a, sizeof(a), &maps[i]), pa_channel_map_snprint(b, sizeof(b), &maps[j]));
+
+ ss1.channels = maps[i].channels;
+ ss2.channels = maps[j].channels;
+
+ ss1.rate = ss2.rate = 44100;
+ ss1.format = ss2.format = PA_SAMPLE_S16NE;
+
+ r = pa_resampler_new(pool, &ss1, &maps[i], &ss2, &maps[j], PA_RESAMPLER_AUTO, 0);
+
+ /* We don't really care for the resampler. We just want to
+ * see the remixing debug output. */
+
+ pa_resampler_free(r);
+ }
+
+
+ pa_mempool_free(pool);
+
+ return 0;
+}
diff --git a/src/tests/resampler-test.c b/src/tests/resampler-test.c
new file mode 100644
index 00000000..820a0c1e
--- /dev/null
+++ b/src/tests/resampler-test.c
@@ -0,0 +1,254 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <pulse/sample.h>
+#include <pulse/volume.h>
+
+#include <pulsecore/resampler.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/endianmacros.h>
+#include <pulsecore/memblock.h>
+#include <pulsecore/sample-util.h>
+
+#include <liboil/liboil.h>
+
+static float swap_float(float a) {
+ uint32_t *b = (uint32_t*) &a;
+ *b = PA_UINT32_SWAP(*b);
+ return a;
+}
+
+static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) {
+ void *d;
+ unsigned i;
+
+ d = pa_memblock_acquire(chunk->memblock);
+
+ switch (ss->format) {
+
+ case PA_SAMPLE_U8:
+ case PA_SAMPLE_ULAW:
+ case PA_SAMPLE_ALAW: {
+ uint8_t *u = d;
+
+ for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
+ printf("0x%02x ", *(u++));
+
+ break;
+ }
+
+ case PA_SAMPLE_S16NE:
+ case PA_SAMPLE_S16RE: {
+ uint16_t *u = d;
+
+ for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
+ printf("0x%04x ", *(u++));
+
+ break;
+ }
+
+ case PA_SAMPLE_S32NE:
+ case PA_SAMPLE_S32RE: {
+ uint32_t *u = d;
+
+ for (i = 0; i < chunk->length / pa_frame_size(ss); i++)
+ printf("0x%08x ", *(u++));
+
+ break;
+ }
+
+ case PA_SAMPLE_FLOAT32NE:
+ case PA_SAMPLE_FLOAT32RE: {
+ float *u = d;
+
+ for (i = 0; i < chunk->length / pa_frame_size(ss); i++) {
+ printf("%1.3g ", ss->format == PA_SAMPLE_FLOAT32NE ? *u : swap_float(*u));
+ u++;
+ }
+
+ break;
+ }
+
+ default:
+ pa_assert_not_reached();
+ }
+
+ printf("\n");
+
+ pa_memblock_release(chunk->memblock);
+}
+
+static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) {
+ pa_memblock *r;
+ void *d;
+ unsigned i;
+
+ pa_assert_se(r = pa_memblock_new(pool, pa_frame_size(ss) * 10));
+ d = pa_memblock_acquire(r);
+
+ switch (ss->format) {
+
+ case PA_SAMPLE_U8:
+ case PA_SAMPLE_ULAW:
+ case PA_SAMPLE_ALAW: {
+ uint8_t *u = d;
+
+ u[0] = 0x00;
+ u[1] = 0xFF;
+ u[2] = 0x7F;
+ u[3] = 0x80;
+ u[4] = 0x9f;
+ u[5] = 0x3f;
+ u[6] = 0x1;
+ u[7] = 0xF0;
+ u[8] = 0x20;
+ u[9] = 0x21;
+ break;
+ }
+
+ case PA_SAMPLE_S16NE:
+ case PA_SAMPLE_S16RE: {
+ uint16_t *u = d;
+
+ u[0] = 0x0000;
+ u[1] = 0xFFFF;
+ u[2] = 0x7FFF;
+ u[3] = 0x8000;
+ u[4] = 0x9fff;
+ u[5] = 0x3fff;
+ u[6] = 0x1;
+ u[7] = 0xF000;
+ u[8] = 0x20;
+ u[9] = 0x21;
+ break;
+ }
+
+ case PA_SAMPLE_S32NE:
+ case PA_SAMPLE_S32RE: {
+ uint32_t *u = d;
+
+ u[0] = 0x00000001;
+ u[1] = 0xFFFF0002;
+ u[2] = 0x7FFF0003;
+ u[3] = 0x80000004;
+ u[4] = 0x9fff0005;
+ u[5] = 0x3fff0006;
+ u[6] = 0x10007;
+ u[7] = 0xF0000008;
+ u[8] = 0x200009;
+ u[9] = 0x21000A;
+ break;
+ }
+
+ case PA_SAMPLE_FLOAT32NE:
+ case PA_SAMPLE_FLOAT32RE: {
+ float *u = d;
+
+ u[0] = 0.0;
+ u[1] = -1.0;
+ u[2] = 1.0;
+ u[3] = 4711;
+ u[4] = 0.222;
+ u[5] = 0.33;
+ u[6] = -.3;
+ u[7] = 99;
+ u[8] = -0.555;
+ u[9] = -.123;
+
+ if (ss->format == PA_SAMPLE_FLOAT32RE)
+ for (i = 0; i < 10; i++)
+ u[i] = swap_float(u[i]);
+
+ break;
+ }
+
+ default:
+ pa_assert_not_reached();
+ }
+
+ pa_memblock_release(r);
+
+ return r;
+}
+
+int main(int argc, char *argv[]) {
+ pa_mempool *pool;
+ pa_sample_spec a, b;
+ pa_cvolume v;
+
+ oil_init();
+ pa_log_set_maximal_level(PA_LOG_DEBUG);
+
+ pa_assert_se(pool = pa_mempool_new(FALSE));
+
+ a.channels = b.channels = 1;
+ a.rate = b.rate = 44100;
+
+ v.channels = a.channels;
+ v.values[0] = pa_sw_volume_from_linear(0.5);
+
+ for (a.format = 0; a.format < PA_SAMPLE_MAX; a.format ++) {
+ for (b.format = 0; b.format < PA_SAMPLE_MAX; b.format ++) {
+
+ pa_resampler *forth, *back;
+ pa_memchunk i, j, k;
+
+ printf("=== %s -> %s -> %s -> /2\n",
+ pa_sample_format_to_string(a.format),
+ pa_sample_format_to_string(b.format),
+ pa_sample_format_to_string(a.format));
+
+ pa_assert_se(forth = pa_resampler_new(pool, &a, NULL, &b, NULL, PA_RESAMPLER_AUTO, 0));
+ pa_assert_se(back = pa_resampler_new(pool, &b, NULL, &a, NULL, PA_RESAMPLER_AUTO, 0));
+
+ i.memblock = generate_block(pool, &a);
+ i.length = pa_memblock_get_length(i.memblock);
+ i.index = 0;
+ pa_resampler_run(forth, &i, &j);
+ pa_resampler_run(back, &j, &k);
+
+ dump_block(&a, &i);
+ dump_block(&b, &j);
+ dump_block(&a, &k);
+
+ pa_memblock_unref(j.memblock);
+ pa_memblock_unref(k.memblock);
+
+ pa_volume_memchunk(&i, &a, &v);
+ dump_block(&a, &i);
+
+ pa_memblock_unref(i.memblock);
+
+ pa_resampler_free(forth);
+ pa_resampler_free(back);
+ }
+ }
+
+ pa_mempool_free(pool);
+
+ return 0;
+}
diff --git a/src/tests/rtpoll-test.c b/src/tests/rtpoll-test.c
new file mode 100644
index 00000000..e6493771
--- /dev/null
+++ b/src/tests/rtpoll-test.c
@@ -0,0 +1,93 @@
+/* $Id: thread-test.c 1621 2007-08-10 22:00:22Z lennart $ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <signal.h>
+#include <poll.h>
+
+#include <pulsecore/log.h>
+#include <pulsecore/rtpoll.h>
+#include <pulsecore/rtsig.h>
+
+static int before(pa_rtpoll_item *i) {
+ pa_log("before");
+ return 0;
+}
+
+static void after(pa_rtpoll_item *i) {
+ pa_log("after");
+}
+
+static int worker(pa_rtpoll_item *w) {
+ pa_log("worker");
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ pa_rtpoll *p;
+ pa_rtpoll_item *i, *w;
+ struct pollfd *pollfd;
+
+#ifdef SIGRTMIN
+ pa_rtsig_configure(SIGRTMIN+10, SIGRTMAX);
+#endif
+
+ p = pa_rtpoll_new();
+
+ i = pa_rtpoll_item_new(p, PA_RTPOLL_EARLY, 1);
+ pa_rtpoll_item_set_before_callback(i, before);
+ pa_rtpoll_item_set_after_callback(i, after);
+
+ pollfd = pa_rtpoll_item_get_pollfd(i, NULL);
+ pollfd->fd = 0;
+ pollfd->events = POLLIN;
+
+ w = pa_rtpoll_item_new(p, PA_RTPOLL_NORMAL, 0);
+ pa_rtpoll_item_set_before_callback(w, worker);
+
+ pa_rtpoll_install(p);
+ pa_rtpoll_set_timer_periodic(p, 10000000); /* 10 s */
+
+ pa_rtpoll_run(p, 1);
+
+ pa_rtpoll_item_free(i);
+
+ i = pa_rtpoll_item_new(p, PA_RTPOLL_EARLY, 1);
+ pa_rtpoll_item_set_before_callback(i, before);
+ pa_rtpoll_item_set_after_callback(i, after);
+
+ pollfd = pa_rtpoll_item_get_pollfd(i, NULL);
+ pollfd->fd = 0;
+ pollfd->events = POLLIN;
+
+ pa_rtpoll_run(p, 1);
+
+ pa_rtpoll_item_free(i);
+
+ pa_rtpoll_item_free(w);
+
+ pa_rtpoll_free(p);
+
+ return 0;
+}
diff --git a/src/tests/sig2str-test.c b/src/tests/sig2str-test.c
new file mode 100644
index 00000000..52cb9db4
--- /dev/null
+++ b/src/tests/sig2str-test.c
@@ -0,0 +1,39 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <signal.h>
+#include <stdio.h>
+
+#include <pulsecore/macro.h>
+#include <pulsecore/core-util.h>
+
+int main(int argc, char *argv[]) {
+ int sig;
+
+ for (sig = -1; sig <= NSIG; sig++)
+ printf("%i = %s\n", sig, pa_sig2str(sig));
+
+ return 0;
+}
diff --git a/src/tests/smoother-test.c b/src/tests/smoother-test.c
new file mode 100644
index 00000000..caa7df70
--- /dev/null
+++ b/src/tests/smoother-test.c
@@ -0,0 +1,80 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <pulsecore/time-smoother.h>
+#include <pulse/timeval.h>
+
+int main(int argc, char*argv[]) {
+ pa_usec_t x;
+ unsigned u = 0;
+ pa_smoother *s;
+ int m;
+
+/* unsigned msec[] = { */
+/* 200, 200, */
+/* 300, 320, */
+/* 400, 400, */
+/* 500, 480, */
+/* 0, 0 */
+/* }; */
+
+ int msec[200];
+
+ srand(0);
+
+ for (m = 0, u = 0; u < PA_ELEMENTSOF(msec)-2; u+= 2) {
+
+ msec[u] = m+1;
+ msec[u+1] = m + rand() % 2000 - 1000;
+
+ m += rand() % 100;
+
+ if (msec[u+1] < 0)
+ msec[u+1] = 0;
+ }
+
+ msec[PA_ELEMENTSOF(msec)-2] = 0;
+ msec[PA_ELEMENTSOF(msec)-1] = 0;
+
+ s = pa_smoother_new(1000*PA_USEC_PER_MSEC, 2000*PA_USEC_PER_MSEC, TRUE);
+
+ for (x = 0, u = 0; x < PA_USEC_PER_SEC * 10; x += PA_USEC_PER_MSEC) {
+
+ while (msec[u] > 0 && (pa_usec_t) msec[u]*PA_USEC_PER_MSEC < x) {
+ pa_smoother_put(s, msec[u]*PA_USEC_PER_MSEC, msec[u+1]*PA_USEC_PER_MSEC);
+ printf("%i\t\t%i\n", msec[u], msec[u+1]);
+ u += 2;
+ }
+
+ printf("%llu\t%llu\n", x/PA_USEC_PER_MSEC, pa_smoother_get(s, x)/PA_USEC_PER_MSEC);
+ }
+
+ pa_smoother_free(s);
+
+ return 0;
+}
diff --git a/src/tests/strlist-test.c b/src/tests/strlist-test.c
new file mode 100644
index 00000000..47770b5d
--- /dev/null
+++ b/src/tests/strlist-test.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+
+#include <pulse/xmalloc.h>
+#include <pulsecore/strlist.h>
+#include <pulsecore/gccmacro.h>
+
+int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char* argv[]) {
+ char *t, *u;
+ pa_strlist *l = NULL;
+
+ l = pa_strlist_prepend(l, "e");
+ l = pa_strlist_prepend(l, "d");
+ l = pa_strlist_prepend(l, "c");
+ l = pa_strlist_prepend(l, "b");
+ l = pa_strlist_prepend(l, "a");
+
+ t = pa_strlist_tostring(l);
+ pa_strlist_free(l);
+
+ fprintf(stderr, "1: %s\n", t);
+
+ l = pa_strlist_parse(t);
+ pa_xfree(t);
+
+ t = pa_strlist_tostring(l);
+ fprintf(stderr, "2: %s\n", t);
+ pa_xfree(t);
+
+ l = pa_strlist_pop(l, &u);
+ fprintf(stderr, "3: %s\n", u);
+ pa_xfree(u);
+
+ l = pa_strlist_remove(l, "c");
+
+ t = pa_strlist_tostring(l);
+ fprintf(stderr, "4: %s\n", t);
+ pa_xfree(t);
+
+ pa_strlist_free(l);
+
+ return 0;
+}
diff --git a/src/tests/sync-playback.c b/src/tests/sync-playback.c
new file mode 100644
index 00000000..63510eb6
--- /dev/null
+++ b/src/tests/sync-playback.c
@@ -0,0 +1,192 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <math.h>
+
+#include <pulse/pulseaudio.h>
+#include <pulse/mainloop.h>
+
+#define NSTREAMS 4
+#define SINE_HZ 440
+#define SAMPLE_HZ 8000
+
+static pa_context *context = NULL;
+static pa_stream *streams[NSTREAMS];
+static pa_mainloop_api *mainloop_api = NULL;
+
+static float data[SAMPLE_HZ]; /* one second space */
+
+static int n_streams_ready = 0;
+
+static const pa_sample_spec sample_spec = {
+ .format = PA_SAMPLE_FLOAT32,
+ .rate = SAMPLE_HZ,
+ .channels = 1
+};
+
+static const pa_buffer_attr buffer_attr = {
+ .maxlength = SAMPLE_HZ*sizeof(float)*NSTREAMS, /* exactly space for the entire play time */
+ .tlength = 0,
+ .prebuf = 0, /* Setting prebuf to 0 guarantees us the the streams will run synchronously, no matter what */
+ .minreq = 0
+};
+
+static void nop_free_cb(void *p) {}
+
+static void underflow_cb(struct pa_stream *s, void *userdata) {
+ int i = (int) (long) userdata;
+
+ fprintf(stderr, "Stream %i finished\n", i);
+
+ if (++n_streams_ready >= 2*NSTREAMS) {
+ fprintf(stderr, "We're done\n");
+ mainloop_api->quit(mainloop_api, 0);
+ }
+}
+
+/* This routine is called whenever the stream state changes */
+static void stream_state_callback(pa_stream *s, void *userdata) {
+ assert(s);
+
+ switch (pa_stream_get_state(s)) {
+ case PA_STREAM_UNCONNECTED:
+ case PA_STREAM_CREATING:
+ case PA_STREAM_TERMINATED:
+ break;
+
+ case PA_STREAM_READY: {
+
+ int r, i = (int) (long) userdata;
+
+ fprintf(stderr, "Writing data to stream %i.\n", i);
+
+ r = pa_stream_write(s, data, sizeof(data), nop_free_cb, sizeof(data) * i, PA_SEEK_ABSOLUTE);
+ assert(r == 0);
+
+ /* Be notified when this stream is drained */
+ pa_stream_set_underflow_callback(s, underflow_cb, userdata);
+
+ /* All streams have been set up, let's go! */
+ if (++n_streams_ready >= NSTREAMS) {
+ fprintf(stderr, "Uncorking\n");
+ pa_operation_unref(pa_stream_cork(s, 0, NULL, NULL));
+ }
+
+ break;
+ }
+
+ default:
+ case PA_STREAM_FAILED:
+ fprintf(stderr, "Stream error: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s))));
+ abort();
+ }
+}
+
+/* This is called whenever the context status changes */
+static void context_state_callback(pa_context *c, void *userdata) {
+ assert(c);
+
+ switch (pa_context_get_state(c)) {
+ case PA_CONTEXT_CONNECTING:
+ case PA_CONTEXT_AUTHORIZING:
+ case PA_CONTEXT_SETTING_NAME:
+ break;
+
+ case PA_CONTEXT_READY: {
+
+ int i;
+ fprintf(stderr, "Connection established.\n");
+
+ for (i = 0; i < NSTREAMS; i++) {
+ char name[64];
+
+ fprintf(stderr, "Creating stream %i\n", i);
+
+ snprintf(name, sizeof(name), "stream #%i", i);
+
+ streams[i] = pa_stream_new(c, name, &sample_spec, NULL);
+ assert(streams[i]);
+ pa_stream_set_state_callback(streams[i], stream_state_callback, (void*) (long) i);
+ pa_stream_connect_playback(streams[i], NULL, &buffer_attr, PA_STREAM_START_CORKED, NULL, i == 0 ? NULL : streams[0]);
+ }
+
+ break;
+ }
+
+ case PA_CONTEXT_TERMINATED:
+ mainloop_api->quit(mainloop_api, 0);
+ break;
+
+ case PA_CONTEXT_FAILED:
+ default:
+ fprintf(stderr, "Context error: %s\n", pa_strerror(pa_context_errno(c)));
+ abort();
+ }
+}
+
+int main(int argc, char *argv[]) {
+ pa_mainloop* m = NULL;
+ int i, ret = 0;
+
+ for (i = 0; i < SAMPLE_HZ; i++)
+ data[i] = (float) sin(((double) i/SAMPLE_HZ)*2*M_PI*SINE_HZ)/2;
+
+ for (i = 0; i < NSTREAMS; i++)
+ streams[i] = NULL;
+
+ /* Set up a new main loop */
+ m = pa_mainloop_new();
+ assert(m);
+
+ mainloop_api = pa_mainloop_get_api(m);
+
+ context = pa_context_new(mainloop_api, argv[0]);
+ assert(context);
+
+ pa_context_set_state_callback(context, context_state_callback, NULL);
+
+ pa_context_connect(context, NULL, 0, NULL);
+
+ if (pa_mainloop_run(m, &ret) < 0)
+ fprintf(stderr, "pa_mainloop_run() failed.\n");
+
+ pa_context_unref(context);
+
+ for (i = 0; i < NSTREAMS; i++)
+ if (streams[i])
+ pa_stream_unref(streams[i]);
+
+ pa_mainloop_free(m);
+
+ return ret;
+}
diff --git a/src/tests/thread-mainloop-test.c b/src/tests/thread-mainloop-test.c
new file mode 100644
index 00000000..558e53a5
--- /dev/null
+++ b/src/tests/thread-mainloop-test.c
@@ -0,0 +1,79 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <pulse/timeval.h>
+#include <pulse/util.h>
+#include <pulse/thread-mainloop.h>
+
+#include <pulsecore/gccmacro.h>
+#include <pulsecore/macro.h>
+
+static void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, void *userdata) {
+ pa_assert_se(pa_threaded_mainloop_in_thread(userdata));
+ fprintf(stderr, "TIME EVENT START\n");
+ pa_threaded_mainloop_signal(userdata, 1);
+ fprintf(stderr, "TIME EVENT END\n");
+}
+
+int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
+ pa_mainloop_api *a;
+ pa_threaded_mainloop *m;
+ struct timeval tv;
+
+ pa_assert_se(m = pa_threaded_mainloop_new());
+ pa_assert_se(a = pa_threaded_mainloop_get_api(m));
+
+ pa_threaded_mainloop_start(m);
+
+ pa_threaded_mainloop_lock(m);
+
+ pa_assert_se(!pa_threaded_mainloop_in_thread(m));
+
+ pa_gettimeofday(&tv);
+ tv.tv_sec += 5;
+ a->time_new(a, &tv, tcb, m);
+
+ fprintf(stderr, "waiting 5s (signal)\n");
+ pa_threaded_mainloop_wait(m);
+ fprintf(stderr, "wait completed\n");
+ pa_threaded_mainloop_accept(m);
+ fprintf(stderr, "signal accepted\n");
+
+ pa_threaded_mainloop_unlock(m);
+
+ fprintf(stderr, "waiting 5s (sleep)\n");
+ pa_msleep(5000);
+
+ fprintf(stderr, "shutting down\n");
+
+ pa_threaded_mainloop_stop(m);
+
+ pa_threaded_mainloop_free(m);
+ return 0;
+}
diff --git a/src/tests/thread-test.c b/src/tests/thread-test.c
new file mode 100644
index 00000000..72dde6cb
--- /dev/null
+++ b/src/tests/thread-test.c
@@ -0,0 +1,144 @@
+/* $Id$ */
+
+/***
+ This file is part of PulseAudio.
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/thread.h>
+#include <pulsecore/mutex.h>
+#include <pulsecore/once.h>
+#include <pulsecore/log.h>
+#include <pulsecore/core-util.h>
+#include <pulse/xmalloc.h>
+
+static pa_mutex *mutex = NULL;
+static pa_cond *cond1 = NULL, *cond2 = NULL;
+static pa_tls *tls = NULL;
+
+static int magic_number = 0;
+
+#define THREADS_MAX 20
+
+static void once_func(void) {
+ pa_log("once!");
+}
+
+static pa_once once = PA_ONCE_INIT;
+
+static void thread_func(void *data) {
+ pa_tls_set(tls, data);
+
+ pa_log("thread_func() for %s starting...", (char*) pa_tls_get(tls));
+
+ pa_mutex_lock(mutex);
+
+ for (;;) {
+ int k, n;
+
+ pa_log("%s waiting ...", (char*) pa_tls_get(tls));
+
+ for (;;) {
+
+ if (magic_number < 0)
+ goto quit;
+
+ if (magic_number != 0)
+ break;
+
+ pa_cond_wait(cond1, mutex);
+ }
+
+ k = magic_number;
+ magic_number = 0;
+
+ pa_mutex_unlock(mutex);
+
+ pa_run_once(&once, once_func);
+
+ pa_cond_signal(cond2, 0);
+
+ pa_log("%s got number %i", (char*) pa_tls_get(tls), k);
+
+ /* Spin! */
+ for (n = 0; n < k; n++)
+ pa_thread_yield();
+
+ pa_mutex_lock(mutex);
+ }
+
+quit:
+
+ pa_mutex_unlock(mutex);
+
+ pa_log("thread_func() for %s done...", (char*) pa_tls_get(tls));
+}
+
+int main(int argc, char *argv[]) {
+ int i, k;
+ pa_thread* t[THREADS_MAX];
+
+ assert(pa_thread_is_running(pa_thread_self()));
+
+ mutex = pa_mutex_new(FALSE, FALSE);
+ cond1 = pa_cond_new();
+ cond2 = pa_cond_new();
+ tls = pa_tls_new(pa_xfree);
+
+ for (i = 0; i < THREADS_MAX; i++) {
+ t[i] = pa_thread_new(thread_func, pa_sprintf_malloc("Thread #%i", i+1));
+ assert(t[i]);
+ }
+
+ pa_mutex_lock(mutex);
+
+ pa_log("loop-init");
+
+ for (k = 0; k < 100; k++) {
+ assert(magic_number == 0);
+
+
+ magic_number = (int) rand() % 0x10000;
+
+ pa_log("iteration %i (%i)", k, magic_number);
+
+ pa_cond_signal(cond1, 0);
+
+ pa_cond_wait(cond2, mutex);
+ }
+
+ pa_log("loop-exit");
+
+ magic_number = -1;
+ pa_cond_signal(cond1, 1);
+
+ pa_mutex_unlock(mutex);
+
+ for (i = 0; i < THREADS_MAX; i++)
+ pa_thread_free(t[i]);
+
+ pa_mutex_free(mutex);
+ pa_cond_free(cond1);
+ pa_cond_free(cond2);
+ pa_tls_free(tls);
+
+ return 0;
+}
diff --git a/src/tests/utf8-test.c b/src/tests/utf8-test.c
new file mode 100644
index 00000000..b9594dcc
--- /dev/null
+++ b/src/tests/utf8-test.c
@@ -0,0 +1,26 @@
+/* $Id$ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include <pulse/utf8.h>
+#include <pulse/xmalloc.h>
+
+int main(int argc, char *argv[]) {
+ char *c;
+
+ assert(pa_utf8_valid("hallo"));
+ assert(pa_utf8_valid("hallo\n"));
+ assert(!pa_utf8_valid("hüpfburg\n"));
+ assert(pa_utf8_valid("hallo\n"));
+ assert(pa_utf8_valid("hüpfburg\n"));
+
+ printf("LATIN1: %s\n", c = pa_utf8_filter("hüpfburg"));
+ pa_xfree(c);
+ printf("UTF8: %sx\n", c = pa_utf8_filter("hüpfburg"));
+ pa_xfree(c);
+ printf("LATIN1: %sx\n", c = pa_utf8_filter("üxknärzmörzeltörszß³§dsjkfh"));
+ pa_xfree(c);
+
+ return 0;
+}
diff --git a/src/tests/voltest.c b/src/tests/voltest.c
new file mode 100644
index 00000000..dcc1ec51
--- /dev/null
+++ b/src/tests/voltest.c
@@ -0,0 +1,22 @@
+/* $Id$ */
+
+#include <stdio.h>
+
+#include <pulse/volume.h>
+#include <pulsecore/gccmacro.h>
+
+int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
+ pa_volume_t v;
+
+ for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 256) {
+
+ double dB = pa_sw_volume_to_dB(v);
+ double f = pa_sw_volume_to_linear(v);
+
+ printf("Volume: %3i; percent: %i%%; decibel %0.2f; linear = %0.2f; volume(decibel): %3i; volume(linear): %3i\n",
+ v, (v*100)/PA_VOLUME_NORM, dB, f, pa_sw_volume_from_dB(dB), pa_sw_volume_from_linear(f));
+
+ }
+
+ return 0;
+}