xref: /src/usr.sbin/virtual_oss/virtual_oss/int.h (revision 6d5a428056b52c7ce47b01d6af8aaaff6feecfdd)
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 	uint32_t rx_filter_size;
126 	uint32_t tx_filter_size;
127 	double *rx_filter_data[VMAX_CHAN];
128 	double *tx_filter_data[VMAX_CHAN];
129 	int64_t	rx_peak_value[VMAX_CHAN];
130 	int64_t	tx_peak_value[VMAX_CHAN];
131 	int8_t	rx_shift[VMAX_CHAN];
132 	int8_t	tx_shift[VMAX_CHAN];
133 	uint8_t	rx_src[VMAX_CHAN];
134 	uint8_t	tx_dst[VMAX_CHAN];
135 	uint8_t	rx_mute[VMAX_CHAN];
136 	uint8_t	tx_mute[VMAX_CHAN];
137 	uint8_t	rx_pol[VMAX_CHAN];
138 	uint8_t	tx_pol[VMAX_CHAN];
139 	uint8_t	bits;
140 	uint8_t	channels;
141 	struct virtual_compressor rx_compressor_param;
142 	double rx_compressor_gain[VMAX_CHAN];
143 	uint8_t synchronized;
144 	uint32_t rec_delay;
145 	int fd_sta;
146 	struct {
147 		const char * host;
148 		const char * port;
149 		const char * rtp_ifname;
150 		const char * rtp_port;
151 		volatile struct http_state * state;
152 		size_t nstate;
153 		int rtp_fd;
154 		int rtp_vlanid;
155 		uint32_t rtp_ts;
156 		uint16_t rtp_seqnum;
157 	} http;
158 };
159 
160 struct virtual_ring {
161 	uint8_t *buf_start;
162 	uint32_t pos_read;
163 	uint32_t total_size;
164 	uint32_t len_write;
165 };
166 
167 struct virtual_resample {
168 	SRC_DATA data;
169 	SRC_STATE *state;
170 	float *data_in;
171 	float *data_out;
172 };
173 
174 struct virtual_client {
175 	vclient_entry_t entry;
176 	uint32_t tx_filter_offset;
177 	uint32_t rx_filter_offset;
178 	int64_t *tx_filter_in[VMAX_CHAN];
179 	int64_t *rx_filter_in[VMAX_CHAN];
180 	double *tx_filter_out[VMAX_CHAN];
181 	double *rx_filter_out[VMAX_CHAN];
182 	struct virtual_ring rx_ring[2];
183 	struct virtual_ring tx_ring[2];
184 	vresample_t rx_resample;
185 	vresample_t tx_resample;
186 	struct virtual_profile *profile;
187 	uint64_t rx_samples;
188 	uint64_t rx_timestamp;
189 	uint64_t tx_samples;
190 	uint64_t tx_timestamp;
191 	uint32_t buffer_frags;
192 	uint32_t buffer_size;
193 	uint32_t low_water;
194 	uint32_t rec_delay;
195 	uint32_t rx_noise_rem;
196 	uint32_t tx_noise_rem;
197 	int	rx_busy;
198 	int	tx_busy;
199 	int	channels;
200 	int	format;
201 	int	rx_enabled;
202 	int	tx_enabled;
203 	int	rx_volume;
204 	int	tx_volume;
205 	int	type;		/* VTYPE_XXX */
206 	int	sample_rate;
207 	uint32_t buffer_size_set:1;
208 	uint32_t buffer_frags_set:1;
209 	uint32_t sync_busy:1;
210 	uint32_t sync_wakeup:1;
211 	int	padding:28;
212 };
213 
214 struct virtual_monitor {
215 	vmonitor_entry_t entry;
216 	int64_t	peak_value;
217 	uint8_t	src_chan;
218 	uint8_t	dst_chan;
219 	uint8_t	pol;
220 	uint8_t	mute;
221 	int8_t	shift;
222 };
223 
224 extern vprofile_head_t virtual_profile_client_head;
225 extern vprofile_head_t virtual_profile_loopback_head;
226 
227 extern vmonitor_head_t virtual_monitor_input;
228 extern vmonitor_head_t virtual_monitor_local;
229 extern vmonitor_head_t virtual_monitor_output;
230 
231 extern const struct cuse_methods vctl_methods;
232 
233 extern struct virtual_compressor voss_output_compressor_param;
234 extern double voss_output_compressor_gain[VMAX_CHAN];
235 extern int64_t voss_output_peak[VMAX_CHAN];
236 extern int64_t voss_input_peak[VMAX_CHAN];
237 extern uint32_t voss_jitter_up;
238 extern uint32_t voss_jitter_down;
239 extern uint32_t voss_max_channels;
240 extern uint32_t voss_mix_channels;
241 extern uint32_t voss_dsp_samples;
242 extern uint32_t voss_dsp_max_channels;
243 extern uint32_t voss_dsp_sample_rate;
244 extern uint32_t voss_dsp_bits;
245 extern uint8_t voss_libsamplerate_enable;
246 extern uint8_t voss_libsamplerate_quality;
247 extern int voss_is_recording;
248 extern int voss_has_synchronization;
249 extern char voss_dsp_rx_device[VMAX_STRING];
250 extern char voss_dsp_tx_device[VMAX_STRING];
251 extern char voss_ctl_device[VMAX_STRING];
252 extern volatile sig_atomic_t voss_exit;
253 
254 extern int vring_alloc(struct virtual_ring *, size_t);
255 extern void vring_free(struct virtual_ring *);
256 extern void vring_reset(struct virtual_ring *);
257 extern void vring_get_read(struct virtual_ring *, uint8_t **, size_t *);
258 extern void vring_get_write(struct virtual_ring *, uint8_t **, size_t *);
259 extern void vring_inc_read(struct virtual_ring *, size_t);
260 extern void vring_inc_write(struct virtual_ring *, size_t);
261 extern size_t vring_total_read_len(struct virtual_ring *);
262 extern size_t vring_total_write_len(struct virtual_ring *);
263 extern size_t vring_write_linear(struct virtual_ring *, const uint8_t *, size_t);
264 extern size_t vring_read_linear(struct virtual_ring *, uint8_t *, size_t);
265 extern size_t vring_write_zero(struct virtual_ring *, size_t);
266 
267 extern vclient_t *vclient_alloc(void);
268 extern void vclient_free(vclient_t *);
269 
270 extern int vclient_get_default_fmt(vprofile_t *, int type);
271 extern int vclient_setup_buffers(vclient_t *, int size, int frags,
272     int channels, int format, int sample_rate);
273 extern int vclient_export_read_locked(vclient_t *);
274 extern void vclient_import_write_locked(vclient_t *);
275 
276 extern uint32_t vclient_sample_bytes(vclient_t *);
277 extern uint32_t vclient_bufsize_internal(vclient_t *);
278 extern uint32_t vclient_bufsize_scaled(vclient_t *);
279 
280 extern int64_t vclient_noise(uint32_t *, int64_t, int8_t);
281 
282 extern vmonitor_t *vmonitor_alloc(int *, vmonitor_head_t *);
283 
284 extern uint32_t format_best(uint32_t);
285 extern void format_import(uint32_t, const uint8_t *, uint32_t, int64_t *);
286 extern void format_export(uint32_t, const int64_t *, uint8_t *, uint32_t);
287 extern int64_t format_max(uint32_t);
288 extern void format_maximum(const int64_t *, int64_t *, uint32_t, uint32_t, int8_t);
289 extern void format_remix(int64_t *, uint32_t, uint32_t, uint32_t);
290 extern void format_silence(uint32_t, uint8_t *, uint32_t);
291 
292 extern void *virtual_oss_process(void *);
293 
294 /* Audio Delay prototypes */
295 extern uint32_t voss_ad_last_delay;
296 extern uint32_t voss_dsp_rx_refresh;
297 extern uint32_t voss_dsp_tx_refresh;
298 extern uint8_t voss_ad_enabled;
299 extern uint8_t voss_ad_output_signal;
300 extern uint8_t voss_ad_input_channel;
301 extern uint8_t voss_ad_output_channel;
302 extern void voss_ad_reset(void);
303 extern void voss_ad_init(uint32_t);
304 extern double voss_ad_getput_sample(double);
305 
306 /* Add audio options prototype */
307 extern void voss_add_options(char *);
308 
309 /* Get current timestamp */
310 extern uint64_t virtual_oss_delay_ns(void);
311 extern void virtual_oss_wait(void);
312 extern uint64_t virtual_oss_timestamp(void);
313 
314 /* Fast array multiplication */
315 extern void voss_x3_multiply_double(const int64_t *, const double *, double *, const size_t);
316 
317 /* Equalizer support */
318 extern void vclient_tx_equalizer(struct virtual_client *, int64_t *, size_t);
319 extern void vclient_rx_equalizer(struct virtual_client *, int64_t *, size_t);
320 extern int vclient_eq_alloc(struct virtual_client *);
321 extern void vclient_eq_free(struct virtual_client *);
322 
323 /* Internal compressor */
324 extern void voss_compressor(int64_t *, double *, const struct virtual_compressor *,
325    const unsigned, const unsigned, const int64_t);
326 
327 /* HTTP daemon support */
328 extern const char *voss_httpd_start(vprofile_t *);
329 
330 #endif					/* _VIRTUAL_INT_H_ */
331