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.
+struct check_wav_context {
enum check_wav_state state;
enum check_wav_state state;
struct btr_node *btrn;
size_t min_iqs;
/* Command line args. */
struct btr_node *btrn;
size_t min_iqs;
/* Command line args. */
-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)
{
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;
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;
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;
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;
if (!strcmp(cmd, "sample_format"))
goto out;
if (given)
val = arg;
else {
if (given)
val = arg;
else {
case CWS_HAVE_HEADER:
val = header_val;
break;
case CWS_HAVE_HEADER:
val = header_val;
break;
-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};
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 (cwt->state != CWS_NEED_HEADER)
+ if (cwc->state != CWS_NEED_HEADER)
- btr_merge(btrn, cwt->min_iqs);
+ btr_merge(btrn, cwc->min_iqs);
sz = btr_next_buffer(btrn, (char **)&a);
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 */
/*
* The default byte ordering assumed for WAVE data files is
* little-endian. Files written using the big-endian byte ordering
/*
* The default byte ordering assumed for WAVE data files is
* little-endian. Files written using the big-endian byte ordering
if (a[0] != 'R' || a[1] != 'I' || a[2] != 'F' ||
(a[3] != 'F' && a[3] != 'X')) {
PARA_NOTICE_LOG("wav header not found\n");
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");
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. */
/* 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",
bps = a[34] + ((unsigned)a[35] << 8);
if (bps != 8 && bps != 16) {
PARA_WARNING_LOG("%u bps not supported, assuming 16\n",
* integers, ranging from -32768 to 32767.
*/
if (bps == 8)
* integers, ranging from -32768 to 32767.
*/
if (bps == 8)
- cwt->sample_format = SF_U8;
+ cwc->sample_format = SF_U8;
- cwt->sample_format = (a[3] == 'F')?
+ cwc->sample_format = (a[3] == 'F')?
- 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:
btr_consume(btrn, WAV_HEADER_LEN);
pushdown:
btr_pushdown(btrn);
out:
- 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,
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)
+struct check_wav_context;
/**
* These come from the command line arguments.
/**
* These come from the command line arguments.
(dst)->sample_format_arg = (src)->sample_format_arg; \
(dst)->sample_format_given = (src)->sample_format_given;
(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);
register_writer_node(wn, parent, s);
}
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;
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 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)
loglevel = get_loglevel_by_name(conf.loglevel_arg);
sit.btrn = btr_new_node(&(struct btr_node_description)
register_task(&s, &sit.task);
COPY_WAV_PARMS(&wp, &conf);
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));
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++)
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,
free(wn->conf);
}
free(wns);
free(wn->conf);
}
free(wns);
- check_wav_shutdown(cwt);
+ check_wav_shutdown(wt.cwc);