Browse Source

alsa: Delay xrun recovery if first xrun recovery does not heal the xruns

On executing the recovery after XRUN, if we still get an XRUN, delay the start
by RECOVER_DELAY_MS ms.

Signed-off-by: Laxmi Devi <Laxmi.Devi@in.bosch.com>
pull/484/head
Laxmi Devi 6 years ago
parent
commit
8b3ea0522f
4 changed files with 28 additions and 8 deletions
  1. +5
    -3
      linux/alsa/JackAlsaDriver.cpp
  2. +5
    -0
      linux/alsa/JackAlsaDriver.h
  3. +17
    -4
      linux/alsa/alsa_driver.c
  4. +1
    -1
      linux/alsa/alsa_driver.h

+ 5
- 3
linux/alsa/JackAlsaDriver.cpp View File

@@ -408,8 +408,6 @@ int JackAlsaDriver::Read()
fDelayedUsecs = 0.f; fDelayedUsecs = 0.f;
int retry_cnt = 0; int retry_cnt = 0;


#define MAX_RECOVERY_RETRY 10

retry: retry:


nframes = alsa_driver_wait((alsa_driver_t *)fDriver, -1, &wait_status, &fDelayedUsecs); nframes = alsa_driver_wait((alsa_driver_t *)fDriver, -1, &wait_status, &fDelayedUsecs);
@@ -933,10 +931,14 @@ void SetTime(jack_time_t time)
g_alsa_driver->SetTimetAux(time); g_alsa_driver->SetTimetAux(time);
} }


int Restart()
int Restart(int delay)
{ {
int res; int res;

if ((res = g_alsa_driver->Stop()) == 0) { if ((res = g_alsa_driver->Stop()) == 0) {
if(delay > 0) {
usleep(delay * MS_TO_US);
}
res = g_alsa_driver->Start(); res = g_alsa_driver->Start();
} }
return res; return res;


+ 5
- 0
linux/alsa/JackAlsaDriver.h View File

@@ -26,6 +26,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackTime.h" #include "JackTime.h"
#include "alsa_driver.h" #include "alsa_driver.h"


/* Milli Seconds represented in Micro seconds */
#define MS_TO_US 1000
/* Max re-try count for Alsa XRUNs */
#define MAX_RECOVERY_RETRY 10

namespace Jack namespace Jack
{ {




+ 17
- 4
linux/alsa/alsa_driver.c View File

@@ -58,6 +58,8 @@ char* strcasestr(const char* haystack, const char* needle);
#define XRUN_REPORT_DELAY 0 #define XRUN_REPORT_DELAY 0
/* Max re-try count for Alsa poll timeout handling */ /* Max re-try count for Alsa poll timeout handling */
#define MAX_RETRY_COUNT 5 #define MAX_RETRY_COUNT 5
/* Delay in initiating the second xrun recovery */
#define RECOVER_DELAY_MS 20


void void
jack_driver_init (jack_driver_t *driver) jack_driver_init (jack_driver_t *driver)
@@ -1168,7 +1170,7 @@ alsa_driver_stop (alsa_driver_t *driver)
} }


static int static int
alsa_driver_restart (alsa_driver_t *driver)
alsa_driver_restart (alsa_driver_t *driver, int delay)
{ {
int res; int res;


@@ -1178,7 +1180,7 @@ alsa_driver_restart (alsa_driver_t *driver)
if ((res = driver->nt_stop((struct _jack_driver_nt *) driver))==0) if ((res = driver->nt_stop((struct _jack_driver_nt *) driver))==0)
res = driver->nt_start((struct _jack_driver_nt *) driver); res = driver->nt_start((struct _jack_driver_nt *) driver);
*/ */
res = Restart();
res = Restart(delay);
driver->xrun_recovery = 0; driver->xrun_recovery = 0;


if (res && driver->midi) if (res && driver->midi)
@@ -1192,6 +1194,7 @@ alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed_usecs)
{ {
snd_pcm_status_t *status; snd_pcm_status_t *status;
int res; int res;
int delay = 0;


snd_pcm_status_alloca(&status); snd_pcm_status_alloca(&status);


@@ -1224,10 +1227,11 @@ alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed_usecs)
} }
} }


driver->xrun_count++;

if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN
&& driver->process_count > XRUN_REPORT_DELAY) { && driver->process_count > XRUN_REPORT_DELAY) {
struct timeval now, diff, tstamp; struct timeval now, diff, tstamp;
driver->xrun_count++;
snd_pcm_status_get_tstamp(status,&now); snd_pcm_status_get_tstamp(status,&now);
snd_pcm_status_get_trigger_tstamp(status, &tstamp); snd_pcm_status_get_trigger_tstamp(status, &tstamp);
timersub(&now, &tstamp, &diff); timersub(&now, &tstamp, &diff);
@@ -1247,7 +1251,12 @@ alsa_driver_xrun_recovery (alsa_driver_t *driver, float *delayed_usecs)
} }
} }


if (alsa_driver_restart (driver)) {
/* Try the first xrun recovery without delay and the subsequent ones with delay */
if(driver->xrun_count > 1) {
delay = RECOVER_DELAY_MS;
}

if (alsa_driver_restart (driver, delay)) {
return -1; return -1;
} }
return 0; return 0;
@@ -1536,6 +1545,10 @@ alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float
if (xrun_detected) { if (xrun_detected) {
*status = alsa_driver_xrun_recovery (driver, delayed_usecs); *status = alsa_driver_xrun_recovery (driver, delayed_usecs);
return 0; return 0;
} else {
if(driver->xrun_count > 0) {
driver->xrun_count = 0;
}
} }


*status = 0; *status = 0;


+ 1
- 1
linux/alsa/alsa_driver.h View File

@@ -278,7 +278,7 @@ void MonitorInput();
void ClearOutput(); void ClearOutput();
void WriteOutput(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten); void WriteOutput(jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten);
void SetTime(jack_time_t time); void SetTime(jack_time_t time);
int Restart();
int Restart(int delay);


#ifdef __cplusplus #ifdef __cplusplus
} }


Loading…
Cancel
Save