From 4bfaf318265027e52181b2447c7d9497d68d2b54 Mon Sep 17 00:00:00 2001 From: hgn Date: Sat, 30 Dec 2023 12:53:38 +0000 Subject: [PATCH] switching output audio devices --- vg.h | 4 +- vg_audio.h | 58 ++++++++++++-------- vg_profiler.h | 8 +++ vg_settings_menu.h | 134 +++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 166 insertions(+), 38 deletions(-) diff --git a/vg.h b/vg.h index 7822a95..82f95fc 100644 --- a/vg.h +++ b/vg.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2021-2023 Harry Godden (hgn) - All Rights Reserved */ +/* Copyright (C) 2021-2024 Mt.Zero Software - All Rights Reserved */ /* @@ -42,7 +42,7 @@ |IMP| | vg_render(void) | | | | | | | v -|IMP| | vg_ui(void) +|IMP| | vg_gui(void) | | | | | | '----' '___' diff --git a/vg_audio.h b/vg_audio.h index 11fb8f4..2bba7ea 100644 --- a/vg_audio.h +++ b/vg_audio.h @@ -96,6 +96,7 @@ struct audio_clip{ struct vg_audio_system{ SDL_AudioDeviceID sdl_output_device; + char *force_device_name; /* NULL: using default */ void *audio_pool, *decode_buffer; @@ -260,30 +261,9 @@ static void audio_unlock(void) audio_lock_checker_store(0); SDL_AtomicUnlock( &vg_audio.sl_sync ); } - static void audio_mixer_callback( void *user, u8 *stream, int frame_count ); -static void vg_audio_init(void) -{ - /* TODO: Move here? */ - vg_console_reg_var( "debug_audio", &vg_audio.debug_ui, - k_var_dtype_i32, VG_VAR_CHEAT ); - vg_console_reg_var( "debug_dsp", &vg_audio.debug_dsp, - k_var_dtype_i32, VG_VAR_CHEAT ); - vg_console_reg_var( "volume", &vg_audio.external_global_volume, - k_var_dtype_f32, VG_VAR_PERSISTENT ); - - /* allocate memory */ - /* 32mb fixed */ - vg_audio.audio_pool = - vg_create_linear_allocator( vg_mem.rtmemory, 1024*1024*32, - VG_MEMORY_SYSTEM ); - - /* fixed */ - u32 decode_size = AUDIO_DECODE_SIZE * AUDIO_CHANNELS; - vg_audio.decode_buffer = vg_linear_alloc( vg_mem.rtmemory, decode_size ); - - vg_dsp_init(); +static void vg_audio_device_init(void){ SDL_AudioSpec spec_desired, spec_got; spec_desired.callback = audio_mixer_callback; spec_desired.channels = 2; @@ -296,13 +276,20 @@ static void vg_audio_init(void) spec_desired.userdata = NULL; vg_audio.sdl_output_device = - SDL_OpenAudioDevice( NULL, 0, &spec_desired, &spec_got,0 ); + SDL_OpenAudioDevice( vg_audio.force_device_name, 0, + &spec_desired, &spec_got,0 ); + + vg_info( "Start audio device (%u, F32, %u) @%s\n", + spec_desired.freq, + AUDIO_FRAME_SIZE, + vg_audio.force_device_name ); if( vg_audio.sdl_output_device ){ SDL_PauseAudioDevice( vg_audio.sdl_output_device, 0 ); + vg_success( "Unpaused device %d.\n", vg_audio.sdl_output_device ); } else{ - vg_fatal_error( + vg_error( "SDL_OpenAudioDevice failed. Your default audio device must support:\n" " Frequency: 44100 hz\n" " Buffer size: 512\n" @@ -311,6 +298,29 @@ static void vg_audio_init(void) } } + +static void vg_audio_init(void){ + vg_console_reg_var( "debug_audio", &vg_audio.debug_ui, + k_var_dtype_i32, VG_VAR_CHEAT ); + vg_console_reg_var( "debug_dsp", &vg_audio.debug_dsp, + k_var_dtype_i32, VG_VAR_CHEAT ); + vg_console_reg_var( "volume", &vg_audio.external_global_volume, + k_var_dtype_f32, VG_VAR_PERSISTENT ); + + /* allocate memory */ + /* 32mb fixed */ + vg_audio.audio_pool = + vg_create_linear_allocator( vg_mem.rtmemory, 1024*1024*32, + VG_MEMORY_SYSTEM ); + + /* fixed */ + u32 decode_size = AUDIO_DECODE_SIZE * AUDIO_CHANNELS; + vg_audio.decode_buffer = vg_linear_alloc( vg_mem.rtmemory, decode_size ); + + vg_dsp_init(); + vg_audio_device_init(); +} + static void vg_audio_free(void) { vg_dsp_free(); diff --git a/vg_profiler.h b/vg_profiler.h index dfc47ef..d0106af 100644 --- a/vg_profiler.h +++ b/vg_profiler.h @@ -78,7 +78,11 @@ static void vg_profile_drawn( struct vg_profile **profiles, u32 count, int ptrs[8]; for( int i=0; ibuffer_current; +#else + ptrs[i] = 0; +#endif avgs[i] = 0.0f; } @@ -91,10 +95,14 @@ static void vg_profile_drawn( struct vg_profile **profiles, u32 count, f64 total = 0.0; for( int j=0; jsamples[ptrs[j]] * rate_mul, px = (total / (budget)) * sw, diff --git a/vg_settings_menu.h b/vg_settings_menu.h index 96fc6ea..68b2171 100644 --- a/vg_settings_menu.h +++ b/vg_settings_menu.h @@ -37,7 +37,8 @@ struct { u32 option_count; const char *label; } - vsync, quality, screenmode; + vsync, quality, screenmode, audio_devices; + i32 temp_audio_choice; int windowed_before[4]; } @@ -52,8 +53,10 @@ static vg_settings = { .options = vg_settings_quality_enum, .option_count = 3 }, .screenmode = { .label = "Type", .actual_value = &vg.screen_mode, - .options = vg_settings_screen_mode_enum, .option_count=3 } - + .options = vg_settings_screen_mode_enum, .option_count=3 }, + .audio_devices = { .label = "Audio Device", + .actual_value = &vg_settings.temp_audio_choice, + .options = NULL, .option_count = 0 } }; static void vg_settings_ui_draw_diff( ui_rect orig ){ @@ -251,6 +254,118 @@ static void vg_settings_video_gui( ui_rect panel ){ } } +static void vg_settings_audio_apply(void){ + if( vg_settings_enum_diff( &vg_settings.audio_devices ) ){ + if( vg_audio.sdl_output_device ){ + vg_info( "Closing audio device %d\n", vg_audio.sdl_output_device ); + SDL_CloseAudioDevice( vg_audio.sdl_output_device ); + } + + if( vg_audio.force_device_name ){ + free( vg_audio.force_device_name ); + vg_audio.force_device_name = NULL; + } + + if( vg_settings.audio_devices.new_value == -1 ){ } + else if( vg_settings.audio_devices.new_value == -2 ){ + vg_fatal_error( "Programming error\n" ); + } + else { + struct ui_enum_opt *selected = NULL, *oi; + + for( int i=0; ivalue == vg_settings.audio_devices.new_value ){ + selected = oi; + break; + } + } + + int len = strlen(oi->alias); + vg_audio.force_device_name = malloc(len+1); + memcpy( vg_audio.force_device_name, (void *)oi->alias, len+1 ); + } + + vg_audio_device_init(); + *vg_settings.audio_devices.actual_value = + vg_settings.audio_devices.new_value; + } +} + +static void vg_settings_audio_gui( ui_rect panel ){ + ui_rect rq; + ui_standard_widget( panel, rq, 1 ); + vg_settings_enum( &vg_settings.audio_devices, rq ); + + const char *string = "Apply"; + + ui_rect last_row; + ui_px height = (vg_ui.font->glyph_height + 18) * k_ui_scale; + ui_split( panel, k_ui_axis_h, -height, k_ui_padding, + panel, last_row ); + + if( ui_button( last_row, string ) == 1 ) + vg_settings_audio_apply(); +} + +static void vg_settings_open(void){ + vg.settings_open = 1; + + ui_settings_ranged_i32_init( &vg_settings.fps_limit ); + ui_settings_enum_init( &vg_settings.vsync ); + ui_settings_enum_init( &vg_settings.quality ); + ui_settings_enum_init( &vg_settings.screenmode ); + + /* Create audio options */ + int count = SDL_GetNumAudioDevices( 0 ); + + struct ui_enum_opt *options = malloc( sizeof(struct ui_enum_opt)*(count+1) ); + vg_settings.audio_devices.options = options; + vg_settings.audio_devices.option_count = count+1; + + struct ui_enum_opt *o0 = &options[0]; + o0->alias = "OS Default"; + o0->value = -1; + + for( int i=0; ialias = malloc( len+1 ); + memcpy( (void *)oi->alias, device_name, len+1 ); + oi->value = i; + } + + if( vg_audio.force_device_name ){ + vg_settings.temp_audio_choice = -2; + + for( int i=0; ialias, vg_audio.force_device_name ) ){ + vg_settings.temp_audio_choice = oi->value; + break; + } + } + } + else { + vg_settings.temp_audio_choice = -1; + } + + ui_settings_enum_init( &vg_settings.audio_devices ); +} + +static void vg_settings_close(void){ + vg.settings_open = 0; + + struct ui_enum_opt *options = vg_settings.audio_devices.options; + for( int i=1; i < vg_settings.audio_devices.option_count; i ++ ) + free( (void *)options[i].alias ); + free( vg_settings.audio_devices.options ); +} + static void vg_settings_gui(void){ ui_rect null; ui_rect screen = { 0, 0, vg.window_x, vg.window_y }; @@ -271,7 +386,7 @@ static void vg_settings_gui(void){ ui_split( title, k_ui_axis_v, title[2]-title[3], 2, title, quit_button ); if( ui_button_text( quit_button, "X", 1 ) == 1 ){ - vg.settings_open = 0; + vg_settings_close(); return; } @@ -284,17 +399,12 @@ static void vg_settings_gui(void){ if( page == 0 ){ vg_settings_video_gui( panel ); } + else if( page == 1 ) + vg_settings_audio_gui( panel ); } static int cmd_vg_settings_toggle( int argc, const char *argv[] ){ - vg.settings_open = !vg.settings_open; - - if( vg.settings_open ){ - ui_settings_ranged_i32_init( &vg_settings.fps_limit ); - ui_settings_enum_init( &vg_settings.vsync ); - ui_settings_enum_init( &vg_settings.quality ); - ui_settings_enum_init( &vg_settings.screenmode ); - } + vg_settings_open(); return 0; } -- 2.25.1