@@ -9,26 +9,24 @@ var currentNote: Note?
99var currentNoteEndTime : Date ?
1010
1111struct ContentView : View {
12-
1312 let songsList : [ Song ]
14-
13+
1514 private let timer = Timer . publish ( every: timerInterval, tolerance: timerInterval, on: . main, in: . common) . autoconnect ( )
16-
15+
1716 @State private var timerEnabled = false
18-
19- @State private var currentNoteIndex : Int = 0 ;
20-
17+
18+ @State private var currentNoteIndex : Int = 0
19+
2120 @State private var tempo = 144.0
2221 @State private var currentSongIndex : Int = 0
23-
22+
2423 init ( songsRepository: SongsRepository ) {
25- self . songsList = songsRepository. listSongs ( )
24+ songsList = songsRepository. listSongs ( )
2625 }
27-
26+
2827 var body : some View {
28+ let tempoStr = String ( format: " %d " , Int ( self . tempo) ) . padding ( toLength: 5 , withPad: " " , startingAt: 0 )
2929
30- let tempoStr = String ( format: " %.1f " , self . tempo) . padding ( toLength: 5 , withPad: " " , startingAt: 0 ) ;
31-
3230 return HStack {
3331 Spacer ( )
3432 . frame ( width: 64.0 )
@@ -41,7 +39,7 @@ struct ContentView: View {
4139 }
4240 HStack {
4341 Text ( " Tempo: \( tempoStr) BPM " ) . frame ( width: 150 , alignment: . leading)
44- Slider ( value: $tempo, in: 40 ... 300 , step: 8 )
42+ Slider ( value: $tempo, in: 40 ... 300 , step: 8 )
4543 }
4644 Spacer ( )
4745 Text ( " Don't take your finger off of the trackpad! " )
@@ -60,111 +58,111 @@ struct ContentView: View {
6058 self . playTick ( time: time)
6159 }
6260 }
63-
64- func handlePickerChange( _ index : Int ) {
65- self . tempo = songsList [ currentSongIndex] . defaultTempo
66- self . stop ( )
61+
62+ func handlePickerChange( _: Int ) {
63+ tempo = songsList [ currentSongIndex] . defaultTempo
64+ stop ( )
6765 }
68-
66+
6967 func toggleTimer( ) {
70- if ( self . timerEnabled) {
71- self . stop ( )
68+ if timerEnabled {
69+ stop ( )
7270 } else {
73- self . start ( )
71+ start ( )
7472 }
7573 }
76-
74+
7775 func start( ) {
78- self . timerEnabled = true
79- self . enqueueInitialNote ( )
76+ timerEnabled = true
77+ enqueueInitialNote ( )
8078 }
81-
79+
8280 func stop( ) {
83- self . timerEnabled = false
84- self . currentNoteIndex = 0
81+ timerEnabled = false
82+ currentNoteIndex = 0
8583 currentNote = nil
8684 currentNoteEndTime = nil
8785 skippedTicksCount = 0
8886 }
89-
87+
9088 func playTick( time: Date ) {
9189 guard timerEnabled else { return }
9290 guard let currentNote = currentNote else { return }
9391 guard let currentNoteEndTime = currentNoteEndTime else { return }
94-
95- if ( time > currentNoteEndTime) {
96- self . enqueueNextNote ( )
92+
93+ if time > currentNoteEndTime {
94+ enqueueNextNote ( )
9795 }
98-
99- self . playTickOfTone ( frequency: currentNote. frequency)
96+
97+ playTickOfTone ( frequency: currentNote. frequency)
10098 }
101-
99+
102100 func enqueueInitialNote( ) {
103- self . currentNoteIndex = 0
104- self . enqueueNote ( )
101+ currentNoteIndex = 0
102+ enqueueNote ( )
105103 }
106-
104+
107105 func enqueueNextNote( ) {
108- self . currentNoteIndex += 1
109- self . enqueueNote ( )
106+ currentNoteIndex += 1
107+ enqueueNote ( )
110108 }
111-
109+
112110 func enqueueNote( ) {
113- guard let note = self . loadNote ( index: self . currentNoteIndex) else {
111+ guard let note = loadNote ( index: currentNoteIndex) else {
114112 // End of song
115- self . stop ( )
113+ stop ( )
116114 return
117115 }
118-
116+
119117 // Time it takes to play a note with 4 beats
120118 // (1min / tempo (bpm))
121- let baseDuration = ( 60000.0 ) / tempo
122-
119+ let baseDuration = 60000.0 / tempo
120+
123121 let noteDuration = baseDuration * note. value
124-
122+
125123 skippedTicksCount = 0
126- currentNote = note;
124+ currentNote = note
127125 currentNoteEndTime = Date ( ) . addingTimeInterval ( noteDuration / 1000.0 )
128126 }
129-
127+
130128 func loadNote( index: Int ) -> Note ? {
131- let currentSong = self . songsList [ currentSongIndex]
132-
133- if ( index >= currentSong. notes. endIndex) {
129+ let currentSong = songsList [ currentSongIndex]
130+
131+ if index >= currentSong. notes. endIndex {
134132 return nil
135133 }
136-
134+
137135 return currentSong. notes [ index]
138136 }
139-
137+
140138 /// Software PWM
141139 /// Only performs haptic feedback in fractions of the timer frequency
142140 /// Example: If timer has frequency of 1000 Hz and we want to play at 100Hz,
143141 /// we need to skip 9 clock ticks. This way, we play once every 10 ticks (1000/10 = 100)
144142 func playTickOfTone( frequency: Double ) {
145- if ( frequency == 0 ) {
146- return ;
143+ if frequency == 0 {
144+ return
147145 }
148146 let clockTicksPerToneTick = Int ( timerClockHz / frequency)
149147 let clockTicksToSkip = clockTicksPerToneTick - 1
150-
151- if ( skippedTicksCount < clockTicksToSkip) {
148+
149+ if skippedTicksCount < clockTicksToSkip {
152150 skippedTicksCount += 1
153151 return
154152 }
155-
156- self . performHapticFeedback ( )
153+
154+ performHapticFeedback ( )
157155 skippedTicksCount = 0
158156 }
159-
157+
160158 func performHapticFeedback( ) {
161159 NSHapticFeedbackManager . defaultPerformer. perform (
162160 NSHapticFeedbackManager . FeedbackPattern. generic,
163- performanceTime: NSHapticFeedbackManager . PerformanceTime. now)
161+ performanceTime: NSHapticFeedbackManager . PerformanceTime. now
162+ )
164163 }
165164}
166165
167-
168166struct ContentView_Previews : PreviewProvider {
169167 static var previews : some View {
170168 ContentView ( songsRepository: SongsRepository ( ) )
0 commit comments