From: hgn Date: Wed, 8 Mar 2023 03:12:47 +0000 (+0000) Subject: resampling rate X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=3b3420de0251e489082814e60dcc45e5e8842224;p=vg.git resampling rate --- diff --git a/vg_audio.h b/vg_audio.h index 20972c0..a0d6b6b 100644 --- a/vg_audio.h +++ b/vg_audio.h @@ -146,7 +146,8 @@ static struct vg_audio_system float volume, /* current volume */ volume_target, /* target volume */ pan, - pan_target; + pan_target, + sampling_rate; u32 volume_rate, pan_rate; @@ -306,6 +307,7 @@ VG_STATIC void vg_audio_free(void) #define AUDIO_EDIT_LFO_ATTACHMENT 0x10 #define AUDIO_EDIT_SPACIAL 0x20 #define AUDIO_EDIT_OWNERSHIP 0x40 +#define AUDIO_EDIT_SAMPLING_RATE 0x80 static audio_channel *audio_request_channel( audio_clip *clip, u32 flags ) { @@ -331,6 +333,7 @@ static audio_channel *audio_request_channel( audio_clip *clip, u32 flags ) v4_copy((v4f){0.0f,0.0f,0.0f,1.0f},ch->editable_state.spacial_falloff); ch->editable_state.lfo = NULL; ch->editable_state.lfo_amount = 0.0f; + ch->editable_state.sampling_rate = 1.0f; ch->editble_state_write_mask = 0x00; return ch; } @@ -346,45 +349,44 @@ static audio_channel *audio_relinquish_channel( audio_channel *ch ) return NULL; } -static audio_channel *audio_channel_slope_volume( audio_channel *ch, - float length, - float new_volume ) +static void audio_channel_slope_volume( audio_channel *ch, float length, + float new_volume ) { ch->editable_state.volume_target = new_volume; ch->editable_state.volume_rate = length * 44100.0f; ch->editble_state_write_mask |= AUDIO_EDIT_VOLUME_SLOPE; +} - return ch; +static void audio_channel_set_sampling_rate( audio_channel *ch, float rate ) +{ + ch->editable_state.sampling_rate = rate; + ch->editble_state_write_mask |= AUDIO_EDIT_SAMPLING_RATE; } -static audio_channel *audio_channel_edit_volume( audio_channel *ch, - float new_volume, int instant ) +static void audio_channel_edit_volume( audio_channel *ch, + float new_volume, int instant ) { if( instant ) { ch->editable_state.volume = 0.0f; ch->editble_state_write_mask |= AUDIO_EDIT_VOLUME; - return ch; } else { - return audio_channel_slope_volume( ch, 0.05f, new_volume ); + audio_channel_slope_volume( ch, 0.05f, new_volume ); } } static audio_channel *audio_channel_fadeout( audio_channel *ch, float length ) { - ch = audio_channel_slope_volume( ch, length, 0.0f ); - ch = audio_relinquish_channel( ch ); - - return ch; + audio_channel_slope_volume( ch, length, 0.0f ); + return audio_relinquish_channel( ch ); } -static audio_channel *audio_channel_fadein( audio_channel *ch, float length ) +static void audio_channel_fadein( audio_channel *ch, float length ) { - ch = audio_channel_edit_volume( ch, 0.0f, 1 ); - ch = audio_channel_slope_volume( ch, length, 1.0f ); - return ch; + audio_channel_edit_volume( ch, 0.0f, 1 ); + audio_channel_slope_volume( ch, length, 1.0f ); } static audio_channel *audio_channel_crossfade( audio_channel *ch, @@ -394,32 +396,25 @@ static audio_channel *audio_channel_crossfade( audio_channel *ch, u32 cursor = 0; if( ch ) - { ch = audio_channel_fadeout( ch, length ); - } audio_channel *replacement = audio_request_channel( new_clip, flags ); if( replacement ) - { - replacement = audio_channel_fadein( replacement, length ); - } + audio_channel_fadein( replacement, length ); return replacement; } -static audio_channel *audio_channel_sidechain_lfo( audio_channel *ch, - int lfo_id, float amount ) +static void audio_channel_sidechain_lfo( audio_channel *ch, int lfo_id, + float amount ) { ch->editable_state.lfo = &vg_audio.oscillators[ lfo_id ]; ch->editable_state.lfo_amount = amount; ch->editble_state_write_mask |= AUDIO_EDIT_LFO_ATTACHMENT; - - return ch; } -static audio_channel *audio_channel_set_spacial( audio_channel *ch, - v3f co, float range ) +static void audio_channel_set_spacial( audio_channel *ch, v3f co, float range ) { if( ch->flags & AUDIO_FLAG_SPACIAL_3D ) { @@ -432,36 +427,38 @@ static audio_channel *audio_channel_set_spacial( audio_channel *ch, vg_warn( "Tried to set spacialization paramaters for 2D channel (%s)\n", ch->name ); } - - return ch; } -static audio_channel *audio_oneshot_3d( audio_clip *clip, v3f position, - float range, float volume ) +static int audio_oneshot_3d( audio_clip *clip, v3f position, + float range, float volume ) { audio_channel *ch = audio_request_channel( clip, AUDIO_FLAG_SPACIAL_3D ); if( ch ) { - ch = audio_channel_set_spacial( ch, position, range ); - ch = audio_channel_edit_volume( ch, volume, 1 ); + audio_channel_set_spacial( ch, position, range ); + audio_channel_edit_volume( ch, volume, 1 ); ch = audio_relinquish_channel( ch ); - } - return ch; + return 1; + } + else + return 0; } -static audio_channel *audio_oneshot( audio_clip *clip, float volume, float pan ) +static int audio_oneshot( audio_clip *clip, float volume, float pan ) { audio_channel *ch = audio_request_channel( clip, 0x00 ); if( ch ) { - ch = audio_channel_edit_volume( ch, volume, 1 ); + audio_channel_edit_volume( ch, volume, 1 ); ch = audio_relinquish_channel( ch ); - } - return ch; + return 1; + } + else + return 0; } static void audio_set_lfo_wave( int id, enum lfo_wave_type type, @@ -730,11 +727,17 @@ static void audio_channel_get_samples( audio_channel *ch, static void audio_channel_mix( audio_channel *ch, float *buffer, u32 frame_count ) { - u32 buffer_pos = 0; - float *pcf = alloca( frame_count * 2 * sizeof(float) ); u32 frames_write = frame_count; - audio_channel_get_samples( ch, frame_count, pcf ); + u32 buffer_length = frame_count; + if( ch->_.sampling_rate != 1.0f ) + { + buffer_length = ceilf( (float)frame_count * ch->_.sampling_rate ) + 1; + } + + float *pcf = alloca( buffer_length * 2 * sizeof(float) ); + + audio_channel_get_samples( ch, buffer_length, pcf ); vg_profile_begin( &_vg_prof_audio_mix ); if( ch->_.lfo ) @@ -793,12 +796,32 @@ static void audio_channel_mix( audio_channel *ch, * ch->_.lfo_amount; float vol_l = vol_norm * framevol_l, - vol_r = vol_norm * framevol_r; - - buffer[ buffer_pos*2+0 ] += pcf[ buffer_pos*2+0 ] * vol_l; - buffer[ buffer_pos*2+1 ] += pcf[ buffer_pos*2+1 ] * vol_r; + vol_r = vol_norm * framevol_r, + sample_l, + sample_r; - buffer_pos ++; + if( ch->_.sampling_rate != 1.0f ) + { + /* absolutely garbage resampling, but it will do + */ + + float sample_index = ch->_.sampling_rate * (float)j; + float t = vg_fractf( sample_index ); + + u32 i0 = floorf( sample_index ), + i1 = i0+1; + + sample_l = pcf[ i0*2+0 ]*(1.0f-t) + pcf[ i1*2+0 ]*t; + sample_r = pcf[ i0*2+1 ]*(1.0f-t) + pcf[ i1*2+1 ]*t; + } + else + { + sample_l = pcf[ j*2+0 ]; + sample_r = pcf[ j*2+1 ]; + } + + buffer[ j*2+0 ] += sample_l * vol_l; + buffer[ j*2+1 ] += sample_r * vol_r; } vg_profile_end( &_vg_prof_audio_mix ); @@ -865,7 +888,13 @@ VG_STATIC void audio_mixer_callback( void *user, u8 *stream, int byte_count ) ch->editable_state.volume_target = ch->_.volume_target; ch->editable_state.volume_rate = ch->_.volume_rate; } - + + + if( ch->editble_state_write_mask & AUDIO_EDIT_SAMPLING_RATE ) + ch->_.sampling_rate = ch->editable_state.sampling_rate; + else + ch->editable_state.sampling_rate = ch->_.sampling_rate; + if( ch->editble_state_write_mask & AUDIO_EDIT_LFO_ATTACHMENT ) {