2 * Copyright (C) 2005-2012 Andre Noll <maan@systemlinux.org>
4 * Licensed under the GPL v2. For licencing details see COPYING.
7 /** \file check_wav.c Detect and delete a wav header. */
15 #include "buffer_tree.h"
17 #include "check_wav.h"
19 /** Length of a standard wav header. */
20 #define WAV_HEADER_LEN 44
22 enum check_wav_state
{
28 struct check_wav_task
{
29 enum check_wav_state state
;
31 struct btr_node
*btrn
;
33 /* Command line args. */
34 struct wav_params params
;
35 /* Extracted from the wav header.*/
37 unsigned sample_format
;
41 static void check_wav_pre_select(struct sched
*s
, struct task
*t
)
43 struct check_wav_task
*cwt
= container_of(t
, struct check_wav_task
, task
);
46 ret
= btr_node_status(cwt
->btrn
, cwt
->min_iqs
, BTR_NT_INTERNAL
);
51 static int check_wav_exec(struct btr_node
*btrn
, const char *cmd
, char **result
)
53 struct check_wav_task
*cwt
= btr_context(btrn
);
54 int val
, header_val
, given
, arg
;
56 header_val
= cwt
->channels
;
57 arg
= cwt
->params
.channels_arg
;
58 given
= cwt
->params
.channels_given
;
59 if (!strcmp(cmd
, "channels"))
62 header_val
= cwt
->sample_rate
;
63 arg
= cwt
->params
.sample_rate_arg
;
64 given
= cwt
->params
.sample_rate_given
;
65 if (!strcmp(cmd
, "sample_rate"))
68 header_val
= cwt
->sample_format
;
69 arg
= cwt
->params
.sample_format_arg
;
70 given
= cwt
->params
.sample_format_given
;
71 if (!strcmp(cmd
, "sample_format"))
74 return -ERRNO_TO_PARA_ERROR(ENOTSUP
);
84 /* Use default value */
91 *result
= make_message("%d", val
);
95 static void check_wav_post_select(__a_unused
struct sched
*s
, struct task
*t
)
97 struct check_wav_task
*cwt
= container_of(t
, struct check_wav_task
, task
);
98 struct btr_node
*btrn
= cwt
->btrn
;
102 uint16_t bps
; /* bits per sample */
103 const char *sample_formats
[] = {SAMPLE_FORMATS
};
106 ret
= btr_node_status(btrn
, cwt
->min_iqs
, BTR_NT_INTERNAL
);
109 if (cwt
->state
!= CWS_NEED_HEADER
)
111 btr_merge(btrn
, cwt
->min_iqs
);
112 sz
= btr_next_buffer(btrn
, (char **)&a
);
113 if (sz
< cwt
->min_iqs
) /* file size less than WAV_HEADER_SIZE */
117 * The default byte ordering assumed for WAVE data files is
118 * little-endian. Files written using the big-endian byte ordering
119 * scheme have the identifier RIFX instead of RIFF.
121 if (a
[0] != 'R' || a
[1] != 'I' || a
[2] != 'F' ||
122 (a
[3] != 'F' && a
[3] != 'X')) {
123 PARA_NOTICE_LOG("wav header not found\n");
124 cwt
->state
= CWS_NO_HEADER
;
125 sprintf(t
->status
, "check wav: no header");
128 PARA_INFO_LOG("found wav header\n");
129 cwt
->state
= CWS_HAVE_HEADER
;
130 sprintf(t
->status
, "check wav: have header");
131 /* Only set those values which have not already been set. */
132 cwt
->channels
= (unsigned)a
[22];
133 cwt
->sample_rate
= a
[24] + (a
[25] << 8) + (a
[26] << 16) + (a
[27] << 24);
134 bps
= a
[34] + ((unsigned)a
[35] << 8);
135 if (bps
!= 8 && bps
!= 16) {
136 PARA_WARNING_LOG("%u bps not supported, assuming 16\n",
141 * 8-bit samples are stored as unsigned bytes, ranging from 0
142 * to 255. 16-bit samples are stored as 2's-complement signed
143 * integers, ranging from -32768 to 32767.
146 cwt
->sample_format
= SF_U8
;
148 cwt
->sample_format
= (a
[3] == 'F')?
149 SF_S16_LE
: SF_S16_BE
;
150 PARA_NOTICE_LOG("%dHz, %s, %s\n", cwt
->sample_rate
,
151 cwt
->channels
== 1? "mono" : "stereo",
152 sample_formats
[cwt
->sample_format
]);
153 btr_consume(btrn
, WAV_HEADER_LEN
);
159 btr_remove_node(&cwt
->btrn
);
162 struct check_wav_task
*check_wav_init(struct sched
*s
, struct btr_node
*parent
,
163 struct wav_params
*params
, struct btr_node
**cwt_btrn
)
165 struct check_wav_task
*cwt
= para_calloc(sizeof(*cwt
));
167 cwt
->state
= CWS_NEED_HEADER
;
168 cwt
->min_iqs
= WAV_HEADER_LEN
;
169 cwt
->params
= *params
;
170 cwt
->btrn
= btr_new_node(&(struct btr_node_description
)
171 EMBRACE(.name
= "check_wav", .parent
= parent
,
172 .handler
= check_wav_exec
, .context
= cwt
));
173 sprintf(cwt
->task
.status
, "check_wav");
174 cwt
->task
.pre_select
= check_wav_pre_select
;
175 cwt
->task
.post_select
= check_wav_post_select
;
177 *cwt_btrn
= cwt
->btrn
;
178 register_task(s
, &cwt
->task
);
182 void check_wav_shutdown(struct check_wav_task
*cwt
)