I’m trying to create a sound recorder using Java Sound API on Kotlin Desktop. I want to automatically stop the recording after 3 seconds. The frame position does initially advance but then gets stuck.
class VoiceRecorder { private val format = AudioFormat( AudioFormat.Encoding.PCM_SIGNED, 16000.0F, 16, 1, 2, 16000.0F, false ) private val info = DataLine.Info(TargetDataLine::class.java, format) private val line = AudioSystem.getLine(info) as TargetDataLine init { if (!AudioSystem.isLineSupported(info)) { println("Line is not supported!!!") }else{ println("Line is supported.") } } fun startRecording(){ line.open() line.start() val recordingStream = AudioInputStream(line) val outputFile = File("src/main/resources/record.wav") val frameRate = format.frameRate runBlocking { while(line.framePosition/frameRate<3.0){ val time = line.framePosition/frameRate delay(100) println("position: ${line.framePosition}, time: $time") } } AudioSystem.write(recordingStream, AudioFileFormat.Type.WAVE, outputFile) line.stop() line.close() } }
This is output of the print statement:
position: 1619, time: 0.0 position: 3219, time: 0.1011875 position: 4835, time: 0.2011875 position: 6435, time: 0.3021875 position: 7999, time: 0.4021875 position: 7999, time: 0.4999375 position: 7999, time: 0.4999375 position: 7999, time: 0.4999375 goes on until you die...
What is causing this and is there a way to fix it?
Advertisement
Answer
The problem was that AudioSystem.write needs to run in a separate coroutine.
For example, add
private val cr = CoroutineScope(Dispatchers.IO)
then do
cr.launch { AudioSystem.write(recordingStream, AudioFileFormat.Type.WAVE, outputFile) } runBlocking { while(line.framePosition/frameRate<3.0){ val time = line.framePosition/frameRate delay(100) println("position: ${line.framePosition}, time: $time") } }