-
- /* only mono is supported in uncompressed */
- u32 length_samples = stb_vorbis_stream_length_in_samples( decoder ),
- data_size = length_samples * sizeof(i16);
-
- audio_lock();
- clip->data = vg_linear_alloc( lin_alloc, data_size );
- clip->size = length_samples;
- audio_unlock();
-
- int read_samples = stb_vorbis_get_samples_i16_downmixed(
- decoder, clip->data, length_samples );
-
- if( read_samples != length_samples )
- vg_fatal_exit_loop( "Decode error" );
-
- float mb = (float)(data_size) / (1024.0f*1024.0f);
- vg_info( "Loaded audio clip '%s' (%.1fmb) %u samples\n", clip->path, mb,
- length_samples );
- }
-
- /* load in directly */
- else if( clip->source_mode == k_audio_source_compressed )
- {
- audio_lock();
- clip->data = vg_file_read( lin_alloc, clip->path, &clip->size );
- audio_unlock();
-
- if( !clip->data )
- vg_fatal_exit_loop( "Audio failed to load" );
-
- float mb = (float)(clip->size) / (1024.0f*1024.0f);
- vg_info( "Loaded audio clip '%s' (%.1fmb)\n", clip->path, mb );
- }
-}
-
-VG_STATIC void audio_clip_loadn( audio_clip *arr, int count, void *lin_alloc )
-{
- for( int i=0; i<count; i++ )
- audio_clip_load( &arr[i], lin_alloc );
-}
-
-/* Mark change to be uploaded through queue system */
-VG_STATIC void audio_player_commit( audio_player *sys )
-{
- audio_require_lock();
-
- if( vg_audio.queue_len >= vg_list_size( vg_audio.entity_queue ) )
- {
- vg_warn( "Audio commit queue full\n" );
- return;
- }
-
- if( sys->enqued )
- {
- vg_warn( "[2] Audio commit spamming; already enqued (%s)\n", sys->name );
- return;
- }
-
- sys->enqued = 1;
- audio_entity *ent = &vg_audio.entity_queue[ vg_audio.queue_len ++ ];
- ent->info = sys->info;
- ent->player = sys;
-}
-
-VG_STATIC void audio_require_init( audio_player *player )
-{
- if( player->init )
- return;
-
- audio_unlock();
- vg_fatal_exit_loop( "Must init audio player before playing! \n" );
-}
-
-VG_STATIC void audio_require_clip_loaded( audio_clip *clip )
-{
- if( clip->data && clip->size )
- return;
-
- audio_unlock();
- vg_fatal_exit_loop( "Must load audio clip before playing! \n" );
-}
-
-/* Play a clip using player. If its already playing something, it will
- * fadeout quickly and start the next sound */
-VG_STATIC void audio_player_playclip( audio_player *player, audio_clip *clip )
-{
- audio_require_lock();
- audio_require_init( player );
- audio_require_clip_loaded( clip );
-
- if( player->info.flags & AUDIO_FLAG_KILL )
- {
- vg_error( "Can't start audio clip on player that is/has disconnected" );
- return;
- }
-
- if( player->enqued )
- {
- vg_warn( "[1] Audio commit spamming; already enqued (%s)\n",
- player->name );
- return;
- }
-
- player->info.source = clip;
- audio_player_commit( player );
-}
-
-VG_STATIC void audio_play_oneshot( audio_clip *clip, float volume )
-{
- audio_require_lock();
- audio_require_clip_loaded( clip );
-
- if( vg_audio.queue_len >= vg_list_size( vg_audio.entity_queue ) )
- {
- vg_warn( "Audio commit queue full\n" );
- return;
- }
-
- audio_entity *ent = &vg_audio.entity_queue[ vg_audio.queue_len ++ ];
-
- ent->info.flags = AUDIO_FLAG_ONESHOT;
- ent->info.pan = 0.0f;
- ent->info.source = clip;
- ent->info.vol = volume;
- ent->player = NULL;
-}
-
-VG_STATIC void audio_player_init( audio_player *player )
-{
- player->active_entity = AATREE_PTR_NIL;
- player->init = 1;
-}
-
-/*
- * Effects
- */
-
-/*
- * Safety enforced Get/set attributes
- */
-
-VG_STATIC int audio_player_is_playing( audio_player *sys )
-{
- audio_require_lock();
-
- if( sys->active_entity != AATREE_PTR_NIL )
- return 1;
- else
- return 0;
-}
-
-VG_STATIC void audio_player_set_position( audio_player *sys, v3f pos )
-{
- audio_require_lock();
- v3_copy( pos, sys->info.world_position );
-}
-
-VG_STATIC void audio_player_set_vol( audio_player *sys, float vol )
-{
- audio_require_lock();
- sys->info.vol = vol;
-}
-
-VG_STATIC float audio_player_get_vol( audio_player *sys )
-{
- audio_require_lock();
- return sys->info.vol;
-}
-
-VG_STATIC void audio_player_set_pan( audio_player *sys, float pan )
-{
- audio_require_lock();
- sys->info.pan = pan;
-}
-
-VG_STATIC float audio_player_get_pan( audio_player *sys )
-{
- audio_require_lock();
- return sys->info.pan;
-}
-
-VG_STATIC void audio_player_set_flags( audio_player *sys, u32 flags )
-{
- audio_require_lock();
- sys->info.flags = flags;
-}
-
-VG_STATIC u32 audio_player_get_flags( audio_player *sys )
-{
- audio_require_lock();
- return sys->info.flags;
-}
-
-
-/*
- * Debugging
- */
-
-VG_STATIC void audio_debug_ui( m4x4f mtx_pv )
-{
- if( !vg_audio.debug_ui )
- return;
-
- /* Get data */
- struct sound_info
- {
- const char *name;
- u32 cursor, flags, length;
- v3f pos;
- float vol;
- }
- infos[ SFX_MAX_SYSTEMS ];
- int num_systems = 0;
-
- audio_lock();
-
- for( int i=0; i<SFX_MAX_SYSTEMS; i ++ )
- {
- struct active_audio_player *aap = &vg_audio.active_players[i];
-
- if( !aap->active )
- continue;
-
- audio_entity *ent = &aap->ent;
- struct sound_info *snd = &infos[ num_systems ++ ];
-
- snd->name = ent->name;
- snd->cursor = ent->cur;
- snd->flags = ent->info.flags;
- snd->length = ent->length;
- snd->vol = ent->info.vol*100.0f;
- v3_copy( ent->info.world_position, snd->pos );
- }
-
- float budget = ((double)vg_audio.samples_last / 44100.0) * 1000.0;
- vg_profile_drawn( (struct vg_profile *[]){ &vg_prof_audio_decode,
- &vg_prof_audio_mix }, 2,
- budget, (ui_rect){ 4, VG_PROFILE_SAMPLE_COUNT*2 + 8,
- 250, 0 }, 3 );
-
- audio_unlock();
-
- char perf[128];
-
- /* Draw UI */
- vg_uictx.cursor[0] = 258;
- vg_uictx.cursor[1] = VG_PROFILE_SAMPLE_COUNT*2+8+24+12;
- vg_uictx.cursor[2] = 150;
- vg_uictx.cursor[3] = 12;