#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 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);
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];
+ struct synth_bird *bird =
+ synth_bird_create( settings, pattern, pattern_count );
- int frame,length;
- struct synth_bird_signature
- {
- float c0, c1, c2, c3, length, pause;
+ u32 size = synth_bird_save_size( bird );
+ char save[ size*2 ];
+ synth_bird_save( bird, save );
- int lfo_hz,
- fm; /* lfo modulation depth (+/- hz) */
- }
- pattern[];
-};
+ fprintf( fp, "%s:\n%.*s\n\n", name, size*2, save );
+}
-static int birdsynth_pattern_count_signatures( const char *pattern )
-{
- /* {200,5000,1000,200,20,10,30,200}, {...} */
+#define _PROFILE( FP, SETTINGS, ARRAY ) \
+ write_profile( FP, SETTINGS, ARRAY, sizeof(ARRAY)/sizeof(ARRAY[0]), \
+ #ARRAY )
- int signatures = 0;
+static void export_all_profiles(void)
+{
+ FILE *fp = fopen( "bird_profiles.txt", "w" );
- const char *c = pattern;
- while( *c )
- {
- if( *c == '{' )
- signatures ++;
+ 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 );
- return signatures;
+ fclose( fp );
}
-static void birdsynth_pattern_decode( struct synth_bird *bird,
- const char *pattern )
+int main( int argc, char *argv[] )
{
- bird->length = 0;
+ vg_dsp_init();
- const char *c = pattern;
- while( *c )
- {
- if( *c == '{' )
- {
- struct synth_bird_signature *sig = &bird->pattern[ bird->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 = 100;
-
- sscanf( c, "{%f,%f,%f,%f,%f,%f,%d,%d}",
- &sig->c0, &sig->c1, &sig->c2, &sig->c3,
- &sig->length, &sig->pause, &sig->lfo_hz, &sig->fm );
- }
-
- c ++;
- }
-}
+ export_all_profiles();
-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 );
- return bird;
-}
+ 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) );
-int main( int argc, char *argv[] )
-{
- vg_dsp_init();
+ for(;;){
+ float stereo[2] = { 0.0f, 0.0f };
+
+ float b[2];
- struct synth_bird *bird = birdsynth_malloc_create( "" );
-
- int f0=2500, 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;
+ 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] * 14000.0f,
+ r = stereo[1] * 14000.0f;
fwrite( &l, 2,1, stdout );
fwrite( &r, 2,1, stdout );
}
/* 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];
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++ )
{
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 );
}
}
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;
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 );
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;
}