Verified Commit 0745e07d authored by Phobos D'thorga's avatar Phobos D'thorga 🐲
Browse files

* Restored the FFT Spectrograph so that there's, once again, a single...

* Restored the FFT Spectrograph so that there's, once again, a single universal pool for the QBuffer origin.
parent 437d8430
Pipeline #1036 passed with stages
in 25 minutes and 28 seconds
...@@ -78,8 +78,9 @@ using namespace Network; ...@@ -78,8 +78,9 @@ using namespace Network;
using namespace GkXmpp; using namespace GkXmpp;
GkAudioEncoding::GkAudioEncoding(QPointer<GekkoFyre::GkLevelDb> database, QPointer<QAudioOutput> audioOutput, GkAudioEncoding::GkAudioEncoding(QPointer<GekkoFyre::GkLevelDb> database, QPointer<QAudioOutput> audioOutput,
QPointer<QAudioInput> audioInput, QPointer<GekkoFyre::StringFuncs> stringFuncs, QPointer<QAudioInput> audioInput, QPointer<QBuffer> audioInputBuf,
QPointer<GekkoFyre::GkEventLogger> eventLogger, QObject *parent) : QObject(parent) QPointer<GekkoFyre::StringFuncs> stringFuncs, QPointer<GekkoFyre::GkEventLogger> eventLogger,
QObject *parent) : QObject(parent)
{ {
setParent(parent); setParent(parent);
gkDb = std::move(database); gkDb = std::move(database);
...@@ -88,6 +89,7 @@ GkAudioEncoding::GkAudioEncoding(QPointer<GekkoFyre::GkLevelDb> database, QPoint ...@@ -88,6 +89,7 @@ GkAudioEncoding::GkAudioEncoding(QPointer<GekkoFyre::GkLevelDb> database, QPoint
gkAudioInput = std::move(audioInput); gkAudioInput = std::move(audioInput);
gkAudioOutput = std::move(audioOutput); gkAudioOutput = std::move(audioOutput);
gkAudioInputBuf = std::move(audioInputBuf);
// //
// Initialize variables // Initialize variables
...@@ -104,11 +106,6 @@ GkAudioEncoding::GkAudioEncoding(QPointer<GekkoFyre::GkLevelDb> database, QPoint ...@@ -104,11 +106,6 @@ GkAudioEncoding::GkAudioEncoding(QPointer<GekkoFyre::GkLevelDb> database, QPoint
QObject::connect(this, SIGNAL(recStatus(const GekkoFyre::GkAudioFramework::GkAudioRecordStatus &)), QObject::connect(this, SIGNAL(recStatus(const GekkoFyre::GkAudioFramework::GkAudioRecordStatus &)),
this, SLOT(setRecStatus(const GekkoFyre::GkAudioFramework::GkAudioRecordStatus &))); this, SLOT(setRecStatus(const GekkoFyre::GkAudioFramework::GkAudioRecordStatus &)));
//
// Setup I/O!
m_audioInputBuf = gkAudioInput->start();
QObject::connect(m_audioInputBuf, &QIODevice::readyRead, this, &GkAudioEncoding::onReadyRead);
return; return;
} }
...@@ -345,6 +342,21 @@ void GkAudioEncoding::setRecStatus(const GekkoFyre::GkAudioFramework::GkAudioRec ...@@ -345,6 +342,21 @@ void GkAudioEncoding::setRecStatus(const GekkoFyre::GkAudioFramework::GkAudioRec
return; return;
} }
/**
* @brief GkAudioEncoding::procAudioInBuffer works coincide with the MainWindow::processAudioInMainBuffer() function from
* the body of the Small World Deluxe application, to update the main QAudioInput buffer(s) associated with any audio
* devices.
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
* @see MainWindow::processAudioInMainBuffer().
*/
void GkAudioEncoding::procAudioInBuffer()
{
gkAudioInputBuf->seek(0);
m_buffer.append(gkAudioInputBuf->readAll());
return;
}
/** /**
* @brief GkAudioEncoding::encodeOpus will perform an encoding with the Ogg Opus library and its parameters. * @brief GkAudioEncoding::encodeOpus will perform an encoding with the Ogg Opus library and its parameters.
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>, * @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>,
...@@ -418,8 +430,17 @@ void GkAudioEncoding::encodeOpus(const qint32 &bitrate, qint32 sample_rate, cons ...@@ -418,8 +430,17 @@ void GkAudioEncoding::encodeOpus(const qint32 &bitrate, qint32 sample_rate, cons
.arg(media_path.fileName(), gkStringFuncs->handleOpusError(err)).toStdString()); .arg(media_path.fileName(), gkStringFuncs->handleOpusError(err)).toStdString());
} }
//
// https://stackoverflow.com/questions/46786922/how-to-confirm-opus-encode-buffer-size
qint32 frame_size = AUDIO_OPUS_FRAMES_PER_BUFFER;
if (sample_rate == 48000) {
//
// The frame-size must therefore be 10 milliseconds for stereo!
frame_size = ((48000 / 1000) * 2) * 10;
}
qint32 ret = m_buffer.size(); qint32 ret = m_buffer.size();
while (1) { while (m_recActive == GkAudioRecordStatus::Active) {
if (ret > 0) { if (ret > 0) {
opus_int16 input_frame[AUDIO_OPUS_FRAMES_PER_BUFFER] = {}; opus_int16 input_frame[AUDIO_OPUS_FRAMES_PER_BUFFER] = {};
const qint32 total_bytes_ready = m_buffer.size(); const qint32 total_bytes_ready = m_buffer.size();
...@@ -430,15 +451,6 @@ void GkAudioEncoding::encodeOpus(const qint32 &bitrate, qint32 sample_rate, cons ...@@ -430,15 +451,6 @@ void GkAudioEncoding::encodeOpus(const qint32 &bitrate, qint32 sample_rate, cons
input_frame[j] = qFromLittleEndian<opus_int16>(m_buffer.data() + j * sizeof(opus_int16)); input_frame[j] = qFromLittleEndian<opus_int16>(m_buffer.data() + j * sizeof(opus_int16));
} }
//
// https://stackoverflow.com/questions/46786922/how-to-confirm-opus-encode-buffer-size
qint32 frame_size = AUDIO_OPUS_FRAMES_PER_BUFFER;
if (sample_rate == 48000) {
//
// The frame-size must therefore be 10 milliseconds for stereo!
frame_size = ((48000 / 1000) * 2) * 10;
}
// //
// Encode the frame... // Encode the frame...
const opus_int32 nbBytes = ope_encoder_write(m_opusEncoder, input_frame, frame_size); const opus_int32 nbBytes = ope_encoder_write(m_opusEncoder, input_frame, frame_size);
...@@ -449,7 +461,7 @@ void GkAudioEncoding::encodeOpus(const qint32 &bitrate, qint32 sample_rate, cons ...@@ -449,7 +461,7 @@ void GkAudioEncoding::encodeOpus(const qint32 &bitrate, qint32 sample_rate, cons
} }
m_totalCompBytesWritten += nbBytes; m_totalCompBytesWritten += nbBytes;
emit bytesRead(m_totalCompBytesWritten, false); emit bytesRead(m_totalCompBytesWritten, false); // Emit the total amount of compressed bytes written!
// //
// Commit out the memory buffer to the file itself! // Commit out the memory buffer to the file itself!
...@@ -620,16 +632,6 @@ void GkAudioEncoding::encodeFLAC(const qint32 &bitrate, qint32 sample_rate, cons ...@@ -620,16 +632,6 @@ void GkAudioEncoding::encodeFLAC(const qint32 &bitrate, qint32 sample_rate, cons
return; return;
} }
/**
* @brief GkAudioEncoding::onReadyRead
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
*/
void GkAudioEncoding::onReadyRead()
{
m_buffer.append(m_audioInputBuf->readAll()); // Record QAudioInput to the buffer object, `m_buffer`!
return;
}
/** /**
* @brief GkAudioEncoding::opusCleanup cleans up after the Opus multimedia encoder in a neat and tidy fashion, all * @brief GkAudioEncoding::opusCleanup cleans up after the Opus multimedia encoder in a neat and tidy fashion, all
* contained within the one function. * contained within the one function.
......
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include "src/gk_string_funcs.hpp" #include "src/gk_string_funcs.hpp"
#include <sndfile.h> #include <sndfile.h>
#include <sndfile.hh> #include <sndfile.hh>
#include <opus/opusenc.h>
#include <mutex> #include <mutex>
#include <thread> #include <thread>
#include <cstdio> #include <cstdio>
...@@ -129,8 +128,9 @@ class GkAudioEncoding : public QObject { ...@@ -129,8 +128,9 @@ class GkAudioEncoding : public QObject {
public: public:
explicit GkAudioEncoding(QPointer<GekkoFyre::GkLevelDb> database, QPointer<QAudioOutput> audioOutput, explicit GkAudioEncoding(QPointer<GekkoFyre::GkLevelDb> database, QPointer<QAudioOutput> audioOutput,
QPointer<QAudioInput> audioInput, QPointer<GekkoFyre::StringFuncs> stringFuncs, QPointer<QAudioInput> audioInput, QPointer<QBuffer> audioInputBuf,
QPointer<GekkoFyre::GkEventLogger> eventLogger, QObject *parent = nullptr); QPointer<GekkoFyre::StringFuncs> stringFuncs, QPointer<GekkoFyre::GkEventLogger> eventLogger,
QObject *parent = nullptr);
~GkAudioEncoding() override; ~GkAudioEncoding() override;
QString codecEnumToStr(const GkAudioFramework::CodecSupport &codec); QString codecEnumToStr(const GkAudioFramework::CodecSupport &codec);
...@@ -143,6 +143,7 @@ public slots: ...@@ -143,6 +143,7 @@ public slots:
void stopEncode(); void stopEncode();
void setRecStatus(const GekkoFyre::GkAudioFramework::GkAudioRecordStatus &status); void setRecStatus(const GekkoFyre::GkAudioFramework::GkAudioRecordStatus &status);
void procAudioInBuffer();
private slots: private slots:
void stopCaller(); void stopCaller();
...@@ -155,8 +156,6 @@ private slots: ...@@ -155,8 +156,6 @@ private slots:
void encodeFLAC(const qint32 &bitrate, qint32 sample_rate, const GekkoFyre::Database::Settings::GkAudioSource &audio_src, void encodeFLAC(const qint32 &bitrate, qint32 sample_rate, const GekkoFyre::Database::Settings::GkAudioSource &audio_src,
const QFileInfo &media_path, const qint32 &frame_size = AUDIO_FRAMES_PER_BUFFER); const QFileInfo &media_path, const qint32 &frame_size = AUDIO_FRAMES_PER_BUFFER);
void onReadyRead();
signals: signals:
void pauseEncode(); void pauseEncode();
...@@ -176,6 +175,7 @@ private: ...@@ -176,6 +175,7 @@ private:
// QAudioSystem initialization and buffers // QAudioSystem initialization and buffers
QPointer<QAudioInput> gkAudioInput; QPointer<QAudioInput> gkAudioInput;
QPointer<QAudioOutput> gkAudioOutput; QPointer<QAudioOutput> gkAudioOutput;
QPointer<QBuffer> gkAudioInputBuf;
qint64 m_totalUncompBytesRead; qint64 m_totalUncompBytesRead;
qint64 m_totalCompBytesWritten; qint64 m_totalCompBytesWritten;
...@@ -186,7 +186,6 @@ private: ...@@ -186,7 +186,6 @@ private:
// //
// Encoder variables // Encoder variables
bool m_initialized = false; // Whether an encoding operation has begun or not; therefore block other attempts until this singular one has stopped. bool m_initialized = false; // Whether an encoding operation has begun or not; therefore block other attempts until this singular one has stopped.
QPointer<QIODevice> m_audioInputBuf; // The QIODevice for this particular audio device.
QByteArray m_buffer; // A QByteArray, providing more readily accessible information as needed by the FLAC, Ogg Vorbis, Ogg Opus, etc. encoders. QByteArray m_buffer; // A QByteArray, providing more readily accessible information as needed by the FLAC, Ogg Vorbis, Ogg Opus, etc. encoders.
QPointer<QBuffer> m_encoded_buf; // For holding the encoded data whether it be FLAC, Ogg Vorbis, Ogg Opus, etc. as calculated from `record_input_buf`. QPointer<QBuffer> m_encoded_buf; // For holding the encoded data whether it be FLAC, Ogg Vorbis, Ogg Opus, etc. as calculated from `record_input_buf`.
SndfileHandle m_handle_in; // The libsndfile handler, for all related operations such as reading, writing (and hence conversion), etc. SndfileHandle m_handle_in; // The libsndfile handler, for all related operations such as reading, writing (and hence conversion), etc.
...@@ -210,7 +209,6 @@ private: ...@@ -210,7 +209,6 @@ private:
std::thread m_encodeFLACThread; std::thread m_encodeFLACThread;
void opusCleanup(); void opusCleanup();
void processByteArray();
}; };
}; };
...@@ -735,7 +735,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi ...@@ -735,7 +735,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
// //
// Initialize the audio codec encoding/decoding libraries! // Initialize the audio codec encoding/decoding libraries!
// //
gkAudioEncoding = new GkAudioEncoding(gkDb, gkAudioOutput, gkAudioInput, gkStringFuncs, gkEventLogger, &gkAudioInputThread); gkAudioEncoding = new GkAudioEncoding(gkDb, gkAudioOutput, gkAudioInput, gkAudioInputBuf, gkStringFuncs, gkEventLogger, &gkAudioInputThread);
gkAudioEncoding->moveToThread(&gkAudioInputThread); gkAudioEncoding->moveToThread(&gkAudioInputThread);
QObject::connect(&gkAudioInputThread, &QThread::finished, gkAudioEncoding, &QObject::deleteLater); QObject::connect(&gkAudioInputThread, &QThread::finished, gkAudioEncoding, &QObject::deleteLater);
...@@ -757,7 +757,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi ...@@ -757,7 +757,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
// Enable updating and clearing of QBuffer pointers across Small World Deluxe! // Enable updating and clearing of QBuffer pointers across Small World Deluxe!
QObject::connect(this, SIGNAL(updateAudioIn()), this, SLOT(processAudioInMainBuffer())); QObject::connect(this, SIGNAL(updateAudioIn()), this, SLOT(processAudioInMainBuffer()));
QObject::connect(this, SIGNAL(updateAudioIn()), gkFftAudio, SLOT(processAudioInFft())); QObject::connect(this, SIGNAL(updateAudioIn()), gkFftAudio, SLOT(processAudioInFft()));
QObject::connect(this, SIGNAL(updateAudioIn()), gkAudioEncoding, SLOT(processAudioInEncode())); QObject::connect(this, SIGNAL(updateAudioIn()), gkAudioEncoding, SLOT(procAudioInBuffer()));
// //
// Allow the changing of Audio I/O with regard to recording audio streams // Allow the changing of Audio I/O with regard to recording audio streams
...@@ -2588,7 +2588,7 @@ void MainWindow::processAudioInMain() ...@@ -2588,7 +2588,7 @@ void MainWindow::processAudioInMain()
} }
/** /**
* @brief MainWindow::processAudioInMainBuffer * @brief MainWindow::procAudioInBuffer
* @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io> * @author Phobos A. D'thorga <phobos.gekko@gekkofyre.io>
*/ */
void MainWindow::processAudioInMainBuffer() void MainWindow::processAudioInMainBuffer()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment