Browse Source

pulseaudio: Use correct buffer size of stream, wait less between fills.

The wait approach is still wonky, but this fixes the hangs on bluetooth
devices for now.
Ryan C. Gordon 1 year ago
parent
commit
4f76f9b0a7
1 changed files with 12 additions and 2 deletions
  1. 12 2
      src/audio/pulseaudio/SDL_pulseaudio.c

+ 12 - 2
src/audio/pulseaudio/SDL_pulseaudio.c

@@ -98,6 +98,7 @@ static int (*PULSEAUDIO_pa_stream_connect_playback)(pa_stream *, const char *,
                                                     const pa_buffer_attr *, pa_stream_flags_t, const pa_cvolume *, pa_stream *);
 static int (*PULSEAUDIO_pa_stream_connect_record)(pa_stream *, const char *,
                                                   const pa_buffer_attr *, pa_stream_flags_t);
+static const pa_buffer_attr *(*PULSEAUDIO_pa_stream_get_buffer_attr)(pa_stream *);
 static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state)(const pa_stream *);
 static size_t (*PULSEAUDIO_pa_stream_writable_size)(const pa_stream *);
 static size_t (*PULSEAUDIO_pa_stream_readable_size)(const pa_stream *);
@@ -211,6 +212,7 @@ static int load_pulseaudio_syms(void)
     SDL_PULSEAUDIO_SYM(pa_stream_set_state_callback);
     SDL_PULSEAUDIO_SYM(pa_stream_connect_playback);
     SDL_PULSEAUDIO_SYM(pa_stream_connect_record);
+    SDL_PULSEAUDIO_SYM(pa_stream_get_buffer_attr);
     SDL_PULSEAUDIO_SYM(pa_stream_get_state);
     SDL_PULSEAUDIO_SYM(pa_stream_writable_size);
     SDL_PULSEAUDIO_SYM(pa_stream_readable_size);
@@ -400,7 +402,7 @@ static void PULSEAUDIO_WaitDevice(SDL_AudioDevice *device)
 
     PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
 
-    while (!SDL_AtomicGet(&device->shutdown) && (h->bytes_requested < (device->buffer_size / 2))) {
+    while (!SDL_AtomicGet(&device->shutdown) && (h->bytes_requested < (device->buffer_size / 4))) {
         /*printf("PULSEAUDIO WAIT IN WAITDEVICE!\n");*/
         PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
 
@@ -676,7 +678,7 @@ static int PULSEAUDIO_OpenDevice(SDL_AudioDevice *device)
     paspec.rate = device->spec.freq;
 
     /* Reduced prebuffering compared to the defaults. */
-    paattr.fragsize = device->buffer_size;
+    paattr.fragsize = device->buffer_size;   // despite the name, this is only used for capture devices, according to PulseAudio docs!
     paattr.tlength = device->buffer_size;
     paattr.prebuf = -1;
     paattr.maxlength = -1;
@@ -729,6 +731,14 @@ static int PULSEAUDIO_OpenDevice(SDL_AudioDevice *device)
 
                 if (!PA_STREAM_IS_GOOD(state)) {
                     retval = SDL_SetError("Could not connect PulseAudio stream");
+                } else {
+                    const pa_buffer_attr *actual_bufattr = PULSEAUDIO_pa_stream_get_buffer_attr(h->stream);
+                    if (!actual_bufattr) {
+                        retval = SDL_SetError("Could not determine connected PulseAudio stream's buffer attributes");
+                    } else {
+                        device->buffer_size = (int) iscapture ? actual_bufattr->tlength : actual_bufattr->fragsize;
+                        device->sample_frames = device->buffer_size / SDL_AUDIO_FRAMESIZE(device->spec);
+                    }
                 }
             }
         }