├── .DS_Store ├── 18461506.png ├── 45961649.png ├── KTSoundWave.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── keenteam.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── keenteam.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── KTSoundWave ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── AudioRecorder.h ├── AudioRecorder.m ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── DDSoundWave │ ├── DDSoundWaveView.h │ └── DDSoundWaveView.m ├── Info.plist ├── UIView+LayoutMethods.h ├── UIView+LayoutMethods.m ├── ViewController.h ├── ViewController.m └── main.m ├── KTSoundWaveTests ├── Info.plist └── KTSoundWaveTests.m ├── KTSoundWaveUITests ├── Info.plist └── KTSoundWaveUITests.m └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeenTeam1990/KTAudioSoundWave/3ea7294998aec5ebbb0d802a001adcb588fb0051/.DS_Store -------------------------------------------------------------------------------- /18461506.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeenTeam1990/KTAudioSoundWave/3ea7294998aec5ebbb0d802a001adcb588fb0051/18461506.png -------------------------------------------------------------------------------- /45961649.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeenTeam1990/KTAudioSoundWave/3ea7294998aec5ebbb0d802a001adcb588fb0051/45961649.png -------------------------------------------------------------------------------- /KTSoundWave.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 451E03FB21DC585500CCCB5C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 451E03FA21DC585500CCCB5C /* AppDelegate.m */; }; 11 | 451E03FE21DC585500CCCB5C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 451E03FD21DC585500CCCB5C /* ViewController.m */; }; 12 | 451E040121DC585500CCCB5C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 451E03FF21DC585500CCCB5C /* Main.storyboard */; }; 13 | 451E040321DC585600CCCB5C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 451E040221DC585600CCCB5C /* Assets.xcassets */; }; 14 | 451E040621DC585600CCCB5C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 451E040421DC585600CCCB5C /* LaunchScreen.storyboard */; }; 15 | 451E040921DC585600CCCB5C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 451E040821DC585600CCCB5C /* main.m */; }; 16 | 451E041321DC585600CCCB5C /* KTSoundWaveTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 451E041221DC585600CCCB5C /* KTSoundWaveTests.m */; }; 17 | 451E041E21DC585600CCCB5C /* KTSoundWaveUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 451E041D21DC585600CCCB5C /* KTSoundWaveUITests.m */; }; 18 | 451E042D21DC587900CCCB5C /* UIView+LayoutMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = 451E042C21DC587900CCCB5C /* UIView+LayoutMethods.m */; }; 19 | 451E043121DC58DC00CCCB5C /* DDSoundWaveView.m in Sources */ = {isa = PBXBuildFile; fileRef = 451E043021DC58DC00CCCB5C /* DDSoundWaveView.m */; }; 20 | 451E043421DC5BF200CCCB5C /* AudioRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 451E043221DC5BF100CCCB5C /* AudioRecorder.m */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXContainerItemProxy section */ 24 | 451E040F21DC585600CCCB5C /* PBXContainerItemProxy */ = { 25 | isa = PBXContainerItemProxy; 26 | containerPortal = 451E03EE21DC585500CCCB5C /* Project object */; 27 | proxyType = 1; 28 | remoteGlobalIDString = 451E03F521DC585500CCCB5C; 29 | remoteInfo = KTSoundWave; 30 | }; 31 | 451E041A21DC585600CCCB5C /* PBXContainerItemProxy */ = { 32 | isa = PBXContainerItemProxy; 33 | containerPortal = 451E03EE21DC585500CCCB5C /* Project object */; 34 | proxyType = 1; 35 | remoteGlobalIDString = 451E03F521DC585500CCCB5C; 36 | remoteInfo = KTSoundWave; 37 | }; 38 | /* End PBXContainerItemProxy section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | 451E03F621DC585500CCCB5C /* KTSoundWave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KTSoundWave.app; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | 451E03F921DC585500CCCB5C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 43 | 451E03FA21DC585500CCCB5C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 44 | 451E03FC21DC585500CCCB5C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 45 | 451E03FD21DC585500CCCB5C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 46 | 451E040021DC585500CCCB5C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 47 | 451E040221DC585600CCCB5C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 48 | 451E040521DC585600CCCB5C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 49 | 451E040721DC585600CCCB5C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50 | 451E040821DC585600CCCB5C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 51 | 451E040E21DC585600CCCB5C /* KTSoundWaveTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KTSoundWaveTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 451E041221DC585600CCCB5C /* KTSoundWaveTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KTSoundWaveTests.m; sourceTree = ""; }; 53 | 451E041421DC585600CCCB5C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 451E041921DC585600CCCB5C /* KTSoundWaveUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KTSoundWaveUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 451E041D21DC585600CCCB5C /* KTSoundWaveUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KTSoundWaveUITests.m; sourceTree = ""; }; 56 | 451E041F21DC585600CCCB5C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 451E042B21DC587900CCCB5C /* UIView+LayoutMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+LayoutMethods.h"; sourceTree = ""; }; 58 | 451E042C21DC587900CCCB5C /* UIView+LayoutMethods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+LayoutMethods.m"; sourceTree = ""; }; 59 | 451E042F21DC58DC00CCCB5C /* DDSoundWaveView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDSoundWaveView.h; sourceTree = ""; }; 60 | 451E043021DC58DC00CCCB5C /* DDSoundWaveView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDSoundWaveView.m; sourceTree = ""; }; 61 | 451E043221DC5BF100CCCB5C /* AudioRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioRecorder.m; sourceTree = ""; }; 62 | 451E043321DC5BF100CCCB5C /* AudioRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioRecorder.h; sourceTree = ""; }; 63 | /* End PBXFileReference section */ 64 | 65 | /* Begin PBXFrameworksBuildPhase section */ 66 | 451E03F321DC585500CCCB5C /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | 451E040B21DC585600CCCB5C /* Frameworks */ = { 74 | isa = PBXFrameworksBuildPhase; 75 | buildActionMask = 2147483647; 76 | files = ( 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | 451E041621DC585600CCCB5C /* Frameworks */ = { 81 | isa = PBXFrameworksBuildPhase; 82 | buildActionMask = 2147483647; 83 | files = ( 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | /* End PBXFrameworksBuildPhase section */ 88 | 89 | /* Begin PBXGroup section */ 90 | 451E03ED21DC585500CCCB5C = { 91 | isa = PBXGroup; 92 | children = ( 93 | 451E03F821DC585500CCCB5C /* KTSoundWave */, 94 | 451E041121DC585600CCCB5C /* KTSoundWaveTests */, 95 | 451E041C21DC585600CCCB5C /* KTSoundWaveUITests */, 96 | 451E03F721DC585500CCCB5C /* Products */, 97 | ); 98 | sourceTree = ""; 99 | }; 100 | 451E03F721DC585500CCCB5C /* Products */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 451E03F621DC585500CCCB5C /* KTSoundWave.app */, 104 | 451E040E21DC585600CCCB5C /* KTSoundWaveTests.xctest */, 105 | 451E041921DC585600CCCB5C /* KTSoundWaveUITests.xctest */, 106 | ); 107 | name = Products; 108 | sourceTree = ""; 109 | }; 110 | 451E03F821DC585500CCCB5C /* KTSoundWave */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 451E042E21DC58DC00CCCB5C /* DDSoundWave */, 114 | 451E042B21DC587900CCCB5C /* UIView+LayoutMethods.h */, 115 | 451E042C21DC587900CCCB5C /* UIView+LayoutMethods.m */, 116 | 451E043321DC5BF100CCCB5C /* AudioRecorder.h */, 117 | 451E043221DC5BF100CCCB5C /* AudioRecorder.m */, 118 | 451E03F921DC585500CCCB5C /* AppDelegate.h */, 119 | 451E03FA21DC585500CCCB5C /* AppDelegate.m */, 120 | 451E03FC21DC585500CCCB5C /* ViewController.h */, 121 | 451E03FD21DC585500CCCB5C /* ViewController.m */, 122 | 451E03FF21DC585500CCCB5C /* Main.storyboard */, 123 | 451E040221DC585600CCCB5C /* Assets.xcassets */, 124 | 451E040421DC585600CCCB5C /* LaunchScreen.storyboard */, 125 | 451E040721DC585600CCCB5C /* Info.plist */, 126 | 451E040821DC585600CCCB5C /* main.m */, 127 | ); 128 | path = KTSoundWave; 129 | sourceTree = ""; 130 | }; 131 | 451E041121DC585600CCCB5C /* KTSoundWaveTests */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 451E041221DC585600CCCB5C /* KTSoundWaveTests.m */, 135 | 451E041421DC585600CCCB5C /* Info.plist */, 136 | ); 137 | path = KTSoundWaveTests; 138 | sourceTree = ""; 139 | }; 140 | 451E041C21DC585600CCCB5C /* KTSoundWaveUITests */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 451E041D21DC585600CCCB5C /* KTSoundWaveUITests.m */, 144 | 451E041F21DC585600CCCB5C /* Info.plist */, 145 | ); 146 | path = KTSoundWaveUITests; 147 | sourceTree = ""; 148 | }; 149 | 451E042E21DC58DC00CCCB5C /* DDSoundWave */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 451E042F21DC58DC00CCCB5C /* DDSoundWaveView.h */, 153 | 451E043021DC58DC00CCCB5C /* DDSoundWaveView.m */, 154 | ); 155 | path = DDSoundWave; 156 | sourceTree = ""; 157 | }; 158 | /* End PBXGroup section */ 159 | 160 | /* Begin PBXNativeTarget section */ 161 | 451E03F521DC585500CCCB5C /* KTSoundWave */ = { 162 | isa = PBXNativeTarget; 163 | buildConfigurationList = 451E042221DC585600CCCB5C /* Build configuration list for PBXNativeTarget "KTSoundWave" */; 164 | buildPhases = ( 165 | 451E03F221DC585500CCCB5C /* Sources */, 166 | 451E03F321DC585500CCCB5C /* Frameworks */, 167 | 451E03F421DC585500CCCB5C /* Resources */, 168 | ); 169 | buildRules = ( 170 | ); 171 | dependencies = ( 172 | ); 173 | name = KTSoundWave; 174 | productName = KTSoundWave; 175 | productReference = 451E03F621DC585500CCCB5C /* KTSoundWave.app */; 176 | productType = "com.apple.product-type.application"; 177 | }; 178 | 451E040D21DC585600CCCB5C /* KTSoundWaveTests */ = { 179 | isa = PBXNativeTarget; 180 | buildConfigurationList = 451E042521DC585600CCCB5C /* Build configuration list for PBXNativeTarget "KTSoundWaveTests" */; 181 | buildPhases = ( 182 | 451E040A21DC585600CCCB5C /* Sources */, 183 | 451E040B21DC585600CCCB5C /* Frameworks */, 184 | 451E040C21DC585600CCCB5C /* Resources */, 185 | ); 186 | buildRules = ( 187 | ); 188 | dependencies = ( 189 | 451E041021DC585600CCCB5C /* PBXTargetDependency */, 190 | ); 191 | name = KTSoundWaveTests; 192 | productName = KTSoundWaveTests; 193 | productReference = 451E040E21DC585600CCCB5C /* KTSoundWaveTests.xctest */; 194 | productType = "com.apple.product-type.bundle.unit-test"; 195 | }; 196 | 451E041821DC585600CCCB5C /* KTSoundWaveUITests */ = { 197 | isa = PBXNativeTarget; 198 | buildConfigurationList = 451E042821DC585600CCCB5C /* Build configuration list for PBXNativeTarget "KTSoundWaveUITests" */; 199 | buildPhases = ( 200 | 451E041521DC585600CCCB5C /* Sources */, 201 | 451E041621DC585600CCCB5C /* Frameworks */, 202 | 451E041721DC585600CCCB5C /* Resources */, 203 | ); 204 | buildRules = ( 205 | ); 206 | dependencies = ( 207 | 451E041B21DC585600CCCB5C /* PBXTargetDependency */, 208 | ); 209 | name = KTSoundWaveUITests; 210 | productName = KTSoundWaveUITests; 211 | productReference = 451E041921DC585600CCCB5C /* KTSoundWaveUITests.xctest */; 212 | productType = "com.apple.product-type.bundle.ui-testing"; 213 | }; 214 | /* End PBXNativeTarget section */ 215 | 216 | /* Begin PBXProject section */ 217 | 451E03EE21DC585500CCCB5C /* Project object */ = { 218 | isa = PBXProject; 219 | attributes = { 220 | LastUpgradeCheck = 1010; 221 | ORGANIZATIONNAME = keenteam; 222 | TargetAttributes = { 223 | 451E03F521DC585500CCCB5C = { 224 | CreatedOnToolsVersion = 10.1; 225 | }; 226 | 451E040D21DC585600CCCB5C = { 227 | CreatedOnToolsVersion = 10.1; 228 | TestTargetID = 451E03F521DC585500CCCB5C; 229 | }; 230 | 451E041821DC585600CCCB5C = { 231 | CreatedOnToolsVersion = 10.1; 232 | TestTargetID = 451E03F521DC585500CCCB5C; 233 | }; 234 | }; 235 | }; 236 | buildConfigurationList = 451E03F121DC585500CCCB5C /* Build configuration list for PBXProject "KTSoundWave" */; 237 | compatibilityVersion = "Xcode 9.3"; 238 | developmentRegion = en; 239 | hasScannedForEncodings = 0; 240 | knownRegions = ( 241 | en, 242 | Base, 243 | ); 244 | mainGroup = 451E03ED21DC585500CCCB5C; 245 | productRefGroup = 451E03F721DC585500CCCB5C /* Products */; 246 | projectDirPath = ""; 247 | projectRoot = ""; 248 | targets = ( 249 | 451E03F521DC585500CCCB5C /* KTSoundWave */, 250 | 451E040D21DC585600CCCB5C /* KTSoundWaveTests */, 251 | 451E041821DC585600CCCB5C /* KTSoundWaveUITests */, 252 | ); 253 | }; 254 | /* End PBXProject section */ 255 | 256 | /* Begin PBXResourcesBuildPhase section */ 257 | 451E03F421DC585500CCCB5C /* Resources */ = { 258 | isa = PBXResourcesBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | 451E040621DC585600CCCB5C /* LaunchScreen.storyboard in Resources */, 262 | 451E040321DC585600CCCB5C /* Assets.xcassets in Resources */, 263 | 451E040121DC585500CCCB5C /* Main.storyboard in Resources */, 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | 451E040C21DC585600CCCB5C /* Resources */ = { 268 | isa = PBXResourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | ); 272 | runOnlyForDeploymentPostprocessing = 0; 273 | }; 274 | 451E041721DC585600CCCB5C /* Resources */ = { 275 | isa = PBXResourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | /* End PBXResourcesBuildPhase section */ 282 | 283 | /* Begin PBXSourcesBuildPhase section */ 284 | 451E03F221DC585500CCCB5C /* Sources */ = { 285 | isa = PBXSourcesBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | 451E03FE21DC585500CCCB5C /* ViewController.m in Sources */, 289 | 451E043121DC58DC00CCCB5C /* DDSoundWaveView.m in Sources */, 290 | 451E043421DC5BF200CCCB5C /* AudioRecorder.m in Sources */, 291 | 451E040921DC585600CCCB5C /* main.m in Sources */, 292 | 451E03FB21DC585500CCCB5C /* AppDelegate.m in Sources */, 293 | 451E042D21DC587900CCCB5C /* UIView+LayoutMethods.m in Sources */, 294 | ); 295 | runOnlyForDeploymentPostprocessing = 0; 296 | }; 297 | 451E040A21DC585600CCCB5C /* Sources */ = { 298 | isa = PBXSourcesBuildPhase; 299 | buildActionMask = 2147483647; 300 | files = ( 301 | 451E041321DC585600CCCB5C /* KTSoundWaveTests.m in Sources */, 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | }; 305 | 451E041521DC585600CCCB5C /* Sources */ = { 306 | isa = PBXSourcesBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | 451E041E21DC585600CCCB5C /* KTSoundWaveUITests.m in Sources */, 310 | ); 311 | runOnlyForDeploymentPostprocessing = 0; 312 | }; 313 | /* End PBXSourcesBuildPhase section */ 314 | 315 | /* Begin PBXTargetDependency section */ 316 | 451E041021DC585600CCCB5C /* PBXTargetDependency */ = { 317 | isa = PBXTargetDependency; 318 | target = 451E03F521DC585500CCCB5C /* KTSoundWave */; 319 | targetProxy = 451E040F21DC585600CCCB5C /* PBXContainerItemProxy */; 320 | }; 321 | 451E041B21DC585600CCCB5C /* PBXTargetDependency */ = { 322 | isa = PBXTargetDependency; 323 | target = 451E03F521DC585500CCCB5C /* KTSoundWave */; 324 | targetProxy = 451E041A21DC585600CCCB5C /* PBXContainerItemProxy */; 325 | }; 326 | /* End PBXTargetDependency section */ 327 | 328 | /* Begin PBXVariantGroup section */ 329 | 451E03FF21DC585500CCCB5C /* Main.storyboard */ = { 330 | isa = PBXVariantGroup; 331 | children = ( 332 | 451E040021DC585500CCCB5C /* Base */, 333 | ); 334 | name = Main.storyboard; 335 | sourceTree = ""; 336 | }; 337 | 451E040421DC585600CCCB5C /* LaunchScreen.storyboard */ = { 338 | isa = PBXVariantGroup; 339 | children = ( 340 | 451E040521DC585600CCCB5C /* Base */, 341 | ); 342 | name = LaunchScreen.storyboard; 343 | sourceTree = ""; 344 | }; 345 | /* End PBXVariantGroup section */ 346 | 347 | /* Begin XCBuildConfiguration section */ 348 | 451E042021DC585600CCCB5C /* Debug */ = { 349 | isa = XCBuildConfiguration; 350 | buildSettings = { 351 | ALWAYS_SEARCH_USER_PATHS = NO; 352 | CLANG_ANALYZER_NONNULL = YES; 353 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 354 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 355 | CLANG_CXX_LIBRARY = "libc++"; 356 | CLANG_ENABLE_MODULES = YES; 357 | CLANG_ENABLE_OBJC_ARC = YES; 358 | CLANG_ENABLE_OBJC_WEAK = YES; 359 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 360 | CLANG_WARN_BOOL_CONVERSION = YES; 361 | CLANG_WARN_COMMA = YES; 362 | CLANG_WARN_CONSTANT_CONVERSION = YES; 363 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 364 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 365 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 366 | CLANG_WARN_EMPTY_BODY = YES; 367 | CLANG_WARN_ENUM_CONVERSION = YES; 368 | CLANG_WARN_INFINITE_RECURSION = YES; 369 | CLANG_WARN_INT_CONVERSION = YES; 370 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 371 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 372 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 373 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 374 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 375 | CLANG_WARN_STRICT_PROTOTYPES = YES; 376 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 377 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 378 | CLANG_WARN_UNREACHABLE_CODE = YES; 379 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 380 | CODE_SIGN_IDENTITY = "iPhone Developer"; 381 | COPY_PHASE_STRIP = NO; 382 | DEBUG_INFORMATION_FORMAT = dwarf; 383 | ENABLE_STRICT_OBJC_MSGSEND = YES; 384 | ENABLE_TESTABILITY = YES; 385 | GCC_C_LANGUAGE_STANDARD = gnu11; 386 | GCC_DYNAMIC_NO_PIC = NO; 387 | GCC_NO_COMMON_BLOCKS = YES; 388 | GCC_OPTIMIZATION_LEVEL = 0; 389 | GCC_PREPROCESSOR_DEFINITIONS = ( 390 | "DEBUG=1", 391 | "$(inherited)", 392 | ); 393 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 394 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 395 | GCC_WARN_UNDECLARED_SELECTOR = YES; 396 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 397 | GCC_WARN_UNUSED_FUNCTION = YES; 398 | GCC_WARN_UNUSED_VARIABLE = YES; 399 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 400 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 401 | MTL_FAST_MATH = YES; 402 | ONLY_ACTIVE_ARCH = YES; 403 | SDKROOT = iphoneos; 404 | }; 405 | name = Debug; 406 | }; 407 | 451E042121DC585600CCCB5C /* Release */ = { 408 | isa = XCBuildConfiguration; 409 | buildSettings = { 410 | ALWAYS_SEARCH_USER_PATHS = NO; 411 | CLANG_ANALYZER_NONNULL = YES; 412 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 413 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 414 | CLANG_CXX_LIBRARY = "libc++"; 415 | CLANG_ENABLE_MODULES = YES; 416 | CLANG_ENABLE_OBJC_ARC = YES; 417 | CLANG_ENABLE_OBJC_WEAK = YES; 418 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 419 | CLANG_WARN_BOOL_CONVERSION = YES; 420 | CLANG_WARN_COMMA = YES; 421 | CLANG_WARN_CONSTANT_CONVERSION = YES; 422 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 423 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 424 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 425 | CLANG_WARN_EMPTY_BODY = YES; 426 | CLANG_WARN_ENUM_CONVERSION = YES; 427 | CLANG_WARN_INFINITE_RECURSION = YES; 428 | CLANG_WARN_INT_CONVERSION = YES; 429 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 430 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 431 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 432 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 433 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 434 | CLANG_WARN_STRICT_PROTOTYPES = YES; 435 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 436 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 437 | CLANG_WARN_UNREACHABLE_CODE = YES; 438 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 439 | CODE_SIGN_IDENTITY = "iPhone Developer"; 440 | COPY_PHASE_STRIP = NO; 441 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 442 | ENABLE_NS_ASSERTIONS = NO; 443 | ENABLE_STRICT_OBJC_MSGSEND = YES; 444 | GCC_C_LANGUAGE_STANDARD = gnu11; 445 | GCC_NO_COMMON_BLOCKS = YES; 446 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 447 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 448 | GCC_WARN_UNDECLARED_SELECTOR = YES; 449 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 450 | GCC_WARN_UNUSED_FUNCTION = YES; 451 | GCC_WARN_UNUSED_VARIABLE = YES; 452 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 453 | MTL_ENABLE_DEBUG_INFO = NO; 454 | MTL_FAST_MATH = YES; 455 | SDKROOT = iphoneos; 456 | VALIDATE_PRODUCT = YES; 457 | }; 458 | name = Release; 459 | }; 460 | 451E042321DC585600CCCB5C /* Debug */ = { 461 | isa = XCBuildConfiguration; 462 | buildSettings = { 463 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 464 | CODE_SIGN_STYLE = Automatic; 465 | DEVELOPMENT_TEAM = WUWYVL564K; 466 | INFOPLIST_FILE = KTSoundWave/Info.plist; 467 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 468 | LD_RUNPATH_SEARCH_PATHS = ( 469 | "$(inherited)", 470 | "@executable_path/Frameworks", 471 | ); 472 | PRODUCT_BUNDLE_IDENTIFIER = kt.KTSoundWave; 473 | PRODUCT_NAME = "$(TARGET_NAME)"; 474 | TARGETED_DEVICE_FAMILY = "1,2"; 475 | }; 476 | name = Debug; 477 | }; 478 | 451E042421DC585600CCCB5C /* Release */ = { 479 | isa = XCBuildConfiguration; 480 | buildSettings = { 481 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 482 | CODE_SIGN_STYLE = Automatic; 483 | DEVELOPMENT_TEAM = WUWYVL564K; 484 | INFOPLIST_FILE = KTSoundWave/Info.plist; 485 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 486 | LD_RUNPATH_SEARCH_PATHS = ( 487 | "$(inherited)", 488 | "@executable_path/Frameworks", 489 | ); 490 | PRODUCT_BUNDLE_IDENTIFIER = kt.KTSoundWave; 491 | PRODUCT_NAME = "$(TARGET_NAME)"; 492 | TARGETED_DEVICE_FAMILY = "1,2"; 493 | }; 494 | name = Release; 495 | }; 496 | 451E042621DC585600CCCB5C /* Debug */ = { 497 | isa = XCBuildConfiguration; 498 | buildSettings = { 499 | BUNDLE_LOADER = "$(TEST_HOST)"; 500 | CODE_SIGN_STYLE = Automatic; 501 | DEVELOPMENT_TEAM = WUWYVL564K; 502 | INFOPLIST_FILE = KTSoundWaveTests/Info.plist; 503 | LD_RUNPATH_SEARCH_PATHS = ( 504 | "$(inherited)", 505 | "@executable_path/Frameworks", 506 | "@loader_path/Frameworks", 507 | ); 508 | PRODUCT_BUNDLE_IDENTIFIER = kt.KTSoundWaveTests; 509 | PRODUCT_NAME = "$(TARGET_NAME)"; 510 | TARGETED_DEVICE_FAMILY = "1,2"; 511 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KTSoundWave.app/KTSoundWave"; 512 | }; 513 | name = Debug; 514 | }; 515 | 451E042721DC585600CCCB5C /* Release */ = { 516 | isa = XCBuildConfiguration; 517 | buildSettings = { 518 | BUNDLE_LOADER = "$(TEST_HOST)"; 519 | CODE_SIGN_STYLE = Automatic; 520 | DEVELOPMENT_TEAM = WUWYVL564K; 521 | INFOPLIST_FILE = KTSoundWaveTests/Info.plist; 522 | LD_RUNPATH_SEARCH_PATHS = ( 523 | "$(inherited)", 524 | "@executable_path/Frameworks", 525 | "@loader_path/Frameworks", 526 | ); 527 | PRODUCT_BUNDLE_IDENTIFIER = kt.KTSoundWaveTests; 528 | PRODUCT_NAME = "$(TARGET_NAME)"; 529 | TARGETED_DEVICE_FAMILY = "1,2"; 530 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KTSoundWave.app/KTSoundWave"; 531 | }; 532 | name = Release; 533 | }; 534 | 451E042921DC585600CCCB5C /* Debug */ = { 535 | isa = XCBuildConfiguration; 536 | buildSettings = { 537 | CODE_SIGN_STYLE = Automatic; 538 | DEVELOPMENT_TEAM = WUWYVL564K; 539 | INFOPLIST_FILE = KTSoundWaveUITests/Info.plist; 540 | LD_RUNPATH_SEARCH_PATHS = ( 541 | "$(inherited)", 542 | "@executable_path/Frameworks", 543 | "@loader_path/Frameworks", 544 | ); 545 | PRODUCT_BUNDLE_IDENTIFIER = kt.KTSoundWaveUITests; 546 | PRODUCT_NAME = "$(TARGET_NAME)"; 547 | TARGETED_DEVICE_FAMILY = "1,2"; 548 | TEST_TARGET_NAME = KTSoundWave; 549 | }; 550 | name = Debug; 551 | }; 552 | 451E042A21DC585600CCCB5C /* Release */ = { 553 | isa = XCBuildConfiguration; 554 | buildSettings = { 555 | CODE_SIGN_STYLE = Automatic; 556 | DEVELOPMENT_TEAM = WUWYVL564K; 557 | INFOPLIST_FILE = KTSoundWaveUITests/Info.plist; 558 | LD_RUNPATH_SEARCH_PATHS = ( 559 | "$(inherited)", 560 | "@executable_path/Frameworks", 561 | "@loader_path/Frameworks", 562 | ); 563 | PRODUCT_BUNDLE_IDENTIFIER = kt.KTSoundWaveUITests; 564 | PRODUCT_NAME = "$(TARGET_NAME)"; 565 | TARGETED_DEVICE_FAMILY = "1,2"; 566 | TEST_TARGET_NAME = KTSoundWave; 567 | }; 568 | name = Release; 569 | }; 570 | /* End XCBuildConfiguration section */ 571 | 572 | /* Begin XCConfigurationList section */ 573 | 451E03F121DC585500CCCB5C /* Build configuration list for PBXProject "KTSoundWave" */ = { 574 | isa = XCConfigurationList; 575 | buildConfigurations = ( 576 | 451E042021DC585600CCCB5C /* Debug */, 577 | 451E042121DC585600CCCB5C /* Release */, 578 | ); 579 | defaultConfigurationIsVisible = 0; 580 | defaultConfigurationName = Release; 581 | }; 582 | 451E042221DC585600CCCB5C /* Build configuration list for PBXNativeTarget "KTSoundWave" */ = { 583 | isa = XCConfigurationList; 584 | buildConfigurations = ( 585 | 451E042321DC585600CCCB5C /* Debug */, 586 | 451E042421DC585600CCCB5C /* Release */, 587 | ); 588 | defaultConfigurationIsVisible = 0; 589 | defaultConfigurationName = Release; 590 | }; 591 | 451E042521DC585600CCCB5C /* Build configuration list for PBXNativeTarget "KTSoundWaveTests" */ = { 592 | isa = XCConfigurationList; 593 | buildConfigurations = ( 594 | 451E042621DC585600CCCB5C /* Debug */, 595 | 451E042721DC585600CCCB5C /* Release */, 596 | ); 597 | defaultConfigurationIsVisible = 0; 598 | defaultConfigurationName = Release; 599 | }; 600 | 451E042821DC585600CCCB5C /* Build configuration list for PBXNativeTarget "KTSoundWaveUITests" */ = { 601 | isa = XCConfigurationList; 602 | buildConfigurations = ( 603 | 451E042921DC585600CCCB5C /* Debug */, 604 | 451E042A21DC585600CCCB5C /* Release */, 605 | ); 606 | defaultConfigurationIsVisible = 0; 607 | defaultConfigurationName = Release; 608 | }; 609 | /* End XCConfigurationList section */ 610 | }; 611 | rootObject = 451E03EE21DC585500CCCB5C /* Project object */; 612 | } 613 | -------------------------------------------------------------------------------- /KTSoundWave.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /KTSoundWave.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /KTSoundWave.xcodeproj/project.xcworkspace/xcuserdata/keenteam.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KeenTeam1990/KTAudioSoundWave/3ea7294998aec5ebbb0d802a001adcb588fb0051/KTSoundWave.xcodeproj/project.xcworkspace/xcuserdata/keenteam.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /KTSoundWave.xcodeproj/xcuserdata/keenteam.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /KTSoundWave.xcodeproj/xcuserdata/keenteam.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | KTSoundWave.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /KTSoundWave/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // KTSoundWave 4 | // 5 | // Created by keenteam on 2019/1/2. 6 | // Copyright © 2019 keenteam. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /KTSoundWave/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // KTSoundWave 4 | // 5 | // Created by keenteam on 2019/1/2. 6 | // Copyright © 2019 keenteam. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // 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. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /KTSoundWave/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 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /KTSoundWave/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /KTSoundWave/AudioRecorder.h: -------------------------------------------------------------------------------- 1 | // 2 | // AudioRecorder.h 3 | // AudioRecorder 4 | // 5 | // Created by builder on 2018/4/24. 6 | // Copyright © 2018年 builder. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class AudioRecorder; 13 | @protocol AudioRecorderDelegate 14 | 15 | @optional 16 | 17 | - (void)audioRecorderDidVoiceChanged:(AudioRecorder *)recorder value:(double)value; 18 | 19 | - (void)audioRecorderDidFinished:(AudioRecorder *)recorder successfully:(BOOL)flag; 20 | 21 | @end 22 | 23 | @interface AudioRecorder : NSObject 24 | 25 | #pragma mark - 录音 26 | 27 | ///单例 28 | + (AudioRecorder *)shareInstance; 29 | ///设置委托 30 | - (void)setRecorderDelegate:(id)recorderDelegate; 31 | ///设置录音配置 32 | - (void)setRecorderSetting:(NSMutableDictionary *)settingDict; 33 | ///开始录音 34 | - (NSError *)startRecordWithFilePath:(NSString *)filePath; 35 | ///停止录音 36 | - (void)stopRecord; 37 | ///获取录音路径 38 | - (NSString *)getRecordFilePath; 39 | ///获取录音时长 40 | - (NSTimeInterval )getRecordDurationWithFilePath:(NSString *)filePath; 41 | ///获得录音实例 42 | - (AVAudioRecorder *)getAVAudioRecorder; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /KTSoundWave/AudioRecorder.m: -------------------------------------------------------------------------------- 1 | // 2 | // AudioRecorder.m 3 | // AudioRecorder 4 | // 5 | // Created by builder on 2018/4/24. 6 | // Copyright © 2018年 builder. All rights reserved. 7 | // 8 | 9 | #import "AudioRecorder.h" 10 | 11 | @interface AudioRecorder () 12 | 13 | @property (nonatomic,assign) id delegate; 14 | @property (nonatomic,strong) AVAudioRecorder *avAudioRecorder; //录音 15 | @property (nonatomic,strong) NSMutableDictionary *audioRecorderSetting; //录音设置 16 | @property (nonatomic,strong) NSTimer *recorderTimer; //录音音量计时器 17 | @property (nonatomic,copy) NSString *recordFilePath; //录音文件路径 18 | @property (nonatomic,assign) double audioRecorderTime; //录音时长 19 | 20 | 21 | @end 22 | 23 | @implementation AudioRecorder 24 | 25 | #pragma mark - 初始化 26 | 27 | - (instancetype)init{ 28 | self = [super init]; 29 | if (self) { 30 | // 参数设置 格式、采样率、录音通道、线性采样位数、录音质量 31 | [self initAudioRecorderSetting]; 32 | } 33 | return self; 34 | } 35 | 36 | /// 参数设置 格式、采样率、录音通道、线性采样位数、录音质量 37 | - (void)initAudioRecorderSetting{ 38 | self.audioRecorderSetting = [NSMutableDictionary dictionary]; 39 | //设置录音格式,kAudioFormatLinearPCM 40 | [self.audioRecorderSetting setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey]; 41 | //设置录音采样率(Hz) 如:AVSampleRateKey==8000/44100/96000(影响音频的质量) 42 | //设置录音采样率,8000是电话采样率,对于一般的录音已经够了 43 | [self.audioRecorderSetting setValue:[NSNumber numberWithInt:11025] forKey:AVSampleRateKey]; 44 | //设置通道,1和2,这里采用单声道 45 | [self.audioRecorderSetting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey]; 46 | //每个采样点位数,分为8,16,24,32 47 | [self.audioRecorderSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey]; 48 | //是否使用浮点数采样 49 | [self.audioRecorderSetting setObject:@(YES) forKey:AVLinearPCMIsFloatKey]; 50 | //录音的质量 51 | [self.audioRecorderSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey]; 52 | } 53 | 54 | ///单例 55 | + (AudioRecorder *)shareInstance{ 56 | static AudioRecorder *staticAudioRecorder; 57 | static dispatch_once_t once; 58 | dispatch_once(&once, ^{ 59 | staticAudioRecorder = [[self alloc] init]; 60 | }); 61 | return staticAudioRecorder; 62 | } 63 | ///设置委托 64 | - (void)setRecorderDelegate:(id)recorderDelegate{ 65 | self.delegate = recorderDelegate; 66 | } 67 | ///设置录音配置 68 | - (void)setRecorderSetting:(NSMutableDictionary *)settingDict{ 69 | self.audioRecorderSetting = settingDict; 70 | } 71 | ///开始录音 72 | - (NSError *)startRecordWithFilePath:(NSString *)filePath{ 73 | 74 | self.recordFilePath = filePath; 75 | 76 | //若有,先停止 77 | [self stopRecord]; 78 | //生成录音文件 79 | NSURL *url = [NSURL fileURLWithPath:filePath]; 80 | NSError *error = nil; 81 | self.avAudioRecorder = [[AVAudioRecorder alloc] initWithURL:url settings:self.audioRecorderSetting error:&error]; 82 | 83 | // 开启音量检测 84 | self.avAudioRecorder.meteringEnabled = YES; 85 | self.avAudioRecorder.delegate = self; 86 | 87 | if (self.avAudioRecorder&&(error==nil)) { 88 | // 录音时设置audioSession属性,否则不兼容Ios7 89 | AVAudioSession *recoderSession = [AVAudioSession sharedInstance];//设置成能播放且能录音 90 | [recoderSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 91 | [recoderSession setActive:YES error:nil]; 92 | 93 | if ([self.avAudioRecorder prepareToRecord]) { 94 | self.audioRecorderTime = 0;//时长 95 | [self.avAudioRecorder record]; 96 | 97 | //开启定时器,刷新音量 98 | [self startTimer]; 99 | } 100 | } 101 | return error; 102 | } 103 | ///停止录音 104 | - (void)stopRecord{ 105 | if (self.avAudioRecorder) { 106 | if ([self.avAudioRecorder isRecording]) { 107 | //设置录音时长 108 | self.audioRecorderTime = [self.avAudioRecorder currentTime]; 109 | 110 | [self.avAudioRecorder stop]; 111 | } 112 | self.avAudioRecorder = nil; 113 | } 114 | //停掉计时器 115 | [self stopTimer]; 116 | } 117 | ///获取录音路径 118 | - (NSString *)getRecordFilePath{ 119 | return self.recordFilePath; 120 | } 121 | ///获取录音时长 122 | - (NSTimeInterval )getRecordDurationWithFilePath:(NSString *)filePath{ 123 | 124 | if (filePath==nil) 125 | return self.audioRecorderTime; 126 | 127 | //耗时操作 128 | NSURL *urlFile = [NSURL fileURLWithPath:filePath]; 129 | AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:urlFile error:nil]; 130 | NSTimeInterval time = audioPlayer.duration; 131 | audioPlayer = nil; 132 | return time; 133 | } 134 | 135 | ///获得录音实例 136 | - (AVAudioRecorder *)getAVAudioRecorder{ 137 | return self.avAudioRecorder; 138 | } 139 | 140 | #pragma mark - timer 141 | 142 | - (void)startTimer{ 143 | [self stopTimer]; 144 | self.recorderTimer = [NSTimer scheduledTimerWithTimeInterval:0.017f target:self selector:@selector(recorderVoiceChange) userInfo:nil repeats:YES]; 145 | } 146 | 147 | - (void)stopTimer{ 148 | if (self.recorderTimer) 149 | [self.recorderTimer invalidate]; 150 | self.recorderTimer = nil; 151 | } 152 | 153 | /// 录音音量显示 154 | - (void)recorderVoiceChange{ 155 | if (self.avAudioRecorder) { 156 | // 刷新音量数据 157 | [self.avAudioRecorder updateMeters]; 158 | 159 | // // 获取音量的平均值 160 | // [self.audioRecorder averagePowerForChannel:0]; 161 | // // 音量的最大值 162 | // [self.audioRecorder peakPowerForChannel:0]; 163 | 164 | //获取第一个通道的音频,注音音频的强度方位-160到0 165 | //float a = [self.avAudioRecorder averagePowerForChannel:0]; 166 | //float b = [self.avAudioRecorder peakPowerForChannel:0]; 167 | 168 | // double lowPassResults = (1.0/160)*(a+160); //pow(10, (0.05 * a));// // //0~1 169 | //double peakPassResults = pow(10, (0.05 * b));// (1.0/160)*(b+160); 170 | 171 | double lowPassResults = pow(10, (0.05 * [self.avAudioRecorder peakPowerForChannel:0])); 172 | 173 | //委托传值 174 | if (self.delegate&&([self.delegate respondsToSelector:@selector(audioRecorderDidVoiceChanged: value:)])) { 175 | [self.delegate audioRecorderDidVoiceChanged:self value:lowPassResults]; 176 | } 177 | } 178 | } 179 | 180 | 181 | 182 | #pragma mark - delegate 183 | 184 | /** 185 | * 录音完成,录音完成后播放录音 186 | * 187 | * @param recorder 录音机对象 188 | * @param flag 是否成功 189 | */ 190 | -(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{ 191 | 192 | //委托传值 193 | if (self.delegate&&([self.delegate respondsToSelector:@selector(audioRecorderDidFinished: successfully:)])) { 194 | [self.delegate audioRecorderDidFinished:self successfully:flag]; 195 | } 196 | } 197 | 198 | 199 | #pragma mark - dealloc 200 | /// 内存释放 201 | - (void)dealloc{ 202 | // 内存释放前先停止录音 203 | if (self.avAudioRecorder){ 204 | if ([self.avAudioRecorder isRecording]) 205 | [self.avAudioRecorder stop]; 206 | self.avAudioRecorder = nil; 207 | } 208 | //停掉计时器 209 | [self stopTimer]; 210 | 211 | if (self.audioRecorderSetting) 212 | self.audioRecorderSetting = nil; 213 | 214 | } 215 | 216 | @end 217 | -------------------------------------------------------------------------------- /KTSoundWave/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 | -------------------------------------------------------------------------------- /KTSoundWave/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 | -------------------------------------------------------------------------------- /KTSoundWave/DDSoundWave/DDSoundWaveView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DDSoundWaveView.h 3 | // DDSoundWave 4 | // 5 | // Created by Teaker on 2018/4/6. 6 | // Copyright © 2018年 Liuzhida. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | 绘制波浪特效视图 13 | */ 14 | @interface DDSoundWaveView : UIView 15 | - (void)displayWave:(double)value; 16 | @end 17 | -------------------------------------------------------------------------------- /KTSoundWave/DDSoundWave/DDSoundWaveView.m: -------------------------------------------------------------------------------- 1 | // 2 | // DDSoundWaveView.m 3 | // DDSoundWave 4 | // 5 | // Created by Teaker on 2018/4/6. 6 | // Copyright © 2018年 Liuzhida. All rights reserved. 7 | // 8 | 9 | #import "DDSoundWaveView.h" 10 | #import "UIView+LayoutMethods.h" 11 | 12 | #define kNumberOfWaves 5 13 | 14 | @interface DDSoundWaveView () 15 | { 16 | 17 | CGFloat _phase; //相位 18 | CGFloat _phaseShift; //相位偏移 19 | CGFloat _amplitude; //振幅 20 | CGFloat _maxAmplitude; //波峰 21 | CGFloat _idleAmplitude; //波谷 22 | CGFloat _waveHeight; //波高度 23 | CGFloat _waveWidth; //波长度 24 | CGFloat _waveMid; //波中心点 25 | CGFloat _density; //波分布密度 26 | CGFloat _frequency; //波频率 27 | CGFloat _mainWaveWidth; //主波宽度 28 | CGFloat _decorativeWavesWidth;//其他波宽度 29 | } 30 | @property (nonatomic, strong) NSMutableArray * waves; 31 | @property (nonatomic, strong) CALayer *waveLayer; //存放波浪layer 32 | 33 | @end 34 | 35 | @implementation DDSoundWaveView 36 | 37 | #pragma mark - overwrite init 38 | 39 | - (instancetype)init { 40 | self = [super init]; 41 | if (self) { 42 | [self setup]; 43 | } 44 | return self; 45 | } 46 | 47 | - (void)setup { 48 | 49 | _phaseShift = -0.25f; 50 | _idleAmplitude = 0.01f; 51 | _density = 1.f; 52 | _frequency = 1.2f; 53 | _mainWaveWidth = 2.0f; 54 | _decorativeWavesWidth = 1.0f; 55 | self.backgroundColor = [UIColor clearColor]; 56 | [self.layer addSublayer:self.waveLayer]; 57 | 58 | } 59 | 60 | - (void)layoutSubviews { 61 | [super layoutSubviews]; 62 | self.waveLayer.frame = self.bounds; 63 | 64 | } 65 | 66 | // 刷新layer布局 67 | - (void)displayWave:(double)value{ 68 | 69 | double lowPassResults = value; 70 | _waveHeight = CGRectGetHeight(self.bounds); 71 | _waveWidth = CGRectGetWidth(self.bounds); 72 | _waveMid = _waveWidth / 2.0f; 73 | _maxAmplitude = _waveHeight - 4.0f; 74 | _phase += _phaseShift; 75 | _amplitude = fmax(lowPassResults, _idleAmplitude); 76 | 77 | UIGraphicsBeginImageContext(self.frame.size); 78 | for(int i = 0; i < self.waves.count; i++) { 79 | 80 | UIBezierPath *wavelinePath = [UIBezierPath bezierPath]; 81 | CGFloat progress = 1.0f - (CGFloat)i / kNumberOfWaves; 82 | CGFloat normedAmplitude = (1.5f * progress - 0.5f) * _amplitude; 83 | 84 | for(CGFloat x = 0; x < _waveWidth + _density; x += _density) { 85 | 86 | CGFloat scaling = -pow(x / _waveMid - 1, 2) + 1; 87 | CGFloat y = scaling * _maxAmplitude * normedAmplitude * sinf(2 * M_PI *(x / _waveWidth) * _frequency + _phase) + (_waveHeight * 0.5); 88 | 89 | if (x==0) { 90 | [wavelinePath moveToPoint:CGPointMake(x, y)]; 91 | } 92 | else { 93 | [wavelinePath addLineToPoint:CGPointMake(x, y)]; 94 | } 95 | } 96 | 97 | CAShapeLayer *waveline = [self.waves objectAtIndex:i]; 98 | waveline.path = [wavelinePath CGPath]; 99 | } 100 | UIGraphicsEndImageContext(); 101 | } 102 | 103 | - (NSMutableArray *)waves { 104 | if (!_waves) { 105 | _waves = [NSMutableArray arrayWithCapacity:kNumberOfWaves]; 106 | for (int i = 0; i < kNumberOfWaves; ++i) { 107 | CAShapeLayer *waveline = [CAShapeLayer layer]; 108 | waveline.lineCap = kCALineCapButt; 109 | waveline.lineJoin = kCALineJoinRound; 110 | waveline.strokeColor = [[UIColor clearColor] CGColor]; 111 | waveline.fillColor = [[UIColor clearColor] CGColor]; 112 | [waveline setLineWidth:(i==0 ? _mainWaveWidth : _decorativeWavesWidth)]; 113 | CGFloat progress = 1.0f - (CGFloat)i / kNumberOfWaves; 114 | CGFloat multiplier = MIN(1.0, (progress / 3.0f * 2.0f) + (1.0f / 3.0f)); 115 | UIColor *color = [[UIColor greenColor] colorWithAlphaComponent:(i == 0 ? 1.0 : 1.0 * multiplier * 0.6)]; 116 | waveline.strokeColor = color.CGColor; 117 | CAGradientLayer *gradientLayer = [CAGradientLayer layer]; 118 | gradientLayer.frame = CGRectMake(0, 0, self.bounds.size.width, 200); 119 | 120 | //设置颜色 121 | [gradientLayer setColors:[NSArray arrayWithObjects:(id)[[UIColor cyanColor] CGColor],(id)[[UIColor greenColor] CGColor], nil]]; 122 | //每种颜色最亮的位置 123 | [gradientLayer setLocations:@[@0,@1]]; 124 | //渐变的方向StartPoint->EndPoint 125 | [gradientLayer setStartPoint:CGPointMake(0, 0.5)]; 126 | [gradientLayer setEndPoint:CGPointMake(1, 0.5)]; 127 | 128 | gradientLayer.mask = waveline; 129 | [self.waveLayer addSublayer:gradientLayer]; 130 | [_waves addObject:waveline]; 131 | } 132 | } 133 | return _waves; 134 | } 135 | 136 | - (CALayer *)waveLayer { 137 | if (!_waveLayer) { 138 | _waveLayer = [CALayer layer]; 139 | } 140 | return _waveLayer; 141 | } 142 | 143 | @end 144 | -------------------------------------------------------------------------------- /KTSoundWave/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSMicrophoneUsageDescription 6 | Demo 需要在机器人服务中使用您的麦克风权限 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /KTSoundWave/UIView+LayoutMethods.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+LayoutMethods.h 3 | // TmallClient4iOS-Prime 4 | // 5 | // Created by casa on 14/12/8. 6 | // Copyright (c) 2014年 casa. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) 12 | #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) 13 | #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) 14 | #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) 15 | #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending) 16 | 17 | #define SCREEN_WIDTH ([[UIScreen mainScreen]bounds].size.width) 18 | #define SCREEN_HEIGHT ([[UIScreen mainScreen]bounds].size.height) 19 | 20 | #define kHPercentage(a) (SCREEN_HEIGHT*((a)/667.00)) 21 | #define kWPercentage(a) (SCREEN_WIDTH *((a)/375.00)) 22 | 23 | #define SCREEN_WITHOUT_STATUS_HEIGHT (SCREEN_HEIGHT - [[UIApplication sharedApplication] statusBarFrame].size.height) 24 | 25 | typedef CGFloat UIScreenType; 26 | 27 | static UIScreenType UIScreenType_iPhone5 = 320.0f; 28 | static UIScreenType UIScreenType_iPhone6 = 375.0f; 29 | static UIScreenType UIScreenType_iPhone6P = 414.0f; 30 | 31 | @interface UIView (LayoutMethods) 32 | 33 | // coordinator getters 34 | - (CGFloat)ct_height; 35 | - (CGFloat)ct_width; 36 | - (CGFloat)ct_x; 37 | - (CGFloat)ct_y; 38 | - (CGSize)ct_size; 39 | - (CGPoint)ct_origin; 40 | - (CGFloat)ct_centerX; 41 | - (CGFloat)ct_centerY; 42 | 43 | - (CGFloat)ct_left; 44 | - (CGFloat)ct_top; 45 | - (CGFloat)ct_bottom; 46 | - (CGFloat)ct_right; 47 | 48 | - (void)setCt_x:(CGFloat)x; 49 | - (void)setCt_left:(CGFloat)left; 50 | - (void)setCt_y:(CGFloat)y; 51 | - (void)setCt_top:(CGFloat)top; 52 | 53 | // height 54 | - (void)setCt_height:(CGFloat)height; 55 | - (void)heightEqualToView:(UIView *)view; 56 | 57 | // width 58 | - (void)setCt_width:(CGFloat)width; 59 | - (void)widthEqualToView:(UIView *)view; 60 | 61 | // size 62 | - (void)setCt_size:(CGSize)size; 63 | - (void)setSize:(CGSize)size screenType:(UIScreenType)screenType; 64 | - (void)sizeEqualToView:(UIView *)view; 65 | 66 | // center 67 | - (void)setCt_centerX:(CGFloat)centerX; 68 | - (void)setCt_centerY:(CGFloat)centerY; 69 | - (void)centerXEqualToView:(UIView *)view; 70 | - (void)centerYEqualToView:(UIView *)view; 71 | - (void)centerEqualToView:(UIView *)view; 72 | 73 | // top, bottom, left, right -- Version 1.1.0 74 | - (void)fromTheTop:(CGFloat)distance ofView:(UIView *)view; 75 | - (void)fromTheBottom:(CGFloat)distance ofView:(UIView *)view; 76 | - (void)fromTheLeft:(CGFloat)distance ofView:(UIView *)view; 77 | - (void)fromTheRight:(CGFloat)distance ofView:(UIView *)view; 78 | 79 | - (void)fromTheRelativeTop:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType; 80 | - (void)fromTheRelativeBottom:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType; 81 | - (void)fromTheRelativeLeft:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType; 82 | - (void)fromTheRelativeRight:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType; 83 | 84 | - (void)relativeTopInContainer:(CGFloat)top shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 85 | - (void)relativeBottomInContainer:(CGFloat)bottom shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 86 | - (void)relativeLeftInContainer:(CGFloat)left shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 87 | - (void)relativeRightInContainer:(CGFloat)right shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 88 | 89 | // top, bottom, left, right -- Old Version 90 | - (void)top:(CGFloat)top FromView:(UIView *)view; 91 | - (void)bottom:(CGFloat)bottom FromView:(UIView *)view; 92 | - (void)left:(CGFloat)left FromView:(UIView *)view; 93 | - (void)right:(CGFloat)right FromView:(UIView *)view; 94 | 95 | - (void)topRatio:(CGFloat)top FromView:(UIView *)view screenType:(UIScreenType)screenType; 96 | - (void)bottomRatio:(CGFloat)bottom FromView:(UIView *)view screenType:(UIScreenType)screenType; 97 | - (void)leftRatio:(CGFloat)left FromView:(UIView *)view screenType:(UIScreenType)screenType; 98 | - (void)rightRatio:(CGFloat)right FromView:(UIView *)view screenType:(UIScreenType)screenType; 99 | 100 | - (void)topInContainer:(CGFloat)top shouldResize:(BOOL)shouldResize; 101 | - (void)bottomInContainer:(CGFloat)bottom shouldResize:(BOOL)shouldResize; 102 | - (void)leftInContainer:(CGFloat)left shouldResize:(BOOL)shouldResize; 103 | - (void)rightInContainer:(CGFloat)right shouldResize:(BOOL)shouldResize; 104 | 105 | - (void)topRatioInContainer:(CGFloat)top shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 106 | - (void)bottomRatioInContainer:(CGFloat)bottom shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 107 | - (void)leftRatioInContainer:(CGFloat)left shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 108 | - (void)rightRatioInContainer:(CGFloat)right shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType; 109 | 110 | - (void)topEqualToView:(UIView *)view; 111 | - (void)bottomEqualToView:(UIView *)view; 112 | - (void)leftEqualToView:(UIView *)view; 113 | - (void)rightEqualToView:(UIView *)view; 114 | 115 | // imbueset 116 | - (void)fillWidth; 117 | - (void)fillHeight; 118 | - (void)fill; 119 | 120 | - (UIView *)topSuperView; 121 | 122 | // iPhoneX adapt 123 | - (CGFloat)safeAreaBottomGap; 124 | - (CGFloat)safeAreaTopGap; 125 | - (CGFloat)safeAreaLeftGap; 126 | - (CGFloat)safeAreaRightGap; 127 | 128 | @end 129 | -------------------------------------------------------------------------------- /KTSoundWave/UIView+LayoutMethods.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+LayoutMethods.m 3 | // TmallClient4iOS-Prime 4 | // 5 | // Created by casa on 14/12/8. 6 | // Copyright (c) 2014年 casa. All rights reserved. 7 | // 8 | 9 | #import "UIView+LayoutMethods.h" 10 | #import 11 | 12 | static void *kUIViewLayoutMethodPropertyBottomGap = &kUIViewLayoutMethodPropertyBottomGap; 13 | static void *kUIViewLayoutMethodPropertyTopGap = &kUIViewLayoutMethodPropertyTopGap; 14 | static void *kUIViewLayoutMethodPropertyLeftGap = &kUIViewLayoutMethodPropertyLeftGap; 15 | static void *kUIViewLayoutMethodPropertyRightGap = &kUIViewLayoutMethodPropertyRightGap; 16 | 17 | @implementation UIView (LayoutMethods) 18 | 19 | // coordinator getters 20 | - (CGFloat)ct_height 21 | { 22 | return self.frame.size.height; 23 | } 24 | 25 | - (CGFloat)ct_width 26 | { 27 | return self.frame.size.width; 28 | } 29 | 30 | - (CGFloat)ct_x 31 | { 32 | return self.frame.origin.x; 33 | } 34 | 35 | - (CGFloat)ct_y 36 | { 37 | return self.frame.origin.y; 38 | } 39 | 40 | - (CGSize)ct_size 41 | { 42 | return self.frame.size; 43 | } 44 | 45 | - (CGPoint)ct_origin 46 | { 47 | return self.frame.origin; 48 | } 49 | 50 | - (CGFloat)ct_centerX 51 | { 52 | return self.center.x; 53 | } 54 | 55 | - (CGFloat)ct_centerY 56 | { 57 | return self.center.y; 58 | } 59 | 60 | - (CGFloat)ct_left 61 | { 62 | return self.frame.origin.x; 63 | } 64 | 65 | - (CGFloat)ct_top 66 | { 67 | return self.frame.origin.y; 68 | } 69 | 70 | - (CGFloat)ct_bottom 71 | { 72 | return self.frame.size.height + self.frame.origin.y; 73 | } 74 | 75 | - (CGFloat)ct_right 76 | { 77 | return self.frame.size.width + self.frame.origin.x; 78 | } 79 | 80 | - (void)setCt_x:(CGFloat)x 81 | { 82 | self.frame = CGRectMake(x, self.frame.origin.y, self.frame.size.width, self.frame.size.height); 83 | } 84 | 85 | - (void)setCt_y:(CGFloat)y 86 | { 87 | self.frame = CGRectMake(self.frame.origin.x, y, self.frame.size.width, self.frame.size.height); 88 | } 89 | 90 | - (void)setCt_left:(CGFloat)left 91 | { 92 | self.ct_x = left; 93 | } 94 | 95 | - (void)setCt_top:(CGFloat)top 96 | { 97 | self.ct_y = top; 98 | } 99 | 100 | - (void)setCt_height:(CGFloat)height 101 | { 102 | CGRect newFrame = CGRectMake(self.ct_x, self.ct_y, self.ct_width, height); 103 | self.frame = newFrame; 104 | } 105 | 106 | - (void)heightEqualToView:(UIView *)view 107 | { 108 | self.ct_height = view.ct_height; 109 | } 110 | 111 | // width 112 | - (void)setCt_width:(CGFloat)width 113 | { 114 | CGRect newFrame = CGRectMake(self.ct_x, self.ct_y, width, self.ct_height); 115 | self.frame = newFrame; 116 | } 117 | 118 | - (void)widthEqualToView:(UIView *)view 119 | { 120 | self.ct_width = view.ct_width; 121 | } 122 | 123 | // center 124 | - (void)setCt_centerX:(CGFloat)centerX 125 | { 126 | CGPoint center = CGPointMake(self.ct_centerX, self.ct_centerY); 127 | center.x = centerX; 128 | self.center = center; 129 | } 130 | 131 | - (void)setCt_centerY:(CGFloat)centerY 132 | { 133 | CGPoint center = CGPointMake(self.ct_centerX, self.ct_centerY); 134 | center.y = centerY; 135 | self.center = center; 136 | } 137 | 138 | - (void)centerXEqualToView:(UIView *)view 139 | { 140 | UIView *superView = view.superview ? view.superview : view; 141 | CGPoint viewCenterPoint = [superView convertPoint:view.center toView:self.topSuperView]; 142 | CGPoint centerPoint = [self.topSuperView convertPoint:viewCenterPoint toView:self.superview]; 143 | self.ct_centerX = centerPoint.x; 144 | } 145 | 146 | - (void)centerYEqualToView:(UIView *)view 147 | { 148 | UIView *superView = view.superview ? view.superview : view; 149 | CGPoint viewCenterPoint = [superView convertPoint:view.center toView:self.topSuperView]; 150 | CGPoint centerPoint = [self.topSuperView convertPoint:viewCenterPoint toView:self.superview]; 151 | self.ct_centerY = centerPoint.y; 152 | } 153 | 154 | - (void)centerEqualToView:(UIView *)view 155 | { 156 | UIView *superView = view.superview ? view.superview : view; 157 | CGPoint viewCenterPoint = [superView convertPoint:view.center toView:self.topSuperView]; 158 | CGPoint centerPoint = [self.topSuperView convertPoint:viewCenterPoint toView:self.superview]; 159 | self.ct_centerX = centerPoint.x; 160 | self.ct_centerY = centerPoint.y; 161 | } 162 | 163 | // top, bottom, left, right -- Version 1.1.0 164 | - (void)fromTheTop:(CGFloat)distance ofView:(UIView *)view 165 | { 166 | [self bottom:distance FromView:view]; 167 | } 168 | 169 | - (void)fromTheBottom:(CGFloat)distance ofView:(UIView *)view 170 | { 171 | [self top:distance FromView:view]; 172 | } 173 | 174 | - (void)fromTheLeft:(CGFloat)distance ofView:(UIView *)view 175 | { 176 | [self left:distance FromView:view]; 177 | } 178 | 179 | - (void)fromTheRight:(CGFloat)distance ofView:(UIView *)view 180 | { 181 | [self right:distance FromView:view]; 182 | } 183 | 184 | 185 | - (void)fromTheRelativeTop:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType 186 | { 187 | [self bottomRatio:distance FromView:view screenType:screenType]; 188 | } 189 | 190 | - (void)fromTheRelativeBottom:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType 191 | { 192 | [self topRatio:distance FromView:view screenType:screenType]; 193 | } 194 | 195 | - (void)fromTheRelativeLeft:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType 196 | { 197 | [self leftRatio:distance FromView:view screenType:screenType]; 198 | } 199 | 200 | - (void)fromTheRelativeRight:(CGFloat)distance ofView:(UIView *)view screenType:(UIScreenType)screenType 201 | { 202 | [self rightRatio:distance FromView:view screenType:screenType]; 203 | } 204 | 205 | 206 | - (void)relativeTopInContainer:(CGFloat)top shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 207 | { 208 | [self topRatioInContainer:top shouldResize:shouldResize screenType:screenType]; 209 | } 210 | 211 | - (void)relativeBottomInContainer:(CGFloat)bottom shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 212 | { 213 | [self bottomRatioInContainer:bottom shouldResize:shouldResize screenType:screenType]; 214 | } 215 | 216 | - (void)relativeLeftInContainer:(CGFloat)left shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 217 | { 218 | [self leftRatioInContainer:left shouldResize:shouldResize screenType:screenType]; 219 | } 220 | 221 | - (void)relativeRightInContainer:(CGFloat)right shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 222 | { 223 | [self rightRatioInContainer:right shouldResize:shouldResize screenType:screenType]; 224 | } 225 | 226 | 227 | // top, bottom, left, right -- Old Version 228 | - (void)top:(CGFloat)top FromView:(UIView *)view 229 | { 230 | UIView *superView = view.superview ? view.superview : view; 231 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 232 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 233 | 234 | self.ct_y = floorf(newOrigin.y + top + view.ct_height); 235 | } 236 | 237 | - (void)bottom:(CGFloat)bottom FromView:(UIView *)view 238 | { 239 | UIView *superView = view.superview ? view.superview : view; 240 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 241 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 242 | 243 | self.ct_y = newOrigin.y - bottom - self.ct_height; 244 | } 245 | 246 | - (void)left:(CGFloat)left FromView:(UIView *)view 247 | { 248 | UIView *superView = view.superview ? view.superview : view; 249 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 250 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 251 | 252 | self.ct_x = newOrigin.x - left - self.ct_width; 253 | } 254 | 255 | - (void)right:(CGFloat)right FromView:(UIView *)view 256 | { 257 | UIView *superView = view.superview ? view.superview : view; 258 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 259 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 260 | 261 | self.ct_x = newOrigin.x + right + view.ct_width; 262 | } 263 | 264 | - (void)topRatio:(CGFloat)top FromView:(UIView *)view screenType:(UIScreenType)screenType 265 | { 266 | CGFloat topRatio = top / screenType; 267 | CGFloat topValue = topRatio * self.superview.ct_width; 268 | [self top:topValue FromView:view]; 269 | } 270 | 271 | - (void)bottomRatio:(CGFloat)bottom FromView:(UIView *)view screenType:(UIScreenType)screenType 272 | { 273 | CGFloat bottomRatio = bottom / screenType; 274 | CGFloat bottomValue = bottomRatio * self.superview.ct_width; 275 | [self bottom:bottomValue FromView:view]; 276 | } 277 | 278 | - (void)leftRatio:(CGFloat)left FromView:(UIView *)view screenType:(UIScreenType)screenType 279 | { 280 | CGFloat leftRatio = left / screenType; 281 | CGFloat leftValue = leftRatio * self.superview.ct_width; 282 | [self left:leftValue FromView:view]; 283 | } 284 | 285 | - (void)rightRatio:(CGFloat)right FromView:(UIView *)view screenType:(UIScreenType)screenType 286 | { 287 | CGFloat rightRatio = right / screenType; 288 | CGFloat rightValue = rightRatio * self.superview.ct_width; 289 | [self right:rightValue FromView:view]; 290 | } 291 | 292 | - (void)topInContainer:(CGFloat)top shouldResize:(BOOL)shouldResize 293 | { 294 | if (shouldResize) { 295 | self.ct_height = self.ct_y - top + self.ct_height; 296 | } 297 | self.ct_y = top; 298 | } 299 | 300 | - (void)bottomInContainer:(CGFloat)bottom shouldResize:(BOOL)shouldResize 301 | { 302 | if (shouldResize) { 303 | self.ct_height = self.superview.ct_height - bottom - self.ct_y - self.safeAreaBottomGap; 304 | } else { 305 | self.ct_y = self.superview.ct_height - self.ct_height - bottom - self.safeAreaBottomGap; 306 | } 307 | } 308 | 309 | - (void)leftInContainer:(CGFloat)left shouldResize:(BOOL)shouldResize 310 | { 311 | if (shouldResize) { 312 | self.ct_width = self.ct_x - left + self.ct_width; 313 | } 314 | self.ct_x = left; 315 | } 316 | 317 | - (void)rightInContainer:(CGFloat)right shouldResize:(BOOL)shouldResize 318 | { 319 | if (shouldResize) { 320 | self.ct_width = self.superview.ct_width - right - self.ct_x; 321 | } else { 322 | self.ct_x = self.superview.ct_width - self.ct_width - right; 323 | } 324 | } 325 | 326 | - (void)topRatioInContainer:(CGFloat)top shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 327 | { 328 | CGFloat topRatio = top / screenType; 329 | CGFloat topValue = topRatio * self.superview.ct_width; 330 | [self topInContainer:topValue shouldResize:shouldResize]; 331 | } 332 | 333 | - (void)bottomRatioInContainer:(CGFloat)bottom shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 334 | { 335 | CGFloat bottomRatio = bottom / screenType; 336 | CGFloat bottomValue = bottomRatio * self.superview.ct_width; 337 | [self bottomInContainer:bottomValue shouldResize:shouldResize]; 338 | } 339 | 340 | - (void)leftRatioInContainer:(CGFloat)left shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 341 | { 342 | CGFloat leftRatio = left / screenType; 343 | CGFloat leftValue = leftRatio * self.superview.ct_width; 344 | [self leftInContainer:leftValue shouldResize:shouldResize]; 345 | } 346 | 347 | - (void)rightRatioInContainer:(CGFloat)right shouldResize:(BOOL)shouldResize screenType:(UIScreenType)screenType 348 | { 349 | CGFloat rightRatio = right / screenType; 350 | CGFloat rightValue = rightRatio * self.superview.ct_width; 351 | [self rightInContainer:rightValue shouldResize:shouldResize]; 352 | } 353 | 354 | - (void)topEqualToView:(UIView *)view 355 | { 356 | UIView *superView = view.superview ? view.superview : view; 357 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 358 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 359 | 360 | self.ct_y = newOrigin.y; 361 | } 362 | 363 | - (void)bottomEqualToView:(UIView *)view 364 | { 365 | UIView *superView = view.superview ? view.superview : view; 366 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 367 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 368 | 369 | self.ct_y = newOrigin.y + view.ct_height - self.ct_height; 370 | } 371 | 372 | - (void)leftEqualToView:(UIView *)view 373 | { 374 | UIView *superView = view.superview ? view.superview : view; 375 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 376 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 377 | 378 | self.ct_x = newOrigin.x; 379 | } 380 | 381 | - (void)rightEqualToView:(UIView *)view 382 | { 383 | UIView *superView = view.superview ? view.superview : view; 384 | CGPoint viewOrigin = [superView convertPoint:view.ct_origin toView:self.topSuperView]; 385 | CGPoint newOrigin = [self.topSuperView convertPoint:viewOrigin toView:self.superview]; 386 | 387 | self.ct_x = newOrigin.x + view.ct_width - self.ct_width; 388 | } 389 | 390 | // size 391 | - (void)setCt_size:(CGSize)size 392 | { 393 | self.frame = CGRectMake(self.ct_x, self.ct_y, size.width, size.height); 394 | } 395 | 396 | - (void)setSize:(CGSize)size screenType:(UIScreenType)screenType 397 | { 398 | CGFloat ratio = SCREEN_WIDTH / screenType; 399 | self.frame = CGRectMake(self.ct_x, self.ct_y, size.width * ratio, size.height * ratio); 400 | } 401 | 402 | - (void)sizeEqualToView:(UIView *)view 403 | { 404 | self.frame = CGRectMake(self.ct_x, self.ct_y, view.ct_width, view.ct_height); 405 | } 406 | 407 | // imbueset 408 | - (void)fillWidth 409 | { 410 | self.ct_width = self.superview.ct_width; 411 | self.ct_x = 0; 412 | } 413 | 414 | - (void)fillHeight 415 | { 416 | self.ct_height = self.superview.ct_height; 417 | self.ct_y = 0; 418 | } 419 | 420 | - (void)fill 421 | { 422 | self.frame = CGRectMake(0, 0, self.superview.ct_width, self.superview.ct_height); 423 | } 424 | 425 | - (UIView *)topSuperView 426 | { 427 | UIView *topSuperView = self.superview; 428 | 429 | if (topSuperView == nil) { 430 | topSuperView = self; 431 | } else { 432 | while (topSuperView.superview) { 433 | topSuperView = topSuperView.superview; 434 | } 435 | } 436 | 437 | return topSuperView; 438 | } 439 | 440 | // iPhoneX adapt 441 | - (CGFloat)safeAreaBottomGap 442 | { 443 | NSNumber *gap = objc_getAssociatedObject(self, kUIViewLayoutMethodPropertyBottomGap); 444 | if (gap == nil) { 445 | if (@available(iOS 11, *)) { 446 | if (self.superview.safeAreaLayoutGuide.layoutFrame.size.height > 0) { 447 | gap = @((self.superview.ct_height - self.superview.safeAreaLayoutGuide.layoutFrame.origin.y - self.superview.safeAreaLayoutGuide.layoutFrame.size.height)); 448 | } else { 449 | gap = nil; 450 | } 451 | } else { 452 | gap = @(0); 453 | } 454 | objc_setAssociatedObject(self, kUIViewLayoutMethodPropertyBottomGap, gap, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 455 | } 456 | return gap.floatValue; 457 | } 458 | 459 | - (CGFloat)safeAreaTopGap 460 | { 461 | NSNumber *gap = objc_getAssociatedObject(self, kUIViewLayoutMethodPropertyTopGap); 462 | if (gap == nil) { 463 | if (@available(iOS 11, *)) { 464 | gap = @(self.superview.safeAreaLayoutGuide.layoutFrame.origin.y); 465 | } else { 466 | gap = @(0); 467 | } 468 | objc_setAssociatedObject(self, kUIViewLayoutMethodPropertyTopGap, gap, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 469 | } 470 | return gap.floatValue; 471 | } 472 | 473 | - (CGFloat)safeAreaLeftGap 474 | { 475 | NSNumber *gap = objc_getAssociatedObject(self, kUIViewLayoutMethodPropertyLeftGap); 476 | if (gap == nil) { 477 | if (@available(iOS 11, *)) { 478 | gap = @(self.superview.safeAreaLayoutGuide.layoutFrame.origin.x); 479 | } else { 480 | gap = @(0); 481 | } 482 | objc_setAssociatedObject(self, kUIViewLayoutMethodPropertyLeftGap, gap, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 483 | } 484 | return gap.floatValue; 485 | } 486 | 487 | - (CGFloat)safeAreaRightGap 488 | { 489 | NSNumber *gap = objc_getAssociatedObject(self, kUIViewLayoutMethodPropertyRightGap); 490 | if (gap == nil) { 491 | if (@available(iOS 11, *)) { 492 | gap = @(self.superview.safeAreaLayoutGuide.layoutFrame.origin.x); 493 | } else { 494 | gap = @(0); 495 | } 496 | objc_setAssociatedObject(self, kUIViewLayoutMethodPropertyRightGap, gap, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 497 | } 498 | return gap.floatValue; 499 | } 500 | 501 | @end 502 | -------------------------------------------------------------------------------- /KTSoundWave/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // KTSoundWave 4 | // 5 | // Created by keenteam on 2019/1/2. 6 | // Copyright © 2019 keenteam. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /KTSoundWave/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // DDSoundWave 4 | // 5 | // Created by Teaker on 2018/4/6. 6 | // Copyright © 2018年 Liuzhida. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "DDSoundWaveView.h" 11 | #import "UIView+LayoutMethods.h" 12 | #import "AudioRecorder.h" 13 | @interface ViewController () 14 | @property (nonatomic, strong) DDSoundWaveView *waveView; 15 | @end 16 | 17 | @implementation ViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | self.view.backgroundColor = [UIColor whiteColor]; 22 | [self.view addSubview:self.waveView]; 23 | //录音开始 24 | [[AudioRecorder shareInstance] startRecordWithFilePath:[self getFilePathWithFileName:@"DemoOneRecord.wav"]]; 25 | [[AudioRecorder shareInstance] setRecorderDelegate:self]; 26 | 27 | } 28 | 29 | - (void)viewWillLayoutSubviews { 30 | [super viewWillLayoutSubviews]; 31 | [self.waveView setCt_size:CGSizeMake(SCREEN_WIDTH, 200)]; 32 | [self.waveView centerXEqualToView:self.view]; 33 | [self.waveView setCt_y:SCREEN_HEIGHT-self.view.safeAreaBottomGap - SCREEN_HEIGHT/2]; 34 | } 35 | 36 | #pragma mark - AudioRecorderDelegate 37 | //音量 38 | - (void)audioRecorderDidVoiceChanged:(AudioRecorder *)recorder value:(double)value{ 39 | 40 | [self.waveView displayWave:value]; 41 | 42 | } 43 | 44 | - (void)didReceiveMemoryWarning { 45 | [super didReceiveMemoryWarning]; 46 | } 47 | 48 | - (DDSoundWaveView *)waveView { 49 | if (!_waveView) { 50 | _waveView = [[DDSoundWaveView alloc] init]; 51 | } 52 | return _waveView; 53 | } 54 | 55 | #pragma mark ----------------- path ---------------- 56 | - (NSString *)getFilePathWithFileName:(NSString *)fileName{ 57 | NSString * filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES ) lastObject]; 58 | filePath = [filePath stringByAppendingPathComponent:fileName]; 59 | return filePath; 60 | } 61 | @end 62 | -------------------------------------------------------------------------------- /KTSoundWave/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // KTSoundWave 4 | // 5 | // Created by keenteam on 2019/1/2. 6 | // Copyright © 2019 keenteam. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /KTSoundWaveTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /KTSoundWaveTests/KTSoundWaveTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // KTSoundWaveTests.m 3 | // KTSoundWaveTests 4 | // 5 | // Created by keenteam on 2019/1/2. 6 | // Copyright © 2019 keenteam. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface KTSoundWaveTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation KTSoundWaveTests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | } 20 | 21 | - (void)tearDown { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | - (void)testExample { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | } 29 | 30 | - (void)testPerformanceExample { 31 | // This is an example of a performance test case. 32 | [self measureBlock:^{ 33 | // Put the code you want to measure the time of here. 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /KTSoundWaveUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /KTSoundWaveUITests/KTSoundWaveUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // KTSoundWaveUITests.m 3 | // KTSoundWaveUITests 4 | // 5 | // Created by keenteam on 2019/1/2. 6 | // Copyright © 2019 keenteam. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface KTSoundWaveUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation KTSoundWaveUITests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | 20 | // In UI tests it is usually best to stop immediately when a failure occurs. 21 | self.continueAfterFailure = NO; 22 | 23 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 24 | [[[XCUIApplication alloc] init] launch]; 25 | 26 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 27 | } 28 | 29 | - (void)tearDown { 30 | // Put teardown code here. This method is called after the invocation of each test method in the class. 31 | } 32 | 33 | - (void)testExample { 34 | // Use recording to get started writing UI tests. 35 | // Use XCTAssert and related functions to verify your tests produce the correct results. 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KTAudioSoundWave 2 | 3 | KTAudioSoundWave-根据语音音贝绘制波浪动画 4 | 5 | # 效果图 6 | 7 | ![](https://github.com/liuzhida33/DDSoundWave/blob/master/images/soundwave.gif) 8 | ``` 9 | [self.waveView setCt_size:CGSizeMake(SCREEN_WIDTH, 200)]; 10 | [self.waveView centerXEqualToView:self.view]; 11 | [self.waveView setCt_y:SCREEN_HEIGHT-self.view.safeAreaBottomGap - SCREEN_HEIGHT/2]; 12 | 13 | - (DDSoundWaveView *)waveView { 14 | if (!_waveView) { 15 | _waveView = [[DDSoundWaveView alloc] init]; 16 | } 17 | return _waveView; 18 | } 19 | ``` 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 22 | 23 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 | 27 | # License star ⭐️🇨🇳⭐️🇨🇳新手项目,多多包涵,谢谢!!有相关问题可以在线留言或发邮件至Keen_Team@163.com,谢谢! 28 | 29 | The MIT License (MIT) Copyright (c) 2014 KEENTEAM 30 | --------------------------------------------------------------------------------