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; +} | 
 
    