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

2020-04-29 Thread Pali Rohár
On Wednesday 29 April 2020 01:57:14 Jim Kent wrote:
> 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?

Yes, you need to disallow access to /dev/snd/... devices for your
application. E.g. by permissions, ACLs or MAC (selinux / apparmor) or by
chrooting (without providing these devices) or running in container
(again without those devices). Just choose your favourite sandboxing
technique.

> Could something like Jack accomplish this?

No, application can again ignore jack and access sound hardware, just
like it did with pulseaudio.

You can e.g. play with "amixer" application. If you run it as
"amixer -D pulse" it will connect to pulseaudio (via unix socket) and
show mixer control which pulseaudio told it. If you run it with
"amixer -c 0" it will directly access sound card 0 (via /dev/snd/...)
and show state of sound card 0.

-- 
Pali Rohár
pali.ro...@gmail.com
___
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 Pali Rohár
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).

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.

-- 
Pali Rohár
pali.ro...@gmail.com
___
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 Pali Rohár
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.

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).

-- 
Pali Rohár
pali.ro...@gmail.com
___
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 Pali Rohár
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?

-- 
Pali Rohár
pali.ro...@gmail.com
___
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 Pali Rohár
On Tuesday 28 April 2020 16:33:01 Tanu Kaskinen wrote:
> On Tue, 2020-04-28 at 13:08 +0200, Pali Rohár wrote:
> > On Tuesday 28 April 2020 13:57:42 Tanu Kaskinen wrote:
> > > Just to chime in on the ofono removal issue: I'm also of the opinion
> > > that removing ofono support is not an option.
> > 
> > Well, in this case you have 3 choices:
> > 
> > * Fix it yourself or find somebody who will work on it and would maintain 
> > this code in future
> > * Try asking ofono community to start cooperate and tell them start
> >   working and fixing that pulseaudio ofono code (including future 
> > maintenance)
> > * Do not take my now fully working hsphpfd support in pulseaudio and do not 
> > implement HSP and HFP profiles properly in pulseaudio at all
> > 
> > I'm not going to spend another time with ofono and its buggy audio
> > support, I tried it and it was waste of time, and specially now when
> > ofono community is not interested in cooperation; and I have working
> > better alternative suitable also for supporting other parts (like
> > battery support, input button support, etc...)
> > 
> > And... what is the purpose of buggy ofono backend support in pulseaudio,
> > now when I provided better code HSP and HFP profiles?
> 
> Last year a Collabora developer made a patch that fixed a crash in the
> oFono backend. I assume their customer is using PulseAudio with oFono,
> so I would also assume that it's not so buggy that it's useless (and
> indeed, Georg reports that it's working fine for him). oFono also
> integrates HFP to the telephony stack, which hsphfpd doesn't do.

Also there are lot of users for which HFP profile via current ofono
pulseaudio implementation does not work, see tons of bugs in issue
tracker and tons of blames for pulseaudio and its totally broken and
non-working microphone bluetooth support on internet forums. And I
understand it, for majority of people it does not work.

Really look at reality, bluetooth microphone support in pulseaudio is
worse then poor. And *nobody* did anything in pulseaudio for years.
I was able to implement now everything related to bluetooth audio.

Is that Collabora developer going to implement all missing, needed and
broken stuff in next days? Or at least next weeks/months? If not, who
other is going to handle all those bluetooth problems? Or do you think
that everything is working fine and there is no need to do anything with
bluetooth related code?

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.

I spend lot of time to understand how is that bluetooth related stuff
working, what is needed for implementation, designed it and implemented.
It is not easy task and I can say that I understand now all parts of
A2DP, HSP and HFP profiles, including how SCO and A2DP audio socket /
transfer works.

Do you think that I'm saying something which is wrong, does not make
sense or could be in better way? If yes, please show me it, so I can
improve that bluetooth parts.

-- 
Pali Rohár
pali.ro...@gmail.com
___
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 Pali Rohár
On Tuesday 28 April 2020 13:57:42 Tanu Kaskinen wrote:
> Just to chime in on the ofono removal issue: I'm also of the opinion
> that removing ofono support is not an option.

Well, in this case you have 3 choices:

* Fix it yourself or find somebody who will work on it and would maintain this 
code in future
* Try asking ofono community to start cooperate and tell them start
* working and fixing that pulseaudio ofono code (including future maintenance)
* Do not take my now fully working hsphpfd support in pulseaudio and do not 
implement HSP and HFP profiles properly in pulseaudio at all

I'm not going to spend another time with ofono and its buggy audio
support, I tried it and it was waste of time, and specially now when
ofono community is not interested in cooperation; and I have working
better alternative suitable also for supporting other parts (like
battery support, input button support, etc...)

And... what is the purpose of buggy ofono backend support in pulseaudio,
now when I provided better code HSP and HFP profiles?

-- 
Pali Rohár
pali.ro...@gmail.com
___
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 Pali Rohár
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).

-- 
Pali Rohár
pali.ro...@gmail.com
___
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 Pali Rohár
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 ...

> Like ofono, without the option, hsphfpd would register both roles.

-- 
Pali Rohár
pali.ro...@gmail.com
___
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 Pali Rohár
On Monday 27 April 2020 21:45:47 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.

Well, this is one of the reason why central proxy daemon (like hsphfpd)
is needed for HSP and HFP profile, which just proxies relevant part of
HSP and HFP connections to relevant application. And reason why I
started with this design. It allows to implement both telephony and
audio parts independently in target application, audio in pulseaudio,
telephony in modem application, without any dependence between these two
applications.

Otherwise you would have to choose which application you want to use
either modem, either audio, either input device, either battery status,
but not all of them at the same time... This is one of the key feature
of hsphpfd to solve this problem.

-- 
Pali Rohár
pali.ro...@gmail.com
___
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-26 Thread Pali Rohár
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. It is same problem as
coexistence of two TCP applications which both want to listen on same
TCP port bound to wildcard address.

Coexistence of two "fully and correctly written" HSP AG or HFP AG
applications is possible only in the case these two applications know
about themselves and they properly register and unregister from bluez at
correct time and also they drop active connections, shutdown and close
all sockets at correct time.

After long debugging I was able to fix pulseaudio's internal HSP AG
implementation to correctly unregister when hsphfpd appear in the system
and register when hsphfpd disappear in the system.

So at least internal HSP AG implementation with lot of my patches could
be compatible with hsphfpd.

-- 
Pali Rohár
pali.ro...@gmail.com
___
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-26 Thread Pali Rohár
On Tuesday 17 March 2020 13:06:52 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.

Done! Now I have working HSP and HFP profiles in pulseaudio via hsphfpd.
Also (asynchronous non-blocking) switching between them is working.

I pushed changes to hsphfpd branch of my pulseaudio fork repository:
https://gitlab.freedesktop.org/pali/pulseaudio/-/tree/hsphfpd

I opened also merge request for comments:
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/288

It is based on my A2DP changes. Please test it and let me know if there
are any problems.

Note that mere request is only WIP and therefore it lacks proper commit
messages, etc...

-- 
Pali Rohár
pali.ro...@gmail.com
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


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

2020-04-15 Thread Pali Rohár
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  | 655 +++-
 src/modules/bluetooth/a2dp-codec-util.c |  18 +-
 2 files changed, 534 insertions(+), 139 deletions(-)

diff --git a/src/modules/bluetooth/a2dp-codec-sbc.c 
b/src/modules/bluetooth/a2dp-codec-sbc.c
index ba47fa066..f275586ef 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 for EDR-2 and to
+ * be below max possible 512 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. */
+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 */
+};
+
+#undef FIXED_SBC_CAPS
+
+/* SBC Auto Quality, only one row which allow any possible configuration up to 
common High Quality */
+/* We need to ensure that bitrate is below max possible 512 kbps, therefore 
limit 

[pulseaudio-discuss] [PATCH v15 08/10] bluetooth: Add A2DP aptX and aptX HD codecs support

2020-04-15 Thread Pali Rohár
_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
diff --git a/src/modules/bluetooth/a2dp-codec-aptx.c 
b/src/modules/bluetooth/a2dp-codec-aptx.c
new file mode 100644
index 0..2d911d902
--- /dev/null
+++ b/src/modules/bluetooth/a2dp-codec-aptx.c
@@ -0,0 +1,522 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2018-2019 Pali Rohár 
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include 
+#endif
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+
+#include "a2dp-codecs.h"
+#include "a2dp-codec-api.h"
+#include "rtp.h"
+
+struct aptx_hd_info {
+struct aptx_context *aptx_c;
+uint16_t seq_num;
+};
+
+static bool can_accept_capabilities_common(const a2dp_aptx_t *capabilities, 
uint32_t vendor_id, uint16_t codec_id) {
+if (A2DP_GET_VENDOR_ID(capabilities->info) != vendor_id || 
A2DP_GET_CODEC_ID(capabilities->info) != codec_id)
+return false;
+
+if (!(capabilities->frequency & (APTX_SAMPLING_FREQ_16000 | 
APTX_SAMPLING_FREQ_32000 |
+ APTX_SAMPLING_FREQ_44100 | 
APTX_SAMPLING_FREQ_48000)))
+return false;
+
+if (!(capabilities->channel_mode & APTX_CHANNEL_MODE_STEREO))
+return false;
+
+return true;
+}
+
+static bool can_accept_capabilities(const uint8_t *capabilities_buffer, 
uint8_t capabilities_size, bool for_encoding) {
+const a2dp_aptx_t *capabilities = (const a2dp_aptx_t *) 
capabilities_buffer;
+
+if (capabilities_size != sizeof(*capabilities))
+return false;
+
+return can_accept_capabilities_common(capabilities, APTX_VENDOR_ID, 
APTX_CODEC_ID);
+}
+
+static bool can_accept_capabilities_hd(const uint8_t *capabilities_buffer, 
uint8_t capabilities_size, bool for_encoding) {
+const a2dp_aptx_hd_t *capabilities = (const a2dp_aptx_hd_t *) 
capabilities_buffer;
+
+if (capabilities_size != sizeof(*capabilities))
+return false;
+
+return can_accept_capabilities_common(>aptx, 
APTX_HD_VENDOR_ID, APTX_HD_CODEC_ID);
+}
+
+static int cmp_endpoints_common(const a2dp_aptx_t *capabilities1, const 
a2dp_aptx_t *capabilities2, const pa_sample_spec *default_sample_spec, bool 
for_encoding) {
+uint32_t freq1 = 0;
+uint32_t freq2 = 0;
+int i;
+
+static const struct {
+uint32_t rate;
+uint8_t cap;
+} freq_table[] = {
+{ 16000U, APTX_SAMPLING_FREQ_16000 },
+{ 32000U, APTX_SAMPLING_FREQ_32000 },
+{ 44100U, APTX_SAMPLING_FREQ_44100 },
+{ 48000U, APTX_SAMPLING_FREQ_48000 }
+};
+
+/* 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 (!freq1 && freq_table[i].rate >= default_sample_spec->rate && 
(capabilities1->frequency & freq_table[i].cap))
+freq1 = freq_table[i].rate;
+if (!freq2 && freq_table[i].rate >= default_sample_spec->rate && 
(capabilities2->frequency & freq_table[i].cap))
+freq2 = freq_table[i].rate;
+if (freq1 && freq2)
+break;
+}
+
+/* Prefer endpoint which frequency is near to default sample rate */
+if (freq1 && freq2) {
+if (freq1 < freq2)
+return -1;
+if (freq1 > freq2)
+return 1;
+} else if (freq1) {
+return freq1;
+} else if (freq2) {
+return freq2;
+} else {
+for (i = PA_ELEMENTSOF(freq_table)-1; i >= 0; i--) {
+if (capabilities1->frequency & freq_table[i].cap)
+freq1 = freq_table[i].rate;
+if (capabilities2->frequency & freq_table[i].cap)
+freq2 = freq_table[i].rate;
+if (freq1 && freq2)
+break;
+}
+pa_assert(i >= 0);
+
+if (freq1 > freq2)
+return -1;
+if (freq2 < freq1)
+   

[pulseaudio-discuss] [PATCH v15 09/10] bluetooth: Add A2DP FastStream codec support

2020-04-15 Thread Pali Rohár
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 | 566 ++
 src/modules/bluetooth/a2dp-codec-util.c   |   4 +
 src/modules/bluetooth/meson.build |   1 +
 4 files changed, 573 insertions(+)
 create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 0842a7bd5..83d8ef7d3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2172,6 +2172,8 @@ libbluez5_util_la_SOURCES += 
modules/bluetooth/a2dp-codec-sbc.c
 libbluez5_util_la_LIBADD += $(SBC_LIBS)
 libbluez5_util_la_CFLAGS += $(SBC_CFLAGS)
 
+libbluez5_util_la_SOURCES += modules/bluetooth/a2dp-codec-faststream.c
+
 if HAVE_OPENAPTX
 libbluez5_util_la_SOURCES += modules/bluetooth/a2dp-codec-aptx.c
 libbluez5_util_la_CPPFLAGS += $(OPENAPTX_CPPFLAGS)
diff --git a/src/modules/bluetooth/a2dp-codec-faststream.c 
b/src/modules/bluetooth/a2dp-codec-faststream.c
new file mode 100644
index 0..973464deb
--- /dev/null
+++ b/src/modules/bluetooth/a2dp-codec-faststream.c
@@ -0,0 +1,566 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2018-2019 Pali Rohár 
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include 
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "a2dp-codecs.h"
+#include "a2dp-codec-api.h"
+
+struct faststream_info {
+sbc_t sbc;   /* Codec data */
+size_t codesize, frame_length;   /* SBC Codesize, frame_length. We 
simply cache those values here */
+bool is_microphone;
+uint8_t frequency;
+};
+
+static bool can_accept_capabilities(const uint8_t *capabilities_buffer, 
uint8_t capabilities_size, bool for_encoding) {
+const a2dp_faststream_t *capabilities = (const a2dp_faststream_t *) 
capabilities_buffer;
+
+if (capabilities_size != sizeof(*capabilities))
+return false;
+
+if (A2DP_GET_VENDOR_ID(capabilities->info) != FASTSTREAM_VENDOR_ID || 
A2DP_GET_CODEC_ID(capabilities->info) != FASTSTREAM_CODEC_ID)
+return false;
+
+if (!(capabilities->direction & FASTSTREAM_DIRECTION_SINK))
+return false;
+
+if (!(capabilities->sink_frequency & (FASTSTREAM_SINK_SAMPLING_FREQ_44100 
| FASTSTREAM_SINK_SAMPLING_FREQ_48000)))
+return false;
+
+return true;
+}
+
+static bool can_accept_capabilities_mic(const uint8_t *capabilities_buffer, 
uint8_t capabilities_size, bool for_encoding) {
+const a2dp_faststream_t *capabilities = (const a2dp_faststream_t *) 
capabilities_buffer;
+
+if (!can_accept_capabilities(capabilities_buffer, capabilities_size, 
for_encoding))
+return false;
+
+if (!(capabilities->direction & FASTSTREAM_DIRECTION_SOURCE))
+return false;
+
+if (!(capabilities->source_frequency & 
FASTSTREAM_SOURCE_SAMPLING_FREQ_16000))
+return false;
+
+return true;
+}
+
+static int cmp_endpoints_common(const uint8_t *capabilities1_buffer, uint8_t 
capabilities1_size, const uint8_t *capabilities2_buffer, uint8_t 
capabilities2_size, const pa_sample_spec *default_sample_spec, bool 
for_encoding, bool with_mic) {
+const a2dp_faststream_t *capabilities1 = (const a2dp_faststream_t *) 
capabilities1_buffer;
+const a2dp_faststream_t 

[pulseaudio-discuss] [PATCH v15 07/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2020-04-15 Thread Pali Rohár
Previously module-bluetooth-policy was switching from A2DP to HSP profile
when VOIP application started recording of source. Now it switch to profile
with the highest priority which has both sink and source. In most cases it
is HSP profile, but it can be also bi-directional A2DP profile (e.g.
FastStream codec) as it has better audio quality.
---
 .../bluetooth/module-bluetooth-policy.c   | 123 +-
 1 file changed, 62 insertions(+), 61 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-policy.c 
b/src/modules/bluetooth/module-bluetooth-policy.c
index 04313aa84..9652a91fe 100644
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -59,7 +59,12 @@ struct userdata {
 pa_hook_slot *card_init_profile_slot;
 pa_hook_slot *card_unlink_slot;
 pa_hook_slot *profile_available_changed_slot;
-pa_hashmap *will_need_revert_card_map;
+pa_hashmap *profile_switch_map;
+};
+
+struct profile_switch {
+const char *from_profile;
+const char *to_profile;
 };
 
 /* When a source is created, loopback it to default sink */
@@ -142,43 +147,57 @@ static pa_hook_result_t sink_put_hook_callback(pa_core 
*c, pa_sink *sink, void *
 return PA_HOOK_OK;
 }
 
-static void card_set_profile(struct userdata *u, pa_card *card, bool 
revert_to_a2dp)
-{
+static void card_set_profile(struct userdata *u, pa_card *card, const char 
*revert_to_profile_name) {
+pa_card_profile *iter_profile;
 pa_card_profile *profile;
+struct profile_switch *ps;
+char *old_profile_name;
 void *state;
 
-/* Find available profile and activate it */
-PA_HASHMAP_FOREACH(profile, card->profiles, state) {
-if (profile->available == PA_AVAILABLE_NO)
-continue;
-
-/* Check for correct profile based on revert_to_a2dp */
-if (revert_to_a2dp) {
-if (!pa_startswith(profile->name, "a2dp_sink"))
+if (revert_to_profile_name) {
+profile = pa_hashmap_get(card->profiles, revert_to_profile_name);
+} else {
+/* Find highest priority profile with both sink and source */
+profile = NULL;
+PA_HASHMAP_FOREACH(iter_profile, card->profiles, state) {
+if (iter_profile->available == PA_AVAILABLE_NO)
 continue;
-} else {
-if (!pa_streq(profile->name, "headset_head_unit"))
+if (iter_profile->n_sources == 0 || iter_profile->n_sinks == 0)
 continue;
+if (!profile || profile->priority < iter_profile->priority)
+profile = iter_profile;
 }
+}
 
-pa_log_debug("Setting card '%s' to profile '%s'", card->name, 
profile->name);
+if (!profile) {
+pa_log_warn("Could not find any suitable profile for card '%s'", 
card->name);
+return;
+}
 
-if (pa_card_set_profile(card, profile, false) != 0) {
-pa_log_warn("Could not set profile '%s'", profile->name);
-continue;
-}
+old_profile_name = card->active_profile->name;
+
+pa_log_debug("Setting card '%s' from profile '%s' to profile '%s'", 
card->name, old_profile_name, profile->name);
 
-/* When we are not in revert_to_a2dp phase flag this card for 
will_need_revert */
-if (!revert_to_a2dp)
-pa_hashmap_put(u->will_need_revert_card_map, card, 
PA_INT_TO_PTR(1));
+if (pa_card_set_profile(card, profile, false) != 0) {
+pa_log_warn("Could not set profile '%s'", profile->name);
+return;
+}
 
-break;
+/* When not reverting, store data for future reverting */
+if (!revert_to_profile_name) {
+ps = pa_xnew0(struct profile_switch, 1);
+ps->from_profile = old_profile_name;
+ps->to_profile = profile->name;
+pa_hashmap_put(u->profile_switch_map, card, ps);
 }
 }
 
 /* Switch profile for one card */
-static void switch_profile(pa_card *card, bool revert_to_a2dp, void *userdata) 
{
+static void switch_profile(pa_card *card, bool revert, void *userdata) {
 struct userdata *u = userdata;
+struct profile_switch *ps;
+const char *from_profile;
+const char *to_profile;
 const char *s;
 
 /* Only consider bluetooth cards */
@@ -186,29 +205,25 @@ static void switch_profile(pa_card *card, bool 
revert_to_a2dp, void *userdata) {
 if (!s || !pa_streq(s, "bluetooth"))
 return;
 
-if (revert_to_a2dp) {
-/* In revert_to_a2dp phase only consider cards with will_need_revert 
flag and remove it */
-if (!pa_hashmap_remove(u->will_need_revert_card_map, card))
+if (revert) {
+/* In revert phase only consider cards which switched profile */
+if (!(ps = pa_hashmap_remove(u->profile_switch_map, card)))
 return;
 
-/* Skip card if does not have active hsp profile */
-if (!pa_streq(card->active_profile->name, "headset_head_unit"))
-return;
+from_profile 

[pulseaudio-discuss] [PATCH v15 04/10] bluetooth: policy: Reflect a2dp profile names

2020-04-15 Thread Pali Rohár
In next patches, codec name is appended end the end of a2dp profile names.
---
 src/modules/bluetooth/module-bluetooth-policy.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-policy.c 
b/src/modules/bluetooth/module-bluetooth-policy.c
index 0a6d59d28..04313aa84 100644
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -85,7 +85,7 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, 
pa_source *source,
 if (!s)
 return PA_HOOK_OK;
 
-if (u->enable_a2dp_source && pa_streq(s, "a2dp_source"))
+if (u->enable_a2dp_source && pa_startswith(s, "a2dp_source"))
 role = "music";
 else if (u->enable_ag && pa_streq(s, "headset_audio_gateway"))
 role = "phone";
@@ -154,7 +154,7 @@ static void card_set_profile(struct userdata *u, pa_card 
*card, bool revert_to_a
 
 /* Check for correct profile based on revert_to_a2dp */
 if (revert_to_a2dp) {
-if (!pa_streq(profile->name, "a2dp_sink"))
+if (!pa_startswith(profile->name, "a2dp_sink"))
 continue;
 } else {
 if (!pa_streq(profile->name, "headset_head_unit"))
@@ -196,11 +196,11 @@ static void switch_profile(pa_card *card, bool 
revert_to_a2dp, void *userdata) {
 return;
 
 /* Skip card if already has active a2dp profile */
-if (pa_streq(card->active_profile->name, "a2dp_sink"))
+if (pa_startswith(card->active_profile->name, "a2dp_sink"))
 return;
 } else {
 /* Skip card if does not have active a2dp profile */
-if (!pa_streq(card->active_profile->name, "a2dp_sink"))
+if (!pa_startswith(card->active_profile->name, "a2dp_sink"))
 return;
 
 /* Skip card if already has active hsp profile */
@@ -307,7 +307,7 @@ static pa_hook_result_t 
card_init_profile_hook_callback(pa_core *c, pa_card *car
 
 /* Ignore card if has already set other initial profile than a2dp */
 if (card->active_profile &&
-!pa_streq(card->active_profile->name, "a2dp_sink"))
+!pa_startswith(card->active_profile->name, "a2dp_sink"))
 return PA_HOOK_OK;
 
 /* Set initial profile to hsp */
@@ -359,7 +359,7 @@ static pa_hook_result_t 
profile_available_hook_callback(pa_core *c, pa_card_prof
 return PA_HOOK_OK;
 
 /* Do not automatically switch profiles for headsets, just in case */
-if (pa_streq(profile->name, "a2dp_sink") || pa_streq(profile->name, 
"headset_head_unit"))
+if (pa_startswith(profile->name, "a2dp_sink") || pa_streq(profile->name, 
"headset_head_unit"))
 return PA_HOOK_OK;
 
 is_active_profile = card->active_profile == profile;
-- 
2.20.1

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


[pulseaudio-discuss] [PATCH v15 01/10] bluetooth: Add missing newlines into inline XML document

2020-04-15 Thread Pali Rohár
When calling introspection function, newlines in XML document makes it
better readable. There are already leading spaces for indentation but
newlines were probably forgotten.
---
 src/modules/bluetooth/bluez5-util.c | 44 ++---
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/modules/bluetooth/bluez5-util.c 
b/src/modules/bluetooth/bluez5-util.c
index a21896ede..eed64dbe7 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -55,28 +55,28 @@
 
 #define ENDPOINT_INTROSPECT_XML \
 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE   \
-""\
-" "  \
-"  "  \
-"   "  \
-"   "\
-"  "   \
-"  "   \
-"   "  \
-"   "\
-"  "   \
-"  "\
-"   "  \
-"  "   \
-"  "   \
-"  "   \
-" " \
-" " \
-"  "\
-"   "  \
-"  "   \
-" " \
-""
+"\n"  \
+" \n"\
+"  \n"\
+"   \n"\
+"   \n"  \
+"  \n" \
+"  \n" \
+"   \n"\
+"   \n"  \
+"  \n" \
+"  \n"  \
+"   \n"\
+"  \n" \
+"  \n" \
+"  \n" \
+" \n"   \
+" \n"   \
+"  \n"  \
+"   \n"\
+"  \n" \
+" \n"   \
+"\n"
 
 struct pa_bluetooth_discovery {
 PA_REFCNT_DECLARE;
-- 
2.20.1

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


[pulseaudio-discuss] [PATCH v15 06/10] bluetooth: Set initial A2DP profile which bluez already activated

2020-04-15 Thread Pali Rohár
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 | 46 +++-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/src/modules/bluetooth/module-bluez5-device.c 
b/src/modules/bluetooth/module-bluez5-device.c
index 912bd498e..975477116 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -2085,6 +2085,50 @@ static void add_card_profile(pa_bluetooth_profile_t 
profile, pa_card_new_data *d
 pa_hashmap_put(data->profiles, cp->name, cp);
 }
 
+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;
+
+/* Try to find the best A2DP profile with active transport */
+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;
+}
+
+/* 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(>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;
@@ -2207,7 +2251,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);
-- 
2.20.1

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


[pulseaudio-discuss] [PATCH v15 05/10] bluetooth: Implement A2DP codec switching and backchannel support

2020-04-15 Thread Pali Rohár
Some A2DP codecs (like FastStream or aptX Low Latency) are bi-directional
and can be used for both music playback and audio calls. This patch
implements usage of backchannel if A2DP codec provided by pulseaudio API
supports it.

A2DP codec switching needs new version of bluez as older version does not
provide needed org.freedesktop.DBus.ObjectManager and RegisterApplication
DBus APIs.

Pulseaudio use for each A2DP codec separate pulseaudio profile, therefore
codec switching is implemented via changing pulseaudio profile and
currently used A2DP codec is visible in pulseaudio profile.

Getting list of supported codecs by remote device is supported only by new
version of bluez daemon.

If old bluez version is detected then only one SBC codec is supported.
---
 src/modules/bluetooth/bluez5-util.c   | 826 +-
 src/modules/bluetooth/bluez5-util.h   |  40 +-
 src/modules/bluetooth/module-bluez5-device.c  | 420 ++---
 .../bluetooth/module-bluez5-discover.c|   3 +-
 4 files changed,  insertions(+), 178 deletions(-)

diff --git a/src/modules/bluetooth/bluez5-util.c 
b/src/modules/bluetooth/bluez5-util.c
index eed64dbe7..5623074a1 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -50,8 +50,34 @@
 
 #define BLUEZ_ERROR_NOT_SUPPORTED "org.bluez.Error.NotSupported"
 
-#define A2DP_SOURCE_ENDPOINT "/MediaEndpoint/A2DPSource"
-#define A2DP_SINK_ENDPOINT "/MediaEndpoint/A2DPSink"
+#define A2DP_OBJECT_MANAGER_PATH "/MediaEndpoint"
+#define A2DP_SOURCE_ENDPOINT A2DP_OBJECT_MANAGER_PATH "/A2DPSource"
+#define A2DP_SINK_ENDPOINT A2DP_OBJECT_MANAGER_PATH "/A2DPSink"
+
+#define OBJECT_MANAGER_INTROSPECT_XML  
\
+DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE  
\
+"\n" 
\
+" \n"   
\
+"  \n"  
\
+"   \n"
\
+"  \n"
\
+"  \n"
\
+"   \n"   
\
+"   \n"   
\
+"  \n"
\
+"  \n"  
\
+"   \n"   
\
+"   \n"  
\
+"  \n"
\
+" \n"  
\
+" \n"  
\
+"  \n" 
\
+"   \n"   
\
+"  \n"
\
+" \n"  
\
+" \n" 
\
+" \n"   
\
+"\n"
 
 #define ENDPOINT_INTROSPECT_XML \
 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE   \
@@ -96,6 +122,11 @@ struct pa_bluetooth_discovery {
 PA_LLIST_HEAD(pa_dbus_pending, pending);
 };
 
+struct a2dp_codec_capabilities {
+uint8_t size;
+uint8_t buffer[]; /* max size is 254 bytes */
+};
+
 static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, 
DBusMessage *m,
   
DBusPendingCallNotifyFunction func, void *call_data) {
 pa_dbus_pending *p;
@@ -171,11 +202,13 @@ static const char 
*transport_state_to_string(pa_bluetooth_transport_state_t stat
 }
 
 static bool device_supports_profile(pa_bluetooth_device *device, 
pa_bluetooth_profile_t profile) {
+const struct a2dp_codec_capabilities *a2dp_codec_capabilities;
+const pa_a2dp_codec *a2dp_codec;
+bool is_a2dp_sink;
+pa_hashmap *endpoints;
+void *state;
+
 switch (profile) {
-case PA_BLUETOOTH_PROFILE_A2DP_SINK:
-return !!pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_A2DP_SINK);
-case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
-return !!pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_A2DP_SOURCE);
 case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
 return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS)
 || !!pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_HSP_HS_ALT)
@@ -184,10 +217,33 @@ static bool device_supports_profile(pa_bluetooth_device 
*device, pa_bluetooth_pr
 return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG)
 || !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG);
 case PA_BLUETOOTH_PROFILE_OFF:
-pa_assert_not_reached();
+return true;
+default:
+break;
 }
 
-pa_assert_not_reached();
+a2dp_codec = pa_bluetooth_profile_to_a2dp_codec(profile);
+is_a2dp_sink = 

[pulseaudio-discuss] [PATCH v15 03/10] bluetooth: Change codec API for choosing remote endpoint

2020-04-15 Thread Pali Rohár
Current codec API for choosing remote endpoint was not suitable for
implementing fallback to another endpoint when first chosen one was not
possible to establish.

To overcome this problem change codec API to rather provide generic method
for comparing two endpoints by their capabilities. Return value is standard
value what comparator function returns (-1, 0, 1). It can be used e.g. for
searching the best remote endpoint (like did previous API method) or
creating a full list of all endpoints in preferred order (e.g. by sorting
function).

Currently this method is not used (neither old choose remote endpoint).
It is used by code for switching A2DP codec which is in next patches.
---
 src/modules/bluetooth/a2dp-codec-api.h |  21 ++--
 src/modules/bluetooth/a2dp-codec-sbc.c | 157 +++--
 2 files changed, 157 insertions(+), 21 deletions(-)

diff --git a/src/modules/bluetooth/a2dp-codec-api.h 
b/src/modules/bluetooth/a2dp-codec-api.h
index a3123f4ca..6ee722e37 100644
--- a/src/modules/bluetooth/a2dp-codec-api.h
+++ b/src/modules/bluetooth/a2dp-codec-api.h
@@ -24,11 +24,6 @@
 
 #define MAX_A2DP_CAPS_SIZE 254
 
-typedef struct pa_a2dp_codec_capabilities {
-uint8_t size;
-uint8_t buffer[]; /* max size is 254 bytes */
-} pa_a2dp_codec_capabilities;
-
 typedef struct pa_a2dp_codec_id {
 uint8_t codec_id;
 uint32_t vendor_id;
@@ -51,11 +46,17 @@ typedef struct pa_a2dp_codec {
 /* Returns true if codec accepts capabilities, for_encoding is true when
  * capabilities are used for encoding */
 bool (*can_accept_capabilities)(const uint8_t *capabilities_buffer, 
uint8_t capabilities_size, bool for_encoding);
-/* Choose remote endpoint based on capabilities from hash map
- * (const char *endpoint -> const pa_a2dp_codec_capabilities *capability)
- * and returns corresponding endpoint key (or NULL when there is no valid),
- * for_encoder is true when capabilities hash map is used for encoding */
-const char *(*choose_remote_endpoint)(const pa_hashmap 
*capabilities_hashmap, const pa_sample_spec *default_sample_spec, bool 
for_encoding);
+/* Comparator function for sorting endpoints, based on endpoint 
capabilities
+ * and default sample spec, this function should return:
+ * -1 if first endpoint is preferred;
+ *  1 if second endpoint is preferred;
+ *  0 if both endpoints have same priority;
+ * for_encoding is true when endpoints are used for encoding,
+ * only endpoints which passed can_accept_capabilities() are compared,
+ * remote endpoints are tried from most preferred to less preferred,
+ * endpoint which better fits for default sample spec should be more
+ * preferred than other endpoints */
+int (*cmp_endpoints)(const uint8_t *capabilities1_buffer, uint8_t 
capabilities1_size, const uint8_t *capabilities2_buffer, uint8_t 
capabilities2_size, const pa_sample_spec *default_sample_spec, bool 
for_encoding);
 /* Fill codec capabilities, returns size of filled buffer */
 uint8_t (*fill_capabilities)(uint8_t 
capabilities_buffer[MAX_A2DP_CAPS_SIZE]);
 /* Validate codec configuration, returns true on success */
diff --git a/src/modules/bluetooth/a2dp-codec-sbc.c 
b/src/modules/bluetooth/a2dp-codec-sbc.c
index 89c647fbe..ba47fa066 100644
--- a/src/modules/bluetooth/a2dp-codec-sbc.c
+++ b/src/modules/bluetooth/a2dp-codec-sbc.c
@@ -77,18 +77,153 @@ static bool can_accept_capabilities(const uint8_t 
*capabilities_buffer, uint8_t
 return true;
 }
 
-static const char *choose_remote_endpoint(const pa_hashmap 
*capabilities_hashmap, const pa_sample_spec *default_sample_spec, bool 
for_encoding) {
-const pa_a2dp_codec_capabilities *a2dp_capabilities;
-const char *key;
-void *state;
-
-/* There is no preference, just choose random valid entry */
-PA_HASHMAP_FOREACH_KV(key, a2dp_capabilities, capabilities_hashmap, state) 
{
-if (can_accept_capabilities(a2dp_capabilities->buffer, 
a2dp_capabilities->size, for_encoding))
-return key;
+static int cmp_endpoints_by_channels(const a2dp_sbc_t *capabilities1, const 
a2dp_sbc_t *capabilities2, const pa_sample_spec *default_sample_spec, bool 
for_encoding) {
+/* Prefer enpoint which number of channels is near to default sample 
channel number */
+if (default_sample_spec->channels < 2) {
+if ((capabilities1->channel_mode & SBC_CHANNEL_MODE_MONO) && 
!(capabilities2->channel_mode & SBC_CHANNEL_MODE_MONO))
+return -1;
+if (!(capabilities1->channel_mode & SBC_CHANNEL_MODE_MONO) && 
(capabilities2->channel_mode & SBC_CHANNEL_MODE_MONO))
+return 1;
+} else {
+if ((capabilities1->channel_mode & 
(SBC_CHANNEL_MODE_DUAL_CHANNEL|SBC_CHANNEL_MODE_STEREO|SBC_CHANNEL_MODE_JOINT_STEREO))
 &&
+   !(capabilities2->channel_mode & 
(SBC_CHANNEL_MODE_DUAL_CHANNEL|SBC_CHANNEL_MODE_STEREO|SBC_CHANNEL_MODE_JOINT_STEREO)))
+return -1;
+if 

[pulseaudio-discuss] [PATCH v15 02/10] bluetooth: Do not export pa_a2dp_codecs array

2020-04-15 Thread Pali Rohár
It is not used directly outside of a2dp-codec-util.c file.
---
 src/modules/bluetooth/a2dp-codec-util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/modules/bluetooth/a2dp-codec-util.c 
b/src/modules/bluetooth/a2dp-codec-util.c
index 94d01e7bd..aff6589ca 100644
--- a/src/modules/bluetooth/a2dp-codec-util.c
+++ b/src/modules/bluetooth/a2dp-codec-util.c
@@ -30,7 +30,7 @@ extern const pa_a2dp_codec pa_a2dp_codec_sbc;
 
 /* This is list of supported codecs. Their order is important.
  * Codec with higher index has higher priority. */
-const pa_a2dp_codec *pa_a2dp_codecs[] = {
+static const pa_a2dp_codec *pa_a2dp_codecs[] = {
 _a2dp_codec_sbc,
 };
 
-- 
2.20.1

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


[pulseaudio-discuss] [PATCH v15 00/10] Bluetooth A2DP codecs

2020-04-15 Thread Pali Rohár
Changes in v15:
* Added patch: Do not export pa_a2dp_codecs array
* Added patch: Change codec API for choosing remote endpoint
* Use pa_assert_se() for expression with side effects

In this patch series was changed API for choosing remote endpoint to
allow possible fallback to another codec compatible endpoint when
currently chosen is unusable.

Patches in this series changed order, so patches with new codec are
after patches which implements usage of more codec.

Pali Rohár (10):
  bluetooth: Add missing newlines into inline XML document
  bluetooth: Do not export pa_a2dp_codecs array
  bluetooth: Change codec API for choosing remote endpoint
  bluetooth: policy: Reflect a2dp profile names
  bluetooth: Implement A2DP codec switching and backchannel support
  bluetooth: Set initial A2DP profile which bluez already activated
  bluetooth: policy: Treat bi-directional A2DP profiles as suitable for
VOIP
  bluetooth: Add A2DP aptX and aptX HD codecs support
  bluetooth: Add A2DP FastStream codec support
  bluetooth: Add more variants of SBC codec

 configure.ac  |  36 +
 src/Makefile.am   |   8 +
 src/modules/bluetooth/a2dp-codec-api.h|  21 +-
 src/modules/bluetooth/a2dp-codec-aptx.c   | 522 +++
 src/modules/bluetooth/a2dp-codec-faststream.c | 566 
 src/modules/bluetooth/a2dp-codec-sbc.c| 798 +---
 src/modules/bluetooth/a2dp-codec-util.c   |  28 +-
 src/modules/bluetooth/bluez5-util.c   | 870 --
 src/modules/bluetooth/bluez5-util.h   |  40 +-
 src/modules/bluetooth/meson.build |   1 +
 .../bluetooth/module-bluetooth-policy.c   | 127 +--
 src/modules/bluetooth/module-bluez5-device.c  | 466 +++---
 .../bluetooth/module-bluez5-discover.c|   3 +-
 13 files changed, 3070 insertions(+), 416 deletions(-)
 create mode 100644 src/modules/bluetooth/a2dp-codec-aptx.c
 create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c

-- 
2.20.1

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


[pulseaudio-discuss] [PATCH v14 3/9] bluetooth: Add A2DP aptX and aptX HD codecs support

2020-03-19 Thread Pali Rohár
_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
diff --git a/src/modules/bluetooth/a2dp-codec-aptx.c 
b/src/modules/bluetooth/a2dp-codec-aptx.c
new file mode 100644
index 0..4adb180f3
--- /dev/null
+++ b/src/modules/bluetooth/a2dp-codec-aptx.c
@@ -0,0 +1,477 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2018-2019 Pali Rohár 
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include 
+#endif
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+
+#include "a2dp-codecs.h"
+#include "a2dp-codec-api.h"
+#include "rtp.h"
+
+struct aptx_hd_info {
+struct aptx_context *aptx_c;
+uint16_t seq_num;
+};
+
+static bool can_accept_capabilities_common(const a2dp_aptx_t *capabilities, 
uint32_t vendor_id, uint16_t codec_id) {
+if (A2DP_GET_VENDOR_ID(capabilities->info) != vendor_id || 
A2DP_GET_CODEC_ID(capabilities->info) != codec_id)
+return false;
+
+if (!(capabilities->frequency & (APTX_SAMPLING_FREQ_16000 | 
APTX_SAMPLING_FREQ_32000 |
+ APTX_SAMPLING_FREQ_44100 | 
APTX_SAMPLING_FREQ_48000)))
+return false;
+
+if (!(capabilities->channel_mode & APTX_CHANNEL_MODE_STEREO))
+return false;
+
+return true;
+}
+
+static bool can_accept_capabilities(const uint8_t *capabilities_buffer, 
uint8_t capabilities_size, bool for_encoding) {
+const a2dp_aptx_t *capabilities = (const a2dp_aptx_t *) 
capabilities_buffer;
+
+if (capabilities_size != sizeof(*capabilities))
+return false;
+
+return can_accept_capabilities_common(capabilities, APTX_VENDOR_ID, 
APTX_CODEC_ID);
+}
+
+static bool can_accept_capabilities_hd(const uint8_t *capabilities_buffer, 
uint8_t capabilities_size, bool for_encoding) {
+const a2dp_aptx_hd_t *capabilities = (const a2dp_aptx_hd_t *) 
capabilities_buffer;
+
+if (capabilities_size != sizeof(*capabilities))
+return false;
+
+return can_accept_capabilities_common(>aptx, 
APTX_HD_VENDOR_ID, APTX_HD_CODEC_ID);
+}
+
+static const char *choose_remote_endpoint_common(bool 
(*can_accept_capabilities_func)(const uint8_t *, uint8_t, bool), const 
pa_hashmap *capabilities_hashmap, bool for_encoding) {
+const pa_a2dp_codec_capabilities *a2dp_capabilities;
+const char *key;
+void *state;
+
+/* There is no preference, just choose random valid entry */
+PA_HASHMAP_FOREACH_KV(key, a2dp_capabilities, capabilities_hashmap, state) 
{
+if (can_accept_capabilities_func(a2dp_capabilities->buffer, 
a2dp_capabilities->size, for_encoding))
+return key;
+}
+
+return NULL;
+}
+
+static const char *choose_remote_endpoint(const pa_hashmap 
*capabilities_hashmap, const pa_sample_spec *default_sample_spec, bool 
for_encoding) {
+return choose_remote_endpoint_common(can_accept_capabilities, 
capabilities_hashmap, for_encoding);
+}
+
+static const char *choose_remote_endpoint_hd(const pa_hashmap 
*capabilities_hashmap, const pa_sample_spec *default_sample_spec, bool 
for_encoding) {
+return choose_remote_endpoint_common(can_accept_capabilities_hd, 
capabilities_hashmap, for_encoding);
+}
+
+static void fill_capabilities_common(a2dp_aptx_t *capabilities, uint32_t 
vendor_id, uint16_t codec_id) {
+capabilities->info = A2DP_SET_VENDOR_ID_CODEC_ID(vendor_id, codec_id);
+capabilities->channel_mode = APTX_CHANNEL_MODE_STEREO;
+capabilities->frequency = APTX_SAMPLING_FREQ_16000 | 
APTX_SAMPLING_FREQ_32000 |
+  APTX_SAMPLING_FREQ_44100 | 
APTX_SAMPLING_FREQ_48000;
+}
+
+static uint8_t fill_capabilities(uint8_t 
capabilities_buffer[MAX_A2DP_CAPS_SIZE]) {
+a2dp_aptx_t *capabilities = (a2dp_aptx_t *) capabilities_buffer;
+
+pa_zero(*capabilities);
+fill_capabilities_common(capabilities, APTX_VENDOR_ID, APTX_CODEC_ID);
+return sizeof(*capabilities);
+}
+
+static uint8_t fill_capabilities_hd(uint8_t 
capabilities_buffer[MAX_A2DP_CAPS_SIZE]) {
+a2d

[pulseaudio-discuss] [PATCH v14 9/9] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2020-03-19 Thread Pali Rohár
Previously module-bluetooth-policy was switching from A2DP to HSP profile
when VOIP application started recording of source. Now it switch to profile
with the highest priority which has both sink and source. In most cases it
is HSP profile, but it can be also bi-directional A2DP profile (e.g.
FastStream codec) as it has better audio quality.
---
 .../bluetooth/module-bluetooth-policy.c   | 123 +-
 1 file changed, 62 insertions(+), 61 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-policy.c 
b/src/modules/bluetooth/module-bluetooth-policy.c
index 04313aa84..9652a91fe 100644
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -59,7 +59,12 @@ struct userdata {
 pa_hook_slot *card_init_profile_slot;
 pa_hook_slot *card_unlink_slot;
 pa_hook_slot *profile_available_changed_slot;
-pa_hashmap *will_need_revert_card_map;
+pa_hashmap *profile_switch_map;
+};
+
+struct profile_switch {
+const char *from_profile;
+const char *to_profile;
 };
 
 /* When a source is created, loopback it to default sink */
@@ -142,43 +147,57 @@ static pa_hook_result_t sink_put_hook_callback(pa_core 
*c, pa_sink *sink, void *
 return PA_HOOK_OK;
 }
 
-static void card_set_profile(struct userdata *u, pa_card *card, bool 
revert_to_a2dp)
-{
+static void card_set_profile(struct userdata *u, pa_card *card, const char 
*revert_to_profile_name) {
+pa_card_profile *iter_profile;
 pa_card_profile *profile;
+struct profile_switch *ps;
+char *old_profile_name;
 void *state;
 
-/* Find available profile and activate it */
-PA_HASHMAP_FOREACH(profile, card->profiles, state) {
-if (profile->available == PA_AVAILABLE_NO)
-continue;
-
-/* Check for correct profile based on revert_to_a2dp */
-if (revert_to_a2dp) {
-if (!pa_startswith(profile->name, "a2dp_sink"))
+if (revert_to_profile_name) {
+profile = pa_hashmap_get(card->profiles, revert_to_profile_name);
+} else {
+/* Find highest priority profile with both sink and source */
+profile = NULL;
+PA_HASHMAP_FOREACH(iter_profile, card->profiles, state) {
+if (iter_profile->available == PA_AVAILABLE_NO)
 continue;
-} else {
-if (!pa_streq(profile->name, "headset_head_unit"))
+if (iter_profile->n_sources == 0 || iter_profile->n_sinks == 0)
 continue;
+if (!profile || profile->priority < iter_profile->priority)
+profile = iter_profile;
 }
+}
 
-pa_log_debug("Setting card '%s' to profile '%s'", card->name, 
profile->name);
+if (!profile) {
+pa_log_warn("Could not find any suitable profile for card '%s'", 
card->name);
+return;
+}
 
-if (pa_card_set_profile(card, profile, false) != 0) {
-pa_log_warn("Could not set profile '%s'", profile->name);
-continue;
-}
+old_profile_name = card->active_profile->name;
+
+pa_log_debug("Setting card '%s' from profile '%s' to profile '%s'", 
card->name, old_profile_name, profile->name);
 
-/* When we are not in revert_to_a2dp phase flag this card for 
will_need_revert */
-if (!revert_to_a2dp)
-pa_hashmap_put(u->will_need_revert_card_map, card, 
PA_INT_TO_PTR(1));
+if (pa_card_set_profile(card, profile, false) != 0) {
+pa_log_warn("Could not set profile '%s'", profile->name);
+return;
+}
 
-break;
+/* When not reverting, store data for future reverting */
+if (!revert_to_profile_name) {
+ps = pa_xnew0(struct profile_switch, 1);
+ps->from_profile = old_profile_name;
+ps->to_profile = profile->name;
+pa_hashmap_put(u->profile_switch_map, card, ps);
 }
 }
 
 /* Switch profile for one card */
-static void switch_profile(pa_card *card, bool revert_to_a2dp, void *userdata) 
{
+static void switch_profile(pa_card *card, bool revert, void *userdata) {
 struct userdata *u = userdata;
+struct profile_switch *ps;
+const char *from_profile;
+const char *to_profile;
 const char *s;
 
 /* Only consider bluetooth cards */
@@ -186,29 +205,25 @@ static void switch_profile(pa_card *card, bool 
revert_to_a2dp, void *userdata) {
 if (!s || !pa_streq(s, "bluetooth"))
 return;
 
-if (revert_to_a2dp) {
-/* In revert_to_a2dp phase only consider cards with will_need_revert 
flag and remove it */
-if (!pa_hashmap_remove(u->will_need_revert_card_map, card))
+if (revert) {
+/* In revert phase only consider cards which switched profile */
+if (!(ps = pa_hashmap_remove(u->profile_switch_map, card)))
 return;
 
-/* Skip card if does not have active hsp profile */
-if (!pa_streq(card->active_profile->name, "headset_head_unit"))
-return;
+from_profile 

[pulseaudio-discuss] [PATCH v14 8/9] bluetooth: Set initial A2DP profile which bluez already activated

2020-03-19 Thread Pali Rohár
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 | 46 +++-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/src/modules/bluetooth/module-bluez5-device.c 
b/src/modules/bluetooth/module-bluez5-device.c
index 865529769..1b36ae3e5 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -2085,6 +2085,50 @@ static void add_card_profile(pa_bluetooth_profile_t 
profile, pa_card_new_data *d
 pa_hashmap_put(data->profiles, cp->name, cp);
 }
 
+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;
+
+/* Try to find the best A2DP profile with active transport */
+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;
+}
+
+/* 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(>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;
@@ -2209,7 +2253,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);
-- 
2.20.1

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


[pulseaudio-discuss] [PATCH v14 5/9] bluetooth: Add more variants of SBC codec

2020-03-19 Thread Pali Rohár
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  | 690 +++-
 src/modules/bluetooth/a2dp-codec-util.c |  18 +-
 2 files changed, 569 insertions(+), 139 deletions(-)

diff --git a/src/modules/bluetooth/a2dp-codec-sbc.c 
b/src/modules/bluetooth/a2dp-codec-sbc.c
index 89c647fbe..d3fb7c5ab 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 for EDR-2 and to
+ * be below max possible 512 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. */
+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 */
+};
+
+#undef FIXED_SBC_CAPS
+
+/* SBC Auto Quality, only one row which allow any possible configuration up to 
common High Quality */
+/* We need to ensure that bitrate is below max possible 512 kbps, therefore 
limit 

[pulseaudio-discuss] [PATCH v14 7/9] bluetooth: Implement A2DP codec switching and backchannel support

2020-03-19 Thread Pali Rohár
Some A2DP codecs (like FastStream or aptX Low Latency) are bi-directional
and can be used for both music playback and audio calls. This patch
implements usage of backchannel if A2DP codec provided by pulseaudio API
supports it.

A2DP codec switching needs new version of bluez as older version does not
provide needed org.freedesktop.DBus.ObjectManager and RegisterApplication
DBus APIs.

Pulseaudio use for each A2DP codec separate pulseaudio profile, therefore
codec switching is implemented via changing pulseaudio profile and
currently used A2DP codec is visible in pulseaudio profile.

Getting list of supported codecs by remote device is supported only by new
version of bluez daemon.

If old bluez version is detected then only one SBC codec is supported.
---
 src/modules/bluetooth/bluez5-util.c   | 716 +-
 src/modules/bluetooth/bluez5-util.h   |  40 +-
 src/modules/bluetooth/module-bluez5-device.c  | 422 +++
 .../bluetooth/module-bluez5-discover.c|   3 +-
 4 files changed, 1003 insertions(+), 178 deletions(-)

diff --git a/src/modules/bluetooth/bluez5-util.c 
b/src/modules/bluetooth/bluez5-util.c
index eed64dbe7..898255c88 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -50,8 +50,34 @@
 
 #define BLUEZ_ERROR_NOT_SUPPORTED "org.bluez.Error.NotSupported"
 
-#define A2DP_SOURCE_ENDPOINT "/MediaEndpoint/A2DPSource"
-#define A2DP_SINK_ENDPOINT "/MediaEndpoint/A2DPSink"
+#define A2DP_OBJECT_MANAGER_PATH "/MediaEndpoint"
+#define A2DP_SOURCE_ENDPOINT A2DP_OBJECT_MANAGER_PATH "/A2DPSource"
+#define A2DP_SINK_ENDPOINT A2DP_OBJECT_MANAGER_PATH "/A2DPSink"
+
+#define OBJECT_MANAGER_INTROSPECT_XML  
\
+DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE  
\
+"\n" 
\
+" \n"   
\
+"  \n"  
\
+"   \n"
\
+"  \n"
\
+"  \n"
\
+"   \n"   
\
+"   \n"   
\
+"  \n"
\
+"  \n"  
\
+"   \n"   
\
+"   \n"  
\
+"  \n"
\
+" \n"  
\
+" \n"  
\
+"  \n" 
\
+"   \n"   
\
+"  \n"
\
+" \n"  
\
+" \n" 
\
+" \n"   
\
+"\n"
 
 #define ENDPOINT_INTROSPECT_XML \
 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE   \
@@ -171,11 +197,13 @@ static const char 
*transport_state_to_string(pa_bluetooth_transport_state_t stat
 }
 
 static bool device_supports_profile(pa_bluetooth_device *device, 
pa_bluetooth_profile_t profile) {
+const pa_a2dp_codec_capabilities *a2dp_codec_capabilities;
+const pa_a2dp_codec *a2dp_codec;
+bool is_a2dp_sink;
+pa_hashmap *endpoints;
+void *state;
+
 switch (profile) {
-case PA_BLUETOOTH_PROFILE_A2DP_SINK:
-return !!pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_A2DP_SINK);
-case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
-return !!pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_A2DP_SOURCE);
 case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
 return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS)
 || !!pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_HSP_HS_ALT)
@@ -184,10 +212,33 @@ static bool device_supports_profile(pa_bluetooth_device 
*device, pa_bluetooth_pr
 return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG)
 || !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG);
 case PA_BLUETOOTH_PROFILE_OFF:
-pa_assert_not_reached();
+return true;
+default:
+break;
 }
 
-pa_assert_not_reached();
+a2dp_codec = pa_bluetooth_profile_to_a2dp_codec(profile);
+is_a2dp_sink = pa_bluetooth_profile_is_a2dp_sink(profile);
+
+if (is_a2dp_sink && !pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_A2DP_SINK))
+return false;
+else if (!is_a2dp_sink && !pa_hashmap_get(device->uuids, 
PA_BLUETOOTH_UUID_A2DP_SOURCE))
+return false;
+
+if (is_a2dp_sink)
+endpoints = pa_hashmap_get(device->a2dp_sink_endpoints, 
_codec->id);
+else
+endpoints = pa_hashmap_get(device->a2dp_source_endpoints, 
_codec->id);
+
+  

[pulseaudio-discuss] [PATCH v14 1/9] bluetooth: Ensure that only one A2DP codec is registered to bluez

2020-03-19 Thread Pali Rohár
Support for multiple codecs needs to use a new Bluez API which pulseaudio
does not implement yet.

So register explicitly only SBC codec which is provided by pulseaudio A2DP
codec API.
---
 src/modules/bluetooth/bluez5-util.c | 24 +---
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/src/modules/bluetooth/bluez5-util.c 
b/src/modules/bluetooth/bluez5-util.c
index d95c9c117..a21896ede 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -944,8 +944,9 @@ static void 
parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessa
 pa_assert(dbus_message_iter_get_arg_type(_i) == DBUS_TYPE_ARRAY);
 
 if (pa_streq(interface, BLUEZ_ADAPTER_INTERFACE)) {
+
+const pa_a2dp_codec *a2dp_codec_sbc;
 pa_bluetooth_adapter *a;
-unsigned a2dp_codec_i;
 
 if ((a = pa_hashmap_get(y->adapters, path))) {
 pa_log_error("Found duplicated D-Bus path for adapter %s", 
path);
@@ -960,20 +961,13 @@ static void 
parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessa
 if (!a->valid)
 return;
 
-/* Order is important. bluez prefers endpoints registered earlier.
- * And codec with higher number has higher priority. So iterate in 
reverse order. */
-for (a2dp_codec_i = pa_bluetooth_a2dp_codec_count(); a2dp_codec_i 
> 0; a2dp_codec_i--) {
-const pa_a2dp_codec *a2dp_codec = 
pa_bluetooth_a2dp_codec_iter(a2dp_codec_i-1);
-char *endpoint;
-
-endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, 
a2dp_codec->name);
-register_endpoint(y, a2dp_codec, path, endpoint, 
PA_BLUETOOTH_UUID_A2DP_SINK);
-pa_xfree(endpoint);
-
-endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, 
a2dp_codec->name);
-register_endpoint(y, a2dp_codec, path, endpoint, 
PA_BLUETOOTH_UUID_A2DP_SOURCE);
-pa_xfree(endpoint);
-}
+/* Currently only one A2DP codec is supported, so register only SBC
+ * Support for multiple codecs needs to use a new Bluez API which
+ * pulseaudio does not implement yet, patches are waiting in queue 
*/
+a2dp_codec_sbc = pa_bluetooth_get_a2dp_codec("sbc");
+pa_assert(a2dp_codec_sbc);
+register_endpoint(y, a2dp_codec_sbc, path, A2DP_SINK_ENDPOINT 
"/sbc", PA_BLUETOOTH_UUID_A2DP_SINK);
+register_endpoint(y, a2dp_codec_sbc, path, A2DP_SOURCE_ENDPOINT 
"/sbc", PA_BLUETOOTH_UUID_A2DP_SOURCE);
 
 } else if (pa_streq(interface, BLUEZ_DEVICE_INTERFACE)) {
 
-- 
2.20.1

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


[pulseaudio-discuss] [PATCH v14 0/9] Bluetooth A2DP codecs

2020-03-19 Thread Pali Rohár
Changes in v14:
* Added patch: Add missing newlines into inline XML document
* Dropped patch: Parse remote timestamp from A2DP RTP packets when available
* Moved patch: Set initial A2DP profile which bluez already activated
* Address review comments by Georg Chini, mostly in SBC codec

I added also a new patch "Ensure that only one A2DP codec is registered
to bluez" which is later in "Implement A2DP codec switching and
backchannel support" reverted/removed.

Now patches in this patch series can be applied in other as I send them.

Pali Rohár (9):
  bluetooth: Ensure that only one A2DP codec is registered to bluez
  bluetooth: Add missing newlines into inline XML document
  bluetooth: Add A2DP aptX and aptX HD codecs support
  bluetooth: Add A2DP FastStream codec support
  bluetooth: Add more variants of SBC codec
  bluetooth: policy: Reflect a2dp profile names
  bluetooth: Implement A2DP codec switching and backchannel support
  bluetooth: Set initial A2DP profile which bluez already activated
  bluetooth: policy: Treat bi-directional A2DP profiles as suitable for
VOIP

 configure.ac  |  36 +
 src/Makefile.am   |   8 +
 src/modules/bluetooth/a2dp-codec-aptx.c   | 477 +++
 src/modules/bluetooth/a2dp-codec-faststream.c | 555 +
 src/modules/bluetooth/a2dp-codec-sbc.c| 690 
 src/modules/bluetooth/a2dp-codec-util.c   |  26 +-
 src/modules/bluetooth/bluez5-util.c   | 768 --
 src/modules/bluetooth/bluez5-util.h   |  40 +-
 src/modules/bluetooth/meson.build |   1 +
 .../bluetooth/module-bluetooth-policy.c   | 127 +--
 src/modules/bluetooth/module-bluez5-device.c  | 468 ---
 .../bluetooth/module-bluez5-discover.c|   3 +-
 12 files changed, 2791 insertions(+), 408 deletions(-)
 create mode 100644 src/modules/bluetooth/a2dp-codec-aptx.c
 create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c

-- 
2.20.1

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


[pulseaudio-discuss] [PATCH v14 4/9] bluetooth: Add A2DP FastStream codec support

2020-03-19 Thread Pali Rohár
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 | 555 ++
 src/modules/bluetooth/a2dp-codec-util.c   |   4 +
 src/modules/bluetooth/meson.build |   1 +
 4 files changed, 562 insertions(+)
 create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 0842a7bd5..83d8ef7d3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2172,6 +2172,8 @@ libbluez5_util_la_SOURCES += 
modules/bluetooth/a2dp-codec-sbc.c
 libbluez5_util_la_LIBADD += $(SBC_LIBS)
 libbluez5_util_la_CFLAGS += $(SBC_CFLAGS)
 
+libbluez5_util_la_SOURCES += modules/bluetooth/a2dp-codec-faststream.c
+
 if HAVE_OPENAPTX
 libbluez5_util_la_SOURCES += modules/bluetooth/a2dp-codec-aptx.c
 libbluez5_util_la_CPPFLAGS += $(OPENAPTX_CPPFLAGS)
diff --git a/src/modules/bluetooth/a2dp-codec-faststream.c 
b/src/modules/bluetooth/a2dp-codec-faststream.c
new file mode 100644
index 0..bf6e94727
--- /dev/null
+++ b/src/modules/bluetooth/a2dp-codec-faststream.c
@@ -0,0 +1,555 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2018-2019 Pali Rohár 
+
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include 
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "a2dp-codecs.h"
+#include "a2dp-codec-api.h"
+
+struct faststream_info {
+sbc_t sbc;   /* Codec data */
+size_t codesize, frame_length;   /* SBC Codesize, frame_length. We 
simply cache those values here */
+bool is_microphone;
+uint8_t frequency;
+};
+
+static bool can_accept_capabilities(const uint8_t *capabilities_buffer, 
uint8_t capabilities_size, bool for_encoding) {
+const a2dp_faststream_t *capabilities = (const a2dp_faststream_t *) 
capabilities_buffer;
+
+if (capabilities_size != sizeof(*capabilities))
+return false;
+
+if (A2DP_GET_VENDOR_ID(capabilities->info) != FASTSTREAM_VENDOR_ID || 
A2DP_GET_CODEC_ID(capabilities->info) != FASTSTREAM_CODEC_ID)
+return false;
+
+if (!(capabilities->direction & FASTSTREAM_DIRECTION_SINK))
+return false;
+
+if (!(capabilities->sink_frequency & (FASTSTREAM_SINK_SAMPLING_FREQ_44100 
| FASTSTREAM_SINK_SAMPLING_FREQ_48000)))
+return false;
+
+return true;
+}
+
+static bool can_accept_capabilities_mic(const uint8_t *capabilities_buffer, 
uint8_t capabilities_size, bool for_encoding) {
+const a2dp_faststream_t *capabilities = (const a2dp_faststream_t *) 
capabilities_buffer;
+
+if (!can_accept_capabilities(capabilities_buffer, capabilities_size, 
for_encoding))
+return false;
+
+if (!(capabilities->direction & FASTSTREAM_DIRECTION_SOURCE))
+return false;
+
+if (!(capabilities->source_frequency & 
FASTSTREAM_SOURCE_SAMPLING_FREQ_16000))
+return false;
+
+return true;
+}
+
+static const char *choose_remote_endpoint(const pa_hashmap 
*capabilities_hashmap, const pa_sample_spec *default_sample_spec, bool 
for_encoding) {
+const pa_a2dp_codec_capabilities *a2dp_capabilities;
+const char *key_with_mic;
+const char *key;
+void *state;
+
+/* Prefer endpoint without microphone support */
+key_with_mic = NULL;
+PA_HASH

[pulseaudio-discuss] [PATCH v14 6/9] bluetooth: policy: Reflect a2dp profile names

2020-03-19 Thread Pali Rohár
In next patches, codec name is appended end the end of a2dp profile names.
---
 src/modules/bluetooth/module-bluetooth-policy.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/modules/bluetooth/module-bluetooth-policy.c 
b/src/modules/bluetooth/module-bluetooth-policy.c
index 0a6d59d28..04313aa84 100644
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -85,7 +85,7 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, 
pa_source *source,
 if (!s)
 return PA_HOOK_OK;
 
-if (u->enable_a2dp_source && pa_streq(s, "a2dp_source"))
+if (u->enable_a2dp_source && pa_startswith(s, "a2dp_source"))
 role = "music";
 else if (u->enable_ag && pa_streq(s, "headset_audio_gateway"))
 role = "phone";
@@ -154,7 +154,7 @@ static void card_set_profile(struct userdata *u, pa_card 
*card, bool revert_to_a
 
 /* Check for correct profile based on revert_to_a2dp */
 if (revert_to_a2dp) {
-if (!pa_streq(profile->name, "a2dp_sink"))
+if (!pa_startswith(profile->name, "a2dp_sink"))
 continue;
 } else {
 if (!pa_streq(profile->name, "headset_head_unit"))
@@ -196,11 +196,11 @@ static void switch_profile(pa_card *card, bool 
revert_to_a2dp, void *userdata) {
 return;
 
 /* Skip card if already has active a2dp profile */
-if (pa_streq(card->active_profile->name, "a2dp_sink"))
+if (pa_startswith(card->active_profile->name, "a2dp_sink"))
 return;
 } else {
 /* Skip card if does not have active a2dp profile */
-if (!pa_streq(card->active_profile->name, "a2dp_sink"))
+if (!pa_startswith(card->active_profile->name, "a2dp_sink"))
 return;
 
 /* Skip card if already has active hsp profile */
@@ -307,7 +307,7 @@ static pa_hook_result_t 
card_init_profile_hook_callback(pa_core *c, pa_card *car
 
 /* Ignore card if has already set other initial profile than a2dp */
 if (card->active_profile &&
-!pa_streq(card->active_profile->name, "a2dp_sink"))
+!pa_startswith(card->active_profile->name, "a2dp_sink"))
 return PA_HOOK_OK;
 
 /* Set initial profile to hsp */
@@ -359,7 +359,7 @@ static pa_hook_result_t 
profile_available_hook_callback(pa_core *c, pa_card_prof
 return PA_HOOK_OK;
 
 /* Do not automatically switch profiles for headsets, just in case */
-if (pa_streq(profile->name, "a2dp_sink") || pa_streq(profile->name, 
"headset_head_unit"))
+if (pa_startswith(profile->name, "a2dp_sink") || pa_streq(profile->name, 
"headset_head_unit"))
 return PA_HOOK_OK;
 
 is_active_profile = card->active_profile == profile;
-- 
2.20.1

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


[pulseaudio-discuss] [PATCH v14 2/9] bluetooth: Add missing newlines into inline XML document

2020-03-19 Thread Pali Rohár
When calling introspection function, newlines in XML document makes it
better readable. There are already leading spaces for indentation but
newlines were probably forgotten.
---
 src/modules/bluetooth/bluez5-util.c | 44 ++---
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/modules/bluetooth/bluez5-util.c 
b/src/modules/bluetooth/bluez5-util.c
index a21896ede..eed64dbe7 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -55,28 +55,28 @@
 
 #define ENDPOINT_INTROSPECT_XML \
 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE   \
-""\
-" "  \
-"  "  \
-"   "  \
-"   "\
-"  "   \
-"  "   \
-"   "  \
-"   "\
-"  "   \
-"  "\
-"   "  \
-"  "   \
-"  "   \
-"  "   \
-" " \
-" " \
-"  "\
-"   "  \
-"  "   \
-" " \
-""
+"\n"  \
+" \n"\
+"  \n"\
+"   \n"\
+"   \n"  \
+"  \n" \
+"  \n" \
+"   \n"\
+"   \n"  \
+"  \n" \
+"  \n"  \
+"   \n"\
+"  \n" \
+"  \n" \
+"  \n" \
+" \n"   \
+" \n"   \
+"  \n"  \
+"   \n"\
+"  \n" \
+" \n"   \
+"\n"
 
 struct pa_bluetooth_discovery {
 PA_REFCNT_DECLARE;
-- 
2.20.1

___
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-03-19 Thread Pali Rohár
On Tuesday 21 January 2020 16:17:16 Georg Chini wrote:
> > +/* 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, 
> > _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 > 
> > capabilities_table[i].max_bitpool)
> > +current_range = capabilities_table[i].max_bitpool - 
> > capabilities_table[i].min_bitpool;
> > +else
> > +current_range = capabilities->max_bitpool - 
> > capabilities_table[i].min_bitpool;
> > +}
> 
> Why not simply
> 
> current_range = PA_MIN(capabilities->max_bitpool,
> capabilities_table[i].max_bitpool) - PA_MAX(capabilities->min_bitpool,
> capabilities_table[i].min_bitpool)
> 
> > +
> > +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'm revisiting this part of code and I figured out, that I was right and
this "best_key" evaluation make sense for "sbc_auto_caps" configuration.

In this code there are two for-loops:

  PA_HASHMAP_FOREACH_KV(key, a2dp_capabilities, capabilities_hashmap, state) {

for (i = 0; i < capabilities_table_elements; i++) {

}

if (...) {
  best_key = ...
}

  }

outer loop is iterating capabilities_hashmap members which contains list
of "remote" device capabilities. Remote device may provide up to the N
arbitrary entries which are not under pulseaudio control.

inner loop is iterating capabilities_table members, which are pulseaudio
list, for auto profile it is one-member array sbc_auto_caps with range
of bitpools.

So the whole outer loop try to find the best remote capability for
pulseaudio capability sbc_auto_caps[0].

I hope it is clear now.

-- 
Pali Rohár
pali.ro...@gmail.com
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Bluetooth codec selection

2020-03-17 Thread Pali Rohár
On Tuesday 17 March 2020 11:23:22 Tanu Kaskinen wrote:
> On Sun, 2020-01-12 at 12:42 +0100, Pali Rohár wrote:
> > On Sunday 12 January 2020 09:21:31 Tanu Kaskinen wrote:
> > > On Tue, 2020-01-07 at 19:37 +0100, 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
> > > >   .

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

2020-03-17 Thread Pali Rohár
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 pro

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

2020-03-16 Thread Pali Rohár
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).

-- 
Pali Rohár
pali.ro...@gmail.com
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2020-03-16 Thread Pali Rohár
Hello! Below is my email from December 2019 about a new and I think
proper way how to handle Bluetooth HSP and HFP profiles on Linux desktop
system which do not have any cellular modem or other mobile hardware.

I would like to ask audio people and teams (bluez-alsa, pipewire) and
also other people around. Are you interested in using my hsphfpd DBus
API in audio applications? And if yes, would you implement this API in
audio routing software? Do you have some comments or review of hsphfpd
API? Or would you like to somehow extend it? Also who could be
interesting in helping, developing, testing or maintaining hsphfpd
daemon itself?

On Sunday 01 December 2019 19:57:40 Pali Rohár wrote:
> Hello!
> 
> I'm sending this email to relevant mailing lists and other people who
> could be interested in it. (I'm not subscribed to all of ML, so please
> CC me when replying).
> 
> 
> I would like to open a discussion about a completely new way of handling
> Bluetooth HSP and HFP profiles on Linux. These two profiles are the only
> standard way how to access microphone data from Bluetooth Headsets.
> 
> 
> Previously in bluez4, HFP profile was implemented by bluez daemon and
> telephony HFP functionality was provided by either dummy modem, ofono
> modem or by Nokia's CSD Maemo modem.
> 
> In bluez5 version was modem code together with implementation of HFP
> profile removed. And let implementation of HSP and HFP profiles to
> external application.
> 
> Currently HSP profile is implemented in pulseaudio daemon to handle
> microphone and Bluetooth speakers. HFP profile is not implemented yet.
> 
> 
> HSP and HFP profiles use AT modem commands, so its implementation needs
> to parse and generates AT commands, plus implement needed state machine
> for it.
> 
> And now problem is that last version of HFP profile specification is too
> complicated, plus Bluetooth headsets vendors started to inventing and
> using of own custom extensions to HFP profile and AT commands.
> 
> Main problem of this "external" implementation outside of bluez is that
> only one application can communicate with remote Bluetooth device. It
> is application which received needed socket from bluez.
> 
> So in this design if audio daemon (pulseaudio) implements HFP profile
> for processing audio, and e.g. power supply application wants to
> retrieve battery level from Bluetooth device, it means that audio daemon
> needs to implement also battery related functionality.
> 
> It does not make sense to force power supply daemon (upower) to
> implement audio routing/encoding/decoding or audio daemon (power supply)
> to force implementing battery related operations.
> 
> 
> For handle this problem I would like to propose a new way how to use and
> implement HSP and HFP profiles on Linux.
> 
> Implement a new HSP/HFP daemon (I called it hsphfpd) which register HSP
> and HFP profiles in bluez and then exports functionality for all other
> specific applications via DBus API (API for audio, power supply, input
> layer, telephony functions, vendor extensions, etc...). So it would acts
> as proxy daemon between bluez and target applications (pulseaudio,
> upower, ofono, ...)
> 
> This would simplify whole HFP usage as applications would not need to
> re-implement parsing and processing of AT commands and it would allow
> more applications to use HFP profile at one time. And also it means that
> audio software does not have to implement telephony stack or power
> supply operations.
> 
> 
> I wrote a document how such DBus API could look like, see here:
> 
>   https://github.com/pali/hsphfpd-prototype/raw/prototype/hsphfpd.txt
> 
> 
> And also I implemented "prototype" implementation to verify that
> designed API make sense and can be really implemented. Prototype fully
> supports HSP profile in both HS and AG role, plus HFP profile in HF
> role. This prototype implementation is available here:
> 
>   https://github.com/pali/hsphfpd-prototype
> 
> Some other details are written in README:
> 
>   https://github.com/pali/hsphfpd-prototype/raw/prototype/README
> 
> 
> What do you think about it? Does it make sense to have such design?
> Would you accept usage of such hsphfpd daemon, implemented according to
> specification, on Linux desktop?
> 
> I would like to hear your opinion if I should continue with this hsphfpd
> design, or not.
> 
> 
> With this design and implementation of hsphfpd is possible to easily fix
> pulseaudio issue about power supply properties:
> 
>   https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/722

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: PGP signature
___
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 Pali Rohár
On Tuesday 18 February 2020 15:29:02 Georg Chini wrote:
> On 18.02.20 13:37, Pali Rohár wrote:
> > > 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.

"Workaround" is not a solution for something which is going to be
discussed how is going to be implemented.

But basically take what is needed (e.g. from my hsphfpd prototype code),
implement it... and you would ends up with half of working telephony
stack.

> > > I don't understand. What you loose are the telephony functions
> > > of the headset like re-dialing and nothing else. The telephone
> > > functionality of a headset cannot be implemented in an audio
> > > server anyway. See also my comments at the bottom.
> > You loose all functionality. HFP profile is implemented in ofono. If you
> > turn then plugin off, then you would loose whole HFP profile
> > functionality. Pulseaudio does not implement HFP profile. What you do
> > not understand on this fact?
> > 
> > If you turn off module which handles HFP profile, then you cannot
> > connect any HFP device to your computer as there is not running any
> > application which could be able to handle HFP profile. I really do not
> > know how to formulate this fact to be better understandable.
> I am only talking about the co-existence of ofono and PA. So you
> can use ofono to implement telephony on one device and you
> could (if it were implemented) use a headset with PA at the same
> time without interference. (If PA would implement a button press
> event, you could even pick up a call by sending the event to ofono.
> I implemented this myself a while ago.)

So this helps only in scenario when you have two devices, first you want
to use for telephony without audio and second one for audio without
telephony. Ok, I agree that this is useful and would work.

But it does not help with you want to use bluetooth HFP headset for both
audio and telephony at the same time...

> > > > Seems you misunderstood the point. The point is that if you implement
> > > > HFP profile in one application and HSP in second application, then you
> > > > need to implement common functionality on two different places.
> > > > 
> > > > So if HSP profile stay implemented in pulseaudio, you would have to
> > > > implement those missing functionality in pulseaudio.
> > > > And if HFP profile is implemented in ofono (or other application) then
> > > > missing functionality must be implemented in that ofono application.
> > > > 
> > > > So you would have implementation of e.g. power supply in two different
> > > > locations (for HSP in pulseaudio, for HFP in ofono). And this
> > > > functionality is basically same, so you would have to implement same
> > > > logic on two different places.
> > > > 
> > > > If you would need to extend it, you would have to do it again on two
> > > > different places.
> > > > 
> > > > In hsphfpd design, I implemented it on one place, in one daemon, which
> > > > shares common functions/code.
> > > All well, but it seems that actually none of the other audio stacks
> > > wants your hsphfpd.
> > Source please.
> > 
> > I got positive reactions about hsphfpd design except from ofono developers.
> I only saw reactions that boiled down to "feel free to implement it, might
> be nice,
> but we are not committing to use it" on the PA mailing list. But maybe I
> read what
> I wanted to read and maybe you got other reactions elsewhere.

That is from ofono developers who are not going to use it.

> > > > > The RFCOMM channel is created when the profile is connected,
> > > > > so it should be possible to have one RFCOMM to device A in AG role
> > > > > and another one to device B in HS role and have ofono handle one
> > > > > device while PA handles the other.
> > > > Seems you again misunderstood the main problem. Please look at my
> > > > hsphppfd email where I already tried to explain it. Via rfcomm socket
> > >

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

2020-02-18 Thread Pali Rohár
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).

> > 
> > > Maybe you have to supply some 

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

2020-02-18 Thread Pali Rohár
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.

> 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.

> 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 bluetoot

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

2020-02-18 Thread Pali Rohár
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.

> > 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 :-(

> > 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 i

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

2020-02-15 Thread Pali Rohár
  anything.

So as you can see there is no reasonable solution. Bluetooth rfcomm
socket would be owned either by ofono (and then there would be no
support for computers without cellular modem) or by other application
e.g. pulseaudio, hsphfpd, ... (and then ofono needs to be stopped and
telephony functions would not be probably supported in near future).


And now I would like to hear from you, pulseaudio developers/maintainers,
which option 1) - 5) you choose to solve problem with Bluetooth HSP and
HFP profiles, specially for wide band support, battery level support,
input event support, telephony support and etc.. So features which are
provided and supported by now all common Bluetooth headsets.

I'm willing to implement option 2). I have already implemented prototype
implementation of hsphfpd and it is already working. So missing part is
support from pulseaudio side. I can implement it and push pulseaudio
code via pull request or patch to mailing list. For pulseaudio it means
implementing just audio parts of HSP nad HFP profiles. Not telephony or
battery/power functions. If somebody is interesting in this option, help
me with this (either pulseaudio part of hsphfpd daemon itself), please
let me know.

On other options 1), 3), 4) or 5) I'm going to participate as I do not
think they bring any value to Linux desktop. And just cause another
problems.

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.

Please note that this is not problem only for pulseaudio, but also for
any other audio software which want to support HSP/HFP on Linux.

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: PGP signature
___
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-02-05 Thread Pali Rohár
On Sunday 02 February 2020 18:46:24 Georg Chini wrote:
> 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.

Yes, I can change it.

> > > > > > +
> > > > > > +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.

Ok, I will drop it for now.

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: PGP signature
___
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-02-02 Thread Pali Rohár
> > > +ret = fill_preferred_configuration_table(default_sample_spec, 
> > > > capabilities_buffer, capabilities_size, config_buffer, 
> > > > sbc_auto_caps_table, PA_ELEMENTSOF(sbc_auto_caps_table));
> > > > +config->max_bitpool = PA_MIN(default_bitpool(config->frequency, 
> > > > config->channel_mode), config->max_bitpool);
> > > > +config->max_bitpool = PA_MAX(config->max_bitpool, 
> > > > config->min_bitpool);
> > > > +
> > > > +return ret;
> > > >}
> > > >static void set_params(struct sbc_info *sbc_info) {
> > > > @@ -500,13 +857,17 @@ static size_t reduce_encoder_bitrate(void 
> > > > *codec_info, size_t write_link_mtu) {
> > > >uint8_t bitpool;
> > > >/* Check if bitpool is already at its limit */
> > > > -if (sbc_info->sbc.bitpool <= SBC_BITPOOL_DEC_LIMIT)
> > > > -return 0;
> > > > -
> > > > -bitpool = sbc_info->sbc.bitpool - SBC_BITPOOL_DEC_STEP;
> > > > -
> > > > -if (bitpool < SBC_BITPOOL_DEC_LIMIT)
> > > > -bitpool = SBC_BITPOOL_DEC_LIMIT;
> > > > +if (sbc_info->mode == SBC_CHANNEL_MODE_MONO || sbc_info->mode == 
> > > > SBC_CHANNEL_MODE_DUAL_CHANNEL) {
> > > > +/* For Mono and Dual Channel modes bitpool value is separete 
> > > > for each channel */
> > > > +bitpool = sbc_info->sbc.bitpool - 
> > > > SBC_SEPARATE_BITPOOL_DEC_STEP;
> > > > +if (bitpool <= SBC_SEPARATE_BITPOOL_DEC_LIMIT)
> > > Should it not be "<" instead of "<="? Or are the limits themselves no
> > > acceptable values?
> > > > +return 0;
> > > > +} else {
> > > > +/* For Stereo modes bitpool value is combined for both 
> > > > channels */
> > > > +bitpool = sbc_info->sbc.bitpool - 
> > > > SBC_COMBINED_BITPOOL_DEC_STEP;
> > > > +if (bitpool <= SBC_COMBINED_BITPOOL_DEC_LIMIT)
> > > Same here.
> > Both macros are some minimal values which during my testing generated
> > unusable audio output. So maybe somebody propose different values (maybe
> > higher?) and therefore +/-1 errors could be there...
> So I understand right that the limits themselves are not usable?

Limits are usable, but probably are not the best. Bitpool values below
the current limits generates unusable audio. But probably bitpool values
around limits could generate audio which for some cases is too degraded.

> > 
> > > > diff --git a/src/modules/bluetooth/a2dp-codec-util.c 
> > > > b/src/modules/bluetooth/a2dp-codec-util.c
> > > > index 521251aea..7b123f7e1 100644
> > > > --- a/src/modules/bluetooth/a2dp-codec-util.c
> > > > +++ b/src/modules/bluetooth/a2dp-codec-util.c
> > > > @@ -26,24 +26,38 @@
> > > >#include "a2dp-codec-util.h"
> > > > +extern const pa_a2dp_codec pa_a2dp_codec_sbc_lq;
> > > >extern const pa_a2dp_codec pa_a2dp_codec_faststream;
> > > >extern const pa_a2dp_codec pa_a2dp_codec_faststream_mic;
> > > > +extern const pa_a2dp_codec pa_a2dp_codec_sbc_mq;
> > > >extern const pa_a2dp_codec pa_a2dp_codec_sbc;
> > > >#ifdef HAVE_OPENAPTX
> > > >extern const pa_a2dp_codec pa_a2dp_codec_aptx;
> > > > +#endif
> > > > +extern const pa_a2dp_codec pa_a2dp_codec_sbc_hq;
> > > Why have you put this in between? The order of declaration does not
> > > matter and for me it looks better if everything related to one codec
> > > stays together.
> > Just because to have same order as in table pa_a2dp_codecs.
> As said, I would prefer per-codec ordering here.

Ok, this could be changed.

> > 
> > > > +#ifdef HAVE_OPENAPTX
> > > >extern const pa_a2dp_codec pa_a2dp_codec_aptx_hd;
> > > >#endif
> > > > +extern const pa_a2dp_codec pa_a2dp_codec_sbc_xq1;
> > > > +extern const pa_a2dp_codec pa_a2dp_codec_sbc_xq2;

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: PGP signature
___
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-22 Thread Pali Rohár
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.

On Tuesday 21 January 2020 16:17:16 Georg Chini wrote:
> 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[] = {
>

Re: [pulseaudio-discuss] [PATCH] core, modules: Remove useless EINTR tests

2020-01-16 Thread Pali Rohár
On Thursday 16 January 2020 17:31:17 Tanu Kaskinen wrote:
> Resurrecting this old patch...
> 
> On Mon, 2019-06-03 at 15:43 +0200, Pali Rohár wrote:
> > On Tuesday 28 May 2019 16:49:19 Frédéric Danis wrote:
> > > Since commit ad447d14682 (in 2009) pa_read and pa_write take care of
> > > handling EINTR error.
> > > So, pa_read, pa_write, pa_iochannel_read and pa_iochannel_write can not
> > > exit with errno set to EINTR, and testing it is useless.
> > > ---
> > >  src/modules/bluetooth/module-bluez5-device.c | 16 +---
> > >  src/modules/module-esound-sink.c |  4 +-
> > >  src/modules/module-pipe-sink.c   | 17 -
> > >  src/modules/module-pipe-source.c |  4 +-
> > >  src/modules/module-solaris.c |  4 +-
> > >  src/modules/oss/module-oss.c | 10 +
> > >  src/pulsecore/fdsem.c| 40 ++--
> > >  src/pulsecore/iochannel.c|  2 +-
> > >  src/pulsecore/protocol-esound.c  |  8 ++--
> > >  src/pulsecore/protocol-simple.c  |  2 +-
> > >  10 files changed, 32 insertions(+), 75 deletions(-)
> > > 
> > > diff --git a/src/modules/bluetooth/module-bluez5-device.c 
> > > b/src/modules/bluetooth/module-bluez5-device.c
> > > index 56c96054d..f850a3a41 100644
> > > --- a/src/modules/bluetooth/module-bluez5-device.c
> > > +++ b/src/modules/bluetooth/module-bluez5-device.c
> > > @@ -279,10 +279,6 @@ static int sco_process_render(struct userdata *u) {
> > >  
> > >  saved_errno = errno;
> > >  
> > > -if (saved_errno == EINTR)
> > > -/* Retry right away if we got interrupted */
> > > -continue;
> > > -
> > >  pa_memblock_unref(memchunk.memblock);
> > >  
> > >  if (saved_errno == EAGAIN) {
> > > @@ -445,11 +441,7 @@ static int a2dp_write_buffer(struct userdata *u, 
> > > size_t nbytes) {
> > >  
> > >  if (l < 0) {
> > >  
> > > -if (errno == EINTR)
> > > -/* Retry right away if we got interrupted */
> > > -continue;
> > > -
> > > -else if (errno == EAGAIN) {
> > > +if (errno == EAGAIN) {
> > >  /* Hmm, apparently the socket was not writable, give up 
> > > for now */
> > >  pa_log_debug("Got EAGAIN on write() after POLLOUT, 
> > > probably there is a temporary connection loss.");
> > >  break;
> > > @@ -543,11 +535,7 @@ static int a2dp_process_push(struct userdata *u) {
> > >  
> > >  if (l <= 0) {
> > >  
> > > -if (l < 0 && errno == EINTR)
> > > -/* Retry right away if we got interrupted */
> > > -continue;
> > > -
> > > -else if (l < 0 && errno == EAGAIN)
> > > +if (l < 0 && errno == EAGAIN)
> > >  /* Hmm, apparently the socket was not readable, give up 
> > > for now. */
> > >  break;
> > >  
> > 
> > Hi! This change conflicts with "Implement reading SO_TIMESTAMP for A2DP
> > source" patch as it stops using pa_read() function. For SO_TIMESTAMP is
> > needed recvmsg() and then also handling of EINTR/EAGAIN.
> 
> Thanks for pointing this out. It would have been easy for me to miss
> this, since git rebased the patch without conflicts.

This is because pa_read() was replaced by recvmsg() in bluetooth code.
So above information about EINTR is not valid for bluetooth code which
reads data, and needs to properly handle EINTR error code.

> fdsem.c had changes like this:
> 
> > @@ -151,11 +151,8 @@ static void flush(pa_fdsem *f) {
> >  uint64_t u;
> >  
> >  if ((r = pa_read(f->efd, , sizeof(u), NULL)) != sizeof(u)) {
> > -
> > -if (r >= 0 || errno != EINTR) {
> > -pa_log_error("Invalid read from eventfd: %s", r < 0 ? 
> > pa_cstrerror(errno) : "EOF");
> > -pa_assert_not_reached();
> > -}
> > +pa_log_error("Invalid read from eventfd: %s", r < 0 ? 
> > pa_cstrerror(errno) : "EOF");
> > +pa_assert_not_reached();
> >  
> >  continue;
> 
> The "continue" statement after the assertion is unnecessary, so I
> removed it.
> 
> I created an MR for this patch, since we now push all changes through
> GitLab: 
> https://gitlab.freedesktop.org/pulseaudio/pulseaudio/merge_requests/238
> 
> I didn't merge the change yet, because we're currently in freeze. I'll
> merge it once 14.0 is out.
> 
> Thanks for the patch, Frédéric, and sorry for the long delay!
> 

-- 
Pali Rohár
pali.ro...@gmail.com
___
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-12 Thread Pali Rohár
On Sunday 12 January 2020 09:21:31 Tanu Kaskinen wrote:
> On Tue, 2020-01-07 at 19:37 +0100, 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 selectio

Re: [pulseaudio-discuss] Bluetooth codec selection

2020-01-08 Thread Pali Rohár
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 

Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2020-01-08 Thread Pali Rohár
e 'AG without a real modem' use case.  That would seem to be the
> biggest 'win' and it should be fairly easy to make this work.

Ok, I will start a separate thread.

> > 
> > I'm not against for it, but I thought that having functionality which is
> > not related to telephony / modem you would not want to see in ofono
> > project (like linux uinput layer for button events or API for displaying
> > raw text on embedded display; or CSR audio codec negotiation).
> > 
> > So how do you see possibility to have also HSP profile in ofono? So have
> > one place which would provide audio API for SCO? Because this is a big
> > requirements from audio software side, to not use 4 different APIs to
> > access SCO sockets (and its rfcomm / SLC configuration) in HSP and HFP
> > profiles.
> > 
> 
> HSP is a separate issue.

It is not separate issue. It is one of the main issues. If ofono is not
going to support HSP then there is absolutely no reason why to use ofono
and extend it to support a new features which currently do not support
(like CSR codecs which are in both HSP and HFP profiles). Basically
without it ofono is unusable for handling bluetooth audio on Linux
desktop.

> Maybe we can handle it like the 'dundee' daemon
> inside oFono (which handles Bluetooth DUN profile).  In other words have a
> dedicated daemon for hsp support that reuses the relevant bits of oFono and
> maybe exposes the same APIs (i.e the ones documented in
> doc/handsfree-audio-api.txt).  That would make life for PulseAudio pretty
> easy.
> 
> Regards,
> -Denis

-- 
Pali Rohár
pali.ro...@gmail.com


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


[pulseaudio-discuss] Bluetooth codec selection

2020-01-07 Thread Pali Rohár
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).

-- 
Pali Rohár
pali.ro...@gmail.com


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


Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2020-01-04 Thread Pali Rohár
On Friday 20 December 2019 23:46:57 Pali Rohár wrote:
> Hi!
> 
> On Friday 20 December 2019 15:19:01 Denis Kenzior wrote:
> > Hi Pali,
> > 
> > > > There have been one or two implementations of AG role fully external to
> > > > oFono.  These implementations simply used the existing oFono APIs to 
> > > > drive
> > > > the modem.
> > > 
> > > bluez & pulseaudio developers told me that it would be a good idea to
> > > avoid implementing a new AT parser for telephony stack. And rather use
> > > ofono implementation for telephony part...
> > 
> > In my opinion there's nothing scary about AT parsing.  In fact that is the
> > easiest part of this whole venture.  If you don't want to roll your own
> > parser, you can borrow one from the oFono project.  We already solved this
> > nicely in the form of the gatchat library.  You could incorporate this into
> > your project (if it is GPL compatible).  Or you could wait until we port
> > gatchat to ell which will be under LGPL license.
> > 
> > > 
> > > But if I should use existing DBus API provided by ofono, it means that I
> > > need to do parsing of all AT commands (including telephony) and
> > > translate them to ofono DBus API.
> > 
> > I think you will need to do this regardless.  Otherwise I fail to see how
> > you prevent one 'agent' from consuming AT commands it shouldn't be. This is
> > a possibility you need to consider, whether it happens by accident or
> > maliciously.
> 
> Some subset of AT commands are needed to parse and interpret. But not
> telephony commands and having up-to-date internal telephony state.
> 
> > > 
> > > I agree, this should work and there is not need to modify ofono. But it
> > > means that in hsphfpd daemon I need to have full AT parser for all
> > > telephony commands and it was something which bluez / pa developers
> > > thought that should be avoided. Therefore I come up with idea that
> > > telephony commands would be handled by external Telephony Agent, which
> > > can be ofono.
> > 
> > Understood.  But I think the metric function was selected inappropriately in
> > this case.  My opinion is that you should have started with what the overall
> > architecture should look like; you should not have based design decisions on
> > which parts might be a little hard to implement.
> > 
> > > 
> > > > You could do that.  But as I said, we rejected such a design a
> > > > long time ago due to complexity and other issues.
> > > 
> > > Anyway, what is the problem with accepting modem socket in ofono via
> > > DBus and starts talking with it like with any other modem which ofono
> > > supports? Currently ofono already takes modem socket from bluez via DBus
> > > API, so in same way hsphfpd can pass modem socket to ofono. Basically
> > > ofono then can reuse same code which already uses for sockets from
> > > bluez, just it do not have to parse and interpret audio related AT
> > > commands (as these are handled by hsphpfd itself).
> > > 
> > > What are exact issues? I do not see complexity at ofono part (as has
> > > already everything implemented) and currently I do not see those "other"
> > > issues.
> > 
> > The issues are many.  And really the question is not whether it 'could be'
> > done, but whether it 'should be' done.  Let me describe a couple examples:
> > 
> > - In the case of HF role (1), oFono already provides all the necessary APIs.
> > So put yourself in oFono's maintainer shoes.  What would we gain by
> > supporting almost the same but different mechanism?  We would have to
> > introduce a new hfp_hf plugin, one that is almost identical, but different
> > to hfp_hf_bluez5 plugin.
> 
> Yes, this would be needed, but because code os very similar it could be
> reused from one common place.
> 
> > These two plugins would have coexistence issues,
> > which would add more complexity.  Then there's the impact on PulseAudio and
> > other users.  How do they know when to use the HandsfreeAudio API vs some
> > external API?
> 
> Because pulseaudio has already own implementation of HSP profile and
> some kind of ofono implementation (which you named below "giant hack")
> it already needs to handle such problem.
> 
> But solution should be relatively simple. If we decide that new daemon
> is "new proper way" then it would have higher priority as current HFP
> API by ofono. So if hsphfpd is registered on dbus && hsphfpd 

Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-21 Thread Pali Rohár
e all HSP
and HFP profile/role combinations.

> - The other example is more practical. HFP Service Level Connection (SLC)
> establishment is actually quite tricky.  There are certain limitations on
> what can and cannot be done prior to SLC establishment, including how audio
> handling is done.

I know :-) I already implemented prototype implementation to check and
see how complicated it is and if API make sense and how hard it is for
agents (audio - pulseaudio) implement and maintain it.

> Unfortunately, codec negotiation, indicator negotiation,
> and feature negotiation are part of the SLC. oFono already solves all of
> this and handles all of it nicely.

CSR codecs are not supported nor implemented in ofono. It is more
complicated as HFP codecs... and needs a new API for audio application.
Another value which brings my hsphfpd is that it handles these CSR
codecs and provide API for audio application to use them.

> We have passed all relevant
> certification testing.  It is very unclear how you plan to handle this (or
> whether you realistically even can) in your architecture when the
> responsibilities are split between the various daemons.  So again, oFono has
> nothing to gain here...

I was not thinking about certification. It is not something which I
could do And also pulseaudio itself do not have certifications.

> > 
> > You suggested to use phone simulator together with ofono and then
> > starts extending / patching phone simulator to supports all needed parts
> > which are in my hsphfpd design (battery status, button press, codec
> > selection)?
> > 
> 
> Not quite.  I suggested you expand oFono's emulator implementation (for AG
> role) and its DBus APIs (for HF role) to support the new vendor specific
> features that you want.
> 
> Forget about the phone simulator, it is really irrelevant for what you're
> trying to accomplish.

Ok. I thought that phone simulator = ofono emulator. I just saw that
phone simulator which is described in pulseaudio documentation.

> > Also how to handle the main problem of phone simulator that it is too
> > much complicated to setup it on desktop? Looking at the steps...
> > 
> > https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Bluetooth/#index5h2
> > 
> > ... that desktop user needs to run nontrivial commands in command like,
> > plus creating configuration file only just to connect bluetooth headset
> > is ridiculous and non-acceptable for desktop application.
> > 
> > If this problem is not fixed, ofono and phone simulator are not usable
> > as "main" software implementation of HFP profile for usage of bluetooth
> > headsets on Linux.
> 
> oFono was never advertised as solving the 'HFP AG without a modem' use case.
> This is something we never had as a requirement / objective. Phonesim is a
> development tool.  So of course it isn't trivial to setup, it isn't meant to
> be used in production in the first place.  The use of phonesim described in
> the PA wiki, while creative, is a giant hack ;)

Ok, so we definitely agree that ofono currently do not support HFP AG
without modem for desktop users. And this scenario is needed for
connecting bluetooth headsets, so we need some solution for it.

> Basically it all boils down to the fact that nobody has stepped up all this
> time to solve a particular use case you care about.  But blaming oFono for
> this is misguided.
> 
> So, if you want to solve the HFP AG without a modem case I fully support
> your efforts.

Ok! So which options do we have?

> Perhaps this can even be solved in oFono itself (since it already does 90%
> of what you want) by making the modem requirement optional.  What we could
> do for example is to create a dummy modem if an AG connection is requested
> and no other suitable modems are detected in the system.  The resultant AG
> wouldn't have any call control capability, it could still be used for
> transferring audio data, battery, etc.  If you want to pursue this, we can
> brainstorm further.

Well, if this would work automatically without any user interaction or
without special setup, it seems to be usable.

But what is needed from this implementation in ofono? Basically API for
each functionality designed in hsphfod daemon. And one of it is also
support for HSP profile (with CSR and Apple extensions).

I'm not against for it, but I thought that having functionality which is
not related to telephony / modem you would not want to see in ofono
project (like linux uinput layer for button events or API for displaying
raw text on embedded display; or CSR audio codec negotiation).

So how do you see possibility to have also HSP profile in ofono? So have
one place which would provide audio API for SCO? Because this is a big
requirements from audio software side, to not use 4 different APIs to
access SCO sockets (and its rfcomm / SLC configuration) in HSP and HFP
profiles.

-- 
Pali Rohár
pali.ro...@gmail.com


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


Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-20 Thread Pali Rohár
 used the existing oFono APIs to drive
> the modem.

bluez & pulseaudio developers told me that it would be a good idea to
avoid implementing a new AT parser for telephony stack. And rather use
ofono implementation for telephony part...

But if I should use existing DBus API provided by ofono, it means that I
need to do parsing of all AT commands (including telephony) and
translate them to ofono DBus API.

I agree, this should work and there is not need to modify ofono. But it
means that in hsphfpd daemon I need to have full AT parser for all
telephony commands and it was something which bluez / pa developers
thought that should be avoided. Therefore I come up with idea that
telephony commands would be handled by external Telephony Agent, which
can be ofono.

> You could do that.  But as I said, we rejected such a design a
> long time ago due to complexity and other issues.

Anyway, what is the problem with accepting modem socket in ofono via
DBus and starts talking with it like with any other modem which ofono
supports? Currently ofono already takes modem socket from bluez via DBus
API, so in same way hsphfpd can pass modem socket to ofono. Basically
ofono then can reuse same code which already uses for sockets from
bluez, just it do not have to parse and interpret audio related AT
commands (as these are handled by hsphpfd itself).

What are exact issues? I do not see complexity at ofono part (as has
already everything implemented) and currently I do not see those "other"
issues.

> Or you can ignore the call control aspects entirely...
> 
> But in the end, it is your architecture.  All I can do is point out (early
> in the process) what is and what is not acceptable to oFono upstream.

And this is why I started discussion across all projects (pulseaudio,
bluez, ofono) so describe current problem and come up with some
architecture which would be suitable for all projects. So thanks for all
your points.

You suggested to use phone simulator together with ofono and then
starts extending / patching phone simulator to supports all needed parts
which are in my hsphfpd design (battery status, button press, codec
selection)?

Also how to handle the main problem of phone simulator that it is too
much complicated to setup it on desktop? Looking at the steps...

https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Bluetooth/#index5h2

... that desktop user needs to run nontrivial commands in command like,
plus creating configuration file only just to connect bluetooth headset
is ridiculous and non-acceptable for desktop application.

If this problem is not fixed, ofono and phone simulator are not usable
as "main" software implementation of HFP profile for usage of bluetooth
headsets on Linux.

> > > 
> > > Okay, I see now.  Yes, the above is correct.  My comments about not 
> > > needing
> > > a modem device hold true only if oFono is in HFP HF role connecting to an
> > > AG.
> > 
> > Ok. So I guess now you understood main problem. I thought it was
> > obvious, but seems that bluetooth HFP is too complicated, so talking
> > about it always needs more detailed explanation. Sorry for that if it
> > was not clear from my side since beginning what are requirements for my
> > setup.
> 
> Well it was a bit of reading comprehension fail on my part as well.  The two
> roles are really quite different, so precise language helps.
> 
> Regards,
> -Denis

-- 
Pali Rohár
pali.ro...@gmail.com


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


Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-20 Thread Pali Rohár
s
> just work without a modem.  If we're the AG, then yes you need a modem to be
> driven by the AG connection.

AG.

> > > 
> > > You must be thinking of the oFono HFP AG implementation...
> > 
> > Yes! For connecting bluetooth headset you need HFP AG implementation.
> > 
> > And I guess this is the reason why simulator is needed. HFP headset acts
> > as a "client" for modem. Therefore on desktop / laptop you need to
> > implement "modem server" which will be used by HFP headset "client".
> > 
> > And phone simulator is doing exactly this "modem server", it is
> > simulator of modem.
> > 
> 
> Okay, I see now.  Yes, the above is correct.  My comments about not needing
> a modem device hold true only if oFono is in HFP HF role connecting to an
> AG.

Ok. So I guess now you understood main problem. I thought it was
obvious, but seems that bluetooth HFP is too complicated, so talking
about it always needs more detailed explanation. Sorry for that if it
was not clear from my side since beginning what are requirements for my
setup.

And question now is how to solve this problem for desktop computers?
Users who want to use their bluetooth headset (HF role on headset; AG
role on laptop) really do not want to do complicated setup of modem
simulator just to use microphone input from headset.

This is reason why I'm proposing hsphfpd daemon and with its API to work
without any modem emulator or ofono software (but optionally modem could
be connected).

-- 
Pali Rohár
pali.ro...@gmail.com


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


Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-18 Thread Pali Rohár
On Wednesday 18 December 2019 11:00:07 Denis Kenzior wrote:
> Hi Pali,
> 
> On 12/16/19 3:15 AM, Pali Rohár wrote:
> > Hi!
> > 
> > On Monday 16 December 2019 00:11:04 Luiz Augusto von Dentz wrote:
> > > Hi Pali,
> > > 
> > > On Thu, Dec 5, 2019 at 11:32 AM Pali Rohár  wrote:
> > > > 
> > > > On Monday 02 December 2019 19:45:12 Pali Rohár wrote:
> > > > > On Monday 02 December 2019 19:01:11 Tanu Kaskinen wrote:
> > > > > > I think hsphfpd should be part of bluetoothd, but if that's not
> > > > > > possible, then that's not possible.
> > > > > 
> > > > > I do not know if bluez developers are interested in having this code 
> > > > > as
> > > > > part of bluez project, specially when in bluez4 HFP profile was there
> > > > > and in bluez5 was HFP code completely removed.
> > > > 
> > > > Hello, could someone from bluez developers comment this Tanu's point?
> > > 
> > > I would have to say no, we are definitely not interested in yet
> > > another daemon for AT parsing, we actually have too many of these
> > > around, either in a form of Modem Manager, oFono, etc.
> > 
> > Proposed hsphfpd daemon is not (only) for parsing AT commands, but for
> > implementing logic around HSP and HFP profiles and export either native
> > interfaces (linux uinput) or DBus interfaces for features provided by
> > HSP and HFP specifications and also for current and future vendor
> > extensions. And part of this HSP/HFP implementation is of course needed
> > parsing and interpreting some of AT commands. Look into my design and
> > API proposal. Current daemons which provides AT parsing (like ofono or
> > modem manager) are not suitable for for whole HSP and HFP profiles with
> > all those extensions (like all possible ways for reporting battery
> > level), so for HFP is needed some of custom AT parser.
> 
> I'm not sure what logic around HSP you really care about.  It is just a
> single button press in the end.

CSR features (battery status level, ...) and CSR codec selection (e.g.
AuriStream). Also some apple extensions are used in HSP profile.

> For HFP, oFono can already support all sorts of extensions.  See for example
> how we handled Siri for HFP support in oFono here:
> https://git.kernel.org/pub/scm/network/ofono/ofono.git/tree/doc/siri-api.txt.

I saw. But it does not support usage of vendor codecs, like CSR
AuriStream and it does not support CSR extensions, like displaying text
on embedded display.

> Many of the extensions you talked about are also relevant for real modems as
> well (like battery reporting, call volume, etc).  Some of these APIs are
> already defined in fact.
> 
> Given the above, oFono upstream has no interest in adding or maintaining
> support this new framework.

Denis, if you are not interested in my proposed hsphfpd daemon, how you
want to solve problem with other extensions and other vendor codecs?

Also in my proposed solution it is possible to use HFP profile without
Telephony Agent (ofono). Do you think it is really a good idea to have
strong dependency on ofono just for bluetooth HFP headset?

Also for using ofono with HFP profile is not possible on desktop
computer which do not have any modem as it is hooked to some active
modem.

There is a way to use ofono sim simulator which provide fake modem, but
its setup is hard on desktop and it not automated.

So connecting bluetooth headset in HFP profile with ofono is something
not so easy and not an obvious way.

-- 
Pali Rohár
pali.ro...@gmail.com


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


Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-18 Thread Pali Rohár
On Wednesday 18 December 2019 18:28:28 Pali Rohár wrote:
> On Wednesday 18 December 2019 11:00:07 Denis Kenzior wrote:
> > Hi Pali,
> > 
> > On 12/16/19 3:15 AM, Pali Rohár wrote:
> > > Hi!
> > > 
> > > On Monday 16 December 2019 00:11:04 Luiz Augusto von Dentz wrote:
> > > > Hi Pali,
> > > > 
> > > > On Thu, Dec 5, 2019 at 11:32 AM Pali Rohár  wrote:
> > > > > 
> > > > > On Monday 02 December 2019 19:45:12 Pali Rohár wrote:
> > > > > > On Monday 02 December 2019 19:01:11 Tanu Kaskinen wrote:
> > > > > > > I think hsphfpd should be part of bluetoothd, but if that's not
> > > > > > > possible, then that's not possible.
> > > > > > 
> > > > > > I do not know if bluez developers are interested in having this 
> > > > > > code as
> > > > > > part of bluez project, specially when in bluez4 HFP profile was 
> > > > > > there
> > > > > > and in bluez5 was HFP code completely removed.
> > > > > 
> > > > > Hello, could someone from bluez developers comment this Tanu's point?
> > > > 
> > > > I would have to say no, we are definitely not interested in yet
> > > > another daemon for AT parsing, we actually have too many of these
> > > > around, either in a form of Modem Manager, oFono, etc.
> > > 
> > > Proposed hsphfpd daemon is not (only) for parsing AT commands, but for
> > > implementing logic around HSP and HFP profiles and export either native
> > > interfaces (linux uinput) or DBus interfaces for features provided by
> > > HSP and HFP specifications and also for current and future vendor
> > > extensions. And part of this HSP/HFP implementation is of course needed
> > > parsing and interpreting some of AT commands. Look into my design and
> > > API proposal. Current daemons which provides AT parsing (like ofono or
> > > modem manager) are not suitable for for whole HSP and HFP profiles with
> > > all those extensions (like all possible ways for reporting battery
> > > level), so for HFP is needed some of custom AT parser.
> > 
> > I'm not sure what logic around HSP you really care about.  It is just a
> > single button press in the end.
> 
> CSR features (battery status level, ...) and CSR codec selection (e.g.
> AuriStream). Also some apple extensions are used in HSP profile.
> 
> > For HFP, oFono can already support all sorts of extensions.  See for example
> > how we handled Siri for HFP support in oFono here:
> > https://git.kernel.org/pub/scm/network/ofono/ofono.git/tree/doc/siri-api.txt.

About Siri: In hsphfpd API it is delegated to Telephony Agent. So
hsphfpd is not going to (re)implement it.

> I saw. But it does not support usage of vendor codecs, like CSR
> AuriStream and it does not support CSR extensions, like displaying text
> on embedded display.
> 
> > Many of the extensions you talked about are also relevant for real modems as
> > well (like battery reporting, call volume, etc).  Some of these APIs are
> > already defined in fact.
> > 
> > Given the above, oFono upstream has no interest in adding or maintaining
> > support this new framework.

Maybe better question: Do you mean that you do not want to maintain
hsphfpd, or that you completely do not want to see that ofono would be
"Telepony Agent" for hsphfpd?

> Denis, if you are not interested in my proposed hsphfpd daemon, how you
> want to solve problem with other extensions and other vendor codecs?
> 
> Also in my proposed solution it is possible to use HFP profile without
> Telephony Agent (ofono). Do you think it is really a good idea to have
> strong dependency on ofono just for bluetooth HFP headset?
> 
> Also for using ofono with HFP profile is not possible on desktop
> computer which do not have any modem as it is hooked to some active
> modem.
> 
> There is a way to use ofono sim simulator which provide fake modem, but
> its setup is hard on desktop and it not automated.
> 
> So connecting bluetooth headset in HFP profile with ofono is something
> not so easy and not an obvious way.
> 

-- 
Pali Rohár
pali.ro...@gmail.com


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


Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-18 Thread Pali Rohár
use ofono sim simulator which provide fake modem, but
> > > its setup is hard on desktop and it not automated.
> > > 
> 
> You must be thinking of the oFono HFP AG implementation...

Yes! For connecting bluetooth headset you need HFP AG implementation.

And I guess this is the reason why simulator is needed. HFP headset acts
as a "client" for modem. Therefore on desktop / laptop you need to
implement "modem server" which will be used by HFP headset "client".

And phone simulator is doing exactly this "modem server", it is
simulator of modem.

> > > So connecting bluetooth headset in HFP profile with ofono is something
> > > not so easy and not an obvious way.
> > > 
> 
> Again, not true.  As I said above, you can use oFono for this use case just
> fine.  Certainly the main driver for the development of oFono was to drive
> real modem hardware, but it isn't limited to that.  So if you want to use it
> only for HFP, you can.

If it is really possible (and need for phone simulator as described
above is not required) then there is completely missing documentation
how to do it. And how should be audio server (pulseaudio) configured to
work in this way.

-- 
Pali Rohár
pali.ro...@gmail.com


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


Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-18 Thread Pali Rohár
On Tuesday 17 December 2019 15:47:16 Luiz Augusto von Dentz wrote:
> Hi Pali,
> 
> On Mon, Dec 16, 2019 at 1:15 AM Pali Rohár  wrote:
> >
> > Hi!
> >
> > On Monday 16 December 2019 00:11:04 Luiz Augusto von Dentz wrote:
> > > Hi Pali,
> > >
> > > On Thu, Dec 5, 2019 at 11:32 AM Pali Rohár  wrote:
> > > >
> > > > On Monday 02 December 2019 19:45:12 Pali Rohár wrote:
> > > > > On Monday 02 December 2019 19:01:11 Tanu Kaskinen wrote:
> > > > > > I think hsphfpd should be part of bluetoothd, but if that's not
> > > > > > possible, then that's not possible.
> > > > >
> > > > > I do not know if bluez developers are interested in having this code 
> > > > > as
> > > > > part of bluez project, specially when in bluez4 HFP profile was there
> > > > > and in bluez5 was HFP code completely removed.
> > > >
> > > > Hello, could someone from bluez developers comment this Tanu's point?
> > >
> > > I would have to say no, we are definitely not interested in yet
> > > another daemon for AT parsing, we actually have too many of these
> > > around, either in a form of Modem Manager, oFono, etc.
> >
> > Proposed hsphfpd daemon is not (only) for parsing AT commands, but for
> > implementing logic around HSP and HFP profiles and export either native
> > interfaces (linux uinput) or DBus interfaces for features provided by
> > HSP and HFP specifications and also for current and future vendor
> > extensions. And part of this HSP/HFP implementation is of course needed
> > parsing and interpreting some of AT commands. Look into my design and
> > API proposal. Current daemons which provides AT parsing (like ofono or
> > modem manager) are not suitable for for whole HSP and HFP profiles with
> > all those extensions (like all possible ways for reporting battery
> > level), so for HFP is needed some of custom AT parser.
> 
> Not following you on this one, oFono is intended for telephony
> functionality

and it should still be for telephony functionality.

> and afaik it could parse battery, etc. Also would your
> daemon include such functionality or you are to combine that with
> oFono?

Have you looked at my proposed API and design document? If not, please
really look at it... I already sent links in first email, but here are:

https://github.com/pali/hsphfpd-prototype/raw/prototype/README
https://github.com/pali/hsphfpd-prototype/raw/prototype/hsphfpd.txt

And if it is not clean how API works or how Agent should behave or how
whole ecosystem should work, please let me know which parts are not
clean so I can update it or explain even more.

All telephony AT commands (more specially, those which are not HFP
specific or which should not be handled by hsphfpd itself) are forwarded
to Telephony Agent. Ofono should be that Telephony Agent for hsphfpd for
handling all telephony stuff.

My hsphfpd daemon does not handle telephony functionality (except just
few commands which are required for HFP to work, but hsphfpd handles it
only when Telephony Agent is not connected).

> I do appreciate the effort you have put into the SBC modes and
> codec support but Im afraid you are going to experience some real pain
> to maintain such a system all in your own, there are a lot of features
> being exposed via AT commands and we risk to have yet another daemon
> that just do parts

Intension of hsphfpd is to dead with all these problems. For all new
functionality which would be introduced in future by vendors, hsphfpd
should be easily extended to either directly support this functionality
or to expose DBus API (or DBus file descriptor with AT socket) for
external application which would handle it.

> of them until the next person comes with a
> different use case and we are back to square one.
> 
> > > That said one
> > > simpler way to resolve all of this is to maintain a plugin to
> > > bluetoothd that way HSP/HFP becomes native again, that can either be
> > > maintained in the tree or out of the tree.
> >
> > I do not see how could just plain plugin for bluez without AT parser
> > could help. This seems to just complicate whole implementation. I
> > already implemented prototype implementation of hsphfpd to see how
> > complicated it is and what is needed...
> 
> Well the exactly the same thing with yet another daemon, we obviously
> will need an AT parser,

Yes, some AT parser would be still needed...

> but the nice thing of being a native plugin is
> that it can detect if another entity register for HSP/HFP and disable
> itself (or have a policy to control that), the implementation can be

Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-16 Thread Pali Rohár
Hi!

On Monday 16 December 2019 00:11:04 Luiz Augusto von Dentz wrote:
> Hi Pali,
> 
> On Thu, Dec 5, 2019 at 11:32 AM Pali Rohár  wrote:
> >
> > On Monday 02 December 2019 19:45:12 Pali Rohár wrote:
> > > On Monday 02 December 2019 19:01:11 Tanu Kaskinen wrote:
> > > > I think hsphfpd should be part of bluetoothd, but if that's not
> > > > possible, then that's not possible.
> > >
> > > I do not know if bluez developers are interested in having this code as
> > > part of bluez project, specially when in bluez4 HFP profile was there
> > > and in bluez5 was HFP code completely removed.
> >
> > Hello, could someone from bluez developers comment this Tanu's point?
> 
> I would have to say no, we are definitely not interested in yet
> another daemon for AT parsing, we actually have too many of these
> around, either in a form of Modem Manager, oFono, etc.

Proposed hsphfpd daemon is not (only) for parsing AT commands, but for
implementing logic around HSP and HFP profiles and export either native
interfaces (linux uinput) or DBus interfaces for features provided by
HSP and HFP specifications and also for current and future vendor
extensions. And part of this HSP/HFP implementation is of course needed
parsing and interpreting some of AT commands. Look into my design and
API proposal. Current daemons which provides AT parsing (like ofono or
modem manager) are not suitable for for whole HSP and HFP profiles with
all those extensions (like all possible ways for reporting battery
level), so for HFP is needed some of custom AT parser.

> That said one
> simpler way to resolve all of this is to maintain a plugin to
> bluetoothd that way HSP/HFP becomes native again, that can either be
> maintained in the tree or out of the tree.

I do not see how could just plain plugin for bluez without AT parser
could help. This seems to just complicate whole implementation. I
already implemented prototype implementation of hsphfpd to see how
complicated it is and what is needed...

So if bluez daemon is not the right place for hsphpfd, it would be
separate daemon outside of bluez.

-- 
Pali Rohár
pali.ro...@gmail.com
___
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-12 Thread Pali Rohár
On Thursday 12 December 2019 22:27:39 Andrey Semashev wrote:
> On 2019-10-06 20: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
> > ---
> >   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
> 
> [snip]
> 
> > +
> > +static 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) {
> > +struct aptx_context *aptx_c = (struct aptx_context *) codec_info;
> > +size_t written;
> > +
> > +*processed = aptx_encode(aptx_c, input_buffer, input_size, 
> > output_buffer, output_size, );
> > +if (PA_UNLIKELY(*processed == 0 || *processed != input_size))
> > +pa_log_error("aptX encoding error");
> > +
> > +return written;
> > +}
> > +
> > +static size_t encode_buffer_hd(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 aptx_hd_info *aptx_hd_info = (struct aptx_hd_info *) codec_info;
> > +struct rtp_header *header;
> > +size_t written;
> > +
> > +if (PA_UNLIKELY(output_size < sizeof(*header))) {
> > +*processed = 0;
> > +return 0;
> > +}
> > +
> > +written = encode_buffer(aptx_hd_info->aptx_c, timestamp, input_buffer, 
> > input_size, output_buffer + sizeof(*header), output_size - sizeof(*header), 
> > processed);
> > +
> > +if (PA_LIKELY(written > 0)) {
> > +header = (struct rtp_header *) output_buffer;
> 
> I'm not sure I understand it correctly, but encode_buffer seems to be
> producing encoded content at the beginning of the output buffer, and
> encode_buffer_hd produces an RTP header followed by encoded content. Is this
> difference intentional? What is expected to be placed in the output buffer -
> a complete RTP packet or RTP payload only?
> 
> The same comment applies to decode_buffer and decode_buffer_hd below.

aptX does not use RTP. So A2DP buffer for aptX contains raw aptX
samples.

On the other hand aptX-HD uses RTP protocol, so aptX-HD samples are put
into RTP packets and then RTP packets are passed to A2DP buffer.

Hope this answer your question.

-- 
Pali Rohár
pali.ro...@gmail.com


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


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

2019-12-11 Thread Pali Rohár
Hello! Some of these patches are already reviewed. Can you include these
patches into pulseaudio master git branch?

-- 
Pali Rohár
pali.ro...@gmail.com
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-09 Thread Pali Rohár
. If other
projects want to use it (e.g. pulseaudio, bluez-alsa, pipewire, jack) we
can start a separate discussion about API of such library. I guess that
more audio daemons would be different requirements and to be usable in
all projects we need to cover all of them.

> * HFP/HSP commands handling

This is already covered by hsphpfd.

> * telephony handling

In hsphfpd this is exported to external telephony agent. Possibly ofono
or modem manager (whatever project will implement needed API and
connects to hsphfpd daemon).

> * exposure of common D-Bus APIs for side-channel things like power
> management or phone dialing

This is part of hsphfpd daemon, please look at hsphfpd.txt if it covers
your needs. Btw, phone dialing is part of telephony handling.

> ... and then every downstream user (pulse, pipewire, bluez-alsa, ...)
> could reuse these components and implement the rest of the routing /
> management logic in their own daemon.
> 
> My two cents...
> 
> Regards,
> George

-- 
Pali Rohár
pali.ro...@gmail.com
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] SBC XQ for PA 13.0

2019-12-09 Thread Pali Rohár
On Monday 09 December 2019 14:47:26 Andrey Semashev wrote:
> As a user, I don't know whether I can use SBC XQ. I don't know whether its
> bitrate will fit in my radio conditions. If my device happens to support SBC
> XQ, that is the codec that will get picked upon connection. Please, correct
> me if I'm wrong, but I don't see a way to influence that.

You can ask same question for aptX-HD codec. It has also fixed high
bitrate.

> SBC XQ is high quality and high bitrate, true, but PA should adapt to the
> actual use conditions.

SBC XQ is defined with usage of one specific bitpool value.

> More so if it actually has the means to do so. If PA
> detects that SBC XQ does not fit in BT bandwidth, it should gradually drop
> quality.

Maybe we can implement disconnecting SBC XQ profile when problem happen
and connect again with SBC in Automatic quality.

But there is another problem. People who chose high quality codec do not
want to see that application itself without their instruction decide to
change codec to low quality. This is reason why non-SBC codecs are used.
Because they provide one fixed quality which is same whatever bluetooth
adapter or headphone you will use. SBC is criticized for a long time
because current implementations automatically choose some quality which
is not under user control. So for these reasons there is SBC LQ, MQ, HQ
and XQ. You can choose what you want to use. By default is automatic
mode which decreasing quality.

-- 
Pali Rohár
pali.ro...@gmail.com
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] SBC XQ for PA 13.0

2019-12-09 Thread Pali Rohár
On Monday 09 December 2019 14:32:52 Andrey Semashev wrote:
> I have another piece of feedback to provide. Sometimes I experience audio
> dropouts. Sometimes in both left and right headphones, sometimes just one.
> In particular, I noticed this happen when I have a Bluetooth-connected
> DualShock 4 gamepad connected and playing games, but it also happens without
> it, although less often.
> 
> I assume this is caused by Bluetooth bandwidth limitation. Note that EOZ Air
> are "truly wireless" (i.e. the two headphones connect wirelessly), and I
> have multiple WiFi networks available (one access point in the same room as
> the Bluetooth transmitter, a few others behind walls). I expect 2.4 GHz
> radio to be rather crowded. The gamepad and the headphones are in the same
> room as the Bluetooth transmitter, in clear direct visibility, so it can't
> get better than that.

Yes, 2.4 GHz is shared by both Bluetooth and WiFi, so it may be a
problem.

> I can see Pali's patches offer reduce_encoder_bitrate API that is supposed
> to mitigate this problem, but both SBC XQ profiles don't allow bitrate
> reduction.

Yes, SBC XQ is there the highest available quality profile of SBC.

> I think, SBC XQ desperately needs to support bitrate reduction,

No, this is main reason for usage of SBC XQ it is high quality codec.
SBC XQ needs high bitrate by its definition.

> as the codec with the highest bitrate out of all. Users might actually have
> reduced experience due to audio dropouts compared to the previously
> supported SBC HQ.

If you cannot use high bitrate codecs, then do not use high bitrate
codecs. There are other profiles of SBC which lower bitpool value and
therefore lower bitrate. E.g. SBC MQ or SBC LQ (medium and low quality).

Or you can use SBC in automatic mode where bitrate is automatically
decreased.

-- 
Pali Rohár
pali.ro...@gmail.com
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] SBC XQ for PA 13.0

2019-12-08 Thread Pali Rohár
On Sunday 08 December 2019 20:40:09 Andrey Semashev wrote:
> On 2019-12-07 22:31, Pali Rohár wrote:
> > On Saturday 07 December 2019 22:13:28 Andrey Semashev wrote:
> > > On 2019-12-07 21:30, Pali Rohár wrote:
> > > > 
> > > > FDK-AAC library is incompatible with any version of the GNU GPL license
> > > > and therefore it is not possible to use it in any GPL licensed software,
> > > > like pulseaudio. See: https://www.gnu.org/licenses/license-list.html#fdk
> > > 
> > > Well, incompatibility means the resulting binary is not redistributable.
> > > Users could still build PA with libfdk-aac locally.
> > 
> > Yes, you are right.
> > 
> > > Or the library could be
> > > loaded dynamically, if present on the user's system, without having to 
> > > link
> > > with it at build time.
> > 
> > Some people says that this is not legal too. Loading library either at
> > build (link) time is same as at runtime... And FSF has similar
> > explanation. Main problem is that license of external library does not
> > allow you to use it in your application. And it does not depend on how
> > you build your application or how you use that library (dlopen or
> > stating or dynamic linking). You are still usage same library API. But
> > I'm not lawyer...
> > 
> > Important it that if there are people who doubt about regular usage then
> > such functionality would not be included into distribution. And above
> > dynamic loading via dlopen is a reason for doubt that something is not
> > there fully legal and can be problematic.
> > 
> > > > If there is other AAC library which license allows usage it in
> > > > pulseaudio then it could be possible. Just somebody needs to write it.
> > > 
> > > The built-in implementation in ffmpeg is under LGPL 2.1, which should be
> > > compatible.
> > 
> > Yes, LGPL 2.1 is fine.
> 
> One other question regarding libfdk-aac. Would it be ok to try using it
> through ffmpeg if it is built with it? If ffmpeg is compiled without
> libfdk-aac then we would fall back to the built-in encoder.
> 
> This would allow people who build ffmpeg themselves to use libfdk-aac. On
> the PA side, this would require very little change code-wise (it would not
> introduce build dependency on libfdk-aac), most of the integration with
> ffmpeg remains the same.

Supported A2DP codecs needs to be know at pulseaudio compile time.
So unsupported codecs are excluded from build. This is also needed to
ensure that compile time flags make sense and prevent problems that user
compiled pulseaudio with codec X, but X does not work because is not
installed available in system. So in pulseaudio's ELF binary are
correctly filled all libraries and its codecs via NEEDED flag (which is
used for generating dependences for probably all package managers).

-- 
Pali Rohár
pali.ro...@gmail.com


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

Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-07 Thread Pali Rohár
+Denis from ofono

ofono and pulseaudio are two main users of HFP profile on Linux...

On Sunday 01 December 2019 19:57:40 Pali Rohár wrote:
> Hello!
> 
> I'm sending this email to relevant mailing lists and other people who
> could be interested in it. (I'm not subscribed to all of ML, so please
> CC me when replying).
> 
> 
> I would like to open a discussion about a completely new way of handling
> Bluetooth HSP and HFP profiles on Linux. These two profiles are the only
> standard way how to access microphone data from Bluetooth Headsets.
> 
> 
> Previously in bluez4, HFP profile was implemented by bluez daemon and
> telephony HFP functionality was provided by either dummy modem, ofono
> modem or by Nokia's CSD Maemo modem.
> 
> In bluez5 version was modem code together with implementation of HFP
> profile removed. And let implementation of HSP and HFP profiles to
> external application.
> 
> Currently HSP profile is implemented in pulseaudio daemon to handle
> microphone and Bluetooth speakers. HFP profile is not implemented yet.
> 
> 
> HSP and HFP profiles use AT modem commands, so its implementation needs
> to parse and generates AT commands, plus implement needed state machine
> for it.
> 
> And now problem is that last version of HFP profile specification is too
> complicated, plus Bluetooth headsets vendors started to inventing and
> using of own custom extensions to HFP profile and AT commands.
> 
> Main problem of this "external" implementation outside of bluez is that
> only one application can communicate with remote Bluetooth device. It
> is application which received needed socket from bluez.
> 
> So in this design if audio daemon (pulseaudio) implements HFP profile
> for processing audio, and e.g. power supply application wants to
> retrieve battery level from Bluetooth device, it means that audio daemon
> needs to implement also battery related functionality.
> 
> It does not make sense to force power supply daemon (upower) to
> implement audio routing/encoding/decoding or audio daemon (power supply)
> to force implementing battery related operations.
> 
> 
> For handle this problem I would like to propose a new way how to use and
> implement HSP and HFP profiles on Linux.
> 
> Implement a new HSP/HFP daemon (I called it hsphfpd) which register HSP
> and HFP profiles in bluez and then exports functionality for all other
> specific applications via DBus API (API for audio, power supply, input
> layer, telephony functions, vendor extensions, etc...). So it would acts
> as proxy daemon between bluez and target applications (pulseaudio,
> upower, ofono, ...)
> 
> This would simplify whole HFP usage as applications would not need to
> re-implement parsing and processing of AT commands and it would allow
> more applications to use HFP profile at one time. And also it means that
> audio software does not have to implement telephony stack or power
> supply operations.
> 
> 
> I wrote a document how such DBus API could look like, see here:
> 
>   https://github.com/pali/hsphfpd-prototype/raw/prototype/hsphfpd.txt
> 
> 
> And also I implemented "prototype" implementation to verify that
> designed API make sense and can be really implemented. Prototype fully
> supports HSP profile in both HS and AG role, plus HFP profile in HF
> role. This prototype implementation is available here:
> 
>   https://github.com/pali/hsphfpd-prototype
> 
> Some other details are written in README:
> 
>   https://github.com/pali/hsphfpd-prototype/raw/prototype/README
> 
> 
> What do you think about it? Does it make sense to have such design?
> Would you accept usage of such hsphfpd daemon, implemented according to
> specification, on Linux desktop?
> 
> I would like to hear your opinion if I should continue with this hsphfpd
> design, or not.
> 
> 
> With this design and implementation of hsphfpd is possible to easily fix
> pulseaudio issue about power supply properties:
> 
>   https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/722
> 
> 

-- 
Pali Rohár
pali.ro...@gmail.com


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

Re: [pulseaudio-discuss] SBC XQ for PA 13.0

2019-12-07 Thread Pali Rohár
On Saturday 07 December 2019 22:13:28 Andrey Semashev wrote:
> On 2019-12-07 21:30, Pali Rohár wrote:
> > On Saturday 07 December 2019 21:09:04 Andrey Semashev wrote:
> > > However, I can still hear compression artefacts on quiet or nearly silent
> > > audio sections, which sound like high-pitch squeaking sounds. It can often
> > > be heard on various music fade out sections. I don't know if this is
> > > inherrent from SBC codec itself or is a deficiency of libsbc 
> > > implementation,
> > > or the headphones. These artefacts are my main complaint about SBC.
> > 
> > See very nice description about this problem 
> > https://habr.com/en/post/456182/
> > Probably your headphones cripple audio by filters when SBC is used...
> 
> Yes, I've read that. That is the reason why I suspect the headphones might
> be the culprit, but I cannot be sure.
> 
> > > Which brings me to my question to PA developers. Would an addition of
> > > support for AAC be possible?
> > 
> > My A2DP patch series brings new pulseaudio API for implementing new A2DP
> > codecs. So yes, additional support for other A2DP codecs with my patch
> > series is possible. My patch series contains support for aptX, aptX-HD
> > and FastStream A2DP codecs.
> 
> Are your patches available in a PR or a git fork somewhere? If I'm going to
> give it a try to add support for AAC, how can I get the up to date PA
> version to develop against?

Patches are available on mailing list, aggregated in patchwork:
https://patchwork.freedesktop.org/series/55117/

Last version is also available in my private git fork (branch a2dp-codecs):
https://gitlab.freedesktop.org/pali/pulseaudio

You can use it as a base for adding a new A2DP codec. Look at how aptX
or FastStream is implemented (they are in separate commits).

> > But... you need a library for encoding and decoding that codec ...
> > 
> > > pulseaudio-modules-bt uses libfdk-aac to implement AAC, and if possible, I
> > > would prefer that library as it provides the best quality available on
> > > Linux. However, if licensing is an issue, there is also a built-in
> > > implementation in ffmpeg.
> > 
> > FDK-AAC library is incompatible with any version of the GNU GPL license
> > and therefore it is not possible to use it in any GPL licensed software,
> > like pulseaudio. See: https://www.gnu.org/licenses/license-list.html#fdk
> 
> Well, incompatibility means the resulting binary is not redistributable.
> Users could still build PA with libfdk-aac locally.

Yes, you are right.

> Or the library could be
> loaded dynamically, if present on the user's system, without having to link
> with it at build time.

Some people says that this is not legal too. Loading library either at
build (link) time is same as at runtime... And FSF has similar
explanation. Main problem is that license of external library does not
allow you to use it in your application. And it does not depend on how
you build your application or how you use that library (dlopen or
stating or dynamic linking). You are still usage same library API. But
I'm not lawyer...

Important it that if there are people who doubt about regular usage then
such functionality would not be included into distribution. And above
dynamic loading via dlopen is a reason for doubt that something is not
there fully legal and can be problematic.

> > If there is other AAC library which license allows usage it in
> > pulseaudio then it could be possible. Just somebody needs to write it.
> 
> The built-in implementation in ffmpeg is under LGPL 2.1, which should be
> compatible.

Yes, LGPL 2.1 is fine.

-- 
Pali Rohár
pali.ro...@gmail.com


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

Re: [pulseaudio-discuss] SBC XQ for PA 13.0

2019-12-07 Thread Pali Rohár
On Saturday 07 December 2019 21:09:04 Andrey Semashev wrote:
> However, I can still hear compression artefacts on quiet or nearly silent
> audio sections, which sound like high-pitch squeaking sounds. It can often
> be heard on various music fade out sections. I don't know if this is
> inherrent from SBC codec itself or is a deficiency of libsbc implementation,
> or the headphones. These artefacts are my main complaint about SBC.

See very nice description about this problem https://habr.com/en/post/456182/
Probably your headphones cripple audio by filters when SBC is used...

> Which brings me to my question to PA developers. Would an addition of
> support for AAC be possible?

My A2DP patch series brings new pulseaudio API for implementing new A2DP
codecs. So yes, additional support for other A2DP codecs with my patch
series is possible. My patch series contains support for aptX, aptX-HD
and FastStream A2DP codecs.

But... you need a library for encoding and decoding that codec ...

> pulseaudio-modules-bt uses libfdk-aac to implement AAC, and if possible, I
> would prefer that library as it provides the best quality available on
> Linux. However, if licensing is an issue, there is also a built-in
> implementation in ffmpeg.

FDK-AAC library is incompatible with any version of the GNU GPL license
and therefore it is not possible to use it in any GPL licensed software,
like pulseaudio. See: https://www.gnu.org/licenses/license-list.html#fdk

If there is other AAC library which license allows usage it in
pulseaudio then it could be possible. Just somebody needs to write it.

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: PGP signature
___
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 Pali Rohár
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.

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: PGP signature
___
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 Pali Rohár
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 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))
> > > > > > +  

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

2019-12-07 Thread Pali Rohár
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/msg30

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

2019-12-07 Thread Pali Rohár
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>

> > +
> > +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(&quo

Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-05 Thread Pali Rohár
On Wednesday 04 December 2019 20:45:23 Arun Raghavan wrote:
> Broadly, I think this is a good thing to do. My main concern is having this 
> be adequately maintained over a longer period of time.

I already prepared prototype implementation, so I know how hard is to
write or maintain this new daemon.

Are there any interested people in either implementing, maintaining or
in other way helping with this project?

The main problem in maintaining this HSP/HFP codebase I see that I do
not have enough testing devices. As we know lot of manufactures produce
devices which are not compliant to standards and this needs to be
handled in HSP/HFP codebase.

> The other thing to note is that in PipeWire, it is possible for external 
> entities to implement the equivalent of a "sink" or "source" (it's just a 
> node in PipeWire terminology), so in the long run, it might be good to have a 
> single BT audio daemon that manages A2DP and HSP/HFP..

PipeWire or any other audio server (jack or bluez-alsa) can benefit from
this hsphfpd daemon that it does not have to implement (again) parsing
and interpreting AT commands (as needed for HFP standard).

For PipeWire developers: Do you have any special requirements for this
hsphfpd daemon which are needed for processing of audio?

See proposed DBus interface, specially "Audio Agent hierarchy":
https://github.com/pali/hsphfpd-prototype/raw/prototype/hsphfpd.txt

> This would also have the benefit of moving codec dependencies out of 
> PulseAudio (which I'll help mitigate in other ways within PulseAudio anyway).

hsphfpd just prepares SCO audio socket and then via DBus pass it to
target application (pulseaudio, pipewire, jacks, ...). And it is up to
the audio application to do codec processing. hsphfpd is not going to do
anything with audio samples or codecs. So this does not help directly...

... But I'm planing to try to separate A2DP code from pulseaudio into
some external library which would not depend on pulseaudio. So this
library can help all audio server projects to not re-implement again and
again A2DP (and HSP/HFP) audio processing. This library should do all
needed codec stuff (encoding, decoding, setup of A2DP, ...).

-- 
Pali Rohár
pali.ro...@gmail.com


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

Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-05 Thread Pali Rohár
On Monday 02 December 2019 19:45:12 Pali Rohár wrote:
> On Monday 02 December 2019 19:01:11 Tanu Kaskinen wrote:
> > I think hsphfpd should be part of bluetoothd, but if that's not
> > possible, then that's not possible.
> 
> I do not know if bluez developers are interested in having this code as
> part of bluez project, specially when in bluez4 HFP profile was there
> and in bluez5 was HFP code completely removed.

Hello, could someone from bluez developers comment this Tanu's point?

-- 
Pali Rohár
pali.ro...@gmail.com
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-02 Thread Pali Rohár
On Monday 02 December 2019 19:01:11 Tanu Kaskinen wrote:
> On Sun, 2019-12-01 at 19:57 +0100, Pali Rohár wrote:
> > Hello!
> > 
> > I'm sending this email to relevant mailing lists and other people who
> > could be interested in it. (I'm not subscribed to all of ML, so please
> > CC me when replying).
> > 
> > 
> > I would like to open a discussion about a completely new way of handling
> > Bluetooth HSP and HFP profiles on Linux. These two profiles are the only
> > standard way how to access microphone data from Bluetooth Headsets.
> > 
> > 
> > Previously in bluez4, HFP profile was implemented by bluez daemon and
> > telephony HFP functionality was provided by either dummy modem, ofono
> > modem or by Nokia's CSD Maemo modem.
> > 
> > In bluez5 version was modem code together with implementation of HFP
> > profile removed. And let implementation of HSP and HFP profiles to
> > external application.
> > 
> > Currently HSP profile is implemented in pulseaudio daemon to handle
> > microphone and Bluetooth speakers. HFP profile is not implemented yet.
> > 
> > 
> > HSP and HFP profiles use AT modem commands, so its implementation needs
> > to parse and generates AT commands, plus implement needed state machine
> > for it.
> > 
> > And now problem is that last version of HFP profile specification is too
> > complicated, plus Bluetooth headsets vendors started to inventing and
> > using of own custom extensions to HFP profile and AT commands.
> > 
> > Main problem of this "external" implementation outside of bluez is that
> > only one application can communicate with remote Bluetooth device. It
> > is application which received needed socket from bluez.
> > 
> > So in this design if audio daemon (pulseaudio) implements HFP profile
> > for processing audio, and e.g. power supply application wants to
> > retrieve battery level from Bluetooth device, it means that audio daemon
> > needs to implement also battery related functionality.
> > 
> > It does not make sense to force power supply daemon (upower) to
> > implement audio routing/encoding/decoding or audio daemon (power supply)
> > to force implementing battery related operations.
> > 
> > 
> > For handle this problem I would like to propose a new way how to use and
> > implement HSP and HFP profiles on Linux.
> > 
> > Implement a new HSP/HFP daemon (I called it hsphfpd) which register HSP
> > and HFP profiles in bluez and then exports functionality for all other
> > specific applications via DBus API (API for audio, power supply, input
> > layer, telephony functions, vendor extensions, etc...). So it would acts
> > as proxy daemon between bluez and target applications (pulseaudio,
> > upower, ofono, ...)
> > 
> > This would simplify whole HFP usage as applications would not need to
> > re-implement parsing and processing of AT commands and it would allow
> > more applications to use HFP profile at one time. And also it means that
> > audio software does not have to implement telephony stack or power
> > supply operations.
> > 
> > 
> > I wrote a document how such DBus API could look like, see here:
> > 
> >   https://github.com/pali/hsphfpd-prototype/raw/prototype/hsphfpd.txt
> > 
> > 
> > And also I implemented "prototype" implementation to verify that
> > designed API make sense and can be really implemented. Prototype fully
> > supports HSP profile in both HS and AG role, plus HFP profile in HF
> > role. This prototype implementation is available here:
> > 
> >   https://github.com/pali/hsphfpd-prototype
> > 
> > Some other details are written in README:
> > 
> >   https://github.com/pali/hsphfpd-prototype/raw/prototype/README
> > 
> > 
> > What do you think about it? Does it make sense to have such design?
> > Would you accept usage of such hsphfpd daemon, implemented according to
> > specification, on Linux desktop?
> > 
> > I would like to hear your opinion if I should continue with this hsphfpd
> > design, or not.
> > 
> > 
> > With this design and implementation of hsphfpd is possible to easily fix
> > pulseaudio issue about power supply properties:
> > 
> >   https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/722
> 
> I quite like this proposal. Avoiding the need to implement the button
> press, battery level etc. handling separately in PulseAudio, oFono and
> PipeWire seems like a pretty good justification to me. I assume you're
> volunteering to maintain this

Re: [pulseaudio-discuss] [PATCH v13 05/10] bluetooth: Add A2DP aptX and aptX HD codecs support

2019-12-02 Thread Pali Rohár
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...

> 
> > 
> > > > 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 = 
> >

[pulseaudio-discuss] Proposal for a new API and usage of Bluetooth HSP and HFP profiles on Linux

2019-12-01 Thread Pali Rohár
Hello!

I'm sending this email to relevant mailing lists and other people who
could be interested in it. (I'm not subscribed to all of ML, so please
CC me when replying).


I would like to open a discussion about a completely new way of handling
Bluetooth HSP and HFP profiles on Linux. These two profiles are the only
standard way how to access microphone data from Bluetooth Headsets.


Previously in bluez4, HFP profile was implemented by bluez daemon and
telephony HFP functionality was provided by either dummy modem, ofono
modem or by Nokia's CSD Maemo modem.

In bluez5 version was modem code together with implementation of HFP
profile removed. And let implementation of HSP and HFP profiles to
external application.

Currently HSP profile is implemented in pulseaudio daemon to handle
microphone and Bluetooth speakers. HFP profile is not implemented yet.


HSP and HFP profiles use AT modem commands, so its implementation needs
to parse and generates AT commands, plus implement needed state machine
for it.

And now problem is that last version of HFP profile specification is too
complicated, plus Bluetooth headsets vendors started to inventing and
using of own custom extensions to HFP profile and AT commands.

Main problem of this "external" implementation outside of bluez is that
only one application can communicate with remote Bluetooth device. It
is application which received needed socket from bluez.

So in this design if audio daemon (pulseaudio) implements HFP profile
for processing audio, and e.g. power supply application wants to
retrieve battery level from Bluetooth device, it means that audio daemon
needs to implement also battery related functionality.

It does not make sense to force power supply daemon (upower) to
implement audio routing/encoding/decoding or audio daemon (power supply)
to force implementing battery related operations.


For handle this problem I would like to propose a new way how to use and
implement HSP and HFP profiles on Linux.

Implement a new HSP/HFP daemon (I called it hsphfpd) which register HSP
and HFP profiles in bluez and then exports functionality for all other
specific applications via DBus API (API for audio, power supply, input
layer, telephony functions, vendor extensions, etc...). So it would acts
as proxy daemon between bluez and target applications (pulseaudio,
upower, ofono, ...)

This would simplify whole HFP usage as applications would not need to
re-implement parsing and processing of AT commands and it would allow
more applications to use HFP profile at one time. And also it means that
audio software does not have to implement telephony stack or power
supply operations.


I wrote a document how such DBus API could look like, see here:

  https://github.com/pali/hsphfpd-prototype/raw/prototype/hsphfpd.txt


And also I implemented "prototype" implementation to verify that
designed API make sense and can be really implemented. Prototype fully
supports HSP profile in both HS and AG role, plus HFP profile in HF
role. This prototype implementation is available here:

  https://github.com/pali/hsphfpd-prototype

Some other details are written in README:

  https://github.com/pali/hsphfpd-prototype/raw/prototype/README


What do you think about it? Does it make sense to have such design?
Would you accept usage of such hsphfpd daemon, implemented according to
specification, on Linux desktop?

I would like to hear your opinion if I should continue with this hsphfpd
design, or not.


With this design and implementation of hsphfpd is possible to easily fix
pulseaudio issue about power supply properties:

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


-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: PGP signature
___
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-11-30 Thread Pali Rohár
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).

> > 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?

> 
> > 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
...
> > +
> > +static bool fill_preferred_configuration_common(const pa_sample_spec 
> > *default_sample_spec, const a2dp_aptx_t *capabilities, a2dp_aptx_t *config, 
> > uint32_t vendor_id, uint16_t codec_id) {
> 
> The return type should be int not bool. Functions that return an error
> always return int
> in PA (negative value for error, >=0 for success).

Ok, I can change it.

> 
> > +int i;
> > +
> > +static const struct {
> > +uint32_t rate;
> > +uint8_t cap;
> > +} freq_table[] = {
> > +{ 16000U, APTX_SAMPLING_FREQ_16000 },
> > +{ 32000U, APTX_SAMPLING_FREQ_32000 },
> > +{ 44100U, APTX_SAMPLING_FREQ_44100 },
> > +{ 48000U, APTX_SAMPLING_FREQ_48000 }
> > +};
> > +
> > +if (A2DP_GET_VENDOR_ID(capabilities->info) != vendor_id || 
> > A2DP_GET_CODEC_ID(capabilities->info) != codec_id) {
> > +pa_log_error("No supported vendor codec information");
> > +return false;
> > +}
> > +
> > +config->info = A2DP_SET_VENDOR_ID_CODEC_ID(vendor_id, codec_id);
> > +
> > +if (!(capabilities->channel_mode & APTX_CHANNEL_MODE_STEREO)) {
> > +pa_log_error("No supported channel modes");
> > +return false;
> > +}
> > +
> > +config->channel_mode = APTX_CHANNEL_MO

Re: [pulseaudio-discuss] [PATCH v13 01/10] bluetooth: Implement reading SO_TIMESTAMP for A2DP source

2019-11-10 Thread Pali Rohár
On Sunday 10 November 2019 11:03:25 Georg Chini wrote:
> 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, >stream_write_type);
> > > > +pa_zero(m);
> > > > +pa_zero(aux);
> > > > +pa_zero(iov);
> > > > +
> > > > +m.msg_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, , 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(); cm; cm = CMSG_NXTHDR(, 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.

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...

> > 
> > > It should run fine even when system time is used.
> > Maybe kernel can for some reason do not add it? I do not know.
> > 

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: PGP signature
___
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-10 Thread Pali Rohár
On Saturday 09 November 2019 13:08:34 Georg Chini wrote:
> 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(); cm; cm = CMSG_NXTHDR(, 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, );
> > +timestamp = 0; /* Decoder does not have to fill RTP timestamp */
> > +memchunk.length = u->a2dp_codec->decode_buffer(u->decoder_info, 
> > , u->decoder_buffer, l, ptr, memchunk.length, );
> >   pa_memblock_release(memchunk.me

Re: [pulseaudio-discuss] [PATCH v13 01/10] bluetooth: Implement reading SO_TIMESTAMP for A2DP source

2019-11-10 Thread Pali Rohár
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, >stream_write_type);
> > +pa_zero(m);
> > +pa_zero(aux);
> > +pa_zero(iov);
> > +
> > +m.msg_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, , 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.

> 
> > +
> > +for (cm = CMSG_FIRSTHDR(); cm; cm = CMSG_NXTHDR(, 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.

> It should run fine even when system time is used.

Maybe kernel can for some reason do not add it? I do not know.

-- 
Pali Rohár
pali.ro...@gmail.com


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

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-29 Thread Pali Rohár
On Tuesday 29 October 2019 11:24:06 Hyperion wrote:
> 
> 
> 29.10.2019, 10:24, "Pali Rohár" :
> > On Monday 28 October 2019 17:12:45 Hyperion wrote:
> >>  28.10.2019, 16:11, "Tanu Kaskinen" :
> >>  > On Sat, 2019-10-26 at 20:23 +0200, Hyperion wrote:
> >>  >>  26.10.2019, 14:39, "Tanu Kaskinen" :
> >>  >>  > On Sat, 2019-10-19 at 18:42 +0200, Pali Rohár wrote:
> >>  >>  > > On Saturday 19 October 2019 19:27:19 Tanu Kaskinen wrote:
> >>  >>  > > > On Sat, 2019-10-19 at 18:16 +0200, Pali Rohár wrote:
> >>  >>  > > > > On Saturday 19 October 2019 19:07:44 Tanu Kaskinen wrote:
> >>  >>  > > > > > On Sat, 2019-10-19 at 17:20 +0200, Pali Rohár wrote:
> >>  >>  > > > > > > On Friday 18 October 2019 15:29:43 Tanu Kaskinen wrote:
> >>  >>  > > > > > > > On Thu, 2019-10-17 at 15:34 +0200, Hyperion wrote:
> >>  >>  > > > > > > > > Regression would mean that some devices can't connect 
> >> anymore : this
> >>  >>  > > > > > > > > won't happen if a workaround is provided, and this 
> >> workaround won't
> >>  >>  > > > > > > > > be used often.
> >>  >>  > > > > > > > >
> >>  >>  > > > > > > > > Most (99% ?) of the devices will work correctly with 
> >> my patch (many
> >>  >>  > > > > > > > > of them in XQ mode, and some in legacy mode because 
> >> they will fall
> >>  >>  > > > > > > > > back to legacy bitpool during negociation)
> >>  >>  > > > > > > > >
> >>  >>  > > > > > > > > The remaining (1% ?) : will need a simple boolean 
> >> swicth in one of
> >>  >>  > > > > > > > > the PA config files to restrict negociation to legacy 
> >> bitpool (a
> >>  >>  > > > > > > > > module option ? or daemon.conf ?).
> >>  >>  > > > > > > > >
> >>  >>  > > > > > > > > I think it's really "simple", efficient, and not 
> >> dependent of any
> >>  >>  > > > > > > > > upcoming Bluez feature.
> >>  >>  > > > > > > > >
> >>  >>  > > > > > > > > "The complex solution is always the best until one 
> >> find a simpler one"
> >>  >>  > > > > > > >
> >>  >>  > > > > > > > I don't know the number of users who use bluetooth 
> >> headsets with
> >>  >>  > > > > > > > PulseAudio, but even just 1% regression rate can mean 
> >> quite a few
> >>  >>  > > > > > > > unhappy users. When your headset suddenly stops 
> >> working, it's not
> >>  >>  > > > > > > > trivial to figure out that you may need to pass a 
> >> special argument to
> >>  >>  > > > > > > > module-bluetooth-discover in order to make it work 
> >> again.
> >>  >>  > > > > > > >
> >>  >>  > > > > > > > It would be better to have a module argument to enable 
> >> the XQ settings.
> >>  >>  > > > > > >
> >>  >>  > > > > > > Main question, do we really need this special "settings"? 
> >> Because my
> >>  >>  > > > > > > patch series introduce also SBC XQ profile and basically 
> >> replaces above
> >>  >>  > > > > > > module parameter, by runtime configuration.
> >>  >>  > > > > > >
> >>  >>  > > > > > > For me above solution looks like a hack. It adds some 
> >> module parameter
> >>  >>  > > > > > > for tweaking configuration. And what would happen with 
> >> that parameter
> >>  >>  > > > > > > after we have "proper" support for multiple codecs? Do we 
> >> need to
> >>  >>  > > > > > > maintain backward compatibility? Or would we remove that 
> >> configuration
> >>  >>  > > > &

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-29 Thread Pali Rohár
On Monday 28 October 2019 17:12:45 Hyperion wrote:
> 28.10.2019, 16:11, "Tanu Kaskinen" :
> > On Sat, 2019-10-26 at 20:23 +0200, Hyperion wrote:
> >>  26.10.2019, 14:39, "Tanu Kaskinen" :
> >>  > On Sat, 2019-10-19 at 18:42 +0200, Pali Rohár wrote:
> >>  > > On Saturday 19 October 2019 19:27:19 Tanu Kaskinen wrote:
> >>  > > > On Sat, 2019-10-19 at 18:16 +0200, Pali Rohár wrote:
> >>  > > > > On Saturday 19 October 2019 19:07:44 Tanu Kaskinen wrote:
> >>  > > > > > On Sat, 2019-10-19 at 17:20 +0200, Pali Rohár wrote:
> >>  > > > > > > On Friday 18 October 2019 15:29:43 Tanu Kaskinen wrote:
> >>  > > > > > > > On Thu, 2019-10-17 at 15:34 +0200, Hyperion wrote:
> >>  > > > > > > > > Regression would mean that some devices can't connect 
> >> anymore : this
> >>  > > > > > > > > won't happen if a workaround is provided, and this 
> >> workaround won't
> >>  > > > > > > > > be used often.
> >>  > > > > > > > >
> >>  > > > > > > > > Most (99% ?) of the devices will work correctly with my 
> >> patch (many
> >>  > > > > > > > > of them in XQ mode, and some in legacy mode because they 
> >> will fall
> >>  > > > > > > > > back to legacy bitpool during negociation)
> >>  > > > > > > > >
> >>  > > > > > > > > The remaining (1% ?) : will need a simple boolean swicth 
> >> in one of
> >>  > > > > > > > > the PA config files to restrict negociation to legacy 
> >> bitpool (a
> >>  > > > > > > > > module option ? or daemon.conf ?).
> >>  > > > > > > > >
> >>  > > > > > > > > I think it's really "simple", efficient, and not 
> >> dependent of any
> >>  > > > > > > > > upcoming Bluez feature.
> >>  > > > > > > > >
> >>  > > > > > > > > "The complex solution is always the best until one find a 
> >> simpler one"
> >>  > > > > > > >
> >>  > > > > > > > I don't know the number of users who use bluetooth headsets 
> >> with
> >>  > > > > > > > PulseAudio, but even just 1% regression rate can mean quite 
> >> a few
> >>  > > > > > > > unhappy users. When your headset suddenly stops working, 
> >> it's not
> >>  > > > > > > > trivial to figure out that you may need to pass a special 
> >> argument to
> >>  > > > > > > > module-bluetooth-discover in order to make it work again.
> >>  > > > > > > >
> >>  > > > > > > > It would be better to have a module argument to enable the 
> >> XQ settings.
> >>  > > > > > >
> >>  > > > > > > Main question, do we really need this special "settings"? 
> >> Because my
> >>  > > > > > > patch series introduce also SBC XQ profile and basically 
> >> replaces above
> >>  > > > > > > module parameter, by runtime configuration.
> >>  > > > > > >
> >>  > > > > > > For me above solution looks like a hack. It adds some module 
> >> parameter
> >>  > > > > > > for tweaking configuration. And what would happen with that 
> >> parameter
> >>  > > > > > > after we have "proper" support for multiple codecs? Do we 
> >> need to
> >>  > > > > > > maintain backward compatibility? Or would we remove that 
> >> configuration
> >>  > > > > > > and therefore revert to state prior existence of new module 
> >> parameter
> >>  > > > > > > (which is current situation)?
> >>  > > > > >
> >>  > > > > > After your patches there's still the "automatic bitpool" mode
> >>  > > > > > available, right?
> >>  > > > >
> >>  > > > > Yes, I wanted to have it there for legacy/backward compatibility 
> >> reasons
> >>  > > > > for tho

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-26 Thread Pali Rohár
On Saturday 26 October 2019 15:39:51 Tanu Kaskinen wrote:
> On Sat, 2019-10-19 at 18:42 +0200, Pali Rohár wrote:
> > On Saturday 19 October 2019 19:27:19 Tanu Kaskinen wrote:
> > > On Sat, 2019-10-19 at 18:16 +0200, Pali Rohár wrote:
> > > > On Saturday 19 October 2019 19:07:44 Tanu Kaskinen wrote:
> > > > > On Sat, 2019-10-19 at 17:20 +0200, Pali Rohár wrote:
> > > > > > On Friday 18 October 2019 15:29:43 Tanu Kaskinen wrote:
> > > > > > > On Thu, 2019-10-17 at 15:34 +0200, Hyperion wrote:
> > > > > > > > Regression would mean that some devices can't connect anymore : 
> > > > > > > > this
> > > > > > > > won't happen if a workaround is provided, and this workaround 
> > > > > > > > won't
> > > > > > > > be used often.
> > > > > > > > 
> > > > > > > > Most (99% ?) of the devices will work correctly with my patch 
> > > > > > > > (many
> > > > > > > > of them in XQ mode, and some in legacy mode because they will 
> > > > > > > > fall
> > > > > > > > back to legacy bitpool during negociation)
> > > > > > > > 
> > > > > > > > The remaining (1% ?) : will need a simple boolean swicth in one 
> > > > > > > > of
> > > > > > > > the PA config files to restrict negociation to legacy bitpool (a
> > > > > > > > module option ? or daemon.conf ?).
> > > > > > > > 
> > > > > > > > I think it's really "simple", efficient, and not dependent of 
> > > > > > > > any
> > > > > > > > upcoming Bluez feature.
> > > > > > > > 
> > > > > > > > "The complex solution is always the best until one find a 
> > > > > > > > simpler one"
> > > > > > > 
> > > > > > > I don't know the number of users who use bluetooth headsets with
> > > > > > > PulseAudio, but even just 1% regression rate can mean quite a few
> > > > > > > unhappy users. When your headset suddenly stops working, it's not
> > > > > > > trivial to figure out that you may need to pass a special 
> > > > > > > argument to
> > > > > > > module-bluetooth-discover in order to make it work again.
> > > > > > > 
> > > > > > > It would be better to have a module argument to enable the XQ 
> > > > > > > settings.
> > > > > > 
> > > > > > Main question, do we really need this special "settings"? Because my
> > > > > > patch series introduce also SBC XQ profile and basically replaces 
> > > > > > above
> > > > > > module parameter, by runtime configuration.
> > > > > > 
> > > > > > For me above solution looks like a hack. It adds some module 
> > > > > > parameter
> > > > > > for tweaking configuration. And what would happen with that 
> > > > > > parameter
> > > > > > after we have "proper" support for multiple codecs? Do we need to
> > > > > > maintain backward compatibility? Or would we remove that 
> > > > > > configuration
> > > > > > and therefore revert to state prior existence of new module 
> > > > > > parameter
> > > > > > (which is current situation)?
> > > > > 
> > > > > After your patches there's still the "automatic bitpool" mode
> > > > > available, right?
> > > > 
> > > > Yes, I wanted to have it there for legacy/backward compatibility reasons
> > > > for those devices which could be broken with new settings. That is the
> > > > reason I do not wanted to touch Automatic mode, to have exact same
> > > > behavior as in current (and older) pulseaudio versions.
> > > > 
> > > > But if automatic mode is going to be changed, I do not see reason for
> > > > keeping it (the argument for backward compatibility would not apply
> > > > anymore, if it is going to be changed). My patch series with new A2DP
> > > > API can fully replace that automatic mode.
> > > 
> > > I don't see how the proposed option changes anything about
> 

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-19 Thread Pali Rohár
On Saturday 19 October 2019 19:27:19 Tanu Kaskinen wrote:
> On Sat, 2019-10-19 at 18:16 +0200, Pali Rohár wrote:
> > On Saturday 19 October 2019 19:07:44 Tanu Kaskinen wrote:
> > > On Sat, 2019-10-19 at 17:20 +0200, Pali Rohár wrote:
> > > > On Friday 18 October 2019 15:29:43 Tanu Kaskinen wrote:
> > > > > On Thu, 2019-10-17 at 15:34 +0200, Hyperion wrote:
> > > > > > Regression would mean that some devices can't connect anymore : this
> > > > > > won't happen if a workaround is provided, and this workaround won't
> > > > > > be used often.
> > > > > > 
> > > > > > Most (99% ?) of the devices will work correctly with my patch (many
> > > > > > of them in XQ mode, and some in legacy mode because they will fall
> > > > > > back to legacy bitpool during negociation)
> > > > > > 
> > > > > > The remaining (1% ?) : will need a simple boolean swicth in one of
> > > > > > the PA config files to restrict negociation to legacy bitpool (a
> > > > > > module option ? or daemon.conf ?).
> > > > > > 
> > > > > > I think it's really "simple", efficient, and not dependent of any
> > > > > > upcoming Bluez feature.
> > > > > > 
> > > > > > "The complex solution is always the best until one find a simpler 
> > > > > > one"
> > > > > 
> > > > > I don't know the number of users who use bluetooth headsets with
> > > > > PulseAudio, but even just 1% regression rate can mean quite a few
> > > > > unhappy users. When your headset suddenly stops working, it's not
> > > > > trivial to figure out that you may need to pass a special argument to
> > > > > module-bluetooth-discover in order to make it work again.
> > > > > 
> > > > > It would be better to have a module argument to enable the XQ 
> > > > > settings.
> > > > 
> > > > Main question, do we really need this special "settings"? Because my
> > > > patch series introduce also SBC XQ profile and basically replaces above
> > > > module parameter, by runtime configuration.
> > > > 
> > > > For me above solution looks like a hack. It adds some module parameter
> > > > for tweaking configuration. And what would happen with that parameter
> > > > after we have "proper" support for multiple codecs? Do we need to
> > > > maintain backward compatibility? Or would we remove that configuration
> > > > and therefore revert to state prior existence of new module parameter
> > > > (which is current situation)?
> > > 
> > > After your patches there's still the "automatic bitpool" mode
> > > available, right?
> > 
> > Yes, I wanted to have it there for legacy/backward compatibility reasons
> > for those devices which could be broken with new settings. That is the
> > reason I do not wanted to touch Automatic mode, to have exact same
> > behavior as in current (and older) pulseaudio versions.
> > 
> > But if automatic mode is going to be changed, I do not see reason for
> > keeping it (the argument for backward compatibility would not apply
> > anymore, if it is going to be changed). My patch series with new A2DP
> > API can fully replace that automatic mode.
> 
> I don't see how the proposed option changes anything about
> compatibility. The option will be disabled by default, so the default
> behaviour will be the same as always.

And what should happen after support for multiple A2DP codecs (from my
patch series) would be there? Basically it obsoletes that config option.
As all such settings can be set at runtime.

> > Automatic mode is also main objection against usage of SBC codec (it
> > does not specify, say or enforce specific bitrate or quality; it can be
> > anything) and also reason why there are vendor codecs like aptX.
> > Defining SBC LQ, MQ, HQ or XQ just allows to compare it with other
> > codecs and guarantee same settings and quality across all devices.
> 
> Doesn't the automatic mode have the benefit that it automatically
> adapts to bad radio conditions so that users get the best quality
> possible without needing to fiddle with any options in case the initial
> bitrate is too high? So it's not entirely pointless.

Yes, but it make sense only for lower bitpool values. Higher bitpool
increase size of SBC frames and with larger SBC frames there would be
lot of wasted space in bluetooth packets as pulseaudio pulseaudio does
not support SBC fragmentation. There are only some higher bitpool values
which make sense to use.

Plus pulseaudio's implementation of (current) automatic mode only
decrease bitpool. It never increase it.

So yes, it is not pointless, but in current state not very useful for
higher bitpool values.

-- 
Pali Rohár
pali.ro...@gmail.com


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

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-19 Thread Pali Rohár
On Saturday 19 October 2019 19:07:44 Tanu Kaskinen wrote:
> On Sat, 2019-10-19 at 17:20 +0200, Pali Rohár wrote:
> > On Friday 18 October 2019 15:29:43 Tanu Kaskinen wrote:
> > > On Thu, 2019-10-17 at 15:34 +0200, Hyperion wrote:
> > > > Regression would mean that some devices can't connect anymore : this
> > > > won't happen if a workaround is provided, and this workaround won't
> > > > be used often.
> > > > 
> > > > Most (99% ?) of the devices will work correctly with my patch (many
> > > > of them in XQ mode, and some in legacy mode because they will fall
> > > > back to legacy bitpool during negociation)
> > > > 
> > > > The remaining (1% ?) : will need a simple boolean swicth in one of
> > > > the PA config files to restrict negociation to legacy bitpool (a
> > > > module option ? or daemon.conf ?).
> > > > 
> > > > I think it's really "simple", efficient, and not dependent of any
> > > > upcoming Bluez feature.
> > > > 
> > > > "The complex solution is always the best until one find a simpler one"
> > > 
> > > I don't know the number of users who use bluetooth headsets with
> > > PulseAudio, but even just 1% regression rate can mean quite a few
> > > unhappy users. When your headset suddenly stops working, it's not
> > > trivial to figure out that you may need to pass a special argument to
> > > module-bluetooth-discover in order to make it work again.
> > > 
> > > It would be better to have a module argument to enable the XQ settings.
> > 
> > Main question, do we really need this special "settings"? Because my
> > patch series introduce also SBC XQ profile and basically replaces above
> > module parameter, by runtime configuration.
> > 
> > For me above solution looks like a hack. It adds some module parameter
> > for tweaking configuration. And what would happen with that parameter
> > after we have "proper" support for multiple codecs? Do we need to
> > maintain backward compatibility? Or would we remove that configuration
> > and therefore revert to state prior existence of new module parameter
> > (which is current situation)?
> 
> After your patches there's still the "automatic bitpool" mode
> available, right?

Yes, I wanted to have it there for legacy/backward compatibility reasons
for those devices which could be broken with new settings. That is the
reason I do not wanted to touch Automatic mode, to have exact same
behavior as in current (and older) pulseaudio versions.

But if automatic mode is going to be changed, I do not see reason for
keeping it (the argument for backward compatibility would not apply
anymore, if it is going to be changed). My patch series with new A2DP
API can fully replace that automatic mode.

Automatic mode is also main objection against usage of SBC codec (it
does not specify, say or enforce specific bitrate or quality; it can be
anything) and also reason why there are vendor codecs like aptX.
Defining SBC LQ, MQ, HQ or XQ just allows to compare it with other
codecs and guarantee same settings and quality across all devices.

> To me it seems that the new option discussed here
> would still be useful, if there are users who prefer to use the
> automatic bitpool mode.

-- 
Pali Rohár
pali.ro...@gmail.com


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

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-19 Thread Pali Rohár
On Friday 18 October 2019 15:29:43 Tanu Kaskinen wrote:
> On Thu, 2019-10-17 at 15:34 +0200, Hyperion wrote:
> > Regression would mean that some devices can't connect anymore : this
> > won't happen if a workaround is provided, and this workaround won't
> > be used often.
> > 
> > Most (99% ?) of the devices will work correctly with my patch (many
> > of them in XQ mode, and some in legacy mode because they will fall
> > back to legacy bitpool during negociation)
> > 
> > The remaining (1% ?) : will need a simple boolean swicth in one of
> > the PA config files to restrict negociation to legacy bitpool (a
> > module option ? or daemon.conf ?).
> > 
> > I think it's really "simple", efficient, and not dependent of any
> > upcoming Bluez feature.
> > 
> > "The complex solution is always the best until one find a simpler one"
> 
> I don't know the number of users who use bluetooth headsets with
> PulseAudio, but even just 1% regression rate can mean quite a few
> unhappy users. When your headset suddenly stops working, it's not
> trivial to figure out that you may need to pass a special argument to
> module-bluetooth-discover in order to make it work again.
> 
> It would be better to have a module argument to enable the XQ settings.

Main question, do we really need this special "settings"? Because my
patch series introduce also SBC XQ profile and basically replaces above
module parameter, by runtime configuration.

For me above solution looks like a hack. It adds some module parameter
for tweaking configuration. And what would happen with that parameter
after we have "proper" support for multiple codecs? Do we need to
maintain backward compatibility? Or would we remove that configuration
and therefore revert to state prior existence of new module parameter
(which is current situation)?

-- 
Pali Rohár
pali.ro...@gmail.com


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

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-17 Thread Pali Rohár
On Thursday 17 October 2019 16:11:26 Tanu Kaskinen wrote:
> On Thu, 2019-10-17 at 14:55 +0200, Pali Rohár wrote:
> > On Thursday 17 October 2019 15:52:00 Tanu Kaskinen wrote:
> > > On Tue, 2019-10-08 at 18:29 +0200, Pali Rohár wrote:
> > > > Automatic SBC profile is not going to be changed. It is there to support
> > > > all devices without any tweaks. ValdikSS already did more tests and
> > > > there are devices which do not work with higher SBC bitpool. So
> > > > increasing max value of bitpool in Automatic SBC profile would lead to
> > > > broken support for these devices and therefore regressions.
> > > > 
> > > > As Automatic SBC profile is the only one available for systems where
> > > > codec switching is not supported, it would mean complete regression as
> > > > these devices completely stops working on those systems.
> > > > 
> > > > Upgrading either pulseaudio or bluez must not lead to problem that some
> > > > bluetooth devices stop working (if they worked before upgrade).
> > > > 
> > > > So no, there would not be any changes in Automatic SBC profile. This one
> > > > should stay untouched, to make it always working with all existing
> > > > devices without any regression.
> > > 
> > > I wasn't aware that advertising the XQ settings during negotiation
> > > breaks some devices. I guess this means that JP Guillaume's SBC XQ
> > > patch can't be accepted, assuming that we value avoiding regressions
> > > more than the improved quality for most headsets?
> > 
> > In this patch series I'm reworking and proposing also XQ profiles at
> > separate endpoints. So in case XQ is broken for paricular device, with
> > codec switching API, user would be able to switch back to automatic SBC
> > profile (on different SEP) which should stay as it is in current
> > version, which is working with all devices.
> 
> Yes, but what about JP Guillaume's patch, which is a simple way of
> achieving XQ support before your patches have been accepted? I planned
> to review it first (because he asked), but now it looks like that may
> not be a good idea (I don't want regressions).

With that "simple way" patch there would be regressions for "broken"
devices. That is the reason why codec switching from bluez side is
needed and having separate SEPs for XQ. So Automatic profile (current
one) could be freezed and would be used like before for all devices.

> > > Here's that patch: 
> > > https://gitlab.freedesktop.org/pulseaudio/pulseaudio/merge_requests/177
> > > 
> 

-- 
Pali Rohár
pali.ro...@gmail.com
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-17 Thread Pali Rohár
On Thursday 17 October 2019 15:52:00 Tanu Kaskinen wrote:
> On Tue, 2019-10-08 at 18:29 +0200, Pali Rohár wrote:
> > Automatic SBC profile is not going to be changed. It is there to support
> > all devices without any tweaks. ValdikSS already did more tests and
> > there are devices which do not work with higher SBC bitpool. So
> > increasing max value of bitpool in Automatic SBC profile would lead to
> > broken support for these devices and therefore regressions.
> > 
> > As Automatic SBC profile is the only one available for systems where
> > codec switching is not supported, it would mean complete regression as
> > these devices completely stops working on those systems.
> > 
> > Upgrading either pulseaudio or bluez must not lead to problem that some
> > bluetooth devices stop working (if they worked before upgrade).
> > 
> > So no, there would not be any changes in Automatic SBC profile. This one
> > should stay untouched, to make it always working with all existing
> > devices without any regression.
> 
> I wasn't aware that advertising the XQ settings during negotiation
> breaks some devices. I guess this means that JP Guillaume's SBC XQ
> patch can't be accepted, assuming that we value avoiding regressions
> more than the improved quality for most headsets?

In this patch series I'm reworking and proposing also XQ profiles at
separate endpoints. So in case XQ is broken for paricular device, with
codec switching API, user would be able to switch back to automatic SBC
profile (on different SEP) which should stay as it is in current
version, which is working with all devices.

> Here's that patch: 
> https://gitlab.freedesktop.org/pulseaudio/pulseaudio/merge_requests/177
> 

-- 
Pali Rohár
pali.ro...@gmail.com
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

[pulseaudio-discuss] Pulseaudio system wide mode design

2019-10-17 Thread Pali Rohár
Hello,

there are repeated problems related to fact that pulseaudio is running
under user session and every user spawns own pulseaudio process.

Only one process can have exclusive access to specific ALSA card.

Also only one process can create connection to bluetooth A2DP device.

Looking at pulseaudio design, which should abstract audio device and
sound cards which are "shared" resources, it looks for me that it is
something which should be managed by (central) point. And not by many,
for every user one.

So what are the main problems which prevent usage of pulseaudio in
system-wide mode. When in system would be running only instance of
pulseaudio and all users would connect to that one instance?

I know only problem related to security, that any process which has
access to pulseaudio socket can control audio settings of all other
processes connected to pulseaudio. And also can load or unload any
pulseaudio module.

But this can be easily fixable by implementing access control, e.g.
users in pulseaudio-admin group would be able to control everything like
before (including module loading) and users in pulseaudio-access group
would be able to see and modify only streams which they created and
would not be able to see other strings (or modify other properties).
And also would not be able to load/unload modules.

Is there anything else which prevents moving pulseaudio into proper
system wide mode?

-- 
Pali Rohár
pali.ro...@gmail.com
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

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

2019-10-17 Thread Pali Rohár
Hello!

On Sunday 06 October 2019 19:58:32 Pali Rohár wrote:
> Changes in v13:
> * Do not use read smoother for A2DP sink when backchannel is in use
> * Use new bluez org.freedesktop.DBus.ObjectManager and RegisterApplication
>   DBus APIs for codec switching
> * Add FastStream codec profile without microphone support
> * Correctly calculate and fill RTP sequence number in aptX-HD encoded frames
> 
> Pali Rohár (10):
>   bluetooth: Implement reading SO_TIMESTAMP for A2DP source
>   bluetooth: Print SO_TIMESTAMP warning for SCO source only once
>   bluetooth: Parse remote timestamp from A2DP RTP packets when available
>   bluetooth: Set initial A2DP profile which bluez already activated

May I ask for review at least for these first 4 patches?

-- 
Pali Rohár
pali.ro...@gmail.com
___
pulseaudio-discuss mailing list
pulseaudio-discuss@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss

Re: [pulseaudio-discuss] How multiple instances of pulse audio handle bluetooth sound devices ?

2019-10-12 Thread Pali Rohár
On Saturday 12 October 2019 12:06:50 Zang MingJie wrote:
> Hi all:
> 
> Currently with typically gdm3 and gnome desktop, multiple instances of
> pulse audio will be started, one for gdm3 login session and one for gnome
> user session.
> 
> Once an bluetooth device is provisioned by bluetoothd, it is not clear
> which instance of pulse audio will grab the devices, currently it may
> depend on the start order of the instance of pulse audio.

Exactly. It should be first instance which asked for bluetooth audio. So
basically pseudo-random one.

> And the current behavior is causing lots of troubles, user may not find the
> sound card because it may be grabbed by the instance of gdm3 session. Is
> there any way to share the device among multiple instances, so all
> instances can play sound to the device.

Pulseaudio supports system-wide mode, when run system instance is
running and any application running under any user can control anything
in pulseaudio.

So the best way would be to teach your gdm3 to stop doing such thing
which is just breaking audio support and other stuff related.

I think that more people should start thinking more about "no
regression" instead of "break everything which is currently working".

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: PGP signature
___
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-10-08 Thread Pali Rohár
On Monday 07 October 2019 10:32:10 Hyperion wrote:
> Not sure it's expired worlwide. In case it is, it's good news. Fine for 
> me.10:28, 7 octobre 2019, "Pali Rohár" 
> pali.ro...@gmail.com: class="b4fd5cf2ec92bc68cb898700bb81355fwmi-quote">If you mean EP class="177d5a4333ac019606de889e143743a1wmi-callto">0398973B1 then it 
> is already expired. I'm not aware ofother patents covering aptX. So I 
> think libopenaptx should be safe here.But I'm not lawyer and do 
> not understand jurisdiction across wholeworld, but I guess it is same 
> problem as with expired patents for MP3.Why should be prohibited 
> to distribute clean room LGPL written code asbinary?On 
> Monday 07 October 2019 10:11:39 Hyperion wrote: class="b4fd5cf2ec92bc68cb898700bb81355fwmi-quote"> both libraries are comming 
> from the same reverse-engineering of a PROPRIETARY PATENTED codec, and BOTH 
> are subject to lawsuit in case it is widely distributed as binary.  /> JP 07.10.2019, 10:06, "Pali Rohár"  href="mailto:pali.ro...@gmail.com;>pali.ro...@gmail.com:  
> But that is something different. Look at commit message where is link to />  correct library for building.   On Monday 07 
> October 2019 10:05:52 Hyperion wrote:   Sorry, I should have 
> provided the link to the source GIT  href="https://github.com/Arkq/openaptx;>https://github.com/Arkq/openaptx  />
> ...

Please do not send such emails to public mailing list, it is hard to
read them and targeted people just need to spend more times to parse
them, before they can reply to it...

About worlwide expiration, I do not know if there are countries in which
aptX patent is still active, but based on fact that aptX codec is more
than 20 years old I guess it should have expired in majority of
countries...

Moreover compilation and packaging of software is distributions job
(like RedHat or Suse). And aptX support in pulseaudio is optional.
Everybody can decide if want to compile also additional aptX support or
not.

So I really do not see a problem there. LGPL license allows it.

-- 
Pali Rohár
pali.ro...@gmail.com


signature.asc
Description: PGP signature
___
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

2019-10-08 Thread Pali Rohár
Explained in other email. We cannot change Automatic SBC profile to not
break some existing devices (with broken A2DP implementation).

One of the main objections against SBC codec is that user does not "what
version of SBC quality is in use" and therefore other proprietary codecs
with fixed settings were created and more widely used. Just because
"aptx-HD" is same on every one device, it is codec with fixed bitrate.
In SBC you do not know if it is low quality = garbage or high quality
comparable ot aptx-HD.

And because of this, there are fixed profiles for SBC codec. SBC-MQ and
SBC-HQ are defined by A2DP standard with fixes SBC settings, so they
always means same parameters, settings and quality (with exception for
sampling frequency). Other profiles SBC-LQ or SBC-XQ are not de-facto
also standardized, there is no bitpool range for them, so they have
fixed bitrate too.

On Monday 07 October 2019 10:04:12 Hyperion wrote:
> Hi Pali, 
> 
> I believe that the average user SHOULD be provided a high quality sound by 
> default. And legacy low quality bitrates SHOULD be a workaround.
> 
> IMHO, an "AUTOMATIC mode with max XQ bitrates and DUAL CHANNEL mode prefered" 
> (aka : max negociated bitpool = 38 per channel) : SHOULD be the default mode 
> of operations, because it will provide a high quality sound for 99% of the 
> devices. 
> 
> Rare remaining devices that have a broken A2DP implementation, OR rare very 
> old devices designed before BT version 2.0 : SHOULD be handled by an  
> "automatic mode with the legacy MQ bitrates" (aka max negociated bitpool = 
> 53). 
> 
> Other SBC modes with FORCED bitpool are usefull for sound researchers / 
> advanced sound specialists, but not relevant for the average user.
> 
> Please tell me what you think about it.
> 
> All the best
> JP
> 
> 06.10.2019, 19:59, "Pali Rohár" :
> > 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), /* bitpoo

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-08 Thread Pali Rohár
Automatic SBC profile is not going to be changed. It is there to support
all devices without any tweaks. ValdikSS already did more tests and
there are devices which do not work with higher SBC bitpool. So
increasing max value of bitpool in Automatic SBC profile would lead to
broken support for these devices and therefore regressions.

As Automatic SBC profile is the only one available for systems where
codec switching is not supported, it would mean complete regression as
these devices completely stops working on those systems.

Upgrading either pulseaudio or bluez must not lead to problem that some
bluetooth devices stop working (if they worked before upgrade).

So no, there would not be any changes in Automatic SBC profile. This one
should stay untouched, to make it always working with all existing
devices without any regression.

On Monday 07 October 2019 16:27:19 Hyperion wrote:
> I'm not talking about old Bluez versions : only about the current stable 
> 5.51, and not talking about codec switchin either.
> 
> Just talking about improvement of MAX negociated values for SBC. Please take 
> a look at my latest patch.
> 
> 07.10.2019, 16:22, "Pali Rohár" :
> > Old bluez versions have bugs and different behavior. So not break
> > anything else and still have working audio playback, it is better to not
> > touch it and use what is currently supported / provided.
> >
> > New features like additional codec support, codec switching, etc...
> > needs new bluez API and new functionality which were introduced in 5.51
> > together with fixed more A2DP related bugs. Instead of workarounding
> > bluez bugs, just to use working one stable SBC codec like before OR
> > update bluez to new version and have new features.
> >
> > On Monday 07 October 2019 16:18:21 Hyperion wrote:
> >>  I disagree with "Also there would not be any feature/functional changes 
> >> in pulseaudio when older bluez version is in use".
> >>  Tests prove that there's no reason for this, if only one mode/profile is 
> >> used.
> >>
> >>  JP
> >>
> >>  07.10.2019, 15:36, "Pali Rohár" :
> >>  > I will try to look what is the problem without --experimental. This
> >>  > should work correctly prior merging this PR.
> >>  >
> >>  > Need to --experimental is just temporary until support in bluez is not
> >>  > fully stable. I guess it would be non-experimental in next bluez
> >>  > version.
> >>  >
> >>  > Also there would not be any feature/functional changes in pulseaudio
> >>  > when older bluez version is in use. So also no change in automatic mode
> >>  > for older bluez versions.
> >>  >
> >>  > On Monday 07 October 2019 15:30:49 Hyperion wrote:
> >>  >>  Without the --experimental flag : negociation stops (see hcidump 
> >> below) and device falls back to "Off" status.
> >>  >>
> >>  >>  btw : if you implement my (simple) negociation algorithm for the 
> >> "Automatic Quality" mode ; AND make it to work without --experimental 
> >> Bluez flag : it woiuld be close to perfect.
> >>  >>
> >>  >>  See my latest patch 
> >> https://gitlab.freedesktop.org/Hyperion/pulseaudio/tree/SBC-XQ
> >>  >>
> >>  >>  jp
> >>  >>
> >>  >>  07.10.2019, 15:25, "Pali Rohár" :
> >>  >>  > And what happened without --experimental?
> >>  >>  >
> >>  >>  > Aim is to support all bluez versions also with and without
> >>  >>  > --experimental flag. Just for older versions (or without 
> >> experimental)
> >>  >>  > it should behave like before this patch series -- only SBC codec in
> >>  >>  > automatic mode and no codec switching.
> >>  >>  >
> >>  >>  > On Monday 07 October 2019 15:20:35 Hyperion wrote:
> >>  >>  >>  Thanks, I forgot the "--experimental" param.
> >>  >>  >>
> >>  >>  >>  Works as expected, like the previous v12 serie of patches
> >>  >>  >>
> >>  >>  >>  JP
> >>  >>  >>
> >>  >>  >>  07.10.2019, 15:15, "Pali Rohár" :
> >>  >>  >>  > Can you check if you have Bluez 5.51 and bluetoothd daemon is 
> >> running with --experimental param?
> >>  >>  >>  >
> >>  >>  >>  > And is not it possible to change profile from Off to Automatic 
>

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-07 Thread Pali Rohár
Old bluez versions have bugs and different behavior. So not break
anything else and still have working audio playback, it is better to not
touch it and use what is currently supported / provided.

New features like additional codec support, codec switching, etc...
needs new bluez API and new functionality which were introduced in 5.51
together with fixed more A2DP related bugs. Instead of workarounding
bluez bugs, just to use working one stable SBC codec like before OR
update bluez to new version and have new features.

On Monday 07 October 2019 16:18:21 Hyperion wrote:
> I disagree with "Also there would not be any feature/functional changes in 
> pulseaudio when older bluez version is in use". 
> Tests prove that there's no reason for this, if only one mode/profile is used.
> 
> JP
> 
> 07.10.2019, 15:36, "Pali Rohár" :
> > I will try to look what is the problem without --experimental. This
> > should work correctly prior merging this PR.
> >
> > Need to --experimental is just temporary until support in bluez is not
> > fully stable. I guess it would be non-experimental in next bluez
> > version.
> >
> > Also there would not be any feature/functional changes in pulseaudio
> > when older bluez version is in use. So also no change in automatic mode
> > for older bluez versions.
> >
> > On Monday 07 October 2019 15:30:49 Hyperion wrote:
> >>  Without the --experimental flag : negociation stops (see hcidump below) 
> >> and device falls back to "Off" status.
> >>
> >>  btw : if you implement my (simple) negociation algorithm for the 
> >> "Automatic Quality" mode ; AND make it to work without --experimental 
> >> Bluez flag : it woiuld be close to perfect.
> >>
> >>  See my latest patch 
> >> https://gitlab.freedesktop.org/Hyperion/pulseaudio/tree/SBC-XQ
> >>
> >>  jp
> >>
> >>  07.10.2019, 15:25, "Pali Rohár" :
> >>  > And what happened without --experimental?
> >>  >
> >>  > Aim is to support all bluez versions also with and without
> >>  > --experimental flag. Just for older versions (or without experimental)
> >>  > it should behave like before this patch series -- only SBC codec in
> >>  > automatic mode and no codec switching.
> >>  >
> >>  > On Monday 07 October 2019 15:20:35 Hyperion wrote:
> >>  >>  Thanks, I forgot the "--experimental" param.
> >>  >>
> >>  >>  Works as expected, like the previous v12 serie of patches
> >>  >>
> >>  >>  JP
> >>  >>
> >>  >>  07.10.2019, 15:15, "Pali Rohár" :
> >>  >>  > Can you check if you have Bluez 5.51 and bluetoothd daemon is 
> >> running with --experimental param?
> >>  >>  >
> >>  >>  > And is not it possible to change profile from Off to Automatic 
> >> Quality?
> >>  >>  >
> >>  >>  > On Monday 07 October 2019 15:08:59 Hyperion wrote:
> >>  >>  >>  The 10 patches compile OK on PA master without warnings.
> >>  >>  >>
> >>  >>  >>  But doesn't work (device is Off with "Automatic Quality 
> >> unavailable" status).
> >>  >>  >>
> >>  >>  >>  Tested on 2 devices.
> >>  >>  >>
> >>  >>  >>  hcidump avdtp
> >>  >>  >>  HCI sniffer - Bluetooth packet analyzer ver 5.51
> >>  >>  >>  device: hci0 snap_len: 1500 filter: 0x400
> >>  >>  >>  < AVDTP(s): Discover cmd: transaction 9 nsp 0x00
> >>  >>  >>  > AVDTP(s): Discover rsp: transaction 9 nsp 0x00
> >>  >>  >>  ACP SEID 1 - Audio Sink
> >>  >>  >>  ACP SEID 2 - Audio Sink
> >>  >>  >>  ACP SEID 3 - Audio Sink
> >>  >>  >>  < AVDTP(s): Set config cmd: transaction 10 nsp 0x00
> >>  >>  >>  ACP SEID 1 - INT SEID 2
> >>  >>  >>  Media Transport
> >>  >>  >>  Media Codec - SBC
> >>  >>  >>    44.1kHz
> >>  >>  >>    DualChannel
> >>  >>  >>    16 Blocks
> >>  >>  >>    8 Subbands
> >>  >>  >>    Loudness
> >>  >>  >>    Bitpool Range 38-38
> >>  >>  >>  > AVDTP(s): Set config rsp: transaction 10 nsp 0x00
> >>  >>  >>  < 

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-07 Thread Pali Rohár
I will try to look what is the problem without --experimental. This
should work correctly prior merging this PR.

Need to --experimental is just temporary until support in bluez is not
fully stable. I guess it would be non-experimental in next bluez
version.

Also there would not be any feature/functional changes in pulseaudio
when older bluez version is in use. So also no change in automatic mode
for older bluez versions.

On Monday 07 October 2019 15:30:49 Hyperion wrote:
> Without the --experimental flag : negociation stops (see hcidump below) and 
> device falls back to "Off" status.
> 
> btw : if you implement my (simple) negociation algorithm for the "Automatic 
> Quality" mode ; AND make it to work without --experimental Bluez flag : it 
> woiuld be close to perfect.
> 
> See my latest patch 
> https://gitlab.freedesktop.org/Hyperion/pulseaudio/tree/SBC-XQ 
> 
> jp
> 
> 07.10.2019, 15:25, "Pali Rohár" :
> > And what happened without --experimental?
> >
> > Aim is to support all bluez versions also with and without
> > --experimental flag. Just for older versions (or without experimental)
> > it should behave like before this patch series -- only SBC codec in
> > automatic mode and no codec switching.
> >
> > On Monday 07 October 2019 15:20:35 Hyperion wrote:
> >>  Thanks, I forgot the "--experimental" param.
> >>
> >>  Works as expected, like the previous v12 serie of patches
> >>
> >>  JP
> >>
> >>  07.10.2019, 15:15, "Pali Rohár" :
> >>  > Can you check if you have Bluez 5.51 and bluetoothd daemon is running 
> >> with --experimental param?
> >>  >
> >>  > And is not it possible to change profile from Off to Automatic Quality?
> >>  >
> >>  > On Monday 07 October 2019 15:08:59 Hyperion wrote:
> >>  >>  The 10 patches compile OK on PA master without warnings.
> >>  >>
> >>  >>  But doesn't work (device is Off with "Automatic Quality unavailable" 
> >> status).
> >>  >>
> >>  >>  Tested on 2 devices.
> >>  >>
> >>  >>  hcidump avdtp
> >>  >>  HCI sniffer - Bluetooth packet analyzer ver 5.51
> >>  >>  device: hci0 snap_len: 1500 filter: 0x400
> >>  >>  < AVDTP(s): Discover cmd: transaction 9 nsp 0x00
> >>  >>  > AVDTP(s): Discover rsp: transaction 9 nsp 0x00
> >>  >>  ACP SEID 1 - Audio Sink
> >>  >>  ACP SEID 2 - Audio Sink
> >>  >>  ACP SEID 3 - Audio Sink
> >>  >>  < AVDTP(s): Set config cmd: transaction 10 nsp 0x00
> >>  >>  ACP SEID 1 - INT SEID 2
> >>  >>  Media Transport
> >>  >>  Media Codec - SBC
> >>  >>    44.1kHz
> >>  >>    DualChannel
> >>  >>    16 Blocks
> >>  >>    8 Subbands
> >>  >>    Loudness
> >>  >>    Bitpool Range 38-38
> >>  >>  > AVDTP(s): Set config rsp: transaction 10 nsp 0x00
> >>  >>  < AVDTP(s): Open cmd: transaction 11 nsp 0x00
> >>  >>  ACP SEID 1
> >>  >>  > AVDTP(s): Open rsp: transaction 11 nsp 0x00
> >>  >>
> >>  >>  06.10.2019, 19:59, "Pali Rohár" :
> >>  >>  > Previously module-bluetooth-policy was switching from A2DP to HSP 
> >> profile
> >>  >>  > when VOIP application started recording of source. Now it switch to 
> >> profile
> >>  >>  > with the highest priority which has both sink and source. In most 
> >> cases it
> >>  >>  > is HSP profile, but it can be also bi-directional A2DP profile (e.g.
> >>  >>  > FastStream codec) as it has better audio quality.
> >>  >>  > ---
> >>  >>  >  src/modules/bluetooth/module-bluetooth-policy.c | 123 
> >> 
> >>  >>  >  1 file changed, 62 insertions(+), 61 deletions(-)
> >>  >>  >
> >>  >>  > diff --git a/src/modules/bluetooth/module-bluetooth-policy.c 
> >> b/src/modules/bluetooth/module-bluetooth-policy.c
> >>  >>  > index 04313aa84..9652a91fe 100644
> >>  >>  > --- a/src/modules/bluetooth/module-bluetooth-policy.c
> >>  >>  > +++ b/src/modules/bluetooth/module-bluetooth-policy.c
> >>  >>  > @@ -59,7 +59,12 @@ struct userdata {
> >>  >>  >  pa_hook_slot *card_init_profile_s

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-07 Thread Pali Rohár
And what happened without --experimental?

Aim is to support all bluez versions also with and without
--experimental flag. Just for older versions (or without experimental)
it should behave like before this patch series -- only SBC codec in
automatic mode and no codec switching.

On Monday 07 October 2019 15:20:35 Hyperion wrote:
> Thanks, I forgot the "--experimental" param.
> 
> Works as expected, like the previous v12 serie of patches
> 
> JP
> 
> 07.10.2019, 15:15, "Pali Rohár" :
> > Can you check if you have Bluez 5.51 and bluetoothd daemon is running with 
> > --experimental param?
> >
> > And is not it possible to change profile from Off to Automatic Quality?
> >
> > On Monday 07 October 2019 15:08:59 Hyperion wrote:
> >>  The 10 patches compile OK on PA master without warnings.
> >>
> >>  But doesn't work (device is Off with "Automatic Quality unavailable" 
> >> status).
> >>
> >>  Tested on 2 devices.
> >>
> >>  hcidump avdtp
> >>  HCI sniffer - Bluetooth packet analyzer ver 5.51
> >>  device: hci0 snap_len: 1500 filter: 0x400
> >>  < AVDTP(s): Discover cmd: transaction 9 nsp 0x00
> >>  > AVDTP(s): Discover rsp: transaction 9 nsp 0x00
> >>  ACP SEID 1 - Audio Sink
> >>  ACP SEID 2 - Audio Sink
> >>  ACP SEID 3 - Audio Sink
> >>  < AVDTP(s): Set config cmd: transaction 10 nsp 0x00
> >>  ACP SEID 1 - INT SEID 2
> >>  Media Transport
> >>  Media Codec - SBC
> >>    44.1kHz
> >>    DualChannel
> >>    16 Blocks
> >>    8 Subbands
> >>    Loudness
> >>    Bitpool Range 38-38
> >>  > AVDTP(s): Set config rsp: transaction 10 nsp 0x00
> >>  < AVDTP(s): Open cmd: transaction 11 nsp 0x00
> >>  ACP SEID 1
> >>  > AVDTP(s): Open rsp: transaction 11 nsp 0x00
> >>
> >>  06.10.2019, 19:59, "Pali Rohár" :
> >>  > Previously module-bluetooth-policy was switching from A2DP to HSP 
> >> profile
> >>  > when VOIP application started recording of source. Now it switch to 
> >> profile
> >>  > with the highest priority which has both sink and source. In most cases 
> >> it
> >>  > is HSP profile, but it can be also bi-directional A2DP profile (e.g.
> >>  > FastStream codec) as it has better audio quality.
> >>  > ---
> >>  >  src/modules/bluetooth/module-bluetooth-policy.c | 123 
> >> 
> >>  >  1 file changed, 62 insertions(+), 61 deletions(-)
> >>  >
> >>  > diff --git a/src/modules/bluetooth/module-bluetooth-policy.c 
> >> b/src/modules/bluetooth/module-bluetooth-policy.c
> >>  > index 04313aa84..9652a91fe 100644
> >>  > --- a/src/modules/bluetooth/module-bluetooth-policy.c
> >>  > +++ b/src/modules/bluetooth/module-bluetooth-policy.c
> >>  > @@ -59,7 +59,12 @@ struct userdata {
> >>  >  pa_hook_slot *card_init_profile_slot;
> >>  >  pa_hook_slot *card_unlink_slot;
> >>  >  pa_hook_slot *profile_available_changed_slot;
> >>  > - pa_hashmap *will_need_revert_card_map;
> >>  > + pa_hashmap *profile_switch_map;
> >>  > +};
> >>  > +
> >>  > +struct profile_switch {
> >>  > + const char *from_profile;
> >>  > + const char *to_profile;
> >>  >  };
> >>  >
> >>  >  /* When a source is created, loopback it to default sink */
> >>  > @@ -142,43 +147,57 @@ static pa_hook_result_t 
> >> sink_put_hook_callback(pa_core *c, pa_sink *sink, void *
> >>  >  return PA_HOOK_OK;
> >>  >  }
> >>  >
> >>  > -static void card_set_profile(struct userdata *u, pa_card *card, bool 
> >> revert_to_a2dp)
> >>  > -{
> >>  > +static void card_set_profile(struct userdata *u, pa_card *card, const 
> >> char *revert_to_profile_name) {
> >>  > + pa_card_profile *iter_profile;
> >>  >  pa_card_profile *profile;
> >>  > + struct profile_switch *ps;
> >>  > + char *old_profile_name;
> >>  >  void *state;
> >>  >
> >>  > - /* Find available profile and activate it */
> >>  > - PA_HASHMAP_FOREACH(profile, card->profiles, state) {
> >>  > - if (profile->available == PA_AVAILABLE_NO)
> >>  > - continue;
> >>  > -
> >>  > - /* Check for correct profi

Re: [pulseaudio-discuss] [PATCH v13 10/10] bluetooth: policy: Treat bi-directional A2DP profiles as suitable for VOIP

2019-10-07 Thread Pali Rohár
Can you check if you have Bluez 5.51 and bluetoothd daemon is running with 
--experimental param?

And is not it possible to change profile from Off to Automatic Quality?

On Monday 07 October 2019 15:08:59 Hyperion wrote:
> The 10 patches compile OK on PA master without warnings.
> 
> But doesn't work (device is Off with "Automatic Quality unavailable" status).
> 
> Tested on 2 devices.
> 
> hcidump avdtp
> HCI sniffer - Bluetooth packet analyzer ver 5.51
> device: hci0 snap_len: 1500 filter: 0x400
> < AVDTP(s): Discover cmd: transaction 9 nsp 0x00
> > AVDTP(s): Discover rsp: transaction 9 nsp 0x00
> ACP SEID 1 - Audio Sink
> ACP SEID 2 - Audio Sink
> ACP SEID 3 - Audio Sink
> < AVDTP(s): Set config cmd: transaction 10 nsp 0x00
> ACP SEID 1 - INT SEID 2
> Media Transport
> Media Codec - SBC
>   44.1kHz 
>   DualChannel 
>   16 Blocks
>   8 Subbands
>   Loudness 
>   Bitpool Range 38-38
> > AVDTP(s): Set config rsp: transaction 10 nsp 0x00
> < AVDTP(s): Open cmd: transaction 11 nsp 0x00
> ACP SEID 1
> > AVDTP(s): Open rsp: transaction 11 nsp 0x00
> 
> 
> 06.10.2019, 19:59, "Pali Rohár" :
> > Previously module-bluetooth-policy was switching from A2DP to HSP profile
> > when VOIP application started recording of source. Now it switch to profile
> > with the highest priority which has both sink and source. In most cases it
> > is HSP profile, but it can be also bi-directional A2DP profile (e.g.
> > FastStream codec) as it has better audio quality.
> > ---
> >  src/modules/bluetooth/module-bluetooth-policy.c | 123 
> > 
> >  1 file changed, 62 insertions(+), 61 deletions(-)
> >
> > diff --git a/src/modules/bluetooth/module-bluetooth-policy.c 
> > b/src/modules/bluetooth/module-bluetooth-policy.c
> > index 04313aa84..9652a91fe 100644
> > --- a/src/modules/bluetooth/module-bluetooth-policy.c
> > +++ b/src/modules/bluetooth/module-bluetooth-policy.c
> > @@ -59,7 +59,12 @@ struct userdata {
> >  pa_hook_slot *card_init_profile_slot;
> >  pa_hook_slot *card_unlink_slot;
> >  pa_hook_slot *profile_available_changed_slot;
> > - pa_hashmap *will_need_revert_card_map;
> > + pa_hashmap *profile_switch_map;
> > +};
> > +
> > +struct profile_switch {
> > + const char *from_profile;
> > + const char *to_profile;
> >  };
> >
> >  /* When a source is created, loopback it to default sink */
> > @@ -142,43 +147,57 @@ static pa_hook_result_t 
> > sink_put_hook_callback(pa_core *c, pa_sink *sink, void *
> >  return PA_HOOK_OK;
> >  }
> >
> > -static void card_set_profile(struct userdata *u, pa_card *card, bool 
> > revert_to_a2dp)
> > -{
> > +static void card_set_profile(struct userdata *u, pa_card *card, const char 
> > *revert_to_profile_name) {
> > + pa_card_profile *iter_profile;
> >  pa_card_profile *profile;
> > + struct profile_switch *ps;
> > + char *old_profile_name;
> >  void *state;
> >
> > - /* Find available profile and activate it */
> > - PA_HASHMAP_FOREACH(profile, card->profiles, state) {
> > - if (profile->available == PA_AVAILABLE_NO)
> > - continue;
> > -
> > - /* Check for correct profile based on revert_to_a2dp */
> > - if (revert_to_a2dp) {
> > - if (!pa_startswith(profile->name, "a2dp_sink"))
> > + if (revert_to_profile_name) {
> > + profile = pa_hashmap_get(card->profiles, revert_to_profile_name);
> > + } else {
> > + /* Find highest priority profile with both sink and source */
> > + profile = NULL;
> > + PA_HASHMAP_FOREACH(iter_profile, card->profiles, state) {
> > + if (iter_profile->available == PA_AVAILABLE_NO)
> >  continue;
> > - } else {
> > - if (!pa_streq(profile->name, "headset_head_unit"))
> > + if (iter_profile->n_sources == 0 || iter_profile->n_sinks == 0)
> >  continue;
> > + if (!profile || profile->priority < iter_profile->priority)
> > + profile = iter_profile;
> >  }
> > + }
> >
> > - pa_log_debug("Setting card '%s' to profile '%s'", card->name, 
> > profile->name);
> > + if (!profile) {
> > + pa_log_warn("Could not find any suitable profile for card '%s'", 
> > card->name);
> > + return;
> > + }
> >
> > - if (pa_card_set_profile(card, profile, false) != 0) {
> > - pa_log_warn("Could not set profile '%s'", profile->name);
> > - contin

Re: [pulseaudio-discuss] [PATCH v13 05/10] bluetooth: Add A2DP aptX and aptX HD codecs support

2019-10-07 Thread Pali Rohár
If you mean EP0398973B1 then it is already expired. I'm not aware of
other patents covering aptX. So I think libopenaptx should be safe here.

But I'm not lawyer and do not understand jurisdiction across whole
world, but I guess it is same problem as with expired patents for MP3.

Why should be prohibited to distribute clean room LGPL written code as
binary?

On Monday 07 October 2019 10:11:39 Hyperion wrote:
> both libraries are comming from the same reverse-engineering of a PROPRIETARY 
> PATENTED codec, and BOTH are subject to lawsuit in case it is widely 
> distributed as binary. 
> 
> JP
> 
> 07.10.2019, 10:06, "Pali Rohár" :
> > But that is something different. Look at commit message where is link to
> > correct library for building.
> >
> > On Monday 07 October 2019 10:05:52 Hyperion wrote:
> >>  Sorry, I should have provided the link to the source GIT 
> >> https://github.com/Arkq/openaptx
> >>
> >>  JP
> >>
> >>  07.10.2019, 09:51, "Pali Rohár" :
> >>  > On Monday 07 October 2019 09:47:21 Hyperion wrote:
> >>  >>  Quotig OpenAPTX Github README :
> >>  >>  "This project is for research purposes only. Without a proper license 
> >> private and commercial usage might be a case of a patent infringement. If 
> >> you are looking for a library, which can be installed and used legally 
> >> (commercial, private and educational usage), go to the Qualcomm® aptX™ 
> >> homepage and contact Qualcomm customer service."
> >>  >
> >>  > Sorry, but I have not found any such quotes in README file.
> >>  >
> >>  >>  So APTX support MUST only be provided for researching purposes, and 
> >> so it should remain an external patch, out of the main PA tree.
> >>  >>
> >>  >>  All the best,
> >>  >>
> >>  >>  The source code itself is licensed under the terms of the MIT 
> >> license. However, compression algorithms are patented and licensed under 
> >> the terms of a proprietary license. Hence, compilation and redistribution 
> >> in a binary format is forbidden!
> >>  >
> >>  > Library is fully licensed under LGPLv2.1+, not under MIT. And there are
> >>  > no proprietary parts. Maybe you are referring to different library?
> >>  >
> >>  >>  06.10.2019, 19:59, "Pali Rohár" :
> >>  >>  > 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
> >>  >>  > ---
> >>  >>  >  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)
> >>

  1   2   3   4   5   >