Example #1
0
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;
}
Example #2
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;
    }
}