122 lines
4.1 KiB
C++
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);
|
|
}
|
|
}
|
|
}
|