p26001-store-acs-soc-fw-app/video/hisi/mpp5/HDMIAudioOutput.cpp
2026-09-28 21:33:04 +08:00

122 lines
4.1 KiB
C++

/*
*******************************************************************************
* INCLUDE
*******************************************************************************
*/
#include "HDMIAudioOutput.h"
#include "Util.h"
#include "util/Math.h"
/*
*******************************************************************************
* CONSTANTS
*******************************************************************************
*/
#define AO_DEV_ID 1
namespace Video
{
namespace MPP5
{
/*
*******************************************************************************
* CLASS DEFINE
*******************************************************************************
*/
HDMIAudioOutput::HDMIAudioOutput(const std::string& arg)
: Core::AudioOutput("MPP5::AudioOutput(" + arg + ")"), MPPChannel((uint32_t)HI_ID_AO, AO_DEV_ID, 0)
{
setSampleRate(48000);
setSampleFormat(Core::SampleFormat::S16P);
setChannelLayout(Core::ChannelLayout::STEREO);
setFrameSize(1024);
}
HDMIAudioOutput::~HDMIAudioOutput()
{
}
void HDMIAudioOutput::initialize()
{
_bitWidth = Util::getBitWidth(getSampleFormat());
_sndMode = Util::getSndMode(getChannelLayout());
hi_aio_attr attr;
attr.sample_rate = (hi_audio_sample_rate)getSampleRate();
attr.bit_width = _bitWidth;
attr.work_mode = HI_AIO_MODE_I2S_MASTER;
attr.i2s_type = HI_AIO_I2STYPE_INNERHDMI;
attr.snd_mode = _sndMode;
attr.expand_flag = 0;
attr.frame_num = 8;
attr.point_num_per_frame = getFrameSize();
attr.chn_cnt = Core::channelLayoutChannels(getChannelLayout());
attr.clk_share = 0;
int rc = hi_mpi_ao_set_pub_attr(deviceID(), &attr);
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(
Poco::format("%s: Configure pub-attr FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
rc = hi_mpi_ao_enable(deviceID());
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(Poco::format("%s: Enable FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
rc = hi_mpi_ao_set_volume(deviceID(), getVolumeValue());
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(Poco::format("%s: Configure volume FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
rc);
rc = hi_mpi_ao_enable_chn(deviceID(), channelID());
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(
Poco::format("%s: Enable CHM#%u FAIL: %d(%#x)", name(), channelID(), rc, (uint32_t)rc), rc);
}
void HDMIAudioOutput::deinitialize()
{
hi_mpi_ao_disable_chn(deviceID(), channelID());
hi_mpi_ao_disable(deviceID());
}
void HDMIAudioOutput::onConfigChanged(ParameterNames& names)
{
if (!started())
return;
int rc = hi_mpi_ao_set_volume(deviceID(), getVolumeValue());
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(Poco::format("%s: Configure volume FAIL: %d(%#x)", name(), rc, (uint32_t)rc),
rc);
}
void HDMIAudioOutput::writeFrame(Core::Frame::Ptr pFrame)
{
hi_audio_frame frame = {};
frame.bit_width = HI_AUDIO_BIT_WIDTH_16;
frame.len = pFrame->length;
frame.time_stamp = pFrame->timestamp;
frame.snd_mode = HI_AUDIO_SOUND_MODE_MONO;
frame.virt_addr[0] = pFrame->data[0].get();
if (HI_AUDIO_SOUND_MODE_STEREO == _sndMode)
frame.virt_addr[1] = pFrame->data[1].get();
int rc = hi_mpi_ao_send_frame(deviceID(), channelID(), &frame, 100);
if (rc != HI_SUCCESS)
throw Poco::InvalidAccessException(Poco::format("%s: Send frame FAIL: %d(%#x)", name(), rc, (uint32_t)rc), rc);
}
int HDMIAudioOutput::getVolumeValue()
{
auto lineMapping = [](int inputMin, int inputMax, int outMin, int outMax, int input) -> int
{ return (input - inputMin) * (outMax - outMin) / (inputMax - inputMin) + outMin; };
int gain = ::Util::Math::clamp(getGain(), -100, 100);
if (gain < 0)
return lineMapping(-100, -1, -121, -1, gain);
return lineMapping(0, 100, 0, 6, gain);
}
}
}