cellAudio: fix downmix if device doesn't support multichannel (#12328)

* cellAudio: fix downmix if device doesn't support multichannel
* Downmix in 2 stages
This commit is contained in:
Vestrel 2022-07-09 22:25:28 +09:00 committed by GitHub
parent cd0d43382f
commit 648ad0cd90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 7 deletions

View file

@ -82,7 +82,8 @@ void cell_audio_config::reset(bool backend_changed)
}
audio_downmix = downmix;
audio_channels = ch_cnt;
backend_ch_cnt = AudioChannelCnt{ch_cnt};
audio_channels = static_cast<u32>(req_ch_cnt);
audio_sampling_rate = static_cast<u32>(freq);
audio_block_period = AUDIO_BUFFER_SAMPLES * 1'000'000 / audio_sampling_rate;
audio_sample_size = static_cast<u32>(sample_size);
@ -155,7 +156,7 @@ audio_ringbuffer::audio_ringbuffer(cell_audio_config& _cfg)
return cfg.audio_min_buffer_duration;
}();
cb_ringbuf.set_buf_size(static_cast<u32>(cfg.audio_channels * cfg.audio_sampling_rate * cfg.audio_sample_size * buffer_dur_mult));
cb_ringbuf.set_buf_size(static_cast<u32>(static_cast<u32>(cfg.backend_ch_cnt) * cfg.audio_sampling_rate * cfg.audio_sample_size * buffer_dur_mult));
backend->SetWriteCallback(std::bind(&audio_ringbuffer::backend_write_callback, this, std::placeholders::_1, std::placeholders::_2));
}
@ -203,7 +204,7 @@ float* audio_ringbuffer::get_current_buffer() const
u64 audio_ringbuffer::get_enqueued_samples() const
{
AUDIT(cfg.buffering_enabled);
const u64 ringbuf_samples = cb_ringbuf.get_used_size() / (cfg.audio_sample_size * cfg.audio_channels);
const u64 ringbuf_samples = cb_ringbuf.get_used_size() / (cfg.audio_sample_size * static_cast<u32>(cfg.backend_ch_cnt));
if (cfg.time_stretching_enabled)
{
@ -264,7 +265,7 @@ void audio_ringbuffer::process_resampled_data()
{
if (!cfg.time_stretching_enabled) return;
const auto samples = resampler.get_samples(static_cast<u32>(cb_ringbuf.get_free_size() / (cfg.audio_sample_size * cfg.audio_channels)));
const auto samples = resampler.get_samples(static_cast<u32>(cb_ringbuf.get_free_size() / (cfg.audio_sample_size * static_cast<u32>(cfg.backend_ch_cnt))));
commit_data(samples.first, samples.second);
}
@ -275,12 +276,48 @@ void audio_ringbuffer::commit_data(f32* buf, u32 sample_cnt)
// Dump audio if enabled
m_dump.WriteData(buf, sample_cnt * static_cast<u32>(AudioSampleSize::FLOAT));
if (cfg.backend->get_convert_to_s16())
if (cfg.backend_ch_cnt < AudioChannelCnt{cfg.audio_channels})
{
AudioBackend::convert_to_s16(sample_cnt, buf, buf);
if (AudioChannelCnt{cfg.audio_channels} == AudioChannelCnt::SURROUND_7_1)
{
if (cfg.backend_ch_cnt == AudioChannelCnt::SURROUND_5_1)
{
AudioBackend::downmix<AudioChannelCnt::SURROUND_7_1, AudioChannelCnt::SURROUND_5_1>(sample_cnt, buf, buf);
}
else if (cfg.backend_ch_cnt == AudioChannelCnt::STEREO)
{
AudioBackend::downmix<AudioChannelCnt::SURROUND_7_1, AudioChannelCnt::STEREO>(sample_cnt, buf, buf);
}
else
{
fmt::throw_exception("Invalid downmix combination: %u -> %u", cfg.audio_channels, static_cast<u32>(cfg.backend_ch_cnt));
}
}
else if (AudioChannelCnt{cfg.audio_channels} == AudioChannelCnt::SURROUND_5_1)
{
if (cfg.backend_ch_cnt == AudioChannelCnt::STEREO)
{
AudioBackend::downmix<AudioChannelCnt::SURROUND_5_1, AudioChannelCnt::STEREO>(sample_cnt, buf, buf);
}
else
{
fmt::throw_exception("Invalid downmix combination: %u -> %u", cfg.audio_channels, static_cast<u32>(cfg.backend_ch_cnt));
}
}
else
{
fmt::throw_exception("Invalid downmix combination: %u -> %u", cfg.audio_channels, static_cast<u32>(cfg.backend_ch_cnt));
}
}
cb_ringbuf.push(buf, sample_cnt * cfg.audio_sample_size);
const u32 sample_cnt_out = sample_cnt / cfg.audio_channels * static_cast<u32>(cfg.backend_ch_cnt);
if (cfg.backend->get_convert_to_s16())
{
AudioBackend::convert_to_s16(sample_cnt_out, buf, buf);
}
cb_ringbuf.push(buf, sample_cnt_out * cfg.audio_sample_size);
}
void audio_ringbuffer::play()

View file

@ -222,6 +222,7 @@ struct cell_audio_config
std::shared_ptr<AudioBackend> backend = nullptr;
AudioChannelCnt audio_downmix = AudioChannelCnt::SURROUND_7_1;
AudioChannelCnt backend_ch_cnt = AudioChannelCnt::SURROUND_7_1;
u32 audio_channels = 0;
u32 audio_sampling_rate = 0;
u32 audio_block_period = 0;