在Android应用中,如何减少从麦克风重复输入的音频作为扬声器的输出音频时的延迟

时间:2018-12-12 17:52:06

标签: android kotlin android-audiomanager audiotrack android-audiorecord

作为一个实验,我试图创建一个应用程序,该应用程序可以重复从麦克风输入的音频作为扬声器的输出音频。到现在为止,我能够以大约0.5到1秒的延迟来做到这一点。因此,如果有人对如何改进以下代码以减少延迟有任何想法。

Android high-performance audio - Google I/O 2016中,我看到进出延迟可以低至20毫秒,比我得到的要短得多。

我尝试在Google上搜索以及关于StackOverflow的其他问题,但其中使用的大多数方法在API级别26中已弃用。

private fun recordAndPlay(){

    val audioManager = this.getSystemService(Context.AUDIO_SERVICE) as AudioManager
    val rate = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)

    val RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO
    val RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT
    val RECORDER_SAMPLERATE = rate.toInt()
    val bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING)
    val BytesPerElement = 2


    val recorder = AudioRecord(MediaRecorder.AudioSource.MIC,
            RECORDER_SAMPLERATE, RECORDER_CHANNELS,
            RECORDER_AUDIO_ENCODING, bufferSize * BytesPerElement)
    Log.e("Buffer , sample rate","*********** ${recorder.sampleRate}")

    recorder.startRecording()

    val audioAttributes = AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA)
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build()
    val audioFormat = AudioFormat.Builder().setEncoding(RECORDER_AUDIO_ENCODING)
            .setSampleRate(RECORDER_SAMPLERATE).setChannelMask(AudioFormat.CHANNEL_OUT_MONO).build()

    val recordingThread = Thread(Runnable {
        try {
            val sData = ByteArray(bufferSize)
            var at : AudioTrack? = AudioTrack.Builder()
                    .setAudioAttributes(audioAttributes)
                    .setAudioFormat(audioFormat)
                    .setBufferSizeInBytes(bufferSize*2)
                    .build()
            while (true) {
                recorder.read(sData, 0, bufferSize)  //isRecording = false; onStop button
                at.play()
                if (at != null) {
                    at.write(sData, 0, sData.size)
                }
                at.stop()
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }, "AudioRecorder Thread")

    recordingThread.start()
}

谢谢。


注意:以前,该问题还解决了输入声音重复回声的问题。此问题是由于使用电话的扬声器而不是耳机导致了如Lucky1928的注释中所述的反馈环路。那回声是我忽略周围环境而不是任何与Android相关的问题的错,因此该部分问题已被删除。因此,在测试上述代码时,请使用耳机。

0 个答案:

没有答案
相关问题