@ -11,7 +11,7 @@
# include <soloud_c.h>
# include <soloud_c.h>
struct Sound_Buffer
struct Sound_Source_ Buffer
{
{
int type ;
int type ;
union
union
@ -33,11 +33,11 @@ static struct Sound_State sound_state =
. volume = 1.f
. volume = 1.f
} ;
} ;
static struct Hashmap * sound_buffer s = NULL ;
static struct Hashmap * sound_source s = NULL ;
bool sound_init ( void )
bool sound_init ( void )
{
{
sound_buffer s = hashmap_new ( ) ;
sound_source s = hashmap_new ( ) ;
sound_state . soloud_context = Soloud_create ( ) ;
sound_state . soloud_context = Soloud_create ( ) ;
@ -55,8 +55,6 @@ bool sound_init(void)
0.f , 0.f , - 1.f , // At
0.f , 0.f , - 1.f , // At
0.f , 1.f , 0.f ) ; // Up
0.f , 1.f , 0.f ) ; // Up
Soloud_update3dAudio ( sound_state . soloud_context ) ;
log_message ( " Sound initialized with %s " , Soloud_getBackendString ( sound_state . soloud_context ) ) ;
log_message ( " Sound initialized with %s " , Soloud_getBackendString ( sound_state . soloud_context ) ) ;
return true ;
return true ;
}
}
@ -69,7 +67,6 @@ void sound_listener_update(float apos_x, float apos_y, float apos_z,
apos_x , apos_y , apos_z , // Position
apos_x , apos_y , apos_z , // Position
afwd_x , afwd_y , afwd_z , // At
afwd_x , afwd_y , afwd_z , // At
aup_x , aup_y , aup_z ) ; // Up
aup_x , aup_y , aup_z ) ; // Up
Soloud_update3dAudio ( sound_state . soloud_context ) ;
}
}
void sound_volume_set ( float volume )
void sound_volume_set ( float volume )
@ -77,23 +74,30 @@ void sound_volume_set(float volume)
if ( volume < 0.f ) volume = 0.f ;
if ( volume < 0.f ) volume = 0.f ;
sound_state . volume = volume ;
sound_state . volume = volume ;
Soloud_setGlobalVolume ( sound_state . soloud_context , sound_state . volume ) ;
Soloud_setGlobalVolume ( sound_state . soloud_context , sound_state . volume ) ;
}
void sound_update_3d ( void )
{
Soloud_update3dAudio ( sound_state . soloud_context ) ;
}
}
void sound_cleanup ( void )
void sound_cleanup ( void )
{
{
char * key = NULL ;
char * key = NULL ;
struct Variant * value = NULL ;
struct Variant * value = NULL ;
HASHMAP_FOREACH ( sound_buffer s , key , value )
HASHMAP_FOREACH ( sound_source s , key , value )
{
{
struct Sound_Buffer * buffer = value - > val_voidptr ;
struct Sound_Source_Buffer * source = value - > val_voidptr ;
switch ( buffer - > type )
sound_source_stop_all ( source ) ;
switch ( source - > type )
{
{
case ST_WAV : Wav_destroy ( buffer - > wav ) ; break ;
case ST_WAV : Wav_destroy ( source - > wav ) ; break ;
case ST_WAV_STREAM : WavStream_destroy ( buffer - > wavstream ) ; break ;
case ST_WAV_STREAM : WavStream_destroy ( source - > wavstream ) ; break ;
}
}
free ( source ) ;
}
}
hashmap_free ( sound_buffer s ) ;
hashmap_free ( sound_source s ) ;
Soloud_deinit ( sound_state . soloud_context ) ;
Soloud_deinit ( sound_state . soloud_context ) ;
Soloud_destroy ( sound_state . soloud_context ) ;
Soloud_destroy ( sound_state . soloud_context ) ;
@ -101,36 +105,114 @@ void sound_cleanup(void)
sound_state . soloud_context = NULL ;
sound_state . soloud_context = NULL ;
}
}
uint sound_source_create ( bool relative , const char * filename , int type )
void sound_source_instance_destroy ( uint source_instance )
{
Soloud_stop ( sound_state . soloud_context , source_instance ) ;
}
void sound_source_instance_update_position ( uint source_instance , float apos_x , float apos_y , float apos_z )
{
Soloud_set3dSourceParameters ( sound_state . soloud_context , source_instance , apos_x , apos_y , apos_z ) ;
}
uint sound_source_instance_create ( struct Sound_Source_Buffer * source , bool is3d )
{
assert ( source ) ;
uint source_instance = 0 ;
if ( is3d )
{
source_instance = Soloud_play3dEx ( sound_state . soloud_context ,
source - > type = = ST_WAV ? source - > wav : source - > wavstream ,
0.f , 0.f , 0.f ,
0.f , 0.f , 0.f ,
1.f ,
true ,
0 ) ;
}
else
{
source_instance = Soloud_playEx ( sound_state . soloud_context , source - > type = = ST_WAV ? source - > wav : source - > wavstream , 1.f , 0.0f , true , 0 ) ;
}
return source_instance ;
}
void sound_source_instance_volume_set ( uint source_instance , float volume )
{
{
uint handle = 0 ;
if ( volume < 0.f ) volume = 0.f ;
struct Sound_Buffer * buffer = NULL ;
Soloud_setVolume ( sound_state . soloud_context , source_instance , volume ) ;
}
void sound_source_instance_loop_set ( uint source_instance , bool loop )
{
Soloud_setLooping ( sound_state . soloud_context , source_instance , loop ) ;
}
void sound_source_instance_play ( uint source_instance )
{
Soloud_setPause ( sound_state . soloud_context , source_instance , false ) ;
}
void sound_source_instance_pause ( uint source_instance )
{
Soloud_setPause ( sound_state . soloud_context , source_instance , true ) ;
}
void sound_source_instance_rewind ( uint source_instance )
{
Soloud_seek ( sound_state . soloud_context , source_instance , 0.0 ) ;
}
void sound_source_instance_stop ( uint source_instance )
{
Soloud_stop ( sound_state . soloud_context , source_instance ) ;
}
void sound_source_instance_min_max_distance_set ( uint source_instance , float min_distance , float max_distance )
{
Soloud_set3dSourceMinMaxDistance ( sound_state . soloud_context , source_instance , min_distance , max_distance ) ;
}
void sound_source_instance_attenuation_set ( uint source_instance , int attenuation_type , float rolloff_factor )
{
Soloud_set3dSourceAttenuation ( sound_state . soloud_context , source_instance , attenuation_type , rolloff_factor ) ;
}
float sound_source_instance_volume_get ( uint source_instance )
{
return Soloud_getVolume ( sound_state . soloud_context , source_instance ) ;
}
bool sound_source_instance_loop_get ( uint source_instance )
{
return Soloud_getLooping ( sound_state . soloud_context , source_instance ) ;
}
bool sound_source_instance_is_paused ( uint source_instance )
{
return Soloud_getPause ( sound_state . soloud_context , source_instance ) ;
}
struct Sound_Source_Buffer * sound_source_create ( const char * filename , int type )
{
if ( ! filename ) return NULL ;
struct Sound_Source_Buffer * source = NULL ;
long size = 0L ;
long size = 0L ;
char * memory = io_file_read ( DIRT_INSTALL , filename , " rb " , & size ) ;
char * memory = io_file_read ( DIRT_INSTALL , filename , " rb " , & size ) ;
//See if we've already loaded this file
//See if we've already loaded this file
if ( hashmap_value_exists ( sound_buffers , filename ) )
if ( hashmap_value_exists ( sound_source s , filename ) )
{
{
buffer = ( struct Sound_Buffer * ) hashmap_ptr_get ( sound_buffers , filename ) ;
source = ( struct Sound_Source_Buffer * ) hashmap_ptr_get ( sound_sources , filename ) ;
if ( relative )
return source ;
{
handle = Soloud_play3dEx ( sound_state . soloud_context ,
type = = ST_WAV ? buffer - > wav : buffer - > wavstream ,
0.f , 0.f , 0.f ,
0.f , 0.f , 0.f ,
1.f ,
true ,
0 ) ;
return handle ;
}
}
}
buffer = malloc ( sizeof ( * buffer ) ) ;
source = malloc ( sizeof ( * source ) ) ;
if ( ! buffer )
if ( ! source )
{
{
log_error ( " sound:source_create " , " Out of memory! " ) ;
log_error ( " sound:source_create " , " Out of memory! " ) ;
return 0 ;
return NULL ;
}
}
switch ( type )
switch ( type )
@ -142,12 +224,11 @@ uint sound_source_create(bool relative, const char* filename, int type)
if ( rc ! = 0 )
if ( rc ! = 0 )
{
{
log_error ( " sound:source_create " , " Failed to load %s, Soloud: %s " , filename , Soloud_getErrorString ( sound_state . soloud_context , rc ) ) ;
log_error ( " sound:source_create " , " Failed to load %s, Soloud: %s " , filename , Soloud_getErrorString ( sound_state . soloud_context , rc ) ) ;
free ( buffer ) ;
free ( source ) ;
return 0 ;
return 0 ;
}
}
buffer - > type = ST_WAV ;
source - > type = ST_WAV ;
buffer - > wav = wave ;
source - > wav = wave ;
Wav_set3dAttenuation ( wave , 1 , 0.9f ) ;
}
}
break ;
break ;
case ST_WAV_STREAM :
case ST_WAV_STREAM :
@ -157,67 +238,81 @@ uint sound_source_create(bool relative, const char* filename, int type)
if ( rc ! = 0 )
if ( rc ! = 0 )
{
{
log_error ( " sound:source_create " , " Failed to load %s, Soloud: %s " , filename , Soloud_getErrorString ( sound_state . soloud_context , rc ) ) ;
log_error ( " sound:source_create " , " Failed to load %s, Soloud: %s " , filename , Soloud_getErrorString ( sound_state . soloud_context , rc ) ) ;
free ( buffer ) ;
free ( source ) ;
return 0 ;
return 0 ;
}
}
buffer - > type = ST_WAV_STREAM ;
source - > type = ST_WAV_STREAM ;
buffer - > wavstream = wave_stream ;
}
}
break ;
break ;
default : log_error ( " sound:source_create " , " Invalid source type %d " , type ) ; return 0 ;
default : log_error ( " sound:source_create " , " Invalid source type %d " , type ) ; return 0 ;
}
}
hashmap_ptr_set ( sound_buffers , filename , ( void * ) buffer ) ;
hashmap_ptr_set ( sound_sources , filename , ( void * ) source ) ;
handle = Soloud_play3dEx ( sound_state . soloud_context ,
return source ;
type = = ST_WAV ? buffer - > wav : buffer - > wavstream ,
0.f , 0.f , 0.f ,
0.f , 0.f , 0.f ,
1.f ,
true ,
0 ) ;
return handle ;
}
void sound_source_destroy ( uint source_handle )
{
Soloud_stop ( sound_state . soloud_context , source_handle ) ;
}
void sound_source_update ( uint source_handle , float apos_x , float apos_y , float apos_z )
{
Soloud_set3dSourceParameters ( sound_state . soloud_context , source_handle , apos_x , apos_y , apos_z ) ;
Soloud_update3dAudio ( sound_state . soloud_context ) ;
}
}
void sound_source_volume_set ( uint source_handle , float volu me)
struct Sound_Source_Buffer * sound_source_get ( const char * name )
{
{
if ( volume < 0.f ) volume = 0.f ;
struct Sound_Source_Buffer * source = NULL ;
Soloud_setVolume ( sound_state . soloud_context , source_handle , volume ) ;
if ( hashmap_value_exists ( sound_sources , name ) )
{
source = ( struct Sound_Source_Buffer * ) hashmap_ptr_get ( sound_sources , name ) ;
}
return source ;
}
}
void sound_source_loop_set ( uint source_handle , bool loop )
void sound_source_destroy ( const char * name )
{
{
Soloud_setLooping ( sound_state . soloud_context , source_handle , loop ) ;
struct Sound_Source_Buffer * source = sound_source_get ( name ) ;
if ( source )
{
sound_source_stop_all ( source ) ;
switch ( source - > type )
{
case ST_WAV : Wav_destroy ( source - > wav ) ; break ;
case ST_WAV_STREAM : WavStream_destroy ( source - > wavstream ) ; break ;
}
free ( source ) ;
}
hashmap_value_remove ( sound_sources , name ) ;
}
}
void sound_source_play ( uint source_handle )
void sound_source_volume_set ( struct Sound_Source_Buffer * source , float volum e )
{
{
Soloud_setPause ( sound_state . soloud_context , source_handle , false ) ;
assert ( source ) ;
switch ( source - > type )
{
case ST_WAV : Wav_setVolume ( source - > wav , volume ) ; break ;
case ST_WAV_STREAM : WavStream_setVolume ( source - > wavstream , volume ) ; break ;
}
}
}
void sound_source_pause ( uint source_handle )
void sound_source_loop_set ( struct Sound_Source_Buffer * source , bool loop )
{
{
Soloud_setPause ( sound_state . soloud_context , source_handle , true ) ;
assert ( source ) ;
switch ( source - > type )
{
case ST_WAV : Wav_setLooping ( source - > wav , loop ) ; break ;
case ST_WAV_STREAM : WavStream_setLooping ( source - > wavstream , loop ) ; break ;
}
}
}
void sound_source_rewind ( uint source_handle )
void sound_source_stop_all ( struct Sound_Source_Buffer * sourc e )
{
{
Soloud_seek ( sound_state . soloud_context , source_handle , 0.0 ) ;
assert ( source ) ;
switch ( source - > type )
{
case ST_WAV : Soloud_stopAudioSource ( sound_state . soloud_context , source - > wav ) ; break ;
case ST_WAV_STREAM : Soloud_stopAudioSource ( sound_state . soloud_context , source - > wavstream ) ; break ;
}
}
}
void sound_source_stop ( uint source_handle )
void sound_source_min_max_distance_set ( struct Sound_Source_Buffer * source , float min_distance , float max_distance )
{
{
Soloud_stop ( sound_state . soloud_context , source_handle ) ;
assert ( source ) ;
}
switch ( source - > type )
{
case ST_WAV : Wav_set3dMinMaxDistance ( source - > wav , min_distance , max_distance ) ; break ;
case ST_WAV_STREAM : WavStream_set3dMinMaxDistance ( source - > wavstream , min_distance , max_distance ) ; break ;
}
}