[讨论] 软解MP3 有做过的来指导一下

90houyidai   2014-12-6 22:10 楼主
串口打印的错误代码
UNKNOWN ERROR:-3
UNKNOWN ERROR:-8

[Hard fault handler - all numbers in hex]
R0 = 200165d0
R1 = 800019d
R2 = 20000eff
R3 = 200009e1
R12 = 20000efd
LR [R14] = 200006a5  subroutine call return address
PC [R15] = 2000170d  program counter
PSR = 0
BFAR = 1fffbfff
CFSR = 8200
HFSR = 40000000
DFSR = 1
AFSR = 0
SCB_SHCSR = 0

程序源码
static void mp3_player(const char *filename)
{
        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解码器指针*/

        //打开音频文件
        fres = f_open (&file, filename, FA_READ );
        //打开失败
        if (fres!=FR_OK)
        {
                printf("read file %s error  ! open another file\r\n",filename);
                fres = f_close (&file);
        }
               
        //打开成功
        //初始化MP3解码器
        Mp3Decoder = MP3InitDecoder();       

        //获取输入数据流,调用helix库解码,输出PCM数据
        while(1)
        {
                //读取MP3文件
                fres = f_read(&file, buffer, sizeof(buffer), &rw_num);
                read_ptr = buffer;                                                                        //指向MP3输入流
                bytes_left = rw_num;                                                                //实际读到的输入流大小

                        while(1)
                        {
                        read_offset = MP3FindSyncWord(read_ptr, bytes_left);        //寻找帧同步,返回同步字
                        if(read_offset < 0)                                //没找到帧同步
                        {
                                break;                                //跳出循环                                                                                                                                                        //
                        }
                       
                        read_ptr += read_offset;                                        //偏移至同步字的位置
                        bytes_left -= read_offset;                                //同步字之后的数据大小
                        if(bytes_left < 1024)                                                        //补充数据
                        {
                                /* 采用DMA读取,补齐4字节对齐 */
                                i=(uint32_t)(bytes_left)&3;                                        //判断多余的字节
                                if(i) i=4-i;                                                                        //需要补充的字节
                                memcpy(buffer+i, read_ptr, bytes_left);        //从对其位置开始复制
                                read_ptr = buffer+i;                                                //指向数据对其位置
                                fres = f_read(&file, buffer+bytes_left+i, sizeof(buffer)-bytes_left-i, &rw_num);//补充数据
                                bytes_left += rw_num;                                                                                //有效数据流大小
                        }
                        err = MP3Decode(Mp3Decoder, &read_ptr, &bytes_left, outBuf[bufflag], 0);                                        //开始解码
                        Frames++;                       
                       
                        if (err != ERR_MP3_NONE)                                                                        //错误处理
                        {
                                switch (err)
                                {
                                        case ERR_MP3_INDATA_UNDERFLOW:
                                                printf("ERR_MP3_INDATA_UNDERFLOW\r\n");
                                                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\r\n");
                                                break;
                       
                                        default:
                                                printf("UNKNOWN ERROR:%d\r\n", err);
                       
                                                // 跳过此帧
                                                if (bytes_left > 0)
                                                {
                                                        bytes_left --;
                                                        read_ptr ++;
                                                }       
                                                break;                                        //程序应该是在这里进入Hard fault
                                }
                        }
                        else                //解码无错误,输出PCM
                        {
                                MP3GetLastFrameInfo(Mp3Decoder, &Mp3FrameInfo);                //获取解码信息                       

                    /* 根据解码信息设置采样率 */
                                if (Mp3FrameInfo.samprate != current_sample_rate)        //采样率
                                {
                                        current_sample_rate = Mp3FrameInfo.samprate;

                                        printf(" \r\n Bitrate       %dKbps", Mp3FrameInfo.bitrate/1000);
                                  printf(" \r\n Samprate      %dHz", current_sample_rate);
                                        printf(" \r\n BitsPerSample %db", Mp3FrameInfo.bitsPerSample);
                                        printf(" \r\n nChans        %d", Mp3FrameInfo.nChans);
                                        printf(" \r\n Layer         %d", Mp3FrameInfo.layer);
                                        printf(" \r\n Version       %d", Mp3FrameInfo.version);
                                        printf(" \r\n OutputSamps   %d", Mp3FrameInfo.outputSamps);

                                        if(current_sample_rate >= I2S_AudioFreq_Default)       
                                        {
                                                CODEC_I2S_Configuration(current_sample_rate); //根据采样率修改I2S速率
                                               
                                        }
                                }
                               
                                /* 输出dac */
                                outputSamps = Mp3FrameInfo.outputSamps;                                                        //PCM数据个数
                               
                                if (outputSamps > 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;
                                        }
                                       
                                Audio_MAL_Play((uint32_t)outBuf[bufflag], outputSamps);
                                        while(XferCplt == 0)                /* wait for DMA transfert complete */
                                        {}                                                                                        /* You can write some code for operate on UDA1380 */
                                        XferCplt = 0;
                                        bufflag = 1 -bufflag;                                       
                                }
                        }
                       
               
                if(file.fptr==file.fsize)                 //文件指针指向文件尾,数据读完
                {
                        printf("END\r\n");                               
                        break;                                                                                
                }
         
        }
       
}
printf(" \r\n关闭解码器");
MP3FreeDecoder(Mp3Decoder);

        f_close(&file);                                                        //关闭文件
}       
       

回复评论 (13)

为什么我的问题永远是零回复
点赞  2014-12-10 22:27
从楼主提供的信息很难分析,没有提供硬件的东西,描述也没有,所以大家也不太好来发表意见

从我的理解来看,软件解码,核心是decode的东西,当然基本的外设都调通了么

比如文件系统、dac等等,这些没有通也是没法实现的

其次,看楼主应该比较新手,只贴出了ERROR-code真的让人头痛,你可以搜索你的代码看看这些code在哪里,或者直接仿真看一下到底哪些地方有问题,基本上有errorcode的代码也算是比较容易调试出问题所在了,哪里error改哪里,比如哪些外设不ok啊

参考一个有效的代码学习起来会快一点,如前一楼层所述链接。

欢迎提供更多的信息,帮您分析
电工
点赞  2014-12-11 09:43
可能要进去MP3Decode函数中看一下-3和-8 ERROR-code代表的含义了,这样定位问题会快一些

电工
点赞  2014-12-11 09:46
引用: lyzhangxiang 发表于 2014-12-11 09:46
可能要进去MP3Decode函数中看一下-3和-8 ERROR-code代表的含义了,这样定位问题会快一些
谢谢回复,提供的三个链接,后两个都看过了,回去研究第一个,硬件部分是spi读写sd卡,通过dma到uda3840的I2s,做wav部分已经可以,error部分有看过,等晚上贴上错误对应代码
点赞  2014-12-11 09:51
通过dma到uda3840的I2s,这部分不太懂,uda3840是啥东西,fs有完整测试过吗,open file---read file ----- re write file ---- file ok ?

引用: 90houyidai 发表于 2014-12-11 09:51
谢谢回复,提供的三个链接,后两个都看过了,回去研究第一个,硬件部分是spi读写sd卡,通过dma到uda3840的I2s,做wav部分已经可以,error部分有看过,等晚上贴上错误对应代码

电工
点赞  2014-12-11 09:56
引用: 90houyidai 发表于 2014-12-10 22:27
为什么我的问题永远是零回复
因为别人不知道你在问什么
点赞  2014-12-11 10:03
引用: lyzhangxiang 发表于 2014-12-11 09:56
通过dma到uda3840的I2s,这部分不太懂,uda3840是啥东西,fs有完整测试过吗,open file---read file ----- re write file ---- file ok ?
文件操作单独做过一遍了typedef void *HMP3Decoder;
enum {
        ERR_MP3_NONE =                  0,
        ERR_MP3_INDATA_UNDERFLOW =     -1,
        ERR_MP3_MAINDATA_UNDERFLOW =   -2,
        ERR_MP3_FREE_BITRATE_SYNC =    -3,
        ERR_MP3_OUT_OF_MEMORY =               -4,
        ERR_MP3_NULL_POINTER =         -5,
        ERR_MP3_INVALID_FRAMEHEADER =  -6,
        ERR_MP3_INVALID_SIDEINFO =     -7,
        ERR_MP3_INVALID_SCALEFACT =    -8,
        ERR_MP3_INVALID_HUFFCODES =    -9,
        ERR_MP3_INVALID_DEQUANTIZE =   -10,
        ERR_MP3_INVALID_IMDCT =        -11,
        ERR_MP3_INVALID_SUBBAND =      -12,

        ERR_UNKNOWN =                  -9999
};

对应的错误代码是这个,不明白是什么意思
点赞  2014-12-11 17:43
引用: lyzhangxiang 发表于 2014-12-11 09:56
通过dma到uda3840的I2s,这部分不太懂,uda3840是啥东西,fs有完整测试过吗,open file---read file ----- re write file ---- file ok ?
不好意思是UDA1380,音频解码,类似da
点赞  2014-12-11 17:46
引用: jishuaihu 发表于 2014-12-11 10:03
因为别人不知道你在问什么
好吧
点赞  2014-12-11 17:50
ERR_MP3_INVALID_SCALEFACT =    -8,
无效的比例因子

ERR_MP3_FREE_BITRATE_SYNC =    -3,
空闲比特同步


从我的理解上来看,问题可能出在其他的模块上面,mp3软件解码你是采用的我之前发的链接中的代码吧,这个应该不会有问题,除非发布者特地修改的问题,当然先别这么想。

这个soft decode模块应该不会有问题,那么主要问题就可能是你的文件流格式不对,看一下你的fs吧,按照我说的测试过了吗,其次是否需要其他的硬件配合比如定时器什么的,移植相关的模块和外设都检查一下。

只能帮你到这了,sorry
电工
点赞  2014-12-12 08:48
引用: lyzhangxiang 发表于 2014-12-12 08:48
ERR_MP3_INVALID_SCALEFACT =    -8,
无效的比例因子

ERR_MP3_FREE_BITRATE_SYNC =    -3,
空闲比特同步


从我的理解上来看,问题可能出在其他的模块上面,mp3软件解码你是采用的我之前发的链接中的代码吧,这个应该不会有问题,除非发布者特地修改的问题,当然先别这么想。

这个soft decode模块应该不会有问题,那么主要问题就可能是你的文件流格式不对,看一下你的fs吧,按照我说的测试过了吗,其次是否需要其他的硬件配合比如定时器什么的,移植相关的模块和外设都检查一下。

只能帮你到这了,sorry
mp3软件解码库是用了野火的,做这个之前单独做过fs读写测试,我再看看其他模块
点赞  2014-12-12 18:26
楼主,你的问题解决了吗?我也遇到了同样的问题。能不能指导一下
点赞  2015-10-31 11:44
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复