*
*/
+//#define RANDOM_BIRD
//#define SINE_ACCURATE
#ifdef SINE_ACCURATE
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[];
};
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;
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 ++;
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};
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;
fwrite( &l, 2,1, stdout );
fwrite( &r, 2,1, stdout );
}
+#endif
}