forked from OpenGamers/abaddon
model stuff to track active device
also minor refactor
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
#include "devices.hpp"
|
#include "devices.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
@@ -24,35 +26,87 @@ void AudioDevices::SetDevices(ma_device_info *pPlayback, ma_uint32 playback_coun
|
|||||||
|
|
||||||
for (ma_uint32 i = 0; i < playback_count; i++) {
|
for (ma_uint32 i = 0; i < playback_count; i++) {
|
||||||
auto &d = pPlayback[i];
|
auto &d = pPlayback[i];
|
||||||
|
|
||||||
auto row = *m_playback->append();
|
auto row = *m_playback->append();
|
||||||
row[m_playback_columns.Name] = d.name;
|
row[m_playback_columns.Name] = d.name;
|
||||||
row[m_playback_columns.DeviceID] = d.id;
|
row[m_playback_columns.DeviceID] = d.id;
|
||||||
|
|
||||||
|
if (d.isDefault) {
|
||||||
|
m_default_playback_iter = row;
|
||||||
|
SetActivePlaybackDevice(row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_capture->clear();
|
m_capture->clear();
|
||||||
|
|
||||||
for (ma_uint32 i = 0; i < capture_count; i++) {
|
for (ma_uint32 i = 0; i < capture_count; i++) {
|
||||||
auto &d = pCapture[i];
|
auto &d = pCapture[i];
|
||||||
|
|
||||||
auto row = *m_capture->append();
|
auto row = *m_capture->append();
|
||||||
row[m_capture_columns.Name] = d.name;
|
row[m_capture_columns.Name] = d.name;
|
||||||
row[m_capture_columns.DeviceID] = d.id;
|
row[m_capture_columns.DeviceID] = d.id;
|
||||||
|
|
||||||
|
if (d.isDefault) {
|
||||||
|
m_default_capture_iter = row;
|
||||||
|
SetActiveCaptureDevice(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_default_playback_iter) {
|
||||||
|
spdlog::get("audio")->warn("No default playback device found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_default_capture_iter) {
|
||||||
|
spdlog::get("audio")->warn("No default capture device found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ma_device_id> AudioDevices::GetPlaybackDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const {
|
std::optional<ma_device_id> AudioDevices::GetPlaybackDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const {
|
||||||
if (iter) {
|
if (iter) {
|
||||||
return static_cast<ma_device_id>((*iter)[m_playback_columns.DeviceID]);
|
return static_cast<ma_device_id>((*iter)[m_playback_columns.DeviceID]);
|
||||||
} else {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ma_device_id> AudioDevices::GetCaptureDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const {
|
std::optional<ma_device_id> AudioDevices::GetCaptureDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const {
|
||||||
if (iter) {
|
if (iter) {
|
||||||
return static_cast<ma_device_id>((*iter)[m_capture_columns.DeviceID]);
|
return static_cast<ma_device_id>((*iter)[m_capture_columns.DeviceID]);
|
||||||
} else {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<ma_device_id> AudioDevices::GetDefaultPlayback() const {
|
||||||
|
if (m_default_playback_iter) {
|
||||||
|
return static_cast<ma_device_id>((*m_default_playback_iter)[m_playback_columns.DeviceID]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<ma_device_id> AudioDevices::GetDefaultCapture() const {
|
||||||
|
if (m_default_capture_iter) {
|
||||||
|
return static_cast<ma_device_id>((*m_default_capture_iter)[m_capture_columns.DeviceID]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDevices::SetActivePlaybackDevice(const Gtk::TreeModel::iterator &iter) {
|
||||||
|
m_active_playback_iter = iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDevices::SetActiveCaptureDevice(const Gtk::TreeModel::iterator &iter) {
|
||||||
|
m_active_capture_iter = iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gtk::TreeModel::iterator AudioDevices::GetActivePlaybackDevice() {
|
||||||
|
return m_active_playback_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gtk::TreeModel::iterator AudioDevices::GetActiveCaptureDevice() {
|
||||||
|
return m_active_capture_iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioDevices::PlaybackColumns::PlaybackColumns() {
|
AudioDevices::PlaybackColumns::PlaybackColumns() {
|
||||||
|
|||||||
@@ -17,8 +17,18 @@ public:
|
|||||||
Glib::RefPtr<Gtk::ListStore> GetCaptureDeviceModel();
|
Glib::RefPtr<Gtk::ListStore> GetCaptureDeviceModel();
|
||||||
|
|
||||||
void SetDevices(ma_device_info *pPlayback, ma_uint32 playback_count, ma_device_info *pCapture, ma_uint32 capture_count);
|
void SetDevices(ma_device_info *pPlayback, ma_uint32 playback_count, ma_device_info *pCapture, ma_uint32 capture_count);
|
||||||
std::optional<ma_device_id> GetPlaybackDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const;
|
|
||||||
std::optional<ma_device_id> GetCaptureDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const;
|
[[nodiscard]] std::optional<ma_device_id> GetPlaybackDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const;
|
||||||
|
[[nodiscard]] std::optional<ma_device_id> GetCaptureDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const;
|
||||||
|
|
||||||
|
[[nodiscard]] std::optional<ma_device_id> GetDefaultPlayback() const;
|
||||||
|
[[nodiscard]] std::optional<ma_device_id> GetDefaultCapture() const;
|
||||||
|
|
||||||
|
void SetActivePlaybackDevice(const Gtk::TreeModel::iterator &iter);
|
||||||
|
void SetActiveCaptureDevice(const Gtk::TreeModel::iterator &iter);
|
||||||
|
|
||||||
|
Gtk::TreeModel::iterator GetActivePlaybackDevice();
|
||||||
|
Gtk::TreeModel::iterator GetActiveCaptureDevice();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class PlaybackColumns : public Gtk::TreeModel::ColumnRecord {
|
class PlaybackColumns : public Gtk::TreeModel::ColumnRecord {
|
||||||
@@ -30,6 +40,8 @@ private:
|
|||||||
};
|
};
|
||||||
PlaybackColumns m_playback_columns;
|
PlaybackColumns m_playback_columns;
|
||||||
Glib::RefPtr<Gtk::ListStore> m_playback;
|
Glib::RefPtr<Gtk::ListStore> m_playback;
|
||||||
|
Gtk::TreeModel::iterator m_active_playback_iter;
|
||||||
|
Gtk::TreeModel::iterator m_default_playback_iter;
|
||||||
|
|
||||||
class CaptureColumns : public Gtk::TreeModel::ColumnRecord {
|
class CaptureColumns : public Gtk::TreeModel::ColumnRecord {
|
||||||
public:
|
public:
|
||||||
@@ -40,5 +52,7 @@ private:
|
|||||||
};
|
};
|
||||||
CaptureColumns m_capture_columns;
|
CaptureColumns m_capture_columns;
|
||||||
Glib::RefPtr<Gtk::ListStore> m_capture;
|
Glib::RefPtr<Gtk::ListStore> m_capture;
|
||||||
|
Gtk::TreeModel::iterator m_active_capture_iter;
|
||||||
|
Gtk::TreeModel::iterator m_default_capture_iter;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -71,24 +71,31 @@ AudioManager::AudioManager() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spdlog::get("audio")->info("Audio backend: {}", ma_get_backend_name(m_context.backend));
|
||||||
|
|
||||||
Enumerate();
|
Enumerate();
|
||||||
|
|
||||||
m_device_config = ma_device_config_init(ma_device_type_playback);
|
m_playback_config = ma_device_config_init(ma_device_type_playback);
|
||||||
m_device_config.playback.format = ma_format_f32;
|
m_playback_config.playback.format = ma_format_f32;
|
||||||
m_device_config.playback.channels = 2;
|
m_playback_config.playback.channels = 2;
|
||||||
m_device_config.sampleRate = 48000;
|
m_playback_config.sampleRate = 48000;
|
||||||
m_device_config.dataCallback = data_callback;
|
m_playback_config.dataCallback = data_callback;
|
||||||
m_device_config.pUserData = this;
|
m_playback_config.pUserData = this;
|
||||||
|
|
||||||
if (ma_device_init(nullptr, &m_device_config, &m_device) != MA_SUCCESS) {
|
if (const auto playback_id = m_devices.GetDefaultPlayback(); playback_id.has_value()) {
|
||||||
|
m_playback_id = *playback_id;
|
||||||
|
m_playback_config.playback.pDeviceID = &m_playback_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ma_device_init(&m_context, &m_playback_config, &m_playback_device) != MA_SUCCESS) {
|
||||||
spdlog::get("audio")->error("failed to initialize playback device");
|
spdlog::get("audio")->error("failed to initialize playback device");
|
||||||
m_ok = false;
|
m_ok = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ma_device_start(&m_device) != MA_SUCCESS) {
|
if (ma_device_start(&m_playback_device) != MA_SUCCESS) {
|
||||||
spdlog::get("audio")->error("failed to start playback");
|
spdlog::get("audio")->error("failed to start playback");
|
||||||
ma_device_uninit(&m_device);
|
ma_device_uninit(&m_playback_device);
|
||||||
m_ok = false;
|
m_ok = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -101,21 +108,30 @@ AudioManager::AudioManager() {
|
|||||||
m_capture_config.dataCallback = capture_data_callback;
|
m_capture_config.dataCallback = capture_data_callback;
|
||||||
m_capture_config.pUserData = this;
|
m_capture_config.pUserData = this;
|
||||||
|
|
||||||
if (ma_device_init(nullptr, &m_capture_config, &m_capture_device) != MA_SUCCESS) {
|
if (const auto capture_id = m_devices.GetDefaultCapture(); capture_id.has_value()) {
|
||||||
|
m_capture_id = *capture_id;
|
||||||
|
m_capture_config.capture.pDeviceID = &m_capture_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ma_device_init(&m_context, &m_capture_config, &m_capture_device) != MA_SUCCESS) {
|
||||||
spdlog::get("audio")->error("failed to initialize capture device");
|
spdlog::get("audio")->error("failed to initialize capture device");
|
||||||
m_ok = false;
|
m_ok = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char device_name[MA_MAX_DEVICE_NAME_LENGTH + 1];
|
char playback_device_name[MA_MAX_DEVICE_NAME_LENGTH + 1];
|
||||||
ma_device_get_name(&m_capture_device, ma_device_type_capture, device_name, sizeof(device_name), nullptr);
|
ma_device_get_name(&m_playback_device, ma_device_type_playback, playback_device_name, sizeof(playback_device_name), nullptr);
|
||||||
spdlog::get("audio")->info("using {} as capture device", device_name);
|
spdlog::get("audio")->info("using {} as playback device", playback_device_name);
|
||||||
|
|
||||||
|
char capture_device_name[MA_MAX_DEVICE_NAME_LENGTH + 1];
|
||||||
|
ma_device_get_name(&m_capture_device, ma_device_type_capture, capture_device_name, sizeof(capture_device_name), nullptr);
|
||||||
|
spdlog::get("audio")->info("using {} as capture device", capture_device_name);
|
||||||
|
|
||||||
Glib::signal_timeout().connect(sigc::mem_fun(*this, &AudioManager::DecayVolumeMeters), 40);
|
Glib::signal_timeout().connect(sigc::mem_fun(*this, &AudioManager::DecayVolumeMeters), 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioManager::~AudioManager() {
|
AudioManager::~AudioManager() {
|
||||||
ma_device_uninit(&m_device);
|
ma_device_uninit(&m_playback_device);
|
||||||
ma_device_uninit(&m_capture_device);
|
ma_device_uninit(&m_capture_device);
|
||||||
ma_context_uninit(&m_context);
|
ma_context_uninit(&m_context);
|
||||||
RemoveAllSSRCs();
|
RemoveAllSSRCs();
|
||||||
@@ -192,24 +208,26 @@ void AudioManager::SetPlaybackDevice(const Gtk::TreeModel::iterator &iter) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_devices.SetActivePlaybackDevice(iter);
|
||||||
|
|
||||||
m_playback_id = *device_id;
|
m_playback_id = *device_id;
|
||||||
|
|
||||||
ma_device_uninit(&m_device);
|
ma_device_uninit(&m_playback_device);
|
||||||
|
|
||||||
m_device_config = ma_device_config_init(ma_device_type_playback);
|
m_playback_config = ma_device_config_init(ma_device_type_playback);
|
||||||
m_device_config.playback.format = ma_format_f32;
|
m_playback_config.playback.format = ma_format_f32;
|
||||||
m_device_config.playback.channels = 2;
|
m_playback_config.playback.channels = 2;
|
||||||
m_device_config.playback.pDeviceID = &m_playback_id;
|
m_playback_config.playback.pDeviceID = &m_playback_id;
|
||||||
m_device_config.sampleRate = 48000;
|
m_playback_config.sampleRate = 48000;
|
||||||
m_device_config.dataCallback = data_callback;
|
m_playback_config.dataCallback = data_callback;
|
||||||
m_device_config.pUserData = this;
|
m_playback_config.pUserData = this;
|
||||||
|
|
||||||
if (ma_device_init(&m_context, &m_device_config, &m_device) != MA_SUCCESS) {
|
if (ma_device_init(&m_context, &m_playback_config, &m_playback_device) != MA_SUCCESS) {
|
||||||
spdlog::get("audio")->error("Failed to initialize new device");
|
spdlog::get("audio")->error("Failed to initialize new device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ma_device_start(&m_device) != MA_SUCCESS) {
|
if (ma_device_start(&m_playback_device) != MA_SUCCESS) {
|
||||||
spdlog::get("audio")->error("Failed to start new device");
|
spdlog::get("audio")->error("Failed to start new device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -224,6 +242,8 @@ void AudioManager::SetCaptureDevice(const Gtk::TreeModel::iterator &iter) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_devices.SetActiveCaptureDevice(iter);
|
||||||
|
|
||||||
m_capture_id = *device_id;
|
m_capture_id = *device_id;
|
||||||
|
|
||||||
ma_device_uninit(&m_capture_device);
|
ma_device_uninit(&m_capture_device);
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ private:
|
|||||||
bool m_ok;
|
bool m_ok;
|
||||||
|
|
||||||
// playback
|
// playback
|
||||||
ma_device m_device;
|
ma_device m_playback_device;
|
||||||
ma_device_config m_device_config;
|
ma_device_config m_playback_config;
|
||||||
ma_device_id m_playback_id;
|
ma_device_id m_playback_id;
|
||||||
// capture
|
// capture
|
||||||
ma_device m_capture_device;
|
ma_device m_capture_device;
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ VoiceWindow::VoiceWindow(Snowflake channel_id)
|
|||||||
m_playback_combo.set_hexpand(true);
|
m_playback_combo.set_hexpand(true);
|
||||||
m_playback_combo.set_halign(Gtk::ALIGN_FILL);
|
m_playback_combo.set_halign(Gtk::ALIGN_FILL);
|
||||||
m_playback_combo.set_model(Abaddon::Get().GetAudio().GetDevices().GetPlaybackDeviceModel());
|
m_playback_combo.set_model(Abaddon::Get().GetAudio().GetDevices().GetPlaybackDeviceModel());
|
||||||
|
m_playback_combo.set_active(Abaddon::Get().GetAudio().GetDevices().GetActivePlaybackDevice());
|
||||||
m_playback_combo.pack_start(*playback_renderer);
|
m_playback_combo.pack_start(*playback_renderer);
|
||||||
m_playback_combo.add_attribute(*playback_renderer, "text", 0);
|
m_playback_combo.add_attribute(*playback_renderer, "text", 0);
|
||||||
m_playback_combo.signal_changed().connect([this]() {
|
m_playback_combo.signal_changed().connect([this]() {
|
||||||
@@ -137,6 +138,7 @@ VoiceWindow::VoiceWindow(Snowflake channel_id)
|
|||||||
m_capture_combo.set_hexpand(true);
|
m_capture_combo.set_hexpand(true);
|
||||||
m_capture_combo.set_halign(Gtk::ALIGN_FILL);
|
m_capture_combo.set_halign(Gtk::ALIGN_FILL);
|
||||||
m_capture_combo.set_model(Abaddon::Get().GetAudio().GetDevices().GetCaptureDeviceModel());
|
m_capture_combo.set_model(Abaddon::Get().GetAudio().GetDevices().GetCaptureDeviceModel());
|
||||||
|
m_capture_combo.set_active(Abaddon::Get().GetAudio().GetDevices().GetActiveCaptureDevice());
|
||||||
m_capture_combo.pack_start(*capture_renderer);
|
m_capture_combo.pack_start(*capture_renderer);
|
||||||
m_capture_combo.add_attribute(*capture_renderer, "text", 0);
|
m_capture_combo.add_attribute(*capture_renderer, "text", 0);
|
||||||
m_capture_combo.signal_changed().connect([this]() {
|
m_capture_combo.signal_changed().connect([this]() {
|
||||||
|
|||||||
Reference in New Issue
Block a user