buffer_ref_notify with multiple buffers

bolau's icon

Hi folks,

I'm still fairly new to the MSP API, so please be patient with me :)
When working on a multi-buffer MSP object I dissected the simpwave example. I understand that the simpwave_notify function is a callback to update a module's state when its referenced buffers have changed.

simpwave_notify uses this return value:
return buffer_ref_notify(x->w_buf, s, msg, sender, data);

But what does this do? And how does this translate to an MSP object with multiple buffers -- how do I now which of my buffers was modified so I can put its reference here as an argument?
The reference PDF just says "Your notify method should then call this notify method for the t_buffer_ref", but it does not reveal (to me) what it does.

Thanks for any help...

Best, Boris

bolau's icon

I should add that this is a nasty issue for me right now: If I call buffer_ref_notify for the wrong (= the unchanged and thus still empty) buffer, Max crashes...
Best, Boris

Timothy Place's icon

Among other things, you need to call this when you receive notifications from the buffer~ for the following scenario:

The buffer~ object is freed

The buffer reference then must be updated to about this event so that it doesn't do something bad (like try to call into the buffer~ that no longer exists).

In this case you should look at the "sender" parameter to your notify method. You can use an if statement to see which buffer~ it matches and forward as necessary.

- .. --

Arvid Tomayko's icon

Sorry to dig up an old thread, but I also working on an object that accesses multiple buffers right now and I'm a bit unclear on this same issue.

How would I test the sender parameter to tell which buffer it is from? Should it match the buffer_ref, buffer_obj or buffer_name of the buffer I'm using?
And then how would I compare sender to said t_buffer_ref or t_buffer_obj, etc to see which one it matches?

For now i've just left this function empty in my object (because at least it doesn't crash from calling buffer_ref_notify on the wrong buffer) and coded all my buffer operations to first check if they reference a valid buffer, but I bet that's not very good practice…

Also, I couldn't find anywhere what symbols the buffer~ would actually send via the notify besides "buffer_modified" ––– eg when it's freed. I figured it out by posting s->s_name to the console and testing, but it would be good if that was in the SDK documentation somewhere…

Thanks!
Arvid

Matthias's icon

I used this notify method for my external, which accesses two buffers simultaneously:

t_max_err cmgrainlabs_notify(t_cmgrainlabs *x, t_symbol *s, t_symbol *msg, void *sender, void *data) {
    t_symbol *buffer_name = (t_symbol *)object_method((t_object *)sender, gensym("getname"));
    if (msg == ps_buffer_modified) {
        x->buffer_modified = 1;
    }
    if (buffer_name == x->window_name) { // check if calling object was the window buffer
        return buffer_ref_notify(x->w_buffer, s, msg, sender, data); // return with the calling buffer
    }
    else { // check if calling object was the sample buffer
        return buffer_ref_notify(x->buffer, s, msg, sender, data); // return with the calling buffer
    }
}

Get the sender pointer and assign it to a t_symbol* pointer variable, you should then be able to differentiate between the various buffers calling the notify method.

Hope that helps.
-Matthias

Arvid Tomayko's icon

Thanks Matthias! That approach seems to work great.

And if the name returned doesn't match one of my buffers (which I assume shouldn't actually happen) i'm returning MAX_ERR_NONE. Does that sound reasonable?

Matthias's icon

I must say I never had the case that the returned buffer name didn't match any of the ones referenced. And I wouldn't be able to tell if such a case could happen at all. Here, I'm at a loss, sorry..

Arvid Tomayko's icon

No problem. Thanks for your help!

Matthias's icon

Check out the second to last post in this thread by RICHARD MITIC:
https://cycling74.com/forums/notify-method-when-accessing-two-buffers/

This could make the whole thing more or less bullet-proof.