mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 03:32:55 +00:00
cellAudio: use format instead of downmix
This commit is contained in:
parent
c42ff338e7
commit
72e1e242a3
@ -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)
|
||||
{
|
||||
case audio_downmix::no_downmix: return AudioChannelCnt::SURROUND_7_1;
|
||||
case audio_downmix::downmix_to_5_1: return AudioChannelCnt::SURROUND_5_1;
|
||||
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);
|
||||
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:
|
||||
{
|
||||
switch (out.channels)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
case 2: return AudioChannelCnt::STEREO;
|
||||
case 6: return AudioChannelCnt::SURROUND_5_1;
|
||||
case 8: return AudioChannelCnt::SURROUND_7_1;
|
||||
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:
|
||||
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,
|
||||
};
|
||||
|
||||
enum class audio_downmix;
|
||||
|
||||
class AudioBackend
|
||||
{
|
||||
public:
|
||||
@ -140,7 +138,7 @@ public:
|
||||
/*
|
||||
* 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.
|
||||
|
@ -66,7 +66,7 @@ void cell_audio_config::reset(bool backend_changed)
|
||||
|
||||
const AudioFreq freq = AudioFreq::FREQ_48K;
|
||||
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;
|
||||
|
||||
audio_channels = static_cast<u32>(ch_cnt);
|
||||
@ -526,7 +526,7 @@ namespace audio
|
||||
.time_stretching_threshold = g_cfg.audio.time_stretching_threshold,
|
||||
.convert_to_s16 = static_cast<bool>(g_cfg.audio.convert_to_s16),
|
||||
.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,
|
||||
.provider = g_cfg.audio.provider
|
||||
};
|
||||
@ -550,7 +550,7 @@ namespace audio
|
||||
raw.time_stretching_threshold != new_raw.time_stretching_threshold ||
|
||||
raw.enable_time_stretching != new_raw.enable_time_stretching ||
|
||||
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.dump_to_file != new_raw.dump_to_file)
|
||||
{
|
||||
@ -848,13 +848,13 @@ void cell_audio_thread::operator()()
|
||||
switch (cfg.audio_channels)
|
||||
{
|
||||
case 2:
|
||||
mix<audio_downmix::downmix_to_stereo>(buf);
|
||||
mix<AudioChannelCnt::STEREO>(buf);
|
||||
break;
|
||||
case 6:
|
||||
mix<audio_downmix::downmix_to_5_1>(buf);
|
||||
mix<AudioChannelCnt::SURROUND_5_1>(buf);
|
||||
break;
|
||||
case 8:
|
||||
mix<audio_downmix::no_downmix>(buf);
|
||||
mix<AudioChannelCnt::SURROUND_7_1>(buf);
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
template <audio_downmix downmix>
|
||||
template <AudioChannelCnt downmix>
|
||||
void cell_audio_thread::mix(float *out_buffer, s32 offset)
|
||||
{
|
||||
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;
|
||||
|
||||
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 + 1] = right;
|
||||
|
||||
if constexpr (downmix != audio_downmix::downmix_to_stereo)
|
||||
if constexpr (downmix != AudioChannelCnt::STEREO)
|
||||
{
|
||||
out_buffer[out + 2] = 0.0f;
|
||||
out_buffer[out + 3] = 0.0f;
|
||||
out_buffer[out + 4] = 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 + 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_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
|
||||
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 + 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 + 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_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
|
||||
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 + 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 + 1] += right;
|
||||
|
@ -201,7 +201,7 @@ struct cell_audio_config
|
||||
s64 time_stretching_threshold = 0;
|
||||
bool convert_to_s16 = 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_provider provider = audio_provider::none;
|
||||
};
|
||||
@ -348,7 +348,7 @@ private:
|
||||
void reset_ports(s32 offset = 0);
|
||||
void advance(u64 timestamp);
|
||||
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 finish_port_volume_stepping();
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "Emu/Cell/lv2/sys_rsxaudio.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Loader/PSF.h"
|
||||
|
||||
#include "cellAudioOut.h"
|
||||
#include "cellAudio.h"
|
||||
@ -34,45 +35,137 @@ audio_out_configuration::audio_out_configuration()
|
||||
{
|
||||
CellAudioOutSoundMode mode{};
|
||||
|
||||
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;
|
||||
// TODO: audio_format should be a bitmap, but we'll keep it simple for now (Linear PCM 2 Ch. 48 kHz should always exist)
|
||||
// TODO: more formats:
|
||||
// - Each LPCM with other sample frequencies (we currently only support 48 kHz)
|
||||
// - 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);
|
||||
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||
const psf::registry psf = psf::load_object(fs::file(Emu.GetSfoDir() + "/PARAM.SFO"));
|
||||
if (psf.contains("SOUND_FORMAT")) sound_format = psf.at("SOUND_FORMAT").as_integer();
|
||||
|
||||
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;
|
||||
if (sound_format & (1 << 0)) // Linear PCM 2 Ch.
|
||||
{
|
||||
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);
|
||||
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||
}
|
||||
|
||||
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;
|
||||
if (sound_format & (1 << 2)) // Linear PCM 5.1 Ch.
|
||||
{
|
||||
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);
|
||||
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||
}
|
||||
|
||||
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;
|
||||
if (sound_format & (1 << 4)) // Linear PCM 7.1 Ch.
|
||||
{
|
||||
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);
|
||||
out.at(CELL_AUDIO_OUT_PRIMARY).sound_modes.push_back(mode);
|
||||
out.at(CELL_AUDIO_OUT_SECONDARY).sound_modes.push_back(mode);
|
||||
}
|
||||
|
||||
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;
|
||||
if (sound_format & (1 << 8)) // 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);
|
||||
out.at(CELL_AUDIO_OUT_PRIMARY).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);
|
||||
@ -87,22 +180,6 @@ error_code cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32
|
||||
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;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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
|
||||
audio_out_configuration& cfg = g_fxo->get<audio_out_configuration>();
|
||||
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_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>();
|
||||
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)
|
||||
{
|
||||
if (mode.type == out.encoder)
|
||||
{
|
||||
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;
|
||||
return mode.type == out.encoder && mode.channel == static_cast<u8>(channels);
|
||||
});
|
||||
|
||||
ensure(it != out.sound_modes.cend());
|
||||
@ -289,8 +336,7 @@ error_code cellAudioOutConfigure(u32 audioOut, vm::ptr<CellAudioOutConfiguration
|
||||
out_new = out;
|
||||
}
|
||||
|
||||
if (g_cfg.audio.audio_channel_downmix == audio_downmix::use_application_settings &&
|
||||
std::memcmp(&out_old, &out_new, sizeof(audio_out_configuration::audio_out)) != 0)
|
||||
if (std::memcmp(&out_old, &out_new, sizeof(audio_out_configuration::audio_out)) != 0)
|
||||
{
|
||||
const auto reset_audio = [audioOut]() -> void
|
||||
{
|
||||
|
@ -254,7 +254,7 @@ error_code cellHddGameCheck(ppu_thread& ppu, u32 version, vm::cptr<char> dirName
|
||||
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
|
||||
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()
|
||||
{
|
||||
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 =
|
||||
{
|
||||
|
@ -235,7 +235,7 @@ struct cfg_root : cfg::node
|
||||
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 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::_bool enable_buffering{ this, "Enable Buffering", true, 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 <>
|
||||
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)
|
||||
{
|
||||
case audio_downmix::no_downmix: return "No downmix";
|
||||
case audio_downmix::downmix_to_stereo: return "Downmix to Stereo";
|
||||
case audio_downmix::downmix_to_5_1: return "Downmix to 5.1";
|
||||
case audio_downmix::use_application_settings: return "Use application settings";
|
||||
case audio_format::automatic: return "Automatic";
|
||||
case audio_format::lpcm_2_48khz: return "Linear PCM 2 Ch. 48 kHz";
|
||||
case audio_format::lpcm_5_1_48khz: return "Linear PCM 5.1 Ch. 48 kHz";
|
||||
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;
|
||||
|
@ -76,12 +76,14 @@ enum class audio_avport
|
||||
spdif_1
|
||||
};
|
||||
|
||||
enum class audio_downmix
|
||||
enum class audio_format
|
||||
{
|
||||
no_downmix, // Surround 7.1
|
||||
downmix_to_stereo,
|
||||
downmix_to_5_1,
|
||||
use_application_settings
|
||||
automatic,
|
||||
lpcm_2_48khz,
|
||||
lpcm_5_1_48khz,
|
||||
lpcm_7_1_48khz,
|
||||
dts,
|
||||
ac3,
|
||||
};
|
||||
|
||||
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");
|
||||
}
|
||||
break;
|
||||
case emu_settings_type::AudioChannels:
|
||||
switch (static_cast<audio_downmix>(index))
|
||||
case emu_settings_type::AudioFormat:
|
||||
switch (static_cast<audio_format>(index))
|
||||
{
|
||||
case audio_downmix::no_downmix: return tr("Surround 7.1", "Audio downmix");
|
||||
case audio_downmix::downmix_to_stereo: return tr("Downmix to Stereo", "Audio downmix");
|
||||
case audio_downmix::downmix_to_5_1: return tr("Downmix to 5.1", "Audio downmix");
|
||||
case audio_downmix::use_application_settings: return tr("Use application settings", "Audio downmix");
|
||||
case audio_format::automatic: return tr("Automatic", "Audio format");
|
||||
case audio_format::lpcm_2_48khz: return tr("Linear PCM 2 Ch. 48 kHz", "Audio format");
|
||||
case audio_format::lpcm_5_1_48khz: return tr("Linear PCM 5.1 Ch. 48 kHz", "Audio format");
|
||||
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;
|
||||
case emu_settings_type::LicenseArea:
|
||||
|
@ -121,7 +121,7 @@ enum class emu_settings_type
|
||||
AudioRenderer,
|
||||
DumpToFile,
|
||||
ConvertTo16Bit,
|
||||
AudioChannels,
|
||||
AudioFormat,
|
||||
AudioProvider,
|
||||
AudioAvport,
|
||||
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::DumpToFile, { "Audio", "Dump to file"}},
|
||||
{ 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::AudioAvport, { "Audio", "RSXAudio Avport"}},
|
||||
{ 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);
|
||||
SubscribeTooltip(ui->gb_default_resolution, tooltips.settings.resolution);
|
||||
// remove unsupported resolutions from the dropdown
|
||||
const int saved_index = ui->resBox->currentIndex();
|
||||
bool saved_index_removed = false;
|
||||
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) },
|
||||
};
|
||||
|
||||
const int saved_index = ui->resBox->currentIndex();
|
||||
|
||||
for (int i = ui->resBox->count() - 1; i >= 0; i--)
|
||||
{
|
||||
bool has_resolution = false;
|
||||
@ -955,8 +956,63 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
||||
#endif
|
||||
connect(ui->audioOutBox, QOverload<int>::of(&QComboBox::currentIndexChanged), enable_buffering);
|
||||
|
||||
m_emu_settings->EnhanceComboBox(ui->combo_audio_downmix, emu_settings_type::AudioChannels);
|
||||
SubscribeTooltip(ui->gb_audio_downmix, tooltips.settings.downmix);
|
||||
m_emu_settings->EnhanceComboBox(ui->combo_audio_format, emu_settings_type::AudioFormat);
|
||||
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);
|
||||
SubscribeTooltip(ui->gb_audio_provider, tooltips.settings.audio_provider);
|
||||
|
@ -1031,13 +1031,13 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gb_audio_downmix">
|
||||
<widget class="QGroupBox" name="gb_audio_format">
|
||||
<property name="title">
|
||||
<string>Audio Channels</string>
|
||||
<string>Audio Format</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="gb_audio_channels_layout">
|
||||
<layout class="QVBoxLayout" name="gb_audio_format_layout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="combo_audio_downmix"/>
|
||||
<widget class="QComboBox" name="combo_audio_format"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
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 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 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.");
|
||||
|
Loading…
x
Reference in New Issue
Block a user