sensorium / Mozzi

sound synthesis library for Arduino

Home Page:https://sensorium.github.io/Mozzi/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ambiguity in `fromAlmostNBit` for 32bits platforms

tomcombriat opened this issue · comments

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!

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);.

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.

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).

Solved by #141