File indexing completed on 2024-06-23 05:42:09

0001 /*
0002  * Copyright 2023 by Aditya Mehra <aix.m@outlook.com>
0003  *
0004  * Licensed under the Apache License, Version 2.0 (the "License");
0005  * you may not use this file except in compliance with the License.
0006  * You may obtain a copy of the License at
0007  *
0008  *    http://www.apache.org/licenses/LICENSE-2.0
0009  *
0010  * Unless required by applicable law or agreed to in writing, software
0011  * distributed under the License is distributed on an "AS IS" BASIS,
0012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013  * See the License for the specific language governing permissions and
0014  * limitations under the License.
0015  *
0016  */
0017 
0018 #pragma once
0019 
0020 #include <QIODevice>
0021 #include <QBuffer>
0022 #include <QAudioDecoder>
0023 #include <QAudioFormat>
0024 #include <QFile>
0025 #include "thirdparty/fftcalc.h"
0026 
0027 class AudioStreamDevice : public QIODevice
0028 {
0029     Q_OBJECT
0030 
0031 public:
0032     explicit AudioStreamDevice(QObject *parent = nullptr);
0033     bool init(const QAudioFormat& format);
0034     bool uninit();
0035 
0036     enum State { Playing, Stopped };
0037 
0038     void play(const QUrl &file);
0039     void stop();
0040 
0041     bool atEnd() const override;
0042 
0043     QVector<double> spectrum() const;
0044 
0045     void calculateSpectrum(QAudioBuffer buffer);
0046 
0047     qint64 duration() const;
0048     qint64 position() const;
0049 
0050     void seekFrom(qint64 position);
0051     void handleError(QAudioDecoder::Error error);
0052 
0053 protected:
0054     qint64 readData(char* data, qint64 maxlen) override;
0055     qint64 writeData(const char* data, qint64 len) override;
0056 
0057 private:
0058     QFile m_file;
0059     QBuffer m_input;
0060     QBuffer m_output;
0061     QByteArray m_data;
0062     QAudioDecoder m_decoder;
0063     QAudioFormat m_format;
0064     FFTCalc *calculator;
0065     QVector<double> sample;
0066     QVector<double> m_spectrum;
0067     double levelLeft, levelRight;
0068     qint64 m_calculatedDuration;
0069 
0070     State m_state;
0071 
0072     bool isInited;
0073     bool isDecodingFinished;
0074 
0075     void clear();
0076 
0077 private slots:
0078     void bufferReady();
0079     void finished();
0080 
0081 signals:
0082     void stateChanged(AudioStreamDevice::State state);
0083     void newData(const QByteArray& data);
0084     int levels(double left, double right);
0085     void spectrumChanged(QVector<double> spectrum);
0086     void invalidMedia();
0087     void endOfMedia();
0088     void bufferingMedia();
0089     void bufferedMedia();
0090     void stalledMedia();
0091     void decodeFinished();
0092     void durationChanged(qint64 duration);
0093     void positionChanged(qint64 position);
0094     void errorDecoding(QAudioDecoder::Error error);
0095 };