buffer, frames and channels clarification

i need a little clarification about the values we deal with when
peeking/poking buffers. Untill now, what i’ve done worked fine but with
a great dose of luck. But i need to understand what’s the matter with
buffer->b_chans & buffer->b_frames… In parts of my code, using
buffer->b_frames for position (in samples) is ok, sometimes i have to
multiply b_frames by b_chans… In the following code, crossfade
positions are wrong and i don’t know why.

> Hello,
>
> i need a little clarification about the values we deal with when
> peeking/poking buffers. Untill now, what i’ve done worked fine but with
> a great dose of luck. But i need to understand what’s the matter with
> buffer->b_chans & buffer->b_frames… In parts of my code, using
> buffer->b_frames for position (in samples) is ok, sometimes i have to
> multiply b_frames by b_chans… In the following code, crossfade
> positions are wrong and i don’t know why.

buffer->b_chans is the number of channels the buffer~ has.

buffer->b_frames is the number auf ‘audio frames’, which can be
calculated as:
buffer->b_frames = buffer->b_size / buffer->b_nchans;

buffer->b_size is the total size of buffer in SAMPLES. These sampes can
be short, int or float or whatever, you set their type in:

buffer->b_outputbytes = sizeof(float); // or whatever it is

However, I’m not sure whether anything apart from float is officially
supported. As long as you use buffer~s with your own objects only and
they know what to do it’s probably okay.

So the total size in bytes of buffer~’s audio part in memory is:

buffer->b_size * buffer->b_outputbytes;

or:

buffer->b_frames * buffer->b_nchans * buffer->b_outputbytes;

Hope this helps a bit.

Ah, and when you modify a buffer you have to do something like this:

buffer->b_modtime = gettime(); buffer->b_valid = true;

This tells Max that you messed with it, the time will tell Max when you
did so, so that it knows whether it should redraw the window.
The last thing is setting the valid tag back to true to allow others to
access buffer again.

In some code examples you see things like this:

while (1) // spin while buffer~ is in use
{
if (!buffer->b_inuse)
break;
}
buffer->b_valid = false;

But when you access a buffer from a second thread you should probably do
something like this:

Many times you need to write routines that interpolate
the samples in a buffer. How would you use this
‘extra’ memory for that purpose?

Any sample code someone could share?

Thank you.

– Luigi

— Olaf Matthes

wrote:

> f.e wrote:
>
> > Hello,
> >
> > i need a little clarification about the values we
> deal with when
> > peeking/poking buffers. Untill now, what i’ve done
> worked fine but with
> > a great dose of luck. But i need to understand
> what’s the matter with
> > buffer->b_chans & buffer->b_frames… In parts of
> my code, using
> > buffer->b_frames for position (in samples) is ok,
> sometimes i have to
> > multiply b_frames by b_chans… In the following
> code, crossfade
> > positions are wrong and i don’t know why.
>
> buffer->b_chans is the number of channels the
> buffer~ has.
>
> buffer->b_frames is the number auf ‘audio frames’,
> which can be
> calculated as:
> buffer->b_frames = buffer->b_size /
> buffer->b_nchans;
>
> buffer->b_size is the total size of buffer in
> SAMPLES. These sampes can
> be short, int or float or whatever, you set their
> type in:
>
> buffer->b_outputbytes = sizeof(float); // or
> whatever it is
>
> However, I’m not sure whether anything apart from
> float is officially
> supported. As long as you use buffer~s with your own
> objects only and
> they know what to do it’s probably okay.
>
> So the total size in bytes of buffer~’s audio part
> in memory is:
>
> buffer->b_size * buffer->b_outputbytes;
>
> or:
>
> buffer->b_frames * buffer->b_nchans *
> buffer->b_outputbytes;
>
>
> Hope this helps a bit.
>
> Ah, and when you modify a buffer you have to do
> something like this:
>
> buffer->b_modtime = gettime(); buffer->b_valid
> = true;
>
> This tells Max that you messed with it, the time
> will tell Max when you
> did so, so that it knows whether it should redraw
> the window.
> The last thing is setting the valid tag back to true
> to allow others to
> access buffer again.
>
> In some code examples you see things like this:
>
> while (1) // spin while buffer~ is in use
> {
> if (!buffer->b_inuse)
> break;
> }
> buffer->b_valid = false;
>
>
> But when you access a buffer from a second thread
> you should probably do
> something like this:
>
> while (1) // spin while buffer~ is in use
> {
> if (!x->x_buffer->b_inuse)
> break;
> else
> #ifdef _WINDOWS
> Sleep(1);
> #else
> usleep(1000);
> #endif
> }
> buffer->b_valid = false;
>
> …because the first example eats all the CPU power
> while spinning in
> the while loop….
>
>
> Olaf
>

————————————————————
THIS E-MAIL MESSAGE IS FOR THE SOLE USE OF THE INTENDED RECIPIENT AND MAY CONTAIN CONFIDENTIAL AND/OR PRIVILEGED INFORMATION. ANY UNAUTHORIZED REVIEW, USE, DISCLOSURE OR DISTRIBUTION IS PROHIBITED. IF YOU ARE NOT THE INTENDED RECIPIENT, CONTACT THE SENDER BY E-MAIL AT SUPERBIGIO@YAHOO.COM AND DESTROY ALL COPIES OF THE ORIGINAL MESSAGE. WITHOUT PREJUDICE UCC1-207.
————————————————————

> Hi there,
>
> thanks Olaf. It definetely helps…
> There is another flag I have never been clear about:
>
> float *b_memory;
> // pointer to where memory starts (initial padding for
> interp)
>
> That’s what the buffer.h file says.
>
> Many times you need to write routines that interpolate
> the samples in a buffer. How would you use this
> ‘extra’ memory for that purpose?

And one more buffer~ question: which memory functions should one use
to resize a buffer~? I’m currently working on an external that
imports audio files into buffers, so I have to resize the buffer to
have the size of the file. Is t_resizebytes() okay for that or should
I use something else?