diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 62d9f43b..3cfa54d7 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -279,7 +279,8 @@ int JackAlsaDriver::Open(jack_nframes_t nframes, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency, - const char* midi_driver_name) + const char* midi_driver_name, + int hw_timestamping) { // Generic JackAudioDriver Open if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, @@ -339,7 +340,8 @@ int JackAlsaDriver::Open(jack_nframes_t nframes, shorts_first, capture_latency, playback_latency, - midi); + midi, + hw_timestamping); if (fDriver) { // ALSA driver may have changed the in/out values fCaptureChannels = ((alsa_driver_t *)fDriver)->capture_nchannels; @@ -750,6 +752,9 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () "ALSA MIDI driver", NULL); + value.i = 0; + jack_driver_descriptor_add_parameter(desc, &filler, "htstamps", 't', JackDriverParamBool, &value, NULL, "Enable htimestamping for the ALSA devices", NULL); + return desc; } @@ -777,6 +782,7 @@ SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLocke const JSList * node; const jack_driver_param_t * param; const char *midi_driver = "none"; + int hw_timestamping = FALSE; for (node = params; node; node = jack_slist_next (node)) { param = (const jack_driver_param_t *) node->data; @@ -875,6 +881,10 @@ SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLocke case 'X': midi_driver = strdup(param->value.str); break; + + case 't': + hw_timestamping = param->value.i; + break; } } @@ -889,7 +899,7 @@ SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLocke // Special open for ALSA driver... if (g_alsa_driver->Open(frames_per_interrupt, user_nperiods, srate, hw_monitoring, hw_metering, capture, playback, dither, soft_mode, monitor, user_capture_nchnls, user_playback_nchnls, shorts_first, capture_pcm_name, playback_pcm_name, - systemic_input_latency, systemic_output_latency, midi_driver) == 0) { + systemic_input_latency, systemic_output_latency, midi_driver, hw_timestamping) == 0) { return threaded_driver; } else { delete threaded_driver; // Delete the decorated driver diff --git a/linux/alsa/JackAlsaDriver.h b/linux/alsa/JackAlsaDriver.h index c62ff541..84d67067 100644 --- a/linux/alsa/JackAlsaDriver.h +++ b/linux/alsa/JackAlsaDriver.h @@ -67,7 +67,8 @@ class JackAlsaDriver : public JackAudioDriver const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency, - const char* midi_driver_name); + const char* midi_driver_name, + int hw_timestamping); int Close(); int Attach(); diff --git a/linux/alsa/alsa_driver.c b/linux/alsa/alsa_driver.c index 7460efdc..be4fa849 100644 --- a/linux/alsa/alsa_driver.c +++ b/linux/alsa/alsa_driver.c @@ -589,6 +589,21 @@ alsa_driver_configure_stream (alsa_driver_t *driver, char *device_name, return -1; } + if (driver->hw_timestamping) { + err = snd_pcm_sw_params_set_tstamp_mode(handle, sw_params, + SND_PCM_TSTAMP_ENABLE); + if (err < 0) { + jack_info("Could not enable ALSA time stamp mode for %s (err %d)", + stream_name, err); + } + err = snd_pcm_sw_params_set_tstamp_type(handle, sw_params, + SND_PCM_TSTAMP_TYPE_MONOTONIC); + if (err < 0) { + jack_info("Could not use monotonic ALSA time stamps for %s (err %d)", + stream_name, err); + } + } + if ((err = snd_pcm_sw_params (handle, sw_params)) < 0) { jack_error ("ALSA: cannot set software parameters for %s\n", stream_name); @@ -1942,7 +1957,8 @@ alsa_driver_new (char *name, char *playback_alsa_device, int shorts_first, jack_nframes_t capture_latency, jack_nframes_t playback_latency, - alsa_midi_t *midi_driver + alsa_midi_t *midi_driver, + int hw_timestamping ) { int err; @@ -2028,6 +2044,7 @@ alsa_driver_new (char *name, char *playback_alsa_device, driver->alsa_name_capture = strdup (capture_alsa_device); driver->midi = midi_driver; + driver->hw_timestamping = hw_timestamping; driver->xrun_recovery = 0; if (alsa_driver_check_card_type (driver)) { diff --git a/linux/alsa/alsa_driver.h b/linux/alsa/alsa_driver.h index efe93de5..f755fcce 100644 --- a/linux/alsa/alsa_driver.h +++ b/linux/alsa/alsa_driver.h @@ -124,6 +124,7 @@ typedef struct _alsa_driver { char has_hw_monitoring; char has_hw_metering; char quirk_bswap; + char hw_timestamping; ReadCopyFunction read_via_copy; WriteCopyFunction write_via_copy; @@ -248,7 +249,8 @@ alsa_driver_new (char *name, char *playback_alsa_device, int shorts_first, jack_nframes_t capture_latency, jack_nframes_t playback_latency, - alsa_midi_t *midi_driver + alsa_midi_t *midi_driver, + int hw_timestamping ); void alsa_driver_delete (alsa_driver_t *driver);