MP3软件解码

2019-07-21 08:40发布

我在论坛里面找了个heilx软件解码的程序,数据是通过串口接收的,
程序查找同步字都成功了,解码函数也执行通过就是没有看到输出PCM数据,不知道PCM数据到底是在那里输出的

大家帮忙看看在那个位置输出PCM

/**
  * @brief  mp3_player 进行mp3文件解码、播放
  * @param  filename:要播放的文件路径
  * @retval none
  */
//static void mp3_player(const char *filename)
void mp3_player(void)
{
        int err,/* i,*/ outputSamps;//, current_sample_rate = 0;       

        int                                read_offset = 0;                                /* 读偏移指针                                */
        int                                bytes_left = 0;                                        /* 剩余字节数                                */       
        unsigned long        Frames = 0;                                            /* mP3帧计数                                */
        unsigned char        *read_ptr = buffer;                            /* 缓冲区指针                                */
        HMP3Decoder                Mp3Decoder;                                                /* mp3解码器指针                */
       

        //打开成功
        //初始化MP3解码器
        Mp3Decoder = MP3InitDecoder();       
       
        //获取输入数据流,调用helix库解码,输出PCM数据,约20ms完成一次循环
        //开始进入播放状态,期间中断会修改touch_even状态
        while(1)        //循环1, 如果touch_even不是切歌状态则继续呆在循环体里
        {
                //有时出现解码错误,错误后继续在本循环体内,继续播放
               
               
                //
                read_ptr  = buffer;
                bytes_left = 0;
               
                //
                Communication();
               
                if(UART1_Index3 < 1126)
                        break;
                read_ptr     = buffer;                                                                                //指向mp3输入流
                bytes_left   = UART1_Index3;                                                                //实际读到的输入流大小大小
                UART1_Index3 = 0;
                bufflag      = 0;
        //        UART1_Index3 = 0;
               
                //按帧处理       
                while(1)                       
                {

                        read_offset = MP3FindSyncWord(read_ptr, bytes_left);        //寻找帧同步,返回第一个同步字的位置
                        if(read_offset < 0)                                                                                //没有找到同步字
                        {
                                break;                                                                                                //跳出循环2,回到循环1       
                        }
                       
                        read_ptr   += read_offset;                                                                //偏移至同步字的位置
                        bytes_left -= read_offset;                                                                //同步字之后的数据大小       
               
                        //
                        err = MP3Decode(Mp3Decoder, &read_ptr, &bytes_left, outBuf[bufflag], 0);                                                //开始解码 参数:mp3解码结构体、输入流指针、输入流大小、输出流指针、数据格式
                        Frames++;                       
                       
                        if (err != ERR_MP3_NONE)                                                                                                //错误处理
                        {
                                switch (err)
                                {
                                        case ERR_MP3_INDATA_UNDERFLOW:
                                        //        printf("ERR_MP3_INDATA_UNDERFLOW ");
                                                read_ptr = buffer;
                                                //fres = f_read(&file, read_ptr, sizeof(buffer), &rw_num);
                                                bytes_left = rw_num;
                                                break;
                       
                                        case ERR_MP3_MAINDATA_UNDERFLOW:
                                                /* do nothing - next call to decode will provide more mainData */
                                        //        printf("ERR_MP3_MAINDATA_UNDERFLOW ");
                                                break;
                       
                                        default:
                                        //        printf("UNKNOWN ERROR:%d ", err);
                       
                                                // 跳过此帧
                                                if (bytes_left > 0)
                                                {
                                                        bytes_left --;
                                                        read_ptr ++;
                                                }       
                                                break;
                                }
                        }
                        else                //解码无错误,准备把数据输出到PCM
                        {
                                MP3GetLastFrameInfo(Mp3Decoder, &Mp3FrameInfo);                //获取解码信息                               

                                /* 输出到DAC */
                                outputSamps = Mp3FrameInfo.outputSamps;                                                        //PCM数据个数
                               
                                if (outputSamps > 0)
                                {
                                        //
                                        if(1 == Mp3FrameInfo.nChans)
                                                Convert_Mono(  &outBuf[bufflag][0]);
                                        else
                                                Convert_Stereo(&outBuf[bufflag][0]);
                                //        if (Mp3FrameInfo.nChans == 1)        //单声道
                                //        {
                                                //单声道数据需要复制一份到另一个声道
                                //                for (i = outputSamps - 1; i >= 0; i--)
                                        //        {
                                        //                outBuf[bufflag][i * 2] = outBuf[bufflag];
                                        //                outBuf[bufflag][i * 2 + 1] = outBuf[bufflag];
                                        //        }
                                        //        outputSamps *= 2;
                                //        }
                                //        else
                                //        {

                                //        }
                               
                                        //非单声道数据可直接由DMA传输到IIS交给DAC
                                        /* 等待DMA播放完,这段时间我们可以干其他的事,扫描事件进行处理 */
                                //        while((DMA1_Channel5->CCR&DMA_CCR1_EN) && !(DMA1->ISR&DMA1_IT_TC5))
                                //        {

                                //                static uint8_t i=0;
                                        //        if(i==0)
                                        //        {
                                                //  PCM1770_VolumeSet(voice);
                                        //          i++;
                                        //        }

//                                                        even_process();                                                       
                                        //        }
                                               
                                                /*DMA传输完毕*/
                                        // DMA_ClearFlag(DMA1_FLAG_TC5 | DMA1_FLAG_TE5);
                                        // DMA_I2S_Configuration((uint32_t)outBuf[bufflag], outputSamps);
                                        //        bufflag = 1 -bufflag;                                                                                                                                                        //切换buffer

                                }
                        }
                       
               
        //        if(file.fptr==file.fsize)                 //如果指针指向了文件尾,表示数据全部读完
        //        {
                //        printf("END ");
                //        if(play_index<file_num-1)                //自动开始下一首歌曲
                //        {
                        //        play_index++;
                        //        player_state = S_SWITCH;        //进入切歌状态,跳出
                        //}
                        //else
                        //{
                        //        play_index = 0;
                        //        player_state = S_SWITCH;
                        //}
                                       
                //        break;                                                                                 //跳出这首歌的播放状态        while break;
        //        }
         
        }
       
}

//        f_close(&file);                                                        //结束播放本歌曲,关闭文件
//        MP3FreeDecoder(Mp3Decoder);
//        I2S_Stop();
       
}




程序已经执行到了红 {MOD}区域了,输出PCM个数是2304个PCM,但是我查看outbuf缓存区全部00不知道是怎么回事
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
爱好单片机
1楼-- · 2019-07-22 07:53
ricefat 发表于 2016-1-6 19:27
如果清空缓冲区 说明mp3帧错误,你看看decode这个函数返回的什么值

返回是0正确的
liweimin134
2楼-- · 2019-07-22 07:55
楼主解决了吗?我遇到和你一模一样的问题,输入指针的数据都有,输出buff全都是0没有数据,解码函数返回值是0也是正常的。

一周热门 更多>