File indexing completed on 2024-04-28 08:43:35

0001 /*
0002 SPDX-FileCopyrightText: 2019 Akhil K Gangadharan <akhilam512@gmail.com>
0003 This file is part of Kdenlive. See www.kdenlive.org.
0004 
0005 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006 */
0007 
0008 #pragma once
0009 
0010 #include <QAudioBuffer>
0011 #include <QAudioInput>
0012 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0013 #include <QAudioRecorder>
0014 #else
0015 #include <QMediaCaptureSession>
0016 #endif
0017 #include <QCamera>
0018 #include <QElapsedTimer>
0019 #include <QIODevice>
0020 #include <QMediaRecorder>
0021 #include <QMutex>
0022 #include <QStringList>
0023 #include <QTimer>
0024 #include <QUrl>
0025 #include <memory>
0026 
0027 class AudioDevInfo: public QIODevice
0028 {
0029     Q_OBJECT
0030 public:
0031     AudioDevInfo(const QAudioFormat &format, QObject *parent = nullptr);
0032     quint32 maxAmplitude = 0;
0033 
0034 Q_SIGNALS:
0035     void levelChanged(const QVector<qreal> &dbLevels);
0036     void levelRecChanged(const QVector<qreal> &dbLevels);
0037 
0038 protected:
0039     qint64 readData(char *data, qint64 maxSize) override;
0040     qint64 writeData(const char *data, qint64 maxSize) override;
0041 private:
0042     const QAudioFormat m_format;
0043 };
0044 
0045 class MediaCapture : public QObject
0046 {
0047     Q_OBJECT
0048     Q_PROPERTY(QVector<qreal> levels READ levels NOTIFY levelsChanged)
0049     Q_PROPERTY(int recordState READ recordState NOTIFY recordStateChanged)
0050     Q_PROPERTY(int recDuration READ recDuration NOTIFY recDurationChanged)
0051 
0052 public:
0053     MediaCapture(QObject *parent);
0054     ~MediaCapture() override;
0055     void recordAudio(int tid, bool record);
0056     // TODO: fix video capture
0057     // void recordVideo(int tid, bool /*record*/);
0058     /** @brief Returns true if a recording is in progress **/
0059     bool isRecording() const;
0060     /** @brief Sets m_path to selected output location **/
0061     void setCaptureOutputLocation();
0062     /** @brief Returns m_path **/
0063     QUrl getCaptureOutputLocation();
0064     /** @brief Sets m_audioDevice to selected audio capture device **/
0065     void setAudioCaptureDevice();
0066     /** @brief Returns list of audio devices available for capture **/
0067     QStringList getAudioCaptureDevices();
0068     /** @brief Sets currentState to QMediaRecorder::State value and returns it **/
0069     int getState();
0070     int currentState;
0071     Q_INVOKABLE QVector<qreal> levels() const;
0072     Q_INVOKABLE int recordState() const;
0073     Q_INVOKABLE int recDuration() const;
0074     void switchMonitorState(bool run);
0075     /** @brief Returns true is audio monitoring is currently in progress **/
0076     bool isMonitoring() const;
0077     const QVector<double> recLevels() const;
0078     /** @brief Start monitoring a track **/
0079     Q_INVOKABLE void switchMonitorState(int tid, bool run);
0080     void pauseRecording();
0081     void resumeRecording();
0082     /** @brief Start the real audio capture **/
0083     int startCapture();
0084 
0085 public Q_SLOTS:
0086     void displayErrorMessage();
0087     /** @brief Sets m_volume to selected audio capture volume **/
0088     void setAudioVolume();
0089 
0090 private:
0091 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0092     std::unique_ptr<QAudioRecorder> m_audioRecorder;
0093 #else
0094     // TODO: Qt6
0095     // std::unique_ptr<QMediaCaptureSession> m_mediaCapture;
0096 #endif
0097     std::unique_ptr<QAudioInput> m_audioInput;
0098     QScopedPointer<AudioDevInfo> m_audioInfo;
0099     std::unique_ptr<QMediaRecorder> m_videoRecorder;
0100     std::unique_ptr<QCamera> m_camera;
0101     QElapsedTimer m_recTimer;
0102     QString m_audioDevice;
0103     QUrl m_path;
0104     QVector<qreal> m_levels;
0105     QVector<double> m_recLevels;
0106     int m_recordState;
0107     /** @brief Last recorded frame */
0108     int m_lastPos;
0109     /** @brief Duration of pre-pause recording */
0110     int m_recOffset;
0111     int m_tid;
0112     /** @brief true if we started the record countdown */
0113     bool m_readyForRecord;
0114     QTimer m_resetTimer;
0115     QMutex m_recMutex;
0116 
0117 private Q_SLOTS:
0118     void resetIfUnused();
0119 
0120 Q_SIGNALS:
0121     void levelsChanged();
0122     void recordStateChanged(int tid, bool recording);
0123     void recordDone();
0124     void audioLevels(QVector<qreal> levels);
0125     void recDurationChanged();
0126 };