7 * TODO: THis can be embedded using 'song strings' in the path field of a sound
8 * entity for skaterift/vg. and the generation algorthm be placed in the
9 * decode section. will need to find a place to store its memory, though.
13 #define WRAP1S( X ) (X)%44100
17 * clang birds.c -lm -o birds && ./birds | aplay -f cd /dev/stdin
19 * Performance measurements: (generate 30seconds audio)
21 * DSP SINE_ACCURATE -O3 x Realtime
31 //#define SINE_ACCURATE
34 static float sine_44100_1( int o
)
36 float t
= (float)o
*(1.0f
/44100.0f
);
37 return sinf(t
*6.28318530717958647692528676655900576);
40 static void sine_44100_4( int o
[4], float v
[4] )
42 v
[0] = sine_44100_1( o
[0] );
43 v
[1] = sine_44100_1( o
[1] );
44 v
[2] = sine_44100_1( o
[2] );
45 v
[3] = sine_44100_1( o
[3] );
49 /* sine functions over the range [0, 44100] : [-pi, pi].
52 static float sine_44100_1( int o
)
54 float s
= (o
<22050)?-1.0f
:1.0f
;
55 float t
= ((float)o
*(1.0f
/22050.0f
))-1.0f
- s
*0.5f
;
58 return s
*(5.0f
*t2
-4.0f
*t4
-1.0f
);
61 static void sine_44100_4( int o
[4], float v
[4] )
63 float s
[4],t
[4],t2
[4],t4
[4];
64 s
[0] = (o
[0]<22050)?-1.0f
:1.0f
;
65 s
[1] = (o
[1]<22050)?-1.0f
:1.0f
;
66 s
[2] = (o
[2]<22050)?-1.0f
:1.0f
;
67 s
[3] = (o
[3]<22050)?-1.0f
:1.0f
;
69 t
[0] = ((float)o
[0]*(1.0f
/22050.0f
))-1.0f
- s
[0]*0.5f
;
70 t
[1] = ((float)o
[1]*(1.0f
/22050.0f
))-1.0f
- s
[1]*0.5f
;
71 t
[2] = ((float)o
[2]*(1.0f
/22050.0f
))-1.0f
- s
[2]*0.5f
;
72 t
[3] = ((float)o
[3]*(1.0f
/22050.0f
))-1.0f
- s
[3]*0.5f
;
84 v
[0] = s
[0]*(5.0f
*t2
[0]-4.0f
*t4
[0]-1.0f
);
85 v
[1] = s
[1]*(5.0f
*t2
[1]-4.0f
*t4
[1]-1.0f
);
86 v
[2] = s
[2]*(5.0f
*t2
[2]-4.0f
*t4
[2]-1.0f
);
87 v
[3] = s
[3]*(5.0f
*t2
[3]-4.0f
*t4
[3]-1.0f
);
91 static float saw_44100_1( int o
)
93 float t
= ((float)o
*(1.0f
/22050.0f
))-1.0f
,
97 return -2.5f
*ttt
+2.5f
*t
;
100 static double rand_float( double min
, double max
)
102 double r
= (double)(rand()&(4096-1))*(1.0/4096.0);
103 return min
+ r
*(max
-min
);
106 static int rand_seconds( double min
, double max
)
108 return rand_float( min
*44100.0, max
*44100.0 );
111 static void vg_dsp_init( void );
112 static void vg_dsp_process( float *stereo_in
, float *stereo_out
);
123 struct synth_bird_signature
125 float c0
, c1
, c2
, c3
, length
, pause
, h0
, h1
, h2
, h3
;
128 float fm
; /* lfo modulation depth (+/- hz) */
133 static int birdsynth_pattern_count_signatures( const char *pattern
)
135 /* {200,5000,1000,200,20,10,30,200}, {...} */
139 const char *c
= pattern
;
151 static void birdsynth_pattern_decode( struct synth_bird
*bird
,
152 const char *pattern
)
154 bird
->pattern_length
= 0;
156 const char *c
= pattern
;
161 struct synth_bird_signature
*sig
=
162 &bird
->pattern
[ bird
->pattern_length
++ ];
177 sscanf( c
, "{%f,%f,%f,%f,%d,%f,%f,%f,%f,%f,%f,%f}",
178 &sig
->c0
, &sig
->c1
, &sig
->c2
, &sig
->c3
,
179 &sig
->lfo_hz
, &sig
->fm
, &sig
->length
, &sig
->pause
,
180 &sig
->h0
, &sig
->h1
, &sig
->h2
, &sig
->h3
);
187 static struct synth_bird
*birdsynth_malloc_create( const char *pattern
)
189 int s
= birdsynth_pattern_count_signatures( pattern
);
193 struct synth_bird
*bird
= malloc( sizeof(struct synth_bird
) +
194 s
* sizeof(struct synth_bird_signature
) );
196 birdsynth_pattern_decode( bird
, pattern
);
198 bird
->harmonic_4
[0] = 0;
199 bird
->harmonic_4
[1] = 0;
200 bird
->harmonic_4
[2] = 0;
201 bird
->harmonic_4
[3] = 0;
202 bird
->fm_oscillator
= 0;
206 bird
->l
= bird
->pattern
[0].length
* 44100.0f
;
213 static void synthbird_generate_samples( struct synth_bird
*bird
,
214 float *stereo_buffer
, int samples
)
216 for( int _
=0; _
<samples
; _
++ )
219 if( bird
->x
>= bird
->l
)
221 if( bird
->a
&& (bird
->pattern
[bird
->frame
].pause
!=0.0f
) )
224 bird
->l
= bird
->pattern
[ bird
->frame
].pause
* 44100.0f
;
230 if( bird
->frame
>= bird
->pattern_length
)
234 bird
->l
= bird
->pattern
[ bird
->frame
].length
* 44100.0f
;
243 if( bird
->v
> 44100 ) bird
->v
= 44100;
248 if( bird
->v
< 0 ) bird
->v
= 0;
251 struct synth_bird_signature
*sig
= &bird
->pattern
[ bird
->frame
];
253 float level
= bird
->v
;
254 level
*= (1.0f
/44100.0f
);
258 float t
= ((float)bird
->x
* (1.0f
/(float)bird
->l
))*2.0f
- 1.0f
,
262 bird
->poly
= sig
->c0
+ t
*sig
->c1
+ tt
*sig
->c2
+ ttt
*sig
->c3
;
265 bird
->fm_oscillator
= WRAP1S( bird
->fm_oscillator
+ sig
->lfo_hz
);
266 float fm
= sine_44100_1( bird
->fm_oscillator
) * sig
->fm
;
268 int freq
= bird
->poly
+ fm
;
269 bird
->harmonic_4
[0] = WRAP1S( bird
->harmonic_4
[0] + (freq
*1) );
270 bird
->harmonic_4
[1] = WRAP1S( bird
->harmonic_4
[1] + (freq
*6)/5 );
271 bird
->harmonic_4
[2] = WRAP1S( bird
->harmonic_4
[2] + (freq
*8)/7 );
272 bird
->harmonic_4
[3] = WRAP1S( bird
->harmonic_4
[3] + (freq
*13)/12 );
275 sine_44100_4( bird
->harmonic_4
, v
);
276 float s
= v
[0] * sig
->h0
+
283 stereo_buffer
[ _
*2+0 ] = s
;
284 stereo_buffer
[ _
*2+1 ] = s
;
288 int main( int argc
, char *argv
[] )
293 int f0
=4500, o1
=0, f1
=30;
298 float c0
=0.0f
, c1
=0.0f
, c2
=0.0f
, c3
=0.0f
; /* signature coefficients */
299 int l
=44100/2, /* length of thing */
300 x
=0, /* frame of thing */
301 a
=0; /* 0: silence 1: signature */
305 for(int _
=0;_
<44100*30;_
++){
307 if( x
>= l
){ /* do new thing */
309 int retrigger
= rand() % 4;
311 if( retrigger
) l
=rand_seconds(0.03,0.1);
312 else l
=rand_seconds(0.5,10.0);
315 c0
=rand_float(-1.0,1.0);
316 c1
=rand_float(-1.0,1.0);
317 c2
=rand_float(-0.1,0.1);
318 c3
=rand_float(-0.5,1.5);
319 l
=rand_seconds(0.05,0.5);
327 if( adsr
> 44100 ) adsr
= 44100;
331 if( adsr
< 0 ) adsr
= 0;
337 float s1
= sine_44100_1( o1
);
339 level
*= (1.0f
/44100.0f
);
343 float t
= ((float)x
* (1.0f
/(float)l
))*2.0f
- 1.0f
,
347 poly
= c0
+t
*c1
+tt
*c2
+ttt
*c3
;
350 int fm
= s1
*100.0f
*(1.0f
+poly
*0.5f
) + poly
*500.0f
;
353 o0
[0] = WRAP1S( o0
[0] + ff
*1 );
354 o0
[1] = WRAP1S( o0
[1] + ff
*2 );
355 o0
[2] = WRAP1S( o0
[2] + ff
*3 );
356 o0
[3] = WRAP1S( o0
[3] + ff
*4 );
359 sine_44100_4( o0
, v
);
366 float stereo
[2] = { s0
, s0
};
367 vg_dsp_process( stereo
, stereo
);
369 int16_t l
= stereo
[0] * 10000.0f
,
370 r
= stereo
[1] * 10000.0f
;
372 fwrite( &l
, 2,1, stdout
);
373 fwrite( &r
, 2,1, stdout
);
377 struct synth_bird
*warbling_vireo
= birdsynth_malloc_create(
378 "{4000,100,100,0,60,200,0.134,0.1}," /* 1 */
379 "{4200,-500,1700,0,60,96,0.1,0.05}," /* 2 */
380 "{2400,-1200,1000,1700,60,96,0.1,0.0}," /* 3 */
381 "{3100,200,-10,-1100,60,90,0.06,0.04}," /* 4 */
382 "{4600,-2000,0,1300,60,10,0.13,0.07}," /* 5 */
383 "{2700,-300,700,800,60,10,0.05,0.0}," /* 6 */
384 "{3600,-300,0,0,60,20,0.09,0.07}," /* 7 */
385 "{4800,1240,300,0,60,20,0.05,0.07}," /* 8 */
386 "{2700,-800,150,1000,60,160,0.08,0.02}," /* 9 */
387 "{2700,-800,150,1000,60,160,0.12,0.08}," /* 10 */
388 "{6300,-100,-3200,1000,60,100,0.1,0.04}," /* 11 */
389 "{4260,-200,300,1100,60,20,0.16,3.0}," /* 12 */
392 struct synth_bird
*pied_monarch
= birdsynth_malloc_create(
393 "{2200,700,-300,0,60,0,0.18,0.13, 0.6,0.05,0,0},"
394 "{2200,700,-300,0,60,0,0.17,0.12, 0.8,0.05,0,0},"
395 "{2200,700,-300,0,60,0,0.16,0.11, 0.9,0.05,0,0},"
396 "{2200,700,-300,0,60,0,0.14,0.09, 1,0.05,0,0},"
397 "{2200,700,-300,0,60,0,0.12,0.07, 1,0.05,0,0},"
398 "{2200,700,-300,0,60,0,0.11,0.06, 1,0.05,0,0},"
399 "{2200,700,-300,0,60,0,0.10,0.05, 1,0.05,0,0},"
400 "{2200,700,-300,0,60,0,0.10,0.05, 1,0.05,0,0},"
401 "{2200,700,-300,0,60,0,0.10,0.05, 1,0.05,0,0},"
402 "{2200,700,-300,0,60,0,0.10,0.05, 1,0.05,0,0},"
403 "{2200,700,-300,0,60,0,0.10,0.05, 1,0.05,0,0},"
404 "{2200,700,-300,0,60,0,0.10,6.05, 1,0.05,0,0},"
407 struct synth_bird
*bridled_honeyeater
= birdsynth_malloc_create(
408 "{2000,-1000,600,0,30,60,0.1,0.1, 1.0,0.0,0.0,0.0},"
409 "{4000,0,-200,-200,30,60,0.1,0.1, 0.8,0.25,0.25,0.25},"
410 "{4000,0,-700,-800,60,20,0.06,0.01, 0.9,0.1,0,0},"
411 "{3950,0,-700,-800,60,20,0.07,0.01, 0.9,0.1,0,0},"
412 "{3900,0,-700,-800,60,20,0.08,0.01, 0.9,0.1,0,0},"
413 "{3850,0,-700,-800,60,20,0.09,0.01, 0.9,0.1,0,0},"
414 "{3800,0,-700,-800,60,20,0.10,0.02, 0.9,0.2,0.1,0},"
415 "{3750,0,-700,-800,60,20,0.11,0.05, 0.9,0.4,0.2,0},"
416 "{3700,0,-700,-800,60,20,0.12,0.2, 0.3,0.1,0,0},"
417 "{2600,1300,600,0,60,20,0.1,4.0, 0.97,0.03,0,0},"
421 float stereo
[2] = { 0.0f
, 0.0f
};
424 synthbird_generate_samples( pied_monarch
, b
, 1 );
425 stereo
[0] += b
[0] * 0.4f
;
426 stereo
[1] += b
[1] * 0.3f
;
428 synthbird_generate_samples( warbling_vireo
, b
, 1 );
429 stereo
[0] += b
[0] * 0.5f
;
430 stereo
[1] += b
[1] * 0.4f
;
432 synthbird_generate_samples( bridled_honeyeater
, b
, 1 );
433 stereo
[0] += b
[0] * 0.6f
;
434 stereo
[1] += b
[1] * 0.6f
;
437 vg_dsp_process( stereo
, stereo
);
439 int16_t l
= stereo
[0] * 10000.0f
,
440 r
= stereo
[1] * 10000.0f
;
442 fwrite( &l
, 2,1, stdout
);
443 fwrite( &r
, 2,1, stdout
);
449 static float dsp_buffer
[(1024*1024)/4];
450 static int dsp_allocations
= 0;
470 static float *dsp_allocate( int l
)
472 float *buf
= &dsp_buffer
[ dsp_allocations
];
473 dsp_allocations
+= l
;
477 static inline void dsp_read_delay( struct dsp_delay
*delay
, float *s
)
479 int index
= delay
->cur
+1;
480 if( index
>= delay
->length
) index
= 0;
481 *s
= delay
->buffer
[ index
];
484 static inline void dsp_write_delay( struct dsp_delay
*delay
, float *s
)
486 int index
= delay
->cur
;
487 delay
->buffer
[ index
] = *s
;
489 if( delay
->cur
>= delay
->length
) delay
->cur
= 0;
492 static void dsp_init_delay( struct dsp_delay
*delay
, float length
)
494 delay
->length
= 44100.0f
* length
;
496 delay
->buffer
= dsp_allocate( delay
->length
);
498 for( int i
=0; i
<delay
->length
; i
++ )
499 delay
->buffer
[i
] = 0.0f
;
502 static void dsp_update_lpf( struct dsp_lpf
*lpf
, float freq
)
504 lpf
->exponent
= 1.0f
-expf( -(1.0f
/44100.0f
) *2.0f
*3.1415926535897f
*freq
);
507 static void dsp_init_lpf( struct dsp_lpf
*lpf
, float freq
)
509 lpf
->buffer
= dsp_allocate( 4 );
510 lpf
->buffer
[0] = 0.0f
;
511 dsp_update_lpf( lpf
, freq
);
514 static inline void dsp_write_lpf( struct dsp_lpf
*lpf
, float *s
)
516 float diff
= *s
- lpf
->buffer
[0];
517 lpf
->buffer
[0] += diff
* lpf
->exponent
;
520 static inline void dsp_read_lpf( struct dsp_lpf
*lpf
, float *s
)
525 static void dsp_init_schroeder( struct dsp_schroeder
*sch
, float length
,
528 dsp_init_delay( &sch
->M
, length
);
532 static inline void dsp_process_schroeder( struct dsp_schroeder
*sch
,
533 float *input
, float *output
)
538 dsp_read_delay( &sch
->M
, &delay_output
);
540 float feedback_attenuated
= delay_output
* sch
->gain
,
541 input_feedback_sum
= dry
+ feedback_attenuated
;
543 dsp_write_delay( &sch
->M
, &input_feedback_sum
);
545 *output
= delay_output
- input_feedback_sum
*sch
->gain
;
548 /* temporary global design */
549 static struct dsp_lpf __lpf_mud_free
,
552 static struct dsp_delay __echos
[8];
553 static struct dsp_lpf __echos_lpf
[8];
554 static struct dsp_schroeder __diffusion_chain
[8];
556 static inline float vg_lerpf( float a
, float b
, float t
)
561 static void vg_dsp_init( void )
563 /* temporary global design */
566 dsp_init_lpf( &__lpf_mud_free
, 125.0f
);
567 dsp_init_lpf( &__hpf_mud_free
, 500.0f
);
570 { 2.0f
, 4.0f
, 8.0f
, 16.0f
, 32.0f
, 64.0f
, 128.0f
, 256.0f
};
572 float reflection_variance
= 0.04f
;
574 for( int i
=0; i
<8; i
++ )
576 float reflection_time
= ((sizes
[i
])/343.0f
) * 1000.0f
;
578 float var
= 1.0f
+ rand_float(-1.0,1.0) * reflection_variance
,
579 total
= reflection_time
* var
;
581 dsp_init_delay( &__echos
[i
], total
/ 1000.0f
);
583 float freq
= vg_lerpf( 800.0f
, 350.0f
, sizes
[i
] / 256.0f
);
584 dsp_init_lpf( &__echos_lpf
[i
], freq
);
587 float diffusions
[] = { 187.0f
, 159.0f
, 143.0f
, 121.0f
,
588 79.0f
, 57.0f
, 27.0f
, 11.0f
};
590 for( int i
=0; i
<8; i
++ )
592 dsp_init_schroeder( __diffusion_chain
+i
, diffusions
[i
]/1000.0f
, 0.7f
);
596 static void vg_dsp_process( float *stereo_in
, float *stereo_out
)
598 float in_total
= (stereo_in
[0]+stereo_in
[1])*0.5f
;
599 float recieved
= 0.0f
;
601 float echo_tunings
[] = { 0.05f
, 0.05f
, 0.1f
, 0.1f
,
602 0.1f
, 0.1f
, 0.2f
, 0.3f
};
604 for( int i
=0; i
<8; i
++ )
607 dsp_read_delay( __echos
+i
, &echo
);
608 dsp_write_lpf( __echos_lpf
+i
, &echo
);
609 dsp_read_lpf( __echos_lpf
+i
, &echo
);
611 recieved
+= echo
* echo_tunings
[i
]*0.9;
614 float diffused
= recieved
;
616 for( int i
=0; i
<8; i
++ )
618 dsp_process_schroeder( __diffusion_chain
+i
, &diffused
, &diffused
);
621 float total
= in_total
+ (diffused
*0.5f
+ recieved
*0.5f
);
623 dsp_write_lpf( &__hpf_mud_free
, &total
);
624 dsp_read_lpf( &__hpf_mud_free
, &total
);
627 dsp_write_lpf( &__lpf_mud_free
, &total
);
628 dsp_read_lpf( &__lpf_mud_free
, &low_mud
);
632 for( int i
=0; i
<8; i
++ )
633 dsp_write_delay( __echos
+i
, &total
);
635 stereo_out
[0] = stereo_in
[0]*0.1f
;
636 stereo_out
[1] = stereo_in
[1]*0.1f
;
637 stereo_out
[0] += diffused
*0.4f
+recieved
*0.9f
;
638 stereo_out
[1] += diffused
*0.4f
+recieved
*0.9f
;