diff --git a/libs/JSystem/include/JSystem/JAudio2/JASChannel.h b/libs/JSystem/include/JSystem/JAudio2/JASChannel.h index 59512fbadd..2310cc590f 100644 --- a/libs/JSystem/include/JSystem/JAudio2/JASChannel.h +++ b/libs/JSystem/include/JSystem/JAudio2/JASChannel.h @@ -8,6 +8,7 @@ #include "JSystem/JAudio2/JASWaveInfo.h" #include "JSystem/JAudio2/JASDSPInterface.h" #include +#include 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 mSampleReference; #endif static DUSK_GAME_DATA OSMessageQueue sBankDisposeMsgQ; diff --git a/libs/JSystem/include/JSystem/JAudio2/JASWaveInfo.h b/libs/JSystem/include/JSystem/JAudio2/JASWaveInfo.h index f559e86c4c..45874f5aa7 100644 --- a/libs/JSystem/include/JSystem/JAudio2/JASWaveInfo.h +++ b/libs/JSystem/include/JSystem/JAudio2/JASWaveInfo.h @@ -2,6 +2,11 @@ #define JASWAVEINFO_H #include +#include + +#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 getSampleReference() const { return nullptr; } #endif }; diff --git a/libs/JSystem/src/JAudio2/JASBank.cpp b/libs/JSystem/src/JAudio2/JASBank.cpp index 9491204cc7..1dc66b377e 100644 --- a/libs/JSystem/src/JAudio2/JASBank.cpp +++ b/libs/JSystem/src/JAudio2/JASBank.cpp @@ -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); diff --git a/src/dusk/mods/svc/audio_res/audio_res.cpp b/src/dusk/mods/svc/audio_res/audio_res.cpp index 20b3e8a95f..d95aba652a 100644 --- a/src/dusk/mods/svc/audio_res/audio_res.cpp +++ b/src/dusk/mods/svc/audio_res/audio_res.cpp @@ -201,6 +201,10 @@ intptr_t AudioWaveReplacementValue::getWavePtr() const { return 0; } +std::unique_ptr AudioWaveReplacementValue::getSampleReference() const { + return std::make_unique(data); +} + void SampleDataPcm16::be_swap() { for (auto& sample : data) { ::be_swap(sample); diff --git a/src/dusk/mods/svc/audio_res/audio_res.hpp b/src/dusk/mods/svc/audio_res/audio_res.hpp index b336dbeda8..bed4567af8 100644 --- a/src/dusk/mods/svc/audio_res/audio_res.hpp +++ b/src/dusk/mods/svc/audio_res/audio_res.hpp @@ -1,6 +1,7 @@ #pragma once #include +#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 data) : data(std::move(data)) {} + + std::shared_ptr 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 getSampleReference() const override; JASWaveInfo wave_info; std::shared_ptr data;