add pausing to audio
authorhgn <hgodden00@gmail.com>
Wed, 5 Mar 2025 13:44:51 +0000 (13:44 +0000)
committerhgn <hgodden00@gmail.com>
Wed, 5 Mar 2025 13:44:51 +0000 (13:44 +0000)
vg_audio.c
vg_audio.h
vg_engine.c

index e39ab802009a1a41ff153998def4fce1c34c8058..670b1da33b8ad11872d75fa6362136c755aed7a1 100644 (file)
@@ -330,6 +330,7 @@ audio_channel_id vg_audio_get_first_idle_channel(void)
          controls->sampling_rate_multiplier = 1.0f;
          controls->lfo_id = 0;
          controls->lfo_attenuation_amount = 0.0f;
+         controls->pause = 0;
          v4_copy( (v4f){0,0,0,1}, controls->spacial_falloff );
 
          struct audio_channel_state *state = get_audio_channel_state( id );
@@ -441,6 +442,13 @@ void vg_audio_set_channel_spacial_falloff( audio_channel_id id, v3f co, f32 rang
    vg_audio_add_channel_flags( id, AUDIO_FLAG_SPACIAL_3D );
 }
 
+void vg_audio_sync_ui_master_controls(void)
+{
+   vg_audio_assert_lock();
+   _vg_audio.controls.volume_target = ((f64)AUDIO_VOLUME_100) * _vg_audio.master_volume_ui;
+   _vg_audio.controls.dsp_enabled = _vg_audio.dsp_enabled_ui;
+}
+
 void vg_audio_set_channel_volume( audio_channel_id id, f64 volume, bool instant )
 {
    vg_audio_assert_lock();
@@ -584,6 +592,28 @@ bool vg_audio_flagged_stopped( u32 flag )
    return 1;
 }
 
+void vg_audio_set_channel_pause( audio_channel_id id, bool pause )
+{
+   vg_audio_assert_lock();
+   struct audio_channel_controls *controls = get_audio_channel_controls( id );
+   controls->pause = pause;
+}
+
+void vg_audio_set_flagged_pause( u32 flag, bool pause )
+{
+   vg_audio_assert_lock();
+   for( u32 id=1; id<=AUDIO_CHANNELS; id ++ )
+   {
+      audio_channel *channel = get_audio_channel( id );
+      if( channel->stage != k_channel_stage_none )
+      {
+         struct audio_channel_controls *controls = get_audio_channel_controls( id );
+         if( controls->flags & flag )
+            vg_audio_set_channel_pause( id, pause );
+      }
+   }
+}
+
 void vg_audio_oneshot_3d( audio_clip *clip, v3f co, f32 range, f32 volume, u16 group, u32 flags )
 {
    vg_audio_assert_lock();
@@ -902,12 +932,15 @@ static void audio_channel_mix( audio_channel_id id,
 
    vg_profile_begin( &_vg_prof_audio_mix );
 
+   /* TODO: Slew this */
+   f64 master_volume = (f64)_vg_audio.state.volume / (f64)AUDIO_VOLUME_100;
+
    for( u32 j=0; j<AUDIO_MIX_FRAME_SIZE; j++ )
    {
       audio_slew_i32( &state->volume, controls->volume_target, controls->volume_slew_rate_per_sample );
       audio_slew_i32( &state->pan,    controls->pan_target,    controls->pan_slew_rate_per_sample );
 
-      f64 v_c = (f64)state->volume / (f64)AUDIO_VOLUME_100;
+      f64 v_c = ((f64)state->volume / (f64)AUDIO_VOLUME_100) * master_volume;
 
       if( controls->lfo_id )
       {
@@ -980,16 +1013,25 @@ static void _vg_audio_mixer( void *user, u8 *stream, int byte_count )
    struct audio_lfo_controls lfo_controls[ AUDIO_LFOS ];
    u32 active_lfo_count = 0;
 
+   struct audio_master_state *master_state = &_vg_audio.state;
+
    vg_audio_lock();
    memcpy( &master_controls, &_vg_audio.controls, sizeof(struct audio_master_controls) );
+
    for( u32 id=1; id<=AUDIO_CHANNELS; id ++ )
    {
       audio_channel *channel = get_audio_channel( id );
       if( channel->stage == k_channel_stage_active )
       {
+         struct audio_channel_controls *controls = get_audio_channel_controls(id);
+         if( controls->pause ) 
+         {
+            channel->ui_activity = k_channel_activity_paused;
+            continue;
+         }
+
          active_channel_list[ active_channel_count ] = id;
-         memcpy( &channel_controls[ active_channel_count ], get_audio_channel_controls(id),
-                 sizeof( struct audio_channel_controls ) );
+         memcpy( &channel_controls[ active_channel_count ], controls, sizeof( struct audio_channel_controls ) );
          active_channel_count ++;
       }
    }
@@ -1011,6 +1053,9 @@ static void _vg_audio_mixer( void *user, u8 *stream, int byte_count )
    vg_audio_unlock();
 
    /* init step */
+   master_state->volume = master_controls.volume_target;
+   master_state->volume_at_frame_start = master_controls.volume_target;
+
    for( u32 i=0; i<active_channel_count; i ++ )
    {
       audio_channel_id id = active_channel_list[i];
@@ -1040,8 +1085,6 @@ static void _vg_audio_mixer( void *user, u8 *stream, int byte_count )
    }
 
    /* mix step */
-   bool dsp_enabled = 1;
-
    for( u32 dry_layer=0; dry_layer<=1; dry_layer ++ )
    {
       for( u32 i=0; i<active_channel_count; i ++ )
@@ -1052,7 +1095,7 @@ static void _vg_audio_mixer( void *user, u8 *stream, int byte_count )
 
          if( state->activity == k_channel_activity_playing )
          {
-            if( dsp_enabled )
+            if( master_controls.dsp_enabled )
             {
                if( controls->flags & AUDIO_FLAG_NO_DSP )
                {
@@ -1088,7 +1131,7 @@ static void _vg_audio_mixer( void *user, u8 *stream, int byte_count )
          }
       }
 
-      if( dsp_enabled )
+      if( master_controls.dsp_enabled )
       {
          if( !dry_layer )
          {
@@ -1393,8 +1436,8 @@ void vg_audio_register(void)
 {
    vg_console_reg_cmd( "vg_audio", cmd_vg_audio, NULL );
    vg_console_reg_var( "volume", &_vg_audio.master_volume_ui, k_var_dtype_f32, VG_VAR_PERSISTENT );
-   vg_console_reg_var( "vg_audio_device", &_vg_audio.device_choice, k_var_dtype_str, VG_VAR_PERSISTENT );
    vg_console_reg_var( "vg_dsp", &_vg_audio.dsp_enabled_ui, k_var_dtype_i32, VG_VAR_PERSISTENT );
+   vg_console_reg_var( "vg_audio_device", &_vg_audio.device_choice, k_var_dtype_str, VG_VAR_PERSISTENT );
 }
 
 void vg_audio_device_init(void)
@@ -1450,7 +1493,7 @@ void vg_audio_init(void)
 
    struct audio_master_controls *master_controls = &_vg_audio.controls;
    master_controls->dsp_enabled = _vg_audio.dsp_enabled_ui;
-   master_controls->volume = (f64)_vg_audio.master_volume_ui * (f64)AUDIO_VOLUME_100;
+   master_controls->volume_target = (f64)_vg_audio.master_volume_ui * (f64)AUDIO_VOLUME_100;
    v3_copy( (v3f){1,0,0}, master_controls->listener_right_ear_direction );
    v3_zero( master_controls->listener_velocity );
    v3_zero( master_controls->listener_position );
index 87414c8c66fe9045011448768580320d36dd71d1..f47f450a766ffbd5110bdf61462ccdefc3f8b889 100644 (file)
@@ -150,6 +150,7 @@ struct audio_channel
       f32 lfo_attenuation_amount; /* multiply volume by (1 + value) */
 
       v4f spacial_falloff; /* xyz, range */
+      bool pause;
    }
    controls;
 
@@ -194,17 +195,24 @@ struct vg_audio
 
    struct audio_master_controls
    {
-      i32 dsp_enabled;
       v3f listener_position,
           listener_right_ear_direction,
           listener_velocity;
-      i32 volume;
+      
+      bool dsp_enabled;
+      i32 volume_target;
    }
    controls;
 
-   i32 dsp_enabled_ui;
-   f32 master_volume_ui;
+   struct audio_master_state
+   {
+      i32 volume, volume_at_frame_start;
+   }
+   state;
    bool always_keep_clips_compressed;
+
+   f32 master_volume_ui;
+   i32 dsp_enabled_ui;
 }
 extern _vg_audio;
 
@@ -241,11 +249,14 @@ void vg_audio_set_lfo_frequency( audio_channel_id lfo_id, f32 freq );
 void vg_audio_start_lfo( audio_channel_id lfo_id );
 
 /* high level functions */
+void vg_audio_sync_ui_master_controls(void);
 audio_channel_id vg_audio_crossfade( audio_channel_id id, audio_clip *new_clip, f32 transition_seconds );
 void vg_audio_oneshot_3d( audio_clip *clip, v3f co, f32 range, f32 volume, u16 group, u32 flags );
 void vg_audio_oneshot( audio_clip *clip, f32 volume, f32 pan, u16 group, u32 flags );
+void vg_audio_set_channel_pause( audio_channel_id id, bool pause );
 
 /* half measures... Don't expect these functions to stay. */
 void vg_audio_fadeout_flagged_audio( u32 flag, f32 length );
 bool vg_audio_flagged_stopped( u32 flag );
 bool vg_audio_is_channel_using_clip( audio_channel_id id, audio_clip *clip );
+void vg_audio_set_flagged_pause( u32 flag, bool pause );
index 4ff81ef639eb7ddb7b4700d7311f322f888683c1..e9151a59cd30f237eb0b3b6a4f4c42ef4e488c1b 100644 (file)
@@ -516,6 +516,10 @@ static void _vg_gameloop(void)
 
       vg.time_frame_delta = 0.0;
       vg.time_spinning = 0;
+
+      vg_audio_lock();
+      vg_audio_sync_ui_master_controls();
+      vg_audio_unlock();
    }
 }
 
@@ -1152,10 +1156,8 @@ static void vg_settings_audio_apply(void)
       *vg_settings.audio_devices.actual_value = vg_settings.audio_devices.new_value;
    }
 
-   vg_audio_lock();
    if( vg_settings_enum_diff( &vg_settings.dsp ) )
       *vg_settings.dsp.actual_value = vg_settings.dsp.new_value;
-   vg_audio_unlock();
 }
 
 static void vg_settings_audio_gui( ui_context *ctx, ui_rect panel )