2 * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
12 VG_STATIC
float audio_occlusion_current
= 0.0f
,
13 k_audio_occlusion_rate
= 1.0f
;
15 VG_STATIC
int k_audio_debug_soundscape
= 0;
17 audio_clip audio_board
[] =
19 { .path
="sound/skate_hpf.ogg" },
20 { .path
="sound/wheel.ogg" },
21 { .path
="sound/slide.ogg" },
22 { .path
="sound/grind_enter.ogg" },
23 { .path
="sound/grind_exit.ogg" },
24 { .path
="sound/grind_loop.ogg" },
25 { .path
="sound/woodslide.ogg" },
26 { .path
="sound/metalscrape.ogg" },
27 { .path
="sound/slidetap.ogg" }
30 audio_clip audio_taps
[] =
32 { .path
="sound/tap0.ogg" },
33 { .path
="sound/tap1.ogg" },
34 { .path
="sound/tap2.ogg" },
35 { .path
="sound/tap3.ogg" }
38 audio_clip audio_hits
[] =
40 { .path
="sound/hit0.ogg" },
41 { .path
="sound/hit1.ogg" },
42 { .path
="sound/hit2.ogg" },
43 { .path
="sound/hit3.ogg" },
44 { .path
="sound/hit4.ogg" }
47 audio_clip audio_splash
=
48 { .path
= "sound/splash.ogg" };
50 audio_clip audio_jumps
[] = {
51 { .path
= "sound/jump0.ogg" },
52 { .path
= "sound/jump1.ogg" },
55 audio_clip audio_footsteps
[] = {
56 {.path
= "sound/step_concrete0.ogg" },
57 {.path
= "sound/step_concrete1.ogg" },
58 {.path
= "sound/step_concrete2.ogg" },
59 {.path
= "sound/step_concrete3.ogg" }
62 audio_clip audio_footsteps_grass
[] = {
63 {.path
= "sound/step_bush0.ogg" },
64 {.path
= "sound/step_bush1.ogg" },
65 {.path
= "sound/step_bush2.ogg" },
66 {.path
= "sound/step_bush3.ogg" },
67 {.path
= "sound/step_bush4.ogg" },
68 {.path
= "sound/step_bush5.ogg" }
71 audio_clip audio_footsteps_wood
[] = {
72 {.path
= "sound/step_wood0.ogg" },
73 {.path
= "sound/step_wood1.ogg" },
74 {.path
= "sound/step_wood2.ogg" },
75 {.path
= "sound/step_wood3.ogg" },
76 {.path
= "sound/step_wood4.ogg" },
77 {.path
= "sound/step_wood5.ogg" }
80 audio_clip audio_lands
[] = {
81 { .path
= "sound/land0.ogg" },
82 { .path
= "sound/land1.ogg" },
83 { .path
= "sound/land2.ogg" },
84 { .path
= "sound/landsk0.ogg" },
85 { .path
= "sound/landsk1.ogg" },
86 { .path
= "sound/onto.ogg" },
87 { .path
= "sound/outo.ogg" },
90 audio_clip audio_water
[] = {
91 { .path
= "sound/wave0.ogg" },
92 { .path
= "sound/wave1.ogg" },
93 { .path
= "sound/wave2.ogg" },
94 { .path
= "sound/wave3.ogg" },
95 { .path
= "sound/wave4.ogg" },
96 { .path
= "sound/wave5.ogg" }
99 audio_clip audio_grass
[] = {
100 { .path
= "sound/grass0.ogg" },
101 { .path
= "sound/grass1.ogg" },
102 { .path
= "sound/grass2.ogg" },
103 { .path
= "sound/grass3.ogg" },
106 audio_clip audio_ambience
[] =
108 { .path
="sound/town_generic.ogg" }
111 audio_clip audio_gate_pass
= {
112 .path
= "sound/gate_pass.ogg"
115 audio_clip audio_gate_lap
= {
116 .path
= "sound/gate_lap.ogg"
119 audio_clip audio_gate_ambient
= {
120 .path
= "sound/gate_ambient.ogg"
124 audio_player ambient_player
=
129 audio_player audio_rewind_player
=
135 audio_clip audio_rewind
[] = {
136 { .path
= "sound/rewind_start.ogg" },
137 { .path
= "sound/rewind_end_1.5.ogg" },
138 { .path
= "sound/rewind_end_2.5.ogg" },
139 { .path
= "sound/rewind_end_6.5.ogg" },
140 { .path
= "sound/rewind_clack.ogg" },
143 audio_clip audio_ui
[] = {
144 { .path
= "sound/ui_click.ogg" },
145 { .path
= "sound/ui_ding.ogg" },
149 audio_player ambient_sprites
[4] =
151 { .name
= "Ambient Sprites 0" },
152 { .name
= "Ambient Sprites 1" },
153 { .name
= "Ambient Sprites 2" },
154 { .name
= "Ambient Sprites 3" },
157 audio_player audio_player0
=
162 audio_player audio_player1
=
167 audio_player audio_player2
=
172 audio_player audio_player3
=
177 audio_player audio_player4
=
182 audio_player audio_player_extra
=
187 audio_player audio_player_gate
=
193 VG_STATIC
void audio_init(void)
196 audio_player_init( &audio_player0
);
197 audio_player_init( &audio_player1
);
198 audio_player_init( &audio_player2
);
199 audio_player_init( &audio_player3
);
200 audio_player_init( &audio_player4
);
201 audio_player_init( &audio_player_gate
);
202 audio_player_init( &ambient_player
);
203 audio_player_init( &ambient_sprites
[0] );
204 audio_player_init( &ambient_sprites
[1] );
205 audio_player_init( &ambient_sprites
[2] );
206 audio_player_init( &ambient_sprites
[3] );
207 audio_player_init( &audio_player_extra
);
208 audio_player_init( &audio_rewind_player
);
211 audio_clip_loadn( audio_board
, vg_list_size(audio_board
), NULL
);
212 audio_clip_loadn( audio_taps
, vg_list_size(audio_taps
), NULL
);
213 audio_clip_loadn( audio_hits
, vg_list_size(audio_hits
), NULL
);
214 audio_clip_loadn( audio_ambience
, vg_list_size(audio_ambience
), NULL
);
215 audio_clip_loadn( &audio_splash
, 1, NULL
);
216 audio_clip_loadn( &audio_gate_pass
, 1, NULL
);
217 audio_clip_loadn( &audio_gate_lap
, 1, NULL
);
218 audio_clip_loadn( &audio_gate_ambient
, 1, NULL
);
220 audio_clip_loadn( audio_jumps
, vg_list_size(audio_jumps
), NULL
);
221 audio_clip_loadn( audio_lands
, vg_list_size(audio_lands
), NULL
);
222 audio_clip_loadn( audio_water
, vg_list_size(audio_water
), NULL
);
223 audio_clip_loadn( audio_grass
, vg_list_size(audio_grass
), NULL
);
224 audio_clip_loadn( audio_footsteps
, vg_list_size(audio_footsteps
), NULL
);
225 audio_clip_loadn( audio_footsteps_grass
,
226 vg_list_size(audio_footsteps_grass
), NULL
);
227 audio_clip_loadn( audio_footsteps_wood
,
228 vg_list_size(audio_footsteps_wood
), NULL
);
229 audio_clip_loadn( audio_rewind
, vg_list_size(audio_rewind
), NULL
);
230 audio_clip_loadn( audio_ui
, vg_list_size(audio_ui
), NULL
);
234 u32 flags
= AUDIO_FLAG_LOOP
|AUDIO_FLAG_SPACIAL_3D
;
236 audio_player_set_flags( &audio_player0
, flags
);
237 audio_player_set_flags( &audio_player1
, flags
);
238 audio_player_set_flags( &audio_player2
, flags
);
239 audio_player_set_flags( &audio_player4
, flags
);
240 audio_player_set_flags( &audio_player_gate
, flags
);
241 audio_player_set_flags( &audio_player3
, AUDIO_FLAG_LOOP
);
242 audio_player_set_flags( &ambient_player
, AUDIO_FLAG_LOOP
);
243 audio_player_set_flags( &ambient_sprites
[0], AUDIO_FLAG_SPACIAL_3D
);
244 audio_player_set_flags( &ambient_sprites
[1], AUDIO_FLAG_SPACIAL_3D
);
245 audio_player_set_flags( &ambient_sprites
[2], AUDIO_FLAG_SPACIAL_3D
);
246 audio_player_set_flags( &ambient_sprites
[3], AUDIO_FLAG_SPACIAL_3D
);
248 audio_player_set_vol( &ambient_player
, 1.0f
);
249 audio_player_set_vol( &audio_player_gate
, 0.0f
);
250 audio_player_set_vol( &audio_player_extra
, 1.0f
);
251 audio_player_set_vol( &audio_rewind_player
, 0.2f
);
252 audio_player_set_flags( &audio_rewind_player
, 0x00 );
254 audio_player_playclip( &audio_player0
, &audio_board
[0] );
255 audio_player_playclip( &audio_player1
, &audio_board
[1] );
256 audio_player_playclip( &audio_player2
, &audio_board
[2] );
257 audio_player_playclip( &audio_player3
, &audio_board
[3] );
258 audio_player_playclip( &audio_player4
, &audio_board
[4] );
259 audio_player_playclip( &ambient_player
, &audio_ambience
[0] );
260 audio_player_playclip( &audio_player_gate
, &audio_gate_ambient
);
265 vg_var_push( (struct vg_var
){
266 .name
= "aud_debug_soundscape",
267 .data
= &k_audio_debug_soundscape
,
268 .data_type
= k_var_dtype_i32
,
269 .opt_i32
= { .min
=0, .max
=1, .clamp
=0 },
273 vg_var_push( (struct vg_var
){
274 .name
= "aud_occlusion_rate",
275 .data
= &k_audio_occlusion_rate
,
276 .data_type
= k_var_dtype_f32
,
277 .opt_f32
= { .clamp
= 0 },
282 audio_set_lfo_wave( 0, k_lfo_polynomial_bipolar
, 80.0f
);
283 audio_set_lfo_frequency( 0, 20.0f
);
287 VG_STATIC
void audio_update(void)
290 static u32 flapflop
= 0x00;
291 static audio_channel
*channel
= NULL
;
293 u32 next
= floorf( vg
.time
/ 0.1f
);
295 if( flapflop
!= next
)
300 channel
= audio_channel_crossfade( channel
,
301 &audio_music
[ next
& 0x1 ], 0.05f
,
302 AUDIO_FLAG_LOOP
|AUDIO_FLAG_SPACIAL_3D
304 channel
= audio_channel_set_spacial( channel
,
305 (v3f
){ -22.3f
, 60.1f
, -52.7f
},
308 audio_channel_sidechain_lfo( channel
, 0, 1.0f
);
314 VG_STATIC
void audio_free(void)
317 vg_warn( "UNIMPLEMENTED: audio_free()\n" );
320 VG_STATIC
void audio_sample_occlusion( v3f origin
)
323 sample_dist
= 880.0f
;
325 int sample_count
= 8;
331 world_instance
*world
= get_active_world();
333 for( int i
=0; i
<sample_count
; i
++ )
339 contact
.dist
= 15.0f
;
341 if( ray_world( world
, origin
, dir
, &contact
) )
346 vg_line( origin
, contact
.pos
, 0xff0000ff );
347 vg_line_pt3( contact
.pos
, 0.1f
, 0xff0000ff );
350 vg_line( contact
.pos
, last
, 0xffffffff );
353 v3_copy( contact
.pos
, last
);
359 v3_muladds( origin
, dir
, sample_dist
, p1
);
362 vg_line( origin
, p1
, 0xffcccccc );
371 float occlusion
= 1.0f
- (d
* (1.0f
/(sample_dist
*(float)sample_count
))),
372 rate
= VG_TIMESTEP_FIXED
* k_audio_occlusion_rate
,
373 target
= powf( vg_maxf(occlusion
,0.0f
), 6.0f
);
374 audio_occlusion_current
= vg_lerpf( audio_occlusion_current
, target
, rate
);
377 enum audio_sprite_type
379 k_audio_sprite_type_none
,
380 k_audio_sprite_type_grass
,
381 k_audio_sprite_type_water
385 * Trace out a random point, near the player to try and determine water areas
387 VG_STATIC
enum audio_sprite_type
audio_sample_sprite_random( v3f origin
,
390 v3f chance
= { (vg_randf()-0.5f
) * 30.0f
,
392 (vg_randf()-0.5f
) * 30.0f
};
395 v3_add( chance
, origin
, pos
);
398 contact
.dist
= vg_minf( 16.0f
, pos
[1] );
400 world_instance
*world
= get_active_world();
402 if( ray_world( world
, pos
, (v3f
){0.0f
,-1.0f
,0.0f
}, &contact
) ){
403 struct world_surface
*mat
= ray_hit_surface( world
, &contact
);
405 if( mat
->info
.surface_prop
== k_surface_prop_grass
){
406 v3_copy( contact
.pos
, output
);
407 return k_audio_sprite_type_grass
;
411 vg_line( pos
, contact
.pos
, 0xff0000ff );
412 vg_line_pt3( contact
.pos
, 0.3f
, 0xff0000ff );
414 return k_audio_sprite_type_none
;
422 if( world
->water
.enabled
)
423 return k_audio_sprite_type_water
;
425 return k_audio_sprite_type_none
;
428 VG_STATIC
void audio_debug_soundscapes(void)
430 if( !k_audio_debug_soundscape
) return;
433 snprintf( buf
, 31, "occlusion: %.5f", audio_occlusion_current
);
435 vg_uictx
.cursor
[0] = 450;
436 vg_uictx
.cursor
[1] = 10;
437 vg_uictx
.cursor
[2] = audio_occlusion_current
* 200.0f
;
438 vg_uictx
.cursor
[3] = 20;
440 ui_fill_rect( vg_uictx
.cursor
, 0x55cccccc );
441 ui_text( vg_uictx
.cursor
, buf
, 1, 0 );