Появление шума между AudioQueueBuffers

Я пытаюсь воспроизвести чистый синусоидальный тон, используя Core Audio AudioQueue (Swift 3).

Он играет хорошо, но я получаю хлопающие звуки каждый раз, когда вызывается мой AudioQueueOutputCallback для заполнения нового буфера аудиоданными.

Мой класс AudioStreamer выглядит так:

let kNumberBuffers = 3

protocol AudioStreamerDelegate {
    func requestAudioData() -> [Float]
}

let sampleRate = 48000.0
let bufferSize = Int(sampleRate) / 50
let bufferByteSize = UInt32(bufferSize * sizeof(Float)) // 20 mili sec of audio

class AudioStreamer {
    var delegate: AudioStreamerDelegate

    var outputQueue: AudioQueueRef?

    var buffers = [AudioQueueBufferRef?](repeatElement(nil, count: kNumberBuffers))

    var streamBasicDescription = AudioStreamBasicDescription(
        mSampleRate: sampleRate,
        mFormatID: kAudioFormatLinearPCM,
        mFormatFlags: kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved,
        mBytesPerPacket: UInt32(sizeof(Float)),
        mFramesPerPacket: 1,
        mBytesPerFrame: UInt32(sizeof(Float)),
        mChannelsPerFrame: 1,
        mBitsPerChannel: UInt32(8 * sizeof(Float)),
        mReserved: 0
    )

    init(delegate: AudioStreamerDelegate) {
        // create new output audio queue
        self.delegate = delegate
    }

    func play() {
        let queue = DispatchQueue.main

        queue.async(execute: {
            let selfPointer = unsafeBitCast(self, to: UnsafeMutablePointer<Void>.self)
            AudioQueueNewOutput(
                &self.streamBasicDescription,
                AudioStreamerOuputCallback,
                selfPointer,
                nil,
                nil,
                0,
                &self.outputQueue
            )

            // allocate buffers
            for i in 0 ..< kNumberBuffers {
                AudioQueueAllocateBuffer(
                    self.outputQueue!,
                    bufferByteSize,
                    &self.buffers[i]
                )

                if let bufferRef = self.buffers[i] {
                    // configure audio buffer
                    let selfPointer = unsafeBitCast(self, to: UnsafeMutablePointer<Void>.self)
                    bufferRef.pointee.mUserData = selfPointer
                    bufferRef.pointee.mAudioDataByteSize = bufferByteSize
                }
            }

            AudioQueuePrime(self.outputQueue!, 0, nil)
            for bufferRef in self.buffers {
                AudioStreamerOuputCallback(userData: unsafeBitCast(self, to: UnsafeMutablePointer<Void>.self), queueRef: self.outputQueue!, buffer: bufferRef!)
            }
            AudioQueueStart(self.outputQueue!, nil)
        })
    }
}

func AudioStreamerOuputCallback(userData: Optional<UnsafeMutablePointer<Void>>, queueRef: AudioQueueRef, buffer: AudioQueueBufferRef) {
    let this = Unmanaged<AudioStreamer>.fromOpaque(OpaquePointer(userData!)).takeUnretainedValue()
    let audioData = this.delegate.requestAudioData()

    memcpy(buffer.pointee.mAudioData, unsafeBitCast(audioData, to: UnsafeMutablePointer<Void>.self), Int(bufferByteSize))
    AudioQueueEnqueueBuffer(queueRef, buffer, 0, nil)
}

Метод генератора аудиоданных класса ViewController с помощью кнопки «воспроизведение» (theta — это сохраненное свойство этого ViewController):

func generateAudioData(frequency: Double) {
    semaphore.wait()

    let amplitude: Double = 0.25

    let theta_increment: Double = 2.0 * M_PI * frequency / sampleRate

    for j in 0 ..< Int(bufferSize) {
        audioData[j] = Float(sin(theta) * amplitude)
        theta += theta_increment

        if theta > 2.0 * M_PI {
            theta -= 2.0 * M_PI
        }
    }
}

Проблема выглядит примерно так же, как в этом вопросе, но никто ответил.

Любая помощь будет оценена.


person Jose L. Fdez-Mayoralas    schedule 21.07.2016    source источник


Ответы (1)


В обратном вызове вывода вы не создали новый набор аудиоданных, где фаза первого сэмпла нового буфера является приращением последнего семпла из предыдущего буфера.

person hotpaw2    schedule 21.07.2016
comment
Я думал, что это может быть проблемой, но этот лог показывает последние 4 выборки las буфера и первые 4 выборки текущего: 956 - -0.051978 - 957 - -0.039109 958 - -0.026132 959 - -0.013084 0 - 0,000000 1 - 0,013084 2 - 0,026132 3 - 0,039109. Как видите, фаза правильная. - person Jose L. Fdez-Mayoralas; 21.07.2016