搜索
bottom↓
回复: 89

非官方之STM32 Radio播放Flac

[复制链接]

出0入0汤圆

发表于 2011-1-24 21:57:52 | 显示全部楼层 |阅读模式
花时间"移植"了一下,得益于POSIX,过程比较顺利,特别多谢314forever提供songbank的源码,99%是复制里面的代码的.
关于Flac的具体文件说明大家可以从这里得知:http://flac.sourceforge.net/format.html
说说软解flac,比软解mp3轻松.flac_init后就可以得到音频信息以及第一个audio frame位置
接着就可以decode_frame了,由flac_decode_frame函数实现,flac_decode_frame需要两个"临时"buffer(decoded0和decoded1),大小都为[4 * MAX_BLOCKSIZE].
两个"临时"PCMbuffer可产生送CODEC的PCM数据,这些在RTT中用内存池存放.

播放流程就不啰嗦了,可以参考examples下wav例子的readme.txt.
点击此处下载 ourdev_613208NEHXLK.txt(文件大小:2K) (原文件名:README.txt)

鉴于能力以及ram大小,现在只支持foobar2000 level2及以下压缩,即max_blocksize=min_blocksize=1152情况,有进展的话立刻补上.

资源使用状况:
Program Size: Code=82644 RO-data=6412 RW-data=528 ZI-data=39160  
裸奔会好些

有Radio的都帮忙测试下啊,下面是工程文件:
点击此处下载 ourdev_613209ZG49MV.rar(文件大小:2.46M) (原文件名:flac example.rar)

忘记说用法了...
finish下输入 flac("/xxx.flac")  即可 有图有真相

(原文件名:flac.jpg)

出0入0汤圆

发表于 2011-1-24 23:03:22 | 显示全部楼层
不错。让STM32也飞了一把

出0入0汤圆

发表于 2011-1-25 07:03:44 | 显示全部楼层
不错不错!以后STM32Radio花样会越来越多了

出0入0汤圆

发表于 2011-1-25 09:35:05 | 显示全部楼层
FLAC的音质很不错,无损音频压缩编码,好图好真相,谢谢分享^_^

出0入0汤圆

发表于 2011-1-25 09:40:28 | 显示全部楼层
mark!

出0入0汤圆

发表于 2011-2-11 22:54:32 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-12 08:37:41 | 显示全部楼层
FLAC

出0入0汤圆

发表于 2011-2-12 09:20:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-12 10:14:24 | 显示全部楼层
学习了·~~

出0入0汤圆

发表于 2011-2-13 14:25:19 | 显示全部楼层
近期的学习内容!

出0入0汤圆

发表于 2011-2-14 14:15:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-14 14:38:07 | 显示全部楼层
学习学习!

出0入0汤圆

发表于 2011-2-17 00:25:04 | 显示全部楼层
不错,好东西

出0入0汤圆

发表于 2011-4-16 15:45:51 | 显示全部楼层
用了个CS8406作为master, STM32作为slave, 改写I2S为:I2S_DataFormat_16bextended, 接上同轴到解码器, 音质效果还行.

出0入0汤圆

 楼主| 发表于 2011-4-23 21:47:04 | 显示全部楼层
现在终于支持全级别了

新增加文件Ext_flac.c,原文件flac.c默认不加入工程
支持level0-level8压缩级别,注意确保外部Ram至少有16*1024可用空间
更改使用内存池的方法为使用信号量.
......
对于一些及其特殊的情况例如Blocksize>4608或者Framesize>15413还是有心无力的
算是将64K内部RAM压干压尽了,对于这样支持更高level是否有意义就见仁见智了,
这里也只能保证PCM不断流(或者说断流时间极短),虽然STM32 I2S不争气,但楼上所说将其作为Slave还是可以听听的,除了此处下载外,大家也可以svn

资源使用情况,不包括filebuffer的16*1024
Program Size: Code=82888 RO-data=6412 RW-data=524 ZI-data=61652  


点击此处下载 ourdev_633063TI5INS.rar(文件大小:2.46M) (原文件名:full_flac.rar)

(原文件名:2011-04-23_214211.jpg)

出0入0汤圆

发表于 2011-4-24 23:01:05 | 显示全部楼层
强人,mark

出0入0汤圆

发表于 2011-4-25 02:00:22 | 显示全部楼层
M

出0入0汤圆

发表于 2011-4-25 10:07:02 | 显示全部楼层
回复【14楼】zzm24
现在终于支持全级别了
新增加文件ext_flac.c,原文件flac.c默认不加入工程
支持level0-level8压缩级别,注意确保外部ram至少有16*1024可用空间
更改使用内存池的方法为使用信号量.
......
对于一些及其特殊的情况例如blocksize>4608或者framesize>15413还是有心无力的
算是将64k内部ram压干压尽了,对于这样支持更高level是否有意义就见仁见智了,
这里也只能保证pcm不断流(或者说断流时间极短),虽然stm32 i2s不争气,但楼上所说将其作为slave还是可以听听的,除了此处下载外,大家也可以svn
资源使用情况,不包括filebuffer的16*1024
program size: code=82888 ro-data=6412 rw-data=524 zi-data=61652   
点击......
-----------------------------------------------------------------------

你试试把读文件缓冲和解码缓冲都放到外部RAM, 再做一个PCM 乒乓双缓冲轮流装载到I2S, 理论上可以做到不断流, 也可以支持高Level.

还有一点, 一般支持到BlockSize=4608已经可以了.

出0入0汤圆

 楼主| 发表于 2011-4-25 13:23:42 | 显示全部楼层
前置知识:对于解Flac(APE也一样),主要有3大"内存杀手",一是文件buffer,一是临时Buffer就是这里的decoded(产生PCM),再就是PCM Buffer了

这里觉得有必要说明一下为什么既然用到了外部RAM,为何不把decoded和PCM Buffer都放外部RAM.原因主要有两个:

1.为移植到下级MCU如 STM32F10xxet 提供了可能
2.外部RAM慢!至少将decoded放外部RAM至少我觉得机会是微乎其微的,因为flac_decode_frame用到decoded,生成PCM用到decoded,对于FSMC还要分频的外部RAM力不从心.要不然 liuweiele 就不会发出STM32的FSMC连44B0的都不如的感慨.这情况也发生在软解mp3上,之前ffxz和aozima也验证过将PCM Buffer放到外部RAM会照成声音不连续.
3.综上要解level8,在不得不用外部RAM的情况下,将其中一个不太经常用到的"内存杀手"--文件buffer 放到外部RAM是个不错的折中方法.
还有一点, 14楼的BlockSize就是4608.
这次欢迎拍砖,^_^.

出0入0汤圆

发表于 2011-4-25 14:30:27 | 显示全部楼层
回复【18楼】zzm24
前置知识:对于解flac(ape也一样),主要有3大"内存杀手",一是文件buffer,一是临时buffer就是这里的decoded(产生pcm),再就是pcm buffer了
这里觉得有必要说明一下为什么既然用到了外部ram,为何不把decoded和pcm buffer都放外部ram.原因主要有两个:
1.为移植到下级mcu如 stm32f10xxet 提供了可能
2.外部ram慢!至少将decoded放外部ram至少我觉得机会是微乎其微的,因为flac_decode_frame用到decoded,生成pcm用到decoded,对于fsmc还要分频的外部ram力不从心.要不然 liuweiele 就不会发出stm32的fsmc连44b0的都不如的感慨.这情况也发生在软解mp3上,之前ffxz和aozima也验证过将pcm buffer放到外部ram会照成声音不连续.
3.综上要解......
-----------------------------------------------------------------------

我在想, 设置PCM乒乓缓冲PCM_A和PCM_B在内部RAM, 读文件缓冲FileBuf和解码缓冲decoded都放到外部RAM.
解码后得到缓冲decoded, 然后把解码数据拷贝到缓冲PCM_A, 此时PCM_B正在送音频数据到I2S;
反过来, 把解码数据到拷贝到缓冲PCM_B, 此时PCM_A此时作用就是送数据到I2S.

这个方式, 能不能要做到I2S不断流(保证声音不会不连续), 这也就是取决于读文件时间+解码时间+外部RAM的decoded缓冲拷贝到内部RAM的PCM缓冲时间 < 送数据到I2S时间. 按道理外部RAM拷贝到内部RAM, 时间应该不多吧...(如果用DMA传送的话)

我刚开始正在用STM32才一个星期, 还不了解STM32的一些特性, 以上只是与你交流一下, 如果能做到, 你可以试试看.

出0入0汤圆

 楼主| 发表于 2011-4-25 15:14:47 | 显示全部楼层
我的想法就是:将解码缓冲decoded放到外部RAM是痛苦的过程(就算可以流畅播放),虽然省下了不少内部RAM,但却占用了CPU宝贵资源.
因为:
1.flac_decode_frame用到decoded,但是cpu填充decoded慢,所以相比decoded放内部慢几倍,这里CPU大部分时间花在等待外部RAM就绪去了
2.decoded->pcm buffer也慢,结果同上
所以应该可以考虑将pcm buffer放到外部RAM.但是也会有问题.因为这样对于播放level2-这些不需占用太多CPU资源级别的可能可以做到不断流.但是对于level8呢?解mp3呢?解APE呢?
当然这里也不是白白让内部RAM牺牲,这里将pcm buffer也当成了decoded.
cheungman兄有兴趣放外部RAM我也很想知道结果,因为我测试时老是fault.

出0入0汤圆

发表于 2011-4-25 15:55:04 | 显示全部楼层
回复【20楼】zzm24
我的想法就是:将解码缓冲decoded放到外部ram是痛苦的过程(就算可以流畅播放),虽然省下了不少内部ram,但却占用了cpu宝贵资源.
因为:
1.flac_decode_frame用到decoded,但是cpu填充decoded慢,所以相比decoded放内部慢几倍,这里cpu大部分时间花在等待外部ram就绪去了
2.decoded-&gt;pcm buffer也慢,结果同上
所以应该可以考虑将pcm buffer放到外部ram.但是也会有问题.因为这样对于播放level2-这些不需占用太多cpu资源级别的可能可以做到不断流.但是对于level8呢?解mp3呢?解ape呢?
当然这里也不是白白让内部ram牺牲,这里将pcm buffer也当成了decoded.
cheungman兄有兴趣放外部ram我也很想知道结果,因为我测试时老是fault.
-----------------------------------------------------------------------

sigh~~~, 照你这么说, STM32的外部RAM接口原来不能完全当成或等同CPU内部RAM来使用, 速度这么慢啊...这种接口也太囧了吧.

出0入0汤圆

 楼主| 发表于 2011-4-25 16:56:49 | 显示全部楼层
回复【21楼】cheungman  
-----------------------------------------------------------------------
不能这么绝对,fsmc接DM9000或者接LCD不是很好么?

出0入0汤圆

发表于 2011-4-25 17:18:46 | 显示全部楼层
回复【21楼】cheungman  
-----------------------------------------------------------------------
只是灵活,速度上确实接外部RAM不咋地,等效于内部的3到5分频吧,具体多少没仔细研究。
不然我的播放器早就用外部RAM支持全LEVEL的FLAC了.
同意zzm24兄台的意见,接某些速度要求不那么高的器件还是很好的。(我只接过RAM和LCD,不过不知道什么原因,我的板子上的外部RAM不好使了.)

出0入0汤圆

发表于 2011-5-21 17:51:54 | 显示全部楼层
make

出0入0汤圆

发表于 2011-5-21 17:57:12 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-5-22 13:42:21 | 显示全部楼层
这个一定要顶~

出0入0汤圆

发表于 2011-6-3 17:22:09 | 显示全部楼层
不得不顶!!

出0入0汤圆

发表于 2011-6-3 17:49:45 | 显示全部楼层
zzm在STM32Radio上加了很多东西,赞一个!

另外还有个以太网转CAN(UDP模式,协议协议兼容zlg的转换器),到时也加上去。

出0入0汤圆

发表于 2011-6-28 21:08:36 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-1 09:28:52 | 显示全部楼层
STM32F207的网络收音机板子拿到了,会在0.4.0 beta2版本发布后开始调试软件。

这个版本的网络收音机包括:88w8686 wifi的接口(模块与主板是分离的,主板上留接口),也会弄个外壳;软件上,会把0.4.0分支中主要的动态模块功能放到Cortex-M3上运行。

可惜和zzm沟通太晚了,否则过来做STM32F2xx网络收音机暑假实习多好:-P 是否还有其他同学有这个意向?

出0入0汤圆

发表于 2011-7-7 09:02:29 | 显示全部楼层
长见识了。

出0入0汤圆

发表于 2011-7-23 13:38:46 | 显示全部楼层
这个得关注一下

出0入0汤圆

发表于 2011-8-17 05:06:23 | 显示全部楼层
flac_decode_frame()解后的资料是否能直接输出到 DAC?

出0入0汤圆

 楼主| 发表于 2011-8-17 10:01:09 | 显示全部楼层
flac_decode_frame()解后存decode0 decode1,分别是左右声道,根据音源或自己需要合成16bit或者24bit等来送给CODEC

出0入0汤圆

发表于 2011-8-18 02:25:13 | 显示全部楼层
回复【34楼】zzm24
flac_decode_frame()解后存decode0 decode1,分别是左右声道,根据音源或自己需要合成16bit或者24bit等来送给codec
-----------------------------------------------------------------------

谢谢说明,如果decode_subframe(FLACContext *s, int channel, int32_t* decoded) 的 decoded 能改成 16bit就能省下很多 RAM空间.

官方的 flac source code 不是很好,FLAC音频格式被发现14个安全漏洞!
http://safe.it168.com/t/2007-11-21/200711212349078.shtml

出0入0汤圆

发表于 2011-8-18 02:49:45 | 显示全部楼层
一推牛人。

出0入0汤圆

发表于 2011-8-18 09:23:16 | 显示全部楼层
回复【35楼】nono2000
回复【34楼】zzm24  
flac_decode_frame()解后存decode0 decode1,分别是左右声道,根据音源或自己需要合成16bit或者24bit等来送给codec
-----------------------------------------------------------------------
谢谢说明,如果decode_subframe(flaccontext *s, int channel, int32_t* decoded) 的 decoded 能改成 16bit就能省下很多 ram空间.
官方的 flac source code 不是很好,flac音频格式被发现14个安全漏洞!
http://safe.it168.com/t/2007-11-21/200711212349078.shtml


-----------------------------------------------------------------------

如果你解码16bit音频, 直接用int16_t* decoded缓冲即可!

出0入0汤圆

 楼主| 发表于 2011-8-18 14:15:27 | 显示全部楼层
回复【35楼】nono2000
回复【34楼】zzm24  
flac_decode_frame()解后存decode0 decode1,分别是左右声道,根据音源或自己需要合成16bit或者24bit等来送给codec
-----------------------------------------------------------------------
谢谢说明,如果decode_subframe(flaccontext *s, int channel, int32_t* decoded) 的 decoded 能改成 16bit就能省下很多 ram空间.
官方的 flac source code 不是很好,flac音频格式被发现14个安全漏洞!
http://safe.it168.com/t/2007-11-21/200711212349078.shtml


-----------------------------------------------------------------------

漏洞嘛...肯定会有的,这里主要向Rockbox看齐,Rockbox有啥bug这就有啥bug,当然与libFLAC相比,Rockbox针对嵌入式的改了不少.毕竟不是PC机,当然不排除有人拿一个特制的flac去hacked一台随身播放器.
PS:不知Rockchip的flac是咋d,应该是自己写的吧?

出0入0汤圆

发表于 2011-8-18 15:40:40 | 显示全部楼层
回复【37楼】cheungman  
如果你解码16bit音频, 直接用int16_t* decoded缓冲即可!
-----------------------------------------------------------------------
真的吗?
decode_subframe()能这样改吗?
RT_flac_decode_frame()虽然是16bit,但是实际也要先解码成 32bit后,再转16bit.

出0入0汤圆

发表于 2011-8-18 15:53:48 | 显示全部楼层
回复【38楼】zzm24
回复【35楼】nono2000  
回复【34楼】zzm24   
flac_decode_frame()解后存decode0 decode1,分别是左右声道,根据音源或自己需要合成16bit或者24bit等来送给codec  
-----------------------------------------------------------------------  
漏洞嘛...肯定会有的,这里主要向Rockbox看齐,Rockbox有啥bug这就有啥bug,当然与libFLAC相比,Rockbox针对嵌入式的改了不少.毕竟不是PC机,当然不排除有人拿一个特制的flac去hacked一台随身播放器.
PS:不知Rockchip的flac是咋d,应该是自己写的吧?
-----------------------------------------------------------------------

呵呵, 如果让我猜, 我猜是libflac的源码, 可惜rockbox封装成.a库, 我看了一下.a的数据, 跟libflac的函数名很像.


回复【39楼】j-link
-----------------------------------------------------------------------
真的吗?
decode_subframe()能这样改吗?
rt_flac_decode_frame()虽然是16bit,但是实际也要先解码成 32bit后,再转16bit.
-----------------------------------------------------------------------
当然可以, decoded解码缓冲的数据是int32_t的, 4byte, 对应采样位数, 如果16bit音频流, 解码后得到是高16位为0, 低16位有效的PCM数据, 既然高16位无效, 当然可以用(int16_t* )decoded了.

出0入0汤圆

发表于 2011-8-18 16:18:57 | 显示全部楼层
回复【40楼】cheungman  
-----------------------------------------------------------------------  
当然可以, decoded解码缓冲的数据是int32_t的, 4byte, 对应采样位数, 如果16bit音频流, 解码后得到是高16位为0, 低16位有效的PCM数据, 既然高16位无效, 当然可以用(int16_t* )decoded了.
-----------------------------------------------------------------------
好像不行!!!!
虽然设定 s->sbp=16 bit,但是解码依然是 32bit.
flac_decode_frame()都是以 32bit 计算解码的,不是那么容易改.

出0入0汤圆

发表于 2011-8-18 21:36:05 | 显示全部楼层
回复【37楼】cheungman
如果你解码16bit音频, 直接用int16_t* decoded缓冲即可!  
-----------------------------------------------------------------------  
谢谢说明,如果decode_subframe(flaccontext *s, int channel, int32_t* decoded) 的 decoded 能改成 16bit就能省下很多 ram空间.  
官方的 flac source code 不是很好,flac音频格式被发现14个安全漏洞!  
http://safe.it168.com/t/2007-11-21/200711212349078.shtml  ......
-----------------------------------------------------------------------

如果能,大家就不用搞的那么累了。

范例1.zzm24
//向mempoll申请空间,如果申请不成功则一直在此等待.
//这里申请的内存用来放置真正送CODEC的PCM数据
decoded = rt_mp_alloc(&_mp, RT_WAITING_FOREVER);

if (flac_decode_frame(&fc,filebuf,bytesleft,decoded) < 0)          
   {
    rt_kprintf("DECODE ERROR, ABORTING\n");
    break;
    }

范例2.sharpufo
//-调用空间体-----------------------------------------------------------------
flac_read_buf=malloc(FLAC_MAX_FRAMESIZE);                   
if(flac_read_buf==NULL ){f_close(&file);return 3;}          

decoded_buf=malloc(2*FLAC_MAX_BLOCKSIZE*sizeof(int));  

if(decoded_buf==NULL )
        {free(flac_read_buf);f_close(&file);return 3;}

出0入0汤圆

发表于 2011-8-18 21:56:45 | 显示全部楼层
如果能,大家就不用搞的那么累了。
-----------------------------------------------------------------------
如果不能, 那么你们的问题, 相信我上边已经写得够清楚了.

出0入0汤圆

发表于 2011-8-18 22:04:32 | 显示全部楼层
回复【43楼】cheungman  
如果能,大家就不用搞的那么累了。
-----------------------------------------------------------------------
如果不能, 那么你们的问题, 相信我上边已经写得够清楚了.

-----------------------------------------------------------------------
好吧,你能提供 flac_decode_frame(FLACContext *s, int16_t* decoded) 范例吗?
谢谢!!!!

出0入0汤圆

发表于 2011-8-19 03:57:00 | 显示全部楼层
回复【40楼】cheungman
  
当然可以, decoded解码缓冲的数据是int32_t的, 4byte, 对应采样位数, 如果16bit音频流, 解码后得到是高16位为0, 低16位有效的PCM数据, 既然高16位无效, 当然可以用(int16_t* )decoded了
-----------------------------------------------------------------------
16bit音频流, 解码后得到是高16位为0--->你自己运行一下就知道了喔,Flac解码没那么简单,,,呵呵,。

出0入0汤圆

发表于 2011-8-19 10:09:02 | 显示全部楼层
回复【44楼】j-link
回复【45楼】nono2000
16bit音频流, 解码后得到是高16位为0---&gt;你自己运行一下就知道了喔,flac解码没那么简单,,,呵呵,。

-----------------------------------------------------------------------

请两位把flac源码中把对应的变量更改为(int16_t *), 包括decoded , decoded0, decoded1等变量. 我自己这么改过并验证过, 不会随便说几句话来显摆.

出0入0汤圆

发表于 2011-8-20 10:58:24 | 显示全部楼层
回复【34楼】zzm24
flac_decode_frame()解后存decode0 decode1,分别是左右声道,根据音源或自己需要合成16bit或者24bit等来送给codec
-----------------------------------------------------------------------
zzm24 版主,我读取 Flac 资料资讯
   
   Blocksize: 1152 .. 1152
   Framesize: 18 .. 4344
   Samplerate: 44100
   Channels: 2
   Bits per sample: 16
   Metadata length: 8282
   Total Samples: 14141423
   Duration: 320000 ms
   Bitrate: 1043 kbps

程序都当在这??
static int decode_frame(FLACContext *s){
        int blocksize_code, sample_rate_code, sample_size_code, assignment, crc8;
        int decorrelation, bps, blocksize, samplerate;
        int res;
   
    blocksize_code = get_bits(&s->gb, 4);

    sample_rate_code = get_bits(&s->gb, 4);
   
    assignment = get_bits(&s->gb, 4); /* channel assignment */
    if (assignment < 8 && s->channels == assignment+1)
        decorrelation = INDEPENDENT;
    else if (assignment >=8 && assignment < 11 && s->channels == 2)
        decorrelation = LEFT_SIDE + assignment - 8;
    else
    {
        return -13;  <===============都错误??
    }

出0入0汤圆

 楼主| 发表于 2011-8-20 11:33:28 | 显示全部楼层
回复【47楼】<FONT style="BACKGROUND-COLOR: #ffd700">nono2000</FONT>
-----------------------------------------------------------------------

初始化成功了吗?还是文件操作接口没移植好?因为RTT是基于POSIX的,如果用FATFS得改文件操作函数,主要是open,read,lseek.请确保移植成功.单独来说,函数int decode_frame(FLACContext *s);是没问题的.还有我还没做上版主呢.这里我只是开了个头,何必一定必要跟着走?Rockbox赤裸裸地躺在那里,不管你上不上,反正我是上了.

出0入0汤圆

发表于 2011-8-20 12:03:00 | 显示全部楼层
回复【48楼】zzm24
回复【47楼】&lt;font style="background-color: #ffd700"&gt;nono2000&lt;/font&gt;  
-----------------------------------------------------------------------
初始化成功了吗?还是文件操作接口没移植好?因为rtt是基于posix的,如果用fatfs得改文件操作函数,主要是open,read,lseek.请确保移植成功.单独来说,函数int decode_frame(flaccontext *s);是没问题的.还有我还没做上版主呢.这里我只是开了个头,何必一定必要跟着走?rockbox赤裸裸地躺在那里,不管你上不上,反正我是上了.
-----------------------------------------------------------------------
既然可以读出flac文件头讯息, 基本可以确认文件系统没问题了. 可以从描述现象来看, 是在读frame header时错了, 先跟踪到
blocksize_code = get_bits(&s->gb, 4);
sample_rate_code = get_bits(&s->gb, 4);
看blocksize_code和sample_rate_code值是否正确, 如果错, 有如下几种可能:
1.偏移metadata地址错
2.注意大小端模式
3.文件系统仍有问题

出0入0汤圆

发表于 2011-8-21 00:10:04 | 显示全部楼层
回复【49楼】cheungman
-----------------------------------------------------------------------  
初始化成功了吗?还是文件操作接口没移植好?因为rtt是基于posix的,如果用fatfs得改文件操作函数,主要是open,read,lseek.请确保移植成功.单独来说,函数int decode_frame(flaccontext *s);是没问题的.还有我还没做上版主呢.这里我只是开了个头,何必一定必要跟着走?rockbox赤裸裸地躺在那里,不管你上不上,反正我是上了.
-----------------------------------------------------------------------
解第1声道正常,解第二声道就return -9;
程序是:flacdecder.c

   s->blocksize    = blocksize;
    s->samplerate   = samplerate;
    s->bps          = bps;
    s->decorrelation= decorrelation;
    /* subframes */
    if ((res = decode_subframe(s, 0, decoded)) < 0)-------------->OK
        {
        return res-100;
        }

    if (s->channels == 2)
        {
            if ((res = decode_subframe(s, 1, decoded + 1)) < 0)
                  return res-200;-------------->Error
    }



int decode_subframe(FLACContext *s, int channel, int32_t* decoded)
{
    int type, wasted = 0;
    int i, tmp;
        int32_t* output;   
    s->curr_bps = s->bps;
    if(channel == 0)
        {
        if(s->decorrelation == RIGHT_SIDE)          // RIGHT_SIDE=2
            s->curr_bps++;
         }
        else
        {
        if(s->decorrelation == LEFT_SIDE || s->decorrelation == MID_SIDE)       
           s->curr_bps++;-->第2声道会将 s->curr_bps+1 很奇怪?   
         }

    if (get_bits1(&s->gb))
    {
//        rprintf("invalid subframe padding\n
        return -9;");<<<<<<<--------------Error
    }

出0入0汤圆

发表于 2011-8-21 00:17:55 | 显示全部楼层
强势围观

出0入0汤圆

发表于 2011-8-21 23:48:50 | 显示全部楼层
我觉得 FLAC (Alex Beregszaszi) 解码漏洞太多,只要FLAC档案有错误,将会导致资料乱丢.
每个 frame 都还要重复计算 blocksize 及 sample_rate_code...如果计算错误,将会很惨...

所以之前使用flac_init()判读 blocksize sample_rate framesize 都是没用的!!!!!

这还是我看过最烂的解码程序......>.<.....helixcommunity MP3都比他好千万倍!!!!

还是找其他专业一点的 FLAC DECODE

出0入0汤圆

发表于 2011-8-24 09:02:13 | 显示全部楼层
最后追踪发现是get_ur_golomb_jpegls 解码错误导致,这样为什么我也不知道??
运行后导致 gb->index 资料错误?
/**
* read signed golomb rice code (flac).
*/
static __inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, int esc_len){
    int v= get_ur_golomb_jpegls(gb, k, limit, esc_len);
    return (v>>1) ^ -(v&1);
}

/**
* read unsigned golomb rice code (jpegls).
*/
static __inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int esc_len){
    unsigned int buf;
    int log;
   
    OPEN_READER(re, gb);
    UPDATE_CACHE(re, gb);
    buf=GET_CACHE(re, gb);

    log= av_log2(buf);
   
    if(log > 31-11){
        buf >>= log - k;
        buf += (30-log)<<k;
        LAST_SKIP_BITS(re, gb, 32 + k - log);
        CLOSE_READER(re, gb);
   
        return buf;
    }else{
        int i;
        for(i=0; SHOW_UBITS(re, gb, 1) == 0; i++){
            LAST_SKIP_BITS(re, gb, 1);
            UPDATE_CACHE(re, gb);
        }
        SKIP_BITS(re, gb, 1);

        if(i < limit - 1){
            if(k){
                buf = SHOW_UBITS(re, gb, k);
                LAST_SKIP_BITS(re, gb, k);
            }else{
                buf=0;
            }

            CLOSE_READER(re, gb);
            return buf + (i<<k);
        }else if(i == limit - 1){
            buf = SHOW_UBITS(re, gb, esc_len);
            LAST_SKIP_BITS(re, gb, esc_len);
            CLOSE_READER(re, gb);
   
            return buf + 1;
        }else
            return -1;
    }
}

出0入0汤圆

发表于 2011-8-24 09:08:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-24 09:11:40 | 显示全部楼层
回复【53楼】nono2000
最后追踪发现是get_ur_golomb_jpegls 解码错误导致,这样为什么我也不知道??
运行后导致 gb-&gt;index 资料错误?
-----------------------------------------------------------------------
把if(log > 31-11)改成
if(log - k >= 32-MIN_CACHE_BITS+(MIN_CACHE_BITS==32) && 32-log < limit)

出0入0汤圆

发表于 2011-8-24 09:20:40 | 显示全部楼层
回复【52楼】d-link
我觉得 flac (alex beregszaszi) 解码漏洞太多,只要flac档案有错误,将会导致资料乱丢.
每个 frame 都还要重复计算 blocksize 及 sample_rate_code...如果计算错误,将会很惨...
所以之前使用flac_init()判读 blocksize sample_rate framesize 都是没用的!!!!!
这还是我看过最烂的解码程序......&gt;.&lt;.....helixcommunity mp3都比他好千万倍!!!!
还是找其他专业一点的 flac decode

-----------------------------------------------------------------------

说的有道理, 这也是因为flac的不固定帧长特性导致的

出0入0汤圆

发表于 2011-8-24 09:26:51 | 显示全部楼层
回复【55楼】cheungman
把if(log > 31-11)改成
if(log - k >= 32-min_cache_bits+(min_cache_bits==32) && 32-log < limit)

-----------------------------------------------------------------------
改过测试也一样?"if(log - k >= 32-min_cache_bits+(min_cache_bits==32) && 32-log < limit)"
RT_FLAC 测试if(log > 31-11)正常,为什么我的运行会错误?导致gb->index 错误?

我比对RT_FLAC全部参数及我的载入资料都正确,但是我的确解码错误?

出0入0汤圆

发表于 2011-8-24 09:34:09 | 显示全部楼层
回复【56楼】cheungman
回复【52楼】d-link  
我觉得 flac (alex beregszaszi) 解码漏洞太多,只要flac档案有错误,将会导致资料乱丢.  
每个 frame 都还要重复计算 blocksize 及 sample_rate_code...如果计算错误,将会很惨...  
所以之前使用flac_init()判读 blocksize sample_rate framesize 都是没用的!!!!!  
这还是我看过最烂的解码程序......&gt;.&lt;.....helixcommunity mp3都比他好千万倍!!!!  
还是找其他专业一点的 flac decode  
-----------------------------------------------------------------------
说的有道理, 这也是因为flac的不固定帧长特性导致的
-----------------------------------------------------------------------
RT_FLAC 采用的是固定长度!!
decode_subframe_fixed(s, decoded, type & ~0x8)

出0入0汤圆

发表于 2011-8-24 09:55:23 | 显示全部楼层
o(╯□╰)o

出0入0汤圆

发表于 2011-8-24 11:42:20 | 显示全部楼层
终于抓到问题了。

读取超过 420 byte 就会出错,但是我读取其他就正常?

FRESULT f_read (
        FIL *fp,                 /* Pointer to the file object */
        void *buff,                /* Pointer to data buffer */
        UINT btr,                /* Number of bytes to read */
        UINT *br                /* Pointer to number of bytes read */
)

出0入0汤圆

发表于 2011-8-24 12:01:54 | 显示全部楼层
是否用stm32?

出0入0汤圆

发表于 2011-8-24 14:12:41 | 显示全部楼层
回复【61楼】cheungman
是否用stm32?
-----------------------------------------------------------------------
对阿使用 stm32f103ze

不过目前读取 flac 档案超过 420 byte 后,资料会乱掉?但是读取 wav 或 mp3 .txt 都没发生?
FATFS 已经使用 FATFS_V0.08B 版怎么会有这样奇怪的问题?

出0入0汤圆

发表于 2011-8-24 18:22:05 | 显示全部楼层
STM32 SDIO 改成中断方式即可

出0入0汤圆

 楼主| 发表于 2011-8-24 20:47:34 | 显示全部楼层
回复【62楼】nono2000
回复【61楼】cheungman  
是否用stm32?
-----------------------------------------------------------------------
对阿使用 stm32f103ze
不过目前读取 flac 档案超过 420 byte 后,资料会乱掉?但是读取 wav 或 mp3 .txt 都没发生?
fatfs 已经使用 fatfs_v0.08b 版怎么会有这样奇怪的问题?

-----------------------------------------------------------------------
终究来说,Rockbox的Flac经历了不少更新,上层是很稳定的.移植过程出现问题,大多是底层问题.这stm32的SDIO也有不少细节值得注意的.楼主位的SDIO是没记错是采用DMA+Polling的。

出0入0汤圆

发表于 2011-8-25 06:47:11 | 显示全部楼层
回复【64楼】zzm24

终究来说,rockbox的flac经历了不少更新,上层是很稳定的.移植过程出现问题,大多是底层问题.这stm32的sdio也有不少细节值得注意的.楼主位的sdio是......
-----------------------------------------------------------------------
楼主这个我知道,因为mp3与wav都已经处理好 4byte,所以不会发生读取 sd 卡错误.
但是flac也使用相同方式处理,但是资料出错!!!!  

最后真正找到问题了!!!!

(((flac 起点的位址并不是 4byte 的倍数,导致 DMA 读取SD 卡发生错误,所以 mp3与wav都是4byte 的倍数的起点)))

出0入0汤圆

 楼主| 发表于 2011-8-25 19:06:52 | 显示全部楼层
回复【65楼】nono2000  
-----------------------------------------------------------------------

在STM32的SDIO DMA + Fatfs情况下,在底层SD读(多)扇区的时候得加个判断,判断目标buffer(相当DMA来说)是否对齐。

1.目标buffer对齐.
直接配置DMA传就行.

2.目标buffer不对齐.
新增一个SECTOR_SIZE的buffer,确保其对齐了.
然后用DMA传到这新增的buffer.
最后copy到目标buffer.

见楼主位sdcard.c的function:
static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size);

出0入0汤圆

发表于 2011-10-31 01:27:02 | 显示全部楼层
一堆高手!

出0入0汤圆

发表于 2011-11-29 11:32:41 | 显示全部楼层
请问,为什么说stm32的i2s不争气,及ape解码真的要用到浮点吗?我在代码上没找到要用浮点的地方,谢谢,最近想用stm32f4来做一个播放器。谢谢

出0入0汤圆

 楼主| 发表于 2011-11-29 12:27:55 | 显示全部楼层
回复【68楼】wdmfhvk 成都
请问,为什么说stm32的i2s不争气
-----------------------------------------------------------------------
请看stm32关于i2s的勘错PDF,或者参考此贴:
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3906346&bbs_page_no=2&bbs_id=9999
对于stm32来说,4系列I2S的确支持全双工,但是从1系列到4系列I2S依然存在于勘错PDF上.

及ape解码真的要用到浮点吗?我在代码上没找到要用浮点的地方.
-----------------------------------------------------------------------
记得我没说过APE要浮点计算啊....要很多的除法运算罢了,但其对CPU的频率要求还是挺高的.Normal以上连跑200M的ARM7都无能为力.

最近想用stm32f4来做一个播放器。
-----------------------------------------------------------------------
自己玩的话不用4系列也可以,2系列完全能胜任,对于stm32要好音质请CODEC做Master.再深层次的话,就选I2S带硬件乒乓缓冲的MCU,例如AVR32.

出0入0汤圆

发表于 2011-11-29 13:46:09 | 显示全部楼层
这么快有有回话了,谢谢,avr32解ape太慢。s64/s256+cs8406我试了,也太慢,wav还行。谢谢。不知有没什么好一点的芯片(解Normal),说说,谢谢!

出0入0汤圆

发表于 2011-11-29 14:20:37 | 显示全部楼层
有没有APE的版本呀

出0入0汤圆

 楼主| 发表于 2011-11-29 19:43:15 | 显示全部楼层
回复【70楼】wdmfhvk 成都
这么快有有回话了,谢谢,avr32解ape太慢。s64/s256+cs8406我试了,也太慢,wav还行。谢谢。不知有没什么好一点的芯片(解normal),说说,谢谢!
-----------------------------------------------------------------------
那就直接收一STM32F4DISCOVERY就行.解Normal无压力.要好音质请CODEC做Master.

出0入0汤圆

发表于 2011-11-30 09:28:55 | 显示全部楼层
谢谢!zzm24,
看了一下
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3906346&bbs_page_no=2&bbs_id=9999
对于stm32来说,4系列I2S的确支持全双工,但是从1系列到4系列I2S依然存在于勘错PDF上.
都快不敢用stm32的mcu了。
我一直用Atmel系例的。
70楼,
说,Normal以上连跑200M的ARM7都无能为力.后来就想用Atmel的arm9 400M的(担心200M的太慢。目前我还不确定这个块子是否I2S带硬件乒乓缓冲,知道的朋友说说一下),我在呼音质,跑裸机,i2s不断流。解ape及常用hifi格式.
看到72:
那就直接收一STM32F4DISCOVERY就行.解Normal无压力.要好音质请CODEC做Master.
我想确认一下,STM32F4是解解Normal无压力,还是指Normal以上(所有ape),都无压力。我是让stm32作slave的,外部cs8406(Master)提供时钟,这样的话,是不是就能避开stm32的i2s bug,谢谢!

出0入0汤圆

 楼主| 发表于 2011-11-30 10:49:11 | 显示全部楼层
我想确认一下,STM32F4是解解Normal无压力,还是指Normal以上(所有ape),都无压力。我是让stm32作slave的,外部cs8406(Master)提供时钟,这样的话,是不是就能避开stm32的i2s bug,谢谢!
-----------------------------------------------------------------------------------------------------------------
Normal以上暂未测试,手头只有2系列,也只能告诉你2系列的成绩,2系列解Normal占用CPU 70%左右.还有就是200M ARM7解Normal占用CPU 80%左右.
至于stm32 I2S,也看见ST一直在努力.4系列I2S已知bug就这:

(原文件名:iis_error.jpg)
看避免方法也不难,只是STM32做Master的话,分频还是不准....

出0入0汤圆

发表于 2011-11-30 15:34:04 | 显示全部楼层
谢谢

出0入0汤圆

发表于 2012-1-5 19:48:04 | 显示全部楼层
mark I2S

出0入0汤圆

发表于 2012-2-12 21:04:16 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-3-25 14:20:30 | 显示全部楼层
俺试了用STM32F4解码flac, 压缩到第八级的双声道16位宽可以无间断播放到192K的采样率, 不过24位宽只能播放到48K, 再高就就会出现断音了.
发现24位解码大量使用了decode_subframe_lpc 这个函数里的64位*64位乘法, pred_order 10 以上时每毫秒要做过万次循环计算, 单片机速度跟不上.

出0入0汤圆

发表于 2012-3-27 09:43:11 | 显示全部楼层
F4应该至少能软解24b/96k flac

出0入0汤圆

发表于 2012-4-3 21:46:36 | 显示全部楼层
不知道用F207能达到多少?

出0入0汤圆

发表于 2012-4-10 22:55:18 | 显示全部楼层
软解是不是DSP更好些

出0入0汤圆

发表于 2012-8-19 20:00:33 | 显示全部楼层
楼主用的哪一颗片子啊?
头像被屏蔽

出0入0汤圆

发表于 2012-12-21 13:27:17 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2013-10-8 16:24:48 | 显示全部楼层
好贴,不顶对不起哥啊

出0入0汤圆

发表于 2013-10-17 12:41:13 | 显示全部楼层
哈哈,断断续续搞了几天,终于能播放flac文件了,谢谢哥!!!!!
我用的是stm32f407,  之前已经弄好u盘播放wav了,没有用rt_thread, ffs也跟哥的不一样,拷贝别人移植的ffs,所以只使用了Flac里面的bitstreamf.c,decoder.c,tables.c三个文件和相关的h文件,然后参照Ext_flac.c重新写一个读取flac文件和播放的程序,折腾了几天,终于能播放16bit flac了,下一步测试一下24bit, 88K, 96k格式的

出0入0汤圆

发表于 2013-10-17 12:49:18 | 显示全部楼层
flac移植还是非常容易的.

出0入0汤圆

发表于 2013-10-17 16:19:53 | 显示全部楼层
MARK下先

出0入0汤圆

发表于 2014-7-22 11:25:05 | 显示全部楼层
在FLAC格式文件说明书里的Frame Header:  
if(variable blocksize)
   <8-56>:"UTF-8" coded sample number (decoded number is 36 bits)
else
   <8-48>:"UTF-8" coded frame number (decoded number is 31 bits)
这段话的含义一直没看明白,不知作何理解?望各为能补充一下.

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-5-3 15:07

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

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