2017-06-21 5 views
2

Ich habe eine AVAudioEngine mit einem benutzerdefinierten AURenderCallback. Als ich den Motor laufen lassen, bis die CPU-Spitzen, und es scheint zu haben, mit der UnsafeMutableBufferPointer.getter und .setter Aktionen:UnsafeMutableBufferPointer langsam bei Verwendung von Getter

func performRender(ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp: UnsafePointer<AudioTimeStamp>, inBusNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>?) -> OSStatus { 

    let blI = UnsafeMutableAudioBufferListPointer(ioData) 

    let numSamples = Int((blI?[0].mDataByteSize)!/UInt32(MemoryLayout<Float32>.stride)) 

    for input in 0 ..< blI!.count{ 

     let bI = blI?[input] 

     guard let inputData = bI?.mData else { 

      //assert(false) 

      return kAudioUnitErr_Uninitialized 
     } 

     let samplesBI = UnsafeMutablePointer<Float32>(inputData.assumingMemoryBound(to: Float32.self)) 

     let samplesI = UnsafeMutableBufferPointer<Float32>(start: samplesBI, count: numSamples) 

     for sampleIndex in 0 ..< samplesI.count { 

      samplesI[sampleIndex] *= 0.5 
     } 

    } 

    return noErr 
} 

Instruments Debug Session

Was dieses ineffiziente Verhalten des Erhaltens verursachen kann und Einstellung der Zeigerdaten? Da es an Audio-Samples arbeitet, führt die Ineffizienz zu Ruckeln im Audiosignal.

Antwort

2

Sie können überspringen die UnsafeMutableBufferPointer() -Aufruf und Index der Probe Zeiger direkt:

let bufferListPtr = UnsafeMutableAudioBufferListPointer(ioData) 
... 
let mBuffer : AudioBuffer = bufferListPtr[0] 
let count = Int(mBuffer.mDataByteSize)/yourSampleSizeInBytes 
let dataPointer = UnsafeMutableRawPointer(mBuffer.mData) 
if let dptr = dataPointer { 
    let sampleArray = dptr.assumingMemoryBound(to: yourSampleType.self) 
    for i in 0..<(count) { 
     let x = sampleArray[i] 
     let y = myModifySample(x) 
     sampleArray[i] = y 
    } 
} 

Ich benutze Int16 für mySampleType (size = 2 Byte), aber es sollte auch für 4-Byte-Typ Float arbeiten .

Die direkte Verwendung des Raw-Speicherzeigers könnte einige Puffer-Getter/Setter-Ineffizienzen (und auch die Validierung, also Vorsicht!) Vermeiden.

Verwandte Themen