commit - b232461a63350252e93337c1c0c30e53f2a8cb0a
commit + 3f64dc1f60040ec3263499bb414cb69aefe967d9
blob - 0d4c17d99a4faa43760f441d3787183fa9d67c9e
blob + 712a5322e29e362f25debe505976c5e3f1b5c376
--- cw.c
+++ cw.c
#include <limits.h> /* CHAR_BIT */
#include <math.h>
#include <sndio.h>
+#include <sys/time.h> /* getclocktime, timespecsub */
#include <assert.h>
#include <err.h>
#include "cw.h"
static size_t framesz, bufsz;
static sample_t *buf;
static int writ, pos; /* total frames and current play pos. */
+static struct timespec tplay; /* time when playback started */
/* envelope parameters */
static int rise = 4; /* ramp up (attack) time [ms] */
#ifdef DEBUGTIME
#include <stdio.h>
-#include <sys/time.h>
static struct timespec t0;
#endif
/* play a beep of the desired frequency and length */
-int
+void
beep(int f, int len)
{
int n; /* samples left to play */
timestamp("beep(): done writing\n");
inbeep = 1;
- return (writ - pos) * 1000 / par.rate; /* remaining play time [ms] */
}
/* play a pause of the desired length */
-int
+void
silence(int len)
{
int n, total;
timestamp("silence(): done writing\n");
inbeep = 0;
- return (writ - pos) * 1000 / par.rate; /* remaining play time [ms] */
}
static void
cb_onmove(void *arg, int delta)
{
+ if (delta == 0) /* start of playback */
+ clock_gettime(CLOCK_MONOTONIC, &tplay);
pos += delta;
#ifdef DEBUGTIME
timestamp("onmove: ");
#endif
}
-void
+int
cwstop(void)
{
#ifdef DEBUGTIME
timestamp("sio_stop() ");
fprintf(stderr, "took %f ms\n", ms);
#endif
+
+ /*
+ * Calculate and report our "return latency", i.e. the time it took
+ * between playback finishing and the return of the function. This
+ * value can be negative, meaning that we actually returned earlier
+ * than playback will finish.
+ */
+ struct timespec tnow, dt;
+ int playms, nowms;
+
+ clock_gettime(CLOCK_MONOTONIC, &tnow);
+ timespecsub(&tnow, &tplay, &dt);
+ nowms = dt.tv_sec * 1000 + dt.tv_nsec / 1000000;
+ playms = writ * 1000 / par.rate;
+
+#ifdef DEBUGTIME
+ timestamp("playback started ");
+ fprintf(stderr, "%d ms ago, playback time %d ms\n", nowms, playms);
+ timestamp("cwstop: ");
+ fprintf(stderr, "return latency %d ms\n", nowms - playms);
+#endif
+ return nowms - playms;
}
blob - 613e77647e70605af48b71e73f79cb6e6cb6fcf1
blob + 6b69c80fa1f7e5c03a73d03c71af983e28dcda85
--- cw.h
+++ cw.h
void cwinit(void);
void cwstart(void);
-void cwstop(void);
-int beep(int, int);
-int silence(int);
+void beep(int, int);
+void silence(int);
+int cwstop(void); /* returns time since playback finished [ms] */
/* getenv helpers */
int getenvnum(const char *, const char *, int *);
blob - 748852b89b60b9fe5bfaf97e7e733f96d617b36e
blob + 2bc6ceac549a2af6034f2c940cf25a20c328e11c
--- morse.c
+++ morse.c
int
play(char *s)
{
- int pause, rem = 0;
+ int pause;
if (*s == '\0')
pause = 7 * pditlen - ditlen; /* inter-word pause */
pause = 3 * pditlen - ditlen; /* intra-word pause */
cwstart();
- rem = silence(pause);
+ silence(pause);
while (*s) {
if (*s == '.')
beep(freq, ditlen);
else if (*s == '-')
beep(freq, 3 * ditlen);
s++;
- rem = silence(ditlen);
+ silence(ditlen);
}
- cwstop();
-
- return rem; /* remaining play time [ms] */
+ return cwstop(); /* return latency [ms] */
}
/* the audio hook for teacher mode */
blob - c135883985cb742fd1e51598dafc674b826609ab
blob + c8aa0f8c51695f3a093a54f420cf896c927387d7
--- teach.c
+++ teach.c
if (failprob[i] > 0.9)
sound(' '); /* inter-word pause */
latency = sound(ch);
- //assert(latency == 0); // XXX
clock_gettime(CLOCK_MONOTONIC, &t0);
if (failprob[i] > 0.9)
printf("%c\b", ch);
clock_gettime(CLOCK_MONOTONIC, &t1);
timespecsub(&t1, &t0, &delta);
taken = delta.tv_sec + delta.tv_nsec / 1000000000.0; /* s */
- //taken += latency / 1000.0;
+ taken += latency / 1000.0;
sigma = sqrt(vartime);
/* if return pressed, pause and show scores */