tp/libs/JSystem/JAudio2/JASChannel.cpp

640 lines
21 KiB
C++

//
// Generated By: dol2asm
// Translation Unit: JASChannel
//
#include "JSystem/JAudio2/JASChannel.h"
#include "JSystem/JAudio2/JASAiCtrl.h"
#include "JSystem/JAudio2/JASCalc.h"
#include "JSystem/JAudio2/JASDriverIF.h"
#include "JSystem/JAudio2/JASDSPChannel.h"
#include "JSystem/JSupport/JSupport.h"
#include "JSystem/JMath/JMATrigonometric.h"
#include "JSystem/JGeometry.h"
//
// Forward References:
//
extern "C" void __ct__10JASChannelFPFUlP10JASChannelPQ26JASDsp8TChannelPv_vPv();
extern "C" void __dt__10JASChannelFv();
extern "C" void play__10JASChannelFv();
extern "C" void playForce__10JASChannelFv();
extern "C" void release__10JASChannelFUs();
extern "C" void setOscInit__10JASChannelFUlPCQ213JASOscillator4Data();
extern "C" void setMixConfig__10JASChannelFUlUs();
extern "C" void calcEffect__10JASChannelFPCQ210JASChannel9PanVector();
extern "C" void calcPan__10JASChannelFPCQ210JASChannel9PanVector();
extern "C" void effectOsc__10JASChannelFUlPQ213JASOscillator12EffectParams();
extern "C" void setKeySweepTarget__10JASChannelFlUl();
extern "C" void
updateEffectorParam__10JASChannelFPQ26JASDsp8TChannelPUsRCQ213JASOscillator12EffectParams();
extern "C" void dspUpdateCallback__10JASChannelFUlPQ26JASDsp8TChannelPv();
extern "C" void initialUpdateDSPChannel__10JASChannelFPQ26JASDsp8TChannel();
extern "C" void updateDSPChannel__10JASChannelFPQ26JASDsp8TChannel();
extern "C" void updateAutoMixer__10JASChannelFPQ26JASDsp8TChannelffff();
extern "C" void updateMixer__10JASChannelFffffPUs();
extern "C" void free__10JASChannelFv();
extern "C" void initBankDisposeMsgQueue__10JASChannelFv();
extern "C" void receiveBankDisposeMsg__10JASChannelFv();
extern "C" void checkBankDispose__10JASChannelCFv();
extern "C" u8 sBankDisposeMsgQ__10JASChannel[32];
extern "C" u8 sBankDisposeMsg__10JASChannel[64];
extern "C" u8 sBankDisposeList__10JASChannel[64];
extern "C" u8 sBankDisposeListSize__10JASChannel[4 + 4 /* padding */];
//
// External References:
//
extern "C" void pow2__7JASCalcFf();
extern "C" void __ct__17JASGenericMemPoolFv();
extern "C" void free__17JASGenericMemPoolFPvUl();
extern "C" void func_802978DC(void* _this);
extern "C" void __ct__6JASLfoFv();
extern "C" void getValue__6JASLfoCFv();
extern "C" void incCounter__6JASLfoFf();
extern "C" void resetCounter__6JASLfoFv();
extern "C" void __ct__13JASOscillatorFv();
extern "C" void initStart__13JASOscillatorFPCQ213JASOscillator4Data();
extern "C" void incCounter__13JASOscillatorFf();
extern "C" void getValue__13JASOscillatorCFv();
extern "C" void release__13JASOscillatorFv();
extern "C" void update__13JASOscillatorFv();
extern "C" void getDacRate__9JASDriverFv();
extern "C" void free__13JASDSPChannelFv();
extern "C" void start__13JASDSPChannelFv();
extern "C" void drop__13JASDSPChannelFv();
extern "C" void alloc__13JASDSPChannelFUcPFUlPQ26JASDsp8TChannelPv_lPv();
extern "C" void allocForce__13JASDSPChannelFUcPFUlPQ26JASDsp8TChannelPv_lPv();
extern "C" void setPriority__13JASDSPChannelFUc();
extern "C" void setWaveInfo__Q26JASDsp8TChannelFRC11JASWaveInfoUlUl();
extern "C" void setOscInfo__Q26JASDsp8TChannelFUl();
extern "C" void initAutoMixer__Q26JASDsp8TChannelFv();
extern "C" void setAutoMixer__Q26JASDsp8TChannelFUsUcUcUcUc();
extern "C" void setPitch__Q26JASDsp8TChannelFUs();
extern "C" void setMixerInitVolume__Q26JASDsp8TChannelFUcs();
extern "C" void setMixerVolume__Q26JASDsp8TChannelFUcs();
extern "C" void setPauseFlag__Q26JASDsp8TChannelFUc();
extern "C" void setBusConnect__Q26JASDsp8TChannelFUcUc();
extern "C" void getChannelLevel_dsp__9JASDriverFv();
extern "C" void getOutputMode__9JASDriverFv();
extern "C" void __register_global_object();
extern "C" void __construct_array();
extern "C" void _savegpr_27();
extern "C" void _savegpr_28();
extern "C" void _savegpr_29();
extern "C" void _restgpr_27();
extern "C" void _restgpr_28();
extern "C" void _restgpr_29();
extern "C" extern u8 data_80431B34[16 + 4 /* padding */];
extern "C" u8 sincosTable___5JMath[65536];
extern "C" u32 one__11JASWaveInfo[1 + 1 /* padding */];
extern "C" extern u8 struct_80451260[8];
//
// Declarations:
//
/* 80431B90-80431BB0 05E8B0 0020+00 2/2 0/0 0/0 .bss sBankDisposeMsgQ__10JASChannel */
OSMessageQueue JASChannel::sBankDisposeMsgQ;
/* 80431BB0-80431BF0 05E8D0 0040+00 1/1 0/0 0/0 .bss sBankDisposeMsg__10JASChannel */
OSMessage JASChannel::sBankDisposeMsg[16];
/* 80431BF0-80431C30 05E910 0040+00 2/2 0/3 0/0 .bss sBankDisposeList__10JASChannel */
OSMessage JASChannel::sBankDisposeList[16];
/* 80451298-804512A0 000798 0004+04 3/3 0/0 0/0 .sbss sBankDisposeListSize__10JASChannel
*/
int JASChannel::sBankDisposeListSize;
/* 8029A800-8029A918 295140 0118+00 0/0 3/3 0/0 .text
* __ct__10JASChannelFPFUlP10JASChannelPQ26JASDsp8TChannelPv_vPv */
JASChannel::JASChannel(Callback i_callback, void* i_callbackData) :
mStatus(STATUS_INACTIVE),
mDspCh(NULL),
mCallback(i_callback),
mCallbackData(i_callbackData),
mUpdateTimer(0),
mBankDisposeID(NULL),
mKey(0),
mVelocity(0x7f),
mKeySweep(0.0f),
mKeySweepTarget(0.0f),
mKeySweepCount(0),
mSkipSamples(0)
{
field_0xdc.field_0x0 = 0;
field_0x104 = 0;
mMixConfig[0].whole = 0x150;
mMixConfig[1].whole = 0x210;
mMixConfig[2].whole = 0x352;
mMixConfig[3].whole = 0x412;
mMixConfig[4].whole = 0;
mMixConfig[5].whole = 0;
mPriority = 0x13f;
mPauseFlag = false;
}
/* 80431C30-80431C40 05E950 000C+04 1/1 0/2 0/0 .bss @556 */
static u8 lit_556[12 + 4 /* padding */];
/* 8029A918-8029A9F0 295258 00D8+00 5/5 0/0 0/0 .text __dt__10JASChannelFv */
#ifdef NONMATCHING
// matches with static data
JASChannel::~JASChannel() {
if (mDspCh != NULL) {
mDspCh->drop();
}
if (mCallback != NULL) {
mCallback(CB_STOP, this, NULL, mCallbackData);
}
}
#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
asm JASChannel::~JASChannel() {
nofralloc
#include "asm/JSystem/JAudio2/JASChannel/__dt__10JASChannelFv.s"
}
#pragma pop
#endif
/* 8029A9F0-8029AA60 295330 0070+00 0/0 2/2 0/0 .text play__10JASChannelFv */
int JASChannel::play() {
JASDSPChannel* channel = JASDSPChannel::alloc(JSULoByte(mPriority), dspUpdateCallback, this);
if (channel == NULL) {
delete this;
return 0;
}
mDspCh = channel;
channel->start();
mStatus = STATUS_ACTIVE;
return 1;
}
/* 8029AA60-8029AAD0 2953A0 0070+00 0/0 1/1 0/0 .text playForce__10JASChannelFv */
int JASChannel::playForce() {
JASDSPChannel* channel = JASDSPChannel::allocForce(JSULoByte(mPriority),
dspUpdateCallback, this);
if (channel == NULL) {
delete this;
return 0;
}
mDspCh = channel;
channel->start();
mStatus = STATUS_ACTIVE;
return 1;
}
/* 8029AAD0-8029AB64 295410 0094+00 0/0 4/4 0/0 .text release__10JASChannelFUs */
void JASChannel::release(u16 i_directRelease) {
if (mStatus == STATUS_ACTIVE) {
if (i_directRelease != 0) {
setDirectRelease(i_directRelease);
}
for (u32 i = 0; i < 2; i++) {
if (mOscillators[i].isValid()) {
mOscillators[i].release();
}
}
mDspCh->setPriority(JSUHiByte(mPriority));
mStatus = STATUS_RELEASE;
}
}
/* 8029AB64-8029AB98 2954A4 0034+00 0/0 4/4 0/0 .text
* setOscInit__10JASChannelFUlPCQ213JASOscillator4Data */
void JASChannel::setOscInit(u32 i_index, JASOscillator::Data const* i_data) {
mOscillators[i_index].initStart(i_data);
}
/* 8029AB98-8029ABA8 2954D8 0010+00 0/0 2/2 0/0 .text setMixConfig__10JASChannelFUlUs */
void JASChannel::setMixConfig(u32 i_index, u16 i_config) {
mMixConfig[i_index].whole = i_config;
}
/* 8029ABA8-8029ABC0 2954E8 0018+00 1/1 0/0 0/0 .text
* calcEffect__10JASChannelFPCQ210JASChannel9PanVector */
f32 JASChannel::calcEffect(JASChannel::PanVector const* i_vector) {
return i_vector->mSound + i_vector->mEffect + i_vector->mChannel;
}
/* 8029ABC0-8029ABEC 295500 002C+00 1/1 0/0 0/0 .text
* calcPan__10JASChannelFPCQ210JASChannel9PanVector */
f32 JASChannel::calcPan(JASChannel::PanVector const* i_vector) {
return 0.5f + (i_vector->mSound - 0.5f) + (i_vector->mEffect - 0.5f)
+ (i_vector->mChannel - 0.5f);
}
/* 8029ABEC-8029ACD4 29552C 00E8+00 3/2 0/0 0/0 .text
* effectOsc__10JASChannelFUlPQ213JASOscillator12EffectParams */
void JASChannel::effectOsc(u32 i_index, JASOscillator::EffectParams* i_params) {
f32 value = mOscillators[i_index].getValue();
switch (mOscillators[i_index].getTarget()) {
case JASOscillator::TARGET_PITCH:
i_params->mPitch *= value;
break;
case JASOscillator::TARGET_VOLUME:
i_params->mVolume *= value;
break;
case JASOscillator::TARGET_PAN:
value -= 0.5;
i_params->mPan += value;
break;
case JASOscillator::TARGET_FXMIX:
i_params->mFxMix += value;
break;
case JASOscillator::TARGET_DOLBY:
i_params->mDolby += value;
break;
case JASOscillator::TARGET_5:
i_params->_14 *= value;
break;
case JASOscillator::TARGET_6:
i_params->_18 *= value;
break;
}
}
/* 8029ACD4-8029AD38 295614 0064+00 0/0 1/1 0/0 .text setKeySweepTarget__10JASChannelFlUl
*/
void JASChannel::setKeySweepTarget(s32 i_target, u32 i_count) {
if (i_count == 0) {
mKeySweep = i_target;
} else {
mKeySweep = 0.0f;
mKeySweepTarget = i_target;
}
mKeySweepCount = i_count;
}
/* 8029AD38-8029AF78 295678 0240+00 2/2 0/0 0/0 .text
* updateEffectorParam__10JASChannelFPQ26JASDsp8TChannelPUsRCQ213JASOscillator12EffectParams */
void JASChannel::updateEffectorParam(JASDsp::TChannel* i_channel, u16* i_mixerVolume,
JASOscillator::EffectParams const& i_params) {
PanVector pan_vector, fxmix_vector, dolby_vector;
pan_vector.mSound = mSoundParams.mPan;
pan_vector.mChannel = mParams.mPan;
pan_vector.mEffect = i_params.mPan;
fxmix_vector.mSound = mSoundParams.mFxMix;
fxmix_vector.mChannel = mParams.mFxMix;
fxmix_vector.mEffect = i_params.mFxMix;
dolby_vector.mSound = mSoundParams.mDolby;
dolby_vector.mChannel = mParams.mDolby;
dolby_vector.mEffect = i_params.mDolby;
f32 pan = 0.5f;
f32 dolby = 0.0f;
switch (JASDriver::getOutputMode()) {
case 0:
break;
case 1:
pan = calcPan(&pan_vector);
break;
case 2:
pan = calcPan(&pan_vector);
dolby = calcEffect(&dolby_vector);
break;
}
f32 fxmix = calcEffect(&fxmix_vector);
f32 volume = mVelocity / 127.0f;
volume = volume * volume;
volume = mSoundParams.mVolume * i_params.mVolume * mParams.mVolume
* (i_params._18 * mTremolo.getValue() + 1.0f) * volume;
if (volume < 0.0f) {
volume = 0.0f;
}
pan = JASCalc::clamp01(pan);
fxmix = JASCalc::clamp01(fxmix);
dolby = JASCalc::clamp01(dolby);
if (isDolbyMode()) {
updateAutoMixer(i_channel, volume, pan, fxmix, dolby);
} else {
updateMixer(volume, pan, fxmix, dolby, i_mixerVolume);
}
}
/* 8029AF78-8029B004 2958B8 008C+00 2/2 0/0 0/0 .text
* dspUpdateCallback__10JASChannelFUlPQ26JASDsp8TChannelPv */
s32 JASChannel::dspUpdateCallback(u32 i_type, JASDsp::TChannel* i_channel, void* i_this) {
JASChannel* _this = static_cast<JASChannel*>(i_this);
switch (i_type) {
case JASDSPChannel::CB_PLAY:
return _this->updateDSPChannel(i_channel);
case JASDSPChannel::CB_START:
return _this->initialUpdateDSPChannel(i_channel);
case JASDSPChannel::CB_STOP:
case JASDSPChannel::CB_DROP:
_this->mDspCh->free();
_this->mDspCh = NULL;
delete _this;
return -1;
}
return 0;
}
/* 8029B004-8029B324 295944 0320+00 1/1 0/0 0/0 .text
* initialUpdateDSPChannel__10JASChannelFPQ26JASDsp8TChannel */
s32 JASChannel::initialUpdateDSPChannel(JASDsp::TChannel* i_channel) {
if (isDolbyMode()) {
i_channel->initAutoMixer();
}
if (mCallback != NULL) {
mCallback(CB_START, this, i_channel, mCallbackData);
}
if (field_0xdc.field_0x4.field_0x20[0] == 0) {
mDspCh->free();
mDspCh = NULL;
delete this;
return -1;
}
if (checkBankDispose()) {
mDspCh->free();
mDspCh = NULL;
delete this;
return -1;
}
switch (field_0xdc.field_0x0) {
case 0:
i_channel->setWaveInfo(field_0xdc.field_0x4, field_0x104, mSkipSamples);
break;
case 2:
i_channel->setOscInfo(field_0x104);
break;
}
for (u8 i = 0; i < 6; i++) {
MixConfig mix_config = mMixConfig[i];
u32 output_mode = JASDriver::getOutputMode();
if (output_mode == 0) {
switch (mix_config.parts.upper) {
case 8:
mix_config.parts.upper = 11;
break;
case 9:
mix_config.parts.upper = 2;
break;
}
} else if (output_mode == 1 && mix_config.parts.upper == 8) {
mix_config.parts.upper = 11;
}
i_channel->setBusConnect(i, mix_config.parts.upper);
}
JASOscillator::EffectParams effect_params;
for (u32 i = 0; i < 2; i++) {
if (mOscillators[i].isValid()) {
mOscillators[i].update();
effectOsc(i, &effect_params);
}
}
mVibrate.resetCounter();
mTremolo.resetCounter();
u16 mixer_volume[6];
updateEffectorParam(i_channel, mixer_volume, effect_params);
for (u8 i = 0; i < 6; i++) {
i_channel->setMixerInitVolume(i, mixer_volume[i]);
}
f32 pitch = JASCalc::pow2(mParams.field_0x8 + (mKey + mKeySweep) / 12.0f
+ effect_params._14 * mVibrate.getValue());
pitch = mSoundParams.mPitch * effect_params.mPitch * pitch * mParams.mPitch * 4096.0f;
if (pitch < 0.0f) {
pitch = 0.0f;
}
i_channel->setPitch(pitch);
i_channel->setPauseFlag(mPauseFlag);
i_channel->field_0x066 = 0;
return 0;
}
/* 8029B324-8029B6A0 295C64 037C+00 1/1 0/0 0/0 .text
* updateDSPChannel__10JASChannelFPQ26JASDsp8TChannel */
s32 JASChannel::updateDSPChannel(JASDsp::TChannel* i_channel) {
if (mCallback != NULL) {
mCallback(CB_PLAY, this, i_channel, mCallbackData);
}
if (field_0xdc.field_0x4.field_0x20[0] == 0) {
mDspCh->free();
mDspCh = NULL;
delete this;
return -1;
}
if (checkBankDispose()) {
mDspCh->free();
mDspCh = NULL;
delete this;
return -1;
}
i_channel->setPauseFlag(mPauseFlag);
JASOscillator::EffectParams effect_params;
if (mPauseFlag) {
if (mOscillators[0].isRelease()) {
mDspCh->free();
mDspCh = NULL;
delete this;
return -1;
}
} else {
f32 inc = 32028.5f / JASDriver::getDacRate();
mVibrate.incCounter(inc);
mTremolo.incCounter(inc);
if (mUpdateTimer != 0) {
mUpdateTimer--;
if (mUpdateTimer == 0 && mCallback != NULL) {
mCallback(CB_TIMER, this, i_channel, mCallbackData);
}
}
inc = 48000.0f / JASDriver::getDacRate();
for (u32 i = 0; i < 2; i++) {
if (mOscillators[i].isValid()) {
mOscillators[i].incCounter(inc);
effectOsc(i, &effect_params);
if (i == 0 && mOscillators[i].isStop()) {
mDspCh->free();
mDspCh = NULL;
delete this;
return -1;
}
}
}
}
u16 mixer_volume[6];
updateEffectorParam(i_channel, mixer_volume, effect_params);
for (u8 i = 0; i < 6; i++) {
i_channel->setMixerVolume(i, mixer_volume[i]);
}
f32 pitch = JASCalc::pow2(mParams.field_0x8 + (mKey + mKeySweep) / 12.0f
+ effect_params._14 * mVibrate.getValue());
pitch = mSoundParams.mPitch * effect_params.mPitch * pitch * mParams.mPitch * 4096.0f;
if (pitch < 0.0f) {
pitch = 0.0f;
}
i_channel->setPitch(pitch);
if (!mPauseFlag && mKeySweepCount != 0) {
mKeySweep += (mKeySweepTarget - mKeySweep) / mKeySweepCount;
mKeySweepCount--;
}
return 0;
}
/* 8029B6A0-8029B7D8 295FE0 0138+00 1/1 0/0 0/0 .text
* updateAutoMixer__10JASChannelFPQ26JASDsp8TChannelffff */
void JASChannel::updateAutoMixer(JASDsp::TChannel* i_channel, f32 param_1, f32 param_2,
f32 param_3, f32 param_4) {
if (JASDriver::getOutputMode() == 0) {
param_1 *= 0.707f;
}
f32 fvar1 = JASCalc::clamp01(param_1);
i_channel->setAutoMixer(fvar1 * JASDriver::getChannelLevel_dsp(), param_2 * 127.5f,
param_4 * 127.5f, param_3 * 127.5f, 0);
}
/* 8029B7D8-8029BBFC 296118 0424+00 3/1 0/0 0/0 .text updateMixer__10JASChannelFffffPUs
*/
void JASChannel::updateMixer(f32 i_volume, f32 i_pan, f32 i_fxmix, f32 i_dolby, u16* i_volumeOut) {
for (u32 i = 0; i < 6; i++) {
f32 volume = i_volume;
MixConfig config = mMixConfig[i];
if (config.parts.upper == 0) {
i_volumeOut[i] = 0;
} else {
f32 scale;
if (config.parts.lower0 != 0) {
switch (config.parts.lower0) {
case 1:
scale = i_pan;
break;
case 2:
scale = i_fxmix;
break;
case 3:
scale = i_dolby;
break;
case 5:
scale = 1.0f - i_pan;
break;
case 6:
scale = 1.0f - i_fxmix;
break;
case 7:
scale = 1.0f - i_dolby;
break;
}
switch (config.parts.lower0) {
case 2:
case 6:
volume *= scale;
break;
default:
if (JASDriver::getOutputMode() == 0) {
volume *= scale;
} else {
volume *= JMASinRadian(scale * JGeometry::TUtil<f32>::PI() * 0.5f);
}
break;
}
}
if (config.parts.lower1 != 0) {
switch (config.parts.lower1) {
case 1:
scale = i_pan;
break;
case 2:
scale = i_fxmix;
break;
case 3:
scale = i_dolby;
break;
case 5:
scale = 1.0f - i_pan;
break;
case 6:
scale = 1.0f - i_fxmix;
break;
case 7:
scale = 1.0f - i_dolby;
break;
}
switch (config.parts.lower1) {
case 3:
case 7:
volume *= JMASinRadian((scale * 0.34776f + 0.32612f)
* JGeometry::TUtil<f32>::PI() * 0.5f);
break;
case 2:
case 6:
volume *= scale;
break;
default:
if (JASDriver::getOutputMode() == 0) {
volume *= scale;
} else {
volume *= JMASinRadian(scale * JGeometry::TUtil<f32>::PI() * 0.5f);
}
break;
}
}
i_volumeOut[i] = JASCalc::clamp01(volume) * JASDriver::getChannelLevel_dsp();
}
}
}
/* 8029BBFC-8029BC0C 29653C 0010+00 0/0 3/3 0/0 .text free__10JASChannelFv */
void JASChannel::free() {
mCallback = NULL;
mCallbackData = NULL;
}
/* 8029BC0C-8029BC48 29654C 003C+00 0/0 1/1 0/0 .text initBankDisposeMsgQueue__10JASChannelFv */
void JASChannel::initBankDisposeMsgQueue() {
OSInitMessageQueue(&sBankDisposeMsgQ, sBankDisposeMsg, 0x10);
sBankDisposeListSize = 0;
}
/* 8029BC48-8029BCC0 296588 0078+00 0/0 1/1 0/0 .text receiveBankDisposeMsg__10JASChannelFv */
void JASChannel::receiveBankDisposeMsg() {
OSMessage msg;
for (sBankDisposeListSize = 0;
OSReceiveMessage(&sBankDisposeMsgQ, &msg, OS_MESSAGE_NOBLOCK);
sBankDisposeListSize++)
{
sBankDisposeList[sBankDisposeListSize] = msg;
}
}
/* 8029BCC0-8029BD14 296600 0054+00 2/2 0/0 0/0 .text checkBankDispose__10JASChannelCFv
*/
bool JASChannel::checkBankDispose() const {
if (mBankDisposeID == NULL) {
return false;
}
for (int i = 0; i < sBankDisposeListSize; i++) {
if (mBankDisposeID == sBankDisposeList[i]) {
return true;
}
}
return false;
}