Hello everybody
I'am writing a program that will play wav files and add some sound effects.
And now I want to ask you some questions about problems, that I faced.
First of all I tried to use write method from QIODevice
QAudioDevice * m_audioOutput;
....
file.seek(44);
buff = file.read(44000);
m_audioOutput = new QAudioDevice(format,this);
m_output = m_audioOutput->start();
int size = m_output->bytesToWrite(); //size =0
int bytesWritten = m_output->write(buff.data(),buff.size()); // bytesWritten = 8192
QAudioDevice * m_audioOutput;
QIODevice * m_output;
QFile file;
QByteArray buff;
....
file.seek(44);
buff = file.read(44000);
m_audioOutput = new QAudioDevice(format,this);
m_output = m_audioOutput->start();
int size = m_output->bytesToWrite(); //size =0
int bytesWritten = m_output->write(buff.data(),buff.size()); // bytesWritten = 8192
To copy to clipboard, switch view to plain text mode
Why was written only 8192 bytes, instead of 44000?
Ok, i sad to myself. It isn't a big problem
QQueue<QByteArray> queue;
for (int i=0;i<50;i++)
{
queue.enqueue(file.read(8192));
}
QObject::connect(m_output,
SIGNAL(bytesWritten
(qint64
)),
&loop,
SLOT(quit
()));
while (!queue.isEmpty())
{
buff = queue.dequeue();
m_output->write(buff.data(),buff.size());
loop.exec();
}
QQueue<QByteArray> queue;
QByteArray buff;
QEventLoop loop;
for (int i=0;i<50;i++)
{
queue.enqueue(file.read(8192));
}
QObject::connect(m_output,SIGNAL(bytesWritten(qint64)),&loop,SLOT(quit()));
while (!queue.isEmpty())
{
buff = queue.dequeue();
m_output->write(buff.data(),buff.size());
loop.exec();
}
To copy to clipboard, switch view to plain text mode
I heard a small pop from speakers. It was first 8192 bytes written to QIODevice. Then program freezes in the loop.
Why signal bytesWritten() doesn't stop loop?
Ok, I said to myself, lets try something else.
QQueue<QByteArray> queue;
for (int i=0;i<50;i++)
{
queue.enqueue(file.read(8192));
}
QObject::connect(m_audioOutput,
SIGNAL(stateChanged
(QAudio
::State)),
&loop,
SLOT(quit
()));
while (!queue.isEmpty())
{
buff = queue.dequeue();
m_output->write(buff.data(),buff.size());
loop.exec();
}
QQueue<QByteArray> queue;
QByteArray buff;
QEventLoop loop;
for (int i=0;i<50;i++)
{
queue.enqueue(file.read(8192));
}
QObject::connect(m_audioOutput,SIGNAL(stateChanged(QAudio::State)),&loop,SLOT(quit()));
while (!queue.isEmpty())
{
buff = queue.dequeue();
m_output->write(buff.data(),buff.size());
loop.exec();
}
To copy to clipboard, switch view to plain text mode
Oh yeah! I hear music, but with lags. It was like 8192 bytes played, then silence for about half of a second, then another 8192 bytes was played.
So I decide to change everything.
I decide to use timer.
#define TIMER_PLAY 30
QQueue<QByteArray> queue;
int bytesToRead = TIMER_PLAY*44100*4/1000; //bytesToRead - it is how many bytes will play in 30 milliseconds between timerEvent
for (int i=0;i<50;i++)
{
queue.enqueue(file.read(bytesToRead));
}
startTimer(TIMER_PLAY,Qt::PreciseTimer); // class Player : public QObject
{
buff = queue.dequeue();
m_output->write(buff.data(),buff.size());
}
#define TIMER_PLAY 30
QQueue<QByteArray> queue;
QByteArray buff;
QEventLoop loop;
int bytesToRead = TIMER_PLAY*44100*4/1000; //bytesToRead - it is how many bytes will play in 30 milliseconds between timerEvent
for (int i=0;i<50;i++)
{
queue.enqueue(file.read(bytesToRead));
}
startTimer(TIMER_PLAY,Qt::PreciseTimer); // class Player : public QObject
void Player::timerEvent(QTimerEvent *)
{
buff = queue.dequeue();
m_output->write(buff.data(),buff.size());
}
To copy to clipboard, switch view to plain text mode
I hear music! it works. I was happy 
My program was growing bigger and bigger. I add some QThreads and some math calculations. And faced new problem.
Timer can't gave me exactly 30 milliseconds and now i can hear some annoying lags (milliseconds).
So i decide to write a post here.
Could you help me please.
1. Why I can write only 8192 bytes to QIODevice?
2. What i'm doing wrong with loops? What should I do to hear music?
Thank you for your attention.
Bookmarks