Rename EngineDevice --> DeviceFinders, Add MMDeviceFinder
This commit is contained in:
parent
62b8521cbe
commit
7b977ea839
|
@ -121,7 +121,7 @@ set(SOURCES
|
|||
|
||||
engine/enginetype.cpp
|
||||
engine/enginebase.cpp
|
||||
engine/enginedevice.cpp
|
||||
engine/devicefinders.cpp
|
||||
engine/devicefinder.cpp
|
||||
|
||||
analyzer/fht.cpp
|
||||
|
@ -315,7 +315,7 @@ set(HEADERS
|
|||
core/mimedata.h
|
||||
|
||||
engine/enginebase.h
|
||||
engine/enginedevice.h
|
||||
engine/devicefinders.h
|
||||
|
||||
analyzer/analyzerbase.h
|
||||
analyzer/analyzercontainer.h
|
||||
|
@ -877,6 +877,7 @@ endif()
|
|||
optional_source(WIN32
|
||||
SOURCES
|
||||
engine/directsounddevicefinder.cpp
|
||||
engine/mmdevicefinder.cpp
|
||||
widgets/osd_win.cpp
|
||||
core/windows7thumbbar.cpp
|
||||
HEADERS
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "engine/enginetype.h"
|
||||
#include "engine/enginedevice.h"
|
||||
#include "engine/devicefinders.h"
|
||||
#include "engine/devicefinder.h"
|
||||
#include "collection/collection.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
|
@ -341,7 +341,7 @@ void ContextView::SetSong(const Song &song) {
|
|||
ui_->spacer_play_output->changeSize(20, 20, QSizePolicy::Fixed);
|
||||
|
||||
DeviceFinder::Device device;
|
||||
for (DeviceFinder *f : app_->enginedevice()->device_finders_) {
|
||||
for (DeviceFinder *f : app_->device_finders()->ListFinders()) {
|
||||
for (const DeviceFinder::Device &d : f->ListDevices()) {
|
||||
if (d.value != app_->player()->engine()->device()) continue;
|
||||
device = d;
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include "player.h"
|
||||
#include "appearance.h"
|
||||
|
||||
#include "engine/enginedevice.h"
|
||||
#include "engine/devicefinders.h"
|
||||
#ifndef Q_OS_WIN
|
||||
# include "device/devicemanager.h"
|
||||
#endif
|
||||
|
@ -105,7 +105,7 @@ class ApplicationImpl {
|
|||
appearance_([=]() { return new Appearance(app); }),
|
||||
task_manager_([=]() { return new TaskManager(app); }),
|
||||
player_([=]() { return new Player(app, app); }),
|
||||
enginedevice_([=]() { return new EngineDevice(app); }),
|
||||
device_finders_([=]() { return new DeviceFinders(app); }),
|
||||
#ifndef Q_OS_WIN
|
||||
device_manager_([=]() { return new DeviceManager(app, app); }),
|
||||
#endif
|
||||
|
@ -175,7 +175,7 @@ class ApplicationImpl {
|
|||
Lazy<Appearance> appearance_;
|
||||
Lazy<TaskManager> task_manager_;
|
||||
Lazy<Player> player_;
|
||||
Lazy<EngineDevice> enginedevice_;
|
||||
Lazy<DeviceFinders> device_finders_;
|
||||
#ifndef Q_OS_WIN
|
||||
Lazy<DeviceManager> device_manager_;
|
||||
#endif
|
||||
|
@ -205,7 +205,7 @@ class ApplicationImpl {
|
|||
Application::Application(QObject *parent)
|
||||
: QObject(parent), p_(new ApplicationImpl(this)) {
|
||||
|
||||
enginedevice()->Init();
|
||||
device_finders()->Init();
|
||||
collection()->Init();
|
||||
tag_reader_client();
|
||||
|
||||
|
@ -307,7 +307,7 @@ Appearance *Application::appearance() const { return p_->appearance_.get(); }
|
|||
Database *Application::database() const { return p_->database_.get(); }
|
||||
TaskManager *Application::task_manager() const { return p_->task_manager_.get(); }
|
||||
Player *Application::player() const { return p_->player_.get(); }
|
||||
EngineDevice *Application::enginedevice() const { return p_->enginedevice_.get(); }
|
||||
DeviceFinders *Application::device_finders() const { return p_->device_finders_.get(); }
|
||||
#ifndef Q_OS_WIN
|
||||
DeviceManager *Application::device_manager() const { return p_->device_manager_.get(); }
|
||||
#endif
|
||||
|
|
|
@ -41,7 +41,7 @@ class TaskManager;
|
|||
class ApplicationImpl;
|
||||
class TagReaderClient;
|
||||
class Database;
|
||||
class EngineDevice;
|
||||
class DeviceFinders;
|
||||
class Player;
|
||||
class Appearance;
|
||||
class SCollection;
|
||||
|
@ -78,7 +78,7 @@ class Application : public QObject {
|
|||
Appearance *appearance() const;
|
||||
TaskManager *task_manager() const;
|
||||
Player *player() const;
|
||||
EngineDevice *enginedevice() const;
|
||||
DeviceFinders *device_finders() const;
|
||||
#ifndef Q_OS_WIN
|
||||
DeviceManager *device_manager() const;
|
||||
#endif
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
#include <QtDebug>
|
||||
|
||||
#include "core/logging.h"
|
||||
#include "devicefinders.h"
|
||||
#include "devicefinder.h"
|
||||
#include "enginedevice.h"
|
||||
|
||||
#ifdef HAVE_ALSA
|
||||
# include "alsadevicefinder.h"
|
||||
|
@ -43,16 +43,16 @@
|
|||
|
||||
#ifdef Q_OS_WIN32
|
||||
# include "directsounddevicefinder.h"
|
||||
# include "mmdevicefinder.h"
|
||||
#endif
|
||||
|
||||
EngineDevice::EngineDevice(QObject *parent) : QObject(parent) {
|
||||
}
|
||||
DeviceFinders::DeviceFinders(QObject *parent) : QObject(parent) {}
|
||||
|
||||
EngineDevice::~EngineDevice() {
|
||||
DeviceFinders::~DeviceFinders() {
|
||||
qDeleteAll(device_finders_);
|
||||
}
|
||||
|
||||
void EngineDevice::Init() {
|
||||
void DeviceFinders::Init() {
|
||||
|
||||
QList<DeviceFinder*> device_finders;
|
||||
|
||||
|
@ -67,6 +67,7 @@ void EngineDevice::Init() {
|
|||
#endif
|
||||
#ifdef Q_OS_WIN32
|
||||
device_finders.append(new DirectSoundDeviceFinder);
|
||||
device_finders.append(new MMDeviceFinder);
|
||||
#endif
|
||||
|
||||
for (DeviceFinder *finder : device_finders) {
|
|
@ -17,8 +17,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef ENGINEDEVICE_H
|
||||
#define ENGINEDEVICE_H
|
||||
#ifndef DEVICEFINDERS_H
|
||||
#define DEVICEFINDERS_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
@ -28,21 +28,19 @@
|
|||
|
||||
class DeviceFinder;
|
||||
|
||||
class EngineDevice : public QObject {
|
||||
class DeviceFinders : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EngineDevice(QObject *parent = nullptr);
|
||||
~EngineDevice();
|
||||
explicit DeviceFinders(QObject *parent = nullptr);
|
||||
~DeviceFinders();
|
||||
|
||||
void Init();
|
||||
|
||||
QList<DeviceFinder*> device_finders_;
|
||||
QList<DeviceFinder*> ListFinders() { return device_finders_; }
|
||||
|
||||
private:
|
||||
QString output_;
|
||||
QList<DeviceFinder*> device_finders_;
|
||||
|
||||
};
|
||||
|
||||
#endif // ENGINEDEVICE_H
|
||||
|
||||
#endif // DEVICEFINDERS_H
|
|
@ -35,7 +35,7 @@
|
|||
#include "core/logging.h"
|
||||
|
||||
DirectSoundDeviceFinder::DirectSoundDeviceFinder()
|
||||
: DeviceFinder("directsound", { "directsound", "dsound", "directsoundsink", "directx", "directx2", "wasapisink" }) {
|
||||
: DeviceFinder("directsound", { "directsound", "dsound", "directsoundsink", "directx", "directx2" }) {
|
||||
}
|
||||
|
||||
QList<DeviceFinder::Device> DirectSoundDeviceFinder::ListDevices() {
|
||||
|
@ -52,9 +52,7 @@ BOOL DirectSoundDeviceFinder::EnumerateCallback(LPGUID guid, LPCSTR description,
|
|||
|
||||
Device dev;
|
||||
dev.description = QString::fromLatin1(description);
|
||||
//if (guid) dev.value = QUuid(*guid).toByteArray();
|
||||
if (guid) dev.value = QUuid(*guid).toString();
|
||||
else dev.value = QVariant();
|
||||
dev.iconname = GuessIconName(dev.description);
|
||||
state->devices.append(dev);
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
#include "engine_fwd.h"
|
||||
#include "enginetype.h"
|
||||
#include "enginedevice.h"
|
||||
#include "devicefinders.h"
|
||||
#include "core/song.h"
|
||||
|
||||
namespace Engine {
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <QTimeLine>
|
||||
#include <QMetaObject>
|
||||
#include <QtDebug>
|
||||
#include <QUuid>
|
||||
|
||||
#include "core/concurrentrun.h"
|
||||
#include "core/logging.h"
|
||||
|
@ -197,11 +198,11 @@ bool GstEnginePipeline::InitAudioBin() {
|
|||
if (device_.isValid() && g_object_class_find_property(G_OBJECT_GET_CLASS(audiosink), "device")) {
|
||||
switch (device_.type()) {
|
||||
case QVariant::String:
|
||||
if (device_.toString().isEmpty()) break;
|
||||
g_object_set(G_OBJECT(audiosink), "device", device_.toString().toUtf8().constData(), nullptr);
|
||||
if (device_.toString().isEmpty()) break;
|
||||
g_object_set(G_OBJECT(audiosink), "device", device_.toString().toUtf8().constData(), nullptr);
|
||||
break;
|
||||
case QVariant::ByteArray:
|
||||
g_object_set(G_OBJECT(audiosink), "device", device_.toByteArray().constData(), nullptr);
|
||||
g_object_set(G_OBJECT(audiosink), "device", device_.toByteArray().constData(), nullptr);
|
||||
break;
|
||||
case QVariant::LongLong:
|
||||
g_object_set(G_OBJECT(audiosink), "device", device_.toLongLong(), nullptr);
|
||||
|
@ -209,12 +210,20 @@ bool GstEnginePipeline::InitAudioBin() {
|
|||
case QVariant::Int:
|
||||
g_object_set(G_OBJECT(audiosink), "device", device_.toInt(), nullptr);
|
||||
break;
|
||||
case QVariant::Uuid:
|
||||
g_object_set(G_OBJECT(audiosink), "device", device_.toUuid(), nullptr);
|
||||
break;
|
||||
default:
|
||||
qLog(Warning) << "Unknown device type" << device_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (output_ == "wasapisink") {
|
||||
g_object_set(G_OBJECT(audiosink), "exclusive", true, nullptr);
|
||||
g_object_set(G_OBJECT(audiosink), "low-latency", true, nullptr);
|
||||
}
|
||||
|
||||
// Create all the other elements
|
||||
|
||||
audioqueue_ = engine_->CreateElement("queue2", audiobin_);
|
||||
|
@ -901,6 +910,7 @@ void GstEnginePipeline::SourceSetupCallback(GstPlayBin *bin, GParamSpec *, gpoin
|
|||
if (g_object_class_find_property(G_OBJECT_GET_CLASS(element), "device") && !instance->source_device().isEmpty()) {
|
||||
// Gstreamer is not able to handle device in URL (referring to Gstreamer documentation, this might be added in the future).
|
||||
// Despite that, for now we include device inside URL: we decompose it during Init and set device here, when this callback is called.
|
||||
qLog(Info) << instance->source_device().toLocal8Bit().constData();
|
||||
g_object_set(element, "device", instance->source_device().toLocal8Bit().constData(), nullptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2019, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <initguid.h>
|
||||
#include <devpkey.h>
|
||||
#include <functiondiscoverykeys_devpkey.h>
|
||||
#include <mmdeviceapi.h>
|
||||
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
#include <QString>
|
||||
|
||||
#include "mmdevicefinder.h"
|
||||
#include "core/logging.h"
|
||||
|
||||
MMDeviceFinder::MMDeviceFinder() : DeviceFinder("mmdevice", { "wasapisink" }) {}
|
||||
|
||||
QList<DeviceFinder::Device> MMDeviceFinder::ListDevices() {
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
IMMDeviceEnumerator *enumerator = nullptr;
|
||||
hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&enumerator);
|
||||
if (FAILED(hr)) {
|
||||
return QList<Device>();
|
||||
}
|
||||
|
||||
IMMDeviceCollection *collection = nullptr;
|
||||
hr = enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &collection);
|
||||
if (FAILED(hr)) {
|
||||
enumerator->Release();
|
||||
return QList<Device>();
|
||||
}
|
||||
|
||||
UINT count;
|
||||
hr = collection->GetCount(&count);
|
||||
if (FAILED(hr)) {
|
||||
collection->Release();
|
||||
enumerator->Release();
|
||||
return QList<Device>();
|
||||
}
|
||||
|
||||
QList<Device> devices;
|
||||
Device default_device;
|
||||
default_device.description = "Default device";
|
||||
default_device.iconname = GuessIconName(default_device.description);
|
||||
devices.append(default_device);
|
||||
|
||||
for (ULONG i = 0 ; i < count ; i++) {
|
||||
|
||||
IMMDevice *endpoint = nullptr;
|
||||
hr = collection->Item(i, &endpoint);
|
||||
if (FAILED(hr)) { return devices; }
|
||||
|
||||
LPWSTR pwszid = nullptr;
|
||||
hr = endpoint->GetId(&pwszid);
|
||||
if (FAILED(hr)) {
|
||||
endpoint->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
IPropertyStore *props = nullptr;
|
||||
hr = endpoint->OpenPropertyStore(STGM_READ, &props);
|
||||
if (FAILED(hr)) {
|
||||
CoTaskMemFree(pwszid);
|
||||
endpoint->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
PROPVARIANT var_name;
|
||||
PropVariantInit(&var_name);
|
||||
hr = props->GetValue(PKEY_Device_FriendlyName, &var_name);
|
||||
if (FAILED(hr)) {
|
||||
props->Release();
|
||||
CoTaskMemFree(pwszid);
|
||||
endpoint->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
Device device;
|
||||
device.description = QString::fromWCharArray(var_name.pwszVal);
|
||||
device.iconname = GuessIconName(device.description);
|
||||
device.value = QString::fromStdWString(pwszid);
|
||||
devices.append(device);
|
||||
|
||||
PropVariantClear(&var_name);
|
||||
props->Release();
|
||||
CoTaskMemFree(pwszid);
|
||||
endpoint->Release();
|
||||
|
||||
}
|
||||
collection->Release();
|
||||
enumerator->Release();
|
||||
|
||||
return devices;
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2019, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Strawberry is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MMDEVICEFINDER_H
|
||||
#define MMDEVICEFINDER_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "devicefinder.h"
|
||||
|
||||
class MMDeviceFinder : public DeviceFinder {
|
||||
public:
|
||||
MMDeviceFinder();
|
||||
virtual bool Initialise() { return true; }
|
||||
virtual QList<Device> ListDevices();
|
||||
};
|
||||
|
||||
#endif // MMDEVICEFINDER_H
|
|
@ -41,7 +41,7 @@
|
|||
#include "core/logging.h"
|
||||
#include "engine/engine_fwd.h"
|
||||
#include "engine/enginebase.h"
|
||||
#include "engine/enginedevice.h"
|
||||
#include "engine/devicefinders.h"
|
||||
#include "engine/enginetype.h"
|
||||
#include "engine/devicefinder.h"
|
||||
#include "widgets/lineedit.h"
|
||||
|
@ -291,7 +291,7 @@ void BackendSettingsPage::Load_Device(QString output, QVariant device) {
|
|||
#endif
|
||||
ui_->combobox_device->addItem(IconLoader::Load("soundcard"), "Automatically select", QVariant());
|
||||
|
||||
for (DeviceFinder *f : dialog()->app()->enginedevice()->device_finders_) {
|
||||
for (DeviceFinder *f : dialog()->app()->device_finders()->ListFinders()) {
|
||||
if (!f->outputs().contains(output)) continue;
|
||||
for (const DeviceFinder::Device &d : f->ListDevices()) {
|
||||
devices++;
|
||||
|
|
Loading…
Reference in New Issue