mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-29 06:16:55 +01:00
ngs2: accept larger custom voice state buffers
Co-authored-by: Frenzied <frenziedsaint@gmail.com>
This commit is contained in:
+13
-15
@@ -2701,24 +2701,22 @@ int KYTY_SYSV_ABI Ngs2VoiceGetState(uintptr_t voice_handle, Ngs2VoiceState* stat
|
|||||||
submixer->voice_state.state_flags = Ngs2GetStateFlags(voice);
|
submixer->voice_state.state_flags = Ngs2GetStateFlags(voice);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Ngs2RackType::CustomMastering: {
|
case Ngs2RackType::CustomMastering:
|
||||||
const auto configured_size =
|
|
||||||
voice->rack->option.custom_mastering.custom_rack_option.state_size;
|
|
||||||
EXIT_NOT_IMPLEMENTED(configured_size < sizeof(Ngs2CustomMasteringVoiceState));
|
|
||||||
EXIT_NOT_IMPLEMENTED(state_size != configured_size);
|
|
||||||
std::memset(state, 0, state_size);
|
|
||||||
auto* mastering = reinterpret_cast<Ngs2CustomMasteringVoiceState*>(state);
|
|
||||||
mastering->voice_state.state_flags = Ngs2GetStateFlags(voice);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Ngs2RackType::CustomSampler: {
|
case Ngs2RackType::CustomSampler: {
|
||||||
|
const bool sampler = voice->rack->type == Ngs2RackType::CustomSampler;
|
||||||
const auto configured_size =
|
const auto configured_size =
|
||||||
voice->rack->option.custom_sampler.custom_rack_option.state_size;
|
voice->rack->option.custom_sampler.custom_rack_option.state_size;
|
||||||
EXIT_NOT_IMPLEMENTED(configured_size < sizeof(Ngs2CustomSamplerVoiceState));
|
EXIT_NOT_IMPLEMENTED(configured_size < (sampler ? sizeof(Ngs2CustomSamplerVoiceState)
|
||||||
EXIT_NOT_IMPLEMENTED(state_size != configured_size);
|
: sizeof(Ngs2CustomMasteringVoiceState)));
|
||||||
std::memset(state, 0, state_size);
|
if (state_size < configured_size) {
|
||||||
auto* sampler = reinterpret_cast<Ngs2CustomSamplerVoiceState*>(state);
|
return static_cast<int32_t>(0x804a8011u);
|
||||||
Ngs2FillSamplerState(*voice, *sampler);
|
}
|
||||||
|
std::memset(state, 0, configured_size);
|
||||||
|
if (sampler) {
|
||||||
|
Ngs2FillSamplerState(*voice, *reinterpret_cast<Ngs2CustomSamplerVoiceState*>(state));
|
||||||
|
} else {
|
||||||
|
state->state_flags = Ngs2GetStateFlags(voice);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Ngs2RackType::Sampler: {
|
case Ngs2RackType::Sampler: {
|
||||||
|
|||||||
@@ -867,6 +867,44 @@ void TestCustomMasteringChannelMixer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestCustomVoiceStateCapacity() {
|
||||||
|
for (auto type: {Ngs2RackType::CustomSampler, Ngs2RackType::CustomMastering}) {
|
||||||
|
Fixture f(48000, 1, Ngs2RackType::CustomSampler);
|
||||||
|
f.rack.type = type;
|
||||||
|
f.rack.option.custom_sampler.custom_rack_option.state_size = 212;
|
||||||
|
f.voice.state_flags = 3;
|
||||||
|
f.voice.decoded_samples = 37;
|
||||||
|
f.voice.decoded_bytes = 128;
|
||||||
|
alignas(Ngs2CustomSamplerVoiceState) std::array<uint8_t, 384> storage;
|
||||||
|
auto* state = reinterpret_cast<Ngs2VoiceState*>(storage.data() + 8);
|
||||||
|
const auto handle = reinterpret_cast<uintptr_t>(&f.voice);
|
||||||
|
for (size_t capacity: {212u, 368u}) {
|
||||||
|
storage.fill(0xa5);
|
||||||
|
Check(Ngs2VoiceGetState(handle, state, capacity) == OK && state->state_flags == 3 &&
|
||||||
|
state->error_code == 0 &&
|
||||||
|
std::all_of(storage.begin(), storage.begin() + 8,
|
||||||
|
[](uint8_t v) { return v == 0xa5; }) &&
|
||||||
|
std::all_of(storage.begin() + 220, storage.end(),
|
||||||
|
[](uint8_t v) { return v == 0xa5; }),
|
||||||
|
"oversized custom state buffer was rejected or overwritten past configured state");
|
||||||
|
if (type == Ngs2RackType::CustomSampler) {
|
||||||
|
const auto* sampler = reinterpret_cast<const Ngs2CustomSamplerVoiceState*>(state);
|
||||||
|
Check(sampler->num_decoded_samples == 37 && sampler->decoded_data_size == 128,
|
||||||
|
"custom sampler state omitted playback progress");
|
||||||
|
}
|
||||||
|
const size_t base_size = type == Ngs2RackType::CustomSampler
|
||||||
|
? sizeof(Ngs2CustomSamplerVoiceState) : sizeof(Ngs2CustomMasteringVoiceState);
|
||||||
|
Check(std::all_of(storage.begin() + 8 + base_size, storage.begin() + 220,
|
||||||
|
[](uint8_t v) { return v == 0; }),
|
||||||
|
"configured custom state extension was not initialized");
|
||||||
|
}
|
||||||
|
storage.fill(0xa5);
|
||||||
|
Check(Ngs2VoiceGetState(handle, state, 211) == static_cast<int32_t>(0x804a8011u) &&
|
||||||
|
std::ranges::all_of(storage, [](uint8_t v) { return v == 0xa5; }),
|
||||||
|
"undersized custom state buffer was accepted or modified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TestPitchLoopAndSkip() {
|
void TestPitchLoopAndSkip() {
|
||||||
Fixture f(24000);
|
Fixture f(24000);
|
||||||
const int16_t pcm[] = {-30000, 8192, 16384};
|
const int16_t pcm[] = {-30000, 8192, 16384};
|
||||||
@@ -1766,6 +1804,7 @@ int main() {
|
|||||||
TestAtrac9Discrete();
|
TestAtrac9Discrete();
|
||||||
TestPcm16RenderOutput();
|
TestPcm16RenderOutput();
|
||||||
TestCustomMasteringChannelMixer();
|
TestCustomMasteringChannelMixer();
|
||||||
|
TestCustomVoiceStateCapacity();
|
||||||
TestSubmixerSetupAndRouting();
|
TestSubmixerSetupAndRouting();
|
||||||
TestCustomSideChainUserFx();
|
TestCustomSideChainUserFx();
|
||||||
TestWaveformBlockGeometry();
|
TestWaveformBlockGeometry();
|
||||||
|
|||||||
Reference in New Issue
Block a user