ngs: fix patch handle storage regression

This commit is contained in:
KorewaWatchful
2026-05-26 10:32:28 -04:00
committed by Gamid
parent b718baa002
commit 88f459c64d
5 changed files with 16 additions and 155 deletions
+5 -7
View File
@@ -218,9 +218,8 @@ EXPORT(SceInt32, sceNgsPatchGetInfo, ngs::Patch *patch, SceNgsPatchAudioPropInfo
return RET_ERROR(SCE_NGS_ERROR_INVALID_ARG);
}
patch->refresh_endpoints(emuenv.mem);
ngs::Voice *source = patch->resolve_source(emuenv.mem);
ngs::Voice *dest = patch->resolve_dest(emuenv.mem);
ngs::Voice *source = patch->source.get(emuenv.mem);
ngs::Voice *dest = patch->dest.get(emuenv.mem);
if (!source || !dest) {
return RET_ERROR(SCE_NGS_ERROR);
}
@@ -235,8 +234,8 @@ EXPORT(SceInt32, sceNgsPatchGetInfo, ngs::Patch *patch, SceNgsPatchAudioPropInfo
deli_info->input_index = patch->dest_index;
deli_info->output_index = patch->output_index;
deli_info->output_subindex = patch->output_sub_index;
deli_info->source_voice_handle = Ptr<ngs::Voice>(source, emuenv.mem);
deli_info->dest_voice_handle = Ptr<ngs::Voice>(dest, emuenv.mem);
deli_info->source_voice_handle = patch->source;
deli_info->dest_voice_handle = patch->dest;
}
return SCE_NGS_OK;
@@ -252,8 +251,7 @@ EXPORT(int, sceNgsPatchRemoveRouting, Ptr<ngs::Patch> patch) {
return RET_ERROR(SCE_NGS_ERROR_INVALID_ARG);
}
patch.get(emuenv.mem)->refresh_endpoints(emuenv.mem);
ngs::Voice *source = patch.get(emuenv.mem)->resolve_source(emuenv.mem);
ngs::Voice *source = patch.get(emuenv.mem)->source.get(emuenv.mem);
if (!source || !source->remove_patch(emuenv.mem, patch)) {
return RET_ERROR(SCE_NGS_ERROR);
}
+3 -29
View File
@@ -43,8 +43,6 @@ constexpr uint32_t default_normal_parameter_size = 100;
struct State;
struct Voice;
struct System;
enum VoiceState {
VOICE_STATE_AVAILABLE,
VOICE_STATE_ACTIVE,
@@ -52,33 +50,16 @@ enum VoiceState {
VOICE_STATE_UNLOADING,
};
struct VoiceAddress {
int32_t rack_index = -1;
int32_t voice_index = -1;
explicit operator bool() const {
return rack_index >= 0 && voice_index >= 0;
}
};
struct Patch {
int32_t output_index;
int32_t output_sub_index;
int32_t dest_index;
// runtime-only caches
ngs::System *system;
ngs::Voice *dest;
ngs::Voice *source;
VoiceAddress dest_address;
VoiceAddress source_address;
Ptr<ngs::Voice> dest;
Ptr<ngs::Voice> source;
float volume_matrix[2][2];
bool is_active() const;
Voice *resolve_source(const MemState &mem) const;
Voice *resolve_dest(const MemState &mem) const;
void refresh_endpoints(const MemState &mem);
};
struct ModuleLogicalState {
@@ -322,7 +303,7 @@ struct Voice {
ModuleData *module_storage(const uint32_t index);
bool remove_patch(const MemState &mem, const Ptr<Patch> patch);
Ptr<Patch> patch(const MemState &mem, const int32_t index, int32_t subindex, int32_t dest_index, Voice *dest);
Ptr<Patch> patch(const MemState &mem, const int32_t index, int32_t subindex, int32_t dest_index, Ptr<Voice> source, Ptr<Voice> dest);
void transition(const MemState &mem, const VoiceState new_state);
bool parse_params(const MemState &mem, const SceNgsModuleParamHeader *header);
@@ -332,8 +313,6 @@ struct Voice {
void invoke_callback(KernelState &kernel, const MemState &mem, const SceUID thread_id, Ptr<void> callback, Ptr<void> user_data,
const uint32_t module_id, const uint32_t reason = 0, const uint32_t reason2 = 0, Address reason_ptr = 0);
VoiceAddress address(const MemState &mem) const;
};
struct System;
@@ -351,8 +330,6 @@ struct Rack : public MempoolObject {
explicit Rack(System *mama, const Ptr<void> memspace, const uint32_t memspace_size);
int32_t index_of_voice(const MemState &mem, const Voice *voice) const;
static uint32_t get_required_memspace_size(MemState &mem, SceNgsRackDescription *description);
};
@@ -365,9 +342,6 @@ struct System : public MempoolObject {
VoiceScheduler voice_scheduler;
explicit System(const Ptr<void> memspace, const uint32_t memspace_size);
int32_t index_of_rack(const Rack *rack) const;
VoiceAddress address_of(const MemState &mem, const Voice *voice) const;
Voice *find_voice(const MemState &mem, const VoiceAddress &address) const;
static uint32_t get_required_memspace_size(SceNgsSystemInitParams *parameters);
};
+4 -112
View File
@@ -30,116 +30,16 @@ Rack::Rack(System *mama, const Ptr<void> memspace, const uint32_t memspace_size)
: MempoolObject(memspace, memspace_size)
, system(mama) {}
int32_t Rack::index_of_voice(const MemState &mem, const Voice *voice) const {
for (size_t i = 0; i < voices.size(); i++) {
if (voices[i].get(mem) == voice) {
return static_cast<int32_t>(i);
}
}
return -1;
}
System::System(const Ptr<void> memspace, const uint32_t memspace_size)
: MempoolObject(memspace, memspace_size)
, max_voices(0)
, granularity(0)
, sample_rate(0) {}
int32_t System::index_of_rack(const Rack *rack) const {
for (size_t i = 0; i < racks.size(); i++) {
if (racks[i] == rack) {
return static_cast<int32_t>(i);
}
}
return -1;
}
Voice *System::find_voice(const MemState &mem, const VoiceAddress &address) const {
if (!address) {
return nullptr;
}
if (address.rack_index < 0 || address.rack_index >= static_cast<int32_t>(racks.size())) {
return nullptr;
}
const Rack *rack = racks[address.rack_index];
if (!rack) {
return nullptr;
}
if (address.voice_index < 0 || address.voice_index >= static_cast<int32_t>(rack->voices.size())) {
return nullptr;
}
return rack->voices[address.voice_index].get(mem);
}
VoiceAddress System::address_of(const MemState &mem, const Voice *voice) const {
if (!voice || !voice->rack) {
return {};
}
VoiceAddress result;
result.rack_index = index_of_rack(voice->rack);
if (result.rack_index < 0) {
return {};
}
result.voice_index = voice->rack->index_of_voice(mem, voice);
if (result.voice_index < 0) {
return {};
}
return result;
}
bool Patch::is_active() const {
return output_sub_index != -1;
}
Voice *Patch::resolve_source(const MemState &mem) const {
if (system && source_address) {
return system->find_voice(mem, source_address);
}
return source;
}
Voice *Patch::resolve_dest(const MemState &mem) const {
if (system && dest_address) {
return system->find_voice(mem, dest_address);
}
return dest;
}
void Patch::refresh_endpoints(const MemState &mem) {
if (!system) {
if (source && source->rack) {
system = source->rack->system;
} else if (dest && dest->rack) {
system = dest->rack->system;
}
}
if (source) {
source_address = source->address(mem);
}
if (system && source_address) {
source = system->find_voice(mem, source_address);
}
if (dest) {
dest_address = dest->address(mem);
}
if (system && dest_address) {
dest = system->find_voice(mem, dest_address);
}
}
void VoiceInputManager::init(const uint32_t granularity, const uint16_t total_input) {
inputs.resize(total_input);
@@ -166,9 +66,8 @@ VoiceInputManager::PCMInput *VoiceInputManager::get_input_buffer_queue(const int
}
int32_t VoiceInputManager::receive(const MemState &mem, ngs::Patch *patch, const VoiceProduct &product) {
patch->refresh_endpoints(mem);
Voice *source = patch->resolve_source(mem);
Voice *dest = patch->resolve_dest(mem);
Voice *source = patch->source.get(mem);
Voice *dest = patch->dest.get(mem);
if (!source || !dest) {
return -1;
}
@@ -267,7 +166,7 @@ void Voice::init(Rack *mama) {
voice_mutex = std::make_unique<std::mutex>();
}
Ptr<Patch> Voice::patch(const MemState &mem, const int32_t index, int32_t subindex, int32_t dest_index, Voice *dest) {
Ptr<Patch> Voice::patch(const MemState &mem, const int32_t index, int32_t subindex, int32_t dest_index, Ptr<Voice> source, Ptr<Voice> dest) {
const std::lock_guard<std::mutex> guard(*voice_mutex);
if (index >= MAX_OUTPUT_PORT) {
@@ -304,11 +203,8 @@ Ptr<Patch> Voice::patch(const MemState &mem, const int32_t index, int32_t subind
patch->output_sub_index = subindex;
patch->output_index = index;
patch->dest_index = dest_index;
patch->system = rack->system;
patch->dest = dest;
patch->source = this;
patch->dest_address = dest ? dest->address(mem) : VoiceAddress();
patch->source_address = address(mem);
patch->source = source;
// Initialize the matrix
memset(patch->volume_matrix, 0, sizeof(patch->volume_matrix));
@@ -442,10 +338,6 @@ void Voice::invoke_callback(KernelState &kernel, const MemState &mem, const SceU
stack_free(*thread->cpu, sizeof(SceNgsCallbackInfo));
}
VoiceAddress Voice::address(const MemState &mem) const {
return rack->system->address_of(mem, this);
}
uint32_t System::get_required_memspace_size(SceNgsSystemInitParams *parameters) {
return sizeof(System);
}
+1 -2
View File
@@ -32,8 +32,7 @@ bool deliver_data(const MemState &mem, const std::vector<Voice *> &voice_queue,
if (!patch || !patch->is_active())
continue;
patch->refresh_endpoints(mem);
Voice *dest = patch->resolve_dest(mem);
Voice *dest = patch->dest.get(mem);
if (!dest || !vector_utils::contains(voice_queue, dest))
continue;
+3 -5
View File
@@ -43,8 +43,7 @@ void VoiceScheduler::deque_insert(const MemState &mem, Voice *voice) {
continue;
}
patch.get(mem)->refresh_endpoints(mem);
Voice *dest = patch.get(mem)->resolve_dest(mem);
Voice *dest = patch.get(mem)->dest.get(mem);
if (!dest) {
continue;
}
@@ -212,8 +211,7 @@ bool VoiceScheduler::resort_to_respect_dependencies(const MemState &mem, Voice *
continue;
}
patch.get(mem)->refresh_endpoints(mem);
Voice *dest = patch.get(mem)->resolve_dest(mem);
Voice *dest = patch.get(mem)->dest.get(mem);
if (!dest) {
continue;
}
@@ -242,7 +240,7 @@ Ptr<Patch> VoiceScheduler::patch(const MemState &mem, SceNgsPatchSetupInfo *info
Voice *source = info->source.get(mem);
Voice *dest = info->dest.get(mem);
Ptr<Patch> patch = source->patch(mem, info->source_output_index, info->source_output_subindex, info->dest_input_index, dest);
Ptr<Patch> patch = source->patch(mem, info->source_output_index, info->source_output_subindex, info->dest_input_index, info->source, info->dest);
if (!patch) {
return patch;