From 216399fa29e2c071cd4485c57b6b1c9f4a74057b Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 28 Oct 2012 15:03:55 +0100 Subject: [PATCH] Replace check_wav_task by write_task. 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 | 102 +++++++++++++++++++++++----------------------------- check_wav.h | 10 +++--- write.c | 36 +++++++++++++++---- 3 files changed, 81 insertions(+), 67 deletions(-) diff --git a/check_wav.c b/check_wav.c index 0ed79e43..12f44b5b 100644 --- a/check_wav.c +++ b/check_wav.c @@ -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); } diff --git a/check_wav.h b/check_wav.h index 102e9514..cdd48320 100644 --- a/check_wav.h +++ b/check_wav.h @@ -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 453824ac..8c57b3bd 100644 --- 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; } -- 2.39.5