Need some help with QIODevice based buffer class
-
I wrote QIODevice based class, which I use as my audio buffer. It consist from two arrays. When I write data, I write it till buffer reach end then switch to second buffer and continue writing, and so on. When I read data a do the same thing.
@#ifndef AUDIOBUFFER_H
#define AUDIOBUFFER_H#include <QAudioFormat>
#include <QIODevice>
#include <QMutex>
#include <QDebug>
#include <QtEndian>class AudioBuffer : public QIODevice
{
Q_OBJECTpublic:
//----------------------------------------------------------------------------------------------------------------------------------
AudioBuffer(QObject parent = NULL, int bufSize = 1411) : QIODevice(parent)
{
m_bufSize = bufSize10/10000/;m_buffer1 = new const char[m_bufSize];
m_buffer2 = new const char[m_bufSize];m_readCursor = 0;
m_writeCursor = 0;qMemSet((void *)m_buffer1,0,m_bufSize);
qMemSet((void *)m_buffer2,0,m_bufSize);m_readBuffer = m_buffer1;
m_writeBuffer = m_buffer1;m_bytesReady = 0;
/* m_flag = false;*/
}
//----------------------------------------------------------------------------------------------------------------------------------
~AudioBuffer()
{
delete m_buffer1;
delete m_buffer2;
}
//----------------------------------------------------------------------------------------------------------------------------------
void start()
{
if(!isOpen())
open(QIODevice::ReadWrite);
}
//----------------------------------------------------------------------------------------------------------------------------------
void stop()
{
delete m_buffer1;
delete m_buffer2;close();
}
//----------------------------------------------------------------------------------------------------------------------------------
qint64 readData(char * data, qint64 len)
{
// if (m_flag == false){
// if (bytesAvailable()>1000)
// {
// m_flag = true;
// }
// else
// return 0;
// }if(len > m_bytesReady) len = m_bytesReady;
int freeBytes = (m_bufSize - m_readCursor);
if(len <= freeBytes)
{
qMemCopy(data,(void *)m_readBuffer,len);
m_readCursor += len;m_bytesReady -= len;
return len;
}qMemCopy(data,(void *)m_readBuffer,freeBytes);
switchBuffer(m_readBuffer);
int leftBytes = len-freeBytes;
qMemCopy(data,(void *)m_readBuffer,leftBytes);
m_readCursor = leftBytes;
m_bytesReady -= len;
return len;
}
//----------------------------------------------------------------------------------------------------------------------------------
qint64 read(char * data, qint64 len)
{
return readData(data,len);
}
//----------------------------------------------------------------------------------------------------------------------------------
qint64 readBlock ( char * data, quint64 size )
{
return readData(data,size);
}
//----------------------------------------------------------------------------------------------------------------------------------
qint64 writeData(const char *data, qint64 len){int freeBytes = (m_bufSize - m_writeCursor);
if(len <= freeBytes){
qMemCopy((void *)m_writeBuffer,data,len);
m_writeCursor += len;
m_bytesReady += len;
return len;
}qMemCopy((void *)m_writeBuffer,data,freeBytes);
switchBuffer(m_writeBuffer);
int leftBytes = len-freeBytes;
if(leftBytes > m_bufSize) { leftBytes = m_bufSize; m_bytesReady += freeBytes + m_bufSize; } else m_bytesReady += len;
qMemCopy((void *)m_writeBuffer,data,leftBytes);
m_writeCursor = leftBytes;
return len;
}
//----------------------------------------------------------------------------------------------------------------------------------
qint64 write(const char *data, qint64 len){return writeData(data,len);
}
//----------------------------------------------------------------------------------------------------------------------------------
void switchBuffer(const char * buffer)
{
if(buffer == m_buffer1)
buffer = m_buffer2;
else
buffer = m_buffer1;
}
//----------------------------------------------------------------------------------------------------------------------------------
qint64 bytesAvailable() const
{
return m_bytesReady;
}
//----------------------------------------------------------------------------------------------------------------------------------
private:
const char * m_buffer1;
const char * m_buffer2;
const char * m_readBuffer;
const char * m_writeBuffer;
qint64 m_readCursor;
qint64 m_writeCursor;
qint64 m_bufSize;
qint64 m_bytesReady;
/bool m_flag;/};
#endif//AUDIOBUFFER_H@
I use m_readCursor and m_writeCursor to continue reading and writing, m_bytesReady to know How much bytes I can read. But when my m_bufSize is to small, like in this code:
@m_bufSize = bufSize*10;@
I've got a crash in read data right here:
@qMemCopy(data,(void *)m_readBuffer,freeBytes);@
because my freeByetes value is < 0 after one iteration. Waiting for your comments and modifications, optimizations. -
-
I solve it by modifying readData like this:
@qint64 readData(char * data, qint64 len)
{
// if (m_flag == false){
// if (bytesAvailable()>1000)
// {
// m_flag = true;
// }
// else
// return 0;
// }if(len > m_bytesReady) len = m_bytesReady;
int freeBytes = (m_bufSize - m_readCursor);
if(len <= freeBytes)
{
qMemCopy(data,(void *)m_readBuffer,len);
m_readCursor += len;m_bytesReady -= len;
return len;
}qMemCopy(data,(void *)m_readBuffer,freeBytes);
switchBuffer(m_readBuffer);
int leftBytes = len-freeBytes; if(leftBytes > m_bufSize) { m_bytesReady -= freeBytes + m_bufSize; qMemCopy(data,(void *)m_readBuffer,m_bufSize); m_readCursor = m_bufSize; return freeBytes + m_bufSize; } qMemCopy(data,(void *)m_readBuffer,leftBytes); m_readCursor = leftBytes; m_bytesReady -= len; return len;
}@
and writeData like this:
@qint64 writeData(const char *data, qint64 len){int freeBytes = (m_bufSize - m_writeCursor);
if(len <= freeBytes){
qMemCopy((void *)m_writeBuffer,data,len);
m_writeCursor += len;
m_bytesReady += len;
return len;
}qMemCopy((void *)m_writeBuffer,data,freeBytes);
switchBuffer(m_writeBuffer);
int leftBytes = len-freeBytes;
if(leftBytes > m_bufSize) { m_bytesReady += freeBytes + m_bufSize; qMemCopy((void *)m_writeBuffer,data,m_bufSize); m_writeCursor = m_bufSize; return freeBytes + m_bufSize; } qMemCopy((void *)m_writeBuffer,data,leftBytes); m_writeCursor = leftBytes; m_bytesReady += len; return len;
}@
But now I hear clicks which depend on my buffer size if it equal to this:
@ m_bufSize = bufSize*5;@
It's a lot of clicks, if I change 5 to 10 it less clicks so i put there 1000. :)