2 #include "vg_audio_dsp.h"
3 #include "vg_platform.h"
6 #include "vg_console.h"
7 #include "vg_profiler.h"
8 #include "vg_audio_synth_bird.h"
12 struct vg_audio_system vg_audio
=
14 .external_global_volume
= 1.0f
,
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()"},
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.
33 static int audio_lock_checker_load(void)
36 SDL_AtomicLock( &vg_audio
.sl_checker
);
37 value
= vg_audio
.sync_locked
;
38 SDL_AtomicUnlock( &vg_audio
.sl_checker
);
42 static void audio_lock_checker_store( int value
)
44 SDL_AtomicLock( &vg_audio
.sl_checker
);
45 vg_audio
.sync_locked
= value
;
46 SDL_AtomicUnlock( &vg_audio
.sl_checker
);
49 static void audio_require_lock(void)
51 if( audio_lock_checker_load() )
54 vg_error( "Modifying sound effects systems requires locking\n" );
60 SDL_AtomicLock( &vg_audio
.sl_sync
);
61 audio_lock_checker_store(1);
64 void audio_unlock(void)
66 audio_lock_checker_store(0);
67 SDL_AtomicUnlock( &vg_audio
.sl_sync
);
70 static void audio_mixer_callback( void *user
, u8
*stream
, int frame_count
);
71 void vg_audio_device_init(void)
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
;
84 vg_audio
.sdl_output_device
=
85 SDL_OpenAudioDevice( vg_audio
.device_choice
.buffer
, 0,
86 &spec_desired
, &spec_got
,0 );
88 vg_info( "Start audio device (%u, F32, %u) @%s\n",
91 vg_audio
.device_choice
.buffer
);
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
);
99 "SDL_OpenAudioDevice failed. Your default audio device must support:\n"
100 " Frequency: 44100 hz\n"
101 " Buffer size: 512\n"
103 " Format: s16 or f32\n" );
107 void vg_audio_register(void)
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
);
121 void vg_audio_init(void)
123 /* allocate memory */
125 vg_audio
.audio_pool
=
126 vg_create_linear_allocator( vg_mem
.rtmemory
, 1024*1024*32,
130 u32 decode_size
= AUDIO_DECODE_SIZE
* AUDIO_CHANNELS
;
131 vg_audio
.decode_buffer
= vg_linear_alloc( vg_mem
.rtmemory
, decode_size
);
134 vg_audio_device_init();
137 void vg_audio_free(void)
140 SDL_CloseAudioDevice( vg_audio
.sdl_output_device
);
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
156 void audio_channel_init( audio_channel
*ch
, audio_clip
*clip
, u32 flags
)
158 audio_require_lock();
163 ch
->colour
= 0x00333333;
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]" );
170 vg_strncpy( clip
->path
, ch
->name
, 32, k_strncpy_always_add_null
);
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;
188 void audio_channel_group( audio_channel
*ch
, u16 group
)
190 audio_require_lock();
192 ch
->colour
= (((u32
)group
* 29986577) & 0x00ffffff) | 0xff000000;
195 void audio_channel_world( audio_channel
*ch
, u8 world_id
)
197 audio_require_lock();
198 ch
->world_id
= world_id
;
201 audio_channel
*audio_get_first_idle_channel(void)
203 audio_require_lock();
204 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ ){
205 audio_channel
*ch
= &vg_audio
.channels
[i
];
207 if( !ch
->allocated
){
215 audio_channel
*audio_get_group_idle_channel( u16 group
, u32 max_count
)
217 audio_require_lock();
219 audio_channel
*dest
= NULL
;
221 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ ){
222 audio_channel
*ch
= &vg_audio
.channels
[i
];
225 if( ch
->group
== group
){
235 if( dest
&& (count
< max_count
) ){
242 audio_channel
*audio_get_group_first_active_channel( u16 group
)
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
) )
253 int audio_channel_finished( audio_channel
*ch
)
255 audio_require_lock();
256 if( ch
->readable_activity
== k_channel_activity_end
)
262 audio_channel
*audio_relinquish_channel( audio_channel
*ch
)
264 audio_require_lock();
265 ch
->editable_state
.relinquished
= 1;
266 ch
->editble_state_write_mask
|= AUDIO_EDIT_OWNERSHIP
;
270 void audio_channel_slope_volume( audio_channel
*ch
, f32 length
, f32 new_vol
)
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
;
278 void audio_channel_set_sampling_rate( audio_channel
*ch
, float rate
)
280 audio_require_lock();
281 ch
->editable_state
.sampling_rate
= rate
;
282 ch
->editble_state_write_mask
|= AUDIO_EDIT_SAMPLING_RATE
;
285 void audio_channel_edit_volume( audio_channel
*ch
, f32 new_vol
, int instant
)
287 audio_require_lock();
289 ch
->editable_state
.volume
= new_vol
;
290 ch
->editble_state_write_mask
|= AUDIO_EDIT_VOLUME
;
293 audio_channel_slope_volume( ch
, 0.05f
, new_vol
);
297 audio_channel
*audio_channel_fadeout( audio_channel
*ch
, float length
)
299 audio_require_lock();
300 audio_channel_slope_volume( ch
, length
, 0.0f
);
301 return audio_relinquish_channel( ch
);
304 void audio_channel_fadein( audio_channel
*ch
, float length
)
306 audio_require_lock();
307 audio_channel_edit_volume( ch
, 0.0f
, 1 );
308 audio_channel_slope_volume( ch
, length
, 1.0f
);
311 audio_channel
*audio_channel_crossfade( audio_channel
*ch
,
312 audio_clip
*new_clip
,
313 float length
, u32 flags
)
315 audio_require_lock();
319 ch
= audio_channel_fadeout( ch
, length
);
321 audio_channel
*replacement
= audio_get_first_idle_channel();
324 audio_channel_init( replacement
, new_clip
, flags
);
325 audio_channel_fadein( replacement
, length
);
331 void audio_channel_sidechain_lfo( audio_channel
*ch
, int lfo_id
, f32 amount
)
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
;
339 void audio_channel_set_spacial( audio_channel
*ch
, v3f co
, float range
)
341 audio_require_lock();
342 if( ch
->flags
& AUDIO_FLAG_SPACIAL_3D
){
343 v3_copy( co
, ch
->editable_state
.spacial_falloff
);
346 ch
->editable_state
.spacial_falloff
[3] = 1.0f
;
348 ch
->editable_state
.spacial_falloff
[3] = 1.0f
/range
;
350 ch
->editble_state_write_mask
|= AUDIO_EDIT_SPACIAL
;
353 vg_warn( "Tried to set spacialization paramaters for 2D channel (%s)\n",
358 int audio_oneshot_3d( audio_clip
*clip
, v3f position
, f32 range
, f32 volume
)
360 audio_require_lock();
361 audio_channel
*ch
= audio_get_first_idle_channel();
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
);
376 int audio_oneshot( audio_clip
*clip
, f32 volume
, f32 pan
)
378 audio_require_lock();
379 audio_channel
*ch
= audio_get_first_idle_channel();
383 audio_channel_init( ch
, clip
, AUDIO_FLAG_NO_DSP
);
384 audio_channel_edit_volume( ch
, volume
, 1 );
385 audio_relinquish_channel( ch
);
393 void audio_set_lfo_wave( int id
, enum lfo_wave_type type
, f32 coefficient
)
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
;
400 lfo
->editble_state_write_mask
|= AUDIO_EDIT_LFO_WAVE
;
403 void audio_set_lfo_frequency( int id
, float freq
)
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
;
414 * -----------------------------------------------------------------------------
416 int audio_channel_load_source( audio_channel
*ch
)
418 u32 format
= ch
->source
->flags
& AUDIO_FLAG_FORMAT
;
420 if( format
== k_audio_format_vorbis
){
421 /* Setup vorbis decoder */
422 u32 index
= ch
- vg_audio
.channels
;
424 u8
*buf
= (u8
*)vg_audio
.decode_buffer
,
425 *loc
= &buf
[AUDIO_DECODE_SIZE
*index
];
427 stb_vorbis_alloc alloc
= {
428 .alloc_buffer
= (char *)loc
,
429 .alloc_buffer_length_in_bytes
= AUDIO_DECODE_SIZE
433 stb_vorbis
*decoder
= stb_vorbis_open_memory(
435 ch
->source
->size
, &err
, &alloc
);
438 vg_error( "stb_vorbis_open_memory failed on '%s' (%d)\n",
439 ch
->source
->path
, err
);
443 ch
->source_length
= stb_vorbis_stream_length_in_samples( decoder
);
444 ch
->handle
.vorbis
= decoder
;
447 else if( format
== k_audio_format_bird
){
448 u32 index
= ch
- vg_audio
.channels
;
450 u8
*buf
= (u8
*)vg_audio
.decode_buffer
;
451 struct synth_bird
*loc
= (void *)&buf
[AUDIO_DECODE_SIZE
*index
];
453 memcpy( loc
, ch
->source
->data
, ch
->source
->size
);
454 synth_bird_reset( loc
);
456 ch
->handle
.bird
= loc
;
457 ch
->source_length
= synth_bird_get_length_in_samples( loc
);
459 else if( format
== k_audio_format_stereo
){
460 ch
->source_length
= ch
->source
->size
/ 2;
462 else if( format
== k_audio_format_gen
){
463 ch
->source_length
= 0xffffffff;
466 ch
->source_length
= ch
->source
->size
;
472 static void audio_decode_uncompressed_mono( i16
*src
, u32 count
, float *dst
)
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
);
480 static inline float audio_lfo_pull_sample( audio_lfo
*lfo
)
484 if( lfo
->time
>= lfo
->_
.period
)
488 t
/= (float)lfo
->_
.period
;
490 if( lfo
->_
.wave_type
== k_lfo_polynomial_bipolar
){
506 return (( 2.0f
* lfo
->sqrt_polynomial_coefficient
* t
) /
507 /* --------------------------------------- */
508 ( 1.0f
+ lfo
->_
.polynomial_coefficient
* t
*t
)
517 static void audio_channel_get_samples( audio_channel
*ch
,
518 u32 count
, float *buf
)
520 vg_profile_begin( &_vg_prof_audio_decode
);
522 u32 remaining
= count
;
525 u32 format
= ch
->source
->flags
& AUDIO_FLAG_FORMAT
;
528 u32 samples_this_run
= VG_MIN(remaining
, ch
->source_length
- ch
->cursor
);
529 remaining
-= samples_this_run
;
531 float *dst
= &buf
[ buffer_pos
* 2 ];
533 if( format
== k_audio_format_stereo
){
534 for( int i
=0;i
<samples_this_run
; i
++ ){
539 else if( format
== k_audio_format_vorbis
){
540 int read_samples
= stb_vorbis_get_samples_float_interleaved_stereo(
545 if( read_samples
!= samples_this_run
){
546 vg_warn( "Invalid samples read (%s)\n", ch
->source
->path
);
548 for( int i
=0; i
<samples_this_run
; i
++ ){
554 else if( format
== k_audio_format_bird
){
555 synth_bird_generate_samples( ch
->handle
.bird
, dst
, samples_this_run
);
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
);
562 i16
*src_buffer
= ch
->source
->data
,
563 *src
= &src_buffer
[ch
->cursor
];
565 audio_decode_uncompressed_mono( src
, samples_this_run
, dst
);
568 ch
->cursor
+= samples_this_run
;
569 buffer_pos
+= samples_this_run
;
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
);
585 buf
[ buffer_pos
*2 + 0 ] = 0.0f
;
586 buf
[ buffer_pos
*2 + 1 ] = 0.0f
;
592 vg_profile_end( &_vg_prof_audio_decode
);
595 static void audio_channel_mix( audio_channel
*ch
, float *buffer
)
597 float framevol_l
= vg_audio
.internal_global_volume
,
598 framevol_r
= vg_audio
.internal_global_volume
;
600 float frame_samplerate
= ch
->_
.sampling_rate
;
602 if( ch
->flags
& AUDIO_FLAG_SPACIAL_3D
){
604 v3_sub( ch
->_
.spacial_falloff
, vg_audio
.internal_listener_pos
, delta
);
606 float dist
= v3_length( delta
),
607 vol
= vg_maxf( 0.0f
, 1.0f
- ch
->_
.spacial_falloff
[3]*dist
);
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
);
617 framevol_l
*= (vol
* 0.5f
) * (1.0f
- pan
);
618 framevol_r
*= (vol
* 0.5f
) * (1.0f
+ pan
);
620 if( !(ch
->source
->flags
& AUDIO_FLAG_NO_DOPPLER
) ){
621 const float vs
= 323.0f
;
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
);
627 if( fabsf(doppler
-1.0f
) > 0.01f
)
628 frame_samplerate
*= doppler
;
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"
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]
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
);
659 float pcf
[ AUDIO_MIX_FRAME_SIZE
* 2 * 2 ];
661 audio_channel_get_samples( ch
, buffer_length
, pcf
);
663 vg_profile_begin( &_vg_prof_audio_mix
);
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
;
669 float volume
= ch
->_
.volume
;
670 const float volume_start
= ch
->volume_movement_start
;
671 const float volume_target
= ch
->_
.volume_target
;
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
);
679 float vol_norm
= volume
* volume
;
682 vol_norm
*= 1.0f
+ audio_lfo_pull_sample(ch
->_
.lfo
) * ch
->_
.lfo_amount
;
684 float vol_l
= vol_norm
* framevol_l
,
685 vol_r
= vol_norm
* framevol_r
,
689 if( frame_samplerate
!= 1.0f
){
690 /* absolutely garbage resampling, but it will do
693 float sample_index
= frame_samplerate
* (float)j
;
694 float t
= vg_fractf( sample_index
);
696 u32 i0
= floorf( sample_index
),
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
;
703 sample_l
= pcf
[ j
*2+0 ];
704 sample_r
= pcf
[ j
*2+1 ];
707 buffer
[ j
*2+0 ] += sample_l
* vol_l
;
708 buffer
[ j
*2+1 ] += sample_r
* vol_r
;
711 ch
->volume_movement
+= AUDIO_MIX_FRAME_SIZE
;
712 ch
->volume_movement
= VG_MIN( ch
->volume_movement
, ch
->_
.volume_rate
);
713 ch
->_
.volume
= volume
;
715 vg_profile_end( &_vg_prof_audio_mix
);
718 static void audio_mixer_callback( void *user
, u8
*stream
, int byte_count
){
720 * Copy data and move edit flags to commit flags
721 * ------------------------------------------------------------- */
723 int use_dsp
= vg_audio
.dsp_enabled
;
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
;
731 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ ){
732 audio_channel
*ch
= &vg_audio
.channels
[i
];
737 if( ch
->activity
== k_channel_activity_alive
){
738 if( (ch
->cursor
>= ch
->source_length
) &&
739 !(ch
->flags
& AUDIO_FLAG_LOOP
) )
741 ch
->activity
= k_channel_activity_end
;
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
) )
751 ch
->_
.relinquished
= 0;
753 ch
->activity
= k_channel_activity_reset
;
758 /* process new channels */
759 if( ch
->activity
== k_channel_activity_reset
){
760 ch
->_
= ch
->editable_state
;
762 ch
->source_length
= 0;
763 ch
->activity
= k_channel_activity_wake
;
766 if( ch
->editble_state_write_mask
& AUDIO_EDIT_OWNERSHIP
)
767 ch
->_
.relinquished
= ch
->editable_state
.relinquished
;
769 ch
->editable_state
.relinquished
= ch
->_
.relinquished
;
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
;
777 ch
->editable_state
.volume
= ch
->_
.volume
;
781 if( ch
->editble_state_write_mask
& AUDIO_EDIT_VOLUME_SLOPE
){
782 ch
->volume_movement_start
= ch
->_
.volume
;
783 ch
->volume_movement
= 0;
785 ch
->_
.volume_target
= ch
->editable_state
.volume_target
;
786 ch
->_
.volume_rate
= ch
->editable_state
.volume_rate
;
789 ch
->editable_state
.volume_target
= ch
->_
.volume_target
;
790 ch
->editable_state
.volume_rate
= ch
->_
.volume_rate
;
794 if( ch
->editble_state_write_mask
& AUDIO_EDIT_SAMPLING_RATE
)
795 ch
->_
.sampling_rate
= ch
->editable_state
.sampling_rate
;
797 ch
->editable_state
.sampling_rate
= ch
->_
.sampling_rate
;
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
;
805 ch
->editable_state
.lfo
= ch
->_
.lfo
;
806 ch
->editable_state
.lfo_amount
= ch
->_
.lfo_amount
;
810 if( ch
->editble_state_write_mask
& AUDIO_EDIT_SPACIAL
)
811 v4_copy( ch
->editable_state
.spacial_falloff
,ch
->_
.spacial_falloff
);
813 v4_copy( ch
->_
.spacial_falloff
,ch
->editable_state
.spacial_falloff
);
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;
822 for( int i
=0; i
<AUDIO_LFOS
; i
++ ){
823 audio_lfo
*lfo
= &vg_audio
.oscillators
[ i
];
825 if( lfo
->editble_state_write_mask
& AUDIO_EDIT_LFO_WAVE
){
826 lfo
->_
.wave_type
= lfo
->editable_state
.wave_type
;
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
);
836 if( lfo
->editble_state_write_mask
& AUDIO_EDIT_LFO_PERIOD
){
839 t
/= (float)lfo
->_
.period
;
841 lfo
->_
.period
= lfo
->editable_state
.period
;
842 lfo
->time
= lfo
->_
.period
* t
;
846 lfo
->_
.period
= lfo
->editable_state
.period
;
850 lfo
->editble_state_write_mask
= 0x00;
853 dsp_update_tunings();
858 * ------------------------------------------------------------- */
859 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ ){
860 audio_channel
*ch
= &vg_audio
.channels
[i
];
862 if( ch
->activity
== k_channel_activity_wake
){
863 if( audio_channel_load_source( ch
) )
864 ch
->activity
= k_channel_activity_alive
;
866 ch
->activity
= k_channel_activity_error
;
872 * -------------------------------------------------------- */
873 int frame_count
= byte_count
/(2*sizeof(float));
876 float *pOut32F
= (float *)stream
;
877 for( int i
=0; i
<frame_count
*2; i
++ )
880 for( int i
=0; i
<AUDIO_LFOS
; i
++ )
882 audio_lfo
*lfo
= &vg_audio
.oscillators
[i
];
883 lfo
->time_startframe
= lfo
->time
;
886 for( int j
=0; j
<2; j
++ )
888 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ )
890 audio_channel
*ch
= &vg_audio
.channels
[i
];
894 if( ch
->flags
& AUDIO_FLAG_NO_DSP
)
906 if( ch
->activity
== k_channel_activity_alive
)
909 ch
->_
.lfo
->time
= ch
->_
.lfo
->time_startframe
;
911 u32 remaining
= frame_count
,
916 audio_channel_mix( ch
, pOut32F
+subpos
);
917 remaining
-= AUDIO_MIX_FRAME_SIZE
;
918 subpos
+= AUDIO_MIX_FRAME_SIZE
*2;
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
);
939 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ )
941 audio_channel
*ch
= &vg_audio
.channels
[i
];
942 ch
->readable_activity
= ch
->activity
;
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
);
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
;
955 vg_audio
.samples_last
= frame_count
;
957 if( vg_audio
.debug_dsp
)
958 vg_dsp_update_texture();
963 void audio_clip_load( audio_clip
*clip
, void *lin_alloc
)
965 if( lin_alloc
== NULL
)
966 lin_alloc
= vg_audio
.audio_pool
;
968 if( vg_audio
.always_keep_compressed
)
970 if( (clip
->flags
& AUDIO_FLAG_FORMAT
) != k_audio_format_bird
){
971 clip
->flags
&= ~AUDIO_FLAG_FORMAT
;
972 clip
->flags
|= k_audio_format_vorbis
;
976 /* load in directly */
977 u32 format
= clip
->flags
& AUDIO_FLAG_FORMAT
;
979 /* TODO: This contains audio_lock() and unlock, but i don't know why
980 * can probably remove them. Low priority to check this */
982 /* TODO: packed files for vorbis etc, should take from data if its not not
983 * NULL when we get the clip
986 if( format
== k_audio_format_vorbis
){
988 vg_fatal_error( "No path specified, embeded vorbis unsupported" );
992 clip
->data
= vg_file_read( lin_alloc
, clip
->path
, &clip
->size
);
996 vg_fatal_error( "Audio failed to load" );
998 float mb
= (float)(clip
->size
) / (1024.0f
*1024.0f
);
999 vg_info( "Loaded audio clip '%s' (%.1fmb)\n", clip
->path
, mb
);
1001 else if( format
== k_audio_format_stereo
){
1002 vg_fatal_error( "Unsupported format (Stereo uncompressed)" );
1004 else if( format
== k_audio_format_bird
){
1006 vg_fatal_error( "No data, external birdsynth unsupported" );
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
);
1013 if( total_size
> AUDIO_DECODE_SIZE
)
1014 vg_fatal_error( "Bird coding too long\n" );
1016 struct synth_bird
*bird
= vg_linear_alloc( lin_alloc
, total_size
);
1017 memcpy( &bird
->settings
, clip
->data
, clip
->size
);
1020 clip
->size
= total_size
;
1022 vg_info( "Loaded bird synthesis pattern (%u bytes)\n", total_size
);
1026 vg_fatal_error( "No path specified, embeded mono unsupported" );
1029 vg_linear_clear( vg_mem
.scratch
);
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
1037 void *filedata
= vg_file_read( vg_mem
.scratch
, clip
->path
, &fsize
);
1040 stb_vorbis
*decoder
= stb_vorbis_open_memory(
1041 filedata
, fsize
, &err
, &alloc
);
1044 vg_error( "stb_vorbis_open_memory failed on '%s' (%d)\n",
1046 vg_fatal_error( "Vorbis decode error" );
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
);
1054 clip
->data
= vg_linear_alloc( lin_alloc
, vg_align8(data_size
) );
1055 clip
->size
= length_samples
;
1058 int read_samples
= stb_vorbis_get_samples_i16_downmixed(
1059 decoder
, clip
->data
, length_samples
);
1061 if( read_samples
!= length_samples
)
1062 vg_fatal_error( "Decode error" );
1065 float mb
= (float)(data_size
) / (1024.0f
*1024.0f
);
1066 vg_info( "Loaded audio clip '%s' (%.1fmb) %u samples\n", clip
->path
, mb
,
1072 void audio_clip_loadn( audio_clip
*arr
, int count
, void *lin_alloc
)
1074 for( int i
=0; i
<count
; i
++ )
1075 audio_clip_load( &arr
[i
], lin_alloc
);
1078 static void audio_require_clip_loaded( audio_clip
*clip
)
1080 if( clip
->data
&& clip
->size
)
1084 vg_fatal_error( "Must load audio clip before playing! \n" );
1091 void audio_debug_ui(
1100 if( !vg_audio
.debug_ui
)
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
);
1112 * -----------------------------------------------------------------------
1115 float budget
= ((double)vg_audio
.samples_last
/ 44100.0) * 1000.0;
1116 vg_profile_drawn( (struct vg_profile
*[]){ &vg_prof_audio_decode
,
1118 &vg_prof_audio_dsp
}, 3,
1119 budget
, (ui_rect
){ 4, VG_PROFILE_SAMPLE_COUNT
*2 + 8,
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
);
1138 ui_rect overlap_buffer
[ AUDIO_CHANNELS
];
1139 u32 overlap_length
= 0;
1141 /* Draw audio stack */
1142 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ ){
1143 audio_channel
*ch
= &vg_audio
.channels
[i
];
1146 ui_split( window
, k_ui_axis_h
, 18, 1, row
, window
);
1148 if( !ch
->allocated
){
1149 ui_fill( row
, 0x50333333 );
1153 const char *formats
[] =
1173 const char *activties
[] =
1182 u32 format_index
= (ch
->source
->flags
& AUDIO_FLAG_FORMAT
)>>9;
1184 snprintf( perf
, 127, "%02d[%#04x.%#06x]%c%c%cD %s [%s] %4.2fv'%s'",
1186 ch
->world_id
, ch
->group
,
1187 (ch
->editable_state
.relinquished
)? 'r': '_',
1190 formats
[format_index
],
1191 activties
[ch
->readable_activity
],
1192 ch
->editable_state
.volume
,
1195 ui_fill( row
, 0xa0000000 | ch
->colour
);
1196 ui_text( row
, perf
, 1, k_ui_align_middle_left
, 0 );
1199 if( AUDIO_FLAG_SPACIAL_3D
){
1201 v3_copy( ch
->editable_state
.spacial_falloff
, wpos
);
1204 m4x4_mulv( mtx_pv
, wpos
, wpos
);
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
);
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
);
1216 for( int j
=0; j
<12; j
++ ){
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])) )
1234 ui_text( wr
, perf
, 1, k_ui_align_middle_left
, 0 );
1235 rect_copy( wr
, overlap_buffer
[ overlap_length
++ ] );