diff options
| author | Luke Street <luke@street.dev> | 2026-03-01 15:35:36 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-01 14:35:36 -0800 |
| commit | 9649319ec4926457ef85e6094f8207474c977c2d (patch) | |
| tree | 1c5cd4c7cc4c1aee03f28921213da47f2775444d /libs/JSystem/src/JAudio2/JASTrack.cpp | |
| parent | 6e149819e13b1f70ecbf8a4c66b030c17ffed2bb (diff) | |
Reorganize library code into `libs/` (#3119)
* Reorganize files into libs/{dolphin,JSystem,PowerPC_EABI_Support,revolution,TRK_MINNOW_DOLPHIN}
* Update configure.py and project.py for new libs structure
* Refactor `#include <dolphin/x.h>` -> `<x.h>`
* Remove `__REVOLUTION_SDK__` forwards from dolphin
* Fix dolphin/ references in revolution
* Wrap `#include <dolphin.h>` in `!__REVOLUTION_SDK__`
* Always build TRK against dolphin headers
* Resolve revolution SDK header resolution issues
Diffstat (limited to 'libs/JSystem/src/JAudio2/JASTrack.cpp')
| -rw-r--r-- | libs/JSystem/src/JAudio2/JASTrack.cpp | 878 |
1 files changed, 878 insertions, 0 deletions
diff --git a/libs/JSystem/src/JAudio2/JASTrack.cpp b/libs/JSystem/src/JAudio2/JASTrack.cpp new file mode 100644 index 0000000000..eec0ebd644 --- /dev/null +++ b/libs/JSystem/src/JAudio2/JASTrack.cpp @@ -0,0 +1,878 @@ +#include "JSystem/JSystem.h" // IWYU pragma: keep + +#include "JSystem/JAudio2/JASTrack.h" +#include "JSystem/JAudio2/JASCriticalSection.h" +#include "JSystem/JAudio2/JASDriverIF.h" +#include "JSystem/JAudio2/JASBank.h" +#include "JSystem/JAudio2/JASAiCtrl.h" +#include "JSystem/JAudio2/JASDSPInterface.h" + +JASTrack::JASTrack() : mDefaultChannelMgr(this), mChannelMgrCount(1), mStatus(0) { + mChannelMgrs[0] = &mDefaultChannelMgr; + for (int i = 1; i < 4; i++) { + mChannelMgrs[i] = NULL; + } + init(); +} + +JASDefaultBankTable JASTrack::sDefaultBankTable; + +JASTrack::TList JASTrack::sTrackList; + +// NONMATCHING JASPoolAllocObject_MultiThreaded<_> locations +JASTrack::~JASTrack() { + JUT_ASSERT(70, mStatus != STATUS_RUN); + for (int i = 1; i < 4; i++) { + delete mChannelMgrs[i]; + } +} + +// NONMATCHING JASPoolAllocObject_MultiThreaded<_> locations +void JASTrack::setChannelMgrCount(u32 count) { + JUT_ASSERT(79, mStatus != STATUS_RUN); + JUT_ASSERT(80, count >= 1 && count <= CHANNEL_MGR_MAX); + mChannelMgrCount = 1; + for (int i = 1; i < count; i++) { + if (mChannelMgrs[i] == NULL) { + mChannelMgrs[i] = new TChannelMgr(this); + if (mChannelMgrs[i] == NULL) { + JUT_WARN(87, "%s", "Not enough JASTrackChannelMgr\n"); + return; + } + } + mChannelMgrCount++; + } + for (u32 i = mChannelMgrCount; i < 4; i++) { + if (mChannelMgrs[i] != NULL) { + delete mChannelMgrs[i]; + mChannelMgrs[i] = NULL; + } + } +} + +JASOscillator::Point const JASTrack::sAdsTable[4] = { + {0, 0, 0x7fff}, + {0, 0, 0x7fff}, + {0, 0, 0}, + {0xe, 0, 0}, +}; + +JASOscillator::Data const JASTrack::sEnvOsc = {0, 1.0f, NULL, NULL, 1.0f, 0.0f}; + +JASOscillator::Data const JASTrack::sPitchEnvOsc = {1, 1.0f, NULL, NULL, 1.0f, 0.0f}; + +// NONMATCHING JASPoolAllocObject_MultiThreaded<_> locations +void JASTrack::init() { + JUT_ASSERT(104, mStatus == STATUS_FREE || mStatus == STATUS_STOPPED); + mSeqCtrl.init(); + mTrackPort.init(); + initTimed(); + mRegisterParam.init(); + mOscParam[0] = sEnvOsc; + mOscParam[1] = sPitchEnvOsc; + for (int i = 0; i < 4; i++) { + mOscPoint[i] = sAdsTable[i]; + } + mParent = NULL; + for (int i = 0; i < 16; i++) { + mChildren[i] = NULL; + } + mChannelMgrs[0]->init(); + mChannelMgrCount = 1; + for (int i = 1; i < 4; i++) { + if (mChannelMgrs[i] != NULL) { + delete mChannelMgrs[i]; + mChannelMgrs[i] = NULL; + } + } + mBankTable = &sDefaultBankTable; + field_0x1d8 = 1.0f; + field_0x1dc = 1.0f; + mVibDepth = 0.0f; + mVibPitch = 1.0f; + mTremDepth = 0.0f; + mTremPitch = 1.0f; + mVibDelay = 0; + mTremDelay = 0; + mPanPower = 1.0f; + mDirectRelease = 0; + mSkipSample = 0; + mTempo = 120; + mTimebase = 0x30; + mTempoRate = 1.0f; + updateTempo(); + mTranspose = 0; + field_0x22b = 60; + mBankNumber = 0; + mProgNumber = 0xf0; + mBendSense = 0xc; + mNoteOnPrio = 0x40; + mReleasePrio = 0; + mGateRate = 100; + mMixConfig[0] = 0x150; + mMixConfig[1] = 0x210; + mMixConfig[2] = 0x352; + mMixConfig[3] = 0x412; + mMixConfig[4] = 0; + mMixConfig[5] = 0; + for (int i = 0; i < 8; i++) { + mFIR[i] = 0; + } + mFIR[0] = 0x7fff; + for (int i = 0; i < 8; i++) { + mIIR[i] = 0; + } + mIIR[0] = 0x7fff; + mFilterMode = 0; + mFlags.pause = false; + mFlags.mute = false; + mFlags.flag2 = true; + mFlags.flag5 = true; + mFlags.autoDelete = false; + mFlags.flag4 = false; + mFlags.flag6 = false; + mStatus = STATUS_FREE; +} + +void JASTrack::initTimed() { + mMoveParam.params.volume.mValue = 1.0f; + mMoveParam.params.pitch.mValue = 0.0f; + mMoveParam.params.pan.mValue = 0.5f; + mMoveParam.params.fxmix.mValue = 0.0f; + mMoveParam.params.dolby.mValue = 0.0f; + mMoveParam.params.distFilter.mValue = 0.0f; + for (int i = 0; i < 6; i++) { + mMoveParam.array[i].mCount = 0; + mMoveParam.array[i].mTarget = mMoveParam.array[i].mValue; + } +} + +void JASTrack::inherit(JASTrack const& i_parent) { + mFlags.flag2 = i_parent.mFlags.flag2; + mBankNumber = i_parent.mBankNumber; + mProgNumber = i_parent.mProgNumber; + mNoteOnPrio = i_parent.mNoteOnPrio; + mReleasePrio = i_parent.mReleasePrio; + mSkipSample = i_parent.mSkipSample; + for (int i = 0; i < 8; i++) { + mFIR[i] = i_parent.mFIR[i]; + } + for (int i = 0; i < 8; i++) { + mIIR[i] = i_parent.mIIR[i]; + } + mFilterMode = i_parent.mFilterMode; + for (int i = 0; i < 6; i++) { + mMixConfig[i] = i_parent.mMixConfig[i]; + } +} + +void JASTrack::assignExtBuffer(u32 index, JASSoundParams* i_soundParams) { + JUT_ASSERT(249, index < mChannelMgrCount); + mChannelMgrs[index]->mSoundParams = i_soundParams; +} + +void JASTrack::setSeqData(void* param_0, u32 param_1) { + JUT_ASSERT(257, mStatus == STATUS_FREE); + mSeqCtrl.start(param_0, param_1); +} + +void JASTrack::startSeq() { + JUT_ASSERT(265, mParent == 0); + JUT_ASSERT(266, mStatus == STATUS_FREE); + JASCriticalSection critical_section; + sTrackList.append(this); + mStatus = STATUS_RUN; +} + +void JASTrack::stopSeq() { + JASCriticalSection critical_section; + mFlags.flag6 = 1; +} + +void JASTrack::start() { + JUT_ASSERT(289, mParent != NULL); + JUT_ASSERT(290, mStatus == STATUS_FREE); + mStatus = STATUS_RUN; +} + +void JASTrack::close() { + for (int i = 0; i < 16; i++) { + JASTrack* child = mChildren[i]; + if (child != NULL) { + child->close(); + if (child->mFlags.autoDelete) { + delete child; + mChildren[i] = NULL; + } + } + } + for (u32 i = 0; i < mChannelMgrCount; i++) { + if (mChannelMgrs[i] != NULL) { + mChannelMgrs[i]->releaseAll(); + } + } + mParent = NULL; + mStatus = STATUS_STOPPED; +} + +bool JASTrack::connectChild(u32 track_no, JASTrack* i_child) { + JUT_ASSERT(326, track_no < MAX_CHILDREN); + if (mChildren[track_no] != NULL) { + return false; + } + i_child->mParent = this; + mChildren[track_no] = i_child; + return true; +} + +void JASTrack::closeChild(u32 track_no) { + JUT_ASSERT(340, track_no < MAX_CHILDREN); + JASTrack* child = mChildren[track_no]; + if (child != NULL) { + getRootTrack()->updateSeq(false, 1.0f); + child->close(); + if (child->mFlags.autoDelete) { + delete child; + mChildren[track_no] = NULL; + } + } +} + +// NONMATCHING JASPoolAllocObject_MultiThreaded<_> locations +JASTrack* JASTrack::openChild(u32 trk_no) { + JUT_ASSERT(358, trk_no < MAX_CHILDREN); + JASTrack* child = mChildren[trk_no]; + if (child != NULL) { + switch (child->mStatus) { + case STATUS_FREE: + break; + case STATUS_RUN: + getRootTrack()->updateSeq(false, 1.0f); + child->close(); + // no break + case STATUS_STOPPED: + bool auto_delete = child->mFlags.autoDelete; + child->init(); + child->mFlags.autoDelete = auto_delete; + mChildren[trk_no] = NULL; + connectChild(trk_no, child); + break; + } + } else { + child = new JASTrack(); + if (child == NULL) { + JUT_WARN(388, "%s", "Not enough JASTrack\n"); + return NULL; + } + child->mFlags.autoDelete = true; + connectChild(trk_no, child); + } + child->setChannelMgrCount(mChannelMgrCount); + child->inherit(*this); + return child; +} + +void JASTrack::connectBus(int line, int param_1) { + JUT_ASSERT(404, line < JASChannel::BUSOUT_CPUCH); + mMixConfig[line] = param_1; +} + +f32 JASTrack::getVolume() const { return mMoveParam.params.volume.mValue; } +f32 JASTrack::getPitch() const { return mMoveParam.params.pitch.mValue; } +f32 JASTrack::getPan() const { return mMoveParam.params.pan.mValue; } +f32 JASTrack::getFxmix() const { return mMoveParam.params.fxmix.mValue; } +f32 JASTrack::getDolby() const { return mMoveParam.params.dolby.mValue; } + +void JASTrack::setLatestKey(u8 param_0) { + field_0x22b = param_0; + field_0x22b += getTransposeTotal(); +} + +JASChannel* JASTrack::channelStart(JASTrack::TChannelMgr* i_channelMgr, u32 param_1, u32 param_2, + u32 i_updateTimer) { + JASBank* bank = NULL; + if (mBankTable != NULL) { + bank = mBankTable->getBank(mBankNumber); + } + JASChannel* channel = JASBank::noteOn(bank, mProgNumber, param_1, param_2, + mNoteOnPrio | mReleasePrio << 8, + channelUpdateCallback, i_channelMgr); + if (channel == NULL) { + return NULL; + } + channel->setUpdateTimer(i_updateTimer); + channel->setSkipSamples(mSkipSample); + channel->setVibrateDelay(mVibDelay); + channel->setTremoloDelay(mTremDelay); + channel->setParams(i_channelMgr->mParams); + for (u32 i = 0; i < 6; i++) { + channel->setMixConfig(i, mMixConfig[i]); + } + overwriteOsc(channel); + if (mDirectRelease != 0) { + channel->setDirectRelease(mDirectRelease); + } + return channel; +} + +int JASTrack::noteOn(u32 noteid, u32 param_1, u32 param_2) { + JUT_ASSERT(486, noteid != 0 && noteid < TChannelMgr::CHANNEL_MAX); + if (isMute()) { + return 0; + } + int ret = 1; + param_1 += getTransposeTotal(); + for (u32 i = 0; i < mChannelMgrCount; i++) { + if (mChannelMgrs[i] != NULL) { + mChannelMgrs[i]->noteOff(noteid, 0); + JASChannel* channel = channelStart(mChannelMgrs[i], param_1, param_2, 0); + if (channel == NULL) { + ret = 0; + } + mChannelMgrs[i]->mChannels[noteid] = channel; + } + } + return ret; +} + +int JASTrack::gateOn(u32 param_0, u32 i_velocity, f32 i_time, u32 i_flags) { + bool result = true; + param_0 += getTransposeTotal(); + if (mGateRate != 100) { + i_time *= mGateRate / 100.0f; + } + u32 uvar2 = seqTimeToDspTime(i_time); + u32 update_timer = (i_flags & 6) ? 0 : uvar2; + int uvar7 = i_flags & 1 ? field_0x22b : param_0; + for (u32 i = 0; i < mChannelMgrCount; i++) { + TChannelMgr* channel_mgr = mChannelMgrs[i]; + if (channel_mgr != NULL) { + if (!mFlags.flag4) { + channel_mgr->noteOff(0, 0); + if (!isMute()) { + channel_mgr->mChannels[0] = + channelStart(channel_mgr, uvar7, i_velocity, update_timer); + } + } else { + JASChannel* channel = channel_mgr->mChannels[0]; + if (channel != NULL) { + channel->setKey(uvar7 - channel->field_0xdc.field_0x4.field_0x01); + channel->setVelocity(i_velocity); + channel->setUpdateTimer(update_timer); + } + } + if (i_flags & 1) { + JASChannel* channel = channel_mgr->mChannels[0]; + if (channel != NULL) { + channel->setKeySweepTarget(param_0 - uvar7, uvar2); + } + } + } + } + mFlags.flag4 = (i_flags & 2) ? true : false; + field_0x22b = param_0; + return result; +} + +int JASTrack::noteOff(u32 noteid, u16 param_1) { + JUT_ASSERT(563, noteid < TChannelMgr::CHANNEL_MAX); + int ret = 1; + for (u32 i = 0; i < mChannelMgrCount; i++) { + if (mChannelMgrs[i] != NULL) { + if (!mChannelMgrs[i]->noteOff(noteid, param_1)) { + ret = 0; + } + } + } + return ret; +} + +bool JASTrack::checkNoteStop(u32 noteid) const { + JUT_ASSERT(581, noteid < TChannelMgr::CHANNEL_MAX); + for (u32 i = 0; i < mChannelMgrCount; i++) { + if (mChannelMgrs[i] != NULL) { + JASChannel* channel = mChannelMgrs[i]->mChannels[noteid]; + if (channel != NULL) { + return false; + } + } + } + return true; +} + +void JASTrack::overwriteOsc(JASChannel* i_channel) { + for (u32 i = 0; i < 2; i++) { + if (mOscParam[i].mTable != NULL) { + JUT_ASSERT(599, mOscParam[i].rel_table == 0); + i_channel->setOscInit(i, &mOscParam[i]); + } + } +} + +void JASTrack::updateTimedParam() { + for (int i = 0; i < 6; i++) { + MoveParam_* param = &mMoveParam.array[i]; + if (param->mCount != 0) { + param->mValue += (param->mTarget - param->mValue) / param->mCount; + param->mCount--; + } + } +} + +void JASTrack::updateTrack(f32 param_0) { + updateTempo(); + for (u32 i = 0; i < mChannelMgrCount; i++) { + TChannelMgr* channel_mgr = mChannelMgrs[i]; + if (channel_mgr != NULL) { + f32 volume = mMoveParam.params.volume.mValue; + volume = volume * volume; + f32 pitch = 1.0f; + f32 fvar6 = mMoveParam.params.pitch.mValue * mBendSense * (1.0f / 3.0f); + f32 pan = (mMoveParam.params.pan.mValue - 0.5f) * mPanPower; + f32 fxmix = mMoveParam.params.fxmix.mValue; + f32 dolby = mMoveParam.params.dolby.mValue; + if (channel_mgr->mSoundParams != NULL) { + volume *= channel_mgr->mSoundParams->mVolume; + pitch *= channel_mgr->mSoundParams->mPitch; + pan += channel_mgr->mSoundParams->mPan - 0.5f; + fxmix += channel_mgr->mSoundParams->mFxMix; + dolby += channel_mgr->mSoundParams->mDolby; + } + pan *= param_0; + if (mParent == NULL) { + channel_mgr->mParams.mVolume = volume; + channel_mgr->mParams.mPitch = pitch; + channel_mgr->mParams.mPan = pan; + channel_mgr->mParams.mFxMix = fxmix; + channel_mgr->mParams.mDolby = dolby; + channel_mgr->mParams.field_0x8 = fvar6; + } else { + TChannelMgr* parent_channel_mgr = mParent->mChannelMgrs[i]; + if (parent_channel_mgr == NULL) { + parent_channel_mgr = mParent->mChannelMgrs[0]; + } + channel_mgr->mParams.mVolume = parent_channel_mgr->mParams.mVolume * volume; + channel_mgr->mParams.mPitch = parent_channel_mgr->mParams.mPitch * pitch; + channel_mgr->mParams.mPan = (parent_channel_mgr->mParams.mPan - 0.5f) + pan; + channel_mgr->mParams.mFxMix = parent_channel_mgr->mParams.mFxMix + fxmix; + channel_mgr->mParams.mDolby = parent_channel_mgr->mParams.mDolby + dolby; + channel_mgr->mParams.field_0x8 = parent_channel_mgr->mParams.field_0x8 + fvar6; + } + channel_mgr->mParams.mPan += 0.5f; + } + } +} + +void JASTrack::updateTempo() { + if (mParent == NULL) { + field_0x1dc = mTempoRate * (mTimebase * mTempo * (4.0f / 3.0f) / JASDriver::getDacRate()); + } else { + mTempo = mParent->mTempo; + mTimebase = mParent->mTimebase; + field_0x1dc = mParent->field_0x1dc; + } +} + +void JASTrack::updateSeq(bool param_0, f32 param_1) { + if (!param_0) { + param_0 = mFlags.flag5; + } + mFlags.flag5 = false; + if (param_0) { + updateTrack(param_1); + } + f32 fvar1 = param_1 * mPanPower; + for (int i = 0; i < 16; i++) { + JASTrack* child = mChildren[i]; + if (child != NULL && child->mStatus == STATUS_RUN) { + child->updateSeq(param_0, fvar1); + } + } +} + +u32 JASTrack::seqTimeToDspTime(f32 i_seqTime) { + if (mFlags.flag2) { + i_seqTime = i_seqTime / field_0x1dc; + } else { + i_seqTime = i_seqTime * (120.0f / mTimebase); + i_seqTime *= JASDriver::getSubFrames() / 10.0f; + } + return i_seqTime; +} + +void JASTrack::setParam(u32 target, f32 i_target, u32 i_count) { + JUT_ASSERT(739, target < TIMED_PARAMS); + MoveParam_* param = &mMoveParam.array[target]; + param->mTarget = i_target; + if (i_count == 0) { + param->mValue = param->mTarget; + } + param->mCount = i_count; +} + +void JASTrack::noteOffAll(u16 param_0) { + for (u8 i = 0; i < 8; i++) { + noteOff(i, param_0); + } + for (int i = 0; i < 16; i++) { + JASTrack* child = mChildren[i]; + if (child != NULL && child->mStatus == STATUS_RUN) { + child->noteOffAll(param_0); + } + } +} + +void JASTrack::mute(bool i_mute) { + mFlags.mute = i_mute; + if (i_mute) { + noteOffAll(10); + } +} + +void JASTrack::setOscScale(u32 osc_no, f32 i_scale) { + JUT_ASSERT(792, osc_no < OSC_NUM); + mOscParam[osc_no].mScale = i_scale; +} + +void JASTrack::setOscTable(u32 osc_no, JASOscillator::Point const* i_table) { + JUT_ASSERT(799, osc_no < OSC_NUM) + mOscParam[osc_no].mTable = i_table; + if (osc_no != 0) { + mOscParam[osc_no].rel_table = NULL; + } +} + +void JASTrack::setOscAdsr(s16 param_0, s16 param_1, s16 param_2, s16 param_3, u16 i_directRelease) { + mOscParam[0] = sEnvOsc; + mOscParam[0].mTable = mOscPoint; + mOscPoint[0]._2 = param_0; + mOscPoint[1]._2 = param_1; + mOscPoint[2]._2 = param_2; + mOscPoint[2]._4 = param_3; + mDirectRelease = i_directRelease; +} + +const u32 JASDsp::FILTER_MODE_IIR = 0x00000020; + +void JASTrack::setFIR(s16 const* i_FIR) { + for (int i = 0; i < 8; i++) { + mFIR[i] = i_FIR[i]; + } + mFilterMode &= JASDsp::FILTER_MODE_IIR; + mFilterMode |= 8; +} + +void JASTrack::setIIR(s16 const* i_IIR) { + for (int i = 0; i < 8; i++) { + mIIR[i] = i_IIR[i]; + } + mFilterMode |= JASDsp::FILTER_MODE_IIR; +} + +u16 JASTrack::readPortSelf(u32 param_0) { + return mTrackPort.readImport(param_0); +} + +void JASTrack::writePortSelf(u32 param_0, u16 param_1) { + mTrackPort.writeExport(param_0, param_1); +} + +void JASTrack::writePort(u32 param_0, u16 param_1) { + JASSeqCtrl::IntrType intr; + mTrackPort.writeImport(param_0, param_1); + if (param_0 == 0 || param_0 == 1) { + if (param_0 == 0) { + intr = JASSeqCtrl::INTRTYPE_VALUE_2; + } else { + intr = JASSeqCtrl::INTRTYPE_VALUE_3; + } + mSeqCtrl.interrupt(intr); + } +} + +u16 JASTrack::readPort(u32 param_0) { + return mTrackPort.readExport(param_0); +} + +void JASTrack::setChannelPauseFlag(bool i_pause) { + for (u32 i = 0; i < mChannelMgrCount; i++) { + TChannelMgr* mgr = mChannelMgrs[i]; + if (mgr != NULL) { + mgr->setPauseFlag(i_pause); + } + } + for (int i = 0; i < 16; i++) { + JASTrack* child = mChildren[i]; + if (child != NULL) { + child->setChannelPauseFlag(i_pause); + } + } +} + +void JASTrack::pause(bool i_pause) { + if (mFlags.pause != i_pause) { + mFlags.pause = i_pause; + setChannelPauseFlag(i_pause); + mSeqCtrl.interrupt(i_pause ? JASSeqCtrl::INTRTYPE_VALUE_0 : JASSeqCtrl::INTRTYPE_VALUE_1); + } +} + +int JASTrack::getTransposeTotal() const { + if (mParent != NULL) { + return mTranspose + mParent->getTransposeTotal(); + } else { + return mTranspose; + } +} + +bool JASTrack::isMute() const { + if (mParent != NULL) { + return mFlags.mute || mParent->isMute(); + } else { + return mFlags.mute; + } +} + +void JASTrack::setTempo(u16 i_tempo) { + JUT_ASSERT(961, mParent == 0); + mTempo = i_tempo; + mFlags.flag5 = true; + updateTempo(); +} + +void JASTrack::setTempoRate(f32 i_tempoRate) { + JUT_ASSERT(969, mParent == 0); + mTempoRate = i_tempoRate; + mFlags.flag5 = true; + updateTempo(); +} + +void JASTrack::setTimebase(u16 i_timebase) { + JUT_ASSERT(977, mParent == 0); + mTimebase = i_timebase; + mFlags.flag5 = true; + updateTempo(); +} + +void JASTrack::updateChannel(JASChannel* param_0, JASDsp::TChannel* param_1) { + param_0->setVibrate(mVibDepth, mVibPitch); + param_0->setTremolo(mTremDepth, mTremPitch); + if (mFilterMode & 0x20) { + param_1->setIIRFilterParam(mIIR); + } + if (mFilterMode & 0x1f) { + param_1->setFIR8FilterParam(mFIR); + } + param_1->setFilterMode(mFilterMode); + param_1->setDistFilter(mMoveParam.params.distFilter.mValue * 32767.0f); +} + + +void JASTrack::channelUpdateCallback(u32 param_0, JASChannel* param_1, + JASDsp::TChannel* param_2, void* param_3) { + TChannelMgr* channel_mgr = static_cast<TChannelMgr*>(param_3); + JASTrack* track = channel_mgr->mTrack; + switch (param_0) { + case 0: + case 1: + param_1->setParams(channel_mgr->mParams); + track->updateChannel(param_1, param_2); + break; + case 3: + param_1->release(0); + param_1->free(); + channel_mgr->mChannels[0] = NULL; + break; + case 2: + for (int i = 0; i < 8; i++) { + if (param_1 == channel_mgr->mChannels[i]) { + channel_mgr->mChannels[i] = NULL; + break; + } + } + break; + } +} + +int JASTrack::getChannelCount() const { + JASCriticalSection cs; + int count = 0; + for (int i = 0; i < mChannelMgrCount; i++) { + if (mChannelMgrs[i]) { + for (int j = 0; j < 8; j++) { + if (mChannelMgrs[i]->mChannels[j]) { + count++; + } + } + } + } + return count; +} + +JASTrack* JASTrack::getRootTrack() { + JASTrack* track = this; + while (track->mParent != NULL) { + track = track->mParent; + } + return track; +} + +int JASTrack::tickProc() { + if (mFlags.pause) { + return 0; + } + int ret = mSeqCtrl.tickProc(this); + updateTimedParam(); + mFlags.flag5 = true; + if (ret < 0) { + return -1; + } + for (int i = 0; i < 16; i++) { + JASTrack* child = mChildren[i]; + if (child != NULL && child->mStatus == STATUS_RUN) { + JUT_ASSERT(1090, this == child->mParent); + ret = child->tickProc(); + if (ret < 0) { + getRootTrack()->updateSeq(false, 1.0f); + child->close(); + if (child->mFlags.autoDelete) { + delete child; + mChildren[i] = NULL; + } + } + } + } + return 0; +} + +int JASTrack::seqMain() { + JUT_ASSERT(1108, mStatus == STATUS_RUN); + if (mFlags.flag6) { + updateSeq(true, 1.0f); + close(); + return -1; + } else { + while (field_0x1d8 >= 1.0f) { + field_0x1d8 -= 1.0f; + int ret = tickProc(); + if (ret < 0) { + updateSeq(false, 1.0f); + close(); + return -1; + } + } + field_0x1d8 += field_0x1dc; + updateSeq(false, 1.0f); + return 0; + } +} + +s32 JASTrack::TList::cbSeqMain(void* i_this) { + JASTrack::TList* list = static_cast<JASTrack::TList*>(i_this); + list->seqMain(); + return 0; +} + +void JASTrack::TList::append(JASTrack* i_track) { + if (!mCallbackRegistered) { + if (!JASDriver::registerSubFrameCallback(cbSeqMain, this)) { + JUT_WARN(1157, "%s", "Failed: registerSubFrameCallback"); + return; + } + mCallbackRegistered = true; + } + Push_back(i_track); +} + +void JASTrack::TList::seqMain() { +#if DEBUG + iterator it, it2; + for (it = begin(); it != end(); it = it2) { + it2 = it; + ++it2; + int seqMainRes = it->seqMain(); + if (seqMainRes < 0) { + Remove(&*it); + if (it->mFlags.autoDelete) { + delete &*it; + } + } + } +#else + iterator it; + for (it = begin(); it != end();) { + // Fakematch: Debug shows that it2 should be declared outside the loop and then this line + // should use operator=, but that results in a missing load instruction for retail, so we + // use the copy constructor instead of the assignment operator, which fixes it for some + // reason. Might be related to the fakematch in the assignment operator? + iterator it2 = it; + ++it2; + int seqMainRes = it->seqMain(); + if (seqMainRes < 0) { + Remove(&*it); + if (it->mFlags.autoDelete) { + delete &*it; + } + } + it = it2; + } +#endif +} + +JASTrack::TChannelMgr::TChannelMgr(JASTrack* i_track) : mSoundParams(NULL), mTrack(i_track) { + for (int i = 0; i < 8; i++) { + mChannels[i] = NULL; + } + for (int i = 0; i < 8; i++) { + field_0x38[i] = 0; + } +} + + +void JASTrack::TChannelMgr::init() { + mSoundParams = NULL; + mParams.init(); + for (int i = 0; i < 8; i++) { + mChannels[i] = NULL; + } + for (int i = 0; i < 8; i++) { + field_0x38[i] = 0; + } +} + + +void JASTrack::TChannelMgr::releaseAll() { + for (int i = 0; i < 8; i++) { + JASChannel* channel = mChannels[i]; + if (channel != NULL) { + channel->release(0); + channel->free(); + mChannels[i] = NULL; + } + } +} + +bool JASTrack::TChannelMgr::noteOff(u32 noteid, u16 param_1) { + JUT_ASSERT(1224, noteid < CHANNEL_MAX); + JASChannel* channel = mChannels[noteid]; + if (channel == NULL) { + return false; + } + if (param_1 == 0) { + channel->release(0); + } else { + channel->release(param_1); + } + channel->free(); + mChannels[noteid] = NULL; + return true; +} + +void JASTrack::TChannelMgr::setPauseFlag(bool i_pause) { + for (int i = 0; i < 8; i++) { + JASChannel* channel = mChannels[i]; + if (channel != NULL) { + channel->setPauseFlag(i_pause); + } + } +} |
