xref: /freebsd/usr.sbin/virtual_oss/virtual_oss/int.h (revision 93a234a694f37d373acf303a247d129dda28044e)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2012-2022 Hans Petter Selasky
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #ifndef _VIRTUAL_INT_H_
29 #define	_VIRTUAL_INT_H_
30 
31 #include <signal.h>
32 #include <pthread.h>
33 
34 #include <cuse.h>
35 #include <samplerate.h>
36 
37 extern pthread_mutex_t atomic_mtx;
38 extern pthread_cond_t atomic_cv;
39 
40 #define atomic_lock()	pthread_mutex_lock(&atomic_mtx)
41 #define atomic_unlock()	pthread_mutex_unlock(&atomic_mtx)
42 #define atomic_wait()	pthread_cond_wait(&atomic_cv, &atomic_mtx)
43 #define atomic_wakeup()	do {			\
44 	pthread_cond_broadcast(&atomic_cv);	\
45 	cuse_poll_wakeup();			\
46 } while (0)
47 
48 #define AFMT_32BIT \
49 	(AFMT_S32_LE | AFMT_S32_BE | AFMT_U32_LE | AFMT_U32_BE | \
50 	AFMT_F32_LE | AFMT_F32_BE)
51 #define AFMT_24BIT \
52 	(AFMT_S24_LE | AFMT_S24_BE | AFMT_U24_LE | AFMT_U24_BE)
53 #define AFMT_16BIT \
54 	(AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE)
55 #define AFMT_8BIT \
56 	(AFMT_U8 | AFMT_S8)
57 
58 #define	VMAX_CHAN 64
59 /*
60  * XXX 32 - strlen("/dev") to not exceed OSS_DEVNODE_SIZE in soundcard.h. Also
61  * silences GCC warnings.
62  */
63 #define	VMAX_STRING 27
64 
65 #define	VTYPE_OSS_DAT 0
66 #define	VTYPE_WAV_HDR 1
67 #define	VTYPE_WAV_DAT 2
68 
69 #define	VPREFERRED_SNE_AFMT \
70   (AFMT_S8 | AFMT_S16_NE | AFMT_S24_NE | AFMT_S32_NE)
71 #define	VPREFERRED_UNE_AFMT \
72   (AFMT_U8 | AFMT_U16_NE | AFMT_U24_NE | AFMT_U32_NE)
73 #define	VPREFERRED_SLE_AFMT \
74   (AFMT_S8 | AFMT_S16_LE | AFMT_S24_LE | AFMT_S32_LE)
75 #define	VPREFERRED_SBE_AFMT \
76   (AFMT_S8 | AFMT_S16_BE | AFMT_S24_BE | AFMT_S32_BE)
77 #define	VPREFERRED_ULE_AFMT \
78   (AFMT_U8 | AFMT_U16_LE | AFMT_U24_LE | AFMT_U32_LE)
79 #define	VPREFERRED_UBE_AFMT \
80   (AFMT_U8 | AFMT_U16_BE | AFMT_U24_BE | AFMT_U32_BE)
81 
82 #define	VSUPPORTED_AFMT \
83   (AFMT_S16_BE | AFMT_S16_LE | AFMT_U16_BE | AFMT_U16_LE | \
84   AFMT_S24_BE | AFMT_S24_LE | AFMT_U24_BE | AFMT_U24_LE | \
85   AFMT_S32_BE | AFMT_S32_LE | AFMT_U32_BE | AFMT_U32_LE | \
86   AFMT_F32_BE | AFMT_F32_LE | \
87   AFMT_U8 | AFMT_S8)
88 
89 #define	VVOLUME_UNIT_SHIFT 7
90 
91 struct virtual_profile;
92 
93 typedef TAILQ_ENTRY(virtual_profile) vprofile_entry_t;
94 typedef TAILQ_HEAD(, virtual_profile) vprofile_head_t;
95 typedef struct virtual_profile vprofile_t;
96 
97 struct virtual_client;
98 
99 typedef TAILQ_ENTRY(virtual_client) vclient_entry_t;
100 typedef TAILQ_HEAD(, virtual_client) vclient_head_t;
101 typedef struct virtual_client vclient_t;
102 
103 struct virtual_monitor;
104 typedef TAILQ_ENTRY(virtual_monitor) vmonitor_entry_t;
105 typedef TAILQ_HEAD(, virtual_monitor) vmonitor_head_t;
106 typedef struct virtual_monitor vmonitor_t;
107 
108 struct virtual_resample;
109 typedef struct virtual_resample vresample_t;
110 
111 struct cuse_methods;
112 
113 struct virtual_compressor {
114 	uint8_t enabled;	/* 0..1 */
115 	uint8_t knee;		/* 0..255 */
116 	uint8_t	attack;		/* 0..62 */
117 	uint8_t	decay;		/* 0..62 */
118 };
119 
120 struct virtual_profile {
121 	vprofile_entry_t entry;
122 	vclient_head_t head;
123 	char oss_name[VMAX_STRING];
124 	char wav_name[VMAX_STRING];
125 	struct cuse_dev *oss_dev;
126 	struct cuse_dev *wav_dev;
127 	uint32_t rx_filter_size;
128 	uint32_t tx_filter_size;
129 	double *rx_filter_data[VMAX_CHAN];
130 	double *tx_filter_data[VMAX_CHAN];
131 	int64_t	rx_peak_value[VMAX_CHAN];
132 	int64_t	tx_peak_value[VMAX_CHAN];
133 	int8_t	rx_shift[VMAX_CHAN];
134 	int8_t	tx_shift[VMAX_CHAN];
135 	uint8_t	rx_src[VMAX_CHAN];
136 	uint8_t	tx_dst[VMAX_CHAN];
137 	uint8_t	rx_mute[VMAX_CHAN];
138 	uint8_t	tx_mute[VMAX_CHAN];
139 	uint8_t	rx_pol[VMAX_CHAN];
140 	uint8_t	tx_pol[VMAX_CHAN];
141 	uint8_t	bits;
142 	uint8_t	channels;
143 	struct virtual_compressor rx_compressor_param;
144 	double rx_compressor_gain[VMAX_CHAN];
145 	uint8_t synchronized;
146 	uint32_t rec_delay;
147 	struct {
148 		const char * host;
149 		const char * port;
150 		const char * rtp_ifname;
151 		const char * rtp_port;
152 		volatile struct http_state * state;
153 		size_t nstate;
154 		int rtp_fd;
155 		int rtp_vlanid;
156 		uint32_t rtp_ts;
157 		uint16_t rtp_seqnum;
158 	} http;
159 };
160 
161 struct virtual_ring {
162 	uint8_t *buf_start;
163 	uint32_t pos_read;
164 	uint32_t total_size;
165 	uint32_t len_write;
166 };
167 
168 struct virtual_resample {
169 	SRC_DATA data;
170 	SRC_STATE *state;
171 	float *data_in;
172 	float *data_out;
173 };
174 
175 struct virtual_client {
176 	vclient_entry_t entry;
177 	uint32_t tx_filter_offset;
178 	uint32_t rx_filter_offset;
179 	int64_t *tx_filter_in[VMAX_CHAN];
180 	int64_t *rx_filter_in[VMAX_CHAN];
181 	double *tx_filter_out[VMAX_CHAN];
182 	double *rx_filter_out[VMAX_CHAN];
183 	struct virtual_ring rx_ring[2];
184 	struct virtual_ring tx_ring[2];
185 	vresample_t rx_resample;
186 	vresample_t tx_resample;
187 	struct virtual_profile *profile;
188 	uint64_t rx_samples;
189 	uint64_t rx_timestamp;
190 	uint64_t tx_samples;
191 	uint64_t tx_timestamp;
192 	uint32_t buffer_frags;
193 	uint32_t buffer_size;
194 	uint32_t low_water;
195 	uint32_t rec_delay;
196 	uint32_t rx_noise_rem;
197 	uint32_t tx_noise_rem;
198 	int	rx_busy;
199 	int	tx_busy;
200 	int	channels;
201 	int	format;
202 	int	rx_enabled;
203 	int	tx_enabled;
204 	int	rx_volume;
205 	int	tx_volume;
206 	int	type;		/* VTYPE_XXX */
207 	int	sample_rate;
208 	uint32_t buffer_size_set:1;
209 	uint32_t buffer_frags_set:1;
210 	uint32_t sync_busy:1;
211 	uint32_t sync_wakeup:1;
212 	int	padding:28;
213 };
214 
215 struct virtual_monitor {
216 	vmonitor_entry_t entry;
217 	int64_t	peak_value;
218 	uint8_t	src_chan;
219 	uint8_t	dst_chan;
220 	uint8_t	pol;
221 	uint8_t	mute;
222 	int8_t	shift;
223 };
224 
225 extern vprofile_head_t virtual_profile_client_head;
226 extern vprofile_head_t virtual_profile_loopback_head;
227 
228 extern vmonitor_head_t virtual_monitor_input;
229 extern vmonitor_head_t virtual_monitor_local;
230 extern vmonitor_head_t virtual_monitor_output;
231 
232 extern const struct cuse_methods vctl_methods;
233 
234 extern struct virtual_compressor voss_output_compressor_param;
235 extern double voss_output_compressor_gain[VMAX_CHAN];
236 extern int64_t voss_output_peak[VMAX_CHAN];
237 extern int64_t voss_input_peak[VMAX_CHAN];
238 extern uint32_t voss_jitter_up;
239 extern uint32_t voss_jitter_down;
240 extern uint32_t voss_max_channels;
241 extern uint32_t voss_mix_channels;
242 extern uint32_t voss_dsp_samples;
243 extern uint32_t voss_dsp_max_channels;
244 extern uint32_t voss_dsp_sample_rate;
245 extern uint32_t voss_dsp_bits;
246 extern uint8_t voss_libsamplerate_enable;
247 extern uint8_t voss_libsamplerate_quality;
248 extern int voss_is_recording;
249 extern int voss_has_synchronization;
250 extern char voss_dsp_rx_device[VMAX_STRING];
251 extern char voss_dsp_tx_device[VMAX_STRING];
252 extern char voss_ctl_device[VMAX_STRING];
253 extern volatile sig_atomic_t voss_exit;
254 
255 extern int vring_alloc(struct virtual_ring *, size_t);
256 extern void vring_free(struct virtual_ring *);
257 extern void vring_reset(struct virtual_ring *);
258 extern void vring_get_read(struct virtual_ring *, uint8_t **, size_t *);
259 extern void vring_get_write(struct virtual_ring *, uint8_t **, size_t *);
260 extern void vring_inc_read(struct virtual_ring *, size_t);
261 extern void vring_inc_write(struct virtual_ring *, size_t);
262 extern size_t vring_total_read_len(struct virtual_ring *);
263 extern size_t vring_total_write_len(struct virtual_ring *);
264 extern size_t vring_write_linear(struct virtual_ring *, const uint8_t *, size_t);
265 extern size_t vring_read_linear(struct virtual_ring *, uint8_t *, size_t);
266 extern size_t vring_write_zero(struct virtual_ring *, size_t);
267 
268 extern vclient_t *vclient_alloc(void);
269 extern void vclient_free(vclient_t *);
270 
271 extern int vclient_get_default_fmt(vprofile_t *, int type);
272 extern int vclient_setup_buffers(vclient_t *, int size, int frags,
273     int channels, int format, int sample_rate);
274 extern int vclient_export_read_locked(vclient_t *);
275 extern void vclient_import_write_locked(vclient_t *);
276 
277 extern uint32_t vclient_sample_bytes(vclient_t *);
278 extern uint32_t vclient_bufsize_internal(vclient_t *);
279 extern uint32_t vclient_bufsize_scaled(vclient_t *);
280 
281 extern int64_t vclient_noise(uint32_t *, int64_t, int8_t);
282 
283 extern vmonitor_t *vmonitor_alloc(int *, vmonitor_head_t *);
284 
285 extern uint32_t format_best(uint32_t);
286 extern void format_import(uint32_t, const uint8_t *, uint32_t, int64_t *);
287 extern void format_export(uint32_t, const int64_t *, uint8_t *, uint32_t);
288 extern int64_t format_max(uint32_t);
289 extern void format_maximum(const int64_t *, int64_t *, uint32_t, uint32_t, int8_t);
290 extern void format_remix(int64_t *, uint32_t, uint32_t, uint32_t);
291 extern void format_silence(uint32_t, uint8_t *, uint32_t);
292 
293 extern void *virtual_oss_process(void *);
294 
295 /* Audio Delay prototypes */
296 extern uint32_t voss_ad_last_delay;
297 extern uint32_t voss_dsp_rx_refresh;
298 extern uint32_t voss_dsp_tx_refresh;
299 extern uint8_t voss_ad_enabled;
300 extern uint8_t voss_ad_output_signal;
301 extern uint8_t voss_ad_input_channel;
302 extern uint8_t voss_ad_output_channel;
303 extern void voss_ad_reset(void);
304 extern void voss_ad_init(uint32_t);
305 extern double voss_ad_getput_sample(double);
306 
307 /* Add audio options prototype */
308 extern void voss_add_options(char *);
309 
310 /* Get current timestamp */
311 extern uint64_t virtual_oss_delay_ns(void);
312 extern void virtual_oss_wait(void);
313 extern uint64_t virtual_oss_timestamp(void);
314 
315 /* Fast array multiplication */
316 extern void voss_x3_multiply_double(const int64_t *, const double *, double *, const size_t);
317 
318 /* Equalizer support */
319 extern void vclient_tx_equalizer(struct virtual_client *, int64_t *, size_t);
320 extern void vclient_rx_equalizer(struct virtual_client *, int64_t *, size_t);
321 extern int vclient_eq_alloc(struct virtual_client *);
322 extern void vclient_eq_free(struct virtual_client *);
323 
324 /* Internal compressor */
325 extern void voss_compressor(int64_t *, double *, const struct virtual_compressor *,
326    const unsigned, const unsigned, const int64_t);
327 
328 /* HTTP daemon support */
329 extern const char *voss_httpd_start(vprofile_t *);
330 
331 #endif					/* _VIRTUAL_INT_H_ */
332