summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/xas/spatial.h46
-rw-r--r--src/spatial.c88
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;
+}