Add ability to choose audio output device via a menu

This commit is contained in:
Lorenzooone
2025-02-02 09:59:51 +01:00
parent 7288cf163a
commit 36a9cfbe8b
12 changed files with 284 additions and 32 deletions

View File

@@ -489,7 +489,7 @@ if(MSVC)
else()
set_source_files_properties(source/conversions.cpp PROPERTIES COMPILE_OPTIONS "$<$<CONFIG:Release>:-O3>")
endif()
add_executable(${OUTPUT_NAME} source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/WindowScreen.cpp source/WindowScreen_Menu.cpp source/devicecapture.cpp source/conversions.cpp source/ExtraButtons.cpp source/Menus/ConnectionMenu.cpp source/Menus/OptionSelectionMenu.cpp source/Menus/MainMenu.cpp source/Menus/VideoMenu.cpp source/Menus/CropMenu.cpp source/Menus/PARMenu.cpp source/Menus/RotationMenu.cpp source/Menus/OffsetMenu.cpp source/Menus/AudioMenu.cpp source/Menus/BFIMenu.cpp source/Menus/RelativePositionMenu.cpp source/Menus/ResolutionMenu.cpp source/Menus/FileConfigMenu.cpp source/Menus/ExtraSettingsMenu.cpp source/Menus/StatusMenu.cpp source/Menus/LicenseMenu.cpp source/WindowCommands.cpp source/Menus/ShortcutMenu.cpp source/Menus/ActionSelectionMenu.cpp source/Menus/ScalingRatioMenu.cpp source/Menus/ISNitroMenu.cpp source/Menus/VideoEffectsMenu.cpp source/CaptureDataBuffers.cpp source/Menus/InputMenu.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp ${TOOLS_DATA_DIR}/shaders_list.cpp ${SOURCE_CPP_EXTRA_FILES})
add_executable(${OUTPUT_NAME} source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/WindowScreen.cpp source/WindowScreen_Menu.cpp source/devicecapture.cpp source/conversions.cpp source/ExtraButtons.cpp source/Menus/ConnectionMenu.cpp source/Menus/OptionSelectionMenu.cpp source/Menus/MainMenu.cpp source/Menus/VideoMenu.cpp source/Menus/CropMenu.cpp source/Menus/PARMenu.cpp source/Menus/RotationMenu.cpp source/Menus/OffsetMenu.cpp source/Menus/AudioMenu.cpp source/Menus/BFIMenu.cpp source/Menus/RelativePositionMenu.cpp source/Menus/ResolutionMenu.cpp source/Menus/FileConfigMenu.cpp source/Menus/ExtraSettingsMenu.cpp source/Menus/StatusMenu.cpp source/Menus/LicenseMenu.cpp source/WindowCommands.cpp source/Menus/ShortcutMenu.cpp source/Menus/ActionSelectionMenu.cpp source/Menus/ScalingRatioMenu.cpp source/Menus/ISNitroMenu.cpp source/Menus/VideoEffectsMenu.cpp source/CaptureDataBuffers.cpp source/Menus/InputMenu.cpp source/Menus/AudioDeviceMenu.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp ${TOOLS_DATA_DIR}/shaders_list.cpp ${SOURCE_CPP_EXTRA_FILES})
if(NOT ("${EXTRA_DEPENDENCIES}" STREQUAL ""))

View File

@@ -0,0 +1,31 @@
#ifndef __AUDIODEVICEMENU_HPP
#define __AUDIODEVICEMENU_HPP
#include "OptionSelectionMenu.hpp"
#include <chrono>
#include "TextRectangle.hpp"
#include "sfml_gfx_structs.hpp"
#include "display_structs.hpp"
#include "audio_data.hpp"
#define AUDIODEVICE_MENU_NO_ACTION -1
#define AUDIODEVICE_MENU_BACK -2
class AudioDeviceMenu : public OptionSelectionMenu {
public:
AudioDeviceMenu(bool font_load_success, sf::Font &text_font);
~AudioDeviceMenu();
void prepare(float scaling_factor, int view_size_x, int view_size_y, const audio_output_device_data curr_device_data);
void insert_data(std::vector<std::string>* possible_devices);
int selected_index = AUDIODEVICE_MENU_NO_ACTION;
void reset_output_option();
protected:
void set_output_option(int index, int action);
int get_num_options();
std::string get_string_option(int index, int action);
void class_setup();
private:
std::vector<std::string>* possible_devices;
};
#endif

View File

@@ -19,7 +19,7 @@ enum AudioMenuOutAction{
AUDIO_MENU_OUTPUT_DEC,
AUDIO_MENU_OUTPUT_INC,
AUDIO_MENU_RESTART,
AUDIO_MENU_NEXT_DEVICE,
AUDIO_MENU_CHANGE_DEVICE,
};
class AudioMenu : public OptionSelectionMenu {

View File

@@ -2,10 +2,18 @@
#define __AUDIO_DATA_HPP
#include <string>
#include <vector>
#define MAX_MAX_AUDIO_LATENCY 10
enum AudioOutputType {AUDIO_OUTPUT_STEREO, AUDIO_OUTPUT_MONO, AUDIO_OUTPUT_END};
struct audio_output_device_data {
bool preference_requested = false;
std::string preferred = "";
};
int searchAudioDevice(std::string device_name, std::vector<std::string> &audio_devices);
class AudioData {
public:
void reset();
@@ -27,12 +35,15 @@ public:
bool load_audio_data(std::string key, std::string value);
std::string save_audio_data();
void set_audio_volume(int new_volume);
audio_output_device_data get_audio_output_device_data();
void set_audio_output_device_data(audio_output_device_data new_device_data);
private:
int volume;
int max_audio_latency;
bool mute;
AudioOutputType output_type;
audio_output_device_data output_device;
bool restart_request = false;
bool text_updated;
std::string text;
@@ -44,6 +55,8 @@ private:
const std::string volume_str = "volume";
const std::string mute_str = "mute";
const std::string output_type_str = "audio_output_type";
const std::string device_request_str = "audio_output_device_requested";
const std::string device_name_str = "audio_output_device_name";
};
#endif

View File

@@ -14,7 +14,7 @@
enum ScreenType { TOP, BOTTOM, JOINT };
enum BottomRelativePosition { UNDER_TOP, LEFT_TOP, ABOVE_TOP, RIGHT_TOP, BOT_REL_POS_END };
enum NonIntegerScalingModes { SMALLER_PRIORITY, INVERSE_PROPORTIONAL_PRIORITY, EQUAL_PRIORITY, PROPORTIONAL_PRIORITY, BIGGER_PRIORITY, END_NONINT_SCALE_MODES };
enum CurrMenuType { DEFAULT_MENU_TYPE, CONNECT_MENU_TYPE, MAIN_MENU_TYPE, VIDEO_MENU_TYPE, AUDIO_MENU_TYPE, CROP_MENU_TYPE, TOP_PAR_MENU_TYPE, BOTTOM_PAR_MENU_TYPE, ROTATION_MENU_TYPE, OFFSET_MENU_TYPE, BFI_MENU_TYPE, LOAD_MENU_TYPE, SAVE_MENU_TYPE, RESOLUTION_MENU_TYPE, EXTRA_MENU_TYPE, STATUS_MENU_TYPE, LICENSES_MENU_TYPE, RELATIVE_POS_MENU_TYPE, SHORTCUTS_MENU_TYPE, ACTION_SELECTION_MENU_TYPE, SCALING_RATIO_MENU_TYPE, ISN_MENU_TYPE, VIDEO_EFFECTS_MENU_TYPE, INPUT_MENU_TYPE };
enum CurrMenuType { DEFAULT_MENU_TYPE, CONNECT_MENU_TYPE, MAIN_MENU_TYPE, VIDEO_MENU_TYPE, AUDIO_MENU_TYPE, CROP_MENU_TYPE, TOP_PAR_MENU_TYPE, BOTTOM_PAR_MENU_TYPE, ROTATION_MENU_TYPE, OFFSET_MENU_TYPE, BFI_MENU_TYPE, LOAD_MENU_TYPE, SAVE_MENU_TYPE, RESOLUTION_MENU_TYPE, EXTRA_MENU_TYPE, STATUS_MENU_TYPE, LICENSES_MENU_TYPE, RELATIVE_POS_MENU_TYPE, SHORTCUTS_MENU_TYPE, ACTION_SELECTION_MENU_TYPE, SCALING_RATIO_MENU_TYPE, ISN_MENU_TYPE, VIDEO_EFFECTS_MENU_TYPE, INPUT_MENU_TYPE, AUDIO_DEVICE_MENU_TYPE };
enum InputColorspaceMode { FULL_COLORSPACE, DS_COLORSPACE, GBA_COLORSPACE, INPUT_COLORSPACE_END };
enum FrameBlendingMode { NO_FRAME_BLENDING, FULL_FRAME_BLENDING, DS_3D_BOTH_SCREENS_FRAME_BLENDING, FRAME_BLENDING_END };

View File

@@ -33,6 +33,7 @@
#include "ISNitroMenu.hpp"
#include "VideoEffectsMenu.hpp"
#include "InputMenu.hpp"
#include "AudioDeviceMenu.hpp"
#include "display_structs.hpp"
#include "event_structs.hpp"
#include "shaders_list.hpp"
@@ -153,12 +154,14 @@ private:
ScalingRatioMenu *scaling_ratio_menu;
VideoEffectsMenu *video_effects_menu;
InputMenu *input_menu;
AudioDeviceMenu *audio_device_menu;
std::vector<const CropData*> possible_crops;
std::vector<const CropData*> possible_crops_ds;
std::vector<const CropData*> possible_crops_with_games;
std::vector<const CropData*> possible_crops_ds_with_games;
std::vector<const PARData*> possible_pars;
std::vector<sf::VideoMode> possible_resolutions;
std::vector<std::string> possible_audio_devices;
std::vector<FileData> possible_files;
std::vector<std::string> possible_buttons_names;
std::vector<const WindowCommand **> possible_buttons_ptrs;
@@ -226,6 +229,7 @@ private:
void fast_poll_change();
void padding_change();
void game_crop_enable_change();
void audio_device_change(audio_output_device_data new_device_data);
void is_nitro_capture_type_change(bool positive);
void is_nitro_capture_speed_change(bool positive);
void is_nitro_capture_reset_hw();
@@ -299,6 +303,7 @@ private:
void setup_bfi_menu(bool reset_data = true);
void setup_fileconfig_menu(bool is_save, bool reset_data = true, bool skip_setup_check = false);
void setup_resolution_menu(bool reset_data = true);
void setup_audio_devices_menu(bool reset_data = true);
void setup_extra_menu(bool reset_data = true);
void setup_shortcuts_menu(bool reset_data = true);
void setup_action_selection_menu(bool reset_data = true);

View File

@@ -262,6 +262,8 @@ static void cypress_device_read_frame_cb(void* user_data, int transfer_length, i
if((*cypress_device_capture_recv_data->consecutive_output_to_thread) > NUM_CONSECUTIVE_NEEDED_OUTPUT)
*cypress_device_capture_recv_data->errors_since_last_output = 0;
*cypress_device_capture_recv_data->last_index = cypress_device_capture_recv_data->index;
// Realign, with multiple of max_usb_packet_size
if((*cypress_device_capture_recv_data->is_active_special_read) && (((int32_t)(cypress_device_capture_recv_data->index - (*cypress_device_capture_recv_data->active_special_read_index))) >= 0)) {
*cypress_device_capture_recv_data->is_active_special_read = false;
return end_cypress_device_read_frame_cb(cypress_device_capture_recv_data);
@@ -394,6 +396,12 @@ void reset_cypress_device_status(CypressDeviceCaptureReceivedData* cypress_devic
}
void recalibration_reads(cyni_device_device_handlers* handlers, const cyni_device_usb_device* usb_device_desc, CypressDeviceCaptureReceivedData* cypress_device_capture_recv_data, CypressDeviceCaptureReceivedData* chosen_buffer, uint32_t &index, CaptureScreensType curr_capture_type) {
// Enforce properly synchronized reads.
// Reduces complexity and latency, at the cost of some extra
// time between lid reopening and visible video output.
// For differences which are multiple of max_usb_packet_size,
// regular reads can be used. For non-multiples, use this,
// which adds sleeps to better align.
CaptureData* capture_data = cypress_device_capture_recv_data[0].capture_data;
do {
if(get_cypress_device_status(cypress_device_capture_recv_data) < 0)

View File

@@ -0,0 +1,71 @@
#include "AudioDeviceMenu.hpp"
AudioDeviceMenu::AudioDeviceMenu(bool font_load_success, sf::Font &text_font) : OptionSelectionMenu(){
this->initialize(font_load_success, text_font);
}
AudioDeviceMenu::~AudioDeviceMenu() {
}
void AudioDeviceMenu::class_setup() {
this->num_options_per_screen = 5;
this->min_elements_text_scaling_factor = num_options_per_screen + 2;
this->width_factor_menu = 16;
this->width_divisor_menu = 9;
this->base_height_factor_menu = 12;
this->base_height_divisor_menu = 6;
this->min_text_size = 0.3;
this->max_width_slack = 1.1;
this->menu_color = sf::Color(30, 30, 60, 192);
this->title = "Audio Device Selection";
this->show_back_x = true;
this->show_x = false;
this->show_title = true;
}
void AudioDeviceMenu::insert_data(std::vector<std::string>* possible_devices) {
this->possible_devices = possible_devices;
this->prepare_options();
}
void AudioDeviceMenu::reset_output_option() {
this->selected_index = AUDIODEVICE_MENU_NO_ACTION;
}
void AudioDeviceMenu::set_output_option(int index, int action) {
if(index == BACK_X_OUTPUT_OPTION)
this->selected_index = AUDIODEVICE_MENU_BACK;
else
this->selected_index = index;
}
int AudioDeviceMenu::get_num_options() {
return this->possible_devices->size() + 1;
}
std::string AudioDeviceMenu::get_string_option(int index, int action) {
if(index == 0)
return "System Preference";
return (*this->possible_devices)[index - 1];
}
void AudioDeviceMenu::prepare(float menu_scaling_factor, int view_size_x, int view_size_y, const audio_output_device_data curr_device_data) {
int num_pages = this->get_num_pages();
if(this->future_data.page >= num_pages)
this->future_data.page = num_pages - 1;
int start = this->future_data.page * this->num_options_per_screen;
for(int i = 0; i < this->num_options_per_screen + 1; i++) {
int index = (i * this->single_option_multiplier) + this->elements_start_id;
if(!this->future_enabled_labels[index])
continue;
int mode_index = start + i;
int device_index = -1;
if(curr_device_data.preference_requested)
device_index = searchAudioDevice(curr_device_data.preferred, *this->possible_devices);
if(mode_index == (device_index + 1))
this->labels[index]->setText("< " + this->get_string_option(mode_index, DEFAULT_ACTION) + " >");
else
this->labels[index]->setText(this->get_string_option(mode_index, DEFAULT_ACTION));
}
this->base_prepare(menu_scaling_factor, view_size_x, view_size_y);
}

View File

@@ -40,9 +40,9 @@ static const AudioMenuOptionInfo audio_restart_option = {
.out_action = AUDIO_MENU_RESTART};
static const AudioMenuOptionInfo audio_next_device_option = {
.base_name = "Output Device", .false_name = "",
.base_name = "Select Output Device", .false_name = "",
.is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = AUDIO_MENU_NO_ACTION,
.out_action = AUDIO_MENU_NEXT_DEVICE};
.out_action = AUDIO_MENU_CHANGE_DEVICE};
static const AudioMenuOptionInfo* pollable_options[] = {
@@ -50,8 +50,8 @@ static const AudioMenuOptionInfo* pollable_options[] = {
&audio_mute_option,
&audio_max_latency_option,
&audio_output_type_option,
&audio_restart_option,
&audio_next_device_option,
&audio_restart_option,
};
AudioMenu::AudioMenu(bool font_load_success, sf::Font &text_font) : OptionSelectionMenu(){
@@ -144,11 +144,6 @@ void AudioMenu::prepare(float menu_scaling_factor, int view_size_x, int view_siz
case AUDIO_MENU_MUTE:
this->labels[index]->setText(this->setTextOptionBool(real_index, audio_data->get_mute()));
break;
case AUDIO_MENU_NEXT_DEVICE:
if (std::optional<std::string> cur_dev = sf::PlaybackDevice::getDevice()) {
this->labels[index]->setText(this->setTextOptionString(real_index, *cur_dev));
}
break;
default:
break;
}

View File

@@ -115,6 +115,7 @@ void WindowScreen::init_menus() {
this->is_nitro_menu = new ISNitroMenu(this->font_load_success, this->text_font);
this->video_effects_menu = new VideoEffectsMenu(this->font_load_success, this->text_font);
this->input_menu = new InputMenu(this->font_load_success, this->text_font);
this->audio_device_menu = new AudioDeviceMenu(this->font_load_success, this->text_font);
}
void WindowScreen::destroy_menus() {
@@ -139,6 +140,7 @@ void WindowScreen::destroy_menus() {
delete this->is_nitro_menu;
delete this->video_effects_menu;
delete this->input_menu;
delete this->audio_device_menu;
}
void WindowScreen::set_close(int ret_val) {
@@ -289,6 +291,11 @@ void WindowScreen::offset_change(float &value, float change) {
this->future_operations.call_screen_settings_update = true;
}
void WindowScreen::audio_device_change(audio_output_device_data new_device_data) {
this->audio_data->set_audio_output_device_data(new_device_data);
this->print_notification("Audio device changed");
}
void WindowScreen::menu_scaling_change(bool positive) {
double old_scaling = this->m_info.menu_scaling_factor;
if(positive)
@@ -694,6 +701,20 @@ void WindowScreen::setup_input_menu(bool reset_data) {
}
}
void WindowScreen::setup_audio_devices_menu(bool reset_data){
if(!this->can_setup_menu())
return;
if(this->curr_menu != AUDIO_DEVICE_MENU_TYPE) {
this->possible_audio_devices.clear();
this->possible_audio_devices = sf::PlaybackDevice::getAvailableDevices();
this->curr_menu = AUDIO_DEVICE_MENU_TYPE;
if(reset_data)
this->audio_device_menu->reset_data();
this->audio_device_menu->insert_data(&this->possible_audio_devices);
this->last_menu_change_time = std::chrono::high_resolution_clock::now();
}
}
void WindowScreen::setup_video_menu(bool reset_data) {
if(!this->can_setup_menu())
return;
@@ -1374,24 +1395,9 @@ void WindowScreen::poll(bool do_everything) {
case AUDIO_MENU_RESTART:
this->audio_data->request_audio_restart();
break;
case AUDIO_MENU_NEXT_DEVICE:
if (std::optional<std::string> cur_dev = sf::PlaybackDevice::getDevice()) {
std::cout << *cur_dev << std::endl;
int idx = 0;
auto audio_devices = sf::PlaybackDevice::getAvailableDevices();
for (const std::string& device : audio_devices) {
if (device == *cur_dev) {
break;
}
idx++;
}
idx = std::max((idx + 1) % static_cast<int>(audio_devices.size()), 0);
std::cout << "next device: " << audio_devices.at(idx) << std::endl;
if (sf::PlaybackDevice::setDevice(audio_devices.at(idx))) {
std::cout << "Device selected: " << audio_devices.at(idx) << std::endl;
// this->audio_data->request_audio_restart();
}
}
case AUDIO_MENU_CHANGE_DEVICE:
this->setup_audio_devices_menu();
done = true;
break;
default:
break;
@@ -1984,6 +1990,29 @@ void WindowScreen::poll(bool do_everything) {
continue;
}
break;
case AUDIO_DEVICE_MENU_TYPE:
if(this->audio_device_menu->poll(event_data)) {
switch(this->audio_device_menu->selected_index) {
case AUDIODEVICE_MENU_BACK:
this->setup_audio_menu(false);
done = true;
break;
case AUDIODEVICE_MENU_NO_ACTION:
break;
default:
audio_output_device_data tmp_out_device;
int output_device_index = this->audio_device_menu->selected_index - 1;
if((output_device_index >= 0) && (output_device_index < this->possible_audio_devices.size())) {
tmp_out_device.preference_requested = true;
tmp_out_device.preferred = this->possible_audio_devices[output_device_index];
}
this->audio_device_change(tmp_out_device);
break;
}
this->audio_device_menu->reset_output_option();
continue;
}
break;
default:
break;
}
@@ -2257,6 +2286,9 @@ void WindowScreen::prepare_menu_draws(int view_size_x, int view_size_y) {
case INPUT_MENU_TYPE:
this->input_menu->prepare(this->loaded_info.menu_scaling_factor, view_size_x, view_size_y, &this->shared_data->input_data);
break;
case AUDIO_DEVICE_MENU_TYPE:
this->audio_device_menu->prepare(this->loaded_info.menu_scaling_factor, view_size_x, view_size_y, this->audio_data->get_audio_output_device_data());
break;
default:
break;
}
@@ -2333,6 +2365,9 @@ void WindowScreen::execute_menu_draws() {
case INPUT_MENU_TYPE:
this->input_menu->draw(this->loaded_info.menu_scaling_factor, this->m_win);
break;
case AUDIO_DEVICE_MENU_TYPE:
this->audio_device_menu->draw(this->loaded_info.menu_scaling_factor, this->m_win);
break;
default:
break;
}

View File

@@ -1,5 +1,15 @@
#include "audio_data.hpp"
int searchAudioDevice(std::string device_name, std::vector<std::string> &audio_devices) {
int index = -1;
for(int i = 0; i < audio_devices.size(); i++)
if(audio_devices[i] == device_name) {
index = i;
break;
}
return index;
}
void AudioData::reset() {
this->volume = 100;
this->mute = false;
@@ -7,6 +17,8 @@ void AudioData::reset() {
this->output_type = AUDIO_OUTPUT_STEREO;
this->restart_request = false;
this->text_updated = false;
this->output_device.preference_requested = false;
this->output_device.preferred = "";
}
void AudioData::change_max_audio_latency(bool is_change_positive) {
@@ -77,6 +89,19 @@ bool AudioData::has_text_to_print() {
return retval;
}
void AudioData::set_audio_output_device_data(audio_output_device_data new_device_data) {
bool had_preference = this->output_device.preference_requested;
if(had_preference)
this->output_device.preference_requested = new_device_data.preference_requested;
this->output_device.preferred = new_device_data.preferred;
if(!had_preference)
this->output_device.preference_requested = new_device_data.preference_requested;
}
audio_output_device_data AudioData::get_audio_output_device_data() {
return this->output_device;
}
std::string AudioData::text_to_print() {
return this->text;
}
@@ -147,6 +172,14 @@ bool AudioData::load_audio_data(std::string key, std::string value) {
this->set_audio_output_type(std::stoi(value));
return true;
}
if (key == this->device_request_str) {
this->output_device.preference_requested = std::stoi(value);
return true;
}
if (key == this->device_name_str) {
this->output_device.preferred = value;
return true;
}
return false;
}
@@ -156,6 +189,8 @@ std::string AudioData::save_audio_data() {
out_str += this->volume_str + "=" + std::to_string(this->volume) + "\n";
out_str += this->max_audio_latency_str + "=" + std::to_string(this->max_audio_latency) + "\n";
out_str += this->output_type_str + "=" + std::to_string(this->output_type) + "\n";
out_str += this->device_request_str + "=" + std::to_string(this->output_device.preference_requested) + "\n";
out_str += this->device_name_str + "=" + this->output_device.preferred + "\n";
return out_str;
}

View File

@@ -328,12 +328,25 @@ static void executeSoundRestart(Audio &audio, AudioData* audio_data, bool do_res
audio.play();
}
static bool setDefaultAudioDevice(Audio &audio) {
bool success = false;
std::optional<std::string> default_device = sf::PlaybackDevice::getDefaultDevice();
if(default_device) {
audio.stop_audio();
audio.stop();
success = sf::PlaybackDevice::setDevice(default_device.value());
}
return success;
}
static void soundCall(AudioData *audio_data, CaptureData* capture_data) {
std::int16_t (*out_buf)[MAX_SAMPLES_IN] = new std::int16_t[NUM_CONCURRENT_AUDIO_BUFFERS][MAX_SAMPLES_IN];
Audio audio(audio_data);
int audio_buf_counter = 0;
const bool endianness = is_big_endian();
volatile int loaded_samples;
audio_output_device_data in_use_audio_output_device_data;
std::optional<std::string> curr_device = sf::PlaybackDevice::getDevice();
while(capture_data->status.running) {
if(capture_data->status.connected && capture_data->status.device.has_audio) {
@@ -361,14 +374,22 @@ static void soundCall(AudioData *audio_data, CaptureData* capture_data) {
loaded_samples = audio.samples.size();
if(audio.getStatus() != sf::SoundStream::Status::Playing) {
audio.stop_audio();
if(loaded_samples > 0)
executeSoundRestart(audio, audio_data, audio.restart);
if(loaded_samples > 0) {
bool do_restart = audio.restart;
executeSoundRestart(audio, audio_data, do_restart);
if(do_restart) {
in_use_audio_output_device_data.preference_requested = false;
curr_device = sf::PlaybackDevice::getDevice();
}
}
}
else {
if(loaded_samples > 0) {
if(audio.hasTooMuchTimeElapsed()) {
audio.stop_audio();
executeSoundRestart(audio, audio_data, true);
in_use_audio_output_device_data.preference_requested = false;
curr_device = sf::PlaybackDevice::getDevice();
}
}
audio.update_volume();
@@ -379,6 +400,44 @@ static void soundCall(AudioData *audio_data, CaptureData* capture_data) {
audio.stop();
default_sleep();
}
// Code for audio device selection
audio_output_device_data new_audio_output_device_data = audio_data->get_audio_output_device_data();
if((new_audio_output_device_data.preference_requested != in_use_audio_output_device_data.preference_requested) || (new_audio_output_device_data.preference_requested && (new_audio_output_device_data.preferred != in_use_audio_output_device_data.preferred))) {
int index = -1;
bool success = false;
if(new_audio_output_device_data.preference_requested) {
std::vector<std::string> audio_devices = sf::PlaybackDevice::getAvailableDevices();
index = searchAudioDevice(new_audio_output_device_data.preferred, audio_devices);
if(index != -1) {
audio.stop_audio();
audio.stop();
success = sf::PlaybackDevice::setDevice(audio_devices[index]);
}
}
if(index == -1)
success = setDefaultAudioDevice(audio);
if(success)
curr_device = sf::PlaybackDevice::getDevice();
}
in_use_audio_output_device_data = new_audio_output_device_data;
if(!in_use_audio_output_device_data.preference_requested) {
std::optional<std::string> default_device = sf::PlaybackDevice::getDefaultDevice();
if(default_device != curr_device) {
bool success = setDefaultAudioDevice(audio);
if(success)
curr_device = sf::PlaybackDevice::getDevice();
}
}
else if(curr_device) {
std::vector<std::string> audio_devices = sf::PlaybackDevice::getAvailableDevices();
int index = searchAudioDevice(curr_device.value(), audio_devices);
if(index == -1) {
bool success = setDefaultAudioDevice(audio);
if(success)
curr_device = sf::PlaybackDevice::getDevice();
}
}
}
audio.stop_audio();
@@ -765,7 +824,7 @@ int main(int argc, char **argv) {
std::cout << " even if multiple are present." << std::endl;
std::cout << " --failure_close Automatically closes the software if the first connection" << std::endl;
std::cout << " doesn't succeed." << std::endl;
std::cout << " --failure_close Automatically closes the software on disconnect." << std::endl;
std::cout << " --auto_close Automatically closes the software on disconnect." << std::endl;
std::cout << " --profile Loads the profile with the specified ID at startup" << std::endl;
std::cout << " instead of the default one. When the program closes," << std::endl;
std::cout << " the data is also saved to the specified profile." << std::endl;