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


    Nov 29 2006 | 10:24 pm
    > > 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

    • Nov 30 2006 | 8:19 pm
      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 >
    • Nov 30 2006 | 8:54 pm
      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
    • Dec 01 2006 | 8:34 pm
      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 >