controls->sampling_rate_multiplier = 1.0f;
controls->lfo_id = 0;
controls->lfo_attenuation_amount = 0.0f;
+ controls->pause = 0;
v4_copy( (v4f){0,0,0,1}, controls->spacial_falloff );
struct audio_channel_state *state = get_audio_channel_state( id );
vg_audio_add_channel_flags( id, AUDIO_FLAG_SPACIAL_3D );
}
+void vg_audio_sync_ui_master_controls(void)
+{
+ vg_audio_assert_lock();
+ _vg_audio.controls.volume_target = ((f64)AUDIO_VOLUME_100) * _vg_audio.master_volume_ui;
+ _vg_audio.controls.dsp_enabled = _vg_audio.dsp_enabled_ui;
+}
+
void vg_audio_set_channel_volume( audio_channel_id id, f64 volume, bool instant )
{
vg_audio_assert_lock();
return 1;
}
+void vg_audio_set_channel_pause( audio_channel_id id, bool pause )
+{
+ vg_audio_assert_lock();
+ struct audio_channel_controls *controls = get_audio_channel_controls( id );
+ controls->pause = pause;
+}
+
+void vg_audio_set_flagged_pause( u32 flag, bool pause )
+{
+ vg_audio_assert_lock();
+ for( u32 id=1; id<=AUDIO_CHANNELS; id ++ )
+ {
+ audio_channel *channel = get_audio_channel( id );
+ if( channel->stage != k_channel_stage_none )
+ {
+ struct audio_channel_controls *controls = get_audio_channel_controls( id );
+ if( controls->flags & flag )
+ vg_audio_set_channel_pause( id, pause );
+ }
+ }
+}
+
void vg_audio_oneshot_3d( audio_clip *clip, v3f co, f32 range, f32 volume, u16 group, u32 flags )
{
vg_audio_assert_lock();
vg_profile_begin( &_vg_prof_audio_mix );
+ /* TODO: Slew this */
+ f64 master_volume = (f64)_vg_audio.state.volume / (f64)AUDIO_VOLUME_100;
+
for( u32 j=0; j<AUDIO_MIX_FRAME_SIZE; j++ )
{
audio_slew_i32( &state->volume, controls->volume_target, controls->volume_slew_rate_per_sample );
audio_slew_i32( &state->pan, controls->pan_target, controls->pan_slew_rate_per_sample );
- f64 v_c = (f64)state->volume / (f64)AUDIO_VOLUME_100;
+ f64 v_c = ((f64)state->volume / (f64)AUDIO_VOLUME_100) * master_volume;
if( controls->lfo_id )
{
struct audio_lfo_controls lfo_controls[ AUDIO_LFOS ];
u32 active_lfo_count = 0;
+ struct audio_master_state *master_state = &_vg_audio.state;
+
vg_audio_lock();
memcpy( &master_controls, &_vg_audio.controls, sizeof(struct audio_master_controls) );
+
for( u32 id=1; id<=AUDIO_CHANNELS; id ++ )
{
audio_channel *channel = get_audio_channel( id );
if( channel->stage == k_channel_stage_active )
{
+ struct audio_channel_controls *controls = get_audio_channel_controls(id);
+ if( controls->pause )
+ {
+ channel->ui_activity = k_channel_activity_paused;
+ continue;
+ }
+
active_channel_list[ active_channel_count ] = id;
- memcpy( &channel_controls[ active_channel_count ], get_audio_channel_controls(id),
- sizeof( struct audio_channel_controls ) );
+ memcpy( &channel_controls[ active_channel_count ], controls, sizeof( struct audio_channel_controls ) );
active_channel_count ++;
}
}
vg_audio_unlock();
/* init step */
+ master_state->volume = master_controls.volume_target;
+ master_state->volume_at_frame_start = master_controls.volume_target;
+
for( u32 i=0; i<active_channel_count; i ++ )
{
audio_channel_id id = active_channel_list[i];
}
/* mix step */
- bool dsp_enabled = 1;
-
for( u32 dry_layer=0; dry_layer<=1; dry_layer ++ )
{
for( u32 i=0; i<active_channel_count; i ++ )
if( state->activity == k_channel_activity_playing )
{
- if( dsp_enabled )
+ if( master_controls.dsp_enabled )
{
if( controls->flags & AUDIO_FLAG_NO_DSP )
{
}
}
- if( dsp_enabled )
+ if( master_controls.dsp_enabled )
{
if( !dry_layer )
{
{
vg_console_reg_cmd( "vg_audio", cmd_vg_audio, NULL );
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_ui, k_var_dtype_i32, VG_VAR_PERSISTENT );
+ vg_console_reg_var( "vg_audio_device", &_vg_audio.device_choice, k_var_dtype_str, VG_VAR_PERSISTENT );
}
void vg_audio_device_init(void)
struct audio_master_controls *master_controls = &_vg_audio.controls;
master_controls->dsp_enabled = _vg_audio.dsp_enabled_ui;
- master_controls->volume = (f64)_vg_audio.master_volume_ui * (f64)AUDIO_VOLUME_100;
+ master_controls->volume_target = (f64)_vg_audio.master_volume_ui * (f64)AUDIO_VOLUME_100;
v3_copy( (v3f){1,0,0}, master_controls->listener_right_ear_direction );
v3_zero( master_controls->listener_velocity );
v3_zero( master_controls->listener_position );
f32 lfo_attenuation_amount; /* multiply volume by (1 + value) */
v4f spacial_falloff; /* xyz, range */
+ bool pause;
}
controls;
struct audio_master_controls
{
- i32 dsp_enabled;
v3f listener_position,
listener_right_ear_direction,
listener_velocity;
- i32 volume;
+
+ bool dsp_enabled;
+ i32 volume_target;
}
controls;
- i32 dsp_enabled_ui;
- f32 master_volume_ui;
+ struct audio_master_state
+ {
+ i32 volume, volume_at_frame_start;
+ }
+ state;
bool always_keep_clips_compressed;
+
+ f32 master_volume_ui;
+ i32 dsp_enabled_ui;
}
extern _vg_audio;
void vg_audio_start_lfo( audio_channel_id lfo_id );
/* high level functions */
+void vg_audio_sync_ui_master_controls(void);
audio_channel_id vg_audio_crossfade( audio_channel_id id, audio_clip *new_clip, f32 transition_seconds );
void vg_audio_oneshot_3d( audio_clip *clip, v3f co, f32 range, f32 volume, u16 group, u32 flags );
void vg_audio_oneshot( audio_clip *clip, f32 volume, f32 pan, u16 group, u32 flags );
+void vg_audio_set_channel_pause( audio_channel_id id, bool pause );
/* half measures... Don't expect these functions to stay. */
void vg_audio_fadeout_flagged_audio( u32 flag, f32 length );
bool vg_audio_flagged_stopped( u32 flag );
bool vg_audio_is_channel_using_clip( audio_channel_id id, audio_clip *clip );
+void vg_audio_set_flagged_pause( u32 flag, bool pause );