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. How to port QAudioOutput device(QAudioDeviceInfo::defaultOutputDevice()); to Qt6?
Forum Updated to NodeBB v4.3 + New Features

How to port QAudioOutput device(QAudioDeviceInfo::defaultOutputDevice()); to Qt6?

Scheduled Pinned Locked Moved Unsolved General and Desktop
26 Posts 3 Posters 4.8k 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.
  • U Urbi

    @Christian-Ehrlicher Christian, sorry, I am looking for a solution, not for playing games. If you knew who I am and what I have already manage to program you wouldn't treat me that way. Sorry, if this just a from some nerds... Good bye.

    Cobra91151C Offline
    Cobra91151C Offline
    Cobra91151
    wrote on last edited by
    #15

    @Urbi

    @Christian-Ehrlicher is right, you need to know at least basic C++ to create your projects. @Urbi in your case your local QFile effect; variable gets out of scope (gets deleted) after the bracket, so no audio will be outputed. You must have it as a pointer and keep in mind to remove it later after you no longer need it to prevent a memory leak. You can use delete or deleteLater(). Please, check out my test code below.

    Code:

       if (play) {
           QFile *effectFile = new QFile(this);
           effectFile->setFileName(QString("%1/%2").arg(homePath, "sounds/1.wav"));
           qDebug() << "Is file exists: " << effectFile->exists() << " | " << effectFile->fileName();
           effectFile->open(QIODevice::ReadOnly);
           audio->start(effectFile);
           effectFile->close();
           effectFile->deleteLater(); //removes the QFile object, or call - delete effectFile
       }
    

    Also, you can use the qDebug() to check the console output for example to see if the file exists and other useful stuff. By the way, what Qt 6 version are you using for this project?

    U 2 Replies Last reply
    1
    • Cobra91151C Cobra91151

      @Urbi

      @Christian-Ehrlicher is right, you need to know at least basic C++ to create your projects. @Urbi in your case your local QFile effect; variable gets out of scope (gets deleted) after the bracket, so no audio will be outputed. You must have it as a pointer and keep in mind to remove it later after you no longer need it to prevent a memory leak. You can use delete or deleteLater(). Please, check out my test code below.

      Code:

         if (play) {
             QFile *effectFile = new QFile(this);
             effectFile->setFileName(QString("%1/%2").arg(homePath, "sounds/1.wav"));
             qDebug() << "Is file exists: " << effectFile->exists() << " | " << effectFile->fileName();
             effectFile->open(QIODevice::ReadOnly);
             audio->start(effectFile);
             effectFile->close();
             effectFile->deleteLater(); //removes the QFile object, or call - delete effectFile
         }
      

      Also, you can use the qDebug() to check the console output for example to see if the file exists and other useful stuff. By the way, what Qt 6 version are you using for this project?

      U Offline
      U Offline
      Urbi
      wrote on last edited by
      #16

      @Cobra91151 It gives this compilation error: 'audio' was not declared in this scope; did you mean 'QAudio'?

      Cobra91151C 1 Reply Last reply
      0
      • Cobra91151C Cobra91151

        @Urbi

        @Christian-Ehrlicher is right, you need to know at least basic C++ to create your projects. @Urbi in your case your local QFile effect; variable gets out of scope (gets deleted) after the bracket, so no audio will be outputed. You must have it as a pointer and keep in mind to remove it later after you no longer need it to prevent a memory leak. You can use delete or deleteLater(). Please, check out my test code below.

        Code:

           if (play) {
               QFile *effectFile = new QFile(this);
               effectFile->setFileName(QString("%1/%2").arg(homePath, "sounds/1.wav"));
               qDebug() << "Is file exists: " << effectFile->exists() << " | " << effectFile->fileName();
               effectFile->open(QIODevice::ReadOnly);
               audio->start(effectFile);
               effectFile->close();
               effectFile->deleteLater(); //removes the QFile object, or call - delete effectFile
           }
        

        Also, you can use the qDebug() to check the console output for example to see if the file exists and other useful stuff. By the way, what Qt 6 version are you using for this project?

        U Offline
        U Offline
        Urbi
        wrote on last edited by
        #17

        @Cobra91151 Sorry, I forgot that I had already deleted the lines

        QAudioFormat format;
         format.setSampleRate(8000);
         format.setChannelCount(1);
         format.setSampleFormat(QAudioFormat::UInt8);
         QAudioSink* audio = new QAudioSink(format, this);
        

        Now it compiles and sends "something" to the default audio device. However, I just hear a crackle, and the program crashes afterwards. But at least one step ahead ...

        Cobra91151C 1 Reply Last reply
        0
        • U Urbi

          @Cobra91151 It gives this compilation error: 'audio' was not declared in this scope; did you mean 'QAudio'?

          Cobra91151C Offline
          Cobra91151C Offline
          Cobra91151
          wrote on last edited by Cobra91151
          #18

          @Urbi

          It's audio object from your code above: QAudioSink *audio = new QAudioSink(format, this);
          What Qt 6 version do you use? Because I got qt.multimedia.audiooutput: Failed to set up resampler issue, which is well known bug: https://bugreports.qt.io/browse/QTBUG-108383. This issue has been fixed in Qt 6.4.3.
          So, I recommend check out the console output for the same issue?

          1 Reply Last reply
          0
          • U Urbi

            @Cobra91151 Sorry, I forgot that I had already deleted the lines

            QAudioFormat format;
             format.setSampleRate(8000);
             format.setChannelCount(1);
             format.setSampleFormat(QAudioFormat::UInt8);
             QAudioSink* audio = new QAudioSink(format, this);
            

            Now it compiles and sends "something" to the default audio device. However, I just hear a crackle, and the program crashes afterwards. But at least one step ahead ...

            Cobra91151C Offline
            Cobra91151C Offline
            Cobra91151
            wrote on last edited by Cobra91151
            #19

            @Urbi

            Then check out your program using the debugger to find out what causes the crash (debug mode only). It should point you to the right code section.

            By the way, include this code in main function:

            #ifdef QT_DEBUG
                qputenv("QT_FATAL_WARNINGS", "1");
                qputenv("QT_MESSAGE_PATTERN",
                        "Type: %{type}\nProduct Name: %{appname}\nFile: %{file}\nLine: %{line}\nMethod: %{function}\nThreadID: %{threadid}\nThreadPtr: %{qthreadptr}\nMessage: %{message}");
            #endif
            

            Then run the debugger. It should provide more details about this issue.

            U 1 Reply Last reply
            0
            • Cobra91151C Cobra91151

              @Urbi

              Then check out your program using the debugger to find out what causes the crash (debug mode only). It should point you to the right code section.

              By the way, include this code in main function:

              #ifdef QT_DEBUG
                  qputenv("QT_FATAL_WARNINGS", "1");
                  qputenv("QT_MESSAGE_PATTERN",
                          "Type: %{type}\nProduct Name: %{appname}\nFile: %{file}\nLine: %{line}\nMethod: %{function}\nThreadID: %{threadid}\nThreadPtr: %{qthreadptr}\nMessage: %{message}");
              #endif
              

              Then run the debugger. It should provide more details about this issue.

              U Offline
              U Offline
              Urbi
              wrote on last edited by
              #20

              @Cobra91151 With these parameters, the wav file is correctly played. However, the program still crashes immediately after playing is finished.

              #include <QSoundEffect>
              #include <QAudioOutput>
              #include <QMediaDevices>
              #include <QAudioDevice>
              #include <QAudioSink>
              #include <QCoreApplication>
              #include <QDir>
              
              {
                QAudioDevice info(QMediaDevices::defaultAudioOutput());
                QString homePath = QDir::homePath();
                QAudioFormat format;
                format.setSampleRate(48000);
                format.setChannelCount(1);
                format.setSampleFormat(QAudioFormat::Int16);
                QAudioSink* audio = new QAudioSink(format, this);
                connect(audio, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State)));
              
                if (play_) {
                    QFile *effectFile = new QFile(this);
                    effectFile->setFileName(QString("%1/%2").arg(homePath, "/sounds/1.wav"));
                    qDebug() << "Is file exists: " << effectFile->exists() << " | " << effectFile->fileName();
                    effectFile->open(QIODevice::ReadOnly);
                    audio->start(effectFile);
                    effectFile->close();
                    effectFile->deleteLater(); //removes the QFile object, or call - delete effectFile
                }
              }
              
              Cobra91151C 1 Reply Last reply
              0
              • U Urbi

                @Cobra91151 With these parameters, the wav file is correctly played. However, the program still crashes immediately after playing is finished.

                #include <QSoundEffect>
                #include <QAudioOutput>
                #include <QMediaDevices>
                #include <QAudioDevice>
                #include <QAudioSink>
                #include <QCoreApplication>
                #include <QDir>
                
                {
                  QAudioDevice info(QMediaDevices::defaultAudioOutput());
                  QString homePath = QDir::homePath();
                  QAudioFormat format;
                  format.setSampleRate(48000);
                  format.setChannelCount(1);
                  format.setSampleFormat(QAudioFormat::Int16);
                  QAudioSink* audio = new QAudioSink(format, this);
                  connect(audio, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State)));
                
                  if (play_) {
                      QFile *effectFile = new QFile(this);
                      effectFile->setFileName(QString("%1/%2").arg(homePath, "/sounds/1.wav"));
                      qDebug() << "Is file exists: " << effectFile->exists() << " | " << effectFile->fileName();
                      effectFile->open(QIODevice::ReadOnly);
                      audio->start(effectFile);
                      effectFile->close();
                      effectFile->deleteLater(); //removes the QFile object, or call - delete effectFile
                  }
                }
                
                Cobra91151C Offline
                Cobra91151C Offline
                Cobra91151
                wrote on last edited by Cobra91151
                #21

                @Urbi

                I see your QAudioSink *audio is initialized but never deleted, this could be a memory leak which could lead to crash.

                Code:

                if (play_)  {
                    QFile *effectFile = new QFile(this);
                    effectFile->setFileName(QString("%1/%2").arg(homePath, "/sounds/1.wav"));
                    qDebug() << "Is file exists: " << effectFile->exists() << " | " << effectFile->fileName();
                    effectFile->open(QIODevice::ReadOnly);
                    audio->start(effectFile);
                    effectFile->close();
                    effectFile->deleteLater(); //removes the QFile object, or call - delete effectFile
                }
                
                audio->deleteLater(); // removes QAudioSink object
                

                Please, check out my post above regarding using the debugger.

                U 1 Reply Last reply
                0
                • Cobra91151C Cobra91151

                  @Urbi

                  I see your QAudioSink *audio is initialized but never deleted, this could be a memory leak which could lead to crash.

                  Code:

                  if (play_)  {
                      QFile *effectFile = new QFile(this);
                      effectFile->setFileName(QString("%1/%2").arg(homePath, "/sounds/1.wav"));
                      qDebug() << "Is file exists: " << effectFile->exists() << " | " << effectFile->fileName();
                      effectFile->open(QIODevice::ReadOnly);
                      audio->start(effectFile);
                      effectFile->close();
                      effectFile->deleteLater(); //removes the QFile object, or call - delete effectFile
                  }
                  
                  audio->deleteLater(); // removes QAudioSink object
                  

                  Please, check out my post above regarding using the debugger.

                  U Offline
                  U Offline
                  Urbi
                  wrote on last edited by
                  #22

                  @Cobra91151 Ok, the last two lines are breaking it.

                  effectFile->close();
                  

                  leads to an abrupt end of the played sound. And this line causes the program crashs:

                  effectFile->deleteLater(); //removes the QFile object, or call - delete effectFile
                  

                  I will now try to consolidate my code. (It was just a simplified example I presented here.) Let's see if I can put the entire definition of audio device, format and so on somewhere else where it is only called once after program start.

                  Anyway, many thanks for your help, Cobra91151!

                  Cobra91151C 1 Reply Last reply
                  0
                  • U Urbi

                    @Cobra91151 Ok, the last two lines are breaking it.

                    effectFile->close();
                    

                    leads to an abrupt end of the played sound. And this line causes the program crashs:

                    effectFile->deleteLater(); //removes the QFile object, or call - delete effectFile
                    

                    I will now try to consolidate my code. (It was just a simplified example I presented here.) Let's see if I can put the entire definition of audio device, format and so on somewhere else where it is only called once after program start.

                    Anyway, many thanks for your help, Cobra91151!

                    Cobra91151C Offline
                    Cobra91151C Offline
                    Cobra91151
                    wrote on last edited by Cobra91151
                    #23

                    @Urbi

                    It could close the file when audio is still running. It was just an example how to work with QFile. So, I recommend you to close and delete the file after the audio is finished. Happy coding!

                    U 1 Reply Last reply
                    1
                    • Cobra91151C Cobra91151

                      @Urbi

                      It could close the file when audio is still running. It was just an example how to work with QFile. So, I recommend you to close and delete the file after the audio is finished. Happy coding!

                      U Offline
                      U Offline
                      Urbi
                      wrote on last edited by
                      #24

                      @Cobra91151 Yes, that seems to be necessary. Because in reality there are up to 12 such wav files played in time cascade under certain conditions. I've set a command to close the audio sink at the end of this cascade to prevent a memory leak. Meanwhile, this is working pretty well.
                      However, I noticed, that the virtual memory slightly increases each time a wav file is loaded. Please tell me: what is the right command to close and delete such a played file? Because as written before, the two lines

                      effectFile->close();
                      effectFile->deleteLater();
                      

                      do not work in my case.

                      U 1 Reply Last reply
                      0
                      • U Urbi

                        @Cobra91151 Yes, that seems to be necessary. Because in reality there are up to 12 such wav files played in time cascade under certain conditions. I've set a command to close the audio sink at the end of this cascade to prevent a memory leak. Meanwhile, this is working pretty well.
                        However, I noticed, that the virtual memory slightly increases each time a wav file is loaded. Please tell me: what is the right command to close and delete such a played file? Because as written before, the two lines

                        effectFile->close();
                        effectFile->deleteLater();
                        

                        do not work in my case.

                        U Offline
                        U Offline
                        Urbi
                        wrote on last edited by
                        #25

                        @Urbi I have now put all the close and delete commands at the end of the cascade and all the

                        QFile *effect123 = new QFile(this);
                        

                        definitions at the beginning. This way the program doesn't crash anymore with the two lines from above. BUT: The observed memory leak effect is still the same. Why?

                        audio->deleteLater();
                        

                        is set, and also for each effect file

                        effect123->close();
                        effect123->deleteLater();
                        

                        I have found a number of similar reports on the Internet, but so far I've not seen any solution. Any idea?

                        Cobra91151C 1 Reply Last reply
                        0
                        • U Urbi

                          @Urbi I have now put all the close and delete commands at the end of the cascade and all the

                          QFile *effect123 = new QFile(this);
                          

                          definitions at the beginning. This way the program doesn't crash anymore with the two lines from above. BUT: The observed memory leak effect is still the same. Why?

                          audio->deleteLater();
                          

                          is set, and also for each effect file

                          effect123->close();
                          effect123->deleteLater();
                          

                          I have found a number of similar reports on the Internet, but so far I've not seen any solution. Any idea?

                          Cobra91151C Offline
                          Cobra91151C Offline
                          Cobra91151
                          wrote on last edited by
                          #26

                          @Urbi

                          Hello!

                          The issue with memory leak could be that you create multiple QFile objects on the heap and remove only some of them. Or you have other objects which are still not deleted. You need a better object management depending on your current project or use the smart pointers (https://wiki.qt.io/Smart_Pointers). As for deleteLater() method it does not remove it immediately, it's only schedules this object for deletion, which is recommended by Qt to use deleteLater() instead of delete. You can use for example: delete someFileObj; to clear the resources immediately. Also, you can make some objects as class member variables and remove them in the destructor, you can reuse one object for several files etc. Additionally, please, check out the docs for more details about deleteLater() method: https://doc.qt.io/qt-6/qobject.html#deleteLater

                          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