+#include "common.h"
+static void audio_spacialize( sfx_system *sys,
+ v3f pos, v3f camera, v3f ears, float vol );
+
#ifndef AUDIO_H
#define AUDIO_H
-#include "common.h"
#include "world.h"
static float audio_occlusion_current = 0.0f,
static int k_audio_debug_soundscape = 0;
-sfx_vol_control audio_vol_all = { .val = 1.0f, .name = "All" };
-
sfx_set audio_board =
{
.sources = "sound/skate.ogg\0"
sfx_set_free( &audio_board );
}
+static void audio_spacialize( sfx_system *sys,
+ v3f pos, v3f camera, v3f ears, float vol )
+{
+ float attn = (v3_dist( pos, camera ) / vol) +1.0f;
+
+ v3f delta;
+ v3_sub( pos, camera, delta );
+ v3_normalize( delta );
+
+ float pan = v3_dot( ears, delta );
+
+ sys->vol = 1.0f/(attn*attn);
+ sys->pan = pan;
+}
+
static void audio_sample_occlusion( v3f origin )
{
float d = 0.0f,
for( int i=0; i<sample_count; i++ )
{
v3f dir;
- dir[0] = vg_randf();
- dir[1] = vg_randf();
- dir[2] = vg_randf();
-
- v3_muls( dir, 2.0f, dir );
- v3_sub( dir, (v3f){1.0f,1.0f,1.0f}, dir );
-
- v3_normalize( dir );
+ vg_rand_dir( dir );
ray_hit contact;
contact.dist = 15.0f;
char buf[64];
snprintf( buf, 31, "occlusion: %.5f", audio_occlusion_current );
- ui_global_ctx.cursor[0] = 10;
+ ui_global_ctx.cursor[0] = 250;
ui_global_ctx.cursor[1] = 10;
ui_global_ctx.cursor[2] = audio_occlusion_current * 200.0f;
ui_global_ctx.cursor[3] = 20;
class classtype_audio_system(Structure):
_pack_ = 1
- _fields_ = [("")]
+ _fields_ = [("sounds", subclass_audio_channel * 4),
+ ("len", c_uint32)]
class classtype_audio_zone(Structure):
_pack_ = 1
v3_muladds( p, p0, 3.0f*tt -ttt -3.0f*t +1.0f, p );
}
+/* TODO: he needs a home somewhere */
+sfx_vol_control audio_vol_all = { .val = 1.0f, .name = "All" };
+
#endif /* COMMON_H */
//glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
audio_debug_soundscapes();
+ world_audio_debug();
#if 0
static double last_b_press = 0.0;
*/
static void player_audio(void)
{
- audio_sample_occlusion( player.camera[3] );
-
- float speed = vg_minf(v3_length( player.rb.v )*0.1f,1.0f),
- attn = v3_dist( player.rb.co, player.camera[3] )+1.0f;
- attn = (1.0f/(attn*attn)) * speed;
+ sfx_lock();
static float air = 0.0f;
air = vg_lerpf(air, player.in_air? 1.0f: 0.0f, 5.0f*ktimestep);
-
+
+ /* Spacial info */
v3f ears = { 1.0f,0.0f,0.0f };
v3f delta;
+ float *cam = player.camera[3],
+ *pos = player.rb.co;
+
v3_sub( player.rb.co, player.camera[3], delta );
v3_normalize( delta );
m3x3_mulv( player.camera, ears, ears );
- float pan = v3_dot( ears, delta );
- audio_player0.pan = pan;
- audio_player1.pan = pan;
- audio_player2.pan = pan;
-
- audio_player3.pan = 0.0f;
-
- if( freecam )
+ if( freecam || player.is_dead || !player.on_board )
{
audio_player0.vol = 0.0f;
audio_player1.vol = 0.0f;
audio_player2.vol = 0.0f;
+
+ audio_player0.pan = 0.0f;
+ audio_player1.pan = 0.0f;
+ audio_player2.pan = 0.0f;
}
else
{
- if( player.is_dead )
- {
- audio_player0.vol = 0.0f;
- audio_player1.vol = 0.0f;
- audio_player2.vol = 0.0f;
- }
- else
- {
- float slide = vg_clampf( fabsf(player.slip), 0.0f, 1.0f );
- audio_player0.vol = (1.0f-air)*attn*(1.0f-slide);
- audio_player1.vol = air *attn;
- audio_player2.vol = (1.0f-air)*attn*slide;
- }
+ /* Spacialize 0 */
+ audio_spacialize( &audio_player0, pos, cam, ears, 1.0f );
+ audio_player1.pan = audio_player0.pan;
+ audio_player2.pan = audio_player0.pan;
+
+ /* Composite */
+ float speed = vg_minf(v3_length( player.rb.v )*0.1f,1.0f),
+ attn = audio_player0.vol * speed,
+ slide = vg_clampf( fabsf(player.slip), 0.0f, 1.0f ),
+ vol0 = (1.0f-air)*attn*(1.0f-slide),
+ vol1 = air *attn,
+ vol2 = (1.0f-air)*attn*slide;
+
+ audio_player1.vol = vol1;
+ audio_player2.vol = vol2;
+ audio_player0.vol = vol0;
}
+ /* Tunnel / occlusion */
+ audio_sample_occlusion( player.camera[3] );
+ audio_player3.pan = 0.0f;
audio_player3.vol = audio_player0.vol * audio_occlusion_current * 2.0f;
+
+ world_audio_update( cam, ears );
+ sfx_unlock();
}
/*
#include "traffic.h" /*TODO: -> world_traffic.h */
#include "world_routes.h"
#include "world_sfd.h"
+#include "world_audio.h"
#include "shaders/terrain.h"
#include "shaders/sky.h"
/* Other systems */
world_sfd_init();
+ world_audio_init();
}
static void world_update(void)
--- /dev/null
+#ifndef WORLD_AUDIO_H
+#define WORLD_AUDIO_H
+
+#include "common.h"
+#include "audio.h"
+
+sfx_set audio_birds =
+{
+ .sources = "sound/bird0.ogg\0"
+ "sound/bird1.ogg\0"
+ "sound/bird2.ogg\0"
+};
+
+static float k_audio_random_freq = 1.0f/10.0f,
+ k_audio_random_hz = 1.0f;
+
+static double world_audio_last_tick = 0.0;
+
+static struct world_ambient_layer
+{
+ sfx_system sys;
+ v3f pos;
+}
+world_ambient_layers[8];
+
+static void world_audio_init(void)
+{
+ sfx_set_init( &audio_birds, NULL );
+
+ vg_convar_push( (struct vg_convar){
+ .name = "aud_random_freq",
+ .data = &k_audio_random_freq,
+ .data_type = k_convar_dtype_f32,
+ .opt_f32 = { .clamp = 0 },
+ .persistent = 1
+ });
+
+ for( int i=0; i<vg_list_size(world_ambient_layers); i++ )
+ {
+ struct world_ambient_layer *layer = &world_ambient_layers[i];
+ sfx_system *sys = &layer->sys;
+ sys->vol = 1.0f;
+ sys->ch = 1;
+ sys->vol_src = &audio_vol_all;
+ sys->name = "ambient";
+ sys->flags = SFX_FLAG_PERSISTENT;
+ }
+}
+
+static void world_audio_spawn_random( v3f around )
+{
+ for( int i=0; i<vg_list_size(world_ambient_layers); i++ )
+ {
+ struct world_ambient_layer *layer = &world_ambient_layers[i];
+
+ if( !layer->sys.is_playing )
+ {
+ sfx_set_playrnd( &audio_birds, &layer->sys, 0, 3 );
+
+ v3f chance;
+ vg_rand_sphere( chance );
+ v3_muladds( around, chance, 100.0f, layer->pos );
+
+ return;
+ }
+ }
+}
+
+static void world_audio_update( v3f around, v3f ears )
+{
+ if( world_audio_last_tick + (double)k_audio_random_hz < vg_time )
+ {
+ world_audio_last_tick = vg_time;
+
+ float chance = vg_randf();
+ if( chance < k_audio_random_freq )
+ {
+ world_audio_spawn_random( around );
+ }
+ }
+
+ /* Spacialize */
+ for( int i=0; i<vg_list_size(world_ambient_layers); i++ )
+ {
+ struct world_ambient_layer *layer = &world_ambient_layers[i];
+
+ if( layer->sys.is_playing )
+ audio_spacialize( &layer->sys, layer->pos, around, ears, 30.0f );
+ }
+}
+
+static void world_audio_debug(void)
+{
+ for( int i=0; i<vg_list_size(world_ambient_layers); i++ )
+ {
+ struct world_ambient_layer *layer = &world_ambient_layers[i];
+
+ if( layer->sys.is_playing )
+ {
+ vg_line_pt3( layer->pos, 1.0f, 0xffff00ff );
+ }
+ }
+}
+
+#endif /* WORLD_AUDIO_H */