X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=projects%2Fbirds.c;h=81646be31a03396f387c5b3fce3852376ee54032;hb=e6f73232f1b16af430e850646215d2c9e07dde2e;hp=a015fe65f56c9f3c9636927a1ecb3e412ca0a51f;hpb=3d52e114a0f608e58bc99cfc6faaeb41cfcf84c7;p=vg.git diff --git a/projects/birds.c b/projects/birds.c index a015fe6..81646be 100644 --- a/projects/birds.c +++ b/projects/birds.c @@ -3,16 +3,11 @@ #include "stdlib.h" #include "math.h" -/* Birds sounds - * TODO: THis can be embedded using 'song strings' in the path field of a sound - * entity for skaterift/vg. and the generation algorthm be placed in the - * decode section. will need to find a place to store its memory, though. - * - * */ +#define SYNTH_BIRD_STDLIB +#include "vg_audio_synth_bird.h" #define WRAP1S( X ) (X)%44100 - /* * clang birds.c -lm -o birds && ./birds | aplay -f cd /dev/stdin * @@ -27,76 +22,6 @@ * */ -//#define RANDOM_BIRD -//#define SINE_ACCURATE - -#ifdef SINE_ACCURATE -static float sine_44100_1( int o ) -{ - float t = (float)o*(1.0f/44100.0f); - return sinf(t*6.28318530717958647692528676655900576); -} - -static void sine_44100_4( int o[4], float v[4] ) -{ - v[0] = sine_44100_1( o[0] ); - v[1] = sine_44100_1( o[1] ); - v[2] = sine_44100_1( o[2] ); - v[3] = sine_44100_1( o[3] ); -} -#else - -/* sine functions over the range [0, 44100] : [-pi, pi]. - * Not accurate! */ - -static float sine_44100_1( int o ) -{ - float s = (o<22050)?-1.0f:1.0f; - float t = ((float)o*(1.0f/22050.0f))-1.0f - s*0.5f; - float t2 = t*t; - float t4 = t2*t2; - return s*(5.0f*t2-4.0f*t4-1.0f); -} - -static void sine_44100_4( int o[4], float v[4] ) -{ - float s[4],t[4],t2[4],t4[4]; - s[0] = (o[0]<22050)?-1.0f:1.0f; - s[1] = (o[1]<22050)?-1.0f:1.0f; - s[2] = (o[2]<22050)?-1.0f:1.0f; - s[3] = (o[3]<22050)?-1.0f:1.0f; - - t[0] = ((float)o[0]*(1.0f/22050.0f))-1.0f - s[0]*0.5f; - t[1] = ((float)o[1]*(1.0f/22050.0f))-1.0f - s[1]*0.5f; - t[2] = ((float)o[2]*(1.0f/22050.0f))-1.0f - s[2]*0.5f; - t[3] = ((float)o[3]*(1.0f/22050.0f))-1.0f - s[3]*0.5f; - - t2[0] = t[0]*t[0]; - t2[1] = t[1]*t[1]; - t2[2] = t[2]*t[2]; - t2[3] = t[3]*t[3]; - - t4[0] = t2[0]*t2[0]; - t4[1] = t2[1]*t2[1]; - t4[2] = t2[2]*t2[2]; - t4[3] = t2[3]*t2[3]; - - v[0] = s[0]*(5.0f*t2[0]-4.0f*t4[0]-1.0f); - v[1] = s[1]*(5.0f*t2[1]-4.0f*t4[1]-1.0f); - v[2] = s[2]*(5.0f*t2[2]-4.0f*t4[2]-1.0f); - v[3] = s[3]*(5.0f*t2[3]-4.0f*t4[3]-1.0f); -} -#endif - -static float saw_44100_1( int o ) -{ - float t = ((float)o*(1.0f/22050.0f))-1.0f, - tt = t*t, - ttt = tt*t; - - return -2.5f*ttt+2.5f*t; -} - static double rand_float( double min, double max ) { double r = (double)(rand()&(4096-1))*(1.0/4096.0); @@ -111,338 +36,72 @@ static int rand_seconds( double min, double max ) static void vg_dsp_init( void ); static void vg_dsp_process( float *stereo_in, float *stereo_out ); -struct synth_bird +static void write_profile( FILE *fp, struct synth_bird_settings *settings, + struct synth_bird_signature *pattern, + u32 pattern_count, const char *name ) { - int harmonic_4[4], - fm_oscillator; - - float poly; - int x,a,l,v, frame; - - int pattern_length; - struct synth_bird_signature - { - float c0, c1, c2, c3, length, pause, h0, h1, h2, h3; + struct synth_bird *bird = + synth_bird_create( settings, pattern, pattern_count ); - int lfo_hz; - float fm; /* lfo modulation depth (+/- hz) */ - } - pattern[]; -}; + u32 size = synth_bird_save_size( bird ); + char save[ size*2 ]; + synth_bird_save( bird, save ); -static int birdsynth_pattern_count_signatures( const char *pattern ) -{ - /* {200,5000,1000,200,20,10,30,200}, {...} */ - - int signatures = 0; - - const char *c = pattern; - while( *c ) - { - if( *c == '{' ) - signatures ++; - - c ++; - } - - return signatures; + fprintf( fp, "%s:\n%.*s\n\n", name, size*2, save ); } -static void birdsynth_pattern_decode( struct synth_bird *bird, - const char *pattern ) +#define _PROFILE( FP, SETTINGS, ARRAY ) \ + write_profile( FP, SETTINGS, ARRAY, sizeof(ARRAY)/sizeof(ARRAY[0]), \ + #ARRAY ) + +static void export_all_profiles(void) { - bird->pattern_length = 0; + FILE *fp = fopen( "bird_profiles.txt", "w" ); - const char *c = pattern; - while( *c ) - { - if( *c == '{' ) - { - struct synth_bird_signature *sig = - &bird->pattern[ bird->pattern_length ++ ]; - - sig->c0 = 3000.0f; - sig->c1 = -800.0f; - sig->c2 = 1500.0f; - sig->c3 = -860.0f; - sig->length = 0.5f; - sig->pause = 0.1f; - sig->lfo_hz = 30; - sig->fm = 10.0f; - sig->h0 = 1.0f; - sig->h1 = 0.5f; - sig->h2 = 0.2f; - sig->h3 = 0.125f; - - sscanf( c, "{%f,%f,%f,%f,%d,%f,%f,%f,%f,%f,%f,%f}", - &sig->c0, &sig->c1, &sig->c2, &sig->c3, - &sig->lfo_hz, &sig->fm, &sig->length, &sig->pause, - &sig->h0, &sig->h1, &sig->h2, &sig->h3 ); - } - - c ++; - } -} + struct synth_bird_settings *settings = &synth_bird__default_settings; -static struct synth_bird *birdsynth_malloc_create( const char *pattern ) -{ - int s = birdsynth_pattern_count_signatures( pattern ); - if( s == 0 ) - s = 1; - - struct synth_bird *bird = malloc( sizeof(struct synth_bird) + - s * sizeof(struct synth_bird_signature) ); - - birdsynth_pattern_decode( bird, pattern ); - - bird->harmonic_4[0] = 0; - bird->harmonic_4[1] = 0; - bird->harmonic_4[2] = 0; - bird->harmonic_4[3] = 0; - bird->fm_oscillator = 0; - bird->poly = 0.0f; - bird->x = 0; - bird->a = 1; - bird->l = bird->pattern[0].length * 44100.0f; - bird->v = 0; - bird->frame = 0; - - return bird; -} + _PROFILE( fp, settings, synth_bird__warbling_vireo ); + _PROFILE( fp, settings, synth_bird__pied_monarch ); + _PROFILE( fp, settings, synth_bird__bridled_honeyeater ); + _PROFILE( fp, settings, synth_bird__cricket ); + _PROFILE( fp, settings, synth_bird__gray_shrikethrush ); + _PROFILE( fp, settings, synth_bird__boobook ); + _PROFILE( fp, settings, synth_bird__shrike_tit ); -static void synthbird_generate_samples( struct synth_bird *bird, - float *stereo_buffer, int samples ) -{ - for( int _=0; _x ++; - if( bird->x >= bird->l ) - { - if( bird->a && (bird->pattern[bird->frame].pause!=0.0f) ) - { - bird->a = 0; - bird->l = bird->pattern[ bird->frame ].pause * 44100.0f; - } - else - { - bird->frame ++; - - if( bird->frame >= bird->pattern_length ) - bird->frame = 0; - - bird->a = 1; - bird->l = bird->pattern[ bird->frame ].length * 44100.0f; - } - - bird->x = 0; - } - - if( bird->a ) - { - bird->v += 40; - if( bird->v > 44100 ) bird->v = 44100; - } - else - { - bird->v -= 100; - if( bird->v < 0 ) bird->v = 0; - } - - struct synth_bird_signature *sig = &bird->pattern[ bird->frame ]; - - float level = bird->v; - level *= (1.0f/44100.0f); - - if( bird->a ) - { - float t = ((float)bird->x * (1.0f/(float)bird->l))*2.0f - 1.0f, - tt = t*t, - ttt = tt*t; - - bird->poly = sig->c0 + t*sig->c1 + tt*sig->c2 + ttt*sig->c3; - } - - bird->fm_oscillator = WRAP1S( bird->fm_oscillator + sig->lfo_hz ); - float fm = sine_44100_1( bird->fm_oscillator ) * sig->fm; - - int freq = bird->poly + fm; - bird->harmonic_4[0] = WRAP1S( bird->harmonic_4[0] + (freq*1) ); - bird->harmonic_4[1] = WRAP1S( bird->harmonic_4[1] + (freq*6)/5 ); - bird->harmonic_4[2] = WRAP1S( bird->harmonic_4[2] + (freq*8)/7 ); - bird->harmonic_4[3] = WRAP1S( bird->harmonic_4[3] + (freq*13)/12 ); - - float v[4]; - sine_44100_4( bird->harmonic_4, v ); - float s = v[0] * sig->h0 + - v[1] * sig->h1 + - v[2] * sig->h2 + - v[3] * sig->h3 ; - - s *= level; - - stereo_buffer[ _*2+0 ] = s; - stereo_buffer[ _*2+1 ] = s; - } + fclose( fp ); } int main( int argc, char *argv[] ) { vg_dsp_init(); -#if RANDOM_BIRD - int f0=4500, o1=0, f1=30; - int adsr=0; - - int o0[4]={0,0,0,0}; - - float c0=0.0f, c1=0.0f, c2=0.0f, c3=0.0f; /* signature coefficients */ - int l=44100/2, /* length of thing */ - x=0, /* frame of thing */ - a=0; /* 0: silence 1: signature */ - - float poly=0.0f; - - for(int _=0;_<44100*30;_++){ - x ++; - if( x >= l ){ /* do new thing */ - if( a ){ - int retrigger = rand() % 4; - a=0; - if( retrigger ) l=rand_seconds(0.03,0.1); - else l=rand_seconds(0.5,10.0); - } - else{ - c0=rand_float(-1.0,1.0); - c1=rand_float(-1.0,1.0); - c2=rand_float(-0.1,0.1); - c3=rand_float(-0.5,1.5); - l=rand_seconds(0.05,0.5); - a=1; - } - x=0; - } - - if(a){ - adsr += 40; - if( adsr > 44100 ) adsr = 44100; - } - else{ - adsr -= 40; - if( adsr < 0 ) adsr = 0; - } - - o1 += f1; - o1 = o1 % 44100; - - float s1 = sine_44100_1( o1 ); - float level = adsr; - level *= (1.0f/44100.0f); - - if( a ) - { - float t = ((float)x * (1.0f/(float)l))*2.0f - 1.0f, - tt = t*t, - ttt = tt*t; - - poly = c0+t*c1+tt*c2+ttt*c3; - } - - int fm = s1*100.0f*(1.0f+poly*0.5f) + poly*500.0f; - - int ff = f0+fm; - o0[0] = WRAP1S( o0[0] + ff*1 ); - o0[1] = WRAP1S( o0[1] + ff*2 ); - o0[2] = WRAP1S( o0[2] + ff*3 ); - o0[3] = WRAP1S( o0[3] + ff*4 ); - - float v[4]; - sine_44100_4( o0, v ); - float s0 = v[0] + - v[1] * 0.5f + - v[2] * 0.25f + - v[3] * 0.125f; - s0 *= level; - - float stereo[2] = { s0, s0 }; - vg_dsp_process( stereo, stereo ); - - int16_t l = stereo[0] * 10000.0f, - r = stereo[1] * 10000.0f; + export_all_profiles(); - fwrite( &l, 2,1, stdout ); - fwrite( &r, 2,1, stdout ); - } -#else - - struct synth_bird *warbling_vireo = birdsynth_malloc_create( - "{4000,100,100,0,60,200,0.134,0.1}," /* 1 */ - "{4200,-500,1700,0,60,96,0.1,0.05}," /* 2 */ - "{2400,-1200,1000,1700,60,96,0.1,0.0}," /* 3 */ - "{3100,200,-10,-1100,60,90,0.06,0.04}," /* 4 */ - "{4600,-2000,0,1300,60,10,0.13,0.07}," /* 5 */ - "{2700,-300,700,800,60,10,0.05,0.0}," /* 6 */ - "{3600,-300,0,0,60,20,0.09,0.07}," /* 7 */ - "{4800,1240,300,0,60,20,0.05,0.07}," /* 8 */ - "{2700,-800,150,1000,60,160,0.08,0.02}," /* 9 */ - "{2700,-800,150,1000,60,160,0.12,0.08}," /* 10 */ - "{6300,-100,-3200,1000,60,100,0.1,0.04}," /* 11 */ - "{4260,-200,300,1100,60,20,0.16,3.0}," /* 12 */ - ); - - struct synth_bird *pied_monarch = birdsynth_malloc_create( - "{2200,700,-300,0,60,0,0.18,0.13, 0.6,0.05,0,0}," - "{2200,700,-300,0,60,0,0.17,0.12, 0.8,0.05,0,0}," - "{2200,700,-300,0,60,0,0.16,0.11, 0.9,0.05,0,0}," - "{2200,700,-300,0,60,0,0.14,0.09, 1,0.05,0,0}," - "{2200,700,-300,0,60,0,0.12,0.07, 1,0.05,0,0}," - "{2200,700,-300,0,60,0,0.11,0.06, 1,0.05,0,0}," - "{2200,700,-300,0,60,0,0.10,0.05, 1,0.05,0,0}," - "{2200,700,-300,0,60,0,0.10,0.05, 1,0.05,0,0}," - "{2200,700,-300,0,60,0,0.10,0.05, 1,0.05,0,0}," - "{2200,700,-300,0,60,0,0.10,0.05, 1,0.05,0,0}," - "{2200,700,-300,0,60,0,0.10,0.05, 1,0.05,0,0}," - "{2200,700,-300,0,60,0,0.10,6.05, 1,0.05,0,0}," - ); - - struct synth_bird *bridled_honeyeater = birdsynth_malloc_create( - "{2000,-1000,600,0,30,60,0.1,0.1, 1.0,0.0,0.0,0.0}," - "{4000,0,-200,-200,30,60,0.1,0.1, 0.8,0.25,0.25,0.25}," - "{4000,0,-700,-800,60,20,0.06,0.01, 0.9,0.1,0,0}," - "{3950,0,-700,-800,60,20,0.07,0.01, 0.9,0.1,0,0}," - "{3900,0,-700,-800,60,20,0.08,0.01, 0.9,0.1,0,0}," - "{3850,0,-700,-800,60,20,0.09,0.01, 0.9,0.1,0,0}," - "{3800,0,-700,-800,60,20,0.10,0.02, 0.9,0.2,0.1,0}," - "{3750,0,-700,-800,60,20,0.11,0.05, 0.9,0.4,0.2,0}," - "{3700,0,-700,-800,60,20,0.12,0.2, 0.3,0.1,0,0}," - "{2600,1300,600,0,60,20,0.1,4.0, 0.97,0.03,0,0}," - ); + struct synth_bird *warbling_vireo = + synth_bird_create( &synth_bird__default_settings, + synth_bird__warbling_vireo, + sizeof(synth_bird__warbling_vireo)/ + sizeof(struct synth_bird_signature) ); for(;;){ float stereo[2] = { 0.0f, 0.0f }; float b[2]; - synthbird_generate_samples( pied_monarch, b, 1 ); - stereo[0] += b[0] * 0.4f; - stereo[1] += b[1] * 0.3f; - - synthbird_generate_samples( warbling_vireo, b, 1 ); - stereo[0] += b[0] * 0.5f; - stereo[1] += b[1] * 0.4f; - - synthbird_generate_samples( bridled_honeyeater, b, 1 ); - stereo[0] += b[0] * 0.6f; - stereo[1] += b[1] * 0.6f; + synth_bird_generate_samples( warbling_vireo, b, 1 ); + stereo[0] += b[0]; + stereo[1] += b[1]; +#if 0 vg_dsp_process( stereo, stereo ); +#endif - int16_t l = stereo[0] * 10000.0f, - r = stereo[1] * 10000.0f; + int16_t l = stereo[0] * 14000.0f, + r = stereo[1] * 14000.0f; fwrite( &l, 2,1, stdout ); fwrite( &r, 2,1, stdout ); } -#endif } @@ -632,9 +291,9 @@ static void vg_dsp_process( float *stereo_in, float *stereo_out ) for( int i=0; i<8; i++ ) dsp_write_delay( __echos+i, &total ); - stereo_out[0] = stereo_in[0]*0.1f; - stereo_out[1] = stereo_in[1]*0.1f; - stereo_out[0] += diffused*0.4f+recieved*0.9f; - stereo_out[1] += diffused*0.4f+recieved*0.9f; + stereo_out[0] = stereo_in[0]*0.5f; + stereo_out[1] = stereo_in[1]*0.5f; + stereo_out[0] += diffused*0.8f+recieved*0.9f; + stereo_out[1] += diffused*0.8f+recieved*0.9f; }