diff options
| -rw-r--r-- | src/Makefile.am | 6 | ||||
| -rw-r--r-- | src/tests/interpol-test.c | 168 | 
2 files changed, 174 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2dc2c663..6a2decb3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -189,6 +189,7 @@ noinst_PROGRAMS = \  		voltest \  		memblockq-test \  		sync-playback \ +		interpol-test \  		channelmap-test \  		thread-mainloop-test \  		utf8-test @@ -284,6 +285,11 @@ sync_playback_LDADD = $(AM_LDADD) libpolyp.la  sync_playback_CFLAGS = $(AM_CFLAGS)   sync_playback_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) +interpol_test_SOURCES = tests/interpol-test.c +interpol_test_LDADD = $(AM_LDADD) libpolyp.la +interpol_test_CFLAGS = $(AM_CFLAGS)  +interpol_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) +  ###################################  #         Client library          #  ################################### diff --git a/src/tests/interpol-test.c b/src/tests/interpol-test.c new file mode 100644 index 00000000..26a92dbf --- /dev/null +++ b/src/tests/interpol-test.c @@ -0,0 +1,168 @@ +/* $Id$ */ + +/*** +  This file is part of polypaudio. +  +  polypaudio 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. +  +  polypaudio 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 polypaudio; 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 <pthread.h> + +#include <polyp/polypaudio.h> +#include <polyp/mainloop.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, rtc, t, rtc-old_rtc, t-old_t, changed*2000000); +            old_t = t; +            old_rtc = rtc; +        } + +        /* Spin loop, eerks but normal usleep is just to badly grained */ + +        tv = now; +        while (pa_timeval_diff(pa_gettimeofday(&now), &tv) < 1000) +            pthread_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; +}  | 
