搜索
bottom↓
回复: 11

请教有关MP3播放有杂音问题,用的是阿莫公司的VS1003

[复制链接]

出0入0汤圆

发表于 2009-7-28 10:38:29 | 显示全部楼层 |阅读模式
请教一下,我用的阿莫公司的片子,片子没有问题,我弄下来焊在阿莫开发板上没有问题,我制作的程序能完整的播放整段音乐,但中间老有杂音,就好像有划伤的CD片播放声音,用的是STM32的片子,嵌的uC系统,代码如下:请帮看下,谢谢。其中播放单字符没有问题,很正常
u16   MP3_Play(u16 item,u8  *buf )                        // item=0 搜索根目录下的 mp3文件并返回数量,不播放
{                                                                                        // item≠0 从item开始播放
        u8  Cnt;                                                // 普通变量
        u8  DirSecCout;                                        // 根目录扇区变量
        u16 coun;                                                // 扇区内偏移变量
        u16 Entry=0;                                                // mp3文件数量
        u32 FileClus;                                        // mp3文件簇号
        u32 FileSect;                                        // mp3文件长度/扇区变量
        u32 totalsect;                                        // 文件拥有的扇区数
        u16 leftbytes;                                        // 文件剩余字节
        u8  n;                                                        // 簇扇区变量
        u8  j;                                                        // 播放字节变量
        u16 count;                                                // 播放缓冲区指针变量
        u32 LBA32;                                                // 32bit绝对扇区变量
        //        u32 Rootcluster;                                        // FAT32根目录簇号暂存变量

        u8  Playbuf[512];
        GPIO_SetBits(GPIOC, GPIO_Pin_9);
        GPIO_ResetBits(GPIOC, GPIO_Pin_12);       
        //        Rootcluster = FirstDircluster;
        // FAT32根目录首簇号赋给暂存变量
        if(DirSecitemCunt==FAT16) DirSecCout=32;
        // FAT16根目录为32扇区
        else DirSecCout=BPBSecPerClust;
        // FAT32单个根目录为一簇的扇区数,分多个簇段  
        LBA32 = (u32)FirstDirSector;
        for(Cnt=0;Cnt<DirSecCout;Cnt++)
        // 在DirSecCout个根目录扇区内搜索  
        {
                if(0 == item) MSD_ReadBlock(buffer, (LBA32+Cnt), 512);                // 搜索歌曲
                for(coun=0;coun<512;coun+=32)                                         // 目录项基数为32字节
                {
                        if(0 != item) MSD_ReadBlock(buffer, (LBA32+Cnt), 512);        // 播放歌曲               
                        if(('.' != buffer[coun])&&(0x00 != buffer[coun])&&(0xE5 != buffer[coun])&&(0x0F != buffer[coun+11]))// 确保是正确可访问文?
                        { //文件名32个字节整数倍的开头       
                                if(( buffer[coun+0] == buf[0])&&( buffer[coun+1] == buf[1])&&( buffer[coun+2] == buf[2])&&
                                ( buffer[coun+3] == buf[3])&&( buffer[coun+4] == buf[4])&&( buffer[coun+5] == buf[5])&&
                                ( buffer[coun+6] == buf[6])&&( buffer[coun+7] == buf[7])&&('M' == buffer[coun+8])&&
                                ('P' == buffer[coun+9])&&('3' == buffer[coun+10]))
                                Entry++;
                                if((item == Entry)&&(0 != Entry))                     // 如果相等开始播放
                                {
                                        /*printf1(0x77);printf1(0x77);printf1(0x77);printf1(0x77);printf1(0x77);printf1(0x77);printf1(0x77);
                                        printf1( buffer[coun+0]);printf1( buffer[coun+1]);printf1( buffer[coun+2]);printf1( buffer[coun+3]);
                                        printf1( buffer[coun+4]);printf1( buffer[coun+5]);printf1( buffer[coun+6]);printf1( buffer[coun+7]);
                                        printf1( buffer[coun+8]);printf1( buffer[coun+9]); printf1( buffer[coun+10]); */   
                                        Mp3Reset();                                   // 播放前软复位VS1003b
                                        if(DirSecitemCunt==FAT16)
                                        {
                                                FileClus = 0;
                                                FileClus = ((u16)buffer[coun+26])|((u16)buffer[coun+27]<<8);    // 获取FAT16文件首簇号
                                        }
                                        else
                                        {
                                                FileClus = ((u32)buffer[coun+26])|((u32)buffer[coun+27]<<8)|
                                                ((u32)buffer[coun+20]<<16)|((u32)buffer[coun+21]<<24);           // 获取FAT32文件首簇号
                                        }
                                        FileSect = ((u32)buffer[coun+28])|((u32)buffer[coun+29]<<8)|
                                              ((u32)buffer[coun+30]<<16)|((u32)buffer[coun+31]<<24);            // 获取文件长度                                       
                                        totalsect = FileSect / 512;  // 计算文件拥有的扇区数
                                        if(totalsect<4) goto Exit;   // 如果文件小于2K
                                        leftbytes = FileSect % 512;  // 计算剩余的字节数  
                                        FatClusSec = 0;              // 簇号所在的FAT扇区,每首歌播放前清0
                                        while(1)                     // 音乐播放函数,一曲播放完退出
                                        {
                                                FileSect=(FileClus-2)*BPBSecPerClust+FirstDataSector-8;   // 数据扇区=(簇号-2)×每簇扇区数+数据区起始扇区
                                                 
                                                Mp3SelectData();
                                               
                                                 Delay_us(1);
                                                Mp3DeselectControl();
                                                Delay_us(1);
                                                for(n=0;n<BPBSecPerClust;n++)// 播放一个簇的全部扇区
                                                {
                                                        MSD_ReadBlock(Playbuf, (FileSect+n), 512);// 读一扇区数据到播放缓冲区
                                                        count=0;
                                                        //Mp3DeselectControl();
                                                        //Mp3SelectData();
                                                        while(count<512)
                                                        {
                                                                  Delay_us(1);  
                                                                    while (GPIO_ReadInputData(GPIOE) & MP3_DREQ == 0);    //等待DREQ为高向VS1003b发送32字节数据
                                                                   if(GPIO_ReadInputData(GPIOE) & MP3_DREQ)
                                                                   {
                                                                        for(j=0;j<32;j++)
                                                                        {
                                                                                SPIPutChar(Playbuf[count]);                                                                        
                                                                                count++;
                                                                                  // Delay_us(100);
                                                                                //  while (GPIO_ReadInputData(GPIOE) & MP3_DREQ != 0);
                                                                        }
                                                                        if((0 ==totalsect)&&(count>=leftbytes)) goto Exit;  // 文件结束?
                                                                        if((n+1 ==BPBSecPerClust)&&(count==32)) FileClus=GetNextCluster(FileClus);
                                                                        // 播放一簇文件的最后一个扇区时加载下一簇号
                                                                        if((DirSecitemCunt==FAT16 && FileClus==0x0000FFFF)||(FileClus==0x0FFFFFFF)) goto Exit;
                                                                                  // 防止读取簇号意外出错
                                                                }
                                                        }
                                                        //Mp3DeselectData();
                                                        totalsect--;      // 文件拥有扇区数减1   
                                                       
                                                }
                                               
                                                 Mp3DeselectData();
                                        }
                                        Exit:
                                        count=2048;                      //  放完一首歌,向VS1003b填充2048个0
                                        Mp3SelectData();
                                        while(count)
                                        {
                                                Delay_us(100);
                                                while (GPIO_ReadInputData(GPIOE) & MP3_DREQ == 0);     //等待DREQ为高   
                                                {
                                                        for(j=0;j<32;j++)
                                                        {
                                                                SPIPutChar(0);
                                                                count--;
                                                        }
                                                }
                                        }
                                        Mp3DeselectData();
                                        item++;                                                    // 放完一首歌加1,否则不能继续播放
                                }
                        }
                }
        }
        return Entry;                // 返回根目录下mp3文件数量



}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2009-7-28 10:40:13 | 显示全部楼层
while(count)
                                        {
                                                Delay_us(100);
                                                while (GPIO_ReadInputData(GPIOE) & MP3_DREQ == 0);     //等待DREQ为高   
                                                {
                                                        for(j=0;j<32;j++)
                                                        {
                                                                SPIPutChar(0);
                                                                count--;
                                                        }
                                                }
                                        }


其中这个位置的延迟时间我完全去掉或者改值都是一样问题

出0入0汤圆

发表于 2009-7-28 11:46:59 | 显示全部楼层
FileSect=(FileClus-2)*BPBSecPerClust+FirstDataSector-8;   // 数据扇区=(簇号-2)×每簇扇区数+数据区起始扇区
为何要减8

出0入0汤圆

发表于 2009-7-28 11:48:21 | 显示全部楼层
可以试试bps很低的MP3文件来放,排除因速度不够,数据断流出现杂音的可能性.比如32kbps的文件来测试.

出0入0汤圆

 楼主| 发表于 2009-7-28 14:10:03 | 显示全部楼层
谢谢你,我先测下看看,,有结果立刻来说

出0入0汤圆

 楼主| 发表于 2009-7-28 16:39:51 | 显示全部楼层
在播放音乐时候,我测VS1003的DREQ引脚时候,发现一直拉高。然后我把该脚与单片机断开,不在检测单片机上的引脚,这时候播放音乐VS1003的DREQ也是始终为高

出0入0汤圆

 楼主| 发表于 2009-7-28 16:48:59 | 显示全部楼层
这应该是哪方面的问题啊
也就是单片机始终在给1003送数据

出0入0汤圆

 楼主| 发表于 2009-7-28 17:02:26 | 显示全部楼层
我播放文件已经是低的bps,但还是一样

出0入0汤圆

发表于 2009-7-28 18:14:02 | 显示全部楼层
像有划伤的CD片播放声音

估计是MP3丢帧了,如果数据来源(MP3文件是完好的、MCU读取文件也没有错误)没有问题,那就看vs1003是否正确初始化,然后再做个正弦波测试看看。

出0入0汤圆

发表于 2009-7-29 11:30:38 | 显示全部楼层
您在初始化VS003B时,观察一下DREQ引脚,应该有跳变脉冲的.还有要将发送到VS1003B的数据全部送串口先在PCS机上显示,核对是否与文件完全一致.

出0入0汤圆

 楼主| 发表于 2009-8-1 14:48:21 | 显示全部楼层
gdrc 古道热肠  谢谢你
我QQ是46631266,你能加我,碰到问题在QQ上问你吗谢谢

出0入0汤圆

 楼主| 发表于 2009-8-10 11:54:05 | 显示全部楼层
正玹波测试没有问题啊,文件也正确啊,初始化看不出问题来,怎么还有那个音
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-12 11:50

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表