Chinaunix首页 | 论坛 | 博客
  • 博客访问: 27374
  • 博文数量: 10
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-02 10:41
文章分类
文章存档

2013年(10)

我的朋友

分类: 嵌入式

2013-04-03 08:20:43

续接Android深入浅出之Audio 第二部分 AudioFlinger分析【转】

写者分析

先用frameavail看看当前剩余多少空间,我们可以假设是第一次进来嘛。读者还在那sleep呢。

uint32_t audio_track_cblk_t::framesAvailable()

{

    Mutex::Autolock _l(lock);

    return framesAvailable_l();

}

int32_t audio_track_cblk_t::framesAvailable_l()

{

    uint32_t u = this->user; 当前写者位置,此时也为0

    uint32_t s = this->server; //当前读者位置,此时为0

    if (out) { out1

        uint32_t limit = (s < loopStart) ? s : loopStart;

我们不设循环播放时间吗。所以loopStart是初始值INT_MAX,所以limit=0

        return limit + frameCount - u;

//返回0+frameCount-0,也就是全缓冲最大的空间。假设frameCount=1024

    }

}

然后调用buffer获得其实位置,buffer就是得到一个地址位置。

void* audio_track_cblk_t::buffer(uint32_t offset) const

{

    return (int8_t *)this->buffers + (offset - userBase) * this->frameSize;

}

完了,我们更新写者,调用stepUser

uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount)

{

//framecount,表示我写了多少,假设这一次写了512

    uint32_t u = this->user;//user位置还没更新呢,此时u=0

 

    u += frameCount;//u更新了,u=512

    // Ensure that user is never ahead of server for AudioRecord

    if (out) {

       //没甚,计算下等待时间

}

//userBase还是初始值为0,可惜啊,我们只写了1024的一半

//所以userBase加不了

   if (u >= userBase + this->frameCount) {

        userBase += this->frameCount;

//但是这句话很重要,userBase也更新了。根据buffer函数的实现来看,似乎把这个

//环形缓冲铺直了....连绵不绝。

    }

    this->user = u;//喔,user位置也更新为512了,但是useBase还是0

    return u;

}

好了,假设写者这个时候sleep了,而读者起来了。

读者分析

 

uint32_t audio_track_cblk_t::framesReady()

{

    uint32_t u = this->user; //u512

    uint32_t s = this->server;//还没读呢,s为零

 

    if (out) {

        if (u < loopEnd) {

            return u - s;//loopEnd也是INT_MAX,所以这里返回512,表示有512帧可读了

        } else {

            Mutex::Autolock _l(lock);

            if (loopCount >= 0) {

                return (loopEnd - loopStart)*loopCount + u - s;

            } else {

                return UINT_MAX;

            }

        }

    } else {

        return s - u;

    }

}

使用完了,然后stepServer

bool audio_track_cblk_t::stepServer(uint32_t frameCount)

{

    status_t err;

   err = lock.tryLock();

    uint32_t s = this->server;

 

    s += frameCount; //读了512帧了,所以s=512

    if (out) {

       

    }

   没有设置循环播放嘛,所以不走这个

    if (s >= loopEnd) {

       s = loopStart;

        if (--loopCount == 0) {

            loopEnd = UINT_MAX;

            loopStart = UINT_MAX;

        }

}

//一样啊,把环形缓冲铺直了

    if (s >= serverBase + this->frameCount) {

        serverBase += this->frameCount;

    }

    this->server = s; //server512

    cv.signal(); //读者读完了。触发下写者吧。

    lock.unlock();

    return true;

}

真的是环形缓冲吗?

环形缓冲是这样一个场景,现在buffer1024帧。

假设:

l         写者先写到1024

l         读者读到512

l         那么,写者还可以从头写512帧。

所以,我们得回头看看frameavail是不是把这512帧算进来了。

uint32_t audio_track_cblk_t::framesAvailable_l()

{

    uint32_t u = this->user;  //1024

    uint32_t s = this->server;//512

 

    if (out) {

        uint32_t limit = (s < loopStart) ? s : loopStart;

        return limit + frameCount - u;返回512,用上了!

    }

}

再看看stepUser这句话

if (u >= userBase + this->frameCount) {u1024userBase0frameCount1024

        userBase += this->frameCount;//好,userBase也为1024

}

看看buffer

return (int8_t *)this->buffers + (offset - userBase) * this->frameSize;

//offset是外界传入的基于user的一个偏移量。offs

阅读(1545) | 评论(0) | 转发(0) |
0

上一篇:数字混音原理

下一篇:Android Looper详解

给主人留下些什么吧!~~