[转帖]机制和策略相分离原则

机制和策略相分离原则

https://blog.csdn.net/azloong/article/details/7387626

“需要提供什么功能”即机制,“如何使用这些功能”即策略。

我还是不太理解..


原创sepnic 最后发布于2012-03-23 16:32:48 阅读数 7585 收藏
展开
这些天大刀阔斧修改了我们的alsa音频驱动,更深切理解了机制和策略分离的重要性。

说来惭愧,Linux Device Drivers一书翻来覆去查阅了无数遍,却忽视了绪论中的一句话:区分机制和策略是Unix设计背后隐含的最好思想之一。

“需要提供什么功能”即机制,“如何使用这些功能”即策略。一年多前,初接手音频驱动开发时,就混淆了机制和策略,主要表现在音频通道方面。

最典型的例如:当codec检测到有headset插入时,就关闭speaker,声音转向headset输出;而检测到headset拔下时,关闭headset通道,声音转向speaker输出。

这个做法,我当时就认为是正确的场景。可是却没有考虑到一些特殊的场景:如在headset插入的状态下,这时如果是闹钟铃声或电话铃声的话,声音还是必须要speaker出来的。

各种应用场景千奇百怪,作为底层的不能假设什么策略是正确的,更不应该擅自去实现这些策略。只需要提供相关的功能即可,上层根据需要来调用这些接口。

还是以上述的音频通道为例:

1、在codec驱动中会实现snd_kcontrol(mixer control)、dapm、audio_map等,如

SOC_SINGLE("Headset Switch", xxx_HEADSET_REG, 0, 1, 0),
SOC_SINGLE("Headfree Switch", xxx_HEADFREE_REG, 0, 1, 0),
上面两个mixer control可对headset和headfree这两个通道进行切换控制。
2、当Android系统跑起来后,可用tinymix命令(Android4.0版本,如果是之前版本的话,用alsa_amixer命令)可看到:

17 BOOL 1 Headset Switch Off
18 BOOL 1 Headfree Switch Off
因为目前没有声音需要输出,因此这两个通道都是关闭的。
3、在Android的音频抽象层audio_hw.c可这样定义:

struct route_setting hf_output[] = {
{
.ctl_name = "Headfree Switch",
.intval = 1,
},

/* end of the route_setting */
{
.ctl_name = NULL,
},
};

struct route_setting hs_output[] = {
{
.ctl_name = "Headset Switch",
.intval = 1,
},

/* end of the route_setting */
{
.ctl_name = NULL,
},
};
这样程序可以根据AudioPolicyService提供的音频策略来控制底层的音频通路:
headset_on = adev->devices & AUDIO_DEVICE_OUT_WIRED_HEADSET;
headphone_on = adev->devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
speaker_on = adev->devices & AUDIO_DEVICE_OUT_SPEAKER;
earpiece_on = adev->devices & AUDIO_DEVICE_OUT_EARPIECE;
bt_on = adev->devices & AUDIO_DEVICE_OUT_ALL_SCO;

/* select output stage */
set_route_by_array(adev->mixer, hs_output, headset_on | headphone_on);
set_route_by_array(adev->mixer, hf_output, speaker_on);
————————————————
版权声明:本文为CSDN博主「sepnic」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/azloong/article/details/7387626

猜你喜欢

转载自www.cnblogs.com/jinanxiaolaohu/p/12491176.html
今日推荐