Beispiel #1
0
// Recevied a reply to a trigger ("sim.reply")
static void reply_cb (flux_t *h,
                      flux_msg_handler_t *w,
                      const flux_msg_t *msg,
                      void *arg)
{
    const char *json_str = NULL;
    json_t *request = NULL;
    ctx_t *ctx = arg;
    sim_state_t *curr_sim_state = ctx->sim_state;
    sim_state_t *reply_sim_state;

    if (flux_msg_get_json (msg, &json_str) < 0 || json_str == NULL
        || !(request = Jfromstr (json_str))) {
        flux_log (h, LOG_ERR, "%s: bad reply message", __FUNCTION__);
        Jput (request);
        return;
    }

    // De-serialize and get new info
    reply_sim_state = json_to_sim_state (request);
    copy_new_state_data (ctx, curr_sim_state, reply_sim_state);

    if (handle_next_event (ctx) < 0) {
        flux_log (h, LOG_DEBUG, "No events remaining");
        if (ctx->exit_on_complete) {
            log_msg_exit ("exit_on_complete is set. Exiting now.");
        } else {
            send_complete_event (h);
        }
    }

    free_simstate (reply_sim_state);
    Jput (request);
}
Beispiel #2
0
static gboolean
parse_MTrk (GstMidiParse * midiparse, guint8 * data, guint size)
{
  GstMidiTrack *track;
  GstClockTime duration;

  /* ignore excess tracks */
  if (midiparse->track_count >= midiparse->ntracks)
    return TRUE;

  track = g_slice_new (GstMidiTrack);
  track->data = data;
  track->size = size;
  reset_track (track, midiparse);

  midiparse->tracks = g_list_append (midiparse->tracks, track);
  midiparse->track_count++;

  /* now loop over all events and calculate the duration */
  while (!track->eot) {
    handle_next_event (midiparse, track, NULL, NULL);
  }

  duration = gst_util_uint64_scale (track->pulse,
      1000 * midiparse->tempo, midiparse->division);

  GST_DEBUG_OBJECT (midiparse, "duration %" GST_TIME_FORMAT,
      GST_TIME_ARGS (duration));

  if (duration > midiparse->segment.duration)
    midiparse->segment.duration = duration;

  reset_track (track, midiparse);

  return TRUE;
}
Beispiel #3
0
static GstFlowReturn
gst_midi_parse_do_play (GstMidiParse * midiparse)
{
  GstFlowReturn res;
  GList *walk;
  guint64 pulse, next_pulse = G_MAXUINT64;
  GstClockTime position, next_position;
  guint64 tick;

  pulse = midiparse->pulse;
  position = midiparse->segment.position;

  if (midiparse->segment_pending) {
    gst_pad_push_event (midiparse->srcpad,
        gst_event_new_segment (&midiparse->segment));
    midiparse->segment_pending = FALSE;
  }

  GST_DEBUG_OBJECT (midiparse, "pulse %" G_GUINT64_FORMAT ", position %"
      GST_TIME_FORMAT, pulse, GST_TIME_ARGS (position));

  for (walk = midiparse->tracks; walk; walk = g_list_next (walk)) {
    GstMidiTrack *track = walk->data;

    while (!track->eot && track->pulse == pulse) {
      res = handle_next_event (midiparse, track, play_push_func, NULL);
      if (res != GST_FLOW_OK)
        goto error;
    }

    if (!track->eot && track->pulse < next_pulse)
      next_pulse = track->pulse;
  }

  if (next_pulse == G_MAXUINT64)
    goto eos;

  tick = position / (10 * GST_MSECOND);
  GST_DEBUG_OBJECT (midiparse, "current tick %" G_GUINT64_FORMAT, tick);

  next_position = gst_util_uint64_scale (next_pulse,
      1000 * midiparse->tempo, midiparse->division);
  GST_DEBUG_OBJECT (midiparse, "next position %" GST_TIME_FORMAT,
      GST_TIME_ARGS (next_position));

  /* send 10ms ticks to advance the downstream element */
  while (TRUE) {
    /* get position of next tick */
    position = ++tick * (10 * GST_MSECOND);
    GST_DEBUG_OBJECT (midiparse, "tick %" G_GUINT64_FORMAT
        ", position %" GST_TIME_FORMAT, tick, GST_TIME_ARGS (position));

    if (position >= next_position)
      break;

    midiparse->segment.position = position;
    res = play_push_func (midiparse, NULL, 0xf9, NULL, 0, NULL);
    if (res != GST_FLOW_OK)
      goto error;
  }

  midiparse->pulse = next_pulse;
  midiparse->segment.position = next_position;

  return GST_FLOW_OK;

  /* ERRORS */
eos:
  {
    GST_DEBUG_OBJECT (midiparse, "we are EOS");
    return GST_FLOW_EOS;
  }
error:
  {
    GST_DEBUG_OBJECT (midiparse, "have flow result %s",
        gst_flow_get_name (res));
    return res;
  }
}
Beispiel #4
0
// Recevied a request to join the simulation ("sim.join")
static void join_cb (flux_t *h,
                     flux_msg_handler_t *w,
                     const flux_msg_t *msg,
                     void *arg)
{
    int mod_rank;
    json_t *request = NULL;
    const char *mod_name = NULL, *json_str = NULL;
    double *next_event = (double *)malloc (sizeof (double));
    ctx_t *ctx = arg;
    sim_state_t *sim_state = ctx->sim_state;
    uint32_t size;

    if (flux_msg_get_json (msg, &json_str) < 0 || json_str == NULL
        || !(request = Jfromstr (json_str))
        || !Jget_str (request, "mod_name", &mod_name)
        || !Jget_int (request, "rank", &mod_rank)
        || !Jget_double (request, "next_event", next_event)) {
        flux_log (h, LOG_ERR, "%s: bad join message", __FUNCTION__);
        goto out;
    }
    if (flux_get_size (h, &size) < 0)
        goto out;
    if (mod_rank < 0 || mod_rank >= size) {
        flux_log (h, LOG_ERR, "%s: bad rank in join message", __FUNCTION__);
        goto out;
    }

    flux_log (h,
              LOG_DEBUG,
              "join rcvd from module %s on rank %d, next event at %f",
              mod_name,
              mod_rank,
              *next_event);

    zhash_t *timers = sim_state->timers;
    if (zhash_insert (timers, mod_name, next_event) < 0) {  // key already
                                                            // exists
        flux_log (h,
                  LOG_ERR,
                  "duplicate join request from %s, module already exists in "
                  "sim_state",
                  mod_name);
        goto out;
    }
    // clear next event so it is not freed below
    next_event = NULL;

    // TODO: this is horribly hackish, improve the handshake to avoid
    // this hardcoded # of modules. maybe use a timeout?  ZMQ provides
    // support for polling etc with timeouts, should try that
    static int num_modules = 3;
    num_modules--;
    if (num_modules <= 0) {
        if (handle_next_event (ctx) < 0) {
            flux_log (h, LOG_ERR, "failure while handling next event");
            return;
        }
    }

out:
    Jput (request);
    free (next_event);
}