JACK: delete broken pause implementation

Previously, calling soundio_outstream_pause or soundio_instream_pause
during the write_callback or read_callback would cause a deadlock. Now,
attempting to pause always results in SoundIoErrorBackendIncompatible.

Closes #39
This commit is contained in:
Andrew Kelley 2015-10-28 16:01:08 -07:00
parent a37b8cf847
commit 8e30053962
3 changed files with 59 additions and 63 deletions

View file

@ -1006,14 +1006,15 @@ SOUNDIO_EXPORT int soundio_outstream_end_write(struct SoundIoOutStream *outstrea
/// * #SoundIoErrorIncompatibleDevice
SOUNDIO_EXPORT int soundio_outstream_clear_buffer(struct SoundIoOutStream *outstream);
/// If the underlying device supports pausing, this pauses the stream.
/// SoundIoOutStream::write_callback may be called a few more times if the
/// buffer is not full.
/// If the underlying backend and device support pausing, this pauses the
/// stream. SoundIoOutStream::write_callback may be called a few more times if
/// the buffer is not full.
/// Pausing might put the hardware into a low power state which is ideal if your
/// software is silent for some time.
/// This function may be called from any thread.
/// This function may be called from any thread context, including
/// SoundIoOutStream::write_callback.
/// Pausing when already paused or unpausing when already unpaused has no
/// effect and always returns SoundIoErrorNone.
/// effect and returns #SoundIoErrorNone.
///
/// Possible errors:
/// * #SoundIoErrorBackendDisconnected
@ -1021,6 +1022,8 @@ SOUNDIO_EXPORT int soundio_outstream_clear_buffer(struct SoundIoOutStream *outst
/// * #SoundIoErrorIncompatibleDevice - device does not support
/// pausing/unpausing. This error code might not be returned even if the
/// device does not support pausing/unpausing.
/// * #SoundIoErrorIncompatibleBackend - backend does not support
/// pausing/unpausing.
/// * #SoundIoErrorInvalid - outstream not opened and started
SOUNDIO_EXPORT int soundio_outstream_pause(struct SoundIoOutStream *outstream, bool pause);
@ -1124,7 +1127,7 @@ SOUNDIO_EXPORT int soundio_instream_end_read(struct SoundIoInStream *instream);
/// #SoundIoErrorIncompatibleDevice.
/// This function may be called from any thread.
/// Pausing when already paused or unpausing when already unpaused has no
/// effect and always returns SoundIoErrorNone.
/// effect and always returns #SoundIoErrorNone.
///
/// Possible errors:
/// * #SoundIoErrorBackendDisconnected

View file

@ -426,8 +426,6 @@ static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStrea
SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device;
SoundIoDeviceJack *dj = &dev->backend_data.jack;
osj->is_paused = true;
if (sij->is_shutdown)
return SoundIoErrorBackendDisconnected;
@ -517,43 +515,38 @@ static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStrea
}
static int outstream_pause_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) {
SoundIoOutStreamJack *osj = &os->backend_data.jack;
SoundIoOutStream *outstream = &os->pub;
SoundIoJack *sij = &si->backend_data.jack;
if (sij->is_shutdown)
return SoundIoErrorBackendDisconnected;
int err;
if (pause) {
if (!osj->is_paused) {
if ((err = jack_deactivate(osj->client)))
return SoundIoErrorStreaming;
osj->is_paused = true;
}
} else {
if (osj->is_paused) {
if ((err = jack_activate(osj->client)))
return SoundIoErrorStreaming;
for (int ch = 0; ch < outstream->layout.channel_count; ch += 1) {
SoundIoOutStreamJackPort *osjp = &osj->ports[ch];
const char *dest_port_name = osjp->dest_port_name;
// allow unconnected ports
if (!dest_port_name)
continue;
const char *source_port_name = jack_port_name(osjp->source_port);
if ((err = jack_connect(osj->client, source_port_name, dest_port_name)))
return SoundIoErrorStreaming;
}
osj->is_paused = false;
}
}
return 0;
return SoundIoErrorIncompatibleBackend;
}
static int outstream_start_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
return outstream_pause_jack(si, os, false);
SoundIoOutStreamJack *osj = &os->backend_data.jack;
SoundIoOutStream *outstream = &os->pub;
SoundIoJack *sij = &si->backend_data.jack;
int err;
if (sij->is_shutdown)
return SoundIoErrorBackendDisconnected;
if ((err = jack_activate(osj->client)))
return SoundIoErrorStreaming;
for (int ch = 0; ch < outstream->layout.channel_count; ch += 1) {
SoundIoOutStreamJackPort *osjp = &osj->ports[ch];
const char *dest_port_name = osjp->dest_port_name;
// allow unconnected ports
if (!dest_port_name)
continue;
const char *source_port_name = jack_port_name(osjp->source_port);
if ((err = jack_connect(osj->client, source_port_name, dest_port_name)))
return SoundIoErrorStreaming;
}
return 0;
}
static int outstream_begin_write_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os,
@ -742,37 +735,38 @@ static int instream_open_jack(struct SoundIoPrivate *si, struct SoundIoInStreamP
}
static int instream_pause_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, bool pause) {
SoundIoInStreamJack *isj = &is->backend_data.jack;
SoundIoInStream *instream = &is->pub;
SoundIoJack *sij = &si->backend_data.jack;
if (sij->is_shutdown)
return SoundIoErrorBackendDisconnected;
int err;
if (pause) {
if ((err = jack_deactivate(isj->client)))
return SoundIoErrorStreaming;
} else {
if ((err = jack_activate(isj->client)))
return SoundIoErrorStreaming;
for (int ch = 0; ch < instream->layout.channel_count; ch += 1) {
SoundIoInStreamJackPort *isjp = &isj->ports[ch];
const char *source_port_name = isjp->source_port_name;
// allow unconnected ports
if (!source_port_name)
continue;
const char *dest_port_name = jack_port_name(isjp->dest_port);
if ((err = jack_connect(isj->client, source_port_name, dest_port_name)))
return SoundIoErrorStreaming;
}
}
return 0;
return SoundIoErrorIncompatibleBackend;
}
static int instream_start_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) {
return instream_pause_jack(si, is, false);
SoundIoInStreamJack *isj = &is->backend_data.jack;
SoundIoInStream *instream = &is->pub;
SoundIoJack *sij = &si->backend_data.jack;
int err;
if (sij->is_shutdown)
return SoundIoErrorBackendDisconnected;
if ((err = jack_activate(isj->client)))
return SoundIoErrorStreaming;
for (int ch = 0; ch < instream->layout.channel_count; ch += 1) {
SoundIoInStreamJackPort *isjp = &isj->ports[ch];
const char *source_port_name = isjp->source_port_name;
// allow unconnected ports
if (!source_port_name)
continue;
const char *dest_port_name = jack_port_name(isjp->dest_port);
if ((err = jack_connect(isj->client, source_port_name, dest_port_name)))
return SoundIoErrorStreaming;
}
return 0;
}
static int instream_begin_read_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is,

View file

@ -49,7 +49,6 @@ struct SoundIoOutStreamJack {
jack_client_t *client;
int period_size;
int frames_left;
bool is_paused;
double hardware_latency;
SoundIoOutStreamJackPort ports[SOUNDIO_MAX_CHANNELS];
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];