Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pipewire pulseaudio: callback only getting called couple of times #877

Open
actondev opened this issue Jul 29, 2024 · 7 comments
Open

pipewire pulseaudio: callback only getting called couple of times #877

actondev opened this issue Jul 29, 2024 · 7 comments

Comments

@actondev
Copy link

I'm noticing a weird issue in my linux setup. If I request a certain periodSizeInFrames, the audio callback gets called 1-3 times, and then no more! Getting this both in master & in dev.

Here's the sample program

#include <stdio.h>
#define MA_DEBUG_OUTPUT
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"

void callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) {
  printf("callback frameCount: %d\n", frameCount);
}

int main() {
  ma_device device;
  ma_device_config config = ma_device_config_init(ma_device_type_playback);
  config.sampleRate = 44100;

  /*
    If I comment out the periodSizeInFrames line, runs fine.
    The debug output says:
    INFO:     Buffer Size: 256*3 (768)
    If I set 768, runs fine.
    If I set 512, runs fine.
   */
  config.periodSizeInFrames = 256;

  config.dataCallback = &callback;
  ma_result result = ma_device_init(NULL, &config, &device);
  if(result != MA_SUCCESS) {
    printf("Failed to initialize device\n");
    return 1;
  }
  result = ma_device_start(&device);
  if(result != MA_SUCCESS) {
    printf("Failed to start device\n");
    return 1;
  }
  while(1) {}
}

And the output: The callback got called 3 times & then nothing, so I just terminated it.

DEBUG: WASAPI backend is disabled.
DEBUG: DirectSound backend is disabled.
DEBUG: WinMM backend is disabled.
DEBUG: Core Audio backend is disabled.
DEBUG: sndio backend is disabled.
DEBUG: audio(4) backend is disabled.
DEBUG: OSS backend is disabled.
DEBUG: Attempting to initialize PulseAudio backend...
DEBUG: Loading library: libpulse.so
DEBUG: Loading symbol: pa_mainloop_new
DEBUG: Loading symbol: pa_mainloop_free
DEBUG: Loading symbol: pa_mainloop_quit
DEBUG: Loading symbol: pa_mainloop_get_api
DEBUG: Loading symbol: pa_mainloop_iterate
DEBUG: Loading symbol: pa_mainloop_wakeup
DEBUG: Loading symbol: pa_threaded_mainloop_new
DEBUG: Loading symbol: pa_threaded_mainloop_free
DEBUG: Loading symbol: pa_threaded_mainloop_start
DEBUG: Loading symbol: pa_threaded_mainloop_stop
DEBUG: Loading symbol: pa_threaded_mainloop_lock
DEBUG: Loading symbol: pa_threaded_mainloop_unlock
DEBUG: Loading symbol: pa_threaded_mainloop_wait
DEBUG: Loading symbol: pa_threaded_mainloop_signal
DEBUG: Loading symbol: pa_threaded_mainloop_accept
DEBUG: Loading symbol: pa_threaded_mainloop_get_retval
DEBUG: Loading symbol: pa_threaded_mainloop_get_api
DEBUG: Loading symbol: pa_threaded_mainloop_in_thread
DEBUG: Loading symbol: pa_threaded_mainloop_set_name
DEBUG: Loading symbol: pa_context_new
DEBUG: Loading symbol: pa_context_unref
DEBUG: Loading symbol: pa_context_connect
DEBUG: Loading symbol: pa_context_disconnect
DEBUG: Loading symbol: pa_context_set_state_callback
DEBUG: Loading symbol: pa_context_get_state
DEBUG: Loading symbol: pa_context_get_sink_info_list
DEBUG: Loading symbol: pa_context_get_source_info_list
DEBUG: Loading symbol: pa_context_get_sink_info_by_name
DEBUG: Loading symbol: pa_context_get_source_info_by_name
DEBUG: Loading symbol: pa_operation_unref
DEBUG: Loading symbol: pa_operation_get_state
DEBUG: Loading symbol: pa_channel_map_init_extend
DEBUG: Loading symbol: pa_channel_map_valid
DEBUG: Loading symbol: pa_channel_map_compatible
DEBUG: Loading symbol: pa_stream_new
DEBUG: Loading symbol: pa_stream_unref
DEBUG: Loading symbol: pa_stream_connect_playback
DEBUG: Loading symbol: pa_stream_connect_record
DEBUG: Loading symbol: pa_stream_disconnect
DEBUG: Loading symbol: pa_stream_get_state
DEBUG: Loading symbol: pa_stream_get_sample_spec
DEBUG: Loading symbol: pa_stream_get_channel_map
DEBUG: Loading symbol: pa_stream_get_buffer_attr
DEBUG: Loading symbol: pa_stream_set_buffer_attr
DEBUG: Loading symbol: pa_stream_get_device_name
DEBUG: Loading symbol: pa_stream_set_write_callback
DEBUG: Loading symbol: pa_stream_set_read_callback
DEBUG: Loading symbol: pa_stream_set_suspended_callback
DEBUG: Loading symbol: pa_stream_set_moved_callback
DEBUG: Loading symbol: pa_stream_is_suspended
DEBUG: Loading symbol: pa_stream_flush
DEBUG: Loading symbol: pa_stream_drain
DEBUG: Loading symbol: pa_stream_is_corked
DEBUG: Loading symbol: pa_stream_cork
DEBUG: Loading symbol: pa_stream_trigger
DEBUG: Loading symbol: pa_stream_begin_write
DEBUG: Loading symbol: pa_stream_write
DEBUG: Loading symbol: pa_stream_peek
DEBUG: Loading symbol: pa_stream_drop
DEBUG: Loading symbol: pa_stream_writable_size
DEBUG: Loading symbol: pa_stream_readable_size
DEBUG: System Architecture:
DEBUG:   Endian: LE
DEBUG:   SSE2:   YES
DEBUG:   AVX2:   NO
DEBUG:   NEON:   NO
INFO: [PulseAudio] Playback attr: maxlength=6144, tlength=2048, prebuf=-1, minreq=-1, fragsize=2048; periodSizeInFrames=256
INFO: [PulseAudio] Playback sample spec: format=32-bit Signed Integer, channels=2, rate=44100
INFO: [PulseAudio] Playback actual attr: maxlength=6144, tlength=1968, prebuf=1032, minreq=944, fragsize=2048; internalPeriodSizeInFrames=256
INFO: [PulseAudio]
INFO:   Tiger Lake-LP Smart Sound Technology Audio Controller Speaker (Playback)
INFO:     Format:      32-bit Signed Integer -> 32-bit Signed Integer
INFO:     Channels:    2 -> 2
INFO:     Sample Rate: 44100 -> 44100
INFO:     Buffer Size: 256*3 (768)
INFO:     Conversion:
INFO:       Pre Format Conversion:  NO
INFO:       Post Format Conversion: NO
INFO:       Channel Routing:        NO
INFO:       Resampling:             NO
INFO:       Passthrough:            YES
INFO:       Channel Map In:         {CHANNEL_FRONT_LEFT CHANNEL_FRONT_RIGHT}
INFO:       Channel Map Out:        {CHANNEL_FRONT_LEFT CHANNEL_FRONT_RIGHT}
callback frameCount: 256
callback frameCount: 256
callback frameCount: 256
^C
@mackron
Copy link
Owner

mackron commented Aug 1, 2024

This is a strange one. I'm at a loss on this. Just for completeness sake, can you post the output when you've commented out the line just so I can see that everything is indeed the same?

@actondev
Copy link
Author

actondev commented Aug 1, 2024

With no requested period size

DEBUG: WASAPI backend is disabled.
DEBUG: DirectSound backend is disabled.
DEBUG: WinMM backend is disabled.
DEBUG: Core Audio backend is disabled.
DEBUG: sndio backend is disabled.
DEBUG: audio(4) backend is disabled.
DEBUG: OSS backend is disabled.
DEBUG: Attempting to initialize PulseAudio backend...
DEBUG: Loading library: libpulse.so
DEBUG: Loading symbol: pa_mainloop_new
DEBUG: Loading symbol: pa_mainloop_free
DEBUG: Loading symbol: pa_mainloop_quit
DEBUG: Loading symbol: pa_mainloop_get_api
DEBUG: Loading symbol: pa_mainloop_iterate
DEBUG: Loading symbol: pa_mainloop_wakeup
DEBUG: Loading symbol: pa_threaded_mainloop_new
DEBUG: Loading symbol: pa_threaded_mainloop_free
DEBUG: Loading symbol: pa_threaded_mainloop_start
DEBUG: Loading symbol: pa_threaded_mainloop_stop
DEBUG: Loading symbol: pa_threaded_mainloop_lock
DEBUG: Loading symbol: pa_threaded_mainloop_unlock
DEBUG: Loading symbol: pa_threaded_mainloop_wait
DEBUG: Loading symbol: pa_threaded_mainloop_signal
DEBUG: Loading symbol: pa_threaded_mainloop_accept
DEBUG: Loading symbol: pa_threaded_mainloop_get_retval
DEBUG: Loading symbol: pa_threaded_mainloop_get_api
DEBUG: Loading symbol: pa_threaded_mainloop_in_thread
DEBUG: Loading symbol: pa_threaded_mainloop_set_name
DEBUG: Loading symbol: pa_context_new
DEBUG: Loading symbol: pa_context_unref
DEBUG: Loading symbol: pa_context_connect
DEBUG: Loading symbol: pa_context_disconnect
DEBUG: Loading symbol: pa_context_set_state_callback
DEBUG: Loading symbol: pa_context_get_state
DEBUG: Loading symbol: pa_context_get_sink_info_list
DEBUG: Loading symbol: pa_context_get_source_info_list
DEBUG: Loading symbol: pa_context_get_sink_info_by_name
DEBUG: Loading symbol: pa_context_get_source_info_by_name
DEBUG: Loading symbol: pa_operation_unref
DEBUG: Loading symbol: pa_operation_get_state
DEBUG: Loading symbol: pa_channel_map_init_extend
DEBUG: Loading symbol: pa_channel_map_valid
DEBUG: Loading symbol: pa_channel_map_compatible
DEBUG: Loading symbol: pa_stream_new
DEBUG: Loading symbol: pa_stream_unref
DEBUG: Loading symbol: pa_stream_connect_playback
DEBUG: Loading symbol: pa_stream_connect_record
DEBUG: Loading symbol: pa_stream_disconnect
DEBUG: Loading symbol: pa_stream_get_state
DEBUG: Loading symbol: pa_stream_get_sample_spec
DEBUG: Loading symbol: pa_stream_get_channel_map
DEBUG: Loading symbol: pa_stream_get_buffer_attr
DEBUG: Loading symbol: pa_stream_set_buffer_attr
DEBUG: Loading symbol: pa_stream_get_device_name
DEBUG: Loading symbol: pa_stream_set_write_callback
DEBUG: Loading symbol: pa_stream_set_read_callback
DEBUG: Loading symbol: pa_stream_set_suspended_callback
DEBUG: Loading symbol: pa_stream_set_moved_callback
DEBUG: Loading symbol: pa_stream_is_suspended
DEBUG: Loading symbol: pa_stream_flush
DEBUG: Loading symbol: pa_stream_drain
DEBUG: Loading symbol: pa_stream_is_corked
DEBUG: Loading symbol: pa_stream_cork
DEBUG: Loading symbol: pa_stream_trigger
DEBUG: Loading symbol: pa_stream_begin_write
DEBUG: Loading symbol: pa_stream_write
DEBUG: Loading symbol: pa_stream_peek
DEBUG: Loading symbol: pa_stream_drop
DEBUG: Loading symbol: pa_stream_writable_size
DEBUG: Loading symbol: pa_stream_readable_size
DEBUG: System Architecture:
DEBUG:   Endian: LE
DEBUG:   SSE2:   YES
DEBUG:   AVX2:   NO
DEBUG:   NEON:   NO
INFO: [PulseAudio] Playback attr: maxlength=26448, tlength=8816, prebuf=-1, minreq=-1, fragsize=8816; periodSizeInFrames=1102
INFO: [PulseAudio] Playback sample spec: format=32-bit Signed Integer, channels=2, rate=44100
INFO: [PulseAudio] Playback actual attr: maxlength=26448, tlength=6608, prebuf=4416, minreq=2200, fragsize=8816; internalPeriodSizeInFrames=826
INFO: [PulseAudio]
INFO:   Tiger Lake-LP Smart Sound Technology Audio Controller Speaker (Playback)
INFO:     Format:      32-bit Signed Integer -> 32-bit Signed Integer
INFO:     Channels:    2 -> 2
INFO:     Sample Rate: 44100 -> 44100
INFO:     Buffer Size: 826*4 (3304)
INFO:     Conversion:
INFO:       Pre Format Conversion:  NO
INFO:       Post Format Conversion: NO
INFO:       Channel Routing:        NO
INFO:       Resampling:             NO
INFO:       Passthrough:            YES
INFO:       Channel Map In:         {CHANNEL_FRONT_LEFT CHANNEL_FRONT_RIGHT}
INFO:       Channel Map Out:        {CHANNEL_FRONT_LEFT CHANNEL_FRONT_RIGHT}
callback frameCount: 826
callback frameCount: 826
callback frameCount: 826
callback frameCount: 826
callback frameCount: 826
callback frameCount: 826
callback frameCount: 826

... and goes on fine

and setting 512 (truncated output)

INFO: [PulseAudio] Playback attr: maxlength=12288, tlength=4096, prebuf=-1, minreq=-1, fragsize=4096; periodSizeInFrames=512
INFO: [PulseAudio] Playback sample spec: format=32-bit Signed Integer, channels=2, rate=44100
INFO: [PulseAudio] Playback actual attr: maxlength=12288, tlength=3072, prebuf=2056, minreq=1024, fragsize=4096; internalPeriodSizeInFrames=384
INFO: [PulseAudio]
INFO:   Tiger Lake-LP Smart Sound Technology Audio Controller Speaker (Playback)
INFO:     Format:      32-bit Signed Integer -> 32-bit Signed Integer
INFO:     Channels:    2 -> 2
INFO:     Sample Rate: 44100 -> 44100
INFO:     Buffer Size: 384*4 (1536)
INFO:     Conversion:
INFO:       Pre Format Conversion:  NO
INFO:       Post Format Conversion: NO
INFO:       Channel Routing:        NO
INFO:       Resampling:             NO
INFO:       Passthrough:            YES
INFO:       Channel Map In:         {CHANNEL_FRONT_LEFT CHANNEL_FRONT_RIGHT}
INFO:       Channel Map Out:        {CHANNEL_FRONT_LEFT CHANNEL_FRONT_RIGHT}
callback frameCount: 512
callback frameCount: 512

and goes on again as expected

@actondev
Copy link
Author

actondev commented Aug 2, 2024

Oh, and to add to the weirdness I just noticed the following:

  • run binary with with config.periodSizeInFrames = 512;
  • run then with `config.periodSizeInFrames = 256;. SOMETIMES it will run normally uninterrupted. 🤷‍♂️

Don't know how also I can help out..

@actondev
Copy link
Author

actondev commented Aug 2, 2024

This is the backtrace of where it's stuck.

#0  0x00007ffff7db2bb0 in __GI_ppoll (fds=0x55555565b2d0, nfds=2, timeout=<optimized out>, sigmask=sigmask@entry=0x0) at ../sysdeps/unix/sysv/linux/ppoll.c:42
#1  0x00007ffff7c6c4e3 in ppoll (__ss=0x0, __timeout=<optimized out>, __nfds=<optimized out>, __fds=<optimized out>) at /usr/include/bits/poll2.h:88
#2  pa_mainloop_poll (m=m@entry=0x555555655f20) at ../pulseaudio/src/pulse/mainloop.c:871
#3  0x00007ffff7c7661c in pa_mainloop_iterate (m=0x555555655f20, block=<optimized out>, retval=0x0) at ../pulseaudio/src/pulse/mainloop.c:945
#4  0x0000555555568ef7 in ma_device_data_loop__pulse (pDevice=0x7fffffffce00) at /home/actondev/dev/actondev/musemacs/libs/miniaudio/miniaudio-dev.h:30952
#5  0x000055555556d498 in ma_worker_thread (pData=0x7fffffffce00) at /home/actondev/dev/actondev/musemacs/libs/miniaudio/miniaudio-dev.h:41065
#6  0x0000555555559acd in ma_thread_entry_proxy (pData=0x555555660e00) at /home/actondev/dev/actondev/musemacs/libs/miniaudio/miniaudio-dev.h:16564
#7  0x00007ffff7d3b39d in start_thread (arg=<optimized out>) at pthread_create.c:447
#8  0x00007ffff7dc049c in __GI___clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

@mackron
Copy link
Owner

mackron commented Aug 4, 2024

I'm suspecting this issue might be related to this: #881. Although the deadlock is happening in different circumstances, both are getting stuck in pa_mainloop_iterate. I will report back when I've got the proposed fix in.

mackron added a commit that referenced this issue Aug 4, 2024
@mackron
Copy link
Owner

mackron commented Aug 5, 2024

Unfortunately the change I was hoping would fix this introduces bad glitching on my computer so I can't be enabling it by default. In any case, if you were interested in trying it yourself, you can add this to the device config: deviceConfig.pulse.blockingMainLoop = MA_FALSE;.

I copied your program exactly and ran it. This is my output:

INFO: [PulseAudio] Playback attr: maxlength=6144, tlength=2048, prebuf=-1, minreq=-1, fragsize=2048; periodSizeInFrames=256
INFO: [PulseAudio] Playback sample spec: format=32-bit Signed Integer, channels=2, rate=44100
INFO: [PulseAudio] Playback actual attr: maxlength=6144, tlength=1968, prebuf=1032, minreq=944, fragsize=2048; internalPeriodSizeInFrames=256
INFO: [PulseAudio]
INFO:   USB Audio Front Headphones (Playback)
INFO:     Format:      32-bit Signed Integer -> 32-bit Signed Integer
INFO:     Channels:    2 -> 2
INFO:     Sample Rate: 44100 -> 44100
INFO:     Buffer Size: 256*3 (768)
INFO:     Conversion:
INFO:       Pre Format Conversion:  NO
INFO:       Post Format Conversion: NO
INFO:       Channel Routing:        NO
INFO:       Resampling:             NO
INFO:       Passthrough:            YES
INFO:       Channel Map In:         {CHANNEL_FRONT_LEFT CHANNEL_FRONT_RIGHT}
INFO:       Channel Map Out:        {CHANNEL_FRONT_LEFT CHANNEL_FRONT_RIGHT}
callback frameCount: 256
callback frameCount: 256
callback frameCount: 256
callback frameCount: 256
callback frameCount: 256
callback frameCount: 256
callback frameCount: 256
callback frameCount: 256
callback frameCount: 256
callback frameCount: 256

The callback printf continues running like normally. From what I can tell, the info looks identical to yours with the exception of the device name. I tried this repeatedly and was never able to replicate the deadlock.

For what it's worth, I'm using PipeWire version 1.2.2:

$ pacman -Qs pipewire
local/gst-plugin-pipewire 1:1.2.2-1
    Multimedia graph framework - pipewire plugin
local/libpipewire 1:1.2.2-1
    Low-latency audio/video router and processor - client library
local/libwireplumber 0.5.5-1
    Session / policy manager implementation for PipeWire - client library
local/pipewire 1:1.2.2-1
    Low-latency audio/video router and processor
local/pipewire-alsa 1:1.2.2-1
    Low-latency audio/video router and processor - ALSA configuration
local/pipewire-audio 1:1.2.2-1
    Low-latency audio/video router and processor - Audio support
local/pipewire-jack 1:1.2.2-1
    Low-latency audio/video router and processor - JACK replacement
local/pipewire-pulse 1:1.2.2-1
    Low-latency audio/video router and processor - PulseAudio replacement
local/qemu-audio-pipewire 9.0.2-1
    QEMU PipeWire audio driver
local/wireplumber 0.5.5-1
    Session / policy manager implementation for PipeWire

My instinct is that this is a PipeWire bug, or a hardware specific bug, but I'm not 100% sure. I don't know what else I can do to work around this one.

@actondev
Copy link
Author

Hm, just tried this and I'm getting exactly the same

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants