사용자 지정 AURenderCallback이있는 AVAudioEngine이 있습니다. 엔진을 실행할 때 CPU가 급증하고 UnsafeMutableBufferPointer.getter 및 .setter 작업과 관련이있는 것 같습니다.
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
}
포인터 데이터를 가져오고 설정하는이 비효율적 인 동작의 원인은 무엇입니까? 오디오 샘플에서 작동하기 때문에 비 효율성으로 인해 오디오 신호가 끊깁니다.
UnsafeMutableBufferPointer () 호출을 건너 뛰고 샘플 포인터를 직접 인덱싱 할 수 있습니다.
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
}
}
mySampleType (크기 = 2 바이트)에 Int16을 사용하지만 4 바이트 유형의 Float에서도 작동합니다.
원시 메모리 포인터를 직접 사용하면 버퍼 getter / setter 비 효율성을 피할 수 있습니다 (또한 유효성 검사도 가능하므로주의하십시오!).
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다