2

The problem

I am setting up a small linux computer (C.H.I.P.) to be a bluetooth receiver using pulseaudio. The device is headless so I would like to get a configuration that works on boot. Everything is good except when my phone connects to C.H.I.P. something always sets its sink volume to 0%.

How do I get Pulse/ALSA to leave the Master volume alone when pulseaudio sets up the sink-input? Or maybe pulse is to blame - I'm not sure.

Things I have tried

  • Removing module-*-restore from pulseaudio.
  • Setting flat-volumes to no
  • alsactl store
  • Adding a directive to system.pa and/or default.pa to make pulseaudio set the volume of that sink to 100%

If I'm running alsamixer while my phone connects I see the volume go from 100% to 0% around the following log line:

D: [pulseaudio] protocol-native.c: Client amixer changes volume of sink alsa_output.platform-1c22c00.codec.analog-stereo.

The set up

  • Bluez advertises as a media/sink device
  • Pulseaudio runs as a system-instance (yes, I know why this is bad)
  • It watches bluez for connections
  • When my phone connects PA sets up a loopback sink-input to the ALSA sink
  • ALSA promptly sets the volume to 0%. This happens every time my phone connects via bluetooth

All I have to do is run alsamixer and set the Master volume to 100%.

Much more information

Here's my message to pulseaudio-discuss (zero replies as of this writing).

The nearby debug log lines:

I: [pulseaudio] client.c: Created 26 "Native client (UNIX socket client)"
I: [pulseaudio] protocol-native.c: Client authenticated anonymously.
D: [pulseaudio] protocol-native.c: Protocol version: remote 29, local 29
D: [pulseaudio] protocol-native.c: SHM possible: no
D: [pulseaudio] protocol-native.c: Negotiated SHM: no
D: [pulseaudio] protocol-native.c: Client amixer changes volume of sink alsa_output.platform-1c22c00.codec.analog-stereo.
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Requested to rewind 524288 bytes.
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Limited to 18200 bytes.
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: before: 2275
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: after: 2275
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Rewound 18200 bytes.
D: [alsa-sink-CDC PCM Codec-0] sink.c: Processing rewind...
D: [alsa-sink-CDC PCM Codec-0] sink-input.c: Have to rewind 18200 bytes on render memblockq.
D: [alsa-sink-CDC PCM Codec-0] source.c: Processing rewind...
I: [pulseaudio] module-device-restore.c: Storing volume/mute for device+port sink:alsa_output.platform-1c22c00.codec.analog-stereo:analog-output.
I: [pulseaudio] client.c: Freed 26 "ALSA plug-in [amixer]"
I: [pulseaudio] protocol-native.c: Connection died.

The full connection debug.

D: [pulseaudio] bluez5-util.c: Properties changed in device /org/bluez/hci0/dev_1C_56_FE_9D_1B_0E
D: [pulseaudio] bluez4-util.c: dbus: interface=org.freedesktop.DBus.Properties, path=/org/bluez/hci0/dev_1C_56_FE_9D_1B_0E, member=PropertiesChanged
D: [pulseaudio] bluez5-util.c: Unknown interface org.freedesktop.DBus.Introspectable found, skipping
D: [pulseaudio] bluez5-util.c: Unknown interface org.bluez.MediaTransport1 found, skipping
D: [pulseaudio] bluez5-util.c: Unknown interface org.freedesktop.DBus.Properties found, skipping
D: [pulseaudio] bluez4-util.c: dbus: interface=org.freedesktop.DBus.ObjectManager, path=/, member=InterfacesAdded
D: [pulseaudio] bluez4-util.c: dbus: interface=org.bluez.MediaEndpoint1, path=/MediaEndpoint/A2DPSink, member=SetConfiguration
D: [pulseaudio] bluez5-util.c: dbus: path=/MediaEndpoint/A2DPSink, interface=org.bluez.MediaEndpoint1, member=SetConfiguration
D: [pulseaudio] bluez5-util.c: Transport /org/bluez/hci0/dev_1C_56_FE_9D_1B_0E/fd11 state changed from disconnected to idle
D: [pulseaudio] module-bluez5-discover.c: Loading module-bluez5-device path=/org/bluez/hci0/dev_1C_56_FE_9D_1B_0E
I: [pulseaudio] card.c: Created 4 "bluez_card.1C_56_FE_9D_1B_0E"
D: [pulseaudio] module-bluez5-device.c: Acquiring transport /org/bluez/hci0/dev_1C_56_FE_9D_1B_0E/fd11
I: [pulseaudio] bluez5-util.c: Failed optional acquire of unavailable transport /org/bluez/hci0/dev_1C_56_FE_9D_1B_0E/fd11
I: [pulseaudio] module-bluez5-device.c: SBC parameters: allocation=0, subbands=1, blocks=3, bitpool=2
D: [pulseaudio] module-device-restore.c: Database contains invalid data for key: source:bluez_source.1C_56_FE_9D_1B_0E:null
I: [pulseaudio] source.c: Created source 5 "bluez_source.1C_56_FE_9D_1B_0E" with sample spec s16le 2ch 44100Hz and channel map front-left,front-right
I: [pulseaudio] source.c:     bluetooth.protocol = "a2dp_source"
I: [pulseaudio] source.c:     device.description = "MotoG3"
I: [pulseaudio] source.c:     device.string = "1C:56:FE:9D:1B:0E"
I: [pulseaudio] source.c:     device.api = "bluez"
I: [pulseaudio] source.c:     device.class = "sound"
I: [pulseaudio] source.c:     device.bus = "bluetooth"
I: [pulseaudio] source.c:     device.form_factor = "phone"
I: [pulseaudio] source.c:     bluez.path = "/org/bluez/hci0/dev_1C_56_FE_9D_1B_0E"
I: [pulseaudio] source.c:     bluez.class = "0x5a020c"
I: [pulseaudio] source.c:     bluez.alias = "MotoG3"
I: [pulseaudio] source.c:     device.icon_name = "audio-card-bluetooth"
D: [bluetooth] module-bluez5-device.c: IO Thread starting up
D: [pulseaudio] module-suspend-on-idle.c: Source bluez_source.1C_56_FE_9D_1B_0E becomes idle, timeout in 5 seconds.
D: [pulseaudio] sink-input.c: Negotiated format: pcm, format.sample_format = "\"s16le\""  format.rate = "44100"  format.channels = "2" format.channel_map = "\"front-left,front-right\""
D: [pulseaudio] module-suspend-on-idle.c: Sink alsa_output.platform-1c22c00.codec.analog-stereo becomes busy, resuming.
D: [pulseaudio] sink.c: Suspend cause of sink alsa_output.platform-1c22c00.codec.analog-stereo is 0x0000, resuming
I: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Trying resume...
I: [alsa-sink-CDC PCM Codec-0] alsa-util.c: cannot disable ALSA period wakeups
D: [alsa-sink-CDC PCM Codec-0] alsa-util.c: Maximum hw buffer size is 1489 ms
D: [alsa-sink-CDC PCM Codec-0] alsa-util.c: Set buffer size first (to 65536 samples), period size second (to 8192 samples).
I: [alsa-sink-CDC PCM Codec-0] alsa-util.c: ALSA period wakeups were not disabled
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: hwbuf_unused=0
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: setting avail_min=64656
I: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Time scheduling watermark is 20.00ms
I: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Resumed successfully...
D: [pulseaudio] module-suspend-on-idle.c: Sink alsa_output.platform-1c22c00.codec.analog-stereo becomes idle, timeout in 5 seconds.
I: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Starting playback.
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Cutting sleep time for the initial iterations by half.
D: [pulseaudio] module-suspend-on-idle.c: Sink alsa_output.platform-1c22c00.codec.analog-stereo becomes idle, timeout in 5 seconds.
I: [pulseaudio] resampler.c: Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.
D: [pulseaudio] resampler.c: Resampler:
D: [pulseaudio] resampler.c:   rate 44100 -> 44000 (method speex-fixed-1)
D: [pulseaudio] resampler.c:   format s16le -> s32le (intermediate s16le)
D: [pulseaudio] resampler.c:   channels 2 -> 2 (resampling 2)
I: [pulseaudio] resampler.c: Choosing speex quality setting 1.
D: [pulseaudio] memblockq.c: memblockq requested: maxlength=33554432, tlength=0, base=8, prebuf=0, minreq=1 maxrewind=0
D: [pulseaudio] memblockq.c: memblockq sanitized: maxlength=33554432, tlength=33554432, base=8, prebuf=0, minreq=8 maxrewind=0
I: [pulseaudio] sink-input.c: Created input 3 "(null)" on alsa_output.platform-1c22c00.codec.analog-stereo with sample spec s16le 2ch 44100Hz and channel map front-left,front-right
I: [pulseaudio] sink-input.c:     media.role = "music"
I: [pulseaudio] sink-input.c:     module-stream-restore.id = "sink-input-by-media-role:music"
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Cutting sleep time for the initial iterations by half.
D: [pulseaudio] module-stream-restore.c: Not restoring device for stream source-output-by-media-role:abstract, because already set
D: [pulseaudio] source-output.c: Negotiated format: pcm, format.sample_format = "\"s16le\""  format.rate = "44100"  format.channels = "2"  format.channel_map = "\"front-left,front-right\""
D: [pulseaudio] module-suspend-on-idle.c: Source bluez_source.1C_56_FE_9D_1B_0E becomes busy, resuming.
D: [pulseaudio] module-suspend-on-idle.c: Source bluez_source.1C_56_FE_9D_1B_0E becomes idle, timeout in 5 seconds.
D: [pulseaudio] memblockq.c: memblockq requested: maxlength=33554432, tlength=0, base=4, prebuf=0, minreq=1 maxrewind=0
D: [pulseaudio] memblockq.c: memblockq sanitized: maxlength=33554432, tlength=33554432, base=4, prebuf=0, minreq=4 maxrewind=0
I: [pulseaudio] source-output.c: Created output 3 "(null)" on bluez_source.1C_56_FE_9D_1B_0E with sample spec s16le 2ch 44100Hz and channel map front-left,front-right
I: [pulseaudio] source-output.c:     media.role = "abstract"
I: [pulseaudio] source-output.c:     module-stream-restore.id = "source-output-by-media-role:abstract"
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Cutting sleep time for the initial iterations by half.
D: [pulseaudio] memblockq.c: memblockq requested: maxlength=16777216, tlength=16777216, base=4, prebuf=0, minreq=0 maxrewind=0
D: [pulseaudio] memblockq.c: memblockq sanitized: maxlength=16777216, tlength=16777216, base=4, prebuf=0, minreq=4 maxrewind=0
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Cutting sleep time for the initial iterations by half.
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Latency set to 66.67ms
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: hwbuf_unused=500824
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: setting avail_min=64657
I: [alsa-sink-CDC PCM Codec-0] module-loopback.c: Max request changed
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Requesting rewind due to latency change.
I: [alsa-sink-CDC PCM Codec-0] module-loopback.c: Max request changed
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Requested to rewind 524288 bytes.
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Limited to 518560 bytes.
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: before: 64820
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: after: 64820
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Rewound 518560 bytes.
D: [alsa-sink-CDC PCM Codec-0] sink.c: Processing rewind...
D: [alsa-sink-CDC PCM Codec-0] sink-input.c: Have to rewind 518560 bytes on render memblockq.
D: [alsa-sink-CDC PCM Codec-0] source.c: Processing rewind...
I: [bluetooth] module-loopback.c: Skipping 0 bytes
D: [pulseaudio] module-suspend-on-idle.c: Source bluez_source.1C_56_FE_9D_1B_0E becomes busy, resuming.
D: [pulseaudio] core-subscribe.c: Dropped redundant event due to change event.
I: [pulseaudio] module.c: Loaded "module-loopback" (index: #22; argument: "source="bluez_source.1C_56_FE_9D_1B_0E" source_dont_move="true" sink_input_properties="media.role=music"").
I: [pulseaudio] module.c: Loaded "module-bluez5-device" (index: #21; argument: "path=/org/bluez/hci0/dev_1C_56_FE_9D_1B_0E").
D: [pulseaudio] bluez5-util.c: Transport /org/bluez/hci0/dev_1C_56_FE_9D_1B_0E/fd11 available for profile a2dp_source
D: [pulseaudio] bluez5-util.c: Unknown interface org.freedesktop.DBus.Introspectable found, skipping
D: [pulseaudio] bluez5-util.c: Unknown interface org.bluez.MediaPlayer1 found, skipping
D: [pulseaudio] bluez5-util.c: Unknown interface org.freedesktop.DBus.Properties found, skipping
D: [pulseaudio] bluez4-util.c: dbus: interface=org.freedesktop.DBus.ObjectManager, path=/, member=InterfacesAdded
D: [pulseaudio] bluez5-util.c: Properties changed in adapter /org/bluez/hci0
D: [pulseaudio] bluez4-util.c: dbus: interface=org.freedesktop.DBus.Properties, path=/org/bluez/hci0, member=PropertiesChanged
I: [pulseaudio] client.c: Created 25 "Native client (UNIX socket client)"
I: [pulseaudio] protocol-native.c: Client authenticated anonymously.
I: [pulseaudio] client.c: Freed 25 "Native client (UNIX socket client)"
I: [pulseaudio] protocol-native.c: Connection died.
I: [pulseaudio] client.c: Created 26 "Native client (UNIX socket client)"
I: [pulseaudio] protocol-native.c: Client authenticated anonymously.
D: [pulseaudio] protocol-native.c: Protocol version: remote 29, local 29
D: [pulseaudio] protocol-native.c: SHM possible: no
D: [pulseaudio] protocol-native.c: Negotiated SHM: no
D: [pulseaudio] protocol-native.c: Client amixer changes volume of sink alsa_output.platform-1c22c00.codec.analog-stereo.
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Requested to rewind 524288 bytes.
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Limited to 18200 bytes.
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: before: 2275
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: after: 2275
D: [alsa-sink-CDC PCM Codec-0] alsa-sink.c: Rewound 18200 bytes.
D: [alsa-sink-CDC PCM Codec-0] sink.c: Processing rewind...
D: [alsa-sink-CDC PCM Codec-0] sink-input.c: Have to rewind 18200 bytes on render memblockq.
D: [alsa-sink-CDC PCM Codec-0] source.c: Processing rewind...
I: [pulseaudio] module-device-restore.c: Storing volume/mute for device+port sink:alsa_output.platform-1c22c00.codec.analog-stereo:analog-output.
I: [pulseaudio] client.c: Freed 26 "ALSA plug-in [amixer]"
I: [pulseaudio] protocol-native.c: Connection died.
I: [pulseaudio] client.c: Created 27 "Native client (UNIX socket client)"
I: [pulseaudio] protocol-native.c: Client authenticated anonymously.
D: [pulseaudio] protocol-native.c: Protocol version: remote 29, local 29
D: [pulseaudio] protocol-native.c: SHM possible: no
D: [pulseaudio] protocol-native.c: Negotiated SHM: no
I: [pulseaudio] client.c: Freed 27 "ALSA plug-in [amixer]"
I: [pulseaudio] protocol-native.c: Connection died.
I: [pulseaudio] client.c: Created 28 "Native client (UNIX socket client)"
I: [pulseaudio] protocol-native.c: Client authenticated anonymously.
D: [pulseaudio] protocol-native.c: Protocol version: remote 29, local 29
D: [pulseaudio] protocol-native.c: SHM possible: no
D: [pulseaudio] protocol-native.c: Negotiated SHM: no
I: [pulseaudio] client.c: Freed 28 "pactl"
I: [pulseaudio] protocol-native.c: Connection died.

/etc/pulse/daemon.conf

daemonize = no
allow-module-loading = yes
allow-exit = no
use-pid-file = yes
system-instance = yes
high-priority = yes
realtime-scheduling = no
log-target = journal
resample-method = ffmpeg
enable-remixing = no
enable-lfe-remixing = no
flat-volumes = yes
default-sample-format = s32le
default-sample-rate = 44000
alternate-sample-rate = 192000
default-sample-channels = 2
default-fragments = 10
default-fragment-size-msec = 50

/etc/pulse/client.conf

extra-arguments = --log-target=syslog --system --disallow-exit -v

/etc/pulse/system.pa

.ifexists module-udev-detect.so
load-module module-udev-detect
.else
load-module module-detect
.endif
.ifexists module-esound-protocol-unix.so
load-module module-esound-protocol-unix auth-anonymous=1
.endif
load-module module-native-protocol-unix auth-anonymous=1
load-module module-stream-restore
load-module module-device-restore
load-module module-default-device-restore
load-module module-rescue-streams
load-module module-always-sink
load-module module-suspend-on-idle
load-module module-position-event-sounds
load-module module-bluetooth-discover
load-module module-bluetooth-policy
load-module module-switch-on-connect

/etc/pulse/default.pa

.nofail
.fail
load-module module-device-restore
load-module module-stream-restore
load-module module-card-restore
load-module module-augment-properties
load-module module-switch-on-port-available
.ifexists module-udev-detect.so
load-module module-udev-detect
.else
load-module module-detect
.endif
.ifexists module-jackdbus-detect.so
.nofail
load-module module-jackdbus-detect channels=2
.fail
.endif
.ifexists module-bluetooth-policy.so
load-module module-bluetooth-policy
.endif
.ifexists module-bluetooth-discover.so
load-module module-bluetooth-discover
.endif
.ifexists module-esound-protocol-unix.so
load-module module-esound-protocol-unix
.endif
load-module module-native-protocol-unix
.ifexists module-gconf.so
.nofail
load-module module-gconf
.fail
.endif
load-module module-default-device-restore
load-module module-rescue-streams
load-module module-always-sink
load-module module-intended-roles
load-module module-suspend-on-idle
.ifexists module-console-kit.so
load-module module-console-kit
.endif
.ifexists module-systemd-login.so
load-module module-systemd-login
.endif
load-module module-position-event-sounds
load-module module-role-cork
load-module module-filter-heuristics
load-module module-filter-apply

The sink-input that gets "muted".

0 ol-blue /etc/pulse # pactl list sink-inputs
Sink Input #0
    Driver: module-loopback.c
    Owner Module: 16
    Client: n/a
    Sink: 0
    Sample Specification: s16le 2ch 44100Hz
    Channel Map: front-left,front-right
    Format: pcm, format.sample_format = "\"s16le\""  format.rate = "44100" format.channels = "2"  format.channel_map = "\"front-left,front-right\""
    Corked: yes
    Mute: no
    Volume: front-left: 1 /   0% / -288.99 d,   front-right: 1 /   0% /
-288.99 d
            balance 0.00
    Buffer Latency: 0 usec
    Sink Latency: 0 usec
    Resample method: speex-fixed-1
    Properties:
        media.role = "music"
        module-stream-restore.id = "sink-input-by-media-role:music"
        media.name = "Loopback from MotoG3"
        media.icon_name = "audio-card-bluetooth"

The ALSA sink:

0 ol-blue /etc/pulse # pactl list sinks
Sink #0
    State: SUSPENDED
    Name: alsa_output.platform-1c22c00.codec.analog-stereo
    Description: sun4i-codec Analog Stereo
    Driver: module-alsa-card.c
    Sample Specification: s32le 2ch 44000Hz
    Channel Map: front-left,front-right
    Owner Module: 1
    Mute: no
    Volume: front-left: 1 /   0% / -288.99 d,   front-right: 1 /   0% / -288.99 d
            balance 0.00
    Base Volume: 65536 / 100% / 0.00 dB
    Monitor Source: alsa_output.platform-1c22c00.codec.analog-stereo.monitor
    Latency: 0 usec, configured 0 usec
    Flags: HARDWARE DECIBEL_VOLUME LATENCY
    Properties:
        alsa.resolution_bits = "24"
        device.api = "alsa"
        device.class = "sound"
        alsa.class = "generic"
        alsa.subclass = "generic-mix"
        alsa.name = ""
        alsa.id = "CDC PCM Codec-0"
        alsa.subdevice = "0"
        alsa.subdevice_name = "subdevice #0"
        alsa.device = "0"
        alsa.card = "0"
        alsa.card_name = "sun4i-codec"
        alsa.long_card_name = "sun4i-codec"
        alsa.driver_name = "sun4i_codec"
        device.bus_path = "platform-1c22c00.codec"
        sysfs.path = "/devices/platform/soc at 01c00000 /1c22c00.codec/sound/card0"
        device.string = "hw:0"
        device.buffering.buffer_size = "524288"
        device.buffering.fragment_size = "65536"
        device.access_mode = "mmap+timer"
        device.profile.name = "analog-stereo"
        device.profile.description = "Analog Stereo"
        device.description = "sun4i-codec Analog Stereo"
        module-udev-detect.discovered = "1"
        device.icon_name = "audio-card"
    Ports:
        analog-output: Analog Output (priority: 9900)
    Active Port: analog-output
    Formats:
        pcm
Dean Brundage
  • 141
  • 1
  • 5
  • Why do you think it's a problem with ALSA? Pulseaudio's `module-device-restore` attempts to restore volumes, and calls `amixer`. Now whatever arguments it gives `amixer` don't seem to work out, because `amixer` understands them as a request to set volume to 0. So what happens if you use `amixer` manually to set the volume? Sometimes ALSA "quantifies" volume settings, and rounds them to the nearest values the hardware supports. Does this happen here? Then the problem could be that `module-device-restore` uses e.g. 99% instead of 100%, and ALSA rounds down. – dirkt Jan 26 '17 at 08:05
  • One thing to try is to disable `module-device-restore` in the pulseaudio configuration files, and see if there's still an attempt to change the volume on connection. – dirkt Jan 26 '17 at 08:10
  • @dirkt: I'm not sure what is to blame really. amixer correctly sets volume at any %. Giving amixer 0dB errors, but doesn't change the Master volume. – Dean Brundage Jan 26 '17 at 16:21
  • @dirkt: I removed `module-device-restore` and the behavior does not change. See the "Things I've Tried" section of my question. – Dean Brundage Jan 26 '17 at 16:21

1 Answers1

0

I believe the PulseAudio Bluetooth a2dp profile handling issue I investigated is the same. Namely that the media role volume is handled differently for the same pulseaudio item than the same item with another media role.

Here Bluetooth a2dp_source set the media role to music and it turns out that the sink-input volume was set to zero when the loopback module sink was created. The workaround was to set the sink-input to not zero once and it then stayed at this value.

I set the application volume with the gnome control center, its "Volume Levels" has volume control for each application, ie one that had no label was set to 0%, I set it to 100% and now the sound is always set to 100% when I connect the Bluetooth device. Issue fixed.

Note that I was able to reproduce the no volume issue with native Pulseaudio (without Bluetooth): PULSE_PROP='media.role=music' paplay <wave file> while a random media role was fine: PULSE_PROP='media.role=blob' paplay <wave file>. I was also able to fix it from gnome-control-center sound 'Volume Levels'.

Also it could requires this pactl fixup: How to reduce the volume of a background music stream when a different audio source is playing?

There is a documented CLI for changing per-client volumes... E.g., pactl set-sink-input-volume 1384 100%, where 1384 is the client number. The secret is that they're called "sink-inputs" for playback clients (and source-outputs for recording clients).

ie one can set the sink-input volume to 100% with: pactl set-sink-input-volume 350 100% and back to 0% with: pactl set-sink-input-volume 350 0% where 350 is the sink-input index.

What is weird is that the pactl sink-input-volume and gnome-control-center application volume level fixes re orthogonal. If one is 0% no sound.

Though I am pretty confident I fixed my Bluetooth loopback with gnome-control-center, my sink-input volume was initially 0%. My tests with paplay must have confused the debug process. But after the fact I can confirm that both application level and sink-input volumes requires to be upped.