#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;
        float   vol;
        
        // Info
-       int ch, end, cur, cur_lagged;
+       u32 ch, end, cur;
        u32 flags;
        
+       int is_queued;
+       
        // Effects
        u32 fadeout, fadeout_current;
        
 #define SFX_A_FLAG_AUTOSTART 0x1
 #define SFX_A_FLAG_AUTOFREE  0x2
 
+/*
 static int sfx_save( sfx_system *sys );
 
 // Asynchronous load-to-system callback
        
        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" );
        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 )
        {
                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 };
                
                
                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 )
                        {
                                        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 ++ )
                                        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 );
                                
                        }
 
                        sys->cur = cursor;
-                       sys->cur_lagged = cursor;
                        sys->signal_average = avgvol / (float)(buffer_pos*2);
                        
                        break;
 
        // 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;
                }
                
 
        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
 
--- /dev/null
+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 );
+}