Add field to JASChannel to keep sample data backing wave replacements alive

How to ensure stuff doesn't get freed when mod reloading gets involved? More shared_ptr
This commit is contained in:
PJB3005
2026-07-26 15:00:53 +02:00
parent f6e05eb04f
commit 4e46c04c91
5 changed files with 47 additions and 2 deletions
@@ -8,6 +8,7 @@
#include "JSystem/JAudio2/JASWaveInfo.h"
#include "JSystem/JAudio2/JASDSPInterface.h"
#include <os.h>
#include <memory>
struct JASDSPChannel;
@@ -15,6 +16,20 @@ namespace JASDsp {
struct TChannel;
}
#if TARGET_PC
/**
* An object to manage the lifetime of the sample data pointed to by JASChannel.
*
* JASChannel can (optionally) accept an unique_ptr to an object to this type,
* in which case it will be destroyed when the JASChannel is done.
*
* @see JASChannel::mSampleReference
*/
struct JASSampleDataReference {
virtual ~JASSampleDataReference() = default;
};
#endif
/**
* @ingroup jsystem-jaudio
*
@@ -176,6 +191,11 @@ public:
* If nullptr, the regular emulated ARAM is used.
*/
void const* mAramBaseAddress;
/**
* @see JASSampleDataReference
*/
std::unique_ptr<JASSampleDataReference> mSampleReference;
#endif
static DUSK_GAME_DATA OSMessageQueue sBankDisposeMsgQ;
@@ -2,6 +2,11 @@
#define JASWAVEINFO_H
#include <types.h>
#include <memory>
#if TARGET_PC
struct JASSampleDataReference;
#endif
struct JASWaveArc;
@@ -50,6 +55,11 @@ public:
* @see JASChannel::mAramBaseAddress
*/
[[nodiscard]] virtual void const* getAramBaseAddress() const = 0;
/**
* Create a @ref JASSampleDataReference to keep the sample data for this wave alive.
*/
[[nodiscard]] virtual std::unique_ptr<JASSampleDataReference> getSampleReference() const { return nullptr; }
#endif
};
+5 -2
View File
@@ -38,6 +38,8 @@ JASChannel* JASBank::noteOn(JASBank const* param_0, int param_1, u8 param_2, u8
if (found_replacement != s_replacements.end()) {
waveHandle = found_replacement->second.get();
}
auto const aramBase = waveHandle->getAramBaseAddress();
#endif
const JASWaveInfo* waveInfo = waveHandle->getWaveInfo();
@@ -45,7 +47,7 @@ JASChannel* JASBank::noteOn(JASBank const* param_0, int param_1, u8 param_2, u8
return NULL;
}
intptr_t wavePtr = waveHandle->getWavePtr();
if (!wavePtr IF_DUSK(&& !waveHandle->getAramBaseAddress())) {
if (!wavePtr IF_DUSK(&& !aramBase)) {
return NULL;
}
@@ -57,7 +59,8 @@ JASChannel* JASBank::noteOn(JASBank const* param_0, int param_1, u8 param_2, u8
channel->field_0xdc.mWaveInfo = *waveInfo;
channel->mWaveAramAddress = wavePtr;
#if TARGET_PC
channel->mAramBaseAddress = waveHandle->getAramBaseAddress();
channel->mAramBaseAddress = aramBase;
channel->mSampleReference = waveHandle->getSampleReference();
#endif
channel->field_0xdc.mChannelType = stack_60.field_0x1c;
channel->setBankDisposeID(param_0);
@@ -201,6 +201,10 @@ intptr_t AudioWaveReplacementValue::getWavePtr() const {
return 0;
}
std::unique_ptr<JASSampleDataReference> AudioWaveReplacementValue::getSampleReference() const {
return std::make_unique<SampleReference>(data);
}
void SampleDataPcm16::be_swap() {
for (auto& sample : data) {
::be_swap(sample);
@@ -1,6 +1,7 @@
#pragma once
#include <memory>
#include "JSystem/JAudio2/JASChannel.h"
#include "JSystem/JAudio2/JASWaveInfo.h"
#include "absl/container/flat_hash_map.h"
#include "mods/svc/audio_res.h"
@@ -40,6 +41,12 @@ struct SampleDataU8 : SampleDataBuf {
}
};
struct SampleReference : JASSampleDataReference {
explicit SampleReference(std::shared_ptr<SampleDataBuf> data) : data(std::move(data)) {}
std::shared_ptr<SampleDataBuf> data;
};
struct AudioWaveKey {
AudioWaveBank bank;
u32 wave_id;
@@ -59,6 +66,7 @@ struct AudioWaveReplacementValue : JASWaveHandle {
[[nodiscard]] const JASWaveInfo* getWaveInfo() const override;
[[nodiscard]] intptr_t getWavePtr() const override;
[[nodiscard]] void const* getAramBaseAddress() const override;
[[nodiscard]] std::unique_ptr<JASSampleDataReference> getSampleReference() const override;
JASWaveInfo wave_info;
std::shared_ptr<SampleDataBuf> data;