xref: /third_party/alsa-utils/axfer/mapper.c (revision c72fcc34)
1// SPDX-License-Identifier: GPL-2.0
2//
3// mapper.c - an interface of muxer/demuxer between buffer with data frames and
4// 	      formatted files.
5//
6// Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp>
7//
8// Licensed under the terms of the GNU General Public License, version 2.
9
10#include "mapper.h"
11#include "misc.h"
12
13#include <stdio.h>
14
15static const char *const mapper_type_labels[] = {
16	[MAPPER_TYPE_MUXER] = "muxer",
17	[MAPPER_TYPE_DEMUXER] = "demuxer",
18};
19
20static const char *const mapper_target_labels[] = {
21	[MAPPER_TARGET_SINGLE] = "single",
22	[MAPPER_TARGET_MULTIPLE] = "multiple",
23};
24
25int mapper_context_init(struct mapper_context *mapper,
26			enum mapper_type type, unsigned int cntr_count,
27			unsigned int verbose)
28{
29	const struct mapper_data *data = NULL;
30
31	assert(mapper);
32	assert(cntr_count > 0);
33
34	// Detect forgotten to destruct.
35	assert(mapper->private_data == NULL);
36
37	memset(mapper, 0, sizeof(*mapper));
38
39	if (type == MAPPER_TYPE_MUXER) {
40		if (cntr_count == 1) {
41			data = &mapper_muxer_single;
42			mapper->target = MAPPER_TARGET_SINGLE;
43		} else {
44			data = &mapper_muxer_multiple;
45			mapper->target = MAPPER_TARGET_MULTIPLE;
46		}
47	} else {
48		if (cntr_count == 1) {
49			data = &mapper_demuxer_single;
50			mapper->target = MAPPER_TARGET_SINGLE;
51		} else {
52			data = &mapper_demuxer_multiple;
53			mapper->target = MAPPER_TARGET_MULTIPLE;
54		}
55	}
56
57	mapper->ops = &data->ops;
58	mapper->type = type;
59
60	mapper->private_data = malloc(data->private_size);
61	if (mapper->private_data == NULL)
62		return -ENOMEM;
63	memset(mapper->private_data, 0, data->private_size);
64
65	mapper->cntr_count = cntr_count;
66	mapper->verbose = verbose;
67
68	return 0;
69}
70
71int mapper_context_pre_process(struct mapper_context *mapper,
72			       snd_pcm_access_t access,
73			       unsigned int bytes_per_sample,
74			       unsigned int samples_per_frame,
75			       unsigned int frames_per_buffer,
76			       struct container_context *cntrs)
77{
78	int err;
79
80	assert(mapper);
81	assert(access >= SND_PCM_ACCESS_MMAP_INTERLEAVED);
82	assert(access <= SND_PCM_ACCESS_RW_NONINTERLEAVED);
83	assert(bytes_per_sample > 0);
84	assert(samples_per_frame > 0);
85	assert(cntrs);
86
87	// The purpose of multiple target is to mux/demux each channels to/from
88	// containers.
89	if (mapper->target == MAPPER_TARGET_MULTIPLE &&
90	    samples_per_frame != mapper->cntr_count)
91		return -EINVAL;
92
93	mapper->access = access;
94	mapper->bytes_per_sample = bytes_per_sample;
95	mapper->samples_per_frame = samples_per_frame;
96	mapper->frames_per_buffer = frames_per_buffer;
97
98	err = mapper->ops->pre_process(mapper, cntrs, mapper->cntr_count);
99	if (err < 0)
100		return err;
101
102	if (mapper->verbose > 0) {
103		fprintf(stderr, "Mapper: %s\n",
104		       mapper_type_labels[mapper->type]);
105		fprintf(stderr, "  target: %s\n",
106		       mapper_target_labels[mapper->target]);
107		fprintf(stderr, "  access: %s\n",
108		       snd_pcm_access_name(mapper->access));
109		fprintf(stderr, "  bytes/sample: %u\n",
110			mapper->bytes_per_sample);
111		fprintf(stderr, "  samples/frame: %u\n",
112			mapper->samples_per_frame);
113		fprintf(stderr, "  frames/buffer: %lu\n",
114			mapper->frames_per_buffer);
115	}
116
117	return 0;
118}
119
120int mapper_context_process_frames(struct mapper_context *mapper,
121				  void *frame_buffer,
122				  unsigned int *frame_count,
123				  struct container_context *cntrs)
124{
125	assert(mapper);
126	assert(frame_buffer);
127	assert(frame_count);
128	assert(*frame_count <= mapper->frames_per_buffer);
129	assert(cntrs);
130
131	return mapper->ops->process_frames(mapper, frame_buffer, frame_count,
132					    cntrs, mapper->cntr_count);
133}
134
135void mapper_context_post_process(struct mapper_context *mapper)
136{
137	assert(mapper);
138
139	if (mapper->ops && mapper->ops->post_process)
140		mapper->ops->post_process(mapper);
141}
142
143void mapper_context_destroy(struct mapper_context *mapper)
144{
145	assert(mapper);
146
147	if (mapper->private_data)
148		free(mapper->private_data);
149	mapper->private_data = NULL;
150}
151