+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;
+ }
+}
+