diff --git a/Visualizer.xcodeproj/project.pbxproj b/Visualizer.xcodeproj/project.pbxproj index f336356..f07b86a 100644 --- a/Visualizer.xcodeproj/project.pbxproj +++ b/Visualizer.xcodeproj/project.pbxproj @@ -3,24 +3,18 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ - FA9F16A624D320B200401F2D /* AmplitudeVisualizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA9F16A524D320B200401F2D /* AmplitudeVisualizer.swift */; }; - FAC4004F24D326570078C6D4 /* VerticalBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC4004E24D326570078C6D4 /* VerticalBar.swift */; }; - FAC7907C24A7940C00EA977D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC7907B24A7940C00EA977D /* AppDelegate.swift */; }; - FAC7907E24A7940C00EA977D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC7907D24A7940C00EA977D /* SceneDelegate.swift */; }; - FAC7908024A7940C00EA977D /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC7907F24A7940C00EA977D /* ContentView.swift */; }; + 61FD94C12BA1FD7800CF52E3 /* Conductors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FD94C02BA1FD7800CF52E3 /* Conductors.swift */; }; + 61FD94C32BA1FDC000CF52E3 /* VisualizerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FD94C22BA1FDC000CF52E3 /* VisualizerApp.swift */; }; + 61FD94C62BA1FE5C00CF52E3 /* AudioKit in Frameworks */ = {isa = PBXBuildFile; productRef = 61FD94C52BA1FE5C00CF52E3 /* AudioKit */; }; + 61FD94C92BA1FE7A00CF52E3 /* AudioKitUI in Frameworks */ = {isa = PBXBuildFile; productRef = 61FD94C82BA1FE7A00CF52E3 /* AudioKitUI */; }; + 61FD94CB2BA1FF6900CF52E3 /* AudioVisualization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61FD94CA2BA1FF6900CF52E3 /* AudioVisualization.swift */; }; + 61FD94CF2BA204D600CF52E3 /* Guitar.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 61FD94CE2BA204D600CF52E3 /* Guitar.mp3 */; }; FAC7908224A7940F00EA977D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FAC7908124A7940F00EA977D /* Assets.xcassets */; }; FAC7908524A7940F00EA977D /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FAC7908424A7940F00EA977D /* Preview Assets.xcassets */; }; - FAC7908824A7940F00EA977D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FAC7908624A7940F00EA977D /* LaunchScreen.storyboard */; }; - FAC7909124A7944900EA977D /* AudioKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAC7909024A7944900EA977D /* AudioKit.framework */; }; - FAC7909224A7944900EA977D /* AudioKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FAC7909024A7944900EA977D /* AudioKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - FAC7909524A7945700EA977D /* AudioKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAC7909424A7945700EA977D /* AudioKitUI.framework */; }; - FAC7909624A7945700EA977D /* AudioKitUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FAC7909424A7945700EA977D /* AudioKitUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - FAC7909824A794D700EA977D /* Conductor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC7909724A794D700EA977D /* Conductor.swift */; }; - FAC7909D24A798CE00EA977D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAC7909C24A798CE00EA977D /* AudioToolbox.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -30,8 +24,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - FAC7909624A7945700EA977D /* AudioKitUI.framework in Embed Frameworks */, - FAC7909224A7944900EA977D /* AudioKit.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -39,21 +31,15 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - FA9F16A524D320B200401F2D /* AmplitudeVisualizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AmplitudeVisualizer.swift; sourceTree = ""; }; - FAC4004E24D326570078C6D4 /* VerticalBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalBar.swift; sourceTree = ""; }; - FAC7907824A7940B00EA977D /* Visualizer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Visualizer.app; sourceTree = BUILT_PRODUCTS_DIR; }; - FAC7907B24A7940C00EA977D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - FAC7907D24A7940C00EA977D /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - FAC7907F24A7940C00EA977D /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 61FD94C02BA1FD7800CF52E3 /* Conductors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Conductors.swift; sourceTree = ""; }; + 61FD94C22BA1FDC000CF52E3 /* VisualizerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisualizerApp.swift; sourceTree = ""; }; + 61FD94CA2BA1FF6900CF52E3 /* AudioVisualization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioVisualization.swift; sourceTree = ""; }; + 61FD94CC2BA2034A00CF52E3 /* Visualizer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Visualizer.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 61FD94CE2BA204D600CF52E3 /* Guitar.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = Guitar.mp3; sourceTree = ""; }; FAC7908124A7940F00EA977D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; FAC7908424A7940F00EA977D /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - FAC7908724A7940F00EA977D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; FAC7908924A7940F00EA977D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - FAC7909024A7944900EA977D /* AudioKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioKit.framework; path = "../../AudioKit-iOS/AudioKit.framework"; sourceTree = ""; }; - FAC7909424A7945700EA977D /* AudioKitUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioKitUI.framework; path = "../../AudioKit-iOS/AudioKitUI.framework"; sourceTree = ""; }; - FAC7909724A794D700EA977D /* Conductor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Conductor.swift; sourceTree = ""; }; FAC7909B24A798CE00EA977D /* Visualizer.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Visualizer.entitlements; sourceTree = ""; }; - FAC7909C24A798CE00EA977D /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -61,21 +47,26 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FAC7909524A7945700EA977D /* AudioKitUI.framework in Frameworks */, - FAC7909124A7944900EA977D /* AudioKit.framework in Frameworks */, - FAC7909D24A798CE00EA977D /* AudioToolbox.framework in Frameworks */, + 61FD94C62BA1FE5C00CF52E3 /* AudioKit in Frameworks */, + 61FD94C92BA1FE7A00CF52E3 /* AudioKitUI in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 61FD94CD2BA204C600CF52E3 /* MusicSamples */ = { + isa = PBXGroup; + children = ( + 61FD94CE2BA204D600CF52E3 /* Guitar.mp3 */, + ); + path = MusicSamples; + sourceTree = ""; + }; FA300A0924E7448100E4068C /* Views */ = { isa = PBXGroup; children = ( - FAC7907F24A7940C00EA977D /* ContentView.swift */, - FA9F16A524D320B200401F2D /* AmplitudeVisualizer.swift */, - FAC4004E24D326570078C6D4 /* VerticalBar.swift */, + 61FD94CA2BA1FF6900CF52E3 /* AudioVisualization.swift */, ); path = Views; sourceTree = ""; @@ -83,7 +74,7 @@ FAA8C38A24E744F800EEEE59 /* Models */ = { isa = PBXGroup; children = ( - FAC7909724A794D700EA977D /* Conductor.swift */, + 61FD94C02BA1FD7800CF52E3 /* Conductors.swift */, ); path = Models; sourceTree = ""; @@ -92,30 +83,20 @@ isa = PBXGroup; children = ( FAC7907A24A7940B00EA977D /* Visualizer */, - FAC7907924A7940B00EA977D /* Products */, - FAC7908F24A7944900EA977D /* Frameworks */, + 61FD94CC2BA2034A00CF52E3 /* Visualizer.app */, ); sourceTree = ""; }; - FAC7907924A7940B00EA977D /* Products */ = { - isa = PBXGroup; - children = ( - FAC7907824A7940B00EA977D /* Visualizer.app */, - ); - name = Products; - sourceTree = ""; - }; FAC7907A24A7940B00EA977D /* Visualizer */ = { isa = PBXGroup; children = ( + 61FD94C22BA1FDC000CF52E3 /* VisualizerApp.swift */, FAC7909B24A798CE00EA977D /* Visualizer.entitlements */, - FAC7907B24A7940C00EA977D /* AppDelegate.swift */, - FAC7907D24A7940C00EA977D /* SceneDelegate.swift */, FAA8C38A24E744F800EEEE59 /* Models */, FA300A0924E7448100E4068C /* Views */, FAC7908124A7940F00EA977D /* Assets.xcassets */, - FAC7908624A7940F00EA977D /* LaunchScreen.storyboard */, FAC7908924A7940F00EA977D /* Info.plist */, + 61FD94CD2BA204C600CF52E3 /* MusicSamples */, FAC7908324A7940F00EA977D /* Preview Content */, ); path = Visualizer; @@ -129,16 +110,6 @@ path = "Preview Content"; sourceTree = ""; }; - FAC7908F24A7944900EA977D /* Frameworks */ = { - isa = PBXGroup; - children = ( - FAC7909C24A798CE00EA977D /* AudioToolbox.framework */, - FAC7909424A7945700EA977D /* AudioKitUI.framework */, - FAC7909024A7944900EA977D /* AudioKit.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -156,8 +127,12 @@ dependencies = ( ); name = Visualizer; + packageProductDependencies = ( + 61FD94C52BA1FE5C00CF52E3 /* AudioKit */, + 61FD94C82BA1FE7A00CF52E3 /* AudioKitUI */, + ); productName = Visualizer; - productReference = FAC7907824A7940B00EA977D /* Visualizer.app */; + productReference = 61FD94CC2BA2034A00CF52E3 /* Visualizer.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -166,8 +141,9 @@ FAC7907024A7940B00EA977D /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1150; - LastUpgradeCheck = 1150; + LastUpgradeCheck = 1520; ORGANIZATIONNAME = "Matt Pfeiffer"; TargetAttributes = { FAC7907724A7940B00EA977D = { @@ -184,7 +160,11 @@ Base, ); mainGroup = FAC7906F24A7940B00EA977D; - productRefGroup = FAC7907924A7940B00EA977D /* Products */; + packageReferences = ( + 61FD94C42BA1FE5C00CF52E3 /* XCRemoteSwiftPackageReference "AudioKit" */, + 61FD94C72BA1FE7A00CF52E3 /* XCRemoteSwiftPackageReference "AudioKitUI" */, + ); + productRefGroup = FAC7906F24A7940B00EA977D; projectDirPath = ""; projectRoot = ""; targets = ( @@ -198,7 +178,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - FAC7908824A7940F00EA977D /* LaunchScreen.storyboard in Resources */, + 61FD94CF2BA204D600CF52E3 /* Guitar.mp3 in Resources */, FAC7908524A7940F00EA977D /* Preview Assets.xcassets in Resources */, FAC7908224A7940F00EA977D /* Assets.xcassets in Resources */, ); @@ -211,28 +191,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - FA9F16A624D320B200401F2D /* AmplitudeVisualizer.swift in Sources */, - FAC7907C24A7940C00EA977D /* AppDelegate.swift in Sources */, - FAC7907E24A7940C00EA977D /* SceneDelegate.swift in Sources */, - FAC4004F24D326570078C6D4 /* VerticalBar.swift in Sources */, - FAC7908024A7940C00EA977D /* ContentView.swift in Sources */, - FAC7909824A794D700EA977D /* Conductor.swift in Sources */, + 61FD94C32BA1FDC000CF52E3 /* VisualizerApp.swift in Sources */, + 61FD94CB2BA1FF6900CF52E3 /* AudioVisualization.swift in Sources */, + 61FD94C12BA1FD7800CF52E3 /* Conductors.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXVariantGroup section */ - FAC7908624A7940F00EA977D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - FAC7908724A7940F00EA977D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ FAC7908A24A7940F00EA977D /* Debug */ = { isa = XCBuildConfiguration; @@ -260,6 +226,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -270,6 +237,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -320,6 +288,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -330,6 +299,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -355,19 +325,21 @@ CODE_SIGN_ENTITLEMENTS = Visualizer/Visualizer.entitlements; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "\"Visualizer/Preview Content\""; - DEVELOPMENT_TEAM = L2FL95P32D; + DEVELOPMENT_TEAM = 9JF99T9A6L; ENABLE_PREVIEWS = YES; FRAMEWORK_SEARCH_PATHS = ( "\"/Users/macbook/Sync/Code/Xcode/AudioDev/AudioKit-iOS\"", "\"/Users/macbook/Sync/Code/Xcode/HapticsDev/lofelt-studio-0.8.2-mac/sdk/ios-framework/universal\"", ); INFOPLIST_FILE = Visualizer/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.music"; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); OTHER_LDFLAGS = "-lc++"; - PRODUCT_BUNDLE_IDENTIFIER = com.MattPfeiffer.Visualizer; + PRODUCT_BUNDLE_IDENTIFIER = com.MattPfeiffer.AudioKitVisualizer; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -381,19 +353,21 @@ CODE_SIGN_ENTITLEMENTS = Visualizer/Visualizer.entitlements; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "\"Visualizer/Preview Content\""; - DEVELOPMENT_TEAM = L2FL95P32D; + DEVELOPMENT_TEAM = 9JF99T9A6L; ENABLE_PREVIEWS = YES; FRAMEWORK_SEARCH_PATHS = ( "\"/Users/macbook/Sync/Code/Xcode/AudioDev/AudioKit-iOS\"", "\"/Users/macbook/Sync/Code/Xcode/HapticsDev/lofelt-studio-0.8.2-mac/sdk/ios-framework/universal\"", ); INFOPLIST_FILE = Visualizer/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.music"; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); OTHER_LDFLAGS = "-lc++"; - PRODUCT_BUNDLE_IDENTIFIER = com.MattPfeiffer.Visualizer; + PRODUCT_BUNDLE_IDENTIFIER = com.MattPfeiffer.AudioKitVisualizer; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -422,6 +396,38 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 61FD94C42BA1FE5C00CF52E3 /* XCRemoteSwiftPackageReference "AudioKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/AudioKit/AudioKit"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.6.3; + }; + }; + 61FD94C72BA1FE7A00CF52E3 /* XCRemoteSwiftPackageReference "AudioKitUI" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/AudioKit/AudioKitUI"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.3.7; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 61FD94C52BA1FE5C00CF52E3 /* AudioKit */ = { + isa = XCSwiftPackageProductDependency; + package = 61FD94C42BA1FE5C00CF52E3 /* XCRemoteSwiftPackageReference "AudioKit" */; + productName = AudioKit; + }; + 61FD94C82BA1FE7A00CF52E3 /* AudioKitUI */ = { + isa = XCSwiftPackageProductDependency; + package = 61FD94C72BA1FE7A00CF52E3 /* XCRemoteSwiftPackageReference "AudioKitUI" */; + productName = AudioKitUI; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = FAC7907024A7940B00EA977D /* Project object */; } diff --git a/Visualizer.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Visualizer.xcodeproj/project.xcworkspace/contents.xcworkspacedata index e1dce91..919434a 100644 --- a/Visualizer.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/Visualizer.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/Visualizer.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Visualizer.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..4bca60b --- /dev/null +++ b/Visualizer.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,32 @@ +{ + "pins" : [ + { + "identity" : "audiokit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/AudioKit/AudioKit", + "state" : { + "revision" : "b2dbaed8cd38077092b6b6e311699ddf5d94dbd7", + "version" : "5.6.3" + } + }, + { + "identity" : "audiokitui", + "kind" : "remoteSourceControl", + "location" : "https://github.com/AudioKit/AudioKitUI", + "state" : { + "revision" : "1a61e8a96c7ee24c3e5abe06dc3334a31fd7571d", + "version" : "0.3.7" + } + }, + { + "identity" : "controls", + "kind" : "remoteSourceControl", + "location" : "https://github.com/AudioKit/Controls.git", + "state" : { + "revision" : "4dd10370125af7f1e26d7a71b2c5929bb3c95087", + "version" : "1.1.4" + } + } + ], + "version" : 2 +} diff --git a/Visualizer.xcodeproj/project.xcworkspace/xcuserdata/alaa.xcuserdatad/UserInterfaceState.xcuserstate b/Visualizer.xcodeproj/project.xcworkspace/xcuserdata/alaa.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..1bd4404 Binary files /dev/null and b/Visualizer.xcodeproj/project.xcworkspace/xcuserdata/alaa.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Visualizer.xcodeproj/xcuserdata/alaa.xcuserdatad/xcschemes/xcschememanagement.plist b/Visualizer.xcodeproj/xcuserdata/alaa.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..c0f7d29 --- /dev/null +++ b/Visualizer.xcodeproj/xcuserdata/alaa.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,56 @@ + + + + + SchemeUserState + + AudioKit (Playground) 1.xcscheme + + isShown + + orderHint + 2 + + AudioKit (Playground) 2.xcscheme + + isShown + + orderHint + 3 + + AudioKit (Playground).xcscheme + + isShown + + orderHint + 0 + + Controls (Playground) 1.xcscheme + + isShown + + orderHint + 5 + + Controls (Playground) 2.xcscheme + + isShown + + orderHint + 6 + + Controls (Playground).xcscheme + + isShown + + orderHint + 4 + + Visualizer.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/Visualizer/AppDelegate.swift b/Visualizer/AppDelegate.swift deleted file mode 100644 index 8bf838d..0000000 --- a/Visualizer/AppDelegate.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// AppDelegate.swift -// Visualizer -// -// Created by Macbook on 6/27/20. -// Copyright © 2020 Matt Pfeiffer. All rights reserved. -// - -import UIKit - -@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - - - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. - return true - } - - // MARK: UISceneSession Lifecycle - - func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { - // Called when a new scene session is being created. - // Use this method to select a configuration to create the new scene with. - return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) - } - - func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { - // Called when the user discards a scene session. - // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. - // Use this method to release any resources that were specific to the discarded scenes, as they will not return. - } - - -} - diff --git a/Visualizer/Base.lproj/LaunchScreen.storyboard b/Visualizer/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 865e932..0000000 --- a/Visualizer/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Visualizer/Models/Conductor.swift b/Visualizer/Models/Conductor.swift deleted file mode 100644 index 9283d5d..0000000 --- a/Visualizer/Models/Conductor.swift +++ /dev/null @@ -1,153 +0,0 @@ -// -// Conductor.swift -// Visualizer -// -// Created by Macbook on 6/27/20. -// Copyright © 2020 Matt Pfeiffer. All rights reserved. -// - -import AudioKit - -/// The persistent data object of the application (it does the audio processing and publishes changes to the UI) -final class Conductor : ObservableObject{ - - /// Single shared data model - static let shared = Conductor() - - /// default microphone - let mic = AKMicrophone() - - /// mixing node for microphone input - routes to plotting and recording paths - let micMixer = AKMixer() - - /// time interval in seconds for repeating timer callback - let refreshTimeInterval : Double = 0.02 - - /// tap for the fft data - let fft : AKFFTTap - - /// size of fft - let FFT_SIZE = 512 - - /// audio sample rate - let sampleRate : double_t = 44100 - - /// limiter to prevent excessive volume at the output - just in case, it's the music producer in me :) - let outputLimiter = AKPeakLimiter() - - /// bin amplitude values (range from 0.0 to 1.0) - @Published var amplitudes : [Double] = Array(repeating: 0.5, count: 50) - - /// constructor - runs during initialization of the object - init(){ - - // connect the fft tap to the mic mixer (this allows us to analyze the audio at the micMixer node) - fft = AKFFTTap.init(micMixer) - - // route the audio from the microphone to the limiter - setupMic() - - // set the limiter as the last node in our audio chain - AudioKit.output = outputLimiter - - // do any AudioKit setting changes before starting the AudioKit engine - setAudioKitSettings() - - // start the AudioKit engine - do{ - try AudioKit.start() - } - catch{ - assert(false, error.localizedDescription) - } - - // create a repeating timer at the rate of our chosen time interval - this updates the amplitudes each timer callback - Timer.scheduledTimer(withTimeInterval: refreshTimeInterval, repeats: true) { timer in - self.updateAmplitudes() - } - - } - - /// Sets AudioKit to appropriate settings - func setAudioKitSettings(){ - - do { - try AKSettings.setSession(category: .ambient, with: [.mixWithOthers]) - } catch { - AKLog("Could not set session category.") - } - - } - - /// Does all the setup required for microphone input - func setupMic(){ - - // route mic to the micMixer which is tapped by our fft - mic?.setOutput(to: micMixer) - - // route mixMixer to a mixer with no volume so that we don't output audio - let silentMixer = AKMixer(micMixer) - silentMixer.volume = 0.0 - - // route the silent Mixer to the limiter (you must always route the audio chain to AudioKit.output) - silentMixer.setOutput(to: outputLimiter) - - } - - /// Analyze fft data and write to our amplitudes array - @objc func updateAmplitudes(){ - //If you are interested in knowing more about this calculation, I have provided a couple recommended links at the bottom of this file. - - // loop by two through all the fft data - for i in stride(from: 0, to: self.FFT_SIZE - 1, by: 2) { - - // get the real and imaginary parts of the complex number - let real = fft.fftData[i] - let imaginary = fft.fftData[i + 1] - - let normalizedBinMagnitude = 2.0 * sqrt(real * real + imaginary * imaginary) / self.FFT_SIZE - let amplitude = (20.0 * log10(normalizedBinMagnitude)) - - // scale the resulting data - var scaledAmplitude = (amplitude + 250) / 229.80 - - // restrict the range to 0.0 - 1.0 - if (scaledAmplitude < 0) { - scaledAmplitude = 0 - } - if (scaledAmplitude > 1.0) { - scaledAmplitude = 1.0 - } - - // add the amplitude to our array (further scaling array to look good in visualizer) - DispatchQueue.main.async { - if(i/2 < self.amplitudes.count){ - self.amplitudes[i/2] = self.mapy(n: scaledAmplitude, start1: 0.3, stop1: 0.9, start2: 0.0, stop2: 1.0) - } - } - } - - } - - /// simple mapping function to scale a value to a different range - func mapy(n:Double, start1:Double, stop1:Double, start2:Double, stop2:Double) -> Double { - return ((n-start1)/(stop1-start1))*(stop2-start2)+start2; - }; -} - -/* - Visual introduction to the fourier transform: - https://www.youtube.com/watch?v=spUNpyF58BY - Shoutout to Grant Sanderson - thank you for your videos! - - Discrete fourier transform: - https://www.youtube.com/watch?v=nl9TZanwbBk - - Fast fourier transform: - https://www.youtube.com/watch?v=E8HeD-MUrjY - Shoutout to Steve Brunton - thank you for your videos! - - Google groups conversation explaining how to use the fft data to calculate bin decibel levels: - https://groups.google.com/g/comp.dsp/c/cZsS1ftN5oI?pli=1 - Shoutout to Stephan M. Sprenger - thank you for sharing! - */ diff --git a/Visualizer/Models/Conductors.swift b/Visualizer/Models/Conductors.swift new file mode 100644 index 0000000..3984361 --- /dev/null +++ b/Visualizer/Models/Conductors.swift @@ -0,0 +1,67 @@ +// +// Conductors.swift +// Visualizer +// +// Created by Treata Norouzi on 3/13/24. +// + +import AudioKit +import AudioKitUI +import Observation + +@Observable +class InputConductor: HasAudioEngine { + + /// Single shared data model + static let shared = InputConductor() + + /// Single shared data model + let engine = AudioEngine() + + /// default microphone + let mic: AudioEngine.InputNode? + /// mixing node for microphone input - routes to plotting and recording paths + let outputMixer: Mixer + + init() { + mic = engine.input + outputMixer = Mixer(mic!) + engine.output = outputMixer + + // start the AudioKit engine + do { + try engine.start() + } catch { + print(error) + } + } +} + +// MARK: - Music Player + +// To have the `URL` struct available in the scope +import UniformTypeIdentifiers + +@Observable +class MusicPlayerConductor: HasAudioEngine, ProcessesPlayerInput { + let engine = AudioEngine() + + let player: AudioPlayer + let outputMixer: Mixer + + init(musicUrl: URL = Bundle.main.url(forResource: "Guitar", withExtension: "mp3")!) { + player = AudioPlayer(url: musicUrl)! + + engine.output = player + player.isLooping = true + outputMixer = Mixer(player) + + engine.output = outputMixer + + do { + try engine.start() + } catch { + print(error) + } + } +} diff --git a/Visualizer/MusicSamples/Guitar.mp3 b/Visualizer/MusicSamples/Guitar.mp3 new file mode 100644 index 0000000..5803543 Binary files /dev/null and b/Visualizer/MusicSamples/Guitar.mp3 differ diff --git a/Visualizer/SceneDelegate.swift b/Visualizer/SceneDelegate.swift deleted file mode 100644 index 55bde1c..0000000 --- a/Visualizer/SceneDelegate.swift +++ /dev/null @@ -1,64 +0,0 @@ -// -// SceneDelegate.swift -// Visualizer -// -// Created by Macbook on 6/27/20. -// Copyright © 2020 Matt Pfeiffer. All rights reserved. -// - -import UIKit -import SwiftUI - -class SceneDelegate: UIResponder, UIWindowSceneDelegate { - - var window: UIWindow? - - - func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. - // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. - // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). - - // Create the SwiftUI view that provides the window contents. - let contentView = ContentView() - - // Use a UIHostingController as window root view controller. - if let windowScene = scene as? UIWindowScene { - let window = UIWindow(windowScene: windowScene) - window.rootViewController = UIHostingController(rootView: contentView.environmentObject(Conductor.shared)) - self.window = window - window.makeKeyAndVisible() - } - } - - func sceneDidDisconnect(_ scene: UIScene) { - // Called as the scene is being released by the system. - // This occurs shortly after the scene enters the background, or when its session is discarded. - // Release any resources associated with this scene that can be re-created the next time the scene connects. - // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). - } - - func sceneDidBecomeActive(_ scene: UIScene) { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. - } - - func sceneWillResignActive(_ scene: UIScene) { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). - } - - func sceneWillEnterForeground(_ scene: UIScene) { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. - } - - func sceneDidEnterBackground(_ scene: UIScene) { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. - } - - -} - diff --git a/Visualizer/Views/AmplitudeVisualizer.swift b/Visualizer/Views/AmplitudeVisualizer.swift deleted file mode 100644 index b3f6cdf..0000000 --- a/Visualizer/Views/AmplitudeVisualizer.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// AmplitudeVisualizer.swift -// Visualizer -// -// Created by Macbook on 7/30/20. -// Copyright © 2020 Matt Pfeiffer. All rights reserved. -// - -import SwiftUI - -struct AmplitudeVisualizer: View { - - @Binding var amplitudes: [Double] - - var body: some View { - HStack(spacing: 0.0){ - ForEach(0 ..< self.amplitudes.count) { number in - VerticalBar(amplitude: self.$amplitudes[number]) - } - } - .background(Color.black) - } -} - -struct AmplitudeVisualizer_Previews: PreviewProvider { - static var previews: some View { - AmplitudeVisualizer(amplitudes: .constant(Array(repeating: 1.0, count: 50))) - } -} diff --git a/Visualizer/Views/AudioVisualization.swift b/Visualizer/Views/AudioVisualization.swift new file mode 100644 index 0000000..a454610 --- /dev/null +++ b/Visualizer/Views/AudioVisualization.swift @@ -0,0 +1,59 @@ +// +// AudioVisualization.swift +// Visualizer +// +// Created by Treata Norouzi on 3/13/24. +// + +import SwiftUI +import AudioKitUI + +struct InputAudioVisualization: View { + @Environment(InputConductor.self) var conductor + + @Environment(\.scenePhase) private var scenePhase + + var body: some View { + FFTView(conductor.outputMixer) + .onChange(of: scenePhase) { + if scenePhase == .inactive { conductor.stop() } + } + .onAppear { + conductor.start() + } + .onDisappear { + conductor.stop() + } + } +} + +//#Preview("InputAudioVisualization") { +// InputAudioVisualization() +// .environment(InputConductor.shared) +//} + +// MARK: - Music Visualizer + +struct MusicVisualizer: View { + // TODO: Create an option to choose a music file + @Environment(MusicPlayerConductor.self) var conductor + + var body: some View { + FFTView(conductor.outputMixer) + .onAppear { + conductor.start() + conductor.player.play() + } + .onDisappear { +// conductor.stop() + conductor.player.stop() + } + } +} + +#Preview("InputAudioVisualization") { + @Bindable var conductor = MusicPlayerConductor() + + return InputAudioVisualization() + .environment(conductor) +} diff --git a/Visualizer/Views/ContentView.swift b/Visualizer/Views/ContentView.swift deleted file mode 100644 index b2a7f6b..0000000 --- a/Visualizer/Views/ContentView.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// ContentView.swift -// Visualizer -// -// Created by Macbook on 6/27/20. -// Copyright © 2020 Matt Pfeiffer. All rights reserved. -// - -import SwiftUI - -struct ContentView: View { - - @EnvironmentObject var conductor: Conductor - - var body: some View { - AmplitudeVisualizer(amplitudes: $conductor.amplitudes) - .edgesIgnoringSafeArea(.all) - } -} - -struct ContentView_Previews: PreviewProvider { - static var previews: some View { - ContentView().environmentObject(Conductor.shared) - } -} diff --git a/Visualizer/Views/VerticalBar.swift b/Visualizer/Views/VerticalBar.swift deleted file mode 100644 index 25a4473..0000000 --- a/Visualizer/Views/VerticalBar.swift +++ /dev/null @@ -1,54 +0,0 @@ -// -// VerticalBar.swift -// Visualizer -// -// Created by Macbook on 7/30/20. -// Copyright © 2020 Matt Pfeiffer. All rights reserved. -// - -import SwiftUI - -/// Single bar of Amplitude Visualizer -struct VerticalBar: View { - - @Binding var amplitude: Double - - var body: some View { - GeometryReader - { geometry in - ZStack(alignment: .bottom){ - - // Colored rectangle in back of ZStack - Rectangle() - .fill(LinearGradient(gradient: Gradient(colors: [.red, .yellow, .green]), startPoint: .top, endPoint: .center)) - - // blue/purple bar style - try switching this out with the .fill statement above - //.fill(LinearGradient(gradient: Gradient(colors: [Color.init(red: 0.0, green: 1.0, blue: 1.0), .blue, .purple]), startPoint: .top, endPoint: .bottom)) - - // Dynamic black mask padded from bottom in relation to the amplitude - Rectangle() - .fill(Color.black) - .mask(Rectangle().padding(.bottom, geometry.size.height * CGFloat(self.amplitude))) - .animation(.easeOut(duration: 0.15)) - - // White bar with slower animation for floating effect - Rectangle() - .fill(Color.white) - .frame(height: geometry.size.height * 0.005) - .offset(x: 0.0, y: -geometry.size.height * CGFloat(self.amplitude) - geometry.size.height * 0.02) - .animation(.easeOut(duration: 0.6)) - - } - .padding(geometry.size.width * 0.1) - .border(Color.black, width: geometry.size.width * 0.1) - } - } - -} - -struct VerticalBar_Previews: PreviewProvider { - static var previews: some View { - VerticalBar(amplitude: .constant(0.8)) - .previewLayout(.fixed(width: 40, height: 500)) - } -} diff --git a/Visualizer/VisualizerApp.swift b/Visualizer/VisualizerApp.swift new file mode 100644 index 0000000..5aa202b --- /dev/null +++ b/Visualizer/VisualizerApp.swift @@ -0,0 +1,41 @@ +// +// VisualizerApp.swift +// Visualizer +// +// Created by Treata Norouzi on 3/13/24. +// + +import SwiftUI + +@main +struct VisualizerApp: App { + @Bindable var inputConductor = InputConductor() + @Bindable var musicConductor = MusicPlayerConductor() + + var body: some Scene { + WindowGroup { + NavigationStack { + MusicVisualizer() + .toolbar { + ToolbarItem { + Menu(content: { +// NavigationLink(destination: MusicVisualizer(), label: { +// Label("Input from File", systemImage: "music.note") +// }) + + NavigationLink(destination: InputAudioVisualization(), label: { + Label("Input from Mic", systemImage: "mic.fill") + }) + }, label: { + Image(systemName: "line.3.horizontal.decrease.circle") + }) + } + } + } + .ignoresSafeArea() + // Injecting the ViewModel(s) + .environment(inputConductor) + .environment(musicConductor) + } + } +}