AVMIDIPlayer 有这个初始化器:
initWithData:soundBankURL:error:
这是用于从标准 MIDI 文件读取的初始化程序的补充。
数据是 NSData,我假设它是标准 MIDI 文件格式。那么,如何获取这些数据呢?目前创建 MIDI 序列的方法是 AudioToolbox MusicSequence。 (AVAudioEngine 甚至有这种类型的成员)。
MusicSequence 有这个转换器:
MusicSequenceFileCreateData (
MusicSequence inSequence,
MusicSequenceFileTypeID inFileType,
MusicSequenceFileFlags inFlags,
SInt16 inResolution,
CFDataRef *outData
);
那么让我们尝试一下吧。
var status = OSStatus(noErr)
var data:Unmanaged<CFData>?
status = MusicSequenceFileCreateData (musicSequence,
MusicSequenceFileTypeID(kMusicSequenceFile_MIDIType),
MusicSequenceFileFlags(kMusicSequenceFileFlags_EraseFile),
480, &data)
var ns:NSData = data!.takeRetainedValue()
var error:NSError?
self.mp = AVMIDIPlayer(data: ns, soundBankURL: soundbank, error: &error)
(我之前已经加载过音库)。 好消息:它确实可以播放 MIDI 数据。 坏消息:到达序列末尾时,它崩溃了。
queue = 'CallbackQueue', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
两个猜测。平台代码或(更有可能)我的代码中有错误。
tl;dr 我获取的数据不正确吗?
我因此获得了风滚草徽章!
不管怎样,问题出在AVMIDIPlayer的播放功能上。如果你给它一个 nil 完成处理程序,它会很高兴并且不会崩溃。如果你给它一个完成处理程序,那么 blammo - 崩溃。我已经为完成处理程序尝试了闭包和花园函数。
var completion:AVMIDIPlayerCompletionHandler = {
println("done")
}
tl;博士
这样做:
midiPlayer.play(nil)
不是这个:
midiPlayer.play(completion)