├── 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 |
--------------------------------------------------------------------------------