From e2784cd97bd9a4b5995c556d35bd4f08a2f4bad7 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Wed, 9 Nov 2022 19:03:53 -0500 Subject: model stuff to track active device also minor refactor --- src/audio/devices.cpp | 62 ++++++++++++++++++++++++++++++++++++++--- src/audio/devices.hpp | 18 ++++++++++-- src/audio/manager.cpp | 68 +++++++++++++++++++++++++++++---------------- src/audio/manager.hpp | 4 +-- src/windows/voicewindow.cpp | 2 ++ 5 files changed, 122 insertions(+), 32 deletions(-) diff --git a/src/audio/devices.cpp b/src/audio/devices.cpp index 5e7720b..dfb7164 100644 --- a/src/audio/devices.cpp +++ b/src/audio/devices.cpp @@ -3,6 +3,8 @@ // clang-format off #include "devices.hpp" +#include +#include // 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++) { auto &d = pPlayback[i]; + auto row = *m_playback->append(); row[m_playback_columns.Name] = d.name; row[m_playback_columns.DeviceID] = d.id; + + if (d.isDefault) { + m_default_playback_iter = row; + SetActivePlaybackDevice(row); + } } m_capture->clear(); for (ma_uint32 i = 0; i < capture_count; i++) { auto &d = pCapture[i]; + auto row = *m_capture->append(); row[m_capture_columns.Name] = d.name; 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 AudioDevices::GetPlaybackDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const { if (iter) { return static_cast((*iter)[m_playback_columns.DeviceID]); - } else { - return std::nullopt; } + + return std::nullopt; } std::optional AudioDevices::GetCaptureDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const { if (iter) { return static_cast((*iter)[m_capture_columns.DeviceID]); - } else { - return std::nullopt; } + + return std::nullopt; +} + +std::optional AudioDevices::GetDefaultPlayback() const { + if (m_default_playback_iter) { + return static_cast((*m_default_playback_iter)[m_playback_columns.DeviceID]); + } + + return std::nullopt; +} + +std::optional AudioDevices::GetDefaultCapture() const { + if (m_default_capture_iter) { + return static_cast((*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() { diff --git a/src/audio/devices.hpp b/src/audio/devices.hpp index 9d3de7d..c83bdb4 100644 --- a/src/audio/devices.hpp +++ b/src/audio/devices.hpp @@ -17,8 +17,18 @@ public: Glib::RefPtr GetCaptureDeviceModel(); void SetDevices(ma_device_info *pPlayback, ma_uint32 playback_count, ma_device_info *pCapture, ma_uint32 capture_count); - std::optional GetPlaybackDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const; - std::optional GetCaptureDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const; + + [[nodiscard]] std::optional GetPlaybackDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const; + [[nodiscard]] std::optional GetCaptureDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const; + + [[nodiscard]] std::optional GetDefaultPlayback() const; + [[nodiscard]] std::optional 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: class PlaybackColumns : public Gtk::TreeModel::ColumnRecord { @@ -30,6 +40,8 @@ private: }; PlaybackColumns m_playback_columns; Glib::RefPtr m_playback; + Gtk::TreeModel::iterator m_active_playback_iter; + Gtk::TreeModel::iterator m_default_playback_iter; class CaptureColumns : public Gtk::TreeModel::ColumnRecord { public: @@ -40,5 +52,7 @@ private: }; CaptureColumns m_capture_columns; Glib::RefPtr m_capture; + Gtk::TreeModel::iterator m_active_capture_iter; + Gtk::TreeModel::iterator m_default_capture_iter; }; #endif diff --git a/src/audio/manager.cpp b/src/audio/manager.cpp index 839bfc8..fcfa9f2 100644 --- a/src/audio/manager.cpp +++ b/src/audio/manager.cpp @@ -71,24 +71,31 @@ AudioManager::AudioManager() { return; } + spdlog::get("audio")->info("Audio backend: {}", ma_get_backend_name(m_context.backend)); + Enumerate(); - m_device_config = ma_device_config_init(ma_device_type_playback); - m_device_config.playback.format = ma_format_f32; - m_device_config.playback.channels = 2; - m_device_config.sampleRate = 48000; - m_device_config.dataCallback = data_callback; - m_device_config.pUserData = this; + m_playback_config = ma_device_config_init(ma_device_type_playback); + m_playback_config.playback.format = ma_format_f32; + m_playback_config.playback.channels = 2; + m_playback_config.sampleRate = 48000; + m_playback_config.dataCallback = data_callback; + m_playback_config.pUserData = this; + + 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(nullptr, &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 playback device"); m_ok = false; 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"); - ma_device_uninit(&m_device); + ma_device_uninit(&m_playback_device); m_ok = false; return; } @@ -101,21 +108,30 @@ AudioManager::AudioManager() { m_capture_config.dataCallback = capture_data_callback; 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"); m_ok = false; return; } - char 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); - spdlog::get("audio")->info("using {} as capture device", device_name); + char playback_device_name[MA_MAX_DEVICE_NAME_LENGTH + 1]; + 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 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); } AudioManager::~AudioManager() { - ma_device_uninit(&m_device); + ma_device_uninit(&m_playback_device); ma_device_uninit(&m_capture_device); ma_context_uninit(&m_context); RemoveAllSSRCs(); @@ -192,24 +208,26 @@ void AudioManager::SetPlaybackDevice(const Gtk::TreeModel::iterator &iter) { return; } + m_devices.SetActivePlaybackDevice(iter); + 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_device_config.playback.format = ma_format_f32; - m_device_config.playback.channels = 2; - m_device_config.playback.pDeviceID = &m_playback_id; - m_device_config.sampleRate = 48000; - m_device_config.dataCallback = data_callback; - m_device_config.pUserData = this; + m_playback_config = ma_device_config_init(ma_device_type_playback); + m_playback_config.playback.format = ma_format_f32; + m_playback_config.playback.channels = 2; + m_playback_config.playback.pDeviceID = &m_playback_id; + m_playback_config.sampleRate = 48000; + m_playback_config.dataCallback = data_callback; + 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"); 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"); return; } @@ -224,6 +242,8 @@ void AudioManager::SetCaptureDevice(const Gtk::TreeModel::iterator &iter) { return; } + m_devices.SetActiveCaptureDevice(iter); + m_capture_id = *device_id; ma_device_uninit(&m_capture_device); diff --git a/src/audio/manager.hpp b/src/audio/manager.hpp index 7805b30..7516918 100644 --- a/src/audio/manager.hpp +++ b/src/audio/manager.hpp @@ -70,8 +70,8 @@ private: bool m_ok; // playback - ma_device m_device; - ma_device_config m_device_config; + ma_device m_playback_device; + ma_device_config m_playback_config; ma_device_id m_playback_id; // capture ma_device m_capture_device; diff --git a/src/windows/voicewindow.cpp b/src/windows/voicewindow.cpp index 19d9863..7b574e4 100644 --- a/src/windows/voicewindow.cpp +++ b/src/windows/voicewindow.cpp @@ -126,6 +126,7 @@ VoiceWindow::VoiceWindow(Snowflake channel_id) m_playback_combo.set_hexpand(true); m_playback_combo.set_halign(Gtk::ALIGN_FILL); 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.add_attribute(*playback_renderer, "text", 0); 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_halign(Gtk::ALIGN_FILL); 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.add_attribute(*capture_renderer, "text", 0); m_capture_combo.signal_changed().connect([this]() { -- cgit v1.2.3