Thanks for the fix in 0.46.7. There are a couple more subtle problems having to do with bounds checking (one of which may be there by design). Bounds checking occurs in the function array_rangeop_getrange() starting line 536:
firstitem = x->x_onset;
if (firstitem < 0)
firstitem = 0;
else if (firstitem > a->a_n)
firstitem = a->a_n;
if (x->x_n < 0)
nitem = a->a_n - firstitem;
else
{
nitem = x->x_n;
if (nitem + firstitem > a->a_n)
nitem = a->a_n - firstitem;
}
So unlike tabread which clips indices from 0 to n-1, this clips the onset from 0 to n, which means an onset greater than (n-1) gets a range with 0 items. I think this might be by design, but I wanted to check because a range with 0 items does something funny in the min/max array objects.
So first off, in these lines (starting line 746):
for (i = 0, besti = 0, bestf= -1e30, itemp = firstitem;
i < nitem; i++, itemp += stride)
if (*(t_float *)itemp > bestf)
bestf = *(t_float *)itemp, besti = i;
If the input range has 0 items (i.e. if nitems is set to zero manually, or if the onset is greater than n-1), the for-loop condition i < nitem is never true, so the value output is going to be the bestf init value -1e30 (likewise with +1e30 in the min function). Since this a value that doesn't point to anything in the array, I wonder if it would be better not to output anything (or maybe a bang) in those cases.
Second, the value x->x_rangeop.x_onset is not bounds checked, so when you do this (line 750):
outlet_float(x->x_out2, besti + x->x_rangeop.x_onset);
if x_rangeop.x_onset iss out of range, you're going to output an erroneous index value, which could be negative or greater than n. firstitem is bounds-checked from the onset by array_rangeop_getrange() -- would it be possible to use that instead?
This suite is really a wonderful addition to Pd, and adds so much new functionality to vanilla. Many cheers!
Matt
On Fri, Sep 4, 2015 at 8:11 PM, Miller Puckette msp@ucsd.edu wrote:
Yep :)
M
On Fri, Sep 04, 2015 at 07:46:30PM -0400, Matt Barber wrote:
Thanks.
I meant to say that there was the same problem in [array min], but you probably caught it in your fix.
Best,
Matt
On Fri, Sep 4, 2015 at 7:19 PM, Miller Puckette msp@ucsd.edu wrote:
Yep... thanks. Fixed in git - may take some time for me to get out a
new
compiled version (other stuff to fix too :)
M
On Fri, Sep 04, 2015 at 05:51:15PM -0400, Matt Barber wrote:
Hi list,
I've been playing around with the new(ish) [array] object suite in
vanilla
0.46.6. Forgive me if this is already a known issue, but it looks
like
the
min and max arguments aren't working properly.
The second inlet (setting the number of points to search) works as expected. The first inlet doesn't update: it seems to be set to 0 no
matter
what (although the index outlet is updated, but not as expected).
I think I see the problem in x_array.c
The max object is defined line 723:
typedef struct _array_max { t_array_rangeop x_rangeop; t_outlet *x_out1; /* value */ t_outlet *x_out2; /* index */ int x_onset; /* search onset */ } t_array_max;
And the bang and float methods starting 740:
static void array_max_bang(t_array_max *x) { char *itemp, *firstitem; int stride, nitem, i, besti; t_float bestf; if (!array_rangeop_getrange(&x->x_rangeop, &firstitem, &nitem,
&stride))
return; for (i = 0, besti = 0, bestf= -1e30, itemp = firstitem; i < nitem; i++, itemp += stride) if (*(t_float *)itemp > bestf) bestf = *(t_float *)itemp, besti = i; outlet_float(x->x_out2, besti+x->x_onset); outlet_float(x->x_out1, bestf);
}
static void array_max_float(t_array_max *x, t_floatarg f) { x->x_onset = f; array_max_bang(x); }
In the float method it looks like the onset is never actually
assigned in
the x_rangeop member of the t_array_max struct, so
array_rangeop_getrange
can't set the firstitem pointer to anything but its init value.
Thanks,
Matt
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management ->
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management ->