Edges Voice allocation

I thought it would be best practice to start learning a bit more about audio development. Edges eurorack code seems ideal to it :slight_smile: It’s focused on only a few functions and it doesn’t seem super complex.

However I (already) fail to understand the usage of bitwise operations in the voice allocation class.

I’m quite new to it. When I program, I only use decimal numbers and const to indicate things. Edges source code is using bitwise operations all the time. I know how to count bitwise and what the operators do, however I’m not sure why, when and how to use it for code.

E.g. I try to understand this peace of code:

  • pool_[voice] = 0x80 | note;
  • // … later:
  • if ((pool_[voice] & 0x7f) == note) {
  • // I tried it and it’s true, but why is it true? is there any way to understand this? I know what & and | is doing, but not why to use it.
  • }

Why not directly saving the note value e.g. 60 and then check it? Maybe there is something I’m missing :confused:

Or in noteOff you are using: pool_[voice] &= 0x7f;
Why not pool_[voice] = 0;?

Same: clearNotes: lru_[i] = kMaxPolyphony – i – 1; //e.g. lru_0 = 4 – 0 – 1 = 3? Why 3?
ClearNotes could be lru_0 = 0?

And where is the difference between lru_[] and pool_[]?

Thanks :slight_smile:

You’re looking at a rather difficult chunk of code!

pool_ stores the state of each voice. lru_ is used to figure out the “age” of each voice - the lower the number, the most recent the voice has been used, the less desirable it is to steal it.

I stuff two pieces of information in the pool_ array. The highest bit is whether the note is active; the lowest 7 bits is the actual MIDI note. To retrieve the note, I mask the 7 lower bits (& 0x7f). To retrieve the highest bit, I mask the highest bit (& 0x80). To write both a note and an “active note” bit, I or both (0x80 | note). To clear the “active note” bit, I mask the rest of the data with a 7 lower bits mask (& 0x7f). Now why do I need to store both pieces of information? When a new note arrive and I need to allocate a channel for it, I want to use, in priority, the least recently used inactive channel (there might still be the “tail” of a decaying envelope…) ; if none is available, the least recently used active channel. So even if a note is off I still need to keep track of it in the array!

The LRU array (“least recently used” – that’s very classic computer science stuff) is filled “backwards” because when I start the machine I want the first note played to be sent to the first channel, then on the second channel etc (it would be weird if when you boot up Ambika or a MIDIpal dispatcher or Edges and press a first note in poly mode, you’d get the last voicecard/MIDI channel/channel to sound). So the channel 1 has to be marked as least recently used

Wow that was a fast answer o0
Thanks! :slight_smile: