Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::Sound, Sf::Buffer bugs and troubles  (Read 3995 times)

0 Members and 1 Guest are viewing this topic.

pixy

  • Newbie
  • *
  • Posts: 4
    • View Profile
sf::Sound, Sf::Buffer bugs and troubles
« on: February 18, 2018, 08:15:58 pm »
Hi everybody, im new on the forum and with the SFML so maybe solution of my problem will be very easy for you. I hope so :)
Im working on application for my own use that will be used to play guitar songs.


My problem:

(inside my class "note")
        //SEPARATED BUFFERS
        sf::SoundBuffer Buffer_clean[STRINGS];                 
        sf::SoundBuffer Buffer_lead[STRINGS];
        sf::SoundBuffer Buffer_pm[STRINGS];

        //SEPARATED SOUNDS
        sf::Sound Sound_clean[STRINGS][RANGEOFSTRINGS];
        sf::Sound Sound_lead[STRINGS][RANGEOFSTRINGS];
        sf::Sound Sound_pm[STRINGS][RANGEOFSTRINGS];

float Pitch_Table[RANGEOFSTRINGS + 1] = { 1.0f, 1.06f, 1.123f, 1.19f, 1.264f, 1.336f, 1.415f, 1.5f, 1.59f, 1.69f, 1.79f, 1.89f, 2.0f, 2.13f, 2.25f, 2.39f, 2.53f, 2.68f, 2.84f, 3.0f, 3.174f, 3.355f, 3.56f, 3.77f, 4.0f, 4.1f };               //TABLE OF PITCHES FOR EACH FRET

 

Where
STRINGS is defined 6
RANGEOFSTRINGS is defined 25


All i want to do is load recorded sounds to buffers, then set every sound with right buffer and pitch that is stored in table.
Here is main part of my "load" function:


(type - determinates what do i load. If 0 then clean, 1 - lead, 2 - palm mute. Function must be launched 3 times to load everything)

//LOAD SOUNDS--------------------------------------------
        string namepatch;
       
        if (type == 0)
                namepatch = "Properties/Sounds/CX.wav";
        else if (type == 1)
                namepatch = "Properties/Sounds/DX.wav";
        else if (type == 2)
                namepatch = "Properties/Sounds/PX.wav";

        for (int i = 0; i < STRINGS; i++) {
               
                //CHANGE THE PATCH
                namepatch.replace(19, 1, to_string(i)); //CHANGES ONLY X FROM NAMEPATCH                                

                //CLEAN---------------
                if (type == 0) {
                        if (this->Buffer_clean[i].loadFromFile(namepatch) == false)    
                                cout << "LOAD ERROR: " << namepatch << endl;

                        //PARAMS
                        for (int j = 0; j < RANGEOFSTRINGS; j++) {
                                this->Sound_clean[i][j].setBuffer(this->Buffer_clean[i]);               //BUFFER
                                this->Sound_clean[i][j].setPitch(this->Pitch_Table[j]);                 //PITCH
                        }
                }

                //LEAD--------------------
                if (type == 1) {
                        if (this->Buffer_lead[i].loadFromFile(namepatch) == false)
                                cout << "LOAD ERROR: " << namepatch << endl;

                        //PARAMS
                        for (int j = 0; j < RANGEOFSTRINGS; j++) {
                                this->Sound_lead[i][j].setBuffer(this->Buffer_lead[i]);         //BUFFER
                                this->Sound_lead[i][j].setPitch(this->Pitch_Table[j]);          //PITCH
                        }
                }

                //PM-----------------------
                if (type == 2) {
                        if (this->Buffer_pm[i].loadFromFile(namepatch) == false)
                                cout << "LOAD ERROR: " << namepatch << endl;

                        //PARAMS
                        for (int j = 0; j < RANGEOFSTRINGS; j++) {
                                this->Sound_pm[i][j].setBuffer(this->Buffer_pm[i]);             //BUFFER
                                this->Sound_pm[i][j].setPitch(this->Pitch_Table[j]);                    //PITCH
                        }
                }
        }


 

What is result and this bug ?
While im trying to play sounds for example clean like:

(in class note function)
this->Sound_clean[0][10].play()

Most of table works right but some random elements of table has completely randomized pitch values and buffers.

Sometimes when playing clean single sound has wrong pitch or even plays sound from for example Buffer_lead.



How do i "fixed" that?

(in "play" function of class "note")

//KEYBOARD CLEAN-------------------------
                if (type == 0) {

                        //PITCH CONTROL --------------------
                        if (this->Sound_clean[string][fret].getPitch() != this->Pitch_Table[fret]) {
                                this->Sound_clean[string][fret].setPitch(this->Pitch_Table[fret]);
                                cout << "something were wrong" << endl;
                        }
                        //END OF PITCH CONTROL -----------
                       
                        this->Sound_clean[string][fret].setBuffer(this->Buffer_clean[string]);
                        this->Sound_clean[string][fret].play();
                }
 

In "play" function before every use of sound i created checking the pitch and set the buffer once again.

How it works now ?


Clean_sound  (table) works fine for whole table
Lead_sound (table) works fine almost everywhere. Some single table positions do not play anything
Pm_sount (table) works only in some positions. Most of them dont play anything


Im trying to solve this problem since some days and many times i reorganized whole code that works with sound. It didnt help so i decided to ask more experienced people than me :)

If i delete code that changes buffer and pitch before use of note, some positions plays completely random buffers and pitches, some do nothing.

Thank You in Advance :)
« Last Edit: February 19, 2018, 06:59:30 pm by pixy »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: sf::Sound, Sf::Buffer bugs and troubles
« Reply #1 on: February 18, 2018, 09:37:39 pm »
And by "random" you mean what exactly?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

pixy

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: sf::Sound, Sf::Buffer bugs and troubles
« Reply #2 on: February 18, 2018, 11:51:55 pm »
The pitches are changing for one of the values from PitchTable. Everytime it happen the changed value is one from the table.
I checked every array in program and i didnt miss the index range in any of them. Also the only one place in code where i modify the pitch value is in Load function (except restart before using). So it seems so magical for me :)

But for me its bigger mystery why and how do the sounds changes their buffers while program is working ... :/

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: sf::Sound, Sf::Buffer bugs and troubles
« Reply #3 on: February 19, 2018, 12:47:35 am »
You need to be more specific with what is changing when and how. Also use a debugger to see what's going on.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

pixy

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: sf::Sound, Sf::Buffer bugs and troubles
« Reply #4 on: February 19, 2018, 06:46:08 pm »
Okay, once again i remaked my code:

Note class:
class Note {            //SOUNDS COUNTAINER AND LAUNCHER
public:
        sf::SoundBuffer Metronome_buffer;               //BUFFER FOR METRONOME SOUND
        sf::Sound Metronome_sound;                              //SOUND OF METRONOME

        //SEPARATED BUFFERS
        sf::SoundBuffer Buffer_clean[STRINGS];                 
        sf::SoundBuffer Buffer_lead[STRINGS];
        sf::SoundBuffer Buffer_pm[STRINGS];

        //SEPARATED SOUNDS
        sf::Sound Sound_clean[STRINGS][RANGEOFSTRINGS];
        sf::Sound Sound_lead[STRINGS][RANGEOFSTRINGS];
        sf::Sound Sound_pm[STRINGS][RANGEOFSTRINGS];

        float Pitch_Table[RANGEOFSTRINGS + 1] = { 1.0f, 1.06f, 1.123f, 1.19f, 1.264f, 1.336f, 1.415f, 1.5f, 1.59f, 1.69f, 1.79f, 1.89f, 2.0f,
                2.13f, 2.25f, 2.39f, 2.53f, 2.68f, 2.84f, 3.0f, 3.174f, 3.355f, 3.56f, 3.77f, 4.0f, 4.1f };             //TABLE OF PITCHES FOR EACH FRET

        Note();
        void play(short type, struct Tab::Fret_cutaway *fr_cut = NULL, short string = 0, short fret = 0);       //PLAY - TYPES: 0\1\2 -C\L\P || 10 FRETCUT
        void load(short type, sf::RenderWindow *window, class System *system);  //SHITDOESNTWORK

        void load_clean();
        void load_lead();
        void load_pm();
};

 

Now i have three separated functions for load each kind of sounds, and i made them as simply as it was possible

void Note::load_clean() {

        //LOAD SOUND    || 0- C | 1- G | 2- C | 5- D
        this->Buffer_clean[0].loadFromFile("Properties/Sounds/C0.wav");        
        this->Buffer_clean[1].loadFromFile("Properties/Sounds/C1.wav");
        this->Buffer_clean[2].loadFromFile("Properties/Sounds/C2.wav");
        this->Buffer_clean[3].loadFromFile("Properties/Sounds/C3.wav");
        this->Buffer_clean[4].loadFromFile("Properties/Sounds/C4.wav");
        this->Buffer_clean[5].loadFromFile("Properties/Sounds/C5.wav");

        //PARAMS
        for (int j = 0; j < RANGEOFSTRINGS; j++) {
                this->Sound_clean[0][j].setBuffer(this->Buffer_clean[0]);
                this->Sound_clean[0][j].setPitch(this->Pitch_Table[j]);

                this->Sound_clean[1][j].setBuffer(this->Buffer_clean[1]);
                this->Sound_clean[1][j].setPitch(this->Pitch_Table[j]);

                this->Sound_clean[2][j].setBuffer(this->Buffer_clean[2]);
                this->Sound_clean[2][j].setPitch(this->Pitch_Table[j]);

                this->Sound_clean[3][j].setBuffer(this->Buffer_clean[3]);
                this->Sound_clean[3][j].setPitch(this->Pitch_Table[j]);

                this->Sound_clean[4][j].setBuffer(this->Buffer_clean[4]);
                this->Sound_clean[4][j].setPitch(this->Pitch_Table[j]);

                this->Sound_clean[5][j].setBuffer(this->Buffer_clean[5]);
                this->Sound_clean[5][j].setPitch(this->Pitch_Table[j]);

                //METRONOME
                this->Metronome_buffer.loadFromFile("Properties/Sounds/_M1.wav");
                this->Metronome_sound.setBuffer(this->Metronome_buffer);
        }
}
 

void Note::load_pm() {

        //LOAD SOUND    || 0- C | 1- G | 2- C | 5- D
        this->Buffer_pm[0].loadFromFile("Properties/Sounds/P0.wav");           
        this->Buffer_pm[1].loadFromFile("Properties/Sounds/P1.wav");
        this->Buffer_pm[2].loadFromFile("Properties/Sounds/P2.wav");
        this->Buffer_pm[3].loadFromFile("Properties/Sounds/P3.wav");
        this->Buffer_pm[4].loadFromFile("Properties/Sounds/P4.wav");
        this->Buffer_pm[5].loadFromFile("Properties/Sounds/P5.wav");

        //PARAMS
        for (int j = 0; j < RANGEOFSTRINGS; j++) {
                this->Sound_pm[0][j].setBuffer(this->Buffer_pm[0]);
                this->Sound_pm[0][j].setPitch(this->Pitch_Table[j]);

                this->Sound_pm[1][j].setBuffer(this->Buffer_pm[1]);
                this->Sound_pm[1][j].setPitch(this->Pitch_Table[j]);

                this->Sound_pm[2][j].setBuffer(this->Buffer_pm[2]);
                this->Sound_pm[2][j].setPitch(this->Pitch_Table[j]);

                this->Sound_pm[3][j].setBuffer(this->Buffer_pm[3]);
                this->Sound_pm[3][j].setPitch(this->Pitch_Table[j]);

                this->Sound_pm[4][j].setBuffer(this->Buffer_pm[4]);
                this->Sound_pm[4][j].setPitch(this->Pitch_Table[j]);

                this->Sound_pm[5][j].setBuffer(this->Buffer_pm[5]);
                this->Sound_pm[5][j].setPitch(this->Pitch_Table[j]);
        }
}

 


And what happens now:

In case i loaded only clean in main():

-every sound works right and have right pitch. Its great isnt it ? :)

In calse i loaded only pm (load_pm() ) in main():

-positions of sound_pm(6)(25)
(0)(8 )
(4)(19)
(4)(8 )
Plays something ....
(i didnt even check pitch becouse it was actually useless)

-rest of table
Sound_pm(6)(25) doesnt play anything


In case i loaded clean and then pm in main():

-Clean works fine (pitch and buffer - type of sound) except:
sound_clean(6)(25) positions:
(1)(18 )
(0)(11)
(0)(3)
On this position buffer is pm. What to say ... :|


-Pm doesnt play any sound except positions

(5)(11)  = (2)(14) = (2)(4)
This three plays exactly same sound and pitch, buffer is right

(2)(11)
(1)(3)
(1)(2)
(1)(0)
(5)(12)
(5)(11)
This positions plays something. I didnt check pitch. The rest of table is dead


My play function looks like:

void Note::play(short type, struct Tab::Fret_cutaway *fr_cut, short string, short fret) {

        //TYPE 0/1/2 - PLAYING ON KEYBOARD- Clean/Lead/Pm
        if (type == 0 || type == 1 || type == 2) {

                //KEYBOARD CLEAN-------------------------
                if (type == 0) {
                        this->Sound_clean[string][fret].play();
                }

                //KEYBOARD LEAD-------------------------
                if (type == 1) {
                        this->Sound_lead[string][fret].play();
                }

                //KEYBOARD PALM MUTE-------------------------
                if (type == 2) {
                        this->Sound_pm[string][fret].play();
                }
        }
}
 

If i run program more times, sometimes different positions works or not.
I completely dont understand what is goin on :)

PS i had to use (2) - brackets instead of [2] becouse there was some problems with right displaying it on forum :)
« Last Edit: February 19, 2018, 06:57:53 pm by pixy »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: sf::Sound, Sf::Buffer bugs and troubles
« Reply #5 on: February 20, 2018, 01:21:04 am »
Oh I see. You have 6 sound buffers (one for each string) and 26 sounds for each string (one for each fret), each being set to the same sound buffer as all of the other sounds on that string. That's 6 x 26 = 156 sounds. This seems excessive considering that you will only ever play a maximum of 6 at a time.

Think of a sound as a "voice". That is, one of the things that plays. Then, think of the pitches as something that the voice changes to match. If you have one sound per string, you can simply "play" the sound representing that string whenever that string is played.

So, have 6 sound buffers and 6 sounds that match them. Then, when playing a note, set the pitch of the sound to match the fret's pitch whenever the sound is played. This has an added advantage too; if you just change the pitch without (re)starting the sound, you get an instant pitch shift and this may help with unpicked/unplucked sounds (hammer-ons, pull-offs and slides, for example).

Another thing to note is that calculating the pitches can be done in real-time when needed rather than using the table.
sound.setPitch(static_cast<float>(std::pow(2, static_cast<double>(fret) / 12.0)));
should do it ;)

fret is the fret number, starting from zero (open).



This might not still fix the problem but I just wanted you to see another approach :)

Try re-ordering the play styles to see if that affects anything.
« Last Edit: February 20, 2018, 01:28:38 am by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: sf::Sound, Sf::Buffer bugs and troubles
« Reply #6 on: February 20, 2018, 07:25:16 am »
There's a limit on how many sf::Sound objects you can have, but usually you can have up to 256, maybe your OS doesn't allow as many?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

pixy

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: sf::Sound, Sf::Buffer bugs and troubles
« Reply #7 on: February 20, 2018, 05:00:16 pm »
Finally i solved it and i understand what was wrong :)
I thought there is limit on buffers not for sounds.

I loaded only 19 buffers for program and i wanted to create table that would store every kind of every sound of every fret ready to play.
3 tables * 6 strings * 25 frets = 450

so i crossed the sounds limit a bit :)

Now i have 19 buffers and 6 sf::sounds for each guitar that represent each string of it, and set the right values before i want to play it.

eXpl0it3r and Hapax, thank You very much for help. It was one of the most magical problem i have ever had with programming :)

 

anything