1. 程式人生 > >android6.0 framework修改使用兩個音效卡

android6.0 framework修改使用兩個音效卡

底層有兩個音效卡,一個音效卡播放alarm通道的聲音,另外一個播放其他通道的聲音

1)增加一個hal層庫

複製Z:\myandroid\hardware\imx\alsa程式碼,修改Android.mk編譯生成另外一個so庫

2)修改程式碼一個hal層庫播放一種聲音。

系統起來以後會載入audio的hardware庫,檢測音效卡,儲存音效卡資訊。在使用mediaplayer或者audiotrack播放聲音時,會通過stream_type 找對應的裝置,在通過裝置在要使用哪個音效卡。

修改scan_available_device()函式實現,因為兩個音效卡的驅動名字一樣,不能通過這個來載入,要不然兩個audio庫都會載入兩個音效卡。

// change compare name , because two sound card have same driver name
            //if(strstr(control_card_info_get_driver(imx_control), audio_card_list[j]->driver_name) != NULL){
            if(strstr(control_card_info_get_name(imx_control), audio_card_list[j]->name) != NULL){

修改audio_policy.conf檔案:增加:

這個代表第二個hardware庫的資訊。支援哪些裝置等。

 sub {    
      outputs {
      sub_device  {
        sampling_rates 48000
        channel_masks AUDIO_CHANNEL_OUT_STEREO
        formats AUDIO_FORMAT_PCM_16_BIT
        devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET
      }
    }
  }

修改音效卡設定資訊:主要支援的裝置和audio_policy.conf中配置的裝置要一致。第一個音效卡:

static struct audio_card  wm8958_card = {

    //modified by leo, change sound card
    //.name = "wm8958-audio",
    //.driver_name = "wm8958-audio",
    .name = "imx-audio-ms6323",
    .driver_name = "imx-audio-ms6323",

supported_out_devices = (AUDIO_DEVICE_OUT_EARPIECE |
            AUDIO_DEVICE_OUT_SPEAKER |
            AUDIO_DEVICE_OUT_WIRED_HEADSET |
            AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
            AUDIO_DEVICE_OUT_ALL_SCO |
            AUDIO_DEVICE_OUT_DEFAULT),

第二個音效卡:

/* ALSA cards for IMX, these must be defined according different board / kernel config*/
static struct audio_card  wm8958_card = {

    //modified by leo, change sound card
    //.name = "wm8958-audio",
    //.driver_name = "wm8958-audio",
    .name = "imx-audio-ms6324",
    .driver_name = "imx-audio-ms6324",
    .supported_out_devices = (AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),

好了,剩下的就是把特定的straem_type導向到那個音效卡:

首先在RoutingStrategy.h中增加一個路由節點:

enum routing_strategy {
    STRATEGY_MEDIA,
    STRATEGY_PHONE,
    STRATEGY_SONIFICATION,
    STRATEGY_SONIFICATION_RESPECTFUL,
    STRATEGY_DTMF,
    STRATEGY_ENFORCED_AUDIBLE,
    STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
    STRATEGY_ACCESSIBILITY,
    STRATEGY_REROUTING,

    //modified by leo, change alarm sound use another sound card, 2016-5-18
    STRATEGY_SUB,
    NUM_STRATEGIES
};

在修改Engine.cpp,把stream_type中的alarm通道聲音導向這個路由:

routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
{
    // stream to strategy mapping
    switch (stream) {
    case AUDIO_STREAM_VOICE_CALL:
    case AUDIO_STREAM_BLUETOOTH_SCO:
        return STRATEGY_PHONE;
    case AUDIO_STREAM_RING:
        return STRATEGY_SONIFICATION;
    case AUDIO_STREAM_ALARM:
        //return STRATEGY_SONIFICATION;
        ////modified by leo, change alarm sound use another sound card, 2016-5-18
        ALOGV("change alarm sound use another sound card");
        return STRATEGY_SUB;
    case AUDIO_STREAM_NOTIFICATION:
        return STRATEGY_SONIFICATION_RESPECTFUL;
    case AUDIO_STREAM_DTMF:
        return STRATEGY_DTMF;
    default:
        ALOGE("unknown stream type %d", stream);
    case AUDIO_STREAM_SYSTEM:
        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
        // while key clicks are played produces a poor result
    case AUDIO_STREAM_MUSIC:
        return STRATEGY_MEDIA;
    case AUDIO_STREAM_ENFORCED_AUDIBLE:
        return STRATEGY_ENFORCED_AUDIBLE;
    case AUDIO_STREAM_TTS:
        return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
    case AUDIO_STREAM_ACCESSIBILITY:
        return STRATEGY_ACCESSIBILITY;
    case AUDIO_STREAM_REROUTING:
        return STRATEGY_REROUTING;
    }
}

routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
{
    const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();

    // usage to strategy mapping
    switch (usage) {
    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
        if (outputs.isStreamActive(AUDIO_STREAM_RING) ||
                outputs.isStreamActive(AUDIO_STREAM_ALARM)) {
            return STRATEGY_SONIFICATION;
        }
        if (isInCall()) {
            return STRATEGY_PHONE;
        }
        return STRATEGY_ACCESSIBILITY;

    case AUDIO_USAGE_MEDIA:
    case AUDIO_USAGE_GAME:
    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
        return STRATEGY_MEDIA;

    case AUDIO_USAGE_VOICE_COMMUNICATION:
        return STRATEGY_PHONE;

    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
        return STRATEGY_DTMF;

    case AUDIO_USAGE_ALARM:
    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
        //return STRATEGY_SONIFICATION;
        ////modified by leo, change alarm sound use another sound card, 2016-5-18
        return STRATEGY_SUB;
    
    case AUDIO_USAGE_NOTIFICATION:
    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
    case AUDIO_USAGE_NOTIFICATION_EVENT:
        return STRATEGY_SONIFICATION_RESPECTFUL;

    case AUDIO_USAGE_UNKNOWN:
    default:
        return STRATEGY_MEDIA;
    }
}

再在audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const函式中,把這個路由節點的裝置改為AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET

這個裝置只在第二個音效卡配置中才支援,所以就使用第二個音效卡播放alarm的聲音。

    case STRATEGY_SUB:        
        ALOGV("do getDeviceForStrategy availableOutputDevices.types()=0x%x",availableOutputDevices.types());
        device = AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;    
        break;