From 917b5f1bf523b34be2cc0e5a9a1fcb337e78867b Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Sat, 17 Dec 2016 19:32:31 -0800 Subject: [PATCH 01/19] * refactoring stuff --- MusicKit.xcodeproj/project.pbxproj | 6 ++++++ MusicKit/Extensions.swift | 26 ++++++++++++++++++++++++++ MusicKit/MKUtil.swift | 21 +++++---------------- 3 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 MusicKit/Extensions.swift diff --git a/MusicKit.xcodeproj/project.pbxproj b/MusicKit.xcodeproj/project.pbxproj index 7038a93..cc02d70 100644 --- a/MusicKit.xcodeproj/project.pbxproj +++ b/MusicKit.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 377091D51E06340B00DFFEA8 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377091D41E06340B00DFFEA8 /* Extensions.swift */; }; + 377091D61E06340B00DFFEA8 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377091D41E06340B00DFFEA8 /* Extensions.swift */; }; 960F015E1AFFA6AA006974AE /* MIDIMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 960F015D1AFFA6AA006974AE /* MIDIMessage.swift */; }; 960F015F1AFFA6AA006974AE /* MIDIMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 960F015D1AFFA6AA006974AE /* MIDIMessage.swift */; }; 960F21F81B08FF320088C194 /* ChordExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 960F21F71B08FF320088C194 /* ChordExtension.swift */; }; @@ -111,6 +113,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 377091D41E06340B00DFFEA8 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 960F015D1AFFA6AA006974AE /* MIDIMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MIDIMessage.swift; sourceTree = ""; }; 960F21F61B08FEC70088C194 /* UnalteredExtendedChords.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; name = UnalteredExtendedChords.playground; path = ../Playgrounds/UnalteredExtendedChords.playground; sourceTree = ""; }; 960F21F71B08FF320088C194 /* ChordExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChordExtension.swift; sourceTree = ""; }; @@ -313,6 +316,7 @@ isa = PBXGroup; children = ( 965AF8C11AF7A1DA00D31E83 /* Protocols.swift */, + 377091D41E06340B00DFFEA8 /* Extensions.swift */, 96DFB6331AF6C2F0005EEBD6 /* MKUtil.swift */, ); name = Internal; @@ -592,6 +596,7 @@ buildActionMask = 2147483647; files = ( 960F21F91B08FF320088C194 /* ChordExtension.swift in Sources */, + 377091D61E06340B00DFFEA8 /* Extensions.swift in Sources */, 96A06D551AFF281400029013 /* MKMIDIProc.m in Sources */, 96DFB6351AF6C2F0005EEBD6 /* MKUtil.swift in Sources */, 9693F6761A57C44A006270F4 /* MusicKit.swift in Sources */, @@ -625,6 +630,7 @@ buildActionMask = 2147483647; files = ( 960F21F81B08FF320088C194 /* ChordExtension.swift in Sources */, + 377091D51E06340B00DFFEA8 /* Extensions.swift in Sources */, 96A06D541AFF281400029013 /* MKMIDIProc.m in Sources */, 96DFB6341AF6C2F0005EEBD6 /* MKUtil.swift in Sources */, 96F299411A5665CA00D7B006 /* Pitch.swift in Sources */, diff --git a/MusicKit/Extensions.swift b/MusicKit/Extensions.swift new file mode 100644 index 0000000..bf4ff95 --- /dev/null +++ b/MusicKit/Extensions.swift @@ -0,0 +1,26 @@ +// +// Extensions.swift +// MusicKit +// +// Created by Adam Nemecek on 12/17/16. +// Copyright © 2016 benzguo. All rights reserved. +// + +import Foundation + +extension Sequence { + public func scan(_ initial: T, _ combine: (T, Iterator.Element) throws -> T) rethrows -> [T] { + var accu = initial + return try map { + accu = try combine(accu, $0) + return accu + } + } +} + +extension Sequence where SubSequence: Sequence { + var tuples: AnyIterator<(SubSequence.Iterator.Element, SubSequence.Iterator.Element)> { + let i = zip(dropFirst(), dropLast()) + return AnyIterator(i.makeIterator()) + } +} diff --git a/MusicKit/MKUtil.swift b/MusicKit/MKUtil.swift index 9ac3e4b..841040e 100644 --- a/MusicKit/MKUtil.swift +++ b/MusicKit/MKUtil.swift @@ -18,7 +18,7 @@ public enum MKUtil { /// Transforms an array of semitone indices so that the first index is zero static func zero(_ semitoneIndices: [Float]) -> [Float] { if semitoneIndices.count < 1 { return semitoneIndices } - return semitoneIndices.map { return $0 - semitoneIndices[0] } + return semitoneIndices.map { $0 - semitoneIndices[0] } } /// Collapses an array of semitone indices to within an octave @@ -40,23 +40,13 @@ public enum MKUtil { /// Converts an array of intervals to semitone indices /// e.g. [4, 3] -> [0, 4, 7] public static func semitoneIndices(_ intervals: [Float]) -> [Float] { - var indices: [Float] = [0] - for i in 0.. [4, 3] public static func intervals(_ semitoneIndices: [Float]) -> [Float] { - var intervals: [Float] = [] - for i in 1.. Int - { + func insertionIndex(_ pitch: Pitch) -> Int { if self.isEmpty { return 0 } @@ -86,7 +75,7 @@ extension Collection where Iterator.Element == Pitch, Index == Int { high = mid } } - + if self[low] >= pitch { return low } From 134401a4f9f2770f66d4b34ea4a713a4a6f0c160 Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Sat, 17 Dec 2016 19:47:55 -0800 Subject: [PATCH 02/19] * refactoring --- MusicKit/Chroma.swift | 5 +---- MusicKit/Extensions.swift | 9 +++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/MusicKit/Chroma.swift b/MusicKit/Chroma.swift index 12c0f93..1f66552 100644 --- a/MusicKit/Chroma.swift +++ b/MusicKit/Chroma.swift @@ -64,10 +64,7 @@ public enum Chroma: UInt { /// Returns true if the given name tuple is a valid name func validateName(_ name: ChromaNameTuple) -> Bool { - return self.names.reduce(false) { - (a, r) -> Bool in - a || (r == name) - } + return names.any { $0 == name } } } diff --git a/MusicKit/Extensions.swift b/MusicKit/Extensions.swift index bf4ff95..b3c8fbc 100644 --- a/MusicKit/Extensions.swift +++ b/MusicKit/Extensions.swift @@ -18,6 +18,15 @@ extension Sequence { } } +extension Sequence { + public func any(predicate: (Iterator.Element) -> Bool) -> Bool { + for e in self where predicate(e) { + return true + } + return false + } +} + extension Sequence where SubSequence: Sequence { var tuples: AnyIterator<(SubSequence.Iterator.Element, SubSequence.Iterator.Element)> { let i = zip(dropFirst(), dropLast()) From d887e42a3e4c357ff7e627ae602126bcab3a494f Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Sat, 17 Dec 2016 19:52:09 -0800 Subject: [PATCH 03/19] * refactoring --- MusicKit/ChordDescriptor.swift | 7 +++++++ MusicKit/ChordName.swift | 13 +------------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/MusicKit/ChordDescriptor.swift b/MusicKit/ChordDescriptor.swift index 9919755..4d4bab7 100644 --- a/MusicKit/ChordDescriptor.swift +++ b/MusicKit/ChordDescriptor.swift @@ -18,6 +18,13 @@ public struct ChordDescriptor: CustomStringConvertible { self.bass = bass } + public var name: String { + if root == bass { + return "\(root)\(quality)" + } + return "\(root)\(quality)/\(bass)" + } + public var description: String { return "root: \(root), quality: \(quality), bass: \(bass)" } diff --git a/MusicKit/ChordName.swift b/MusicKit/ChordName.swift index 14cdf3e..26428ab 100644 --- a/MusicKit/ChordName.swift +++ b/MusicKit/ChordName.swift @@ -14,18 +14,7 @@ extension PitchSet { extension Chord { /// Returns the name of the chord if found. public static func name(_ pitchSet: PitchSet) -> String? { - if let desc = descriptor(pitchSet) { - let rootName = desc.root.description - let quality = desc.quality.description - if desc.root == desc.bass { - return "\(rootName)\(quality)" - } - else { - let bassName = desc.bass.description - return "\(rootName)\(quality)/\(bassName)" - } - } - return nil + return descriptor(pitchSet)?.name } /// Returns an optional `ChordDescriptor`. From a4904bd12ee1dbb2d006047fc090a8877e79e7dc Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Sat, 17 Dec 2016 20:23:45 -0800 Subject: [PATCH 04/19] * refactoring --- MusicKit/ChordName.swift | 2 +- MusicKit/Harmony.swift | 2 +- MusicKit/MKUtil.swift | 3 +- MusicKit/PitchSet.swift | 64 +++++++++++++------------------ MusicKit/PitchSetExtensions.swift | 21 ++-------- 5 files changed, 33 insertions(+), 59 deletions(-) diff --git a/MusicKit/ChordName.swift b/MusicKit/ChordName.swift index 26428ab..dad64a0 100644 --- a/MusicKit/ChordName.swift +++ b/MusicKit/ChordName.swift @@ -96,7 +96,7 @@ extension Chord { return nil } - let bass = pitchSet.first()! + let bass = pitchSet.first! let bassChromaOpt = bass.chroma let indices = pitchSet.semitoneIndices() diff --git a/MusicKit/Harmony.swift b/MusicKit/Harmony.swift index 30e7161..925816d 100644 --- a/MusicKit/Harmony.swift +++ b/MusicKit/Harmony.swift @@ -19,7 +19,7 @@ public struct Harmony { let pitchSet = PitchSet(pitches: firstPitch) return intervals.reduce(pitchSet) { (ps, interval) -> PitchSet in - return ps + [ps.last()! + interval] + return ps + [ps.last! + interval] } } } diff --git a/MusicKit/MKUtil.swift b/MusicKit/MKUtil.swift index 841040e..8856785 100644 --- a/MusicKit/MKUtil.swift +++ b/MusicKit/MKUtil.swift @@ -10,14 +10,13 @@ public enum MKUtil { var semitones = semitoneIndices for _ in 0.. [Float] { - if semitoneIndices.count < 1 { return semitoneIndices } return semitoneIndices.map { $0 - semitoneIndices[0] } } diff --git a/MusicKit/PitchSet.swift b/MusicKit/PitchSet.swift index cf9950c..09a4fa8 100644 --- a/MusicKit/PitchSet.swift +++ b/MusicKit/PitchSet.swift @@ -6,13 +6,7 @@ import Foundation /// A collection of unique `Pitch` instances ordered by frequency. public struct PitchSet: Equatable { - var contents: [Pitch] = [] - - /// The number of pitches the `PitchSet` contains. - public var count: Int { - return contents.count - } - + fileprivate var contents: [Pitch] = [] /// Creates an empty `PitchSet` public init() { } @@ -29,7 +23,7 @@ public struct PitchSet: Equatable { /// Returns the index of the given `pitch` /// /// :returns: The index of the first instance of `pitch`, or `nil` if `pitch` isn't found. - public func indexOf(_ pitch: Pitch) -> Int? { + public func index(of pitch: Pitch) -> Int? { let index = contents.insertionIndex(pitch) if index == count { return nil @@ -39,13 +33,9 @@ public struct PitchSet: Equatable { /// Returns true iff `pitch` is found in the collection. public func contains(_ pitch: Pitch) -> Bool { - return indexOf(pitch) != nil + return index(of: pitch) != nil } - /// Returns true iff there are no pitches in the collection - public func isEmpty() -> Bool { - return count == 0 - } /// Returns a new `PitchSet` with the combined contents of `self` and the given pitches. public func merge(_ pitches: Pitch...) -> PitchSet { @@ -75,14 +65,13 @@ public struct PitchSet: Equatable { /// /// :returns: The given pitch if found, otherwise `nil`. public mutating func remove(_ pitch: Pitch) -> Pitch? { - if let index = indexOf(pitch) { - return contents.remove(at: index) + return index(of: pitch).map { + self.contents.remove(at: $0) } - return nil } /// Removes and returns the pitch at `index`. Requires count > 0. - public mutating func removeAtIndex(_ index: Int) -> Pitch { + public mutating func remove(at index: Int) -> Pitch { return contents.remove(at: index) } @@ -103,7 +92,7 @@ extension PitchSet: CustomStringConvertible { extension PitchSet: Collection { /// Returns the position immediately after the given index. public func index(after i: Int) -> Int { - return i+1 > count ? i : i+1; + return i + 1 } /// The position of the first pitch in the set. (Always zero.) @@ -114,7 +103,7 @@ extension PitchSet: Collection { /// One greater than the position of the last pitch in the set. /// Zero when the collection is empty. public var endIndex: Int { - return count + return contents.endIndex } /// Accesses the pitch at index `i`. @@ -132,21 +121,19 @@ extension PitchSet: Collection { // MARK: ArrayLiteralConvertible extension PitchSet: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Pitch...) { - self.contents = Array(Set(elements)).sorted() + self.contents = Set(elements).sorted() + } +} + +extension PitchSet: BidirectionalCollection { + public func index(before i: Int) -> Int { + return i - 1 } } // MARK: Equatable public func ==(lhs: PitchSet, rhs: PitchSet) -> Bool { - if lhs.count != rhs.count { - return false - } - for (lhs, rhs) in zip(lhs, rhs) { - if lhs != rhs { - return false - } - } - return true + return lhs.count == rhs.count && lhs.elementsEqual(rhs) } // MARK: Operators @@ -205,7 +192,7 @@ public struct PitchSetSlice { /// Returns the index of the given `pitch` /// /// :returns: The index of the first instance of `pitch`, or `nil` if `pitch` isn't found. - public func indexOf(_ pitch: Pitch) -> Int? { + public func index(of pitch: Pitch) -> Int? { let index = contents.insertionIndex(pitch) if index == count { return nil @@ -215,7 +202,7 @@ public struct PitchSetSlice { /// Returns true iff `pitch` is found in the slice. public func contains(_ pitch: Pitch) -> Bool { - return indexOf(pitch) != nil + return index(of: pitch) != nil } /// Returns a new `PitchSetSlice` with the combined contents of `self` and the given pitches. @@ -246,14 +233,11 @@ public struct PitchSetSlice { /// /// :returns: The given value if found, otherwise `nil`. public mutating func remove(_ pitch: Pitch) -> Pitch? { - if let index = indexOf(pitch) { - return contents.remove(at: index) - } - return nil + return index(of: pitch).map { self.contents.remove(at: $0) } } /// Removes and returns the pitch at `index`. Requires count > 0. - public mutating func removeAtIndex(_ index: Int) -> Pitch { + public mutating func remove(at index: Int) -> Pitch { return contents.remove(at: index) } @@ -274,7 +258,7 @@ extension PitchSetSlice: CustomStringConvertible { extension PitchSetSlice: Collection { /// Returns the position immediately after the given index. public func index(after i: Int) -> Int { - return i+1 > count ? i : i+1; + return i + 1 } public typealias Index = Int @@ -302,6 +286,12 @@ extension PitchSetSlice: Collection { } } +extension PitchSetSlice: BidirectionalCollection { + public func index(before i: Int) -> Int { + return i - 1 + } +} + // MARK: ArrayLiteralConvertible extension PitchSetSlice: ExpressibleByArrayLiteral { public init(arrayLiteral elements: Pitch...) { diff --git a/MusicKit/PitchSetExtensions.swift b/MusicKit/PitchSetExtensions.swift index d208e23..816bee2 100644 --- a/MusicKit/PitchSetExtensions.swift +++ b/MusicKit/PitchSetExtensions.swift @@ -6,13 +6,7 @@ import Foundation extension PitchSet { /// Returns the set of chroma contained in the `PitchSet` public func gamut() -> Set { - var set = Set() - for pitch in self.contents { - if let chroma = pitch.chroma { - set.insert(chroma) - } - } - return set + return Set( flatMap { $0.chroma } ) } } @@ -20,7 +14,7 @@ extension PitchSet { extension PitchSet: Transposable { public func transpose(_ semitones: Float) -> PitchSet { // TODO: use PitchSet.map - return PitchSet(contents.map { $0.transpose(semitones) }) + return PitchSet(map { $0.transpose(semitones) }) } } @@ -43,7 +37,7 @@ extension PitchSet { /// Returns the semitone indices when the lowest pitch is given index 0. public func semitoneIndices() -> [Float] { if self.count < 1 { - return [Float(0)] + return [0] } let first = self[0].midi return map { $0.midi - first } @@ -120,15 +114,6 @@ extension PitchSet { } } - /// The first pitch, or `nil` if the set is empty. - public func first() -> Pitch? { - return contents.first - } - - /// The last pitch, or `nil` if the set is empty - public func last() -> Pitch? { - return contents.last - } } // MARK: PitchSet-Pitch operators From 20bc318c60bffd6dcaa9ff84db5bb94d69fd22c8 Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Sat, 17 Dec 2016 20:28:49 -0800 Subject: [PATCH 05/19] * refactoring --- MusicKit/PitchSetExtensions.swift | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/MusicKit/PitchSetExtensions.swift b/MusicKit/PitchSetExtensions.swift index 816bee2..4b1208b 100644 --- a/MusicKit/PitchSetExtensions.swift +++ b/MusicKit/PitchSetExtensions.swift @@ -36,11 +36,9 @@ extension PitchSet { extension PitchSet { /// Returns the semitone indices when the lowest pitch is given index 0. public func semitoneIndices() -> [Float] { - if self.count < 1 { - return [0] - } - let first = self[0].midi - return map { $0.midi - first } + return first.map { f in + self.map { $0.midi - f.midi } + } ?? [0] } /// Inverts the `PitchSet` the given number of times. @@ -52,12 +50,11 @@ extension PitchSet { } mutating func _invert() { - if self.count < 1 { - return - } + guard isEmpty else { return } + var bass = self[0] _ = remove(bass) - let last = self[count - 1] + let last = self.last! while bass < last { bass = bass + 12 } From db16b25e54f0c9677f83ae8f49ca494cc53b9227 Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Sat, 17 Dec 2016 20:37:35 -0800 Subject: [PATCH 06/19] * refactoring --- MusicKit/Extensions.swift | 12 ++++++++++++ MusicKit/PitchSetExtensions.swift | 19 ++----------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/MusicKit/Extensions.swift b/MusicKit/Extensions.swift index b3c8fbc..266138a 100644 --- a/MusicKit/Extensions.swift +++ b/MusicKit/Extensions.swift @@ -18,6 +18,18 @@ extension Sequence { } } +extension Sequence where Iterator.Element: Hashable { + var unique: [Iterator.Element] { + var s: Set = [] + return filter { s.insert($0).inserted } + } + + var duplicates: [Iterator.Element] { + var s: Set = [] + return filter { !s.insert($0).inserted } + } +} + extension Sequence { public func any(predicate: (Iterator.Element) -> Bool) -> Bool { for e in self where predicate(e) { diff --git a/MusicKit/PitchSetExtensions.swift b/MusicKit/PitchSetExtensions.swift index 4b1208b..837c8ef 100644 --- a/MusicKit/PitchSetExtensions.swift +++ b/MusicKit/PitchSetExtensions.swift @@ -75,26 +75,11 @@ extension PitchSet { /// Removes duplicate chroma from the pitch set, starting from the root. /// Note that pitches without chroma will be ignored. public mutating func dedupe() { - var gamut = Set() - var pitchesToRemove = PitchSet() - for i in 0.. Date: Sat, 17 Dec 2016 20:42:14 -0800 Subject: [PATCH 07/19] * refactoring --- MusicKit/Chroma.swift | 8 +++----- MusicKit/Pitch.swift | 8 ++++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/MusicKit/Chroma.swift b/MusicKit/Chroma.swift index 1f66552..1376805 100644 --- a/MusicKit/Chroma.swift +++ b/MusicKit/Chroma.swift @@ -71,11 +71,9 @@ public enum Chroma: UInt { // MARK: Printable extension Chroma: CustomStringConvertible { public var description: String { - let nameTupleOpt: ChromaNameTuple? = self.names.first - if let (letterName, accidental) = nameTupleOpt { - return "\(letterName.description)\(accidental.description(true))" - } - return "" + return names.first.flatMap { tup in + "\(tup.0)\(tup.1.description(true))" + } ?? "" } } diff --git a/MusicKit/Pitch.swift b/MusicKit/Pitch.swift index 44bb999..f1eb1c2 100644 --- a/MusicKit/Pitch.swift +++ b/MusicKit/Pitch.swift @@ -28,14 +28,14 @@ public struct Pitch: Comparable { /// The frequency of the pitch in Hz public var frequency: Float { - return Pitch.mtof(self.midi) + return Pitch.mtof(midi) } /// A `Chroma`, or nil if the pitch doesn't align with the chromas /// in the current tuning system. public var chroma: Chroma? { - if self.midi - floor(self.midi) == 0 { - return Chroma(rawValue: UInt(self.midi)%12) + if midi - floor(midi) == 0 { + return Chroma(rawValue: UInt(midi)%12) } return nil } @@ -54,7 +54,7 @@ public struct Pitch: Comparable { /// Unadjusted octave number var octaveNumber: Int { - return Int((self.midi - 12.0)/12.0) + return Int((midi - 12.0)/12.0) } /// Combines an octave number with a chroma name, taking into account From 66aa7f42ea1c3759d4f3625cbdd2741b765b6fe6 Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Sat, 17 Dec 2016 20:54:03 -0800 Subject: [PATCH 08/19] * refactoring --- MusicKit/PitchSetExtensions.swift | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/MusicKit/PitchSetExtensions.swift b/MusicKit/PitchSetExtensions.swift index 837c8ef..4128ee2 100644 --- a/MusicKit/PitchSetExtensions.swift +++ b/MusicKit/PitchSetExtensions.swift @@ -50,9 +50,7 @@ extension PitchSet { } mutating func _invert() { - guard isEmpty else { return } - - var bass = self[0] + guard var bass = first else { return } _ = remove(bass) let last = self.last! while bass < last { @@ -126,9 +124,8 @@ public func /(lhs: PitchSet, rhs: Chroma) -> PitchSet { } var lhs = lhs let firstPitch = lhs[0] - if firstPitch.chroma == nil { - return lhs - } + guard firstPitch.chroma != nil else { return lhs } + var newFirstPitch = firstPitch while (newFirstPitch.chroma.map { $0 == rhs } != Optional(true)) { newFirstPitch = newFirstPitch-- From 92183466c1f47a8355a0d921664710c125b3285f Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Sat, 17 Dec 2016 21:04:21 -0800 Subject: [PATCH 09/19] * refactoring pitchset --- MusicKit/PitchSet.swift | 97 ++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 50 deletions(-) diff --git a/MusicKit/PitchSet.swift b/MusicKit/PitchSet.swift index 09a4fa8..f2a0200 100644 --- a/MusicKit/PitchSet.swift +++ b/MusicKit/PitchSet.swift @@ -5,25 +5,27 @@ import Foundation // MARK: == PitchSet == /// A collection of unique `Pitch` instances ordered by frequency. public struct PitchSet: Equatable { + public typealias Index = Int + public typealias Element = Pitch - fileprivate var contents: [Pitch] = [] + fileprivate var contents: [Element] = [] /// Creates an empty `PitchSet` public init() { } /// Creates a new `PitchSet` with the contents of a given sequence of pitches. - public init(_ sequence: S) where S.Iterator.Element == Pitch { - contents = Array(Set(sequence)).sorted() + public init(_ sequence: S) where S.Iterator.Element == Element { + contents = Set(sequence).sorted() } /// Creates a new `PitchSet` with the given pitches. - public init(pitches: Pitch...) { - contents = Array(Set(pitches)).sorted() + public init(pitches: Element...) { + self.init(pitches) } /// Returns the index of the given `pitch` /// /// :returns: The index of the first instance of `pitch`, or `nil` if `pitch` isn't found. - public func index(of pitch: Pitch) -> Int? { + public func index(of pitch: Element) -> Index? { let index = contents.insertionIndex(pitch) if index == count { return nil @@ -32,23 +34,23 @@ public struct PitchSet: Equatable { } /// Returns true iff `pitch` is found in the collection. - public func contains(_ pitch: Pitch) -> Bool { + public func contains(_ pitch: Element) -> Bool { return index(of: pitch) != nil } /// Returns a new `PitchSet` with the combined contents of `self` and the given pitches. - public func merge(_ pitches: Pitch...) -> PitchSet { + public func merge(_ pitches: Element...) -> PitchSet { return merge(pitches) } /// Returns a new `PitchSet` with the combined contents of `self` and the given sequence of pitches. - public func merge(_ pitches: S) -> PitchSet where S.Iterator.Element == Pitch { + public func merge(_ pitches: S) -> PitchSet where S.Iterator.Element == Element { return PitchSet(contents + pitches) } /// Inserts one or more new pitches into the `PitchSet` in the correct order. - public mutating func insert(_ pitches: Pitch...) { + public mutating func insert(_ pitches: Element...) { for pitch in pitches { if !contains(pitch) { contents.insert(pitch, at: contents.insertionIndex(pitch)) @@ -58,20 +60,20 @@ public struct PitchSet: Equatable { /// Inserts the contents of a sequence of pitches into the `PitchSet`. public mutating func insert(_ pitches: S) where S.Iterator.Element == Pitch { - contents = Array(Set(contents + pitches)).sorted() + contents = Set(contents + pitches).sorted() } /// Removes `pitch` from the `PitchSet` if it exists. /// /// :returns: The given pitch if found, otherwise `nil`. - public mutating func remove(_ pitch: Pitch) -> Pitch? { + public mutating func remove(_ pitch: Element) -> Element? { return index(of: pitch).map { self.contents.remove(at: $0) } } /// Removes and returns the pitch at `index`. Requires count > 0. - public mutating func remove(at index: Int) -> Pitch { + public mutating func remove(at index: Index) -> Element { return contents.remove(at: index) } @@ -91,42 +93,42 @@ extension PitchSet: CustomStringConvertible { // MARK: CollectionType extension PitchSet: Collection { /// Returns the position immediately after the given index. - public func index(after i: Int) -> Int { + public func index(after i: Index) -> Index { return i + 1 } /// The position of the first pitch in the set. (Always zero.) - public var startIndex: Int { + public var startIndex: Index { return 0 } /// One greater than the position of the last pitch in the set. /// Zero when the collection is empty. - public var endIndex: Int { + public var endIndex: Index { return contents.endIndex } /// Accesses the pitch at index `i`. /// Read-only to ensure sorting - use `insert` to add new pitches. - public subscript(i: Int) -> Pitch { + public subscript(i: Index) -> Element { return contents[i] } /// Access the elements in the given range. - public subscript(range: Range) -> PitchSetSlice { + public subscript(range: Range) -> PitchSetSlice { return PitchSetSlice(contents[range]) } } // MARK: ArrayLiteralConvertible extension PitchSet: ExpressibleByArrayLiteral { - public init(arrayLiteral elements: Pitch...) { + public init(arrayLiteral elements: Element...) { self.contents = Set(elements).sorted() } } extension PitchSet: BidirectionalCollection { - public func index(before i: Int) -> Int { + public func index(before i: Index) -> Index { return i - 1 } } @@ -164,35 +166,32 @@ public func -=(lhs: inout PitchSet, rhs: PitchSet) { // MARK: == PitchSetSlice == /// A slice of a `PitchSet`. public struct PitchSetSlice { - fileprivate var contents: ArraySlice = [] - - /// The number of elements the `PitchSetSlice` contains. - public var count: Int { - return contents.count - } + public typealias Index = Int + public typealias Element = Pitch + fileprivate var contents: ArraySlice = [] /// Creates an empty `PitchSetSlice`. public init() { } /// Creates a new `PitchSetSlice` with the contents of a given sequence. - public init(_ sequence: S) where S.Iterator.Element == Pitch { - contents = ArraySlice(Array(Set(sequence)).sorted()) + public init(_ sequence: S) where S.Iterator.Element == Element { + contents = ArraySlice(Set(sequence).sorted()) } /// Creates a new `PitchSetSlice` with the given values. - public init(values: Pitch...) { - contents = ArraySlice(Array(Set(values)).sorted()) + public init(values: Element...) { + contents = ArraySlice(Set(values).sorted()) } /// Creates a new `PitchSetSlice` from a sorted slice. - fileprivate init(sortedSlice: ArraySlice) { + fileprivate init(sortedSlice: ArraySlice) { contents = sortedSlice } /// Returns the index of the given `pitch` /// /// :returns: The index of the first instance of `pitch`, or `nil` if `pitch` isn't found. - public func index(of pitch: Pitch) -> Int? { + public func index(of pitch: Element) -> Index? { let index = contents.insertionIndex(pitch) if index == count { return nil @@ -201,12 +200,12 @@ public struct PitchSetSlice { } /// Returns true iff `pitch` is found in the slice. - public func contains(_ pitch: Pitch) -> Bool { + public func contains(_ pitch: Element) -> Bool { return index(of: pitch) != nil } /// Returns a new `PitchSetSlice` with the combined contents of `self` and the given pitches. - public func merge(_ pitches: Pitch...) -> PitchSetSlice { + public func merge(_ pitches: Element...) -> PitchSetSlice { return merge(pitches) } @@ -216,7 +215,7 @@ public struct PitchSetSlice { } /// Inserts one or more new pitches into the slice in the correct order. - public mutating func insert(_ pitches: Pitch...) { + public mutating func insert(_ pitches: Element...) { for pitch in pitches { if !contains(pitch) { contents.insert(pitch, at: contents.insertionIndex(pitch)) @@ -225,19 +224,19 @@ public struct PitchSetSlice { } /// Inserts the contents of a sequence into the `PitchSetSlice`. - public mutating func insert(_ pitches: S) where S.Iterator.Element == Pitch { - contents = ArraySlice(Array(Set(contents + pitches)).sorted()) + public mutating func insert(_ pitches: S) where S.Iterator.Element == Element { + contents = ArraySlice(Set(contents + pitches).sorted()) } /// Removes `pitch` from the slice if it exists. /// /// :returns: The given value if found, otherwise `nil`. - public mutating func remove(_ pitch: Pitch) -> Pitch? { - return index(of: pitch).map { self.contents.remove(at: $0) } + public mutating func remove(_ pitch: Element) -> Element? { + return index(of: pitch).map { contents.remove(at: $0) } } /// Removes and returns the pitch at `index`. Requires count > 0. - public mutating func remove(at index: Int) -> Pitch { + public mutating func remove(at index: Index) -> Element { return contents.remove(at: index) } @@ -257,44 +256,42 @@ extension PitchSetSlice: CustomStringConvertible { // MARK: CollectionType extension PitchSetSlice: Collection { /// Returns the position immediately after the given index. - public func index(after i: Int) -> Int { + public func index(after i: Index) -> Index { return i + 1 } - public typealias Index = Int - /// The position of the first pitch in the slice. (Always zero.) - public var startIndex: Int { + public var startIndex: Index { return 0 } /// One greater than the position of the last element in the slice. Zero when the slice is empty. - public var endIndex: Int { + public var endIndex: Index { return count } /// Accesses the pitch at index `i`. /// /// Read-only to ensure sorting - use `insert` to add new pitches. - public subscript(i: Int) -> Pitch { + public subscript(i: Index) -> Element { return contents[i] } /// Access the elements in the given range. - public subscript(range: Range) -> PitchSetSlice { + public subscript(range: Range) -> PitchSetSlice { return PitchSetSlice(contents[range]) } } extension PitchSetSlice: BidirectionalCollection { - public func index(before i: Int) -> Int { + public func index(before i: Index) -> Index { return i - 1 } } // MARK: ArrayLiteralConvertible extension PitchSetSlice: ExpressibleByArrayLiteral { - public init(arrayLiteral elements: Pitch...) { - self.contents = ArraySlice(Array(Set(elements)).sorted()) + public init(arrayLiteral elements: Element...) { + contents = ArraySlice(Set(elements).sorted()) } } From 5b020afc2ea3052f34697d272ef13a4f5b020578 Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Tue, 14 Mar 2017 08:52:04 -0700 Subject: [PATCH 10/19] * update to swift 3 --- MusicKit/Chroma.swift | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/MusicKit/Chroma.swift b/MusicKit/Chroma.swift index 1376805..4ae62b3 100644 --- a/MusicKit/Chroma.swift +++ b/MusicKit/Chroma.swift @@ -71,18 +71,12 @@ public enum Chroma: UInt { // MARK: Printable extension Chroma: CustomStringConvertible { public var description: String { - return names.first.flatMap { tup in + return names.first.map { tup in "\(tup.0)\(tup.1.description(true))" } ?? "" } } -// MARK: Operators -public func == (p1:(LetterName, Accidental), p2:(LetterName, Accidental)) -> Bool -{ - return (p1.0 == p2.0) && (p1.1 == p2.1) -} - public func +(lhs: Chroma, rhs: Int) -> Chroma { var rhs = rhs while rhs < 0 { From 4e6adc85c54a8848bc58504a6fb69be101c11f38 Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Tue, 14 Mar 2017 09:08:42 -0700 Subject: [PATCH 11/19] * refactoring --- MusicKit/ChordName.swift | 11 +- MusicKit/ChordQualities.swift | 972 +++++++++++++++++----------------- MusicKit/Chroma.swift | 68 +-- MusicKit/MKUtil.swift | 9 +- MusicKit/PitchSet.swift | 22 +- 5 files changed, 539 insertions(+), 543 deletions(-) diff --git a/MusicKit/ChordName.swift b/MusicKit/ChordName.swift index dad64a0..c81046e 100644 --- a/MusicKit/ChordName.swift +++ b/MusicKit/ChordName.swift @@ -91,12 +91,7 @@ extension Chord { static func _descriptor(_ pitchSet: PitchSet, qualities: [ChordQuality]) -> ChordDescriptor? { - let count = pitchSet.count - if count < 1 { - return nil - } - - let bass = pitchSet.first! + guard let bass = pitchSet.first else { return nil } let bassChromaOpt = bass.chroma let indices = pitchSet.semitoneIndices() @@ -112,10 +107,10 @@ extension Chord { // check inversions for quality in qualities { let _indices = MKUtil.collapse(MKUtil.semitoneIndices(quality.intervals)) - for i in 1.. Bool { return names.any { $0 == name } } + + static public func +(lhs: Chroma, rhs: Int) -> Chroma { + var rhs = rhs + while rhs < 0 { + rhs = rhs + 12 + } + let newRawValue = (lhs.rawValue + UInt(rhs))%12 + return Chroma(rawValue: newRawValue)! + } + + static public func -(lhs: Chroma, rhs: Int) -> Chroma { + return lhs + (-1*rhs) + } + + static postfix func --(chroma: inout Chroma) -> Chroma { + chroma = chroma - 1 + return chroma + } + + static postfix func ++(chroma: inout Chroma) -> Chroma { + chroma = chroma + 1 + return chroma + } + + /// Returns the minimum distance between two chromas + static public func -(lhs: Chroma, rhs: Chroma) -> UInt { + let lminusr = abs(Int(lhs.rawValue) - Int(rhs.rawValue)) + let rminusl = abs(Int(rhs.rawValue) - Int(lhs.rawValue)) + return UInt(min(lminusr, rminusl)) + } + + static public func *(lhs: Chroma, rhs: Int) -> Pitch { + return Pitch(chroma: lhs, octave: UInt(abs(rhs))) + } } // MARK: Printable @@ -76,37 +110,3 @@ extension Chroma: CustomStringConvertible { } ?? "" } } - -public func +(lhs: Chroma, rhs: Int) -> Chroma { - var rhs = rhs - while rhs < 0 { - rhs = rhs + 12 - } - let newRawValue = (lhs.rawValue + UInt(rhs))%12 - return Chroma(rawValue: newRawValue)! -} - -public func -(lhs: Chroma, rhs: Int) -> Chroma { - return lhs + (-1*rhs) -} - -postfix func --(chroma: inout Chroma) -> Chroma { - chroma = chroma - 1 - return chroma -} - -postfix func ++(chroma: inout Chroma) -> Chroma { - chroma = chroma + 1 - return chroma -} - -/// Returns the minimum distance between two chromas -public func -(lhs: Chroma, rhs: Chroma) -> UInt { - let lminusr = abs(Int(lhs.rawValue) - Int(rhs.rawValue)) - let rminusl = abs(Int(rhs.rawValue) - Int(lhs.rawValue)) - return UInt(min(lminusr, rminusl)) -} - -public func *(lhs: Chroma, rhs: Int) -> Pitch { - return Pitch(chroma: lhs, octave: UInt(abs(rhs))) -} diff --git a/MusicKit/MKUtil.swift b/MusicKit/MKUtil.swift index 8856785..e315c82 100644 --- a/MusicKit/MKUtil.swift +++ b/MusicKit/MKUtil.swift @@ -49,7 +49,8 @@ public enum MKUtil { } } -extension Collection where Iterator.Element == Pitch, Index == Int { + +extension Collection where Iterator.Element : Comparable, Index == Int { /// Returns the insertion point for `pitch` in the collection of `pitches`. /// @@ -58,7 +59,7 @@ extension Collection where Iterator.Element == Pitch, Index == Int { /// could be inserted, keeping `pitchSet` in order. /// /// :returns: An index in the range `0...count(pitches)` where `pitch` can be inserted. - func insertionIndex(_ pitch: Pitch) -> Int { + func insertionIndex(_ element: Iterator.Element) -> Index { if self.isEmpty { return 0 } @@ -68,14 +69,14 @@ extension Collection where Iterator.Element == Pitch, Index == Int { while low < high { mid = (high - low) / 2 + low - if self[mid] < pitch { + if self[mid] < element { low = mid + 1 } else { high = mid } } - if self[low] >= pitch { + if self[low] >= element { return low } diff --git a/MusicKit/PitchSet.swift b/MusicKit/PitchSet.swift index f2a0200..b1d441a 100644 --- a/MusicKit/PitchSet.swift +++ b/MusicKit/PitchSet.swift @@ -4,7 +4,7 @@ import Foundation // MARK: == PitchSet == /// A collection of unique `Pitch` instances ordered by frequency. -public struct PitchSet: Equatable { +public struct PitchSet : Equatable { public typealias Index = Int public typealias Element = Pitch @@ -81,6 +81,10 @@ public struct PitchSet: Equatable { public mutating func removeAll(_ keepCapacity: Bool = true) { contents.removeAll(keepingCapacity: keepCapacity) } + + static public func ==(lhs: PitchSet, rhs: PitchSet) -> Bool { + return lhs.count == rhs.count && lhs.elementsEqual(rhs) + } } // MARK: Printable @@ -121,22 +125,18 @@ extension PitchSet: Collection { } // MARK: ArrayLiteralConvertible -extension PitchSet: ExpressibleByArrayLiteral { +extension PitchSet : ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { self.contents = Set(elements).sorted() } } -extension PitchSet: BidirectionalCollection { +extension PitchSet : BidirectionalCollection { public func index(before i: Index) -> Index { return i - 1 } } -// MARK: Equatable -public func ==(lhs: PitchSet, rhs: PitchSet) -> Bool { - return lhs.count == rhs.count && lhs.elementsEqual(rhs) -} // MARK: Operators public func +(lhs: PitchSet, rhs: PitchSet) -> PitchSet { @@ -247,14 +247,14 @@ public struct PitchSetSlice { } // MARK: Printable -extension PitchSetSlice: CustomStringConvertible { +extension PitchSetSlice : CustomStringConvertible { public var description: String { return contents.description } } // MARK: CollectionType -extension PitchSetSlice: Collection { +extension PitchSetSlice : Collection { /// Returns the position immediately after the given index. public func index(after i: Index) -> Index { return i + 1 @@ -283,14 +283,14 @@ extension PitchSetSlice: Collection { } } -extension PitchSetSlice: BidirectionalCollection { +extension PitchSetSlice : BidirectionalCollection { public func index(before i: Index) -> Index { return i - 1 } } // MARK: ArrayLiteralConvertible -extension PitchSetSlice: ExpressibleByArrayLiteral { +extension PitchSetSlice : ExpressibleByArrayLiteral { public init(arrayLiteral elements: Element...) { contents = ArraySlice(Set(elements).sorted()) } From 2fe60917d0adca26e57aa7761c3ec1cd2fa85fba Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Tue, 14 Mar 2017 09:22:11 -0700 Subject: [PATCH 12/19] * refactored any --- MusicKit/Extensions.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/MusicKit/Extensions.swift b/MusicKit/Extensions.swift index 266138a..0875d6a 100644 --- a/MusicKit/Extensions.swift +++ b/MusicKit/Extensions.swift @@ -32,10 +32,7 @@ extension Sequence where Iterator.Element: Hashable { extension Sequence { public func any(predicate: (Iterator.Element) -> Bool) -> Bool { - for e in self where predicate(e) { - return true - } - return false + return first { predicate($0) } != nil } } From 0e371cb1d9e671c6c8ace921ced646c22640ce9a Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Tue, 14 Mar 2017 09:23:23 -0700 Subject: [PATCH 13/19] * removed any --- MusicKit.xcodeproj/project.pbxproj | 4 ++-- MusicKit/Chroma.swift | 2 +- MusicKit/Extensions.swift | 6 ------ 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/MusicKit.xcodeproj/project.pbxproj b/MusicKit.xcodeproj/project.pbxproj index cc02d70..82a9614 100644 --- a/MusicKit.xcodeproj/project.pbxproj +++ b/MusicKit.xcodeproj/project.pbxproj @@ -505,11 +505,11 @@ TargetAttributes = { 9691BB231A57C75500421B56 = { CreatedOnToolsVersion = 6.1.1; - LastSwiftMigration = 0800; + LastSwiftMigration = 0820; }; 9693F6521A57C403006270F4 = { CreatedOnToolsVersion = 6.1.1; - LastSwiftMigration = 0800; + LastSwiftMigration = 0820; }; 96F299211A5663E500D7B006 = { CreatedOnToolsVersion = 6.1.1; diff --git a/MusicKit/Chroma.swift b/MusicKit/Chroma.swift index 30d56ae..340bdac 100644 --- a/MusicKit/Chroma.swift +++ b/MusicKit/Chroma.swift @@ -64,7 +64,7 @@ public enum Chroma: UInt { /// Returns true if the given name tuple is a valid name func validateName(_ name: ChromaNameTuple) -> Bool { - return names.any { $0 == name } + return names.contains { $0 == name } } static public func +(lhs: Chroma, rhs: Int) -> Chroma { diff --git a/MusicKit/Extensions.swift b/MusicKit/Extensions.swift index 0875d6a..6377cda 100644 --- a/MusicKit/Extensions.swift +++ b/MusicKit/Extensions.swift @@ -30,12 +30,6 @@ extension Sequence where Iterator.Element: Hashable { } } -extension Sequence { - public func any(predicate: (Iterator.Element) -> Bool) -> Bool { - return first { predicate($0) } != nil - } -} - extension Sequence where SubSequence: Sequence { var tuples: AnyIterator<(SubSequence.Iterator.Element, SubSequence.Iterator.Element)> { let i = zip(dropFirst(), dropLast()) From 7ecd8730f11cc865641312f3e9c8f8274f84129b Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Tue, 14 Mar 2017 09:33:45 -0700 Subject: [PATCH 14/19] * updated to swift 3? --- MusicKit.xcodeproj/project.pbxproj | 6 ++ MusicKit/ChordExtensions.swift | 2 +- MusicKit/Extensions.swift | 2 + .../section-1.swift | 68 +++++++++---------- .../timeline.xctimeline | 8 +-- 5 files changed, 47 insertions(+), 39 deletions(-) diff --git a/MusicKit.xcodeproj/project.pbxproj b/MusicKit.xcodeproj/project.pbxproj index 82a9614..a0e01ad 100644 --- a/MusicKit.xcodeproj/project.pbxproj +++ b/MusicKit.xcodeproj/project.pbxproj @@ -513,9 +513,11 @@ }; 96F299211A5663E500D7B006 = { CreatedOnToolsVersion = 6.1.1; + LastSwiftMigration = 0820; }; 96F2992C1A5663E500D7B006 = { CreatedOnToolsVersion = 6.1.1; + LastSwiftMigration = 0820; }; }; }; @@ -883,6 +885,7 @@ SKIP_INSTALL = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -903,6 +906,7 @@ PRODUCT_NAME = MusicKit; SKIP_INSTALL = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -922,6 +926,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "benzguo.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -937,6 +942,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "benzguo.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/MusicKit/ChordExtensions.swift b/MusicKit/ChordExtensions.swift index 13d6f83..86c8c7c 100644 --- a/MusicKit/ChordExtensions.swift +++ b/MusicKit/ChordExtensions.swift @@ -10,7 +10,7 @@ extension Chord { } // sort and convert to zero-indexed indices - let sortedIndices = (indices.map { $0 - 1 }).sorted() + let sortedIndices = indices.map { $0 - 1 }.sorted() let maxIndex = Int(sortedIndices.last!) var scalePitches = harmonizer(Chroma.c*0) diff --git a/MusicKit/Extensions.swift b/MusicKit/Extensions.swift index 6377cda..b97bf5a 100644 --- a/MusicKit/Extensions.swift +++ b/MusicKit/Extensions.swift @@ -30,6 +30,8 @@ extension Sequence where Iterator.Element: Hashable { } } + + extension Sequence where SubSequence: Sequence { var tuples: AnyIterator<(SubSequence.Iterator.Element, SubSequence.Iterator.Element)> { let i = zip(dropFirst(), dropLast()) diff --git a/Playgrounds/FrameworkOverview.playground/section-1.swift b/Playgrounds/FrameworkOverview.playground/section-1.swift index 0ae88cb..c0cffd1 100644 --- a/Playgrounds/FrameworkOverview.playground/section-1.swift +++ b/Playgrounds/FrameworkOverview.playground/section-1.swift @@ -8,19 +8,19 @@ import MusicKit ///* A `Pitch` can be created with a MIDI number, or with a chroma and octave number. ///```swift -let A4 = Pitch(midi: 69) -print(A4.noteName) // A4 -print(A4.frequency) // 440.0 +let a4 = Pitch(midi: 69) +print(a4.noteName) // A4 +print(a4.frequency) // 440.0 -let DSharp2 = Pitch(chroma: .Ds, octave: 2) -let C5 = Chroma.C*5 +let ds2 = Pitch(chroma: .ds, octave: 2) +let c5 = Chroma.c*5 ///``` ///* Changing the value of MusicKit's concert A changes the computed frequency of all pitches. ///```swift MusicKit.concertA = 444 -print(A4.frequency) // 444.0 +print(a4.frequency) // 444.0 MusicKit.concertA = 440 ///``` @@ -28,50 +28,50 @@ MusicKit.concertA = 440 ///* A `Pitch` has a `Chroma` if it has an integral MIDI number. ///```swift -print(A4.chroma) // Optional(A) -let AHalfSharp = Pitch(midi: 69.5) -print(AHalfSharp.chroma) // nil +print(a4.chroma) // Optional(A) +let ahalfsharp = Pitch(midi: 69.5) +print(ahalfsharp.chroma) // nil ///``` ///* A `Chroma` and an octave number can be used to create a `Pitch`. ///```swift -let D5 = Pitch(chroma: .D, octave: 5) -print(D5) // D5 +let d5 = Pitch(chroma: .d, octave: 5) +print(d5) // D5 ///``` ///* A `Chroma` can be created with an index or using one of the provided constants. ///```swift -let C = Chroma.C -print(C) // C -let CSharp = Chroma.Cs -print(CSharp) // C♯ -let D = C + 2 -print(D) // D +let c = Chroma.c +print(c) // C +let cs = Chroma.cs +print(cs) // C♯ +let d = c + 2 +print(d) // D ///``` ///### PitchSet ///* A `PitchSet` is a collection of unique `Pitch` instances ordered by frequency. ///```swift -var CMajor = PitchSet(pitches: Chroma.C*2, Chroma.E*2, Chroma.G*2) -print(CMajor) // [C2, E2, G2] +var cmaj = PitchSet(pitches: Chroma.c*2, Chroma.e*2, Chroma.g*2) +print(cmaj) // [C2, E2, G2] -let pitches = [Chroma.Fs*2, Chroma.As*2, Chroma.Cs*3] -var FSharpMajor = PitchSet(pitches) -print(FSharpMajor) // [F♯2, B♭2, C♯3] +let pitches = [Chroma.fs*2, Chroma.as*2, Chroma.cs*3] +var fsmaj = PitchSet(pitches) +print(fsmaj) // [F♯2, B♭2, C♯3] ///``` ///* `PitchSet` supports many operations. ///```swift -var petrushka = CMajor + FSharpMajor +var petrushka = cmaj + fsmaj print(petrushka) // [C2, E2, F♯2, G2, B♭2, C♯3] -print(CMajor == FSharpMajor) // false +print(cmaj == fsmaj) // false print(petrushka.gamut()) // [F♯, G, B♭, C, E, C♯] -petrushka.remove(Pitch(chroma: Chroma.G, octave: 2)) +petrushka.remove(Pitch(chroma: Chroma.g, octave: 2)) print(petrushka) // [C2, E2, F♯2, B♭2, C♯3] -let F = Chroma.F -print(CMajor / F) // [F1, C2, E2, G2] +let f = Chroma.f +print(cmaj / f) // [F1, C2, E2, G2] ///``` ///### Harmonizer @@ -84,7 +84,7 @@ print(CMajor / F) // [F1, C2, E2, G2] ///```swift let major = Scale.Major -print(major(A4)) // [A4, B4, C♯5, D5, E5, F♯5, G♯5] +print(major(a4)) // [A4, B4, C♯5, D5, E5, F♯5, G♯5] ///``` ///* The `Harmony` enum provides a way to create custom harmonizers from an array of semitone intervals. @@ -98,7 +98,7 @@ let equidistantPentatonic = Harmony.create([2.4, 2.4, 2.4, 2.4, 2.4]) ///```swift let minor = Chord.Minor -print(minor(A4)) // [A4, C5, E5] +print(minor(a4)) // [A4, C5, E5] ///``` ///* `Chord` also provides a function to create a chord based on a `Harmonizer` (typically a scale). @@ -112,7 +112,7 @@ print(ch) // [A4, C♯5, E5, G♯5] ///* `Chord.name` can be used to derive a chord name from a pitch set ///```swift -let pitchSet: PitchSet = [Chroma.B*0, Chroma.Cs*2, Chroma.F*3, Chroma.G*4] +let pitchSet: PitchSet = [Chroma.b*0, Chroma.cs*2, Chroma.f*3, Chroma.g*4] print(Chord.name(pitchSet)!) // G7♭5/B let descriptor = Chord.descriptor(pitchSet) print(descriptor!) // root: G, quality: dominant seventh flat five, bass: B @@ -123,9 +123,9 @@ print(descriptor!) // root: G, quality: dominant seventh flat five, bass: B ///```swift let neapolitan = Major.bII -print(neapolitan(Chroma.C*5)) // [C♯5, E♯5, G♯5] -let G4 = Chroma.G*4 -let plagalCadence = [Major.IV, Major.I] * G4 +print(neapolitan(Chroma.c*5)) // [C♯5, E♯5, G♯5] +let g4 = Chroma.g*4 +let plagalCadence = [Major.IV, Major.I] * g4 print(plagalCadence) // [[C5, E5, G5], [G4, B4, D5]] ///``` @@ -133,6 +133,6 @@ print(plagalCadence) // [[C5, E5, G5], [G4, B4, D5]] ///```swift let V7ofV = HarmonicFunction.create(Scale.Major, degree: 5, chord: Major.V7) -print(V7ofV(C5)) // [D6, F♯6, A6, C7] +print(V7ofV(c5)) // [D6, F♯6, A6, C7] ///``` diff --git a/Playgrounds/FrameworkOverview.playground/timeline.xctimeline b/Playgrounds/FrameworkOverview.playground/timeline.xctimeline index 8a1d9db..29b4919 100644 --- a/Playgrounds/FrameworkOverview.playground/timeline.xctimeline +++ b/Playgrounds/FrameworkOverview.playground/timeline.xctimeline @@ -3,22 +3,22 @@ version = "3.0"> From a8239ae8c0a76ca397d5b69abb799a438c840f20 Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Tue, 14 Mar 2017 09:36:31 -0700 Subject: [PATCH 15/19] * switchify --- MusicKit/ChordName.swift | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/MusicKit/ChordName.swift b/MusicKit/ChordName.swift index c81046e..a4b6236 100644 --- a/MusicKit/ChordName.swift +++ b/MusicKit/ChordName.swift @@ -16,35 +16,30 @@ extension Chord { public static func name(_ pitchSet: PitchSet) -> String? { return descriptor(pitchSet)?.name } - + /// Returns an optional `ChordDescriptor`. public static func descriptor(_ pitchSet: PitchSet) -> ChordDescriptor? { var pitchSet = pitchSet pitchSet.normalize() let count = pitchSet.count let gamutCount = pitchSet.gamut().count - + // early return if: // - less than a dyad after normalization // - one or more pitch is chroma-less if count < 2 || count != gamutCount { return nil } - + let bass = pitchSet[0] let bassChromaOpt = bass.chroma // pitch set with bass removed var bassRemoved = pitchSet _ = bassRemoved.remove(bass) - + // dyads - if count == 2 { - return _descriptor(pitchSet, qualities: ChordQuality.Dyads) - } - // triads - else if count == 3 { - return _descriptor(pitchSet, qualities: ChordQuality.Triads) - } - // Tetrads, Pentads, Hexads, Heptads - else if count > 3 && count < 8 { + switch count { + case 2: return _descriptor(pitchSet, qualities: ChordQuality.Dyads) + case 3: return _descriptor(pitchSet, qualities: ChordQuality.Triads) + case 4..<8: var fullQs = [ChordQuality]() var fullUnalteredQs = [ChordQuality]() var slashQs = [ChordQuality]() @@ -83,17 +78,18 @@ extension Chord { } } return slashNoBassOpt ?? fullOpt + default: return nil } - return nil + } - + /// Returns an optional `ChordDescriptor`. static func _descriptor(_ pitchSet: PitchSet, - qualities: [ChordQuality]) -> ChordDescriptor? + qualities: [ChordQuality]) -> ChordDescriptor? { guard let bass = pitchSet.first else { return nil } let bassChromaOpt = bass.chroma - + let indices = pitchSet.semitoneIndices() // check root position chords for quality in qualities { From 91e5292f99fc7e9cf178479cd7fe32dd21cc32af Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Tue, 14 Mar 2017 09:52:22 -0700 Subject: [PATCH 16/19] * fixed playground --- MusicKit/ChordName.swift | 8 ++--- .../Contents.swift | 31 ++++++++++--------- .../contents.xcplayground | 2 +- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/MusicKit/ChordName.swift b/MusicKit/ChordName.swift index a4b6236..1cce6b8 100644 --- a/MusicKit/ChordName.swift +++ b/MusicKit/ChordName.swift @@ -16,25 +16,25 @@ extension Chord { public static func name(_ pitchSet: PitchSet) -> String? { return descriptor(pitchSet)?.name } - + /// Returns an optional `ChordDescriptor`. public static func descriptor(_ pitchSet: PitchSet) -> ChordDescriptor? { var pitchSet = pitchSet pitchSet.normalize() let count = pitchSet.count let gamutCount = pitchSet.gamut().count - + // early return if: // - less than a dyad after normalization // - one or more pitch is chroma-less if count < 2 || count != gamutCount { return nil } - + let bass = pitchSet[0] let bassChromaOpt = bass.chroma // pitch set with bass removed var bassRemoved = pitchSet _ = bassRemoved.remove(bass) - + // dyads switch count { case 2: return _descriptor(pitchSet, qualities: ChordQuality.Dyads) diff --git a/Playgrounds/UnalteredExtendedChords.playground/Contents.swift b/Playgrounds/UnalteredExtendedChords.playground/Contents.swift index 19d0a5a..58ed92b 100644 --- a/Playgrounds/UnalteredExtendedChords.playground/Contents.swift +++ b/Playgrounds/UnalteredExtendedChords.playground/Contents.swift @@ -8,48 +8,49 @@ var unalteredHexads = ([String](), [String]()) var unalteredHeptads = ([String](), [String]()) for q in unalteredTetrads { // pentad symbols - var name = q.name.stringByReplacingOccurrencesOfString("Seventh", withString: "Ninth") - var symbol = q.description.stringByReplacingOccurrencesOfString("7", withString: "9") + var name = q.name.replacingOccurrences(of: "Seventh", with: "Ninth") + var symbol = q.description.replacingOccurrences(of: "7", with: "9") var symbolLine = "case \(name) = \"\(symbol)\"" unalteredPentads.0.append(symbolLine) // pentad intervals var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.Nine.rawValue)]) + [Float(ChordExtension.nine.rawValue)]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } var intervalLine = "case \(name): return \(intIntervals)" unalteredPentads.1.append(intervalLine) // hexad symbols - name = q.name.stringByReplacingOccurrencesOfString("Seventh", withString: "Eleventh") - symbol = q.description.stringByReplacingOccurrencesOfString("7", withString: "11") + + name = q.name.replacingOccurrences(of: "Seventh", with: "Eleventh") + symbol = q.description.replacingOccurrences(of: "7", with: "11") symbolLine = "case \(name) = \"\(symbol)\"" unalteredHexads.0.append(symbolLine) // hexad intervals intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.Nine.rawValue), - Float(ChordExtension.Eleven.rawValue)]) + [Float(ChordExtension.nine.rawValue), + Float(ChordExtension.eleven.rawValue)]) intIntervals.removeAll() for i in intervals { intIntervals.append(Int(i)) } intervalLine = "case \(name): return \(intIntervals)" unalteredHexads.1.append(intervalLine) // heptad symbols - name = q.name.stringByReplacingOccurrencesOfString("Seventh", withString: "Thirteenth") - symbol = q.description.stringByReplacingOccurrencesOfString("7", withString: "13") + name = q.name.replacingOccurrences(of: "Seventh", with: "Thirteenth") + symbol = q.description.replacingOccurrences(of: "7", with: "13") symbolLine = "case \(name) = \"\(symbol)\"" unalteredHeptads.0.append(symbolLine) // heptad intervals intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.Nine.rawValue), - Float(ChordExtension.Eleven.rawValue), - Float(ChordExtension.Thirteen.rawValue)]) + [Float(ChordExtension.nine.rawValue), + Float(ChordExtension.eleven.rawValue), + Float(ChordExtension.thirteen.rawValue)]) intIntervals.removeAll() for i in intervals { intIntervals.append(Int(i)) } intervalLine = "case \(name): return \(intIntervals)" @@ -65,6 +66,6 @@ func printCode(groupName: String, symbols: [String], intervals: [String]) { print("\n") } -printCode("unaltered pentads", symbols: unalteredPentads.0, intervals: unalteredPentads.1) -printCode("unaltered hexads", symbols: unalteredHexads.0, intervals: unalteredHexads.1) -printCode("unaltered heptads", symbols: unalteredHeptads.0, intervals: unalteredHeptads.1) +printCode(groupName: "unaltered pentads", symbols: unalteredPentads.0, intervals: unalteredPentads.1) +printCode(groupName: "unaltered hexads", symbols: unalteredHexads.0, intervals: unalteredHexads.1) +printCode(groupName: "unaltered heptads", symbols: unalteredHeptads.0, intervals: unalteredHeptads.1) diff --git a/Playgrounds/UnalteredExtendedChords.playground/contents.xcplayground b/Playgrounds/UnalteredExtendedChords.playground/contents.xcplayground index 06828af..6504303 100644 --- a/Playgrounds/UnalteredExtendedChords.playground/contents.xcplayground +++ b/Playgrounds/UnalteredExtendedChords.playground/contents.xcplayground @@ -1,4 +1,4 @@ - + \ No newline at end of file From 12dbe1f8b6792b59d0c256b9a22d085c8a3787b1 Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Tue, 14 Mar 2017 09:54:14 -0700 Subject: [PATCH 17/19] f --- MusicKit/PitchSet.swift | 51 ++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/MusicKit/PitchSet.swift b/MusicKit/PitchSet.swift index b1d441a..69e7afd 100644 --- a/MusicKit/PitchSet.swift +++ b/MusicKit/PitchSet.swift @@ -122,6 +122,31 @@ extension PitchSet: Collection { public subscript(range: Range) -> PitchSetSlice { return PitchSetSlice(contents[range]) } + + // MARK: Operators + static public func +(lhs: PitchSet, rhs: PitchSet) -> PitchSet { + var lhs = lhs + lhs.insert(rhs) + return lhs + } + + static public func +=(lhs: inout PitchSet, rhs: PitchSet) { + lhs.insert(rhs) + } + + static public func -(lhs: PitchSet, rhs: PitchSet) -> PitchSet { + var lhs = lhs + for pitch in rhs { + _ = lhs.remove(pitch) + } + return lhs + } + + static public func -=(lhs: inout PitchSet, rhs: PitchSet) { + for pitch in rhs { + _ = lhs.remove(pitch) + } + } } // MARK: ArrayLiteralConvertible @@ -137,32 +162,6 @@ extension PitchSet : BidirectionalCollection { } } - -// MARK: Operators -public func +(lhs: PitchSet, rhs: PitchSet) -> PitchSet { - var lhs = lhs - lhs.insert(rhs) - return lhs -} - -public func +=(lhs: inout PitchSet, rhs: PitchSet) { - lhs.insert(rhs) -} - -public func -(lhs: PitchSet, rhs: PitchSet) -> PitchSet { - var lhs = lhs - for pitch in rhs { - _ = lhs.remove(pitch) - } - return lhs -} - -public func -=(lhs: inout PitchSet, rhs: PitchSet) { - for pitch in rhs { - _ = lhs.remove(pitch) - } -} - // MARK: == PitchSetSlice == /// A slice of a `PitchSet`. public struct PitchSetSlice { From 5ec071f9a8410d3fdc154ae52ba5da7b3714eccb Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Tue, 14 Mar 2017 09:58:41 -0700 Subject: [PATCH 18/19] * fixed one more playground --- MusicKit/PitchSet.swift | 1 - .../Contents.swift | 30 +++++++++---------- .../contents.xcplayground | 2 +- .../contents.xcplayground | 2 +- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/MusicKit/PitchSet.swift b/MusicKit/PitchSet.swift index 69e7afd..b90ab4a 100644 --- a/MusicKit/PitchSet.swift +++ b/MusicKit/PitchSet.swift @@ -38,7 +38,6 @@ public struct PitchSet : Equatable { return index(of: pitch) != nil } - /// Returns a new `PitchSet` with the combined contents of `self` and the given pitches. public func merge(_ pitches: Element...) -> PitchSet { return merge(pitches) diff --git a/Playgrounds/AlteredHexadsSingle.playground/Contents.swift b/Playgrounds/AlteredHexadsSingle.playground/Contents.swift index a1cf311..a780cec 100644 --- a/Playgrounds/AlteredHexadsSingle.playground/Contents.swift +++ b/Playgrounds/AlteredHexadsSingle.playground/Contents.swift @@ -15,17 +15,17 @@ var nonDiminishedAugmentedTetrads = unalteredTetrads.filter { var flatNines = ([String](), [String]()) for q in unalteredTetrads { - var name = q.name.stringByReplacingOccurrencesOfString("Seventh", withString: "Eleventh") + var name = q.name.replacingOccurrences(of: "Seventh", with: "Eleventh") name = name + "FlatNine" - var symbol = q.description.stringByReplacingOccurrencesOfString("7", withString: "11") + var symbol = q.description.replacingOccurrences(of: "7", with: "11") symbol = symbol + "♭9" var symbolLine = "case \(name) = \"\(symbol)\"" flatNines.0.append(symbolLine) var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.FlatNine.rawValue), - Float(ChordExtension.Eleven.rawValue)]) + [Float(ChordExtension.flatNine.rawValue), + Float(ChordExtension.eleven.rawValue)]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } var intervalLine = "case \(name): return \(intIntervals)" @@ -34,17 +34,17 @@ for q in unalteredTetrads { var sharpElevens = ([String](), [String]()) for q in nonDiminishedTetrads { - var name = q.name.stringByReplacingOccurrencesOfString("Seventh", withString: "Ninth") + var name = q.name.replacingOccurrences(of: "Seventh", with: "Ninth") name = name + "SharpEleven" - var symbol = q.description.stringByReplacingOccurrencesOfString("7", withString: "9") + var symbol = q.description.replacingOccurrences(of: "7", with: "9") symbol = symbol + "♯11" var symbolLine = "case \(name) = \"\(symbol)\"" sharpElevens.0.append(symbolLine) var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.Nine.rawValue), - Float(ChordExtension.SharpEleven.rawValue)]) + [Float(ChordExtension.nine.rawValue), + Float(ChordExtension.sharpEleven.rawValue)]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } var intervalLine = "case \(name): return \(intIntervals)" @@ -53,17 +53,17 @@ for q in nonDiminishedTetrads { var flatThirteens = ([String](), [String]()) for q in nonAugmentedTetrads { - var name = q.name.stringByReplacingOccurrencesOfString("Seventh", withString: "Ninth") + var name = q.name.replacingOccurrences(of: "Seventh", with: "Ninth") name = name + "FlatThirteen" - var symbol = q.description.stringByReplacingOccurrencesOfString("7", withString: "9") + var symbol = q.description.replacingOccurrences(of: "7", with: "9") symbol = symbol + "♭13" var symbolLine = "case \(name) = \"\(symbol)\"" flatThirteens.0.append(symbolLine) var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.Nine.rawValue), - Float(ChordExtension.FlatThirteen.rawValue)]) + [Float(ChordExtension.nine.rawValue), + Float(ChordExtension.flatThirteen.rawValue)]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } var intervalLine = "case \(name): return \(intIntervals)" @@ -79,6 +79,6 @@ func printCode(groupName: String, symbols: [String], intervals: [String]) { print("\n") } -printCode("flat nine hexads", symbols: flatNines.0, intervals: flatNines.1) -printCode("sharp eleven hexads", symbols: sharpElevens.0, intervals: sharpElevens.1) -printCode("flat thirteen hexads", symbols: flatThirteens.0, intervals: flatThirteens.1) +printCode(groupName: "flat nine hexads", symbols: flatNines.0, intervals: flatNines.1) +printCode(groupName: "sharp eleven hexads", symbols: sharpElevens.0, intervals: sharpElevens.1) +printCode(groupName: "flat thirteen hexads", symbols: flatThirteens.0, intervals: flatThirteens.1) diff --git a/Playgrounds/AlteredHexadsSingle.playground/contents.xcplayground b/Playgrounds/AlteredHexadsSingle.playground/contents.xcplayground index 06828af..6504303 100644 --- a/Playgrounds/AlteredHexadsSingle.playground/contents.xcplayground +++ b/Playgrounds/AlteredHexadsSingle.playground/contents.xcplayground @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/Playgrounds/AlteredPentads.playground/contents.xcplayground b/Playgrounds/AlteredPentads.playground/contents.xcplayground index 06828af..6504303 100644 --- a/Playgrounds/AlteredPentads.playground/contents.xcplayground +++ b/Playgrounds/AlteredPentads.playground/contents.xcplayground @@ -1,4 +1,4 @@ - + \ No newline at end of file From 8359e0f3091aa4bb62eda807f28c5755864ab2c2 Mon Sep 17 00:00:00 2001 From: Adam Nemecek Date: Tue, 14 Mar 2017 10:04:23 -0700 Subject: [PATCH 19/19] * fixed remaining playgrounds --- .../Contents.swift | 44 +++++++++---------- .../contents.xcplayground | 2 +- .../Contents.swift | 36 +++++++-------- .../contents.xcplayground | 2 +- .../Contents.swift | 22 +++++----- .../contents.xcplayground | 2 +- 6 files changed, 54 insertions(+), 54 deletions(-) diff --git a/Playgrounds/AlteredHeptadsMulti.playground/Contents.swift b/Playgrounds/AlteredHeptadsMulti.playground/Contents.swift index c9220e1..2b2fb9d 100644 --- a/Playgrounds/AlteredHeptadsMulti.playground/Contents.swift +++ b/Playgrounds/AlteredHeptadsMulti.playground/Contents.swift @@ -15,18 +15,18 @@ var nonDiminishedAugmentedTetrads = unalteredTetrads.filter { var flatNineSharpElevens = ([String](), [String]()) for q in nonDiminishedTetrads { - var name = q.name.stringByReplacingOccurrencesOfString("Seventh", withString: "Thirteenth") + var name = q.name.replacingOccurrences(of: "Seventh", with: "Thirteenth") name = name + "FlatNineSharpEleven" - var symbol = q.description.stringByReplacingOccurrencesOfString("7", withString: "13") + var symbol = q.description.replacingOccurrences(of: "7", with: "13") symbol = symbol + "♭9♯11" var symbolLine = "case \(name) = \"\(symbol)\"" flatNineSharpElevens.0.append(symbolLine) var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.FlatNine.rawValue), - Float(ChordExtension.SharpEleven.rawValue), - Float(ChordExtension.Thirteen.rawValue), + [Float(ChordExtension.flatNine.rawValue), + Float(ChordExtension.sharpEleven.rawValue), + Float(ChordExtension.thirteen.rawValue), ]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } @@ -36,18 +36,18 @@ for q in nonDiminishedTetrads { var flatNineFlatThirteens = ([String](), [String]()) for q in nonAugmentedTetrads { - var name = q.name.stringByReplacingOccurrencesOfString("Seventh", withString: "Eleventh") + var name = q.name.replacingOccurrences(of: "Seventh", with: "Eleventh") name = name + "FlatNineFlatThirteen" - var symbol = q.description.stringByReplacingOccurrencesOfString("7", withString: "11") + var symbol = q.description.replacingOccurrences(of: "7", with: "11") symbol = symbol + "♭9♭13" var symbolLine = "case \(name) = \"\(symbol)\"" flatNineFlatThirteens.0.append(symbolLine) var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.FlatNine.rawValue), - Float(ChordExtension.Eleven.rawValue), - Float(ChordExtension.FlatThirteen.rawValue)]) + [Float(ChordExtension.flatNine.rawValue), + Float(ChordExtension.eleven.rawValue), + Float(ChordExtension.flatThirteen.rawValue)]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } var intervalLine = "case \(name): return \(intIntervals)" @@ -56,18 +56,18 @@ for q in nonAugmentedTetrads { var sharpElevenFlatThirteens = ([String](), [String]()) for q in nonDiminishedAugmentedTetrads { - var name = q.name.stringByReplacingOccurrencesOfString("Seventh", withString: "Ninth") + var name = q.name.replacingOccurrences(of: "Seventh", with: "Ninth") name = name + "SharpElevenFlatThirteen" - var symbol = q.description.stringByReplacingOccurrencesOfString("7", withString: "9") + var symbol = q.description.replacingOccurrences(of: "7", with: "9") symbol = symbol + "♯11♭13" var symbolLine = "case \(name) = \"\(symbol)\"" sharpElevenFlatThirteens.0.append(symbolLine) var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.Nine.rawValue), - Float(ChordExtension.SharpEleven.rawValue), - Float(ChordExtension.FlatThirteen.rawValue)]) + [Float(ChordExtension.nine.rawValue), + Float(ChordExtension.sharpEleven.rawValue), + Float(ChordExtension.flatThirteen.rawValue)]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } var intervalLine = "case \(name): return \(intIntervals)" @@ -83,9 +83,9 @@ for q in nonDiminishedAugmentedTetrads { var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.FlatNine.rawValue), - Float(ChordExtension.SharpEleven.rawValue), - Float(ChordExtension.FlatThirteen.rawValue)]) + [Float(ChordExtension.flatNine.rawValue), + Float(ChordExtension.sharpEleven.rawValue), + Float(ChordExtension.flatThirteen.rawValue)]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } var intervalLine = "case \(name): return \(intIntervals)" @@ -101,7 +101,7 @@ func printCode(groupName: String, symbols: [String], intervals: [String]) { print("\n") } -printCode("flat nine sharp eleven heptads", symbols: flatNineSharpElevens.0, intervals: flatNineSharpElevens.1) -printCode("flat nine flat thirteen heptads", symbols: flatNineFlatThirteens.0, intervals: flatNineFlatThirteens.1) -printCode("sharp eleven flat thirteen heptads", symbols: sharpElevenFlatThirteens.0, intervals: sharpElevenFlatThirteens.1) -printCode("flat nine sharp eleven flat thirteen heptads", symbols: flatNineSharpElevenFlatThirteens.0, intervals: flatNineSharpElevenFlatThirteens.1) +printCode(groupName: "flat nine sharp eleven heptads", symbols: flatNineSharpElevens.0, intervals: flatNineSharpElevens.1) +printCode(groupName: "flat nine flat thirteen heptads", symbols: flatNineFlatThirteens.0, intervals: flatNineFlatThirteens.1) +printCode(groupName: "sharp eleven flat thirteen heptads", symbols: sharpElevenFlatThirteens.0, intervals: sharpElevenFlatThirteens.1) +printCode(groupName: "flat nine sharp eleven flat thirteen heptads", symbols: flatNineSharpElevenFlatThirteens.0, intervals: flatNineSharpElevenFlatThirteens.1) diff --git a/Playgrounds/AlteredHeptadsMulti.playground/contents.xcplayground b/Playgrounds/AlteredHeptadsMulti.playground/contents.xcplayground index 06828af..6504303 100644 --- a/Playgrounds/AlteredHeptadsMulti.playground/contents.xcplayground +++ b/Playgrounds/AlteredHeptadsMulti.playground/contents.xcplayground @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/Playgrounds/AlteredHeptadsSingle.playground/Contents.swift b/Playgrounds/AlteredHeptadsSingle.playground/Contents.swift index 1ee30ee..8e0ec79 100644 --- a/Playgrounds/AlteredHeptadsSingle.playground/Contents.swift +++ b/Playgrounds/AlteredHeptadsSingle.playground/Contents.swift @@ -15,18 +15,18 @@ var nonDiminishedAugmentedTetrads = unalteredTetrads.filter { var flatNines = ([String](), [String]()) for q in unalteredTetrads { - var name = q.name.stringByReplacingOccurrencesOfString("Seventh", withString: "Thirteenth") + var name = q.name.replacingOccurrences(of: "Seventh", with: "Thirteenth") name = name + "FlatNine" - var symbol = q.description.stringByReplacingOccurrencesOfString("7", withString: "13") + var symbol = q.description.replacingOccurrences(of: "7", with: "13") symbol = symbol + "♭9" var symbolLine = "case \(name) = \"\(symbol)\"" flatNines.0.append(symbolLine) var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.FlatNine.rawValue), - Float(ChordExtension.Eleven.rawValue), - Float(ChordExtension.Thirteen.rawValue), + [Float(ChordExtension.flatNine.rawValue), + Float(ChordExtension.eleven.rawValue), + Float(ChordExtension.thirteen.rawValue), ]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } @@ -36,18 +36,18 @@ for q in unalteredTetrads { var sharpElevens = ([String](), [String]()) for q in nonDiminishedTetrads { - var name = q.name.stringByReplacingOccurrencesOfString("Seventh", withString: "Thirteenth") + var name = q.name.replacingOccurrences(of: "Seventh", with: "Thirteenth") name = name + "SharpEleven" - var symbol = q.description.stringByReplacingOccurrencesOfString("7", withString: "13") + var symbol = q.description.replacingOccurrences(of: "7", with: "13") symbol = symbol + "♯11" var symbolLine = "case \(name) = \"\(symbol)\"" sharpElevens.0.append(symbolLine) var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.Nine.rawValue), - Float(ChordExtension.SharpEleven.rawValue), - Float(ChordExtension.Thirteen.rawValue), + [Float(ChordExtension.nine.rawValue), + Float(ChordExtension.sharpEleven.rawValue), + Float(ChordExtension.thirteen.rawValue), ]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } @@ -57,18 +57,18 @@ for q in nonDiminishedTetrads { var flatThirteens = ([String](), [String]()) for q in nonAugmentedTetrads { - var name = q.name.stringByReplacingOccurrencesOfString("Seventh", withString: "Eleventh") + var name = q.name.replacingOccurrences(of: "Seventh", with: "Eleventh") name = name + "FlatThirteen" - var symbol = q.description.stringByReplacingOccurrencesOfString("7", withString: "11") + var symbol = q.description.replacingOccurrences(of: "7", with: "11") symbol = symbol + "♭13" var symbolLine = "case \(name) = \"\(symbol)\"" flatThirteens.0.append(symbolLine) var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.Nine.rawValue), - Float(ChordExtension.Eleven.rawValue), - Float(ChordExtension.FlatThirteen.rawValue)]) + [Float(ChordExtension.nine.rawValue), + Float(ChordExtension.eleven.rawValue), + Float(ChordExtension.flatThirteen.rawValue)]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } var intervalLine = "case \(name): return \(intIntervals)" @@ -84,6 +84,6 @@ func printCode(groupName: String, symbols: [String], intervals: [String]) { print("\n") } -printCode("flat nine heptads", symbols: flatNines.0, intervals: flatNines.1) -printCode("sharp eleven heptads", symbols: sharpElevens.0, intervals: sharpElevens.1) -printCode("flat thirteen heptads", symbols: flatThirteens.0, intervals: flatThirteens.1) +printCode(groupName: "flat nine heptads", symbols: flatNines.0, intervals: flatNines.1) +printCode(groupName: "sharp eleven heptads", symbols: sharpElevens.0, intervals: sharpElevens.1) +printCode(groupName: "flat thirteen heptads", symbols: flatThirteens.0, intervals: flatThirteens.1) diff --git a/Playgrounds/AlteredHeptadsSingle.playground/contents.xcplayground b/Playgrounds/AlteredHeptadsSingle.playground/contents.xcplayground index 06828af..6504303 100644 --- a/Playgrounds/AlteredHeptadsSingle.playground/contents.xcplayground +++ b/Playgrounds/AlteredHeptadsSingle.playground/contents.xcplayground @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/Playgrounds/AlteredHexadsMulti.playground/Contents.swift b/Playgrounds/AlteredHexadsMulti.playground/Contents.swift index 154b960..0dc01b1 100644 --- a/Playgrounds/AlteredHexadsMulti.playground/Contents.swift +++ b/Playgrounds/AlteredHexadsMulti.playground/Contents.swift @@ -15,15 +15,15 @@ var nonDiminishedAugmentedTetrads = unalteredTetrads.filter { var flatNineSharpElevens = ([String](), [String]()) for q in nonDiminishedTetrads { - var name = q.name + "FlatNineSharpEleven" + var name = q.name + "flatNineSharpEleven" var symbol = q.description + "♭9♯11" var symbolLine = "case \(name) = \"\(symbol)\"" flatNineSharpElevens.0.append(symbolLine) var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.FlatNine.rawValue), - Float(ChordExtension.SharpEleven.rawValue)]) + [Float(ChordExtension.flatNine.rawValue), + Float(ChordExtension.sharpEleven.rawValue)]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } var intervalLine = "case \(name): return \(intIntervals)" @@ -32,15 +32,15 @@ for q in nonDiminishedTetrads { var flatNineFlatThirteens = ([String](), [String]()) for q in nonAugmentedTetrads { - var name = q.name + "FlatNineFlatThirteen" + var name = q.name + "flatNineFlatThirteen" var symbol = q.description + "♭9♭13" var symbolLine = "case \(name) = \"\(symbol)\"" flatNineFlatThirteens.0.append(symbolLine) var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.FlatNine.rawValue), - Float(ChordExtension.FlatThirteen.rawValue)]) + [Float(ChordExtension.flatNine.rawValue), + Float(ChordExtension.flatThirteen.rawValue)]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } var intervalLine = "case \(name): return \(intIntervals)" @@ -56,8 +56,8 @@ for q in nonDiminishedAugmentedTetrads { var intervals = MKUtil.intervals( MKUtil.semitoneIndices(q.intervals) + - [Float(ChordExtension.SharpEleven.rawValue), - Float(ChordExtension.FlatThirteen.rawValue)]) + [Float(ChordExtension.sharpEleven.rawValue), + Float(ChordExtension.flatThirteen.rawValue)]) var intIntervals = [Int]() for i in intervals { intIntervals.append(Int(i)) } var intervalLine = "case \(name): return \(intIntervals)" @@ -73,6 +73,6 @@ func printCode(groupName: String, symbols: [String], intervals: [String]) { print("\n") } -printCode("flat nine sharp eleven hexads", symbols: flatNineSharpElevens.0, intervals: flatNineSharpElevens.1) -printCode("flat nine flat thirteen hexads", symbols: flatNineFlatThirteens.0, intervals: flatNineFlatThirteens.1) -printCode("sharp eleven flat thirteen hexads", symbols: sharpElevenFlatThirteens.0, intervals: sharpElevenFlatThirteens.1) +printCode(groupName: "flat nine sharp eleven hexads", symbols: flatNineSharpElevens.0, intervals: flatNineSharpElevens.1) +printCode(groupName: "flat nine flat thirteen hexads", symbols: flatNineFlatThirteens.0, intervals: flatNineFlatThirteens.1) +printCode(groupName: "sharp eleven flat thirteen hexads", symbols: sharpElevenFlatThirteens.0, intervals: sharpElevenFlatThirteens.1) diff --git a/Playgrounds/AlteredHexadsMulti.playground/contents.xcplayground b/Playgrounds/AlteredHexadsMulti.playground/contents.xcplayground index 06828af..6504303 100644 --- a/Playgrounds/AlteredHexadsMulti.playground/contents.xcplayground +++ b/Playgrounds/AlteredHexadsMulti.playground/contents.xcplayground @@ -1,4 +1,4 @@ - + \ No newline at end of file