X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=vg_audio.h;h=5b65ccbd0dc040bf03be9559cb8f8b5ec2e5e4d7;hb=28ec4a17033cc45198adab23ddf66ccd7a230db8;hp=0968957a64dbe7983f9e7d629960647bf3b83a0b;hpb=3d52e114a0f608e58bc99cfc6faaeb41cfcf84c7;p=vg.git diff --git a/vg_audio.h b/vg_audio.h index 0968957..5b65ccb 100644 --- a/vg_audio.h +++ b/vg_audio.h @@ -14,6 +14,7 @@ #include "vg/vg_console.h" #include "vg/vg_store.h" #include "vg/vg_profiler.h" +#include "vg/vg_audio_synth_bird.h" #include #include @@ -52,8 +53,32 @@ /* Vorbis will ALWAYS use the maximum amount of channels it can */ //#define AUDIO_FLAG_MONO 0x100 NOTE: This is the default, so its not used -#define AUDIO_FLAG_STEREO 0x200 -#define AUDIO_FLAG_VORBIS 0x400 +//#define AUDIO_FLAG_STEREO 0x200 +//#define AUDIO_FLAG_VORBIS 0x400 +//#define AUDIO_FLAG_BIRD_SYNTH 0x800 + +#define AUDIO_FLAG_FORMAT 0x1E00 + +enum audio_format +{ + k_audio_format_mono = 0x000u, + k_audio_format_stereo = 0x200u, + k_audio_format_vorbis = 0x400u, + k_audio_format_none0 = 0x600u, + k_audio_format_none1 = 0x800u, + k_audio_format_none2 = 0xA00u, + k_audio_format_none3 = 0xC00u, + k_audio_format_none4 = 0xE00u, + + k_audio_format_bird = 0x1000u, + k_audio_format_none5 = 0x1200u, + k_audio_format_none6 = 0x1400u, + k_audio_format_none7 = 0x1600u, + k_audio_format_none8 = 0x1800u, + k_audio_format_none9 = 0x1A00u, + k_audio_format_none10 = 0x1C00u, + k_audio_format_none11 = 0x1E00u, +}; #define AUDIO_DECODE_SIZE (1024*256) /* 256 kb decoding buffers */ #define AUDIO_MUTE_VOLUME 0.0f @@ -128,7 +153,12 @@ static struct vg_audio_system u32 volume_movement, pan_movement; - stb_vorbis *vorbis_handle; + union + { + struct synth_bird *bird_handle; + stb_vorbis *vorbis_handle; + }; + stb_vorbis_alloc vorbis_alloc; enum channel_activity @@ -174,7 +204,8 @@ static struct vg_audio_system int debug_ui, debug_ui_3d; v3f listener_pos, - listener_ears; + listener_ears, + listener_velocity; float volume, volume_target, @@ -334,7 +365,11 @@ static audio_channel *audio_request_channel( audio_clip *clip, u32 flags ) ch->source = clip; ch->flags = flags; ch->colour = 0x00333333; - strcpy( ch->name, clip->path ); + + if( (ch->source->flags & AUDIO_FLAG_FORMAT) == k_audio_format_bird ) + strcpy( ch->name, "[array]" ); + else + strncpy( ch->name, clip->path, 31 ); ch->allocated = 1; @@ -506,13 +541,17 @@ static void audio_set_lfo_frequency( int id, float freq ) lfo->editble_state_write_mask |= AUDIO_EDIT_LFO_PERIOD; } + + /* * Committers * ----------------------------------------------------------------------------- */ static int audio_channel_load_source( audio_channel *ch ) { - if( ch->source->flags & AUDIO_FLAG_VORBIS ) + u32 format = ch->source->flags & AUDIO_FLAG_FORMAT; + + if( format == k_audio_format_vorbis ) { /* Setup vorbis decoder */ u32 index = ch - vg_audio.channels; @@ -542,7 +581,20 @@ static int audio_channel_load_source( audio_channel *ch ) ch->vorbis_handle = decoder; } } - else if( ch->source->flags & AUDIO_FLAG_STEREO ) + else if( format == k_audio_format_bird ) + { + u32 index = ch - vg_audio.channels; + + u8 *buf = (u8*)vg_audio.decode_buffer; + struct synth_bird *loc = (void *)&buf[AUDIO_DECODE_SIZE*index]; + + memcpy( loc, ch->source->data, ch->source->size ); + synth_bird_reset( loc ); + + ch->bird_handle = loc; + ch->source_length = synth_bird_get_length_in_samples( loc ); + } + else if( format == k_audio_format_stereo ) { ch->source_length = ch->source->size / 2; } @@ -684,14 +736,16 @@ static void audio_channel_get_samples( audio_channel *ch, u32 remaining = count; u32 buffer_pos = 0; + u32 format = ch->source->flags & AUDIO_FLAG_FORMAT; + while( remaining ) { - u32 samples_this_run = VG_MIN( remaining, ch->source_length -ch->cursor ); + u32 samples_this_run = VG_MIN(remaining, ch->source_length - ch->cursor); remaining -= samples_this_run; float *dst = &buf[ buffer_pos * 2 ]; - if( ch->source->flags & AUDIO_FLAG_STEREO ) + if( format == k_audio_format_stereo ) { for( int i=0;isource->flags & AUDIO_FLAG_VORBIS ) + else if( format == k_audio_format_vorbis ) { int read_samples = stb_vorbis_get_samples_float_interleaved_stereo( ch->vorbis_handle, @@ -717,6 +771,10 @@ static void audio_channel_get_samples( audio_channel *ch, } } } + else if( format == k_audio_format_bird ) + { + synth_bird_generate_samples( ch->bird_handle, dst, samples_this_run ); + } else { i16 *src_buffer = ch->source->data, @@ -730,8 +788,10 @@ static void audio_channel_get_samples( audio_channel *ch, if( (ch->flags & AUDIO_FLAG_LOOP) && remaining ) { - if( ch->source->flags & AUDIO_FLAG_VORBIS ) + if( format == k_audio_format_vorbis ) stb_vorbis_seek_start( ch->vorbis_handle ); + else if( format == k_audio_format_bird ) + synth_bird_reset( ch->bird_handle ); ch->cursor = 0; continue; @@ -754,25 +814,19 @@ static void audio_channel_get_samples( audio_channel *ch, static void audio_channel_mix( audio_channel *ch, float *buffer ) { - u32 buffer_length = AUDIO_MIX_FRAME_SIZE; - if( ch->_.sampling_rate != 1.0f ) - { - float l = ceilf( (float)(AUDIO_MIX_FRAME_SIZE) * ch->_.sampling_rate ); - buffer_length = l+1; - } - - float pcf[ AUDIO_MIX_FRAME_SIZE * 2 * 2 ]; - - audio_channel_get_samples( ch, buffer_length, pcf ); - float framevol_l = 1.0f, framevol_r = 1.0f; + float frame_samplerate = ch->_.sampling_rate; + if( ch->flags & AUDIO_FLAG_SPACIAL_3D ) { if( !vg_validf(vg_audio.listener_pos[0]) || !vg_validf(vg_audio.listener_pos[1]) || !vg_validf(vg_audio.listener_pos[2]) || + !vg_validf(vg_audio.listener_velocity[0]) || + !vg_validf(vg_audio.listener_velocity[1]) || + !vg_validf(vg_audio.listener_velocity[2]) || !vg_validf(ch->_.spacial_falloff[0]) || !vg_validf(ch->_.spacial_falloff[1]) || !vg_validf(ch->_.spacial_falloff[2]) ) @@ -795,8 +849,28 @@ static void audio_channel_mix( audio_channel *ch, float *buffer ) framevol_l *= (vol * 0.5f) * (1.0f - pan); framevol_r *= (vol * 0.5f) * (1.0f + pan); + + v3_muls( delta, 1.0f/dist, delta ); + + const float vs = 100.0f; + float doppler = (vs+v3_dot(delta,vg_audio.listener_velocity))/vs; + doppler = vg_clampf( doppler, 0.6f, 1.4f ); + + if( fabsf(doppler-1.0f) > 0.01f ) + frame_samplerate *= doppler; + } + + u32 buffer_length = AUDIO_MIX_FRAME_SIZE; + if( frame_samplerate != 1.0f ) + { + float l = ceilf( (float)(AUDIO_MIX_FRAME_SIZE) * frame_samplerate ); + buffer_length = l+1; } + float pcf[ AUDIO_MIX_FRAME_SIZE * 2 * 2 ]; + + audio_channel_get_samples( ch, buffer_length, pcf ); + vg_profile_begin( &_vg_prof_audio_mix ); float volume_movement = ch->volume_movement; @@ -837,12 +911,12 @@ static void audio_channel_mix( audio_channel *ch, float *buffer ) sample_l, sample_r; - if( ch->_.sampling_rate != 1.0f ) + if( frame_samplerate != 1.0f ) { /* absolutely garbage resampling, but it will do */ - float sample_index = ch->_.sampling_rate * (float)j; + float sample_index = frame_samplerate * (float)j; float t = vg_fractf( sample_index ); u32 i0 = floorf( sample_index ), @@ -920,9 +994,14 @@ VG_STATIC void audio_mixer_callback( void *user, u8 *stream, int byte_count ) if( ch->editble_state_write_mask & AUDIO_EDIT_VOLUME ) + { ch->_.volume = ch->editable_state.volume; + ch->_.volume_target = ch->editable_state.volume; + } else + { ch->editable_state.volume = ch->_.volume; + } if( ch->editble_state_write_mask & AUDIO_EDIT_VOLUME_SLOPE ) @@ -1103,9 +1182,13 @@ VG_STATIC void audio_clip_load( audio_clip *clip, void *lin_alloc ) if( lin_alloc == NULL ) lin_alloc = vg_audio.audio_pool; - /* load in directly */ - if( clip->flags & AUDIO_FLAG_VORBIS ) + u32 format = clip->flags & AUDIO_FLAG_FORMAT; + + /* TODO: This contains audio_lock() and unlock, but i don't know why + * can probably remove them. Low priority to check this */ + + if( format == k_audio_format_vorbis ) { audio_lock(); clip->data = vg_file_read( lin_alloc, clip->path, &clip->size ); @@ -1117,10 +1200,23 @@ VG_STATIC void audio_clip_load( audio_clip *clip, void *lin_alloc ) float mb = (float)(clip->size) / (1024.0f*1024.0f); vg_info( "Loaded audio clip '%s' (%.1fmb)\n", clip->path, mb ); } - else if( clip->flags & AUDIO_FLAG_STEREO ) + else if( format == k_audio_format_stereo ) { vg_fatal_exit_loop( "Unsupported format (Stereo uncompressed)" ); } + else if( format == k_audio_format_bird ) + { + u32 len = strlen( clip->path ), + size = synth_bird_memory_requirement( len ); + + if( size > AUDIO_DECODE_SIZE ) + vg_fatal_exit_loop( "Bird code too long\n" ); + + clip->size = size; + clip->data = vg_linear_alloc( lin_alloc, size ); + + synth_bird_load( clip->data, clip->path, len ); + } else { vg_linear_clear( vg_mem.scratch ); @@ -1254,10 +1350,22 @@ VG_STATIC void audio_debug_ui( m4x4f mtx_pv ) const char *formats[] = { - "------", - "Mono ", - "Stereo", - "Vorbis" + " mono ", + " stereo ", + " vorbis ", + " none0 ", + " none1 ", + " none2 ", + " none3 ", + " none4 ", + "synth:bird", + " none5 ", + " none6 ", + " none7 ", + " none8 ", + " none9 ", + " none10 ", + " none11 ", }; const char *activties[] = @@ -1269,14 +1377,7 @@ VG_STATIC void audio_debug_ui( m4x4f mtx_pv ) "error" }; - int format_index = 0; - - if( ch->source->flags & AUDIO_FLAG_STEREO ) - format_index = 2; - else if( ch->source->flags & AUDIO_FLAG_VORBIS ) - format_index = 3; - else - format_index = 1; + u32 format_index = (ch->source->flags & AUDIO_FLAG_FORMAT)>>9; snprintf( perf, 127, "%02d %c%c%cD %s [%s] %4.2fv'%s'", i, @@ -1288,14 +1389,7 @@ VG_STATIC void audio_debug_ui( m4x4f mtx_pv ) ch->editable_state.volume, ch->name ); - if( format_index == 0 ) - { - ui_fill_rect( vg_uictx.cursor, 0xa00000ff ); - } - else - { - ui_fill_rect( vg_uictx.cursor, 0xa0000000 | ch->colour ); - } + ui_fill_rect( vg_uictx.cursor, 0xa0000000 | ch->colour ); vg_uictx.cursor[0] += 2; vg_uictx.cursor[1] += 2;