int setup_router() { const char *host = "localhost"; router = mapper_router_new(source, host, destination->props.port, mdev_name(destination), 0); mdev_add_router(source, router); printf("Router to %s:%d added.\n", host, destination->props.port); char signame_in[1024]; if (!msig_full_name(recvsig, signame_in, 1024)) { printf("Could not get destination signal name.\n"); return 1; } char signame_out[1024]; if (!msig_full_name(sendsig, signame_out, 1024)) { printf("Could not get source signal name.\n"); return 1; } printf("Connecting signal %s -> %s\n", signame_out, signame_in); mapper_connection c = mapper_router_add_connection(router, sendsig, recvsig->props.name, 'f', 1); mapper_connection_range_t range; range.src_min = 0; range.src_max = 1; range.dest_min = -10; range.dest_max = 10; range.known = CONNECTION_RANGE_KNOWN; mapper_connection_set_linear_range(c, &range); return 0; }
void mapper_connection_set_from_message(mapper_connection c, mapper_signal sig, mapper_message_t *msg) { /* First record any provided parameters. */ /* Destination type. */ const char *dest_type = mapper_msg_get_param_if_char(msg, AT_TYPE); if (dest_type) c->props.dest_type = dest_type[0]; /* Range information. */ float range[4]; int range_known = get_range(sig, c, msg, range); if (range_known & CONNECTION_RANGE_SRC_MIN) { c->props.range.known |= CONNECTION_RANGE_SRC_MIN; c->props.range.src_min = range[0]; } if (range_known & CONNECTION_RANGE_SRC_MAX) { c->props.range.known |= CONNECTION_RANGE_SRC_MAX; c->props.range.src_max = range[1]; } if (range_known & CONNECTION_RANGE_DEST_MIN) { c->props.range.known |= CONNECTION_RANGE_DEST_MIN; c->props.range.dest_min = range[2]; } if (range_known & CONNECTION_RANGE_DEST_MAX) { c->props.range.known |= CONNECTION_RANGE_DEST_MAX; c->props.range.dest_max = range[3]; } // TO DO: test if range has actually changed if (c->props.range.known == CONNECTION_RANGE_KNOWN && c->props.mode == MO_LINEAR) { mapper_connection_set_linear_range(c, sig, &c->props.range); } /* Muting. */ int muting; if (!mapper_msg_get_param_if_int(msg, AT_MUTE, &muting)) c->props.muted = muting; /* Clipping. */ int clip_min = mapper_msg_get_clipping(msg, AT_CLIPMIN); if (clip_min >= 0) c->props.clip_min = clip_min; int clip_max = mapper_msg_get_clipping(msg, AT_CLIPMAX); if (clip_max >= 0) c->props.clip_max = clip_max; /* Expression. */ const char *expr = mapper_msg_get_param_if_string(msg, AT_EXPRESSION); if (expr) replace_expression_string(c, sig, expr); /* Now set the mode type depending on the requested type and * the known properties. */ int mode = mapper_msg_get_mode(msg); switch (mode) { case -1: /* No mode type specified; if mode not yet set, see if we know the range and choose between linear or direct connection. */ if (c->props.mode == MO_UNDEFINED) { if (range_known == CONNECTION_RANGE_KNOWN) { /* We have enough information for a linear connection. */ mapper_connection_range_t r; r.src_min = range[0]; r.src_max = range[1]; r.dest_min = range[2]; r.dest_max = range[3]; r.known = range_known; mapper_connection_set_linear_range(c, sig, &r); } else /* No range, default to direct connection. */ mapper_connection_set_direct(c); } break; case MO_BYPASS: mapper_connection_set_direct(c); break; case MO_LINEAR: if (range_known == CONNECTION_RANGE_KNOWN) { mapper_connection_range_t r; r.src_min = range[0]; r.src_max = range[1]; r.dest_min = range[2]; r.dest_max = range[3]; r.known = range_known; mapper_connection_set_linear_range(c, sig, &r); } break; case MO_CALIBRATE: if (range_known & (CONNECTION_RANGE_DEST_MIN | CONNECTION_RANGE_DEST_MAX)) mapper_connection_set_calibrate(c, sig, range[2], range[3]); break; case MO_EXPRESSION: { if (!c->props.expression) c->props.expression = strdup("y=x"); mapper_connection_set_expression(c, sig, c->props.expression); } break; default: trace("unknown result from mapper_msg_get_mode()\n"); break; } }
int mapper_connection_perform(mapper_connection connection, mapper_signal sig, mapper_signal_value_t *from_value, mapper_signal_value_t *to_value) { int changed = 0; float f = 0; if (connection->props.muted) return 0; /* If the destination type is unknown, we can't do anything * intelligent here -- even bypass mode might screw up if we * assume the types work out. */ if (connection->props.dest_type != 'f' && connection->props.dest_type != 'i') { return 0; } if (!connection->props.mode || connection->props.mode == MO_BYPASS) { if (connection->props.src_type == connection->props.dest_type) *to_value = *from_value; else if (connection->props.src_type == 'f' && connection->props.dest_type == 'i') to_value->i32 = (int)from_value->f; else if (connection->props.src_type == 'i' && connection->props.dest_type == 'f') to_value->f = (float)from_value->i32; } else if (connection->props.mode == MO_EXPRESSION || connection->props.mode == MO_LINEAR) { die_unless(connection->expr!=0, "Missing expression.\n"); *to_value = mapper_expr_evaluate(connection->expr, from_value); } else if (connection->props.mode == MO_CALIBRATE) { if (connection->props.src_type == 'f') f = from_value->f; else if (connection->props.src_type == 'i') f = (float)from_value->i32; /* If calibration mode has just taken effect, first data * sample sets source min and max */ if (!connection->calibrating) { connection->props.range.src_min = f; connection->props.range.src_max = f; connection->props.range.known |= CONNECTION_RANGE_SRC_MIN | CONNECTION_RANGE_SRC_MAX; connection->calibrating = 1; changed = 1; } else { if (f < connection->props.range.src_min) { connection->props.range.src_min = f; connection->props.range.known |= CONNECTION_RANGE_SRC_MIN; changed = 1; } if (f > connection->props.range.src_max) { connection->props.range.src_max = f; connection->props.range.known |= CONNECTION_RANGE_SRC_MAX; changed = 1; } } if (changed) { mapper_connection_set_linear_range(connection, sig, &connection->props.range); /* Stay in calibrate mode. */ connection->props.mode = MO_CALIBRATE; } if (connection->expr) *to_value = mapper_expr_evaluate(connection->expr, from_value); } return 1; }