UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
utils.h File Reference
#include <cstdint>
#include <cstddef>
#include "audio/types.h"
Include dependency graph for utils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  channel_map
 

Macros

#define STORE_I32_SAMPLE(ptr, val, out_bps)
 stores given int32_t sample at required out_bps
 

Functions

bool append_audio_frame (struct audio_frame *frame, char *data, size_t data_len)
 
void audio_channel_demux (const audio_frame2 *, int, audio_channel *)
 
bool audio_desc_eq (struct audio_desc, struct audio_desc)
 
struct audio_desc audio_desc_from_audio_channel (const audio_channel *)
 
struct audio_desc audio_desc_from_frame (const struct audio_frame *frame)
 
const char * audio_desc_to_cstring (struct audio_desc desc)
 
struct audio_frame * audio_frame_copy (const struct audio_frame *src, bool keep_size)
 
void audio_frame_multiply_channel (struct audio_frame *frame, int new_channel_count)
 
void audio_frame_write_desc (struct audio_frame *f, struct audio_desc desc)
 
double calculate_rms (audio_frame *frame, int channel, double *peak)
 
double calculate_rms (audio_frame2 *frame, int channel, double *peak)
 Calculates mean and peak RMS from audio samples.
 
void change_bps (char *out, int out_bps, const char *in, int in_bps, int in_len)
 
void change_bps2 (char *out, int out_bps, const char *in, int in_bps, int in_len, bool dither)
 changes bps with option to specify whether or not do the dithering
 
void copy_channel (char *out, const char *in, int bps, int in_len, int out_channel_count)
 
void demux_channel (char *out, char *in, int bps, int in_len, int in_stream_channels, int pos_in_stream)
 
int32_t downshift_with_dither (int32_t val, int shift)
 
void float2int (char *out, const char *in, int len)
 
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.99")
 
double get_avg_volume (char *data, int bps, int in_len, int stream_channels, int chan_pos_stream)
 
void int2float (char *out, const char *in, int len)
 
void interleaved2noninterleaved (char *out, const char *in, int bps, int in_len, int channel_count)
 
void interleaved2noninterleaved2 (char **out, const char *in, int bps, int in_len, int channel_count)
 
void interleaved2noninterleaved_float (char **out, const char *in, int in_bps, int in_len, int channel_count)
 
void mux_and_mix_channel (char *out, const char *in, int bps, int in_len, int out_stream_channels, int chan_pos_stream, double scale)
 
void mux_channel (char *out, const char *in, int bps, int in_len, int out_stream_channels, int chan_pos_stream, double scale)
 
int parse_audio_format (const char *str, struct audio_desc *ret)
 
bool parse_channel_map_cfg (struct channel_map *channel_map, const char *cfg)
 
void remux_and_mix_channel (char *out, const char *in, int bps, int frames, int in_stream_channels, int out_stream_channels, int in_channel, int out_channel, double scale)
 
void remux_channel (char *out, const char *in, int bps, int in_len, int in_stream_channels, int out_stream_channels, int pos_in_stream, int pos_out_stream)
 
void signed2unsigned (char *out, const char *in, int in_len)
 

Detailed Description

Macro Definition Documentation

◆ STORE_I32_SAMPLE

#define STORE_I32_SAMPLE ( ptr,
val,
out_bps )
Value:
memcpy((ptr), ((const char *) &(val)) + 4 - (out_bps), (out_bps))
int void * val

stores given int32_t sample at required out_bps

Definition at line 143 of file utils.h.

143#define STORE_I32_SAMPLE(ptr, val, out_bps) \
144 memcpy((ptr), ((const char *) &(val)) + 4 - (out_bps), (out_bps))

Referenced by generate_audio_sine(), and get_ebu_signal().

Function Documentation

◆ append_audio_frame()

bool append_audio_frame ( struct audio_frame * frame,
char * data,
size_t data_len )

Appends data to audio frame

Returns
whether all data has been written

Definition at line 620 of file utils.cpp.

620 {
621 bool ret = true;
622 if (frame->data_len + data_len > (size_t) frame->max_size) {
623 log_msg(LOG_LEVEL_WARNING, "Audio frame overrun, discarding some data.\n");
624 data_len = frame->max_size - frame->data_len;
625 ret = false;
626 }
627 memcpy(frame->data + frame->data_len, data, data_len);
628 frame->data_len += data_len;
629
630 return ret;
631}
struct video_frame * frame
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60

References frame, LOG_LEVEL_WARNING, and log_msg().

Referenced by display_pipe_get_audio().

Here is the call graph for this function:

◆ audio_channel_demux()

void audio_channel_demux ( const audio_frame2 * frame,
int index,
audio_channel * channel )

Definition at line 528 of file utils.cpp.

529{
530 channel->data = frame->get_data(index);
531 channel->data_len = frame->get_data_len(index);
532 channel->codec = frame->get_codec();
533 channel->bps = frame->get_bps();
534 channel->sample_rate = frame->get_sample_rate();
535}
audio_codec_t codec
Definition types.h:127
const char * data
Definition types.h:125
int sample_rate
Definition types.h:124
int data_len
Definition types.h:126

References audio_channel::bps, audio_channel::codec, audio_channel::data, audio_channel::data_len, frame, and audio_channel::sample_rate.

Referenced by audio_codec_compress(), and audio_codec_decompress().

◆ audio_desc_eq()

bool audio_desc_eq ( struct audio_desc a1,
struct audio_desc a2 )

Definition at line 189 of file utils.cpp.

189 {
190 return a1.bps == a2.bps &&
191 a1.sample_rate == a2.sample_rate &&
192 a1.ch_count == a2.ch_count &&
193 a1.codec == a2.codec;
194}
int sample_rate
Definition types.h:78
int ch_count
Definition types.h:79
int bps
Definition types.h:77
audio_codec_t codec
Definition types.h:80

References audio_desc::bps, audio_desc::ch_count, audio_desc::codec, and audio_desc::sample_rate.

Referenced by audio_append_pcm(), audio_export(), audio_receiver_thread(), check_reconf(), display_pipe_get_audio(), libavcodec_decompress(), and process_input().

◆ audio_desc_from_audio_channel()

struct audio_desc audio_desc_from_audio_channel ( const audio_channel * channel)

Definition at line 205 of file utils.cpp.

206{
207 return audio_desc { channel->bps,
208 channel->sample_rate,
209 1,
210 channel->codec
211 };
212}

Referenced by libavcodec_decompress(), and process_input().

◆ audio_desc_from_frame()

struct audio_desc audio_desc_from_frame ( const struct audio_frame * frame)

Definition at line 196 of file utils.cpp.

196 {
197 return audio_desc { frame->bps,
198 frame->sample_rate,
199 frame->ch_count,
200 AC_PCM
201 };
202}
@ AC_PCM
Definition types.h:53

References AC_PCM, and frame.

Referenced by audio_append_pcm(), audio_export(), audio_receiver_thread(), display_file_put_audio_frame(), display_pipe_get_audio(), generate_signal(), setup_audio(), vidcap_state_aja::SetupAudio(), and wait_for_channel().

◆ audio_desc_to_cstring()

const char * audio_desc_to_cstring ( struct audio_desc desc)

Definition at line 644 of file utils.cpp.

644 {
645 thread_local string str = desc;
646 return str.c_str();
647}
struct video_desc desc

References desc.

Referenced by generate_signal(), set_audio_spec_to_vrxtx(), and vidcap_file_init().

◆ audio_frame_copy()

struct audio_frame * audio_frame_copy ( const struct audio_frame * src,
bool keep_size )

Creates a deep copy of src. Both struct and audio_frame::data is malloc'd.

Parameters
keep_sizeallocate exactly same storage (audio_frame::max_size) as original frame. If false, the storage may be shorter.

Definition at line 633 of file utils.cpp.

633 {
634 struct audio_frame *ret = (struct audio_frame *) malloc(sizeof(struct audio_frame));
635 memcpy(ret, src, sizeof *ret);
636 if (!keep_size) {
637 ret->max_size = src->data_len;
638 }
639 ret->data = (char *) malloc(ret->max_size);
640 memcpy(ret->data, src->data, src->data_len);
641 return ret;
642}
struct used to comunicate with audio capture/playback device
Definition types.h:99
char * data
Definition types.h:102
int data_len
Definition types.h:103
int max_size
Definition types.h:105

References audio_frame::data, audio_frame::data_len, and audio_frame::max_size.

Referenced by display_pipe_put_audio_frame().

◆ audio_frame_multiply_channel()

void audio_frame_multiply_channel ( struct audio_frame * frame,
int new_channel_count )

Makes n copies of first channel (interleaved).

Definition at line 328 of file utils.cpp.

328 {
329 assert((unsigned int) frame->max_size >= (unsigned int) frame->data_len * new_channel_count / frame->ch_count);
330
331 copy_channel(frame->data, frame->data, frame->bps, frame->data_len, new_channel_count);
332}
void copy_channel(char *out, const char *in, int bps, int in_len, int out_channel_count)
Definition utils.cpp:306

References copy_channel(), and frame.

Here is the call graph for this function:

◆ audio_frame_write_desc()

void audio_frame_write_desc ( struct audio_frame * f,
struct audio_desc desc )

Copies desc from desc to f.

Note
Doesn't clear/set other members of f, thus caller needs to do that first if needed.

Definition at line 220 of file utils.cpp.

221{
222 f->bps = desc.bps;
223 f->sample_rate = desc.sample_rate;
224 f->ch_count = desc.ch_count;
225}
int sample_rate
Definition types.h:101
int ch_count
Definition types.h:104
int bps
Definition types.h:100

References audio_frame::bps, audio_frame::ch_count, desc, and audio_frame::sample_rate.

Referenced by display_pipe_get_audio(), and get_audio().

◆ calculate_rms() [1/2]

double calculate_rms ( audio_frame * frame,
int channel,
double * peak )

Definition at line 169 of file utils.cpp.

170{
171 assert(channel < frame->ch_count);
172 char *data = frame->data + channel * frame->bps;
173 int sample_count = frame->data_len / frame->bps / frame->ch_count;
174 switch (frame->bps) {
175 case 1:
176 return calculate_rms_helper<1>(data, sample_count, peak, frame->ch_count);
177 case 2:
178 return calculate_rms_helper<2>(data, sample_count, peak, frame->ch_count);
179 case 3:
180 return calculate_rms_helper<3>(data, sample_count, peak, frame->ch_count);
181 case 4:
182 return calculate_rms_helper<4>(data, sample_count, peak, frame->ch_count);
183 default:
184 LOG(LOG_LEVEL_FATAL) << "Wrong BPS " << frame->bps << "\n";
185 abort();
186 }
187}
#define LOG(level)
Definition debug.h:313
#define LOG_LEVEL_FATAL
errors that prevent UG run
Definition debug.h:58
static double calculate_rms_helper(const char *channel_data, int sample_count, double *peak, int sample_stride=1)
Calculates mean and peak RMS from audio samples.
Definition utils.cpp:113

References calculate_rms_helper(), frame, LOG, and LOG_LEVEL_FATAL.

Here is the call graph for this function:

◆ calculate_rms() [2/2]

double calculate_rms ( audio_frame2 * frame,
int channel,
double * peak )

Calculates mean and peak RMS from audio samples.

Parameters
[in]frameaudio frame
[in]channelchannel index to calculate RMS to
[out]peakpeak RMS
Returns
mean RMS

Definition at line 150 of file utils.cpp.

151{
152 assert(frame->get_codec() == AC_PCM);
153 int sample_count = frame->get_data_len(channel) / frame->get_bps();
154 switch (frame->get_bps()) {
155 case 1:
156 return calculate_rms_helper<1>(frame->get_data(channel), sample_count, peak);
157 case 2:
158 return calculate_rms_helper<2>(frame->get_data(channel), sample_count, peak);
159 case 3:
160 return calculate_rms_helper<3>(frame->get_data(channel), sample_count, peak);
161 case 4:
162 return calculate_rms_helper<4>(frame->get_data(channel), sample_count, peak);
163 default:
164 LOG(LOG_LEVEL_FATAL) << "Wrong BPS " << frame->get_bps() << "\n";
165 abort();
166 }
167}

References AC_PCM, calculate_rms_helper(), frame, LOG, and LOG_LEVEL_FATAL.

Referenced by adec_compute_and_print_stats(), asend_compute_and_print_stats(), decode_audio_frame(), and filter().

Here is the call graph for this function:

◆ change_bps()

void change_bps ( char * out,
int out_bps,
const char * in,
int in_bps,
int in_len )

Changes bps for everey sample.

The memory areas shouldn't (supposedly) overlap.

Definition at line 258 of file utils.cpp.

258 {
259 static const bool dither = commandline_params.find(NO_DITHER_PARAM) == commandline_params.end();
260 change_bps2(out, out_bps, in, in_bps, in_len, dither);
261}
std::unordered_map< std::string, std::string > commandline_params
Definition host.cpp:184
void change_bps2(char *out, int out_bps, const char *in, int in_bps, int in_len, bool dither)
changes bps with option to specify whether or not do the dithering
Definition utils.cpp:263
#define NO_DITHER_PARAM
Definition utils.cpp:254

References change_bps2(), commandline_params, and NO_DITHER_PARAM.

Referenced by audio_testcard_read_wav(), display_sdl_put_audio_frame(), echo_cancel(), echo_play(), and process_input().

Here is the call graph for this function:

◆ change_bps2()

void change_bps2 ( char * out,
int out_bps,
const char * in,
int in_bps,
int in_len,
bool dither )

changes bps with option to specify whether or not do the dithering

Definition at line 263 of file utils.cpp.

264{
265 assert ((unsigned int) out_bps <= sizeof(int32_t));
266 static_assert(-2>>1 == -1, "Implementation-defined behavior doesn't work as expected by the implementation.");
267
268 if (in_bps == out_bps ) {
269 memcpy(out, in, in_len);
270 return;
271 }
272
273 if (in_bps < out_bps ) {
274 for (int i = 0; i < in_len / in_bps; i++) {
275 int32_t in_value = format_from_in_bps(in, in_bps);
276 int32_t out_value = in_value << (out_bps * 8 - in_bps * 8);
277 format_to_out_bps(out, out_bps, out_value);
278 in += in_bps;
279 out += out_bps;
280 }
281 return;
282 }
283
284 // downsampling
285 if (dither) {
286 const int downshift = in_bps * 8 - out_bps * 8;
287 for (int i = 0; i < in_len / in_bps; i++) {
288 int32_t in_value = format_from_in_bps(in, in_bps);
289 int32_t out_value = downshift_with_dither(in_value, downshift);
290 format_to_out_bps(out, out_bps, out_value);
291 in += in_bps;
292 out += out_bps;
293 }
294 return;
295 }
296 // no dithering
297 for (int i = 0; i < in_len / in_bps; i++) {
298 int32_t in_value = format_from_in_bps(in, in_bps);
299 int32_t out_value = in_value >> (in_bps * 8 - out_bps * 8);
300 format_to_out_bps(out, out_bps, out_value);
301 in += in_bps;
302 out += out_bps;
303 }
304}
static int32_t format_from_in_bps(const char *in, int bps)
reads sample at specified BPS and returns it in i32 container (not scaled)
Definition utils.cpp:539
static void format_to_out_bps(char *out, int bps, int32_t out_value)
Definition utils.cpp:556
int32_t downshift_with_dither(int32_t val, int shift)
Definition utils.cpp:227

References downshift_with_dither(), format_from_in_bps(), and format_to_out_bps().

Referenced by change_bps(), and get_sine_signal().

Here is the call graph for this function:

◆ copy_channel()

void copy_channel ( char * out,
const char * in,
int bps,
int in_len,
int out_channel_count )

Definition at line 306 of file utils.cpp.

307{
308 int samples = in_len / bps;
309 int i;
310
311 assert(out_channel_count > 0);
312 assert(bps > 0);
313 assert(in_len >= 0);
314
315 in += in_len;
316 out += in_len * out_channel_count;
317 for (i = samples; i > 0 ; --i) {
318 int j;
319
320 in -= bps;
321 for (j = out_channel_count + 0; j > 0; --j) {
322 out -= bps;
323 memmove(out, in, bps);
324 }
325 }
326}

References audio_desc::bps.

Referenced by audio_frame_multiply_channel().

◆ demux_channel()

void demux_channel ( char * out,
char * in,
int bps,
int in_len,
int in_stream_channels,
int pos_in_stream )

Definition at line 334 of file utils.cpp.

335{
336 int samples = in_len / (in_stream_channels * bps);
337 int i;
338
339 assert (bps <= 4);
340
341 in += pos_in_stream * bps;
342
343 for (i = 0; i < samples; ++i) {
344 memcpy(out, in, bps);
345
346 out += bps;
347 in += in_stream_channels * bps;
348
349 }
350}

References audio_desc::bps.

Referenced by audio_frame2::audio_frame2(), audio_cap_alsa_read(), display_deltacast_put_audio_frame(), jack_process_callback(), process_new_audio_packets(), and vidcap_dvs_grab_thread().

◆ downshift_with_dither()

int32_t downshift_with_dither ( int32_t val,
int shift )

Bit-shifts val down by shift bits with a triangular dither noise.

By reducing bit-depth of audio, quantization noise is introduced. If the bit depth is reduced by consistent rounding (either always down, always up, or always to nearest) the quantization noise is correlated with the input signal and percieved as distortion. Adding a small amount of noise to the input signal before reducing the bit-depth causes random rounding, which makes the noise uncorrelated and uniformly spread through the whole spectrum.

Definition at line 227 of file utils.cpp.

227 {
228 static thread_local uint32_t last_rand = 0;
229
230 //Quick and dirty random number generation (ranqd1)
231 //Numerical Recipes in C, page 284
232 last_rand = (last_rand * 1664525) + 1013904223L;
233 int triangle_dither = last_rand >> (32 - shift);
234 last_rand = (last_rand * 1664525) + 1013904223L;
235 triangle_dither -= last_rand >> (32 - shift); //triangle probability distribution
236
237 /* Prevent over/underflow when val is big.
238 *
239 * abs(val) could cause problems if val is INT32_MIN, but integer
240 * 32-bit pcm is rare and should not contain the value INT32_MIN
241 * anyway because of symmetry, as specified by AES17 and IEC 61606-3
242 */
243 if(INT32_MAX - abs(val) < (1 << shift) - 1 + (1 << (shift - 1)))
244 return val / (1 << shift);
245
246 if(val > 0)
247 val += 1 << (shift - 1);
248 else
249 val -= 1 << (shift - 1);
250
251 return (val + triangle_dither) / (1 << shift);
252}
static __device__ vec2 abs(const vec2 &v)
Definition cuda_dxt.cu:118

References abs(), and val.

Referenced by change_bps2().

Here is the call graph for this function:

◆ float2int()

void float2int ( char * out,
const char * in,
int len )

This fuction converts from normalized float to int32_t representation Input and output data may overlap.

Parameters
[out]out4-byte aligned output buffer
[in]in4-byte aligned input buffer

Can be used in situ.

Definition at line 482 of file utils.cpp.

483{
484 const float *inf = (const float *)(const void *) in;
485 int32_t *outi = (int32_t *)(void *) out;
486 int items = len / sizeof(int32_t);
487
488 while(items-- > 0) {
489 float sample = *inf++;
490 if(sample > 1.0) sample = 1.0;
491 if(sample < -1.0) sample = -1.0;
492 *outi++ = sample * INT_MAX_FLT;
493 }
494}
int void size_t * len
const float INT_MAX_FLT
Definition utils.cpp:477

References INT_MAX_FLT, and len.

Referenced by audio_cap_jack_read(), libavcodec_decompress(), and vidcap_file_write_audio().

◆ format_audio_channel_volume()

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.99")

Parameters
rmsvolume RMS in range [0,1]
peakvalue of sample with maximal absolute value in range [0,1]
[in,out]volume_startstring to be wwritten to, after function exit will to point after just written data

Definition at line 828 of file utils.cpp.

830{
831 if (chan_idx > 0) {
832 *volume_start +=
833 snprintf(*volume_start, volume_end - *volume_start, ", ");
834 }
835 const double rms_dbfs = 20.0 * log(rms) / log(10.0);
836 const double peak_dbfs = 20.0 * log(peak) / log(10.0);
837 *volume_start +=
838 snprintf(*volume_start, volume_end - *volume_start,
839 "[%d] %s%.2f" TERM_RESET "/%s%.2f" TERM_RESET, chan_idx,
840 format_color, rms_dbfs, format_color, peak_dbfs);
841}
#define TERM_RESET
Definition color_out.h:47

References TERM_RESET.

Referenced by adec_compute_and_print_stats(), and asend_compute_and_print_stats().

◆ get_avg_volume()

double get_avg_volume ( char * data,
int bps,
int in_len,
int stream_channels,
int chan_pos_stream )

Definition at line 461 of file utils.cpp.

461 {
462 switch (bps) {
463 case 1:
464 return get_avg_volume_helper<1>(data, sample_count, stream_channels, pos_in_stream);
465 case 2:
466 return get_avg_volume_helper<2>(data, sample_count, stream_channels, pos_in_stream);
467 case 3:
468 return get_avg_volume_helper<3>(data, sample_count, stream_channels, pos_in_stream);
469 case 4:
470 return get_avg_volume_helper<4>(data, sample_count, stream_channels, pos_in_stream);
471 default:
472 LOG(LOG_LEVEL_FATAL) << "Wrong BPS " << bps << "\n";
473 abort();
474 }
475}
static double get_avg_volume_helper(const char *data, int sample_count, int stream_channels, int pos_in_stream)
Definition utils.cpp:446

References audio_desc::bps, get_avg_volume_helper(), LOG, and LOG_LEVEL_FATAL.

Referenced by decode_audio_frame().

Here is the call graph for this function:

◆ int2float()

void int2float ( char * out,
const char * in,
int len )

This fuction converts from int32_t to normalized float Input and output data may overlap.

Parameters
[out]out4-byte aligned output buffer
[in]in4-byte aligned input buffer

Definition at line 496 of file utils.cpp.

497{
498 const int32_t *ini = (const int32_t *)(const void *) in;
499 float *outf = (float *)(void *) out;
500 int items = len / sizeof(int32_t);
501
502 while(items-- > 0) {
503 *outf++ = (float) *ini++ / (float) INT_MAX;
504 }
505}

References len.

Referenced by audio_play_jack_put_frame(), and process_input().

◆ interleaved2noninterleaved()

void interleaved2noninterleaved ( char * out,
const char * in,
int bps,
int in_len,
int channel_count )

Definition at line 610 of file utils.cpp.

612{
613 vector<char *> out_ch(channel_count);
614 for (int i = 0; i < channel_count; ++i) {
615 out_ch[i] = out + (ptrdiff_t) in_len / channel_count * i;
616 }
617 interleaved2noninterleaved2(out_ch.data(), in, bps, in_len, channel_count);
618}
void interleaved2noninterleaved2(char **out_ch, const char *in, int bps, int in_len, int channel_count)
Definition utils.cpp:566

References audio_desc::bps, and interleaved2noninterleaved2().

Referenced by write_samples().

Here is the call graph for this function:

◆ interleaved2noninterleaved2()

void interleaved2noninterleaved2 ( char ** out,
const char * in,
int bps,
int in_len,
int channel_count )

Definition at line 566 of file utils.cpp.

568{
569 for (int i = 0; i < in_len / channel_count / bps; ++i) {
570 for (int ch = 0; ch < channel_count; ++ch) {
571 memcpy(out_ch[ch] + (ptrdiff_t) i * bps, in, bps);
572 in += bps;
573 }
574 }
575}

References audio_desc::bps.

Referenced by file_append_audio_frame(), and interleaved2noninterleaved().

◆ interleaved2noninterleaved_float()

void interleaved2noninterleaved_float ( char ** out,
const char * in,
int in_bps,
int in_len,
int channel_count )

Definition at line 578 of file utils.cpp.

580{
581 for (int ch = 0; ch < channel_count; ++ch) {
582 assert((uintptr_t) out_ch[ch] % 4 == 0);
583 }
584 if (in_bps == 1) { // bps 1 is unsigned
585 for (int i = 0; i < in_len / channel_count; ++i) {
586 for (int ch = 0; ch < channel_count; ++ch) {
587 const int val =
588 INT8_MIN + *(const uint8_t *) in;
589 *(float *) (void *) (out_ch[ch] +
590 (ptrdiff_t) i * 4) =
591 (float) val / -INT8_MIN;
592 in++;;
593 }
594 }
595 } else {
596 for (int i = 0; i < in_len / channel_count / in_bps; ++i) {
597 for (int ch = 0; ch < channel_count; ++ch) {
598 int32_t val = 0;
599 memcpy((char *) &val + 4 - in_bps, in, in_bps);
600 *(float *) (void *) (out_ch[ch] +
601 (ptrdiff_t) i * 4) =
602 (float) val / (-1.0F * INT32_MIN);
603 in += in_bps;
604 }
605 }
606 }
607}

References val.

Referenced by file_append_audio_frame().

◆ mux_and_mix_channel()

void mux_and_mix_channel ( char * out,
const char * in,
int bps,
int in_len,
int out_stream_channels,
int chan_pos_stream,
double scale )

Definition at line 402 of file utils.cpp.

403{
404 int i;
405
406 assert (bps <= 4);
407
408 out += pos_in_stream * bps;
409
410 for(i = 0; i < in_len / bps; i++) {
411 int32_t in_value = format_from_in_bps(in, bps);
412 int32_t out_value = format_from_in_bps(out, bps);
413
414 int32_t new_value = (double)in_value * scale + out_value;
415
416 format_to_out_bps(out, bps, new_value);
417
418 in += bps;
419 out += out_stream_channels * bps;
420 }
421}

References audio_desc::bps, format_from_in_bps(), and format_to_out_bps().

Referenced by decode_audio_frame().

Here is the call graph for this function:

◆ mux_channel()

void mux_channel ( char * out,
const char * in,
int bps,
int in_len,
int out_stream_channels,
int chan_pos_stream,
double scale )

Definition at line 371 of file utils.cpp.

372{
373 int samples = in_len / bps;
374 int i;
375
376 assert (bps <= 4);
377
378 out += pos_in_stream * bps;
379
380 if(scale == 1.0) {
381 for (i = 0; i < samples; ++i) {
382 memcpy(out, in, bps);
383
384 in += bps;
385 out += out_stream_channels * bps;
386
387 }
388 } else {
389 for (i = 0; i < samples; ++i) {
390 int32_t in_value = format_from_in_bps(in, bps);
391
392 in_value *= scale;
393
394 format_to_out_bps(out, bps, in_value);
395
396 in += bps;
397 out += out_stream_channels * bps;
398 }
399 }
400}

References audio_desc::bps, format_from_in_bps(), and format_to_out_bps().

Referenced by decode_yuri_audio_frame(), InputProc(), jack_process_callback(), and vidcap_file_write_audio().

Here is the call graph for this function:

◆ parse_audio_format()

int parse_audio_format ( const char * str,
struct audio_desc * ret )

Parses configuration string for audio format.

Only members that are specified explicitly by the config string are changed in returned audio desc, the remaining members are left untouched!

Definition at line 655 of file utils.cpp.

655 {
656 if (strcmp(str, "help") == 0) {
657 color_printf(TBOLD("Audio format") " syntax:\n");
658 color_printf(TBOLD("\t{channels=<num>|bps=<bits_per_sample>|sample_rate=<rate>}*\n"));
659 color_printf("\t\tmultiple options can be separated by a colon\n");
660 return 1;
661 }
662
663 unique_ptr<char[]> arg_copy(new char[strlen(str) + 1]);
664 char *arg = arg_copy.get();
665 strcpy(arg, str);
666
667 char *save_ptr = nullptr;
668 char *tmp = arg;
669
670 while (char *item = strtok_r(tmp, ",:", &save_ptr)) {
671 const char *const val = strchr(item, '=') + 1;
672 if (IS_KEY_PREFIX(item, "channels")) {
673 ret->ch_count = stoi(val);
674 if (ret->ch_count < 1 ||
675 ret->ch_count > MAX_AUD_CH_COUNT) {
677 "Invalid number of channels %s! Valid "
678 "range 1-%d.\n",
680 return -1;
681 }
682 } else if (IS_KEY_PREFIX(item, "bps")) {
683 const int bps = stoi(val);
684 if (bps % 8 != 0 || bps <= 0 || bps > 32) {
685 log_msg(LOG_LEVEL_ERROR, "Invalid bps %s!\n",
686 val);
687 if (bps % 8 != 0) {
688 LOG(LOG_LEVEL_WARNING) << "bps is in bits per sample but a value not divisible by 8 was given.\n";
689 }
690 log_msg(LOG_LEVEL_ERROR, "Supported values are 8, 16, 24, or 32 bits.\n");
691 return -1;
692 }
693 ret->bps = bps / 8;
694 } else if (IS_KEY_PREFIX(item, "sample_rate")) {
695 const long long rate = unit_evaluate(val, nullptr);
696 if (rate <= 0 || rate > MAX_AUD_SAMPLE_RATE) {
698 << "Invalid sample_rate " << rate
699 << "! Valid range 1-"
700 << MAX_AUD_SAMPLE_RATE << ".\n";
701 return -1;
702 }
703 ret->sample_rate = (int) rate;
704 } else {
705 LOG(LOG_LEVEL_ERROR) << "Unkonwn option \"" << item << "\" for audio format!\n";
706 LOG(LOG_LEVEL_INFO) << "Use \"help\" keyword for syntax.!\n";
707 return -1;
708 }
709
710 tmp = nullptr;
711 }
712 return 0;
713}
@ MAX_AUD_CH_COUNT
Definition types.h:68
@ MAX_AUD_SAMPLE_RATE
Definition types.h:69
int color_printf(const char *format,...)
#define TBOLD(x)
Definition color_out.h:70
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define IS_KEY_PREFIX(tok, key)
expands to true value if <k> from tok in format <k>=<v> is prefix of key
Definition macros.h:138
long long unit_evaluate(const char *str, const char **endptr)
Definition misc.cpp:81
Definition hd-rum.c:27

References audio_desc::bps, audio_frame::bps, audio_desc::ch_count, color_printf(), IS_KEY_PREFIX, LOG, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, log_msg(), MAX_AUD_CH_COUNT, MAX_AUD_SAMPLE_RATE, audio_desc::sample_rate, TBOLD, unit_evaluate(), and val.

Referenced by audio_decoder_reconfigure(), and set_audio_capture_format().

Here is the call graph for this function:

◆ parse_channel_map_cfg()

bool parse_channel_map_cfg ( struct channel_map * channel_map,
const char * cfg )

Definition at line 716 of file utils.cpp.

716 {
717 char *save_ptr = NULL;
718 char *item;
719 char *ptr;
720 char *tmp = ptr = strdup(cfg);
721
722 channel_map->size = 0;
723 while((item = strtok_r(ptr, ",", &save_ptr))) {
724 ptr = NULL;
725 // item is in format x1:y1
726 if(isdigit(item[0])) {
727 channel_map->size = std::max(channel_map->size, atoi(item) + 1);
728 }
729 }
730
731 channel_map->map = (int **) malloc(channel_map->size * sizeof(int *));
732 channel_map->sizes = (int *) malloc(channel_map->size * sizeof(int));
733
734 /* default value, do not process */
735 for(int i = 0; i < channel_map->size; ++i) {
736 channel_map->map[i] = NULL;
737 channel_map->sizes[i] = 0;
738 }
739
740 free (tmp);
741 tmp = ptr = strdup(cfg);
742
743 while((item = strtok_r(ptr, ",", &save_ptr))) {
744 ptr = NULL;
745
746 assert(strchr(item, ':') != NULL);
747 int src;
748 if(isdigit(item[0])) {
749 src = atoi(item);
750 } else {
751 src = -1;
752 }
753 if(!isdigit(strchr(item, ':')[1])) {
754 log_msg(LOG_LEVEL_ERROR, "Audio destination channel not entered!\n");
755 free(tmp);
756 return false;
757 }
758 int dst = atoi(strchr(item, ':') + 1);
759 if(src >= 0) {
760 channel_map->sizes[src] += 1;
761 if(channel_map->map[src] == NULL) {
762 channel_map->map[src] = (int *) malloc(1 * sizeof(int));
763 } else {
764 channel_map->map[src] = (int *) realloc(channel_map->map[src], channel_map->sizes[src] * sizeof(int));
765 }
766 channel_map->map[src][channel_map->sizes[src] - 1] = dst;
767 }
768 }
769
770 free(tmp);
771 tmp = NULL;
772
773 if (!channel_map->validate()) {
774 log_msg(LOG_LEVEL_ERROR, "Wrong audio mapping.\n");
775 return false;
776 }
778
779 return true;
780}
int * sizes
Definition utils.h:171
void compute_contributors()
Definition utils.cpp:804
bool validate()
Definition utils.cpp:791
int size
Definition utils.h:173
int ** map
Definition utils.h:170

References channel_map::compute_contributors(), LOG_LEVEL_ERROR, log_msg(), channel_map::map, channel_map::size, channel_map::sizes, and channel_map::validate().

Referenced by audio_decoder_init(), and init().

Here is the call graph for this function:

◆ remux_and_mix_channel()

void remux_and_mix_channel ( char * out,
const char * in,
int bps,
int frames,
int in_stream_channels,
int out_stream_channels,
int in_channel,
int out_channel,
double scale )

Definition at line 423 of file utils.cpp.

424{
425 int i;
426
427 assert (bps <= 4);
428
429 out += out_channel * bps;
430 in += in_channel * bps;
431
432 for(i = 0; i < frames; i++) {
433 int32_t in_value = format_from_in_bps(in, bps);
434 int32_t out_value = format_from_in_bps(out, bps);
435
436 int32_t new_value = (double)in_value * scale + out_value;
437
438 format_to_out_bps(out, bps, new_value);
439
440 in += in_stream_channels * bps;
441 out += out_stream_channels * bps;
442 }
443}

References audio_desc::bps, format_from_in_bps(), and format_to_out_bps().

Referenced by filter().

Here is the call graph for this function:

◆ remux_channel()

void remux_channel ( char * out,
const char * in,
int bps,
int in_len,
int in_stream_channels,
int out_stream_channels,
int pos_in_stream,
int pos_out_stream )

Definition at line 352 of file utils.cpp.

353{
354 int samples = in_len / (in_stream_channels * bps);
355 int i;
356
357 assert (bps <= 4);
358
359 in += pos_in_stream * bps;
360 out += pos_out_stream * bps;
361
362 for (i = 0; i < samples; ++i) {
363 memcpy(out, in, bps);
364
365 out += bps * out_stream_channels;
366 in += bps * in_stream_channels;
367
368 }
369}

References audio_desc::bps.

Referenced by audio_tx_send_standard(), and vidcap_state_aja::grab().

◆ signed2unsigned()

void signed2unsigned ( char * out,
const char * in,
int in_len )

Converts int8_t samples to uint8_t by adding 128 (standard shifted zero unsigned samples).

Works also in the opposite direction!

Can be used in situ.

Definition at line 515 of file utils.cpp.

516{
517 const auto *inch = reinterpret_cast<const int8_t *>(in);
518 uint8_t *outch = (uint8_t *) out;
519 int items = in_len / sizeof(int8_t);
520
521 while(items-- > 0) {
522 int8_t in_value = *inch++;
523 uint8_t out_value = (int) 128 + in_value;
524 *outch++ = out_value;
525 }
526}

Referenced by audio_cap_alsa_read(), libavcodec_compress(), libavcodec_decompress(), wav_read(), wav_writer_write(), and write_samples().