コード例 #1
0
ファイル: implicitmap.c プロジェクト: malloch/implicitmap
// *********************************************************
// -(set up new device and monitor)-------------------------
void impmap_update_output_vector_positions(impmap *x)
{
    int i, k=0, count;
    int num_outputs = mapper_device_num_signals(x->device, MAPPER_DIR_OUTGOING) - 1;

    // store output signal pointers
    mapper_signal signals[num_outputs];
    mapper_signal *psig = mapper_device_signals(x->device, MAPPER_DIR_OUTGOING);

    i = 0;
    while (psig) {
        if (*psig != x->dummy_output)
            signals[i++] = *psig;
        psig = mapper_signal_query_next(psig);
    }

    // sort output signal pointer array
    qsort(signals, num_outputs, sizeof(mapper_signal), compare_signal_names);

    // set offsets and user_data
    for (i = 0; i < num_outputs; i++) {
        x->signals_out[i].offset = k;
        mapper_signal_set_user_data(signals[i], &x->signals_out[i]);
        k += mapper_signal_length(signals[i]);
    }
    count = k < MAX_LIST ? k : MAX_LIST;
    if (count != x->size_out && x->num_snapshots) {
        post("implicitmap: output vector size has changed - resetting snapshots!");
        impmap_clear_snapshots(x);
    }
    x->size_out = count;
}
コード例 #2
0
/*! Creation of a local source. */
int setup_source()
{
    char sig_name[20];
    source = mapper_device_new("testquery-send", 0, 0);
    if (!source)
        goto error;
    eprintf("source created.\n");

    int mn[]={0,0,0,0}, mx[]={10,10,10,10};

    for (int i = 0; i < 4; i++) {
        snprintf(sig_name, 20, "%s%i", "outsig_", i);
        sendsig[i] = mapper_device_add_output_signal(source, sig_name, i+1, 'i',
                                                     0, mn, mx);
        mapper_signal_set_callback(sendsig[i], query_response_handler);
        mapper_signal_update(sendsig[i], mn, 0, MAPPER_NOW);
    }

    eprintf("Output signals registered.\n");
    eprintf("Number of outputs: %d\n",
            mapper_device_num_signals(source, MAPPER_DIR_OUTGOING));

    return 0;

error:
    return 1;
}
コード例 #3
0
/*! Creation of a local destination. */
int setup_destination()
{
    char sig_name[10];
    destination = mapper_device_new("testquery-recv", 0, 0);
    if (!destination)
        goto error;
    eprintf("destination created.\n");

    float mn[]={0,0,0,0}, mx[]={1,1,1,1};

    for (int i = 0; i < 4; i++) {
        snprintf(sig_name, 10, "%s%i", "insig_", i);
        recvsig[i] = mapper_device_add_input_signal(destination, sig_name, i+1,
                                                    'f', 0, mn, mx,
                                                    insig_handler, 0);
    }

    eprintf("Input signal 'insig' registered.\n");
    eprintf("Number of inputs: %d\n",
            mapper_device_num_signals(destination, MAPPER_DIR_INCOMING));

    return 0;

error:
    return 1;
}
コード例 #4
0
int setup_destination()
{
    destination = mapper_device_new("testrecv", 0, 0);
    if (!destination)
        goto error;
    eprintf("destination created.\n");

    float mn=0, mx=1;
    recvsig = mapper_device_add_input_signal(destination, "insig", 1, 'f', 0,
                                             &mn, &mx, insig_handler, 0);

    eprintf("Input signal 'insig' registered.\n");
    eprintf("Number of inputs: %d\n",
            mapper_device_num_signals(destination, MAPPER_DIR_INCOMING));
    return 0;

  error:
    return 1;
}
コード例 #5
0
int setup_source()
{
    source = mapper_device_new("testsend", 0, 0);
    if (!source)
        goto error;
    eprintf("source created.\n");

    float mn=0, mx=1;
    sendsig = mapper_device_add_output_signal(source, "outsig", 1, 'f', 0,
                                              &mn, &mx);

    eprintf("Output signal 'outsig' registered.\n");
    eprintf("Number of outputs: %d\n",
            mapper_device_num_signals(source, MAPPER_DIR_OUTGOING));
    return 0;

  error:
    return 1;
}
コード例 #6
0
ファイル: implicitmap.c プロジェクト: malloch/implicitmap
// *********************************************************
// -(connection handler)------------------------------------
void impmap_on_map(mapper_device dev, mapper_map map, mapper_record_event e)
{
    // if connected involves current generic signal, create a new generic signal
    impmap *x = (void*)mapper_device_user_data(dev);
    if (!x) {
        post("error in connect handler: user_data is NULL");
        return;
    }
    if (!x->ready) {
        post("error in connect handler: device not ready");
        return;
    }

    // retrieve devices and signals
    mapper_slot slot = mapper_map_slot(map, MAPPER_LOC_SOURCE, 0);
    mapper_signal src_sig = mapper_slot_signal(slot);
    mapper_device src_dev = mapper_signal_device(src_sig);
    slot = mapper_map_slot(map, MAPPER_LOC_DESTINATION, 0);
    mapper_signal dst_sig = mapper_slot_signal(slot);
    mapper_device dst_dev = mapper_signal_device(dst_sig);

    // sanity check: don't allow self-connections
    if (src_dev == dst_dev) {
        mapper_map_release(map);
        return;
    }

    char full_name[256];

    if (e == MAPPER_ADDED) {
        if (src_dev == x->device) {
            snprintf(full_name, 256, "%s/%s", mapper_device_name(dst_dev),
                     mapper_signal_name(dst_sig));
            if (strcmp(mapper_signal_name(src_sig), full_name) == 0) {
                // <thisDev>:<dstDevName>/<dstSigName> -> <dstDev>:<dstSigName>
                return;
            }
            if (mapper_device_num_signals(x->device, MAPPER_DIR_OUTGOING) >= MAX_LIST) {
                post("Max outputs reached!");
                return;
            }
            // unmap the generic signal
            mapper_map_release(map);

            // add a matching output signal
            int i, length = mapper_signal_length(dst_sig);
            char type = mapper_signal_type(dst_sig);
            void *min = mapper_signal_minimum(dst_sig);
            void *max = mapper_signal_maximum(dst_sig);

            float *minf = 0, *maxf = 0;
            if (type == 'f') {
                minf = (float*)min;
                maxf = (float*)max;
            }
            else {
                if (min) {
                    minf = alloca(length * sizeof(float));
                    if (type == 'i') {
                        int *mini = (int*)min;
                        for (i = 0; i < length; i++)
                            minf[i] = (float)mini[i];
                    }
                    else if (type == 'd') {
                        double *mind = (double*)min;
                        for (i = 0; i < length; i++)
                            minf[i] = (float)mind[i];
                    }
                    else
                        minf = 0;
                }
                if (max) {
                    maxf = alloca(length * sizeof(float));
                    if (type == 'i') {
                        int *maxi = (int*)max;
                        for (i = 0; i < length; i++)
                            maxf[i] = (float)maxi[i];
                    }
                    else if (type == 'd') {
                        double *maxd = (double*)max;
                        for (i = 0; i < length; i++)
                            maxf[i] = (float)maxd[i];
                    }
                    else
                        maxf = 0;
                }
            }
            src_sig = mapper_device_add_output_signal(x->device, full_name,
                                                      length, 'f', 0, minf, maxf);
            if (!src_sig) {
                post("error creating new source signal!");
                return;
            }
            mapper_signal_set_callback(src_sig, impmap_on_query);

            // map the new signal
            map = mapper_map_new(1, &src_sig, 1, &dst_sig);
            mapper_map_set_mode(map, MAPPER_MODE_EXPRESSION);
            mapper_map_set_expression(map, "y=x");
            mapper_map_push(map);

            impmap_update_output_vector_positions(x);

            //output numOutputs
            maxpd_atom_set_int(&x->msg_buffer,
                               mapper_device_num_signals(x->device, MAPPER_DIR_OUTGOING) - 1);
            outlet_anything(x->outlet3, gensym("numOutputs"), 1, &x->msg_buffer);
        }
        else if (dst_dev == x->device) {
            snprintf(full_name, 256, "%s/%s", mapper_device_name(src_dev),
                     mapper_signal_name(src_sig));
            if (strcmp(mapper_signal_name(dst_sig), full_name) == 0) {
                // <srcDevName>:<srcSigName> -> <thisDev>:<srcDevName>/<srcSigName>
                return;
            }
            if (mapper_device_num_signals(x->device, MAPPER_DIR_INCOMING) >= MAX_LIST) {
                post("Max inputs reached!");
                return;
            }
            // unmap the generic signal
            mapper_map_release(map);

            // add a matching input signal
            int i, length = mapper_signal_length(src_sig);
            char type = mapper_signal_type(src_sig);
            void *min = mapper_signal_minimum(src_sig);
            void *max = mapper_signal_maximum(src_sig);

            float *minf = 0, *maxf = 0;
            if (type == 'f') {
                minf = (float*)min;
                maxf = (float*)max;
            }
            else {
                if (min) {
                    minf = alloca(length * sizeof(float));
                    if (type == 'i') {
                        int *mini = (int*)min;
                        for (i = 0; i < length; i++)
                        minf[i] = (float)mini[i];
                    }
                    else if (type == 'd') {
                        double *mind = (double*)min;
                        for (i = 0; i < length; i++)
                        minf[i] = (float)mind[i];
                    }
                    else
                        minf = 0;
                }
                if (max) {
                    maxf = alloca(length * sizeof(float));
                    if (type == 'i') {
                        int *maxi = (int*)max;
                        for (i = 0; i < length; i++)
                        maxf[i] = (float)maxi[i];
                    }
                    else if (type == 'd') {
                        double *maxd = (double*)max;
                        for (i = 0; i < length; i++)
                        maxf[i] = (float)maxd[i];
                    }
                    else
                        maxf = 0;
                }
            }
            dst_sig = mapper_device_add_input_signal(x->device, full_name,
                                                     length, 'f', 0, minf, maxf,
                                                     impmap_on_input, 0);
            if (!dst_sig) {
                post("error creating new destination signal!");
                return;
            }

            // map the new signal
            map = mapper_map_new(1, &src_sig, 1, &dst_sig);
            mapper_map_set_mode(map, MAPPER_MODE_EXPRESSION);
            mapper_map_set_expression(map, "y=x");
            mapper_map_push(map);

            impmap_update_input_vector_positions(x);

            //output numInputs
            maxpd_atom_set_int(&x->msg_buffer,
                               mapper_device_num_signals(x->device, MAPPER_DIR_INCOMING) - 1);
            outlet_anything(x->outlet3, gensym("numInputs"), 1, &x->msg_buffer);
        }
    }
    else if (e == MAPPER_REMOVED) {
        if (src_sig == x->dummy_input || src_sig == x->dummy_output
            || dst_sig == x->dummy_input || dst_sig == x->dummy_output)
            return;
        if (src_dev == x->device) {
            snprintf(full_name, 256, "%s/%s", mapper_device_name(dst_dev),
                     mapper_signal_name(dst_sig));
            if (strcmp(mapper_signal_name(src_sig), full_name) != 0)
                return;
            // remove signal
            mapper_device_remove_signal(x->device, src_sig);
            impmap_update_input_vector_positions(x);

            //output numOutputs
            maxpd_atom_set_int(&x->msg_buffer,
                               mapper_device_num_signals(x->device, MAPPER_DIR_OUTGOING) - 1);
            outlet_anything(x->outlet3, gensym("numOutputs"), 1, &x->msg_buffer);
        }
        else if (dst_dev == x->device) {
            snprintf(full_name, 256, "%s/%s", mapper_device_name(src_dev),
                     mapper_signal_name(src_sig));
            if (strcmp(mapper_signal_name(dst_sig), full_name) != 0)
                return;
            // remove signal
            mapper_device_remove_signal(x->device, dst_sig);
            impmap_update_input_vector_positions(x);

            //output numInputs
            maxpd_atom_set_int(&x->msg_buffer,
                               mapper_device_num_signals(x->device, MAPPER_DIR_INCOMING) - 1);
            outlet_anything(x->outlet3, gensym("numInputs"), 1, &x->msg_buffer);
        }
    }
}
コード例 #7
0
ファイル: implicitmap.c プロジェクト: malloch/implicitmap
// *********************************************************
// -(new)---------------------------------------------------
void *impmap_new(t_symbol *s, int argc, t_atom *argv)
{
    impmap *x = NULL;
    long i;
    const char *alias = NULL;
    const char *iface = NULL;

#ifdef MAXMSP
    if ((x = object_alloc(mapper_class))) {
        x->outlet3 = listout((t_object *)x);
        x->outlet2 = listout((t_object *)x);
        x->outlet1 = listout((t_object *)x);
#else
    if (x = (impmap *) pd_new(mapper_class) ) {
        x->outlet1 = outlet_new(&x->ob, gensym("list"));
        x->outlet2 = outlet_new(&x->ob, gensym("list"));
        x->outlet3 = outlet_new(&x->ob, gensym("list"));
#endif
        x->name = strdup("implicitmap");
        for (i = 0; i < argc; i++) {
            if ((argv + i)->a_type == A_SYM) {
                if(strcmp(maxpd_atom_get_string(argv+i), "@alias") == 0) {
                    if ((argv+i+1)->a_type == A_SYM) {
                        alias = maxpd_atom_get_string(argv+i+1);
                        i++;
                    }
                }
                else if(strcmp(maxpd_atom_get_string(argv+i), "@interface") == 0) {
                    if ((argv+i+1)->a_type == A_SYM) {
                        iface = maxpd_atom_get_string(argv+i+1);
                        i++;
                    }
                }
            }
        }

        if (alias) {
            free(x->name);
            x->name = *alias == '/' ? strdup(alias+1) : strdup(alias);
        }

        if (impmap_setup_mapper(x, iface)) {
            post("implicitmap: Error initializing.");
        }
        else {
            x->ready = 0;
            x->mute = 0;
            x->new_in = 0;
            x->query_count = 0;
            x->num_snapshots = 0;
            x->snapshots = 0;
            // initialize input and output buffers
            for (i = 0; i < MAX_LIST; i++) {
                maxpd_atom_set_float(x->buffer_in+i, 0);
                maxpd_atom_set_float(x->buffer_out+i, 0);
                x->signals_in[i].x = x;
                x->signals_out[i].x = x;
            }
            x->size_in = 0;
            x->size_out = 0;
#ifdef MAXMSP
            x->clock = clock_new(x, (method)impmap_poll);    // Create the timing clock
            x->timeout = clock_new(x, (method)impmap_output_snapshot);
#else
            x->clock = clock_new(x, (t_method)impmap_poll);
            x->timeout = clock_new(x, (t_method)impmap_output_snapshot);
#endif
            clock_delay(x->clock, INTERVAL);  // Set clock to go off after delay
        }
    }
    return (x);
}

// *********************************************************
// -(free)--------------------------------------------------
void impmap_free(impmap *x)
{
    if (x->clock) {
        clock_unset(x->clock);    // Remove clock routine from the scheduler
        clock_free(x->clock);     // Frees memory used by clock
    }
    if (x->device) {
        mapper_device_free(x->device);
    }
    if (x->name) {
        free(x->name);
    }
    impmap_clear_snapshots(x);
}

// *********************************************************
// -(print properties)--------------------------------------
void impmap_print_properties(impmap *x)
{
    if (x->ready) {
        //output name
        maxpd_atom_set_string(&x->msg_buffer, mapper_device_name(x->device));
        outlet_anything(x->outlet3, gensym("name"), 1, &x->msg_buffer);

        mapper_network net = mapper_device_network(x->device);
        //output interface
        maxpd_atom_set_string(&x->msg_buffer, (char *)mapper_network_interface(net));
        outlet_anything(x->outlet3, gensym("interface"), 1, &x->msg_buffer);

        //output IP
        const struct in_addr *ip = mapper_network_ip4(net);
        if (ip) {
            maxpd_atom_set_string(&x->msg_buffer, inet_ntoa(*ip));
            outlet_anything(x->outlet3, gensym("IP"), 1, &x->msg_buffer);
        }

        //output port
        maxpd_atom_set_int(&x->msg_buffer, mapper_device_port(x->device));
        outlet_anything(x->outlet3, gensym("port"), 1, &x->msg_buffer);

        //output numInputs
        maxpd_atom_set_int(&x->msg_buffer, mapper_device_num_signals(x->device, MAPPER_DIR_INCOMING) - 1);
        outlet_anything(x->outlet3, gensym("numInputs"), 1, &x->msg_buffer);

        //output numOutputs
        maxpd_atom_set_int(&x->msg_buffer, mapper_device_num_signals(x->device, MAPPER_DIR_OUTGOING) - 1);
        outlet_anything(x->outlet3, gensym("numOutputs"), 1, &x->msg_buffer);
    }
}

// *********************************************************
// -(inlet/outlet assist - maxmsp only)---------------------
#ifdef MAXMSP
void impmap_assist(impmap *x, void *b, long m, long a, char *s)
{
    if (m == ASSIST_INLET) { // inlet
        sprintf(s, "OSC input");
    }
    else {    // outlet
        if (a == 0) {
            sprintf(s, "Mapped OSC inputs");
        }
        else if (a == 1) {
            sprintf(s, "Snapshot data");
        }
        else {
            sprintf(s, "Device information");
        }
    }
}
#endif

// *********************************************************
// -(snapshot)----------------------------------------------
void impmap_snapshot(impmap *x)
{
    // if previous snapshot still in progress, output current snapshot status
    if (x->query_count) {
        post("still waiting for last snapshot");
        return;
    }

    mapper_signal *psig;
    x->query_count = 0;

    // allocate a new snapshot
    if (x->ready) {
        t_snapshot new_snapshot = (t_snapshot)malloc(sizeof(t_snapshot));
        new_snapshot->id = x->num_snapshots++;
        new_snapshot->next = x->snapshots;
        new_snapshot->inputs = calloc(x->size_in, sizeof(float));
        new_snapshot->outputs = calloc(x->size_out, sizeof(float));
        x->snapshots = new_snapshot;
    }

    // iterate through input signals and store their current values
    psig = mapper_device_signals(x->device, MAPPER_DIR_INCOMING);
    while (psig) {
        if (*psig != x->dummy_input) {
            void *value = (void*)mapper_signal_value(*psig, 0);
            t_signal_ref *ref = mapper_signal_user_data(*psig);
            int siglength = mapper_signal_length(*psig);
            int length = ref->offset + siglength < MAX_LIST ? siglength : MAX_LIST - ref->offset;
            // we can simply use memcpy here since all our signals are type 'f'
            memcpy(&x->snapshots->inputs[ref->offset], value, length * sizeof(float));
        }
        psig = mapper_signal_query_next(psig);
    }

    mapper_timetag_now(&x->tt);
    mapper_device_start_queue(x->device, x->tt);

    // iterate through output signals and query the remote ends
    psig = mapper_device_signals(x->device, MAPPER_DIR_OUTGOING);
    while (psig) {
        if (*psig != x->dummy_output) {
            // query the remote value
            x->query_count += mapper_signal_query_remotes(*psig, MAPPER_NOW);
        }
        psig = mapper_signal_query_next(psig);
    }
    mapper_device_send_queue(x->device, x->tt);
    post("sent %i queries", x->query_count);

    if (x->query_count)
        clock_delay(x->timeout, 1000);  // Set clock to go off after delay
}

// *********************************************************
// -(snapshot)----------------------------------------------
void impmap_output_snapshot(impmap *x)
{
    if (x->query_count) {
        post("query timeout! setting query count to 0 and outputting current values.");
        x->query_count = 0;
    }
    maxpd_atom_set_int(x->buffer_in, x->snapshots->id+1);
    outlet_anything(x->outlet3, gensym("numSnapshots"), 1, x->buffer_in);
    maxpd_atom_set_float_array(x->buffer_in, x->snapshots->inputs, x->size_in);
    outlet_anything(x->outlet2, gensym("in"), x->size_in, x->buffer_in);
    maxpd_atom_set_float_array(x->buffer_out, x->snapshots->outputs, x->size_out);
    outlet_anything(x->outlet2, gensym("out"), x->size_out, x->buffer_out);
    maxpd_atom_set_int(x->buffer_in, x->snapshots->id);
    outlet_anything(x->outlet2, gensym("snapshot"), 1, x->buffer_in);
}

// *********************************************************
// -(mute output)-------------------------------------------
void impmap_mute_output(impmap *x, t_symbol *s, int argc, t_atom *argv)
{
    if (argc) {
        if (argv->a_type == A_FLOAT)
            x->mute = (int)atom_getfloat(argv);
#ifdef MAXMSP
        else if (argv->a_type == A_LONG)
            x->mute = atom_getlong(argv);
#endif
    }
}

// *********************************************************
// -(process)-----------------------------------------------
void impmap_process(impmap *x)
{
    outlet_anything(x->outlet2, gensym("process"), 0, 0);
}