获取<AudioTimeStamp>音频队列缓冲区



我正在尝试在 Swift 中创建一个连续的 FIFO 录音机。我在尝试创建音频队列回调时遇到并出现问题。

从文档中AudioTimeStamp有这个 init 方法:

AudioTimeStamp(mSampleTime: Float64, mHostTime: UInt64, mRateScalar: Float64, mWordClockTime: UInt64, mSMPTETime: SMPTETime, mFlags: AudioTimeStampFlags, mReserved: UInt32)

而且我不知道如何使用它。

在我看来,该设备应该有一个可靠的内部时钟来管理音频队列,但我无法找到任何文档。

这是我创建 BufferQueue 的尝试:

ypealias WYNDRInputQueueCallback = ((Data) -> Void)
class WYNDRInputQueue {
  class WYNDRInputQueueUserData {
    let callback: WYNDRInputQueueCallback
    let bufferStub: NSData
    init(callback: @escaping WYNDRInputQueueCallback, bufferStub: NSData){
      self.callback = callback
      self.bufferStub = bufferStub
    }
  }

  private var audioQueueRef: AudioQueueRef?
  private let userData: WYNDRInputQueueUserData

  public init(asbd: inout AudioStreamBasicDescription, callback: @escaping WYNDRInputQueueCallback, buffersCount: UInt32 = 3, bufferSize: UInt32 = 9600) throws {
    self.userData = WYNDRInputQueueUserData(callback: callback, bufferStub: NSMutableData(length: Int(bufferSize))!)
    let userDataUnsafe = UnsafeMutableRawPointer(Unmanaged.passRetained(self.userData).toOpaque())
    let input = AudioQueueNewInput(&asbd,
                                   audioQueueInputCallback,
                                   userDataUnsafe,
                                   .none,
                                   .none,
                                   0,
                                   &audioQueueRef)
    if input != noErr {
      throw InputQueueError.genericError(input)
    }
    assert(audioQueueRef != nil )
    for _ in 0..<buffersCount {
      var bufferRef: AudioQueueBufferRef?
      let bufferInput = AudioQueueAllocateBuffer(audioQueueRef!, bufferSize, &bufferRef)
      if bufferInput != noErr {
        throw InputQueueError.genericError(bufferInput)
      }
      assert(bufferRef != nil)

这是我使用 audioTimeStamp 的地方:

      audioQueueInputCallback(userDataUnsafe, audioQueueRef!, bufferRef!, <#T##UnsafePointer<AudioTimeStamp>#>, 0, nil)
    }
  }
  private let audioQueueInputCallback: AudioQueueInputCallback = { (inUserData, inAQ, inBuffer, inStartTime, inNumberPacketDescriptions, inPacketDescs) in
    let userData = Unmanaged<WYNDRInputQueueUserData>.fromOpaque(inUserData!).takeUnretainedValue()
    let dataSize = Int(inBuffer.pointee.mAudioDataByteSize)
    let inputData = Data(bytes: inBuffer.pointee.mAudioData, count: dataSize)
    userData.callback(inputData)
    AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, nil)
  }

这里的任何建议将不胜感激!

我不确定时间戳将如何使用或谁将使用它,但如果有疑问,为什么不使用您记录的样本数量作为时间戳?

var timestamp = AudioTimeStamp()
timestamp.mSampleTime = numberOfSamplesRecorded
timestamp.mFlags = .sampleHostTimeValid

最新更新