diff --git a/ForceTouchPlayer.xcodeproj/project.pbxproj b/ForceTouchPlayer.xcodeproj/project.pbxproj index e6050a6..6ea8423 100644 --- a/ForceTouchPlayer.xcodeproj/project.pbxproj +++ b/ForceTouchPlayer.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ 31ED4854252FFA15002B9BAD /* Tetris.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31ED4853252FFA15002B9BAD /* Tetris.swift */; }; 7D830402253FB48E002466B0 /* HedwigsTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D830401253FB48E002466B0 /* HedwigsTheme.swift */; }; 7DDC3568253DC8D000F48DCD /* ImperialMarch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DDC3567253DC8D000F48DCD /* ImperialMarch.swift */; }; + 9729DA332985EC9A004C9AB3 /* Greensleeves.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9729DA322985EC9A004C9AB3 /* Greensleeves.swift */; }; BA357D2725D6B85900300A5E /* CantinaBand.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA357D2525D6B85900300A5E /* CantinaBand.swift */; }; BA357D2825D6B85900300A5E /* Doom.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA357D2625D6B85900300A5E /* Doom.swift */; }; /* End PBXBuildFile section */ @@ -43,6 +44,7 @@ 31ED4853252FFA15002B9BAD /* Tetris.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tetris.swift; sourceTree = ""; }; 7D830401253FB48E002466B0 /* HedwigsTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HedwigsTheme.swift; sourceTree = ""; }; 7DDC3567253DC8D000F48DCD /* ImperialMarch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImperialMarch.swift; sourceTree = ""; }; + 9729DA322985EC9A004C9AB3 /* Greensleeves.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Greensleeves.swift; sourceTree = ""; }; BA357D2525D6B85900300A5E /* CantinaBand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CantinaBand.swift; sourceTree = ""; }; BA357D2625D6B85900300A5E /* Doom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Doom.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -110,6 +112,7 @@ 31A156D22530030800777E42 /* HappyBirthday.swift */, 7DDC3567253DC8D000F48DCD /* ImperialMarch.swift */, 7D830401253FB48E002466B0 /* HedwigsTheme.swift */, + 9729DA322985EC9A004C9AB3 /* Greensleeves.swift */, 317A217B2541277B00A96DF2 /* CMajorScale.swift */, ); path = Songs; @@ -189,6 +192,7 @@ 31ED484D252FE058002B9BAD /* Song.swift in Sources */, BA357D2825D6B85900300A5E /* Doom.swift in Sources */, 311A7A9C252D08620072A16B /* ContentView.swift in Sources */, + 9729DA332985EC9A004C9AB3 /* Greensleeves.swift in Sources */, 7D830402253FB48E002466B0 /* HedwigsTheme.swift in Sources */, 31ED4854252FFA15002B9BAD /* Tetris.swift in Sources */, 7DDC3568253DC8D000F48DCD /* ImperialMarch.swift in Sources */, diff --git a/ForceTouchPlayer/Songs/Greensleeves.swift b/ForceTouchPlayer/Songs/Greensleeves.swift new file mode 100644 index 0000000..e784c24 --- /dev/null +++ b/ForceTouchPlayer/Songs/Greensleeves.swift @@ -0,0 +1,70 @@ +// +// Greensleeves.swift +// ForceTouchPlayer +// +// Created by Arthur Ginzburg on 29.01.2023. +// Copyright © 2023 Danilo Campana Fuchs. All rights reserved. +// +// Adapted from https://github.com/robsoncouto/arduino-songs/blob/master/greensleeves/greensleeves.ino +// + +import Foundation + +// matched from different songs that existed in both this repo and the arduino-songs repo. +//let DURATION_OVERRIDE_MINUS_16 = 0.375; // from Doom +let DURATION_OVERRIDE_MINUS_8 = 0.5; // out of thin air, did not find references. +//let DURATION_OVERRIDE_MINUS_4 = 1; +let DURATION_OVERRIDE_MINUS_2 = 2.0; +let DURATION_OVERRIDE_2 = 0.9; // out of thin air, did not find references. +let DURATION_OVERRIDE_4 = 0.75; +let DURATION_OVERRIDE_8 = 0.25; +let DURATION_OVERRIDE_16 = 0.1; // out of thin air, did not find references. + +// TODO: prevent these constants from being global. They should only be relevant for this song (but I did not check this approach with other songs). + +// just replaced every 5 with 2, and every 4 with 1 for now, nothing complicated. But it worked. +let OVERRIDE_NOTE_G4 = NOTE_G1; +let OVERRIDE_NOTE_AS4 = NOTE_AS1; +let OVERRIDE_NOTE_C5 = NOTE_C2; +let OVERRIDE_NOTE_D5 = NOTE_D2; +let OVERRIDE_NOTE_DS5 = NOTE_DS2; +let OVERRIDE_NOTE_A4 = NOTE_A1; +let OVERRIDE_NOTE_F4 = NOTE_F1; +let OVERRIDE_NOTE_FS4 = NOTE_FS1; +let OVERRIDE_NOTE_D4 = NOTE_D1; +let OVERRIDE_NOTE_E4 = NOTE_E1; +let OVERRIDE_NOTE_F5 = NOTE_F2; // highest note +let OVERRIDE_NOTE_E5 = NOTE_E2; + +let greensleeves = Song( + name: "Greensleeves", + defaultTempo: 82.0, // searched the Web for "greensleeves bpm" + padding: Note(frequency: REST, value: 0.28), // out of thin air. Chose a value that made the song slow enough but still melodical. + rawNotes: [ +// Translated these notes from arduino to Swift this way: +// Opened https://chat.openai.com +// Texted: `Group this C array by each 2 values and translate into Swift:`, added a newline, and pasted the arduino array. And sent the message to the AI. + (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_8), + (OVERRIDE_NOTE_AS4,DURATION_OVERRIDE_4), (OVERRIDE_NOTE_C5,DURATION_OVERRIDE_8), (OVERRIDE_NOTE_D5,DURATION_OVERRIDE_MINUS_8), (OVERRIDE_NOTE_DS5,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_D5,DURATION_OVERRIDE_8), + (OVERRIDE_NOTE_C5,DURATION_OVERRIDE_4), (OVERRIDE_NOTE_A4,DURATION_OVERRIDE_8), (OVERRIDE_NOTE_F4,DURATION_OVERRIDE_MINUS_8), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_A4,DURATION_OVERRIDE_8), + (OVERRIDE_NOTE_AS4,DURATION_OVERRIDE_4), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_8), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_MINUS_8), (OVERRIDE_NOTE_FS4,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_8), + (OVERRIDE_NOTE_A4,DURATION_OVERRIDE_4), (OVERRIDE_NOTE_FS4,DURATION_OVERRIDE_8), (OVERRIDE_NOTE_D4,DURATION_OVERRIDE_4), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_8), + + (OVERRIDE_NOTE_AS4,DURATION_OVERRIDE_4), (OVERRIDE_NOTE_C5,DURATION_OVERRIDE_8), (OVERRIDE_NOTE_D5,DURATION_OVERRIDE_MINUS_8), (OVERRIDE_NOTE_DS5,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_D5,DURATION_OVERRIDE_8), + (OVERRIDE_NOTE_C5,DURATION_OVERRIDE_4), (OVERRIDE_NOTE_A4,DURATION_OVERRIDE_8), (OVERRIDE_NOTE_F4,DURATION_OVERRIDE_MINUS_8), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_A4,DURATION_OVERRIDE_8), + (OVERRIDE_NOTE_AS4,DURATION_OVERRIDE_MINUS_8), (OVERRIDE_NOTE_A4,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_8), (OVERRIDE_NOTE_FS4,DURATION_OVERRIDE_MINUS_8), (OVERRIDE_NOTE_E4,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_FS4,DURATION_OVERRIDE_8), + (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_MINUS_2), + (OVERRIDE_NOTE_F5,DURATION_OVERRIDE_2), (OVERRIDE_NOTE_E5,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_D5,DURATION_OVERRIDE_8), + + (OVERRIDE_NOTE_C5,DURATION_OVERRIDE_4), (OVERRIDE_NOTE_A4,DURATION_OVERRIDE_8), (OVERRIDE_NOTE_F4,DURATION_OVERRIDE_MINUS_8), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_A4,DURATION_OVERRIDE_8), + (OVERRIDE_NOTE_AS4,DURATION_OVERRIDE_4), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_8), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_MINUS_8), (OVERRIDE_NOTE_FS4,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_8), + (OVERRIDE_NOTE_A4,DURATION_OVERRIDE_4), (OVERRIDE_NOTE_FS4,DURATION_OVERRIDE_8), (OVERRIDE_NOTE_D4,DURATION_OVERRIDE_4), + (OVERRIDE_NOTE_F5,DURATION_OVERRIDE_2), (OVERRIDE_NOTE_E5,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_D5,DURATION_OVERRIDE_8), + (OVERRIDE_NOTE_C5,DURATION_OVERRIDE_4), (OVERRIDE_NOTE_A4,DURATION_OVERRIDE_8), (OVERRIDE_NOTE_F4,DURATION_OVERRIDE_MINUS_8), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_A4,DURATION_OVERRIDE_8), + + (OVERRIDE_NOTE_AS4,DURATION_OVERRIDE_MINUS_8), (OVERRIDE_NOTE_A4,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_8), (OVERRIDE_NOTE_FS4,DURATION_OVERRIDE_MINUS_8), (OVERRIDE_NOTE_E4,DURATION_OVERRIDE_16), (OVERRIDE_NOTE_FS4,DURATION_OVERRIDE_8), + (OVERRIDE_NOTE_G4,DURATION_OVERRIDE_MINUS_2) +// then it just repeats once more in the arduino code. Decided to DRY it. + ] +) + diff --git a/ForceTouchPlayer/SongsRepository.swift b/ForceTouchPlayer/SongsRepository.swift index 11fcb91..4546caf 100644 --- a/ForceTouchPlayer/SongsRepository.swift +++ b/ForceTouchPlayer/SongsRepository.swift @@ -10,6 +10,7 @@ struct SongsRepository { cMajorScale, cantinaBand, doomE1M1, + greensleeves, ] func listSongs() -> [Song] {