├── Example ├── Soundrecognizer │ ├── .gitmodules │ ├── SoundRecognizer │ │ ├── Resources │ │ │ ├── Assets.xcassets │ │ │ │ ├── Contents.json │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ ├── SoundRecognition.mlmodel │ │ │ ├── Base.lproj │ │ │ │ └── LaunchScreen.storyboard │ │ │ └── Info.plist │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ ├── SoundRecognizer.entitlements │ │ └── Source │ │ │ ├── Engine │ │ │ ├── MicrophoneReader │ │ │ │ ├── MicrophoneReader.swift │ │ │ │ ├── AudioRecordingManager.swift │ │ │ │ ├── AudioRecorder.swift │ │ │ │ └── AudioSampler.swift │ │ │ ├── CategoryRepository.swift │ │ │ └── SoundRecognizerEngine.swift │ │ │ ├── Screens │ │ │ └── Main │ │ │ │ ├── SaveDocumentPicker.swift │ │ │ │ ├── MainView.swift │ │ │ │ └── MainViewModel.swift │ │ │ ├── AppDelegate.swift │ │ │ └── SceneDelegate.swift │ ├── SoundRecognizerTests │ │ ├── 1-137-A-32.wav │ │ ├── 1-47250-A-41.wav │ │ ├── 1-48298-A-46.wav │ │ ├── 1-84393-A-32.wav │ │ ├── 4-150364-A-46.wav │ │ ├── Info.plist │ │ └── SoundRecognizerTests.swift │ ├── SoundRecognizer.xcodeproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ ├── xcuserdata │ │ │ └── dhrebeniuk.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── .gitignore │ ├── SoundRecognizer.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── Podfile │ └── Podfile.lock ├── RosaKitExample │ ├── RosaKitExample │ │ ├── test.wav │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── RosaKitExample.entitlements │ │ ├── RenderingEngine │ │ │ ├── CommonUtils.h │ │ │ ├── CommonUtils.metal │ │ │ ├── MTLTextureExtensions.swift │ │ │ ├── Shaders.metal │ │ │ ├── SamplesRenderer.swift │ │ │ └── MTLDeviceExtensions.swift │ │ ├── ViewController.swift │ │ ├── AppDelegate.swift │ │ ├── Info.plist │ │ └── Spectrogram │ │ │ ├── SpectrogramViewController.swift │ │ │ └── SpectrogramView.swift │ ├── Podfile │ ├── RosaKitExample.xcodeproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── project.pbxproj │ ├── RosaKitExample.xcworkspace │ │ └── contents.xcworkspacedata │ └── Podfile.lock └── NoiseReductionExample │ ├── NoiseReductionExample │ ├── Assets.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── test.wav │ ├── SoundNoiseReduction.mlmodel │ ├── NoiseReductionExample.entitlements │ ├── RenderingEngine │ │ ├── CommonUtils.h │ │ ├── CommonUtils.metal │ │ ├── MTLTextureExtensions.swift │ │ ├── Shaders.metal │ │ ├── SamplesRenderer.swift │ │ └── MTLDeviceExtensions.swift │ ├── AppDelegate.swift │ ├── Info.plist │ ├── Spectrogram │ │ ├── SpectrogramViewController.swift │ │ └── SpectrogramView.swift │ └── MainViewController.swift │ ├── NoiseReductionExample.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── project.pbxproj │ ├── Podfile │ ├── NoiseReductionExample.xcworkspace │ └── contents.xcworkspacedata │ └── Podfile.lock ├── SoundExample.png ├── RosaKit.xcodeproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── .gitignore ├── RosaKitiOS ├── RosaKit.h └── Info.plist ├── RosaKitMacOS ├── RosaKit.h └── Info.plist ├── Package.swift ├── LICENSE ├── Sources ├── Rosa │ ├── RosaFloatingPointExtensions.swift │ ├── WavFileManager.swift │ └── ArrayLibRosaExtensions.swift ├── NumKit │ ├── DataExtensions.swift │ ├── FloatingPointExtensions.swift │ ├── ArrayExtensions.swift │ └── ArrayMatrixExtensions.swift └── SciKit │ └── ArrayDoubleExtensions.swift ├── RosaKit.podspec └── README.md /Example/Soundrecognizer/.gitmodules: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SoundExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhrebeniuk/RosaKit/HEAD/SoundExample.png -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/test.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhrebeniuk/RosaKit/HEAD/Example/RosaKitExample/RosaKitExample/test.wav -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizerTests/1-137-A-32.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhrebeniuk/RosaKit/HEAD/Example/Soundrecognizer/SoundRecognizerTests/1-137-A-32.wav -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/test.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhrebeniuk/RosaKit/HEAD/Example/NoiseReductionExample/NoiseReductionExample/test.wav -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizerTests/1-47250-A-41.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhrebeniuk/RosaKit/HEAD/Example/Soundrecognizer/SoundRecognizerTests/1-47250-A-41.wav -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizerTests/1-48298-A-46.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhrebeniuk/RosaKit/HEAD/Example/Soundrecognizer/SoundRecognizerTests/1-48298-A-46.wav -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizerTests/1-84393-A-32.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhrebeniuk/RosaKit/HEAD/Example/Soundrecognizer/SoundRecognizerTests/1-84393-A-32.wav -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizerTests/4-150364-A-46.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhrebeniuk/RosaKit/HEAD/Example/Soundrecognizer/SoundRecognizerTests/4-150364-A-46.wav -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Resources/SoundRecognition.mlmodel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhrebeniuk/RosaKit/HEAD/Example/Soundrecognizer/SoundRecognizer/Resources/SoundRecognition.mlmodel -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/SoundNoiseReduction.mlmodel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhrebeniuk/RosaKit/HEAD/Example/NoiseReductionExample/NoiseReductionExample/SoundNoiseReduction.mlmodel -------------------------------------------------------------------------------- /RosaKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/RosaKitExample/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | 3 | target "RosaKitExample" do 4 | platform :osx, '10.13' 5 | use_frameworks! 6 | inhibit_all_warnings! 7 | 8 | pod 'RosaKit', :path => '../../' 9 | end 10 | 11 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer.xcodeproj/project.xcworkspace/xcuserdata/dhrebeniuk.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhrebeniuk/RosaKit/HEAD/Example/Soundrecognizer/SoundRecognizer.xcodeproj/project.xcworkspace/xcuserdata/dhrebeniuk.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Example/NoiseReductionExample/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | 3 | target "NoiseReductionExample" do 4 | platform :osx, '10.13' 5 | use_frameworks! 6 | inhibit_all_warnings! 7 | 8 | pod 'RosaKit', :path => '../../' 9 | pod 'PlainPocketFFT', :path => '../../../plain-pocketfft' 10 | end 11 | 12 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/.gitignore: -------------------------------------------------------------------------------- 1 | # Add any directories, files, or patterns you don't want to be tracked by version control 2 | *.xcodeproj/project.xcworkspace/xcuserdata/* 3 | *.xcodeproj/xcuserdata/* 4 | *.xcworkspace/xcuserdata/* 5 | *.xcuserdatad 6 | *.xcscmblueprint 7 | 8 | build/* 9 | Pods/* 10 | fastlane 11 | IDEWorkspaceChecks.plist 12 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/RosaKitExample.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/NoiseReductionExample.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/RenderingEngine/CommonUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // CommonUtils.h 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 2/18/18. 6 | // Copyright © 2018 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | #ifndef CommonUtils_h 10 | #define CommonUtils_h 11 | 12 | using namespace metal; 13 | 14 | float3 hsv2rgb(float3 c); 15 | 16 | float3 rgb2hsv(float3 c); 17 | 18 | #endif /* CommonUtils_h */ 19 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/RenderingEngine/CommonUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // CommonUtils.h 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 2/18/18. 6 | // Copyright © 2018 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | #ifndef CommonUtils_h 10 | #define CommonUtils_h 11 | 12 | using namespace metal; 13 | 14 | float3 hsv2rgb(float3 c); 15 | 16 | float3 rgb2hsv(float3 c); 17 | 18 | #endif /* CommonUtils_h */ 19 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | 3 | target "SoundRecognizer" do 4 | platform :ios, '13.0' 5 | use_frameworks! 6 | inhibit_all_warnings! 7 | 8 | pod 'RosaKit', :path => '../../' 9 | pod 'ZIPFoundation' 10 | 11 | end 12 | 13 | target "SoundRecognizerTests" do 14 | platform :ios, '13.0' 15 | use_frameworks! 16 | inhibit_all_warnings! 17 | 18 | pod 'RosaKit', :path => '../../' 19 | 20 | end 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Add any directories, files, or patterns you don't want to be tracked by version control 2 | *.xcodeproj/project.xcworkspace/xcuserdata/* 3 | *.xcodeproj/xcuserdata/* 4 | *.xcworkspace/xcuserdata/* 5 | *.xcuserdatad 6 | *.xcscmblueprint 7 | 8 | Example/RosaKitExample/Pods/* 9 | IDEWorkspaceChecks.plist 10 | Example/*/Pods 11 | Podfile.lock 12 | Example/.DS_Store 13 | .DS_Store 14 | xcuserdata/* 15 | *.xcbkptlist 16 | Example/Soundrecognizer/SoundRecognizer.xcworkspace/xcuserdata/ 17 | *xcschememanagement.plist 18 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/SoundRecognizer.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.device.audio-input 8 | 9 | com.apple.security.files.user-selected.read-write 10 | 11 | com.apple.security.network.client 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /RosaKitiOS/RosaKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // RosaKitiOS.h 3 | // RosaKitiOS 4 | // 5 | // Created by Hrebeniuk Dmytro on 04.01.2020. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for RosaKitiOS. 11 | FOUNDATION_EXPORT double RosaKitiOSVersionNumber; 12 | 13 | //! Project version string for RosaKitiOS. 14 | FOUNDATION_EXPORT const unsigned char RosaKitiOSVersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | 19 | #import 20 | -------------------------------------------------------------------------------- /RosaKitMacOS/RosaKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // RosaKitMacOS.h 3 | // RosaKitMacOS 4 | // 5 | // Created by Hrebeniuk Dmytro on 04.01.2020. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for RosaKitMacOS. 11 | FOUNDATION_EXPORT double RosaKitMacOSVersionNumber; 12 | 13 | //! Project version string for RosaKitMacOS. 14 | FOUNDATION_EXPORT const unsigned char RosaKitMacOSVersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | #import 19 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // RosaKitExample 4 | // 5 | // Created by Hrebeniuk Dmytro on 09.06.2020. 6 | // Copyright © 2020 Hrebeniuk Dmytro. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class ViewController: NSViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override var representedObject: Any? { 20 | didSet { 21 | // Update the view, if already loaded. 22 | } 23 | } 24 | 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // RosaKitExample 4 | // 5 | // Created by Hrebeniuk Dmytro on 09.06.2020. 6 | // Copyright © 2020 Hrebeniuk Dmytro. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | func applicationDidFinishLaunching(_ aNotification: Notification) { 16 | // Insert code here to initialize your application 17 | } 18 | 19 | func applicationWillTerminate(_ aNotification: Notification) { 20 | // Insert code here to tear down your application 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // RosaKitExample 4 | // 5 | // Created by Hrebeniuk Dmytro on 09.06.2020. 6 | // Copyright © 2020 Hrebeniuk Dmytro. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | func applicationDidFinishLaunching(_ aNotification: Notification) { 16 | // Insert code here to initialize your application 17 | } 18 | 19 | func applicationWillTerminate(_ aNotification: Notification) { 20 | // Insert code here to tear down your application 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Example/RosaKitExample/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - PlainPocketFFT (0.0.9) 3 | - PocketFFT (0.0.1) 4 | - RosaKit (0.0.6): 5 | - PlainPocketFFT (~> 0.0.9) 6 | - PocketFFT (~> 0.0.1) 7 | 8 | DEPENDENCIES: 9 | - RosaKit (from `../../`) 10 | 11 | SPEC REPOS: 12 | https://github.com/CocoaPods/Specs.git: 13 | - PlainPocketFFT 14 | - PocketFFT 15 | 16 | EXTERNAL SOURCES: 17 | RosaKit: 18 | :path: "../../" 19 | 20 | SPEC CHECKSUMS: 21 | PlainPocketFFT: 3763f37fba0737e457ed1a3b9b7bfa70c00ff213 22 | PocketFFT: cdbe7ef5b7cd08520655d85d03d701b5ba35fdec 23 | RosaKit: 02cda721ff10053041e17269d23020247269c9e8 24 | 25 | PODFILE CHECKSUM: 5a26e4d412be76e11d075c662b00c33386142ac1 26 | 27 | COCOAPODS: 1.11.2 28 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | 3 | import PackageDescription 4 | 5 | let package = Package(name: "RosaKit", 6 | platforms: [.iOS(.v9)], 7 | products: [.library(name: "RosaKit", 8 | targets: ["RosaKit"])], 9 | dependencies: [ 10 | .package(url: "https://github.com/dhrebeniuk/plain-pocketfft.git", from: "0.0.9"), 11 | .package(url: "https://github.com/dhrebeniuk/pocketfft.git", from: "0.0.1"), 12 | ], targets: [.target(name: "RosaKit", dependencies: ["PlainPocketFFT", "PocketFFT"], 13 | path: "Sources")], 14 | swiftLanguageVersions: [.v5]) 15 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - PlainPocketFFT (0.0.9) 3 | - PocketFFT (0.0.1) 4 | - RosaKit (0.0.8): 5 | - PlainPocketFFT (~> 0.0.9) 6 | - PocketFFT (~> 0.0.1) 7 | 8 | DEPENDENCIES: 9 | - PlainPocketFFT (from `../../../plain-pocketfft`) 10 | - RosaKit (from `../../`) 11 | 12 | SPEC REPOS: 13 | https://github.com/CocoaPods/Specs.git: 14 | - PocketFFT 15 | 16 | EXTERNAL SOURCES: 17 | PlainPocketFFT: 18 | :path: "../../../plain-pocketfft" 19 | RosaKit: 20 | :path: "../../" 21 | 22 | SPEC CHECKSUMS: 23 | PlainPocketFFT: 3763f37fba0737e457ed1a3b9b7bfa70c00ff213 24 | PocketFFT: cdbe7ef5b7cd08520655d85d03d701b5ba35fdec 25 | RosaKit: a268816d50169a302d1dab0df651a5ac0ac506c9 26 | 27 | PODFILE CHECKSUM: 58b547f55cd3fe1e92c99ecd7a7574d07ba583fd 28 | 29 | COCOAPODS: 1.11.3 30 | -------------------------------------------------------------------------------- /RosaKitMacOS/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /RosaKitiOS/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizerTests/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - PlainPocketFFT (0.0.9) 3 | - PocketFFT (0.0.1) 4 | - RosaKit (0.0.8): 5 | - PlainPocketFFT (~> 0.0.9) 6 | - PocketFFT (~> 0.0.1) 7 | - ZIPFoundation (0.9.13) 8 | 9 | DEPENDENCIES: 10 | - RosaKit (from `../../`) 11 | - ZIPFoundation 12 | 13 | SPEC REPOS: 14 | https://github.com/CocoaPods/Specs.git: 15 | - PlainPocketFFT 16 | - PocketFFT 17 | - ZIPFoundation 18 | 19 | EXTERNAL SOURCES: 20 | RosaKit: 21 | :path: "../../" 22 | 23 | SPEC CHECKSUMS: 24 | PlainPocketFFT: 3763f37fba0737e457ed1a3b9b7bfa70c00ff213 25 | PocketFFT: cdbe7ef5b7cd08520655d85d03d701b5ba35fdec 26 | RosaKit: a268816d50169a302d1dab0df651a5ac0ac506c9 27 | ZIPFoundation: ae5b4b813d216d3bf0a148773267fff14bd51d37 28 | 29 | PODFILE CHECKSUM: ff4c09aef33bea7c651d82102e3d8ba84dcd908d 30 | 31 | COCOAPODS: 1.11.3 32 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/RenderingEngine/CommonUtils.metal: -------------------------------------------------------------------------------- 1 | // 2 | // CommonUtils.metal 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 2/18/18. 6 | // Copyright © 2018 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | #include 10 | using namespace metal; 11 | 12 | float3 hsv2rgb(float3 c) { 13 | float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 14 | float3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); 15 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 16 | } 17 | 18 | float3 rgb2hsv(float3 c) 19 | { 20 | float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 21 | float4 p = mix(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g)); 22 | float4 q = mix(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r)); 23 | 24 | float d = q.x - min(q.w, q.y); 25 | float e = 1.0e-10; 26 | return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); 27 | } 28 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/RenderingEngine/CommonUtils.metal: -------------------------------------------------------------------------------- 1 | // 2 | // CommonUtils.metal 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 2/18/18. 6 | // Copyright © 2018 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | #include 10 | using namespace metal; 11 | 12 | float3 hsv2rgb(float3 c) { 13 | float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 14 | float3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); 15 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 16 | } 17 | 18 | float3 rgb2hsv(float3 c) 19 | { 20 | float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 21 | float4 p = mix(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g)); 22 | float4 q = mix(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r)); 23 | 24 | float d = q.x - min(q.w, q.y); 25 | float e = 1.0e-10; 26 | return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 dhrebeniuk 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 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Source/Engine/MicrophoneReader/MicrophoneReader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VolumeRecognizer.swift 3 | // dbMeter 4 | // 5 | // Created by Dmytro Hrebeniuk on 2/10/17. 6 | // Copyright © 2017 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import AVFoundation 10 | 11 | public typealias MicrophoneReaderHandler = (_ audioPowerBuffer: [Double]) -> Void 12 | 13 | class MicrophoneReader { 14 | 15 | private static let kIntToDoubleScale: Double = 32768.0 16 | 17 | private(set) var audioRecordingManager: AudioRecordingManager = AudioRecordingManager() 18 | 19 | func startReading(handler: @escaping MicrophoneReaderHandler) { 20 | let audioRecordingManager = AudioRecordingManager() 21 | self.audioRecordingManager = audioRecordingManager 22 | 23 | try? audioRecordingManager.setup() { (data, timestamp, timeScale, samplesCount, sampleRate) in 24 | 25 | let powers = data.withUnsafeBytes { rawPointer -> [Double] in 26 | rawPointer.bindMemory(to: Int16.self) 27 | .map { Double($0)/Self.kIntToDoubleScale } 28 | } 29 | handler(powers) 30 | } 31 | 32 | audioRecordingManager.startRecording() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/Rosa/RosaFloatingPointExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RosaFloatingPointExtensions.swift 3 | // RosaKitMacOS 4 | // 5 | // Created by Hrebeniuk Dmytro on 10.01.2020. 6 | // 7 | 8 | import Foundation 9 | import CoreGraphics 10 | 11 | extension FloatingPoint { 12 | 13 | func powerToDB() -> T { 14 | switch self { 15 | case let self as Double: 16 | return Double(10.0) * log10(self) as? T ?? 0 17 | case let self as CGFloat: 18 | return Float(10.0) * log10f(Float(self)) as? T ?? 0 19 | case let self as Float: 20 | return Float(10.0) * log10f(self) as? T ?? 0 21 | default: 22 | return 0 as T 23 | } 24 | } 25 | 26 | func dbToPower() -> T { 27 | switch self { 28 | case let self as Double: 29 | return pow(Double(10.0), self/Double(10.0)) as? T ?? 0 30 | case let self as CGFloat: 31 | return powf(Float(10.0), Float(self)/Float(10.0)) as? T ?? 0 32 | case let self as Float: 33 | return powf(Float(10.0), self/Float(10.0)) as? T ?? 0 34 | default: 35 | return 0 as T 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "scale" : "1x", 6 | "size" : "16x16" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "1x", 16 | "size" : "32x32" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "2x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "1x", 26 | "size" : "128x128" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "2x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "1x", 36 | "size" : "256x256" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "2x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "1x", 46 | "size" : "512x512" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "2x", 51 | "size" : "512x512" 52 | } 53 | ], 54 | "info" : { 55 | "author" : "xcode", 56 | "version" : 1 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "scale" : "1x", 6 | "size" : "16x16" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "scale" : "2x", 11 | "size" : "16x16" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "scale" : "1x", 16 | "size" : "32x32" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "scale" : "2x", 21 | "size" : "32x32" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "scale" : "1x", 26 | "size" : "128x128" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "scale" : "2x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "scale" : "1x", 36 | "size" : "256x256" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "scale" : "2x", 41 | "size" : "256x256" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "scale" : "1x", 46 | "size" : "512x512" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "scale" : "2x", 51 | "size" : "512x512" 52 | } 53 | ], 54 | "info" : { 55 | "author" : "xcode", 56 | "version" : 1 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /RosaKit.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint SegueWithCompletion.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | s.name = "RosaKit" 12 | s.version = "0.0.11" 13 | s.summary = "RosaKit it's lightweight port to iOS libRosa" 14 | s.description = "RosaKit it's lightweight port to iOS libRosa which written on Python, it's used for sound analyse" 15 | 16 | s.homepage = "https://github.com/dhrebeniuk/RosaKit" 17 | 18 | s.license = "LICENSE" 19 | s.author = { "Dmytro Hrebeniuk" => "dmytrohrebeniuk@gmail.com" } 20 | 21 | s.ios.deployment_target = "11.0" 22 | s.osx.deployment_target = "11.0" 23 | s.tvos.deployment_target = "11.0" 24 | 25 | s.source = { :git => "https://github.com/dhrebeniuk/RosaKit.git", :tag => "#{s.version}" } 26 | s.source_files = "Sources/**/*.{swift,h}" 27 | 28 | s.dependency 'PlainPocketFFT', '~> 0.0.9' 29 | s.dependency 'PocketFFT', '~> 0.0.1' 30 | 31 | s.requires_arc = true 32 | s.swift_versions = "5.1" 33 | 34 | end 35 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2020 Hrebeniuk Dmytro. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | NSSupportsAutomaticTermination 32 | 33 | NSSupportsSuddenTermination 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2020 Hrebeniuk Dmytro. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | NSSupportsAutomaticTermination 32 | 33 | NSSupportsSuddenTermination 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Source/Screens/Main/SaveDocumentPicker.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SaveDocumentPicker.swift 3 | // SoundRecognizer 4 | // 5 | // Created by Hrebeniuk Dmytro on 20.07.2022. 6 | // Copyright © 2022 Hrebeniuk Dmytro. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import SwiftUI 12 | 13 | struct SaveDocumentPicker: UIViewControllerRepresentable { 14 | 15 | @Binding var url: URL 16 | 17 | func makeCoordinator() -> DocumentPickerCoordinator { 18 | return DocumentPickerCoordinator(url: $url) 19 | } 20 | 21 | func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIDocumentPickerViewController { 22 | let controller = UIDocumentPickerViewController(forExporting: [url]) 23 | controller.delegate = context.coordinator 24 | return controller 25 | } 26 | 27 | func updateUIViewController(_ uiviewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext) { 28 | } 29 | 30 | } 31 | 32 | class DocumentPickerCoordinator: NSObject, UIDocumentPickerDelegate, UINavigationControllerDelegate { 33 | 34 | @Binding var url: URL 35 | 36 | init(url: Binding) { 37 | _url = url 38 | } 39 | 40 | func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { 41 | 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ban Russia from SWIFT! Protect Ukrainian Sky! Send NATO to Ukraine! #BanRussiafromSwift #CloseTheSky #SendNatoToUkraine 2 | 3 | # RosaKit 4 | 5 | RosaKit - LibRosa port to Swift for iOS and macOS platforms. 6 | 7 | Library can generate Mel-spectrogram using Short-time Fourier transform (STFT) algorithm. 8 | 9 | It's provide methods for calcualte Short-time Fourier transform window and Spectrogram. 10 | 11 | ## Installation 12 | Via [CocoaPods](http://cocoapods.org): 13 | ```ruby 14 | pod 'RosaKit' 15 | 16 | ``` 17 | 18 | # Goals 19 | 20 | * Generate Spectrogram for visualisations 21 | 22 | * Preprocessing steps for most Machine Learning models in Sound Recognition Sphere 23 | 24 | 25 | # Original Project: 26 | 27 | https://librosa.github.io 28 | 29 | ## melspectrogram: 30 | https://librosa.github.io/librosa/generated/librosa.feature.melspectrogram.html 31 | 32 | ## Usage in swift 33 | 34 | You can use such code: 35 | 36 | ```swift 37 | 38 | let rawAudioData = Data(...) 39 | 40 | let chunkSize = 66000 41 | let chunkOfSamples = Array(rawAudioData[0.. Bool { 16 | // Override point for customization after application launch. 17 | 18 | return true 19 | } 20 | 21 | // MARK: UISceneSession Lifecycle 22 | 23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 24 | // Called when a new scene session is being created. 25 | // Use this method to select a configuration to create the new scene with. 26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 27 | } 28 | 29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 30 | // Called when the user discards a scene session. 31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 33 | } 34 | 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/RenderingEngine/MTLTextureExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTLTextureExtensions.swift 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 1/25/18. 6 | // Copyright © 2018 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Metal 11 | import CoreGraphics 12 | 13 | private let kColorComponetnsCount = 4 14 | 15 | extension MTLTexture { 16 | 17 | func toCGImage() -> CGImage? { 18 | let width = self.width 19 | let height = self.height 20 | let rowBytesCount = self.width * kColorComponetnsCount 21 | let rawPointer = malloc(width * height * kColorComponetnsCount) 22 | 23 | guard let pointer = rawPointer else { 24 | return nil 25 | } 26 | 27 | self.getBytes(pointer, bytesPerRow: rowBytesCount, from: MTLRegionMake2D(0, 0, width, height), mipmapLevel: 0) 28 | 29 | let selftureSize = self.width * self.height * kColorComponetnsCount 30 | 31 | guard let provider = CGDataProvider(dataInfo: nil, data: pointer, size: selftureSize, releaseData: { (_, data, size) in 32 | data.deallocate() 33 | }) else { 34 | return nil 35 | } 36 | 37 | let rawBitmapInfo = CGImageAlphaInfo.noneSkipFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue 38 | let bitmapInfo = CGBitmapInfo(rawValue: rawBitmapInfo) 39 | let pColorSpace = CGColorSpaceCreateDeviceRGB() 40 | 41 | let cgImage = CGImage(width: self.width, height: self.height, bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: rowBytesCount, space: pColorSpace, bitmapInfo: bitmapInfo, provider: provider, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent) 42 | 43 | return cgImage 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/RenderingEngine/MTLTextureExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTLTextureExtensions.swift 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 1/25/18. 6 | // Copyright © 2018 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Metal 11 | import CoreGraphics 12 | 13 | private let kColorComponetnsCount = 4 14 | 15 | extension MTLTexture { 16 | 17 | func toCGImage() -> CGImage? { 18 | let width = self.width 19 | let height = self.height 20 | let rowBytesCount = self.width * kColorComponetnsCount 21 | let rawPointer = malloc(width * height * kColorComponetnsCount) 22 | 23 | guard let pointer = rawPointer else { 24 | return nil 25 | } 26 | 27 | self.getBytes(pointer, bytesPerRow: rowBytesCount, from: MTLRegionMake2D(0, 0, width, height), mipmapLevel: 0) 28 | 29 | let selftureSize = self.width * self.height * kColorComponetnsCount 30 | 31 | guard let provider = CGDataProvider(dataInfo: nil, data: pointer, size: selftureSize, releaseData: { (_, data, size) in 32 | data.deallocate() 33 | }) else { 34 | return nil 35 | } 36 | 37 | let rawBitmapInfo = CGImageAlphaInfo.noneSkipFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue 38 | let bitmapInfo = CGBitmapInfo(rawValue: rawBitmapInfo) 39 | let pColorSpace = CGColorSpaceCreateDeviceRGB() 40 | 41 | let cgImage = CGImage(width: self.width, height: self.height, bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: rowBytesCount, space: pColorSpace, bitmapInfo: bitmapInfo, provider: provider, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent) 42 | 43 | return cgImage 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Source/Engine/MicrophoneReader/AudioRecordingManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AudioRecordingManager.swift 3 | // dbMeter 4 | // 5 | // Created by Dmytro Hrebeniuk on 2/10/17. 6 | // Copyright © 2017 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import AVFoundation 10 | 11 | open class AudioRecordingManager { 12 | 13 | private let session: AVCaptureSession 14 | private let audioRecorder: AudioRecorder 15 | private let audioSampler: AudioSampler 16 | 17 | public convenience init() { 18 | self.init(AVCaptureSession()) 19 | } 20 | 21 | public init(_ captureSession: AVCaptureSession) { 22 | self.session = captureSession 23 | 24 | self.audioRecorder = AudioRecorder(captureSession) 25 | self.audioSampler = AudioSampler(captureSession) 26 | } 27 | 28 | // MARK: Public 29 | 30 | open func setup(audioHandler: @escaping AudioSamplerHandler) throws { 31 | let isRecordingRunning = self.session.isRunning 32 | 33 | if isRecordingRunning { 34 | self.stopRecording() 35 | } 36 | 37 | try self.audioRecorder.setupRecordingSession() 38 | 39 | self.audioSampler.audioSamplerOutputHandler = audioHandler 40 | self.audioSampler.setupOutput() 41 | 42 | if isRecordingRunning { 43 | self.startRecording() 44 | } 45 | } 46 | 47 | open func setup(audioDeviceNameHandler: @escaping AudioRecorderDeviceNameHandler) { 48 | self.audioRecorder.audioRecorderDeviceNameHandler = audioDeviceNameHandler 49 | } 50 | 51 | open func startRecording() { 52 | if !self.session.isRunning { 53 | self.session.startRunning() 54 | } 55 | } 56 | 57 | open func stopRecording() { 58 | if self.session.isRunning { 59 | self.session.stopRunning() 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/RenderingEngine/Shaders.metal: -------------------------------------------------------------------------------- 1 | // 2 | // Shaders.metal 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 12/6/17. 6 | // Copyright © 2017 dmytro. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "CommonUtils.h" 11 | using namespace metal; 12 | 13 | typedef struct { 14 | float4 renderedCoordinate [[position]]; 15 | float2 textureCoordinate; 16 | } TextureMappingVertex; 17 | 18 | vertex TextureMappingVertex mapTexture(unsigned int vertex_id [[ vertex_id ]]) { 19 | float4x4 renderedCoordinates = float4x4(float4( -1.0, -1.0, 0.0, 1.0 ), /// (x, y, depth, W) 20 | float4( 1.0, -1.0, 0.0, 1.0 ), 21 | float4( -1.0, 1.0, 0.0, 1.0 ), 22 | float4( 1.0, 1.0, 0.0, 1.0 )); 23 | 24 | float4x2 textureCoordinates = float4x2(float2( 0.0, 1.0 ), /// (x, y) 25 | float2( 1.0, 1.0 ), 26 | float2( 0.0, 0.0 ), 27 | float2( 1.0, 0.0 )); 28 | TextureMappingVertex outVertex; 29 | outVertex.renderedCoordinate = renderedCoordinates[vertex_id]; 30 | outVertex.textureCoordinate = textureCoordinates[vertex_id]; 31 | 32 | return outVertex; 33 | } 34 | 35 | fragment half4 displayBackTexture(TextureMappingVertex mappingVertex [[ stage_in ]], 36 | texture2d luminanceTexture [[ texture(0) ]]) { 37 | constexpr sampler s(address::clamp_to_edge, filter::linear); 38 | 39 | float2 coords = mappingVertex.textureCoordinate; 40 | coords.x = coords.x; 41 | float4 luminance = luminanceTexture.sample(s, float2(1.0 - coords.y, coords.x)); 42 | 43 | float hue = luminance.x*3.0; 44 | 45 | float3 rgb = hsv2rgb(float3(hue, 1.0, min(10.0*pow(luminance.x, 2.0), 1.0))); 46 | 47 | return half4(float4(rgb, 1.0)); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/RenderingEngine/Shaders.metal: -------------------------------------------------------------------------------- 1 | // 2 | // Shaders.metal 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 12/6/17. 6 | // Copyright © 2017 dmytro. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "CommonUtils.h" 11 | using namespace metal; 12 | 13 | typedef struct { 14 | float4 renderedCoordinate [[position]]; 15 | float2 textureCoordinate; 16 | } TextureMappingVertex; 17 | 18 | vertex TextureMappingVertex mapTexture(unsigned int vertex_id [[ vertex_id ]]) { 19 | float4x4 renderedCoordinates = float4x4(float4( -1.0, -1.0, 0.0, 1.0 ), /// (x, y, depth, W) 20 | float4( 1.0, -1.0, 0.0, 1.0 ), 21 | float4( -1.0, 1.0, 0.0, 1.0 ), 22 | float4( 1.0, 1.0, 0.0, 1.0 )); 23 | 24 | float4x2 textureCoordinates = float4x2(float2( 0.0, 1.0 ), /// (x, y) 25 | float2( 1.0, 1.0 ), 26 | float2( 0.0, 0.0 ), 27 | float2( 1.0, 0.0 )); 28 | TextureMappingVertex outVertex; 29 | outVertex.renderedCoordinate = renderedCoordinates[vertex_id]; 30 | outVertex.textureCoordinate = textureCoordinates[vertex_id]; 31 | 32 | return outVertex; 33 | } 34 | 35 | fragment half4 displayBackTexture(TextureMappingVertex mappingVertex [[ stage_in ]], 36 | texture2d luminanceTexture [[ texture(0) ]]) { 37 | constexpr sampler s(address::clamp_to_edge, filter::linear); 38 | 39 | float2 coords = mappingVertex.textureCoordinate; 40 | coords.x = coords.x; 41 | float4 luminance = luminanceTexture.sample(s, float2(1.0 - coords.y, coords.x)); 42 | 43 | float hue = luminance.x*3.0; 44 | 45 | float3 rgb = hsv2rgb(float3(hue, 1.0, min(10.0*pow(luminance.x, 2.0), 1.0))); 46 | 47 | return half4(float4(rgb, 1.0)); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Resources/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 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Source/Engine/CategoryRepository.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CategoryRepository.swift 3 | // SoundRecognizer 4 | // 5 | // Created by Hrebeniuk Dmytro on 25.06.2020. 6 | // Copyright © 2020 Hrebeniuk Dmytro. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class CategoryRepository { 12 | 13 | static let indexToCategoryMap: [Int: String] = 14 | [0: "dog", 15 | 14: "chirping_birds", 16 | 36: "vacuum_cleaner", 17 | 19: "thunderstorm", 18 | 30: "door_wood_knock", 19 | 34: "can_opening", 20 | 9: "crow", 21 | 22: "clapping", 22 | 48: "fireworks", 23 | 41: "chainsaw", 24 | 47: "airplane", 25 | 31: "mouse_click", 26 | 17: "pouring_water", 27 | 45: "train", 28 | 8: "sheep", 29 | 15: "water_drops", 30 | 46: "church_bells", 31 | 37: "clock_alarm", 32 | 32: "keyboard_typing", 33 | 16: "wind", 34 | 25: "footsteps", 35 | 4: "frog", 36 | 3: "cow", 37 | 27: "brushing_teeth", 38 | 43: "car_horn", 39 | 12: "crackling_fire", 40 | 40: "helicopter", 41 | 29: "drinking_sipping", 42 | 10: "rain", 43 | 7: "insects", 44 | 26: "laughing", 45 | 6: "hen", 46 | 44: "engine", 47 | 23: "breathing", 48 | 20: "crying_baby", 49 | 49: "hand_saw", 50 | 24: "coughing", 51 | 39: "glass_breaking", 52 | 28: "snoring", 53 | 18: "toilet_flush", 54 | 2: "pig", 55 | 35: "washing_machine", 56 | 38: "clock_tick", 57 | 21: "sneezing", 58 | 1: "rooster", 59 | 11: "sea_waves", 60 | 42: "siren", 61 | 5: "cat", 62 | 33: "door_wood_creaks", 63 | 13: "crickets" 64 | ] 65 | 66 | } 67 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizerTests/SoundRecognizerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SoundRecognizerTests.swift 3 | // SoundRecognizerTests 4 | // 5 | // Created by Hrebeniuk Dmytro on 30.06.2020. 6 | // Copyright © 2020 Hrebeniuk Dmytro. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import RosaKit 11 | import SoundRecognizer 12 | 13 | class SoundRecognizerTests: XCTestCase { 14 | 15 | override func setUpWithError() throws { 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDownWithError() throws { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | } 22 | 23 | func testRecognizer() throws { 24 | let url = Bundle(for: Self.self).url(forResource: "1-48298-A-46", withExtension: "wav") 25 | 26 | let soundFile = url.flatMap { try? WavFileManager().readWavFile(at: $0) } 27 | 28 | let int16Array = soundFile?.data.int16Array.map { Double($0)/32768.0 } 29 | 30 | let xshape = int16Array?.count ?? 0 31 | let size = 110250 32 | let offset = size/8 33 | let count = xshape/offset - 30/2 34 | 35 | let validCategory = 46 36 | 37 | let soundRecognizerEngine = SoundRecognizerEngine(sampleRate: 44100, windowLength: size) 38 | 39 | var isCorrect = true 40 | 41 | for index in 0.. 0.95 && ((result?.category ?? -1) % 100) == validCategory 46 | } 47 | 48 | XCTAssertTrue(isCorrect) 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Sources/NumKit/DataExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DataExtensions.swift 3 | // RosaKit 4 | // 5 | // Created by Hrebeniuk Dmytro on 17.12.2019. 6 | // Copyright © 2019 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public extension Data { 12 | 13 | func generateArray() -> [T] { 14 | return self.withUnsafeBytes { rawPointer -> [T] in 15 | let words = rawPointer.bindMemory(to: T.self) 16 | var array: [T] = [T]() 17 | for index in 0.. [Int16] in 27 | let words = rawPointer.bindMemory(to: Int16.self) 28 | var array: [Int16] = [] 29 | for index in 0.. [Int8] in 39 | let words = rawPointer.bindMemory(to: Int8.self) 40 | var array: [Int8] = [] 41 | for index in 0.. [Float] in 51 | let words = rawPointer.bindMemory(to: Float32.self) 52 | var array: [Float] = [] 53 | for index in 0.. 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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | NSMicrophoneUsageDescription 24 | Your microphone will be used to analyze volume level 25 | UIApplicationSceneManifest 26 | 27 | UIApplicationSupportsMultipleScenes 28 | 29 | UISceneConfigurations 30 | 31 | UIWindowSceneSessionRoleApplication 32 | 33 | 34 | UISceneConfigurationName 35 | Default Configuration 36 | UISceneDelegateClassName 37 | $(PRODUCT_MODULE_NAME).SceneDelegate 38 | 39 | 40 | 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIRequiredDeviceCapabilities 45 | 46 | armv7 47 | 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | UISupportedInterfaceOrientations~ipad 55 | 56 | UIInterfaceOrientationPortrait 57 | UIInterfaceOrientationPortraitUpsideDown 58 | UIInterfaceOrientationLandscapeLeft 59 | UIInterfaceOrientationLandscapeRight 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Source/Screens/Main/MainView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainView.swift 3 | // SoundRecognizer 4 | // 5 | // Created by Hrebeniuk Dmytro on 27.12.2019. 6 | // Copyright © 2019 Hrebeniuk Dmytro. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct MainView: View { 12 | @EnvironmentObject var viewModel: MainViewModel 13 | 14 | var body: some View { 15 | VStack { 16 | 17 | switch viewModel.state { 18 | case .initial: 19 | Text("") 20 | case .downloading: 21 | Text("Downloading Dataset...") 22 | case .unzip: 23 | Text("Unzipping...") 24 | case .processing: 25 | Text("Percentage Proceccesed: \(viewModel.percentageProceccesed * 100)%") 26 | Text("Percentage Valid: \(viewModel.percentageValid * 100)%") 27 | Text("Percentage Invalid: \(viewModel.percentageInvalid * 100)%") 28 | 29 | ScrollView { 30 | ForEach(self.viewModel.problemPreditions, id: \.self) { problemPrediction in 31 | HStack { 32 | Text("FileName: \(problemPrediction.fileName)") 33 | Text("Predicted: \(problemPrediction.predictedCategory)") 34 | Text("(\(problemPrediction.percentage))") 35 | Text("Target: \(problemPrediction.targetCategory)") 36 | 37 | Spacer() 38 | Button("Save Wave") { 39 | viewModel.copyWave(toClipboard: problemPrediction) 40 | }.padding() 41 | 42 | Button("Save STFT") { 43 | viewModel.copySTFT(toClipboard: problemPrediction) 44 | }.padding() 45 | }.sheet(isPresented: $viewModel.showFileExportPicker) { 46 | SaveDocumentPicker(url: $viewModel.fileExportURL) 47 | } 48 | } 49 | } 50 | } 51 | 52 | } 53 | } 54 | } 55 | 56 | struct MainView_Previews: PreviewProvider { 57 | static var previews: some View { 58 | MainView() 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/Spectrogram/SpectrogramViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpectrogramViewController.swift 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 6/09/2020. 6 | // Copyright © 2020 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import RosaKit 11 | import CoreMedia 12 | 13 | class SpectrogramViewController: NSViewController { 14 | 15 | @IBOutlet weak var spectrogramView: SpectrogramView! 16 | @IBOutlet weak var zoomSlider: NSSlider? 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | spectrogramView?.elementWidth = CGFloat(zoomSlider?.floatValue ?? 20.0) 22 | spectrogramView.delegate = self 23 | 24 | loadData() 25 | 26 | spectrogramView.reloadData() 27 | } 28 | 29 | private var spectrograms = [[Double]]() 30 | 31 | private func loadData() { 32 | spectrograms = [[Double]]() 33 | 34 | let url = Bundle.main.url(forResource: "test", withExtension: "wav") 35 | 36 | let soundFile = url.flatMap { try? WavFileManager().readWavFile(at: $0) } 37 | 38 | let dataCount = soundFile?.data.count ?? 0 39 | let sampleRate = soundFile?.sampleRate ?? 44100 40 | let bytesPerSample = soundFile?.bytesPerSample ?? 0 41 | 42 | let chunkSize = 66000 43 | let chunksCount = dataCount/(chunkSize*bytesPerSample) - 1 44 | 45 | let rawData = soundFile?.data.int16Array 46 | 47 | for index in 0.. Int { 64 | return spectrograms.count 65 | } 66 | 67 | func elementsValueInSpectrogram(view: SpectrogramView, at index: Int) -> [Double] { 68 | if index < spectrograms.count { 69 | return spectrograms[index] 70 | } 71 | else { 72 | return [Double]() 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/RenderingEngine/SamplesRenderer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SamplesRenderer.swift 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 12/18/17. 6 | // Copyright © 2017 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Metal 10 | import CoreMedia 11 | 12 | class SamplesMetalRenderer { 13 | 14 | private let device: MTLDevice? 15 | private let commandQueue: MTLCommandQueue? 16 | 17 | init() { 18 | self.device = MTLCreateSystemDefaultDevice() 19 | self.commandQueue = self.device?.makeCommandQueue(maxCommandBufferCount: 1) 20 | } 21 | 22 | private var renderPipelineState: MTLRenderPipelineState? 23 | private var texture: MTLTexture? 24 | private var commandBuffer: MTLCommandBuffer? 25 | 26 | var scaleFactor: Float = 1.0 27 | 28 | func setup() { 29 | self.initializeRenderPipelineState() 30 | } 31 | 32 | private func initializeRenderPipelineState() { 33 | guard let device = self.device, 34 | let library = device.makeDefaultLibrary() else { 35 | return 36 | } 37 | 38 | let pipelineDescriptor = MTLRenderPipelineDescriptor() 39 | pipelineDescriptor.sampleCount = 1 40 | pipelineDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm 41 | pipelineDescriptor.depthAttachmentPixelFormat = .invalid 42 | 43 | pipelineDescriptor.vertexFunction = library.makeFunction(name: "mapTexture") 44 | pipelineDescriptor.fragmentFunction = library.makeFunction(name: "displayBackTexture") 45 | 46 | do { 47 | try self.renderPipelineState = device.makeRenderPipelineState(descriptor: pipelineDescriptor) 48 | } 49 | catch { 50 | assertionFailure("Failed creating a render state pipeline. Can't render the texture without one.") 51 | return 52 | } 53 | } 54 | 55 | func render(with renderPassDescriptor: MTLRenderPassDescriptor, drawable: MTLDrawable) { 56 | guard let texture = self.texture else { 57 | return 58 | } 59 | 60 | guard let renderPipelineState = self.renderPipelineState 61 | else { 62 | return 63 | } 64 | 65 | guard let commandBuffer = self.commandQueue?.makeCommandBuffer() else { 66 | return 67 | } 68 | 69 | let encoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) 70 | encoder?.pushDebugGroup("RenderFrame") 71 | encoder?.setRenderPipelineState(renderPipelineState) 72 | encoder?.setFragmentTexture(texture, index: 0) 73 | 74 | encoder?.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4, instanceCount: 1) 75 | encoder?.popDebugGroup() 76 | encoder?.endEncoding() 77 | 78 | commandBuffer.present(drawable) 79 | commandBuffer.commit() 80 | } 81 | 82 | func send(texture: MTLTexture) { 83 | self.texture = texture 84 | } 85 | 86 | func requestRenderedTexture() -> MTLTexture? { 87 | return self.texture 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/RenderingEngine/SamplesRenderer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SamplesRenderer.swift 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 12/18/17. 6 | // Copyright © 2017 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Metal 10 | import CoreMedia 11 | 12 | class SamplesMetalRenderer { 13 | 14 | private let device: MTLDevice? 15 | private let commandQueue: MTLCommandQueue? 16 | 17 | init() { 18 | self.device = MTLCreateSystemDefaultDevice() 19 | self.commandQueue = self.device?.makeCommandQueue(maxCommandBufferCount: 1) 20 | } 21 | 22 | private var renderPipelineState: MTLRenderPipelineState? 23 | private var texture: MTLTexture? 24 | private var commandBuffer: MTLCommandBuffer? 25 | 26 | var scaleFactor: Float = 1.0 27 | 28 | func setup() { 29 | self.initializeRenderPipelineState() 30 | } 31 | 32 | private func initializeRenderPipelineState() { 33 | guard let device = self.device, 34 | let library = device.makeDefaultLibrary() else { 35 | return 36 | } 37 | 38 | let pipelineDescriptor = MTLRenderPipelineDescriptor() 39 | pipelineDescriptor.sampleCount = 1 40 | pipelineDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm 41 | pipelineDescriptor.depthAttachmentPixelFormat = .invalid 42 | 43 | pipelineDescriptor.vertexFunction = library.makeFunction(name: "mapTexture") 44 | pipelineDescriptor.fragmentFunction = library.makeFunction(name: "displayBackTexture") 45 | 46 | do { 47 | try self.renderPipelineState = device.makeRenderPipelineState(descriptor: pipelineDescriptor) 48 | } 49 | catch { 50 | assertionFailure("Failed creating a render state pipeline. Can't render the texture without one.") 51 | return 52 | } 53 | } 54 | 55 | func render(with renderPassDescriptor: MTLRenderPassDescriptor, drawable: MTLDrawable) { 56 | guard let texture = self.texture else { 57 | return 58 | } 59 | 60 | guard let renderPipelineState = self.renderPipelineState 61 | else { 62 | return 63 | } 64 | 65 | guard let commandBuffer = self.commandQueue?.makeCommandBuffer() else { 66 | return 67 | } 68 | 69 | let encoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) 70 | encoder?.pushDebugGroup("RenderFrame") 71 | encoder?.setRenderPipelineState(renderPipelineState) 72 | encoder?.setFragmentTexture(texture, index: 0) 73 | 74 | encoder?.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4, instanceCount: 1) 75 | encoder?.popDebugGroup() 76 | encoder?.endEncoding() 77 | 78 | commandBuffer.present(drawable) 79 | commandBuffer.commit() 80 | } 81 | 82 | func send(texture: MTLTexture) { 83 | self.texture = texture 84 | } 85 | 86 | func requestRenderedTexture() -> MTLTexture? { 87 | return self.texture 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/Spectrogram/SpectrogramViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpectrogramViewController.swift 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 6/09/2020. 6 | // Copyright © 2020 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import RosaKit 11 | import CoreMedia 12 | 13 | class SpectrogramViewController: NSViewController { 14 | 15 | @IBOutlet weak var spectrogramView: SpectrogramView! 16 | @IBOutlet weak var zoomSlider: NSSlider? 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | spectrogramView?.elementWidth = CGFloat(zoomSlider?.floatValue ?? 20.0) 22 | spectrogramView.delegate = self 23 | 24 | loadData() 25 | 26 | spectrogramView.reloadData() 27 | } 28 | 29 | private var spectrograms = [[Double]]() 30 | 31 | var fileData: (fileDescriptor: WavFileManager.WAVFileDesriptor, data: Data)? { 32 | didSet { 33 | loadData() 34 | } 35 | } 36 | 37 | private func loadData() { 38 | spectrograms = [[Double]]() 39 | 40 | guard let fileData = self.fileData else { 41 | return 42 | } 43 | 44 | let soundFile: WavFileManager.WAVFileDesriptor? = fileData.fileDescriptor 45 | 46 | let dataCount = fileData.data.count 47 | let sampleRate = soundFile?.sampleRate ?? 44100 48 | let bytesPerSample = soundFile?.bytesPerSample ?? 0 49 | 50 | let chunkSize = 2048*20 51 | let chunksCount = dataCount/(chunkSize*bytesPerSample) 52 | 53 | let rawData = fileData.data.int16Array 54 | 55 | for index in 0.. Int { 72 | return spectrograms.count 73 | } 74 | 75 | func elementsValueInSpectrogram(view: SpectrogramView, at index: Int) -> [Double] { 76 | if index < spectrograms.count { 77 | return spectrograms[index] 78 | } 79 | else { 80 | return [Double]() 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Source/Engine/MicrophoneReader/AudioRecorder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AudioRecorder.swift 3 | // dbMeter 4 | // 5 | // Created by Dmytro Hrebeniuk on 2/10/17. 6 | // Copyright © 2017 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import AVFoundation 10 | 11 | public typealias AudioRecorderDeviceNameHandler = (_ deviceName: String) -> Void 12 | 13 | class AudioRecorder { 14 | 15 | private let session: AVCaptureSession 16 | 17 | private var currentCaptureInput: AVCaptureDeviceInput! 18 | 19 | private var connectedObserver: NSObjectProtocol? 20 | private var diconnectedObserver: NSObjectProtocol? 21 | 22 | private var currentDeviceName: String? 23 | 24 | var audioRecorderDeviceNameHandler: AudioRecorderDeviceNameHandler? { 25 | didSet { 26 | currentDeviceName.map { audioRecorderDeviceNameHandler?($0) } 27 | } 28 | } 29 | 30 | init(_ captureSession: AVCaptureSession) { 31 | self.session = captureSession 32 | 33 | self.connectedObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.AVCaptureDeviceWasConnected, object: nil, queue: OperationQueue.main) { [weak self] notification in 34 | if let audioCaptureDevice = notification.object as? AVCaptureDevice { 35 | self?.updateCurrentDeviceInfo(with: audioCaptureDevice) 36 | } 37 | } 38 | 39 | self.diconnectedObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.AVCaptureDeviceWasDisconnected, object: nil, queue: OperationQueue.main) { [weak self] _ in 40 | if let audioCaptureDevice = AVCaptureDevice.default(for: AVMediaType.audio) { 41 | self?.updateCurrentDeviceInfo(with: audioCaptureDevice) 42 | } 43 | } 44 | } 45 | 46 | func setupRecordingSession() throws { 47 | if self.currentCaptureInput == nil { 48 | 49 | if #available(OSX 10.14, *) { 50 | let microPhoneStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.audio) 51 | 52 | if microPhoneStatus == .denied || microPhoneStatus == .restricted { 53 | return 54 | } 55 | } 56 | 57 | guard let audioCaptureDevice = AVCaptureDevice.default(for: AVMediaType.audio) else { 58 | return 59 | } 60 | 61 | self.updateCurrentDeviceInfo(with: audioCaptureDevice) 62 | 63 | let audioInput = try AVCaptureDeviceInput(device: audioCaptureDevice) 64 | self.currentCaptureInput = audioInput 65 | 66 | if self.session.canAddInput(audioInput) { 67 | self.session.addInput(audioInput) 68 | } 69 | } 70 | } 71 | 72 | private func updateCurrentDeviceInfo(with device: AVCaptureDevice) { 73 | currentDeviceName = device.localizedName 74 | audioRecorderDeviceNameHandler?(device.localizedName) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Source/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // SoundRecognizer 4 | // 5 | // Created by Hrebeniuk Dmytro on 27.12.2019. 6 | // Copyright © 2019 Hrebeniuk Dmytro. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SwiftUI 11 | 12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 21 | 22 | let mainViewModel = MainViewModel() 23 | 24 | // Create the SwiftUI view that provides the window contents. 25 | let mainView = MainView() 26 | 27 | // Use a UIHostingController as window root view controller. 28 | if let windowScene = scene as? UIWindowScene { 29 | let window = UIWindow(windowScene: windowScene) 30 | window.rootViewController = UIHostingController(rootView: mainView.environmentObject(mainViewModel)) 31 | self.window = window 32 | window.makeKeyAndVisible() 33 | } 34 | 35 | mainViewModel.setup() 36 | } 37 | 38 | func sceneDidDisconnect(_ scene: UIScene) { 39 | // Called as the scene is being released by the system. 40 | // This occurs shortly after the scene enters the background, or when its session is discarded. 41 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 42 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 43 | } 44 | 45 | func sceneDidBecomeActive(_ scene: UIScene) { 46 | // Called when the scene has moved from an inactive state to an active state. 47 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 48 | } 49 | 50 | func sceneWillResignActive(_ scene: UIScene) { 51 | // Called when the scene will move from an active state to an inactive state. 52 | // This may occur due to temporary interruptions (ex. an incoming phone call). 53 | } 54 | 55 | func sceneWillEnterForeground(_ scene: UIScene) { 56 | // Called as the scene transitions from the background to the foreground. 57 | // Use this method to undo the changes made on entering the background. 58 | } 59 | 60 | func sceneDidEnterBackground(_ scene: UIScene) { 61 | // Called as the scene transitions from the foreground to the background. 62 | // Use this method to save data, release shared resources, and store enough scene-specific state information 63 | // to restore the scene back to its current state. 64 | } 65 | 66 | 67 | } 68 | 69 | -------------------------------------------------------------------------------- /Sources/NumKit/FloatingPointExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FloatingPointExtensions.swift 3 | // RosaKit 4 | // 5 | // Created by Hrebeniuk Dmytro on 17.12.2019. 6 | // Copyright © 2019 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreGraphics 11 | 12 | extension FloatingPoint { 13 | 14 | var byteArray: [UInt8] { 15 | var value = self 16 | return withUnsafeBytes(of: &value) { Array($0) } 17 | } 18 | 19 | static func MEL(fromHZ frequency: T) -> T { 20 | let fmin = T(0) 21 | let fsp = T(200) / T(3) 22 | 23 | var mels = (frequency - fmin) / fsp 24 | 25 | let minLogHZ = T(1000) 26 | let minLogMEL = (minLogHZ - fmin) / fsp 27 | let logStep = ((T(64)/T(10)).logarithm() as T)/T(27) 28 | 29 | if frequency >= minLogHZ { 30 | mels = minLogMEL + (frequency / minLogHZ).logarithm() / logStep 31 | } 32 | 33 | return mels 34 | } 35 | 36 | static func HZ(fromMEL mels: T) -> T { 37 | let fmin = T(0) 38 | let fsp = T(200) / T(3) 39 | 40 | var freqs = fmin + fsp*mels 41 | 42 | let minLogHZ = T(1000) 43 | let minLogMEL = (minLogHZ - fmin) / fsp 44 | 45 | let logStep = ((T(64)/T(10)).logarithm() as T)/T(27) 46 | 47 | if mels >= minLogMEL { 48 | let exponent = (logStep as T * (mels - minLogMEL)).exponent() as T 49 | freqs = minLogHZ*exponent 50 | } 51 | 52 | return freqs 53 | } 54 | 55 | func logarithm10() -> T { 56 | switch self { 57 | case let self as Double: 58 | return log10(self) as? T ?? 0 59 | case let self as CGFloat: 60 | return log10f(Float(self)) as? T ?? 0 61 | case let self as Float: 62 | return log10f(Float(self)) as? T ?? 0 63 | default: 64 | return 0 as T 65 | } 66 | } 67 | 68 | func logarithm() -> T { 69 | switch self { 70 | case let self as Double: 71 | return log(self) as? T ?? 0 72 | case let self as CGFloat: 73 | return logf(Float(self)) as? T ?? 0 74 | case let self as Float: 75 | return logf(Float(self)) as? T ?? 0 76 | default: 77 | return 0 as T 78 | } 79 | } 80 | 81 | func exponent() -> T { 82 | switch self { 83 | case let self as Double: 84 | return exp(self) as? T ?? 0 85 | case let self as CGFloat: 86 | return expf(Float(self)) as? T ?? 0 87 | case let self as Float: 88 | return expf(Float(self)) as? T ?? 0 89 | default: 90 | return 0 as T 91 | } 92 | } 93 | 94 | func cosine() -> T { 95 | switch self { 96 | case let self as Double: 97 | return cos(-self) as? T ?? 0 98 | case let self as CGFloat: 99 | return cosf(-Float(self)) as? T ?? 0 100 | case let self as Float: 101 | return cosf(-Float(self)) as? T ?? 0 102 | default: 103 | return 0 as T 104 | } 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /Sources/SciKit/ArrayDoubleExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ArrayDoubleExtensions.swift 3 | // RosaKit 4 | // 5 | // Created by Hrebeniuk Dmytro on 17.12.2019. 6 | // Copyright © 2019 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Array where Iterator.Element: FloatingPoint { 12 | 13 | func floatingPointStrided(shape: (width: Int, height: Int), stride: (xStride: Int, yStride: Int)? = nil) -> [[Element]] { 14 | var resultArray: [[Element]] = [] 15 | 16 | let byteStrideX = stride?.xStride ?? 1 17 | let byteStrideY = stride?.yStride ?? shape.height 18 | var byteOffsetX: Int = 0 19 | var byteOffsetY: Int = 0 20 | for yIndex in 0.. [[Element]] { 34 | let elementSize = MemoryLayout.size 35 | return floatingPointStrided(shape: shape, stride: (xStride: (stride?.xStride ?? elementSize)/elementSize, yStride: (stride?.yStride ?? elementSize)/elementSize)) 36 | } 37 | 38 | var diff: [Element] { 39 | var diff = [Element]() 40 | 41 | for index in 1.. [[Element]] { 50 | var result = [[Element]]() 51 | 52 | let rows = self.count 53 | let cols = array.count 54 | 55 | for row in 0.. [[Element]] { 73 | let framesCount = 1 + (self.count - frameLength) / hopLength 74 | let strides = MemoryLayout.size(ofValue: Double(0)) 75 | 76 | let outputShape = (width: self.count - frameLength + 1, height: frameLength) 77 | let outputStrides = (xStride: strides*hopLength, yStride: strides) 78 | 79 | let verticalSize = Int(ceil(Float(outputShape.width)/Float(hopLength))) 80 | 81 | var xw = [[Double]]() 82 | 83 | for yIndex in 0.. [[Element]] { 14 | var result: [[Element]] = [[Element]]() 15 | 16 | for _ in 0.. [Element] { 28 | var result: [Element] = [Element]() 29 | 30 | for _ in 0.. [Element] { 38 | var array = [Element]() 39 | 40 | array.append(contentsOf: [Element].init(repeating: Element(0), count: fftSize/2)) 41 | array.append(contentsOf: self) 42 | array.append(contentsOf: [Element].init(repeating: Element(0), count: fftSize/2)) 43 | 44 | return array 45 | } 46 | 47 | static func linespace(start: Element, stop: Element, num: Element) -> [Element] { 48 | var linespace = [Element]() 49 | 50 | let one = num/num 51 | var index = num*0 52 | while index < num-one { 53 | let startPart = (start*(one - index/floor(num - one))) 54 | let stopPart = (index*stop/floor(num - one)) 55 | 56 | let value = startPart + stopPart 57 | 58 | linespace.append(value) 59 | index += num/num 60 | } 61 | 62 | linespace.append(stop) 63 | 64 | return linespace 65 | } 66 | 67 | 68 | 69 | } 70 | 71 | extension Array where Iterator.Element == Double { 72 | 73 | static func getHannWindow(frameLength: Int) -> [Double] { 74 | let fac = [Double].linespace(start: -Double.pi, stop: Double.pi, num: Double(frameLength + 1)) 75 | 76 | var w = [Double](repeating: 0.0, count: frameLength+1) 77 | 78 | for (k, a) in [0.5, 0.5].enumerated(){ 79 | for index in 0.. [Double] { 88 | let nCount = nFFt + hopLength * (nFrames - 1) 89 | 90 | var x = Self.zeros(length: nCount) 91 | 92 | var winSQ = getHannWindow(frameLength: (winLength)).map { Double($0)*Double(($0)) } 93 | 94 | for index in 0.. Void 15 | 16 | class AudioSampler: NSObject, AVCaptureAudioDataOutputSampleBufferDelegate { 17 | 18 | private let session: AVCaptureSession 19 | private var audioOutput: AVCaptureAudioDataOutput! 20 | 21 | var isSoundEnabled: Bool = true 22 | 23 | var audioSamplerOutputHandler: AudioSamplerHandler? 24 | 25 | init(_ captureSession: AVCaptureSession) { 26 | self.session = captureSession 27 | } 28 | 29 | func setupOutput() { 30 | guard self.audioOutput == nil else { return } 31 | 32 | self.audioOutput = AVCaptureAudioDataOutput() 33 | let queue = DispatchQueue(label: kSampleBufferQueue, attributes: []) 34 | self.audioOutput.setSampleBufferDelegate(self, queue: queue) 35 | 36 | if self.session.canAddOutput(self.audioOutput) { 37 | self.session.addOutput(self.audioOutput) 38 | } 39 | } 40 | 41 | func unSetupOutput() { 42 | guard self.audioOutput != nil else { return } 43 | 44 | self.session.removeOutput(self.audioOutput) 45 | self.audioOutput = nil 46 | } 47 | 48 | func captureOutput(_ captureOutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { 49 | 50 | if let handler = self.audioSamplerOutputHandler { 51 | var blockBufferOut: CMBlockBuffer? 52 | var sizeOut = Int(0) 53 | 54 | guard let formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer) else { 55 | return 56 | } 57 | 58 | let streamDescription = CMAudioFormatDescriptionGetStreamBasicDescription(formatDescription) 59 | 60 | let audioBufferSizeStatus = CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, bufferListSizeNeededOut: &sizeOut, bufferListOut: nil, bufferListSize: 0, blockBufferAllocator: nil, blockBufferMemoryAllocator: nil, flags: 0, blockBufferOut: nil) 61 | guard audioBufferSizeStatus == noErr else { 62 | return 63 | } 64 | 65 | var audioBufferList: AudioBufferList = AudioBufferList.allocate(maximumBuffers: MemoryLayout.size + sizeOut).unsafePointer.pointee 66 | 67 | let audioBufferStatus = CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, bufferListSizeNeededOut: &sizeOut, bufferListOut: &audioBufferList, bufferListSize: sizeOut, blockBufferAllocator: kCFAllocatorDefault, blockBufferMemoryAllocator: kCFAllocatorDefault, flags: kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, blockBufferOut: &blockBufferOut) 68 | guard audioBufferStatus == noErr else { 69 | return 70 | } 71 | 72 | let sampleRate = streamDescription?.pointee.mSampleRate ?? 0 73 | 74 | let audioBuffer = audioBufferList.mBuffers 75 | let samplesCount = Int64(CMSampleBufferGetNumSamples(sampleBuffer)) 76 | 77 | let presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer) 78 | 79 | let data = Data(bytes: UnsafeMutableRawPointer(audioBuffer.mData!), count: Int(audioBuffer.mDataByteSize)) 80 | 81 | handler(data, presentationTimeStamp.value, Int64(presentationTimeStamp.timescale), samplesCount, Int64(sampleRate)) 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/RenderingEngine/MTLDeviceExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTLDeviceExtensions.swift 3 | // RosaKitExample 4 | // 5 | // Created by Hrebeniuk Dmytro on 07.01.2020. 6 | // Copyright © 2020 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Metal 10 | import CoreMedia 11 | 12 | extension MTLDevice { 13 | 14 | public func createRedTexture(from data: [UInt8], width: Int, height: Int) -> MTLTexture? { 15 | let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .r8Unorm, width: width, height: height, mipmapped: false) 16 | 17 | let texture = self.makeTexture(descriptor: textureDescriptor) 18 | 19 | data.withUnsafeBytes { 20 | $0.baseAddress.map { 21 | texture?.replace(region: MTLRegionMake2D(0, 0, width, height), mipmapLevel: 0, withBytes: $0, bytesPerRow: width) 22 | } 23 | } 24 | 25 | return texture 26 | } 27 | 28 | func createRedTexture(from pixelBuffer: CVPixelBuffer, textureCache: CVMetalTextureCache? = nil) -> MTLTexture? { 29 | let width = CVPixelBufferGetWidth(pixelBuffer) 30 | let height = CVPixelBufferGetHeight(pixelBuffer) 31 | 32 | let format: MTLPixelFormat = .r8Unorm 33 | 34 | var cvMetalTexture: CVMetalTexture? 35 | 36 | var currentTextureCache: CVMetalTextureCache? = textureCache 37 | 38 | if currentTextureCache == nil { 39 | guard CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, self, nil, ¤tTextureCache) == kCVReturnSuccess 40 | else { 41 | return nil 42 | } 43 | } 44 | 45 | guard let metalTextureCache = currentTextureCache else { 46 | return nil 47 | } 48 | 49 | let status = CVMetalTextureCacheCreateTextureFromImage(nil, 50 | metalTextureCache, pixelBuffer, nil, format, width, height, 0, &cvMetalTexture) 51 | 52 | var texture: MTLTexture? 53 | if(status == kCVReturnSuccess) { 54 | texture = CVMetalTextureGetTexture(cvMetalTexture!) 55 | } 56 | 57 | return texture 58 | } 59 | 60 | func createTexture(from pixelBuffer: CVPixelBuffer, textureCache: CVMetalTextureCache? = nil) -> MTLTexture? { 61 | let width = CVPixelBufferGetWidth(pixelBuffer) 62 | let height = CVPixelBufferGetHeight(pixelBuffer) 63 | 64 | let format: MTLPixelFormat = .bgra8Unorm 65 | 66 | var cvMetalTexture: CVMetalTexture? 67 | 68 | var currentTextureCache: CVMetalTextureCache? = textureCache 69 | 70 | if currentTextureCache == nil { 71 | guard CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, self, nil, ¤tTextureCache) == kCVReturnSuccess 72 | else { 73 | return nil 74 | } 75 | } 76 | 77 | guard let metalTextureCache = currentTextureCache else { 78 | return nil 79 | } 80 | 81 | let status = CVMetalTextureCacheCreateTextureFromImage(nil, 82 | metalTextureCache, pixelBuffer, nil, format, width, height, 0, &cvMetalTexture) 83 | 84 | var texture: MTLTexture? 85 | if(status == kCVReturnSuccess) { 86 | texture = CVMetalTextureGetTexture(cvMetalTexture!) 87 | } 88 | 89 | return texture 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/RenderingEngine/MTLDeviceExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MTLDeviceExtensions.swift 3 | // RosaKitExample 4 | // 5 | // Created by Hrebeniuk Dmytro on 07.01.2020. 6 | // Copyright © 2020 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Metal 10 | import CoreMedia 11 | 12 | extension MTLDevice { 13 | 14 | public func createRedTexture(from data: [UInt8], width: Int, height: Int) -> MTLTexture? { 15 | let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .r8Unorm, width: width, height: height, mipmapped: false) 16 | 17 | let texture = self.makeTexture(descriptor: textureDescriptor) 18 | 19 | data.withUnsafeBytes { 20 | $0.baseAddress.map { 21 | texture?.replace(region: MTLRegionMake2D(0, 0, width, height), mipmapLevel: 0, withBytes: $0, bytesPerRow: width) 22 | } 23 | } 24 | 25 | return texture 26 | } 27 | 28 | func createRedTexture(from pixelBuffer: CVPixelBuffer, textureCache: CVMetalTextureCache? = nil) -> MTLTexture? { 29 | let width = CVPixelBufferGetWidth(pixelBuffer) 30 | let height = CVPixelBufferGetHeight(pixelBuffer) 31 | 32 | let format: MTLPixelFormat = .r8Unorm 33 | 34 | var cvMetalTexture: CVMetalTexture? 35 | 36 | var currentTextureCache: CVMetalTextureCache? = textureCache 37 | 38 | if currentTextureCache == nil { 39 | guard CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, self, nil, ¤tTextureCache) == kCVReturnSuccess 40 | else { 41 | return nil 42 | } 43 | } 44 | 45 | guard let metalTextureCache = currentTextureCache else { 46 | return nil 47 | } 48 | 49 | let status = CVMetalTextureCacheCreateTextureFromImage(nil, 50 | metalTextureCache, pixelBuffer, nil, format, width, height, 0, &cvMetalTexture) 51 | 52 | var texture: MTLTexture? 53 | if(status == kCVReturnSuccess) { 54 | texture = CVMetalTextureGetTexture(cvMetalTexture!) 55 | } 56 | 57 | return texture 58 | } 59 | 60 | func createTexture(from pixelBuffer: CVPixelBuffer, textureCache: CVMetalTextureCache? = nil) -> MTLTexture? { 61 | let width = CVPixelBufferGetWidth(pixelBuffer) 62 | let height = CVPixelBufferGetHeight(pixelBuffer) 63 | 64 | let format: MTLPixelFormat = .bgra8Unorm 65 | 66 | var cvMetalTexture: CVMetalTexture? 67 | 68 | var currentTextureCache: CVMetalTextureCache? = textureCache 69 | 70 | if currentTextureCache == nil { 71 | guard CVMetalTextureCacheCreate(kCFAllocatorDefault, nil, self, nil, ¤tTextureCache) == kCVReturnSuccess 72 | else { 73 | return nil 74 | } 75 | } 76 | 77 | guard let metalTextureCache = currentTextureCache else { 78 | return nil 79 | } 80 | 81 | let status = CVMetalTextureCacheCreateTextureFromImage(nil, 82 | metalTextureCache, pixelBuffer, nil, format, width, height, 0, &cvMetalTexture) 83 | 84 | var texture: MTLTexture? 85 | if(status == kCVReturnSuccess) { 86 | texture = CVMetalTextureGetTexture(cvMetalTexture!) 87 | } 88 | 89 | return texture 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Source/Engine/SoundRecognizerEngine.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SoundRecognizerEngine.swift 3 | // SoundRecognizer 4 | // 5 | // Created by Hrebeniuk Dmytro on 25.06.2020. 6 | // Copyright © 2020 Hrebeniuk Dmytro. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreML 11 | import RosaKit 12 | 13 | public class SoundRecognizerEngine { 14 | 15 | private var model: SoundRecognition? 16 | private var samplesCollection: [Double] = [] 17 | 18 | let melBasis: [[Double]] 19 | let sampleRate: Int 20 | let windowLength: Int 21 | 22 | public init(sampleRate: Int = 22050, windowLength length: Int) { 23 | let config = MLModelConfiguration() 24 | config.computeUnits = .cpuOnly 25 | self.model = try? SoundRecognition.init(configuration: config) 26 | 27 | self.sampleRate = sampleRate 28 | self.melBasis = [Double].createMelFilter(sampleRate: sampleRate, FTTCount: 1024, melsCount: 128) 29 | self.windowLength = length 30 | } 31 | 32 | public func predict(samples: [Double]) -> (percentage: Double, category: Int, title: String)? { 33 | var predicatedResult: (Double, Int, String)? = nil 34 | 35 | let bunchSize = self.windowLength 36 | 37 | let remaidToAddSamples = bunchSize - (self.samplesCollection.count) 38 | samplesCollection.append(contentsOf: samples[0..= bunchSize { 41 | let collectionToPredict = samplesCollection 42 | samplesCollection = [Double]() 43 | 44 | let spectrogram = collectionToPredict.stft(nFFT: 1024, hopLength: 512).map { $0.map { pow($0.real, 2.0) + pow($0.imagine, 2.0) } } 45 | let melSpectrogram = self.melBasis.dot(matrix: spectrogram) 46 | 47 | let powerSpectrogram = melSpectrogram//.normalizeAudioPowerArray() 48 | let filteredSpectrogram = powerSpectrogram 49 | 50 | let mlArray = try? MLMultiArray(shape: [NSNumber(value: 1), NSNumber(value: 128), NSNumber(value: 216), NSNumber(value: 1)], dataType: MLMultiArrayDataType.double) 51 | 52 | let flatSpectrogram = filteredSpectrogram.flatMap { $0 } 53 | for index in 0.. [[Double]] { 15 | let newMatrixCols = matrix1.count 16 | let newMatrixRows = matrix2.first?.count ?? 1 17 | 18 | var result = [Double](repeating: 0.0, count: newMatrixCols*newMatrixRows) 19 | 20 | let flatMatrix1 = matrix1.flatMap { $0 } 21 | let flatMatrix2 = matrix2.flatMap { $0 } 22 | 23 | for index in 0.. [[Double]] { 33 | let newMatrixCols = matrix1.count 34 | let newMatrixRows = matrix2.first?.count ?? 1 35 | 36 | var result = [Double](repeating: 0.0, count: newMatrixCols*newMatrixRows) 37 | 38 | let flatMatrix1 = matrix1.flatMap { $0 } 39 | let flatMatrix2 = matrix2.flatMap { $0 } 40 | 41 | for index in 0..(matrix1: [T], matrix2: [T]) -> [T] { 51 | let minCount = Swift.min(matrix1.count, matrix2.count) 52 | 53 | var result = [T](repeating: 0, count: minCount) 54 | 55 | for index in 0..(matrix1: [T], matrix2: [T]) -> [T] { 63 | let minCount = Swift.min(matrix1.count, matrix2.count) 64 | 65 | var result = [T](repeating: 0, count: minCount) 66 | 67 | for index in 0.. [[Element]] { 75 | return stride(from: 0, to: count, by: size).map { 76 | Array(self[$0 ..< Swift.min($0 + size, count)]) 77 | } 78 | } 79 | 80 | } 81 | 82 | extension Array where Element == [Double] { 83 | 84 | public var transposed: [[Double]] { 85 | let matrix = self 86 | let newMatrixCols = matrix.count 87 | let newMatrixRows = matrix.first?.count ?? 1 88 | 89 | var results = [Double](repeating: 0.0, count: newMatrixCols*newMatrixRows) 90 | 91 | vDSP_mtransD(matrix.flatMap { $0 }, 1, &results, 1, vDSP_Length(newMatrixRows), vDSP_Length(newMatrixCols)) 92 | 93 | return results.chunked(into: newMatrixCols) 94 | } 95 | 96 | func multiplyVector(matrix: [Element]) -> [Element] { 97 | let newMatrixCols = self.count 98 | let newMatrixRows = matrix.first?.count ?? 1 99 | 100 | var result = [Double](repeating: 0.0, count: newMatrixCols*newMatrixRows) 101 | 102 | let flatMatrix1 = self.flatMap { $0 } 103 | let flatMatrix2 = matrix.flatMap { $0 } 104 | 105 | for index in 0.. [Element] { 115 | let matrixRows = matrix.count 116 | let matrixCols = matrix.first?.count ?? 1 117 | 118 | let selfMatrixRows = self.count 119 | 120 | var result = [Double](repeating: 0.0, count: Int(selfMatrixRows * matrixCols)) 121 | 122 | let flatMatrix1 = self.flatMap { $0 } 123 | let flatMatrix2 = matrix.flatMap { $0 } 124 | 125 | vDSP_mmulD(flatMatrix1, 1, flatMatrix2, 1, &result, 1, vDSP_Length(selfMatrixRows), vDSP_Length(matrixCols), vDSP_Length(matrixRows)) 126 | 127 | return result.chunked(into: Int(matrixCols)) 128 | } 129 | } 130 | 131 | 132 | extension Array where Element == [(real: Double, imagine: Double)] { 133 | 134 | public var transposed: [Element] { 135 | let matrix = self 136 | let newMatrixCols = matrix.count 137 | let newMatrixRows = matrix.first?.count ?? 1 138 | 139 | var resultsCols = [[(real: Double, imagine: Double)]].init(repeating: [(real: Double, imagine: Double)](), count: newMatrixRows) 140 | 141 | for col in 0.. WAVFileDesriptor { 35 | let data = try Data(contentsOf: url) 36 | 37 | let dataSize = Int(data.count) 38 | 39 | return try data.withUnsafeBytes { rawPointer -> WAVFileDesriptor in 40 | let bytes = rawPointer.bindMemory(to: UInt8.self) 41 | 42 | let RIFFData = rawPointer.baseAddress.map { Data(bytes: $0, count: 4) } 43 | 44 | let RIFFLabel = RIFFData.map { String(data: $0, encoding: .utf8) } 45 | 46 | guard RIFFLabel == "RIFF" else { 47 | throw ReadError.fail 48 | } 49 | 50 | let chunkSize = rawPointer.load(fromByteOffset: 4, as: UInt32.self) - 36 51 | 52 | let WAVELabel = String(bytes: bytes[8..<12], encoding: .utf8) 53 | guard WAVELabel == "WAVE" else { 54 | throw ReadError.fail 55 | } 56 | 57 | let fmtLabel = String(bytes: bytes[12..<16], encoding: .utf8) 58 | guard fmtLabel == "fmt " else { 59 | throw ReadError.fail 60 | } 61 | 62 | _ = rawPointer.load(fromByteOffset: 16, as: Int32.self) 63 | 64 | let format = rawPointer.load(fromByteOffset: 20, as: Int16.self) 65 | guard format == 1 else { 66 | throw ReadError.nonPCM 67 | } 68 | 69 | let channels = rawPointer.load(fromByteOffset: 22, as: Int16.self) 70 | 71 | let sampleRate = rawPointer.load(fromByteOffset: 24, as: Int32.self) 72 | let byteRate = rawPointer.load(fromByteOffset: 28, as: Int32.self) 73 | 74 | guard byteRate/sampleRate == 2 || byteRate/sampleRate == 4 else { 75 | throw ReadError.supportOnly16bitChannel 76 | } 77 | 78 | var sampleSize: Int = 0 79 | 80 | if sampleRate == 22050 { 81 | sampleSize = 256 82 | } 83 | else if sampleRate == 44100 { 84 | sampleSize = 512 85 | } 86 | else if sampleRate == 48000 { 87 | sampleSize = 960 88 | } 89 | else { 90 | throw ReadError.nonSupportedSampleRate 91 | } 92 | 93 | _ = rawPointer.load(fromByteOffset: 30, as: Int16.self) 94 | let bytesPerSample = rawPointer.load(fromByteOffset: 32, as: Int16.self) 95 | 96 | let dataLabel = String(bytes: bytes[36..<40], encoding: .utf8) 97 | guard dataLabel == "data" else { 98 | throw ReadError.fail 99 | } 100 | 101 | let data = Data(bytes[44..<(44 + Int(min(chunkSize, UInt32(dataSize-44))))]) 102 | 103 | return WAVFileDesriptor(sampleRate: Int(sampleRate), bytesPerSample: Int(bytesPerSample), sampleSize: Int(sampleSize), channels: Int(channels), data: data) 104 | } 105 | 106 | } 107 | 108 | public func createWavFile(using rawData: Data, atURL url: URL, sampleRate: Int, channels: Int = 1) throws { 109 | //Prepare Wav file header 110 | let waveHeaderFormate = createWaveHeader(data: rawData, sampleRate: sampleRate, channels: channels) as Data 111 | 112 | //Prepare Final Wav File Data 113 | let waveFileData = waveHeaderFormate + rawData 114 | 115 | //Store Wav file in document directory. 116 | try storeMusicFile(data: waveFileData, atURL: url) 117 | } 118 | 119 | private func createWaveHeader(data: Data, sampleRate: Int, channels channelsCount: Int = 1) -> NSData { 120 | let sampleRate: Int32 = Int32(sampleRate) 121 | let chunkSize: Int32 = 36 + Int32(data.count) 122 | let subChunkSize: Int32 = 16 123 | let format: Int16 = 1 124 | let channels: Int16 = Int16(channelsCount) 125 | let bytesPerSample: Int16 = 16 126 | let byteRate: Int32 = sampleRate * Int32(channels * bytesPerSample / 8) 127 | let blockAlign: Int16 = channels * bytesPerSample / 8 128 | let dataSize: Int32 = Int32(data.count) 129 | 130 | let header = NSMutableData() 131 | 132 | header.append([UInt8]("RIFF".utf8), length: 4) 133 | header.append(intToByteArray(chunkSize), length: 4) 134 | 135 | //WAVE 136 | header.append([UInt8]("WAVE".utf8), length: 4) 137 | 138 | //FMT 139 | header.append([UInt8]("fmt ".utf8), length: 4) 140 | 141 | header.append(intToByteArray(subChunkSize), length: 4) 142 | header.append(shortToByteArray(format), length: 2) 143 | header.append(shortToByteArray(channels), length: 2) 144 | header.append(intToByteArray(sampleRate), length: 4) 145 | header.append(intToByteArray(byteRate), length: 4) 146 | header.append(shortToByteArray(blockAlign), length: 2) 147 | header.append(shortToByteArray(bytesPerSample), length: 2) 148 | 149 | header.append([UInt8]("data".utf8), length: 4) 150 | header.append(intToByteArray(dataSize), length: 4) 151 | 152 | return header 153 | } 154 | 155 | private func intToByteArray(_ integer: Int32) -> [UInt8] { 156 | return [ 157 | //little endian 158 | UInt8(truncatingIfNeeded: (integer) & 0xff), 159 | UInt8(truncatingIfNeeded: (integer >> 8) & 0xff), 160 | UInt8(truncatingIfNeeded: (integer >> 16) & 0xff), 161 | UInt8(truncatingIfNeeded: (integer >> 24) & 0xff) 162 | ] 163 | } 164 | 165 | private func shortToByteArray(_ integer: Int16) -> [UInt8] { 166 | return [ 167 | //little endian 168 | UInt8(truncatingIfNeeded: (integer) & 0xff), 169 | UInt8(truncatingIfNeeded: (integer >> 8) & 0xff) 170 | ] 171 | } 172 | 173 | func storeMusicFile(data: Data, atURL url: URL) throws { 174 | try data.write(to: url) 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample/Spectrogram/SpectrogramView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpectrogramView.swift 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 1/5/19. 6 | // Copyright © 2019 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Metal 11 | import MetalKit 12 | import RosaKit 13 | 14 | protocol SpectrogramViewDataSource: AnyObject { 15 | 16 | func elementsCountInSpectrogram(view: SpectrogramView) -> Int 17 | 18 | func elementsValueInSpectrogram(view: SpectrogramView, at index: Int) -> [Double] 19 | 20 | } 21 | 22 | class SpectrogramView: NSScrollView { 23 | 24 | let samplesMetalRenderer = SamplesMetalRenderer() 25 | 26 | @IBInspectable open var backgroundChartColor: NSColor = .black 27 | @IBInspectable open var chartLineColor: NSColor = .white 28 | 29 | private static let leftMarginToSnap: CGFloat = 20.0 30 | private static var labelWidth: CGFloat = 200.0 31 | 32 | var elementWidth: CGFloat = 20.0 33 | 34 | weak var delegate: SpectrogramViewDataSource? 35 | 36 | private var scrollNotificationHandler: NSObjectProtocol? 37 | 38 | private var metalView: MTKView? 39 | 40 | override func viewDidMoveToWindow() { 41 | super.viewDidMoveToWindow() 42 | 43 | samplesMetalRenderer.setup() 44 | 45 | initializeMetalView() 46 | 47 | scrollNotificationHandler.map { NotificationCenter.default.removeObserver($0) } 48 | scrollNotificationHandler = NotificationCenter.default.addObserver(forName: NSScrollView.didLiveScrollNotification, object: self, queue: .main) { [weak self] _ in 49 | self?.setNeedsDisplay(self?.bounds ?? .zero) 50 | } 51 | } 52 | 53 | private func initializeMetalView() { 54 | let metalView = MTLCreateSystemDefaultDevice().map { MTKView(frame: self.bounds, device: $0) } 55 | metalView?.delegate = self 56 | metalView?.framebufferOnly = false 57 | metalView?.colorPixelFormat = .bgra8Unorm 58 | metalView?.preferredFramesPerSecond = 30 59 | metalView?.enableSetNeedsDisplay = true 60 | metalView.map { self.addSubview($0) } 61 | 62 | self.metalView = metalView 63 | } 64 | 65 | func reloadData(magnitifyIfNeeded: Bool = true) { 66 | setNeedsDisplay(bounds) 67 | 68 | let elementsCount = delegate?.elementsCountInSpectrogram(view: self) ?? 0 69 | let documentSize = documentView?.frame.size ?? .zero 70 | 71 | let shouldMagnitityDelta = abs(contentView.bounds.maxX - documentSize.width) 72 | let shouldMagnitityToLeft = shouldMagnitityDelta <= SpectrogramView.leftMarginToSnap 73 | 74 | let documentWidth = max(elementWidth*CGFloat(elementsCount), frame.width) 75 | documentView?.setFrameSize(NSSize(width: documentWidth, height: documentSize.height)) 76 | 77 | if shouldMagnitityToLeft, magnitifyIfNeeded { 78 | let horizontalOffset = max(documentWidth - bounds.width, 0.0) 79 | contentView.bounds = contentView.bounds.offsetBy(dx: horizontalOffset, dy: 0.0) 80 | } 81 | else if !magnitifyIfNeeded { 82 | contentView.bounds = CGRect(origin: .zero, size: contentView.bounds.size) 83 | } 84 | layoutMetalView() 85 | } 86 | 87 | private func layoutMetalView() { 88 | self.samplesMetalRenderer.scaleFactor = Float(elementWidth) 89 | 90 | self.metalView?.frame = NSRect(origin: NSPoint(x: 0.0, y: 0.0), size: NSSize(width: frame.size.width, height: bounds.size.height - 40.0)) 91 | } 92 | 93 | override func resize(withOldSuperviewSize oldSize: NSSize) { 94 | super.resize(withOldSuperviewSize: oldSize) 95 | 96 | reloadData() 97 | } 98 | 99 | private func redrawSpectrogram() { 100 | let rect = self.documentVisibleRect 101 | 102 | let elementsCount = delegate?.elementsCountInSpectrogram(view: self) ?? 0 103 | 104 | guard elementsCount > 1 else { 105 | return 106 | } 107 | 108 | let startElement = Int(rect.origin.x/elementWidth) 109 | let endElement = Int(ceil(rect.maxX/elementWidth) + 1) 110 | 111 | guard startElement >= 0 else { 112 | return 113 | } 114 | 115 | guard startElement < endElement else { 116 | return 117 | } 118 | 119 | var bytes = [UInt8]() 120 | 121 | let cols = endElement - startElement - 1 122 | let items = delegate?.elementsValueInSpectrogram(view: self, at: 0) ?? [Double]() 123 | let rows = items.count 124 | 125 | for index in startElement...endElement-1 { 126 | let items = delegate?.elementsValueInSpectrogram(view: self, at: index) ?? [Double]() 127 | if items.count > 0 { 128 | for value in items { 129 | let dbValue = value*100 130 | bytes.append(UInt8(round(min(max(dbValue, 0), 255)))) 131 | } 132 | } 133 | else { 134 | bytes.append(contentsOf: [UInt8](repeating: 0, count: rows)) 135 | } 136 | } 137 | 138 | let texture = MTLCreateSystemDefaultDevice()?.createRedTexture(from: bytes, width: rows, height: cols) 139 | 140 | texture.map { 141 | samplesMetalRenderer.send(texture: $0) 142 | } 143 | 144 | metalView.map { 145 | $0.setNeedsDisplay($0.frame) 146 | } 147 | } 148 | 149 | override func draw(_ dirtyRect: NSRect) { 150 | super.draw(dirtyRect) 151 | 152 | redrawSpectrogram() 153 | 154 | let rect = self.documentVisibleRect 155 | 156 | let elementsCount = delegate?.elementsCountInSpectrogram(view: self) ?? 0 157 | 158 | guard elementsCount > 1 else { 159 | return 160 | } 161 | 162 | let startElement = abs(Int(rect.origin.x/elementWidth)) 163 | let endElement = min(Int(ceil(rect.maxX/elementWidth) + 1), elementsCount) 164 | 165 | guard startElement < endElement else { 166 | return 167 | } 168 | 169 | let dateFormatter = DateFormatter() 170 | dateFormatter.timeZone = TimeZone(secondsFromGMT: 0) 171 | dateFormatter.dateFormat = "mm:ss" 172 | 173 | let offset = contentView.bounds.origin.x 174 | let localOffset = offset 175 | 176 | let globalOffset = offset 177 | 178 | let strideBy = Int(SpectrogramView.labelWidth) 179 | let audioLength = localOffset + contentView.bounds.width 180 | 181 | let range = stride(from: CGFloat(0.0), through: audioLength, by: CGFloat.Stride(strideBy)) 182 | for position in range { 183 | let point = NSPoint(x: (position - globalOffset).truncatingRemainder(dividingBy: contentView.bounds.width), y: bounds.height - 25.0) 184 | 185 | let timeInterval = TimeInterval(position/(15500.0))/TimeInterval(elementWidth/SpectrogramView.labelWidth) 186 | let date = Date(timeIntervalSince1970: timeInterval) 187 | 188 | let timeString = dateFormatter.string(from: date) 189 | 190 | (timeString as NSString).draw(at: point, withAttributes: [NSAttributedString.Key.foregroundColor: chartLineColor]) 191 | } 192 | } 193 | 194 | } 195 | 196 | extension SpectrogramView: MTKViewDelegate { 197 | 198 | func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) { 199 | 200 | } 201 | 202 | func draw(in view: MTKView) { 203 | guard let currentRenderPassDescriptor = view.currentRenderPassDescriptor, 204 | let currentDrawable = view.currentDrawable 205 | else { 206 | return 207 | } 208 | 209 | samplesMetalRenderer.render(with: currentRenderPassDescriptor, drawable: currentDrawable) 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample/Spectrogram/SpectrogramView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpectrogramView.swift 3 | // RosaKitExample 4 | // 5 | // Created by Dmytro Hrebeniuk on 1/5/19. 6 | // Copyright © 2019 Dmytro Hrebeniuk. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Metal 11 | import MetalKit 12 | import RosaKit 13 | 14 | protocol SpectrogramViewDataSource: class { 15 | 16 | func elementsCountInSpectrogram(view: SpectrogramView) -> Int 17 | 18 | func elementsValueInSpectrogram(view: SpectrogramView, at index: Int) -> [Double] 19 | 20 | } 21 | 22 | class SpectrogramView: NSScrollView { 23 | 24 | let samplesMetalRenderer = SamplesMetalRenderer() 25 | 26 | @IBInspectable open var backgroundChartColor: NSColor = .black 27 | @IBInspectable open var chartLineColor: NSColor = .white 28 | 29 | private static let leftMarginToSnap: CGFloat = 20.0 30 | private static var labelWidth: CGFloat = 200.0 31 | 32 | var elementWidth: CGFloat = 20.0 33 | 34 | weak var delegate: SpectrogramViewDataSource? 35 | 36 | private var scrollNotificationHandler: NSObjectProtocol? 37 | 38 | private var metalView: MTKView? 39 | 40 | override func viewDidMoveToWindow() { 41 | super.viewDidMoveToWindow() 42 | 43 | samplesMetalRenderer.setup() 44 | 45 | initializeMetalView() 46 | 47 | scrollNotificationHandler.map { NotificationCenter.default.removeObserver($0) } 48 | scrollNotificationHandler = NotificationCenter.default.addObserver(forName: NSScrollView.didLiveScrollNotification, object: self, queue: .main) { [weak self] _ in 49 | self?.setNeedsDisplay(self?.bounds ?? .zero) 50 | } 51 | } 52 | 53 | private func initializeMetalView() { 54 | let metalView = MTLCreateSystemDefaultDevice().map { MTKView(frame: self.bounds, device: $0) } 55 | metalView?.delegate = self 56 | metalView?.framebufferOnly = false 57 | metalView?.colorPixelFormat = .bgra8Unorm 58 | metalView?.preferredFramesPerSecond = 30 59 | metalView?.enableSetNeedsDisplay = true 60 | metalView.map { self.addSubview($0) } 61 | 62 | self.metalView = metalView 63 | } 64 | 65 | func reloadData(magnitifyIfNeeded: Bool = true) { 66 | setNeedsDisplay(bounds) 67 | 68 | let elementsCount = delegate?.elementsCountInSpectrogram(view: self) ?? 0 69 | let documentSize = documentView?.frame.size ?? .zero 70 | 71 | let shouldMagnitityDelta = abs(contentView.bounds.maxX - documentSize.width) 72 | let shouldMagnitityToLeft = shouldMagnitityDelta <= SpectrogramView.leftMarginToSnap 73 | 74 | let documentWidth = max(elementWidth*CGFloat(elementsCount), frame.width) 75 | documentView?.setFrameSize(NSSize(width: documentWidth, height: documentSize.height)) 76 | 77 | if shouldMagnitityToLeft, magnitifyIfNeeded { 78 | let horizontalOffset = max(documentWidth - bounds.width, 0.0) 79 | contentView.bounds = contentView.bounds.offsetBy(dx: horizontalOffset, dy: 0.0) 80 | } 81 | else if !magnitifyIfNeeded { 82 | contentView.bounds = CGRect(origin: .zero, size: contentView.bounds.size) 83 | } 84 | layoutMetalView() 85 | } 86 | 87 | private func layoutMetalView() { 88 | self.samplesMetalRenderer.scaleFactor = Float(elementWidth) 89 | 90 | self.metalView?.frame = NSRect(origin: NSPoint(x: 0.0, y: 0.0), size: NSSize(width: frame.size.width, height: bounds.size.height - 40.0)) 91 | } 92 | 93 | override func resize(withOldSuperviewSize oldSize: NSSize) { 94 | super.resize(withOldSuperviewSize: oldSize) 95 | 96 | reloadData() 97 | } 98 | 99 | private func redrawSpectrogram() { 100 | let rect = self.documentVisibleRect 101 | 102 | let elementsCount = delegate?.elementsCountInSpectrogram(view: self) ?? 0 103 | 104 | guard elementsCount > 1 else { 105 | return 106 | } 107 | 108 | let startElement = Int(rect.origin.x/elementWidth) 109 | let endElement = Int(ceil(rect.maxX/elementWidth) + 1) 110 | 111 | guard startElement >= 0 else { 112 | return 113 | } 114 | 115 | guard startElement < endElement else { 116 | return 117 | } 118 | 119 | var bytes = [UInt8]() 120 | 121 | let cols = endElement - startElement - 1 122 | let items = delegate?.elementsValueInSpectrogram(view: self, at: 0) ?? [Double]() 123 | let rows = items.count 124 | 125 | for index in startElement...endElement-1 { 126 | let items = delegate?.elementsValueInSpectrogram(view: self, at: index) ?? [Double]() 127 | if items.count > 0 { 128 | for value in items { 129 | if value.isNaN == false { 130 | let dbValue = value*100 131 | bytes.append(UInt8(round(min(max(dbValue, 0), 255)))) 132 | } 133 | else { 134 | bytes.append(0) 135 | } 136 | } 137 | } 138 | else { 139 | bytes.append(contentsOf: [UInt8](repeating: 0, count: rows)) 140 | } 141 | } 142 | 143 | let texture = MTLCreateSystemDefaultDevice()?.createRedTexture(from: bytes, width: rows, height: cols) 144 | 145 | texture.map { 146 | samplesMetalRenderer.send(texture: $0) 147 | } 148 | 149 | metalView.map { 150 | $0.setNeedsDisplay($0.frame) 151 | } 152 | } 153 | 154 | override func draw(_ dirtyRect: NSRect) { 155 | super.draw(dirtyRect) 156 | 157 | redrawSpectrogram() 158 | 159 | let rect = self.documentVisibleRect 160 | 161 | let elementsCount = delegate?.elementsCountInSpectrogram(view: self) ?? 0 162 | 163 | guard elementsCount > 1 else { 164 | return 165 | } 166 | 167 | let startElement = abs(Int(rect.origin.x/elementWidth)) 168 | let endElement = min(Int(ceil(rect.maxX/elementWidth) + 1), elementsCount) 169 | 170 | guard startElement < endElement else { 171 | return 172 | } 173 | 174 | let dateFormatter = DateFormatter() 175 | dateFormatter.timeZone = TimeZone(secondsFromGMT: 0) 176 | dateFormatter.dateFormat = "mm:ss" 177 | 178 | let offset = contentView.bounds.origin.x 179 | let localOffset = offset 180 | 181 | let globalOffset = offset 182 | 183 | let strideBy = Int(SpectrogramView.labelWidth) 184 | let audioLength = localOffset + contentView.bounds.width 185 | 186 | let range = stride(from: CGFloat(0.0), through: audioLength, by: CGFloat.Stride(strideBy)) 187 | for position in range { 188 | let point = NSPoint(x: (position - globalOffset).truncatingRemainder(dividingBy: contentView.bounds.width), y: bounds.height - 25.0) 189 | 190 | let timeInterval = TimeInterval(position/(15500.0))/TimeInterval(elementWidth/SpectrogramView.labelWidth) 191 | let date = Date(timeIntervalSince1970: timeInterval) 192 | 193 | let timeString = dateFormatter.string(from: date) 194 | 195 | (timeString as NSString).draw(at: point, withAttributes: [NSAttributedString.Key.foregroundColor: chartLineColor]) 196 | } 197 | } 198 | 199 | } 200 | 201 | extension SpectrogramView: MTKViewDelegate { 202 | 203 | func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) { 204 | 205 | } 206 | 207 | func draw(in view: MTKView) { 208 | guard let currentRenderPassDescriptor = view.currentRenderPassDescriptor, 209 | let currentDrawable = view.currentDrawable 210 | else { 211 | return 212 | } 213 | 214 | samplesMetalRenderer.render(with: currentRenderPassDescriptor, drawable: currentDrawable) 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /Example/Soundrecognizer/SoundRecognizer/Source/Screens/Main/MainViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewModel.swift 3 | // SoundRecognizer 4 | // 5 | // Created by Hrebeniuk Dmytro on 27.12.2019. 6 | // Copyright © 2019 Hrebeniuk Dmytro. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Combine 11 | import CoreML 12 | import RosaKit 13 | import ZIPFoundation 14 | 15 | struct ProblemPredition { 16 | 17 | let fileName: String 18 | let predictedCategory: Int 19 | let targetCategory: Int 20 | let percentage: Double 21 | let waveWindow: [Double] 22 | 23 | } 24 | 25 | extension ProblemPredition: Equatable { 26 | 27 | static func == (lhs: ProblemPredition, rhs: ProblemPredition) -> Bool { 28 | return lhs.fileName == rhs.fileName 29 | && lhs.predictedCategory == rhs.predictedCategory 30 | && lhs.targetCategory == rhs.targetCategory 31 | && lhs.percentage == rhs.percentage 32 | && lhs.waveWindow == rhs.waveWindow 33 | } 34 | 35 | } 36 | 37 | extension ProblemPredition: Hashable { 38 | 39 | func hash(into hasher: inout Hasher) { 40 | hasher.combine(fileName) 41 | hasher.combine(targetCategory) 42 | hasher.combine(predictedCategory) 43 | hasher.combine(percentage) 44 | hasher.combine(waveWindow) 45 | } 46 | 47 | } 48 | 49 | 50 | enum MainViewModelState { 51 | 52 | case initial 53 | 54 | case downloading 55 | 56 | case unzip 57 | 58 | case processing 59 | 60 | } 61 | 62 | class MainViewModel: ObservableObject { 63 | 64 | @Published var state: MainViewModelState = .initial 65 | 66 | @Published var percentageProceccesed: Double = 0.0 67 | @Published var percentageValid: Double = 0.0 68 | @Published var percentageInvalid: Double = 0.0 69 | 70 | @Published var problemPreditions: [ProblemPredition] = [] 71 | 72 | private var samplesCollection: [Double] = [] 73 | 74 | let soundRecognizerEngine = SoundRecognizerEngine(sampleRate: 44100, windowLength: 2048*20) 75 | 76 | @Published var showFileExportPicker = false 77 | @Published var fileExportURL: URL = URL(fileURLWithPath: "/") 78 | 79 | private func downloadDataset(to archiveURL: URL) async throws { 80 | let urbanSoundDataURL = URL(string: "https://github.com/karoldvl/ESC-50/archive/master.zip") 81 | return try await withUnsafeThrowingContinuation() { continuation in 82 | let downloadTask = urbanSoundDataURL.map { URLSession.shared.downloadTask(with: $0) { tempFileURL, _, error in 83 | if let networkError = error { 84 | continuation.resume(throwing: networkError) 85 | } 86 | else if let url = tempFileURL { 87 | try? FileManager.default.moveItem(at: url, to: archiveURL) 88 | continuation.resume() 89 | } 90 | }} 91 | downloadTask?.resume() 92 | } 93 | } 94 | 95 | func copyWave(toClipboard problemPrediction: ProblemPredition) { 96 | let content = problemPrediction.waveWindow.description 97 | if let fileURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first?.appendingPathComponent("Wave_ \(problemPrediction.targetCategory).json") { 98 | try? content.write(to: fileURL, atomically: true, encoding: .utf8) 99 | self.fileExportURL = fileURL 100 | self.showFileExportPicker = true 101 | } 102 | } 103 | 104 | func copySTFT(toClipboard problemPrediction: ProblemPredition) { 105 | let spectrogram = problemPrediction.waveWindow.stft(nFFT: 1024, hopLength: 512).map { $0.map { pow($0.real, 2.0) + pow($0.imagine, 2.0) } } 106 | let sampleRate = 44100 107 | let melBasis = [Double].createMelFilter(sampleRate: sampleRate, FTTCount: 1024, melsCount: 128) 108 | 109 | let melSpectrogram = melBasis.dot(matrix: spectrogram) 110 | 111 | let content = melSpectrogram.description 112 | if let fileURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first?.appendingPathComponent("stft_\(problemPrediction.targetCategory).json") { 113 | try? content.write(to: fileURL, atomically: true, encoding: .utf8) 114 | self.fileExportURL = fileURL 115 | self.showFileExportPicker = true 116 | } 117 | } 118 | 119 | func setup() { 120 | guard let cachesURL = FileManager.default.urls(for: FileManager.SearchPathDirectory.cachesDirectory, in: .userDomainMask).first else { return } 121 | let archiveCacheURL = cachesURL.appendingPathComponent("master.zip") 122 | let datasetURL = cachesURL.appendingPathComponent("ESC-50-master") 123 | 124 | self.state = .downloading 125 | Task { 126 | if FileManager.default.fileExists(atPath: archiveCacheURL.path) == false { 127 | try? await downloadDataset(to: archiveCacheURL) 128 | } 129 | 130 | DispatchQueue.main.sync { 131 | self.state = .unzip 132 | } 133 | 134 | if FileManager.default.fileExists(atPath: datasetURL.path) == false { 135 | try? FileManager.default.unzipItem(at: archiveCacheURL, to: cachesURL) 136 | } 137 | 138 | DispatchQueue.main.sync { 139 | self.state = .processing 140 | } 141 | 142 | let metaURL = datasetURL.appendingPathComponent("meta/esc50.csv") 143 | let content = try? String(contentsOf: metaURL) 144 | var lines = content?.split(separator: "\n") 145 | lines?.removeFirst() 146 | 147 | let metaData = lines.map { $0.map { $0.split(separator: ",") }.map { (fileName: $0[0], taget:Int($0[2]) ?? 0) } } 148 | 149 | let windowLength = 110250 150 | 151 | let soundRecognizerEngine = SoundRecognizerEngine(sampleRate: 44100, windowLength: windowLength) 152 | let items = metaData ?? [] 153 | for item in items { 154 | autoreleasepool { 155 | let url = datasetURL.appendingPathComponent("audio").appendingPathComponent(String(item.fileName)) 156 | let soundFile = try? WavFileManager().readWavFile(at: url) 157 | let int16Array = soundFile?.data.int16Array.map { Double($0)/32768.0 } 158 | 159 | let samplesCount = int16Array?.count ?? 0 160 | if samplesCount >= windowLength { 161 | let window = 0.5 162 | let overlap = 0.5 163 | let chunk = (Double(samplesCount) * window) 164 | let offset = Int(chunk * (1.0 - overlap)) 165 | 166 | let windowsCount = (samplesCount - (windowLength - offset))/offset 167 | 168 | let targetCategory = item.taget 169 | 170 | var preditedCategories = [Int]() 171 | var preditedCategoriesPercentages = [Double]() 172 | for index in 0.. [Element] { 18 | return [Element].linespace(start: 0, stop: Element(sampleRate)/Element(2), num: Element(1 + FTTCount/2)) 19 | } 20 | 21 | static func createMELFrequencies(MELCount: Int, fmin: Element, fmax: Element) -> [Element] { 22 | let minMEL = Element.MEL(fromHZ: fmin) 23 | let maxMEL = Element.MEL(fromHZ: fmax) 24 | 25 | let mels = [Element].linespace(start: minMEL, stop: maxMEL, num: Element(MELCount)) 26 | 27 | return mels.map { Element.HZ(fromMEL: $0) } 28 | } 29 | 30 | static func createMelFilter(sampleRate: Int, FTTCount: Int, melsCount: Int = 128) -> [[Element]] { 31 | let fmin = Element(0) 32 | let fmax = Element(sampleRate) / 2 33 | 34 | var weights = [Element].empty(width: melsCount, height: 1 + FTTCount/2, defaultValue: Element(0)) 35 | 36 | let FFTFreqs = [Element].createFFTFrequencies(sampleRate: sampleRate, FTTCount: FTTCount) 37 | 38 | let MELFreqs = [Element].createMELFrequencies(MELCount: melsCount + 2, fmin: fmin, fmax: fmax) 39 | 40 | let diff = MELFreqs.diff 41 | 42 | let ramps = MELFreqs.outerSubstract(array: FFTFreqs) 43 | 44 | for index in 0.. [Element] { 60 | let ten = Element(10) 61 | 62 | let logSpec = map { ten * (Swift.max(amin, $0)).logarithm10() - ten * (Swift.max(amin, abs(ref))).logarithm10() } 63 | 64 | let maximum = (logSpec.max() ?? Element(0)) 65 | 66 | return logSpec.map { Swift.max($0, maximum - topDB) } 67 | } 68 | 69 | func normalizeAudioPower() -> [Element] { 70 | var dbValues = powerToDB() 71 | 72 | let minimum = (dbValues.min() ?? Element(0)) 73 | dbValues = dbValues.map { $0 - minimum} 74 | let maximun = (dbValues.map { abs($0) }.max() ?? Element(0)) 75 | dbValues = dbValues.map { $0/(maximun + Element(1)) } 76 | return dbValues 77 | } 78 | } 79 | 80 | public extension Array where Element == Double { 81 | 82 | func stft(nFFT: Int = 256, hopLength: Int = 1024, isAccelerated: Bool = false) -> [[(real: Double, imagine: Double)]] { 83 | let FFTWindow = [Double].getHannWindow(frameLength: (nFFT)).map { [$0] } 84 | 85 | let centered = self.reflectPad(fftSize: nFFT) 86 | 87 | let yFrames = centered.frame(frameLength: nFFT, hopLength: hopLength) 88 | 89 | let matrix = FFTWindow.multiplyVector(matrix: yFrames) 90 | 91 | let rfftMatrix = isAccelerated ? matrix.acceleratedRFFT : matrix.rfft 92 | 93 | let result = rfftMatrix 94 | 95 | return result 96 | } 97 | 98 | func melspectrogram(nFFT: Int = 2048, hopLength: Int = 512, sampleRate: Int = 22050, melsCount: Int = 128) -> [[Double]] { 99 | let spectrogram = self.stft(nFFT: nFFT, hopLength: hopLength) 100 | .map { $0.map { sqrt(pow($0.real, 2.0) + pow($0.imagine, 2.0)) } } 101 | let melBasis = [Double].createMelFilter(sampleRate: sampleRate, FTTCount: nFFT, melsCount: melsCount) 102 | return melBasis.dot(matrix: spectrogram) 103 | } 104 | 105 | func mfcc(nMFCC: Int = 20, nFFT: Int = 2048, hopLength: Int = 512, sampleRate: Int = 22050, melsCount: Int = 128) -> [[Double]] { 106 | let melSpectrogram = self.melspectrogram(nFFT: nFFT, hopLength: hopLength, sampleRate: sampleRate, melsCount: melsCount) 107 | var S = melSpectrogram.map { $0.powerToDB() } 108 | 109 | let cols = S.count 110 | let rows = S[0].count 111 | 112 | var resultArray = [Double](repeating: 0.0, count: cols*rows) 113 | 114 | S.withUnsafeMutableBytes { flatData -> Void in 115 | let sourceDoubleData = flatData.bindMemory(to: Double.self).baseAddress 116 | 117 | resultArray.withUnsafeMutableBytes { destinationData -> Void in 118 | let destinationDoubleData = destinationData.bindMemory(to: Double.self).baseAddress 119 | 120 | PocketFFTRunner.execute_dct(sourceDoubleData, result: destinationDoubleData, dctType: 2, inorm: 1, cols: Int32(cols), rows: Int32(rows)) 121 | } 122 | } 123 | 124 | let mfccResult = resultArray.chunked(into: rows)[0.. [Double] { 134 | let nFFT = 2 * (self.count - 1) 135 | let winLength = nFFT 136 | let hopLength = inputHopLength ?? winLength / 4 137 | 138 | let iFFTWindow = [Double].getHannWindow(frameLength: nFFT).map { [$0] } 139 | 140 | let nFramesCount = self[0].count 141 | 142 | let expectedSignalLen = nFFT + hopLength * (nFramesCount - 1) 143 | 144 | let nCollumns = (4096 * MemoryLayout.size) / self.count 145 | 146 | var y = Array(repeating: 0.0, count: expectedSignalLen) 147 | 148 | var frame = 0 149 | 150 | for index in 0...(nFramesCount / nCollumns) { 151 | let blS = index * nCollumns 152 | let blT = Swift.min(blS + nCollumns, nFramesCount) 153 | 154 | let size = blT - blS 155 | var resultArray = Array(repeating: 0.0, count: size*self.count) 156 | 157 | let norm = nFFT 158 | let fct = 1.0 / Double(nFFT) 159 | 160 | let trimmedMatrix = self.map { Array<(real: Double, imagine: Double)>($0[blS.. Double.leastNonzeroMagnitude { 184 | y[index] /= (winSQ[index]); 185 | } 186 | } 187 | 188 | return y 189 | } 190 | 191 | var irfft: [[Double]] { 192 | let invNorm = (self.count - 1) * 2 193 | let cols = self.count 194 | let rows = self.first?.count ?? 0 195 | 196 | var slicedMatrix = Array>(repeating: Array<(real: Double, imagine: Double)>(repeating: (real: 0.0, imagine: 0.0), count: rows), count: invNorm); 197 | 198 | for colIndex in 0.. Void in 212 | let stftChunkDataDoubleData = stftChunkData.bindMemory(to: Double.self).baseAddress 213 | resultArray.withUnsafeMutableBytes { (resultArrayFlatData) -> Void in 214 | let destinationDoubleData = resultArrayFlatData.bindMemory(to: Double.self).baseAddress 215 | execute_real_backward(stftChunkDataDoubleData, destinationDoubleData, npy_intp(slicedMatrix.count), npy_intp(slicedMatrix.first?.count ?? 0), fct) 216 | } 217 | } 218 | 219 | let backSTFT = resultArray.chunked(into: slicedMatrix.first?.count ?? 0) 220 | 221 | let backSTFTTransposed = backSTFT.transposed 222 | 223 | return backSTFTTransposed 224 | } 225 | } 226 | 227 | extension Array where Element == [Double] { 228 | 229 | var acceleratedRFFT: [[(real: Double, imagine: Double)]] { 230 | let newMatrixCols = self.first?.count ?? 1 231 | let newMatrixRows = self.count 232 | 233 | let rfftRows = newMatrixRows/2 + 1 234 | let rfftCount = rfftRows*newMatrixCols + newMatrixCols + 1 235 | 236 | let flatMatrix = self.transposed.flatMap { return $0 } 237 | 238 | let size = (1 + newMatrixCols/2)*newMatrixRows 239 | let length = vDSP_Length(pow(2, floor(log2(Float(size))))) 240 | 241 | let setup = vDSP_DFT_zop_CreateSetupD(nil, length, vDSP_DFT_Direction.FORWARD) 242 | 243 | let inputImaginary = [Double](repeating: 0.0, count: rfftCount) 244 | var outputImaginary = [Double](repeating: 0.0, count: rfftCount) 245 | var outputReal = [Double](repeating: 0.0, count: rfftCount) 246 | 247 | vDSP_DFT_ExecuteD(setup!, flatMatrix, inputImaginary, &outputReal, &outputImaginary) 248 | 249 | let resultRealMatrix = outputReal.chunked(into: newMatrixCols) 250 | let resultImagineMatrix = outputImaginary.chunked(into: newMatrixCols) 251 | 252 | var result = [[(real: Double, imagine: Double)]]() 253 | for row in 0.. Void in 278 | let destinationDoubleData = destinationData.bindMemory(to: Double.self).baseAddress 279 | flatMatrix.withUnsafeMutableBytes { (flatData) -> Void in 280 | let sourceDoubleData = flatData.bindMemory(to: Double.self).baseAddress 281 | execute_real_forward(sourceDoubleData, destinationDoubleData, npy_intp(Int32(cols)), npy_intp(Int32(rows)), 1) 282 | } 283 | } 284 | 285 | var realMatrix = [Double](repeating: 0.0, count: rfftCount) 286 | var imagineMatrix = [Double](repeating: 0.0, count: rfftCount) 287 | 288 | for index in 0.. [[Double]] { 314 | let chunkSize = self.first?.count ?? 0 315 | let dbValues = self.flatMap { $0 }.normalizeAudioPower().chunked(into: chunkSize) 316 | return dbValues 317 | } 318 | } 319 | -------------------------------------------------------------------------------- /Example/RosaKitExample/RosaKitExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | CC6CFB060E74375D663F7D29 /* Pods_RosaKitExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A69EE509E49D020FACDBF822 /* Pods_RosaKitExample.framework */; }; 11 | EBF4BEDD248EE7AF00C6F6B0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BEDC248EE7AF00C6F6B0 /* AppDelegate.swift */; }; 12 | EBF4BEDF248EE7AF00C6F6B0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BEDE248EE7AF00C6F6B0 /* ViewController.swift */; }; 13 | EBF4BEE1248EE7B400C6F6B0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EBF4BEE0248EE7B400C6F6B0 /* Assets.xcassets */; }; 14 | EBF4BEE4248EE7B400C6F6B0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EBF4BEE2248EE7B400C6F6B0 /* Main.storyboard */; }; 15 | EBF4BEED248EE7E500C6F6B0 /* test.wav in Resources */ = {isa = PBXBuildFile; fileRef = EBF4BEEC248EE7E500C6F6B0 /* test.wav */; }; 16 | EBF4BEF4248EE86300C6F6B0 /* SpectrogramViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BEF1248EE86200C6F6B0 /* SpectrogramViewController.swift */; }; 17 | EBF4BEF8248EE88100C6F6B0 /* SpectrogramView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BEF7248EE88100C6F6B0 /* SpectrogramView.swift */; }; 18 | EBF4BF06248EEB5C00C6F6B0 /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BF01248EEB5B00C6F6B0 /* Shaders.metal */; }; 19 | EBF4BF07248EEB5C00C6F6B0 /* CommonUtils.metal in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BF03248EEB5B00C6F6B0 /* CommonUtils.metal */; }; 20 | EBF4BF08248EEB5C00C6F6B0 /* MTLTextureExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BF04248EEB5C00C6F6B0 /* MTLTextureExtensions.swift */; }; 21 | EBF4BF09248EEB5C00C6F6B0 /* SamplesRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BF05248EEB5C00C6F6B0 /* SamplesRenderer.swift */; }; 22 | EBF4BF0B248EEBA400C6F6B0 /* MTLDeviceExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BF0A248EEBA400C6F6B0 /* MTLDeviceExtensions.swift */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 427DD64D5279FC54D40AD1BE /* Pods-RosaKitExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RosaKitExample.debug.xcconfig"; path = "Target Support Files/Pods-RosaKitExample/Pods-RosaKitExample.debug.xcconfig"; sourceTree = ""; }; 27 | A69EE509E49D020FACDBF822 /* Pods_RosaKitExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RosaKitExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | EBF4BED9248EE7AF00C6F6B0 /* RosaKitExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RosaKitExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | EBF4BEDC248EE7AF00C6F6B0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 30 | EBF4BEDE248EE7AF00C6F6B0 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 31 | EBF4BEE0248EE7B400C6F6B0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 32 | EBF4BEE3248EE7B400C6F6B0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 33 | EBF4BEE5248EE7B400C6F6B0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 34 | EBF4BEE6248EE7B400C6F6B0 /* RosaKitExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RosaKitExample.entitlements; sourceTree = ""; }; 35 | EBF4BEEC248EE7E500C6F6B0 /* test.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = test.wav; sourceTree = ""; }; 36 | EBF4BEF1248EE86200C6F6B0 /* SpectrogramViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpectrogramViewController.swift; sourceTree = ""; }; 37 | EBF4BEF7248EE88100C6F6B0 /* SpectrogramView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpectrogramView.swift; sourceTree = ""; }; 38 | EBF4BF01248EEB5B00C6F6B0 /* Shaders.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Shaders.metal; sourceTree = ""; }; 39 | EBF4BF02248EEB5B00C6F6B0 /* CommonUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonUtils.h; sourceTree = ""; }; 40 | EBF4BF03248EEB5B00C6F6B0 /* CommonUtils.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = CommonUtils.metal; sourceTree = ""; }; 41 | EBF4BF04248EEB5C00C6F6B0 /* MTLTextureExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTLTextureExtensions.swift; sourceTree = ""; }; 42 | EBF4BF05248EEB5C00C6F6B0 /* SamplesRenderer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SamplesRenderer.swift; sourceTree = ""; }; 43 | EBF4BF0A248EEBA400C6F6B0 /* MTLDeviceExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTLDeviceExtensions.swift; sourceTree = ""; }; 44 | F91367C50922BBA1E748553A /* Pods-RosaKitExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RosaKitExample.release.xcconfig"; path = "Target Support Files/Pods-RosaKitExample/Pods-RosaKitExample.release.xcconfig"; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | EBF4BED6248EE7AF00C6F6B0 /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | CC6CFB060E74375D663F7D29 /* Pods_RosaKitExample.framework in Frameworks */, 53 | ); 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | /* End PBXFrameworksBuildPhase section */ 57 | 58 | /* Begin PBXGroup section */ 59 | 7901FAC5324E9909E3787037 /* Frameworks */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | A69EE509E49D020FACDBF822 /* Pods_RosaKitExample.framework */, 63 | ); 64 | name = Frameworks; 65 | sourceTree = ""; 66 | }; 67 | E96B08C8C5CCFC0D7FF8A3CB /* Pods */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 427DD64D5279FC54D40AD1BE /* Pods-RosaKitExample.debug.xcconfig */, 71 | F91367C50922BBA1E748553A /* Pods-RosaKitExample.release.xcconfig */, 72 | ); 73 | path = Pods; 74 | sourceTree = ""; 75 | }; 76 | EBF4BED0248EE7AF00C6F6B0 = { 77 | isa = PBXGroup; 78 | children = ( 79 | EBF4BEDB248EE7AF00C6F6B0 /* RosaKitExample */, 80 | EBF4BEDA248EE7AF00C6F6B0 /* Products */, 81 | E96B08C8C5CCFC0D7FF8A3CB /* Pods */, 82 | 7901FAC5324E9909E3787037 /* Frameworks */, 83 | ); 84 | sourceTree = ""; 85 | }; 86 | EBF4BEDA248EE7AF00C6F6B0 /* Products */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | EBF4BED9248EE7AF00C6F6B0 /* RosaKitExample.app */, 90 | ); 91 | name = Products; 92 | sourceTree = ""; 93 | }; 94 | EBF4BEDB248EE7AF00C6F6B0 /* RosaKitExample */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | EBF4BF00248EEB3F00C6F6B0 /* RenderingEngine */, 98 | EBF4BEF0248EE85500C6F6B0 /* Spectrogram */, 99 | EBF4BEDC248EE7AF00C6F6B0 /* AppDelegate.swift */, 100 | EBF4BEDE248EE7AF00C6F6B0 /* ViewController.swift */, 101 | EBF4BEE0248EE7B400C6F6B0 /* Assets.xcassets */, 102 | EBF4BEE2248EE7B400C6F6B0 /* Main.storyboard */, 103 | EBF4BEE5248EE7B400C6F6B0 /* Info.plist */, 104 | EBF4BEEC248EE7E500C6F6B0 /* test.wav */, 105 | EBF4BEE6248EE7B400C6F6B0 /* RosaKitExample.entitlements */, 106 | ); 107 | path = RosaKitExample; 108 | sourceTree = ""; 109 | }; 110 | EBF4BEF0248EE85500C6F6B0 /* Spectrogram */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | EBF4BEF7248EE88100C6F6B0 /* SpectrogramView.swift */, 114 | EBF4BEF1248EE86200C6F6B0 /* SpectrogramViewController.swift */, 115 | ); 116 | path = Spectrogram; 117 | sourceTree = ""; 118 | }; 119 | EBF4BF00248EEB3F00C6F6B0 /* RenderingEngine */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | EBF4BF02248EEB5B00C6F6B0 /* CommonUtils.h */, 123 | EBF4BF03248EEB5B00C6F6B0 /* CommonUtils.metal */, 124 | EBF4BF04248EEB5C00C6F6B0 /* MTLTextureExtensions.swift */, 125 | EBF4BF05248EEB5C00C6F6B0 /* SamplesRenderer.swift */, 126 | EBF4BF01248EEB5B00C6F6B0 /* Shaders.metal */, 127 | EBF4BF0A248EEBA400C6F6B0 /* MTLDeviceExtensions.swift */, 128 | ); 129 | path = RenderingEngine; 130 | sourceTree = ""; 131 | }; 132 | /* End PBXGroup section */ 133 | 134 | /* Begin PBXNativeTarget section */ 135 | EBF4BED8248EE7AF00C6F6B0 /* RosaKitExample */ = { 136 | isa = PBXNativeTarget; 137 | buildConfigurationList = EBF4BEE9248EE7B400C6F6B0 /* Build configuration list for PBXNativeTarget "RosaKitExample" */; 138 | buildPhases = ( 139 | DF179311DDD055328BEE94F3 /* [CP] Check Pods Manifest.lock */, 140 | EBF4BED5248EE7AF00C6F6B0 /* Sources */, 141 | EBF4BED6248EE7AF00C6F6B0 /* Frameworks */, 142 | EBF4BED7248EE7AF00C6F6B0 /* Resources */, 143 | DDC0F1265033247A3B5E8FD5 /* [CP] Embed Pods Frameworks */, 144 | ); 145 | buildRules = ( 146 | ); 147 | dependencies = ( 148 | ); 149 | name = RosaKitExample; 150 | productName = RosaKitExample; 151 | productReference = EBF4BED9248EE7AF00C6F6B0 /* RosaKitExample.app */; 152 | productType = "com.apple.product-type.application"; 153 | }; 154 | /* End PBXNativeTarget section */ 155 | 156 | /* Begin PBXProject section */ 157 | EBF4BED1248EE7AF00C6F6B0 /* Project object */ = { 158 | isa = PBXProject; 159 | attributes = { 160 | LastSwiftUpdateCheck = 1150; 161 | LastUpgradeCheck = 1150; 162 | ORGANIZATIONNAME = "Hrebeniuk Dmytro"; 163 | TargetAttributes = { 164 | EBF4BED8248EE7AF00C6F6B0 = { 165 | CreatedOnToolsVersion = 11.5; 166 | }; 167 | }; 168 | }; 169 | buildConfigurationList = EBF4BED4248EE7AF00C6F6B0 /* Build configuration list for PBXProject "RosaKitExample" */; 170 | compatibilityVersion = "Xcode 9.3"; 171 | developmentRegion = en; 172 | hasScannedForEncodings = 0; 173 | knownRegions = ( 174 | en, 175 | Base, 176 | ); 177 | mainGroup = EBF4BED0248EE7AF00C6F6B0; 178 | productRefGroup = EBF4BEDA248EE7AF00C6F6B0 /* Products */; 179 | projectDirPath = ""; 180 | projectRoot = ""; 181 | targets = ( 182 | EBF4BED8248EE7AF00C6F6B0 /* RosaKitExample */, 183 | ); 184 | }; 185 | /* End PBXProject section */ 186 | 187 | /* Begin PBXResourcesBuildPhase section */ 188 | EBF4BED7248EE7AF00C6F6B0 /* Resources */ = { 189 | isa = PBXResourcesBuildPhase; 190 | buildActionMask = 2147483647; 191 | files = ( 192 | EBF4BEED248EE7E500C6F6B0 /* test.wav in Resources */, 193 | EBF4BEE1248EE7B400C6F6B0 /* Assets.xcassets in Resources */, 194 | EBF4BEE4248EE7B400C6F6B0 /* Main.storyboard in Resources */, 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | }; 198 | /* End PBXResourcesBuildPhase section */ 199 | 200 | /* Begin PBXShellScriptBuildPhase section */ 201 | DDC0F1265033247A3B5E8FD5 /* [CP] Embed Pods Frameworks */ = { 202 | isa = PBXShellScriptBuildPhase; 203 | buildActionMask = 2147483647; 204 | files = ( 205 | ); 206 | inputFileListPaths = ( 207 | "${PODS_ROOT}/Target Support Files/Pods-RosaKitExample/Pods-RosaKitExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", 208 | ); 209 | name = "[CP] Embed Pods Frameworks"; 210 | outputFileListPaths = ( 211 | "${PODS_ROOT}/Target Support Files/Pods-RosaKitExample/Pods-RosaKitExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", 212 | ); 213 | runOnlyForDeploymentPostprocessing = 0; 214 | shellPath = /bin/sh; 215 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RosaKitExample/Pods-RosaKitExample-frameworks.sh\"\n"; 216 | showEnvVarsInLog = 0; 217 | }; 218 | DF179311DDD055328BEE94F3 /* [CP] Check Pods Manifest.lock */ = { 219 | isa = PBXShellScriptBuildPhase; 220 | buildActionMask = 2147483647; 221 | files = ( 222 | ); 223 | inputFileListPaths = ( 224 | ); 225 | inputPaths = ( 226 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 227 | "${PODS_ROOT}/Manifest.lock", 228 | ); 229 | name = "[CP] Check Pods Manifest.lock"; 230 | outputFileListPaths = ( 231 | ); 232 | outputPaths = ( 233 | "$(DERIVED_FILE_DIR)/Pods-RosaKitExample-checkManifestLockResult.txt", 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | shellPath = /bin/sh; 237 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 238 | showEnvVarsInLog = 0; 239 | }; 240 | /* End PBXShellScriptBuildPhase section */ 241 | 242 | /* Begin PBXSourcesBuildPhase section */ 243 | EBF4BED5248EE7AF00C6F6B0 /* Sources */ = { 244 | isa = PBXSourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | EBF4BEF4248EE86300C6F6B0 /* SpectrogramViewController.swift in Sources */, 248 | EBF4BEDF248EE7AF00C6F6B0 /* ViewController.swift in Sources */, 249 | EBF4BF08248EEB5C00C6F6B0 /* MTLTextureExtensions.swift in Sources */, 250 | EBF4BEF8248EE88100C6F6B0 /* SpectrogramView.swift in Sources */, 251 | EBF4BF0B248EEBA400C6F6B0 /* MTLDeviceExtensions.swift in Sources */, 252 | EBF4BF09248EEB5C00C6F6B0 /* SamplesRenderer.swift in Sources */, 253 | EBF4BEDD248EE7AF00C6F6B0 /* AppDelegate.swift in Sources */, 254 | EBF4BF07248EEB5C00C6F6B0 /* CommonUtils.metal in Sources */, 255 | EBF4BF06248EEB5C00C6F6B0 /* Shaders.metal in Sources */, 256 | ); 257 | runOnlyForDeploymentPostprocessing = 0; 258 | }; 259 | /* End PBXSourcesBuildPhase section */ 260 | 261 | /* Begin PBXVariantGroup section */ 262 | EBF4BEE2248EE7B400C6F6B0 /* Main.storyboard */ = { 263 | isa = PBXVariantGroup; 264 | children = ( 265 | EBF4BEE3248EE7B400C6F6B0 /* Base */, 266 | ); 267 | name = Main.storyboard; 268 | sourceTree = ""; 269 | }; 270 | /* End PBXVariantGroup section */ 271 | 272 | /* Begin XCBuildConfiguration section */ 273 | EBF4BEE7248EE7B400C6F6B0 /* Debug */ = { 274 | isa = XCBuildConfiguration; 275 | buildSettings = { 276 | ALWAYS_SEARCH_USER_PATHS = NO; 277 | CLANG_ANALYZER_NONNULL = YES; 278 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 279 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 280 | CLANG_CXX_LIBRARY = "libc++"; 281 | CLANG_ENABLE_MODULES = YES; 282 | CLANG_ENABLE_OBJC_ARC = YES; 283 | CLANG_ENABLE_OBJC_WEAK = YES; 284 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 285 | CLANG_WARN_BOOL_CONVERSION = YES; 286 | CLANG_WARN_COMMA = YES; 287 | CLANG_WARN_CONSTANT_CONVERSION = YES; 288 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 289 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 290 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 291 | CLANG_WARN_EMPTY_BODY = YES; 292 | CLANG_WARN_ENUM_CONVERSION = YES; 293 | CLANG_WARN_INFINITE_RECURSION = YES; 294 | CLANG_WARN_INT_CONVERSION = YES; 295 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 296 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 297 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 298 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 299 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 300 | CLANG_WARN_STRICT_PROTOTYPES = YES; 301 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 302 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 303 | CLANG_WARN_UNREACHABLE_CODE = YES; 304 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 305 | COPY_PHASE_STRIP = NO; 306 | DEBUG_INFORMATION_FORMAT = dwarf; 307 | ENABLE_STRICT_OBJC_MSGSEND = YES; 308 | ENABLE_TESTABILITY = YES; 309 | GCC_C_LANGUAGE_STANDARD = gnu11; 310 | GCC_DYNAMIC_NO_PIC = NO; 311 | GCC_NO_COMMON_BLOCKS = YES; 312 | GCC_OPTIMIZATION_LEVEL = 0; 313 | GCC_PREPROCESSOR_DEFINITIONS = ( 314 | "DEBUG=1", 315 | "$(inherited)", 316 | ); 317 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 318 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 319 | GCC_WARN_UNDECLARED_SELECTOR = YES; 320 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 321 | GCC_WARN_UNUSED_FUNCTION = YES; 322 | GCC_WARN_UNUSED_VARIABLE = YES; 323 | MACOSX_DEPLOYMENT_TARGET = 10.15; 324 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 325 | MTL_FAST_MATH = YES; 326 | ONLY_ACTIVE_ARCH = YES; 327 | SDKROOT = macosx; 328 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 329 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 330 | }; 331 | name = Debug; 332 | }; 333 | EBF4BEE8248EE7B400C6F6B0 /* Release */ = { 334 | isa = XCBuildConfiguration; 335 | buildSettings = { 336 | ALWAYS_SEARCH_USER_PATHS = NO; 337 | CLANG_ANALYZER_NONNULL = YES; 338 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 339 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 340 | CLANG_CXX_LIBRARY = "libc++"; 341 | CLANG_ENABLE_MODULES = YES; 342 | CLANG_ENABLE_OBJC_ARC = YES; 343 | CLANG_ENABLE_OBJC_WEAK = YES; 344 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 345 | CLANG_WARN_BOOL_CONVERSION = YES; 346 | CLANG_WARN_COMMA = YES; 347 | CLANG_WARN_CONSTANT_CONVERSION = YES; 348 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 349 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 350 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 351 | CLANG_WARN_EMPTY_BODY = YES; 352 | CLANG_WARN_ENUM_CONVERSION = YES; 353 | CLANG_WARN_INFINITE_RECURSION = YES; 354 | CLANG_WARN_INT_CONVERSION = YES; 355 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 356 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 357 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 358 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 359 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 360 | CLANG_WARN_STRICT_PROTOTYPES = YES; 361 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 362 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 363 | CLANG_WARN_UNREACHABLE_CODE = YES; 364 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 365 | COPY_PHASE_STRIP = NO; 366 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 367 | ENABLE_NS_ASSERTIONS = NO; 368 | ENABLE_STRICT_OBJC_MSGSEND = YES; 369 | GCC_C_LANGUAGE_STANDARD = gnu11; 370 | GCC_NO_COMMON_BLOCKS = YES; 371 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 372 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 373 | GCC_WARN_UNDECLARED_SELECTOR = YES; 374 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 375 | GCC_WARN_UNUSED_FUNCTION = YES; 376 | GCC_WARN_UNUSED_VARIABLE = YES; 377 | MACOSX_DEPLOYMENT_TARGET = 10.15; 378 | MTL_ENABLE_DEBUG_INFO = NO; 379 | MTL_FAST_MATH = YES; 380 | SDKROOT = macosx; 381 | SWIFT_COMPILATION_MODE = wholemodule; 382 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 383 | }; 384 | name = Release; 385 | }; 386 | EBF4BEEA248EE7B400C6F6B0 /* Debug */ = { 387 | isa = XCBuildConfiguration; 388 | baseConfigurationReference = 427DD64D5279FC54D40AD1BE /* Pods-RosaKitExample.debug.xcconfig */; 389 | buildSettings = { 390 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 391 | CODE_SIGN_ENTITLEMENTS = RosaKitExample/RosaKitExample.entitlements; 392 | CODE_SIGN_IDENTITY = "Apple Development"; 393 | CODE_SIGN_STYLE = Manual; 394 | COMBINE_HIDPI_IMAGES = YES; 395 | DEVELOPMENT_TEAM = L9DCNBKQG8; 396 | ENABLE_HARDENED_RUNTIME = YES; 397 | INFOPLIST_FILE = RosaKitExample/Info.plist; 398 | LD_RUNPATH_SEARCH_PATHS = ( 399 | "$(inherited)", 400 | "@executable_path/../Frameworks", 401 | ); 402 | PRODUCT_BUNDLE_IDENTIFIER = com.dmytro.RosaKitExample; 403 | PRODUCT_NAME = "$(TARGET_NAME)"; 404 | PROVISIONING_PROFILE_SPECIFIER = ""; 405 | SWIFT_VERSION = 5.0; 406 | }; 407 | name = Debug; 408 | }; 409 | EBF4BEEB248EE7B400C6F6B0 /* Release */ = { 410 | isa = XCBuildConfiguration; 411 | baseConfigurationReference = F91367C50922BBA1E748553A /* Pods-RosaKitExample.release.xcconfig */; 412 | buildSettings = { 413 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 414 | CODE_SIGN_ENTITLEMENTS = RosaKitExample/RosaKitExample.entitlements; 415 | CODE_SIGN_IDENTITY = "Apple Development"; 416 | CODE_SIGN_STYLE = Manual; 417 | COMBINE_HIDPI_IMAGES = YES; 418 | DEVELOPMENT_TEAM = L9DCNBKQG8; 419 | ENABLE_HARDENED_RUNTIME = YES; 420 | INFOPLIST_FILE = RosaKitExample/Info.plist; 421 | LD_RUNPATH_SEARCH_PATHS = ( 422 | "$(inherited)", 423 | "@executable_path/../Frameworks", 424 | ); 425 | PRODUCT_BUNDLE_IDENTIFIER = com.dmytro.RosaKitExample; 426 | PRODUCT_NAME = "$(TARGET_NAME)"; 427 | PROVISIONING_PROFILE_SPECIFIER = ""; 428 | SWIFT_VERSION = 5.0; 429 | }; 430 | name = Release; 431 | }; 432 | /* End XCBuildConfiguration section */ 433 | 434 | /* Begin XCConfigurationList section */ 435 | EBF4BED4248EE7AF00C6F6B0 /* Build configuration list for PBXProject "RosaKitExample" */ = { 436 | isa = XCConfigurationList; 437 | buildConfigurations = ( 438 | EBF4BEE7248EE7B400C6F6B0 /* Debug */, 439 | EBF4BEE8248EE7B400C6F6B0 /* Release */, 440 | ); 441 | defaultConfigurationIsVisible = 0; 442 | defaultConfigurationName = Release; 443 | }; 444 | EBF4BEE9248EE7B400C6F6B0 /* Build configuration list for PBXNativeTarget "RosaKitExample" */ = { 445 | isa = XCConfigurationList; 446 | buildConfigurations = ( 447 | EBF4BEEA248EE7B400C6F6B0 /* Debug */, 448 | EBF4BEEB248EE7B400C6F6B0 /* Release */, 449 | ); 450 | defaultConfigurationIsVisible = 0; 451 | defaultConfigurationName = Release; 452 | }; 453 | /* End XCConfigurationList section */ 454 | }; 455 | rootObject = EBF4BED1248EE7AF00C6F6B0 /* Project object */; 456 | } 457 | -------------------------------------------------------------------------------- /Example/NoiseReductionExample/NoiseReductionExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | D02153070BBB25EBBF45B228 /* Pods_NoiseReductionExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 547DB39160D230B33BCAB90B /* Pods_NoiseReductionExample.framework */; }; 11 | EB5C7E9226E01D0D003728EB /* SoundNoiseReduction.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = EB5C7E9126E01D0D003728EB /* SoundNoiseReduction.mlmodel */; }; 12 | EB5C7E9426E021E6003728EB /* test.wav in Resources */ = {isa = PBXBuildFile; fileRef = EB5C7E9326E021E6003728EB /* test.wav */; }; 13 | EBF4BEDD248EE7AF00C6F6B0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BEDC248EE7AF00C6F6B0 /* AppDelegate.swift */; }; 14 | EBF4BEDF248EE7AF00C6F6B0 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BEDE248EE7AF00C6F6B0 /* MainViewController.swift */; }; 15 | EBF4BEE1248EE7B400C6F6B0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EBF4BEE0248EE7B400C6F6B0 /* Assets.xcassets */; }; 16 | EBF4BEE4248EE7B400C6F6B0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EBF4BEE2248EE7B400C6F6B0 /* Main.storyboard */; }; 17 | EBF4BEF4248EE86300C6F6B0 /* SpectrogramViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BEF1248EE86200C6F6B0 /* SpectrogramViewController.swift */; }; 18 | EBF4BEF8248EE88100C6F6B0 /* SpectrogramView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BEF7248EE88100C6F6B0 /* SpectrogramView.swift */; }; 19 | EBF4BF06248EEB5C00C6F6B0 /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BF01248EEB5B00C6F6B0 /* Shaders.metal */; }; 20 | EBF4BF07248EEB5C00C6F6B0 /* CommonUtils.metal in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BF03248EEB5B00C6F6B0 /* CommonUtils.metal */; }; 21 | EBF4BF08248EEB5C00C6F6B0 /* MTLTextureExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BF04248EEB5C00C6F6B0 /* MTLTextureExtensions.swift */; }; 22 | EBF4BF09248EEB5C00C6F6B0 /* SamplesRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BF05248EEB5C00C6F6B0 /* SamplesRenderer.swift */; }; 23 | EBF4BF0B248EEBA400C6F6B0 /* MTLDeviceExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF4BF0A248EEBA400C6F6B0 /* MTLDeviceExtensions.swift */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 1FC8463E8753DA71B0BB493D /* Pods-NoiseReductionExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NoiseReductionExample.debug.xcconfig"; path = "Target Support Files/Pods-NoiseReductionExample/Pods-NoiseReductionExample.debug.xcconfig"; sourceTree = ""; }; 28 | 427DD64D5279FC54D40AD1BE /* Pods-RosaKitExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RosaKitExample.debug.xcconfig"; path = "Target Support Files/Pods-RosaKitExample/Pods-RosaKitExample.debug.xcconfig"; sourceTree = ""; }; 29 | 547DB39160D230B33BCAB90B /* Pods_NoiseReductionExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NoiseReductionExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | 58425DFF2D9CD64C40EE3E85 /* Pods-NoiseReductionExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NoiseReductionExample.release.xcconfig"; path = "Target Support Files/Pods-NoiseReductionExample/Pods-NoiseReductionExample.release.xcconfig"; sourceTree = ""; }; 31 | EB5C7E9026E00B28003728EB /* NoiseReductionExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NoiseReductionExample.entitlements; sourceTree = ""; }; 32 | EB5C7E9126E01D0D003728EB /* SoundNoiseReduction.mlmodel */ = {isa = PBXFileReference; lastKnownFileType = file.mlmodel; path = SoundNoiseReduction.mlmodel; sourceTree = ""; }; 33 | EB5C7E9326E021E6003728EB /* test.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = test.wav; sourceTree = ""; }; 34 | EBF4BED9248EE7AF00C6F6B0 /* NoiseReductionExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NoiseReductionExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | EBF4BEDC248EE7AF00C6F6B0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 36 | EBF4BEDE248EE7AF00C6F6B0 /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 37 | EBF4BEE0248EE7B400C6F6B0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 38 | EBF4BEE3248EE7B400C6F6B0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 39 | EBF4BEE5248EE7B400C6F6B0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 40 | EBF4BEF1248EE86200C6F6B0 /* SpectrogramViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpectrogramViewController.swift; sourceTree = ""; }; 41 | EBF4BEF7248EE88100C6F6B0 /* SpectrogramView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpectrogramView.swift; sourceTree = ""; }; 42 | EBF4BF01248EEB5B00C6F6B0 /* Shaders.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Shaders.metal; sourceTree = ""; }; 43 | EBF4BF02248EEB5B00C6F6B0 /* CommonUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonUtils.h; sourceTree = ""; }; 44 | EBF4BF03248EEB5B00C6F6B0 /* CommonUtils.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = CommonUtils.metal; sourceTree = ""; }; 45 | EBF4BF04248EEB5C00C6F6B0 /* MTLTextureExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTLTextureExtensions.swift; sourceTree = ""; }; 46 | EBF4BF05248EEB5C00C6F6B0 /* SamplesRenderer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SamplesRenderer.swift; sourceTree = ""; }; 47 | EBF4BF0A248EEBA400C6F6B0 /* MTLDeviceExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MTLDeviceExtensions.swift; sourceTree = ""; }; 48 | F91367C50922BBA1E748553A /* Pods-RosaKitExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RosaKitExample.release.xcconfig"; path = "Target Support Files/Pods-RosaKitExample/Pods-RosaKitExample.release.xcconfig"; sourceTree = ""; }; 49 | /* End PBXFileReference section */ 50 | 51 | /* Begin PBXFrameworksBuildPhase section */ 52 | EBF4BED6248EE7AF00C6F6B0 /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | D02153070BBB25EBBF45B228 /* Pods_NoiseReductionExample.framework in Frameworks */, 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | /* End PBXFrameworksBuildPhase section */ 61 | 62 | /* Begin PBXGroup section */ 63 | 7901FAC5324E9909E3787037 /* Frameworks */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | 547DB39160D230B33BCAB90B /* Pods_NoiseReductionExample.framework */, 67 | ); 68 | name = Frameworks; 69 | sourceTree = ""; 70 | }; 71 | E96B08C8C5CCFC0D7FF8A3CB /* Pods */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 427DD64D5279FC54D40AD1BE /* Pods-RosaKitExample.debug.xcconfig */, 75 | F91367C50922BBA1E748553A /* Pods-RosaKitExample.release.xcconfig */, 76 | 1FC8463E8753DA71B0BB493D /* Pods-NoiseReductionExample.debug.xcconfig */, 77 | 58425DFF2D9CD64C40EE3E85 /* Pods-NoiseReductionExample.release.xcconfig */, 78 | ); 79 | path = Pods; 80 | sourceTree = ""; 81 | }; 82 | EBF4BED0248EE7AF00C6F6B0 = { 83 | isa = PBXGroup; 84 | children = ( 85 | EBF4BEDB248EE7AF00C6F6B0 /* NoiseReductionExample */, 86 | EBF4BEDA248EE7AF00C6F6B0 /* Products */, 87 | E96B08C8C5CCFC0D7FF8A3CB /* Pods */, 88 | 7901FAC5324E9909E3787037 /* Frameworks */, 89 | ); 90 | sourceTree = ""; 91 | }; 92 | EBF4BEDA248EE7AF00C6F6B0 /* Products */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | EBF4BED9248EE7AF00C6F6B0 /* NoiseReductionExample.app */, 96 | ); 97 | name = Products; 98 | sourceTree = ""; 99 | }; 100 | EBF4BEDB248EE7AF00C6F6B0 /* NoiseReductionExample */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | EBF4BF00248EEB3F00C6F6B0 /* RenderingEngine */, 104 | EBF4BEF0248EE85500C6F6B0 /* Spectrogram */, 105 | EBF4BEDC248EE7AF00C6F6B0 /* AppDelegate.swift */, 106 | EBF4BEDE248EE7AF00C6F6B0 /* MainViewController.swift */, 107 | EB5C7E9026E00B28003728EB /* NoiseReductionExample.entitlements */, 108 | EBF4BEE0248EE7B400C6F6B0 /* Assets.xcassets */, 109 | EB5C7E9126E01D0D003728EB /* SoundNoiseReduction.mlmodel */, 110 | EBF4BEE2248EE7B400C6F6B0 /* Main.storyboard */, 111 | EBF4BEE5248EE7B400C6F6B0 /* Info.plist */, 112 | EB5C7E9326E021E6003728EB /* test.wav */, 113 | ); 114 | path = NoiseReductionExample; 115 | sourceTree = ""; 116 | }; 117 | EBF4BEF0248EE85500C6F6B0 /* Spectrogram */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | EBF4BEF7248EE88100C6F6B0 /* SpectrogramView.swift */, 121 | EBF4BEF1248EE86200C6F6B0 /* SpectrogramViewController.swift */, 122 | ); 123 | path = Spectrogram; 124 | sourceTree = ""; 125 | }; 126 | EBF4BF00248EEB3F00C6F6B0 /* RenderingEngine */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | EBF4BF02248EEB5B00C6F6B0 /* CommonUtils.h */, 130 | EBF4BF03248EEB5B00C6F6B0 /* CommonUtils.metal */, 131 | EBF4BF04248EEB5C00C6F6B0 /* MTLTextureExtensions.swift */, 132 | EBF4BF05248EEB5C00C6F6B0 /* SamplesRenderer.swift */, 133 | EBF4BF01248EEB5B00C6F6B0 /* Shaders.metal */, 134 | EBF4BF0A248EEBA400C6F6B0 /* MTLDeviceExtensions.swift */, 135 | ); 136 | path = RenderingEngine; 137 | sourceTree = ""; 138 | }; 139 | /* End PBXGroup section */ 140 | 141 | /* Begin PBXNativeTarget section */ 142 | EBF4BED8248EE7AF00C6F6B0 /* NoiseReductionExample */ = { 143 | isa = PBXNativeTarget; 144 | buildConfigurationList = EBF4BEE9248EE7B400C6F6B0 /* Build configuration list for PBXNativeTarget "NoiseReductionExample" */; 145 | buildPhases = ( 146 | DF179311DDD055328BEE94F3 /* [CP] Check Pods Manifest.lock */, 147 | EBF4BED5248EE7AF00C6F6B0 /* Sources */, 148 | EBF4BED6248EE7AF00C6F6B0 /* Frameworks */, 149 | EBF4BED7248EE7AF00C6F6B0 /* Resources */, 150 | DDC0F1265033247A3B5E8FD5 /* [CP] Embed Pods Frameworks */, 151 | ); 152 | buildRules = ( 153 | ); 154 | dependencies = ( 155 | ); 156 | name = NoiseReductionExample; 157 | productName = RosaKitExample; 158 | productReference = EBF4BED9248EE7AF00C6F6B0 /* NoiseReductionExample.app */; 159 | productType = "com.apple.product-type.application"; 160 | }; 161 | /* End PBXNativeTarget section */ 162 | 163 | /* Begin PBXProject section */ 164 | EBF4BED1248EE7AF00C6F6B0 /* Project object */ = { 165 | isa = PBXProject; 166 | attributes = { 167 | LastSwiftUpdateCheck = 1150; 168 | LastUpgradeCheck = 1150; 169 | ORGANIZATIONNAME = "Hrebeniuk Dmytro"; 170 | TargetAttributes = { 171 | EBF4BED8248EE7AF00C6F6B0 = { 172 | CreatedOnToolsVersion = 11.5; 173 | }; 174 | }; 175 | }; 176 | buildConfigurationList = EBF4BED4248EE7AF00C6F6B0 /* Build configuration list for PBXProject "NoiseReductionExample" */; 177 | compatibilityVersion = "Xcode 9.3"; 178 | developmentRegion = en; 179 | hasScannedForEncodings = 0; 180 | knownRegions = ( 181 | en, 182 | Base, 183 | ); 184 | mainGroup = EBF4BED0248EE7AF00C6F6B0; 185 | productRefGroup = EBF4BEDA248EE7AF00C6F6B0 /* Products */; 186 | projectDirPath = ""; 187 | projectRoot = ""; 188 | targets = ( 189 | EBF4BED8248EE7AF00C6F6B0 /* NoiseReductionExample */, 190 | ); 191 | }; 192 | /* End PBXProject section */ 193 | 194 | /* Begin PBXResourcesBuildPhase section */ 195 | EBF4BED7248EE7AF00C6F6B0 /* Resources */ = { 196 | isa = PBXResourcesBuildPhase; 197 | buildActionMask = 2147483647; 198 | files = ( 199 | EB5C7E9426E021E6003728EB /* test.wav in Resources */, 200 | EBF4BEE1248EE7B400C6F6B0 /* Assets.xcassets in Resources */, 201 | EBF4BEE4248EE7B400C6F6B0 /* Main.storyboard in Resources */, 202 | ); 203 | runOnlyForDeploymentPostprocessing = 0; 204 | }; 205 | /* End PBXResourcesBuildPhase section */ 206 | 207 | /* Begin PBXShellScriptBuildPhase section */ 208 | DDC0F1265033247A3B5E8FD5 /* [CP] Embed Pods Frameworks */ = { 209 | isa = PBXShellScriptBuildPhase; 210 | buildActionMask = 2147483647; 211 | files = ( 212 | ); 213 | inputFileListPaths = ( 214 | "${PODS_ROOT}/Target Support Files/Pods-NoiseReductionExample/Pods-NoiseReductionExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", 215 | ); 216 | name = "[CP] Embed Pods Frameworks"; 217 | outputFileListPaths = ( 218 | "${PODS_ROOT}/Target Support Files/Pods-NoiseReductionExample/Pods-NoiseReductionExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | shellPath = /bin/sh; 222 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-NoiseReductionExample/Pods-NoiseReductionExample-frameworks.sh\"\n"; 223 | showEnvVarsInLog = 0; 224 | }; 225 | DF179311DDD055328BEE94F3 /* [CP] Check Pods Manifest.lock */ = { 226 | isa = PBXShellScriptBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | ); 230 | inputFileListPaths = ( 231 | ); 232 | inputPaths = ( 233 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 234 | "${PODS_ROOT}/Manifest.lock", 235 | ); 236 | name = "[CP] Check Pods Manifest.lock"; 237 | outputFileListPaths = ( 238 | ); 239 | outputPaths = ( 240 | "$(DERIVED_FILE_DIR)/Pods-NoiseReductionExample-checkManifestLockResult.txt", 241 | ); 242 | runOnlyForDeploymentPostprocessing = 0; 243 | shellPath = /bin/sh; 244 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 245 | showEnvVarsInLog = 0; 246 | }; 247 | /* End PBXShellScriptBuildPhase section */ 248 | 249 | /* Begin PBXSourcesBuildPhase section */ 250 | EBF4BED5248EE7AF00C6F6B0 /* Sources */ = { 251 | isa = PBXSourcesBuildPhase; 252 | buildActionMask = 2147483647; 253 | files = ( 254 | EBF4BEF4248EE86300C6F6B0 /* SpectrogramViewController.swift in Sources */, 255 | EBF4BEDF248EE7AF00C6F6B0 /* MainViewController.swift in Sources */, 256 | EBF4BF08248EEB5C00C6F6B0 /* MTLTextureExtensions.swift in Sources */, 257 | EBF4BEF8248EE88100C6F6B0 /* SpectrogramView.swift in Sources */, 258 | EBF4BF0B248EEBA400C6F6B0 /* MTLDeviceExtensions.swift in Sources */, 259 | EBF4BF09248EEB5C00C6F6B0 /* SamplesRenderer.swift in Sources */, 260 | EBF4BEDD248EE7AF00C6F6B0 /* AppDelegate.swift in Sources */, 261 | EB5C7E9226E01D0D003728EB /* SoundNoiseReduction.mlmodel in Sources */, 262 | EBF4BF07248EEB5C00C6F6B0 /* CommonUtils.metal in Sources */, 263 | EBF4BF06248EEB5C00C6F6B0 /* Shaders.metal in Sources */, 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | /* End PBXSourcesBuildPhase section */ 268 | 269 | /* Begin PBXVariantGroup section */ 270 | EBF4BEE2248EE7B400C6F6B0 /* Main.storyboard */ = { 271 | isa = PBXVariantGroup; 272 | children = ( 273 | EBF4BEE3248EE7B400C6F6B0 /* Base */, 274 | ); 275 | name = Main.storyboard; 276 | sourceTree = ""; 277 | }; 278 | /* End PBXVariantGroup section */ 279 | 280 | /* Begin XCBuildConfiguration section */ 281 | EBF4BEE7248EE7B400C6F6B0 /* Debug */ = { 282 | isa = XCBuildConfiguration; 283 | buildSettings = { 284 | ALWAYS_SEARCH_USER_PATHS = NO; 285 | CLANG_ANALYZER_NONNULL = YES; 286 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 287 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 288 | CLANG_CXX_LIBRARY = "libc++"; 289 | CLANG_ENABLE_MODULES = YES; 290 | CLANG_ENABLE_OBJC_ARC = YES; 291 | CLANG_ENABLE_OBJC_WEAK = YES; 292 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 293 | CLANG_WARN_BOOL_CONVERSION = YES; 294 | CLANG_WARN_COMMA = YES; 295 | CLANG_WARN_CONSTANT_CONVERSION = YES; 296 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 297 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 298 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 299 | CLANG_WARN_EMPTY_BODY = YES; 300 | CLANG_WARN_ENUM_CONVERSION = YES; 301 | CLANG_WARN_INFINITE_RECURSION = YES; 302 | CLANG_WARN_INT_CONVERSION = YES; 303 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 304 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 305 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 306 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 307 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 308 | CLANG_WARN_STRICT_PROTOTYPES = YES; 309 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 310 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 311 | CLANG_WARN_UNREACHABLE_CODE = YES; 312 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 313 | COPY_PHASE_STRIP = NO; 314 | DEBUG_INFORMATION_FORMAT = dwarf; 315 | ENABLE_STRICT_OBJC_MSGSEND = YES; 316 | ENABLE_TESTABILITY = YES; 317 | GCC_C_LANGUAGE_STANDARD = gnu11; 318 | GCC_DYNAMIC_NO_PIC = NO; 319 | GCC_NO_COMMON_BLOCKS = YES; 320 | GCC_OPTIMIZATION_LEVEL = 0; 321 | GCC_PREPROCESSOR_DEFINITIONS = ( 322 | "DEBUG=1", 323 | "$(inherited)", 324 | ); 325 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 326 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 327 | GCC_WARN_UNDECLARED_SELECTOR = YES; 328 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 329 | GCC_WARN_UNUSED_FUNCTION = YES; 330 | GCC_WARN_UNUSED_VARIABLE = YES; 331 | MACOSX_DEPLOYMENT_TARGET = 10.15; 332 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 333 | MTL_FAST_MATH = YES; 334 | ONLY_ACTIVE_ARCH = YES; 335 | SDKROOT = macosx; 336 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 337 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 338 | }; 339 | name = Debug; 340 | }; 341 | EBF4BEE8248EE7B400C6F6B0 /* Release */ = { 342 | isa = XCBuildConfiguration; 343 | buildSettings = { 344 | ALWAYS_SEARCH_USER_PATHS = NO; 345 | CLANG_ANALYZER_NONNULL = YES; 346 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 347 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 348 | CLANG_CXX_LIBRARY = "libc++"; 349 | CLANG_ENABLE_MODULES = YES; 350 | CLANG_ENABLE_OBJC_ARC = YES; 351 | CLANG_ENABLE_OBJC_WEAK = YES; 352 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 353 | CLANG_WARN_BOOL_CONVERSION = YES; 354 | CLANG_WARN_COMMA = YES; 355 | CLANG_WARN_CONSTANT_CONVERSION = YES; 356 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 357 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 358 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 359 | CLANG_WARN_EMPTY_BODY = YES; 360 | CLANG_WARN_ENUM_CONVERSION = YES; 361 | CLANG_WARN_INFINITE_RECURSION = YES; 362 | CLANG_WARN_INT_CONVERSION = YES; 363 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 364 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 365 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 366 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 367 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 368 | CLANG_WARN_STRICT_PROTOTYPES = YES; 369 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 370 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 371 | CLANG_WARN_UNREACHABLE_CODE = YES; 372 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 373 | COPY_PHASE_STRIP = NO; 374 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 375 | ENABLE_NS_ASSERTIONS = NO; 376 | ENABLE_STRICT_OBJC_MSGSEND = YES; 377 | GCC_C_LANGUAGE_STANDARD = gnu11; 378 | GCC_NO_COMMON_BLOCKS = YES; 379 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 380 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 381 | GCC_WARN_UNDECLARED_SELECTOR = YES; 382 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 383 | GCC_WARN_UNUSED_FUNCTION = YES; 384 | GCC_WARN_UNUSED_VARIABLE = YES; 385 | MACOSX_DEPLOYMENT_TARGET = 10.15; 386 | MTL_ENABLE_DEBUG_INFO = NO; 387 | MTL_FAST_MATH = YES; 388 | SDKROOT = macosx; 389 | SWIFT_COMPILATION_MODE = wholemodule; 390 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 391 | }; 392 | name = Release; 393 | }; 394 | EBF4BEEA248EE7B400C6F6B0 /* Debug */ = { 395 | isa = XCBuildConfiguration; 396 | baseConfigurationReference = 1FC8463E8753DA71B0BB493D /* Pods-NoiseReductionExample.debug.xcconfig */; 397 | buildSettings = { 398 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 399 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 400 | CODE_SIGN_ENTITLEMENTS = NoiseReductionExample/NoiseReductionExample.entitlements; 401 | CODE_SIGN_IDENTITY = "Apple Development"; 402 | CODE_SIGN_STYLE = Automatic; 403 | COMBINE_HIDPI_IMAGES = YES; 404 | DEVELOPMENT_TEAM = ""; 405 | ENABLE_HARDENED_RUNTIME = YES; 406 | INFOPLIST_FILE = NoiseReductionExample/Info.plist; 407 | LD_RUNPATH_SEARCH_PATHS = ( 408 | "$(inherited)", 409 | "@executable_path/../Frameworks", 410 | ); 411 | PRODUCT_BUNDLE_IDENTIFIER = com.dmytro.NoiseReductionExample; 412 | PRODUCT_NAME = "$(TARGET_NAME)"; 413 | PROVISIONING_PROFILE_SPECIFIER = ""; 414 | SWIFT_VERSION = 5.0; 415 | }; 416 | name = Debug; 417 | }; 418 | EBF4BEEB248EE7B400C6F6B0 /* Release */ = { 419 | isa = XCBuildConfiguration; 420 | baseConfigurationReference = 58425DFF2D9CD64C40EE3E85 /* Pods-NoiseReductionExample.release.xcconfig */; 421 | buildSettings = { 422 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 423 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 424 | CODE_SIGN_ENTITLEMENTS = NoiseReductionExample/NoiseReductionExample.entitlements; 425 | CODE_SIGN_IDENTITY = "-"; 426 | CODE_SIGN_STYLE = Manual; 427 | COMBINE_HIDPI_IMAGES = YES; 428 | DEVELOPMENT_TEAM = ""; 429 | ENABLE_HARDENED_RUNTIME = YES; 430 | INFOPLIST_FILE = NoiseReductionExample/Info.plist; 431 | LD_RUNPATH_SEARCH_PATHS = ( 432 | "$(inherited)", 433 | "@executable_path/../Frameworks", 434 | ); 435 | PRODUCT_BUNDLE_IDENTIFIER = com.dmytro.NoiseReductionExample; 436 | PRODUCT_NAME = "$(TARGET_NAME)"; 437 | PROVISIONING_PROFILE_SPECIFIER = ""; 438 | SWIFT_VERSION = 5.0; 439 | }; 440 | name = Release; 441 | }; 442 | /* End XCBuildConfiguration section */ 443 | 444 | /* Begin XCConfigurationList section */ 445 | EBF4BED4248EE7AF00C6F6B0 /* Build configuration list for PBXProject "NoiseReductionExample" */ = { 446 | isa = XCConfigurationList; 447 | buildConfigurations = ( 448 | EBF4BEE7248EE7B400C6F6B0 /* Debug */, 449 | EBF4BEE8248EE7B400C6F6B0 /* Release */, 450 | ); 451 | defaultConfigurationIsVisible = 0; 452 | defaultConfigurationName = Release; 453 | }; 454 | EBF4BEE9248EE7B400C6F6B0 /* Build configuration list for PBXNativeTarget "NoiseReductionExample" */ = { 455 | isa = XCConfigurationList; 456 | buildConfigurations = ( 457 | EBF4BEEA248EE7B400C6F6B0 /* Debug */, 458 | EBF4BEEB248EE7B400C6F6B0 /* Release */, 459 | ); 460 | defaultConfigurationIsVisible = 0; 461 | defaultConfigurationName = Release; 462 | }; 463 | /* End XCConfigurationList section */ 464 | }; 465 | rootObject = EBF4BED1248EE7AF00C6F6B0 /* Project object */; 466 | } 467 | --------------------------------------------------------------------------------