Files
tww/src/JSystem/JAudio/JASChannel.cpp
T
2025-03-15 19:55:45 -04:00

868 lines
27 KiB
C++

//
// Generated by dtk
// Translation Unit: JASChannel.cpp
//
#include "JSystem/JAudio/JASChannel.h"
#include "JSystem/JAudio/JASCalc.h"
#include "JSystem/JAudio/JASChAllocQueue.h"
#include "JSystem/JAudio/JASChGlobal.h"
#include "JSystem/JAudio/JASChannelMgr.h"
#include "JSystem/JAudio/JASDSPChannel.h"
#include "JSystem/JAudio/JASDSPInterface.h"
#include "JSystem/JAudio/JASDriverTables.h"
#include "JSystem/JAudio/JASDriverIF.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "dolphin/types.h"
namespace JASystem {
enum CalcSource {
CALC_Sound = 0,
CALC_Effect = 1,
CALC_Channel = 2,
};
enum CalcStyle {
CALC_NONE = 0, // don't add that component
CALC_ADD = 1, // simply add that component
CALC_WEIGHT = 2, // add component weighted by power
};
u8 Driver::calc_sw_table[27][3] = {
// sound, effect, channel
{ CALC_NONE, CALC_NONE, CALC_NONE }, // 0, null
{ CALC_NONE, CALC_NONE, CALC_ADD }, // 1, add only channel
{ CALC_NONE, CALC_NONE, CALC_ADD }, // 2, add only channel
{ CALC_NONE, CALC_ADD, CALC_NONE }, // 3, add only effect
{ CALC_NONE, CALC_ADD, CALC_ADD }, // 4, add effect and channel
{ CALC_NONE, CALC_ADD, CALC_WEIGHT }, // 5, add effect, weight channel
{ CALC_NONE, CALC_ADD, CALC_NONE }, // 6, add only effect
{ CALC_NONE, CALC_WEIGHT, CALC_ADD }, // 7, weight effect, add channel
{ CALC_NONE, CALC_WEIGHT, CALC_WEIGHT }, // 8, weight effect and channel
{ CALC_ADD, CALC_NONE, CALC_NONE }, // 9, add only sound
{ CALC_ADD, CALC_NONE, CALC_ADD }, // 10, add sound and channel
{ CALC_ADD, CALC_NONE, CALC_WEIGHT }, // 11, add sound, weight channel
{ CALC_ADD, CALC_ADD, CALC_NONE }, // 12, add sound and effect
{ CALC_ADD, CALC_ADD, CALC_ADD }, // 13, add all
{ CALC_ADD, CALC_ADD, CALC_WEIGHT }, // 14, add sound and effect, weight channel
{ CALC_ADD, CALC_WEIGHT, CALC_NONE }, // 15, add sound, weight effect
{ CALC_ADD, CALC_WEIGHT, CALC_ADD }, // 16, add sound and channel, weight effect
{ CALC_ADD, CALC_WEIGHT, CALC_WEIGHT }, // 17, add sound, weight effect and channel
{ CALC_ADD, CALC_NONE, CALC_NONE }, // 18, add only sound
{ CALC_WEIGHT, CALC_NONE, CALC_ADD }, // 19, weight sound, add channel
{ CALC_WEIGHT, CALC_NONE, CALC_WEIGHT }, // 20, weight sound and channel
{ CALC_WEIGHT, CALC_ADD, CALC_NONE }, // 21, weight sound, add effect
{ CALC_WEIGHT, CALC_ADD, CALC_ADD }, // 22, weight sound, add effect and channel
{ CALC_WEIGHT, CALC_ADD, CALC_WEIGHT }, // 23, weight sound and channel, weight effect
{ CALC_WEIGHT, CALC_WEIGHT, CALC_NONE }, // 24, weight sound and effect
{ CALC_WEIGHT, CALC_WEIGHT, CALC_ADD }, // 25, weight sound and effect, add channel
{ CALC_WEIGHT, CALC_WEIGHT, CALC_WEIGHT }, // 26, weight all
};
/* 8028B3E8-8028B5A4 .text init__Q28JASystem8TChannelFv */
void TChannel::init() {
field_0x28 = NULL;
field_0x2c = NULL;
field_0x30 = 0;
field_0x34 = 0;
field_0x10 = NULL;
field_0xc = 0;
field_0x14 = 0;
field_0x18 = 0;
field_0x1c = 0;
field_0xd4 = 0;
if (!field_0x4) {
mMixConfigs[0].mWhole = 0x150;
mMixConfigs[1].mWhole = 0x210;
mMixConfigs[2].mWhole = 0x352;
mMixConfigs[3].mWhole = 0x412;
mMixConfigs[4].mWhole = 0;
mMixConfigs[5].mWhole = 0;
field_0x48 = 0x10101;
field_0x4c = 600;
mCalcTypes[0] = CALC_WeightAll; // Pan
mCalcTypes[1] = CALC_AddChannelOnly; // FxMix
mCalcTypes[2] = CALC_AddChannelOnly;
} else {
for (int i = 0; i < 6; i++) {
mMixConfigs[i].mWhole = field_0x4->field_0x4e[i];
}
field_0x48 = field_0x4->field_0x68;
field_0x4c = field_0x4->field_0x6c;
for (int i = 0; i < 3; i++) {
mCalcTypes[i] = field_0x4->mCalcTypes[i];
}
}
for (u32 i = 0; i < 4; i++) {
JUT_ASSERT(155, osc[i]);
osc[i]->setOsc(NULL);
osc[i]->init();
}
mPauseFlag = 0;
field_0xc8++;
if (s32(field_0xc8) == 0) {
field_0xc8 = 1;
}
field_0xe8 = 0;
}
/* 8028B5A4-8028B620 .text setOscillator__Q28JASystem8TChannelFUlPQ28JASystem11TOscillator */
void TChannel::setOscillator(u32 oscnum, TOscillator* param_2) {
JUT_ASSERT(173, oscnum < (4));
osc[oscnum] = param_2;
}
/* 8028B620-8028B6A8 .text setOscInit__Q28JASystem8TChannelFUlPCQ38JASystem11TOscillator4Osc_ */
void TChannel::setOscInit(u32 oscnum, const TOscillator::Osc_* param_2) {
JUT_ASSERT(183, oscnum < (4));
osc[oscnum]->setOsc(param_2);
osc[oscnum]->initStart();
}
/* 8028B6A8-8028B73C .text forceStopOsc__Q28JASystem8TChannelFUl */
bool TChannel::forceStopOsc(u32 numosc) {
JUT_ASSERT(195, numosc < (4));
return osc[numosc]->isOsc() ? osc[numosc]->forceStop() : false;
}
/* 8028B73C-8028B7D0 .text releaseOsc__Q28JASystem8TChannelFUl */
bool TChannel::releaseOsc(u32 numosc) {
JUT_ASSERT(209, numosc < (4));
return osc[numosc]->isOsc() ? osc[numosc]->release() : false;
}
/* 8028B7D0-8028B850 .text directReleaseOsc__Q28JASystem8TChannelFUlUs */
void TChannel::directReleaseOsc(u32 oscnum, u16 param_2) {
JUT_ASSERT(224, oscnum < (4));
osc[oscnum]->releaseDirect(param_2);
}
/* 8028B850-8028B8E4 .text bankOscToOfs__Q28JASystem8TChannelFUl */
f32 TChannel::bankOscToOfs(u32 oscnum) {
JUT_ASSERT(234, oscnum < (4));
// Probably uses inline JASystem::TOscillator::bankOscToOfs
return osc[oscnum]->isOsc() ? osc[oscnum]->getOffset() : 1.0f;
}
/* 8028B8E4-8028BA98 .text effectOsc__Q28JASystem8TChannelFUlf */
void TChannel::effectOsc(u32 oscnum, f32 effect) {
JUT_ASSERT(246, oscnum < (4));
switch (osc[oscnum]->getOsc()->field_0x0) {
case 1:
field_0x94 *= effect;
break;
case 0:
field_0x98 *= effect;
break;
case 2:
effect -= 0.5; // Must be double literal to match
mPanVec.mEffect += effect;
mPanVec.mEffect = Driver::Clamp01(mPanVec.mEffect);
break;
case 3:
mFxmixVec.mEffect += effect;
mFxmixVec.mEffect = Driver::Clamp01(mFxmixVec.mEffect);
break;
case 4:
mDolbyVec.mEffect += effect;
mDolbyVec.mEffect = Driver::Clamp01(mDolbyVec.mEffect);
break;
}
}
/* 8028BA98-8028BB14 .text getOscState__Q28JASystem8TChannelCFUl */
u8 TChannel::getOscState(u32 oscnum) const {
JUT_ASSERT(274, oscnum < (4));
return osc[oscnum]->mState;
}
/* 8028BB14-8028BB98 .text isOsc__Q28JASystem8TChannelFUl */
BOOL TChannel::isOsc(u32 oscnum) {
JUT_ASSERT(284, oscnum < (4));
return osc[oscnum]->isOsc();
}
/* 8028BB98-8028BC78 .text copyOsc__Q28JASystem8TChannelFUlPQ38JASystem11TOscillator4Osc_ */
void TChannel::copyOsc(u32 oscnum, TOscillator::Osc_* param_2) {
JUT_ASSERT(295, oscnum < (4));
if (isOsc(oscnum)) {
*param_2 = *osc[oscnum]->getOsc();
} else {
OSReport("osc[%d] is NULL\n", oscnum);
}
}
/* 8028BC78-8028BD10 .text overwriteOsc__Q28JASystem8TChannelFUlPQ38JASystem11TOscillator4Osc_ */
void TChannel::overwriteOsc(u32 oscnum, TOscillator::Osc_* param_2) {
JUT_ASSERT(308, oscnum < (4));
setOscInit(oscnum, param_2);
effectOsc(oscnum, bankOscToOfs(oscnum));
}
/* 8028BD10-8028BDA4 .text setKeySweepTarget__Q28JASystem8TChannelFUcUl */
void TChannel::setKeySweepTarget(u8 key, u32 target) {
s32 r0;
if (field_0xc == 2 || field_0x10 == 0)
r0 = key;
else
r0 = key + 0x3C - field_0x10->field_0x2;
if (r0 < 0)
r0 = 0;
else if (r0 > 0x7F)
r0 = 0x7F;
f32 val = Driver::C5BASE_PITCHTABLE[r0];
val *= field_0x50;
if (target == 0) {
field_0x58 = val;
field_0x2c = NULL;
return;
}
field_0x9c = val;
field_0xa2 = target;
field_0x2c = &TChannel::extraUpdate;
}
/* 8028BDA4-8028BDAC .text setPauseFlag__Q28JASystem8TChannelFUc */
void TChannel::setPauseFlag(u8 param_1) {
mPauseFlag = param_1;
}
/* 8028BDAC-8028BDBC .text setPauseFlagReq__Q28JASystem8TChannelFUc */
void TChannel::setPauseFlagReq(u8 param_1) {
mPauseFlag = param_1;
field_0x3 = 1;
}
/* 8028BDBC-8028BE64 .text setPanPower__Q28JASystem8TChannelFffff */
void TChannel::setPanPower(f32 param_1, f32 param_2, f32 param_3, f32 param_4) {
f32 px = param_1 + param_2 + param_3;
if (px == 0.0f) {
OSReport("----- JASChannel::setPanPower : px == 0.0\n");
px = 1.0f;
}
mPanPower.mSound = param_1 / px;
mPanPower.mEffect = param_2 / px;
mPanPower.mChannel = param_3 / px;
}
/* 8028BE64-8028BEB8 .text checkLogicalChannel__Q28JASystem8TChannelFv */
BOOL TChannel::checkLogicalChannel() {
if (!field_0x10 && field_0xc == 0) {
OSReport("----- checkLC : 波形がアサインされていません\n");
return false;
}
return true;
}
/* 8028BEB8-8028BF40 .text play__Q28JASystem8TChannelFUl */
BOOL TChannel::play(u32 param_1) {
if (param_1 == 0) {
param_1 = -1;
}
field_0x30 = param_1;
field_0x34 = field_0x30;
field_0x28 = &updatecallLogicalChannel;
field_0x20 = NULL;
if (!checkLogicalChannel()) {
return false;
}
TDSPQueue::enQueue(this);
field_0x4->addListTail(this, 3);
return true;
}
/* 8028BF40-8028BFAC .text stop__Q28JASystem8TChannelFUs */
void TChannel::stop(u16 param_1) {
if (!field_0x20) {
updatecallLogicalChannel(this, 6);
} else if (param_1 == 0) {
updatecallLogicalChannel(this, 0);
} else {
directReleaseOsc(0, param_1);
updatecallLogicalChannel(this, 0);
}
}
/* 8028BFAC-8028C108 .text updateJcToDSP__Q28JASystem8TChannelFv */
void TChannel::updateJcToDSP() {
DSPInterface::DSPBuffer* dspBuffer = field_0x20->field_0xc;
if (field_0xd4) {
for (u8 i = 0; i < 6; i++) {
dspBuffer->setMixerVolumeOnly(i, field_0xbc[i]);
}
dspBuffer->setPitch(mPitch);
dspBuffer->setPauseFlag(mPauseFlag);
dspBuffer->flushChannel();
} else {
for (u8 i = 0; i < 6; i++) {
dspBuffer->setMixerVolume(i, field_0xbc[i], field_0x4->field_0x5a[i]);
}
dspBuffer->setPitch(mPitch);
if (field_0x4->field_0x61 & 0x20) {
dspBuffer->setIIRFilterParam(field_0x4->field_0x3c);
}
if (field_0x4->field_0x61 & 0x1f) {
dspBuffer->setFIR8FilterParam(field_0x4->field_0x2c);
}
dspBuffer->setFilterMode(field_0x4->field_0x61);
dspBuffer->setDistFilter(field_0x4->field_0x4c);
dspBuffer->setPauseFlag(mPauseFlag);
field_0x20->field_0xc->flushChannel();
}
}
/* 8028C108-8028C140 .text forceStopLogicalChannel__Q28JASystem8TChannelFv */
bool TChannel::forceStopLogicalChannel() {
if (!field_0x20) {
return false;
}
field_0x20->forceStop();
return true;
}
/* 8028C140-8028C1C0 .text stopLogicalChannel__Q28JASystem8TChannelFv */
BOOL TChannel::stopLogicalChannel() {
if (!field_0x20) {
OSReport("----- stopLC : DSP Ch is not assigned\n");
return FALSE;
}
field_0x20->mCallback = NULL;
field_0x20->setCBInterval(0);
field_0x20->stop();
TDSPChannel::free(field_0x20, u32(this));
field_0x20 = NULL;
return TRUE;
}
/* 8028C1C0-8028C3A8 .text playLogicalChannel__Q28JASystem8TChannelFv */
BOOL TChannel::playLogicalChannel() {
if (!field_0x20) {
OSReport("----- playLC DSP Ch が割当てられていません\n");
return FALSE;
}
if (!checkLogicalChannel())
return FALSE;
field_0x20->mCallback = &TChannel::updatecallDSPChannel;
field_0x20->setCBInterval(1);
DSPInterface::DSPBuffer* buf = field_0x20->field_0xc;
switch (field_0xc) {
case 0:
buf->setWaveInfo(field_0x10, field_0x14, field_0xe8);
break;
case 2:
buf->setOscInfo(field_0x14);
break;
}
for (u8 i = 0; i < 6; ++i) {
// Something ungodly is occurring here.
union {
u16 asS16;
struct {
u8 hi;
u8 lo;
} asP;
} s;
s.asS16 = mMixConfigs[i].mWhole;
u32 om = Driver::getOutputMode();
if (om == 0) {
switch (s.asP.hi) {
case 8:
s.asP.hi = 0xB;
break;
case 9:
s.asP.hi = 0x2;
break;
}
} else if (om == 1) {
if (s.asP.hi == 8)
s.asP.hi = 0xB;
}
buf->setBusConnect(i, s.asP.hi);
}
field_0xa4 = field_0x4;
for (u32 i = 0; i < 4; ++i) {
if (isOsc(i)) {
effectOsc(i, bankOscToOfs(i));
}
}
updateEffectorParam();
updateJcToDSPInit();
field_0x20->setPriority(field_0x48);
field_0x20->setPriorityTime(field_0x4c);
field_0x20->play();
return TRUE;
}
/* 8028C3A8-8028C62C .text updateEffectorParam__Q28JASystem8TChannelFv */
void TChannel::updateEffectorParam() {
f32 pan;
f32 fxmix;
f32 dolby = 0.0f;
if (field_0xa4 == field_0x4) {
field_0xa8 = field_0x4->field_0x1c;
field_0xac = field_0x4->field_0x18;
mPanVec.mChannel = field_0x4->field_0x20;
mFxmixVec.mChannel = field_0x4->field_0x24;
mDolbyVec.mChannel = field_0x4->field_0x28;
for (int i = 0; i < 3; i++) {
mCalcTypes[i] = field_0x4->mCalcTypes[i];
}
}
switch (Driver::getOutputMode()) {
case 0:
pan = 0.5f;
dolby = 0.0f;
fxmix = calcEffect(&mFxmixVec, &mPanPower, mCalcTypes[1]);
break;
case 1:
pan = (mCalcTypes[0] == CALC_None) ? 0.5f : calcPan(&mPanVec, &mPanPower, mCalcTypes[0]);
fxmix = calcEffect(&mFxmixVec, &mPanPower, mCalcTypes[1]);
dolby = 0.0f;
break;
case 2:
pan = (mCalcTypes[0] == CALC_None) ? 0.5f : calcPan(&mPanVec, &mPanPower, mCalcTypes[0]);
fxmix = calcEffect(&mFxmixVec, &mPanPower, mCalcTypes[1]);
dolby = calcEffect(&mDolbyVec, &mPanPower, mCalcTypes[2]);
break;
}
f32 volume = field_0xac * (field_0x5c * field_0x98);
pan = Driver::Clamp01(pan);
fxmix = Driver::Clamp01(fxmix);
dolby = Driver::Clamp01(dolby);
mPitch = 4096.0f * (field_0xa8 * (field_0x58 * field_0x94));
if (mMixConfigs[0].mWhole != 0xFFFF) {
updateMixer(volume, pan, fxmix, dolby);
} else {
updateAutoMixer(volume, pan, fxmix, dolby);
}
}
/* 8028C62C-8028C6C4 .text killBrokenLogicalChannels__Q28JASystem8TChannelFPQ28JASystem11TDSPChannel */
void TChannel::killBrokenLogicalChannels(TDSPChannel* dspChannel) {
TChannelMgr* mgr;
for (u32 i = 0; i < 256; i++) {
TChannel* channel = TGlobalChannel::getChannelHandle(i);
if (channel == NULL) continue;
if (channel->field_0x20 != dspChannel) continue;
mgr = channel->field_0x4;
if (mgr == NULL) continue;
channel->stopLogicalChannel();
if (!mgr->moveListHead(channel, 0)) {
OSReport("----- killBrokenLogicalChannels : Cutできない\n");
}
}
}
/* 8028C6C4-8028CABC .text updatecallDSPChannel__Q28JASystem8TChannelFPQ28JASystem11TDSPChannelUl */
int TChannel::updatecallDSPChannel(TDSPChannel* dspChannel, u32 param_2) {
TChannel* channel = dspChannel->getLogicalChannel();
TChannelMgr* mgr = channel->field_0x4;
u32 i;
u32 r27 = 0;
if (channel == NULL) {
OSReport("-----Error JASDriver::commonCallbackLC DSPchのsignがNULL\n");
dspChannel->mCallback = NULL;
dspChannel->mPriority = 0;
killBrokenLogicalChannels(dspChannel);
return 0;
}
if (channel->field_0x20 != dspChannel) {
if (channel->field_0x20 != NULL && channel == channel->field_0x20->getLogicalChannel()) {
killBrokenLogicalChannels(dspChannel);
} else {
channel->stopLogicalChannel();
if (!mgr->moveListHead(channel, 0)) {
OSReport("----- updatecallDSPChannel : Cutできない\n");
}
}
dspChannel->forceDelete();
return 0;
} else {
if (param_2 == 2) {
if (channel->field_0x28 != NULL) {
channel->field_0x28(channel, 1);
} else {
channel->stopLogicalChannel();
if (!mgr->moveListHead(channel, 0)) {
OSReport("----- updatecallDSPChannel : Cutできない\n");
}
}
return 0;
}
if (channel->field_0x10 != NULL && channel->field_0x10->field_0x24[0] == 0) {
dspChannel->forceStop();
return -1;
}
if (param_2 == 4) {
u8 priority = channel->getLifeTimePriority();
if (channel->field_0x20 != NULL) {
if (priority < channel->field_0x20->getPriority()) {
channel->field_0x20->setPriority(priority);
}
}
return 0;
}
if (param_2 == 3) {
channel->forceStopOsc(0);
if (!mgr->moveListHead(channel, 3)) {
OSReport("----- updatecallDSPChannel : Cutできない\n");
return 1;
}
param_2 = 0;
}
if (param_2 == 0) {
channel->field_0x94 = 1.0f;
channel->field_0x98 = 1.0f;
channel->mPanVec.mEffect = 0.5f;
channel->mFxmixVec.mEffect = 0.0f;
channel->mDolbyVec.mEffect = 0.0f;
for (i = 0; i < 4; i++) {
if (!channel->isOsc(i)) continue;
channel->effectOsc(i, channel->bankOscToOfs(i));
if (i == 0 && channel->getOscState(i) == 0) {
if (channel->field_0x28 == NULL) {
OSReport("----- updatecallDSPCh JC停止のためのUPDATECALLがNULL\n");
if (!channel->stopLogicalChannel()) {
dspChannel->stop();
}
if (!mgr->moveListHead(channel, 0)) {
OSReport("----- updatecallDSPChannel : Cutできない update\n");
}
return 0;
}
channel->field_0x28(channel, 2);
return 0;
}
r27++;
}
if (r27 != 0) {
channel->updateEffectorParam();
channel->field_0x3 = 1;
}
if (channel->field_0x2c != NULL) {
if (channel->field_0x2c(channel, 0) == 1) {
channel->field_0x3++;
}
}
u8 updateInterval = Driver::getUpdateInterval();
if (channel->field_0x28 == NULL) {
return updateInterval;
}
if (channel->field_0x34 > 0) {
if (channel->field_0x34 > updateInterval) {
channel->field_0x34 -= updateInterval;
} else {
channel->field_0x34 = 0;
}
}
}
if (channel->field_0x34 == 0) {
channel->field_0x28(channel, 0);
channel->field_0x34 = channel->field_0x30;
}
if (channel->field_0x3 != 0) {
channel->updateJcToDSP();
channel->field_0x3 = 0;
}
return Driver::getUpdateInterval();
}
dspChannel->forceDelete();
}
/* 8028CABC-8028CB88 .text calcEffect__Q28JASystem8TChannelFPCQ38JASystem6Driver10PanMatrix_PCQ38JASystem6Driver10PanMatrix_Uc */
f32 TChannel::calcEffect(const Driver::PanMatrix_* params, const Driver::PanMatrix_* power, u8 calcType) {
f32 value = 0.0f;
const u8* calcTypes = Driver::calc_sw_table[calcType];
switch (calcTypes[CALC_Sound]) {
case CALC_NONE:
break;
case CALC_ADD:
value += params->mSound;
break;
case CALC_WEIGHT:
value += params->mSound * power->mSound;
break;
}
switch (calcTypes[CALC_Effect]) {
case CALC_NONE:
break;
case CALC_ADD:
value += params->mEffect;
break;
case CALC_WEIGHT:
value += params->mEffect * power->mEffect;
break;
}
switch (calcTypes[CALC_Channel]) {
case CALC_NONE:
break;
case CALC_ADD:
value += params->mChannel;
break;
case CALC_WEIGHT:
value += params->mChannel * power->mChannel;
break;
}
return value;
}
/* 8028CB88-8028CC90 .text calcPan__Q28JASystem8TChannelFPCQ38JASystem6Driver10PanMatrix_PCQ38JASystem6Driver10PanMatrix_Uc */
f32 TChannel::calcPan(const Driver::PanMatrix_* params, const Driver::PanMatrix_* power, u8 calcType) {
f32 value = 0.0f;
const u8* calcTypes = Driver::calc_sw_table[calcType];
switch (calcTypes[CALC_Sound]) {
case CALC_NONE:
break;
case CALC_ADD:
value += (params->mSound - 0.5f);
break;
case CALC_WEIGHT:
value += (params->mSound - 0.5f) * power->mSound;
break;
}
switch (calcTypes[CALC_Effect]) {
case CALC_NONE:
break;
case CALC_ADD:
value += (params->mEffect - 0.5f);
break;
case CALC_WEIGHT:
value += (params->mEffect - 0.5f) * power->mEffect;
break;
}
switch (calcTypes[CALC_Channel]) {
case CALC_NONE:
break;
case CALC_ADD:
value += (params->mChannel - 0.5f);
break;
case CALC_WEIGHT:
value += (params->mChannel - 0.5f) * power->mChannel;
break;
}
value += 0.5f;
return value;
}
/* 8028CC90-8028CD90 .text updateJcToDSPInit__Q28JASystem8TChannelFv */
void TChannel::updateJcToDSPInit() {
DSPInterface::DSPBuffer* buf = field_0x20->field_0xc;
if (mMixConfigs[0].mWhole == 0xFFFF) {
field_0x20->field_0xc->initAutoMixer();
} else {
buf->setMixerInitDelayMax(field_0x4->field_0x60);
for (u8 i = 0; i < 6; ++i)
buf->setMixerInitVolume(i, field_0xbc[i],
field_0x4->field_0x5a[i]);
}
buf->setPitch(mPitch);
if (field_0x4->field_0x61 & 0x20)
buf->setIIRFilterParam(field_0x4->field_0x3c);
if (field_0x4->field_0x61 & 0x1F)
buf->setFIR8FilterParam(field_0x4->field_0x2c);
buf->setFilterMode(field_0x4->field_0x61);
buf->setPauseFlag(mPauseFlag);
}
/* 8028CD90-8028CEA8 .text updateAutoMixer__Q28JASystem8TChannelFffff */
void TChannel::updateAutoMixer(f32 volume, f32 pan, f32 fxmix, f32 dolby) {
field_0x20->field_0xc->setAutoMixer(
Driver::Clamp01(volume) * Driver::getAutoLevel(),
pan * 127.5f, dolby * 127.5f, fxmix * 127.5f,
mMixConfigs[1].mWhole
);
}
/* 8028CEA8-8028D128 .text updateMixer__Q28JASystem8TChannelFffff */
void TChannel::updateMixer(f32 volume, f32 pan, f32 fxmix, f32 dolby) {
for (u32 i = 0; i < 6; i++) {
f32 vol = volume;
MixConfig config = mMixConfigs[i];
if (config.mParts.u == 0) {
field_0xbc[i] = 0;
} else {
f32 scale;
if (config.mParts.l0 != 0) {
switch (config.mParts.l0) {
case 1:
scale = pan;
break;
case 2:
scale = fxmix;
break;
case 3:
scale = dolby;
break;
case 5:
scale = 1.0f - pan;
break;
case 6:
scale = 1.0f - fxmix;
break;
case 7:
scale = 1.0f - dolby;
break;
}
vol *= Calc::sinfT(scale);
}
if (config.mParts.l1 != 0) {
switch (config.mParts.l1) {
case 1:
scale = pan;
break;
case 2:
scale = fxmix;
break;
case 3:
scale = dolby;
break;
case 5:
scale = 1.0f - pan;
break;
case 6:
scale = 1.0f - fxmix;
break;
case 7:
scale = 1.0f - dolby;
break;
}
switch (config.mParts.l1) {
case 3:
case 7:
vol *= Calc::sinfDolby2(scale);
break;
default:
vol *= Calc::sinfT(scale);
break;
}
}
field_0xbc[i] = Driver::Clamp01(vol) * Driver::getChannelLevel();
}
}
}
/* 8028D128-8028D218 .text extraUpdate__Q28JASystem8TChannelFPQ28JASystem8TChannelUl */
u32 TChannel::extraUpdate(TChannel* channel, u32) {
if (channel->field_0xa2 != 0) {
f32 f31 = channel->field_0x9c - channel->field_0x58;
u8 updateInterval = Driver::getUpdateInterval();
if (channel->field_0xa2 <= updateInterval) {
channel->field_0xa2 = 1;
}
f31 /= channel->field_0xa2;
channel->field_0x58 += f31 * updateInterval;
if ((channel->field_0xa2 - updateInterval) <= 0) {
channel->field_0xa2 = 0;
} else {
channel->field_0xa2 -= updateInterval;
}
if (channel->field_0xa2 == 0) {
channel->field_0x2c = NULL;
}
return 1;
} else {
return 0;
}
}
/* 8028D218-8028D3C0 .text updatecallLogicalChannel__Q28JASystem8TChannelFPQ28JASystem8TChannelUl */
BOOL TChannel::updatecallLogicalChannel(TChannel* channel, u32 param) {
TChannelMgr* mgr = channel->field_0x4;
if (param == 0) {
for (u32 i = 0; i < 4; ++i)
channel->releaseOsc(i);
if (channel->field_0x20)
channel->field_0x20->mPriority = channel->getReleasePriority();
if (!mgr->moveListTail(channel, 2)) {
OSReport("----- updatecallLC : CUT失敗(release)\n");
}
channel->field_0x30 = -1;
return FALSE;
} else if (param == 1 || param == 2 || param == 6) {
if (mgr->field_0x4 != 0) {
if (mgr->cutList(channel) == -1) {
OSReport("----- updatecallLC : CUT失敗(extra)\n");
} else {
--mgr->field_0x4;
if (u32 thing = channel->field_0xcc) {
channel->field_0xcc = 0;
mgr->checkLimitStop(channel, thing);
}
TGlobalChannel::release(channel);
}
} else {
int r29 = channel->field_0xcc;
if (!mgr->moveListHead(channel, 0)) {
OSReport("----- updatecallLC : CUT失敗(not extra)\n");
}
mgr->checkLimitStop(channel, r29);
}
if (param != 6)
channel->stopLogicalChannel();
else
TDSPQueue::deleteQueue(channel);
channel->field_0x1 = 0xFF;
channel->field_0x30 = 0xFFFFFFFF;
channel->field_0x28 = NULL;
}
return FALSE;
}
}; // namespace JASystem