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