Add ALSA Device Finder (#6079)
This commit is contained in:
parent
41ed505277
commit
f3aab34d3a
@ -54,6 +54,10 @@ find_package(Gettext REQUIRED)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
find_package(Protobuf REQUIRED)
|
||||
find_package(FFTW3)
|
||||
find_package(ALSA)
|
||||
if(ALSA_FOUND)
|
||||
set(HAVE_ALSA ON)
|
||||
endif()
|
||||
|
||||
find_library(PROTOBUF_STATIC_LIBRARY libprotobuf.a libprotobuf)
|
||||
|
||||
|
@ -1187,6 +1187,12 @@ optional_source(HAVE_LIBPULSE
|
||||
engines/pulsedevicefinder.cpp
|
||||
)
|
||||
|
||||
# ALSA integration
|
||||
optional_source(HAVE_ALSA
|
||||
SOURCES
|
||||
engines/alsadevicefinder.cpp
|
||||
)
|
||||
|
||||
# Hack to add Clementine to the Unity system tray whitelist
|
||||
optional_source(LINUX
|
||||
SOURCES core/ubuntuunityhack.cpp
|
||||
@ -1305,6 +1311,10 @@ if(HAVE_LIBPULSE)
|
||||
target_link_libraries(clementine_lib ${LIBPULSE_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(HAVE_ALSA)
|
||||
target_link_libraries(clementine_lib ${ALSA_LIBRARIES})
|
||||
endif(HAVE_ALSA)
|
||||
|
||||
if (APPLE)
|
||||
target_link_libraries(clementine_lib
|
||||
"-framework AppKit"
|
||||
|
@ -36,6 +36,7 @@
|
||||
#cmakedefine HAVE_LIBLASTFM1
|
||||
#cmakedefine HAVE_LIBMTP
|
||||
#cmakedefine HAVE_LIBPULSE
|
||||
#cmakedefine HAVE_ALSA
|
||||
#cmakedefine HAVE_MOODBAR
|
||||
#cmakedefine HAVE_SEAFILE
|
||||
#cmakedefine HAVE_SKYDRIVE
|
||||
|
107
src/engines/alsadevicefinder.cpp
Normal file
107
src/engines/alsadevicefinder.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2017, Jonas Kvinge <jonas@jkvinge.net>
|
||||
|
||||
Clementine 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.
|
||||
|
||||
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <boost/scope_exit.hpp>
|
||||
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
#include <core/logging.h>
|
||||
|
||||
#include "alsadevicefinder.h"
|
||||
#include "devicefinder.h"
|
||||
|
||||
AlsaDeviceFinder::AlsaDeviceFinder() : DeviceFinder("alsasink") {}
|
||||
|
||||
QList<DeviceFinder::Device> AlsaDeviceFinder::ListDevices() {
|
||||
QList<Device> ret;
|
||||
|
||||
snd_pcm_stream_name(SND_PCM_STREAM_PLAYBACK);
|
||||
|
||||
int card = -1;
|
||||
snd_ctl_card_info_t* cardinfo;
|
||||
snd_ctl_card_info_alloca(&cardinfo);
|
||||
while (true) {
|
||||
int result = snd_card_next(&card);
|
||||
if (result < 0) {
|
||||
qLog(Error) << "Unable to get soundcard:" << snd_strerror(result);
|
||||
break;
|
||||
}
|
||||
if (card < 0) break;
|
||||
|
||||
char str[32];
|
||||
snprintf(str, sizeof(str) - 1, "hw:%d", card);
|
||||
|
||||
snd_ctl_t* handle;
|
||||
result = snd_ctl_open(&handle, str, 0);
|
||||
if (result < 0) {
|
||||
qLog(Error) << "Unable to open soundcard" << card << ":"
|
||||
<< snd_strerror(result);
|
||||
continue;
|
||||
}
|
||||
BOOST_SCOPE_EXIT(&handle) { snd_ctl_close(handle); }
|
||||
BOOST_SCOPE_EXIT_END
|
||||
|
||||
result = snd_ctl_card_info(handle, cardinfo);
|
||||
if (result < 0) {
|
||||
qLog(Error) << "Control hardware failure for card" << card << ":"
|
||||
<< snd_strerror(result);
|
||||
continue;
|
||||
}
|
||||
|
||||
int dev = -1;
|
||||
snd_pcm_info_t* pcminfo;
|
||||
snd_pcm_info_alloca(&pcminfo);
|
||||
while (true) {
|
||||
result = snd_ctl_pcm_next_device(handle, &dev);
|
||||
if (result < 0) {
|
||||
qLog(Error) << "Unable to get PCM for card" << card << ":"
|
||||
<< snd_strerror(result);
|
||||
continue;
|
||||
}
|
||||
if (dev < 0) break;
|
||||
|
||||
snd_pcm_info_set_device(pcminfo, dev);
|
||||
snd_pcm_info_set_subdevice(pcminfo, 0);
|
||||
snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
|
||||
|
||||
result = snd_ctl_pcm_info(handle, pcminfo);
|
||||
if (result < 0) {
|
||||
if (result != -ENOENT)
|
||||
qLog(Error) << "Unable to get control digital audio info for card"
|
||||
<< card << ":" << snd_strerror(result);
|
||||
continue;
|
||||
}
|
||||
|
||||
Device device;
|
||||
device.description = QString("%1 %2")
|
||||
.arg(snd_ctl_card_info_get_name(cardinfo))
|
||||
.arg(snd_pcm_info_get_name(pcminfo));
|
||||
device.device_property_value = QString("hw:%1,%2").arg(card).arg(dev);
|
||||
device.icon_name = GuessIconName(device.description);
|
||||
ret.append(device);
|
||||
}
|
||||
}
|
||||
|
||||
snd_config_update_free_global();
|
||||
|
||||
return ret;
|
||||
}
|
33
src/engines/alsadevicefinder.h
Normal file
33
src/engines/alsadevicefinder.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* This file is part of Clementine.
|
||||
Copyright 2017, Jonas Kvinge <jonas@jkvinge.net>
|
||||
|
||||
Clementine 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.
|
||||
|
||||
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ALSADEVICEFINDER_H
|
||||
#define ALSADEVICEFINDER_H
|
||||
|
||||
#include <QList>
|
||||
|
||||
#include "devicefinder.h"
|
||||
|
||||
class AlsaDeviceFinder : public DeviceFinder {
|
||||
public:
|
||||
AlsaDeviceFinder();
|
||||
|
||||
virtual bool Initialise() { return true; }
|
||||
virtual QList<Device> ListDevices();
|
||||
};
|
||||
|
||||
#endif // ALSADEVICEFINDER_H
|
@ -58,6 +58,10 @@
|
||||
#include "engines/pulsedevicefinder.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ALSA
|
||||
#include "engines/alsadevicefinder.h"
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_DARWIN
|
||||
#include "engines/osxdevicefinder.h"
|
||||
#endif
|
||||
@ -76,6 +80,7 @@
|
||||
#endif
|
||||
|
||||
using std::shared_ptr;
|
||||
using std::unique_ptr;
|
||||
using std::vector;
|
||||
|
||||
const char* GstEngine::kSettingsGroup = "GstEngine";
|
||||
@ -158,10 +163,23 @@ void GstEngine::InitialiseGstreamer() {
|
||||
plugin_names.insert(plugin.name);
|
||||
}
|
||||
|
||||
QList<DeviceFinder*> device_finders;
|
||||
bool pa(false);
|
||||
#ifdef HAVE_LIBPULSE
|
||||
device_finders.append(new PulseDeviceFinder);
|
||||
unique_ptr<DeviceFinder> finder_pulse(new PulseDeviceFinder);
|
||||
if (plugin_names.contains(finder_pulse->gstreamer_sink()) &&
|
||||
finder_pulse->Initialise()) {
|
||||
pa = true;
|
||||
device_finders_.append(finder_pulse.release());
|
||||
}
|
||||
#endif
|
||||
|
||||
QList<DeviceFinder*> device_finders;
|
||||
if (!pa) { // Only add alsa devices if pulseaudio is not enabled to avoid
|
||||
// confusion.
|
||||
#ifdef HAVE_ALSA
|
||||
device_finders.append(new AlsaDeviceFinder);
|
||||
#endif
|
||||
}
|
||||
#ifdef Q_OS_DARWIN
|
||||
device_finders.append(new OsxDeviceFinder);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user