[pulseaudio-discuss] [RFC] [PATCH] tests: Add a latency measurement test
Peter Meerwald
pmeerw at pmeerw.net
Tue May 21 08:13:55 PDT 2013
Hello,
> This test is intended to measure real latency by playing a sample to a
> sink and capturing that over a loopback interface. The loopback can
> either be physical (cable running from headphone out to line in) or
> virtual (monitor source or module loopback).
nice idea :)
the sine tone in the beginning has chirps, intended?
the program's output could be clearer; it is not obvious what is going on
('giving up' but the program does not stop?):
Capture signal too weak at 100% volume (0.766978). Giving up.
Capture signal too weak at 100% volume (0.748493). Giving up.
Capture signal too weak at 100% volume (0.797834). Giving up.
Underflow
Capture signal too weak at 100% volume (0.418111). Giving up.
Too much noise on capture (0.606354). Giving up.
Latency 10565
Latency 10678
Latency 10709
+#define TONE_HZ SAMPLE_HZ / 100
maybe #define TONE_HZ (SAMPLE_HZ / 100)
+#define PLAYBACK_LATENCY 25 /* ms */
+#define CAPTURE_LATENCY 5 /* ms */
> +static const char *bname = NULL;
bname is not very clear; what is it for?
> +static float out[N_OUT][CHANNELS];
> +static int ppos = 0;
> +
> +static int n_underflow = 0;
> +static int n_overflow = 0;
unsigned maybe?
> +static inline float rms(const float *s, int n) {
> + float sq = 0;
> + int i;
float sq = 0.0f;
unsigned i, unsigned n?
> +
> + for (i = 0; i < n; i++)
> + sq += s[i] * s[i];
> +
> + return sqrt(sq / n);
should be sqrtf() since sq is float
> +#define WINDOW 2 * CHANNELS
#define WINDOW (2 * CHANNELS)
> +static void read_cb(pa_stream *s, size_t nbytes, void *userdata) {
> + static float last = 0.0;
static float last = 0.0f;
> + const float *in;
> + float cur;
> + int r;
> + unsigned int i = 0;
here we have an unsigned?
> + /* We leave the definition of 0 generous since the window might
> + * straddle the 0->1 transition, raising the average power. We keep the
> + * definition of 1 tight in this case and detect the transition in the
> + * next round. */
> + if (last < 0.5 && cur > 0.8) {
I'd append an f to denote float precision, so 0.5f and 0.8f
> + pa_gettimeofday(&tv_in);
> + fprintf(stderr, "Latency %llu\n", (unsigned long long) pa_timeval_diff(&tv_in, &tv_out));
is the cast necessary?
> +enum {
> + CALIBRATION_ONE,
> + CALIBRATION_ZERO,
> + CALIBRATION_DONE,
> +};
> +
> +static int cal_state = CALIBRATION_ONE;
> +
> +static void calibrate_write_cb(pa_stream *s, size_t nbytes, void *userdata) {
> + int i, r, nsamp = nbytes / fs;
> + float tmp[nsamp][2];
> + static int count = 0;
> +
> + /* Write out a sine tone */
> + for (i = 0; i < nsamp; i++)
> + tmp[i][0] = tmp[i][1] = cal_state == CALIBRATION_ONE ? sin(count++ * TONE_HZ * 2 * M_PI / SAMPLE_HZ) : 0.0;
sinf() since float, 0.0f
> +START_TEST (loopback_test) {
> + pa_mainloop* m = NULL;
> + int i, ret = 0, pulse_hz = N_OUT / 1000;
division rounds towards zero, intended?
> +
> + /* Generate a square pulse */
> + for (i = 0; i < N_OUT; i++)
> + if (i < pulse_hz)
> + out[i][0] = out[i][1] = 1.0;
> + else
> + out[i][0] = out[i][1] = 0.0;
--
Peter Meerwald
+43-664-2444418 (mobile)
More information about the pulseaudio-discuss
mailing list