Hi,
i tried to compile the uDMX ( http://www.anyma.ch/research/udmx/ )
external on winxp. which worked after some trial and error. but now my
question is: can somebody tell me by looking an the source why it
crashes pd if i send a float message to the right inlet (there is no
device connected - so maybe it wont crash if there is, but i'm curious
how to figure out the reason) i started pd with -d (different numbers)
and there was no output related to the crash (which debug level is the
best for this case?)
best
g.

/*
        udmx.c
        
        pd-Interface to the [ a n y m a | udmx - Open Source USB Sensor Box ]
        
        Authors:        Michael Egger
        Copyright:      2007 [ a n y m a ]
        Website:        www.anyma.ch
        
        License:        GNU GPL 2.0 www.gnu.org
        
        Version:        0.1 2007-01-28
        */

#include "m_pd.h"

#include "uDMX_cmds.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "usb.h"    /* this is libusb, see http://libusb.sourceforge.net/ */

#define USBDEV_SHARED_VENDOR    0x16C0  /* VOTI */
#define USBDEV_SHARED_PRODUCT   0x05DC  /* Obdev's free shared PID */

typedef struct _uDMX                            // defines our object's 
internal variables for each instance in a patch
{
        t_object p_ob;                                  // object header - ALL 
objects MUST begin with this...
        usb_dev_handle  *dev_handle;    // handle to the uDMX usb device
        int     debug_flag;
        int channel;                                    // int value - received 
from the right inlet and stored internally for each object instance
} t_uDMX;

void *uDMX_class;                                       // global pointer to 
the object class - so max can reference the object 



// these are prototypes for the methods that are defined below
void uDMX_int(t_uDMX *x, long n);
void uDMX_debug(t_uDMX *x,  t_symbol *s, short ac, t_atom *av);
void uDMX_list(t_uDMX *x, t_symbol *s, short ac, t_atom *av);
void uDMX_open(t_uDMX *x);
void uDMX_close(t_uDMX *x);
void *uDMX_new(long n);
static int  usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char 
*buf, int buflen);
void find_device(t_uDMX *x);

//--------------------------------------------------------------------------

void uDMX_setup(void)
{

        uDMX_class = class_new ( gensym("uDMX"),(t_newmethod)uDMX_new, 0, 
sizeof(t_uDMX),       CLASS_DEFAULT,0);
        
        class_addfloat(uDMX_class, (t_method)uDMX_int);                 // the 
method for an int in the left inlet (inlet 0)
        class_addmethod(uDMX_class, (t_method)uDMX_debug,gensym("debug"), 
A_GIMME, 0);
        class_addlist(uDMX_class, (t_method)uDMX_list);
        class_addmethod(uDMX_class, (t_method)uDMX_open, gensym("open"), 0);    
        
        class_addmethod(uDMX_class, (t_method)uDMX_close, gensym("close"), 0);  

        post("uDMX version 0.9 - (c) 2006 [ a n y m a ]",0);    // post any 
important info to the max window when our object is laoded
}
//--------------------------------------------------------------------------

void uDMX_int(t_uDMX *x, long n)        // x = the instance of the object; n = 
the int received in the left inlet 
{
        unsigned char       buffer[8];
        int                 nBytes;

        if (n > 255) n=255;
        if (n < 0) n=0;
        if (x->channel > 512) x->channel=512;
        if (x->channel < 0) x->channel=0;
        
        if (!(x->dev_handle)) find_device(x);
        else {
                nBytes = usb_control_msg(x->dev_handle, USB_TYPE_VENDOR | 
USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
                                                                        
cmd_SetSingleChannel, n, x->channel, buffer, sizeof(buffer), 5000);
                if(nBytes < 0)
                         if (x->debug_flag) error("uDMX: USB error: %s", 
usb_strerror());
        }
}

//--------------------------------------------------------------------------

void uDMX_list(t_uDMX *x, t_symbol *s, short ac, t_atom *av)
{
        int i;
        unsigned char* buf = malloc(ac);
        int                 nBytes;

        if (x->channel > 512) x->channel=512;
        if (x->channel < 0) x->channel=0;

        if (!(x->dev_handle)) find_device(x);
        else {

                if (x->debug_flag) post("uDMX: ac: %i\n", ac);
                for(i=0; i<ac; ++i,av++) {
                        if (av->a_type==A_FLOAT)
                                buf[i] = MIN(MAX(av->a_w.w_float, 0), 255);
                        else
                                buf[i] = 0;
                }
                nBytes = usb_control_msg(x->dev_handle, USB_TYPE_VENDOR | 
USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
                                                                        
cmd_SetChannelRange, ac, x->channel, buf, ac, 5000);
                if (x->debug_flag) post( "bytes returned: %i\n", nBytes);
                if(nBytes < 0)
           if (x->debug_flag) error("uDMX: USB error: %s\n", usb_strerror());
                else if(nBytes > 0)  if (x->debug_flag) post("uDMX: returned: 
%i\n", (int)(buf[0]));
                free(buf);
        }
}

//--------------------------------------------------------------------------

void uDMX_debug(t_uDMX *x, t_symbol *s, short ac, t_atom *av)   // x = the 
instance of the object; n = the int received in the left inlet 
{
        x->debug_flag = 1;
        if (ac) {
                if (av->a_type==A_FLOAT) x->debug_flag = av->a_w.w_float;
        }
}



//--------------------------------------------------------------------------

void uDMX_free(t_uDMX *x)
{
        if (x->dev_handle)
                usb_close(x->dev_handle);
}

//--------------------------------------------------------------------------

void uDMX_open(t_uDMX *x)
{
        if (x->dev_handle) {
                post("uDMX: There is already a connection to 
www.anyma.ch/uDMX",0);
        } else find_device(x);
}

//--------------------------------------------------------------------------

void uDMX_close(t_uDMX *x)
{
        if (x->dev_handle) {
                usb_close(x->dev_handle);
                x->dev_handle = NULL;
                post("uDMX: Closed connection to www.anyma.ch/uDMX",0);
        } else
                post("uDMX: There was no open connection to 
www.anyma.ch/uDMX",0);
}


//--------------------------------------------------------------------------

void *uDMX_new(long n)          // n = int argument typed into object box 
(A_DEFLONG) -- defaults to 0 if no args are typed
{
        t_uDMX *x;                              // local variable (pointer to a 
t_uDMX data structure)

        x = (t_uDMX *)pd_new(uDMX_class); // create a new instance of this 
object
        
        // create a second int inlet (leftmost inlet is automatic - all objects 
have one inlet by default)
        floatinlet_new((t_object *)x, (t_float *)x->channel); //assigns float 
in inlet 2 directly to channel

        x->channel = 0;
        x->debug_flag = 0;
        x->dev_handle = NULL;
        
        find_device(x);

        return(x);                                      // return a reference 
to the object instance 
}

//--------------------------------------------------------------------------


static int  usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char 
*buf, int buflen)
{
char    buffer[256];
int     rval, i;

    if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, 
(USB_DT_STRING << 8) + index, langid, buffer, sizeof(buffer), 1000)) < 0)
        return rval;
    if(buffer[1] != USB_DT_STRING)
        return 0;
    if((unsigned char)buffer[0] < rval)
        rval = (unsigned char)buffer[0];
    rval /= 2;
    /* lossy conversion to ISO Latin1 */
    for(i=1;i<rval;i++){
        if(i > buflen)  /* destination buffer overflow */
            break;
        buf[i-1] = buffer[2 * i];
        if(buffer[2 * i + 1] != 0)  /* outside of ISO Latin1 range */
            buf[i-1] = '?';
    }
    buf[i-1] = 0;
    return i-1;
}

//--------------------------------------------------------------------------


void find_device(t_uDMX *x)
{
        usb_dev_handle      *handle = NULL;
        struct usb_bus      *bus;
        struct usb_device   *dev;

        usb_init();
        usb_find_busses();
    usb_find_devices();
         for(bus=usb_get_busses(); bus; bus=bus->next){
        for(dev=bus->devices; dev; dev=dev->next){
            if(dev->descriptor.idVendor == USBDEV_SHARED_VENDOR && 
dev->descriptor.idProduct == USBDEV_SHARED_PRODUCT){
                char    string[256];
                int     len;
                handle = usb_open(dev); /* we need to open the device in order 
to query strings */
                if(!handle){
                    error ("Warning: cannot open USB device: %s", 
usb_strerror());
                    continue;
                }
                /* now find out whether the device actually is uDMX */
                len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, 
0x0409, string, sizeof(string));
                if(len < 0){
                    post("uDMX: warning: cannot query manufacturer for device: 
%s", usb_strerror());
                    goto skipDevice;
                }
                
                        //      post("uDMX: seen device from vendor ->%s<-", 
string); 
                if(strcmp(string, "www.anyma.ch") != 0)
                    goto skipDevice;
                len = usbGetStringAscii(handle, dev->descriptor.iProduct, 
0x0409, string, sizeof(string));
                if(len < 0){
                    post("uDMX: warning: cannot query product for device: %s", 
usb_strerror());
                    goto skipDevice;
                }
              //  post("uDMX: seen product ->%s<-", string);
                if(strcmp(string, "uDMX") == 0)
                    break;
skipDevice:
                usb_close(handle);
                handle = NULL;
            }
        }
        if(handle)
            break;
    }
        
    if(!handle){
        post("uDMX: Could not find USB device www.anyma.ch/uDMX");
                x->dev_handle = NULL;
        } else {
                x->dev_handle = handle;
                 post("uDMX: Found USB device www.anyma.ch/uDMX");
        }
}

_______________________________________________
Pd-dev mailing list
[email protected]
http://lists.puredata.info/listinfo/pd-dev

Reply via email to