Browse Source

jack alsa: implement restart request [1/3]

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
Adam Miartus Timo Wischer 6 years ago
parent
commit
78e97af266
4 changed files with 601 additions and 334 deletions
  1. +68
    -0
      linux/alsa/JackAlsaDriver.cpp
  2. +5
    -0
      linux/alsa/JackAlsaDriver.h
  3. +510
    -333
      linux/alsa/alsa_driver.c
  4. +18
    -1
      linux/alsa/alsa_driver.h

+ 68
- 0
linux/alsa/JackAlsaDriver.cpp View File

@@ -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 */


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

@@ -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);


+ 510
- 333
linux/alsa/alsa_driver.c
File diff suppressed because it is too large
View File


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

@@ -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


Loading…
Cancel
Save