├── IHWaveformView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── mdibrahimhassan.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── mdibrahimhassan.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── IHWaveformView.xcscheme │ └── xcschememanagement.plist ├── IHWaveformView ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── IHWaveFormView.swift ├── Info.plist └── ViewController.swift ├── LICENSE ├── README.md └── bensound-sunny.mp3 /IHWaveformView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DB0611901F4059DD0092EF4C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06118F1F4059DD0092EF4C /* AppDelegate.swift */; }; 11 | DB0611921F4059DD0092EF4C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0611911F4059DD0092EF4C /* ViewController.swift */; }; 12 | DB0611951F4059DD0092EF4C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DB0611931F4059DD0092EF4C /* Main.storyboard */; }; 13 | DB0611971F4059DD0092EF4C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB0611961F4059DD0092EF4C /* Assets.xcassets */; }; 14 | DB06119A1F4059DD0092EF4C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DB0611981F4059DD0092EF4C /* LaunchScreen.storyboard */; }; 15 | DB68D6D01F43787A001D69A1 /* IHWaveFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB68D6CF1F43787A001D69A1 /* IHWaveFormView.swift */; }; 16 | DB68D6D21F437E5F001D69A1 /* bensound-sunny.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = DB68D6D11F437E5F001D69A1 /* bensound-sunny.mp3 */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | DB06118C1F4059DD0092EF4C /* IHWaveformView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IHWaveformView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 21 | DB06118F1F4059DD0092EF4C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 22 | DB0611911F4059DD0092EF4C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 23 | DB0611941F4059DD0092EF4C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 24 | DB0611961F4059DD0092EF4C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 25 | DB0611991F4059DD0092EF4C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 26 | DB06119B1F4059DD0092EF4C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 27 | DB68D6CF1F43787A001D69A1 /* IHWaveFormView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IHWaveFormView.swift; sourceTree = ""; }; 28 | DB68D6D11F437E5F001D69A1 /* bensound-sunny.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = "bensound-sunny.mp3"; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | DB0611891F4059DD0092EF4C /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | DB0611831F4059DD0092EF4C = { 43 | isa = PBXGroup; 44 | children = ( 45 | DB06118E1F4059DD0092EF4C /* IHWaveformView */, 46 | DB06118D1F4059DD0092EF4C /* Products */, 47 | DB68D6D11F437E5F001D69A1 /* bensound-sunny.mp3 */, 48 | ); 49 | sourceTree = ""; 50 | }; 51 | DB06118D1F4059DD0092EF4C /* Products */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | DB06118C1F4059DD0092EF4C /* IHWaveformView.app */, 55 | ); 56 | name = Products; 57 | sourceTree = ""; 58 | }; 59 | DB06118E1F4059DD0092EF4C /* IHWaveformView */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | DB06118F1F4059DD0092EF4C /* AppDelegate.swift */, 63 | DB0611911F4059DD0092EF4C /* ViewController.swift */, 64 | DB4D6B971F6E30A00020C94B /* source */, 65 | DB0611931F4059DD0092EF4C /* Main.storyboard */, 66 | DB0611961F4059DD0092EF4C /* Assets.xcassets */, 67 | DB0611981F4059DD0092EF4C /* LaunchScreen.storyboard */, 68 | DB06119B1F4059DD0092EF4C /* Info.plist */, 69 | ); 70 | path = IHWaveformView; 71 | sourceTree = ""; 72 | }; 73 | DB4D6B971F6E30A00020C94B /* source */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | DB68D6CF1F43787A001D69A1 /* IHWaveFormView.swift */, 77 | ); 78 | name = source; 79 | sourceTree = ""; 80 | }; 81 | /* End PBXGroup section */ 82 | 83 | /* Begin PBXNativeTarget section */ 84 | DB06118B1F4059DD0092EF4C /* IHWaveformView */ = { 85 | isa = PBXNativeTarget; 86 | buildConfigurationList = DB06119E1F4059DD0092EF4C /* Build configuration list for PBXNativeTarget "IHWaveformView" */; 87 | buildPhases = ( 88 | DB0611881F4059DD0092EF4C /* Sources */, 89 | DB0611891F4059DD0092EF4C /* Frameworks */, 90 | DB06118A1F4059DD0092EF4C /* Resources */, 91 | ); 92 | buildRules = ( 93 | ); 94 | dependencies = ( 95 | ); 96 | name = IHWaveformView; 97 | productName = IHWaveformView; 98 | productReference = DB06118C1F4059DD0092EF4C /* IHWaveformView.app */; 99 | productType = "com.apple.product-type.application"; 100 | }; 101 | /* End PBXNativeTarget section */ 102 | 103 | /* Begin PBXProject section */ 104 | DB0611841F4059DD0092EF4C /* Project object */ = { 105 | isa = PBXProject; 106 | attributes = { 107 | LastSwiftUpdateCheck = 0810; 108 | LastUpgradeCheck = 0810; 109 | ORGANIZATIONNAME = "Md Ibrahim Hassan"; 110 | TargetAttributes = { 111 | DB06118B1F4059DD0092EF4C = { 112 | CreatedOnToolsVersion = 8.1; 113 | ProvisioningStyle = Automatic; 114 | }; 115 | }; 116 | }; 117 | buildConfigurationList = DB0611871F4059DD0092EF4C /* Build configuration list for PBXProject "IHWaveformView" */; 118 | compatibilityVersion = "Xcode 3.2"; 119 | developmentRegion = English; 120 | hasScannedForEncodings = 0; 121 | knownRegions = ( 122 | English, 123 | en, 124 | Base, 125 | ); 126 | mainGroup = DB0611831F4059DD0092EF4C; 127 | productRefGroup = DB06118D1F4059DD0092EF4C /* Products */; 128 | projectDirPath = ""; 129 | projectRoot = ""; 130 | targets = ( 131 | DB06118B1F4059DD0092EF4C /* IHWaveformView */, 132 | ); 133 | }; 134 | /* End PBXProject section */ 135 | 136 | /* Begin PBXResourcesBuildPhase section */ 137 | DB06118A1F4059DD0092EF4C /* Resources */ = { 138 | isa = PBXResourcesBuildPhase; 139 | buildActionMask = 2147483647; 140 | files = ( 141 | DB68D6D21F437E5F001D69A1 /* bensound-sunny.mp3 in Resources */, 142 | DB06119A1F4059DD0092EF4C /* LaunchScreen.storyboard in Resources */, 143 | DB0611971F4059DD0092EF4C /* Assets.xcassets in Resources */, 144 | DB0611951F4059DD0092EF4C /* Main.storyboard in Resources */, 145 | ); 146 | runOnlyForDeploymentPostprocessing = 0; 147 | }; 148 | /* End PBXResourcesBuildPhase section */ 149 | 150 | /* Begin PBXSourcesBuildPhase section */ 151 | DB0611881F4059DD0092EF4C /* Sources */ = { 152 | isa = PBXSourcesBuildPhase; 153 | buildActionMask = 2147483647; 154 | files = ( 155 | DB0611921F4059DD0092EF4C /* ViewController.swift in Sources */, 156 | DB0611901F4059DD0092EF4C /* AppDelegate.swift in Sources */, 157 | DB68D6D01F43787A001D69A1 /* IHWaveFormView.swift in Sources */, 158 | ); 159 | runOnlyForDeploymentPostprocessing = 0; 160 | }; 161 | /* End PBXSourcesBuildPhase section */ 162 | 163 | /* Begin PBXVariantGroup section */ 164 | DB0611931F4059DD0092EF4C /* Main.storyboard */ = { 165 | isa = PBXVariantGroup; 166 | children = ( 167 | DB0611941F4059DD0092EF4C /* Base */, 168 | ); 169 | name = Main.storyboard; 170 | sourceTree = ""; 171 | }; 172 | DB0611981F4059DD0092EF4C /* LaunchScreen.storyboard */ = { 173 | isa = PBXVariantGroup; 174 | children = ( 175 | DB0611991F4059DD0092EF4C /* Base */, 176 | ); 177 | name = LaunchScreen.storyboard; 178 | sourceTree = ""; 179 | }; 180 | /* End PBXVariantGroup section */ 181 | 182 | /* Begin XCBuildConfiguration section */ 183 | DB06119C1F4059DD0092EF4C /* Debug */ = { 184 | isa = XCBuildConfiguration; 185 | buildSettings = { 186 | ALWAYS_SEARCH_USER_PATHS = NO; 187 | CLANG_ANALYZER_NONNULL = YES; 188 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 189 | CLANG_CXX_LIBRARY = "libc++"; 190 | CLANG_ENABLE_MODULES = YES; 191 | CLANG_ENABLE_OBJC_ARC = YES; 192 | CLANG_WARN_BOOL_CONVERSION = YES; 193 | CLANG_WARN_CONSTANT_CONVERSION = YES; 194 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 195 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 196 | CLANG_WARN_EMPTY_BODY = YES; 197 | CLANG_WARN_ENUM_CONVERSION = YES; 198 | CLANG_WARN_INFINITE_RECURSION = YES; 199 | CLANG_WARN_INT_CONVERSION = YES; 200 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 201 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 202 | CLANG_WARN_UNREACHABLE_CODE = YES; 203 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 204 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 205 | COPY_PHASE_STRIP = NO; 206 | DEBUG_INFORMATION_FORMAT = dwarf; 207 | ENABLE_STRICT_OBJC_MSGSEND = YES; 208 | ENABLE_TESTABILITY = YES; 209 | GCC_C_LANGUAGE_STANDARD = gnu99; 210 | GCC_DYNAMIC_NO_PIC = NO; 211 | GCC_NO_COMMON_BLOCKS = YES; 212 | GCC_OPTIMIZATION_LEVEL = 0; 213 | GCC_PREPROCESSOR_DEFINITIONS = ( 214 | "DEBUG=1", 215 | "$(inherited)", 216 | ); 217 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 218 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 219 | GCC_WARN_UNDECLARED_SELECTOR = YES; 220 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 221 | GCC_WARN_UNUSED_FUNCTION = YES; 222 | GCC_WARN_UNUSED_VARIABLE = YES; 223 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 224 | MTL_ENABLE_DEBUG_INFO = YES; 225 | ONLY_ACTIVE_ARCH = YES; 226 | SDKROOT = iphoneos; 227 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 228 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 229 | TARGETED_DEVICE_FAMILY = "1,2"; 230 | }; 231 | name = Debug; 232 | }; 233 | DB06119D1F4059DD0092EF4C /* Release */ = { 234 | isa = XCBuildConfiguration; 235 | buildSettings = { 236 | ALWAYS_SEARCH_USER_PATHS = NO; 237 | CLANG_ANALYZER_NONNULL = YES; 238 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 239 | CLANG_CXX_LIBRARY = "libc++"; 240 | CLANG_ENABLE_MODULES = YES; 241 | CLANG_ENABLE_OBJC_ARC = YES; 242 | CLANG_WARN_BOOL_CONVERSION = YES; 243 | CLANG_WARN_CONSTANT_CONVERSION = YES; 244 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 245 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 246 | CLANG_WARN_EMPTY_BODY = YES; 247 | CLANG_WARN_ENUM_CONVERSION = YES; 248 | CLANG_WARN_INFINITE_RECURSION = YES; 249 | CLANG_WARN_INT_CONVERSION = YES; 250 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 251 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 252 | CLANG_WARN_UNREACHABLE_CODE = YES; 253 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 254 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 255 | COPY_PHASE_STRIP = NO; 256 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 257 | ENABLE_NS_ASSERTIONS = NO; 258 | ENABLE_STRICT_OBJC_MSGSEND = YES; 259 | GCC_C_LANGUAGE_STANDARD = gnu99; 260 | GCC_NO_COMMON_BLOCKS = YES; 261 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 262 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 263 | GCC_WARN_UNDECLARED_SELECTOR = YES; 264 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 265 | GCC_WARN_UNUSED_FUNCTION = YES; 266 | GCC_WARN_UNUSED_VARIABLE = YES; 267 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 268 | MTL_ENABLE_DEBUG_INFO = NO; 269 | SDKROOT = iphoneos; 270 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 271 | TARGETED_DEVICE_FAMILY = "1,2"; 272 | VALIDATE_PRODUCT = YES; 273 | }; 274 | name = Release; 275 | }; 276 | DB06119F1F4059DD0092EF4C /* Debug */ = { 277 | isa = XCBuildConfiguration; 278 | buildSettings = { 279 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 280 | INFOPLIST_FILE = IHWaveformView/Info.plist; 281 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 282 | PRODUCT_BUNDLE_IDENTIFIER = "IbrahimH-ss-n.IHWaveformView"; 283 | PRODUCT_NAME = "$(TARGET_NAME)"; 284 | SWIFT_VERSION = 5.0; 285 | }; 286 | name = Debug; 287 | }; 288 | DB0611A01F4059DD0092EF4C /* Release */ = { 289 | isa = XCBuildConfiguration; 290 | buildSettings = { 291 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 292 | INFOPLIST_FILE = IHWaveformView/Info.plist; 293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 294 | PRODUCT_BUNDLE_IDENTIFIER = "IbrahimH-ss-n.IHWaveformView"; 295 | PRODUCT_NAME = "$(TARGET_NAME)"; 296 | SWIFT_VERSION = 5.0; 297 | }; 298 | name = Release; 299 | }; 300 | /* End XCBuildConfiguration section */ 301 | 302 | /* Begin XCConfigurationList section */ 303 | DB0611871F4059DD0092EF4C /* Build configuration list for PBXProject "IHWaveformView" */ = { 304 | isa = XCConfigurationList; 305 | buildConfigurations = ( 306 | DB06119C1F4059DD0092EF4C /* Debug */, 307 | DB06119D1F4059DD0092EF4C /* Release */, 308 | ); 309 | defaultConfigurationIsVisible = 0; 310 | defaultConfigurationName = Release; 311 | }; 312 | DB06119E1F4059DD0092EF4C /* Build configuration list for PBXNativeTarget "IHWaveformView" */ = { 313 | isa = XCConfigurationList; 314 | buildConfigurations = ( 315 | DB06119F1F4059DD0092EF4C /* Debug */, 316 | DB0611A01F4059DD0092EF4C /* Release */, 317 | ); 318 | defaultConfigurationIsVisible = 0; 319 | defaultConfigurationName = Release; 320 | }; 321 | /* End XCConfigurationList section */ 322 | }; 323 | rootObject = DB0611841F4059DD0092EF4C /* Project object */; 324 | } 325 | -------------------------------------------------------------------------------- /IHWaveformView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /IHWaveformView.xcodeproj/project.xcworkspace/xcuserdata/mdibrahimhassan.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ibrahimhass/IHEqualizerView/0799cf3458ec28b72992426ef01f226238a06f72/IHWaveformView.xcodeproj/project.xcworkspace/xcuserdata/mdibrahimhassan.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /IHWaveformView.xcodeproj/xcuserdata/mdibrahimhassan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 40 | 52 | 53 | 67 | 68 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /IHWaveformView.xcodeproj/xcuserdata/mdibrahimhassan.xcuserdatad/xcschemes/IHWaveformView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /IHWaveformView.xcodeproj/xcuserdata/mdibrahimhassan.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | IHWaveformView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | DB06118B1F4059DD0092EF4C 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /IHWaveformView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | //Copyright (c) 2017 Md Ibrahim Hassan 4 | // 5 | //Permission is hereby granted, free of charge, to any person obtaining a copy 6 | //of this software and associated documentation files (the "Software"), to deal 7 | //in the Software without restriction, including without limitation the rights 8 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | //copies of the Software, and to permit persons to whom the Software is 10 | //furnished to do so, subject to the following conditions: 11 | // 12 | //The above copyright notice and this permission notice shall be included in all 13 | //copies or substantial portions of the Software. 14 | // 15 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | //SOFTWARE. 22 | 23 | import UIKit 24 | 25 | @UIApplicationMain 26 | class AppDelegate: UIResponder, UIApplicationDelegate { 27 | 28 | var window: UIWindow? 29 | 30 | 31 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 32 | // Override point for customization after application launch. 33 | return true 34 | } 35 | 36 | func applicationWillResignActive(_ application: UIApplication) { 37 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 38 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 39 | } 40 | 41 | func applicationDidEnterBackground(_ application: UIApplication) { 42 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 43 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 44 | } 45 | 46 | func applicationWillEnterForeground(_ application: UIApplication) { 47 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 48 | } 49 | 50 | func applicationDidBecomeActive(_ application: UIApplication) { 51 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 52 | } 53 | 54 | func applicationWillTerminate(_ application: UIApplication) { 55 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 56 | } 57 | 58 | 59 | } 60 | 61 | -------------------------------------------------------------------------------- /IHWaveformView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /IHWaveformView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /IHWaveformView/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /IHWaveformView/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /IHWaveformView/IHWaveFormView.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | //Copyright (c) 2017 Md Ibrahim Hassan 4 | // 5 | //Permission is hereby granted, free of charge, to any person obtaining a copy 6 | //of this software and associated documentation files (the "Software"), to deal 7 | //in the Software without restriction, including without limitation the rights 8 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | //copies of the Software, and to permit persons to whom the Software is 10 | //furnished to do so, subject to the following conditions: 11 | // 12 | //The above copyright notice and this permission notice shall be included in all 13 | //copies or substantial portions of the Software. 14 | // 15 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | //SOFTWARE. 22 | 23 | import UIKit 24 | import AVFoundation 25 | import Accelerate 26 | 27 | protocol IHWaveFormViewDelegate : class { 28 | func didFinishPlayBack() 29 | func didStartPlayingWithSuccess() 30 | } 31 | 32 | @objc protocol IHWaveFormViewDataSource : class { 33 | func urlToPlay() -> URL 34 | @objc optional func shouldPreRender() -> Bool 35 | @objc optional func lineWidth() -> CGFloat 36 | @objc optional func lineSeperation() -> CGFloat 37 | 38 | } 39 | 40 | class IHWaveFormView: UIView, AVAudioPlayerDelegate { 41 | private var player: AVAudioPlayer! 42 | fileprivate let centerLineView = UIView() 43 | private var dataArray : [Float] = [] 44 | private var totalCount : Int = 0 45 | private var xPoint : CGFloat = 0.0 46 | private var gameTimer: Timer! 47 | fileprivate var internalLineWidth : CGFloat = 2.0 48 | fileprivate var internalLineSeperation : CGFloat = 1.0 49 | private var preRender : Bool = false 50 | fileprivate var width : CGFloat? 51 | 52 | private var urlToPlay : URL { 53 | return (dataSource?.urlToPlay())! 54 | } 55 | 56 | weak var delegate : IHWaveFormViewDelegate? 57 | weak var dataSource : IHWaveFormViewDataSource? { 58 | didSet { 59 | if (dataSource?.urlToPlay() != nil) { 60 | guard let preRenderOption = dataSource?.shouldPreRender?() else { 61 | self.getPath(url: (dataSource?.urlToPlay())!) 62 | preRender = false 63 | return 64 | } 65 | preRender = preRenderOption 66 | self.getPath(url: (dataSource?.urlToPlay())!) 67 | } 68 | } 69 | } 70 | 71 | required init?(coder aDecoder: NSCoder) { 72 | super.init(coder: aDecoder) 73 | xPoint = 0.0 74 | } 75 | 76 | override init(frame: CGRect) { 77 | super.init(frame: frame) 78 | xPoint = 0.0 79 | } 80 | 81 | override func draw(_ rect: CGRect) { 82 | super.draw(rect) 83 | commonInit() 84 | } 85 | 86 | var orientationChangesCount : Int = 0 87 | @objc func rotated(sender: UIDeviceOrientation) { 88 | orientationChangesCount += 1 89 | if (orientationChangesCount == 1) { 90 | return 91 | } 92 | redrawView() 93 | } 94 | 95 | private func eraseView() { 96 | for views in subviews { 97 | views.removeFromSuperview() 98 | } 99 | self.layer.sublayers?.forEach { $0.removeFromSuperlayer() } 100 | } 101 | 102 | func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { 103 | guard let gameTimer = gameTimer else { 104 | delegate?.didFinishPlayBack() 105 | return 106 | } 107 | gameTimer.invalidate() 108 | delegate?.didFinishPlayBack() 109 | } 110 | 111 | 112 | private func addCentreLine(){ 113 | centerLineView.frame = CGRect.init(x: 0, y: self.frame.size.height / 2.0, width: self.frame.size.width, height: 1) 114 | centerLineView.backgroundColor = .black 115 | self.addSubview(centerLineView) 116 | } 117 | 118 | private func invertColor(_ color : UIColor) -> UIColor { 119 | var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0 120 | self.backgroundColor?.getRed(&r, green: &g, blue: &b, alpha: &a) 121 | let lineColor = UIColor.init(red: self.invertB(r), green: self.invertB(g), blue: self.invert(b), alpha: a) 122 | return lineColor 123 | } 124 | 125 | private func invertB(_ val : CGFloat) -> CGFloat{ 126 | return (1.0 - val) * 0.9 127 | } 128 | 129 | private func invert(_ val : CGFloat) -> CGFloat{ 130 | if (val > 0.6 && val < 0.90){ 131 | return 0.6 + 0.1 132 | } 133 | return (1.0 - val) 134 | } 135 | 136 | func commonInit(){ 137 | self.addCentreLine() 138 | guard let lineWidth = dataSource?.lineWidth?() else { 139 | return 140 | } 141 | guard let lineSeperation = dataSource?.lineSeperation?() else { 142 | return 143 | } 144 | internalLineWidth = lineWidth 145 | internalLineSeperation = lineSeperation 146 | } 147 | 148 | private func getPath(url : URL){ 149 | if (preRender) { 150 | preRenderAudioFile(withPath: url, completion: { result in 151 | if (result) { 152 | self.player = try? AVAudioPlayer(contentsOf: url) 153 | self.player.delegate = self 154 | self.player.play() 155 | } 156 | }) 157 | return 158 | } 159 | do { 160 | if player != nil, 161 | (player.isPlaying) { 162 | xPoint = 0 163 | for i in dataArray { 164 | if (xPoint < CGFloat(player.currentTime) / CGFloat(player.duration) * self.bounds.width) { 165 | let twoDecimalPlaces = String(format: "%.2f", i) 166 | self.generatePoints1(dBVal: twoDecimalPlaces) 167 | } 168 | else{ 169 | break 170 | } 171 | } 172 | 173 | let val : CGFloat = CGFloat(player.duration) / (CGFloat(self.frame.size.width - xPoint) * CGFloat(player.rate)) 174 | self.trackAudio() 175 | gameTimer.invalidate() 176 | gameTimer = Timer.scheduledTimer(timeInterval: TimeInterval(val * (internalLineWidth + internalLineSeperation)), target: self, selector: #selector(trackAudio), userInfo: nil, repeats: true) 177 | return 178 | } 179 | player = try AVAudioPlayer(contentsOf: url) 180 | player.delegate = self 181 | player.enableRate = true 182 | player.isMeteringEnabled = true 183 | player.play() 184 | delegate?.didStartPlayingWithSuccess() 185 | let duration = player.duration 186 | let val : CGFloat = CGFloat(duration) / (CGFloat(self.frame.size.width) * CGFloat(player.rate)) 187 | self.trackAudio() 188 | gameTimer = Timer.scheduledTimer(timeInterval: TimeInterval(val * (internalLineWidth + internalLineSeperation)), target: self, selector: #selector(trackAudio), userInfo: nil, repeats: true) 189 | } catch { 190 | // couldn't load file :( 191 | } 192 | } 193 | 194 | private func makeNewWaveForm(_ yValNegative : CGFloat) -> (CGFloat){ 195 | let totalHeight = self.frame.size.height / 12.0 196 | let yVal : CGFloat = CGFloat(abs(yValNegative)) 197 | var yOffSet : CGFloat = totalHeight * 5 + (120 - 10)/(120 - 10) * totalHeight 198 | if (yVal > 0 && yVal <= 1){ 199 | yOffSet = (yVal - 0)/(1) * totalHeight 200 | } 201 | else if (yVal > 1 && yVal <= 3){ 202 | yOffSet = totalHeight + (yVal - 1)/2 * totalHeight 203 | } 204 | else if (yVal > 3 && yVal <= 6){ 205 | yOffSet = totalHeight * 2 + (yVal - 3)/3 * totalHeight 206 | } 207 | else if (yVal > 6 && yVal <= 7){ 208 | yOffSet = totalHeight * 3 + (yVal - 6)/1 * totalHeight 209 | } 210 | else if (yVal > 7 && yVal <= 10){ 211 | yOffSet = totalHeight * 4 + (yVal - 7)/3 * totalHeight 212 | } 213 | else if (yVal > 10 && yVal <= 120){ 214 | yOffSet = totalHeight * 5 + (yVal - 10)/(120 - 10) * totalHeight 215 | } 216 | return (yOffSet) 217 | } 218 | 219 | private func getReflectionPoint(yInput : CGFloat) -> CGFloat{ 220 | return (self.frame.size.height - CGFloat(abs(yInput))) 221 | } 222 | 223 | @objc private func trackAudio() { 224 | NotificationCenter.default.addObserver(self, selector: #selector(rotated(sender:)), name: UIDevice.orientationDidChangeNotification, object: nil) 225 | player.updateMeters() 226 | let dBLogValue : Float = player.averagePower(forChannel: 0) 227 | dataArray.append(dBLogValue) 228 | let twoDecimalPlaces = String(format: "%.2f", dataArray[totalCount]) 229 | totalCount += 1 230 | self.generatePoints1(dBVal: twoDecimalPlaces) 231 | } 232 | 233 | private func redrawView() { 234 | eraseView() 235 | self.commonInit() 236 | self.getPath(url: urlToPlay) 237 | } 238 | 239 | fileprivate func generatePoints1(dBVal : String){ 240 | let aPath = UIBezierPath() 241 | let floatVal : Float = Float(dBVal)! 242 | let fromYPoint : CGFloat = self.makeNewWaveForm(CGFloat(floatVal)) 243 | let toYPoint : CGFloat = self.getReflectionPoint(yInput: fromYPoint) 244 | aPath.move(to: CGPoint(x:xPoint , y: fromYPoint)) 245 | aPath.addLine(to: CGPoint(x: xPoint, y: toYPoint)) 246 | let diff = toYPoint - fromYPoint 247 | let shapeLayer1 = CAShapeLayer() 248 | let shapeLayer2 = CAShapeLayer() 249 | let shapeLayer3 = CAShapeLayer() 250 | self.layer.insertSublayer(shapeLayer1, at: 0) 251 | self.layer.insertSublayer(shapeLayer2, at: 1) 252 | self.layer.insertSublayer(shapeLayer3, at: 2) 253 | if diff <= 0.33 * self.frame.size.height { 254 | shapeLayer1.path = aPath.cgPath 255 | shapeLayer1.strokeColor = #colorLiteral(red: 0.937254902, green: 0.5058823529, blue: 0.4941176471, alpha: 1).cgColor 256 | shapeLayer1.lineWidth = internalLineWidth 257 | shapeLayer1.zPosition = 2.0 258 | } 259 | else if (diff <= self.frame.size.height * 0.66 && diff >= 0.33 * self.frame.size.height) { 260 | shapeLayer2.path = aPath.cgPath 261 | shapeLayer2.strokeColor = #colorLiteral(red: 0.7882352941, green: 0.3647058824, blue: 0.3529411765, alpha: 1).cgColor 262 | shapeLayer2.lineWidth = internalLineWidth 263 | shapeLayer1.zPosition = 0.0 264 | shapeLayer3.zPosition = 1.0 265 | shapeLayer2.zPosition = 2.0 266 | } 267 | else if (diff >= 0.67 * self.frame.size.height) 268 | { 269 | shapeLayer3.path = aPath.cgPath 270 | shapeLayer3.strokeColor = #colorLiteral(red: 0.7294117647, green: 0.1610280275, blue: 0.1210218742, alpha: 1).cgColor 271 | shapeLayer3.lineWidth = internalLineWidth 272 | shapeLayer2.zPosition = 1.0 273 | shapeLayer1.zPosition = 0.0 274 | shapeLayer3.zPosition = 2.0 275 | } 276 | xPoint += internalLineSeperation 277 | xPoint += internalLineWidth 278 | } 279 | } 280 | 281 | // Pre Render Code and Logic 282 | extension IHWaveFormView { 283 | 284 | func preRenderAudioFile(withPath url: URL, completion : @escaping(_ rendered: Bool) -> () ) { 285 | getDataArray(withPath: url, completionHandler: {value in 286 | DispatchQueue.main.async { 287 | for element in value { 288 | let twoDecimalPlaces = String(format: "%.2f", log(abs(element))) 289 | self.generatePoints1(dBVal: twoDecimalPlaces) 290 | } 291 | completion(true) 292 | } 293 | }) 294 | } 295 | 296 | private func getDataArray(withPath audioFileURL : URL, completionHandler: @escaping(_ success: [Float]) -> () ) { 297 | let audioFile = try! AVAudioFile(forReading: audioFileURL) 298 | let audioFilePFormat = audioFile.processingFormat 299 | let audioFileLength = audioFile.length 300 | // get numberOfReadLoops value 301 | let numberOfReadLoops = Int(self.frame.width / (internalLineWidth + internalLineSeperation)) 302 | let frameSizeToRead = Int(audioFileLength) / numberOfReadLoops 303 | DispatchQueue.global(qos: .userInitiated).async { 304 | var returnArray : [Float] = [] 305 | for i in 0.. CGFloat { 337 | if amount == nil { 338 | return (val * 0.9 * amount!) 339 | } 340 | return (val * 0.9 * 0.1) 341 | }*/ 342 | 343 | -------------------------------------------------------------------------------- /IHWaveformView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationPortraitUpsideDown 36 | UIInterfaceOrientationLandscapeRight 37 | 38 | UISupportedInterfaceOrientations~ipad 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationPortraitUpsideDown 42 | UIInterfaceOrientationLandscapeLeft 43 | UIInterfaceOrientationLandscapeRight 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /IHWaveformView/ViewController.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | //Copyright (c) 2017 Md Ibrahim Hassan 4 | // 5 | //Permission is hereby granted, free of charge, to any person obtaining a copy 6 | //of this software and associated documentation files (the "Software"), to deal 7 | //in the Software without restriction, including without limitation the rights 8 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | //copies of the Software, and to permit persons to whom the Software is 10 | //furnished to do so, subject to the following conditions: 11 | // 12 | //The above copyright notice and this permission notice shall be included in all 13 | //copies or substantial portions of the Software. 14 | // 15 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | //SOFTWARE. 22 | 23 | import UIKit 24 | class ViewController: UIViewController { 25 | 26 | @IBOutlet var musicView: IHWaveFormView! 27 | override func viewDidLoad() { 28 | super.viewDidLoad() 29 | 30 | // self.musicView.setUpView(urlToPlay: url!, lineWith: 2.0, lineSeperation: 1.0) 31 | self.musicView.backgroundColor = #colorLiteral(red: 0.9607843137, green: 0.9607843137, blue: 0.8509803922, alpha: 1) 32 | self.musicView.delegate = self 33 | self.musicView.dataSource = self 34 | 35 | } 36 | 37 | } 38 | 39 | extension ViewController: IHWaveFormViewDelegate { 40 | func didFinishPlayBack() { 41 | print ("playBack Finished") 42 | } 43 | 44 | func didStartPlayingWithSuccess() { 45 | print ("Playback started successfully") 46 | } 47 | } 48 | 49 | extension ViewController: IHWaveFormViewDataSource { 50 | 51 | func urlToPlay() -> URL { 52 | var url : URL? 53 | let path = Bundle.main.path(forResource: "bensound-sunny.mp3", ofType:nil)! 54 | url = URL(fileURLWithPath: path) 55 | return url! 56 | } 57 | 58 | func shouldPreRender() -> Bool { 59 | return true 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Md Ibrahim Hassan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IHEqualizerView 2 | A simple, intuitive audio asset visualiser for iOS. 3 | 4 | # Example 5 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 6 | 7 | # Highlights 8 | Very simple and lightweight. Color Coding for differnt output range. Written in Swift. 9 | 10 | * Pale red for low output 11 | * Light red for medium 12 | * Red for high output 13 | * Based on the output distribution pattern of Recorder App from Apple 14 | * Option to pre-render audio file 15 | 16 | # Getting Started 17 | 18 | To begin using IHEqualizerView you must first make sure you have the proper build requirements. 19 | 20 | 21 | # Screen Recordings 22 | | | | 23 | |:-------------------------:|:-------------------------:| 24 | |Screen Recording 1 | Screen Recording 2| 25 | 26 | # Build Requirements 27 | 28 | ## iOS 29 | 30 | 10.0+ 31 | 32 | ## Installation 33 | 34 | IHEqualizerView is available through [CocoaPods](http://cocoapods.org). To install 35 | it, simply add the following line to your Podfile: 36 | 37 | ```ruby 38 | pod 'IHEqualizerView' 39 | ``` 40 | 41 | # Adding Manually To Project 42 | 43 | You can add IHEqualizerView to your project in a few ways: 44 | 45 | The way to use IHEqualizerView is to download the IHWaveFormView class file in your project as is and use. 46 | 47 | # Usage 48 | 49 | ## StoryBoard 50 | 51 | Make the UIView a subclass of IHEqualizerView, make its outlet and initialise as follows: 52 | 53 | @IBOutlet var musicView: IHWaveFormView! 54 | extension ViewController: IHWaveFormViewDataSource { 55 | 56 | func urlToPlay() -> URL { 57 | var url : URL? 58 | let path = Bundle.main.path(forResource: "bensound-sunny.mp3", ofType:nil)! 59 | url = URL(fileURLWithPath: path) 60 | 61 | return url! 62 | } 63 | 64 | func lineWidth() -> CGFloat { 2 } 65 | 66 | func lineSeperation() -> CGFloat { 1 } 67 | 68 | func shouldPreRender() -> Bool { true } 69 | } 70 | 71 | ## Author 72 | 73 | Md Ibrahim Hassan, mdibrahimhassan@gmail.com 74 | 75 | ## License 76 | 77 | IHEqualizerView is available under the MIT license. See the LICENSE file for more info. 78 | 79 | -------------------------------------------------------------------------------- /bensound-sunny.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ibrahimhass/IHEqualizerView/0799cf3458ec28b72992426ef01f226238a06f72/bensound-sunny.mp3 --------------------------------------------------------------------------------