UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
audio_buffer.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  audio_buffer_api
 

Typedefs

typedef struct audio_buffer audio_buffer_t
 

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
 

Detailed Description

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

Definition in file audio_buffer.h.

Typedef Documentation

◆ audio_buffer_t

typedef struct audio_buffer audio_buffer_t

Definition at line 46 of file audio_buffer.h.

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
extern

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};
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)

Referenced by audio_play_ca_reconfigure(), and audio_play_jack_reconfigure().