fixed REALLY bad threading bugs with audio
authorhgn <hgodden00@gmail.com>
Wed, 27 Oct 2021 04:01:26 +0000 (05:01 +0100)
committerhgn <hgodden00@gmail.com>
Wed, 27 Oct 2021 04:01:26 +0000 (05:01 +0100)
fishladder.c
fishladder_resources.h
vg/vg.h
vg/vg_audio.h
vg/vg_debug.h [new file with mode: 0644]
vg/vg_m.h
vg/vg_ui.h

index e6d2ef7da97ca18bc2f92965bd84fc7fd9898c97..d7a1f28343749ef16bbb47c3c8853af2cba18ad5 100644 (file)
@@ -597,6 +597,7 @@ void vg_update(void)
                else
                        world.selected = -1;
        }
+       else world.selected = -1;
        
        // Simulation stop/start
        if( vg_get_button_down("go") )
@@ -638,9 +639,10 @@ void vg_update(void)
        // Fish ticks
        if( world.simulating )
        {
-               while( world.sim_frame < (int)((vg_time-world.sim_start)*2.0f) )
+               while( world.sim_frame < (int)((vg_time-world.sim_start)*20.0f) )
                {
                        vg_info( "frame: %u\n", world.sim_frame );
+                       sfx_set_playrnd( &audio_random, &audio_system_balls_switching, 0, 5 );
                        
                        for( int i = 0; i < arrlen( world.io ); i ++ )
                        {
@@ -1100,4 +1102,5 @@ void vg_render(void)
 void vg_ui(void)
 {
        //ui_test();
+       sfx_internal_debug_overlay();
 }
index cd73f52899a380f01c0137c8194b7c72045dcde6..1f8c5454da860017005ac429a71fd2353df94cb3 100644 (file)
@@ -47,6 +47,19 @@ sound/rolling_01.ogg\0\
 sound/rolling_02.ogg\0"
 };
 
+sfx_set audio_random =
+{
+ .sources = "\
+sound/random_01.ogg\0\
+sound/random_02.ogg\0\
+sound/random_03.ogg\0\
+sound/random_04.ogg\0\
+sound/random_05.ogg\0\
+sound/random_06.ogg\0\
+sound/random_07.ogg\0\
+sound/random_08.ogg\0"
+};
+
 // One two or three layers of rolling noise
 sfx_system audio_system_balls_rolling =
 {
@@ -84,14 +97,17 @@ static void resource_load_main(void)
        sfx_set_init( &audio_tile_mod, NULL );
        sfx_set_init( &audio_splitter, NULL );
        sfx_set_init( &audio_rolls, NULL );
+       sfx_set_init( &audio_random, NULL );
 }
 
 static void resource_free_main(void)
 {
-       vg_tex2d_free( texture_list, vg_list_size( texture_list ) );    
+       vg_tex2d_free( texture_list, vg_list_size( texture_list ) );
+       
        sfx_set_free( &audio_tile_mod );
        sfx_set_free( &audio_splitter );
        sfx_set_free( &audio_rolls );
+       sfx_set_free( &audio_random );
 }
 
 // SHADERS
diff --git a/vg/vg.h b/vg/vg.h
index bd518c48bf6cea24de85413027c300f945f9b01c..33f177cedb5e210a691351551efe9bdae59e7c7b 100644 (file)
--- a/vg/vg.h
+++ b/vg/vg.h
@@ -47,6 +47,7 @@ float vg_time_delta;
 #include "vg/vg_tex.h"
 #include "vg/vg_input.h"
 #include "vg/vg_ui.h"
+#include "vg/vg_debug.h"
 
 #include "steam/steamworks_thin.h"
 
@@ -206,8 +207,6 @@ static void vg_init( int argc, char *argv[], const char *window_name )
                }
        }
        
-       vg_audio_init();
-       vg_register_exit( &vg_audio_free, "vg_audio_free" );
        vg_lines_init();
        vg_register_exit( &vg_lines_free, "vg_lines_free" );
        ui_default_init();
@@ -220,6 +219,9 @@ static void vg_init( int argc, char *argv[], const char *window_name )
        {
                vg_start();
        
+               vg_audio_init();
+               vg_register_exit( &vg_audio_free, "vg_audio_free" );
+       
                // Main gameloop
                while( !glfwWindowShouldClose( vg_window ) )
                {
index 35b36c5f07a13aac6395a83200b4008bc1f3e6a0..249bedc8f390452ba9a98adab4d6cbaecee7d535 100644 (file)
@@ -11,7 +11,7 @@
 #define SFX_FLAG_STEREO                0x2
 #define SFX_FLAG_REPEAT        0x4
 #define SFX_FLAG_GHOST         0x8
-#define FADEOUT_LENGTH                 441
+#define FADEOUT_LENGTH                 4410
 #define FADEOUT_DIVISOR        (1.f/(float)FADEOUT_LENGTH)
 
 typedef struct sfx_vol_control sfx_vol_control;
@@ -33,9 +33,11 @@ struct sfx_system
        float   vol;
        
        // Info
-       int ch, end, cur, cur_lagged;
+       u32 ch, end, cur;
        u32 flags;
        
+       int is_queued;
+       
        // Effects
        u32 fadeout, fadeout_current;
        
@@ -183,6 +185,7 @@ struct sfx_vorbis_a_to_inf
 #define SFX_A_FLAG_AUTOSTART 0x1
 #define SFX_A_FLAG_AUTOFREE  0x2
 
+/*
 static int sfx_save( sfx_system *sys );
 
 // Asynchronous load-to-system callback
@@ -217,16 +220,30 @@ void sfx_vorbis_a_to( sfx_system *sys, const char *strFileName, int channels, u3
        
        if( !sfx_vorbis_a( strFileName, channels, sfx_vorbis_a_to_c, inf ) )
                free( inf );
-}
+}*/
 
 // 0
 // ======================================================
 
-// Mark change to be uploaded to queue system
-static int sfx_save( sfx_system *sys )
+static int sfx_begin_edit( sfx_system *sys )
 {
        MUTEX_LOCK( sfx_mux_t01 );
+       
+       if( sys->is_queued )
+       {
+               MUTEX_UNLOCK( sfx_mux_t01 );
+               
+               vg_warn( "Sfx system locked for writing.. Spam is being created!\n" );
+               return 0;
+       }
+       
+       sys->is_queued = 1;
+       return 1;
+}
 
+// Mark change to be uploaded to queue system
+static int sfx_save( sfx_system *sys )
+{
        if( sfx_q_len >= SFX_MAX_SYSTEMS )
        {
                vg_error( "Warning: No free space in sound queue\n" );
@@ -366,36 +383,43 @@ void audio_mixer_callback( ma_device *pDevice, void *pOutBuf, const void *pInput
        while( sfx_q_len --> 0 )
        {
                sfx_system *src = sfx_q[sfx_q_len];
+               src->is_queued = 0;
+               
                sfx_system *clone;
                
                // This is a 'new' sound if thread_clone not set.
-               if( !src->thread_clone || src->flags & SFX_FLAG_ONESHOT )
+               if( !src->thread_clone || (src->flags & SFX_FLAG_ONESHOT) )
                {
-                       src->thread_clone = sfx_alloc();
-                       if( !src->thread_clone )
+                       clone = sfx_alloc();
+                       if( !clone )
                                break;
+                               
+                       src->thread_clone = clone;
                }
                else
                {
-                       // Modifying an active system spawns a small fadeout ghost system
-                       sfx_system *ghost_system = sfx_alloc();
-                       
-                       if( !ghost_system )
-                               break;
-                       
-                       ghost_system->source = src->source;
-                       ghost_system->ch = src->ch;
-                       ghost_system->end = src->end;
-                       ghost_system->cur = src->cur_lagged;
-                       ghost_system->flags = SFX_FLAG_GHOST;
-                       ghost_system->fadeout = FADEOUT_LENGTH;
-                       ghost_system->fadeout_current = FADEOUT_LENGTH;
-                       ghost_system->vol_src = src->vol_src;
-                       ghost_system->name = src->name;
-                       ghost_system->thread_clone = src;
-               }
+                       clone = src->thread_clone;
                
-               clone = src->thread_clone;
+                       // Modifying an active system's cursor spawns a small fadeout ghost system
+                       if( clone->cur != src->cur )
+                       {
+                               sfx_system *ghost_system = sfx_alloc();
+                               
+                               if( !ghost_system )
+                                       break;
+                               
+                               ghost_system->source = clone->source;
+                               ghost_system->ch = clone->ch;
+                               ghost_system->end = clone->end;
+                               ghost_system->cur = clone->cur;
+                               ghost_system->flags = SFX_FLAG_GHOST;
+                               ghost_system->fadeout = FADEOUT_LENGTH;
+                               ghost_system->fadeout_current = FADEOUT_LENGTH;
+                               ghost_system->vol_src = clone->vol_src;
+                               ghost_system->name = clone->name;
+                               ghost_system->thread_clone = src;
+                       }
+               }               
                
                // run replacement routine if one is waiting (todo: what is this?)
                if( src->replacement )
@@ -446,8 +470,7 @@ void audio_mixer_callback( ma_device *pDevice, void *pOutBuf, const void *pInput
        {
                sfx_system *sys = sfx_sys + i;
                
-               u32 cursor = sys->cur, buffer_pos = 0;
-               
+               u32 cursor = sys->cur, buffer_pos = 0;          
                float avgvol = 0.f;
                float pcf[2] = { 0.f, 0.0f };
                
@@ -456,7 +479,7 @@ void audio_mixer_callback( ma_device *pDevice, void *pOutBuf, const void *pInput
                
                while( frames_write )
                {
-                       u32 samples_this_run = vg_min( frames_write, sys->end - cursor );
+                       u32 samples_this_run = VG_MIN( frames_write, sys->end - cursor );
                
                        if( sys->fadeout )
                        {
@@ -468,7 +491,7 @@ void audio_mixer_callback( ma_device *pDevice, void *pOutBuf, const void *pInput
                                        break;
                                }
                                
-                               samples_this_run = vg_min( samples_this_run, sys->fadeout_current );
+                               samples_this_run = VG_MIN( samples_this_run, sys->fadeout_current );
                        }
                        
                        for( u32 j = 0; j < samples_this_run; j ++ )
@@ -482,10 +505,15 @@ void audio_mixer_callback( ma_device *pDevice, void *pOutBuf, const void *pInput
                                        vol *= (float)sys->fadeout_current * fadeout_divisor;
                                        sys->fadeout_current --;
                                }
+                               
+                               if( buffer_pos >= frameCount )
+                               {
+                                       break;
+                               }
 
                                pOut32F[ buffer_pos*2+0 ] += pcf[0] * vol;
                                pOut32F[ buffer_pos*2+1 ] += pcf[1] * vol;
-                                                               
+                               
                                avgvol += fabs( pcf[0] * vol );
                                avgvol += fabs( pcf[1] * vol );
                                
@@ -505,7 +533,6 @@ void audio_mixer_callback( ma_device *pDevice, void *pOutBuf, const void *pInput
                        }
 
                        sys->cur = cursor;
-                       sys->cur_lagged = cursor;
                        sys->signal_average = avgvol / (float)(buffer_pos*2);
                        
                        break;
@@ -514,25 +541,27 @@ void audio_mixer_callback( ma_device *pDevice, void *pOutBuf, const void *pInput
 
        // Redistribute sound systems
        MUTEX_LOCK( sfx_mux_t01 );
-       
-       unsigned int idx = 0, wr = 0;
+
+       u32 idx = 0, wr = 0;
        while( idx != sfx_sys_len )
        {
                sfx_system *src = sfx_sys + idx;
-       
+               
                // Keep only if cursor is before end or repeating
                if( src->cur < src->end || (src->flags & SFX_FLAG_REPEAT) ) 
                {
                        // Correct source pointer on persisitent originals since we shifted ID's
-                       if( !(src->flags & SFX_FLAG_ONESHOT) )
+                       if( !(src->flags & (SFX_FLAG_ONESHOT|SFX_FLAG_GHOST)) )
+                       {
                                src->thread_clone->thread_clone = sfx_sys + wr;
+                       }
                        
                        sfx_sys[ wr ++ ] = sfx_sys[ idx ];
                }
                else
                {
                        // Clear link on persistent sources (done playing)
-                       if( !(src->flags & SFX_FLAG_ONESHOT) )
+                       if( !(src->flags & (SFX_FLAG_ONESHOT|SFX_FLAG_GHOST)) )
                                src->thread_clone->thread_clone = NULL;
                }
                
@@ -616,21 +645,30 @@ static void sfx_set_playrnd( sfx_set *source, sfx_system *sys, int min_id, int m
 
        int pick = (rand() % (max_id-min_id)) + min_id;
 
-       sys->fadeout = 0;
-       sys->source = source->main;
-       sys->cur        = source->segments[ pick*2 + 0 ];
-       sys->end        = source->segments[ pick*2 + 1 ];
-       sys->ch                 = source->ch;
-       
-       sfx_save( sys );
+       if( sfx_begin_edit( sys ) )
+       {
+               sys->fadeout = 0;
+               sys->source = source->main;
+               sys->cur        = source->segments[ pick*2 + 0 ];
+               sys->end        = source->segments[ pick*2 + 1 ];
+               sys->ch                 = source->ch;
+               
+               sfx_save( sys );
+       }
 }
 
 static void sfx_system_fadeout( sfx_system *sys, u32 length_samples )
 {
-       sys->fadeout_current = length_samples;
-       sys->fadeout = length_samples;
+       if( sfx_begin_edit( sys ) )
+       {
+               sys->fadeout_current = length_samples;
+               sys->fadeout = length_samples;
+               
+               if( sys->thread_clone )
+                       sys->cur = sys->thread_clone->cur;
        
-       sfx_save( sys );
+               sfx_save( sys );
+       }
 }
 
 // Free set resources
diff --git a/vg/vg_debug.h b/vg/vg_debug.h
new file mode 100644 (file)
index 0000000..9f0ac1c
--- /dev/null
@@ -0,0 +1,73 @@
+static void sfx_internal_debug_overlay(void)
+{
+       // Grab values
+       struct sound_info
+       {
+               float signal;
+               const char *name;
+               u32 length, cursor, flags;
+       }
+       infos[ SFX_MAX_SYSTEMS ];
+       int num_systems;
+       
+       MUTEX_LOCK( sfx_mux_t01 );
+       
+       num_systems = sfx_sys_len;
+       
+       for( int i = 0; i < sfx_sys_len; i ++ )
+       {
+               sfx_system *sys = sfx_sys + i;
+               struct sound_info *snd = &infos[ i ];
+               
+               snd->signal = sys->signal_average;
+               snd->name = sys->name;
+               snd->length = sys->end;
+               snd->cursor = sys->cur;
+               snd->flags = sys->flags;                
+       }
+       
+       MUTEX_UNLOCK( sfx_mux_t01 );
+
+       // UI part
+       // ========
+
+       ui_begin( &ui_global_ctx, vg_window_x, vg_window_y );
+       
+       // TODO: Find a more elegent form for this
+       int mouse_state = 0;
+       if( vg_get_button( "primary" ) ) mouse_state = 2;
+       if( vg_get_button_down( "primary" ) ) mouse_state = 1;
+       if( vg_get_button_up( "primary" ) ) mouse_state = 3;
+               
+       ui_set_mouse( &ui_global_ctx, vg_mouse[0], vg_mouse[1], mouse_state );
+       
+       // Draw audio stack 
+       for( int i = 0; i < num_systems; i ++ )
+       {
+               ui_global_ctx.cursor[2] = 300;
+               ui_global_ctx.cursor[3] = 25;
+               
+               u32 alpha = (infos[i].flags & SFX_FLAG_GHOST)? 0x44000000: 0xff000000;
+
+               ui_new_node( &ui_global_ctx );
+               {       
+                       ui_fill_rect( &ui_global_ctx, ui_global_ctx.cursor, 0x00333333 | alpha );
+                       
+                       ui_global_ctx.cursor[2] = (int)(((float)infos[i].cursor / (float)infos[i].length) * 300.0f);
+                       ui_fill_rect( &ui_global_ctx, ui_global_ctx.cursor, 0x77ffffff );
+                       
+                       ui_text( &ui_global_ctx, infos[i].name, 2, 0 );
+               }
+               ui_end_down( &ui_global_ctx );
+               ui_global_ctx.cursor[1] += 1;
+       }
+       
+       ui_resolve( &ui_global_ctx );
+       
+       m3x3f view = M3X3_IDENTITY;
+       m3x3_translate( view, (v3f){ -1.0f, 1.0f, 0.0f } );
+       m3x3_scale( view, (v3f){ 1.0f/((float)vg_window_x*0.5f), -1.0f/((float)vg_window_y*0.5f), 1.0f } );
+       vg_lines_drawall( (float*)view );
+       
+       ui_draw( &ui_global_ctx );
+}
index 0c4ba358593af4927a59f6e6335906a5cf0e653c..cb98db2d1a5a64f060a5c150b9bdc9d663a6b3d3 100644 (file)
--- a/vg/vg_m.h
+++ b/vg/vg_m.h
@@ -17,6 +17,10 @@ static inline float vg_maxf( float a, float b )
        return a > b? a: b;
 }
 
+#define VG_MIN( A, B ) ((A)<(B)?(A):(B))
+#define VG_MAX( A, B ) ((A)>(B)?(A):(B))
+
+// Hopefully deprecate this!!
 static inline int vg_min( int a, int b )
 {
        return a < b? a: b;
index 45120fd8b03b0740d234459f876e043da28e345a..74ecc97988771f70a4a4f03d8e696fbec7ed0034 100644 (file)
@@ -35,7 +35,7 @@ SHADER_DEFINE( shader_ui,
 )
 
 #define UI_AUTO_FILL 0
-#define UI_DEBUG
+//#define UI_DEBUG
 
 // Types
 // ===========================================================================================================