//*****************************************************************************
//
// Main Function.
//
//*****************************************************************************
int
main(void)
{
//
// Set the clock frequency.
//
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
//
// Set the default cache configuration
//
am_hal_cachectrl_config(&am_hal_cachectrl_benchmark);
am_hal_cachectrl_enable();
//
// Configure the board for low power operation.
//
am_bsp_low_power_init();
#if (PRINT_UART == 1)
am_bsp_uart_printf_enable();
//
// Clear the terminal and print the banner.
//
am_util_stdio_terminal_clear();
am_util_stdio_printf("Ambiq Micro 'while' example.\n\n");
//
// Brief description
//
am_util_stdio_printf("Used for measuring power in an infinite while loop.\n");
//
// Print the compiler version.
//
am_util_stdio_printf("App Compiler: %s\n", COMPILER_VERSION);
am_util_stdio_printf("HAL Compiler: %s\n", g_ui8HALcompiler);
am_util_stdio_printf("HAL SDK version: %d.%d.%d\n",
g_ui32HALversion.s.Major,
g_ui32HALversion.s.Minor,
g_ui32HALversion.s.Revision);
am_util_stdio_printf("HAL compiled with %s-style registers\n",
g_ui32HALversion.s.bAMREGS ? "AM_REG" : "CMSIS");
#endif // PRINT_UART
amu2s_init();
PDMInit();
am_hal_pdm_enable(PDMHandle);
pdm_trigger_dma();
SEGGER_RTT_ConfigUpBuffer(1, "TestDataLogger", ui8RttLoggerBuffer, RTT_LOGGER_BUFFER_LENGTH_BYTE, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
#if USE_OPUS
/* initialize the audio encoder */
audio_enc_init(true); // true for with header
#endif // #if USE_OPUS
// master interrupt enable
am_hal_interrupt_master_enable();
while(1)
{
#if USE_OPUS
if(g_opusInputReadyFlag == true)
{
g_opusInputReadyFlag = false;
// data ready to encode, run encoder
uint32_t encoded_bytes = audio_enc_encode_frame((short*)g_opusAudioInputBuffer, AUDIO_FRAME_SIZE_SAMPLES, (unsigned char*)g_opusAudioOutputBuffer);
for (int i = 0; i < encoded_bytes; i++)
{
am_util_stdio_printf("%02X ", g_opusAudioOutputBuffer[i]); // %02X 表示大写十六进制,固定2位
}
// send to RTT
//SEGGER_RTT_Write(1, (uint8_t*)g_opusAudioOutputBuffer, encoded_bytes);
// send to AmU2S
amu2s_send(Amu2s_opus, g_opusAudioOutputBuffer, AMU2S_OPUS_BYTES);
#endif // #if USE_OPUS
}
}
}
经上述程序处理,通过串口发送给电脑串口工具接收处理,如下图:
Opus音频数据(压缩比8:1)可以复制串口数据,经winhex工具,直接组成BIN文件,如下图:
然后按下面步骤转换成可以正常播放的wav文件,
将opus文件转成pcm文件命令:
opus_demo_tools_0.2 -d 16000 1 audio_opus opus_pcm
如下图:
//将PCM转换成wav播放文件命令:
python bin_to_wav.py mono -i opus_pcm
如下图:
opus_demo_tools_0.2 -d <sampling rate> <channels> [options] <input> <output>
必选参数:
sampling rate:输出音频的采样率(需与编码时一致)。
channels:声道数(1/2)。
input/output:输入 Opus 比特流和输出文件(如 PCM)。
常用选项:
-d:仅运行解码器。
OPUS文件数据每一帧长度为88个字节,帧开头00 00 00 50,如下面二帧数据,保存BIN文件时,必须保证每帧数据完整,否则在转成PCM文件会出错。
00 00 00 50 12 D8 E5 00 B8 51 93 9B B7 0F 96 C8 88 C1 53 EA 76 1B 12 8F 15 D5 6A 65 3C D2 D8 24 72 07 E5 72 D8 5C 36 EF 66 53 35 DE 5C C8 9D 77 E8 BE 95 DC EF FD 01 A1 2F 88 85 77 16 6B ED DD 0F DF 6A A0 30 AD 8D 02 42 82 D7 B5 FE 21 B4 0A 37 C2 0E B4 A9 A3 45 FA
00 00 00 50 2B 37 89 00 B8 51 93 B0 14 C3 B2 7E 88 83 08 5E 29 62 39 CF C8 0D E6 4A 85 80 D0 56 40 7D EE 07 46 4C B1 08 73 DD 3A DB F7 12 70 3C 7F E3 9B BD 8A E9 A7 E0 83 D7 50 95 9A 64 51 CF 97 6A 37 0E DA 0A B2 53 41 9F E1 1E B3 C1 54 9A 26 C1 4E 7B 97 28 4C 7F
下图出错,就是opus文件有帧不完整时,就会出现转换pcm文件时报错。