simplify
[vg.git] / projects / birds.c
index 09de9f0169a367a4e45c48a35acfdc890fe05d8b..81646be31a03396f387c5b3fce3852376ee54032 100644 (file)
@@ -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
  *
  *
  */
 
-//#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,290 +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
-{
-   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;
-
-      int lfo_hz;
-      float fm;     /* lfo modulation depth (+/- hz) */
-   }
-   pattern[];
-};
-
-static int birdsynth_pattern_count_signatures( const char *pattern )
+static void write_profile( FILE *fp, struct synth_bird_settings *settings,
+                           struct synth_bird_signature *pattern,
+                           u32 pattern_count, const char *name )
 {
-   /*  {200,5000,1000,200,20,10,30,200}, {...} */
+   struct synth_bird *bird = 
+      synth_bird_create( settings, pattern, pattern_count );
 
-   int signatures = 0;
+   u32 size = synth_bird_save_size( bird );
+   char save[ size*2 ];
+   synth_bird_save( bird, save );
 
-   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 )
-{
-   bird->pattern_length = 0;
+#define _PROFILE( FP, SETTINGS, ARRAY ) \
+   write_profile( FP, SETTINGS, ARRAY, sizeof(ARRAY)/sizeof(ARRAY[0]), \
+                  #ARRAY )
 
-   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;
+static void export_all_profiles(void)
+{
+   FILE *fp = fopen( "bird_profiles.txt", "w" );
 
-#if 0
-         sscanf( c, "{%f,%f,%f,%f,%f,%f,%d,%f}",
-                     &sig->c0, &sig->c1, &sig->c2, &sig->c3,
-                     &sig->length, &sig->pause, &sig->lfo_hz, &sig->fm );
-#endif
-      }
+   struct synth_bird_settings *settings = &synth_bird__default_settings;
 
-      c ++;
-   }
-}
+   _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 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;
-}
-
-static void synthbird_generate_samples( struct synth_bird *bird,
-                                        float *stereo_buffer, int samples )
-{
-   for( int _=0; _<samples; _++ )
-   {
-      bird->x ++;
-      if( bird->x >= bird->l )
-      {
-         if( bird->a )
-         {
-            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 -= 40;
-         if( bird->v < 0 ) bird->v = 0;
-      }
-
-      struct synth_bird_signature *sig = &bird->pattern[ bird->frame ];
-
-         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;
-      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*2 );
-      bird->harmonic_4[2] = WRAP1S( bird->harmonic_4[2] + freq*3 );
-      bird->harmonic_4[3] = WRAP1S( bird->harmonic_4[3] + freq*4 );
-
-      float v[4];
-      sine_44100_4( bird->harmonic_4, v );
-      float s = v[0] +
-                v[1] * 0.5f +
-                v[2] * 0.25f +
-                v[3] * 0.125f;
-
-      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 );
+   export_all_profiles();
 
-      int16_t l = stereo[0] * 10000.0f,
-              r = stereo[1] * 10000.0f;
+   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) );
 
-      fwrite( &l, 2,1, stdout );
-      fwrite( &r, 2,1, stdout );
-   }
-#else
+   for(;;){
+      float stereo[2] = { 0.0f, 0.0f };
 
-   struct synth_bird *bird = birdsynth_malloc_create( "" );
+      float b[2];
+
+      synth_bird_generate_samples( warbling_vireo, b, 1 );
+      stereo[0] += b[0];
+      stereo[1] += b[1];
 
-   for(int _=0;_<44100*60;_++){
-      float stereo[2] = { 0.0f, 0.0f };
-      
-      synthbird_generate_samples( bird, stereo, 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
 }
 
 
@@ -498,7 +205,9 @@ static inline void dsp_process_schroeder( struct dsp_schroeder *sch,
 }
 
 /* temporary global design */
-static struct dsp_lpf __lpf_mud_free;
+static struct dsp_lpf __lpf_mud_free,
+                      __hpf_mud_free;
+
 static struct dsp_delay __echos[8];
 static struct dsp_lpf   __echos_lpf[8];
 static struct dsp_schroeder __diffusion_chain[8];
@@ -514,11 +223,12 @@ static void vg_dsp_init( void )
 
 
    dsp_init_lpf( &__lpf_mud_free, 125.0f );
+   dsp_init_lpf( &__hpf_mud_free, 500.0f );
 
    float sizes[] = 
          { 2.0f, 4.0f, 8.0f, 16.0f,   32.0f, 64.0f, 128.0f, 256.0f };
 
-   float reflection_variance = 0.1f;
+   float reflection_variance = 0.04f;
 
    for( int i=0; i<8; i++ )
    {
@@ -538,7 +248,7 @@ static void vg_dsp_init( void )
 
    for( int i=0; i<8; i++ )
    {
-      dsp_init_schroeder( __diffusion_chain+i, diffusions[i]/1000.0f, 0.8f );
+      dsp_init_schroeder( __diffusion_chain+i, diffusions[i]/1000.0f, 0.7f );
    }
 }
 
@@ -557,7 +267,7 @@ static void vg_dsp_process( float *stereo_in, float *stereo_out )
       dsp_write_lpf( __echos_lpf+i, &echo );
       dsp_read_lpf(  __echos_lpf+i, &echo );
 
-      recieved += echo * echo_tunings[i]*0.997;
+      recieved += echo * echo_tunings[i]*0.9;
    }
 
    float diffused = recieved;
@@ -567,7 +277,10 @@ static void vg_dsp_process( float *stereo_in, float *stereo_out )
       dsp_process_schroeder( __diffusion_chain+i, &diffused, &diffused );
    }
 
-   float total = in_total + (diffused*0.1f + recieved*0.9f);
+   float total = in_total + (diffused*0.5f + recieved*0.5f);
+
+   dsp_write_lpf( &__hpf_mud_free, &total );
+   dsp_read_lpf(  &__hpf_mud_free, &total );
 
    float low_mud;
    dsp_write_lpf( &__lpf_mud_free, &total );
@@ -578,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.25f;
-   stereo_out[1]  = stereo_in[1]*0.25f;
-   stereo_out[0] += diffused*0.5f+recieved*0.9f;
-   stereo_out[1] += diffused*0.5f+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;
 }