mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2025-01-03 14:15:47 +00:00
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:
parent
a37b8cf847
commit
8e30053962
|
@ -1006,14 +1006,15 @@ SOUNDIO_EXPORT int soundio_outstream_end_write(struct SoundIoOutStream *outstrea
|
||||||
/// * #SoundIoErrorIncompatibleDevice
|
/// * #SoundIoErrorIncompatibleDevice
|
||||||
SOUNDIO_EXPORT int soundio_outstream_clear_buffer(struct SoundIoOutStream *outstream);
|
SOUNDIO_EXPORT int soundio_outstream_clear_buffer(struct SoundIoOutStream *outstream);
|
||||||
|
|
||||||
/// If the underlying device supports pausing, this pauses the stream.
|
/// If the underlying backend and device support pausing, this pauses the
|
||||||
/// SoundIoOutStream::write_callback may be called a few more times if the
|
/// stream. SoundIoOutStream::write_callback may be called a few more times if
|
||||||
/// buffer is not full.
|
/// the buffer is not full.
|
||||||
/// Pausing might put the hardware into a low power state which is ideal if your
|
/// Pausing might put the hardware into a low power state which is ideal if your
|
||||||
/// software is silent for some time.
|
/// 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
|
/// Pausing when already paused or unpausing when already unpaused has no
|
||||||
/// effect and always returns SoundIoErrorNone.
|
/// effect and returns #SoundIoErrorNone.
|
||||||
///
|
///
|
||||||
/// Possible errors:
|
/// Possible errors:
|
||||||
/// * #SoundIoErrorBackendDisconnected
|
/// * #SoundIoErrorBackendDisconnected
|
||||||
|
@ -1021,6 +1022,8 @@ SOUNDIO_EXPORT int soundio_outstream_clear_buffer(struct SoundIoOutStream *outst
|
||||||
/// * #SoundIoErrorIncompatibleDevice - device does not support
|
/// * #SoundIoErrorIncompatibleDevice - device does not support
|
||||||
/// pausing/unpausing. This error code might not be returned even if the
|
/// pausing/unpausing. This error code might not be returned even if the
|
||||||
/// device does not support pausing/unpausing.
|
/// device does not support pausing/unpausing.
|
||||||
|
/// * #SoundIoErrorIncompatibleBackend - backend does not support
|
||||||
|
/// pausing/unpausing.
|
||||||
/// * #SoundIoErrorInvalid - outstream not opened and started
|
/// * #SoundIoErrorInvalid - outstream not opened and started
|
||||||
SOUNDIO_EXPORT int soundio_outstream_pause(struct SoundIoOutStream *outstream, bool pause);
|
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.
|
/// #SoundIoErrorIncompatibleDevice.
|
||||||
/// This function may be called from any thread.
|
/// This function may be called from any thread.
|
||||||
/// Pausing when already paused or unpausing when already unpaused has no
|
/// Pausing when already paused or unpausing when already unpaused has no
|
||||||
/// effect and always returns SoundIoErrorNone.
|
/// effect and always returns #SoundIoErrorNone.
|
||||||
///
|
///
|
||||||
/// Possible errors:
|
/// Possible errors:
|
||||||
/// * #SoundIoErrorBackendDisconnected
|
/// * #SoundIoErrorBackendDisconnected
|
||||||
|
|
106
src/jack.cpp
106
src/jack.cpp
|
@ -426,8 +426,6 @@ static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStrea
|
||||||
SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device;
|
SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device;
|
||||||
SoundIoDeviceJack *dj = &dev->backend_data.jack;
|
SoundIoDeviceJack *dj = &dev->backend_data.jack;
|
||||||
|
|
||||||
osj->is_paused = true;
|
|
||||||
|
|
||||||
if (sij->is_shutdown)
|
if (sij->is_shutdown)
|
||||||
return SoundIoErrorBackendDisconnected;
|
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) {
|
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;
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
|
|
||||||
if (sij->is_shutdown)
|
if (sij->is_shutdown)
|
||||||
return SoundIoErrorBackendDisconnected;
|
return SoundIoErrorBackendDisconnected;
|
||||||
|
|
||||||
int err;
|
return SoundIoErrorIncompatibleBackend;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int outstream_start_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
|
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,
|
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) {
|
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;
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
|
|
||||||
if (sij->is_shutdown)
|
if (sij->is_shutdown)
|
||||||
return SoundIoErrorBackendDisconnected;
|
return SoundIoErrorBackendDisconnected;
|
||||||
|
|
||||||
int err;
|
return SoundIoErrorIncompatibleBackend;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int instream_start_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) {
|
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,
|
static int instream_begin_read_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is,
|
||||||
|
|
|
@ -49,7 +49,6 @@ struct SoundIoOutStreamJack {
|
||||||
jack_client_t *client;
|
jack_client_t *client;
|
||||||
int period_size;
|
int period_size;
|
||||||
int frames_left;
|
int frames_left;
|
||||||
bool is_paused;
|
|
||||||
double hardware_latency;
|
double hardware_latency;
|
||||||
SoundIoOutStreamJackPort ports[SOUNDIO_MAX_CHANNELS];
|
SoundIoOutStreamJackPort ports[SOUNDIO_MAX_CHANNELS];
|
||||||
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
|
||||||
|
|
Loading…
Reference in a new issue