-
Notifications
You must be signed in to change notification settings - Fork 190
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
16 bit wavetable support #132
Comments
I managed to quickly add 16 bit wavetable support by slightly altering the |
I would definitely love to see this extended to all the other wave forms. |
I would also like to see this, particularly for the AVR arduino. Yes, it's 8-bit, but its output range is -488...487 and we can't take advantage of that right now with Oscil: in effect, from16Bit isn't all that useful because the input was just upsampled from 8 bit! Perhaps we could make an Oscil16? |
I hope this doesn't sound defeatist, but as the initial author of Mozzi, I think at this time that to make meaningful use of 16 bit wavetables, most of the library would need redesigning. |
Hi, On the other hand, I always wondered what would be the use case of a 16bits wavetables? I personally nearly always end up with more than 16bits before outputting: you multiply a Just to say, I'm not against it, I am just questioning the usefulness of it, especially for 8bitters like the Arduino where timings are already quite short… |
Oscil is only 8 bits. If we're typically outputting data at a constant gain, it's still 8-bits no matter how you slice it. But to keep things simple, loet's say that all I want to do is output a sine wave, for example. In fact I do that all the time with additive synths on Mozzi. All Oscil can give me is 0...255, but the Arduino can output 0...487. So I multiply the Oscil by 256, then hand it to from16Bit(...) to convert it to 0...487, but it's still 8-bit data, not 9-bit as the Arduino can do. But if Oscil (or an Oscil16) optionally outputted 16-bit, and we had 16-bit wavetables available (Or 8-bit mu-law!) I could likely get higher quality sound out of the Arduino than Mozzi is presently providing. If you want to multiply the gain by an envelope, sure, you'll go into 32-bit territory and then divide back down to 16-bit likely. Or you could just have your envelope go 0...64, use a -244...+243 wavetable stored in 16-bit, and you'd still be in 16 bit and have the full wavetable resolution that the Arduino can generate. |
For me, I don't need the rest of the library: I literally just need 16-bit wavetables and (ideally) 16-bit filters for them, so I can call next(). I handle the rest of it myself.
BTW, I have also been doing 8-bit u-law samples, which sound FAR better than the hissy 8-bit linear samples in Mozzi's Sample class. I just load u-law samples into Sample, call next(), and run it through a lookup table to convert to 16-bit. It is a huge improvement. I am a C guy, not a C++ guy, so I don't know exactly how to modify the Sample code to do this automatically, but I'd be glad to provide that table if someone was interested in incorporating it.
… On Dec 19, 2023, at 10:14 AM, Mr Sensorium ***@***.***> wrote:
I hope this doesn't sound defeatist, but as the initial author of Mozzi, I think at this time that to make meaningful use of 16 bit wavetables, most of the library would need redesigning.
The main challenge in first writing Mozzi was optimising it within the limitations of the 8 bit processors which were available then. Even if you have a 16 bit wavetable, you'd often need to scale it back to 8 bits to work with the synthesis classes in Mozzi.
I might be wrong, but I think the code would become unwieldy if you tried porting all of the synthesis classes differently for multiple processors. If you want higher resolution synthesis, I expect it would be simplest to find or begin a new library designed for more capable processors.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.
|
Alright, note that 16-bits filters are already there ( The u-bit law sample is interesting, but why using |
Well, there is a gotcha.
u-Law is stupidly designed: 0 input does not produce 0 output. So when the sample is over, obviously 0 is being produced, which when pumped through the lookup table will result in 32124.
So to do u-Law you have to do this:
if (sample.isPlaying()) return 0;
else return ulaw[sample.next()]
Thus you can't do this with just a waveshaper. Since u-Law is normally only used for samples, it'd make sense to incorporate it into the Sample class.
… On Dec 19, 2023, at 11:41 AM, Thomas Combriat ***@***.***> wrote:
For me, I don't need the rest of the library: I literally just need 16-bit wavetables and (ideally) 16-bit filters for them, so I can call next(). I handle the rest of it myself.
Alright, note that 16-bits filters are already there (ResonantFilter).
The u-bit law sample is interesting, but why using Sample instead of Oscil ? There are basically the same thing. I think the correct way to do it would be to send it afterward to WaveShaper, with the correct lookup table. Such a inverse u-law convert table would indeed be interesting to have built-in in Mozzi (probably just need to add the lookup somewhere and add an example of usage in combination with WaveShaper).
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.
|
Here's the uLaw lookup table. It takes a uint8_t input from Sample.next() and produces a uint16_t output. From there you can pass it to from16Bit(...) to output it. But make sure that sample is playing: if it is not, you need to pass from16Bit(0).
This table was generated from a famous and old chunk of code:
|
Have to say I do not really get it… You can put any lookup table in the WaveShaper, in particular ones that artificially maps 0 to 0. Having a test at AUDIO_RATE could also lead to some troubles in terms of performances. Also, I guess this would integrate way more if working on signed samples (like the ones handled by Mozzi). This triggered my curiosity, will probably try at some point! |
That's right. All we really need is a 16-bit oscil, and sin/square/tri/saw tables in 16-bit. |
@eclab Are you using u-law with PWM output? I read here and there that this is mainly used for PCM, does it also improves the quality for PWM and DAC outputs? |
Before I answer that question, one of my own. Supposedly the PWM output on the Arduino can range from -244 to + 243 (hence the "8.5 bit" stuff). Indeed the fromAlmostNBit(...) function documentation says:
But it does nothing of the sort. It just scales to 9 bit (+/-256) and expects you to clip the result. That's gonna sound terrible. I don't understand why it would do this when there's such an easy procedure to scale to exactly the right value:
Is it in fact the case that the PWM range is 488 values? And if so, why is Mozzi just clipping? |
At any rate, uLaw is just a companding algorithm: it logarithmically stretches 8 bits into 12 bits in a clever way designed to sound like 12 bits to human ears. It's useful for reducing the noise floor and for taking advantage of the 9 bits if you had them. |
That's interesting, will try to test that in a |
Currently the wavetables have an 8 bit resolution. It would be nice to also support a higher resolution like 16 bit, especially in combination with a 12 bit DAW. Any idea how to implement this?
The text was updated successfully, but these errors were encountered: