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

Author Topic: sf::SoundStream throws std::bad_alloc  (Read 3413 times)

0 Members and 1 Guest are viewing this topic.

Gigotdarnaud

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
sf::SoundStream throws std::bad_alloc
« on: July 27, 2012, 08:38:49 pm »
Hello again,
I got a new issue with my little VOIP system. Now the sf::SoundStream seems to work fine, until it throws a std::bad_alloc exception after some time (it goes from ten seconds to a few minutes).
Trouble is, the memory consumption is stable (+/- 4,7Mo, Qt is quite heavy even without a GUI), so it's not just a memory leak waiting to be fixed. Since sf::SoundStream delete its OpenAL buffers, but only when the recording is stopped, I have to call stop()/play() every once in a while to clear the memory though.

The code:

Player.h
#ifndef PLAYER_H
#define PLAYER_H

#include <QObject>
#include <QQueue>
#include <SFML2/Audio.hpp>

#include <QMetaType>
#include <QVector>

typedef QVector<sf::Int16> IntVector;
Q_DECLARE_METATYPE(IntVector);

#include <QDebug>
#define D() qDebug() << __FILE__ << ";" << __LINE__

class Player : public QObject, public sf::SoundStream
{
    Q_OBJECT
    public:
        Player(size_t sampleRate);

    public slots:
        void queue(const IntVector& frame);

    protected:
        virtual bool onGetData(Chunk& Data);
        virtual void onSeek(sf::Time) {}

    private:

        size_t m_pending;

        QQueue<Chunk> m_buffers;

        sf::Mutex m_mutex;

};

#endif // PLAYER_H
 

Player.cpp
#include "Player.h"

#define MAX_BUFFER 10
#define CLEAR_BUFFER 15 //Has to be > to sf::SoundStream internal buffer count to prevent shuttering. Aims to prevent a huge memory leak.

Player::Player(size_t sampleRate)
{
    m_pending=0;

    initialize(1, sampleRate);
}

bool Player::onGetData(Chunk& Data)
{
    Chunk chu;
    m_mutex.lock();
    if(m_buffers.size() == 0)
    {
        sf::Int16* s =new sf::Int16[1000];
        for(size_t i=0;i<1000;++i)
            s[i]=0;

        chu.sampleCount=1000;
        chu.samples=s;
    }
    else
    {
        chu=m_buffers.dequeue();
    }

    D() << m_pending << m_buffers.size();

    Data=chu;
    ++m_pending;
    m_mutex.unlock();
    return true;
}

void Player::queue(const IntVector& frame)
{
    m_mutex.lock();
    if(m_buffers.size()>=MAX_BUFFER)
    {
        D() << "No buffers available!";
        return;
    }

    if(frame.size() == 0)
        return;

    Chunk chu;
    chu.sampleCount=frame.size();
    sf::Int16* s=new sf::Int16[chu.sampleCount];

    for(size_t i=0;i<chu.sampleCount;++i)
        s[i]=frame[i];

    chu.samples=s;

    m_buffers.enqueue(chu);

    if(m_pending>=CLEAR_BUFFER)
    {
       stop(); // Will clear all the OpenAL buffers as a side effect
       m_pending=0;

       play();
    }
    m_mutex.unlock();
}
 

Debugging with GDB just give my a Segfault and no useful information whatsoever, just that it happens in "rtlsidhashlookup" in ntdll.dll. No exception caught it seems.

I am probably doing something wrong. I uploaded the whole test project (with the SoundRecorder subclass, the main file...) here in case you want to see if it's coming from somewhere else, but I doubt it. I didn't have this problem when the sf::SoundStream subclass wasn't working at all.

Using: SFML 2.0 RC, Qt (core only, unrelated to the issue), Mingw, Windows 7 64bits.

Thanks.

[attachment deleted by admin]

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: sf::SoundStream throws std::bad_alloc
« Reply #1 on: July 27, 2012, 09:24:42 pm »
Debugging with GDB just give my a Segfault and no useful information whatsoever, just that it happens in "rtlsidhashlookup" in ntdll.dll. No exception caught it seems.
That's because you don't know enough on how to use GDB (or don't use a user friendly interface).
With a full backtrack log you'll be able to see how the application came from your code to the rtlsidhashlookup in the ntdll.dll and you get the exact function call what went wrong where.
Next you can set there a breakpoint and slowly step through your application and see if everything is consistante and what the problem could be.

I don't think many, if any will go through your code, trying to understand it and making sure that's thread safe etc. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/