// // AudioSensor.m // Pennyworth // // Created by Chris Karr on 5/21/08. // Copyright 2008 Chris Karr. All rights reserved. // #import "AudioSensor.h" #import "Context.h" #import "SensorsController.h" #define SENSOR_NAME @"Audio Volume" #define MONITOR_AUDIO @"Monitor_Audio" @implementation AudioSensor - (void) awakeFromNib { [[SensorsController sharedController] addSensor:SENSOR_NAME]; volume = 0.0; input = [[MTCoreAudioDevice defaultInputDevice] retain]; [input setDelegate:self]; [input setIOTarget:self withSelector:@selector(ioForDevice:timeStamp:inputData:inputTime:outputData:outputTime:clientData:) withClientData:nil]; [input deviceStart]; started = YES; [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(update:) userInfo:nil repeats:YES] retain]; } - (void) update: (NSTimer *) theTimer { if (![[SensorsController sharedController] canFire:SENSOR_NAME]) { if (started) { [input deviceStop]; started = NO; } NSMutableDictionary * note = [NSMutableDictionary dictionary]; [note setValue:SENSOR_NAME forKey:OBSERVATION_SENSOR]; [[NSNotificationCenter defaultCenter] postNotificationName:OBSERVATION_UPDATE object:self userInfo:note]; return; } else { if (!started) { [input deviceStart]; started = YES; } } NSMutableDictionary * note = [NSMutableDictionary dictionary]; [note setValue:SENSOR_NAME forKey:OBSERVATION_SENSOR]; [note setValue:[NSNumber numberWithInteger:((NSInteger) volume * 10)] forKey:OBSERVATION_OBSERVATION]; [note setValue:[NSNumber numberWithInteger:5] forKey:OBSERVATION_LIFESPAN]; [[NSNotificationCenter defaultCenter] postNotificationName:OBSERVATION_UPDATE object:self userInfo:note]; } - (void) audioDeviceStartDidFail:(MTCoreAudioDevice *) theDevice forReason:(OSStatus) theReason { NSLog (@"error 0x%x", theReason); } - (OSStatus) ioForDevice:(MTCoreAudioDevice *) theDevice timeStamp:(const AudioTimeStamp *) inNow inputData:(const AudioBufferList *) inInputData inputTime:(const AudioTimeStamp *) inInputTime outputData:(AudioBufferList *) outOutputData outputTime:(const AudioTimeStamp *) inOutputTime clientData:(void *) inClientData { unsigned count = inInputData->mBuffers[0].mDataByteSize; unsigned size = sizeof (volume); float sampleRate = 100; float myVolume = 0.0; float * data = inInputData->mBuffers[0].mData; unsigned i = 0; for (i = 0; i < count / size; i++) myVolume += fabsf (data[i]); volume = ((volume * (sampleRate - 1)) + (20 * log10f (myVolume / (count / size)))) / sampleRate; return noErr; } @end