mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-30 01:01:21 +00:00
ngs2: apply mastering voice full band and LFE gain
Co-authored-by: Phr3d13 <phr3d13@gmail.com>
This commit is contained in:
1 parent
67f8276751
commit
e66a7f52b5
2 files changed
+47
-3
No files matched your search
+14
-3
@@ -568,6 +568,8 @@ struct Ngs2VoiceInternal {
|
|||||||
std::vector<float> output_matrix;
|
std::vector<float> output_matrix;
|
||||||
uint32_t channels = 0;
|
uint32_t channels = 0;
|
||||||
uint32_t output_id = 0;
|
uint32_t output_id = 0;
|
||||||
|
float fbw_level = 1.0f;
|
||||||
|
float lfe_level = 1.0f;
|
||||||
bool rendering = false;
|
bool rendering = false;
|
||||||
bool rendered = false;
|
bool rendered = false;
|
||||||
bool has_samples = false;
|
bool has_samples = false;
|
||||||
@@ -1978,10 +1980,13 @@ int KYTY_SYSV_ABI Ngs2SystemRender(uintptr_t system_handle, const Ngs2RenderBuff
|
|||||||
pcm = static_cast<float*>(output.buffer);
|
pcm = static_cast<float*>(output.buffer);
|
||||||
}
|
}
|
||||||
for (uint32_t dst = 0; dst < output.num_channels; ++dst) {
|
for (uint32_t dst = 0; dst < output.num_channels; ++dst) {
|
||||||
|
// Output channel 3 is LFE; every other channel is full band.
|
||||||
|
const float gain = dst == 3 ? voice->lfe_level : voice->fbw_level;
|
||||||
for (uint32_t src = 0; src < voice->channels; ++src) {
|
for (uint32_t src = 0; src < voice->channels; ++src) {
|
||||||
const float level = voice->output_matrix.empty()
|
const float level =
|
||||||
? (src == dst ? 1.0f : 0.0f)
|
gain * (voice->output_matrix.empty()
|
||||||
: voice->output_matrix.at(src * output.num_channels + dst);
|
? static_cast<float>(src == dst)
|
||||||
|
: voice->output_matrix.at(src * output.num_channels + dst));
|
||||||
if (level == 0.0f) {
|
if (level == 0.0f) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -2481,6 +2486,12 @@ int KYTY_SYSV_ABI Ngs2VoiceControl(uintptr_t voice_handle, const Ngs2VoiceParamH
|
|||||||
matrix->levels + matrix->num_levels);
|
matrix->levels + matrix->num_levels);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 4: {
|
||||||
|
const auto* levels = reinterpret_cast<const float*>(values);
|
||||||
|
voice->fbw_level = std::clamp(levels[0], 0.0f, 4.0f);
|
||||||
|
voice->lfe_level = std::clamp(levels[1], 0.0f, 4.0f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 5: voice->output_id = values[0]; break;
|
case 5: voice->output_id = values[0]; break;
|
||||||
default: EXIT("unsupported mastering control: 0x%08" PRIx32 "\n", param->id);
|
default: EXIT("unsupported mastering control: 0x%08" PRIx32 "\n", param->id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -822,6 +822,38 @@ void TestPatchToRackHandle() {
|
|||||||
"patch to a rack handle did not connect to its voice #0");
|
"patch to a rack handle did not connect to its voice #0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestMasteringGain() {
|
||||||
|
Ngs2Internal system;
|
||||||
|
system.option = Ngs2DefaultSystemOption();
|
||||||
|
system.option.num_grain_samples = 1;
|
||||||
|
Ngs2RackOptionUnion sampler_option {}, mastering_option {};
|
||||||
|
Ngs2FillDefaultRackOption(0x1000, &sampler_option);
|
||||||
|
Ngs2FillDefaultRackOption(0x3000, &mastering_option);
|
||||||
|
sampler_option.common.max_voices = 1;
|
||||||
|
RenderRack sampler(system, 0x1000, sampler_option.common);
|
||||||
|
RenderRack master(system, 0x3000, mastering_option.common);
|
||||||
|
auto& source = sampler.Voice();
|
||||||
|
auto& mastering = master.Voice();
|
||||||
|
mastering.channels = 8;
|
||||||
|
mastering.state = Ngs2VoicePlayState::Playing;
|
||||||
|
const int16_t frame[8] = {8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192};
|
||||||
|
source.SetupSampler({0x12, 8, 48000});
|
||||||
|
source.blocks.push_back({reinterpret_cast<const uint8_t*>(frame), {0, sizeof(frame), 0, 0, 1}});
|
||||||
|
source.ports[0].dest = &mastering;
|
||||||
|
source.SetEvent(1);
|
||||||
|
struct {
|
||||||
|
Ngs2VoiceParamHeader header {16, 0, 0x30000004};
|
||||||
|
float fbw = 5.0f, lfe = 0.5f;
|
||||||
|
} gain;
|
||||||
|
float pcm[8] = {};
|
||||||
|
Ngs2RenderBufferInfo output {pcm, sizeof(pcm), 0x18, 8};
|
||||||
|
const float expected[8] = {1.0f, 1.0f, 1.0f, 0.125f, 1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
Check(Ngs2VoiceControl(reinterpret_cast<uintptr_t>(&mastering), &gain.header) == OK &&
|
||||||
|
Ngs2SystemRender(reinterpret_cast<uintptr_t>(&system), &output, 1) == OK &&
|
||||||
|
std::ranges::equal(pcm, expected),
|
||||||
|
"mastering gain was not clamped or applied per full band and LFE channel");
|
||||||
|
}
|
||||||
|
|
||||||
void TestCustomMasteringChannelMixer() {
|
void TestCustomMasteringChannelMixer() {
|
||||||
Ngs2Internal system;
|
Ngs2Internal system;
|
||||||
system.option = Ngs2DefaultSystemOption();
|
system.option = Ngs2DefaultSystemOption();
|
||||||
@@ -1819,6 +1851,7 @@ int main() {
|
|||||||
TestAtrac9Discrete();
|
TestAtrac9Discrete();
|
||||||
TestPcm16RenderOutput();
|
TestPcm16RenderOutput();
|
||||||
TestPatchToRackHandle();
|
TestPatchToRackHandle();
|
||||||
|
TestMasteringGain();
|
||||||
TestCustomMasteringChannelMixer();
|
TestCustomMasteringChannelMixer();
|
||||||
TestCustomVoiceStateCapacity();
|
TestCustomVoiceStateCapacity();
|
||||||
TestSubmixerSetupAndRouting();
|
TestSubmixerSetupAndRouting();
|
||||||
|
|||||||
Reference in new issue
Block a user