Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. QtonPi
  4. Connect QAudioProbe to QMediaPlayer with RaspberryPi0
Forum Updated to NodeBB v4.3 + New Features

Connect QAudioProbe to QMediaPlayer with RaspberryPi0

Scheduled Pinned Locked Moved Solved QtonPi
6 Posts 2 Posters 893 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.
  • D Offline
    D Offline
    davidino
    wrote on last edited by davidino
    #1

    Goodmorning,
    I'm using an image made with boot2qt version QT 5.12.0
    As shown in the code below I'm trying to get the audio level out of a mediaPlayer made in QML. I can correctly setSource to the mediaplayer but the slot processBuffer is never called.
    For information the audio is played via HDMI.
    Can you advice?

    #include <QObject>
    #include <QAudioProbe>
    #include <QMediaPlayer>
    #include <QTimer>
    #include <vector>
    #include <memory>
    
    #include "playListModel_global.h"
    
    class PLAYLISTMODEL_EXPORT VolumeLevel : public QObject
    {
        Q_OBJECT
    public:
        VolumeLevel(QObject *parent = nullptr);
        ~VolumeLevel();
    
        Q_INVOKABLE void initVolume(QString qmlObjectName);
        void initVolume(QMediaPlayer *player);
    
    public slots:
        void processBuffer(QAudioBuffer buffer);
        void timerExpired();
    
    private:
        QAudioProbe probe;
        QTimer timer;
        QMediaPlayer *player;
    };
    
    #endif // VOLUMELEVEL_H
    
    
    
    
    #include "volumelevel.h"
    #include <QDebug>
    
    #include <QAudioProbe>
    
    VolumeLevel::VolumeLevel(QObject *parent) :
        QObject(parent)
    {}
    
    void VolumeLevel::initVolume(QString qmlObjectName)
    {
        player = static_cast<QMediaPlayer*>(QObject::findChild<QObject*>(qmlObjectName));
        initVolume(player);
    }
    
    void VolumeLevel::initVolume(QMediaPlayer* player)
    {
        if(probe.setSource(player)) {
            connect(&probe, &QAudioProbe::audioBufferProbed, this, &VolumeLevel::processBuffer);
            connect(&timer, &QTimer::timeout, this, &VolumeLevel::timerExpired);
            qDebug()<<"Connection done";
            timer.start(1000);
        }
    }
    
    void VolumeLevel::processBuffer(QAudioBuffer buffer)
    {
        // With a 16bit sample buffer:
        const quint16 *data = buffer.constData<quint16>();
        qDebug()<<"Raw: "<<*data;
    }
    
    void VolumeLevel::timerExpired()
    {
        qDebug()<<"probe is active: "<<probe.isActive();
    }
    
    VolumeLevel::~VolumeLevel()
    {
    
    }
    
    
    
    jsulmJ 1 Reply Last reply
    0
    • D Offline
      D Offline
      davidino
      wrote on last edited by
      #6

      Here, you can find the solution.
      https://forum.qt.io/topic/115268/cast-a-qobject-to-qmediaplayer-with-qobject_cast

      Regards,
      Davidino

      1 Reply Last reply
      0
      • D davidino

        Goodmorning,
        I'm using an image made with boot2qt version QT 5.12.0
        As shown in the code below I'm trying to get the audio level out of a mediaPlayer made in QML. I can correctly setSource to the mediaplayer but the slot processBuffer is never called.
        For information the audio is played via HDMI.
        Can you advice?

        #include <QObject>
        #include <QAudioProbe>
        #include <QMediaPlayer>
        #include <QTimer>
        #include <vector>
        #include <memory>
        
        #include "playListModel_global.h"
        
        class PLAYLISTMODEL_EXPORT VolumeLevel : public QObject
        {
            Q_OBJECT
        public:
            VolumeLevel(QObject *parent = nullptr);
            ~VolumeLevel();
        
            Q_INVOKABLE void initVolume(QString qmlObjectName);
            void initVolume(QMediaPlayer *player);
        
        public slots:
            void processBuffer(QAudioBuffer buffer);
            void timerExpired();
        
        private:
            QAudioProbe probe;
            QTimer timer;
            QMediaPlayer *player;
        };
        
        #endif // VOLUMELEVEL_H
        
        
        
        
        #include "volumelevel.h"
        #include <QDebug>
        
        #include <QAudioProbe>
        
        VolumeLevel::VolumeLevel(QObject *parent) :
            QObject(parent)
        {}
        
        void VolumeLevel::initVolume(QString qmlObjectName)
        {
            player = static_cast<QMediaPlayer*>(QObject::findChild<QObject*>(qmlObjectName));
            initVolume(player);
        }
        
        void VolumeLevel::initVolume(QMediaPlayer* player)
        {
            if(probe.setSource(player)) {
                connect(&probe, &QAudioProbe::audioBufferProbed, this, &VolumeLevel::processBuffer);
                connect(&timer, &QTimer::timeout, this, &VolumeLevel::timerExpired);
                qDebug()<<"Connection done";
                timer.start(1000);
            }
        }
        
        void VolumeLevel::processBuffer(QAudioBuffer buffer)
        {
            // With a 16bit sample buffer:
            const quint16 *data = buffer.constData<quint16>();
            qDebug()<<"Raw: "<<*data;
        }
        
        void VolumeLevel::timerExpired()
        {
            qDebug()<<"probe is active: "<<probe.isActive();
        }
        
        VolumeLevel::~VolumeLevel()
        {
        
        }
        
        
        
        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @davidino said in Connect QAudioProbe to QMediaPlayer with RaspberryPi0:

        player = static_cast<QMediaPlayer*>(QObject::findChild<QObject*>(qmlObjectName));

        Did you check whether player is not nullptr?

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        1
        • D Offline
          D Offline
          davidino
          wrote on last edited by
          #3

          Hello @jsulm,
          you are right. I've modified the function as follow:

          void VolumeLevel::initVolume(QString qmlObjectName)
          {
              player = QObject::findChild<QMediaPlayer*>(qmlObjectName);
              if(player != nullptr)
                  initVolume(player);
              else
                  qDebug()<<"MediaPlayer not found "<<qmlObjectName;
          }
          

          Unfortunately I still get object not found. In QML the MediaPlayer is defined as follow:

              MediaPlayer {
                  id: playMusic
                  objectName: "mediaplayer"
                  autoLoad: true
                  autoPlay: true
                  playlist: Playlist{id:playerList}
                  property Volume volumeMeter : Volume {id: volume}
                  Component.onCompleted: volume.initVolume(playMusic.objectName)
              }
          

          I've register Volume in main.cpp as:
          qmlRegisterType<VolumeLevel>("VolumeLib", 1, 0, "Volume");

          jsulmJ 1 Reply Last reply
          0
          • D davidino

            Hello @jsulm,
            you are right. I've modified the function as follow:

            void VolumeLevel::initVolume(QString qmlObjectName)
            {
                player = QObject::findChild<QMediaPlayer*>(qmlObjectName);
                if(player != nullptr)
                    initVolume(player);
                else
                    qDebug()<<"MediaPlayer not found "<<qmlObjectName;
            }
            

            Unfortunately I still get object not found. In QML the MediaPlayer is defined as follow:

                MediaPlayer {
                    id: playMusic
                    objectName: "mediaplayer"
                    autoLoad: true
                    autoPlay: true
                    playlist: Playlist{id:playerList}
                    property Volume volumeMeter : Volume {id: volume}
                    Component.onCompleted: volume.initVolume(playMusic.objectName)
                }
            

            I've register Volume in main.cpp as:
            qmlRegisterType<VolumeLevel>("VolumeLib", 1, 0, "Volume");

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #4

            @davidino said in Connect QAudioProbe to QMediaPlayer with RaspberryPi0:

            QObject::findChild<QMediaPlayer*>(qmlObjectName);

            findChild() is not static! It finds children of a parent. You need to call findChild on the widget which is parent of your QML object.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            1
            • D Offline
              D Offline
              davidino
              wrote on last edited by davidino
              #5

              Hello @jsulm ,
              you are right, I didn't read carefully the documentation. I tried several attempts and still I cannot figure it out. This is my last changing:

              void VolumeLevel::initVolume(QString qmlObjectName)
              {
                  if(parent() != nullptr) 
                  {
                      qDebug()<<"Parent name is: "<<parent()->objectName();
                      player = parent()->findChild<QMediaPlayer*>(qmlObjectName);
                      if(player != nullptr)
                          initVolume(player);
                      else
                          qDebug()<<"MediaPlayer not found "<<qmlObjectName;
                  }
              }
              
                  Item {
                      id: musicSystem
                      objectName: "musicSystem"
              
                      MediaPlayer {
                          id: playMusic
                          objectName: "mediaSystem"
                          autoLoad: true
                          autoPlay: true
                          playlist: Playlist{id:playerList}
                      }
                      Volume {id:volume; objectName: "volumeSystem"}
              
                      Component.onCompleted: volume.initVolume(playMusic.objectName)
                  }
              

              The result is the following, it can identify correctly musicSystem as the parent but not the mediaplayer
              Parent name is: "musicSystem"
              MediaPlayer not found "mediaSystem"

              I tried also with the approach:
              QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/music/MusicPage.qml")));
              QObject *object = component.create();
              but with no success.

              Thank you.
              Regards,
              Davide

              1 Reply Last reply
              0
              • D Offline
                D Offline
                davidino
                wrote on last edited by
                #6

                Here, you can find the solution.
                https://forum.qt.io/topic/115268/cast-a-qobject-to-qmediaplayer-with-qobject_cast

                Regards,
                Davidino

                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