Send raw data to QAudioOutput.
-
wrote on 19 Dec 2011, 15:38 last edited by
RTP defines all values to be transmitted in big-endian, so no surprise there;-)
http://developer.qt.nokia.com/doc/qt-4.8/qtendian.html to the rescue.
-
wrote on 20 Dec 2011, 06:14 last edited by
-
wrote on 20 Dec 2011, 07:09 last edited by
This does not helped:
@
char * dt = new char[dataSize];
itoa(qFromBigEndian<qint16>(data),dt,2);
m_buf->writeData((const char*)dt,dataSize);
delete dt;
@ -
wrote on 20 Dec 2011, 07:49 last edited by
Edited to :
@qint16 val = qFromBigEndian<qint16>(data);
uchar* dt = new uchar[dataSize];
qToLittleEndian<qint16>(val,dt);
m_buf->writeData((const char*)dt,dataSize);
delete dt;@
But the quality of audio is worse then without conversation. -
wrote on 20 Dec 2011, 11:51 last edited by
I write function:
@bool SpeakerSink::toLittleEndian( const char * src, int size, int nBits)
{
if(src == NULL)
return false;for (int i = 0; i < size; i+=nBits) { qint16 val = qFromBigEndian<qint16>((const uchar*)(src+i)); qMemCopy((void*)(src+i),&val,nBits); } return true;
}@
It solve task of converting from big-endian to little-endian and in headphones I get the same result(I mean sound is recognizable but bad quality) as if my server will transmit data without conversation to big-endian. But sound still distorted and interrupts. -
wrote on 20 Dec 2011, 12:13 last edited by
I open VLC player and receive this stream normally, then I look at codec details and see some PCM S16BE(twos). So what is it and can I transform data to play normal PCM on QAudioOutput ? So is it 16-bit Big-endian pcm or something else? What means S ?
-
wrote on 20 Dec 2011, 13:37 last edited by
I record output of my sound card when receiving stream with sine of 1000 Hz. After opening it in Sound Forge I see pauses in this sine with delays from 5 ms to 25 ms but sine has the same shape(I mean no distortions).
-
wrote on 20 Dec 2011, 15:09 last edited by
Sorry, no idea what kind of data you send around your network;-)
Why do you have nBits in the toLittleEndian method shown above? Anything but nBits == 2 breaks the method, doesn't it? The name is rather confusing, too... shouldn't it at least be nBytes?
-
wrote on 21 Dec 2011, 05:56 last edited by
You're right the name must be at least nBytes :) Maybe QAudioOutput reads the buffer faster than it writes by receiving data from network, and I just need to wait some time before playing.
-
wrote on 21 Dec 2011, 07:45 last edited by
I rewrite my audio buffer class. Now it looks like this:
@#ifndef AUDIOBUFFER_H
#define AUDIOBUFFER_H#include <QAudioFormat>
#include <QIODevice>
#include <QMutex>
#include <QDebug>class AudioBuffer : public QIODevice
{
Q_OBJECTpublic:
//----------------------------------------------------------------------------------------------------------------------------------
AudioBuffer(/const QAudioFormat &format,/ QObject parent = NULL, int bufSize = 1400) : QIODevice(parent)
{
m_bufSize = bufSize4;m_buffer1 = new const char[m_bufSize]; m_buffer2 = new const char[m_bufSize]; m_rightOffset = 0; m_leftOffset = 0; m_cursor = 0; qMemSet((void *)m_buffer1,0,m_bufSize); }
//----------------------------------------------------------------------------------------------------------------------------------
~AudioBuffer()
{
delete m_buffer1;
delete m_buffer2;
}
//----------------------------------------------------------------------------------------------------------------------------------
void start()
{
if(!isOpen())
open(QIODevice::ReadWrite);
}
//----------------------------------------------------------------------------------------------------------------------------------
void stop()
{
close();
}
//----------------------------------------------------------------------------------------------------------------------------------
qint64 readData(char * data, qint64 len)
{
int free2end = m_bufSize-m_cursor;if(len <= free2end){ qMemCopy(data,m_buffer1+m_cursor,len); m_rightOffset += len; m_cursor += len; return len; } else { qMemCopy(data,m_buffer1+m_cursor,free2end); m_cursor = 0; qMemCopy(data+free2end,m_buffer1,len-free2end); m_rightOffset = len-free2end; m_leftOffset = 0; m_cursor += m_rightOffset; return len; } return 0; }
//----------------------------------------------------------------------------------------------------------------------------------
qint64 writeData(const char *data, qint64 len)
{
int free2end = m_bufSize-m_rightOffset;if(len <= free2end) // if we don't reach end of buffer { qMemCopy((void*)(m_buffer1+m_rightOffset),data,len); m_rightOffset += len; qDebug() << m_buffer1; return len; } else if(len <= (m_leftOffset+free2end)) { qMemCopy((void*)(m_buffer1+m_rightOffset),data,free2end); //write to end m_leftOffset = len-free2end; // need to write more from source and set new left offset qMemCopy((void*)m_buffer1,data+free2end,m_leftOffset); //write lefted part m_rightOffset = m_leftOffset; // set new right offset value m_leftOffset = 0; // set new left offset value qDebug() << m_buffer1; return len; } else { qMemCopy((void*)(m_buffer1+m_rightOffset),data,free2end); //write to end m_rightOffset += len-free2end; // need to write more from source len -= free2end; qMemCopy((void*)m_buffer1,data+free2end,m_leftOffset); //write lefted part m_rightOffset = 0; // set new right offset value len -= m_leftOffset; m_leftOffset = 0; qDebug() << m_buffer1; return len; } return 0; }
//----------------------------------------------------------------------------------------------------------------------------------
private:
const char * m_buffer1;
const char * m_buffer2;
int m_rightOffset;
int m_leftOffset;
int m_cursor;
int m_bufSize;
};#endif//AUDIOBUFFER_H@
And now I'm using it like this:
@m_output->start(m_buf);@
and it enters write data functions, but doesn't reads data. So question: How QAudioOutput asks for the data to play from QIODevice ? Is it call readData function or not ? And one more question: Is it possible to play rtsp stream using Phonon ? -
wrote on 21 Dec 2011, 13:24 last edited by
One more question whats the main difference between push and pull mode of playing ?
-
wrote on 29 Dec 2011, 08:07 last edited by
Interesting thing: when I play 22050 Hz 16 bit 2 channels audio stream - it plays normally without interruptions, but when playing 44100 Hz 16 bit stereo - not. If I open same stream(44 kHz) in VLC player or any other it plays normally without interruptions.
-
wrote on 3 Jul 2014, 22:59 last edited by
this is an interesting thread. a QAudioOuput from a buffer example should be added to the document.
too bad the document only has an example of playing a file.
-
wrote on 17 Feb 2015, 22:25 last edited by
has this issue been resolved yet? I also need to achieve the same thing?
-
wrote on 17 Feb 2015, 22:25 last edited by
has this issue been resolved yet? I also need to achieve the same thing?