Re: [pulseaudio-discuss] How to change profile of bluetooth headset for different applications?
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?
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?
'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?
'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