send raw data to QAudioOutput.
I’ve got QAudioOutput which initialized by next format:
- QAudioFormat format;
- // Set up the format, eg.
- format.setFrequency(44100);
- format.setChannels(2);
- format.setSampleSize(16);
- format.setCodec("audio/pcm");
- format.setByteOrder(QAudioFormat::LittleEndian);
- format.setSampleType(QAudioFormat::UnSignedInt);
- QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
- if (!info.isFormatSupported(format)) {
- qWarning()<<"raw audio format not supported by backend, cannot play audio.";
- return;
- }
I’ve got a class subclassed from QIODevice to store incoming data which uses like a buffer:
- #ifndef AUDIOBUFFER_H
- #define AUDIOBUFFER_H
- #include <QAudioFormat>
- #include <QIODevice>
- #include <QMutex>
- {
- Q_OBJECT
- public:
- struct block
- {
- char * ptr;
- qint64 len;
- int index;
- };
- //----------------------------------------------------------------------------------------------------------------------------------
- {
- // const char * someData = "12MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWQuhaSSSSSSSSSSSSSSSSSSSSSSSSSSss";
- // writeData(someData,sizeof(someData));
- }
- //----------------------------------------------------------------------------------------------------------------------------------
- ~AudioBuffer()
- {
- clear();
- }
- //----------------------------------------------------------------------------------------------------------------------------------
- void start()
- {
- if(!isOpen())
- }
- //----------------------------------------------------------------------------------------------------------------------------------
- void stop()
- {
- close();
- }
- //----------------------------------------------------------------------------------------------------------------------------------
- qint64 readData(char * data, qint64 maxlen)
- {
- start();
- if(m_buffer.isEmpty())
- return 0;
- int length = maxlen;
- int size = 0;
- while (m_buffer.isEmpty() == false) {
- block bl = m_buffer.at(0);
- if (bl.len <= length) {
- memcpy(data+size, bl.ptr, bl.len);
- m_buffer.removeAt(0);
- delete [] bl.ptr;
- length -= bl.len;
- size += bl.len;
- continue;
- }
- memcpy(data+size, bl.ptr, length);
- bl.len -= length;
- m_buffer[0] = bl;
- memcpy(bl.ptr, bl.ptr+length, bl.len);
- size += length;
- length = 0;
- break;
- }
- if (length > 0)
- memset(data + (maxlen - length), 0xCC, length);
- return maxlen;
- }
- //----------------------------------------------------------------------------------------------------------------------------------
- qint64 writeData(const char *data, qint64 len)
- {
- start();
- char * ptr = new char[len];
- memcpy(ptr,data,len);
- block bl;
- bl.ptr = ptr;
- bl.len = len;
- m_buffer.append(bl);
- return len;
- }
- //----------------------------------------------------------------------------------------------------------------------------------
- void clear(){
- for(int i = 0; i<m_buffer.count(); i++)
- {
- block bl = m_buffer.at(i);
- delete [] bl.ptr;
- }
- m_buffer.clear();
- }
- //----------------------------------------------------------------------------------------------------------------------------------
- private:
- QMutex m_mutex;
- };
- #endif//AUDIOBUFFER_H
Then I do the following thing:
- AudioBuffer * m_buf;
- QAudioOutput * m_output;
- m_buf = new AudioBuffer();
- m_buf->start();
- m_output = new QAudioOutput(format);
- m_output->start(m_buf);
And later add data in another place:
- m_buf->writeData((const char *)data,dataSize);
But after all this manipulations I hear no sound at output.
15 replies
I replace AudioBuffer By new variable QIODevice * m_dev; And do the following declarations
- m_dev = m_output->start();
and replace
- m_buf->writeData((const char *)data,dataSize);
by
- m_dev->write((const char *)data,dataSize);
And now I get a beautiful noise in output but not that music which I put there. An this noise is interrupt periodically. But it finishes when data transmit finishes. Maybe something wrong with format?
As a source I am using wav file 44100 Hz 16 bit stereo, which i transmit over network an receive data by portions and write it actually here:
- m_buf->writeData((const char *)data,dataSize);
So if I use a file to receive this data, and after receiving I open it, it’s contains the music that I transmitt.
Edit: fixed code formatting and merged two posts; Andre
Now I’m using my buffer such as QIODevice
- m_buf = (AudioBuffer *)m_output->start();
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.
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.
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>
- {
- Q_OBJECT
- public:
- //----------------------------------------------------------------------------------------------------------------------------------
- {
- m_bufSize = bufSize*4;
- 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())
- }
- //----------------------------------------------------------------------------------------------------------------------------------
- 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 ?
You must log in to post a reply. Not a member yet? Register here!



