Improvements to device selection

This commit is contained in:
Jonas Kvinge 2018-06-07 19:38:40 +02:00
parent d45f8672cd
commit 60b55b6d7d
10 changed files with 66 additions and 57 deletions

View File

@ -19,7 +19,6 @@
project(strawberry) project(strawberry)
cmake_minimum_required(VERSION 2.8.11) cmake_minimum_required(VERSION 2.8.11)
cmake_policy(SET CMP0054 NEW) cmake_policy(SET CMP0054 NEW)
cmake_policy(SET CMP0072 NEW)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
include(CheckIncludeFiles) include(CheckIncludeFiles)
@ -141,9 +140,6 @@ else()
set(QT_LIBRARIES Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Network Qt5::Sql Qt5::OpenGL Qt5::Xml) set(QT_LIBRARIES Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Network Qt5::Sql Qt5::OpenGL Qt5::Xml)
endif() endif()
# Remove GLU and GL from the link line - they're not really required and don't exist on my mingw toolchain
list(REMOVE_ITEM QT_LIBRARIES "-lGLU -lGL")
# Don't try to use webkit if their include directories couldn't be found. # Don't try to use webkit if their include directories couldn't be found.
if (NOT QT_QTWEBKIT_INCLUDE_DIR) if (NOT QT_QTWEBKIT_INCLUDE_DIR)
set (QT_USE_QTWEBKIT 0) set (QT_USE_QTWEBKIT 0)

View File

@ -896,9 +896,6 @@ void MainWindow::LoadPlaybackStatus() {
saved_playback_state_ = static_cast<Engine::State> (settings.value("playback_state", Engine::Empty).toInt()); saved_playback_state_ = static_cast<Engine::State> (settings.value("playback_state", Engine::Empty).toInt());
saved_playback_position_ = settings.value("playback_position", 0).toDouble(); saved_playback_position_ = settings.value("playback_position", 0).toDouble();
settings.endGroup(); settings.endGroup();
qLog(Debug) << "playback_state" << saved_playback_state_;
qLog(Debug) << "playback_position" << saved_playback_position_;
if (saved_playback_state_ == Engine::Empty || saved_playback_state_ == Engine::Idle) { if (saved_playback_state_ == Engine::Empty || saved_playback_state_ == Engine::Idle) {
return; return;

View File

@ -60,9 +60,9 @@ QList<DeviceFinder::Device> AlsaDeviceFinder::ListDevices() {
result = snd_card_next(&card); result = snd_card_next(&card);
if (result < 0) { if (result < 0) {
qLog(Error) << "Unable to get soundcard:" << snd_strerror(result); qLog(Error) << "Unable to get soundcard:" << snd_strerror(result);
return ret; break;
} }
if (card < 0) return ret; if (card < 0) break;
char name[32]; char name[32];
sprintf(name, "hw:%d", card); sprintf(name, "hw:%d", card);
@ -109,9 +109,6 @@ QList<DeviceFinder::Device> AlsaDeviceFinder::ListDevices() {
snd_ctl_close(handle); snd_ctl_close(handle);
} }
snd_pcm_info_free(pcminfo); pcminfo = NULL;
snd_ctl_card_info_free(cardinfo); cardinfo = NULL;
snd_config_update_free_global(); snd_config_update_free_global();
return ret; return ret;

View File

@ -35,7 +35,7 @@
#include "core/logging.h" #include "core/logging.h"
DirectSoundDeviceFinder::DirectSoundDeviceFinder() DirectSoundDeviceFinder::DirectSoundDeviceFinder()
: DeviceFinder("directsoundsink") { : DeviceFinder("directsound") {
} }
QList<DeviceFinder::Device> DirectSoundDeviceFinder::ListDevices() { QList<DeviceFinder::Device> DirectSoundDeviceFinder::ListDevices() {

View File

@ -81,4 +81,3 @@ void EngineDevice::Init() {
} }
} }

View File

@ -74,12 +74,16 @@ using std::vector;
const char *GstEngine::kAutoSink = "autoaudiosink"; const char *GstEngine::kAutoSink = "autoaudiosink";
const char *GstEngine::kALSASink = "alsasink"; const char *GstEngine::kALSASink = "alsasink";
const char *GstEngine::kOpenALSASink = "openalsink";
const char *GstEngine::kOSSSink = "osssink"; const char *GstEngine::kOSSSink = "osssink";
const char *GstEngine::kOSS4Sink = "oss4sink"; const char *GstEngine::kOSS4Sink = "oss4sink";
const char *GstEngine::kJackAudioSink = "jackaudiosink"; const char *GstEngine::kJackAudioSink = "jackaudiosink";
const char *GstEngine::kPulseSink = "pulsesink"; const char *GstEngine::kPulseSink = "pulsesink";
const char *GstEngine::kA2DPSink = "a2dpsink"; const char *GstEngine::kA2DPSink = "a2dpsink";
const char *GstEngine::kAVDTPSink = "avdtpsink"; const char *GstEngine::kAVDTPSink = "avdtpsink";
const char *GstEngine::InterAudiosink = "interaudiosink";
const char *GstEngine::kDirectSoundSink = "directsoundsink";
const char *GstEngine::kOSXAudioSink = "osxaudiosink";
GstEngine::GstEngine(TaskManager *task_manager) GstEngine::GstEngine(TaskManager *task_manager)
: Engine::Base(), : Engine::Base(),
@ -835,18 +839,6 @@ shared_ptr<GstEnginePipeline> GstEngine::CreatePipeline(const QByteArray &url, q
} }
bool GstEngine::ALSADeviceSupport(const QString &name) {
return (name == kALSASink || name == kOSSSink);
}
bool GstEngine::PulseDeviceSupport(const QString &name) {
return (name == kPulseSink);
}
void GstEngine::AddBufferConsumer(GstBufferConsumer *consumer) { void GstEngine::AddBufferConsumer(GstBufferConsumer *consumer) {
buffer_consumers_ << consumer; buffer_consumers_ << consumer;
if (current_pipeline_) current_pipeline_->AddBufferConsumer(consumer); if (current_pipeline_) current_pipeline_->AddBufferConsumer(consumer);
@ -901,3 +893,23 @@ EngineBase::OutputDetailsList GstEngine::GetOutputsList() const {
return ret; return ret;
} }
bool GstEngine::ALSADeviceSupport(const QString &name) {
return (name == kALSASink);
}
bool GstEngine::PulseDeviceSupport(const QString &name) {
return (name == kPulseSink);
}
bool GstEngine::DirectSoundDeviceSupport(const QString &name) {
return (name == kDirectSoundSink);
}
bool GstEngine::OSXAudioDeviceSupport(const QString &name) {
return (name == kOSXAudioSink);
}
bool GstEngine::CustomDeviceSupport(const QString &name) {
return (name == kALSASink || name == kOpenALSASink || name == kOSSSink || name == kOSS4Sink || name == kA2DPSink || name == kAVDTPSink);
}

View File

@ -66,13 +66,6 @@ class GstEngine : public Engine::Base, public GstBufferConsumer {
~GstEngine(); ~GstEngine();
static const char *kAutoSink; static const char *kAutoSink;
static const char *kALSASink;
static const char *kOSSSink;
static const char *kOSS4Sink;
static const char *kJackAudioSink;
static const char *kPulseSink;
static const char *kA2DPSink;
static const char *kAVDTPSink;
bool Init(); bool Init();
void EnsureInitialised() { initialising_.waitForFinished(); } void EnsureInitialised() { initialising_.waitForFinished(); }
@ -86,16 +79,19 @@ class GstEngine : public Engine::Base, public GstBufferConsumer {
Engine::State state() const; Engine::State state() const;
const Engine::Scope &scope(int chunk_length); const Engine::Scope &scope(int chunk_length);
static bool ALSADeviceSupport(const QString &name);
static bool PulseDeviceSupport(const QString &name);
GstElement *CreateElement(const QString &factoryName, GstElement *bin = 0, bool fatal = true, bool showerror = true); GstElement *CreateElement(const QString &factoryName, GstElement *bin = 0, bool fatal = true, bool showerror = true);
// BufferConsumer // BufferConsumer
void ConsumeBuffer(GstBuffer *buffer, int pipeline_id); void ConsumeBuffer(GstBuffer *buffer, int pipeline_id);
bool IsEqualizerEnabled() { return equalizer_enabled_; } bool IsEqualizerEnabled() { return equalizer_enabled_; }
static bool ALSADeviceSupport(const QString &name);
static bool PulseDeviceSupport(const QString &name);
static bool DirectSoundDeviceSupport(const QString &name);
static bool OSXAudioDeviceSupport(const QString &name);
static bool CustomDeviceSupport(const QString &name);
public slots: public slots:
void StartPreloading(const QUrl &url, bool force_stop_at_end, qint64 beginning_nanosec, qint64 end_nanosec); void StartPreloading(const QUrl &url, bool force_stop_at_end, qint64 beginning_nanosec, qint64 end_nanosec);
bool Load(const QUrl &, Engine::TrackChangeFlags change, bool force_stop_at_end, quint64 beginning_nanosec, qint64 end_nanosec); bool Load(const QUrl &, Engine::TrackChangeFlags change, bool force_stop_at_end, quint64 beginning_nanosec, qint64 end_nanosec);
@ -142,6 +138,19 @@ class GstEngine : public Engine::Base, public GstBufferConsumer {
void BufferingFinished(); void BufferingFinished();
private: private:
static const char *kALSASink;
static const char *kOpenALSASink;
static const char *kOSSSink;
static const char *kOSS4Sink;
static const char *kJackAudioSink;
static const char *kPulseSink;
static const char *kA2DPSink;
static const char *kAVDTPSink;
static const char *InterAudiosink;
static const char *kDirectSoundSink;
static const char *kOSXAudioSink;
PluginDetailsList GetPluginList(const QString &classname) const; PluginDetailsList GetPluginList(const QString &classname) const;
void StartFadeout(); void StartFadeout();

View File

@ -62,7 +62,7 @@ std::unique_ptr<T> GetProperty(const AudioDeviceID& device_id, const AudioObject
OsxDeviceFinder::OsxDeviceFinder() OsxDeviceFinder::OsxDeviceFinder()
: DeviceFinder("osxaudiosink") { : DeviceFinder("osxaudio") {
} }
QList<DeviceFinder::Device> OsxDeviceFinder::ListDevices() { QList<DeviceFinder::Device> OsxDeviceFinder::ListDevices() {
@ -94,8 +94,7 @@ QList<DeviceFinder::Device> OsxDeviceFinder::ListDevices() {
continue; continue;
} }
// Determine if the device is an output device (it is an output device if // Determine if the device is an output device (it is an output device if it has output channels)
// it has output channels)
address.mSelector = kAudioDevicePropertyStreamConfiguration; address.mSelector = kAudioDevicePropertyStreamConfiguration;
std::unique_ptr<AudioBufferList> buffer_list = GetProperty<AudioBufferList>(id, address); std::unique_ptr<AudioBufferList> buffer_list = GetProperty<AudioBufferList>(id, address);
if (!buffer_list.get() || buffer_list->mNumberBuffers == 0) { if (!buffer_list.get() || buffer_list->mNumberBuffers == 0) {

View File

@ -193,7 +193,7 @@ void BackendSettingsPage::Load_Engine(Engine::EngineType enginetype) {
} }
void BackendSettingsPage::Load_Device(QString output, QVariant device, bool alsa, bool pulseaudio) { void BackendSettingsPage::Load_Device(QString output, QVariant device, bool alsa, bool pulseaudio, bool directsound, bool osxaudio, bool custom) {
int devices = 0; int devices = 0;
DeviceFinder::Device dfdevice; DeviceFinder::Device dfdevice;
@ -206,12 +206,14 @@ void BackendSettingsPage::Load_Device(QString output, QVariant device, bool alsa
ui_->combobox_device->addItem(IconLoader::Load("soundcard"), "Automatically select", ""); ui_->combobox_device->addItem(IconLoader::Load("soundcard"), "Automatically select", "");
#endif #endif
if (alsa || pulseaudio) ui_->lineedit_device->setEnabled(true); if (alsa) ui_->lineedit_device->setEnabled(true);
else ui_->lineedit_device->setEnabled(false); else ui_->lineedit_device->setEnabled(false);
for (DeviceFinder *f : dialog()->app()->enginedevice()->device_finders_) { for (DeviceFinder *f : dialog()->app()->enginedevice()->device_finders_) {
if (f->name() == "alsa" && !alsa) continue; if (f->name() == "alsa" && !alsa) continue;
if (f->name() == "pulseaudio" && !pulseaudio) continue; if (f->name() == "pulseaudio" && !pulseaudio) continue;
if (f->name() == "directsound" && !directsound) continue;
if (f->name() == "osxaudio" && !osxaudio) continue;
for (const DeviceFinder::Device &d : f->ListDevices()) { for (const DeviceFinder::Device &d : f->ListDevices()) {
devices++; devices++;
ui_->combobox_device->addItem(IconLoader::Load(d.iconname), d.description, d.value); ui_->combobox_device->addItem(IconLoader::Load(d.iconname), d.description, d.value);
@ -219,10 +221,10 @@ void BackendSettingsPage::Load_Device(QString output, QVariant device, bool alsa
} }
} }
if (alsa || pulseaudio) ui_->combobox_device->addItem(IconLoader::Load("soundcard"), "Custom", QVariant("")); if (custom) ui_->combobox_device->addItem(IconLoader::Load("soundcard"), "Custom", QVariant(""));
bool found = false; bool found = false;
if (devices > 0) ui_->combobox_device->setEnabled(true); if (custom || devices > 0) ui_->combobox_device->setEnabled(true);
for (int i = 0; i < ui_->combobox_device->count(); ++i) { for (int i = 0; i < ui_->combobox_device->count(); ++i) {
QVariant d = ui_->combobox_device->itemData(i).value<QVariant>(); QVariant d = ui_->combobox_device->itemData(i).value<QVariant>();
if (dfdevice.value == d) { if (dfdevice.value == d) {
@ -233,7 +235,7 @@ void BackendSettingsPage::Load_Device(QString output, QVariant device, bool alsa
} }
// This allows a custom ALSA device string ie: "hw:0,0" even if it is not listed. // This allows a custom ALSA device string ie: "hw:0,0" even if it is not listed.
if (found == false && alsa && device.type() == QVariant::String && !device.toString().isEmpty()) { if (found == false && custom && device.type() == QVariant::String && !device.toString().isEmpty()) {
ui_->lineedit_device->setText(device.toString()); ui_->lineedit_device->setText(device.toString());
} }
@ -270,7 +272,7 @@ void BackendSettingsPage::Gst_Load(QString output, QVariant device) {
engineloaded_=Engine::GStreamer; engineloaded_=Engine::GStreamer;
ui_->groupbox_replaygain->setEnabled(true); ui_->groupbox_replaygain->setEnabled(true);
Load_Device(output, device, GstEngine::ALSADeviceSupport(output), GstEngine::PulseDeviceSupport(output)); Load_Device(output, device, GstEngine::ALSADeviceSupport(output), GstEngine::PulseDeviceSupport(output), GstEngine::DirectSoundDeviceSupport(output), GstEngine::OSXAudioDeviceSupport(output), GstEngine::CustomDeviceSupport(output));
} }
#endif #endif
@ -304,7 +306,7 @@ void BackendSettingsPage::Xine_Load(QString output, QVariant device) {
engineloaded_=Engine::Xine; engineloaded_=Engine::Xine;
Load_Device(output, device, false); Load_Device(output, device);
} }
#endif #endif
@ -318,7 +320,7 @@ void BackendSettingsPage::Phonon_Load(QString output, QVariant device) {
engineloaded_=Engine::Phonon; engineloaded_=Engine::Phonon;
Load_Device(output, device, false); Load_Device(output, device);
} }
#endif #endif
@ -332,7 +334,7 @@ void BackendSettingsPage::VLC_Load(QString output, QVariant device) {
engineloaded_=Engine::VLC; engineloaded_=Engine::VLC;
Load_Device(output, device, false); Load_Device(output, device);
} }
#endif #endif
@ -469,7 +471,7 @@ void BackendSettingsPage::OutputChanged(int index, Engine::EngineType enginetype
void BackendSettingsPage::Xine_OutputChanged(int index) { void BackendSettingsPage::Xine_OutputChanged(int index) {
EngineBase::OutputDetails output = ui_->combobox_output->itemData(index).value<EngineBase::OutputDetails>(); EngineBase::OutputDetails output = ui_->combobox_output->itemData(index).value<EngineBase::OutputDetails>();
Load_Device(output.name, QVariant(), false); Load_Device(output.name, QVariant());
} }
#endif #endif
@ -478,20 +480,20 @@ void BackendSettingsPage::Xine_OutputChanged(int index) {
void BackendSettingsPage::Gst_OutputChanged(int index) { void BackendSettingsPage::Gst_OutputChanged(int index) {
EngineBase::OutputDetails output = ui_->combobox_output->itemData(index).value<EngineBase::OutputDetails>(); EngineBase::OutputDetails output = ui_->combobox_output->itemData(index).value<EngineBase::OutputDetails>();
Load_Device(output.name, QVariant(), GstEngine::ALSADeviceSupport(output.name), GstEngine::PulseDeviceSupport(output.name)); Load_Device(output.name, QVariant(), GstEngine::ALSADeviceSupport(output.name), GstEngine::PulseDeviceSupport(output.name), GstEngine::DirectSoundDeviceSupport(output.name), GstEngine::OSXAudioDeviceSupport(output.name), GstEngine::CustomDeviceSupport(output.name));
} }
#endif #endif
#ifdef HAVE_PHONON #ifdef HAVE_PHONON
void BackendSettingsPage::Phonon_OutputChanged(int index) { void BackendSettingsPage::Phonon_OutputChanged(int index) {
Load_Device("", QVariant(), false); Load_Device("", QVariant());
} }
#endif #endif
#ifdef HAVE_VLC #ifdef HAVE_VLC
void BackendSettingsPage::VLC_OutputChanged(int index) { void BackendSettingsPage::VLC_OutputChanged(int index) {
Load_Device("", QVariant(), false); Load_Device("", QVariant());
} }
#endif #endif
@ -503,14 +505,12 @@ void BackendSettingsPage::DeviceSelectionChanged(int index) {
return; return;
} }
#if !defined(Q_OS_WIN32)
QVariant device = ui_->combobox_device->itemData(index).value<QVariant>(); QVariant device = ui_->combobox_device->itemData(index).value<QVariant>();
if (device.type() == QVariant::String) { if (device.type() == QVariant::String && device.toString().startsWith("hw:", Qt::CaseInsensitive)) {
ui_->lineedit_device->setEnabled(true); ui_->lineedit_device->setEnabled(true);
ui_->lineedit_device->setText(device.toString()); ui_->lineedit_device->setText(device.toString());
return; return;
} }
#endif
ui_->lineedit_device->setEnabled(false); ui_->lineedit_device->setEnabled(false);
ui_->lineedit_device->setText(""); ui_->lineedit_device->setText("");

View File

@ -67,7 +67,7 @@ private:
void OutputChanged(int index, Engine::EngineType enginetype); void OutputChanged(int index, Engine::EngineType enginetype);
void Load_Engine(Engine::EngineType enginetype); void Load_Engine(Engine::EngineType enginetype);
void Load_Device(QString output, QVariant device, bool alsa, bool pulseaudio); void Load_Device(QString output, QVariant device, bool alsa = false, bool pulseaudio = false, bool directsound = false, bool osxaudio = false, bool custom = false);
#ifdef HAVE_XINE #ifdef HAVE_XINE
void Xine_Load(QString output, QVariant device); void Xine_Load(QString output, QVariant device);