ERROR: Non Boolean in test

ERROR: Non Boolean in test. is an error I ran into several times. With some fiddling with the squiggels I get it to run most of the time. I do not understand what the error exactly means and see no consistent cause. Some guidance is needed desperately.

The code below I can’t get running. The first if runs fine, the second one barks at me.

	if (arrayDimension == 1, {
		if (maxVal < 256,
			{audiodata = Array.fill(width * height, {img.getInt8});},
			{audiodata = Array.fill(width * height, {img.getInt16});}
		)
	});
	if (arrayDimension == 2, {
		if (maxVal < 256,
			{audiodata = Array.fill([width , height], {img.getInt8});}, // ERROR: Non Boolean in test.
			{audiodata = Array.fill([width , height], {img.getInt16});} // ERROR: Non Boolean in test.
		)
	});

TIA

Where does maxVal come from?
Perhaps it’s not a number when
arrayDimension == 2

Cheers,
eddi
https://soundcloud.com/all-n4tural/sets/spotlight

postf("maxVal % (%)\n", maxVal, maxVal.class); ---> maxVal 65535 (Integer)

it comes from an array of chars, read from a file. Then converted to int via str.

The problem seems to be in the line {audiodata = Array.fill([width , height], {img.getInt16});} It also gives the error when it is not enclosed in the if statement. Same with audiodata = Array.fill2D(width , height, {img.getInt16});

Stack trace:

ERROR: Non Boolean in test.
RECEIVER:
Instance of Array {    (000001A6A54B1440, gc=64, fmt=01, flg=00, set=09)
  indexed slots [500]
      0 : true
      1 : true
      2 : true
      3 : true
      4 : true
      5 : true
      6 : true
      7 : true
      8 : true
      9 : true
     10 : true
     11 : true
     12 : false
     13 : false
     14 : false
     15 : false
    ...
}
PATH: [...]
CALL STACK:
	MethodError:reportError
		arg this = <instance of MustBeBooleanError>
	Nil:handleError
		arg this = nil
		arg error = <instance of MustBeBooleanError>
	Thread:handleError
		arg this = <instance of Thread>
		arg error = <instance of MustBeBooleanError>
	Object:throw
		arg this = <instance of MustBeBooleanError>
	Object:mustBeBoolean
		arg this = [*500]
	< FunctionDef in Method Collection:minItem >
		arg elem = [*500]
		arg i = 1
	ArrayedCollection:do
		arg this = [*500]
		arg function = <instance of Function>
		var i = 1
	Collection:minItem
		arg this = [*500]
		arg function = nil
		var minValue = nil
		var minElement = [*500]
	ArrayedCollection:normalize
		arg this = [*500]
		arg min = -1
		arg max = 1
		var minItem = nil
		var maxItem = nil
	Interpreter:interpretPrintCmdLine
		arg this = <instance of Interpreter>
		var res = nil
		var func = <instance of Function>
		var code = "~readPGM.("C:/Users/ingo/Doc..."
		var doc = nil
		var ideClass = <instance of Meta_ScIDE>
	Process:interpretPrintCmdLine
		arg this = <instance of Main>
^^ The preceding error dump is for ERROR: Non Boolean in test.
RECEIVER: [ true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false, false,...etc...

The clue is in your stack trace.
The implementation of Collection:minItem does:

this.do {|elem, i|
...

This is ArrayedCollection:do, the next stack item (i == 1 here, so you’re failing at the second item in whatever you’re calling normalize on).

This do is just calling the function provided in minItem:

			this.do {|elem, i|
				if (minElement.isNil) {
					minElement = elem;
				}{
					if (elem < minElement) {
						minElement = elem;
					}
				}
			};

The trace shows that elem = [*500], e.g. an array w/ 500 elements. This means elem < minElement will produce an array of true/false and not a single boolean value, which is the source of the error.

Seems like somewhere you’re trying to run ArrayedCollection:normalize on an array that contains other arrays and not just numbers. I don’t see how the normalize relates to the code you posted though? But in general, you can’t normalize a nested array, which is what Array.fill2D is producing. You can always do something like:

~a = [[1, 2, 3], [3, 4, 5]];
~a = ~a.linlin(~a.flatten.minItem, ~a.flatten.maxItem, 0, 1);

Thanks. That explains the matter. There’s a normalise just one step after the code snippet I posted.

In the meanwhile took a slightly different route as I’m mainly interested in a 1D array and a 2D is optional:

	if (maxVal < 256.0,
		{audiodata = Array.fill(width * height, {val = img.getInt8; if(val<0, {256+val},{val});});},
		{audiodata = Array.fill(width * height, {val = img.getInt16; if(val<0, {65536+val},{val});});} //UInt16
	);
	audiodata = audiodata.normalize(-1,1);
	if (arrayDimension == 2,
		{audiodata = Array2D.fromArray(width, height, audiodata);}
	);

Thanks.