From 8df4cf2cdcd5f65cd947d444dbae6e77cc05a5e7 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 27 Sep 2019 03:01:09 +1000 Subject: [PATCH] audiomanager implementation --- app/audio/audiomanager.cpp | 82 +++++++++++++++++++ app/audio/audiomanager.h | 23 ++++++ app/common/rational.cpp | 6 ++ app/common/rational.h | 3 + app/core.cpp | 2 + app/dialog/preferences/preferences.cpp | 1 + .../tabs/preferencesgeneraltab.cpp | 16 ++-- app/widget/viewer/viewer.cpp | 8 ++ app/window/mainwindow/mainwindow.cpp | 5 ++ 9 files changed, 139 insertions(+), 7 deletions(-) diff --git a/app/audio/audiomanager.cpp b/app/audio/audiomanager.cpp index a03faf166..c0e0ce81e 100644 --- a/app/audio/audiomanager.cpp +++ b/app/audio/audiomanager.cpp @@ -20,6 +20,8 @@ #include "audiomanager.h" +#include "config/config.h" + AudioManager* AudioManager::audio_ = nullptr; void AudioManager::CreateInstance() @@ -59,6 +61,51 @@ bool AudioManager::IsRefreshing() return refreshing_devices_; } +#include +void AudioManager::StartOutput(QIODevice *device) +{ + if (output_ == nullptr) { + return; + } + + output_file_ = device; + + output_->start(output_file_); +} + +void AudioManager::StopOutput() +{ + if (output_ == nullptr) { + return; + } + + output_->stop(); + + output_file_->close(); + delete output_file_; + output_file_ = nullptr; +} + +void AudioManager::SetOutputDevice(const QAudioDeviceInfo &info) +{ + QAudioFormat format; + format.setSampleRate(44100); + format.setChannelCount(2); + format.setSampleSize(32); + format.setCodec("audio/pcm"); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setSampleType(QAudioFormat::Float); + + output_ = std::unique_ptr(new QAudioOutput(info, format, this)); + output_device_info_ = info; +} + +void AudioManager::SetInputDevice(const QAudioDeviceInfo &info) +{ + input_ = std::unique_ptr(new QAudioInput(info, QAudioFormat(), this)); + input_device_info_ = info; +} + const QList &AudioManager::ListInputDevices() { return input_devices_; @@ -71,6 +118,9 @@ const QList &AudioManager::ListOutputDevices() AudioManager::AudioManager() : output_(nullptr), + output_file_(nullptr), + input_(nullptr), + input_file_(nullptr), refreshing_devices_(false) { RefreshDevices(); @@ -85,6 +135,38 @@ void AudioManager::RefreshThreadDone() refreshing_devices_ = false; + QString preferred_audio_output = Config::Current()["PreferredAudioOutput"].toString(); + + if (output_ == nullptr + || (!preferred_audio_output.isEmpty() && output_device_info_.deviceName() != preferred_audio_output)) { + if (preferred_audio_output.isEmpty()) { + SetOutputDevice(QAudioDeviceInfo::defaultOutputDevice()); + } else { + foreach (const QAudioDeviceInfo& info, output_devices_) { + if (info.deviceName() == preferred_audio_output) { + SetOutputDevice(info); + break; + } + } + } + } + + QString preferred_audio_input = Config::Current()["PreferredAudioInput"].toString(); + + if (input_ == nullptr + || (!preferred_audio_input.isEmpty() && input_device_info_.deviceName() != preferred_audio_input)) { + if (preferred_audio_input.isEmpty()) { + SetInputDevice(QAudioDeviceInfo::defaultInputDevice()); + } else { + foreach (const QAudioDeviceInfo& info, input_devices_) { + if (info.deviceName() == preferred_audio_input) { + SetInputDevice(info); + break; + } + } + } + } + emit DeviceListReady(); } diff --git a/app/audio/audiomanager.h b/app/audio/audiomanager.h index 75778ee61..7cbf6df3b 100644 --- a/app/audio/audiomanager.h +++ b/app/audio/audiomanager.h @@ -22,6 +22,7 @@ #define AUDIOMANAGER_H #include +#include #include #include @@ -61,6 +62,22 @@ public: bool IsRefreshing(); + /** + * @brief Start playing audio from QIODevice + * + * This takes ownership of the QIODevice and will delete it when StopOutput() is called + */ + void StartOutput(QIODevice* device); + + /** + * @brief Stop audio output + */ + void StopOutput(); + + void SetOutputDevice(const QAudioDeviceInfo& info); + + void SetInputDevice(const QAudioDeviceInfo& info); + const QList& ListInputDevices(); const QList& ListOutputDevices(); @@ -77,6 +94,12 @@ private: static AudioManager* audio_; std::unique_ptr output_; + QAudioDeviceInfo output_device_info_; + QIODevice* output_file_; + + std::unique_ptr input_; + QAudioDeviceInfo input_device_info_; + QIODevice* input_file_; bool refreshing_devices_; diff --git a/app/common/rational.cpp b/app/common/rational.cpp index 2246ce427..9286a8e97 100644 --- a/app/common/rational.cpp +++ b/app/common/rational.cpp @@ -106,6 +106,12 @@ int rational::getActiveInstances() return activeInstances; } +rational::operator QString() const +{ + return QString("%1/%2").arg(QString::number(numer), + QString::number(denom)); +} + const intType &rational::numerator() const { return numer; diff --git a/app/common/rational.h b/app/common/rational.h index ea01425dc..225877112 100644 --- a/app/common/rational.h +++ b/app/common/rational.h @@ -7,6 +7,7 @@ #define RATIONAL_H #include +#include #include extern "C" { @@ -114,6 +115,8 @@ public: friend ostream& operator<<(ostream &out, const rational &value); friend istream& operator>>(istream &in, rational &value); + operator QString() const; + const intType& numerator() const; const intType& denominator() const; diff --git a/app/core.cpp b/app/core.cpp index 6f7f1c9a0..15e2a32f1 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -106,6 +106,8 @@ void Core::Start() void Core::Stop() { + AudioManager::DestroyInstance(); + delete main_window_; } diff --git a/app/dialog/preferences/preferences.cpp b/app/dialog/preferences/preferences.cpp index bf48487f9..28848beb3 100644 --- a/app/dialog/preferences/preferences.cpp +++ b/app/dialog/preferences/preferences.cpp @@ -42,6 +42,7 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, QMenuBar* main_menu_bar) : QVBoxLayout* layout = new QVBoxLayout(this); QSplitter* splitter = new QSplitter(); + splitter->setChildrenCollapsible(false); layout->addWidget(splitter); list_widget_ = new QListWidget(); diff --git a/app/dialog/preferences/tabs/preferencesgeneraltab.cpp b/app/dialog/preferences/tabs/preferencesgeneraltab.cpp index a03362062..0039efa09 100644 --- a/app/dialog/preferences/tabs/preferencesgeneraltab.cpp +++ b/app/dialog/preferences/tabs/preferencesgeneraltab.cpp @@ -51,7 +51,7 @@ PreferencesGeneralTab::PreferencesGeneralTab() } */ - general_layout->addWidget(language_combobox, row, 1, 1, 4); + general_layout->addWidget(language_combobox, row, 1); row++; @@ -61,19 +61,21 @@ PreferencesGeneralTab::PreferencesGeneralTab() thumbnail_res_spinbox = new QSpinBox(this); thumbnail_res_spinbox->setMinimum(0); thumbnail_res_spinbox->setMaximum(INT_MAX); - //thumbnail_res_spinbox->setValue(olive::config.thumbnail_resolution); general_layout->addWidget(thumbnail_res_spinbox, row, 1); - general_layout->addWidget(new QLabel(tr("Waveform Resolution:"), this), row, 2); + row++; + + general_layout->addWidget(new QLabel(tr("Waveform Resolution:"), this), row, 0); waveform_res_spinbox = new QSpinBox(this); waveform_res_spinbox->setMinimum(0); waveform_res_spinbox->setMaximum(INT_MAX); - //waveform_res_spinbox->setValue(olive::config.waveform_resolution); - general_layout->addWidget(waveform_res_spinbox, row, 3); + general_layout->addWidget(waveform_res_spinbox, row, 1); + + row++; QPushButton* delete_preview_btn = new QPushButton(tr("Delete Previews")); - general_layout->addWidget(delete_preview_btn, row, 4); + general_layout->addWidget(delete_preview_btn, row, 1); //connect(delete_preview_btn, SIGNAL(clicked(bool)), this, SLOT(delete_all_previews())); row++; @@ -86,7 +88,7 @@ PreferencesGeneralTab::PreferencesGeneralTab() connect(default_sequence_settings, SIGNAL(clicked(bool)), this, SLOT(edit_default_sequence_settings())); misc_general->addWidget(default_sequence_settings); - general_layout->addLayout(misc_general, row, 0, 1, 5); + general_layout->addLayout(misc_general, row, 0); layout->addStretch(); } diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 22acf0c10..e2ec2a570 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -26,6 +26,7 @@ #include #include +#include "audio/audiomanager.h" #include "common/timecodefunctions.h" #include "viewersizer.h" @@ -195,6 +196,11 @@ void ViewerWidget::PlayInternal(int speed) start_timestamp_ = ruler_->GetTime(); playback_speed_ = speed; + /*QFile* file = new QFile("path-to-cache-audio"); + if (file->open(QFile::ReadOnly)) { + AudioManager::instance()->StartOutput(file); + }*/ + playback_timer_.start(); controls_->ShowPauseButton(); @@ -219,6 +225,8 @@ void ViewerWidget::Pause() controls_->ShowPlayButton(); playback_speed_ = 0; + + AudioManager::instance()->StopOutput(); } void ViewerWidget::GoToStart() diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 2d49eea7c..16001df7f 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -120,6 +120,11 @@ void olive::MainWindow::ProjectOpen(Project* p) TimelinePanel* timeline_panel = olive::panel_manager->CreatePanel(this); addDockWidget(Qt::BottomDockWidgetArea, timeline_panel); + TaskManagerPanel* task_man_panel = olive::panel_manager->CreatePanel(this); + addDockWidget(Qt::BottomDockWidgetArea, task_man_panel); + task_man_panel->setFloating(true); + task_man_panel->setVisible(false); + connect(node_panel, SIGNAL(SelectionChanged(QList)), param_panel, SLOT(SetNodes(QList))); }