Java/Kotlin record microphone input and detect volume concurrently without distortion

99 views Asked by At

I am creating a "Voice Recorder" app using Kotlin Multiplatform for Windows/Desktop. I got basic working functionality using the Java Sound API to record microphone input and save it to a file with the below:

val format = AudioFormat(41000f, 16, 1, true, false)
val targetDataLine = AudioSystem.getTargetDataLine(format)
targetDataLine.open(format)
targetDataLine.start()

val audioInputStream = AudioInputStream(targetDataLine)
val outputFile = File("recording.wav")

AudioSystem.write(audioInputStream, Type.WAVE, outputFile)

Now I'm trying to add a new feature which shows the volume of the audio being recorded to give some UI feedback. The problem is that as I attempt to add this feature, the audio recording seriously degrades. I'm mainly running into chunks of sound like it's in "fast-forward". (Please note that I'm not trained in audio particularly so I'm learning as I go).

My most recent attempt is to add in using the TarsusDSP library. I came up with this so far and it's getting better but still not the quality I'm expecting.

val format = AudioFormat(41000f, 16, 1, true, false)
val tarsosFormat = TarsosDSPAudioFormat(41000f, 16, 1, true, false)
val targetDataLine = AudioSystem.getTargetDataLine(format)
val outputFile = File("recording.wav")
val writer = WaveformWriter(tarsosFormat, outputFile.path)
targetDataLine.open(format)
targetDataLine.start()

val audioInputStream = AudioInputStream(targetDataLine)
val jvmAudioInputStream = JVMAudioInputStream(audioInputStream)
val bufferSize = 1024

/* increasing the buffer size has lessened the 'fast forward' effect, 
 * but causes audio to get cut a bit when stopped
 */
val dispatcher = AudioDispatcher(jvmAudioInputStream, bufferSize * 32, 0)
dispatcher.addAudioProcessor(object: AudioProcessor {
   override fun process(event: AudioEvent?): Boolean {
      onVolumeLevelCaptured(event?.rms ?: 0.0) // UI function to show the volume in visual form
      return true
   }
   override fun processingFinished() {}
})
dispatcher.addAudioProcessor(writer)
dispatcher.run()

So my question is, how can I safely acheive extracting the volume without damaging the quality of the audio input?

0

There are 0 answers