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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - DojoMike

Pages: [1]
1
Audio / Static/popping noises on Raspberry Pi 3
« on: October 25, 2018, 05:11:59 am »
Hey guys, what's up? :)

I've been messing with the Raspberry Pi a lot lately, and I found it supports SFML, so I've been having a lot of fun with that (lol).  Anyway, I notice when I use the audio API, there is a sort of static / popping type noise in the background when sound is playing.

Here are some details on my system: it's a Raspberry Pi 3, purchased in March/April of this year (so it's running a relatively new version of Raspbian, though I'm not sure how to get an exact version number).  I'm also using a USB headset, and I haven't connected an HDMI monitor (getting sound to play on HDMI was another rabbit-hole of obscure config files and random forum posts, lol - I did eventually crack it, so chances are there's some related setting in some equally obscure config file, but for now that should not be a factor since I'm not using HDMI at the moment).
And here's an example of my code:
sf::SoundBuffer buff;
buff.loadFromFile("/home/my_username/Desktop/test.wav");
sf::Sound test(buff);

// Then in my event loop, on key press
test.play();
What's interesting is if I just do
system("play /home/my_username/Desktop/test.wav");
the sound plays with no popping/staticky sounds.  So I know it's not my headset or the Pi.  Maybe it does ".ogg" or some other format better?  idk... anyway, I've Googled myself stupid and created several useless config files, and nothing seems to work.  Has anyone else hear dealt with this?  Thanks in advance.

2
Hey guys,

I've been on a roll with SFML, creating a simple scrolling shooter, but so far the only way I've been able to keep references to graphics available long enough to be used is by storing them in fixed-size arrays or class properties for every instance.  Initially I thought it was possible to use vectors, maps, etc. but quickly found out that the way those classes work internally is to make copies, so anything I create is destroyed the second it goes out of scope.  Sounds don't play, and graphics get the white square bug, if I use anything out of the STL.

But then again, I'm thinking that might not actually be the case.  I've only been doing C++ for about 6 months, and it's the first language I've learned where memory management is an issue.  So odds are that there's some other way I just haven't learned yet.  Take for example these 2 versions of the same class:

// This is the version that works, using a class property for every instance
#ifndef SOUND_PLAYER_H
#define SOUND_PLAYER_H
#include <map>
#include <SFML/Audio.hpp>

class SoundPlayer
{
public:
    static SoundPlayer * Get();
    void PlayerLaser();
private:
    static SoundPlayer * Instance;
    SoundPlayer();
    sf::SoundBuffer player_laser, enemy1_explode;
    sf::Sound sound;
};

SoundPlayer * SoundPlayer::Instance = NULL;

SoundPlayer * SoundPlayer::Get()
{
    if (Instance == NULL)
        Instance = new SoundPlayer();
    return Instance;
}
SoundPlayer::SoundPlayer()
{
    if (!player_laser.loadFromFile("bin\\debug\\sounds\\player_laser.wav"))
        throw "Error loading the player laser sound";
    if (!enemy1_explode.loadFromFile("bin\\debug\\sounds\\enemy1_explode.wav"))
        throw "Error loading the enemy 1 explosion sound";
}
void SoundPlayer::PlayerLaser()
{
    sound.setBuffer(player_laser);
    sound.play();
}

#endif
 
// And this is the one that doesn't work, using maps
// I've tried maps of objects, and maps of pointers (which is what's shown here)
// and both don't seem to have what it takes to work in SFML - but they've been around for decades so it's obviously just me being a noob :)
#ifndef SOUND_PLAYER_H
#define SOUND_PLAYER_H
#include <map>
#include <SFML/Audio.hpp>

class SoundPlayer
{
public:
    static SoundPlayer * Get();
    void PlayerLaser();
private:
    static SoundPlayer * Instance;
    SoundPlayer();
    std::map<std::string, sf::SoundBuffer*> buffers;
    std::map<std::string, sf::Sound*> sounds;
};

SoundPlayer * SoundPlayer::Instance = NULL;

SoundPlayer * SoundPlayer::Get()
{
    if (Instance == NULL)
        Instance = new SoundPlayer();
    return Instance;
}
SoundPlayer::SoundPlayer()
{
    sf::SoundBuffer b1;
    if (!b1.loadFromFile("bin\\debug\\sounds\\player_laser.wav"))
        throw "Error loading the player laser sound";
    buffers.insert(std::make_pair("player_laser", &b1));

    sf::Sound s1;
    s1.setBuffer(b1);
    sounds.insert(std::make_pair("player_laser", &s1));
}
void SoundPlayer::PlayerLaser()
{
    sounds["player_laser"]->play();
}

#endif
 

Both compile fine, and both "look" like they should work, but because of however these STL classes work "under the hood" they just don't seem to work well with SFML, making the idea little more than wishful thinking.  From what I've read (including another question on this forum) the way they work is to make copies of the objects, and I haven't been able to figure out a way around that obstacle yet.  I've tried vectors/maps of objects, and also pointers (shown above), and none of it seems to work... so it's gotta be me just being a noob (lol).

But it's no biggy if it actually can't be done.  Fixed arrays and class properties per object are working reliably, and I've got a pretty cool little game going using them as my go-to for everything SFML-related.  Heck, even the NES could only have up to 64 objects on the screen at once, so my player object only being able to use up to 5 laser instances or there only being up to 16 enemies is not an issue.  But there's a reason the STL was created, problems with the fixed-size way of doing things that it was meant to solve, and I bet there's a better way to use it that I just haven't figured out yet.

So how do you guys handle textures, sprites, sound buffers, sounds, and other stuff like that?  I'm sure I'm not the first guy who's ever had this question (and since the white square issue is brought up in the documentation it must be super-common) but so far I haven't managed to fish up any answers on Google, so I figured I'd ask the pros. :)

Thanks in advance. :)

3
Audio / Playing audio
« on: June 21, 2017, 04:19:53 am »
Hey guys, what's up,

So I've been following the tutorials on playing sounds, and I've run into a kind of weird issue that doesn't seem to be mentioned anywhere: The sound doesn't play, and when the program ends I get this error: "AL lib: (EE) alc_cleanup: 1 device not closed".  So after a bit of Googlefishing, I found a few sites where people have asked about it, and even one guy who filed a bug about it - but since I'm new to SFML I'm assuming it's something I've done wrong. :D

So here's my code:


#ifndef SOUND_PLAYER_H
#define SOUND_PLAYER_H
#include <map>
#include <SFML/Audio.hpp>

class SoundPlayer
{
public:
    static SoundPlayer * Get();
    void PlayerLaser();
private:
    static SoundPlayer * Instance;
    SoundPlayer();
    sf::SoundBuffer player_laser;
};

SoundPlayer * SoundPlayer::Instance = NULL;

SoundPlayer * SoundPlayer::Get()
{
    if (Instance == NULL)
        Instance = new SoundPlayer();
    return Instance;
}
SoundPlayer::SoundPlayer()
{
    if (!player_laser.loadFromFile("bin\\debug\\sounds\\player_laser.wav"))
        throw "Error loading the player laser sound";
}
void SoundPlayer::PlayerLaser()
{
    sf::Sound sound;
    sound.setBuffer(player_laser);
    sound.play();
}

#endif

// And here is how it's used:
SoundPlayer * sp = SoundPlayer::Get();
sp->PlayerLaser();
The SoundPlayer class is mostly an attempt to keep the sound-related objects in scope (since stuff seems to go out of scope and get destroyed super-easy/almost instantly with SFML), but originally it was the constructor and PlayerLaser methods as one function.  I figured that was not efficient (cuz it would have to re-load-from-file every time the sound is played), but I figured I'd share it anyway.

But this error seems to suggest that something needs closing?  I didn't see anything in the tutorial about that (apart from if you have too many sounds, but I can't get it to play just one).  I haven't managed to find any clear answer on Google or in the API docs, but then again I only spent like half an hour fighting with it.  Has anyone here dealt with this cryptic error before?  No big deal (I can always use IrrKlang for sounds if I can't get past it) but I'm guessing it's another newbie mistake on my part and a common pitfall everybody fights with at some point.

Also, if there is a better way to make references to SFML objects permanent, or at least exist a little longer, I'm all ears.  I recently had a similar struggle with textures, and learned the hard way that storing them in a vector was a dumb idea.  I know others have found or built workarounds, but if it's basic C++ stuff it really is something I should learn.  I know what a pointer is, but I've never had as many issues with pointers being destroyed as I have with SFML; but I'm sure SFML isn't the only framework to auto-destroy pointers, so I "better figger it out fast" tyvm

4
Graphics / Trying to solve the white square riddle
« on: June 20, 2017, 04:44:23 am »
Hey, what's up,

I've recently started with SFML, and I've run into the infamous "white square problem".  The documentation explains the problem, but doesn't give any hints at solutions.  I get that under the hood, it uses a pointer to a texture, but that doesn't explain what "breaks" this pointer or what can be done to keep it "intact" (lol).

So I'm writing this simple 2D shooter, and I have a player class and a laser class.  The player class has a vector of lasers, and draws them all in its "update" method.  The objects are created and added to the vector, but this is where I'm hitting the white square bug.  Here's some code:

// Player class

#include <vector>
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include "PlayerLaser.h"

class Player
{
public:

    /**
     * Constructor - initialize instance variables
     */

    Player();

    /**
     * Updates the player's position based on keyboard input
     * @param[in] Pointer to the keyboard event
     */

    void HandleEvents(sf::Event * event);

    /**
     * Update and draw the object to the screen
     * @param[in] Pointer to the window to draw to
     * @param[in] The player's speed
     */

    void Update(sf::RenderWindow * window, float speed);
private:
    sf::Texture texture;
    sf::Sprite sprite;
    bool MovingLeft, MovingRight, MovingUp, MovingDown;
    int index;
    std::vector<PlayerLaser> Lasers;
};

Player::Player()
{
    // Set up the sprite
    if (!texture.loadFromFile("bin\\debug\\graphics\\player.png"))
        throw "Failed to load player texture.";
    sprite.setTexture(texture);
    sprite.setTextureRect(sf::IntRect(0, 0, 64, 32));
    sprite.setPosition(320, 320);

    // Init other variables
    MovingUp = false;
    MovingDown = false;
    MovingLeft = false;
    MovingRight = false;
    index = 0;
}
void Player::HandleEvents(sf::Event * event)
{
    if (event->type == sf::Event::KeyPressed)
    {
        if (event->key.code == sf::Keyboard::Left)
            MovingLeft = true;
        else if (event->key.code == sf::Keyboard::Right)
            MovingRight = true;
        else if (event->key.code == sf::Keyboard::Up)
            MovingUp = true;
        else if (event->key.code == sf::Keyboard::Down)
            MovingDown = true;
        else if (event->key.code == sf::Keyboard::Space)
        {
            PlayerLaser pl(sprite.getPosition().x, sprite.getPosition().y);
            Lasers.push_back(pl);
        }
    }
    else if (event->type == sf::Event::KeyReleased)
    {
        if (event->key.code == sf::Keyboard::Left)
            MovingLeft = false;
        else if (event->key.code == sf::Keyboard::Right)
            MovingRight = false;
        else if (event->key.code == sf::Keyboard::Up)
            MovingUp = false;
        else if (event->key.code == sf::Keyboard::Down)
            MovingDown = false;
    }
}
void Player::Update(sf::RenderWindow * window, float speed)
{
    // Update the player's animation
    index++;
    if (index == 1000)
        sprite.setTextureRect(sf::IntRect(0, 32, 64, 32));
    if (index == 2000)
    {
        sprite.setTextureRect(sf::IntRect(0, 0, 64, 32));
        index = 0;
    }

    // Update the player's position
    if (MovingLeft && sprite.getPosition().x > 0)
        sprite.move(speed * -1, 0);
    else if (MovingRight && sprite.getPosition().x < 640 - 64)
        sprite.move(speed, 0);
    if (MovingUp && sprite.getPosition().y > 0)
        sprite.move(0, speed * -1);
    if (MovingDown && sprite.getPosition().y < 480 - 32)
        sprite.move(0, speed);

    // Draw the player
    window->draw(sprite);

    // Draw the lasers
    for (PlayerLaser pl : Lasers)
        pl.Update(window, speed + (speed / 2));
}

// Main
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include "Background.h"
#include "Player.h"
#include "PlayerLaser.h"

int main()
{
    // Create the main window
    sf::RenderWindow window(sf::VideoMode(640, 480), "3017");

    // Create the background and player objects
    Background background;
    Player player;

    // Test
    PlayerLaser pl(32, 32);

    /*
    // Create a graphical text to display
    sf::Font font;
    if (!font.loadFromFile("arial.ttf"))
        return EXIT_FAILURE;
    sf::Text text("Hello SFML", font, 50);

    // Load music to play
    sf::Music music;
    if (!music.openFromFile("nice_music.ogg"))
        return EXIT_FAILURE;

    // Play the music
    music.play();
    */


    // Start the game loop
    while (window.isOpen())
    {
        // Process events
        sf::Event event;
        while (window.pollEvent(event))
        {
            // Close window: exit
            if (event.type == sf::Event::Closed)
                window.close();
            else if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
                window.close();
            else
                player.HandleEvents(&event);
        }
        // Clear screen
        window.clear();

        // Draw the background
        background.Update(&window, 0.025);
        player.Update(&window, 0.1);

        // test - no white square for this instance
        pl.Update(&window, 0.2);

        // Update the window
        window.display();
    }
    return EXIT_SUCCESS;
}
 

So the laser object works, if it's created at compile time, before the while loop.  But if it's created by the player object pressing space, it gets whitesquared.  So are objects not allowed to be created at runtime or something?  I suppose if I create every single instance at compile time it'll avoid the problem, but I'd really like to know if there's an actual solution available.  Unfortunately my knowledge of SFML's internals, vector's internals and whatever else the heck could be causing this to even come up with a logical theory; so for now I'm left Googling and guessing. (hair--;) lol

Any clues would be greatly appreciated.

Pages: [1]