static const char *const cntr_format_labels[] = {
[CONTAINER_FORMAT_RIFF_WAVE] = "riff/wave",
+ [CONTAINER_FORMAT_AU] = "au",
+ [CONTAINER_FORMAT_VOC] = "voc",
+ [CONTAINER_FORMAT_RAW] = "raw",
};
static const char *const suffixes[] = {
- [CONTAINER_FORMAT_RIFF_WAVE] = ".wav",
+ [CONTAINER_FORMAT_RIFF_WAVE] = ".wav",
+ [CONTAINER_FORMAT_AU] = ".au",
+ [CONTAINER_FORMAT_VOC] = ".voc",
+ [CONTAINER_FORMAT_RAW] = "",
};
-
const char *const container_suffix_from_format(enum container_format format)
{
return suffixes[format];
}
// Unsupported.
- return CONTAINER_FORMAT_COUNT;
+ return CONTAINER_FORMAT_RAW;
}
int container_seek_offset(struct container_context *cntr, off64_t offset)
{
const struct container_parser *parsers[] = {
[CONTAINER_FORMAT_RIFF_WAVE] = &container_parser_riff_wave,
+ [CONTAINER_FORMAT_AU] = &container_parser_au,
+ [CONTAINER_FORMAT_VOC] = &container_parser_voc,
};
const struct container_parser *parser;
unsigned int size;
// Open a target descriptor.
if (!strcmp(path, "-")) {
cntr->fd = fileno(stdin);
+ if (isatty(cntr->fd)) {
+ fprintf(stderr,
+ "A terminal is referred for standard input. "
+ "Output from any process or shell redirection "
+ "should be referred instead.\n");
+ return -EIO;
+ }
err = set_nonblock_flag(cntr->fd);
if (err < 0)
return err;
// Unless detected, use raw container.
if (i == ARRAY_SIZE(parsers))
- return -EINVAL;
+ parser = &container_parser_raw;
// Allocate private data for the parser.
if (parser->private_size > 0) {
{
const struct container_builder *builders[] = {
[CONTAINER_FORMAT_RIFF_WAVE] = &container_builder_riff_wave,
+ [CONTAINER_FORMAT_AU] = &container_builder_au,
+ [CONTAINER_FORMAT_VOC] = &container_builder_voc,
+ [CONTAINER_FORMAT_RAW] = &container_builder_raw,
};
const struct container_builder *builder;
int err;
return -EINVAL;
if (!strcmp(path, "-")) {
cntr->fd = fileno(stdout);
+ if (isatty(cntr->fd)) {
+ fprintf(stderr,
+ "A terminal is referred for standard output. "
+ "Input to any process or shell redirection "
+ "should be referred instead.\n");
+ return -EIO;
+ }
err = set_nonblock_flag(cntr->fd);
if (err < 0)
return err;
return 0;
}
+ if (cntr->format == CONTAINER_FORMAT_RAW) {
+ if (*format == SND_PCM_FORMAT_UNKNOWN ||
+ *samples_per_frame == 0 || *frames_per_second == 0) {
+ fprintf(stderr,
+ "Any file format is not detected. Need to "
+ "indicate all of sample format, channels and "
+ "rate explicitly.\n");
+ return -EINVAL;
+ }
+ }
assert(*format >= SND_PCM_FORMAT_S8);
assert(*format <= SND_PCM_FORMAT_LAST);
assert(*samples_per_frame > 0);
char *buf = frame_buffer;
unsigned int bytes_per_frame;
unsigned int byte_count;
+ unsigned int target_byte_count;
int err;
assert(cntr);
assert(frame_count);
bytes_per_frame = cntr->bytes_per_sample * cntr->samples_per_frame;
- byte_count = *frame_count * bytes_per_frame;
+ target_byte_count = *frame_count * bytes_per_frame;
+
+ // A parser of cotainers already read first 4 bytes to detect format
+ // of container, however they includes PCM frames when any format was
+ // undetected. Surely to write out them.
+ byte_count = target_byte_count;
+ if (cntr->format == CONTAINER_FORMAT_RAW &&
+ cntr->type == CONTAINER_TYPE_PARSER && !cntr->magic_handled) {
+ memcpy(buf, cntr->magic, sizeof(cntr->magic));
+ buf += sizeof(cntr->magic);
+ byte_count -= sizeof(cntr->magic);
+ cntr->magic_handled = true;
+ }
// Each container has limitation for its volume for sample data.
if (cntr->handled_byte_count > cntr->max_size - byte_count)
return err;
}
- cntr->handled_byte_count += byte_count;
+ cntr->handled_byte_count += target_byte_count;
if (cntr->handled_byte_count == cntr->max_size)
cntr->eof = true;
- *frame_count = byte_count / bytes_per_frame;
+ *frame_count = target_byte_count / bytes_per_frame;
return 0;
}