From 5baa7a07c2faf6086582a749baec5fffa1d2d7ef Mon Sep 17 00:00:00 2001 From: John Boiles Date: Tue, 15 Oct 2013 13:49:40 -0700 Subject: [PATCH 1/2] Adding some casts to get rid of Xcode warnings. --- Audjustable/Classes/AudioPlayer/AudioPlayer.m | 2 +- Audjustable/Classes/AudioPlayer/HttpDataSource.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Audjustable/Classes/AudioPlayer/AudioPlayer.m b/Audjustable/Classes/AudioPlayer/AudioPlayer.m index ff3099b..cfb035e 100644 --- a/Audjustable/Classes/AudioPlayer/AudioPlayer.m +++ b/Audjustable/Classes/AudioPlayer/AudioPlayer.m @@ -733,7 +733,7 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ if (currentlyReadingEntry->processedPacketsSizeTotal < 0xfffff) { - OSAtomicAdd32(packetSize, ¤tlyReadingEntry->processedPacketsSizeTotal); + OSAtomicAdd32((int32_t)packetSize, ¤tlyReadingEntry->processedPacketsSizeTotal); OSAtomicIncrement32(¤tlyReadingEntry->processedPacketsCount); } diff --git a/Audjustable/Classes/AudioPlayer/HttpDataSource.m b/Audjustable/Classes/AudioPlayer/HttpDataSource.m index 2839743..a0a5104 100644 --- a/Audjustable/Classes/AudioPlayer/HttpDataSource.m +++ b/Audjustable/Classes/AudioPlayer/HttpDataSource.m @@ -153,7 +153,7 @@ stream = 0; relativePosition = 0; - seekStart = offset; + seekStart = (int)offset; [self open]; [self reregisterForEvents]; From 05f50e11d0bcd3b4ebb5be210c6e4025146dd7c4 Mon Sep 17 00:00:00 2001 From: John Boiles Date: Tue, 15 Oct 2013 14:18:33 -0700 Subject: [PATCH 2/2] Adding level metering APIs, similar to those in AVAudioPlayer. --- Audjustable/Classes/AudioPlayer/AudioPlayer.h | 12 ++++ Audjustable/Classes/AudioPlayer/AudioPlayer.m | 55 +++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/Audjustable/Classes/AudioPlayer/AudioPlayer.h b/Audjustable/Classes/AudioPlayer/AudioPlayer.h index 8f2f551..0878321 100644 --- a/Audjustable/Classes/AudioPlayer/AudioPlayer.h +++ b/Audjustable/Classes/AudioPlayer/AudioPlayer.h @@ -172,6 +172,10 @@ AudioQueueBufferRefLookupEntry; volatile BOOL audioQueueFlushing; volatile SInt64 audioPacketsReadCount; volatile SInt64 audioPacketsPlayedCount; + + BOOL meteringEnabled; + AudioQueueLevelMeterState *levelMeterState; + NSInteger numberOfChannels; } @property (readonly) double duration; @@ -179,6 +183,8 @@ AudioQueueBufferRefLookupEntry; @property (readwrite) AudioPlayerState state; @property (readonly) AudioPlayerStopReason stopReason; @property (readwrite, unsafe_unretained) id delegate; +//! Turns level metering on or off. Default is off +@property(getter=isMeteringEnabled) BOOL meteringEnabled; -(id) init; -(id) initWithNumberOfAudioQueueBuffers:(int)numberOfAudioQueueBuffers andReadBufferSize:(int)readBufferSizeIn; @@ -193,5 +199,11 @@ AudioQueueBufferRefLookupEntry; -(void) flushStop; -(void) dispose; -(NSObject*) currentlyPlayingQueueItemId; +//! Call to refresh meter values +- (void) updateMeters; +//! Returns peak power in decibels for a given channel +- (float) peakPowerForChannel:(NSUInteger)channelNumber; +//! Returns average power in decibels for a given channel +- (float) averagePowerForChannel:(NSUInteger)channelNumber; @end diff --git a/Audjustable/Classes/AudioPlayer/AudioPlayer.m b/Audjustable/Classes/AudioPlayer/AudioPlayer.m index cfb035e..170b881 100644 --- a/Audjustable/Classes/AudioPlayer/AudioPlayer.m +++ b/Audjustable/Classes/AudioPlayer/AudioPlayer.m @@ -451,6 +451,7 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ free(packetDescs); free(audioQueueBuffer); free(audioQueueBufferLookup); + free(levelMeterState); } -(void) startSystemBackgroundTask @@ -1215,6 +1216,9 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, 1); + // Re set metering enabled in case the user set it before the queue was created + [self setMeteringEnabled:meteringEnabled]; + free(cookieData); } @@ -2169,4 +2173,55 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ return retval; } +#pragma mark Metering + +-(void) setMeteringEnabled:(BOOL)enabled +{ + // If the audioQueue isn't already created, set the property for later + if (!audioQueue) { + meteringEnabled = enabled; + return; + } + UInt32 on = enabled ? 1 : 0; + OSStatus error = AudioQueueSetProperty(audioQueue, kAudioQueueProperty_EnableLevelMetering, &on, sizeof(on)); + if (error) { + meteringEnabled = NO; + } else { + meteringEnabled = YES; + } +} + +-(BOOL) isMeteringEnabled +{ + return meteringEnabled; +} + +-(void) updateMeters +{ + if (!meteringEnabled) NSAssert(NO, @"Metering is not enabled. Make sure to set meteringEnabled = YES."); + + NSInteger channels = currentAudioStreamBasicDescription.mChannelsPerFrame; + if (numberOfChannels != channels) { + numberOfChannels = channels; + if (levelMeterState) free(levelMeterState); + levelMeterState = malloc(sizeof(AudioQueueLevelMeterState) * numberOfChannels); + } + + UInt32 sizeofMeters = sizeof(AudioQueueLevelMeterState) * numberOfChannels; + + AudioQueueGetProperty(audioQueue, kAudioQueueProperty_CurrentLevelMeterDB, levelMeterState, &sizeofMeters); +} + +-(float) peakPowerForChannel:(NSUInteger)channelNumber +{ + if (!meteringEnabled || !levelMeterState || (channelNumber > numberOfChannels)) return 0; + return levelMeterState[channelNumber].mPeakPower; +} + +-(float) averagePowerForChannel:(NSUInteger)channelNumber +{ + if (!meteringEnabled || !levelMeterState || (channelNumber > numberOfChannels)) return 0; + return levelMeterState[channelNumber].mAveragePower; +} + @end