#import "MiscTapper.h"
#import <soundkit/soundkit.h>
#import <stdio.h>
#import <objc/objc-runtime.h>

volatile int	tapper_initialized;
volatile int	tapper_suspended;
volatile int	tapper_load;


#define			TAPPER_BUFFER_SIZE		44100
	// buffer size to deliver to stream reading in from microphone
#define 		TAPPER_TAG 				679201341		
	// if this object pauses, try changing this arbitrary tag
#define			TAPPER_REFRESH			.1
	// fraction of a second tapper checks for finished data.



// timed entry procedure for periodically updating

DPSTimedEntryProc tapper_timer
	(DPSTimedEntry teNum,double now, void* the_tapper)
	{
	MiscTapper* temp_tapper=(MiscTapper*) the_tapper;
	[temp_tapper update];
	return (void*) NULL;
	}


@implementation MiscTapper
	
- init
	{
	id returnval;
	if (tapper_initialized) return NULL;
	tapper_initialized=YES;
	returnval=[super init];
	tapper_device=[[NXSoundIn alloc] init];
	tapper_stream=[[NXRecordStream alloc] initOnDevice:tapper_device];
	[tapper_stream activate];
	[tapper_stream setDelegate:self];
	tapper_load=1;
	
	teNum=DPSAddTimedEntry(TAPPER_REFRESH, 
		(DPSTimedEntryProc) tapper_timer,
		(void*) self, (int) NX_RUNMODALTHRESHOLD);
	return returnval;
	}

- suspend:sender
	{
	if (teNum) DPSRemoveTimedEntry(teNum);
	teNum=0;
	[tapper_stream deactivate];
	return self;
	}
	
	
- resume:sender
	{
	if (teNum) DPSRemoveTimedEntry(teNum);
	teNum=DPSAddTimedEntry(TAPPER_REFRESH, 
		(DPSTimedEntryProc) tapper_timer,
		(void*) self, (int) NX_RUNMODALTHRESHOLD);
	[tapper_stream activate];
	return self;
	}


- free
	{
	if (teNum) DPSRemoveTimedEntry(teNum);
	teNum=0;
	[tapper_stream deactivate];
	[tapper_stream free];
	[tapper_device free];
	tapper_initialized=NO;
	return [super free];
	}

- soundStream:sender didRecordData:(void*) data 
	size:(unsigned int) numBytes forBuffer:(int)tag
	{
	vm_deallocate(task_self(),(vm_address_t) data,(vm_size_t) numBytes);
	tapper_load=1;
	return self;
	}
	
	
- update
	{
	if (tapper_load) 
		{
		tapper_load=0;
		[tapper_stream recordSize:TAPPER_BUFFER_SIZE tag:TAPPER_TAG];
		}
	return self;	
	}	
	
@end
