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. QAudioOutput on two devices(headphones)
Qt 6.11 is out! See what's new in the release blog

QAudioOutput on two devices(headphones)

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 2 Posters 584 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.
  • S Offline
    S Offline
    Sandres92
    wrote on last edited by Sandres92
    #1

    Hello. There is way output sound on two devices simultaneously. Two headphones connected to the computer and i output sound on them. I hear intermittent sound . Expectation : AAAAAA". Reality: "A--A--A".

    I get the sound from the microphone QAudioInput. I simulate a telephone connection . I receive sound from the microphone and transmit to the headphones

    When i use one devices, one headphone, it work correctly!! When I add a second device, I get intermittent sound.

    Could you help me? How can I get the sound right?

    1 Reply Last reply
    0
    • S Offline
      S Offline
      Sandres92
      wrote on last edited by
      #2

      QAudioInput and QAudioOutput i use from Examples.
      Input:

      void MainWindow::initializeAudio(const QAudioDeviceInfo &deviceInfo)
      {
          format.setSampleRate(8000);
              format.setChannelCount(1);
              format.setSampleSize(16);
              format.setSampleType(QAudioFormat::SignedInt);
              format.setByteOrder(QAudioFormat::LittleEndian);
              format.setCodec("audio/pcm");
          
              if (!deviceInfo.isFormatSupported(format))
              {
                  qWarning("Default format not supported - trying to use nearest");
                  //qWarning() << "Default format not supported - trying to use nearest";
                  format = deviceInfo.nearestFormat(format);
              }
          
              m_audioInfo.reset(new AudioInfo(format));
          
              connect(m_audioInfo.data(), &AudioInfo::update, [this]() {
                  sliderAnim(m_audioInfo->level());
              });
          
              m_audioInfo->start();
              
              m_audioInput.reset(new QAudioInput(deviceInfo, format));
              qreal initialVolume = QAudio::convertVolume(m_audioInput->volume(),
                                                          QAudio::LinearVolumeScale,
                                                          QAudio::LogarithmicVolumeScale);
          
              int v = qRound(initialVolume * 100);
              ui->horizontalSlider->setValue(v);
              ui->horizontalSlider->setValue(0.f * 100.0f);
          
              m_audioInput->stop();
              setResume();
              m_audioInput->start(m_audioInfo.data());
          
              _inputThread = new QThread();
              m_audioInput->moveToThread(_inputThread);
      }
      

      Output:

          m_audioInput.reset(new QAudioInput(deviceInfo, format));
          qreal initialVolume = QAudio::convertVolume(m_audioInput->volume(),
                                                      QAudio::LinearVolumeScale,
                                                      QAudio::LogarithmicVolumeScale);
      
          int v = qRound(initialVolume * 100);
          ui->horizontalSlider->setValue(v);
          ui->horizontalSlider->setValue(0.f * 100.0f);
      
          m_audioInput->stop();
          setResume();
          m_audioInput->start(m_audioInfo.data());
      
          //_inputThread = new QThread();
          //m_audioInput->moveToThread(_inputThread);
      

      I try add Output on thread, it doesn't help:

      _inputThread = new QThread();
          m_audioInput->moveToThread(_inputThread);
      
      1 Reply Last reply
      0
      • S Offline
        S Offline
        Sandres92
        wrote on last edited by
        #3

        AudioInfo class:

        class AudioInfo: public QIODevice
        {
            Q_OBJECT
        public:
            AudioInfo(const QAudioFormat &format);
        
            void start();
            void stop();
        
            qreal level() const { return m_level; }
        
            qint64 readData(char *data, qint64 len) override;
            qint64 writeData(const char *data, qint64 len) override;
            qint64 bytesAvailable() const;
        
        private:
            const QAudioFormat m_format;
            quint32 m_maxAmplitude = 0;
            qreal m_level = 0.0; // 0.0 <= m_level <= 1.0
        
            void  generateData(const QAudioFormat &format, qint64 durationUs, int sampleRate);
        
            QByteArray m_buffer_array;
            qint64 m_pos = 0;
            QBuffer     m_buffer;  // buffer to store received datagrams
        
            QByteArray m_buffer_test;
        
        signals:
            void update();
        
        #include "AudioInfo.h"
        
        AudioInfo::AudioInfo(const QAudioFormat &format)
            : m_format(format)
        {
            switch (m_format.sampleSize()) {
            case 8:
                switch (m_format.sampleType()) {
                case QAudioFormat::UnSignedInt:
                    m_maxAmplitude = 255;
                    break;
                case QAudioFormat::SignedInt:
                    m_maxAmplitude = 127;
                    break;
                default:
                    break;
                }
                break;
            case 16:
                switch (m_format.sampleType()) {
                case QAudioFormat::UnSignedInt:
                    m_maxAmplitude = 65535;
                    break;
                case QAudioFormat::SignedInt:
                    m_maxAmplitude = 32767;
                    break;
                default:
                    break;
                }
                break;
        
            case 32:
                switch (m_format.sampleType()) {
                case QAudioFormat::UnSignedInt:
                    m_maxAmplitude = 0xffffffff;
                    break;
                case QAudioFormat::SignedInt:
                    m_maxAmplitude = 0x7fffffff;
                    break;
                case QAudioFormat::Float:
                    m_maxAmplitude = 0x7fffffff; // Kind of
                default:
                    break;
                }
                break;
        
            default:
                break;
            }
        
            if (format.isValid())
            {
                //generateData(format, durationUs, sampleRate);
            }
        }
        
        void AudioInfo::start()
        {
            m_buffer.open(QIODevice::ReadWrite);
            open(QIODevice::ReadWrite);
        }
        
        void AudioInfo::stop()
        {
            close();
        }
        
        qint64 AudioInfo::writeData(const char *data, qint64 len)
        {
            //qDebug() << "writeData" << m_buffer_test.length();
            m_buffer_test.append(data, len);
            //qDebug() << "writeData finish" << m_buffer_test.length();
            return len;
        }
        
        qint64 AudioInfo::bytesAvailable() const
        {
            return m_buffer.size() + QIODevice::bytesAvailable();
        }
        
        qint64 AudioInfo::readData(char *data, qint64 len)
        {
            //qDebug() << "readData finish" << m_buffer_test.length();
            if (!m_buffer_test.isEmpty()) {
                memset(data, 0, len);
                if (m_buffer_test.size() < len) {
                    len = m_buffer_test.size();
                }
                if (len > 0) {
                    memcpy(data, m_buffer_test.left(len).data(), len);
                    m_buffer_test.remove(0, len);
                }
            } else {
                memset(data, 0, len);
            }
            return len;
        }
        
        1 Reply Last reply
        0
        • S Offline
          S Offline
          Sandres92
          wrote on last edited by
          #4

          I try add QThread for output. it doesn't help:

          class SfxThread: public QThread
          {
              Q_OBJECT
          
          public:
              SfxThread(const QAudioDeviceInfo &deviceInfo, const QAudioFormat &format,
                        QScopedPointer<AudioInfo> &m_audioInfo);
              ~SfxThread();
              void run();
          
          signals:
          
          public slots:
              void play();
              void playerStateChanged(QAudio::State state);
          private:
              void playNext();
              void play(QString& filename);
          
              QScopedPointer<AudioInfo> _ai;
              QScopedPointer<QAudioOutput> _ao;
              QAudioFormat _af;
              //QBuffer _buf;
          };
          
          #include "SfxThread.h"
          
          SfxThread::SfxThread(const QAudioDeviceInfo &deviceInfo, const QAudioFormat &format,
                               QScopedPointer<AudioInfo> &m_audioInfo)
          {
              _ai.reset(m_audioInfo.data());
          
              //.do precaching etc of the sounds here
              _ao.reset(new QAudioOutput(deviceInfo, format));
              start();
          
              // Move event processing of SfxThread to this thread
              QObject::moveToThread(this);
          }
          
          SfxThread::~SfxThread()
          {
              quit();
              wait();
          }
          
          void SfxThread::play()
          {
              //playlist.append(...);
              playNext();
          }
          
          // Plays the next file from queue
          void SfxThread::playNext()
          {
              //if (playlist.length() == 0 || _ao->state() == QAudio::ActiveState) {
              //    return;
              //}
              _ao->stop();
              //_buf.close();
              //play(playlist.dequeue());
          }
          
          void SfxThread::play(QString& filename)
          {
              //// load content here
              //QByteArray *ptr = ...
              //
              //_buf.setBuffer(ptr);
              //_buf.open(QIODevice::ReadOnly);
              //
              //_ao->setBufferSize(_buf.size());
              _ao->start(_ai.data());
          }
          
          void SfxThread::playerStateChanged(QAudio::State state)
          {
              // Play finished, play next clip
              if (state == QAudio::IdleState)
              {
                  playNext();
              }
          }
          
          void SfxThread::run()
          {
              //.set audio format here (_af.setCodec etc)
              _ao->start(_ai.data());
              //connect(_ao, SIGNAL(stateChanged(QAudio::State)), this, SLOT(playerStateChanged(QAudio::State)));
              exec();
          }
          
          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Hi,

            Which version of Qt are you using ?
            Why are you using threading ?

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

            S 1 Reply Last reply
            0
            • SGaistS SGaist

              Hi,

              Which version of Qt are you using ?
              Why are you using threading ?

              S Offline
              S Offline
              Sandres92
              wrote on last edited by Sandres92
              #6

              @SGaist Hello. Qt 5.12.1 MinGW 64-bit.
              At first I didn't use threads. It didn't work correctly. I hear intermittent sound .
              I decided threads would help. Add each QAudioOutput on separate thread .

                  m_audioOutput.reset(new QAudioOutput(deviceInfo, format));
                  m_audioOutput->start(m_audioInfo.data());
              
                  _outputThread = new QThread();
                  m_audioOutput->moveToThread(_outputThread);
                  _outputThread->start();
              

              It did not help too.

              Two QAudioOutput don't work as with threads as without threads. (Two QAudioOutput work, but I hear intermittent sound. Wheh work one QAudioOutput I hear correctly sound )

              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