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]