diff --git a/axfer/Makefile.am b/axfer/Makefile.am index 55fcf71..cb4b188 100644 --- a/axfer/Makefile.am +++ b/axfer/Makefile.am @@ -17,7 +17,8 @@ LDADD = \ noinst_HEADERS = \ misc.h \ subcmd.h \ - container.h + container.h \ + mapper.h axfer_SOURCES = \ misc.h \ @@ -29,4 +30,6 @@ axfer_SOURCES = \ container-riff-wave.c \ container-au.c \ container-voc.c \ - container-raw.c + container-raw.c \ + mapper.h \ + mapper.c diff --git a/axfer/mapper.c b/axfer/mapper.c new file mode 100644 index 0000000..eb63a0e --- /dev/null +++ b/axfer/mapper.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// mapper.c - an interface of muxer/demuxer between buffer with data frames and +// formatted files. +// +// Copyright (c) 2018 Takashi Sakamoto +// +// Licensed under the terms of the GNU General Public License, version 2. + +#include "mapper.h" +#include "misc.h" + +#include + +static const char *const mapper_type_labels[] = { + [MAPPER_TYPE_MUXER] = "muxer", + [MAPPER_TYPE_DEMUXER] = "demuxer", +}; + +static const char *const mapper_target_labels[] = { + [MAPPER_TARGET_COUNT] = "", +}; + +int mapper_context_init(struct mapper_context *mapper, + enum mapper_type type, unsigned int cntr_count, + unsigned int verbose) +{ + const struct mapper_data *data = NULL; + + assert(mapper); + assert(cntr_count > 0); + + // Detect forgotten to destruct. + assert(mapper->private_data == NULL); + + memset(mapper, 0, sizeof(*mapper)); + + mapper->ops = &data->ops; + mapper->type = type; + + mapper->private_data = malloc(data->private_size); + if (mapper->private_data == NULL) + return -ENOMEM; + memset(mapper->private_data, 0, data->private_size); + + mapper->cntr_count = cntr_count; + mapper->verbose = verbose; + + return 0; +} + +int mapper_context_pre_process(struct mapper_context *mapper, + snd_pcm_access_t access, + unsigned int bytes_per_sample, + unsigned int samples_per_frame, + unsigned int frames_per_buffer, + struct container_context *cntrs) +{ + int err; + + assert(mapper); + assert(access >= SND_PCM_ACCESS_MMAP_INTERLEAVED); + assert(access <= SND_PCM_ACCESS_RW_NONINTERLEAVED); + assert(bytes_per_sample > 0); + assert(samples_per_frame > 0); + assert(cntrs); + + mapper->access = access; + mapper->bytes_per_sample = bytes_per_sample; + mapper->samples_per_frame = samples_per_frame; + mapper->frames_per_buffer = frames_per_buffer; + + err = mapper->ops->pre_process(mapper, cntrs, mapper->cntr_count); + if (err < 0) + return err; + + if (mapper->verbose > 0) { + fprintf(stderr, "Mapper: %s\n", + mapper_type_labels[mapper->type]); + fprintf(stderr, " target: %s\n", + mapper_target_labels[mapper->target]); + fprintf(stderr, " access: %s\n", + snd_pcm_access_name(mapper->access)); + fprintf(stderr, " bytes/sample: %u\n", + mapper->bytes_per_sample); + fprintf(stderr, " samples/frame: %u\n", + mapper->samples_per_frame); + fprintf(stderr, " frames/buffer: %lu\n", + mapper->frames_per_buffer); + } + + return 0; +} + +int mapper_context_process_frames(struct mapper_context *mapper, + void *frame_buffer, + unsigned int *frame_count, + struct container_context *cntrs) +{ + assert(mapper); + assert(frame_buffer); + assert(frame_count); + assert(*frame_count <= mapper->frames_per_buffer); + assert(cntrs); + + return mapper->ops->process_frames(mapper, frame_buffer, frame_count, + cntrs, mapper->cntr_count); +} + +void mapper_context_post_process(struct mapper_context *mapper) +{ + assert(mapper); + + if (mapper->ops && mapper->ops->post_process) + mapper->ops->post_process(mapper); +} + +void mapper_context_destroy(struct mapper_context *mapper) +{ + assert(mapper); + + if (mapper->private_data) + free(mapper->private_data); + mapper->private_data = NULL; +} diff --git a/axfer/mapper.h b/axfer/mapper.h new file mode 100644 index 0000000..c4caf09 --- /dev/null +++ b/axfer/mapper.h @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// mapper.h - an interface of muxer/demuxer between buffer with data frames and +// formatted files. +// +// Copyright (c) 2018 Takashi Sakamoto +// +// Licensed under the terms of the GNU General Public License, version 2. + +#ifndef __ALSA_UTILS_AXFER_MAPPER__H_ +#define __ALSA_UTILS_AXFER_MAPPER__H_ + +#include "container.h" + +enum mapper_type { + MAPPER_TYPE_MUXER = 0, + MAPPER_TYPE_DEMUXER, + MAPPER_TYPE_COUNT, +}; + +enum mapper_target { + MAPPER_TARGET_COUNT, +}; + +struct mapper_ops; + +struct mapper_context { + enum mapper_type type; + enum mapper_target target; + const struct mapper_ops *ops; + unsigned int private_size; + + void *private_data; + unsigned int cntr_count; + + // A part of parameters of PCM substream. + snd_pcm_access_t access; + unsigned int bytes_per_sample; + unsigned int samples_per_frame; + snd_pcm_uframes_t frames_per_buffer; + + unsigned int verbose; +}; + +int mapper_context_init(struct mapper_context *mapper, + enum mapper_type type, unsigned int cntr_count, + unsigned int verbose); +int mapper_context_pre_process(struct mapper_context *mapper, + snd_pcm_access_t access, + unsigned int bytes_per_sample, + unsigned int samples_per_frame, + unsigned int frames_per_buffer, + struct container_context *cntrs); +int mapper_context_process_frames(struct mapper_context *mapper, + void *frame_buffer, + unsigned int *frame_count, + struct container_context *cntrs); +void mapper_context_post_process(struct mapper_context *mapper); +void mapper_context_destroy(struct mapper_context *mapper); + +// For internal use in 'mapper' module. + +struct mapper_ops { + int (*pre_process)(struct mapper_context *mapper, + struct container_context *cntrs, + unsigned int cntr_count); + int (*process_frames)(struct mapper_context *mapper, + void *frame_buffer, unsigned int *frame_count, + struct container_context *cntrs, + unsigned int cntr_count); + void (*post_process)(struct mapper_context *mapper); +}; + +struct mapper_data { + struct mapper_ops ops; + unsigned int private_size; +}; + +#endif