bad char
[vg.git] / vg_audio_synth_bird.h
index ff6ef50153c1f99a13bf132c624f70fc535a10ad..0a2f418a2ba4d373c5bbaf83e93be5b2e72fd194 100644 (file)
@@ -1,14 +1,11 @@
-#ifndef VG_AUDIO_SYNTH_BIRD_H
-#define VG_AUDIO_SYNTH_BIRD_H
-
-#include "vg_binstr.h"
-#include "vg_stdint.h"
+#pragma once
 
 #ifndef BIRD_SAMPLE_RATE
  #define BIRD_SAMPLE_RATE 44100
 #endif
 
-struct synth_bird_signature{
+struct synth_bird_signature
+{
    float length, pause,  /* timings in seconds */
          x0,x1,x2,x3,    /* polynomial coefficients for the fundemental */
          v0,v1,v2,v3;    /* volume of each oscillator */
@@ -17,7 +14,8 @@ struct synth_bird_signature{
    float fm;             /* LFO modulation depth (+/- hz) */
 };
 
-struct synth_bird{
+struct synth_bird
+{
    struct{
       int osc_main[4],
           osc_lfo;
@@ -54,421 +52,7 @@ struct synth_bird{
    settings;
 };
 
-#define DEFAULT_VOL 1.0f,0.5f,0.2f,0.125f
-#define DEFAULT_TONES { {1,1}, {6,5}, {8,7}, {13,12} }
-#define DEFAULT_RISE 0.00090702947f
-#define DEFAULT_FALL 0.00226757369f
-
-static struct synth_bird_settings synth_bird__default_settings =
-{
-   .tones = DEFAULT_TONES,
-   .type  = k_bird_lfo_sine_approx,
-   .adsr_rise = DEFAULT_RISE,
-   .adsr_fall = DEFAULT_FALL
-};
-
-static struct synth_bird_signature synth_bird__warbling_vireo[] =
-{
-   /* timing    fundemental            volumes       lfo hz,depth */
-   {0.13,0.10,  4000,100,100,0,        DEFAULT_VOL,  60,200 },
-   {0.10,0.05,  4200,-500,1700,0,      DEFAULT_VOL,  60,96  },
-   {0.10,0.00,  2400,-1200,1000,1700,  DEFAULT_VOL,  60,96  },
-   {0.06,0.04,  3100,200,-10,-1100,    DEFAULT_VOL,  60,90  },
-   {0.13,0.07,  4600,-2000,0,1300,     DEFAULT_VOL,  60,10  },
-   {0.05,0.00,  2700,-300,700,800,     DEFAULT_VOL,  60,10  },
-   {0.09,0.07,  3600,-300,0,0,         DEFAULT_VOL,  60,20  },
-   {0.05,0.07,  4800,1240,300,0,       DEFAULT_VOL,  60,20  },
-   {0.08,0.02,  2700,-800,150,1000,    DEFAULT_VOL,  60,160 },
-   {0.12,0.08,  2700,-800,150,1000,    DEFAULT_VOL,  60,160 },
-   {0.10,0.04,  6300,-100,-3200,1000,  DEFAULT_VOL,  60,100 },
-   {0.16,0.10,  4260,-200,300,1100,    DEFAULT_VOL,  60,20  }
-};
-
-static struct synth_bird_signature synth_bird__pied_monarch[] =
-{
-   /* timing    fundemental       volumes        lfo hz,depth */
-   {0.18,0.13,  2200,700,-300,0,  0.6,0.05,0,0,  60,0  },
-   {0.17,0.12,  2200,700,-300,0,  0.8,0.05,0,0,  60,0  },
-   {0.16,0.11,  2200,700,-300,0,  0.9,0.05,0,0,  60,0  },
-   {0.14,0.09,  2200,700,-300,0,  1.0,0.05,0,0,  60,0  },
-   {0.12,0.07,  2200,700,-300,0,  1.0,0.05,0,0,  60,0  },
-   {0.11,0.06,  2200,700,-300,0,  1.0,0.05,0,0,  60,0  },
-   {0.10,0.05,  2200,700,-300,0,  1.0,0.05,0,0,  60,0  },
-   {0.10,0.05,  2200,700,-300,0,  1.0,0.05,0,0,  60,0  },
-   {0.10,0.05,  2200,700,-300,0,  1.0,0.05,0,0,  60,0  },
-   {0.10,0.05,  2200,700,-300,0,  1.0,0.05,0,0,  60,0  },
-   {0.10,0.05,  2200,700,-300,0,  1.0,0.05,0,0,  60,0  },
-   {0.10,0.10,  2200,700,-300,0,  1.0,0.05,0,0,  60,0  }
-};
-
-static struct synth_bird_signature synth_bird__bridled_honeyeater[] =
-{
-   /* timing    fundemental        volumes               lfo hz,depth */
-   {0.10,0.10,  2000,-1000,600,0,  1.00,0.00,0.00,0.00,  30,60},
-   {0.10,0.10,  4000,0,-200,-200,  0.80,0.25,0.25,0.25,  30,60},
-   {0.06,0.01,  4000,0,-700,-800,  0.90,0.10,0.00,0.00,  60,20},
-   {0.07,0.01,  3950,0,-700,-800,  0.90,0.10,0.00,0.00,  60,20},
-   {0.08,0.01,  3900,0,-700,-800,  0.90,0.10,0.00,0.00,  60,20},
-   {0.09,0.01,  3850,0,-700,-800,  0.90,0.10,0.00,0.00,  60,20},
-   {0.10,0.02,  3800,0,-700,-800,  0.90,0.20,0.10,0.00,  60,20},
-   {0.11,0.05,  3750,0,-700,-800,  0.90,0.40,0.20,0.00,  60,20},
-   {0.12,0.20,  3700,0,-700,-800,  0.30,0.10,0.00,0.00,  60,20},
-   {0.10,0.10,  2600,1300,600,0,   0.97,0.03,0.00,0.00,  60,20},
-};
-
-static struct synth_bird_signature synth_bird__cricket[] =
-{
-   /* timing   fundemental   volumes              lfo hz, depth */
-   {0.10,0.15, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
-   {0.11,0.14, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
-   {0.13,0.15, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
-   {0.09,0.16, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
-   {0.10,0.12, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
-   {0.10,0.15, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
-   {0.11,0.14, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
-   {0.13,0.15, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
-   {0.09,0.16, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
-   {0.10,0.12, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200}
-};
-
-static struct synth_bird_signature synth_bird__gray_shrikethrush[] =
-{
-   /* timing   fundemental         volumes             lfo hz, depth */
-   { 0.13,0.1, 2600,-200,-100,200, 0.9,0.1,0.05,0.001, 60,10 }
-};
-
-static struct synth_bird_signature synth_bird__boobook[] =
-{
-   /* timing  fundemental     volumes           lfo hz, depth */
-   {0.3,0.14, 700,0,-100,100, 0.9,0.14,0.0,0.2, 30,18},
-   {0.3,1.20, 630,0,-100,100, 0.9,0.00,0.3,0.0, 30,18}
-};
-
-static struct synth_bird_signature synth_bird__shrike_tit[] =
-{
-   /* timing   fundemental         volumes           lfo hz, depth */
-   {0.6,1.4,   2300,-300,-100,100, 1.0,0.14,0.0,0.1, 60,5 }
-};
-
-/* sine functions over the range [0, 44100] : [-pi, pi].
- * Not accurate! */
-
-static float sine_1second_1( int o )
-{
-   float s = (o<(BIRD_SAMPLE_RATE/2))?-1.0f:1.0f;
-   float t = ((float)o*(1.0f/(float)(BIRD_SAMPLE_RATE/2)))-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_1second_4( int o[4], float v[4] )
-{
-   float s[4],t[4],t2[4],t4[4];
-   s[0] = (o[0]<(BIRD_SAMPLE_RATE/2))?-1.0f:1.0f;
-   s[1] = (o[1]<(BIRD_SAMPLE_RATE/2))?-1.0f:1.0f;
-   s[2] = (o[2]<(BIRD_SAMPLE_RATE/2))?-1.0f:1.0f;
-   s[3] = (o[3]<(BIRD_SAMPLE_RATE/2))?-1.0f:1.0f;
-
-   t[0] = ((float)o[0]*(1.0f/(float)(BIRD_SAMPLE_RATE/2)))-1.0f - s[0]*0.5f;
-   t[1] = ((float)o[1]*(1.0f/(float)(BIRD_SAMPLE_RATE/2)))-1.0f - s[1]*0.5f;
-   t[2] = ((float)o[2]*(1.0f/(float)(BIRD_SAMPLE_RATE/2)))-1.0f - s[2]*0.5f;
-   t[3] = ((float)o[3]*(1.0f/(float)(BIRD_SAMPLE_RATE/2)))-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);
-}
-
-static float saw_1second_1( int o )
-{
-   float t = ((float)o*(1.0f/(float)(BIRD_SAMPLE_RATE/2)))-1.0f,
-         tt = t*t,
-         ttt = tt*t;
-
-   return -2.5f*ttt+2.5f*t;
-}
-
-static u32 synth_bird_get_length_in_samples( struct synth_bird *bird )
-{
-   u32 total = 0;
-
-   for( int i=0; i<bird->settings.pattern_length; i ++ ){
-      struct synth_bird_signature *sig = &bird->settings.pattern[i];
-      
-      u32 l = sig->length * (float)BIRD_SAMPLE_RATE,
-          p = sig->pause  * (float)BIRD_SAMPLE_RATE;
-
-      total += l+p;
-   }
-
-   return total;
-}
-
-static void synth_bird_reset( struct synth_bird *bird )
-{
-   bird->rt.osc_main[0] = 0;
-   bird->rt.osc_main[1] = 0;
-   bird->rt.osc_main[2] = 0;
-   bird->rt.osc_main[3] = 0;
-   bird->rt.osc_lfo = 0;
-
-   bird->rt.volume[0] = 0.0f;
-   bird->rt.volume[1] = 0.0f;
-   bird->rt.volume[2] = 0.0f;
-   bird->rt.volume[3] = 0.0f;
-
-   bird->rt.fundamental = 0.0f;
-   bird->rt.x = 0;
-   bird->rt.length = bird->settings.pattern[0].length * (float)BIRD_SAMPLE_RATE;
-   bird->rt.gate = 1;
-   bird->rt.adsr = 0;
-   bird->rt.frame = 0;
-   bird->rt.lfo_hz = 0;
-   bird->rt.fm_depth = 0.0f;
-
-   bird->rt.adsr_rise = bird->settings.adsr_rise * (float)BIRD_SAMPLE_RATE;
-   bird->rt.adsr_fall = bird->settings.adsr_fall * (float)BIRD_SAMPLE_RATE;
-}
-
-static u32 synth_bird_save_size( struct synth_bird *bird )
-{
-   return sizeof(struct synth_bird_signature) * bird->settings.pattern_length +
-          sizeof(struct synth_bird_settings);
-}
-
-static void synth_bird_save( struct synth_bird *bird, void *txt )
-{
-   void *src = &bird->settings;
-   vg_bin_str( src, txt, synth_bird_save_size( bird ) );
-}
-
-#if 0
-static void synth_bird_load( struct synth_bird *bird, 
-                             const char *txt, u32 length )
-{
-   vg_str_bin( txt, &bird->settings, length );
-   synth_bird_reset( bird );
-}
-
-/* expects a null terminated string */
-static u32 synth_bird_memory_requirement( u32 string_length )
-{
-   return (string_length/2) + 
-            sizeof(struct synth_bird) - sizeof(struct synth_bird_settings);
-}
-#endif
-
-#ifdef SYNTH_BIRD_STDLIB
-#include "stdlib.h"
-#include "string.h"
-
-static struct synth_bird *synth_bird_create(
-                           struct synth_bird_settings *settings,
-                           struct synth_bird_signature *pattern, 
-                           u32 pattern_length )
-{
-   u32 pattern_size = sizeof( struct synth_bird_signature ) * pattern_length;
-   u32 total_size = sizeof( struct synth_bird ) + pattern_size;
-   struct synth_bird *bird = malloc( total_size );
-
-   bird->settings = *settings;
-   
-   memcpy( bird->settings.pattern, pattern, pattern_size );
-   bird->settings.pattern_length = pattern_length;
-
-   synth_bird_reset( bird );
-   return bird;
-}
-
-#endif
-
-static void synth_bird_think( struct synth_bird *bird )
-{
-   struct synth_bird_signature *sig = &bird->settings.pattern[ bird->rt.frame ];
-
-   bird->rt.x ++;
-   if( bird->rt.x >= bird->rt.length )
-   {
-      if( bird->rt.gate && (sig->pause != 0.0f) )
-      {
-         bird->rt.gate = 0;
-         bird->rt.length = sig->pause * (float)BIRD_SAMPLE_RATE;
-      }
-      else
-      {
-         bird->rt.frame ++;
-
-         if( bird->rt.frame >= bird->settings.pattern_length )
-            bird->rt.frame = 0;
-
-         sig = &bird->settings.pattern[ bird->rt.frame ];
-         
-         bird->rt.gate = 1;
-         bird->rt.length = sig->length * (float)BIRD_SAMPLE_RATE;
-      }
-
-      bird->rt.x = 0;
-   }
-
-   if( bird->rt.gate )
-   {
-      bird->rt.adsr += bird->rt.adsr_rise;
-      if( bird->rt.adsr > BIRD_SAMPLE_RATE ) 
-         bird->rt.adsr = BIRD_SAMPLE_RATE;
-   }
-   else
-   {
-      bird->rt.adsr -= bird->rt.adsr_fall;
-      if( bird->rt.adsr < 0 ) 
-         bird->rt.adsr = 0;
-   }
-
-   if( bird->rt.gate )
-   {
-      float l = (float)bird->rt.length,
-            t = ((float)bird->rt.x * (1.0f/l))*2.0f - 1.0f,
-            tt = t*t,
-            ttt = tt*t;
-
-      bird->rt.fundamental = sig->x0 + t*sig->x1 + tt*sig->x2 + ttt*sig->x3;
-   }
-
-   float vol = (float)bird->rt.adsr * (1.0f/(float)BIRD_SAMPLE_RATE);
-
-   bird->rt.fm_depth  = sig->fm;
-   bird->rt.lfo_hz    = sig->lfo_hz;
-   bird->rt.volume[0] = sig->v0 * vol;
-   bird->rt.volume[1] = sig->v1 * vol;
-   bird->rt.volume[2] = sig->v2 * vol;
-   bird->rt.volume[3] = sig->v3 * vol;
-}
-
-static inline void int_add_mod( int *a, int const b )
-{
-   *a += b;
-
-   if( *a > BIRD_SAMPLE_RATE )
-      *a -= BIRD_SAMPLE_RATE;
-}
-
-static void synth_bird_generate_samples( struct synth_bird *bird,
-                                        float *stereo_buffer, int samples )
-{
-   for( int _=0; _<samples; _++ )
-   {
-      synth_bird_think( bird );
-
-      int_add_mod( &bird->rt.osc_lfo, bird->rt.lfo_hz );
-      float fm = sine_1second_1( bird->rt.osc_lfo ) * bird->rt.fm_depth;
-
-      int freq = bird->rt.fundamental + fm;
-      int hz[4] =
-      {
-         (freq * bird->settings.tones[0][0]) / bird->settings.tones[0][1],
-         (freq * bird->settings.tones[1][0]) / bird->settings.tones[1][1],
-         (freq * bird->settings.tones[2][0]) / bird->settings.tones[2][1],
-         (freq * bird->settings.tones[3][0]) / bird->settings.tones[3][1],
-      };
-
-      int_add_mod( bird->rt.osc_main + 0, hz[0] );
-      int_add_mod( bird->rt.osc_main + 1, hz[1] );
-      int_add_mod( bird->rt.osc_main + 2, hz[2] );
-      int_add_mod( bird->rt.osc_main + 3, hz[3] );
-
-      float v[4];
-      sine_1second_4( bird->rt.osc_main, v );
-
-      float s = v[0] * bird->rt.volume[0] +
-                v[1] * bird->rt.volume[1] +
-                v[2] * bird->rt.volume[2] +
-                v[3] * bird->rt.volume[3] ;
-
-      stereo_buffer[ _*2+0 ] = s;
-      stereo_buffer[ _*2+1 ] = s;
-   }
-}
-
-#ifdef SYNTH_BIRD_STDLIB
-#include "stdio.h"
-
-#define KNRM  "\x1B[00m"
-#define KRED  "\x1B[31m"
-#define KGRN  "\x1B[32m"
-#define KYEL  "\x1B[33m"
-#define KBLU  "\x1B[34m"
-#define KMAG  "\x1B[35m"
-#define KCYN  "\x1B[36m"
-#define KWHT  "\x1B[37m"
-
-#define LOG_BAR0 "               .               |"
-#define LOG_BAR1 "-------+-------+-------+-------+"
-#define LOG_BAR2     "                            "
-
-static void synth_bird_log_pattern( struct synth_bird *bird )
-{
-   synth_bird_reset( bird );
-
-   char output[][400]= {
-KNRM "9k-"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KNRM "  -"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KNRM "8k-"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KNRM "  -"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KNRM "7k-"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KNRM "  -"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KMAG "6k-"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KMAG "  -"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KCYN "5k-"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KCYN "  -"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KBLU "4k-"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KBLU "  -"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KGRN "3k-"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KGRN "  -"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KYEL "2k-"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KYEL "  -"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KRED "1k-"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KRED "  -"   LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0      LOG_BAR0,
-KWHT "  +"   LOG_BAR1      LOG_BAR1      LOG_BAR1      LOG_BAR1      LOG_BAR1
-KWHT "  0.0s"LOG_BAR2"0.5s"LOG_BAR2"1.0s"LOG_BAR2"1.5s"LOG_BAR2"2.0s"LOG_BAR2
-   };
-
-   for( int i=0; i<190*8; i++ )
-   {
-      for( int j=0; j<BIRD_SAMPLE_RATE/(32*8*2); j++ )
-         synth_bird_think( bird );
-
-      float hz = bird->rt.fundamental / 500.0f;
-      int j = hz;
-
-      if( j < 0 ) j = 0;
-      if( j > 18 ) j = 18;
-      j = 18-j;
-
-      float level = bird->rt.adsr;
-            level *= (1.0f/(float)BIRD_SAMPLE_RATE);
-
-      int ch = level*3.0f;
-
-      if( ch )
-         output[j][(i/8)+7] = " *###"[ch];
-   }
-
-   for( int i=0; i<20; i++ )
-   {
-      puts( output[i] );
-   }
-}
-#endif
-
-#endif /* VG_AUDIO_SYNTH_BIRD_H */
+void synth_bird_reset( struct synth_bird *bird );
+u32 synth_bird_get_length_in_samples( struct synth_bird *bird );
+void synth_bird_generate_samples( struct synth_bird *bird,
+                                  float *stereo_buffer, int samples );