1 /* Copyright (C) 2021-2023 Harry Godden (hgn) - All Rights Reserved */
9 #include "vg/vg_stdint.h"
10 #include "vg/vg_platform.h"
14 #include "vg/vg_console.h"
15 #include "vg/vg_store.h"
16 #include "vg/vg_profiler.h"
17 #include "vg/vg_audio_synth_bird.h"
24 #pragma GCC push_options
25 #pragma GCC optimize ("O3")
26 #pragma GCC diagnostic push
27 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
31 #define STB_VORBIS_MAX_CHANNELS 2
32 #include "submodules/stb/stb_vorbis.c"
39 #pragma GCC pop_options
40 #pragma GCC diagnostic pop
44 #define AUDIO_FRAME_SIZE 512
45 #define AUDIO_MIX_FRAME_SIZE 256
47 #define AUDIO_CHANNELS 32
49 #define AUDIO_FILTERS 16
50 #define AUDIO_FLAG_LOOP 0x1
51 #define AUDIO_FLAG_SPACIAL_3D 0x4
52 #define AUDIO_FLAG_AUTO_START 0x8
54 /* Vorbis will ALWAYS use the maximum amount of channels it can */
55 //#define AUDIO_FLAG_MONO 0x100 NOTE: This is the default, so its not used
56 //#define AUDIO_FLAG_STEREO 0x200
57 //#define AUDIO_FLAG_VORBIS 0x400
58 //#define AUDIO_FLAG_BIRD_SYNTH 0x800
60 #define AUDIO_FLAG_FORMAT 0x1E00
64 k_audio_format_mono
= 0x000u
,
65 k_audio_format_stereo
= 0x200u
,
66 k_audio_format_vorbis
= 0x400u
,
67 k_audio_format_none0
= 0x600u
,
68 k_audio_format_none1
= 0x800u
,
69 k_audio_format_none2
= 0xA00u
,
70 k_audio_format_none3
= 0xC00u
,
71 k_audio_format_none4
= 0xE00u
,
73 k_audio_format_bird
= 0x1000u
,
74 k_audio_format_none5
= 0x1200u
,
75 k_audio_format_none6
= 0x1400u
,
76 k_audio_format_none7
= 0x1600u
,
77 k_audio_format_none8
= 0x1800u
,
78 k_audio_format_none9
= 0x1A00u
,
79 k_audio_format_none10
= 0x1C00u
,
80 k_audio_format_none11
= 0x1E00u
,
83 #define AUDIO_DECODE_SIZE (1024*256) /* 256 kb decoding buffers */
84 #define AUDIO_MUTE_VOLUME 0.0f
85 #define AUDIO_BASE_VOLUME 1.0f
87 typedef struct audio_clip audio_clip
;
88 typedef struct audio_channel audio_channel
;
89 typedef struct audio_lfo audio_lfo
;
100 static struct vg_audio_system
102 SDL_AudioDeviceID sdl_output_device
;
111 SDL_mutex
*mux_checker
,
116 u32 time
, time_startframe
;
117 float sqrt_polynomial_coefficient
;
126 k_lfo_polynomial_bipolar
131 float polynomial_coefficient
;
134 u32 editble_state_write_mask
;
136 oscillators
[ AUDIO_LFOS
];
141 char name
[32]; /* only editable while allocated == 0 */
142 audio_clip
*source
; /* ... */
144 u32 colour
; /* ... */
146 /* internal non-readable state
147 * -----------------------------*/
148 u32 cursor
, source_length
;
150 float volume_movement_start
,
158 struct synth_bird
*bird_handle
;
159 stb_vorbis
*vorbis_handle
;
162 stb_vorbis_alloc vorbis_alloc
;
164 enum channel_activity
166 k_channel_activity_reset
, /* will advance if allocated==1, to wake */
167 k_channel_activity_wake
, /* will advance to either of next two */
168 k_channel_activity_alive
,
169 k_channel_activity_end
,
170 k_channel_activity_error
176 * editable structure, can be modified inside _lock and _unlock
177 * the edit mask tells which to copy into internal _, or to discard
178 * ----------------------------------------------------------------------
184 float volume
, /* current volume */
185 volume_target
, /* target volume */
193 v4f spacial_falloff
; /* xyz, range */
199 u32 editble_state_write_mask
;
201 channels
[ AUDIO_CHANNELS
];
203 /* System queue, and access from thread 0 */
204 int debug_ui
, debug_ui_3d
;
212 volume_target_internal
,
215 vg_audio
= { .volume_console
= 1.0f
};
217 #include "vg/vg_audio_dsp.h"
219 static struct vg_profile
220 _vg_prof_audio_decode
= {.mode
= k_profile_mode_accum
,
221 .name
= "[T2] audio_decode()"},
222 _vg_prof_audio_mix
= {.mode
= k_profile_mode_accum
,
223 .name
= "[T2] audio_mix()"},
224 _vg_prof_dsp
= {.mode
= k_profile_mode_accum
,
225 .name
= "[T2] dsp_process()"},
226 vg_prof_audio_decode
,
231 * These functions are called from the main thread and used to prevent bad
232 * access. TODO: They should be no-ops in release builds.
234 VG_STATIC
int audio_lock_checker_load(void)
237 SDL_LockMutex( vg_audio
.mux_checker
);
238 value
= vg_audio
.sync_locked
;
239 SDL_UnlockMutex( vg_audio
.mux_checker
);
243 VG_STATIC
void audio_lock_checker_store( int value
)
245 SDL_LockMutex( vg_audio
.mux_checker
);
246 vg_audio
.sync_locked
= value
;
247 SDL_UnlockMutex( vg_audio
.mux_checker
);
250 VG_STATIC
void audio_require_lock(void)
252 if( audio_lock_checker_load() )
255 vg_error( "Modifying sound effects systems requires locking\n" );
259 VG_STATIC
void audio_lock(void)
261 SDL_LockMutex( vg_audio
.mux_sync
);
262 audio_lock_checker_store(1);
265 VG_STATIC
void audio_unlock(void)
267 audio_lock_checker_store(0);
268 SDL_UnlockMutex( vg_audio
.mux_sync
);
271 VG_STATIC
void audio_mixer_callback( void *user
, u8
*stream
, int frame_count
);
272 VG_STATIC
void vg_audio_init(void)
274 vg_audio
.mux_checker
= SDL_CreateMutex();
275 vg_audio
.mux_sync
= SDL_CreateMutex();
277 /* TODO: Move here? */
278 vg_var_push( (struct vg_var
){
279 .name
= "debug_audio",
280 .data
= &vg_audio
.debug_ui
,
281 .data_type
= k_var_dtype_i32
,
282 .opt_i32
= { .min
=0, .max
=1, .clamp
=1 },
286 vg_var_push( (struct vg_var
){
288 .data
= &vg_audio
.volume_console
,
289 .data_type
= k_var_dtype_f32
,
290 .opt_f32
= { .min
=0.0f
, .max
=2.0f
, .clamp
=1 },
294 /* allocate memory */
297 vg_audio
.audio_pool
=
298 vg_create_linear_allocator( vg_mem
.rtmemory
, 1024*1024*32,
302 u32 decode_size
= AUDIO_DECODE_SIZE
* AUDIO_CHANNELS
;
303 vg_audio
.decode_buffer
= vg_linear_alloc( vg_mem
.rtmemory
, decode_size
);
307 SDL_AudioSpec spec_desired
, spec_got
;
308 spec_desired
.callback
= audio_mixer_callback
;
309 spec_desired
.channels
= 2;
310 spec_desired
.format
= AUDIO_F32
;
311 spec_desired
.freq
= 44100;
312 spec_desired
.padding
= 0;
313 spec_desired
.samples
= AUDIO_FRAME_SIZE
;
314 spec_desired
.silence
= 0;
315 spec_desired
.size
= 0;
316 spec_desired
.userdata
= NULL
;
318 vg_audio
.sdl_output_device
=
319 SDL_OpenAudioDevice( NULL
, 0, &spec_desired
, &spec_got
,0 );
321 if( vg_audio
.sdl_output_device
)
323 SDL_PauseAudioDevice( vg_audio
.sdl_output_device
, 0 );
328 "SDL_OpenAudioDevice failed. Your default audio device must support:\n"
329 " Frequency: 44100 hz\n"
330 " Buffer size: 512\n"
332 " Format: s16 or f32\n" );
335 vg_success( "Ready\n" );
338 VG_STATIC
void vg_audio_free(void)
341 SDL_CloseAudioDevice( vg_audio
.sdl_output_device
);
348 #define AUDIO_EDIT_VOLUME_SLOPE 0x1
349 #define AUDIO_EDIT_VOLUME 0x2
350 #define AUDIO_EDIT_LFO_PERIOD 0x4
351 #define AUDIO_EDIT_LFO_WAVE 0x8
352 #define AUDIO_EDIT_LFO_ATTACHMENT 0x10
353 #define AUDIO_EDIT_SPACIAL 0x20
354 #define AUDIO_EDIT_OWNERSHIP 0x40
355 #define AUDIO_EDIT_SAMPLING_RATE 0x80
357 static audio_channel
*audio_request_channel( audio_clip
*clip
, u32 flags
)
359 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ )
361 audio_channel
*ch
= &vg_audio
.channels
[i
];
367 ch
->colour
= 0x00333333;
369 if( (ch
->source
->flags
& AUDIO_FLAG_FORMAT
) == k_audio_format_bird
)
370 strcpy( ch
->name
, "[array]" );
372 strncpy( ch
->name
, clip
->path
, 31 );
376 ch
->editable_state
.relinquished
= 0;
377 ch
->editable_state
.volume
= 1.0f
;
378 ch
->editable_state
.volume_target
= 1.0f
;
379 ch
->editable_state
.pan
= 0.0f
;
380 ch
->editable_state
.pan_target
= 0.0f
;
381 ch
->editable_state
.volume_rate
= 0;
382 ch
->editable_state
.pan_rate
= 0;
383 v4_copy((v4f
){0.0f
,0.0f
,0.0f
,1.0f
},ch
->editable_state
.spacial_falloff
);
384 ch
->editable_state
.lfo
= NULL
;
385 ch
->editable_state
.lfo_amount
= 0.0f
;
386 ch
->editable_state
.sampling_rate
= 1.0f
;
387 ch
->editble_state_write_mask
= 0x00;
395 static int audio_channel_finished( audio_channel
*ch
)
397 if( ch
->readable_activity
== k_channel_activity_end
)
403 static audio_channel
*audio_relinquish_channel( audio_channel
*ch
)
405 ch
->editable_state
.relinquished
= 1;
406 ch
->editble_state_write_mask
|= AUDIO_EDIT_OWNERSHIP
;
410 static void audio_channel_slope_volume( audio_channel
*ch
, float length
,
413 ch
->editable_state
.volume_target
= new_volume
;
414 ch
->editable_state
.volume_rate
= length
* 44100.0f
;
415 ch
->editble_state_write_mask
|= AUDIO_EDIT_VOLUME_SLOPE
;
418 static void audio_channel_set_sampling_rate( audio_channel
*ch
, float rate
)
420 ch
->editable_state
.sampling_rate
= rate
;
421 ch
->editble_state_write_mask
|= AUDIO_EDIT_SAMPLING_RATE
;
424 static void audio_channel_edit_volume( audio_channel
*ch
,
425 float new_volume
, int instant
)
429 ch
->editable_state
.volume
= new_volume
;
430 ch
->editble_state_write_mask
|= AUDIO_EDIT_VOLUME
;
434 audio_channel_slope_volume( ch
, 0.05f
, new_volume
);
438 static audio_channel
*audio_channel_fadeout( audio_channel
*ch
, float length
)
440 audio_channel_slope_volume( ch
, length
, 0.0f
);
441 return audio_relinquish_channel( ch
);
444 static void audio_channel_fadein( audio_channel
*ch
, float length
)
446 audio_channel_edit_volume( ch
, 0.0f
, 1 );
447 audio_channel_slope_volume( ch
, length
, 1.0f
);
450 static audio_channel
*audio_channel_crossfade( audio_channel
*ch
,
451 audio_clip
*new_clip
,
452 float length
, u32 flags
)
457 ch
= audio_channel_fadeout( ch
, length
);
459 audio_channel
*replacement
= audio_request_channel( new_clip
, flags
);
462 audio_channel_fadein( replacement
, length
);
467 static void audio_channel_sidechain_lfo( audio_channel
*ch
, int lfo_id
,
470 ch
->editable_state
.lfo
= &vg_audio
.oscillators
[ lfo_id
];
471 ch
->editable_state
.lfo_amount
= amount
;
472 ch
->editble_state_write_mask
|= AUDIO_EDIT_LFO_ATTACHMENT
;
475 static void audio_channel_set_spacial( audio_channel
*ch
, v3f co
, float range
)
477 if( ch
->flags
& AUDIO_FLAG_SPACIAL_3D
)
479 v3_copy( co
, ch
->editable_state
.spacial_falloff
);
482 ch
->editable_state
.spacial_falloff
[3] = 1.0f
;
484 ch
->editable_state
.spacial_falloff
[3] = 1.0f
/range
;
486 ch
->editble_state_write_mask
|= AUDIO_EDIT_SPACIAL
;
490 vg_warn( "Tried to set spacialization paramaters for 2D channel (%s)\n",
495 static int audio_oneshot_3d( audio_clip
*clip
, v3f position
,
496 float range
, float volume
)
498 audio_channel
*ch
= audio_request_channel( clip
, AUDIO_FLAG_SPACIAL_3D
);
502 audio_channel_set_spacial( ch
, position
, range
);
503 audio_channel_edit_volume( ch
, volume
, 1 );
504 ch
= audio_relinquish_channel( ch
);
512 static int audio_oneshot( audio_clip
*clip
, float volume
, float pan
)
514 audio_channel
*ch
= audio_request_channel( clip
, 0x00 );
518 audio_channel_edit_volume( ch
, volume
, 1 );
519 ch
= audio_relinquish_channel( ch
);
527 static void audio_set_lfo_wave( int id
, enum lfo_wave_type type
,
530 audio_lfo
*lfo
= &vg_audio
.oscillators
[ id
];
531 lfo
->editable_state
.polynomial_coefficient
= coefficient
;
532 lfo
->editable_state
.wave_type
= type
;
534 lfo
->editble_state_write_mask
|= AUDIO_EDIT_LFO_WAVE
;
537 static void audio_set_lfo_frequency( int id
, float freq
)
539 audio_lfo
*lfo
= &vg_audio
.oscillators
[ id
];
540 lfo
->editable_state
.period
= 44100.0f
/ freq
;
541 lfo
->editble_state_write_mask
|= AUDIO_EDIT_LFO_PERIOD
;
548 * -----------------------------------------------------------------------------
550 static int audio_channel_load_source( audio_channel
*ch
)
552 u32 format
= ch
->source
->flags
& AUDIO_FLAG_FORMAT
;
554 if( format
== k_audio_format_vorbis
)
556 /* Setup vorbis decoder */
557 u32 index
= ch
- vg_audio
.channels
;
559 u8
*buf
= (u8
*)vg_audio
.decode_buffer
,
560 *loc
= &buf
[AUDIO_DECODE_SIZE
*index
];
562 stb_vorbis_alloc alloc
= {
563 .alloc_buffer
= (char *)loc
,
564 .alloc_buffer_length_in_bytes
= AUDIO_DECODE_SIZE
568 stb_vorbis
*decoder
= stb_vorbis_open_memory(
570 ch
->source
->size
, &err
, &alloc
);
574 vg_error( "stb_vorbis_open_memory failed on '%s' (%d)\n",
575 ch
->source
->path
, err
);
580 ch
->source_length
= stb_vorbis_stream_length_in_samples( decoder
);
581 ch
->vorbis_handle
= decoder
;
584 else if( format
== k_audio_format_bird
)
586 u32 index
= ch
- vg_audio
.channels
;
588 u8
*buf
= (u8
*)vg_audio
.decode_buffer
;
589 struct synth_bird
*loc
= (void *)&buf
[AUDIO_DECODE_SIZE
*index
];
591 memcpy( loc
, ch
->source
->data
, ch
->source
->size
);
592 synth_bird_reset( loc
);
594 ch
->bird_handle
= loc
;
595 ch
->source_length
= synth_bird_get_length_in_samples( loc
);
597 else if( format
== k_audio_format_stereo
)
599 ch
->source_length
= ch
->source
->size
/ 2;
603 ch
->source_length
= ch
->source
->size
;
609 VG_STATIC
void audio_decode_uncompressed_mono( i16
*src
, u32 count
, float *dst
)
611 for( u32 i
=0; i
<count
; i
++ )
613 dst
[ i
*2 + 0 ] = ((float)src
[i
]) * (1.0f
/32767.0f
);
614 dst
[ i
*2 + 1 ] = ((float)src
[i
]) * (1.0f
/32767.0f
);
619 * adapted from stb_vorbis.h, since the original does not handle mono->stereo
622 stb_vorbis_get_samples_float_interleaved_stereo( stb_vorbis
*f
, float *buffer
,
626 c
= VG_MIN( 1, f
->channels
- 1 );
630 int k
= f
->channel_buffer_end
- f
->channel_buffer_start
;
635 for( int j
=0; j
< k
; ++j
)
637 *buffer
++ = f
->channel_buffers
[ 0 ][f
->channel_buffer_start
+j
];
638 *buffer
++ = f
->channel_buffers
[ c
][f
->channel_buffer_start
+j
];
642 f
->channel_buffer_start
+= k
;
647 if( !stb_vorbis_get_frame_float( f
, NULL
, NULL
))
655 * ........ more wrecked code sorry!
658 stb_vorbis_get_samples_i16_downmixed( stb_vorbis
*f
, i16
*buffer
, int len
)
661 c
= VG_MIN( 1, f
->channels
- 1 );
665 int k
= f
->channel_buffer_end
- f
->channel_buffer_start
;
670 for( int j
=0; j
< k
; ++j
)
672 float sl
= f
->channel_buffers
[ 0 ][f
->channel_buffer_start
+j
],
673 sr
= f
->channel_buffers
[ c
][f
->channel_buffer_start
+j
];
675 *buffer
++ = vg_clampf( 0.5f
*(sl
+sr
), -1.0f
, 1.0f
) * 32767.0f
;
676 //*buffer++ = vg_clampf( sr, -1.0f, 1.0f ) * 32767.0f;
680 f
->channel_buffer_start
+= k
;
685 if( !stb_vorbis_get_frame_float( f
, NULL
, NULL
))
692 static inline float audio_lfo_pull_sample( audio_lfo
*lfo
)
696 if( lfo
->time
>= lfo
->_
.period
)
700 t
/= (float)lfo
->_
.period
;
702 if( lfo
->_
.wave_type
== k_lfo_polynomial_bipolar
)
719 return (( 2.0f
* lfo
->sqrt_polynomial_coefficient
* t
) /
720 /* --------------------------------------- */
721 ( 1.0f
+ lfo
->_
.polynomial_coefficient
* t
*t
)
731 static void audio_channel_get_samples( audio_channel
*ch
,
732 u32 count
, float *buf
)
734 vg_profile_begin( &_vg_prof_audio_decode
);
736 u32 remaining
= count
;
739 u32 format
= ch
->source
->flags
& AUDIO_FLAG_FORMAT
;
743 u32 samples_this_run
= VG_MIN(remaining
, ch
->source_length
- ch
->cursor
);
744 remaining
-= samples_this_run
;
746 float *dst
= &buf
[ buffer_pos
* 2 ];
748 if( format
== k_audio_format_stereo
)
750 for( int i
=0;i
<samples_this_run
; i
++ )
756 else if( format
== k_audio_format_vorbis
)
758 int read_samples
= stb_vorbis_get_samples_float_interleaved_stereo(
763 if( read_samples
!= samples_this_run
)
765 vg_warn( "Invalid samples read (%s)\n", ch
->source
->path
);
767 for( int i
=0; i
<samples_this_run
; i
++ )
774 else if( format
== k_audio_format_bird
)
776 synth_bird_generate_samples( ch
->bird_handle
, dst
, samples_this_run
);
780 i16
*src_buffer
= ch
->source
->data
,
781 *src
= &src_buffer
[ch
->cursor
];
783 audio_decode_uncompressed_mono( src
, samples_this_run
, dst
);
786 ch
->cursor
+= samples_this_run
;
787 buffer_pos
+= samples_this_run
;
789 if( (ch
->flags
& AUDIO_FLAG_LOOP
) && remaining
)
791 if( format
== k_audio_format_vorbis
)
792 stb_vorbis_seek_start( ch
->vorbis_handle
);
793 else if( format
== k_audio_format_bird
)
794 synth_bird_reset( ch
->bird_handle
);
805 buf
[ buffer_pos
*2 + 0 ] = 0.0f
;
806 buf
[ buffer_pos
*2 + 1 ] = 0.0f
;
812 vg_profile_end( &_vg_prof_audio_decode
);
815 static void audio_channel_mix( audio_channel
*ch
, float *buffer
)
817 float framevol_l
= 1.0f
,
820 float frame_samplerate
= ch
->_
.sampling_rate
;
822 if( ch
->flags
& AUDIO_FLAG_SPACIAL_3D
)
824 if( !vg_validf(vg_audio
.listener_pos
[0]) ||
825 !vg_validf(vg_audio
.listener_pos
[1]) ||
826 !vg_validf(vg_audio
.listener_pos
[2]) ||
827 !vg_validf(vg_audio
.listener_velocity
[0]) ||
828 !vg_validf(vg_audio
.listener_velocity
[1]) ||
829 !vg_validf(vg_audio
.listener_velocity
[2]) ||
830 !vg_validf(ch
->_
.spacial_falloff
[0]) ||
831 !vg_validf(ch
->_
.spacial_falloff
[1]) ||
832 !vg_validf(ch
->_
.spacial_falloff
[2]) )
834 vg_error( "NaN listener/world position (%s)\n", ch
->name
);
841 v3_sub( ch
->_
.spacial_falloff
, vg_audio
.listener_pos
, delta
);
843 float dist
= v3_length( delta
),
844 vol
= vg_maxf( 0.0f
, 1.0f
- ch
->_
.spacial_falloff
[3]*dist
);
846 v3_muls( delta
, 1.0f
/dist
, delta
);
847 float pan
= v3_dot( vg_audio
.listener_ears
, delta
);
848 vol
= powf( vol
, 5.0f
);
850 framevol_l
*= (vol
* 0.5f
) * (1.0f
- pan
);
851 framevol_r
*= (vol
* 0.5f
) * (1.0f
+ pan
);
853 v3_muls( delta
, 1.0f
/dist
, delta
);
855 const float vs
= 100.0f
;
856 float doppler
= (vs
+v3_dot(delta
,vg_audio
.listener_velocity
))/vs
;
857 doppler
= vg_clampf( doppler
, 0.6f
, 1.4f
);
859 if( fabsf(doppler
-1.0f
) > 0.01f
)
860 frame_samplerate
*= doppler
;
863 u32 buffer_length
= AUDIO_MIX_FRAME_SIZE
;
864 if( frame_samplerate
!= 1.0f
)
866 float l
= ceilf( (float)(AUDIO_MIX_FRAME_SIZE
) * frame_samplerate
);
870 float pcf
[ AUDIO_MIX_FRAME_SIZE
* 2 * 2 ];
872 audio_channel_get_samples( ch
, buffer_length
, pcf
);
874 vg_profile_begin( &_vg_prof_audio_mix
);
876 float volume_movement
= ch
->volume_movement
;
877 float const fvolume_rate
= vg_maxf( 1.0f
, ch
->_
.volume_rate
);
878 const float inv_volume_rate
= 1.0f
/fvolume_rate
;
880 float volume
= ch
->_
.volume
;
881 const float volume_start
= ch
->volume_movement_start
;
882 const float volume_target
= ch
->_
.volume_target
;
884 for( u32 j
=0; j
<AUDIO_MIX_FRAME_SIZE
; j
++ )
887 * there is some REALLY weird behaviour with minss,
888 * i cannot begin to guess what the cause is, but the bahaviour when
889 * the second argument is not 1.0 would seemingly tripple or up to
890 * eight times this routine.
892 * the times it would happen are when moving from empty space into areas
893 * with geometry. in the bvh for skate rift.
895 * it should be completely unrelated to this, but somehow -- it is
896 * effecting the speed of minss. and severely at that too.
899 volume_movement
+= 1.0f
;
900 float movement_t
= volume_movement
* inv_volume_rate
;
901 movement_t
= vg_minf( volume_movement
, 1.0f
);
902 volume
= vg_lerpf( volume_start
, volume_target
, movement_t
);
904 float vol_norm
= volume
* volume
;
907 vol_norm
*= 1.0f
+ audio_lfo_pull_sample(ch
->_
.lfo
) * ch
->_
.lfo_amount
;
909 float vol_l
= vol_norm
* framevol_l
,
910 vol_r
= vol_norm
* framevol_r
,
914 if( frame_samplerate
!= 1.0f
)
916 /* absolutely garbage resampling, but it will do
919 float sample_index
= frame_samplerate
* (float)j
;
920 float t
= vg_fractf( sample_index
);
922 u32 i0
= floorf( sample_index
),
925 sample_l
= pcf
[ i0
*2+0 ]*(1.0f
-t
) + pcf
[ i1
*2+0 ]*t
;
926 sample_r
= pcf
[ i0
*2+1 ]*(1.0f
-t
) + pcf
[ i1
*2+1 ]*t
;
930 sample_l
= pcf
[ j
*2+0 ];
931 sample_r
= pcf
[ j
*2+1 ];
934 buffer
[ j
*2+0 ] += sample_l
* vol_l
;
935 buffer
[ j
*2+1 ] += sample_r
* vol_r
;
938 ch
->volume_movement
+= AUDIO_MIX_FRAME_SIZE
;
939 ch
->volume_movement
= VG_MIN( ch
->volume_movement
, ch
->_
.volume_rate
);
940 ch
->_
.volume
= volume
;
942 vg_profile_end( &_vg_prof_audio_mix
);
945 VG_STATIC
void audio_mixer_callback( void *user
, u8
*stream
, int byte_count
)
948 * Copy data and move edit flags to commit flags
949 * ------------------------------------------------------------- */
951 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ )
953 audio_channel
*ch
= &vg_audio
.channels
[i
];
958 if( ch
->activity
== k_channel_activity_alive
)
960 if( (ch
->cursor
>= ch
->source_length
) &&
961 !(ch
->flags
& AUDIO_FLAG_LOOP
) )
963 ch
->activity
= k_channel_activity_end
;
967 /* process relinquishments */
968 if( (ch
->activity
!= k_channel_activity_reset
) && ch
->_
.relinquished
)
970 if( (ch
->activity
== k_channel_activity_end
)
971 || (ch
->_
.volume
== 0.0f
)
972 || (ch
->activity
== k_channel_activity_error
) )
974 ch
->_
.relinquished
= 0;
976 ch
->activity
= k_channel_activity_reset
;
981 /* process new channels */
982 if( ch
->activity
== k_channel_activity_reset
)
984 ch
->_
= ch
->editable_state
;
986 ch
->source_length
= 0;
987 ch
->activity
= k_channel_activity_wake
;
990 if( ch
->editble_state_write_mask
& AUDIO_EDIT_OWNERSHIP
)
991 ch
->_
.relinquished
= ch
->editable_state
.relinquished
;
993 ch
->editable_state
.relinquished
= ch
->_
.relinquished
;
996 if( ch
->editble_state_write_mask
& AUDIO_EDIT_VOLUME
)
998 ch
->_
.volume
= ch
->editable_state
.volume
;
999 ch
->_
.volume_target
= ch
->editable_state
.volume
;
1003 ch
->editable_state
.volume
= ch
->_
.volume
;
1007 if( ch
->editble_state_write_mask
& AUDIO_EDIT_VOLUME_SLOPE
)
1009 ch
->volume_movement_start
= ch
->_
.volume
;
1010 ch
->volume_movement
= 0;
1012 ch
->_
.volume_target
= ch
->editable_state
.volume_target
;
1013 ch
->_
.volume_rate
= ch
->editable_state
.volume_rate
;
1017 ch
->editable_state
.volume_target
= ch
->_
.volume_target
;
1018 ch
->editable_state
.volume_rate
= ch
->_
.volume_rate
;
1022 if( ch
->editble_state_write_mask
& AUDIO_EDIT_SAMPLING_RATE
)
1023 ch
->_
.sampling_rate
= ch
->editable_state
.sampling_rate
;
1025 ch
->editable_state
.sampling_rate
= ch
->_
.sampling_rate
;
1028 if( ch
->editble_state_write_mask
& AUDIO_EDIT_LFO_ATTACHMENT
)
1030 ch
->_
.lfo
= ch
->editable_state
.lfo
;
1031 ch
->_
.lfo_amount
= ch
->editable_state
.lfo_amount
;
1035 ch
->editable_state
.lfo
= ch
->_
.lfo
;
1036 ch
->editable_state
.lfo_amount
= ch
->_
.lfo_amount
;
1040 if( ch
->editble_state_write_mask
& AUDIO_EDIT_SPACIAL
)
1041 v4_copy( ch
->editable_state
.spacial_falloff
,ch
->_
.spacial_falloff
);
1043 v4_copy( ch
->_
.spacial_falloff
,ch
->editable_state
.spacial_falloff
);
1046 /* currently readonly, i guess */
1047 ch
->editable_state
.pan_target
= ch
->_
.pan_target
;
1048 ch
->editable_state
.pan
= ch
->_
.pan
;
1049 ch
->editble_state_write_mask
= 0x00;
1052 for( int i
=0; i
<AUDIO_LFOS
; i
++ )
1054 audio_lfo
*lfo
= &vg_audio
.oscillators
[ i
];
1056 if( lfo
->editble_state_write_mask
& AUDIO_EDIT_LFO_WAVE
)
1058 lfo
->_
.wave_type
= lfo
->editable_state
.wave_type
;
1060 if( lfo
->_
.wave_type
== k_lfo_polynomial_bipolar
)
1062 lfo
->_
.polynomial_coefficient
=
1063 lfo
->editable_state
.polynomial_coefficient
;
1064 lfo
->sqrt_polynomial_coefficient
=
1065 sqrtf(lfo
->_
.polynomial_coefficient
);
1069 if( lfo
->editble_state_write_mask
& AUDIO_EDIT_LFO_PERIOD
)
1073 float t
= lfo
->time
;
1074 t
/= (float)lfo
->_
.period
;
1076 lfo
->_
.period
= lfo
->editable_state
.period
;
1077 lfo
->time
= lfo
->_
.period
* t
;
1082 lfo
->_
.period
= lfo
->editable_state
.period
;
1086 lfo
->editble_state_write_mask
= 0x00;
1089 dsp_update_tunings();
1094 * ------------------------------------------------------------- */
1095 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ )
1097 audio_channel
*ch
= &vg_audio
.channels
[i
];
1099 if( ch
->activity
== k_channel_activity_wake
)
1101 if( audio_channel_load_source( ch
) )
1102 ch
->activity
= k_channel_activity_alive
;
1104 ch
->activity
= k_channel_activity_error
;
1110 * -------------------------------------------------------- */
1111 int frame_count
= byte_count
/(2*sizeof(float));
1114 float *pOut32F
= (float *)stream
;
1115 for( int i
=0; i
<frame_count
*2; i
++ )
1118 for( int i
=0; i
<AUDIO_LFOS
; i
++ )
1120 audio_lfo
*lfo
= &vg_audio
.oscillators
[i
];
1121 lfo
->time_startframe
= lfo
->time
;
1124 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ )
1126 audio_channel
*ch
= &vg_audio
.channels
[i
];
1128 if( ch
->activity
== k_channel_activity_alive
)
1131 ch
->_
.lfo
->time
= ch
->_
.lfo
->time_startframe
;
1133 u32 remaining
= frame_count
,
1138 audio_channel_mix( ch
, pOut32F
+subpos
);
1139 remaining
-= AUDIO_MIX_FRAME_SIZE
;
1140 subpos
+= AUDIO_MIX_FRAME_SIZE
*2;
1145 vg_profile_begin( &_vg_prof_dsp
);
1147 for( int i
=0; i
<frame_count
; i
++ )
1148 vg_dsp_process( pOut32F
+ i
*2, pOut32F
+ i
*2 );
1150 vg_profile_end( &_vg_prof_dsp
);
1154 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ )
1156 audio_channel
*ch
= &vg_audio
.channels
[i
];
1157 ch
->readable_activity
= ch
->activity
;
1160 /* Profiling information
1161 * ----------------------------------------------- */
1162 vg_profile_increment( &_vg_prof_audio_decode
);
1163 vg_profile_increment( &_vg_prof_audio_mix
);
1164 vg_profile_increment( &_vg_prof_dsp
);
1166 vg_prof_audio_mix
= _vg_prof_audio_mix
;
1167 vg_prof_audio_decode
= _vg_prof_audio_decode
;
1168 vg_prof_audio_dsp
= _vg_prof_dsp
;
1170 vg_audio
.samples_last
= frame_count
;
1172 if( vg_audio
.debug_ui
)
1174 vg_dsp_update_texture();
1180 VG_STATIC
void audio_clip_load( audio_clip
*clip
, void *lin_alloc
)
1182 if( lin_alloc
== NULL
)
1183 lin_alloc
= vg_audio
.audio_pool
;
1185 /* load in directly */
1186 u32 format
= clip
->flags
& AUDIO_FLAG_FORMAT
;
1188 /* TODO: This contains audio_lock() and unlock, but i don't know why
1189 * can probably remove them. Low priority to check this */
1191 if( format
== k_audio_format_vorbis
)
1194 clip
->data
= vg_file_read( lin_alloc
, clip
->path
, &clip
->size
);
1198 vg_fatal_exit_loop( "Audio failed to load" );
1200 float mb
= (float)(clip
->size
) / (1024.0f
*1024.0f
);
1201 vg_info( "Loaded audio clip '%s' (%.1fmb)\n", clip
->path
, mb
);
1203 else if( format
== k_audio_format_stereo
)
1205 vg_fatal_exit_loop( "Unsupported format (Stereo uncompressed)" );
1207 else if( format
== k_audio_format_bird
)
1209 u32 len
= strlen( clip
->path
),
1210 size
= synth_bird_memory_requirement( len
);
1212 if( size
> AUDIO_DECODE_SIZE
)
1213 vg_fatal_exit_loop( "Bird code too long\n" );
1216 clip
->data
= vg_linear_alloc( lin_alloc
, size
);
1218 synth_bird_load( clip
->data
, clip
->path
, len
);
1222 vg_linear_clear( vg_mem
.scratch
);
1225 stb_vorbis_alloc alloc
= {
1226 .alloc_buffer
= vg_linear_alloc( vg_mem
.scratch
, AUDIO_DECODE_SIZE
),
1227 .alloc_buffer_length_in_bytes
= AUDIO_DECODE_SIZE
1230 void *filedata
= vg_file_read( vg_mem
.scratch
, clip
->path
, &fsize
);
1233 stb_vorbis
*decoder
= stb_vorbis_open_memory(
1234 filedata
, fsize
, &err
, &alloc
);
1238 vg_error( "stb_vorbis_open_memory failed on '%s' (%d)\n",
1240 vg_fatal_exit_loop( "Vorbis decode error" );
1243 /* only mono is supported in uncompressed */
1244 u32 length_samples
= stb_vorbis_stream_length_in_samples( decoder
),
1245 data_size
= length_samples
* sizeof(i16
);
1248 clip
->data
= vg_linear_alloc( lin_alloc
, vg_align8(data_size
) );
1249 clip
->size
= length_samples
;
1252 int read_samples
= stb_vorbis_get_samples_i16_downmixed(
1253 decoder
, clip
->data
, length_samples
);
1255 if( read_samples
!= length_samples
)
1256 vg_fatal_exit_loop( "Decode error" );
1258 float mb
= (float)(data_size
) / (1024.0f
*1024.0f
);
1259 vg_info( "Loaded audio clip '%s' (%.1fmb) %u samples\n", clip
->path
, mb
,
1264 VG_STATIC
void audio_clip_loadn( audio_clip
*arr
, int count
, void *lin_alloc
)
1266 for( int i
=0; i
<count
; i
++ )
1267 audio_clip_load( &arr
[i
], lin_alloc
);
1270 VG_STATIC
void audio_require_clip_loaded( audio_clip
*clip
)
1272 if( clip
->data
&& clip
->size
)
1276 vg_fatal_exit_loop( "Must load audio clip before playing! \n" );
1283 VG_STATIC
void audio_debug_ui( m4x4f mtx_pv
)
1285 if( !vg_audio
.debug_ui
)
1290 glBindTexture( GL_TEXTURE_2D
, vg_dsp
.view_texture
);
1291 glTexSubImage2D( GL_TEXTURE_2D
, 0, 0, 0, 256, 256,
1292 GL_RGBA
, GL_UNSIGNED_BYTE
,
1293 vg_dsp
.view_texture_buffer
);
1297 * -----------------------------------------------------------------------
1300 float budget
= ((double)vg_audio
.samples_last
/ 44100.0) * 1000.0;
1301 vg_profile_drawn( (struct vg_profile
*[]){ &vg_prof_audio_decode
,
1303 &vg_prof_audio_dsp
}, 3,
1304 budget
, (ui_rect
){ 4, VG_PROFILE_SAMPLE_COUNT
*2 + 8,
1311 vg_uictx
.cursor
[0] = 512 + 8;
1312 vg_uictx
.cursor
[1] = VG_PROFILE_SAMPLE_COUNT
*2+8+24+12+12;
1313 vg_uictx
.cursor
[2] = 150;
1314 vg_uictx
.cursor
[3] = 12;
1316 ui_rect view_thing
= { 4, vg
.window_y
-512-4, 512, 512 };
1317 ui_push_image( view_thing
, vg_dsp
.view_texture
);
1319 float mb1
= 1024.0f
*1024.0f
,
1320 usage
= vg_linear_get_cur( vg_audio
.audio_pool
) / mb1
,
1321 total
= vg_linear_get_capacity( vg_audio
.audio_pool
) / mb1
,
1322 percent
= (usage
/total
) * 100.0f
;
1324 snprintf( perf
, 127, "Mem: %.1f/%.1fmb (%.1f%%)\n", usage
, total
, percent
);
1326 ui_text( vg_uictx
.cursor
, perf
, 1, 0 );
1327 vg_uictx
.cursor
[1] += 20;
1329 ui_rect overlap_buffer
[ AUDIO_CHANNELS
];
1330 u32 overlap_length
= 0;
1332 /* Draw audio stack */
1333 for( int i
=0; i
<AUDIO_CHANNELS
; i
++ )
1335 audio_channel
*ch
= &vg_audio
.channels
[i
];
1337 vg_uictx
.cursor
[2] = 400;
1338 vg_uictx
.cursor
[3] = 18;
1342 if( !ch
->allocated
)
1344 ui_fill_rect( vg_uictx
.cursor
, 0x50333333 );
1347 vg_uictx
.cursor
[1] += 1;
1351 const char *formats
[] =
1371 const char *activties
[] =
1380 u32 format_index
= (ch
->source
->flags
& AUDIO_FLAG_FORMAT
)>>9;
1382 snprintf( perf
, 127, "%02d %c%c%cD %s [%s] %4.2fv'%s'",
1384 (ch
->editable_state
.relinquished
)? 'r': '_',
1387 formats
[format_index
],
1388 activties
[ch
->readable_activity
],
1389 ch
->editable_state
.volume
,
1392 ui_fill_rect( vg_uictx
.cursor
, 0xa0000000 | ch
->colour
);
1394 vg_uictx
.cursor
[0] += 2;
1395 vg_uictx
.cursor
[1] += 2;
1396 ui_text( vg_uictx
.cursor
, perf
, 1, 0 );
1399 vg_uictx
.cursor
[1] += 1;
1401 if( AUDIO_FLAG_SPACIAL_3D
)
1404 v3_copy( ch
->editable_state
.spacial_falloff
, wpos
);
1407 m4x4_mulv( mtx_pv
, wpos
, wpos
);
1409 if( wpos
[3] > 0.0f
)
1411 v2_muls( wpos
, (1.0f
/wpos
[3]) * 0.5f
, wpos
);
1412 v2_add( wpos
, (v2f
){ 0.5f
, 0.5f
}, wpos
);
1415 wr
[0] = wpos
[0] * vg
.window_x
;
1416 wr
[1] = (1.0f
-wpos
[1]) * vg
.window_y
;
1420 for( int j
=0; j
<12; j
++ )
1423 for( int k
=0; k
<overlap_length
; k
++ )
1425 ui_px
*wk
= overlap_buffer
[k
];
1426 if( ((wr
[0] <= wk
[0]+wk
[2]) && (wr
[0]+wr
[2] >= wk
[0])) &&
1427 ((wr
[1] <= wk
[1]+wk
[3]) && (wr
[1]+wr
[3] >= wk
[1])) )
1440 ui_text( wr
, perf
, 1, 0 );
1442 ui_rect_copy( wr
, overlap_buffer
[ overlap_length
++ ] );
1450 #endif /* VG_AUDIO_H */