diff options
| author | XANTRONIX Development | 2022-03-17 11:44:36 -0400 | 
|---|---|---|
| committer | XANTRONIX Development | 2022-03-17 11:44:36 -0400 | 
| commit | d685f7a7c3f1abcc402e1ac8b808f2ccd16708ad (patch) | |
| tree | 49d9745d840f587ab5bf77ddf164491a53dd570e /src | |
| parent | 89401de8a6caecc8c283081e7036ad7c0b5d6a92 (diff) | |
| download | xas-d685f7a7c3f1abcc402e1ac8b808f2ccd16708ad.tar.gz xas-d685f7a7c3f1abcc402e1ac8b808f2ccd16708ad.tar.bz2 xas-d685f7a7c3f1abcc402e1ac8b808f2ccd16708ad.zip | |
Refactor to allow sequencing events on drones
Changes:
    * Consolidate xas_drone_vox into xas_drone
    * Refactor xas_drone to no longer be centered around spatial
      objects for its vocalisations
    * Add a two-tone beep system to drones to allow beeping according
      to mood
    * Consolidate head-oriented sound effects into a single spatial
      object within drones
    * Implement ability to add a mixer to a spatial scene
    * Allow setting spatial coordinates for objects generically; remove
      code from src/spatial.c for doing this specifically
Diffstat (limited to 'src')
| -rw-r--r-- | src/drone.c | 290 | ||||
| -rw-r--r-- | src/seq.c | 44 | ||||
| -rw-r--r-- | src/spatial.c | 19 | 
3 files changed, 240 insertions, 113 deletions
| diff --git a/src/drone.c b/src/drone.c index 096507f..fcd73ca 100644 --- a/src/drone.c +++ b/src/drone.c @@ -7,11 +7,97 @@  #include <xas/vox.h>  #include <xas/drone.h> +static inline int drone_beep(xas_drone *drone) { +    struct { +        size_t a, b; +        enum xas_synth_type b_type; +    } freqs[6] = { +        { 400,   0, XAS_SYNTH_SINE     }, +        { 600,   0, XAS_SYNTH_SINE     }, +        { 800,   0, XAS_SYNTH_SINE     }, +        { 300,   0, XAS_SYNTH_SINE     }, +        { 300, 200, XAS_SYNTH_SQUARE   }, +        { 400, 600, XAS_SYNTH_SAWTOOTH } +    }; + +    switch (drone->mood) { +        case XAS_DRONE_MOOD_NEUTRAL: +        case XAS_DRONE_MOOD_HAPPY: +        case XAS_DRONE_MOOD_FLIRTY: +        case XAS_DRONE_MOOD_SAD: +        case XAS_DRONE_MOOD_ANGRY: +        case XAS_DRONE_MOOD_DISTRESSED: +            xas_synth_set_frequency(drone->beep_a, freqs[drone->mood].a); +            xas_synth_set_frequency(drone->beep_b, freqs[drone->mood].b); +            xas_synth_set_type(     drone->beep_b, freqs[drone->mood].b_type); + +            break; +    } + +    return 0; +} + +static int drone_start(xas_drone *drone, size_t index) { +    switch (index) { +        case XAS_DRONE_INDEX_BANK: +            return xas_bank_player_start(drone->player); + +        case XAS_DRONE_INDEX_BEEP: +            return drone_beep(drone); + +        default: +            break; +    } + +    return 0; +} + +static int drone_stop(xas_drone *drone, size_t index) { +    switch (index) { +        case XAS_DRONE_INDEX_BANK: +            return xas_bank_player_stop(drone->player); + +        case XAS_DRONE_INDEX_BEEP: +            xas_synth_stop(drone->beep_a); +            xas_synth_stop(drone->beep_b); + +            break; +    } + +    return 0; +} + +static int drone_set_entry(xas_drone *drone, size_t index, size_t entry) { +    switch (index) { +        case XAS_DRONE_INDEX_BANK: +            return xas_bank_player_set_entry(drone->player, entry); + +        default: +            break; +    } + +    return 0; +} + +static int drone_set_flags(xas_drone *drone, int flags) { +    return xas_bank_player_set_flags(drone->player, flags); +} + +static xas_object_call_table call_table = { +    .start     = (xas_object_start_callback)drone_start, +    .stop      = (xas_object_stop_callback)drone_stop, +    .set_entry = (xas_object_set_entry_callback)drone_set_entry, +    .set_flags = (xas_object_set_flags_callback)drone_set_flags +}; +  xas_drone *xas_drone_new(xas_spatial_scene *scene,                               xas_spatial_coord position,                               size_t bank_entry_size,                               size_t bank_entry_count) {      xas_drone *drone; +    xas_object *objects[3]; + +    int i;      if ((drone = malloc(sizeof(*drone))) == NULL) {          goto error_malloc_drone; @@ -23,17 +109,85 @@ xas_drone *xas_drone_new(xas_spatial_scene *scene,          goto error_bank_new;      } -    if ((drone->obj = xas_spatial_scene_add_bank_player(scene, -                                                          position, -                                                          drone->bank)) == NULL) { -        goto error_spatial_scene_add_bank_player; +    if ((drone->sfx = xas_bank_new(scene->format, +                                     XAS_DRONE_SFX_BANK_SIZE, +                                     XAS_DRONE_SFX_BANK_ENTRIES)) == NULL) { +        goto error_bank_new_sfx; +    } + +    if ((drone->vox = xas_vox_new(scene->format, +                                    XAS_DRONE_VOX_BUFFER_SIZE, +                                    XAS_DRONE_VOX_TEXT2WAVE_PATH)) == NULL) { +        goto error_vox_new; +    } + +    if ((drone->player = xas_bank_player_new(drone->bank)) == NULL) { +        goto error_bank_player_new; +    } + +    if ((drone->beep_a = xas_synth_new(scene->format, +                                         XAS_DRONE_BEEP_BUFFER_SIZE, +                                         XAS_SYNTH_SINE)) == NULL) { +        goto error_synth_new_a;      } +    if ((drone->beep_b = xas_synth_new(scene->format, +                                         XAS_DRONE_BEEP_BUFFER_SIZE, +                                         XAS_SYNTH_SINE)) == NULL) { +        goto error_synth_new_b; +    } + +    if ((drone->mixer = xas_mixer_new(xas_audio_format_mono(scene->format), +                                        XAS_DRONE_MIXER_BUFFER_SIZE)) == NULL) { +        goto error_mixer_new; +    } + +    objects[0] = &drone->player->obj; +    objects[1] = &drone->beep_a->obj; +    objects[2] = &drone->beep_b->obj; + +    for (i=0; i<3; i++) { +        if ((xas_mixer_object_add(drone->mixer, +                                    objects[i], +                                    XAS_DRONE_MIXER_DEFAULT_GAIN, +                                    XAS_DRONE_MIXER_DEFAULT_PAN)) == NULL) { +            goto error_mixer_object_add; +        } +    } + +    if ((drone->head = xas_spatial_scene_add_mixer(scene, +                                                     position, +                                                     drone->mixer)) == NULL) { +        goto error_spatial_scene_add_mixer; +    } + +    drone->obj.table = &call_table; + +    drone->mood  = XAS_DRONE_MOOD_NEUTRAL;      drone->scene = scene;      return drone; -error_spatial_scene_add_bank_player: +error_spatial_scene_add_mixer: +error_mixer_object_add: +    xas_mixer_destroy(drone->mixer); + +error_mixer_new: +    xas_synth_destroy(drone->beep_b); + +error_synth_new_b: +    xas_synth_destroy(drone->beep_a); + +error_synth_new_a: +    xas_vox_destroy(drone->vox); + +error_vox_new: +    xas_bank_player_destroy(drone->player); + +error_bank_player_new: +    xas_bank_destroy(drone->sfx); + +error_bank_new_sfx:      xas_bank_destroy(drone->bank);  error_bank_new: @@ -44,6 +198,12 @@ error_malloc_drone:  }  void xas_drone_destroy(xas_drone *drone) { +    xas_mixer_destroy(drone->mixer); +    xas_synth_destroy(drone->beep_b); +    xas_synth_destroy(drone->beep_a); +    xas_bank_player_destroy(drone->player); +    xas_vox_destroy(drone->vox); +    xas_bank_destroy(drone->sfx);      xas_bank_destroy(drone->bank);      free(drone); @@ -62,7 +222,7 @@ ssize_t xas_drone_sample_record(xas_drone *drone,                                    size_t sample_index,                                    size_t sample_len) {      if (sample_index >= drone->bank->entry_count -     || sample_len > drone->bank->entry_size) { +     || sample_len   >  drone->bank->entry_size) {          errno = EINVAL;          goto error_invalid; @@ -113,7 +273,6 @@ int xas_drone_speech_import(xas_drone *drone,                                size_t sample_index,                                size_t sample_count,                                const char **speech_lines) { -    xas_drone_vox *vox;      size_t i, o;      if (sample_index + sample_count - 1 >= drone->bank->entry_count) { @@ -122,38 +281,26 @@ int xas_drone_speech_import(xas_drone *drone,          goto error_invalid;      } -    if ((vox = xas_drone_vox_new(drone)) == NULL) { -        goto error_vox_new; -    } -      if (voice) { -        xas_drone_vox_set_voice(vox, voice); +        xas_vox_set_voice(drone->vox, voice);      } -    xas_drone_vox_set_speed(vox, speed); +    xas_drone_vox_set_speed(drone, speed);      for (i=0, o=sample_index; i<sample_count; i++, o++) { -        if (xas_drone_vox_say(vox, speech_lines[i]) < 0) { +        if (xas_vox_say(drone->vox, speech_lines[i]) < 0) {              goto error_vox_say;          } -        if (xas_drone_vox_save(vox, o) < 0) { +        if (xas_drone_vox_save(drone, o) < 0) {              goto error_vox_save;          } - -        if (xas_vox_stop(vox->obj) < 0) { -            goto error_vox_stop_obj; -        }      } -    xas_drone_vox_destroy(vox); -      return 0; -error_vox_stop_obj:  error_vox_save:  error_vox_say: -error_vox_new:  error_invalid:      return -1;  } @@ -165,16 +312,18 @@ int xas_drone_seq_sample(xas_drone *drone,      struct timeval duration,                     tmp; -    if (xas_seq_add_set_bank(seq, -                               drone->obj, -                               *now, -                               speech_part) < 0) { +    if (xas_seq_add_set_bank_entry(seq, +                                     &drone->obj, +                                     *now, +                                     XAS_DRONE_INDEX_BANK, +                                     speech_part) < 0) {          goto error_xas_seq_add;      }      if (xas_seq_add_event_on(seq, -                               drone->obj, -                               *now) < 0) { +                               &drone->obj, +                               *now, +                               XAS_DRONE_INDEX_BANK) < 0) {          goto error_xas_seq_add;      } @@ -193,83 +342,54 @@ error_xas_seq_add:      return -1;  } -xas_drone_vox *xas_drone_vox_new(xas_drone *drone) { -    xas_drone_vox *vox; - -    if ((vox = malloc(sizeof(*vox))) == NULL) { -        goto error_malloc_vox; -    } - -    if ((vox->obj = xas_vox_new(drone->scene->format, -                                  XAS_DRONE_VOX_BUFFER_SIZE, -                                  XAS_DRONE_VOX_TEXT2WAVE_PATH)) == NULL) { -        goto error_vox_new; -    } - -    vox->drone = drone; - -    return vox; - -error_vox_new: -    free(vox); - -error_malloc_vox: -    return NULL; -} - -void xas_drone_vox_destroy(xas_drone_vox *vox) { -    xas_vox_destroy(vox->obj); -    free(vox); +int xas_drone_vox_set_voice(xas_drone *drone, const char *voice) { +    return xas_vox_set_voice(drone->vox, voice);  } -int xas_drone_vox_set_voice(xas_drone_vox *vox, const char *voice) { -    return xas_vox_set_voice(vox->obj, voice); -} - -int xas_drone_vox_set_speed(xas_drone_vox *vox, float speed) { -    return xas_vox_set_parameter_float(vox->obj, +int xas_drone_vox_set_speed(xas_drone *drone, float speed) { +    return xas_vox_set_parameter_float(drone->vox,                                           "Duration_Stretch",                                           1.0f / speed);  } -int xas_drone_vox_say(xas_drone_vox *vox, const char *text) { -    return xas_vox_say(vox->obj, text); +int xas_drone_vox_say(xas_drone *drone, const char *text) { +    return xas_vox_say(drone->vox, text);  } -int xas_drone_vox_vsayf(xas_drone_vox *vox, +int xas_drone_vox_vsayf(xas_drone *drone,                            const char *format,                            va_list args) { -    return xas_vox_vsayf(vox->obj, format, args); +    return xas_vox_vsayf(drone->vox, format, args);  } -int xas_drone_vox_sayf(xas_drone_vox *vox, const char *format, ...) { +int xas_drone_vox_sayf(xas_drone *drone, const char *format, ...) {      int ret;      va_list args;      va_start(args, format); -    ret = xas_vox_vsayf(vox->obj, format, args); +    ret = xas_vox_vsayf(drone->vox, format, args);      va_end(args);      return ret;  } -int xas_drone_vox_save(xas_drone_vox *vox, size_t sample_index) { +int xas_drone_vox_save(xas_drone *drone, size_t sample_index) {      xas_audio_stream *source; -    if ((source = xas_vox_stream_new(vox->obj)) == NULL) { +    if ((source = xas_vox_stream_new(drone->vox)) == NULL) {          goto error_vox_stream_new;      } -    if (xas_vox_generate(vox->obj) < 0) { +    if (xas_vox_generate(drone->vox) < 0) {          goto error_vox_generate;      } -    if (xas_bank_record(vox->drone->bank, +    if (xas_bank_record(drone->bank,                            source,                            sample_index, -                          vox->drone->bank->entry_size) < 0) { +                          drone->bank->entry_size) < 0) {          goto error_bank_record;      } @@ -367,7 +487,7 @@ void xas_drone_chamber_set_drone_gain(xas_drone_chamber *chamber, float gain) {      for (i=0; i<chamber->drone_count; i++) {          xas_drone *drone = chamber->drones[i]; -        xas_object_set_gain(drone->obj->ctx, gain); +        xas_object_set_gain(&drone->mixer->obj, gain);      }  } @@ -412,28 +532,28 @@ int xas_drone_chamber_seq_intervals(xas_drone_chamber *chamber,          };          if (xas_seq_add_set_frequency(seq, -                                        chamber->synth_l, +                                        chamber->synth_l->ctx,                                          *now,                                          intervals[i].freq_l) < 0) {              goto error_seq_add;          }          if (xas_seq_add_set_synth_type(seq, -                                         chamber->synth_l, +                                         chamber->synth_l->ctx,                                           *now,                                           intervals[i].type_l) < 0) {              goto error_seq_add;          }          if (xas_seq_add_set_frequency(seq, -                                        chamber->synth_r, +                                        chamber->synth_r->ctx,                                          *now,                                          intervals[i].freq_r) < 0) {              goto error_seq_add;          }          if (xas_seq_add_set_synth_type(seq, -                                         chamber->synth_r, +                                         chamber->synth_r->ctx,                                           *now,                                           intervals[i].type_r) < 0) {              goto error_seq_add; @@ -487,14 +607,18 @@ int xas_drone_chamber_seq_chorus(xas_drone_chamber *chamber,      for (i=0; i<chamber->drone_count; i++) {          xas_drone *drone = chamber->drones[i]; -        if (xas_seq_add_set_bank(seq, -                                   drone->obj, -                                   *now, -                                   speech_part) < 0) { +        if (xas_seq_add_set_bank_entry(seq, +                                         &drone->obj, +                                         *now, +                                         XAS_DRONE_INDEX_BANK, +                                         speech_part) < 0) {              goto error_seq_add;          } -        if (xas_seq_add_event_on(seq, drone->obj, *now) < 0) { +        if (xas_seq_add_event_on(seq, +                                   &drone->obj, +                                   *now, +                                   XAS_DRONE_INDEX_BANK) < 0) {              goto error_seq_add;          }      } @@ -157,7 +157,7 @@ static void event_sort(xas_seq *seq) {  }  int xas_seq_add_event_off(xas_seq *seq, -                            xas_spatial_object *object, +                            xas_object *object,                              struct timeval timestamp,                              size_t index) {      xas_seq_event *ev; @@ -185,7 +185,7 @@ error_malloc_ev:  }  int xas_seq_add_event_on(xas_seq *seq, -                           xas_spatial_object *object, +                           xas_object *object,                             struct timeval timestamp,                             size_t index) {      xas_seq_event *ev; @@ -213,7 +213,7 @@ error_malloc_ev:  }  int xas_seq_add_set_position(xas_seq *seq, -                               xas_spatial_object *object, +                               xas_object *object,                                 struct timeval timestamp,                                 xas_spatial_coord point) {      xas_seq_event *ev; @@ -241,7 +241,7 @@ error_malloc_ev:  }  int xas_seq_add_set_heading(xas_seq *seq, -                              xas_spatial_object *object, +                              xas_object *object,                                struct timeval timestamp,                                xas_spatial_coord heading) {      xas_seq_event *ev; @@ -269,7 +269,7 @@ error_malloc_ev:  }  int xas_seq_add_set_speed(xas_seq *seq, -                            xas_spatial_object *object, +                            xas_object *object,                              struct timeval timestamp,                              float speed) {      xas_seq_event *ev; @@ -297,7 +297,7 @@ error_malloc_ev:  }  int xas_seq_add_set_gain(xas_seq *seq, -                           xas_spatial_object *object, +                           xas_object *object,                             struct timeval timestamp,                             float gain) {      xas_seq_event *ev; @@ -325,7 +325,7 @@ error_malloc_ev:  }  int xas_seq_add_set_bank_entry(xas_seq *seq, -                                 xas_spatial_object *object, +                                 xas_object *object,                                   struct timeval timestamp,                                   size_t index,                                   size_t entry) { @@ -355,7 +355,7 @@ error_malloc_ev:  }  int xas_seq_add_set_player_flags(xas_seq *seq, -                                   xas_spatial_object *object, +                                   xas_object *object,                                     struct timeval timestamp,                                     int flags) {      xas_seq_event *ev; @@ -383,7 +383,7 @@ error_malloc_ev:  }  int xas_seq_add_set_synth_type(xas_seq *seq, -                                 xas_spatial_object *object, +                                 xas_object *object,                                   struct timeval timestamp,                                   enum xas_synth_type type) {      xas_seq_event *ev; @@ -411,7 +411,7 @@ error_malloc_ev:  }  int xas_seq_add_set_frequency(xas_seq *seq, -                                xas_spatial_object *object, +                                xas_object *object,                                  struct timeval timestamp,                                  size_t frequency) {      xas_seq_event *ev; @@ -439,7 +439,7 @@ error_malloc_ev:  }  int xas_seq_add_phrase(xas_seq *seq, -                         xas_spatial_object *object, +                         xas_object *object,                           struct timeval timestamp,                           const char *phrase) {      xas_seq_event *ev; @@ -495,10 +495,10 @@ error_malloc_ev:  static int event_trigger(xas_spatial_scene *scene, xas_seq_event *ev) {      switch (ev->type) {          case XAS_SEQ_EVENT_OFF: -            return xas_object_stop(ev->object->ctx, ev->index); +            return xas_object_stop(ev->object, ev->index);          case XAS_SEQ_EVENT_ON: -            return xas_object_start(ev->object->ctx, ev->index); +            return xas_object_start(ev->object, ev->index);          case XAS_SEQ_EVENT_SET_POSITION:              xas_spatial_scene_position_object(scene, @@ -508,43 +508,43 @@ static int event_trigger(xas_spatial_scene *scene, xas_seq_event *ev) {              break;          case XAS_SEQ_EVENT_SET_HEADING: -            ev->object->heading = ev->heading; +            xas_object_set_heading(ev->object, ev->heading);              break;          case XAS_SEQ_EVENT_SET_SPEED: -            ev->object->speed = ev->speed; +            xas_object_set_speed(ev->object, ev->speed);              break;          case XAS_SEQ_EVENT_SET_GAIN: -            xas_object_set_gain(ev->object->ctx, ev->gain); +            xas_object_set_gain(ev->object, ev->gain);              break;          case XAS_SEQ_EVENT_SET_FREQUENCY: -            xas_synth_set_frequency(ev->object->ctx, ev->frequency); +            xas_object_set_freq(ev->object, ev->frequency);              break;          case XAS_SEQ_EVENT_SET_SYNTH_TYPE: -            xas_synth_set_type(ev->object->ctx, ev->synth_type); +            xas_synth_set_type((xas_synth *)ev->object, ev->synth_type);              break;          case XAS_SEQ_EVENT_SET_BANK_ENTRY: -            xas_object_set_entry(ev->object->ctx, ev->index, ev->entry); +            xas_object_set_entry(ev->object, ev->index, ev->entry);              break;          case XAS_SEQ_EVENT_SET_PLAYER_FLAGS: -            xas_object_set_flags(ev->object->ctx, ev->flags); +            xas_object_set_flags(ev->object, ev->flags);              break;          case XAS_SEQ_EVENT_SPEECH: -            xas_vox_say(ev->object->ctx, ev->phrase); -            xas_vox_generate(ev->object->ctx); +            xas_vox_say((xas_vox *)ev->object, ev->phrase); +            xas_vox_generate((xas_vox *)ev->object);              break; diff --git a/src/spatial.c b/src/spatial.c index 0cc58e9..68c7d41 100644 --- a/src/spatial.c +++ b/src/spatial.c @@ -569,6 +569,15 @@ error_bank_player_new:      return NULL;  } +xas_spatial_object *xas_spatial_scene_add_mixer(xas_spatial_scene *scene, +                                                    xas_spatial_coord point, +                                                    xas_mixer *mixer) { +    return xas_spatial_scene_add_object(scene, +                                          point, +                                          xas_mixer_output(mixer), +                                          mixer); +} +  xas_spatial_object *xas_spatial_scene_add_vox(xas_spatial_scene *scene,                                                    xas_spatial_coord point,                                                    const char *text2wave_path) { @@ -608,9 +617,9 @@ error_vox_new:  }  void xas_spatial_scene_position_object(xas_spatial_scene *scene, -                                         xas_spatial_object *object, +                                         xas_object *object,                                           xas_spatial_coord point) { -    object->point = point; +    xas_object_set_point(object, point);      object_update_delays(scene);  } @@ -623,12 +632,6 @@ xas_audio_stream *xas_spatial_scene_stream_new(xas_spatial_scene *scene,                                           buffer_size,                                           scene);  } -void xas_spatial_object_get_point(xas_spatial_object *object, -                                    xas_spatial_coord *point) { -    point->x = object->point.x; -    point->y = object->point.y; -    point->z = object->point.z; -}  float xas_spatial_object_get_speed(xas_spatial_object *object) {      return object->speed; | 
 
    