bad char
[vg.git] / vg_audio.c
1 #include "vg_audio.h"
2 #include "vg_audio_dsp.h"
3 #include "vg_platform.h"
4 #include "vg_io.h"
5 #include "vg_m.h"
6 #include "vg_console.h"
7 #include "vg_profiler.h"
8 #include "vg_audio_synth_bird.h"
9 #include "vg_vorbis.h"
10 #include <string.h>
11
12 struct vg_audio_system vg_audio =
13 {
14 .external_global_volume = 1.0f,
15 .dsp_enabled = 1
16 };
17
18 static struct vg_profile
19 _vg_prof_audio_decode = {.mode = k_profile_mode_accum,
20 .name = "[T2] audio_decode()"},
21 _vg_prof_audio_mix = {.mode = k_profile_mode_accum,
22 .name = "[T2] audio_mix()"},
23 _vg_prof_dsp = {.mode = k_profile_mode_accum,
24 .name = "[T2] dsp_process()"},
25 vg_prof_audio_decode,
26 vg_prof_audio_mix,
27 vg_prof_audio_dsp;
28
29 /*
30 * These functions are called from the main thread and used to prevent bad
31 * access. TODO: They should be no-ops in release builds.
32 */
33 static int audio_lock_checker_load(void)
34 {
35 int value;
36 SDL_AtomicLock( &vg_audio.sl_checker );
37 value = vg_audio.sync_locked;
38 SDL_AtomicUnlock( &vg_audio.sl_checker );
39 return value;
40 }
41
42 static void audio_lock_checker_store( int value )
43 {
44 SDL_AtomicLock( &vg_audio.sl_checker );
45 vg_audio.sync_locked = value;
46 SDL_AtomicUnlock( &vg_audio.sl_checker );
47 }
48
49 static void audio_require_lock(void)
50 {
51 if( audio_lock_checker_load() )
52 return;
53
54 vg_error( "Modifying sound effects systems requires locking\n" );
55 abort();
56 }
57
58 void audio_lock(void)
59 {
60 SDL_AtomicLock( &vg_audio.sl_sync );
61 audio_lock_checker_store(1);
62 }
63
64 void audio_unlock(void)
65 {
66 audio_lock_checker_store(0);
67 SDL_AtomicUnlock( &vg_audio.sl_sync );
68 }
69
70 static void audio_mixer_callback( void *user, u8 *stream, int frame_count );
71 void vg_audio_device_init(void)
72 {
73 SDL_AudioSpec spec_desired, spec_got;
74 spec_desired.callback = audio_mixer_callback;
75 spec_desired.channels = 2;
76 spec_desired.format = AUDIO_F32;
77 spec_desired.freq = 44100;
78 spec_desired.padding = 0;
79 spec_desired.samples = AUDIO_FRAME_SIZE;
80 spec_desired.silence = 0;
81 spec_desired.size = 0;
82 spec_desired.userdata = NULL;
83
84 vg_audio.sdl_output_device =
85 SDL_OpenAudioDevice( vg_audio.device_choice.buffer, 0,
86 &spec_desired, &spec_got,0 );
87
88 vg_info( "Start audio device (%u, F32, %u) @%s\n",
89 spec_desired.freq,
90 AUDIO_FRAME_SIZE,
91 vg_audio.device_choice.buffer );
92
93 if( vg_audio.sdl_output_device ){
94 SDL_PauseAudioDevice( vg_audio.sdl_output_device, 0 );
95 vg_success( "Unpaused device %d.\n", vg_audio.sdl_output_device );
96 }
97 else{
98 vg_error(
99 "SDL_OpenAudioDevice failed. Your default audio device must support:\n"
100 " Frequency: 44100 hz\n"
101 " Buffer size: 512\n"
102 " Channels: 2\n"
103 " Format: s16 or f32\n" );
104 }
105 }
106
107 void vg_audio_register(void)
108 {
109 vg_console_reg_var( "debug_audio", &vg_audio.debug_ui,
110 k_var_dtype_i32, VG_VAR_CHEAT );
111 vg_console_reg_var( "debug_dsp", &vg_audio.debug_dsp,
112 k_var_dtype_i32, VG_VAR_CHEAT );
113 vg_console_reg_var( "volume", &vg_audio.external_global_volume,
114 k_var_dtype_f32, VG_VAR_PERSISTENT );
115 vg_console_reg_var( "vg_audio_device", &vg_audio.device_choice,
116 k_var_dtype_str, VG_VAR_PERSISTENT );
117 vg_console_reg_var( "vg_dsp", &vg_audio.dsp_enabled,
118 k_var_dtype_i32, VG_VAR_PERSISTENT );
119 }
120
121 void vg_audio_init(void)
122 {
123 /* allocate memory */
124 /* 32mb fixed */
125 vg_audio.audio_pool =
126 vg_create_linear_allocator( vg_mem.rtmemory, 1024*1024*32,
127 VG_MEMORY_SYSTEM );
128
129 /* fixed */
130 u32 decode_size = AUDIO_DECODE_SIZE * AUDIO_CHANNELS;
131 vg_audio.decode_buffer = vg_linear_alloc( vg_mem.rtmemory, decode_size );
132
133 vg_dsp_init();
134 vg_audio_device_init();
135 }
136
137 void vg_audio_free(void)
138 {
139 vg_dsp_free();
140 SDL_CloseAudioDevice( vg_audio.sdl_output_device );
141 }
142
143 /*
144 * thread 1
145 */
146
147 #define AUDIO_EDIT_VOLUME_SLOPE 0x1
148 #define AUDIO_EDIT_VOLUME 0x2
149 #define AUDIO_EDIT_LFO_PERIOD 0x4
150 #define AUDIO_EDIT_LFO_WAVE 0x8
151 #define AUDIO_EDIT_LFO_ATTACHMENT 0x10
152 #define AUDIO_EDIT_SPACIAL 0x20
153 #define AUDIO_EDIT_OWNERSHIP 0x40
154 #define AUDIO_EDIT_SAMPLING_RATE 0x80
155
156 void audio_channel_init( audio_channel *ch, audio_clip *clip, u32 flags )
157 {
158 audio_require_lock();
159 ch->group = 0;
160 ch->world_id = 0;
161 ch->source = clip;
162 ch->flags = flags;
163 ch->colour = 0x00333333;
164
165 if( (ch->source->flags & AUDIO_FLAG_FORMAT) == k_audio_format_bird )
166 strcpy( ch->name, "[array]" );
167 else if( (ch->source->flags & AUDIO_FLAG_FORMAT) == k_audio_format_gen )
168 strcpy( ch->name, "[program]" );
169 else
170 vg_strncpy( clip->path, ch->name, 32, k_strncpy_always_add_null );
171
172 ch->allocated = 1;
173
174 ch->editable_state.relinquished = 0;
175 ch->editable_state.volume = 1.0f;
176 ch->editable_state.volume_target = 1.0f;
177 ch->editable_state.pan = 0.0f;
178 ch->editable_state.pan_target = 0.0f;
179 ch->editable_state.volume_rate = 0;
180 ch->editable_state.pan_rate = 0;
181 v4_copy((v4f){0.0f,0.0f,0.0f,1.0f},ch->editable_state.spacial_falloff);
182 ch->editable_state.lfo = NULL;
183 ch->editable_state.lfo_amount = 0.0f;
184 ch->editable_state.sampling_rate = 1.0f;
185 ch->editble_state_write_mask = 0x00;
186 }
187
188 void audio_channel_group( audio_channel *ch, u16 group )
189 {
190 audio_require_lock();
191 ch->group = group;
192 ch->colour = (((u32)group * 29986577) & 0x00ffffff) | 0xff000000;
193 }
194
195 void audio_channel_world( audio_channel *ch, u8 world_id )
196 {
197 audio_require_lock();
198 ch->world_id = world_id;
199 }
200
201 audio_channel *audio_get_first_idle_channel(void)
202 {
203 audio_require_lock();
204 for( int i=0; i<AUDIO_CHANNELS; i++ ){
205 audio_channel *ch = &vg_audio.channels[i];
206
207 if( !ch->allocated ){
208 return ch;
209 }
210 }
211
212 return NULL;
213 }
214
215 audio_channel *audio_get_group_idle_channel( u16 group, u32 max_count )
216 {
217 audio_require_lock();
218 u32 count = 0;
219 audio_channel *dest = NULL;
220
221 for( int i=0; i<AUDIO_CHANNELS; i++ ){
222 audio_channel *ch = &vg_audio.channels[i];
223
224 if( ch->allocated ){
225 if( ch->group == group ){
226 count ++;
227 }
228 }
229 else{
230 if( !dest )
231 dest = ch;
232 }
233 }
234
235 if( dest && (count < max_count) ){
236 return dest;
237 }
238
239 return NULL;
240 }
241
242 audio_channel *audio_get_group_first_active_channel( u16 group )
243 {
244 audio_require_lock();
245 for( int i=0; i<AUDIO_CHANNELS; i++ ){
246 audio_channel *ch = &vg_audio.channels[i];
247 if( ch->allocated && (ch->group == group) )
248 return ch;
249 }
250 return NULL;
251 }
252
253 int audio_channel_finished( audio_channel *ch )
254 {
255 audio_require_lock();
256 if( ch->readable_activity == k_channel_activity_end )
257 return 1;
258 else
259 return 0;
260 }
261
262 audio_channel *audio_relinquish_channel( audio_channel *ch )
263 {
264 audio_require_lock();
265 ch->editable_state.relinquished = 1;
266 ch->editble_state_write_mask |= AUDIO_EDIT_OWNERSHIP;
267 return NULL;
268 }
269
270 void audio_channel_slope_volume( audio_channel *ch, f32 length, f32 new_vol )
271 {
272 audio_require_lock();
273 ch->editable_state.volume_target = new_vol;
274 ch->editable_state.volume_rate = length * 44100.0f;
275 ch->editble_state_write_mask |= AUDIO_EDIT_VOLUME_SLOPE;
276 }
277
278 void audio_channel_set_sampling_rate( audio_channel *ch, float rate )
279 {
280 audio_require_lock();
281 ch->editable_state.sampling_rate = rate;
282 ch->editble_state_write_mask |= AUDIO_EDIT_SAMPLING_RATE;
283 }
284
285 void audio_channel_edit_volume( audio_channel *ch, f32 new_vol, int instant )
286 {
287 audio_require_lock();
288 if( instant ){
289 ch->editable_state.volume = new_vol;
290 ch->editble_state_write_mask |= AUDIO_EDIT_VOLUME;
291 }
292 else{
293 audio_channel_slope_volume( ch, 0.05f, new_vol );
294 }
295 }
296
297 audio_channel *audio_channel_fadeout( audio_channel *ch, float length )
298 {
299 audio_require_lock();
300 audio_channel_slope_volume( ch, length, 0.0f );
301 return audio_relinquish_channel( ch );
302 }
303
304 void audio_channel_fadein( audio_channel *ch, float length )
305 {
306 audio_require_lock();
307 audio_channel_edit_volume( ch, 0.0f, 1 );
308 audio_channel_slope_volume( ch, length, 1.0f );
309 }
310
311 audio_channel *audio_channel_crossfade( audio_channel *ch,
312 audio_clip *new_clip,
313 float length, u32 flags )
314 {
315 audio_require_lock();
316 u32 cursor = 0;
317
318 if( ch )
319 ch = audio_channel_fadeout( ch, length );
320
321 audio_channel *replacement = audio_get_first_idle_channel();
322
323 if( replacement ){
324 audio_channel_init( replacement, new_clip, flags );
325 audio_channel_fadein( replacement, length );
326 }
327
328 return replacement;
329 }
330
331 void audio_channel_sidechain_lfo( audio_channel *ch, int lfo_id, f32 amount )
332 {
333 audio_require_lock();
334 ch->editable_state.lfo = &vg_audio.oscillators[ lfo_id ];
335 ch->editable_state.lfo_amount = amount;
336 ch->editble_state_write_mask |= AUDIO_EDIT_LFO_ATTACHMENT;
337 }
338
339 void audio_channel_set_spacial( audio_channel *ch, v3f co, float range )
340 {
341 audio_require_lock();
342 if( ch->flags & AUDIO_FLAG_SPACIAL_3D ){
343 v3_copy( co, ch->editable_state.spacial_falloff );
344
345 if( range == 0.0f )
346 ch->editable_state.spacial_falloff[3] = 1.0f;
347 else
348 ch->editable_state.spacial_falloff[3] = 1.0f/range;
349
350 ch->editble_state_write_mask |= AUDIO_EDIT_SPACIAL;
351 }
352 else{
353 vg_warn( "Tried to set spacialization paramaters for 2D channel (%s)\n",
354 ch->name );
355 }
356 }
357
358 int audio_oneshot_3d( audio_clip *clip, v3f position, f32 range, f32 volume )
359 {
360 audio_require_lock();
361 audio_channel *ch = audio_get_first_idle_channel();
362
363 if( ch )
364 {
365 audio_channel_init( ch, clip, AUDIO_FLAG_SPACIAL_3D );
366 audio_channel_set_spacial( ch, position, range );
367 audio_channel_edit_volume( ch, volume, 1 );
368 audio_relinquish_channel( ch );
369
370 return 1;
371 }
372 else
373 return 0;
374 }
375
376 int audio_oneshot( audio_clip *clip, f32 volume, f32 pan )
377 {
378 audio_require_lock();
379 audio_channel *ch = audio_get_first_idle_channel();
380
381 if( ch )
382 {
383 audio_channel_init( ch, clip, AUDIO_FLAG_NO_DSP );
384 audio_channel_edit_volume( ch, volume, 1 );
385 audio_relinquish_channel( ch );
386
387 return 1;
388 }
389 else
390 return 0;
391 }
392
393 void audio_set_lfo_wave( int id, enum lfo_wave_type type, f32 coefficient )
394 {
395 audio_require_lock();
396 audio_lfo *lfo = &vg_audio.oscillators[ id ];
397 lfo->editable_state.polynomial_coefficient = coefficient;
398 lfo->editable_state.wave_type = type;
399
400 lfo->editble_state_write_mask |= AUDIO_EDIT_LFO_WAVE;
401 }
402
403 void audio_set_lfo_frequency( int id, float freq )
404 {
405 audio_require_lock();
406 audio_lfo *lfo = &vg_audio.oscillators[ id ];
407 lfo->editable_state.period = 44100.0f / freq;
408 lfo->editble_state_write_mask |= AUDIO_EDIT_LFO_PERIOD;
409 }
410
411
412 /*
413 * Committers
414 * -----------------------------------------------------------------------------
415 */
416 int audio_channel_load_source( audio_channel *ch )
417 {
418 u32 format = ch->source->flags & AUDIO_FLAG_FORMAT;
419
420 if( format == k_audio_format_vorbis ){
421 /* Setup vorbis decoder */
422 u32 index = ch - vg_audio.channels;
423
424 u8 *buf = (u8*)vg_audio.decode_buffer,
425 *loc = &buf[AUDIO_DECODE_SIZE*index];
426
427 stb_vorbis_alloc alloc = {
428 .alloc_buffer = (char *)loc,
429 .alloc_buffer_length_in_bytes = AUDIO_DECODE_SIZE
430 };
431
432 int err;
433 stb_vorbis *decoder = stb_vorbis_open_memory(
434 ch->source->data,
435 ch->source->size, &err, &alloc );
436
437 if( !decoder ){
438 vg_error( "stb_vorbis_open_memory failed on '%s' (%d)\n",
439 ch->source->path, err );
440 return 0;
441 }
442 else{
443 ch->source_length = stb_vorbis_stream_length_in_samples( decoder );
444 ch->handle.vorbis = decoder;
445 }
446 }
447 else if( format == k_audio_format_bird ){
448 u32 index = ch - vg_audio.channels;
449
450 u8 *buf = (u8*)vg_audio.decode_buffer;
451 struct synth_bird *loc = (void *)&buf[AUDIO_DECODE_SIZE*index];
452
453 memcpy( loc, ch->source->data, ch->source->size );
454 synth_bird_reset( loc );
455
456 ch->handle.bird = loc;
457 ch->source_length = synth_bird_get_length_in_samples( loc );
458 }
459 else if( format == k_audio_format_stereo ){
460 ch->source_length = ch->source->size / 2;
461 }
462 else if( format == k_audio_format_gen ){
463 ch->source_length = 0xffffffff;
464 }
465 else{
466 ch->source_length = ch->source->size;
467 }
468
469 return 1;
470 }
471
472 static void audio_decode_uncompressed_mono( i16 *src, u32 count, float *dst )
473 {
474 for( u32 i=0; i<count; i++ ){
475 dst[ i*2 + 0 ] = ((float)src[i]) * (1.0f/32767.0f);
476 dst[ i*2 + 1 ] = ((float)src[i]) * (1.0f/32767.0f);
477 }
478 }
479
480 static inline float audio_lfo_pull_sample( audio_lfo *lfo )
481 {
482 lfo->time ++;
483
484 if( lfo->time >= lfo->_.period )
485 lfo->time = 0;
486
487 float t = lfo->time;
488 t /= (float)lfo->_.period;
489
490 if( lfo->_.wave_type == k_lfo_polynomial_bipolar ){
491 /*
492 * #
493 * # #
494 * # #
495 * # #
496 * ### # ###
497 * ## #
498 * # #
499 * # #
500 * ##
501 */
502
503 t *= 2.0f;
504 t -= 1.0f;
505
506 return (( 2.0f * lfo->sqrt_polynomial_coefficient * t ) /
507 /* --------------------------------------- */
508 ( 1.0f + lfo->_.polynomial_coefficient * t*t )
509
510 ) * (1.0f-fabsf(t));
511 }
512 else{
513 return 0.0f;
514 }
515 }
516
517 static void audio_channel_get_samples( audio_channel *ch,
518 u32 count, float *buf )
519 {
520 vg_profile_begin( &_vg_prof_audio_decode );
521
522 u32 remaining = count;
523 u32 buffer_pos = 0;
524
525 u32 format = ch->source->flags & AUDIO_FLAG_FORMAT;
526
527 while( remaining ){
528 u32 samples_this_run = VG_MIN(remaining, ch->source_length - ch->cursor);
529 remaining -= samples_this_run;
530
531 float *dst = &buf[ buffer_pos * 2 ];
532
533 if( format == k_audio_format_stereo ){
534 for( int i=0;i<samples_this_run; i++ ){
535 dst[i*2+0] = 0.0f;
536 dst[i*2+1] = 0.0f;
537 }
538 }
539 else if( format == k_audio_format_vorbis ){
540 int read_samples = stb_vorbis_get_samples_float_interleaved_stereo(
541 ch->handle.vorbis,
542 dst,
543 samples_this_run );
544
545 if( read_samples != samples_this_run ){
546 vg_warn( "Invalid samples read (%s)\n", ch->source->path );
547
548 for( int i=0; i<samples_this_run; i++ ){
549 dst[i*2+0] = 0.0f;
550 dst[i*2+1] = 0.0f;
551 }
552 }
553 }
554 else if( format == k_audio_format_bird ){
555 synth_bird_generate_samples( ch->handle.bird, dst, samples_this_run );
556 }
557 else if( format == k_audio_format_gen ){
558 void (*fn)( void *data, f32 *buf, u32 count ) = ch->source->func;
559 fn( ch->source->data, dst, samples_this_run );
560 }
561 else{
562 i16 *src_buffer = ch->source->data,
563 *src = &src_buffer[ch->cursor];
564
565 audio_decode_uncompressed_mono( src, samples_this_run, dst );
566 }
567
568 ch->cursor += samples_this_run;
569 buffer_pos += samples_this_run;
570
571 if( (ch->flags & AUDIO_FLAG_LOOP) && remaining ){
572 if( format == k_audio_format_vorbis )
573 stb_vorbis_seek_start( ch->handle.vorbis );
574 else if( format == k_audio_format_bird )
575 synth_bird_reset( ch->handle.bird );
576
577 ch->cursor = 0;
578 continue;
579 }
580 else
581 break;
582 }
583
584 while( remaining ){
585 buf[ buffer_pos*2 + 0 ] = 0.0f;
586 buf[ buffer_pos*2 + 1 ] = 0.0f;
587 buffer_pos ++;
588
589 remaining --;
590 }
591
592 vg_profile_end( &_vg_prof_audio_decode );
593 }
594
595 static void audio_channel_mix( audio_channel *ch, float *buffer )
596 {
597 float framevol_l = vg_audio.internal_global_volume,
598 framevol_r = vg_audio.internal_global_volume;
599
600 float frame_samplerate = ch->_.sampling_rate;
601
602 if( ch->flags & AUDIO_FLAG_SPACIAL_3D ){
603 v3f delta;
604 v3_sub( ch->_.spacial_falloff, vg_audio.internal_listener_pos, delta );
605
606 float dist = v3_length( delta ),
607 vol = vg_maxf( 0.0f, 1.0f - ch->_.spacial_falloff[3]*dist );
608
609 if( dist <= 0.01f ){
610
611 }
612 else{
613 v3_muls( delta, 1.0f/dist, delta );
614 float pan = v3_dot( vg_audio.internal_listener_ears, delta );
615 vol = powf( vol, 5.0f );
616
617 framevol_l *= (vol * 0.5f) * (1.0f - pan);
618 framevol_r *= (vol * 0.5f) * (1.0f + pan);
619
620 if( !(ch->source->flags & AUDIO_FLAG_NO_DOPPLER) ){
621 const float vs = 323.0f;
622
623 float dv = v3_dot(delta,vg_audio.internal_listener_velocity);
624 float doppler = (vs+dv)/vs;
625 doppler = vg_clampf( doppler, 0.6f, 1.4f );
626
627 if( fabsf(doppler-1.0f) > 0.01f )
628 frame_samplerate *= doppler;
629 }
630 }
631
632 if( !vg_validf( framevol_l ) ||
633 !vg_validf( framevol_r ) ||
634 !vg_validf( frame_samplerate ) ){
635 vg_fatal_error( "Invalid sampling conditions.\n"
636 "This crash is to protect your ears.\n"
637 " channel: %p (%s)\n"
638 " sample_rate: %f\n"
639 " volume: L%f R%f\n"
640 " listener: %.2f %.2f %.2f [%.2f %.2f %.2f]\n",
641 ch, ch->name, frame_samplerate,
642 framevol_l, framevol_r,
643 vg_audio.internal_listener_pos[0],
644 vg_audio.internal_listener_pos[1],
645 vg_audio.internal_listener_pos[2],
646 vg_audio.internal_listener_ears[0],
647 vg_audio.internal_listener_ears[1],
648 vg_audio.internal_listener_ears[2]
649 );
650 }
651 }
652
653 u32 buffer_length = AUDIO_MIX_FRAME_SIZE;
654 if( frame_samplerate != 1.0f ){
655 float l = ceilf( (float)(AUDIO_MIX_FRAME_SIZE) * frame_samplerate );
656 buffer_length = l+1;
657 }
658
659 float pcf[ AUDIO_MIX_FRAME_SIZE * 2 * 2 ];
660
661 audio_channel_get_samples( ch, buffer_length, pcf );
662
663 vg_profile_begin( &_vg_prof_audio_mix );
664
665 float volume_movement = ch->volume_movement;
666 float const fvolume_rate = vg_maxf( 1.0f, ch->_.volume_rate );
667 const float inv_volume_rate = 1.0f/fvolume_rate;
668
669 float volume = ch->_.volume;
670 const float volume_start = ch->volume_movement_start;
671 const float volume_target = ch->_.volume_target;
672
673 for( u32 j=0; j<AUDIO_MIX_FRAME_SIZE; j++ ){
674 volume_movement += 1.0f;
675 float movement_t = volume_movement * inv_volume_rate;
676 movement_t = vg_minf( movement_t, 1.0f );
677 volume = vg_lerpf( volume_start, volume_target, movement_t );
678
679 float vol_norm = volume * volume;
680
681 if( ch->_.lfo )
682 vol_norm *= 1.0f + audio_lfo_pull_sample(ch->_.lfo) * ch->_.lfo_amount;
683
684 float vol_l = vol_norm * framevol_l,
685 vol_r = vol_norm * framevol_r,
686 sample_l,
687 sample_r;
688
689 if( frame_samplerate != 1.0f ){
690 /* absolutely garbage resampling, but it will do
691 */
692
693 float sample_index = frame_samplerate * (float)j;
694 float t = vg_fractf( sample_index );
695
696 u32 i0 = floorf( sample_index ),
697 i1 = i0+1;
698
699 sample_l = pcf[ i0*2+0 ]*(1.0f-t) + pcf[ i1*2+0 ]*t;
700 sample_r = pcf[ i0*2+1 ]*(1.0f-t) + pcf[ i1*2+1 ]*t;
701 }
702 else{
703 sample_l = pcf[ j*2+0 ];
704 sample_r = pcf[ j*2+1 ];
705 }
706
707 buffer[ j*2+0 ] += sample_l * vol_l;
708 buffer[ j*2+1 ] += sample_r * vol_r;
709 }
710
711 ch->volume_movement += AUDIO_MIX_FRAME_SIZE;
712 ch->volume_movement = VG_MIN( ch->volume_movement, ch->_.volume_rate );
713 ch->_.volume = volume;
714
715 vg_profile_end( &_vg_prof_audio_mix );
716 }
717
718 static void audio_mixer_callback( void *user, u8 *stream, int byte_count ){
719 /*
720 * Copy data and move edit flags to commit flags
721 * ------------------------------------------------------------- */
722 audio_lock();
723 int use_dsp = vg_audio.dsp_enabled;
724
725 v3_copy( vg_audio.external_listener_pos, vg_audio.internal_listener_pos );
726 v3_copy( vg_audio.external_listener_ears, vg_audio.internal_listener_ears );
727 v3_copy( vg_audio.external_lister_velocity,
728 vg_audio.internal_listener_velocity );
729 vg_audio.internal_global_volume = vg_audio.external_global_volume;
730
731 for( int i=0; i<AUDIO_CHANNELS; i++ ){
732 audio_channel *ch = &vg_audio.channels[i];
733
734 if( !ch->allocated )
735 continue;
736
737 if( ch->activity == k_channel_activity_alive ){
738 if( (ch->cursor >= ch->source_length) &&
739 !(ch->flags & AUDIO_FLAG_LOOP) )
740 {
741 ch->activity = k_channel_activity_end;
742 }
743 }
744
745 /* process relinquishments */
746 if( (ch->activity != k_channel_activity_reset) && ch->_.relinquished ){
747 if( (ch->activity == k_channel_activity_end)
748 || (ch->_.volume == 0.0f)
749 || (ch->activity == k_channel_activity_error) )
750 {
751 ch->_.relinquished = 0;
752 ch->allocated = 0;
753 ch->activity = k_channel_activity_reset;
754 continue;
755 }
756 }
757
758 /* process new channels */
759 if( ch->activity == k_channel_activity_reset ){
760 ch->_ = ch->editable_state;
761 ch->cursor = 0;
762 ch->source_length = 0;
763 ch->activity = k_channel_activity_wake;
764 }
765
766 if( ch->editble_state_write_mask & AUDIO_EDIT_OWNERSHIP )
767 ch->_.relinquished = ch->editable_state.relinquished;
768 else
769 ch->editable_state.relinquished = ch->_.relinquished;
770
771
772 if( ch->editble_state_write_mask & AUDIO_EDIT_VOLUME ){
773 ch->_.volume = ch->editable_state.volume;
774 ch->_.volume_target = ch->editable_state.volume;
775 }
776 else{
777 ch->editable_state.volume = ch->_.volume;
778 }
779
780
781 if( ch->editble_state_write_mask & AUDIO_EDIT_VOLUME_SLOPE ){
782 ch->volume_movement_start = ch->_.volume;
783 ch->volume_movement = 0;
784
785 ch->_.volume_target = ch->editable_state.volume_target;
786 ch->_.volume_rate = ch->editable_state.volume_rate;
787 }
788 else{
789 ch->editable_state.volume_target = ch->_.volume_target;
790 ch->editable_state.volume_rate = ch->_.volume_rate;
791 }
792
793
794 if( ch->editble_state_write_mask & AUDIO_EDIT_SAMPLING_RATE )
795 ch->_.sampling_rate = ch->editable_state.sampling_rate;
796 else
797 ch->editable_state.sampling_rate = ch->_.sampling_rate;
798
799
800 if( ch->editble_state_write_mask & AUDIO_EDIT_LFO_ATTACHMENT ){
801 ch->_.lfo = ch->editable_state.lfo;
802 ch->_.lfo_amount = ch->editable_state.lfo_amount;
803 }
804 else{
805 ch->editable_state.lfo = ch->_.lfo;
806 ch->editable_state.lfo_amount = ch->_.lfo_amount;
807 }
808
809
810 if( ch->editble_state_write_mask & AUDIO_EDIT_SPACIAL )
811 v4_copy( ch->editable_state.spacial_falloff,ch->_.spacial_falloff );
812 else
813 v4_copy( ch->_.spacial_falloff,ch->editable_state.spacial_falloff );
814
815
816 /* currently readonly, i guess */
817 ch->editable_state.pan_target = ch->_.pan_target;
818 ch->editable_state.pan = ch->_.pan;
819 ch->editble_state_write_mask = 0x00;
820 }
821
822 for( int i=0; i<AUDIO_LFOS; i++ ){
823 audio_lfo *lfo = &vg_audio.oscillators[ i ];
824
825 if( lfo->editble_state_write_mask & AUDIO_EDIT_LFO_WAVE ){
826 lfo->_.wave_type = lfo->editable_state.wave_type;
827
828 if( lfo->_.wave_type == k_lfo_polynomial_bipolar ){
829 lfo->_.polynomial_coefficient =
830 lfo->editable_state.polynomial_coefficient;
831 lfo->sqrt_polynomial_coefficient =
832 sqrtf(lfo->_.polynomial_coefficient);
833 }
834 }
835
836 if( lfo->editble_state_write_mask & AUDIO_EDIT_LFO_PERIOD ){
837 if( lfo->_.period ){
838 float t = lfo->time;
839 t/= (float)lfo->_.period;
840
841 lfo->_.period = lfo->editable_state.period;
842 lfo->time = lfo->_.period * t;
843 }
844 else{
845 lfo->time = 0;
846 lfo->_.period = lfo->editable_state.period;
847 }
848 }
849
850 lfo->editble_state_write_mask = 0x00;
851 }
852
853 dsp_update_tunings();
854 audio_unlock();
855
856 /*
857 * Process spawns
858 * ------------------------------------------------------------- */
859 for( int i=0; i<AUDIO_CHANNELS; i++ ){
860 audio_channel *ch = &vg_audio.channels[i];
861
862 if( ch->activity == k_channel_activity_wake ){
863 if( audio_channel_load_source( ch ) )
864 ch->activity = k_channel_activity_alive;
865 else
866 ch->activity = k_channel_activity_error;
867 }
868 }
869
870 /*
871 * Mix everything
872 * -------------------------------------------------------- */
873 int frame_count = byte_count/(2*sizeof(float));
874
875 /* Clear buffer */
876 float *pOut32F = (float *)stream;
877 for( int i=0; i<frame_count*2; i ++ )
878 pOut32F[i] = 0.0f;
879
880 for( int i=0; i<AUDIO_LFOS; i++ )
881 {
882 audio_lfo *lfo = &vg_audio.oscillators[i];
883 lfo->time_startframe = lfo->time;
884 }
885
886 for( int j=0; j<2; j++ )
887 {
888 for( int i=0; i<AUDIO_CHANNELS; i ++ )
889 {
890 audio_channel *ch = &vg_audio.channels[i];
891
892 if( use_dsp )
893 {
894 if( ch->flags & AUDIO_FLAG_NO_DSP )
895 {
896 if( j==0 )
897 continue;
898 }
899 else
900 {
901 if( j==1 )
902 continue;
903 }
904 }
905
906 if( ch->activity == k_channel_activity_alive )
907 {
908 if( ch->_.lfo )
909 ch->_.lfo->time = ch->_.lfo->time_startframe;
910
911 u32 remaining = frame_count,
912 subpos = 0;
913
914 while( remaining )
915 {
916 audio_channel_mix( ch, pOut32F+subpos );
917 remaining -= AUDIO_MIX_FRAME_SIZE;
918 subpos += AUDIO_MIX_FRAME_SIZE*2;
919 }
920 }
921 }
922
923 if( use_dsp )
924 {
925 if( j==0 )
926 {
927 vg_profile_begin( &_vg_prof_dsp );
928 for( int i=0; i<frame_count; i++ )
929 vg_dsp_process( pOut32F + i*2, pOut32F + i*2 );
930 vg_profile_end( &_vg_prof_dsp );
931 }
932 }
933 else
934 break;
935 }
936
937 audio_lock();
938
939 for( int i=0; i<AUDIO_CHANNELS; i ++ )
940 {
941 audio_channel *ch = &vg_audio.channels[i];
942 ch->readable_activity = ch->activity;
943 }
944
945 /* Profiling information
946 * ----------------------------------------------- */
947 vg_profile_increment( &_vg_prof_audio_decode );
948 vg_profile_increment( &_vg_prof_audio_mix );
949 vg_profile_increment( &_vg_prof_dsp );
950
951 vg_prof_audio_mix = _vg_prof_audio_mix;
952 vg_prof_audio_decode = _vg_prof_audio_decode;
953 vg_prof_audio_dsp = _vg_prof_dsp;
954
955 vg_audio.samples_last = frame_count;
956
957 if( vg_audio.debug_dsp )
958 vg_dsp_update_texture();
959
960 audio_unlock();
961 }
962
963 void audio_clip_load( audio_clip *clip, void *lin_alloc )
964 {
965 if( lin_alloc == NULL )
966 lin_alloc = vg_audio.audio_pool;
967
968 if( vg_audio.always_keep_compressed )
969 {
970 if( (clip->flags & AUDIO_FLAG_FORMAT) != k_audio_format_bird ){
971 clip->flags &= ~AUDIO_FLAG_FORMAT;
972 clip->flags |= k_audio_format_vorbis;
973 }
974 }
975
976 /* load in directly */
977 u32 format = clip->flags & AUDIO_FLAG_FORMAT;
978
979 /* TODO: This contains audio_lock() and unlock, but i don't know why
980 * can probably remove them. Low priority to check this */
981
982 /* TODO: packed files for vorbis etc, should take from data if its not not
983 * NULL when we get the clip
984 */
985
986 if( format == k_audio_format_vorbis ){
987 if( !clip->path ){
988 vg_fatal_error( "No path specified, embeded vorbis unsupported" );
989 }
990
991 audio_lock();
992 clip->data = vg_file_read( lin_alloc, clip->path, &clip->size );
993 audio_unlock();
994
995 if( !clip->data )
996 vg_fatal_error( "Audio failed to load" );
997
998 float mb = (float)(clip->size) / (1024.0f*1024.0f);
999 vg_info( "Loaded audio clip '%s' (%.1fmb)\n", clip->path, mb );
1000 }
1001 else if( format == k_audio_format_stereo ){
1002 vg_fatal_error( "Unsupported format (Stereo uncompressed)" );
1003 }
1004 else if( format == k_audio_format_bird ){
1005 if( !clip->data ){
1006 vg_fatal_error( "No data, external birdsynth unsupported" );
1007 }
1008
1009 u32 total_size = clip->size + sizeof(struct synth_bird);
1010 total_size -= sizeof(struct synth_bird_settings);
1011 total_size = vg_align8( total_size );
1012
1013 if( total_size > AUDIO_DECODE_SIZE )
1014 vg_fatal_error( "Bird coding too long\n" );
1015
1016 struct synth_bird *bird = vg_linear_alloc( lin_alloc, total_size );
1017 memcpy( &bird->settings, clip->data, clip->size );
1018
1019 clip->data = bird;
1020 clip->size = total_size;
1021
1022 vg_info( "Loaded bird synthesis pattern (%u bytes)\n", total_size );
1023 }
1024 else{
1025 if( !clip->path ){
1026 vg_fatal_error( "No path specified, embeded mono unsupported" );
1027 }
1028
1029 vg_linear_clear( vg_mem.scratch );
1030 u32 fsize;
1031
1032 stb_vorbis_alloc alloc = {
1033 .alloc_buffer = vg_linear_alloc( vg_mem.scratch, AUDIO_DECODE_SIZE ),
1034 .alloc_buffer_length_in_bytes = AUDIO_DECODE_SIZE
1035 };
1036
1037 void *filedata = vg_file_read( vg_mem.scratch, clip->path, &fsize );
1038
1039 int err;
1040 stb_vorbis *decoder = stb_vorbis_open_memory(
1041 filedata, fsize, &err, &alloc );
1042
1043 if( !decoder ){
1044 vg_error( "stb_vorbis_open_memory failed on '%s' (%d)\n",
1045 clip->path, err );
1046 vg_fatal_error( "Vorbis decode error" );
1047 }
1048
1049 /* only mono is supported in uncompressed */
1050 u32 length_samples = stb_vorbis_stream_length_in_samples( decoder ),
1051 data_size = length_samples * sizeof(i16);
1052
1053 audio_lock();
1054 clip->data = vg_linear_alloc( lin_alloc, vg_align8(data_size) );
1055 clip->size = length_samples;
1056 audio_unlock();
1057
1058 int read_samples = stb_vorbis_get_samples_i16_downmixed(
1059 decoder, clip->data, length_samples );
1060
1061 if( read_samples != length_samples )
1062 vg_fatal_error( "Decode error" );
1063
1064 #if 0
1065 float mb = (float)(data_size) / (1024.0f*1024.0f);
1066 vg_info( "Loaded audio clip '%s' (%.1fmb) %u samples\n", clip->path, mb,
1067 length_samples );
1068 #endif
1069 }
1070 }
1071
1072 void audio_clip_loadn( audio_clip *arr, int count, void *lin_alloc )
1073 {
1074 for( int i=0; i<count; i++ )
1075 audio_clip_load( &arr[i], lin_alloc );
1076 }
1077
1078 static void audio_require_clip_loaded( audio_clip *clip )
1079 {
1080 if( clip->data && clip->size )
1081 return;
1082
1083 audio_unlock();
1084 vg_fatal_error( "Must load audio clip before playing! \n" );
1085 }
1086
1087 /*
1088 * Debugging
1089 */
1090
1091 void audio_debug_ui(
1092
1093 #ifdef VG_3D
1094 m4x4f
1095 #else
1096 m3x3f
1097 #endif
1098 mtx_pv ){
1099
1100 if( !vg_audio.debug_ui )
1101 return;
1102
1103 audio_lock();
1104
1105 glBindTexture( GL_TEXTURE_2D, vg_dsp.view_texture );
1106 glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 256,
1107 GL_RGBA, GL_UNSIGNED_BYTE,
1108 vg_dsp.view_texture_buffer );
1109
1110 /*
1111 * Profiler
1112 * -----------------------------------------------------------------------
1113 */
1114
1115 float budget = ((double)vg_audio.samples_last / 44100.0) * 1000.0;
1116 vg_profile_drawn( (struct vg_profile *[]){ &vg_prof_audio_decode,
1117 &vg_prof_audio_mix,
1118 &vg_prof_audio_dsp}, 3,
1119 budget, (ui_rect){ 4, VG_PROFILE_SAMPLE_COUNT*2 + 8,
1120 512, 0 }, 0, 0 );
1121
1122
1123 char perf[128];
1124
1125 /* Draw UI */
1126 ui_rect window = {
1127 0,
1128 0,
1129 800,
1130 AUDIO_CHANNELS * 18
1131 };
1132
1133 if( vg_audio.debug_dsp ){
1134 ui_rect view_thing = { 4, vg.window_y-512-4, 512, 512 };
1135 ui_image( view_thing, vg_dsp.view_texture );
1136 }
1137
1138 ui_rect overlap_buffer[ AUDIO_CHANNELS ];
1139 u32 overlap_length = 0;
1140
1141 /* Draw audio stack */
1142 for( int i=0; i<AUDIO_CHANNELS; i ++ ){
1143 audio_channel *ch = &vg_audio.channels[i];
1144
1145 ui_rect row;
1146 ui_split( window, k_ui_axis_h, 18, 1, row, window );
1147
1148 if( !ch->allocated ){
1149 ui_fill( row, 0x50333333 );
1150 continue;
1151 }
1152
1153 const char *formats[] =
1154 {
1155 " mono ",
1156 " stereo ",
1157 " vorbis ",
1158 " none0 ",
1159 " none1 ",
1160 " none2 ",
1161 " none3 ",
1162 " none4 ",
1163 "synth:bird",
1164 " none5 ",
1165 " none6 ",
1166 " none7 ",
1167 " none8 ",
1168 " none9 ",
1169 " none10 ",
1170 " none11 ",
1171 };
1172
1173 const char *activties[] =
1174 {
1175 "reset",
1176 "wake ",
1177 "alive",
1178 "end ",
1179 "error"
1180 };
1181
1182 u32 format_index = (ch->source->flags & AUDIO_FLAG_FORMAT)>>9;
1183
1184 snprintf( perf, 127, "%02d[%#04x.%#06x]%c%c%cD %s [%s] %4.2fv'%s'",
1185 i,
1186 ch->world_id, ch->group,
1187 (ch->editable_state.relinquished)? 'r': '_',
1188 0? 'r': '_',
1189 0? '3': '2',
1190 formats[format_index],
1191 activties[ch->readable_activity],
1192 ch->editable_state.volume,
1193 ch->name );
1194
1195 ui_fill( row, 0xa0000000 | ch->colour );
1196 ui_text( row, perf, 1, k_ui_align_middle_left, 0 );
1197
1198 #ifdef VG_3D
1199 if( AUDIO_FLAG_SPACIAL_3D ){
1200 v4f wpos;
1201 v3_copy( ch->editable_state.spacial_falloff, wpos );
1202
1203 wpos[3] = 1.0f;
1204 m4x4_mulv( mtx_pv, wpos, wpos );
1205
1206 if( wpos[3] > 0.0f ){
1207 v2_muls( wpos, (1.0f/wpos[3]) * 0.5f, wpos );
1208 v2_add( wpos, (v2f){ 0.5f, 0.5f }, wpos );
1209
1210 ui_rect wr;
1211 wr[0] = vg_clampf(wpos[0] * vg.window_x, -32000.0f,32000.0f);
1212 wr[1] = vg_clampf((1.0f-wpos[1]) * vg.window_y,-32000.0f,32000.0f);
1213 wr[2] = 1000;
1214 wr[3] = 17;
1215
1216 for( int j=0; j<12; j++ ){
1217 int collide = 0;
1218 for( int k=0; k<overlap_length; k++ ){
1219 ui_px *wk = overlap_buffer[k];
1220 if( ((wr[0] <= wk[0]+wk[2]) && (wr[0]+wr[2] >= wk[0])) &&
1221 ((wr[1] <= wk[1]+wk[3]) && (wr[1]+wr[3] >= wk[1])) )
1222 {
1223 collide = 1;
1224 break;
1225 }
1226 }
1227
1228 if( !collide )
1229 break;
1230 else
1231 wr[1] += 18;
1232 }
1233
1234 ui_text( wr, perf, 1, k_ui_align_middle_left, 0 );
1235 rect_copy( wr, overlap_buffer[ overlap_length ++ ] );
1236 }
1237 }
1238 #endif
1239 }
1240
1241 audio_unlock();
1242 }