如何使用Swift采样器播放音调,然后在播放下一个音调之前暂停一下? [英] How do I use the Swift sampler to play a tone then pause before playing the next?
问题描述
我有代码来将字符串中的字母序列解释为注释.然后,代码将播放音符.问题在于它们都同时播放.我该如何将它们分别演奏为四分音符,本质上是演奏一个音符,等待其结束,然后再演奏下一个音符?
I have code to take a sequence of letters in a string and interpret them as notes. The code will then play the notes. The problem is that they all play at the same time. How do I play them each as a quarter note, essentially to play a note, wait for it to end, and then play the next note?
@IBAction func playButton(sender: AnyObject) {
fractalEngine.output = "adgadefe"
var notes = Array(fractalEngine.output.characters)
var counter = 0
while counter < notes.count {
var note = notes[counter]
if note == "a" {
play(58)
}
else if note == "b" {
play(59)
}
else if note == "c" {
play(60)
}
else if note == "d" {
play(61)
}
else if note == "e" {
play(62)
}
else if note == "f" {
play(63)
}
else {
play(64)
}
counter += 1
}
//self.sampler.startNote(60, withVelocity: 64, onChannel: 0)
}
func play(note: UInt8) {
sampler.startNote(note, withVelocity: 64, onChannel: 0)
}
func stop(note: UInt8) {
sampler.stopNote(note, onChannel: 0)
}
以下是启动采样器的代码:
Here's the code that initiates the sampler:
func initAudio(){
engine = AVAudioEngine()
self.sampler = AVAudioUnitSampler()
engine.attachNode(self.sampler)
engine.connect(self.sampler, to: engine.outputNode, format: nil)
guard let soundbank = NSBundle.mainBundle().URLForResource("gs_instruments", withExtension: "dls") else {
print("Could not initalize soundbank.")
return
}
let melodicBank:UInt8 = UInt8(kAUSampler_DefaultMelodicBankMSB)
let gmHarpsichord:UInt8 = 6
do {
try engine.start()
try self.sampler.loadSoundBankInstrumentAtURL(soundbank, program: gmHarpsichord, bankMSB: melodicBank, bankLSB: 0)
}catch {
print("An error occurred \(error)")
return
}
/*
self.musicSequence = createMusicSequence()
createAVMIDIPlayer(self.musicSequence)
createAVMIDIPlayerFromMIDIFIle()
self.musicPlayer = createMusicPlayer(musicSequence)
*/
}
推荐答案
您似乎需要延迟依次轮流播放.这是一个实现(避免阻塞主线程).
It looks like you need to delay playing each in turn. Here's one implementation (that avoids blocking the main thread).
//global delay helper function
func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
//inside your playButton
let delayConstant = 0.05 //customize as needed
for (noteNumber, note) in notes.enumerate() {
delay(delayConstant * noteNumber) {
play(note)
//handle stopping
delay(delayConstant) {stop(note)}
}
}
此操作是在逐步增加的延迟后播放每个音符,然后在音符长度(假定为延迟常数)之后停止播放.
What this does is plays each note after an escalating delay, then stops playing after note length, which is assumed to be the delay constant.
这篇关于如何使用Swift采样器播放音调,然后在播放下一个音调之前暂停一下?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!