1 #include "vg_audio_synth_bird.h"
4 #define DEFAULT_VOL 1.0f,0.5f,0.2f,0.125f
5 #define DEFAULT_TONES { {1,1}, {6,5}, {8,7}, {13,12} }
6 #define DEFAULT_RISE 0.00090702947f
7 #define DEFAULT_FALL 0.00226757369f
9 static struct synth_bird_settings synth_bird__default_settings
=
11 .tones
= DEFAULT_TONES
,
12 .type
= k_bird_lfo_sine_approx
,
13 .adsr_rise
= DEFAULT_RISE
,
14 .adsr_fall
= DEFAULT_FALL
17 static struct synth_bird_signature synth_bird__warbling_vireo
[] =
19 /* timing fundemental volumes lfo hz,depth */
20 {0.13,0.10, 4000,100,100,0, DEFAULT_VOL
, 60,200 },
21 {0.10,0.05, 4200,-500,1700,0, DEFAULT_VOL
, 60,96 },
22 {0.10,0.00, 2400,-1200,1000,1700, DEFAULT_VOL
, 60,96 },
23 {0.06,0.04, 3100,200,-10,-1100, DEFAULT_VOL
, 60,90 },
24 {0.13,0.07, 4600,-2000,0,1300, DEFAULT_VOL
, 60,10 },
25 {0.05,0.00, 2700,-300,700,800, DEFAULT_VOL
, 60,10 },
26 {0.09,0.07, 3600,-300,0,0, DEFAULT_VOL
, 60,20 },
27 {0.05,0.07, 4800,1240,300,0, DEFAULT_VOL
, 60,20 },
28 {0.08,0.02, 2700,-800,150,1000, DEFAULT_VOL
, 60,160 },
29 {0.12,0.08, 2700,-800,150,1000, DEFAULT_VOL
, 60,160 },
30 {0.10,0.04, 6300,-100,-3200,1000, DEFAULT_VOL
, 60,100 },
31 {0.16,0.10, 4260,-200,300,1100, DEFAULT_VOL
, 60,20 }
34 static struct synth_bird_signature synth_bird__pied_monarch
[] =
36 /* timing fundemental volumes lfo hz,depth */
37 {0.18,0.13, 2200,700,-300,0, 0.6,0.05,0,0, 60,0 },
38 {0.17,0.12, 2200,700,-300,0, 0.8,0.05,0,0, 60,0 },
39 {0.16,0.11, 2200,700,-300,0, 0.9,0.05,0,0, 60,0 },
40 {0.14,0.09, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
41 {0.12,0.07, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
42 {0.11,0.06, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
43 {0.10,0.05, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
44 {0.10,0.05, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
45 {0.10,0.05, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
46 {0.10,0.05, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
47 {0.10,0.05, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 },
48 {0.10,0.10, 2200,700,-300,0, 1.0,0.05,0,0, 60,0 }
51 static struct synth_bird_signature synth_bird__bridled_honeyeater
[] =
53 /* timing fundemental volumes lfo hz,depth */
54 {0.10,0.10, 2000,-1000,600,0, 1.00,0.00,0.00,0.00, 30,60},
55 {0.10,0.10, 4000,0,-200,-200, 0.80,0.25,0.25,0.25, 30,60},
56 {0.06,0.01, 4000,0,-700,-800, 0.90,0.10,0.00,0.00, 60,20},
57 {0.07,0.01, 3950,0,-700,-800, 0.90,0.10,0.00,0.00, 60,20},
58 {0.08,0.01, 3900,0,-700,-800, 0.90,0.10,0.00,0.00, 60,20},
59 {0.09,0.01, 3850,0,-700,-800, 0.90,0.10,0.00,0.00, 60,20},
60 {0.10,0.02, 3800,0,-700,-800, 0.90,0.20,0.10,0.00, 60,20},
61 {0.11,0.05, 3750,0,-700,-800, 0.90,0.40,0.20,0.00, 60,20},
62 {0.12,0.20, 3700,0,-700,-800, 0.30,0.10,0.00,0.00, 60,20},
63 {0.10,0.10, 2600,1300,600,0, 0.97,0.03,0.00,0.00, 60,20},
66 static struct synth_bird_signature synth_bird__cricket
[] =
68 /* timing fundemental volumes lfo hz, depth */
69 {0.10,0.15, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
70 {0.11,0.14, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
71 {0.13,0.15, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
72 {0.09,0.16, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
73 {0.10,0.12, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
74 {0.10,0.15, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
75 {0.11,0.14, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
76 {0.13,0.15, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
77 {0.09,0.16, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200},
78 {0.10,0.12, 5000,0,0,100, 0.25,0.25,0.25,0.25, 40,200}
81 static struct synth_bird_signature synth_bird__gray_shrikethrush
[] =
83 /* timing fundemental volumes lfo hz, depth */
84 { 0.13,0.1, 2600,-200,-100,200, 0.9,0.1,0.05,0.001, 60,10 }
87 static struct synth_bird_signature synth_bird__boobook
[] =
89 /* timing fundemental volumes lfo hz, depth */
90 {0.3,0.14, 700,0,-100,100, 0.9,0.14,0.0,0.2, 30,18},
91 {0.3,1.20, 630,0,-100,100, 0.9,0.00,0.3,0.0, 30,18}
94 static struct synth_bird_signature synth_bird__shrike_tit
[] =
96 /* timing fundemental volumes lfo hz, depth */
97 {0.6,1.4, 2300,-300,-100,100, 1.0,0.14,0.0,0.1, 60,5 }
100 /* sine functions over the range [0, 44100] : [-pi, pi].
103 static float sine_1second_1( int o
)
105 float s
= (o
<(BIRD_SAMPLE_RATE
/2))?-1.0f
:1.0f
;
106 float t
= ((float)o
*(1.0f
/(float)(BIRD_SAMPLE_RATE
/2)))-1.0f
- s
*0.5f
;
109 return s
*(5.0f
*t2
-4.0f
*t4
-1.0f
);
112 static void sine_1second_4( int o
[4], float v
[4] )
114 float s
[4],t
[4],t2
[4],t4
[4];
115 s
[0] = (o
[0]<(BIRD_SAMPLE_RATE
/2))?-1.0f
:1.0f
;
116 s
[1] = (o
[1]<(BIRD_SAMPLE_RATE
/2))?-1.0f
:1.0f
;
117 s
[2] = (o
[2]<(BIRD_SAMPLE_RATE
/2))?-1.0f
:1.0f
;
118 s
[3] = (o
[3]<(BIRD_SAMPLE_RATE
/2))?-1.0f
:1.0f
;
120 t
[0] = ((float)o
[0]*(1.0f
/(float)(BIRD_SAMPLE_RATE
/2)))-1.0f
- s
[0]*0.5f
;
121 t
[1] = ((float)o
[1]*(1.0f
/(float)(BIRD_SAMPLE_RATE
/2)))-1.0f
- s
[1]*0.5f
;
122 t
[2] = ((float)o
[2]*(1.0f
/(float)(BIRD_SAMPLE_RATE
/2)))-1.0f
- s
[2]*0.5f
;
123 t
[3] = ((float)o
[3]*(1.0f
/(float)(BIRD_SAMPLE_RATE
/2)))-1.0f
- s
[3]*0.5f
;
135 v
[0] = s
[0]*(5.0f
*t2
[0]-4.0f
*t4
[0]-1.0f
);
136 v
[1] = s
[1]*(5.0f
*t2
[1]-4.0f
*t4
[1]-1.0f
);
137 v
[2] = s
[2]*(5.0f
*t2
[2]-4.0f
*t4
[2]-1.0f
);
138 v
[3] = s
[3]*(5.0f
*t2
[3]-4.0f
*t4
[3]-1.0f
);
141 static float saw_1second_1( int o
)
143 float t
= ((float)o
*(1.0f
/(float)(BIRD_SAMPLE_RATE
/2)))-1.0f
,
147 return -2.5f
*ttt
+2.5f
*t
;
150 u32
synth_bird_get_length_in_samples( struct synth_bird
*bird
)
154 for( int i
=0; i
<bird
->settings
.pattern_length
; i
++ ){
155 struct synth_bird_signature
*sig
= &bird
->settings
.pattern
[i
];
157 u32 l
= sig
->length
* (float)BIRD_SAMPLE_RATE
,
158 p
= sig
->pause
* (float)BIRD_SAMPLE_RATE
;
166 void synth_bird_reset( struct synth_bird
*bird
)
168 bird
->rt
.osc_main
[0] = 0;
169 bird
->rt
.osc_main
[1] = 0;
170 bird
->rt
.osc_main
[2] = 0;
171 bird
->rt
.osc_main
[3] = 0;
172 bird
->rt
.osc_lfo
= 0;
174 bird
->rt
.volume
[0] = 0.0f
;
175 bird
->rt
.volume
[1] = 0.0f
;
176 bird
->rt
.volume
[2] = 0.0f
;
177 bird
->rt
.volume
[3] = 0.0f
;
179 bird
->rt
.fundamental
= 0.0f
;
181 bird
->rt
.length
= bird
->settings
.pattern
[0].length
* (float)BIRD_SAMPLE_RATE
;
186 bird
->rt
.fm_depth
= 0.0f
;
188 bird
->rt
.adsr_rise
= bird
->settings
.adsr_rise
* (float)BIRD_SAMPLE_RATE
;
189 bird
->rt
.adsr_fall
= bird
->settings
.adsr_fall
* (float)BIRD_SAMPLE_RATE
;
192 static u32
synth_bird_save_size( struct synth_bird
*bird
)
194 return sizeof(struct synth_bird_signature
) * bird
->settings
.pattern_length
+
195 sizeof(struct synth_bird_settings
);
198 static void synth_bird_save( struct synth_bird
*bird
, void *txt
)
200 void *src
= &bird
->settings
;
201 vg_bin_str( src
, txt
, synth_bird_save_size( bird
) );
205 static void synth_bird_load( struct synth_bird
*bird
,
206 const char *txt
, u32 length
)
208 vg_str_bin( txt
, &bird
->settings
, length
);
209 synth_bird_reset( bird
);
212 /* expects a null terminated string */
213 static u32
synth_bird_memory_requirement( u32 string_length
)
215 return (string_length
/2) +
216 sizeof(struct synth_bird
) - sizeof(struct synth_bird_settings
);
220 #ifdef SYNTH_BIRD_STDLIB
224 static struct synth_bird
*synth_bird_create(
225 struct synth_bird_settings
*settings
,
226 struct synth_bird_signature
*pattern
,
229 u32 pattern_size
= sizeof( struct synth_bird_signature
) * pattern_length
;
230 u32 total_size
= sizeof( struct synth_bird
) + pattern_size
;
231 struct synth_bird
*bird
= malloc( total_size
);
233 bird
->settings
= *settings
;
235 memcpy( bird
->settings
.pattern
, pattern
, pattern_size
);
236 bird
->settings
.pattern_length
= pattern_length
;
238 synth_bird_reset( bird
);
244 static void synth_bird_think( struct synth_bird
*bird
)
246 struct synth_bird_signature
*sig
= &bird
->settings
.pattern
[ bird
->rt
.frame
];
249 if( bird
->rt
.x
>= bird
->rt
.length
)
251 if( bird
->rt
.gate
&& (sig
->pause
!= 0.0f
) )
254 bird
->rt
.length
= sig
->pause
* (float)BIRD_SAMPLE_RATE
;
260 if( bird
->rt
.frame
>= bird
->settings
.pattern_length
)
263 sig
= &bird
->settings
.pattern
[ bird
->rt
.frame
];
266 bird
->rt
.length
= sig
->length
* (float)BIRD_SAMPLE_RATE
;
274 bird
->rt
.adsr
+= bird
->rt
.adsr_rise
;
275 if( bird
->rt
.adsr
> BIRD_SAMPLE_RATE
)
276 bird
->rt
.adsr
= BIRD_SAMPLE_RATE
;
280 bird
->rt
.adsr
-= bird
->rt
.adsr_fall
;
281 if( bird
->rt
.adsr
< 0 )
287 float l
= (float)bird
->rt
.length
,
288 t
= ((float)bird
->rt
.x
* (1.0f
/l
))*2.0f
- 1.0f
,
292 bird
->rt
.fundamental
= sig
->x0
+ t
*sig
->x1
+ tt
*sig
->x2
+ ttt
*sig
->x3
;
295 float vol
= (float)bird
->rt
.adsr
* (1.0f
/(float)BIRD_SAMPLE_RATE
);
297 bird
->rt
.fm_depth
= sig
->fm
;
298 bird
->rt
.lfo_hz
= sig
->lfo_hz
;
299 bird
->rt
.volume
[0] = sig
->v0
* vol
;
300 bird
->rt
.volume
[1] = sig
->v1
* vol
;
301 bird
->rt
.volume
[2] = sig
->v2
* vol
;
302 bird
->rt
.volume
[3] = sig
->v3
* vol
;
305 static inline void int_add_mod( int *a
, int const b
)
309 if( *a
> BIRD_SAMPLE_RATE
)
310 *a
-= BIRD_SAMPLE_RATE
;
313 void synth_bird_generate_samples( struct synth_bird
*bird
,
314 float *stereo_buffer
, int samples
)
316 for( int _
=0; _
<samples
; _
++ )
318 synth_bird_think( bird
);
320 int_add_mod( &bird
->rt
.osc_lfo
, bird
->rt
.lfo_hz
);
321 float fm
= sine_1second_1( bird
->rt
.osc_lfo
) * bird
->rt
.fm_depth
;
323 int freq
= bird
->rt
.fundamental
+ fm
;
326 (freq
* bird
->settings
.tones
[0][0]) / bird
->settings
.tones
[0][1],
327 (freq
* bird
->settings
.tones
[1][0]) / bird
->settings
.tones
[1][1],
328 (freq
* bird
->settings
.tones
[2][0]) / bird
->settings
.tones
[2][1],
329 (freq
* bird
->settings
.tones
[3][0]) / bird
->settings
.tones
[3][1],
332 int_add_mod( bird
->rt
.osc_main
+ 0, hz
[0] );
333 int_add_mod( bird
->rt
.osc_main
+ 1, hz
[1] );
334 int_add_mod( bird
->rt
.osc_main
+ 2, hz
[2] );
335 int_add_mod( bird
->rt
.osc_main
+ 3, hz
[3] );
338 sine_1second_4( bird
->rt
.osc_main
, v
);
340 float s
= v
[0] * bird
->rt
.volume
[0] +
341 v
[1] * bird
->rt
.volume
[1] +
342 v
[2] * bird
->rt
.volume
[2] +
343 v
[3] * bird
->rt
.volume
[3] ;
345 stereo_buffer
[ _
*2+0 ] = s
;
346 stereo_buffer
[ _
*2+1 ] = s
;
350 #ifdef SYNTH_BIRD_STDLIB
353 #define KNRM "\x1B[00m"
354 #define KRED "\x1B[31m"
355 #define KGRN "\x1B[32m"
356 #define KYEL "\x1B[33m"
357 #define KBLU "\x1B[34m"
358 #define KMAG "\x1B[35m"
359 #define KCYN "\x1B[36m"
360 #define KWHT "\x1B[37m"
362 #define LOG_BAR0 " . |"
363 #define LOG_BAR1 "-------+-------+-------+-------+"
366 static void synth_bird_log_pattern( struct synth_bird
*bird
)
368 synth_bird_reset( bird
);
370 char output
[][400]= {
371 KNRM
"9k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
372 KNRM
" -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
373 KNRM
"8k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
374 KNRM
" -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
375 KNRM
"7k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
376 KNRM
" -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
377 KMAG
"6k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
378 KMAG
" -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
379 KCYN
"5k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
380 KCYN
" -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
381 KBLU
"4k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
382 KBLU
" -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
383 KGRN
"3k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
384 KGRN
" -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
385 KYEL
"2k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
386 KYEL
" -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
387 KRED
"1k-" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
388 KRED
" -" LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0 LOG_BAR0
,
389 KWHT
" +" LOG_BAR1 LOG_BAR1 LOG_BAR1 LOG_BAR1 LOG_BAR1
390 KWHT
" 0.0s"LOG_BAR2
"0.5s"LOG_BAR2
"1.0s"LOG_BAR2
"1.5s"LOG_BAR2
"2.0s"LOG_BAR2
393 for( int i
=0; i
<190*8; i
++ )
395 for( int j
=0; j
<BIRD_SAMPLE_RATE
/(32*8*2); j
++ )
396 synth_bird_think( bird
);
398 float hz
= bird
->rt
.fundamental
/ 500.0f
;
405 float level
= bird
->rt
.adsr
;
406 level
*= (1.0f
/(float)BIRD_SAMPLE_RATE
);
411 output
[j
][(i
/8)+7] = " *###"[ch
];
414 for( int i
=0; i
<20; i
++ )