非官方之STM32 Radio播放Flac
花时间"移植"了一下,得益于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),大小都为.
两个"临时"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")即可 有图有真相
http://cache.amobbs.com/bbs_upload782111/files_36/ourdev_613210TNX5W3.jpg
(原文件名:flac.jpg) 不错。让STM32也飞了一把 不错不错!以后STM32Radio花样会越来越多了 FLAC的音质很不错,无损音频压缩编码,好图好真相,谢谢分享^_^ mark! mark FLAC mark 学习了·~~ 近期的学习内容! mark 学习学习! 不错,好东西 用了个CS8406作为master, STM32作为slave, 改写I2S为:I2S_DataFormat_16bextended, 接上同轴到解码器, 音质效果还行. 现在终于支持全级别了
新增加文件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)
http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_633064DKTU0H.jpg
(原文件名:2011-04-23_214211.jpg) 强人,mark M 回复【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已经可以了. 前置知识:对于解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.
这次欢迎拍砖,^_^. 回复【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的一些特性, 以上只是与你交流一下, 如果能做到, 你可以试试看. 我的想法就是:将解码缓冲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. 回复【20楼】zzm24
我的想法就是:将解码缓冲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.
-----------------------------------------------------------------------
sigh~~~, 照你这么说, STM32的外部RAM接口原来不能完全当成或等同CPU内部RAM来使用, 速度这么慢啊...这种接口也太囧了吧. 回复【21楼】cheungman
-----------------------------------------------------------------------
不能这么绝对,fsmc接DM9000或者接LCD不是很好么? 回复【21楼】cheungman
-----------------------------------------------------------------------
只是灵活,速度上确实接外部RAM不咋地,等效于内部的3到5分频吧,具体多少没仔细研究。
不然我的播放器早就用外部RAM支持全LEVEL的FLAC了.
同意zzm24兄台的意见,接某些速度要求不那么高的器件还是很好的。(我只接过RAM和LCD,不过不知道什么原因,我的板子上的外部RAM不好使了.) make MARK 这个一定要顶~ 不得不顶!! zzm在STM32Radio上加了很多东西,赞一个!
另外还有个以太网转CAN(UDP模式,协议协议兼容zlg的转换器),到时也加上去。 mark STM32F207的网络收音机板子拿到了,会在0.4.0 beta2版本发布后开始调试软件。
这个版本的网络收音机包括:88w8686 wifi的接口(模块与主板是分离的,主板上留接口),也会弄个外壳;软件上,会把0.4.0分支中主要的动态模块功能放到Cortex-M3上运行。
可惜和zzm沟通太晚了,否则过来做STM32F2xx网络收音机暑假实习多好:-P 是否还有其他同学有这个意向? 长见识了。 这个得关注一下 flac_decode_frame()解后的资料是否能直接输出到 DAC? flac_decode_frame()解后存decode0 decode1,分别是左右声道,根据音源或自己需要合成16bit或者24bit等来送给CODEC 回复【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 一推牛人。 回复【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缓冲即可! 回复【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,应该是自己写的吧? 回复【37楼】cheungman
如果你解码16bit音频, 直接用int16_t* decoded缓冲即可!
-----------------------------------------------------------------------
真的吗?
decode_subframe()能这样改吗?
RT_flac_decode_frame()虽然是16bit,但是实际也要先解码成 32bit后,再转16bit. 回复【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了. 回复【40楼】cheungman
-----------------------------------------------------------------------
当然可以, decoded解码缓冲的数据是int32_t的, 4byte, 对应采样位数, 如果16bit音频流, 解码后得到是高16位为0, 低16位有效的PCM数据, 既然高16位无效, 当然可以用(int16_t* )decoded了.
-----------------------------------------------------------------------
好像不行!!!!
虽然设定 s->sbp=16 bit,但是解码依然是 32bit.
flac_decode_frame()都是以 32bit 计算解码的,不是那么容易改. 回复【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;} 如果能,大家就不用搞的那么累了。
-----------------------------------------------------------------------
如果不能, 那么你们的问题, 相信我上边已经写得够清楚了. 回复【43楼】cheungman
如果能,大家就不用搞的那么累了。
-----------------------------------------------------------------------
如果不能, 那么你们的问题, 相信我上边已经写得够清楚了.
-----------------------------------------------------------------------
好吧,你能提供 flac_decode_frame(FLACContext *s, int16_t* decoded) 范例吗?
谢谢!!!! 回复【40楼】cheungman
当然可以, decoded解码缓冲的数据是int32_t的, 4byte, 对应采样位数, 如果16bit音频流, 解码后得到是高16位为0, 低16位有效的PCM数据, 既然高16位无效, 当然可以用(int16_t* )decoded了
-----------------------------------------------------------------------
16bit音频流, 解码后得到是高16位为0--->你自己运行一下就知道了喔,Flac解码没那么简单,,,呵呵,。 回复【44楼】j-link
回复【45楼】nono2000
16bit音频流, 解码后得到是高16位为0--->你自己运行一下就知道了喔,flac解码没那么简单,,,呵呵,。
-----------------------------------------------------------------------
请两位把flac源码中把对应的变量更改为(int16_t *), 包括decoded , decoded0, decoded1等变量. 我自己这么改过并验证过, 不会随便说几句话来显摆. 回复【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;<===============都错误??
} 回复【47楼】<FONT style="BACKGROUND-COLOR: #ffd700">nono2000</FONT>
-----------------------------------------------------------------------
初始化成功了吗?还是文件操作接口没移植好?因为RTT是基于POSIX的,如果用FATFS得改文件操作函数,主要是open,read,lseek.请确保移植成功.单独来说,函数int decode_frame(FLACContext *s);是没问题的.还有我还没做上版主呢.这里我只是开了个头,何必一定必要跟着走?Rockbox赤裸裸地躺在那里,不管你上不上,反正我是上了. 回复【48楼】zzm24
回复【47楼】<font style="background-color: #ffd700">nono2000</font>
-----------------------------------------------------------------------
初始化成功了吗?还是文件操作接口没移植好?因为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.文件系统仍有问题 回复【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
} 强势围观 我觉得 FLAC (Alex Beregszaszi) 解码漏洞太多,只要FLAC档案有错误,将会导致资料乱丢.
每个 frame 都还要重复计算 blocksize 及 sample_rate_code...如果计算错误,将会很惨...
所以之前使用flac_init()判读 blocksize sample_rate framesize 都是没用的!!!!!
这还是我看过最烂的解码程序......>.<.....helixcommunity MP3都比他好千万倍!!!!
还是找其他专业一点的 FLAC DECODE 最后追踪发现是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;
}
} mark 回复【53楼】nono2000
最后追踪发现是get_ur_golomb_jpegls 解码错误导致,这样为什么我也不知道??
运行后导致 gb->index 资料错误?
-----------------------------------------------------------------------
把if(log > 31-11)改成
if(log - k >= 32-MIN_CACHE_BITS+(MIN_CACHE_BITS==32) && 32-log < limit) 回复【52楼】d-link
我觉得 flac (alex beregszaszi) 解码漏洞太多,只要flac档案有错误,将会导致资料乱丢.
每个 frame 都还要重复计算 blocksize 及 sample_rate_code...如果计算错误,将会很惨...
所以之前使用flac_init()判读 blocksize sample_rate framesize 都是没用的!!!!!
这还是我看过最烂的解码程序......>.<.....helixcommunity mp3都比他好千万倍!!!!
还是找其他专业一点的 flac decode
-----------------------------------------------------------------------
说的有道理, 这也是因为flac的不固定帧长特性导致的 回复【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全部参数及我的载入资料都正确,但是我的确解码错误? 回复【56楼】cheungman
回复【52楼】d-link
我觉得 flac (alex beregszaszi) 解码漏洞太多,只要flac档案有错误,将会导致资料乱丢.
每个 frame 都还要重复计算 blocksize 及 sample_rate_code...如果计算错误,将会很惨...
所以之前使用flac_init()判读 blocksize sample_rate framesize 都是没用的!!!!!
这还是我看过最烂的解码程序......>.<.....helixcommunity mp3都比他好千万倍!!!!
还是找其他专业一点的 flac decode
-----------------------------------------------------------------------
说的有道理, 这也是因为flac的不固定帧长特性导致的
-----------------------------------------------------------------------
RT_FLAC 采用的是固定长度!!
decode_subframe_fixed(s, decoded, type & ~0x8) o(╯□╰)o 终于抓到问题了。
读取超过 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 */
) 是否用stm32? 回复【61楼】cheungman
是否用stm32?
-----------------------------------------------------------------------
对阿使用 stm32f103ze
不过目前读取 flac 档案超过 420 byte 后,资料会乱掉?但是读取 wav 或 mp3 .txt 都没发生?
FATFS 已经使用 FATFS_V0.08B 版怎么会有这样奇怪的问题? STM32 SDIO 改成中断方式即可 回复【62楼】nono2000
回复【61楼】cheungman
是否用stm32?
-----------------------------------------------------------------------
对阿使用 stm32f103ze
不过目前读取 flac 档案超过 420 byte 后,资料会乱掉?但是读取 wav 或 mp3 .txt 都没发生?
fatfs 已经使用 fatfs_v0.08b 版怎么会有这样奇怪的问题?
-----------------------------------------------------------------------
终究来说,Rockbox的Flac经历了不少更新,上层是很稳定的.移植过程出现问题,大多是底层问题.这stm32的SDIO也有不少细节值得注意的.楼主位的SDIO是没记错是采用DMA+Polling的。 回复【64楼】zzm24
终究来说,rockbox的flac经历了不少更新,上层是很稳定的.移植过程出现问题,大多是底层问题.这stm32的sdio也有不少细节值得注意的.楼主位的sdio是......
-----------------------------------------------------------------------
楼主这个我知道,因为mp3与wav都已经处理好 4byte,所以不会发生读取 sd 卡错误.
但是flac也使用相同方式处理,但是资料出错!!!!
最后真正找到问题了!!!!
(((flac 起点的位址并不是 4byte 的倍数,导致 DMA 读取SD 卡发生错误,所以 mp3与wav都是4byte 的倍数的起点))) 回复【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); 一堆高手! 请问,为什么说stm32的i2s不争气,及ape解码真的要用到浮点吗?我在代码上没找到要用浮点的地方,谢谢,最近想用stm32f4来做一个播放器。谢谢 回复【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. 这么快有有回话了,谢谢,avr32解ape太慢。s64/s256+cs8406我试了,也太慢,wav还行。谢谢。不知有没什么好一点的芯片(解Normal),说说,谢谢! 有没有APE的版本呀 回复【70楼】wdmfhvk 成都
这么快有有回话了,谢谢,avr32解ape太慢。s64/s256+cs8406我试了,也太慢,wav还行。谢谢。不知有没什么好一点的芯片(解normal),说说,谢谢!
-----------------------------------------------------------------------
那就直接收一STM32F4DISCOVERY就行.解Normal无压力.要好音质请CODEC做Master. 谢谢!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,谢谢! 我想确认一下,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就这:
http://cache.amobbs.com/bbs_upload782111/files_48/ourdev_700226ZZH70G.jpg
(原文件名:iis_error.jpg)
看避免方法也不难,只是STM32做Master的话,分频还是不准.... 谢谢 mark I2S mark 俺试了用STM32F4解码flac, 压缩到第八级的双声道16位宽可以无间断播放到192K的采样率, 不过24位宽只能播放到48K, 再高就就会出现断音了.
发现24位解码大量使用了decode_subframe_lpc 这个函数里的64位*64位乘法, pred_order 10 以上时每毫秒要做过万次循环计算, 单片机速度跟不上. F4应该至少能软解24b/96k flac 不知道用F207能达到多少? 软解是不是DSP更好些 楼主用的哪一颗片子啊? 好贴,不顶对不起哥啊{:handshake:} 哈哈,断断续续搞了几天,终于能播放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格式的 flac移植还是非常容易的. MARK下先{:smile:} 在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)
这段话的含义一直没看明白,不知作何理解?望各为能补充一下. 有没有解24位FFLAC/WAV的源码可以分享?QQ376678497
页:
[1]