@@ -37,7 +37,9 @@ aplay_SOURCES = \
xfer-alsa.h \
xfer-alsa.c \
xfer-alsa-io-mmap.c \
- xfer-alsa-io-rw.c
+ xfer-alsa-io-rw.c \
+ xfer-alsa-sched-irq.c \
+ xfer-alsa-sched-timer.c
EXTRA_DIST = aplay.1 arecord.1
EXTRA_CLEAN = arecord
new file mode 100644
@@ -0,0 +1,18 @@
+/*
+ * xfer-alsa-sched-irq.c - interrupt-based scheduling model of ALSA.
+ *
+ * Copyright (c) 2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
+ *
+ * Licensed under the terms of the GNU General Public License, version 2.
+ */
+
+#include "xfer-alsa.h"
+
+static int alsa_irq_pre_process(struct xfer_context *xfer)
+{
+ return 0;
+}
+
+const struct xfer_alsa_sched_ops xfer_alsa_sched_irq_ops = {
+ .pre_process = alsa_irq_pre_process,
+};
new file mode 100644
@@ -0,0 +1,49 @@
+/*
+ * xfer-alsa-sched-timer.c - timer-based scheduling model of ALSA.
+ *
+ * Copyright (c) 2017 Takashi Sakamoto <o-takashi@sakamocchi.jp>
+ *
+ * Licensed under the terms of the GNU General Public License, version 2.
+ */
+
+#include "xfer-alsa.h"
+
+static int alsa_timer_pre_process(struct xfer_context *xfer)
+{
+ struct alsa_state *state = xfer->private_data;
+ snd_pcm_uframes_t boundary;
+ snd_pcm_uframes_t avail_min;
+ int err;
+
+ err = snd_pcm_sw_params_get_boundary(state->sw_params, &boundary);
+ if (err < 0)
+ return err;
+
+ err = snd_pcm_sw_params_set_stop_threshold(state->handle,
+ state->sw_params, boundary);
+ if (err < 0)
+ return err;
+
+ err = snd_pcm_sw_params_set_start_threshold(state->handle,
+ state->sw_params, -1);
+ if (err < 0)
+ return err;
+
+ /* TODO: calculate proper value fo ravail_min. */
+ err = snd_pcm_hw_params_get_period_size(state->hw_params, &avail_min,
+ NULL);
+ if (err < 0)
+ return err;
+
+ err = snd_pcm_sw_params_set_avail_min(state->handle, state->sw_params,
+ avail_min);
+ if (err < 0)
+ return err;
+
+ return snd_pcm_sw_params_set_period_event(state->handle,
+ state->sw_params, 1);
+}
+
+const struct xfer_alsa_sched_ops xfer_alsa_sched_timer_ops = {
+ .pre_process = alsa_timer_pre_process,
+};
@@ -415,6 +415,7 @@ static int xfer_alsa_pre_process(struct xfer_context *xfer,
return err;
/* Assign scheduling operation. */
+ state->sched_ops = &xfer_alsa_sched_irq_ops;
err = state->sched_ops->pre_process(xfer);
if (err < 0)
return err;
@@ -58,4 +58,7 @@ extern const struct xfer_alsa_io_ops xfer_alsa_mmap_ops;
extern const struct xfer_alsa_io_ops xfer_alsa_r_ops;
extern const struct xfer_alsa_io_ops xfer_alsa_w_ops;
+extern const struct xfer_alsa_sched_ops xfer_alsa_sched_irq_ops;
+extern const struct xfer_alsa_sched_ops xfer_alsa_sched_timer_ops;
+
#endif