AURenderCallback在Swift中
我正在创build一个使用audio单元的应用程序,尽pipe在Objective-C(包括苹果自己的aurioTouch和其他)中有很多代码示例,但我试图在Swift中编写整个代码。
我已经能够build立我的AUGraph并通过它运行一些audio,但我似乎无法弄清楚回显的callback语法。 我已经尝试了几种方法:
方法1:直接创build一个AURenderCallback
let render : AURenderCallback = { ( inRefCon: UnsafeMutablePointer<Void>, ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp: UnsafePointer<AudioTimeStamp>, inBufNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus in return noErr }
在这个callback中,除了返回noErr之外,我什么都没有做,因为我只是想让它工作。 但是,编译器返回以下错误:
(UnsafeMutablePointer,UnsafeMutablePointer,UnsafePointer,UInt32,UInt32,UnsafeMutablePointer) – > OSStatus'不能转换为'AURenderCallback
AURenderCallback在文档中的定义是这样的:
typealias AURenderCallback = (UnsafeMutablePointer<Void>,UnsafeMutablePointer<AudioUnitRenderActionFlags>,UnsafePointer<AudioTimeStamp>, UInt32, UInt32,UnsafeMutablePointer<AudioBufferList>) -> OSStatus
这似乎与我所input的一样,虽然可能是我不明白文档要求什么。
方法2:创build一个代表AURenderCallback的函数
func render( inRefCon: UnsafeMutablePointer<Void>, ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp: UnsafePointer<AudioTimeStamp>, inBufNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus { return noErr }
这不会给任何错误作为一个函数,但是当我把它放入inputProc参数AURenderCallbackStruct中时,我收到一个错误:
(InputProc:(UnsafeMutablePointer,UnsafeMutablePointer,UnsafePointer,UInt32,UInt32,UnsafeMutablePointer) – > OSStatus,inputProcRefCon:nil)无法findtypes为“AURenderCallbackStruct”的初始化程序。
我还没有发现在Swift中创buildAURenderCallbacks的很多例子,与Objective-C相比,在语法上似乎有很大的不同。 任何帮助,将不胜感激。
我只是find你的文章,试图找出相同的(这是不容易find示例代码和CoreAudio /audio单元和Swift结合的例子)。
通过查看这个仓库和阅读(几次:-))苹果关于使用cocoa和Objective-C的Swift的文档,我设法把东西拼凑在一起。 正如它在Function Pointers
部分所述
当调用一个带有函数指针参数的函数时,可以传递一个顶级Swift函数,一个闭包文字或者nil。
所以。 在我的课外,我有一个如下所示的方法:
func renderCallback(inRefCon:UnsafeMutablePointer<Void>, ioActionFlags:UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp:UnsafePointer<AudioTimeStamp>, inBusNumber:UInt32, inNumberFrames:UInt32, ioData:UnsafeMutablePointer<AudioBufferList>) -> OSStatus { let delegate = unsafeBitCast(inRefCon, AURenderCallbackDelegate.self) let result = delegate.performRender(ioActionFlags, inTimeStamp: inTimeStamp, inBusNumber: inBusNumber, inNumberFrames: inNumberFrames, ioData: ioData) return result }
正如你所看到的,我只是在这里打电话给一个代表。 这个委托是这样宣布的(也在课外,但你已经知道:-))
@objc protocol AURenderCallbackDelegate { func performRender(ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp: UnsafePointer<AudioTimeStamp>, inBusNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus }
这样做可以让我“回到我的课堂”,通过符合AURenderCallbackDelegate
像这样:
class AudioUnitGraphManager: NSObject, AURenderCallbackDelegate
然后在我的renderCallback
类中实现renderCallback
方法
func performRender(ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp: UnsafePointer<AudioTimeStamp>, inBusNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus { print("Hello there!") return noErr }
拼图的最后一部分是实际启用渲染通知callback,我这样做:
AudioUnitAddRenderNotify(mixerUnit, renderCallback, UnsafeMutablePointer(unsafeAddressOf(self)))
希望这给你一些继续斗争。
Swift中的变化3
在Swift 3中, AURenderCallback
的声明已经更改为:
typealias AURenderCallback = (UnsafeMutableRawPointer, UnsafeMutablePointer<AudioUnitRenderActionFlags>, UnsafePointer<AudioTimeStamp>, UInt32, UInt32, UnsafeMutablePointer<AudioBufferList>?) -> OSStatus
注意最后一个参数是UnsafeMutablePointer<AudioBufferList>?
与之前的UnsafeMutablePointer<AudioBufferList>
相比(现在是可选的)。
这意味着代码现在看起来像这样。
renderCallback
函数
func renderCallback(inRefCon:UnsafeMutablePointer<Void>, ioActionFlags:UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp:UnsafePointer<AudioTimeStamp>, inBusNumber:UInt32, inNumberFrames:UInt32, ioData:UnsafeMutablePointer<AudioBufferList>?) -> OSStatus { let delegate = unsafeBitCast(inRefCon, AURenderCallbackDelegate.self) let result = delegate.performRender(ioActionFlags, inTimeStamp: inTimeStamp, inBusNumber: inBusNumber, inNumberFrames: inNumberFrames, ioData: ioData) return result }
AURenderCallbackDelegate
协议
@objc protocol AURenderCallbackDelegate { func performRender(ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp: UnsafePointer<AudioTimeStamp>, inBusNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>?) -> OSStatus }
performRender
的实际执行
func performRender(ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp: UnsafePointer<AudioTimeStamp>, inBusNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>?) -> OSStatus { print("Hello there!") return noErr }
启用渲染通知callback
AudioUnitAddRenderNotify(mixerUnit!, renderCallback, Unmanaged.passUnretained(self).toOpaque())