Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
Improve pcm underrun and overrun recovery.
Enlarge buffer sizes to avoid underruns or overruns.
  • Loading branch information
i-rinat committed Apr 18, 2017
2 parents ec575ce + e59f74b commit 86f0841
Showing 1 changed file with 60 additions and 1 deletion.
61 changes: 60 additions & 1 deletion src/apulse-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,64 @@ data_available_for_stream(pa_mainloop_api *a, pa_io_event *ioe, int fd, pa_io_ev
ret = snd_pcm_recover(s->ph, frame_count, 1);
} while (ret == -1 && errno == EINTR && cnt < 5);

switch (snd_pcm_state(s->ph)) {
case SND_PCM_STATE_OPEN:
// Highly unlikely device will be here in this state. But if it is, there is nothing
// can be done.
trace_error(
"Stream '%s' of context '%s' have its associated PCM device in "
"SND_PCM_STATE_OPEN state. Reconfiguration is required, but is not possible at "
"the moment. Giving up.",
s->name ? s->name : "", s->c->name ? s->c->name : "");
break;

case SND_PCM_STATE_SETUP:
// There is configuration, but device is not prepared and not started.
snd_pcm_prepare(s->ph);
snd_pcm_start(s->ph);
break;

case SND_PCM_STATE_PREPARED:
// Device prepared, but not started.
snd_pcm_start(s->ph);
break;

case SND_PCM_STATE_RUNNING:
// That's the expected state.
break;

case SND_PCM_STATE_XRUN:
trace_error(
"Stream '%s' of context '%s' have its associated device in SND_PCM_STATE_XRUN "
"state even after xrun recovery.",
s->name ? s->name : "", s->c->name ? s->c->name : "");
break;

case SND_PCM_STATE_DRAINING:
trace_error(
"Stream '%s' of context '%s' have its associated device in "
"SND_PCM_STATE_DRAINING state, which is highly unusual.",
s->name ? s->name : "", s->c->name ? s->c->name : "");
break;

case SND_PCM_STATE_PAUSED:
// Resume from paused state.
snd_pcm_pause(s->ph, 0);
break;

case SND_PCM_STATE_SUSPENDED:
// Resume from suspended state.
snd_pcm_resume(s->ph);
break;

case SND_PCM_STATE_DISCONNECTED:
trace_error(
"Stream '%s' of context '%s' have its associated device in "
"SND_PCM_STATE_DISCONNECTED state. Giving up.",
s->name ? s->name : "", s->c->name ? s->c->name : "");
break;
}

#if HAVE_SND_PCM_AVAIL
frame_count = snd_pcm_avail(s->ph);
#else
Expand Down Expand Up @@ -282,8 +340,9 @@ do_connect_pcm(pa_stream *s, snd_pcm_stream_t stream_direction)
trace_info_f("%s: requested period size of %d frames, got %d frames for %s\n", __func__,
(int)requested_period_size, (int)period_size, device_description);

// Set up buffer size. Ensure it's at least four times larger than a period size.
snd_pcm_uframes_t requested_buffer_size = s->buffer_attr.tlength / frame_size;
snd_pcm_uframes_t buffer_size = requested_buffer_size;
snd_pcm_uframes_t buffer_size = MAX(requested_buffer_size, 4 * period_size);
errcode = snd_pcm_hw_params_set_buffer_size_near(s->ph, hw_params, &buffer_size);
if (errcode != 0) {
trace_error(
Expand Down

0 comments on commit 86f0841

Please sign in to comment.