File indexing completed on 2024-04-28 04:51:59

0001 /*
0002     SPDX-FileCopyrightText: 2012 Simon Andreas Eugster <simon.eu@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 "audioInfo.h"
0011 #include <QFutureWatcher>
0012 #include <QObject>
0013 #include <memory>
0014 #include <mlt++/Mlt.h>
0015 #include <vector>
0016 
0017 class QImage;
0018 
0019 /**
0020   The audio envelope is a simplified version of an audio track
0021   with frame resolution. One entry is calculated by the sum
0022   of the absolute values of all samples in the current frame.
0023 
0024   See also: http://web.archive.org/web/20180626235917/http://bemasc.net/wordpress/2011/07/26/an-auto-aligner-for-pitivi/
0025   */
0026 class AudioEnvelope : public QObject
0027 {
0028     Q_OBJECT
0029 
0030 public:
0031     explicit AudioEnvelope(const QString &binId, int clipId, size_t offset = 0, size_t length = 0, size_t startPos = 0);
0032     ~AudioEnvelope() override;
0033     /**
0034        Starts the asynchronous computation that computes the
0035        envelope. When the computations are done, the signal
0036        'envelopeReady' will be emitted.
0037     */
0038     void startComputeEnvelope();
0039 
0040     /**
0041        Returns whether startComputeEnvelope() has been called.
0042     */
0043     bool hasComputationStarted() const;
0044 
0045     /**
0046        Returns the envelope data. Blocks until the computation of the
0047        envelope is done.
0048        REQUIRES: startComputeEnvelope() has been called.
0049     */
0050     const std::vector<qint64> &envelope();
0051 
0052     QImage drawEnvelope();
0053 
0054     size_t offset();
0055 
0056     void dumpInfo();
0057 
0058     int clipId() const;
0059     size_t startPos() const;
0060 
0061 private:
0062     struct AudioSummary
0063     {
0064         explicit AudioSummary(size_t size)
0065             : audioAmplitudes(size)
0066         {
0067         }
0068         AudioSummary() = default;
0069         // This is the envelope data. There is one element for each
0070         // frame, which contains the sum of the absolute amplitudes of
0071         // the audio signal for that frame.
0072         std::vector<qint64> audioAmplitudes;
0073         // Maximum absolute value of the elements in 'audioAmplitudes'.
0074         qint64 amplitudeMax = 0;
0075     };
0076 
0077     /**
0078        Blocks until the AudioSummary has been computed.
0079        REQUIRES: startComputeEnvelope() has been called.
0080     */
0081     const AudioSummary &audioSummary();
0082 
0083     /**
0084      Actually computes the envelope data, synchronously.
0085     */
0086     AudioSummary loadAndNormalizeEnvelope() const;
0087 
0088     std::shared_ptr<Mlt::Producer> m_producer;
0089     std::unique_ptr<AudioInfo> m_info;
0090     QFutureWatcher<AudioSummary> m_watcher;
0091     QFuture<AudioSummary> m_audioSummary;
0092 
0093     size_t m_offset;
0094     const int m_clipId;
0095     const size_t m_startpos;
0096     size_t m_envelopeSize;
0097 
0098 Q_SIGNALS:
0099     void envelopeReady(AudioEnvelope *envelope);
0100 };