struggling refactoring this piece of code

Maybe I’m tired, but I’m not able to refactoring this piece of code:

if (someCondition) {
	for (int c = 0; c < channels; c += 4) {
		// some works
		rack::simd::float_4 out = 0.0f;
		
		// some process on out
        out += functionA();

		outputs[THE_OUTPUT].setVoltageSimd(out * 5.0f, (uint8_t)c);
	}
} else {
	for (int c = 0; c < channels; c += 4) {
		outputs[THE_OUTPUT].setVoltageSimd(rack::simd::float_4(0.0f), (uint8_t)c);
	}
}

outputs[THE_OUTPUT].setChannels((uint8_t)channels);

in this (exporting the out array, and give only one setVoltageSimd):

std::array<rack::simd::float_4, 4> outNew;
outNew.fill(rack::simd::float_4(0.0f));

if (someCondition) {
	for (int c = 0; c < channels; c += 4) {
		// some works
		outNew[c / 4] = 0.0f;
		
		// some process on outNew[c / 4]
        outNew[c / 4] += functionA();
	}
}

for (int c = 0; c < channels; c += 4) {
	outputs[THE_OUTPUT].setVoltageSimd(outNew[c / 4] * 5.0f, (uint8_t)c);
}

outputs[THE_OUTPUT].setChannels((uint8_t)channels);

The second version output weird/glitch audio, sometimes crashing rack, and I’m not able to understand why.

Aren’t the two equivalent in terms of final output?

This is exactly the kind of thing I would test and debug in a unit test or some other isolated context. Otherwise I would never be able to get this to act correctly. But that’s just me.

I don’t immediately see the issue. Where is outNew declared? is it a local variable (which would be terrible), a class member (presumably), or a global variable?

Its declared in the process() scope, alongside the rest of the code processing audio.

Why do you say “terribile”? Would be used as register “on the fly” I would says, without storing in Memory etc

If the condition is the same the first code seems to set the value to the out value *5 for each match and the second one only seems to zero the values. But, obviously we don’t see all the code so kind of impossible to guess really.

If the if condition in fragment 1 a match with the else condition in fragment 2?

You may know all this, and is so apologies in advance. I assumed that outNew was something that should be retained from one process call to the next. If that was the intention, this will not do it, since it will be destroyed and re-created every process call. I meant “terrible” if the intention was to have it retained. As @main.tenant says, it’s difficult to know in isolation…

1 Like

Should be pretty irrelevant, for the purpose of the comparison, let say it will add the result of an external function (I’ve edited the question, making it more clear).

Yep is intended to be this way, as “out” variabile won’t be available in the next block as for the first example (init on place).

I can’t see anything obviously wrong, but we are only seeing the code where you think the problems exists and I know because it has bitten me on the arse loads of times it might not be that code that’s the problem.

As Squinky says, maybe do more testing like a full step through in a debugger watching locals and checking state.

1 Like

Got it. Was an un-init variable in the for loop. Introducing main array, it has start to value it with non-zero value, making things weird.

Thanks for the support anyway.

1 Like

for me the the problem is in outNew not reinited in the second loop/example

if the !someCondition than outNew stays with last value