当前位置:操作系统 > 安卓/Android >>

Android Audio延迟(latency)

最近在看Android中播放延迟的问题,看了下代码,发现AudioTrack类中的函数latency有以下注释:

[cpp]
/* Returns this track's latency in milliseconds.
 * This includes the latency due to AudioTrack buffer size, AudioMixer (if any)
 * and audio hardware driver.
 */ 

够强大,前几天自己还叭叭根据buffer计算延迟呢,原来可以调个函数就搞定。


看看函数AudioTrack::latency()的实现吧:
[cpp]
uint32_t AudioTrack::latency() const 

    return mLatency; 

没什么内涵,直接返回了成员变量。
mLatency是在哪儿被 赋值的呢?


AudioTrack::createTrack函数中对mLatency进行了赋值:

[cpp]
mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate; 

其中afLatency是硬件的延迟。
(1000*mCblk->frameCount) / sampleRate,这一坨,是根据AudioTrack中的audio_track_cblk_t的buffer,计算AudioTrack buffer导致的延迟。


afLatency的来历,也在函数AudioTrack::createTrack中:
[cpp]
uint32_t afLatency; 
if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) { 
    return NO_INIT; 

AudioSystem::getOutputLatency函数中首先根据stream type获取对应的output,然后尝试获取output的描述.
若取得成功,则使用output描述中的延迟;否则,获取AudioFlinger,并使用AudioFlinger中的延迟。
具体代码如下:
[cpp]
status_t AudioSystem::getOutputLatency(uint32_t* latency, int streamType) 

    OutputDescriptor *outputDesc; 
    audio_io_handle_t output; 
 
    if (streamType == DEFAULT) { 
        streamType = MUSIC; 
    } 
 
    output = getOutput((stream_type)streamType); 
    if (output == 0) { 
        return PERMISSION_DENIED; 
    } 
 
    gLock.lock(); 
    outputDesc = AudioSystem::gOutputs.valueFor(output); 
    if (outputDesc == 0) { 
        gLock.unlock(); 
        const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); 
        if (af == 0) return PERMISSION_DENIED; 
        *latency = af->latency(output); 
    } else { 
        *latency = outputDesc->latency; 
        gLock.unlock(); 
    } 
 
    LOGV("getOutputLatency() streamType %d, output %d, latency %d", streamType, output, *latency); 
 
    return NO_ERROR; 

先看看AudioFlinger中的latency:
AudioFlinger::latency函数中,首先获取output对应的PlaybackThread,然后取得PlaybackThread的latency:
[cpp]
return thread->latency(); 

看看函数AudioFlinger::PlaybackThread::latency():
[cpp]
uint32_t AudioFlinger::PlaybackThread::latency() const 

    if (mOutput) { 
        return mOutput->latency(); 
    } 
    else { 
        return 0; 
    } 

我做的这个项目中,mOutput其实就是AudioStreamOutALSA。
AudioStreamOutALSA::latency()函数:
[cpp]
#define USEC_TO_MSEC(x) ((x + 999) / 1000) 
 
uint32_t AudioStreamOutALSA::latency() const 

    // 将微秒转化为毫秒 
    // Android wants latency in milliseconds. 
    return USEC_TO_MSEC (mHandle->latency); 

mHandler中父类ALSAStreamOps的构造函数中被赋值。
用的是AudioStreamOutALSA构造函数中的参数handle。


AudioStreamOutALSA对象在函数AudioHardwareALSA::openOutputStream中被创建:
[cpp]
out = new AudioStreamOutALSA(this, &(*it)); 

it的赋值:
[cpp]
ALSAHandleList::iterator it = mDeviceList.begin(); 

mDeviceList的赋值在AudioHardwareALSA的构造函数中:
[cpp]
mALSADevice->init(mALSADevice, mDeviceList); 

init函数其实就是s_init函数:
[cpp]
static status_t s_init(alsa_device_t *module, ALSAHandleList &list) 

    LOGD("Initializing devices for IMX51 ALSA module"); 
 
    list.clear(); 
 
    for (size_t i = 0; i < ARRAY_SIZE(_defaults); i++) { 
 
        _defaults[i].module = module; 
        list.push_back(_defaults[i]); 
    } 
 
    return NO_ERROR; 

[cpp]
_defaults的定义: 

[cpp]
static alsa_handle_t _defaults[] = { 
    { 
        module      : 0, 
        devices     : IMX51_OUT_DEFAULT, 
        curDev      : 0, 
        curMode     : 0, 
        handle      : 0, 
        format      : SND_PCM_FORMAT_S16_LE, // AudioSystem::PCM_16_BIT 
        channels    : 2, 
        sampleRate  : DEFAULT_SAMPLE_RATE, 
        latency     : 200000, // Desired Delay in usec 
        bufferSize  : 6144, // Desired Number of samples 
        modPrivate  : (void *)&setDefaultControls, 
    }, 
    { 
        module      : 0, 
        devices     : IMX51_IN_DEFAULT, 
        curDev      : 0, 
        curMode     : 0, 
        handle      : 0, 
        format      : SND_PCM_FORMAT_S16_LE, // AudioSystem::PCM_16_BIT 
        channels    : 2, 
        sampleRate  : DEFAULT_SAMPLE_RATE, 
        latency     : 250000, // Desired Delay in usec 
        bufferSize  : 6144, // Desired Number of samples 
        modPrivate  : (void *)&setDefaultControls, 

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,