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 #include <sys/queue.h>
29 #include <sys/types.h>
30 #include <sys/soundcard.h>
31
32 #include <stdint.h>
33 #include <stdbool.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <err.h>
38 #include <time.h>
39 #include <assert.h>
40
41 #include "backend.h"
42 #include "int.h"
43
44 uint64_t
virtual_oss_timestamp(void)45 virtual_oss_timestamp(void)
46 {
47 struct timespec ts;
48 uint64_t nsec;
49
50 clock_gettime(CLOCK_MONOTONIC, &ts);
51
52 nsec = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
53 return (nsec);
54 }
55
56 uint64_t
virtual_oss_delay_ns(void)57 virtual_oss_delay_ns(void)
58 {
59 uint64_t delay;
60
61 delay = voss_dsp_samples;
62 delay *= 1000000000ULL;
63 delay /= voss_dsp_sample_rate;
64
65 return (delay);
66 }
67
68 void
virtual_oss_wait(void)69 virtual_oss_wait(void)
70 {
71 uint64_t delay;
72 uint64_t nsec;
73
74 nsec = virtual_oss_timestamp();
75
76 delay = virtual_oss_delay_ns();
77
78 usleep((delay - (nsec % delay)) / 1000);
79 }
80
81 static size_t
vclient_read_linear(struct virtual_client * pvc,struct virtual_ring * pvr,int64_t * dst,size_t total)82 vclient_read_linear(struct virtual_client *pvc, struct virtual_ring *pvr,
83 int64_t *dst, size_t total) __requires_exclusive(atomic_mtx)
84 {
85 size_t total_read = 0;
86
87 pvc->sync_busy = 1;
88 while (1) {
89 size_t read = vring_read_linear(pvr, (uint8_t *)dst, 8 * total) / 8;
90
91 total_read += read;
92 dst += read;
93 total -= read;
94
95 if (!pvc->profile->synchronized || pvc->sync_wakeup ||
96 total == 0) {
97 /* fill rest of buffer with silence, if any */
98 if (total_read != 0 && total != 0)
99 memset(dst, 0, 8 * total);
100 break;
101 }
102 atomic_wait();
103 }
104 pvc->sync_busy = 0;
105 if (pvc->sync_wakeup)
106 atomic_wakeup();
107
108 vclient_tx_equalizer(pvc, dst - total_read, total_read);
109
110 return (total_read);
111 }
112
113 static size_t
vclient_write_linear(struct virtual_client * pvc,struct virtual_ring * pvr,int64_t * src,size_t total)114 vclient_write_linear(struct virtual_client *pvc, struct virtual_ring *pvr,
115 int64_t *src, size_t total) __requires_exclusive(atomic_mtx)
116 {
117 size_t total_written = 0;
118
119 vclient_rx_equalizer(pvc, src, total);
120
121 pvc->sync_busy = 1;
122 while (1) {
123 size_t written = vring_write_linear(pvr, (uint8_t *)src, total * 8) / 8;
124
125 total_written += written;
126 src += written;
127 total -= written;
128
129 if (!pvc->profile->synchronized || pvc->sync_wakeup ||
130 total == 0)
131 break;
132 atomic_wait();
133 }
134 pvc->sync_busy = 0;
135 if (pvc->sync_wakeup)
136 atomic_wakeup();
137
138 return (total_written);
139 }
140
141 static inline void
virtual_oss_mixer_core_sub(const int64_t * src,int64_t * dst,uint32_t * pnoise,int src_chan,int dst_chan,int num,int64_t volume,int shift,int shift_orig,bool pol,bool assign)142 virtual_oss_mixer_core_sub(const int64_t *src, int64_t *dst,
143 uint32_t *pnoise, int src_chan, int dst_chan, int num,
144 int64_t volume, int shift, int shift_orig, bool pol,
145 bool assign)
146 {
147 if (pol)
148 volume = -volume;
149
150 if (shift < 0) {
151 shift = -shift;
152 while (num--) {
153 if (assign)
154 *dst = (*src * volume) >> shift;
155 else
156 *dst += (*src * volume) >> shift;
157 if (__predict_true(pnoise != NULL))
158 *dst += vclient_noise(pnoise, volume, shift_orig);
159 src += src_chan;
160 dst += dst_chan;
161 }
162 } else {
163 while (num--) {
164 if (assign)
165 *dst = (*src * volume) << shift;
166 else
167 *dst += (*src * volume) << shift;
168 if (__predict_true(pnoise != NULL))
169 *dst += vclient_noise(pnoise, volume, shift_orig);
170 src += src_chan;
171 dst += dst_chan;
172 }
173 }
174 }
175
176 static inline void
virtual_oss_mixer_core(const int64_t * src,int64_t * dst,uint32_t * pnoise,int src_chan,int dst_chan,int num,int64_t volume,int shift,int shift_orig,bool pol,bool assign)177 virtual_oss_mixer_core(const int64_t *src, int64_t *dst,
178 uint32_t *pnoise, int src_chan, int dst_chan, int num,
179 int64_t volume, int shift, int shift_orig, bool pol,
180 bool assign)
181 {
182 const uint8_t selector = (shift_orig > 0) + assign * 2;
183
184 /* optimize some cases */
185 switch (selector) {
186 case 0:
187 virtual_oss_mixer_core_sub(src, dst, NULL, src_chan, dst_chan,
188 num, volume, shift, shift_orig, pol, false);
189 break;
190 case 1:
191 virtual_oss_mixer_core_sub(src, dst, pnoise, src_chan, dst_chan,
192 num, volume, shift, shift_orig, pol, false);
193 break;
194 case 2:
195 virtual_oss_mixer_core_sub(src, dst, NULL, src_chan, dst_chan,
196 num, volume, shift, shift_orig, pol, true);
197 break;
198 case 3:
199 virtual_oss_mixer_core_sub(src, dst, pnoise, src_chan, dst_chan,
200 num, volume, shift, shift_orig, pol, true);
201 break;
202 }
203 }
204
205 void *
virtual_oss_process(void * arg __unused)206 virtual_oss_process(void *arg __unused)
207 {
208 vprofile_t *pvp;
209 vclient_t *pvc;
210 vmonitor_t *pvm;
211 struct voss_backend *rx_be = voss_rx_backend;
212 struct voss_backend *tx_be = voss_tx_backend;
213 int rx_fmt;
214 int tx_fmt;
215 int rx_chn;
216 int tx_chn;
217 int off;
218 int src_chans;
219 int dst_chans;
220 int src;
221 int len;
222 int samples;
223 int shift;
224 int shift_orig;
225 int shift_fmt;
226 int buffer_dsp_max_size;
227 int buffer_dsp_half_size;
228 int buffer_dsp_rx_sample_size;
229 int buffer_dsp_rx_size;
230 int buffer_dsp_tx_size_ref;
231 int buffer_dsp_tx_size;
232 uint64_t nice_timeout = 0;
233 uint64_t last_timestamp;
234 int blocks;
235 int volume;
236 int x_off;
237 int x;
238 int y;
239
240 uint8_t *buffer_dsp;
241 int64_t *buffer_monitor;
242 int64_t *buffer_temp;
243 int64_t *buffer_data;
244 int64_t *buffer_local;
245 int64_t *buffer_orig;
246
247 bool need_delay = false;
248
249 buffer_dsp_max_size = voss_dsp_samples *
250 voss_dsp_max_channels * (voss_dsp_bits / 8);
251 buffer_dsp_half_size = (voss_dsp_samples / 2) *
252 voss_dsp_max_channels * (voss_dsp_bits / 8);
253
254 buffer_dsp = malloc(buffer_dsp_max_size);
255 buffer_temp = malloc(voss_dsp_samples * voss_max_channels * 8);
256 buffer_monitor = malloc(voss_dsp_samples * voss_max_channels * 8);
257 buffer_local = malloc(voss_dsp_samples * voss_max_channels * 8);
258 buffer_data = malloc(voss_dsp_samples * voss_max_channels * 8);
259 buffer_orig = malloc(voss_dsp_samples * voss_max_channels * 8);
260
261 if (buffer_dsp == NULL || buffer_temp == NULL ||
262 buffer_monitor == NULL || buffer_local == NULL ||
263 buffer_data == NULL || buffer_orig == NULL)
264 errx(1, "Cannot allocate buffer memory");
265
266 while (1) {
267 rx_be->close(rx_be);
268 tx_be->close(tx_be);
269
270 if (voss_exit)
271 break;
272 if (need_delay)
273 sleep(2);
274
275 voss_dsp_rx_refresh = 0;
276 voss_dsp_tx_refresh = 0;
277
278 rx_be = voss_rx_backend;
279 tx_be = voss_tx_backend;
280
281 switch (voss_dsp_bits) {
282 case 8:
283 rx_fmt = tx_fmt =
284 AFMT_S8 | AFMT_U8;
285 break;
286 case 16:
287 rx_fmt = tx_fmt =
288 AFMT_S16_BE | AFMT_S16_LE |
289 AFMT_U16_BE | AFMT_U16_LE;
290 break;
291 case 24:
292 rx_fmt = tx_fmt =
293 AFMT_S24_BE | AFMT_S24_LE |
294 AFMT_U24_BE | AFMT_U24_LE;
295 break;
296 case 32:
297 rx_fmt = tx_fmt =
298 AFMT_S32_BE | AFMT_S32_LE |
299 AFMT_U32_BE | AFMT_U32_LE |
300 AFMT_F32_BE | AFMT_F32_LE;
301 break;
302 default:
303 rx_fmt = tx_fmt = 0;
304 break;
305 }
306
307 rx_chn = voss_dsp_max_channels;
308
309 if (rx_be->open(rx_be, voss_dsp_rx_device, voss_dsp_sample_rate,
310 buffer_dsp_half_size, &rx_chn, &rx_fmt) < 0) {
311 need_delay = true;
312 continue;
313 }
314
315 buffer_dsp_rx_sample_size = rx_chn * (voss_dsp_bits / 8);
316 buffer_dsp_rx_size = voss_dsp_samples * buffer_dsp_rx_sample_size;
317
318 tx_chn = voss_dsp_max_channels;
319 if (tx_be->open(tx_be, voss_dsp_tx_device, voss_dsp_sample_rate,
320 buffer_dsp_max_size, &tx_chn, &tx_fmt) < 0) {
321 need_delay = true;
322 continue;
323 }
324
325 buffer_dsp_tx_size_ref = voss_dsp_samples *
326 tx_chn * (voss_dsp_bits / 8);
327
328 /* reset compressor gain */
329 for (x = 0; x != VMAX_CHAN; x++)
330 voss_output_compressor_gain[x] = 1.0;
331
332 /* reset local buffer */
333 memset(buffer_local, 0, 8 * voss_dsp_samples * voss_max_channels);
334
335 while (1) {
336 uint64_t delta_time;
337
338 /* Check if DSP device should be re-opened */
339 if (voss_exit)
340 break;
341 if (voss_dsp_rx_refresh || voss_dsp_tx_refresh) {
342 need_delay = false;
343 break;
344 }
345 delta_time = nice_timeout - virtual_oss_timestamp();
346
347 /* Don't service more than 2x sample rate */
348 nice_timeout = virtual_oss_delay_ns() / 2;
349 if (delta_time >= 1000 && delta_time <= nice_timeout) {
350 /* convert from ns to us */
351 usleep(delta_time / 1000);
352 }
353 /* Compute next timeout */
354 nice_timeout += virtual_oss_timestamp();
355
356 /* Read in samples */
357 len = rx_be->transfer(rx_be, buffer_dsp, buffer_dsp_rx_size);
358 if (len < 0 || (len % buffer_dsp_rx_sample_size) != 0) {
359 need_delay = true;
360 break;
361 }
362 if (len == 0)
363 continue;
364
365 /* Convert to 64-bit samples */
366 format_import(rx_fmt, buffer_dsp, len, buffer_data);
367
368 samples = len / buffer_dsp_rx_sample_size;
369 src_chans = voss_mix_channels;
370
371 /* Compute master input peak values */
372 format_maximum(buffer_data, voss_input_peak, rx_chn, samples, 0);
373
374 /* Remix format */
375 format_remix(buffer_data, rx_chn, src_chans, samples);
376
377 /* Refresh timestamp */
378 last_timestamp = virtual_oss_timestamp();
379
380 atomic_lock();
381
382 if (TAILQ_FIRST(&virtual_monitor_input) != NULL) {
383 /* make a copy of the input data, in case of remote monitoring */
384 memcpy(buffer_monitor, buffer_data, 8 * samples * src_chans);
385 }
386
387 /* (0) Check for local monitoring of output data */
388
389 TAILQ_FOREACH(pvm, &virtual_monitor_local, entry) {
390
391 int64_t val;
392
393 if (pvm->mute != 0 || pvm->src_chan >= src_chans ||
394 pvm->dst_chan >= src_chans)
395 continue;
396
397 src = pvm->src_chan;
398 shift = pvm->shift;
399 x = pvm->dst_chan;
400
401 if (pvm->pol) {
402 if (shift < 0) {
403 shift = -shift;
404 for (y = 0; y != samples; y++) {
405 val = -(buffer_local[(y * src_chans) + src] >> shift);
406 buffer_data[(y * src_chans) + x] += val;
407 if (val < 0)
408 val = -val;
409 if (val > pvm->peak_value)
410 pvm->peak_value = val;
411 }
412 } else {
413 for (y = 0; y != samples; y++) {
414 val = -(buffer_local[(y * src_chans) + src] << shift);
415 buffer_data[(y * src_chans) + x] += val;
416 if (val < 0)
417 val = -val;
418 if (val > pvm->peak_value)
419 pvm->peak_value = val;
420 }
421 }
422 } else {
423 if (shift < 0) {
424 shift = -shift;
425 for (y = 0; y != samples; y++) {
426 val = (buffer_local[(y * src_chans) + src] >> shift);
427 buffer_data[(y * src_chans) + x] += val;
428 if (val < 0)
429 val = -val;
430 if (val > pvm->peak_value)
431 pvm->peak_value = val;
432 }
433 } else {
434 for (y = 0; y != samples; y++) {
435 val = (buffer_local[(y * src_chans) + src] << shift);
436 buffer_data[(y * src_chans) + x] += val;
437 if (val < 0)
438 val = -val;
439 if (val > pvm->peak_value)
440 pvm->peak_value = val;
441 }
442 }
443 }
444 }
445
446 /* make a copy of the input data */
447 memcpy(buffer_orig, buffer_data, 8 * samples * src_chans);
448
449 /* (1) Distribute input samples to all clients */
450
451 TAILQ_FOREACH(pvp, &virtual_profile_client_head, entry) {
452
453 if (TAILQ_FIRST(&pvp->head) == NULL)
454 continue;
455
456 /* check if compressor should be applied */
457 voss_compressor(buffer_data, pvp->rx_compressor_gain,
458 &pvp->rx_compressor_param, samples * src_chans,
459 src_chans, (1ULL << (pvp->bits - 1)) - 1ULL);
460
461 TAILQ_FOREACH(pvc, &pvp->head, entry) {
462
463 dst_chans = pvc->channels;
464
465 if (dst_chans > (int)voss_max_channels)
466 continue;
467
468 shift_fmt = pvp->bits - (vclient_sample_bytes(pvc) * 8);
469
470 for (x = 0; x != dst_chans; x++) {
471 src = pvp->rx_src[x];
472 shift_orig = pvp->rx_shift[x] - shift_fmt;
473 shift = shift_orig - VVOLUME_UNIT_SHIFT;
474 volume = pvc->rx_volume;
475
476 if (pvp->rx_mute[x] || src >= src_chans || volume == 0) {
477 for (y = 0; y != (samples * dst_chans); y += dst_chans)
478 buffer_temp[y + x] = 0;
479 continue;
480 }
481
482 virtual_oss_mixer_core(buffer_data + src, buffer_temp + x,
483 &pvc->rx_noise_rem, src_chans, dst_chans, samples,
484 volume, shift, shift_orig, pvp->rx_pol[x], true);
485 }
486
487 format_maximum(buffer_temp, pvp->rx_peak_value,
488 dst_chans, samples, shift_fmt);
489
490 /* check if recording is disabled */
491 if (pvc->rx_enabled == 0 ||
492 (voss_is_recording == 0 && pvc->type != VTYPE_OSS_DAT))
493 continue;
494
495 pvc->rx_timestamp = last_timestamp;
496 pvc->rx_samples += samples * dst_chans;
497
498 /* store data into ring buffer */
499 vclient_write_linear(pvc, &pvc->rx_ring[0],
500 buffer_temp, samples * dst_chans);
501 }
502
503 /* restore buffer, if any */
504 if (pvp->rx_compressor_param.enabled)
505 memcpy(buffer_data, buffer_orig, 8 * samples * src_chans);
506 }
507
508 /* fill main output buffer with silence */
509
510 memset(buffer_temp, 0, sizeof(buffer_temp[0]) *
511 samples * src_chans);
512
513 /* (2) Run audio delay locator */
514
515 if (voss_ad_enabled != 0) {
516 y = (samples * voss_mix_channels);
517 for (x = 0; x != y; x += voss_mix_channels) {
518 buffer_temp[x + voss_ad_output_channel] +=
519 voss_ad_getput_sample(buffer_data
520 [x + voss_ad_input_channel]);
521 }
522 }
523
524 /* (3) Load output samples from all clients */
525
526 TAILQ_FOREACH(pvp, &virtual_profile_client_head, entry) {
527 TAILQ_FOREACH(pvc, &pvp->head, entry) {
528
529 if (pvc->tx_enabled == 0)
530 continue;
531
532 dst_chans = pvc->channels;
533
534 if (dst_chans > (int)voss_max_channels)
535 continue;
536
537 /* update counters regardless of data presence */
538 pvc->tx_timestamp = last_timestamp;
539 pvc->tx_samples += samples * dst_chans;
540
541 /* read data from ring buffer */
542 if (vclient_read_linear(pvc, &pvc->tx_ring[0],
543 buffer_data, samples * dst_chans) == 0)
544 continue;
545
546 shift_fmt = pvp->bits - (vclient_sample_bytes(pvc) * 8);
547
548 format_maximum(buffer_data, pvp->tx_peak_value,
549 dst_chans, samples, shift_fmt);
550
551 for (x = 0; x != pvp->channels; x++) {
552 src = pvp->tx_dst[x];
553 shift_orig = pvp->tx_shift[x] + shift_fmt;
554 shift = shift_orig - VVOLUME_UNIT_SHIFT;
555 volume = pvc->tx_volume;
556
557 if (pvp->tx_mute[x] || src >= src_chans || volume == 0)
558 continue;
559
560 /*
561 * Automagically re-map
562 * channels when the client is
563 * requesting fewer channels
564 * than specified in the
565 * profile. This typically
566 * allows automagic mono to
567 * stereo conversion.
568 */
569 if (__predict_false(x >= dst_chans))
570 x_off = x % dst_chans;
571 else
572 x_off = x;
573
574 virtual_oss_mixer_core(buffer_data + x_off, buffer_temp + src,
575 &pvc->tx_noise_rem, dst_chans, src_chans, samples,
576 volume, shift, shift_orig, pvp->tx_pol[x], false);
577 }
578 }
579 }
580
581 /* (4) Load output samples from all loopbacks */
582
583 TAILQ_FOREACH(pvp, &virtual_profile_loopback_head, entry) {
584 TAILQ_FOREACH(pvc, &pvp->head, entry) {
585
586 if (pvc->tx_enabled == 0)
587 continue;
588
589 dst_chans = pvc->channels;
590
591 if (dst_chans > (int)voss_max_channels)
592 continue;
593
594 /* read data from ring buffer */
595 if (vclient_read_linear(pvc, &pvc->tx_ring[0],
596 buffer_data, samples * dst_chans) == 0)
597 continue;
598
599 pvc->tx_timestamp = last_timestamp;
600 pvc->tx_samples += samples * dst_chans;
601
602 shift_fmt = pvp->bits - (vclient_sample_bytes(pvc) * 8);
603
604 format_maximum(buffer_data, pvp->tx_peak_value,
605 dst_chans, samples, shift_fmt);
606
607 for (x = 0; x != pvp->channels; x++) {
608 src = pvp->tx_dst[x];
609 shift_orig = pvp->tx_shift[x] + shift_fmt;
610 shift = shift_orig - VVOLUME_UNIT_SHIFT;
611 volume = pvc->tx_volume;
612
613 if (pvp->tx_mute[x] || src >= src_chans || volume == 0)
614 continue;
615
616 /*
617 * Automagically re-map
618 * channels when the client is
619 * requesting fewer channels
620 * than specified in the
621 * profile. This typically
622 * allows automagic mono to
623 * stereo conversion.
624 */
625 if (__predict_false(x >= dst_chans))
626 x_off = x % dst_chans;
627 else
628 x_off = x;
629
630 virtual_oss_mixer_core(buffer_data + x_off, buffer_temp + src,
631 &pvc->tx_noise_rem, dst_chans, src_chans, samples,
632 volume, shift, shift_orig, pvp->tx_pol[x], false);
633 }
634 }
635 }
636
637 /* (5) Check for input monitoring */
638
639 TAILQ_FOREACH(pvm, &virtual_monitor_input, entry) {
640
641 int64_t val;
642
643 if (pvm->mute != 0 || pvm->src_chan >= src_chans ||
644 pvm->dst_chan >= src_chans)
645 continue;
646
647 src = pvm->src_chan;
648 shift = pvm->shift;
649 x = pvm->dst_chan;
650
651 if (pvm->pol) {
652 if (shift < 0) {
653 shift = -shift;
654 for (y = 0; y != samples; y++) {
655 val = -(buffer_monitor[(y * src_chans) + src] >> shift);
656 buffer_temp[(y * src_chans) + x] += val;
657 if (val < 0)
658 val = -val;
659 if (val > pvm->peak_value)
660 pvm->peak_value = val;
661 }
662 } else {
663 for (y = 0; y != samples; y++) {
664 val = -(buffer_monitor[(y * src_chans) + src] << shift);
665 buffer_temp[(y * src_chans) + x] += val;
666 if (val < 0)
667 val = -val;
668 if (val > pvm->peak_value)
669 pvm->peak_value = val;
670 }
671 }
672 } else {
673 if (shift < 0) {
674 shift = -shift;
675 for (y = 0; y != samples; y++) {
676 val = (buffer_monitor[(y * src_chans) + src] >> shift);
677 buffer_temp[(y * src_chans) + x] += val;
678 if (val < 0)
679 val = -val;
680 if (val > pvm->peak_value)
681 pvm->peak_value = val;
682 }
683 } else {
684 for (y = 0; y != samples; y++) {
685 val = (buffer_monitor[(y * src_chans) + src] << shift);
686 buffer_temp[(y * src_chans) + x] += val;
687 if (val < 0)
688 val = -val;
689 if (val > pvm->peak_value)
690 pvm->peak_value = val;
691 }
692 }
693 }
694 }
695
696 if (TAILQ_FIRST(&virtual_monitor_output) != NULL) {
697 memcpy(buffer_monitor, buffer_temp,
698 8 * samples * src_chans);
699 }
700
701 /* (6) Check for output monitoring */
702
703 TAILQ_FOREACH(pvm, &virtual_monitor_output, entry) {
704
705 int64_t val;
706
707 if (pvm->mute != 0 || pvm->src_chan >= src_chans ||
708 pvm->dst_chan >= src_chans)
709 continue;
710
711 src = pvm->src_chan;
712 shift = pvm->shift;
713 x = pvm->dst_chan;
714
715 if (pvm->pol) {
716 if (shift < 0) {
717 shift = -shift;
718 for (y = 0; y != samples; y++) {
719 val = -(buffer_monitor[(y * src_chans) + src] >> shift);
720 buffer_temp[(y * src_chans) + x] += val;
721 if (val < 0)
722 val = -val;
723 if (val > pvm->peak_value)
724 pvm->peak_value = val;
725 }
726 } else {
727 for (y = 0; y != samples; y++) {
728 val = -(buffer_monitor[(y * src_chans) + src] << shift);
729 buffer_temp[(y * src_chans) + x] += val;
730 if (val < 0)
731 val = -val;
732 if (val > pvm->peak_value)
733 pvm->peak_value = val;
734 }
735 }
736 } else {
737 if (shift < 0) {
738 shift = -shift;
739 for (y = 0; y != samples; y++) {
740 val = (buffer_monitor[(y * src_chans) + src] >> shift);
741 buffer_temp[(y * src_chans) + x] += val;
742 if (val < 0)
743 val = -val;
744 if (val > pvm->peak_value)
745 pvm->peak_value = val;
746 }
747 } else {
748 for (y = 0; y != samples; y++) {
749 val = (buffer_monitor[(y * src_chans) + src] << shift);
750 buffer_temp[(y * src_chans) + x] += val;
751 if (val < 0)
752 val = -val;
753 if (val > pvm->peak_value)
754 pvm->peak_value = val;
755 }
756 }
757 }
758 }
759
760 /* make a copy of the output data */
761 memcpy(buffer_data, buffer_temp, 8 * samples * src_chans);
762
763 /* make a copy for local monitoring, if any */
764 if (TAILQ_FIRST(&virtual_monitor_local) != NULL) {
765 const int end = src_chans * (voss_dsp_samples - samples);
766 const int offs = src_chans * samples;
767
768 assert(end >= 0);
769
770 /* shift down samples */
771 for (int xx = 0; xx != end; xx++)
772 buffer_local[xx] = buffer_local[xx + offs];
773 /* copy in new ones */
774 memcpy(buffer_local + end, buffer_temp, 8 * samples * src_chans);
775 }
776
777 /* (7) Check for output recording */
778
779 TAILQ_FOREACH(pvp, &virtual_profile_loopback_head, entry) {
780
781 if (TAILQ_FIRST(&pvp->head) == NULL)
782 continue;
783
784 /* check if compressor should be applied */
785 voss_compressor(buffer_temp, pvp->rx_compressor_gain,
786 &pvp->rx_compressor_param, samples,
787 samples * src_chans, (1ULL << (pvp->bits - 1)) - 1ULL);
788
789 TAILQ_FOREACH(pvc, &pvp->head, entry) {
790
791 dst_chans = pvc->channels;
792
793 if (dst_chans > (int)voss_max_channels)
794 continue;
795
796 shift_fmt = pvp->bits - (vclient_sample_bytes(pvc) * 8);
797
798 for (x = 0; x != dst_chans; x++) {
799 src = pvp->rx_src[x];
800 shift_orig = pvp->rx_shift[x] - shift_fmt;
801 shift = shift_orig - VVOLUME_UNIT_SHIFT;
802 volume = pvc->rx_volume;
803
804 if (pvp->rx_mute[x] || src >= src_chans || volume == 0) {
805 for (y = 0; y != (samples * dst_chans); y += dst_chans)
806 buffer_monitor[y + x] = 0;
807 continue;
808 }
809
810 virtual_oss_mixer_core(buffer_temp + src, buffer_monitor + x,
811 &pvc->rx_noise_rem, src_chans, dst_chans, samples,
812 volume, shift, shift_orig, pvp->rx_pol[x], true);
813 }
814
815 format_maximum(buffer_monitor, pvp->rx_peak_value,
816 dst_chans, samples, shift_fmt);
817
818 /* check if recording is disabled */
819 if (pvc->rx_enabled == 0 ||
820 (voss_is_recording == 0 && pvc->type != VTYPE_OSS_DAT))
821 continue;
822
823 pvc->rx_timestamp = last_timestamp;
824 pvc->rx_samples += samples * dst_chans;
825
826 /* store data into ring buffer */
827 vclient_write_linear(pvc, &pvc->rx_ring[0],
828 buffer_monitor, samples * dst_chans);
829 }
830
831 /* restore buffer, if any */
832 if (pvp->rx_compressor_param.enabled)
833 memcpy(buffer_temp, buffer_data, 8 * samples * src_chans);
834 }
835
836 atomic_wakeup();
837
838 format_remix(buffer_temp, voss_mix_channels, tx_chn, samples);
839
840 /* Compute master output peak values */
841
842 format_maximum(buffer_temp, voss_output_peak,
843 tx_chn, samples, 0);
844
845 /* Apply compressor, if any */
846
847 voss_compressor(buffer_temp, voss_output_compressor_gain,
848 &voss_output_compressor_param, samples * tx_chn,
849 tx_chn, format_max(tx_fmt));
850
851 /* Recompute buffer DSP transmit size according to received number of samples */
852
853 buffer_dsp_tx_size = samples * tx_chn * (voss_dsp_bits / 8);
854
855 /* Export and transmit resulting audio */
856
857 format_export(tx_fmt, buffer_temp, buffer_dsp,
858 buffer_dsp_tx_size);
859
860 atomic_unlock();
861
862 /* Get output delay in bytes */
863 tx_be->delay(tx_be, &blocks);
864
865 /*
866 * Simple fix for jitter: Repeat data when too
867 * little. Skip data when too much. This
868 * should not happen during normal operation.
869 */
870 if (blocks == 0) {
871 blocks = 2; /* buffer is empty */
872 voss_jitter_up++;
873 } else if (blocks >= (3 * buffer_dsp_tx_size_ref)) {
874 blocks = 0; /* too much data */
875 voss_jitter_down++;
876 } else {
877 blocks = 1; /* normal */
878 }
879
880 len = 0;
881 while (blocks--) {
882 off = 0;
883 while (off < (int)buffer_dsp_tx_size) {
884 len = tx_be->transfer(tx_be, buffer_dsp + off,
885 buffer_dsp_tx_size - off);
886 if (len <= 0)
887 break;
888 off += len;
889 }
890 if (len <= 0)
891 break;
892 }
893
894 /* check for error only */
895 if (len < 0) {
896 need_delay = true;
897 break;
898 }
899 }
900 }
901
902 free(buffer_dsp);
903 free(buffer_temp);
904 free(buffer_monitor);
905 free(buffer_local);
906 free(buffer_data);
907 free(buffer_orig);
908
909 return (NULL);
910 }
911