播放一个又一个音符的最佳方式是什么?这是我现在拥有的最具功能性的代码。
let majorScale = [60, 62, 64, 65, 67, 69, 71, 72]
for i in majorScale {
sampler.startNote(UInt8(i), withVelocity: 127, onChannel: 1)
sleep(1)
sampler.stopNote(UInt8(i), onChannel: 1)
}
这个方法的问题是sleep()只将UInt8作为参数,所以我不能以这种方式记录不到1秒。
我首先是音乐家。当我参加几个java课程时,我恰好对大学后期的编程有所了解。也就是说,我真的不知道还有其他选择。
我可以用一些内置的MIDI播放器处理音符持续时间吗?
有没有办法“睡眠”不到一秒钟,然后自己计算持续时间?如在1/8音符中以100 bpm播放将持续((60/100)/ 2)= 0.3秒。
我是否应该记录笔记信息并基本上制作一个我可以播放的MIDI文件?
如何最好地解决这个问题?
修改
以下是更新后的代码:
for i in majorScale {
sampler.startNote(UInt8(i), withVelocity: 127, onChannel: 1)
let pause = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 1 * Int64(NSEC_PER_SEC))
dispatch_after(pause, dispatch_get_main_queue()) {
self.sampler.stopNote(UInt8(i), onChannel: 1)
}
sampler.stopNote(UInt8(i), onChannel: 1)
}
所以我意识到了这一点。我把乐器改成了风琴(而不是钢琴),它确实在1秒或10秒之后停止了音符,或者我放在那里的任何东西,但是在此期间似乎它正在进行for循环,所以所有的音符同时发声而不是按顺序发声。
答案 0 :(得分:0)
我无法帮助解决这个问题,但至于暂停或睡眠,你应该使用dispatch_after
。将以下代码放在sleep(1)和stopNote调用的位置。这将允许您以纳秒精度执行延迟。只需将dispatch_time_t()调用的第二个参数更改为您需要的任何时间。
let pause = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 1 * Int64(NSEC_PER_SEC))
dispatch_after(pause, dispatch_get_main_queue()) {
sampler.stopNote(UInt8(i), onChannel: 1)
}
答案 1 :(得分:0)
尝试使用计时器来控制通过notes数组的循环。 音符播放一次后,在下次启动计时器时停止音符。
var playCount = 0
timer = Timer.scheduledTimer(timeInterval: 0.6, target: self, selector: #selector(fireTimerContinue), userInfo: nil, repeats: true)
@objc func fireTimerContinue(){
var note: Int8 = 0
if(index < note_array.count){
note = Int8(note_array[index])
self.audioEngine.sampler.startNote(UInt8(note), withVelocity: UInt8(velocity), onChannel: 0)
playCount += 1
if playCount > 1 {
audioEngine.sampler.stopNote(UInt8(note), onChannel: 0)
playCount = 0
index = index + 1
}
}
}