medium sized dollop
[vg.git] / src / vg / vg_audio.h
index 2171359eda030edc572e0e1d5fafdd0af589d1d8..8cdaa4acb744e1c165de6f95e0d663dbbec96b0f 100644 (file)
@@ -6,7 +6,16 @@
 #define MA_NO_GENERATION
 #define MA_NO_DECODING
 #define MA_NO_ENCODING
+#define MA_NO_WAV
+#define MA_NO_FLAC
+#define MA_NO_MP3
+#define MA_NO_ENGINE
+#define MA_NO_NODE_GRAPH
+#define MA_NO_RESOURCE_MANAGER
+
 #include "dr_soft/miniaudio.h"
+
+
 #include "vg/vg.h"
 #include "vg/vg_stdint.h"
 #include "vg/vg_platform.h"
 
 #include <time.h>
 
+#ifdef __GNUC__
+  #pragma GCC push_options
+  #pragma GCC optimize ("O3")
+#endif
+
 #define STB_VORBIS_MAX_CHANNELS 2
 #include "stb/stb_vorbis.h"
 
+#ifdef __GNUC__
+  #pragma GCC pop_options
+#endif
+
 #define SFX_MAX_SYSTEMS       32
 #define AUDIO_FLAG_LOOP       0x1
 #define AUDIO_FLAG_ONESHOT    0x2
@@ -102,8 +120,9 @@ static struct vg_audio_system
 
    /* synchro */
    int               sync_locked;
-   MUTEX_TYPE        mutex_checker;
-   MUTEX_TYPE        mutex_sync;
+
+   vg_mutex          mux_checker,
+                     mux_sync;
 
    /* Audio engine, thread 1 */
    struct active_audio_player
@@ -167,17 +186,17 @@ static void *audio_alloc( u32 size )
 static int audio_lock_checker_load(void)
 {
    int value;
-   MUTEX_LOCK( vg_audio.mutex_checker );
+   vg_mutex_lock( &vg_audio.mux_checker );
    value = vg_audio.sync_locked;
-   MUTEX_UNLOCK( vg_audio.mutex_checker );
+   vg_mutex_unlock( &vg_audio.mux_checker );
    return value;
 }
 
 static void audio_lock_checker_store( int value )
 {
-   MUTEX_LOCK( vg_audio.mutex_checker );
+   vg_mutex_lock( &vg_audio.mux_checker );
    vg_audio.sync_locked = value;
-   MUTEX_UNLOCK( vg_audio.mutex_checker );
+   vg_mutex_unlock( &vg_audio.mux_checker );
 }
 
 static void audio_require_lock(void)
@@ -185,19 +204,20 @@ static void audio_require_lock(void)
    if( audio_lock_checker_load() )
       return;
 
-   vg_exiterr( "Modifying sound effects systems requires locking\n" );
+   vg_error( "Modifying sound effects systems requires locking\n" );
+   abort();
 }
 
 static void audio_lock(void)
 {
-   MUTEX_LOCK( vg_audio.mutex_sync );
+   vg_mutex_lock( &vg_audio.mux_sync );
    audio_lock_checker_store(1);
 }
 
 static void audio_unlock(void)
 {
    audio_lock_checker_store(0);
-   MUTEX_UNLOCK( vg_audio.mutex_sync );
+   vg_mutex_unlock( &vg_audio.mux_sync );
 }
 
 
@@ -206,6 +226,9 @@ static void audio_mixer_callback( ma_device *pDevice, void *pOutBuf,
 
 static int vg_audio_init(void)
 {
+   vg_mutex_init( &vg_audio.mux_checker );
+   vg_mutex_init( &vg_audio.mux_sync );
+
    vg_convar_push( (struct vg_convar){
       .name = "debug_audio",
       .data = &vg_audio.debug_ui,
@@ -231,7 +254,7 @@ static int vg_audio_init(void)
    ma_device_config *dconf  = &vg_audio.miniaudio_dconfig;
    ma_device        *device = &vg_audio.miniaudio_device;
 
-    *dconf = ma_device_config_init( ma_device_type_playback );
+   *dconf = ma_device_config_init( ma_device_type_playback );
    dconf->playback.format    = ma_format_f32;
    dconf->playback.channels  = 2;
    dconf->sampleRate         = 44100;
@@ -256,16 +279,20 @@ static int vg_audio_init(void)
          return 0;
       }
    }
-
+   
+   vg_success( "Ready\n" );
    return 1;
 }
 
-static void vg_audio_free(void)
+static void vg_audio_free(void * nothing)
 {
    ma_device        *device = &vg_audio.miniaudio_device;
    ma_device_uninit( device );
 
    free( vg_audio.mem );
+
+   vg_mutex_free( &vg_audio.mux_checker );
+   vg_mutex_free( &vg_audio.mux_sync );
 }
 
 /* 
@@ -461,16 +488,32 @@ static void audio_system_cleanup(void)
  */
 static void audio_entity_spacialize( audio_entity *ent, float *vol, float *pan )
 {
+   if( ent->info.vol < 0.01f )
+   {
+      *vol = ent->info.vol;
+      *pan = 0.0f;
+      return;
+   }
+
    v3f delta;
    v3_sub( ent->info.world_position, vg_audio.listener_pos, delta );
 
-   float dist = v3_length( delta ),
-         attn = (dist / ent->info.vol) +1.0f;
+   float dist2 = v3_length2( delta );
 
-   v3_muls( delta, 1.0f/dist, delta );
+   if( dist2 < 0.0001f )
+   {
+      *pan = 0.0f;
+      *vol = 1.0f;
+   }
+   else
+   {
+      float dist = sqrtf( dist2 ),
+            attn = (dist / ent->info.vol) +1.0f;
 
-   *pan = v3_dot( vg_audio.listener_ears, delta );
-   *vol = 1.0f/(attn*attn);
+      v3_muls( delta, 1.0f/dist, delta );
+      *pan = v3_dot( vg_audio.listener_ears, delta );
+      *vol = 1.0f/(attn*attn);
+   }
 }
 
 static void audio_decode_uncompressed_mono( float *src, u32 count, float *dst )
@@ -664,7 +707,9 @@ static void audio_mixer_callback( ma_device *pDevice, void *pOutBuf,
       struct active_audio_player *aap = &vg_audio.active_players[i];
 
       if( aap->active )
+      {
          audio_entity_mix( i, pOut32F, frame_count );
+      }
    }
    
 #if 0
@@ -730,7 +775,8 @@ static float *audio_decompress_vorbis( const unsigned char *data, int len,
    if( !buffer )
    {
       stb_vorbis_close( pv );
-      vg_exit();
+      vg_error( "Failed to allocated memory for audio\n" );
+      return NULL;
    }
    
    int read_samples = stb_vorbis_get_samples_float_interleaved( 
@@ -762,7 +808,7 @@ static int audio_clip_load( audio_clip *clip )
 
    if( clip->source_mode == k_audio_source_mono )
    {
-      u32 samples;
+      u32 samples = 0;
       float *sound = audio_decompress_vorbis( filedata, file_len, 1, &samples );
       clip->data = sound;
       clip->len = samples;
@@ -833,9 +879,8 @@ static void audio_require_init( audio_player *player )
    if( player->init )
       return;
 
-   char err[128];
-   snprintf( err, 127, "Must init before playing! (%s)\n", player->name );
-   vg_exiterr( err );
+   vg_error( "Must init before playing! (%s)\n", player->name );
+   abort();
 }
 
 /* Play a clip using player. If its already playing something, it will 
@@ -890,6 +935,16 @@ static void audio_player_init( audio_player *player )
  * Safety enforced Get/set attributes
  */
 
+static int audio_player_is_playing( audio_player *sys )
+{
+   audio_require_lock();
+
+   if( sys->active_entity != AATREE_PTR_NIL )
+      return 1;
+   else 
+      return 0;
+}
+
 static void audio_player_set_position( audio_player *sys, v3f pos )
 {
    audio_require_lock();