Separated sound source from sound source's instance

dev
Shariq Shah 8 years ago
parent 1c246273dd
commit e2fd8e2411
  1. 2
      README.md
  2. 42
      src/common/common.h
  3. 35
      src/game/main.c
  4. 245
      src/game/sound.c
  5. 40
      src/game/sound.h
  6. 132
      src/libsymmetry/entity.c
  7. 18
      src/libsymmetry/entity.h
  8. 45
      src/libsymmetry/game.c

@ -155,7 +155,6 @@
- ## TODO
- Replace OpenAL with Soloud
- Store Materials in new format supported by parser
- Add model description file which has the same syntax supported by parser and modify old blender exporter to conform to new standards
- Implement sound/listener loading from scene file
@ -331,3 +330,4 @@
* Implmented writing to file through the new Parser and Parser_Objects
* Changed Config to read/write using new Parser and Parser_Objects
* Implemented Reading/Writing keybindings using new parser object
* Replaced OpenAL with Soloud with SDL2 backend

@ -15,6 +15,7 @@ extern struct Game_Api game;
struct Window;
struct Hashmap;
struct Sound_Source_Buffer;
// Function Pointer decls
typedef void (*Keyboard_Event_Func) (int key, int scancode, int state, int repeat, int mod_ctrl, int mod_shift, int mod_alt);
@ -38,21 +39,44 @@ enum Sound_Source_Type
ST_WAV_STREAM
};
enum Sound_Attenuation_Type
{
SA_NONE = 0, // No attenuation
SA_INVERSE, // Inverse distance attenuation model
SA_LINEAR, // Linear distance attenuation model
SA_EXPONENTIAL // Exponential distance attenuation model
};
struct Sound_Api
{
void (*update_3d)(void);
void (*volume_set)(float volume);
void (*listener_update)(float apos_x, float apos_y, float apos_z,
float afwd_x, float afwd_y, float afwd_z,
float aup_x, float aup_y, float aup_z);
void (*source_update)(uint source_handle, float apos_x, float apos_y, float apos_z);
uint (*source_create)(bool relative, const char* filename, int type);
void (*source_destroy)(uint source_handle);
void (*source_volume_set)(uint source_handle, float volume);
void (*source_loop_set)(uint source_handle, bool loop);
void (*source_play)(uint source_handle);
void (*source_pause)(uint source_handle);
void (*source_rewind)(uint source_handle);
void (*source_stop)(uint source_handle);
void (*source_instance_update_position)(uint source_instance, float apos_x, float apos_y, float apos_z);
uint (*source_instance_create)(struct Sound_Source_Buffer* source, bool is3d);
void (*source_instance_destroy)(uint source_instance);
void (*source_instance_volume_set)(uint source_instance, float volume);
void (*source_instance_loop_set)(uint source_instance, bool loop);
void (*source_instance_play)(uint source_instance);
void (*source_instance_pause)(uint source_instance);
void (*source_instance_rewind)(uint source_instance);
void (*source_instance_stop)(uint source_instance);
void (*source_instance_min_max_distance_set)(uint source_instance, float min_distance, float max_distance);
void (*source_instance_attenuation_set)(uint source_instance, int attenuation_type, float rolloff_factor);
float (*source_instance_volume_get)(uint source_instance);
bool (*source_instance_loop_get)(uint source_instance);
bool (*source_instance_is_paused)(uint source_instance);
struct Sound_Source_Buffer* (*source_create)(const char* filename, int type);
struct Sound_Source_Buffer* (*source_get)(const char* name);
void (*source_destroy)(const char* buffer_name);
void (*source_volume_set)(struct Sound_Source_Buffer* source, float volume);
void (*source_loop_set)(struct Sound_Source_Buffer* source, bool loop);
void (*source_stop_all)(struct Sound_Source_Buffer* source);
void (*source_min_max_distance_set)(struct Sound_Source_Buffer* source, float min_distance, float max_distance);
};
struct Window_Api

@ -64,17 +64,30 @@ int main(int argc, char** args)
.reload_game_lib = &game_lib_reload,
.sound =
{
.volume_set = &sound_volume_set,
.listener_update = &sound_listener_update,
.source_update = &sound_source_update,
.source_create = &sound_source_create,
.source_destroy = &sound_source_destroy,
.source_volume_set = &sound_source_volume_set,
.source_loop_set = &sound_source_loop_set,
.source_play = &sound_source_play,
.source_pause = &sound_source_pause,
.source_rewind = &sound_source_rewind,
.source_stop = &sound_source_stop
.update_3d = &sound_update_3d,
.volume_set = &sound_volume_set,
.listener_update = &sound_listener_update,
.source_instance_update_position = &sound_source_instance_update_position,
.source_instance_create = &sound_source_instance_create,
.source_instance_destroy = &sound_source_instance_destroy,
.source_instance_volume_set = &sound_source_instance_volume_set,
.source_instance_loop_set = &sound_source_instance_loop_set,
.source_instance_play = &sound_source_instance_play,
.source_instance_pause = &sound_source_instance_pause,
.source_instance_rewind = &sound_source_instance_rewind,
.source_instance_stop = &sound_source_instance_stop,
.source_instance_min_max_distance_set = &sound_source_instance_min_max_distance_set,
.source_instance_attenuation_set = &sound_source_instance_attenuation_set,
.source_instance_volume_get = &sound_source_instance_volume_get,
.source_instance_loop_get = &sound_source_instance_loop_get,
.source_instance_is_paused = &sound_source_instance_is_paused,
.source_create = &sound_source_create,
.source_get = &sound_source_get,
.source_destroy = &sound_source_destroy,
.source_volume_set = &sound_source_volume_set,
.source_loop_set = &sound_source_loop_set,
.source_stop_all = &sound_source_stop_all,
.source_min_max_distance_set = &sound_source_min_max_distance_set
},
.window =
{

@ -11,7 +11,7 @@
#include <soloud_c.h>
struct Sound_Buffer
struct Sound_Source_Buffer
{
int type;
union
@ -33,11 +33,11 @@ static struct Sound_State sound_state =
.volume = 1.f
};
static struct Hashmap* sound_buffers = NULL;
static struct Hashmap* sound_sources = NULL;
bool sound_init(void)
{
sound_buffers = hashmap_new();
sound_sources = hashmap_new();
sound_state.soloud_context = Soloud_create();
@ -55,8 +55,6 @@ bool sound_init(void)
0.f, 0.f, -1.f, // At
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));
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
afwd_x, afwd_y, afwd_z, // At
aup_x, aup_y, aup_z); // Up
Soloud_update3dAudio(sound_state.soloud_context);
}
void sound_volume_set(float volume)
@ -77,23 +74,30 @@ void sound_volume_set(float volume)
if(volume < 0.f) volume = 0.f;
sound_state.volume = 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)
{
char* key = NULL;
struct Variant* value = NULL;
HASHMAP_FOREACH(sound_buffers, key, value)
HASHMAP_FOREACH(sound_sources, key, value)
{
struct Sound_Buffer* buffer = value->val_voidptr;
switch(buffer->type)
struct Sound_Source_Buffer* source = value->val_voidptr;
sound_source_stop_all(source);
switch(source->type)
{
case ST_WAV: Wav_destroy(buffer->wav); break;
case ST_WAV_STREAM: WavStream_destroy(buffer->wavstream); break;
case ST_WAV: Wav_destroy(source->wav); break;
case ST_WAV_STREAM: WavStream_destroy(source->wavstream); break;
}
free(source);
}
hashmap_free(sound_buffers);
hashmap_free(sound_sources);
Soloud_deinit(sound_state.soloud_context);
Soloud_destroy(sound_state.soloud_context);
@ -101,36 +105,114 @@ void sound_cleanup(void)
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;
struct Sound_Buffer* buffer = NULL;
if(volume < 0.f) volume = 0.f;
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;
char* memory = io_file_read(DIRT_INSTALL, filename, "rb", &size);
//See if we've already loaded this file
if(hashmap_value_exists(sound_buffers, filename))
if(hashmap_value_exists(sound_sources, filename))
{
buffer = (struct Sound_Buffer*)hashmap_ptr_get(sound_buffers, filename);
if(relative)
{
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;
}
source = (struct Sound_Source_Buffer*)hashmap_ptr_get(sound_sources, filename);
return source;
}
buffer = malloc(sizeof(*buffer));
if(!buffer)
source = malloc(sizeof(*source));
if(!source)
{
log_error("sound:source_create", "Out of memory!");
return 0;
return NULL;
}
switch(type)
@ -142,12 +224,11 @@ uint sound_source_create(bool relative, const char* filename, int type)
if(rc != 0)
{
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;
}
buffer->type = ST_WAV;
buffer->wav = wave;
Wav_set3dAttenuation(wave, 1, 0.9f);
source->type = ST_WAV;
source->wav = wave;
}
break;
case ST_WAV_STREAM:
@ -157,67 +238,81 @@ uint sound_source_create(bool relative, const char* filename, int type)
if(rc != 0)
{
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;
}
buffer->type = ST_WAV_STREAM;
buffer->wavstream = wave_stream;
source->type = ST_WAV_STREAM;
}
break;
default: log_error("sound:source_create", "Invalid source type %d", type); return 0;
}
hashmap_ptr_set(sound_buffers, filename, (void*)buffer);
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;
}
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);
hashmap_ptr_set(sound_sources, filename, (void*)source);
return source;
}
void sound_source_volume_set(uint source_handle, float volume)
struct Sound_Source_Buffer* sound_source_get(const char* name)
{
if(volume < 0.f) volume = 0.f;
Soloud_setVolume(sound_state.soloud_context, source_handle, volume);
struct Sound_Source_Buffer* source = NULL;
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 volume)
{
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* source)
{
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)
{
Soloud_stop(sound_state.soloud_context, source_handle);
}
void sound_source_min_max_distance_set(struct Sound_Source_Buffer* source, float min_distance, float max_distance)
{
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;
}
}

@ -3,28 +3,40 @@
#include "../common/num_types.h"
#ifdef AL_DEBUG
#define al_check(expr) expr;
#else
#define al_check(expr) expr;
#endif
struct Sound_Source_Buffer;
bool sound_init(void);
void sound_cleanup(void);
void sound_volume_set(float volume);
void sound_update_3d(void);
void sound_listener_update(float apos_x, float apos_y, float apos_z,
float afwd_x, float afwd_y, float afwd_z,
float aup_x, float aup_y, float aup_z);
void sound_source_update(uint source_handle, float apos_x, float apos_y, float apos_z);
uint sound_source_create(bool relative, const char* filename, int type);
void sound_source_destroy(uint handle);
void sound_source_volume_set(uint handle, float volume);
void sound_source_loop_set(uint handle, bool loop);
void sound_source_play(uint handle);
void sound_source_pause(uint handle);
void sound_source_rewind(uint handle);
void sound_source_stop(uint handle);
void sound_source_instance_update_position(uint source_instance, float apos_x, float apos_y, float apos_z);
uint sound_source_instance_create(struct Sound_Source_Buffer* source, bool is3d);
void sound_source_instance_destroy(uint source_instance);
void sound_source_instance_volume_set(uint source_instance, float volume);
void sound_source_instance_loop_set(uint source_instance, bool loop);
void sound_source_instance_play(uint source_instance);
void sound_source_instance_pause(uint source_instance);
void sound_source_instance_rewind(uint source_instance);
void sound_source_instance_stop(uint source_instance);
void sound_source_instance_min_max_distance_set(uint source_instance, float min_distance, float max_distance);
void sound_source_instance_attenuation_set(uint source_instance, int attenuation_type, float rolloff_factor);
float sound_source_instance_volume_get(uint source_instance);
bool sound_source_instance_loop_get(uint source_instance);
bool sound_source_instance_is_paused(uint source_instance);
struct Sound_Source_Buffer* sound_source_create(const char* filename, int type);
struct Sound_Source_Buffer* sound_source_get(const char* name);
void sound_source_destroy(const char* buffer_name);
void sound_source_volume_set(struct Sound_Source_Buffer* source, float volume);
void sound_source_loop_set(struct Sound_Source_Buffer* source, bool loop);
void sound_source_stop_all(struct Sound_Source_Buffer* source);
void sound_source_min_max_distance_set(struct Sound_Source_Buffer* source, float min_distance, float max_distance);
#endif

@ -162,7 +162,7 @@ void entity_post_update(void)
transform_get_absolute_forward(entity, &abs_fwd);
transform_get_absolute_up(entity, &abs_up);
platform->sound.source_update(entity->sound_source.source_handle, abs_pos.x, abs_pos.y, abs_pos.z);
platform->sound.source_instance_update_position(entity->sound_source.source_instance, abs_pos.x, abs_pos.y, abs_pos.z);
}
if(entity->is_listener)
@ -270,11 +270,16 @@ bool entity_write(struct Entity* entity, struct Parser_Object* object)
}
case ET_SOUND_SOURCE:
{
hashmap_bool_set(entity_data, "active", entity->sound_source.active);
hashmap_bool_set(entity_data, "relative", entity->sound_source.relative);
hashmap_int_set(entity_data, "sound_type", entity->sound_source.type);
hashmap_str_set(entity_data, "wav_filename", entity->sound_source.wav_filename);
hashmap_bool_set(entity_data, "loop", entity->sound_source.loop);
struct Sound_Source* sound_source = &entity->sound_source;
hashmap_str_set(entity_data, "source_filename", sound_source->source_filename);
hashmap_bool_set(entity_data, "playing", sound_source->playing);
hashmap_int_set(entity_data, "sound_type", sound_source->type);
hashmap_bool_set(entity_data, "loop", sound_source->loop);
hashmap_float_set(entity_data, "volume", sound_source->volume);
hashmap_float_set(entity_data, "sound_min_distance", sound_source->min_distance);
hashmap_float_set(entity_data, "sound_max_distance", sound_source->max_distance);
hashmap_float_set(entity_data, "rolloff_factor", sound_source->rolloff_factor);
hashmap_int_set(entity_data, "sound_attenuation_type", sound_source->attenuation_type);
break;
}
};
@ -439,31 +444,61 @@ struct Entity* entity_read(struct Parser_Object* object)
case ET_SOUND_SOURCE:
{
struct Sound_Source* sound_source = &entity->sound_source;
sound_source->active = false;
sound_source->relative = false;
sound_source->loop = false;
sound_source->source_handle = 0;
sound_source->wav_filename = NULL;
sound_source->type = ST_WAV;
if(hashmap_value_exists(object->data, "active")) sound_source->active = hashmap_bool_get(object->data, "active");
if(hashmap_value_exists(object->data, "relative")) sound_source->relative = hashmap_bool_get(object->data, "relative");
if(hashmap_value_exists(object->data, "loop")) sound_source->loop = hashmap_bool_get(object->data, "loop");
if(hashmap_value_exists(object->data, "wav_filename")) sound_source->wav_filename = str_new(hashmap_str_get(object->data, "wav_filename"));
if(hashmap_value_exists(object->data, "sound_type")) sound_source->type = hashmap_int_get(object->data, "sound_type");
if(sound_source->wav_filename)
sound_source->type = ST_WAV;
sound_source->playing = false;
sound_source->loop = false;
sound_source->source_instance = 0;
sound_source->min_distance = 1.f;
sound_source->max_distance = 1000.f;
sound_source->volume = 1.f;
sound_source->rolloff_factor = 1.f;
sound_source->attenuation_type = SA_EXPONENTIAL;
sound_source->source = NULL;
sound_source->source_filename = NULL;
if(hashmap_value_exists(object->data, "playing")) sound_source->playing = hashmap_bool_get(object->data, "playing");
if(hashmap_value_exists(object->data, "loop")) sound_source->loop = hashmap_bool_get(object->data, "loop");
if(hashmap_value_exists(object->data, "sound_min_distance")) sound_source->min_distance = hashmap_float_get(object->data, "sound_min_distance");
if(hashmap_value_exists(object->data, "sound_max_distance")) sound_source->max_distance = hashmap_float_get(object->data, "sound_max_distance");
if(hashmap_value_exists(object->data, "volume")) sound_source->volume = hashmap_float_get(object->data, "volume");
if(hashmap_value_exists(object->data, "rolloff_factor")) sound_source->rolloff_factor = hashmap_float_get(object->data, "rolloff_factor");
if(hashmap_value_exists(object->data, "source_filename")) sound_source->source_filename = str_new(hashmap_str_get(object->data, "source_filename"));
if(hashmap_value_exists(object->data, "sound_type")) sound_source->type = hashmap_int_get(object->data, "sound_type");
if(hashmap_value_exists(object->data, "sound_attenuation_type")) sound_source->attenuation_type = hashmap_int_get(object->data, "sound_attenuation_type");
if(sound_source->source_filename)
{
sound_source->source_handle = platform->sound.source_create(sound_source->relative, sound_source->wav_filename, sound_source->type);
platform->sound.source_loop_set(sound_source->source_handle, sound_source->loop);
sound_source->source = platform->sound.source_create(sound_source->source_filename, sound_source->type);
if(sound_source->source)
{
sound_source->source_instance = platform->sound.source_instance_create(sound_source->source, true);
vec3 abs_pos = {0.f, 0.f, 0.f};
vec3 abs_fwd = {0.f, 0.f, -1.f};
vec3 abs_up = {0.f, 1.f, 0.f};
transform_get_absolute_pos(entity, &abs_pos);
transform_get_absolute_forward(entity, &abs_fwd);
transform_get_absolute_up(entity, &abs_up);
platform->sound.source_instance_update_position(entity->sound_source.source_instance, abs_pos.x, abs_pos.y, abs_pos.z);
platform->sound.source_instance_loop_set(sound_source->source_instance, sound_source->loop);
platform->sound.source_instance_min_max_distance_set(sound_source->source_instance, sound_source->min_distance, sound_source->max_distance);
platform->sound.source_instance_attenuation_set(sound_source->source_instance, sound_source->attenuation_type, sound_source->rolloff_factor);
platform->sound.source_instance_volume_set(sound_source->source_instance, sound_source->volume);
platform->sound.update_3d();
if(sound_source->playing) platform->sound.source_instance_play(sound_source->source_instance);
}
else
{
log_error("Failed to create sound source from '%s'", sound_source->source_filename);
free(sound_source->source_filename);
sound_source->source_filename = NULL;
}
}
else
{
log_error("entity:read", "No filename provided for sound source for entity '%s'", entity->name);
}
vec3 abs_pos = {0.f, 0.f, 0.f};
vec3 abs_fwd = {0.f, 0.f, -1.f};
vec3 abs_up = {0.f, 1.f, 0.f};
transform_get_absolute_pos(entity, &abs_pos);
transform_get_absolute_forward(entity, &abs_fwd);
transform_get_absolute_up(entity, &abs_up);
platform->sound.source_update(entity->sound_source.source_handle, abs_pos.x, abs_pos.y, abs_pos.z);
}
break;
case ET_PLAYER:
@ -572,4 +607,43 @@ const char* entity_type_name_get(struct Entity* entity)
default: typename = "Unknown"; break;
};
return typename;
}
void entity_apply_sound_params(struct Entity* entity)
{
if(entity->type != ET_SOUND_SOURCE) return;
struct Sound_Source* sound_source = &entity->sound_source;
// Check if sound source has no buffer attached but filename exists, this would mean we have to load the file first
if(!sound_source->source && sound_source->source_filename)
{
sound_source->source = platform->sound.source_create(sound_source->source_filename, sound_source->type);
if(!sound_source->source)
{
log_error("entity:sync_sound_params", "Failed to load file '%s' to provide sound source for entity %s", sound_source->source_filename, entity->name);
free(sound_source->source_filename);
sound_source->source_filename = NULL;
sound_source->source_instance = 0;
return;
}
}
if(sound_source->source_instance == 0) sound_source->source_instance = platform->sound.source_instance_create(sound_source->source, true);
vec3 abs_pos = {0.f, 0.f, 0.f};
vec3 abs_fwd = {0.f, 0.f, -1.f};
vec3 abs_up = {0.f, 1.f, 0.f};
transform_get_absolute_pos(entity, &abs_pos);
transform_get_absolute_forward(entity, &abs_fwd);
transform_get_absolute_up(entity, &abs_up);
platform->sound.source_instance_update_position(entity->sound_source.source_instance, abs_pos.x, abs_pos.y, abs_pos.z);
platform->sound.source_instance_loop_set(sound_source->source_instance, sound_source->loop);
platform->sound.source_instance_min_max_distance_set(sound_source->source_instance, sound_source->min_distance, sound_source->max_distance);
platform->sound.source_instance_attenuation_set(sound_source->source_instance, sound_source->attenuation_type, sound_source->rolloff_factor);
platform->sound.source_instance_volume_set(sound_source->source_instance, sound_source->volume);
platform->sound.update_3d();
if(sound_source->playing) platform->sound.source_instance_play(sound_source->source_instance);
}

@ -52,12 +52,17 @@ struct Model
struct Sound_Source
{
bool active;
int type;
bool relative;
bool loop;
char* wav_filename;
uint source_handle;
int type;
bool playing;
bool loop;
char* source_filename;
uint source_instance;
float min_distance;
float max_distance;
float rolloff_factor;
float volume;
int attenuation_type;
struct Sound_Source_Buffer* source;
};
struct Camera
@ -134,6 +139,7 @@ bool entity_load(const char* filename, int directory_type);
bool entity_write(struct Entity* entity, struct Parser_Object* object);
struct Entity* entity_read(struct Parser_Object* object);
const char* entity_type_name_get(struct Entity* entity);
void entity_apply_sound_params(struct Entity* entity); // Convenience function to sync the data set in entity's sound_source with the actual sound source's instance
#endif

@ -218,38 +218,24 @@ void scene_setup(void)
struct Entity* suz = entity_find("Suzanne");
struct Entity* sound_ent = scene_add_as_child("Sound_Ent", ET_SOUND_SOURCE, suz->id);
sound_ent->sound_source.source_handle = platform->sound.source_create(true, "sounds/teh_beatz.wav", ST_WAV);
platform->sound.source_loop_set(sound_ent->sound_source.source_handle, true);
platform->sound.source_play(sound_ent->sound_source.source_handle);
struct Sound_Source* sound_source = &sound_ent->sound_source;
sound_source->source_filename = str_new("sounds/teh_beatz.wav");
sound_source->type = ST_WAV;
sound_source->attenuation_type = SA_LINEAR;
sound_source->rolloff_factor = 0.95f;
sound_source->loop = true;
sound_source->volume = 1.f;
sound_source->min_distance = 1.f;
sound_source->max_distance = 50.f;
sound_source->playing = true;
sound_source->source_instance = 0;
sound_source->source = NULL;
entity_apply_sound_params(sound_ent);
//scene_save("parser_write.symtres", DIRT_INSTALL);
}
/*
FILE* obj_file = platform->file.open(DIRT_INSTALL, "obj_test.symtres", "rb");
if(obj_file)
{
struct Parser* parsed_file = parser_load_objects(obj_file, "obj_test.symtres");
log_message("%d objects read from %s", array_len(parsed_file->objects), "obj_test.symtres");
for(int i = 0; i < array_len(parsed_file->objects); i++)
{
struct Parser_Object* object = &parsed_file->objects[i];
if(object->type == PO_UNKNOWN)
log_message("Type : Unknown");
else if(object->type == PO_ENTITY)
log_message("Type : Entity");
else if(object->type == PO_MATERIAL)
log_message("Type : Material");
else if(object->type == PO_MODEL)
log_message("Type : Model");
hashmap_debug_print(object->data);
}
fclose(obj_file);
}
else
{
log_warning("Failed to open obj_test.symtres");
}*/
}
void debug(float dt)
@ -398,6 +384,7 @@ bool run(void)
render();
platform->window.swap_buffers(game_state->window);
entity_post_update();
platform->sound.update_3d();
}
return true;
}

Loading…
Cancel
Save