UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
audio.cpp
Go to the documentation of this file.
1/*
2 * FILE: audio/audio.cpp
3 * AUTHORS: Martin Benes <martinbenesh@gmail.com>
4 * Lukas Hejtmanek <xhejtman@ics.muni.cz>
5 * Petr Holub <hopet@ics.muni.cz>
6 * Milos Liska <xliska@fi.muni.cz>
7 * Jiri Matela <matela@ics.muni.cz>
8 * Dalibor Matura <255899@mail.muni.cz>
9 * Martin Pulec <martin.pulec@cesnet.cz>
10 * Ian Wesley-Smith <iwsmith@cct.lsu.edu>
11 *
12 * Copyright (c) 2005-2024 CESNET z.s.p.o.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, is permitted provided that the following conditions
16 * are met:
17 *
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 *
25 * 3. All advertising materials mentioning features or use of this software
26 * must display the following acknowledgement:
27 *
28 * This product includes software developed by CESNET z.s.p.o.
29 *
30 * 4. Neither the name of CESNET nor the names of its contributors may be used
31 * to endorse or promote products derived from this software without specific
32 * prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
35 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
36 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
37 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
38 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
39 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
41 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
43 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
44 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
45 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 *
47 *
48 */
49
50#include <array>
51#include <cinttypes>
52#include <cstdio>
53#include <cstdlib>
54#include <cstring>
55#include <iomanip>
56#include <memory>
57#include <sstream>
58#include <string>
59
60#include "../export.h" // not audio/export.h
61#include "audio/audio.h"
62#include "audio/audio_capture.h"
63#include "audio/audio_filter.h"
65#include "audio/capture/sdi.h"
66#include "audio/codec.h"
67#include "audio/echo.h"
69#include "audio/jack.h"
70#include "audio/playback/sdi.h"
71#include "audio/resampler.hpp"
72#include "audio/utils.h"
73#include "debug.h"
74#include "host.h"
75#include "module.h"
76#include "pdb.h"
77#include "rtp/audio_decoders.h"
78#include "rtp/fec.h"
79#include "rtp/pbuf.h"
80#include "rtp/rtp.h"
81#include "rtp/rtp_callback.h"
82#include "transmit.h"
83#include "tv.h"
84#include "types.h"
85#include "ug_runtime_error.hpp"
86#include "utils/color_out.h"
87#include "utils/net.h"
88#include "utils/sdp.h"
90#include "utils/thread.h"
91#include "utils/worker.h"
92#include "video_rxtx.hpp" // for video_rxtx
93
94using std::array;
95using std::fixed;
96using std::ostringstream;
97using std::setprecision;
98using std::string;
99using std::to_string;
100using std::unique_ptr;
101using namespace std::string_literals;
102
108
109#define DEFAULT_AUDIO_RECV_BUF_SIZE (256 * 1024)
110#define MOD_NAME "[audio] "
111
113 char *addr = nullptr;
114 int recv_port = 0;
115 int send_port = 0;
116 struct pdb *participants = 0;
118 const char *mcast_if;
119 int ttl = -1;
120};
121
133 delete fec_state;
134 }
135
136 bool should_exit = false;
137
141
144
146
148
150 struct rtp *audio_network_device = nullptr;
151 struct pdb *audio_participants = nullptr;
152 std::string proto_cfg; // audio network protocol options
153 void *jack_connection = nullptr;
156
158 time_ns_t t0; // for statistics
159
161
162 struct tx *tx_session = nullptr;
163 fec *fec_state = nullptr;
164
169
170 char *audio_channel_map = nullptr;
171 const char *audio_scale = nullptr;
173 struct exporter *exporter = nullptr;
174 int resample_to = 0;
175
177
179
180 double volume = 1.0; // receiver volume scale
181 bool muted_receiver = false;
182 bool muted_sender = false;
183
185
186 struct video_rxtx *vrxtx = nullptr;
187};
188
194typedef void (*audio_device_help_t)(void);
195
196static void *audio_sender_thread(void *arg);
197static void *audio_receiver_thread(void *arg);
199static struct response *audio_receiver_process_message(struct state_audio *s, struct msg_receiver *msg);
200static struct response *audio_sender_process_message(struct state_audio *s, struct msg_sender *msg);
201
202static void audio_channel_map_usage(void);
203static void audio_scale_usage(void);
204
205static void audio_channel_map_usage(void)
206{
207 printf("\t--audio-channel-map <mapping> mapping of input audio channels\n");
208 printf("\t to output audio channels comma-separated\n");
209 printf("\t list of channel mapping (receiver only)\n");
210 printf("\t eg. 0:0,1:0 - mixes first 2 channels\n");
211 printf("\t 0:0 - play only first channel\n");
212 printf("\t 0:0,:1 - sets second channel to\n");
213 printf("\t a silence, first one is\n");
214 printf("\t left as is\n");
215 printf("\t 0:0,0:1 - splits mono into\n");
216 printf("\t 2 channels\n");
217}
218
219static void audio_scale_usage(void)
220{
221 col() << "Usage:\n";
222 col() << TBOLD(TRED("\t--audio-scale [<factor>|<method>]\n"));
223 col() << "\t Floating point number that tells a static scaling factor for all\n";
224 col() << "\t output channels. Scaling method can be one from these:\n";
225 col() << TBOLD("\t 0.0-1.0") << " - factor to scale to (usually 0-1 but can be more)\n";
226 col() << TBOLD("\t mixauto") << " - automatically adjust volume if using channel\n";
227 col() << "\t mixing/remapping (default)\n";
228 col() << TBOLD("\t auto") << " - automatically adjust volume\n";
229 col() << TBOLD("\t none") << " - no scaling will be performed\n";
230}
231
232static void should_exit_audio(void *state) {
233 auto *s = (struct state_audio *) state;
234 s->should_exit = true;
235}
236
237void
239 const enum module_class *path,
240 const char *address)
241{
242 array<char, 1024> pathV{};
243
244 append_message_path(pathV.data(), pathV.size(), path);
245
246 // CHANGE DST ADDRESS
247 auto *msgV2 = reinterpret_cast<struct msg_sender *>(
248 new_message(sizeof(struct msg_sender)));
249 strncpy(static_cast<char *>(msgV2->receiver), address,
250 sizeof(msgV2->receiver) - 1);
251 msgV2->type = SENDER_MSG_CHANGE_RECEIVER;
252
253 auto *resp = send_message(root, pathV.data(),
254 reinterpret_cast<struct message *>(msgV2));
255 if (response_get_status(resp) == RESPONSE_OK) {
257 << "[SDP] Changing address to " << address << "\n";
258 } else {
260 << "[SDP] Unable to change address to " << address << " ("
261 << response_get_status(resp) << ")\n";
262 }
263 free_response(resp);
264}
265
272int audio_init(struct state_audio **ret,
273 const struct audio_options *opt,
274 const struct common_opts *common)
275{
276 char *tmp, *unused = NULL;
277 char *addr;
278 int retval = -1;
279
280 assert(opt->send_cfg != NULL);
281 assert(opt->recv_cfg != NULL);
282
283 if (opt->channel_map &&
284 strcmp("help", opt->channel_map) == 0) {
286 return 1;
287 }
288
289 if (opt->scale &&
290 strcmp("help", opt->scale) == 0) {
292 return 1;
293 }
294
295 struct state_audio *s =
296 new state_audio(common->parent, common->start_time);
297
299 s->audio_scale = opt->scale;
300
303
304 s->exporter = common->exporter;
305
306 if (opt->echo_cancellation) {
307#ifdef HAVE_SPEEXDSP
309 fprintf(stderr, "Echo cancellation is currently experimental "
310 "and may not work as expected.");
311 goto error;
312#else
313 fprintf(stderr, "Speex not compiled in. Could not enable echo cancellation.\n");
314 delete s;
315 goto error;
316#endif /* HAVE_SPEEXDSP */
317 } else {
318 s->echo_state = NULL;
319 }
320
321 if(opt->filter_cfg){
322 std::string_view cfg_sv = opt->filter_cfg;;
323 std::string_view item;
324 while(item = tokenize(cfg_sv, '#'), !item.empty()) {
325 if(!s->filter_chain.emplace_new(item)) {
326 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Failed to init audio filter\n");
327 goto error;
328 }
329 }
330 }
331
332 s->opts = *common;
333
334 assert(opt->host != nullptr);
335 tmp = strdup(opt->host);
337 addr = strtok_r(tmp, ",", &unused);
338 assert(addr != nullptr);
339
340 s->audio_network_parameters.addr = strdup(addr);
341 s->audio_network_parameters.recv_port = opt->recv_port;
342 s->audio_network_parameters.send_port = opt->send_port;
343 s->audio_network_parameters.participants = s->audio_participants;
344 s->audio_network_parameters.force_ip_version = common->force_ip_version;
345 s->audio_network_parameters.mcast_if =
346 strlen(s->opts.mcast_if) > 0 ? s->opts.mcast_if : nullptr;
347 s->audio_network_parameters.ttl = s->opts.ttl;
348 free(tmp);
349
350 if (strcmp(opt->send_cfg, "none") != 0) {
351 const char *cfg = "";
352 char *device = strdup(opt->send_cfg);
353 if(strchr(device, ':')) {
354 char *delim = strchr(device, ':');
355 *delim = '\0';
356 cfg = delim + 1;
357 }
358
359 int ret = audio_capture_init(s->audio_sender_module.get(), device, cfg, &s->audio_capture_device);
360 free(device);
361 if (ret != 0) {
362 retval = ret;
363 goto error;
364 }
365 s->tx_session = tx_init(
366 s->audio_sender_module.get(), common->mtu, TX_MEDIA_AUDIO,
367 opt->fec_cfg, common->encryption, 0 /* unused */);
368 if(!s->tx_session) {
369 fprintf(stderr, "Unable to initialize audio transmit.\n");
370 goto error;
371 }
372
374 } else {
376 }
377
378 if (strcmp(opt->recv_cfg, "none") != 0) {
379 const char *cfg = "";
380 char *device = strdup(opt->recv_cfg);
381 if(strchr(device, ':')) {
382 char *delim = strchr(device, ':');
383 *delim = '\0';
384 cfg = delim + 1;
385 }
386
387 int ret = audio_playback_init(device, cfg, &s->audio_playback_device);
388 free(device);
389 if (ret != 0) {
390 retval = ret;
391 goto error;
392 }
394 } else {
396 }
397
398 if (s->audio_tx_mode != 0) {
401 == nullptr) {
402 LOG(LOG_LEVEL_ERROR) << MOD_NAME << "Unable to open audio network\n";
403 goto error;
404 }
405 }
406 if ((s->audio_tx_mode & MODE_RECEIVER) != 0U) {
407 size_t len = sizeof(struct rtp *);
411 }
412
413 if ((s->audio_tx_mode & MODE_SENDER) != 0U || "help"s == opt->codec_cfg) {
414 if ((s->audio_encoder = audio_codec_init_cfg(opt->codec_cfg, AUDIO_CODER)) == nullptr) {
415 goto error;
416 }
417 }
418
419 s->proto_cfg = opt->proto_cfg;
420
421 if (strcasecmp(opt->proto, "ultragrid_rtp") == 0) {
422 s->sender = NET_NATIVE;
423 s->receiver = NET_NATIVE;
424 } else if (strcasecmp(opt->proto, "rtsp") == 0 || strcasecmp(opt->proto, "sdp") == 0) {
426 s->sender = NET_STANDARD;
427 if (strcasecmp(opt->proto, "sdp") == 0) {
428 if (sdp_set_options(opt->proto_cfg) != 0) {
429 goto error;
430 }
431 }
432 } else if (strcasecmp(opt->proto, "JACK") == 0) {
433#ifndef HAVE_JACK_TRANS
434 fprintf(stderr, "[Audio] JACK transport requested, "
435 "but JACK support isn't compiled.\n");
436 goto error;
437#else
438 s->sender = NET_JACK;
439 s->receiver = NET_JACK;
440#endif
441 } else if (s->audio_tx_mode != 0) {
442 log_msg(LOG_LEVEL_ERROR, "Unknow audio protocol: %s\n", opt->proto);
443 goto error;
444 }
445
447
448 *ret = s;
449 return 0;
450
451error:
452 if(s->tx_session)
454 if(s->audio_participants) {
456 }
457
459 delete s;
460 return retval;
461}
462
463void audio_start(struct state_audio *s) {
464#ifdef HAVE_JACK_TRANS
465 if (s->sender == NET_JACK || s->receiver == NET_JACK) {
466 s->jack_connection = jack_start(s->proto_cfg.c_str());
467 if (s->jack_connection) {
469 s->sender = NET_NATIVE;
470 }
472 s->receiver = NET_NATIVE;
473 }
474 } else {
475 log_msg(LOG_LEVEL_FATAL, "JACK transport initialization failed!\n");
477 }
478 }
479#endif
480
481 if (s->audio_tx_mode & MODE_SENDER) {
482 if (pthread_create
483 (&s->audio_sender_thread_id, NULL, audio_sender_thread, (void *)s) != 0) {
484 log_msg(LOG_LEVEL_FATAL, "Error creating audio thread. Quitting\n");
486 } else {
487 s->audio_sender_thread_started = true;
488 }
489 }
490
491 if (s->audio_tx_mode & MODE_RECEIVER) {
492 if (pthread_create
493 (&s->audio_receiver_thread_id, NULL, audio_receiver_thread, (void *)s) != 0) {
494 log_msg(LOG_LEVEL_FATAL, "Error creating audio thread. Quitting\n");
496 } else {
497 s->audio_receiver_thread_started = true;
498 }
499 }
500}
501
502void audio_join(struct state_audio *s) {
503 if (!s) {
504 return;
505 }
507 pthread_join(s->audio_receiver_thread_id, NULL);
509 pthread_join(s->audio_sender_thread_id, NULL);
510}
511
512void audio_done(struct state_audio *s)
513{
514 if (!s) {
515 return;
516 }
519 // process remaining messages
520 struct message *msg;
521 while ((msg = check_message(s->audio_receiver_module.get()))) {
522 struct response *r = audio_receiver_process_message(s, (struct msg_receiver *) msg);
523 free_message(msg, r);
524 }
525 while ((msg = check_message(s->audio_sender_module.get()))) {
526 struct response *r = audio_sender_process_message(s, (struct msg_sender *) msg);
527 free_message(msg, r);
528 }
529
533 if(s->audio_participants) {
535 }
536
537 free(s->audio_network_parameters.addr);
538
540
543
544 delete s;
545}
546
548{
549 struct rtp *r;
550 double rtcp_bw = 1024 * 512; // FIXME: something about 5% for rtcp is said in rfc
551
552 r = rtp_init_if(params->addr, params->mcast_if, params->recv_port,
553 params->send_port, params->ttl, rtcp_bw,
555 (uint8_t *) params->participants,
556 params->force_ip_version, false);
557 if (r != NULL) {
558 pdb_add(params->participants, rtp_my_ssrc(r));
563 PACKAGE_STRING, strlen(PACKAGE_VERSION));
564 if (strcmp(params->addr, IN6_BLACKHOLE_SERVER_MODE_STR) == 0) {
566 }
568 }
569
570 return r;
571}
572
577
579{
580 switch (msg->type) {
582 assert(s->audio_tx_mode == MODE_RECEIVER); // receiver only
583 struct rtp *old_audio_network_device = s->audio_network_device;
584 int old_rx_port = s->audio_network_parameters.recv_port;
585 s->audio_network_parameters.recv_port = msg->new_rx_port;
588 if (s->audio_network_device == nullptr) {
589 s->audio_network_parameters.recv_port = old_rx_port;
590 s->audio_network_device = old_audio_network_device;
591 string err = string("Changing audio RX port to ") +
592 to_string(msg->new_rx_port) + " failed!";
593 LOG(LOG_LEVEL_ERROR) << err << "\n";
594 return new_response(RESPONSE_INT_SERV_ERR, err.c_str());
595 }
596 rtp_done(old_audio_network_device);
597 LOG(LOG_LEVEL_INFO) << "Successfully changed audio "
598 "RX port to "
599 << msg->new_rx_port << ".\n";
600 break;
601 }
603 double ret = s->muted_receiver ? 0.0 : s->volume;
604 char volume_str[128] = "";
605 snprintf(volume_str, sizeof volume_str, "%lf,%d", ret,
606 (int) s->muted_receiver);
607 return new_response(RESPONSE_OK, volume_str);
608 break;
609 }
615 if (msg->type == RECEIVER_MSG_INCREASE_VOLUME) {
616 s->volume *= 1.1;
617 } else if (msg->type == RECEIVER_MSG_DECREASE_VOLUME) {
618 s->volume /= 1.1;
619 } else {
620 s->muted_receiver =
622 ? !s->muted_receiver
623 : msg->type == RECEIVER_MSG_MUTE;
624 }
625 double new_volume = s->muted_receiver ? 0.0 : s->volume;
626 double db = 20.0 * log10(new_volume);
627 if (msg->type == RECEIVER_MSG_MUTE_TOGGLE) {
629 << "Audio receiver "
630 << (s->muted_receiver ? "" : "un") << "muted.\n";
631 } else {
633 "Playback volume: %.2f%% (%+.2f dB)\n",
634 new_volume * 100.0, db);
635 }
636 pdb_iter_t it{};
637 struct pdb_e *cp = pdb_iter_init(s->audio_participants, &it);
638 while (cp != nullptr) {
639 auto *dec_state =
640 (struct audio_decoder *) cp->decoder_state;
641 if (dec_state != nullptr) {
643 dec_state->pbuf_data.decoder, new_volume);
644 }
645 cp = pdb_iter_next(&it);
646 }
647 pdb_iter_done(&it);
648 break;
649 }
651 abort();
652 }
653
654 return new_response(RESPONSE_OK, nullptr);
655}
656
658 auto *dec_state = (struct audio_decoder *) calloc(1, sizeof(struct audio_decoder));
659 assert(dec_state != NULL);
660 dec_state->enabled = true;
661 dec_state->pbuf_data.decoder =
663 s->audio_channel_map, s->audio_scale, s->opts.encryption,
666 if (!dec_state->pbuf_data.decoder) {
667 free(dec_state);
668 return NULL;
669 }
670 audio_decoder_set_volume(dec_state->pbuf_data.decoder, s->muted_receiver ? 0.0 : s->volume);
671 return dec_state;
672}
673
675{
676 struct audio_decoder *s = (struct audio_decoder *) state;
677
678 free(s->pbuf_data.buffer.data);
680
681 free(s);
682}
683
684static void audio_update_recv_buf(struct state_audio *s, size_t curr_frame_len)
685{
686 size_t new_size = curr_frame_len * 2;
687
688 if (new_size > s->recv_buf_size) {
689 s->recv_buf_size = new_size;
690 LOG(LOG_LEVEL_DEBUG) << "[Audio receiver] Recv buffer adjusted to " << new_size << "\n";
692 }
693}
694
695static void *audio_receiver_thread(void *arg)
696{
697 set_thread_name(__func__);
698 struct state_audio *s = (struct state_audio *) arg;
699 // rtp variables
700 struct pdb_e *cp;
701 struct audio_desc device_desc{};
702 bool playback_supports_multiple_streams;
703
704 struct pbuf_audio_data *current_pbuf = NULL;
705
706#ifdef HAVE_JACK_TRANS
707 struct pbuf_audio_data jack_pbuf{};
708 current_pbuf = &jack_pbuf;
709#endif
710
711 size_t len = sizeof playback_supports_multiple_streams;
713 &playback_supports_multiple_streams, &len)) {
714 playback_supports_multiple_streams = false;
715 }
716
717 time_ns_t last_not_timeout = 0;
718 printf("Audio receiving started.\n");
719 while (!s->should_exit) {
720 struct message *msg;
721 while((msg= check_message(s->audio_receiver_module.get()))) {
722 struct response *r = audio_receiver_process_message(s, (struct msg_receiver *) msg);
723 free_message(msg, r);
724 }
725
726 bool decoded = false;
727
728 if (s->receiver == NET_NATIVE || s->receiver == NET_STANDARD) {
729 time_ns_t curr_time = get_time_in_ns();
730 uint32_t ts = (curr_time - s->start_time) / 100'000 * 9; // at 90000 Hz
731 rtp_update(s->audio_network_device, curr_time);
732 rtp_send_ctrl(s->audio_network_device, ts, 0, curr_time);
733 struct timeval timeout;
734 timeout.tv_sec = 0;
735 // timeout.tv_usec = 999999 / 59.94; // audio goes almost always at the same rate
736 // as video frames
737 if ((curr_time - last_not_timeout) > NS_IN_SEC) {
738 timeout.tv_usec = 100000;
739 } else {
740 timeout.tv_usec = 1000; // this stuff really smells !!!
741 }
742 bool ret = rtp_recv_r(s->audio_network_device, &timeout, ts);
743 if (ret) {
744 last_not_timeout = curr_time;
745 }
746 pdb_iter_t it;
747 cp = pdb_iter_init(s->audio_participants, &it);
748
749 while (cp != NULL) {
750 if (cp->decoder_state == NULL &&
751 !pbuf_is_empty(cp->playout_buffer)) { // the second check is need ed because we want to assign display to participant that really sends data
752 // disable all previous sources
753 if (!playback_supports_multiple_streams) {
754 pdb_iter_t it;
755 struct pdb_e *cp = pdb_iter_init(s->audio_participants, &it);
756 while (cp != NULL) {
757 if(cp->decoder_state) {
758 ((struct audio_decoder *) cp->decoder_state)->enabled = false;
759 }
760 cp = pdb_iter_next(&it);
761 }
762 pdb_iter_done(&it);
763 }
764
765 if (get_commandline_param("low-latency-audio")) {
766 pbuf_set_playout_delay(cp->playout_buffer, strcmp(get_commandline_param("low-latency-audio"), "ultra") == 0 ? 0.001 :0.005);
767 }
769 if (!cp->decoder_state) {
770 exit_uv(1);
771 break;
772 }
774 }
775
776 struct audio_decoder *dec_state = (struct audio_decoder *) cp->decoder_state;
777 if (dec_state && dec_state->enabled) {
778 dec_state->pbuf_data.buffer.data_len = 0;
779 dec_state->pbuf_data.buffer.timestamp = -1;
780 // We iterate in loop since there can be more than one frmae present in
781 // the playout buffer and it would be discarded by following pbuf_remove()
782 // call.
784
785 current_pbuf = &dec_state->pbuf_data;
786 decoded = true;
787 }
788 }
789
790 pbuf_remove(cp->playout_buffer, curr_time);
791 cp = pdb_iter_next(&it);
792
793 if (decoded && !playback_supports_multiple_streams)
794 break;
795 }
796 pdb_iter_done(&it);
797 }else { /* NET_JACK */
798#ifdef HAVE_JACK_TRANS
799 decoded = jack_receive(s->jack_connection, &jack_pbuf);
800#endif
801 }
802
803 if (decoded) {
804 bool failed = false;
805
806 struct audio_desc curr_desc;
807 curr_desc = audio_desc_from_frame(&current_pbuf->buffer);
808
809 if(!audio_desc_eq(device_desc, curr_desc)) {
810 int log_l;
811 string msg;
813 curr_desc.ch_count,
814 curr_desc.sample_rate) != TRUE) {
815 log_l = LOG_LEVEL_ERROR;
816 msg = "Audio reconfiguration failed";
817 failed = true;
818 }
819 else {
820 log_l = LOG_LEVEL_INFO;
821 msg = "Audio reconfiguration succeeded";
822 device_desc = curr_desc;
824 }
825 LOG(log_l) << msg << " (" << curr_desc << ")" << (log_l < LOG_LEVEL_WARNING ? "!" : ".") << "\n";
827 }
828
829 if (failed) {
830 continue;
831 }
832 audio_update_recv_buf(s, current_pbuf->frame_size);
833
834 if(s->echo_state) {
835#ifdef HAVE_SPEEXDSP
836 echo_play(s->echo_state, &current_pbuf->buffer);
837#endif
838 }
839
840 if (!playback_supports_multiple_streams) {
842 } else {
843 pdb_iter_t it;
844 cp = pdb_iter_init(s->audio_participants, &it);
845 while (cp != NULL) {
846 struct audio_decoder *dec_state = (struct audio_decoder *) cp->decoder_state;
847 if (dec_state && dec_state->enabled && dec_state->pbuf_data.buffer.data_len > 0) {
848 struct audio_frame *f = &dec_state->pbuf_data.buffer;
849 f->network_source = &dec_state->pbuf_data.source;
851 }
852 cp = pdb_iter_next(&it);
853 }
854 pdb_iter_done(&it);
855 }
856 }
857 }
858
859#ifdef HAVE_JACK_TRANS
860 free(jack_pbuf.buffer.data);
861#endif
862
863 return NULL;
864}
865
867{
868 switch (msg->type) {
870 auto *old_fec_state = s->fec_state;
871 s->fec_state = nullptr;
872 if (strcmp(msg->fec_cfg, "flush") == 0) {
873 delete old_fec_state;
874 break;
875 }
876 s->fec_state = fec::create_from_config(msg->fec_cfg, true);
877 if (s->fec_state == nullptr) {
878 s->fec_state = old_fec_state;
879 if (strstr(msg->fec_cfg, "help") !=
880 nullptr) { // -f LDGM:help or so + init
881 exit_uv(0);
882 } else {
884 << "[control] Unable to initalize FEC!\n";
885 }
886 return new_response(RESPONSE_INT_SERV_ERR, nullptr);
887 }
888 delete old_fec_state;
890 "[control] Fec changed successfully\n");
891 } break;
893 assert(s->audio_tx_mode == MODE_SENDER);
894 auto *old_device = s->audio_network_device;
895 auto *old_receiver = s->audio_network_parameters.addr;
896
897 s->audio_network_parameters.addr = strdup(msg->receiver);
900 if (s->audio_network_device == nullptr) {
901 s->audio_network_device = old_device;
902 free(s->audio_network_parameters.addr);
903 s->audio_network_parameters.addr = old_receiver;
905 "Changing receiver failed!");
906 }
907 free(old_receiver);
908 rtp_done(old_device);
909 MSG(NOTICE, "Changed receiver to %s\n", msg->receiver);
910 break;
911 }
913 assert(s->audio_tx_mode == MODE_SENDER);
914 auto *old_device = s->audio_network_device;
915 auto old_port = s->audio_network_parameters.send_port;
916
917 s->audio_network_parameters.send_port = msg->tx_port;
918 if (msg->rx_port != 0) {
919 s->audio_network_parameters.recv_port = msg->rx_port;
920 }
923 if (s->audio_network_device == nullptr) {
924 s->audio_network_device = old_device;
925 s->audio_network_parameters.send_port = old_port;
927 "Changing receiver failed!");
928 }
929 rtp_done(old_device);
930 MSG(NOTICE, "Changed TX port to %d\n", msg->tx_port);
931 break;
932 }
934 char status[128] = "";
935 snprintf(status, sizeof status, "%d", (int) s->muted_sender);
937 break;
938 }
939 case SENDER_MSG_MUTE:
943 ? !s->muted_sender
944 : msg->type == SENDER_MSG_MUTE;
945 log_msg(LOG_LEVEL_NOTICE, "Audio sender %smuted.\n",
946 s->muted_sender ? "" : "un");
947 break;
949 return new_response(RESPONSE_BAD_REQUEST, nullptr);
951 assert(s->audio_tx_mode == MODE_SENDER);
952 const uint32_t old_ssrc = rtp_my_ssrc(s->audio_network_device);
953 auto *old_devices = s->audio_network_device;
956 if (s->audio_network_device == nullptr) {
957 s->audio_network_device = old_devices;
959 "[control] Audio: Unable to change SSRC!\n");
960 return new_response(RESPONSE_INT_SERV_ERR, nullptr);
961 }
962
963 rtp_done(old_devices);
965 "[control] Audio: changed SSRC from 0x%08" PRIx32 " to "
966 "0x%08" PRIx32 ".\n",
967 old_ssrc, rtp_my_ssrc(s->audio_network_device));
968 } break;
969 }
970 return new_response(RESPONSE_OK, nullptr);
971}
972
978
979static void *asend_compute_and_print_stats(void *arg) {
980 auto *d = (struct asend_stats_processing_data*) arg;
981
982 log_msg(LOG_LEVEL_INFO, "[Audio sender] Sent %d samples in last %f seconds.\n",
983 d->frame.get_sample_count(),
984 d->seconds);
985
986 char volume[STR_LEN];
987 char *vol_start = volume;
988 for (int i = 0; i < d->frame.get_channel_count(); ++i) {
989 double rms = 0.0;
990 double peak = 0.0;
991 rms = calculate_rms(&d->frame, i, &peak);
993 i, rms, peak, TERM_BOLD TERM_FG_GREEN, &vol_start,
994 volume + sizeof volume);
995 }
996
997 log_msg(LOG_LEVEL_INFO, "[Audio sender] Volume: %s dBFS RMS/peak%s\n",
998 volume, d->muted_sender ? TBOLD(TRED(" (muted)")) : "");
999
1000 delete d;
1001
1002 return NULL;
1003}
1004
1005static void process_statistics(struct state_audio *s, audio_frame2 *buffer)
1006{
1007 if (!s->captured.has_same_prop_as(*buffer)) {
1008 s->captured.init(buffer->get_channel_count(), buffer->get_codec(),
1009 buffer->get_bps(), buffer->get_sample_rate());
1010 }
1011 s->captured.append(*buffer);
1012
1014 if (t - s->t0 > 5 * NS_IN_SEC) {
1015 double seconds = (double)(t - s->t0) / NS_IN_SEC;
1016 auto d = new asend_stats_processing_data;
1017 std::swap(d->frame, s->captured);
1018 d->seconds = seconds;
1019 d->muted_sender = s->muted_sender;
1020
1022 s->t0 = t;
1023 }
1024}
1025
1026static int find_codec_sample_rate(int sample_rate, const int *supported) {
1027 if (!supported) {
1028 return 0;
1029 }
1030
1031 int rate_hi = 0, // nearest high
1032 rate_lo = 0; // nearest low
1033
1034 const int *tmp = supported;
1035 while (*tmp != 0) {
1036 if (*tmp == sample_rate) {
1037 return sample_rate;
1038 }
1039 if (*tmp > sample_rate && (rate_hi == 0 || *tmp < rate_hi)) {
1040 rate_hi = *tmp;
1041 }
1042
1043 if (*tmp < sample_rate && *tmp > rate_lo) {
1044 rate_lo = *tmp;
1045 }
1046 tmp++;
1047 }
1048
1049 return rate_hi > 0 ? rate_hi : rate_lo;
1050}
1051
1052static void
1053set_audio_spec_to_vrxtx(struct video_rxtx *vrxtx, audio_frame2 *compressed_frm,
1054 struct rtp *netdev, int tx_port, bool *audio_spec_to_vrxtx_set)
1055{
1056 if (*audio_spec_to_vrxtx_set) {
1057 return;
1058 }
1059
1060 *audio_spec_to_vrxtx_set = true;
1061
1062 const struct audio_desc desc = compressed_frm->get_desc();
1063 const int rx_port = rtp_get_udp_rx_port(netdev);
1064
1065 MSG(VERBOSE, "Setting audio desc %s, rx port=%d to RXTX.\n",
1066 audio_desc_to_cstring(desc), rx_port);
1067
1068 assert(vrxtx != nullptr);
1069 vrxtx->set_audio_spec(&desc, rx_port, tx_port, rtp_is_ipv6(netdev));
1070}
1071
1072static void *audio_sender_thread(void *arg)
1073{
1074 set_thread_name(__func__);
1075 struct state_audio *s = (struct state_audio *) arg;
1076 bool audio_spec_to_vrxtx_set = false;
1077 struct audio_frame *buffer = NULL;
1078 unique_ptr<audio_frame2_resampler> resampler_state;
1079 try {
1080 resampler_state = unique_ptr<audio_frame2_resampler>(new audio_frame2_resampler);
1081 } catch (ug_runtime_error &e) {
1082 log_msg(LOG_LEVEL_ERROR, MOD_NAME "%s\n", e.what());
1083 exit_uv(1);
1084 return NULL;
1085 }
1086
1087 printf("Audio sending started.\n");
1088
1089 while (!s->should_exit) {
1090 struct message *msg;
1091 while((msg = check_message(s->audio_sender_module.get()))) {
1092 struct response *r = audio_sender_process_message(s, (struct msg_sender *) msg);
1093 free_message(msg, r);
1094 }
1095
1096 if ((s->audio_tx_mode & MODE_RECEIVER) == 0) { // otherwise receiver thread does the stuff...
1097 time_ns_t curr_time = get_time_in_ns();
1098 uint32_t ts = (curr_time - s->start_time) / 10'0000 * 9; // at 90000 Hz
1099 rtp_update(s->audio_network_device, curr_time);
1100 rtp_send_ctrl(s->audio_network_device, ts, 0, curr_time);
1101
1102 // receive RTCP
1103 struct timeval timeout;
1104 timeout.tv_sec = 0;
1105 timeout.tv_usec = 0;
1106 rtcp_recv_r(s->audio_network_device, &timeout, ts);
1107 }
1108
1110 if(buffer) {
1111 if(s->echo_state) {
1112#ifdef HAVE_SPEEXDSP
1113 buffer = echo_cancel(s->echo_state, buffer);
1114 if(!buffer)
1115 continue;
1116#endif
1117 }
1118 if (s->muted_sender) {
1119 memset(buffer->data, 0, buffer->data_len);
1120 }
1121 export_audio(s->exporter, buffer);
1122
1123 s->filter_chain.filter(&buffer);
1124
1125 if(!buffer)
1126 continue;
1127
1128 audio_frame2 bf_n(buffer);
1129
1130 // RESAMPLE
1131 int resample_to = s->resample_to;
1132 if (resample_to == 0) {
1133 const int *supp_sample_rates = audio_codec_get_supported_samplerates(s->audio_encoder);
1134 resample_to = find_codec_sample_rate(bf_n.get_sample_rate(),
1135 supp_sample_rates);
1136 }
1137 if (resample_to != 0 && bf_n.get_sample_rate() != resample_to) {
1138 if (bf_n.get_bps() != 2) {
1139 bf_n.change_bps(2);
1140 }
1141
1142 bf_n.resample(*resampler_state, resample_to);
1143 }
1144 // COMPRESS
1145 process_statistics(s, &bf_n);
1146 // SEND
1147 if(s->sender == NET_NATIVE) {
1148 audio_frame2 *uncompressed = &bf_n;
1149 while (audio_frame2 to_send = audio_codec_compress(s->audio_encoder, uncompressed)) {
1150 if (s->fec_state != nullptr) {
1151 to_send = s->fec_state->encode(to_send);
1152 }
1154 uncompressed = NULL;
1155 }
1156 }else if(s->sender == NET_STANDARD){
1157 audio_frame2 *uncompressed = &bf_n;
1158 while (audio_frame2 compressed = audio_codec_compress(s->audio_encoder, uncompressed)) {
1159 //TODO to be dynamic as a function of the selected codec, now only accepting mulaw without checking errors
1161 uncompressed = NULL;
1163 s->vrxtx, &compressed,
1165 s->audio_network_parameters.send_port,
1166 &audio_spec_to_vrxtx_set);
1167 }
1168 }
1169#ifdef HAVE_JACK_TRANS
1170 else
1171 jack_send(s->jack_connection, buffer);
1172#endif
1173 }
1174 }
1175
1176 return NULL;
1177}
1178
1180 void *sdi_capture;
1181 if (!s->audio_capture_device)
1182 return;
1184 return;
1185
1188}
1189
1190void
1192 struct additional_audio_data data)
1193{
1195 auto *sdi_playback = (struct state_sdi_playback *)
1198 sdi_playback, data.display_callbacks.udata,
1199 (void (*)(void *, const struct audio_frame *))
1201 (bool (*)(void *, int, int,
1202 int)) data.display_callbacks.reconfigure,
1203 (bool (*)(void *, int, void *,
1204 size_t *)) data.display_callbacks.get_property);
1205 }
1206
1207 s->vrxtx = data.vrxtx;
1208}
1209
1214
1215std::ostream& operator<<(std::ostream& os, const audio_desc& desc)
1216{
1217 os << desc.ch_count << " channel" << (desc.ch_count > 1 ? "s" : "") << ", " << desc.bps << " Bps, " << desc.sample_rate << " Hz, codec: " << get_name_to_audio_codec(desc.codec);
1218 return os;
1219}
1220
void ** state
struct video_desc desc
int int int sample_rate
struct video_frame * frame
int void size_t * len
This file contains definition of some common audio types.
void audio_register_aux_data(struct state_audio *s, struct additional_audio_data data)
Definition audio.cpp:1191
static void should_exit_audio(void *state)
Definition audio.cpp:232
unsigned int audio_get_display_flags(struct state_audio *s)
Definition audio.cpp:1210
void(* audio_device_help_t)(void)
Definition audio.cpp:194
static struct rtp * initialize_audio_network(struct audio_network_parameters *params)
Definition audio.cpp:547
static int find_codec_sample_rate(int sample_rate, const int *supported)
Definition audio.cpp:1026
static void audio_scale_usage(void)
Definition audio.cpp:219
static void audio_update_recv_buf(struct state_audio *s, size_t curr_frame_len)
Definition audio.cpp:684
static void set_audio_spec_to_vrxtx(struct video_rxtx *vrxtx, audio_frame2 *compressed_frm, struct rtp *netdev, int tx_port, bool *audio_spec_to_vrxtx_set)
Definition audio.cpp:1053
void audio_join(struct state_audio *s)
Definition audio.cpp:502
audio_transport_device
Definition audio.cpp:103
@ NET_JACK
Definition audio.cpp:105
@ NET_STANDARD
Definition audio.cpp:106
@ NET_NATIVE
Definition audio.cpp:104
static struct response * audio_sender_process_message(struct state_audio *s, struct msg_sender *msg)
Definition audio.cpp:866
static struct response * audio_receiver_process_message(struct state_audio *s, struct msg_receiver *msg)
Definition audio.cpp:578
static struct audio_decoder * audio_decoder_state_create(struct state_audio *s)
Definition audio.cpp:657
static void * audio_sender_thread(void *arg)
Definition audio.cpp:1072
void audio_sdi_send(struct state_audio *s, struct audio_frame *frame)
Definition audio.cpp:1179
static void * audio_receiver_thread(void *arg)
Definition audio.cpp:695
static void audio_decoder_state_deleter(void *state)
Definition audio.cpp:674
#define DEFAULT_AUDIO_RECV_BUF_SIZE
Definition audio.cpp:109
void audio_done(struct state_audio *s)
Definition audio.cpp:512
#define MOD_NAME
Definition audio.cpp:110
static void process_statistics(struct state_audio *s, audio_frame2 *buffer)
Definition audio.cpp:1005
int audio_init(struct state_audio **ret, const struct audio_options *opt, const struct common_opts *common)
Definition audio.cpp:272
static void * asend_compute_and_print_stats(void *arg)
Definition audio.cpp:979
static void audio_channel_map_usage(void)
Definition audio.cpp:205
void sdp_send_change_address_message(struct module *root, const enum module_class *path, const char *address)
Definition audio.cpp:238
void audio_start(struct state_audio *s)
Definition audio.cpp:463
std::ostream & operator<<(std::ostream &os, const audio_desc &desc)
Definition audio.cpp:1215
int audio_capture_init(struct module *parent, const char *driver, const char *cfg, struct state_audio_capture **state)
struct state_audio_capture * audio_capture_init_null_device()
unsigned int audio_capture_get_vidcap_flags(const char *const_device_name)
void audio_capture_done(struct state_audio_capture *s)
void * audio_capture_get_state_pointer(struct state_audio_capture *s)
const char * audio_capture_get_driver_name(struct state_audio_capture *s)
struct audio_frame * audio_capture_read(struct state_audio_capture *s)
void audio_decoder_destroy(void *state)
int decode_audio_frame_mulaw(struct coded_data *cdata, void *data, struct pbuf_stats *)
void * audio_decoder_init(char *audio_channel_map, const char *audio_scale, const char *encryption, audio_playback_ctl_t c, void *p_state, struct module *parent)
int decode_audio_frame(struct coded_data *cdata, void *pbuf_data, struct pbuf_stats *)
void audio_decoder_set_volume(void *state, double val)
bool(* audio_playback_ctl_t)(void *state, int request, void *data, size_t *len)
bool audio_playback_ctl(struct state_audio_playback *s, int request, void *data, size_t *len)
void * audio_playback_get_state_pointer(struct state_audio_playback *s)
unsigned int audio_playback_get_display_flags(struct state_audio_playback *s)
bool audio_playback_reconfigure(struct state_audio_playback *s, int quant_samples, int channels, int sample_rate)
int audio_playback_init(const char *device, const char *cfg, struct state_audio_playback **state)
struct state_audio_playback * audio_playback_init_null_device(void)
void audio_playback_put_frame(struct state_audio_playback *s, const struct audio_frame *frame)
void audio_playback_done(struct state_audio_playback *s)
#define AUDIO_PLAYBACK_CTL_MULTIPLE_STREAMS
#define AUDIO_PLAYBACK_PUT_NETWORK_DEVICE
bool emplace_new(std::string_view cfg)
af_result_code filter(struct audio_frame **frame)
void change_bps(int new_bps)
Definition types.cpp:313
struct audio_desc get_desc() const
Definition types.cpp:205
bool has_same_prop_as(audio_frame2 const &frame) const
Definition types.cpp:280
void init(int nr_channels, audio_codec_t codec, int bps, int sample_rate)
Initializes audio_frame2 for use. If already initialized, data are dropped.
Definition types.cpp:115
audio_codec_t get_codec() const
Definition types.cpp:213
int get_channel_count() const
Definition types.cpp:260
bool resample(audio_frame2_resampler &resampler_state, int new_sample_rate)
Definition types.cpp:361
int get_sample_rate() const
Definition types.cpp:275
int get_bps() const
Definition types.cpp:200
void append(audio_frame2 const &frame)
Definition types.cpp:125
struct audio_codec_state * audio_codec_init_cfg(const char *audio_codec_cfg, audio_codec_direction_t direction)
Definition codec.cpp:165
struct audio_codec_params parse_audio_codec_params(const char *ccfg)
Definition codec.cpp:402
const char * get_name_to_audio_codec(audio_codec_t codec)
Definition codec.cpp:450
audio_frame2 audio_codec_compress(struct audio_codec_state *s, const audio_frame2 *frame)
Definition codec.cpp:245
const int * audio_codec_get_supported_samplerates(struct audio_codec_state *s)
Definition codec.cpp:367
void audio_codec_done(struct audio_codec_state *s)
Definition codec.cpp:372
@ AUDIO_CODER
Definition codec.h:46
#define TERM_BOLD
Definition color_out.h:48
#define TERM_FG_GREEN
Definition color_out.h:51
#define TRED(x)
Definition color_out.h:75
#define TBOLD(x)
Definition color_out.h:70
#define TRUE
#define FALSE
static void new_message(struct module *m)
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_NOTICE
information that may be interesting
Definition debug.h:61
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define MSG(l, fmt,...)
Definition debug.h:96
#define LOG(level)
Definition debug.h:313
#define LOG_LEVEL_FATAL
errors that prevent UG run
Definition debug.h:58
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
struct echo_cancellation * echo_cancellation_init(void)
Definition echo.cpp:132
void echo_play(struct echo_cancellation *s, struct audio_frame *frame)
Definition echo.cpp:179
struct audio_frame * echo_cancel(struct echo_cancellation *s, struct audio_frame *frame)
Definition echo.cpp:235
void export_audio(struct exporter *s, struct audio_frame *frame)
Definition export.c:341
void module_done(struct module *module_data)
Definition module.c:93
module_class
Definition module.h:81
#define CAST_MODULE(x)
Definition module.h:197
struct module * get_root_module(struct module *node)
Definition module.c:203
void append_message_path(char *buf, int buflen, const enum module_class *modules)
Definition module.c:187
@ MODULE_CLASS_RECEIVER
Definition module.h:88
@ MODULE_CLASS_AUDIO
Definition module.h:90
@ MODULE_CLASS_SENDER
Definition module.h:87
void exit_uv(int status)
Definition host.cpp:625
void register_should_exit_callback(struct module *mod, void(*callback)(void *), void *udata)
Definition host.cpp:1144
volatile int audio_offset
added audio delay in ms (non-negative), can be used to tune AV sync
Definition host.cpp:178
const char * get_commandline_param(const char *key)
Definition host.cpp:894
void unregister_should_exit_callback(struct module *mod, void(*callback)(void *), void *udata)
Definition host.cpp:1158
#define EXIT_FAIL_AUDIO
Definition host.h:70
#define MODE_SENDER
Definition host.h:102
#define MODE_RECEIVER
Definition host.h:103
void * jack_start(const char *cfg)
Definition jack.c:264
int is_jack_receiver(void *state)
Definition jack.c:426
void jack_send(void *state, struct audio_frame *frame)
Definition jack.c:355
bool jack_receive(void *state, void *data)
Receives data from JACK.
Definition jack.c:387
int is_jack_sender(void *state)
Definition jack.c:421
#define LOG_LEVEL_DEBUG
Definition kernels.cu:48
@ STR_LEN
"standard" string length placeholder
Definition macros.h:134
void free_message(struct message *msg, struct response *r)
struct response * new_response(int status, const char *text)
int response_get_status(struct response *r)
struct response * send_message(struct module *root, const char *const_path, struct message *msg)
Sends message without waiting for response.
struct message * check_message(struct module *mod)
void free_response(struct response *r)
@ SENDER_MSG_MUTE_TOGGLE
Definition messaging.h:89
@ SENDER_MSG_RESET_SSRC
Definition messaging.h:92
@ SENDER_MSG_QUERY_VIDEO_MODE
Definition messaging.h:91
@ SENDER_MSG_GET_STATUS
Definition messaging.h:86
@ SENDER_MSG_MUTE
Definition messaging.h:87
@ SENDER_MSG_CHANGE_FEC
Definition messaging.h:90
@ SENDER_MSG_CHANGE_RECEIVER
Definition messaging.h:84
@ SENDER_MSG_UNMUTE
Definition messaging.h:88
@ SENDER_MSG_CHANGE_PORT
Definition messaging.h:85
#define RESPONSE_OK
Definition messaging.h:57
@ RECEIVER_MSG_MUTE_TOGGLE
Definition messaging.h:116
@ RECEIVER_MSG_DECREASE_VOLUME
Definition messaging.h:113
@ RECEIVER_MSG_UNMUTE
Definition messaging.h:115
@ RECEIVER_MSG_CHANGE_RX_PORT
Definition messaging.h:109
@ RECEIVER_MSG_INCREASE_VOLUME
Definition messaging.h:112
@ RECEIVER_MSG_MUTE
Definition messaging.h:114
@ RECEIVER_MSG_GET_AUDIO_STATUS
Definition messaging.h:111
@ RECEIVER_MSG_VIDEO_PROP_CHANGED
Definition messaging.h:110
#define RESPONSE_BAD_REQUEST
Definition messaging.h:60
#define RESPONSE_INT_SERV_ERR
Definition messaging.h:63
#define IN6_BLACKHOLE_SERVER_MODE_STR
Definition net.h:52
int pbuf_decode(struct pbuf *playout_buf, time_ns_t curr_time, decode_frame_t decode_func, void *data)
Definition pbuf.c:562
void pbuf_set_playout_delay(struct pbuf *playout_buf, double playout_delay)
Definition pbuf.c:597
int pbuf_is_empty(struct pbuf *playout_buf)
Definition pbuf.c:553
void pbuf_remove(struct pbuf *playout_buf, time_ns_t curr_time)
Definition pbuf.c:498
void pdb_iter_done(pdb_iter_t *it)
Definition pdb.c:412
struct pdb_e * pdb_iter_next(pdb_iter_t *it)
Definition pdb.c:402
struct pdb_e * pdb_iter_init(struct pdb *db, pdb_iter_t *it)
Definition pdb.c:393
struct pdb * pdb_init(volatile int *delay_ms)
Definition pdb.c:244
int pdb_add(struct pdb *db, uint32_t ssrc)
Definition pdb.c:299
void pdb_destroy(struct pdb **db_p)
Definition pdb.c:256
void * pdb_iter_t
Definition pdb.h:106
void rtp_flush_recv_buf(struct rtp *session)
Definition rtp.c:3964
bool rtp_set_recv_buf(struct rtp *session, int bufsize)
Definition rtp.c:3938
bool rtp_set_option(struct rtp *session, rtp_option optname, int optval)
Definition rtp.c:1308
void rtp_update(struct rtp *session, time_ns_t curr_time)
Definition rtp.c:3456
struct rtp * rtp_init_if(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl, double rtcp_bw, int tfrc_on, rtp_callback callback, uint8_t *userdata, int force_ip_version, bool multithreaded)
Definition rtp.c:1034
uint32_t rtp_my_ssrc(struct rtp *session)
Definition rtp.c:1401
void rtp_send_ctrl(struct rtp *session, uint32_t rtp_ts, rtcp_app_callback appcallback, time_ns_t curr_time)
Definition rtp.c:3409
bool rtp_set_sdes(struct rtp *session, uint32_t ssrc, rtcp_sdes_type type, const char *value, int length)
Definition rtp.c:2546
int rtp_get_udp_rx_port(struct rtp *session)
Definition rtp.c:4042
bool rtp_recv_r(struct rtp *session, struct timeval *timeout, uint32_t curr_rtp_ts)
Receive RTP packets and dispatch them.
Definition rtp.c:2338
bool rtp_is_ipv6(struct rtp *session)
Definition rtp.c:4022
bool rtcp_recv_r(struct rtp *session, struct timeval *timeout, uint32_t curr_rtp_ts)
Definition rtp.c:2398
void rtp_done(struct rtp *session)
Definition rtp.c:3676
@ RTCP_SDES_TOOL
Definition rtp.h:215
@ RTP_OPT_PROMISC
Definition rtp.h:228
@ RTP_OPT_WEAK_VALIDATION
Definition rtp.h:229
@ RTP_OPT_SEND_BACK
Definition rtp.h:236
@ RTP_OPT_RECORD_SOURCE
Definition rtp.h:234
void rtp_recv_callback(struct rtp *session, rtp_event *e)
struct msghdr msg
void sdi_register_display_callbacks(void *state, void *udata, void(*putf)(void *, const struct audio_frame *), bool(*reconfigure)(void *, int, int, int), bool(*get_property)(void *, int, void *, size_t *))
Definition sdi.c:117
void sdi_capture_new_incoming_frame(void *state, struct audio_frame *frame)
Definition sdi.cpp:174
int sdp_set_options(const char *opts)
Definition sdp.c:585
const char * parent
Definition settings.cpp:198
bool enabled
Definition settings.cpp:197
std::string_view tokenize(std::string_view &str, char delim, char quot)
Tokenizer for string_view.
struct additional_audio_data::@2 display_callbacks
void(* putf)(struct display *, const struct audio_frame *)
Definition audio.h:106
bool(* reconfigure)(struct display *, int, int, int)
Definition audio.h:107
bool(* get_property)(struct display *, int, void *, size_t *)
Definition audio.h:108
struct video_rxtx * vrxtx
Definition audio.h:110
struct pbuf_audio_data pbuf_data
Definition audio.cpp:575
int sample_rate
Definition types.h:78
int ch_count
Definition types.h:79
int bps
Definition types.h:77
struct used to comunicate with audio capture/playback device
Definition types.h:99
int64_t timestamp
Definition types.h:109
char * data
Definition types.h:102
int data_len
Definition types.h:103
void * network_source
Definition types.h:106
struct pdb * participants
Definition audio.cpp:116
const char * mcast_if
Definition audio.cpp:118
const char * fec_cfg
Definition audio.h:76
const char * host
Definition audio.h:69
const char * recv_cfg
Definition audio.h:72
const char * send_cfg
Definition audio.h:73
int send_port
Definition audio.h:71
const char * filter_cfg
Definition audio.h:81
int recv_port
Definition audio.h:70
bool echo_cancellation
Definition audio.h:79
char * channel_map
Definition audio.h:77
const char * scale
Definition audio.h:78
const char * codec_cfg
Definition audio.h:80
char encryption[STR_LEN]
Definition host.h:172
int mtu
Definition host.h:174
struct module * parent
Definition host.h:171
struct exporter * exporter
Definition host.h:177
time_ns_t start_time
Definition host.h:178
int force_ip_version
Definition host.h:176
Definition fec.h:51
static fec * create_from_config(const char *str, bool is_audio) noexcept
Definition fec.cpp:62
virtual std::shared_ptr< video_frame > encode(std::shared_ptr< video_frame >)=0
Definition hd-rum.c:27
struct sockaddr_storage source
Definition pbuf.h:100
size_t frame_size
currently decoded audio frame size (used similarly as vcodec_state::max_frame_size to allow caller ad...
Definition pbuf.h:104
struct state_audio_decoder * decoder
Definition pbuf.h:101
audio_frame buffer
Definition pbuf.h:99
Definition pdb.h:72
decoder_state_deleter_t decoder_state_deleter
decoder state deleter
Definition pdb.h:82
void * decoder_state
state of decoder for participant
Definition pdb.h:81
struct pbuf * playout_buffer
Definition pdb.h:84
Definition pdb.c:84
Definition rtp.c:274
double rtcp_bw
Definition rtp.c:297
source * db[RTP_DB_SIZE]
Definition rtp.c:282
options * opt
Definition rtp.c:284
module_raii mod
Definition audio.cpp:138
pthread_t audio_sender_thread_id
Definition audio.cpp:165
size_t recv_buf_size
Definition audio.cpp:184
bool audio_receiver_thread_started
Definition audio.cpp:168
pthread_t audio_receiver_thread_id
Definition audio.cpp:166
time_ns_t start_time
Definition audio.cpp:157
struct video_rxtx * vrxtx
Definition audio.cpp:186
audio_frame2 captured
Definition audio.cpp:160
int resample_to
Definition audio.cpp:174
state_audio(struct module *parent, time_ns_t st)
Definition audio.cpp:123
std::string proto_cfg
Definition audio.cpp:152
time_ns_t t0
Definition audio.cpp:158
enum audio_transport_device sender
Definition audio.cpp:154
module_raii audio_sender_module
Definition audio.cpp:143
struct pdb * audio_participants
Definition audio.cpp:151
double volume
Definition audio.cpp:180
module_raii audio_receiver_module
Definition audio.cpp:142
bool audio_sender_thread_started
Definition audio.cpp:167
enum audio_transport_device receiver
Definition audio.cpp:155
bool muted_sender
Definition audio.cpp:182
Filter_chain filter_chain
Definition audio.cpp:145
struct state_audio_playback * audio_playback_device
Definition audio.cpp:140
fec * fec_state
Definition audio.cpp:163
struct tx * tx_session
Definition audio.cpp:162
int audio_tx_mode
Definition audio.cpp:178
struct audio_codec_state * audio_encoder
Definition audio.cpp:147
bool should_exit
Definition audio.cpp:136
struct rtp * audio_network_device
Definition audio.cpp:150
echo_cancellation_t * echo_state
Definition audio.cpp:172
struct state_audio_capture * audio_capture_device
Definition audio.cpp:139
char * audio_channel_map
Definition audio.cpp:170
struct exporter * exporter
Definition audio.cpp:173
bool muted_receiver
Definition audio.cpp:181
const char * audio_scale
Definition audio.cpp:171
void * jack_connection
Definition audio.cpp:153
virtual void set_audio_spec(const struct audio_desc *desc, int audio_rx_port, int audio_tx_port, bool ipv6)
uint32_t ts
Definition tfrc.c:101
void set_thread_name(const char *name)
Definition thread.c:72
void audio_tx_send(struct tx *tx, struct rtp *rtp_session, const audio_frame2 *buffer)
Definition transmit.cpp:799
void audio_tx_send_standard(struct tx *tx, struct rtp *rtp_session, const audio_frame2 *buffer)
Definition transmit.cpp:958
struct tx * tx_init(struct module *parent, unsigned mtu, enum tx_media_type media_type, const char *fec, const char *encryption, long long int bitrate)
Definition transmit.cpp:201
long long time_ns_t
Definition tv.h:81
#define NS_IN_SEC
Definition tv.h:92
static time_ns_t get_time_in_ns()
Definition tv.h:101
@ TX_MEDIA_AUDIO
Definition types.h:364
struct audio_desc audio_desc_from_frame(const struct audio_frame *frame)
Definition utils.cpp:196
bool audio_desc_eq(struct audio_desc a1, struct audio_desc a2)
Definition utils.cpp:189
double calculate_rms(audio_frame2 *frame, int channel, double *peak)
Calculates mean and peak RMS from audio samples.
Definition utils.cpp:150
void format_audio_channel_volume(int chan_idx, double rms, double peak, const char *format_color, char **volume_start, char *volume_end)
format per channel incrementally volume string (eg. "[0]-18.00/-14.99, [1] -18.00/-14....
Definition utils.cpp:828
const char * audio_desc_to_cstring(struct audio_desc desc)
Definition utils.cpp:644
void task_run_async_detached(runnable_t task, void *data)
Runs task asynchronously in a detached state.
Definition worker.cpp:275