Swift SDL 音频回调实现中的噪音和失真

Noise and distortion in Swift implementation of SDL audio callback

我目前正在 Swift 中使用 GME for generating sound buffers and SDL for audio playback. I have previously (and successfully) used SDL_QueueAudio for playback, but I need more fine tuned control over the buffer handling in order to determine song progress, song end etc. So, that leaves me with SDL_AudioCallback in the SDL_AudioSpec API.

为 Mac OS 构建游戏音乐播放器

我能听到这首歌在播放,但伴有噪音和失真(有时会出现回声,具体取决于我的尝试)。

设置

var desiredSpec = SDL_AudioSpec()
desiredSpec.freq = Int32(44100)
desiredSpec.format = SDL_AudioFormat(AUDIO_U8)
desiredSpec.samples = 512
desiredSpec.channels = 2
desiredSpec.callback = { callback(userData: [=11=], stream: , length: ) }

SDL_OpenAudio(&desiredSpec, nil)

回调

func callback(userData: UnsafeMutableRawPointer?, stream: UnsafeMutablePointer<UInt8>?, length: Int32) {
    // Half sample length to compensate for double byte Int16.
    var output = Array<Int16>.init(repeating: 0, count: Int(length / 2))

    // Generates stereo signed Int16 audio samples.
    gme_play(emulator, Int32(output.count), &output)

    // Converts Int16 samples to UInt8 samples expected by the mixer below. Then adds to buffer.
    var buffer = [UInt8]()
    for i in 0 ..< (output.count) {
        let uIntVal = UInt16(bitPattern: output[i])
        buffer.append(UInt8(uIntVal & 0xff))
        buffer.append(UInt8((uIntVal >> 8) & 0xff))
    }

    SDL_MixAudio(stream, buffer, Uint32(length), SDL_MIX_MAXVOLUME)
}

已解决! 最后,这足以让它发挥作用:

desiredSpec.format = SDL_AudioFormat(AUDIO_S16)

var buffer = Array<Int16>(repeating: 0, count: Int(length / 2))
gme_play(emulator, Int32(output.count), &output)
SDL_memcpy(stream, buffer, Int(length))