diff options
Diffstat (limited to 'src/audio')
-rw-r--r-- | src/audio/devices.cpp | 62 | ||||
-rw-r--r-- | src/audio/devices.hpp | 18 | ||||
-rw-r--r-- | src/audio/manager.cpp | 68 | ||||
-rw-r--r-- | src/audio/manager.hpp | 4 |
4 files changed, 120 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 <cstring> +#include <spdlog/spdlog.h> // 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<ma_device_id> AudioDevices::GetPlaybackDeviceIDFromModel(const Gtk::TreeModel::iterator &iter) const { if (iter) { 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 { if (iter) { 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() { 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<Gtk::ListStore> GetCaptureDeviceModel(); 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: class PlaybackColumns : public Gtk::TreeModel::ColumnRecord { @@ -30,6 +40,8 @@ private: }; PlaybackColumns m_playback_columns; 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 { public: @@ -40,5 +52,7 @@ private: }; CaptureColumns m_capture_columns; Glib::RefPtr<Gtk::ListStore> 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; |