baldram/ESP_VS1053_Library

Bass/Treble enhancement (SCI_BASS) requires a 16-bit value (4 nibbles)

RalphBacon opened this issue ยท 13 comments

The function

void VS1053::setTone(uint8_t *rtone)

requires 4 nibbles (4 bytes each) so 16 bits in total. The current 8-bit parameter does not allow this unless I've totally misunderstood the datasheet.

I've written my own function to prove this and a uint16_t seems to work fine.

Any chance of correcting my understanding or the function please?

Hi, thank you for interesting report.
Not sure I'm able to correct your understanding. The setTone function is aligned with the original API from here, what was well tested with the full featured radio project. I see that it's still like this in the ESP32 version of the project. You might have a look for use case on how it is executed there. If I'm not wrong, this part might be interesting.

I had a look on the other, quite similar thing, which was recently adjusted by @fabitom. The change is here, and setVolume is still dealing with uint8_t .

I see the code fix you refer to, which is probably here. Not sure why this is not an issue for the original radio project, from where I extracted the driver part.

Maybe @Edzelf might have any insights on this?

*rtone is an array (uint8_t rtone[4]) later converted to uint16_t.

The parameter is not an 8 bit value, but a pointer to an array of 4 nibbles.

Ah ha! I was unaware that the parameter was supposed to point to an array.

Even so, I see that the array is made up of 4 single character (8-bit) integer, so you're actually bit-shifting left 4 bits (the leading 4 zeroes of the short int won't affect the result or the OR-ing). So not quite a nibble unless you mentally ignore the left 4 bits of each uint8_t of the array? Trying to get my head around whether the 32-bit architecture of the ESP32 is relevant here? I feel I'm missing something.

In principle I sort of get this, but I do this the exact opposite way by creating a two-byte integer and bit shifting the values into the bass LSB/treble MSB and then supplying the entire 16-bits for the register.

I really need to read that code more closely now that I understand that it's an array but as I'm moving home this week (yay!) time is short.

Thanks for all the replies.

A nibble is not a datatype in C OR c++. So a byte is the datatype closest to a nibble. And since we want an array of 4 nibbles, an array of 4 bytes is the best option.

Sorry for being so uneducated on this topic, but I wanted to know the simplest way to adjust bass on the VS1053.

If I want to have the bass boosted by 10db in the code with no UI to adjust it can I write something similar to setTone(10) for example?

There is no simple way, but maybe this helps:
You can call setTone() with a pointer to an array of 4 bytes. In fact it is an array of 4 nibbles, because only the 4 lowest bits of every byte are used. The 4 nibbles represent HA, HF, LA and LF respectively. The values in HA, HF, LA and LF have the following meaning:

#  variable value meaning
-  -------- ----- ---------------------
0  HA           0 Off
                1  +1.5 dB gain for treble
                2  +3.0 dB gain for treble
                3  +4.5 dB gain for treble
                4  +6.0 dB gain for treble
                5  +7.5 dB gain for treble
                6  +9.0 dB gain for treble
                7 +10.5 dB gain for treble
                8 -12.0 dB gain for treble
                9 -10.5 dB gain for treble
               10  -9.0 dB gain for treble
               11  -7.5 dB gain for treble
               12  -6.0 dB gain for treble
               13  -4.5 dB gain for treble
               14  -3.0 dB gain for treble
               15  -1.5 dB gain for treble
1  HF           1  1 kHz cutoff for treble
                2  2 kHz cutoff for treble
                3  3 kHz cutoff for treble
                4  4 kHz cutoff for treble
                5  5 kHz cutoff for treble
                6  6 kHz cutoff for treble
                7  7 kHz cutoff for treble
                8  8 kHz cutoff for treble
                9  9 kHz cutoff for treble
               10 10 kHz cutoff for treble
               11 11 kHz cutoff for treble
               12 12 kHz cutoff for treble
               13 13 kHz cutoff for treble
               14 14 kHz cutoff for treble
               15 15 kHz cutoff for treble
2  LA           0 Off
                1  +1 dB gain for bass
                2  +2 dB gain for bass
                3  +3 dB gain for bass
                4  +4 dB gain for bass
                5  +5 dB gain for bass
                6  +6 dB gain for bass
                7  +7 dB gain for bass
                8  +8 dB gain for bass
                9  +9 dB gain for bass
               10 +10 dB gain for bass
               11 +11 dB gain for bass
               12 +12 dB gain for bass
               13 +13 dB gain for bass
               14 +14 dB gain for bass
               15 +15 dB gain for bass
3  LF           2  10 Hz cutoff for bass
                3  20 Hz cutoff for bass
                4  30 Hz cutoff for bass
                5  40 Hz cutoff for bass
                6  50 Hz cutoff for bass
                7  60 Hz cutoff for bass
                8  70 Hz cutoff for bass
                9  80 Hz cutoff for bass
               10  90 Hz cutoff for bass
               11 100 Hz cutoff for bass
               12 110 Hz cutoff for bass
               13 120 Hz cutoff for bass
               14 130 Hz cutoff for bass
               15 140 Hz cutoff for bass

Example:

uint8_t tone[4] = { 0, 0, 5, 5 } ;
setTone ( tone ) ;

Will give 5 dB gain for frequencies below 40 Hz.

That helps a lot! It compiles now, but it seems like the tone setting is changing back to the default settings instantly.
At first I adjusted the tone within setup and I couldn't hear a difference. So I setup a switch to change tone values between default settings and a 14db gain for frequencies below 70hz.

What I noticed is that it seems to make a spike in volume right when I press the button but then goes back to the default tone settings. It is very quick, almost like a pop, so I assume the tone setting is being changed but is only remaining for one cycle in the loop and then going back to default tone settings.

This is not my actual code that I'm using in my project, but for the sake of explaining the problem I made a simplified example.
Audio plays just fine, but I still can't get it to keep the tone settings.

At first I tried this and there was no noticeable difference.

uint8_t rtoneDefault[4] = { 0, 0, 0, 0 } ; 
uint8_t rtoneCustom[4] = { 0, 0, 14, 8 } ;

void setup () {
    pinMode(eqButton, INPUT_PULLUP);
    player.begin();
    player.switchToMp3Mode(); //
    player.setTone(rtoneCustom); // 
    player.setVolume(volume); // (uint8_t vol)
    }
    
void loop() {
    if (client.available() > 0)
      {
        uint8_t bytesread = client.read(mp3buff, 32);
        player.playChunk(mp3buff, bytesread); 
      }
}
     

Then here is my simplified example with using a button

uint8_t rtoneDefault[4] = { 0, 0, 0, 0 } ; 
uint8_t rtoneCustom[4] = { 0, 0, 14, 8 } ;
const int eqButton = 15; // external button

void setup () {
    pinMode(eqButton, INPUT_PULLUP);
    player.begin();
    player.switchToMp3Mode(); //
    player.setTone(rtoneDefault); // 
    player.setVolume(volume); // (uint8_t vol)
    }
    
void loop() {
    if (digitalRead(eqButton) == LOW){ // button pressed
          player.setTone(rtoneCustom);
          Serial.println("EQ Bass Boosted!");
        }else{
          player.setTone(rtoneDefault); 
          Serial.println("EQ default");
        }
    if (client.available() > 0)
      {
        uint8_t bytesread = client.read(mp3buff, 32);
        player.playChunk(mp3buff, bytesread); 
      }
}
     

In the loop, the default setting is restored whenever the button is not pushed.....

Yes I realized that, but the point is that it seems to go back to the default setting while the button is pushed too. Only for the first split second do I hear a jump in volume. Again, this is not the real code but just trying to explain what I'm doing and have tried.

So for example if I run code similar to the following, it will make a very short sound in which the volume gets louder for a second and still goes back to the default setting even though there seems to be nothing in the code telling it to return to the default setting. This code should have it start with the default setting and switch to the custom setting when the button is pressed. From there it should not be able to go back to the default settings, but it sounds as if it is going back to the default settings anyway.

uint8_t rtoneDefault[4] = { 0, 0, 0, 0 } ; 
uint8_t rtoneCustom[4] = { 0, 0, 14, 8 } ;
const int eqButton = 15; // external button

void setup () {
    pinMode(eqButton, INPUT_PULLUP);
    player.begin();
    player.switchToMp3Mode(); //
    player.setTone(rtoneDefault); // 
    player.setVolume(volume); // (uint8_t vol)
    }
    
void loop() {
    if (digitalRead(eqButton) == LOW){ // button pressed
          player.setTone(rtoneCustom);
          Serial.println("EQ Bass Boosted!");
        }
    if (client.available() > 0)
      {
        uint8_t bytesread = client.read(mp3buff, 32);
        player.playChunk(mp3buff, bytesread); 
      }
}

Look for calls to setVolume() and setTone(). Comment them out to see (hear in this case) to find the unwanted.

So I've figured it out!

My speakers simply aren't able to create any perceptible difference at that bass range! I realized this when I tried boosting treble instead of bass.

All I actually needed was the table you provided earlier and the following example

uint8_t tone[4] = { 0, 0, 5, 5 } ; // 
setTone ( tone ) ;

Thank you for your time and pardon my stupidity!

Should I delete my last comments for the sake of cleaning up this thread?

I think no need to delete anything. Someone else might go the same path and find further comments useful. Those threads are a source of knowledge and experience share. I'm wondering whether not go through the closed threads and extract some useful hints. Creating a kind of "FAQ" section in README and links to particular posts from discussions. Thank you @Edzelf for your insights and hints.