Replace check_wav_task by write_task.
authorAndre Noll <maan@systemlinux.org>
Sun, 28 Oct 2012 14:03:55 +0000 (15:03 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 25 Nov 2012 13:08:55 +0000 (14:08 +0100)
Besides the task(s) associated with the given writer(s), para_write
currently sets up two other tasks: The stdin task and the check_wav
task.

The resample filter, which is to be introduced in subsequent patches,
also needs the functionality that is provided by the check wav task.
However, as filters are not supposed to create their own tasks, there
should not be a dedicated task instance for checking the wav header.

To overcome this problem we move the task member from
check_wav.c to write.c and rename the check_wav_task struct to
check_wav_context. Hence the ->pre_select and ->post_select methods
become part of para_write that call into check_wav.c to do the work.

The patch is quite large but large parts of the changes are just
trivial cwt -> cwc conversions.

check_wav.c
check_wav.h
write.c

index 0ed79e43534792c3b82049606f2c1e31ee09f8cd..12f44b5be4efb032ba6db054764d108b987cb58c 100644 (file)
@@ -25,9 +25,8 @@ enum check_wav_state {
        CWS_NO_HEADER,
 };
 
-struct check_wav_task {
+struct check_wav_context {
        enum check_wav_state state;
-       struct task task;
        struct btr_node *btrn;
        size_t min_iqs;
        /* Command line args. */
@@ -38,36 +37,33 @@ struct check_wav_task {
        unsigned sample_rate;
 };
 
-static void check_wav_pre_select(struct sched *s, struct task *t)
+void check_wav_pre_select(struct sched *s, struct check_wav_context *cwc)
 {
-       struct check_wav_task *cwt = container_of(t, struct check_wav_task, task);
-       int ret;
-
-       ret = btr_node_status(cwt->btrn, cwt->min_iqs, BTR_NT_INTERNAL);
+       int ret = btr_node_status(cwc->btrn, cwc->min_iqs, BTR_NT_INTERNAL);
        if (ret != 0)
                sched_min_delay(s);
 }
 
 static int check_wav_exec(struct btr_node *btrn, const char *cmd, char **result)
 {
-       struct check_wav_task *cwt = btr_context(btrn);
+       struct check_wav_context *cwc = btr_context(btrn);
        int val, header_val, given, arg;
 
-       header_val = cwt->channels;
-       arg = cwt->params.channels_arg;
-       given = cwt->params.channels_given;
+       header_val = cwc->channels;
+       arg = cwc->params.channels_arg;
+       given = cwc->params.channels_given;
        if (!strcmp(cmd, "channels"))
                goto out;
 
-       header_val = cwt->sample_rate;
-       arg = cwt->params.sample_rate_arg;
-       given = cwt->params.sample_rate_given;
+       header_val = cwc->sample_rate;
+       arg = cwc->params.sample_rate_arg;
+       given = cwc->params.sample_rate_given;
        if (!strcmp(cmd, "sample_rate"))
                goto out;
 
-       header_val = cwt->sample_format;
-       arg = cwt->params.sample_format_arg;
-       given = cwt->params.sample_format_given;
+       header_val = cwc->sample_format;
+       arg = cwc->params.sample_format_arg;
+       given = cwc->params.sample_format_given;
        if (!strcmp(cmd, "sample_format"))
                goto out;
 
@@ -76,7 +72,7 @@ out:
        if (given)
                val = arg;
        else {
-               switch (cwt->state) {
+               switch (cwc->state) {
                case CWS_HAVE_HEADER:
                        val = header_val;
                        break;
@@ -92,27 +88,25 @@ out:
        return 1;
 }
 
-static void check_wav_post_select(__a_unused struct sched *s, struct task *t)
+int check_wav_post_select(struct check_wav_context *cwc)
 {
-       struct check_wav_task *cwt = container_of(t, struct check_wav_task, task);
-       struct btr_node *btrn = cwt->btrn;
+       struct btr_node *btrn = cwc->btrn;
        unsigned char *a;
        size_t sz;
        int ret;
        uint16_t bps; /* bits per sample */
        const char *sample_formats[] = {SAMPLE_FORMATS};
 
-       t->error = 0;
-       ret = btr_node_status(btrn, cwt->min_iqs, BTR_NT_INTERNAL);
+       ret = btr_node_status(btrn, cwc->min_iqs, BTR_NT_INTERNAL);
        if (ret <= 0)
                goto out;
-       if (cwt->state != CWS_NEED_HEADER)
+       if (cwc->state != CWS_NEED_HEADER)
                goto pushdown;
-       btr_merge(btrn, cwt->min_iqs);
+       btr_merge(btrn, cwc->min_iqs);
        sz = btr_next_buffer(btrn, (char **)&a);
-       if (sz < cwt->min_iqs) /* file size less than WAV_HEADER_SIZE */
+       if (sz < cwc->min_iqs) /* file size less than WAV_HEADER_SIZE */
                goto pushdown;
-       cwt->min_iqs = 0;
+       cwc->min_iqs = 0;
        /*
         * The default byte ordering assumed for WAVE data files is
         * little-endian. Files written using the big-endian byte ordering
@@ -121,16 +115,14 @@ static void check_wav_post_select(__a_unused struct sched *s, struct task *t)
        if (a[0] != 'R' || a[1] != 'I' || a[2] != 'F' ||
                        (a[3] != 'F' && a[3] != 'X')) {
                PARA_NOTICE_LOG("wav header not found\n");
-               cwt->state = CWS_NO_HEADER;
-               sprintf(t->status, "check wav: no header");
+               cwc->state = CWS_NO_HEADER;
                goto out;
        }
        PARA_INFO_LOG("found wav header\n");
-       cwt->state = CWS_HAVE_HEADER;
-       sprintf(t->status, "check wav: have header");
+       cwc->state = CWS_HAVE_HEADER;
        /* Only set those values which have not already been set. */
-       cwt->channels = (unsigned)a[22];
-       cwt->sample_rate = a[24] + (a[25] << 8) + (a[26] << 16) + (a[27] << 24);
+       cwc->channels = (unsigned)a[22];
+       cwc->sample_rate = a[24] + (a[25] << 8) + (a[26] << 16) + (a[27] << 24);
        bps = a[34] + ((unsigned)a[35] << 8);
        if (bps != 8 && bps != 16) {
                PARA_WARNING_LOG("%u bps not supported, assuming 16\n",
@@ -143,43 +135,39 @@ static void check_wav_post_select(__a_unused struct sched *s, struct task *t)
         * integers, ranging from -32768 to 32767.
         */
        if (bps == 8)
-               cwt->sample_format = SF_U8;
+               cwc->sample_format = SF_U8;
        else
-               cwt->sample_format = (a[3] == 'F')?
+               cwc->sample_format = (a[3] == 'F')?
                        SF_S16_LE : SF_S16_BE;
-       PARA_NOTICE_LOG("%dHz, %s, %s\n", cwt->sample_rate,
-               cwt->channels == 1? "mono" : "stereo",
-               sample_formats[cwt->sample_format]);
+       PARA_NOTICE_LOG("%dHz, %s, %s\n", cwc->sample_rate,
+               cwc->channels == 1? "mono" : "stereo",
+               sample_formats[cwc->sample_format]);
        btr_consume(btrn, WAV_HEADER_LEN);
 pushdown:
        btr_pushdown(btrn);
 out:
-       t->error = ret;
        if (ret < 0)
-               btr_remove_node(&cwt->btrn);
+               btr_remove_node(&cwc->btrn);
+       return ret;
 }
 
-struct check_wav_task *check_wav_init(struct sched *s, struct btr_node *parent,
-               struct wav_params *params, struct btr_node **cwt_btrn)
+struct check_wav_context *check_wav_init(struct btr_node *parent,
+               struct wav_params *params, struct btr_node **cw_btrn)
 {
-       struct check_wav_task *cwt = para_calloc(sizeof(*cwt));
+       struct check_wav_context *cwc = para_calloc(sizeof(*cwc));
 
-       cwt->state = CWS_NEED_HEADER;
-       cwt->min_iqs = WAV_HEADER_LEN;
-       cwt->params = *params;
-       cwt->btrn = btr_new_node(&(struct btr_node_description)
+       cwc->state = CWS_NEED_HEADER;
+       cwc->min_iqs = WAV_HEADER_LEN;
+       cwc->params = *params;
+       cwc->btrn = btr_new_node(&(struct btr_node_description)
                EMBRACE(.name = "check_wav", .parent = parent,
-               .handler = check_wav_exec, .context = cwt));
-       sprintf(cwt->task.status, "check_wav");
-       cwt->task.pre_select = check_wav_pre_select;
-       cwt->task.post_select = check_wav_post_select;
-       if (cwt_btrn)
-               *cwt_btrn = cwt->btrn;
-       register_task(s, &cwt->task);
-       return cwt;
+               .handler = check_wav_exec, .context = cwc));
+       if (cw_btrn)
+               *cw_btrn = cwc->btrn;
+       return cwc;
 }
 
-void check_wav_shutdown(struct check_wav_task *cwt)
+void check_wav_shutdown(struct check_wav_context *cwc)
 {
-       free(cwt);
+       free(cwc);
 }
index 102e9514b960411dd667c349da2e4b0c0b30fca2..cdd483200782499d0fb360bc36779fe2dbced41d 100644 (file)
@@ -1,4 +1,4 @@
-struct check_wav_task;
+struct check_wav_context;
 
 /**
  * These come from the command line arguments.
@@ -38,6 +38,8 @@ struct wav_params {
        (dst)->sample_format_arg = (src)->sample_format_arg; \
        (dst)->sample_format_given = (src)->sample_format_given;
 
-struct check_wav_task *check_wav_init(struct sched *s, struct btr_node *parent,
-               struct wav_params *params, struct btr_node **cwt_btrn);
-void check_wav_shutdown(struct check_wav_task *cwt);
+struct check_wav_context *check_wav_init(struct btr_node *parent,
+               struct wav_params *params, struct btr_node **cw_btrn);
+void check_wav_pre_select(struct sched *s, struct check_wav_context *cwc);
+int check_wav_post_select(struct check_wav_context *cwc);
+void check_wav_shutdown(struct check_wav_context *cwc);
diff --git a/write.c b/write.c
index 453824ace679f97feaa24c0d74b61ebdd83b049f..8c57b3bde28fc45d2337f316a0c7cf8d41f4d112 100644 (file)
--- a/write.c
+++ b/write.c
@@ -75,14 +75,37 @@ static void setup_writer_node(const char *arg, struct btr_node *parent,
        register_writer_node(wn, parent, s);
 }
 
+struct write_task {
+       struct task task;
+       struct check_wav_context *cwc;
+};
+
+static void write_pre_select(struct sched *s, struct task *t)
+{
+       struct write_task *wt = container_of(t, struct write_task, task);
+       check_wav_pre_select(s, wt->cwc);
+}
+
+static void write_post_select(__a_unused struct sched *s, struct task *t)
+{
+       struct write_task *wt = container_of(t, struct write_task, task);
+       t->error = check_wav_post_select(wt->cwc);
+}
+
 static int setup_and_schedule(void)
 {
        int i, ret;
-       struct check_wav_task *cwt;
-       struct btr_node *cwt_btrn;
+       struct btr_node *cw_btrn;
        struct writer_node *wns;
        static struct sched s;
        struct wav_params wp;
+       struct write_task wt = {
+               .task = {
+                       .pre_select = write_pre_select,
+                       .post_select = write_post_select,
+                       .status = "write task",
+               },
+       };
 
        loglevel = get_loglevel_by_name(conf.loglevel_arg);
        sit.btrn = btr_new_node(&(struct btr_node_description)
@@ -91,15 +114,16 @@ static int setup_and_schedule(void)
        register_task(&s, &sit.task);
 
        COPY_WAV_PARMS(&wp, &conf);
-       cwt = check_wav_init(&s, sit.btrn, &wp, &cwt_btrn);
+       wt.cwc = check_wav_init(sit.btrn, &wp, &cw_btrn);
+       register_task(&s, &wt.task);
        if (!conf.writer_given) {
                wns = para_calloc(sizeof(*wns));
-               setup_writer_node(NULL, cwt_btrn, wns, &s);
+               setup_writer_node(NULL, cw_btrn, wns, &s);
                i = 1;
        } else {
                wns = para_calloc(conf.writer_given * sizeof(*wns));
                for (i = 0; i < conf.writer_given; i++)
-                       setup_writer_node(conf.writer_arg[i], cwt_btrn,
+                       setup_writer_node(conf.writer_arg[i], cw_btrn,
                                wns + i, &s);
        }
 
@@ -130,7 +154,7 @@ static int setup_and_schedule(void)
                free(wn->conf);
        }
        free(wns);
-       check_wav_shutdown(cwt);
+       check_wav_shutdown(wt.cwc);
        return ret;
 }