AudioTrack滞后:obtainBuffer超时 [英] AudioTrack lag: obtainBuffer timed out

查看:1097
本文介绍了AudioTrack滞后:obtainBuffer超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的Andr​​oid手机播放WAV文件被通过的FileInputStream>的BufferedInputStream>的DataInputStream方法加载文件和喂养字节到AudioTrack.write()。音频播放罚款,如果是这样,我可以很容易地在与漂亮的业绩飞调节采样率,音量等。然而,这需要大约两个完整秒的曲目开始播放。我知道AudioTrack有不可推卸的延迟,但是这是荒谬的。我每次播放曲目,我得到这样的:

I'm playing WAVs on my Android phone by loading the file and feeding the bytes into AudioTrack.write() via the FileInputStream > BufferedInputStream > DataInputStream method. The audio plays fine and when it is, I can easily adjust sample rate, volume, etc on the fly with nice performance. However, it's taking about two full seconds for a track to start playing. I know AudioTrack has an inescapable delay, but this is ridiculous. Every time I play a track, I get this:

03-13 14:55:57.100: WARN/AudioTrack(3454): obtainBuffer timed out (is the CPU pegged?) 0x2e9348 user=00000960,     server=00000000
03-13 14:55:57.340: WARN/AudioFlinger(72): write blocked for 233 msecs, 9 delayed writes, thread 0xba28

我已经注意到,每一次延迟写入次数增加一个我播放曲目 - 甚至可以跨多个会话 - 从时间手机已经开启。阻塞时间总是230 - 240毫秒,这是有道理的考虑9600的最小缓冲区大小该装置(四万四千一分之九千六)上。我已经看到在互联网上无数次的搜索此消息,但它通常似乎与不玩音频的全部或跳过音频。就我而言,它只是延迟启动。

I've noticed that the delayed write count increases by one every time I play a track -- even across multiple sessions -- from the time the phone has been turned on. The block time is always 230 - 240ms, which makes sense considering a minimum buffer size of 9600 on this device (9600 / 44100). I've seen this message in countless searches on the Internet, but it usually seems to be related to not playing audio at all or skipping audio. In my case, it's just a delayed start.

我跑我所有的code在高优先级的线程。下面是我在做什么的截尚未功能版本。这是我的播放类中的线程回调。同样,这个工程(只打16位,44.1kHz的,立体声文件现在),它只是需要永远启动,并具有obtainBuffer /写入延迟的消息每一次。

I'm running all my code in a high priority thread. Here's a truncated-yet-functional version of what I'm doing. This is the thread callback in my playback class. Again, this works (only playing 16-bit, 44.1kHz, stereo files right now), it just takes forever to start and has that obtainBuffer/delayed write message every time.

public void run()
{

    // Load file
    FileInputStream mFileInputStream;
    try
    {
        // mFile is instance of custom file class -- this is correct, 
        // so don't sweat this line
        mFileInputStream = new FileInputStream(mFile.path());
    } catch (FileNotFoundException e) {}
    BufferedInputStream mBufferedInputStream = new BufferedInputStream(mFileInputStream, mBufferLength);
    DataInputStream mDataInputStream = new DataInputStream(mBufferedInputStream);

    // Skip header
    try
    {
        if (mDataInputStream.available() > 44)
            mDataInputStream.skipBytes(44);
    } catch (IOException e) {}

    // Initialize device
    mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, ConfigManager.SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_STEREO, AudioFormat.ENCODING_PCM_16BIT, ConfigManager.AUDIO_BUFFER_LENGTH,
            AudioTrack.MODE_STREAM);
    mAudioTrack.play();

    // Initialize buffer
    byte[] mByteArray = new byte[mBufferLength];
    int mBytesToWrite = 0;
    int mBytesWritten = 0;

    // Loop to keep thread running
    while (mRun)
    {

        // This flag is turned on when the user presses "play"
        while (mPlaying)
        {

            try
            {

                // Check if data is available
                if (mDataInputStream.available() > 0)
                {

                    // Read data from file and write to audio device
                    mBytesToWrite = mDataInputStream.read(mByteArray, 0, mBufferLength);
                    mBytesWritten += mAudioTrack.write(mByteArray, 0, mBytesToWrite);

                }

            }
            catch (IOException e)
            {
            }

        }

    }

}

如果我能得到过去的人为长的滞后,我可以很容易地与继承的等待时间由开始我写在后面,predictable位置处理(即跳过最小的缓冲区长度,当我开始播放的文件)

If I can get past the artificially long lag, I can easily deal with the inherit latency by starting my write at a later, predictable position (ie, skip past the minimum buffer length when I start playing a file).

推荐答案

迟到了有点回答这个,但如果它可以帮助任何人在未来的 - 我遇到了与code $ P $这个确切的问题ptty的类似code中的问题,在其中创建AudioTrack,并设置为播放,但不能立即写入。

A bit late to the party answering this, but in case it helps anyone in the future - I ran into this exact problem with code pretty similar to the code in the question, where the AudioTrack is created and set to play, but not written to immediately.

我发现,在创建AudioTrack立即然后再开始编写向它提出的延迟消失。出于某种原因,AudioTrack似乎并不喜欢围坐在一个空的缓冲区。

I found that creating the AudioTrack immediately before you start writing to it made the delay go away. For some reason AudioTrack doesn't seem to like sitting around with an empty buffer.

在的code以上的条款,你想要做这样的事情

In terms of the code above, you'd want to do something like

mAudioTrack=null;
while (mRun) 
{ 

    // This flag is turned on when the user presses "play" 
    while (mPlaying) 
    { 

        try 
        { 
            if (mAudioTrack==null) {   
                mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, ConfigManager.SAMPLE_RATE,AudioFormat.CHANNEL_CONFIGURATION_STEREO, AudioFormat.ENCODING_PCM_16BIT,ConfigManager.AUDIO_BUFFER_LENGTH,AudioTrack.MODE_STREAM);   
                mAudioTrack.play();   
            }
            // Rest of the playback code here
        }
    }
    mAudioTrack=null;
}

这篇关于AudioTrack滞后:obtainBuffer超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆