mstar 平台在配置完音频通道,调通功放后,需要调整声音曲线和声音功率。声音功率是调整音量逻辑最大值(100)时,喇叭(负载)功率的最大值,而声音曲线是音量0 ~ 100 整个区间,对应的音频输出的增益大小,所以声音功率调试也是曲线调试的一部分。
1. 增益寄存器
例如,我当前平台音频输出对应的bank 是0x112D。
其中,音频输出通道有6个,如下
两个寄存器组成16 位,来完成增益值的配置。
2. 增益调整
从上面的excel表格中,可以知悉每个音频通道的增益调整的寄存器的16个bit位。接好喇叭(负载的阻值要和客户要求一样,例如;8欧姆),播放1KHZ -12 db 的音源,接上示波器量负载电压。
-
最大功率调整
将电视音量调整到最大值100,再调整对应输出通道寄存器值,
观察电压变化,并计算功率,达到客户要求的功率为止。 -
曲线调整
最大功率就是音量为100时,寄存器的增益值。接着在调整0~99
这个区间对应的增益值。
3. 音频曲线配置
在customer_1.ini 中
u8Volume_Int 对应的是8~14 bit,u8Volume_Fra对应的是5 ~ 7bit
15 bit 对应的是mute/unmute 位。
曲线关系就是:
音量1 : u8Volume_Int [1] << & u8Volume_Fra[1]
音量2 : u8Volume_Int [2] << & u8Volume_Fra[2]
音量3 : u8Volume_Int [3] << & u8Volume_Fra[3]
… : …
音量100 : u8Volume_Int [100] << & u8Volume_Fra[100]
这100组值就是声音曲线。
4. 曲线设置
mapi_audio_customer.cpp
void mapi_audio_customer::SetAbsoluteVolume(const MAPI_U8 u8Path, MAPI_U8 uPercent, const MAPI_U8 uReserve) const
{
MAPI_U8 TransVolum_int = 0;
MAPI_U8 TransVolum_fra = 0;
UNUSED(uReserve);
if(uPercent >= MAPI_AUDIO_VOLUME_ARRAY_NUMBER)
{
uPercent = MAPI_AUDIO_VOLUME_ARRAY_NUMBER - 1;
printf("SetAbsoluteVolume: uPercent value overflow!!!\n");
}
//check if system configuration provide customized volume curve.
const VolumeCurve_t* const curve = mapi_syscfg_fetch::GetInstance()->GetVolumeCurve();
if ((curve != NULL) && (curve->bEnabled == 1))
{
TransVolum_int = curve->u8Volume_Int[uPercent];
TransVolum_fra = curve->u8Volume_Fra[uPercent];
}
else // Use default volume table.
{
TransVolum_int = (MAPI_U8)(u8Volume[uPercent] >> 8);
TransVolum_fra = (MAPI_U8)(u8Volume[uPercent] & 0x00FF);
}
printf("\nSetAbsoluteVolume: u8Path = 0x%x\n",u8Path);
printf("\nSetAbsoluteVolume: Set Volume int value = 0x%x\n", TransVolum_int);
printf("\nSetAbsoluteVolume: Set Volume fra value = 0x%x\n", TransVolum_fra);
MApi_AUDIO_SetAbsoluteVolume(u8Path, TransVolum_int, TransVolum_fra);
}
u8Patch 对应的就是 lineout0,lineout1,lingout2,lineout3…
当使用外挂混音,需要固定主芯片输出时,可以
MAPI_U8 mapi_audio_customer::fixOutputVolumeOffset() const
{
#define REGADDR (0x112D00)
MAPI_U8 TransVolum_int = 0;
MAPI_U8 TransVolum_fra = 0;
MAPI_U16 u16Temp = 0x0000;
const MAPI_U16 u16Vga = 0x0c00;
const MAPI_U16 u16Hdmi = 0x0400;
const MAPI_U16 u16tv = 0x04c0; // atv, dtv
const MAPI_U16 u16Storage = 0x0b80;
const MAPI_U16 u16Cvbs = 0x0a80;
if(MAPI_INPUT_SOURCE_VGA == m_mainCurInputSrc)
{
u16Temp = u16Vga;
}
else if(MAPI_INPUT_SOURCE_ATV == m_mainCurInputSrc || MAPI_INPUT_SOURCE_DTV == m_mainCurInputSrc)
{
u16Temp = u16tv;
}
else if(MAPI_INPUT_SOURCE_CVBS <= m_mainCurInputSrc && MAPI_INPUT_SOURCE_CVBS_MAX > m_mainCurInputSrc)
{
u16Temp = u16Cvbs;
}
else if (MAPI_INPUT_SOURCE_YPBPR <= m_mainCurInputSrc && MAPI_INPUT_SOURCE_YPBPR_MAX > m_mainCurInputSrc)
{
u16Temp = u16Cvbs;
}
else if(MAPI_INPUT_SOURCE_HDMI <= m_mainCurInputSrc && MAPI_INPUT_SOURCE_HDMI_MAX > m_mainCurInputSrc)
{
u16Temp = u16Hdmi;
}
else if(MAPI_INPUT_SOURCE_STORAGE == m_mainCurInputSrc)
{
u16Temp = u16Storage;
}
else
{
return 0;
}
TransVolum_int = (u16Temp >> 8);
TransVolum_fra = (u16Temp & 0x00FF);
printf("[%s][%d] fix the android output to 4.6db \n",__FUNCTION__,__LINE__);
printf("[%s][%d] source id: %d, reg[0x112D].value = 0x%04x \n",__FUNCTION__,__LINE__,m_mainCurInputSrc,u16Temp);
printf("[%s][%d] int: 0x%02x, fra: 0x%02x \n",__FUNCTION__,__LINE__,TransVolum_int,TransVolum_fra);
MApi_XC_WriteByte(REGADDR , TransVolum_fra);
MApi_XC_WriteByte(REGADDR + 1, TransVolum_int);
return 1;
}
通过MApi_XC_WriteByte 直接固定了lineout0(0x112D) 这一路的输出,其它路也可以通过这种方式固定。