From 22f75c99d8521c23cd6dd6ccede95037705d05bc Mon Sep 17 00:00:00 2001 From: Leo Thiessen Date: Thu, 7 Apr 2016 09:41:52 -0500 Subject: [PATCH 1/2] Added AEMeteringModule --- .../project.pbxproj | 16 +++++ .../Modules/Taps/AEMeteringModule.h | 57 ++++++++++++++++ .../Modules/Taps/AEMeteringModule.m | 65 +++++++++++++++++++ TheAmazingAudioEngine/TheAmazingAudioEngine.h | 1 + 4 files changed, 139 insertions(+) create mode 100644 TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.h create mode 100644 TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.m diff --git a/TheAmazingAudioEngine.xcodeproj/project.pbxproj b/TheAmazingAudioEngine.xcodeproj/project.pbxproj index 308dae2..7e53285 100644 --- a/TheAmazingAudioEngine.xcodeproj/project.pbxproj +++ b/TheAmazingAudioEngine.xcodeproj/project.pbxproj @@ -202,6 +202,12 @@ 4CDCADAD1CAB89CF008AAEF1 /* AEArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CDCADAB1CAB89CF008AAEF1 /* AEArray.m */; }; 4CDCADB51CABDE68008AAEF1 /* AEAudioUnitOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CDCADB31CABDE62008AAEF1 /* AEAudioUnitOutput.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4CDCADBB1CAC95A8008AAEF1 /* AEAudioUnitOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CDCADB41CABDE62008AAEF1 /* AEAudioUnitOutput.m */; }; + B337B7141CB6A39D005B7380 /* AEMeteringModule.h in Headers */ = {isa = PBXBuildFile; fileRef = B337B7121CB6A39D005B7380 /* AEMeteringModule.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B337B7151CB6A39D005B7380 /* AEMeteringModule.h in Headers */ = {isa = PBXBuildFile; fileRef = B337B7121CB6A39D005B7380 /* AEMeteringModule.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B337B7161CB6A39D005B7380 /* AEMeteringModule.h in Headers */ = {isa = PBXBuildFile; fileRef = B337B7121CB6A39D005B7380 /* AEMeteringModule.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B337B7171CB6A39D005B7380 /* AEMeteringModule.m in Sources */ = {isa = PBXBuildFile; fileRef = B337B7131CB6A39D005B7380 /* AEMeteringModule.m */; }; + B337B7181CB6A39D005B7380 /* AEMeteringModule.m in Sources */ = {isa = PBXBuildFile; fileRef = B337B7131CB6A39D005B7380 /* AEMeteringModule.m */; }; + B337B7191CB6A39D005B7380 /* AEMeteringModule.m in Sources */ = {isa = PBXBuildFile; fileRef = B337B7131CB6A39D005B7380 /* AEMeteringModule.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -321,6 +327,8 @@ 4CDCADAB1CAB89CF008AAEF1 /* AEArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AEArray.m; sourceTree = ""; }; 4CDCADB31CABDE62008AAEF1 /* AEAudioUnitOutput.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AEAudioUnitOutput.h; sourceTree = ""; }; 4CDCADB41CABDE62008AAEF1 /* AEAudioUnitOutput.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AEAudioUnitOutput.m; sourceTree = ""; }; + B337B7121CB6A39D005B7380 /* AEMeteringModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AEMeteringModule.h; sourceTree = ""; }; + B337B7131CB6A39D005B7380 /* AEMeteringModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AEMeteringModule.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -361,6 +369,8 @@ children = ( 4C94E2A31CAE6AFF006EB497 /* AEFileRecorderModule.h */, 4C94E2A41CAE6AFF006EB497 /* AEFileRecorderModule.m */, + B337B7121CB6A39D005B7380 /* AEMeteringModule.h */, + B337B7131CB6A39D005B7380 /* AEMeteringModule.m */, ); path = Taps; sourceTree = ""; @@ -554,6 +564,7 @@ 4C9F0F5D1CB265F90032903E /* AEAudioUnitModule.h in Headers */, 4C9F0F5E1CB265F90032903E /* AELowPassModule.h in Headers */, 4C9F0F5F1CB265F90032903E /* AEDynamicsProcessorModule.h in Headers */, + B337B7151CB6A39D005B7380 /* AEMeteringModule.h in Headers */, 4C9F0F601CB265F90032903E /* AEBandpassModule.h in Headers */, 4C9F0F621CB265F90032903E /* AEOscillatorModule.h in Headers */, 4C9F0F631CB265F90032903E /* AEParametricEqModule.h in Headers */, @@ -592,6 +603,7 @@ 4C9F0FA61CB269C30032903E /* AEAudioUnitModule.h in Headers */, 4C9F0FA71CB269C30032903E /* AELowPassModule.h in Headers */, 4C9F0FA81CB269C30032903E /* AEDynamicsProcessorModule.h in Headers */, + B337B7161CB6A39D005B7380 /* AEMeteringModule.h in Headers */, 4C9F0FA91CB269C30032903E /* AEBandpassModule.h in Headers */, 4C9F0FAA1CB269C30032903E /* AEOscillatorModule.h in Headers */, 4C9F0FAB1CB269C30032903E /* AEParametricEqModule.h in Headers */, @@ -637,6 +649,7 @@ 4CDCAD801CA5484D008AAEF1 /* AEHighPassModule.h in Headers */, 4CDCACEB1CA25B6F008AAEF1 /* TheAmazingAudioEngine.h in Headers */, 4C9F0F251CB224D70032903E /* AEIOAudioUnit.h in Headers */, + B337B7141CB6A39D005B7380 /* AEMeteringModule.h in Headers */, 4C94E2C91CAF95BD006EB497 /* AEManagedValue.h in Headers */, 4CDCAD391CA3C31C008AAEF1 /* AETypes.h in Headers */, 4CDCAD371CA3C31C008AAEF1 /* AEBufferStack.h in Headers */, @@ -797,6 +810,7 @@ 4C9F0F3E1CB265F90032903E /* AELowPassModule.m in Sources */, 4C9F0F3F1CB265F90032903E /* AEHighPassModule.m in Sources */, 4C9F0F401CB265F90032903E /* AEVarispeedModule.m in Sources */, + B337B7181CB6A39D005B7380 /* AEMeteringModule.m in Sources */, 4C9F0F411CB265F90032903E /* AEBandpassModule.m in Sources */, 4C9F0F421CB265F90032903E /* AEFileRecorderModule.m in Sources */, 4C9F0F431CB265F90032903E /* AEAudioFilePlayerModule.m in Sources */, @@ -835,6 +849,7 @@ 4C9F0F881CB269C30032903E /* AELowPassModule.m in Sources */, 4C9F0F891CB269C30032903E /* AEHighPassModule.m in Sources */, 4C9F0F8A1CB269C30032903E /* AEVarispeedModule.m in Sources */, + B337B7191CB6A39D005B7380 /* AEMeteringModule.m in Sources */, 4C9F0F8B1CB269C30032903E /* AEBandpassModule.m in Sources */, 4C9F0F8C1CB269C30032903E /* AEFileRecorderModule.m in Sources */, 4C9F0F8D1CB269C30032903E /* AEAudioFilePlayerModule.m in Sources */, @@ -873,6 +888,7 @@ 4CDCAD851CA5484D008AAEF1 /* AELowPassModule.m in Sources */, 4CDCAD811CA5484D008AAEF1 /* AEHighPassModule.m in Sources */, 4CDCAD911CA5484D008AAEF1 /* AEVarispeedModule.m in Sources */, + B337B7171CB6A39D005B7380 /* AEMeteringModule.m in Sources */, 4CDCAD791CA5484D008AAEF1 /* AEBandpassModule.m in Sources */, 4C94E2A61CAE6AFF006EB497 /* AEFileRecorderModule.m in Sources */, 4CDCADA11CA90FD3008AAEF1 /* AEAudioFilePlayerModule.m in Sources */, diff --git a/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.h b/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.h new file mode 100644 index 0000000..a5e4ce3 --- /dev/null +++ b/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.h @@ -0,0 +1,57 @@ +// +// AEMeteringModule.h +// TheAmazingAudioEngine +// +// Created on 4/06/2016. +// Copyright © 2016 A Tasty Pixel. All rights reserved. +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// + +#ifdef __cplusplus +extern "C" { +#endif + +#import "AEModule.h" + +/*! + * Stereo Audio Metering Module + * + * This module calculates the average and peak power for channels 0 and 1 (left/right). + * After processing, it leaves the buffer stack intact. + */ +@interface AEMeteringModule : AEModule + +/*! + * Default initializer + * + * @param renderer The renderer + */ +- (instancetype _Nullable)initWithRenderer:(AERenderer * _Nonnull)renderer; + +@property (nonatomic, readonly) double avgPowerLeft; +@property (nonatomic, readonly) double avgPowerRight; +@property (nonatomic, readonly) double peakPowerLeft; +@property (nonatomic, readonly) double peakPowerRight; + +@end + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.m b/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.m new file mode 100644 index 0000000..8f1b112 --- /dev/null +++ b/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.m @@ -0,0 +1,65 @@ +// +// AEMeteringModule.m +// TheAmazingAudioEngine +// +// Created on 4/06/2016. +// Copyright © 2016 A Tasty Pixel. All rights reserved. +// + +#import "AEMeteringModule.h" +#import + +@implementation AEMeteringModule { + float _avgPowerLeft; + float _avgPowerRight; + float _peakPowerLeft; + float _peakPowerRight; +} + +- (instancetype)initWithRenderer:(AERenderer *)renderer { + if ( !(self = [super initWithRenderer:renderer]) ) return nil; + self.processFunction = AEMeteringModuleProcess; + return self; +} + +- (double)avgPowerLeft { + return (double)_avgPowerLeft; +} + +- (double)avgPowerRight { + return (double)_avgPowerRight; +} + +- (double)peakPowerLeft { + return (double)_peakPowerLeft; +} + +- (double)peakPowerRight { + return (double)_peakPowerRight; +} + +static void AEMeteringModuleProcess(__unsafe_unretained AEMeteringModule * THIS, + const AERenderContext * _Nonnull context) { + const AudioBufferList * abl = AEBufferStackGet(context->stack, 0); + if ( !abl ) return; + + // "Left" Channel + if ( abl->mNumberBuffers > 0 ) { + float avg = 0.0f, peak = 0.0f; + vDSP_meamgv((float*)abl->mBuffers[0].mData, 1, &avg, context->frames); + vDSP_maxmgv((float*)abl->mBuffers[0].mData, 1, &peak, context->frames); + THIS->_peakPowerLeft = peak; + THIS->_avgPowerLeft = avg; + } + + // "Right" Channel + if ( abl->mNumberBuffers > 1 ) { + float avg = 0.0f, peak = 0.0f; + vDSP_meamgv((float*)abl->mBuffers[1].mData, 1, &avg, context->frames); + vDSP_maxmgv((float*)abl->mBuffers[1].mData, 1, &peak, context->frames); + THIS->_avgPowerRight = peak; + THIS->_peakPowerRight = avg; + } +} + +@end \ No newline at end of file diff --git a/TheAmazingAudioEngine/TheAmazingAudioEngine.h b/TheAmazingAudioEngine/TheAmazingAudioEngine.h index 7d4ad89..4a14128 100644 --- a/TheAmazingAudioEngine/TheAmazingAudioEngine.h +++ b/TheAmazingAudioEngine/TheAmazingAudioEngine.h @@ -45,6 +45,7 @@ #import #import #import +#import #if TARGET_OS_IPHONE #import #endif From 2692244c801ad078b068485b3178b4d5b6e610cc Mon Sep 17 00:00:00 2001 From: Leo Thiessen Date: Thu, 7 Apr 2016 09:47:10 -0500 Subject: [PATCH 2/2] Added AEMeteringModule - insert newline at end of files per github suggestion --- TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.h | 2 +- TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.h b/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.h index a5e4ce3..86c00ad 100644 --- a/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.h +++ b/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.h @@ -54,4 +54,4 @@ extern "C" { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.m b/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.m index 8f1b112..b04d845 100644 --- a/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.m +++ b/TheAmazingAudioEngine/Modules/Taps/AEMeteringModule.m @@ -62,4 +62,4 @@ static void AEMeteringModuleProcess(__unsafe_unretained AEMeteringModule * THIS, } } -@end \ No newline at end of file +@end