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. Need some help with QIODevice based buffer class
Forum Updated to NodeBB v4.3 + New Features

Need some help with QIODevice based buffer class

Scheduled Pinned Locked Moved General and Desktop
5 Posts 2 Posters 3.8k 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
    #1

    I wrote QIODevice based class, which I use as my audio buffer. It consist from two arrays. When I write data, I write it till buffer reach end then switch to second buffer and continue writing, and so on. When I read data a do the same thing.
    @#ifndef AUDIOBUFFER_H
    #define AUDIOBUFFER_H

    #include <QAudioFormat>
    #include <QIODevice>
    #include <QMutex>
    #include <QDebug>
    #include <QtEndian>

    class AudioBuffer : public QIODevice
    {
    Q_OBJECT

    public:
    //----------------------------------------------------------------------------------------------------------------------------------
    AudioBuffer(QObject parent = NULL, int bufSize = 1411) : QIODevice(parent)
    {
    m_bufSize = bufSize
    10/10000/;

    m_buffer1 = new const char[m_bufSize];
    m_buffer2 = new const char[m_bufSize];

    m_readCursor = 0;
    m_writeCursor = 0;

    qMemSet((void *)m_buffer1,0,m_bufSize);
    qMemSet((void *)m_buffer2,0,m_bufSize);

    m_readBuffer = m_buffer1;
    m_writeBuffer = m_buffer1;

    m_bytesReady = 0;

    /* m_flag = false;*/

    }
    //----------------------------------------------------------------------------------------------------------------------------------
    ~AudioBuffer()
    {
    delete m_buffer1;
    delete m_buffer2;
    }
    //----------------------------------------------------------------------------------------------------------------------------------
    void start()
    {
    if(!isOpen())
    open(QIODevice::ReadWrite);
    }
    //----------------------------------------------------------------------------------------------------------------------------------
    void stop()
    {
    delete m_buffer1;
    delete m_buffer2;

    close();
    }
    //----------------------------------------------------------------------------------------------------------------------------------
    qint64 readData(char * data, qint64 len)
    {
    // if (m_flag == false){
    // if (bytesAvailable()>1000)
    // {
    // m_flag = true;
    // }
    // else
    // return 0;
    // }

        if(len > m_bytesReady)
            len = m_bytesReady;
    

    int freeBytes = (m_bufSize - m_readCursor);

    if(len <= freeBytes)
    {
    qMemCopy(data,(void *)m_readBuffer,len);
    m_readCursor += len;

    m_bytesReady -= len;

    return len;
    }

    qMemCopy(data,(void *)m_readBuffer,freeBytes);

    switchBuffer(m_readBuffer);

    int leftBytes = len-freeBytes;

    qMemCopy(data,(void *)m_readBuffer,leftBytes);

    m_readCursor = leftBytes;

    m_bytesReady -= len;

    return len;
    }
    //----------------------------------------------------------------------------------------------------------------------------------
    qint64 read(char * data, qint64 len)
    {
    return readData(data,len);
    }
    //----------------------------------------------------------------------------------------------------------------------------------
    qint64 readBlock ( char * data, quint64 size )
    {
    return readData(data,size);
    }
    //----------------------------------------------------------------------------------------------------------------------------------
    qint64 writeData(const char *data, qint64 len){

    int freeBytes = (m_bufSize - m_writeCursor);

    if(len <= freeBytes){
    qMemCopy((void *)m_writeBuffer,data,len);
    m_writeCursor += len;
    m_bytesReady += len;
    return len;
    }

    qMemCopy((void *)m_writeBuffer,data,freeBytes);

    switchBuffer(m_writeBuffer);

    int leftBytes = len-freeBytes;

        if(leftBytes > m_bufSize)
        {
           leftBytes = m_bufSize;
           m_bytesReady += freeBytes + m_bufSize;
        }
        else
            m_bytesReady += len;
    

    qMemCopy((void *)m_writeBuffer,data,leftBytes);

    m_writeCursor = leftBytes;

    return len;
    }
    //----------------------------------------------------------------------------------------------------------------------------------
    qint64 write(const char *data, qint64 len){

    return writeData(data,len);
    }
    //----------------------------------------------------------------------------------------------------------------------------------
    void switchBuffer(const char * buffer)
    {
    if(buffer == m_buffer1)
    buffer = m_buffer2;
    else
    buffer = m_buffer1;
    }
    //----------------------------------------------------------------------------------------------------------------------------------
    qint64 bytesAvailable() const
    {
    return m_bytesReady;
    }
    //----------------------------------------------------------------------------------------------------------------------------------
    private:
    const char * m_buffer1;
    const char * m_buffer2;
    const char * m_readBuffer;
    const char * m_writeBuffer;
    qint64 m_readCursor;
    qint64 m_writeCursor;
    qint64 m_bufSize;
    qint64 m_bytesReady;
    /bool m_flag;/

    };

    #endif//AUDIOBUFFER_H@
    I use m_readCursor and m_writeCursor to continue reading and writing, m_bytesReady to know How much bytes I can read. But when my m_bufSize is to small, like in this code:
    @m_bufSize = bufSize*10;@
    I've got a crash in read data right here:
    @qMemCopy(data,(void *)m_readBuffer,freeBytes);@
    because my freeByetes value is < 0 after one iteration. Waiting for your comments and modifications, optimizations.

    1 Reply Last reply
    0
    • J Offline
      J Offline
      joonhwan
      wrote on last edited by
      #2

      Though I don't know well about QIODevice class, but generally handling audio buffer requires us to use thread lock mechanism(like QMutex ..). Did you consider this?

      BTW, what kind of application you are building? I love DAW things. :-)

      joonhwan at gmail dot com

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

        This is just buffer class, and as you said the threads is needed, and I use it in other place in thread. So all with threads is OK :) This will be something like net player which uses RTSP session and receives data thou RTP and play it on a speakers.

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

          I solve it by modifying readData like this:
          @qint64 readData(char * data, qint64 len)
          {
          // if (m_flag == false){
          // if (bytesAvailable()>1000)
          // {
          // m_flag = true;
          // }
          // else
          // return 0;
          // }

              if(len > m_bytesReady)
                  len = m_bytesReady;
          

          int freeBytes = (m_bufSize - m_readCursor);

          if(len <= freeBytes)
          {
          qMemCopy(data,(void *)m_readBuffer,len);
          m_readCursor += len;

          m_bytesReady -= len;

          return len;
          }

          qMemCopy(data,(void *)m_readBuffer,freeBytes);

          switchBuffer(m_readBuffer);

              int leftBytes = len-freeBytes;
          
              if(leftBytes > m_bufSize)
              {
                  m_bytesReady -= freeBytes + m_bufSize;
          
                  qMemCopy(data,(void *)m_readBuffer,m_bufSize);
          
                  m_readCursor = m_bufSize;
          
                  return freeBytes + m_bufSize;
              }
          
              qMemCopy(data,(void *)m_readBuffer,leftBytes);
          
              m_readCursor = leftBytes;
          
              m_bytesReady -= len;
          
              return len;
          

          }@

          and writeData like this:
          @qint64 writeData(const char *data, qint64 len){

          int freeBytes = (m_bufSize - m_writeCursor);

          if(len <= freeBytes){
          qMemCopy((void *)m_writeBuffer,data,len);
          m_writeCursor += len;
          m_bytesReady += len;
          return len;
          }

          qMemCopy((void *)m_writeBuffer,data,freeBytes);

          switchBuffer(m_writeBuffer);

          int leftBytes = len-freeBytes;

              if(leftBytes > m_bufSize)
              {
                 m_bytesReady += freeBytes + m_bufSize;
          
                 qMemCopy((void *)m_writeBuffer,data,m_bufSize);
          
                 m_writeCursor = m_bufSize;
          
                 return freeBytes + m_bufSize;
              }
          
              qMemCopy((void *)m_writeBuffer,data,leftBytes);
          
              m_writeCursor = leftBytes;
          
              m_bytesReady += len;
          
              return len;  
          

          }@
          But now I hear clicks which depend on my buffer size if it equal to this:
          @ m_bufSize = bufSize*5;@
          It's a lot of clicks, if I change 5 to 10 it less clicks so i put there 1000. :)

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

            I found the place when it clicks. It clicks when I reach the end of buffer and make switchBuffer, so thats why when I make my buffer bigger it clicks rare, but why and how to solve it ?

            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