Browse Source

Add option for selecting audio device

pull/4644/head
staphen 4 years ago committed by Anders Jenbo
parent
commit
83168f7954
  1. 74
      Source/options.cpp
  2. 30
      Source/options.h
  3. 2
      Source/sound.cpp

74
Source/options.cpp

@ -638,9 +638,11 @@ AudioOptions::AudioOptions()
bufferSize.SetValueChangedCallback(OptionAudioChanged);
resamplingQuality.SetValueChangedCallback(OptionAudioChanged);
resampler.SetValueChangedCallback(OptionAudioChanged);
device.SetValueChangedCallback(OptionAudioChanged);
}
std::vector<OptionEntryBase *> AudioOptions::GetEntries()
{
// clang-format off
return {
&soundVolume,
&musicVolume,
@ -652,7 +654,11 @@ std::vector<OptionEntryBase *> AudioOptions::GetEntries()
&bufferSize,
&resampler,
&resamplingQuality,
#if SDL_VERSION_ATLEAST(2, 0, 0)
&device,
#endif
};
// clang-format on
}
OptionEntryResolution::OptionEntryResolution()
@ -812,6 +818,74 @@ void OptionEntryResampler::UpdateDependentOptions() const
#endif
}
OptionEntryAudioDevice::OptionEntryAudioDevice()
: OptionEntryListBase("Device", OptionEntryFlags::CantChangeInGame, N_("Device"), N_("Audio device"))
{
}
void OptionEntryAudioDevice::LoadFromIni(string_view category)
{
char deviceStr[100];
GetIniValue(category, key, deviceStr, sizeof(deviceStr), "");
deviceName_ = deviceStr;
}
void OptionEntryAudioDevice::SaveToIni(string_view category) const
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
SetIniValue(category, key, deviceName_);
#endif
}
size_t OptionEntryAudioDevice::GetListSize() const
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
return SDL_GetNumAudioDevices(false) + 1;
#else
return 1;
#endif
}
string_view OptionEntryAudioDevice::GetListDescription(size_t index) const
{
constexpr size_t MaxWidth = 500;
string_view deviceName = GetDeviceName(index);
if (deviceName.empty())
return "System Default";
while (GetLineWidth(deviceName, GameFont24, 1) > MaxWidth) {
size_t lastSymbolIndex = FindLastUtf8Symbols(deviceName);
deviceName = string_view(deviceName.data(), lastSymbolIndex);
}
return deviceName;
}
size_t OptionEntryAudioDevice::GetActiveListIndex() const
{
for (size_t i = 0; i < GetListSize(); i++) {
string_view deviceName = GetDeviceName(i);
if (deviceName == deviceName_)
return i;
}
return 0;
}
void OptionEntryAudioDevice::SetActiveListIndex(size_t index)
{
deviceName_ = std::string { GetDeviceName(index) };
NotifyValueChanged();
}
string_view OptionEntryAudioDevice::GetDeviceName(size_t index) const
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (index != 0)
return SDL_GetAudioDeviceName(index - 1, false);
#endif
return "";
}
GraphicsOptions::GraphicsOptions()
: OptionCategoryBase("Graphics", N_("Graphics"), N_("Graphics Settings"))
, fullscreen("Fullscreen", OnlyIfSupportsWindowed | OptionEntryFlags::CantChangeInGame | OptionEntryFlags::RecreateUI, N_("Fullscreen"), N_("Display the game in windowed or fullscreen mode."), true)

30
Source/options.h

@ -339,6 +339,34 @@ private:
Resampler resampler_;
};
class OptionEntryAudioDevice : public OptionEntryListBase {
public:
OptionEntryAudioDevice();
void LoadFromIni(string_view category) override;
void SaveToIni(string_view category) const override;
[[nodiscard]] size_t GetListSize() const override;
[[nodiscard]] string_view GetListDescription(size_t index) const override;
[[nodiscard]] size_t GetActiveListIndex() const override;
void SetActiveListIndex(size_t index) override;
std::string operator*() const
{
for (size_t i = 0; i < GetListSize(); i++) {
string_view deviceName = GetDeviceName(i);
if (deviceName == deviceName_)
return deviceName_;
}
return "";
}
private:
string_view GetDeviceName(size_t index) const;
std::string deviceName_;
};
struct OptionCategoryBase {
OptionCategoryBase(string_view key, string_view name, string_view description);
@ -414,6 +442,8 @@ struct AudioOptions : OptionCategoryBase {
OptionEntryResampler resampler;
/** @brief Quality of the resampler, from 0 (lowest) to 10 (highest). Available for the speex resampler only. */
OptionEntryInt<std::uint8_t> resamplingQuality;
/** @brief Audio device. */
OptionEntryAudioDevice device;
};
struct GraphicsOptions : OptionCategoryBase {

2
Source/sound.cpp

@ -201,7 +201,7 @@ void snd_init()
// Initialize the SDL_audiolib library. Set the output sample rate to
// 22kHz, the audio format to 16-bit signed, use 2 output channels
// (stereo), and a 2KiB output buffer.
if (!Aulib::init(*sgOptions.Audio.sampleRate, AUDIO_S16, *sgOptions.Audio.channels, *sgOptions.Audio.bufferSize)) {
if (!Aulib::init(*sgOptions.Audio.sampleRate, AUDIO_S16, *sgOptions.Audio.channels, *sgOptions.Audio.bufferSize, *sgOptions.Audio.device)) {
LogError(LogCategory::Audio, "Failed to initialize audio (Aulib::init): {}", SDL_GetError());
return;
}

Loading…
Cancel
Save