[alsa-devel] [RFC] ALSA scenario API
A little late with this but "better late than never".....I did promise a few people that I would post what was imho needed for ALSA scenarios.
Also, apologies for cross posting, but it some of this probably applies to both lists...
ALSA probably needs functionality to define and set audio usage scenarios. A scenario is simply a list of sound card mixer settings for a given use case. This is quite important for mobile devices (e.g. Smartphones, GPS, PDA, etc) with complex audio routing and power requirements. Some example scenarios could be :-
"HiFi Headphone Playback" "HiFi Speaker Playback" "Handset Phone Call" "Headset Phone Call" etc...
Scenarios are changed atm by either manually setting each control (e.g. using alsamixer or alsa-lib in apps) or by using alsactl to restore a scenario. The above two methods are not very portable between devices and applications. We would ideally like to just say "set Phone Call Handset" for a regular handset phone call or "set HiFi Headphones" for MP3 playback.
ALSA also needs to have functionality to alias mixer controls. This would allow a single master volume/mute control to be exposed to user space and have it aliased to different hardware controls based upon the current scenario. e.g. Many mobile devices have different physical volume controls for speaker and headphones. This makes it somewhat difficult for user space apps to change the correct volume (without being bound to the hardware). We would like to be able to just say "set volume to 0dB" and have the alias take care of the correct physical CODEC mixer for the current scenario.
Proposal: ========
1. Add some new scenario functions to (s)alsa-lib. e.g.
snd_scenario_set(); snd_scenario_get(); snd_scenario_list();
_set() would set the scenario e.g.
snd_scenario_set(card, SND_VOICE_CALL_HANDSET);
We would need to have a list of standard scenarios so that applications could be more portable. Vendor scenario's should also be supported.
_get() would return the current scenario.
_list() would return a list of supported scenarios for the given device.
2. Add some new mixer alias functions to set/get the current "master" volume/mute. e.g.
snd_kcontrol *snd_scenario_volume_set(card, type, volume); snd_kcontrol *snd_scenario_switch_set(card, type, switch);
where type is playback, capture, sidetone, bypass, etc
This would set the volume for the current scenario and would guarantee always to get/set the _correct_ volume/switch.
3. Add a new function to return the active PCM for a given scenario. e.g.
snd_scenario_get_pcm(card, scenario);
Would return the given PCM for a particular scenario. i.e. the WM9713 driver has PCM 0.0 for high quality (higher power) audio (MP3), PCM 0.1 for lower power voice and PCM 0.2 for lowest power and quality system sounds.
Note: scenarios may need to be more tightly bound to PCM's rather than cards.
4. Define a file format to represent each scenario. Probably base this upon alsactl's format as alsamixer could be used to quickly generate good settings and then save them with alsactl. Alias, scenario names and PCM would need to be added later somehow.
5. (Optional) Allow scenarios to define active kcontrols. This would allow tools like alsamixer to only display mixer controls for the given scenario. Controls that don't effect the scenario would not be rendered. (similar to alsamixers Playback|Capture|All tab)
6. (OHM list) Add input driver (or similar) for sound card user events. We need to be able to send events like "Headphone Jack Insertion", "Mic Jack Insertion", etc to user space. This would allow changing of scenario and power configuration depending on policy and configuration.
Just my 2p
Unfortunately I'm not in a position to implement any of this functionality. However, it's probably useful to folks working on mobile devices. Maybe a good project for Google SoC.
HTH
Liam
At Wed, 17 Oct 2007 01:12:13 +0100, Liam Girdwood wrote:
A little late with this but "better late than never".....I did promise a few people that I would post what was imho needed for ALSA scenarios.
Also, apologies for cross posting, but it some of this probably applies to both lists...
ALSA probably needs functionality to define and set audio usage scenarios. A scenario is simply a list of sound card mixer settings for a given use case. This is quite important for mobile devices (e.g. Smartphones, GPS, PDA, etc) with complex audio routing and power requirements. Some example scenarios could be :-
"HiFi Headphone Playback" "HiFi Speaker Playback" "Handset Phone Call" "Headset Phone Call" etc...
Scenarios are changed atm by either manually setting each control (e.g. using alsamixer or alsa-lib in apps) or by using alsactl to restore a scenario. The above two methods are not very portable between devices and applications. We would ideally like to just say "set Phone Call Handset" for a regular handset phone call or "set HiFi Headphones" for MP3 playback.
ALSA also needs to have functionality to alias mixer controls. This would allow a single master volume/mute control to be exposed to user space and have it aliased to different hardware controls based upon the current scenario. e.g. Many mobile devices have different physical volume controls for speaker and headphones. This makes it somewhat difficult for user space apps to change the correct volume (without being bound to the hardware). We would like to be able to just say "set volume to 0dB" and have the alias take care of the correct physical CODEC mixer for the current scenario.
Proposal:
- Add some new scenario functions to (s)alsa-lib. e.g.
snd_scenario_set(); snd_scenario_get(); snd_scenario_list();
_set() would set the scenario e.g.
snd_scenario_set(card, SND_VOICE_CALL_HANDSET);
We would need to have a list of standard scenarios so that applications could be more portable. Vendor scenario's should also be supported.
_get() would return the current scenario.
_list() would return a list of supported scenarios for the given device.
- Add some new mixer alias functions to set/get the current "master"
volume/mute. e.g.
snd_kcontrol *snd_scenario_volume_set(card, type, volume); snd_kcontrol *snd_scenario_switch_set(card, type, switch);
where type is playback, capture, sidetone, bypass, etc
This would set the volume for the current scenario and would guarantee always to get/set the _correct_ volume/switch.
- Add a new function to return the active PCM for a given scenario.
e.g.
snd_scenario_get_pcm(card, scenario);
Would return the given PCM for a particular scenario. i.e. the WM9713 driver has PCM 0.0 for high quality (higher power) audio (MP3), PCM 0.1 for lower power voice and PCM 0.2 for lowest power and quality system sounds.
Note: scenarios may need to be more tightly bound to PCM's rather than cards.
- Define a file format to represent each scenario. Probably base this
upon alsactl's format as alsamixer could be used to quickly generate good settings and then save them with alsactl. Alias, scenario names and PCM would need to be added later somehow.
- (Optional) Allow scenarios to define active kcontrols. This would
allow tools like alsamixer to only display mixer controls for the given scenario. Controls that don't effect the scenario would not be rendered. (similar to alsamixers Playback|Capture|All tab)
- (OHM list) Add input driver (or similar) for sound card user events.
We need to be able to send events like "Headphone Jack Insertion", "Mic Jack Insertion", etc to user space. This would allow changing of scenario and power configuration depending on policy and configuration.
Just my 2p
Unfortunately I'm not in a position to implement any of this functionality. However, it's probably useful to folks working on mobile devices. Maybe a good project for Google SoC.
It's an interesting idea. Similar things are needed vastly for other purposes, such as speaker setup. But, my first thinking is whether we need this in the upper (user-space alsa-lib) level or in the driver level.
Certainly the driver must know at best what scenario is available and how it should react. I've thought this kind of thing could be implemented better, more elegantly, on user-space. But, thinking twice, the driver implementation can be much easier in many cases. Suppose the switching (aliasing) the control name depending on the given scenario. The scenario state is global and must be stored in a global position. The easiest one is in the driver -- this will solve the access permission and race problem automatically, too, which the shared-memory solution always suffers.
Thus, it would be maybe good to implement the secnario as a control element (not necessarily as a mixer element but we can give a different IFACE attribute, e.g. SND_CTL_ELEM_IFACE_CARD). Then the above snd_scenario_set/get/list functions becomes simple snd_ctl_*().
About PCM: if we implement again this kind of things in the driver, we may have a virtual PCM stream for the default use and other fixed PCM streams. They can be opened exclusively, and the default stream opens different H/W stream according to the current scenario. (BTW, still a question remains: when the scenario switch happens on the fly during a PCM stream being used, what should be done?)
Or, simply alsa-lib checks the current scenario value and chooses the appropriate preset setup. This would work well (at least for alsa-lib, not salsa-lib - such a complicated implementation is outside the scope of salsa-lib). This user-space solution (for PCM) has another advantage that it's easier to handle PCM setups for multiple streams. For example, suppose we use "scenario" for speaker setup. emu10k1 uses multiple PCM streams for 4.0/5.1 surrounds, and the driver-side implementation wouldn't work unless it reflects to alsa-lib setup.
My another $0.02.
Takashi
Hi
Thanks for the Takashi's idea.
It's agreement that controlling the scenarios is needed in the alsa-lib. To the mobile device, the policy about the router switch or volume control is so complex that we can't resolve all issues by modified the alsa-lib.
Whether we can develop a simple server which carries out the policy?
But we still need define the control element, it's very important to the server's portability. Because the definition makes BSP to write driver which have the same interface.
-----邮件原件----- 发件人: Takashi Iwai [mailto:tiwai@suse.de] 发送时间: 2007年10月19日 17:15 收件人: Liam Girdwood 抄送: Leijin Tang; alsa-devel; ohm-devel 主题: Re: [alsa-devel] [RFC] ALSA scenario API
At Wed, 17 Oct 2007 01:12:13 +0100,
Liam Girdwood wrote:
A little late with this but "better late than never".....I did promise a
few people that I would post what was imho needed for ALSA scenarios.
Also, apologies for cross posting, but it some of this probably applies
to both lists...
ALSA probably needs functionality to define and set audio usage
scenarios. A scenario is simply a list of sound card mixer settings for
a given use case. This is quite important for mobile devices (e.g.
Smartphones, GPS, PDA, etc) with complex audio routing and power
requirements. Some example scenarios could be :-
"HiFi Headphone Playback"
"HiFi Speaker Playback"
"Handset Phone Call"
"Headset Phone Call"
etc...
Scenarios are changed atm by either manually setting each control (e.g.
using alsamixer or alsa-lib in apps) or by using alsactl to restore a
scenario. The above two methods are not very portable between devices
and applications. We would ideally like to just say "set Phone Call
Handset" for a regular handset phone call or "set HiFi Headphones" for
MP3 playback.
ALSA also needs to have functionality to alias mixer controls. This
would allow a single master volume/mute control to be exposed to user
space and have it aliased to different hardware controls based upon the
current scenario. e.g. Many mobile devices have different physical
volume controls for speaker and headphones. This makes it somewhat
difficult for user space apps to change the correct volume (without
being bound to the hardware). We would like to be able to just say "set
volume to 0dB" and have the alias take care of the correct physical
CODEC mixer for the current scenario.
Proposal:
========
- Add some new scenario functions to (s)alsa-lib. e.g.
snd_scenario_set();
snd_scenario_get();
snd_scenario_list();
_set() would set the scenario e.g.
snd_scenario_set(card, SND_VOICE_CALL_HANDSET);
We would need to have a list of standard scenarios so that applications
could be more portable. Vendor scenario's should also be supported.
_get() would return the current scenario.
_list() would return a list of supported scenarios for the given device.
- Add some new mixer alias functions to set/get the current "master"
volume/mute. e.g.
snd_kcontrol *snd_scenario_volume_set(card, type, volume);
snd_kcontrol *snd_scenario_switch_set(card, type, switch);
where type is playback, capture, sidetone, bypass, etc
This would set the volume for the current scenario and would guarantee
always to get/set the _correct_ volume/switch.
- Add a new function to return the active PCM for a given scenario.
e.g.
snd_scenario_get_pcm(card, scenario);
Would return the given PCM for a particular scenario. i.e. the WM9713
driver has PCM 0.0 for high quality (higher power) audio (MP3), PCM 0.1
for lower power voice and PCM 0.2 for lowest power and quality system
sounds.
Note: scenarios may need to be more tightly bound to PCM's rather than
cards.
- Define a file format to represent each scenario. Probably base this
upon alsactl's format as alsamixer could be used to quickly generate
good settings and then save them with alsactl. Alias, scenario names and
PCM would need to be added later somehow.
- (Optional) Allow scenarios to define active kcontrols. This would
allow tools like alsamixer to only display mixer controls for the given
scenario. Controls that don't effect the scenario would not be rendered.
(similar to alsamixers Playback|Capture|All tab)
- (OHM list) Add input driver (or similar) for sound card user events.
We need to be able to send events like "Headphone Jack Insertion", "Mic
Jack Insertion", etc to user space. This would allow changing of
scenario and power configuration depending on policy and configuration.
Just my 2p
Unfortunately I'm not in a position to implement any of this
functionality. However, it's probably useful to folks working on mobile
devices. Maybe a good project for Google SoC.
It's an interesting idea. Similar things are needed vastly for other
purposes, such as speaker setup. But, my first thinking is whether we
need this in the upper (user-space alsa-lib) level or in the driver
level.
Certainly the driver must know at best what scenario is available and
how it should react. I've thought this kind of thing could be
implemented better, more elegantly, on user-space. But, thinking
twice, the driver implementation can be much easier in many cases.
Suppose the switching (aliasing) the control name depending on the
given scenario. The scenario state is global and must be stored in a
global position. The easiest one is in the driver -- this will solve
the access permission and race problem automatically, too, which the
shared-memory solution always suffers.
Thus, it would be maybe good to implement the secnario as a control
element (not necessarily as a mixer element but we can give a
different IFACE attribute, e.g. SND_CTL_ELEM_IFACE_CARD). Then the
above snd_scenario_set/get/list functions becomes simple snd_ctl_*().
About PCM: if we implement again this kind of things in the driver, we
may have a virtual PCM stream for the default use and other fixed PCM
streams. They can be opened exclusively, and the default stream opens
different H/W stream according to the current scenario. (BTW, still a
question remains: when the scenario switch happens on the fly during a
PCM stream being used, what should be done?)
Or, simply alsa-lib checks the current scenario value and chooses the
appropriate preset setup. This would work well (at least for
alsa-lib, not salsa-lib - such a complicated implementation is outside
the scope of salsa-lib). This user-space solution (for PCM) has
another advantage that it's easier to handle PCM setups for multiple
streams. For example, suppose we use "scenario" for speaker setup.
emu10k1 uses multiple PCM streams for 4.0/5.1 surrounds, and the
driver-side implementation wouldn't work unless it reflects to
alsa-lib setup.
My another $0.02.
Takashi
On Mon, 2007-10-22 at 18:50 +0800, Leijin Tang wrote:
Hi
Thanks for the Takashi's idea. It's agreement that controlling the scenarios is needed in the
alsa-lib. To the mobile device, the policy about the router switch or volume control is so complex that we can't resolve all issues by modified the alsa-lib.
Whether we can develop a simple server which carries out the policy?
But we still need define the control element, it's very important to the server's portability. Because the definition makes BSP to write driver which have the same interface.
The current zaurusd (policy/scenario manager for OpenZaurus) manages the complete and complex audio routing atm very well without any new control elements. It does this by having an asound.state for each scenario and a driver that exposes all it's audio controls. This way it's covers all possible routes within the sound card.
I'm now beginning to think it may be quick and easy to turn some of alsactl into a separate lib (from alsa-lib) and reuse it's file format and store/restore code for scenarios. A new master scenario file could then be added that will list the supported scenarios. e.g.
scenario { name = "phone call handset" # standard name file = "/path/to/phone-call-handset.state" alias master playback volume = 1 # number is control id from state file }
(This format is up to the implementer)
This new file would be parsed by the scenario lib and would allow apps to get/set/list scenarios. It would also allow the aliases to be queried by any device manager daemon/application (in order to update any volume controls).
Liam
On Fri, 2007-10-19 at 11:14 +0200, Takashi Iwai wrote:
About PCM: if we implement again this kind of things in the driver, we may have a virtual PCM stream for the default use and other fixed PCM streams. They can be opened exclusively, and the default stream opens different H/W stream according to the current scenario. (BTW, still a question remains: when the scenario switch happens on the fly during a PCM stream being used, what should be done?)
This probably depends on the scenario change and probably wont matter for most changes e.g. hifi playback then headphone insertion (same pcm) or hifi playback then phone call (different PCM - stop hifi then start voice). I suppose the PCM option was more for scenario audio type e.g. all system sound use pcm:0.2, all voice use pcm:0.1, etc
Or, simply alsa-lib checks the current scenario value and chooses the appropriate preset setup. This would work well (at least for alsa-lib, not salsa-lib - such a complicated implementation is outside the scope of salsa-lib).
This is what's working on the OpenZaurus atm. There is a daemon that alsactl restores a scenario based upon events. i.e. there is an asound.state for each anticipated use case (scenario).
This works well for routing audio (and saving power) but cant tell apps what scenarios are supported or the sink/source pcm.
This user-space solution (for PCM) has another advantage that it's easier to handle PCM setups for multiple streams. For example, suppose we use "scenario" for speaker setup. emu10k1 uses multiple PCM streams for 4.0/5.1 surrounds, and the driver-side implementation wouldn't work unless it reflects to alsa-lib setup.
Imho, the quickest way in user space (without using alsa-lib or salsa) for route, alias and pcm would probably be to extend alsactl (or make a new lib based on alsactl). This would easily give the scenario route changing (already mostly done) and would need simple enough code to add options to get aliases and PCM's.
Liam
participants (3)
-
Leijin Tang
-
Liam Girdwood
-
Takashi Iwai