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

* Updated the CMakeLists.txt under the root directory so it works with older...

* Updated the CMakeLists.txt under the root directory so it works with older versions of CMake now. Which is particularly useful for working with our Jenkins CI/CD workflow too, as it uses an older version of CMake to everything else.
* Made many more functions multithreaded with regards to the audio encoding/decoding code under Small World Deluxe itself.
* We're getting closer to successfully encoding audio at last with the same as above.
parent 5a73b043
Pipeline #1025 passed with stages
in 31 minutes and 19 seconds
......@@ -40,16 +40,32 @@
cmake_minimum_required(VERSION 3.5 FATAL_ERROR) # This version is needed to properly search for libpthreads
# https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/Useful-Variables#system-compiler-information
if(${CMAKE_VERSION} VERSION_GREATER "3.15.0")
cmake_policy(SET CMP0091 NEW)
cmake_policy(SET CMP0020 NEW)
cmake_policy(SET CMP0025 NEW)
#
# https://cmake.org/cmake/help/latest/policy/CMP0054.html
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.1.0")
cmake_policy(SET CMP0054 NEW)
endif()
CMAKE_POLICY(SET CMP0020 NEW)
cmake_policy(SET CMP0074 NEW)
cmake_policy(SET CMP0054 NEW)
cmake_policy(SET CMP0087 NEW)
cmake_policy(SET CMP0025 NEW)
#
# https://cmake.org/cmake/help/latest/policy/CMP0074.html
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.12.0")
cmake_policy(SET CMP0074 NEW)
endif()
#
# https://cmake.org/cmake/help/git-stage/policy/CMP0087.html
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14.0")
cmake_policy(SET CMP0087 NEW)
endif()
#
# https://cmake.org/cmake/help/git-stage/policy/CMP0091.html
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.15.0")
cmake_policy(SET CMP0091 NEW)
endif()
#
# RPATH is aimed at Linux installations primarily
......
......@@ -81,8 +81,8 @@ using namespace GkXmpp;
GkAudioEncoding::GkAudioEncoding(const QPointer<QBuffer> &audioInputBuf, const QPointer<QBuffer> &audioOutputBuf,
QPointer<GekkoFyre::GkLevelDb> database, QPointer<QAudioOutput> audioOutput,
QPointer<QAudioInput> audioInput, const GkDevice &output_device, const GkDevice &input_device,
QPointer<GekkoFyre::GkEventLogger> eventLogger, QObject *parent) : QObject(parent)
QPointer<QAudioInput> audioInput, QPointer<GekkoFyre::GkEventLogger> eventLogger,
QObject *parent) : QObject(parent)
{
setParent(parent);
gkDb = std::move(database);
......@@ -90,8 +90,6 @@ GkAudioEncoding::GkAudioEncoding(const QPointer<QBuffer> &audioInputBuf, const Q
gkAudioInput = std::move(audioInput);
gkAudioOutput = std::move(audioOutput);
gkInputDev = input_device;
gkOutputDev = output_device;
//
// Initialize variables
......@@ -396,20 +394,24 @@ void GkAudioEncoding::handleError(const QString &msg, const GkSeverity &severity
void GkAudioEncoding::processAudioInEncode(const GkAudioFramework::CodecSupport &codec, const qint32 &bitrate,
const qint32 &sample_rate, const qint32 &frame_size)
{
if (m_initialized) {
gkAudioInputBuf->seek(0);
m_buffer.append(gkAudioInputBuf->readAll());
while (!m_buffer.isEmpty()) {
if (codec == CodecSupport::Opus) {
encodeOpus(bitrate, sample_rate, frame_size);
} else if (codec == CodecSupport::OggVorbis) {
encodeVorbis(bitrate, sample_rate, frame_size);
} else if (codec == CodecSupport::FLAC) {
encodeFLAC(bitrate, sample_rate, frame_size);
} else {
throw std::invalid_argument(tr("The codec you have chosen is not supported as of yet, please try another!").toStdString());
try {
if (m_initialized) {
gkAudioInputBuf->seek(0);
m_buffer.append(gkAudioInputBuf->readAll());
while (!m_buffer.isEmpty()) {
if (codec == CodecSupport::Opus) {
encodeOpus(bitrate, sample_rate, frame_size);
} else if (codec == CodecSupport::OggVorbis) {
encodeVorbis(bitrate, sample_rate, frame_size);
} else if (codec == CodecSupport::FLAC) {
encodeFLAC(bitrate, sample_rate, frame_size);
} else {
throw std::invalid_argument(tr("The codec you have chosen is not supported as of yet, please try another!").toStdString());
}
}
}
} catch (const std::exception &e) {
}
return;
......
......@@ -129,9 +129,8 @@ class GkAudioEncoding : public QObject {
public:
explicit GkAudioEncoding(const QPointer<QBuffer> &audioInputBuf, const QPointer<QBuffer> &audioOutputBuf,
QPointer<GekkoFyre::GkLevelDb> database, QPointer<QAudioOutput> audioOutput,
QPointer<QAudioInput> audioInput, const GekkoFyre::Database::Settings::Audio::GkDevice &output_device,
const GekkoFyre::Database::Settings::Audio::GkDevice &input_device,
QPointer<GekkoFyre::GkEventLogger> eventLogger, QObject *parent = nullptr);
QPointer<QAudioInput> audioInput, QPointer<GekkoFyre::GkEventLogger> eventLogger,
QObject *parent = nullptr);
~GkAudioEncoding() override;
QString codecEnumToStr(const GkAudioFramework::CodecSupport &codec);
......@@ -172,8 +171,6 @@ private:
//
// QAudioSystem initialization and buffers
GekkoFyre::Database::Settings::Audio::GkDevice gkInputDev;
GekkoFyre::Database::Settings::Audio::GkDevice gkOutputDev;
QPointer<QAudioInput> gkAudioInput;
QPointer<QAudioOutput> gkAudioOutput;
......
......@@ -41,9 +41,7 @@
#include "src/pa_stream_handler.hpp"
#include <utility>
#include <algorithm>
#include <exception>
#include <QIODevice>
#include <QDateTime>
#include <QtEndian>
#include <QBuffer>
......@@ -130,6 +128,10 @@ GkPaStreamHandler::~GkPaStreamHandler()
}
}
if (m_recordMediaFileHelperThread.joinable()) {
m_recordMediaFileHelperThread.join();
}
return;
}
......@@ -276,7 +278,14 @@ void GkPaStreamHandler::playMediaFile(const QDir &media_path, const CodecSupport
void GkPaStreamHandler::recordMediaFile(const QFileInfo &media_path, const GkAudioFramework::CodecSupport &supported_codec,
qint32 encoding_bitrate, const GkDevice &audio_device)
{
recordMediaFileHelper(media_path, supported_codec, encoding_bitrate, audio_device);
if (m_recordMediaFileHelperThread.joinable()) {
m_recordMediaFileHelperThread.join();
}
m_recordMediaFileHelperThread = std::thread(&GkPaStreamHandler::recordMediaFileHelper, this, media_path, std::ref(supported_codec),
encoding_bitrate, std::ref(audio_device));
m_recordMediaFileHelperThread.detach();
return;
}
......@@ -290,8 +299,14 @@ void GkPaStreamHandler::recordMediaFile(const QFileInfo &media_path, const GkAud
void GkPaStreamHandler::recordMediaFile(const QDir &media_path, const CodecSupport &supported_codec,
qint32 encoding_bitrate, const GkDevice &audio_device)
{
if (m_recordMediaFileHelperThread.joinable()) {
m_recordMediaFileHelperThread.join();
}
const QFileInfo file_info_tmp(media_path.path());
recordMediaFileHelper(file_info_tmp, supported_codec, encoding_bitrate, audio_device);
m_recordMediaFileHelperThread = std::thread(&GkPaStreamHandler::recordMediaFileHelper, this, file_info_tmp, std::ref(supported_codec),
encoding_bitrate, std::ref(audio_device));
m_recordMediaFileHelperThread.detach();
return;
}
......@@ -420,6 +435,7 @@ void GkPaStreamHandler::recordingHandleStateChanged(QAudio::State changed_state)
*/
QFileInfo GkPaStreamHandler::createRecordMediaFile(const QFileInfo &media_path, const CodecSupport &supported_codec)
{
std::lock_guard<std::mutex> lock_guard(m_createRecordMediaFileInfoMutex);
const auto randStr = gkDb->createRandomString(16);
const auto epochSecs = QDateTime::currentSecsSinceEpoch();
const auto extension = gkDb->convCodecFormatToFileExtension(supported_codec);
......@@ -437,6 +453,7 @@ QFileInfo GkPaStreamHandler::createRecordMediaFile(const QFileInfo &media_path,
*/
QFileInfo GkPaStreamHandler::createRecordMediaFile(const QDir &media_path, const CodecSupport &supported_codec)
{
std::lock_guard<std::mutex> lock_guard(m_createRecordMediaFileDirMutex);
const auto randStr = gkDb->createRandomString(16);
const auto epochSecs = QDateTime::currentSecsSinceEpoch();
const auto extension = gkDb->convCodecFormatToFileExtension(supported_codec);
......@@ -452,8 +469,7 @@ QFileInfo GkPaStreamHandler::createRecordMediaFile(const QDir &media_path, const
* @param media_path
* @param supported_codec
*/
void GkPaStreamHandler::playMediaFileHelper(const QFileInfo &media_path, const CodecSupport &supported_codec,
const GkDevice &audio_device)
void GkPaStreamHandler::playMediaFileHelper(QFileInfo media_path, const CodecSupport &supported_codec, const GkDevice &audio_device)
{
try {
if (gkAudioOutput.isNull()) {
......@@ -511,12 +527,13 @@ void GkPaStreamHandler::playMediaFileHelper(const QFileInfo &media_path, const C
* @param supported_codec The codec you would like to make the recording with.
* @param encoding_bitrate The bitrate at which to encode with (i.e. 192 kbit/sec).
*/
void GkPaStreamHandler::recordMediaFileHelper(const QFileInfo &media_path, const CodecSupport &supported_codec,
void GkPaStreamHandler::recordMediaFileHelper(QFileInfo media_path, const CodecSupport &supported_codec,
qint32 encoding_bitrate, const GkDevice &audio_device)
{
try {
std::lock_guard<std::mutex> lock_guard(m_recordMediaFileHelperMutex);
if (encoding_bitrate >= 8) {
if (audio_device.is_enabled) {
if (!audio_device.audio_device_info.isNull()) {
//
// Make use of the Input Audio Device!
if (supported_codec == CodecSupport::Opus) {
......@@ -539,34 +556,10 @@ void GkPaStreamHandler::recordMediaFileHelper(const QFileInfo &media_path, const
procMediaEventLoop = new QEventLoop(this);
do {
procMediaEventLoop->exec(QEventLoop::WaitForMoreEvents);
} while (gkAudioInput->state() == QAudio::ActiveState);
delete procMediaEventLoop;
} else if (audio_device.is_enabled) {
//
// Make use of the Output Audio Device!
if (supported_codec == CodecSupport::Opus) {
//
// Create a media file with a randomized name within the given path, for recording purposes!
m_mediaFile = createRecordMediaFile(media_path, CodecSupport::Opus);
//
// Use a differing FRAME SIZE for Opus!
emit initEncode(m_mediaFile, audio_device, encoding_bitrate, supported_codec, AUDIO_OPUS_MAX_FRAME_SIZE);
} else {
//
// Create a media file with a randomized name within the given path, for recording purposes!
m_mediaFile = createRecordMediaFile(media_path, supported_codec);
//
// PCM, Ogg Vorbis, etc.
emit initEncode(m_mediaFile, audio_device, encoding_bitrate, supported_codec, AUDIO_FRAMES_PER_BUFFER);
}
procMediaEventLoop = new QEventLoop(this);
do {
procMediaEventLoop->exec(QEventLoop::WaitForMoreEvents);
} while (gkAudioInput->state() == QAudio::ActiveState);
if (!procMediaEventLoop.isNull()) {
procMediaEventLoop->exec(QEventLoop::WaitForMoreEvents);
}
} while (gkAudioInput->state() == QAudio::ActiveState && gkAudioEncoding->getRecStatus() == GkAudioRecordStatus::Active);
delete procMediaEventLoop;
} else {
//
......
......@@ -47,9 +47,11 @@
#include "src/gk_pcm_file_stream.hpp"
#include "src/gk_audio_encoding.hpp"
#include <AudioFile.h>
#include <mutex>
#include <memory>
#include <vector>
#include <string>
#include <thread>
#include <QDir>
#include <QMap>
#include <QObject>
......@@ -150,6 +152,13 @@ private:
QPointer<GekkoFyre::GkAudioEncoding> gkAudioEncoding;
QFileInfo m_mediaFile;
//
// Multithreading and mutexes
std::mutex m_recordMediaFileHelperMutex;
std::mutex m_createRecordMediaFileInfoMutex;
std::mutex m_createRecordMediaFileDirMutex;
std::thread m_recordMediaFileHelperThread;
//
// QAudioSystem initialization and buffers
QPointer<QEventLoop> procMediaEventLoop;
......@@ -157,9 +166,9 @@ private:
QPointer<QAudioOutput> gkAudioOutput;
QMap<QString, AudioFile<double>> gkSounds;
void playMediaFileHelper(const QFileInfo &media_path, const GekkoFyre::GkAudioFramework::CodecSupport &supported_codec,
void playMediaFileHelper(QFileInfo media_path, const GekkoFyre::GkAudioFramework::CodecSupport &supported_codec,
const GekkoFyre::Database::Settings::Audio::GkDevice &audio_device);
void recordMediaFileHelper(const QFileInfo &media_path, const GekkoFyre::GkAudioFramework::CodecSupport &supported_codec,
void recordMediaFileHelper(QFileInfo media_path, const GekkoFyre::GkAudioFramework::CodecSupport &supported_codec,
qint32 encoding_bitrate, const GekkoFyre::Database::Settings::Audio::GkDevice &audio_device);
};
......
......@@ -351,10 +351,20 @@ void GkAudioPlayDialog::on_pushButton_playback_record_clicked()
emit recStatus(GkAudioRecordStatus::Active);
switch (ui->comboBox_playback_rec_source->currentIndex()) {
case AUDIO_RECORDING_SOURCE_INPUT_IDX:
gkPaAudioPlayer->record(codec_used, m_recordDirPath, pref_input_device);
{
auto rec_future = std::async(std::launch::deferred, &GkPaAudioPlayer::record, gkPaAudioPlayer, std::ref(codec_used),
std::ref(m_recordDirPath), std::ref(pref_output_device));
rec_future.get();
}
break;
case AUDIO_RECORDING_SOURCE_OUTPUT_IDX:
gkPaAudioPlayer->record(codec_used, m_recordDirPath, pref_output_device);
{
auto rec_future = std::async(std::launch::deferred, &GkPaAudioPlayer::record, gkPaAudioPlayer, std::ref(codec_used),
std::ref(m_recordDirPath), std::ref(pref_output_device));
rec_future.get();
}
break;
default:
throw std::invalid_argument(tr("Invalid argument provided for audio device determination, when attempting to record!").toStdString());
......@@ -366,7 +376,7 @@ void GkAudioPlayDialog::on_pushButton_playback_record_clicked()
}
} else {
throw std::invalid_argument(tr("Unable to use directory, \"%1\", for reading and/or writing!")
.arg(m_recordDirPath.path()).toStdString());
.arg(m_recordDirPath.path()).toStdString());
}
} else {
//
......
......@@ -734,7 +734,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
//
// Initialize the audio codec encoding/decoding libraries!
//
gkAudioEncoding = new GkAudioEncoding(gkAudioInputBuf, gkAudioOutputBuf, gkDb, gkAudioOutput, gkAudioInput, pref_output_device, pref_input_device, gkEventLogger, &gkAudioEncodingThread);
gkAudioEncoding = new GkAudioEncoding(gkAudioInputBuf, gkAudioOutputBuf, gkDb, gkAudioOutput, gkAudioInput, gkEventLogger, &gkAudioEncodingThread);
gkAudioEncoding->moveToThread(&gkAudioEncodingThread);
QObject::connect(&gkAudioEncodingThread, &QThread::finished, gkAudioEncoding, &QObject::deleteLater);
gkAudioEncodingThread.start();
......
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