UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
audio_decoders.cpp File Reference
#include "src/rtp/audio_decoders.h"
#include <algorithm>
#include <atomic>
#include <cassert>
#include <chrono>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "audio/audio_playback.h"
#include "audio/codec.h"
#include "audio/resampler.hpp"
#include "audio/types.h"
#include "audio/utils.h"
#include "compat/htonl.h"
#include "compat/strings.h"
#include "control_socket.h"
#include "crypto/openssl_decrypt.h"
#include "crypto/openssl_encrypt.h"
#include "debug.h"
#include "host.h"
#include "lib_common.h"
#include "messaging.h"
#include "module.h"
#include "rtp/fec.h"
#include "rtp/pbuf.h"
#include "rtp/rtp.h"
#include "rtp/rtp_types.h"
#include "tv.h"
#include "types.h"
#include "ug_runtime_error.hpp"
#include "utils/color_out.h"
#include "utils/macros.h"
#include "utils/packet_counter.h"
#include "utils/worker.h"
Include dependency graph for audio_decoders.cpp:

Go to the source code of this file.

Classes

struct  adec_stats_processing_data
 
struct  scale_data
 
struct  state_audio_decoder
 
struct  state_audio_decoder_summary
 

Macros

#define AUDIO_DECODER_MAGIC   0x12ab332bu
 
#define MOD_NAME   "[audio dec.] "
 

Functions

 ADD_TO_PARAM ("audio-dec-format", "* audio-dec-format=<fmt>|help\n" " Forces specified format playback format.\n")
 
 ADD_TO_PARAM ("soft-resample", "* soft-resample=<num>/<den>\n" " Resample to specified sampling rate, eg. 12288128/256 for 48000.5 Hz\n")
 
static void * adec_compute_and_print_stats (void *arg)
 
void audio_decoder_destroy (void *state)
 
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)
 
static void audio_decoder_process_message (struct module *m)
 
static bool audio_decoder_reconfigure (struct state_audio_decoder *decoder, struct pbuf_audio_data *s, audio_frame2 &received_frame, int input_channels, int bps, int sample_rate, uint32_t audio_tag)
 
void audio_decoder_set_volume (void *state, double val)
 
static bool audio_fec_decode (struct pbuf_audio_data *s, vector< pair< vector< char >, map< int, int > > > &fec_data, uint32_t fec_params, audio_frame2 &received_frame)
 
static void compute_scale (struct scale_data *scale_data, double vol_avg, int samples, int sample_rate)
 
int decode_audio_frame (struct coded_data *cdata, void *pbuf_data, struct pbuf_stats *)
 
int decode_audio_frame_mulaw (struct coded_data *cdata, void *data, struct pbuf_stats *)
 
bool parse_audio_hdr (uint32_t *hdr, struct audio_desc *desc)
 

Variables

constexpr double VOL_DOWN = 1.0/1.1
 
constexpr double VOL_UP = 1.1
 

Detailed Description

Macro Definition Documentation

◆ AUDIO_DECODER_MAGIC

#define AUDIO_DECODER_MAGIC   0x12ab332bu

Definition at line 96 of file audio_decoders.cpp.

Referenced by audio_decoder_destroy(), and audio_decoder_init().

◆ MOD_NAME

#define MOD_NAME   "[audio dec.] "

Function Documentation

◆ ADD_TO_PARAM() [1/2]

ADD_TO_PARAM ( "audio-dec-format" )

◆ ADD_TO_PARAM() [2/2]

ADD_TO_PARAM ( "soft-resample" ,
"* soft- resample = <num>/<den>\n" "  Resample to specified sampling rate,
eg. 12288128/256 for 48000.5 Hz\n"  )

◆ adec_compute_and_print_stats()

static void * adec_compute_and_print_stats ( void * arg)
static

Definition at line 377 of file audio_decoders.cpp.

377 {
378 auto d = (struct adec_stats_processing_data*) arg;
379 string loss;
380 if (d->bytes_received < d->bytes_expected) {
381 loss = " (" + to_string(d->bytes_expected - d->bytes_received) + " lost)";
382 }
383 log_msg(LOG_LEVEL_INFO, "[Audio decoder] Received %ld/%ld B%s, "
384 "decoded %d samples in %.2f sec.\n",
385 d->bytes_received,
386 d->bytes_expected,
387 loss.c_str(),
388 d->frame.get_sample_count(),
389 d->seconds);
390
391 char volume[STR_LEN];
392 char *vol_start = volume;
393 for (int i = 0; i < d->frame.get_channel_count(); ++i) {
394 double rms = 0.0;
395 double peak = 0.0;
396 rms = calculate_rms(&d->frame, i, &peak);
397 format_audio_channel_volume(i, rms, peak,
399 &vol_start, volume + sizeof volume);
400 }
401
402 log_msg(LOG_LEVEL_INFO, "[Audio decoder] Volume: %s dBFS RMS/peak%s\n",
403 volume, d->muted_receiver ? TBOLD(TRED(" (muted)")) : "");
404
405 delete d;
406
407 return NULL;
408}
#define TERM_BOLD
Definition color_out.h:48
#define TRED(x)
Definition color_out.h:75
#define TBOLD(x)
Definition color_out.h:70
#define TERM_FG_MAGENTA
Definition color_out.h:54
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
static struct @51 loss[MAX_HISTORY]
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(), loss, STR_LEN, TBOLD, TERM_BOLD, TERM_FG_MAGENTA, and TRED.

Referenced by decode_audio_frame().

Here is the call graph for this function:

◆ audio_decoder_destroy()

void audio_decoder_destroy ( void * state)

Definition at line 338 of file audio_decoders.cpp.

339{
340 struct state_audio_decoder *s = (struct state_audio_decoder *) state;
341
342 assert(s != NULL);
343 assert(s->magic == AUDIO_DECODER_MAGIC);
344
347
348 if (s->dec_funcs) {
349 s->dec_funcs->destroy(s->decrypt);
350 }
351
352 delete s->fec_state;
353 module_done(&s->mod);
354 delete s;
355}
void ** state
#define AUDIO_DECODER_MAGIC
void audio_codec_done(struct audio_codec_state *s)
Definition codec.cpp:372
void module_done(struct module *module_data)
Definition module.c:93
void packet_counter_destroy(struct packet_counter *state)
void(* destroy)(struct openssl_decrypt *state)
struct audio_codec_state * audio_decompress
struct packet_counter * packet_counter
struct openssl_decrypt * decrypt
const struct openssl_decrypt_info * dec_funcs

References audio_codec_done(), AUDIO_DECODER_MAGIC, state_audio_decoder::audio_decompress, state_audio_decoder::dec_funcs, state_audio_decoder::decrypt, openssl_decrypt_info::destroy, state_audio_decoder::fec_state, state_audio_decoder::magic, state_audio_decoder::mod, module_done(), state_audio_decoder::packet_counter, packet_counter_destroy(), and state.

Referenced by audio_decoder_init(), and audio_decoder_state_deleter().

Here is the call graph for this function:

◆ audio_decoder_init()

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 )

Definition at line 238 of file audio_decoders.cpp.

239{
240 struct state_audio_decoder *s = NULL;
241 bool scale_auto = false;
242 double scale_factor = 1.0;
243 char *tmp = nullptr;
244
245 assert(audio_scale != NULL);
246
247 try {
248 s = new struct state_audio_decoder();
249 } catch (ug_runtime_error &e) {
250 log_msg(LOG_LEVEL_ERROR, MOD_NAME "%s\n", e.what());
251 goto error;
252 }
253
256 s->audio_playback_state = p_state;
257
260 s->mod.priv_data = s;
263
264 if (const char *val = get_commandline_param("soft-resample")) {
265 assert(strchr(val, '/') != nullptr);
266 s->req_resample_to = strtoll(val, NULL, 0) << 32LLU | strtoll(strchr(val, '/') + 1, NULL, 0);
267 }
268
269 gettimeofday(&s->t0, NULL);
271
272 s->audio_decompress = NULL;
273
274 s->control = (struct control_state *) get_module(get_root_module(parent), "control");
275
276 if (strlen(encryption) > 0) {
277 s->dec_funcs = static_cast<const struct openssl_decrypt_info *>(load_library("openssl_decrypt",
279 if (!s->dec_funcs) {
280 log_msg(LOG_LEVEL_ERROR, "This UltraGrid version was build "
281 "without OpenSSL support!\n");
282 delete s;
283 return NULL;
284 }
285 if (s->dec_funcs->init(&s->decrypt, encryption) != 0) {
286 log_msg(LOG_LEVEL_ERROR, "Unable to create decompress!\n");
287 delete s;
288 return NULL;
289 }
290 }
291
292 if(audio_channel_map) {
293 if (!parse_channel_map_cfg(&s->channel_map, audio_channel_map)) {
294 goto error;
295 }
296 s->channel_remapping = true;
297 } else {
298 s->channel_remapping = false;
299 s->channel_map.map = NULL;
300 s->channel_map.sizes = NULL;
301 s->channel_map.size = 0;
302 }
303
304 if(strcasecmp(audio_scale, "mixauto") == 0) {
305 if(s->channel_remapping) {
306 log_msg(LOG_LEVEL_WARNING, MOD_NAME "Channel remapping detected - automatically scaling audio levels. Use \"--audio-scale none\" to disable.\n");
307 scale_auto = true;
308 } else {
309 scale_auto = false;
310 }
311 } else if(strcasecmp(audio_scale, "auto") == 0) {
312 scale_auto = true;
313 } else if(strcasecmp(audio_scale, "none") == 0) {
314 scale_auto = false;
315 scale_factor = 1.0;
316 } else {
317 scale_auto = false;
318 scale_factor = atof(audio_scale);
319 if(scale_factor <= 0.0) {
320 log_msg(LOG_LEVEL_ERROR, "Invalid audio scaling factor!\n");
321 goto error;
322 }
323 }
324
325 s->fixed_scale = scale_auto ? false : true;
326 s->scale.at(0).scale = scale_factor;
327
328 return s;
329
330error:
331 free(tmp);
332 if (s) {
334 }
335 return NULL;
336}
int void * val
void audio_decoder_destroy(void *state)
#define MOD_NAME
static void audio_decoder_process_message(struct module *m)
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
void module_init_default(struct module *module_data)
Definition module.c:48
void module_register(struct module *module_data, struct module *parent)
Definition module.c:82
struct module * get_module(struct module *root, const char *const_path)
Definition module.c:264
struct module * get_root_module(struct module *node)
Definition module.c:203
@ MODULE_CLASS_DECODER
Definition module.h:95
const char * get_commandline_param(const char *key)
Definition host.cpp:894
const void * load_library(const char *name, enum library_class cls, int abi_version)
@ LIBRARY_CLASS_UNDEFINED
Definition lib_common.h:74
#define OPENSSL_DECRYPT_ABI_VERSION
struct packet_counter * packet_counter_init(int num_substreams)
const char * parent
Definition settings.cpp:198
int * sizes
Definition utils.h:171
int size
Definition utils.h:173
int ** map
Definition utils.h:170
enum module_class cls
Definition module.h:115
void * priv_data
Definition module.h:126
notify_t new_message
if set, notifies module that new message is in queue, receiver lock is hold during the call
Definition module.h:119
int(* init)(struct openssl_decrypt **state, const char *passphrase)
vector< struct scale_data > scale
contains scaling metadata if we want to perform audio scaling
std::atomic_uint64_t req_resample_to
struct control_state * control
struct channel_map channel_map
audio_playback_ctl_t audio_playback_ctl_func
unsigned int channel_remapping
bool parse_channel_map_cfg(struct channel_map *channel_map, const char *cfg)
Definition utils.cpp:716

References audio_decoder_destroy(), AUDIO_DECODER_MAGIC, audio_decoder_process_message(), state_audio_decoder::audio_decompress, state_audio_decoder::audio_playback_ctl_func, state_audio_decoder::audio_playback_state, state_audio_decoder::channel_map, state_audio_decoder::channel_remapping, module::cls, state_audio_decoder::control, state_audio_decoder::dec_funcs, state_audio_decoder::decrypt, state_audio_decoder::fixed_scale, get_commandline_param(), get_module(), get_root_module(), openssl_decrypt_info::init, LIBRARY_CLASS_UNDEFINED, load_library(), LOG_LEVEL_ERROR, LOG_LEVEL_WARNING, log_msg(), state_audio_decoder::magic, channel_map::map, state_audio_decoder::mod, MOD_NAME, MODULE_CLASS_DECODER, module_init_default(), module_register(), module::new_message, OPENSSL_DECRYPT_ABI_VERSION, state_audio_decoder::packet_counter, packet_counter_init(), parent, parse_channel_map_cfg(), module::priv_data, state_audio_decoder::req_resample_to, state_audio_decoder::scale, channel_map::size, channel_map::sizes, state_audio_decoder::t0, and val.

Referenced by audio_decoder_state_create().

Here is the call graph for this function:

◆ audio_decoder_process_message()

static void audio_decoder_process_message ( struct module * m)
static

Definition at line 218 of file audio_decoders.cpp.

219{
220 auto *s = static_cast<struct state_audio_decoder *>(m->priv_data);
221
222 while (auto *msg = reinterpret_cast<msg_universal *>(check_message(m))) {
223 struct response *r = nullptr;
224 if (strstr(msg->text, MSG_UNIVERSAL_TAG_AUDIO_DECODER) == msg->text) {
225 s->req_resample_to = strtoull(msg->text + strlen(MSG_UNIVERSAL_TAG_AUDIO_DECODER), nullptr, 0);
226 LOG(LOG_LEVEL_VERBOSE) << MOD_NAME << "Resampling sound to: " << (s->req_resample_to >> ADEC_CH_RATE_SHIFT) << "/" << (s->req_resample_to & ((1LLU << ADEC_CH_RATE_SHIFT) - 1)) << "\n";
227 r = new_response(RESPONSE_OK, nullptr);
228 } else {
229 r = new_response(RESPONSE_NOT_FOUND, nullptr);
230 }
231 free_message(reinterpret_cast<message *>(msg), r);
232 }
233}
#define ADEC_CH_RATE_SHIFT
#define MSG_UNIVERSAL_TAG_AUDIO_DECODER
#define LOG_LEVEL_VERBOSE
Definition debug.h:63
#define LOG(level)
Definition debug.h:313
void free_message(struct message *msg, struct response *r)
struct response * new_response(int status, const char *text)
struct message * check_message(struct module *mod)
#define RESPONSE_OK
Definition messaging.h:57
#define RESPONSE_NOT_FOUND
Definition messaging.h:61

References ADEC_CH_RATE_SHIFT, check_message(), free_message(), LOG, LOG_LEVEL_VERBOSE, MOD_NAME, MSG_UNIVERSAL_TAG_AUDIO_DECODER, new_response(), module::priv_data, RESPONSE_NOT_FOUND, and RESPONSE_OK.

Referenced by audio_decoder_init().

Here is the call graph for this function:

◆ audio_decoder_reconfigure()

static bool audio_decoder_reconfigure ( struct state_audio_decoder * decoder,
struct pbuf_audio_data * s,
audio_frame2 & received_frame,
int input_channels,
int bps,
int sample_rate,
uint32_t audio_tag )
static

Compares provided parameters with previous configuration and if it differs, reconfigure the decoder, otherwise the reconfiguration is skipped.

Definition at line 417 of file audio_decoders.cpp.

418{
419 if(decoder->saved_desc.ch_count == input_channels &&
420 decoder->saved_desc.bps == bps &&
421 decoder->saved_desc.sample_rate == sample_rate &&
422 decoder->saved_audio_tag == audio_tag) {
423 return true;
424 }
425
426 log_msg(LOG_LEVEL_NOTICE, "New incoming audio format detected: %d Hz, %d channel%s, %d bits per sample, codec %s\n",
427 sample_rate, input_channels, input_channels == 1 ? "": "s", bps * 8,
429
430 if(decoder->channel_remapping && decoder->channel_map.size > input_channels){
431 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Audio channel map references channels with idx higher than ch. count!\n");
432 }
433
434 int output_channels = decoder->channel_remapping ?
435 decoder->channel_map.max_output + 1: input_channels;
436 audio_desc device_desc = audio_desc{bps, sample_rate, output_channels, AC_PCM};
437 if (const char *fmt = get_commandline_param("audio-dec-format")) {
438 if (int ret = parse_audio_format(fmt, &device_desc)) {
439 exit_uv(ret > 0 ? 0 : 1);
440 return false;
441 }
442 }
443 size_t len = sizeof device_desc;
444 if (!decoder->audio_playback_ctl_func(decoder->audio_playback_state, AUDIO_PLAYBACK_CTL_QUERY_FORMAT, &device_desc, &len)) {
445 log_msg(LOG_LEVEL_ERROR, "Unable to query audio desc!\n");
446 return false;
447 }
448
449 s->buffer.bps = device_desc.bps;
450 s->buffer.ch_count = device_desc.ch_count;
451 s->buffer.sample_rate = device_desc.sample_rate;
452
453 if(!decoder->fixed_scale) {
454 decoder->scale.clear();
455 int scale_count = decoder->channel_remapping ? decoder->channel_map.max_output + 1: decoder->saved_desc.ch_count;
456 decoder->scale.resize(scale_count);
457 }
458 decoder->saved_desc.ch_count = input_channels;
459 decoder->saved_desc.bps = bps;
461 decoder->saved_audio_tag = audio_tag;
462 audio_codec_t audio_codec = get_audio_codec_to_tag(audio_tag);
463
464 received_frame.init(input_channels, audio_codec, bps, sample_rate);
465 decoder->decoded.init(input_channels, AC_PCM,
466 device_desc.bps, device_desc.sample_rate);
467 decoder->decoded.reserve(device_desc.bps * device_desc.sample_rate * 6);
468
470 if(!decoder->audio_decompress) {
471 log_msg(LOG_LEVEL_FATAL, "Unable to create audio decompress!\n");
472 exit_uv(1);
473 return false;
474 }
475
476 decoder->resample_remainder = {};
477 return true;
478}
int int int sample_rate
const char * fmt
int void size_t * len
audio_codec_t
Definition types.h:51
@ AC_PCM
Definition types.h:53
#define AUDIO_PLAYBACK_CTL_QUERY_FORMAT
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
void reserve(size_t len)
Definition types.cpp:161
audio_codec_t get_audio_codec_to_tag(uint32_t tag)
Definition codec.cpp:460
const char * get_name_to_audio_codec(audio_codec_t codec)
Definition codec.cpp:450
struct audio_codec_state * audio_codec_reconfigure(struct audio_codec_state *old, audio_codec_t audio_codec, audio_codec_direction_t direction)
Definition codec.cpp:225
@ AUDIO_DECODER
Definition codec.h:47
#define LOG_LEVEL_NOTICE
information that may be interesting
Definition debug.h:61
#define LOG_LEVEL_FATAL
errors that prevent UG run
Definition debug.h:58
void exit_uv(int status)
Definition host.cpp:625
int sample_rate
Definition types.h:78
int ch_count
Definition types.h:79
int bps
Definition types.h:77
int sample_rate
Definition types.h:101
int ch_count
Definition types.h:104
int bps
Definition types.h:100
int max_output
Definition utils.h:174
audio_frame buffer
Definition pbuf.h:99
audio_frame2 resample_remainder
audio_frame2 decoded
buffer that keeps audio samples from last 5 seconds (for statistics)
struct audio_desc saved_desc
int parse_audio_format(const char *str, struct audio_desc *ret)
Definition utils.cpp:655

References AC_PCM, audio_codec_reconfigure(), AUDIO_DECODER, state_audio_decoder::audio_decompress, state_audio_decoder::audio_playback_ctl_func, AUDIO_PLAYBACK_CTL_QUERY_FORMAT, state_audio_decoder::audio_playback_state, audio_desc::bps, audio_frame::bps, pbuf_audio_data::buffer, audio_desc::ch_count, audio_frame::ch_count, state_audio_decoder::channel_map, state_audio_decoder::channel_remapping, state_audio_decoder::decoded, exit_uv(), state_audio_decoder::fixed_scale, fmt, get_audio_codec_to_tag(), get_commandline_param(), get_name_to_audio_codec(), audio_frame2::init(), len, LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LOG_LEVEL_NOTICE, log_msg(), channel_map::max_output, MOD_NAME, parse_audio_format(), state_audio_decoder::resample_remainder, audio_frame2::reserve(), audio_desc::sample_rate, audio_frame::sample_rate, sample_rate, state_audio_decoder::saved_audio_tag, state_audio_decoder::saved_desc, state_audio_decoder::scale, and channel_map::size.

Referenced by audio_fec_decode(), and decode_audio_frame().

Here is the call graph for this function:

◆ audio_decoder_set_volume()

void audio_decoder_set_volume ( void * state,
double val )

Definition at line 881 of file audio_decoders.cpp.

882{
883 auto s = (struct state_audio_decoder *) state;
884 for (auto & i : s->scale) {
885 i.scale = val;
886 }
887 s->muted = val == 0.0;
888}

References state, and val.

Referenced by audio_decoder_state_create(), and audio_receiver_process_message().

◆ audio_fec_decode()

static bool audio_fec_decode ( struct pbuf_audio_data * s,
vector< pair< vector< char >, map< int, int > > > & fec_data,
uint32_t fec_params,
audio_frame2 & received_frame )
static

Definition at line 480 of file audio_decoders.cpp.

481{
482 struct state_audio_decoder *decoder = s->decoder;
483 fec_desc fec_desc { FEC_RS, fec_params >> 19U, (fec_params >> 6U) & 0x1FFFU, fec_params & 0x3F };
484
485 if (decoder->fec_state == NULL || decoder->fec_state_desc.k != fec_desc.k || decoder->fec_state_desc.m != fec_desc.m || decoder->fec_state_desc.c != fec_desc.c) {
486 delete decoder->fec_state;
488 if (decoder->fec_state == nullptr) {
489 LOG(LOG_LEVEL_ERROR) << MOD_NAME << "Cannot initialize FEC decoder!\n";
490 return false;
491 }
492 decoder->fec_state_desc = fec_desc;
493 }
494
496
497 int channel = 0;
498 for (auto & c : fec_data) {
499 char *out = nullptr;
500 int out_len = 0;
501 if (decoder->fec_state->decode(c.first.data(), c.first.size(), &out, &out_len, c.second)) {
502 assert(out_len >= (int) sizeof(audio_payload_hdr_t));
503 if (!desc) {
504 uint32_t quant_sample_rate = 0;
505 uint32_t audio_tag = 0;
506
507 memcpy(&quant_sample_rate, out + 3 * sizeof(uint32_t), sizeof(uint32_t));
508 memcpy(&audio_tag, out + 4 * sizeof(uint32_t), sizeof(uint32_t));
509 quant_sample_rate = ntohl(quant_sample_rate);
510 audio_tag = ntohl(audio_tag);
511
512 desc.bps = (quant_sample_rate >> 26) / 8;
513 desc.sample_rate = quant_sample_rate & 0x07FFFFFFU;
514 desc.ch_count = fec_data.size();
515 desc.codec = get_audio_codec_to_tag(audio_tag);
516 if (!desc.codec) {
517 auto flags = std::clog.flags();
518 LOG(LOG_LEVEL_ERROR) << MOD_NAME << "Wrong AudioTag 0x" << hex << audio_tag << "\n";
519 std::clog.flags(flags);
520 }
521
522 if (!audio_decoder_reconfigure(decoder, s, received_frame, desc.ch_count, desc.bps, desc.sample_rate, audio_tag)) {
523 return false;
524 }
525 }
526 received_frame.replace(channel, 0, out + sizeof(audio_payload_hdr_t), out_len - sizeof(audio_payload_hdr_t));
527 }
528 channel += 1;
529 }
530
531 return true;
532}
struct video_desc desc
const char unsigned int flags
static bool audio_decoder_reconfigure(struct state_audio_decoder *decoder, struct pbuf_audio_data *s, audio_frame2 &received_frame, int input_channels, int bps, int sample_rate, uint32_t audio_tag)
void replace(int channel, size_t offset, const char *data, size_t length)
replaces portion of data of specified channel. If the size of the channel is not sufficient,...
Definition types.cpp:152
uint32_t audio_payload_hdr_t[5]
Definition rtp_types.h:129
unsigned int k
Definition types.h:209
unsigned int m
Definition types.h:209
unsigned int c
Definition types.h:209
static fec * create_from_desc(struct fec_desc) noexcept
Definition fec.cpp:107
virtual bool decode(char *in, int in_len, char **out, int *out_len, const std::map< int, int > &)=0
struct state_audio_decoder * decoder
Definition pbuf.h:101
@ FEC_RS
Definition types.h:204

References audio_decoder_reconfigure(), fec_desc::c, fec::create_from_desc(), fec::decode(), pbuf_audio_data::decoder, desc, FEC_RS, state_audio_decoder::fec_state, state_audio_decoder::fec_state_desc, flags, get_audio_codec_to_tag(), fec_desc::k, LOG, LOG_LEVEL_ERROR, fec_desc::m, MOD_NAME, and audio_frame2::replace().

Referenced by decode_audio_frame().

Here is the call graph for this function:

◆ compute_scale()

static void compute_scale ( struct scale_data * scale_data,
double vol_avg,
int samples,
int sample_rate )
static

Definition at line 192 of file audio_decoders.cpp.

193{
194 scale_data->vol_avg = scale_data->vol_avg * (scale_data->samples / ((double) scale_data->samples + samples)) +
195 vol_avg * (samples / ((double) scale_data->samples + samples));
196 scale_data->samples += samples;
197
198 if (scale_data->samples > sample_rate * 6) {
199 double ratio = 1.0;
200
201 if (scale_data->vol_avg > 0.25 || (scale_data->vol_avg > 0.05 && scale_data->scale > 1.0)) {
202 ratio = VOL_DOWN;
203 } else if (scale_data->vol_avg < 0.20 && scale_data->scale < 1.0) {
204 ratio = VOL_UP;
205 }
206
207 scale_data->scale *= ratio;
208 scale_data->vol_avg *= ratio;
209
210 MSG(VERBOSE,
211 "Audio scale adjusted to: %f (average volume was %f)\n",
213
215 }
216}
constexpr double VOL_UP
constexpr double VOL_DOWN
#define MSG(l, fmt,...)
Definition debug.h:96

References MSG, sample_rate, scale_data::samples, scale_data::scale, scale_data::vol_avg, VOL_DOWN, and VOL_UP.

Referenced by decode_audio_frame().

◆ decode_audio_frame()

int decode_audio_frame ( struct coded_data * cdata,
void * pbuf_data,
struct pbuf_stats * stats )
Todo
do we really want to scale to expected buffer length even if some frames are missing at the end of the buffer
Todo
this will certainly result in a syscall, maybe use some pool?

Definition at line 534 of file audio_decoders.cpp.

535{
536 struct pbuf_audio_data *s = (struct pbuf_audio_data *) pbuf_data;
537 struct state_audio_decoder *decoder = s->decoder;
538
539 int input_channels = 0;
540
541 bool first = true;
542 int bufnum = 0;
543
544 if(!cdata) {
545 return false;
546 }
547
548 if (!cdata->data->m) {
549 // skip frame without m-bit, we cannot determine number of channels
550 // (it is maximal substream number + 1 in packet with m-bit)
551 return false;
552 }
553
554 DEBUG_TIMER_START(audio_decode);
555 audio_frame2 received_frame;
556 received_frame.init(decoder->saved_desc.ch_count,
558 decoder->saved_desc.bps,
559 decoder->saved_desc.sample_rate);
560 received_frame.set_timestamp(cdata->data->ts);
561 vector<pair<vector<char>, map<int, int>>> fec_data;
562 uint32_t fec_params = 0;
563
564 while (cdata != NULL) {
565 char *data;
566 // for definition see rtp_callbacks.h
567 uint32_t *audio_hdr = (uint32_t *)(void *) cdata->data->data;
568 const int pt = cdata->data->pt;
569 enum openssl_mode crypto_mode;
570
571 if (PT_AUDIO_IS_ENCRYPTED(pt)) {
572 if(!decoder->decrypt) {
573 log_msg(LOG_LEVEL_WARNING, "Receiving encrypted audio data but "
574 "no decryption key entered!\n");
575 return false;
576 }
577 } else if (PT_IS_AUDIO(pt) && !PT_AUDIO_IS_ENCRYPTED(pt)) {
578 if(decoder->decrypt) {
579 log_msg(LOG_LEVEL_WARNING, "Receiving unencrypted audio data "
580 "while expecting encrypted.\n");
581 return false;
582 }
583 } else {
584 if (pt == PT_Unassign_Type95) {
585 log_msg_once(LOG_LEVEL_WARNING, to_fourcc('U', 'V', 'P', 'T'), MOD_NAME "Unassigned PT 95 received, ignoring.\n");
586 } else {
587 log_msg(LOG_LEVEL_WARNING, "Unknown audio packet type: %d\n", pt);
588 }
589 return false;
590 }
591
592 unsigned int length;
593 char plaintext[RTP_MAX_PACKET_LEN]; // plaintext will be actually shorter
594 size_t main_hdr_len = PT_AUDIO_HAS_FEC(pt) ? sizeof(fec_payload_hdr_t) : sizeof(audio_payload_hdr_t);
595 if (PT_AUDIO_IS_ENCRYPTED(pt)) {
596 uint32_t encryption_hdr = ntohl(*(uint32_t *)(void *) (cdata->data->data + main_hdr_len));
597 crypto_mode = (enum openssl_mode) (encryption_hdr >> 24);
598 if (crypto_mode == MODE_AES128_NONE || crypto_mode > MODE_AES128_MAX) {
599 log_msg(LOG_LEVEL_WARNING, "Unknown cipher mode: %d\n", (int) crypto_mode);
600 return false;
601 }
602 char *ciphertext = cdata->data->data + sizeof(crypto_payload_hdr_t) +
603 main_hdr_len;
604 int ciphertext_len = cdata->data->data_len - main_hdr_len -
605 sizeof(crypto_payload_hdr_t);
606
607 if((length = decoder->dec_funcs->decrypt(decoder->decrypt,
608 ciphertext, ciphertext_len,
609 (char *) audio_hdr, sizeof(audio_payload_hdr_t),
610 plaintext, crypto_mode)) == 0) {
611 return false;
612 }
613 data = plaintext;
614 } else {
615 assert(PT_IS_AUDIO(pt));
616 length = cdata->data->data_len - main_hdr_len;
617 data = cdata->data->data + main_hdr_len;
618 }
619
620 /* we receive last channel first (with m bit, last packet) */
621 /* thus can be set only with m-bit packet */
622 if(cdata->data->m) {
623 input_channels = ((ntohl(audio_hdr[0]) >> 22) & 0x3ff) + 1;
624 }
625
626 // we have:
627 // 1) last packet, then we have just set total channels
628 // 2) not last, but the last one was processed at first
629 assert(input_channels > 0);
630
631 int channel = (ntohl(audio_hdr[0]) >> 22) & 0x3ff;
632 bufnum = ntohl(audio_hdr[0]) & ((1U<<BUFNUM_BITS) - 1U);
633 int sample_rate = ntohl(audio_hdr[3]) & 0x3fffff;
634 unsigned int offset = ntohl(audio_hdr[1]);
635 unsigned int buffer_len = ntohl(audio_hdr[2]);
636 //fprintf(stderr, "%d-%d-%d ", length, bufnum, channel);
637
638 if (packet_counter_get_channels(decoder->packet_counter) != input_channels) {
640 decoder->packet_counter = packet_counter_init(input_channels);
641 }
642
643 if (PT_AUDIO_HAS_FEC(pt)) {
644 fec_data.resize(input_channels);
645 fec_data[channel].first.resize(buffer_len);
646 fec_params = ntohl(audio_hdr[3]);
647 fec_data[channel].second[offset] = length;
648 memcpy(fec_data[channel].first.data() + offset, data, length);
649 } else {
650 int bps = (ntohl(audio_hdr[3]) >> 26) / 8;
651 uint32_t audio_tag = ntohl(audio_hdr[4]);
652
653 if (!audio_decoder_reconfigure(decoder, s, received_frame, input_channels, bps, sample_rate, audio_tag)) {
654 return false;
655 }
656
657 received_frame.replace(channel, offset, data, length);
658
659 /* buffer size same for every packet of the frame */
662 received_frame.resize(channel, buffer_len);
663 }
664
665 packet_counter_register_packet(decoder->packet_counter, channel, bufnum, offset, length);
666
667 if (first) {
668 memcpy(&s->source, ((char *) cdata->data) + RTP_MAX_PACKET_LEN, sizeof(struct sockaddr_storage));
669 first = false;
670 }
671
672 cdata = cdata->nxt;
673 }
674
675 decoder->summary.update(bufnum);
676
677 if (fec_params != 0) {
678 if (!audio_fec_decode(s, fec_data, fec_params, received_frame)) {
679 return false;
680 }
681 }
682
683 s->frame_size = received_frame.get_data_len();
684 audio_frame2 decompressed = audio_codec_decompress(decoder->audio_decompress, &received_frame);
685 if (!decompressed) {
686 return false;
687 }
688
689 // Perform a variable rate resample if any output device has requested it
690 if (decoder->req_resample_to != 0 || s->buffer.sample_rate != decompressed.get_sample_rate()) {
691 int resampler_bps = decoder->resampler.align_bps(decompressed.get_bps());
692 if (resampler_bps <= 0) {
693 return false;
694 }
695 if (resampler_bps != decompressed.get_bps()) {
696 decompressed.change_bps(resampler_bps);
697 }
698 if (decoder->req_resample_to != 0) {
699 auto [ret, remainder] = decompressed.resample_fake(decoder->resampler, decoder->req_resample_to >> ADEC_CH_RATE_SHIFT, decoder->req_resample_to & ((1LLU << ADEC_CH_RATE_SHIFT) - 1));
700 if (!ret) {
701 LOG(LOG_LEVEL_INFO) << MOD_NAME << "You may try to set different sampling on sender.\n";
702 return false;
703 }
704 decoder->resample_remainder = std::move(remainder);
705 } else {
706 if (!decompressed.resample(decoder->resampler, s->buffer.sample_rate)) {
707 LOG(LOG_LEVEL_INFO) << MOD_NAME << "You may try to set different sampling on sender.\n";
708 return false;
709 }
710 }
711 }
712
713 if (decompressed.get_bps() != s->buffer.bps) {
714 decompressed.change_bps(s->buffer.bps);
715 }
716
717 size_t new_data_len = s->buffer.data_len + decompressed.get_data_len(0) * s->buffer.ch_count;
718 if ((size_t) s->buffer.max_size < new_data_len) {
719 s->buffer.max_size = new_data_len;
720 s->buffer.data = (char *) realloc(s->buffer.data, new_data_len);
721 }
722
723 memset(s->buffer.data + s->buffer.data_len, 0, new_data_len - s->buffer.data_len);
724
725 if (!decoder->muted) {
726 // there is a mapping for channel
727 for(int channel = 0; channel < decompressed.get_channel_count(); ++channel) {
728 if(decoder->channel_remapping) {
729 if(channel < decoder->channel_map.size) {
730 for(int i = 0; i < decoder->channel_map.sizes[channel]; ++i) {
731 int new_position = decoder->channel_map.map[channel][i];
732 if (new_position >= s->buffer.ch_count)
733 continue;
735 decompressed.get_data(channel),
736 decompressed.get_bps(), decompressed.get_data_len(channel),
737 s->buffer.ch_count, new_position,
738 decoder->scale.at(decoder->fixed_scale ? 0 : new_position).scale);
739 }
740 }
741 } else {
742 if (channel >= s->buffer.ch_count)
743 continue;
744 mux_and_mix_channel(s->buffer.data + s->buffer.data_len, decompressed.get_data(channel),
745 decompressed.get_bps(),
746 decompressed.get_data_len(channel), s->buffer.ch_count, channel,
747 decoder->scale.at(decoder->fixed_scale ? 0 : input_channels).scale);
748 }
749 }
750 }
751 s->buffer.data_len = new_data_len;
752 if (s->buffer.timestamp == -1) {
753 s->buffer.timestamp = decompressed.get_timestamp();
754 }
755
756 decoder->decoded.append(decompressed);
757
758 if (control_stats_enabled(decoder->control)) {
759 std::string report = "ARECV";
760 int num_ch = std::min(decompressed.get_channel_count(), control_audio_ch_report_count(decoder->control));
761 for(int i = 0; i < num_ch; i++){
762 double rms, peak;
763 rms = calculate_rms(&decompressed, i, &peak);
764 double rms_dbfs0 = 20 * log(rms) / log(10);
765 double peak_dbfs0 = 20 * log(peak) / log(10);
766 report += " volrms" + std::to_string(i) + " " + std::to_string(rms_dbfs0);
767 report += " volpeak" + std::to_string(i) + " " + std::to_string(peak_dbfs0);
768 }
769
770 control_report_stats(decoder->control, report);
771 }
772
773 double seconds;
774 struct timeval t;
775
776 gettimeofday(&t, 0);
777 seconds = tv_diff(t, decoder->t0);
778 if(seconds > 5.0) {
779 auto d = new adec_stats_processing_data;
780 d->frame.init(decoder->decoded.get_channel_count(), decoder->decoded.get_codec(), decoder->decoded.get_bps(), decoder->decoded.get_sample_rate());
783 d->frame.reserve(decoder->decoded.get_bps() * decoder->decoded.get_sample_rate() * 6);
784
785 std::swap(d->frame, decoder->decoded);
786 d->seconds = seconds;
787 d->bytes_received = packet_counter_get_total_bytes(decoder->packet_counter);
788 d->bytes_expected = packet_counter_get_all_bytes(decoder->packet_counter);
789 d->muted_receiver = decoder->muted;
790
792
793 decoder->t0 = t;
795 }
796
797 DEBUG_TIMER_START(audio_decode_compute_autoscale);
798 if(!decoder->fixed_scale) {
799 int output_channels = decoder->channel_remapping ?
800 decoder->channel_map.max_output + 1: input_channels;
801 for(int i = 0; i <= decoder->channel_map.max_output; ++i) {
802 if (decoder->channel_map.contributors[i] <= 1) {
803 continue;
804 }
805 double avg = get_avg_volume(s->buffer.data, s->buffer.bps,
806 s->buffer.data_len / output_channels / s->buffer.bps, output_channels, i);
807 compute_scale(&decoder->scale.at(i), avg,
808 s->buffer.data_len / output_channels / s->buffer.bps, s->buffer.sample_rate);
809 }
810 }
811 DEBUG_TIMER_STOP(audio_decode_compute_autoscale);
812 DEBUG_TIMER_STOP(audio_decode);
813
814 return true;
815}
static bool audio_fec_decode(struct pbuf_audio_data *s, vector< pair< vector< char >, map< int, int > > > &fec_data, uint32_t fec_params, audio_frame2 &received_frame)
static void compute_scale(struct scale_data *scale_data, double vol_avg, int samples, int sample_rate)
static void * adec_compute_and_print_stats(void *arg)
int align_bps(int orig)
void change_bps(int new_bps)
Definition types.cpp:313
void resize(int channel, size_t len)
Definition types.cpp:183
char * get_data(int channel)
Definition types.cpp:218
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
int64_t get_timestamp() const
Definition types.cpp:340
std::tuple< bool, audio_frame2 > resample_fake(audio_frame2_resampler &resampler_state, int new_sample_rate_num, int new_sample_rate_den)
@ resamples to new sample rate while keeping nominal sample rate intact
Definition types.cpp:342
void set_timestamp(int64_t ts)
Definition types.cpp:335
size_t get_data_len(int channel) const
Definition types.cpp:228
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 audio_codec_decompress(struct audio_codec_state *s, audio_frame2 *frame)
Definition codec.cpp:299
bool control_stats_enabled(struct control_state *s)
int control_audio_ch_report_count(struct control_state *state)
void control_report_stats(struct control_state *s, const std::string &report_line)
static __device__ const float offset
Definition cuda_dxt.cu:139
void log_msg_once(int level, uint32_t id, const char *msg,...)
Definition debug.cpp:137
#define DEBUG_TIMER_START(name)
Definition debug.h:324
#define DEBUG_TIMER_STOP(name)
Definition debug.h:325
#define to_fourcc(a, b, c, d)
Creates FourCC word.
Definition macros.h:114
openssl_mode
only GCM provides autenticity, other modes only check integrity (CRC)
@ MODE_AES128_NONE
@ MODE_AES128_MAX
int packet_counter_get_all_bytes(struct packet_counter *state)
int packet_counter_get_channels(struct packet_counter *state)
void packet_counter_clear(struct packet_counter *state)
int packet_counter_get_total_bytes(struct packet_counter *state)
void packet_counter_register_packet(struct packet_counter *state, unsigned int substream_id, unsigned int bufnum, unsigned int offset, unsigned int len)
#define RTP_MAX_PACKET_LEN
Definition rtp.h:61
#define PT_AUDIO_IS_ENCRYPTED(pt)
Definition rtp_types.h:166
#define BUFNUM_BITS
Definition rtp_types.h:171
uint32_t fec_payload_hdr_t[5]
Definition rtp_types.h:152
#define PT_AUDIO_HAS_FEC(pt)
RFC 2550 hdr for audio - 16b MBZ, 16b Frag_off.
Definition rtp_types.h:165
#define PT_IS_AUDIO(pt)
Definition rtp_types.h:167
#define PT_Unassign_Type95
Definition rtp_types.h:77
uint32_t crypto_payload_hdr_t[1]
Definition rtp_types.h:161
codec_t first
Definition sdl2.c:423
int64_t timestamp
Definition types.h:109
char * data
Definition types.h:102
int data_len
Definition types.h:103
int max_size
Definition types.h:105
int * contributors
Definition utils.h:172
rtp_packet * data
Definition pbuf.h:75
struct coded_data * nxt
Definition pbuf.h:72
int(* decrypt)(struct openssl_decrypt *decrypt, const char *ciphertext, int ciphertext_len, const char *aad, int aad_len, char *plaintext, enum openssl_mode mode)
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
void update(unsigned long int bufnum)
struct state_audio_decoder_summary summary
audio_frame2_resampler resampler
double tv_diff(struct timeval curr_time, struct timeval prev_time)
Definition tv.c:97
void mux_and_mix_channel(char *out, const char *in, int bps, int in_len, int out_stream_channels, int pos_in_stream, double scale)
Definition utils.cpp:402
double get_avg_volume(char *data, int bps, int sample_count, int stream_channels, int pos_in_stream)
Definition utils.cpp:461
void task_run_async_detached(runnable_t task, void *data)
Runs task asynchronously in a detached state.
Definition worker.cpp:275

References ADEC_CH_RATE_SHIFT, adec_compute_and_print_stats(), audio_frame2_resampler::align_bps(), audio_frame2::append(), audio_codec_decompress(), audio_decoder_reconfigure(), state_audio_decoder::audio_decompress, audio_fec_decode(), audio_desc::bps, audio_frame::bps, pbuf_audio_data::buffer, BUFNUM_BITS, calculate_rms(), audio_desc::ch_count, audio_frame::ch_count, audio_frame2::change_bps(), state_audio_decoder::channel_map, state_audio_decoder::channel_remapping, compute_scale(), channel_map::contributors, state_audio_decoder::control, control_audio_ch_report_count(), control_report_stats(), control_stats_enabled(), audio_frame::data, coded_data::data, audio_frame::data_len, DEBUG_TIMER_START, DEBUG_TIMER_STOP, state_audio_decoder::dec_funcs, state_audio_decoder::decoded, pbuf_audio_data::decoder, openssl_decrypt_info::decrypt, state_audio_decoder::decrypt, first, state_audio_decoder::fixed_scale, adec_stats_processing_data::frame, pbuf_audio_data::frame_size, get_audio_codec_to_tag(), get_avg_volume(), audio_frame2::get_bps(), audio_frame2::get_channel_count(), audio_frame2::get_codec(), audio_frame2::get_data(), audio_frame2::get_data_len(), audio_frame2::get_sample_rate(), audio_frame2::get_timestamp(), audio_frame2::init(), LOG, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, log_msg(), log_msg_once(), channel_map::map, channel_map::max_output, audio_frame::max_size, MOD_NAME, MODE_AES128_MAX, MODE_AES128_NONE, state_audio_decoder::muted, mux_and_mix_channel(), coded_data::nxt, offset, state_audio_decoder::packet_counter, packet_counter_clear(), packet_counter_destroy(), packet_counter_get_all_bytes(), packet_counter_get_channels(), packet_counter_get_total_bytes(), packet_counter_init(), packet_counter_register_packet(), PT_AUDIO_HAS_FEC, PT_AUDIO_IS_ENCRYPTED, PT_IS_AUDIO, PT_Unassign_Type95, audio_frame2::replace(), state_audio_decoder::req_resample_to, audio_frame2::resample(), audio_frame2::resample_fake(), state_audio_decoder::resample_remainder, state_audio_decoder::resampler, audio_frame2::resize(), RTP_MAX_PACKET_LEN, audio_desc::sample_rate, audio_frame::sample_rate, sample_rate, state_audio_decoder::saved_audio_tag, state_audio_decoder::saved_desc, state_audio_decoder::scale, audio_frame2::set_timestamp(), channel_map::size, channel_map::sizes, pbuf_audio_data::source, state_audio_decoder::summary, state_audio_decoder::t0, task_run_async_detached(), audio_frame::timestamp, to_fourcc, tv_diff(), and state_audio_decoder_summary::update().

Referenced by audio_receiver_thread().

Here is the call graph for this function:

◆ decode_audio_frame_mulaw()

int decode_audio_frame_mulaw ( struct coded_data * cdata,
void * data,
struct pbuf_stats * stats )

Definition at line 821 of file audio_decoders.cpp.

822{
823 struct pbuf_audio_data *s = (struct pbuf_audio_data *) data;
824 struct state_audio_decoder *audio = s->decoder;
825
826 //struct state_audio_decoder *audio = (struct state_audio_decoder *)data;
827
828 if(!cdata) return false;
829
830 audio_frame2 received_frame;
831 received_frame.init(audio->saved_desc.ch_count, audio->saved_desc.codec,
832 audio->saved_desc.bps, audio->saved_desc.sample_rate);
833
834 // Check-if-there-is-only-one-channel optimization.
835 if (received_frame.get_channel_count() == 1) {
836 //char *to = audio->received_frame->data[0];
837 while (cdata != NULL) {
838 // Get the data to copy into the received_frame.
839 char *from = cdata->data->data;
840
841 received_frame.append(0, from, cdata->data->data_len);
842
843 cdata = cdata->nxt;
844 }
845 } else { // Multi-channel case.
846
847 /*
848 * Unoptimized version of the multi-channel handling.
849 * TODO: Optimize it! It's a matrix transpose.
850 * Take a look at http://stackoverflow.com/questions/1777901/array-interleaving-problem
851 */
852
853 while (cdata != NULL) {
854 // Check that the amount of data on cdata->data->data is congruent with 0 modulus audio->received_frame->ch_count.
855 if (cdata->data->data_len % received_frame.get_channel_count() != 0) {
856 // printf something?
857 return false;
858 }
859
860 char *from = cdata->data->data;
861
862 // For each group of samples.
863 for (int g = 0 ; g < (cdata->data->data_len / received_frame.get_channel_count()) ; g++) {
864 // Iterate throught each channel.
865 for (int ch = 0 ; ch < received_frame.get_channel_count(); ch ++) {
866
867 received_frame.append(ch, from, cdata->data->data_len);
868
869 from += received_frame.get_bps();
870 }
871 }
872
873 cdata = cdata->nxt;
874 }
875
876 }
877
878 return true;
879}
struct audio_frame ** audio

References audio_frame2::append(), audio, audio_frame::bps, audio_frame::ch_count, coded_data::data, pbuf_audio_data::decoder, audio_frame2::get_bps(), audio_frame2::get_channel_count(), audio_frame2::init(), coded_data::nxt, and audio_frame::sample_rate.

Referenced by audio_receiver_thread().

Here is the call graph for this function:

◆ parse_audio_hdr()

bool parse_audio_hdr ( uint32_t * hdr,
struct audio_desc * desc )

Definition at line 357 of file audio_decoders.cpp.

358{
359 desc->ch_count = ((ntohl(hdr[0]) >> 22) & 0x3ff) + 1;
360 desc->sample_rate = ntohl(hdr[3]) & 0x3fffff;
361 desc->bps = (ntohl(hdr[3]) >> 26) / 8;
362
363 uint32_t audio_tag = ntohl(hdr[4]);
364 desc->codec = get_audio_codec_to_tag(audio_tag);
365
366 return true;
367}

References desc, and get_audio_codec_to_tag().

Referenced by decode_yuri_audio_frame().

Here is the call graph for this function:

Variable Documentation

◆ VOL_DOWN

double VOL_DOWN = 1.0/1.1
constexpr

Definition at line 190 of file audio_decoders.cpp.

Referenced by compute_scale().

◆ VOL_UP

double VOL_UP = 1.1
constexpr

Definition at line 189 of file audio_decoders.cpp.

Referenced by compute_scale().