211 lines
5.5 KiB
C++
211 lines
5.5 KiB
C++
/*
|
|
* 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 <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#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__);
|
|
}
|
|
}
|
|
|
|
|