birds read
authorhgn <hgodden00@gmail.com>
Tue, 14 Mar 2023 04:49:09 +0000 (04:49 +0000)
committerhgn <hgodden00@gmail.com>
Tue, 14 Mar 2023 04:49:09 +0000 (04:49 +0000)
projects/birds [new file with mode: 0755]
projects/birds.c
submodules/SDL

diff --git a/projects/birds b/projects/birds
new file mode 100755 (executable)
index 0000000..339fe0c
Binary files /dev/null and b/projects/birds differ
index 95d9249fb7b677aa24e20028ce81a2bcba787eec..09de9f0169a367a4e45c48a35acfdc890fe05d8b 100644 (file)
@@ -27,6 +27,7 @@
  *
  */
 
+//#define RANDOM_BIRD
 //#define SINE_ACCURATE
 
 #ifdef SINE_ACCURATE
@@ -112,15 +113,18 @@ static void vg_dsp_process( float *stereo_in, float *stereo_out );
 
 struct synth_bird
 {
-   int harmonic_4[4];
+   int harmonic_4[4],
+       fm_oscillator;
+   float poly;
+   int x,a,l,v, frame;
 
-   int frame,length;
+   int pattern_length;
    struct synth_bird_signature
    {
       float c0, c1, c2, c3, length, pause;
 
-      int lfo_hz,
-          fm;     /* lfo modulation depth (+/- hz) */
+      int lfo_hz;
+      float fm;     /* lfo modulation depth (+/- hz) */
    }
    pattern[];
 };
@@ -146,14 +150,16 @@ static int birdsynth_pattern_count_signatures( const char *pattern )
 static void birdsynth_pattern_decode( struct synth_bird *bird, 
                                       const char *pattern )
 {
-   bird->length = 0;
+   bird->pattern_length = 0;
 
    const char *c = pattern;
    while( *c )
    {
       if( *c == '{' )
       {
-         struct synth_bird_signature *sig = &bird->pattern[ bird->length ++ ];
+         struct synth_bird_signature *sig = 
+            &bird->pattern[ bird->pattern_length ++ ];
+         
          sig->c0     =  3000.0f;
          sig->c1     = -800.0f;
          sig->c2     =  1500.0f;
@@ -161,11 +167,13 @@ static void birdsynth_pattern_decode( struct synth_bird *bird,
          sig->length =  0.5f;
          sig->pause  =  0.1f;
          sig->lfo_hz =  30;
-         sig->fm     =  100;
+         sig->fm     =  10.0f;
 
-         sscanf( c, "{%f,%f,%f,%f,%f,%f,%d,%d}",
+#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
       }
 
       c ++;
@@ -180,18 +188,113 @@ static struct synth_bird *birdsynth_malloc_create( const char *pattern )
 
    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;
+   }
+}
+
 int main( int argc, char *argv[] )
 {
    vg_dsp_init();
 
-   struct synth_bird *bird = birdsynth_malloc_create( "" );
-
-   int f0=2500, o1=0, f1=30;
+#if RANDOM_BIRD
+   int f0=4500, o1=0, f1=30;
    int adsr=0;
    
    int o0[4]={0,0,0,0};
@@ -265,7 +368,25 @@ int main( int argc, char *argv[] )
       s0 *= level;
 
       float stereo[2] = { s0, s0 };
-      //vg_dsp_process( stereo, stereo );
+      vg_dsp_process( stereo, stereo );
+
+      int16_t l = stereo[0] * 10000.0f,
+              r = stereo[1] * 10000.0f;
+
+      fwrite( &l, 2,1, stdout );
+      fwrite( &r, 2,1, stdout );
+   }
+#else
+
+   struct synth_bird *bird = birdsynth_malloc_create( "" );
+
+   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;
@@ -273,6 +394,7 @@ int main( int argc, char *argv[] )
       fwrite( &l, 2,1, stdout );
       fwrite( &r, 2,1, stdout );
    }
+#endif
 }
 
 
index eef4d3c86a653f91b7221c80809ba8ab56f94cf1..06492c598158cf825a18aececaf7511d7fd04f48 160000 (submodule)
@@ -1 +1 @@
-Subproject commit eef4d3c86a653f91b7221c80809ba8ab56f94cf1
+Subproject commit 06492c598158cf825a18aececaf7511d7fd04f48