Forums > Java

MXJ and reacTIVision Crash


December 26, 2011 | 7:09 pm

Dear all,

I am currently implementing an mxj external for Max with which I will connect the [TuioClient] object (provided by the reacTIVision team, for more info visit the official web page which is http://reactivision.sourceforge.net/). I am trying to use fiducials in order to create Max Objects and move them around and/or interact with them. So far, my tests have shown that I get a crash from Max when I am trying to create an MSP Object (the ones that end with a ‘~’). The crash report refers mainly to the main max thread. A part of the report is this:

Interval Since Last Report: 560915 sec
Crashes Since Last Report: 46
Per-App Interval Since Last Report: 89355 sec
Per-App Crashes Since Last Report: 26
Anonymous UUID: 0BA8D3C0-14B6-465F-AC44-E53C6BD3B2D8

Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x000000000000001c
Crashed Thread: 0 Java: AWT-AppKit Dispatch queue: com.apple.main-thread

Application Specific Information:

Java information:
Exception type: Bus Error (0xa) at pc=0000000097e82b22

Java VM: Java HotSpot(TM) Client VM (20.4-b02-402 mixed mode macosx-x86)

Current thread (000000001b801c00): JavaThread "AWT-AppKit" [_thread_in_native, id=-1609931456, stack(00000000bf800000,00000000c0000000)]
Stack: [00000000bf800000,00000000c0000000]

For obvious reasons I haven’t posted the full crash report (it’s very big…).

The way [TuioClient] communicates (it’s output is connected to the one and only input of my mxj object) with my mxj object is that it sends some lists with a "process identifier" and then some data. So I implemented some methods in my mxj class named after the "process identifiers" and in that way every time the TuioClient sends a message to my mxj the appropriate method is called. So I post the code that I have written to create max objects in my patch:

public void addObject(float sessionID, float fiducialID, float xPosition, float yPosition, float angle) {
// Calculate Coordinates to Initially Place
coordinates[(int)fiducialID][0] = Math.round(xPosition * patch.getWindow().getSize()[0]); // New X Coordinate for the Left Top Corner
coordinates[(int)fiducialID][1] = Math.round(yPosition * patch.getWindow().getSize()[1]); // New Y Coordinate for the Left Top Corner

// Check in Which Object Category the Added Fiducial Belongs
if(fiducialID >= 0 && fiducialID < = 9) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "cycle~", new Atom[]{Atom.newAtom(0)}); // Create Cycle~ Object
} else if(fiducialID >= 10 && fiducialID < = 14) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "phasor~", new Atom[]{Atom.newAtom(0)}); // Create Phasor~ Object
} else if(fiducialID >= 15 && fiducialID < = 16) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "rect~", new Atom[]{Atom.newAtom(0)}); // Create Rect~ Object
} else if(fiducialID >= 17 && fiducialID < = 18) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "saw~", new Atom[]{Atom.newAtom(0)}); // Create Saw~ Object
} else if(fiducialID >= 19 && fiducialID < = 20) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "tri~", new Atom[]{Atom.newAtom(0)}); // Create Tri~ Object
} else if(fiducialID >= 21 && fiducialID < 22) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "noise~", new Atom[]{Atom.newAtom(0)}); // Create Noise~ Object
} else if(fiducialID >= 23 && fiducialID < = 37) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "toggle", new Atom[]{Atom.newAtom(0)}); // Create Toggle Object
} else if(fiducialID >= 38 && fiducialID < 57) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "flonum", new Atom[]{Atom.newAtom(0f)}); // Create Floating-Point Number Box
values[(int)fiducialID - 38] = 0;
} else if(fiducialID == 58) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "ezdac~", new Atom[]{Atom.newAtom("stop")}); // Create EzDAC~ Object
} else if(fiducialID >= 59 && fiducialID < = 68) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "button", new Atom[]{Atom.newAtom(0)}); // Create Bang Object
} else if(fiducialID >= 69 && fiducialID < = 73) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "+~", new Atom[]{Atom.newAtom(0)}); // Create MSP Addition Object
} else if(fiducialID >= 74 && fiducialID < = 78) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "-~", new Atom[]{Atom.newAtom(0)}); // Create MSP Subtraction Object
} else if(fiducialID >= 79 && fiducialID < = 83) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "*~", new Atom[]{Atom.newAtom(1)}); // Create MSP Multiplication Object
} else if(fiducialID >= 84 && fiducialID < = 88) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "/~", new Atom[]{Atom.newAtom(1)}); // Create MSP Division Object
} else if(fiducialID >= 89 && fiducialID < = 93) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "reson~", new Atom[]{Atom.newAtom(0)}); // Create Reson~ Object
} else if(fiducialID >= 94 && fiducialID < = 98) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "groove~", new Atom[]{Atom.newAtom("")}); // Create Groove~ Object
} else if(fiducialID >= 99 && fiducialID < = 103) {
objects[(int)fiducialID] = patch.newDefault(coordinates[(int)fiducialID][0], coordinates[(int)fiducialID][1], "sig~", new Atom[]{Atom.newAtom("")}); // Create Sig~ Object
}
}

The variable patcher represents the parent patcher where the mxj object is held. The array objects[] contains all the objects that can be created. The array coordinates is used to hold the coordinates of the max objects that are being created. So now I come again to the problem and remind you that, when I create an MSP Object (like the cycle~, noise~, or any object that ends with ‘~’) Max crashes. The other objects (namely, toggle, button and flonum) that are not signal/MSP objects work perfectly and exactly in the way I want them (this leads me to think that my code works OK and that probably there is a Max bug/problem).

I have translated the code to JS in Max and works perfectly even for the MSP Objects.

Please let me know if you know about any related bugs or problems known or if you have found any problems in my code.

All the best and thank you in advance,

Achilles.



December 27, 2011 | 3:27 pm

Hey again,

I have also noticed another problem on my mxj object… When connected a flonum with a cycle~ and then the cycle~ to an ezdac~ I was changing the number inside the number box but I got no sound. Then I tried to turn off and then again on the ezdac~ and I got sound… BUT, when disconnected the cycle~ from the ezdac~ (while the ezdac~ was still on) I could still hear sound. It seems that the connection and disconnection doesn’t work properly (although the visual part of connection and disconnection in the patch works properly). I do all the process of creation, connection/disconnection, and change of the number box (I have tried changing the number with my mouse and keyboard too, but it didn’t "trigger" anything), as well as the on/off process of the ezdac~ from my mxj external.

The code that I use to connect and disconnect looks like this:

if(connection) {
patch.connect(firstObject, outletNumber, secondObject, inletNumber);
} else if(!connection) {
patch.disconnect(firstObject, outletNumber, secondObject, inletNumber);
}

Where, the variable patch equals to this.getParentPatcher().

I have also tried the exact same thing but this time bu connecting a toggle to the flonum and vice versa and everything works fine. It seems that the problem appears when I have to deal with MSP Objects. As before (on my initial post) all the problems seem to arise when it comes to the MSP part of Max. Please let me know if there is anything I am missing or misunderstanding, ’cause it is really frustrating to me, as I am new to java and generally programming.

Thanks again,

Achilles.


Viewing 2 posts - 1 through 2 (of 2 total)