代码之家  ›  专栏  ›  技术社区  ›  user2649681

实时生成音频以写入“SourceDataLine”`

  •  0
  • user2649681  · 技术社区  · 3 月前

    我想知道是否有可能将动态生成的音频不断输出到 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)
        }
    }
    
    0 回复  |  直到 3 月前