int mapper_connection_set_from_message(mapper_connection c, mapper_message_t *msg) { int updated = 0; /* 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]) { // TODO: need to reinitialize connections using this destination signal c->props.dest_type = dest_type[0]; updated++; } /* Range information. */ updated += set_range(c, msg); if (c->props.range_known == CONNECTION_RANGE_KNOWN && c->props.mode == MO_LINEAR) { mapper_connection_set_mode_linear(c); } /* Muting. */ int muting; if (!mapper_msg_get_param_if_int(msg, AT_MUTE, &muting) && c->props.muted != muting) { c->props.muted = muting; updated++; } /* Range boundary actions. */ int bound_min = mapper_msg_get_boundary_action(msg, AT_BOUND_MIN); if (bound_min >= 0 && c->props.bound_min != bound_min) { c->props.bound_min = bound_min; updated++; } int bound_max = mapper_msg_get_boundary_action(msg, AT_BOUND_MAX); if (bound_max >= 0 && c->props.bound_max != bound_max) { c->props.bound_max = bound_max; updated++; } /* Expression. */ const char *expr = mapper_msg_get_param_if_string(msg, AT_EXPRESSION); if (expr && (!c->props.expression || strcmp(c->props.expression, expr))) { int input_history_size, output_history_size; if (!replace_expression_string(c, expr, &input_history_size, &output_history_size)) { if (c->props.mode == MO_EXPRESSION) { reallocate_connection_histories(c, input_history_size, output_history_size); } } updated++; } /* Instances. */ int send_as_instance; if (!mapper_msg_get_param_if_int(msg, AT_SEND_AS_INSTANCE, &send_as_instance) && c->props.send_as_instance != send_as_instance) { c->props.send_as_instance = send_as_instance; updated++; } /* Scopes. */ lo_arg **a_scopes = mapper_msg_get_param(msg, AT_SCOPE); int num_scopes = mapper_msg_get_length(msg, AT_SCOPE); mapper_db_connection_update_scope(&c->props.scope, a_scopes, num_scopes); /* Extra properties. */ updated += mapper_msg_add_or_update_extra_params(c->props.extra, msg); /* Now set the mode type depending on the requested type and * the known properties. */ int mode = mapper_msg_get_mode(msg); if (mode >= 0 && mode != c->props.mode) updated++; 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 (c->props.range_known == CONNECTION_RANGE_KNOWN) { /* We have enough information for a linear connection. */ mapper_connection_set_mode_linear(c); } else /* No range, default to direct connection. */ mapper_connection_set_mode_direct(c); } break; case MO_BYPASS: mapper_connection_set_mode_direct(c); break; case MO_LINEAR: if (c->props.range_known == CONNECTION_RANGE_KNOWN) { mapper_connection_set_mode_linear(c); } break; case MO_CALIBRATE: if (c->props.range_known & (CONNECTION_RANGE_DEST_MIN | CONNECTION_RANGE_DEST_MAX)) mapper_connection_set_mode_calibrate(c); break; case MO_EXPRESSION: { if (!c->props.expression) { if (c->props.src_length == c->props.dest_length) c->props.expression = strdup("y=x"); else { char expr[256] = ""; if (c->props.src_length > c->props.dest_length) { // truncate source if (c->props.dest_length == 1) snprintf(expr, 256, "y=x[0]"); else snprintf(expr, 256, "y=x[0:%i]", c->props.dest_length-1); } else { // truncate destination if (c->props.src_length == 1) snprintf(expr, 256, "y[0]=x"); else snprintf(expr, 256, "y[0:%i]=x", c->props.src_length); } c->props.expression = strdup(expr); } } mapper_connection_set_mode_expression(c, c->props.expression); } break; case MO_REVERSE: mapper_connection_set_mode_reverse(c); break; default: trace("unknown result from mapper_msg_get_mode()\n"); break; } return updated; }
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; } }