2016-07-21 8 views
1

Я пытаюсь воспроизвести чистый синусоидальный звук с использованием Core Audio AudioQueue (Swift 3).Поппинг-шум между AudioQueueBuffers

Он играет красиво, но я получаю шум при каждом вызове 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 с просто кнопку "играть" (тета хранимая собственности на этом 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 
     } 
    } 
} 

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

Любая помощь будет принята с благодарностью.

ответ

0

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

+0

Я думал, что это может быть проблемой, но этот журнал показывает последние 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. Как видите, фаза правильная. –