UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
audio.cpp File Reference
#include <array>
#include <cinttypes>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <memory>
#include <sstream>
#include <string>
#include "../export.h"
#include "audio/audio.h"
#include "audio/audio_capture.h"
#include "audio/audio_filter.h"
#include "audio/audio_playback.h"
#include "audio/capture/sdi.h"
#include "audio/codec.h"
#include "audio/echo.h"
#include "audio/filter_chain.hpp"
#include "audio/jack.h"
#include "audio/playback/sdi.h"
#include "audio/resampler.hpp"
#include "audio/utils.h"
#include "debug.h"
#include "host.h"
#include "module.h"
#include "pdb.h"
#include "rtp/audio_decoders.h"
#include "rtp/fec.h"
#include "rtp/pbuf.h"
#include "rtp/rtp.h"
#include "rtp/rtp_callback.h"
#include "transmit.h"
#include "tv.h"
#include "types.h"
#include "ug_runtime_error.hpp"
#include "utils/color_out.h"
#include "utils/net.h"
#include "utils/sdp.h"
#include "utils/string_view_utils.hpp"
#include "utils/thread.h"
#include "utils/worker.h"
#include "video_rxtx.hpp"
Include dependency graph for audio.cpp:

Go to the source code of this file.

Classes

struct  asend_stats_processing_data
 
struct  audio_decoder
 
struct  audio_network_parameters
 
struct  state_audio
 
struct  state_audio::audio_network_parameters
 
struct  state_audio::opts
 

Macros

#define DEFAULT_AUDIO_RECV_BUF_SIZE   (256 * 1024)
 
#define MOD_NAME   "[audio] "
 

Typedefs

typedef void(* audio_device_help_t) (void)
 

Enumerations

enum  audio_transport_device { NET_NATIVE , NET_JACK , NET_STANDARD }
 

Functions

static void * asend_compute_and_print_stats (void *arg)
 
static void audio_channel_map_usage (void)
 
static struct audio_decoder * audio_decoder_state_create (struct state_audio *s)
 
static void audio_decoder_state_deleter (void *state)
 
void audio_done (struct state_audio *s)
 
unsigned int audio_get_display_flags (struct state_audio *s)
 
int audio_init (struct state_audio **ret, const struct audio_options *opt, const struct common_opts *common)
 
void audio_join (struct state_audio *s)
 
static struct response * audio_receiver_process_message (struct state_audio *s, struct msg_receiver *msg)
 
static void * audio_receiver_thread (void *arg)
 
void audio_register_aux_data (struct state_audio *s, struct additional_audio_data data)
 
static void audio_scale_usage (void)
 
void audio_sdi_send (struct state_audio *s, struct audio_frame *frame)
 
static struct response * audio_sender_process_message (struct state_audio *s, struct msg_sender *msg)
 
static void * audio_sender_thread (void *arg)
 
void audio_start (struct state_audio *s)
 
static void audio_update_recv_buf (struct state_audio *s, size_t curr_frame_len)
 
static int find_codec_sample_rate (int sample_rate, const int *supported)
 
static struct rtp * initialize_audio_network (struct audio_network_parameters *params)
 
std::ostream & operator<< (std::ostream &os, const audio_desc &desc)
 
static void process_statistics (struct state_audio *s, audio_frame2 *buffer)
 
void sdp_send_change_address_message (struct module *root, const enum module_class *path, const char *address)
 
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)
 
static void should_exit_audio (void *state)
 

Macro Definition Documentation

◆ DEFAULT_AUDIO_RECV_BUF_SIZE

#define DEFAULT_AUDIO_RECV_BUF_SIZE   (256 * 1024)

Definition at line 109 of file audio.cpp.

Referenced by initialize_audio_network().

◆ MOD_NAME

Typedef Documentation

◆ audio_device_help_t

typedef void(* audio_device_help_t) (void)

Copies one input channel into n output (interlaced).

Input and output data may overlap.

Definition at line 194 of file audio.cpp.

Enumeration Type Documentation

◆ audio_transport_device

Enumerator
NET_NATIVE 
NET_JACK 
NET_STANDARD 

Definition at line 103 of file audio.cpp.

103 {
105 NET_JACK,
107};
@ NET_JACK
Definition audio.cpp:105
@ NET_STANDARD
Definition audio.cpp:106
@ NET_NATIVE
Definition audio.cpp:104

Function Documentation

◆ asend_compute_and_print_stats()

static void * asend_compute_and_print_stats ( void * arg)
static

Definition at line 979 of file audio.cpp.

979 {
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}
#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
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62
@ STR_LEN
"standard" string length placeholder
Definition macros.h:134
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

References calculate_rms(), format_audio_channel_volume(), LOG_LEVEL_INFO, log_msg(), STR_LEN, TBOLD, TERM_BOLD, TERM_FG_GREEN, and TRED.

Referenced by process_statistics().

Here is the call graph for this function:

◆ audio_channel_map_usage()

static void audio_channel_map_usage ( void )
static

Definition at line 205 of file audio.cpp.

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}

Referenced by audio_init().

◆ audio_decoder_state_create()

static struct audio_decoder * audio_decoder_state_create ( struct state_audio * s)
static

Definition at line 657 of file audio.cpp.

657 {
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}
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)
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)
double volume
Definition audio.cpp:180
module_raii audio_receiver_module
Definition audio.cpp:142
struct state_audio_playback * audio_playback_device
Definition audio.cpp:140
char * audio_channel_map
Definition audio.cpp:170
bool muted_receiver
Definition audio.cpp:181
const char * audio_scale
Definition audio.cpp:171

References state_audio::audio_channel_map, audio_decoder_init(), audio_decoder_set_volume(), audio_playback_ctl(), state_audio::audio_playback_device, state_audio::audio_receiver_module, state_audio::audio_scale, state_audio::muted_receiver, and state_audio::volume.

Referenced by audio_receiver_thread().

Here is the call graph for this function:

◆ audio_decoder_state_deleter()

static void audio_decoder_state_deleter ( void * state)
static

Definition at line 674 of file audio.cpp.

675{
676 struct audio_decoder *s = (struct audio_decoder *) state;
677
678 free(s->pbuf_data.buffer.data);
680
681 free(s);
682}
void ** state
void audio_decoder_destroy(void *state)
struct pbuf_audio_data pbuf_data
Definition audio.cpp:575
char * data
Definition types.h:102
struct state_audio_decoder * decoder
Definition pbuf.h:101
audio_frame buffer
Definition pbuf.h:99

References audio_decoder_destroy(), pbuf_audio_data::buffer, audio_frame::data, pbuf_audio_data::decoder, audio_decoder::pbuf_data, and state.

Referenced by audio_receiver_thread().

Here is the call graph for this function:

◆ audio_done()

void audio_done ( struct state_audio * s)

Definition at line 512 of file audio.cpp.

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}
static void should_exit_audio(void *state)
Definition audio.cpp:232
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
void audio_capture_done(struct state_audio_capture *s)
void audio_playback_done(struct state_audio_playback *s)
void audio_codec_done(struct audio_codec_state *s)
Definition codec.cpp:372
void module_done(struct module *module_data)
Definition module.c:93
#define CAST_MODULE(x)
Definition module.h:197
struct module * get_root_module(struct module *node)
Definition module.c:203
void unregister_should_exit_callback(struct module *mod, void(*callback)(void *), void *udata)
Definition host.cpp:1158
void free_message(struct message *msg, struct response *r)
struct message * check_message(struct module *mod)
void pdb_destroy(struct pdb **db_p)
Definition pdb.c:256
void rtp_done(struct rtp *session)
Definition rtp.c:3676
struct msghdr msg
module_raii mod
Definition audio.cpp:138
module_raii audio_sender_module
Definition audio.cpp:143
struct pdb * audio_participants
Definition audio.cpp:151
struct tx * tx_session
Definition audio.cpp:162
struct audio_codec_state * audio_encoder
Definition audio.cpp:147
struct rtp * audio_network_device
Definition audio.cpp:150
struct state_audio_capture * audio_capture_device
Definition audio.cpp:139

References state_audio::audio_capture_device, audio_capture_done(), audio_codec_done(), state_audio::audio_encoder, state_audio::audio_network_device, state_audio::audio_participants, state_audio::audio_playback_device, audio_playback_done(), state_audio::audio_receiver_module, audio_receiver_process_message(), state_audio::audio_sender_module, audio_sender_process_message(), CAST_MODULE, check_message(), free_message(), get_root_module(), state_audio::mod, module_done(), msg, pdb_destroy(), rtp_done(), should_exit_audio(), state_audio::tx_session, and unregister_should_exit_callback().

Referenced by main(), and vidcap_ug_input_done().

Here is the call graph for this function:

◆ audio_get_display_flags()

unsigned int audio_get_display_flags ( struct state_audio * s)

Definition at line 1210 of file audio.cpp.

1211{
1213}
unsigned int audio_playback_get_display_flags(struct state_audio_playback *s)

References state_audio::audio_playback_device, and audio_playback_get_display_flags().

Referenced by main().

Here is the call graph for this function:

◆ audio_init()

int audio_init ( struct state_audio ** ret,
const struct audio_options * opt,
const struct common_opts * common )

take care that addrs can also be comma-separated list of addresses !

Return values
0state succesfully initialized
<0error occured
>0success but no state was created (eg. help printed)

Definition at line 272 of file audio.cpp.

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}
int void size_t * len
static struct rtp * initialize_audio_network(struct audio_network_parameters *params)
Definition audio.cpp:547
static void audio_scale_usage(void)
Definition audio.cpp:219
#define MOD_NAME
Definition audio.cpp:110
static void audio_channel_map_usage(void)
Definition audio.cpp:205
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()
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)
#define AUDIO_PLAYBACK_PUT_NETWORK_DEVICE
bool emplace_new(std::string_view cfg)
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
@ AUDIO_CODER
Definition codec.h:46
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define LOG(level)
Definition debug.h:313
struct echo_cancellation * echo_cancellation_init(void)
Definition echo.cpp:132
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
#define MODE_SENDER
Definition host.h:102
#define MODE_RECEIVER
Definition host.h:103
struct pdb * pdb_init(volatile int *delay_ms)
Definition pdb.c:244
int sdp_set_options(const char *opts)
Definition sdp.c:585
std::string_view tokenize(std::string_view &str, char delim, char quot)
Tokenizer for string_view.
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 hd-rum.c:27
Definition rtp.c:274
options * opt
Definition rtp.c:284
bool audio_receiver_thread_started
Definition audio.cpp:168
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
enum audio_transport_device sender
Definition audio.cpp:154
bool audio_sender_thread_started
Definition audio.cpp:167
enum audio_transport_device receiver
Definition audio.cpp:155
Filter_chain filter_chain
Definition audio.cpp:145
int audio_tx_mode
Definition audio.cpp:178
echo_cancellation_t * echo_state
Definition audio.cpp:172
struct exporter * exporter
Definition audio.cpp:173
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
@ TX_MEDIA_AUDIO
Definition types.h:364

References state_audio::state_audio(), state_audio::audio_capture_device, audio_capture_init(), audio_capture_init_null_device(), state_audio::audio_channel_map, audio_channel_map_usage(), audio_codec_done(), audio_codec_init_cfg(), AUDIO_CODER, state_audio::audio_encoder, state_audio::audio_network_device, audio_offset, state_audio::audio_participants, audio_playback_ctl(), state_audio::audio_playback_device, audio_playback_init(), audio_playback_init_null_device(), AUDIO_PLAYBACK_PUT_NETWORK_DEVICE, state_audio::audio_receiver_thread_started, state_audio::audio_scale, audio_scale_usage(), state_audio::audio_sender_module, state_audio::audio_sender_thread_started, state_audio::audio_tx_mode, CAST_MODULE, audio_options::channel_map, audio_options::codec_cfg, audio_options::echo_cancellation, echo_cancellation_init(), state_audio::echo_state, Filter_chain::emplace_new(), common_opts::encryption, common_opts::exporter, state_audio::exporter, audio_options::fec_cfg, audio_options::filter_cfg, state_audio::filter_chain, common_opts::force_ip_version, audio_options::host, initialize_audio_network(), len, LOG, LOG_LEVEL_ERROR, log_msg(), MOD_NAME, MODE_RECEIVER, MODE_SENDER, module_done(), common_opts::mtu, NET_JACK, NET_NATIVE, NET_STANDARD, rtp::opt, common_opts::parent, parse_audio_codec_params(), pdb_destroy(), pdb_init(), state_audio::proto_cfg, state_audio::receiver, audio_options::recv_cfg, audio_options::recv_port, register_should_exit_callback(), state_audio::resample_to, audio_codec_params::sample_rate, audio_options::scale, sdp_set_options(), audio_options::send_cfg, audio_options::send_port, state_audio::sender, should_exit_audio(), common_opts::start_time, tokenize(), tx_init(), TX_MEDIA_AUDIO, and state_audio::tx_session.

Referenced by main(), and vidcap_ug_input_init().

Here is the call graph for this function:

◆ audio_join()

void audio_join ( struct state_audio * s)

Definition at line 502 of file audio.cpp.

502 {
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}
pthread_t audio_sender_thread_id
Definition audio.cpp:165
pthread_t audio_receiver_thread_id
Definition audio.cpp:166

References state_audio::audio_receiver_thread_id, state_audio::audio_receiver_thread_started, state_audio::audio_sender_thread_id, and state_audio::audio_sender_thread_started.

Referenced by main(), and vidcap_ug_input_done().

◆ audio_receiver_process_message()

static struct response * audio_receiver_process_message ( struct state_audio * s,
struct msg_receiver * msg )
static

Definition at line 578 of file audio.cpp.

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}
#define LOG_LEVEL_NOTICE
information that may be interesting
Definition debug.h:61
struct response * new_response(int status, const char *text)
#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_INT_SERV_ERR
Definition messaging.h:63
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
void * pdb_iter_t
Definition pdb.h:106
Definition pdb.h:72
void * decoder_state
state of decoder for participant
Definition pdb.h:81
source * db[RTP_DB_SIZE]
Definition rtp.c:282

References audio_decoder_set_volume(), state_audio::audio_network_device, state_audio::audio_participants, state_audio::audio_tx_mode, rtp::db, pdb_e::decoder_state, initialize_audio_network(), LOG, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_NOTICE, log_msg(), MODE_RECEIVER, state_audio::muted_receiver, new_response(), pdb_iter_done(), pdb_iter_init(), pdb_iter_next(), RECEIVER_MSG_CHANGE_RX_PORT, RECEIVER_MSG_DECREASE_VOLUME, RECEIVER_MSG_GET_AUDIO_STATUS, RECEIVER_MSG_INCREASE_VOLUME, RECEIVER_MSG_MUTE, RECEIVER_MSG_MUTE_TOGGLE, RECEIVER_MSG_UNMUTE, RECEIVER_MSG_VIDEO_PROP_CHANGED, RESPONSE_INT_SERV_ERR, RESPONSE_OK, rtp_done(), and state_audio::volume.

Referenced by audio_done(), and audio_receiver_thread().

Here is the call graph for this function:

◆ audio_receiver_thread()

static void * audio_receiver_thread ( void * arg)
static

Definition at line 695 of file audio.cpp.

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.
783 while (pbuf_decode(cp->playout_buffer, curr_time, s->receiver == NET_NATIVE ? decode_audio_frame : decode_audio_frame_mulaw, &dec_state->pbuf_data)) {
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;
812 if (audio_playback_reconfigure(s->audio_playback_device, curr_desc.bps * 8,
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}
static void audio_update_recv_buf(struct state_audio *s, size_t curr_frame_len)
Definition audio.cpp:684
static struct audio_decoder * audio_decoder_state_create(struct state_audio *s)
Definition audio.cpp:657
static void audio_decoder_state_deleter(void *state)
Definition audio.cpp:674
int decode_audio_frame_mulaw(struct coded_data *cdata, void *data, struct pbuf_stats *)
int decode_audio_frame(struct coded_data *cdata, void *pbuf_data, struct pbuf_stats *)
bool audio_playback_reconfigure(struct state_audio_playback *s, int quant_samples, int channels, int sample_rate)
void audio_playback_put_frame(struct state_audio_playback *s, const struct audio_frame *frame)
#define AUDIO_PLAYBACK_CTL_MULTIPLE_STREAMS
#define TRUE
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
void echo_play(struct echo_cancellation *s, struct audio_frame *frame)
Definition echo.cpp:179
void exit_uv(int status)
Definition host.cpp:625
const char * get_commandline_param(const char *key)
Definition host.cpp:894
bool jack_receive(void *state, void *data)
Receives data from JACK.
Definition jack.c:387
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 rtp_flush_recv_buf(struct rtp *session)
Definition rtp.c:3964
void rtp_update(struct rtp *session, time_ns_t curr_time)
Definition rtp.c:3456
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_recv_r(struct rtp *session, struct timeval *timeout, uint32_t curr_rtp_ts)
Receive RTP packets and dispatch them.
Definition rtp.c:2338
bool enabled
Definition settings.cpp:197
struct used to comunicate with audio capture/playback device
Definition types.h:99
void * network_source
Definition types.h:106
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
decoder_state_deleter_t decoder_state_deleter
decoder state deleter
Definition pdb.h:82
struct pbuf * playout_buffer
Definition pdb.h:84
time_ns_t start_time
Definition audio.cpp:157
bool should_exit
Definition audio.cpp:136
void * jack_connection
Definition audio.cpp:153
uint32_t ts
Definition tfrc.c:101
void set_thread_name(const char *name)
Definition thread.c:72
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
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

References audio_decoder_state_create(), audio_decoder_state_deleter(), audio_desc_eq(), audio_desc_from_frame(), state_audio::audio_network_device, state_audio::audio_participants, audio_playback_ctl(), AUDIO_PLAYBACK_CTL_MULTIPLE_STREAMS, state_audio::audio_playback_device, audio_playback_put_frame(), audio_playback_reconfigure(), state_audio::audio_receiver_module, audio_receiver_process_message(), audio_update_recv_buf(), audio_desc::bps, pbuf_audio_data::buffer, audio_desc::ch_count, check_message(), audio_frame::data, audio_frame::data_len, decode_audio_frame(), decode_audio_frame_mulaw(), pdb_e::decoder_state, pdb_e::decoder_state_deleter, echo_play(), state_audio::echo_state, audio_decoder::enabled, enabled, exit_uv(), pbuf_audio_data::frame_size, free_message(), get_commandline_param(), get_time_in_ns(), state_audio::jack_connection, jack_receive(), len, LOG, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, msg, NET_NATIVE, NET_STANDARD, audio_frame::network_source, NS_IN_SEC, audio_decoder::pbuf_data, pbuf_decode(), pbuf_is_empty(), pbuf_remove(), pbuf_set_playout_delay(), pdb_iter_done(), pdb_iter_init(), pdb_iter_next(), pdb_e::playout_buffer, state_audio::receiver, rtp_flush_recv_buf(), rtp_recv_r(), rtp_send_ctrl(), rtp_update(), audio_desc::sample_rate, set_thread_name(), state_audio::should_exit, pbuf_audio_data::source, state_audio::start_time, audio_frame::timestamp, TRUE, and ts.

Referenced by audio_start().

Here is the call graph for this function:

◆ audio_register_aux_data()

void audio_register_aux_data ( struct state_audio * s,
struct additional_audio_data data )

Definition at line 1191 of file audio.cpp.

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}
void * audio_playback_get_state_pointer(struct state_audio_playback *s)
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
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 video_rxtx * vrxtx
Definition audio.cpp:186

References state_audio::audio_playback_device, audio_playback_get_display_flags(), audio_playback_get_state_pointer(), additional_audio_data::display_callbacks, additional_audio_data::get_property, additional_audio_data::putf, additional_audio_data::reconfigure, sdi_register_display_callbacks(), additional_audio_data::udata, additional_audio_data::vrxtx, and state_audio::vrxtx.

Referenced by main(), and vidcap_ug_input_init().

Here is the call graph for this function:

◆ audio_scale_usage()

static void audio_scale_usage ( void )
static

Definition at line 219 of file audio.cpp.

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}

References TBOLD, and TRED.

Referenced by audio_init().

◆ audio_sdi_send()

void audio_sdi_send ( struct state_audio * s,
struct audio_frame * frame )

Definition at line 1179 of file audio.cpp.

1179 {
1180 void *sdi_capture;
1181 if (!s->audio_capture_device)
1182 return;
1184 return;
1185
1188}
struct video_frame * frame
unsigned int audio_capture_get_vidcap_flags(const char *const_device_name)
void * audio_capture_get_state_pointer(struct state_audio_capture *s)
const char * audio_capture_get_driver_name(struct state_audio_capture *s)
void sdi_capture_new_incoming_frame(void *state, struct audio_frame *frame)
Definition sdi.cpp:174

References state_audio::audio_capture_device, audio_capture_get_driver_name(), audio_capture_get_state_pointer(), audio_capture_get_vidcap_flags(), frame, and sdi_capture_new_incoming_frame().

Referenced by capture_thread().

Here is the call graph for this function:

◆ audio_sender_process_message()

static struct response * audio_sender_process_message ( struct state_audio * s,
struct msg_sender * msg )
static

Definition at line 866 of file audio.cpp.

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}
#define MSG(l, fmt,...)
Definition debug.h:96
@ 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_BAD_REQUEST
Definition messaging.h:60
uint32_t rtp_my_ssrc(struct rtp *session)
Definition rtp.c:1401
static fec * create_from_config(const char *str, bool is_audio) noexcept
Definition fec.cpp:62
bool muted_sender
Definition audio.cpp:182
fec * fec_state
Definition audio.cpp:163

References state_audio::audio_network_device, state_audio::audio_tx_mode, fec::create_from_config(), exit_uv(), state_audio::fec_state, initialize_audio_network(), LOG, LOG_LEVEL_ERROR, LOG_LEVEL_NOTICE, log_msg(), MODE_SENDER, MSG, state_audio::muted_sender, new_response(), RESPONSE_BAD_REQUEST, RESPONSE_INT_SERV_ERR, RESPONSE_OK, rtp_done(), rtp_my_ssrc(), SENDER_MSG_CHANGE_FEC, SENDER_MSG_CHANGE_PORT, SENDER_MSG_CHANGE_RECEIVER, SENDER_MSG_GET_STATUS, SENDER_MSG_MUTE, SENDER_MSG_MUTE_TOGGLE, SENDER_MSG_QUERY_VIDEO_MODE, SENDER_MSG_RESET_SSRC, and SENDER_MSG_UNMUTE.

Referenced by audio_done(), and audio_sender_thread().

Here is the call graph for this function:

◆ audio_sender_thread()

static void * audio_sender_thread ( void * arg)
static

Definition at line 1072 of file audio.cpp.

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}
static int find_codec_sample_rate(int sample_rate, const int *supported)
Definition audio.cpp:1026
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
static void process_statistics(struct state_audio *s, audio_frame2 *buffer)
Definition audio.cpp:1005
struct audio_frame * audio_capture_read(struct state_audio_capture *s)
af_result_code filter(struct audio_frame **frame)
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
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 jack_send(void *state, struct audio_frame *frame)
Definition jack.c:355
bool rtcp_recv_r(struct rtp *session, struct timeval *timeout, uint32_t curr_rtp_ts)
Definition rtp.c:2398
int data_len
Definition types.h:103
virtual std::shared_ptr< video_frame > encode(std::shared_ptr< video_frame >)=0
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

References state_audio::audio_capture_device, audio_capture_read(), audio_codec_compress(), audio_codec_get_supported_samplerates(), state_audio::audio_encoder, state_audio::audio_network_device, state_audio::audio_sender_module, audio_sender_process_message(), state_audio::audio_tx_mode, audio_tx_send(), audio_tx_send_standard(), audio_frame2::change_bps(), check_message(), audio_frame::data, audio_frame::data_len, echo_cancel(), state_audio::echo_state, fec::encode(), exit_uv(), export_audio(), state_audio::exporter, state_audio::fec_state, Filter_chain::filter(), state_audio::filter_chain, find_codec_sample_rate(), free_message(), audio_frame2::get_bps(), audio_frame2::get_sample_rate(), get_time_in_ns(), state_audio::jack_connection, jack_send(), LOG_LEVEL_ERROR, log_msg(), MOD_NAME, MODE_RECEIVER, msg, state_audio::muted_sender, NET_NATIVE, NET_STANDARD, process_statistics(), audio_frame2::resample(), state_audio::resample_to, rtcp_recv_r(), rtp_send_ctrl(), rtp_update(), state_audio::sender, set_audio_spec_to_vrxtx(), set_thread_name(), state_audio::should_exit, state_audio::start_time, ts, state_audio::tx_session, and state_audio::vrxtx.

Referenced by audio_start().

Here is the call graph for this function:

◆ audio_start()

void audio_start ( struct state_audio * s)

Definition at line 463 of file audio.cpp.

463 {
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}
static void * audio_sender_thread(void *arg)
Definition audio.cpp:1072
static void * audio_receiver_thread(void *arg)
Definition audio.cpp:695
#define LOG_LEVEL_FATAL
errors that prevent UG run
Definition debug.h:58
#define EXIT_FAIL_AUDIO
Definition host.h:70
void * jack_start(const char *cfg)
Definition jack.c:264
int is_jack_receiver(void *state)
Definition jack.c:426
int is_jack_sender(void *state)
Definition jack.c:421

References audio_receiver_thread(), state_audio::audio_receiver_thread_id, audio_sender_thread(), state_audio::audio_sender_thread_id, state_audio::audio_tx_mode, EXIT_FAIL_AUDIO, exit_uv(), is_jack_receiver(), is_jack_sender(), state_audio::jack_connection, jack_start(), LOG_LEVEL_FATAL, log_msg(), MODE_RECEIVER, MODE_SENDER, NET_JACK, NET_NATIVE, state_audio::proto_cfg, state_audio::receiver, and state_audio::sender.

Referenced by main(), vidcap_ug_input_init(), and write_video_frame().

Here is the call graph for this function:

◆ audio_update_recv_buf()

static void audio_update_recv_buf ( struct state_audio * s,
size_t curr_frame_len )
static

Definition at line 684 of file audio.cpp.

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}
#define LOG_LEVEL_DEBUG
Definition kernels.cu:48
bool rtp_set_recv_buf(struct rtp *session, int bufsize)
Definition rtp.c:3938
size_t recv_buf_size
Definition audio.cpp:184

References state_audio::audio_network_device, LOG, LOG_LEVEL_DEBUG, state_audio::recv_buf_size, and rtp_set_recv_buf().

Referenced by audio_receiver_thread().

Here is the call graph for this function:

◆ find_codec_sample_rate()

static int find_codec_sample_rate ( int sample_rate,
const int * supported )
static

Definition at line 1026 of file audio.cpp.

1026 {
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}
int int int sample_rate

References sample_rate.

Referenced by audio_sender_thread().

◆ initialize_audio_network()

static struct rtp * initialize_audio_network ( struct audio_network_parameters * params)
static

Definition at line 547 of file audio.cpp.

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}
#define DEFAULT_AUDIO_RECV_BUF_SIZE
Definition audio.cpp:109
#define FALSE
#define IN6_BLACKHOLE_SERVER_MODE_STR
Definition net.h:52
int pdb_add(struct pdb *db, uint32_t ssrc)
Definition pdb.c:299
bool rtp_set_option(struct rtp *session, rtp_option optname, int optval)
Definition rtp.c:1308
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
bool rtp_set_sdes(struct rtp *session, uint32_t ssrc, rtcp_sdes_type type, const char *value, int length)
Definition rtp.c:2546
@ 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)
double rtcp_bw
Definition rtp.c:297

References DEFAULT_AUDIO_RECV_BUF_SIZE, FALSE, IN6_BLACKHOLE_SERVER_MODE_STR, pdb_add(), rtp::rtcp_bw, RTCP_SDES_TOOL, rtp_init_if(), rtp_my_ssrc(), RTP_OPT_PROMISC, RTP_OPT_RECORD_SOURCE, RTP_OPT_SEND_BACK, RTP_OPT_WEAK_VALIDATION, rtp_recv_callback(), rtp_set_option(), rtp_set_recv_buf(), rtp_set_sdes(), and TRUE.

Referenced by audio_init(), audio_receiver_process_message(), and audio_sender_process_message().

Here is the call graph for this function:

◆ operator<<()

std::ostream & operator<< ( std::ostream & os,
const audio_desc & desc )

Definition at line 1215 of file audio.cpp.

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}
struct video_desc desc
const char * get_name_to_audio_codec(audio_codec_t codec)
Definition codec.cpp:450

References desc, and get_name_to_audio_codec().

Here is the call graph for this function:

◆ process_statistics()

static void process_statistics ( struct state_audio * s,
audio_frame2 * buffer )
static

Definition at line 1005 of file audio.cpp.

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}
static void * asend_compute_and_print_stats(void *arg)
Definition audio.cpp:979
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
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
audio_frame2 captured
Definition audio.cpp:160
time_ns_t t0
Definition audio.cpp:158
void task_run_async_detached(runnable_t task, void *data)
Runs task asynchronously in a detached state.
Definition worker.cpp:275

References audio_frame2::append(), asend_compute_and_print_stats(), state_audio::captured, audio_frame2::get_bps(), audio_frame2::get_channel_count(), audio_frame2::get_codec(), audio_frame2::get_sample_rate(), get_time_in_ns(), audio_frame2::has_same_prop_as(), audio_frame2::init(), state_audio::muted_sender, NS_IN_SEC, asend_stats_processing_data::seconds, state_audio::t0, and task_run_async_detached().

Referenced by audio_sender_thread().

Here is the call graph for this function:

◆ sdp_send_change_address_message()

void sdp_send_change_address_message ( struct module * root,
const enum module_class * path,
const char * address )

Definition at line 238 of file audio.cpp.

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}
static void new_message(struct module *m)
void append_message_path(char *buf, int buflen, const enum module_class *modules)
Definition module.c:187
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.
void free_response(struct response *r)

References append_message_path(), free_response(), LOG, LOG_LEVEL_NOTICE, LOG_LEVEL_WARNING, new_message(), response_get_status(), RESPONSE_OK, send_message(), and SENDER_MSG_CHANGE_RECEIVER.

Referenced by h264_sdp_video_rxtx::change_address_callback(), and sdp_change_address_callback().

Here is the call graph for this function:

◆ set_audio_spec_to_vrxtx()

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 )
static

Definition at line 1053 of file audio.cpp.

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}
struct audio_desc get_desc() const
Definition types.cpp:205
int rtp_get_udp_rx_port(struct rtp *session)
Definition rtp.c:4042
bool rtp_is_ipv6(struct rtp *session)
Definition rtp.c:4022
virtual void set_audio_spec(const struct audio_desc *desc, int audio_rx_port, int audio_tx_port, bool ipv6)
const char * audio_desc_to_cstring(struct audio_desc desc)
Definition utils.cpp:644

References audio_desc_to_cstring(), desc, audio_frame2::get_desc(), MSG, rtp_get_udp_rx_port(), rtp_is_ipv6(), and video_rxtx::set_audio_spec().

Referenced by audio_sender_thread().

Here is the call graph for this function:

◆ should_exit_audio()

static void should_exit_audio ( void * state)
static

Definition at line 232 of file audio.cpp.

232 {
233 auto *s = (struct state_audio *) state;
234 s->should_exit = true;
235}

References state.

Referenced by audio_done(), and audio_init().