mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 07:21:25 +12:00
cellAudio: use format instead of downmix
This commit is contained in:
parent
c42ff338e7
commit
72e1e242a3
15 changed files with 271 additions and 176 deletions
|
@ -100,59 +100,48 @@ void AudioBackend::normalize(u32 sample_cnt, const f32* src, f32* dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioChannelCnt AudioBackend::get_channel_count(audio_downmix downmix)
|
AudioChannelCnt AudioBackend::get_channel_count()
|
||||||
{
|
{
|
||||||
switch (downmix)
|
audio_out_configuration& audio_out = g_fxo->get<audio_out_configuration>();
|
||||||
{
|
std::lock_guard lock(audio_out.mtx);
|
||||||
case audio_downmix::no_downmix: return AudioChannelCnt::SURROUND_7_1;
|
ensure(!audio_out.out.empty());
|
||||||
case audio_downmix::downmix_to_5_1: return AudioChannelCnt::SURROUND_5_1;
|
audio_out_configuration::audio_out& out = audio_out.out.at(CELL_AUDIO_OUT_PRIMARY);
|
||||||
case audio_downmix::downmix_to_stereo: return AudioChannelCnt::STEREO;
|
|
||||||
case audio_downmix::use_application_settings:
|
|
||||||
{
|
|
||||||
audio_out_configuration& audio_out = g_fxo->get<audio_out_configuration>();
|
|
||||||
std::lock_guard lock(audio_out.mtx);
|
|
||||||
ensure(!audio_out.out.empty());
|
|
||||||
audio_out_configuration::audio_out& out = audio_out.out.at(CELL_AUDIO_OUT_PRIMARY);
|
|
||||||
|
|
||||||
switch (out.downmixer)
|
switch (out.downmixer)
|
||||||
|
{
|
||||||
|
case CELL_AUDIO_OUT_DOWNMIXER_NONE:
|
||||||
|
{
|
||||||
|
switch (out.channels)
|
||||||
{
|
{
|
||||||
case CELL_AUDIO_OUT_DOWNMIXER_NONE:
|
case 2: return AudioChannelCnt::STEREO;
|
||||||
{
|
case 6: return AudioChannelCnt::SURROUND_5_1;
|
||||||
switch (out.channels)
|
case 8: return AudioChannelCnt::SURROUND_7_1;
|
||||||
{
|
|
||||||
case 2: return AudioChannelCnt::STEREO;
|
|
||||||
case 6: return AudioChannelCnt::SURROUND_5_1;
|
|
||||||
case 8: return AudioChannelCnt::SURROUND_7_1;
|
|
||||||
default:
|
|
||||||
fmt::throw_exception("Unsupported channel count in cellAudioOut config: %d", out.channels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case CELL_AUDIO_OUT_DOWNMIXER_TYPE_A:
|
|
||||||
{
|
|
||||||
switch (out.channels)
|
|
||||||
{
|
|
||||||
case 2:
|
|
||||||
return AudioChannelCnt::STEREO;
|
|
||||||
default:
|
|
||||||
fmt::throw_exception("Unsupported channel count for CELL_AUDIO_OUT_DOWNMIXER_TYPE_A in cellAudioOut config: %d", out.channels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case CELL_AUDIO_OUT_DOWNMIXER_TYPE_B:
|
|
||||||
{
|
|
||||||
switch (out.channels)
|
|
||||||
{
|
|
||||||
case 6:
|
|
||||||
case 8:
|
|
||||||
return AudioChannelCnt::SURROUND_5_1;
|
|
||||||
default:
|
|
||||||
fmt::throw_exception("Unsupported channel count for CELL_AUDIO_OUT_DOWNMIXER_TYPE_B in cellAudioOut config: %d", out.channels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
fmt::throw_exception("Unknown downmixer in cellAudioOut config: %d", out.downmixer);
|
fmt::throw_exception("Unsupported channel count in cellAudioOut config: %d", out.channels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case CELL_AUDIO_OUT_DOWNMIXER_TYPE_A:
|
||||||
|
{
|
||||||
|
switch (out.channels)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
return AudioChannelCnt::STEREO;
|
||||||
|
default:
|
||||||
|
fmt::throw_exception("Unsupported channel count for CELL_AUDIO_OUT_DOWNMIXER_TYPE_A in cellAudioOut config: %d", out.channels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case CELL_AUDIO_OUT_DOWNMIXER_TYPE_B:
|
||||||
|
{
|
||||||
|
switch (out.channels)
|
||||||
|
{
|
||||||
|
case 6:
|
||||||
|
case 8:
|
||||||
|
return AudioChannelCnt::SURROUND_5_1;
|
||||||
|
default:
|
||||||
|
fmt::throw_exception("Unsupported channel count for CELL_AUDIO_OUT_DOWNMIXER_TYPE_B in cellAudioOut config: %d", out.channels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fmt::throw_exception("Unknown audio channel mode %s (%d)", downmix, static_cast<int>(downmix));
|
fmt::throw_exception("Unknown downmixer in cellAudioOut config: %d", out.downmixer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,6 @@ enum class AudioChannelCnt : u32
|
||||||
SURROUND_7_1 = 8,
|
SURROUND_7_1 = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class audio_downmix;
|
|
||||||
|
|
||||||
class AudioBackend
|
class AudioBackend
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -140,7 +138,7 @@ public:
|
||||||
/*
|
/*
|
||||||
* Returns the channel count based on the downmix mode.
|
* Returns the channel count based on the downmix mode.
|
||||||
*/
|
*/
|
||||||
static AudioChannelCnt get_channel_count(audio_downmix downmix);
|
static AudioChannelCnt get_channel_count();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Downmix audio stream.
|
* Downmix audio stream.
|
||||||
|
|
|
@ -66,7 +66,7 @@ void cell_audio_config::reset(bool backend_changed)
|
||||||
|
|
||||||
const AudioFreq freq = AudioFreq::FREQ_48K;
|
const AudioFreq freq = AudioFreq::FREQ_48K;
|
||||||
const AudioSampleSize sample_size = raw.convert_to_s16 ? AudioSampleSize::S16 : AudioSampleSize::FLOAT;
|
const AudioSampleSize sample_size = raw.convert_to_s16 ? AudioSampleSize::S16 : AudioSampleSize::FLOAT;
|
||||||
const AudioChannelCnt ch_cnt = AudioBackend::get_channel_count(raw.downmix);
|
const AudioChannelCnt ch_cnt = AudioBackend::get_channel_count();
|
||||||
const f64 cb_frame_len = backend->Open(freq, sample_size, ch_cnt) ? backend->GetCallbackFrameLen() : 0.0;
|
const f64 cb_frame_len = backend->Open(freq, sample_size, ch_cnt) ? backend->GetCallbackFrameLen() : 0.0;
|
||||||
|
|
||||||
audio_channels = static_cast<u32>(ch_cnt);
|
audio_channels = static_cast<u32>(ch_cnt);
|
||||||
|
@ -526,7 +526,7 @@ namespace audio
|
||||||
.time_stretching_threshold = g_cfg.audio.time_stretching_threshold,
|
.time_stretching_threshold = g_cfg.audio.time_stretching_threshold,
|
||||||
.convert_to_s16 = static_cast<bool>(g_cfg.audio.convert_to_s16),
|
.convert_to_s16 = static_cast<bool>(g_cfg.audio.convert_to_s16),
|
||||||
.dump_to_file = static_cast<bool>(g_cfg.audio.dump_to_file),
|
.dump_to_file = static_cast<bool>(g_cfg.audio.dump_to_file),
|
||||||
.downmix = g_cfg.audio.audio_channel_downmix,
|
.format = g_cfg.audio.format,
|
||||||
.renderer = g_cfg.audio.renderer,
|
.renderer = g_cfg.audio.renderer,
|
||||||
.provider = g_cfg.audio.provider
|
.provider = g_cfg.audio.provider
|
||||||
};
|
};
|
||||||
|
@ -550,7 +550,7 @@ namespace audio
|
||||||
raw.time_stretching_threshold != new_raw.time_stretching_threshold ||
|
raw.time_stretching_threshold != new_raw.time_stretching_threshold ||
|
||||||
raw.enable_time_stretching != new_raw.enable_time_stretching ||
|
raw.enable_time_stretching != new_raw.enable_time_stretching ||
|
||||||
raw.convert_to_s16 != new_raw.convert_to_s16 ||
|
raw.convert_to_s16 != new_raw.convert_to_s16 ||
|
||||||
raw.downmix != new_raw.downmix ||
|
raw.format != new_raw.format ||
|
||||||
raw.renderer != new_raw.renderer ||
|
raw.renderer != new_raw.renderer ||
|
||||||
raw.dump_to_file != new_raw.dump_to_file)
|
raw.dump_to_file != new_raw.dump_to_file)
|
||||||
{
|
{
|
||||||
|
@ -848,13 +848,13 @@ void cell_audio_thread::operator()()
|
||||||
switch (cfg.audio_channels)
|
switch (cfg.audio_channels)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
mix<audio_downmix::downmix_to_stereo>(buf);
|
mix<AudioChannelCnt::STEREO>(buf);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
mix<audio_downmix::downmix_to_5_1>(buf);
|
mix<AudioChannelCnt::SURROUND_5_1>(buf);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
mix<audio_downmix::no_downmix>(buf);
|
mix<AudioChannelCnt::SURROUND_7_1>(buf);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fmt::throw_exception("Unsupported number of audio channels: %u", cfg.audio_channels);
|
fmt::throw_exception("Unsupported number of audio channels: %u", cfg.audio_channels);
|
||||||
|
@ -884,12 +884,12 @@ audio_port* cell_audio_thread::open_port()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <audio_downmix downmix>
|
template <AudioChannelCnt downmix>
|
||||||
void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
||||||
{
|
{
|
||||||
AUDIT(out_buffer != nullptr);
|
AUDIT(out_buffer != nullptr);
|
||||||
|
|
||||||
constexpr u32 channels = downmix == audio_downmix::no_downmix ? 8 : downmix == audio_downmix::downmix_to_5_1 ? 6 : 2;
|
constexpr u32 channels = static_cast<u32>(downmix);
|
||||||
constexpr u32 out_buffer_sz = channels * AUDIO_BUFFER_SAMPLES;
|
constexpr u32 out_buffer_sz = channels * AUDIO_BUFFER_SAMPLES;
|
||||||
|
|
||||||
bool first_mix = true;
|
bool first_mix = true;
|
||||||
|
@ -941,14 +941,14 @@ void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
||||||
out_buffer[out + 0] = left;
|
out_buffer[out + 0] = left;
|
||||||
out_buffer[out + 1] = right;
|
out_buffer[out + 1] = right;
|
||||||
|
|
||||||
if constexpr (downmix != audio_downmix::downmix_to_stereo)
|
if constexpr (downmix != AudioChannelCnt::STEREO)
|
||||||
{
|
{
|
||||||
out_buffer[out + 2] = 0.0f;
|
out_buffer[out + 2] = 0.0f;
|
||||||
out_buffer[out + 3] = 0.0f;
|
out_buffer[out + 3] = 0.0f;
|
||||||
out_buffer[out + 4] = 0.0f;
|
out_buffer[out + 4] = 0.0f;
|
||||||
out_buffer[out + 5] = 0.0f;
|
out_buffer[out + 5] = 0.0f;
|
||||||
|
|
||||||
if constexpr (downmix != audio_downmix::downmix_to_5_1)
|
if constexpr (downmix != AudioChannelCnt::SURROUND_5_1)
|
||||||
{
|
{
|
||||||
out_buffer[out + 6] = 0.0f;
|
out_buffer[out + 6] = 0.0f;
|
||||||
out_buffer[out + 7] = 0.0f;
|
out_buffer[out + 7] = 0.0f;
|
||||||
|
@ -989,14 +989,14 @@ void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
||||||
const float rear_left = buf[in + 6] * m;
|
const float rear_left = buf[in + 6] * m;
|
||||||
const float rear_right = buf[in + 7] * m;
|
const float rear_right = buf[in + 7] * m;
|
||||||
|
|
||||||
if constexpr (downmix == audio_downmix::downmix_to_stereo)
|
if constexpr (downmix == AudioChannelCnt::STEREO)
|
||||||
{
|
{
|
||||||
// Don't mix in the lfe as per dolby specification and based on documentation
|
// Don't mix in the lfe as per dolby specification and based on documentation
|
||||||
const float mid = center * 0.5f;
|
const float mid = center * 0.5f;
|
||||||
out_buffer[out + 0] = left * minus_3db + mid + side_left * 0.5f + rear_left * 0.5f;
|
out_buffer[out + 0] = left * minus_3db + mid + side_left * 0.5f + rear_left * 0.5f;
|
||||||
out_buffer[out + 1] = right * minus_3db + mid + side_right * 0.5f + rear_right * 0.5f;
|
out_buffer[out + 1] = right * minus_3db + mid + side_right * 0.5f + rear_right * 0.5f;
|
||||||
}
|
}
|
||||||
else if constexpr (downmix == audio_downmix::downmix_to_5_1)
|
else if constexpr (downmix == AudioChannelCnt::SURROUND_5_1)
|
||||||
{
|
{
|
||||||
out_buffer[out + 0] = left;
|
out_buffer[out + 0] = left;
|
||||||
out_buffer[out + 1] = right;
|
out_buffer[out + 1] = right;
|
||||||
|
@ -1034,14 +1034,14 @@ void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
||||||
const float rear_left = buf[in + 6] * m;
|
const float rear_left = buf[in + 6] * m;
|
||||||
const float rear_right = buf[in + 7] * m;
|
const float rear_right = buf[in + 7] * m;
|
||||||
|
|
||||||
if constexpr (downmix == audio_downmix::downmix_to_stereo)
|
if constexpr (downmix == AudioChannelCnt::STEREO)
|
||||||
{
|
{
|
||||||
// Don't mix in the lfe as per dolby specification and based on documentation
|
// Don't mix in the lfe as per dolby specification and based on documentation
|
||||||
const float mid = center * 0.5f;
|
const float mid = center * 0.5f;
|
||||||
out_buffer[out + 0] += left * minus_3db + mid + side_left * 0.5f + rear_left * 0.5f;
|
out_buffer[out + 0] += left * minus_3db + mid + side_left * 0.5f + rear_left * 0.5f;
|
||||||
out_buffer[out + 1] += right * minus_3db + mid + side_right * 0.5f + rear_right * 0.5f;
|
out_buffer[out + 1] += right * minus_3db + mid + side_right * 0.5f + rear_right * 0.5f;
|
||||||
}
|
}
|
||||||
else if constexpr (downmix == audio_downmix::downmix_to_5_1)
|
else if constexpr (downmix == AudioChannelCnt::SURROUND_5_1)
|
||||||
{
|
{
|
||||||
out_buffer[out + 0] += left;
|
out_buffer[out + 0] += left;
|
||||||
out_buffer[out + 1] += right;
|
out_buffer[out + 1] += right;
|
||||||
|
|
|
@ -201,7 +201,7 @@ struct cell_audio_config
|
||||||
s64 time_stretching_threshold = 0;
|
s64 time_stretching_threshold = 0;
|
||||||
bool convert_to_s16 = false;
|
bool convert_to_s16 = false;
|
||||||
bool dump_to_file = false;
|
bool dump_to_file = false;
|
||||||
audio_downmix downmix = audio_downmix::downmix_to_stereo;
|
audio_format format = audio_format::lpcm_2_48khz;
|
||||||
audio_renderer renderer = audio_renderer::null;
|
audio_renderer renderer = audio_renderer::null;
|
||||||
audio_provider provider = audio_provider::none;
|
audio_provider provider = audio_provider::none;
|
||||||
};
|
};
|
||||||
|
@ -348,7 +348,7 @@ private:
|
||||||
void reset_ports(s32 offset = 0);
|
void reset_ports(s32 offset = 0);
|
||||||
void advance(u64 timestamp);
|
void advance(u64 timestamp);
|
||||||
std::tuple<u32, u32, u32, u32> count_port_buffer_tags();
|
std::tuple<u32, u32, u32, u32> count_port_buffer_tags();
|
||||||
template <audio_downmix downmix>
|
template <AudioChannelCnt downmix>
|
||||||
void mix(float *out_buffer, s32 offset = 0);
|
void mix(float *out_buffer, s32 offset = 0);
|
||||||
void finish_port_volume_stepping();
|
void finish_port_volume_stepping();
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "Emu/Cell/lv2/sys_rsxaudio.h"
|
#include "Emu/Cell/lv2/sys_rsxaudio.h"
|
||||||
#include "Emu/IdManager.h"
|
#include "Emu/IdManager.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
|
#include "Loader/PSF.h"
|
||||||
|
|
||||||
#include "cellAudioOut.h"
|
#include "cellAudioOut.h"
|
||||||
#include "cellAudio.h"
|
#include "cellAudio.h"
|
||||||
|
@ -34,45 +35,137 @@ audio_out_configuration::audio_out_configuration()
|
||||||
{
|
{
|
||||||
CellAudioOutSoundMode mode{};
|
CellAudioOutSoundMode mode{};
|
||||||
|
|
||||||
mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM;
|
// TODO: audio_format should be a bitmap, but we'll keep it simple for now (Linear PCM 2 Ch. 48 kHz should always exist)
|
||||||
mode.channel = CELL_AUDIO_OUT_CHNUM_8;
|
// TODO: more formats:
|
||||||
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
// - Each LPCM with other sample frequencies (we currently only support 48 kHz)
|
||||||
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_8CH_LREClrxy;
|
// - AAC
|
||||||
|
// - Dolby Digital Plus
|
||||||
|
// - Dolby TrueHD
|
||||||
|
// - DTS-HD High Resolution Audio
|
||||||
|
// - DTS-HD Master Audio
|
||||||
|
// - ...
|
||||||
|
switch (g_cfg.audio.format)
|
||||||
|
{
|
||||||
|
case audio_format::automatic: // Automatic based on supported formats
|
||||||
|
{
|
||||||
|
s32 sound_format = (1 << 0);
|
||||||
|
|
||||||
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
const psf::registry psf = psf::load_object(fs::file(Emu.GetSfoDir() + "/PARAM.SFO"));
|
||||||
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
if (psf.contains("SOUND_FORMAT")) sound_format = psf.at("SOUND_FORMAT").as_integer();
|
||||||
|
|
||||||
mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM;
|
if (sound_format & (1 << 0)) // Linear PCM 2 Ch.
|
||||||
mode.channel = CELL_AUDIO_OUT_CHNUM_6;
|
{
|
||||||
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM;
|
||||||
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr;
|
mode.channel = CELL_AUDIO_OUT_CHNUM_2;
|
||||||
|
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
||||||
|
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_2CH;
|
||||||
|
|
||||||
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||||
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||||
|
}
|
||||||
|
|
||||||
mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM;
|
if (sound_format & (1 << 2)) // Linear PCM 5.1 Ch.
|
||||||
mode.channel = CELL_AUDIO_OUT_CHNUM_2;
|
{
|
||||||
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM;
|
||||||
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_2CH;
|
mode.channel = CELL_AUDIO_OUT_CHNUM_6;
|
||||||
|
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
||||||
|
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr;
|
||||||
|
|
||||||
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||||
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||||
|
}
|
||||||
|
|
||||||
mode.type = CELL_AUDIO_OUT_CODING_TYPE_DTS;
|
if (sound_format & (1 << 4)) // Linear PCM 7.1 Ch.
|
||||||
mode.channel = CELL_AUDIO_OUT_CHNUM_6;
|
{
|
||||||
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM;
|
||||||
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr;
|
mode.channel = CELL_AUDIO_OUT_CHNUM_8;
|
||||||
|
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
||||||
|
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_8CH_LREClrxy;
|
||||||
|
|
||||||
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||||
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||||
|
}
|
||||||
|
|
||||||
mode.type = CELL_AUDIO_OUT_CODING_TYPE_AC3;
|
if (sound_format & (1 << 8)) // DTS 5.1 Ch.
|
||||||
mode.channel = CELL_AUDIO_OUT_CHNUM_6;
|
{
|
||||||
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
mode.type = CELL_AUDIO_OUT_CODING_TYPE_DTS;
|
||||||
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr;
|
mode.channel = CELL_AUDIO_OUT_CHNUM_6;
|
||||||
|
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
||||||
|
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr;
|
||||||
|
|
||||||
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||||
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sound_format & (1 << 9)) // Dolby Digital 5.1 Ch.
|
||||||
|
{
|
||||||
|
mode.type = CELL_AUDIO_OUT_CODING_TYPE_AC3;
|
||||||
|
mode.channel = CELL_AUDIO_OUT_CHNUM_6;
|
||||||
|
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
||||||
|
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr;
|
||||||
|
|
||||||
|
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||||
|
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case audio_format::lpcm_2_48khz: // Linear PCM 2 Ch. 48 kHz
|
||||||
|
{
|
||||||
|
mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM;
|
||||||
|
mode.channel = CELL_AUDIO_OUT_CHNUM_2;
|
||||||
|
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
||||||
|
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_2CH;
|
||||||
|
|
||||||
|
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||||
|
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case audio_format::lpcm_5_1_48khz: // Linear PCM 5.1 Ch. 48 kHz
|
||||||
|
{
|
||||||
|
mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM;
|
||||||
|
mode.channel = CELL_AUDIO_OUT_CHNUM_6;
|
||||||
|
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
||||||
|
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr;
|
||||||
|
|
||||||
|
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||||
|
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case audio_format::lpcm_7_1_48khz: // Linear PCM 7.1 Ch. 48 kHz
|
||||||
|
{
|
||||||
|
mode.type = CELL_AUDIO_OUT_CODING_TYPE_LPCM;
|
||||||
|
mode.channel = CELL_AUDIO_OUT_CHNUM_8;
|
||||||
|
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
||||||
|
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_8CH_LREClrxy;
|
||||||
|
|
||||||
|
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||||
|
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case audio_format::dts: // DTS 5.1 Ch.
|
||||||
|
{
|
||||||
|
mode.type = CELL_AUDIO_OUT_CODING_TYPE_DTS;
|
||||||
|
mode.channel = CELL_AUDIO_OUT_CHNUM_6;
|
||||||
|
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
||||||
|
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr;
|
||||||
|
|
||||||
|
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||||
|
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case audio_format::ac3: // Dolby Digital 5.1 Ch.
|
||||||
|
{
|
||||||
|
mode.type = CELL_AUDIO_OUT_CODING_TYPE_AC3;
|
||||||
|
mode.channel = CELL_AUDIO_OUT_CHNUM_6;
|
||||||
|
mode.fs = CELL_AUDIO_OUT_FS_48KHZ;
|
||||||
|
mode.layout = CELL_AUDIO_OUT_SPEAKER_LAYOUT_6CH_LREClr;
|
||||||
|
|
||||||
|
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||||
|
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code cellAudioOutGetNumberOfDevice(u32 audioOut);
|
error_code cellAudioOutGetNumberOfDevice(u32 audioOut);
|
||||||
|
@ -87,22 +180,6 @@ error_code cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32
|
||||||
default: return not_an_error(0);
|
default: return not_an_error(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case CELL_AUDIO_OUT_CODING_TYPE_LPCM:
|
|
||||||
{
|
|
||||||
switch (g_cfg.audio.audio_channel_downmix)
|
|
||||||
{
|
|
||||||
case audio_downmix::no_downmix: return not_an_error(8);
|
|
||||||
case audio_downmix::downmix_to_5_1: return not_an_error(6);
|
|
||||||
case audio_downmix::downmix_to_stereo: return not_an_error(2);
|
|
||||||
case audio_downmix::use_application_settings: break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 available = 0;
|
s32 available = 0;
|
||||||
|
|
||||||
// Check if the requested audio parameters are available and find the max supported channel count
|
// Check if the requested audio parameters are available and find the max supported channel count
|
||||||
|
@ -131,22 +208,6 @@ error_code cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32
|
||||||
default: return not_an_error(0);
|
default: return not_an_error(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case CELL_AUDIO_OUT_CODING_TYPE_LPCM:
|
|
||||||
{
|
|
||||||
switch (g_cfg.audio.audio_channel_downmix)
|
|
||||||
{
|
|
||||||
case audio_downmix::no_downmix: return not_an_error(8);
|
|
||||||
case audio_downmix::downmix_to_5_1: return not_an_error(6);
|
|
||||||
case audio_downmix::downmix_to_stereo: return not_an_error(2);
|
|
||||||
case audio_downmix::use_application_settings: break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the requested audio parameters are available
|
// Check if the requested audio parameters are available
|
||||||
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
|
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
|
||||||
std::lock_guard lock(cfg.mtx);
|
std::lock_guard lock(cfg.mtx);
|
||||||
|
@ -203,7 +264,7 @@ error_code cellAudioOutGetState(u32 audioOut, u32 deviceIndex, vm::ptr<CellAudio
|
||||||
case CELL_AUDIO_OUT_PRIMARY:
|
case CELL_AUDIO_OUT_PRIMARY:
|
||||||
case CELL_AUDIO_OUT_SECONDARY:
|
case CELL_AUDIO_OUT_SECONDARY:
|
||||||
{
|
{
|
||||||
const AudioChannelCnt channels = AudioBackend::get_channel_count(g_cfg.audio.audio_channel_downmix);
|
const AudioChannelCnt channels = AudioBackend::get_channel_count();
|
||||||
|
|
||||||
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
|
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
|
||||||
std::lock_guard lock(cfg.mtx);
|
std::lock_guard lock(cfg.mtx);
|
||||||
|
@ -211,21 +272,7 @@ error_code cellAudioOutGetState(u32 audioOut, u32 deviceIndex, vm::ptr<CellAudio
|
||||||
|
|
||||||
const auto it = std::find_if(out.sound_modes.cbegin(), out.sound_modes.cend(), [&channels, &out](const CellAudioOutSoundMode& mode)
|
const auto it = std::find_if(out.sound_modes.cbegin(), out.sound_modes.cend(), [&channels, &out](const CellAudioOutSoundMode& mode)
|
||||||
{
|
{
|
||||||
if (mode.type == out.encoder)
|
return mode.type == out.encoder && mode.channel == static_cast<u8>(channels);
|
||||||
{
|
|
||||||
switch (mode.type)
|
|
||||||
{
|
|
||||||
case CELL_AUDIO_OUT_CODING_TYPE_LPCM:
|
|
||||||
return mode.channel == static_cast<u8>(channels);
|
|
||||||
case CELL_AUDIO_OUT_CODING_TYPE_AC3:
|
|
||||||
case CELL_AUDIO_OUT_CODING_TYPE_DTS:
|
|
||||||
return true; // We currently only have one possible sound mode for these types
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ensure(it != out.sound_modes.cend());
|
ensure(it != out.sound_modes.cend());
|
||||||
|
@ -289,8 +336,7 @@ error_code cellAudioOutConfigure(u32 audioOut, vm::ptr<CellAudioOutConfiguration
|
||||||
out_new = out;
|
out_new = out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_cfg.audio.audio_channel_downmix == audio_downmix::use_application_settings &&
|
if (std::memcmp(&out_old, &out_new, sizeof(audio_out_configuration::audio_out)) != 0)
|
||||||
std::memcmp(&out_old, &out_new, sizeof(audio_out_configuration::audio_out)) != 0)
|
|
||||||
{
|
{
|
||||||
const auto reset_audio = [audioOut]() -> void
|
const auto reset_audio = [audioOut]() -> void
|
||||||
{
|
{
|
||||||
|
|
|
@ -254,7 +254,7 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: Is cellHddGameCheck really responsible for writing the information in get->getParam ? (If not, delete this else)
|
// TODO: Is cellHddGameCheck really responsible for writing the information in get->getParam ? (If not, delete this else)
|
||||||
const auto& psf = psf::load_object(fs::file(local_dir +"/PARAM.SFO"));
|
const psf::registry psf = psf::load_object(fs::file(local_dir +"/PARAM.SFO"));
|
||||||
|
|
||||||
// Some following fields may be zero in old FW 1.00 version PARAM.SFO
|
// Some following fields may be zero in old FW 1.00 version PARAM.SFO
|
||||||
if (psf.contains("PARENTAL_LEVEL")) get->getParam.parentalLevel = psf.at("PARENTAL_LEVEL").as_integer();
|
if (psf.contains("PARENTAL_LEVEL")) get->getParam.parentalLevel = psf.at("PARENTAL_LEVEL").as_integer();
|
||||||
|
|
|
@ -1322,7 +1322,7 @@ void rsxaudio_backend_thread::update_emu_cfg()
|
||||||
|
|
||||||
rsxaudio_backend_thread::emu_audio_cfg rsxaudio_backend_thread::get_emu_cfg()
|
rsxaudio_backend_thread::emu_audio_cfg rsxaudio_backend_thread::get_emu_cfg()
|
||||||
{
|
{
|
||||||
const AudioChannelCnt out_ch_cnt = AudioBackend::get_channel_count(g_cfg.audio.audio_channel_downmix);
|
const AudioChannelCnt out_ch_cnt = AudioBackend::get_channel_count();
|
||||||
|
|
||||||
emu_audio_cfg cfg =
|
emu_audio_cfg cfg =
|
||||||
{
|
{
|
||||||
|
|
|
@ -235,7 +235,7 @@ struct cfg_root : cfg::node
|
||||||
cfg::_enum<audio_avport> rsxaudio_port{ this, "RSXAudio Avport", audio_avport::hdmi_0, true };
|
cfg::_enum<audio_avport> rsxaudio_port{ this, "RSXAudio Avport", audio_avport::hdmi_0, true };
|
||||||
cfg::_bool dump_to_file{ this, "Dump to file", false, true };
|
cfg::_bool dump_to_file{ this, "Dump to file", false, true };
|
||||||
cfg::_bool convert_to_s16{ this, "Convert to 16 bit", false, true };
|
cfg::_bool convert_to_s16{ this, "Convert to 16 bit", false, true };
|
||||||
cfg::_enum<audio_downmix> audio_channel_downmix{ this, "Audio Channels", audio_downmix::downmix_to_stereo, true };
|
cfg::_enum<audio_format> format{ this, "Audio Format", audio_format::automatic, false };
|
||||||
cfg::_int<0, 200> volume{ this, "Master Volume", 100, true };
|
cfg::_int<0, 200> volume{ this, "Master Volume", 100, true };
|
||||||
cfg::_bool enable_buffering{ this, "Enable Buffering", true, true };
|
cfg::_bool enable_buffering{ this, "Enable Buffering", true, true };
|
||||||
cfg::_int <4, 250> desired_buffer_duration{ this, "Desired Audio Buffer Duration", 100, true };
|
cfg::_int <4, 250> desired_buffer_duration{ this, "Desired Audio Buffer Duration", 100, true };
|
||||||
|
|
|
@ -532,16 +532,18 @@ void fmt_class_string<audio_avport>::format(std::string& out, u64 arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void fmt_class_string<audio_downmix>::format(std::string& out, u64 arg)
|
void fmt_class_string<audio_format>::format(std::string& out, u64 arg)
|
||||||
{
|
{
|
||||||
format_enum(out, arg, [](audio_downmix value)
|
format_enum(out, arg, [](audio_format value)
|
||||||
{
|
{
|
||||||
switch (value)
|
switch (value)
|
||||||
{
|
{
|
||||||
case audio_downmix::no_downmix: return "No downmix";
|
case audio_format::automatic: return "Automatic";
|
||||||
case audio_downmix::downmix_to_stereo: return "Downmix to Stereo";
|
case audio_format::lpcm_2_48khz: return "Linear PCM 2 Ch. 48 kHz";
|
||||||
case audio_downmix::downmix_to_5_1: return "Downmix to 5.1";
|
case audio_format::lpcm_5_1_48khz: return "Linear PCM 5.1 Ch. 48 kHz";
|
||||||
case audio_downmix::use_application_settings: return "Use application settings";
|
case audio_format::lpcm_7_1_48khz: return "Linear PCM 7.1 Ch. 48 kHz";
|
||||||
|
case audio_format::dts: return "DTS 5.1 Ch.";
|
||||||
|
case audio_format::ac3: return "Dolby Digital 5.1 Ch.";
|
||||||
}
|
}
|
||||||
|
|
||||||
return unknown;
|
return unknown;
|
||||||
|
|
|
@ -76,12 +76,14 @@ enum class audio_avport
|
||||||
spdif_1
|
spdif_1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class audio_downmix
|
enum class audio_format
|
||||||
{
|
{
|
||||||
no_downmix, // Surround 7.1
|
automatic,
|
||||||
downmix_to_stereo,
|
lpcm_2_48khz,
|
||||||
downmix_to_5_1,
|
lpcm_5_1_48khz,
|
||||||
use_application_settings
|
lpcm_7_1_48khz,
|
||||||
|
dts,
|
||||||
|
ac3,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class music_handler
|
enum class music_handler
|
||||||
|
|
|
@ -1140,13 +1140,15 @@ QString emu_settings::GetLocalizedSetting(const QString& original, emu_settings_
|
||||||
case enter_button_assign::cross: return tr("Enter with cross", "Enter button assignment");
|
case enter_button_assign::cross: return tr("Enter with cross", "Enter button assignment");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case emu_settings_type::AudioChannels:
|
case emu_settings_type::AudioFormat:
|
||||||
switch (static_cast<audio_downmix>(index))
|
switch (static_cast<audio_format>(index))
|
||||||
{
|
{
|
||||||
case audio_downmix::no_downmix: return tr("Surround 7.1", "Audio downmix");
|
case audio_format::automatic: return tr("Automatic", "Audio format");
|
||||||
case audio_downmix::downmix_to_stereo: return tr("Downmix to Stereo", "Audio downmix");
|
case audio_format::lpcm_2_48khz: return tr("Linear PCM 2 Ch. 48 kHz", "Audio format");
|
||||||
case audio_downmix::downmix_to_5_1: return tr("Downmix to 5.1", "Audio downmix");
|
case audio_format::lpcm_5_1_48khz: return tr("Linear PCM 5.1 Ch. 48 kHz", "Audio format");
|
||||||
case audio_downmix::use_application_settings: return tr("Use application settings", "Audio downmix");
|
case audio_format::lpcm_7_1_48khz: return tr("Linear PCM 7.1 Ch. 48 kHz", "Audio format");
|
||||||
|
case audio_format::dts: return tr("DTS 5.1 Ch.", "Audio format");
|
||||||
|
case audio_format::ac3: return tr("Dolby Digital 5.1 Ch.", "Audio format");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case emu_settings_type::LicenseArea:
|
case emu_settings_type::LicenseArea:
|
||||||
|
|
|
@ -121,7 +121,7 @@ enum class emu_settings_type
|
||||||
AudioRenderer,
|
AudioRenderer,
|
||||||
DumpToFile,
|
DumpToFile,
|
||||||
ConvertTo16Bit,
|
ConvertTo16Bit,
|
||||||
AudioChannels,
|
AudioFormat,
|
||||||
AudioProvider,
|
AudioProvider,
|
||||||
AudioAvport,
|
AudioAvport,
|
||||||
MasterVolume,
|
MasterVolume,
|
||||||
|
@ -291,7 +291,7 @@ inline static const QMap<emu_settings_type, cfg_location> settings_location =
|
||||||
{ emu_settings_type::AudioRenderer, { "Audio", "Renderer"}},
|
{ emu_settings_type::AudioRenderer, { "Audio", "Renderer"}},
|
||||||
{ emu_settings_type::DumpToFile, { "Audio", "Dump to file"}},
|
{ emu_settings_type::DumpToFile, { "Audio", "Dump to file"}},
|
||||||
{ emu_settings_type::ConvertTo16Bit, { "Audio", "Convert to 16 bit"}},
|
{ emu_settings_type::ConvertTo16Bit, { "Audio", "Convert to 16 bit"}},
|
||||||
{ emu_settings_type::AudioChannels, { "Audio", "Audio Channels"}},
|
{ emu_settings_type::AudioFormat, { "Audio", "Audio Format"}},
|
||||||
{ emu_settings_type::AudioProvider, { "Audio", "Audio Provider"}},
|
{ emu_settings_type::AudioProvider, { "Audio", "Audio Provider"}},
|
||||||
{ emu_settings_type::AudioAvport, { "Audio", "RSXAudio Avport"}},
|
{ emu_settings_type::AudioAvport, { "Audio", "RSXAudio Avport"}},
|
||||||
{ emu_settings_type::MasterVolume, { "Audio", "Master Volume"}},
|
{ emu_settings_type::MasterVolume, { "Audio", "Master Volume"}},
|
||||||
|
|
|
@ -444,7 +444,6 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||||
m_emu_settings->EnhanceComboBox(ui->resBox, emu_settings_type::Resolution);
|
m_emu_settings->EnhanceComboBox(ui->resBox, emu_settings_type::Resolution);
|
||||||
SubscribeTooltip(ui->gb_default_resolution, tooltips.settings.resolution);
|
SubscribeTooltip(ui->gb_default_resolution, tooltips.settings.resolution);
|
||||||
// remove unsupported resolutions from the dropdown
|
// remove unsupported resolutions from the dropdown
|
||||||
const int saved_index = ui->resBox->currentIndex();
|
|
||||||
bool saved_index_removed = false;
|
bool saved_index_removed = false;
|
||||||
if (game && game->resolution > 0)
|
if (game && game->resolution > 0)
|
||||||
{
|
{
|
||||||
|
@ -458,6 +457,8 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||||
// { 1 << 5, fmt::format("%s", video_resolution::_576p_16:9) },
|
// { 1 << 5, fmt::format("%s", video_resolution::_576p_16:9) },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const int saved_index = ui->resBox->currentIndex();
|
||||||
|
|
||||||
for (int i = ui->resBox->count() - 1; i >= 0; i--)
|
for (int i = ui->resBox->count() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
bool has_resolution = false;
|
bool has_resolution = false;
|
||||||
|
@ -955,8 +956,63 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||||
#endif
|
#endif
|
||||||
connect(ui->audioOutBox, QOverload<int>::of(&QComboBox::currentIndexChanged), enable_buffering);
|
connect(ui->audioOutBox, QOverload<int>::of(&QComboBox::currentIndexChanged), enable_buffering);
|
||||||
|
|
||||||
m_emu_settings->EnhanceComboBox(ui->combo_audio_downmix, emu_settings_type::AudioChannels);
|
m_emu_settings->EnhanceComboBox(ui->combo_audio_format, emu_settings_type::AudioFormat);
|
||||||
SubscribeTooltip(ui->gb_audio_downmix, tooltips.settings.downmix);
|
SubscribeTooltip(ui->gb_audio_format, tooltips.settings.audio_format);
|
||||||
|
bool saved_audio_format_index_removed = false;
|
||||||
|
if (game && game->sound_format > 0)
|
||||||
|
{
|
||||||
|
const std::map<u32, std::vector<audio_format>> formats
|
||||||
|
{
|
||||||
|
{ 1 << 0, { audio_format::lpcm_2_48khz } },
|
||||||
|
{ 1 << 2, { audio_format::lpcm_5_1_48khz } },
|
||||||
|
{ 1 << 4, { audio_format::lpcm_7_1_48khz } },
|
||||||
|
{ 1 << 8, { audio_format::ac3 } },
|
||||||
|
{ 1 << 9, { audio_format::dts } },
|
||||||
|
};
|
||||||
|
|
||||||
|
const int saved_index = ui->combo_audio_format->currentIndex();
|
||||||
|
|
||||||
|
for (int i = ui->combo_audio_format->count() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
const QVariantList var_list = ui->combo_audio_format->itemData(i).toList();
|
||||||
|
ensure(var_list.size() == 2 && var_list[1].canConvert<int>());
|
||||||
|
|
||||||
|
const audio_format format = static_cast<audio_format>(var_list[1].toInt());
|
||||||
|
|
||||||
|
bool has_format = false;
|
||||||
|
for (const auto& entry : formats)
|
||||||
|
{
|
||||||
|
if ((game->sound_format & entry.first) && std::find(entry.second.cbegin(), entry.second.cend(), format) != entry.second.cend())
|
||||||
|
{
|
||||||
|
has_format = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!has_format)
|
||||||
|
{
|
||||||
|
ui->combo_audio_format->removeItem(i);
|
||||||
|
if (i == saved_index)
|
||||||
|
{
|
||||||
|
saved_audio_format_index_removed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Set the current selection to the default if the original setting wasn't valid
|
||||||
|
if (saved_audio_format_index_removed)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ui->combo_audio_format->count(); i++)
|
||||||
|
{
|
||||||
|
const QVariantList var_list = ui->combo_audio_format->itemData(i).toList();
|
||||||
|
ensure(var_list.size() == 2 && var_list[1].canConvert<int>());
|
||||||
|
|
||||||
|
if (var_list[1].toInt() == static_cast<int>(g_cfg.audio.format.def))
|
||||||
|
{
|
||||||
|
ui->combo_audio_format->setCurrentIndex(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_emu_settings->EnhanceComboBox(ui->audioProviderBox, emu_settings_type::AudioProvider);
|
m_emu_settings->EnhanceComboBox(ui->audioProviderBox, emu_settings_type::AudioProvider);
|
||||||
SubscribeTooltip(ui->gb_audio_provider, tooltips.settings.audio_provider);
|
SubscribeTooltip(ui->gb_audio_provider, tooltips.settings.audio_provider);
|
||||||
|
|
|
@ -1031,13 +1031,13 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="gb_audio_downmix">
|
<widget class="QGroupBox" name="gb_audio_format">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Audio Channels</string>
|
<string>Audio Format</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="gb_audio_channels_layout">
|
<layout class="QVBoxLayout" name="gb_audio_format_layout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="combo_audio_downmix"/>
|
<widget class="QComboBox" name="combo_audio_format"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
const QString audio_avport = tr("Controls which avport is used to sample audio data from.");
|
const QString audio_avport = tr("Controls which avport is used to sample audio data from.");
|
||||||
const QString audio_dump = tr("Saves all audio as a raw wave file. If unsure, leave this unchecked.");
|
const QString audio_dump = tr("Saves all audio as a raw wave file. If unsure, leave this unchecked.");
|
||||||
const QString convert = tr("Uses 16-bit audio samples instead of default 32-bit floating point.\nUse with buggy audio drivers if you have no sound or completely broken sound.");
|
const QString convert = tr("Uses 16-bit audio samples instead of default 32-bit floating point.\nUse with buggy audio drivers if you have no sound or completely broken sound.");
|
||||||
const QString downmix = tr("Uses chosen audio output instead of default 7.1 surround sound.\nUse downmix to stereo with stereo audio devices.\nUse 5.1 or higher only if you are using a surround sound audio system.\nIf you want to let the game decide choose the application settings.");
|
const QString audio_format = tr("Determines the sound format.\nConfigure this setting if you want to switch between stereo and surround sound.\nChanging this value requires a restart of the game.\nUse automatic if you are unsure.");
|
||||||
const QString master_volume = tr("Controls the overall volume of the emulation.\nValues above 100% might reduce the audio quality.");
|
const QString master_volume = tr("Controls the overall volume of the emulation.\nValues above 100% might reduce the audio quality.");
|
||||||
const QString enable_buffering = tr("Enables audio buffering, which reduces crackle/stutter but increases audio latency.");
|
const QString enable_buffering = tr("Enables audio buffering, which reduces crackle/stutter but increases audio latency.");
|
||||||
const QString audio_buffer_duration = tr("Target buffer duration in milliseconds.\nHigher values make the buffering algorithm's job easier, but may introduce noticeable audio latency.");
|
const QString audio_buffer_duration = tr("Target buffer duration in milliseconds.\nHigher values make the buffering algorithm's job easier, but may introduce noticeable audio latency.");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue