Merge pull request #37 from johnboiles/master

Adding level metering APIs. Adding casts to get rid of Xcode warnings.
This commit is contained in:
Thong Nguyen 2013-10-22 15:17:43 -07:00
commit 062a320de6
3 changed files with 69 additions and 2 deletions

View File

@ -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<AudioPlayerDelegate> delegate;
//! Turns level metering on or off. Default is off
@property(getter=isMeteringEnabled) BOOL meteringEnabled;
-(id) init;
-(id) initWithNumberOfAudioQueueBuffers:(int)numberOfAudioQueueBuffers andReadBufferSize:(int)readBufferSizeIn;
@ -195,5 +201,11 @@ AudioQueueBufferRefLookupEntry;
-(void) unmute;
-(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

View File

@ -451,6 +451,7 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ
free(packetDescs);
free(audioQueueBuffer);
free(audioQueueBufferLookup);
free(levelMeterState);
}
-(void) startSystemBackgroundTask
@ -733,7 +734,7 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ
if (currentlyReadingEntry->processedPacketsSizeTotal < 0xfffff)
{
OSAtomicAdd32(packetSize, &currentlyReadingEntry->processedPacketsSizeTotal);
OSAtomicAdd32((int32_t)packetSize, &currentlyReadingEntry->processedPacketsSizeTotal);
OSAtomicIncrement32(&currentlyReadingEntry->processedPacketsCount);
}
@ -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);
}
@ -2179,4 +2183,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

View File

@ -153,7 +153,7 @@
stream = 0;
relativePosition = 0;
seekStart = offset;
seekStart = (int)offset;
[self open];
[self reregisterForEvents];