diff options
-rw-r--r-- | include/xas/spatial.h | 46 | ||||
-rw-r--r-- | src/spatial.c | 88 |
2 files changed, 116 insertions, 18 deletions
diff --git a/include/xas/spatial.h b/include/xas/spatial.h index 7f07b01..8b1ca05 100644 --- a/include/xas/spatial.h +++ b/include/xas/spatial.h @@ -3,12 +3,23 @@ #include <xas/audio.h> -#define XAS_SPATIAL_SPEED_M_S 343.0f +#define XAS_SPATIAL_DEFAULT_OBSERVER_WIDTH 0.18f +#define XAS_SPATIAL_DEFAULT_SPEED 343.0f /* m/s */ typedef struct _xas_spatial_coord { float x, y, z; } xas_spatial_coord; +typedef struct _xas_spatial_rotation { + float pitch, roll, yaw; +} xas_spatial_rotation; + +typedef struct _xas_spatial_observer { + xas_spatial_coord coord; + xas_spatial_rotation rotation; + float width; +} xas_spatial_observer; + typedef struct _xas_spatial_object xas_spatial_object; struct _xas_spatial_object { @@ -18,41 +29,38 @@ struct _xas_spatial_object { }; typedef struct _xas_spatial_scene { + xas_audio_format format; + + xas_spatial_observer observer; + xas_spatial_coord speaker_l, - speaker_r, - observer; + speaker_r; - float speed_m_s, - headwidth; + float speed; xas_spatial_object *first, *last; - xas_audio_stream *source; - void *buf; size_t buflen; } xas_spatial_scene; -xas_spatial_scene *xas_spatial_scene_new(xas_spatial_coord speaker_l, - xas_spatial_coord speaker_r, - xas_spatial_coord observer, - float headwidth); +xas_spatial_scene *xas_spatial_scene_new(xas_audio_format format, + xas_spatial_coord speaker_l, + xas_spatial_coord speaker_r); void xas_spatial_scene_destroy(xas_spatial_scene *scene); -void xas_spatial_scene_set_speed_m_s(xas_spatial_scene *scene, - float m_s); +int xas_spatial_scene_set_observer(xas_spatial_scene *scene, + xas_spatial_coord coord, + xas_spatial_rotation rotation, + float width); void xas_spatial_scene_set_speaker_coords(xas_spatial_scene *scene, xas_spatial_coord speaker_l, xas_spatial_coord speaker_r); -void xas_spatial_scene_set_observer_coords(xas_spatial_scene *scene, - xas_spatial_coord observer); - -void xas_spatial_scene_set_observer_headwidth(xas_spatial_scene *scene, - float headwidth); +void xas_spatial_scene_set_speed(xas_spatial_scene *scene, float speed); xas_spatial_object *xas_spatial_scene_add_object(xas_spatial_coord coord, xas_audio_stream *source); @@ -63,4 +71,6 @@ void xas_spatial_object_get_coord(xas_spatial_object *object, void xas_spatial_object_set_coord(xas_spatial_object *object, xas_spatial_coord coord); +xas_audio_stream *xas_spatial_scene_new_stream(xas_spatial_scene *scene); + #endif /* _XAS_SPATIAL_H */ diff --git a/src/spatial.c b/src/spatial.c new file mode 100644 index 0000000..809fce1 --- /dev/null +++ b/src/spatial.c @@ -0,0 +1,88 @@ +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include <xas/spatial.h> + +static inline float dist(xas_spatial_coord a, xas_spatial_coord b) { + return powf(powf(b.x - a.x, 2.0f) + + powf(b.y - a.y, 2.0f) + + powf(b.z - a.z, 2.0f), 0.5f); +} + +static int buf_realloc(xas_spatial_scene *scene, void *buf) { + float width = scene->observer.width, + speed = scene->speed; + + size_t sample_rate = scene->format.sample_rate, + stride = scene->format.channels * scene->format.sample_size, + count = floorf(width / (speed / sample_rate)); + + if ((buf = realloc(buf, stride * count)) == NULL) { + goto error_realloc; + } + + scene->buf = buf; + scene->buflen = count; + + return 0; + +error_realloc: + return -1; +} + +xas_spatial_scene *xas_spatial_scene_new(xas_audio_format format, + xas_spatial_coord speaker_l, + xas_spatial_coord speaker_r) { + xas_spatial_scene *scene; + + if ((scene = malloc(sizeof(*scene))) == NULL) { + goto error_malloc_scene; + } + + memset(scene, '\0', sizeof(*scene)); + + scene->format = format; + scene->speaker_l = speaker_l; + scene->speaker_r = speaker_r; + scene->speed = XAS_SPATIAL_DEFAULT_SPEED; + + if (buf_realloc(scene, NULL) < 0) { + goto error_buf_realloc; + } + + return scene; + +error_buf_realloc: + free(scene); + +error_malloc_scene: + return NULL; +} + +void xas_spatial_scene_destroy(xas_spatial_scene *scene) { + free(scene->buf); + free(scene); +} + +int xas_spatial_scene_set_observer(xas_spatial_scene *scene, + xas_spatial_coord coord, + xas_spatial_rotation rotation, + float width) { + scene->observer.coord = coord; + scene->observer.rotation = rotation; + scene->observer.width = width; + + return buf_realloc(scene, scene->buf); +} + +void xas_spatial_scene_set_speaker_coords(xas_spatial_scene *scene, + xas_spatial_coord speaker_l, + xas_spatial_coord speaker_r) { + scene->speaker_l = speaker_l; + scene->speaker_r = speaker_r; +} + +void xas_spatial_scene_set_speed(xas_spatial_scene *scene, float speed) { + scene->speed = speed; +} |