Q: can we read/modify buffer~ data from an MSP object?

Nov 29, 2006 at 10:24pm

Q: can we read/modify buffer~ data from an MSP object?

>
> And if so, how do we get to the t_buffer struct from a buffer~ name
> (as t_symbol or char * or whatever)?
>
> I looked at buffer.h and z_dsp.h but there don’t appear to be any
> functions for accessing, allocating or modifying buffer~ data.
>
> Thanks

#28972
Nov 30, 2006 at 8:19pm

Hi Graham,

buffer~ objects but a pointer to their memory location in the s_thing
field of their associated symbol. eg, here’s a method from peek~ that
should illustrate how to get at a buffer’s data.

void peek_writebuf(t_peek *x, long chan, long index, double value)
{
t_buffer *b;

if (x->p_sym == ps_nothing)
return;

b = (t_buffer *)x->p_sym->s_thing;

if (!b)
return;

if (ob_sym(b) == ps_buffer && b->b_valid) {
index = CLIP(index,0,b->b_frames-1);
index *= b->b_nchans;
chan = CLIP(chan,1,b->b_nchans) – 1;
index += chan;
b->b_samples[index] = value;
peek_dirtybuffer(x,b);
}
}

Note that it’s important to check the buffer’s validity every time
your obj wants to read or write from or to it. Note also that if you
change the contents of the buffer you should call the buffer’s dirty
function:

void peek_dirtybuffer(t_peek *x, t_buffer *b)
{
static zero_meth dirtier = 0;
static Boolean dirtylookup = false;

if (!dirtylookup) {
dirtier = (zero_meth)zgetfn((t_object *)b,ps_dirty);
dirtylookup = true;
}
if (dirtier)
(*dirtier)(b);
}

Hope that helps.
Ben

On 11/29/06, Graham Wakefield

wrote:
> >
> > And if so, how do we get to the t_buffer struct from a buffer~ name
> > (as t_symbol or char * or whatever)?
> >
> > I looked at buffer.h and z_dsp.h but there don’t appear to be any
> > functions for accessing, allocating or modifying buffer~ data.
> >
> > Thanks
>

#89601
Nov 30, 2006 at 8:54pm

On Nov 30, 2006, at 3:19 PM, Ben Nevile wrote:
> Note that it’s important to check the buffer’s validity every time
> your obj wants to read or write from or to it. Note also that if you
> change the contents of the buffer you should call the buffer’s dirty
> function:

I’ll echo Ben’s comments and add that you should be mindful of the
“b_inuse” variable. This what was causing me problems when I ported
my granular objects over to UB. If you use the buffer contents
during your perform method…

t_int *myobject_perform(t_int *w)
{
// local variables
t_myobject *x = (t_myobject *)(w[1]);
long saveinuse;
t_buffer *s_ptr = x->snd_buf_ptr;

// update the in use state
saveinuse = s_ptr->b_inuse
s_ptr->b_inuse = true;

// process //
// something //
// here //

// reset “in use” state
s_ptr->b_inuse = saveinuse_s;
}

Because my objects can change associated buffers *during* the perform
method, my code was actually leaving the state set to “true” sometimes.

NOTE TO C74: Max 4.6.2 crashes hard if you do this then try to
change the contents of a buffer. Max 4.5.7 happily told me that the
buffer could not be be changed at this time. Might want to check on
this. (MacBook Pro, 2 GHz, 1 gig RAM)

Anyway, all fixed now. Just make sure that when you quit using the
buffer you reset this variable.

—–
Nathan Wolek
nw@nathanwolek.com

http://www.nathanwolek.com

#89602
Dec 1, 2006 at 8:34pm

Thanks for the tip. I will definitely be doing things to buffer~s in
the perform method.

On Nov 30, 2006, at 12:54 PM, Nathan Wolek wrote:

> On Nov 30, 2006, at 3:19 PM, Ben Nevile wrote:
>> Note that it’s important to check the buffer’s validity every time
>> your obj wants to read or write from or to it. Note also that if you
>> change the contents of the buffer you should call the buffer’s dirty
>> function:
>
> I’ll echo Ben’s comments and add that you should be mindful of the
> “b_inuse” variable. This what was causing me problems when I
> ported my granular objects over to UB. If you use the buffer
> contents during your perform method…
>
> t_int *myobject_perform(t_int *w)
> {
> // local variables
> t_myobject *x = (t_myobject *)(w[1]);
> long saveinuse;
> t_buffer *s_ptr = x->snd_buf_ptr;
>
> // update the in use state
> saveinuse = s_ptr->b_inuse
> s_ptr->b_inuse = true;
>
> // process //
> // something //
> // here //
>
> // reset “in use” state
> s_ptr->b_inuse = saveinuse_s;
> }
>
> Because my objects can change associated buffers *during* the
> perform method, my code was actually leaving the state set to
> “true” sometimes.
>
> NOTE TO C74: Max 4.6.2 crashes hard if you do this then try to
> change the contents of a buffer. Max 4.5.7 happily told me that
> the buffer could not be be changed at this time. Might want to
> check on this. (MacBook Pro, 2 GHz, 1 gig RAM)
>
> Anyway, all fixed now. Just make sure that when you quit using the
> buffer you reset this variable.
>
> —–
> Nathan Wolek
> nw@nathanwolek.com
> http://www.nathanwolek.com
>

#89603

You must be logged in to reply to this topic.