Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/110.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在音乐序列中显示当前节拍位置(coreMIDI/Swift)_Ios_Swift_Audiotoolbox_Coremidi - Fatal编程技术网

Ios 在音乐序列中显示当前节拍位置(coreMIDI/Swift)

Ios 在音乐序列中显示当前节拍位置(coreMIDI/Swift),ios,swift,audiotoolbox,coremidi,Ios,Swift,Audiotoolbox,Coremidi,我已经使用coreMIDI和AudioToolBox创建了一个音乐序列,现在想在UI中显示循环序列的当前节拍位置。如果循环只有四个节拍,我希望显示在1,2,3,4之间切换,并返回到1作为序列循环(很像在程序的传输中,如Logic Pro)。我制作了一个函数,它使用MusicSequenceGetBeatsForSeconds()根据自按下play后经过的时间量(使用CFAbsoluteTimeGetCurrent())计算节拍,但这会使值线性增加(在下一次测量节拍时,显示器显示为“5.0”)。如

我已经使用coreMIDI和AudioToolBox创建了一个音乐序列,现在想在UI中显示循环序列的当前节拍位置。如果循环只有四个节拍,我希望显示在1,2,3,4之间切换,并返回到1作为序列循环(很像在程序的传输中,如Logic Pro)。我制作了一个函数,它使用
MusicSequenceGetBeatsForSeconds()
根据自按下play后经过的时间量(使用
CFAbsoluteTimeGetCurrent()
)计算节拍,但这会使值线性增加(在下一次测量节拍时,显示器显示为“5.0”)。如何读取序列的当前节拍?

请查看播放器的功能


根据您想要执行的操作,您可以将虚拟目的地设置为音乐序列的端点,并在其读取块中响应发生的事件。

跳过曲目结束消息;你不能依赖它

而是创建一个
MusicSequenceUserCallback
。然后在序列中添加一个保存用户事件的轨迹。事件中的实际数据并不重要

var event = MusicEventUserData(length: 1, data: (0xAA))
let status = MusicTrackNewUserEvent(markerTrack, endBeat, &event)
然后在回调中查找此任意数据值,并执行您想要执行的操作

let d = eventData.memory
if d.data == 0xAA {

在Swift 2.2中,回调不能是闭包。所以,让它成为一个全局函数。

谢谢@GeneDeLisa,我忽略了
MusicPlayerGetTime
函数。虽然它比我以前使用的
CFAbsoluteTime
的函数干净得多,但即使我的序列在重复,它仍然会让我的节拍线性增加。我查看了从MIDIPacketList中获得的信息,但找不到任何东西可以让我读取测量中的当前位置…你必须原谅我的无知--只是一个钢琴家试图学习编程。或者我应该研究创建一个函数,该函数接收序列中的节拍数,并在循环后重置为1重复?也许您可以查找到达虚拟目的地的MIDI曲目结束消息,并在收到消息时重置计数器。这适用于任何长度,而不仅仅是4拍序列。ps packetList中的每个数据包都有一个时间戳。MIDI曲目结束消息是MIDIMetaEvent,对吗?它看起来像是0x2F类型…虽然我在曲目中添加了MIDIMetaEvent,但似乎无法在数据包列表中读取它,但在这方面遇到了问题…花了一些时间,但最终找到了如何设置用户回调等。非常感谢@GeneDeLisaGlad让它正常工作。关于那些用户事件,有一件事。我之所以把它们放在一个单独的轨道上,是因为如果你将序列保存到一个MDI文件中,然后尝试将其读入另一个应用程序(如Sibelius)中,导入过程将被搞砸——音符的节拍不正确。