dictionary_getatoms() question

Dec 30, 2013 at 8:37pm

dictionary_getatoms() question

Hi all,

I’m hitting a wall in one area of my external code trying to grab a t_atom array value from a t_dictionary * internal to my object. I’ve used dictionary_getatoms in other very similar areas of my code without any issues, but for some reason, I can’t get this to work.

I have a dictionary * (called nodeDict) with an array of floats stored at the key “position”. Here’s an example of what the dictionary might look like:

"0" : {
"channel" : 1,
"type" : 1,
"position" : [ -250.5979, 358.714111 ],
"attenuation" : 1.0
}

When I dump the dict, I can confirm that the position values are there and correct. But when I use dictionary_getatoms() to grab them, and post the results, I’m getting 0.000000 for everything. I’ve tried dictionary_copyatoms() as well, same result. Totally confused here. Again, doing virtually the exact same thing in another area of my code without issue… Here’s the code snippet below. Does anyone have any idea what I’m doing wrong here?

best,
Zachary

t_symbol *posSym = gensym("position");
t_atom *nodePosition = NULL;
long length = 0;
dictionary_dump(nodeDict, 0, 0);
if (dictionary_getatoms(nodeDict, posSym, &length, &nodePosition) == MAX_ERR_NONE) {
if (length == 2) {
if ((atom_gettype(nodePosition) == A_LONG || atom_gettype(nodePosition) == A_FLOAT) &&
(atom_gettype(nodePosition+1) == A_LONG || atom_gettype(nodePosition+1) == A_FLOAT)) {
post("node position x: %f y: %f", atom_getfloat(nodePosition), atom_getfloat(nodePosition+1));
}
}
}

#277005
Dec 31, 2013 at 6:59am

Hi,

Your code seems good. Surely a weird bugs. That i did not experienced before, so i don’t have any clue. Maybe you should provide more code.

#277042
Dec 31, 2013 at 5:27pm

Hi Nicolas,

I’ve done a little more debugging, and the weirdness factor is increasing. I’ve been running in Max 6.1.6 64-bit mode (and would like to support that).

Some observations (Cycling folks, if you could chime in here, it would be very appreciated. I’ve spent at least 8 hours trying to figure this out before posting):

1. If I change to 32-bit mode Max then post sends the correct values to the Max window. In 64-bit mode all zeros (as mentioned in my first post).

2. Posting the values as %ld (atom_getlong(nodePosition), etc. prints the correct values, of course truncated. I mentioned that I’m doing the very same thing in another area of my code without issue. Turns out this is because the values in that t_atom array are long (not float). If I post those values as floats also prints zeros (where it should just coerce to float).

3. If I send the t_atom array out of an outlet via outlet_list, it sends the correct values!!

I even tried grabbing the array using dictionary_getatomarray(), along with the necessary code to then grab the atoms, and same exact behavior.

I tried running this in Max 6.1.3 64-bit mode as well. Same exact behavior. Also tried compiling using 6.1.3 SDK. Same behavior.

Ideas???

best,
Zachary

#277077
Dec 31, 2013 at 8:52pm

Happy New Year!

Ok, this code snippet summarizes the problem, I think. Nicolas or anyone else, please add this code snippet to one of your objects, and see if you experience the same behavior.

t_atom testList[2];
atom_setfloat(testList, 33.333);
atom_setfloat(testList+1, -500.0);
outlet_list(x->u_out, 0L, 2, testList);
outlet_float(x->u_out, atom_getfloat(testList));
outlet_float(x->u_out, atom_getfloat(testList+1));
post("Test List (floats from atoms): %f %f", atom_getfloat(testList), atom_getfloat(testList+1));
post("Test List (longs from atoms): %ld %ld", atom_getlong(testList), atom_getlong(testList+1));
post("....");

double tl[2];
tl[0] = atom_getfloat(testList);
tl[1] = atom_getfloat(testList+1);
outlet_float(x->u_out, tl[0]);
outlet_float(x->u_out, tl[1]);
post("Test List (floats): %f %f", tl[0], tl[1]);

Running this in 64-bit Max 6.1.x I get all zeros for floats using post(), but everything’s as it should be when sending out a physical output. That’s good news for me because it means I’m not having a problem with dictionary_getatoms() at all. Should I be using a different printf format string for floats and doubles in post()?? I tried a variety of them, no luck, unless I run in 32-bit mode.

I’m running Max 6.1.6 on OSX 10.8.5. Compiling using Xcode 5.0.2 with Base SDK and Deployment Target of 10.8 (although I experimented with others, same behavior in 64-bit mode).

Pictures attached of the Max window printout for the above code snippet in 32-bit and 64-bit modes.

best,
Zachary

Attachments:
  1. 32-bit_Max
  2. 64-bit_Max
#277080
Dec 31, 2013 at 11:25pm

Hi,

So it is a noise from 64-bit “post”. Sorry, i’m stuck to Max 5 so i cannot experiment 64-bit features (i’m not very used with the new SDK). This bug sound silly, and that’s exactly the situation when you hate closed source libraries. Have you tried to insert memory barrier (to exclude compiler and CPU reordering)? It’s surely a desperate and stupid hypothesis but after so many hours who cares? (And if you are not patient enough to wait C74′s folks, you may look and compare assembly code in order to understand a bit more what’s happening.)

double tl[2];
tl[0] = atom_getfloat(testList);
tl[1] = atom_getfloat(testList+1);
outlet_float(x->u_out, tl[0]);
outlet_float(x->u_out, tl[1]);

OSMemoryBarrier( );

post("Test List (floats): %f %f", tl[0], tl[1]);
#277083
Jan 1, 2014 at 9:33pm

Hi Nicolas,

OSMemoryBarrier() didn’t fix it. Thanks for the suggestion. Now that I know the behavior (at least with Xcode 5.0.x), I don’t have to waste more time on it…

I’ll submit a bug report (if no one from Cycling reads this) whenever I can muster up the will to do so…

best,
Zachary

#277130
Jan 4, 2014 at 7:35am

Hi there,

I got curious from this post because the bug that Zachary is describing is really weird.

On my machine everything works as it should. I am on Mac OS 10.9.1 running Max 6.1.6 in 64bit mode. Compiling using Xcode 5.0.2 with Base SDK and Deployment Target of 10.8.

I am using exactly the same code that Zachary posted:

t_atom testList[2];
atom_setfloat(testList, 33.333);
atom_setfloat(testList+1, -500.0);
outlet_list(x->u_out, 0L, 2, testList);
outlet_float(x->u_out, atom_getfloat(testList));
outlet_float(x->u_out, atom_getfloat(testList+1));
post("Test List (floats from atoms): %f %f", atom_getfloat(testList), atom_getfloat(testList+1));
post("Test List (longs from atoms): %ld %ld", atom_getlong(testList), atom_getlong(testList+1));
post("....");

As you can see the only difference from my setup and Zachary’s is the OS version. Might that be the culprit? Honestly, I don’t think so… but I can’t be absolutely certain.

Also, this code:

t_symbol *posSym = gensym("position");
t_atom *nodePosition = NULL;
long length = 0;
dictionary_dump(nodeDict, 0, 0);
if (dictionary_getatoms(nodeDict, posSym, &length, &nodePosition) == MAX_ERR_NONE) {
if (length == 2) {
if ((atom_gettype(nodePosition) == A_LONG || atom_gettype(nodePosition) == A_FLOAT) &&
(atom_gettype(nodePosition+1) == A_LONG || atom_gettype(nodePosition+1) == A_FLOAT)) {
post("node position x: %f y: %f", atom_getfloat(nodePosition), atom_getfloat(nodePosition+1));
}
}
}

can be simplified to the following:

t_symbol *posSym = gensym("position");
t_atom *nodePosition = NULL;
long length = 0;
dictionary_dump(nodeDict, 0, 0);
if (dictionary_getatoms(nodeDict, posSym, &length, &nodePosition) == MAX_ERR_NONE) {
if (length == 2) {
post("node position x: %f y: %f", atom_getfloat(nodePosition), atom_getfloat(nodePosition+1));
}
}

@Zachary:
If you have a chance to test your code on 10.9.1 and are still getting the same bug then we’ll know for sure that there’s an issue with your code, not with the SDK. Please, do that before submitting a bug report.

Best

- Luigi

Attachments:
  1. Luigi_Setup
#277376
Jan 4, 2014 at 7:54am

Hi Luigi,

By testing with only that simple block of code, I have already removed the possibility of it being an issue with my code. However, it does seem to be an issue with something in my Xcode config, interestingly. Same exact code behaves fine when I insert it into dummy_bang of the examples dummy object.

I’ll look into what the differences are sometime soon, and post back here, just in case someone else ends up with this behavior.

best,
Zachary

#277384
Jan 5, 2014 at 7:03pm

So I’ve found the culprit, although I haven’t wrapped my head around exactly why I get the behavior detailed in my first two posts.

I prefer to link to the SDK frameworks with xcconfig variables that can be changed by users, rather than save the frameworks via drop and paste into the Xcode project (the default way it’s done in the examples provided). That way, I can include the code in other repositories that don’t necessarily wind up in a subdirectory of the MaxSDK, and a collaborator can just update those variables and compile.

Anyways, I was adding -framework MaxAPI -framework MaxAudioAP to the OTHER_LDFLAGS variable. -framework MaxAPI was causing this bizarre behavior in 64-bit mode, interestingly. Maybe I needed it at some point, but as it turns out, with the current SDK and Xcode 5.0.2, I don’t even need to specify it. I Do, however, need -framework MaxAudioAPI, if I’m building MSP externals. I’ve included an example xcconfig file.

If any of you have other ways of doing this, please chime in here. I find Xcode config somewhat confusing.

best,
Zachary

#277497

You must be logged in to reply to this topic.