mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-30 01:01:21 +00:00
ngs2: render the reverb voice dry signal
Co-authored-by: Phr3d13 <phr3d13@gmail.com>
This commit is contained in:
1 parent
2aa0d58ffb
commit
08a7d7fbed
2 files changed
+55
-1
No files matched your search
+31
-1
@@ -570,6 +570,7 @@ struct Ngs2VoiceInternal {
|
|||||||
uint32_t output_id = 0;
|
uint32_t output_id = 0;
|
||||||
float fbw_level = 1.0f;
|
float fbw_level = 1.0f;
|
||||||
float lfe_level = 1.0f;
|
float lfe_level = 1.0f;
|
||||||
|
float dry_level = 0.0f;
|
||||||
bool rendering = false;
|
bool rendering = false;
|
||||||
bool rendered = false;
|
bool rendered = false;
|
||||||
bool has_samples = false;
|
bool has_samples = false;
|
||||||
@@ -1869,6 +1870,11 @@ static void Ngs2RenderVoice(Ngs2VoiceInternal& voice, const std::vector<Ngs2Voic
|
|||||||
voice.has_samples = true;
|
voice.has_samples = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (voice.has_samples && voice.rack->type == Ngs2RackType::Reverb) {
|
||||||
|
for (auto& sample: voice.samples) {
|
||||||
|
sample *= voice.dry_level;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (voice.has_samples) {
|
if (voice.has_samples) {
|
||||||
const auto& custom = voice.rack->option.custom_sampler.custom_rack_option;
|
const auto& custom = voice.rack->option.custom_sampler.custom_rack_option;
|
||||||
const auto rate = voice.rack->ngs->option.sample_rate;
|
const auto rate = voice.rack->ngs->option.sample_rate;
|
||||||
@@ -2472,7 +2478,31 @@ int KYTY_SYSV_ABI Ngs2VoiceControl(uintptr_t voice_handle, const Ngs2VoiceParamH
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x2001: EXIT_NOT_IMPLEMENTED(voice->rack->type != Ngs2RackType::Reverb); break;
|
case 0x2001: {
|
||||||
|
EXIT_NOT_IMPLEMENTED(voice->rack->type != Ngs2RackType::Reverb);
|
||||||
|
const auto* values = reinterpret_cast<const uint32_t*>(param + 1);
|
||||||
|
switch (param->id & 0xffffu) {
|
||||||
|
case 0:
|
||||||
|
// Input and output channels, flags; channel conversion stays silent.
|
||||||
|
EXIT_NOT_IMPLEMENTED(values[0] == 0 || values[2] != 0);
|
||||||
|
voice->ResetSetupState();
|
||||||
|
voice->channels = values[1] == values[0] ? values[0] : 0;
|
||||||
|
break;
|
||||||
|
case 1: {
|
||||||
|
// The reverb parameters start with the wet and dry levels.
|
||||||
|
const auto* levels = reinterpret_cast<const float*>(values);
|
||||||
|
voice->dry_level = std::clamp(levels[1], 0.0f, 1.0f);
|
||||||
|
|
||||||
|
static std::atomic_bool wet_warned = false;
|
||||||
|
if (levels[0] != 0.0f && !wet_warned.exchange(true)) {
|
||||||
|
Log::WriteToConsoleAndLog("warning: NGS2 reverb wet signal is muted\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: EXIT("unsupported reverb control: 0x%08" PRIx32 "\n", param->id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 0x3000: {
|
case 0x3000: {
|
||||||
EXIT_NOT_IMPLEMENTED(voice->rack->type != Ngs2RackType::Mastering);
|
EXIT_NOT_IMPLEMENTED(voice->rack->type != Ngs2RackType::Mastering);
|
||||||
const auto* values = reinterpret_cast<const uint32_t*>(param + 1);
|
const auto* values = reinterpret_cast<const uint32_t*>(param + 1);
|
||||||
|
|||||||
@@ -854,6 +854,29 @@ void TestMasteringGain() {
|
|||||||
"mastering gain was not clamped or applied per full band and LFE channel");
|
"mastering gain was not clamped or applied per full band and LFE channel");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestReverbDryLevel() {
|
||||||
|
Fixture f(48000);
|
||||||
|
Ngs2RackInternal reverb_rack {};
|
||||||
|
reverb_rack.ngs = &f.system;
|
||||||
|
reverb_rack.type = Ngs2RackType::Reverb;
|
||||||
|
Ngs2VoiceInternal reverb;
|
||||||
|
reverb.rack = &reverb_rack;
|
||||||
|
f.voice.ports.push_back({&reverb, 0, 1.0f, -1});
|
||||||
|
const int16_t pcm = 8192;
|
||||||
|
f.Queue(&pcm, 1, 0);
|
||||||
|
struct {
|
||||||
|
Ngs2VoiceParamHeader header {24, 24, 0x20010000};
|
||||||
|
uint32_t channels[4] = {1, 1, 0, 0};
|
||||||
|
Ngs2VoiceParamHeader levels_header {96, 0, 0x20010001};
|
||||||
|
float levels[22] = {0.6f, 0.4f};
|
||||||
|
} setup;
|
||||||
|
Ngs2VoiceControl(reinterpret_cast<uintptr_t>(&reverb), &setup.header);
|
||||||
|
reverb.SetEvent(1);
|
||||||
|
Ngs2RenderVoice(reverb, {&f.voice, &reverb}, 1);
|
||||||
|
Check(reverb.has_samples && reverb.samples[0] == 0.25f * 0.4f,
|
||||||
|
"reverb did not pass its dry signal");
|
||||||
|
}
|
||||||
|
|
||||||
void TestCustomMasteringChannelMixer() {
|
void TestCustomMasteringChannelMixer() {
|
||||||
Ngs2Internal system;
|
Ngs2Internal system;
|
||||||
system.option = Ngs2DefaultSystemOption();
|
system.option = Ngs2DefaultSystemOption();
|
||||||
@@ -1875,6 +1898,7 @@ int main() {
|
|||||||
TestPcm16RenderOutput();
|
TestPcm16RenderOutput();
|
||||||
TestPatchToRackHandle();
|
TestPatchToRackHandle();
|
||||||
TestMasteringGain();
|
TestMasteringGain();
|
||||||
|
TestReverbDryLevel();
|
||||||
TestCustomMasteringChannelMixer();
|
TestCustomMasteringChannelMixer();
|
||||||
TestCustomVoiceStateCapacity();
|
TestCustomVoiceStateCapacity();
|
||||||
TestSubmixerSetupAndRouting();
|
TestSubmixerSetupAndRouting();
|
||||||
|
|||||||
Reference in new issue
Block a user