Skip to content

Instantly share code, notes, and snippets.

@tatat
Created February 12, 2019 03:30
Show Gist options
  • Save tatat/3ec5c318e5e6d2abe233c9ac335343c4 to your computer and use it in GitHub Desktop.
Save tatat/3ec5c318e5e6d2abe233c9ac335343c4 to your computer and use it in GitHub Desktop.
Some notes don't play a sound.
import Foundation
import AVFoundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
// NOTE: ~/Documents/Shared Playground Data/GeneralUser GS v1.471.sf2
// http://schristiancollins.com/generaluser.php
let url = PlaygroundSupport.playgroundSharedDataDirectory.appendingPathComponent("GeneralUser GS v1.471.sf2")
let engine = AVAudioEngine()
let sampler = AVAudioUnitSampler()
engine.attach(sampler)
engine.connect(sampler, to: engine.mainMixerNode, format: nil)
try engine.start()
try sampler.loadSoundBankInstrument(at: url,
program: 12,
bankMSB: UInt8(kAUSampler_DefaultMelodicBankMSB),
bankLSB: UInt8(kAUSampler_DefaultBankLSB))
var playingNotes = [UInt8: Timer]()
func randomNote() -> UInt8 {
let scale = [0, 4, 7, 9].randomElement()!
let octave = [-12, 0, 12].randomElement()!
return UInt8(60 + scale + octave)
}
func randomNotes() -> [UInt8] {
let count = (1..<4).randomElement()!
var notes = [UInt8]()
while notes.count != count {
let note = randomNote()
if !notes.contains(note) {
notes.append(note)
}
}
return notes
}
func playSingleNote(_ note: UInt8, _ duration: Double) {
if let timer = playingNotes.removeValue(forKey: note) {
timer.invalidate()
sampler.stopNote(note, onChannel: 0)
}
sampler.startNote(note, withVelocity: 127, onChannel: 0)
playingNotes[note] = Timer.scheduledTimer(withTimeInterval: duration,
repeats: false,
block: { [weak sampler] timer in sampler?.stopNote(note, onChannel: 0) })
}
func playNotes(_ duration: Double) {
let notes = randomNotes()
notes.forEach { playSingleNote($0, duration) }
print("Notes: \(notes)")
}
let tempo = 120.0
let duration = 60.0 / (tempo * 2.0)
Timer.scheduledTimer(withTimeInterval: duration,
repeats: true,
block: { _ in playNotes(duration) })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment