Re: Getting Pulseaudio and alsa to share one sound card

2024-05-09 Thread Georg Chini

Hi,

when you are changing default.pa anyway, you can comment out the lines
loading module-udev-detect and module-detect near the top of the file. 
Usually,

module-detect is not loaded anyway. Also, you can load module-alsa-sink and
module-alsa-source at the same place. If you take a look at default.pa, 
there are

some examples.

Regards
  Georg

On 08.05.24 19:02, Richard Reina wrote:


Thanks for the idea George. I tried using dmix with the instructions 
in the link that you provided above but it instructs to create a .pa 
file in the directory: |/etc/pulse/default.pa.d/| but this is a 
directory that does not exist on the RPI. I have tried appending the 
lines:


|unload-module module-udev-detect unload-module module-detect 
load-module module-alsa-sink device=dmix load-module 
module-alsa-source device=dsnoop |


to my |/etc/pulse/default.pa <http://default.pa>| but that causes 
aplay to give a busy error: |aplay: main:830: audio open error: Device 
or resource busy| and Moode to also still give one as well.



El mar, 7 may 2024 a las 14:59, Georg Chini () escribió:

Hi,

mh, looks like you have a problem then. Pulseaudio exclusively
opens the sound devices, so
if the player cannot be configured to use the alsa default device,
it will not work. You could
try using dmix (https://wiki.archlinux.org/title/PulseAudio
chapter 5.1.3, just used Google,
did not check the content)

The only other option left is to start the player with
pasuspender, but then again ledfx won't
work while the player is active.

Regards
   Georg

On 07.05.24 21:50, Richard Reina wrote:

$ aplay -L
null
    Discard all samples (playback) or generate zero samples (capture)
default
    Playback/recording through the PulseAudio sound server
lavrate
    Rate Converter Plugin Using Libav/FFmpeg Library
samplerate
    Rate Converter Plugin Using Samplerate Library
speexrate
    Rate Converter Plugin Using Speex Resampler
jack
    JACK Audio Connection Kit
oss
    Open Sound System
pulse
    PulseAudio Sound Server
upmix
    Plugin for channel upmix (4,6,8)
vdownmix
    Plugin for channel downmix (stereo) with a simple spacialization
_audioout
_audioout__
alsaequal
plug_alsaequal
btstream
camilladsp
crossfeed
plug_bs2b
eqfa12p
plug_eqfa12p
invpolarity
trx_send
hw:CARD=sndrpihifiberry,DEV=0
    snd_rpi_hifiberry_dacplus, HiFiBerry DAC+ HiFi pcm512x-hifi-0
    Direct hardware device without any conversions
plughw:CARD=sndrpihifiberry,DEV=0
    snd_rpi_hifiberry_dacplus, HiFiBerry DAC+ HiFi pcm512x-hifi-0
    Hardware device with all software conversions
sysdefault:CARD=sndrpihifiberry
    snd_rpi_hifiberry_dacplus, HiFiBerry DAC+ HiFi pcm512x-hifi-0
    Default Audio Device
dmix:CARD=sndrpihifiberry,DEV=0
    snd_rpi_hifiberry_dacplus, HiFiBerry DAC+ HiFi pcm512x-hifi-0
    Direct sample mixing device
usbstream:CARD=sndrpihifiberry
    snd_rpi_hifiberry_dacplus
    USB Stream Output

El mar, 7 may 2024 a las 14:44, Georg Chini ()
escribió:

Hi,

so what's the output of aplay -L?

Regards
   Georg

On 07.05.24 21:12, Richard Reina wrote:

Hello Georg, Thank you for the reply. Yes Moode accesses
alsa directly and unfortunately there is no option for
making it use pulse.

El mar, 7 may 2024 a las 13:33, Georg Chini
() escribió:

Hello,

maybe you don't have the alsa config for pulseaudio.
Normally aplay -L
shows that the default device points to pulse:

null
    Discard all samples (playback) or generate zero
samples (capture)
default
    Playback/recording through the PulseAudio sound server

...

pulse
    PulseAudio Sound Server

...

I guess the Moode audio player tries to access the ALSA
device directly
and fails because the device is already in use by
pulseaudio. There might
also be a configuration option in the player to make it
use pulse.

Regards
  Georg

On 07.05.24 18:34, Richard Reina wrote:

Yes it's a requirement. Setting the audio device to
pulse in Ledfx is the only way it will work.

El mar, 7 may 2024 a las 11:21, Mark Gaiser
() escribió:

Have you tried changing your device in ledfx to pulse?
https://ledfx.readthedocs.io/en/latest/directing_audio.html

Again no idea if this works, I don't know nor use
ledfx :) Just trying to help out.

 

Re: Getting Pulseaudio and alsa to share one sound card

2024-05-07 Thread Georg Chini

Hi,

mh, looks like you have a problem then. Pulseaudio exclusively opens the 
sound devices, so
if the player cannot be configured to use the alsa default device, it 
will not work. You could
try using dmix (https://wiki.archlinux.org/title/PulseAudio chapter 
5.1.3, just used Google,

did not check the content)

The only other option left is to start the player with pasuspender, but 
then again ledfx won't

work while the player is active.

Regards
   Georg

On 07.05.24 21:50, Richard Reina wrote:

$ aplay -L
null
    Discard all samples (playback) or generate zero samples (capture)
default
    Playback/recording through the PulseAudio sound server
lavrate
    Rate Converter Plugin Using Libav/FFmpeg Library
samplerate
    Rate Converter Plugin Using Samplerate Library
speexrate
    Rate Converter Plugin Using Speex Resampler
jack
    JACK Audio Connection Kit
oss
    Open Sound System
pulse
    PulseAudio Sound Server
upmix
    Plugin for channel upmix (4,6,8)
vdownmix
    Plugin for channel downmix (stereo) with a simple spacialization
_audioout
_audioout__
alsaequal
plug_alsaequal
btstream
camilladsp
crossfeed
plug_bs2b
eqfa12p
plug_eqfa12p
invpolarity
trx_send
hw:CARD=sndrpihifiberry,DEV=0
    snd_rpi_hifiberry_dacplus, HiFiBerry DAC+ HiFi pcm512x-hifi-0
    Direct hardware device without any conversions
plughw:CARD=sndrpihifiberry,DEV=0
    snd_rpi_hifiberry_dacplus, HiFiBerry DAC+ HiFi pcm512x-hifi-0
    Hardware device with all software conversions
sysdefault:CARD=sndrpihifiberry
    snd_rpi_hifiberry_dacplus, HiFiBerry DAC+ HiFi pcm512x-hifi-0
    Default Audio Device
dmix:CARD=sndrpihifiberry,DEV=0
    snd_rpi_hifiberry_dacplus, HiFiBerry DAC+ HiFi pcm512x-hifi-0
    Direct sample mixing device
usbstream:CARD=sndrpihifiberry
    snd_rpi_hifiberry_dacplus
    USB Stream Output

El mar, 7 may 2024 a las 14:44, Georg Chini () escribió:

Hi,

so what's the output of aplay -L?

Regards
   Georg

On 07.05.24 21:12, Richard Reina wrote:

Hello Georg, Thank you for the reply. Yes Moode accesses alsa
directly and unfortunately there is no option for making it use
pulse.

El mar, 7 may 2024 a las 13:33, Georg Chini ()
escribió:

Hello,

maybe you don't have the alsa config for pulseaudio. Normally
aplay -L
shows that the default device points to pulse:

null
    Discard all samples (playback) or generate zero samples
(capture)
default
    Playback/recording through the PulseAudio sound server

...

pulse
    PulseAudio Sound Server

...

I guess the Moode audio player tries to access the ALSA
device directly
and fails because the device is already in use by pulseaudio.
There might
also be a configuration option in the player to make it use
pulse.

Regards
  Georg

On 07.05.24 18:34, Richard Reina wrote:

Yes it's a requirement. Setting the audio device to pulse in
Ledfx is the only way it will work.

El mar, 7 may 2024 a las 11:21, Mark Gaiser
() escribió:

Have you tried changing your device in ledfx to pulse?
https://ledfx.readthedocs.io/en/latest/directing_audio.html

Again no idea if this works, I don't know nor use ledfx
:) Just trying to help out.

On Tue, May 7, 2024 at 6:14 PM Richard Reina
 wrote:

Hi Mark,

Thank you for the reply.  paplay also works but
there's no change. It's not the playing of the song
that locks up the device and causes Moode audio not
to be able to use it, it's the starting of ledfx.
Once I do systemctl start ledfx the moode audio
player can no longer use the output device
regardless if I play a sound file with aplay, paplay
or don't play a sound file at all. Moode audio can't
use the device until I do systemctl stop ledfx.

El mar, 7 may 2024 a las 10:48, Mark Gaiser
() escribió:

Can you use paplay instead?
That is the pulseaudio aplay drop-in replacement.
I'm guessing you won't have "device or resource
busy" errors when using paplay.

I did not test this! But do let us know if it
works for you :)

On Tue, May 7, 2024 at 3:24 PM Richard Reina
 wrote:

I have a Raspberry Pi 3b with a Hifiberry
Amp4/DAC hat runs Moode Audio OS.

If I pick |Pulse| as they audio device in
LedFx and play a sound file with |ap

Re: Getting Pulseaudio and alsa to share one sound card

2024-05-07 Thread Georg Chini

Hi,

so what's the output of aplay -L?

Regards
   Georg

On 07.05.24 21:12, Richard Reina wrote:
Hello Georg, Thank you for the reply. Yes Moode accesses alsa directly 
and unfortunately there is no option for making it use pulse.


El mar, 7 may 2024 a las 13:33, Georg Chini () escribió:

Hello,

maybe you don't have the alsa config for pulseaudio. Normally aplay -L
shows that the default device points to pulse:

null
    Discard all samples (playback) or generate zero samples (capture)
default
    Playback/recording through the PulseAudio sound server

...

pulse
    PulseAudio Sound Server

...

I guess the Moode audio player tries to access the ALSA device
directly
and fails because the device is already in use by pulseaudio.
There might
also be a configuration option in the player to make it use pulse.

Regards
  Georg

On 07.05.24 18:34, Richard Reina wrote:

Yes it's a requirement. Setting the audio device to pulse in
Ledfx is the only way it will work.

El mar, 7 may 2024 a las 11:21, Mark Gaiser ()
escribió:

Have you tried changing your device in ledfx to pulse?
https://ledfx.readthedocs.io/en/latest/directing_audio.html

Again no idea if this works, I don't know nor use ledfx :)
Just trying to help out.

On Tue, May 7, 2024 at 6:14 PM Richard Reina
 wrote:

Hi Mark,

Thank you for the reply.  paplay also works but there's
no change. It's not the playing of the song that locks up
the device and causes Moode audio not to be able to use
it, it's the starting of ledfx. Once I do systemctl start
ledfx the moode audio player can no longer use the output
device regardless if I play a sound file with aplay,
paplay or don't play a sound file at all. Moode audio
can't use the device until I do systemctl stop ledfx.

El mar, 7 may 2024 a las 10:48, Mark Gaiser
() escribió:

Can you use paplay instead?
That is the pulseaudio aplay drop-in replacement.
I'm guessing you won't have "device or resource busy"
errors when using paplay.

I did not test this! But do let us know if it works
for you :)

On Tue, May 7, 2024 at 3:24 PM Richard Reina
 wrote:

I have a Raspberry Pi 3b with a Hifiberry
Amp4/DAC hat runs Moode Audio OS.

If I pick |Pulse| as they audio device in LedFx
and play a sound file with |aplay sound_file.wav|
my leds react to the music.

The problem is that after |aplay| has finished
playing the sound file if I then go try to use
Moode audio player Moode audio won't play music
and gives me the following error:

|MPD error Failed to open "ALSA Default" (alsa);
Failed to open ALSA device "_audioout": Device or
resource busy|

This persists until I stop Ledfx. Is there a way
I can switch back and forth between aplay and
Moode Audio player without having to stop and
start Ledfx? I am not looking to get LedFx
working with Moode I only want reactive lights
when I play a song with |aplay|.

$ aplay -l

 List of PLAYBACK Hardware Devices 

card 0: sndrpihifiberry
[snd_rpi_hifiberry_dacplus], device 0: HiFiBerry
DAC+ HiFi pcm512x-hifi-0 [HiFiBerry DAC+ HiFi
pcm512x-hifi-0]

Subdevices: 0/1

Subdevice #0: subdevice #0

$ amixer
Simple mixer control 'Master',0
  Capabilities: pvolume pswitch pswitch-joined
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 65536
  Mono:
  Front Left: Playback 65536 [100%] [on]
  Front Right: Playback 65536 [100%] [on]
Simple mixer control 'Capture',0
  Capabilities: cvolume cswitch cswitch-joined
  Capture channels: Front Left - Front Right
  Limits: Capture 0 - 65536
  Front Left: Capture 65536 [100%] [on]
  Front Right: Capture 65536 [100%] [on]


Re: Getting Pulseaudio and alsa to share one sound card

2024-05-07 Thread Georg Chini

Hello,

maybe you don't have the alsa config for pulseaudio. Normally aplay -L
shows that the default device points to pulse:

null
    Discard all samples (playback) or generate zero samples (capture)
default
    Playback/recording through the PulseAudio sound server

...

pulse
    PulseAudio Sound Server

...

I guess the Moode audio player tries to access the ALSA device directly
and fails because the device is already in use by pulseaudio. There might
also be a configuration option in the player to make it use pulse.

Regards
  Georg

On 07.05.24 18:34, Richard Reina wrote:
Yes it's a requirement. Setting the audio device to pulse in Ledfx is 
the only way it will work.


El mar, 7 may 2024 a las 11:21, Mark Gaiser () 
escribió:


Have you tried changing your device in ledfx to pulse?
https://ledfx.readthedocs.io/en/latest/directing_audio.html

Again no idea if this works, I don't know nor use ledfx :) Just
trying to help out.

On Tue, May 7, 2024 at 6:14 PM Richard Reina
 wrote:

Hi Mark,

Thank you for the reply.  paplay also works but there's no
change. It's not the playing of the song that locks up the
device and causes Moode audio not to be able to use it, it's
the starting of ledfx. Once I do systemctl start ledfx the
moode audio player can no longer use the output device
regardless if I play a sound file with aplay, paplay or don't
play a sound file at all. Moode audio can't use the device
until I do systemctl stop ledfx.

El mar, 7 may 2024 a las 10:48, Mark Gaiser
() escribió:

Can you use paplay instead?
That is the pulseaudio aplay drop-in replacement.
I'm guessing you won't have "device or resource busy"
errors when using paplay.

I did not test this! But do let us know if it works for you :)

On Tue, May 7, 2024 at 3:24 PM Richard Reina
 wrote:

I have a Raspberry Pi 3b with a Hifiberry Amp4/DAC hat
runs Moode Audio OS.

If I pick |Pulse| as they audio device in LedFx and
play a sound file with |aplay sound_file.wav| my leds
react to the music.

The problem is that after |aplay| has finished playing
the sound file if I then go try to use Moode audio
player Moode audio won't play music and gives me the
following error:

|MPD error Failed to open "ALSA Default" (alsa);
Failed to open ALSA device "_audioout": Device or
resource busy|

This persists until I stop Ledfx. Is there a way I can
switch back and forth between aplay and Moode Audio
player without having to stop and start Ledfx? I am
not looking to get LedFx working with Moode I only
want reactive lights when I play a song with |aplay|.

$ aplay -l

 List of PLAYBACK Hardware Devices 

card 0: sndrpihifiberry [snd_rpi_hifiberry_dacplus],
device 0: HiFiBerry DAC+ HiFi pcm512x-hifi-0
[HiFiBerry DAC+ HiFi pcm512x-hifi-0]

Subdevices: 0/1

Subdevice #0: subdevice #0

$ amixer
Simple mixer control 'Master',0
  Capabilities: pvolume pswitch pswitch-joined
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 65536
  Mono:
  Front Left: Playback 65536 [100%] [on]
  Front Right: Playback 65536 [100%] [on]
Simple mixer control 'Capture',0
  Capabilities: cvolume cswitch cswitch-joined
  Capture channels: Front Left - Front Right
  Limits: Capture 0 - 65536
  Front Left: Capture 65536 [100%] [on]
  Front Right: Capture 65536 [100%] [on]


Re: Dedicated notification sink?

2024-05-04 Thread Georg Chini

Hi Mark,

there are module-role-cork and module-role-ducking which provide the 
kind of functionality
you are looking for. If you have a stream with "role1" assigned, which 
should duck all other

streams, the command would be something like

pactl load-module module-role-ducking trigger_roles="role1" 
ducking_roles="any_role" global=1


The grouping of roles works for both, module-role-cork and 
module-role-ducking even though

it is only mentioned in the description of module-role-ducking.
(pacmd describe-module module-role-ducking) You can use the special 
roles "any_role" to specify
all streams and "no_role" for those streams that do not have a role 
assigned.


The main problem is to make sure that your (trigger) streams always have 
the correct role,

so you have to set the media.role property somehow.

Regards
   Georg

On 04.05.24 10:27, Mark Gaiser wrote:

Hi,

Let me first try to describe what I'm trying to do. Perhaps there is 
an existing solution for this already that I haven't found yet.


This is mostly for home automation purposes. Imagine you have a DIY 
speaker with a raspberry pi. You use it to play music on. Perhaps even 
with a higher quality DAC. The gist is that you have a linux-based 
speaker that uses pulseaudio for playback.


Now you want to send an audio notification. What you would want to do is:
- Whatever is currently playing, lower it's volume
- Play the notification at a louder volume
- Resume to whatever was playing at whatever volume it was

Are there any ways that one can achieve the above with the current 
pulseaudio version?


The following is a brainstorm! What I'm thinking is if it would be 
possible to make a pulseaudio module that registers its own dedicated 
sink. When audio is being sent to that sink then it would lower the 
volume on the other sinks. When no more audio is sent the other sinks 
get restored to whatever their level was. Audio played on this 
"notification sink" is boosted a little. All these options should be 
configurable. Would such a plugin even be possible in pulseaudio? I 
guess I'm asking if a plugin has the capabilities to modify the output 
of other sinks?


I'm looking forward to what you folks think.
Hopefully it's all already possible :) That sure is a million times 
easier!


Best regards,
Mark



Re: Stuttering when recording sink monitor audio.

2024-01-21 Thread Georg Chini

On 19.01.24 09:39, 赵成义 wrote:

Hi guys,

I found a issue about stuttering when recording sink monitor audio, as 
shown below:


Preconditions:
1. The sound card only supports software volume.
2. Two audio players play different audios at the same time.
3. Set to speaker output audio.

Test steps:
1. Record the audio stream of the monitor of the speaker sink through 
parec.
    For example: parec -d 
alsa_output.platform-raoliang-sndcard.analog-stereo.monitor 
--file-format=wav test1.wav

2. Change the volume of the speaker sink during recording.
3. It will cause stuttering in the audio stream recorded from the 
monitor channel of the speaker sink.

4. However, the audio output from the sound card speaker does not stutter.

Could you tell me why this problem occurs? thanks a lot.

Cheers,
Chengyi


Hi,

which version of PA are you using? That behavior has been a known bug in 
older versions,
but at least version 16 or the recently released 17 should not show that 
issue.


Regards
  Georg



Re: [pulseaudio-discuss] Bluetooth audio connection issue for multi-user login

2023-05-07 Thread Georg Chini

On 06.05.23 08:07, Chengyi Zhao wrote:

Hi guys,

In Debian system, if I log in multiple users, the system will start 
multiple PulseAudio processes at user level,
when establishing Bluetooth audio connection with Bluetooth headset, 
there will be a random use of a particular
PulseAudio to start SCO connection, which cannot guarantee the current 
user can use Bluetooth audio.


How can we deal with this issue? Thanks a lot!

Cheers,
Chengyi


Hi,


how should the system figure out, which user connected the BT device?


Regards

 Georg


Re: [pulseaudio-discuss] RTP makes high tone pitch

2023-03-26 Thread Georg Chini

Hi Lars,

14.2 is pretty old, current version is 16.1 and we are shortly before 
releasing 17.0.
So if possible, I would recommend to update to a newer version, at least 
if your

problems return.

Concerning documentation - you are right, the module page has not been 
updated
for quite some time and unfortunately there is no newer documentation. 
You can
use "pacmd describe-module " to get a list and a short 
description

of supported module arguments. The arguments mentioned on the module page
should still all work, we try not to break existing configurations, but 
meanwhile

there may be quite a few new arguments that have been added over time.

If you set the log level to 4 you should see quite a bit of output, for 
example
module-loopback should tell you every adjust_time seconds the current 
source,
sink and buffer latency. Also module-rtp-recv and module-loopback should 
both
log the current sample rate they are using. If you did not see any of 
that, something
was wrong with the logging. In 14.2, the log_interval parameter to 
module-loopback

should not be necessary.

Regards
   Georg

On 26.03.23 19:43, Lars Stollenwerk wrote:

Hi Georg,

thank you for your detailed answer! Especially the hint regarding the number
of samples in the latency buffer was very enlightening.

Now at the weekend I had time to test your suggestions. I'm using
pulseaudio version 14.2 as part of the current raspberry pi os. The parameter
log_interval to the module-loopback seems not to be supported; the
corresponding call of 'pactl load-module ...' returns with non-zero return
code. Setting log-level to 4 did not produce any relevant log lines.

Nevertheless, I increased the latency step by step to 70 ms for the
module-loopback with max_latency_msec of 100. For module-rtp-recv I set the
latency to 100 ms. Now we are testing the intercom with these parameters.
Right now, it works since several hours without helium-voice. I am
optimistic...

By the way, the documentation of the modules at [1] seems not to contain all
module parameters (e. g. log_interval is not mentioned). Furthermore, it is
not clear to me which version the documentation belongs to. Is there another
resource with the full documentation of a given version?

Many thanks and best regards
Lars

[1] 
https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Modules/


Hi,

you say below, that a few hundred milliseconds would be an acceptable
latency.
Why then do you set the values so low? Setting the loopback latency to
1ms and
max_latency to 10ms is not a good idea and will probably not work as
expected.
The latency you specify for the loopback includes source and sink latency
(= source latency + sink latency + loopback buffer latency), so a
reasonable value
for you would be around 50 ms or larger when you are using an USB device.
The max_latency parameter is only intended to be used when the latency grows
too much and should not be specified unless the latency increases
significantly
over time.

Something similar applies to module-rtp-recv. Specifying a latency of 1ms at
8000 Hz means that you have just 8 audio frames of latency. So here I would
go for something like 100ms.

Both, module-loopback and module-rtp-recv try to adjust to the requested
latency by changing the sample rate. This is probably what you hear. In
particular, while module-loopback stops when the sample rate is more than
1% away from the base rate, there is no such limit for module-rtp-recv.

To debug the situation I would run PA with debug logging and also add
the log-interval=1 parameter to module-loopback. This produces quite a
lot of output, but then you should be able to see what happens and can
adjust your parameters for optimum performance. To enable debug logging
and to send the output to a file you can use

pacmd set-log-level 4
pacmd set-log-target file://tmp/pulse.log

The log settings will revert to the default values when PA is restarted.
Hope this helps.

Regards
    Georg

On 19.03.23 16:14, Lars Stollenwerk wrote:

Hi all,

I am using PulseAudio to implement a kind of intercom: In our ham radio club
house we want to install in every room a raspberry pi with PulseAudio running;
this is what I call a 'client'. Each client is connecet to a microphone and a
speaker using a USB sound card. To send and receive the audio signal over
network, on each client a set of PulseAudio modules is started using 'pactl
load-module ...'. The follwing modules are started:

Sending path

Signal path: mic-source -> loopback -> null-sink -> rtp-send

module-null-sink
  sink_name=rtp-tx-sink
  rate=8000
  channels=1
module-loopback
  source=
  sink=rtp-tx-sink
  latency_msec=1
  max_latency_msec=10
  fast_adjust_threshold_msec=100
  adjust_time=1
  rate=8000
  channels=1
module-rtp-send
  rate=8000
  channels=1
  loop=false
  source=rtp-tx-sink.monitor
  destination=224.0.0.47

Receiving path
--

Re: [pulseaudio-discuss] RTP makes high tone pitch

2023-03-20 Thread Georg Chini

Hi,

you say below, that a few hundred milliseconds would be an acceptable 
latency.
Why then do you set the values so low? Setting the loopback latency to 
1ms and
max_latency to 10ms is not a good idea and will probably not work as 
expected.

The latency you specify for the loopback includes source and sink latency
(= source latency + sink latency + loopback buffer latency), so a 
reasonable value

for you would be around 50 ms or larger when you are using an USB device.
The max_latency parameter is only intended to be used when the latency grows
too much and should not be specified unless the latency increases 
significantly

over time.

Something similar applies to module-rtp-recv. Specifying a latency of 1ms at
8000 Hz means that you have just 8 audio frames of latency. So here I would
go for something like 100ms.

Both, module-loopback and module-rtp-recv try to adjust to the requested
latency by changing the sample rate. This is probably what you hear. In
particular, while module-loopback stops when the sample rate is more than
1% away from the base rate, there is no such limit for module-rtp-recv.

To debug the situation I would run PA with debug logging and also add
the log-interval=1 parameter to module-loopback. This produces quite a
lot of output, but then you should be able to see what happens and can
adjust your parameters for optimum performance. To enable debug logging
and to send the output to a file you can use

pacmd set-log-level 4
pacmd set-log-target file://tmp/pulse.log

The log settings will revert to the default values when PA is restarted.
Hope this helps.

Regards
   Georg

On 19.03.23 16:14, Lars Stollenwerk wrote:

Hi all,

I am using PulseAudio to implement a kind of intercom: In our ham radio club
house we want to install in every room a raspberry pi with PulseAudio running;
this is what I call a 'client'. Each client is connecet to a microphone and a
speaker using a USB sound card. To send and receive the audio signal over
network, on each client a set of PulseAudio modules is started using 'pactl
load-module ...'. The follwing modules are started:

Sending path

Signal path: mic-source -> loopback -> null-sink -> rtp-send

module-null-sink
 sink_name=rtp-tx-sink
 rate=8000
 channels=1
module-loopback
 source=
 sink=rtp-tx-sink
 latency_msec=1
 max_latency_msec=10
 fast_adjust_threshold_msec=100
 adjust_time=1
 rate=8000
 channels=1
module-rtp-send
 rate=8000
 channels=1
 loop=false
 source=rtp-tx-sink.monitor
 destination=224.0.0.47

Receiving path
--
Signal path: rtp-recv -> null-sink -> loopback -> speaker-sink

module-null-sink
 sink_name=rtp-rx-sink
 rate=8000
 channels=1
module-loopback
 source=rtp-rx-sink.monitor
 sink=
 latency_msec=1
 max_latency_msec=10
 fast_adjust_threshold_msec=100
 adjust_time=1
 rate=8000
 channels=1
module-rtp-recv
 latency_msec=1
 sink=rtp-rx-sink
 sap_address=224.0.0.47

The null-sinks are used to mute the stream when necessary.

Generally, the set-up works. However, often the pitch of the voice is much too
high. I. e., the voice can be well understood but sounds more or less like a
Helium voice.

The values for latency are all chosen to be very small. The reason is that we
can accept short drop-outs, but not a big latency (few 100 ms is the maxium
acceptable).  I have tryed to increase max_latency_msec of the loopback
devices to 60 ms - without success.

My question to the community is: Does anyone know where the high pitch voice
comes from? And how to avoid this?

I am thankful for any help!

Best ragards
Lars
--
/   ePistulae: form...@opppf.de
   O-O-@
   / | \PGP Key  : 0x6E5651C4
  FORMICA   Homepage : http://www.Opppf.de/





Re: [pulseaudio-discuss] pulse audio not output for some apps

2023-03-20 Thread Georg Chini

Hi,

unfortunately the information you give is not sufficient to help you.
Can you at least supply the output of "pactl info"?

Regards
   Georg

On 20.03.23 11:54, Igor Lerinc wrote:

i cant use multiple apps in same time !

so, i need to close app completely, in order for other to work !
and that's why other apps don't work

how to fix this

On Mon, Mar 20, 2023 at 11:29 AM Igor Lerinc  
wrote:


I don't know what is problem, but i have latest system upgrade,
manjaro. and sometimes, pulseaudio is just buggy, some apps work
some dont
VLC player once work, once doesn't work.
I don't know why is this happening



Re: [pulseaudio-discuss] Help with receiving multicast

2023-01-07 Thread Georg Chini

Hi,

do you have a loopback from rtpsink.monitor to your default sink? The 
null sink

just discards the audio.
pactl load-module module-loopback source=rtpsink.monitor

Regards
   Georg

On 06.01.23 15:07, Jerry Geis wrote:

Hi - Using ubuntu 20.04 LTS


I have this in my startup:
# Forward 11000 UDP to 9875 for pulse audio
socat UDP4-RECVFROM:11000,fork UDP4-SENDTO:localhost:9875 &

pacmd load-module module-null-sink sink_name=rtpsink format=s16be 
channels=1 rate=44100

pacmd load-module module-rtp-recv sink=rtpsink sap_address=239.168.3.10

Doing netstat -g shows
IPv6/IPv4 Group Memberships
Interface       RefCnt Group
--- -- -
lo              1      224.0.0.251
lo              1 all-systems.mcast.net 
eno1            1      239.168.3.10
eno1            1      224.0.0.251
eno1            1 all-systems.mcast.net 
wlo2            1 all-systems.mcast.net 
lo              1      ff02::fb
lo              1      ip6-allnodes
lo              1      ff01::1
eno1            1      ff02::fb
eno1            1      ff02::1:ff1f:6c0e
eno1            1      ip6-allnodes
eno1            1      ff01::1
wlo2            1      ip6-allnodes
wlo2            1      ff01::1

But I do not hear any audio when I multicast from asterisk. There is 
another SIP speaker that receives the multicast but not my PC.


What am I not doing correct ?
Thanks

Jerry




Re: [pulseaudio-discuss] Output switches to HDMI after locking screen

2022-11-08 Thread Georg Chini

Hi,

do you have module-switch-on-port-available loaded? To me it looks like 
module-switch-on-connect
refuses to switch, but then the switch is done because the port becomes 
available.


Regards
  Georg

On 08.11.22 10:35, Blazej Slusarek wrote:

Hi all,

I've been having issues with my sound output switching to HDMI each 
time I lock my screen. After digging into some logs I found the following:


lis 08 10:12:53 ucnd0463sy2 pulseaudio[973556]: Refusing to switch to 
blacklisted sink alsa_output.pci-_01_00.1.hdmi-stereo
lis 08 10:12:53 ucnd0463sy2 pulseaudio[973556]: 
alsa_card.pci-_01_00.1: active_profile: off -> output:hdmi-stereo


Looks a bit like the blacklist works but then it switches anyway? 
Could that be a problem with module-switch-on-connect? The full log is 
here: https://pastebin.com/KB86Gub4 . The laptop is HP ZBook Fury G7 
Mobile Workstation. Any help or potential workaround would be appreciated!


Best regards,
Blazej





Re: [pulseaudio-discuss] Null sink and its monitor cause high CPU usage in headless environment

2022-11-01 Thread Georg Chini

Hi Tudor,

yes, there is one sink input still active (qemu?) which is also the one 
that requests the
low latency (requested latency: 0.50 ms). As long as there is an active 
stream, the

sink will not be suspended.

I do not see module-loopback in the list of loaded modules. For 
module-loopback, the
default latency is 200 ms, so reducing it to 5 ms will surely increase 
CPU load. The
default latency is a bit on the large side, I would go for something 
between 20ms and

50 ms.

Regards
   Georg

On 31.10.22 22:54, Tudor Zaharia wrote:

Hi Georg,

Thank you so much for the quick response!

That sounds like what I need, but unfortunately I have problems with both 
proposed mitigation measures:

1. Configuring the latency of the null-sink

I couldn't find a setting for it in the documentation 
(https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Modules/#module-null-sink)
 so I tried adding a module-loopback with a latency_msec=5. Unfortunately this 
increased CPU load even further and even without any clients connected.

Sorry if I sound stupid, but I'm quite new to pulseaudio: I'm guessing that the 
client itself is requesting this latency when connecting to it? I looked a bit 
through the client's code but nowhere this value of 500us is set:

     pa_buffer_attr ba;
     ba.tlength = pa_usec_to_bytes (10 * 1000, &ss);
     ba.minreq = pa_usec_to_bytes (5 * 1000, &ss);
     ba.maxlength = -1;
     ba.prebuf = -1;

     int r = pa_stream_connect_playback (stream, dev, ba,
         PA_STREAM_INTERPOLATE_TIMING
         |PA_STREAM_ADJUST_LATENCY
         |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);

     From this I'm guessing a latency of 5000us = 5ms, so exactly what you were 
suggesting. But still pacmd list shows a 500us requested latency value (see 
below). I don't understand why!
 
2. Using module-suspend-on-idle


This sounds like a great idea, but the output sink (emulator_out) is always 
running, so it doesn't get suspended, although there is no sound coming from 
the client. Same, I don't understand why it is still in running state!

     $ pacmd list

     Memory blocks currently allocated: 1, size: 63.9 KiB.
     Memory blocks allocated during the whole lifetime: 7789, size: 794.0 KiB.
     Memory blocks imported from other processes: 0, size: 0 B.
     Memory blocks exported to other processes: 0, size: 0 B.
     Total sample cache size: 0 B.
     Default sample spec: s16le 2ch 48000Hz
     Default channel map: front-left,front-right
     Default sink name: emulator_out
     Default source name: emulator_out.monitor
     Memory blocks of type POOL: 1 allocated/7789 accumulated.
     Memory blocks of type POOL_EXTERNAL: 0 allocated/0 accumulated.
     Memory blocks of type APPENDED: 0 allocated/0 accumulated.
     Memory blocks of type USER: 0 allocated/0 accumulated.
     Memory blocks of type FIXED: 0 allocated/0 accumulated.
     Memory blocks of type IMPORTED: 0 allocated/0 accumulated.
     5 module(s) loaded.
         index: 0
         name: 
         argument: 
         used: 1
         load once: no
         properties:
             module.author = "Lennart Poettering"
             module.description = "Clocked NULL sink"
             module.version = "10.0"
         index: 1
         name: 
         argument: 
         used: 1
         load once: no
         properties:
             module.author = "Lennart Poettering"
             module.description = "Clocked NULL sink"
             module.version = "10.0"
         index: 2
         name: 
         argument: 
         used: -1
         load once: yes
         properties:
             module.author = "Lennart Poettering"
             module.description = "When a sink/source is idle for too long, suspend 
it"
             module.version = "10.0"
         index: 3
         name: 
         argument: 
         used: -1
         load once: no
         properties:
             module.author = "Lennart Poettering"
             module.description = "Native protocol (UNIX sockets)"
             module.version = "10.0"
         index: 4
         name: 
         argument: <>
         used: -1
         load once: no
         properties:
             module.author = "Lennart Poettering"
             module.description = "Command line interface protocol (UNIX 
sockets)"
             module.version = "10.0"
     2 sink(s) available.
     * index: 0
         name: 
         driver: 
         flags: DECIBEL_VOLUME LATENCY FLAT_VOLUME DYNAMIC_LATENCY
         state: RUNNING
         suspend cause:
         priority: 1000
         volume: front-left: 65536 / 100% / 0.00 dB,   front-right: 65536 / 
100% / 0.00 dB
                 balance 0.00
         base volume: 65536 / 100% / 0.00 dB
         volume steps: 65537
         muted: no
         current latency: 0.38 ms
         max request: 0 KiB
         max rewind: 0 KiB
         monitor source: 0
         sample spec: s16le 2ch 48000Hz
         channel map: front-left,front-rig

Re: [pulseaudio-discuss] Null sink and its monitor cause high CPU usage in headless environment

2022-10-31 Thread Georg Chini

Hi,

the first null-sink is configured for 500 usec latency, that causes the 
high CPU load.
If you use something higher, say 5 msec, the load will go down 
significantly. Also,

you don't have module-suspend-on-idle loaded, which means that the sinks are
active all the time, even if they are not used.

Regards
   Georg

On 31.10.22 19:32, Tudor Zaharia wrote:

Hello,



I'm posting here after reading this thread: 
https://www.mail-archive.com/pulseaudio-discuss@lists.freedesktop.org/msg21644.html
 Unfortunately I couldn't find a solution for my case there.

The problem:
I am seeing high CPU usage caused by pulseaudio in a headless environment where 
the only module that I need is the null sink. Moreover, the high CPU symptom is 
noticeable even when there is no audio IO performed by the client, i.e. the 
client app is not reading nor writing anything to/from the null sinks and its 
monitors.

A. The setup:

1. Pulseaudio:

 * client.conf:
 default-server = unix:/pa/pulse-socket
 autospawn=no
 daemon-binary = /bin/true
 enable-shm = false

 * default.pa:
 load-module module-null-sink sink_name=emulator_out 
sink_properties=device.description=emulator_out format=s16le rate=48000 
channels=2 channel_map=front-left,front-right
 load-module module-null-sink sink_name=emulator_in 
sink_properties=device.description=emulator_in format=s16le rate=48000 
channels=2 channel_map=front-left,front-right

 * daemon.conf:
 ; daemonize = no
 ; fail = yes
 ; allow-module-loading = yes
 ; allow-exit = yes
 ; use-pid-file = yes
 ; system-instance = yes
 ; local-server-type = user
 ; enable-shm = yes
 ; enable-memfd = yes
 ; shm-size-bytes = 0 # setting this 0 will use the system-default, 
usually 64 MiB
 ; lock-memory = no
 ; cpu-limit = no

 ; high-priority = yes
 ; nice-level = -11

 ; realtime-scheduling = yes
 ; realtime-priority = 5

 ; exit-idle-time = 20
 ; scache-idle-time = 20

 ; dl-search-path = (depends on architecture)

 ; load-default-script-file = yes
 ; default-script-file = /etc/pulse/default.pa

 ; log-target = auto
 ; log-level = notice
 ; log-meta = no
 ; log-time = no
 ; log-backtrace = 0

 ; remixing-use-all-sink-channels = yes
 ; remixing-produce-lfe = no
 ; remixing-consume-lfe = no
 ; lfe-crossover-freq = 0

 ; flat-volumes = no

 ; rescue-streams = yes

 ; rlimit-fsize = -1
 ; rlimit-data = -1
 ; rlimit-stack = -1
 ; rlimit-core = -1
 ; rlimit-as = -1
 ; rlimit-rss = -1
 ; rlimit-nproc = -1
 ; rlimit-nofile = 256
 ; rlimit-memlock = -1
 ; rlimit-locks = -1
 ; rlimit-sigpending = -1
 ; rlimit-msgqueue = -1
 ; rlimit-nice = 31
 ; rlimit-rtprio = 9
 ; rlimit-rttime = 20

 ; default-sample-format = s16le
 ; default-sample-channels = 2
 ; default-channel-map = front-left,front-right

 ; default-fragments = 4
 ; default-fragment-size-msec = 25

 ; enable-deferred-volume = yes
 deferred-volume-safety-margin-usec = 1
 ; deferred-volume-extra-delay-usec = 0

 ; avoid-resampling = true
 default-sample-rate = 48000
 alternate-sample-rate = 24000
 enable-remixing = no
 resample-method = trivial

 * In order to completely isolate the pulseaudio server, I have made a 
Docker image based on bitnami/minideb:stretch where I installed pulseaudio. 
Then I start the container by mapping a volume on the host to enable socket 
communication between the host and the guest:
 $ docker run --name pa --rm --privileged -v /tmp/pa-docker:/pa mypa


2. Start Android Emulator (this is the pulseaudio client that will connect to 
the above setup server):

 $ QEMU_PA_SERVER=unix:/tmp/pa-docker/pulse-socket QEMU_AUDIO_DRV=pa 
QEMU_PA_SINK=emulator_out QEMU_PA_SOURCE=emulator_in.monitor 
QEMU_AUDIO_DAC_FIXED_FREQ=48000 QEMU_AUDIO_ADC_FIXED_FREQ=48000 
ANDROID_SDK_ROOT=~/Android/Sdk ~/Android/Sdk/emulator/emulator -verbose 
@Pixel_2_API_29

 This runs on the host but connects to the guest through the socket on the 
mapped volume (QEMU_PA_SERVER).

B. The behavior

The setup above works fine, but pulseaudio uses anywhere between 6% and 15% of 
the CPU although the emulator is neither outputting any audio, nor reading the 
virtual microphone. It is basically idle.

 $ docker exec -it pa top

 Tasks:   2 total,   1 running,   1 sleeping,   0 stopped,   0 zombie
 %Cpu(s):  3.2 us,  9.8 sy,  0.0 ni, 87.0 id,  0.0 wa,  0.0 hi,  0.0 si,  
0.0 st
 KiB Mem : 65784824 total, 31055920 free, 16851640 used, 17877264 buff/cache
 KiB Swap:  2097148 total,  2097148 free,  

Re: [pulseaudio-discuss] Pulse audio is designed to destroy your hearing and your equipment

2022-06-03 Thread Georg Chini
Instead of insulting people who spend their free time improving 
pulseaudio, you could have made

a difference by getting involved.

On 03.06.22 00:45, Patrick May wrote:

Here's a warning that if you try this command

pactl -- set-sink-volume 0 10.5%

Pulseaudio will set your volume to 150% and destroy your ears as well 
as your headphones.
This is the latest in the very long list of times pulseaudio has 
blasted loud noise at me due to poor design and programming. Fuck you.





Re: [pulseaudio-discuss] module-remap-source, module-virtual-source, and latencies

2022-04-18 Thread Georg Chini

Hi Chase,

let me know the results of your tests. I would especially be interested 
in the

difference between using module-null-sink with module-remap-source
and module-null-source with the uplink sink of module-remap-source.

Regards
   Georg

On 19.04.22 01:32, Chase Lambert wrote:

Thanks for the replies!

guest271314 - Huh, that's odd that you would see any audio 
differences. My stab in the dark guess would be some sort of 
PulseAudio resampling? Otherwise I would think the PCM data would be 
the same. I'll double check that the audio quality is as expected.


Georg - I can see how that MR could reduce latency, interesting.

I'm kind of just thinking out loud here, but the latency can get very 
low (say to 10ms), right? As long as I have small numbers 
in pa_buffer_attr, I would think that:
- My application would get a callback from PulseAudio, telling it to 
write something

- My application writes something
- Immediately thereafter, Chrome gets a callback to read data
- Chrome reads the data
- There isn't a risk of an underrun here by Chrome, because it will 
only get callbacks when data is ready (hazy guess!)


I ask this because my alternative is modifying Chromium and sending 
data directly to it over a custom IPC channel. But in theory that IPC 
channel should not be faster than PulseAudio. PulseAudio is just 
acting as a queue, and ultimately just a form of IPC between my 
application and Chrome.


In any case, I'll soon find the answer myself. Thanks!

On Sun, Apr 17, 2022 at 9:13 AM guest271314 > wrote:


I am not sure about different latencies re module-remap-source and
module-virtual-source. From my testing the quality of audio output
when using a remapped source with getUserMedia() is inferior
compared to getting the raw PCM using pactl or parec with fetch()
on the browser side then using AudioWorklet or
MediaStreamTrackGenerator in Chrome/Chromium to output the audio.



On Sat, Apr 16, 2022 at 9:49 PM Chase Lambert
mailto:chaselam...@gmail.com>> wrote:

Hi,

I'm trying to make a low latency Virtual microphone. What that
means is I make a null sink, and then a module-virtual-source
or module-remap-source that has a master pointing to the
sink's monitor.

Then I can write to that sink, and get data to show up in this
virtual microphone.

I've found that module-remap-source has a lower latency
than module-virtual-source, (~400ms lower it seems), but I
don't have any idea why. And more generally -- what is the
difference between these two modules? I looked at their source
and also the git history, but that didn't clear much up for me.

Also, is this the best way to make a low latency microphone? I
have an application that I want to send data to Chrome, with
as low latency as possible. Chrome operates directly with
pulseaudio[0].

Thanks,
Chase

[0]

https://source.chromium.org/chromium/chromium/src/+/main:media/audio/pulse/audio_manager_pulse.cc







Re: [pulseaudio-discuss] module-remap-source, module-virtual-source, and latencies

2022-04-17 Thread Georg Chini

Hi,

re-reading, it seems that you don't want to mix your microphone with 
some application
data, but just send the application data to Chrome. Without !661, you 
would use
module-remap-source with the master pointing to the monitor of a null 
sink, with !661
you have the additional option of using module-null-source and let 
module-remap-source

create your sink with the uplink_sink parameter.

Regards
   Georg

On 17.04.22 11:44, Georg Chini wrote:

Hi,

module-virtual-source is only an example of how a filter source should 
be implemented and
is very rarely used. Module-remap-source is intended to be used if you 
want to change the
channel map of your source. Module-remap-source has much less 
overhead, so it is probably

the better option for your use case.
On the other hand, module-virtual-source provides the uplink_sink 
option, which creates a
sink that is mixed into the virtual source, which means you would not 
need the null sink.


If you are able to compile your own pulseaudio, you might want to try
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/661
This MR generalizes the uplink_sink feature so that you can also use 
it with module-remap-sink

which should provide the lowest possible latency.

Regards
   Georg

On 17.04.22 06:48, Chase Lambert wrote:

Hi,

I'm trying to make a low latency Virtual microphone. What that means 
is I make a null sink, and then a module-virtual-source 
or module-remap-source that has a master pointing to the sink's monitor.


Then I can write to that sink, and get data to show up in this 
virtual microphone.


I've found that module-remap-source has a lower latency 
than module-virtual-source, (~400ms lower it seems), but I don't have 
any idea why. And more generally -- what is the difference between 
these two modules? I looked at their source and also the git history, 
but that didn't clear much up for me.


Also, is this the best way to make a low latency microphone? I have 
an application that I want to send data to Chrome, with as low 
latency as possible. Chrome operates directly with pulseaudio[0].


Thanks,
Chase

[0] 
https://source.chromium.org/chromium/chromium/src/+/main:media/audio/pulse/audio_manager_pulse.cc 
<https://source.chromium.org/chromium/chromium/src/+/main:media/audio/pulse/audio_manager_pulse.cc> 








Re: [pulseaudio-discuss] module-remap-source, module-virtual-source, and latencies

2022-04-17 Thread Georg Chini

Hi,

module-virtual-source is only an example of how a filter source should 
be implemented and
is very rarely used. Module-remap-source is intended to be used if you 
want to change the
channel map of your source. Module-remap-source has much less overhead, 
so it is probably

the better option for your use case.
On the other hand, module-virtual-source provides the uplink_sink 
option, which creates a
sink that is mixed into the virtual source, which means you would not 
need the null sink.


If you are able to compile your own pulseaudio, you might want to try
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/661
This MR generalizes the uplink_sink feature so that you can also use it 
with module-remap-sink

which should provide the lowest possible latency.

Regards
   Georg

On 17.04.22 06:48, Chase Lambert wrote:

Hi,

I'm trying to make a low latency Virtual microphone. What that means 
is I make a null sink, and then a module-virtual-source 
or module-remap-source that has a master pointing to the sink's monitor.


Then I can write to that sink, and get data to show up in this virtual 
microphone.


I've found that module-remap-source has a lower latency 
than module-virtual-source, (~400ms lower it seems), but I don't have 
any idea why. And more generally -- what is the difference between 
these two modules? I looked at their source and also the git history, 
but that didn't clear much up for me.


Also, is this the best way to make a low latency microphone? I have an 
application that I want to send data to Chrome, with as low latency as 
possible. Chrome operates directly with pulseaudio[0].


Thanks,
Chase

[0] 
https://source.chromium.org/chromium/chromium/src/+/main:media/audio/pulse/audio_manager_pulse.cc 






Re: [pulseaudio-discuss] Dropped xxx samples. This is most likely because downstream can't keep up and is consuming samples too slowly.

2022-02-13 Thread Georg Chini

On 13.02.22 21:02, corbeille wrote:

I will try to use the loopback module since it performs adaptive
resampling between source and sink.
If I understand what you write, I should use something like this :

$ pacmd load-module module-null-sink sink_name=MySink
$ pacmd load-module module-null-sink sink_name=MySink2
$ pacmd load-module module-loopback source=alsa_input.usb-0d8c_C-
Media_USB_Headphone_Set-00.mono-fallback sink=MySink2

And then start my two gstreamer pipelines :

$ gst-launch-1.0 pulsesrc device=MySink2.monitor ! audioconvert !
audioresample ! pulsesink device=MySink
$ gst-launch-1.0 pulsesrc device=MySink.monitor ! audio/x-
raw,channels=2 ! audioconvert ! audioresample ! opusenc bitrate=256000
! oggmux ! shout2send ip=... port=... mount=... password=...

Is it correct ?


Yes, that's correct.



At this moment, I don't try to mesure latency between audio input and
output.
++

Jack




Le dimanche 13 février 2022 à 20:17 +0100, Georg Chini a écrit :

On 13.02.22 17:09, corbeille wrote:

Hey Georg,

I have updated my to raspios since last time : Debian GNU/Linux 11
(bullseye).
It comes with :
- pulseaudio 14.2
- GStreamer 1.18.4

Is it also too old ?
I was hoping to avoid installing pulseaudio from source.
If so, I will give it a try...
++

Jack

Well, 14.2 is at least not completely out of date. Nevertheless I
would try
current git. What I wonder about is that the problem only occurs with
a
second null sink. Are you sure about that? The two null sinks should
not
interact at all. Maybe with the second null sink the problem occurs
only
later?

I can understand that there is an issue, because the system time and
sound
card time are normally different. So if the source for example (from
a
system
time perspective) delivers samples at 48003 Hz while the samples are
played
with 48000 Hz you will have three samples left per second which pile
up
pretty fast. module-loopback has mechanisms to deal with the rate
difference
between source and sink. Maybe you can try to use a loopback from the
alsa
source to a null-sink and then use the monitor of that null sink in
your
first
gst-launch command instead of using the alsa source directly.

Do you see increasing latency before the sound gets choppy?


Le dimanche 13 février 2022 à 17:05 +0100, Georg Chini a écrit :

On 13.02.22 16:57, corbeille wrote:

Hello,

I did some additional tests.
And it seems the problem occurs when I have a second null sink.
With
only one null sink, I don't have any problem. Weird.

So here is an example of the configuration that causes the
problem
:

1st shell:
$ pacmd load-module module-null-sink sink_name=MySink
$ pacmd load-module module-null-sink sink_name=MySink2

2nd shell:
$ gst-launch-1.0 pulsesrc device="alsa_input.usb-0d8c_C-
Media_USB_Headphone_Set-00.analog-mono" ! audioconvert !
audioresample
! pulsesink device=MySink

3rd shell:
$ gst-launch-1.0 pulsesrc device=MySink.monitor ! audio/x-
raw,channels=2 ! audioconvert ! audioresample ! opusenc !
oggmux !
shout2send ip=... port=... mount=... password=...

After 20 minutes, the sound becomes choppy and stop 4/5 minutes
after.

You can notice that I don't use the second null sink.

Is it a normal behavior ? If so, how can I do to achieve this
configuration on my RPi (by using multi null sink) :

gst_input1 => MySink => gst output1
gst_input2 => MySink2 => gst output2

without any trouble ?
Thanks.
++

Jack



Le vendredi 11 février 2022 à 21:33 +0100, corbeille a écrit :

Hello,

I am using pulseaudio (version 12.2) to "join" two audio
streams
created
with gstreamer (1.14.4) on a raspberry pi (Raspbian GNU/Linux
10
(buster)).

Here the real things :

In a first shell, i start with :
$ pacmd load-module module-null-sink sink_name=MySink

Then I use gstreamer to get the sound from my audio input (in
an
other
shell) :
$ gst-launch-1.0 pulsesrc
device="alsa_input.usb-0d8c_C-Media_USB_Headphone_Set-
00.analog-
mono"
!
audioconvert ! audioresample ! pulsesink device=MySink

and I send this sound on an icecast server (in an other
shell) :
$ gst-launch-1.0 pulsesrc device=MySink.monitor !
"audio/x-raw,channels=2" ! audioconvert ! audioresample !
opusenc
!
oggmux ! shout2send ip=... port=... mount=... password=...

Everything is fine, but after 10 minutes, I get in the 3rd
shell
($
gst-launch-1.0 pulsesrc device=MySink.monitor ! ...) a
sequence
of
messages like :

WARNING: from element
/GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Can't record audio fast enough
Additional debug info:
gstaudiobasesrc.c(849): gst_audio_base_src_create ():
/GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Dropped 10080 samples. This is most likely because downstream
can't
keep
up and is consuming samples too slowly.
WARNING: from element
/GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Can't record audio fast enough
Additional debug info:
gstaudiobasesrc.c(849): gst_audio_base_src_create ():
/GstPipeline:pipeline0/Gst

Re: [pulseaudio-discuss] Dropped xxx samples. This is most likely because downstream can't keep up and is consuming samples too slowly.

2022-02-13 Thread Georg Chini

On 13.02.22 17:09, corbeille wrote:

Hey Georg,

I have updated my to raspios since last time : Debian GNU/Linux 11
(bullseye).
It comes with :
- pulseaudio 14.2
- GStreamer 1.18.4

Is it also too old ?
I was hoping to avoid installing pulseaudio from source.
If so, I will give it a try...
++

Jack


Well, 14.2 is at least not completely out of date. Nevertheless I would try
current git. What I wonder about is that the problem only occurs with a
second null sink. Are you sure about that? The two null sinks should not
interact at all. Maybe with the second null sink the problem occurs only
later?

I can understand that there is an issue, because the system time and sound
card time are normally different. So if the source for example (from a 
system

time perspective) delivers samples at 48003 Hz while the samples are played
with 48000 Hz you will have three samples left per second which pile up
pretty fast. module-loopback has mechanisms to deal with the rate difference
between source and sink. Maybe you can try to use a loopback from the alsa
source to a null-sink and then use the monitor of that null sink in your 
first

gst-launch command instead of using the alsa source directly.

Do you see increasing latency before the sound gets choppy?




Le dimanche 13 février 2022 à 17:05 +0100, Georg Chini a écrit :

On 13.02.22 16:57, corbeille wrote:

Hello,

I did some additional tests.
And it seems the problem occurs when I have a second null sink.
With
only one null sink, I don't have any problem. Weird.

So here is an example of the configuration that causes the problem
:

1st shell:
$ pacmd load-module module-null-sink sink_name=MySink
$ pacmd load-module module-null-sink sink_name=MySink2

2nd shell:
$ gst-launch-1.0 pulsesrc device="alsa_input.usb-0d8c_C-
Media_USB_Headphone_Set-00.analog-mono" ! audioconvert !
audioresample
! pulsesink device=MySink

3rd shell:
$ gst-launch-1.0 pulsesrc device=MySink.monitor ! audio/x-
raw,channels=2 ! audioconvert ! audioresample ! opusenc ! oggmux !
shout2send ip=... port=... mount=... password=...

After 20 minutes, the sound becomes choppy and stop 4/5 minutes
after.

You can notice that I don't use the second null sink.

Is it a normal behavior ? If so, how can I do to achieve this
configuration on my RPi (by using multi null sink) :

gst_input1 => MySink => gst output1
gst_input2 => MySink2 => gst output2

without any trouble ?
Thanks.
++

Jack



Le vendredi 11 février 2022 à 21:33 +0100, corbeille a écrit :

Hello,

I am using pulseaudio (version 12.2) to "join" two audio streams
created
with gstreamer (1.14.4) on a raspberry pi (Raspbian GNU/Linux 10
(buster)).

Here the real things :

In a first shell, i start with :
$ pacmd load-module module-null-sink sink_name=MySink

Then I use gstreamer to get the sound from my audio input (in an
other
shell) :
$ gst-launch-1.0 pulsesrc
device="alsa_input.usb-0d8c_C-Media_USB_Headphone_Set-00.analog-
mono"
!
audioconvert ! audioresample ! pulsesink device=MySink

and I send this sound on an icecast server (in an other shell) :
$ gst-launch-1.0 pulsesrc device=MySink.monitor !
"audio/x-raw,channels=2" ! audioconvert ! audioresample ! opusenc
!
oggmux ! shout2send ip=... port=... mount=... password=...

Everything is fine, but after 10 minutes, I get in the 3rd shell
($
gst-launch-1.0 pulsesrc device=MySink.monitor ! ...) a sequence
of
messages like :

WARNING: from element
/GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Can't record audio fast enough
Additional debug info:
gstaudiobasesrc.c(849): gst_audio_base_src_create ():
/GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Dropped 10080 samples. This is most likely because downstream
can't
keep
up and is consuming samples too slowly.
WARNING: from element
/GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Can't record audio fast enough
Additional debug info:
gstaudiobasesrc.c(849): gst_audio_base_src_create ():
/GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Dropped 34560 samples. This is most likely because downstream
can't
keep
up and is consuming samples too slowly.
WARNING: from element
/GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Can't record audio fast enough
Additional debug info:
gstaudiobasesrc.c(849): gst_audio_base_src_create ():
/GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Dropped 48000 samples. This is most likely because downstream
can't
keep
up and is consuming samples too slowly.
...

The sound become glitchy and stop after 2 or 3 minutes.

According to the message, the stream after "pulsesrc
device=MySink.monitor" is too slow. But I don't understand why.

Do you know where is the problem in this setup and how to solve
it ?
Thanks !
++

Jack


Hello,

have you tried with a more recent version of pulseaudio? 12.2 is
pretty
old. You should use 15.0 or current git.

Regards
 Georg





Re: [pulseaudio-discuss] Dropped xxx samples. This is most likely because downstream can't keep up and is consuming samples too slowly.

2022-02-13 Thread Georg Chini

On 13.02.22 16:57, corbeille wrote:

Hello,

I did some additional tests.
And it seems the problem occurs when I have a second null sink. With
only one null sink, I don't have any problem. Weird.

So here is an example of the configuration that causes the problem :

1st shell:
$ pacmd load-module module-null-sink sink_name=MySink
$ pacmd load-module module-null-sink sink_name=MySink2

2nd shell:
$ gst-launch-1.0 pulsesrc device="alsa_input.usb-0d8c_C-
Media_USB_Headphone_Set-00.analog-mono" ! audioconvert ! audioresample
! pulsesink device=MySink

3rd shell:
$ gst-launch-1.0 pulsesrc device=MySink.monitor ! audio/x-
raw,channels=2 ! audioconvert ! audioresample ! opusenc ! oggmux !
shout2send ip=... port=... mount=... password=...

After 20 minutes, the sound becomes choppy and stop 4/5 minutes after.

You can notice that I don't use the second null sink.

Is it a normal behavior ? If so, how can I do to achieve this
configuration on my RPi (by using multi null sink) :

gst_input1 => MySink => gst output1
gst_input2 => MySink2 => gst output2

without any trouble ?
Thanks.
++

Jack



Le vendredi 11 février 2022 à 21:33 +0100, corbeille a écrit :

Hello,

I am using pulseaudio (version 12.2) to "join" two audio streams
created
with gstreamer (1.14.4) on a raspberry pi (Raspbian GNU/Linux 10
(buster)).

Here the real things :

In a first shell, i start with :
$ pacmd load-module module-null-sink sink_name=MySink

Then I use gstreamer to get the sound from my audio input (in an
other
shell) :
$ gst-launch-1.0 pulsesrc
device="alsa_input.usb-0d8c_C-Media_USB_Headphone_Set-00.analog-mono"
!
audioconvert ! audioresample ! pulsesink device=MySink

and I send this sound on an icecast server (in an other shell) :
$ gst-launch-1.0 pulsesrc device=MySink.monitor !
"audio/x-raw,channels=2" ! audioconvert ! audioresample ! opusenc !
oggmux ! shout2send ip=... port=... mount=... password=...

Everything is fine, but after 10 minutes, I get in the 3rd shell ($
gst-launch-1.0 pulsesrc device=MySink.monitor ! ...) a sequence of
messages like :

WARNING: from element /GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Can't record audio fast enough
Additional debug info:
gstaudiobasesrc.c(849): gst_audio_base_src_create ():
/GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Dropped 10080 samples. This is most likely because downstream can't
keep
up and is consuming samples too slowly.
WARNING: from element /GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Can't record audio fast enough
Additional debug info:
gstaudiobasesrc.c(849): gst_audio_base_src_create ():
/GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Dropped 34560 samples. This is most likely because downstream can't
keep
up and is consuming samples too slowly.
WARNING: from element /GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Can't record audio fast enough
Additional debug info:
gstaudiobasesrc.c(849): gst_audio_base_src_create ():
/GstPipeline:pipeline0/GstPulseSrc:pulsesrc0:
Dropped 48000 samples. This is most likely because downstream can't
keep
up and is consuming samples too slowly.
...

The sound become glitchy and stop after 2 or 3 minutes.

According to the message, the stream after "pulsesrc
device=MySink.monitor" is too slow. But I don't understand why.

Do you know where is the problem in this setup and how to solve it ?
Thanks !
++

Jack


Hello,

have you tried with a more recent version of pulseaudio? 12.2 is pretty
old. You should use 15.0 or current git.

Regards
   Georg



Re: [pulseaudio-discuss] Make paired (but not connected) BT device available as sink?

2022-01-02 Thread Georg Chini

On 02.01.22 15:18, Josef Wolf wrote:

On Sun, Jan 02, 2022 at 02:42:42PM +0100, Josef Wolf wrote:

On Sun, Jan 02, 2022 at 02:02:39PM +0100, Georg Chini wrote:

On 02.01.22 12:32, Josef Wolf wrote:

   pactl load-module module-udev-detect
   pactl load-module module-combine-sink 
slaves=alsa_output.0.hdmi-stereo,bluez_sink.A4_77_58_02_93_FB.a2dp_sink

if you load module-combine-sink without the slaves argument, it should
add newly appearing sinks automatically to the combine sink.

Ah!

Thanks for the hint, Georg! This works (as far as PA is concerned!)

Turns out that I mis-interpreted the cause of the problem. The real problem
seems to lie withhin the BT stack: the BT-speaker will not reconnect
automatically when libreelec is rebooted.

Adding

  systemctl start bluetooth
  (sleep 1; bluetoothctl connect "A4:77:58:02:93:FB") &

to the startup script solved the problem. Thanks!

But there are some noticeable sync-problems (one stream seems to be somewhat
delayed). Is this expected? I thought module-combine-sink would try to
syncronize?



There are some sync issues with the combine sink that should be fixed in 
current master.
Do you have a chance to test it? 
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/tree/master





Re: [pulseaudio-discuss] Make paired (but not connected) BT device available as sink?

2022-01-02 Thread Georg Chini

On 02.01.22 12:32, Josef Wolf wrote:

Hello all,

is there any way to make paired (but currently not connected) BT devices
available as a sink? The autodetect finds only connected devices and the BT
modules don't seem to have any options to specifically create a sink e.g. by
its MAC address.

Background of the question: for Libreelec on RPi4, I want simultanous output
to HDMI-TV and to some BT-Speaker. I can achieve the desired behavior by
connecting the BT-speaker and then executing:

  pactl load-module module-udev-detect
  pactl load-module module-combine-sink 
slaves=alsa_output.0.hdmi-stereo,bluez_sink.A4_77_58_02_93_FB.a2dp_sink

Once those commands were successfully executed, I can switch the BT-speaker
off and on and PA catches up without any noticeable problems.

Unfortunately, those commands will NOT work from boot-scripts, since
module-combine-sink will error out complaining that the BT-sink is not
available.

Any ideas how to work around this?


Hi,

if you load module-combine-sink without the slaves argument, it should
add newly appearing sinks automatically to the combine sink.

Regards
   Georg



Re: [pulseaudio-discuss] High CPU Usage in System Mode

2020-06-27 Thread Georg Chini

On 25.06.20 21:32, jtharkey wrote:

Hello,

We have an embedded device that we're switching from straight ALSA 
over to PulseAudio. There are no users on the system other than root 
so we have pulse running in system mode. It works, but has unusually 
high CPU usage. The device has a 2.6GHz Dual Core CPU. At idle, pulse 
is using about 15-20% of the CPU. Every now and then it spikes up to 
80-90% CPU usage. However, on our dev machines running on the same 
hardware and under XFCE with pulse in user mode, this doesn't happen. 
The idle usage is less than 1% and it can get up to 3-5% max.


This makes me think pulse is setup differently on our dev machines, 
but looking at the configuration files that doesn't seem to be the 
case. Could this have something to do with running in system mode? If 
so, how do I fix it?


Thanks,
JT

Which PA version are you using? What does "idle" mean exactly? All sinks 
and sources suspended?
Can you check with "pactl list sinks" and "pactl list sources" if really 
everything is suspended?
If "idle" only means no sound (but sinks/sources still in RUNNING or 
IDLE state), can you compare

the latency in system and user mode?
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] 回复: How to fix pulseaudio crash when playing music

2020-06-11 Thread Georg Chini

On 09.06.20 16:13, Chengyi Zhao wrote:

Hi Georg,

Thanks for your reply!

Hi all,

I try to apply the following patch to fix this issue, please help 
review, thanks!




Thanks for the patch. Because all patches have to go though Gitlab,

can you please open a merge request on Gitlab?

https://gitlab.freedesktop.org/pulseaudio/pulseaudio/


Two small comment below.



Date:   Tue Jun 9 22:09:36 2020 +0800

    srb: ignore srb when reading/writing srb generated an exception

    When the function do_read() returns -1, the program continues
    reading the same srb, maybe it will occur the crash.

diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c
index 3b94a3adf..4fcec51c6 100644
--- a/src/pulsecore/pstream.c
+++ b/src/pulsecore/pstream.c
@@ -235,7 +235,7 @@ void pa_cmsg_ancil_data_close_fds(struct 
pa_cmsg_ancil_data *ancil) {

 static int do_write(pa_pstream *p);
 static int do_read(pa_pstream *p, struct pstream_read *re);

-static void do_pstream_read_write(pa_pstream *p) {
+static int do_pstream_read_write(pa_pstream *p) {
     pa_assert(p);
     pa_assert(PA_REFCNT_VALUE(p) > 0);

@@ -244,8 +244,15 @@ static void do_pstream_read_write(pa_pstream *p) {
     p->mainloop->defer_enable(p->defer_event, 0);

     if (!p->dead && p->srb) {


r should be defined here.



-         do_write(p);
-         while (!p->dead && do_read(p, &p->readsrb) == 0);
+        if(do_write(p) < 0)
+            goto ignore;
+
+        int r = 0;
+        while (!p->dead && r == 0) {
+            r = do_read(p, &p->readsrb);
+            if (r < 0)
+            goto ignore;
+        }
     }

     if (!p->dead && pa_iochannel_is_readable(p->io)) {
@@ -263,7 +270,12 @@ static void do_pstream_read_write(pa_pstream *p) {
     }

     pa_pstream_unref(p);
-    return;
+    return 0;
+
+ignore:
+
+    pa_pstream_unref(p);
+    return -1;

 fail:

@@ -272,9 +284,11 @@ fail:

     pa_pstream_unlink(p);
     pa_pstream_unref(p);
+    return -1;
 }

 static bool srb_callback(pa_srbchannel *srb, void *userdata) {
+    int r;
     bool b;
     pa_pstream *p = userdata;

@@ -284,11 +298,11 @@ static bool srb_callback(pa_srbchannel *srb, 
void *userdata) {


     pa_pstream_ref(p);

-    do_pstream_read_write(p);
+    r = do_pstream_read_write(p);

     /* If either pstream or the srb is going away, return false.
        We need to check this before p is destroyed. */


Please correct the comment, we now also fail if the read_write failed.



-    b = (PA_REFCNT_VALUE(p) > 1) && (p->srb == srb);
+    b = (r == 0) && (PA_REFCNT_VALUE(p) > 1) && (p->srb == srb);
     pa_pstream_unref(p);

     return b;

Best Regards,
Chengyi

*From:* Georg Chini 
*Sent:* Tuesday, June 9, 2020 2:01
*To:* General PulseAudio Discussion 
; Zhao Chengyi 

*Subject:* Re: [pulseaudio-discuss] 回复: How to fix pulseaudio crash 
when playing music

On 09.06.20 10:39, Zhao Chengyi wrote:

Please ignore the gdb bt information above because of error dbgsyms,
and please refer to the following logs when occurring crash.

5月 26 03:14:24 test-PC pulseaudio[2841]: W: [pulseaudio] pstream.c: 
Received SHM memblock frame with invalid frame length.
5月 26 03:14:24 test-PC pulseaudio[2841]: E: [pulseaudio] pstream.c: 
Assertion 're->data || re->memblock' failed at 
pulsecore/pstream.c:862, function do_read(). Aborting.
5月 26 03:14:24 test-PC systemd[1]: Created slice 
system-systemd\x2dcoredump.slice.
5月 26 03:14:24 test-PC systemd[1]: Started Process Core Dump (PID 
10183/UID 0).
5月 26 03:14:25 test-PC bluetoothd[1700]: Endpoint unregistered: 
sender=:1.60 path=/MediaEndpoint/A2DPSource
5月 26 03:14:25 test-PC bluetoothd[1700]: Endpoint unregistered: 
sender=:1.60 path=/MediaEndpoint/A2DPSink
5月 26 03:14:25 test-PC daemon/audio[2874]: audio_events.go:65: 
pulseaudio context state failed
5月 26 03:14:25 test-PC systemd[2674]: pulseaudio.service: Main 
process exited, code=dumped, status=6/ABRT
5月 26 03:14:25 test-PC systemd[2674]: pulseaudio.service: Failed with 
result 'core-dump'.
5月 26 03:14:25 test-PC systemd-coredump[10184]: Process 2841 
(pulseaudio) of user 1000 dumped core.


Stack trace of thread 2841:
                                                  #0 
 0x8702a714 raise (libc.so.6)
                                                  #1 
 0x870188e8 abort (libc.so.6)
                                                  #2 
 0x873b5728 n/a (libpulsecommon-12.2.so)
                                                  #3 
 0x873b7fd8 n/a (libpulsecommon-12.2.so)
                                                  #4 
 0x873b8368 n/a (libpulsecommon-12.2.so)
                                                  #5 
 0x873b8bec n/a (libpulsecommon-12.2.so)
                                                  #6 
 0x000

Re: [pulseaudio-discuss] Pulseaudio and HomePod / ATV4

2020-06-11 Thread Georg Chini

On 11.06.20 11:50, Jerome O'Flaherty wrote:

Georg,
 I did compile 13.99 on my RPi yesterday and it still happened 
unfortunately. 13.99 also seems to timeout quicker so I switched back for now 
to the ‘official’ pulse for RPI which seems to be 12.

Jerome


On 11 Jun 2020, at 10:40, Georg Chini  wrote:

On 11.06.20 11:12, Jerome O'Flaherty wrote:

I have been trying to get Pulseaudio setup on a headless RPI to provide output 
via a HomePod

So, I have added the module-raop-discover to the default.pa.

I can see my HomePod in the list of sinks.
I can set the home as the default sink

e.g.
set-default-sink raop_output.Home-Pod.local

But say playing a WAV file (as a test hangs??) e.g.

pacat -v < ./DING.wav
Opening a playback stream with sample specification 's16le 2ch 44100Hz' and 
channel map 'front-left,front-right'.
Connection established.
Stream successfully created.
Buffer metrics: maxlength=4194304, tlength=352800, prebuf=349276, minreq=3528
Using sample spec 's16le 2ch 44100Hz', channel map 'front-left,front-right'.
Connected to device raop_output.Home-Pod.local (index: 3, suspended: no).
Got EOF.
Failed to drain stream: Timeout3 usec.
Playback stream drained.
Draining connection to server.

On the same RPI I have forked-daapd working perfectly streaming audio to the 
HomePod (so I believe the connectivity is perfect) !!

What I specifically want to do is use librespot to publish the HomePod locally 
around my network on Spotify and separately
I can see that LibReSpot using using PulseAudio as its output and roughly hangs 
in the same place.

So, basically I am wondering if anyone has successful managed to get the RAOP 
support in Pulseaudio to work - I did look at the
source of forked-daapd and they seem to have their own RAOP codebase so 
possible they have forked the RAOP code for their own use.

Anyway, any help would be great.

Thanks

Which pulseaudio version are you using? Did you try current git or PA 13.99? 
There
have been quite a few changes in the RAOP code since 13.0. If that does not 
work,
please open an issue at 
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues

Regards
 Georg


OK, so as said you should open an issue on Gitlab. I included Christophe 
in the mail because

he did most of the development on the RAOP code, maybe he can help you.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Pulseaudio and HomePod / ATV4

2020-06-11 Thread Georg Chini

On 11.06.20 11:12, Jerome O'Flaherty wrote:

I have been trying to get Pulseaudio setup on a headless RPI to provide output 
via a HomePod

So, I have added the module-raop-discover to the default.pa.

I can see my HomePod in the list of sinks.
I can set the home as the default sink

e.g.
set-default-sink raop_output.Home-Pod.local

But say playing a WAV file (as a test hangs??) e.g.

pacat -v < ./DING.wav
Opening a playback stream with sample specification 's16le 2ch 44100Hz' and 
channel map 'front-left,front-right'.
Connection established.
Stream successfully created.
Buffer metrics: maxlength=4194304, tlength=352800, prebuf=349276, minreq=3528
Using sample spec 's16le 2ch 44100Hz', channel map 'front-left,front-right'.
Connected to device raop_output.Home-Pod.local (index: 3, suspended: no).
Got EOF.
Failed to drain stream: Timeout3 usec.
Playback stream drained.
Draining connection to server.

On the same RPI I have forked-daapd working perfectly streaming audio to the 
HomePod (so I believe the connectivity is perfect) !!

What I specifically want to do is use librespot to publish the HomePod locally 
around my network on Spotify and separately
I can see that LibReSpot using using PulseAudio as its output and roughly hangs 
in the same place.

So, basically I am wondering if anyone has successful managed to get the RAOP 
support in Pulseaudio to work - I did look at the
source of forked-daapd and they seem to have their own RAOP codebase so 
possible they have forked the RAOP code for their own use.

Anyway, any help would be great.

Thanks
Which pulseaudio version are you using? Did you try current git or PA 
13.99? There
have been quite a few changes in the RAOP code since 13.0. If that does 
not work,
please open an issue at 
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues


Regards
    Georg
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Bluetooth headset profile

2020-06-09 Thread Georg Chini

On 09.06.20 13:59, Chris Adams wrote:

I am running Fedora 31, with pulseaudio 13.99.1-3.fc31 and bluez
5.54-1.fc31.  I am unable to get any Bluetooth headset to work in
headset_head_unit (HSP/HFP) mode.  I tried a new headset I just bought
for video chats an old pair of headphones (that I'm pretty sure I used
in headset mode years ago), and a pair of earbuds.

The headset and old earphones both have both Headset and Handsfree
Bluetooth available, so from what I read should work.  The earbuds only
have Handsfree, so I guess that's not even expected to work with Linux.

When I run "pacmd set-card-profile  headset_head_unit", it
appears to work, but nothing is heard from the mic and any attempts to
output sound just hang (and no output).

Is there any way to get this working?


Hi,

there is currently a lot going on to achieve better BT support in PA.
Please refer to

https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/288

Testers welcome!

Regards
 Georg

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] 回复: How to fix pulseaudio crash when playing music

2020-06-09 Thread Georg Chini

On 09.06.20 10:39, Zhao Chengyi wrote:

Please ignore the gdb bt information above because of error dbgsyms,
and please refer to the following logs when occurring crash.

5月 26 03:14:24 test-PC pulseaudio[2841]: W: [pulseaudio] pstream.c: 
Received SHM memblock frame with invalid frame length.
5月 26 03:14:24 test-PC pulseaudio[2841]: E: [pulseaudio] pstream.c: 
Assertion 're->data || re->memblock' failed at 
pulsecore/pstream.c:862, function do_read(). Aborting.
5月 26 03:14:24 test-PC systemd[1]: Created slice 
system-systemd\x2dcoredump.slice.
5月 26 03:14:24 test-PC systemd[1]: Started Process Core Dump (PID 
10183/UID 0).
5月 26 03:14:25 test-PC bluetoothd[1700]: Endpoint unregistered: 
sender=:1.60 path=/MediaEndpoint/A2DPSource
5月 26 03:14:25 test-PC bluetoothd[1700]: Endpoint unregistered: 
sender=:1.60 path=/MediaEndpoint/A2DPSink
5月 26 03:14:25 test-PC daemon/audio[2874]: audio_events.go:65: 
pulseaudio context state failed
5月 26 03:14:25 test-PC systemd[2674]: pulseaudio.service: Main process 
exited, code=dumped, status=6/ABRT
5月 26 03:14:25 test-PC systemd[2674]: pulseaudio.service: Failed with 
result 'core-dump'.
5月 26 03:14:25 test-PC systemd-coredump[10184]: Process 2841 
(pulseaudio) of user 1000 dumped core.


                                                  Stack trace of 
thread 2841:
                                                  #0 
 0x8702a714 raise (libc.so.6)
                                                  #1 
 0x870188e8 abort (libc.so.6)
                                                  #2 
 0x873b5728 n/a (libpulsecommon-12.2.so)
                                                  #3 
 0x873b7fd8 n/a (libpulsecommon-12.2.so)
                                                  #4 
 0x873b8368 n/a (libpulsecommon-12.2.so)
                                                  #5 
 0x873b8bec n/a (libpulsecommon-12.2.so)
                                                  #6 
 0x87339c70 pa_mainloop_dispatch (libpulse.so.0)
                                                  #7 
 0x8733a01c pa_mainloop_iterate (libpulse.so.0)
                                                  #8 
 0x8733a0d8 pa_mainloop_run (libpulse.so.0)
                                                  #9 
 0x00406894 main (pulseaudio)
                                                  #10 
0x87018d24 __libc_start_main (libc.so.6)
                                                  #11 
0x004076c4 _start (pulseaudio)
                                                  #12 
0x004076c4 _start (pulseaudio)
5月 26 03:14:25 test-PC systemd[2674]: pulseaudio.service: Service 
RestartSec=100ms expired, scheduling restart.
5月 26 03:14:25 test-PC systemd[2674]: pulseaudio.service: Scheduled 
restart job, restart counter is at 1.

5月 26 03:14:25 test-PC systemd[2674]: Stopped Sound Service.
5月 26 03:14:25 test-PC systemd[2674]: Starting Sound Service...
5月 26 03:14:25 test-PC pulseaudio[10197]: W: [pulseaudio] pid.c: Stale 
PID file, overwriting.


Best Regards,
Chengyi

*发件人:* Zhao Chengyi
*发送时间:* 2020年6月9日 0:30
*收件人:* pulseaudio-discuss@lists.freedesktop.org 


*主题:* How to fix pulseaudio crash when playing music
Hi,

I found pulseaudio crash when playing music, please help fix this 
issue, thanks a lot!


please refer to the following gdb information when occurring crash:

[Current thread is 1 (Thread 0x86823010 (LWP 2841))]
(gdb) bt
#0  0x8702a714 in __GI_raise (sig=sig@entry=6) at 
../sysdeps/unix/sysv/linux/raise.c:50

#1  0x870188e8 in __GI_abort () at abort.c:79
#2  0x873b5728 in do_read (p=p@entry=0x3673a170, 
re=re@entry=0x3673a338) at pulsecore/pstream.c:856
#3  0x873b7fd8 in do_pstream_read_write (p=0x3673a170) at 
pulsecore/pstream.c:248
#4  0x873b8368 in srb_callback (srb=, 
userdata=0x3673a170) at pulsecore/pstream.c:287
#5  0x873b8bec in srbchannel_rwloop (sr=0x36766ae0) at 
pulsecore/srbchannel.c:190
#6  0x87339c70 in dispatch_pollfds (m=0x36670db0) at 
pulse/mainloop.c:655
#7  0x87339c70 in pa_mainloop_dispatch (m=m@entry=0x36670db0) 
at pulse/mainloop.c:898
#8  0x8733a01c in pa_mainloop_iterate (m=0x36670db0, 
block=, retval=0xd9683030) at pulse/mainloop.c:929
#9  0x8733a0d8 in pa_mainloop_run (m=m@entry=0x36670db0, 
retval=retval@entry=0xd9683030) at pulse/mainloop.c:945
#10 0x00406894 in main (argc=, argv=out>) at daemon/main.c:1144


Best Regards,
Chengyi


Hi,


there is a bug report on Gitlab which describes exactly the same problem:

https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/859


Unfortunately we did not yet have the time to investigate further.


Regards

 Georg

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.o

Re: [pulseaudio-discuss] Block sizes

2020-05-28 Thread Georg Chini

On 27.05.20 14:11, Robert Bielik wrote:


Hi all,

Running my ladspa plugin I can see all sorts of block(fragment) sizes 
in the run function (it starts f.i. with 8059 frames…(?)). Is there 
any way to force these to say 512 frames per fragment?


Regards

/R

No, PA uses variable block size. Again, I have patches that implement a 
module-plugin-sink
which allows to write PA specific filter plugins that can use a fixed 
block size and have a callback

to allow the filter to rewind or can disable rewinding.
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] LADSPA plugin strange behavior

2020-05-28 Thread Georg Chini

On 27.05.20 12:12, Robert Bielik wrote:


Oh, forgot to mention, I’m running pulseaudio 12.2 on a Raspberry Pi 
Model 3.


*From:*pulseaudio-discuss 
 *On Behalf Of 
*Robert Bielik

*Sent:* Wednesday, 27 May 2020 12:10
*To:* pulseaudio-discuss@lists.freedesktop.org
*Subject:* [pulseaudio-discuss] LADSPA plugin strange behavior

Hi all,

New to the list. I’m setting up a system where I have a 
post-processing LADSPA plugin. I’ve setup /etc/pulse/default.pa to 
load my LADSPA plugin and to set it as the default sink.


Running pulseaudio with “pulseaudio 2>&1” I can see all the logs from 
my plugin, with it being properly initialized upon start of pulseaudio 
server, and deinitialized when shutting down the server.


But, there is a strange behavior. Running one audio stream with aplay 
f.i., and then starting another one with paplay f.i., I can see that 
the pulseaudio server deactivates, and re-activates the plugin. This 
it does for any stream started AND stopped.


Isn’t the stream to the plugin supposed to be continuous? Can the 
pulseaudio server be configured not to do this ?


Regards

/Robert

This behavior is caused by rewinding. Basically, rewinding is used to 
ensure that

a new stream is heard immediately. Consider a stream running with a large
latency of let's say 500 ms. This means, that PA has already processed 
500 ms
more audio than has been played. When a new stream is added, it would 
normally
take half a second before the new stream is audible. To avoid this, PA 
will roll back
the latency of the old stream as far as possible and then add the new 
stream.


For a filter this means, that it has to process audio that already 
passed through
the filter. This can lead to distortions. In an ideal case, the filter 
would be able
to rewind to the state which matches the point in time where the stream 
is picked
up again. This is however not possible, so PA resets the filter in the 
hope that this

has less impact than simply running the same audio through the filter again.

For me, the concept of rewinding was difficult to understand, so I hope 
the explanation
is understandable. The correct solution here is to avoid rewinding 
completely for
the LADSPA sink and limit the latency to some small value. I have 
patches that do
exactly that, but they depend on lots of other patches that are still 
not reviewed.


For the moment I guess you have to live with that behavior (or you could 
patch the

LADSPA sink not to reset the filter and see if this gives better results).
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Volume mismatch between pulseaudio and alsa

2020-05-09 Thread Georg Chini

On 09.05.20 06:08, l...@sunray.cn wrote:

Hi

I so sorry that I sent a lot of mails these days. Now I summarize all 
the problems in this mail.


Device: IMX6DL
Kernel: 4.1.15
Environment: pulseaudio 8.0, alsa( alsactl -v : 1.1.0)

Reason:
I used "mplayer" to play audio file in "system()" before (didn't open 
pulseaudio).

I want to optimized that so I use Qt function(based on pulseaudio).
After I changed configuration to let the pulseaudio start when the 
system startup and I play audio with Qt, I found the volume was 
mismatch when I changed it in Qt function
    (*QSoundEffect::setVolume(), range:0.0 ~ 1.0, if volume is bigger 
than 0.1, the voice would be biggest)
    So I used "mplayer -af volume=[-20, -10, 0, 10] XXX.wav" to test 
again, then I found if the volume is bigger than -10, the voice would 
be biggest.


    I can attach the output of "paplay -v test.wav",but "aplay 
-Dplughw:0,0 test.wav"  just has a short "bit" voice either pulseaudio 
is opened or not.


I hope you can give me a hand again
PS: I also send a mail to alsa-user, you can follow it : 
https://sourceforge.net/p/alsa/mailman/message/37005410/



Best Regards
Mihan


You should upgrade your software stack. Pulseaudio 8 is already 4 years 
old and the kernel is even older.


Regards
  Georg

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Question about Pulseaudio hardware abstraction

2020-04-29 Thread Georg Chini

On 29.04.20 10:57, Jim Kent wrote:


I have a question about how Pulseaudio functions between sound 
hardware and applications in Linux and spins. I noticed both Firefox 
and Chromium internally report many hardware details, including the 
sound output chipset and connected Bluetooth devices (with unique 
identifiers).


I am not sure this information is taken from pulseaudio. If you do 
"pactl list sinks", you can

see what is exposed to clients.

I assumed that Pulseaudio behaved as an opaque interface between 
software and hardware, in other words, applications send and receive 
inputs and outputs to Pulseaudio, which in turn mixes and exclusively 
communicates with sound hardware. Instead, I have noticed many 
instances where browsers exhibit unintended control over sound 
outputs, for instance, playing a youtube video will sometimes abruptly 
disconnect a Bluetooth headset.


This sounds weird and I never heard about such a behavior. If the 
browser is doing such things it is certainly
not through PA. A disconnect may happen if there are issues with the 
bluetooth connectivity, but in that case

the problem should not be application related and is below the PA level.


Is this behavior by design? Is it possible to sandbox applications 
from the sound hardware so that they only communicate and have a view 
of Pulseaudio, rather than the underlying hardware? Could something 
like Jack accomplish this?




___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Bluetooth HSP and HFP support in pulseaudio

2020-04-28 Thread Georg Chini

On 29.04.20 00:03, Pali Rohár wrote:

On Tuesday 28 April 2020 21:52:55 Georg Chini wrote:

On 28.04.20 21:06, Pali Rohár wrote:

On Tuesday 28 April 2020 20:50:33 Georg Chini wrote:

Personally I don't see a problem to remove the AG role support from
the ofono backend because nobody uses it. What I proposed earlier
- allow hsphfpd to disable the HFP HS role and keep a "legacy" ofono
backend for the HFP HS role - should not be that hard to implement
compared to all the time and work you already invested and it would
help us to keep users happy.

As I said, I have no problems with allowing to disable particular
profile from hsphpfd. But the way how ofono has it implemented, when it
is not possible to unregister specific profile and it always register
master SCO listening socket, it means that you cannot have two
applications which would implement or register HSP or HFP profile for
audio, independently of the role.

So you cannot use ofono's HFP AG role for connecting mobile phone and
other application (e.g. hsphpfd) for using HFP HS role for connecting
headset.

Sorry, forgive my ignorance. You can switch off ofonos AG role,
in that case it will only register the HS role with bluetoothd and
only react to connection attempts with the specific UUID.
Is it not possible that ofono registers one role and hsphfpd the
other?

Via --noplugin you specify which ofono plugins would not be loaded. So
you can instruct ofono to not register HF or AG role of HFP to
bluetoothd, which cause that bluetoothd does not create new RFCOMM
connection for particular profile UUID. So registering / unregistering
of UUIF can be done by restarting ofono with different parameters.

But for HSP and HFP this is not enough! SCO listening master socket is
created by ofono if at least one of HF or AG role plugin is loaded. And
you cannot control this behavior as ofono does not have API for it.


And even if it is not possible and you can't use both at the same
time (which would be a pity)

No it is not possible. It is even not possible to have one application
with HSP HS and one with HFP AG (see difference HSP and HFP, even
different profile is not possible).


That is definitely possible. This is how I have had working basic
headset support + mobile support for the last couple of years.
After switching off the AG role in ofono, a mobile will connect
to HFP provided by ofono while a headset connects to HSP
provided by the native backend. And actually I don't want to loose
this functionality (though at the moment the new board I have
has a broken USB3 implementation so that I cannot use BT at all).



As I wrote is exactly same as if two applications want to listen on TCP
port 1234 and both applications wants to accept only socket with
specific parameters which can be deduced only after accepting socket.

SCO sockets are not managed by bluetoothd daemon, but by target agent
application which implements that particular profile.


we still have to respect if a user
thinks that for him a working implementation for his mobile is
more important than good headset support and therefore prefers
the ofono backend over any other backend.

So what you want is currently impossible. You have to first fix ofono
daemon, design and export API for it and then implement other side to
use that API.

And I'm explaining again that this is reason why to have one central
daemon which would implement HSP and HFP profiles and proxies needed
support / sockets to target applications.

If one application is stealing listening sockets and cannot be
configured to not do it, other applications are just out of luck.

It is same as if two UDP or TCP applications wants to listen on port
1234 and both want to accept new connections. Without full cooperative
environment it does not work. hsphfpd daemon is there to accept new
connections from both RFCOMM and SCO sockets and do all needed stuff
with it (pass to other application, or process data on it directly).


The point is, that the applications that support the new hsphfpd
not yet exist, so we have at least to support the status quo until
there is some alternative.

Are there other modem softwares? I can write e.g. simple application for
hsphfpd which exports socket as tty device (via pts kernel interface).
If there are working modem software which can use tty modem then could
access also modem exported in this way.


Well, ofono provides support for all kinds of modems, so it should
be possible still to use ofono. Actually the main target of ofono are
hardware modems and the HFP stuff is more like an add-on.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Bluetooth HSP and HFP support in pulseaudio

2020-04-28 Thread Georg Chini

On 28.04.20 21:06, Pali Rohár wrote:

On Tuesday 28 April 2020 20:50:33 Georg Chini wrote:

Personally I don't see a problem to remove the AG role support from
the ofono backend because nobody uses it. What I proposed earlier
- allow hsphfpd to disable the HFP HS role and keep a "legacy" ofono
backend for the HFP HS role - should not be that hard to implement
compared to all the time and work you already invested and it would
help us to keep users happy.

As I said, I have no problems with allowing to disable particular
profile from hsphpfd. But the way how ofono has it implemented, when it
is not possible to unregister specific profile and it always register
master SCO listening socket, it means that you cannot have two
applications which would implement or register HSP or HFP profile for
audio, independently of the role.

So you cannot use ofono's HFP AG role for connecting mobile phone and
other application (e.g. hsphpfd) for using HFP HS role for connecting
headset.

Sorry, forgive my ignorance. You can switch off ofonos AG role,
in that case it will only register the HS role with bluetoothd and
only react to connection attempts with the specific UUID.
Is it not possible that ofono registers one role and hsphfpd the
other?

And even if it is not possible and you can't use both at the same
time (which would be a pity), we still have to respect if a user
thinks that for him a working implementation for his mobile is
more important than good headset support and therefore prefers
the ofono backend over any other backend.


So what you want is currently impossible. You have to first fix ofono
daemon, design and export API for it and then implement other side to
use that API.

And I'm explaining again that this is reason why to have one central
daemon which would implement HSP and HFP profiles and proxies needed
support / sockets to target applications.

If one application is stealing listening sockets and cannot be
configured to not do it, other applications are just out of luck.

It is same as if two UDP or TCP applications wants to listen on port
1234 and both want to accept new connections. Without full cooperative
environment it does not work. hsphfpd daemon is there to accept new
connections from both RFCOMM and SCO sockets and do all needed stuff
with it (pass to other application, or process data on it directly).


The point is, that the applications that support the new hsphfpd
not yet exist, so we have at least to support the status quo until
there is some alternative.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Bluetooth HSP and HFP support in pulseaudio

2020-04-28 Thread Georg Chini

On 28.04.20 19:08, Pali Rohár wrote:

On Tuesday 28 April 2020 19:25:12 Tanu Kaskinen wrote:

It's not helpful to repeat that the ofono code needs massive changes as
a precondition to having a hsphfpd backend without specifying those
changes, because it sounds so unlikely to be true. Later in your mail
you mentioned that the profile switching needs to be changed from
synchronous to asynchronous. Good, now there's something concrete to
discuss.

ofono API does not support closing and unregistering profile connection:
https://git.kernel.org/pub/scm/network/ofono/ofono.git/tree/doc/handsfree-api.txt
https://git.kernel.org/pub/scm/network/ofono/ofono.git/tree/doc/handsfree-audio-api.txt
Without it, it is not possible to implement coexistency. There is only
API for unregistring agent, which is not enough. ofono API does not
support HSP profiles at all.

So HSP and HSP profile switching is not possible to implement with this
backend.

Next problem is that this ofono API does not provide MTU of acquired SCO
socket. Without it it not possible to implement correct handling of
buffer sizes, which is e.g. used by my changes for hsphfpd
implementation.

I already wrote all those problems in previous emails and I really do
not want to copy+paste content of my previous emails.

ofono API is basically broken design for audio applications and proper
usage needs to be changed and fixed. But I already did it, and it is
what resulted in hsphfpd API.


I do not want to disagree that for some people it works, I have no
reason to not trust Georg that it works for him.


Even if hsphfpd could do everything that oFono does, it's a new
project, I'd call it experimental at this stage. I don't want to tell
users that they have to change their working software stack in order to
keep old features when updating to a new PulseAudio version.

If oFono is not working for you and you therefore can't test it, then
don't test it. Fixing existing bugs in oFono isn't your job. Just avoid
touching the oFono code as much as possible.

I really cannot implement and use hsphpfd backend coexistence with
current ofono backend. And I cannot implement (asynchronous) support for
profile switching between A2DP, HSP and HFP profile which I did in that
published code with current ofono backend. This profile switching is
required for hsphfpd and it is not possible to implement it without
touching and fixing ofono code. So this was also another reason why I
removed it from my WIP codebase.

Ok, so you need to change how profile switching works. Can you abstract
away the differences between asynchronous and synchronous profile
switching? Like call a different card_set_profile() implementation with
ofono (this is just an example).

Why? I said that I spent to much time with that ofono and I really do
not want to invest more time in ofono backend which is basically
incompatible with hsphpfd daemon.


To me it seems that it should be entirely possible to move the old
bluez-util.c code to the ofono backend for those parts that cause major
problems with adapting the ofono code. In the worst case the whole
bluetooth infrastructure and modules need to be duplicated, and I
really hope we don't have to go there, but that's still better than
removing functionality. 

Well, why you do not try to yourself? You are talking about it like
something easy to implement, debug and deliver to users.

I also spend too much time trying to fix internal pulseaudio HSP profile
implementation and every time I think it works, something else appeared
to be broken again. But finally I was able to do it.

Why you are still trying to keep this ofono backend as is as we know
that is cause interopability problems, have broken API for audio, ofono
community is not willing to fix it and maintain it and moreover there is
replacement in my new hsphpfd design?


Neither Tanu nor I want to say that things are easy and we both do not
expect you to fix the ofono backend. But people are using it to connect
their mobile and I have not seen many complaints concerning this.
The complaints are all about headset support which I agree is unusable
for the ofono backend and far from perfect for the native backend.

Personally I don't see a problem to remove the AG role support from
the ofono backend because nobody uses it. What I proposed earlier
- allow hsphfpd to disable the HFP HS role and keep a "legacy" ofono
backend for the HFP HS role - should not be that hard to implement
compared to all the time and work you already invested and it would
help us to keep users happy.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Bluetooth HSP and HFP support in pulseaudio

2020-04-27 Thread Georg Chini

On 27.04.20 22:22, Pali Rohár wrote:

On Monday 27 April 2020 22:18:38 Georg Chini wrote:

On 27.04.20 22:12, Pali Rohár wrote:

On Monday 27 April 2020 22:06:29 Georg Chini wrote:

On 27.04.20 21:45, Georg Chini wrote:

On 27.04.20 01:44, Pali Rohár wrote:

On Tuesday 31 March 2020 09:36:21 Georg Chini wrote:

One comment here: The hsphfpd should be able to co-exist with
ofono. ofono + PA currently is the only way you can use your mobile
on Linux and we should not break this (unless the hsphfpd supplies
the same functionality). So - similar to ofono - it should at least be
possible to switch off the corresponding role, so that ofono can be
used for one role and hsphfpd for the other.

If you can disable HFP support in ofono, then hsphfpd and ofono can
coexist in system.

But coexistence of two HSP AG or HFP AG applications in system is
impossible due to master listening SCO socket.

That is exactly my point. But you can have one application handle the
AG role while the other handles the HS role. For ofono mainly the HS
role is interesting, for PA mainly the AG role. Removing ofono completly
makes mobiles unusable under linux. In ofono, you can switch off
the AG role.

You would only need an option so that hsphfpd does not register the HS
role with bluetoothd and would need to keep the corresponding bits of the
ofono backend.

I can do this in hsphfpd daemon...


That should not be much additional work and would not
break the current use cases of the PA/ofono combination.

... but I had to remove ofono backend from pulseaudio. Sorry it is
broken and I do not have power to fix ...

The HS implementation is not broken but works very well.

My test results are different. (I spent more days with with this during
implementation of hsphfpd, integration into pulseaudio and
interoperability).

It works well for me and for other people, so simply removing the 
functionality

is not an option in my opinion. If there are issues, they must be fixed, but
that needs not be part of your patch set. Can you be a little bit more 
specific

what does not work?

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Bluetooth HSP and HFP support in pulseaudio

2020-04-27 Thread Georg Chini

On 27.04.20 22:12, Pali Rohár wrote:

On Monday 27 April 2020 22:06:29 Georg Chini wrote:

On 27.04.20 21:45, Georg Chini wrote:

On 27.04.20 01:44, Pali Rohár wrote:

On Tuesday 31 March 2020 09:36:21 Georg Chini wrote:

One comment here: The hsphfpd should be able to co-exist with
ofono. ofono + PA currently is the only way you can use your mobile
on Linux and we should not break this (unless the hsphfpd supplies
the same functionality). So - similar to ofono - it should at least be
possible to switch off the corresponding role, so that ofono can be
used for one role and hsphfpd for the other.

If you can disable HFP support in ofono, then hsphfpd and ofono can
coexist in system.

But coexistence of two HSP AG or HFP AG applications in system is
impossible due to master listening SCO socket.

That is exactly my point. But you can have one application handle the
AG role while the other handles the HS role. For ofono mainly the HS
role is interesting, for PA mainly the AG role. Removing ofono completly
makes mobiles unusable under linux. In ofono, you can switch off
the AG role.

You would only need an option so that hsphfpd does not register the HS
role with bluetoothd and would need to keep the corresponding bits of the
ofono backend.

I can do this in hsphfpd daemon...


That should not be much additional work and would not
break the current use cases of the PA/ofono combination.

... but I had to remove ofono backend from pulseaudio. Sorry it is
broken and I do not have power to fix ...


The HS implementation is not broken but works very well. I agree that
the AG implementation is broken. So from the ofono backend, only the
AG part needs to be removed. As far as I remember that is not much
and should not be that difficult to separate out.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Bluetooth HSP and HFP support in pulseaudio

2020-04-27 Thread Georg Chini

On 27.04.20 21:45, Georg Chini wrote:

On 27.04.20 01:44, Pali Rohár wrote:

On Tuesday 31 March 2020 09:36:21 Georg Chini wrote:

One comment here: The hsphfpd should be able to co-exist with
ofono. ofono + PA currently is the only way you can use your mobile
on Linux and we should not break this (unless the hsphfpd supplies
the same functionality). So - similar to ofono - it should at least be
possible to switch off the corresponding role, so that ofono can be
used for one role and hsphfpd for the other.

If you can disable HFP support in ofono, then hsphfpd and ofono can
coexist in system.

But coexistence of two HSP AG or HFP AG applications in system is
impossible due to master listening SCO socket.


That is exactly my point. But you can have one application handle the
AG role while the other handles the HS role. For ofono mainly the HS
role is interesting, for PA mainly the AG role. Removing ofono completly
makes mobiles unusable under linux. In ofono, you can switch off
the AG role.


You would only need an option so that hsphfpd does not register the HS
role with bluetoothd and would need to keep the corresponding bits of the
ofono backend. That should not be much additional work and would not
break the current use cases of the PA/ofono combination.
Like ofono, without the option, hsphfpd would register both roles.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Bluetooth HSP and HFP support in pulseaudio

2020-04-27 Thread Georg Chini

On 27.04.20 01:44, Pali Rohár wrote:

On Tuesday 31 March 2020 09:36:21 Georg Chini wrote:

One comment here: The hsphfpd should be able to co-exist with
ofono. ofono + PA currently is the only way you can use your mobile
on Linux and we should not break this (unless the hsphfpd supplies
the same functionality). So - similar to ofono - it should at least be
possible to switch off the corresponding role, so that ofono can be
used for one role and hsphfpd for the other.

If you can disable HFP support in ofono, then hsphfpd and ofono can
coexist in system.

But coexistence of two HSP AG or HFP AG applications in system is
impossible due to master listening SCO socket.


That is exactly my point. But you can have one application handle the
AG role while the other handles the HS role. For ofono mainly the HS
role is interesting, for PA mainly the AG role. Removing ofono completly
makes mobiles unusable under linux. In ofono, you can switch off
the AG role.


___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Device fallback priority

2020-04-12 Thread Georg Chini

On 11.04.20 22:29, Daniel wrote:

Hello,

I have 2 alsa devices in my system, card 0 is my Nvidia graphics card
for HDMI Audio output, card 1 is my internal onboard audio. I prefer
the HDMI Audio via my Nvidia card and setting this as default device
works just fine.

When I now add another audio device like via USB or Bluetooth, its
sink becomes default, and this is quite what I want, so this is fine.
But when I now disconnect this device again, the new default sink
always is my internal audio instead of the HDMI audio.

How can I get the system to fall back to my HDMI Audio after the
active sink gets unavailable? Can I set priorities manually in
default.pa or similar?

The modules module-default-device-restore, module-device-restore,
module-stream-restore and module-card-restore are loaded. If one of
these is supposed to do this job, does that need some manual
configuration? If yes, how?

I'm running Ubuntu 19.10 64-bit. I already deleted ~.config/pulse and
restarted pulseaudio to make sure there are no unwanted settings in my
pulse db files. The file .config/pulse/[id]-default-sink correctly
contains the HDMI sink in the format of the output below.

$ pactl info
Server String: /run/user/1000/pulse/native
Library Protocol Version: 33
Server Protocol Version: 33
Is Local: yes
Client Index: 8
Tile Size: 65472
User Name: daniel
Host Name: windseeker
Server Name: pulseaudio
Server Version: 13.0
Default Sample Specification: s16le 2ch 44100Hz
Default Channel Map: front-left,front-right
Default Sink: alsa_output.pci-_01_00.1.hdmi-stereo
Default Source: alsa_output.pci-_01_00.1.hdmi-stereo.monitor
Cookie: b87b:c3cd

$ pactl list sinks short
1   alsa_output.pci-_00_1b.0.analog-stereo
module-alsa-card.c  s16le 2ch 44100Hz   IDLE
4   alsa_output.pci-_01_00.1.hdmi-stereo
module-alsa-card.c  s16le 2ch 44100Hz   IDLE

Thank you and best regards,
Daniel

The short answer is: You can't achieve what you want, at least not
by tweaking the configuration.

What you could try to do is write a script that catches default sink changes
(for example by parsing the output of "pactl subscribe") and switches to 
HDMI

when necessary.

The feature you are requesting is one of the things that we plan to 
implement.

We need to remember the user defined default sink when one of the routing
modules changes the default sink so that we can fall back to the 
original sink

once the temporary default sink disappears.

Regards
    Georg
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Bluetooth HSP and HFP support in pulseaudio

2020-03-31 Thread Georg Chini

On 17.03.20 13:06, Pali Rohár wrote:

On Monday 16 March 2020 18:19:47 Tanu Kaskinen wrote:

On Sun, 2020-03-15 at 14:37 +0100, Pali Rohár wrote:

Hello! One month passed and I have not answer which solution would
pulseaudio choose for HSP and HFP support. Could you please really look
at my email about state of HSP / HFP support?

On Saturday 15 February 2020 22:33:10 Pali Rohár wrote:

If Linux desktop / laptop with pulseaudio want to support HFP profile
there are following options:

1) As written above, implement full HFP profile, therefore telephony
stack in pulseaudio and handle all users features in pulseaudio
(input devices, power devices, telephony features) including audio
features (wide band support, custom codec support). In this setup
pulseaudio would be incompatible with ofono and ofono must be stopped
on that computer to prevent ofono from taking rfcom socket.

2) Delegate all non-audio features of HSP and HFP profiles from 1) to
hsphfpd daemon and implement in pulseaudio only audio related
features via DBus API provided by hsphfpd daemon. In this setup
hsphfpd would own rfcom socket and via DBus API would communicate
with other applications (e.g. pulseaudio, upower). This setup is
incompatible with ofono, as ofono developers wrote that they do not
want to use this design and because ofono implements own handling of
HFP profiles, ofono daemon would need to be stopped on such machine
to prevent ofono from taking rfcom socket. So telephony functions would
not be supported until somebody write alternative telephony software
which would connect to hsphfpd as ofono devs do not want to use
hsphfpd.

3) In pulseaudio drop support for all desktop and laptop computers which
do not have connected cellular modem compatible with ofono. In this
way we could use ofono's HFP implementation for some basic audio
stuff. But no additional features (like battery status or input
buttons) would be provided. Also no custom codecs, etc.

4) In pulseaudio do not implement proper and full HFP profile support at
all. Just say to users, that if they want to use bluetooth HFP
headset, they have to change operating system from Linux to some
other which implement it.

5) Like 4) but be silent and do not say anything to users. Do not answer
to question from users about bluetooth HSP/HFP. Just do not do
anything.

...

So please, pulseaudio developers/maintainers, write what you think and
which option you choose and who would implement that option. Remember,
that silence means you automatically chose option 5) which would be rude
to all pulseaudio users.

Does really silence mean that option 5) was automatically chosen? I hope
that not.

If you have not had time to discuss, compare and choose solution, please
write at least that you are not going to choose option 5).

I have not had time to discuss.

I think it makes sense to try the hsphfpd approach, if you're motivated
to write and maintain that all by yourself (plus the integration code
in PulseAudio). With luck you'll find someone to help, but I'm not
aware of anyone who has time for that.

As I said, I can develop integration code for pulseaudio too. And also I
can maintain hsphfpd daemon.

I will try to find a time and prepare integration part for pulseaudio.


Georg said that it doesn't make sense to implement this only for PA,
but if you get it to a working state, I don't see why PipeWire (and
maybe alsa-bluez) wouldn't use it too.

Ok.


There's one other approach, however, that you seem to reject for a
reason that is not clear to me: if I understood correctly the
discussion with the oFono developers[1], they're open to implementing
everything hsphfpd does in oFono.

There is a main rejection in design, that HSP and HFP cannot be in one
service and therefore on ofono side it needs to be on two separated
places, plus target audio application (pulseaudio) would need to
implement two separate services and endpoints, one for HSP and one for
HFP, even for audio part they are same.

In my hsphfpd API, there is just one service for both HSP and HFP
profiles and audio application needs to implement communication with
just one service which provides audio socket (either from HSP or HFP).


They said they're not planning to add
the missing features, but they didn't say they would reject patches.
For comparison, I'm not really planning to add any features to
PulseAudio either (no time for that), but that doesn't mean I reject
features implemented by other people than me.

Another thing against ofono: it is modem connection software. Why such
software needs to be requirement for desktop system which do not have
any cellular (or other) modem?

Also more people prefer to use other modem connection software, e.g.
ModemManager. Now if we add requirement that ofono is crucial part for
bluetooth, then there would be another problem: How to use ModemManager
on system with bluetooth head

Re: [pulseaudio-discuss] Latency problem with module-loopback after downtime

2020-03-01 Thread Georg Chini

On 23.02.20 12:16, Daniel Krysiak wrote:

Hi,

No, this is not about the usual loopback latency ;) I have found a 
strange anomaly.


I have 2 sound cards: C-Media CMI8738 (I've check, well supported on 
Linux, work great)
1st is for Toslink input, 2nd for Toslink output (and this is the 
default and only sink for the whole system)


I'm setting up a loopback device like this:
pactl load-module module-loopback \
latency_msec=1 \
source=alsa_input.pci-_06_01.0.iec958-stereo \
sink=alsa_output.pci-_06_02.0.iec958-stereo

And this works great! Latency is very low:
Sink Input #0
    Driver: module-loopback.c
    [...]
    Buffer Latency: 10250 usec
    Sink Latency: 7263 usec

Source Output #0
    Driver: module-loopback.c
    [...]
    Buffer Latency: 0 usec
    Source Latency: 380 usec


Now, here is the problem. When I unplug a cable of the source, source 
latency rises to infinity. And I understand why, it's fine, but, when 
I plug the cable again, then: source Latency slowly goes down, but 
sink's buffer latency rises, up to even 8-12 seconds.


Notes:
 - Reloading the module is a fix.
 - by unplug I mean unplug, or shut down the source: anything that 
stops the signal.



What I'm looking for:
1. This is most likely a bug, which I could help analyze by providing 
more data.
2. But in the meantime, I'm looking for a way to reload the module 
when source device shows up. This is the best I came up with so far, 
in tmux:


watch -n 105 'pactl list | grep -A 12 module-loopback.c | grep "Source 
Latency" | grep -Eo "[0-9]{9}" &> /dev/null && pactl unload-module 
module-loopback && sleep 6 && pactl load-module module-loopback 
latency_msec=1 source=alsa_input.pci-_06_01.0.iec958-stereo 
sink=alsa_output.pci-_06_02.0.iec958-stereo && echo "reload"'


(if Source Latency goes over 8 digit number (100seconds), reload the 
module-loopback)


What PA version are you using?

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Bluetooth HSP and HFP support in pulseaudio

2020-02-18 Thread Georg Chini

On 18.02.20 13:37, Pali Rohár wrote:

On Tuesday 18 February 2020 13:13:35 Georg Chini wrote:

On 18.02.20 11:29, Pali Rohár wrote:

On Tuesday 18 February 2020 11:06:03 Georg Chini wrote:

On 18.02.20 10:34, Pali Rohár wrote:

Hello!

On Tuesday 18 February 2020 09:42:38 Georg Chini wrote:

On 15.02.20 22:33, Pali Rohár wrote:

Hello!

More then two months ago I started discussion how to handle currently
unsupported parts of Bluetooth HSP and HFP profiles on Linux via
pulseaudio.

Main problems are:

1) These profiles are bound with telephony stack and without having half
   of telephony stack it is not possible to handle stable and working
   HFP profile. Telephony stack is needed for parsing AT commands and
   handling state machine.

There are several patch sets on gitlab and on the mailing list that
prove that you don't need half the telephony stack. Yes, you need
some of it but I think you overestimate what is really needed.

These patches does not work and completely break support for some
headsets which are currently working fine. Examples of such headsets are
from Creative Labs company. I already wrote it to pull request on
gitlab.

So no, this is not a solution, breaking support for headsets which are
currently working fine.

They are at least nearly working. Yes, they have some flaws
but with some work on them it can surely be improved.

They have important flaws, after they are integrated they completely
breaks support for headsets which are currently working. This is really
no-go.

But better to have a starting point than start from scratch.

Work
on the implementation is needed anyway and the old patches
on patchwork and the current ones on gitlab provide a good
starting point because a lot of the work is already done.

2) Only one application can own RFCOMM socket over which are transmitting
   AT commands.

3) Application which own socket needs to implement all features of HSP
   and HFP profiles. Therefore if users want to read battery status,
   this application needs to implement it. If users want to handle
   headset buttons, this application needs to implement it. And if users
   want to do telephony operations, this application needs to implement
   whole telephony stack.

Again I don't agree. There is no need to handle the whole telephony
stack if you only want headset support.

Unfortunately for some headsets it is needed :-(

I can't believe that.

Me too. But I already spend 3+ months in this area. During implementation
of hsphfpd and debugging more headsets I saw how they works, what they
implements and how to use it.

I still can't believe that not implementing all functionality renders

You still cannot believe it?

Then take free time for one half our year, starts collecting different
headsets, implement your own HFP profile implementation, start testing
it and come up with results.

I cannot say more about it.


a headset useless. There must be ways to work around such broken
implementations. Would those headsets then not also break with
your hsphfpd if there is no application that handles the telephony
stuff? If not, you obviously found a workaround already.

In hsphfpd I implemented small telephony stack which is used when there
is no application connected. It is just very simple, reject all
incoming calls, correctly send notifications that there is no active
call (for AT commands which may change internal telephony state).

That's what I say. So there is a workaround.

Maybe you have to supply some dummy answers
to certain AT commands, but it should be doable.

4) Wideband audio depends on HFP profile. Therefor 3), 2) and 1) must be
   solved if we want wideband high quality audio support for voice
   calls.

To solve these problems I proposed a new hsphfpd daemon which would
implement HSP and HFP profiles, therefore a new daemon which would own
rfcomm socket and would proxies AT commands (which could not resolve by
its own) to target applications. So telephony operations could be
implemented by one software (e.g. ofono), battery/power related by
another (e.g. upower) and audio by another (e.g. pulseaudio).

This design was rejected by ofono developers as they do not want to use
such proxy daemon. ofono already implements some parts of HFP profile
(but not HSP) and therefore is in the position of the "owner" of rfcomm
socket, like my design of hsphfpd. ofono already provides some API for
audio applications, but this API is not very suitable. I asked about
missing features and APIs which are designed and provided by hsphfpd,
but after a longer discussion ofono developer said that there are no
plans in ofono to implement missing features and APIs of HFP profile
which are currently missing in ofono. Also ofono's implementation of HFP
profile requires in computer to have connected and working cellular
modem, without it bluetooth HFP profile for bluetooth headsets does not
work. Pulseaud

Re: [pulseaudio-discuss] Bluetooth HSP and HFP support in pulseaudio

2020-02-18 Thread Georg Chini

On 18.02.20 11:29, Pali Rohár wrote:

On Tuesday 18 February 2020 11:06:03 Georg Chini wrote:

On 18.02.20 10:34, Pali Rohár wrote:

Hello!

On Tuesday 18 February 2020 09:42:38 Georg Chini wrote:

On 15.02.20 22:33, Pali Rohár wrote:

Hello!

More then two months ago I started discussion how to handle currently
unsupported parts of Bluetooth HSP and HFP profiles on Linux via
pulseaudio.

Main problems are:

1) These profiles are bound with telephony stack and without having half
  of telephony stack it is not possible to handle stable and working
  HFP profile. Telephony stack is needed for parsing AT commands and
  handling state machine.

There are several patch sets on gitlab and on the mailing list that
prove that you don't need half the telephony stack. Yes, you need
some of it but I think you overestimate what is really needed.

These patches does not work and completely break support for some
headsets which are currently working fine. Examples of such headsets are
from Creative Labs company. I already wrote it to pull request on
gitlab.

So no, this is not a solution, breaking support for headsets which are
currently working fine.

They are at least nearly working. Yes, they have some flaws
but with some work on them it can surely be improved.

They have important flaws, after they are integrated they completely
breaks support for headsets which are currently working. This is really
no-go.

But better to have a starting point than start from scratch.



Work
on the implementation is needed anyway and the old patches
on patchwork and the current ones on gitlab provide a good
starting point because a lot of the work is already done.

2) Only one application can own RFCOMM socket over which are transmitting
  AT commands.

3) Application which own socket needs to implement all features of HSP
  and HFP profiles. Therefore if users want to read battery status,
  this application needs to implement it. If users want to handle
  headset buttons, this application needs to implement it. And if users
  want to do telephony operations, this application needs to implement
  whole telephony stack.

Again I don't agree. There is no need to handle the whole telephony
stack if you only want headset support.

Unfortunately for some headsets it is needed :-(

I can't believe that.

Me too. But I already spend 3+ months in this area. During implementation
of hsphfpd and debugging more headsets I saw how they works, what they
implements and how to use it.

I still can't believe that not implementing all functionality renders
a headset useless. There must be ways to work around such broken
implementations. Would those headsets then not also break with
your hsphfpd if there is no application that handles the telephony
stuff? If not, you obviously found a workaround already.



Maybe you have to supply some dummy answers
to certain AT commands, but it should be doable.

4) Wideband audio depends on HFP profile. Therefor 3), 2) and 1) must be
  solved if we want wideband high quality audio support for voice
  calls.

To solve these problems I proposed a new hsphfpd daemon which would
implement HSP and HFP profiles, therefore a new daemon which would own
rfcomm socket and would proxies AT commands (which could not resolve by
its own) to target applications. So telephony operations could be
implemented by one software (e.g. ofono), battery/power related by
another (e.g. upower) and audio by another (e.g. pulseaudio).

This design was rejected by ofono developers as they do not want to use
such proxy daemon. ofono already implements some parts of HFP profile
(but not HSP) and therefore is in the position of the "owner" of rfcomm
socket, like my design of hsphfpd. ofono already provides some API for
audio applications, but this API is not very suitable. I asked about
missing features and APIs which are designed and provided by hsphfpd,
but after a longer discussion ofono developer said that there are no
plans in ofono to implement missing features and APIs of HFP profile
which are currently missing in ofono. Also ofono's implementation of HFP
profile requires in computer to have connected and working cellular
modem, without it bluetooth HFP profile for bluetooth headsets does not
work. Pulseaudio has on wiki written some steps how to workaround this
limitation by usage of modem simulator, but ofono developers wrote that
this is hack and should not be used at all. And HSP profile is not
supported at all.

So conclusion from ofono discussion is: They do not want to support my
proposed solution via hsphpfd. And also they do not plan to implement
missing features of HFP profile to their HFP implementations, like usage
of bluetooth headset without connected cellular modem into computers,
support for HSP profile, support for custom HSP and HFP audio codecs,
support for battery and input buttons, etc...

So ofono is fully unusable for any HSP or HF

Re: [pulseaudio-discuss] Bluetooth HSP and HFP support in pulseaudio

2020-02-18 Thread Georg Chini

On 18.02.20 10:34, Pali Rohár wrote:

Hello!

On Tuesday 18 February 2020 09:42:38 Georg Chini wrote:

On 15.02.20 22:33, Pali Rohár wrote:

Hello!

More then two months ago I started discussion how to handle currently
unsupported parts of Bluetooth HSP and HFP profiles on Linux via
pulseaudio.

Main problems are:

1) These profiles are bound with telephony stack and without having half
 of telephony stack it is not possible to handle stable and working
 HFP profile. Telephony stack is needed for parsing AT commands and
 handling state machine.

There are several patch sets on gitlab and on the mailing list that
prove that you don't need half the telephony stack. Yes, you need
some of it but I think you overestimate what is really needed.

These patches does not work and completely break support for some
headsets which are currently working fine. Examples of such headsets are
from Creative Labs company. I already wrote it to pull request on
gitlab.

So no, this is not a solution, breaking support for headsets which are
currently working fine.

They are at least nearly working. Yes, they have some flaws
but with some work on them it can surely be improved. Work
on the implementation is needed anyway and the old patches
on patchwork and the current ones on gitlab provide a good
starting point because a lot of the work is already done.



2) Only one application can own RFCOMM socket over which are transmitting
 AT commands.

3) Application which own socket needs to implement all features of HSP
 and HFP profiles. Therefore if users want to read battery status,
 this application needs to implement it. If users want to handle
 headset buttons, this application needs to implement it. And if users
 want to do telephony operations, this application needs to implement
 whole telephony stack.

Again I don't agree. There is no need to handle the whole telephony
stack if you only want headset support.

Unfortunately for some headsets it is needed :-(

I can't believe that. Maybe you have to supply some dummy answers
to certain AT commands, but it should be doable.



4) Wideband audio depends on HFP profile. Therefor 3), 2) and 1) must be
 solved if we want wideband high quality audio support for voice
 calls.

To solve these problems I proposed a new hsphfpd daemon which would
implement HSP and HFP profiles, therefore a new daemon which would own
rfcomm socket and would proxies AT commands (which could not resolve by
its own) to target applications. So telephony operations could be
implemented by one software (e.g. ofono), battery/power related by
another (e.g. upower) and audio by another (e.g. pulseaudio).

This design was rejected by ofono developers as they do not want to use
such proxy daemon. ofono already implements some parts of HFP profile
(but not HSP) and therefore is in the position of the "owner" of rfcomm
socket, like my design of hsphfpd. ofono already provides some API for
audio applications, but this API is not very suitable. I asked about
missing features and APIs which are designed and provided by hsphfpd,
but after a longer discussion ofono developer said that there are no
plans in ofono to implement missing features and APIs of HFP profile
which are currently missing in ofono. Also ofono's implementation of HFP
profile requires in computer to have connected and working cellular
modem, without it bluetooth HFP profile for bluetooth headsets does not
work. Pulseaudio has on wiki written some steps how to workaround this
limitation by usage of modem simulator, but ofono developers wrote that
this is hack and should not be used at all. And HSP profile is not
supported at all.

So conclusion from ofono discussion is: They do not want to support my
proposed solution via hsphpfd. And also they do not plan to implement
missing features of HFP profile to their HFP implementations, like usage
of bluetooth headset without connected cellular modem into computers,
support for HSP profile, support for custom HSP and HFP audio codecs,
support for battery and input buttons, etc...

So ofono is fully unusable for any HSP or HFP features of bluetooth
headsets on regular desktop or laptop computer with Linux.

If Linux desktop / laptop with pulseaudio want to support HFP profile
there are following options:

1) As written above, implement full HFP profile, therefore telephony
 stack in pulseaudio and handle all users features in pulseaudio
 (input devices, power devices, telephony features) including audio
 features (wide band support, custom codec support). In this setup
 pulseaudio would be incompatible with ofono and ofono must be stopped
 on that computer to prevent ofono from taking rfcom socket.

This is not true. You can disable the ofono headset support selectively
in ofono, so ofono could still handle telephony while PA handles headsets.

Ok, so if this is truth that you can disable ofono <--> bluetooth

Re: [pulseaudio-discuss] Bluetooth HSP and HFP support in pulseaudio

2020-02-18 Thread Georg Chini

On 15.02.20 22:33, Pali Rohár wrote:

Hello!

More then two months ago I started discussion how to handle currently
unsupported parts of Bluetooth HSP and HFP profiles on Linux via
pulseaudio.

Main problems are:

1) These profiles are bound with telephony stack and without having half
of telephony stack it is not possible to handle stable and working
HFP profile. Telephony stack is needed for parsing AT commands and
handling state machine.

There are several patch sets on gitlab and on the mailing list that
prove that you don't need half the telephony stack. Yes, you need
some of it but I think you overestimate what is really needed.


2) Only one application can own RFCOMM socket over which are transmitting
AT commands.

3) Application which own socket needs to implement all features of HSP
and HFP profiles. Therefore if users want to read battery status,
this application needs to implement it. If users want to handle
headset buttons, this application needs to implement it. And if users
want to do telephony operations, this application needs to implement
whole telephony stack.

Again I don't agree. There is no need to handle the whole telephony
stack if you only want headset support.


4) Wideband audio depends on HFP profile. Therefor 3), 2) and 1) must be
solved if we want wideband high quality audio support for voice
calls.

To solve these problems I proposed a new hsphfpd daemon which would
implement HSP and HFP profiles, therefore a new daemon which would own
rfcomm socket and would proxies AT commands (which could not resolve by
its own) to target applications. So telephony operations could be
implemented by one software (e.g. ofono), battery/power related by
another (e.g. upower) and audio by another (e.g. pulseaudio).

This design was rejected by ofono developers as they do not want to use
such proxy daemon. ofono already implements some parts of HFP profile
(but not HSP) and therefore is in the position of the "owner" of rfcomm
socket, like my design of hsphfpd. ofono already provides some API for
audio applications, but this API is not very suitable. I asked about
missing features and APIs which are designed and provided by hsphfpd,
but after a longer discussion ofono developer said that there are no
plans in ofono to implement missing features and APIs of HFP profile
which are currently missing in ofono. Also ofono's implementation of HFP
profile requires in computer to have connected and working cellular
modem, without it bluetooth HFP profile for bluetooth headsets does not
work. Pulseaudio has on wiki written some steps how to workaround this
limitation by usage of modem simulator, but ofono developers wrote that
this is hack and should not be used at all. And HSP profile is not
supported at all.

So conclusion from ofono discussion is: They do not want to support my
proposed solution via hsphpfd. And also they do not plan to implement
missing features of HFP profile to their HFP implementations, like usage
of bluetooth headset without connected cellular modem into computers,
support for HSP profile, support for custom HSP and HFP audio codecs,
support for battery and input buttons, etc...

So ofono is fully unusable for any HSP or HFP features of bluetooth
headsets on regular desktop or laptop computer with Linux.

If Linux desktop / laptop with pulseaudio want to support HFP profile
there are following options:

1) As written above, implement full HFP profile, therefore telephony
stack in pulseaudio and handle all users features in pulseaudio
(input devices, power devices, telephony features) including audio
features (wide band support, custom codec support). In this setup
pulseaudio would be incompatible with ofono and ofono must be stopped
on that computer to prevent ofono from taking rfcom socket.


This is not true. You can disable the ofono headset support selectively
in ofono, so ofono could still handle telephony while PA handles headsets.



2) Delegate all non-audio features of HSP and HFP profiles from 1) to
hsphfpd daemon and implement in pulseaudio only audio related
features via DBus API provided by hsphfpd daemon. In this setup
hsphfpd would own rfcom socket and via DBus API would communicate
with other applications (e.g. pulseaudio, upower). This setup is
incompatible with ofono, as ofono developers wrote that they do not
want to use this design and because ofono implements own handling of
HFP profiles, ofono daemon would need to be stopped on such machine
to prevent ofono from taking rfcom socket. So telephony functions would
not be supported until somebody write alternative telephony software
which would connect to hsphfpd as ofono devs do not want to use
hsphfpd.

3) In pulseaudio drop support for all desktop and laptop computers which
do not have connected cellular modem compatible with ofono. In this
way we could use ofono's HFP implementation for some b

Re: [pulseaudio-discuss] [PATCH v13 07/10] bluetooth: Add more variants of SBC codec

2020-02-02 Thread Georg Chini

On 02.02.20 14:08, Pali Rohár wrote:

On Thursday 23 January 2020 12:29:15 Georg Chini wrote:

On Tuesday 21 January 2020 16:17:16 Georg Chini wrote:

...

+}
+
+static bool can_accept_capabilities_xq2(const uint8_t *capabilities_buffer, 
uint8_t capabilities_size, bool for_encoding) {
+return can_accept_capabilities_table(capabilities_buffer, 
capabilities_size, sbc_xq2_caps_table, PA_ELEMENTSOF(sbc_xq2_caps_table));
+}
+
+static const char *choose_remote_endpoint_table(const pa_hashmap 
*capabilities_hashmap, const pa_sample_spec *default_sample_spec, const 
a2dp_sbc_t capabilities_table[], unsigned capabilities_table_elements) {
const pa_a2dp_codec_capabilities *a2dp_capabilities;
+const a2dp_sbc_t *capabilities;
const char *key;
void *state;
+unsigned i;
+uint8_t table_range;
+uint8_t current_range;
+const char *best_key = NULL;
+uint8_t best_range = 0;
+uint8_t frequency = 0;
+bool is_mono = (default_sample_spec->channels <= 1);
+
+static const struct {
+uint32_t rate;
+uint8_t cap;
+} freq_table[] = {
+{ 16000U, SBC_SAMPLING_FREQ_16000 },
+{ 32000U, SBC_SAMPLING_FREQ_32000 },
+{ 44100U, SBC_SAMPLING_FREQ_44100 },
+{ 48000U, SBC_SAMPLING_FREQ_48000 }
+};
+
+for (i = 0; i < PA_ELEMENTSOF(freq_table); i++) {
+if (freq_table[i].rate == default_sample_spec->rate) {

Is an exact match necessary here? Or would >= be OK as well?

For fixed SBC profiles we need to check for exact frequency. As there
are specific bitpool values for specific frequency.

Sure, in the end we will use one of the specific frequencies.
But need the default_sample_spec already contain the exact frequency?
Or can we choose the one nearest to default_sample_spec->rate?

Here we compare SBC freq capability with pulseaudio internal frequency.
So non-exact nearest frequency could be used too.

 I think you do that for the other codecs as well.

+
+table_range = capabilities_table[i].max_bitpool - 
capabilities_table[i].min_bitpool;
+
+/* use current remote capabilities if its bitpool range is closer to 
bitpool range in table */
+if (!best_key || abs((int)current_range - (int)(table_range)) < 
abs((int)best_range - (int)(table_range))) {
+best_range = current_range;
+best_key = key;
+}

Does that best_key evaluation really make sense? current_range and
table_range will both be 0 in all
cases except for the sbc_auto_caps case and in that case there is only one
possible element in the table.

I written this code prior to defining final list of SBC profiles. So
code was prepared to work with any list of SBC definitions.

Maybe you are right that for currently defined SBC profiles it is not
needed, but I wanted that current code would work with any SBC profile
table definition.

I don't think that makes sense. In are_configs_compatible() you rely on the
fact that the table entries only contain a single bitpool value.

That is because all currently defined profiles (except auto) have fixed
bitpool value.
Do you intend to add any other profile which would require a variable 
bitpool?

If you don't have any use case, please drop it.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH] module-zeroconf-discovery: Add parameter for switching to new tunnel modules

2020-01-30 Thread Georg Chini

On 08.05.19 20:12, Yauhen Kharuzhy wrote:

Add boolean parameter 'use_new_tunnel' to add ability to use
module-tunnel-{sink,source}-new instead of old
module-tunnel-{sink,source} modules. This parameter is false by default
for maintain behaviour compatible.

The new tunnel module don't send 'early requests' flag to server and
allow to tune latency, by using adjust latency mode and by propagating of
tlength buffer attribute from stream to server. This can be useful
during of setting up networking audio via Wi-Fi.
---
  src/modules/module-zeroconf-discover.c | 15 ++-
  1 file changed, 14 insertions(+), 1 deletion(-)


Thank you, patch looks good. We will merge it after the current
14.0 code freeze. Sorry for the late response.

Regards
 Georg

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v13 07/10] bluetooth: Add more variants of SBC codec

2020-01-23 Thread Georg Chini

On 22.01.20 20:15, Pali Rohár wrote:

Hello! Thank you for review. Comments are below inlined. Remarks about
return values of API is I guess out of scope of this patch as patch just
implements API. API is already in pulseaudio git master, so it needs to
be changed first there if really needed.


Yes, I think it needs to be changed. I agree that this is not part of
this patch and only wanted to remind that there is an open topic.
Therefore the general remark here and no comment in the code.



On Tuesday 21 January 2020 16:17:16 Georg Chini wrote:

...

+}
+
+static bool can_accept_capabilities_xq2(const uint8_t *capabilities_buffer, 
uint8_t capabilities_size, bool for_encoding) {
+return can_accept_capabilities_table(capabilities_buffer, 
capabilities_size, sbc_xq2_caps_table, PA_ELEMENTSOF(sbc_xq2_caps_table));
+}
+
+static const char *choose_remote_endpoint_table(const pa_hashmap 
*capabilities_hashmap, const pa_sample_spec *default_sample_spec, const 
a2dp_sbc_t capabilities_table[], unsigned capabilities_table_elements) {
   const pa_a2dp_codec_capabilities *a2dp_capabilities;
+const a2dp_sbc_t *capabilities;
   const char *key;
   void *state;
+unsigned i;
+uint8_t table_range;
+uint8_t current_range;
+const char *best_key = NULL;
+uint8_t best_range = 0;
+uint8_t frequency = 0;
+bool is_mono = (default_sample_spec->channels <= 1);
+
+static const struct {
+uint32_t rate;
+uint8_t cap;
+} freq_table[] = {
+{ 16000U, SBC_SAMPLING_FREQ_16000 },
+{ 32000U, SBC_SAMPLING_FREQ_32000 },
+{ 44100U, SBC_SAMPLING_FREQ_44100 },
+{ 48000U, SBC_SAMPLING_FREQ_48000 }
+};
+
+for (i = 0; i < PA_ELEMENTSOF(freq_table); i++) {
+if (freq_table[i].rate == default_sample_spec->rate) {

Is an exact match necessary here? Or would >= be OK as well?

For fixed SBC profiles we need to check for exact frequency. As there
are specific bitpool values for specific frequency.


Sure, in the end we will use one of the specific frequencies.
But need the default_sample_spec already contain the exact frequency?
Or can we choose the one nearest to default_sample_spec->rate?




+frequency = freq_table[i].cap;
+break;
+}
+}
+
+if (!frequency)
+return NULL;
-/* There is no preference, just choose random valid entry */
+/* choose remote capabilities which are compatible and its bitpool range 
is nearest to one from capabilities table */
   PA_HASHMAP_FOREACH_KV(key, a2dp_capabilities, capabilities_hashmap, 
state) {
-if (can_accept_capabilities(a2dp_capabilities->buffer, 
a2dp_capabilities->size, for_encoding))
-return key;
+/* skip remote capabilities which are not compatible */
+if (!can_accept_capabilities(a2dp_capabilities->buffer, 
a2dp_capabilities->size, false))
+continue;
+
+capabilities = (const a2dp_sbc_t *) a2dp_capabilities->buffer;
+
+/* choose capabilities from our table which is compatible with sample 
spec and remote capabilities */
+for (i = 0; i < capabilities_table_elements; i++) {
+if (!are_capabilities_compatible(capabilities, 
&capabilities_table[i]))
+continue;
+/* For mono mode both capabilities must support mono */
+if (is_mono && !((capabilities->channel_mode & SBC_CHANNEL_MODE_MONO) 
& (capabilities_table[i].channel_mode & SBC_CHANNEL_MODE_MONO)))
+continue;
+/* For non-mono mode both capabilities must support at least one 
common non-mode mode */
+if (!is_mono && !((capabilities->channel_mode & 
(SBC_CHANNEL_MODE_JOINT_STEREO | SBC_CHANNEL_MODE_STEREO | SBC_CHANNEL_MODE_DUAL_CHANNEL)) & 
(capabilities_table[i].channel_mode & (SBC_CHANNEL_MODE_JOINT_STEREO | SBC_CHANNEL_MODE_STEREO | 
SBC_CHANNEL_MODE_DUAL_CHANNEL
+continue;
+/* And both capabilites must be compatible with chosen frequency */
+if (!(capabilities->frequency & frequency) || 
!(capabilities_table[i].frequency & frequency))
+continue;
+break;
+}
+
+/* skip if nothing is compatible */
+if (i == capabilities_table_elements)
+continue;
+
+/* calculate current bitpool range compatible with both remote 
capabilities and capabilities from our table */
+if (capabilities->min_bitpool > capabilities_table[i].min_bitpool) {
+if (capabilities->max_bitpool > capabilities_table[i].max_bitpool)
+current_range = capabilities_table[i].max_bitpool - 
capabilities->min_bitpool;
+else
+current_range = capabilities->max_bitpool - 
capabilities->min_bitpool;
+} else {
+if (capabilities->max_bitpool > c

Re: [pulseaudio-discuss] [PATCH v13 07/10] bluetooth: Add more variants of SBC codec

2020-01-21 Thread Georg Chini
Finally managed to review this one. The general remarks concerning the 
return

values of the API functions apply here as well. Sorry for the delay.

On 06.10.19 19:58, Pali Rohár wrote:

Specify configuration for Low, Middle, High and eXtreme Quality of SBC
codec. SBC codec in eXtreme Quality has higher quality than aptX.

Automatic Quality mode matches configuration of SBC codec which was used
before this change. Which means that it accept configuration between Low
and High quality.

Current SBC code was extended to allow definitions of arbitrary
configuration variants of SBC codec parameters.

SBC XQ testing is in following article:
http://soundexpert.org/articles/-/blogs/audio-quality-of-sbc-xq-bluetooth-audio-codec
---
  src/modules/bluetooth/a2dp-codec-sbc.c  | 737 ++--
  src/modules/bluetooth/a2dp-codec-util.c |  20 +-
  2 files changed, 618 insertions(+), 139 deletions(-)

diff --git a/src/modules/bluetooth/a2dp-codec-sbc.c 
b/src/modules/bluetooth/a2dp-codec-sbc.c
index 733c1a9ab..8db3416b9 100644
--- a/src/modules/bluetooth/a2dp-codec-sbc.c
+++ b/src/modules/bluetooth/a2dp-codec-sbc.c
@@ -36,8 +36,71 @@
  #include "a2dp-codec-api.h"
  #include "rtp.h"
  
-#define SBC_BITPOOL_DEC_LIMIT 32

-#define SBC_BITPOOL_DEC_STEP 5
+/* Below are capabilities tables for different qualities. Order of 
capabilities in tables are from the most preferred to the least preferred. */
+
+#define FIXED_SBC_CAPS(mode, freq, bitpool) { .channel_mode = (mode), 
.frequency = (freq), .min_bitpool = (bitpool), .max_bitpool = (bitpool), 
.allocation_method = SBC_ALLOCATION_LOUDNESS, .subbands = SBC_SUBBANDS_8, 
.block_length = SBC_BLOCK_LENGTH_16 }
+
+/* SBC Low Quality, Joint Stereo is same as FastStream's SBC codec 
configuration, Mono was calculated to match Joint Stereo */
+static const a2dp_sbc_t sbc_lq_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 
29), /* 195.7 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 
29), /* 213   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 
15), /* 104.7 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 
15), /* 114   kbps */
+};
+
+/* SBC Middle Quality, based on A2DP spec: Recommended sets of SBC parameters 
*/
+static const a2dp_sbc_t sbc_mq_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 
SBC_BITPOOL_MQ_JOINT_STEREO_44100), /* bitpool = 35, 228.8 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 
SBC_BITPOOL_MQ_JOINT_STEREO_48000), /* bitpool = 33, 237   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 
SBC_BITPOOL_MQ_MONO_44100), /* bitpool = 19, 126.8 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 
SBC_BITPOOL_MQ_MONO_48000), /* bitpool = 18, 132   kbps */
+};
+
+/* SBC High Quality, based on A2DP spec: Recommended sets of SBC parameters */
+static const a2dp_sbc_t sbc_hq_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 
SBC_BITPOOL_HQ_JOINT_STEREO_44100), /* bitpool = 53, 328   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 
SBC_BITPOOL_HQ_JOINT_STEREO_48000), /* bitpool = 51, 345   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 
SBC_BITPOOL_HQ_MONO_44100), /* bitpool = 31, 192.9 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 
SBC_BITPOOL_HQ_MONO_48000), /* bitpool = 29, 210   kbps */
+};
+
+/* SBC eXtreme Quality, calculated to minimize wasted bytes and to be below 
max possible 512 kbps */
+static const a2dp_sbc_t sbc_xq1_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 
76), /* 454.8 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 
76), /* 495   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_STEREO,   SBC_SAMPLING_FREQ_44100, 
76), /* 452   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_STEREO,   SBC_SAMPLING_FREQ_48000, 
76), /* 492   kbps */
+};
+static const a2dp_sbc_t sbc_xq2_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_DUAL_CHANNEL, SBC_SAMPLING_FREQ_44100, 
38), /* 452   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_DUAL_CHANNEL, SBC_SAMPLING_FREQ_48000, 
38), /* 492   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 
37), /* 226   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 
37), /* 246   kbps */
+};
+/* In most cases bluetooth headsets would support only sbc dual channel mode
+ * for 2 channels as they have limited maximal bitpool value to 53.
+ * We need to define it in two tables to disallow invalid combination of
+ * joint stereo with bitpool 38 which is not XQ. */


The comment should be above

Re: [pulseaudio-discuss] Pending patches

2020-01-17 Thread Georg Chini

On 13.07.19 23:27, Georg Chini wrote:

Hi,

today I did a review/cleanup/rebase of all the patches I have 
accumulated.
I found there is a total of 65 patches in 11 series, together 8041 
additions
and 3233 deletions. I wonder if this ever has the chance to get 
completely

reviewed ...

Here the series in detail:

1) Messaging patches
8 patches, partly reviewed, introduces messaging API

2) Rewind and resampler patches
9 patches, fixes volume change crackling, introduces resampler delay
measurement

3) Smoother patches
10 patches, introduces new time smoother

4) Loopback patches
10 patches, optimizes latency handling of module-loopback
depends on 2)

5) Combine/Tunnel sink latency fixes
6 patches, fixes latency calculation for tunnel sink/source and 
combine sink

depends on 2)

6) Signal patches
3 patches, introduces signals as alternative to subscription
depends on 1)

7) Jack detection patches
2 patches, adds messages to enable/disable jack detection and set port 
state

depends on 1)

8) virtual source crash patch
1 patch, fixes crash with stacked virtual sources

9) virtual sink consolidation patches
8 patches, consolidates virtual sink code in a library, fixes multiple 
(crash) bugs

depends on 2)

10) virtual sink messages patches
7 patches, adds parameter setting via messages to virtual sinks
depends on 1), 2)

11) module-plugin-sink patch
1 patch, adds new module to support PA specific filter plugins
depends on 1), 2), 9), 10)

Regards
 Georg

Half a year later, after another rebase/cleanup, the situation has not 
changed very
much. Only 8) was merged recently, there has been no review progress on 
any of

the other patch series.
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Bluetooth codec selection

2020-01-08 Thread Georg Chini

On 08.01.20 12:35, Pali Rohár wrote:

On Tuesday 07 January 2020 21:57:40 Georg Chini wrote:

On 07.01.20 19:37, Pali Rohár wrote:

Hello!

My A2DP patch series which adds support for more A2DP codecs is still in
review state, but Tanu about year ago wrote that do not like my proposal
with usage of PA profiles for selecting A2DP codec. Because nobody for
last year come up with another option how to solve this problem and
because without it is not possible to add support for other codecs it
means that pulseaudio is stucked and has no way to improve A2DP support.

So here I'm adding another proposal how to handle multi-codec support
for bluetooth in pulseaudio. But first description of our problem:

Currently we have following profiles for bluetooth card:

* headset_audio_gateway
* headset_head_unit
* a2dp_source
* a2dp_sink

If we look at HW level of HSP/HFP profiles they may supports following
codecs: CVSD, mSBC, AuriStream. All are bidirectional, synchronous.
Moreover encoding from PCM stream to codec data may be done at HW level
(bluetooth adapter) or on SW level (pulseaudio). Currently encoding to
CVSD is done at HW level and encoding to mSBC at SW level. But e.g. new
Thinkpads has bluetooth adapters which can do mSBC-encoding at HW level
and theoretically pulseaudio could just pass PCM samples to BT without
need to use any software sbc encoding library (*).

And if we look at A2DP profiles it is quite a bit complicated. Every
"A2DP codec" is either one-way (source or sink) or is bi-directional
(but it is rare and most devices does not support them). Plus every
"A2DP codec" may support more "codec profiles", so e.g. we have SBC-MQ
or SBC-HQ. And bidirectional "A2DP codecs" may use different "audio
codec" for one directional and different for back directional (e.g.
A2DP codec aptX-LL uses aptX codec for playing and SBC codec for
recording).

Result is: "SBC" codec is supported in "headset_head_unit" PA profile
(as mSBC"), it is supported also in "a2dp_sink" PA profile when "A2DP
SBC" codec is used and also in "a2dp_source" PA profile when "aptX-LL"
codec is used.

So adding a new API which sets codec on PA bluetooth card is not enough.

I would propose following API:

Add support for pulseaudio "sub-profiles". For every pulseaudio profile
it would be possible to register sub-profile and applications via
pulseaudio API would be able to change sub-profile of some PA card (if
currently selected PA profile would support it).

Just to make it clear, by "applications" I mean mixer setting
applications (e.g. pactl, pavucontrol, kmix, gnome settings, ...).


Plus adds a two new profiles:
* a2dp_source_with_backchannel
* a2dp_sink_with_backchannel

For music playback in most cases is useful only profiles without
backchannel to maximize bandwidth. And because A2DP codecs with
bachannel does not fit into HSP profiles it make sense to have them in
separate profile. In most cases A2DP profile with backchannel is the
best way for VOIP (as it has microphone recording support), so bluetooth
policy plugin would be extended to use also this profile for VOIP.

Sub-profiles for bluetooth PA card would be following:

* headset_audio_gateway
- CVSD (hardware)
- mSBC (software)
- mSBC (hardware)
...
* headset_head_unit
- same as in headset_audio_gateway
* a2dp_source
- SBC-LQ
- SBC-MQ
- SBC-HQ
..,
- faststream without backchannel
- aptX
- aptX-HD
- aptX-LL without backannel
- LDAC
...
* a2dp_sink
- same as in a2dp_source
* a2dp_source_with_backchannel
- faststream with backchannel
- aptX-LL with backchannel
* a2dp_sink_with_backchannel
- same as in a2dp_source_with_backchannel

So sub-profile would be one specific configuration of codec. In HSP/HFP
there would be two sub-profiles for every codec (one for software
encoding, one for hardware encoding). In A2DP it may be various. E.g.
for "SBC profiles" there would be one sub-profile for every SBC
configuration. For faststream codec there would be two, one with
backchannel, one without. Default sub-codec selection would be up to
the pulseaudio module. And applications (pactl / pavucontrol / ...)
would be able to change PA sub-profile in similar way how they can do it
for PA profiles.

Of course some sub-profiles does not have to be supported (e.g. mSBC in
hardware encoding) and in these cases pulseaudio would not announce
these unsupported sub-profiles.

What do you think about this my proposal?

Tanu, is this acceptable for you?

Basically it is needed only to add APIs for applications to:
* get current sub-profile of card
* get list of all sub-profiles for specific profile
* change sub-profile of card

I'm not saying how would API look like. I'm open for implementation
details... I can imagine that we can extend PA protocol or use messaging
A

Re: [pulseaudio-discuss] Bluetooth codec selection

2020-01-07 Thread Georg Chini

On 07.01.20 19:37, Pali Rohár wrote:

Hello!

My A2DP patch series which adds support for more A2DP codecs is still in
review state, but Tanu about year ago wrote that do not like my proposal
with usage of PA profiles for selecting A2DP codec. Because nobody for
last year come up with another option how to solve this problem and
because without it is not possible to add support for other codecs it
means that pulseaudio is stucked and has no way to improve A2DP support.

So here I'm adding another proposal how to handle multi-codec support
for bluetooth in pulseaudio. But first description of our problem:

Currently we have following profiles for bluetooth card:

* headset_audio_gateway
* headset_head_unit
* a2dp_source
* a2dp_sink

If we look at HW level of HSP/HFP profiles they may supports following
codecs: CVSD, mSBC, AuriStream. All are bidirectional, synchronous.
Moreover encoding from PCM stream to codec data may be done at HW level
(bluetooth adapter) or on SW level (pulseaudio). Currently encoding to
CVSD is done at HW level and encoding to mSBC at SW level. But e.g. new
Thinkpads has bluetooth adapters which can do mSBC-encoding at HW level
and theoretically pulseaudio could just pass PCM samples to BT without
need to use any software sbc encoding library (*).

And if we look at A2DP profiles it is quite a bit complicated. Every
"A2DP codec" is either one-way (source or sink) or is bi-directional
(but it is rare and most devices does not support them). Plus every
"A2DP codec" may support more "codec profiles", so e.g. we have SBC-MQ
or SBC-HQ. And bidirectional "A2DP codecs" may use different "audio
codec" for one directional and different for back directional (e.g.
A2DP codec aptX-LL uses aptX codec for playing and SBC codec for
recording).

Result is: "SBC" codec is supported in "headset_head_unit" PA profile
(as mSBC"), it is supported also in "a2dp_sink" PA profile when "A2DP
SBC" codec is used and also in "a2dp_source" PA profile when "aptX-LL"
codec is used.

So adding a new API which sets codec on PA bluetooth card is not enough.

I would propose following API:

Add support for pulseaudio "sub-profiles". For every pulseaudio profile
it would be possible to register sub-profile and applications via
pulseaudio API would be able to change sub-profile of some PA card (if
currently selected PA profile would support it).

Plus adds a two new profiles:
* a2dp_source_with_backchannel
* a2dp_sink_with_backchannel

For music playback in most cases is useful only profiles without
backchannel to maximize bandwidth. And because A2DP codecs with
bachannel does not fit into HSP profiles it make sense to have them in
separate profile. In most cases A2DP profile with backchannel is the
best way for VOIP (as it has microphone recording support), so bluetooth
policy plugin would be extended to use also this profile for VOIP.

Sub-profiles for bluetooth PA card would be following:

* headset_audio_gateway
   - CVSD (hardware)
   - mSBC (software)
   - mSBC (hardware)
   ...
* headset_head_unit
   - same as in headset_audio_gateway
* a2dp_source
   - SBC-LQ
   - SBC-MQ
   - SBC-HQ
   ..,
   - faststream without backchannel
   - aptX
   - aptX-HD
   - aptX-LL without backannel
   - LDAC
   ...
* a2dp_sink
   - same as in a2dp_source
* a2dp_source_with_backchannel
   - faststream with backchannel
   - aptX-LL with backchannel
* a2dp_sink_with_backchannel
   - same as in a2dp_source_with_backchannel

So sub-profile would be one specific configuration of codec. In HSP/HFP
there would be two sub-profiles for every codec (one for software
encoding, one for hardware encoding). In A2DP it may be various. E.g.
for "SBC profiles" there would be one sub-profile for every SBC
configuration. For faststream codec there would be two, one with
backchannel, one without. Default sub-codec selection would be up to
the pulseaudio module. And applications (pactl / pavucontrol / ...)
would be able to change PA sub-profile in similar way how they can do it
for PA profiles.

Of course some sub-profiles does not have to be supported (e.g. mSBC in
hardware encoding) and in these cases pulseaudio would not announce
these unsupported sub-profiles.

What do you think about this my proposal?

Tanu, is this acceptable for you?

Basically it is needed only to add APIs for applications to:
* get current sub-profile of card
* get list of all sub-profiles for specific profile
* change sub-profile of card

I'm not saying how would API look like. I'm open for implementation
details... I can imagine that we can extend PA protocol or use messaging
API for it or anything else...


(*) - currently Linux kernel blocks this usage of mSBC HW encoding and
force userspace to do whole encoding at application level (in
pulseaudio).


I think your proposal looks good. I agree that we need new profiles for A2DP
with backchannel and your sub-profiles basically implement codec switching
(or codec parameter switching in some cases). Sub-profile switching could
b

Re: [pulseaudio-discuss] [PATCH v13 00/10] Bluetooth A2DP codecs

2019-12-14 Thread Georg Chini

On 14.12.19 19:15, Tanu Kaskinen wrote:

On Wed, 2019-12-11 at 15:44 +0100, Pali Rohár wrote:

Hello! Some of these patches are already reviewed. Can you include these
patches into pulseaudio master git branch?

You me this also on IRC, but at the moment you're not on the channel,
so I'm responding here: Georg knows better which patches are ready to
be merged than me, so I'll let Georg do the merging. I read a few
messages, and it seemed that there were still small issues left
unresolved.


As discussed briefly on IRC, the first two patches are good to merge.
Pali, it would be good if you could open a MR for them as our policy
now is that every patch has to go through gitlab.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] [PATCH v13 06/10] bluetooth: Add A2DP FastStream codec support

2019-12-07 Thread Georg Chini

On 07.12.19 18:49, Pali Rohár wrote:

On Saturday 07 December 2019 18:39:20 Georg Chini wrote:

Otherwise 44k1 could be chosen falsely here if
the headset
again sends both frequencies.

Remote side here send all supported frequencies. If there are more
frequencies we choose just one which we want to use and then send it to
remote side to inform which we have chosen. We must send exactly one
frequency to remote side.


But wasn't it the case, that if both frequencies are sent, 44k1 does not
work?

No, bug is different. Tested buggy headset supports both frequencies.
And if you negotiate 44.1kHz it works fine.

Bug is that headset returned in config buffer two frequences which is
invalid -- config buffer must contain only one frequency. Headset in
config buffer announce what is the final frequency used in audio stream
which is going to start transmitting. And by observation I figured out
that always when headset put both frequencies in config buffer it
starts transmitting audio stream at 48kHz.


Understood, so patch 6 looks good (apart from sometimes returning 0 in the
error case - but that's something general I already mentioned in the 
previous

patch).

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v13 06/10] bluetooth: Add A2DP FastStream codec support

2019-12-07 Thread Georg Chini

On 07.12.19 18:25, Pali Rohár wrote:

On Saturday 07 December 2019 18:15:38 Georg Chini wrote:

On 07.12.19 16:56, Pali Rohár wrote:

On Saturday 07 December 2019 16:44:20 Georg Chini wrote:

On 07.12.19 15:47, Pali Rohár wrote:

On Saturday 07 December 2019 15:37:15 Georg Chini wrote:

On 06.10.19 19:58, Pali Rohár wrote:

This patch provides support for FastStream codec in bluetooth A2DP profile.
FastStream codec is bi-directional, which means that it supports both music
playback and microphone voice at the same time.

FastStream codec is just SBC codec with fixed parameters. For playback are
used following parameters: 48.0kHz or 44.1kHz, Blocks 16, Sub-bands 8,
Joint Stereo, Loudness, Bitpool = 29 (data rate = 212kbps, packet size =
(71+1)*3 <= DM5 = 220, with 3 SBC frames). SBC frame size is 71 bytes, but
FastStream is zero-padded to the even size (72). For microphone are used
following SBC parameters: 16kHz, Mono, Blocks 16, Sub-bands 8, Loudness,
Bitpool = 32 (data rate = 72kbps, packet size = 72*3 <= DM5 = 220, with
3 SBC frames).

So FastStream codec is equivalent to SBC in Low Quality settings. But the
main benefit of FastStream codec is support for microphone voice channel
for audio calls. Compared to bluetooth HSP profile (with CVSD codec), it
provides better audio quality for both playback and recording.
---
 src/Makefile.am   |   2 +
 src/modules/bluetooth/a2dp-codec-faststream.c | 554 
++
 src/modules/bluetooth/a2dp-codec-util.c   |   4 +
 src/modules/bluetooth/meson.build |   1 +
 4 files changed, 561 insertions(+)
 create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c


...


+
+static uint8_t fill_preferred_configuration(const pa_sample_spec 
*default_sample_spec, const uint8_t *capabilities_buffer, uint8_t 
capabilities_size, uint8_t config_buffer[MAX_A2DP_CAPS_SIZE]) {
+a2dp_faststream_t *config = (a2dp_faststream_t *) config_buffer;
+const a2dp_faststream_t *capabilities = (const a2dp_faststream_t *) 
capabilities_buffer;
+int i;
+
+static const struct {
+uint32_t rate;
+uint8_t cap;
+} freq_table[] = {
+{ 44100U, FASTSTREAM_SINK_SAMPLING_FREQ_44100 },
+{ 48000U, FASTSTREAM_SINK_SAMPLING_FREQ_48000 }
+};
+
+if (capabilities_size != sizeof(*capabilities)) {
+pa_log_error("Invalid size of capabilities buffer");
+return 0;
+}
+
+pa_zero(*config);
+
+if (A2DP_GET_VENDOR_ID(capabilities->info) != FASTSTREAM_VENDOR_ID || 
A2DP_GET_CODEC_ID(capabilities->info) != FASTSTREAM_CODEC_ID) {
+pa_log_error("No supported vendor codec information");
+return 0;
+}
+
+config->info = A2DP_SET_VENDOR_ID_CODEC_ID(FASTSTREAM_VENDOR_ID, 
FASTSTREAM_CODEC_ID);
+
+/* Find the lowest freq that is at least as high as the requested sampling 
rate */
+for (i = 0; (unsigned) i < PA_ELEMENTSOF(freq_table); i++)
+if (freq_table[i].rate >= default_sample_spec->rate && 
(capabilities->sink_frequency & freq_table[i].cap)) {

If this is a "new" set of capabilities, do you not need to check that the
frequencies only
contain one of 44k1 or 48k?

No. Capabilities is set of supported features. Config is one specific
model of capabilities, one exact configuration. I tried to call all
variables consistency, so it is know if buffer contains either
"capabilities" or "config".
That's clear, but you said below (cut off in this mail) that the device 
sends a new

set of capabilities that must be checked in this function.



Here, in fill_preferred_configuration function, we get remote
capabilities (all supported features advertised by remote endpoint) and
we need create one specific configuration which is compatible with
advertised capabilities.


That's the point. If the remote device previously falsely announced 44k1 
and 48k
it might do the same thing here and you might end up trying to use 44k1 
which

as you say does not work if both frequencies are announced.




Otherwise 44k1 could be chosen falsely here if
the headset
again sends both frequencies.

Remote side here send all supported frequencies. If there are more
frequencies we choose just one which we want to use and then send it to
remote side to inform which we have chosen. We must send exactly one
frequency to remote side.

But wasn't it the case, that if both frequencies are sent, 44k1 does not 
work?

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v13 06/10] bluetooth: Add A2DP FastStream codec support

2019-12-07 Thread Georg Chini

On 07.12.19 16:56, Pali Rohár wrote:

On Saturday 07 December 2019 16:44:20 Georg Chini wrote:

On 07.12.19 15:47, Pali Rohár wrote:

On Saturday 07 December 2019 15:37:15 Georg Chini wrote:

On 06.10.19 19:58, Pali Rohár wrote:

This patch provides support for FastStream codec in bluetooth A2DP profile.
FastStream codec is bi-directional, which means that it supports both music
playback and microphone voice at the same time.

FastStream codec is just SBC codec with fixed parameters. For playback are
used following parameters: 48.0kHz or 44.1kHz, Blocks 16, Sub-bands 8,
Joint Stereo, Loudness, Bitpool = 29 (data rate = 212kbps, packet size =
(71+1)*3 <= DM5 = 220, with 3 SBC frames). SBC frame size is 71 bytes, but
FastStream is zero-padded to the even size (72). For microphone are used
following SBC parameters: 16kHz, Mono, Blocks 16, Sub-bands 8, Loudness,
Bitpool = 32 (data rate = 72kbps, packet size = 72*3 <= DM5 = 220, with
3 SBC frames).

So FastStream codec is equivalent to SBC in Low Quality settings. But the
main benefit of FastStream codec is support for microphone voice channel
for audio calls. Compared to bluetooth HSP profile (with CVSD codec), it
provides better audio quality for both playback and recording.
---
src/Makefile.am   |   2 +
src/modules/bluetooth/a2dp-codec-faststream.c | 554 
++
src/modules/bluetooth/a2dp-codec-util.c   |   4 +
src/modules/bluetooth/meson.build |   1 +
4 files changed, 561 insertions(+)
create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c


...

+static bool is_configuration_valid_common(const a2dp_faststream_t *config, 
uint8_t config_size) {
+uint8_t sink_frequency;
+
+if (config_size != sizeof(*config)) {
+pa_log_error("Invalid size of config buffer");
+return false;
+}
+
+if (A2DP_GET_VENDOR_ID(config->info) != FASTSTREAM_VENDOR_ID || 
A2DP_GET_CODEC_ID(config->info) != FASTSTREAM_CODEC_ID) {
+pa_log_error("Invalid vendor codec information in configuration");
+return false;
+}
+
+if (!(config->direction & FASTSTREAM_DIRECTION_SINK)) {
+pa_log_error("Invalid direction in configuration");
+return false;
+}
+
+sink_frequency = config->sink_frequency;
+
+/* Some headsets are buggy and set both 48 kHz and 44.1 kHz in
+ * the config. In such situation trying to send audio at 44.1 kHz
+ * results in choppy audio, so we have to assume that the headset
+ * actually wants 48 kHz audio. */
+if (sink_frequency == (FASTSTREAM_SINK_SAMPLING_FREQ_44100 | 
FASTSTREAM_SINK_SAMPLING_FREQ_48000))
+sink_frequency = FASTSTREAM_SINK_SAMPLING_FREQ_48000;
+
+if (sink_frequency != FASTSTREAM_SINK_SAMPLING_FREQ_44100 && 
sink_frequency != FASTSTREAM_SINK_SAMPLING_FREQ_48000) {
+pa_log_error("Invalid sink sampling frequency in configuration");
+return false;
+}
+
+return true;
+}

Why not simply

  if (config->sink_frequency & (FASTSTREAM_SINK_SAMPLING_FREQ_44100 | 
FASTSTREAM_SINK_SAMPLING_FREQ_48000))
   return true;

  return false;

This change suggested Tanu in email Message-ID: 
<4622e48b2c79eaab2486cdc43a5fdf430859345e.ca...@iki.fi>

Can't find the e-mail with that reference.

https://www.spinics.net/lists/pulse-audio/msg30932.html


Well, if he says so lets keep it, though I think the comment would be 
fully sufficient.






+
+static bool is_configuration_valid(const uint8_t *config_buffer, uint8_t 
config_size) {
+const a2dp_faststream_t *config = (const a2dp_faststream_t *) 
config_buffer;
+
+if (!is_configuration_valid_common(config, config_size))
+return false;
+
+if (config->direction & FASTSTREAM_DIRECTION_SOURCE) {
+pa_log_error("Invalid direction in configuration");
+return false;
+}
+
+return true;
+}
+
+static bool is_configuration_valid_mic(const uint8_t *config_buffer, uint8_t 
config_size) {
+const a2dp_faststream_t *config = (const a2dp_faststream_t *) 
config_buffer;
+
+if (!is_configuration_valid_common(config, config_size))
+return false;
+
+if (!(config->direction & FASTSTREAM_DIRECTION_SOURCE)) {
+pa_log_error("Invalid direction in configuration");
+return false;
+}
+
+if (config->source_frequency != FASTSTREAM_SOURCE_SAMPLING_FREQ_16000) {
+pa_log_error("Invalid source sampling frequency in configuration");
+return false;
+}
+
+return true;
+}
+
+static uint8_t fill_preferred_configuration(const pa_sample_spec 
*default_sample_spec, const uint8_t *capabilities_buffer, uint8_t 
capabilities_size, uint8_t config_buffer[MAX_A2DP_CAPS_SIZE]) {
+a2dp_faststream_t *config = (a2dp_faststream_t *) config_buffer;
+const a2dp_faststream_t *capabilities = 

Re: [pulseaudio-discuss] [PATCH v13 06/10] bluetooth: Add A2DP FastStream codec support

2019-12-07 Thread Georg Chini

On 07.12.19 15:47, Pali Rohár wrote:

On Saturday 07 December 2019 15:37:15 Georg Chini wrote:

On 06.10.19 19:58, Pali Rohár wrote:

This patch provides support for FastStream codec in bluetooth A2DP profile.
FastStream codec is bi-directional, which means that it supports both music
playback and microphone voice at the same time.

FastStream codec is just SBC codec with fixed parameters. For playback are
used following parameters: 48.0kHz or 44.1kHz, Blocks 16, Sub-bands 8,
Joint Stereo, Loudness, Bitpool = 29 (data rate = 212kbps, packet size =
(71+1)*3 <= DM5 = 220, with 3 SBC frames). SBC frame size is 71 bytes, but
FastStream is zero-padded to the even size (72). For microphone are used
following SBC parameters: 16kHz, Mono, Blocks 16, Sub-bands 8, Loudness,
Bitpool = 32 (data rate = 72kbps, packet size = 72*3 <= DM5 = 220, with
3 SBC frames).

So FastStream codec is equivalent to SBC in Low Quality settings. But the
main benefit of FastStream codec is support for microphone voice channel
for audio calls. Compared to bluetooth HSP profile (with CVSD codec), it
provides better audio quality for both playback and recording.
---
   src/Makefile.am   |   2 +
   src/modules/bluetooth/a2dp-codec-faststream.c | 554 
++
   src/modules/bluetooth/a2dp-codec-util.c   |   4 +
   src/modules/bluetooth/meson.build |   1 +
   4 files changed, 561 insertions(+)
   create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c


...

+static bool is_configuration_valid_common(const a2dp_faststream_t *config, 
uint8_t config_size) {
+uint8_t sink_frequency;
+
+if (config_size != sizeof(*config)) {
+pa_log_error("Invalid size of config buffer");
+return false;
+}
+
+if (A2DP_GET_VENDOR_ID(config->info) != FASTSTREAM_VENDOR_ID || 
A2DP_GET_CODEC_ID(config->info) != FASTSTREAM_CODEC_ID) {
+pa_log_error("Invalid vendor codec information in configuration");
+return false;
+}
+
+if (!(config->direction & FASTSTREAM_DIRECTION_SINK)) {
+pa_log_error("Invalid direction in configuration");
+return false;
+}
+
+sink_frequency = config->sink_frequency;
+
+/* Some headsets are buggy and set both 48 kHz and 44.1 kHz in
+ * the config. In such situation trying to send audio at 44.1 kHz
+ * results in choppy audio, so we have to assume that the headset
+ * actually wants 48 kHz audio. */
+if (sink_frequency == (FASTSTREAM_SINK_SAMPLING_FREQ_44100 | 
FASTSTREAM_SINK_SAMPLING_FREQ_48000))
+sink_frequency = FASTSTREAM_SINK_SAMPLING_FREQ_48000;
+
+if (sink_frequency != FASTSTREAM_SINK_SAMPLING_FREQ_44100 && 
sink_frequency != FASTSTREAM_SINK_SAMPLING_FREQ_48000) {
+pa_log_error("Invalid sink sampling frequency in configuration");
+return false;
+}
+
+return true;
+}

Why not simply

 if (config->sink_frequency & (FASTSTREAM_SINK_SAMPLING_FREQ_44100 | 
FASTSTREAM_SINK_SAMPLING_FREQ_48000))
  return true;

 return false;

This change suggested Tanu in email Message-ID: 
<4622e48b2c79eaab2486cdc43a5fdf430859345e.ca...@iki.fi>

Can't find the e-mail with that reference.



+
+static bool is_configuration_valid(const uint8_t *config_buffer, uint8_t 
config_size) {
+const a2dp_faststream_t *config = (const a2dp_faststream_t *) 
config_buffer;
+
+if (!is_configuration_valid_common(config, config_size))
+return false;
+
+if (config->direction & FASTSTREAM_DIRECTION_SOURCE) {
+pa_log_error("Invalid direction in configuration");
+return false;
+}
+
+return true;
+}
+
+static bool is_configuration_valid_mic(const uint8_t *config_buffer, uint8_t 
config_size) {
+const a2dp_faststream_t *config = (const a2dp_faststream_t *) 
config_buffer;
+
+if (!is_configuration_valid_common(config, config_size))
+return false;
+
+if (!(config->direction & FASTSTREAM_DIRECTION_SOURCE)) {
+pa_log_error("Invalid direction in configuration");
+return false;
+}
+
+if (config->source_frequency != FASTSTREAM_SOURCE_SAMPLING_FREQ_16000) {
+pa_log_error("Invalid source sampling frequency in configuration");
+return false;
+}
+
+return true;
+}
+
+static uint8_t fill_preferred_configuration(const pa_sample_spec 
*default_sample_spec, const uint8_t *capabilities_buffer, uint8_t 
capabilities_size, uint8_t config_buffer[MAX_A2DP_CAPS_SIZE]) {
+a2dp_faststream_t *config = (a2dp_faststream_t *) config_buffer;
+const a2dp_faststream_t *capabilities = (const a2dp_faststream_t *) 
capabilities_buffer;
+int i;
+
+static const struct {
+uint32_t rate;
+uint8_t cap;
+} freq_table[] = {
+{ 44100U, FASTSTREAM_SINK_SAMPLING_FREQ_44100 },
+{ 48000U, FASTSTREAM_SINK_SAM

Re: [pulseaudio-discuss] [PATCH v13 06/10] bluetooth: Add A2DP FastStream codec support

2019-12-07 Thread Georg Chini

On 06.10.19 19:58, Pali Rohár wrote:

This patch provides support for FastStream codec in bluetooth A2DP profile.
FastStream codec is bi-directional, which means that it supports both music
playback and microphone voice at the same time.

FastStream codec is just SBC codec with fixed parameters. For playback are
used following parameters: 48.0kHz or 44.1kHz, Blocks 16, Sub-bands 8,
Joint Stereo, Loudness, Bitpool = 29 (data rate = 212kbps, packet size =
(71+1)*3 <= DM5 = 220, with 3 SBC frames). SBC frame size is 71 bytes, but
FastStream is zero-padded to the even size (72). For microphone are used
following SBC parameters: 16kHz, Mono, Blocks 16, Sub-bands 8, Loudness,
Bitpool = 32 (data rate = 72kbps, packet size = 72*3 <= DM5 = 220, with
3 SBC frames).

So FastStream codec is equivalent to SBC in Low Quality settings. But the
main benefit of FastStream codec is support for microphone voice channel
for audio calls. Compared to bluetooth HSP profile (with CVSD codec), it
provides better audio quality for both playback and recording.
---
  src/Makefile.am   |   2 +
  src/modules/bluetooth/a2dp-codec-faststream.c | 554 ++
  src/modules/bluetooth/a2dp-codec-util.c   |   4 +
  src/modules/bluetooth/meson.build |   1 +
  4 files changed, 561 insertions(+)
  create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c


...

+static bool is_configuration_valid_common(const a2dp_faststream_t *config, 
uint8_t config_size) {
+uint8_t sink_frequency;
+
+if (config_size != sizeof(*config)) {
+pa_log_error("Invalid size of config buffer");
+return false;
+}
+
+if (A2DP_GET_VENDOR_ID(config->info) != FASTSTREAM_VENDOR_ID || 
A2DP_GET_CODEC_ID(config->info) != FASTSTREAM_CODEC_ID) {
+pa_log_error("Invalid vendor codec information in configuration");
+return false;
+}
+
+if (!(config->direction & FASTSTREAM_DIRECTION_SINK)) {
+pa_log_error("Invalid direction in configuration");
+return false;
+}
+
+sink_frequency = config->sink_frequency;
+
+/* Some headsets are buggy and set both 48 kHz and 44.1 kHz in
+ * the config. In such situation trying to send audio at 44.1 kHz
+ * results in choppy audio, so we have to assume that the headset
+ * actually wants 48 kHz audio. */
+if (sink_frequency == (FASTSTREAM_SINK_SAMPLING_FREQ_44100 | 
FASTSTREAM_SINK_SAMPLING_FREQ_48000))
+sink_frequency = FASTSTREAM_SINK_SAMPLING_FREQ_48000;
+
+if (sink_frequency != FASTSTREAM_SINK_SAMPLING_FREQ_44100 && 
sink_frequency != FASTSTREAM_SINK_SAMPLING_FREQ_48000) {
+pa_log_error("Invalid sink sampling frequency in configuration");
+return false;
+}
+
+return true;
+}


Why not simply

if (config->sink_frequency & (FASTSTREAM_SINK_SAMPLING_FREQ_44100 | 
FASTSTREAM_SINK_SAMPLING_FREQ_48000))
 return true;

return false;


+
+static bool is_configuration_valid(const uint8_t *config_buffer, uint8_t 
config_size) {
+const a2dp_faststream_t *config = (const a2dp_faststream_t *) 
config_buffer;
+
+if (!is_configuration_valid_common(config, config_size))
+return false;
+
+if (config->direction & FASTSTREAM_DIRECTION_SOURCE) {
+pa_log_error("Invalid direction in configuration");
+return false;
+}
+
+return true;
+}
+
+static bool is_configuration_valid_mic(const uint8_t *config_buffer, uint8_t 
config_size) {
+const a2dp_faststream_t *config = (const a2dp_faststream_t *) 
config_buffer;
+
+if (!is_configuration_valid_common(config, config_size))
+return false;
+
+if (!(config->direction & FASTSTREAM_DIRECTION_SOURCE)) {
+pa_log_error("Invalid direction in configuration");
+return false;
+}
+
+if (config->source_frequency != FASTSTREAM_SOURCE_SAMPLING_FREQ_16000) {
+pa_log_error("Invalid source sampling frequency in configuration");
+return false;
+}
+
+return true;
+}
+
+static uint8_t fill_preferred_configuration(const pa_sample_spec 
*default_sample_spec, const uint8_t *capabilities_buffer, uint8_t 
capabilities_size, uint8_t config_buffer[MAX_A2DP_CAPS_SIZE]) {
+a2dp_faststream_t *config = (a2dp_faststream_t *) config_buffer;
+const a2dp_faststream_t *capabilities = (const a2dp_faststream_t *) 
capabilities_buffer;
+int i;
+
+static const struct {
+uint32_t rate;
+uint8_t cap;
+} freq_table[] = {
+{ 44100U, FASTSTREAM_SINK_SAMPLING_FREQ_44100 },
+{ 48000U, FASTSTREAM_SINK_SAMPLING_FREQ_48000 }
+};
+
+if (capabilities_size != sizeof(*capabilities)) {
+pa_log_error("Invalid size of capabilities buffer");
+return 0;
+}
+
+pa_zero(*config);
+
+if (A2DP_GET_VENDOR_ID(capabilities->info) != FASTSTREAM_VENDOR_ID || 
A2DP_GET_CODEC_ID(capabilities->info) != FASTSTREAM_CODEC_ID) {
+pa_log_error("No supported vendor codec informatio

Re: [pulseaudio-discuss] [PATCH v13 05/10] bluetooth: Add A2DP aptX and aptX HD codecs support

2019-12-02 Thread Georg Chini

On 02.12.19 15:47, Tanu Kaskinen wrote:

On Mon, 2019-12-02 at 13:00 +0100, Pali Rohár wrote:

On Sunday 01 December 2019 12:24:07 Georg Chini wrote:

On 30.11.19 23:39, Pali Rohár wrote:

On Saturday 30 November 2019 22:43:47 Georg Chini wrote:

On 06.10.19 19:58, Pali Rohár wrote:

This patch provides support for aptX and aptX HD codecs in bluetooth A2DP
profile. It uses open source LGPLv2.1+ licensed libopenaptx library which
can be found at https://github.com/pali/libopenaptx.

aptX for s24 stereo samples provides fixed 6:1 compression ratio and
bitrate 352.8 kbit/s, aptX HD provides fixed 4:1 compression ratio and
bitrate 529.2 kbit/s.

According to soundexpert research, aptX codec used in bluetooth A2DP is no
better than SBC High Quality settings. And you cannot hear difference
between aptX and SBC High Quality, aptX is just a copper-less overpriced
audio cable.

aptX HD is high-bitrate version of aptX. It has clearly noticeable increase
in sound quality (not dramatic though taking into account the increase in
bitrate).

http://soundexpert.org/news/-/blogs/audio-quality-of-bluetooth-aptx

One general remark: I would consider passing the a2dp_codec as argument
to the API functions. This way you can avoid having to create one function
per codec variant. Instead you can use the vendor ID/codec ID or just the
codec name as a key to a "case" or "if" instruction to distinguish between
different codec variants. I think especially in the SBC case the code would
be better readable. In this patch you could avoid duplicating functions
if you can read the vendor and codec ID from the a2dp_codec instead of
hard coding them.

I do not think that passing codec structure into every function is a big
win. In your suggestion, instead of N functions (one for each codec) you
would have just one function with N if-then-else-else-else... branches,
one branch for each codec. Currently common parts for all codecs is
already in sub-function with suffix _common (so code is not duplicated).

I do not think it would produce less code, but the code would be
easier to read.
Now you have to check which codec variant uses which function,
then you have to check this function for the arguments of the
common function and then you can look what the common function
does.
With passing the codec that could be avoided: All (or at least most)
codec variants would use the same function

That is not fully truth. SBC XQ variant needs to check that remote side
supports configuration for SBC XQ. SBC LQ needs to check that remote
side supports configuration for SBC LQ.

If variants would be same, then one function for checking would be
enough. But they are variants of just because codecs are not same.


and you could directly
see what happens for each variant in this function. Effectively, multiple
functions would be replaced by if or case instructions as you already
said, but for me that would be the purpose of the change.

Maybe we should ask Tanu for an opinion? I can live with the current
approach but would prefer passing the codec.

Both approaches are (if implemented) correctly should provide equivalent
set of features. So there is no functionality lost when choosing either
my our your implementation variant.

So maybe Tanu (or somebody else) could give us some comments? If my
currently implemented variant of code API is OK or if Georg's variant
should be used and therefore changing existing code and code in my
patches to it...

I'm fine with either. I vote for keeping the current API, since that
means less work.


OK, so let's keep it.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v13 05/10] bluetooth: Add A2DP aptX and aptX HD codecs support

2019-12-01 Thread Georg Chini

On 30.11.19 23:39, Pali Rohár wrote:

On Saturday 30 November 2019 22:43:47 Georg Chini wrote:

On 06.10.19 19:58, Pali Rohár wrote:

This patch provides support for aptX and aptX HD codecs in bluetooth A2DP
profile. It uses open source LGPLv2.1+ licensed libopenaptx library which
can be found at https://github.com/pali/libopenaptx.

aptX for s24 stereo samples provides fixed 6:1 compression ratio and
bitrate 352.8 kbit/s, aptX HD provides fixed 4:1 compression ratio and
bitrate 529.2 kbit/s.

According to soundexpert research, aptX codec used in bluetooth A2DP is no
better than SBC High Quality settings. And you cannot hear difference
between aptX and SBC High Quality, aptX is just a copper-less overpriced
audio cable.

aptX HD is high-bitrate version of aptX. It has clearly noticeable increase
in sound quality (not dramatic though taking into account the increase in
bitrate).

http://soundexpert.org/news/-/blogs/audio-quality-of-bluetooth-aptx

One general remark: I would consider passing the a2dp_codec as argument
to the API functions. This way you can avoid having to create one function
per codec variant. Instead you can use the vendor ID/codec ID or just the
codec name as a key to a "case" or "if" instruction to distinguish between
different codec variants. I think especially in the SBC case the code would
be better readable. In this patch you could avoid duplicating functions
if you can read the vendor and codec ID from the a2dp_codec instead of
hard coding them.

I do not think that passing codec structure into every function is a big
win. In your suggestion, instead of N functions (one for each codec) you
would have just one function with N if-then-else-else-else... branches,
one branch for each codec. Currently common parts for all codecs is
already in sub-function with suffix _common (so code is not duplicated).


I do not think it would produce less code, but the code would be
easier to read.
Now you have to check which codec variant uses which function,
then you have to check this function for the arguments of the
common function and then you can look what the common function
does.
With passing the codec that could be avoided: All (or at least most)
codec variants would use the same function and you could directly
see what happens for each variant in this function. Effectively, multiple
functions would be replaced by if or case instructions as you already
said, but for me that would be the purpose of the change.

Maybe we should ask Tanu for an opinion? I can live with the current
approach but would prefer passing the codec.





diff --git a/src/Makefile.am b/src/Makefile.am
index b84c778cc..e317b7972 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2164,6 +2164,12 @@ libbluez5_util_la_SOURCES += 
modules/bluetooth/a2dp-codec-sbc.c
   libbluez5_util_la_LIBADD += $(SBC_LIBS)
   libbluez5_util_la_CFLAGS += $(SBC_CFLAGS)
+if HAVE_OPENAPTX
+libbluez5_util_la_SOURCES += modules/bluetooth/a2dp-codec-aptx.c
+libbluez5_util_la_CPPFLAGS += $(OPENAPTX_CPPFLAGS)
+libbluez5_util_la_LDFLAGS += $(OPENAPTX_LDFLAGS)
+endif
+
   module_bluez5_discover_la_SOURCES = 
modules/bluetooth/module-bluez5-discover.c
   module_bluez5_discover_la_LDFLAGS = $(MODULE_LDFLAGS)
   module_bluez5_discover_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) 
libbluez5-util.la

The part for the meson build system is missing.

Sorry, I do not understand meson build system deeply enough to write
needed rule for it (including searching & linking flags).

Can somebody help with this part?


I guess Arun can help here.





diff --git a/src/modules/bluetooth/a2dp-codec-aptx.c 
b/src/modules/bluetooth/a2dp-codec-aptx.c
new file mode 100644
index 0..2bd9e7652
--- /dev/null
+++ b/src/modules/bluetooth/a2dp-codec-aptx.c

...

+pa_log_error("Not suitable sample rate");
+return false;
+}
+}
+
+return true;
+}
+
+static uint8_t fill_preferred_configuration(const pa_sample_spec 
*default_sample_spec, const uint8_t *capabilities_buffer, uint8_t 
capabilities_size, uint8_t config_buffer[MAX_A2DP_CAPS_SIZE]) {

Return type should be size_t and function should return (size_t) -1 on
error.

No, it cannot. API expects that zero value is returned on error.


Then the API should be changed to expect a negative value on error 
because this is

the convention in PA (unless there is a very good reason not to do so).




Also maximal size of A2DP cap buffer is 255 bytes, so it does not make
sense to use bigger types. It is A2DP specific.


I think because the function returns a size, size_t is the correct type 
for the

return value, even if the maximum is 255, but that's not something I have
a strong opinion about.





+a2dp_aptx_t *config = (a2dp_aptx_t *) config_buffer;
+const a2dp_aptx_t *capabilities = (const a2dp_aptx_t *) 
capabilities_buffer;
+
+if (capabilities_size != sizeof(*capabilities)) {
+pa_log_error("Invalid size

Re: [pulseaudio-discuss] [PATCH v13 05/10] bluetooth: Add A2DP aptX and aptX HD codecs support

2019-11-30 Thread Georg Chini

On 06.10.19 19:58, Pali Rohár wrote:

This patch provides support for aptX and aptX HD codecs in bluetooth A2DP
profile. It uses open source LGPLv2.1+ licensed libopenaptx library which
can be found at https://github.com/pali/libopenaptx.

aptX for s24 stereo samples provides fixed 6:1 compression ratio and
bitrate 352.8 kbit/s, aptX HD provides fixed 4:1 compression ratio and
bitrate 529.2 kbit/s.

According to soundexpert research, aptX codec used in bluetooth A2DP is no
better than SBC High Quality settings. And you cannot hear difference
between aptX and SBC High Quality, aptX is just a copper-less overpriced
audio cable.

aptX HD is high-bitrate version of aptX. It has clearly noticeable increase
in sound quality (not dramatic though taking into account the increase in
bitrate).

http://soundexpert.org/news/-/blogs/audio-quality-of-bluetooth-aptx


One general remark: I would consider passing the a2dp_codec as argument
to the API functions. This way you can avoid having to create one function
per codec variant. Instead you can use the vendor ID/codec ID or just the
codec name as a key to a "case" or "if" instruction to distinguish between
different codec variants. I think especially in the SBC case the code would
be better readable. In this patch you could avoid duplicating functions
if you can read the vendor and codec ID from the a2dp_codec instead of
hard coding them.



---
  configure.ac|  36 +++
  src/Makefile.am |   6 +
  src/modules/bluetooth/a2dp-codec-aptx.c | 479 
  src/modules/bluetooth/a2dp-codec-util.c |   8 +
  4 files changed, 529 insertions(+)
  create mode 100644 src/modules/bluetooth/a2dp-codec-aptx.c

diff --git a/configure.ac b/configure.ac
index 8278353d4..26c625a59 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1118,6 +1118,40 @@ AC_SUBST(HAVE_BLUEZ_5_NATIVE_HEADSET)
  AM_CONDITIONAL([HAVE_BLUEZ_5_NATIVE_HEADSET], [test 
"x$HAVE_BLUEZ_5_NATIVE_HEADSET" = x1])
  AS_IF([test "x$HAVE_BLUEZ_5_NATIVE_HEADSET" = "x1"], 
AC_DEFINE([HAVE_BLUEZ_5_NATIVE_HEADSET], 1, [Bluez 5 native headset backend enabled]))
  
+ Bluetooth A2DP aptX codec (optional) ###

+
+AC_ARG_ENABLE([aptx],
+AS_HELP_STRING([--disable-aptx],[Disable optional bluetooth A2DP aptX and 
aptX HD codecs support (via libopenaptx)]))
+AC_ARG_VAR([OPENAPTX_CPPFLAGS], [C preprocessor flags for openaptx])
+AC_ARG_VAR([OPENAPTX_LDFLAGS], [linker flags for openaptx])
+
+CPPFLAGS_SAVE="$CPPFLAGS"
+LDFLAGS_SAVE="$LDFLAGS"
+LIBS_SAVE="$LIBS"
+
+CPPFLAGS="$CPPFLAGS $OPENAPTX_CPPFLAGS"
+LDFLAGS="$LDFLAGS $OPENAPTX_LDFLAGS"
+
+AS_IF([test "x$HAVE_BLUEZ_5" = "x1" && test "x$enable_aptx" != "xno"],
+[AC_CHECK_HEADER([openaptx.h],
+[AC_SEARCH_LIBS([aptx_init], [openaptx],
+[HAVE_OPENAPTX=1; AS_IF([test "x$ac_cv_search_aptx_init" != "xnone 
required"], [OPENAPTX_LDFLAGS="$OPENAPTX_LDFLAGS $ac_cv_search_aptx_init"])],
+[HAVE_OPENAPTX=0])],
+[HAVE_OPENAPTX=0])])
+
+CPPFLAGS="$CPPFLAGS_SAVE"
+LDFLAGS="$LDFLAGS_SAVE"
+LIBS="$LIBS_SAVE"
+
+AS_IF([test "x$HAVE_BLUEZ_5" = "x1" && test "x$enable_aptx" = "xyes" && test 
"x$HAVE_OPENAPTX" = "x0"],
+[AC_MSG_ERROR([*** libopenaptx from https://github.com/pali/libopenaptx 
not found])])
+
+AC_SUBST(OPENAPTX_CPPFLAGS)
+AC_SUBST(OPENAPTX_LDFLAGS)
+AC_SUBST(HAVE_OPENAPTX)
+AM_CONDITIONAL([HAVE_OPENAPTX], [test "x$HAVE_OPENAPTX" = "x1"])
+AS_IF([test "x$HAVE_OPENAPTX" = "x1"], AC_DEFINE([HAVE_OPENAPTX], 1, [Have 
openaptx codec library]))
+
   UDEV support (optional) 
  
  AC_ARG_ENABLE([udev],

@@ -1603,6 +1637,7 @@ AS_IF([test "x$HAVE_SYSTEMD_JOURNAL" = "x1"], 
ENABLE_SYSTEMD_JOURNAL=yes, ENABLE
  AS_IF([test "x$HAVE_BLUEZ_5" = "x1"], ENABLE_BLUEZ_5=yes, ENABLE_BLUEZ_5=no)
  AS_IF([test "x$HAVE_BLUEZ_5_OFONO_HEADSET" = "x1"], 
ENABLE_BLUEZ_5_OFONO_HEADSET=yes, ENABLE_BLUEZ_5_OFONO_HEADSET=no)
  AS_IF([test "x$HAVE_BLUEZ_5_NATIVE_HEADSET" = "x1"], 
ENABLE_BLUEZ_5_NATIVE_HEADSET=yes, ENABLE_BLUEZ_5_NATIVE_HEADSET=no)
+AS_IF([test "x$HAVE_OPENAPTX" = "x1"], ENABLE_APTX=yes, ENABLE_APTX=no)
  AS_IF([test "x$HAVE_HAL_COMPAT" = "x1"], ENABLE_HAL_COMPAT=yes, 
ENABLE_HAL_COMPAT=no)
  AS_IF([test "x$HAVE_TCPWRAP" = "x1"], ENABLE_TCPWRAP=yes, ENABLE_TCPWRAP=no)
  AS_IF([test "x$HAVE_LIBSAMPLERATE" = "x1"], ENABLE_LIBSAMPLERATE="yes 
(DEPRECATED)", ENABLE_LIBSAMPLERATE=no)
@@ -1661,6 +1696,7 @@ echo "
Enable BlueZ 5:  ${ENABLE_BLUEZ_5}
  Enable ofono headsets: ${ENABLE_BLUEZ_5_OFONO_HEADSET}
  Enable native headsets:${ENABLE_BLUEZ_5_NATIVE_HEADSET}
+Enable aptX+aptXHD codecs: ${ENABLE_APTX}
  Enable udev:   ${ENABLE_UDEV}
Enable HAL->udev compat: ${ENABLE_HAL_COMPAT}
  Enable systemd
diff --git a/src/Makefile.am b/src/Makefile.am
index b84c778cc..e317b7972 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2164,6 +2164,12 @@ libbluez5_util_la_SOURCES += 
modules/bluetooth/a2dp

Re: [pulseaudio-discuss] [PATCH v13 04/10] bluetooth: Set initial A2DP profile which bluez already activated

2019-11-25 Thread Georg Chini

On 16.11.19 17:12, Georg Chini wrote:

On 06.10.19 19:58, Pali Rohár wrote:

Bluez and remote device decide which A2DP codec would use. Use this
selected A2DP codec as initial profile in pulseaudio.

In most cases it is either last used codec or codec with higher 
priority by

defined by remote device.

To detect which A2DP profile was activated by bluez, look at bluez
transport state.
---
  src/modules/bluetooth/module-bluez5-device.c | 66 
+++-

  1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/src/modules/bluetooth/module-bluez5-device.c 
b/src/modules/bluetooth/module-bluez5-device.c

index fb77afaad..9afd1dbd1 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -1993,6 +1993,70 @@ static int uuid_to_profile(const char *uuid, 
pa_bluetooth_profile_t *_r) {

  return 0;
  }
  +static void choose_initial_profile(struct userdata *u) {
+    struct pa_bluetooth_transport *transport;
+    pa_card_profile *iter_profile;
+    pa_card_profile *profile;
+    void *state;
+
+    pa_log_debug("Looking for A2DP profile which has active bluez 
transport for card %s", u->card->name);

+
+    profile = NULL;
+
+    /* First try to find the best A2DP profile with transport in 
playing state */

+    PA_HASHMAP_FOREACH(iter_profile, u->card->profiles, state) {
+    transport = u->device->transports[*(pa_bluetooth_profile_t 
*)PA_CARD_PROFILE_DATA(iter_profile)];

+
+    /* Ignore profiles without active bluez transport in playing 
state */
+    if (!transport || transport->state != 
PA_BLUETOOTH_TRANSPORT_STATE_PLAYING)

+    continue;
+
+    /* Ignore non-A2DP profiles */
+    if (!pa_startswith(iter_profile->name, "a2dp_"))
+    continue;
+
+    pa_log_debug("%s has active bluez transport in playing 
state", iter_profile->name);

+
+    if (!profile || iter_profile->priority > profile->priority)
+    profile = iter_profile;
+    }


As also discussed via IRC could you please verify that the first 
iteration is needed at all?
I could not find any place where the transport can be set to playing 
state before the card
is put. If this iteration is not needed, patch 4 can be dropped and 
choose_initial_profile()

can be introduced in patch 9 using only the second iteration.


+
+    /* Second if there is no profile A2DP profile with transport in 
playing state, look at active transports */

+    if (!profile) {
+    PA_HASHMAP_FOREACH(iter_profile, u->card->profiles, state) {
+    transport = 
u->device->transports[*(pa_bluetooth_profile_t 
*)PA_CARD_PROFILE_DATA(iter_profile)];

+
+    /* Ignore profiles without active bluez transport */
+    if (!transport || transport->state == 
PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED)

+    continue;
+
+    /* Ignore non-A2DP profiles */
+    if (!pa_startswith(iter_profile->name, "a2dp_"))
+    continue;
+
+    pa_log_debug("%s has active bluez transport", 
iter_profile->name);

+
+    if (!profile || iter_profile->priority > profile->priority)
+    profile = iter_profile;
+    }
+    }


As discussed on IRC, please move the second iteration to patch 9 because
it is currently not needed.


+
+    /* When there is no active A2DP bluez transport, fallback to 
core pulseaudio function for choosing initial profile */

+    if (!profile) {
+    pa_log_debug("No A2DP profile with bluez active transport 
was found for card %s", u->card->name);

+    pa_card_choose_initial_profile(u->card);
+    return;
+    }
+
+    /* Do same job as pa_card_choose_initial_profile() */
+    pa_log_info("Setting initial A2DP profile '%s' for card %s", 
profile->name, u->card->name);

+    u->card->active_profile = profile;
+    u->card->save_profile = false;
+
+    /* Let policy modules override the default. */
+ 
pa_hook_fire(&u->card->core->hooks[PA_CORE_HOOK_CARD_CHOOSE_INITIAL_PROFILE], 
u->card);

+}
+
  /* Run from main thread */
  static int add_card(struct userdata *u) {
  const pa_bluetooth_device *d;
@@ -2063,7 +2127,7 @@ static int add_card(struct userdata *u) {
    u->card->userdata = u;
  u->card->set_profile = set_profile_cb;
-    pa_card_choose_initial_profile(u->card);
+    choose_initial_profile(u);
  pa_card_put(u->card);
    p = PA_CARD_PROFILE_DATA(u->card->active_profile);


Otherwise looks good.



___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v13 04/10] bluetooth: Set initial A2DP profile which bluez already activated

2019-11-16 Thread Georg Chini

On 06.10.19 19:58, Pali Rohár wrote:

Bluez and remote device decide which A2DP codec would use. Use this
selected A2DP codec as initial profile in pulseaudio.

In most cases it is either last used codec or codec with higher priority by
defined by remote device.

To detect which A2DP profile was activated by bluez, look at bluez
transport state.
---
  src/modules/bluetooth/module-bluez5-device.c | 66 +++-
  1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/src/modules/bluetooth/module-bluez5-device.c 
b/src/modules/bluetooth/module-bluez5-device.c
index fb77afaad..9afd1dbd1 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -1993,6 +1993,70 @@ static int uuid_to_profile(const char *uuid, 
pa_bluetooth_profile_t *_r) {
  return 0;
  }
  
+static void choose_initial_profile(struct userdata *u) {

+struct pa_bluetooth_transport *transport;
+pa_card_profile *iter_profile;
+pa_card_profile *profile;
+void *state;
+
+pa_log_debug("Looking for A2DP profile which has active bluez transport for card 
%s", u->card->name);
+
+profile = NULL;
+
+/* First try to find the best A2DP profile with transport in playing state 
*/
+PA_HASHMAP_FOREACH(iter_profile, u->card->profiles, state) {
+transport = u->device->transports[*(pa_bluetooth_profile_t 
*)PA_CARD_PROFILE_DATA(iter_profile)];
+
+/* Ignore profiles without active bluez transport in playing state */
+if (!transport || transport->state != 
PA_BLUETOOTH_TRANSPORT_STATE_PLAYING)
+continue;
+
+/* Ignore non-A2DP profiles */
+if (!pa_startswith(iter_profile->name, "a2dp_"))
+continue;
+
+pa_log_debug("%s has active bluez transport in playing state", 
iter_profile->name);
+
+if (!profile || iter_profile->priority > profile->priority)
+profile = iter_profile;
+}
+
+/* Second if there is no profile A2DP profile with transport in playing 
state, look at active transports */
+if (!profile) {
+PA_HASHMAP_FOREACH(iter_profile, u->card->profiles, state) {
+transport = u->device->transports[*(pa_bluetooth_profile_t 
*)PA_CARD_PROFILE_DATA(iter_profile)];
+
+/* Ignore profiles without active bluez transport */
+if (!transport || transport->state == 
PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED)
+continue;
+
+/* Ignore non-A2DP profiles */
+if (!pa_startswith(iter_profile->name, "a2dp_"))
+continue;
+
+pa_log_debug("%s has active bluez transport", iter_profile->name);
+
+if (!profile || iter_profile->priority > profile->priority)
+profile = iter_profile;
+}
+}


As discussed on IRC, please move the second iteration to patch 9 because
it is currently not needed.


+
+/* When there is no active A2DP bluez transport, fallback to core 
pulseaudio function for choosing initial profile */
+if (!profile) {
+pa_log_debug("No A2DP profile with bluez active transport was found for card 
%s", u->card->name);
+pa_card_choose_initial_profile(u->card);
+return;
+}
+
+/* Do same job as pa_card_choose_initial_profile() */
+pa_log_info("Setting initial A2DP profile '%s' for card %s", profile->name, 
u->card->name);
+u->card->active_profile = profile;
+u->card->save_profile = false;
+
+/* Let policy modules override the default. */
+pa_hook_fire(&u->card->core->hooks[PA_CORE_HOOK_CARD_CHOOSE_INITIAL_PROFILE], 
u->card);
+}
+
  /* Run from main thread */
  static int add_card(struct userdata *u) {
  const pa_bluetooth_device *d;
@@ -2063,7 +2127,7 @@ static int add_card(struct userdata *u) {
  
  u->card->userdata = u;

  u->card->set_profile = set_profile_cb;
-pa_card_choose_initial_profile(u->card);
+choose_initial_profile(u);
  pa_card_put(u->card);
  
  p = PA_CARD_PROFILE_DATA(u->card->active_profile);


Otherwise looks good.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v13 01/10] bluetooth: Implement reading SO_TIMESTAMP for A2DP source

2019-11-10 Thread Georg Chini

On 10.11.19 11:09, Pali Rohár wrote:

On Sunday 10 November 2019 11:03:25 Georg Chini wrote:

On 10.11.19 09:44, Pali Rohár wrote:


Otherwise looks good, though I wonder if the warning is really necessary.

It was there before, so I have not deleted it. It is also there for SCO
socket.

I know, but I am actually for dropping the warning in both cases.
Given the precision of the smoother, it should not matter much
if the current time or the  time when the packet was received
are used in the calculations.

Yes.


Also, if SO_TIMESTAMP is not
supported, we can't do anything about it and we get a warning
when the socket is created.

That is true, it is only warning.

But I think it has a value for debugging purposes. It could be possible
that today or future there code can work quite differently and if user
provide logs with above warning it could be easier to debug problems...



What I mean is that we get a warning earlier, when the socket is
created in setup_stream(). So the warning here only adds additional
information if the platform pretends to support SO_TIMESTAMP
but does not in fact do so, which I think is not very likely. But I am
also OK with leaving it in if you prefer.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v13 01/10] bluetooth: Implement reading SO_TIMESTAMP for A2DP source

2019-11-10 Thread Georg Chini

On 10.11.19 09:44, Pali Rohár wrote:

On Saturday 09 November 2019 12:34:02 Georg Chini wrote:

On 06.10.19 19:58, Pali Rohár wrote:

---
   src/modules/bluetooth/module-bluez5-device.c | 33 
++--
   1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/src/modules/bluetooth/module-bluez5-device.c 
b/src/modules/bluetooth/module-bluez5-device.c
index cff1cd6f2..9a81f4c69 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -548,13 +548,29 @@ static int a2dp_process_push(struct userdata *u) {
   a2dp_prepare_decoder_buffer(u);
   for (;;) {
+uint8_t aux[1024];
+struct iovec iov;
+struct cmsghdr *cm;
+struct msghdr m;
   bool found_tstamp = false;
   pa_usec_t tstamp;
   uint8_t *ptr;
   ssize_t l;
   size_t processed;
-l = pa_read(u->stream_fd, u->decoder_buffer, u->decoder_buffer_size, 
&u->stream_write_type);
+pa_zero(m);
+pa_zero(aux);
+pa_zero(iov);
+
+m.msg_iov = &iov;
+m.msg_iovlen = 1;
+m.msg_control = aux;
+m.msg_controllen = sizeof(aux);
+
+iov.iov_base = u->decoder_buffer;
+iov.iov_len = u->decoder_buffer_size;
+
+l = recvmsg(u->stream_fd, &m, 0);
   if (l <= 0) {
@@ -574,8 +590,21 @@ static int a2dp_process_push(struct userdata *u) {
   pa_assert((size_t) l <= u->decoder_buffer_size);
   /* TODO: get timestamp from rtp */

You should remove the TODO from the comment.

Why? This comment has nothing to do with patch in this email.

This patch does *not* implement reading timestamp from RTP packet. It
reads SO_TIMESTAMP from socket added by kernel.


I thought this referred to reading the SO_TIMESTAMP, sorry.




+
+for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm)) {
+if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SO_TIMESTAMP) 
{
+struct timeval *tv = (struct timeval*) CMSG_DATA(cm);
+pa_rtclock_from_wallclock(tv);
+tstamp = pa_timeval_load(tv);
+found_tstamp = true;
+break;
+}
+}
+
   if (!found_tstamp) {
-/* pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() 
data!"); */
+PA_ONCE_BEGIN {
+pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() 
data!");
+} PA_ONCE_END;
   tstamp = pa_rtclock_now();
   }

Otherwise looks good, though I wonder if the warning is really necessary.

It was there before, so I have not deleted it. It is also there for SCO
socket.


I know, but I am actually for dropping the warning in both cases.
Given the precision of the smoother, it should not matter much
if the current time or the  time when the packet was received
are used in the calculations. Also, if SO_TIMESTAMP is not
supported, we can't do anything about it and we get a warning
when the socket is created.




It should run fine even when system time is used.

Maybe kernel can for some reason do not add it? I do not know.


___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v13 03/10] bluetooth: Parse remote timestamp from A2DP RTP packets when available

2019-11-09 Thread Georg Chini

On 06.10.19 19:58, Pali Rohár wrote:

Some A2DP codecs (e.g. SBC or aptX-HD) use RTP packets. For sources use
timestamps from RTP packets to calculate read index and therefore remote
timestamp for synchronization.
---
  src/modules/bluetooth/a2dp-codec-api.h   |  4 ++--
  src/modules/bluetooth/a2dp-codec-sbc.c   |  3 ++-
  src/modules/bluetooth/module-bluez5-device.c | 14 +++---
  3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/src/modules/bluetooth/a2dp-codec-api.h 
b/src/modules/bluetooth/a2dp-codec-api.h
index a3123f4ca..1fd8e81d0 100644
--- a/src/modules/bluetooth/a2dp-codec-api.h
+++ b/src/modules/bluetooth/a2dp-codec-api.h
@@ -91,8 +91,8 @@ typedef struct pa_a2dp_codec {
  size_t (*encode_buffer)(void *codec_info, uint32_t timestamp, const 
uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t 
output_size, size_t *processed);
  /* Decode input_buffer of input_size to output_buffer of output_size,
   * returns size of filled ouput_buffer and set processed to size of
- * processed input_buffer */
-size_t (*decode_buffer)(void *codec_info, const uint8_t *input_buffer, 
size_t input_size, uint8_t *output_buffer, size_t output_size, size_t 
*processed);
+ * processed input_buffer and set timestamp */
+size_t (*decode_buffer)(void *codec_info, uint32_t *timestamp, const 
uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t 
output_size, size_t *processed);
  } pa_a2dp_codec;
  
  #endif

diff --git a/src/modules/bluetooth/a2dp-codec-sbc.c 
b/src/modules/bluetooth/a2dp-codec-sbc.c
index 89c647fbe..733c1a9ab 100644
--- a/src/modules/bluetooth/a2dp-codec-sbc.c
+++ b/src/modules/bluetooth/a2dp-codec-sbc.c
@@ -597,7 +597,7 @@ static size_t encode_buffer(void *codec_info, uint32_t 
timestamp, const uint8_t
  return d - output_buffer;
  }
  
-static size_t decode_buffer(void *codec_info, const uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size, size_t *processed) {

+static size_t decode_buffer(void *codec_info, uint32_t *timestamp, const 
uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t 
output_size, size_t *processed) {
  struct sbc_info *sbc_info = (struct sbc_info *) codec_info;
  
  struct rtp_header *header;

@@ -657,6 +657,7 @@ static size_t decode_buffer(void *codec_info, const uint8_t 
*input_buffer, size_
  frame_count--;
  }
  
+*timestamp = ntohl(header->timestamp);

  *processed = p - input_buffer;
  return d - output_buffer;
  }
diff --git a/src/modules/bluetooth/module-bluez5-device.c 
b/src/modules/bluetooth/module-bluez5-device.c
index 9da5d1ac3..fb77afaad 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -556,6 +556,7 @@ static int a2dp_process_push(struct userdata *u) {
  struct msghdr m;
  bool found_tstamp = false;
  pa_usec_t tstamp;
+uint32_t timestamp;
  uint8_t *ptr;
  ssize_t l;
  size_t processed;
@@ -591,8 +592,6 @@ static int a2dp_process_push(struct userdata *u) {
  
  pa_assert((size_t) l <= u->decoder_buffer_size);
  
-/* TODO: get timestamp from rtp */

-
  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm)) {
  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == 
SO_TIMESTAMP) {
  struct timeval *tv = (struct timeval*) CMSG_DATA(cm);
@@ -613,7 +612,8 @@ static int a2dp_process_push(struct userdata *u) {
  ptr = pa_memblock_acquire(memchunk.memblock);
  memchunk.length = pa_memblock_get_length(memchunk.memblock);
  
-memchunk.length = u->a2dp_codec->decode_buffer(u->decoder_info, u->decoder_buffer, l, ptr, memchunk.length, &processed);

+timestamp = 0; /* Decoder does not have to fill RTP timestamp */
+memchunk.length = u->a2dp_codec->decode_buffer(u->decoder_info, ×tamp, 
u->decoder_buffer, l, ptr, memchunk.length, &processed);
  
  pa_memblock_release(memchunk.memblock);
  
@@ -623,6 +623,14 @@ static int a2dp_process_push(struct userdata *u) {

  break;
  }
  
+/* Some codecs may provide RTP timestamp, so use it to update read_index for calculation of remote tstamp */

+if (timestamp) {
+/* RTP timestamp is only 32bit and may overflow, avoid it by 
calculating high 32bits from the last read_index */
+size_t frame_size = pa_frame_size(&u->decoder_sample_spec);
+uint64_t timestamp_hi = (u->read_index / frame_size) & 
0xULL;
+u->read_index = (timestamp_hi | timestamp) * frame_size;
+}
+
  u->read_index += (uint64_t) memchunk.length;
  pa_smoother_put(u->read_smoother, tstamp, pa_bytes_to_usec(u->read_index, 
&u->decoder_sample_spec));
  pa_smoother_resume(u->read_smoother, tstamp, true);


This patch has three issues:

1) According to the

Re: [pulseaudio-discuss] [PATCH v13 02/10] bluetooth: Print SO_TIMESTAMP warning for SCO source only once

2019-11-09 Thread Georg Chini

On 06.10.19 19:58, Pali Rohár wrote:

---
  src/modules/bluetooth/module-bluez5-device.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/modules/bluetooth/module-bluez5-device.c 
b/src/modules/bluetooth/module-bluez5-device.c
index 9a81f4c69..9da5d1ac3 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -395,7 +395,9 @@ static int sco_process_push(struct userdata *u) {
  }
  
  if (!found_tstamp) {

-pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() 
data!");
+PA_ONCE_BEGIN {
+pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() 
data!");
+} PA_ONCE_END;
  tstamp = pa_rtclock_now();
  }
  


Looks good, but the same comment about the warning.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v13 01/10] bluetooth: Implement reading SO_TIMESTAMP for A2DP source

2019-11-09 Thread Georg Chini

On 06.10.19 19:58, Pali Rohár wrote:

---
  src/modules/bluetooth/module-bluez5-device.c | 33 ++--
  1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/src/modules/bluetooth/module-bluez5-device.c 
b/src/modules/bluetooth/module-bluez5-device.c
index cff1cd6f2..9a81f4c69 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -548,13 +548,29 @@ static int a2dp_process_push(struct userdata *u) {
  a2dp_prepare_decoder_buffer(u);
  
  for (;;) {

+uint8_t aux[1024];
+struct iovec iov;
+struct cmsghdr *cm;
+struct msghdr m;
  bool found_tstamp = false;
  pa_usec_t tstamp;
  uint8_t *ptr;
  ssize_t l;
  size_t processed;
  
-l = pa_read(u->stream_fd, u->decoder_buffer, u->decoder_buffer_size, &u->stream_write_type);

+pa_zero(m);
+pa_zero(aux);
+pa_zero(iov);
+
+m.msg_iov = &iov;
+m.msg_iovlen = 1;
+m.msg_control = aux;
+m.msg_controllen = sizeof(aux);
+
+iov.iov_base = u->decoder_buffer;
+iov.iov_len = u->decoder_buffer_size;
+
+l = recvmsg(u->stream_fd, &m, 0);
  
  if (l <= 0) {
  
@@ -574,8 +590,21 @@ static int a2dp_process_push(struct userdata *u) {

  pa_assert((size_t) l <= u->decoder_buffer_size);
  
  /* TODO: get timestamp from rtp */


You should remove the TODO from the comment.



+
+for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm)) {
+if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SO_TIMESTAMP) 
{
+struct timeval *tv = (struct timeval*) CMSG_DATA(cm);
+pa_rtclock_from_wallclock(tv);
+tstamp = pa_timeval_load(tv);
+found_tstamp = true;
+break;
+}
+}
+
  if (!found_tstamp) {
-/* pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() 
data!"); */
+PA_ONCE_BEGIN {
+pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() 
data!");
+} PA_ONCE_END;
  tstamp = pa_rtclock_now();
  }
  


Otherwise looks good, though I wonder if the warning is really 
necessary. It should

run fine even when system time is used.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] Early steps for an investigation (stuttering)

2019-11-01 Thread Georg Chini

On 01.11.19 16:28, ebla...@libero.it wrote:

My laptop suffers from audio stuttering (it's been a while, now) but
I'm not very sure about the root reason and so I'm here. OS is LMDE 3
x64 (Debian Stretch based) with latest updates, it ships with
pulseaudio 10.0.
Hardware is based on an intel i5 with integrated audio
device (I can provide further details if needed) but also an external
USB card, suffering the same audio issue.
Now, the issue itself is not
easy to reproduce, as it is randomly appearing but it is an audio
stuttering, it lasts some 200 ms of repeated sound, happening (about)
every ten minutes, it is very annoying. In the last few days I played
youtube videos using firefox (stuttering appears) and played a Windows
game using wine (stuttering appears). Further, I can tweak a bit mpv
and deadbeef: well, when using pulseaudio output both stutter, but if I
forward output directly to alsa driver then I have no stuttering
anymore.
So, can I say pulseaudio is causing my issue? And if I can,
should I fix this by tweaking pulseaudio settings? Or should I first
update pulseaudio perhaps?

Elio


I would recommend upgrading to 13.0. Also you could try
to load module-udev-detect with tsched=0. Do you get any
log messages when the stuttering appears?

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v3 0/8] Change the bool sink_save to char *preferred_sink

2019-08-23 Thread Georg Chini

On 18.08.19 07:32, Hui Wang wrote:

In the V3, I addressed all Tanu's and Georg's comments:
0002-xxx.patch:
remove the pa_subscription_post() in the pa_sink_input_set_preferred_sink()

0003-xxx.patch:
Add the check of sink_input->sink->card in the subscribe_callback()

0004-xxx.patch:
Initialize the varible old_sink_is_unavailable
Add the check of core->default_sink == NULL || 
core->default_sink->unlink_requested
in the pa_sink_move_streams_to_default_sink()

0007-xxx.patch:
Move the calling of pa_sink_move_streams_to_default_sink() after the
pa_core_update_default_sink() in the pa_sink_unlink()
Add shutdown check in the pa_sink_move_streams_to_default_sink()
Change the logging message in the pa_sink_move_streams_to_default_sink()
Remove the sink and sink_input parts in the module-rescue-streams.c



This is based on Tanu's design:
https://lists.freedesktop.org/archives/pulseaudio-discuss/2018-October/030531.html

And this is only for sink-input and sink, not for source-output and source.

In the V2, I addressed all comments of V1 and split the big patch into small 
patches
as suggested by Tanu. It will be easy to review in the future.


Thanks for the updated patches. I will be on vacation starting end of 
next week,
so I will not find the time for a review before end of September. Is it 
possible

that you open a merge request on Gitlab for this?
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/

If not, I will open the merge request for you once the review is complete
because we changed our policy so that all changes have to go through a
merge request.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] Changing Volume on Streams ( not Sinks )

2019-07-29 Thread Georg Chini

On 28.07.19 19:44, Brian Bulkowski wrote:
I posted yesterday, twice, about how the "stream get sink id" was 
going to solve my problems.


In 10.0 ( the distro version on Debian Stretch on the Raspberry PI ), 
the "sink ID" returned from that call is not a valid sink ID and 
doesn't do anything good.


I am hoping this call is more functional ( does anything functional ) 
in later revs, so I'm onward to upgrading to 12.2 or similar, before 
embarking on creating lots of extra Sinks in the configuration system.


-brian


Hi Brian,

first, let me clarify the terminology pulseaudio is using:

- The term "sink" is used for for an audio output, for example your
speakers connected to your internal sound card or an USB or
Bluetooth device.

- The term "sink input" refers to an individual stream. A sink input
can be connected to a sink. Then the stream will play on your
output device.

To list sink inputs, the function pa_context_get_sink_input_info_list()
can be used. Then the volume can be changed with
pa_context_set_sink_input_volume().

For complete documentation see
https://freedesktop.org/software/pulseaudio/doxygen/

The functions I referenced above can be found at
https://freedesktop.org/software/pulseaudio/doxygen/introspect_8h.html

Regards
 Georg

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [pulseaudio-commits] [Git][pulseaudio/pulseaudio][master] i18n: Don't compile with -ffast-math

2019-07-15 Thread Georg Chini

On 13.07.19 14:03, Georg Chini wrote:

On 13.07.19 14:00, Georg Chini wrote:

On 28.05.19 18:18, Tanu Kaskinen wrote:

GitLab


  Tanu Kaskinen pushed to branch master at PulseAudio /
  pulseaudio <https://gitlab.freedesktop.org/pulseaudio/pulseaudio>


Commits:

  * *fd9e3452

<https://gitlab.freedesktop.org/pulseaudio/pulseaudio/commit/fd9e3452e2e2eb298a5d2f58809febf2bf44453b>*

by Felipe Sateler /at 2019-05-28T16:16:49Z/
i18n: Don't compile with -ffast-math

This flag results in calls to (at least) isfinite() and isnan() becoming
skipped, and a constant false returned. This caused volume-test to fail
on Debian:https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916504

Since PulseAudio deals with negative infinities with volume dB values,
this is not a problem only in volume-test. We shouldn't use -ffast-math
at all.


1 changed file:

  * configure.ac <#87db583be5c13c1f7b3c958b10e03d67b6a2ca06>


Changes:

# *configure.ac* 
<https://gitlab.freedesktop.org/pulseaudio/pulseaudio/commit/fd9e3452e2e2eb298a5d2f58809febf2bf44453b#87db583be5c13c1f7b3c958b10e03d67b6a2ca06> 



... ... @@ -175,7 +175,7 @@ AX_CHECK_COMPILE_FLAG([-std=gnu11],
175 175 
  [-pedantic -Werror])
176 176 
  
177 	177 	

  AX_APPEND_COMPILE_FLAGS(
178 

-[-Wall -W -Wextra -pipe -Wno-long-long -Wno-overlength-strings 
-Wunsafe-loop-optimizations -Wundef -Wformat=2 -Wlogical-op 
-Wsign-compare -Wformat-security -Wmissing-include-dirs 
-Wformat-nonliteral -Wold-style-definition -Wpointer-arith 
-Winit-self -Wdeclaration-after-statement -Wfloat-equal 
-Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls 
-Wmissing-declarations -Wmissing-noreturn -Wshadow -Wendif-labels 
-Wcast-align -Wstrict-aliasing -Wwrite-strings -Wno-unused-parameter 
-ffast-math -fno-common -fdiagnostics-show-option 
-fdiagnostics-color=auto],


178 
+[-Wall -W -Wextra -pipe -Wno-long-long -Wno-overlength-strings 
-Wunsafe-loop-optimizations -Wundef -Wformat=2 -Wlogical-op 
-Wsign-compare -Wformat-security -Wmissing-include-dirs 
-Wformat-nonliteral -Wold-style-definition -Wpointer-arith 
-Winit-self -Wdeclaration-after-statement -Wfloat-equal 
-Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls 
-Wmissing-declarations -Wmissing-noreturn -Wshadow -Wendif-labels 
-Wcast-align -Wstrict-aliasing -Wwrite-strings -Wno-unused-parameter 
-fno-common -fdiagnostics-show-option -fdiagnostics-color=auto],

179 179 
  [], [-pedantic -Werror])
180 180 
  
181 	181 	

  AS_CASE([" $CFLAGS "], [*" -O0 "*], [], [


—
View it on GitLab 
<https://gitlab.freedesktop.org/pulseaudio/pulseaudio/commit/fd9e3452e2e2eb298a5d2f58809febf2bf44453b>. 

You're receiving this email because of your account on 
gitlab.freedesktop.org. If you'd like to receive fewer emails, you 
can adjust your notification settings.



___
pulseaudio-commits mailing list
pulseaudio-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-commits


This patch breaks the use of the soxr resampler for me.
PA crashes under certain conditions. I only tested after
applying !120. (Before this patch set, the soxr resampler
behaves quite strange anyway).

I think PA kicks me out because the real-time limit is
exceeded and the limit is exceeded because the resampler
is compiled without -ffast-math


Further investigation shows that it does not affect current master.
The problem starts with patch 2 of !120, which changes the soxr
resampler to variable rate. The reason why the crash happens is
totally unclear.
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 7/8] sink: move the streams to the default_sink when the sink is unlinked

2019-07-15 Thread Georg Chini

On 15.07.19 14:40, Tanu Kaskinen wrote:

On Sat, 2019-07-13 at 11:03 +0200, Georg Chini wrote:

On 30.06.19 14:15, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:

When a sink is unlinked, all streams of this sink are moved to
default_sink, this action is implemented in the core rather than
modules now.

Signed-off-by: Hui Wang 
---
   src/modules/module-stream-restore.c | 50 -
   src/pulsecore/sink.c|  3 ++
   2 files changed, 3 insertions(+), 50 deletions(-)

diff --git a/src/modules/module-stream-restore.c
b/src/modules/module-stream-restore.c
index c7a5f228a..fd3acb5bd 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -96,7 +96,6 @@ struct userdata {
   *source_output_new_hook_slot,
   *source_output_fixate_hook_slot,
   *source_put_hook_slot,
-*sink_unlink_hook_slot,
   *source_unlink_hook_slot,
   *connection_unlink_hook_slot;
   pa_time_event *save_time_event;
@@ -1691,54 +1690,6 @@ static pa_hook_result_t
source_put_hook_callback(pa_core *c, pa_source *source,
   return PA_HOOK_OK;
   }
   -static pa_hook_result_t sink_unlink_hook_callback(pa_core *c,
pa_sink *sink, struct userdata *u) {
-pa_sink_input *si;
-uint32_t idx;
-
-pa_assert(c);
-pa_assert(sink);
-pa_assert(u);
-pa_assert(u->on_rescue && u->restore_device);
-
-/* There's no point in doing anything if the core is shut down
anyway */
-if (c->state == PA_CORE_SHUTDOWN)
-return PA_HOOK_OK;
-
-PA_IDXSET_FOREACH(si, sink->inputs, idx) {
-char *name;
-struct entry *e;
-
-if (!si->sink)
-continue;
-
-/* Skip this sink input if it is connecting a filter sink to
- * the master */
-if (si->origin_sink)
-continue;
-
-if (!(name = pa_proplist_get_stream_group(si->proplist,
"sink-input", IDENTIFICATION_PROPERTY)))
-continue;
-
-if ((e = entry_read(u, name))) {
-
-if (e->device_valid) {
-pa_sink *d;
-
-if ((d = pa_namereg_get(c, e->device,
PA_NAMEREG_SINK)) &&
-d != sink &&
-PA_SINK_IS_LINKED(d->state))
-pa_sink_input_move_to(si, d, true);
-}
-
-entry_free(e);
-}
-
-pa_xfree(name);
-}
-
-return PA_HOOK_OK;
-}
-
   static pa_hook_result_t source_unlink_hook_callback(pa_core *c,
pa_source *source, struct userdata *u) {
   pa_source_output *so;
   uint32_t idx;
@@ -2420,7 +2371,6 @@ int pa__init(pa_module*m) {
 if (restore_device && on_rescue) {
   /* A little bit earlier than module-intended-roles,
module-rescue-streams, ... */
-pa_module_hook_connect(m,
&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_LATE,
(pa_hook_cb_t) sink_unlink_hook_callback, u);
   pa_module_hook_connect(m,
&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_LATE,
(pa_hook_cb_t) source_unlink_hook_callback, u);
   }
   diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index cf43a78e8..d7973b7c9 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -745,6 +745,9 @@ void pa_sink_unlink(pa_sink* s) {
 linked = PA_SINK_IS_LINKED(s->state);
   +if (linked)
+pa_sink_move_streams_to_default_sink(s->core, s, false);
+

This is called too early. It might be the current default sink that we
are unlinking.


   if (linked)
pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s);

I wonder if we should not drop this patch from the series. Otherwise I think
it has to be re-worked a bit. If we keep it, part of the logic in
module-rescue-stream
needs to be copied to the core (and removed from module-rescue-stream).
First, it is a good idea not to start moving sink-inputs around if the
core is
shutting down anyway and second, simply moving streams to the default
sink may fail. As an example, if you set your default sink to a virtual sink
and the master sink of the virtual sink goes away, you can't move the
sink-input of the virtual sink to the default sink. module-rescue-stream
has find_evacuation_sink() to determine where a sink input should be
moved to. If the patch is re-worked, remember we also need a check for
s->unlink_requested.

Tanu, what would you prefer?

Is the question do I prefer dropping this patch or improving the patch?
I prefer improving the patch, because I think this is an important part
of the policy we want in the core (i.e. keep streams routed to the
default sink when they don't have a preferred sink set or the preferred
sink isn't available).


OK, I would also prefer improving though the patch is slightly
off topic in my opinion because it does not deal with a default
sink transition. That's why I asked if it

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-07-15 Thread Georg Chini

On 15.07.19 14:42, Tanu Kaskinen wrote:

On Sat, 2019-07-13 at 11:31 +0200, Georg Chini wrote:

On 13.07.19 10:46, Georg Chini wrote:

On 30.06.19 13:52, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:

When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the preferred_sink
string is set to the old default sink and the active port of the old
default sink is not unavailable

Signed-off-by: Hui Wang 
---
   src/modules/dbus/iface-core.c   |  2 +-
   src/modules/module-default-device-restore.c |  2 +-
   src/modules/module-switch-on-connect.c  | 27 ++--
   src/pulsecore/cli-command.c |  2 +-
   src/pulsecore/core.c| 10 --
   src/pulsecore/core.h|  4 +--
   src/pulsecore/device-port.c |  2 +-
   src/pulsecore/protocol-native.c |  2 +-
   src/pulsecore/sink.c| 35
+++--
   src/pulsecore/sink.h|  6 
   10 files changed, 54 insertions(+), 38 deletions(-)

diff --git a/src/modules/dbus/iface-core.c
b/src/modules/dbus/iface-core.c
index 5229c0467..9763480d2 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -721,7 +721,7 @@ static void
handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, DBu
   return;
   }
   -pa_core_set_configured_default_sink(c->core,
pa_dbusiface_device_get_sink(fallback_sink)->name);
+pa_core_set_configured_default_sink(c->core,
pa_dbusiface_device_get_sink(fallback_sink)->name, true);
 pa_dbus_send_empty_reply(conn, msg);
   }
diff --git a/src/modules/module-default-device-restore.c
b/src/modules/module-default-device-restore.c
index c4dbad99f..33e74c071 100644
--- a/src/modules/module-default-device-restore.c
+++ b/src/modules/module-default-device-restore.c
@@ -69,7 +69,7 @@ static void load(struct userdata *u) {
   pa_log_warn("Invalid sink name: %s", ln);
   else {
   pa_log_info("Restoring default sink '%s'.", ln);
-pa_core_set_configured_default_sink(u->core, ln);
+pa_core_set_configured_default_sink(u->core, ln, false);
   }
 } else if (errno != ENOENT)
diff --git a/src/modules/module-switch-on-connect.c
b/src/modules/module-switch-on-connect.c
index f0cb29a7c..3ceac8b4f 100644
--- a/src/modules/module-switch-on-connect.c
+++ b/src/modules/module-switch-on-connect.c
@@ -54,9 +54,6 @@ struct userdata {
   };
 static pa_hook_result_t sink_put_hook_callback(pa_core *c,
pa_sink *sink, void* userdata) {
-pa_sink_input *i;
-uint32_t idx;
-pa_sink *old_default_sink;
   const char *s;
   struct userdata *u = userdata;
   @@ -88,7 +85,7 @@ static pa_hook_result_t
sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
 /* No default sink, nothing to move away, just set the new
default */
   if (!c->default_sink) {
-pa_core_set_configured_default_sink(c, sink->name);
+pa_core_set_configured_default_sink(c, sink->name, false);
   return PA_HOOK_OK;
   }
   @@ -103,28 +100,8 @@ static pa_hook_result_t
sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
   return PA_HOOK_OK;
   }
   -old_default_sink = c->default_sink;
-
   /* Actually do the switch to the new sink */
-pa_core_set_configured_default_sink(c, sink->name);
-
-/* Now move all old inputs over */
-if (pa_idxset_size(old_default_sink->inputs) <= 0) {
-pa_log_debug("No sink inputs to move away.");
-return PA_HOOK_OK;
-}
-
-PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) {
-if (pa_safe_streq(i->sink->name, i->preferred_sink) ||
!PA_SINK_INPUT_IS_LINKED(i->state))
-continue;
-
-if (pa_sink_input_move_to(i, sink, false) < 0)
-pa_log_info("Failed to move sink input %u \"%s\" to
%s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist,
PA_PROP_APPLICATION_NAME)), sink->name);
-else
-pa_log_info("Successfully moved sink input %u \"%s\" to
%s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist,
PA_PROP_APPLICATION_NAME)), sink->name);
-}
+pa_core_set_configured_default_sink(c, sink->name, false);

I wonder if we could use something like
pa_core_set_temporary_default_sink() here
and have a variable core->temporary_default_sink that has even higher
priority
than core->configured_default_sink in the default sink selection
process. The temporary
default sink could be reset when the sink vanishes again or replaced
when another new
sink turns up. What module-switch-on-connect does is to temporarily
override the default
sink that the user configured. If we save this in another variable w

[pulseaudio-discuss] Pending patches

2019-07-13 Thread Georg Chini

Hi,

today I did a review/cleanup/rebase of all the patches I have accumulated.
I found there is a total of 65 patches in 11 series, together 8041 additions
and 3233 deletions. I wonder if this ever has the chance to get completely
reviewed ...

Here the series in detail:

1) Messaging patches
8 patches, partly reviewed, introduces messaging API

2) Rewind and resampler patches
9 patches, fixes volume change crackling, introduces resampler delay
measurement

3) Smoother patches
10 patches, introduces new time smoother

4) Loopback patches
10 patches, optimizes latency handling of module-loopback
depends on 2)

5) Combine/Tunnel sink latency fixes
6 patches, fixes latency calculation for tunnel sink/source and combine sink
depends on 2)

6) Signal patches
3 patches, introduces signals as alternative to subscription
depends on 1)

7) Jack detection patches
2 patches, adds messages to enable/disable jack detection and set port state
depends on 1)

8) virtual source crash patch
1 patch, fixes crash with stacked virtual sources

9) virtual sink consolidation patches
8 patches, consolidates virtual sink code in a library, fixes multiple 
(crash) bugs

depends on 2)

10) virtual sink messages patches
7 patches, adds parameter setting via messages to virtual sinks
depends on 1), 2)

11) module-plugin-sink patch
1 patch, adds new module to support PA specific filter plugins
depends on 1), 2), 9), 10)

Regards
 Georg

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [pulseaudio-commits] [Git][pulseaudio/pulseaudio][master] i18n: Don't compile with -ffast-math

2019-07-13 Thread Georg Chini

On 13.07.19 14:00, Georg Chini wrote:

On 28.05.19 18:18, Tanu Kaskinen wrote:

GitLab


  Tanu Kaskinen pushed to branch master at PulseAudio /
  pulseaudio <https://gitlab.freedesktop.org/pulseaudio/pulseaudio>


Commits:

  * *fd9e3452

<https://gitlab.freedesktop.org/pulseaudio/pulseaudio/commit/fd9e3452e2e2eb298a5d2f58809febf2bf44453b>*

by Felipe Sateler /at 2019-05-28T16:16:49Z/
i18n: Don't compile with -ffast-math

This flag results in calls to (at least) isfinite() and isnan() becoming
skipped, and a constant false returned. This caused volume-test to fail
on Debian:https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916504

Since PulseAudio deals with negative infinities with volume dB values,
this is not a problem only in volume-test. We shouldn't use -ffast-math
at all.


1 changed file:

  * configure.ac <#87db583be5c13c1f7b3c958b10e03d67b6a2ca06>


Changes:

# *configure.ac* 
<https://gitlab.freedesktop.org/pulseaudio/pulseaudio/commit/fd9e3452e2e2eb298a5d2f58809febf2bf44453b#87db583be5c13c1f7b3c958b10e03d67b6a2ca06> 



... ... @@ -175,7 +175,7 @@ AX_CHECK_COMPILE_FLAG([-std=gnu11],
175 175 
  [-pedantic -Werror])
176 176 
  
177 	177 	

  AX_APPEND_COMPILE_FLAGS(
178 

-[-Wall -W -Wextra -pipe -Wno-long-long -Wno-overlength-strings 
-Wunsafe-loop-optimizations -Wundef -Wformat=2 -Wlogical-op 
-Wsign-compare -Wformat-security -Wmissing-include-dirs 
-Wformat-nonliteral -Wold-style-definition -Wpointer-arith 
-Winit-self -Wdeclaration-after-statement -Wfloat-equal 
-Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls 
-Wmissing-declarations -Wmissing-noreturn -Wshadow -Wendif-labels 
-Wcast-align -Wstrict-aliasing -Wwrite-strings -Wno-unused-parameter 
-ffast-math -fno-common -fdiagnostics-show-option 
-fdiagnostics-color=auto],


178 
+[-Wall -W -Wextra -pipe -Wno-long-long -Wno-overlength-strings 
-Wunsafe-loop-optimizations -Wundef -Wformat=2 -Wlogical-op 
-Wsign-compare -Wformat-security -Wmissing-include-dirs 
-Wformat-nonliteral -Wold-style-definition -Wpointer-arith 
-Winit-self -Wdeclaration-after-statement -Wfloat-equal 
-Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls 
-Wmissing-declarations -Wmissing-noreturn -Wshadow -Wendif-labels 
-Wcast-align -Wstrict-aliasing -Wwrite-strings -Wno-unused-parameter 
-fno-common -fdiagnostics-show-option -fdiagnostics-color=auto],

179 179 
  [], [-pedantic -Werror])
180 180 
  
181 	181 	

  AS_CASE([" $CFLAGS "], [*" -O0 "*], [], [


—
View it on GitLab 
<https://gitlab.freedesktop.org/pulseaudio/pulseaudio/commit/fd9e3452e2e2eb298a5d2f58809febf2bf44453b>. 

You're receiving this email because of your account on 
gitlab.freedesktop.org. If you'd like to receive fewer emails, you 
can adjust your notification settings.



___
pulseaudio-commits mailing list
pulseaudio-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-commits


This patch breaks the use of the soxr resampler for me.
PA crashes under certain conditions. I only tested after
applying !120. (Before this patch set, the soxr resampler
behaves quite strange anyway).

I think PA kicks me out because the real-time limit is
exceeded and the limit is exceeded because the resampler
is compiled without -ffast-math


sent to the wrong list ...

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-07-13 Thread Georg Chini

On 13.07.19 10:46, Georg Chini wrote:

On 30.06.19 13:52, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:

When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the preferred_sink
string is set to the old default sink and the active port of the old
default sink is not unavailable

Signed-off-by: Hui Wang 
---
  src/modules/dbus/iface-core.c   |  2 +-
  src/modules/module-default-device-restore.c |  2 +-
  src/modules/module-switch-on-connect.c  | 27 ++--
  src/pulsecore/cli-command.c |  2 +-
  src/pulsecore/core.c    | 10 --
  src/pulsecore/core.h    |  4 +--
  src/pulsecore/device-port.c |  2 +-
  src/pulsecore/protocol-native.c |  2 +-
  src/pulsecore/sink.c    | 35 
+++--

  src/pulsecore/sink.h    |  6 
  10 files changed, 54 insertions(+), 38 deletions(-)

diff --git a/src/modules/dbus/iface-core.c 
b/src/modules/dbus/iface-core.c

index 5229c0467..9763480d2 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -721,7 +721,7 @@ static void 
handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, DBu

  return;
  }
  -    pa_core_set_configured_default_sink(c->core, 
pa_dbusiface_device_get_sink(fallback_sink)->name);
+    pa_core_set_configured_default_sink(c->core, 
pa_dbusiface_device_get_sink(fallback_sink)->name, true);

    pa_dbus_send_empty_reply(conn, msg);
  }
diff --git a/src/modules/module-default-device-restore.c 
b/src/modules/module-default-device-restore.c

index c4dbad99f..33e74c071 100644
--- a/src/modules/module-default-device-restore.c
+++ b/src/modules/module-default-device-restore.c
@@ -69,7 +69,7 @@ static void load(struct userdata *u) {
  pa_log_warn("Invalid sink name: %s", ln);
  else {
  pa_log_info("Restoring default sink '%s'.", ln);
-    pa_core_set_configured_default_sink(u->core, ln);
+    pa_core_set_configured_default_sink(u->core, ln, false);
  }
    } else if (errno != ENOENT)
diff --git a/src/modules/module-switch-on-connect.c 
b/src/modules/module-switch-on-connect.c

index f0cb29a7c..3ceac8b4f 100644
--- a/src/modules/module-switch-on-connect.c
+++ b/src/modules/module-switch-on-connect.c
@@ -54,9 +54,6 @@ struct userdata {
  };
    static pa_hook_result_t sink_put_hook_callback(pa_core *c, 
pa_sink *sink, void* userdata) {

-    pa_sink_input *i;
-    uint32_t idx;
-    pa_sink *old_default_sink;
  const char *s;
  struct userdata *u = userdata;
  @@ -88,7 +85,7 @@ static pa_hook_result_t 
sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
    /* No default sink, nothing to move away, just set the new 
default */

  if (!c->default_sink) {
-    pa_core_set_configured_default_sink(c, sink->name);
+    pa_core_set_configured_default_sink(c, sink->name, false);
  return PA_HOOK_OK;
  }
  @@ -103,28 +100,8 @@ static pa_hook_result_t 
sink_put_hook_callback(pa_core *c, pa_sink *sink, void*

  return PA_HOOK_OK;
  }
  -    old_default_sink = c->default_sink;
-
  /* Actually do the switch to the new sink */
-    pa_core_set_configured_default_sink(c, sink->name);
-
-    /* Now move all old inputs over */
-    if (pa_idxset_size(old_default_sink->inputs) <= 0) {
-    pa_log_debug("No sink inputs to move away.");
-    return PA_HOOK_OK;
-    }
-
-    PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) {
-    if (pa_safe_streq(i->sink->name, i->preferred_sink) || 
!PA_SINK_INPUT_IS_LINKED(i->state))

-    continue;
-
-    if (pa_sink_input_move_to(i, sink, false) < 0)
-    pa_log_info("Failed to move sink input %u \"%s\" to 
%s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);

-    else
-    pa_log_info("Successfully moved sink input %u \"%s\" to 
%s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);

-    }
+    pa_core_set_configured_default_sink(c, sink->name, false);


I wonder if we could use something like 
pa_core_set_temporary_default_sink() here
and have a variable core->temporary_default_sink that has even higher 
priority
than core->configured_default_sink in the default sink selection 
process. The temporary
default sink could be reset when the sink vanishes again or replaced 
when another new
sink turns up. What module-switch-on-connect does is to temporarily 
override the default
sink that the user configured. If we save this in another variable we 
would not overwrite
the user configured default sink by a sink that is not expected to be 
pres

Re: [pulseaudio-discuss] [PATCH v2 7/8] sink: move the streams to the default_sink when the sink is unlinked

2019-07-13 Thread Georg Chini

On 30.06.19 14:15, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:

When a sink is unlinked, all streams of this sink are moved to
default_sink, this action is implemented in the core rather than
modules now.

Signed-off-by: Hui Wang 
---
  src/modules/module-stream-restore.c | 50 -
  src/pulsecore/sink.c    |  3 ++
  2 files changed, 3 insertions(+), 50 deletions(-)

diff --git a/src/modules/module-stream-restore.c 
b/src/modules/module-stream-restore.c

index c7a5f228a..fd3acb5bd 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -96,7 +96,6 @@ struct userdata {
  *source_output_new_hook_slot,
  *source_output_fixate_hook_slot,
  *source_put_hook_slot,
-    *sink_unlink_hook_slot,
  *source_unlink_hook_slot,
  *connection_unlink_hook_slot;
  pa_time_event *save_time_event;
@@ -1691,54 +1690,6 @@ static pa_hook_result_t 
source_put_hook_callback(pa_core *c, pa_source *source,

  return PA_HOOK_OK;
  }
  -static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, 
pa_sink *sink, struct userdata *u) {

-    pa_sink_input *si;
-    uint32_t idx;
-
-    pa_assert(c);
-    pa_assert(sink);
-    pa_assert(u);
-    pa_assert(u->on_rescue && u->restore_device);
-
-    /* There's no point in doing anything if the core is shut down 
anyway */

-    if (c->state == PA_CORE_SHUTDOWN)
-    return PA_HOOK_OK;
-
-    PA_IDXSET_FOREACH(si, sink->inputs, idx) {
-    char *name;
-    struct entry *e;
-
-    if (!si->sink)
-    continue;
-
-    /* Skip this sink input if it is connecting a filter sink to
- * the master */
-    if (si->origin_sink)
-    continue;
-
-    if (!(name = pa_proplist_get_stream_group(si->proplist, 
"sink-input", IDENTIFICATION_PROPERTY)))

-    continue;
-
-    if ((e = entry_read(u, name))) {
-
-    if (e->device_valid) {
-    pa_sink *d;
-
-    if ((d = pa_namereg_get(c, e->device, 
PA_NAMEREG_SINK)) &&

-    d != sink &&
-    PA_SINK_IS_LINKED(d->state))
-    pa_sink_input_move_to(si, d, true);
-    }
-
-    entry_free(e);
-    }
-
-    pa_xfree(name);
-    }
-
-    return PA_HOOK_OK;
-}
-
  static pa_hook_result_t source_unlink_hook_callback(pa_core *c, 
pa_source *source, struct userdata *u) {

  pa_source_output *so;
  uint32_t idx;
@@ -2420,7 +2371,6 @@ int pa__init(pa_module*m) {
    if (restore_device && on_rescue) {
  /* A little bit earlier than module-intended-roles, 
module-rescue-streams, ... */
-    pa_module_hook_connect(m, 
&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_LATE, 
(pa_hook_cb_t) sink_unlink_hook_callback, u);
  pa_module_hook_connect(m, 
&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_LATE, 
(pa_hook_cb_t) source_unlink_hook_callback, u);

  }
  diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index cf43a78e8..d7973b7c9 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -745,6 +745,9 @@ void pa_sink_unlink(pa_sink* s) {
    linked = PA_SINK_IS_LINKED(s->state);
  +    if (linked)
+    pa_sink_move_streams_to_default_sink(s->core, s, false);
+


This is called too early. It might be the current default sink that we 
are unlinking.



  if (linked)
pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s);




I wonder if we should not drop this patch from the series. Otherwise I think
it has to be re-worked a bit. If we keep it, part of the logic in 
module-rescue-stream

needs to be copied to the core (and removed from module-rescue-stream).
First, it is a good idea not to start moving sink-inputs around if the 
core is

shutting down anyway and second, simply moving streams to the default
sink may fail. As an example, if you set your default sink to a virtual sink
and the master sink of the virtual sink goes away, you can't move the
sink-input of the virtual sink to the default sink. module-rescue-stream
has find_evacuation_sink() to determine where a sink input should be
moved to. If the patch is re-worked, remember we also need a check for
s->unlink_requested.

Tanu, what would you prefer?

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-07-13 Thread Georg Chini

On 30.06.19 13:52, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:

When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the preferred_sink
string is set to the old default sink and the active port of the old
default sink is not unavailable

Signed-off-by: Hui Wang 
---
  src/modules/dbus/iface-core.c   |  2 +-
  src/modules/module-default-device-restore.c |  2 +-
  src/modules/module-switch-on-connect.c  | 27 ++--
  src/pulsecore/cli-command.c |  2 +-
  src/pulsecore/core.c    | 10 --
  src/pulsecore/core.h    |  4 +--
  src/pulsecore/device-port.c |  2 +-
  src/pulsecore/protocol-native.c |  2 +-
  src/pulsecore/sink.c    | 35 +++--
  src/pulsecore/sink.h    |  6 
  10 files changed, 54 insertions(+), 38 deletions(-)

diff --git a/src/modules/dbus/iface-core.c 
b/src/modules/dbus/iface-core.c

index 5229c0467..9763480d2 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -721,7 +721,7 @@ static void 
handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, DBu

  return;
  }
  -    pa_core_set_configured_default_sink(c->core, 
pa_dbusiface_device_get_sink(fallback_sink)->name);
+    pa_core_set_configured_default_sink(c->core, 
pa_dbusiface_device_get_sink(fallback_sink)->name, true);

    pa_dbus_send_empty_reply(conn, msg);
  }
diff --git a/src/modules/module-default-device-restore.c 
b/src/modules/module-default-device-restore.c

index c4dbad99f..33e74c071 100644
--- a/src/modules/module-default-device-restore.c
+++ b/src/modules/module-default-device-restore.c
@@ -69,7 +69,7 @@ static void load(struct userdata *u) {
  pa_log_warn("Invalid sink name: %s", ln);
  else {
  pa_log_info("Restoring default sink '%s'.", ln);
-    pa_core_set_configured_default_sink(u->core, ln);
+    pa_core_set_configured_default_sink(u->core, ln, false);
  }
    } else if (errno != ENOENT)
diff --git a/src/modules/module-switch-on-connect.c 
b/src/modules/module-switch-on-connect.c

index f0cb29a7c..3ceac8b4f 100644
--- a/src/modules/module-switch-on-connect.c
+++ b/src/modules/module-switch-on-connect.c
@@ -54,9 +54,6 @@ struct userdata {
  };
    static pa_hook_result_t sink_put_hook_callback(pa_core *c, 
pa_sink *sink, void* userdata) {

-    pa_sink_input *i;
-    uint32_t idx;
-    pa_sink *old_default_sink;
  const char *s;
  struct userdata *u = userdata;
  @@ -88,7 +85,7 @@ static pa_hook_result_t 
sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
    /* No default sink, nothing to move away, just set the new 
default */

  if (!c->default_sink) {
-    pa_core_set_configured_default_sink(c, sink->name);
+    pa_core_set_configured_default_sink(c, sink->name, false);
  return PA_HOOK_OK;
  }
  @@ -103,28 +100,8 @@ static pa_hook_result_t 
sink_put_hook_callback(pa_core *c, pa_sink *sink, void*

  return PA_HOOK_OK;
  }
  -    old_default_sink = c->default_sink;
-
  /* Actually do the switch to the new sink */
-    pa_core_set_configured_default_sink(c, sink->name);
-
-    /* Now move all old inputs over */
-    if (pa_idxset_size(old_default_sink->inputs) <= 0) {
-    pa_log_debug("No sink inputs to move away.");
-    return PA_HOOK_OK;
-    }
-
-    PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) {
-    if (pa_safe_streq(i->sink->name, i->preferred_sink) || 
!PA_SINK_INPUT_IS_LINKED(i->state))

-    continue;
-
-    if (pa_sink_input_move_to(i, sink, false) < 0)
-    pa_log_info("Failed to move sink input %u \"%s\" to 
%s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);

-    else
-    pa_log_info("Successfully moved sink input %u \"%s\" to 
%s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);

-    }
+    pa_core_set_configured_default_sink(c, sink->name, false);


I wonder if we could use something like 
pa_core_set_temporary_default_sink() here
and have a variable core->temporary_default_sink that has even higher 
priority
than core->configured_default_sink in the default sink selection 
process. The temporary
default sink could be reset when the sink vanishes again or replaced 
when another new
sink turns up. What module-switch-on-connect does is to temporarily 
override the default
sink that the user configured. If we save this in another variable we 
would not overwrite
the user configured default sink by a sink that is not expected to be 
present the next

time PA is started. But

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-07-12 Thread Georg Chini

On 12.07.19 13:13, Tanu Kaskinen wrote:

On Wed, 2019-07-10 at 22:03 +0200, Georg Chini wrote:

On 10.07.19 16:03, Tanu Kaskinen wrote:

On Fri, 2019-07-05 at 10:57 +0200, Georg Chini wrote:

On 05.07.19 09:41, Tanu Kaskinen wrote:

On Tue, 2019-07-02 at 09:08 +0200, Georg Chini wrote:

On 02.07.19 08:43, Tanu Kaskinen wrote:

On Mon, 2019-07-01 at 08:03 +0200, Georg Chini wrote:

On 01.07.19 07:08, Tanu Kaskinen wrote:
When a new sink appears, pa_core_update_default_sink() is called. Since
PulseAudio 11.1, bluetooth and USB sinks have higher priority than the
internal sound card, so pa_core_update_default_sink() will switch to
the BT speakers in your example. The main benefit of module-switch-on-
connect was that it moved existing streams to the new sink, but after
this patch set that's handled by the core. Therefore there's much less
need for module-switch-on-connect.


This is true, but only relevant if there is no configured default
sink. If the configured default sink is set, there will be no switch
to a newly appearing sink because the configured default sink
is prioritized over all other sinks. In this case you still need
module-switch-on-connect.

My estimation is that this is very rarely a problem.

Mh, my estimation is, that this will be the normal case. At some
point the user will set a default sink manually, and from that point
on, automatic switching will no longer work. The configured default
sink is never unset once it is set.

Yes, sure, but I tried to explain why this is rarely a problem. (In
another thread you described a valid use case where this becomes a
problem, but I don't think that's a "normal case".)


If you have manually selected an external sound card as the default
sink and you then plug in another external sound card, then you may or
may not want to automatically switch to the new sound card. If you
fiddle a lot with two external sound cards and you always want to use
the last one plugged in, then module-switch-on-connect is still useful,
but in this case it doesn't really matter that your old default device
choice is forgotten, because PulseAudio will anyway prefer the
remaining external sound card.

This topic is not about forgetting the last sink, but about switching
to a new sink at all. Once you manually set the default sink, it will
never switch automatically without module-switch-on-connect,
because the default sink selection process prefers the configured
default sink over all other sinks.

You're assuming that we always want to switch to a newly plugged in
device. Let's say that you have just one USB device, no other external
devices. If you for some reason set the internal sound card as the
default device, I think it's a good thing that we don't automatically
switch to that USB device when it's plugged in again. Therefore I think
it's a good thing that we don't load module-switch-on-connect by
default.

If you in this situation plug in another external device, it would
probably make sense to switch to it, but I don't what the full policy
would look like that would allow this without breaking anything. I
believe it's a good compromise to stick to the current configured
default sink until the user changes it or the device goes away.


You said you will write another mail tomorrow, so I skip most
of your comments, but while reading your mails I realized
what is really behind my dislike of the current switching logic:

I believe it is a bad idea to make switching to new sinks
dependent on the configured default sink. Switching to
new sinks is something a user should be able to turn on
and off separately. Behavior could be something like that:

If switching to new sinks is turned off and a new sink turns up,
we should never switch to it, even if it has higher priority and
even if the configured default sink is not set. The only exception
would be if the configured default sink is set and the sink that
turns up is the configured default sink.

If switching to new sinks is turned on, we always switch to a
new device. The configured default sink is the one we always
return to when the last added device is removed. This means
if two devices have been added, we would already go back to
the configured default when the second device is removed. If
no default is configured, we would use the highest priority sink
to return to.

As I said in IRC, I changed my mind about always switching to new
devices regardless of the current configured default sink. I now think
that's a good idea. As you've said, if the user ever configures the
default sink, PulseAudio will from then on never switch to plugged in
devices. I first thought that's OK, because we should respect the
user's explicit preference if the configured default device remains
available, and if it isn't available, then automatic switching to the
plugged in device will work fine.

But if we implement default device histor

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-07-10 Thread Georg Chini

On 10.07.19 16:03, Tanu Kaskinen wrote:

On Fri, 2019-07-05 at 10:57 +0200, Georg Chini wrote:

On 05.07.19 09:41, Tanu Kaskinen wrote:

On Tue, 2019-07-02 at 09:08 +0200, Georg Chini wrote:

On 02.07.19 08:43, Tanu Kaskinen wrote:

On Mon, 2019-07-01 at 08:03 +0200, Georg Chini wrote:

On 01.07.19 07:08, Tanu Kaskinen wrote:
When a new sink appears, pa_core_update_default_sink() is called. Since
PulseAudio 11.1, bluetooth and USB sinks have higher priority than the
internal sound card, so pa_core_update_default_sink() will switch to
the BT speakers in your example. The main benefit of module-switch-on-
connect was that it moved existing streams to the new sink, but after
this patch set that's handled by the core. Therefore there's much less
need for module-switch-on-connect.


This is true, but only relevant if there is no configured default
sink. If the configured default sink is set, there will be no switch
to a newly appearing sink because the configured default sink
is prioritized over all other sinks. In this case you still need
module-switch-on-connect.

My estimation is that this is very rarely a problem.

Mh, my estimation is, that this will be the normal case. At some
point the user will set a default sink manually, and from that point
on, automatic switching will no longer work. The configured default
sink is never unset once it is set.

Yes, sure, but I tried to explain why this is rarely a problem. (In
another thread you described a valid use case where this becomes a
problem, but I don't think that's a "normal case".)


If you have manually selected an external sound card as the default
sink and you then plug in another external sound card, then you may or
may not want to automatically switch to the new sound card. If you
fiddle a lot with two external sound cards and you always want to use
the last one plugged in, then module-switch-on-connect is still useful,
but in this case it doesn't really matter that your old default device
choice is forgotten, because PulseAudio will anyway prefer the
remaining external sound card.

This topic is not about forgetting the last sink, but about switching
to a new sink at all. Once you manually set the default sink, it will
never switch automatically without module-switch-on-connect,
because the default sink selection process prefers the configured
default sink over all other sinks.

You're assuming that we always want to switch to a newly plugged in
device. Let's say that you have just one USB device, no other external
devices. If you for some reason set the internal sound card as the
default device, I think it's a good thing that we don't automatically
switch to that USB device when it's plugged in again. Therefore I think
it's a good thing that we don't load module-switch-on-connect by
default.

If you in this situation plug in another external device, it would
probably make sense to switch to it, but I don't what the full policy
would look like that would allow this without breaking anything. I
believe it's a good compromise to stick to the current configured
default sink until the user changes it or the device goes away.


You said you will write another mail tomorrow, so I skip most
of your comments, but while reading your mails I realized
what is really behind my dislike of the current switching logic:

I believe it is a bad idea to make switching to new sinks
dependent on the configured default sink. Switching to
new sinks is something a user should be able to turn on
and off separately. Behavior could be something like that:

If switching to new sinks is turned off and a new sink turns up,
we should never switch to it, even if it has higher priority and
even if the configured default sink is not set. The only exception
would be if the configured default sink is set and the sink that
turns up is the configured default sink.

If switching to new sinks is turned on, we always switch to a
new device. The configured default sink is the one we always
return to when the last added device is removed. This means
if two devices have been added, we would already go back to
the configured default when the second device is removed. If
no default is configured, we would use the highest priority sink
to return to.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] RTP Latency - how to reduce.

2019-07-08 Thread Georg Chini

On 08.07.19 15:51, Sergei Steshenko wrote:


On 07/07/2019 21:47, tony.cha...@vartaxos.com wrote:

I have searched

Setup: Desktop machine (Centos 7, PulseAudio 10.0), and a Raspberry 
Pi 2B (Raspbian (Debian) Buster PulseAudio 12.2) with DAC and speaker.


If I play a video point-to-point over TCP the synch is fine, but over 
RTP (with latency_msec=1 on RPi) there is signifcant audio latency - 
enough to be irritating.


If I add a second, identical RPi (although with Raspbian Stretch and 
PulseAudio 12.2), the RTP sound is synchronous on each machine (but 
not with the video).


This is on a small private wired LAN (Netgear GS724T V3), 1G to 
desktop, 100M to RPI.


I have set tsched=0 in order to eradicate pops and sprogs.

What can I do to reduce RTP latency?

I eventually want to connect a guitar, and would need realtime 
loop-through, so no suggestions about increasing audio latency to 
obtain lip-synch, please.


Tony

"I eventually want to connect a guitar" - I was doing some estimates, 
and if I were you, I would bypass not only pulseuadio, but also ALSA 
I.e. I would create a dedicated audio program that bypasses the kernel 
and interacts with device directly. I would also starve the OS WRT 
scheduling. I.e. I would allocate, say, 99% of time to the dedicated 
program. I would also tune kernel ticks to be in sync with sample rate.



--Sergei.

What do you think is the actual latency you can live with? And is RTP a 
requirement?
If ~ 10ms is sufficient and you can you also use a tunnel sink,  you 
could try this merge

request:
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/merge_requests/53
It allows to reduce the latency of the tunnel sink by using a command 
line parameter.
I was able to get down to around 7ms (real latency, measured with an 
oscilloscope).

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-07-05 Thread Georg Chini

On 05.07.19 10:57, Georg Chini wrote:

On 05.07.19 09:41, Tanu Kaskinen wrote:

On Tue, 2019-07-02 at 09:08 +0200, Georg Chini wrote:

On 02.07.19 08:43, Tanu Kaskinen wrote:

On Mon, 2019-07-01 at 08:03 +0200, Georg Chini wrote:

On 01.07.19 07:08, Tanu Kaskinen wrote:

On Sun, 2019-06-30 at 13:52 +0200, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:
When the default sink changes, the streams from the old default 
sink

should be moved to the new default sink, unless the preferred_sink
string is set to the old default sink and the active port of 
the old

default sink is not unavailable


  static pa_hook_result_t 
sink_put_hook_callback(pa_core *c, pa_sink *sink, void* 
userdata) {

-    pa_sink_input *i;
-    uint32_t idx;
-    pa_sink *old_default_sink;
 const char *s;
 struct userdata *u = userdata;
 @@ -88,7 +85,7 @@ static pa_hook_result_t 
sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
  /* No default sink, nothing to move away, just 
set the new default */

 if (!c->default_sink) {
-    pa_core_set_configured_default_sink(c, sink->name);
+    pa_core_set_configured_default_sink(c, sink->name, 
false);

 return PA_HOOK_OK;
 }
 @@ -103,28 +100,8 @@ static pa_hook_result_t 
sink_put_hook_callback(pa_core *c, pa_sink *sink, void*

 return PA_HOOK_OK;
 }
 -    old_default_sink = c->default_sink;
-
 /* Actually do the switch to the new sink */
-    pa_core_set_configured_default_sink(c, sink->name);
-
-    /* Now move all old inputs over */
-    if (pa_idxset_size(old_default_sink->inputs) <= 0) {
-    pa_log_debug("No sink inputs to move away.");
-    return PA_HOOK_OK;
-    }
-
-    PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) {
-    if (pa_safe_streq(i->sink->name, i->preferred_sink) || 
!PA_SINK_INPUT_IS_LINKED(i->state))

-    continue;
-
-    if (pa_sink_input_move_to(i, sink, false) < 0)
-    pa_log_info("Failed to move sink input %u \"%s\" 
to %s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);

-    else
-    pa_log_info("Successfully moved sink input %u 
\"%s\" to %s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);

-    }
+    pa_core_set_configured_default_sink(c, sink->name, false);

I wonder if we could use something like
pa_core_set_temporary_default_sink() here
and have a variable core->temporary_default_sink that has even 
higher

priority
than core->configured_default_sink in the default sink selection
process. The temporary
default sink could be reset when the sink vanishes again or 
replaced

when another new
sink turns up. What module-switch-on-connect does is to temporarily
override the default
sink that the user configured. If we save this in another 
variable we

would not overwrite
the user configured default sink by a sink that is not expected 
to be

present the next
time PA is started. But that would be just nice to have.

I'm against adding that kind of extra complexity without a very good
justification. module-switch-on-connect should become nearly 
obsolete

anyway after this patch set has been merged.

We already talked about this some time ago and you agreed
that this would be useful. Maybe you remember that discussion.

I remember that we discussed my initial attempt at implementing what
this patch set does. I probably should go back to that discussion to
find out why I agreed that we should add a separate "temporary default
sink" variable.

You did not exactly agree to adding a temporary_default_sink
variable. You agreed however (after some discussion) that
what module-switch-on-connect does is a temporary override
of the configured default sink and that there should be a way
to restore the original default sink. (The user may have set
another than the highest priority sink as default, see also
below).

It seems quite simple to add such a variable and replace it
when a new sink turns up or set it to NULL if the current
temporary default sink is removed. This would then make
it really easy to implement the module-switch-on-connect
functionality in the core at some later point.

I'm concerned about the complexity of answering the question "how is
the default sink determined". The fact that "default sink" and
"configured default sink" are different things is already bothersome.


Why do you find this bothersome? I think it is pretty obvious
that the two are not necessarily identical.


Your point about restoring the old configured default sink is
definitely valid, although that problem seems to be not specific to
module-switch-on-connect: if there are 3 sinks, the user can't specify
which of them is the second most prefer

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-07-05 Thread Georg Chini

On 05.07.19 09:56, Tanu Kaskinen wrote:

On Tue, 2019-07-02 at 10:25 +0200, Georg Chini wrote:

On 02.07.19 06:49, Tanu Kaskinen wrote:

On Mon, 2019-07-01 at 08:48 +0200, Georg Chini wrote:

On 01.07.19 08:03, Georg Chini wrote:

On 01.07.19 07:08, Tanu Kaskinen wrote:

On Sun, 2019-06-30 at 13:52 +0200, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:

When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the preferred_sink
string is set to the old default sink and the active port of the old
default sink is not unavailable
 +
+void pa_sink_move_streams_to_default_sink(pa_core *core, pa_sink
*old_sink, bool from_user) {
+pa_sink_input *i;
+uint32_t idx;
+bool old_sink_is_unavailable;

Does this not give a warning about using uninitialized variables?

+
+pa_assert(core);
+pa_assert(old_sink);
+
+if (old_sink == core->default_sink)
+return;
+
+if (old_sink->active_port && old_sink->active_port->available
== PA_AVAILABLE_NO)
+old_sink_is_unavailable = true;

This is not sufficient to determine if the old sink is still available.
There are sinks
that do not have ports (null-sink, virtual sinks). I think you will
need
another boolean
argument to the function which indicates availability of the old sink.

The definition of an unavailable sink is that its active port is
unavailable. I don't know what kind of sinks you're thinking about
here, maybe virtual sinks that are on top of an unavailable hardware
sink? There are many places where we check the availability of a sink
this way, and I don't think it makes sense to be different here.

I don't understand. Virtual sinks don't have ports. So checking only
sinks that have an active port excludes all sinks that don't have
ports like the null-sink and virtual sinks. Following your definition
above, those sinks are never available.

You have it reversed: following my definition above, those sinks are
always available.

Right, sorry. (I seem to be reading things wrong quite often
the last few weeks ... I'll do my best to be more thorough in
the future.)

Checking the code, only alsa, bluetooth and raop sinks define ports and
the "many places" you are referring to are compare_sinks() and
compare_sources() in core.c and a check in module-switch-on-connect,
which is used to determine the availability of the default sink.

At least module-stream-restore checks device availability too (although
probably not anymore after this patch set, because module-stream-
restore won't do the routing directly anymore, it will just restore the
preferred_sink variable, which can be done regardless of the sink
availability).

Extending the hardware sink availability to filter sinks probably makes
sense, but I think that's a topic for a separate patch (or patches).

You suggested an extra flag for pa_sink_move_streams_to_default_sink(),
which seems unnecessary to me. The function can in any case figure out
the availability by itself (possibly using a helper function
pa_sink_is_available() that can handle filter sinks too).


I think some additional check is still needed at least for
s->unlink_requested
because when a sink is going to be unlinked and the function is called from
pa_sink_unlink() in patch 7, there may be nothing else that indicates
that the
sink is going to be removed. When I proposed an additional argument, I did
not see that pa_sink_unlink() already sets a flag that can be used.

So I would suggest that the helper function checks on
- link state

I don't expect this to be necessary, although it can't hurt either.


- port availability
- s->unlink_requested

If this is indeed used from pa_sink_unlink() to rescue streams, then
checking this seems appropriate (and can't hurt anyway).


- suspend state (any reason apart from SUSPEND_IDLE)

This doesn't seem appropriate, unless we start avoiding suspended sinks
in the same way we avoid unavailable sinks. That would mean that we
would never use a suspended sink as the default sink. That would
probably make sense actually, so I'm just pointing out that we need to
be consistent: if we avoid suspended sinks in one situation, we should
avoid them in all situations.


Yes, we should do that. Therefore my suggestion is to add a helper
function to this patch set. For consistency we could exclude the
suspend state for the moment, though I would recommend to include
it. Using the helper function outside this patch set in all places where
we check availability should then be the task of another patch series.
By suspended I guess you mean suspended apart from idle, correct?




Using the helper function in other places (and extending it if I forgot
something
in the list above) could then be done in a separate patch. Are you OK
with that?

Yes, I think a helper function can be added, and if it's added, it's
a

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-07-05 Thread Georg Chini

On 05.07.19 09:41, Tanu Kaskinen wrote:

On Tue, 2019-07-02 at 09:08 +0200, Georg Chini wrote:

On 02.07.19 08:43, Tanu Kaskinen wrote:

On Mon, 2019-07-01 at 08:03 +0200, Georg Chini wrote:

On 01.07.19 07:08, Tanu Kaskinen wrote:

On Sun, 2019-06-30 at 13:52 +0200, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:

When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the preferred_sink
string is set to the old default sink and the active port of the old
default sink is not unavailable


 
 static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* userdata) {

-pa_sink_input *i;
-uint32_t idx;
-pa_sink *old_default_sink;
 const char *s;
 struct userdata *u = userdata;
 
@@ -88,7 +85,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
 
 /* No default sink, nothing to move away, just set the new default */

 if (!c->default_sink) {
-pa_core_set_configured_default_sink(c, sink->name);
+pa_core_set_configured_default_sink(c, sink->name, false);
 return PA_HOOK_OK;
 }
 
@@ -103,28 +100,8 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*

 return PA_HOOK_OK;
 }
 
-old_default_sink = c->default_sink;

-
 /* Actually do the switch to the new sink */
-pa_core_set_configured_default_sink(c, sink->name);
-
-/* Now move all old inputs over */
-if (pa_idxset_size(old_default_sink->inputs) <= 0) {
-pa_log_debug("No sink inputs to move away.");
-return PA_HOOK_OK;
-}
-
-PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) {
-if (pa_safe_streq(i->sink->name, i->preferred_sink) || 
!PA_SINK_INPUT_IS_LINKED(i->state))
-continue;
-
-if (pa_sink_input_move_to(i, sink, false) < 0)
-pa_log_info("Failed to move sink input %u \"%s\" to %s.", i->index,
-pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);
-else
-pa_log_info("Successfully moved sink input %u \"%s\" to %s.", 
i->index,
-pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);
-}
+pa_core_set_configured_default_sink(c, sink->name, false);

I wonder if we could use something like
pa_core_set_temporary_default_sink() here
and have a variable core->temporary_default_sink that has even higher
priority
than core->configured_default_sink in the default sink selection
process. The temporary
default sink could be reset when the sink vanishes again or replaced
when another new
sink turns up. What module-switch-on-connect does is to temporarily
override the default
sink that the user configured. If we save this in another variable we
would not overwrite
the user configured default sink by a sink that is not expected to be
present the next
time PA is started. But that would be just nice to have.

I'm against adding that kind of extra complexity without a very good
justification. module-switch-on-connect should become nearly obsolete
anyway after this patch set has been merged.

We already talked about this some time ago and you agreed
that this would be useful. Maybe you remember that discussion.

I remember that we discussed my initial attempt at implementing what
this patch set does. I probably should go back to that discussion to
find out why I agreed that we should add a separate "temporary default
sink" variable.

You did not exactly agree to adding a temporary_default_sink
variable. You agreed however (after some discussion) that
what module-switch-on-connect does is a temporary override
of the configured default sink and that there should be a way
to restore the original default sink. (The user may have set
another than the highest priority sink as default, see also
below).

It seems quite simple to add such a variable and replace it
when a new sink turns up or set it to NULL if the current
temporary default sink is removed. This would then make
it really easy to implement the module-switch-on-connect
functionality in the core at some later point.

I'm concerned about the complexity of answering the question "how is
the default sink determined". The fact that "default sink" and
"configured default sink" are different things is already bothersome.


Why do you find this bothersome? I think it is pretty obvious
that the two are not necessarily identical.


Your point about restoring the old configured default sink is
definitely valid, although that problem seems to be not specific to
module-switch-on-connect: if there are 3 sinks, the user can't specify
which of them is the second most preferred sink in

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-07-02 Thread Georg Chini

On 17.01.19 07:53, Hui Wang wrote:

When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the preferred_sink
string is set to the old default sink and the active port of the old
default sink is not unavailable

Signed-off-by: Hui Wang 
---

...

+
+void pa_sink_move_streams_to_default_sink(pa_core *core, pa_sink *old_sink, 
bool from_user) {
+pa_sink_input *i;
+uint32_t idx;
+bool old_sink_is_unavailable;
+
+pa_assert(core);
+pa_assert(old_sink);
+
+if (old_sink == core->default_sink)
+return;
+
+if (old_sink->active_port && old_sink->active_port->available == 
PA_AVAILABLE_NO)
+old_sink_is_unavailable = true;
+
+if (pa_idxset_size(old_sink->inputs) > 0) {
+PA_IDXSET_FOREACH(i, old_sink->inputs, idx) {
+if (!PA_SINK_INPUT_IS_LINKED(i->state))
+continue;
+
+if (pa_safe_streq(old_sink->name, i->preferred_sink) && 
!old_sink_is_unavailable)
+continue;
+
+pa_log_info("The sink input %u \"%s\" is moving to %s due to 
default_sink is changed.",
+i->index, pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), core->default_sink->name);
+pa_sink_input_move_to(i, core->default_sink, from_user);
+}
+}
+}


If the last sink is in the process of getting removed,  old_sink would 
be the previous
default sink and core->default_sink would be NULL. Is it possible, that 
in this situation
there are still inputs on the sink? Maybe the function should check if 
core->default_sink

is not NULL, just to make sure.



___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-07-02 Thread Georg Chini

On 02.07.19 06:49, Tanu Kaskinen wrote:

On Mon, 2019-07-01 at 08:48 +0200, Georg Chini wrote:

On 01.07.19 08:03, Georg Chini wrote:

On 01.07.19 07:08, Tanu Kaskinen wrote:

On Sun, 2019-06-30 at 13:52 +0200, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:

When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the preferred_sink
string is set to the old default sink and the active port of the old
default sink is not unavailable



+
+void pa_sink_move_streams_to_default_sink(pa_core *core, pa_sink
*old_sink, bool from_user) {
+pa_sink_input *i;
+uint32_t idx;
+bool old_sink_is_unavailable;

Does this not give a warning about using uninitialized variables?

+
+pa_assert(core);
+pa_assert(old_sink);
+
+if (old_sink == core->default_sink)
+return;
+
+if (old_sink->active_port && old_sink->active_port->available
== PA_AVAILABLE_NO)
+old_sink_is_unavailable = true;

This is not sufficient to determine if the old sink is still available.
There are sinks
that do not have ports (null-sink, virtual sinks). I think you will
need
another boolean
argument to the function which indicates availability of the old sink.

The definition of an unavailable sink is that its active port is
unavailable. I don't know what kind of sinks you're thinking about
here, maybe virtual sinks that are on top of an unavailable hardware
sink? There are many places where we check the availability of a sink
this way, and I don't think it makes sense to be different here.

I don't understand. Virtual sinks don't have ports. So checking only
sinks that have an active port excludes all sinks that don't have
ports like the null-sink and virtual sinks. Following your definition
above, those sinks are never available.

You have it reversed: following my definition above, those sinks are
always available.

Right, sorry. (I seem to be reading things wrong quite often
the last few weeks ... I'll do my best to be more thorough in
the future.)



Checking the code, only alsa, bluetooth and raop sinks define ports and
the "many places" you are referring to are compare_sinks() and
compare_sources() in core.c and a check in module-switch-on-connect,
which is used to determine the availability of the default sink.

At least module-stream-restore checks device availability too (although
probably not anymore after this patch set, because module-stream-
restore won't do the routing directly anymore, it will just restore the
preferred_sink variable, which can be done regardless of the sink
availability).

Extending the hardware sink availability to filter sinks probably makes
sense, but I think that's a topic for a separate patch (or patches).

You suggested an extra flag for pa_sink_move_streams_to_default_sink(),
which seems unnecessary to me. The function can in any case figure out
the availability by itself (possibly using a helper function
pa_sink_is_available() that can handle filter sinks too).

I think some additional check is still needed at least for 
s->unlink_requested

because when a sink is going to be unlinked and the function is called from
pa_sink_unlink() in patch 7, there may be nothing else that indicates 
that the

sink is going to be removed. When I proposed an additional argument, I did
not see that pa_sink_unlink() already sets a flag that can be used.

So I would suggest that the helper function checks on
- link state
- port availability
- s->unlink_requested
- suspend state (any reason apart from SUSPEND_IDLE)

Using the helper function in other places (and extending it if I forgot 
something
in the list above) could then be done in a separate patch. Are you OK 
with that?



___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-07-02 Thread Georg Chini

On 02.07.19 08:43, Tanu Kaskinen wrote:

On Mon, 2019-07-01 at 08:03 +0200, Georg Chini wrote:

On 01.07.19 07:08, Tanu Kaskinen wrote:

On Sun, 2019-06-30 at 13:52 +0200, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:

When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the preferred_sink
string is set to the old default sink and the active port of the old
default sink is not unavailable

Signed-off-by: Hui Wang 
---
src/modules/dbus/iface-core.c   |  2 +-
src/modules/module-default-device-restore.c |  2 +-
src/modules/module-switch-on-connect.c  | 27 ++--
src/pulsecore/cli-command.c |  2 +-
src/pulsecore/core.c| 10 --
src/pulsecore/core.h|  4 +--
src/pulsecore/device-port.c |  2 +-
src/pulsecore/protocol-native.c |  2 +-
src/pulsecore/sink.c| 35 +++--
src/pulsecore/sink.h|  6 
10 files changed, 54 insertions(+), 38 deletions(-)

diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
index 5229c0467..9763480d2 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -721,7 +721,7 @@ static void handle_set_fallback_sink(DBusConnection *conn, 
DBusMessage *msg, DBu
return;
}

-pa_core_set_configured_default_sink(c->core, pa_dbusiface_device_get_sink(fallback_sink)->name);

+pa_core_set_configured_default_sink(c->core, 
pa_dbusiface_device_get_sink(fallback_sink)->name, true);

pa_dbus_send_empty_reply(conn, msg);

}
diff --git a/src/modules/module-default-device-restore.c 
b/src/modules/module-default-device-restore.c
index c4dbad99f..33e74c071 100644
--- a/src/modules/module-default-device-restore.c
+++ b/src/modules/module-default-device-restore.c
@@ -69,7 +69,7 @@ static void load(struct userdata *u) {
pa_log_warn("Invalid sink name: %s", ln);
else {
pa_log_info("Restoring default sink '%s'.", ln);
-pa_core_set_configured_default_sink(u->core, ln);
+pa_core_set_configured_default_sink(u->core, ln, false);
}

} else if (errno != ENOENT)

diff --git a/src/modules/module-switch-on-connect.c 
b/src/modules/module-switch-on-connect.c
index f0cb29a7c..3ceac8b4f 100644
--- a/src/modules/module-switch-on-connect.c
+++ b/src/modules/module-switch-on-connect.c
@@ -54,9 +54,6 @@ struct userdata {
};

static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* userdata) {

-pa_sink_input *i;
-uint32_t idx;
-pa_sink *old_default_sink;
const char *s;
struct userdata *u = userdata;

@@ -88,7 +85,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*

/* No default sink, nothing to move away, just set the new default */

if (!c->default_sink) {
-pa_core_set_configured_default_sink(c, sink->name);
+pa_core_set_configured_default_sink(c, sink->name, false);
return PA_HOOK_OK;
}

@@ -103,28 +100,8 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*

return PA_HOOK_OK;
}

-old_default_sink = c->default_sink;

-
/* Actually do the switch to the new sink */
-pa_core_set_configured_default_sink(c, sink->name);
-
-/* Now move all old inputs over */
-if (pa_idxset_size(old_default_sink->inputs) <= 0) {
-pa_log_debug("No sink inputs to move away.");
-return PA_HOOK_OK;
-}
-
-PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) {
-if (pa_safe_streq(i->sink->name, i->preferred_sink) || 
!PA_SINK_INPUT_IS_LINKED(i->state))
-continue;
-
-if (pa_sink_input_move_to(i, sink, false) < 0)
-pa_log_info("Failed to move sink input %u \"%s\" to %s.", i->index,
-pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);
-else
-pa_log_info("Successfully moved sink input %u \"%s\" to %s.", 
i->index,
-pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);
-}
+pa_core_set_configured_default_sink(c, sink->name, false);

I wonder if we could use something like
pa_core_set_temporary_default_sink() here
and have a variable core->temporary_default_sink that has even higher
priority
than core->configured_default_sink in the default sink selection
process. The temporary
default sink could be reset when the sink vanishes again or replaced
when another new
sink turns up. What mod

Re: [pulseaudio-discuss] [PATCH v2 7/8] sink: move the streams to the default_sink when the sink is unlinked

2019-07-01 Thread Georg Chini

On 17.01.19 07:53, Hui Wang wrote:

When a sink is unlinked, all streams of this sink are moved to
default_sink, this action is implemented in the core rather than
modules now.

Signed-off-by: Hui Wang 
---
  src/modules/module-stream-restore.c | 50 -
  src/pulsecore/sink.c|  3 ++
  2 files changed, 3 insertions(+), 50 deletions(-)


module-rescue-stream also has to be modified to reflect
that change. It should now only rescue source streams.
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-06-30 Thread Georg Chini

On 01.07.19 08:03, Georg Chini wrote:

On 01.07.19 07:08, Tanu Kaskinen wrote:

On Sun, 2019-06-30 at 13:52 +0200, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:

When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the preferred_sink
string is set to the old default sink and the active port of the old
default sink is not unavailable





   +
+void pa_sink_move_streams_to_default_sink(pa_core *core, pa_sink 
*old_sink, bool from_user) {

+    pa_sink_input *i;
+    uint32_t idx;
+    bool old_sink_is_unavailable;

Does this not give a warning about using uninitialized variables?

+
+    pa_assert(core);
+    pa_assert(old_sink);
+
+    if (old_sink == core->default_sink)
+    return;
+
+    if (old_sink->active_port && old_sink->active_port->available 
== PA_AVAILABLE_NO)

+    old_sink_is_unavailable = true;

This is not sufficient to determine if the old sink is still available.
There are sinks
that do not have ports (null-sink, virtual sinks). I think you will 
need

another boolean
argument to the function which indicates availability of the old sink.

The definition of an unavailable sink is that its active port is
unavailable. I don't know what kind of sinks you're thinking about
here, maybe virtual sinks that are on top of an unavailable hardware
sink? There are many places where we check the availability of a sink
this way, and I don't think it makes sense to be different here.


I don't understand. Virtual sinks don't have ports. So checking only
sinks that have an active port excludes all sinks that don't have
ports like the null-sink and virtual sinks. Following your definition
above, those sinks are never available.



Checking the code, only alsa, bluetooth and raop sinks define ports and
the "many places" you are referring to are compare_sinks() and
compare_sources() in core.c and a check in module-switch-on-connect,
which is used to determine the availability of the default sink.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-06-30 Thread Georg Chini

On 01.07.19 07:08, Tanu Kaskinen wrote:

On Sun, 2019-06-30 at 13:52 +0200, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:

When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the preferred_sink
string is set to the old default sink and the active port of the old
default sink is not unavailable

Signed-off-by: Hui Wang 
---
   src/modules/dbus/iface-core.c   |  2 +-
   src/modules/module-default-device-restore.c |  2 +-
   src/modules/module-switch-on-connect.c  | 27 ++--
   src/pulsecore/cli-command.c |  2 +-
   src/pulsecore/core.c| 10 --
   src/pulsecore/core.h|  4 +--
   src/pulsecore/device-port.c |  2 +-
   src/pulsecore/protocol-native.c |  2 +-
   src/pulsecore/sink.c| 35 +++--
   src/pulsecore/sink.h|  6 
   10 files changed, 54 insertions(+), 38 deletions(-)

diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
index 5229c0467..9763480d2 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -721,7 +721,7 @@ static void handle_set_fallback_sink(DBusConnection *conn, 
DBusMessage *msg, DBu
   return;
   }
   
-pa_core_set_configured_default_sink(c->core, pa_dbusiface_device_get_sink(fallback_sink)->name);

+pa_core_set_configured_default_sink(c->core, 
pa_dbusiface_device_get_sink(fallback_sink)->name, true);
   
   pa_dbus_send_empty_reply(conn, msg);

   }
diff --git a/src/modules/module-default-device-restore.c 
b/src/modules/module-default-device-restore.c
index c4dbad99f..33e74c071 100644
--- a/src/modules/module-default-device-restore.c
+++ b/src/modules/module-default-device-restore.c
@@ -69,7 +69,7 @@ static void load(struct userdata *u) {
   pa_log_warn("Invalid sink name: %s", ln);
   else {
   pa_log_info("Restoring default sink '%s'.", ln);
-pa_core_set_configured_default_sink(u->core, ln);
+pa_core_set_configured_default_sink(u->core, ln, false);
   }
   
   } else if (errno != ENOENT)

diff --git a/src/modules/module-switch-on-connect.c 
b/src/modules/module-switch-on-connect.c
index f0cb29a7c..3ceac8b4f 100644
--- a/src/modules/module-switch-on-connect.c
+++ b/src/modules/module-switch-on-connect.c
@@ -54,9 +54,6 @@ struct userdata {
   };
   
   static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* userdata) {

-pa_sink_input *i;
-uint32_t idx;
-pa_sink *old_default_sink;
   const char *s;
   struct userdata *u = userdata;
   
@@ -88,7 +85,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
   
   /* No default sink, nothing to move away, just set the new default */

   if (!c->default_sink) {
-pa_core_set_configured_default_sink(c, sink->name);
+pa_core_set_configured_default_sink(c, sink->name, false);
   return PA_HOOK_OK;
   }
   
@@ -103,28 +100,8 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*

   return PA_HOOK_OK;
   }
   
-old_default_sink = c->default_sink;

-
   /* Actually do the switch to the new sink */
-pa_core_set_configured_default_sink(c, sink->name);
-
-/* Now move all old inputs over */
-if (pa_idxset_size(old_default_sink->inputs) <= 0) {
-pa_log_debug("No sink inputs to move away.");
-return PA_HOOK_OK;
-}
-
-PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) {
-if (pa_safe_streq(i->sink->name, i->preferred_sink) || 
!PA_SINK_INPUT_IS_LINKED(i->state))
-continue;
-
-if (pa_sink_input_move_to(i, sink, false) < 0)
-pa_log_info("Failed to move sink input %u \"%s\" to %s.", i->index,
-pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);
-else
-pa_log_info("Successfully moved sink input %u \"%s\" to %s.", 
i->index,
-pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);
-}
+pa_core_set_configured_default_sink(c, sink->name, false);

I wonder if we could use something like
pa_core_set_temporary_default_sink() here
and have a variable core->temporary_default_sink that has even higher
priority
than core->configured_default_sink in the default sink selection
process. The temporary
default sink could be reset when the sink vanishes again or replaced
when another new
sink turns up. What module-switch-on-connect does is to temporarily
override the default
sink that the user configured. If we save this in another variable we
woul

[pulseaudio-discuss] Resampler rewinding

2019-06-30 Thread Georg Chini

Hi Tanu,

Here a new picture:

DIAGRAM FOR HARDWARE SINK 1 BEFORE STARTING THE MOVE (OR BEFORE STARTING A 
REWIND)

+-+-
|   client stream memblockq 
  |
+-+-

  ^ read index
 
   +--+

   | data in the client 
resampler |
   
+--+

+--+
|  client render_memblockq  | queue length |
+--+
^ read index   ^ write index

+---+-+---+-
|  client history_queue | length equal to resampler data  |   queue length  
  |
+---+-+---+-
  ^ read index  
  ^write index
+
   |  dma buffer|
+
   ^ hardware playback position,
 can't rewind beyond this point


What you can see in this picture is, that the difference between the render 
memblockq
read index and the history queue read index will always equal the amount of 
data in the
resampler, even if that amount is varying. So rewinding the history queue by 
the same
amount as the render memblockq plus the resampler delay ensures, that after the 
rewind
the read index of both queues is equal.
The render memblockq plus resampler data and the history queue data are 
completely
equivalent, just in different sample specs. Read and write index of the history
queue are both ahead of the render queue by the amount of data in the resampler.
The equivalence ensures that an operation done on one queue can be mirrored to 
the
other queue.

Meanwhile I changed the SOXR resampler to use variable rate. This makes it 
behave like
all the other resamplers do. Probably I could try your approach again, but I 
still think
my solution is more elegant than trying to force the queue into the audio flow 
somehow.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 6/8] device-port: moving streams due to changing the status of active_port

2019-06-30 Thread Georg Chini

On 30.06.19 14:52, Georg Chini wrote:

On 17.01.19 07:53, Hui Wang wrote:

When the active port of a sink becomes unavailable, all streams from
that sink should be moved to the default sink.

When the active port of a sink changes state from unavailable, all
streams that have their preferred_sink set to this sink should be moved
to this sink.


Is that necessary at all? If an additional port becomes available
or unavailable (lets say I plug in/out head phones) the sink does
not change. Only if the last port becomes available/unavailable
the sink also becomes available/unavailable and in that case the
switch to/from the sink will be handled elsewhere.

Or am I thinking wrong?



Well, I was thinking wrong. I understand now why it is needed,
so forget my previous mail.

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 6/8] device-port: moving streams due to changing the status of active_port

2019-06-30 Thread Georg Chini

On 17.01.19 07:53, Hui Wang wrote:

When the active port of a sink becomes unavailable, all streams from
that sink should be moved to the default sink.

When the active port of a sink changes state from unavailable, all
streams that have their preferred_sink set to this sink should be moved
to this sink.


Is that necessary at all? If an additional port becomes available
or unavailable (lets say I plug in/out head phones) the sink does
not change. Only if the last port becomes available/unavailable
the sink also becomes available/unavailable and in that case the
switch to/from the sink will be handled elsewhere.

Or am I thinking wrong?

___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 7/8] sink: move the streams to the default_sink when the sink is unlinked

2019-06-30 Thread Georg Chini

On 17.01.19 07:53, Hui Wang wrote:

When a sink is unlinked, all streams of this sink are moved to
default_sink, this action is implemented in the core rather than
modules now.

Signed-off-by: Hui Wang 
---
  src/modules/module-stream-restore.c | 50 -
  src/pulsecore/sink.c|  3 ++
  2 files changed, 3 insertions(+), 50 deletions(-)

diff --git a/src/modules/module-stream-restore.c 
b/src/modules/module-stream-restore.c
index c7a5f228a..fd3acb5bd 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -96,7 +96,6 @@ struct userdata {
  *source_output_new_hook_slot,
  *source_output_fixate_hook_slot,
  *source_put_hook_slot,
-*sink_unlink_hook_slot,
  *source_unlink_hook_slot,
  *connection_unlink_hook_slot;
  pa_time_event *save_time_event;
@@ -1691,54 +1690,6 @@ static pa_hook_result_t source_put_hook_callback(pa_core 
*c, pa_source *source,
  return PA_HOOK_OK;
  }
  
-static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {

-pa_sink_input *si;
-uint32_t idx;
-
-pa_assert(c);
-pa_assert(sink);
-pa_assert(u);
-pa_assert(u->on_rescue && u->restore_device);
-
-/* There's no point in doing anything if the core is shut down anyway */
-if (c->state == PA_CORE_SHUTDOWN)
-return PA_HOOK_OK;
-
-PA_IDXSET_FOREACH(si, sink->inputs, idx) {
-char *name;
-struct entry *e;
-
-if (!si->sink)
-continue;
-
-/* Skip this sink input if it is connecting a filter sink to
- * the master */
-if (si->origin_sink)
-continue;
-
-if (!(name = pa_proplist_get_stream_group(si->proplist, "sink-input", 
IDENTIFICATION_PROPERTY)))
-continue;
-
-if ((e = entry_read(u, name))) {
-
-if (e->device_valid) {
-pa_sink *d;
-
-if ((d = pa_namereg_get(c, e->device, PA_NAMEREG_SINK)) &&
-d != sink &&
-PA_SINK_IS_LINKED(d->state))
-pa_sink_input_move_to(si, d, true);
-}
-
-entry_free(e);
-}
-
-pa_xfree(name);
-}
-
-return PA_HOOK_OK;
-}
-
  static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source 
*source, struct userdata *u) {
  pa_source_output *so;
  uint32_t idx;
@@ -2420,7 +2371,6 @@ int pa__init(pa_module*m) {
  
  if (restore_device && on_rescue) {

  /* A little bit earlier than module-intended-roles, 
module-rescue-streams, ... */
-pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], 
PA_HOOK_LATE, (pa_hook_cb_t) sink_unlink_hook_callback, u);
  pa_module_hook_connect(m, 
&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) 
source_unlink_hook_callback, u);
  }
  
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c

index cf43a78e8..d7973b7c9 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -745,6 +745,9 @@ void pa_sink_unlink(pa_sink* s) {
  
  linked = PA_SINK_IS_LINKED(s->state);
  
+if (linked)

+pa_sink_move_streams_to_default_sink(s->core, s, false);
+


This is called too early. It might be the current default sink that we 
are unlinking.



  if (linked)
  pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_UNLINK], s);
  



___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 4/8] core: move sink-inputs conditionally when update default_sink

2019-06-30 Thread Georg Chini

On 17.01.19 07:53, Hui Wang wrote:

When the default sink changes, the streams from the old default sink
should be moved to the new default sink, unless the preferred_sink
string is set to the old default sink and the active port of the old
default sink is not unavailable

Signed-off-by: Hui Wang 
---
  src/modules/dbus/iface-core.c   |  2 +-
  src/modules/module-default-device-restore.c |  2 +-
  src/modules/module-switch-on-connect.c  | 27 ++--
  src/pulsecore/cli-command.c |  2 +-
  src/pulsecore/core.c| 10 --
  src/pulsecore/core.h|  4 +--
  src/pulsecore/device-port.c |  2 +-
  src/pulsecore/protocol-native.c |  2 +-
  src/pulsecore/sink.c| 35 +++--
  src/pulsecore/sink.h|  6 
  10 files changed, 54 insertions(+), 38 deletions(-)

diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
index 5229c0467..9763480d2 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -721,7 +721,7 @@ static void handle_set_fallback_sink(DBusConnection *conn, 
DBusMessage *msg, DBu
  return;
  }
  
-pa_core_set_configured_default_sink(c->core, pa_dbusiface_device_get_sink(fallback_sink)->name);

+pa_core_set_configured_default_sink(c->core, 
pa_dbusiface_device_get_sink(fallback_sink)->name, true);
  
  pa_dbus_send_empty_reply(conn, msg);

  }
diff --git a/src/modules/module-default-device-restore.c 
b/src/modules/module-default-device-restore.c
index c4dbad99f..33e74c071 100644
--- a/src/modules/module-default-device-restore.c
+++ b/src/modules/module-default-device-restore.c
@@ -69,7 +69,7 @@ static void load(struct userdata *u) {
  pa_log_warn("Invalid sink name: %s", ln);
  else {
  pa_log_info("Restoring default sink '%s'.", ln);
-pa_core_set_configured_default_sink(u->core, ln);
+pa_core_set_configured_default_sink(u->core, ln, false);
  }
  
  } else if (errno != ENOENT)

diff --git a/src/modules/module-switch-on-connect.c 
b/src/modules/module-switch-on-connect.c
index f0cb29a7c..3ceac8b4f 100644
--- a/src/modules/module-switch-on-connect.c
+++ b/src/modules/module-switch-on-connect.c
@@ -54,9 +54,6 @@ struct userdata {
  };
  
  static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* userdata) {

-pa_sink_input *i;
-uint32_t idx;
-pa_sink *old_default_sink;
  const char *s;
  struct userdata *u = userdata;
  
@@ -88,7 +85,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
  
  /* No default sink, nothing to move away, just set the new default */

  if (!c->default_sink) {
-pa_core_set_configured_default_sink(c, sink->name);
+pa_core_set_configured_default_sink(c, sink->name, false);
  return PA_HOOK_OK;
  }
  
@@ -103,28 +100,8 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*

  return PA_HOOK_OK;
  }
  
-old_default_sink = c->default_sink;

-
  /* Actually do the switch to the new sink */
-pa_core_set_configured_default_sink(c, sink->name);
-
-/* Now move all old inputs over */
-if (pa_idxset_size(old_default_sink->inputs) <= 0) {
-pa_log_debug("No sink inputs to move away.");
-return PA_HOOK_OK;
-}
-
-PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) {
-if (pa_safe_streq(i->sink->name, i->preferred_sink) || 
!PA_SINK_INPUT_IS_LINKED(i->state))
-continue;
-
-if (pa_sink_input_move_to(i, sink, false) < 0)
-pa_log_info("Failed to move sink input %u \"%s\" to %s.", i->index,
-pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);
-else
-pa_log_info("Successfully moved sink input %u \"%s\" to %s.", 
i->index,
-pa_strnull(pa_proplist_gets(i->proplist, 
PA_PROP_APPLICATION_NAME)), sink->name);
-}
+pa_core_set_configured_default_sink(c, sink->name, false);


I wonder if we could use something like 
pa_core_set_temporary_default_sink() here
and have a variable core->temporary_default_sink that has even higher 
priority
than core->configured_default_sink in the default sink selection 
process. The temporary
default sink could be reset when the sink vanishes again or replaced 
when another new
sink turns up. What module-switch-on-connect does is to temporarily 
override the default
sink that the user configured. If we save this in another variable we 
would not overwrite
the user configured default sink by a sink that is not expected to be 
present the next

time PA is started. But that would be just nice to have.

  
  return PA_HOOK_OK;

  }
diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c
index 5205349bd..cc7addaa1

Re: [pulseaudio-discuss] [PATCH v2 3/8] sink-input: clear the preferred_sink if it is default_sink

2019-06-30 Thread Georg Chini

On 17.01.19 07:53, Hui Wang wrote:

When the user moves a stream to the current default sink, the
preferred_sink should be set to NULL and module-stream-restore
should clear the routing for that stream in the stream database. From
that point on the stream will be always routed to the default sink.

Signed-off-by: Hui Wang 
---
  src/modules/module-stream-restore.c | 19 ++-
  src/pulsecore/sink-input.c  |  6 +-
  2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/src/modules/module-stream-restore.c 
b/src/modules/module-stream-restore.c
index 366f1a5a8..142d1e3b4 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -1311,13 +1311,22 @@ static void subscribe_callback(pa_core *c, 
pa_subscription_event_type_t t, uint3
  mute_updated = !created_new_entry && (!old->muted_valid || 
entry->muted != old->muted);
  }
  
-if (sink_input->preferred_sink != NULL) {

+if (sink_input->preferred_sink != NULL || !created_new_entry) {
  pa_xfree(entry->device);
-entry->device = pa_xstrdup(sink_input->preferred_sink);
-entry->device_valid = true;
+if (sink_input->preferred_sink != NULL) {
+entry->device = pa_xstrdup(sink_input->preferred_sink);
+entry->device_valid = true;
+} else {
+entry->device = NULL;
+entry->device_valid = false;
+}
  
-device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry->device, old->device));

-if (sink_input->sink->card) {
+device_updated = !created_new_entry && !pa_safe_streq(entry->device, 
old->device);
+if (entry->device_valid == false) {
+pa_xfree(entry->card);
+entry->card = NULL;
+entry->card_valid = false;
+} else {
  pa_xfree(entry->card);
  entry->card = pa_xstrdup(sink_input->sink->card->name);
  entry->card_valid = true;
You still need to check sink_input->sink->card. The virtual sinks don't 
have a card,

so it may well be that the device is valid but there is no card.
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v2 2/8] sink-input: add a new API pa_sink_input_set_preferred_sink

2019-06-30 Thread Georg Chini

Sorry for the late feedback.

On 17.01.19 07:53, Hui Wang wrote:

If the sink here is NULL, that means users want to clear the
preferred_sink and move the sink-input to the default_sink, otherwise
set the preferred_sink to the sink->name and move the sink-input to
the sink. After that fire the sink_input_change event.

After adding this API, we can use this API to simplify the entry_apply
in the module-stream-restore.c.

Signed-off-by: Hui Wang 
---
  src/modules/module-stream-restore.c | 10 ++
  src/pulsecore/sink-input.c  | 14 ++
  src/pulsecore/sink-input.h  |  2 ++
  3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/src/modules/module-stream-restore.c 
b/src/modules/module-stream-restore.c
index a8c6a42c5..366f1a5a8 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -1953,18 +1953,12 @@ static void entry_apply(struct userdata *u, const char 
*name, struct entry *e) {
 preferred_sink is cleared as the user may have 
specifically
 removed the sink element from the rule. */
  pa_xfree(si->preferred_sink);
-si->preferred_sink = NULL;
-/* This is cheating a bit. The sink input itself has not 
changed
-   but the rules governing its routing have, so we fire 
this event
-   such that other routing modules (e.g. 
module-device-manager)
-   will pick up the change and reapply their routing */
-pa_subscription_post(si->core, 
PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, si->index);
+pa_sink_input_set_preferred_sink(si, NULL);
  }
  } else if ((s = pa_namereg_get(u->core, e->device, 
PA_NAMEREG_SINK))) {
  pa_log_info("Restoring device for stream %s.", name);
-pa_sink_input_move_to(si, s, true);
  pa_xfree(si->preferred_sink);
-si->preferred_sink = pa_xstrdup(s->name);
+pa_sink_input_set_preferred_sink(si, s);
  }
  }
  }
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index f41eacf07..4dbc0cdef 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -2416,3 +2416,17 @@ void pa_sink_input_set_reference_ratio(pa_sink_input *i, 
const pa_cvolume *ratio
   pa_cvolume_snprint_verbose(old_ratio_str, sizeof(old_ratio_str), 
&old_ratio, &i->channel_map, true),
   pa_cvolume_snprint_verbose(new_ratio_str, sizeof(new_ratio_str), 
ratio, &i->channel_map, true));
  }
+
+/* Called from the main thread. */
+void pa_sink_input_set_preferred_sink(pa_sink_input *i, pa_sink *s) {
+pa_assert(i);
+
+if (s) {
+i->preferred_sink = pa_xstrdup(s->name);
+pa_sink_input_move_to(i, s, true);
+} else {
+i->preferred_sink = NULL;
+pa_sink_input_move_to(i, i->core->default_sink, true);
+}
+pa_subscription_post(i->core, 
PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
+}
You do not have to send the subscription event here, 
pa_sink_input_finish_move()

will already send the event.
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

  1   2   3   4   5   6   7   8   9   10   >