mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-29 15:23:01 -04:00
Allow audio samples to be played back from anywhere in memory rather than ARAM.
This is accomplished through a new mAramBaseAddress field on the DSP channels, which effectively relocates ARAM for that channel.
This commit is contained in:
@@ -13,6 +13,12 @@ struct JASBasicWaveBank : public JASWaveBank {
|
||||
TWaveHandle() { mHeap = NULL; }
|
||||
virtual intptr_t getWavePtr() const;
|
||||
virtual const JASWaveInfo* getWaveInfo() const { return &mWaveInfo; }
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* @see JASChannel::mAramBaseAddress
|
||||
*/
|
||||
[[nodiscard]] void const* getAramBaseAddress() const override { return nullptr; }
|
||||
#endif
|
||||
bool compareHeap(JASHeap* heap) const { return mHeap == heap;}
|
||||
|
||||
/* 0x04 */ JASWaveInfo mWaveInfo;
|
||||
|
||||
@@ -166,6 +166,18 @@ public:
|
||||
u32 field_0x104;
|
||||
};
|
||||
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* Memory address at which this sound effect should consider ARAM to start.
|
||||
*
|
||||
* By changing this, sound effects can effectively be played back from anywhere in memory,
|
||||
* rather than just the emulated ARAM space.
|
||||
*
|
||||
* If nullptr, the regular emulated ARAM is used.
|
||||
*/
|
||||
void const* mAramBaseAddress;
|
||||
#endif
|
||||
|
||||
static DUSK_GAME_DATA OSMessageQueue sBankDisposeMsgQ;
|
||||
static DUSK_GAME_DATA OSMessage sBankDisposeMsg[16];
|
||||
static DUSK_GAME_DATA OSMessage sBankDisposeList[16];
|
||||
|
||||
@@ -179,6 +179,20 @@ namespace JASDsp {
|
||||
/* 0x130 */ u8 _unused9[0x148 - 0x130];
|
||||
/* 0x148 */ s16 iir_filter_params[8];
|
||||
/* 0x158 */ u8 _unused10[0x180 - 0x158];
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* Memory address at which this sound effect should consider ARAM to start.
|
||||
* This means fields like mWaveAramAddress will be relative to this pointer instead.
|
||||
*
|
||||
* By changing this, sound effects can effectively be played back from anywhere in memory,
|
||||
* rather than just the emulated ARAM space.
|
||||
*
|
||||
* If nullptr, the regular emulated ARAM is used.
|
||||
*/
|
||||
void const* mAramBaseAddress;
|
||||
#endif
|
||||
};
|
||||
|
||||
void boot(void (*)(void*));
|
||||
|
||||
@@ -10,6 +10,12 @@ struct JASSimpleWaveBank : JASWaveBank, JASWaveArc {
|
||||
intptr_t getWavePtr() const;
|
||||
TWaveHandle();
|
||||
const JASWaveInfo* getWaveInfo() const;
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* @see JASChannel::mAramBaseAddress
|
||||
*/
|
||||
[[nodiscard]] void const* getAramBaseAddress() const override { return nullptr; }
|
||||
#endif
|
||||
|
||||
/* 0x04 */ JASWaveInfo mWaveInfo;
|
||||
/* 0x28 */ JASHeap* mHeap;
|
||||
|
||||
@@ -45,6 +45,12 @@ public:
|
||||
virtual ~JASWaveHandle() {}
|
||||
virtual const JASWaveInfo* getWaveInfo() const = 0;
|
||||
virtual intptr_t getWavePtr() const = 0;
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* @see JASChannel::mAramBaseAddress
|
||||
*/
|
||||
[[nodiscard]] virtual void const* getAramBaseAddress() const = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,7 +33,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 (!wavePtr IF_DUSK(&& !waveHandle->getAramBaseAddress())) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,9 @@ JASChannel* JASBank::noteOn(JASBank const* param_0, int param_1, u8 param_2, u8
|
||||
channel->setPriority(param_4);
|
||||
channel->field_0xdc.mWaveInfo = *waveInfo;
|
||||
channel->mWaveAramAddress = wavePtr;
|
||||
#if TARGET_PC
|
||||
channel->mAramBaseAddress = waveHandle->getAramBaseAddress();
|
||||
#endif
|
||||
channel->field_0xdc.mChannelType = stack_60.field_0x1c;
|
||||
channel->setBankDisposeID(param_0);
|
||||
channel->setInitPitch(stack_60.mPitch * (waveInfo->mSampleRate / JASDriver::getDacRate()));
|
||||
|
||||
@@ -26,6 +26,9 @@ JASChannel::JASChannel(Callback i_callback, void* i_callbackData) :
|
||||
mCallback(i_callback),
|
||||
mCallbackData(i_callbackData),
|
||||
mUpdateTimer(0),
|
||||
#if TARGET_PC
|
||||
mAramBaseAddress(nullptr),
|
||||
#endif
|
||||
mBankDisposeID(NULL),
|
||||
mKey(0),
|
||||
mVelocity(0x7f),
|
||||
@@ -256,6 +259,9 @@ s32 JASChannel::initialUpdateDSPChannel(JASDsp::TChannel* i_channel) {
|
||||
switch (field_0xdc.mChannelType) {
|
||||
case 0:
|
||||
i_channel->setWaveInfo(field_0xdc.mWaveInfo, mWaveAramAddress, mSkipSamples);
|
||||
#if TARGET_PC
|
||||
i_channel->mAramBaseAddress = mAramBaseAddress;
|
||||
#endif
|
||||
break;
|
||||
case 2:
|
||||
i_channel->setOscInfo(mOscillatorSomething);
|
||||
|
||||
@@ -317,7 +317,7 @@ void dusk::audio::DspRender(OutputSubframe& subframe) {
|
||||
}
|
||||
|
||||
OutputSubframe channelSubframe = {};
|
||||
if (channel.mWaveAramAddress == 0) {
|
||||
if (channel.mWaveAramAddress == 0 && !channel.mAramBaseAddress) {
|
||||
RenderOscChannel(channel, channelAux, channelSubframe);
|
||||
} else {
|
||||
ValidateChannel(channel);
|
||||
@@ -455,7 +455,8 @@ static int ReadChannelSamplesChunk(
|
||||
|
||||
assert(desiredSamples >= 0);
|
||||
|
||||
auto aramBase = static_cast<u8*>(ARGetStorageAddress()) + channel.mWaveAramAddress;
|
||||
auto aramBase = static_cast<u8 const*>(channel.mAramBaseAddress ? channel.mAramBaseAddress : ARGetStorageAddress());
|
||||
aramBase += channel.mWaveAramAddress;
|
||||
|
||||
auto curSamplePosition = channel.mSamplePosition;
|
||||
u32 skipSamples = curSamplePosition % channel.mSamplesPerBlock;
|
||||
|
||||
Reference in New Issue
Block a user