MCUdude / SigmaDSP

A versatile Arduino library for interfacing with the ADAU1401, ADAU1701 and ADAU1702 audio DSPs
GNU Lesser General Public License v3.0
165 stars 33 forks source link

Linear volume option #8

Closed Onefabis closed 9 months ago

Onefabis commented 4 years ago

Hi, could you please, add Slew volume linear option? This will be very handy for balance left-right channels. Something like this:

void SigmaDSP::volume_slew(uint16_t startMemoryAddress, float dB, int mode, uint8_t slew)
{
    float volume;
    if ( mode == 0 ){
        volume = pow(10, dB / 20); // 10^(dB / 20)
    } else {
        volume = dB; // Direct value
    };

  int32_t slewrate = 0x400000 / (1 << (slew - 1)); // 0x400000/2^(slew - 1))

  safeload_write(startMemoryAddress, volume, slewrate);
}
MCUdude commented 4 years ago

Well, audio is always logarithmic, no matter if you're adjusting balance or master volume. I have an application where I use two "regular" volume sliders to adjust balance. It is logarithmic (uses dB's) and works as expected + "feels" linear.

The good thing about this library is that it's very simple to create your own function based on what you see in Sigma Studio. The function you request is something you could implement yourself.

void linearVolume(uint16_t startMemoryAddress, int32_t volume, uint8_t slew)
{
  int32_t slewrate = 0x400000 / (1 << (slew - 1)); // 0x400000/2^(slew - 1))
  dsp.safeload_write(startMemoryAddress, volume, slewrate);
}
Onefabis commented 4 years ago

Hmm, I am curious how did you done the balance in accurate way? I use encoder with stm32 to do this. Let's pretend we have three slew sliders with 0 to -90dB range. One for master and two for left-right balance. Your volume code 10^(dB/20) is exponential, not logarithmic, right? I thought that the formula is y=10^(x/20), maybe I'm wrong with that. But I thought if I'm right, exponential is great for master volume, because ear more sensitive in the lowest volumes, so slew should change very accurate in the volume near -90dB, and more rough in the volume near 0dB. But what if the same approach will be used in the balance slew? Let's pretend that the balance relative value is 50/50, which means that both channels are equal and in the maximum volume (limited by the master volume slew, of course), so if I rotate encoder to the right with 10 units, I'll get 40/60, which means that I should get 80% of the left and 100% (or even 120% in compensation approach), I'll get rough significant changes in volume since exponential formula near 0dB changed very extensive: 10^(10dB/20)=3.16, 10^(0dB/20)=1, 10^(-10dB/20)=0.316, 10^(-20dB/20)=0.1, etc. The bigger X(dB) value the rougher delta in Y I'll get. Which results in that even little encoder rotate 40/60 cause almost silence in the left channel. That's why I was asked about linear option for those who want more predictive balance changes. P. S. Yes, I already did library modification for this node and another nodes in sigma studio, thank you anyway.