<div dir="ltr"><div>I open the audio playback device like this:<br><br></div><div><div><font face="monospace, monospace">    pa_threaded_mainloop_lock(audio_hardware->main_loop);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    pa_sample_spec sample_spec;</font></div><div><font face="monospace, monospace">    sample_spec.format = to_pulseaudio_sample_format(sample_format);</font></div><div><font face="monospace, monospace">    sample_spec.rate = audio_device->default_sample_rate;</font></div><div><font face="monospace, monospace">    sample_spec.channels = audio_device->channel_layout.channel_count;</font></div><div><font face="monospace, monospace">    pa_channel_map channel_map = to_pulseaudio_channel_map(&audio_device->channel_layout);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    open_playback_device->stream = pa_stream_new(audio_hardware->pulse_context,</font></div><div><font face="monospace, monospace">            "Genesis", &sample_spec, &channel_map);</font></div><div><font face="monospace, monospace">    // error handling omitted</font></div><div><font face="monospace, monospace">    pa_stream_set_state_callback(open_playback_device->stream, playback_stream_state_callback,</font></div><div><font face="monospace, monospace">            open_playback_device);</font></div><div><font face="monospace, monospace">    pa_stream_set_write_callback(open_playback_device->stream, playback_stream_write_callback,</font></div><div><font face="monospace, monospace">            open_playback_device);</font></div><div><font face="monospace, monospace">    pa_stream_set_underflow_callback(open_playback_device->stream, playback_stream_underflow_callback,</font></div><div><font face="monospace, monospace">            open_playback_device);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    open_playback_device->bytes_per_frame = genesis_get_bytes_per_frame(sample_format,</font></div><div><font face="monospace, monospace">            audio_device->channel_layout.channel_count);</font></div><div><font face="monospace, monospace">    int bytes_per_second = open_playback_device->bytes_per_frame * audio_device->default_sample_rate;</font></div><div><font face="monospace, monospace">    int buffer_length = open_playback_device->bytes_per_frame *</font></div><div><font face="monospace, monospace">        ceil(latency * bytes_per_second / (double)open_playback_device->bytes_per_frame);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    open_playback_device->buffer_attr.maxlength = buffer_length;</font></div><div><font face="monospace, monospace">    open_playback_device->buffer_attr.tlength = buffer_length;</font></div><div><font face="monospace, monospace">    open_playback_device->buffer_attr.prebuf = 0;</font></div><div><font face="monospace, monospace">    open_playback_device->buffer_attr.minreq = UINT32_MAX;</font></div><div><font face="monospace, monospace">    open_playback_device->buffer_attr.fragsize = UINT32_MAX;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    pa_stream_connect_playback(open_playback_device->stream,</font></div><div><font face="monospace, monospace">            open_playback_device->audio_device->name, &open_playback_device->buffer_attr,</font></div><div><font face="monospace, monospace">            PA_STREAM_ADJUST_LATENCY, nullptr, nullptr);</font></div><div><font face="monospace, monospace">    // error handling omitted</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    while (!open_playback_device->stream_ready)</font></div><div><font face="monospace, monospace">        pa_threaded_mainloop_wait(audio_hardware->main_loop);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    pa_threaded_mainloop_unlock(audio_hardware->main_loop);</font></div></div><div><br></div><div><br></div><div>Here is some output from my program. When it prints UNDERRUN that means the underflow callback was called. The number is the number of seconds that the write callback took to fill the playback buffer. In this example the audio device is opened with latency set to 10ms, e.g. 0.01 seconds. The percent is how long the callback took out of how long the buffer size is. So that first UNDERRUN makes sense, because the callback took 2x as long as it was supposed to. When an underrun occurs, the playback buffer is filled completely with silence. So why am I getting all these other underflow callbacks when the callback was well within the range of time which should have been fine? Any ideas of things I can do to troubleshoot?</div><div><br></div><div>callback took 0.02038 (203%)</div><div>UNDERRUN</div><div>callback took 0.00395 (39%)</div><div>callback took 0.00397 (39%)</div><div>callback took 0.00282 (28%)</div><div>UNDERRUN</div><div>UNDERRUN</div><div>callback took 0.00236 (23%)</div><div>UNDERRUN</div><div>callback took 0.00347 (34%)</div><div>UNDERRUN</div><div>callback took 0.00282 (28%)</div><div>callback took 0.00371 (37%)</div><div>UNDERRUN</div><div>UNDERRUN</div><div>callback took 0.00140 (13%)</div><div>UNDERRUN</div><div>callback took 0.00355 (35%)</div><div>callback took 0.00450 (44%)</div><div>UNDERRUN</div><div>callback took 0.00273 (27%)</div><div>callback took 0.00379 (37%)</div><div>callback took 0.00207 (20%)</div><div>UNDERRUN</div><div>callback took 0.00120 (11%)</div><div>callback took 0.00397 (39%)</div><div>UNDERRUN</div><div>callback took 0.00197 (19%)</div><div>callback took 0.00121 (12%)</div><div>callback took 0.00394 (39%)</div><div>UNDERRUN</div><div>callback took 0.00217 (21%)</div><div>callback took 0.00503 (50%)</div><div>UNDERRUN</div><div>callback took 0.00276 (27%)</div><div>callback took 0.00381 (38%)</div><div>callback took 0.00218 (21%)</div><div>UNDERRUN</div><div>callback took 0.00121 (12%)</div><div>callback took 0.00395 (39%)</div><div>callback took 0.00218 (21%)</div><div>callback took 0.00402 (40%)</div><div>UNDERRUN</div><div>callback took 0.00199 (19%)</div><div>callback took 0.00509 (50%)</div><div>UNDERRUN</div><div>callback took 0.00257 (25%)</div><div>callback took 0.00405 (40%)</div><div>UNDERRUN</div><div>callback took 0.00239 (23%)</div><div>callback took 0.00516 (51%)</div><div>UNDERRUN</div><div>callback took 0.00242 (24%)</div><div>callback took 0.00438 (43%)</div><div>callback took 0.00229 (22%)</div><div>callback took 0.00406 (40%)</div><div>callback took 0.00220 (21%)</div><div>callback took 0.00397 (39%)</div><div>callback took 0.00221 (22%)</div><div>callback took 0.00404 (40%)</div><div>UNDERRUN</div><div>callback took 0.00202 (20%)</div><div>callback took 0.00521 (52%)</div><div>UNDERRUN</div><div>callback took 0.00298 (29%)</div><div>callback took 0.00400 (39%)</div><div>UNDERRUN</div><div>callback took 0.00222 (22%)</div><div>callback took 0.00619 (61%)</div><div>UNDERRUN</div><div>callback took 0.00470 (46%)</div><div>callback took 0.00271 (27%)</div><div>UNDERRUN</div><div>callback took 0.00154 (15%)</div><div>callback took 0.00422 (42%)</div><div>callback took 0.00224 (22%)</div><div>callback took 0.00465 (46%)</div><div>UNDERRUN<br></div></div>