Skip to content

Instantly share code, notes, and snippets.

@sgoodwin
Created September 3, 2019 19:01
Show Gist options
  • Save sgoodwin/2f790a70df7a3befca550839e85e41be to your computer and use it in GitHub Desktop.
Save sgoodwin/2f790a70df7a3befca550839e85e41be to your computer and use it in GitHub Desktop.
enum Note: Int {
case C = 0
case Csharp
case D
case Dsharp
case E
case F
case Fsharp
case G
case Gsharp
case A
case Asharp
case B
func shift(_ halfsteps: Int) -> Note {
return Note(rawValue: (self.rawValue + halfsteps) % 12) ?? .C
}
}
enum Mode {
case ionian
case dorian
var sequence: [Int] {
switch self {
case .ionian:
return [0, 0, 0, 0, 0, 0, 0, 0]
case .dorian:
return [0, 0, -1, 0, 0, 0, -1, 0]
}
}
}
func notes(root: Note, mode: Mode) -> [Note] {
let reference = [2, 2, 1, 2, 2, 2, 1]
var base = [Note]()
for i in 0..<8 {
if i == 0 {
base.append(root)
} else {
base.append(base[i-1].shift(reference[i-1]))
}
}
return zip(mode.sequence, base).map { (adjust, note) -> Note in
return note.shift(adjust)
}
}
func prettyPrint(_ notes: [Note]) {
let enharmonics = [
"Csharp": "Db",
"Dsharp": "Eb",
"Fsharp": "Gb",
"Gsharp": "Ab",
"Asharp": "Bb"
]
let result = notes.enumerated().map { (index, note) -> String in
if index == notes.count-1 {
return String(describing: note)
}
if let firstIndex = notes.firstIndex(of: note.shift(-1)), firstIndex < index {
return enharmonics[String(describing: note)] ?? String(describing: note)
} else {
return String(describing: note)
}
}
result.forEach { print($0.replacingOccurrences(of: "sharp", with: "#")) }
}
//prettyPrint(notes(root: .C, mode: .ionian))
//prettyPrint(notes(root: .D, mode: .dorian))
//prettyPrint(notes(root: .C, mode: .dorian))
prettyPrint(notes(root: .A, mode: .ionian))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment