diff options
Diffstat (limited to 'src/tests')
34 files changed, 1309 insertions, 480 deletions
diff --git a/src/tests/Makefile b/src/tests/Makefile deleted file mode 120000 index c110232d..00000000 --- a/src/tests/Makefile +++ /dev/null @@ -1 +0,0 @@ -../pulse/Makefile
\ No newline at end of file diff --git a/src/tests/alsa-time-test.c b/src/tests/alsa-time-test.c index 233bbe64..1a572b30 100644 --- a/src/tests/alsa-time-test.c +++ b/src/tests/alsa-time-test.c @@ -12,7 +12,7 @@ static uint64_t timespec_us(const struct timespec *ts) { int main(int argc, char *argv[]) { const char *dev; - int r; + int r, cap; snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; snd_pcm_status_t *status; @@ -38,8 +38,12 @@ int main(int argc, char *argv[]) { start_us = timespec_us(&start); dev = argc > 1 ? argv[1] : "front:AudioPCI"; + cap = argc > 2 ? atoi(argv[2]) : 0; - r = snd_pcm_open(&pcm, dev, SND_PCM_STREAM_PLAYBACK, 0); + if (cap == 0) + r = snd_pcm_open(&pcm, dev, SND_PCM_STREAM_PLAYBACK, 0); + else + r = snd_pcm_open(&pcm, dev, SND_PCM_STREAM_CAPTURE, 0); assert(r == 0); r = snd_pcm_hw_params_any(pcm, hwparams); @@ -78,7 +82,10 @@ int main(int argc, char *argv[]) { r = snd_pcm_sw_params_current(pcm, swparams); assert(r == 0); - r = snd_pcm_sw_params_set_avail_min(pcm, swparams, 1); + if (cap == 0) + r = snd_pcm_sw_params_set_avail_min(pcm, swparams, 1); + else + r = snd_pcm_sw_params_set_avail_min(pcm, swparams, 0); assert(r == 0); r = snd_pcm_sw_params_set_period_event(pcm, swparams, 0); @@ -117,13 +124,19 @@ int main(int argc, char *argv[]) { r = snd_pcm_poll_descriptors(pcm, pollfds, n_pollfd); assert(r == n_pollfd); + if (cap) { + r = snd_pcm_start(pcm); + assert(r == 0); + } + for (;;) { snd_pcm_sframes_t avail, delay; struct timespec now, timestamp; unsigned short revents; - int written = 0; + int handled = 0; uint64_t now_us, timestamp_us; snd_pcm_state_t state; + unsigned long long pos; r = poll(pollfds, n_pollfd, 0); assert(r >= 0); @@ -131,7 +144,10 @@ int main(int argc, char *argv[]) { r = snd_pcm_poll_descriptors_revents(pcm, pollfds, n_pollfd, &revents); assert(r == 0); - assert((revents & ~POLLOUT) == 0); + if (cap == 0) + assert((revents & ~POLLOUT) == 0); + else + assert((revents & ~POLLIN) == 0); avail = snd_pcm_avail(pcm); assert(avail >= 0); @@ -152,18 +168,22 @@ int main(int argc, char *argv[]) { assert(!revents || avail > 0); - if (avail) { + if ((!cap && avail) || (cap && (unsigned)avail >= buffer_size)) { snd_pcm_sframes_t sframes; - static const uint16_t samples[2] = { 0, 0 }; + static const uint16_t psamples[2] = { 0, 0 }; + uint16_t csamples[2]; - sframes = snd_pcm_writei(pcm, samples, 1); + if (cap == 0) + sframes = snd_pcm_writei(pcm, psamples, 1); + else + sframes = snd_pcm_readi(pcm, csamples, 1); assert(sframes == 1); - written = 1; + handled = 1; sample_count++; } - if (!written && + if (!handled && memcmp(×tamp, &last_timestamp, sizeof(timestamp)) == 0 && avail == last_avail && delay == last_delay) { @@ -174,19 +194,26 @@ int main(int argc, char *argv[]) { now_us = timespec_us(&now); timestamp_us = timespec_us(×tamp); - printf("%llu\t%llu\t%llu\t%li\t%li\t%i\t%i\t%i\n", + if (cap == 0) + pos = (unsigned long long) ((sample_count - handled - delay) * 1000000LU / 44100); + else + pos = (unsigned long long) ((sample_count - handled + delay) * 1000000LU / 44100); + + printf("%llu\t%llu\t%llu\t%llu\t%li\t%li\t%i\t%i\t%i\n", (unsigned long long) (now_us - start_us), (unsigned long long) (timestamp_us ? timestamp_us - start_us : 0), - (unsigned long long) ((sample_count - 1 - delay) * 1000000LU / 44100), + pos, + (unsigned long long) sample_count, (signed long) avail, (signed long) delay, revents, - written, + handled, state); - /** When this assert is hit, most likely something bad - * happened, i.e. the avail jumped suddenly. */ - assert((unsigned) avail <= buffer_size); + if (cap == 0) + /** When this assert is hit, most likely something bad + * happened, i.e. the avail jumped suddenly. */ + assert((unsigned) avail <= buffer_size); last_avail = avail; last_delay = delay; diff --git a/src/tests/asyncmsgq-test.c b/src/tests/asyncmsgq-test.c index 40c74f76..96e5a0df 100644 --- a/src/tests/asyncmsgq-test.c +++ b/src/tests/asyncmsgq-test.c @@ -25,12 +25,9 @@ #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 { @@ -80,7 +77,7 @@ int main(int argc, char *argv[]) { pa_assert_se(q = pa_asyncmsgq_new(0)); - pa_assert_se(t = pa_thread_new(the_thread, q)); + pa_assert_se(t = pa_thread_new("test", the_thread, q)); printf("Operation A post\n"); pa_asyncmsgq_post(q, NULL, OPERATION_A, NULL, 0, NULL, NULL); diff --git a/src/tests/asyncq-test.c b/src/tests/asyncq-test.c index a617e1a0..46bac9f4 100644 --- a/src/tests/asyncq-test.c +++ b/src/tests/asyncq-test.c @@ -26,11 +26,9 @@ #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) { @@ -51,7 +49,7 @@ static void consumer(void *_q) { void *p; int i; - sleep(1); + pa_msleep(1000); for (i = 0;; i++) { p = pa_asyncq_pop(q, TRUE); @@ -73,8 +71,8 @@ int main(int argc, char *argv[]) { 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_assert_se(t1 = pa_thread_new("producer", producer, q)); + pa_assert_se(t2 = pa_thread_new("consumer", consumer, q)); pa_thread_free(t1); pa_thread_free(t2); diff --git a/src/tests/channelmap-test.c b/src/tests/channelmap-test.c index 6cf58fb0..70d6a6a9 100644 --- a/src/tests/channelmap-test.c +++ b/src/tests/channelmap-test.c @@ -6,7 +6,6 @@ #include <assert.h> #include <pulse/channelmap.h> -#include <pulse/gccmacro.h> int main(int argc, char *argv[]) { char cm[PA_CHANNEL_MAP_SNPRINT_MAX]; diff --git a/src/tests/connect-stress.c b/src/tests/connect-stress.c new file mode 100644 index 00000000..eadcf885 --- /dev/null +++ b/src/tests/connect-stress.c @@ -0,0 +1,206 @@ +/*** + 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 + 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 <pulse/pulseaudio.h> +#include <pulse/mainloop.h> + +#include <pulsecore/sink.h> + +/* Set the number of streams such that it allows two simultaneous instances of + * connect-stress to be run and not go above the max limit for streams-per-sink. + * This leaves enough room for a couple other streams from regular system usage, + * which makes a non-error abort less likely (although still easily possible of + * playing >=3 streams outside of the test - including internal loopback, rtp, + * combine, remap streams etc.) */ +#define NSTREAMS ((PA_MAX_INPUTS_PER_SINK/2) - 1) +#define NTESTS 1000 +#define SAMPLE_HZ 44100 + +static pa_context *context = NULL; +static pa_stream *streams[NSTREAMS]; +static pa_threaded_mainloop *mainloop = NULL; + +static const pa_sample_spec sample_spec = { + .format = PA_SAMPLE_FLOAT32, + .rate = SAMPLE_HZ, + .channels = 1 +}; + +static void context_state_callback(pa_context *c, void *userdata); + +static void connect(const char *name, int *try) { + int ret; + pa_mainloop_api *api; + + /* Set up a new main loop */ + mainloop = pa_threaded_mainloop_new(); + assert(mainloop); + + api = pa_threaded_mainloop_get_api(mainloop); + context = pa_context_new(api, name); + assert(context); + + pa_context_set_state_callback(context, context_state_callback, try); + + /* Connect the context */ + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + fprintf(stderr, "pa_context_connect() failed.\n"); + abort(); + } + + ret = pa_threaded_mainloop_start(mainloop); + assert(ret == 0); +} + +static void disconnect(void) { + int i; + + assert(mainloop); + assert(context); + + pa_threaded_mainloop_lock(mainloop); + + for (i = 0; i < NSTREAMS; i++) + if (streams[i]) { + pa_stream_disconnect(streams[i]); + pa_stream_unref(streams[i]); + streams[i] = NULL; + } + + pa_context_disconnect(context); + context = NULL; + + pa_threaded_mainloop_unlock(mainloop); + pa_threaded_mainloop_stop(mainloop); + pa_threaded_mainloop_free(mainloop); + mainloop = NULL; +} + +static const pa_buffer_attr buffer_attr = { + .maxlength = SAMPLE_HZ * sizeof(float) * NSTREAMS, + .tlength = (uint32_t) -1, + .prebuf = 0, /* Setting prebuf to 0 guarantees us the the streams will run synchronously, no matter what */ + .minreq = (uint32_t) -1, + .fragsize = 0 +}; + +static void stream_write_callback(pa_stream *stream, size_t nbytes, void *userdata) { + char silence[8192]; + + memset(silence, 0, sizeof(silence)); + + while (nbytes) { + int n = PA_MIN(sizeof(silence), nbytes); + pa_stream_write(stream, silence, n, NULL, 0, 0); + nbytes -= n; + } +} + +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: + case PA_STREAM_READY: + break; + + default: + case PA_STREAM_FAILED: + fprintf(stderr, "Stream error: %s\n", pa_strerror(pa_context_errno(pa_stream_get_context(s)))); + abort(); + } +} + +static void context_state_callback(pa_context *c, void *userdata) { + int *try; + + assert(c); + assert(userdata); + + try = (int*)userdata; + + 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 (%d of %d) established.\n", (*try)+1, NTESTS); + + for (i = 0; i < NSTREAMS; i++) { + char name[64]; + + 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, NULL); + pa_stream_set_write_callback(streams[i], stream_write_callback, NULL); + pa_stream_connect_playback(streams[i], NULL, &buffer_attr, 0, NULL, NULL); + } + + break; + } + + case PA_CONTEXT_TERMINATED: + fprintf(stderr, "Connection terminated.\n"); + pa_context_unref(context); + context = NULL; + 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[]) { + int i; + + for (i = 0; i < NSTREAMS; i++) + streams[i] = NULL; + + for (i = 0; i < NTESTS; i++) { + connect(argv[0], &i); + usleep(rand() % 500000); + disconnect(); + usleep(rand() % 500000); + } + + fprintf(stderr, "Done.\n"); + + return 0; +} diff --git a/src/tests/cpulimit-test.c b/src/tests/cpulimit-test.c index 9d0f4eef..8bd03417 100644 --- a/src/tests/cpulimit-test.c +++ b/src/tests/cpulimit-test.c @@ -22,19 +22,18 @@ #endif #include <assert.h> -#include <sys/time.h> +#include <time.h> #include <stdlib.h> #include <stdio.h> #include <signal.h> #include <pulse/mainloop.h> -#include <pulse/gccmacro.h> #ifdef TEST2 #include <pulse/mainloop-signal.h> #endif -#include "../daemon/cpulimit.h" +#include <daemon/cpulimit.h> /* A simple example for testing the cpulimit subsystem */ diff --git a/src/tests/envelope-test.c b/src/tests/envelope-test.c deleted file mode 100644 index 3af3044e..00000000 --- a/src/tests/envelope-test.c +++ /dev/null @@ -1,246 +0,0 @@ -/*** - 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 - 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.0f, 0.2f }, - .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.2f, 1.0f }, - .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.8f, 0.7f }, - .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.7f, 0.9f }, - .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 = (unsigned) (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.0f); - - 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_level(PA_LOG_DEBUG); - - pa_assert_se(pool = pa_mempool_new(FALSE, 0)); - 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/extended-test.c b/src/tests/extended-test.c new file mode 100644 index 00000000..631fdc89 --- /dev/null +++ b/src/tests/extended-test.c @@ -0,0 +1,197 @@ +/*** + 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 + 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 <errno.h> +#include <unistd.h> +#include <assert.h> +#include <stdio.h> +#include <stdlib.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_buffer_attr buffer_attr = { + .maxlength = SAMPLE_HZ*sizeof(float)*NSTREAMS, /* exactly space for the entire play time */ + .tlength = (uint32_t) -1, + .prebuf = 0, /* Setting prebuf to 0 guarantees us the the streams will run synchronously, no matter what */ + .minreq = (uint32_t) -1, + .fragsize = 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, (int64_t) sizeof(data) * (int64_t) 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]; + pa_format_info *formats[1]; + + formats[0] = pa_format_info_new(); + formats[0]->encoding = PA_ENCODING_PCM; + pa_format_info_set_sample_format(formats[0], PA_SAMPLE_FLOAT32); + pa_format_info_set_rate(formats[0], SAMPLE_HZ); + pa_format_info_set_channels(formats[0], 1); + + fprintf(stderr, "Creating stream %i\n", i); + + snprintf(name, sizeof(name), "stream #%i", i); + + streams[i] = pa_stream_new_extended(c, name, formats, 1, 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]); + + pa_format_info_free(formats[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); + + /* Connect the context */ + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + fprintf(stderr, "pa_context_connect() failed.\n"); + goto quit; + } + + if (pa_mainloop_run(m, &ret) < 0) + fprintf(stderr, "pa_mainloop_run() failed.\n"); + +quit: + 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/flist-test.c b/src/tests/flist-test.c index 64c0add2..69152041 100644 --- a/src/tests/flist-test.c +++ b/src/tests/flist-test.c @@ -87,7 +87,7 @@ int main(int argc, char* argv[]) { 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)); + threads[i] = pa_thread_new("test", thread_func, pa_sprintf_malloc("Thread #%i", i+1)); assert(threads[i]); } diff --git a/src/tests/format-test.c b/src/tests/format-test.c new file mode 100644 index 00000000..888db8c9 --- /dev/null +++ b/src/tests/format-test.c @@ -0,0 +1,106 @@ +/*** + 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 + 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 <pulsecore/macro.h> +#include <pulse/format.h> + +#define INIT(f) f = pa_format_info_new() +#define DEINIT(f) pa_format_info_free(f); +#define REINIT(f) { DEINIT(f); INIT(f); } + +int main(int argc, char *argv[]) { + pa_format_info *f1 = NULL, *f2 = NULL; + int rates1[] = { 32000, 44100, 48000 }; + const char *strings[] = { "thing1", "thing2", "thing3" }; + + /* 1. Simple fixed format int check */ + INIT(f1); INIT(f2); + f1->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_int(f1, PA_PROP_FORMAT_RATE, 32000); + f2->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 44100); + pa_assert(!pa_format_info_is_compatible(f1, f2)); + + /* 2. Check int array membership - positive */ + REINIT(f1); REINIT(f2); + f1->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_int_array(f1, PA_PROP_FORMAT_RATE, rates1, PA_ELEMENTSOF(rates1)); + f2->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 44100); + pa_assert(pa_format_info_is_compatible(f1, f2)); + pa_assert(pa_format_info_is_compatible(f2, f1)); + + /* 3. Check int array memebership - negative */ + REINIT(f2); + f2->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 96000); + pa_assert(!pa_format_info_is_compatible(f1, f2)); + pa_assert(!pa_format_info_is_compatible(f2, f1)); + + /* 4. Check int range - positive */ + REINIT(f1); REINIT(f2); + f1->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_int_range(f1, PA_PROP_FORMAT_RATE, 32000, 48000); + f2->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 44100); + pa_assert(pa_format_info_is_compatible(f1, f2)); + pa_assert(pa_format_info_is_compatible(f2, f1)); + + /* 5. Check int range - negative */ + REINIT(f2); + f2->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_int(f2, PA_PROP_FORMAT_RATE, 96000); + pa_assert(!pa_format_info_is_compatible(f1, f2)); + pa_assert(!pa_format_info_is_compatible(f2, f1)); + + /* 6. Simple fixed format string check */ + REINIT(f1); REINIT(f2); + f1->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_string(f1, "format.test_string", "thing1"); + f2->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_string(f2, "format.test_string", "notthing1"); + pa_assert(!pa_format_info_is_compatible(f1, f2)); + + /* 7. Check string array membership - positive */ + REINIT(f1); REINIT(f2); + f1->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_string_array(f1, "format.test_string", strings, PA_ELEMENTSOF(strings)); + f2->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_string(f2, "format.test_string", "thing3"); + pa_assert(pa_format_info_is_compatible(f1, f2)); + pa_assert(pa_format_info_is_compatible(f2, f1)); + + /* 8. Check string array memebership - negative */ + REINIT(f2); + f2->encoding = PA_ENCODING_AC3_IEC61937; + pa_format_info_set_prop_string(f2, "format.test_string", "thing5"); + pa_assert(!pa_format_info_is_compatible(f1, f2)); + pa_assert(!pa_format_info_is_compatible(f2, f1)); + + DEINIT(f1); + DEINIT(f2); + + return 0; +} diff --git a/src/tests/get-binary-name-test.c b/src/tests/get-binary-name-test.c index a34e38fd..4afe81b3 100644 --- a/src/tests/get-binary-name-test.c +++ b/src/tests/get-binary-name-test.c @@ -21,14 +21,34 @@ #include <config.h> #endif -#include <limits.h> #include <stdio.h> +#include <string.h> #include <pulse/util.h> +#include <pulse/xmalloc.h> int main(int argc, char *argv[]) { - char exename[PATH_MAX]; + char *exename; + size_t allocated = 128; + + for (;;) { + exename = pa_xmalloc(allocated); + + if (!pa_get_binary_name(exename, allocated)) { + printf("failed to read binary name\n"); + pa_xfree(exename); + break; + } + + if (strlen(exename) < allocated - 1) { + printf("%s\n", exename); + pa_xfree(exename); + break; + } + + pa_xfree(exename); + allocated *= 2; + } - printf("%s\n", pa_get_binary_name(exename, sizeof(exename))); return 0; } diff --git a/src/tests/interpol-test.c b/src/tests/interpol-test.c index 0c906d3e..ffe4ab38 100644 --- a/src/tests/interpol-test.c +++ b/src/tests/interpol-test.c @@ -28,8 +28,6 @@ #include <assert.h> #include <stdio.h> #include <stdlib.h> -#include <getopt.h> -#include <math.h> #include <pulse/pulseaudio.h> #include <pulse/mainloop.h> @@ -43,20 +41,37 @@ static pa_context *context = NULL; static pa_stream *stream = NULL; static pa_mainloop_api *mainloop_api = NULL; static pa_bool_t playback = TRUE; +static pa_usec_t latency = 0; static void stream_write_cb(pa_stream *p, size_t nbytes, void *userdata) { /* Just some silence */ - pa_assert_se(pa_stream_write(p, pa_xmalloc0(nbytes), nbytes, pa_xfree, 0, PA_SEEK_RELATIVE) == 0); + + for (;;) { + void *data; + + pa_assert_se((nbytes = pa_stream_writable_size(p)) != (size_t) -1); + + if (nbytes <= 0) + break; + + pa_assert_se(pa_stream_begin_write(p, &data, &nbytes) == 0); + pa_memzero(data, nbytes); + pa_assert_se(pa_stream_write(p, data, nbytes, NULL, 0, PA_SEEK_RELATIVE) == 0); + } } static void stream_read_cb(pa_stream *p, size_t nbytes, void *userdata) { - /* We don't care, just drop the data */ + /* We don't care about the data, just drop it */ - while (pa_stream_readable_size(p) > 0) { - const void *d; - size_t b; + for (;;) { + const void *data; - pa_assert_se(pa_stream_peek(p, &d, &b) == 0); + pa_assert_se((nbytes = pa_stream_readable_size(p)) != (size_t) -1); + + if (nbytes <= 0) + break; + + pa_assert_se(pa_stream_peek(p, &data, &nbytes) == 0); pa_assert_se(pa_stream_drop(p) == 0); } } @@ -82,27 +97,36 @@ static void context_state_callback(pa_context *c, void *userdata) { case PA_CONTEXT_READY: { pa_stream_flags_t flags = PA_STREAM_AUTO_TIMING_UPDATE; - + pa_buffer_attr attr; static const pa_sample_spec ss = { .format = PA_SAMPLE_S16LE, .rate = 44100, .channels = 2 }; + pa_zero(attr); + attr.maxlength = (uint32_t) -1; + attr.tlength = latency > 0 ? (uint32_t) pa_usec_to_bytes(latency, &ss) : (uint32_t) -1; + attr.prebuf = (uint32_t) -1; + attr.minreq = (uint32_t) -1; + attr.fragsize = (uint32_t) -1; + #ifdef INTERPOLATE flags |= PA_STREAM_INTERPOLATE_TIMING; #endif + if (latency > 0) + flags |= PA_STREAM_ADJUST_LATENCY; + fprintf(stderr, "Connection established.\n"); - stream = pa_stream_new(c, "interpol-test", &ss, NULL); - assert(stream); + pa_assert_se(stream = pa_stream_new(c, "interpol-test", &ss, NULL)); if (playback) { - pa_assert_se(pa_stream_connect_playback(stream, NULL, NULL, flags, NULL, NULL) == 0); + pa_assert_se(pa_stream_connect_playback(stream, NULL, &attr, flags, NULL, NULL) == 0); pa_stream_set_write_callback(stream, stream_write_cb, NULL); } else { - pa_assert_se(pa_stream_connect_record(stream, NULL, NULL, flags) == 0); + pa_assert_se(pa_stream_connect_record(stream, NULL, &attr, flags) == 0); pa_stream_set_read_callback(stream, stream_read_cb, NULL); } @@ -123,7 +147,7 @@ static void context_state_callback(pa_context *c, void *userdata) { int main(int argc, char *argv[]) { pa_threaded_mainloop* m = NULL; - int k, r; + int k; struct timeval start, last_info = { 0, 0 }; pa_usec_t old_t = 0, old_rtc = 0; #ifdef CORK @@ -134,24 +158,22 @@ int main(int argc, char *argv[]) { playback = argc <= 1 || !pa_streq(argv[1], "-r"); - /* Set up a new main loop */ - m = pa_threaded_mainloop_new(); - assert(m); - - mainloop_api = pa_threaded_mainloop_get_api(m); + latency = + (argc >= 2 && !pa_streq(argv[1], "-r")) ? atoi(argv[1]) : + (argc >= 3 ? atoi(argv[2]) : 0); - context = pa_context_new(mainloop_api, argv[0]); - assert(context); + /* Set up a new main loop */ + pa_assert_se(m = pa_threaded_mainloop_new()); + pa_assert_se(mainloop_api = pa_threaded_mainloop_get_api(m)); + pa_assert_se(context = pa_context_new(mainloop_api, argv[0])); pa_context_set_state_callback(context, context_state_callback, NULL); - r = pa_context_connect(context, NULL, 0, NULL); - assert(r >= 0); + pa_assert_se(pa_context_connect(context, NULL, 0, NULL) >= 0); pa_gettimeofday(&start); - r = pa_threaded_mainloop_start(m); - assert(r >= 0); + pa_assert_se(pa_threaded_mainloop_start(m) >= 0); /* #ifdef CORK */ for (k = 0; k < 20000; k++) @@ -160,7 +182,7 @@ int main(int argc, char *argv[]) { /* #endif */ { pa_bool_t success = FALSE, changed = FALSE; - pa_usec_t t, rtc; + pa_usec_t t, rtc, d; struct timeval now, tv; pa_bool_t playing = FALSE; @@ -169,7 +191,8 @@ int main(int argc, char *argv[]) { if (stream) { const pa_timing_info *info; - if (pa_stream_get_time(stream, &t) >= 0) + if (pa_stream_get_time(stream, &t) >= 0 && + pa_stream_get_latency(stream, &d, NULL) >= 0) success = TRUE; if ((info = pa_stream_get_timing_info(stream))) { @@ -191,14 +214,16 @@ int main(int argc, char *argv[]) { pa_bool_t cork_now; #endif rtc = pa_timeval_diff(&now, &start); - printf("%i\t%llu\t%llu\t%llu\t%llu\t%lli\t%u\t%u\n", k, + printf("%i\t%llu\t%llu\t%llu\t%llu\t%lli\t%u\t%u\t%llu\t%llu\n", k, (unsigned long long) rtc, (unsigned long long) t, (unsigned long long) (rtc-old_rtc), (unsigned long long) (t-old_t), (signed long long) rtc - (signed long long) t, changed, - playing); + playing, + (unsigned long long) latency, + (unsigned long long) d); fflush(stdout); old_t = t; diff --git a/src/tests/ipacl-test.c b/src/tests/ipacl-test.c index f89665cd..be9caadf 100644 --- a/src/tests/ipacl-test.c +++ b/src/tests/ipacl-test.c @@ -8,9 +8,6 @@ #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 @@ -20,14 +17,11 @@ #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/macro.h" +#include <pulsecore/socket.h> +#include <pulsecore/macro.h> #include <pulsecore/ipacl.h> +#include <pulsecore/arpa-inet.h> int main(int argc, char *argv[]) { struct sockaddr_in sa; @@ -91,8 +85,10 @@ int main(int argc, char *argv[]) { close(fd); #ifdef HAVE_IPV6 - fd = socket(PF_INET6, SOCK_STREAM, 0); - assert(fd >= 0); + if ( (fd = socket(PF_INET6, SOCK_STREAM, 0)) < 0 ) { + printf("Unable to open IPv6 socket, IPv6 tests ignored"); + return 0; + } memset(&sa6, 0, sizeof(sa6)); sa6.sin6_family = AF_INET6; diff --git a/src/tests/lock-autospawn-test.c b/src/tests/lock-autospawn-test.c index c754e230..9ba61296 100644 --- a/src/tests/lock-autospawn-test.c +++ b/src/tests/lock-autospawn-test.c @@ -23,9 +23,9 @@ #include <config.h> #endif -#include <sys/poll.h> #include <string.h> +#include <pulsecore/poll.h> #include <pulsecore/macro.h> #include <pulsecore/thread.h> #include <pulsecore/lock-autospawn.h> @@ -69,7 +69,7 @@ static void thread_func2(void *k) { pollfd.fd = fd; pollfd.events = POLLIN; - pa_assert_se(poll(&pollfd, 1, -1) == 1); + pa_assert_se(pa_poll(&pollfd, 1, -1) == 1); pa_log("%i, woke up", PA_PTR_TO_INT(k)); } @@ -88,10 +88,10 @@ static void thread_func2(void *k) { int main(int argc, char**argv) { pa_thread *a, *b, *c, *d; - pa_assert_se((a = pa_thread_new(thread_func, PA_INT_TO_PTR(1)))); - pa_assert_se((b = pa_thread_new(thread_func2, PA_INT_TO_PTR(2)))); - pa_assert_se((c = pa_thread_new(thread_func2, PA_INT_TO_PTR(3)))); - pa_assert_se((d = pa_thread_new(thread_func, PA_INT_TO_PTR(4)))); + pa_assert_se((a = pa_thread_new("test1", thread_func, PA_INT_TO_PTR(1)))); + pa_assert_se((b = pa_thread_new("test2", thread_func2, PA_INT_TO_PTR(2)))); + pa_assert_se((c = pa_thread_new("test3", thread_func2, PA_INT_TO_PTR(3)))); + pa_assert_se((d = pa_thread_new("test4", thread_func, PA_INT_TO_PTR(4)))); pa_thread_join(a); pa_thread_join(b); diff --git a/src/tests/mainloop-test.c b/src/tests/mainloop-test.c index 4ca63513..ab23de43 100644 --- a/src/tests/mainloop-test.c +++ b/src/tests/mainloop-test.c @@ -26,10 +26,11 @@ #include <sys/time.h> #include <assert.h> +#include <pulse/rtclock.h> #include <pulse/timeval.h> -#include <pulse/gccmacro.h> #include <pulsecore/core-util.h> +#include <pulsecore/core-rtclock.h> #ifdef GLIB_MAIN_LOOP @@ -46,7 +47,7 @@ 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; - (void) read(fd, &c, sizeof(c)); + pa_assert_se(read(fd, &c, sizeof(c)) >= 0); fprintf(stderr, "IO EVENT: %c\n", c < 32 ? '.' : c); a->defer_enable(de, 1); } @@ -99,9 +100,7 @@ int main(int argc, char *argv[]) { de = a->defer_new(a, dcb, NULL); assert(de); - pa_gettimeofday(&tv); - tv.tv_sec += 10; - te = a->time_new(a, &tv, tcb, NULL); + te = a->time_new(a, pa_timeval_rtstore(&tv, pa_rtclock_now() + 2 * PA_USEC_PER_SEC, TRUE), tcb, NULL); #if defined(GLIB_MAIN_LOOP) g_main_loop_run(glib_main_loop); diff --git a/src/tests/mcalign-test.c b/src/tests/mcalign-test.c index 92e3e14e..75a71dd1 100644 --- a/src/tests/mcalign-test.c +++ b/src/tests/mcalign-test.c @@ -29,8 +29,6 @@ #include <stdlib.h> #include <time.h> -#include <pulse/gccmacro.h> - #include <pulsecore/core-util.h> #include <pulsecore/mcalign.h> diff --git a/src/tests/memblockq-test.c b/src/tests/memblockq-test.c index ec3f5426..b6c60039 100644 --- a/src/tests/memblockq-test.c +++ b/src/tests/memblockq-test.c @@ -29,23 +29,39 @@ #include <pulsecore/memblockq.h> #include <pulsecore/log.h> +static void dump_chunk(const pa_memchunk *chunk) { + size_t n; + void *q; + char *e; + + pa_assert(chunk); + + q = pa_memblock_acquire(chunk->memblock); + for (e = (char*) q + chunk->index, n = 0; n < chunk->length; n++, e++) + printf("%c", *e); + pa_memblock_release(chunk->memblock); +} + static void dump(pa_memblockq *bq) { - printf(">"); + pa_memchunk out; - for (;;) { - pa_memchunk out; - char *e; - size_t n; - void *q; + pa_assert(bq); + /* First let's dump this as fixed block */ + printf("FIXED >"); + pa_memblockq_peek_fixed_size(bq, 64, &out); + dump_chunk(&out); + pa_memblock_unref(out.memblock); + printf("<\n"); + + /* Then let's dump the queue manually */ + printf("MANUAL>"); + + for (;;) { if (pa_memblockq_peek(bq, &out) < 0) break; - q = pa_memblock_acquire(out.memblock); - for (e = (char*) q + out.index, n = 0; n < out.length; n++) - printf("%c", *e); - pa_memblock_release(out.memblock); - + dump_chunk(&out); pa_memblock_unref(out.memblock); pa_memblockq_drop(bq, out.length); } @@ -65,12 +81,12 @@ int main(int argc, char *argv[]) { p = pa_mempool_new(FALSE, 0); - silence.memblock = pa_memblock_new_fixed(p, (char*) "__", 2, 1); + silence.memblock = pa_memblock_new_fixed(p, (char*) "__", 2, 1); assert(silence.memblock); silence.index = 0; silence.length = pa_memblock_get_length(silence.memblock); - bq = pa_memblockq_new(0, 40, 10, 2, 4, 4, 40, &silence); + bq = pa_memblockq_new(0, 200, 10, 2, 4, 4, 40, &silence); assert(bq); chunk1.memblock = pa_memblock_new_fixed(p, (char*) "11", 2, 1); diff --git a/src/tests/mix-test.c b/src/tests/mix-test.c index ac4b57b5..7c05b8ed 100644 --- a/src/tests/mix-test.c +++ b/src/tests/mix-test.c @@ -26,20 +26,11 @@ #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; @@ -69,6 +60,8 @@ static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) { break; } + case PA_SAMPLE_S24_32NE: + case PA_SAMPLE_S24_32RE: case PA_SAMPLE_S32NE: case PA_SAMPLE_S32RE: { uint32_t *u = d; @@ -79,12 +72,24 @@ static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) { break; } + case PA_SAMPLE_S24NE: + case PA_SAMPLE_S24RE: { + uint8_t *u = d; + + for (i = 0; i < chunk->length / pa_frame_size(ss); i++) { + printf("0x%02x%02x%02xx ", *u, *(u+1), *(u+2)); + u += 3; + } + + 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)); + printf("%1.5f ", ss->format == PA_SAMPLE_FLOAT32NE ? *u : PA_FLOAT32_SWAP(*u)); u++; } @@ -113,73 +118,72 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) { case PA_SAMPLE_U8: case PA_SAMPLE_ULAW: case PA_SAMPLE_ALAW: { - uint8_t *u = d; + static const uint8_t u8_samples[] = { + 0x00, 0xFF, 0x7F, 0x80, 0x9f, + 0x3f, 0x01, 0xF0, 0x20, 0x21 + }; - 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; + memcpy(d, u8_samples, sizeof(u8_samples)); break; } case PA_SAMPLE_S16NE: case PA_SAMPLE_S16RE: { - uint16_t *u = d; + static const uint16_t u16_samples[] = { + 0x0000, 0xFFFF, 0x7FFF, 0x8000, 0x9fff, + 0x3fff, 0x0001, 0xF000, 0x0020, 0x0021 + }; - 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; + memcpy(d, u16_samples, sizeof(u16_samples)); break; } + case PA_SAMPLE_S24_32NE: + case PA_SAMPLE_S24_32RE: case PA_SAMPLE_S32NE: case PA_SAMPLE_S32RE: { - uint32_t *u = d; + static const uint32_t u32_samples[] = { + 0x00000001, 0xFFFF0002, 0x7FFF0003, 0x80000004, 0x9fff0005, + 0x3fff0006, 0x00010007, 0xF0000008, 0x00200009, 0x0021000A + }; + + memcpy(d, u32_samples, sizeof(u32_samples)); + break; + } - 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; + case PA_SAMPLE_S24NE: + case PA_SAMPLE_S24RE: { + /* Need to be on a byte array because they are not aligned */ + static const uint8_t u24_samples[] = { + 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0x02, + 0x7F, 0xFF, 0x03, + 0x80, 0x00, 0x04, + 0x9f, 0xff, 0x05, + 0x3f, 0xff, 0x06, + 0x01, 0x00, 0x07, + 0xF0, 0x00, 0x08, + 0x20, 0x00, 0x09, + 0x21, 0x00, 0x0A + }; + + memcpy(d, u24_samples, sizeof(u24_samples)); break; } case PA_SAMPLE_FLOAT32NE: case PA_SAMPLE_FLOAT32RE: { float *u = d; + static const float float_samples[] = { + 0.0f, -1.0f, 1.0f, 4711.0f, 0.222f, + 0.33f, -.3f, 99.0f, -0.555f, -.123f + }; - u[0] = 0.0f; - u[1] = -1.0f; - u[2] = 1.0f; - u[3] = 4711.0f; - u[4] = 0.222f; - u[5] = 0.33f; - u[6] = -.3f; - u[7] = 99.0f; - u[8] = -0.555f; - u[9] = -.123f; - - if (ss->format == PA_SAMPLE_FLOAT32RE) + if (ss->format == PA_SAMPLE_FLOAT32RE) { for (i = 0; i < 10; i++) - u[i] = swap_float(u[i]); + u[i] = PA_FLOAT32_SWAP(float_samples[i]); + } else + memcpy(d, float_samples, sizeof(float_samples)); break; } @@ -198,7 +202,6 @@ int main(int argc, char *argv[]) { pa_sample_spec a; pa_cvolume v; - oil_init(); pa_log_set_level(PA_LOG_DEBUG); pa_assert_se(pool = pa_mempool_new(FALSE, 0)); diff --git a/src/tests/once-test.c b/src/tests/once-test.c new file mode 100644 index 00000000..8a9995da --- /dev/null +++ b/src/tests/once-test.c @@ -0,0 +1,111 @@ +/*** + 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 + 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 + +#ifdef HAVE_PTHREAD +#include <pthread.h> +#endif + +#include <pulsecore/thread.h> +#include <pulsecore/once.h> +#include <pulsecore/log.h> +#include <pulsecore/core-util.h> +#include <pulsecore/atomic.h> +#include <pulse/xmalloc.h> + +static pa_once once = PA_ONCE_INIT; +static volatile unsigned n_run = 0; +static const char * volatile ran_by = NULL; +#ifdef HAVE_PTHREAD +static pthread_barrier_t barrier; +#endif +static unsigned n_cpu; + +#define N_ITERATIONS 500 +#define N_THREADS 100 + +static void once_func(void) { + n_run++; + ran_by = (const char*) pa_thread_get_data(pa_thread_self()); +} + +static void thread_func(void *data) { +#ifdef HAVE_PTHREAD + int r; + +#ifdef HAVE_PTHREAD_SETAFFINITY_NP + static pa_atomic_t i_cpu = PA_ATOMIC_INIT(0); + cpu_set_t mask; + + CPU_ZERO(&mask); + CPU_SET((size_t) (pa_atomic_inc(&i_cpu) % n_cpu), &mask); + pa_assert_se(pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) == 0); +#endif + + /* pa_log("started up: %s", data); */ + + r = pthread_barrier_wait(&barrier); + pa_assert(r == 0 || r == PTHREAD_BARRIER_SERIAL_THREAD); +#endif /* HAVE_PTHREAD */ + + pa_run_once(&once, once_func); +} + +int main(int argc, char *argv[]) { + unsigned n, i; + + n_cpu = pa_ncpus(); + + for (n = 0; n < N_ITERATIONS; n++) { + pa_thread* threads[N_THREADS]; + +#ifdef HAVE_PTHREAD + pa_assert_se(pthread_barrier_init(&barrier, NULL, N_THREADS) == 0); +#endif + + /* Yes, kinda ugly */ + pa_zero(once); + + for (i = 0; i < N_THREADS; i++) + threads[i] = pa_thread_new("once", thread_func, pa_sprintf_malloc("Thread #%i", i+1)); + + for (i = 0; i < N_THREADS; i++) + pa_thread_join(threads[i]); + + pa_assert(n_run == 1); + pa_log("ran by %s", ran_by); + + for (i = 0; i < N_THREADS; i++) { + pa_xfree(pa_thread_get_data(threads[i])); + pa_thread_free(threads[i]); + } + + n_run = 0; + ran_by = NULL; + +#ifdef HAVE_PTHREAD + pa_assert_se(pthread_barrier_destroy(&barrier) == 0); +#endif + } + + return 0; +} diff --git a/src/tests/pacat-simple.c b/src/tests/pacat-simple.c index d4224e11..7d119c44 100644 --- a/src/tests/pacat-simple.c +++ b/src/tests/pacat-simple.c @@ -29,7 +29,6 @@ #include <pulse/simple.h> #include <pulse/error.h> -#include <pulse/gccmacro.h> #define BUFSIZE 1024 diff --git a/src/tests/parec-simple.c b/src/tests/parec-simple.c index 9f19ff47..dfa43f0f 100644 --- a/src/tests/parec-simple.c +++ b/src/tests/parec-simple.c @@ -28,7 +28,6 @@ #include <pulse/simple.h> #include <pulse/error.h> -#include <pulse/gccmacro.h> #define BUFSIZE 1024 diff --git a/src/tests/queue-test.c b/src/tests/queue-test.c index 7ee2693d..b21775e8 100644 --- a/src/tests/queue-test.c +++ b/src/tests/queue-test.c @@ -25,11 +25,8 @@ #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[]) { diff --git a/src/tests/remix-test.c b/src/tests/remix-test.c index 9d110d6b..19f5582b 100644 --- a/src/tests/remix-test.c +++ b/src/tests/remix-test.c @@ -24,15 +24,10 @@ #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[]) { @@ -55,7 +50,6 @@ int main(int argc, char *argv[]) { unsigned i, j; pa_mempool *pool; - oil_init(); pa_log_set_level(PA_LOG_DEBUG); pa_assert_se(pool = pa_mempool_new(FALSE, 0)); diff --git a/src/tests/resampler-test.c b/src/tests/resampler-test.c index 7236265a..78461da5 100644 --- a/src/tests/resampler-test.c +++ b/src/tests/resampler-test.c @@ -22,7 +22,13 @@ #endif #include <stdio.h> +#include <getopt.h> +#include <locale.h> +#include <pulse/i18n.h> +#include <pulse/pulseaudio.h> + +#include <pulse/rtclock.h> #include <pulse/sample.h> #include <pulse/volume.h> @@ -31,8 +37,7 @@ #include <pulsecore/endianmacros.h> #include <pulsecore/memblock.h> #include <pulsecore/sample-util.h> - -#include <liboil/liboil.h> +#include <pulsecore/core-util.h> static void dump_block(const pa_sample_spec *ss, const pa_memchunk *chunk) { void *d; @@ -243,34 +248,209 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) { return r; } +static void help(const char *argv0) { + printf(_("%s [options]\n\n" + "-h, --help Show this help\n" + "-v, --verbose Print debug messages\n" + " --from-rate=SAMPLERATE From sample rate in Hz (defaults to 44100)\n" + " --from-format=SAMPLEFORMAT From sample type (defaults to s16le)\n" + " --from-channels=CHANNELS From number of channels (defaults to 1)\n" + " --to-rate=SAMPLERATE To sample rate in Hz (defaults to 44100)\n" + " --to-format=SAMPLEFORMAT To sample type (defaults to s16le)\n" + " --to-channels=CHANNELS To number of channels (defaults to 1)\n" + " --resample-method=METHOD Resample method (defaults to auto)\n" + " --seconds=SECONDS From stream duration (defaults to 60)\n" + "\n" + "If the formats are not specified, the test performs all formats combinations,\n" + "back and forth.\n" + "\n" + "Sample type must be one of s16le, s16be, u8, float32le, float32be, ulaw, alaw,\n" + "32le, s32be (defaults to s16ne)\n" + "\n" + "See --dump-resample-methods for possible values of resample methods.\n"), + argv0); +} + +enum { + ARG_VERSION = 256, + ARG_FROM_SAMPLERATE, + ARG_FROM_SAMPLEFORMAT, + ARG_FROM_CHANNELS, + ARG_TO_SAMPLERATE, + ARG_TO_SAMPLEFORMAT, + ARG_TO_CHANNELS, + ARG_SECONDS, + ARG_RESAMPLE_METHOD, + ARG_DUMP_RESAMPLE_METHODS +}; + +static void dump_resample_methods(void) { + int i; + + for (i = 0; i < PA_RESAMPLER_MAX; i++) + if (pa_resample_method_supported(i)) + printf("%s\n", pa_resample_method_to_string(i)); + +} + int main(int argc, char *argv[]) { - pa_mempool *pool; + pa_mempool *pool = NULL; pa_sample_spec a, b; pa_cvolume v; + int ret = 1, verbose = 0, c; + pa_bool_t all_formats = TRUE; + pa_resample_method_t method; + int seconds; + + static const struct option long_options[] = { + {"help", 0, NULL, 'h'}, + {"verbose", 0, NULL, 'v'}, + {"version", 0, NULL, ARG_VERSION}, + {"from-rate", 1, NULL, ARG_FROM_SAMPLERATE}, + {"from-format", 1, NULL, ARG_FROM_SAMPLEFORMAT}, + {"from-channels", 1, NULL, ARG_FROM_CHANNELS}, + {"to-rate", 1, NULL, ARG_TO_SAMPLERATE}, + {"to-format", 1, NULL, ARG_TO_SAMPLEFORMAT}, + {"to-channels", 1, NULL, ARG_TO_CHANNELS}, + {"seconds", 1, NULL, ARG_SECONDS}, + {"resample-method", 1, NULL, ARG_RESAMPLE_METHOD}, + {"dump-resample-methods", 0, NULL, ARG_DUMP_RESAMPLE_METHODS}, + {NULL, 0, NULL, 0} + }; + + setlocale(LC_ALL, ""); + bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR); - oil_init(); pa_log_set_level(PA_LOG_DEBUG); pa_assert_se(pool = pa_mempool_new(FALSE, 0)); a.channels = b.channels = 1; a.rate = b.rate = 44100; - + a.format = b.format = PA_SAMPLE_S16LE; v.channels = a.channels; v.values[0] = pa_sw_volume_from_linear(0.5); + method = PA_RESAMPLER_AUTO; + seconds = 60; + + while ((c = getopt_long(argc, argv, "hv", long_options, NULL)) != -1) { + + switch (c) { + case 'h' : + help(argv[0]); + ret = 0; + goto quit; + + case 'v': + pa_log_set_level(PA_LOG_DEBUG); + verbose = 1; + break; + + case ARG_VERSION: + printf(_("%s %s\n"), argv[0], PACKAGE_VERSION); + ret = 0; + goto quit; + + case ARG_DUMP_RESAMPLE_METHODS: + dump_resample_methods(); + ret = 0; + goto quit; + + case ARG_FROM_CHANNELS: + a.channels = (uint8_t) atoi(optarg); + break; + + case ARG_FROM_SAMPLEFORMAT: + a.format = pa_parse_sample_format(optarg); + all_formats = FALSE; + break; + + case ARG_FROM_SAMPLERATE: + a.rate = (uint32_t) atoi(optarg); + break; + + case ARG_TO_CHANNELS: + b.channels = (uint8_t) atoi(optarg); + break; + + case ARG_TO_SAMPLEFORMAT: + b.format = pa_parse_sample_format(optarg); + all_formats = FALSE; + break; + + case ARG_TO_SAMPLERATE: + b.rate = (uint32_t) atoi(optarg); + break; + + case ARG_SECONDS: + seconds = atoi(optarg); + break; + + case ARG_RESAMPLE_METHOD: + if (*optarg == '\0' || pa_streq(optarg, "help")) { + dump_resample_methods(); + ret = 0; + goto quit; + } + method = pa_parse_resample_method(optarg); + break; + + default: + goto quit; + } + } + + ret = 0; + pa_assert_se(pool = pa_mempool_new(FALSE, 0)); + + if (!all_formats) { + + pa_resampler *resampler; + pa_memchunk i, j; + pa_usec_t ts; + + if (verbose) { + printf(_("Compilation CFLAGS: %s\n"), PA_CFLAGS); + printf(_("=== %d seconds: %d Hz %d ch (%s) -> %d Hz %d ch (%s)\n"), seconds, + a.rate, a.channels, pa_sample_format_to_string(a.format), + b.rate, b.channels, pa_sample_format_to_string(b.format)); + } + + ts = pa_rtclock_now(); + pa_assert_se(resampler = pa_resampler_new(pool, &a, NULL, &b, NULL, method, 0)); + printf("init: %llu\n", (long long unsigned)(pa_rtclock_now() - ts)); + + i.memblock = pa_memblock_new(pool, pa_usec_to_bytes(1*PA_USEC_PER_SEC, &a) / pa_frame_size(&a)); + + ts = pa_rtclock_now(); + i.length = pa_memblock_get_length(i.memblock); + i.index = 0; + while (seconds--) { + pa_resampler_run(resampler, &i, &j); + pa_memblock_unref(j.memblock); + } + printf("resampling: %llu\n", (long long unsigned)(pa_rtclock_now() - ts)); + pa_memblock_unref(i.memblock); + + pa_resampler_free(resampler); + + goto quit; + } + 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)); + if (verbose) + 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)); + pa_assert_se(forth = pa_resampler_new(pool, &a, NULL, &b, NULL, method, 0)); + pa_assert_se(back = pa_resampler_new(pool, &b, NULL, &a, NULL, method, 0)); i.memblock = generate_block(pool, &a); i.length = pa_memblock_get_length(i.memblock); @@ -299,7 +479,9 @@ int main(int argc, char *argv[]) { } } - pa_mempool_free(pool); + quit: + if (pool) + pa_mempool_free(pool); - return 0; + return ret; } diff --git a/src/tests/rtpoll-test.c b/src/tests/rtpoll-test.c index 4ac96446..6a6b73a8 100644 --- a/src/tests/rtpoll-test.c +++ b/src/tests/rtpoll-test.c @@ -22,11 +22,10 @@ #endif #include <signal.h> -#include <poll.h> +#include <pulsecore/poll.h> #include <pulsecore/log.h> #include <pulsecore/rtpoll.h> -#include <pulsecore/rtsig.h> static int before(pa_rtpoll_item *i) { pa_log("before"); @@ -47,10 +46,6 @@ int main(int argc, char *argv[]) { 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); @@ -64,7 +59,6 @@ int main(int argc, char *argv[]) { 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_relative(p, 10000000); /* 10 s */ pa_rtpoll_run(p, 1); diff --git a/src/tests/rtstutter.c b/src/tests/rtstutter.c index f04d43af..739683d5 100644 --- a/src/tests/rtstutter.c +++ b/src/tests/rtstutter.c @@ -26,73 +26,69 @@ #include <stdlib.h> #include <unistd.h> #include <time.h> -#include <sched.h> #include <inttypes.h> -#include <string.h> + +#ifdef HAVE_PTHREAD #include <pthread.h> +#endif +#include <pulse/util.h> #include <pulse/timeval.h> #include <pulse/gccmacro.h> #include <pulsecore/log.h> #include <pulsecore/macro.h> +#include <pulsecore/thread.h> #include <pulsecore/core-util.h> +#include <pulsecore/core-rtclock.h> static int msec_lower, msec_upper; -static void* work(void *p) PA_GCC_NORETURN; +static void work(void *p) PA_GCC_NORETURN; -static void* work(void *p) { -#ifdef HAVE_PTHREAD_SETAFFINITY_NP - cpu_set_t mask; -#endif - struct sched_param param; +static void work(void *p) { pa_log_notice("CPU%i: Created thread.", PA_PTR_TO_UINT(p)); - memset(¶m, 0, sizeof(param)); - param.sched_priority = 12; - pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m) == 0); + pa_make_realtime(12); #ifdef HAVE_PTHREAD_SETAFFINITY_NP +{ + cpu_set_t mask; + CPU_ZERO(&mask); CPU_SET((size_t) PA_PTR_TO_UINT(p), &mask); pa_assert_se(pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) == 0); +} #endif for (;;) { - struct timespec now, end; - uint64_t nsec; + struct timeval now, end; + uint64_t usec; pa_log_notice("CPU%i: Sleeping for 1s", PA_PTR_TO_UINT(p)); - sleep(1); - - pa_assert_se(clock_gettime(CLOCK_REALTIME, &end) == 0); + pa_msleep(1000); - nsec = - (uint64_t) ((((double) rand())*(double)(msec_upper-msec_lower)*PA_NSEC_PER_MSEC)/RAND_MAX) + - (uint64_t) ((uint64_t) msec_lower*PA_NSEC_PER_MSEC); + usec = + (uint64_t) ((((double) rand())*(double)(msec_upper-msec_lower)*PA_USEC_PER_MSEC)/RAND_MAX) + + (uint64_t) ((uint64_t) msec_lower*PA_USEC_PER_MSEC); - pa_log_notice("CPU%i: Freezing for %ims", PA_PTR_TO_UINT(p), (int) (nsec/PA_NSEC_PER_MSEC)); + pa_log_notice("CPU%i: Freezing for %ims", PA_PTR_TO_UINT(p), (int) (usec/PA_USEC_PER_MSEC)); - end.tv_sec += (time_t) (nsec / PA_NSEC_PER_SEC); - end.tv_nsec += (long int) (nsec % PA_NSEC_PER_SEC); - - while ((pa_usec_t) end.tv_nsec > PA_NSEC_PER_SEC) { - end.tv_sec++; - end.tv_nsec -= (long int) PA_NSEC_PER_SEC; - } + pa_rtclock_get(&end); + pa_timeval_add(&end, usec); do { - pa_assert_se(clock_gettime(CLOCK_REALTIME, &now) == 0); - } while (now.tv_sec < end.tv_sec || - (now.tv_sec == end.tv_sec && now.tv_nsec < end.tv_nsec)); + pa_rtclock_get(&now); + } while (pa_timeval_cmp(&now, &end) < 0); } } int main(int argc, char*argv[]) { unsigned n; + pa_log_set_level(PA_LOG_INFO); + srand((unsigned) time(NULL)); if (argc >= 3) { @@ -109,11 +105,10 @@ int main(int argc, char*argv[]) { pa_assert(msec_upper > 0); pa_assert(msec_upper >= msec_lower); - pa_log_notice("Creating random latencies in the range of %ims to %ims.", msec_lower, msec_upper); + pa_log_notice("Creating random latencies in the range of %ims to %ims.", msec_lower, msec_upper); for (n = 1; n < pa_ncpus(); n++) { - pthread_t t; - pa_assert_se(pthread_create(&t, NULL, work, PA_UINT_TO_PTR(n)) == 0); + pa_assert_se(pa_thread_new("rtstutter", work, PA_UINT_TO_PTR(n))); } work(PA_INT_TO_PTR(0)); diff --git a/src/tests/stripnul.c b/src/tests/stripnul.c index 1d8c4938..d677ad20 100644 --- a/src/tests/stripnul.c +++ b/src/tests/stripnul.c @@ -31,7 +31,7 @@ int main(int argc, char *argv[]) { FILE *i, *o; size_t granularity; - pa_bool_t found; + pa_bool_t found = FALSE; uint8_t *zero; pa_assert_se(argc >= 2); diff --git a/src/tests/strlist-test.c b/src/tests/strlist-test.c index 10f370c2..86f4f075 100644 --- a/src/tests/strlist-test.c +++ b/src/tests/strlist-test.c @@ -1,7 +1,6 @@ #include <stdio.h> #include <pulse/xmalloc.h> -#include <pulse/gccmacro.h> #include <pulsecore/strlist.h> diff --git a/src/tests/sync-playback.c b/src/tests/sync-playback.c index bb64a91f..8eaa25fe 100644 --- a/src/tests/sync-playback.c +++ b/src/tests/sync-playback.c @@ -22,13 +22,11 @@ #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> diff --git a/src/tests/thread-mainloop-test.c b/src/tests/thread-mainloop-test.c index ad89414f..72275972 100644 --- a/src/tests/thread-mainloop-test.c +++ b/src/tests/thread-mainloop-test.c @@ -25,14 +25,15 @@ #include <unistd.h> #include <stdio.h> +#include <pulse/rtclock.h> #include <pulse/timeval.h> #include <pulse/util.h> #include <pulse/thread-mainloop.h> -#include <pulse/gccmacro.h> #include <pulsecore/macro.h> +#include <pulsecore/core-rtclock.h> -static void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, void *userdata) { +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); @@ -53,9 +54,7 @@ int main(int argc, char *argv[]) { pa_assert_se(!pa_threaded_mainloop_in_thread(m)); - pa_gettimeofday(&tv); - tv.tv_sec += 5; - a->time_new(a, &tv, tcb, m); + a->time_new(a, pa_timeval_rtstore(&tv, pa_rtclock_now() + 5 * PA_USEC_PER_SEC, TRUE), tcb, m); fprintf(stderr, "waiting 5s (signal)\n"); pa_threaded_mainloop_wait(m); diff --git a/src/tests/thread-test.c b/src/tests/thread-test.c index 2c07b1cc..4071e429 100644 --- a/src/tests/thread-test.c +++ b/src/tests/thread-test.c @@ -94,15 +94,13 @@ 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)); + t[i] = pa_thread_new("test", thread_func, pa_sprintf_malloc("Thread #%i", i+1)); assert(t[i]); } diff --git a/src/tests/usergroup-test.c b/src/tests/usergroup-test.c new file mode 100644 index 00000000..3948e0f8 --- /dev/null +++ b/src/tests/usergroup-test.c @@ -0,0 +1,155 @@ +/*** + This file is part of PulseAudio. + + Copyright 2009 Ted Percival + + 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. +***/ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <pwd.h> +#include <grp.h> +#include <errno.h> + +#include <pulsecore/usergroup.h> + +static int load_reference_structs(struct group **gr, struct passwd **pw) { + setpwent(); + *pw = getpwent(); + endpwent(); + + setgrent(); + *gr = getgrent(); + endgrent(); + + return (*gr && *pw) ? 0 : 1; +} + +static int compare_group(const struct group *a, const struct group *b) { + char **amem, **bmem; + + if (strcmp(a->gr_name, b->gr_name)) { + fprintf(stderr, "Group name mismatch: [%s] [%s]\n", a->gr_name, b->gr_name); + return 1; + } + + if (strcmp(a->gr_passwd, b->gr_passwd)) { + fprintf(stderr, "Group password mismatch: [%s] [%s]\n", a->gr_passwd, b->gr_passwd); + return 1; + } + + if (a->gr_gid != b->gr_gid) { + fprintf(stderr, "Gid mismatch: [%lu] [%lu]\n", (unsigned long) a->gr_gid, (unsigned long) b->gr_gid); + return 1; + } + + /* XXX: Assuming the group ordering is identical. */ + for (amem = a->gr_mem, bmem = b->gr_mem; *amem && *bmem; ++amem, ++bmem) { + if (strcmp(*amem, *bmem)) { + fprintf(stderr, "Group member mismatch: [%s] [%s]\n", *amem, *bmem); + return 1; + } + } + + if (*amem || *bmem) { + fprintf(stderr, "Mismatched group count\n"); + return 1; + } + + return 0; +} + +static int compare_passwd(const struct passwd *a, const struct passwd *b) { + if (strcmp(a->pw_name, b->pw_name)) { + fprintf(stderr, "pw_name mismatch: [%s] [%s]\n", a->pw_name, b->pw_name); + return 1; + } + + if (strcmp(a->pw_passwd, b->pw_passwd)) { + fprintf(stderr, "pw_passwd mismatch: [%s] [%s]\n", a->pw_passwd, b->pw_passwd); + return 1; + } + + if (a->pw_uid != b->pw_uid) { + fprintf(stderr, "pw_uid mismatch: [%lu] [%lu]\n", (unsigned long) a->pw_uid, (unsigned long) b->pw_uid); + return 1; + } + + if (a->pw_gid != b->pw_gid) { + fprintf(stderr, "pw_gid mismatch: [%lu] [%lu]\n", (unsigned long) a->pw_gid, (unsigned long) b->pw_gid); + return 1; + } + + if (strcmp(a->pw_gecos, b->pw_gecos)) { + fprintf(stderr, "pw_gecos mismatch: [%s] [%s]\n", a->pw_gecos, b->pw_gecos); + return 1; + } + + if (strcmp(a->pw_dir, b->pw_dir)) { + fprintf(stderr, "pw_dir mismatch: [%s] [%s]\n", a->pw_dir, b->pw_dir); + return 1; + } + + if (strcmp(a->pw_shell, b->pw_shell)) { + fprintf(stderr, "pw_shell mismatch: [%s] [%s]\n", a->pw_shell, b->pw_shell); + return 1; + } + + return 0; +} + +int main(int argc, char *argv[]) { + struct group *gr; + struct passwd *pw; + int err; + struct group *reference_group = NULL; + struct passwd *reference_passwd = NULL; + + err = load_reference_structs(&reference_group, &reference_passwd); + if (err) + return 77; + + errno = 0; + gr = pa_getgrgid_malloc(reference_group->gr_gid); + if (compare_group(reference_group, gr)) + return 1; + pa_getgrgid_free(gr); + + errno = 0; + gr = pa_getgrnam_malloc(reference_group->gr_name); + if (compare_group(reference_group, gr)) + return 1; + pa_getgrnam_free(gr); + + errno = 0; + pw = pa_getpwuid_malloc(reference_passwd->pw_uid); + if (compare_passwd(reference_passwd, pw)) + return 1; + pa_getpwuid_free(pw); + + errno = 0; + pw = pa_getpwnam_malloc(reference_passwd->pw_name); + if (compare_passwd(reference_passwd, pw)) + return 1; + pa_getpwnam_free(pw); + + return 0; +} diff --git a/src/tests/voltest.c b/src/tests/voltest.c index 2dcfa53c..ece86f85 100644 --- a/src/tests/voltest.c +++ b/src/tests/voltest.c @@ -1,13 +1,40 @@ +/*** + 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 + 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 <math.h> #include <pulse/volume.h> -#include <pulse/gccmacro.h> + +#include <pulsecore/macro.h> int main(int argc, char *argv[]) { pa_volume_t v; pa_cvolume cv; float b; pa_channel_map map; + pa_volume_t md = 0; + unsigned mdn = 0; printf("Attenuation of sample 1 against 32767: %g dB\n", 20.0*log10(1.0/32767.0)); printf("Smallest possible attenutation > 0 applied to 32767: %li\n", lrint(32767.0*pa_sw_volume_to_linear(1))); @@ -60,5 +87,48 @@ int main(int argc, char *argv[]) { printf("After: volume: [%s]; balance: %2.1f (intended: %2.1f) %s\n", pa_cvolume_snprint(s, sizeof(s), &r), k, b, k < b-.05 || k > b+.5 ? "MISMATCH" : ""); } + for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 51) { + + double l = pa_sw_volume_to_linear(v); + pa_volume_t k = pa_sw_volume_from_linear(l); + double db = pa_sw_volume_to_dB(v); + pa_volume_t r = pa_sw_volume_from_dB(db); + pa_volume_t w; + + pa_assert(k == v); + pa_assert(r == v); + + for (w = PA_VOLUME_MUTED; w < PA_VOLUME_NORM*2; w += 37) { + + double t = pa_sw_volume_to_linear(w); + double db2 = pa_sw_volume_to_dB(w); + pa_volume_t p, p1, p2; + double q, qq; + + p = pa_sw_volume_multiply(v, w); + qq = db + db2; + p2 = pa_sw_volume_from_dB(qq); + q = l*t; + p1 = pa_sw_volume_from_linear(q); + + if (p2 > p && p2 - p > md) + md = p2 - p; + if (p2 < p && p - p2 > md) + md = p - p2; + if (p1 > p && p1 - p > md) + md = p1 - p; + if (p1 < p && p - p1 > md) + md = p - p1; + + if (p1 != p || p2 != p) + mdn++; + } + } + + printf("max deviation: %lu n=%lu\n", (unsigned long) md, (unsigned long) mdn); + + pa_assert(md <= 1); + pa_assert(mdn <= 251); + return 0; } |
