我想知道是否有可能将动态生成的音频不断输出到
DataLine
例如,声音会根据用户输入等某种状态而变化。我正处于可以无限期地写入行的状态,但我只是不断地不间断地写入,而不是根据需要只保留一小段额外的音频缓冲区。除了打电话,有没有别的办法
Thread.sleep
在循环中缓冲的持续时间?
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer
import javax.sound.sampled.*
import kotlin.math.PI
import kotlin.math.sin
const val SAMPLING_RATE = 44100F
const val BITS16 = 16
const val STEREO = 2
val format = AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
SAMPLING_RATE,
BITS16,
STEREO,
BITS16 * STEREO / 8,
SAMPLING_RATE * BITS16 * STEREO / 8,
false)
const val BUFFER_SIZE = 4096
var phase = 0F
fun generateBuffer(n: Int, buffer: FloatBuffer) {
// Some potentially state-sensitive audio generation procedure. Generating a pure sine as an example.
repeat(n) {buffer.put(sin((phase + it * 2 * PI * 440 / 44100F).toFloat()))}
phase += (n * 2 * PI * 440 / 44100F).toFloat()
}
fun main() {
val dataLineInfo = DataLine.Info(
SourceDataLine::class.java,
format)
val dataLine = AudioSystem.getLine(dataLineInfo) as SourceDataLine
dataLine.open()
val byteBuffer = ByteBuffer.allocate(2 * 2 * BUFFER_SIZE).order(ByteOrder.LITTLE_ENDIAN)
val intBuffer = byteBuffer.asIntBuffer()
val floatBuffer = FloatBuffer.allocate(BUFFER_SIZE)
dataLine.start()
// This just generates and writes data nonstop. Can I generate chunks of audio on-demand as they are exhausted?
while (true) {
floatBuffer.rewind()
generateBuffer(BUFFER_SIZE, floatBuffer)
floatBuffer.rewind()
intBuffer.rewind()
repeat(BUFFER_SIZE) { intBuffer.put((floatBuffer.get() * 32767).toInt()) }
dataLine.write(byteBuffer.array(), 0, 2 * 2 * BUFFER_SIZE)
}
}