switching output audio devices
authorhgn <hgodden00@gmail.com>
Sat, 30 Dec 2023 12:53:38 +0000 (12:53 +0000)
committerhgn <hgodden00@gmail.com>
Sat, 30 Dec 2023 12:53:38 +0000 (12:53 +0000)
vg.h
vg_audio.h
vg_profiler.h
vg_settings_menu.h

diff --git a/vg.h b/vg.h
index 7822a9595c8e7ae9ec5c87f91f9f25d191909584..82f95fcceab3a17469a552feee97b06d4528373f 100644 (file)
--- 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)
 |   | |      |
 |   |  '----'
 '___'
index 11fb8f46596465e6a0afae0e59728318fff60ea3..2bba7ea09ec4e4ea31fa806cf3519523844a6750 100644 (file)
@@ -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();
index dfc47ef1266d680b5fe1db657f4ad9b583870493..d0106af5d7eef89c6ffd3503d8715853aa1faf47 100644 (file)
@@ -78,7 +78,11 @@ static void vg_profile_drawn( struct vg_profile **profiles, u32 count,
    int ptrs[8];
 
    for( int i=0; i<count; i++ ){
+#if 0
       ptrs[i] = profiles[i]->buffer_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; j<count; j++ ){
+#if 0
          ptrs[j] --;
 
          if( ptrs[j] < 0 )
             ptrs[j] = VG_PROFILE_SAMPLE_COUNT-1;
+#else
+         ptrs[j] ++;
+#endif
 
          f64 sample  = (f64)profiles[j]->samples[ptrs[j]] * rate_mul,
                 px   = (total  / (budget)) * sw,
index 96fc6ea4725ff4bf0e433175ffcd456dc0b25655..68b2171a5c6f2b995a90f84afcc8911ae2429c4c 100644 (file)
@@ -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; i<vg_settings.audio_devices.option_count; i ++ ){
+            oi = &vg_settings.audio_devices.options[i];
+
+            if( oi->value == 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; i<count; i ++ ){
+      struct ui_enum_opt *oi = &options[i+1];
+
+      const char *device_name = SDL_GetAudioDeviceName( i, 0 );
+      int len = strlen(device_name);
+
+      oi->alias = 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; i<count; i ++ ){
+         struct ui_enum_opt *oi = &options[i+1];
+         if( !strcmp( oi->alias, 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;
 }