+static void check_wav_pre_select_btr(__a_unused struct sched *s, struct task *t)
+{
+ struct check_wav_task_btr *cwt = container_of(t, struct check_wav_task_btr, task);
+
+ if (btr_get_input_queue_size(cwt->btrn) < WAV_HEADER_LEN)
+ return;
+ s->timeout.tv_sec = 0;
+ s->timeout.tv_usec = 1;
+}
+
+static int check_wav_exec(struct btr_node *btrn, const char *cmd, char **result)
+{
+ struct check_wav_task_btr *cwt = btr_context(btrn);
+
+
+ if (!strcmp(cmd, "samplerate")) {
+ if (cwt->state != CWS_HAVE_HEADER)
+ return -ERRNO_TO_PARA_ERROR(ENAVAIL);
+ *result = make_message("%d", cwt->samplerate);
+ return 1;
+ }
+ if (!strcmp(cmd, "channels")) {
+ if (cwt->state != CWS_HAVE_HEADER)
+ return -ERRNO_TO_PARA_ERROR(ENAVAIL);
+ *result = make_message("%d", cwt->channels);
+ return 1;
+ }
+ return -ERRNO_TO_PARA_ERROR(ENOTSUP);
+}
+
+static void check_wav_post_select_btr(__a_unused struct sched *s, struct task *t)
+{
+ struct check_wav_task_btr *cwt = container_of(t, struct check_wav_task_btr, task);
+ unsigned char *a;
+ size_t sz = btr_get_input_queue_size(cwt->btrn);
+
+ t->error = 0;
+ if (cwt->state != CWS_NEED_HEADER)
+ goto out;
+ if (sz < WAV_HEADER_LEN) {
+ if (!btr_no_parent(cwt->btrn))
+ return;
+ if (sz != 0) {
+ cwt->state = CWS_NO_HEADER;
+ goto out;
+ }
+ t->error = -E_WRITE_EOF;
+ goto err;
+ }
+ cwt->channels = 2;
+ cwt->samplerate = 44100;
+ btr_next_buffer(cwt->btrn, (char **)&a);
+ if (a[0] != 'R' || a[1] != 'I' || a[2] != 'F' || a[3] != 'F') {
+ PARA_NOTICE_LOG("wav header not found\n");
+ cwt->state = CWS_NO_HEADER;
+ sprintf(t->status, "check wav: no header");
+ goto consume;
+ }
+ PARA_INFO_LOG("found wav header\n");
+ cwt->state = CWS_HAVE_HEADER;
+ sprintf(t->status, "check wav: have header");
+ cwt->channels = (unsigned) a[22];
+ cwt->samplerate = a[24] + (a[25] << 8) + (a[26] << 16) + (a[27] << 24);
+consume:
+ PARA_INFO_LOG("channels: %d, sample rate: %d\n", cwt->channels, cwt->samplerate);
+ btr_consume(cwt->btrn, WAV_HEADER_LEN);
+out:
+ if (sz) {
+ btr_pushdown(cwt->btrn);
+ s->timeout.tv_sec = 0;
+ s->timeout.tv_usec = 1;
+ } else {
+ if (btr_no_parent(cwt->btrn))
+ t->error = -E_WRITE_EOF;
+ }
+err:
+ if (t->error < 0)
+ btr_del_node(cwt->btrn);
+}
+