#include "vg/vg_console.h"
#include "vg/vg_store.h"
#include "vg/vg_profiler.h"
+#include "vg/vg_audio_synth_bird.h"
#include <sys/time.h>
#include <math.h>
/* 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
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
int debug_ui, debug_ui_3d;
v3f listener_pos,
- listener_ears;
+ listener_ears,
+ listener_velocity;
float volume,
volume_target,
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;
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;
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;
}
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;i<samples_this_run; i++ )
{
dst[i*2+1] = 0.0f;
}
}
- else if( ch->source->flags & AUDIO_FLAG_VORBIS )
+ else if( format == k_audio_format_vorbis )
{
int read_samples = stb_vorbis_get_samples_float_interleaved_stereo(
ch->vorbis_handle,
}
}
}
+ 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,
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;
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]) )
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;
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 ),
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 )
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 );
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 );
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[] =
"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,
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;