├── .gitignore ├── LICENSE ├── Noise-Classification-2-Mic ├── Noise_Classification.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Noise_Classification │ ├── AppDelegate.swift │ ├── AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469 │ ├── AppIcon24x24@2x.png │ ├── AppIcon27.5x27.5@2x.png │ ├── AppIcon40x40@2x.png │ ├── AppIcon44x44@2x.png │ ├── AppIcon86x86@2x.png │ ├── AppIcon98x98@2x.png │ ├── GooglePlayStore.png │ ├── Icon-60@2x.png │ ├── Icon-60@3x.png │ ├── Icon-72.png │ ├── Icon-72@2x.png │ ├── Icon-76.png │ ├── Icon-76@2x.png │ ├── Icon-83.5@2x.png │ ├── Icon-Notification.png │ ├── Icon-Notification@3x.png │ ├── Icon-Small-40.png │ ├── Icon-Small-40@2x.png │ ├── Icon-Small-50.png │ ├── Icon-Small-50@2x.png │ ├── Icon-Small.png │ ├── Icon-Small@2x.png │ ├── Icon-Small@3x.png │ ├── Icon.png │ ├── Icon@2x.png │ ├── hdpi.png │ ├── iTunesArtwork │ ├── iTunesArtwork@2x │ ├── ldpi.png │ ├── mdpi.png │ ├── xhdpi.png │ ├── xxhdpi.png │ └── xxxhdpi.png │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── FIRFilter.c │ ├── FIRFilter.h │ ├── IOSAudioController.h │ ├── IOSAudioController.m │ ├── Info.plist │ ├── MovingAverageBuffer.h │ ├── MovingAverageBuffer.m │ ├── NC-2Ch-Bridging-Header.h │ ├── RandomForest.c │ ├── RandomForest.h │ ├── SpeechProcessing.c │ ├── SpeechProcessing.h │ ├── SubbandFeatures.c │ ├── SubbandFeatures.h │ ├── TPCircularBuffer.c │ ├── TPCircularBuffer.h │ ├── TrainData.h │ ├── Transforms2.c │ ├── Transforms2.h │ ├── UTD_emblem_blk.png │ ├── ViewController.swift │ ├── filterCoefficients.h │ └── utd_print_black_ecs_mono_stacked.png ├── Noise-Reduction-2-Mic ├── Noise_Reduction.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Noise_Reduction │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── FIRFilter.c │ ├── FIRFilter.h │ ├── IOSAudioController.h │ ├── IOSAudioController.m │ ├── Info.plist │ ├── MovingAverageBuffer.h │ ├── MovingAverageBuffer.m │ ├── NC-2Ch-Bridging-Header.h │ ├── NLMS.c │ ├── NLMS.h │ ├── NoiseReduction.c │ ├── NoiseReduction.h │ ├── TPCircularBuffer.c │ ├── TPCircularBuffer.h │ ├── UTD_emblem_blk.png │ ├── ViewController.swift │ ├── abs.c │ ├── abs.h │ ├── bluestein_setup.c │ ├── bluestein_setup.h │ ├── fft.c │ ├── fft.h │ ├── filterCoefficients.h │ ├── power.c │ ├── power.h │ ├── rdivide.c │ ├── rdivide.h │ ├── rtGetInf.c │ ├── rtGetInf.h │ ├── rtGetNaN.c │ ├── rtGetNaN.h │ ├── rt_nonfinite.c │ ├── rt_nonfinite.h │ ├── rtwtypes.h │ ├── wienerAB.c │ ├── wienerAB.h │ ├── wienerAB_emxutil.c │ ├── wienerAB_emxutil.h │ ├── wienerAB_initialize.c │ ├── wienerAB_initialize.h │ ├── wienerAB_rtwutil.c │ ├── wienerAB_rtwutil.h │ ├── wienerAB_terminate.c │ ├── wienerAB_terminate.h │ └── wienerAB_types.h ├── README.md └── Users-Guide-iOS-TwoExternalMics.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | # All the model generated files 2 | 3 | *.h5 4 | *.pb 5 | *.mlmodel 6 | *.tflite 7 | 8 | # All the jupyter notebook checkpoints 9 | .ipynb_checkpoints 10 | 11 | # Mac finder specific files 12 | .DS_Store 13 | 14 | # OpenCV2 Framework 15 | 16 | opencv2.framework 17 | 18 | # Xcode 19 | # 20 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 21 | 22 | ## User settings 23 | xcuserdata/ 24 | 25 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 26 | *.xcscmblueprint 27 | *.xccheckout 28 | 29 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 30 | build/ 31 | DerivedData/ 32 | *.moved-aside 33 | *.pbxuser 34 | !default.pbxuser 35 | *.mode1v3 36 | !default.mode1v3 37 | *.mode2v3 38 | !default.mode2v3 39 | *.perspectivev3 40 | !default.perspectivev3 41 | 42 | # Android Studio Projects 43 | 44 | # Built application files 45 | /*/build/ 46 | 47 | # Crashlytics configuations 48 | com_crashlytics_export_strings.xml 49 | 50 | # Local configuration file (sdk path, etc) 51 | local.properties 52 | 53 | # Gradle generated files 54 | .gradle/ 55 | 56 | # Signing files 57 | .signing/ 58 | 59 | # User-specific configurations 60 | .idea/libraries/ 61 | .idea/workspace.xml 62 | .idea/tasks.xml 63 | .idea/.name 64 | .idea/compiler.xml 65 | .idea/copyright/profiles_settings.xml 66 | .idea/encodings.xml 67 | .idea/misc.xml 68 | .idea/modules.xml 69 | .idea/scopes/scope_settings.xml 70 | .idea/vcs.xml 71 | *.iml 72 | 73 | # OS-specific files 74 | .DS_Store 75 | .DS_Store? 76 | ._* 77 | .Spotlight-V100 78 | .Trashes 79 | ehthumbs.db 80 | Thumbs.db 81 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Signal and Image Processing Lab 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 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/AppIcon24x24@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/AppIcon24x24@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/AppIcon27.5x27.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/AppIcon27.5x27.5@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/AppIcon40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/AppIcon40x40@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/AppIcon44x44@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/AppIcon44x44@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/AppIcon86x86@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/AppIcon86x86@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/AppIcon98x98@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/AppIcon98x98@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/GooglePlayStore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/GooglePlayStore.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-60@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-60@3x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-72.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-72@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-76.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-76@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-83.5@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Notification.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Notification@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Notification@3x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small-40.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small-40@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small-50.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small-50@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon-Small@3x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/Icon@2x.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/hdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/hdpi.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/iTunesArtwork: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/iTunesArtwork -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/iTunesArtwork@2x: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/iTunesArtwork@2x -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/ldpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/ldpi.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/mdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/mdpi.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/xhdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/xhdpi.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/xxhdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/xxhdpi.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/xxxhdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/AppIconResizer_201707201709_99ce3de694bade9ba3d5e8728dc6c469/xxxhdpi.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 37 | 52 | 58 | 59 | 60 | 61 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 85 | 86 | 87 | 88 | Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/FIRFilter.c: -------------------------------------------------------------------------------- 1 | // 2 | // FIRFilter.c 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/18/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #include "FIRFilter.h" 10 | #include "filterCoefficients.h" 11 | 12 | FIR* initFIR(int stepSize) { 13 | 14 | FIR* fir = (FIR*)malloc(sizeof(FIR)); 15 | 16 | fir->N = stepSize; 17 | 18 | fir->inputBuffer = (float*)calloc(2*stepSize, sizeof(float)); 19 | 20 | return fir; 21 | 22 | } 23 | 24 | void processFIRFilter(FIR* fir, float* input, float* output) { 25 | 26 | int i,j, idx; 27 | float temp; 28 | 29 | for (i = 0; i < fir->N; i++) { 30 | fir->inputBuffer[i] = fir->inputBuffer[fir->N + i]; 31 | fir->inputBuffer[fir->N + i] = input[i]; 32 | } 33 | 34 | for (i = 0; i < fir->N; i++) { 35 | temp = 0; 36 | 37 | for (j = 0; j < NCOEFFS; j++) { 38 | idx = fir->N + (i - j); 39 | temp += (fir->inputBuffer[idx]*filterCoefficients[j]); 40 | } 41 | output[i] = temp; 42 | } 43 | } 44 | 45 | void destroyFIR(FIR **fir) { 46 | 47 | if ((*fir) != NULL) { 48 | 49 | if ((*fir)->inputBuffer != NULL) { 50 | free((*fir)->inputBuffer); 51 | (*fir)->inputBuffer = NULL; 52 | } 53 | 54 | free((*fir)); 55 | (*fir) = NULL; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/FIRFilter.h: -------------------------------------------------------------------------------- 1 | // 2 | // FIRFilter.h 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/18/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #ifndef FIRFilter_h 10 | #define FIRFilter_h 11 | 12 | #include 13 | #include 14 | 15 | 16 | 17 | typedef struct FIR { 18 | 19 | int N; 20 | 21 | float* inputBuffer; 22 | } FIR; 23 | 24 | FIR* initFIR(int stepSize); 25 | void processFIRFilter(FIR* fir, float* input, float* output); 26 | void destroyFIR(FIR **fir); 27 | 28 | #endif /* FIRFilter_h */ 29 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/IOSAudioController.h: -------------------------------------------------------------------------------- 1 | // 2 | // IOSAudioController.h 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TPCircularBuffer.h" 11 | #import 12 | #import 13 | #import 14 | #import "MovingAverageBuffer.h" 15 | #import "SpeechProcessing.h" 16 | 17 | @interface IOSAudioController : NSObject { 18 | AudioUnit au; 19 | } 20 | 21 | @property AudioUnit au; 22 | @property MovingAverageBuffer *timeBuffer; 23 | @property int allocFrameSize; 24 | @property NSString* info; 25 | @property int classLabel; 26 | @property MovingAverageBuffer *classBuffer; 27 | - (void) processAudio; 28 | - (void) start: (BOOL) store; 29 | - (void) stop; 30 | 31 | @end 32 | 33 | extern IOSAudioController* audioController; 34 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/IOSAudioController.m: -------------------------------------------------------------------------------- 1 | // 2 | // IOSAudioController.m 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #import "IOSAudioController.h" 10 | 11 | #define kOutputBus 0 12 | #define kInputBus 1 13 | #define SHORT2FLOAT 1/32768.0 14 | #define FLOAT2SHORT 32768.0 15 | #define NUMCHANNELS 2 16 | #define BUFFER 64 17 | #define FRAMESIZE 600 18 | #define FS 48000 19 | #define DECISIONBUFFERLENGTH 25 20 | 21 | 22 | 23 | long **memoryPointers; 24 | float **bufs, **outBufs, *scoreLeft, *scoreRight; 25 | TPCircularBuffer *inputBuffer, *outputBuffer; 26 | AudioBufferList *inputBufferList; 27 | IOSAudioController *audioController; 28 | NSDate *start; 29 | NSTimeInterval timeElapsed = 0; 30 | int allocFrameSize; 31 | int classLabel; 32 | static int* smoothingBuffer; 33 | static int smoothingBufferLength; 34 | 35 | AudioStreamBasicDescription format; 36 | ExtAudioFileRef cfref; 37 | NSString* str; 38 | 39 | 40 | static OSStatus playbackCallback(void *inRefCon, 41 | AudioUnitRenderActionFlags *ioActionFlags, 42 | const AudioTimeStamp *inTimeStamp, 43 | UInt32 inBusNumber, 44 | UInt32 inNumberFrames, 45 | AudioBufferList *ioData) { 46 | 47 | if (outputBuffer->fillCount >= ioData->mBuffers[0].mDataByteSize) { 48 | AudioBuffer buffer = ioData->mBuffers[0]; 49 | UInt32 size = buffer.mDataByteSize; 50 | int32_t availableBytes; 51 | short* tail = TPCircularBufferTail(outputBuffer, &availableBytes); 52 | memcpy(buffer.mData, tail, size); 53 | TPCircularBufferConsume(outputBuffer, size); 54 | } 55 | 56 | return noErr; 57 | } 58 | 59 | static OSStatus recordingCallback(void *inRefCon, 60 | AudioUnitRenderActionFlags *ioActionFlags, 61 | const AudioTimeStamp *inTimeStamp, 62 | UInt32 inBusNumber, 63 | UInt32 inNumberFrames, 64 | AudioBufferList *ioData) { 65 | 66 | //Create Audio Buffer List 67 | inputBufferList->mNumberBuffers = 1;//NUMCHANNELS; 68 | 69 | inputBufferList->mBuffers[0].mDataByteSize = NUMCHANNELS * inNumberFrames * sizeof(short); 70 | inputBufferList->mBuffers[0].mNumberChannels = NUMCHANNELS; 71 | inputBufferList->mBuffers[0].mData = malloc(inputBufferList->mBuffers[0].mDataByteSize); 72 | 73 | 74 | 75 | 76 | // Render audio into the input buffer list 77 | AudioUnitRender(audioController.au, 78 | ioActionFlags, 79 | inTimeStamp, 80 | inBusNumber, 81 | inNumberFrames, 82 | inputBufferList); 83 | 84 | TPCircularBufferProduceBytes(inputBuffer, (void*)inputBufferList->mBuffers[0].mData, inputBufferList->mBuffers[0].mDataByteSize); 85 | 86 | if (inputBuffer->fillCount >= FRAMESIZE*sizeof(short)*NUMCHANNELS) { 87 | start = [NSDate date]; 88 | [audioController processAudio]; 89 | [audioController.timeBuffer addDatum:[NSNumber numberWithFloat:[[NSDate date] timeIntervalSinceDate:start]]]; 90 | audioController.allocFrameSize = inNumberFrames; 91 | } 92 | 93 | if (cfref != NULL) { 94 | ExtAudioFileWriteAsync(cfref, inNumberFrames, inputBufferList); 95 | } 96 | free(inputBufferList->mBuffers[0].mData); 97 | inputBufferList->mBuffers[0].mData = NULL; 98 | 99 | 100 | 101 | return noErr; 102 | } 103 | 104 | void deinterleave(const short* interleavedAudio, float* leftChannel, float* rightChannel, int nSamples){ 105 | 106 | for (int i = 0; i < nSamples; i++) { 107 | leftChannel[i] = ((float)interleavedAudio[2*i]) * SHORT2FLOAT; 108 | rightChannel[i] = ((float)interleavedAudio[(2*i) + 1]) * SHORT2FLOAT; 109 | } 110 | 111 | } 112 | 113 | void interleave(const float* leftChannel, const float* rightChannel, short* interleavedAudio, int nSamples){ 114 | for (int i = 0; i < nSamples; i++) { 115 | interleavedAudio[2*i] = (short)(FLOAT2SHORT * leftChannel[i]); 116 | interleavedAudio[(2*i) + 1] = (short)(FLOAT2SHORT * rightChannel[i]); 117 | } 118 | } 119 | 120 | 121 | @implementation IOSAudioController 122 | 123 | @synthesize au, timeBuffer, info; 124 | 125 | - (id) init { 126 | 127 | self = [super init]; 128 | 129 | // Create the audio session 130 | [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayAndRecord 131 | error: NULL]; 132 | [[AVAudioSession sharedInstance] setMode: AVAudioSessionModeMeasurement 133 | error:NULL]; 134 | [[AVAudioSession sharedInstance] setPreferredSampleRate:FS 135 | error:NULL]; 136 | [[AVAudioSession sharedInstance] setPreferredIOBufferDuration:(float)BUFFER/(float)FS 137 | error:NULL]; 138 | 139 | 140 | // Setup Audio Component Description 141 | AudioComponentDescription desc; 142 | desc.componentType = kAudioUnitType_Output; 143 | desc.componentSubType = kAudioUnitSubType_RemoteIO; 144 | desc.componentFlags = 0; 145 | desc.componentFlagsMask = 0; 146 | desc.componentManufacturer = kAudioUnitManufacturer_Apple; 147 | AudioComponent component = AudioComponentFindNext(NULL, &desc); 148 | if (AudioComponentInstanceNew(component, &au) != 0) abort(); 149 | 150 | 151 | UInt32 value = 1; 152 | if (AudioUnitSetProperty(au, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &value, sizeof(value))) abort(); 153 | value = 1; 154 | if (AudioUnitSetProperty(au, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &value, sizeof(value))) abort(); 155 | 156 | // Setup Audio Stream Basic Description 157 | //AudioStreamBasicDescription format; 158 | format.mSampleRate = FS; 159 | format.mFormatID = kAudioFormatLinearPCM; 160 | format.mFormatFlags = kAudioFormatFlagIsSignedInteger; 161 | format.mFramesPerPacket = 1; 162 | format.mChannelsPerFrame = NUMCHANNELS; 163 | format.mBitsPerChannel = 16; 164 | format.mBytesPerPacket = 4; 165 | format.mBytesPerFrame = 4; 166 | if (AudioUnitSetProperty(au, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &format, sizeof(format))) abort(); 167 | if (AudioUnitSetProperty(au, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &format, sizeof(format))) abort(); 168 | 169 | // Set input callback 170 | AURenderCallbackStruct callbackStruct; 171 | callbackStruct.inputProc = recordingCallback; 172 | callbackStruct.inputProcRefCon = (__bridge void *)(self); 173 | AudioUnitSetProperty(au, 174 | kAudioOutputUnitProperty_SetInputCallback, 175 | kAudioUnitScope_Global, 176 | kInputBus, 177 | &callbackStruct, 178 | sizeof(callbackStruct)); 179 | 180 | 181 | 182 | // Set output callback 183 | callbackStruct.inputProc = playbackCallback; 184 | callbackStruct.inputProcRefCon = (__bridge void *)(self); 185 | AudioUnitSetProperty(au, 186 | kAudioUnitProperty_SetRenderCallback, 187 | kAudioUnitScope_Global, 188 | kOutputBus, 189 | &callbackStruct, 190 | sizeof(callbackStruct)); 191 | 192 | AudioUnitInitialize(au); 193 | 194 | timeBuffer = [[MovingAverageBuffer alloc] initWithPeriod:round(FS/FRAMESIZE)]; 195 | NSLog(@"Sampling Frequency of Device:\t%.0f", [AVAudioSession sharedInstance].sampleRate); 196 | NSLog(@"Input Buffer Size for Callback:\t%.0f", [AVAudioSession sharedInstance].IOBufferDuration*[AVAudioSession sharedInstance].sampleRate); 197 | NSLog(@"Specified Overlap Frame Size:\t%d",FRAMESIZE); 198 | 199 | /* Getting all the available inputs */ 200 | 201 | AVAudioSession* myAudioSession = [AVAudioSession sharedInstance]; 202 | NSArray* inputs = myAudioSession.currentRoute.inputs; 203 | for (AVAudioSessionPortDescription* port in inputs) { 204 | str = [NSString stringWithFormat:@"%@", port.portType]; 205 | info = [NSString stringWithFormat:@"Microphone Specifications\n\nPort: %@\nUID: %@\n\n\nAudio I/O Setup\n\nInput Microphones:\t%lu\nOutput Speakers:\t%lu\n\n\nNoise Classifier Setup\n\nFeatures: Subband Features\nNumber of Subbands Used: %d\n\nClassifier: Random Forest\nNumber of Trees Used: %d\n", 206 | port.portName, 207 | port.UID, 208 | (long)myAudioSession.maximumInputNumberOfChannels, 209 | (long)myAudioSession.maximumOutputNumberOfChannels, 210 | 8,20]; 211 | 212 | } 213 | 214 | return self; 215 | 216 | } 217 | 218 | - (void) start: (BOOL) store { 219 | 220 | // Setup the circular buffers, float buffers and algorithm memory pointers 221 | memoryPointers = (long**)malloc(sizeof(long*) * NUMCHANNELS); 222 | for (size_t n = 0; n < NUMCHANNELS; n++) { 223 | memoryPointers[n] = initialize(FRAMESIZE, FS, DECISIONBUFFERLENGTH); 224 | } 225 | inputBuffer = (TPCircularBuffer*)malloc(sizeof(TPCircularBuffer)); 226 | outputBuffer = (TPCircularBuffer*)malloc(sizeof(TPCircularBuffer)); 227 | TPCircularBufferInit(inputBuffer, 2048*16); 228 | TPCircularBufferInit(outputBuffer, 2048*16); 229 | 230 | scoreLeft = (float*)calloc(returnElements(memoryPointers[0]), sizeof(float)); 231 | scoreRight = (float*)calloc(returnElements(memoryPointers[1]), sizeof(float)); 232 | 233 | smoothingBufferLength = 13; 234 | smoothingBuffer = calloc(sizeof(int), smoothingBufferLength); 235 | 236 | bufs = (float**)malloc(sizeof(float*)*NUMCHANNELS); 237 | outBufs = (float**)malloc(sizeof(float*)*NUMCHANNELS); 238 | for (size_t n = 0; n < NUMCHANNELS; n++) { 239 | bufs[n] = (float*)calloc(FRAMESIZE, sizeof(float)); 240 | outBufs[n] = (float*)calloc(FRAMESIZE, sizeof(float)); 241 | }; 242 | 243 | // define input buffer list 244 | inputBufferList = (AudioBufferList *)malloc(sizeof(AudioBufferList) 245 | + sizeof(AudioBuffer) * 2); 246 | 247 | if (store) { 248 | 249 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 250 | [formatter setDateFormat:@"MM_dd_yyyy_HH_mm_ss"]; 251 | NSString* dateString = [formatter stringFromDate:[NSDate date]]; 252 | 253 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 254 | NSString *documentsDirectory = [paths objectAtIndex:0]; 255 | NSString* destinationFilePath = [[NSString alloc] initWithFormat: @"%@/%@_%@.caf", documentsDirectory, str, dateString]; 256 | CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false); 257 | 258 | OSStatus status; 259 | 260 | 261 | 262 | status = ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, 263 | &format, NULL, kAudioFileFlags_EraseFile, 264 | &cfref); 265 | } 266 | 267 | // Start the audio 268 | AudioOutputUnitStart(au); 269 | } 270 | 271 | - (void) stop { 272 | 273 | // Stop the audio 274 | AudioOutputUnitStop(au); 275 | 276 | if (cfref != NULL) { 277 | ExtAudioFileDispose(cfref); 278 | } 279 | 280 | 281 | // Clean up all initialized memory 282 | for (size_t n = 0; n < NUMCHANNELS; n++) { 283 | destroy(memoryPointers[n]); 284 | } 285 | free(memoryPointers); 286 | memoryPointers = NULL; 287 | 288 | free(inputBuffer); 289 | inputBuffer = NULL; 290 | free(outputBuffer); 291 | outputBuffer = NULL; 292 | 293 | for (size_t n = 0; n < NUMCHANNELS; n++) { 294 | free(bufs[n]); 295 | bufs[n] = NULL; 296 | free(outBufs[n]); 297 | outBufs[n] = NULL; 298 | } 299 | free(bufs); 300 | bufs = NULL; 301 | free(outBufs); 302 | outBufs = NULL; 303 | free(inputBufferList); 304 | inputBufferList = NULL; 305 | 306 | } 307 | 308 | - (void) processAudio { 309 | 310 | uint32_t frameSize = FRAMESIZE * sizeof(short) * NUMCHANNELS; 311 | int32_t availableBytes; 312 | 313 | short* tail = TPCircularBufferTail(inputBuffer, &availableBytes); 314 | 315 | if (availableBytes >= frameSize) { 316 | // Deinterleave to float 317 | deinterleave(tail, bufs[0], bufs[1], FRAMESIZE); 318 | 319 | // Run the algorithms 320 | for (int i = 0; i < NUMCHANNELS; i++) { 321 | compute(memoryPointers[i], bufs[i], outBufs[i], i); 322 | 323 | } 324 | 325 | getScores(memoryPointers[0], scoreLeft); 326 | getScores(memoryPointers[1], scoreRight); 327 | 328 | float maxScore = 0.0; 329 | for (int i = 0; i < returnElements(memoryPointers[0]); i++) { 330 | if (maxScore < scoreRight[i]*scoreLeft[i]) { 331 | classLabel = i+1; 332 | maxScore = scoreRight[i]*scoreLeft[i]; 333 | 334 | } 335 | int i, class1 = 0, class2 = 0, class3 = 0; 336 | 337 | for (i = smoothingBufferLength-1; i > 0 ; i--) { 338 | smoothingBuffer[i] = smoothingBuffer[i-1]; 339 | } 340 | 341 | smoothingBuffer[0] = classLabel; 342 | 343 | for (i = 0; i < smoothingBufferLength; i++) { 344 | switch (smoothingBuffer[i]) { 345 | case 1: 346 | class1++; 347 | break; 348 | case 2: 349 | class2++; 350 | break; 351 | case 3: 352 | class3++; 353 | break; 354 | default: 355 | break; 356 | } 357 | } 358 | 359 | if (class1 > class2) { 360 | if (class1 > class3) { 361 | audioController.classLabel = 1; 362 | } 363 | else { 364 | audioController.classLabel = 3; 365 | } 366 | } 367 | else { 368 | if (class2 > class3) { 369 | audioController.classLabel = 2; 370 | } 371 | else { 372 | audioController.classLabel = 3; 373 | } 374 | } 375 | } 376 | 377 | 378 | // Interleave data into short 379 | short* head = TPCircularBufferHead(outputBuffer, &availableBytes); 380 | interleave(outBufs[0], outBufs[1], head, FRAMESIZE); 381 | 382 | 383 | TPCircularBufferProduce(outputBuffer, frameSize); 384 | TPCircularBufferConsume(inputBuffer, frameSize); 385 | 386 | } 387 | } 388 | 389 | -(void) dealloc{ 390 | 391 | 392 | } 393 | 394 | @end 395 | 396 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | NSMicrophoneUsageDescription 24 | 25 | UIFileSharingEnabled 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/MovingAverageBuffer.h: -------------------------------------------------------------------------------- 1 | // 2 | // MovingAverageBuffer.h 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MovingAverageBuffer : NSObject 12 | 13 | @property (readonly, nonatomic) float movingAverage; 14 | @property (readonly, nonatomic) float cumulativeAverage; 15 | 16 | - (id) initWithPeriod:(NSUInteger)period; 17 | - (void) addDatum:(NSNumber *)datum; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/MovingAverageBuffer.m: -------------------------------------------------------------------------------- 1 | // 2 | // MovingAverageBuffer.m 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #import "MovingAverageBuffer.h" 10 | 11 | @interface MovingAverageBuffer() 12 | @property (strong, nonatomic) NSMutableArray *queue; 13 | @property (assign, nonatomic) NSUInteger period; 14 | @property (assign, nonatomic) NSUInteger count; 15 | @property (assign, nonatomic) float movingAverage; 16 | @property (assign, nonatomic) float cumulativeAverage; 17 | @end 18 | 19 | @implementation MovingAverageBuffer 20 | 21 | - (id)initWithPeriod:(NSUInteger)period { 22 | 23 | self = [self init]; 24 | if(self){ 25 | _period = period; 26 | _queue = [NSMutableArray array]; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)addDatum:(NSNumber *)datum { 32 | 33 | [self.queue insertObject:datum atIndex:0]; 34 | 35 | float removed = 0; 36 | float datumf = [datum floatValue]; 37 | 38 | if(self.queue.count > self.period) { 39 | removed = [[self.queue lastObject] floatValue]; 40 | [self.queue removeLastObject]; 41 | } 42 | 43 | self.movingAverage = self.movingAverage - (removed/self.period) + (datumf/self.period); 44 | 45 | self.cumulativeAverage = self.cumulativeAverage + (datumf - self.cumulativeAverage)/++self.count; 46 | 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/NC-2Ch-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "IOSAudioController.h" 6 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/RandomForest.c: -------------------------------------------------------------------------------- 1 | /* 2 | * RandomForest.c 3 | * 4 | * Created on: Apr 17, 2015 5 | * Author: Carissa 6 | */ 7 | 8 | #include "RandomForest.h" 9 | #include "TrainData.h" 10 | 11 | RandomForests* initRandomForest() { 12 | RandomForests* newRandomForest; 13 | 14 | newRandomForest = (RandomForests*)malloc(sizeof(RandomForests)); 15 | newRandomForest->nTrees = nTrees; 16 | newRandomForest->nClasses = nClasses; 17 | newRandomForest->classDecision = -1; 18 | newRandomForest->treeVotes = (int*)malloc(nTrees*sizeof(int)); 19 | newRandomForest->scores = (float*)malloc(nClasses*sizeof(float)); 20 | 21 | 22 | return newRandomForest; 23 | } 24 | 25 | const char* returnClassLabel(int classIndex) { 26 | 27 | if (classIndex < 1) { 28 | return classLabels[0]; 29 | } 30 | else{ 31 | return classLabels[classIndex]; 32 | } 33 | } 34 | 35 | void evalTrees(RandomForests* RandomForest, float* inputFeatureList) { 36 | RandomForests* rf = RandomForest; 37 | int i; 38 | int current_node; 39 | int cvar; 40 | //int tree_output[nTrees]; 41 | int classVotes[nClasses]; 42 | int max; 43 | //int mismatch_count=0; 44 | //float newNormalizedClassDecision; 45 | 46 | // Initialize vote counts to zero 47 | for(i=0;inTrees ;i++) 53 | { 54 | current_node = 0; 55 | while (childnode[i][current_node]!=0) 56 | { 57 | cvar = nodeCutVar[i][current_node]; 58 | //if (inputFeatureList[i + (cvar-1)*M] < nodeCutValue[i][current_node]) 59 | if( (inputFeatureList[cvar-1]) < nodeCutValue[i][current_node]) 60 | current_node = childnode[i][current_node]-1; 61 | else current_node = childnode[i][current_node]; 62 | } 63 | rf->treeVotes[i] = nodelabel[i][current_node]; // for debug 64 | classVotes[(nodelabel[i][current_node])-1]++; 65 | } 66 | 67 | // Check which class received the most votes 68 | max=classVotes[0]; 69 | rf->classDecision = 1; 70 | rf->scores[0] = (float)classVotes[0]/(float)nTrees; 71 | //rf->classDecisionCount[0]=classVotes[0]; 72 | for(i=1;inClasses;i++) 73 | { 74 | rf->scores[i] = (float)classVotes[i]/(float)nTrees; 75 | //rf->classDecisionCount[i]=classVotes[i]; 76 | if(classVotes[i]>max) 77 | { 78 | max=classVotes[i]; 79 | rf->classDecision=i+1; 80 | } 81 | } 82 | 83 | 84 | // // Multiply the class decision by 1/N 85 | // newNormalizedClassDecision = rf->Normalize * (float)rf->classDecision; 86 | // // Remove the oldest decision from the average 87 | // rf->floatAverageClassDecision -= rf->classDecisionBuffer[rf->oldestClassDecision]; 88 | // // Add the newest decision to the average 89 | // rf->floatAverageClassDecision += newNormalizedClassDecision; 90 | // // Store the newest cbn to the periodicity buffer 91 | // rf->classDecisionBuffer[rf->oldestClassDecision]=newNormalizedClassDecision; 92 | // 93 | // // Round the floating point average class to an integer class 94 | // rf->averageClassDecision = (int) (rf->floatAverageClassDecision + 0.5); 95 | // // Update the pointer in the decision buffer 96 | // if (rf->oldestClassDecision < rf->bufferLength-1) 97 | // rf->oldestClassDecision++; 98 | // else 99 | // rf->oldestClassDecision=0; 100 | } 101 | 102 | void destroyRandomForest(RandomForests** rf) { 103 | if((*rf)->treeVotes != NULL){ 104 | free((*rf)->treeVotes); 105 | (*rf)->treeVotes = NULL; 106 | } 107 | // if((*rf)->classDecisionCount != NULL){ 108 | // free((*rf)->classDecisionCount); 109 | // (*rf)->classDecisionCount = NULL; 110 | // } 111 | if(*rf != NULL){ 112 | free(*rf); 113 | *rf=NULL; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/RandomForest.h: -------------------------------------------------------------------------------- 1 | /* 2 | * RandomForest.h 3 | * 4 | * Created on: Apr 17, 2015 5 | * Author: Carissa 6 | */ 7 | 8 | #ifndef RANDOMFOREST_H_ 9 | #define RANDOMFOREST_H_ 10 | #define _USE_MATH_DEFINES 11 | 12 | #include 13 | #include 14 | 15 | typedef struct RandomForests { 16 | int nTrees; // Number of trees 17 | int nClasses; // Number of noise classes 18 | int classDecision; // Classifier output result 19 | int* treeVotes; // class vote from each tree for debug 20 | float* scores; 21 | } RandomForests; 22 | 23 | /*! 24 | * Initializes the Random Forest Classifier 25 | * 26 | * This function initializes the Random Forest Classifier and sets 27 | * the parameters for the different trees 28 | * 29 | * @return pointer to initialized Random Forest Classifier 30 | * 31 | */ 32 | RandomForests* initRandomForest(); 33 | 34 | /*! 35 | * Predicts the class based on the features provided 36 | * 37 | * This function accepts the feature vector and then classifies the vector. 38 | * The classification output is stored in the classDecision variable of 39 | * the random forest structure 40 | * 41 | * @param RandomForest pointer to initialized Random Forest Classifier 42 | * @param inputFeatureList The features based on which the classifier makes 43 | * a decision 44 | * 45 | * 46 | */ 47 | void evalTrees(RandomForests* RandomForest, float* inputFeatureList); 48 | 49 | const char* returnClassLabel(int classIndex); 50 | void destroyRandomForest(RandomForests** rf); 51 | 52 | #endif /* RANDOMFOREST_H_ */ 53 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/SpeechProcessing.c: -------------------------------------------------------------------------------- 1 | // 2 | // SpeechProcessing.c 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #include "SpeechProcessing.h" 10 | 11 | #define DECIMATION_FACTOR 3 12 | 13 | static int* smoothingBuffer; 14 | static int smoothingBufferLength; 15 | 16 | long* initialize(int stepSize, int samplingFrequency, int decisionBufferLength) { 17 | 18 | Variables* inParam = (Variables*)malloc(sizeof(Variables)); 19 | 20 | inParam->stepSize = (int)floor((float)stepSize/(float)DECIMATION_FACTOR); 21 | inParam->frameSize = 2 * inParam->stepSize; 22 | inParam->fs = samplingFrequency; 23 | inParam->firstFrame = 1; 24 | inParam->frameCount = 0; 25 | inParam->decisionBufferLength = decisionBufferLength; 26 | inParam->class = -1; 27 | 28 | inParam->fir = initFIR(stepSize); 29 | 30 | int pow2size = 0x1; 31 | 32 | while (pow2size < inParam->frameSize) { 33 | pow2size = pow2size << 1; 34 | } 35 | 36 | inParam->input = (float complex *)calloc(sizeof(float complex), inParam->frameSize); 37 | inParam->fft = initTransform(inParam->frameSize, (int)(samplingFrequency/stepSize), pow2size); 38 | inParam->sf = initSubbandFeatures(inParam->fft->nFFT, decisionBufferLength); 39 | inParam->rf = initRandomForest(); 40 | 41 | smoothingBufferLength = 5; 42 | smoothingBuffer = calloc(sizeof(int), smoothingBufferLength); 43 | 44 | return (long*)inParam; 45 | } 46 | 47 | void compute(long *memoryPointer, float *input, float* output, size_t channelNo){ 48 | 49 | Variables* inParam = (Variables*)memoryPointer; 50 | 51 | processFIRFilter(inParam->fir, input, output); 52 | 53 | for (size_t n = 0; n < inParam->stepSize; n++) { 54 | inParam->input[n] = inParam->input[n + inParam->stepSize]; 55 | inParam->input[n + inParam->stepSize] = output[3*n]; 56 | } 57 | 58 | // Compute the FFT of the incoming frame 59 | FFT(inParam->fft, inParam->input); 60 | 61 | // Calculate the subband features of the frame 62 | computeSubbandFeatures(inParam->sf, inParam->fft, &inParam->firstFrame); 63 | 64 | if (inParam->frameCount > inParam->decisionBufferLength) { 65 | evalTrees(inParam->rf, inParam->sf->subbandFeatureList); 66 | if (channelNo) { 67 | printf("%f, %f, %f\n",inParam->rf->scores[0], 68 | inParam->rf->scores[1], 69 | inParam->rf->scores[2]); 70 | } 71 | inParam->frameCount = 0; 72 | 73 | inParam->class = inParam->rf->classDecision; 74 | 75 | 76 | //Smoothing buffer: The decision is averaged over 77 | // a duration of 5 * Decision Buffer Length * step size 78 | int i, class1 = 0, class2 = 0, class3 = 0; 79 | 80 | for (i = smoothingBufferLength-1; i > 0 ; i--) { 81 | smoothingBuffer[i] = smoothingBuffer[i-1]; 82 | } 83 | 84 | smoothingBuffer[0] = inParam->rf->classDecision; 85 | 86 | for (i = 0; i < smoothingBufferLength; i++) { 87 | switch (smoothingBuffer[i]) { 88 | case 1: 89 | class1++; 90 | break; 91 | case 2: 92 | class2++; 93 | break; 94 | case 3: 95 | class3++; 96 | break; 97 | default: 98 | break; 99 | } 100 | } 101 | 102 | if (class1 > class2) { 103 | if (class1 > class3) { 104 | inParam->class = 1; 105 | } 106 | else { 107 | inParam->class = 3; 108 | } 109 | } 110 | else { 111 | if (class2 > class3) { 112 | inParam->class = 2; 113 | } 114 | else { 115 | inParam->class = 3; 116 | } 117 | } 118 | } 119 | else{ 120 | inParam->frameCount++; 121 | } 122 | // 123 | // 124 | // memcpy(output, input, sizeof(float) * inParam->stepSize); 125 | 126 | } 127 | 128 | 129 | 130 | int returnElements(long* memoryPointer){ 131 | Variables* inParam = (Variables*)memoryPointer; 132 | return inParam->rf->nClasses; 133 | } 134 | 135 | void getScores(long* memoryPointer, float* scores){ 136 | Variables* inParam = (Variables*)memoryPointer; 137 | 138 | for(int i = 0; i < inParam->rf->nClasses; i++){ 139 | scores[i] = inParam->rf->scores[i]; 140 | } 141 | } 142 | 143 | void copyArray(long *memoryPointer, float* array){ 144 | Variables* inParam = (Variables*)memoryPointer; 145 | memcpy(array, inParam->fir->inputBuffer + inParam->fir->N, inParam->fir->N * sizeof(float)); 146 | } 147 | 148 | 149 | 150 | void destroy(long* memoryPointer) { 151 | 152 | Variables* inParam = (Variables*)memoryPointer; 153 | 154 | if (memoryPointer != NULL) { 155 | 156 | destroyFIR(&(inParam->fir)); 157 | destroyTransform2(&(inParam->fft)); 158 | destroySubbandFeatures(&(inParam->sf)); 159 | destroyRandomForest(&(inParam->rf)); 160 | 161 | if (inParam->input != NULL) { 162 | free(inParam->input); 163 | inParam->input = NULL; 164 | } 165 | 166 | free(inParam); 167 | inParam = NULL; 168 | } 169 | 170 | } 171 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/SpeechProcessing.h: -------------------------------------------------------------------------------- 1 | // 2 | // SpeechProcessing.h 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #ifndef SpeechProcessing_h 10 | #define SpeechProcessing_h 11 | 12 | #include 13 | #include 14 | #include "Transforms2.h" 15 | #include "SubbandFeatures.h" 16 | #include "RandomForest.h" 17 | #include "FIRFilter.h" 18 | 19 | typedef struct Variables { 20 | 21 | int frameSize; 22 | int stepSize; 23 | int fs; 24 | int firstFrame; 25 | int frameCount; 26 | int decisionBufferLength; 27 | int class; 28 | 29 | FIR* fir; 30 | float complex *input; 31 | Transform2 *fft; 32 | SubbandFeatures *sf; 33 | RandomForests *rf; 34 | 35 | } Variables; 36 | 37 | long* initialize(int stepSize, int samplingFrequency, int decisionBufferLength); 38 | void compute(long* memoryPointer, float* input, float* output, size_t channelNo); 39 | void destroy(long* memoryPointer); 40 | int returnElements(long* memoryPointer); 41 | void copyArray(long *memoryPointer, float* array); 42 | void getScores(long* memoryPointer, float* scores); 43 | #endif /* SpeechProcessing_h */ 44 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/SubbandFeatures.c: -------------------------------------------------------------------------------- 1 | // 2 | // SubbandFeatures.c 3 | // algorithm 4 | // 5 | // Created by Abhishek Sehgal on 5/15/17. 6 | // Copyright © 2017 default. All rights reserved. 7 | // 8 | 9 | #include "SubbandFeatures.h" 10 | 11 | // Change bands in power of 2 12 | const int NBANDS = 8; 13 | const int NHISTBINS = 10; 14 | 15 | 16 | SubbandFeatures* initSubbandFeatures(int nFFT, int decisionBufferLength) { 17 | 18 | SubbandFeatures* newSubbandFeatures = (SubbandFeatures*) malloc(sizeof(SubbandFeatures)); 19 | 20 | newSubbandFeatures->nBands = NBANDS; 21 | newSubbandFeatures->nFFT = nFFT; 22 | newSubbandFeatures->normalize = 1.0/decisionBufferLength; 23 | newSubbandFeatures->subbandWidth = nFFT/(2*NBANDS); 24 | newSubbandFeatures->histBins = NHISTBINS; 25 | newSubbandFeatures->decisionBufferLength = decisionBufferLength; 26 | 27 | 28 | newSubbandFeatures->currentFrame = (float complex*)malloc(nFFT * sizeof(float complex)); 29 | newSubbandFeatures->previousFrame = (float complex*)malloc(nFFT * sizeof(float complex)); 30 | 31 | newSubbandFeatures->histCount = (int*)calloc(sizeof(int), NHISTBINS); 32 | newSubbandFeatures->subbandPower = (float*)calloc(sizeof(float), newSubbandFeatures->subbandWidth); 33 | 34 | newSubbandFeatures->currentSubbands = (Transform2**)malloc(sizeof(Transform2*) * NBANDS); 35 | newSubbandFeatures->previousSubbands = (Transform2**)malloc(sizeof(Transform2*) * NBANDS); 36 | newSubbandFeatures->periodicityTransform = (Transform2**)malloc(sizeof(Transform2*) * NBANDS); 37 | 38 | for (size_t i = 0; i < NBANDS; i++) { 39 | newSubbandFeatures->currentSubbands[i] = initTransform(newSubbandFeatures->subbandWidth, 1, 2* newSubbandFeatures->subbandWidth); 40 | newSubbandFeatures->previousSubbands[i] = initTransform(newSubbandFeatures->subbandWidth, 1, 2* newSubbandFeatures->subbandWidth); 41 | newSubbandFeatures->periodicityTransform[i] = initTransform(2*newSubbandFeatures->subbandWidth, 1, 2* newSubbandFeatures->subbandWidth); 42 | } 43 | 44 | newSubbandFeatures->subbandFeatureList = (float*)calloc(sizeof(float), 2 * NBANDS); 45 | newSubbandFeatures->bandPeriodicity = newSubbandFeatures->subbandFeatureList; 46 | newSubbandFeatures->bandEntropy = newSubbandFeatures->subbandFeatureList + NBANDS; 47 | 48 | newSubbandFeatures->bandEntropyBuffer = (float**)malloc(sizeof(float*) * NBANDS); 49 | newSubbandFeatures->bandPeriodicityBuffer = (float**)malloc(sizeof(float*) * NBANDS); 50 | 51 | for (size_t i = 0; i < NBANDS; i++) { 52 | 53 | newSubbandFeatures->bandPeriodicityBuffer[i] = (float*)calloc(sizeof(float), decisionBufferLength); 54 | newSubbandFeatures->bandEntropyBuffer[i] = (float*)calloc(sizeof(float), decisionBufferLength); 55 | 56 | } 57 | 58 | return newSubbandFeatures; 59 | 60 | } 61 | 62 | void computeSubbandFeatures(SubbandFeatures* sbf, Transform2* fft, int *isFirstFrame){ 63 | 64 | float histMin, histMax, max, temp, currentSum, previousSum, histWidth, histSum; 65 | 66 | memcpy(sbf->currentFrame, fft->input, sizeof(float complex) * fft->nFFT); 67 | if (*isFirstFrame == 1) { 68 | memcpy(sbf->previousFrame, fft->input, sizeof(float complex) * fft->nFFT); 69 | (*isFirstFrame) = 0; 70 | } 71 | 72 | // Calculating Band Periodicity 73 | for (size_t i = 0; i < NBANDS; i++) { 74 | 75 | max = 0; 76 | histMin = 1; 77 | histMax = 0; 78 | histSum = 0; 79 | currentSum = 0; 80 | previousSum = 0; 81 | 82 | for (size_t n = 0; n < sbf->subbandWidth; n++) { 83 | sbf->subbandPower[n] = cabsf(sbf->currentFrame[n + (i * sbf->subbandWidth)]); 84 | histMax = (histMax > sbf->subbandPower[n] ? histMax : sbf->subbandPower[n]); 85 | histMin = (histMin < sbf->subbandPower[n] ? histMin : sbf->subbandPower[n]); 86 | 87 | currentSum += powf(sbf->subbandPower[n],2); 88 | previousSum += powf(cabsf(sbf->previousFrame[n + (i * sbf->subbandWidth)]),2); 89 | } 90 | 91 | // Calculating Band Periodicity 92 | 93 | FFTwithoutWindow(sbf->currentSubbands[i], sbf->currentFrame + (i * sbf->subbandWidth)); 94 | FFTwithoutWindow(sbf->previousSubbands[i], sbf->previousFrame + (i * sbf->subbandWidth)); 95 | 96 | for (size_t n = 0; n < sbf->periodicityTransform[i]->nFFT; n++) { 97 | sbf->periodicityTransform[i]->input[n] = sbf->currentSubbands[i]->input[n] * conjf(sbf->previousSubbands[i]->input[n]); 98 | } 99 | 100 | IFFT(sbf->periodicityTransform[i]); 101 | 102 | for (size_t n = 0; n < sbf->periodicityTransform[i]->nFFT; n++) { 103 | temp = cabsf(sbf->periodicityTransform[i]->input[n]); 104 | max = (max > temp ? max : temp); 105 | } 106 | max /= (sqrtf(currentSum * previousSum) + 1e-10); 107 | 108 | sbf->bandPeriodicity[i] = sbf->bandPeriodicity[i] + (max - sbf->bandPeriodicityBuffer[i][0])*sbf->normalize; 109 | memcpy(sbf->bandPeriodicityBuffer[i], sbf->bandPeriodicityBuffer[i] + 1, 110 | sizeof(sbf->bandPeriodicityBuffer[i][0]) * (sbf->decisionBufferLength - 1)); 111 | sbf->bandPeriodicityBuffer[i][sbf->decisionBufferLength - 1] = max; 112 | 113 | 114 | // Calculating Band Entropy 115 | 116 | histWidth = (histMax - histMin)/NHISTBINS; 117 | memset(sbf->histCount, 0, NHISTBINS * sizeof(sbf->histCount[0])); 118 | 119 | for (size_t n = 0; n < sbf->subbandWidth; n++) { 120 | size_t k; 121 | for (k = 0; k < NHISTBINS && sbf->subbandPower[n] >= (histMin + k*histWidth); k++); 122 | ++sbf->histCount[k-1]; 123 | } 124 | 125 | for (size_t n = 0; n < NHISTBINS; n++) { 126 | histSum += sbf->histCount[n] * logf(sbf->histCount[n] + 1e-10); 127 | } 128 | histSum /= sbf->subbandWidth; 129 | 130 | sbf->bandEntropy[i] = sbf->bandEntropy[i] + (histSum - sbf->bandEntropyBuffer[i][0])*sbf->normalize; 131 | memcpy(sbf->bandEntropyBuffer[i], sbf->bandEntropyBuffer[i] + 1, 132 | sizeof(sbf->bandEntropyBuffer[i][0]) * sbf->decisionBufferLength - 1); 133 | sbf->bandEntropyBuffer[i][sbf->decisionBufferLength - 1] = histSum; 134 | } 135 | 136 | 137 | memcpy(sbf->previousFrame, sbf->currentFrame, sizeof(float complex) * fft->nFFT); 138 | 139 | } 140 | 141 | void destroySubbandFeatures(SubbandFeatures** sbf) { 142 | 143 | if (*sbf != NULL) { 144 | 145 | if((*sbf)->currentFrame != NULL){ 146 | free((*sbf)->currentFrame); 147 | (*sbf)->currentFrame = NULL; 148 | } 149 | 150 | if((*sbf)->previousFrame != NULL){ 151 | free((*sbf)->previousFrame); 152 | (*sbf)->previousFrame = NULL; 153 | } 154 | 155 | if((*sbf)->subbandPower != NULL){ 156 | free((*sbf)->subbandPower); 157 | (*sbf)->subbandPower = NULL; 158 | } 159 | 160 | if((*sbf)->histCount != NULL){ 161 | free((*sbf)->histCount); 162 | (*sbf)->histCount = NULL; 163 | } 164 | 165 | if ((*sbf)->currentSubbands != NULL) { 166 | for (size_t i =0; i < NBANDS; i++) { 167 | if ((*sbf)->currentSubbands[i] != NULL){ 168 | free((*sbf)->currentSubbands[i]); 169 | (*sbf)->currentSubbands[i] = NULL; 170 | } 171 | } 172 | 173 | free((*sbf)->currentSubbands); 174 | (*sbf)->currentSubbands = NULL; 175 | } 176 | 177 | if ((*sbf)->previousSubbands != NULL) { 178 | for (size_t i =0; i < NBANDS; i++) { 179 | if ((*sbf)->previousSubbands[i] != NULL){ 180 | free((*sbf)->previousSubbands[i]); 181 | (*sbf)->previousSubbands[i] = NULL; 182 | } 183 | } 184 | 185 | free((*sbf)->previousSubbands); 186 | (*sbf)->previousSubbands = NULL; 187 | } 188 | 189 | if ((*sbf)->periodicityTransform != NULL) { 190 | for (size_t i =0; i < NBANDS; i++) { 191 | if ((*sbf)->periodicityTransform[i] != NULL){ 192 | free((*sbf)->periodicityTransform[i]); 193 | (*sbf)->periodicityTransform[i] = NULL; 194 | } 195 | } 196 | 197 | free((*sbf)->periodicityTransform); 198 | (*sbf)->periodicityTransform = NULL; 199 | } 200 | 201 | if ((*sbf)->bandPeriodicityBuffer != NULL) { 202 | for (size_t i =0; i < NBANDS; i++) { 203 | if ((*sbf)->bandPeriodicityBuffer[i] != NULL){ 204 | free((*sbf)->bandPeriodicityBuffer[i]); 205 | (*sbf)->bandPeriodicityBuffer[i] = NULL; 206 | } 207 | } 208 | 209 | free((*sbf)->bandPeriodicityBuffer); 210 | (*sbf)->bandPeriodicityBuffer = NULL; 211 | } 212 | 213 | if ((*sbf)->bandEntropyBuffer != NULL) { 214 | for (size_t i =0; i < NBANDS; i++) { 215 | if ((*sbf)->bandEntropyBuffer[i] != NULL){ 216 | free((*sbf)->bandEntropyBuffer[i]); 217 | (*sbf)->bandEntropyBuffer[i] = NULL; 218 | } 219 | } 220 | 221 | free((*sbf)->bandEntropyBuffer); 222 | (*sbf)->bandEntropyBuffer = NULL; 223 | } 224 | 225 | if ((*sbf)->subbandFeatureList != NULL) { 226 | free((*sbf)->subbandFeatureList); 227 | (*sbf)->subbandFeatureList = NULL; 228 | (*sbf)->bandPeriodicity = NULL; 229 | (*sbf)->bandEntropy = NULL; 230 | } 231 | 232 | free((*sbf)); 233 | (*sbf) = NULL; 234 | 235 | } 236 | 237 | } 238 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/SubbandFeatures.h: -------------------------------------------------------------------------------- 1 | // 2 | // SubbandFeatures.h 3 | // algorithm 4 | // 5 | // Created by Abhishek Sehgal on 5/15/17. 6 | // Copyright © 2017 default. All rights reserved. 7 | // 8 | 9 | #ifndef SubbandFeatures_h 10 | #define SubbandFeatures_h 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "Transforms2.h" 17 | 18 | typedef struct SubbandFeatures { 19 | 20 | int nBands; 21 | int nFFT; 22 | float normalize; 23 | int subbandWidth; 24 | int histBins; 25 | int decisionBufferLength; 26 | 27 | float complex* currentFrame; 28 | float complex* previousFrame; 29 | 30 | float* subbandPower; 31 | int* histCount; 32 | 33 | Transform2** currentSubbands; 34 | Transform2** previousSubbands; 35 | Transform2** periodicityTransform; 36 | 37 | float* bandPeriodicity; 38 | float** bandPeriodicityBuffer; 39 | float* bandEntropy; 40 | float** bandEntropyBuffer; 41 | float* subbandFeatureList; 42 | 43 | 44 | } SubbandFeatures; 45 | 46 | SubbandFeatures* initSubbandFeatures(int nFFT, int decisionBufferLength); 47 | void computeSubbandFeatures(SubbandFeatures* sbf, Transform2* fft, int *isFirstFrame); 48 | void destroySubbandFeatures(SubbandFeatures** sbf); 49 | 50 | #endif /* SubbandFeatures_h */ 51 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/TPCircularBuffer.c: -------------------------------------------------------------------------------- 1 | // 2 | // TPCircularBuffer.c 3 | // Circular/Ring buffer implementation 4 | // 5 | // https://github.com/michaeltyson/TPCircularBuffer 6 | // 7 | // Created by Michael Tyson on 10/12/2011. 8 | // 9 | // Copyright (C) 2012-2013 A Tasty Pixel 10 | // 11 | // This software is provided 'as-is', without any express or implied 12 | // warranty. In no event will the authors be held liable for any damages 13 | // arising from the use of this software. 14 | // 15 | // Permission is granted to anyone to use this software for any purpose, 16 | // including commercial applications, and to alter it and redistribute it 17 | // freely, subject to the following restrictions: 18 | // 19 | // 1. The origin of this software must not be misrepresented; you must not 20 | // claim that you wrote the original software. If you use this software 21 | // in a product, an acknowledgment in the product documentation would be 22 | // appreciated but is not required. 23 | // 24 | // 2. Altered source versions must be plainly marked as such, and must not be 25 | // misrepresented as being the original software. 26 | // 27 | // 3. This notice may not be removed or altered from any source distribution. 28 | // 29 | 30 | #include "TPCircularBuffer.h" 31 | #include 32 | #include 33 | #include 34 | 35 | #define reportResult(result,operation) (_reportResult((result),(operation),strrchr(__FILE__, '/')+1,__LINE__)) 36 | static inline bool _reportResult(kern_return_t result, const char *operation, const char* file, int line) { 37 | if ( result != ERR_SUCCESS ) { 38 | printf("%s:%d: %s: %s\n", file, line, operation, mach_error_string(result)); 39 | return false; 40 | } 41 | return true; 42 | } 43 | 44 | bool _TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length, size_t structSize) { 45 | 46 | assert(length > 0); 47 | 48 | if ( structSize != sizeof(TPCircularBuffer) ) { 49 | fprintf(stderr, "TPCircularBuffer: Header version mismatch. Check for old versions of TPCircularBuffer in your project\n"); 50 | abort(); 51 | } 52 | 53 | // Keep trying until we get our buffer, needed to handle race conditions 54 | int retries = 3; 55 | while ( true ) { 56 | 57 | buffer->length = (int32_t)round_page(length); // We need whole page sizes 58 | 59 | // Temporarily allocate twice the length, so we have the contiguous address space to 60 | // support a second instance of the buffer directly after 61 | vm_address_t bufferAddress; 62 | kern_return_t result = vm_allocate(mach_task_self(), 63 | &bufferAddress, 64 | buffer->length * 2, 65 | VM_FLAGS_ANYWHERE); // allocate anywhere it'll fit 66 | if ( result != ERR_SUCCESS ) { 67 | if ( retries-- == 0 ) { 68 | reportResult(result, "Buffer allocation"); 69 | return false; 70 | } 71 | // Try again if we fail 72 | continue; 73 | } 74 | 75 | // Now replace the second half of the allocation with a virtual copy of the first half. Deallocate the second half... 76 | result = vm_deallocate(mach_task_self(), 77 | bufferAddress + buffer->length, 78 | buffer->length); 79 | if ( result != ERR_SUCCESS ) { 80 | if ( retries-- == 0 ) { 81 | reportResult(result, "Buffer deallocation"); 82 | return false; 83 | } 84 | // If this fails somehow, deallocate the whole region and try again 85 | vm_deallocate(mach_task_self(), bufferAddress, buffer->length); 86 | continue; 87 | } 88 | 89 | // Re-map the buffer to the address space immediately after the buffer 90 | vm_address_t virtualAddress = bufferAddress + buffer->length; 91 | vm_prot_t cur_prot, max_prot; 92 | result = vm_remap(mach_task_self(), 93 | &virtualAddress, // mirror target 94 | buffer->length, // size of mirror 95 | 0, // auto alignment 96 | 0, // force remapping to virtualAddress 97 | mach_task_self(), // same task 98 | bufferAddress, // mirror source 99 | 0, // MAP READ-WRITE, NOT COPY 100 | &cur_prot, // unused protection struct 101 | &max_prot, // unused protection struct 102 | VM_INHERIT_DEFAULT); 103 | if ( result != ERR_SUCCESS ) { 104 | if ( retries-- == 0 ) { 105 | reportResult(result, "Remap buffer memory"); 106 | return false; 107 | } 108 | // If this remap failed, we hit a race condition, so deallocate and try again 109 | vm_deallocate(mach_task_self(), bufferAddress, buffer->length); 110 | continue; 111 | } 112 | 113 | if ( virtualAddress != bufferAddress+buffer->length ) { 114 | // If the memory is not contiguous, clean up both allocated buffers and try again 115 | if ( retries-- == 0 ) { 116 | printf("Couldn't map buffer memory to end of buffer\n"); 117 | return false; 118 | } 119 | 120 | vm_deallocate(mach_task_self(), virtualAddress, buffer->length); 121 | vm_deallocate(mach_task_self(), bufferAddress, buffer->length); 122 | continue; 123 | } 124 | 125 | buffer->buffer = (void*)bufferAddress; 126 | buffer->fillCount = 0; 127 | buffer->head = buffer->tail = 0; 128 | buffer->atomic = true; 129 | 130 | return true; 131 | } 132 | return false; 133 | } 134 | 135 | void TPCircularBufferCleanup(TPCircularBuffer *buffer) { 136 | vm_deallocate(mach_task_self(), (vm_address_t)buffer->buffer, buffer->length * 2); 137 | memset(buffer, 0, sizeof(TPCircularBuffer)); 138 | } 139 | 140 | void TPCircularBufferClear(TPCircularBuffer *buffer) { 141 | int32_t fillCount; 142 | if ( TPCircularBufferTail(buffer, &fillCount) ) { 143 | TPCircularBufferConsume(buffer, fillCount); 144 | } 145 | } 146 | 147 | void TPCircularBufferSetAtomic(TPCircularBuffer *buffer, bool atomic) { 148 | buffer->atomic = atomic; 149 | } 150 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/TPCircularBuffer.h: -------------------------------------------------------------------------------- 1 | // 2 | // TPCircularBuffer.h 3 | // Circular/Ring buffer implementation 4 | // 5 | // https://github.com/michaeltyson/TPCircularBuffer 6 | // 7 | // Created by Michael Tyson on 10/12/2011. 8 | // 9 | // 10 | // This implementation makes use of a virtual memory mapping technique that inserts a virtual copy 11 | // of the buffer memory directly after the buffer's end, negating the need for any buffer wrap-around 12 | // logic. Clients can simply use the returned memory address as if it were contiguous space. 13 | // 14 | // The implementation is thread-safe in the case of a single producer and single consumer. 15 | // 16 | // Virtual memory technique originally proposed by Philip Howard (http://vrb.slashusr.org/), and 17 | // adapted to Darwin by Kurt Revis (http://www.snoize.com, 18 | // http://www.snoize.com/Code/PlayBufferedSoundFile.tar.gz) 19 | // 20 | // 21 | // Copyright (C) 2012-2013 A Tasty Pixel 22 | // 23 | // This software is provided 'as-is', without any express or implied 24 | // warranty. In no event will the authors be held liable for any damages 25 | // arising from the use of this software. 26 | // 27 | // Permission is granted to anyone to use this software for any purpose, 28 | // including commercial applications, and to alter it and redistribute it 29 | // freely, subject to the following restrictions: 30 | // 31 | // 1. The origin of this software must not be misrepresented; you must not 32 | // claim that you wrote the original software. If you use this software 33 | // in a product, an acknowledgment in the product documentation would be 34 | // appreciated but is not required. 35 | // 36 | // 2. Altered source versions must be plainly marked as such, and must not be 37 | // misrepresented as being the original software. 38 | // 39 | // 3. This notice may not be removed or altered from any source distribution. 40 | // 41 | 42 | #ifndef TPCircularBuffer_h 43 | #define TPCircularBuffer_h 44 | 45 | #include 46 | #include 47 | #include 48 | 49 | #ifdef __cplusplus 50 | extern "C++" { 51 | #include 52 | using namespace std; 53 | } 54 | #else 55 | #include 56 | #endif 57 | 58 | #ifdef __cplusplus 59 | extern "C" { 60 | #endif 61 | 62 | typedef struct { 63 | void *buffer; 64 | int32_t length; 65 | int32_t tail; 66 | int32_t head; 67 | volatile atomic_int fillCount; 68 | bool atomic; 69 | } TPCircularBuffer; 70 | 71 | /*! 72 | * Initialise buffer 73 | * 74 | * Note that the length is advisory only: Because of the way the 75 | * memory mirroring technique works, the true buffer length will 76 | * be multiples of the device page size (e.g. 4096 bytes) 77 | * 78 | * If you intend to use the AudioBufferList utilities, you should 79 | * always allocate a bit more space than you need for pure audio 80 | * data, so there's room for the metadata. How much extra is required 81 | * depends on how many AudioBufferList structures are used, which is 82 | * a function of how many audio frames each buffer holds. A good rule 83 | * of thumb is to add 15%, or at least another 2048 bytes or so. 84 | * 85 | * @param buffer Circular buffer 86 | * @param length Length of buffer 87 | */ 88 | #define TPCircularBufferInit(buffer, length) \ 89 | _TPCircularBufferInit(buffer, length, sizeof(*buffer)) 90 | bool _TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length, size_t structSize); 91 | 92 | /*! 93 | * Cleanup buffer 94 | * 95 | * Releases buffer resources. 96 | */ 97 | void TPCircularBufferCleanup(TPCircularBuffer *buffer); 98 | 99 | /*! 100 | * Clear buffer 101 | * 102 | * Resets buffer to original, empty state. 103 | * 104 | * This is safe for use by consumer while producer is accessing 105 | * buffer. 106 | */ 107 | void TPCircularBufferClear(TPCircularBuffer *buffer); 108 | 109 | /*! 110 | * Set the atomicity 111 | * 112 | * If you set the atomiticy to false using this method, the buffer will 113 | * not use atomic operations. This can be used to give the compiler a little 114 | * more optimisation opportunities when the buffer is only used on one thread. 115 | * 116 | * Important note: Only set this to false if you know what you're doing! 117 | * 118 | * The default value is true (the buffer will use atomic operations) 119 | * 120 | * @param buffer Circular buffer 121 | * @param atomic Whether the buffer is atomic (default true) 122 | */ 123 | void TPCircularBufferSetAtomic(TPCircularBuffer *buffer, bool atomic); 124 | 125 | // Reading (consuming) 126 | 127 | /*! 128 | * Access end of buffer 129 | * 130 | * This gives you a pointer to the end of the buffer, ready 131 | * for reading, and the number of available bytes to read. 132 | * 133 | * @param buffer Circular buffer 134 | * @param availableBytes On output, the number of bytes ready for reading 135 | * @return Pointer to the first bytes ready for reading, or NULL if buffer is empty 136 | */ 137 | static __inline__ __attribute__((always_inline)) void* TPCircularBufferTail(TPCircularBuffer *buffer, int32_t* availableBytes) { 138 | *availableBytes = buffer->fillCount; 139 | if ( *availableBytes == 0 ) return NULL; 140 | return (void*)((char*)buffer->buffer + buffer->tail); 141 | } 142 | 143 | /*! 144 | * Consume bytes in buffer 145 | * 146 | * This frees up the just-read bytes, ready for writing again. 147 | * 148 | * @param buffer Circular buffer 149 | * @param amount Number of bytes to consume 150 | */ 151 | static __inline__ __attribute__((always_inline)) void TPCircularBufferConsume(TPCircularBuffer *buffer, int32_t amount) { 152 | buffer->tail = (buffer->tail + amount) % buffer->length; 153 | if ( buffer->atomic ) { 154 | atomic_fetch_add(&buffer->fillCount, -amount); 155 | } else { 156 | buffer->fillCount -= amount; 157 | } 158 | assert(buffer->fillCount >= 0); 159 | } 160 | 161 | /*! 162 | * Access front of buffer 163 | * 164 | * This gives you a pointer to the front of the buffer, ready 165 | * for writing, and the number of available bytes to write. 166 | * 167 | * @param buffer Circular buffer 168 | * @param availableBytes On output, the number of bytes ready for writing 169 | * @return Pointer to the first bytes ready for writing, or NULL if buffer is full 170 | */ 171 | static __inline__ __attribute__((always_inline)) void* TPCircularBufferHead(TPCircularBuffer *buffer, int32_t* availableBytes) { 172 | *availableBytes = (buffer->length - buffer->fillCount); 173 | if ( *availableBytes == 0 ) return NULL; 174 | return (void*)((char*)buffer->buffer + buffer->head); 175 | } 176 | 177 | // Writing (producing) 178 | 179 | /*! 180 | * Produce bytes in buffer 181 | * 182 | * This marks the given section of the buffer ready for reading. 183 | * 184 | * @param buffer Circular buffer 185 | * @param amount Number of bytes to produce 186 | */ 187 | static __inline__ __attribute__((always_inline)) void TPCircularBufferProduce(TPCircularBuffer *buffer, int32_t amount) { 188 | buffer->head = (buffer->head + amount) % buffer->length; 189 | if ( buffer->atomic ) { 190 | atomic_fetch_add(&buffer->fillCount, amount); 191 | } else { 192 | buffer->fillCount += amount; 193 | } 194 | assert(buffer->fillCount <= buffer->length); 195 | } 196 | 197 | /*! 198 | * Helper routine to copy bytes to buffer 199 | * 200 | * This copies the given bytes to the buffer, and marks them ready for reading. 201 | * 202 | * @param buffer Circular buffer 203 | * @param src Source buffer 204 | * @param len Number of bytes in source buffer 205 | * @return true if bytes copied, false if there was insufficient space 206 | */ 207 | static __inline__ __attribute__((always_inline)) bool TPCircularBufferProduceBytes(TPCircularBuffer *buffer, const void* src, int32_t len) { 208 | int32_t space; 209 | void *ptr = TPCircularBufferHead(buffer, &space); 210 | if ( space < len ) return false; 211 | memcpy(ptr, src, len); 212 | TPCircularBufferProduce(buffer, len); 213 | return true; 214 | } 215 | 216 | /*! 217 | * Deprecated method 218 | */ 219 | static __inline__ __attribute__((always_inline)) __deprecated_msg("use TPCircularBufferSetAtomic(false) and TPCircularBufferConsume instead") 220 | void TPCircularBufferConsumeNoBarrier(TPCircularBuffer *buffer, int32_t amount) { 221 | buffer->tail = (buffer->tail + amount) % buffer->length; 222 | buffer->fillCount -= amount; 223 | assert(buffer->fillCount >= 0); 224 | } 225 | 226 | /*! 227 | * Deprecated method 228 | */ 229 | static __inline__ __attribute__((always_inline)) __deprecated_msg("use TPCircularBufferSetAtomic(false) and TPCircularBufferProduce instead") 230 | void TPCircularBufferProduceNoBarrier(TPCircularBuffer *buffer, int32_t amount) { 231 | buffer->head = (buffer->head + amount) % buffer->length; 232 | buffer->fillCount += amount; 233 | assert(buffer->fillCount <= buffer->length); 234 | } 235 | 236 | #ifdef __cplusplus 237 | } 238 | #endif 239 | 240 | #endif 241 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/Transforms2.c: -------------------------------------------------------------------------------- 1 | // 2 | // Transforms2.c 3 | // algorithm 4 | // 5 | // Created by Abhishek Sehgal on 5/5/17. 6 | // Copyright © 2017 default. All rights reserved. 7 | // 8 | 9 | #include "Transforms2.h" 10 | #define P_REF -93.9794 11 | 12 | Transform2* initTransform(int windowSize, int framesPerSecond, int nFFT) { 13 | Transform2* newTransform = (Transform2*)malloc(sizeof(Transform2)); 14 | 15 | newTransform->windowSize = windowSize; 16 | newTransform->framesPerSecond = framesPerSecond; 17 | 18 | 19 | int pow2Size = nFFT; 20 | // while (pow2Size < windowSize) { 21 | // pow2Size = pow2Size << 1; 22 | // } 23 | newTransform->nFFT = nFFT; 24 | 25 | newTransform->input = (float complex *)malloc(pow2Size*sizeof(float complex)); 26 | newTransform->power = (float*)malloc(pow2Size*sizeof(float)); 27 | newTransform->sine = (float*)malloc((pow2Size/2)*sizeof(float)); 28 | newTransform->cosine = (float*)malloc((pow2Size/2)*sizeof(float)); 29 | newTransform->dBpowerBuffer = (float*)calloc(framesPerSecond, 30 | sizeof(float)); 31 | newTransform->dbpower = 0; 32 | 33 | //precompute twiddle factors 34 | double arg; 35 | int i; 36 | for (i = 0; i < pow2Size/2; i++) { 37 | arg = (-2.0*M_PI*i)/pow2Size; 38 | newTransform->cosine[i] = cosf(arg); 39 | newTransform->sine[i] = sinf(arg); 40 | } 41 | 42 | //create Hanning Window 43 | newTransform->window = (float*)malloc(pow2Size*sizeof(float)); 44 | for (i = 0; i < windowSize; i++) { 45 | newTransform->window[i] = (1.0 - cosf(2.0*M_PI*(i+1)/(windowSize+1)))*0.5; 46 | } 47 | for (i=windowSize; i < pow2Size; i++) { 48 | newTransform->window[i] = 0; 49 | } 50 | 51 | return newTransform; 52 | } 53 | 54 | void FFT(Transform2* fft, float complex * input) { 55 | int i,j,k,L,m,n,o,p,q; 56 | float tempReal, tempImaginary, cos, sin,xt, yt, temp; 57 | k = fft->nFFT; 58 | fft->totalPower = 0; 59 | 60 | for (i = 0; i < k; i++) { 61 | fft->input[i] = 0.0 + 0.0*I; 62 | } 63 | 64 | for (i = 0; i < fft->windowSize; i++) { 65 | fft->input[i] = input[i] * fft->window[i]; 66 | } 67 | 68 | j = 0; 69 | m = k/2; 70 | 71 | //bit reversal 72 | for (i = 1; i<(k-1);i++) { 73 | 74 | L = m; 75 | 76 | while(j>=L) { 77 | j = j-L; 78 | L = L/2; 79 | } 80 | 81 | j = j + L; 82 | 83 | if(iinput[i]); 85 | tempImaginary = cimagf(fft->input[i]); 86 | 87 | fft->input[i] = fft->input[j]; 88 | 89 | fft->input[j] = tempReal + tempImaginary * I; 90 | } 91 | } 92 | 93 | 94 | L = 0; 95 | m = 1; 96 | n = k/2; 97 | 98 | //computation 99 | for (i = k; i > 1; i = (i>>1)) { 100 | L = m; 101 | m = 2*m; 102 | o = 0; 103 | 104 | for (j = 0; j < L; j++) { 105 | cos = fft->cosine[o]; 106 | sin = fft->sine[o]; 107 | o = o+n; 108 | 109 | for (p = j; p < k; p = p + m) { 110 | q = p + L; 111 | 112 | xt = cos * crealf(fft->input[q]) - sin * cimagf(fft->input[q]); 113 | yt = sin * crealf(fft->input[q]) + cos * cimagf(fft->input[q]); 114 | 115 | fft->input[q] = (crealf(fft->input[p]) - xt) + I * (cimagf(fft->input[p]) - yt); 116 | fft->input[p] = (crealf(fft->input[p]) + xt) + I * (cimagf(fft->input[p]) + yt); 117 | 118 | } 119 | } 120 | n = n>>1; 121 | } 122 | 123 | for (i = 0; i < k; i++) { 124 | fft->power[i] = cabsf(fft->input[i]); 125 | fft->totalPower += fft->power[i]/fft->nFFT; 126 | } 127 | 128 | fft->dBSPL = 10 * log10f(fft->totalPower + 1e-6) - P_REF; 129 | temp = fft->dBSPL; 130 | fft->dbpower = fft->dbpower + (temp - fft->dBpowerBuffer[0])/fft->framesPerSecond; 131 | memmove(fft->dBpowerBuffer, fft->dBpowerBuffer + 1, sizeof(*fft->dBpowerBuffer)*(fft->framesPerSecond-1)); 132 | fft->dBpowerBuffer[fft->framesPerSecond -1] = temp; 133 | } 134 | 135 | void FFTwithoutWindow(Transform2* fft, float complex * input){ 136 | int i,j,k,L,m,n,o,p,q; 137 | float tempReal, tempImaginary, cos, sin,xt, yt, temp; 138 | k = fft->nFFT; 139 | fft->totalPower = 0; 140 | 141 | for (i = 0; i < k; i++) { 142 | fft->input[i] = 0.0 + 0.0*I; 143 | } 144 | 145 | for (i = 0; i < fft->windowSize; i++) { 146 | fft->input[i] = input[i]; 147 | } 148 | 149 | j = 0; 150 | m = k/2; 151 | 152 | //bit reversal 153 | for (i = 1; i<(k-1);i++) { 154 | 155 | L = m; 156 | 157 | while(j>=L) { 158 | j = j-L; 159 | L = L/2; 160 | } 161 | 162 | j = j + L; 163 | 164 | if(iinput[i]); 166 | tempImaginary = cimagf(fft->input[i]); 167 | 168 | fft->input[i] = fft->input[j]; 169 | 170 | fft->input[j] = tempReal + tempImaginary * I; 171 | } 172 | } 173 | 174 | 175 | L = 0; 176 | m = 1; 177 | n = k/2; 178 | 179 | //computation 180 | for (i = k; i > 1; i = (i>>1)) { 181 | L = m; 182 | m = 2*m; 183 | o = 0; 184 | 185 | for (j = 0; j < L; j++) { 186 | cos = fft->cosine[o]; 187 | sin = fft->sine[o]; 188 | o = o+n; 189 | 190 | for (p = j; p < k; p = p + m) { 191 | q = p + L; 192 | 193 | xt = cos * crealf(fft->input[q]) - sin * cimagf(fft->input[q]); 194 | yt = sin * crealf(fft->input[q]) + cos * cimagf(fft->input[q]); 195 | 196 | fft->input[q] = (crealf(fft->input[p]) - xt) + I * (cimagf(fft->input[p]) - yt); 197 | fft->input[p] = (crealf(fft->input[p]) + xt) + I * (cimagf(fft->input[p]) + yt); 198 | 199 | } 200 | } 201 | n = n>>1; 202 | } 203 | 204 | for (i = 0; i < k; i++) { 205 | fft->power[i] = cabsf(fft->input[i]); 206 | fft->totalPower += fft->power[i]/fft->nFFT; 207 | } 208 | 209 | fft->dBSPL = 10 * log10f(fft->totalPower + 1e-6) - P_REF; 210 | temp = fft->dBSPL; 211 | fft->dbpower = fft->dbpower + (temp - fft->dBpowerBuffer[0])/fft->framesPerSecond; 212 | memmove(fft->dBpowerBuffer, fft->dBpowerBuffer + 1, sizeof(*fft->dBpowerBuffer)*(fft->framesPerSecond-1)); 213 | fft->dBpowerBuffer[fft->framesPerSecond -1] = temp; 214 | } 215 | 216 | void IFFT(Transform2* fft){ 217 | 218 | int i,j,k,L,m,n,o,p,q; 219 | float tempReal, tempImaginary, cos, sin, xt, yt; 220 | k = fft->nFFT; 221 | 222 | j = 0; 223 | m=k/2; 224 | 225 | //bit reversal 226 | for (i = 1; i<(k-1);i++) { 227 | 228 | L = m; 229 | 230 | while(j>=L) { 231 | j = j-L; 232 | L = L/2; 233 | } 234 | 235 | j = j + L; 236 | 237 | if(iinput[i]); 239 | tempImaginary = cimagf(fft->input[i]); 240 | 241 | fft->input[i] = fft->input[j]; 242 | 243 | fft->input[j] = tempReal + tempImaginary * I; 244 | } 245 | } 246 | 247 | L=0; 248 | m=1; 249 | n=k/2; 250 | 251 | //computation 252 | for (i = k; i > 1; i = (i>>1)) { 253 | L = m; 254 | m = 2*m; 255 | o = 0; 256 | 257 | for (j = 0; j < L; j++) { 258 | cos = fft->cosine[o]; 259 | sin = -fft->sine[o]; 260 | o = o+n; 261 | 262 | for (p = j; p < k; p = p + m) { 263 | q = p + L; 264 | 265 | xt = cos * crealf(fft->input[q]) - sin * cimagf(fft->input[q]); 266 | yt = sin * crealf(fft->input[q]) + cos * cimagf(fft->input[q]); 267 | 268 | fft->input[q] = (crealf(fft->input[p]) - xt) + I * (cimagf(fft->input[p]) - yt); 269 | fft->input[p] = (crealf(fft->input[p]) + xt) + I * (cimagf(fft->input[p]) + yt); 270 | 271 | } 272 | } 273 | n = n>>1; 274 | } 275 | 276 | for (i=0; iinput[i] /= k; 278 | } 279 | } 280 | 281 | 282 | void destroyTransform2(Transform2** transform){ 283 | if (*transform != NULL) { 284 | if((*transform)->cosine != NULL){ 285 | free((*transform)->cosine); 286 | (*transform)->cosine = NULL; 287 | } 288 | if((*transform)->sine != NULL){ 289 | free((*transform)->sine); 290 | (*transform)->sine = NULL; 291 | } 292 | if ((*transform)->input != NULL) { 293 | free((*transform)->input); 294 | (*transform)->input = NULL; 295 | } 296 | if((*transform)->power != NULL){ 297 | free((*transform)->power); 298 | (*transform)->power = NULL; 299 | } 300 | if((*transform)->dBpowerBuffer != NULL){ 301 | free((*transform)->dBpowerBuffer); 302 | (*transform)->dBpowerBuffer = NULL; 303 | } 304 | if((*transform)->window != NULL){ 305 | free((*transform)->window); 306 | (*transform)->window = NULL; 307 | } 308 | free(*transform); 309 | *transform = NULL; 310 | } 311 | } 312 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/Transforms2.h: -------------------------------------------------------------------------------- 1 | // 2 | // Transforms2.h 3 | // algorithm 4 | // 5 | // Created by Abhishek Sehgal on 5/5/17. 6 | // Copyright © 2017 default. All rights reserved. 7 | // 8 | 9 | #ifndef Transforms2_h 10 | #define Transforms2_h 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | typedef struct Transform2 { 20 | 21 | int nFFT; 22 | int windowSize; 23 | float dBSPL; 24 | float dbpower; 25 | int framesPerSecond; 26 | float totalPower; 27 | 28 | float complex *input; 29 | float *power; 30 | float *sine; 31 | float *cosine; 32 | float *window; 33 | float *dBpowerBuffer; 34 | 35 | } Transform2; 36 | 37 | Transform2* initTransform(int windowSize, int framesPerSecond, int nFFT); 38 | void FFT(Transform2* fft, float complex * input); 39 | void FFTwithoutWindow(Transform2* fft, float complex * input); 40 | void IFFT(Transform2* fft); 41 | void destroyTransform2(Transform2** transform); 42 | 43 | #endif /* Transforms2_h */ 44 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/UTD_emblem_blk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/UTD_emblem_blk.png -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | 14 | @IBOutlet weak var storeSwitch: UISwitch! 15 | @IBOutlet weak var buttonStart: UIButton! 16 | @IBOutlet weak var buttonStop: UIButton! 17 | @IBOutlet weak var labelTime: UILabel! 18 | @IBOutlet weak var storeLabel: UILabel! 19 | @IBOutlet weak var infoView: UITextView! 20 | @IBOutlet weak var noiseLabel: UILabel! 21 | 22 | 23 | var timer: Timer! = Timer() 24 | 25 | func buttonEnable(set: Bool) { 26 | buttonStart.isEnabled = set 27 | storeSwitch.isEnabled = set 28 | buttonStop.isEnabled = !set 29 | } 30 | 31 | @IBAction func buttonStartPress(_ sender: Any) { 32 | timer = Timer.scheduledTimer(withTimeInterval: 0.5, 33 | repeats: true, 34 | block: { 35 | _ in self.labelTime.text = String(format: "Frame Processing Time: %.2f ms", 1000*audioController.timeBuffer.movingAverage, audioController.classLabel) 36 | switch audioController.classLabel{ 37 | case 1: 38 | self.noiseLabel.text = String(format: "Detected Noise Class: Babble") 39 | case 2: 40 | self.noiseLabel.text = String(format: "Detected Noise Class: Driving Car") 41 | case 3: 42 | self.noiseLabel.text = String(format: "Detected Noise Class: Machinery") 43 | default: 44 | self.noiseLabel.text = String(format: "Detected Noise Class: ") 45 | } 46 | 47 | }); 48 | 49 | buttonEnable(set: false); 50 | audioController.start(storeSwitch.isOn); 51 | 52 | } 53 | 54 | @IBAction func buttonStopPress(_ sender: Any) { 55 | timer.invalidate() 56 | buttonEnable(set: true); 57 | audioController.stop(); 58 | 59 | } 60 | 61 | 62 | override func viewDidLoad() { 63 | super.viewDidLoad() 64 | // Do any additional setup after loading the view, typically from a nib. 65 | 66 | storeSwitch.setOn(false, animated: false) 67 | storeLabel.text = "Record Audio" 68 | buttonEnable(set: true); 69 | audioController = IOSAudioController(); 70 | labelTime.text = "Frame Processing Time:" 71 | infoView.text = audioController.info 72 | noiseLabel.text = "Detected Noise Class:" 73 | } 74 | 75 | override func didReceiveMemoryWarning() { 76 | super.didReceiveMemoryWarning() 77 | // Dispose of any resources that can be recreated. 78 | } 79 | 80 | 81 | } 82 | 83 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/filterCoefficients.h: -------------------------------------------------------------------------------- 1 | // 2 | // filterCoefficients.h 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/17/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | 10 | 11 | #define NCOEFFS 81 12 | 13 | 14 | const float filterCoefficients[] = {0.00014543,0.00028767,0.0002943,9.5746e-05,-0.00033927,-0.00069088,-0.00064432,1.669e-05,0.00096313,0.0015294,0.0010208,-0.00054488,-0.0022758,-0.0027458,-0.0011214,0.0019911,0.0044961,0.004146,0.00031845,-0.0049142,-0.0077294,-0.0051395,0.0022971,0.0099666,0.011779,0.0046813,-0.0081021,-0.017933,-0.016155,-0.00088928,0.01962,0.030579,0.020125,-0.01076,-0.044912,-0.055944,-0.022911,0.055509,0.15629,0.24093,0.27391,0.24093,0.15629,0.055509,-0.022911,-0.055944,-0.044912,-0.01076,0.020125,0.030579,0.01962,-0.00088928,-0.016155,-0.017933,-0.0081021,0.0046813,0.011779,0.0099666,0.0022971,-0.0051395,-0.0077294,-0.0049142,0.00031845,0.004146,0.0044961,0.0019911,-0.0011214,-0.0027458,-0.0022758,-0.00054488,0.0010208,0.0015294,0.00096313,1.669e-05,-0.00064432,-0.00069088,-0.00033927,9.5746e-05,0.0002943,0.00028767,0.00014543}; 15 | 16 | -------------------------------------------------------------------------------- /Noise-Classification-2-Mic/Noise_Classification/utd_print_black_ecs_mono_stacked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Classification-2-Mic/Noise_Classification/utd_print_black_ecs_mono_stacked.png -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/FIRFilter.c: -------------------------------------------------------------------------------- 1 | // 2 | // FIRFilter.c 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/18/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #include "FIRFilter.h" 10 | #include "filterCoefficients.h" 11 | 12 | float checkRange(float input){ 13 | float output; 14 | if (input > 1.0) { 15 | output = 1.0; 16 | } 17 | else if(input < -1.0){ 18 | output = -1.0; 19 | } 20 | else { 21 | output = input; 22 | } 23 | 24 | return output; 25 | } 26 | 27 | FIR* initFIR(int stepSize) { 28 | 29 | FIR* fir = (FIR*)malloc(sizeof(FIR)); 30 | 31 | fir->N = stepSize; 32 | 33 | fir->inputBuffer = (float*)calloc(2*stepSize, sizeof(float)); 34 | 35 | return fir; 36 | 37 | } 38 | 39 | void processFIRFilter(FIR* fir, float* input, float* output) { 40 | 41 | int i,j, idx; 42 | float temp; 43 | 44 | for (i = 0; i < fir->N; i++) { 45 | fir->inputBuffer[i] = fir->inputBuffer[fir->N + i]; 46 | fir->inputBuffer[fir->N + i] = input[i]; 47 | } 48 | 49 | for (i = 0; i < fir->N; i++) { 50 | temp = 0; 51 | 52 | for (j = 0; j < NCOEFFS; j++) { 53 | idx = fir->N + (i - j); 54 | temp += (fir->inputBuffer[idx]*filterCoefficients[j]); 55 | } 56 | output[i] = checkRange(temp); 57 | } 58 | } 59 | 60 | void destroyFIR(FIR **fir) { 61 | 62 | if ((*fir) != NULL) { 63 | 64 | if ((*fir)->inputBuffer != NULL) { 65 | free((*fir)->inputBuffer); 66 | (*fir)->inputBuffer = NULL; 67 | } 68 | 69 | free((*fir)); 70 | (*fir) = NULL; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/FIRFilter.h: -------------------------------------------------------------------------------- 1 | // 2 | // FIRFilter.h 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/18/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #ifndef FIRFilter_h 10 | #define FIRFilter_h 11 | 12 | #include 13 | #include 14 | 15 | 16 | 17 | typedef struct FIR { 18 | 19 | int N; 20 | 21 | float* inputBuffer; 22 | } FIR; 23 | 24 | FIR* initFIR(int stepSize); 25 | void processFIRFilter(FIR* fir, float* input, float* output); 26 | void destroyFIR(FIR **fir); 27 | 28 | #endif /* FIRFilter_h */ 29 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/IOSAudioController.h: -------------------------------------------------------------------------------- 1 | // 2 | // IOSAudioController.h 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TPCircularBuffer.h" 11 | #import 12 | #import 13 | #import 14 | #import "MovingAverageBuffer.h" 15 | #import "NoiseReduction.h" 16 | //#import "SpeechProcessing.h" 17 | //#import "NLMS.h" 18 | 19 | @interface IOSAudioController : NSObject { 20 | AudioUnit au; 21 | } 22 | 23 | @property AudioUnit au; 24 | @property MovingAverageBuffer *timeBuffer; 25 | @property int allocFrameSize; 26 | @property bool audioOutput; 27 | @property int noiseReductionSelect; 28 | @property NSString* info; 29 | 30 | - (void) processAudio; 31 | - (void) start: (BOOL) store; 32 | - (void) stop; 33 | 34 | @end 35 | 36 | extern IOSAudioController* audioController; 37 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/IOSAudioController.m: -------------------------------------------------------------------------------- 1 | // 2 | // IOSAudioController.m 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #import "IOSAudioController.h" 10 | 11 | #define kOutputBus 0 12 | #define kInputBus 1 13 | #define SHORT2FLOAT 1/32768.0 14 | #define FLOAT2SHORT 32768.0 15 | #define NUMCHANNELS 2 16 | #define BUFFER 64 17 | #define FRAMESIZE 600 18 | #define FS 48000 19 | #define DECISIONBUFFERLENGTH 25 20 | #define FAC 3.051757812500000e-05f 21 | 22 | 23 | NoiseReduction* noiseReduction; 24 | long **memoryPointers; 25 | long *nlms; 26 | float **bufs, **outBufs; 27 | TPCircularBuffer *inputBuffer, *outputBuffer; 28 | AudioBufferList *inputBufferList; 29 | IOSAudioController *audioController; 30 | NSDate *start; 31 | NSTimeInterval timeElapsed = 0; 32 | int allocFrameSize, count; 33 | 34 | AudioStreamBasicDescription format; 35 | ExtAudioFileRef cfref; 36 | NSString* str; 37 | 38 | 39 | static OSStatus playbackCallback(void *inRefCon, 40 | AudioUnitRenderActionFlags *ioActionFlags, 41 | const AudioTimeStamp *inTimeStamp, 42 | UInt32 inBusNumber, 43 | UInt32 inNumberFrames, 44 | AudioBufferList *ioData) { 45 | 46 | if (outputBuffer->fillCount >= ioData->mBuffers[0].mDataByteSize) { 47 | AudioBuffer buffer = ioData->mBuffers[0]; 48 | UInt32 size = buffer.mDataByteSize; 49 | int32_t availableBytes; 50 | short* tail = TPCircularBufferTail(outputBuffer, &availableBytes); 51 | memcpy(buffer.mData, tail, size); 52 | TPCircularBufferConsume(outputBuffer, size); 53 | if (cfref!=NULL) { 54 | ExtAudioFileWriteAsync(cfref, inNumberFrames, ioData); 55 | } 56 | } 57 | 58 | return noErr; 59 | } 60 | 61 | static OSStatus recordingCallback(void *inRefCon, 62 | AudioUnitRenderActionFlags *ioActionFlags, 63 | const AudioTimeStamp *inTimeStamp, 64 | UInt32 inBusNumber, 65 | UInt32 inNumberFrames, 66 | AudioBufferList *ioData) { 67 | 68 | //Create Audio Buffer List 69 | inputBufferList->mNumberBuffers = 1;//NUMCHANNELS; 70 | 71 | inputBufferList->mBuffers[0].mDataByteSize = NUMCHANNELS * inNumberFrames * sizeof(short); 72 | inputBufferList->mBuffers[0].mNumberChannels = NUMCHANNELS; 73 | inputBufferList->mBuffers[0].mData = malloc(inputBufferList->mBuffers[0].mDataByteSize); 74 | 75 | 76 | 77 | 78 | // Render audio into the input buffer list 79 | AudioUnitRender(audioController.au, 80 | ioActionFlags, 81 | inTimeStamp, 82 | inBusNumber, 83 | inNumberFrames, 84 | inputBufferList); 85 | 86 | TPCircularBufferProduceBytes(inputBuffer, (void*)inputBufferList->mBuffers[0].mData, inputBufferList->mBuffers[0].mDataByteSize); 87 | 88 | if (inputBuffer->fillCount >= FRAMESIZE*sizeof(short)*NUMCHANNELS) { 89 | start = [NSDate date]; 90 | [audioController processAudio]; 91 | [audioController.timeBuffer addDatum:[NSNumber numberWithFloat:[[NSDate date] timeIntervalSinceDate:start]]]; 92 | audioController.allocFrameSize = inNumberFrames; 93 | } 94 | 95 | // if (cfref != NULL) { 96 | // ExtAudioFileWriteAsync(cfref, inNumberFrames, inputBufferList); 97 | // } 98 | free(inputBufferList->mBuffers[0].mData); 99 | inputBufferList->mBuffers[0].mData = NULL; 100 | 101 | 102 | 103 | return noErr; 104 | } 105 | 106 | void deinterleave(const short* interleavedAudio, float* leftChannel, float* rightChannel, int nSamples){ 107 | 108 | for (int i = 0, j = 0; i < nSamples; i++, j += 2) { 109 | leftChannel[i] = interleavedAudio[j] * FAC; 110 | rightChannel[i] = interleavedAudio[j + 1] * FAC; 111 | } 112 | 113 | } 114 | 115 | void interleave(const float* leftChannel, const float* rightChannel, short* interleavedAudio, int nSamples){ 116 | for (int i = 0, j = 0; i < nSamples; i++, j += 2) { 117 | interleavedAudio[j] = (short)(FLOAT2SHORT * leftChannel[i]); 118 | interleavedAudio[j + 1] = (short)(FLOAT2SHORT * rightChannel[i]); 119 | } 120 | } 121 | 122 | 123 | @implementation IOSAudioController 124 | 125 | @synthesize au, timeBuffer, info; 126 | 127 | - (id) init { 128 | 129 | self = [super init]; 130 | 131 | // Create the audio session 132 | [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayAndRecord 133 | error: NULL]; 134 | [[AVAudioSession sharedInstance] setMode: AVAudioSessionModeMeasurement 135 | error:NULL]; 136 | [[AVAudioSession sharedInstance] setPreferredSampleRate:FS 137 | error:NULL]; 138 | [[AVAudioSession sharedInstance] setPreferredIOBufferDuration:(float)BUFFER/(float)FS 139 | error:NULL]; 140 | 141 | 142 | // Setup Audio Component Description 143 | AudioComponentDescription desc; 144 | desc.componentType = kAudioUnitType_Output; 145 | desc.componentSubType = kAudioUnitSubType_RemoteIO; 146 | desc.componentFlags = 0; 147 | desc.componentFlagsMask = 0; 148 | desc.componentManufacturer = kAudioUnitManufacturer_Apple; 149 | AudioComponent component = AudioComponentFindNext(NULL, &desc); 150 | if (AudioComponentInstanceNew(component, &au) != 0) abort(); 151 | 152 | 153 | UInt32 value = 1; 154 | if (AudioUnitSetProperty(au, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &value, sizeof(value))) abort(); 155 | value = 1; 156 | if (AudioUnitSetProperty(au, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &value, sizeof(value))) abort(); 157 | 158 | // Setup Audio Stream Basic Description 159 | //AudioStreamBasicDescription format; 160 | format.mSampleRate = FS; 161 | format.mFormatID = kAudioFormatLinearPCM; 162 | format.mFormatFlags = kAudioFormatFlagIsSignedInteger; 163 | format.mFramesPerPacket = 1; 164 | format.mChannelsPerFrame = NUMCHANNELS; 165 | format.mBitsPerChannel = 16; 166 | format.mBytesPerPacket = 4; 167 | format.mBytesPerFrame = 4; 168 | if (AudioUnitSetProperty(au, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &format, sizeof(format))) abort(); 169 | if (AudioUnitSetProperty(au, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &format, sizeof(format))) abort(); 170 | 171 | // Set input callback 172 | AURenderCallbackStruct callbackStruct; 173 | callbackStruct.inputProc = recordingCallback; 174 | callbackStruct.inputProcRefCon = (__bridge void *)(self); 175 | AudioUnitSetProperty(au, 176 | kAudioOutputUnitProperty_SetInputCallback, 177 | kAudioUnitScope_Global, 178 | kInputBus, 179 | &callbackStruct, 180 | sizeof(callbackStruct)); 181 | 182 | 183 | 184 | // Set output callback 185 | callbackStruct.inputProc = playbackCallback; 186 | callbackStruct.inputProcRefCon = (__bridge void *)(self); 187 | AudioUnitSetProperty(au, 188 | kAudioUnitProperty_SetRenderCallback, 189 | kAudioUnitScope_Global, 190 | kOutputBus, 191 | &callbackStruct, 192 | sizeof(callbackStruct)); 193 | 194 | AudioUnitInitialize(au); 195 | 196 | timeBuffer = [[MovingAverageBuffer alloc] initWithPeriod:round(FS/FRAMESIZE)]; 197 | NSLog(@"Sampling Frequency of Device:\t%.0f", [AVAudioSession sharedInstance].sampleRate); 198 | NSLog(@"Input Buffer Size for Callback:\t%.0f", [AVAudioSession sharedInstance].IOBufferDuration*[AVAudioSession sharedInstance].sampleRate); 199 | NSLog(@"Specified Overlap Frame Size:\t%d",FRAMESIZE); 200 | 201 | /* Getting all the available inputs */ 202 | 203 | AVAudioSession* myAudioSession = [AVAudioSession sharedInstance]; 204 | NSArray* inputs = myAudioSession.currentRoute.inputs; 205 | for (AVAudioSessionPortDescription* port in inputs) { 206 | str = [NSString stringWithFormat:@"%@", port.portType]; 207 | info = [NSString stringWithFormat:@"Microphone Specifications\n\nPort: %@\nUID: %@\n\nAudio I/O Setup\n\nInput Microphones: \t%lu\nOutput Speakers: \t%lu\n\n", 208 | port.portName, 209 | port.UID, 210 | (long)myAudioSession.maximumInputNumberOfChannels, 211 | (long)myAudioSession.maximumOutputNumberOfChannels]; 212 | 213 | } 214 | 215 | return self; 216 | 217 | } 218 | 219 | - (void) start: (BOOL) store { 220 | 221 | count = 0; 222 | 223 | // Setup the circular buffers, float buffers and algorithm memory pointers 224 | // nlms = initializeNLMS(FRAMESIZE, 2*FRAMESIZE, 64, 0.1); 225 | // memoryPointers = (long**)malloc(sizeof(long*) * NUMCHANNELS); 226 | // for (size_t n = 0; n < NUMCHANNELS; n++) { 227 | // memoryPointers[n] = initialize(FRAMESIZE, FS, DECISIONBUFFERLENGTH); 228 | // } 229 | 230 | noiseReduction = initNoiseReduction(FRAMESIZE); 231 | inputBuffer = (TPCircularBuffer*)malloc(sizeof(TPCircularBuffer)); 232 | outputBuffer = (TPCircularBuffer*)malloc(sizeof(TPCircularBuffer)); 233 | TPCircularBufferInit(inputBuffer, 2048*16); 234 | TPCircularBufferInit(outputBuffer, 2048*16); 235 | 236 | 237 | bufs = (float**)malloc(sizeof(float*)*NUMCHANNELS); 238 | outBufs = (float**)malloc(sizeof(float*)*NUMCHANNELS); 239 | for (size_t n = 0; n < NUMCHANNELS; n++) { 240 | bufs[n] = (float*)calloc(FRAMESIZE, sizeof(float)); 241 | outBufs[n] = (float*)calloc(FRAMESIZE, sizeof(float)); 242 | }; 243 | 244 | // define input buffer list 245 | inputBufferList = (AudioBufferList *)malloc(sizeof(AudioBufferList) 246 | + sizeof(AudioBuffer) * 2); 247 | 248 | if (store) { 249 | 250 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 251 | [formatter setDateFormat:@"MM_dd_yyyy_HH_mm_ss"]; 252 | NSString* dateString = [formatter stringFromDate:[NSDate date]]; 253 | 254 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 255 | NSString *documentsDirectory = [paths objectAtIndex:0]; 256 | NSString* destinationFilePath = [[NSString alloc] initWithFormat: @"%@/%@_%@.caf", documentsDirectory, str, dateString]; 257 | CFURLRef destinationURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)destinationFilePath, kCFURLPOSIXPathStyle, false); 258 | 259 | OSStatus status; 260 | 261 | 262 | 263 | status = ExtAudioFileCreateWithURL(destinationURL, kAudioFileCAFType, 264 | &format, NULL, kAudioFileFlags_EraseFile, 265 | &cfref); 266 | } 267 | 268 | // Start the audio 269 | AudioOutputUnitStart(au); 270 | } 271 | 272 | - (void) stop { 273 | 274 | // Stop the audio 275 | AudioOutputUnitStop(au); 276 | 277 | if (cfref != NULL) { 278 | ExtAudioFileDispose(cfref); 279 | } 280 | 281 | 282 | // Clean up all initialized memory 283 | // for (size_t n = 0; n < NUMCHANNELS; n++) { 284 | // destroy(memoryPointers[n]); 285 | // } 286 | free(memoryPointers); 287 | memoryPointers = NULL; 288 | 289 | free(inputBuffer); 290 | inputBuffer = NULL; 291 | free(outputBuffer); 292 | outputBuffer = NULL; 293 | 294 | for (size_t n = 0; n < NUMCHANNELS; n++) { 295 | free(bufs[n]); 296 | bufs[n] = NULL; 297 | free(outBufs[n]); 298 | outBufs[n] = NULL; 299 | } 300 | free(bufs); 301 | bufs = NULL; 302 | free(outBufs); 303 | outBufs = NULL; 304 | free(inputBufferList); 305 | inputBufferList = NULL; 306 | 307 | } 308 | 309 | - (void) processAudio { 310 | 311 | uint32_t frameSize = FRAMESIZE * sizeof(short) * NUMCHANNELS; 312 | int32_t availableBytes; 313 | 314 | short* tail = TPCircularBufferTail(inputBuffer, &availableBytes); 315 | 316 | if (availableBytes >= frameSize) { 317 | // Deinterleave to float 318 | //deinterleave(tail, bufs[0], bufs[1], FRAMESIZE); 319 | 320 | // Run the algorithms 321 | // for (int i = 0; i < NUMCHANNELS; i++) { 322 | // compute(memoryPointers[i], bufs[i], outBufs[i], i); 323 | // } 324 | // if (count > 120) { 325 | // processAudio(nlms, tail, outBufs[0], outBufs[1]); 326 | // } 327 | // else{ 328 | // count++; 329 | // } 330 | short* head = TPCircularBufferHead(outputBuffer, &availableBytes); 331 | doNoiseReduction(noiseReduction, tail, head, audioController.noiseReductionSelect); 332 | 333 | // Interleave data into short 334 | 335 | //interleave(bufs[0], bufs[1], head, FRAMESIZE); 336 | 337 | 338 | TPCircularBufferProduce(outputBuffer, frameSize); 339 | TPCircularBufferConsume(inputBuffer, frameSize); 340 | 341 | } 342 | } 343 | 344 | -(void) dealloc{ 345 | 346 | 347 | } 348 | 349 | @end 350 | 351 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Noise_Reduction 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSMicrophoneUsageDescription 26 | 27 | UIFileSharingEnabled 28 | 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | UISupportedInterfaceOrientations~ipad 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationPortraitUpsideDown 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/MovingAverageBuffer.h: -------------------------------------------------------------------------------- 1 | // 2 | // MovingAverageBuffer.h 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MovingAverageBuffer : NSObject 12 | 13 | @property (readonly, nonatomic) float movingAverage; 14 | @property (readonly, nonatomic) float cumulativeAverage; 15 | 16 | - (id) initWithPeriod:(NSUInteger)period; 17 | - (void) addDatum:(NSNumber *)datum; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/MovingAverageBuffer.m: -------------------------------------------------------------------------------- 1 | // 2 | // MovingAverageBuffer.m 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #import "MovingAverageBuffer.h" 10 | 11 | @interface MovingAverageBuffer() 12 | @property (strong, nonatomic) NSMutableArray *queue; 13 | @property (assign, nonatomic) NSUInteger period; 14 | @property (assign, nonatomic) NSUInteger count; 15 | @property (assign, nonatomic) float movingAverage; 16 | @property (assign, nonatomic) float cumulativeAverage; 17 | @end 18 | 19 | @implementation MovingAverageBuffer 20 | 21 | - (id)initWithPeriod:(NSUInteger)period { 22 | 23 | self = [self init]; 24 | if(self){ 25 | _period = period; 26 | _queue = [NSMutableArray array]; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)addDatum:(NSNumber *)datum { 32 | 33 | [self.queue insertObject:datum atIndex:0]; 34 | 35 | float removed = 0; 36 | float datumf = [datum floatValue]; 37 | 38 | if(self.queue.count > self.period) { 39 | removed = [[self.queue lastObject] floatValue]; 40 | [self.queue removeLastObject]; 41 | } 42 | 43 | self.movingAverage = self.movingAverage - (removed/self.period) + (datumf/self.period); 44 | 45 | self.cumulativeAverage = self.cumulativeAverage + (datumf - self.cumulativeAverage)/++self.count; 46 | 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/NC-2Ch-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "IOSAudioController.h" 6 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/NLMS.c: -------------------------------------------------------------------------------- 1 | // 2 | // NLMS.c 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 6/5/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #include "NLMS.h" 10 | 11 | float checkOutputRange(float input){ 12 | float output; 13 | if (input > 1.0) { 14 | output = 1.0; 15 | } 16 | else if(input < -1.0){ 17 | output = -1.0; 18 | } 19 | else { 20 | output = input; 21 | } 22 | 23 | return output; 24 | } 25 | 26 | NLMS* initializeNLMS(int stepSize, int frameSize, int filtLen, float mu) { 27 | NLMS *mainParam = (NLMS*) malloc(sizeof(NLMS)); 28 | int i; 29 | 30 | mainParam->u = mu; 31 | mainParam->stepSize = stepSize; 32 | mainParam->frameSize = frameSize; 33 | mainParam->filLen = 64; 34 | 35 | mainParam->topMicBuffer = (float*) calloc(frameSize + mainParam->filLen - 1,sizeof(float)); 36 | mainParam->botMicBuffer = (float*) calloc(frameSize + mainParam->filLen - 1,sizeof(float)); 37 | mainParam->w = (float*) malloc(mainParam->filLen * sizeof(float)); 38 | for (i = 0; i < mainParam->filLen; i++) { 39 | mainParam->w[i] = 0.5; 40 | } 41 | mainParam->y_curr = (float*) calloc(frameSize, sizeof(float)); 42 | mainParam->y_prev = (float*) calloc(frameSize, sizeof(float)); 43 | mainParam->e = (float*) calloc(stepSize, sizeof(float)); 44 | 45 | return mainParam; 46 | } 47 | 48 | void processAudio(NLMS* memoryPointer, short* _in, float* _out){ 49 | 50 | NLMS *mainParam = memoryPointer; 51 | 52 | int i, j, stepSize, frameSize, filLen; 53 | float tempVar, tempEng; 54 | stepSize = mainParam->stepSize; 55 | frameSize = mainParam->frameSize; 56 | filLen = mainParam->filLen; 57 | 58 | for (i = 0; i < filLen - 1; i++) { 59 | mainParam->topMicBuffer[i] = mainParam->topMicBuffer[i + stepSize]; 60 | mainParam->botMicBuffer[i] = mainParam->botMicBuffer[i + stepSize]; 61 | } 62 | 63 | for (i = filLen - 1, j = 0; i < filLen + stepSize - 1; i++, j += 2) { 64 | mainParam->topMicBuffer[i] = mainParam->topMicBuffer[i + stepSize]; 65 | mainParam->topMicBuffer[i + stepSize] = _in[j]*FAC; 66 | mainParam->botMicBuffer[i] = mainParam->botMicBuffer[i + stepSize]; 67 | mainParam->botMicBuffer[i + stepSize] = _in[j+1]*FAC; 68 | } 69 | 70 | /* Pre Processing */ 71 | 72 | tempEng = 0; 73 | for (i = 0; i < frameSize; i++) { 74 | mainParam->y_prev[i] = mainParam->y_curr[i]; 75 | tempVar = 0; 76 | for (j = 0; j < filLen; j++) { 77 | tempVar += mainParam->w[j] * mainParam->botMicBuffer[i + j]; 78 | tempEng += mainParam->botMicBuffer[i + j]* mainParam->botMicBuffer[i + j]; 79 | } 80 | mainParam->y_curr[i] = tempVar; 81 | } 82 | 83 | for (i = 0; i < stepSize; i++) { 84 | mainParam->e[i] = mainParam->topMicBuffer[i + filLen - 1]- 0.5 * (mainParam->y_prev[i + stepSize] + mainParam->y_curr[i]); 85 | } 86 | 87 | for (i = 0; i < filLen; i++) { 88 | tempVar = 0; 89 | for (j = 0; j < stepSize; j++) { 90 | tempVar += mainParam->botMicBuffer[j + i] * mainParam->e[j]; 91 | } 92 | mainParam->w[i] += mainParam->u * tempVar / (tempEng + EPS); 93 | } 94 | 95 | for (i = 0; i < stepSize; i++) { 96 | _out[i] = checkOutputRange(mainParam->e[i]); 97 | } 98 | 99 | } 100 | 101 | 102 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/NLMS.h: -------------------------------------------------------------------------------- 1 | // 2 | // NLMS.h 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 6/5/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #ifndef NLMS_h 10 | #define NLMS_h 11 | 12 | #include 13 | #include 14 | #include 15 | #define EPS 1.0e-7 16 | #define FAC 3.051757812500000e-05f 17 | 18 | 19 | typedef struct NLMS{ 20 | int stepSize; 21 | int frameSize; 22 | int filLen; 23 | float u; 24 | 25 | float* topMicBuffer; 26 | float* botMicBuffer; 27 | float* y_prev; 28 | float* y_curr; 29 | float* w; 30 | float* e; 31 | } NLMS; 32 | 33 | NLMS* initializeNLMS(int stepSize, int frameSize, int filtLen, float mu); 34 | void processAudio(NLMS* memoryPointer, short* _in, float* _out); 35 | 36 | #endif /* NLMS_h */ 37 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/NoiseReduction.c: -------------------------------------------------------------------------------- 1 | // 2 | // NoiseReduction.c 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 6/19/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #include "NoiseReduction.h" 10 | 11 | #define DECIMATION_FACTOR 3 12 | #define EPS 1.0e-7 13 | #define S2F 3.051757812500000e-05f 14 | #define F2S 32768 15 | 16 | const double amplitude = 0.75; 17 | 18 | NoiseReduction* initNoiseReduction(int stepSize){ 19 | 20 | NoiseReduction* inParam = (NoiseReduction*)malloc(sizeof(NoiseReduction)); 21 | 22 | inParam->stepSize = stepSize; 23 | inParam->decimatedStepSize = stepSize/DECIMATION_FACTOR; 24 | 25 | inParam->leftIn = (float*)calloc(sizeof(float), stepSize); 26 | inParam->rightIn = (float*)calloc(sizeof(float), stepSize); 27 | 28 | inParam->leftDS = (float*)calloc(sizeof(float), stepSize); 29 | inParam->rightDS = (float*)calloc(sizeof(float), stepSize); 30 | inParam->interpolated = (float*)calloc(sizeof(float), stepSize); 31 | 32 | inParam->decimated = (short*)calloc(sizeof(short), 2*inParam->decimatedStepSize); 33 | inParam->decimatedMono = (float*)calloc(sizeof(float), inParam->decimatedStepSize); 34 | 35 | inParam->wienerInput = (float*)calloc(sizeof(float), inParam->decimatedStepSize); 36 | inParam->wienerOutput = (float*)calloc(sizeof(float), inParam->decimatedStepSize); 37 | 38 | inParam->output = (float*)calloc(sizeof(float), inParam->stepSize); 39 | 40 | inParam->firLeft = initFIR(stepSize); 41 | inParam->firRight = initFIR(stepSize); 42 | inParam->interpolation = initFIR(stepSize); 43 | 44 | inParam->nlms = initializeNLMS(inParam->decimatedStepSize, 45 | 2*inParam->decimatedStepSize, 46 | 64, 47 | 0.1); 48 | wienerAB_init(); 49 | return inParam; 50 | } 51 | 52 | void doNoiseReduction(NoiseReduction* _ptr, short* _in, short* _out, int audioOutput){ 53 | 54 | NoiseReduction* inParam = _ptr; 55 | 56 | int i,j; 57 | 58 | // Deinterleave 59 | 60 | for (i = 0, j = 0; i < inParam->stepSize; i++, j += 2) { 61 | inParam->leftIn[i] = _in[j] * S2F; 62 | inParam->rightIn[i] = _in[j+1] * S2F; 63 | } 64 | 65 | // Downsample 66 | 67 | processFIRFilter(inParam->firLeft, inParam->leftIn, inParam->leftDS); 68 | processFIRFilter(inParam->firRight, inParam->rightIn, inParam->rightDS); 69 | 70 | // Decimate and InterLeave 71 | 72 | for (i = 0, j = 0; i < 2*inParam->decimatedStepSize; i += 2, j += 3) { 73 | inParam->decimated[i] = F2S * inParam->leftDS[j]; 74 | inParam->decimated[i+1] = F2S * inParam->rightDS[j]; 75 | inParam->decimatedMono[(int)i/2] = 0.5*(inParam->leftDS[j] + inParam->rightDS[j]); 76 | } 77 | 78 | // Block-NLMS 79 | if (audioOutput == 0) { 80 | for (i = 0, j = 0; i < inParam->decimatedStepSize; i++, j += 3) { 81 | inParam->interpolated[j] = inParam->decimatedMono[i]; 82 | } 83 | } 84 | 85 | else if (audioOutput == 1) { 86 | wienerAB(inParam->decimatedMono, -1, 16000, inParam->wienerOutput); 87 | // Interpolation 88 | 89 | for (i = 0, j = 0; i < inParam->decimatedStepSize; i++, j += 3) { 90 | inParam->output[j] = inParam->wienerOutput[i]; 91 | } 92 | processFIRFilter(inParam->interpolation, inParam->output, inParam->interpolated); 93 | } 94 | 95 | else if (audioOutput == 2) { 96 | processAudio(inParam->nlms, inParam->decimated, inParam->wienerInput); 97 | wienerAB(inParam->wienerInput, -1, 16000, inParam->wienerOutput); 98 | // Interpolation 99 | 100 | for (i = 0, j = 0; i < inParam->decimatedStepSize; i++, j += 3) { 101 | inParam->output[j] = inParam->wienerOutput[i]; 102 | } 103 | 104 | processFIRFilter(inParam->interpolation, inParam->output, inParam->interpolated); 105 | } 106 | 107 | 108 | 109 | 110 | 111 | 112 | // Interleave 113 | 114 | for (i = 0, j = 0; i < inParam->stepSize; i++, j += 2) { 115 | _out[j] = (short)(F2S * inParam->interpolated[i]); 116 | _out[j+1] = (short)(F2S * inParam->interpolated[i]); 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/NoiseReduction.h: -------------------------------------------------------------------------------- 1 | // 2 | // NoiseReduction.h 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 6/19/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | #ifndef NoiseReduction_h 10 | #define NoiseReduction_h 11 | 12 | #include 13 | #include 14 | #include "FIRFilter.h" 15 | #include "NLMS.h" 16 | #include "wienerAB.h" 17 | 18 | typedef struct NoiseReduction { 19 | 20 | int stepSize; 21 | int decimatedStepSize; 22 | 23 | float* leftIn; 24 | float* rightIn; 25 | float* leftDS; 26 | float* rightDS; 27 | short* decimated; 28 | float* decimatedMono; 29 | float* interpolated; 30 | 31 | float* wienerInput; 32 | float* wienerOutput; 33 | float* output; 34 | 35 | FIR* firLeft; 36 | FIR* firRight; 37 | FIR* interpolation; 38 | 39 | NLMS* nlms; 40 | 41 | } NoiseReduction; 42 | 43 | NoiseReduction* initNoiseReduction(int stepSize); 44 | void doNoiseReduction(NoiseReduction* _ptr, short* _in, short* _out, int audioOutput); 45 | 46 | #endif /* NoiseReduction_h */ 47 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/TPCircularBuffer.c: -------------------------------------------------------------------------------- 1 | // 2 | // TPCircularBuffer.c 3 | // Circular/Ring buffer implementation 4 | // 5 | // https://github.com/michaeltyson/TPCircularBuffer 6 | // 7 | // Created by Michael Tyson on 10/12/2011. 8 | // 9 | // Copyright (C) 2012-2013 A Tasty Pixel 10 | // 11 | // This software is provided 'as-is', without any express or implied 12 | // warranty. In no event will the authors be held liable for any damages 13 | // arising from the use of this software. 14 | // 15 | // Permission is granted to anyone to use this software for any purpose, 16 | // including commercial applications, and to alter it and redistribute it 17 | // freely, subject to the following restrictions: 18 | // 19 | // 1. The origin of this software must not be misrepresented; you must not 20 | // claim that you wrote the original software. If you use this software 21 | // in a product, an acknowledgment in the product documentation would be 22 | // appreciated but is not required. 23 | // 24 | // 2. Altered source versions must be plainly marked as such, and must not be 25 | // misrepresented as being the original software. 26 | // 27 | // 3. This notice may not be removed or altered from any source distribution. 28 | // 29 | 30 | #include "TPCircularBuffer.h" 31 | #include 32 | #include 33 | #include 34 | 35 | #define reportResult(result,operation) (_reportResult((result),(operation),strrchr(__FILE__, '/')+1,__LINE__)) 36 | static inline bool _reportResult(kern_return_t result, const char *operation, const char* file, int line) { 37 | if ( result != ERR_SUCCESS ) { 38 | printf("%s:%d: %s: %s\n", file, line, operation, mach_error_string(result)); 39 | return false; 40 | } 41 | return true; 42 | } 43 | 44 | bool _TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length, size_t structSize) { 45 | 46 | assert(length > 0); 47 | 48 | if ( structSize != sizeof(TPCircularBuffer) ) { 49 | fprintf(stderr, "TPCircularBuffer: Header version mismatch. Check for old versions of TPCircularBuffer in your project\n"); 50 | abort(); 51 | } 52 | 53 | // Keep trying until we get our buffer, needed to handle race conditions 54 | int retries = 3; 55 | while ( true ) { 56 | 57 | buffer->length = (int32_t)round_page(length); // We need whole page sizes 58 | 59 | // Temporarily allocate twice the length, so we have the contiguous address space to 60 | // support a second instance of the buffer directly after 61 | vm_address_t bufferAddress; 62 | kern_return_t result = vm_allocate(mach_task_self(), 63 | &bufferAddress, 64 | buffer->length * 2, 65 | VM_FLAGS_ANYWHERE); // allocate anywhere it'll fit 66 | if ( result != ERR_SUCCESS ) { 67 | if ( retries-- == 0 ) { 68 | reportResult(result, "Buffer allocation"); 69 | return false; 70 | } 71 | // Try again if we fail 72 | continue; 73 | } 74 | 75 | // Now replace the second half of the allocation with a virtual copy of the first half. Deallocate the second half... 76 | result = vm_deallocate(mach_task_self(), 77 | bufferAddress + buffer->length, 78 | buffer->length); 79 | if ( result != ERR_SUCCESS ) { 80 | if ( retries-- == 0 ) { 81 | reportResult(result, "Buffer deallocation"); 82 | return false; 83 | } 84 | // If this fails somehow, deallocate the whole region and try again 85 | vm_deallocate(mach_task_self(), bufferAddress, buffer->length); 86 | continue; 87 | } 88 | 89 | // Re-map the buffer to the address space immediately after the buffer 90 | vm_address_t virtualAddress = bufferAddress + buffer->length; 91 | vm_prot_t cur_prot, max_prot; 92 | result = vm_remap(mach_task_self(), 93 | &virtualAddress, // mirror target 94 | buffer->length, // size of mirror 95 | 0, // auto alignment 96 | 0, // force remapping to virtualAddress 97 | mach_task_self(), // same task 98 | bufferAddress, // mirror source 99 | 0, // MAP READ-WRITE, NOT COPY 100 | &cur_prot, // unused protection struct 101 | &max_prot, // unused protection struct 102 | VM_INHERIT_DEFAULT); 103 | if ( result != ERR_SUCCESS ) { 104 | if ( retries-- == 0 ) { 105 | reportResult(result, "Remap buffer memory"); 106 | return false; 107 | } 108 | // If this remap failed, we hit a race condition, so deallocate and try again 109 | vm_deallocate(mach_task_self(), bufferAddress, buffer->length); 110 | continue; 111 | } 112 | 113 | if ( virtualAddress != bufferAddress+buffer->length ) { 114 | // If the memory is not contiguous, clean up both allocated buffers and try again 115 | if ( retries-- == 0 ) { 116 | printf("Couldn't map buffer memory to end of buffer\n"); 117 | return false; 118 | } 119 | 120 | vm_deallocate(mach_task_self(), virtualAddress, buffer->length); 121 | vm_deallocate(mach_task_self(), bufferAddress, buffer->length); 122 | continue; 123 | } 124 | 125 | buffer->buffer = (void*)bufferAddress; 126 | buffer->fillCount = 0; 127 | buffer->head = buffer->tail = 0; 128 | buffer->atomic = true; 129 | 130 | return true; 131 | } 132 | return false; 133 | } 134 | 135 | void TPCircularBufferCleanup(TPCircularBuffer *buffer) { 136 | vm_deallocate(mach_task_self(), (vm_address_t)buffer->buffer, buffer->length * 2); 137 | memset(buffer, 0, sizeof(TPCircularBuffer)); 138 | } 139 | 140 | void TPCircularBufferClear(TPCircularBuffer *buffer) { 141 | int32_t fillCount; 142 | if ( TPCircularBufferTail(buffer, &fillCount) ) { 143 | TPCircularBufferConsume(buffer, fillCount); 144 | } 145 | } 146 | 147 | void TPCircularBufferSetAtomic(TPCircularBuffer *buffer, bool atomic) { 148 | buffer->atomic = atomic; 149 | } 150 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/TPCircularBuffer.h: -------------------------------------------------------------------------------- 1 | // 2 | // TPCircularBuffer.h 3 | // Circular/Ring buffer implementation 4 | // 5 | // https://github.com/michaeltyson/TPCircularBuffer 6 | // 7 | // Created by Michael Tyson on 10/12/2011. 8 | // 9 | // 10 | // This implementation makes use of a virtual memory mapping technique that inserts a virtual copy 11 | // of the buffer memory directly after the buffer's end, negating the need for any buffer wrap-around 12 | // logic. Clients can simply use the returned memory address as if it were contiguous space. 13 | // 14 | // The implementation is thread-safe in the case of a single producer and single consumer. 15 | // 16 | // Virtual memory technique originally proposed by Philip Howard (http://vrb.slashusr.org/), and 17 | // adapted to Darwin by Kurt Revis (http://www.snoize.com, 18 | // http://www.snoize.com/Code/PlayBufferedSoundFile.tar.gz) 19 | // 20 | // 21 | // Copyright (C) 2012-2013 A Tasty Pixel 22 | // 23 | // This software is provided 'as-is', without any express or implied 24 | // warranty. In no event will the authors be held liable for any damages 25 | // arising from the use of this software. 26 | // 27 | // Permission is granted to anyone to use this software for any purpose, 28 | // including commercial applications, and to alter it and redistribute it 29 | // freely, subject to the following restrictions: 30 | // 31 | // 1. The origin of this software must not be misrepresented; you must not 32 | // claim that you wrote the original software. If you use this software 33 | // in a product, an acknowledgment in the product documentation would be 34 | // appreciated but is not required. 35 | // 36 | // 2. Altered source versions must be plainly marked as such, and must not be 37 | // misrepresented as being the original software. 38 | // 39 | // 3. This notice may not be removed or altered from any source distribution. 40 | // 41 | 42 | #ifndef TPCircularBuffer_h 43 | #define TPCircularBuffer_h 44 | 45 | #include 46 | #include 47 | #include 48 | 49 | #ifdef __cplusplus 50 | extern "C++" { 51 | #include 52 | using namespace std; 53 | } 54 | #else 55 | #include 56 | #endif 57 | 58 | #ifdef __cplusplus 59 | extern "C" { 60 | #endif 61 | 62 | typedef struct { 63 | void *buffer; 64 | int32_t length; 65 | int32_t tail; 66 | int32_t head; 67 | volatile atomic_int fillCount; 68 | bool atomic; 69 | } TPCircularBuffer; 70 | 71 | /*! 72 | * Initialise buffer 73 | * 74 | * Note that the length is advisory only: Because of the way the 75 | * memory mirroring technique works, the true buffer length will 76 | * be multiples of the device page size (e.g. 4096 bytes) 77 | * 78 | * If you intend to use the AudioBufferList utilities, you should 79 | * always allocate a bit more space than you need for pure audio 80 | * data, so there's room for the metadata. How much extra is required 81 | * depends on how many AudioBufferList structures are used, which is 82 | * a function of how many audio frames each buffer holds. A good rule 83 | * of thumb is to add 15%, or at least another 2048 bytes or so. 84 | * 85 | * @param buffer Circular buffer 86 | * @param length Length of buffer 87 | */ 88 | #define TPCircularBufferInit(buffer, length) \ 89 | _TPCircularBufferInit(buffer, length, sizeof(*buffer)) 90 | bool _TPCircularBufferInit(TPCircularBuffer *buffer, int32_t length, size_t structSize); 91 | 92 | /*! 93 | * Cleanup buffer 94 | * 95 | * Releases buffer resources. 96 | */ 97 | void TPCircularBufferCleanup(TPCircularBuffer *buffer); 98 | 99 | /*! 100 | * Clear buffer 101 | * 102 | * Resets buffer to original, empty state. 103 | * 104 | * This is safe for use by consumer while producer is accessing 105 | * buffer. 106 | */ 107 | void TPCircularBufferClear(TPCircularBuffer *buffer); 108 | 109 | /*! 110 | * Set the atomicity 111 | * 112 | * If you set the atomiticy to false using this method, the buffer will 113 | * not use atomic operations. This can be used to give the compiler a little 114 | * more optimisation opportunities when the buffer is only used on one thread. 115 | * 116 | * Important note: Only set this to false if you know what you're doing! 117 | * 118 | * The default value is true (the buffer will use atomic operations) 119 | * 120 | * @param buffer Circular buffer 121 | * @param atomic Whether the buffer is atomic (default true) 122 | */ 123 | void TPCircularBufferSetAtomic(TPCircularBuffer *buffer, bool atomic); 124 | 125 | // Reading (consuming) 126 | 127 | /*! 128 | * Access end of buffer 129 | * 130 | * This gives you a pointer to the end of the buffer, ready 131 | * for reading, and the number of available bytes to read. 132 | * 133 | * @param buffer Circular buffer 134 | * @param availableBytes On output, the number of bytes ready for reading 135 | * @return Pointer to the first bytes ready for reading, or NULL if buffer is empty 136 | */ 137 | static __inline__ __attribute__((always_inline)) void* TPCircularBufferTail(TPCircularBuffer *buffer, int32_t* availableBytes) { 138 | *availableBytes = buffer->fillCount; 139 | if ( *availableBytes == 0 ) return NULL; 140 | return (void*)((char*)buffer->buffer + buffer->tail); 141 | } 142 | 143 | /*! 144 | * Consume bytes in buffer 145 | * 146 | * This frees up the just-read bytes, ready for writing again. 147 | * 148 | * @param buffer Circular buffer 149 | * @param amount Number of bytes to consume 150 | */ 151 | static __inline__ __attribute__((always_inline)) void TPCircularBufferConsume(TPCircularBuffer *buffer, int32_t amount) { 152 | buffer->tail = (buffer->tail + amount) % buffer->length; 153 | if ( buffer->atomic ) { 154 | atomic_fetch_add(&buffer->fillCount, -amount); 155 | } else { 156 | buffer->fillCount -= amount; 157 | } 158 | assert(buffer->fillCount >= 0); 159 | } 160 | 161 | /*! 162 | * Access front of buffer 163 | * 164 | * This gives you a pointer to the front of the buffer, ready 165 | * for writing, and the number of available bytes to write. 166 | * 167 | * @param buffer Circular buffer 168 | * @param availableBytes On output, the number of bytes ready for writing 169 | * @return Pointer to the first bytes ready for writing, or NULL if buffer is full 170 | */ 171 | static __inline__ __attribute__((always_inline)) void* TPCircularBufferHead(TPCircularBuffer *buffer, int32_t* availableBytes) { 172 | *availableBytes = (buffer->length - buffer->fillCount); 173 | if ( *availableBytes == 0 ) return NULL; 174 | return (void*)((char*)buffer->buffer + buffer->head); 175 | } 176 | 177 | // Writing (producing) 178 | 179 | /*! 180 | * Produce bytes in buffer 181 | * 182 | * This marks the given section of the buffer ready for reading. 183 | * 184 | * @param buffer Circular buffer 185 | * @param amount Number of bytes to produce 186 | */ 187 | static __inline__ __attribute__((always_inline)) void TPCircularBufferProduce(TPCircularBuffer *buffer, int32_t amount) { 188 | buffer->head = (buffer->head + amount) % buffer->length; 189 | if ( buffer->atomic ) { 190 | atomic_fetch_add(&buffer->fillCount, amount); 191 | } else { 192 | buffer->fillCount += amount; 193 | } 194 | assert(buffer->fillCount <= buffer->length); 195 | } 196 | 197 | /*! 198 | * Helper routine to copy bytes to buffer 199 | * 200 | * This copies the given bytes to the buffer, and marks them ready for reading. 201 | * 202 | * @param buffer Circular buffer 203 | * @param src Source buffer 204 | * @param len Number of bytes in source buffer 205 | * @return true if bytes copied, false if there was insufficient space 206 | */ 207 | static __inline__ __attribute__((always_inline)) bool TPCircularBufferProduceBytes(TPCircularBuffer *buffer, const void* src, int32_t len) { 208 | int32_t space; 209 | void *ptr = TPCircularBufferHead(buffer, &space); 210 | if ( space < len ) return false; 211 | memcpy(ptr, src, len); 212 | TPCircularBufferProduce(buffer, len); 213 | return true; 214 | } 215 | 216 | /*! 217 | * Deprecated method 218 | */ 219 | static __inline__ __attribute__((always_inline)) __deprecated_msg("use TPCircularBufferSetAtomic(false) and TPCircularBufferConsume instead") 220 | void TPCircularBufferConsumeNoBarrier(TPCircularBuffer *buffer, int32_t amount) { 221 | buffer->tail = (buffer->tail + amount) % buffer->length; 222 | buffer->fillCount -= amount; 223 | assert(buffer->fillCount >= 0); 224 | } 225 | 226 | /*! 227 | * Deprecated method 228 | */ 229 | static __inline__ __attribute__((always_inline)) __deprecated_msg("use TPCircularBufferSetAtomic(false) and TPCircularBufferProduce instead") 230 | void TPCircularBufferProduceNoBarrier(TPCircularBuffer *buffer, int32_t amount) { 231 | buffer->head = (buffer->head + amount) % buffer->length; 232 | buffer->fillCount += amount; 233 | assert(buffer->fillCount <= buffer->length); 234 | } 235 | 236 | #ifdef __cplusplus 237 | } 238 | #endif 239 | 240 | #endif 241 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/UTD_emblem_blk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Noise-Reduction-2-Mic/Noise_Reduction/UTD_emblem_blk.png -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/12/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | 14 | @IBOutlet weak var storeSwitch: UISwitch! 15 | @IBOutlet weak var buttonStart: UIButton! 16 | @IBOutlet weak var buttonStop: UIButton! 17 | @IBOutlet weak var labelTime: UILabel! 18 | @IBOutlet weak var storeLabel: UILabel! 19 | @IBOutlet weak var infoView: UITextView! 20 | @IBOutlet weak var noiseReductionSelect: UISegmentedControl! 21 | 22 | 23 | var timer: Timer! = Timer() 24 | 25 | func buttonEnable(set: Bool) { 26 | buttonStart.isEnabled = set 27 | storeSwitch.isEnabled = set 28 | buttonStop.isEnabled = !set 29 | noiseReductionSelect.isEnabled = set 30 | } 31 | 32 | @IBAction func buttonStartPress(_ sender: Any) { 33 | timer = Timer.scheduledTimer(withTimeInterval: 0.5, 34 | repeats: true, 35 | block: { 36 | _ in self.labelTime.text = String(format: "Frame Processing Time: %.2f ms", 1000*audioController.timeBuffer.movingAverage) 37 | 38 | 39 | }); 40 | 41 | audioController.noiseReductionSelect = Int32(self.noiseReductionSelect.selectedSegmentIndex) 42 | buttonEnable(set: false); 43 | audioController.start(storeSwitch.isOn); 44 | 45 | } 46 | 47 | @IBAction func buttonStopPress(_ sender: Any) { 48 | timer.invalidate() 49 | buttonEnable(set: true); 50 | audioController.stop(); 51 | labelTime.text = "Frame Processing Time:" 52 | 53 | } 54 | 55 | 56 | override func viewDidLoad() { 57 | super.viewDidLoad() 58 | // Do any additional setup after loading the view, typically from a nib. 59 | 60 | storeSwitch.setOn(false, animated: false) 61 | storeLabel.text = "Record Audio" 62 | buttonEnable(set: true); 63 | audioController = IOSAudioController(); 64 | labelTime.text = "Frame Processing Time:" 65 | infoView.text = audioController.info 66 | } 67 | 68 | override func didReceiveMemoryWarning() { 69 | super.didReceiveMemoryWarning() 70 | // Dispose of any resources that can be recreated. 71 | } 72 | 73 | 74 | } 75 | 76 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/abs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: abs.c 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | /* Include Files */ 12 | #include "rt_nonfinite.h" 13 | #include "wienerAB.h" 14 | #include "abs.h" 15 | #include "wienerAB_rtwutil.h" 16 | 17 | /* Function Definitions */ 18 | 19 | /* 20 | * Arguments : const creal32_T x[512] 21 | * float y[512] 22 | * Return Type : void 23 | */ 24 | void b_abs(const creal32_T x[512], float y[512]) 25 | { 26 | int k; 27 | for (k = 0; k < 512; k++) { 28 | y[k] = rt_hypotf_snf(x[k].re, x[k].im); 29 | } 30 | } 31 | 32 | /* 33 | * File trailer for abs.c 34 | * 35 | * [EOF] 36 | */ 37 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/abs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: abs.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef ABS_H 12 | #define ABS_H 13 | 14 | /* Include Files */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "rt_nonfinite.h" 20 | #include "rtwtypes.h" 21 | #include "wienerAB_types.h" 22 | 23 | /* Function Declarations */ 24 | extern void b_abs(const creal32_T x[512], float y[512]); 25 | 26 | #endif 27 | 28 | /* 29 | * File trailer for abs.h 30 | * 31 | * [EOF] 32 | */ 33 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/bluestein_setup.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: bluestein_setup.c 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | /* Include Files */ 12 | #include "rt_nonfinite.h" 13 | #include "wienerAB.h" 14 | #include "bluestein_setup.h" 15 | 16 | /* Function Definitions */ 17 | 18 | /* 19 | * Arguments : creal32_T wwc[799] 20 | * Return Type : void 21 | */ 22 | void bluestein_setup(creal32_T wwc[799]) 23 | { 24 | int idx; 25 | int rt; 26 | int k; 27 | int y; 28 | float nt_im; 29 | float nt_re; 30 | idx = 398; 31 | rt = 0; 32 | wwc[399].re = 1.0F; 33 | wwc[399].im = 0.0F; 34 | for (k = 0; k < 399; k++) { 35 | y = ((k + 1) << 1) - 1; 36 | if (800 - rt <= y) { 37 | rt = (y + rt) - 800; 38 | } else { 39 | rt += y; 40 | } 41 | 42 | nt_im = -3.14159274F * (float)rt / 400.0F; 43 | if (nt_im == 0.0F) { 44 | nt_re = 1.0F; 45 | nt_im = 0.0F; 46 | } else { 47 | nt_re = (float)cos(nt_im); 48 | nt_im = (float)sin(nt_im); 49 | } 50 | 51 | wwc[idx].re = nt_re; 52 | wwc[idx].im = -nt_im; 53 | idx--; 54 | } 55 | 56 | idx = 0; 57 | for (k = 398; k >= 0; k += -1) { 58 | wwc[k + 400] = wwc[idx]; 59 | idx++; 60 | } 61 | } 62 | 63 | /* 64 | * File trailer for bluestein_setup.c 65 | * 66 | * [EOF] 67 | */ 68 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/bluestein_setup.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: bluestein_setup.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef BLUESTEIN_SETUP_H 12 | #define BLUESTEIN_SETUP_H 13 | 14 | /* Include Files */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "rt_nonfinite.h" 20 | #include "rtwtypes.h" 21 | #include "wienerAB_types.h" 22 | 23 | /* Function Declarations */ 24 | extern void bluestein_setup(creal32_T wwc[799]); 25 | 26 | #endif 27 | 28 | /* 29 | * File trailer for bluestein_setup.h 30 | * 31 | * [EOF] 32 | */ 33 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/fft.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: fft.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef FFT_H 12 | #define FFT_H 13 | 14 | /* Include Files */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "rt_nonfinite.h" 20 | #include "rtwtypes.h" 21 | #include "wienerAB_types.h" 22 | 23 | /* Function Declarations */ 24 | extern void b_fft(const float x[400], creal32_T y[512]); 25 | extern void fft(const float x[400], creal32_T y[400]); 26 | 27 | #endif 28 | 29 | /* 30 | * File trailer for fft.h 31 | * 32 | * [EOF] 33 | */ 34 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/filterCoefficients.h: -------------------------------------------------------------------------------- 1 | // 2 | // filterCoefficients.h 3 | // NC-2Ch 4 | // 5 | // Created by Abhishek Sehgal on 5/17/17. 6 | // Copyright © 2017 SIPLab. All rights reserved. 7 | // 8 | 9 | 10 | 11 | #define NCOEFFS 81 12 | 13 | 14 | const float filterCoefficients[] = {0.00014543,0.00028767,0.0002943,9.5746e-05,-0.00033927,-0.00069088,-0.00064432,1.669e-05,0.00096313,0.0015294,0.0010208,-0.00054488,-0.0022758,-0.0027458,-0.0011214,0.0019911,0.0044961,0.004146,0.00031845,-0.0049142,-0.0077294,-0.0051395,0.0022971,0.0099666,0.011779,0.0046813,-0.0081021,-0.017933,-0.016155,-0.00088928,0.01962,0.030579,0.020125,-0.01076,-0.044912,-0.055944,-0.022911,0.055509,0.15629,0.24093,0.27391,0.24093,0.15629,0.055509,-0.022911,-0.055944,-0.044912,-0.01076,0.020125,0.030579,0.01962,-0.00088928,-0.016155,-0.017933,-0.0081021,0.0046813,0.011779,0.0099666,0.0022971,-0.0051395,-0.0077294,-0.0049142,0.00031845,0.004146,0.0044961,0.0019911,-0.0011214,-0.0027458,-0.0022758,-0.00054488,0.0010208,0.0015294,0.00096313,1.669e-05,-0.00064432,-0.00069088,-0.00033927,9.5746e-05,0.0002943,0.00028767,0.00014543}; 15 | 16 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/power.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: power.c 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | /* Include Files */ 12 | #include "rt_nonfinite.h" 13 | #include "wienerAB.h" 14 | #include "power.h" 15 | #include "wienerAB_emxutil.h" 16 | 17 | /* Function Definitions */ 18 | 19 | /* 20 | * Arguments : const emxArray_real32_T *a 21 | * emxArray_real32_T *y 22 | * Return Type : void 23 | */ 24 | void b_power(const emxArray_real32_T *a, emxArray_real32_T *y) 25 | { 26 | short iv0[2]; 27 | int n; 28 | int k; 29 | for (n = 0; n < 2; n++) { 30 | iv0[n] = (short)a->size[n]; 31 | } 32 | 33 | n = y->size[0] * y->size[1]; 34 | y->size[0] = iv0[0]; 35 | y->size[1] = iv0[1]; 36 | emxEnsureCapacity((emxArray__common *)y, n, (int)sizeof(float)); 37 | n = a->size[0] * a->size[1]; 38 | for (k = 0; k + 1 <= n; k++) { 39 | y->data[k] = a->data[k] * a->data[k]; 40 | } 41 | } 42 | 43 | /* 44 | * Arguments : const float a[512] 45 | * float y[512] 46 | * Return Type : void 47 | */ 48 | void power(const float a[512], float y[512]) 49 | { 50 | int k; 51 | for (k = 0; k < 512; k++) { 52 | y[k] = a[k] * a[k]; 53 | } 54 | } 55 | 56 | /* 57 | * File trailer for power.c 58 | * 59 | * [EOF] 60 | */ 61 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/power.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: power.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef POWER_H 12 | #define POWER_H 13 | 14 | /* Include Files */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "rt_nonfinite.h" 20 | #include "rtwtypes.h" 21 | #include "wienerAB_types.h" 22 | 23 | /* Function Declarations */ 24 | extern void b_power(const emxArray_real32_T *a, emxArray_real32_T *y); 25 | extern void power(const float a[512], float y[512]); 26 | 27 | #endif 28 | 29 | /* 30 | * File trailer for power.h 31 | * 32 | * [EOF] 33 | */ 34 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/rdivide.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: rdivide.c 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | /* Include Files */ 12 | #include "rt_nonfinite.h" 13 | #include "wienerAB.h" 14 | #include "rdivide.h" 15 | 16 | /* Function Definitions */ 17 | 18 | /* 19 | * Arguments : const float x[512] 20 | * const emxArray_real32_T *y 21 | * float z[512] 22 | * Return Type : void 23 | */ 24 | void rdivide(const float x[512], const emxArray_real32_T *y, float z[512]) 25 | { 26 | int i0; 27 | for (i0 = 0; i0 < 512; i0++) { 28 | z[i0] = x[i0] / y->data[i0]; 29 | } 30 | } 31 | 32 | /* 33 | * File trailer for rdivide.c 34 | * 35 | * [EOF] 36 | */ 37 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/rdivide.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: rdivide.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef RDIVIDE_H 12 | #define RDIVIDE_H 13 | 14 | /* Include Files */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "rt_nonfinite.h" 20 | #include "rtwtypes.h" 21 | #include "wienerAB_types.h" 22 | 23 | /* Function Declarations */ 24 | extern void rdivide(const float x[512], const emxArray_real32_T *y, float z[512]); 25 | 26 | #endif 27 | 28 | /* 29 | * File trailer for rdivide.h 30 | * 31 | * [EOF] 32 | */ 33 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/rtGetInf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: rtGetInf.c 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | /* 12 | * Abstract: 13 | * MATLAB for code generation function to initialize non-finite, Inf and MinusInf 14 | */ 15 | #include "rtGetInf.h" 16 | #define NumBitsPerChar 8U 17 | 18 | /* Function: rtGetInf ================================================== 19 | * Abstract: 20 | * Initialize rtInf needed by the generated code. 21 | * Inf is initialized as non-signaling. Assumes IEEE. 22 | */ 23 | real_T rtGetInf(void) 24 | { 25 | size_t bitsPerReal = sizeof(real_T) * (NumBitsPerChar); 26 | real_T inf = 0.0; 27 | if (bitsPerReal == 32U) { 28 | inf = rtGetInfF(); 29 | } else { 30 | uint16_T one = 1U; 31 | enum { 32 | LittleEndian, 33 | BigEndian 34 | } machByteOrder = (*((uint8_T *) &one) == 1U) ? LittleEndian : BigEndian; 35 | switch (machByteOrder) { 36 | case LittleEndian: 37 | { 38 | union { 39 | LittleEndianIEEEDouble bitVal; 40 | real_T fltVal; 41 | } tmpVal; 42 | 43 | tmpVal.bitVal.words.wordH = 0x7FF00000U; 44 | tmpVal.bitVal.words.wordL = 0x00000000U; 45 | inf = tmpVal.fltVal; 46 | break; 47 | } 48 | 49 | case BigEndian: 50 | { 51 | union { 52 | BigEndianIEEEDouble bitVal; 53 | real_T fltVal; 54 | } tmpVal; 55 | 56 | tmpVal.bitVal.words.wordH = 0x7FF00000U; 57 | tmpVal.bitVal.words.wordL = 0x00000000U; 58 | inf = tmpVal.fltVal; 59 | break; 60 | } 61 | } 62 | } 63 | 64 | return inf; 65 | } 66 | 67 | /* Function: rtGetInfF ================================================== 68 | * Abstract: 69 | * Initialize rtInfF needed by the generated code. 70 | * Inf is initialized as non-signaling. Assumes IEEE. 71 | */ 72 | real32_T rtGetInfF(void) 73 | { 74 | IEEESingle infF; 75 | infF.wordL.wordLuint = 0x7F800000U; 76 | return infF.wordL.wordLreal; 77 | } 78 | 79 | /* Function: rtGetMinusInf ================================================== 80 | * Abstract: 81 | * Initialize rtMinusInf needed by the generated code. 82 | * Inf is initialized as non-signaling. Assumes IEEE. 83 | */ 84 | real_T rtGetMinusInf(void) 85 | { 86 | size_t bitsPerReal = sizeof(real_T) * (NumBitsPerChar); 87 | real_T minf = 0.0; 88 | if (bitsPerReal == 32U) { 89 | minf = rtGetMinusInfF(); 90 | } else { 91 | uint16_T one = 1U; 92 | enum { 93 | LittleEndian, 94 | BigEndian 95 | } machByteOrder = (*((uint8_T *) &one) == 1U) ? LittleEndian : BigEndian; 96 | switch (machByteOrder) { 97 | case LittleEndian: 98 | { 99 | union { 100 | LittleEndianIEEEDouble bitVal; 101 | real_T fltVal; 102 | } tmpVal; 103 | 104 | tmpVal.bitVal.words.wordH = 0xFFF00000U; 105 | tmpVal.bitVal.words.wordL = 0x00000000U; 106 | minf = tmpVal.fltVal; 107 | break; 108 | } 109 | 110 | case BigEndian: 111 | { 112 | union { 113 | BigEndianIEEEDouble bitVal; 114 | real_T fltVal; 115 | } tmpVal; 116 | 117 | tmpVal.bitVal.words.wordH = 0xFFF00000U; 118 | tmpVal.bitVal.words.wordL = 0x00000000U; 119 | minf = tmpVal.fltVal; 120 | break; 121 | } 122 | } 123 | } 124 | 125 | return minf; 126 | } 127 | 128 | /* Function: rtGetMinusInfF ================================================== 129 | * Abstract: 130 | * Initialize rtMinusInfF needed by the generated code. 131 | * Inf is initialized as non-signaling. Assumes IEEE. 132 | */ 133 | real32_T rtGetMinusInfF(void) 134 | { 135 | IEEESingle minfF; 136 | minfF.wordL.wordLuint = 0xFF800000U; 137 | return minfF.wordL.wordLreal; 138 | } 139 | 140 | /* 141 | * File trailer for rtGetInf.c 142 | * 143 | * [EOF] 144 | */ 145 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/rtGetInf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: rtGetInf.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef RTGETINF_H 12 | #define RTGETINF_H 13 | #include 14 | #include "rtwtypes.h" 15 | #include "rt_nonfinite.h" 16 | 17 | extern real_T rtGetInf(void); 18 | extern real32_T rtGetInfF(void); 19 | extern real_T rtGetMinusInf(void); 20 | extern real32_T rtGetMinusInfF(void); 21 | 22 | #endif 23 | 24 | /* 25 | * File trailer for rtGetInf.h 26 | * 27 | * [EOF] 28 | */ 29 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/rtGetNaN.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: rtGetNaN.c 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | /* 12 | * Abstract: 13 | * MATLAB for code generation function to initialize non-finite, NaN 14 | */ 15 | #include "rtGetNaN.h" 16 | #define NumBitsPerChar 8U 17 | 18 | /* Function: rtGetNaN ================================================== 19 | * Abstract: 20 | * Initialize rtNaN needed by the generated code. 21 | * NaN is initialized as non-signaling. Assumes IEEE. 22 | */ 23 | real_T rtGetNaN(void) 24 | { 25 | size_t bitsPerReal = sizeof(real_T) * (NumBitsPerChar); 26 | real_T nan = 0.0; 27 | if (bitsPerReal == 32U) { 28 | nan = rtGetNaNF(); 29 | } else { 30 | uint16_T one = 1U; 31 | enum { 32 | LittleEndian, 33 | BigEndian 34 | } machByteOrder = (*((uint8_T *) &one) == 1U) ? LittleEndian : BigEndian; 35 | switch (machByteOrder) { 36 | case LittleEndian: 37 | { 38 | union { 39 | LittleEndianIEEEDouble bitVal; 40 | real_T fltVal; 41 | } tmpVal; 42 | 43 | tmpVal.bitVal.words.wordH = 0xFFF80000U; 44 | tmpVal.bitVal.words.wordL = 0x00000000U; 45 | nan = tmpVal.fltVal; 46 | break; 47 | } 48 | 49 | case BigEndian: 50 | { 51 | union { 52 | BigEndianIEEEDouble bitVal; 53 | real_T fltVal; 54 | } tmpVal; 55 | 56 | tmpVal.bitVal.words.wordH = 0x7FFFFFFFU; 57 | tmpVal.bitVal.words.wordL = 0xFFFFFFFFU; 58 | nan = tmpVal.fltVal; 59 | break; 60 | } 61 | } 62 | } 63 | 64 | return nan; 65 | } 66 | 67 | /* Function: rtGetNaNF ================================================== 68 | * Abstract: 69 | * Initialize rtNaNF needed by the generated code. 70 | * NaN is initialized as non-signaling. Assumes IEEE. 71 | */ 72 | real32_T rtGetNaNF(void) 73 | { 74 | IEEESingle nanF = { { 0 } }; 75 | 76 | uint16_T one = 1U; 77 | enum { 78 | LittleEndian, 79 | BigEndian 80 | } machByteOrder = (*((uint8_T *) &one) == 1U) ? LittleEndian : BigEndian; 81 | switch (machByteOrder) { 82 | case LittleEndian: 83 | { 84 | nanF.wordL.wordLuint = 0xFFC00000U; 85 | break; 86 | } 87 | 88 | case BigEndian: 89 | { 90 | nanF.wordL.wordLuint = 0x7FFFFFFFU; 91 | break; 92 | } 93 | } 94 | 95 | return nanF.wordL.wordLreal; 96 | } 97 | 98 | /* 99 | * File trailer for rtGetNaN.c 100 | * 101 | * [EOF] 102 | */ 103 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/rtGetNaN.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: rtGetNaN.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef RTGETNAN_H 12 | #define RTGETNAN_H 13 | #include 14 | #include "rtwtypes.h" 15 | #include "rt_nonfinite.h" 16 | 17 | extern real_T rtGetNaN(void); 18 | extern real32_T rtGetNaNF(void); 19 | 20 | #endif 21 | 22 | /* 23 | * File trailer for rtGetNaN.h 24 | * 25 | * [EOF] 26 | */ 27 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/rt_nonfinite.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: rt_nonfinite.c 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | /* 12 | * Abstract: 13 | * MATLAB for code generation function to initialize non-finites, 14 | * (Inf, NaN and -Inf). 15 | */ 16 | #include "rt_nonfinite.h" 17 | #include "rtGetNaN.h" 18 | #include "rtGetInf.h" 19 | 20 | real_T rtInf; 21 | real_T rtMinusInf; 22 | real_T rtNaN; 23 | real32_T rtInfF; 24 | real32_T rtMinusInfF; 25 | real32_T rtNaNF; 26 | 27 | /* Function: rt_InitInfAndNaN ================================================== 28 | * Abstract: 29 | * Initialize the rtInf, rtMinusInf, and rtNaN needed by the 30 | * generated code. NaN is initialized as non-signaling. Assumes IEEE. 31 | */ 32 | void rt_InitInfAndNaN(size_t realSize) 33 | { 34 | (void) (realSize); 35 | rtNaN = rtGetNaN(); 36 | rtNaNF = rtGetNaNF(); 37 | rtInf = rtGetInf(); 38 | rtInfF = rtGetInfF(); 39 | rtMinusInf = rtGetMinusInf(); 40 | rtMinusInfF = rtGetMinusInfF(); 41 | } 42 | 43 | /* Function: rtIsInf ================================================== 44 | * Abstract: 45 | * Test if value is infinite 46 | */ 47 | boolean_T rtIsInf(real_T value) 48 | { 49 | return ((value==rtInf || value==rtMinusInf) ? 1U : 0U); 50 | } 51 | 52 | /* Function: rtIsInfF ================================================= 53 | * Abstract: 54 | * Test if single-precision value is infinite 55 | */ 56 | boolean_T rtIsInfF(real32_T value) 57 | { 58 | return(((value)==rtInfF || (value)==rtMinusInfF) ? 1U : 0U); 59 | } 60 | 61 | /* Function: rtIsNaN ================================================== 62 | * Abstract: 63 | * Test if value is not a number 64 | */ 65 | boolean_T rtIsNaN(real_T value) 66 | { 67 | 68 | #if defined(_MSC_VER) && (_MSC_VER <= 1200) 69 | 70 | return _isnan(value)? TRUE:FALSE; 71 | 72 | #else 73 | 74 | return (value!=value)? 1U:0U; 75 | 76 | #endif 77 | 78 | } 79 | 80 | /* Function: rtIsNaNF ================================================= 81 | * Abstract: 82 | * Test if single-precision value is not a number 83 | */ 84 | boolean_T rtIsNaNF(real32_T value) 85 | { 86 | 87 | #if defined(_MSC_VER) && (_MSC_VER <= 1200) 88 | 89 | return _isnan((real_T)value)? true:false; 90 | 91 | #else 92 | 93 | return (value!=value)? 1U:0U; 94 | 95 | #endif 96 | 97 | } 98 | 99 | /* 100 | * File trailer for rt_nonfinite.c 101 | * 102 | * [EOF] 103 | */ 104 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/rt_nonfinite.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: rt_nonfinite.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef RT_NONFINITE_H 12 | #define RT_NONFINITE_H 13 | #if defined(_MSC_VER) && (_MSC_VER <= 1200) 14 | #include 15 | #endif 16 | 17 | #include 18 | #include "rtwtypes.h" 19 | 20 | extern real_T rtInf; 21 | extern real_T rtMinusInf; 22 | extern real_T rtNaN; 23 | extern real32_T rtInfF; 24 | extern real32_T rtMinusInfF; 25 | extern real32_T rtNaNF; 26 | extern void rt_InitInfAndNaN(size_t realSize); 27 | extern boolean_T rtIsInf(real_T value); 28 | extern boolean_T rtIsInfF(real32_T value); 29 | extern boolean_T rtIsNaN(real_T value); 30 | extern boolean_T rtIsNaNF(real32_T value); 31 | typedef struct { 32 | struct { 33 | uint32_T wordH; 34 | uint32_T wordL; 35 | } words; 36 | } BigEndianIEEEDouble; 37 | 38 | typedef struct { 39 | struct { 40 | uint32_T wordL; 41 | uint32_T wordH; 42 | } words; 43 | } LittleEndianIEEEDouble; 44 | 45 | typedef struct { 46 | union { 47 | real32_T wordLreal; 48 | uint32_T wordLuint; 49 | } wordL; 50 | } IEEESingle; 51 | 52 | #endif 53 | 54 | /* 55 | * File trailer for rt_nonfinite.h 56 | * 57 | * [EOF] 58 | */ 59 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/rtwtypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: rtwtypes.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef RTWTYPES_H 12 | #define RTWTYPES_H 13 | #ifndef __TMWTYPES__ 14 | #define __TMWTYPES__ 15 | 16 | /*=======================================================================* 17 | * Target hardware information 18 | * Device type: Generic->MATLAB Host Computer 19 | * Number of bits: char: 8 short: 16 int: 32 20 | * long: 64 long long: 64 21 | * native word size: 64 22 | * Byte ordering: LittleEndian 23 | * Signed integer division rounds to: Zero 24 | * Shift right on a signed integer as arithmetic shift: on 25 | *=======================================================================*/ 26 | 27 | /*=======================================================================* 28 | * Fixed width word size data types: * 29 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 30 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 31 | * real32_T, real64_T - 32 and 64 bit floating point numbers * 32 | *=======================================================================*/ 33 | typedef signed char int8_T; 34 | typedef unsigned char uint8_T; 35 | typedef short int16_T; 36 | typedef unsigned short uint16_T; 37 | typedef int int32_T; 38 | typedef unsigned int uint32_T; 39 | typedef long int64_T; 40 | typedef unsigned long uint64_T; 41 | typedef float real32_T; 42 | typedef double real64_T; 43 | 44 | /*===========================================================================* 45 | * Generic type definitions: real_T, time_T, boolean_T, int_T, uint_T, * 46 | * ulong_T, ulonglong_T, char_T and byte_T. * 47 | *===========================================================================*/ 48 | typedef double real_T; 49 | typedef double time_T; 50 | typedef unsigned char boolean_T; 51 | typedef int int_T; 52 | typedef unsigned int uint_T; 53 | typedef unsigned long ulong_T; 54 | typedef unsigned long long ulonglong_T; 55 | typedef char char_T; 56 | typedef char_T byte_T; 57 | 58 | /*===========================================================================* 59 | * Complex number type definitions * 60 | *===========================================================================*/ 61 | #define CREAL_T 62 | 63 | typedef struct { 64 | real32_T re; 65 | real32_T im; 66 | } creal32_T; 67 | 68 | typedef struct { 69 | real64_T re; 70 | real64_T im; 71 | } creal64_T; 72 | 73 | typedef struct { 74 | real_T re; 75 | real_T im; 76 | } creal_T; 77 | 78 | typedef struct { 79 | int8_T re; 80 | int8_T im; 81 | } cint8_T; 82 | 83 | typedef struct { 84 | uint8_T re; 85 | uint8_T im; 86 | } cuint8_T; 87 | 88 | typedef struct { 89 | int16_T re; 90 | int16_T im; 91 | } cint16_T; 92 | 93 | typedef struct { 94 | uint16_T re; 95 | uint16_T im; 96 | } cuint16_T; 97 | 98 | typedef struct { 99 | int32_T re; 100 | int32_T im; 101 | } cint32_T; 102 | 103 | typedef struct { 104 | uint32_T re; 105 | uint32_T im; 106 | } cuint32_T; 107 | 108 | typedef struct { 109 | int64_T re; 110 | int64_T im; 111 | } cint64_T; 112 | 113 | typedef struct { 114 | uint64_T re; 115 | uint64_T im; 116 | } cuint64_T; 117 | 118 | /*=======================================================================* 119 | * Min and Max: * 120 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 121 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 122 | *=======================================================================*/ 123 | #define MAX_int8_T ((int8_T)(127)) 124 | #define MIN_int8_T ((int8_T)(-128)) 125 | #define MAX_uint8_T ((uint8_T)(255)) 126 | #define MIN_uint8_T ((uint8_T)(0)) 127 | #define MAX_int16_T ((int16_T)(32767)) 128 | #define MIN_int16_T ((int16_T)(-32768)) 129 | #define MAX_uint16_T ((uint16_T)(65535)) 130 | #define MIN_uint16_T ((uint16_T)(0)) 131 | #define MAX_int32_T ((int32_T)(2147483647)) 132 | #define MIN_int32_T ((int32_T)(-2147483647-1)) 133 | #define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU)) 134 | #define MIN_uint32_T ((uint32_T)(0)) 135 | #define MAX_int64_T ((int64_T)(9223372036854775807L)) 136 | #define MIN_int64_T ((int64_T)(-9223372036854775807L-1L)) 137 | #define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFUL)) 138 | #define MIN_uint64_T ((uint64_T)(0UL)) 139 | 140 | /* Logical type definitions */ 141 | #if !defined(__cplusplus) && !defined(__true_false_are_keywords) 142 | # ifndef false 143 | # define false (0U) 144 | # endif 145 | 146 | # ifndef true 147 | # define true (1U) 148 | # endif 149 | #endif 150 | 151 | /* 152 | * Maximum length of a MATLAB identifier (function/variable) 153 | * including the null-termination character. Referenced by 154 | * rt_logging.c and rt_matrx.c. 155 | */ 156 | #define TMW_NAME_LENGTH_MAX 64 157 | #endif 158 | #endif 159 | 160 | /* 161 | * File trailer for rtwtypes.h 162 | * 163 | * [EOF] 164 | */ 165 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/wienerAB.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: wienerAB.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef WIENERAB_H 12 | #define WIENERAB_H 13 | 14 | /* Include Files */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "rt_nonfinite.h" 20 | #include "rtwtypes.h" 21 | #include "wienerAB_types.h" 22 | 23 | /* Function Declarations */ 24 | extern void wienerAB(const float frame_in[200], float spl_threshold, float Srate, 25 | float out[200]); 26 | extern void wienerAB_free(void); 27 | extern void wienerAB_init(void); 28 | 29 | #endif 30 | 31 | /* 32 | * File trailer for wienerAB.h 33 | * 34 | * [EOF] 35 | */ 36 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/wienerAB_emxutil.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: wienerAB_emxutil.c 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | /* Include Files */ 12 | #include "rt_nonfinite.h" 13 | #include "wienerAB.h" 14 | #include "wienerAB_emxutil.h" 15 | 16 | /* Function Definitions */ 17 | 18 | /* 19 | * Arguments : emxArray__common *emxArray 20 | * int oldNumel 21 | * int elementSize 22 | * Return Type : void 23 | */ 24 | void emxEnsureCapacity(emxArray__common *emxArray, int oldNumel, int elementSize) 25 | { 26 | int newNumel; 27 | int i; 28 | void *newData; 29 | if (oldNumel < 0) { 30 | oldNumel = 0; 31 | } 32 | 33 | newNumel = 1; 34 | for (i = 0; i < emxArray->numDimensions; i++) { 35 | newNumel *= emxArray->size[i]; 36 | } 37 | 38 | if (newNumel > emxArray->allocatedSize) { 39 | i = emxArray->allocatedSize; 40 | if (i < 16) { 41 | i = 16; 42 | } 43 | 44 | while (i < newNumel) { 45 | if (i > 1073741823) { 46 | i = MAX_int32_T; 47 | } else { 48 | i <<= 1; 49 | } 50 | } 51 | 52 | newData = calloc((unsigned int)i, (unsigned int)elementSize); 53 | if (emxArray->data != NULL) { 54 | memcpy(newData, emxArray->data, (unsigned int)(elementSize * oldNumel)); 55 | if (emxArray->canFreeData) { 56 | free(emxArray->data); 57 | } 58 | } 59 | 60 | emxArray->data = newData; 61 | emxArray->allocatedSize = i; 62 | emxArray->canFreeData = true; 63 | } 64 | } 65 | 66 | /* 67 | * Arguments : emxArray_real32_T **pEmxArray 68 | * Return Type : void 69 | */ 70 | void emxFree_real32_T(emxArray_real32_T **pEmxArray) 71 | { 72 | if (*pEmxArray != (emxArray_real32_T *)NULL) { 73 | if (((*pEmxArray)->data != (float *)NULL) && (*pEmxArray)->canFreeData) { 74 | free((void *)(*pEmxArray)->data); 75 | } 76 | 77 | free((void *)(*pEmxArray)->size); 78 | free((void *)*pEmxArray); 79 | *pEmxArray = (emxArray_real32_T *)NULL; 80 | } 81 | } 82 | 83 | /* 84 | * Arguments : emxArray_real32_T **pEmxArray 85 | * int numDimensions 86 | * Return Type : void 87 | */ 88 | void emxInit_real32_T(emxArray_real32_T **pEmxArray, int numDimensions) 89 | { 90 | emxArray_real32_T *emxArray; 91 | int i; 92 | *pEmxArray = (emxArray_real32_T *)malloc(sizeof(emxArray_real32_T)); 93 | emxArray = *pEmxArray; 94 | emxArray->data = (float *)NULL; 95 | emxArray->numDimensions = numDimensions; 96 | emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions)); 97 | emxArray->allocatedSize = 0; 98 | emxArray->canFreeData = true; 99 | for (i = 0; i < numDimensions; i++) { 100 | emxArray->size[i] = 0; 101 | } 102 | } 103 | 104 | /* 105 | * File trailer for wienerAB_emxutil.c 106 | * 107 | * [EOF] 108 | */ 109 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/wienerAB_emxutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: wienerAB_emxutil.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef WIENERAB_EMXUTIL_H 12 | #define WIENERAB_EMXUTIL_H 13 | 14 | /* Include Files */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "rt_nonfinite.h" 20 | #include "rtwtypes.h" 21 | #include "wienerAB_types.h" 22 | 23 | /* Function Declarations */ 24 | extern void emxEnsureCapacity(emxArray__common *emxArray, int oldNumel, int 25 | elementSize); 26 | extern void emxFree_real32_T(emxArray_real32_T **pEmxArray); 27 | extern void emxInit_real32_T(emxArray_real32_T **pEmxArray, int numDimensions); 28 | 29 | #endif 30 | 31 | /* 32 | * File trailer for wienerAB_emxutil.h 33 | * 34 | * [EOF] 35 | */ 36 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/wienerAB_initialize.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: wienerAB_initialize.c 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | /* Include Files */ 12 | #include "rt_nonfinite.h" 13 | #include "wienerAB.h" 14 | #include "wienerAB_initialize.h" 15 | 16 | /* Function Definitions */ 17 | 18 | /* 19 | * Arguments : void 20 | * Return Type : void 21 | */ 22 | void wienerAB_initialize(void) 23 | { 24 | rt_InitInfAndNaN(8U); 25 | wienerAB_init(); 26 | } 27 | 28 | /* 29 | * File trailer for wienerAB_initialize.c 30 | * 31 | * [EOF] 32 | */ 33 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/wienerAB_initialize.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: wienerAB_initialize.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef WIENERAB_INITIALIZE_H 12 | #define WIENERAB_INITIALIZE_H 13 | 14 | /* Include Files */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "rt_nonfinite.h" 20 | #include "rtwtypes.h" 21 | #include "wienerAB_types.h" 22 | 23 | /* Function Declarations */ 24 | extern void wienerAB_initialize(void); 25 | 26 | #endif 27 | 28 | /* 29 | * File trailer for wienerAB_initialize.h 30 | * 31 | * [EOF] 32 | */ 33 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/wienerAB_rtwutil.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: wienerAB_rtwutil.c 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | /* Include Files */ 12 | #include "rt_nonfinite.h" 13 | #include "wienerAB.h" 14 | #include "wienerAB_rtwutil.h" 15 | 16 | /* Function Definitions */ 17 | 18 | /* 19 | * Arguments : float u0 20 | * float u1 21 | * Return Type : float 22 | */ 23 | float rt_hypotf_snf(float u0, float u1) 24 | { 25 | float y; 26 | float a; 27 | float b; 28 | a = (float)fabs(u0); 29 | b = (float)fabs(u1); 30 | if (a < b) { 31 | a /= b; 32 | y = b * (float)sqrt(a * a + 1.0F); 33 | } else if (a > b) { 34 | b /= a; 35 | y = a * (float)sqrt(b * b + 1.0F); 36 | } else if (rtIsNaNF(b)) { 37 | y = b; 38 | } else { 39 | y = a * 1.41421354F; 40 | } 41 | 42 | return y; 43 | } 44 | 45 | /* 46 | * File trailer for wienerAB_rtwutil.c 47 | * 48 | * [EOF] 49 | */ 50 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/wienerAB_rtwutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: wienerAB_rtwutil.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef WIENERAB_RTWUTIL_H 12 | #define WIENERAB_RTWUTIL_H 13 | 14 | /* Include Files */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "rt_nonfinite.h" 20 | #include "rtwtypes.h" 21 | #include "wienerAB_types.h" 22 | 23 | /* Function Declarations */ 24 | extern float rt_hypotf_snf(float u0, float u1); 25 | 26 | #endif 27 | 28 | /* 29 | * File trailer for wienerAB_rtwutil.h 30 | * 31 | * [EOF] 32 | */ 33 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/wienerAB_terminate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: wienerAB_terminate.c 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | /* Include Files */ 12 | #include "rt_nonfinite.h" 13 | #include "wienerAB.h" 14 | #include "wienerAB_terminate.h" 15 | 16 | /* Function Definitions */ 17 | 18 | /* 19 | * Arguments : void 20 | * Return Type : void 21 | */ 22 | void wienerAB_terminate(void) 23 | { 24 | wienerAB_free(); 25 | } 26 | 27 | /* 28 | * File trailer for wienerAB_terminate.c 29 | * 30 | * [EOF] 31 | */ 32 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/wienerAB_terminate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: wienerAB_terminate.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef WIENERAB_TERMINATE_H 12 | #define WIENERAB_TERMINATE_H 13 | 14 | /* Include Files */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "rt_nonfinite.h" 20 | #include "rtwtypes.h" 21 | #include "wienerAB_types.h" 22 | 23 | /* Function Declarations */ 24 | extern void wienerAB_terminate(void); 25 | 26 | #endif 27 | 28 | /* 29 | * File trailer for wienerAB_terminate.h 30 | * 31 | * [EOF] 32 | */ 33 | -------------------------------------------------------------------------------- /Noise-Reduction-2-Mic/Noise_Reduction/wienerAB_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Academic License - for use in teaching, academic research, and meeting 3 | * course requirements at degree granting institutions only. Not for 4 | * government, commercial, or other organizational use. 5 | * File: wienerAB_types.h 6 | * 7 | * MATLAB Coder version : 3.2 8 | * C/C++ source code generated on : 19-Jun-2017 17:45:48 9 | */ 10 | 11 | #ifndef WIENERAB_TYPES_H 12 | #define WIENERAB_TYPES_H 13 | 14 | /* Include Files */ 15 | #include "rtwtypes.h" 16 | 17 | /* Type Definitions */ 18 | #ifndef struct_emxArray__common 19 | #define struct_emxArray__common 20 | 21 | struct emxArray__common 22 | { 23 | void *data; 24 | int *size; 25 | int allocatedSize; 26 | int numDimensions; 27 | boolean_T canFreeData; 28 | }; 29 | 30 | #endif /*struct_emxArray__common*/ 31 | 32 | #ifndef typedef_emxArray__common 33 | #define typedef_emxArray__common 34 | 35 | typedef struct emxArray__common emxArray__common; 36 | 37 | #endif /*typedef_emxArray__common*/ 38 | 39 | #ifndef struct_emxArray_real32_T 40 | #define struct_emxArray_real32_T 41 | 42 | struct emxArray_real32_T 43 | { 44 | float *data; 45 | int *size; 46 | int allocatedSize; 47 | int numDimensions; 48 | boolean_T canFreeData; 49 | }; 50 | 51 | #endif /*struct_emxArray_real32_T*/ 52 | 53 | #ifndef typedef_emxArray_real32_T 54 | #define typedef_emxArray_real32_T 55 | 56 | typedef struct emxArray_real32_T emxArray_real32_T; 57 | 58 | #endif /*typedef_emxArray_real32_T*/ 59 | #endif 60 | 61 | /* 62 | * File trailer for wienerAB_types.h 63 | * 64 | * [EOF] 65 | */ 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adaptive Noise Reduction and Background Noise Classification using External Microphones on iOS 2 | 3 | This GitHub repository is the code accompaniment of the following paper: 4 | > **Utilization of two microphones for real-time low-latency audio smartphone apps**
5 | > Abhishek Sehgal and Nasser Kehtarnavaz - University of Texas at Dallas
6 | > https://ieeexplore.ieee.org/document/8326213
7 | > 8 | > **Abstract:** This paper presents an approach to overcome the limitation imposed by existing smartphone operating systems in using two microphones of smartphones at the same time for real-time low-latency audio apps that require the use of two microphones. This approach involves the use of an external dual-microphone and the processing steps needed to access audio signals from both of the external microphones at the same time. The developed approach is then applied to two example audio applications consisting of noise classification and noise reduction. It is shown that these dual-microphone apps lead to improved noise classification and noise reduction accuracy compared to the apps using a single microphone. 9 | 10 | ## Resources 11 | 12 | Supporting materials related to this work are available via the following links: 13 | 14 | |**Link**|Description 15 | |:-------|:---------- 16 | |https://ieeexplore.ieee.org/document/8326213| IEEE Manuscript 17 | |www.utdallas.edu/~kehtar/DualMicNoiseReduction.mp4| Videoclip of the Adaptive Noise Reduction app using 2 external mics on iOS 18 | |www.utdallas.edu/~kehtar/DualMicNoiseClassification.mp4| Videoclip of the Background Noise Classification app using 2 external mics on iOS 19 | 20 | ## Getting Started 21 | 22 | A [User's Guide](Users-Guide-iOS-TwoExternalMics.pdf) is provided which describes how to run the codes for the Adaptive Noise Reduction and Background Noise Classification apps on iOS smartphones. 23 | 24 | ## License and Citation 25 | The codes are licensed under MIT license. 26 | 27 | For any utilization of the code content of this repository, the following paper needs to get cited by the user: 28 | 29 | - A. Sehgal and N. Kehtarnavaz, "Utilization of two microphones for real-time low-latency audio smartphone apps," Proceedings of IEEE International Conference on Consumer Electronics (ICCE), Las Vegas, Jan 2018. 30 | -------------------------------------------------------------------------------- /Users-Guide-iOS-TwoExternalMics.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SIP-Lab/iOS-TwoExternalMics/a71cd4fa495e559f50c88551087f09ca07cdb073/Users-Guide-iOS-TwoExternalMics.pdf --------------------------------------------------------------------------------