Files
2026-08-24 10:03:24 +08:00

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__);
}
}