sensorium / Mozzi

sound synthesis library for Arduino
https://sensorium.github.io/Mozzi/
GNU Lesser General Public License v2.1
1.07k stars 186 forks source link

Ambiguity in `fromAlmostNBit` for 32bits platforms #140

Closed tomcombriat closed 2 years ago

tomcombriat commented 2 years ago

Hi,

According to the forum, the examples containing the MonoOutput::fromAlmostNBit function creates an ambiguity for the compiler, resulting in a compilation fail. Eg:


StateVariableFilter:55: error: call of overloaded 'fromAlmostNBit(int, int)' is ambiguous
   return MonoOutput::fromAlmostNBit(12, svf.next(aNoise.next()));
In file included from C:\Users\User\Documents\Arduino\libraries\Mozzi/MozziGuts.h:223:0,
                 from C:\Users\User\Documents\Arduino\libraries\Mozzi\examples\10.Audio_Filters\StateVariableFilter\StateVariableFilter.ino:19:
C:\Users\User\Documents\Arduino\libraries\Mozzi/AudioOutput.h:173:28: note: candidate: static MonoOutput MonoOutput::fromAlmostNBit(uint8_t, int16_t)
   static inline MonoOutput fromAlmostNBit(uint8_t bits, int16_t l) { return MonoOutput(SCALE_AUDIO_NEAR(l, bits)); }
C:\Users\User\Documents\Arduino\libraries\Mozzi/AudioOutput.h:175:28: note: candidate: static MonoOutput MonoOutput::fromAlmostNBit(uint8_t, int32_t)
static inline MonoOutput fromAlmostNBit(uint8_t bits, int32_t l) { return MonoOutput(SCALE_AUDIO_NEAR(l, bits)); }
 call of overloaded 'fromAlmostNBit(int, int)' is ambiguous

I have reproduced the error here on STM32 and Teensy. An easy fix is to add a cast on call in these examples, for instance replacing

return MonoOutput::fromAlmostNBit(12, svf.next(aNoise.next()));

with

return MonoOutput::fromAlmostNBit(12, (int16_t) svf.next(aNoise.next()));

But I am not sure if that is the cleanest. Maybe @tfry-git will have a better idea!

tfry-git commented 2 years ago

I am somewhat confused, why the compiler considers this to be ambiguous. Either way, this should not be something for the user to worry about (and thus not something to fix in the example code).

The clean solution will be to add more overloads, but I'm not entirely sure, which one(s) (the overloads, here, do not really do anything special, but are simply meant to avoid unneeded conversions). Possibly MonoOutput::fromAlmostNBit(int, int);.

tomcombriat commented 2 years ago

Either way, this should not be something for the user to worry about (and thus not something to fix in the example code).

Yes, I knew there would be a better solution. I will try to add an overload and test if you want.

tfry-git commented 2 years ago

I will try to add an overload and test if you want.

That would be cool. After some thinking, I believe the overload to add is "simply":

template<typename A, typename B> static inline MonoOutput fromAlmostNBit(A bits, B l) { return MonoOutput(SCALE_AUDIO_NEAR(l, bits)); }

This one could then replace the two existing overloads (which simply wrap a macro, anyway, and are supposed to be optimized away).

tomcombriat commented 2 years ago

Solved by #141