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
30 //#define SINE_ACCURATE
33 static float sine_44100_1( int o
)
35 float t
= (float)o
*(1.0f
/44100.0f
);
36 return sinf(t
*6.28318530717958647692528676655900576);
39 static void sine_44100_4( int o
[4], float v
[4] )
41 v
[0] = sine_44100_1( o
[0] );
42 v
[1] = sine_44100_1( o
[1] );
43 v
[2] = sine_44100_1( o
[2] );
44 v
[3] = sine_44100_1( o
[3] );
48 /* sine functions over the range [0, 44100] : [-pi, pi].
51 static float sine_44100_1( int o
)
53 float s
= (o
<22050)?-1.0f
:1.0f
;
54 float t
= ((float)o
*(1.0f
/22050.0f
))-1.0f
- s
*0.5f
;
57 return s
*(5.0f
*t2
-4.0f
*t4
-1.0f
);
60 static void sine_44100_4( int o
[4], float v
[4] )
62 float s
[4],t
[4],t2
[4],t4
[4];
63 s
[0] = (o
[0]<22050)?-1.0f
:1.0f
;
64 s
[1] = (o
[1]<22050)?-1.0f
:1.0f
;
65 s
[2] = (o
[2]<22050)?-1.0f
:1.0f
;
66 s
[3] = (o
[3]<22050)?-1.0f
:1.0f
;
68 t
[0] = ((float)o
[0]*(1.0f
/22050.0f
))-1.0f
- s
[0]*0.5f
;
69 t
[1] = ((float)o
[1]*(1.0f
/22050.0f
))-1.0f
- s
[1]*0.5f
;
70 t
[2] = ((float)o
[2]*(1.0f
/22050.0f
))-1.0f
- s
[2]*0.5f
;
71 t
[3] = ((float)o
[3]*(1.0f
/22050.0f
))-1.0f
- s
[3]*0.5f
;
83 v
[0] = s
[0]*(5.0f
*t2
[0]-4.0f
*t4
[0]-1.0f
);
84 v
[1] = s
[1]*(5.0f
*t2
[1]-4.0f
*t4
[1]-1.0f
);
85 v
[2] = s
[2]*(5.0f
*t2
[2]-4.0f
*t4
[2]-1.0f
);
86 v
[3] = s
[3]*(5.0f
*t2
[3]-4.0f
*t4
[3]-1.0f
);
90 static float saw_44100_1( int o
)
92 float t
= ((float)o
*(1.0f
/22050.0f
))-1.0f
,
96 return -2.5f
*ttt
+2.5f
*t
;
99 static double rand_float( double min
, double max
)
101 double r
= (double)(rand()&(4096-1))*(1.0/4096.0);
102 return min
+ r
*(max
-min
);
105 static int rand_seconds( double min
, double max
)
107 return rand_float( min
*44100.0, max
*44100.0 );
110 static void vg_dsp_init( void );
111 static void vg_dsp_process( float *stereo_in
, float *stereo_out
);
118 struct synth_bird_signature
120 float c0
, c1
, c2
, c3
, length
, pause
;
123 fm
; /* lfo modulation depth (+/- hz) */
128 static int birdsynth_pattern_count_signatures( const char *pattern
)
130 /* {200,5000,1000,200,20,10,30,200}, {...} */
134 const char *c
= pattern
;
146 static void birdsynth_pattern_decode( struct synth_bird
*bird
,
147 const char *pattern
)
151 const char *c
= pattern
;
156 struct synth_bird_signature
*sig
= &bird
->pattern
[ bird
->length
++ ];
166 sscanf( c
, "{%f,%f,%f,%f,%f,%f,%d,%d}",
167 &sig
->c0
, &sig
->c1
, &sig
->c2
, &sig
->c3
,
168 &sig
->length
, &sig
->pause
, &sig
->lfo_hz
, &sig
->fm
);
175 static struct synth_bird
*birdsynth_malloc_create( const char *pattern
)
177 int s
= birdsynth_pattern_count_signatures( pattern
);
181 struct synth_bird
*bird
= malloc( sizeof(struct synth_bird
) +
182 s
* sizeof(struct synth_bird_signature
) );
184 birdsynth_pattern_decode( bird
, pattern
);
188 int main( int argc
, char *argv
[] )
192 struct synth_bird
*bird
= birdsynth_malloc_create( "" );
194 int f0
=2500, o1
=0, f1
=30;
199 float c0
=0.0f
, c1
=0.0f
, c2
=0.0f
, c3
=0.0f
; /* signature coefficients */
200 int l
=44100/2, /* length of thing */
201 x
=0, /* frame of thing */
202 a
=0; /* 0: silence 1: signature */
206 for(int _
=0;_
<44100*30;_
++){
208 if( x
>= l
){ /* do new thing */
210 int retrigger
= rand() % 4;
212 if( retrigger
) l
=rand_seconds(0.03,0.1);
213 else l
=rand_seconds(0.5,10.0);
216 c0
=rand_float(-1.0,1.0);
217 c1
=rand_float(-1.0,1.0);
218 c2
=rand_float(-0.1,0.1);
219 c3
=rand_float(-0.5,1.5);
220 l
=rand_seconds(0.05,0.5);
228 if( adsr
> 44100 ) adsr
= 44100;
232 if( adsr
< 0 ) adsr
= 0;
238 float s1
= sine_44100_1( o1
);
240 level
*= (1.0f
/44100.0f
);
244 float t
= ((float)x
* (1.0f
/(float)l
))*2.0f
- 1.0f
,
248 poly
= c0
+t
*c1
+tt
*c2
+ttt
*c3
;
251 int fm
= s1
*100.0f
*(1.0f
+poly
*0.5f
) + poly
*500.0f
;
254 o0
[0] = WRAP1S( o0
[0] + ff
*1 );
255 o0
[1] = WRAP1S( o0
[1] + ff
*2 );
256 o0
[2] = WRAP1S( o0
[2] + ff
*3 );
257 o0
[3] = WRAP1S( o0
[3] + ff
*4 );
260 sine_44100_4( o0
, v
);
267 float stereo
[2] = { s0
, s0
};
268 //vg_dsp_process( stereo, stereo );
270 int16_t l
= stereo
[0] * 10000.0f
,
271 r
= stereo
[1] * 10000.0f
;
273 fwrite( &l
, 2,1, stdout
);
274 fwrite( &r
, 2,1, stdout
);
279 static float dsp_buffer
[(1024*1024)/4];
280 static int dsp_allocations
= 0;
300 static float *dsp_allocate( int l
)
302 float *buf
= &dsp_buffer
[ dsp_allocations
];
303 dsp_allocations
+= l
;
307 static inline void dsp_read_delay( struct dsp_delay
*delay
, float *s
)
309 int index
= delay
->cur
+1;
310 if( index
>= delay
->length
) index
= 0;
311 *s
= delay
->buffer
[ index
];
314 static inline void dsp_write_delay( struct dsp_delay
*delay
, float *s
)
316 int index
= delay
->cur
;
317 delay
->buffer
[ index
] = *s
;
319 if( delay
->cur
>= delay
->length
) delay
->cur
= 0;
322 static void dsp_init_delay( struct dsp_delay
*delay
, float length
)
324 delay
->length
= 44100.0f
* length
;
326 delay
->buffer
= dsp_allocate( delay
->length
);
328 for( int i
=0; i
<delay
->length
; i
++ )
329 delay
->buffer
[i
] = 0.0f
;
332 static void dsp_update_lpf( struct dsp_lpf
*lpf
, float freq
)
334 lpf
->exponent
= 1.0f
-expf( -(1.0f
/44100.0f
) *2.0f
*3.1415926535897f
*freq
);
337 static void dsp_init_lpf( struct dsp_lpf
*lpf
, float freq
)
339 lpf
->buffer
= dsp_allocate( 4 );
340 lpf
->buffer
[0] = 0.0f
;
341 dsp_update_lpf( lpf
, freq
);
344 static inline void dsp_write_lpf( struct dsp_lpf
*lpf
, float *s
)
346 float diff
= *s
- lpf
->buffer
[0];
347 lpf
->buffer
[0] += diff
* lpf
->exponent
;
350 static inline void dsp_read_lpf( struct dsp_lpf
*lpf
, float *s
)
355 static void dsp_init_schroeder( struct dsp_schroeder
*sch
, float length
,
358 dsp_init_delay( &sch
->M
, length
);
362 static inline void dsp_process_schroeder( struct dsp_schroeder
*sch
,
363 float *input
, float *output
)
368 dsp_read_delay( &sch
->M
, &delay_output
);
370 float feedback_attenuated
= delay_output
* sch
->gain
,
371 input_feedback_sum
= dry
+ feedback_attenuated
;
373 dsp_write_delay( &sch
->M
, &input_feedback_sum
);
375 *output
= delay_output
- input_feedback_sum
*sch
->gain
;
378 /* temporary global design */
379 static struct dsp_lpf __lpf_mud_free
;
380 static struct dsp_delay __echos
[8];
381 static struct dsp_lpf __echos_lpf
[8];
382 static struct dsp_schroeder __diffusion_chain
[8];
384 static inline float vg_lerpf( float a
, float b
, float t
)
389 static void vg_dsp_init( void )
391 /* temporary global design */
394 dsp_init_lpf( &__lpf_mud_free
, 125.0f
);
397 { 2.0f
, 4.0f
, 8.0f
, 16.0f
, 32.0f
, 64.0f
, 128.0f
, 256.0f
};
399 float reflection_variance
= 0.1f
;
401 for( int i
=0; i
<8; i
++ )
403 float reflection_time
= ((sizes
[i
])/343.0f
) * 1000.0f
;
405 float var
= 1.0f
+ rand_float(-1.0,1.0) * reflection_variance
,
406 total
= reflection_time
* var
;
408 dsp_init_delay( &__echos
[i
], total
/ 1000.0f
);
410 float freq
= vg_lerpf( 800.0f
, 350.0f
, sizes
[i
] / 256.0f
);
411 dsp_init_lpf( &__echos_lpf
[i
], freq
);
414 float diffusions
[] = { 187.0f
, 159.0f
, 143.0f
, 121.0f
,
415 79.0f
, 57.0f
, 27.0f
, 11.0f
};
417 for( int i
=0; i
<8; i
++ )
419 dsp_init_schroeder( __diffusion_chain
+i
, diffusions
[i
]/1000.0f
, 0.8f
);
423 static void vg_dsp_process( float *stereo_in
, float *stereo_out
)
425 float in_total
= (stereo_in
[0]+stereo_in
[1])*0.5f
;
426 float recieved
= 0.0f
;
428 float echo_tunings
[] = { 0.05f
, 0.05f
, 0.1f
, 0.1f
,
429 0.1f
, 0.1f
, 0.2f
, 0.3f
};
431 for( int i
=0; i
<8; i
++ )
434 dsp_read_delay( __echos
+i
, &echo
);
435 dsp_write_lpf( __echos_lpf
+i
, &echo
);
436 dsp_read_lpf( __echos_lpf
+i
, &echo
);
438 recieved
+= echo
* echo_tunings
[i
]*0.997;
441 float diffused
= recieved
;
443 for( int i
=0; i
<8; i
++ )
445 dsp_process_schroeder( __diffusion_chain
+i
, &diffused
, &diffused
);
448 float total
= in_total
+ (diffused
*0.1f
+ recieved
*0.9f
);
451 dsp_write_lpf( &__lpf_mud_free
, &total
);
452 dsp_read_lpf( &__lpf_mud_free
, &low_mud
);
456 for( int i
=0; i
<8; i
++ )
457 dsp_write_delay( __echos
+i
, &total
);
459 stereo_out
[0] = stereo_in
[0]*0.25f
;
460 stereo_out
[1] = stereo_in
[1]*0.25f
;
461 stereo_out
[0] += diffused
*0.5f
+recieved
*0.9f
;
462 stereo_out
[1] += diffused
*0.5f
+recieved
*0.9f
;