在线时间18 小时
UID3422508
注册时间2017-9-11
NXP金币0
该用户从未签到
注册会员

- 积分
- 72
- 最后登录
- 2022-3-3
|
在论坛潜水很久,今天帮大家解决两个音频库的问题吧。 1。采样率过快导致音乐失真
2。播放2次音乐后报错,无法继续使用
LPC54114的板子和音频库已经放出来很久了,相信大家对板子的使用已经很熟悉,音频库的移植和使用大家可以参考小马哥的帖子,这里不多说。NXP的音频库做的还是很好的,但是里面有两个小BUG,第一播放音乐时采样速率偏快导致失真。先看下shell信息:
音频库支持的采样率时48k 和44.1k的采样率 ,wav文件的采样率是44.1k,音频库在修改采样率时中只对WM8904的寄存器进行了配置,并没有修改IIS输出的位时钟频率,IIS输出的位时钟频率程序里设置的是通过 PLL分频得到, 代码的如下:
- Chip_Clock_SetFLEXCOMMClockSource(I2S7_FLEXCOMM, SYSCON_FLEXCOMMCLKSELSRC_PLL);
- Chip_I2S_Config(I2S_PORT_TX, &audio_fmt_tx);
复制代码- static I2S_AUDIO_FORMAT_T audio_fmt_tx = {
- I2S_TX, /*!< Data direction: tx or rx */
- NORMAL_MASTER, /*!< Master / Slave configuration */
- I2S_CLASSIC, /*!< I2S mode */
- false, /*!< right channel data in low portion of FIFO */
- false, /*!< left justify data in FIFO */
- false, /*!< data source is the D-Mic subsystem */
- false, /*!< SCK polarity */
- false, /*!< WS polarity */
- 16*LPC54110_IIS_MUL, /*!< Flexcomm function clock divider */
- 2, /*!< Channel Number - 1 is mono, 2 is stereo */
- 16, /*!< Word Width */
- 32, /*!< Frame Width */
- 0, /*!< Data position in the frame */
- 5, /*!< FIFO depth (fifo config) */
- };
复制代码 16*LPC54110_IIS_MUL就是分频比,LPC54110_IIS_MUL是什么呢? 在board.h里面有定义
- #define LPC54110_MAIN_CLOCK 98304000 // 98304000 // 24576000 // 49152000 // 73728000 //98304000
- #define LPC54110_IIS_MUL LPC54110_MAIN_CLOCK/22579200 //24576000
复制代码 音频库中默认是24576000,这个值时匹配48kHZ的,我把他改为 22579200,改完后就可以采样44.1Khz的音乐了。计算公式是
44100(采样率)*2(通道数)*16(数据位数)*16. 至于这个公式是怎么来的我也是一知半解,和WM8904的时钟设置 和 IIS的配置有关
总之这样改完,音乐就不会失真了。
第二个BUG,还是看一下shell信息 如下:
如图所示,在播放第一遍音乐结束之后可以再次播放,第二次播放完以后报了一个错误:
(mem->used) assertion failed at function:rt_free, line number:539
之后就死机了,无法操作shell
导致这个的原因是,wav函数中为两个buf申请内存,释放后buf0和buf1的值没有置位NULL,导致第二次播放时,无法调用rt_malloc函数继续申请内存,
但是由于buf0和buf1维持原来的起始地址,还是可以继续播放音乐,播放完毕后调用释放内存rt_free函数出错。
- void wav(char* filename)
- {
- uint32_t temp;
- int fd;
- struct FMT_BLOCK_DEF fmt_block;
- #if Magicoe
- //检查mempool是否被初始化,否则进行初始化.
- if (is_inited == RT_FALSE)
- {
- rt_mp_init(&_mp, "wav_buf", &mempool[0], sizeof(mempool), mempll_block_size);
- is_inited = RT_TRUE;
- }
- #endif
- if(wav_buf0 == NULL) {
- wav_buf0 = rt_malloc(9000);
- if(wav_buf0 == NULL) {
- rt_kprintf("malloc wav_buf0 failed\n");
- }
- }
- if(wav_buf1 == NULL) {
- wav_buf1 = rt_malloc(9000);
- if(wav_buf1 == NULL) {
- rt_kprintf("malloc wav_buf1 failed\n");
- }
- }
- rt_kprintf("malloc wav_buf0&1 ok %x %x\n", wav_buf0, wav_buf1);
复制代码 代码如图所示,可以看到wav_buf0和wav_buf1申请内存之前先判断是否为NULL。
修改方法如下:在wav函数结尾添加 wav_buf0 = NULL;wav_buf1 = NULL;即可
- rt_free(wav_buf0);
- rt_free(wav_buf1);
-
- wav_buf0 = NULL;
- wav_buf1 = NULL;
-
- list_mem();
-
- close(fd);
- }
- }
复制代码 mp3播放函数同样存在这个问题,修改方法一样!同学们自行修改就好。
|
|