Android Audio 01 - Control Block
来源:互联网 发布:网络兼职赚钱平台 编辑:程序博客网 时间:2024/06/07 00:30
Audio CB: audio_track_cblk_t
userBase, serverBase, frameCount, stepUser, stepServer, buffer, frameAvailable, frameReady
userBase: 写数据的基数位置
serverBase: 读数据的基数位置
FrameCount: 读写大小
stepUser:更新写数据的位置
stepServer: 更新读数据的位置
underrun模式:生产者跟不上消费者,消费者得wait,生产者有数据了signal
生产者:obtainBuffer/memcpy/releaseBuffer
消费者: getNextBuffer/releaseBuffer
-------------------------------------------------------------------------------------------
cblk_t | server读 | user写 | |
-------------------------------------------------------------------------------------------
stepUSER() and stepServer的作用是调整当前偏移的位置,可以看到,他们仅仅是把成员变量user server的值加上需要移动的数量,user和server的值并不考虑FIFO的边界问题,随着数据的不停写入和读出,user和server的值不断增加,只要处理得当,user总是出现在server的后面,因此frameAvailable和frameReady才会成立。根据这种算法,user和server都会大于FIFO的大小,frameCount,那么如何确定真正的写指针的位置了?需要用到userbase这个变量。在stepUser中,每当user的值越过(UserBase+farmeCount) userBase就会增加frameCount,这样映射到FIFO中的偏移总是可以通过user-userBase获得。因此,获得当前FIFO的写指针可以通过buffer()返回
p = mCblk->buffer(mcblk->user)
---------------- 华华丽丽的分割线----------------------------------
细读了android中关于audio这块的源码,发现有个地方设计的挺巧妙的。
他将一块有限的线性buffer,变成了可以循环的环形缓冲,生产者/消费者模式
原来的代码函数是,frameAvaliable Buffer stepUser// frameReady/stepServer etc.
我稍微简化了些,留作以后可能需要生产者/消费者的读写I/O
1 const int bufferSize = 1000; 2 const int loopStart = 1000; 3 //userBase = everytime the buffer write cross the scope, 4 //loop to the first place, userBase += bufferSize 5 6 /* 7 * buffer():provide the init position for write 8 */ 9 void* audio_track_cblk_t::buffer(int write) const 10 { 11 return buffers + write - userBase; 12 } 13 //how many bytes could be available 14 int audio_track_cblk_t::bufferAvailable() 15 { 16 int limit = (read < loopStart) ? read : loopStart; 17 return limit + loopStart - write; 18 } 19 int audio_track_cblk_t::updateWrite(int frameCount)//frameCount is how many bytes been written 20 { 21 //update the position of write 22 write += frameCount; 23 if (write >= userBase + bufferSize){ 24 userBase += bufferSize;//userBase will loop to the front 25 } 26 return write; 27 } 28 int audio_track_cblk_t::bufferCouldRead() 29 { 30 // write will always larger than read position 31 // whenever the loop has happened 32 // the max gap between write and read will be bufferSize 33 return write - read; 34 } 35 bool audio_track_cblk_t::updateReadPos(int frameCount) 36 { 37 LOG("after read, update the read position"); 38 LOG("frameCount is the buffer size been read"); 39 read+= frameCount; 40 41 if ( read >= userBase + bufferSize) 42 userBase += bufferSize; 43 44 signal();//signal the write side 45 return true; 46 }
稍微说明:
bufferSize就是这块线性内存的大小,userBase其实一直被增长,但是每次都是bufferSize的整数倍,当write越界了,超过bufferSize了,比如写了1300,bufferSize才1000,那userBase就必须加上1000,这样write-userBase=300,这样才是正确的相对写位置。读位置同理。
write要一直比read快,否则生产者/消费者模型就有问题了。wait/signal/broadcast/ could help.
- Android Audio 01 - Control Block
- Android Audio special Introduction2 -- ICS A2DP Control
- memory control block system
- Android Audio Subsystem - get_audio_flinger - 01
- Android Audio
- android audio
- android audio
- android Audio
- android audio
- Android audio
- android audio
- Android Audio
- [Audio] Android深入浅出之Audio
- [Audio] Android Audio 相关知识
- Usb Audio Device Descriptor(1) Standard Audio Control Interface Descriptor
- Audio Gain Control Using Digital Potentiometers
- Android Audio 1:Android Audio概述
- Android Audio代码分析26 - Audio Strategy
- 不重新编译php, 安装curl扩展
- HttpClient ssl双向认证
- php utf8 截取字符串(支持中文)
- 调用系统程序导入手机上的vcard文件
- Android MediaPlayer架构图解
- Android Audio 01 - Control Block
- Android的intent之间复杂参数的传递
- 关闭子页面刷新父页面时候,Firefox 必须发送将会导致重复之前动作的数据(例如搜索或者下订单)。 ie提示:若要再次显示该页面,web浏览器需要重新发送您以前提交的信息
- 获得系统名称
- 瑞芯微平台编译说明
- nginx安装配置
- js计算日期差,单位为小时;满足firefox,ie浏览器
- Makefile.am
- smark使用小结