fcked it
authorhgn <hgodden00@gmail.com>
Sun, 2 Mar 2025 20:59:32 +0000 (20:59 +0000)
committerhgn <hgodden00@gmail.com>
Sun, 2 Mar 2025 20:59:32 +0000 (20:59 +0000)
vg_async.c
vg_audio.c
vg_audio.h
vg_console.c
vg_engine.c
vg_log.c
vg_log.h

index 9a3da53d1a77931ba7357921f753311096543df7..00dfb9bed0eaedd19f4e694991dea56e8e2903be 100644 (file)
@@ -98,19 +98,23 @@ void vg_run_async_checked(void)
 {
    SDL_AtomicLock( &vg_async.sl_index );
 
-   while( vg_async.start ){
+   while( vg_async.start )
+   {
       vg_async_item *entry = vg_async.start;
 
-      if( entry->fn_runner ){
+      if( entry->fn_runner )
+      {
          entry->fn_runner( entry->payload, entry->size );
          vg_async.start = entry->next;
 
-         if( vg_async.start == NULL ){
+         if( vg_async.start == NULL )
+         {
             vg_async.end = NULL;
 
             vg_linear_clear( vg_async.buffer );
 
-            if( !SDL_SemValue( vg_async.sem_wait_for_flush ) ){
+            if( !SDL_SemValue( vg_async.sem_wait_for_flush ) )
+            {
                SDL_SemPost( vg_async.sem_wait_for_flush );
             }
          }
@@ -122,7 +126,8 @@ void vg_run_async_checked(void)
       }
    }
 
-   if( !SDL_SemValue( vg_async.sem_wait_for_flush ) ){
+   if( !SDL_SemValue( vg_async.sem_wait_for_flush ) )
+   {
       SDL_SemPost( vg_async.sem_wait_for_flush );
    }
 
index 53d332790578e13357f078bd9c362b5732dab194..2ff5dcf0801e95107fecc54ac5ef089706f1c559 100644 (file)
@@ -9,30 +9,25 @@
 #include "vg_vorbis.h"
 #include <string.h>
 
-struct vg_audio_system vg_audio = 
+struct vg_audio _vg_audio = 
 { 
-   .external_global_volume = 1.0f, 
-   .dsp_enabled = 1 
+   .master_volume = 1.0f,
+   .dsp_enabled = 1
 };
 
 static struct vg_profile 
-   _vg_prof_audio_decode = {.mode = k_profile_mode_accum,
-                            .name = "[T2] audio_decode()"},
-   _vg_prof_audio_mix    = {.mode = k_profile_mode_accum,
-                            .name = "[T2] audio_mix()"},
-   _vg_prof_dsp          = {.mode = k_profile_mode_accum,
-                            .name = "[T2] dsp_process()"},
-   vg_prof_audio_decode,
-   vg_prof_audio_mix,
-   vg_prof_audio_dsp;
-
+   _vg_prof_audio_decode = { .mode = k_profile_mode_accum, .name = "[T2] audio_decode()" },
+   _vg_prof_audio_mix    = { .mode = k_profile_mode_accum, .name = "[T2] audio_mix()" },
+   _vg_prof_dsp          = { .mode = k_profile_mode_accum, .name = "[T2] dsp_process()" },
+   _vg_prof_audio_decode_ui,
+   _vg_prof_audio_mix_ui,
+   _vg_prof_audio_dsp_ui;
 
 static f64 _vg_audio_budget()
 {
    audio_lock();
-   f64 ms = ((double)vg_audio.samples_last / 44100.0) * 1000.0;
+   f64 ms = ((double)_vg_audio.samples_written_last_audio_frame / 44100.0) * 1000.0;
    audio_unlock();
-
    return ms;
 }
 
@@ -43,10 +38,12 @@ struct vg_profile_set static _vg_prof_audio =
    .get_budget = _vg_audio_budget,
    .list = 
    {
-      &vg_prof_audio_decode, &vg_prof_audio_mix, &vg_prof_audio_dsp
+      &_vg_prof_audio_decode_ui, &_vg_prof_audio_mix_ui, &_vg_prof_audio_dsp_ui
    }
 };
 
+#if 0
+
 
 /* 
  * These functions are called from the main thread and used to prevent bad 
@@ -77,55 +74,6 @@ static void audio_require_lock(void)
    abort();
 }
 
-void audio_lock(void)
-{
-   SDL_AtomicLock( &vg_audio.sl_sync );
-   audio_lock_checker_store(1);
-}
-
-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 );
-void vg_audio_device_init(void)
-{
-   SDL_AudioSpec spec_desired, spec_got;
-   spec_desired.callback = audio_mixer_callback;
-   spec_desired.channels = 2;
-   spec_desired.format   = AUDIO_F32;
-   spec_desired.freq     = 44100;
-   spec_desired.padding  = 0;
-   spec_desired.samples  = AUDIO_FRAME_SIZE;
-   spec_desired.silence  = 0;
-   spec_desired.size     = 0;
-   spec_desired.userdata = NULL;
-
-   vg_audio.sdl_output_device = 
-      SDL_OpenAudioDevice( vg_audio.device_choice.buffer, 0, 
-                           &spec_desired, &spec_got,0 );
-
-   vg_info( "Start audio device (%u, F32, %u) @%s\n", 
-               spec_desired.freq,
-               AUDIO_FRAME_SIZE,
-               vg_audio.device_choice.buffer );
-
-   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_error( 
-         "SDL_OpenAudioDevice failed. Your default audio device must support:\n"
-         "  Frequency: 44100 hz\n"
-         "  Buffer size: 512\n"
-         "  Channels: 2\n"
-         "  Format: s16 or f32\n" );
-   }
-}
-
 /* 
  * thread 1
  */
@@ -143,13 +91,13 @@ void audio_channel_init( audio_channel *ch, audio_clip *clip, u32 flags )
 {
    audio_require_lock();
    ch->group = 0;
-   ch->source = clip;
+   ch->clip = clip;
    ch->flags = flags;
    ch->colour = 0x00333333;
 
-   if( (ch->source->flags & AUDIO_FLAG_FORMAT) == k_audio_format_bird )
+   if( (ch->clip->flags & AUDIO_FLAG_FORMAT) == k_audio_format_bird )
       strcpy( ch->name, "[array]" );
-   else if( (ch->source->flags & AUDIO_FLAG_FORMAT) == k_audio_format_gen )
+   else if( (ch->clip->flags & AUDIO_FLAG_FORMAT) == k_audio_format_gen )
       strcpy( ch->name, "[program]" );
    else
       vg_strncpy( clip->path, ch->name, 32, k_strncpy_always_add_null );
@@ -261,14 +209,17 @@ void audio_channel_set_sampling_rate( audio_channel *ch, float rate )
    ch->editble_state_write_mask |= AUDIO_EDIT_SAMPLING_RATE;
 }
 
+/* Review: this is never called with instant set to 1 */
 void audio_channel_edit_volume( audio_channel *ch, f32 new_vol, int instant )
 {
    audio_require_lock();
-   if( instant ){
+   if( instant )
+   {
       ch->editable_state.volume = new_vol;
       ch->editble_state_write_mask |= AUDIO_EDIT_VOLUME;
    }
-   else{
+   else
+   {
       audio_channel_slope_volume( ch, 0.05f, new_vol );
    }
 }
@@ -395,7 +346,7 @@ void audio_set_lfo_frequency( int id, float freq )
  */
 int audio_channel_load_source( audio_channel *ch )
 {
-   u32 format = ch->source->flags & AUDIO_FLAG_FORMAT;
+   u32 format = ch->clip->flags & AUDIO_FLAG_FORMAT;
 
    if( format == k_audio_format_vorbis ){
       /* Setup vorbis decoder */
@@ -411,16 +362,16 @@ int audio_channel_load_source( audio_channel *ch )
 
       int err;
       stb_vorbis *decoder = stb_vorbis_open_memory( 
-            ch->source->data,
-            ch->source->size, &err, &alloc );
+            ch->clip->data,
+            ch->clip->size, &err, &alloc );
 
       if( !decoder ){
          vg_error( "stb_vorbis_open_memory failed on '%s' (%d)\n", 
-                     ch->source->path, err );
+                     ch->clip->path, err );
          return 0;
       }
       else{
-         ch->source_length = stb_vorbis_stream_length_in_samples( decoder );
+         ch->clip_length = stb_vorbis_stream_length_in_samples( decoder );
          ch->handle.vorbis = decoder;
       }
    }
@@ -430,20 +381,20 @@ int audio_channel_load_source( audio_channel *ch )
       u8 *buf = (u8*)vg_audio.decode_buffer;
       struct synth_bird *loc = (void *)&buf[AUDIO_DECODE_SIZE*index];
 
-      memcpy( loc, ch->source->data, ch->source->size );
+      memcpy( loc, ch->clip->data, ch->clip->size );
       synth_bird_reset( loc );
 
       ch->handle.bird = loc;
-      ch->source_length = synth_bird_get_length_in_samples( loc );
+      ch->clip_length = synth_bird_get_length_in_samples( loc );
    }
    else if( format == k_audio_format_stereo ){
-      ch->source_length = ch->source->size / 2;
+      ch->clip_length = ch->clip->size / 2;
    }
    else if( format == k_audio_format_gen ){
-      ch->source_length = 0xffffffff;
+      ch->clip_length = 0xffffffff;
    }
    else{
-      ch->source_length = ch->source->size;
+      ch->clip_length = ch->clip->size;
    }
 
    return 1;
@@ -502,10 +453,10 @@ static void audio_channel_get_samples( audio_channel *ch,
    u32 remaining = count;
    u32 buffer_pos = 0;
 
-   u32 format = ch->source->flags & AUDIO_FLAG_FORMAT;
+   u32 format = ch->clip->flags & AUDIO_FLAG_FORMAT;
 
    while( remaining ){
-      u32 samples_this_run = VG_MIN(remaining, ch->source_length - ch->cursor);
+      u32 samples_this_run = VG_MIN(remaining, ch->clip_length - ch->cursor);
       remaining -= samples_this_run;
 
       float *dst = &buf[ buffer_pos * 2 ]; 
@@ -523,7 +474,7 @@ static void audio_channel_get_samples( audio_channel *ch,
                samples_this_run );
 
          if( read_samples != samples_this_run ){
-            vg_warn( "Invalid samples read (%s)\n", ch->source->path );
+            vg_warn( "Invalid samples read (%s)\n", ch->clip->path );
 
             for( int i=0; i<samples_this_run; i++ ){
                dst[i*2+0] = 0.0f;
@@ -535,11 +486,11 @@ static void audio_channel_get_samples( audio_channel *ch,
          synth_bird_generate_samples( ch->handle.bird, dst, samples_this_run );
       }
       else if( format == k_audio_format_gen ){
-         void (*fn)( void *data, f32 *buf, u32 count ) = ch->source->func;
-         fn( ch->source->data, dst, samples_this_run );
+         void (*fn)( void *data, f32 *buf, u32 count ) = ch->clip->func;
+         fn( ch->clip->data, dst, samples_this_run );
       }
       else{
-         i16 *src_buffer = ch->source->data,
+         i16 *src_buffer = ch->clip->data,
              *src        = &src_buffer[ch->cursor];
 
          audio_decode_uncompressed_mono( src, samples_this_run, dst );
@@ -597,7 +548,7 @@ static void audio_channel_mix( audio_channel *ch, float *buffer )
          framevol_l *= (vol * 0.5f) * (1.0f - pan);
          framevol_r *= (vol * 0.5f) * (1.0f + pan);
 
-         if( !(ch->source->flags & AUDIO_FLAG_NO_DOPPLER) ){
+         if( !(ch->clip->flags & AUDIO_FLAG_NO_DOPPLER) ){
             const float vs = 323.0f;
 
             float dv = v3_dot(delta,vg_audio.internal_listener_velocity);
@@ -718,7 +669,7 @@ static void audio_mixer_callback( void *user, u8 *stream, int byte_count )
 
       if( ch->activity == k_channel_activity_alive )
       {
-         if( (ch->cursor >= ch->source_length) && 
+         if( (ch->cursor >= ch->clip_length) && 
                !(ch->flags & AUDIO_FLAG_LOOP) )
          {
             ch->activity = k_channel_activity_end;
@@ -743,7 +694,7 @@ static void audio_mixer_callback( void *user, u8 *stream, int byte_count )
       {
          ch->_ = ch->editable_state;
          ch->cursor = 0;
-         ch->source_length = 0;
+         ch->clip_length = 0;
          ch->activity = k_channel_activity_wake;
       }
 
@@ -945,10 +896,9 @@ static void audio_mixer_callback( void *user, u8 *stream, int byte_count )
 
    if( vg_audio.inspector_open )
    {
-      vg_prof_audio_mix = _vg_prof_audio_mix;
-      vg_prof_audio_decode = _vg_prof_audio_decode;
-      vg_prof_audio_dsp = _vg_prof_dsp;
-
+      _vg_prof_audio_mix_ui = _vg_prof_audio_mix;
+      _vg_prof_audio_decode_ui = _vg_prof_audio_decode;
+      _vg_prof_audio_dsp_ui = _vg_prof_dsp;
       vg_audio.samples_last = frame_count;
    }
 
@@ -1090,6 +1040,53 @@ static void audio_require_clip_loaded( audio_clip *clip )
    vg_fatal_error( "Must load audio clip before playing! \n" );
 }
 
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+static void _vg_audio_mixer( void *user, u8 *stream, int byte_count )
+{
+   int sample_count = byte_count/(2*sizeof(f32));
+   
+   f32 *output_stereo = (f32 *)stream;
+   for( int i=0; i<sample_count*2; i ++ )
+      output_stereo[i] = 0.0f;
+
+   audio_lock();
+   _vg_audio.samples_written_last_audio_frame = sample_count;
+   audio_unlock();
+}
+
 /* 
  * Debugging
  */
@@ -1098,8 +1095,12 @@ struct vg_audio_view_data
    i32 view_3d;
 };
 
-static void cb_vg_audio_view( ui_context *ctx, ui_rect rect, 
-                              struct vg_magi_panel *magi )
+static f32 audio_volume_integer_to_float( i32 volume )
+{
+   return (f32)volume / (f32)AUDIO_VOLUME_100;
+}
+
+static void cb_vg_audio_view( ui_context *ctx, ui_rect rect, struct vg_magi_panel *magi )
 {
    struct vg_audio_view_data *vd = magi->data;
 
@@ -1115,14 +1116,14 @@ static void cb_vg_audio_view( ui_context *ctx, ui_rect rect,
        /* Draw audio stack */
        for( int i=0; i<AUDIO_CHANNELS; i ++ )
    {
-      audio_channel *ch = &vg_audio.channels[i];
+      audio_channel *ch = &_vg_audio.channels[i];
 
       ui_rect row;
       ui_split( panel, k_ui_axis_h, 18, 1, row, panel );
 
       bool show_row = ui_clip( rect, row, row );
 
-      if( !ch->allocated )
+      if( ch->activity == k_channel_activity_none )
       {
          if( show_row )
             ui_fill( ctx, row, 0x50333333 );
@@ -1159,21 +1160,22 @@ static void cb_vg_audio_view( ui_context *ctx, ui_rect rect,
          "error"
       };
 
-      u32 format_index = (ch->source->flags & AUDIO_FLAG_FORMAT)>>9;
+      u32 format_index = (ch->clip->flags & AUDIO_FLAG_FORMAT)>>9;
+      f32 volume = audio_volume_integer_to_float( ch->volume );
 
       snprintf( perf, 127, "%02d[%#06x]%c%c%cD %s [%s] %4.2fv'%s'", 
-               i, ch->group,
-               (ch->editable_state.relinquished)? 'r': '_',
-               0?                                 'r': '_',
-               0?                                 '3': '2',
-               formats[format_index],
-               activties[ch->readable_activity],
-               ch->editable_state.volume,
-               ch->name );
+                i, ch->group,
+                (ch->flags & AUDIO_FLAG_RELINQUISHED)? 'r': '_',
+                0?                                     'r': '_',
+                0?                                     '3': '2',
+                formats[format_index],
+                activties[ch->activity],
+                volume,
+                ch->ui_name );
 
       if( show_row )
       {
-         ui_fill( ctx, row, 0xa0000000 | ch->colour );
+         ui_fill( ctx, row, 0xa0000000 | ch->ui_colour );
          ui_text( ctx, row, perf, 1, k_ui_align_middle_left, 0 );
       }
       
@@ -1181,7 +1183,7 @@ static void cb_vg_audio_view( ui_context *ctx, ui_rect rect,
       if( vd->view_3d && (ch->flags & AUDIO_FLAG_SPACIAL_3D) )
       {
          v4f wpos;
-         v3_copy( ch->editable_state.spacial_falloff, wpos );
+         v3_copy( ch->spacial_falloff, wpos );
 
          wpos[3] = 1.0f;
          m4x4_mulv( vg.pv, wpos, wpos );
@@ -1229,19 +1231,19 @@ static void cb_vg_audio_view( ui_context *ctx, ui_rect rect,
 
 static void cb_vg_audio_close( struct vg_magi_panel *me )
 {
-   vg_audio.inspector_open = 0;
+   _vg_audio.inspector_open = 0;
    free( me->data );
 }
 
 static int cmd_vg_audio( int argc, const char *argv[] )
 {
-   if( vg_audio.inspector_open )
+   if( _vg_audio.inspector_open )
    {
       vg_error( "Only 1 audio inspector at a time.\n" );
       return 0;
    }
 
-   vg_audio.inspector_open = 1;
+   _vg_audio.inspector_open = 1;
    ui_px w = 800, h=8*18;
    struct vg_magi_panel *magi = _vg_magi_open( w,h, VG_MAGI_ALL );
    magi->title = "Audio inspector";
@@ -1258,27 +1260,71 @@ static int cmd_vg_audio( int argc, const char *argv[] )
 void vg_audio_register(void)
 {
    vg_console_reg_cmd( "vg_audio", cmd_vg_audio, NULL );
-   vg_console_reg_var( "volume", &vg_audio.external_global_volume,
-                        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,
-                        k_var_dtype_i32, VG_VAR_PERSISTENT );
+   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, k_var_dtype_i32, VG_VAR_PERSISTENT );
+}
+
+void audio_lock(void)
+{
+   SDL_LockMutex( _vg_audio.mutex );
+}
+
+void audio_unlock(void)
+{
+   SDL_UnlockMutex( _vg_audio.mutex );
+}
+
+void vg_audio_device_init(void)
+{
+   SDL_AudioSpec spec_desired, spec_got;
+   spec_desired.callback = _vg_audio_mixer;
+   spec_desired.channels = 2;
+   spec_desired.format   = AUDIO_F32;
+   spec_desired.freq     = 44100;
+   spec_desired.padding  = 0;
+   spec_desired.samples  = AUDIO_FRAME_SIZE;
+   spec_desired.silence  = 0;
+   spec_desired.size     = 0;
+   spec_desired.userdata = NULL;
+
+   _vg_audio.sdl_output_device = SDL_OpenAudioDevice( _vg_audio.device_choice.buffer, 0, 
+                                                      &spec_desired, &spec_got, 0 );
+
+   vg_info( "Start audio device (%u, F32, %u) @%s\n", spec_desired.freq, AUDIO_FRAME_SIZE, 
+            _vg_audio.device_choice.buffer );
+
+   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_error( 
+         "SDL_OpenAudioDevice failed. Your default audio device must support (or transcode from):\n"
+         "  Sample rate: 44100 hz\n"
+         "  Buffer size: 512 samples\n"
+         "  Channels: 2\n"
+         "  Format: s16 or f32\n" );
+   }
 }
 
 void vg_audio_init(void)
 {
+   _vg_audio.mutex = SDL_CreateMutex();
+   if( _vg_audio.mutex == NULL )
+      vg_fatal_error( "SDL2: %s\n", SDL_GetError() );
+
    _vg_profile_reg_set( &_vg_prof_audio );
 
    /* allocate memory */
    /* 32mb fixed */
-   vg_audio.audio_pool = 
-      vg_create_linear_allocator( vg_mem.rtmemory, 1024*1024*32, 
-                                  VG_MEMORY_SYSTEM );
+   _vg_audio.data_allocator = 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_audio.decoding_buffer = vg_linear_alloc( vg_mem.rtmemory, decode_size );
 
    vg_dsp_init();
    vg_audio_device_init();
@@ -1286,6 +1332,6 @@ void vg_audio_init(void)
 
 void vg_audio_free(void)
 {
-   SDL_CloseAudioDevice( vg_audio.sdl_output_device );
+   SDL_CloseAudioDevice( _vg_audio.sdl_output_device );
 }
 
index ce299a4589157cf6c548fb011420dd80db5efc1c..bae314bd4dae4cbfbacac467c32d8ba0544be4ec 100644 (file)
@@ -20,6 +20,7 @@
 #define AUDIO_FLAG_NO_DSP     0x10
 #define AUDIO_FLAG_WORLD      0x20
 #define AUDIO_FLAG_FORMAT     0x1E00
+#define AUDIO_FLAG_RELINQUISHED 0x2000
 
 enum audio_format
 {
@@ -43,8 +44,8 @@ enum audio_format
 };
 
 #define AUDIO_DECODE_SIZE     (1024*256)  /* 256 kb decoding buffers */
-#define AUDIO_MUTE_VOLUME     0.0f
-#define AUDIO_BASE_VOLUME     1.0f
+
+#define AUDIO_VOLUME_100 500000000
 
 typedef struct audio_clip audio_clip;
 typedef struct audio_channel audio_channel;
@@ -55,10 +56,9 @@ struct audio_clip
    union 
    {
       const char *path;
-      void *func;
+      void *generative_function;
 
-      u64 _p64_; /* force width to be 64 because we save this structure on
-                    disk in Skaterift yay */
+      u64 __serialized_pointer_width0;
    };
 
    u32 flags;
@@ -66,12 +66,119 @@ struct audio_clip
 
    union
    { 
-      void *data;
-
-      u64 _p64;
+      void *any_data;
+      u64 __serialized_pointer_width1;
    };
 };
 
+struct audio_lfo
+{
+   u32 time, period_in_samples;
+
+   enum lfo_wave_type
+   {
+      k_lfo_triangle,
+      k_lfo_square,
+      k_lfo_saw,
+      k_lfo_polynomial_bipolar
+   }
+   wave_type;
+
+   f32 polynomial_coefficient;
+   u32 flags;
+};
+
+#define LFO_FLAG_PERIOD_CHANGED 0x1
+
+struct audio_channel
+{
+   /* properties */
+   char ui_name[32];
+   u32  ui_colour;
+   u32 flags;
+   u16 group;
+
+   enum channel_activity
+   {
+      k_channel_activity_none,
+      k_channel_activity_allocation,
+      k_channel_activity_alive,
+      k_channel_activity_pause,
+      k_channel_activity_end,
+      k_channel_activity_error
+   }
+   activity;
+
+   audio_clip *clip;
+   u32 clip_length;
+
+   union
+   {
+      struct synth_bird *bird;
+      stb_vorbis *vorbis;
+   }
+   decoder_handle;
+
+   u32 cursor;
+
+   i32 volume, volume_target, volume_slew_rate_per_sample;
+   i32 pan, pan_target, pan_slew_rate_per_sample;
+
+   f32 sampling_rate_multiplier;
+
+   v4f spacial_falloff; /* xyz, range */
+
+   audio_lfo *lfo;
+   f32 lfo_attenuation_amount; /* multiply volume by (1 + value) */
+};
+
+
+struct vg_audio
+{
+   SDL_AudioDeviceID sdl_output_device;
+   vg_str device_choice; /* buffer is null? use default from OS */
+
+   void *data_allocator; /* allocator for practically static sound data */
+   void *decoding_buffer; /* place where raw samples get decoded into */
+
+   SDL_mutex *mutex;
+   u32 samples_written_last_audio_frame;
+
+   audio_lfo lfos[ AUDIO_LFOS ];
+   audio_channel channels[ AUDIO_CHANNELS ];
+   stb_vorbis_alloc vorbis_decoders[ AUDIO_CHANNELS ];
+
+   bool inspector_open;
+   i32 dsp_enabled;
+
+   v3f listener_position,
+       listener_right_ear_direction,
+       listener_velocity;
+
+   f32 master_volume_ui;
+   i32 master_volume;
+}
+extern _vg_audio;
+
+void vg_audio_register(void);
+void vg_audio_device_init(void);
+void vg_audio_init(void);
+void vg_audio_free(void);
+
+void audio_clip_load( audio_clip *clip, void *lin_alloc );
+void audio_clip_loadn( audio_clip *arr, int count, void *lin_alloc );
+
+void audio_lock(void);
+void audio_unlock(void);
+
+void audio_channel_init( audio_channel *ch, audio_clip *clip, u32 flags );
+void audio_channel_group( audio_channel *ch, u16 group );
+audio_channel *audio_get_first_idle_channel(void);
+audio_channel *audio_get_group_idle_channel( u16 group, u32 max_count );
+audio_channel *audio_get_group_first_active_channel( u16 group );
+
+#if 0
+
 struct vg_audio_system
 {
    SDL_AudioDeviceID sdl_output_device;
@@ -112,47 +219,44 @@ struct vg_audio_system
 
    struct audio_channel
    {
-      int allocated;
+      /* properties */
+      char name[32];
+      u32 flags;
+      u32 colour;
       u16 group;
 
-      char name[32];       /* only editable while allocated == 0 */
-      audio_clip *source;  /* ... */
-      u32 flags;           /* ... */
-      u32 colour;          /* ... */
+      audio_clip *source;
+      u32 source_length;
 
-      /* internal non-readable state 
-       * -----------------------------*/
-      u32 cursor, source_length;
+      u32 cursor;
 
+#if 0
       float volume_movement_start,
             pan_movement_start;
-
       u32 volume_movement,
           pan_movement;
+#endif
 
-      union{
+      union
+      {
          struct synth_bird *bird;
          stb_vorbis *vorbis;
       }
       handle;
-
       stb_vorbis_alloc vorbis_alloc;
 
-      enum channel_activity{
+      enum channel_activity
+      {
+         k_channel_activity_none,
+         k_channel_activity_allocation,
          k_channel_activity_reset,   /* will advance if allocated==1, to wake */
          k_channel_activity_wake,    /* will advance to either of next two */
          k_channel_activity_alive,
          k_channel_activity_end,
          k_channel_activity_error
       }
-      activity,
-      readable_activity;
-   
-      /* 
-       * editable structure, can be modified inside _lock and _unlock
-       * the edit mask tells which to copy into internal _, or to discard
-       * ----------------------------------------------------------------------
-       */
+      activity;
+#if 0
       struct channel_state{
          int   relinquished;
 
@@ -172,6 +276,9 @@ struct vg_audio_system
       }
       _, editable_state;
       u32 editble_state_write_mask;
+#endif
+
+
    }
    channels[ AUDIO_CHANNELS ];
 
@@ -224,3 +331,5 @@ audio_channel *audio_oneshot( audio_clip *clip, f32 volume, f32 pan );
 void audio_set_lfo_wave( int id, enum lfo_wave_type type, f32 coefficient );
 void audio_set_lfo_frequency( int id, float freq );
 int audio_channel_load_source( audio_channel *ch );
+
+#endif
index a57c1a26744c89206a5477129966ab20d78b595a..0a726268e85d6c351e613389f0b03075c3d20587 100644 (file)
@@ -649,7 +649,8 @@ void vg_console_draw( ui_context *ctx )
 {
        if( !vg_console.enabled ) return;
 
-   SDL_AtomicLock( &vg_log.print_sl );
+   if( SDL_LockMutex( vg_log.mutex ) )
+      vg_fatal_error( "" );
 
        int ptr = vg_log.log_line_current;
    int const fh = ctx->font->sy, log_lines = 32;
@@ -721,12 +722,12 @@ void vg_console_draw( ui_context *ctx )
          }
          else text_colour = ui_colourcont( ctx, k_ui_bg );
 
-         ui_text( ctx, rect_suggest, vg_console.suggestions[i].str, 1,
-                  k_ui_align_left, text_colour );
+         ui_text( ctx, rect_suggest, vg_console.suggestions[i].str, 1, k_ui_align_left, text_colour );
 
          rect_suggest[1] += fh;
       }
    }
 
-   SDL_AtomicUnlock( &vg_log.print_sl );
+   if( SDL_UnlockMutex( vg_log.mutex ) )
+      vg_fatal_error( "" );
 }
index 6f0d519cb598d25deb82329a223590191920d6cb..e5236667b04b2e82419b7921e8f21cfe983c5f5a 100644 (file)
@@ -737,14 +737,10 @@ void vg_enter( int argc, char *argv[], const char *window_name )
    vg_console_init();
    vg_magi_init();
    
-   vg_console_reg_var( "vg_fps_limit", &vg.fps_limit, 
-                        k_var_dtype_i32, VG_VAR_PERSISTENT );
-   vg_console_reg_var( "vg_vsync", &vg.vsync, 
-                        k_var_dtype_i32, VG_VAR_PERSISTENT );
-   vg_console_reg_var( "vg_quality", &vg.quality_profile, 
-                        k_var_dtype_i32, VG_VAR_PERSISTENT );
-   vg_console_reg_var( "vg_screen_mode", &vg.screen_mode,
-                        k_var_dtype_i32, VG_VAR_PERSISTENT );
+   vg_console_reg_var( "vg_fps_limit", &vg.fps_limit, k_var_dtype_i32, VG_VAR_PERSISTENT );
+   vg_console_reg_var( "vg_vsync", &vg.vsync, k_var_dtype_i32, VG_VAR_PERSISTENT );
+   vg_console_reg_var( "vg_quality", &vg.quality_profile, k_var_dtype_i32, VG_VAR_PERSISTENT );
+   vg_console_reg_var( "vg_screen_mode", &vg.screen_mode, k_var_dtype_i32, VG_VAR_PERSISTENT );
 
    vg_audio_register();
    vg_console_load_autos();
@@ -877,7 +873,7 @@ static vg_settings = {
                       .actual_value = &vg_settings.temp_audio_choice,
                       .options = NULL, .option_count = 0 },
    .dsp = { .label = "Audio effects (reverb etc.)",
-             .actual_value = &vg_audio.dsp_enabled,
+             .actual_value = &_vg_audio.dsp_enabled,
              .options = vg_settings_dsp_enum, .option_count=2 },
 };
 
@@ -1121,13 +1117,13 @@ static void vg_settings_audio_apply(void)
 {
    if( vg_settings_enum_diff( &vg_settings.audio_devices ) )
    {
-      if( vg_audio.sdl_output_device )
+      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 );
+         vg_info( "Closing audio device %d\n", _vg_audio.sdl_output_device );
+         SDL_CloseAudioDevice( _vg_audio.sdl_output_device );
       }
       
-      vg_strfree( &vg_audio.device_choice );
+      vg_strfree( &_vg_audio.device_choice );
 
       if( vg_settings.audio_devices.new_value == -1 ){ }
       else if( vg_settings.audio_devices.new_value == -2 )
@@ -1138,7 +1134,7 @@ static void vg_settings_audio_apply(void)
       {
          struct ui_enum_opt *selected = NULL, *oi;
 
-     for( int i=0; i<vg_settings.audio_devices.option_count; i ++ )
+         for( int i=0; i<vg_settings.audio_devices.option_count; i ++ )
          {
             oi = &vg_settings.audio_devices.options[i];
 
@@ -1149,22 +1145,17 @@ static void vg_settings_audio_apply(void)
             }
          }
 
-         vg_strnull( &vg_audio.device_choice, NULL, -1 );
-         vg_strcat( &vg_audio.device_choice, oi->alias );
+         vg_strnull( &_vg_audio.device_choice, NULL, -1 );
+         vg_strcat( &_vg_audio.device_choice, oi->alias );
       }
 
       vg_audio_device_init();
-      *vg_settings.audio_devices.actual_value = 
-         vg_settings.audio_devices.new_value;
+      *vg_settings.audio_devices.actual_value = vg_settings.audio_devices.new_value;
    }
 
    audio_lock();
    if( vg_settings_enum_diff( &vg_settings.dsp ) )
-   {
-      *vg_settings.dsp.actual_value =
-         vg_settings.dsp.new_value;
-   }
-
+      *vg_settings.dsp.actual_value = vg_settings.dsp.new_value;
    audio_unlock();
 }
 
@@ -1212,12 +1203,15 @@ void vg_settings_open(void)
       oi->value = i;
    }
 
-   if( vg_audio.device_choice.buffer ){
+   if( _vg_audio.device_choice.buffer )
+   {
       vg_settings.temp_audio_choice = -2;
 
-      for( int i=0; i<count; i ++ ){
+      for( int i=0; i<count; i ++ )
+      {
          struct ui_enum_opt *oi = &options[i+1];
-         if( !strcmp( oi->alias, vg_audio.device_choice.buffer ) ){
+         if( !strcmp( oi->alias, _vg_audio.device_choice.buffer ) )
+         {
             vg_settings.temp_audio_choice = oi->value;
             break;
          }
index cb168e6f38d12a76c3085f05c75fc162ccb61f33..1a042afcde19319c0af9f22ea52e771e5d9b08f5 100644 (file)
--- a/vg_log.c
+++ b/vg_log.c
@@ -19,13 +19,33 @@ static void _vg_log_append_line( const char *str )
       vg_log.log_line_current = 0;
 }
 
-void _vg_logx_va( FILE *file, 
-                         const char *location, const char *prefix,
-                         const char *colour,
-                         const char *fmt, va_list args )
+void vg_log_init(void)
 {
+   vg_log.initialized = 1;
 #ifdef VG_ENGINE
-   SDL_AtomicLock( &vg_log.print_sl );
+   vg_log.mutex = SDL_CreateMutex();
+   if( vg_log.mutex == NULL )
+   {
+      printf( "SDL2 Error: %s\n", SDL_GetError() );
+      exit(-1);
+   }
+#endif
+}
+
+void _vg_logx_va( FILE *file, const char *location, const char *prefix,
+                              const char *colour,
+                              const char *fmt, va_list args )
+{
+   if( vg_log.initialized == 0 )
+   {
+      printf( "vg_log not initialized before use. (call vg_log_init()).\n" );
+      exit(-1);
+      return;
+   }
+
+#ifdef VG_ENGINE
+   if( SDL_LockMutex( vg_log.mutex ) )
+      vg_fatal_error( "" );
 #endif
 
        char buffer[4096], line[96];
@@ -62,11 +82,9 @@ void _vg_logx_va( FILE *file,
          {
 #ifdef VG_ENGINE
             const char *thread_colours[] = { KGRN, KMAG, KCYN, KYEL, KBLU };
-            const char *colour = thread_colours[
-               (vg_thread_purpose() % VG_ARRAY_LEN( thread_colours ))];
+            const char *colour = thread_colours[(vg_thread_purpose() % VG_ARRAY_LEN( thread_colours ))];
 
-            fprintf( file, "%s%u|"KNRM"%.32s", 
-                     colour, vg_thread_purpose(), location );
+            fprintf( file, "%s%u|"KNRM"%.32s", colour, vg_thread_purpose(), location );
 #else
             fprintf( file, KNRM "%.32s", location );
 #endif
@@ -74,8 +92,7 @@ void _vg_logx_va( FILE *file,
 
          _vg_log_append_line( line );
          fputs( line, file );
-         line_length = snprintf( line, 90, "%s       " KNRM "%c%s ", 
-                                 colour, marker, colour );
+         line_length = snprintf( line, 90, "%s       " KNRM "%c%s ", colour, marker, colour );
       }
 
       if( c == '\0' ) break;
@@ -83,7 +100,8 @@ void _vg_logx_va( FILE *file,
    }
 
 #ifdef VG_ENGINE
-   SDL_AtomicUnlock( &vg_log.print_sl );
+   if( SDL_UnlockMutex( vg_log.mutex ) )
+      vg_fatal_error( "" );
 #endif
 }
 
index ebfa59d6bc30938207194d1a6c22ca9b45deb500..1af78722250c5cf6da7708fd60c7cb0abb5fbfd6 100644 (file)
--- a/vg_log.h
+++ b/vg_log.h
@@ -48,12 +48,16 @@ struct vg_log
    char log[64][96];
    u32  log_line_count, log_line_current;
 
+   bool initialized;
 #ifdef VG_ENGINE
-   SDL_SpinLock print_sl;
+   SDL_mutex *mutex;
 #endif
 }
 extern vg_log;
 
+void vg_log_init(void);
+void vg_log_free(void);
+
 void vg_logx( FILE *file, 
               const char *location, const char *prefix, 
               const char *colour,