Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Send raw data to QAudioOutput.

Send raw data to QAudioOutput.

Scheduled Pinned Locked Moved General and Desktop
21 Posts 4 Posters 16.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Anticross
    wrote on last edited by
    #2

    I replace AudioBuffer By new variable <code>QIODevice * m_dev;</code> 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

    1 Reply Last reply
    0
    • A Offline
      A Offline
      Anticross
      wrote on last edited by
      #3

      Now I'm using my buffer such as QIODevice @m_buf = (AudioBuffer *)m_output->start();@ and get the same. I change the file that I transmit to another one, and notice that I can hear music, but it's very distorted, and interrupts as I wrote previously. But one more notice that the high freq sounds with low volume hears better than others.

      1 Reply Last reply
      0
      • A Offline
        A Offline
        Anticross
        wrote on last edited by
        #4

        It seems like data sending through RTP is converted to BigEndian format before reaching client. But I find no BigEndian support of playback, so maybe I need to do some fast conversation. Question: How to do that ?

        1 Reply Last reply
        0
        • T Offline
          T Offline
          tobias.hunger
          wrote on last edited by
          #5

          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.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            Anticross
            wrote on last edited by
            #6

            OK, thanks. Another question: I have @unsigned char const* data@ with size @unsigned dataSize@ , qFromBigEndian needs to chose type (qInt16,qInt32,qInt64), and returns value of it's type, but how can I put this data back into unsigned char const* array with size of dataSize ?

            1 Reply Last reply
            0
            • A Offline
              A Offline
              Anticross
              wrote on last edited by
              #7

              This does not helped:
              @
              char * dt = new char[dataSize];
              itoa(qFromBigEndian<qint16>(data),dt,2);
              m_buf->writeData((const char*)dt,dataSize);
              delete dt;
              @

              1 Reply Last reply
              0
              • A Offline
                A Offline
                Anticross
                wrote on last edited by
                #8

                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.

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  Anticross
                  wrote on last edited by
                  #9

                  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.

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    Anticross
                    wrote on last edited by
                    #10

                    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 ?

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      Anticross
                      wrote on last edited by
                      #11

                      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).

                      1 Reply Last reply
                      0
                      • T Offline
                        T Offline
                        tobias.hunger
                        wrote on last edited by
                        #12

                        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?

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          Anticross
                          wrote on last edited by
                          #13

                          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.

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            Anticross
                            wrote on last edited by
                            #14

                            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_OBJECT

                            public:
                            //----------------------------------------------------------------------------------------------------------------------------------
                            AudioBuffer(/const QAudioFormat &format,/ QObject parent = NULL, int bufSize = 1400) : QIODevice(parent)
                            {
                            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())
                            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 ?

                            1 Reply Last reply
                            0
                            • A Offline
                              A Offline
                              Anticross
                              wrote on last edited by
                              #15

                              One more question whats the main difference between push and pull mode of playing ?

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                Anticross
                                wrote on last edited by
                                #16

                                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.

                                1 Reply Last reply
                                0
                                • B Offline
                                  B Offline
                                  billconan
                                  wrote on last edited by
                                  #17

                                  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.

                                  1 Reply Last reply
                                  0
                                  • B Offline
                                    B Offline
                                    billconan
                                    wrote on last edited by
                                    #18

                                    has this issue been resolved yet? I also need to achieve the same thing?

                                    1 Reply Last reply
                                    0
                                    • B Offline
                                      B Offline
                                      billconan
                                      wrote on last edited by
                                      #19

                                      has this issue been resolved yet? I also need to achieve the same thing?

                                      1 Reply Last reply
                                      0
                                      • L Offline
                                        L Offline
                                        lynic
                                        wrote on last edited by
                                        #20

                                        I had a similar problem using a ringbuffer as a QIODevice backend for which I spent a whole day. The solution was to override the following method:

                                        @bool isSequential() const
                                        {
                                        return true;
                                        }@

                                        1 Reply Last reply
                                        0
                                        • L Offline
                                          L Offline
                                          lynic
                                          wrote on last edited by
                                          #21

                                          I had a similar problem using a ringbuffer as a QIODevice backend for which I spent a whole day. The solution was to override the following method:

                                          @bool isSequential() const
                                          {
                                          return true;
                                          }@

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved