/* * Copyright (c) 2014 Amlogic, Inc. All rights reserved. * * This source code is subject to the terms and conditions defined in the * file 'LICENSE' which is part of this source code package. * * Description: c++ file */ #define LOG_MODULE_TAG "TV" #define LOG_CLASS_TAG "CTvAudio" #include #include #include #include "CTvLog.h" #include "CTvAudio.h" #include "audio_if.h" #include "TvCommon.h" #include "CTvResman.h" CTvAudio *CTvAudio::mInstance; CTvAudio::CTvAudio() { iSInit = true; int ret; ret = audio_hw_load_interface(&device); if (ret) { LOGE("%s %d error:%d\n", __func__, __LINE__, ret); iSInit = false; } LOGI("hw version: %x\n", device->common.version); LOGI("hal api version: %x\n", device->common.module->hal_api_version); LOGI("module id: %s\n", device->common.module->id); LOGI("module name: %s\n", device->common.module->name); if (device->get_supported_devices) { uint32_t support_dev = 0; support_dev = device->get_supported_devices(device); LOGI("supported device: %x\n", support_dev); } int inited = device->init_check(device); if (inited) { LOGE("device not inited, quit\n"); iSInit = false; } memset(&source, 0 , sizeof(struct audio_port_config)); memset(&sink, 0 , sizeof(struct audio_port_config)); patch_handle = -1; sub_patch_handle = -1; main_id = -1; sub_id = -1; } CTvAudio::~CTvAudio() { if (iSInit) { audio_hw_unload_interface(device); iSInit = false; } } CTvAudio *CTvAudio::getInstance() { if (NULL == mInstance) { mInstance = new CTvAudio(); } return mInstance; } void CTvAudio::create_audio_patch(int channel, int device_type) { if (!iSInit) return; int ret; audio_patch_handle_t handle = -1; int decoder_id = -1; /* create the audio patch*/ memset(&source, 0 , sizeof(struct audio_port_config)); source.id = 1; source.role = AUDIO_PORT_ROLE_SOURCE; source.type = AUDIO_PORT_TYPE_DEVICE; source.ext.device.type = device_type; memset(&sink, 0 , sizeof(struct audio_port_config)); sink.id = 2; sink.role = AUDIO_PORT_ROLE_SINK; sink.type = AUDIO_PORT_TYPE_DEVICE; sink.ext.device.type = AUDIO_DEVICE_OUT_SPEAKER; LOGD("create %s mix --> speaker patch...\n", channel == TV_CHANNEL_MAIN ? "MAIN":"SUB"); if (!CTvResman::getInstance()->Resman_Request(RESMAN_APP_HDMI_IN, RESMAN_ID_AUDIO_DECODER, 10000, NULL)) { return; } ret = device->create_audio_patch(device, 1, &source, 1, &sink, &handle); if (ret) { LOGE("%s:fail ret:%d\n",__FUNCTION__,ret); CTvResman::getInstance()->Resman_FreeRes(RESMAN_ID_AUDIO_DECODER); return; } else { LOGD("%s:success\n",__FUNCTION__); } if (channel == TV_CHANNEL_MAIN) { patch_handle = handle; decoder_id = main_id; } else { sub_patch_handle = handle; decoder_id = sub_id; } if (decoder_id == -1) { LOGD("%s:didn't set decoder id?\n", __FUNCTION__); return; } char parm[64] = {0}; sprintf(parm, "patch_set_decoder_id=%d,%d",handle, decoder_id); LOGD("%s:set %s\n", __FUNCTION__, parm); ret = device->set_parameters(device, parm); if (ret) { LOGE("%s:fail ret:%d\n\n",__FUNCTION__,ret); } else { LOGD("%s:success\n",__FUNCTION__); } LOGD("Audio patch created and configured for channel: %s\n", channel == TV_CHANNEL_MAIN ? "MAIN" : "SUB"); } void CTvAudio::release_audio_patch(int channel) { if (!iSInit) return; audio_patch_handle_t handle = -1; if (channel == TV_CHANNEL_MAIN) { handle = patch_handle; patch_handle = -1; } else if (channel == TV_CHANNEL_SUB) { handle = sub_patch_handle; sub_patch_handle = -1; } else { LOGD("Unknown channel: %d\n", channel); return; } if (handle <= 0) { LOGD("No patch to release for channel %s\n", channel == TV_CHANNEL_MAIN ? "MAIN" : "SUB"); return; } LOGD("Destroying audio patch for channel %s (handle=%d)...\n", channel == TV_CHANNEL_MAIN ? "MAIN" : "SUB", handle); int ret = device->release_audio_patch(device, handle); if (ret) { LOGE("Failed to release audio patch, ret=%d\n", ret); } else { LOGD("Audio patch released successfully\n"); } CTvResman::getInstance()->Resman_FreeRes(RESMAN_ID_AUDIO_DECODER); } void CTvAudio::set_audio_av_mute(bool mute) { if (iSInit) { int ret; char parm[64] = {0}; if (mute) { sprintf(parm, "hdmi_av_mute=%s","true"); } else { sprintf(parm, "hdmi_av_mute=%s","false"); } LOGD("%s:set %s\n", __FUNCTION__, parm); ret = device->set_parameters(device, parm); if (ret) { LOGE("%s:fail ret:%d\n",__FUNCTION__,ret); } else { LOGD("%s:success\n",__FUNCTION__); } } } void CTvAudio::set_audio_decoder_id(int channel, int id) { LOGD("%s:channel =%d, id = %d\n", __FUNCTION__, channel, id); if (channel == TV_CHANNEL_MAIN) { main_id = id; } else { sub_id = id; } } void CTvAudio::set_audio_av_audio_only_enabled(bool enable) { int ret; char parm[64] = {0}; sprintf(parm, "av_audio_only=%d",enable ? 1:0); LOGD("%s:set %s\n", __FUNCTION__, parm); ret = device->set_parameters(device, parm); if (ret) { LOGE("%s:fail ret:%d\n",__FUNCTION__,ret); } else { LOGD("%s:success\n",__FUNCTION__); } }