UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
audio_buffer.c File Reference
#include "audio/types.h"
#include "debug.h"
#include "host.h"
#include "utils/audio_buffer.h"
#include "utils/ring_buffer.h"
Include dependency graph for audio_buffer.c:

Go to the source code of this file.

Classes

struct  audio_buffer
 

Macros

#define AGGRESSIVITY_MAX   4
 
#define AGGRESSIVITY_STEP   100
 
#define BUF_LAST_OVERRUN_THRESHOLD   10000
 
#define BUF_LAST_UNDERRUN_MAX   1000000000
 
#define BUF_LAST_UNDERRUN_THRESHOLD   10000
 
#define max(a, b)
 
#define min(a, b)
 
#define WINDOW   50
 

Functions

void audio_buffer_destroy (struct audio_buffer *buf)
 
struct audio_buffer * audio_buffer_init (int sample_rate, int bps, int ch_count, int suggested_latency_ms)
 
int audio_buffer_read (struct audio_buffer *buf, char *out, int max_len)
 
void audio_buffer_write (struct audio_buffer *buf, const char *in, int len)
 

Variables

struct audio_buffer_api audio_buffer_fns
 
static const int occupacy_windows [] = { 50, 200 }
 

Detailed Description

Author
Martin Pulec pulec.nosp@m.@ces.nosp@m.net.c.nosp@m.z

Definition in file audio_buffer.c.

Macro Definition Documentation

◆ AGGRESSIVITY_MAX

#define AGGRESSIVITY_MAX   4

Definition at line 60 of file audio_buffer.c.

Referenced by audio_buffer_read().

◆ AGGRESSIVITY_STEP

#define AGGRESSIVITY_STEP   100

Definition at line 61 of file audio_buffer.c.

Referenced by audio_buffer_init(), and audio_buffer_read().

◆ BUF_LAST_OVERRUN_THRESHOLD

#define BUF_LAST_OVERRUN_THRESHOLD   10000

Definition at line 59 of file audio_buffer.c.

Referenced by audio_buffer_read().

◆ BUF_LAST_UNDERRUN_MAX

#define BUF_LAST_UNDERRUN_MAX   1000000000

Definition at line 57 of file audio_buffer.c.

Referenced by audio_buffer_init(), and audio_buffer_read().

◆ BUF_LAST_UNDERRUN_THRESHOLD

#define BUF_LAST_UNDERRUN_THRESHOLD   10000

Definition at line 58 of file audio_buffer.c.

Referenced by audio_buffer_read().

◆ max

#define max ( a,
b )
Value:
(((a) > (b))? (a): (b))

Definition at line 54 of file audio_buffer.c.

Referenced by audio_buffer_read().

◆ min

#define min ( a,
b )
Value:
(((a) < (b))? (a): (b))

Definition at line 55 of file audio_buffer.c.

Referenced by audio_buffer_read().

◆ WINDOW

#define WINDOW   50

Definition at line 50 of file audio_buffer.c.

Referenced by audio_buffer_read(), and audio_buffer_write().

Function Documentation

◆ audio_buffer_destroy()

void audio_buffer_destroy ( struct audio_buffer * buf)

Definition at line 99 of file audio_buffer.c.

100{
101 if (!buf) {
102 return;
103 }
105 free(buf);
106}
void ring_buffer_destroy(struct ring_buffer *ring)
ring_buffer_t * ring

References audio_buffer::ring, and ring_buffer_destroy().

Referenced by am_participant::~am_participant(), audio_play_alsa_done(), audio_play_alsa_reconfigure(), and cleanup().

Here is the call graph for this function:

◆ audio_buffer_init()

struct audio_buffer * audio_buffer_init ( int sample_rate,
int bps,
int ch_count,
int suggested_latency_ms )

Definition at line 80 of file audio_buffer.c.

81{
82 struct audio_buffer *buf = calloc(1, sizeof(struct audio_buffer));
84 buf->desc.bps = bps;
85 buf->desc.ch_count = ch_count;
86
88
89 buf->ring = ring_buffer_init(sample_rate * bps * ch_count);
90
92
93 buf->aggressivity = 1;
95
96 return buf;
97}
int int int sample_rate
#define AGGRESSIVITY_STEP
#define BUF_LAST_UNDERRUN_MAX
struct ring_buffer * ring_buffer_init(int size)
struct audio_desc desc
int suggested_latency_ms
int last_aggressivity_change
int sample_rate
Definition types.h:78
int ch_count
Definition types.h:79
int bps
Definition types.h:77

References audio_buffer::aggressivity, AGGRESSIVITY_STEP, audio_desc::bps, BUF_LAST_UNDERRUN_MAX, audio_desc::ch_count, audio_buffer::desc, audio_buffer::last_aggressivity_change, audio_buffer::last_underrun, audio_buffer::ring, ring_buffer_init(), audio_desc::sample_rate, sample_rate, and audio_buffer::suggested_latency_ms.

Referenced by am_participant::am_participant(), audio_play_alsa_reconfigure(), audio_play_ca_reconfigure(), audio_play_jack_reconfigure(), and audio_play_portaudio_reconfigure().

Here is the call graph for this function:

◆ audio_buffer_read()

int audio_buffer_read ( struct audio_buffer * buf,
char * out,
int max_len )

Definition at line 108 of file audio_buffer.c.

109{
110 if (buf->out_pkt_size > 0) {
111 buf->out_pkt_size = (max_len + (buf->out_pkt_size * (WINDOW-1))) / WINDOW;
112 } else {
113 buf->out_pkt_size = max_len;
114 }
115
116 int ring_size = ring_get_current_size(buf->ring);
117
118 for (unsigned int i = 0; i < sizeof buf->avg_occupancy / sizeof buf->avg_occupancy[0]; ++i) {
119 if (buf->avg_occupancy[i] > 0) {
120 buf->avg_occupancy[i] = (ring_size + (buf->avg_occupancy[i] * (occupacy_windows[i] -1))) / occupacy_windows[i];
121 } else {
122 buf->avg_occupancy[i] = ring_size;
123 }
124 }
125
126 // handle underruns
127 if (ring_size < max_len) {
128 buf->last_underrun = 0;
129 } else {
131 buf->last_underrun += 1;
132 }
133 }
134
135 int suggested_latency_bytes = buf->suggested_latency_ms * buf->desc.bps * buf->desc.ch_count * buf->desc.sample_rate / 1000;
136 int requested_latency_bytes = max(suggested_latency_bytes, 2*max(buf->in_pkt_size, buf->out_pkt_size));
137
138 int ret = ring_buffer_read(buf->ring, out, max_len);
139
140 // fiddle aggressivity
146 buf->aggressivity = max(buf->aggressivity - 1, 1);
147 }
148 } else {
149 buf->last_aggressivity_change += 1;
150 }
151
152 // handle overruns
153 int remaining_bytes = ring_size - ret;
154 if (requested_latency_bytes < remaining_bytes) {
155 int len_drop = (1<<buf->aggressivity) * buf->desc.bps * buf->desc.ch_count * 128;
156 len_drop = min(len_drop, remaining_bytes / 2);
157
158 char *tmp = alloca(len_drop);
159 ring_buffer_read(buf->ring, tmp, len_drop);
160 buf->last_overrun = 0;
161 log_msg(LOG_LEVEL_VERBOSE, "Dropped audio samples: req latency %d remaining %d dropped %d!\n", requested_latency_bytes, remaining_bytes, len_drop);
162 } else {
163 buf->last_overrun += 1;
164 }
165
166 log_msg(LOG_LEVEL_DEBUG, "buf - in a. %d, out a. %d, occ. a. [%d,%d] last under/overrun %d, %d aggressivity %d\n", buf->in_pkt_size, buf->out_pkt_size, buf->avg_occupancy[0],buf->avg_occupancy[1], buf->last_underrun, buf->last_overrun, buf->aggressivity);
167
168 return ret;
169}
#define BUF_LAST_UNDERRUN_THRESHOLD
static const int occupacy_windows[]
#define WINDOW
#define BUF_LAST_OVERRUN_THRESHOLD
#define AGGRESSIVITY_MAX
#define min(a, b)
#define max(a, b)
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_VERBOSE
Definition debug.h:63
#define LOG_LEVEL_DEBUG
Definition kernels.cu:48
int ring_get_current_size(struct ring_buffer *ring)
int ring_buffer_read(struct ring_buffer *ring, char *out, int max_len)
int avg_occupancy[2]

References audio_buffer::aggressivity, AGGRESSIVITY_MAX, AGGRESSIVITY_STEP, audio_buffer::avg_occupancy, audio_desc::bps, BUF_LAST_OVERRUN_THRESHOLD, BUF_LAST_UNDERRUN_MAX, BUF_LAST_UNDERRUN_THRESHOLD, audio_desc::ch_count, audio_buffer::desc, audio_buffer::in_pkt_size, audio_buffer::last_aggressivity_change, audio_buffer::last_overrun, audio_buffer::last_underrun, LOG_LEVEL_DEBUG, LOG_LEVEL_VERBOSE, log_msg(), max, min, occupacy_windows, audio_buffer::out_pkt_size, audio_buffer::ring, ring_buffer_read(), ring_get_current_size(), audio_desc::sample_rate, audio_buffer::suggested_latency_ms, and WINDOW.

Referenced by alsa_play_async_callback(), callback(), state_audio_mixer::worker(), and worker().

Here is the call graph for this function:

◆ audio_buffer_write()

void audio_buffer_write ( struct audio_buffer * buf,
const char * in,
int len )

Definition at line 171 of file audio_buffer.c.

172{
173 if (buf->in_pkt_size > 0) {
174 buf->in_pkt_size = (len + (buf->in_pkt_size * (WINDOW-1))) / WINDOW;
175 } else {
176 buf->in_pkt_size = len;
177 }
178 ring_buffer_write(buf->ring, in, len);
179}
int void size_t * len
void ring_buffer_write(struct ring_buffer *ring, const char *in, int len)

References audio_buffer::in_pkt_size, len, audio_buffer::ring, ring_buffer_write(), and WINDOW.

Referenced by audio_play_alsa_put_frame(), audio_play_mixer_put_frame(), and audio_play_portaudio_put_frame().

Here is the call graph for this function:

Variable Documentation

◆ audio_buffer_fns

struct audio_buffer_api audio_buffer_fns
Initial value:
= {
(void (*)(void *)) audio_buffer_destroy,
(int (*)(void *, char *, int)) audio_buffer_read,
(void (*)(void *, const char *, int)) audio_buffer_write,
}
void audio_buffer_destroy(struct audio_buffer *buf)
int audio_buffer_read(struct audio_buffer *buf, char *out, int max_len)
void audio_buffer_write(struct audio_buffer *buf, const char *in, int len)

Definition at line 181 of file audio_buffer.c.

181 {
182 (void (*)(void *)) audio_buffer_destroy,
183 (int (*)(void *, char *, int)) audio_buffer_read,
184 (void (*)(void *, const char *, int)) audio_buffer_write,
185};

Referenced by audio_play_ca_reconfigure(), and audio_play_jack_reconfigure().

◆ occupacy_windows

const int occupacy_windows[] = { 50, 200 }
static

Definition at line 63 of file audio_buffer.c.

63{ 50, 200 };

Referenced by audio_buffer_read().