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. Creating QIODevice with infinite data
QtWS25 Last Chance

Creating QIODevice with infinite data

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtmultimediaqiodeviceqaudioqbuffer
3 Posts 3 Posters 347 Views
  • 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
    artemious3
    wrote on 22 Feb 2024, 08:01 last edited by artemious3
    #1

    I'm making a simple DAW and my aim is to make a readonly audio buffer, containing a pregenerated sine wave, that can be read infinitely. So, if all the bytes of internal audioBuffer were read, it start reading it from the beginning. My current implementation is as follows:

    AudioSynthBuffer.h:

    
    #include <QAudio>
    #include <QBuffer>
    const qint32 SAMPLING_FREQUENCY = 44100;
    class AudioSynthBuffer  : public QIODevice{
    
        private:
            const qint32 bufferSize = SAMPLING_FREQUENCY * 2;
            char* audioData;
    
        public:
            AudioSynthBuffer(QObject* parent = nullptr);
            ~AudioSynthBuffer();
    
            virtual qint64 readData(char *data, qint64 maxSize) override;
            virtual bool open(QIODevice::OpenMode om = ReadOnly) override;
            qint64 bytesAvailable() const override;
        };
    

    AudioSynthBuffer.cpp:

    #include "AudioSynthBuffer.h"
    
    AudioSynthBuffer::AudioSynthBuffer(QObject *parent) : QIODevice(parent)
    {
        audioData = new char[bufferSize];
    
        /* initializing audioBuffer somehow... */
    
    }
    
    bool AudioSynthBuffer::open(OpenMode om) {
        if(om != ReadOnly){
            setOpenMode(NotOpen);
            return false;
        }
        return QIODevice::open(om);
    }
    
    qint64 AudioSynthBuffer::readData(char *targetData, qint64 maxRead) {
        qint64 bytesRead = 0;
        qint64 remainingBytes = maxRead;
        char* currentDataPtr;
    
        while(bytesRead < maxRead){
            currentDataPtr = std::copy(audioData, audioData + remainingBytes, targetData);
            bytesRead = currentDataPtr - targetData;
            remainingBytes = (maxRead - bytesRead >= bufferSize) ? bufferSize : maxRead - bytesRead;
        }
    
        return bytesRead;
    }
    
    AudioSynthBuffer::~AudioSynthBuffer() {
        delete[] audioData;
    }
    
    qint64 AudioSynthBuffer::bytesAvailable() const {
        return ULLONG_MAX;
    }
    

    It seems like it doesn't work in appropriate way. I'd like to know if you can see some problems with this implementation, and what should I change, just opinion of experienced programmers. Maybe I should not even create subclass of QIODevice and use a different concept?

    C 1 Reply Last reply 23 Feb 2024, 02:06
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 22 Feb 2024, 20:16 last edited by
      #2

      Hi and welcome to devnet,

      How are you using it ?
      What exact error are you getting ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • A artemious3
        22 Feb 2024, 08:01

        I'm making a simple DAW and my aim is to make a readonly audio buffer, containing a pregenerated sine wave, that can be read infinitely. So, if all the bytes of internal audioBuffer were read, it start reading it from the beginning. My current implementation is as follows:

        AudioSynthBuffer.h:

        
        #include <QAudio>
        #include <QBuffer>
        const qint32 SAMPLING_FREQUENCY = 44100;
        class AudioSynthBuffer  : public QIODevice{
        
            private:
                const qint32 bufferSize = SAMPLING_FREQUENCY * 2;
                char* audioData;
        
            public:
                AudioSynthBuffer(QObject* parent = nullptr);
                ~AudioSynthBuffer();
        
                virtual qint64 readData(char *data, qint64 maxSize) override;
                virtual bool open(QIODevice::OpenMode om = ReadOnly) override;
                qint64 bytesAvailable() const override;
            };
        

        AudioSynthBuffer.cpp:

        #include "AudioSynthBuffer.h"
        
        AudioSynthBuffer::AudioSynthBuffer(QObject *parent) : QIODevice(parent)
        {
            audioData = new char[bufferSize];
        
            /* initializing audioBuffer somehow... */
        
        }
        
        bool AudioSynthBuffer::open(OpenMode om) {
            if(om != ReadOnly){
                setOpenMode(NotOpen);
                return false;
            }
            return QIODevice::open(om);
        }
        
        qint64 AudioSynthBuffer::readData(char *targetData, qint64 maxRead) {
            qint64 bytesRead = 0;
            qint64 remainingBytes = maxRead;
            char* currentDataPtr;
        
            while(bytesRead < maxRead){
                currentDataPtr = std::copy(audioData, audioData + remainingBytes, targetData);
                bytesRead = currentDataPtr - targetData;
                remainingBytes = (maxRead - bytesRead >= bufferSize) ? bufferSize : maxRead - bytesRead;
            }
        
            return bytesRead;
        }
        
        AudioSynthBuffer::~AudioSynthBuffer() {
            delete[] audioData;
        }
        
        qint64 AudioSynthBuffer::bytesAvailable() const {
            return ULLONG_MAX;
        }
        

        It seems like it doesn't work in appropriate way. I'd like to know if you can see some problems with this implementation, and what should I change, just opinion of experienced programmers. Maybe I should not even create subclass of QIODevice and use a different concept?

        C Offline
        C Offline
        ChrisW67
        wrote on 23 Feb 2024, 02:06 last edited by
        #3

        @artemious3 said in Creating QIODevice with infinite data:

        I'd like to know if you can see some problems with this implementation,

        On a cursory inspection...
        Let's say your audioData buffer size is 1024 bytes, for example, and the user requests a read of 2048 bytes (because your bytesAvailable says that is available). This line:

        currentDataPtr = std::copy(audioData, audioData + remainingBytes, targetData);
        

        will try to copy 2048 bytes out of a 1024 byte buffer.

        You should also look at the QIODevice::bytesAvailable() docs regarding what this should return.

        1 Reply Last reply
        0

        1/3

        22 Feb 2024, 08:01

        • Login

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