2017-05-17 71 views
2

我试图在Swift中创建连续的FIFO音频记录器。我尝试创建audioQueueCallback时遇到并发出问题。获取音频队列缓冲区的<AudioTimeStamp>

从文档AudioTimeStamp有这个init方法:

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

,我还没有知道如何使用它。

在我看来,设备应该有一个可靠的内部时钟,以便能够管理audioQueue,但我一直无法找到任何文档。

这是我在创造一个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) 
    } 

这里任何意见将不胜感激!

回答

1

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

var timestamp = AudioTimeStamp() 

timestamp.mSampleTime = numberOfSamplesRecorded 
timestamp.mFlags = .sampleHostTimeValid 
+0

谢谢。我想我只是不明白班级是如何工作的,或者如果所有变量都是必要的。我在我的代码中评论过我称之为使用时间戳的地方。我是 – aBikis

+1

是的,这对工会来说是一个混乱的尝试。作为一个快速列举,它会更有意义。 –