Fir*_*ers 5 xcode audiounit ios swift
我正在创建一个使用Audio Units的应用程序,虽然Objective-C中有很多代码示例(包括Apple自己的aurioTouch等),但我试图在Swift中编写整个代码.
我已经能够设置我的AUGraph并通过它运行一些音频,但我似乎无法弄清楚渲染回调的语法.我尝试了几种方法:
方法1:直接创建AURenderCallback
let render : AURenderCallback = { (
inRefCon: UnsafeMutablePointer<Void>,
ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>,
inTimeStamp: UnsafePointer<AudioTimeStamp>,
inBufNumber: UInt32,
inNumberFrames: UInt32,
ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus in
return noErr
}
Run Code Online (Sandbox Code Playgroud)
因为我只是想让它工作,所以除了在此时返回noErr之外我在这个回调中什么都不做.但是,编译器返回以下错误:
(UnsafeMutablePointer,UnsafeMutablePointer,UnsafePointer,UInt32,UInt32,UnsafeMutablePointer) - > OSStatus'无法转换为'AURenderCallback
文档中AURenderCallback的定义如下:
typealias AURenderCallback = (UnsafeMutablePointer<Void>,UnsafeMutablePointer<AudioUnitRenderActionFlags>,UnsafePointer<AudioTimeStamp>, UInt32, UInt32,UnsafeMutablePointer<AudioBufferList>) -> OSStatus
Run Code Online (Sandbox Code Playgroud)
它似乎与我输入的相同,尽管可能是我不明白文档要求的内容.
方法2:创建表示AURenderCallback的函数
func render(
inRefCon: UnsafeMutablePointer<Void>,
ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>,
inTimeStamp: UnsafePointer<AudioTimeStamp>,
inBufNumber: UInt32,
inNumberFrames: UInt32,
ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus {
return noErr
}
Run Code Online (Sandbox Code Playgroud)
这不会将任何错误作为函数提供,但是当我将它放入inputProc参数中的AURenderCallbackStruct时,我收到一个错误:
找不到类型'AURenderCallbackStruct'的初始值设定项,它接受类型'的参数列表'(inputProc:(UnsafeMutablePointer,UnsafeMutablePointer,UnsafePointer,UInt32,UInt32,UnsafeMutablePointer) - > OSStatus,inputProcRefCon:nil)
我没有找到很多在Swift中创建AURenderCallbacks的例子,与Objective-C相比,语法似乎有很大差异.任何帮助,将不胜感激.
我刚刚发现你的帖子,同时试图找出相同的结果(找到结合CoreAudio/Audio Unit和Swift的示例代码和示例并不容易).
通过查看此存储库并阅读(几次:-))关于将Swift与Cocoa和Objective-C一起使用的 Apples文档我设法将某些内容组合在一起.正如它在章节中所述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
}
Run Code Online (Sandbox Code Playgroud)
如你所见,我只是在这里召集代表.那个代表是这样声明的(也在课外,但你已经知道:-))
@objc protocol AURenderCallbackDelegate {
func performRender(ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>,
inTimeStamp: UnsafePointer<AudioTimeStamp>,
inBusNumber: UInt32,
inNumberFrames: UInt32,
ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus
}
Run Code Online (Sandbox Code Playgroud)
这样做使我能够通过符合这样的方式"回到我的班级" AURenderCallbackDelegate:
class AudioUnitGraphManager: NSObject, AURenderCallbackDelegate
然后renderCallback在我的AudioUnitGraphManager课堂上实现该方法
func performRender(ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp: UnsafePointer<AudioTimeStamp>, inBusNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>) -> OSStatus {
print("Hello there!")
return noErr
}
Run Code Online (Sandbox Code Playgroud)
最后一个难题是实际启用渲染通知回调,我喜欢这样:
AudioUnitAddRenderNotify(mixerUnit, renderCallback, UnsafeMutablePointer(unsafeAddressOf(self)))
希望这能让你继续奋斗.
在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
}
Run Code Online (Sandbox Code Playgroud)
AURenderCallbackDelegate协议@objc protocol AURenderCallbackDelegate {
func performRender(ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>,
inTimeStamp: UnsafePointer<AudioTimeStamp>,
inBusNumber: UInt32,
inNumberFrames: UInt32,
ioData: UnsafeMutablePointer<AudioBufferList>?) -> OSStatus
}
Run Code Online (Sandbox Code Playgroud)
performRender func performRender(ioActionFlags: UnsafeMutablePointer<AudioUnitRenderActionFlags>, inTimeStamp: UnsafePointer<AudioTimeStamp>, inBusNumber: UInt32, inNumberFrames: UInt32, ioData: UnsafeMutablePointer<AudioBufferList>?) -> OSStatus {
print("Hello there!")
return noErr
}
Run Code Online (Sandbox Code Playgroud)
AudioUnitAddRenderNotify(mixerUnit!, renderCallback, Unmanaged.passUnretained(self).toOpaque())
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2366 次 |
| 最近记录: |