From dbfa6d001b0f28b0121f8e9943d374a675cccfc4 Mon Sep 17 00:00:00 2001 From: Laptop Date: Fri, 26 Jun 2015 15:37:58 -0400 Subject: [PATCH] add recording, etc. hooks. --- RecorderPlugin.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++ hook.c | 100 ++++++++++++++++++++++++++++ hook.h | 18 +++++ 3 files changed, 288 insertions(+) create mode 100644 RecorderPlugin.c create mode 100644 hook.c create mode 100644 hook.h diff --git a/RecorderPlugin.c b/RecorderPlugin.c new file mode 100644 index 0000000..0583ee8 --- /dev/null +++ b/RecorderPlugin.c @@ -0,0 +1,170 @@ +#include "outdrivers.h" +#include +#include +#include +#include +#include +#include "parameters.h" +#include "hook.h" + +struct RecorderPlugin +{ + int is_recording; + int sps; + char In_Filename[PARAM_BUFF]; + char Out_Filename[PARAM_BUFF]; + + int DunBoop; + int BypassLength; + int TimeSinceStart; + + FILE * fRec; + FILE * fPlay; +}; + + +void StopRecording( struct RecorderPlugin * rp ) +{ + if( !rp->is_recording ) return; + + rp->TimeSinceStart = 0; + rp->DunBoop = 0; + fclose( rp->fRec ); + fclose( rp->fPlay ); + rp->is_recording = 0; + rp->fRec = 0; + rp->fPlay = 0; +} + +void StartRecording( struct RecorderPlugin * rp ) +{ + if( rp->is_recording ) return; + + rp->TimeSinceStart = 0; + rp->DunBoop = 0; + rp->is_recording = 1; + + if( rp->In_Filename[0] == 0 ) + { + //Nothing + rp->fPlay = 0; + } + else + { + rp->fPlay = fopen( rp->In_Filename, "rb" ); + if( !rp->fPlay ) + { + fprintf( stderr, "Warning: Could not play filename: %s\n", rp->In_Filename ); + } + } + + if( rp->Out_Filename[0] == 0 ) + { + //Nothing + rp->fRec = 0; + } + else + { + int i; + for( i = 0; i < 999; i++ ) + { + char cts[1024]; + if( i == 0 ) + { + snprintf( cts, 1023, "%s", rp->Out_Filename ); + } + else + { + snprintf( cts, 1023, "%s.%03d", rp->Out_Filename, i ); + } + + rp->fRec = fopen( cts, "wb" ); + if( rp->fRec ) break; + } + } +} + + +static void RecordEvent(void * v, int samples, float * samps, int channel_ct) +{ + struct RecorderPlugin * rp = (struct RecorderPlugin*)v; + if( !rp->fRec || !rp->is_recording ) return; + + if( rp->DunBoop || !rp->fPlay ) + { + int r = fwrite( samps, channel_ct * sizeof( float ), samples, rp->fRec ); + if( r != samples ) + { + StopRecording( rp ); + } + } +} + +static void PlaybackEvent(void * v, int samples, float * samps, int channel_ct) +{ + struct RecorderPlugin * rp = (struct RecorderPlugin*)v; + if( !rp->fPlay ) return; + + if( rp->TimeSinceStart < rp->BypassLength ) + { + int r = fread( samps, channel_ct * sizeof( float ), samples, rp->fPlay ); + if( r != samples ) + { + StopRecording( rp ); + } + + rp->TimeSinceStart += samples; + if( rp->TimeSinceStart > rp->BypassLength ) + { + rp->DunBoop = 1; + } + else + { + int r = fwrite( samps, channel_ct * sizeof( float ), samples, rp->fRec ); + if( r != samples ) + { + StopRecording( rp ); + } + } + } +} + +static void MKeyEvent( void * v, int keycode, int down ) +{ + struct RecorderPlugin * rp = (struct RecorderPlugin*)v; + char c = toupper( keycode ); + if( c == 'R' && down && !rp->is_recording ) StartRecording( rp ); + if( c == 'S' && down && rp->is_recording ) StopRecording( rp ); +} + +static void DPOUpdate(void * id, struct NoteFinder*nf) +{ + //Do nothing, happens every frame. +} + + +static void DPOParams(void * id ) +{ + struct RecorderPlugin * d = (struct RecorderPlugin*)id; + d->sps = 0; RegisterValue( "samplerate", PAINT, &d->sps, sizeof( d->sps ) ); +} + +static struct DriverInstances * RecorderPlugin(const char * parameters) +{ + struct DriverInstances * ret = malloc( sizeof( struct DriverInstances ) ); + struct RecorderPlugin * rp = ret->id = malloc( sizeof( struct RecorderPlugin ) ); + memset( rp, 0, sizeof( struct RecorderPlugin ) ); + ret->Func = DPOUpdate; + ret->Params = DPOParams; + DPOParams( rp ); + + HookKeyEvent( MKeyEvent, rp ); + HookSoundInEvent( RecordEvent, rp, 0 ); + HookSoundInEvent( PlaybackEvent, rp, 1 ); + + return ret; +} + +REGISTER_OUT_DRIVER(RecorderPlugin); + + diff --git a/hook.c b/hook.c new file mode 100644 index 0000000..97c2dbd --- /dev/null +++ b/hook.c @@ -0,0 +1,100 @@ +#include "hook.h" + +struct KeyEvent +{ + void (*KeyE)( void * v, int key, int down ); + void * v; +} KeyEvents[MAX_KEY_EVENTS]; + +void KeyHappened( int key, int down ) +{ + int i; + for( i = 0; i < MAX_KEY_EVENTS; i++ ) + { + if( KeyEvents[i].KeyE ) + KeyEvents[i].KeyE( KeyEvents[i].v, key, down ); + } +} + +void HookKeyEvent( void (*KeyE)( void * v, int key, int down ), void * v ) +{ + int i; + for( i = 0; i < MAX_KEY_EVENTS; i++ ) + { + if( !KeyEvents[i].KeyE ) + { + KeyEvents[i].KeyE = KeyE; + KeyEvents[i].v = v; + } + } +} + +void UnhookKeyEvent( void (*KeyE)( void * v, int key, int down ), void * v ) +{ + int i; + for( i = 0; i < MAX_KEY_EVENTS; i++ ) + { + if( KeyEvents[i].KeyE == KeyE && KeyEvents[i].v == v ) + { + KeyEvents[i].KeyE = 0; + KeyEvents[i].v = 0; + } + } +} + + + + + + + + +struct SoundEvent +{ + void (*SoundE)( void * v, int samples, float * samps, int channel_ct ); + void * v; +}; +struct SoundEvent SoundEvents[2][MAX_SOUND_EVENTS]; + + +void SoundEventHappened( int samples, float * samps, int is_out, int channel_ct ) +{ + int i; + for( i = 0; i < MAX_SOUND_EVENTS; i++ ) + { + if( SoundEvents[is_out][i].SoundE ) + { + printf( "%d\n", i ); + SoundEvents[is_out][i].SoundE( SoundEvents[is_out][i].v, samples, samps, channel_ct ); + } + } +} + +void HookSoundInEvent( void (*SoundE)( void * v, int samples, float * samps, int channel_ct ), void * v, int is_out ) +{ + int i; + for( i = 0; i < MAX_SOUND_EVENTS; i++ ) + { + if( !SoundEvents[is_out][i].SoundE ) + { + SoundEvents[is_out][i].SoundE = SoundE; + SoundEvents[is_out][i].v = v; + } + } +} + +void UnhookSoundInEvent( void (*SoundE)( void * v, int samples, float * samps, int channel_ct ), void * v, int is_out ) +{ + int i; + for( i = 0; i < MAX_SOUND_EVENTS; i++ ) + { + if( SoundEvents[is_out][i].SoundE == SoundE && SoundEvents[is_out][i].v == v ) + { + SoundEvents[is_out][i].SoundE = 0; + SoundEvents[is_out][i].v = 0; + } + } +} + + + diff --git a/hook.h b/hook.h new file mode 100644 index 0000000..ad5199b --- /dev/null +++ b/hook.h @@ -0,0 +1,18 @@ +#ifndef _KEYHOOK_H +#define _KEYHOOK_H + +#define MAX_KEY_EVENTS 16 +#define MAX_SOUND_EVENTS 16 + +void KeyHappened( int key, int down ); +void HookKeyEvent( void (*KeyEvent)( void * v, int key, int down ), void * v ); +void UnhookKeyEvent( void (*KeyEvent)( void * v, int key, int down ), void * v ); + + +void SoundEventHappened( int samples, float * samps, int channel_ct, int is_out ); +void HookSoundInEvent( void (*SoundE)( void * v, int samples, float * samps, int channel_ct ), void * v, int is_out ); +void UnhookSoundInEvent( void (*SoundE)( void * v, int samples, float * samps, int channel_ct ), void * v, int is_out ); + + +#endif +