AudioRecord / Playback延迟大约1秒以上

时间:2018-05-07 15:06:40

标签: android buffer audio-streaming audiotrack audiorecord

这是我的CaptureThread:

  private class CaptureThread implements Runnable {

    @Override
    public void run() {
        Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);

        AudioRecord record = new AudioRecord(MediaRecorder.AudioSource.MIC,
                mCaptureSampleRate,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT,
                mCaptureBufferSize);

        record.startRecording();
        short[] captureBuffer = new short[mCaptureBufferLength];

        if(mDebugLoopback) {
            int count;
            while(mRunning) {
                count = record.read(mLoopbackBuffer, 0, mLoopbackBuffer.length);
                if(count < mLoopbackBuffer.length) throw new AssertionError("count < captureBuffer.length");
                synchronized (mLoopbackBufferCapturedNotifier) {
                    mLoopbackBufferCapturedNotifier.notifyAll();
                }
            }
        }
        else {
            int count;
            while (mRunning) {
                count = record.read(captureBuffer, 0, captureBuffer.length);

                try {
                    TS3Client.processCustomCaptureData(getDeviceId(), captureBuffer, count);
                } catch (TS3Exception e) {
                    e.printStackTrace();
                }
            }
        }

        record.stop();
        record.release();
    }
}

这是我的PlaybackThread:

  private class PlaybackThread implements Runnable {
    @Override
    public void run() {
        Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);

        AudioTrack audioTrack = new AudioTrack(
                AudioManager.STREAM_VOICE_CALL,
                mPlaybackSampleRate,
                AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT,
                mPlaybackBufferSize,
                AudioTrack.MODE_STREAM);

        audioTrack.play();

        short[] buffer = new short[mPlaybackBufferLength];

        if(mDebugLoopback) {
            while (mRunning) {
                try {
                    synchronized (mLoopbackBufferCapturedNotifier) {
                        mLoopbackBufferCapturedNotifier.wait();
                    }
                    audioTrack.write(mLoopbackBuffer, 0, mLoopbackBuffer.length);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        else {
            while (mRunning) {
                try {
                    TS3Client.acquireCustomPlaybackData(getDeviceId(), buffer, mPlaybackBufferLength);
                    audioTrack.write(buffer, 0, mPlaybackBufferLength);
                } catch (TS3Exception e) {
                    e.printStackTrace();
                }
            }
        }

        audioTrack.stop();
        audioTrack.release();
    }
}

这是我设置到缓冲区的值:

   private void setupCaptureValues() {
    mCaptureSampleRate = getLowestSupportedCaptureSampleRate();
    if(mCaptureSampleRate == -1) {
        throw new RuntimeException("No supported capture sample rate known");
    }

    mCaptureBufferSize = AudioRecord.getMinBufferSize(mCaptureSampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
    mCaptureBufferLength = mCaptureBufferSize / 2; // 1 short = 2 bytes
    Log.i("","setupPlaybackValues mCaptureBufferSize is: " + mCaptureBufferSize);
    Log.i("","setupPlaybackValues mCaptureBufferLength is: " + mCaptureBufferLength);
}

private void setupPlaybackValues(AudioManager audioManager) {
    mPlaybackSampleRate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_VOICE_CALL);

    // By default use the min buffer size
    mPlaybackBufferSize = AudioTrack.getMinBufferSize(
            mPlaybackSampleRate,
            AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT);

    Log.d(TAG, "setupPlaybackValues: mPlaybackSampleRate: " + mPlaybackSampleRate);
    Log.d(TAG, "setupPlaybackValues: mPlaybackBufferSize: " + mPlaybackBufferSize);

    // If supported use the buffer size and sample rate required for a "low latency" streams
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
        String lowLatencyBufferSizeStr = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
        mPlaybackBufferSize = Integer.parseInt(lowLatencyBufferSizeStr);
        // This value is in frames and not bytes, 1 short = 2 bytes
        mPlaybackBufferSize *= 2;

        String lowLatencySampleRateStr = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
        mPlaybackSampleRate = Integer.parseInt(lowLatencySampleRateStr);

        Log.d(TAG, "setupPlaybackValues: using low latency stream values of");
        Log.d(TAG, "setupPlaybackValues: mPlaybackSampleRate: " + mPlaybackSampleRate);
        Log.d(TAG, "setupPlaybackValues: mPlaybackBufferSize: " + mPlaybackBufferSize);
    }

    mPlaybackBufferLength = mPlaybackBufferSize / 2; // 1 short = 2 bytes
}

哪个帖子发布:

05-07 17:03:19.858: D/TS3Client(15053): setupPlaybackValues mCaptureBufferSize is: 640
05-07 17:03:19.858: D/TS3Client(15053): setupPlaybackValues mCaptureBufferLength is: 320
05-07 17:03:19.861: D/AndroidAudioDevice(15053): setupPlaybackValues: mPlaybackSampleRate: 48000
05-07 17:03:19.861: D/AndroidAudioDevice(15053): setupPlaybackValues: mPlaybackBufferSize: 3848
05-07 17:03:19.863: D/AndroidAudioDevice(15053): setupPlaybackValues: using low latency stream values of
05-07 17:03:19.863: D/AndroidAudioDevice(15053): setupPlaybackValues: mPlaybackSampleRate: 48000
05-07 17:03:19.864: D/AndroidAudioDevice(15053): setupPlaybackValues: mPlaybackBufferSize: 480

现在我已经尝试为缓冲区提供尽可能小的值。我记录它们,如果我尝试任何更小的值,它只是崩溃说它不是一个有效的值。我需要找出一种方法来减少延迟,可能导致它的原因,还有另一种方法可以减少它,如果不是通过干预缓冲区吗?

0 个答案:

没有答案