hi,

i asked michael eggers (the developer of uDMX) and he did answer very quickly. if anybody needs it here is my .dll file for win32 and the udmx.c.
cheers
georg


volker böhm schrieb:
hi georg,
i had the same problem when i tried compiling uDMX on linux.
the trouble i think is in the new method:

floatinlet_new((t_object *)x, (t_float *)x->channel); //assigns float in inlet 2 directly to channel

where channel is an int. this compiles but crashed pd when second inlet is used.
for me it worked to rewrite it using inlet_new() instead:

inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), gensym("ft1"));

then of course you need a dedicated method to assign the input to x->channel
something like:

void uDMX_ft1(t_uDMX *x, t_floatarg f)
{
    x->channel = f;
    ...
}

but why don't you ask michi himself. normally he is quite responsive.
volker.


On 26 May 2009, at 09:26, Georg Werner wrote:

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.


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

Attachment: uDMX.dll
Description: application/msdownload

/*
        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.2     2009-06-30      
                                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_setchannel(t_uDMX *x, t_floatarg f);
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);  
        class_addmethod(uDMX_class, (t_method)uDMX_setchannel, 
gensym("setchannel"), A_FLOAT, 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_setchannel(t_uDMX *x, t_floatarg f)
{
        x->channel = f;
}

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

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

        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) {
                                n = (int) av->a_w.w_float;
                                if (n > 255) n=255;
                                if (n < 0) n=0;

                                buf[i] = n;
                        } 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(x, x->channel); //crashes on PD .... assigns float in 
inlet 2 directly to channel
        inlet_new(&x->p_ob, &x->p_ob.ob_pd, gensym("float"), 
gensym("setchannel"));

        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