audio: allow looping waveform blocks and exit-loop on NGS2 custom samplers

This commit is contained in:
Mr. Big Britches authored and nmzik committed 2026-10-20 15:21:19 +02:00
1 parent 6b6274fa5a
commit 18e6747dbf
2 files changed
+8 -8

No files matched your search

-2
View File
@@ -703,7 +703,6 @@ struct Ngs2VoiceInternal {
info.num_skip_samples = 0; info.num_skip_samples = 0;
info.num_samples = 0; info.num_samples = 0;
} }
EXIT_NOT_IMPLEMENTED(info.num_repeats != 0 && rack->type != Ngs2RackType::Sampler);
EXIT_NOT_IMPLEMENTED(decoder == nullptr && EXIT_NOT_IMPLEMENTED(decoder == nullptr &&
(uint64_t(info.num_skip_samples) + info.num_samples) * (uint64_t(info.num_skip_samples) + info.num_samples) *
channels * sizeof(int16_t) > channels * sizeof(int16_t) >
@@ -2510,7 +2509,6 @@ int KYTY_SYSV_ABI Ngs2VoiceControl(uintptr_t voice_handle, const Ngs2VoiceParamH
break; break;
} }
case 4: { case 4: {
EXIT_NOT_IMPLEMENTED(voice->rack->type != Ngs2RackType::Sampler);
for (auto& block: voice->blocks) { for (auto& block: voice->blocks) {
if (block.info.num_repeats != 0) { if (block.info.num_repeats != 0) {
block.info.num_repeats = 0; block.info.num_repeats = 0;
+8 -6
View File
@@ -1193,9 +1193,9 @@ void KYTY_SYSV_ABI RecordLoopCallback(const Ngs2VoiceCallbackInfo* info) {
} }
} }
void TestLoopCallbacksAndExit() { void TestLoopCallbacksAndExit(Ngs2RackType type) {
const int16_t pcm[] = {8192, 16384, 24576}; const int16_t pcm[] = {8192, 16384, 24576};
Fixture f(48000); Fixture f(48000, 1, type);
LoopCallbacks log; LoopCallbacks log;
f.voice.callback = reinterpret_cast<uintptr_t>(&RecordLoopCallback); f.voice.callback = reinterpret_cast<uintptr_t>(&RecordLoopCallback);
f.voice.callback_data = reinterpret_cast<uintptr_t>(&log); f.voice.callback_data = reinterpret_cast<uintptr_t>(&log);
@@ -1206,7 +1206,7 @@ void TestLoopCallbacksAndExit() {
"loop and completion callbacks lost the completed repeat count"); "loop and completion callbacks lost the completed repeat count");
Check(f.voice.blocks.empty(), "finite loop did not complete"); Check(f.voice.blocks.empty(), "finite loop did not complete");
Fixture active(48000); Fixture active(48000, 1, type);
log.events.clear(); log.events.clear();
log.pause = true; log.pause = true;
active.voice.callback = reinterpret_cast<uintptr_t>(&RecordLoopCallback); active.voice.callback = reinterpret_cast<uintptr_t>(&RecordLoopCallback);
@@ -1218,7 +1218,8 @@ void TestLoopCallbacksAndExit() {
Check(log.events.size() == 1 && active.voice.decoded_samples == 2 && Check(log.events.size() == 1 && active.voice.decoded_samples == 2 &&
active.voice.blocks.front().cursor == 0 && active.voice.samples[2] == 0, active.voice.blocks.front().cursor == 0 && active.voice.samples[2] == 0,
"loop callback pause consumed another iteration"); "loop callback pause consumed another iteration");
Ngs2VoiceParamHeader exit_loop {sizeof(Ngs2VoiceParamHeader), 0, 0x10000004}; Ngs2VoiceParamHeader exit_loop {sizeof(Ngs2VoiceParamHeader), 0,
type == Ngs2RackType::Sampler ? 0x10000004u : 0x40010004u};
Ngs2VoiceControl(reinterpret_cast<uintptr_t>(&active.voice), &exit_loop); Ngs2VoiceControl(reinterpret_cast<uintptr_t>(&active.voice), &exit_loop);
active.voice.SetEvent(32); active.voice.SetEvent(32);
active.Render(5); active.Render(5);
@@ -1226,7 +1227,7 @@ void TestLoopCallbacksAndExit() {
active.voice.blocks.empty() && log.events.size() == 1, active.voice.blocks.empty() && log.events.size() == 1,
"exiting infinite loop lost its final iteration or ignored callback flags"); "exiting infinite loop lost its final iteration or ignored callback flags");
Fixture pending(48000); Fixture pending(48000, 1, type);
pending.Queue(pcm, 1, 1); pending.Queue(pcm, 1, 1);
pending.Queue(pcm + 1, 1, 1, UINT32_MAX); pending.Queue(pcm + 1, 1, 1, UINT32_MAX);
pending.Queue(pcm + 2, 1, 0); pending.Queue(pcm + 2, 1, 0);
@@ -1663,7 +1664,8 @@ int main() {
TestResamplingPhaseAfterStarvation(); TestResamplingPhaseAfterStarvation();
TestSamplerReuseResetsRouting(); TestSamplerReuseResetsRouting();
TestDeferredSamplerSetup(); TestDeferredSamplerSetup();
TestLoopCallbacksAndExit(); TestLoopCallbacksAndExit(Ngs2RackType::Sampler);
TestLoopCallbacksAndExit(Ngs2RackType::CustomSampler);
TestAtrac9Looping(); TestAtrac9Looping();
TestAtrac9WaveformJoining(); TestAtrac9WaveformJoining();
TestWaveformReadAddress(); TestWaveformReadAddress();