How to pass custom object in MTAudioProcessingTapCallbacks?

I wrote the code below to pass my custom object Engine in MTAudioProcessingTapCallbacks Here is code:

func getTap() -> MTAudioProcessingTap? {
    var tap: Unmanaged<MTAudioProcessingTap>?
     
    func onInit(tap:MTAudioProcessingTap,clientInfo:UnsafeMutableRawPointer?,tagStroageOut:UnsafeMutablePointer<UnsafeMutableRawPointer?>) {
       
      let engine = Engine()
      tagStroageOut.pointee = Unmanaged<Engine>.passUnretained(engine).toOpaque()
    }
     
     
    var callback = MTAudioProcessingTapCallbacks(version: kMTAudioProcessingTapCallbacksVersion_0, clientInfo:nil, init: onInit, finalize: nil, prepare: nil, unprepare: nil) { tap, numberFrames, flags, bufferListInOut, numberFramesOut, flagsOut in
       
      guard MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, flagsOut, nil, numberFramesOut) == noErr else {
        preconditionFailure()
      }
       
      let storage = MTAudioProcessingTapGetStorage(tap)
      let engine = Unmanaged<Engine>.fromOpaque(storage).takeUnretainedValue()
       
      // This line crashed :
      // ClientProcessingTapManager (14): EXC_BAD_ACCESS (code=1, address=0x544453e46ea0)
      engine.dealWith(bufferPtr: bufferListInOut)
    }
    guard MTAudioProcessingTapCreate(kCFAllocatorDefault, &callback, kMTAudioProcessingTapCreationFlag_PostEffects, &tap) == noErr else{
      fatalError()
    }
    return tap?.takeRetainedValue()
  }
}

How can I do it?

Answered by luckysmg in 695016022

  let tapInit: MTAudioProcessingTapInitCallback = {
      (tap, clientInfo, tapStorageOut) in
      tapStorageOut.pointee = clientInfo
    }



 var callback = MTAudioProcessingTapCallbacks(version: kMTAudioProcessingTapCallbacksVersion_0, clientInfo:UnsafeMutableRawPointer(Unmanaged.passUnretained(self.engine).toOpaque()), init: tapInit, finalize: tapFinalize, prepare: tapPrepare, unprepare: tapUnprepare) { tap, numberFrames, flags, bufferListInOut, numberFramesOut, flagsOut in
       
      guard MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, flagsOut, nil, numberFramesOut) == noErr else {
        preconditionFailure()
      }

      let storage = MTAudioProcessingTapGetStorage(tap)
      let engine = Unmanaged<Engine>.fromOpaque(storage).takeUnretainedValue()
      engine.render(bufferPtr: bufferListInOut)
      
    }




Accepted Answer

  let tapInit: MTAudioProcessingTapInitCallback = {
      (tap, clientInfo, tapStorageOut) in
      tapStorageOut.pointee = clientInfo
    }



 var callback = MTAudioProcessingTapCallbacks(version: kMTAudioProcessingTapCallbacksVersion_0, clientInfo:UnsafeMutableRawPointer(Unmanaged.passUnretained(self.engine).toOpaque()), init: tapInit, finalize: tapFinalize, prepare: tapPrepare, unprepare: tapUnprepare) { tap, numberFrames, flags, bufferListInOut, numberFramesOut, flagsOut in
       
      guard MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, flagsOut, nil, numberFramesOut) == noErr else {
        preconditionFailure()
      }

      let storage = MTAudioProcessingTapGetStorage(tap)
      let engine = Unmanaged<Engine>.fromOpaque(storage).takeUnretainedValue()
      engine.render(bufferPtr: bufferListInOut)
      
    }




How to pass custom object in MTAudioProcessingTapCallbacks?
 
 
Q