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_context
{
29 enum check_wav_state state
;
30 struct btr_node
*btrn
;
32 /* Command line args. */
33 struct wav_params params
;
34 /* Extracted from the wav header.*/
36 unsigned sample_format
;
40 void check_wav_pre_select(struct sched
*s
, struct check_wav_context
*cwc
)
42 int ret
= btr_node_status(cwc
->btrn
, cwc
->min_iqs
, BTR_NT_INTERNAL
);
47 static int check_wav_exec(struct btr_node
*btrn
, const char *cmd
, char **result
)
49 struct check_wav_context
*cwc
= btr_context(btrn
);
50 int val
, header_val
, given
, arg
;
52 header_val
= cwc
->channels
;
53 arg
= cwc
->params
.channels_arg
;
54 given
= cwc
->params
.channels_given
;
55 if (!strcmp(cmd
, "channels"))
58 header_val
= cwc
->sample_rate
;
59 arg
= cwc
->params
.sample_rate_arg
;
60 given
= cwc
->params
.sample_rate_given
;
61 if (!strcmp(cmd
, "sample_rate"))
64 header_val
= cwc
->sample_format
;
65 arg
= cwc
->params
.sample_format_arg
;
66 given
= cwc
->params
.sample_format_given
;
67 if (!strcmp(cmd
, "sample_format"))
70 return -ERRNO_TO_PARA_ERROR(ENOTSUP
);
81 * No wav header available and no value specified at
82 * the command line. Maybe one of our parent nodes
85 if (btr_exec_up(btr_parent(cwc
->btrn
), cmd
, result
) >= 0)
87 /* Use default value */
94 *result
= make_message("%d", val
);
98 int check_wav_post_select(struct check_wav_context
*cwc
)
100 struct btr_node
*btrn
= cwc
->btrn
;
104 uint16_t bps
; /* bits per sample */
105 const char *sample_formats
[] = {SAMPLE_FORMATS
};
107 ret
= btr_node_status(btrn
, cwc
->min_iqs
, BTR_NT_INTERNAL
);
110 if (cwc
->state
!= CWS_NEED_HEADER
)
112 btr_merge(btrn
, cwc
->min_iqs
);
113 sz
= btr_next_buffer(btrn
, (char **)&a
);
114 if (sz
< cwc
->min_iqs
) /* file size less than WAV_HEADER_SIZE */
118 * The default byte ordering assumed for WAVE data files is
119 * little-endian. Files written using the big-endian byte ordering
120 * scheme have the identifier RIFX instead of RIFF.
122 if (a
[0] != 'R' || a
[1] != 'I' || a
[2] != 'F' ||
123 (a
[3] != 'F' && a
[3] != 'X')) {
124 PARA_NOTICE_LOG("wav header not found\n");
125 cwc
->state
= CWS_NO_HEADER
;
128 PARA_INFO_LOG("found wav header\n");
129 cwc
->state
= CWS_HAVE_HEADER
;
130 /* Only set those values which have not already been set. */
131 cwc
->channels
= (unsigned)a
[22];
132 cwc
->sample_rate
= a
[24] + (a
[25] << 8) + (a
[26] << 16) + (a
[27] << 24);
133 bps
= a
[34] + ((unsigned)a
[35] << 8);
134 if (bps
!= 8 && bps
!= 16) {
135 PARA_WARNING_LOG("%u bps not supported, assuming 16\n",
140 * 8-bit samples are stored as unsigned bytes, ranging from 0
141 * to 255. 16-bit samples are stored as 2's-complement signed
142 * integers, ranging from -32768 to 32767.
145 cwc
->sample_format
= SF_U8
;
147 cwc
->sample_format
= (a
[3] == 'F')?
148 SF_S16_LE
: SF_S16_BE
;
149 PARA_NOTICE_LOG("%dHz, %s, %s\n", cwc
->sample_rate
,
150 cwc
->channels
== 1? "mono" : "stereo",
151 sample_formats
[cwc
->sample_format
]);
152 btr_consume(btrn
, WAV_HEADER_LEN
);
157 btr_remove_node(&cwc
->btrn
);
161 struct check_wav_context
*check_wav_init(struct btr_node
*parent
,
162 struct wav_params
*params
, struct btr_node
**cw_btrn
)
164 struct check_wav_context
*cwc
= para_calloc(sizeof(*cwc
));
166 cwc
->state
= CWS_NEED_HEADER
;
167 cwc
->min_iqs
= WAV_HEADER_LEN
;
168 cwc
->params
= *params
;
169 cwc
->btrn
= btr_new_node(&(struct btr_node_description
)
170 EMBRACE(.name
= "check_wav", .parent
= parent
,
171 .handler
= check_wav_exec
, .context
= cwc
));
173 *cw_btrn
= cwc
->btrn
;
177 void check_wav_shutdown(struct check_wav_context
*cwc
)