Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
Update to 4.3.2
**Enhancements**
* A totally new PipeWire backend featuring full synchronisation.

**Bug Fixes**
* Stability improvements for the PulseAudio backend.
* Fix a crash when the Avahi subsystem became disconnected. This is normally a rare occurrence, but Shairport Sync was not dereferencing obsolete data correctly when it happened.
* Set and reset Bonjour flags correctly when it's a Classic Airplay session in AirPlay 2 operation.
* Fix a number of FreeBSD compilation errors and warnings.
* Fix various errors when breaking into an existing session to terminate it. Thanks again to [aaronk6](https://github.com/aaronk6).
* Fix some debug message errors, sigh. Thanks to [Nathan Gray](https://github.com/n8gray).
  • Loading branch information
mikebrady committed Oct 15, 2023
2 parents 728756a + 9732afb commit 2ed5d99
Show file tree
Hide file tree
Showing 16 changed files with 543 additions and 562 deletions.
67 changes: 35 additions & 32 deletions audio_pa.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ pa_threaded_mainloop *mainloop;
pa_mainloop_api *mainloop_api;
pa_context *context;
pa_stream *stream;
char *audio_lmb, *audio_umb, *audio_toq, *audio_eoq;
size_t audio_size = buffer_allocation;
size_t audio_occupancy;
static char *audio_lmb, *audio_umb, *audio_toq, *audio_eoq;
static size_t audio_size = buffer_allocation;
static size_t audio_occupancy;

void context_state_cb(pa_context *context, void *mainloop);
void stream_state_cb(pa_stream *s, void *mainloop);
Expand Down Expand Up @@ -259,27 +259,33 @@ static int play(void *buf, int samples, __attribute__((unused)) int sample_type,
// copy the samples into the queue
check_pa_stream_status(stream, "audio_pa play.");
size_t bytes_to_transfer = samples * 2 * 2;
size_t space_to_end_of_buffer = audio_umb - audio_eoq;
if (space_to_end_of_buffer >= bytes_to_transfer) {
memcpy(audio_eoq, buf, bytes_to_transfer);
audio_occupancy += bytes_to_transfer;
pthread_mutex_lock(&buffer_mutex);
audio_eoq += bytes_to_transfer;
pthread_mutex_unlock(&buffer_mutex);
} else {
memcpy(audio_eoq, buf, space_to_end_of_buffer);
buf += space_to_end_of_buffer;
memcpy(audio_lmb, buf, bytes_to_transfer - space_to_end_of_buffer);
pthread_mutex_lock(&buffer_mutex);

pthread_mutex_lock(&buffer_mutex);
size_t bytes_available = audio_size - audio_occupancy;
if (bytes_available < bytes_to_transfer)
bytes_to_transfer = bytes_available;
if (bytes_to_transfer > 0) {
size_t space_to_end_of_buffer = audio_umb - audio_eoq;
if (space_to_end_of_buffer >= bytes_to_transfer) {
memcpy(audio_eoq, buf, bytes_to_transfer);
audio_eoq += bytes_to_transfer;
} else {
memcpy(audio_eoq, buf, space_to_end_of_buffer);
buf += space_to_end_of_buffer;
memcpy(audio_lmb, buf, bytes_to_transfer - space_to_end_of_buffer);
audio_eoq = audio_lmb + bytes_to_transfer - space_to_end_of_buffer;
}
audio_occupancy += bytes_to_transfer;
pthread_mutex_unlock(&buffer_mutex);
audio_eoq = audio_lmb + bytes_to_transfer - space_to_end_of_buffer;
}

if ((audio_occupancy >= 11025 * 2 * 2) && (pa_stream_is_corked(stream))) {
// debug(1,"Uncorked");
pthread_mutex_unlock(&buffer_mutex);
pa_threaded_mainloop_lock(mainloop);
pa_stream_cork(stream, 0, stream_success_cb, mainloop);
pa_threaded_mainloop_unlock(mainloop);
} else {
pthread_mutex_unlock(&buffer_mutex);
}
return 0;
}
Expand Down Expand Up @@ -308,18 +314,20 @@ int pa_delay(long *the_delay) {
return reply;
}

void flush(void) {
static void flush(void) {
check_pa_stream_status(stream, "audio_pa flush.");
pa_threaded_mainloop_lock(mainloop);
if (pa_stream_is_corked(stream) == 0) {
// debug(1,"Flush and cork for flush.");
pa_stream_flush(stream, stream_success_cb, NULL);
pa_stream_cork(stream, 1, stream_success_cb, mainloop);
}
pa_threaded_mainloop_unlock(mainloop);
pthread_mutex_lock(&buffer_mutex);
audio_toq = audio_eoq = audio_lmb;
audio_umb = audio_lmb + audio_size;
audio_occupancy = 0;
pa_threaded_mainloop_unlock(mainloop);
pthread_mutex_unlock(&buffer_mutex);
}

static void stop(void) {
Expand All @@ -331,10 +339,12 @@ static void stop(void) {
pa_stream_flush(stream, stream_success_cb, NULL);
pa_stream_cork(stream, 1, stream_success_cb, mainloop);
}
pa_threaded_mainloop_unlock(mainloop);
pthread_mutex_lock(&buffer_mutex);
audio_toq = audio_eoq = audio_lmb;
audio_umb = audio_lmb + audio_size;
audio_occupancy = 0;
pa_threaded_mainloop_unlock(mainloop);
pthread_mutex_unlock(&buffer_mutex);
}

audio_output audio_pa = {.name = "pa",
Expand Down Expand Up @@ -370,6 +380,8 @@ void stream_write_cb(pa_stream *stream, size_t requested_bytes,
int bytes_transferred = 0;
uint8_t *buffer = NULL;
int ret = 0;
pthread_mutex_lock(&buffer_mutex);
pthread_cleanup_push(mutex_unlock, (void *)&buffer_mutex);
while ((bytes_to_transfer > 0) && (audio_occupancy > 0) && (ret == 0)) {
if (pa_stream_is_suspended(stream))
debug(1, "stream is suspended");
Expand All @@ -390,13 +402,7 @@ void stream_write_cb(pa_stream *stream, size_t requested_bytes,
// the bytes are all in a row in the audo buffer
memcpy(buffer, audio_toq, bytes_we_can_transfer);
audio_toq += bytes_we_can_transfer;
// lock
pthread_mutex_lock(&buffer_mutex);
audio_occupancy -= bytes_we_can_transfer;
pthread_mutex_unlock(&buffer_mutex);
// unlock
ret = pa_stream_write(stream, buffer, bytes_we_can_transfer, NULL, 0LL, PA_SEEK_RELATIVE);
bytes_transferred += bytes_we_can_transfer;
} else {
// the bytes are in two places in the audio buffer
size_t first_portion_to_write = audio_umb - audio_toq;
Expand All @@ -405,17 +411,14 @@ void stream_write_cb(pa_stream *stream, size_t requested_bytes,
uint8_t *new_buffer = buffer + first_portion_to_write;
memcpy(new_buffer, audio_lmb, bytes_we_can_transfer - first_portion_to_write);
ret = pa_stream_write(stream, buffer, bytes_we_can_transfer, NULL, 0LL, PA_SEEK_RELATIVE);
bytes_transferred += bytes_we_can_transfer;
audio_toq = audio_lmb + bytes_we_can_transfer - first_portion_to_write;
// lock
pthread_mutex_lock(&buffer_mutex);
audio_occupancy -= bytes_we_can_transfer;
pthread_mutex_unlock(&buffer_mutex);
// unlock
}
bytes_transferred += bytes_we_can_transfer;
audio_occupancy -= bytes_we_can_transfer;
bytes_to_transfer -= bytes_we_can_transfer;
}
}
pthread_cleanup_pop(1); // release the mutex
if (ret != 0)
debug(1, "error writing to pa buffer");
// debug(1,"<<<Frames requested %d, written to pa: %d, corked status:
Expand Down

0 comments on commit 2ed5d99

Please sign in to comment.