2016-06-10 10 views
0

Ich habe Code, um eine Folge von Buchstaben in einer Zeichenfolge zu nehmen und sie als Notizen zu interpretieren. Der Code wird dann die Noten spielen. Das Problem ist, dass sie alle gleichzeitig spielen. Wie spiele ich sie jeweils als Viertelnote, im Wesentlichen um eine Note zu spielen, zu warten bis sie endet und dann die nächste Note spielt?Wie verwende ich den Swift-Sampler, um einen Ton zu spielen, dann pausiere, bevor ich den nächsten spiele?

@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) 

} 

Hier ist der Code, der den Sampler initiiert:

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) 
    */ 

} 

Antwort

1

Es sieht aus wie Sie jede wiederum verzögern müssen spielen. Hier ist eine Implementierung (die verhindert, dass der Hauptthread blockiert wird).

//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)} 
    } 
} 

Was das bedeutet ist, spielt jede Note nach einer eskalierenden Verzögerung, dann stoppt nach Notenlänge zu spielen, von der angenommen wird die Verzögerung konstant ist.

+0

Vielen Dank, das hat perfekt funktioniert! – c0rv0s

Verwandte Themen