搜索
bottom↓
123
返回列表 发新帖
楼主: lusson

闲来无事,也想做个WAV播放器

  [复制链接]

出0入0汤圆

发表于 2014-2-25 22:28:59 | 显示全部楼层
lusson 发表于 2014-2-25 22:22
手工焊的就是没那么好看啊,你的贴片阻容放得真近。
有外壳吗?

尺寸跟这位网友的差不多,经他指点 也买了这个外壳,不过看起来有点厚,而且是铝壳 还不知道怎么钻孔呢
http://www.amobbs.com/thread-5567068-1-1.html

出0入0汤圆

发表于 2014-2-26 09:02:51 | 显示全部楼层
rootxie 发表于 2014-2-25 20:07
还没查呢,到时候全部焊完 再细查!焊接的时候用刀头焊接0805的电容,好些都焊接短路了,查了我好久,真 ...

0805略挤啊,换0603的会好一下… 另外 焊盘先上锡再焊元件不会翘起来么?

出0入0汤圆

发表于 2014-2-26 09:04:56 | 显示全部楼层
lusson 发表于 2014-2-23 14:26
汇报一下最近进展。

已经把CPLD使用上了,I2S时序全部由CPLD产生。CPLD和MCU使用SPI通讯,CPLD内建了8BYTE ...

厉害 这样就完美了! lz的方式好内存好少,我用8k的文件缓冲,内存不够了…

出0入0汤圆

发表于 2014-2-26 11:14:47 | 显示全部楼层
本帖最后由 rootxie 于 2014-2-26 11:45 编辑
majianjia1991 发表于 2014-2-26 09:02
0805略挤啊,换0603的会好一下… 另外 焊盘先上锡再焊元件不会翘起来么?


我就是用的0603的贴片,DAC用的AD1955是电流输出,得多用一级运放,所以明显多了一级调理电路
附上图片,已经焊接完毕,接下来调程序,本来还想搞一下RT-THREAD,先算了,用框架来先做一个

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入54汤圆

 楼主| 发表于 2014-2-26 12:09:35 | 显示全部楼层
majianjia1991 发表于 2014-2-26 09:04
厉害 这样就完美了! lz的方式好内存好少,我用8k的文件缓冲,内存不够了… ...

文件的BUF一样要的啊,目前使用的是双3K buf
现在SPI DMA双BUF方式。
现在使用的库竟然没有DBM的定义,自己上去了。

出0入0汤圆

发表于 2014-2-27 08:15:28 | 显示全部楼层
你们是怎么解决24bit文件的数据对齐的呢?
是先从SD卡上读到buff里面,再来一次数据搬迁中间插入0x00,还是在读SD卡的时候就间隔插入0x00?

出0入54汤圆

 楼主| 发表于 2014-2-27 08:43:56 | 显示全部楼层
dudududu 发表于 2014-2-27 08:15
你们是怎么解决24bit文件的数据对齐的呢?
是先从SD卡上读到buff里面,再来一次数据搬迁中间插入0x00,还是 ...

我?
我现在还没试24bit
目前的设计是CPLD来做,补8bit至32bit是CPLD来做的事情
因为MCU与CPLD是字节传输的,所以MCU不需要去补齐,直接顺序传过去就好了。
顺便问一下。
24bit字节排序和16bit是一样的吧?只是多了个字节。。

出0入0汤圆

发表于 2014-2-27 09:06:42 | 显示全部楼层
lusson 发表于 2014-2-27 08:43
我?
我现在还没试24bit
目前的设计是CPLD来做,补8bit至32bit是CPLD来做的事情

恩,在WAV文件里式样一样地

出0入0汤圆

发表于 2014-2-27 11:07:13 | 显示全部楼层
dudududu 发表于 2014-2-27 09:06
恩,在WAV文件里式样一样地

请教下,你的TF卡有无出现以下问题?


SDIO驱动论坛找了一个,发现TF卡初始化 和FATFS mount都OK,但是一旦打开目录,就跑到
B
ENDP
ALIGN
的B前面,
初步判断,1. 8GTF卡 不读卡,2.硬件有问题,目前这2问题很难排除,手上没有其他的TF卡

请问你的SDIO驱动和FATFS有好用的吗?能否共享一个?谢谢!

出0入0汤圆

发表于 2014-2-27 16:02:31 | 显示全部楼层
rootxie 发表于 2014-2-27 11:07
请教下,你的TF卡有无出现以下问题?

这个就难为我了,我在STM32F4上面只是用官方的库函数跑过一次SDIO,试着从SD卡里面读数据,成功了,并且测试了一下块读和扇区读的速度,然后就没有然后了,直到现在我都还没有把播放器的系统搞定,主要是时间太零碎,没有精力搞;
关于WAV的一点认知,也是之前在TI的M3上面成功播放过一次,不过也只是16bit,24bit貌似TI的M3搞不定所以就转战STM32了。
前段时间把板子洗出啦完成了打件现在还没有正式开始写程序呢。

出0入0汤圆

发表于 2014-2-27 16:48:35 | 显示全部楼层
dudududu 发表于 2014-2-27 16:02
这个就难为我了,我在STM32F4上面只是用官方的库函数跑过一次SDIO,试着从SD卡里面读数据,成功了,并且 ...

你的进度真是龟速啊,貌似你几个月前就打完板了,心态真好!
今天下午搞定SDIO(经QQ群里的一位兄弟提醒),现在根目录 长文件名 搞定了,下午搞了很久的LCD,就是刷不出来,唉,慢慢来吧

出0入0汤圆

发表于 2014-2-27 16:58:51 | 显示全部楼层
rootxie 发表于 2014-2-27 16:48
你的进度真是龟速啊,貌似你几个月前就打完板了,心态真好!
今天下午搞定SDIO(经QQ群里的一位兄弟提醒 ...

必须心态好啊,不然早就死在办工作上了

出0入0汤圆

发表于 2014-2-28 13:42:01 | 显示全部楼层
我晕啊,这正常吗? AD1955 ADA896 + OPA+耳放(目前还没动作) 耗掉 500mA电流

出0入54汤圆

 楼主| 发表于 2014-2-28 15:46:23 | 显示全部楼层
rootxie 发表于 2014-2-28 13:42
我晕啊,这正常吗? AD1955 ADA896 + OPA+耳放(目前还没动作) 耗掉 500mA电流

500mA不是没有可能啊。跟你怎么供电有很大关系。
昨天没看到你的SDIO的问题,我之前也是在论坛找的一个,读大容量卡后面的时候有问题,改了个地方才OK。目前一直很稳定。

出0入0汤圆

发表于 2014-2-28 21:23:25 | 显示全部楼层
rootxie 发表于 2014-2-28 13:42
我晕啊,这正常吗? AD1955 ADA896 + OPA+耳放(目前还没动作) 耗掉 500mA电流

极有可能,因为你是3.7V电压升压的,所以低压端电流大很正常,算上电源效率,然后模拟电路和AD1955什么的,基本上工作和不工作,耗电差不多,只是耳放会有些许差异,但是也不大.
这个和你的运放是多高电压.DAC是多高电压也有关系,自己简单推算一下,应该差别不大

比如,你运放耳放等模拟电路,一个通道静态电流20ma,两个通道就是40ma,然后又是±12V供电,那么功耗就是 40ma*24V = 960mw,算上电源效率80%,功耗为 960mw ÷ 80% = 1200mw,那么对应电池的电流为 1200mw ÷ 3.7V = 324ma, 打给这么估算

出0入0汤圆

发表于 2014-3-1 00:24:13 | 显示全部楼层
lusson 发表于 2014-2-28 15:46
500mA不是没有可能啊。跟你怎么供电有很大关系。
昨天没看到你的SDIO的问题,我之前也是在论坛找的一个, ...


说的有道理
我的电压是从锂电池 直接升压到正负12伏,然后再降压到运放正9伏,另外耳放,AD1955模拟电压降压到5V
发现压差实在太大,效率实在太低,反正DC/DC能调整电压,准备调到正负7.5V,然后再LDO到正负7伏给运放供电
对了,你的硬盘盒子在淘宝哪家买的?我买的那个铝盒实在看上去太厚,不好搞孔

出0入54汤圆

 楼主| 发表于 2014-3-1 08:32:02 | 显示全部楼层
rootxie 发表于 2014-3-1 00:24
说的有道理
我的电压是从锂电池 直接升压到正负12伏,然后再降压到运放正9伏,另外耳放,AD1955模拟电压 ...

这个是在京东上买的
淘宝上一搜也一大截,最便宜的20块钱。我觉得挺合适的。
你搜IT-CEO就有了。
主要是开液晶屏就破坏了美观。

主内部空间是放一个标准笔记本硬盘的,100*70*10(mm)

出0入54汤圆

 楼主| 发表于 2014-3-2 17:03:31 | 显示全部楼层
发现STM32F4的SPI SLAVE模式并不能达到手册写的PCK/2


SPI3理论的话应该是21Mbps,我使用12M就有问题。
现在改用SPI1了,理论是42Mbps

以上都是主频在168M情况下。

出0入54汤圆

 楼主| 发表于 2014-3-3 12:01:43 | 显示全部楼层
刚才测了下192k/16bit和192k/24bit CPU的占用率,分别为18%不到和22%不到。。。。。
不过目前没有加LCD操作。

出0入0汤圆

发表于 2014-3-4 08:55:43 | 显示全部楼层
lusson 发表于 2014-3-3 12:01
刚才测了下192k/16bit和192k/24bit CPU的占用率,分别为18%不到和22%不到。。。。。
不过目前没有加LCD操作 ...

我有点好奇,你们都是怎么测试CPU使用率的??

出0入54汤圆

 楼主| 发表于 2014-3-4 09:36:30 | 显示全部楼层
本帖最后由 lusson 于 2014-3-4 09:37 编辑
dudududu 发表于 2014-3-4 08:55
我有点好奇,你们都是怎么测试CPU使用率的??


我使用的是轮循的架构。
在主循环中时间到了就执行对应的task,否则就执行长任务。长任务周期是16ms

所以只要在主循环中执行task拉低,执行完拉高。然后几个16ms平均起来的CPU占用率就差不多了,出来后波形如下:


中断占用的时间很短,就忽略了。
上面的低电平基本上是读文件的时间。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入54汤圆

 楼主| 发表于 2014-3-5 09:27:18 | 显示全部楼层
FLAC也可以了,解码部分移植的这帖子里的:
http://www.amobbs.com/thread-4531723-1-1.html
谢谢那位朋友。

如帖子所说,在使用FATFS DMA方式 时,需要注意文件buf 4字节对齐的问题,那帖中说读多个block时要判断对齐,我这边测试是不过读多个还是单个都需要判断下对齐。

现在只测了16bit 44.1k的,CPU占用率20%左右。

出0入0汤圆

发表于 2014-3-5 10:04:41 | 显示全部楼层
lusson 发表于 2014-3-5 09:27
FLAC也可以了,解码部分移植的这帖子里的:
http://www.amobbs.com/thread-4531723-1-1.html
谢谢那位朋友 ...

注意buf 4字节对齐问题?神马意思,不是很明白,定义的时候定义成4字节对齐的u8不就行了?
唉,我的播放器要暂停一段时间了,主要原因是,调试的时候不小心碰到那个电源,输出电压调高了,3.3V的升降压芯片立马烧了,吹下来发现 板子焊盘掉了,我靠芯片是QFN那种12pin的,根本就飞不了线出来
我要崩溃了。。。目前再焊接一块板感觉力不从心,等缓缓再说

出0入54汤圆

 楼主| 发表于 2014-3-5 10:30:19 | 显示全部楼层
本帖最后由 lusson 于 2014-3-5 11:30 编辑
rootxie 发表于 2014-3-5 10:04
注意buf 4字节对齐问题?神马意思,不是很明白,定义的时候定义成4字节对齐的u8不就行了?
唉,我的播放 ...


比如你定义一个unsigned char buf[1000]
如果buf[0]的地址是0,那么 buf[1]的地址就是1,依此类推。
buf[1],buf[2],buf[3]的地址都都不能整除4,如果传给fatfs的文件buf,在使用DMA就会出问题。
所以在diskio.c中需要对传过来的buffer判断一下是不是4的倍数。

对以上内容补充下,要4字节对齐是因为FATFS使用DMA是WORD传输,在datasheet中有这样的说明:

When the data width (programmed in the PSIZE or MSIZE bits in the DMA_SxCR register)
is a half-word or a word, respectively, the peripheral or memory address written into the
DMA_SxPAR or DMA_SxM0AR/M1AR registers has to be aligned on a word or half-word
address boundary, respectively.

出0入0汤圆

发表于 2014-3-5 10:44:33 | 显示全部楼层
lusson 发表于 2014-3-5 10:30
比如你定义一个unsigned char buf[1000]
如果buf[0]的地址是0,那么 buf[1]的地址就是1,依此类推。
buf[ ...

难道解码的时候 有block不是2的倍数,不然可以直接定位buf长度为512的倍数,同时指定4字节对齐,就省得判断了

出0入54汤圆

 楼主| 发表于 2014-3-5 11:35:13 | 显示全部楼层
rootxie 发表于 2014-3-5 10:44
难道解码的时候 有block不是2的倍数,不然可以直接定位buf长度为512的倍数,同时指定4字节对齐,就省得判 ...

对齐的原因我上面回帖补充了。

至于为什么会不对齐,是因为FLAC解码时的特点。
FLtxAC每次解码完还会有剩下数据是下一帧的,这时候是先把下一帖的数据移到文件 buf的最前面,然后再把剩余数据读到文件buf中,在读剩余数据的时候,传给f_read的文件buf指针就有可能不是4字节对齐了。
比如我解一帧后剩余下一帧的数字是1个字节,那么我下次读剩余数据时就会使用f_read(&FIL,&buf[1],....),这时候&buf[1]就不是4字节对齐了。

出0入0汤圆

发表于 2014-3-5 16:55:52 | 显示全部楼层
全是高手,受益了。

出0入54汤圆

 楼主| 发表于 2014-3-5 17:56:25 | 显示全部楼层
现在有个比较麻烦的问题。
在切曲的时候会有爆音,我试过把WM8740 MUTE也会有。歌曲间加上2秒的延时的话,则会响2下。
我试了下,应该是I2S时钟在停和开的时候有这个声音。
但是我现在用CPLD生成时钟,在2首歌中间是需要把I2S时钟停一下,BIT和采样率切换完成后再输出。

出0入0汤圆

发表于 2014-3-6 09:16:41 | 显示全部楼层
真是厉害啊

出0入0汤圆

发表于 2014-3-6 12:22:10 | 显示全部楼层
本帖最后由 rootxie 于 2014-3-6 12:26 编辑
lusson 发表于 2014-3-5 17:56
现在有个比较麻烦的问题。
在切曲的时候会有爆音,我试过把WM8740 MUTE也会有。歌曲间加上2秒的延时的话, ...


爆音是DAC配置玩开始运行时的突变引起的,可以给0数据缓冲一段时间,具体缓冲多久,可以查看芯片手册,大概持续几百毫秒,结束也需要一段缓冲,不然也有噗噗声。当然这么做“噗噗噗”声得到极大改善,如果还有可以考虑切断DAC电源,先送一段时间0,DMA发送途中开电源,配置,完毕一段时候后,最后再送音频正文,反正对于一段音频来说,多个几百毫秒-几秒,影响不大

这是我原先调试PCM1770时采用的方法,可以尝试下

出0入0汤圆

发表于 2014-3-6 12:45:16 | 显示全部楼层
本帖最后由 rootxie 于 2014-3-6 12:49 编辑

最近真TM郁闷,摊上事情了。目前正在考虑要不要另外换工作。给大家分享下奇葩的经历!
公司是综合性质的公司,我是属于做硬件的,主要职责是原理图设计,然后出PCB Layout guideline,确认评审PCB(后期如果PCB调试有问题,基本上layout工程师不会承担一分责任),调试PCBA,负责整机EMC 安规(电源还有电源工程师)整改,然后就是协助工厂生产。
奇葩事情开始了,前段时间公司来个人 开始做研究型项目,公司因为没有搞算法的,然后拉了3个人,我是属于其中一人,然后每个人分配了3份不同的数字信号处理方法,然后通过某知名网站的数据库开始各自仿真,我因为以前喜欢捣鼓软件(虽然离专业还是有很大距离),于是就把3个人各自的整合,后端查看了一些资料 做了个整合,然后自动出数据将数据库中的数据做了个结果文档统计,LD一看 还可以 就接着做吧,接着我就又开始负责搞硬件(由于算法计算量大,还用上了ADI的ADSP),把这一套东西都搭出来了(LD一定要搞一个产品的样子出来,板子做得奇小,调试很不方便,当时我就差砸了),接着又购入一个仿真器,测试发现偏差还是太大。于是,下一步我建议先把仿真器的数据采集下来 然后先MATLAB分析,奇葩的事情就此发生,我竟然被指派一个人去搞这个算法? 大家觉得我是不是需要另外再找一份工作?(注:本人非博士学历,个人觉得即使公司要找搞算法的,起码也是博士学历,我觉得这段时间是属于浪费我增强职业技能的时间)

出0入54汤圆

 楼主| 发表于 2014-3-6 13:18:31 | 显示全部楼层
rootxie 发表于 2014-3-6 12:45
最近真TM郁闷,摊上事情了。目前正在考虑要不要另外换工作。给大家分享下奇葩的经历!
公司是综合性质的公 ...

牛人啊。
哈哈,如果拒绝会怎么样?

出0入0汤圆

发表于 2014-3-6 13:24:55 | 显示全部楼层
lusson 发表于 2014-3-6 13:18
牛人啊。
哈哈,如果拒绝会怎么样?

牛人啥啊,主要我不怎么会啊,搞一年没成果,如今这年头,什么公司都是计件性质的,如果一年下来没成果,就是没表现,年底基本没钱!自己 难道要饿死啊,最后还得走人!
我已经拒绝了,但是领导不同意啊,答复我部门只能是我了,因为说前面那个东西基本都是我搞的 只能我继续,别人无法接手!
看来我是太嫩了,很多时候瞎表现的后果就是给你一泡屎,自己擦去吧!

出0入54汤圆

 楼主| 发表于 2014-3-6 14:15:31 | 显示全部楼层
本帖最后由 lusson 于 2014-3-6 14:19 编辑
rootxie 发表于 2014-3-6 13:24
牛人啥啊,主要我不怎么会啊,搞一年没成果,如今这年头,什么公司都是计件性质的,如果一年下来没成果, ...


说道算法,我前面那家公司做ASIC的,有专门的一个算法组,人家是硕士起步的。个个看起来是高智商的样子。

出0入0汤圆

发表于 2014-3-6 14:36:16 | 显示全部楼层
lusson 发表于 2014-3-6 14:15
说道算法,我前面那家公司做ASIC的,有专门的一个算法组,人家是硕士起步的。个个看起来是高智商的样子。 ...

是啊,我准备硬着头皮搞一搞再说
目标就是一段时间上司实在忍受不了我的无能 而裁掉我,这就是最美的结局了(我司裁人有n+2的赔偿),至少半年找工作肯定不愁没人要!

出0入54汤圆

 楼主| 发表于 2014-3-6 17:41:06 | 显示全部楼层
rootxie 发表于 2014-3-6 14:36
是啊,我准备硬着头皮搞一搞再说
目标就是一段时间上司实在忍受不了我的无能 而裁掉我,这就是最美的结局 ...


SD卡在线升级也OK了。
也是移植的坛里的,不过改了些地方。
另外需要注意的一个地方是,他在进入APP程序起始地址前先把全局中断关了。
所以在APP程序中需要把这个全局中断再打开。
使用汇编指令:
  1. __asm("CPSIE  I");
复制代码


他的跳转程序是这样的。
  1. void Jump_To_APP(void)
  2. {
  3.           void (*pUserApp)(void);
  4.                                          INT32U JumpAddress;  
  5.                                          __asm("CPSID  I");
  6.                                        
  7.                                         JumpAddress = *(volatile uint32_t*) (APP_START_ADDR+4);
  8.                                         pUserApp = (void (*)(void)) JumpAddress;
  9.                                         /* Initialize user application's Stack Pointer */
  10.                                         __set_PSP(*(volatile uint32_t*) APP_START_ADDR);
  11.                                         __set_CONTROL(0);
  12.                                         __set_MSP(*(volatile uint32_t*) APP_START_ADDR);
  13.                                         pUserApp();
  14. }
复制代码


另外需要注意时钟。
因为在BOOTLOADER程序中已经把时钟设置好了,所以在APP程序中对时钟的处理需要注意

出0入0汤圆

发表于 2014-3-14 10:26:25 | 显示全部楼层
lusson 发表于 2013-12-29 12:57
暂时先把WM8740放一放,花了一个晚上把文件扫描弄完了。
使用FATFS,支持长文件名。

请教下你的文件名是用短名寻址还是用的长文件名,另外看你的定义,是不是还得定义很大一个数组来存储短文件名?
方便共享先你的文件初始化代码吗?谢谢!

出0入54汤圆

 楼主| 发表于 2014-3-14 10:33:15 | 显示全部楼层
本帖最后由 lusson 于 2014-3-14 10:36 编辑
rootxie 发表于 2014-3-14 10:26
请教下你的文件名是用短名寻址还是用的长文件名,另外看你的定义,是不是还得定义很大一个数组来存储短文 ...


支持长文件名。我是开了一个很大的buf来存文件名以及文件列表。
扫描代码如下:
  1. FRESULT scan_files(char *path)
  2. {
  3. #define NAME_BUF_REFRESH buf_index = &list_name_buf.buf[list_name_buf.index]

  4.         DIR_LIST_STRUCT *dir_point;
  5.         char *buf_index;
  6.         FILE_FORMAT file_format;
  7.         FILE_BUF_STRUCT *file_buf_point;
  8.     FRESULT res;
  9.     FILINFO fno;
  10.     DIR dir;
  11.         int dir_num = 1;
  12.         int temp_len;
  13.     char *fn;   /* This function is assuming non-Unicode cfg. */
  14. #if _USE_LFN
  15.     char lfn[_MAX_LFN + 1];   /* Buffer to store the LFN */
  16.     fno.lfname = lfn;
  17.     fno.lfsize = sizeof(lfn);
  18. #endif
  19.         dir_point = &list_info.dir_list[0];
  20.         file_buf_point = &list_info.file_list[0];
  21.         NAME_BUF_REFRESH;                                /*refresh buf point*/
  22.         dir_point->f_dir_name = buf_index;        /*first dir*/
  23.         list_info.dir_number = 1;                        /*dir number : 1*/
  24.             list_name_buf.index = stringcpy(path, (char *)dir_point->f_dir_name, _MAX_LFN);                /*cpy dir name*/
  25.         NAME_BUF_REFRESH;
  26.        
  27.         res = f_opendir(&dir, path);                       /* Open the first directory */
  28.     if (res == FR_OK) {
  29.                
  30.         for (;;) {
  31.             res = f_readdir(&dir, &fno);                   /* Read a directory item */
  32.             if (res != FR_OK) break;                                                  /* Break on error or end of dir */
  33.             if (fno.fname[0] == '.') continue;             /* Ignore dot entry */
  34.                 if (  fno.fname[0] == 0 ){                                                       
  35.                         f_closedir(&dir);
  36.                         dir_num ++;
  37.                         if ( dir_num > list_info.dir_number){
  38.                                 break;                                                /*dir num search finish*/
  39.                         }
  40.                         dir_point ++;                                /*next dir*/
  41.                         if ( (dir_point->f_dir_name) == 0 ){
  42.                                 break;
  43.                         }else if ( *(dir_point->f_dir_name) == 0){
  44.                                 break;
  45.                         }else{
  46.                                 path = (char *)dir_point->f_dir_name;
  47.                                 res = f_opendir(&dir,path);
  48.                                 if ( res != FR_OK ){
  49.                                         break;
  50.                                 }else{
  51.                                         continue;
  52.                                 }
  53.                         }
  54.                 }
  55.             fn = *fno.lfname ? fno.lfname : fno.fname;
  56.                        
  57.             if (fno.fattrib & AM_DIR) {                    /* It is a directory */
  58.                         if ( list_info.dir_number >= DIR_NUMBER){               
  59.                                 break;                /*dir number full*/
  60.                         }
  61.                         temp_len = strlen(path)+strlen(fn)+2;
  62.                        
  63.                         if ((temp_len+list_name_buf.index)>= (LIST_NAME_BUF_LEN)){
  64.                                 break;                        /*buf full*/
  65.                         }

  66.                         if ( dir_point->son == (DIR_LIST_STRUCT *)0){                        /*first son dir*/
  67.                                 dir_point->son = &list_info.dir_list[list_info.dir_number];
  68.                         }else{
  69.                                 list_info.dir_list[list_info.dir_number].pre = dir_point->current_son;
  70.                                 dir_point->current_son->next = &list_info.dir_list[list_info.dir_number];
  71.                         }
  72.                        
  73.                         list_info.dir_list[list_info.dir_number].father = dir_point;

  74.                         dir_point->current_son = &list_info.dir_list[list_info.dir_number];
  75.                        
  76.                         temp_len = dir_string_merge(path, fn,  buf_index);
  77.                         list_info.dir_list[list_info.dir_number].f_dir_name = buf_index;
  78.                         list_name_buf.index += temp_len;
  79.                         NAME_BUF_REFRESH;
  80.                         list_info.dir_number ++;
  81.                         continue;
  82.             } else {                                       /* It is a file. */
  83.                             /*store file name*/
  84.                         file_format = file_is_music(fn);
  85.                         if ( NO_MUSIC == file_format){
  86.                                 continue;
  87.                         }
  88.                         temp_len = strlen(fn)+1;
  89.                         if( ( temp_len + list_name_buf.index) >= LIST_NAME_BUF_LEN){
  90.                                 break;
  91.                         }
  92.                         file_buf_point->f_name = buf_index;
  93.                         stringcpy(fn,file_buf_point->f_name,_MAX_LFN);
  94.                         file_buf_point->file_format = file_format;
  95.                         list_name_buf.index += temp_len;
  96.                         NAME_BUF_REFRESH;
  97.                         if ( dir_point->files_number == 0){
  98.                                 dir_point->f_first_point = file_buf_point;                        /*save first file*/
  99.                         }else{
  100.                                 dir_point->f_point->next = file_buf_point;
  101.                                 #ifdef FILE_LIST_PRE                                                        /*pre point*/
  102.                                 file_buf_point->pre = dir_point->f_point;
  103.                                 #endif
  104.                         }
  105.                         dir_point->f_point = file_buf_point;
  106.                         #ifdef FILE_LIST_DIR
  107.                         dir_point->f_point->dir = (void *)dir_point;
  108.                         #endif
  109.                         dir_point->f_point->file_index = list_info.files_number;
  110.                         if ( (dir_point->files_number >= FILES_NUMBER) ||
  111.                             (list_info.files_number >= FILES_NUMBER)){
  112.                                 break;                                /*file full*/
  113.                         }
  114.                         dir_point->files_number ++;
  115.                         list_info.files_number ++;
  116.                         file_buf_point ++;
  117.             }
  118.         }
  119.         f_closedir(&dir);
  120.     }

  121.     return res;
  122. }
复制代码


关键结构体定义:
  1. /******************file list struct***************************/
  2. typedef struct node{
  3. #ifdef FILE_LIST_PRE
  4.         struct node *pre;                        /*previous file*/
  5. #endif
  6.         char *f_name;                        /*file name*/
  7.         struct node *next;                /*next file*/
  8. #ifdef FILE_LIST_DIR
  9.         struct DIR *dir;
  10. #endif
  11.         FILE_FORMAT file_format;
  12.         unsigned int file_index;
  13. }FILE_BUF_STRUCT;


  14. typedef struct DIR{
  15.         char *f_dir_name;                                                                /*dir name*/
  16.         FILE_BUF_STRUCT  *f_point;                                                /*current file point*/
  17.         FILE_BUF_STRUCT *f_first_point;                                        /*fist file point*/
  18.         unsigned short files_number;                                                /*current dir's file number*/
  19.         struct DIR *father;                                                                /*father dir*/
  20.         struct DIR *son;                                                                        /*son dir*/
  21.         struct DIR *current_son;                                                                /*current dir*/
  22.         struct DIR *pre;                                                                        /*previous dir*/
  23.         struct DIR *next;                                                                        /*next dir*/
  24. }DIR_LIST_STRUCT;


  25. typedef struct{
  26.         unsigned long file_index;
  27.         unsigned long dir_index;
  28.         unsigned long dir_number;
  29.         unsigned long files_number;
  30.         DIR_LIST_STRUCT dir_list[DIR_NUMBER];               
  31.         FILE_BUF_STRUCT file_list[FILES_NUMBER];
  32. }LIST_STRUCT;
复制代码



思路就是:
读文件夹,遇到是文件的话判断是否支持的格式,支持就存起来,同时DIR指向当前的DIR
如果是DIR也存起来,父DIR指向当前DIR。
读完之后再依次读SON DIR,依次循环。

其中DIR存的是绝对路径,这个我还在想要不要改一下。
FILE是存的文件名。

DIR和FILE的名字专门开了个数组来存,使用动态的方式。即FILE结构体内的name就是一个指针,指向名字buf

暂时没去整理。可能后面会改进下,这个太占RAM了。

出0入0汤圆

发表于 2014-3-14 10:55:17 | 显示全部楼层
本帖最后由 rootxie 于 2014-3-14 10:56 编辑
lusson 发表于 2014-3-14 10:33
支持长文件名。我是开了一个很大的buf来存文件名以及文件列表。
扫描代码如下:

谢谢你的回复!

我粗粗一算 1000个文件,这个东西都放在RAM里 实在太耗内存了,因为还有mp3解码(helix 30K),GUI(20K不知道够不够,刷局部图片)
最好只定义一个中转的目录,文件夹,文件名,其余的在刚开始扫描完后 存入在Flash里,只记录位置即可,这样 可以节省很多内存,不过,不知道切歌的时候会不会出现卡顿现象!
发现这个东西做好的话, 需要有些底层软件基础积累(外设SDIO,LCD,USB,文件系统,GUI,mp3解码,FLAC解码),基本上这个完全搞定后,可以从事底层嵌入式工作了(还差一个网络)!

出0入54汤圆

 楼主| 发表于 2014-3-14 11:10:01 | 显示全部楼层
rootxie 发表于 2014-3-14 10:55
谢谢你的回复!

我粗粗一算 1000个文件,这个东西都放在RAM里 实在太耗内存了,因为还有mp3解码(helix 3 ...

其实很多网上都能搜得到啊。所以关系要有搜索能力

我也在想是不是存在flash里面,把省下来的空间使用,速度肯定不是问题,因为这些名字只是在打开文件时用一下,完全可以存在flash里面。就是每次开机要擦除flash一次,所以其实也可以考虑存在SD卡里。
STM32F4有192K可用,目前我还没加LCD呢。我估计勉强可以整下来。
另外 MP3解码后面再看,USB也不整了。

出0入0汤圆

发表于 2014-3-21 11:53:56 | 显示全部楼层
楼主,快来更新。

出0入54汤圆

 楼主| 发表于 2014-3-21 12:10:20 | 显示全部楼层
TimCheng 发表于 2014-3-21 11:53
楼主,快来更新。

更新什么啊?
最近没怎么弄了啊,

在研究CPLD的在线更新。

出0入54汤圆

 楼主| 发表于 2014-4-2 11:56:48 | 显示全部楼层
之前一直想弄SPDIF,昨天研究了下,在我原来CPLD程序上改了改,完美实现。
后面分析了下,其实用I2S也能实现,使用2倍速32bit模式就可以。
比如44.1k采样率,设置为88.2的话然后再组数据再发送应该就行。
传2个SPDIF资料上来。




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-4-30 15:42:11 | 显示全部楼层
谢谢不错

出0入0汤圆

发表于 2014-5-3 22:30:28 | 显示全部楼层
支持樓主了~期待开源

出0入0汤圆

发表于 2014-5-4 07:42:18 来自手机 | 显示全部楼层
期待套件 。。。

出20入0汤圆

发表于 2014-5-4 17:21:56 | 显示全部楼层
看楼主发行套件,过下瘾

出0入0汤圆

发表于 2014-5-22 13:28:33 | 显示全部楼层
撸兄,弄个套件玩玩~~

出0入54汤圆

 楼主| 发表于 2014-5-22 15:26:03 | 显示全部楼层
fsclub 发表于 2014-5-22 13:28
撸兄,弄个套件玩玩~~

没那么多精力,等后面闲一点再弄吧。目前项目正忙的时候。
其实也可以考虑买市面上现成的,1000左右有国产的也还可以。

出0入0汤圆

发表于 2014-5-26 10:32:02 | 显示全部楼层
lusson 发表于 2013-12-23 09:25
IC的话在淘宝上找了一家,都能单个买,价格还算公道,唯一没有的器件是电感。
JLC商城的东西虽然便宜,可是 ...

您好!我也想搞一个无损播放器,你的这个淘宝的地址可以PM给我吗?谢谢!

出0入54汤圆

 楼主| 发表于 2014-6-16 09:18:14 | 显示全部楼层
chhaich 发表于 2014-5-26 10:32
您好!我也想搞一个无损播放器,你的这个淘宝的地址可以PM给我吗?谢谢! ...

不好意思,现在才看到。马上PM你。

出0入54汤圆

 楼主| 发表于 2014-6-16 09:26:02 | 显示全部楼层
本帖最后由 lusson 于 2014-6-16 09:27 编辑

把MP3解码部分上传上来,使用Libmad,移植的时候主要是按照这个文档来修改的
源代码打包上来:
注意只是MP3解码部分,整个工程就不传上来了。

我整个运行框架是基于状态机。
先调用init,然后再循环调用task,直到解码结束调用stop。
文件系统是已经能用的FATFS,解码后数据存在buf0和buf1中循环使用。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-7-4 21:20:58 | 显示全部楼层
lusson 发表于 2014-1-15 10:03
淘宝上有卖,20多块钱一片。如果需要的话可以发链接给你,我的WM8740什么的全在他那买的。8740是11块多一 ...

麻烦给个购买链接,不方便的话站内信,多谢了!

出0入0汤圆

发表于 2014-7-10 14:08:25 | 显示全部楼层
LZ有没有兴趣出套件什么的?或者PCB也可以啊,方便我们技术不好的仿制

出0入0汤圆

发表于 2014-7-12 18:51:02 | 显示全部楼层
定额,必须的

出0入0汤圆

发表于 2017-1-23 13:44:39 | 显示全部楼层
楼主的这个东西 结尾没有?有没有最后更新的图啊,准备搞一个玩玩

出0入0汤圆

发表于 2017-1-23 14:34:14 | 显示全部楼层
rootxie 发表于 2017-1-23 13:44
楼主的这个东西 结尾没有?有没有最后更新的图啊,准备搞一个玩玩

我是对lz的cpld部分很感兴趣,没搞过fpga,对这玩意好陌生,看了些资料还是不知道咋整

出0入0汤圆

发表于 2017-1-23 14:55:40 | 显示全部楼层
mubei 发表于 2017-1-23 14:34
我是对lz的cpld部分很感兴趣,没搞过fpga,对这玩意好陌生,看了些资料还是不知道咋整 ...

可能这么搞,幻想加想象

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2017-1-23 15:55:33 | 显示全部楼层
rootxie 发表于 2017-1-23 14:55
可能这么搞,幻想加想象

我觉得是这样的,CPLD作为I2S的master,mcu和dac作为slave,mcu通过spi通讯控制cpld产生不同频率的I2S信号
只是不理解怎么通过spi通讯控制cpld选择双晶振产生不同频率的I2S的信号

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

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

本版积分规则

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

GMT+8, 2024-4-20 13:47

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

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