summaryrefslogtreecommitdiff
path: root/drivers/alsa
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2013-09-19 21:56:43 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2013-09-19 21:56:43 -0400
commit39e0d9dd7856fb29ea3f3d6af26683dda1556980 (patch)
treeb0bf5c14f4ea658adc1cc7ac8752ff1f658f01c6 /drivers/alsa
parent92468acc967aaae8d6b5079565009c5029ae5e08 (diff)
downloadjack1-39e0d9dd7856fb29ea3f3d6af26683dda1556980.tar.gz
ALSA backend: fall back on previous successful configuration if a new one fails
Diffstat (limited to 'drivers/alsa')
-rw-r--r--drivers/alsa/alsa_driver.c31
-rw-r--r--drivers/alsa/alsa_driver.h1
2 files changed, 24 insertions, 8 deletions
diff --git a/drivers/alsa/alsa_driver.c b/drivers/alsa/alsa_driver.c
index f3320f9..bd8fd85 100644
--- a/drivers/alsa/alsa_driver.c
+++ b/drivers/alsa/alsa_driver.c
@@ -591,6 +591,9 @@ alsa_driver_set_parameters (alsa_driver_t *driver,
unsigned int pr = 0;
unsigned int cr = 0;
int err;
+ jack_nframes_t old_frames_per_cycle = driver->frames_per_cycle;
+ jack_nframes_t old_rate = driver->frame_rate;
+ jack_nframes_t old_user_nperiods = driver->user_nperiods;
driver->frame_rate = rate;
driver->frames_per_cycle = frames_per_cycle;
@@ -612,7 +615,7 @@ alsa_driver_set_parameters (alsa_driver_t *driver,
&driver->capture_nchannels,
driver->capture_sample_bytes)) {
jack_error ("ALSA: cannot configure capture channel");
- return -1;
+ goto errout;
}
}
@@ -628,7 +631,7 @@ alsa_driver_set_parameters (alsa_driver_t *driver,
&driver->playback_nchannels,
driver->playback_sample_bytes)) {
jack_error ("ALSA: cannot configure playback channel");
- return -1;
+ goto errout;
}
}
@@ -698,7 +701,7 @@ alsa_driver_set_parameters (alsa_driver_t *driver,
PRIu32
" frames but got %u frames for playback",
driver->frames_per_cycle, p_period_size);
- return -1;
+ goto errout;
}
}
@@ -721,7 +724,7 @@ alsa_driver_set_parameters (alsa_driver_t *driver,
PRIu32
" frames but got %uc frames for capture",
driver->frames_per_cycle, p_period_size);
- return -1;
+ goto errout;
}
}
@@ -775,7 +778,7 @@ alsa_driver_set_parameters (alsa_driver_t *driver,
&my_areas, &offset, &frames) < 0) {
jack_error ("ALSA: %s: mmap areas info error",
driver->alsa_name_playback);
- return -1;
+ goto errout;
}
driver->interleave_unit =
snd_pcm_format_physical_width (
@@ -791,7 +794,7 @@ alsa_driver_set_parameters (alsa_driver_t *driver,
&my_areas, &offset, &frames) < 0) {
jack_error ("ALSA: %s: mmap areas info error",
driver->alsa_name_capture);
- return -1;
+ goto errout;
}
}
@@ -866,11 +869,23 @@ alsa_driver_set_parameters (alsa_driver_t *driver,
if (driver->engine->set_buffer_size (driver->engine,
driver->frames_per_cycle)) {
jack_error ("ALSA: Cannot set engine buffer size to %d", driver->frames_per_cycle);
- return -1;
+ goto errout;
}
}
+ driver->previously_successfully_configured = TRUE;
return 0;
+
+ errout:
+ if (driver->previously_successfully_configured) {
+ /* attempt to restore previous configuration */
+ jack_info ("ALSA: falling back to old configuration");
+ if (alsa_driver_set_parameters (driver, old_frames_per_cycle, old_user_nperiods, old_rate) == 0) {
+ jack_error ("ALSA: reverted to previous parameters after failure");
+ return 0;
+ }
+ }
+ return -1;
}
static int
@@ -2178,7 +2193,7 @@ alsa_driver_new (char *name, char *playback_alsa_device,
driver->capture_addr = 0;
driver->playback_interleave_skip = NULL;
driver->capture_interleave_skip = NULL;
-
+ driver->previously_successfully_configured = FALSE;
driver->silent = 0;
driver->all_monitor_in = FALSE;
diff --git a/drivers/alsa/alsa_driver.h b/drivers/alsa/alsa_driver.h
index e1e4fa8..67bbc89 100644
--- a/drivers/alsa/alsa_driver.h
+++ b/drivers/alsa/alsa_driver.h
@@ -138,6 +138,7 @@ typedef struct _alsa_driver {
alsa_midi_t *midi;
int xrun_recovery;
+ int previously_successfully_configured;
} alsa_driver_t;