Add Audio Device Selection to GUI (Fix #376) (#377)

This commit is contained in:
Blueroom VR 2020-11-20 04:14:45 -08:00 committed by GitHub
commit a11341f448
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 4 deletions

View file

@ -2,7 +2,7 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Multimedia OpenGL Svg)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Concurrent Multimedia OpenGL Svg)
if(APPLE)
find_package(Qt5 REQUIRED COMPONENTS MacExtras)
endif()
@ -74,7 +74,7 @@ if(CHIAKI_ENABLE_CLI)
endif()
target_link_libraries(chiaki FFMPEG::avcodec FFMPEG::avutil)
target_link_libraries(chiaki Qt5::Core Qt5::Widgets Qt5::Gui Qt5::Multimedia Qt5::OpenGL Qt5::Svg)
target_link_libraries(chiaki Qt5::Core Qt5::Widgets Qt5::Gui Qt5::Concurrent Qt5::Multimedia Qt5::OpenGL Qt5::Svg)
if(APPLE)
target_link_libraries(chiaki Qt5::MacExtras)
target_compile_definitions(chiaki PRIVATE CHIAKI_GUI_ENABLE_QT_MACEXTRAS)

View file

@ -9,6 +9,7 @@
#include "videodecoder.h"
#include <QSettings>
#include <QAudioDeviceInfo>
enum class ControllerButtonExt
{
@ -93,6 +94,9 @@ class Settings : public QObject
*/
unsigned int GetAudioBufferSize() const;
void SetAudioBufferSize(unsigned int size);
QString GetAudioOutDevice() const;
void SetAudioOutDevice(QString device_name);
ChiakiConnectVideoProfile GetVideoProfile();

View file

@ -25,6 +25,7 @@ class SettingsDialog : public QDialog
QComboBox *fps_combo_box;
QLineEdit *bitrate_edit;
QLineEdit *audio_buffer_size_edit;
QComboBox *audio_device_combo_box;
QCheckBox *pi_decoder_check_box;
QComboBox *hardware_decode_combo_box;
@ -41,6 +42,7 @@ class SettingsDialog : public QDialog
void FPSSelected();
void BitrateEdited();
void AudioBufferSizeEdited();
void AudioOutputSelected();
void HardwareDecodeEngineSelected();
void UpdateHardwareDecodeEngineComboBox();

View file

@ -42,6 +42,7 @@ struct StreamSessionConnectInfo
QMap<Qt::Key, int> key_map;
Decoder decoder;
HardwareDecodeEngine hw_decode_engine;
QString audio_out_device;
uint32_t log_level_mask;
QString log_file;
QString host;
@ -81,6 +82,7 @@ class StreamSession : public QObject
ChiakiPiDecoder *pi_decoder;
#endif
QAudioDeviceInfo audio_out_device_info;
unsigned int audio_buffer_size;
QAudioOutput *audio_output;
QIODevice *audio_io;

View file

@ -130,6 +130,16 @@ unsigned int Settings::GetAudioBufferSize() const
return v ? v : GetAudioBufferSizeDefault();
}
QString Settings::GetAudioOutDevice() const
{
return settings.value("settings/audio_out_device").toString();
}
void Settings::SetAudioOutDevice(QString device_name)
{
settings.setValue("settings/audio_out_device", device_name);
}
void Settings::SetAudioBufferSize(unsigned int size)
{
settings.setValue("settings/audio_buffer_size", size);

View file

@ -19,6 +19,8 @@
#include <QMap>
#include <QCheckBox>
#include <QLineEdit>
#include <QtConcurrent>
#include <QFutureWatcher>
#include <chiaki/config.h>
@ -151,6 +153,36 @@ SettingsDialog::SettingsDialog(Settings *settings, QWidget *parent) : QDialog(pa
audio_buffer_size_edit->setPlaceholderText(tr("Default (%1)").arg(settings->GetAudioBufferSizeDefault()));
connect(audio_buffer_size_edit, &QLineEdit::textEdited, this, &SettingsDialog::AudioBufferSizeEdited);
audio_device_combo_box = new QComboBox(this);
audio_device_combo_box->addItem(tr("Auto"));
auto current_audio_device = settings->GetAudioOutDevice();
if(!current_audio_device.isEmpty())
{
// temporarily add the selected device before async fetching is done
audio_device_combo_box->addItem(current_audio_device, current_audio_device);
audio_device_combo_box->setCurrentIndex(1);
}
connect(audio_device_combo_box, QOverload<int>::of(&QComboBox::activated), this, [this](){
this->settings->SetAudioOutDevice(audio_device_combo_box->currentData().toString());
});
// do this async because it's slow, assuming availableDevices() is thread-safe
auto audio_devices_future = QtConcurrent::run([]() {
return QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
});
auto audio_devices_future_watcher = new QFutureWatcher<QList<QAudioDeviceInfo>>(this);
connect(audio_devices_future_watcher, &QFutureWatcher<QList<QAudioDeviceInfo>>::finished, this, [this, audio_devices_future_watcher, settings]() {
auto available_devices = audio_devices_future_watcher->result();
while(audio_device_combo_box->count() > 1) // remove all but "Auto"
audio_device_combo_box->removeItem(1);
for (QAudioDeviceInfo di : available_devices)
audio_device_combo_box->addItem(di.deviceName(), di.deviceName());
int audio_out_device_index = audio_device_combo_box->findData(settings->GetAudioOutDevice());
audio_device_combo_box->setCurrentIndex(audio_out_device_index < 0 ? 0 : audio_out_device_index);
});
audio_devices_future_watcher->setFuture(audio_devices_future);
general_layout->addRow(tr("Audio Output Device:"), audio_device_combo_box);
// Decode Settings
auto decode_settings = new QGroupBox(tr("Decode Settings"));
@ -291,6 +323,11 @@ void SettingsDialog::AudioBufferSizeEdited()
settings->SetAudioBufferSize(audio_buffer_size_edit->text().toUInt());
}
void SettingsDialog::AudioOutputSelected()
{
settings->SetAudioOutDevice(audio_device_combo_box->currentText());
}
void SettingsDialog::HardwareDecodeEngineSelected()
{
settings->SetHardwareDecodeEngine((HardwareDecodeEngine)hardware_decode_combo_box->currentData().toInt());

View file

@ -20,6 +20,7 @@ StreamSessionConnectInfo::StreamSessionConnectInfo(Settings *settings, QString h
key_map = settings->GetControllerMappingForDecoding();
decoder = settings->GetDecoder();
hw_decode_engine = settings->GetHardwareDecodeEngine();
audio_out_device = settings->GetAudioOutDevice();
log_level_mask = settings->GetLogLevelMask();
log_file = CreateLogFilename();
video_profile = settings->GetVideoProfile();
@ -67,6 +68,19 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje
}
#endif
audio_out_device_info = QAudioDeviceInfo::defaultOutputDevice();
if(!connect_info.audio_out_device.isEmpty())
{
for(QAudioDeviceInfo di : QAudioDeviceInfo::availableDevices(QAudio::AudioOutput))
{
if(di.deviceName() == connect_info.audio_out_device)
{
audio_out_device_info = di;
break;
}
}
}
chiaki_opus_decoder_init(&opus_decoder, log.GetChiakiLog());
audio_buffer_size = connect_info.audio_buffer_size;
@ -296,7 +310,7 @@ void StreamSession::InitAudio(unsigned int channels, unsigned int rate)
audio_format.setCodec("audio/pcm");
audio_format.setSampleType(QAudioFormat::SignedInt);
QAudioDeviceInfo audio_device_info(QAudioDeviceInfo::defaultOutputDevice());
QAudioDeviceInfo audio_device_info = audio_out_device_info;
if(!audio_device_info.isFormatSupported(audio_format))
{
CHIAKI_LOGE(log.GetChiakiLog(), "Audio Format with %u channels @ %u Hz not supported by Audio Device %s",
@ -305,7 +319,7 @@ void StreamSession::InitAudio(unsigned int channels, unsigned int rate)
return;
}
audio_output = new QAudioOutput(audio_format, this);
audio_output = new QAudioOutput(audio_device_info, audio_format, this);
audio_output->setBufferSize(audio_buffer_size);
audio_io = audio_output->start();