diff options
author | Mikkel Krautz <mikkel@krautz.dk> | 2013-11-23 18:10:27 +0400 |
---|---|---|
committer | Mikkel Krautz <mikkel@krautz.dk> | 2013-11-23 18:10:53 +0400 |
commit | e845b28746f819946a88df14e433a5a596984645 (patch) | |
tree | f30e75cc0fb5c8b912f904951abe16fb2029b24c | |
parent | 1b4e604f27ff64f4ade69f6ab9855dec21b69f9c (diff) |
MKAudio: add support for querying the audio mixer for debug info.
-rw-r--r-- | src/MKAudio.m | 4 | ||||
-rw-r--r-- | src/MKAudioOutput.h | 1 | ||||
-rw-r--r-- | src/MKAudioOutput.m | 85 | ||||
-rw-r--r-- | src/MumbleKit/MKAudio.h | 13 |
4 files changed, 103 insertions, 0 deletions
diff --git a/src/MKAudio.m b/src/MKAudio.m index e4fea69..83360a9 100644 --- a/src/MKAudio.m +++ b/src/MKAudio.m @@ -466,4 +466,8 @@ static void MKAudio_UpdateAudioSessionSettings(MKAudio *audio) { return NO; } +- (NSDictionary *) copyAudioOutputMixerDebugInfo { + return [_audioOutput copyMixerInfo]; +} + @end diff --git a/src/MKAudioOutput.h b/src/MKAudioOutput.h index a718dad..eeaa680 100644 --- a/src/MKAudioOutput.h +++ b/src/MKAudioOutput.h @@ -18,5 +18,6 @@ - (void) removeBuffer:(MKAudioOutputUser *)u; - (BOOL) mixFrames: (void *)frames amount:(unsigned int)nframes; - (void) addFrameToBufferWithSession:(NSUInteger)session data:(NSData *)data sequence:(NSUInteger)seq type:(MKUDPMessageType)msgType; +- (NSDictionary *) copyMixerInfo; @end diff --git a/src/MKAudioOutput.m b/src/MKAudioOutput.m index 43387c7..b96ae52 100644 --- a/src/MKAudioOutput.m +++ b/src/MKAudioOutput.m @@ -6,6 +6,7 @@ #import "MKAudioOutput.h" #import "MKAudioOutputSpeech.h" #import "MKAudioOutputUser.h" +#import "MKAudioOutputSidetone.h" #import "MKAudioDevice.h" #import <AudioUnit/AudioUnit.h> @@ -23,6 +24,9 @@ float *_speakerVolume; NSLock *_outputLock; NSMutableDictionary *_outputs; + + NSLock *_mixerInfoLock; + NSDictionary *_mixerInfo; double _cngAmpliScaler; double _cngLastSample; @@ -69,11 +73,20 @@ [_device setupOutput:^BOOL(short *frames, unsigned int nsamp) { return [self mixFrames:frames amount:nsamp]; }]; + + _mixerInfo = [[NSDictionary dictionaryWithObjectsAndKeys: + [NSDate date], @"last-update", + [NSArray array], @"sources", + [NSArray array], @"removed", + nil] retain]; + _mixerInfoLock = [[NSLock alloc] init]; } return self; } - (void) dealloc { + [_mixerInfoLock release]; + [_mixerInfo release]; [_device setupOutput:NULL]; [_device release]; [_outputLock release]; @@ -81,6 +94,46 @@ [super dealloc]; } +- (NSDictionary *) audioOutputDebugDescription:(id)ou { + if ([ou isKindOfClass:[MKAudioOutputSpeech class]]) { + MKAudioOutputSpeech *ous = (MKAudioOutputSpeech *)ou; + + NSString *msgType = nil; + switch ([ous messageType]) { + case UDPVoiceCELTAlphaMessage: + msgType = @"celt-alpha"; + break; + case UDPVoiceCELTBetaMessage: + msgType = @"celt-beta"; + break; + case UDPVoiceSpeexMessage: + msgType = @"speex"; + break; + case UDPVoiceOpusMessage: + msgType = @"opus"; + break; + default: + msgType = @"unknown"; + break; + } + + return [NSDictionary dictionaryWithObjectsAndKeys: + @"user", @"kind", + [NSString stringWithFormat:@"session %lu codec %@", (unsigned long) [ous userSession], msgType], @"identifier", + nil]; + } else if ([ou isKindOfClass:[MKAudioOutputSidetone class]]) { + return [NSDictionary dictionaryWithObjectsAndKeys: + @"sidetone", @"kind", + @"sidetone", @"identifier", + nil]; + } else { + return [NSDictionary dictionaryWithObjectsAndKeys: + @"unknown", @"kind", + @"unknown", @"identifier", + nil]; + } +} + - (BOOL) mixFrames:(void *)frames amount:(unsigned int)nsamp { unsigned int i, s; BOOL retVal = NO; @@ -105,7 +158,31 @@ [mix addObject:[[MKAudio sharedAudio] sidetoneOutput]]; } } + + if (_settings.audioMixerDebug) { + NSMutableDictionary *mixerInfo = [[[NSMutableDictionary alloc] init] autorelease]; + NSMutableArray *sources = [[[NSMutableArray alloc] init] autorelease]; + NSMutableArray *removed = [[[NSMutableArray alloc] init] autorelease]; + for (id ou in mix) { + [sources addObject:[self audioOutputDebugDescription:ou]]; + } + + for (id ou in del) { + [sources addObject:[self audioOutputDebugDescription:ou]]; + } + + + [mixerInfo setObject:[NSDate date] forKey:@"last-update"]; + [mixerInfo setObject:sources forKey:@"sources"]; + [mixerInfo setObject:removed forKey:@"removed"]; + + [_mixerInfoLock lock]; + [_mixerInfo release]; + _mixerInfo = [mixerInfo retain]; + [_mixerInfoLock unlock]; + } + float *mixBuffer = alloca(sizeof(float)*_numChannels*nsamp); memset(mixBuffer, 0, sizeof(float)*_numChannels*nsamp); @@ -204,4 +281,12 @@ [outputUser release]; } +- (NSDictionary *) copyMixerInfo { + NSDictionary *mixerInfoCopy = nil; + [_mixerInfoLock lock]; + mixerInfoCopy = [_mixerInfo copy]; + [_mixerInfoLock unlock]; + return mixerInfoCopy; +} + @end diff --git a/src/MumbleKit/MKAudio.h b/src/MumbleKit/MKAudio.h index 1f8fd42..6b12d24 100644 --- a/src/MumbleKit/MKAudio.h +++ b/src/MumbleKit/MKAudio.h @@ -57,6 +57,7 @@ typedef struct _MKAudioSettings { BOOL preferReceiverOverSpeaker; BOOL opusForceCELTMode; + BOOL audioMixerDebug; } MKAudioSettings; /// @protocol MKAudioDelegate MKAudio.h MumbleKit/MKAudio.h @@ -212,4 +213,16 @@ typedef struct _MKAudioSettings { - (float) speechProbablity; - (float) peakCleanMic; +///---------------------------- +/// @name Audio Mixer Debugging +///---------------------------- + +/// Query the MKAudioOutput module for debugging +/// data from its mixer. +/// +/// If this method is called without enabling the +/// audioMixerDebug flag in MKSettings, the debug +/// info will be mostly empty, but still valid. +- (NSDictionary *) copyAudioOutputMixerDebugInfo; + @end |