2017-05-17 9 views
2

Swift에서 연속 FIFO 오디오 레코더를 만들려고합니다. audioQueueCallback을 만들려고 노력하는 중에 문제가 있습니다. 워드 프로세서 AudioTimeStamp에서Audio Queue Buffer에 대해 <AudioTimeStamp>를 얻습니다.

이 init 메소드가 있습니다

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

을 그리고 나는 그것을 사용하는 방법을 생각하지 않았습니다.

기기에서 audioQueues를 관리 할 수있는 기기가 안정적인 내부 시계를 가지고 있어야하지만 모든 문서를 찾을 수 없었던 것 같습니다. 나는 audioTimeStamp을 사용하고 어디에

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) 

은 다음과 같습니다 :

는 여기 BufferQueue를 작성하려고 시도한이다

여기
 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

감사합니다. 클래스가 어떻게 작동했는지, 또는 변수가 모두 필요한지는 이해하지 못했을 것입니다. 나는 타임 스탬프를 사용하는 곳에서 코드에 주석을 달았다. I – aBikis

+1

네, 노조에서 지저분한 시도입니다. 신속한 열거로 훨씬 더 의미가 있습니다. –