2017-05-17 2 views
2

Ich versuche, einen kontinuierlichen FIFO-Audio-Recorder in Swift zu erstellen. Ich stoße auf und versuche es, um den audioQueueCallback zu erstellen.Erhalten Sie einen <AudioTimeStamp> für Audio Queue Buffer

Aus den docs AudioTimeStamp hat diese Methode init:

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

Und ich habe nicht Ahnung, wie es zu benutzen.

Es scheint mir, dass das Gerät eine zuverlässige interne Uhr haben sollte, um audioQueues aus zu verwalten, aber ich konnte keine Dokumentation dafür finden.

Hier ist mein Versuch, eine BufferQueue erstellen:

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) 

Hier ist, wo ich die audioTimeStamp bin mit:

hier
 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) 
    } 

Jede Beratung wäre sehr dankbar!

Antwort

1

Ich bin mir nicht sicher, wie der Zeitstempel verwendet wird oder wer ihn benutzt, aber wenn Sie Zweifel haben, warum nicht die Anzahl der Samples verwenden, die Sie als Zeitstempel aufgenommen haben?

var timestamp = AudioTimeStamp() 

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

Danke. Ich glaube, ich habe einfach nicht verstanden, wie die Klasse funktioniert hat oder ob alle Variablen notwendig sind. Ich habe in meinem Code kommentiert, wo ich den Zeitstempel benutze. I – aBikis

+1

Ja, es ist ein unordentlicher Versuch einer Vereinigung. Es wäre viel sinnvoller als eine schnelle Aufzählung. –

Verwandte Themen