xref: /src/sys/dev/sound/pcm/feeder.h (revision 6002ce537b6a0e524da1a60ccd70493d8cd59b9b)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2005-2009 Ariff Abdullah <ariff@FreeBSD.org>
5  * Copyright (c) 1999 Cameron Grant <cg@FreeBSD.org>
6  * All rights reserved.
7  * Copyright (c) 2025 The FreeBSD Foundation
8  *
9  * Portions of this software were developed by Christos Margiolis
10  * <christos@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 enum feeder_type {
35 	FEEDER_ROOT,
36 	FEEDER_FORMAT,
37 	FEEDER_MIXER,
38 	FEEDER_RATE,
39 	FEEDER_EQ,
40 	FEEDER_VOLUME,
41 	FEEDER_MATRIX,
42 	FEEDER_LAST,
43 };
44 
45 struct pcm_feederdesc {
46 	u_int32_t in, out;
47 };
48 
49 struct feeder_class {
50 	KOBJ_CLASS_FIELDS;
51 	enum feeder_type type;
52 	SLIST_ENTRY(feeder_class) link;
53 };
54 
55 struct pcm_feeder {
56     	KOBJ_FIELDS;
57 	struct pcm_feederdesc desc;
58 	void *data;
59 	struct feeder_class *class;
60 	struct pcm_feeder *source, *parent;
61 };
62 
63 void feeder_register(void *p);
64 struct feeder_class *feeder_getclass(u_int32_t type);
65 
66 u_int32_t snd_fmtscore(u_int32_t fmt);
67 u_int32_t snd_fmtbestbit(u_int32_t fmt, u_int32_t *fmts);
68 u_int32_t snd_fmtbestchannel(u_int32_t fmt, u_int32_t *fmts);
69 u_int32_t snd_fmtbest(u_int32_t fmt, u_int32_t *fmts);
70 
71 int feeder_add(struct pcm_channel *c, struct feeder_class *fc,
72     struct pcm_feederdesc *desc);
73 void feeder_remove(struct pcm_channel *c);
74 struct pcm_feeder *feeder_find(struct pcm_channel *c, u_int32_t type);
75 int feeder_chain(struct pcm_channel *);
76 
77 #define FEEDER_DECLARE(feeder, ctype)					\
78 static struct feeder_class feeder ## _class = {				\
79 	.name =		#feeder,					\
80 	.methods =	feeder ## _methods,				\
81 	.size =		sizeof(struct pcm_feeder),			\
82 	.type =		ctype,						\
83 };									\
84 SYSINIT(feeder, SI_SUB_DRIVERS, SI_ORDER_ANY, feeder_register,		\
85     &feeder ## _class)
86 
87 /* feeder_format */
88 enum {
89 	FEEDFORMAT_CHANNELS
90 };
91 
92 /* feeder_mixer */
93 enum {
94 	FEEDMIXER_CHANNELS
95 };
96 
97 /* feeder_rate */
98 enum {
99 	FEEDRATE_SRC,
100 	FEEDRATE_DST,
101 	FEEDRATE_QUALITY,
102 	FEEDRATE_CHANNELS
103 };
104 
105 #define FEEDRATE_RATEMIN	1
106 #define FEEDRATE_RATEMAX	2016000		/* 48000 * 42 */
107 #define FEEDRATE_MIN		1
108 #define FEEDRATE_MAX		0x7fffff	/* sign 24bit ~ 8ghz ! */
109 #define FEEDRATE_ROUNDHZ	25
110 #define FEEDRATE_ROUNDHZ_MIN	0
111 #define FEEDRATE_ROUNDHZ_MAX	500
112 
113 extern int feeder_rate_min;
114 extern int feeder_rate_max;
115 extern int feeder_rate_round;
116 extern int feeder_rate_quality;
117 
118 /* feeder_eq */
119 enum {
120 	FEEDEQ_CHANNELS,
121 	FEEDEQ_RATE,
122 	FEEDEQ_TREBLE,
123 	FEEDEQ_BASS,
124 	FEEDEQ_PREAMP,
125 	FEEDEQ_STATE,
126 	FEEDEQ_DISABLE,
127 	FEEDEQ_ENABLE,
128 	FEEDEQ_BYPASS,
129 	FEEDEQ_UNKNOWN
130 };
131 
132 int feeder_eq_validrate(uint32_t);
133 void feeder_eq_initsys(device_t);
134 
135 /* feeder_volume */
136 enum {
137 	FEEDVOLUME_CLASS,
138 	FEEDVOLUME_CHANNELS,
139 	FEEDVOLUME_STATE,
140 	FEEDVOLUME_ENABLE,
141 	FEEDVOLUME_BYPASS
142 };
143 
144 int feeder_volume_apply_matrix(struct pcm_feeder *, struct pcmchan_matrix *);
145 
146 /* feeder_matrix */
147 int feeder_matrix_default_id(uint32_t);
148 struct pcmchan_matrix *feeder_matrix_default_channel_map(uint32_t);
149 
150 uint32_t feeder_matrix_default_format(uint32_t);
151 
152 int feeder_matrix_format_id(uint32_t);
153 struct pcmchan_matrix *feeder_matrix_format_map(uint32_t);
154 
155 struct pcmchan_matrix *feeder_matrix_id_map(int);
156 
157 int feeder_matrix_setup(struct pcm_feeder *, struct pcmchan_matrix *,
158     struct pcmchan_matrix *);
159 int feeder_matrix_compare(struct pcmchan_matrix *, struct pcmchan_matrix *);
160 
161 /* 4Front OSS stuffs */
162 int feeder_matrix_oss_get_channel_order(struct pcmchan_matrix *,
163     unsigned long long *);
164 int feeder_matrix_oss_set_channel_order(struct pcmchan_matrix *,
165     unsigned long long *);
166 
167 /*
168  * By default, various feeders only deal with sign 16/32 bit native-endian
169  * since it should provide the fastest processing path. Processing 8bit samples
170  * is too noisy due to limited dynamic range, while 24bit is quite slow due to
171  * unnatural per-byte read/write. However, for debugging purposes, ensuring
172  * implementation correctness and torture test, the following can be defined:
173  *
174  *      SND_FEEDER_MULTIFORMAT - Compile all type of converters, but force
175  *                               8bit samples to be converted to 16bit
176  *                               native-endian for better dynamic range.
177  *                               Process 24bit samples natively.
178  * SND_FEEDER_FULL_MULTIFORMAT - Ditto, but process 8bit samples natively.
179  */
180 #ifdef SND_FEEDER_FULL_MULTIFORMAT
181 #undef SND_FEEDER_MULTIFORMAT
182 #define SND_FEEDER_MULTIFORMAT	1
183 #endif
184