10

AudioTrackストリーミング モードで動的に生成されたオーディオを再生するアプリがあります。アプリは入力に即座に応答する必要がないため、プログラムのその側ではレイテンシーの問題は気になりません。

問題は、オーディオとできるだけ正確に「同期」する必要があるアニメーションがあり、デバイスが異なればAudioTrack、通話のブロックが停止write()してより多くのデータを要求するまでの時間も異なるようです。そのオーディオはスピーカーから再生されます。

私の現在の解決策は、ほとんどの方法でそこに到達します。AudioTrackこれまでに渡したフレームの数を数え、それを と比較しgetPlaybackHeadPosition()ます。基本的に次のようになります。

long currentTimeInFrames = 0;
while(playingAudio) {
  currentTimeInFrames += numberOfFramesToWrite;
  long delayInFrames = (currentTimeInFrames - audioTrack.getPlaybackHeadPosition());
  audioTrack.write(frameBuffer,0,sampleSize);
  doAnimationAfterDelay(delayInFrames);
}

getPlaybackHeadPosition()ただし、デバイスによって異なりますが、それを説明していないように見える遅延がまだいくつかあります.

AudioTrack のレイテンシーについてシステムをポーリングする方法はありますか?

4

4 に答える 4

5

API レベル 19 では、getTimeStamp()AudioTrackという メソッドが追加されています。ドキュメントから:

オンデマンドでタイムスタンプをポーリングします。

最初のウォームアップ中、またはルーティングまたはモードの変更後にタイムスタンプを追跡する必要がある場合は、報告されたタイムスタンプがフレーム位置が進んでいることを示すまで、またはこのルートでタイムスタンプが利用できないことが明らかになるまで、定期的に新しいタイムスタンプを要求する必要があります。

関数のパラメーターとしてAudioTimestampオブジェクトを指定すると、最新の「提示された」フレーム位置と、ナノ秒単位の「推定された」タイムスタンプが入力されます。ナノ秒の値は、 SystemClock.uptimeMillis()によって返されるミリ秒の値に対応します。

AudioTrack次に、その特定のフレームをいつ書き込んだのgetTimestamp()か、それが実際に表示されたと考えたのかを把握することで、レイテンシを決定できます。この方法は、上記の他の方法よりも正確であることがわかりました。

ただし、注意が必要です。ドキュメントによるgetTimeStamp()と、すべてのプラットフォームまたはすべてのルートでサポートされているわけではありません。boolean戻り値を確認することで、呼び出しが成功したかどうかを判断できます。私がテストしたデバイスでは、オーディオの表示が開始されるまで関数が false を返し、その後の呼び出しが true を返すことがわかりました。モードでのみテストしAudioTrackました。STREAM_MUSICあなたのマイレージは異なる場合があります。

于 2016-06-04T02:37:02.777 に答える
-1

AudioTrack の作成時に渡したバッファサイズを考慮する必要があります。

final int minBufSize = AudioTrack.getMinBufferSize(Application.PLAYRATE,
AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);

out=new AudioTrack(AudioManager.STREAM_MUSIC, Application.PLAYRATE, 
AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, minBufSize, 
AudioTrack.MODE_STREAM);

extraLatencyFrames = minBufSize/4;
于 2013-09-10T13:25:01.957 に答える
-1

わかりました、これが鍵です。最初に Audiotrack クラスを拡張する必要があります。次に、getNativeFrameCount を使用して、ネイティブ側に関連するレイテンシを概算します。

class MyAudioTrack extends AudioTrack
{
    public MyAudioTrack(int streamType, int sampleRateInHz, int channelConfig,
            int audioFormat, int bufferSizeInBytes, int mode)
            throws IllegalArgumentException {
        super(streamType, sampleRateInHz, channelConfig, audioFormat,
                bufferSizeInBytes, mode);
        System.out.println("Native framecount "+getNativeFrameCount());
    }   
    public int getFrameCount()
    {
        return getNativeFrameCount();
    }
}
于 2013-09-10T19:21:34.830 に答える