SFML community forums

Help => Audio => Topic started by: FPtje on July 22, 2009, 11:43:01 am

Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 22, 2009, 11:43:01 am
Hi I'm making a piano program(simple console application using sfml to play piano on the computer keyboard).

When I compile it in windows everything is superfast. When I press a button on my keyboard the sound plays instantly.

So yesterday I installed code::blocks on my linux mint gloria 7 installation on my laptop. I had some trouble setting everything up but in the end I got everything to work. The problem is, when I compile it in linux, with gcc compiler and linux settings(no .exe in wine :v:) it's slower!

I press a key on the keyboard, but the sound plays about a second later!

Here is the code:
Code: [Select]
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>

sf::Music Piano[100];

void PlayPiano(float pitch);
int width = sf::VideoMode::GetMode(0).Width;
int height = sf::VideoMode::GetMode(0).Height;

int main()
{
    //I know I shouldnt be doing this, but I dont know of any other way, Im still learning. Could you help me with this too?
    for (int i = 0;i < 100; i++){
        //Piano[i].OpenFromMemory(Piano[0]);
        Piano[i].OpenFromFile("piano.ogg");
    }

    // Create the main window
    sf::RenderWindow App(sf::VideoMode::GetMode(0), "Piano!", sf::Style::Fullscreen);
    // Piano picture
sf::Image pianopic;
pianopic.LoadFromFile("PianoPic.tga");


sf::Sprite PianoSprite;
PianoSprite.SetImage(pianopic);
    PianoSprite.SetPosition(0,0);
    PianoSprite.SetCenter(0, 0);
    PianoSprite.Resize(width, height);

App.Clear(sf::Color(0, 100, 0));
App.Draw(PianoSprite);
    App.Display();

    sf::Event PressKey;
    std::cout << "Start playing the piano!"<<std::endl << "Press escape to quit!" << std::endl;
    // Start main loopv
    bool running = true;
    while (running){
        while(App.GetEvent(PressKey)){
            if (PressKey.Type == sf::Event::KeyPressed) {

              //Toets ingedrukt
                switch(PressKey.Key.Code){
                    //I removed some cases here, I only left the escape and I button, but they are there in the real program.
                    case(sf::Key::I):
                        PlayPiano(1);
                        break;
                    case (sf::Key::Escape):
                        App.Close();
                        running = false;
                        break;
                    default:
                        break;
                }
            }
        }
    }

    return EXIT_SUCCESS;
}

void PlayPiano(float pitch){
//If one piano sound is also playing, then play the next piano sound(this way you can use multiple tones at the same time)
    for (int i = 0; i < 100; i++){
        if (Piano[i].GetStatus() != Piano[i].Playing){
             Piano[i].Stop();
             Piano[i].SetPitch (pitch);
             std::cout << "PLAYING TONE" << std::endl;
             Piano[i].Play();
             break;
        }
    }
}


The windows code is about the same and it runs perfectly.

about the "PLAYING TONE" cout:
WHen I press the I button, I immediately see "PLAYING TONE" in the console screen, but the sound plays a second later!
I made some couts
Title: Piano fast in windows, slow in linux?
Post by: Laurent on July 22, 2009, 11:47:38 am
Which OpenAL package/version is installed on your Linux?
Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 22, 2009, 11:48:34 am
I don't know, how do I find out?

Synaptic says I have 1:1.4.272-2
Title: Piano fast in windows, slow in linux?
Post by: Laurent on July 22, 2009, 12:05:37 pm
Try upgrading to the latest version.
Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 22, 2009, 12:23:45 pm
it IS the latest version:
(http://img512.imageshack.us/img512/7394/screenshotfnv.png) (http://img512.imageshack.us/i/screenshotfnv.png/)
Title: Piano fast in windows, slow in linux?
Post by: Laurent on July 22, 2009, 12:29:58 pm
Maybe you can get it from the official website (look for OpenAL-Soft, not OpenAL) and recompile the actual latest version, which is 1.8.466.

It's going to be hard to know if the problem is in SFML or in an external library :?
Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 22, 2009, 12:43:08 pm
Luckilly I found the the latest version and managed to compile + install it correctly.

however this has no effect! I still have the same problem!
Title: Piano fast in windows, slow in linux?
Post by: Laurent on July 22, 2009, 01:12:38 pm
You can try this: construct your sf::Music instances with a parameter such as 10000, instead of using the default constructor. You'll have to tweak you code, as you can only use the default constructor with static arrays.

Then tell me if the delay is shorter, or if it doesn't make any difference.
Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 22, 2009, 02:05:59 pm
I'm sorry, I'm new to C++, what exactly do I do with my code to do this? I can't seem to figure it out...
Title: Piano fast in windows, slow in linux?
Post by: Laurent on July 22, 2009, 02:15:21 pm
Here is a quick and dirty replacement:
Code: [Select]
...
std::vector<sf::Music*> Piano;
...

int main()
{
    Piano.resize(100, new sf::Music(10000));
    ...

    for (int i = 0; i < 100; ++i)
        delete Piano[i];

    return EXIT_SUCCESS;
}

Try different values instead of 10000, and tell me if it makes the delay shorter or longer.
Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 22, 2009, 02:32:38 pm
This line errors:
Piano.OpenFromFile("piano.ogg");

when I do that it errors:
/home/falco/C++/Projects/linux piano/linux piano/main.cpp|21|error: request for member ‘OpenFromFile’ in ‘Piano.std::vector<_Tp, _Alloc>::operator[] [with _Tp = sf::Music*, _Alloc = std::allocator<sf::Music*>](((unsigned int)i))’, which is of non-class type ‘sf::Music*’|
Title: Piano fast in windows, slow in linux?
Post by: Laurent on July 22, 2009, 02:40:33 pm
The elements of your array are now pointers, so you have to replace every Piano. with Piano->
Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 22, 2009, 02:46:06 pm
Ok it works.

Changing the sample rate has no effect at all. I've tried 96000 44100 and 10000. All the same response time.
Title: Piano fast in windows, slow in linux?
Post by: Laurent on July 22, 2009, 02:59:45 pm
Ok, thanks for your help. I'm really starting to think that this issue has nothing to do with SFML. I'll try your program at home to see whether I can reproduce the problem or not.

PS: it is not the sample rate, it is the size of the internal buffer ;)
Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 22, 2009, 03:16:22 pm
Ok thanks

What I noticed with the vector by the way is that I can't play multiple tones at the same time.

(I guess all the entries in the vector are pointing at the same sf::Music thing)

But that is my problem, I'll try to fix that myself :)
Title: Piano fast in windows, slow in linux?
Post by: Laurent on July 22, 2009, 03:51:23 pm
Correct :)
Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 22, 2009, 03:58:38 pm
By the way, the same program on the windows installation on the same laptop is fast. so Linux is the problem.
Title: Piano fast in windows, slow in linux?
Post by: Nexus on July 22, 2009, 07:59:24 pm
Quote from: "Laurent"
Here is a quick and dirty replacement:
Code: [Select]
...
std::vector<sf::Music*> Piano;
...

int main()
{
    Piano.resize(100, new sf::Music(10000));
    ...

    for (int i = 0; i < 100; ++i)
        delete Piano[i];

    return EXIT_SUCCESS;
}

Be careful, since std::vector::resize() only copies the pointer and not the value behind it. 99 of 100 delete-statements result in undefined behaviour.
Title: Piano fast in windows, slow in linux?
Post by: Laurent on July 22, 2009, 08:42:53 pm
That's what we said previously ;)
Title: Piano fast in windows, slow in linux?
Post by: Nexus on July 22, 2009, 09:58:37 pm
Oh sorry, didn't see that... :oops:
Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 23, 2009, 11:12:03 pm
So does anyone know the cause of this problem?
Title: Piano fast in windows, slow in linux?
Post by: Laurent on July 24, 2009, 03:06:46 pm
Have you tried using sf::Sound instead of sf::Music? sf::Music is really overkill for playing such a small sound, the audio samples are reloaded/streamed from the disk every time you play the music.
Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 24, 2009, 06:02:32 pm
Yes I have, someone helped me with it:
Code: [Select]
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>

sf::Sound Piano[100];
sf::SoundBuffer PianoSound;

void PlayPiano(float pitch);
int width = sf::VideoMode::GetMode(0).Width;
int height = sf::VideoMode::GetMode(0).Height;

int main()
{
    PianoSound.LoadFromFile( "piano.wav");
    //I know I shouldnt be doing this, but I dont know of any other way, Im still learning
    for (int i = 0;i < 100; i++){
        Piano[i].SetBuffer(PianoSound);
    }

    // Create the main window
    sf::RenderWindow App(sf::VideoMode::GetMode(0), "Piano!", sf::Style::Fullscreen);
    // Piano picture
sf::Image pianopic;
pianopic.LoadFromFile("PianoPic.tga");


sf::Sprite PianoSprite;
PianoSprite.SetImage(pianopic);
    PianoSprite.SetPosition(0,0);
    PianoSprite.SetCenter(0, 0);
    PianoSprite.Resize(width, height);

App.Clear(sf::Color(0, 100, 0));
App.Draw(PianoSprite);
    App.Display();

    sf::Event PressKey;
    std::cout << "Start playing the piano!"<<std::endl << "Press escape to quit!" << std::endl;
    // Start main loopv
    bool running = true;
    while (running){
        while(App.GetEvent(PressKey)){
            if (PressKey.Type == sf::Event::KeyPressed) {

              //Toets ingedrukt
                switch(PressKey.Key.Code){
                    // insert cases here.
                    case (sf::Key::Escape):
                        App.Close();
                        running = false;
                        break;
                    default:
                        break;
                }
            }
        }
    }

    return EXIT_SUCCESS;
}

void PlayPiano(float pitch){
    for (int i = 0; i < 100; i++){
        if (Piano[i].GetStatus() != Piano[i].Playing){
             Piano[i].Stop();
             Piano[i].SetPitch (pitch);
             Piano[i].Play();
             break;
        }
    }
}
Title: Piano fast in windows, slow in linux?
Post by: Laurent on July 24, 2009, 07:06:12 pm
And it made no difference at all?
Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 25, 2009, 10:27:25 am
No difference at all.
Title: Piano fast in windows, slow in linux?
Post by: FPtje on July 29, 2009, 08:54:20 pm
There seems to be a delay in this application too:

Code: [Select]

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Audio.hpp>
#include <iomanip>
#include <iostream>


////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////
int main()
{
    int a;
    std::cin >> a;
    std::cout << "TEST" << std::endl;
    // Load a sound buffer from a wav file
    sf::SoundBuffer Buffer;
    if (!Buffer.LoadFromFile("sound.wav"))
        return EXIT_FAILURE;

    // Display sound informations
    std::cout << "sound.wav :" << std::endl;
    std::cout << " " << Buffer.GetDuration()      << " sec"           << std::endl;
    std::cout << " " << Buffer.GetSampleRate()    << " samples / sec" << std::endl;
    std::cout << " " << Buffer.GetChannelsCount() << " channels"      << std::endl;

    // Create a sound instance and play it
    sf::Sound Sound(Buffer);
    Sound.Play();

    // Loop while the sound is playing
    while (Sound.GetStatus() == sf::Sound::Playing)
    {
        // Display the playing position
        std::cout << "\rPlaying... " << std::fixed << std::setprecision(2) << Sound.GetPlayingOffset() << " sec";

        // Leave some CPU time for other threads
        sf::Sleep(0.1f);
    }
    std::cout << std::endl;

    // Wait until the user presses 'enter' key
    std::cout << "Press enter to exit..." << std::endl;
    std::cin.ignore(10000, '\n');

    return EXIT_SUCCESS;
}
Title: Piano fast in windows, slow in linux?
Post by: Laurent on July 29, 2009, 09:20:16 pm
In this case it could be the loading.
Title: Piano fast in windows, slow in linux?
Post by: FPtje on August 01, 2009, 12:51:47 pm
no it isn't
Title: Piano fast in windows, slow in linux?
Post by: drmoth on November 18, 2009, 01:37:27 am
Hi,

I've recently been running the Linux version of the audio subsystem of SFML and it works fine. The latency with the latest version of OpenAL Soft is really very good under Alsa (I have a crappy integrated laptop sound card).

You can tweak the buffer size of the OpenAL Soft driver in a config file in order to improve latency. Download the OpenAL Soft source package and read the contents of the alsoft.conf file.

If you have really large latencies you are possibly running OpenAL under pulseaudio.

Latencies in audio occur under Linux when your audio is not set up properly. There's a good guide to lowering latencies of audio under Linux that comes with the demo of Pianoteq (http://www.pianoteq.com/)