在Android上将FloatArray音频缓冲区保存到WAV文件

时间:2019-08-21 23:32:36

标签: android audio kotlin wav tarsosdsp

我在寻找一种解决方案时遇到了问题,该解决方案是使用Kotlin保存从TarsosDSP在Android上生成的音频数据的FloatArray缓冲区。目标是使音频缓冲区为1秒,并使用新的缓冲区数据不断更新,并丢弃较旧的数据。我希望在请求时保存此缓冲区。

我试图使用TarsosDSP库找到一种解决方案,但是它想将连续的流写入wav文件中。我只需要一秒钟,并且可以按需保存。这个WavFileWriter看起来很有希望-> https://github.com/philburk/jsyn/blob/master/src/com/jsyn/util/WaveFileWriter.java,但是正如我将其添加到我的android项目中一样,需要javax。我一直不知道,直到查找什么是Javax,而android不支持它。试图找到一个可以解决这个问题的库,结果却很少。

private val SAMPLE_RATE = 16000
private val BUFFER_SIZE = 1024
private val SECONDS = 1.0
private val sampleFileName: String = "audio_sample.wav"
private var audioBuffer = FloatArray(SAMPLE_RATE * SECONDS.toInt())

private var dispatcher =
        AudioDispatcherFactory.fromDefaultMicrophone(SAMPLE_RATE, BUFFER_SIZE, 128)
init {

blankProcessor = object : AudioProcessor {
   override fun processingFinished() {}

   override fun process(audioEvent: AudioEvent): Boolean {
      var buffer = audioEvent.floatBuffer
      val insertPoint = audioBuffer.lastIndex - buffer.lastIndex
      Arrays.copyOfRange(audioBuffer, insertPoint, audioBuffer.size)
                    .copyInto(audioBuffer, 0)
      buffer.copyInto(audioBuffer, insertPoint)
      return true
    }
}

dispatcher.addAudioProcessor(blankProcessor)

audioThread = Thread(dispatcher, "Audio Thread")
}


private fun writeWavFile() {
   val file = File(context.cacheDir.absolutePath + "/" + sampleFileName)
   // missing wav write code
}

1 个答案:

答案 0 :(得分:0)

TarsosDSP提供WriterProcessor类,用于将音频写入文件:

https://github.com/JorenSix/TarsosDSP/blob/c26e5004e203ee79be1ec25c2603b1f11b69d276/src/core/be/tarsos/dsp/writer/WriterProcessor.java

这是您修改的示例:

private var dispatcher =
        AudioDispatcherFactory.fromDefaultMicrophone(SAMPLE_RATE, BUFFER_SIZE, 128)

init {

blankProcessor = object : AudioProcessor {
   override fun processingFinished() {}

   override fun process(audioEvent: AudioEvent): Boolean {
      var buffer = audioEvent.floatBuffer
      val insertPoint = audioBuffer.lastIndex - buffer.lastIndex
      Arrays.copyOfRange(audioBuffer, insertPoint, audioBuffer.size)
                    .copyInto(audioBuffer, 0)
      buffer.copyInto(audioBuffer, insertPoint)
      return true
    }
}

dispatcher.addAudioProcessor(blankProcessor)

// The important bit

val outputFile = File(context.filesDir, "file_name")
val randomAccessFile = RandomAccessFile(outputFile, "rw")
val fileWriter = WriterProcessor(audioFormat, randomAccessFile)

dispatcher.addAudioProcessor(fileWriter)

audioThread = Thread(dispatcher, "Audio Thread")
}