on restart request desired state of devices is evaluated, devices will be
closed, left prepared, started depending on selected options or their usage
(number or connected ports)
Change-Id: Id512e013556169dfc3837fd5f10845848a211d5b
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
(cherry picked from commit 9bdb9d09de)
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
pull/608/head
| @@ -349,6 +349,12 @@ int JackAlsaDriver::Open(alsa_driver_info_t info) | |||
| fDriver = alsa_driver_new ((char*)"alsa_pcm", info, NULL); | |||
| if (fDriver) { | |||
| /* we need to initialize variables for all devices, mainly channels count since this is required by Jack to setup ports */ | |||
| UpdateDriverTargetState(1); | |||
| if (alsa_driver_open((alsa_driver_t *)fDriver) < 0) { | |||
| Close(); | |||
| return -1; | |||
| } | |||
| // ALSA driver may have changed the in/out values | |||
| fCaptureChannels = ((alsa_driver_t *)fDriver)->capture_nchannels; | |||
| fPlaybackChannels = ((alsa_driver_t *)fDriver)->playback_nchannels; | |||
| @@ -360,6 +366,7 @@ int JackAlsaDriver::Open(alsa_driver_info_t info) | |||
| } | |||
| } | |||
| #endif | |||
| return 0; | |||
| } else { | |||
| Close(); | |||
| @@ -372,6 +379,8 @@ int JackAlsaDriver::Close() | |||
| // Generic audio driver close | |||
| int res = JackAudioDriver::Close(); | |||
| alsa_driver_close((alsa_driver_t *)fDriver); | |||
| if (fDriver) { | |||
| alsa_driver_delete((alsa_driver_t*)fDriver); | |||
| } | |||
| @@ -424,6 +433,23 @@ int JackAlsaDriver::Stop() | |||
| return res; | |||
| } | |||
| int JackAlsaDriver::Reload() | |||
| { | |||
| UpdateDriverTargetState(); | |||
| alsa_driver_t* driver = (alsa_driver_t*) fDriver; | |||
| if (alsa_driver_close (driver) < 0) { | |||
| jack_error("JackAlsaDriver::Reload close failed"); | |||
| return -1; | |||
| } | |||
| if (alsa_driver_open (driver) < 0) { | |||
| jack_error("JackAlsaDriver::Reload open failed"); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| int JackAlsaDriver::Read() | |||
| { | |||
| /* Taken from alsa_driver_run_cycle */ | |||
| @@ -503,6 +529,48 @@ int JackAlsaDriver::PortSetDefaultMetadata(jack_port_id_t port_id, const char* p | |||
| return fEngine->PortSetDefaultMetadata(fClientControl.fRefNum, port_id, pretty_name); | |||
| } | |||
| int JackAlsaDriver::UpdateDriverTargetState(int init) | |||
| { | |||
| int c_list_index = 0, p_list_index = 0; | |||
| alsa_driver_t* driver = (alsa_driver_t*) fDriver; | |||
| for (int i = 0; i < driver->devices_count; ++i) { | |||
| alsa_device_t *device = &driver->devices[i]; | |||
| int capture_connections_count = 0; | |||
| for (int j = 0; j < device->capture_nchannels; ++j) { | |||
| capture_connections_count += fGraphManager->GetConnectionsNum(fCapturePortList[c_list_index]); | |||
| c_list_index++; | |||
| } | |||
| device->capture_target_state = TargetState(init, capture_connections_count); | |||
| int playback_connections_count = 0; | |||
| for (int j = 0; j < device->playback_nchannels; ++j) { | |||
| playback_connections_count += fGraphManager->GetConnectionsNum(fPlaybackPortList[p_list_index]); | |||
| p_list_index++; | |||
| } | |||
| device->playback_target_state = TargetState(init, playback_connections_count); | |||
| } | |||
| return 0; | |||
| } | |||
| int JackAlsaDriver::TargetState(int init, int connections_count) | |||
| { | |||
| alsa_driver_t* driver = (alsa_driver_t*) fDriver; | |||
| int state = SND_PCM_STATE_PREPARED; | |||
| if (connections_count > 0) { | |||
| state = SND_PCM_STATE_RUNNING; | |||
| } else if (init) { | |||
| state = SND_PCM_STATE_RUNNING; | |||
| } else { | |||
| state = SND_PCM_STATE_PREPARED; | |||
| } | |||
| return state; | |||
| } | |||
| void JackAlsaDriver::WriteOutputAux(alsa_device_t *device, jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten) | |||
| { | |||
| /* global channel offset to fPlaybackPortList of this playback alsa device */ | |||
| @@ -59,6 +59,7 @@ class JackAlsaDriver : public JackAudioDriver | |||
| int Start(); | |||
| int Stop(); | |||
| int Reload(); | |||
| int Read(); | |||
| int Write(); | |||
| @@ -79,6 +80,10 @@ class JackAlsaDriver : public JackAudioDriver | |||
| int PortSetDefaultMetadata(jack_port_id_t port_id, const char* pretty_name); | |||
| int UpdateDriverTargetState(int init = 0); | |||
| int TargetState(int init, int connections_count); | |||
| // JACK API emulation for the midi driver | |||
| int is_realtime() const; | |||
| int create_thread(pthread_t *thread, int prio, int rt, void *(*start_func)(void*), void *arg); | |||
| @@ -54,8 +54,10 @@ | |||
| #define SND_PCM_FORMAT_S32_LE SND_PCM_SFMT_S32_LE | |||
| #define SND_PCM_FORMAT_S32_BE SND_PCM_SFMT_S32_BE | |||
| #define SND_PCM_FORMAT_FLOAT_LE SND_PCM_SFMT_FLOAT_LE | |||
| #define SND_PCM_STATE_PREPARED SND_PCM_STATUS_PREPARED | |||
| #define SND_PCM_STATE_SUSPENDED SND_PCM_STATUS_SUSPENDED | |||
| #define SND_PCM_STATE_XRUN SND_PCM_STATUS_UNDERRUN | |||
| #define SND_PCM_STATE_RUNNING SND_PCM_STATUS_RUNNING | |||
| #define SND_PCM_STREAM_PLAYBACK SND_PCM_CHANNEL_PLAYBACK | |||
| #define SND_PCM_STREAM_CAPTURE SND_PCM_CHANNEL_CAPTURE | |||
| @@ -128,13 +130,17 @@ typedef struct _alsa_device { | |||
| unsigned long playback_sample_bytes; | |||
| unsigned long capture_sample_bytes; | |||
| /* is this device linked to first device */ | |||
| /* device is 'snd_pcm_link' to a group, only 1 group of linked devices is allowed */ | |||
| int capture_linked; | |||
| int playback_linked; | |||
| int capture_xrun_count; | |||
| int playback_xrun_count; | |||
| /* desired state of device, decided by JackAlsaDriver */ | |||
| int capture_target_state; | |||
| int playback_target_state; | |||
| jack_hardware_t *hw; | |||
| char *alsa_driver; | |||
| } alsa_device_t; | |||
| @@ -198,6 +204,8 @@ typedef struct _alsa_driver { | |||
| int devices_count; | |||
| int devices_c_count; | |||
| int devices_p_count; | |||
| int features; | |||
| } alsa_driver_t; | |||
| typedef struct _alsa_device_info { | |||
| @@ -232,6 +240,8 @@ typedef struct _alsa_driver_info { | |||
| int hw_metering; | |||
| int monitor; | |||
| int soft_mode; | |||
| int features; | |||
| } alsa_driver_info_t; | |||
| static inline void | |||
| @@ -311,12 +321,18 @@ alsa_driver_new (char *name, alsa_driver_info_t info, jack_client_t *client); | |||
| void | |||
| alsa_driver_delete (alsa_driver_t *driver); | |||
| int | |||
| alsa_driver_open (alsa_driver_t *driver); | |||
| int | |||
| alsa_driver_start (alsa_driver_t *driver); | |||
| int | |||
| alsa_driver_stop (alsa_driver_t *driver); | |||
| int | |||
| alsa_driver_close (alsa_driver_t *driver); | |||
| jack_nframes_t | |||
| alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *status, float | |||
| *delayed_usecs); | |||
| @@ -334,6 +350,7 @@ void MonitorInput(); | |||
| void ClearOutput(); | |||
| void WriteOutput(alsa_device_t *device, jack_nframes_t orig_nframes, snd_pcm_sframes_t contiguous, snd_pcm_sframes_t nwritten); | |||
| void SetTime(jack_time_t time); | |||
| int Restart(); | |||
| #ifdef __cplusplus | |||