-// Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
+/* Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved */
#define MA_NO_GENERATION
#define MA_NO_DECODING
#include "stb/stb_vorbis.h"
#define SFX_MAX_SYSTEMS 32
-//#define SFX_FLAG_ONESHOT 0x1
#define SFX_FLAG_STEREO 0x2
#define SFX_FLAG_REPEAT 0x4
#define SFX_FLAG_PERSISTENT 0x8
sfx_system *persisitent_source;
int in_queue;
- // Source buffer start
+ /* Source buffer start */
float *source, *replacement;
u32 clip_start, clip_end, buffer_length;
- // Modifiers
+ /* Modifiers */
sfx_vol_control *vol_src;
float vol, cvol;
- // Info
+ /* Info */
u32 ch, end, cur;
u32 flags;
- // Effects
+ /* Effects */
u32 fadeout, fadeout_current;
- // Diagnostic
+ /* Diagnostic */
const char *name;
};
-// Set of up to 8 sound effects packed into one
+/* Set of up to 8 sound effects packed into one */
typedef struct sfx_set sfx_set;
struct sfx_set
{
float *main;
char *sources;
- u32 segments[32]; //from->to,from->to ...
+ u32 segments[32]; /* from->to,from->to ... */
u32 numsegments;
u32 ch;
u32 flags;
ma_device g_aud_device;
ma_device_config g_aud_dconfig;
-// Thread 1 - audio engine ( spawned from miniaudio.h )
-// ======================================================
+/*
+ * Thread 1 - audio engine ( spawned from miniaudio.h )
+ * ======================================================
+ */
sfx_system sfx_sys[SFX_MAX_SYSTEMS];
int sfx_sys_len = 0;
-// Thread 0 - Critical transfer section
-// ======================================================
-MUTEX_TYPE sfx_mux_t01; // Resources share: 0 & 1
+/*
+ * Thread 0 - Critical transfer section
+ * ======================================================
+ */
+MUTEX_TYPE sfx_mux_t01; /* Resources share: 0 & 1 */
-sfx_system *sfx_q[SFX_MAX_SYSTEMS]; // Stuff changed
-int sfx_q_len = 0; // How much
+sfx_system *sfx_q[SFX_MAX_SYSTEMS]; /* Stuff changed */
+int sfx_q_len = 0;
-// x / 2
-// ======================================================
-
-// g_vol_master is never directly acessed by users
float g_master_volume = 1.f;
-// Decompress entire vorbis stream into buffer
-static float *sfx_vorbis_stream( const unsigned char *data, int len, int channels, u32 *samples )
+/* Decompress entire vorbis stream into buffer */
+static float *sfx_vorbis_stream( const unsigned char *data, int len,
+ int channels, u32 *samples )
{
int err;
stb_vorbis *pv = stb_vorbis_open_memory( data, len, &err, NULL );
}
u32 length_samples = stb_vorbis_stream_length_in_samples( pv );
- float *buffer = (float *)malloc( length_samples * channels * sizeof( float ));
+ float *buffer = (float *)malloc( length_samples * channels * sizeof(float));
if( !buffer )
{
return NULL;
}
- int read_samples = stb_vorbis_get_samples_float_interleaved( pv, channels, buffer, length_samples * channels );
+ int read_samples = stb_vorbis_get_samples_float_interleaved(
+ pv, channels, buffer, length_samples * channels );
+
if( read_samples != length_samples )
{
- vg_warn( "| warning: sample count mismatch. Expected %u got %i\n", length_samples, read_samples );
+ vg_warn( "| warning: sample count mismatch. Expected %u got %i\n",
+ length_samples, read_samples );
length_samples = read_samples;
}
}
}
-typedef struct sfx_bgload sfx_bgload_t;
-struct sfx_bgload
-{
- char *path;
- u32 channels;
-
- float *buffer;
- u32 samples;
-
- void *user;
-
- void(*OnComplete)(sfx_bgload_t *inf);
-};
-
-// Thread worker for background load job
-void *sfx_vorbis_a_t( void *_inf )
-{
- sfx_bgload_t *info = _inf;
-
- // Load the ogg clip
- info->buffer = sfx_vorbis( info->path, info->channels, &info->samples );
- info->OnComplete( info );
-
- return NULL;
-}
-
-// Asynchronous resource load
-int sfx_vorbis_a( const char *path, int channels, void(*OnComplete)(sfx_bgload_t *inf), void *user )
-{
- vg_info( "background job started for: %s\n", path );
-
- sfx_bgload_t *params = malloc( sizeof( sfx_bgload_t ) );
- params->path = malloc( strlen( path ) + 1 );
- strcpy( params->path, path );
- params->OnComplete = OnComplete;
- params->user = user;
- params->channels = channels;
-
- return vg_thread_run( sfx_vorbis_a_t, params );
-}
-
-// Asynchronous load-to-system callback
-struct sfx_vorbis_a_to_inf
-{
- sfx_system *sys;
- u32 flags;
-};
-
-#define SFX_A_FLAG_AUTOSTART 0x1
-#define SFX_A_FLAG_AUTOFREE 0x2
-
-/*
-static int sfx_save( sfx_system *sys );
-
-// Asynchronous load-to-system callback
-void sfx_vorbis_a_to_c( sfx_bgload_t *loadinf )
-{
- struct sfx_vorbis_a_to_inf *inf = loadinf->user;
-
- // Mark buffer for deallocation if autofree is set
- if( inf->flags & SFX_A_FLAG_AUTOFREE )
- inf->sys->replacement = loadinf->buffer;
- else
- inf->sys->source = loadinf->buffer;
-
- inf->sys->end = loadinf->samples;
-
- if( inf->flags & SFX_A_FLAG_AUTOSTART )
- sfx_save( inf->sys );
-
- free( loadinf->path );
- free( loadinf );
- free( inf );
-}
-
-// Asynchronous vorbis load into audio system
-void sfx_vorbis_a_to( sfx_system *sys, const char *strFileName, int channels, u32 flags )
-{
- struct sfx_vorbis_a_to_inf *inf = malloc( sizeof( struct sfx_vorbis_a_to_inf ) );
- inf->flags = flags;
- inf->sys = sys;
-
- sys->ch = channels;
-
- if( !sfx_vorbis_a( strFileName, channels, sfx_vorbis_a_to_c, inf ) )
- free( inf );
-}*/
-
-// 0
-// ======================================================
-
+/*
+ * thread 0 / client code
+ */
static int sfx_begin_edit( sfx_system *sys )
{
MUTEX_LOCK( sfx_mux_t01 );
MUTEX_UNLOCK( sfx_mux_t01 );
}
-// Mark change to be uploaded to queue system
+/* Mark change to be uploaded to queue system */
static int sfx_push( sfx_system *sys )
{
if( !sys->in_queue )
{
- // Mark change in queue
sfx_q[ sfx_q_len ++ ] = sys;
sys->in_queue = 1;
}
return 1;
}
-// Edit a volume float, has to be function wrapped because of mutex
+/* Edit a volume float, has to be function wrapped because of mutex */
static void sfx_vol_fset( sfx_vol_control *src, float to )
{
MUTEX_LOCK( sfx_mux_t01 );
MUTEX_UNLOCK( sfx_mux_t01 );
}
-// thread-safe get volume value
+/* thread-safe get volume value */
static float sfx_vol_fget( sfx_vol_control *src )
{
float val;
return val;
}
-// thread-safe set master volume
+/* thread-safe set master volume */
static void sfx_set_master( float to )
{
MUTEX_LOCK( sfx_mux_t01 );
MUTEX_UNLOCK( sfx_mux_t01 );
}
-// thread-safe get master volume
+/* thread-safe get master volume */
static float sfx_get_master(void)
{
float val;
void audio_mixer_callback( ma_device *pDevice, void *pOutBuf, const void *pInput, ma_uint32 frameCount );
-// Miniaudio.h init
static void vg_audio_init(void)
{
g_aud_dconfig = ma_device_config_init( ma_device_type_playback );
}
}
-// Shutdown audio device
static void vg_audio_free(void)
{
ma_device_uninit( &g_aud_device );
}
-// 1
-// ======================================================
+/*
+ * thread 1
+ */
-// Create and return slot for a sound
static sfx_system *sfx_alloc(void)
{
if( sfx_sys_len >= SFX_MAX_SYSTEMS )
return NULL;
- // A conditional is done against this in localization step,
- // Needs to be initialized.
+ /*
+ * A conditional is done against this in localization step,
+ * Needs to be initialized.
+ */
sfx_sys[ sfx_sys_len ].source = NULL;
return sfx_sys + (sfx_sys_len++);
}
-// Fetch samples into pcf
+/* Fetch samples into pcf */
static void audio_mixer_getsamples( float *pcf, float *source, u32 cur, u32 ch )
{
if( ch == 2 )
}
}
-// miniaudio.h interface
-void audio_mixer_callback( ma_device *pDevice, void *pOutBuf, const void *pInput, ma_uint32 frameCount )
+/*
+ * callback from miniaudio.h interface
+ */
+void audio_mixer_callback( ma_device *pDevice, void *pOutBuf,
+ const void *pInput, ma_uint32 frameCount )
{
- // Process incoming sound queue
+ /* Process incoming sound queue */
MUTEX_LOCK( sfx_mux_t01 );
while( sfx_q_len --> 0 )
src->in_queue = 0;
- // Copy
clone = sfx_alloc();
*clone = *src;
- // Links need to exist on persistent sounds
+ /* Links need to exist on persistent sounds */
clone->persisitent_source = src->flags & SFX_FLAG_PERSISTENT? src: NULL;
}
sfx_q_len = 0;
- // Volume modifiers
+ /* Volume modifiers */
for( int i = 0; i < sfx_sys_len; i ++ )
{
sfx_system *sys = sfx_sys + i;
- // Apply persistent volume if linked
+ /* Apply persistent volume if linked */
if( sys->flags & SFX_FLAG_PERSISTENT )
{
sys->vol = sys->persisitent_source->vol * g_master_volume;
- // Persistent triggers
- // -------------------
-
- // Fadeout effect ( + remove )
+ /* Fadeout effect ( + remove ) */
if( sys->persisitent_source->fadeout )
{
sys->fadeout_current = sys->persisitent_source->fadeout_current;
}
}
- // Apply volume slider if it has one linked
+ /* Apply volume slider if it has one linked */
if( sys->vol_src )
sys->cvol = sys->vol * sys->vol_src->val;
else
MUTEX_UNLOCK( sfx_mux_t01 );
- // Clear buffer
+ /* Clear buffer */
float *pOut32F = (float *)pOutBuf;
for( int i = 0; i < frameCount * 2; i ++ ){
pOut32F[i] = 0.f;
if( sys->fadeout )
{
- // Force this system to be removed now
+ /* Force this system to be removed now */
if( sys->fadeout_current == 0 )
{
sys->flags &= 0x00000000;
{
audio_mixer_getsamples( pcf, sys->source, cursor, sys->ch );
- float vol = sys->vol;
+ float vol = sys->cvol;
if( sys->fadeout )
{
}
}
- // Redistribute sound systems
+ /* Redistribute sound systems */
MUTEX_LOCK( sfx_mux_t01 );
u32 idx = 0, wr = 0;
{
sfx_system *src = sfx_sys + idx;
- // Keep only if cursor is before end or repeating
+ /* Keep only if cursor is before end or repeating */
if( src->cur < src->end || (src->flags & SFX_FLAG_REPEAT) )
{
sfx_sys[ wr ++ ] = sfx_sys[ idx ];
(void)pInput;
}
-// Load strings into sfx_set's memory
-// String layout: "sounda.ogg\0soundb.ogg\0soundc.ogg\0\0"
-static void sfx_set_strings( sfx_set *dest, char *strSources, u32 flags, int bAsync )
+/*
+ * Load strings into sfx_set's memory
+ * String layout: "sounda.ogg\0soundb.ogg\0soundc.ogg\0\0"
+ */
+static void sfx_set_strings( sfx_set *dest, char *strSources,
+ u32 flags, int bAsync )
{
dest->ch = (flags & SFX_FLAG_STEREO)? 2: 1;
if( nbuf )
{
dest->main = nbuf;
- memcpy( dest->main + (total-samples)*dest->ch, sound, samples*dest->ch*sizeof(float) );
+ memcpy( dest->main + (total-samples)*dest->ch,
+ sound, samples*dest->ch*sizeof(float) );
free( sound );
dest->segments[ dest->numsegments*2+0 ] = total-samples;
sys->end = source->segments[ id*2 + 1 ];
sys->ch = source->ch;
- // Diagnostics
+ /* for diagnostics */
sys->clip_start = sys->cur;
sys->clip_end = sys->end;
sys->buffer_length = source->segments[ (source->numsegments-1)*2 + 1 ];
}
}
-// Pick a random sound from the buffer and play it into system
-static void sfx_set_playrnd( sfx_set *source, sfx_system *sys, int min_id, int max_id )
+/* Pick a random sound from the buffer and play it into system */
+static void sfx_set_playrnd( sfx_set *source, sfx_system *sys,
+ int min_id, int max_id )
{
if( !source->numsegments )
return;
}
}
-// Free set resources
static void sfx_set_free( sfx_set *set )
{
free( set->main );