Braids code at 48kHz?

This discussion was created from comments split from: Buffering.

Noted. But the actual code to generate each oscillator type should be portable, though? Or are they completely tied in to the buffer setup?

I was looking at the ‘render’ methods in digital_oscillator.cc, trying to work out how self-contained the methods are. Some seem to depend on lookup tables that seem to be generated at compile time by a python script. Is this the case?

a|x

> But the actual code to generate each oscillator type should be portable

Yes, but it’s still tied to the 96kHz sample rate.

> Is this the case?

Yes. You’ll need to make the required modification in the python scripts to account for the change in playback rate and regenerate the lookup tables.

So it’s a matter of adjusting the phase-increment amount, then? Or is there more to it than that?
Are there any of the oscillator types that would likely sound especially bad at 48k?

a|x

> So it’s a matter of adjusting the phase-increment amount, then?

Everything is in the precomputed table.

> Are there any of the oscillator types that would likely sound especially bad at 48k?

As long as you play your notes one octave lower, no :slight_smile:

Only the first “analog” waveforms have proper bandlimiting. For Z*****, VOSIM, TOY*, the wavetables etc, the code relies on oversampling.

By oversampling, you mean computing the samples at 96k, then averaging them down to 48k?

What’s in the precomputed table, exactly? Do you mean there’s a different precomputed table for each oscillator type?

I don’t see why oversampling shouldn’t also be possible on the Axoloti.

a|x

Oh, do you mean the phase-increment amount is precomputed for different frequencies? You must still have to interpolate, though, if that’s the case- you couldn’t put every possible frequency in there…

Sorry, these are all probably stupid questions. Just trying to understand some basic principles…

a|x

> By oversampling, you mean computing the samples at 96k, then averaging them down to 48k?

No.

Some of the code written for Braids rely on the fact that the sample rate is 96k, and thus that the aliasing will mostly be above the audible range. If you run the same code at 48k, the aliasing will be more noticeable.

Averaging samples won’t really work in this case.

> What’s in the precomputed table, exactly?

It’s not like the code is kept secret and has no comments. I can read:

  • oscillator increments
  • oscillator delays
  • “Resonator coefficients”
  • “SVF coefficients”
  • Bowing envelope and frction curve

So all the stuff related to conversion from frequency to samples or increments, and filters, envelopes…

> Do you mean there’s a different precomputed table for each oscillator type?

No.

There’s an important difference between something being visible, and being comprehensible, to a limited brain like mine :wink:

But thank you for your patience in the face of my uneducated questions.

a|x

“Read the source, Luke”

Indeed, t2k…

a|x

One thing that has helped me understand other people’s code is trying to re-implement it myself in small steps with lots of debugging output.

That sounds like a good strategy, t2k. I’ve done quite a lot of coding myself, over the years, just no real DSP stuff.

The problem with that strategy, when a given block of code isn’t well understood, is that’s it’s hard to simplify it down to small discrete components, when it’s not clear what each part does, and how the various parts inter-relate.

I’ve had quite a lot of practice picking apart (and occasionally successfully reassembling) other people’s code, but sorting out some basic principles by asking someone who knows, and is generous with his knowledge, is still very valuable.

a|x

The thing is, Braids’ code is tied way too much to the limitations of its hardware (lack of floating point for example). I can’t name a thing it does that couldn’t be done better on an M4.

Completely understood.

I wouldn’t know where to start rewriting in floating-point though, whereas I’m starting to get an idea of how I might start re-purposing some of the oscillator types for Axoloti, in more-or-less their current, non-M4-optimised form.

Having said that, in the past, I’ve worked a lot with GLSL, where a lot of techniques rely on using floating-point numbers in the 0-1 range. Any head-start I may have in that sense is more than cancelled out by my basic maths myopia, sadly.

The nice thing about the Axoloti platform (and also the Patchblocks system, to an extent, though it runs in much more limited hardware) is that it does a lot of stuff for you- I/O, MIDI etc., but also makes it relatively easy to drop in your own code via custom objects, so it’s good for someone like me, who wants to dip their toes in to DSP, without investing a huge amount of time setting everything up from scratch.

a|x