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