Re: [pulseaudio-discuss] How to change profile of bluetooth headset for different applications?

2011-05-26 Thread Tanu Kaskinen
On Mon, 2011-05-23 at 18:18 +0100, Colin Guthrie wrote:
 How about this:
 
 Define a new card property similar in concept to
 PA_PROP_DEVICE_INTENDED_ROLES (device.intended_roles) called
 PA_PROP_DEVICE_INTENDED_PROFILE (device.intended_profile).
 
 In bluetooth device, when loading a headset that has both HSP and A2DP,
 populate the device with the following code:
 
 if (supports_hsp  supports_a2dp)
 {
   char *k;
 
   k = pa_sprintf_malloc(%s.%s, PA_PROP_DEVICE_INTENDED_PROFILE, music);
   pa_proplist_sets(card_data.proplist, k, a2dp);
   pa_xfree(k);
 
   k = pa_sprintf_malloc(%s.%s, PA_PROP_DEVICE_INTENDED_PROFILE, video);
   pa_proplist_sets(card_data.proplist, k, a2dp);
   pa_xfree(k);
 
   k = pa_sprintf_malloc(%s.%s, PA_PROP_DEVICE_INTENDED_PROFILE, phone);
   pa_proplist_sets(card_data.proplist, k, hsp);
   pa_xfree(k);
 }
 
 This should result in pacmd list-cards dumping a proplist that includes:
 
  device.intended_profile.music = a2dp
  device.intended_profile.video = a2dp
  device.intended_profile.phone = hsp
 
 
 
 Then a separate module (module-intended-profiles?) could take care of
 listening quite generically for streams landing on sink and do the
 following logic:
 
 
 if (!si-sink || !si-sink-card)
   return PA_HOOK_OK;
 
 char *role = pa_proplist_gets(si-proplist, PA_PROP_MEDIA_ROLE);
 if (!role)
   return PA_HOOK_OK;
 
 char *k = pa_sprintf_malloc(%s.%s, PA_PROP_DEVICE_INTENDED_PROFILE, role);
 pa_card *card = si-sink-card;
 char *profile = pa_proplist_gets(card-proplist, k);
 pa_xfree(k);
 if (!profile)
   return PA_HOOK_OK;
 
 if (!pa_streq(card-active_profile, profile)) {
/* Save the current profile for later restoration */
...
 
if (pa_card_set_profile(card, profile, FALSE)  0)
/* Find the sink of this card as the above call will likely have
 changed it */
sink = pa_idxset_first(card-sinks, NULL);
 
pa_sink_input_move_to(si, sink, FALSE);
 }
 
 
 This code is then completely generic. I'm not 100% sure how well this
 will work in practice as there may be some nasty races etc. but I think
 this general approach could work... Perhaps others (i.e. Tanu :D) have
 better suggestions?

If the priority lists would exist already, the module deciding the
routing could examine the stream properties and pick the sink+port with
the highest priority that can be made available - if the sink+port isn't
immediately available, but can be made available, then the routing
module would change the profile and port as needed.

But the priority lists are not available. I believe the logic that you
propose is otherwise good, except that I don't see how the stream could
land on the bluetooth (a2dp) sink automatically on phone calls.
module-bluetooth-device tags only hsp sinks with the phone tag, not a2dp
sinks, so module-intended-roles can't do the required magic. If the hsp
sink doesn't exist because the a2dp profile is selected, I don't think
there's currently any logic to route the stream to the bluetooth sink.
If, however, by some magic the phone stream would be routed to the a2dp
sink, then I think your proposal would work fine.

For better suggestions, I don't think I have any. Except that use the
policy framework - Lin posted from an intel.com address, so I assume he
or she (sorry, I don't know Chinese names) is working on Meego, and I've
thought that Meego got the policy framework from Maemo. In Maemo the
routing is handled by module-policy-enforcement (which gets the command
to enable the bluetooth-hsp routing mode from the policy framework), and
it works pretty nicely for this kind of use cases.

-- 
Tanu

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] How to change profile of bluetooth headset for different applications?

2011-05-24 Thread Lin, Mengdong
The idea of intended profile is awesome! Great thanks for sharing, Col!  I'll 
try to implement the pseudo module as you suggested. 

I have a quick question: 
 Then a separate module (module-intended-profiles?) could take care of
 listening quite generically for streams landing on sink and do the
 following logic ...

Which event shall I hook for stream landing on sink, is it 
PA_CORE_HOOK_SINK_INPUT_PUT?

Thanks
Amanda
___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] How to change profile of bluetooth headset for different applications?

2011-05-24 Thread Colin Guthrie
'Twas brillig, and Lin, Mengdong at 24/05/11 16:18 did gyre and gimble:
 The idea of intended profile is awesome! Great thanks for sharing, Col!  I'll 
 try to implement the pseudo module as you suggested. 
 
 I have a quick question: 
 Then a separate module (module-intended-profiles?) could take care of
 listening quite generically for streams landing on sink and do the
 following logic ...
 
 Which event shall I hook for stream landing on sink, is it 
 PA_CORE_HOOK_SINK_INPUT_PUT?

Yeah I think that's the right one I'd normally say the _NEW one, but
we need to actually route things first (i.e. assign a sink to the
sink-input) and thus the _PUT is likely the right one.

Like I said in the last mail however, I suspect there could be problems
with changing the profile here due to race conditions of calling a
function inside a hook that triggers another hook, but if we're lucky
there wont be any other module fiddling about that would conflict with
this logic.

It should be quite quick to test it all out tho' just to check that all
is well :)

Good luck and feel free to ask any other questions. You can also pop on
IRC if you like :)

Cheers

Col

-- 

Colin Guthrie
gmane(at)colin.guthr.ie
http://colin.guthr.ie/

Day Job:
  Tribalogic Limited [http://www.tribalogic.net/]
Open Source:
  Mageia Contributor [http://www.mageia.org/]
  PulseAudio Hacker [http://www.pulseaudio.org/]
  Trac Hacker [http://trac.edgewall.org/]

___
pulseaudio-discuss mailing list
pulseaudio-discuss@mail.0pointer.de
https://tango.0pointer.de/mailman/listinfo/pulseaudio-discuss


Re: [pulseaudio-discuss] How to change profile of bluetooth headset for different applications?

2011-05-23 Thread Colin Guthrie
'Twas brillig, and Lin, Mengdong at 23/05/11 16:58 did gyre and gimble:
 Is it possible to handle bluetooth profile change within
 “module-bluetooth-device”, instead of unload this module and reloading
 it with the new profile argument for the same device?

Yeah, this can be changed quite easily. It's already exposed in the API
to allow profile changes without reloading the module.


 I need my bluetooth headset working under A2DP profile for a music/video
 application and switch to HSP profile automatically for a incoming phone
 application. I wonder if the “module-bluetooth-device” can monitor
 application change by hooking sink input’s put and unlink event, change
 profile accordingly, and create/delete sink or source by itself. Then
 “module-switch-on-connect” can handle sink/source switch and
 “module-cork-music-on-phone” can handle music interrupted by a incoming
 call J

Yeah, this kind of support is already planned, so it's certainly not
beyond the realms of possibility!  The policy based configuration goes
beyond bluetooth, for example, if we play 5.1 input, perhaps we should
change to a 5.1 profile (this is a rather basic example, but when UCM
support comes in, this kind of thing will be somewhat commonplace)


 My current solution is to monitor application change in
 “module-bluetooth-discover”: when a phone’s input stream is put and
 current profile is not HSP, the discover module will unload
 “module-bluetooth-device” and reload it to HSP profile. I wonder if the
 bluetooth device module can handle this by itself so unloading and
 reloading can be saved.

Yes, you can just change the profile (pa_card_set_profile()). The sink
itself should ultimately disappear and reappear which may fire other
hooks etc, but hopefully that won't get in your way.

I'm not 100% sure where this code should go however... I'm not convinced
it should be in module-bluetooth-device


How about this:

Define a new card property similar in concept to
PA_PROP_DEVICE_INTENDED_ROLES (device.intended_roles) called
PA_PROP_DEVICE_INTENDED_PROFILE (device.intended_profile).

In bluetooth device, when loading a headset that has both HSP and A2DP,
populate the device with the following code:

if (supports_hsp  supports_a2dp)
{
  char *k;

  k = pa_sprintf_malloc(%s.%s, PA_PROP_DEVICE_INTENDED_PROFILE, music);
  pa_proplist_sets(card_data.proplist, k, a2dp);
  pa_xfree(k);

  k = pa_sprintf_malloc(%s.%s, PA_PROP_DEVICE_INTENDED_PROFILE, video);
  pa_proplist_sets(card_data.proplist, k, a2dp);
  pa_xfree(k);

  k = pa_sprintf_malloc(%s.%s, PA_PROP_DEVICE_INTENDED_PROFILE, phone);
  pa_proplist_sets(card_data.proplist, k, hsp);
  pa_xfree(k);
}

This should result in pacmd list-cards dumping a proplist that includes:

 device.intended_profile.music = a2dp
 device.intended_profile.video = a2dp
 device.intended_profile.phone = hsp



Then a separate module (module-intended-profiles?) could take care of
listening quite generically for streams landing on sink and do the
following logic:


if (!si-sink || !si-sink-card)
return PA_HOOK_OK;

char *role = pa_proplist_gets(si-proplist, PA_PROP_MEDIA_ROLE);
if (!role)
return PA_HOOK_OK;

char *k = pa_sprintf_malloc(%s.%s, PA_PROP_DEVICE_INTENDED_PROFILE, role);
pa_card *card = si-sink-card;
char *profile = pa_proplist_gets(card-proplist, k);
pa_xfree(k);
if (!profile)
return PA_HOOK_OK;

if (!pa_streq(card-active_profile, profile)) {
   /* Save the current profile for later restoration */
   ...

   if (pa_card_set_profile(card, profile, FALSE)  0)
   /* Find the sink of this card as the above call will likely have
changed it */
   sink = pa_idxset_first(card-sinks, NULL);

   pa_sink_input_move_to(si, sink, FALSE);
}


This code is then completely generic. I'm not 100% sure how well this
will work in practice as there may be some nasty races etc. but I think
this general approach could work... Perhaps others (i.e. Tanu :D) have
better suggestions?


 I have another question, I learned that the internal concept of a single
 default device can be replaced by priority lists of devices in future
 routing (from Colin’s blog:
 http://colin.guthr.ie/2010/02/this-is-the-route-to-hell/)
 
 Can the logic of “module-switch-on-connect” conflict with the new
 routing design?

Yes and in fact I've stated as such on
http://pulseaudio.org/ticket/706#comment:11 although I will obviously
ensure that any functionality it achieves is preserved when implementing
more advanced routing options :)


 If yes, this means a latest connected Bluetooth headset may not be the
 default device for a phone call and changing the profile is not needed.
 How can the Bluetooth device module know whether it’s the default device
 for an application when this application’s input stream is PUT?

Good question! I'm not 100% sure, but I think the approach I outlined
above (caveats with races not withstanding) could be the short term
solution.

We were recently talking about routing to sinks+ports in a