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.
Forum Updated to NodeBB v4.3 + New Features

Send raw data to QAudioOutput.

Scheduled Pinned Locked Moved General and Desktop
21 Posts 4 Posters 15.7k 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.
  • 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