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
This commit is contained in:
Luke Street
2026-03-01 15:35:36 -07:00
committed by GitHub
parent c9a46bd65b
commit 4df8ccc871
1740 changed files with 583 additions and 825 deletions
+5
View File
@@ -0,0 +1,5 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAIAudible.h"
JAIAudible::~JAIAudible() {}
+12
View File
@@ -0,0 +1,12 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAIAudience.h"
#include "JSystem/JAudio2/JAISeMgr.h"
#include "JSystem/JAudio2/JAISeqMgr.h"
#include "JSystem/JAudio2/JAIStreamMgr.h"
JAIAudience::~JAIAudience() {
JUT_ASSERT(14, ! JAISeMgr::getInstance() || ( JAISeMgr::getInstance() ->getAudience() != this ));
JUT_ASSERT(15, ! JAISeqMgr::getInstance() || ( JAISeqMgr::getInstance() ->getAudience() != this ));
JUT_ASSERT(16, ! JAIStreamMgr::getInstance() || ( JAIStreamMgr::getInstance() ->getAudience() != this ));
}
+217
View File
@@ -0,0 +1,217 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAISe.h"
#include "JSystem/JAudio2/JAIAudience.h"
#include "JSystem/JAudio2/JAISeMgr.h"
JAISe::JAISe(JAISeMgr* seMgr, JAISoundStrategyMgr<JAISe>* soundStrategyMgr, u32 priority) : JSULink<JAISe>(this) {
inner_.mSoundStrategyMgr = soundStrategyMgr;
inner_.seMgr = seMgr;
inner_.mProperPriority = priority;
}
void JAISe::mixOut_(const JASSoundParams& params) {
inner_.track.setTempoRate(inner_.mTempoMgr.getTempo());
JASSoundParams mixParams;
params_.mixOutAll(params, &mixParams, fader_.getIntensity());
if (inner_.field_0x278) {
inner_.field_0x278->virtual4(this, mixParams);
}
if (audible_) {
int maxChannels = audience_->getMaxChannels();
for (int i = 0; i < maxChannels; i++) {
audience_->mixChannelOut(mixParams, audible_, i);
}
} else {
inner_.mSoundParams = mixParams;
}
}
void JAISe::stopTrack_() {
switch (inner_.track.getStatus()) {
case JASTrack::STATUS_FREE:
break;
case JASTrack::STATUS_RUN:
inner_.track.stopSeq();
break;
case JASTrack::STATUS_STOPPED:
break;
}
}
void JAISe::startTrack_(const JASSoundParams& params) {
JUT_ASSERT(72, inner_.track.getStatus() != JASTrack::STATUS_RUN);
if (inner_.track.getStatus() == JASTrack::STATUS_STOPPED) {
inner_.track.init();
}
if (audible_) {
initTrack_JAISound_(&inner_.track);
} else {
params_.mixOutAll(params, &inner_.mSoundParams, fader_.getIntensity());
inner_.track.setChannelMgrCount(1);
inner_.track.assignExtBuffer(0, &inner_.mSoundParams);
}
inner_.field_0x26c = 1;
inner_.track.setSeqData(inner_.mSeqData.field_0x0, inner_.mSeqData.field_0x4);
inner_.track.startSeq();
}
void JAISe::JAISeCategoryMgr_mixOut_(bool param_0, const JASSoundParams& params, JAISoundActivity activity) {
mixOut_(params);
if (isStopping()) {
stopTrack_();
} else if (param_0) {
if (status_.isPlaying()) {
if (inner_.field_0x26c) {
switch (inner_.track.getStatus()) {
case JASTrack::STATUS_STOPPED:
if (status_.field_0x1.flags.flag1) {
startTrack_(params);
} else {
stop_JAISound_();
}
break;
case JASTrack::STATUS_RUN:
inner_.track.pause(status_.isPaused() || activity.field_0x0.flags.flag2);
inner_.track.mute(status_.isMute() || activity.field_0x0.flags.flag1);
}
} else {
startTrack_(params);
}
}
} else if (status_.field_0x1.flags.flag1) {
if (status_.field_0x1.flags.flag3) {
inner_.track.pause(true);
} else {
stopTrack_();
}
} else {
stopTrack_();
stop_JAISound_();
}
}
void JAISe::JAISeCategoryMgr_calc_() {
prepare_();
if (calc_JAISound_()) {
inner_.mTempoMgr.calc();
if (inner_.field_0x278) {
inner_.field_0x278->calc(this);
}
}
if (isStopping() || priority_ == -1) {
inner_.mPriority = -1;
} else {
inner_.mPriority = inner_.mProperPriority + priority_;
}
}
bool JAISe::JAISound_tryDie_() {
switch (inner_.track.getStatus()) {
case JASTrack::STATUS_FREE:
case JASTrack::STATUS_STOPPED:
if (inner_.field_0x278) {
inner_.mSoundStrategyMgr->virtual4(inner_.field_0x278);
inner_.field_0x278 = NULL;
}
die_JAISound_();
return true;
case JASTrack::STATUS_RUN:
break;
}
return false;
}
void JAISe::JAISeMgr_startID_(JAISoundID id, const JGeometry::TVec3<f32>* posPtr, JAIAudience* audience) {
JUT_ASSERT(221, inner_.track.getStatus() == JASTrack::STATUS_FREE);
start_JAISound_(id, posPtr, audience);
inner_.field_0x26c = 0;
if (inner_.mSoundStrategyMgr) {
inner_.field_0x278 = inner_.mSoundStrategyMgr->calc(id);
} else {
inner_.field_0x278 = NULL;
}
}
s32 JAISe::getNumChild() const {
return 0;
}
JAISoundChild* JAISe::getChild(int param_0) {
return NULL;
}
void JAISe::releaseChild(int param_0) {}
bool JAISe::prepare_getSeqData_() {
JUT_ASSERT(271, inner_.track.getStatus() != JASTrack::STATUS_RUN);
JUT_ASSERT(272, inner_.seMgr);
JUT_ASSERT(273, inner_.seMgr ->getSeqDataMgr());
switch (inner_.seMgr->getSeqDataMgr()->getSeqData(getID(), &inner_.mSeqData)) {
case 0:
OS_REPORT("Failed In Loading Sequence Data:SE(0x%08x)\n", *(u32*)&getID());
status_.state.unk = 2;
return false;
case 1:
increasePrepareCount_JAISound_();
return false;
case 2:
return true;
default:
JUT_ASSERT(296, false);
}
return false;
}
void JAISe::prepare_() {
switch (status_.state.unk) {
case 6:
JUT_ASSERT(306, false);
break;
case 2:
stop_JAISound_();
break;
case 0:
if (prepare_getSeqData_()) {
status_.state.unk = 5;
}
break;
case 1:
if (prepare_getSeqData_()) {
status_.state.unk = 3;
}
break;
case 4:
status_.state.unk = 5;
break;
case 3:
case 5:
break;
}
}
JASTrack* JAISe::getTrack() {
return &inner_.track;
}
JASTrack* JAISe::getChildTrack(int param_0) {
return inner_.track.getChild(param_0);
}
JAISe* JAISe::asSe() {
return this;
}
JAITempoMgr* JAISe::getTempoMgr() {
return &inner_.mTempoMgr;
}
+331
View File
@@ -0,0 +1,331 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAISeMgr.h"
#include "JSystem/JAudio2/JAISoundHandles.h"
#include "JSystem/JAudio2/JAISoundInfo.h"
#include "JSystem/JAudio2/JASReport.h"
bool JAISeCategoryMgr::isUsingSeqData(const JAISeqDataRegion& seqDataRegion) {
{
JSULink<JAISe>* i = mSeList.getFirst();
while (i != NULL) {
if (seqDataRegion.intersects(*i->getObject()->getSeqData())) {
return true;
}
i = i->getNext();
}
}
return false;
}
int JAISeCategoryMgr::releaseSeqData(const JAISeqDataRegion& seqDataRegion) {
bool bVar1 = false;
for (JSULink<JAISe>* i = mSeList.getFirst(); i != NULL; i = i->getNext()) {
if (seqDataRegion.intersects(*i->getObject()->getSeqData())) {
i->getObject()->stop();
bVar1 = true;
}
}
enum {_1 = 1, _2}; // fakematch, figure out what this enum is eventually
return bVar1 ? _1 : _2;
}
void JAISeCategoryMgr::JAISeMgr_calc_() {
mParams.calc();
for (JSULink<JAISe>* i = mSeList.getFirst(); i != NULL; i = i->getNext()) {
i->getObject()->JAISeCategoryMgr_calc_();
}
sortByPriority_();
}
void JAISeCategoryMgr::JAISeMgr_freeDeadSe_() {
JSULink<JAISe>* i = mSeList.getFirst();
while (i != NULL) {
JSULink<JAISe>* link_next = i->getNext();
if (i->getObject()->status_.isDead()) {
JUT_ASSERT(71, ! i->getObject() ->isHandleAttached());
mSeList.remove(i);
delete i->getObject();
}
i = link_next;
}
}
bool JAISeCategoryMgr::JAISeMgr_acceptsNewSe_(u32 priority) const {
s32 maxSe = getMaxSe();
if (maxSe <= 0) {
return 1;
}
s32 stopCount = 0;
for (JSULink<JAISe>* i = mSeList.getFirst(); i != NULL; i = i->getNext()) {
if (priority < i->getObject()->JAISeCategoryMgr_getProperPriority_()) {
return 1;
}
if (!i->getObject()->isStopping()) {
stopCount++;
}
}
if (stopCount < maxSe) {
return true;
} else {
return false;
}
}
void JAISeCategoryMgr::sortByPriority_() {
for (u32 i = mSeList.getNumLinks(); i != 0; i--) {
JSULink<JAISe>* link = mSeList.getFirst();
u32 lowestPriority = link->getObject()->JAISeCategoryMgr_getPriority_();
JSULink<JAISe>* current = link->getNext();
for (int j = 1; j < i; j++) {
u32 itemPriority = current->getObject()->JAISeCategoryMgr_getPriority_();
if (itemPriority < lowestPriority) {
lowestPriority = itemPriority;
link = current;
}
current = current->getNext();
}
bool result = mSeList.remove(link);
JUT_ASSERT(131, result);
result = mSeList.append(link);
JUT_ASSERT(133, result);
}
}
void JAISeCategoryMgr::stop(u32 fadeTime) {
for (JSULink<JAISe>* i = mSeList.getFirst(); i != NULL; i = i->getNext()) {
i->getObject()->stop(fadeTime);
}
}
void JAISeCategoryMgr::stop() {
for (JSULink<JAISe>* i = mSeList.getFirst(); i != NULL; i = i->getNext()) {
i->getObject()->stop();
}
}
void JAISeCategoryMgr::stopSoundID(JAISoundID id) {
if (!id.isAnonymous()) {
for (JSULink<JAISe>* i = mSeList.getFirst(); i != NULL; i = i->getNext()) {
if ((u32)i->getObject()->getID() == (u32)id) {
i->getObject()->stop();
}
}
}
}
void JAISeCategoryMgr::pause(bool param_0) {
for (JSULink<JAISe>* i = mSeList.getFirst(); i != NULL; i = i->getNext()) {
i->getObject()->pause(param_0);
}
}
void JAISeCategoryMgr::JAISeMgr_mixOut_(const JAISoundParamsMove& params,
JAISoundActivity activity) {
JASSoundParams mixParams;
mixParams.combine(params.params_, mParams.params_);
JSULink<JAISe>* i = mSeList.getFirst();
int maxActiveSe = getMaxActiveSe();
int sp28;
if (maxActiveSe > 0) {
while (i != NULL && maxActiveSe > 0 && !i->getObject()->isFarAway()) {
i->getObject()->JAISeCategoryMgr_mixOut_(true, mixParams, activity);
i = i->getNext();
maxActiveSe--;
sp28 = maxActiveSe;
}
for (; i != NULL; i = i->getNext()) {
i->getObject()->JAISeCategoryMgr_mixOut_(false, mixParams, activity);
}
} else {
while (i != NULL && !i->getObject()->isFarAway()) {
i->getObject()->JAISeCategoryMgr_mixOut_(true, mixParams, activity);
i = i->getNext();
}
for (; i != NULL; i = i->getNext()) {
i->getObject()->JAISeCategoryMgr_mixOut_(false, mixParams, activity);
}
}
}
JAISeMgr::JAISeMgr(bool setInstance) : JASGlobalInstance<JAISeMgr>(setInstance) {
mAudience = NULL;
mSeqDataMgr = NULL;
mStrategyMgr = NULL;
mParams.init();
mSoundActivity.init();
}
bool JAISeMgr::isUsingSeqData(const JAISeqDataRegion& seqDataRegion) {
for (int i = 0; i < 16; i++) {
if (mCategoryMgrs[i].JAISeCategoryMgr::isUsingSeqData(seqDataRegion)) {
return true;
}
}
return false;
}
int JAISeMgr::releaseSeqData(const JAISeqDataRegion& seqDataRegion) {
bool r30 = 0;
for (int i = 0; i < 16; i++) {
switch (mCategoryMgrs[i].JAISeCategoryMgr::releaseSeqData(seqDataRegion)) {
case 0:
return 0;
case 1:
r30 = 1;
break;
}
}
return (r30 != 0) ? 1 : 0;
}
void JAISeMgr::setCategoryArrangement(const JAISeCategoryArrangement& arrangement) {
for (int i = 0; i < 16; i++) {
mCategoryMgrs[i].setMaxActiveSe(arrangement.mItems[i].mMaxActiveSe);
mCategoryMgrs[i].setMaxInactiveSe(arrangement.mItems[i].mMaxInactiveSe);
}
}
void JAISeMgr::getCategoryArrangement(JAISeCategoryArrangement* arrangement) {
for (int i = 0; i < 16; i++) {
int active = mCategoryMgrs[i].getMaxActiveSe();
JUT_ASSERT(299, active <= 255);
arrangement->mItems[i].mMaxActiveSe = active;
int inactive = mCategoryMgrs[i].getMaxInactiveSe();
JUT_ASSERT(302, inactive <= 255);
arrangement->mItems[i].mMaxInactiveSe = inactive;
}
}
void JAISeMgr::stop() {
for (int i = 0; i < 16; i++) {
mCategoryMgrs[i].stop();
}
}
void JAISeMgr::stopSoundID(JAISoundID id) {
for (int i = 0; i < 16; i++) {
mCategoryMgrs[i].stopSoundID(id);
}
}
void JAISeMgr::initParams() {
for (int i = 0; i < 16; i++) {
mCategoryMgrs[i].getParams()->init();
}
}
void JAISeMgr::setAudience(JAIAudience* audience) {
JUT_ASSERT(363, ! isActive());
mAudience = audience;
}
void JAISeMgr::setSeqDataMgr(JAISeqDataMgr* seqDataMgr) {
JUT_ASSERT(377, ! isActive());
resetSeqDataMgr();
mSeqDataMgr = seqDataMgr;
mSeqDataMgr->setSeqDataUser(this);
}
void JAISeMgr::resetSeqDataMgr() {
if (mSeqDataMgr) {
mSeqDataMgr->setSeqDataUser(NULL);
mSeqDataMgr = NULL;
}
}
JAISe* JAISeMgr::newSe_(int category, u32 priority) {
JUT_ASSERT(396, category < NUM_CATEGORIES);
if (category < 0) {
category = 0;
}
JAISeCategoryMgr* categoryMgr = &mCategoryMgrs[category];
if (!categoryMgr->JAISeMgr_acceptsNewSe_(priority)) {
return NULL;
}
JAISe* se = new JAISe(this, mStrategyMgr, priority);
if (se == NULL) {
JUT_WARN(410, "%s", "JASPoolAllocObject::<JAISe>::operator new failed .\n")
return NULL;
}
categoryMgr->JAISeMgr_appendSe_(se);
return se;
}
void JAISeMgr::calc() {
mParams.calc();
for (int i = 0; i < 16; i++) {
mCategoryMgrs[i].JAISeMgr_calc_();
}
for (int i = 0; i < 16; i++) {
mCategoryMgrs[i].JAISeMgr_freeDeadSe_();
}
}
void JAISeMgr::mixOut() {
for (int i = 0; i < 16; i++) {
mCategoryMgrs[i].JAISeMgr_mixOut_(mParams, mSoundActivity);
}
}
bool JAISeMgr::startSound(JAISoundID id, JAISoundHandle* handle, const JGeometry::TVec3<f32>* posPtr) {
if (handle && *handle) {
(*handle)->stop();
}
JAISoundInfo* soundInfoPtr = JASGlobalInstance<JAISoundInfo>::getInstance();
u32 priority;
u32 category;
if (soundInfoPtr != NULL) {
category = soundInfoPtr->getCategory(id);
priority = soundInfoPtr->getPriority(id);
} else {
category = id.id_.info.type.parts.groupID;
priority = 0;
}
JAISe* se = newSe_(category, priority);
if (se == NULL) {
#if !PLATFORM_SHIELD
JASReport("cannot new Se %08x.", id.id_.composite_);
#endif
return false;
}
JAIAudience* audiencePtr = getAudience(category);
se->JAISeMgr_startID_(id, posPtr, audiencePtr);
if (soundInfoPtr != NULL) {
soundInfoPtr->getSeInfo(id, se);
}
if (handle != NULL) {
se->attachHandle(handle);
}
return true;
}
int JAISeMgr::getNumActiveSe() const {
int num = 0;
for (int i = 0; i < 16; i++) {
num += mCategoryMgrs[i].getNumSe();
}
return num;
}
+304
View File
@@ -0,0 +1,304 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAISeq.h"
#include "JSystem/JAudio2/JAISeqMgr.h"
#include "JSystem/JAudio2/JAISoundChild.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
#include "JSystem/JAudio2/JAIAudience.h"
namespace {
static bool JASTrack_isFreeOrStopped(JASTrack* track) {
u32 status = track->getStatus();
return status == JASTrack::STATUS_FREE || status == JASTrack::STATUS_STOPPED;
}
} // namespace
JAISeq::JAISeq(JAISeqMgr* seqMgr, JAISoundStrategyMgr<JAISeq>* soundStrategyMgr) : JSULink<JAISeq>(this) {
inner_.seqMgr = seqMgr;
inner_.strategyMgr = soundStrategyMgr;
inner_.mSoundParams.init();
for (int i = 0; i < 32; i++) {
inner_.mSoundChild[i] = NULL;
}
}
void JAISeq::JAISeqMgr_startID_(JAISoundID id, const JGeometry::TVec3<f32>* posPtr,
JAIAudience* audience, int category, int param_4) {
inner_.field_0x39c = category;
reserveChildTracks_(param_4);
start_JAISound_(id, posPtr, audience);
if (inner_.strategyMgr) {
field_0x3a8 = inner_.strategyMgr->calc(id);
} else {
field_0x3a8 = NULL;
}
}
void JAISeq::playSeqData_(const JASSoundParams& params, JAISoundActivity activity) {
JUT_ASSERT(72, JASTrack_isFreeOrStopped( & inner_.outputTrack ));
inner_.outputTrack.setSeqData(inner_.mSeqData.field_0x0, inner_.mSeqData.field_0x4);
if (audible_) {
initTrack_JAISound_(&inner_.outputTrack);
} else {
inner_.outputTrack.setChannelMgrCount(1);
inner_.outputTrack.assignExtBuffer(0, &inner_.mSoundParams);
}
mixOut_(params, activity);
inner_.outputTrack.startSeq();
}
void JAISeq::reserveChildTracks_(int param_0) {
JUT_ASSERT(92, inner_.outputTrack.getStatus() == JASTrack::STATUS_FREE);
for (int i = 0; i < 2; i++) {
JASTrack* track = new JASTrack();
if (track) {
track->setAutoDelete(true);
inner_.outputTrack.connectChild(i, track);
for (int j = 0; j < 16; j++) {
int sp18 = i * 16 + j;
if (sp18 >= param_0) {
continue;
}
JASTrack* track2 = new JASTrack();
if (track2) {
track2->setAutoDelete(true);
track->connectChild(j, track2);
} else {
JUT_WARN(117, "%s", "JASPoolAllocObject::<JASTrack>::operator new failed .\n");
continue;
}
}
} else {
JUT_WARN(124, "%s", "JASPoolAllocObject::<JASTrack>::operator new failed .\n");
continue;
}
}
}
void JAISeq::releaseChildTracks_() {
for (u32 i = 0; i < 2; i++) {
JASTrack* track = inner_.outputTrack.getChild(i);
if (track) {
for (u32 j = 0; j < 16; j++) {
JASTrack* track2 = track->getChild(j);
if (track2) {
delete track2;
}
}
delete track;
}
}
}
bool JAISeq::prepare_getSeqData_() {
if (getID().isAnonymous()) {
return true;
}
JAISeqDataMgr* seqDataMgr = inner_.seqMgr->getSeqDataMgr();
JUT_ASSERT(162, seqDataMgr);
switch (seqDataMgr->getSeqData(getID(), &inner_.mSeqData)) {
case 0:
OS_REPORT("Failed In Loading Sequence Data:SEQ(0x%08x)\n", getID());
status_.state.unk = 2;
break;
case 1:
increasePrepareCount_JAISound_();
return false;
case 2:
return true;
}
return false;
}
bool JAISeq::prepare_(const JASSoundParams& params, JAISoundActivity activity) {
switch (status_.state.unk) {
case 6:
JUT_ASSERT(193, false);
break;
case 2:
stop_JAISound_();
break;
case 0:
if (prepare_getSeqData_()) {
status_.state.unk = 5;
playSeqData_(params, activity);
return true;
}
break;
case 1:
if (prepare_getSeqData_()) {
status_.state.unk = 3;
}
return false;
case 4:
status_.state.unk = 5;
playSeqData_(params, activity);
return true;
case 5:
return true;
}
return false;
}
void JAISeq::JAISeqMgr_calc_() {
if (inner_.outputTrack.getStatus() == JASTrack::STATUS_STOPPED || (inner_.outputTrack.getStatus() == JASTrack::STATUS_FREE && status_.state.unk == 2)) {
die_();
return;
}
if (calc_JAISound_()) {
inner_.mTempoMgr.calc();
for (int i = 0; i < 32; i++) {
if (inner_.mSoundChild[i]) {
inner_.mSoundChild[i]->calc();
}
}
if (field_0x3a8) {
field_0x3a8->calc(this);
}
}
}
void JAISeq::die_() {
JUT_ASSERT(269, JASTrack_isFreeOrStopped( & inner_.outputTrack ));
for (int i = 0; i < 32; i++) {
if (inner_.mSoundChild[i]) {
delete inner_.mSoundChild[i];
inner_.mSoundChild[i] = NULL;
}
}
if (field_0x3a8) {
JUT_ASSERT(281, inner_.strategyMgr);
inner_.strategyMgr->virtual4(field_0x3a8);
field_0x3a8 = NULL;
}
releaseChildTracks_();
die_JAISound_();
}
bool JAISeq::JAISound_tryDie_() {
if (JASTrack_isFreeOrStopped(&inner_.outputTrack)) {
die_();
return true;
}
fader_.forceOut();
status_.state.flags.flag1 = 1;
{
JASCriticalSection cs;
inner_.outputTrack.stopSeq();
}
return false;
}
void JAISeq::mixOut_(const JASSoundParams& params, JAISoundActivity activity) {
inner_.outputTrack.setTempoRate(inner_.mTempoMgr.getTempo());
inner_.outputTrack.mute(activity.field_0x0.flags.flag1 || status_.isMute());
inner_.outputTrack.pause(activity.field_0x0.flags.flag2 || status_.isPaused());
JASSoundParams outParams;
params_.mixOutAll(params, &outParams, fader_.getIntensity());
if (field_0x3a8) {
field_0x3a8->virtual4(this, outParams);
}
if (audible_) {
int maxChannels = audience_->getMaxChannels();
for (int i = 0; i < maxChannels; i++) {
audience_->mixChannelOut(outParams, audible_, i);
}
} else {
inner_.mSoundParams = outParams;
for (int i = 0; i < NUM_CHILDREN; i++) {
if (inner_.mSoundChild[i]) {
JASTrack* track = JAISeq::getChildTrack(i);
if (track) {
inner_.mSoundChild[i]->mixOut(track);
}
}
}
}
}
void JAISeq::JAISeqMgr_mixOut_(const JASSoundParams& params, JAISoundActivity activity) {
if (prepare_(params, activity) && inner_.outputTrack.getStatus() == JASTrack::STATUS_RUN) {
mixOut_(params, activity);
}
}
s32 JAISeq::getNumChild() const {
return NUM_CHILDREN;
}
JAISoundChild* JAISeq::getChild(int index) {
JUT_ASSERT(371, status_.isAlive());
JUT_ASSERT(372, index >= 0);
JUT_ASSERT(373, index < NUM_CHILDREN);
if (inner_.mSoundChild[index]) {
return inner_.mSoundChild[index];
}
inner_.mSoundChild[index] = new JAISoundChild();
if (!inner_.mSoundChild[index]) {
JUT_WARN(379, "%s", "JASPoolAllocObject::<JAISoundChild>::operator new failed .\n");
return NULL;
}
return inner_.mSoundChild[index];
}
void JAISeq::releaseChild(int index) {
if (inner_.outputTrack.getStatus() == JASTrack::STATUS_RUN && inner_.mSoundChild[index]) {
JASTrack* track = getChildTrack(index);
if (track) {
track->assignExtBuffer(0, NULL);
}
delete inner_.mSoundChild[index];
inner_.mSoundChild[index] = NULL;
}
}
JASTrack* JAISeq::getTrack() {
return &inner_.outputTrack;
}
JASTrack* JAISeq::getChildTrack(int param_0) {
u32 index = u32(param_0) >> 4;
JASTrack* track = inner_.outputTrack.getChild(index);
if (track) {
u32 var_r28 = param_0 - (index << 4);
JASTrack* track2 = track->getChild(var_r28);
return track2;
}
return NULL;
}
JAISeq* JAISeq::asSeq() {
return this;
}
JAITempoMgr* JAISeq::getTempoMgr() {
return &inner_.mTempoMgr;
}
@@ -0,0 +1,9 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAISeqDataMgr.h"
JAISeqDataUser::~JAISeqDataUser() {}
JAISeqDataMgr::~JAISeqDataMgr() {
JUT_ASSERT(14, false);
}
+143
View File
@@ -0,0 +1,143 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAISeqMgr.h"
#include "JSystem/JAudio2/JAISeq.h"
#include "JSystem/JAudio2/JAISoundHandles.h"
#include "JSystem/JAudio2/JAISoundInfo.h"
bool JAISeqMgr::isUsingSeqData(const JAISeqDataRegion& seqDataRegion) {
JSULink<JAISeq>* link;
for (link = mSeqList.getFirst(); link != NULL; link = link->getNext()) {
if (seqDataRegion.intersects(link->getObject()->getSeqData())) {
return true;
}
}
return false;
}
int JAISeqMgr::releaseSeqData(const JAISeqDataRegion& seqDataRegion) {
bool bVar1 = false;
JSULink<JAISeq>* link;
for (link = mSeqList.getFirst(); link != NULL; link = link->getNext()) {
if (seqDataRegion.intersects(link->getObject()->getSeqData())) {
link->getObject()->stop();
bVar1 = true;
}
}
return bVar1 ? RELEASE_SEQ_1 : RELEASE_SEQ_2;
}
JAISeqMgr::JAISeqMgr(bool setInstance) : JASGlobalInstance<JAISeqMgr>(setInstance), mAudience(NULL) {
seqDataMgr_ = NULL;
field_0x10 = NULL;
field_0x70 = 16;
mMove.init();
mActivity.init();
}
void JAISeqMgr::freeDeadSeq_() {
JSULink<JAISeq>* i = mSeqList.getFirst();
while (i != NULL) {
JAISeq* seq = i->getObject();
JSULink<JAISeq>* next = i->getNext();
if (seq->status_.isDead()) {
mSeqList.remove(i);
delete seq;
}
i = next;
}
}
bool JAISeqMgr::startSound(JAISoundID id, JAISoundHandle* handle, const JGeometry::TVec3<f32>* posPtr) {
if (handle != NULL && *handle) {
(*handle)->stop();
}
JAISoundInfo* soundInfo = JASGlobalInstance<JAISoundInfo>::getInstance();
int category = (soundInfo != NULL) ? soundInfo->getCategory(id) : -1;
JAISeqData seqData(NULL, 0);
JUT_ASSERT(81, seqDataMgr_);
if (seqDataMgr_->getSeqData(id, &seqData) == JAISeqDataMgr::SeqDataReturnValue_0) {
return false;
}
JAISeq* seq = beginStartSeq_();
if (seq != NULL) {
seq->JAISeqMgr_startID_(id, posPtr, mAudience, category, field_0x70);
if (endStartSeq_(seq, handle)) {
if (soundInfo != NULL) {
soundInfo->getSeqInfo(id, seq);
}
return true;
}
}
return false;
}
void JAISeqMgr::calc() {
mMove.calc();
JSULink<JAISeq>* i;
for (i = mSeqList.getFirst(); i != NULL; i = i->getNext()) {
i->getObject()->JAISeqMgr_calc_();
}
freeDeadSeq_();
}
void JAISeqMgr::stop() {
JSULink<JAISeq>* i;
for (i = mSeqList.getFirst(); i != NULL; i = i->getNext()) {
i->getObject()->stop();
}
}
void JAISeqMgr::stop(u32 fadeTime) {
JSULink<JAISeq>* i;
for (i = mSeqList.getFirst(); i != NULL; i = i->getNext()) {
i->getObject()->stop(fadeTime);
}
}
void JAISeqMgr::stopSoundID(JAISoundID id) {
JSULink<JAISeq>* i;
if (!id.isAnonymous()) {
for (i = mSeqList.getFirst(); i != NULL; i = i->getNext()) {
if ((u32)i->getObject()->getID() == (u32)id) {
i->getObject()->stop();
}
}
}
}
void JAISeqMgr::mixOut() {
JSULink<JAISeq>* i;
for (i = mSeqList.getFirst(); i != NULL; i = i->getNext()) {
i->getObject()->JAISeqMgr_mixOut_(mMove.params_, mActivity);
}
}
JAISeq* JAISeqMgr::beginStartSeq_() {
JAISeq* seq = new JAISeq(this, field_0x10);
if (seq == NULL) {
JUT_WARN(273, "%s", "JASPoolAllocObject::<JAISeq>::operator new failed .\n");
}
return seq;
}
bool JAISeqMgr::endStartSeq_(JAISeq* seq, JAISoundHandle* handle) {
JAISeq* sound = seq->getObject();
if (sound != NULL) {
if (sound->status_.isAlive()) {
mSeqList.append(seq);
if (handle != NULL) {
sound->attachHandle(handle);
}
return true;
}
delete sound;
}
return false;
}
+215
View File
@@ -0,0 +1,215 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAISound.h"
#include "JSystem/JAudio2/JAIAudience.h"
#include "JSystem/JAudio2/JAISoundHandles.h"
#include "JSystem/JAudio2/JASReport.h"
#include "JSystem/JAudio2/JASTrack.h"
void JAISoundHandle::releaseSound() {
if (sound_ != NULL) {
sound_->handle_ = NULL;
sound_ = NULL;
}
}
void JAISound::releaseHandle() {
if (handle_ != NULL) {
handle_->sound_ = NULL;
handle_ = NULL;
}
}
void JAISound::attachHandle(JAISoundHandle* handle) {
JUT_ASSERT(55, handle);
if (handle->isSoundAttached()) {
handle->getSound()->stop();
}
if (isHandleAttached()) {
releaseHandle();
}
handle_ = handle;
handle_->sound_ = this;
}
s32 JAISoundStatus_::lockWhenPrepared() {
if (state.unk == 0) {
state.unk = 1;
return 1;
}
return 0;
}
s32 JAISoundStatus_::unlockIfLocked() {
if (state.unk == 3) {
state.unk = 4;
return 1;
}
if (state.unk == 1) {
state.unk = 0;
return 1;
}
return 0;
}
void JAISoundParams::mixOutAll(const JASSoundParams& inParams, JASSoundParams* outParams, f32 param_2) {
outParams->mVolume = move_.params_.mVolume * (inParams.mVolume * property_.field_0x0) * param_2;
outParams->mFxMix = move_.params_.mFxMix + (inParams.mFxMix + property_.field_0x4);
outParams->mPitch = move_.params_.mPitch * (inParams.mPitch * property_.field_0x8);
outParams->mPan = (inParams.mPan + move_.params_.mPan) - 0.5f;
outParams->mDolby = inParams.mDolby + move_.params_.mDolby;
}
JAISound::JAISound() : params_() {}
void JAISound::start_JAISound_(JAISoundID id, const JGeometry::TVec3<f32>* posPtr, JAIAudience* audience) {
handle_ = NULL;
soundID_ = id;
status_.init();
params_.init();
fader_.forceIn();
audience_ = audience;
prepareCount_ = 0;
count_ = 0;
if (posPtr != NULL && audience_ != NULL) {
audible_ = audience_->newAudible(*posPtr, soundID_, NULL, 0);
} else {
audible_ = NULL;
}
priority_ = 0;
}
bool JAISound::acceptsNewAudible() const {
bool accepts = false;
if (audible_ == NULL && status_.state.flags.calcedOnce == 0) {
accepts = true;
}
return accepts;
}
void JAISound::newAudible(const JGeometry::TVec3<f32>& pos,
const JGeometry::TVec3<f32>* param_1, u32 param_2, JAIAudience* audience) {
JUT_ASSERT(151, acceptsNewAudible());
if (audience != NULL) {
audience_ = audience;
}
JUT_ASSERT(157, audience_);
audible_ = audience_->newAudible(pos, soundID_, param_1, param_2);
}
void JAISound::stop(u32 fadeTime) {
JUT_ASSERT(164, status_.isAlive());
if (fadeTime == 0) {
stop();
} else {
fader_.fadeOut(fadeTime);
removeLifeTime_();
status_.state.flags.flag5 = 1;
status_.state.flags.flag1 = 1;
}
}
void JAISound::stop() {
stop_JAISound_();
releaseHandle();
}
JAISe* JAISound::asSe() {
return NULL;
}
JAISeq* JAISound::asSeq() {
return NULL;
}
JAIStream* JAISound::asStream() {
return NULL;
}
void JAISound::die_JAISound_() {
if (audible_ != NULL) {
audience_->deleteAudible(audible_);
audible_ = NULL;
audience_ = NULL;
}
fader_.forceOut();
releaseHandle();
status_.state.unk = 6;
}
void JAISound::increasePrepareCount_JAISound_() {
if ((++prepareCount_ & 0xFF) == 0) {
JASReport("It cost %d steps to prepare Sound(ID:%08x, Address%08x).\n", prepareCount_,
*(u32*)&soundID_, this);
}
}
bool JAISound::calc_JAISound_() {
status_.state.flags.calcedOnce = 1;
if (isStopping() && JAISound_tryDie_()) {
return false;
}
JUT_ASSERT(230, status_.isAlive());
bool isPlaying = status_.isPlaying();
if (isPlaying) {
count_++;
}
bool isPaused = status_.isPaused();
if (isPaused == false) {
fader_.calc();
}
bool playing = isPlaying && isPaused == false;
if (playing) {
params_.move_.calc();
if (audible_ != NULL) {
audible_->calc();
}
if (status_.field_0x1.flags.flag2 != 0) {
if (lifeTime_ == 0) {
stop_JAISound_();
} else {
lifeTime_--;
}
}
}
if (audience_ != NULL && audible_ != NULL) {
if ((priority_ = audience_->calcPriority(audible_)) == 0xFFFFFFFF && status_.field_0x1.flags.flag1 == 0) {
stop_JAISound_();
}
} else {
priority_ = 0;
}
return playing;
}
void JAISound::initTrack_JAISound_(JASTrack* track) {
JASSoundParams* soundParams[JASTrack::TChannelMgr::CHANNEL_MAX];
JUT_ASSERT(286, audience_);
JUT_ASSERT(287, audible_);
int numChannels = 0;
JUT_ASSERT(290, audience_->getMaxChannels() < JASTrack::TChannelMgr::CHANNEL_MAX);
for (int i = 0; i < audience_->getMaxChannels(); i++) {
JASSoundParams* currentParams = audible_->getOuterParams(i);
if (currentParams != NULL) {
soundParams[numChannels++] = currentParams;
}
}
JUT_ASSERT(298, numChannels >= 1);
track->setChannelMgrCount(numChannels);
for (u32 i = 0; i < track->getChannelMgrCount(); i++) {
track->assignExtBuffer(i, soundParams[i]);
}
}
@@ -0,0 +1,18 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAISoundChild.h"
#include "JSystem/JAudio2/JASTrack.h"
void JAISoundChild::init() {
mMove.init();
mParams.init();
}
void JAISoundChild::mixOut(JASTrack* track) {
mParams = mMove.params_;
track->assignExtBuffer(0, &mParams);
}
void JAISoundChild::calc() {
mMove.calc();
}
@@ -0,0 +1,25 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAISoundHandles.h"
JAISoundHandle* JAISoundHandles::getHandleSoundID(JAISoundID id) {
for (int i = 0; i < numHandles_; i++) {
if (handle_[i].isSoundAttached()) {
if (handle_[i]->getID() == id) {
return &handle_[i];
}
}
}
return NULL;
}
JAISoundHandle* JAISoundHandles::getFreeHandle() {
for (int i = 0; i < numHandles_; i++) {
if (!handle_[i].isSoundAttached()) {
return &handle_[i];
}
}
return NULL;
}
@@ -0,0 +1,9 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAISoundInfo.h"
JAISoundInfo::JAISoundInfo(bool setInstance) : JASGlobalInstance<JAISoundInfo>(setInstance) {}
JAISoundInfo::~JAISoundInfo() {
JUT_ASSERT(14, false);
}
@@ -0,0 +1,50 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAISoundParams.h"
void JAISoundParamsMove::moveVolume(f32 newValue, u32 maxSteps) {
JUT_ASSERT(12, (newValue>=0.f));
if (maxSteps == 0) {
params_.mVolume = newValue;
transition_.volume_.remainingSteps_ = 0;
} else {
transition_.volume_.set(newValue, params_.mVolume, maxSteps);
}
}
void JAISoundParamsMove::movePitch(f32 newValue, u32 maxSteps) {
JUT_ASSERT(27, (newValue>=0.f));
if (maxSteps == 0) {
params_.mPitch = newValue;
transition_.pitch_.remainingSteps_ = 0;
} else {
transition_.pitch_.set(newValue, params_.mPitch, maxSteps);
}
}
void JAISoundParamsMove::moveFxMix(f32 newValue, u32 maxSteps) {
if (maxSteps == 0) {
params_.mFxMix = newValue;
transition_.fxMix_.remainingSteps_ = 0;
} else {
transition_.fxMix_.set(newValue, params_.mFxMix, maxSteps);
}
}
void JAISoundParamsMove::movePan(f32 newValue, u32 maxSteps) {
if (maxSteps == 0) {
params_.mPan = newValue;
transition_.pan_.remainingSteps_ = 0;
} else {
transition_.pan_.set(newValue, params_.mPan, maxSteps);
}
}
void JAISoundParamsMove::moveDolby(f32 newValue, u32 maxSteps) {
if (maxSteps == 0) {
params_.mDolby = newValue;
transition_.dolby_.remainingSteps_ = 0;
} else {
transition_.dolby_.set(newValue, params_.mDolby, maxSteps);
}
}
@@ -0,0 +1,29 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAISoundStarter.h"
#include "JSystem/JAudio2/JAISoundHandles.h"
JAISoundStarter::JAISoundStarter(bool setInstance) :
JASGlobalInstance<JAISoundStarter>(setInstance) {}
JAISoundStarter::~JAISoundStarter() {}
bool JAISoundStarter::startLevelSound(JAISoundID id, JAISoundHandle* handlePtr, const JGeometry::TVec3<f32>* posPtr) {
JUT_ASSERT(20, handlePtr);
JAISoundHandle* handlePtr2 = handlePtr;
if (*handlePtr2) {
if ((*handlePtr2)->getID() == id) {
(*handlePtr2)->updateLifeTime(1);
if (posPtr != NULL) {
(*handlePtr2)->setPos(*posPtr);
}
return true;
}
}
bool rt = startSound(id, handlePtr, posPtr);
if (rt && *handlePtr2) {
(*handlePtr2)->setLifeTime(1, false);
}
return rt;
}
+281
View File
@@ -0,0 +1,281 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAIStream.h"
#include "JSystem/JAudio2/JAIStreamMgr.h"
#include "JSystem/JAudio2/JAISoundChild.h"
#include "JSystem/JAudio2/JAIStreamDataMgr.h"
#include "JSystem/JAudio2/JAIAudience.h"
static void JAIStream_JASAramStreamCallback_(u32 type, JASAramStream* aramStream, void* userData) {
JAIStream* stream = (JAIStream*)userData;
switch (type) {
case 1:
stream->field_0x2c5 = 1;
break;
case 0:
stream->field_0x2c6 = 1;
break;
}
}
JAIStream::JAIStream(JAIStreamMgr* streamMgr, JAISoundStrategyMgr<JAIStream>* soundStrategyMgr) : JSULink<JAIStream>(this) {
field_0x290 = 0;
field_0x2c0 = soundStrategyMgr;
streamMgr_ = streamMgr;
streamAramAddr_ = 0;
field_0x2c5 = 0;
field_0x2c6 = 0;
for (int i = 0; i < NUM_CHILDREN; i++) {
children_[i] = NULL;
}
}
void JAIStream::JAIStreamMgr_startID_(JAISoundID id, s32 streamFileEntry,
const JGeometry::TVec3<f32>* posPtr, JAIAudience* audience,
int category) {
field_0x298 = category;
field_0x294 = streamFileEntry;
start_JAISound_(id, posPtr, audience);
field_0x290 = 0;
if (field_0x2c0 != NULL) {
field_0x2bc = field_0x2c0->calc(id);
} else {
field_0x2bc = NULL;
}
}
bool JAIStream::prepare_prepareStream_() {
u32 local_28;
JAIStreamAramMgr* streamAramMgr;
switch (field_0x290) {
case 0:
streamAramMgr = streamMgr_->getStreamAramMgr();
JUT_ASSERT(100, streamAramMgr);
streamAramAddr_ = streamAramMgr->newStreamAram(&local_28);
if (streamAramAddr_ != NULL) {
inner_.aramStream_.init((u32)streamAramAddr_, local_28, &JAIStream_JASAramStreamCallback_, this);
field_0x290 = 1;
prepareCount_ = 0;
} else {
increasePrepareCount_JAISound_();
}
break;
case 1:
if (audible_ != NULL) {
JASSoundParams* soundParams = audible_->getOuterParams(0);
inner_.aramStream_.setPitch(soundParams->mPitch);
inner_.aramStream_.setVolume(soundParams->mVolume);
inner_.aramStream_.setPan(soundParams->mPan);
inner_.aramStream_.setFxmix(soundParams->mFxMix);
inner_.aramStream_.setDolby(soundParams->mDolby);
}
field_0x2c5 = 0;
if (inner_.aramStream_.prepare(field_0x294, -1)) {
field_0x290 = 2;
}
break;
case 2:
if (field_0x2c5 != 0) {
field_0x2c5 = 0;
field_0x290 = 3;
} else {
increasePrepareCount_JAISound_();
}
break;
case 3:
return true;
case 4:
JUT_WARN(155, "%s", "PC must not pass here.");
break;
}
return false;
}
void JAIStream::prepare_() {
if (field_0x2c6 != 0) {
return;
}
switch(status_.state.unk) {
case 6:
JUT_ASSERT(171, false);
break;
case 0:
if (prepare_prepareStream_()) {
status_.state.unk = 5;
prepare_startStream_();
}
break;
case 1:
if (prepare_prepareStream_()) {
status_.state.unk = 3;
}
break;
case 4:
status_.state.unk = 5;
prepare_startStream_();
break;
case 5:
break;
}
}
void JAIStream::prepare_startStream_() {
if (inner_.aramStream_.start()) {
field_0x2c6 = 0;
field_0x2c4 = 0;
field_0x290 = 4;
}
}
void JAIStream::JAIStreamMgr_mixOut_(const JASSoundParams& inParams, JAISoundActivity activity) {
bool local_54;
JASSoundParams outParams;
params_.mixOutAll(inParams, &outParams, (status_.isMute() || activity.field_0x0.flags.flag1) ? 0.0f : fader_.getIntensity());
if (field_0x2bc != NULL) {
field_0x2bc->virtual4(this, outParams);
}
JASSoundParams* mixParams = &outParams;
if (audible_ != NULL && audience_ != NULL) {
for (int i = 0; i < audience_->getMaxChannels(); i++) {
JASSoundParams* outerParams = audible_->getOuterParams(i);
if (outerParams != NULL) {
audience_->mixChannelOut(outParams, audible_, i);
mixParams = outerParams;
break;
}
}
}
for (int i = 0; i < NUM_CHILDREN; i++) {
inner_.aramStream_.setPitch(mixParams->mPitch);
if (children_[i] != NULL) {
inner_.aramStream_.setChannelVolume(i, children_[i]->mMove.params_.mVolume * mixParams->mVolume);
inner_.aramStream_.setChannelPan(i, (children_[i]->mMove.params_.mPan + mixParams->mPan) - 0.5f);
inner_.aramStream_.setChannelFxmix(i, children_[i]->mMove.params_.mFxMix + mixParams->mFxMix);
inner_.aramStream_.setChannelDolby(i, children_[i]->mMove.params_.mDolby + mixParams->mDolby);
} else {
inner_.aramStream_.setChannelVolume(i, mixParams->mVolume);
inner_.aramStream_.setChannelPan(i, mixParams->mPan);
inner_.aramStream_.setChannelFxmix(i, mixParams->mFxMix);
inner_.aramStream_.setChannelDolby(i, mixParams->mDolby);
}
}
prepare_();
if (field_0x290 == 4) {
local_54 = status_.isPaused() || activity.field_0x0.flags.flag2;
if (local_54 != field_0x2c4) {
inner_.aramStream_.pause(local_54);
field_0x2c4 = local_54;
}
}
}
void JAIStream::die_JAIStream_() {
die_JAISound_();
for (int i = 0; i < NUM_CHILDREN; i++) {
if (children_[i] != NULL) {
delete children_[i];
children_[i] = NULL;
}
}
if (field_0x2bc != NULL) {
field_0x2c0->virtual4(field_0x2bc);
field_0x2bc = NULL;
}
}
bool JAIStream::JAISound_tryDie_() {
if (field_0x2c6) {
die_JAIStream_();
return true;
}
switch (field_0x290) {
case 0:
case 1:
die_JAIStream_();
return true;
case 2:
case 3:
field_0x290 = 5;
inner_.aramStream_.cancel();
break;
case 4:
field_0x290 = 6;
inner_.aramStream_.stop(10);
break;
}
return false;
}
void JAIStream::JAIStreamMgr_calc_() {
if (field_0x2c6 != 0) {
field_0x290 = 0;
stop_JAISound_();
}
if (calc_JAISound_()) {
for (int i = 0; i < NUM_CHILDREN; i++) {
if (children_[i] != NULL) {
children_[i]->calc();
}
}
if (field_0x2bc != NULL) {
field_0x2bc->calc(this);
}
}
}
s32 JAIStream::getNumChild() const {
return NUM_CHILDREN;
}
JAISoundChild* JAIStream::getChild(int index) {
if (children_[index] == NULL) {
children_[index] = new JAISoundChild();
if (children_[index] == NULL) {
JUT_WARN(370, "%s", "JASPoolAllocObject::<JAISoundChild>::operator new failed .\n")
}
}
return children_[index];
}
void JAIStream::releaseChild(int index) {
if (children_[index] != NULL) {
delete children_[index];
children_[index] = NULL;
}
}
JASTrack* JAIStream::getTrack() {
return NULL;
}
JASTrack* JAIStream::getChildTrack(int param_0) {
return NULL;
}
JAIStream* JAIStream::asStream() {
return this;
}
JAITempoMgr* JAIStream::getTempoMgr() {
return NULL;
}
@@ -0,0 +1,11 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAIStreamDataMgr.h"
JAIStreamDataMgr::~JAIStreamDataMgr() {
JUT_ASSERT(11, false);
}
JAIStreamAramMgr::~JAIStreamAramMgr() {
JUT_ASSERT(16, false);
}
+125
View File
@@ -0,0 +1,125 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAIStreamMgr.h"
#include "JSystem/JAudio2/JAISoundHandles.h"
#include "JSystem/JAudio2/JAIStreamDataMgr.h"
#include "JSystem/JAudio2/JAISoundInfo.h"
JAIStreamMgr::JAIStreamMgr(bool setInstance) : JASGlobalInstance<JAIStreamMgr>(setInstance) {
streamDataMgr_ = NULL;
mStreamAramMgr = NULL;
field_0x6c = NULL;
mAudience = NULL;
mParams.init();
mActivity.init();
}
bool JAIStreamMgr::startSound(JAISoundID id, JAISoundHandle* handle, const JGeometry::TVec3<f32>* posPtr) {
JUT_ASSERT(37, streamDataMgr_);
if (handle != NULL && *handle) {
(*handle)->stop();
}
s32 streamFileEntry = streamDataMgr_->getStreamFileEntry(id);
if (streamFileEntry < 0) {
JUT_WARN(46, "Cannot find the stream file entry for ID:%08x\n", id.id_.composite_)
return false;
}
JAIStream* stream = newStream_();
JAISoundInfo* soundInfo = JASGlobalInstance<JAISoundInfo>::getInstance();
int category = -1;
if (soundInfo != NULL) {
category = soundInfo->getCategory(id);
}
if (stream == NULL) {
return false;
}
stream->JAIStreamMgr_startID_(id, streamFileEntry, posPtr, mAudience, category);
if (soundInfo != NULL) {
soundInfo->getStreamInfo(id, stream);
}
if (handle != NULL) {
stream->attachHandle(handle);
}
return false;
}
void JAIStreamMgr::freeDeadStream_() {
JSULink<JAIStream>* i = mStreamList.getFirst();
while (i != NULL) {
JAIStream* stream = i->getObject();
JSULink<JAIStream>* next = i->getNext();
if (stream->status_.isDead()) {
mStreamList.remove(i);
void* aramAddr = stream->JAIStreamMgr_getAramAddr_();
if (aramAddr != NULL) {
bool result = mStreamAramMgr->deleteStreamAram((u32)aramAddr);
JUT_ASSERT(105, result);
}
delete stream;
}
i = next;
}
}
void JAIStreamMgr::calc() {
JSULink<JAIStream>* i;
mParams.calc();
for (i = mStreamList.getFirst(); i != NULL; i = i->getNext()) {
i->getObject()->JAIStreamMgr_calc_();
}
freeDeadStream_();
}
void JAIStreamMgr::stop() {
JSULink<JAIStream>* i;
for (i = mStreamList.getFirst(); i != NULL; i = i->getNext()) {
i->getObject()->stop();
}
}
void JAIStreamMgr::stop(u32 fadeTime) {
JSULink<JAIStream>* i;
for (i = mStreamList.getFirst(); i != NULL; i = i->getNext()) {
i->getObject()->stop(fadeTime);
}
}
void JAIStreamMgr::stopSoundID(JAISoundID id) {
JSULink<JAIStream>* i;
for (i = mStreamList.getFirst(); i != NULL; i = i->getNext()) {
if ((u32)i->getObject()->getID() == (u32)id) {
i->getObject()->stop();
}
}
}
void JAIStreamMgr::mixOut() {
JSULink<JAIStream>* i;
for (i = mStreamList.getFirst(); i != NULL; i = i->getNext()) {
i->getObject()->JAIStreamMgr_mixOut_(mParams.params_, mActivity);
}
}
JAIStream* JAIStreamMgr::newStream_() {
if (mStreamAramMgr == NULL) {
JUT_WARN(229, "%s", "JAIStreamAramMgr must be set.\n");
return NULL;
}
JAIStream* stream = new JAIStream(this, field_0x6c);
if (stream == NULL) {
JUT_WARN(235, "%s", "JASPoolAllocObject::<JAIStream>::operator new failed .\n");
return NULL;
}
mStreamList.append(stream);
return stream;
}
+366
View File
@@ -0,0 +1,366 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASAiCtrl.h"
#include "JSystem/JAudio2/JASAudioThread.h"
#include "JSystem/JAudio2/JASCalc.h"
#include "JSystem/JAudio2/JASChannel.h"
#include "JSystem/JAudio2/JASCmdStack.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
#include "JSystem/JAudio2/JASDSPChannel.h"
#include "JSystem/JAudio2/JASDSPInterface.h"
#include "JSystem/JAudio2/JASHeapCtrl.h"
#include "JSystem/JAudio2/JASProbe.h"
#include "JSystem/JAudio2/JASReport.h"
#include "JSystem/JAudio2/JASLfo.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
#include "JSystem/JUtility/JUTAssert.h"
#include <ai.h>
#include <os.h>
#include <stdint.h>
s16* JASDriver::sDmaDacBuffer[3];
static u8 data_804507A8 = 3;
s16** JASDriver::sDspDacBuffer;
s32 JASDriver::sDspDacWriteBuffer;
s32 JASDriver::sDspDacReadBuffer;
s32 JASDriver::sDspStatus;
JASDriver::DSPBufCallback JASDriver::sDspDacCallback;
s16* JASDriver::lastRspMadep;
void (*JASDriver::dacCallbackFunc)(s16*, u32);
JASDriver::MixCallback JASDriver::extMixCallback;
u32 JASDriver::sOutputRate;
JASMixMode JASDriver::sMixMode = MIX_MODE_EXTRA;
f32 JASDriver::sDacRate = 32028.5f;
u32 JASDriver::sSubFrames = 0x00000007;
void JASDriver::initAI(void (*param_0)(void)) {
setOutputRate(OUTPUT_RATE_0);
u32 dacSize = getDacSize();
const u32 size = dacSize * 2;
for (int i = 0; i < 3; i++) {
sDmaDacBuffer[i] = new(JASDram, 0x20) s16[dacSize];
JUT_ASSERT(102, sDmaDacBuffer[i])
JASCalc::bzero(sDmaDacBuffer[i], size);
DCStoreRange(sDmaDacBuffer[i], size);
}
sDspDacBuffer = new(JASDram, 0) s16*[data_804507A8];
JUT_ASSERT(113, sDspDacBuffer);
for (int i = 0; i < data_804507A8; i++) {
sDspDacBuffer[i] = new(JASDram, 0x20) s16[getDacSize()];
JUT_ASSERT(119, sDspDacBuffer[i]);
JASCalc::bzero(sDspDacBuffer[i], size);
DCStoreRange(sDspDacBuffer[i], size);
}
sDspDacWriteBuffer = data_804507A8 - 1;
sDspDacReadBuffer = 0;
sDspStatus = 0;
JASChannel::initBankDisposeMsgQueue();
AIInit(NULL);
AIInitDMA((uintptr_t)sDmaDacBuffer[2], size);
BOOL isOutputRate;
if (sOutputRate == 0) {
isOutputRate = FALSE;
} else {
isOutputRate = TRUE;
}
AISetDSPSampleRate((u8)isOutputRate);
AIRegisterDMACallback(param_0);
}
void JASDriver::startDMA() {
AIStartDMA();
}
void JASDriver::stopDMA() {
AIStopDMA();
}
void JASDriver::setOutputRate(JASOutputRate param_0) {
sOutputRate = param_0;
if (param_0 == 0) {
sSubFrames = 7;
sDacRate = 32000.0f;
} else {
sSubFrames = 10;
sDacRate = 48000.0f;
}
sDacRate *= 1.0008897f;
}
const JASDriver::MixFunc JASDriver::sMixFuncs[4] = {
mixMonoTrack,
mixMonoTrackWide,
mixExtraTrack,
mixInterleaveTrack,
};
u32 JASDriver::sSubFrameCounter;
void JASDriver::updateDac() {
static u32 dacp = 0;
s16* r30 = lastRspMadep;
lastRspMadep = NULL;
if (r30) {
AIInitDMA((uintptr_t)r30, getDacSize() * 2);
}
s32 frameSamples = getFrameSamples();
readDspBuffer(sDmaDacBuffer[dacp], frameSamples);
if (sDspStatus == 0) {
finishDSPFrame();
}
if (extMixCallback) {
sMixFuncs[sMixMode](sDmaDacBuffer[dacp], frameSamples, extMixCallback);
}
{
JASCriticalSection cs;
DCStoreRange(sDmaDacBuffer[dacp], getDacSize() * 2);
}
lastRspMadep = sDmaDacBuffer[dacp];
dacp++;
if (dacp >= 3) {
dacp = 0;
}
if (dacCallbackFunc) {
dacCallbackFunc(lastRspMadep, getFrameSamples());
}
}
void JASDriver::updateDSP() {
JASProbe::start(3, "SFR-UPDATE");
JASDsp::invalChannelAll();
#if DEBUG
JASDsp::dspMutex = 1;
#endif
JASPortCmd::execAllCommand();
DSPSyncCallback();
static u32 old_time = 0;
static u32 history[10] = {0x000F4240};
u32 r28 = OSGetTick();
u32 r27 = r28 - old_time;
old_time = r28;
u32 subFrame = getSubFrames();
int r26 = JASAudioThread::getDSPSyncCount();
JUT_ASSERT(254, subFrame <= 10);
history[subFrame - r26] = r27;
if (subFrame != r26 && f32(history[0]) / r27 < 1.1f) {
#if DEBUG
static int killCounter;
JASReport("kill DSP channel", killCounter);
JASDSPChannel::killActiveChannel();
killCounter++;
#else
JASReport("kill DSP channel");
JASDSPChannel::killActiveChannel();
#endif
}
JASChannel::receiveBankDisposeMsg();
JASDSPChannel::updateAll();
#if DEBUG
JASDsp::dspMutex = 0;
#endif
subframeCallback();
f32 freeRun = 32028.5f / getDacRate();
JASLfo::updateFreeRun(freeRun);
JASProbe::stop(3);
sSubFrameCounter++;
}
void JASDriver::readDspBuffer(s16* param_0, u32 param_1) {
s32 nbuf = sDspDacReadBuffer + 1;
if (nbuf == data_804507A8) {
nbuf = 0;
}
if (nbuf == sDspDacWriteBuffer && data_804507A8 >= 3) {
s16 r25 = (s16)sDspDacBuffer[sDspDacReadBuffer][param_1 / 2 - 1];
s16 r24 = (s16)sDspDacBuffer[sDspDacReadBuffer][param_1 - 1];
for (int i = 0; i < param_1; i++) {
sDspDacBuffer[sDspDacReadBuffer][i] = (s16)r25;
}
for (int i = param_1; i < param_1 * 2; i++) {
sDspDacBuffer[sDspDacReadBuffer][i] = (s16)r24;
}
#if DEBUG
JASReport("readDspBuffer nbuf:%d sWBuf:%d BCount:%d stat:%d", nbuf, sDspDacWriteBuffer,
data_804507A8, sDspStatus);
#endif
} else {
sDspDacReadBuffer = nbuf;
DCInvalidateRange(sDspDacBuffer[sDspDacReadBuffer], param_1 * 2 * 2);
}
s16* dacBuffer = sDspDacBuffer[sDspDacReadBuffer];
s16* endDacBuffer = dacBuffer + param_1;
JASCalc::imixcopy(endDacBuffer, dacBuffer, param_0, param_1);
}
u32 sDspUpCount;
void JASDriver::finishDSPFrame() {
static u32 waitcount;
int r30 = sDspDacWriteBuffer + 1;
if (r30 == data_804507A8) {
r30 = 0;
}
if (r30 == sDspDacReadBuffer) {
sDspStatus = 0;
#if DEBUG
if (sDspStatus != 0) {
waitcount = 0;
} else {
waitcount++;
}
if (waitcount != 7) {
return;
}
if (sDspUpCount != 0) {
JUT_WARN(0, "forth DSP return\n");
}
if (sDspUpCount == 0) {
sDspUpCount += 1;
}
JASReport("finishDSPFrame nbuf:%d sWBuf:%d BCount:%d stat:%d", r30, sDspDacWriteBuffer, data_804507A8, sDspStatus);
#else
return;
#endif
}
sDspDacWriteBuffer = r30;
JASAudioThread::setDSPSyncCount(getSubFrames());
JASProbe::start(7, "DSP-MAIN");
u32 r27 = getFrameSamples();
JASDsp::syncFrame(getSubFrames(), u32(sDspDacBuffer[sDspDacWriteBuffer]), u32(sDspDacBuffer[sDspDacWriteBuffer] + r27));
sDspStatus = 1;
updateDSP();
if (sDspDacCallback) {
sDspDacCallback(sDspDacBuffer[sDspDacWriteBuffer], r27);
}
}
void JASDriver::registerMixCallback(MixCallback param_0, JASMixMode param_1) {
extMixCallback = param_0;
sMixMode = param_1;
}
void JASDriver::registDSPBufCallback(DSPBufCallback cb) {
sDspDacCallback = cb;
}
f32 JASDriver::getDacRate() {
return sDacRate;
}
u32 JASDriver::getSubFrames() {
return sSubFrames;
}
u32 JASDriver::getDacSize() {
return sSubFrames * 0x50 * 2;
}
u32 JASDriver::getFrameSamples() {
return sSubFrames * 0x50;
}
void JASDriver::mixMonoTrack(s16* buffer, u32 param_1, MixCallback param_2) {
JASProbe::start(5, "MONO-MIX");
s16* r26 = param_2(param_1);
if (r26 == NULL) {
return;
}
JASProbe::stop(5);
s16* pTrack = buffer;
s16* r28 = r26;
for (u32 i = param_1; i != 0; i--) {
s32 src = pTrack[0];
src += r28[0];
pTrack[0] = JASCalc::clamp<s16, s32>(src);
pTrack++;
src = pTrack[0];
src += r28[0];
pTrack[0] = JASCalc::clamp<s16, s32>(src);
pTrack++;
r28++;
}
}
void JASDriver::mixMonoTrackWide(s16* buffer, u32 param_1, MixCallback param_2) {
JASProbe::start(5, "MONO(W)-MIX");
s16* r26 = param_2(param_1);
if (!r26) {
return;
}
JASProbe::stop(5);
s16* pTrack = buffer;
s16* r28 = r26;
for (u32 i = param_1; i != 0; i--) {
s32 src = pTrack[0];
src += r28[0];
pTrack[0] = JASCalc::clamp<s16, s32>(src);
pTrack++;
src = pTrack[0];
src -= r28[0];
pTrack[0] = JASCalc::clamp<s16, s32>(src);
pTrack++;
r28++;
}
}
void JASDriver::mixExtraTrack(s16* buffer, u32 param_1, MixCallback param_2) {
JASProbe::start(5, "DSPMIX");
s16* r27 = param_2(param_1);
if (!r27) {
return;
}
JASProbe::stop(5);
JASProbe::start(6, "MIXING");
s16* pTrack = buffer;
s16* r29 = r27;
s16* r28 = r27 + getFrameSamples();
for (u32 i = param_1; i != 0; i--) {
s32 r25 = pTrack[0] + r28[0];
pTrack[0] = JASCalc::clamp<s16, s32>(r25);
pTrack++;
r25 = pTrack[0] + r29[0];
pTrack[0] = JASCalc::clamp<s16, s32>(r25);
pTrack++;
r28++;
r29++;
}
JASProbe::stop(6);
}
void JASDriver::mixInterleaveTrack(s16* buffer, u32 param_1, MixCallback param_2) {
s16* r31 = param_2(param_1);
if (!r31) {
return;
}
s16* pTrack = buffer;
s16* r30 = r31;
for (u32 i = param_1 * 2; i != 0; i--) {
s32 r26 = pTrack[0] + r30[0];
pTrack[0] = JASCalc::clamp<s16, s32>(r26);
pTrack++;
r30++;
}
}
u32 JASDriver::getSubFrameCounter() {
return sSubFrameCounter;
}
+697
View File
@@ -0,0 +1,697 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASAramStream.h"
#include "JSystem/JAudio2/JASAiCtrl.h"
#include "JSystem/JAudio2/JASChannel.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
#include "JSystem/JAudio2/JASDriverIF.h"
#include "JSystem/JAudio2/JASDSPInterface.h"
#include "JSystem/JAudio2/JASDvdThread.h"
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
#include "JSystem/JSupport/JSupport.h"
JASTaskThread* JASAramStream::sLoadThread;
u8* JASAramStream::sReadBuffer;
u32 JASAramStream::sBlockSize;
u32 JASAramStream::sChannelMax;
bool struct_80451260;
bool struct_80451261;
void JASAramStream::initSystem(u32 block_size, u32 channel_max) {
JUT_ASSERT(66, block_size % 32 == 0);
JUT_ASSERT(67, block_size % 9 == 0);
JUT_ASSERT(68, channel_max > 0 && channel_max <= CHANNEL_MAX);
JUT_ASSERT(69, sReadBuffer == 0);
if (!JASDriver::registerSubFrameCallback(dvdErrorCheck, NULL)) {
JUT_WARN(72, "%s", "registerSubFrameCallback Failed");
} else {
if (sLoadThread == NULL) {
sLoadThread = JASDvd::getThreadPointer();
}
sReadBuffer = new (JASDram, 0x20) u8[(block_size + 0x20) * channel_max];
JUT_ASSERT(79, sReadBuffer);
sBlockSize = block_size;
sChannelMax = channel_max;
struct_80451260 = false;
struct_80451261 = false;
}
}
JASAramStream::JASAramStream() {
field_0x0a8 = NULL;
field_0x0ac = false;
field_0x0ad = false;
field_0x0ae = 0;
field_0x0b0 = 0;
field_0x0b4 = 0;
field_0x0b8 = 0;
field_0x0bc = 0;
field_0x0c0 = false;
field_0x0c4 = 0;
field_0x0c8 = 0.0f;
field_0x108 = 0;
field_0x10c = 0;
mBlock = 0;
field_0x114 = 0;
field_0x118 = 0;
field_0x12c = 0;
field_0x148 = 0;
field_0x14c = 0;
mCallback = NULL;
mCallbackData = NULL;
field_0x158 = 0;
mChannelNum = 0;
mBufCount = 0;
field_0x160 = 0;
field_0x164 = 0;
mLoop = false;
mLoopStart = 0;
mLoopEnd = 0;
mVolume = 1.0f;
mPitch = 1.0f;
for (int i = 0; i < 6; i++) {
mChannels[i] = NULL;
field_0x130[i] = 0;
field_0x13c[i] = 0;
mChannelVolume[i] = 1.0f;
mChannelPan[i] = 0.5f;
mChannelFxMix[i] = 0.0f;
mChannelDolby[i] = 0.0f;
}
for (int i = 0; i < 6; i++) {
field_0x1dc[i] = 0;
}
}
void JASAramStream::init(u32 param_0, u32 param_1, StreamCallback i_callback, void* i_callbackData) {
JUT_ASSERT(153, sReadBuffer != NULL);
field_0x148 = param_0;
field_0x14c = param_1;
field_0x0c8 = 0.0f;
field_0x0ae = 0;
field_0x0ac = false;
field_0x0ad = false;
field_0x114 = 0;
mChannelNum = 0;
for (int i = 0; i < 6; i++) {
mChannelVolume[i] = 1.0f;
mChannelPan[i] = 0.5f;
mChannelFxMix[i] = 0.0f;
mChannelDolby[i] = 0.0f;
}
mVolume = 1.0f;
mPitch = 1.0f;
field_0x1dc[0] = 0xffff;
mCallback = i_callback;
mCallbackData = i_callbackData;
OSInitMessageQueue(&field_0x000, field_0x040, 0x10);
OSInitMessageQueue(&field_0x020, field_0x080, 4);
}
bool JASAramStream::prepare(s32 param_0, int param_1) {
if (!DVDFastOpen(param_0, &mDvdFileInfo)) {
JUT_WARN(240, "%s", "DVDFastOpen Failed");
return false;
}
if (!JASDriver::registerSubFrameCallback(channelProcCallback, this)) {
JUT_WARN(245, "%s", "registerSubFrameCallback Failed");
return false;
}
TaskData data;
data.stream = this;
data.field_0x4 = field_0x14c;
data.field_0x8 = param_1;
if (!sLoadThread->sendCmdMsg(headerLoadTask, &data, 0xc)) {
JUT_WARN(254, "%s", "sendCmdMsg headerLoadTask Failed");
JASDriver::rejectCallback(channelProcCallback, this);
return false;
}
return true;
}
bool JASAramStream::start() {
if (!OSSendMessage(&field_0x000, (OSMessage)0, OS_MESSAGE_NOBLOCK)) {
JUT_WARN(273, "%s", "OSSendMessage Failed")
return false;
}
return true;
}
bool JASAramStream::stop(u16 param_0) {
if (!OSSendMessage(&field_0x000, (OSMessage)(uintptr_t)(param_0 << 0x10 | 1), OS_MESSAGE_NOBLOCK)) {
JUT_WARN(290, "%s", "OSSendMessage Failed");
return false;
}
return true;
}
bool JASAramStream::pause(bool param_0) {
OSMessage msg = param_0 ? (OSMessage)2 : (OSMessage)3;
if (!OSSendMessage(&field_0x000, msg, OS_MESSAGE_NOBLOCK)) {
JUT_WARN(308, "%s", "OSSendMessage Failed");
return false;
}
return true;
}
bool JASAramStream::cancel() {
field_0x114 = 1;
if (!sLoadThread->sendCmdMsg(finishTask, this)) {
JUT_WARN(326, "%s", "sendCmdMsg finishTask Failed");
return false;
}
return true;
}
u32 JASAramStream::getBlockSamples() const {
return field_0x158 == 0 ? (sBlockSize << 4) / 9 : sBlockSize >> 1;
}
void JASAramStream::headerLoadTask(void* i_data) {
TaskData* data = (TaskData*)i_data;
data->stream->headerLoad(data->field_0x4, data->field_0x8);
}
void JASAramStream::firstLoadTask(void* i_data) {
TaskData* data = (TaskData*)i_data;
JASAramStream* _this = data->stream;
if (!_this->load()) {
return;
}
if (data->field_0x8 > 0) {
data->field_0x8--;
if (data->field_0x8 == 0) {
if (!sLoadThread->sendCmdMsg(prepareFinishTask, _this)) {
JUT_WARN(364, "%s", "sendCmdMsg prepareFinishTask Failed");
struct_80451261 = true;
}
}
}
if (data->field_0x4 != 0) {
data->field_0x4--;
if (!sLoadThread->sendCmdMsg(firstLoadTask, data, 0xc)) {
JUT_WARN(372, "%s", "sendCmdMsg firstLoadTask Failed");
struct_80451261 = true;
}
JASCriticalSection cs;
_this->field_0x118++;
}
}
void JASAramStream::loadToAramTask(void* i_this) {
JASAramStream* stream = (JASAramStream*)i_this;
stream->load();
}
void JASAramStream::finishTask(void* i_this) {
JASAramStream* _this = (JASAramStream*)i_this;
if (!JASDriver::rejectCallback(channelProcCallback, _this)) {
JUT_WARN(392, "%s", "rejectSubFrameCallback Failed");
}
if (_this->mCallback != NULL) {
_this->mCallback(CB_START, _this, _this->mCallbackData);
_this->mCallback = NULL;
}
}
void JASAramStream::prepareFinishTask(void* i_this) {
JASAramStream* _this = (JASAramStream*)i_this;
OSSendMessage(&_this->field_0x020, (OSMessage)4, OS_MESSAGE_BLOCK);
if (_this->mCallback != NULL) {
_this->mCallback(CB_STOP, _this, _this->mCallbackData);
}
}
bool JASAramStream::headerLoad(u32 param_0, int param_1) {
if (struct_80451261) {
return false;
}
if (field_0x114 != 0) {
return false;
}
if (DVDReadPrio(&mDvdFileInfo, sReadBuffer, sizeof(Header), 0, 1) < 0) {
JUT_WARN(420, "%s", "DVDReadPrio Failed");
struct_80451261 = true;
return false;
}
Header* header = (Header*)sReadBuffer;
JUT_ASSERT(426, header->tag == 'STRM');
JUT_ASSERT(427, header->format <= 1);
JUT_ASSERT(428, header->bits == 16);
JUT_ASSERT(429, header->channels <= sChannelMax);
JUT_ASSERT(430, header->block_size == sBlockSize);
field_0x158 = header->format;
mChannelNum = header->channels;
field_0x164 = header->field_0x10;
mLoop = header->loop != 0;
mLoopStart = header->loop_start;
mLoopEnd = header->loop_end;
mVolume = header->field_0x28 / 127.0f;
field_0x118 = 0;
mBlock = 0;
field_0x10c = 0;
field_0x160 = (param_0 / sBlockSize) / header->channels;
mBufCount = field_0x160;
JUT_ASSERT(445, mBufCount > 0);
mBufCount--;
if (mBufCount < 3) {
JUT_WARN(449, "%s", "Too few Buffer-Size");
}
field_0x108 = mBufCount;
u32 local_2c = (mLoopEnd - 1) / getBlockSamples();
if (local_2c <= mBufCount && mLoop) {
JUT_WARN(458, "%s", "Too few samples for Loop-buffer");
}
if (param_1 < 0 || param_1 > field_0x108) {
param_1 = field_0x108;
}
if (field_0x114 != 0) {
return false;
}
TaskData data;
data.stream = this;
data.field_0x4 = field_0x108 - 1;
data.field_0x8 = param_1;
if (!sLoadThread->sendCmdMsg(firstLoadTask, &data, 0xc)) {
JUT_WARN(472, "%s", "sendCmdMsg firstLoadTask Failed");
struct_80451261 = true;
return false;
}
JASCriticalSection cs;
field_0x118++;
return true;
}
bool JASAramStream::load() {
{
JASCriticalSection cs;
field_0x118--;
}
if (struct_80451261) {
return false;
}
if (field_0x114 != 0) {
return false;
}
u32 loop_end_block = (mLoopEnd - 1) / getBlockSamples();
u32 loop_start_block = mLoopStart / getBlockSamples();
if (mBlock > loop_end_block) {
return false;
}
u32 offset = mBlock * (sBlockSize * mChannelNum + sizeof(BlockHeader)) + sizeof(Header);
u32 size = sBlockSize * mChannelNum + sizeof(BlockHeader);
if (mBlock == loop_end_block) {
size = mDvdFileInfo.length - offset;
}
if (DVDReadPrio(&mDvdFileInfo, sReadBuffer, size, offset, 1) < 0) {
JUT_WARN(507, "%s", "DVDReadPrio Failed");
struct_80451261 = true;
return false;
}
BlockHeader* bhead = (BlockHeader*)sReadBuffer;
JUT_ASSERT(512, bhead->tag == 'BLCK');
if (field_0x114 != 0) {
return false;
}
u32 sp08 = field_0x148 + field_0x10c * sBlockSize;
for (int i = 0; i < mChannelNum; i++) {
(void)i;
// Fakematch? It seems the only way to get the bhead->field_0x4 load in the right order is
// with a pointer cast on its address in one of the two places it is read, but not both.
if (!JKRMainRamToAram(sReadBuffer + *(u32*)&bhead->field_0x4 * i + sizeof(BlockHeader),
sp08 + sBlockSize * field_0x160 * i,
bhead->field_0x4, EXPAND_SWITCH_UNKNOWN0, 0, NULL, -1, NULL)) {
JUT_WARN(522, "%s", "JKRMainRamToAram Failed");
struct_80451261 = 1;
return false;
}
}
field_0x10c++;
if (field_0x10c >= field_0x108) {
u32 r28 = mBlock;
r28 += field_0x108 - 1;
if (mLoop) {
JUT_ASSERT(537, loop_start_block < loop_end_block);
while (r28 > loop_end_block) {
r28 -= loop_end_block;
r28 += loop_start_block;
}
}
if (r28 == loop_end_block || r28 + 2 == loop_end_block) {
field_0x108 = field_0x160;
OSSendMessage(&field_0x020, (OSMessage)5, OS_MESSAGE_BLOCK);
} else {
field_0x108 = field_0x160 - 1;
}
for (int i = 0; i < mChannelNum; i++) {
field_0x130[i] = (s16)bhead->field_0x8[i].field_0x0;
field_0x13c[i] = (s16)bhead->field_0x8[i].field_0x2;
}
field_0x10c = 0;
}
mBlock++;
if (mBlock > loop_end_block && mLoop) {
mBlock = loop_start_block;
}
return true;
}
s32 JASAramStream::channelProcCallback(void* i_this) {
JASAramStream* stream = (JASAramStream*)i_this;
return stream->channelProc();
}
s32 JASAramStream::dvdErrorCheck(void* param_0) {
s32 status = DVDGetDriveStatus();
switch (status) {
case DVD_STATE_END:
struct_80451260 = false;
break;
case DVD_STATE_BUSY:
break;
case DVD_STATE_WAITING:
case DVD_STATE_COVER_CLOSED:
case DVD_STATE_NO_DISK:
case DVD_STATE_WRONG_DISK:
case DVD_STATE_MOTOR_STOPPED:
case DVD_STATE_IGNORED:
case DVD_STATE_CANCELED:
case DVD_STATE_RETRY:
case DVD_STATE_FATAL_ERROR:
default:
struct_80451260 = true;
break;
}
return 0;
}
void JASAramStream::channelCallback(u32 i_callbackType, JASChannel* i_channel,
JASDsp::TChannel* i_dspChannel, void* i_this) {
JASAramStream* stream = (JASAramStream*)i_this;
stream->updateChannel(i_callbackType, i_channel, i_dspChannel);
}
void JASAramStream::updateChannel(u32 i_callbackType, JASChannel* i_channel,
JASDsp::TChannel* i_dspChannel) {
u32 block_samples = getBlockSamples();
switch (i_callbackType) {
case JASChannel::CB_START:
if (field_0x0a8 == NULL) {
field_0x0a8 = i_channel;
field_0x0b4 = block_samples * mBufCount;
field_0x0b8 = 0;
field_0x0b0 = 0;
field_0x0bc = (mLoopEnd - 1) / block_samples;
field_0x0c0 = 0;
field_0x0c4 = 0;
field_0x12c = 0;
}
break;
case JASChannel::CB_PLAY:
if (i_dspChannel->field_0x008 == 0) {
if (i_channel == field_0x0a8) {
field_0x12c = 0;
u32 sp28 = i_dspChannel->field_0x074 + i_dspChannel->field_0x064;
if (sp28 <= field_0x0b4) {
field_0x0b8 += field_0x0b4 - sp28;
} else {
if (!field_0x0c0) {
field_0x0b8 += field_0x0b4;
field_0x0b8 += block_samples * mBufCount - sp28;
} else {
field_0x0b8 += field_0x0b4;
field_0x0b8 += block_samples * mBufCount - sp28
- i_dspChannel->field_0x110;
field_0x0b8 -= mLoopEnd;
field_0x0b8 += mLoopStart;
i_dspChannel->field_0x110 = 0;
field_0x120 = 0;
field_0x12c |= 2;
if (field_0x0c4 < 0xffffffff) {
field_0x0c4++;
}
field_0x0c0 = false;
}
}
if (field_0x0b8 > mLoopEnd) {
JUT_WARN(686, "%s", "mReadSample > mLoopEnd");
struct_80451261 = true;
}
f32 fvar1 = field_0x0c4;
fvar1 *= mLoopEnd - mLoopStart;
if (field_0x0c4 < 0xffffffff) {
fvar1 += field_0x0b8;
}
fvar1 /= field_0x164;
field_0x0c8 = fvar1;
if (field_0x0b8 + 400 >= mLoopEnd && !field_0x0c0) {
if (mLoop) {
u32 uvar5 = field_0x0bc + 1;
if (uvar5 >= mBufCount) {
uvar5 = 0;
}
i_dspChannel->field_0x110 = mLoopStart % block_samples
+ uvar5 * block_samples;
field_0x120 = i_dspChannel->field_0x110;
field_0x12c |= 2;
} else {
i_dspChannel->field_0x102 = 0;
field_0x128 = 0;
field_0x12c |= 8;
}
int sp20 = field_0x0bc * block_samples + mLoopEnd % block_samples;
i_dspChannel->field_0x074 -= block_samples * mBufCount - sp20;
field_0x11c = i_dspChannel->field_0x074;
field_0x12c |= 1;
field_0x0bc += (mLoopEnd - 1) / block_samples - mLoopStart / block_samples + 1;
field_0x0c0 = true;
}
u32 uvar4 = i_dspChannel->field_0x070 - i_channel->field_0x104;
if (uvar4 != 0) {
uvar4--;
}
u32 sp18 = uvar4 / sBlockSize;
u32 sp14 = (mLoopEnd - 1) / getBlockSamples();
if (sp18 != field_0x0b0) {
bool cmp = sp18 < field_0x0b0;
while (sp18 != field_0x0b0) {
if (!sLoadThread->sendCmdMsg(loadToAramTask, this)) {
JUT_WARN(741, "sendCmdMsg Failed %d %d (%d %d)", i_dspChannel->field_0x070, i_channel->field_0x104, sp18, field_0x0b0);
struct_80451261 = true;
break;
}
{
JASCriticalSection cs;
field_0x118++;
}
field_0x0b0++;
if (field_0x0b0 >= mBufCount) {
field_0x0b0 = 0;
}
}
if (cmp) {
field_0x0bc -= mBufCount;
if (field_0x0ad) {
if (!field_0x0c0) {
i_dspChannel->field_0x074 += block_samples;
field_0x11c = i_dspChannel->field_0x074;
field_0x12c |= 1;
}
i_dspChannel->field_0x114 += block_samples;
field_0x124 = i_dspChannel->field_0x114;
field_0x12c |= 4;
mBufCount = field_0x160;
field_0x0ad = false;
} else {
if (mBufCount != field_0x160 - 1) {
mBufCount = field_0x160 - 1;
i_dspChannel->field_0x114 -= block_samples;
field_0x124 = i_dspChannel->field_0x114;
field_0x12c |= 4;
if (!field_0x0c0) {
i_dspChannel->field_0x074 -= block_samples;
field_0x11c = i_dspChannel->field_0x074;
field_0x12c |= 1;
}
}
}
}
} else {
if (field_0x118 == 0 && !struct_80451260) {
field_0x0ae &= ~2;
field_0x0ae &= ~4;
}
}
field_0x0b4 = i_dspChannel->field_0x074 + i_dspChannel->field_0x064;
if (field_0x118 >= field_0x160 - 2) {
JUT_WARN_DEVICE(810, 1, "%s", "buffer under error");
field_0x0ae |= (u8)4;
}
} else {
if (field_0x12c & 1) {
i_dspChannel->field_0x074 = field_0x11c;
}
if (field_0x12c & 2) {
i_dspChannel->field_0x110 = field_0x120;
}
if (field_0x12c & 4) {
i_dspChannel->field_0x114 = field_0x124;
}
if (field_0x12c & 8) {
i_dspChannel->field_0x102 = field_0x128;
}
}
int ch = 0;
for (; ch < 6; ch++) {
if (i_channel == mChannels[ch]) {
break;
}
}
JUT_ASSERT(834, ch < CHANNEL_MAX);
i_dspChannel->field_0x104 = (s16)field_0x130[ch];
i_dspChannel->field_0x106 = (s16)field_0x13c[ch];
}
break;
case JASChannel::CB_STOP:
bool open_channel = false;
for (int i = 0; i < 6; i++) {
if (i_channel == mChannels[i]) {
mChannels[i] = NULL;
} else if (mChannels[i] != NULL) {
open_channel = true;
}
}
if (!open_channel) {
field_0x114 = 1;
if (!sLoadThread->sendCmdMsg(finishTask, this)) {
JUT_WARN(854, "%s", "sendCmdMsg finishTask Failed");
struct_80451261 = true;
return;
}
}
break;
}
i_channel->setPauseFlag(field_0x0ae != 0);
}
s32 JASAramStream::channelProc() {
OSMessage msg;
while (OSReceiveMessage(&field_0x020, &msg, OS_MESSAGE_NOBLOCK)) {
switch ((u32)msg) {
case 4:
field_0x0ac = true;
break;
case 5:
field_0x0ad = true;
break;
}
}
if (!field_0x0ac) {
return 0;
}
while (OSReceiveMessage(&field_0x000, &msg, OS_MESSAGE_NOBLOCK)) {
switch ((u32)msg & 0xff) {
case 0:
channelStart();
break;
case 1:
channelStop(JSUHiHalf((u32)msg));
break;
case 2:
field_0x0ae |= 1;
break;
case 3:
field_0x0ae &= ~1;
break;
}
}
if (struct_80451261) {
field_0x0ae |= 8;
}
if (struct_80451260) {
field_0x0ae |= 2;
}
for (int i = 0; i < mChannelNum; i++) {
JASChannel* channel = mChannels[i];
if (channel != NULL) {
JASChannelParams params;
params.mVolume = mVolume * mChannelVolume[i];
params.mPitch = mPitch;
params.field_0x8 = 0.0f;
params.mPan = mChannelPan[i];
params.mFxMix = mChannelFxMix[i];
params.mDolby = mChannelDolby[i];
channel->setParams(params);
}
}
return 0;
}
static JASOscillator::Point const OSC_RELEASE_TABLE[2] = {
{0x0000, 0x0002, 0x0000},
{0x000F, 0x0000, 0x0000},
};
static JASOscillator::Data const OSC_ENV = {0, 1.0f, NULL, OSC_RELEASE_TABLE, 1.0f, 0.0f};
void JASAramStream::channelStart() {
u8 r31;
switch (field_0x158) {
case 0:
r31 = 0;
break;
case 1:
r31 = 3;
break;
}
for (int i = 0; i < mChannelNum; i++) {
JASWaveInfo wave_info;
wave_info.field_0x00 = r31;
wave_info.field_0x02 = 0xff;
wave_info.field_0x10 = 0;
wave_info.field_0x14 = mBufCount * getBlockSamples();
wave_info.field_0x18 = wave_info.field_0x14;
wave_info.field_0x1c = 0;
wave_info.field_0x1e = 0;
// probably a fake match, this should be set in the JASWaveInfo constructor
static u32 const one = 1;
wave_info.field_0x20 = &one;
JASChannel* jc = new JASChannel(channelCallback, this);
JUT_ASSERT(963, jc);
jc->setPriority(0x7f7f);
for (u32 j = 0; j < 6; j++) {
jc->setMixConfig(j, field_0x1dc[j]);
}
jc->setInitPitch(field_0x164 / JASDriver::getDacRate());
jc->setOscInit(0, &OSC_ENV);
jc->field_0xdc.field_0x4 = wave_info;
jc->field_0x104 = field_0x148 + sBlockSize * field_0x160 * i;
jc->field_0xdc.field_0x0 = 0;
int ret = jc->playForce();
JUT_ASSERT(977, ret);
JUT_ASSERT_MSG(979, mChannels[i] == NULL, "channelStart for already playing channel");
mChannels[i] = jc;
}
field_0x0a8 = NULL;
}
void JASAramStream::channelStop(u16 i_directRelease) {
for (int i = 0; i < mChannelNum; i++) {
JASChannel* channel = mChannels[i];
if (channel != NULL) {
channel->release(i_directRelease);
}
}
}
@@ -0,0 +1,72 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASAudioReseter.h"
#include "JSystem/JAudio2/JASAudioThread.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
#include "JSystem/JAudio2/JASDriverIF.h"
#include "JSystem/JAudio2/JASDSPChannel.h"
#include <types.h>
JASAudioReseter::JASAudioReseter() {
field_0x0 = 0;
mDoneFlag = true;
mThreadStopFlag = false;
mDSPLevel = JASDriver::getDSPLevel();
}
JASAudioReseter::~JASAudioReseter() {
JUT_ASSERT(28, mDoneFlag);
}
bool JASAudioReseter::start(u32 param_0, bool param_1) {
if (mDoneFlag == false) {
return false;
}
mThreadStopFlag = param_1;
JASCriticalSection critical;
if (!JASDriver::registerDspSyncCallback(callback, this)) {
JUT_WARN(40, "%s", "Failed JASAudioReseter start\n");
return false;
} else {
mDSPLevel = JASDriver::getDSPLevel();
field_0x0 = param_0;
mDoneFlag = false;
return true;
}
}
void JASAudioReseter::resume() {
JUT_ASSERT(55, mDoneFlag);
JUT_ASSERT(56, ! mThreadStopFlag);
JASDriver::setDSPLevel(mDSPLevel);
}
s32 JASAudioReseter::checkDone() const {
return mDoneFlag;
}
s32 JASAudioReseter::calc() {
if (field_0x0==0) {
for (size_t i = 0; i<64; i++) {
JASDSPChannel* handle = JASDSPChannel::getHandle(i);
if (handle->getStatus() == 0) {
handle->drop();
}
}
if (mThreadStopFlag!=false) {
JASAudioThread* pAudioThread = JASGlobalInstance<JASAudioThread>::getInstance();
JUT_ASSERT(78, pAudioThread);
pAudioThread->stop();
}
mDoneFlag = 1;
return -1;
}
field_0x0--;
JASDriver::setDSPLevel(field_0x0 * JASDriver::getDSPLevel() / (field_0x0 + 1));
return 0;
}
s32 JASAudioReseter::callback(void* param_0) {
JASAudioReseter* i_this = (JASAudioReseter*) param_0;
return i_this->calc();
}
+140
View File
@@ -0,0 +1,140 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASAudioThread.h"
#include "JSystem/JAudio2/JASAiCtrl.h"
#include "JSystem/JAudio2/JASDriverIF.h"
#include "JSystem/JAudio2/JASDSPChannel.h"
#include "JSystem/JAudio2/JASDSPInterface.h"
#include "JSystem/JAudio2/JASHeapCtrl.h"
#include "JSystem/JAudio2/JASProbe.h"
#include "JSystem/JAudio2/JASReport.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
#include <dsp.h>
#include <stdint.h>
JASAudioThread::JASAudioThread(int stackSize, int msgCount, u32 threadPriority)
:
JKRThread(JASDram, threadPriority, msgCount, stackSize),
JASGlobalInstance<JASAudioThread>(true)
{
sbPauseFlag = false;
OSInitThreadQueue(&sThreadQueue);
}
void JASAudioThread::create(s32 threadPriority) {
#if PLATFORM_GCN
const int size = 0x1400;
#else
const int size = 0x2800;
#endif
JASAudioThread* pAudioThread = new (JASDram, 0) JASAudioThread(threadPriority, 0x10, size);
JUT_ASSERT(46, pAudioThread);
JKRHeap* pCurrentHeap = JKRGetSystemHeap();
JUT_ASSERT(48, pCurrentHeap);
pAudioThread->setCurrentHeap(pCurrentHeap);
pAudioThread->resume();
}
void JASAudioThread::stop() {
jamMessageBlock((void*)2);
}
volatile int JASAudioThread::snIntCount;
class Lock {
public:
Lock() {
mInterrupts = OSDisableInterrupts();
}
~Lock() {
OSRestoreInterrupts(mInterrupts);
}
private:
BOOL mInterrupts;
};
class JASChannel {
u8 filler[0x108];
};
// NONMATCHING location of JASPoolAllocObject_MultiThreaded<JASChannel>
void* JASAudioThread::run() {
OSInitFastCast();
JASDriver::initAI(DMACallback);
JASDsp::boot(DSPCallback);
JASDsp::initBuffer();
JASDSPChannel::initAll();
JASPoolAllocObject_MultiThreaded<JASChannel>::newMemPool(0x48);
JASDriver::startDMA();
OSMessage msg;
while (true) {
msg = waitMessageBlock();
switch ((intptr_t)msg) {
case AUDIOMSG_DMA:
if (sbPauseFlag) {
JUT_PANIC(107, "AUDIO THREAD PAUSED\n");
JASDriver::stopDMA();
OSSleepThread(&sThreadQueue);
}
#if DEBUG
if (snIntCount != 0) {
JASReport("DSP process is over.");
}
#endif
JASDriver::updateDac();
JASDriver::updateDacCallback();
continue;
case AUDIOMSG_DSP:
JUT_ASSERT(125, snIntCount != 0);
snIntCount--;
if (snIntCount == 0) {
JASProbe::stop(7);
JASDriver::finishDSPFrame();
} else {
JASProbe::start(2, "SFR_DSP");
JASDriver::updateDSP();
JASProbe::stop(2);
}
continue;
case AUDIOMSG_STOP:
JASDriver::stopDMA();
OSExitThread(NULL);
continue;
default:
JUT_PANIC(152, "AUDIO THREAD INVALID MESSAGE\n");
}
}
}
void JASAudioThread::DMACallback() {
JASAudioThread* pAudioThread = getInstance();
JUT_ASSERT(167, pAudioThread);
JASProbe::stop(4);
JASProbe::start(4, "UPDATE-DAC");
if (!pAudioThread->sendMessage((void*)AUDIOMSG_DMA)) {
JUT_WARN_DEVICE(173, 1, "%s","----- DMACallback : Can\'t send DAC_SYNC message\n");
}
}
void JASAudioThread::DSPCallback(void*) {
JASAudioThread* pAudioThread = getInstance();
JUT_ASSERT(184, pAudioThread);
while (DSPCheckMailFromDSP() == 0) { }
u32 mail = DSPReadMailFromDSP();
if (mail >> 0x10 != 0xF355) {
JUT_WARN(196, "DSP Mail format error %x\n", mail);
} else {
if ((mail & 0xFF00) == 0xFF00) {
if (!pAudioThread->sendMessage((void*)AUDIOMSG_DSP)) {
JUT_WARN_DEVICE(204, 1, "%s", "----- syncDSP : Send Miss\n");
}
} else {
JASDsp::finishWork(mail);
}
}
}
+326
View File
@@ -0,0 +1,326 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASBNKParser.h"
#include "JSystem/JAudio2/JASBasicBank.h"
#include "JSystem/JAudio2/JASCalc.h"
#include "JSystem/JAudio2/JASDrumSet.h"
#include "JSystem/JAudio2/JASHeapCtrl.h"
#include "JSystem/JAudio2/JASChannel.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
#include "JSystem/JSupport/JSupport.h"
JASBank* JASBNKParser::createBank(void const* stream, JKRHeap* heap) {
return createBasicBank(stream, heap);
}
u32 JASBNKParser::sUsedHeapSize;
JASBasicBank* JASBNKParser::createBasicBank(void const* stream, JKRHeap* heap) {
if (heap == NULL) {
heap = JASDram;
}
u32 free_size = heap->getFreeSize();
TFileHeader* filep = (TFileHeader*)stream;
JUT_ASSERT(59, filep->id == 'IBNK');
JASBasicBank* bank = NULL;
switch (filep->mVersion) {
case 0:
bank = Ver0::createBasicBank(stream, heap);
break;
case 1:
bank = Ver1::createBasicBank(stream, heap);
break;
}
sUsedHeapSize += free_size - heap->getFreeSize();
return bank;
}
JASBNKParser::Ver1::TChunk* JASBNKParser::Ver1::findChunk(void const* stream, u32 id) {
TFileHeader* header = (TFileHeader*)stream;
void* end = (void*)((intptr_t)stream + header->mSize);
TChunk* chunk = (TChunk*)((intptr_t)stream + 0x20);
while (chunk < end) {
if (chunk->mID == id) {
return chunk;
}
chunk = (TChunk*)(((intptr_t)chunk + 0xb + chunk->mSize) & ~3);
}
return NULL;
}
JASBasicBank* JASBNKParser::Ver1::createBasicBank(void const* stream, JKRHeap* heap) {
if (heap == NULL) {
heap = JASDram;
}
JASBasicBank* bank = new (heap, 0) JASBasicBank();
if (bank == NULL) {
return NULL;
}
TEnvtChunk* envt_chunk = (TEnvtChunk*)findChunk(stream, 'ENVT');
JUT_ASSERT(139, envt_chunk);
TOscChunk* osc_chunk = (TOscChunk*)findChunk(stream, 'OSCT');
JUT_ASSERT(142, osc_chunk);
TListChunk* list_chunk = (TListChunk*)findChunk(stream, 'LIST');
JUT_ASSERT(145, list_chunk);
u8* envt = new (heap, 2) u8[envt_chunk->mSize];
JASCalc::bcopy(envt_chunk->mData, envt, envt_chunk->mSize);
u32* ptr = &osc_chunk->mCount;
u32 count = *ptr++;
JASOscillator::Data* osc_data = new (heap, 0) JASOscillator::Data[count];
for (int i = 0; i < count; i++, ptr += sizeof(TOsc) >> 2) {
TOsc* op = (TOsc*)ptr;
JUT_ASSERT(155, op->id == 'Osci');
JASOscillator::Data* data = &osc_data[i];
data->mTarget = op->mTarget;
data->_04 = op->_08;
data->mScale = op->mScale;
data->_14 = op->_18;
data->mTable = (JASOscillator::Point*)(envt + op->mTableOffset);
data->rel_table = (JASOscillator::Point*)(envt + op->_10);
}
TListChunk* list = list_chunk;
JUT_ASSERT(172, list->count <= JASBank::PRG_OSC);
bank->newInstTable(list_chunk->count, heap);
for (int i = 0; i < list_chunk->count; i++) {
if (list_chunk->mOffsets[i] != 0) {
u32* data = (u32*)((intptr_t)stream + list_chunk->mOffsets[i]);
switch (*data++) {
case 'Inst': {
JASBasicInst* instp = new (heap, 0) JASBasicInst();
JUT_ASSERT(187, instp != NULL);
u32 count = *data++;
for (int j = 0; j < count; j++) {
u32 index = *data++;
instp->setOsc(j, &osc_data[index]);
}
count = *data++;
for (int j = 0; j < count; j++) {
data++;
}
count = *data++;
instp->setKeyRegionCount(count, heap);
for (int j = 0; j < count; j++) {
JASBasicInst::TKeymap* keymap = instp->getKeyRegion(j);
keymap->setHighKey(*data >> 0x18);
u32 fVar4 = data[1];
keymap->field_0x4 = JSULoHalf(data[3]);
keymap->field_0x8 = *(f32*)&data[4];
keymap->field_0xc = *(f32*)&data[5];
data += 2;
for (int k = 0; k < fVar4; k++) {
data += 4;
}
}
instp->setVolume(*(f32*)&data[0]);
instp->setPitch(*(f32*)&data[1]);
bank->setInst(i, instp);
break;
}
case 'Perc': {
JASDrumSet* drump = new (heap, 0) JASDrumSet();
JUT_ASSERT(264, drump != NULL);
u32 pmap_count = data[1];
JUT_ASSERT(268, pmap_count <= 128);
u32 count = *data++;
drump->newPercArray(count, heap);
for (int j = 0; j < count; j++) {
u32 offset = *data++;
if (offset != 0) {
JASDrumSet::TPerc* percp = new (heap, 0) JASDrumSet::TPerc();
JUT_ASSERT(277, percp);
u32 type = data[0];
JUT_ASSERT(282, type == 'Pmap');
u32* ptr = (u32*)((intptr_t)stream + offset);
TPercData* perc_data = (TPercData*)(ptr + 1);
percp->setVolume(perc_data->mVolume);
percp->setPitch(perc_data->mPitch);
percp->setPan((f32)perc_data->mPan / 127.0f);
percp->setRelease(perc_data->mRelease);
ptr = (u32*)&perc_data->field_0xc;
u32 count2 = *ptr++;
for (int k = 0; k < count2; k++) {
ptr++;
}
u32 pVar6 = ptr[0];
percp->field_0xe = JSULoHalf(ptr[2]);
percp->field_0x10 = *(f32*)&ptr[3];
percp->field_0x14 = *(f32*)&ptr[4];
for (int k = 0; k < pVar6; k++) {}
drump->setPerc(j, percp);
}
}
bank->setInst(i, drump);
break;
}
default:
JUT_PANIC(338, "Unexpected Inst Type");
break;
}
}
}
return bank;
}
JASBasicBank* JASBNKParser::Ver0::createBasicBank(void const* stream, JKRHeap* heap) {
if (heap == NULL) {
heap = JASDram;
}
THeader const* header = (THeader*)stream;
JASBasicBank* bank = new (heap, 0) JASBasicBank();
if (bank == NULL) {
return NULL;
}
bank->newInstTable(0x80, heap);
for (int i = 0; i < 0x80; i++) {
TInst* tinst = header->mOffsets.mInstOffset[i].ptr(header);
if (tinst != NULL) {
JASBasicInst* instp = new (heap, 0) JASBasicInst();
JUT_ASSERT(368, instp != NULL);
instp->setVolume(tinst->mVolume);
instp->setPitch(tinst->mPitch);
int osc_idx = 0;
for (int j = 0; j < 2; j++) {
TOsc* tosc = tinst->mOscOffset[j].ptr(header);
if (tosc != NULL) {
JASOscillator::Data* osc = findOscPtr(bank, header, tosc);
if (osc != NULL) {
instp->setOsc(osc_idx, osc);
} else {
osc = new (heap, 0) JASOscillator::Data();
JUT_ASSERT(386, osc != NULL);
osc->mTarget = tosc->mTarget;
osc->_04 = tosc->field_0x4;
JASOscillator::Point* points = tosc->mPointOffset.ptr(header);
if (points != NULL) {
const JASOscillator::Point* endPtr = getOscTableEndPtr(points);
int size = endPtr - points;
JASOscillator::Point* table = new (heap, 0) JASOscillator::Point[size];
JUT_ASSERT(396, table != NULL);
JASCalc::bcopy(points, table, size * sizeof(JASOscillator::Point));
osc->mTable = table;
} else {
osc->mTable = NULL;
}
points = tosc->field_0xc.ptr(header);
if (points != NULL) {
const JASOscillator::Point* endPtr = getOscTableEndPtr(points);
int size = endPtr - points;
JASOscillator::Point* table = new (heap, 0) JASOscillator::Point[size];
JUT_ASSERT(409, table != NULL);
JASCalc::bcopy(points, table, size * sizeof(JASOscillator::Point));
osc->rel_table = table;
} else {
osc->rel_table = NULL;
}
osc->mScale = tosc->mScale;
osc->_14 = tosc->field_0x14;
instp->setOsc(osc_idx, osc);
}
osc_idx++;
}
}
instp->setKeyRegionCount(tinst->mKeyRegionCount, heap);
for (int j = 0; j < tinst->mKeyRegionCount; j++) {
JASBasicInst::TKeymap* keymap = instp->getKeyRegion(j);
TKeymap* tkeymap = tinst->mKeymapOffset[j].ptr(header);
keymap->setHighKey(tkeymap->mHighKey);
TVmap* tvmap = tkeymap->mVmapOffset.ptr(header);
keymap->field_0x4 = JSULoHalf(tvmap->field_0x4);
keymap->field_0x8 = tvmap->field_0x8;
keymap->field_0xc = tvmap->field_0xc;
}
bank->setInst(i, instp);
}
}
for (int i = 0; i < 12; i++) {
TPerc* tperc = header->mOffsets.mPercOffset[i].ptr(header);
if (tperc != NULL) {
JASDrumSet* setp = new (heap, 0) JASDrumSet();
JUT_ASSERT(509, setp != NULL);
setp->newPercArray(0x80, heap);
for (int j = 0; j < 0x80; j++) {
TPmap* tpmap = tperc->mPmapOffset[j].ptr(header);
if (tpmap != NULL) {
JASDrumSet::TPerc* percp = new (heap, 0) JASDrumSet::TPerc();
JUT_ASSERT(519, percp);
percp->setVolume(tpmap->mVolume);
percp->setPitch(tpmap->mPitch);
if (tperc->mMagic == 'PER2') {
percp->setPan(tperc->mPan[j] / 127.0f);
percp->setRelease(tperc->mRelease[j]);
}
TVmap* vmap = tpmap->mVmapOffset.ptr(header);
percp->field_0xe = JSULoHalf(vmap->field_0x4);
percp->field_0x10 = vmap->field_0x8;
percp->field_0x14 = vmap->field_0xc;
setp->setPerc(j, percp);
}
}
bank->setInst(i + 0xe4, setp);
}
}
return bank;
}
JASOscillator::Data* JASBNKParser::Ver0::findOscPtr(JASBasicBank* bank, THeader const* header,
TOsc const* osc) {
TOffsetData const* data = &header->mOffsets;
for (int i = 0; i < 0x80; i++) {
TInst* tinst = data->mInstOffset[i].ptr(header);
if (tinst != NULL) {
for (int j = 0; j < 2; j++) {
if (tinst->mOscOffset[j].ptr(header) == osc) {
JASInst* inst = bank->getInst(i);
if (inst != NULL) {
JASInstParam param;
inst->getParam(0x3c, 0x7f, &param);
if (j < param.field_0x1d) {
return param.field_0x14[j];
}
}
}
}
}
}
return NULL;
}
JASOscillator::Point const* JASBNKParser::Ver0::getOscTableEndPtr(JASOscillator::Point const* points) {
const JASOscillator::Point* ptr = points;
while(true) {
s16 tmp = ptr->_0;
ptr++;
if (tmp > 10) {
break;
}
}
return ptr;
}
// Fakematch? Why is this here?
template<>
JASMemPool_MultiThreaded<JASChannel> JASPoolAllocObject_MultiThreaded<JASChannel>::memPool_;
+92
View File
@@ -0,0 +1,92 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASBank.h"
#include "JSystem/JAudio2/JASAiCtrl.h"
#include "JSystem/JAudio2/JASBasicInst.h"
#include "JSystem/JAudio2/JASBasicWaveBank.h"
#include "JSystem/JAudio2/JASChannel.h"
// NONMATCHING JASPoolAllocObject_MultiThreaded<_> locations
JASChannel* JASBank::noteOn(JASBank const* param_0, int param_1, u8 param_2, u8 param_3, u16 param_4,
void (*param_5)(u32, JASChannel*, JASDsp::TChannel*, void*),
void* param_6) {
if (param_1 >= 0xf0) {
return noteOnOsc(param_1 - 0xf0, param_2, param_3, param_4, param_5, param_6);
}
if (!param_0) {
return NULL;
}
JASInstParam stack_60;
if (!param_0->getInstParam(param_1, param_2, param_3, &stack_60)) {
return NULL;
}
JASWaveBank* waveBank = param_0->getWaveBank();
if (!waveBank) {
return NULL;
}
JASWaveHandle* waveHandle = waveBank->getWaveHandle(stack_60.field_0x1a);
if (!waveHandle) {
return NULL;
}
const JASWaveInfo* waveInfo = waveHandle->getWaveInfo();
if (!waveInfo) {
return NULL;
}
int wavePtr = waveHandle->getWavePtr();
if (!wavePtr) {
return NULL;
}
JASChannel* channel = new JASChannel(param_5, param_6);
if (!channel) {
return NULL;
}
channel->setPriority(param_4);
channel->field_0xdc.field_0x4 = *waveInfo;
channel->field_0x104 = wavePtr;
channel->field_0xdc.field_0x0 = stack_60.field_0x1c;
channel->setBankDisposeID(param_0);
channel->setInitPitch(stack_60.mPitch * (waveInfo->field_0x04 / JASDriver::getDacRate()));
if (stack_60.field_0x1e == 0) {
channel->setKey(param_2 - waveInfo->field_0x01);
}
channel->setInitVolume(stack_60.mVolume);
channel->setVelocity(param_3);
channel->setInitPan(stack_60.mPan);
channel->setInitFxmix(stack_60.mFxMix);
channel->setInitDolby(stack_60.mDolby);
for (u32 i = 0; i < stack_60.field_0x1d; i++) {
channel->setOscInit(i, stack_60.field_0x14[i]);
}
channel->setDirectRelease(stack_60.field_0x18);
if (!channel->play()) {
return NULL;
}
return channel;
}
// NONMATCHING JASPoolAllocObject_MultiThreaded<_> locations
JASChannel* JASBank::noteOnOsc(int param_0, u8 param_1, u8 param_2, u16 param_3,
void (*param_4)(u32, JASChannel*, JASDsp::TChannel*, void*),
void* param_5) {
static JASOscillator::Point const OSC_RELEASE_TABLE[2] = {
{0x0001, 0x000A, 0x0000},
{0x000F, 0x0000, 0x0000},
};
static const JASOscillator::Data OSC_ENV = {0, 1.0f, NULL, OSC_RELEASE_TABLE, 1.0f, 0.0f};
JASChannel* channel = new JASChannel(param_4, param_5);
if (!channel) {
return NULL;
}
channel->setPriority(param_3);
channel->field_0x104 = param_0;
channel->field_0xdc.field_0x0 = 2;
channel->setInitPitch(16736.016f / JASDriver::getDacRate());
channel->setKey(param_1 - channel->field_0xdc.field_0x4.field_0x01);
channel->setVelocity(param_2);
channel->setOscInit(0, &OSC_ENV);
if (!channel->play()) {
return NULL;
}
return channel;
}
+49
View File
@@ -0,0 +1,49 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASBasicBank.h"
#include "JSystem/JAudio2/JASCalc.h"
JASBasicBank::JASBasicBank() {
mInstTable = NULL;
mInstNumMax = 0;
}
void JASBasicBank::newInstTable(u8 num, JKRHeap* heap) {
if (num != 0) {
JUT_ASSERT(31, num <= JASBank::PRG_OSC);
mInstNumMax = num;
mInstTable = new (heap, 0) JASInst*[mInstNumMax];
JASCalc::bzero(mInstTable, mInstNumMax * 4);
}
}
bool JASBasicBank::getInstParam(int prg_no, int param_1, int param_2,
JASInstParam* o_param) const {
JASInst* inst = getInst(prg_no);
if (inst == NULL) {
return NULL;
}
return inst->getParam(param_1, param_2, o_param);
}
void JASBasicBank::setInst(int prg_no, JASInst* inst) {
if (mInstTable != NULL) {
JUT_ASSERT(50, prg_no < mInstNumMax);
JUT_ASSERT(54, prg_no >= 0);
JUT_ASSERT(56, mInstTable[prg_no] == 0);
mInstTable[prg_no] = inst;
}
}
JASInst* JASBasicBank::getInst(int prg_no) const {
if (prg_no < 0) {
return NULL;
}
if (prg_no >= mInstNumMax) {
return NULL;
}
if (mInstTable == NULL) {
return NULL;
}
return mInstTable[prg_no];
}
+82
View File
@@ -0,0 +1,82 @@
//
// JASBasicInst
//
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASBasicInst.h"
#include "JSystem/JAudio2/JASCalc.h"
#include "JSystem/JKernel/JKRHeap.h"
JASBasicInst::JASBasicInst() {
mVolume = 1.0;
mPitch = 1.0;
mKeymapCount = 0;
mKeymap = NULL;
JASCalc::bzero(field_0xc, sizeof(field_0xc));
}
JASBasicInst::~JASBasicInst() {
delete[] mKeymap;
}
bool JASBasicInst::getParam(int param_0, int param_1, JASInstParam* param_2) const {
UNUSED(param_1);
param_2->field_0x1c = 0;
param_2->field_0x1e = 0;
param_2->field_0x14 = (JASOscillator::Data**)&field_0xc;
param_2->field_0x1d = 2;
param_2->mVolume = mVolume;
param_2->mPitch = mPitch;
TKeymap* keyMap = NULL;
for (int i = 0; i < mKeymapCount; i++) {
if (param_0 <= mKeymap[i].mHighKey) {
keyMap = &mKeymap[i];
break;
}
}
if (keyMap == NULL) {
return false;
}
param_2->mVolume *= keyMap->field_0x8;
param_2->mPitch *= keyMap->field_0xc;
param_2->field_0x1a = u16(keyMap->field_0x4);
return true;
}
void JASBasicInst::setKeyRegionCount(u32 count, JKRHeap* param_1) {
delete [] mKeymap;
mKeymap = new (param_1, 0) TKeymap[count];
JUT_ASSERT(114, mKeymap != NULL);
mKeymapCount = count;
}
void JASBasicInst::setOsc(int index, JASOscillator::Data const* param_1) {
JUT_ASSERT(128, index < OSC_MAX);
JUT_ASSERT(129, index >= 0);
field_0xc[index] = param_1;
}
JASBasicInst::TKeymap* JASBasicInst::getKeyRegion(int index) {
JUT_ASSERT(146, index >= 0);
if (index >= mKeymapCount) {
return NULL;
}
return mKeymap + index;
}
JASBasicInst::TKeymap* JASBasicInst::getKeyRegion(int index) const {
JUT_ASSERT(155, index >= 0);
if (index >= mKeymapCount) {
return NULL;
}
return mKeymap + index;
}
JASBasicInst::TKeymap::~TKeymap() {
}
@@ -0,0 +1,135 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASBasicWaveBank.h"
#include "JSystem/JAudio2/JASMutex.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTAssert.h"
#include <stdint.h>
JASBasicWaveBank::JASBasicWaveBank() {
mWaveTable = NULL;
mWaveGroupArray = NULL;
mHandleCount = 0;
mGroupCount = 0;
OSInitMutex(&field_0x4);
}
JASBasicWaveBank::~JASBasicWaveBank() {
delete[] mWaveTable;
delete[] mWaveGroupArray;
}
JASBasicWaveBank::TWaveGroup* JASBasicWaveBank::getWaveGroup(u32 param_0) {
if (param_0 >= mGroupCount) {
return NULL;
}
return mWaveGroupArray + param_0;
}
void JASBasicWaveBank::setGroupCount(u32 param_0, JKRHeap* param_1) {
delete[] mWaveGroupArray;
mGroupCount = param_0;
mWaveGroupArray = new(param_1, 0) TWaveGroup[param_0];
JUT_ASSERT(62, mWaveGroupArray != NULL);
for (int i = 0; i < mGroupCount; i++) {
mWaveGroupArray[i].mBank = this;
}
}
void JASBasicWaveBank::setWaveTableSize(u32 param_0, JKRHeap* param_1) {
delete[] mWaveTable;
mWaveTable = new(param_1, 0) TWaveHandle[param_0];
JUT_ASSERT(92, mWaveTable != NULL);
mHandleCount = param_0;
}
void JASBasicWaveBank::incWaveTable(JASBasicWaveBank::TWaveGroup const* param_0) {
JASMutexLock lock(&field_0x4);
for (u32 i = 0; i < param_0->getWaveCount(); i++) {
TWaveHandle* handle = mWaveTable + param_0->getWaveID(i);
if (!handle->mHeap) {
handle->mHeap = &param_0->mHeap;
handle->field_0x4.field_0x20 = &param_0->_48;
handle->field_0x4.field_0x08 = param_0->mCtrlWaveArray[i].field_0x4;
}
}
}
u32 JASBasicWaveBank::mNoLoad;
void JASBasicWaveBank::decWaveTable(JASBasicWaveBank::TWaveGroup const* param_0) {
JASMutexLock lock(&field_0x4);
for (u32 i = 0; i < param_0->getWaveCount(); i++) {
TWaveHandle* handle = mWaveTable + param_0->getWaveID(i);
if (handle->mHeap == &param_0->mHeap) {
handle->mHeap = NULL;
handle->field_0x4.field_0x20 = &mNoLoad;
handle->field_0x4.field_0x08 = -1;
}
}
}
JASWaveHandle* JASBasicWaveBank::getWaveHandle(u32 param_0) const {
if (param_0 >= mHandleCount) {
return NULL;
}
if (!mWaveTable[param_0].mHeap) {
return NULL;
}
return mWaveTable + param_0;
}
void JASBasicWaveBank::setWaveInfo(JASBasicWaveBank::TWaveGroup* wgrp, int index,
u16 param_2, JASWaveInfo const& param_3) {
JUT_ASSERT(204, wgrp);
JUT_ASSERT(205, index < wgrp->mWaveCount);
JUT_ASSERT(206, index >= 0);
mWaveTable[param_2].field_0x4 = param_3;
mWaveTable[param_2].field_0x4.field_0x20 = &mNoLoad;
mWaveTable[param_2].field_0x4.field_0x08 = -1;
wgrp->mCtrlWaveArray[index].field_0x0 = param_2;
wgrp->mCtrlWaveArray[index].field_0x4 = param_3.field_0x08;
}
JASBasicWaveBank::TWaveGroup::TWaveGroup() {
mBank = NULL;
mCtrlWaveArray = NULL;
mWaveCount = 0;
}
JASBasicWaveBank::TWaveGroup::~TWaveGroup() {
delete[] mCtrlWaveArray;
}
void JASBasicWaveBank::TWaveGroup::setWaveCount(u32 param_0, JKRHeap* param_1) {
delete[] mCtrlWaveArray;
mWaveCount = param_0;
mCtrlWaveArray = new(param_1, 0) TGroupWaveInfo[param_0];
JUT_ASSERT(255, mCtrlWaveArray != NULL);
}
void JASBasicWaveBank::TWaveGroup::onLoadDone() {
JUT_ASSERT(286, mBank);
mBank->incWaveTable(this);
}
void JASBasicWaveBank::TWaveGroup::onEraseDone() {
JUT_ASSERT(292, mBank);
mBank->decWaveTable(this);
}
u32 JASBasicWaveBank::TWaveGroup::getWaveID(int index) const {
JUT_ASSERT(298, index < mWaveCount);
JUT_ASSERT(299, index >= 0);
return mCtrlWaveArray[index].field_0x0;
}
int JASBasicWaveBank::TWaveHandle::getWavePtr() const {
JUT_ASSERT(313, mHeap);
void* base = mHeap->getBase();
if (base == 0) {
return 0;
}
return (intptr_t)base + field_0x4.field_0x08;
}
+318
View File
@@ -0,0 +1,318 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASCalc.h"
#include <cmath>
#include <limits>
void JASCalc::imixcopy(const s16* s1, const s16* s2, s16* dst, u32 n) {
for (n; n != 0; n--) {
*dst++ = *(s1)++;
*dst++ = *(s2)++;
}
}
void JASCalc::bcopyfast(const void* src, void* dest, u32 size) {
JUT_ASSERT(226, (reinterpret_cast<u32>(src) & 0x03) == 0);
JUT_ASSERT(227, (reinterpret_cast<u32>(dest) & 0x03) == 0);
JUT_ASSERT(228, (size & 0x0f) == 0);
u32 copy1, copy2, copy3, copy4;
u32* usrc = (u32*)src;
u32* udest = (u32*)dest;
for (size = size / (4 * sizeof(u32)); size != 0; size--) {
copy1 = *(usrc)++;
copy2 = *(usrc)++;
copy3 = *(usrc)++;
copy4 = *(usrc)++;
*udest++ = copy1;
*udest++ = copy2;
*udest++ = copy3;
*udest++ = copy4;
}
}
void JASCalc::bcopy(const void* src, void* dest, u32 size) {
u32* usrc;
u32* udest;
u8* bsrc = (u8*)src;
u8* bdest = (u8*)dest;
u8 endbitsSrc = (reinterpret_cast<u32>(bsrc) & 0x03);
u8 enbitsDst = (reinterpret_cast<u32>(bdest) & 0x03);
if ((endbitsSrc) == (enbitsDst) && (size & 0x0f) == 0) {
bcopyfast(src, dest, size);
}
else if ((endbitsSrc == enbitsDst) && (size >= 16)) {
if (endbitsSrc != 0) {
for (endbitsSrc = 4 - endbitsSrc; endbitsSrc != 0; endbitsSrc--) {
*bdest++ = (u32)*bsrc++;
size--;
}
}
udest = (u32 *)bdest;
usrc = (u32 *)bsrc;
for (; size >= 4; size -= 4) {
*udest++ = *usrc++;
}
if (size != 0) {
bdest = (u8 *)udest;
bsrc = (u8 *)usrc;
for (; size != 0; size--) {
*bdest++ = (u32)*bsrc++;
}
}
}
else {
for (; size != 0; size--) {
*bdest++ = (u32)*bsrc++;
}
}
}
void JASCalc::bzerofast(void* dest, u32 size) {
JUT_ASSERT(336, (reinterpret_cast<u32>(dest) & 0x03) == 0);
JUT_ASSERT(337, (size & 0x0f) == 0);
u32* udest = (u32*)dest;
for (size = size / (4 * sizeof(u32)); size != 0; size--) {
*udest++ = 0;
*udest++ = 0;
*udest++ = 0;
*udest++ = 0;
}
}
void JASCalc::bzero(void* dest, u32 size) {
u32* udest;
u8* bdest = (u8*)dest;
if ((size & 0x1f) == 0 && (reinterpret_cast<u32>(dest) & 0x1f) == 0) {
DCZeroRange(dest, size);
return;
}
u8 alignedbitsDst = reinterpret_cast<u32>(bdest) & 0x3;
if ((size & 0xf) == 0 && alignedbitsDst == 0) {
bzerofast(dest, size);
return;
}
if (size >= 16) {
if (alignedbitsDst != 0) {
for (alignedbitsDst = 4 - alignedbitsDst; alignedbitsDst != 0; alignedbitsDst--) {
*bdest++ = 0;
size--;
}
}
udest = (u32 *)bdest;
for (; size >= 4; size -= 4) {
*udest++ = 0;
}
if (size != 0) {
bdest = (u8 *)udest;
for (; size != 0; size--) {
*bdest++ = 0;
}
}
}
else {
for (; size != 0; size--) {
*bdest++ = 0;
}
}
}
s16 const JASCalc::CUTOFF_TO_IIR_TABLE[128][4] = {
0x0F5C, 0x0A3D, 0x4665, 0x1E73,
0x0F5E, 0x0A3D, 0x4664, 0x1E73,
0x0F63, 0x0A3C, 0x4661, 0x1E71,
0x0F6C, 0x0A3C, 0x465B, 0x1E6F,
0x0F79, 0x0A3A, 0x4653, 0x1E6B,
0x0F89, 0x0A39, 0x4649, 0x1E67,
0x0F9C, 0x0A37, 0x463D, 0x1E62,
0x0FB4, 0x0A35, 0x462E, 0x1E5B,
0x0FCE, 0x0A33, 0x461D, 0x1E54,
0x0FED, 0x0A30, 0x460A, 0x1E4C,
0x100F, 0x0A2D, 0x45F5, 0x1E43,
0x1034, 0x0A29, 0x45DE, 0x1E39,
0x105D, 0x0A26, 0x45C4, 0x1E2D,
0x108A, 0x0A22, 0x45A8, 0x1E21,
0x10BA, 0x0A1D, 0x458A, 0x1E14,
0x10EE, 0x0A18, 0x456A, 0x1E06,
0x1126, 0x0A13, 0x4547, 0x1DF7,
0x1161, 0x0A0E, 0x4522, 0x1DE7,
0x119F, 0x0A08, 0x44FB, 0x1DD6,
0x11E1, 0x0A02, 0x44D2, 0x1DC5,
0x1227, 0x09FC, 0x44A6, 0x1DB2,
0x1270, 0x09F5, 0x4478, 0x1D9E,
0x12BD, 0x09EE, 0x4448, 0x1D89,
0x130E, 0x09E7, 0x4416, 0x1D73,
0x1362, 0x09DF, 0x43E1, 0x1D5D,
0x13B9, 0x09D7, 0x43AB, 0x1D45,
0x1415, 0x09CF, 0x4372, 0x1D2C,
0x1473, 0x09C7, 0x4336, 0x1D13,
0x14D6, 0x09BE, 0x42F9, 0x1CF8,
0x153C, 0x09B4, 0x42B9, 0x1CDD,
0x15A5, 0x09AB, 0x4277, 0x1CC0,
0x1612, 0x09A1, 0x4233, 0x1CA3,
0x1683, 0x0997, 0x41ED, 0x1C84,
0x16F7, 0x098C, 0x41A4, 0x1C65,
0x176F, 0x0981, 0x4159, 0x1C44,
0x17EA, 0x0976, 0x410C, 0x1C23,
0x1869, 0x096A, 0x40BD, 0x1C01,
0x18EB, 0x095F, 0x406B, 0x1BDD,
0x1972, 0x0952, 0x4018, 0x1BB9,
0x19FB, 0x0946, 0x3FC2, 0x1B94,
0x1A88, 0x0939, 0x3F69, 0x1B6E,
0x1B19, 0x092C, 0x3F0F, 0x1B47,
0x1BAE, 0x091E, 0x3EB2, 0x1B1E,
0x1C46, 0x0911, 0x3E53, 0x1AF5,
0x1CE1, 0x0902, 0x3DF2, 0x1ACB,
0x1D80, 0x08F4, 0x3D8E, 0x1AA0,
0x1E23, 0x08E5, 0x3D29, 0x1A74,
0x1EC9, 0x08D6, 0x3CC1, 0x1A47,
0x1F73, 0x08C7, 0x3C57, 0x1A19,
0x2020, 0x08B7, 0x3BEA, 0x19EB,
0x20D1, 0x08A7, 0x3B7C, 0x19BB,
0x2186, 0x0896, 0x3B0B, 0x198A,
0x223E, 0x0886, 0x3A98, 0x1958,
0x22FA, 0x0875, 0x3A22, 0x1925,
0x23B9, 0x0863, 0x39AB, 0x18F2,
0x247C, 0x0851, 0x3931, 0x18BD,
0x2542, 0x083F, 0x38B5, 0x1887,
0x260C, 0x082D, 0x3837, 0x1851,
0x26DA, 0x081A, 0x37B6, 0x1819,
0x27AB, 0x0807, 0x3734, 0x17E1,
0x2880, 0x07F4, 0x36AF, 0x17A7,
0x2958, 0x07E0, 0x3628, 0x176D,
0x2A34, 0x07CC, 0x359E, 0x1731,
0x2B14, 0x07B8, 0x3512, 0x16F5,
0x2BF7, 0x07A3, 0x3485, 0x16B7,
0x2CDD, 0x078E, 0x33F4, 0x1679,
0x2DC8, 0x0779, 0x3362, 0x163A,
0x2EB5, 0x0764, 0x32CD, 0x15FA,
0x2FA7, 0x074E, 0x3237, 0x15B8,
0x309C, 0x0737, 0x319E, 0x1576,
0x3194, 0x0721, 0x3102, 0x1533,
0x3290, 0x070A, 0x3065, 0x14EF,
0x3390, 0x06F3, 0x2FC5, 0x14AA,
0x3493, 0x06DB, 0x2F23, 0x1464,
0x359A, 0x06C3, 0x2E7F, 0x141C,
0x36A4, 0x06AB, 0x2DD8, 0x13D4,
0x37B2, 0x0692, 0x2D2F, 0x138C,
0x38C4, 0x067A, 0x2C85, 0x1342,
0x39D9, 0x0660, 0x2BD7, 0x12F7,
0x3AF1, 0x0647, 0x2B28, 0x12AB,
0x3C0E, 0x062D, 0x2A76, 0x125E,
0x3D2E, 0x0613, 0x29C2, 0x1210,
0x3E51, 0x05F8, 0x290C, 0x11C1,
0x3F78, 0x05DE, 0x2854, 0x1172,
0x40A3, 0x05C2, 0x2799, 0x1121,
0x41D1, 0x05A7, 0x26DC, 0x10CF,
0x4302, 0x058B, 0x261D, 0x107D,
0x4438, 0x056F, 0x255C, 0x1029,
0x4571, 0x0553, 0x2499, 0x0FD4,
0x46AD, 0x0536, 0x23D3, 0x0F7F,
0x47ED, 0x0519, 0x230B, 0x0F28,
0x4931, 0x04FB, 0x2241, 0x0ED1,
0x4A78, 0x04DE, 0x2174, 0x0E78,
0x4BC2, 0x04C0, 0x20A5, 0x0E1F,
0x4D11, 0x04A1, 0x1FD4, 0x0DC5,
0x4E63, 0x0482, 0x1F01, 0x0D69,
0x4FB8, 0x0463, 0x1E2C, 0x0D0D,
0x5111, 0x0444, 0x1D54, 0x0CB0,
0x526E, 0x0424, 0x1C7A, 0x0C51,
0x53CE, 0x0404, 0x1B9E, 0x0BF2,
0x5532, 0x03E4, 0x1AC0, 0x0B92,
0x5699, 0x03C3, 0x19DF, 0x0B31,
0x5804, 0x03A2, 0x18FD, 0x0ACF,
0x5972, 0x0381, 0x1818, 0x0A6C,
0x5AE5, 0x035F, 0x1730, 0x0A08,
0x5C5A, 0x033D, 0x1647, 0x09A3,
0x5DD3, 0x031B, 0x155B, 0x093D,
0x5F50, 0x02F9, 0x146D, 0x08D6,
0x60D1, 0x02D6, 0x137D, 0x086E,
0x6255, 0x02B2, 0x128A, 0x0805,
0x63DC, 0x028F, 0x1196, 0x079B,
0x6567, 0x026B, 0x109F, 0x0730,
0x66F6, 0x0247, 0x0FA6, 0x06C5,
0x6888, 0x0222, 0x0EAA, 0x0658,
0x6A1E, 0x01FD, 0x0DAD, 0x05EA,
0x6BB7, 0x01D8, 0x0CAD, 0x057B,
0x6D54, 0x01B2, 0x0BAB, 0x050C,
0x6EF5, 0x018D, 0x0AA6, 0x049B,
0x7099, 0x0166, 0x09A0, 0x042A,
0x7241, 0x0140, 0x0897, 0x03B7,
0x73EC, 0x0119, 0x078C, 0x0344,
0x759B, 0x00F2, 0x067F, 0x02CF,
0x774D, 0x00CA, 0x056F, 0x025A,
0x7903, 0x00A3, 0x045D, 0x01E3,
0x7ABD, 0x007A, 0x0349, 0x016C,
0x7C7A, 0x0052, 0x0233, 0x00F4,
0x7E3B, 0x0029, 0x011B, 0x007A,
0x7FFF, 0x0000, 0x0000, 0x0000,
};
// currently required because of missing functions
// JASCalc::hannWindow(short *, u32)
// JASCalc::hammWindow(short *, u32)
// JASCalc::fft(float *, float *, u32, s32)
f32 JASCalc::fake1() { return 0.5f; }
f32 JASCalc::fake2(s32 x) { return JASCalc::clamp<s16, s32>(x); }
f32 JASCalc::fake3() { return 0.0f; }
f32 JASCalc::pow2(f32 x) {
s32 frac_index = 0;
union {
s32 l;
f32 f;
} exponent;
exponent.l = (x >= 0.0f ? (s32)(x - 0.5f) : (s32)(x + 0.5f)); // Shift towards 0 and round
f32 pannedval = x - exponent.l; // strictly between 1.5 and -1.5
// 2^x will not fit in an IEEE-754 float
if(exponent.l > 128) {
return HUGE_VALF;
}
// convert to exponent of IEEE-754 float
exponent.l += 127;
exponent.l <<= 23;
// Calculate the mantissa
static const f32 scale_frac[] = { 0.0f, 0.5f };
// { 1 , 1/sqrt2 }
static const f32 two_to_frac[] = {1.0f, 0.70710677f};
// coefficients of Taylor polynomial of 2^x - 1 at 0:
// 2^x - 1 = (log2) * x + (log2)^2 / 2! * x^2 + ...
static const f32 __two_to_x[] = {
0.6931472f, 0.24022661,
0.055502914f, 0.009625022f,
0.0013131053f, 1.8300806E-4f
};
if (pannedval < 0.0f) {
frac_index += 1;
}
f32 ret = pannedval + scale_frac[frac_index];
// Evaluate Taylor polynomial using Horner's method
ret = ret * (ret * (ret * (ret * (ret * (ret * __two_to_x[5] + __two_to_x[4]) +
__two_to_x[3]) + __two_to_x[2]) + __two_to_x[1]) + __two_to_x[0]);
// 2^n * (corrected mantissa)
ret = exponent.f * (0.75f * two_to_frac[frac_index] + ((0.25f + ret) * two_to_frac[frac_index]));
return ret;
}
+42
View File
@@ -0,0 +1,42 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASCallback.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
bool JASCallbackMgr::regist(JASCallback* callback, void* argument) {
JASCriticalSection criticalSection;
for (int i = 0; i < NUM_CALLBACKS; i++) {
if (callbacks_[i].callback_ == NULL) {
callbacks_[i].callback_ = callback;
callbacks_[i].arg_ = argument;
return true;
}
}
return false;
}
int JASCallbackMgr::reject(JASCallback* callback, void* argument) {
int rejectNum = 0;
JASCriticalSection criticalSection;
for (int i = 0; i < NUM_CALLBACKS; i++) {
if (callbacks_[i].callback_ == callback && callbacks_[i].arg_ == argument) {
callbacks_[i].callback_ = NULL;
callbacks_[i].arg_ = NULL;
rejectNum++;
}
}
return rejectNum;
}
void JASCallbackMgr::callback() {
for (int i = 0; i < NUM_CALLBACKS; i++) {
if (callbacks_[i].callback_) {
s32 result = callbacks_[i].callback_(callbacks_[i].arg_);
if (result < 0) {
callbacks_[i].callback_ = NULL;
callbacks_[i].arg_ = NULL;
}
}
}
}
+520
View File
@@ -0,0 +1,520 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#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"
OSMessageQueue JASChannel::sBankDisposeMsgQ;
OSMessage JASChannel::sBankDisposeMsg[16];
OSMessage JASChannel::sBankDisposeList[16];
int JASChannel::sBankDisposeListSize;
JASChannel::JASChannel(Callback i_callback, void* i_callbackData) :
mStatus(STATUS_STOP),
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;
}
JASChannel::~JASChannel() {
if (mDspCh != NULL) {
JUT_WARN(62, "%s","~JASChannel:: mDspCh != NULL");
mDspCh->drop();
}
if (mCallback != NULL) {
mCallback(CB_STOP, this, NULL, mCallbackData);
}
}
int JASChannel::play() {
JASDSPChannel* channel = JASDSPChannel::alloc(JSULoByte(mPriority), dspUpdateCallback, this);
if (channel == NULL) {
delete this;
return 0;
}
mDspCh = channel;
channel->start();
mStatus = STATUS_PLAY;
return 1;
}
int JASChannel::playForce() {
JASDSPChannel* channel = JASDSPChannel::allocForce(JSULoByte(mPriority),
dspUpdateCallback, this);
if (channel == NULL) {
delete this;
return 0;
}
mDspCh = channel;
channel->start();
mStatus = STATUS_PLAY;
return 1;
}
void JASChannel::release(u16 i_directRelease) {
if (mStatus == STATUS_PLAY) {
if (i_directRelease != 0) {
setDirectRelease(i_directRelease);
}
for (u32 i = 0; i < 2; i++) {
if (mOscillators[i].isValid()) {
mOscillators[i].release();
}
}
JUT_ASSERT(135, mDspCh);
mDspCh->setPriority(JSUHiByte(mPriority));
mStatus = STATUS_RELEASE;
}
}
void JASChannel::setOscInit(u32 oscnum, JASOscillator::Data const* i_data) {
JUT_ASSERT(147, oscnum < OSC_NUM);
mOscillators[oscnum].initStart(i_data);
}
void JASChannel::setMixConfig(u32 bus, u16 i_config) {
JUT_ASSERT(153, bus < BUSOUT_CPUCH);
mMixConfig[bus].whole = i_config;
}
f32 JASChannel::calcEffect(JASChannel::PanVector const* i_vector) {
return i_vector->mSound + i_vector->mEffect + i_vector->mChannel;
}
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);
}
void JASChannel::effectOsc(u32 oscnum, JASOscillator::EffectParams* i_params) {
JUT_ASSERT(176, oscnum < OSC_NUM);
f32 value = mOscillators[oscnum].getValue();
switch (mOscillators[oscnum].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;
default:
JUT_WARN(205, "%s", "Invalid osc target");
}
}
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;
}
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);
}
}
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;
default:
JUT_WARN(323, "Unexpected JASDSPChannel::UpdateStatus %d", i_type);
}
return 0;
}
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) {
JUT_WARN_DEVICE(346, 2, "%s", "Lost wave data while playing");
mDspCh->free();
mDspCh = NULL;
delete this;
return -1;
}
if (checkBankDispose()) {
JUT_WARN_DEVICE(357, 2, "%s","Lost bank data while playing");
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;
}
s32 JASChannel::updateDSPChannel(JASDsp::TChannel* i_channel) {
JUT_ASSERT(444, mStatus == STATUS_PLAY || mStatus == STATUS_RELEASE);
JUT_ASSERT(445, mDspCh);
if (mCallback != NULL) {
mCallback(CB_PLAY, this, i_channel, mCallbackData);
}
if (field_0xdc.field_0x4.field_0x20[0] == 0) {
JUT_WARN_DEVICE(456, 2, "%s","Lost wave data while playing");
mDspCh->free();
mDspCh = NULL;
delete this;
return -1;
}
if (checkBankDispose()) {
JUT_WARN_DEVICE(467, 2, "%s", "Lost bank data while playing");
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;
}
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;
}
param_1 = JASCalc::clamp01(param_1);
u16 r31 = param_1 * JASDriver::getChannelLevel_dsp();
u8 r30 = param_2 * 127.5f;
u8 r29 = param_4 * 127.5f;
u8 r28 = param_3 * 127.5f;
i_channel->setAutoMixer(r31, r30, r29, r28, 0);
}
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;
}
}
volume = JASCalc::clamp01(volume);
i_volumeOut[i] = volume * JASDriver::getChannelLevel_dsp();
}
}
}
void JASChannel::free() {
JUT_ASSERT(661, mStatus == STATUS_RELEASE || mStatus == STATUS_STOP);
mCallback = NULL;
mCallbackData = NULL;
}
void JASChannel::initBankDisposeMsgQueue() {
OSInitMessageQueue(&sBankDisposeMsgQ, sBankDisposeMsg, 0x10);
sBankDisposeListSize = 0;
}
void JASChannel::receiveBankDisposeMsg() {
OSMessage msg;
for (sBankDisposeListSize = 0;
OSReceiveMessage(&sBankDisposeMsgQ, &msg, OS_MESSAGE_NOBLOCK);
sBankDisposeListSize++)
{
sBankDisposeList[sBankDisposeListSize] = msg;
}
}
bool JASChannel::checkBankDispose() const {
if (mBankDisposeID == NULL) {
return false;
}
for (int i = 0; i < sBankDisposeListSize; i++) {
if (mBankDisposeID == sBankDisposeList[i]) {
return true;
}
}
return false;
}
+52
View File
@@ -0,0 +1,52 @@
//
// JASCmdStack
//
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASCmdStack.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
#include <os.h>
JASPortCmd::TPortHead JASPortCmd::sCommandListOnce;
JASPortCmd::TPortHead JASPortCmd::sCommandListStay;
bool JASPortCmd::addPortCmdOnce() {
JASCriticalSection cs;
return sCommandListOnce.append(this);
}
bool JASPortCmd::setPortCmd(Command func, JASPortArgs* args) {
JUT_ASSERT(81, func != NULL);
if (getSupervisor()) {
return false;
}
mFunc = func;
mArgs = args;
return true;
}
void JASPortCmd::execAllCommand() {
sCommandListOnce.execCommandOnce();
sCommandListStay.execCommandStay();
}
void JASPortCmd::TPortHead::execCommandOnce() {
JASCriticalSection cs;
JSULink<JASPortCmd>* next;
for (JSULink<JASPortCmd>* link = getFirst(); link != NULL; link = next) {
next = link->getNext();
JASPortCmd* cmd = link->getObject();
cmd->getFunc()(cmd->getArgs());
remove(link);
}
}
void JASPortCmd::TPortHead::execCommandStay() {
JASCriticalSection cs;
for (JSULink<JASPortCmd>* link = getFirst(); link != NULL; link = link->getNext()) {
JASPortCmd* cmd = link->getObject();
cmd->getFunc()(cmd->getArgs());
}
}
+259
View File
@@ -0,0 +1,259 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASDSPChannel.h"
#include "JSystem/JAudio2/JASHeapCtrl.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
JASDSPChannel* JASDSPChannel::sDspChannels;
JASDSPChannel::JASDSPChannel() :
mStatus(STATUS_INACTIVE),
mPriority(-1),
mFlags(0),
field_0xc(0),
mCallback(NULL),
mCallbackData(NULL),
mChannel(NULL)
{
/* empty function */
}
void JASDSPChannel::free() {
mCallback = NULL;
mCallbackData = NULL;
}
void JASDSPChannel::start() {
mFlags |= 1;
}
void JASDSPChannel::drop() {
if (mCallback != NULL) {
mCallback(CB_DROP, NULL, mCallbackData);
}
mCallback = NULL;
mCallbackData = NULL;
mPriority = -1;
mFlags &= ~1;
if (mStatus == STATUS_ACTIVE) {
mFlags |= 2;
mStatus = STATUS_DROP;
}
}
void JASDSPChannel::initAll() {
sDspChannels = new (JASDram, 0x20) JASDSPChannel[0x40];
JUT_ASSERT(102, sDspChannels);
for (int i = 0; i < 0x40; i++) {
sDspChannels[i].mChannel = JASDsp::getDSPHandle(i);
}
}
JASDSPChannel* JASDSPChannel::alloc(u8 i_priority, Callback i_callback, void* i_callbackData) {
JASDSPChannel* channel = getLowestChannel(i_priority);
if (channel == NULL) {
return NULL;
}
channel->drop();
channel->mPriority = i_priority;
channel->field_0xc = 0;
channel->mCallback = i_callback;
channel->mCallbackData = i_callbackData;
return channel;
}
JASDSPChannel* JASDSPChannel::allocForce(u8 i_priority, Callback i_callback, void* i_callbackData) {
JASDSPChannel* channel = getLowestChannel(i_priority);
if (channel == NULL) {
return NULL;
}
channel->mStatus = STATUS_INACTIVE;
channel->drop();
channel->mPriority = i_priority;
channel->field_0xc = 0;
channel->mCallback = i_callback;
channel->mCallbackData = i_callbackData;
return channel;
}
void JASDSPChannel::setPriority(u8 i_priority) {
mPriority = i_priority;
}
JASDSPChannel* JASDSPChannel::getLowestChannel(int i_priority) {
s16 best_priority = 0xff;
int best_index = -1;
int best_unknown = 0;
for (int i = 0; i < 0x40; i++) {
JASDSPChannel* channel = &sDspChannels[i];
s16 priority = channel->mPriority;
if (priority < 0) {
return &sDspChannels[i];
}
if (priority <= i_priority && priority <= best_priority) {
if (priority != best_priority || channel->field_0xc > best_unknown) {
best_unknown = channel->field_0xc;
best_index = i;
best_priority = priority;
}
}
}
if (best_index < 0) {
return NULL;
}
return &sDspChannels[best_index];
}
JASDSPChannel* JASDSPChannel::getLowestActiveChannel() {
s16 best_priority = 0xff;
int best_index = -1;
int best_unknown = 0;
for (int i = 0; i < 0x40; i++) {
JASDSPChannel* channel = &sDspChannels[i];
if (channel->mStatus == STATUS_ACTIVE) {
s16 priority = channel->mPriority;
if (priority < 0x7f && priority <= best_priority) {
if (priority != best_priority || channel->field_0xc > best_unknown) {
best_unknown = channel->field_0xc;
best_index = i;
best_priority = priority;
}
}
}
}
if (best_index < 0) {
return NULL;
}
return &sDspChannels[best_index];
}
void JASDSPChannel::updateProc() {
int ret = 0;
bool flush;
if (mChannel->isFinish()) {
mFlags &= ~2;
if (mStatus == STATUS_ACTIVE) {
if (mCallback != NULL) {
ret = mCallback(CB_STOP, NULL, mCallbackData);
} else {
ret = -1;
}
if (ret < 0) {
mPriority = -1;
}
}
mStatus = STATUS_INACTIVE;
mChannel->replyFinishRequest();
mChannel->flush();
} else if (mFlags & 2) {
mFlags &= ~2;
mChannel->forceStop();
mChannel->flush();
} else if (mStatus != STATUS_DROP) {
if ((mFlags & 1) && mStatus == STATUS_INACTIVE) {
mFlags &= ~1;
mStatus = STATUS_ACTIVE;
mChannel->init();
if (mCallback != NULL) {
ret = mCallback(CB_START, mChannel, mCallbackData);
} else {
ret = 0;
}
if (ret < 0) {
mStatus = STATUS_INACTIVE;
if (mCallback != NULL) {
ret = mCallback(CB_STOP, NULL, mCallbackData);
} else {
ret = -1;
}
if (ret < 0) {
mPriority = -1;
}
mChannel->flush();
} else {
mChannel->playStart();
mChannel->flush();
}
} else if (mStatus != STATUS_INACTIVE) {
flush = false;
if (mCallback != NULL) {
ret = mCallback(CB_PLAY, mChannel, mCallbackData);
flush = true;
} else {
ret = 0;
}
if (ret < 0) {
mStatus = STATUS_INACTIVE;
if (mCallback != NULL) {
ret = mCallback(CB_STOP, NULL, mCallbackData);
} else {
ret = -1;
}
if (ret < 0) {
mPriority = -1;
}
mChannel->playStop();
mChannel->flush();
} else {
field_0xc++;
if (flush) {
mChannel->flush();
}
}
}
}
}
void JASDSPChannel::updateAll() {
for (u32 i = 0; i < 0x40; i++) {
if ((i & 0xf) == 0 && i != 0) {
JASDsp::releaseHalt((i - 1) >> 4);
}
sDspChannels[i].updateProc();
}
JASDsp::releaseHalt(3);
}
int JASDSPChannel::killActiveChannel() {
JASDSPChannel* channel = getLowestActiveChannel();
if (channel == NULL) {
return 0;
} else {
channel->drop();
return 1;
}
}
JASDSPChannel* JASDSPChannel::getHandle(u32 i_index) {
return &sDspChannels[i_index];
}
u32 JASDSPChannel::getNumUse() {
u32 count = 0;
for (int i = 0; i < 0x40; i++) {
if (sDspChannels[i].mStatus == 0) {
count++;
}
}
return count;
}
u32 JASDSPChannel::getNumFree() {
u32 count = 0;
for (int i = 0; i < 0x40; i++) {
if (sDspChannels[i].mStatus == 1) {
count++;
}
}
return count;
}
u32 JASDSPChannel::getNumBreak() {
u32 count = 0;
for (int i = 0; i < 0x40; i++) {
if (sDspChannels[i].mStatus == 2) {
count++;
}
}
return count;
}
@@ -0,0 +1,724 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASDSPInterface.h"
#include "JSystem/JAudio2/JASCalc.h"
#include "JSystem/JAudio2/JASHeapCtrl.h"
#include "JSystem/JAudio2/JASWaveInfo.h"
#include "JSystem/JAudio2/dspproc.h"
#include "JSystem/JAudio2/dsptask.h"
#include "JSystem/JAudio2/osdsp_task.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
#include <os.h>
JASDsp::TChannel* JASDsp::CH_BUF;
JASDsp::FxBuf* JASDsp::FX_BUF;
f32 JASDsp::sDSPVolume;
u16 JASDsp::SEND_TABLE[] = {
0x0D00,
0x0D60,
0x0DC8,
0x0E28,
0x0E88,
0x0EE8,
0x0CA0,
0x0F40,
0x0FA0,
0x0B00,
0x09A0,
0x0000,
};
u32 JASWaveInfo::one = 1;
#if DEBUG
s32 JASDsp::dspMutex = 1;
#endif
void JASDsp::boot(void (*param_0)(void*)) {
static bool data_804512F4 = true;
if (data_804512F4) {
DspBoot(param_0);
#if !PLATFORM_GCN
// DsetVARAM(JKRHeap::getAltAramStartAdr());
#endif
data_804512F4 = false;
}
}
void JASDsp::releaseHalt(u32 param_0) {
DSPReleaseHalt2(param_0);
}
void JASDsp::finishWork(u16 param_0) {
DspFinishWork(param_0);
}
void JASDsp::syncFrame(u32 param_0, u32 param_1, u32 param_2) {
DsyncFrame2(param_0, param_1, param_2);
}
void JASDsp::setDSPMixerLevel(f32 dsp_level) {
sDSPVolume = dsp_level;
dsp_level *= 4.0f;
JUT_ASSERT(277, (0.0 <= dsp_level) && (dsp_level <= 8.0));
DsetMixerLevel(dsp_level);
}
f32 JASDsp::getDSPMixerLevel() {
return sDSPVolume;
}
JASDsp::TChannel* JASDsp::getDSPHandle(int param_0) {
return CH_BUF + param_0;
}
JASDsp::TChannel* JASDsp::getDSPHandleNc(int param_0) {
return (TChannel*)OSCachedToUncached(CH_BUF + param_0);
}
void JASDsp::setFilterTable(s16* param_0, s16* param_1, u32 param_2) {
for (int i = 0; i < param_2; i++) {
*param_0++ = *param_1++;
}
}
void JASDsp::flushBuffer() {
DCFlushRange(CH_BUF, sizeof(TChannel) * 64);
DCFlushRange(FX_BUF, sizeof(FxBuf) * 4);
}
void JASDsp::invalChannelAll() {
DCInvalidateRange(CH_BUF, sizeof(TChannel) * 64);
}
u8 const ATTRIBUTE_ALIGN(32) JASDsp::DSPADPCM_FILTER[64] = {
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00,
0x10, 0x00, 0xF8, 0x00, 0x0E, 0x00, 0xFA, 0x00, 0x0C, 0x00, 0xFC, 0x00, 0x12, 0x00, 0xF6, 0x00,
0x10, 0x68, 0xF7, 0x38, 0x12, 0xC0, 0xF7, 0x04, 0x14, 0x00, 0xF4, 0x00, 0x08, 0x00, 0xF8, 0x00,
0x04, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x04, 0x00, 0xFC, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00,
};
u32 const ATTRIBUTE_ALIGN(32) JASDsp::DSPRES_FILTER[320] = {
0x0C3966AD,
0x0D46FFDF,
0x0B396696,
0x0E5FFFD8,
0x0A446669,
0x0F83FFD0,
0x095A6626,
0x10B4FFC8,
0x087D65CD,
0x11F0FFBF,
0x07AB655E,
0x1338FFB6,
0x06E464D9,
0x148CFFAC,
0x0628643F,
0x15EBFFA1,
0x0577638F,
0x1756FF96,
0x04D162CB,
0x18CBFF8A,
0x043561F3,
0x1A4CFF7E,
0x03A46106,
0x1BD7FF71,
0x031C6007,
0x1D6CFF64,
0x029F5EF5,
0x1F0BFF56,
0x022A5DD0,
0x20B3FF48,
0x01BE5C9A,
0x2264FF3A,
0x015B5B53,
0x241EFF2C,
0x010159FC,
0x25E0FF1E,
0x00AE5896,
0x27A9FF10,
0x00635720,
0x297AFF02,
0x001F559D,
0x2B50FEF4,
0xFFE2540D,
0x2D2CFEE8,
0xFFAC5270,
0x2F0DFEDB,
0xFF7C50C7,
0x30F3FED0,
0xFF534F14,
0x32DCFEC6,
0xFF2E4D57,
0x34C8FEBD,
0xFF0F4B91,
0x36B6FEB6,
0xFEF549C2,
0x38A5FEB0,
0xFEDF47ED,
0x3A95FEAC,
0xFECE4611,
0x3C85FEAB,
0xFEC04430,
0x3E74FEAC,
0xFEB6424A,
0x4060FEAF,
0xFEAF4060,
0x424AFEB6,
0xFEAC3E74,
0x4430FEC0,
0xFEAB3C85,
0x4611FECE,
0xFEAC3A95,
0x47EDFEDF,
0xFEB038A5,
0x49C2FEF5,
0xFEB636B6,
0x4B91FF0F,
0xFEBD34C8,
0x4D57FF2E,
0xFEC632DC,
0x4F14FF53,
0xFED030F3,
0x50C7FF7C,
0xFEDB2F0D,
0x5270FFAC,
0xFEE82D2C,
0x540DFFE2,
0xFEF42B50,
0x559D001F,
0xFF02297A,
0x57200063,
0xFF1027A9,
0x589600AE,
0xFF1E25E0,
0x59FC0101,
0xFF2C241E,
0x5B53015B,
0xFF3A2264,
0x5C9A01BE,
0xFF4820B3,
0x5DD0022A,
0xFF561F0B,
0x5EF5029F,
0xFF641D6C,
0x6007031C,
0xFF711BD7,
0x610603A4,
0xFF7E1A4C,
0x61F30435,
0xFF8A18CB,
0x62CB04D1,
0xFF961756,
0x638F0577,
0xFFA115EB,
0x643F0628,
0xFFAC148C,
0x64D906E4,
0xFFB61338,
0x655E07AB,
0xFFBF11F0,
0x65CD087D,
0xFFC810B4,
0x6626095A,
0xFFD00F83,
0x66690A44,
0xFFD80E5F,
0x66960B39,
0xFFDF0D46,
0x66AD0C39,
0x00000C8B,
0x18F82527,
0x30FB3C56,
0x471C5133,
0x5A8262F1,
0x6A6D70E2,
0x76417A7C,
0x7D897F61,
0x7FFF7F61,
0x7D897A7C,
0x764170E2,
0x6A6D62F1,
0x5A825133,
0x471C3C56,
0x30FB2527,
0x18F80C8B,
0x0000F375,
0xE708DAD9,
0xCF05C3AA,
0xB8E4AECD,
0xA57E9D0F,
0x95938F1E,
0x89BF8584,
0x8277809F,
0x8001809F,
0x82778584,
0x89BF8F1E,
0x95939D0F,
0xA57EAECD,
0xB8E4C3AA,
0xCF05DAD9,
0xE708F375,
0x000007FF,
0x0FFF17FF,
0x1FFF27FF,
0x2FFF37FF,
0x3FFF47FF,
0x4FFF57FF,
0x5FFF67FF,
0x6FFF77FF,
0x7FFF7800,
0x70006800,
0x60005800,
0x50004800,
0x40003800,
0x30002800,
0x20001800,
0x10000800,
0x0000F801,
0xF001E801,
0xE001D801,
0xD001C801,
0xC001B801,
0xB001A801,
0xA0019801,
0x90018801,
0x80018800,
0x90009800,
0xA000A800,
0xB000B800,
0xC000C800,
0xD000D800,
0xE000E800,
0xF000F800,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0x1FFF3FFF,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0x1FFFC001,
0x00000192,
0x032404B6,
0x064707D9,
0x096A0AFB,
0x0C8B0E1B,
0x0FAB1139,
0x12C71455,
0x15E1176D,
0x18F81A82,
0x1C0B1D93,
0x1F19209F,
0x222323A6,
0x252726A7,
0x282629A3,
0x2B1F2C98,
0x2E102F87,
0x30FB326E,
0x33DE354D,
0x36B93824,
0x398C3AF2,
0x3C563DB7,
0x3F174073,
0x41CD4325,
0x447A45CC,
0x471C4869,
0x49B34AFB,
0x4C3F4D81,
0x4EBF4FFB,
0x51335268,
0x539A54C9,
0x55F5571D,
0x58425964,
0x5A825B9C,
0x5CB35DC7,
0x5ED75FE3,
0x60EB61F0,
0x62F163EE,
0x64E865DD,
0x66CF67BC,
0x68A6698B,
0x6A6D6B4A,
0x6C236CF8,
0x6DC96E96,
0x6F5E7022,
0x70E2719D,
0x72547307,
0x73B5745F,
0x750475A5,
0x764176D8,
0x776B77FA,
0x78847909,
0x79897A05,
0x7A7C7AEE,
0x7B5C7BC5,
0x7C297C88,
0x7CE37D39,
0x7D897DD5,
0x7E1D7E5F,
0x7E9C7ED5,
0x7F097F37,
0x7F617F86,
0x7FA67FC1,
0x7FD87FE9,
0x7FF57FFD,
};
void JASDsp::initBuffer() {
CH_BUF = new(JASDram, 0x20) TChannel[64];
JUT_ASSERT(354, CH_BUF);
FX_BUF = new(JASDram, 0x20) FxBuf[4];
JUT_ASSERT(356, FX_BUF);
JASCalc::bzero(CH_BUF, 0x6000);
JASCalc::bzero(FX_BUF, sizeof(FxBuf) * 4);
for (u8 i = 0; i < 4; i++) {
setFXLine(i, NULL, NULL);
}
DsetupTable(0x40, u32(CH_BUF), u32(&DSPRES_FILTER), u32(&DSPADPCM_FILTER), u32(FX_BUF));
flushBuffer();
}
int JASDsp::setFXLine(u8 param_0, s16* buffer, JASDsp::FxlineConfig_* param_2) {
FxBuf* puVar3 = FX_BUF + param_0;
JASCriticalSection aJStack_20;
puVar3->field_0x0 = 0;
if (param_2 != NULL) {
puVar3->field_0xa = param_2->field_0x4;
puVar3->field_0x8 = SEND_TABLE[param_2->field_0x2];
puVar3->field_0xe = param_2->field_0x8;
puVar3->field_0xc = SEND_TABLE[param_2->field_0x6];
puVar3->field_0x2 = param_2->field_0xc;
setFilterTable((s16*)puVar3->field_0x10, param_2->field_0x10, 8);
}
if (buffer != NULL && param_2 != NULL) {
u32 bufsize = param_2->field_0xc * 0xa0;
puVar3->field_0x4 = buffer;
JASCalc::bzero(buffer, bufsize);
JUT_ASSERT(420, (reinterpret_cast<u32>(buffer) & 0x1f) == 0);
JUT_ASSERT(421, (bufsize & 0x1f) == 0);
DCFlushRange(buffer, bufsize);
} else if (param_2 == NULL || buffer != NULL) {
puVar3->field_0x4 = buffer;
}
if (puVar3->field_0x4 != NULL) {
puVar3->field_0x0 = param_2->field_0x0;
} else {
puVar3->field_0x0 = 0;
}
DCFlushRange(puVar3, sizeof(FxBuf));
return 1;
}
BOOL JASDsp::changeFXLineParam(u8 param_0, u8 param_1, uintptr_t param_2) {
JUT_ASSERT(450, dspMutex);
FxBuf* buf = &FX_BUF[param_0];
switch (param_1) {
case 0: buf->field_0x8 = param_2; break;
case 1: buf->field_0xc = param_2; break;
case 2: buf->field_0xa = param_2; break;
case 3: buf->field_0xe = param_2; break;
case 4: buf->field_0x2 = param_2; break;
case 5: buf->field_0x10[0] = param_2; break;
case 6: buf->field_0x10[1] = param_2; break;
case 7: buf->field_0x10[2] = param_2; break;
case 8: buf->field_0x10[3] = param_2; break;
case 9: buf->field_0x10[4] = param_2; break;
case 10: buf->field_0x10[5] = param_2; break;
case 11: buf->field_0x10[6] = param_2; break;
case 12: buf->field_0x10[7] = param_2; break;
case 13: setFilterTable((s16*)buf->field_0x10, (s16*)param_2, 8); break;
case 14: buf->field_0x0 = param_2; break;
}
return 1;
}
void JASDsp::TChannel::init() {
JUT_ASSERT(489, dspMutex);
mPauseFlag = 0;
mIsFinished = 0;
mForcedStop = 0;
mIsActive = 0;
field_0x058 = 0;
field_0x068 = 0;
initFilter();
}
void JASDsp::TChannel::playStart() {
JUT_ASSERT(508, dspMutex);
field_0x10c = 0;
field_0x060 = 0;
field_0x008 = 1;
field_0x066 = 0;
int i;
for (i = 0; i < 4; i++) {
field_0x078[i] = 0;
field_0x0a8[i] = 0;
}
for (i = 0; i < 20; i++) {
field_0x080[i] = 0;
}
mIsActive = 1;
}
void JASDsp::TChannel::playStop() {
JUT_ASSERT(540, dspMutex);
mIsActive = 0;
}
void JASDsp::TChannel::replyFinishRequest() {
JUT_ASSERT(549, dspMutex);
mIsFinished = 0;
mIsActive = 0;
}
void JASDsp::TChannel::forceStop() {
JUT_ASSERT(559, dspMutex);
mForcedStop = 1;
}
bool JASDsp::TChannel::isActive() const {
JUT_ASSERT(568, dspMutex);
return mIsActive != 0;
}
bool JASDsp::TChannel::isFinish() const {
JUT_ASSERT(577, dspMutex);
return mIsFinished != 0;
}
void JASDsp::TChannel::setWaveInfo(JASWaveInfo const& param_0, u32 param_1, u32 param_2) {
int i;
JUT_ASSERT(610, dspMutex);
field_0x118 = param_1;
static const u8 COMP_BLOCKSAMPLES[8] = {0x10, 0x10, 0x01, 0x01, 0x01, 0x10, 0x10, 0x01};
field_0x064 = COMP_BLOCKSAMPLES[param_0.field_0x00];
static const u8 COMP_BLOCKBYTES[8] = {0x09, 0x05, 0x08, 0x10, 0x01, 0x01, 0x01, 0x01};
field_0x100 = COMP_BLOCKBYTES[param_0.field_0x00];
field_0x068 = 0;
if (field_0x100 >= 4) {
field_0x11c = param_0.field_0x18;
field_0x102 = param_0.field_0x02;
if (field_0x102) {
if (param_2 == 1) {
param_2 = param_0.field_0x10;
}
field_0x110 = param_0.field_0x10;
field_0x114 = param_0.field_0x14;
field_0x104 = param_0.field_0x1c;
field_0x106 = param_0.field_0x1e;
} else {
field_0x114 = field_0x11c;
}
if (param_2 && field_0x114 > param_2) {
switch (param_0.field_0x00) {
case 0:
case 1:
field_0x068 = param_2;
field_0x118 += param_2 * field_0x100 >> 4;
field_0x110 -= param_2;
field_0x114 -= param_2;
break;
case 2:
case 3:
field_0x068 = param_2;
break;
}
}
for (i = 0; i < 16; i++) {
field_0x0b0[i] = 0;
}
}
}
void JASDsp::TChannel::setOscInfo(u32 param_0) {
JUT_ASSERT(671, dspMutex);
field_0x118 = 0;
field_0x064 = 16;
field_0x100 = param_0;
}
void JASDsp::TChannel::initAutoMixer() {
JUT_ASSERT(688, dspMutex);
if (field_0x058) {
field_0x054 = field_0x056;
} else {
field_0x054 = 0;
field_0x058 = 1;
}
}
void JASDsp::TChannel::setAutoMixer(u16 param_0, u8 param_1, u8 param_2, u8 param_3,
u8 param_4) {
JUT_ASSERT(709, dspMutex);
field_0x050 = (param_1 << 8) | param_2;
field_0x052 = param_3 << 8 | param_3 << 1;
field_0x056 = param_0;
field_0x058 = 1;
}
void JASDsp::TChannel::setPitch(u16 param_0) {
JUT_ASSERT(763, dspMutex);
if (param_0 >= 0x7fff) {
param_0 = 0x7fff;
}
mPitch = param_0;
}
void JASDsp::TChannel::setMixerInitVolume(u8 param_0, s16 param_1) {
JUT_ASSERT(798, dspMutex);
u16* tmp = field_0x010[param_0];
tmp[2] = param_1;
tmp[1] = param_1;
tmp[3] = 0;
}
void JASDsp::TChannel::setMixerVolume(u8 param_0, s16 param_1) {
u16* tmp;
JUT_ASSERT(841, dspMutex);
if (mForcedStop == 0) {
tmp = field_0x010[param_0];
tmp[1] = param_1;
tmp[3] &= 0xff;
}
}
void JASDsp::TChannel::setPauseFlag(u8 param_0) {
JUT_ASSERT(863, dspMutex);
mPauseFlag = param_0;
}
void JASDsp::TChannel::flush() {
DCFlushRange(this, sizeof(*this));
}
void JASDsp::TChannel::initFilter() {
u32 i;
JUT_ASSERT(888, dspMutex);
for (i = 0; i < 8; i++) {
fir_filter_params[i] = 0;
}
fir_filter_params[0] = 0x7fff;
for (i = 0; i < 8; i++) {
iir_filter_params[i] = 0;
}
iir_filter_params[0] = 0x7fff;
iir_filter_params[4] = 0;
}
void JASDsp::TChannel::setFilterMode(u16 param_0) {
JUT_ASSERT(914, dspMutex);
u8 r30 = param_0 & 0x20;
u8 r31 = param_0 & 0x1f;
if (r30) {
if (r31 > 0x14) {
r31 = 0x14;
}
} else {
if (r31 > 0x18) {
r31 = 0x18;
}
}
mFilterMode = r30 + r31;
}
void JASDsp::TChannel::setIIRFilterParam(s16* param_0) {
JUT_ASSERT(937, dspMutex);
setFilterTable(iir_filter_params, param_0, 8);
}
void JASDsp::TChannel::setFIR8FilterParam(s16* param_0) {
JUT_ASSERT(948, dspMutex);
setFilterTable(fir_filter_params, param_0, 8);
}
void JASDsp::TChannel::setDistFilter(s16 param_0) {
JUT_ASSERT(959, dspMutex);
iir_filter_params[4] = param_0;
}
void JASDsp::TChannel::setBusConnect(u8 param_0, u8 param_1) {
JUT_ASSERT(973, dspMutex);
u16* tmp = field_0x010[param_0];
static u16 const connect_table[12] = {
0x0000, 0x0D00, 0x0D60, 0x0DC0, 0x0E20, 0x0E80,
0x0EE0, 0x0CA0, 0x0F40, 0x0FA0, 0x0B00, 0x09A0,
};
u16 r30 = 0;
r30 = connect_table[param_1];
tmp[0] = r30;
}
u16 DSP_CreateMap2(u32 param_0) {
u16 r30 = 0;
JASDsp::TChannel* channel = &JASDsp::CH_BUF[param_0 << 4];
for (int i = 0; i < 16; i++) {
r30 <<= 1;
if (channel->isActive()) {
r30 |= 1;
}
channel++;
}
return r30;
}
+74
View File
@@ -0,0 +1,74 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASDriverIF.h"
#include "JSystem/JAudio2/JASAiCtrl.h"
#include "JSystem/JAudio2/JASDSPInterface.h"
#include <os.h>
void JASDriver::setDSPLevel(f32 param_0) {
JASDsp::setDSPMixerLevel(param_0);
}
u16 JASDriver::MAX_MIXERLEVEL = 0x2EE0;
u16 JASDriver::getChannelLevel_dsp() {
return JASDriver::MAX_MIXERLEVEL;
}
f32 JASDriver::getChannelLevel() {
return MAX_MIXERLEVEL / 16383.5f;
}
f32 JASDriver::getDSPLevel() {
return JASDsp::getDSPMixerLevel();
}
u32 JASDriver::JAS_SYSTEM_OUTPUT_MODE = 0x00000001;
void JASDriver::setOutputMode(u32 param_0) {
JAS_SYSTEM_OUTPUT_MODE = param_0;
}
u32 JASDriver::getOutputMode() {
return JASDriver::JAS_SYSTEM_OUTPUT_MODE;
}
void JASDriver::waitSubFrame() {
u32 r31 = getSubFrameCounter();
do {
OSYieldThread();
} while (r31 == getSubFrameCounter());
}
JASCallbackMgr JASDriver::sDspSyncCallback;
JASCallbackMgr JASDriver::sSubFrameCallback;
JASCallbackMgr JASDriver::sUpdateDacCallback;
int JASDriver::rejectCallback(DriverCallback callback, void* param_1) {
int r31 = sDspSyncCallback.reject(callback, param_1);
r31 += sSubFrameCallback.reject(callback, param_1);
r31 += sUpdateDacCallback.reject(callback, param_1);
return r31;
}
bool JASDriver::registerDspSyncCallback(DriverCallback callback, void* param_1) {
return sDspSyncCallback.regist(callback, param_1);
}
bool JASDriver::registerSubFrameCallback(DriverCallback callback, void* param_1) {
return sSubFrameCallback.regist(callback, param_1);
}
void JASDriver::subframeCallback() {
sSubFrameCallback.callback();
}
void JASDriver::DSPSyncCallback() {
sDspSyncCallback.callback();
}
void JASDriver::updateDacCallback() {
sUpdateDacCallback.callback();
}
+114
View File
@@ -0,0 +1,114 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASDrumSet.h"
#include "JSystem/JAudio2/JASCalc.h"
#include "JSystem/JKernel/JKRHeap.h"
JASDrumSet::JASDrumSet() {
mPercArray = NULL;
mPercNumMax = 0;
}
JASDrumSet::~JASDrumSet() {
}
void JASDrumSet::newPercArray(u8 num, JKRHeap* heap) {
if (num) {
JUT_ASSERT(39, num <= 128);
mPercNumMax = num;
mPercArray = new (heap, 0) TPerc*[mPercNumMax];
JASCalc::bzero(mPercArray, mPercNumMax * sizeof(TPerc*));
}
}
bool JASDrumSet::getParam(int key, int param_1, JASInstParam* param_2) const {
UNUSED(param_1);
JUT_ASSERT(48, key >= 0);
if (mPercArray == NULL) {
return false;
}
if (key >= mPercNumMax) {
JUT_WARN(54, "JASDrumSet: key %d >= PERC_MAX %d\n", key, mPercNumMax);
return false;
}
TPerc* perc = mPercArray[key];
if (perc == NULL) {
return false;
}
param_2->field_0x1c = 0;
param_2->field_0x1e = 1;
param_2->mVolume = perc->mVolume;
param_2->mPitch = perc->mPitch;
param_2->mPan = perc->mPan;
param_2->field_0x18 = u16(perc->field_0xc);
static JASOscillator::Data osc;
osc.mTarget = 0;
osc._04 = 1.0f;
osc.mTable = NULL;
osc.rel_table = NULL;
osc.mScale = 1.0f;
osc._14 = 0.0f;
static JASOscillator::Data* oscp = &osc;
param_2->field_0x14 = &oscp;
param_2->field_0x1d = 1;
param_2->mVolume *= perc->field_0x10;
param_2->mPitch *= perc->field_0x14;
param_2->field_0x1a = u16(perc->field_0xe);
return true;
}
void JASDrumSet::setPerc(int index, JASDrumSet::TPerc* param_1) {
JUT_ASSERT(123, index >= 0);
JUT_ASSERT(125, index < mPercNumMax);
JUT_ASSERT(126, mPercArray);
JUT_ASSERT(127, mPercArray[index] == 0);
mPercArray[index] = param_1;
}
JASDrumSet::TPerc* JASDrumSet::getPerc(int index) {
if (index < 0) {
return NULL;
}
if (index >= mPercNumMax) {
return NULL;
}
if (!mPercArray) {
return NULL;
}
return mPercArray[index];
}
JASDrumSet::TPerc* JASDrumSet::getPerc(int index) const {
if (index < 0) {
return NULL;
}
if (index >= mPercNumMax) {
return NULL;
}
if (!mPercArray) {
return NULL;
}
return mPercArray[index];
}
JASDrumSet::TPerc::TPerc() {
mVolume = 1.0f;
mPitch = 1.0f;
mPan = 0.5f;
field_0xc = 1000;
}
void JASDrumSet::TPerc::setRelease(u32 release) {
JUT_ASSERT(224, release < 0x10000);
field_0xc = release;
}
u32 JASDrumSet::getType() const { return 'PERC'; }
+28
View File
@@ -0,0 +1,28 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASDvdThread.h"
#include "JSystem/JAudio2/JASTaskThread.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
JASTaskThread* JASDvd::sThread;
JASTaskThread* JASDvd::getThreadPointer() {
return JASDvd::sThread;
}
bool JASDvd::createThread(s32 priority, int msgCount, u32 stackSize) {
if (sThread != NULL) {
JUT_WARN_DEVICE(32, 2, "%s", "JASDvd::createThread が2回呼び出されました");
return false;
}
sThread = new (JASDram, 0) JASTaskThread(priority, msgCount, stackSize);
JUT_ASSERT(36, sThread);
JKRHeap* pCurrentHeap = JKRGetSystemHeap();
JUT_ASSERT(38, pCurrentHeap);
sThread->setCurrentHeap(pCurrentHeap);
sThread->resume();
return true;
}
+336
View File
@@ -0,0 +1,336 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASHeapCtrl.h"
#include "JSystem/JAudio2/JASMutex.h"
#include "JSystem/JAudio2/JASWaveArcLoader.h"
#include "JSystem/JKernel/JKRExpHeap.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
#include "JSystem/JUtility/JUTAssert.h"
#ifdef __REVOLUTION_SDK__
#include <revolution/aralt.h>
#else
#include <dolphin/ar.h>
#endif
JASHeap::JASHeap(JASDisposer* disposer) : mTree(this) {
mDisposer = disposer;
mBase = NULL;
mSize = 0;
field_0x40 = 0;
OSInitMutex(&mMutex);
}
void JASHeap::initRootHeap(void* param_0, u32 param_1) {
JUT_ASSERT(97, ! isAllocated());
JASMutexLock lock(&mMutex);
mBase = (u8*)OSRoundUp32B(param_0);
field_0x40 = NULL;
mSize = param_1 - (u32(mBase) - u32(param_0));
}
bool JASHeap::alloc(JASHeap* mother, u32 param_1) {
JUT_ASSERT(120, mother != NULL);
JASMutexLock lock(&mMutex);
if (isAllocated()) {
OS_REPORT("[JASHeap::alloc] すでにヒープは確保されています。初期化してからにしてください。\n");
return 0;
}
if (!mother->isAllocated()) {
return 0;
}
param_1 = OSRoundUp32B(param_1);
u32 local_28 = mother->getCurOffset();
u32 local_2c = mother->getTailOffset();
if (local_28 + param_1 <= local_2c) {
mother->insertChild(this, mother->getTailHeap(), mother->mBase + local_28, param_1, false);
return 1;
}
s32 r27 = -1;
u8* r29 = mother->mBase;
bool local_43 = false;
JASHeap* local_30 = NULL;
void* local_34;
JSUTreeIterator<JASHeap> it;
for (it = mother->mTree.getFirstChild(); it != mother->mTree.getEndChild(); it++) {
if (r29 >= mother->mBase + local_2c) {
break;
}
u32 local_3c = u32(it->mBase) - u32(r29);
if (local_3c >= param_1 && local_3c < r27) {
local_30 = *it;
local_34 = r29;
r27 = local_3c;
local_43 = true;
}
u32 r25 = it->mSize;
r29 = (u8*)it->mBase + r25;
}
if (r29 != mother->mBase && r29 < mother->mBase + local_2c) {
u32 local_40 = mother->mBase + mother->mSize - r29;
if (local_40 >= param_1 && local_40 < r27) {
local_30 = NULL;
local_34 = r29;
r27 = local_40;
local_43 = true;
}
}
if (!local_43) {
OS_REPORT("[JASHeap::alloc] マザーメモリが足りないので確保できません。\n");
return 0;
}
mother->insertChild(this, local_30, local_34, param_1, false);
return 1;
}
bool JASHeap::allocTail(JASHeap* mother, u32 size) {
JUT_ASSERT(208, mother != NULL);
JASMutexLock lock(&mMutex);
if (isAllocated()) {
OS_REPORT("[JASHeap::alloc] すでにヒープは確保されています。初期化してからにしてください。\n");
return false;
}
if (!mother->isAllocated()) {
return false;
}
u32 aligned_size = (size + 0x1f) & ~0x1f;
u32 cur_offset = mother->getCurOffset();
u32 tail_offset = mother->getTailOffset();
if (cur_offset + aligned_size > tail_offset) {
return false;
}
mother->insertChild(this, mother->getTailHeap(), mother->mBase + tail_offset - aligned_size,
aligned_size, true);
return true;
}
bool JASHeap::free() {
JASMutexLock lock(&mMutex);
if (!isAllocated()) {
return false;
}
JSUTreeIterator<JASHeap> stack_20;
for (JSUTreeIterator<JASHeap> it(mTree.getFirstChild()); it != mTree.getEndChild(); it = stack_20) {
stack_20 = it;
++stack_20;
it->free();
}
JSUTree<JASHeap>* parentTree = mTree.getParent();
if (parentTree) {
JASHeap* parentHeap = parentTree->getObject();
if (parentHeap->field_0x40 == this) {
JSUTreeIterator<JASHeap> stack_28(mTree.getPrevChild());
if (stack_28 != mTree.getEndChild()) {
parentHeap->field_0x40 = *stack_28;
} else {
parentHeap->field_0x40 = NULL;
}
}
parentTree->removeChild(&mTree);
}
mBase = NULL;
field_0x40 = NULL;
mSize = 0;
if (mDisposer) {
mDisposer->onDispose();
}
return true;
}
u32 JASHeap::getTotalFreeSize() const {
JASMutexLock lock(const_cast<OSMutex*>(&mMutex));
u8* r28 = mBase;
u32 r29 = 0;
for (JSUTreeIterator<JASHeap> it = mTree.getFirstChild(); it != mTree.getEndChild(); it++) {
r29 += it->mBase - r28;
u32 r26 = it->mSize;
r28 = it->mBase + r26;
}
r29 += mBase + mSize - r28;
return r29;
}
u32 JASHeap::getFreeSize() const {
JASMutexLock lock(const_cast<OSMutex*>(&mMutex));
u8* r27 = mBase;
u32 r29 = 0;
u32 r28;
for (JSUTreeIterator<JASHeap> it = mTree.getFirstChild(); it != mTree.getEndChild(); it++) {
r28 = it->mBase - r27;
if (r28 > r29) {
r29 = r28;
}
u32 r25 = it->mSize;
r27 = it->mBase + r25;
}
r28 = mBase + mSize - r27;
if (r28 > r29) {
r29 = r28;
}
return r29;
}
void JASHeap::insertChild(JASHeap* heap, JASHeap* next, void* param_2, u32 param_3, bool param_4) {
JUT_ASSERT(513, heap != NULL);
JUT_ASSERT(514, next == NULL || &mTree == next->mTree.getParent());
JASMutexLock lock(&mMutex);
if (!param_4) {
JSUTreeIterator<JASHeap> it;
if (!next) {
it = mTree.getLastChild();
} else {
it = next->mTree.getPrevChild();
}
JASHeap* r24 = it != mTree.getEndChild() ? it.getObject() : NULL;
if (field_0x40 == r24) {
field_0x40 = heap;
}
}
heap->mBase = (u8*)param_2;
heap->mSize = param_3;
heap->field_0x40 = NULL;
mTree.insertChild(&next->mTree, &heap->mTree);
}
JASHeap* JASHeap::getTailHeap() {
int r30 = 0;
JSUTreeIterator<JASHeap> it;
JASMutexLock lock(&mMutex);
if (!field_0x40) {
it = mTree.getFirstChild();
} else {
it = field_0x40->mTree.getNextChild();
}
if (it == mTree.getEndChild()) {
return NULL;
}
return it.getObject();
}
u32 JASHeap::getTailOffset() {
u32 offset = 0;
JASMutexLock lock(&mMutex);
JASHeap* heap = getTailHeap();
if (heap == NULL) {
offset = mSize;
} else {
offset = heap->mBase - mBase;
}
return offset;
}
u32 JASHeap::getCurOffset() {
u32 offset = 0;
JASMutexLock lock(&mMutex);
if (field_0x40 == NULL) {
offset = 0;
} else {
offset = field_0x40->mBase + field_0x40->mSize - mBase;
}
return offset;
}
JASGenericMemPool::JASGenericMemPool() {
field_0x0 = NULL;
freeMemCount = 0;
totalMemCount = 0;
usedMemCount = 0;
}
JASGenericMemPool::~JASGenericMemPool() {
void* chunk = field_0x0;
while (chunk != NULL) {
void* next_chunk = *(void**)chunk;
delete[] chunk;
chunk = next_chunk;
}
}
JKRSolidHeap* JASDram;
// TODO: What is this and Where does it go?
struct TNextOnFreeList {
u8 pad[4];
}; // Size: 0x4
void JASGenericMemPool::newMemPool(u32 n, int param_1) {
JUT_ASSERT(734, n >= sizeof(TNextOnFreeList));
void* runner;
for (int i = 0; i < param_1; i++) {
runner = new (JASDram, 0) u8[n];
JUT_ASSERT(739, runner);
*(void**)runner = field_0x0;
field_0x0 = runner;
}
freeMemCount += param_1;
totalMemCount += param_1;
}
void* JASGenericMemPool::alloc(u32 param_0) {
if (field_0x0 == NULL) {
return NULL;
}
void* chunk = field_0x0;
field_0x0 = *(void**)chunk;
freeMemCount--;
if (usedMemCount < totalMemCount - freeMemCount) {
usedMemCount = totalMemCount - freeMemCount;
}
return chunk;
}
void JASGenericMemPool::free(void* ptr, u32 param_1) {
if (!ptr) {
return;
}
void* chunk = ptr;
*(void**)chunk = field_0x0;
field_0x0 = chunk;
freeMemCount++;
}
uintptr_t JASKernel::sAramBase;
JKRHeap* JASKernel::sSystemHeap;
JASMemChunkPool<1024, JASThreadingModel::ObjectLevelLockable>* JASKernel::sCommandHeap;
void JASKernel::setupRootHeap(JKRSolidHeap* heap, u32 size) {
JUT_ASSERT(784, heap);
sSystemHeap = JKRExpHeap::create(size, heap, false);
JUT_ASSERT(787, sSystemHeap);
sCommandHeap = new (heap, 0) JASMemChunkPool<1024, JASThreadingModel::ObjectLevelLockable>();
JUT_ASSERT(790, sCommandHeap);
JASDram = heap;
}
JKRHeap* JASKernel::getSystemHeap() {
return JASKernel::sSystemHeap;
}
JASMemChunkPool<1024, JASThreadingModel::ObjectLevelLockable>* JASKernel::getCommandHeap() {
return JASKernel::sCommandHeap;
}
JASHeap JASKernel::audioAramHeap;
void JASKernel::setupAramHeap(uintptr_t param_0, u32 param_1) {
#if !PLATFORM_GCN
OSReport("setupAramHeap %x, %x, %x\n", param_0, ARGetBaseAddress(), param_1);
param_0 = ARGetBaseAddress();
#endif
sAramBase = param_0;
audioAramHeap.initRootHeap((void*)sAramBase, param_1);
}
JASHeap* JASKernel::getAramHeap() {
return &audioAramHeap;
}
u32 JASKernel::getAramFreeSize() {
return audioAramHeap.getFreeSize();
}
u32 JASKernel::getAramSize() {
return audioAramHeap.getSize();
}
+55
View File
@@ -0,0 +1,55 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASLfo.h"
#include "SSystem/SComponent/c_math.h"
JASLfo::JASLfo() {
field_0x0 = 0;
field_0x4 = 1;
field_0x8 = 0.0f;
mDepth = 0.0f;
mPitch = 1.0f;
mDelay = 0;
field_0x16 = 0;
}
f32 JASLfo::getValue() const {
if (field_0x16) {
return 0.0f;
}
if (mDepth == 0.0f) {
return 0.0f;
}
return mDepth * JMASinLap(field_0x8);
}
void JASLfo::incCounter(f32 param_0) {
if (field_0x16) {
field_0x16--;
return;
}
field_0x8 += param_0 * ((1.0f / 72.0f) * mPitch);
if (field_0x8 >= 1.0f) {
field_0x8 -= 1.0f;
}
}
JASLfo JASLfo::sFreeRunLfo;
void JASLfo::resetCounter() {
field_0x16 = mDelay;
switch (field_0x4) {
case 0:
field_0x8 = sFreeRunLfo.field_0x8;
break;
case 1:
field_0x8 = 0.0f;
break;
}
}
+172
View File
@@ -0,0 +1,172 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASOscillator.h"
JASOscillator::JASOscillator() {
mData = NULL;
_14 = 0;
mDirectRelease = 0;
_18 = 0;
_1C = 0;
_04 = _08 = _10 = _0C = 0.0f;
}
void JASOscillator::initStart(JASOscillator::Data const* data) {
mData = data;
_04 = 0.0f;
_08 = 0.0f;
_0C = 0.0f;
_14 = 0;
mDirectRelease = 0;
if (!data) {
_1C = 0;
return;
}
if (mData->mTable == NULL) {
_1C = 2;
_08 = 1.0f;
return;
}
_10 = mData->mTable[0]._4 / 32768.0f;
_18 = mData->mTable[0]._0;
_1C = 1;
}
void JASOscillator::incCounter(f32 param_0) {
const short* v1;
switch (_1C) {
case 0:
case 2:
return;
case 1:
break;
}
_04 += param_0 * mData->_04;
update();
}
f32 JASOscillator::getValue() const {
JUT_ASSERT(120, mData);
return _08 * mData->mScale + mData->_14;
}
void JASOscillator::release() {
if (mData->rel_table == NULL && mDirectRelease == 0) {
stop();
return;
}
if (mDirectRelease != 0) {
_04 = 0.0f;
_0C = _08;
_10 = 0.0f;
_14 = 0;
_18 = (mDirectRelease >> 14) & 3;
_1C = 4;
update();
return;
}
if (mData->mTable != mData->rel_table) {
JUT_ASSERT(157, mData->rel_table != NULL);
_04 = 0.0f;
_0C = _08;
_10 = mData->rel_table[0]._4 / 32768.0f;
_14 = 0;
_18 = mData->rel_table[0]._0;
}
_1C = 3;
update();
}
void JASOscillator::update() {
if (_1C == 4) {
s32 x = mDirectRelease & 0x3FFF;
if (_04 < x) {
updateCurrentValue(x);
} else {
_08 = _10;
_1C = 0;
}
return;
}
if (_1C == 2) return;
const Point* psVar1 = _1C == 1 ? mData->mTable : mData->rel_table;
if (psVar1 == NULL) {
_1C = 2;
return;
}
while (_04 >= psVar1[_14]._2) {
_04 -= psVar1[_14]._2;
_08 = _10;
_14++;
_0C = _08;
const s16* ps = &psVar1[_14]._0;
s16 r26 = ps[0];
switch(r26) {
case 0xf:
_1C = 0;
return;
case 0xe:
_1C = 2;
return;
case 0xd:
_14 = ps[2];
break;
default:
_18 = r26;
_10 = ps[2] / 32768.0f;
break;
}
}
updateCurrentValue(psVar1[_14]._2);
}
f32 const JASOscillator::sCurveTableLinear[17] = {
1.0, 0.9375, 0.875, 0.8125, 0.75, 0.6875, 0.625, 0.5625, 0.5,
0.4375, 0.375, 0.3125, 0.25, 0.1875, 0.125, 0.0625, 0.0,
};
f32 const JASOscillator::sCurveTableSampleCell[17] = {
1.0, 0.9704890251159668, 0.7812740206718445, 0.5462809801101685, 0.39979198575019836,
0.28931498527526855, 0.21210399270057678, 0.15747599303722382, 0.1126129999756813, 0.08178959786891937,
0.057985201478004456, 0.04364150017499924, 0.03082370012998581, 0.023712899535894394, 0.015259300358593464,
0.00915555004030466, 0.0
};
f32 const JASOscillator::sCurveTableSqRoot[17] = {
1.0, 0.8789060115814209, 0.765625, 0.6601560115814209, 0.5625, 0.4726560115814209,
0.390625, 0.3164060115814209, 0.25, 0.1914059966802597, 0.140625, 0.09765619784593582,
0.0625, 0.03515620157122612, 0.015625, 0.00390625, 0.0
};
f32 const JASOscillator::sCurveTableSquare[17] = {
1.0, 0.9682459831237793, 0.9354140162467957, 0.9013879895210266, 0.8660249710083008,
0.8291559815406799, 0.790569007396698, 0.75, 0.7071070075035095, 0.66143798828125,
0.6123719811439514, 0.55901700258255, 0.5, 0.433012992143631, 0.35355299711227417, 0.25, 0.0,
};
static f32* table_list[4] = {
(f32*)JASOscillator::sCurveTableLinear,
(f32*)JASOscillator::sCurveTableSquare,
(f32*)JASOscillator::sCurveTableSqRoot,
(f32*)JASOscillator::sCurveTableSampleCell,
};
void JASOscillator::updateCurrentValue(f32 param_0) {
f32* table = table_list[_18];
f32 fVar1 = 16.0f * (_04 / param_0);
u32 index = (u32) fVar1;
f32 fVar3 = (fVar1 - index);
f32 fVar4 = (1.0f - fVar3) * table[index] + fVar3 * table[index + 1];
_08 = _0C * fVar4 + _10 * (1.0f - fVar4);
}
+49
View File
@@ -0,0 +1,49 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASProbe.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
void JASProbe::start(char const* name) {
JASCriticalSection cs;
mName = name;
mStartTime = OSGetTime();
}
void JASProbe::stop() {
JASCriticalSection cs;
u32 r29 = OSGetTime();
_08 = r29 - mStartTime;
_08 /= OS_TIMER_CLOCK / 59.94f;
if (_10 < _08 && 100 < _1A8) {
_10 = _08;
}
_0C = _0C * 0.96f + _08 * 0.04f;
u32 resultIndex = _1A8 % 100;
_14 -= _18[resultIndex];
_18[resultIndex] = _08;
_14 += _08;
_1A8++;
}
JASProbe* JASProbe::sProbeTable[16];
void JASProbe::start(s32 index, char const* name) {
JASProbe* probe;
if (index < 16) {
probe = sProbeTable[index];
if (probe != NULL) {
probe->start(name);
}
}
}
void JASProbe::stop(s32 index) {
JASProbe* probe;
if (index < 16) {
probe = sProbeTable[index];
if (probe != NULL) {
probe->stop();
}
}
}
@@ -0,0 +1,129 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASRegisterParam.h"
#include "JSystem/JSupport/JSupport.h"
JASRegisterParam::JASRegisterParam() {
for (int i = 0; i < 14; i++) {
field_0x0[i] = 0;
}
}
void JASRegisterParam::init() {
for (int i = 0; i < 14; i++) {
field_0x0[i] = 0;
}
}
void JASRegisterParam::write(JASRegisterParam::RegID param_0, u32 param_1) {
if (param_0 < 14) {
if (param_0 <= 2) {
field_0x0[param_0] = (u8)param_1;
} else {
field_0x0[param_0] = param_1;
}
return;
}
switch (param_0) {
case 32:
field_0x0[0] = JSUHiByte(param_1);
field_0x0[1] = JSULoByte(param_1);
break;
case 33:
field_0x0[4] = JSUHiHalf(param_1);
field_0x0[5] = JSULoHalf(param_1);
break;
case 34:
field_0x0[4] = u8(field_0x0[4]);
field_0x0[4] |= u16((param_1 & 0xff) << 8);
break;
case 35:
field_0x0[4] &= 0xff00;
field_0x0[4] |= u8(param_1);
break;
case 36:
field_0x0[5] = u8(field_0x0[5]);
field_0x0[5] |= u16((param_1 & 0xff) << 8);
break;
case 37:
field_0x0[5] &= 0xff00;
field_0x0[5] |= u8(param_1);
break;
case 38:
field_0x0[6] = JSUHiHalf(param_1);
field_0x0[7] = JSULoHalf(param_1);
break;
case 39:
field_0x0[8] = JSUHiHalf(param_1);
field_0x0[9] = JSULoHalf(param_1);
break;
case 40:
field_0x0[10] = JSUHiHalf(param_1);
field_0x0[11] = JSULoHalf(param_1);
break;
case 41:
field_0x0[12] = JSUHiHalf(param_1);
field_0x0[13] = JSULoHalf(param_1);
break;
default:
JUT_WARN(92, "%s", "Warning: Unsupported REG id");
break;
}
}
u32 JASRegisterParam::read(JASRegisterParam::RegID param_0) {
if (param_0 < 14) {
return field_0x0[param_0];
}
u32 rv = 0;
switch (param_0) {
case 32:
rv = ((field_0x0[0] & 0xff) << 8) | (field_0x0[1] & 0xff) ;
break;
case 33:
rv = field_0x0[4];
rv <<= 16;
rv |= field_0x0[5];
break;
case 34:
rv = JSUHiByte(field_0x0[4]);
break;
case 35:
rv = JSULoByte(field_0x0[4]);
break;
case 36:
rv = JSUHiByte(field_0x0[5]);
break;
case 37:
rv = JSULoByte(field_0x0[5]);
break;
case 38:
rv = field_0x0[6];
rv <<= 16;
rv |= field_0x0[7];
break;
case 39:
rv = field_0x0[8];
rv <<= 16;
rv |= field_0x0[9];
break;
case 40:
rv = field_0x0[10];
rv <<= 16;
rv |= field_0x0[11];
break;
case 41:
// !@bug I think this should get field_0x0[12] and field_0x0[13]. Looks like a copy paste bug.
rv = field_0x0[10];
rv <<= 16;
rv |= field_0x0[11];
break;
default:
JUT_WARN(160, "%s", "Warning: Unsupported REG id");
break;
}
return rv;
}
+77
View File
@@ -0,0 +1,77 @@
//
// Translation Unit: JASReport
//
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASReport.h"
#include "JSystem/JAudio2/JASCalc.h"
#include "JSystem/JAudio2/JASMutex.h"
#include "JSystem/JKernel/JKRHeap.h"
#include <cstdio>
static OSMutex sMutex;
static char* sBuffer;
static int sLineMax;
static int sLineCount;
static int sTop;
void JASReportInit(JKRHeap* heap, int lineMax) {
JUT_ASSERT(33, sBuffer == NULL);
JUT_ASSERT(35, heap != NULL);
OSInitMutex(&sMutex);
sLineMax = lineMax;
sBuffer = new (heap, 0) char[sLineMax * 64];
JUT_ASSERT(41, sBuffer);
}
int JASReportGetLineMax() {
return sLineMax;
}
int JASReportCopyBuffer(char *param_1,int lines) {
if (!sBuffer) {
return 0;
}
if (lines < 0) {
lines = sLineMax;
}
char* dest = param_1;
JASMutexLock lock(&sMutex);
int i;
int r30 = sTop - 1;
char* src;
for (i = 0; i < sLineCount && i < lines; i++) {
if (r30 < 0) {
r30 = sLineMax - 1;
}
src = &sBuffer[r30 * 64];
JASCalc::bcopy(src, dest, 64);
r30--;
dest += 64;
}
return i;
}
void JASReport(const char * str, ...) {
va_list vl;
if(!sBuffer) {
return;
}
va_start(vl, str);
JASMutexLock mutexLock(&sMutex);
vsnprintf(sBuffer + (sTop * 64), 64, str, vl);
va_end(vl);
sTop++;
if (sTop >= sLineMax)
sTop = 0;
if (sLineCount < sLineMax)
sLineCount++;
}
@@ -0,0 +1,69 @@
/**
* JASResArcLoader.cpp
* JAS - Resource Archive Loader
*/
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASResArcLoader.h"
#include "JSystem/JAudio2/JASDvdThread.h"
#include "JSystem/JAudio2/JASTaskThread.h"
size_t JASResArcLoader::getResSize(JKRArchive const* i_archiveP, u16 i_resourceID) {
JKRArchive::SDIFileEntry* file = i_archiveP->findIdResource(i_resourceID);
if (file == 0) {
return 0;
}
return file->data_size;
}
size_t JASResArcLoader::getResMaxSize(JKRArchive const* i_archiveP) {
u32 maxSize, index;
u32 fileEntries = i_archiveP->countFile();
maxSize = 0;
for (index = 0; index < fileEntries; index++) {
JKRArchive::SDIFileEntry* file = i_archiveP->findIdxResource(index);
if (file) {
if (maxSize < file->data_size) {
maxSize = file->data_size;
}
}
}
return maxSize;
}
static void JASResArcLoader::loadResourceCallback(void* args) {
TLoadResInfo* castedArgs = static_cast<TLoadResInfo*>(args);
u32 readResult = castedArgs->mArchive->readResource(castedArgs->mBuffer, castedArgs->mBufferSize, castedArgs->mID);
if (castedArgs->mCallback) {
castedArgs->mCallback(readResult, castedArgs->mCallbackArg);
}
if (readResult == 0) {
if (castedArgs->mQueue) {
OSSendMessage(castedArgs->mQueue, (void*)RESARCMSG_Error, OS_MESSAGE_BLOCK);
}
return;
}
if (castedArgs->mQueue) {
OSSendMessage(castedArgs->mQueue, (void*)RESARCMSG_Success, OS_MESSAGE_BLOCK);
}
}
int JASResArcLoader::loadResourceAsync(JKRArchive* archive, u16 id, u8* buffer, u32 size, LoadCallback callback, uintptr_t cbArg)
{
TLoadResInfo args(archive, id, buffer, size);
args.mCallback = callback;
args.mCallbackArg = cbArg;
int r31 = JASDvd::getThreadPointer()->sendCmdMsg(&loadResourceCallback, (void*)&args, sizeof(TLoadResInfo));
if (!r31) {
JUT_WARN(160, "%s", "sendCmdMsg loadResourceCallback Failed");
}
return r31;
}
+145
View File
@@ -0,0 +1,145 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASSeqCtrl.h"
#include "JSystem/JAudio2/JASSeqParser.h"
#include "JSystem/JAudio2/JASTrack.h"
JASSeqParser JASSeqCtrl::sDefaultParser;
JASSeqCtrl::JASSeqCtrl() {
field_0x3c = &sDefaultParser;
field_0x40 = 0;
field_0x44 = NULL;
field_0x48 = 0;
field_0x4c = 0;
field_0x4e = 0;
field_0x50 = 0;
field_0x51 = 0;
field_0x54 = 0;
field_0x58 = 0;
mReader.init();
}
void JASSeqCtrl::init() {
mReader.init();
field_0x3c = &sDefaultParser;
field_0x40 = 0;
field_0x44 = NULL;
field_0x48 = 0;
field_0x4c = 0;
field_0x4e = 0;
field_0x50 = 0;
field_0x54 = 0;
field_0x58 = 0;
field_0x51 = 0;
}
void JASSeqCtrl::start(void* param_0, u32 param_1) {
mReader.init(param_0);
mReader.jump(param_1);
}
int JASSeqCtrl::tickProc(JASTrack* param_0) {
if (!mReader.getBase()) {
return 0;
}
interrupt(INTRTYPE_VALUE_6);
timerProcess();
if (field_0x51) {
if (!param_0->checkNoteStop(0)) {
return 0;
}
field_0x51 = 0;
}
if (field_0x40 > 0) {
field_0x40--;
}
checkIntr();
while ((field_0x40 == 0 || field_0x44 != NULL) && field_0x51 == 0) {
if (field_0x3c->parse(param_0) < 0) {
return -1;
}
}
return 0;
}
void JASSeqCtrl::interrupt(JASSeqCtrl::IntrType param_0) {
if (field_0x4e & (1 << param_0)) {
field_0x4c |= (1 << param_0);
}
}
void JASSeqCtrl::setIntrMask(u32 param_0) {
field_0x4e |= param_0;
}
void JASSeqCtrl::clrIntrMask(u32 param_0) {
field_0x4e &= ~param_0;
}
int JASSeqCtrl::retIntr() {
if (field_0x44 == NULL) {
return 0;
}
mReader.jump(field_0x44);
field_0x44 = NULL;
return 1;
}
int JASSeqCtrl::findIntr() {
u32 uVar1 = field_0x4e;
uVar1 &= field_0x4c;
int i;
for (i = 0; uVar1 != 0; i++) {
if (uVar1 & 1) {
field_0x4c &= ~(1 << i);
return i;
}
uVar1 >>= 1;
}
return -1;
}
void JASSeqCtrl::checkIntr() {
if (field_0x44) {
return;
}
int intr = findIntr();
if (intr < 0) {
return;
}
u32 vec = field_0x48;
JUT_ASSERT(144, vec != 0);
vec += intr * 3;
vec = get24(vec);
field_0x44 = mReader.getCur();
mReader.jump(vec);
}
void JASSeqCtrl::timerProcess() {
if (field_0x54 == 0) return;
field_0x54--;
if (field_0x54) return;
interrupt(INTRTYPE_VALUE_5);
if (field_0x50) {
field_0x50--;
if (field_0x50) {
field_0x54 = field_0x58;
}
} else {
field_0x54 = field_0x58;
}
}
File diff suppressed because it is too large Load Diff
+120
View File
@@ -0,0 +1,120 @@
/**
* JASSeqReader.cpp
*
*/
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASSeqReader.h"
void JASSeqReader::init() {
field_0x00 = 0;
field_0x04 = 0;
field_0x08 = 0;
for (int i = 0; i < 8; i++) {
field_0x0c[i] = NULL;
field_0x2c[i] = 0;
}
}
void JASSeqReader::init(void* param_0) {
field_0x00 = (u8*)param_0;
field_0x04 = field_0x00;
field_0x08 = 0;
for (int i = 0; i < 8; i++) {
field_0x0c[i] = NULL;
field_0x2c[i] = 0;
}
}
bool JASSeqReader::call(u32 param_0) {
if (field_0x08 >= 8) {
JUT_WARN(42, "%s", "Cannot exec call command");
return false;
}
field_0x0c[field_0x08++] = (u16*)field_0x04;
field_0x04 = field_0x00 + param_0;
return true;
}
bool JASSeqReader::loopStart(u32 param_0) {
if (8 <= field_0x08) {
JUT_WARN(53, "%s", "Cannot exec loopStart command");
return false;
}
field_0x0c[field_0x08] = (u16*)field_0x04;
field_0x2c[field_0x08++] = param_0;
return true;
}
bool JASSeqReader::loopEnd() {
if (field_0x08 == 0) {
JUT_WARN(65, "%s", "cannot loopE for call-stack is NULL");
return false;
}
u16 tmp = field_0x2c[field_0x08 - 1];
if (tmp != 0) {
tmp--;
}
if (!tmp) {
field_0x08--;
return true;
}
field_0x2c[field_0x08 - 1] = tmp;
field_0x04 = (u8*)field_0x0c[field_0x08 - 1];
return true;
}
bool JASSeqReader::ret() {
if (field_0x08 == 0) {
return false;
}
field_0x04 = (u8*)field_0x0c[--field_0x08];
return true;
}
int JASSeqReader::readMidiValue() {
int byte = readByte();
if (!(byte & 0x80)) {
return byte;
}
byte &= 0x7f;
int i = 0;
while (true) {
if (2 < i) {
JUT_WARN(100, "%s", "readMidiValue: Too large value");
return 0;
}
u8 newByte = readByte();
byte = byte << 7;
byte |= newByte & 0x7f;
if (!(newByte & 0x80)) {
break;
}
i++;
}
return byte;
}
@@ -0,0 +1,60 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASSimpleWaveBank.h"
#include <stdint.h>
JASSimpleWaveBank::JASSimpleWaveBank() {
mWaveTable = NULL;
mWaveTableSize = 0;
}
JASSimpleWaveBank::~JASSimpleWaveBank() {
delete[] mWaveTable;
}
void JASSimpleWaveBank::setWaveTableSize(u32 size, JKRHeap* heap) {
delete[] mWaveTable;
mWaveTable = new (heap, 0) TWaveHandle[size];
JUT_ASSERT(29, mWaveTable != NULL);
mWaveTableSize = size;
}
JASWaveHandle* JASSimpleWaveBank::getWaveHandle(u32 no) const {
if (no >= mWaveTableSize) {
return NULL;
}
return &mWaveTable[no];
}
void JASSimpleWaveBank::setWaveInfo(u32 no, JASWaveInfo const& waveInfo) {
mWaveTable[no].mWaveInfo = waveInfo;
mWaveTable[no].mWaveInfo.field_0x20 = &_48;
mWaveTable[no].mHeap = &mHeap;
}
JASWaveArc* JASSimpleWaveBank::getWaveArc(u32 no) {
if (no != 0) {
return NULL;
}
return this;
}
int JASSimpleWaveBank::TWaveHandle::getWavePtr() const {
void* base = mHeap->getBase();
if (base == NULL) {
return 0;
}
return (intptr_t)base + mWaveInfo.field_0x08;
}
JASSimpleWaveBank::TWaveHandle::TWaveHandle() {
mHeap = NULL;
}
const JASWaveInfo* JASSimpleWaveBank::TWaveHandle::getWaveInfo() const {
return &mWaveInfo;
}
u32 JASSimpleWaveBank::getArcCount() const {
return 1;
}
@@ -0,0 +1,19 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASSoundParams.h"
void JASSoundParams::clamp() {
clampVolume();
clampPitch();
clampFxMix();
clampPan();
clampDolby();
}
void JASSoundParams::combine(const JASSoundParams &other1, const JASSoundParams &other2) {
mVolume = other1.mVolume * other2.mVolume;
mPitch = other1.mPitch * other2.mPitch;
mFxMix = other1.mFxMix + other2.mFxMix;
mPan = other1.mPan + other2.mPan - 0.5f;
mDolby = other1.mDolby + other2.mDolby;
}
+113
View File
@@ -0,0 +1,113 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASTaskThread.h"
#include "JSystem/JAudio2/JASCalc.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
JASTaskThread::JASTaskThread(int priority, int msgCount, u32 stackSize) :
JKRThread(JASDram, stackSize, msgCount, priority)
{
field_0x84 = false;
OSInitThreadQueue(&threadQueue_);
}
JASTaskThread::~JASTaskThread() {
OSMessage msg;
BOOL received;
while (true) {
msg = waitMessage(&received);
if (!received) {
return;
}
JASKernel::getCommandHeap()->free(msg);
}
}
void* JASTaskThread::allocCallStack(JASThreadCallback callback, const void* msg, u32 msgSize) {
ThreadMemPool* heap;
u32 size = msgSize + 8;
JASThreadCallStack *callStack = (JASThreadCallStack*) JASKernel::getCommandHeap()->alloc(size);
if (callStack == NULL) {
return NULL;
}
callStack->msgType_ = 1;
JASCalc::bcopy(msg, callStack->msg.buffer, msgSize);
callStack->callback_ = callback;
return callStack;
}
void* JASTaskThread::allocCallStack(JASThreadCallback callback, void* msg) {
JASThreadCallStack *callStack;
callStack = (JASThreadCallStack*)JASKernel::getCommandHeap()->alloc(12);
if (callStack == NULL) {
return NULL;
}
callStack->msgType_ = 0;
callStack->msg.bufferPtr = msg;
callStack->callback_ = callback;
return callStack;
}
int JASTaskThread::sendCmdMsg(JASThreadCallback callback, const void* msg, u32 msgSize) {
void* callstack;
callstack = allocCallStack(callback, msg, msgSize);
if (callstack == NULL) {
return 0;
}
BOOL iVar2 = sendMessage(callstack);
if (!iVar2) {
JASKernel::getCommandHeap()->free(callstack);
}
return iVar2;
}
int JASTaskThread::sendCmdMsg(JASThreadCallback callback, void* msg) {
void* callstack;
callstack = allocCallStack(callback, msg);
if (callstack == NULL) {
return 0;
}
BOOL iVar2 = sendMessage(callstack);
if (!iVar2) {
JASKernel::getCommandHeap()->free(callstack);
}
return iVar2;
}
void* JASTaskThread::run() {
JASThreadCallStack* callstack;
OSInitFastCast();
do {
callstack = static_cast<JASThreadCallStack*>(waitMessageBlock());
if (field_0x84) {
OSSleepThread(&threadQueue_);
}
if (callstack->msgType_) {
callstack->callback_(callstack->msg.buffer);
} else {
callstack->callback_(callstack->msg.bufferPtr);
}
JASKernel::getCommandHeap()->free(callstack);
} while (true);
}
void JASTaskThread::pause(bool param_0) {
JASCriticalSection aJStack_14;
if (param_0) {
field_0x84 = 1;
} else {
if (field_0x84) {
OSWakeupThread(&threadQueue_);
}
field_0x84 = 0;
}
}
+878
View File
@@ -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);
}
}
}
+43
View File
@@ -0,0 +1,43 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASTrackPort.h"
void JASTrackPort::init() {
for (int i = 0; i < 16; i++) {
field_0x4[i] = 0;
}
field_0x0 = 0;
field_0x2 = 0;
}
u16 JASTrackPort::readImport(u32 port_num) {
JUT_ASSERT(27, port_num < MAX_PORTS);
field_0x0 = field_0x0 & ~(1 << port_num);
return field_0x4[port_num];
}
u16 JASTrackPort::readExport(u32 port_num) {
JUT_ASSERT(34, port_num < MAX_PORTS);
field_0x2 = field_0x2 & ~(1 << port_num);
return field_0x4[port_num];
}
void JASTrackPort::writeImport(u32 port_num, u16 param_1) {
JUT_ASSERT(41, port_num < MAX_PORTS);
field_0x0 = field_0x0 | (1 << port_num);
field_0x4[port_num] = param_1;
}
void JASTrackPort::writeExport(u32 port_num, u16 param_1) {
JUT_ASSERT(47, port_num < MAX_PORTS);
field_0x2 = field_0x2 | (1 << port_num);
field_0x4[port_num] = param_1;
}
u32 JASTrackPort::checkImport(u32 param_0) const {
return field_0x0 & 1 << param_0 ? 1 : 0;
}
u32 JASTrackPort::checkExport(u32 param_0) const {
return field_0x2 & 1 << param_0 ? 1 : 0;
}
+28
View File
@@ -0,0 +1,28 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASVoiceBank.h"
#include "JSystem/JAudio2/JASBasicInst.h"
const JASOscillator::Data JASVoiceBank::sOscData = {
0, 1.0f, NULL, NULL, 1.0f, 0.0f,
};
JASOscillator::Data* JASVoiceBank::sOscTable;
bool JASVoiceBank::getInstParam(int param_0, int param_1, int param_2,
JASInstParam* param_3) const {
if (param_0 < 0) {
return false;
}
sOscTable = (JASOscillator::Data*)&sOscData;
param_3->field_0x1a = param_0;
param_3->field_0x1d = 1;
param_3->field_0x14 = &sOscTable;
return true;
}
JASVoiceBank::~JASVoiceBank() {}
u32 JASVoiceBank::getType() const {
return 'VOIC';
}
+126
View File
@@ -0,0 +1,126 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASWSParser.h"
#include "JSystem/JAudio2/JASBasicWaveBank.h"
#include "JSystem/JAudio2/JASSimpleWaveBank.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
u32 JASWSParser::getGroupCount(void const* stream) {
THeader* header = (THeader*)stream;
TCtrlGroup* group = header->mCtrlGroupOffset.ptr(header);
return group->mGroupCount;
}
JASWaveBank* JASWSParser::createWaveBank(void const* stream, JKRHeap* heap) {
if (getGroupCount(stream) == 1) {
return createSimpleWaveBank(stream, heap);
} else {
return createBasicWaveBank(stream, heap);
}
}
u32 JASWSParser::sUsedHeapSize;
JASBasicWaveBank* JASWSParser::createBasicWaveBank(void const* stream, JKRHeap* heap) {
if (heap == NULL) {
heap = JASDram;
}
u32 free_size = heap->getFreeSize();
THeader* header = (THeader*)stream;
JASBasicWaveBank* wave_bank = new (heap, 0) JASBasicWaveBank();
if (wave_bank == NULL) {
return NULL;
}
TCtrlGroup* ctrl_group = header->mCtrlGroupOffset.ptr(header);
wave_bank->setGroupCount(ctrl_group->mGroupCount, heap);
wave_bank->setWaveTableSize(header->mWaveTableSize, heap);
for (u32 i = 0; i < ctrl_group->mGroupCount; i++) {
TCtrlScene* ctrlScene = ctrl_group->mCtrlSceneOffsets[i].ptr(header);
TCtrl* ctrl = ctrlScene->mCtrlOffset.ptr(header);
JASBasicWaveBank::TWaveGroup* wave_group = wave_bank->getWaveGroup(i);
TWaveArchiveBank* archiveBank = header->mArchiveBankOffset.ptr(header);
TWaveArchive* archive = archiveBank->mArchiveOffsets[i].ptr(header);
wave_group->setWaveCount(ctrl->mWaveCount, heap);
for (int j = 0; j < ctrl->mWaveCount; j++) {
TWave* wave = archive->mWaveOffsets[j].ptr(header);
JASWaveInfo wave_info;
wave_info.field_0x00 = wave->_01;
wave_info.field_0x01 = wave->_02;
wave_info.field_0x04 = wave->_04;
wave_info.field_0x08 = wave->mOffset;
wave_info.field_0x0c = wave->_0C;
wave_info.field_0x02 = wave->_10 == 0 ? 0 : 0xff;
wave_info.field_0x10 = wave->_14;
wave_info.field_0x14 = wave->_18;
wave_info.field_0x18 = wave->_1C;
wave_info.field_0x1c = wave->_20;
wave_info.field_0x1e = wave->_22;
TCtrlWave* ctrl_wave = ctrl->mCtrlWaveOffsets[j].ptr(header);
u16 local_74 = JSULoHalf(ctrl_wave->_00);
wave_bank->setWaveInfo(wave_group, j, local_74, wave_info);
}
wave_group->setFileName(archive->mFileName);
}
sUsedHeapSize += (free_size - heap->getFreeSize());
return wave_bank;
}
JASSimpleWaveBank* JASWSParser::createSimpleWaveBank(void const* stream, JKRHeap* heap) {
if (heap == NULL) {
heap = JASDram;
}
u32 free_size = heap->getFreeSize();
THeader* header = (THeader*)stream;
TCtrlGroup* ctrl_group = header->mCtrlGroupOffset.ptr(header);
if (ctrl_group->mGroupCount != 1) {
return NULL;
}
JASSimpleWaveBank* wave_bank = new (heap, 0) JASSimpleWaveBank();
if (wave_bank == NULL) {
return NULL;
}
u32 max = 0;
TCtrlScene* ctrlScene = ctrl_group->mCtrlSceneOffsets[0].ptr(header);
TCtrl* ctrl = ctrlScene->mCtrlOffset.ptr(header);
TWaveArchiveBank* archiveBank = header->mArchiveBankOffset.ptr(header);
TWaveArchive* archive = archiveBank->mArchiveOffsets[0].ptr(header);
for (int i = 0; i < ctrl->mWaveCount; i++) {
TCtrlWave* ctrlWave = ctrl->mCtrlWaveOffsets[i].ptr(header);
u32 tmp = JSULoHalf(ctrlWave->_00);
if (max < tmp) {
max = tmp;
}
}
wave_bank->setWaveTableSize(max + 1, heap);
for (int i = 0; i < ctrl->mWaveCount; i++) {
TWave* wave = archive->mWaveOffsets[i].ptr(header);
JASWaveInfo wave_info;
wave_info.field_0x00 = wave->_01;
wave_info.field_0x01 = wave->_02;
wave_info.field_0x04 = wave->_04;
wave_info.field_0x08 = wave->mOffset;
wave_info.field_0x0c = wave->_0C;
wave_info.field_0x02 = wave->_10 == 0 ? 0 : 0xff;
wave_info.field_0x10 = wave->_14;
wave_info.field_0x14 = wave->_18;
wave_info.field_0x18 = wave->_1C;
wave_info.field_0x1c = wave->_20;
wave_info.field_0x1e = wave->_22;
TCtrlWave* ctrl_wave = ctrl->mCtrlWaveOffsets[i].ptr(header);
u32 tmp = JSULoHalf(ctrl_wave->_00);
wave_bank->setWaveInfo(tmp, wave_info);
}
wave_bank->setFileName(archive->mFileName);
sUsedHeapSize += (free_size - heap->getFreeSize());
return wave_bank;
}
@@ -0,0 +1,182 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JASWaveArcLoader.h"
#include "JSystem/JAudio2/JASDvdThread.h"
#include "JSystem/JAudio2/JASTaskThread.h"
#include "JSystem/JAudio2/JASMutex.h"
#include "JSystem/JKernel/JKRDvdAramRipper.h"
#include <cstring>
#include <os.h>
#include <stdint.h>
JASHeap* JASWaveArcLoader::sAramHeap;
JASHeap* JASWaveArcLoader::getRootHeap() {
if (JASWaveArcLoader::sAramHeap) {
return JASWaveArcLoader::sAramHeap;
}
return JASKernel::getAramHeap();
}
char JASWaveArcLoader::sCurrentDir[DIR_MAX] = "/AudioRes/Waves/";
void JASWaveArcLoader::setCurrentDir(char const* dir) {
JUT_ASSERT(40, std::strlen(dir) < DIR_MAX - 1);
strcpy(sCurrentDir, dir);
u32 len = strlen(sCurrentDir);
if (sCurrentDir[len - 1] != '/') {
JUT_ASSERT(45, len + 1 < DIR_MAX);
sCurrentDir[len] = '/';
sCurrentDir[len + 1] = '\0';
}
}
char* JASWaveArcLoader::getCurrentDir() {
return sCurrentDir;
}
JASWaveArc::JASWaveArc() : mHeap(this) {
_48 = 0;
mStatus = 0;
mEntryNum = -1;
mFileLength = 0;
_58 = 0;
_5a = 0;
OSInitMutex(&mMutex);
}
JASWaveArc::~JASWaveArc() {}
bool JASWaveArc::loadSetup(u32 param_0) {
JASMutexLock mutexLock(&mMutex);
if (_58 != param_0) {
return false;
}
if (mStatus != 1) {
return false;
}
_48 = 1;
mStatus = 2;
return true;
}
bool JASWaveArc::eraseSetup() {
JASMutexLock mutexLock(&mMutex);
if (mStatus == 0) {
return false;
}
if (mStatus == 1) {
mStatus = 0;
return false;
}
_48 = 0;
mStatus = 0;
return true;
}
void JASWaveArc::loadToAramCallback(void* this_) {
loadToAramCallbackParams* tmp = (loadToAramCallbackParams*)this_;
JASWaveArc* wavArc = tmp->mWavArc;
if (JKRDvdAramRipper::loadToAram(tmp->mEntryNum, tmp->mBase, EXPAND_SWITCH_UNKNOWN0, 0, 0, NULL) == NULL) {
JUT_WARN(129, "%s", "loadToAram Failed");
return;
}
wavArc->_5a--;
if (wavArc->loadSetup(tmp->_c)) {
wavArc->onLoadDone();
}
}
bool JASWaveArc::sendLoadCmd() {
JASMutexLock mutexLock(&mMutex);
_48 = 0;
mStatus = 1;
loadToAramCallbackParams commandInfo;
commandInfo.mWavArc = this;
commandInfo.mEntryNum = mEntryNum;
commandInfo.mBase = (uintptr_t)mHeap.getBase();
commandInfo._c = ++_58;
_5a++;
if (JASDvd::getThreadPointer()->sendCmdMsg(loadToAramCallback, &commandInfo, 0x10) == 0) {
JUT_WARN(193, "%s", "sendCmdMsg loadToAramCallback Failed");
mHeap.free();
return false;
}
return true;
}
bool JASWaveArc::load(JASHeap* heap) {
if (mEntryNum < 0) {
return false;
}
JASMutexLock mutexLock(&mMutex);
if (mStatus != 0) {
return false;
}
if (heap == NULL) {
heap = JASWaveArcLoader::getRootHeap();
}
if (mHeap.alloc(heap, mFileLength) == false) {
return false;
}
return sendLoadCmd();
}
bool JASWaveArc::loadTail(JASHeap* heap) {
if (mEntryNum < 0) {
return false;
}
JASMutexLock mutexLock(&mMutex);
if (mStatus != 0) {
return false;
}
if (heap == NULL) {
heap = JASWaveArcLoader::getRootHeap();
}
if (mHeap.allocTail(heap, mFileLength) == false) {
return false;
}
return sendLoadCmd();
}
bool JASWaveArc::erase() {
return mHeap.free();
}
void JASWaveArc::onDispose() {
if (eraseSetup()) {
onEraseDone();
}
}
void JASWaveArc::setEntryNum(s32 entryNum) {
DVDFileInfo fileInfo;
if (entryNum < 0) {
return;
}
if (DVDFastOpen(entryNum, &fileInfo) == FALSE) {
return;
}
mFileLength = fileInfo.length;
DVDClose(&fileInfo);
mEntryNum = entryNum;
}
void JASWaveArc::setFileName(char const* fileName) {
char* currentDir = JASWaveArcLoader::getCurrentDir();
size_t length = strlen(currentDir);
length = length + strlen(fileName);
char* path = new (JASKernel::getSystemHeap(), -4) char[length + 1];
JUT_ASSERT(322, path);
strcpy(path, currentDir);
strcat(path, fileName);
path[length] = '\0';
int entryNum = DVDConvertPathToEntrynum(path);
delete[] path;
if (entryNum < 0) {
return;
}
setEntryNum(entryNum);
}
+5
View File
@@ -0,0 +1,5 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUAudience.h"
// NONMATCHING
@@ -0,0 +1,115 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUAudioArcInterpreter.h"
#include "JSystem/JUtility/JUTAssert.h"
JAUAudioArcInterpreter::JAUAudioArcInterpreter() {
mBase = NULL;
mReadPtr = NULL;
}
JAUAudioArcInterpreter::~JAUAudioArcInterpreter() {}
bool JAUAudioArcInterpreter::parse(void const* param_0) {
mBase = (const u8*)param_0;
mReadPtr = mBase;
if (readU32_() != 'AA_<') {
return false;
}
while (readCommand_()) {}
return true;
}
bool JAUAudioArcInterpreter::readCommandMore(u32 param_0) {
return false;
}
bool JAUAudioArcInterpreter::readCommand_() {
u32 cmd = readU32_();
switch (cmd) {
case '>_AA':
return false;
case 'ws ': {
u32 var1 = readU32_();
u32 var2 = readU32_();
u32 var3 = readU32_();
readWS(var1, getContent_(var2), var3);
break;
}
case 'bnk ': {
u32 var1 = readU32_();
u32 var2 = readU32_();
readBNK(var1, getContent_(var2));
break;
}
case 'bl_<': {
u32 var1 = readU32_();
u32 var2 = readU32_();
beginBNKList(var1, var2);
break;
}
case '>_bl':
endBNKList();
break;
case 'bsc ': {
u32 var1 = readU32_();
u32 var2 = readU32_();
readBSC(getContent_(var1), var2 - var1);
break;
}
case 'bst ': {
u32 var1 = readU32_();
u32 var2 = readU32_();
readBST(getContent_(var1), var2 - var1);
break;
}
case 'bstn': {
u32 var1 = readU32_();
u32 var2 = readU32_();
readBSTN(getContent_(var1), var2 - var1);
break;
}
case 'bms ': {
u32 var1 = readU32_();
u32 var2 = readU32_();
u32 var3 = readU32_();
readBMS(var1, getContent_(var2), var3 - var2);
break;
}
case 'bmsa': {
u32 var1 = readU32_();
readBMS_fromArchive(var1);
break;
}
case 'vbnk': {
u32 var1 = readU32_();
u32 var2 = readU32_();
newVoiceBank(var1, var2);
break;
}
case 'dsqb': {
u32 var1 = readU32_();
newDynamicSeqBlock(var1);
break;
}
case 'bsft': {
u32 var1 = readU32_();
readBSFT(getContent_(var1));
break;
}
case 'sect': {
u8 var1 = readU8_();
u8 var2 = readU8_();
u8 var3 = readU8_();
u8 var4 = readU8_();
readMaxSeCategory(var2, var3, var4);
break;
}
default:
if (!readCommandMore(cmd)) {
JUT_ASSERT(145, false);
}
break;
}
return true;
}
@@ -0,0 +1,148 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUAudioArcLoader.h"
#include "JSystem/JAudio2/JAISeMgr.h"
#include "JSystem/JAudio2/JASReport.h"
#include "JSystem/JAudio2/JAUSectionHeap.h"
JAUAudioArcLoader::JAUAudioArcLoader(JAUSection* section) {
JUT_ASSERT(13, section->isOpen());
JUT_ASSERT(14, section->isBuilding());
mSection = section;
}
bool JAUAudioArcLoader::load(void const* param_0) {
return parse(param_0);
}
void JAUAudioArcLoader::readWS(u32 param_0, void const* param_1, u32 param_2) {
mSection->newWaveBank(param_0, param_1);
if (param_2) {
mSection->loadWaveArc(param_0, param_2);
}
}
void JAUAudioArcLoader::readBNK(u32 param_0, void const* param_1) {
mSection->newBank(param_1, param_0);
}
void JAUAudioArcLoader::readBSC(void const* param_0, u32 param_1) {
mSection->newSeSeqCollection(param_0, param_1);
}
void JAUAudioArcLoader::readBST(void const* param_0, u32 param_1) {
mSection->newSoundTable(param_0, param_1, true);
}
void JAUAudioArcLoader::readBSTN(void const* param_0, u32 param_1) {
mSection->newSoundNameTable(param_0, param_1, true);
}
void JAUAudioArcLoader::readBMS(u32 param_0, void const* param_1, u32 param_2) {
mSection->newStaticSeqData(param_0, param_1, param_2);
}
void JAUAudioArcLoader::readBMS_fromArchive(u32 param_0) {
mSection->newStaticSeqData(param_0);
}
void JAUAudioArcLoader::newVoiceBank(u32 param_0, u32 param_1) {
mSection->newVoiceBank(param_1, param_0);
}
void JAUAudioArcLoader::newDynamicSeqBlock(u32 param_0) {
JAUSectionHeap* sectionHeap = mSection->asSectionHeap();
JUT_ASSERT(72, sectionHeap);
sectionHeap->newDynamicSeqBlock(param_0);
}
void JAUAudioArcLoader::readBSFT(void const* param_0) {
mSection->newStreamFileTable(param_0, true);
}
void JAUAudioArcLoader::beginBNKList(u32 param_0, u32 param_1) {
mSection->beginNewBankTable(param_0, param_1);
}
void JAUAudioArcLoader::endBNKList() {
mSection->endNewBankTable();
}
void JAUAudioArcLoader::readMaxSeCategory(int param_0, int param_1, int param_2) {
{
JAISeMgr* seMgr = JASGlobalInstance<JAISeMgr>::getInstance();
if (seMgr) {
seMgr->getCategory(param_0)->setMaxActiveSe(param_1);
seMgr->getCategory(param_0)->setMaxInactiveSe(param_2);
}
}
}
void JAUAudioArcLoader_withoutCopy::readWS(u32 param_0, void const* param_1, u32 param_2) {
mSection->newWaveBank(param_0, param_1);
if (param_2) {
mSection->loadWaveArc(param_0, param_2);
}
JASReport(".ws resource remains at Heap Head\n");
}
void JAUAudioArcLoader_withoutCopy::readBNK(u32 param_0, void const* param_1) {
mSection->newBank(param_1, param_0);
JASReport(".bnk resource remains at Heap Head\n");
}
void JAUAudioArcLoader_withoutCopy::readBSC(void const* param_0, u32 param_1) {
UNUSED(param_1);
mSection->newSeSeqCollection(param_0, 0);
}
void JAUAudioArcLoader_withoutCopy::readBST(void const* param_0, u32 param_1) {
UNUSED(param_1);
mSection->newSoundTable(param_0, 0, true);
}
void JAUAudioArcLoader_withoutCopy::readBSTN(void const* param_0, u32 param_1) {
UNUSED(param_1);
mSection->newSoundNameTable(param_0, 0, true);
}
void JAUAudioArcLoader_withoutCopy::readBMS(u32 param_0, void const* param_1, u32 param_2) {
UNUSED(param_2);
mSection->newStaticSeqData(param_0, param_1, 0);
}
void JAUAudioArcLoader_withoutCopy::readBMS_fromArchive(u32 param_0) {
mSection->newStaticSeqData(param_0);
}
void JAUAudioArcLoader_withoutCopy::newVoiceBank(u32 param_0, u32 param_1) {
mSection->newVoiceBank(param_1, param_0);
}
void JAUAudioArcLoader_withoutCopy::newDynamicSeqBlock(u32 param_0) {
JAUSectionHeap* sectionHeap = mSection->asSectionHeap();
JUT_ASSERT(166, sectionHeap);
sectionHeap->newDynamicSeqBlock(param_0);
}
void JAUAudioArcLoader_withoutCopy::readBSFT(void const* param_0) {
mSection->newStreamFileTable(param_0, false);
}
void JAUAudioArcLoader_withoutCopy::beginBNKList(u32 param_0, u32 param_1) {
mSection->beginNewBankTable(param_0, param_1);
}
void JAUAudioArcLoader_withoutCopy::endBNKList() {
mSection->endNewBankTable();
}
void JAUAudioArcLoader_withoutCopy::readMaxSeCategory(int param_0, int param_1, int param_2) {
{
JAISeMgr* seMgr = JASGlobalInstance<JAISeMgr>::getInstance();
if (seMgr) {
seMgr->getCategory(param_0)->setMaxActiveSe(param_1);
seMgr->getCategory(param_0)->setMaxInactiveSe(param_2);
}
}
}
+20
View File
@@ -0,0 +1,20 @@
//
// JAUAudioMgr
//
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUAudioMgr.h"
#include "JSystem/JAudio2/JASHeapCtrl.h"
#include "JSystem/JAudio2/JAUStreamAramMgr.h"
// Here to generate JASHeap::__defctor (ctor generated by default arguments)
void dummyDefCtor() {
JASHeap dummy[20];
//TODO: ShieldD needs the weak functions this pulls in, but in retail it breaks weak function
// placement
#if VERSION == VERSION_SHIELD_DEBUG
JAUStreamStaticAramMgr_<1>* streamStaticAramMgr = new(NULL, 0) JAUStreamStaticAramMgr_<1>();
streamStaticAramMgr->reserveAram(NULL, 0, 0x14);
#endif
}
+12
View File
@@ -0,0 +1,12 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUBankTable.h"
void JAUBankTableDictionary::appendBankTable(JSULink<JAUBankTable>* bankTableList) {
append(bankTableList);
}
// Needed to make the inline function JAUBankTable::getBank appear in this TU
static const JASBank* dummy(const JAUBankTable* table) {
return table->getBank(0);
}
@@ -0,0 +1,16 @@
//
// JAUClusterSound
//
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUClusterSound.h"
#include "JSystem/JAudio2/JAISoundHandles.h"
#include "JSystem/JAudio2/JAISoundStarter.h"
// Dummy function to generate JAISoundHandle::JAISoundHandle
static void dummyCtor() {
JASGlobalInstance<JAISoundStarter>::getInstance();
JAISoundHandle dummy[20];
JAISoundHandles handles(dummy, 20);
}
+108
View File
@@ -0,0 +1,108 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUInitializer.h"
#include "JSystem/JAudio2/JAISe.h"
#include "JSystem/JAudio2/JAISeq.h"
#include "JSystem/JAudio2/JAISoundChild.h"
#include "JSystem/JAudio2/JAIStream.h"
#include "JSystem/JAudio2/JASAramStream.h"
#include "JSystem/JAudio2/JASAudioThread.h"
#include "JSystem/JAudio2/JASDriverIF.h"
#include "JSystem/JAudio2/JASDvdThread.h"
#include "JSystem/JAudio2/JASTrack.h"
#include "JSystem/JAudio2/JASWaveArcLoader.h"
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
#include "JSystem/JKernel/JKRThread.h"
JAU_JASInitializer::JAU_JASInitializer() {
audioMemory_ = 0;
audioMemSize_ = 0;
dvdThreadId_ = -1;
audioThreadId_ = -1;
heapSize_ = 0x1000;
dvdThreadPriority_ = 3;
audioThreadPriority_ = 2;
field_0x1c = 0x80;
dspLevel_ = 1.0f;
aramBlockSize_ = 0x2760;
aramChannelNum_ = 2;
field_0x20 = 0;
waveArcDir_ = NULL;
}
// NONMATCHING JASPoolAllocObject_MultiThreaded<_> locations
void JAU_JASInitializer::initJASystem(JKRSolidHeap* heap) {
if (JASAudioThread::getThreadPointer()) {
JUT_WARN(48, "%s", "Though initialized JASAudioThread, called JAU_JASInitializer::initJASystem()\n");
} else if (JASDvd::getThreadPointer()) {
JUT_WARN(52, "%s", "Though initialized JASDvd, called JAU_JASInitializer::initJASystem()\n");
} else {
JASKernel::setupRootHeap(heap, heapSize_);
if (audioMemory_ == 0) {
audioMemory_ = JKRAram::getManager()->getAudioMemory();
}
if (audioMemSize_ == 0) {
audioMemSize_ = JKRAram::getManager()->getAudioMemSize();
}
JASKernel::setupAramHeap(audioMemory_, audioMemSize_);
JASTrack::newMemPool(field_0x1c);
if (field_0x20 > 0) {
JASTrack::TChannelMgr::newMemPool(field_0x20);
}
JASDvd::createThread(dvdThreadPriority_, 0x80, 0x1000);
JASAudioThread::create(audioThreadPriority_);
JKRThreadSwitch* threadSwitch = JKRThreadSwitch::getManager();
if (threadSwitch) {
if (dvdThreadId_ >= 0) {
threadSwitch->enter(JASDvd::getThreadPointer(), dvdThreadId_);
}
if (audioThreadId_ >= 0) {
threadSwitch->enter(JASAudioThread::getThreadPointer(), audioThreadId_);
}
}
JASDriver::setDSPLevel(dspLevel_);
JASAramStream::initSystem(aramBlockSize_, aramChannelNum_);
}
if (waveArcDir_) {
JASWaveArcLoader::setCurrentDir(waveArcDir_);
}
#if PLATFORM_SHIELD
JASDriver::setOutputMode(1);
#else
switch (OSGetSoundMode()) {
case 0:
JASDriver::setOutputMode(0);
break;
case 1:
JASDriver::setOutputMode(1);
break;
}
#endif
}
JAU_JAIInitializer::JAU_JAIInitializer() {
field_0x0 = 100;
field_0x4 = 4;
field_0x8 = 2;
field_0xc = 16;
}
// NONMATCHING JASPoolAllocObject<_> locations
void JAU_JAIInitializer::initJAInterface() {
s32 r30 = JASDram->getFreeSize();
JAIStream::newMemPool(field_0x8);
JAISeq::newMemPool(field_0x4);
JAISe::newMemPool(field_0x0);
JAISoundChild::newMemPool(field_0xc);
s32 r29 = JASDram->getFreeSize();
OS_REPORT("JAU_JAIInitializer uses %d bytes\n", r30 - r29);
}
+524
View File
@@ -0,0 +1,524 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUSectionHeap.h"
#include "JSystem/JAudio2/JASBNKParser.h"
#include "JSystem/JAudio2/JASBankTable.h"
#include "JSystem/JAudio2/JASBasicWaveBank.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
#include "JSystem/JAudio2/JASHeapCtrl.h"
#include "JSystem/JAudio2/JASResArcLoader.h"
#include "JSystem/JAudio2/JASVoiceBank.h"
#include "JSystem/JAudio2/JASWSParser.h"
#include "JSystem/JAudio2/JAUSeqCollection.h"
#include "JSystem/JAudio2/JAUSoundInfo.h"
#include "JSystem/JAudio2/JAUSoundTable.h"
#include "JSystem/JAudio2/JAUStreamFileTable.h"
#include "JSystem/JKernel/JKRSolidHeap.h"
#include <dvd.h>
#include <cstring>
namespace {
class TPushCurrentHeap {
public:
TPushCurrentHeap(JKRHeap* heap) { mHeap = JKRSetCurrentHeap(heap); }
~TPushCurrentHeap() { JKRSetCurrentHeap(mHeap); }
private:
JKRHeap* mHeap;
};
class TStreamDataMgr : public JAIStreamDataMgr {
public:
TStreamDataMgr(const void* param_0) {
JAUStreamFileTable stack_14;
stack_14.init(param_0);
if (!stack_14.isValid()) {
field_0x4 = 0;
field_0x8 = NULL;
return;
}
field_0x4 = stack_14.getNumFiles();
field_0x8 = new s32[field_0x4];
if (!field_0x8) {
field_0x4 = 0;
return;
}
for (u32 i = 0; i < field_0x4; i++) {
field_0x8[i] = DVDConvertPathToEntrynum(stack_14.getFilePath(i));
}
}
virtual s32 getStreamFileEntry(JAISoundID id) {
u32 short_id = id.id_.info.waveID;
if (short_id >= field_0x4) {
return -1;
}
return field_0x8[short_id];
}
bool isValid() { return field_0x4; }
u32 field_0x4;
s32* field_0x8;
};
}
namespace {
bool JKRSolidHeap_isEmpty(JKRSolidHeap* pHeap) {
u32 beforeSize = pHeap->getFreeSize();
pHeap->freeAll();
return pHeap->getFreeSize() - beforeSize == 0;
}
}
JAUSection::TSectionData::TSectionData() {
resetRegisteredWaveBankTables();
resetRegisteredBankTables();
mBstDst = NULL;
mBstnDst = NULL;
field_0x80 = NULL;
field_0xa0 = 0;
field_0x9c = 0;
}
void JAUSection::TSectionData::resetRegisteredBankTables() {
for (u32 i = 0; i < 255; i++) {
registeredBankTables.reset(i);
}
}
void JAUSection::TSectionData::resetRegisteredWaveBankTables() {
for (u32 i = 0; i < 255; i++) {
registeredWaveBankTables.reset(i);
}
}
JAUSection::JAUSection(JAUSectionHeap* param_0, u32 param_1, s32 param_2)
: JSULink<JAUSection>(this), field_0x28(param_1), sectionHeap_(param_0) {
buildingBankTable_ = NULL;
field_0x2c = 1;
data_.field_0x98 = param_2;
if (this != sectionHeap_) {
data_.field_0x00.setSeqDataArchive(sectionHeap_->sectionHeapData_.seqDataBlocks.getSeqDataArchive());
}
}
void JAUSection::finishBuild() {
JUT_ASSERT(143, isOpen());
JUT_ASSERT(144, isBuilding());
{
TPushCurrentHeap push(getHeap_());
}
data_.field_0x98 -= getHeap_()->getFreeSize();
getHeap_()->freeTail();
field_0x2c = 0;
}
void JAUSection::dispose() {
JUT_ASSERT(267, ! data_.registeredBankTables.any());
JUT_ASSERT(268, ! data_.registeredWaveBankTables.any());
if (data_.mBstDst) {
sectionHeap_->sectionHeapData_.soundTable->~JAUSoundTable();
sectionHeap_->sectionHeapData_.soundTable = NULL;
}
if ((data_.mBstnDst)) {
sectionHeap_->sectionHeapData_.soundNameTable->~JAUSoundNameTable();
sectionHeap_->sectionHeapData_.soundNameTable = NULL;
}
}
JAUSoundTable* JAUSection::newSoundTable(void const* bst, u32 param_1, bool param_2) {
JUT_ASSERT(285, isOpen());
JUT_ASSERT(286, isBuilding());
JUT_ASSERT(287, bst);
JUT_ASSERT(288, asSectionHeap() == this);
JUT_ASSERT(289, sectionHeap_->sectionHeapData_.soundTable == NULL);
{
TPushCurrentHeap push(getHeap_());
void const* bstDst = bst;
if (param_1) {
bstDst = newCopy(bst, param_1, 4);
JUT_ASSERT(296, bstDst);
}
JAUSoundTable* soundTable = new JAUSoundTable(param_2);
JUT_ASSERT(299, soundTable);
soundTable->init(bstDst);
sectionHeap_->sectionHeapData_.soundTable = soundTable;
data_.mBstDst = bstDst;
}
return sectionHeap_->sectionHeapData_.soundTable;
}
JAUSoundNameTable* JAUSection::newSoundNameTable(void const* bstn, u32 param_1, bool param_2) {
JUT_ASSERT(315, isOpen());
JUT_ASSERT(316, isBuilding());
JUT_ASSERT(317, bstn);
JUT_ASSERT(318, asSectionHeap() == this);
JUT_ASSERT(319, sectionHeap_->sectionHeapData_.soundNameTable == NULL);
{
TPushCurrentHeap push(getHeap_());
void const* bstnDst = bstn;
if (param_1) {
bstnDst = newCopy(bstn, param_1, 4);
JUT_ASSERT(326, bstnDst);
}
JAUSoundNameTable* soundNameTable = new JAUSoundNameTable(param_2);
JUT_ASSERT(329, soundNameTable);
soundNameTable->init(bstnDst);
sectionHeap_->sectionHeapData_.soundNameTable = soundNameTable;
data_.mBstnDst = bstnDst;
}
return sectionHeap_->sectionHeapData_.soundNameTable;
}
JAIStreamDataMgr* JAUSection::newStreamFileTable(void const* param_0, bool param_1) {
JUT_ASSERT(345, asSectionHeap() == this);
JUT_ASSERT(346, isOpen());
JUT_ASSERT(347, isBuilding());
JUT_ASSERT(348, sectionHeap_->sectionHeapData_.streamDataMgr_ == NULL);
{
TPushCurrentHeap push(getHeap_());
JAIStreamDataMgr* r28 = NULL;
if (param_1) {
TStreamDataMgr* r26 = new TStreamDataMgr(param_0);
if (r26->isValid()) {
r28 = r26;
}
} else {
JAUStreamDataMgr_StreamFileTable* r25 = new JAUStreamDataMgr_StreamFileTable();
r25->init(param_0);
if (r25->isValid()) {
r28 = r25;
}
}
sectionHeap_->sectionHeapData_.streamDataMgr_ = r28;
}
return sectionHeap_->sectionHeapData_.streamDataMgr_;
}
JAISeqDataMgr* JAUSection::newSeSeqCollection(void const* bsc, u32 param_1) {
JUT_ASSERT(398, asSectionHeap() == this);
JUT_ASSERT(399, sectionHeap_->sectionHeapData_.seSeqDataMgr_ == NULL);
if (param_1) {
bsc = newCopy(bsc, param_1, 4);
}
JUT_ASSERT(405, bsc);
{
TPushCurrentHeap push(getHeap_());
JAUSeqDataMgr_SeqCollection* seSeqDataMgr = new JAUSeqDataMgr_SeqCollection();
JUT_ASSERT(409, seSeqDataMgr);
seSeqDataMgr->init(bsc);
sectionHeap_->sectionHeapData_.seSeqDataMgr_ = seSeqDataMgr;
data_.field_0x80 = seSeqDataMgr;
}
return sectionHeap_->sectionHeapData_.seSeqDataMgr_;
}
u8* JAUSection::newStaticSeqDataBlock_(JAISoundID param_0, u32 size) {
JUT_ASSERT(419, isOpen());
JUT_ASSERT(420, isBuilding());
JUT_ASSERT(421, size);
{
TPushCurrentHeap push(getHeap_());
JAUSeqDataBlock* seqDataBlock = new JAUSeqDataBlock();
if (!seqDataBlock) {
return NULL;
}
JSULink<JAUSeqDataBlock>* link = new JSULink<JAUSeqDataBlock>(seqDataBlock);
if (!link) {
JUT_WARN(432, "%s", "created UNUSED object in Heap\n");
return NULL;
}
u8* r28 = new(0x20) u8[size];
if (!r28) {
JUT_WARN(438, "%s", "created UNUSED object in Heap\n");
return NULL;
}
seqDataBlock->region.addr = r28;
seqDataBlock->region.size = size;
seqDataBlock->field_0x10 = param_0;
JASCriticalSection cs;
if(data_.field_0x00.appendDynamicSeqDataBlock(seqDataBlock)) {
data_.field_0x28.append(link);
return r28;
}
}
return NULL;
}
bool JAUSection::newStaticSeqData(JAISoundID param_0, void const* param_1, u32 param_2) {
{
u8* r30 = newStaticSeqDataBlock_(param_0, param_2);
if (r30) {
memcpy(r30, param_1, param_2);
return true;
}
}
return false;
}
bool JAUSection::newStaticSeqData(JAISoundID param_0) {
JKRArchive* seqArchive = data_.field_0x00.getSeqDataArchive();
JUT_ASSERT(481, seqArchive);
JAUSoundInfo* soundInfo = JASGlobalInstance<JAUSoundInfo>::getInstance();
if (!soundInfo) {
JUT_WARN(485, "%s","cannot JAUSoundInfo::getInstance().");
return false;
}
u16 r26 = soundInfo->getBgmSeqResourceID(param_0);
u32 r25 = JASResArcLoader::getResSize(seqArchive, r26);
u8* r24 = newStaticSeqDataBlock_(0xffffffff, r25);
if (r24) {
data_.field_0x00.loadDynamicSeq(param_0, true, sectionHeap_->sectionHeapData_.seqDataUser);
return true;
}
return false;
}
void* JAUSection::newCopy(void const* param_0, u32 param_1, s32 param_2) {
JUT_ASSERT(516, isOpen());
JUT_ASSERT(517, isBuilding());
u8* r31 = new(getHeap_(), param_2) u8[param_1];
if (r31) {
memcpy(r31, param_0, param_1);
}
return r31;
}
static bool dummy_string(int i) {
std::bitset<1> x;
return x.test(i);
}
JASWaveBank* JAUSection::newWaveBank(u32 bank_no, void const* param_1) {
JUT_ASSERT(528, isOpen());
JUT_ASSERT(529, isBuilding());
{
TPushCurrentHeap push(getHeap_());
s32 r27 = getHeap_()->getFreeSize();
JASWaveBank* waveBank = JASWSParser::createWaveBank(param_1, getHeap_());
if (waveBank) {
JUT_ASSERT(536, sectionHeap_->getWaveBankTable().getWaveBank( bank_no ) == NULL);
sectionHeap_->getWaveBankTable().registWaveBank(bank_no, waveBank);
data_.registeredWaveBankTables.set(bank_no, true);
data_.field_0xa0 += r27 - getHeap_()->getFreeSize();
return waveBank;
}
}
return NULL;
}
bool JAUSection::loadWaveArc(u32 param_0, u32 param_1) {
if (data_.registeredWaveBankTables.test(param_0)) {
JASWaveBank* waveBank = sectionHeap_->getWaveBankTable().getWaveBank(param_0);
if (waveBank) {
for (u32 i = 0; i < waveBank->getArcCount(); i++) {
if (param_1 & 1 << i) {
JASWaveArc* waveArc = waveBank->getWaveArc(i);
waveArc->load(NULL);
}
}
return true;
}
}
return false;
}
JASBank* JAUSection::newBank(void const* param_0, u32 param_1) {
JUT_ASSERT(647, isOpen());
JUT_ASSERT(648, isBuilding());
JASWaveBank* waveBank = sectionHeap_->getWaveBankTable().getWaveBank(param_1);
JUT_ASSERT(650, waveBank != NULL);
{
TPushCurrentHeap push(getHeap_());
u32 bank_no = JASBNKParser::getBankNumber(param_0);
s32 r25 = getHeap_()->getFreeSize();
JASBank* bank = JASBNKParser::createBank(param_0, getHeap_());
if (bank) {
if (buildingBankTable_) {
JUT_ASSERT(660, buildingBankTable_->getBank( bank_no ) == NULL);
buildingBankTable_->registBank(bank_no, bank);
} else {
JUT_ASSERT(665, JASDefaultBankTable::getInstance() ->getBank( bank_no ) == NULL);
JASDefaultBankTable::getInstance()->registBank(bank_no, bank);
data_.registeredBankTables.set(bank_no, true);
}
bank->assignWaveBank(waveBank);
data_.field_0x9c += r25 - getHeap_()->getFreeSize();
return bank;
}
}
return 0;
}
JASVoiceBank* JAUSection::newVoiceBank(u32 bank_no, u32 param_1) {
{
JUT_ASSERT(685, isOpen());
JUT_ASSERT(686, isBuilding());
JASWaveBank* waveBank = sectionHeap_->getWaveBankTable().getWaveBank(param_1);
JUT_ASSERT(688, waveBank != NULL);
TPushCurrentHeap push(getHeap_());
JASBank* voiceBank = new JASVoiceBank();
if (voiceBank) {
if (buildingBankTable_) {
JUT_ASSERT(696, buildingBankTable_->getBank( bank_no ) == NULL);
buildingBankTable_->registBank(bank_no, voiceBank);
} else {
JUT_ASSERT(701, JASDefaultBankTable::getInstance() ->getBank( bank_no ) == NULL);
JASDefaultBankTable::getInstance()->registBank(bank_no, voiceBank);
data_.registeredBankTables.set(bank_no, true);
}
voiceBank->assignWaveBank(waveBank);
return (JASVoiceBank*)voiceBank;
}
}
return NULL;
}
bool JAUSection::beginNewBankTable(u32 param_0, u32 param_1) {
JUT_ASSERT(714, isOpen());
JUT_ASSERT(715, isBuilding());
JUT_ASSERT(716, buildingBankTable_ == NULL);
JAUBankTableLink* bankTableLink = NULL;
{
TPushCurrentHeap push(getHeap_());
JASBank** r26 = new JASBank*[param_1];
if (r26) {
bankTableLink = new JAUBankTableLink(param_0, r26, param_1);
if (bankTableLink) {
buildingBankTable_ = bankTableLink;
} else {
JUT_WARN(730, "%s","created UNUSED object in Heap\n");
}
} else {
JUT_WARN(735, "%s","created UNUSED object in Heap\n");
}
}
return bankTableLink;
}
JAUBankTable* JAUSection::endNewBankTable() {
JAUBankTable* r29 = NULL;
if (buildingBankTable_) {
data_.field_0x74.appendBankTable(buildingBankTable_);
buildingBankTable_ = NULL;
r29 = buildingBankTable_;
}
return r29;
}
JAUSectionHeap::TSectionHeapData::TSectionHeapData() {
seSeqDataMgr_ = NULL;
streamDataMgr_ = NULL;
soundTable = NULL;
soundNameTable = NULL;
seqDataUser = NULL;
}
void JAUSectionHeap::setSeqDataArchive(JKRArchive* param_0) {
sectionHeapData_.seqDataBlocks.setSeqDataArchive(param_0);
JSULink<JAUSection>* link;
for (link = mSectionList.getFirst(); link; link = link->getNext()) {
link->getObject()->data_.field_0x00.setSeqDataArchive(param_0);
}
}
bool JAUSectionHeap::loadDynamicSeq(JAISoundID param_0, bool param_1) {
return sectionHeapData_.seqDataBlocks.loadDynamicSeq(param_0, param_1, sectionHeapData_.seqDataUser);
}
u32 JAUSectionHeap::releaseIdleDynamicSeqDataBlock() {
return sectionHeapData_.seqDataBlocks.releaseIdleDynamicSeqDataBlock(sectionHeapData_.seqDataUser);
}
static JAUSectionHeap* JAUNewSectionHeap(JKRSolidHeap* heap, bool param_1) {
JUT_ASSERT(809, JKRSolidHeap_isEmpty( heap ));
TPushCurrentHeap push(heap);
s32 r29 = heap->getFreeSize();
JAUSectionHeap* sectionHeap = new JAUSectionHeap(heap, param_1, r29);
return sectionHeap;
}
JAUSectionHeap* JAUNewSectionHeap(bool param_0) {
s32 freeSize = JASDram->getFreeSize();
JKRSolidHeap* sectionHeap = JKRCreateSolidHeap(freeSize, JASDram, true);
JUT_ASSERT(821, sectionHeap);
return JAUNewSectionHeap(sectionHeap, param_0);
}
JAUSectionHeap::JAUSectionHeap(JKRSolidHeap* param_0, bool param_1, s32 param_2)
: JAUSection(this, 0, param_2), JASGlobalInstance<JAUSectionHeap>(param_1), mHeap(param_0) {
field_0xe4 = 0;
mSectionList.append(this);
}
JAUSection* JAUSectionHeap::getOpenSection() {
return mSectionList.getLast()->getObject();
}
JAUSection* JAUSectionHeap::getSection(int param_0) {
JSULink<JAUSection>* link = mSectionList.getFirst();
while (param_0 > 0) {
JSULink<JAUSection>* link2 = link->getNext();
if (!link2) {
return NULL;
}
link = link2;
param_0--;
}
return link->getObject();
}
bool JAUSectionHeap::setSeqDataUser(JAISeqDataUser* param_0) {
sectionHeapData_.seqDataUser = param_0;
return true;
}
bool JAUSectionHeap::newDynamicSeqBlock(u32 size) {
JUT_ASSERT(937, isOpen());
JUT_ASSERT(938, isBuilding());
JUT_ASSERT(939, sectionHeap_ == this);
{
TPushCurrentHeap push(getHeap_());
JAUSeqDataBlock * seqDataBlock = new JAUSeqDataBlock();
if (!seqDataBlock) {
return false;
}
JSULink<JAUSeqDataBlock> * link = new JSULink<JAUSeqDataBlock>(seqDataBlock);
if (!link) {
JUT_WARN(950, "%s", "created UNUSED object in Heap\n");
return false;
}
u8* r25 = new(0x20) u8[size];
if (!r25) {
JUT_WARN(956, "%s", "created UNUSED object in Heap\n");
return false;
}
seqDataBlock->region.addr = r25;
seqDataBlock->region.size = size;
seqDataBlock->field_0x10.setAnonymous();
JASCriticalSection cs;
if (sectionHeap_->sectionHeapData_.seqDataBlocks.appendDynamicSeqDataBlock(seqDataBlock)) {
return true;
}
JUT_WARN(968, "%s","created UNUSED object in Heap\n");
}
return false;
}
JAISeqDataMgr::SeqDataReturnValue JAUSectionHeap::getSeqData(JAISoundID param_0, JAISeqData* param_1) {
const int JAI_ASYNC_RESULT_RETRY = 1;
for (JSULink<JAUSection> * link = mSectionList.getFirst(); link; link = link->getNext()) {
s32 result = link->getObject()->data_.field_0x00.getSeqData(param_0, sectionHeapData_.seqDataUser, param_1, false);
JUT_ASSERT(994, result != JAI_ASYNC_RESULT_RETRY);
if (result == 2) {
return JAISeqDataMgr::SeqDataReturnValue_2;
}
}
return (SeqDataReturnValue)sectionHeapData_.seqDataBlocks.getSeqData(param_0, sectionHeapData_.seqDataUser, param_1, true);
}
int JAUSectionHeap::releaseSeqData() {
JUT_WARN(1005, "%s", "JAUSectionHeap cannot release SeqData all at once. Please pop Section.\n");
return 0;
}
@@ -0,0 +1,75 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUSeqCollection.h"
#include "JSystem/JUtility/JUTAssert.h"
JAUSeqCollection::JAUSeqCollection() {
field_0x8 = NULL;
}
void JAUSeqCollection::init(void const* param_0) {
field_0x8 = (const JAUSeqCollectionData*)param_0;
if (field_0x8->field_0x0 != 0x53 || field_0x8->field_0x1 != 0x43) {
field_0x8 = NULL;
return;
}
field_0x0 = field_0x8->field_0x2;
field_0xc = field_0x8->field_0x4;
field_0x4 = &field_0x8->field_0x8;
}
bool JAUSeqCollection::getSeqData(int param_0, int param_1, JAISeqData* param_2) {
if (param_0 >= field_0x0) {
return false;
}
u32 r29 = field_0x4[param_0];
u32* puVar2 = (u32*)((u8*)field_0x8 + r29);
if (param_1 >= puVar2[0]) {
return false;
}
param_2->set((void*)field_0x8, puVar2[param_1 + 1]);
return true;
}
bool JAUSeqCollection::getSeqDataRegion(JAISeqDataRegion* param_0) {
if (isValid()) {
param_0->addr = (u8*)field_0x8;
param_0->size = field_0xc;
return true;
}
return false;
}
JAUSeqDataMgr_SeqCollection::JAUSeqDataMgr_SeqCollection() {
user_ = NULL;
}
bool JAUSeqDataMgr_SeqCollection::setSeqDataUser(JAISeqDataUser* param_0) {
JUT_ASSERT(60, user_ == NULL);
user_ = param_0;
return true;
}
int JAUSeqDataMgr_SeqCollection::releaseSeqData() {
if (user_) {
JAISeqDataRegion region;
getSeqDataRegion(&region);
int result = user_->releaseSeqData(region);
return result;
}
return 2;
}
JAUSeqDataMgr_SeqCollection::SeqDataReturnValue JAUSeqDataMgr_SeqCollection::getSeqData(JAISoundID param_0, JAISeqData* param_1) {
if (!isValid()) {
return SeqDataReturnValue_0;
}
if (JAUSeqCollection::getSeqData(param_0.id_.info.type.parts.groupID, param_0.id_.info.waveID, param_1)) {
return SeqDataReturnValue_2;
}
return SeqDataReturnValue_0;
}
JAUSeqDataMgr_SeqCollection::~JAUSeqDataMgr_SeqCollection() {}
@@ -0,0 +1,226 @@
//
// JAUSeqDataBlockMgr
//
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUSeqDataBlockMgr.h"
#include "JSystem/JAudio2/JAUSoundInfo.h"
#include "JSystem/JAudio2/JASResArcLoader.h"
#include <types.h>
JAUSeqDataBlock::JAUSeqDataBlock() : field_0x0(this) {}
u8* JAUSeqDataBlocks::getSeqData(JAISoundID param_0) {
if (param_0.isAnonymous()) {
return NULL;
}
JSULink<JAUSeqDataBlock>* link;
for (link = getFirst(); link != NULL;
link = link->getNext())
{
if ((u32)link->getObject()->field_0x10 == (u32)param_0) {
return link->getObject()->region.addr;
}
}
return NULL;
}
JSULink<JAUSeqDataBlock>* JAUSeqDataBlocks::seekFreeBlock(u32 size) {
u32 currentBlockSize = 0xffffffff;
JSULink<JAUSeqDataBlock>* rv = NULL;
for (JSULink<JAUSeqDataBlock>* link = getFirst(); link != NULL; link = link->getNext())
{
if (link->getObject()->field_0x10.isAnonymous()) {
u32 blockSize = link->getObject()->region.size;
if (blockSize >= size && blockSize < currentBlockSize) {
rv = link;
currentBlockSize = blockSize;
}
}
}
if (rv != NULL) {
return rv;
}
return NULL;
}
bool JAUSeqDataBlocks::append(JSULink<JAUSeqDataBlock>* param_0) {
return JSUList::append(param_0);
}
bool JAUSeqDataBlocks::remove(JSULink<JAUSeqDataBlock>* param_0) {
return JSUList::remove(param_0);
}
bool JAUSeqDataBlocks::hasFailedBlock(JAISoundID param_0) {
JSULink<JAUSeqDataBlock>* link;
for (link = getFirst(); link != NULL; link = link->getNext())
{
if (link->getObject()->field_0x10 == param_0) {
link->getObject()->field_0x10.setAnonymous();
return true;
}
}
return false;
}
JAUDynamicSeqDataBlocks::JAUDynamicSeqDataBlocks() {
seqDataArchive_ = NULL;
}
void JAUDynamicSeqDataBlocks::setSeqDataArchive(JKRArchive* param_0) {
JUT_ASSERT(104, seqDataArchive_ == NULL);
seqDataArchive_ = param_0;
}
s32 JAUDynamicSeqDataBlocks::getSeqData(JAISoundID param_0, JAISeqDataUser* param_1,
JAISeqData* param_2, bool param_3) {
rearrangeLoadingSeqs_();
if (mFreeBlocks.hasFailedBlock(param_0)) {
return 0;
}
if (field_0xc.getSeqData(param_0)) {
return 1;
}
u8* seqData = mLoadedBlocks.getSeqData(param_0);
if (seqData != NULL) {
param_2->field_0x0 = seqData;
param_2->field_0x4 = 0;
return 2;
}
if (loadDynamicSeq(param_0, param_3, param_1)) {
return 1;
}
return 0;
}
bool JAUDynamicSeqDataBlocks::appendDynamicSeqDataBlock(JAUSeqDataBlock* seqDataBlock) {
JUT_ASSERT(135, ( reinterpret_cast < u32 > ( seqDataBlock->region.addr ) & 0x1f ) == 0);
rearrangeLoadingSeqs_();
bool result;
if (seqDataBlock->field_0x10.isAnonymous()) {
result = mFreeBlocks.append(&seqDataBlock->field_0x0);
} else {
result = mLoadedBlocks.append(&seqDataBlock->field_0x0);
}
JUT_ASSERT(144, result);
return 1;
}
static void JAUDynamicSeqDataBlocks_receiveLoaded_(u32 param_0, uintptr_t param_1) {
JSULink<JAUSeqDataBlock>* link = (JSULink<JAUSeqDataBlock>*)param_1;
JAUSeqDataBlock* seqDataBlock = link->getObject();
if (param_0 != 0) {
seqDataBlock->field_0x1c = 2;
} else {
seqDataBlock->field_0x1c = 0;
}
}
bool JAUDynamicSeqDataBlocks::loadDynamicSeq(JAISoundID param_0, bool param_1,
JAISeqDataUser* param_2) {
{
if (seqDataArchive_ == NULL) {
JUT_WARN(192, "%s", "cannot get sequence data archive.");
return false;
}
JAUSoundInfo* soundInfo = JASGlobalInstance<JAUSoundInfo>::getInstance();
if (soundInfo == NULL) {
JUT_WARN(198, "%s", "cannot JAUSoundInfo::getInstance().");
return false;
}
u16 resourceId = soundInfo->getBgmSeqResourceID(param_0);
size_t resSize = JASResArcLoader::getResSize(seqDataArchive_, resourceId);
JSULink<JAUSeqDataBlock>* link = mFreeBlocks.seekFreeBlock(resSize);
if (link == NULL) {
if (param_1) {
link = &releaseIdleDynamicSeqDataBlock_(param_2, resSize)->field_0x0;
if (link == NULL) {
return false;
}
} else {
return false;
}
}
mFreeBlocks.remove(link);
link->getObject()->field_0x10 = param_0;
link->getObject()->field_0x1c = 1;
field_0xc.append(link);
JASResArcLoader::loadResourceAsync(
seqDataArchive_, resourceId,
link->getObject()->region.addr, link->getObject()->region.size,
JAUDynamicSeqDataBlocks_receiveLoaded_, (uintptr_t)link);
}
return true;
}
u32 JAUDynamicSeqDataBlocks::releaseIdleDynamicSeqDataBlock(JAISeqDataUser* param_0) {
rearrangeLoadingSeqs_();
u32 size = 0;
JSULink<JAUSeqDataBlock>* nextLink;
for (JSULink<JAUSeqDataBlock>* link = mLoadedBlocks.getFirst(); link != NULL; ) {
nextLink = link->getNext();
JAUSeqDataBlock* seqDataBlock = link->getObject();
if (param_0 == NULL || !param_0->isUsingSeqData(seqDataBlock->region)) {
mLoadedBlocks.remove(link);
JAUSeqDataBlock* seqDataBlock = link->getObject();
seqDataBlock->field_0x10.setAnonymous();
if (size < seqDataBlock->region.size) {
size = seqDataBlock->region.size;
}
mFreeBlocks.append(link);
}
link = nextLink;
}
return size;
}
JAUSeqDataBlock*
JAUDynamicSeqDataBlocks::releaseIdleDynamicSeqDataBlock_(JAISeqDataUser* param_0, u32 param_1) {
rearrangeLoadingSeqs_();
u32 minSize = 0xffffffff;
JSULink<JAUSeqDataBlock>* foundBlock = NULL;
JSULink<JAUSeqDataBlock>* link = mLoadedBlocks.getFirst();
JSULink<JAUSeqDataBlock>* nextLink;
while (link != NULL) {
nextLink = link->getNext();
JAUSeqDataBlock* seqDataBlock = link->getObject();
if (param_0 == NULL || !param_0->isUsingSeqData(seqDataBlock->region)) {
u32 size = seqDataBlock->region.size;
if (size >= param_1 && size < minSize) {
foundBlock = link;
minSize = size;
}
}
link = nextLink;
}
if (foundBlock != NULL) {
mLoadedBlocks.remove(foundBlock);
JAUSeqDataBlock* seqDataBlock = foundBlock->getObject();
seqDataBlock->field_0x10.setAnonymous();
mFreeBlocks.append(foundBlock);
return foundBlock->getObject();
}
return NULL;
}
void JAUDynamicSeqDataBlocks::rearrangeLoadingSeqs_() {
JSULink<JAUSeqDataBlock>* link = field_0xc.getFirst();
JSULink<JAUSeqDataBlock>* nextLink;
while (link != NULL) {
nextLink = link->getNext();
JAUSeqDataBlock* seqDataBlock = link->getObject();
if (seqDataBlock->field_0x1c == 0) {
field_0xc.remove(link);
mFreeBlocks.append(link);
} else if (seqDataBlock->field_0x1c == 2) {
field_0xc.remove(link);
mLoadedBlocks.append(link);
}
link = nextLink;
}
}
@@ -0,0 +1,27 @@
//
// Translation Unit: JAUSoundAnimator
//
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUSoundAnimator.h"
int JAUSoundAnimation::getStartSoundIndex(f32 param_0) const {
int i;
for (i = 0; i < getNumSounds(); i++) {
if (getSound(i)->field_0x04 >= param_0) {
break;
}
}
return i;
}
int JAUSoundAnimation::getEndSoundIndex(f32 param_0) const {
int i;
for (i = 0; i < getNumSounds(); i++) {
if (getSound(i)->field_0x04 > param_0) {
break;
}
}
return i;
}
@@ -0,0 +1,9 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUSoundObject.h"
#include "JSystem/JGeometry.h"
static void dummy(JGeometry::TVec3<f32>* vec_1, JGeometry::TVec3<f32>* vec_2) {
*vec_1 = *vec_2;
}
@@ -0,0 +1,53 @@
//
// JAUSoundTable
//
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUSoundTable.h"
void JAUSoundTable::init(void const* param_0) {
if (param_0 != NULL) {
field_0x0.init(param_0);
} else {
field_0x0.reset();
}
}
u8 JAUSoundTable::getTypeID(JAISoundID param_0) const {
if (param_0.isAnonymous()) {
return 0xff;
}
JAUSoundTableSection* section = field_0x0.getSection(param_0.id_.info.type.parts.sectionID);
if (section == NULL) {
return 0xff;
}
JAUSoundTableGroup* group = field_0x0.getGroup(section, param_0.id_.info.type.parts.groupID);
if (group == NULL) {
return 0xff;
}
return group->getTypeID(param_0.id_.info.waveID);
}
JAUSoundTableItem* JAUSoundTable::getData(JAISoundID param_0) const {
if (param_0.isAnonymous()) {
return NULL;
}
JAUSoundTableSection* section = field_0x0.getSection(param_0.id_.info.type.parts.sectionID);
if (section == NULL) {
return NULL;
}
JAUSoundTableGroup* group = field_0x0.getGroup(section, param_0.id_.info.type.parts.groupID);
if (group == NULL) {
return NULL;
}
return getItem(group, param_0.id_.info.waveID);
}
void JAUSoundNameTable::init(void const* param_0) {
if (param_0 != NULL) {
field_0x0.init(param_0);
} else {
field_0x0.reset();
}
}
@@ -0,0 +1,40 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/JAUStreamFileTable.h"
JAUStreamFileTable::JAUStreamFileTable() {
mData = NULL;
}
void JAUStreamFileTable::init(void const* data) {
const BinaryStreamFileTable* binaryTable = (const BinaryStreamFileTable*)data;
if (binaryTable == NULL) {
mData = NULL;
return;
}
if (binaryTable->mIdentifier[0] == 'b' && binaryTable->mIdentifier[1] == 's' && binaryTable->mIdentifier[2] == 'f' && binaryTable->mIdentifier[3] == 't') {
mData = binaryTable;
}
}
u32 JAUStreamFileTable::getNumFiles() const {
return mData->mNumFiles;
}
const char* JAUStreamFileTable::getFilePath(int index) const {
if (mData == NULL) {
return 0;
}
JUT_ASSERT(52, index >= 0);
JUT_ASSERT(53, index < getNumFiles());
char* data = (char*)mData;
return (char*)(data + *(int*)(data + 8 + (index * sizeof(s32))));
}
s32 JAUStreamDataMgr_StreamFileTable::getStreamFileEntry(JAISoundID soundId) {
const char* filePath = getFilePath(soundId.id_.info.waveID);
if (filePath == NULL) {
return -1;
}
return DVDConvertPathToEntrynum(filePath);
}
+64
View File
@@ -0,0 +1,64 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/dspproc.h"
#include "JSystem/JAudio2/dsptask.h"
#include "JSystem/JAudio2/JASDSPInterface.h"
void DSPReleaseHalt2(u32 msg) {
u32 msgs[2];
u16 dspMap = DSP_CreateMap2(msg);
msgs[0] = (msg << 16) | dspMap;
DSPSendCommands2(msgs, 0, NULL);
}
static volatile BOOL flag;
static void setup_callback(u16 param_0) {
OS_REPORT("Finish %d\n", param_0);
flag = FALSE;
}
void DsetupTable(u32 param_0, u32 param_1, u32 param_2, u32 param_3, u32 param_4) {
u32 table[5];
table[0] = (param_0 & 0xFFFF) | 0x81000000;
table[1] = param_1;
table[2] = param_2;
table[3] = param_3;
table[4] = param_4;
OS_REPORT("Table Setup\n");
flag = TRUE;
DSPSendCommands2(table, 5, setup_callback);
while (true) {
if (!flag) {
return;
}
}
}
static u16 DSP_MIXERLEVEL = 0x4000;
void DsetMixerLevel(f32 level) {
DSP_MIXERLEVEL = 4096.0f * level;
}
void DsyncFrame2ch(u32 param_0, u32 param_1, u32 param_2) {
u32 msgs[5];
msgs[0] = (param_0 & 0xff) << 0x10 | 0x82000000 | DSP_MIXERLEVEL;
msgs[1] = param_1;
msgs[2] = param_2;
msgs[3] = 0;
msgs[4] = 0;
DSPSendCommands2(msgs, 5, 0);
}
void DsyncFrame4ch(u32 param_0, u32 param_1, u32 param_2, u32 param_3, u32 param_4) {
u32 msgs[5];
msgs[0] = (param_0 & 0xff) << 0x10 | 0x82000000 | DSP_MIXERLEVEL;
msgs[1] = param_1;
msgs[2] = param_2;
msgs[3] = param_3;
msgs[4] = param_4;
DSPSendCommands2(msgs, 5, 0);
}
+629
View File
@@ -0,0 +1,629 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/dsptask.h"
#include "JSystem/JAudio2/osdsp.h"
#include "global.h"
static void DspInitWork();
static void DspHandShake(void* param_0);
static int DspStartWork(u32 param_0, void (*param_1)(u16));
extern int Dsp_Running_Check();
extern void Dsp_Running_Start();
void DspHandShake(void*) {
OS_REPORT("DSP InitCallback \n");
while (DSPCheckMailFromDSP() == 0) {}
u32 result = DSPReadMailFromDSP();
OS_REPORT("♪JDSP/Boot:: DSPからのファーストメール(%x)が届きました\n", result);
result = DSPCheckMailFromDSP();
OS_REPORT("♪JDSP/Boot:: DSPからのセカンドメール(%x)が届きました\n", result);
OS_REPORT("♪JDSP/Boot:: DSPとの接続に成功しました\n");
Dsp_Running_Start();
}
static u8 jdsp[7936] ATTRIBUTE_ALIGN(32) = {
0x02, 0x9F, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0x00, 0x00,
0x02, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02, 0x9F, 0x06, 0xA5,
0x02, 0x9F, 0x00, 0x4E, 0x12, 0x05, 0x02, 0xBF, 0x00, 0x57, 0x81, 0x00, 0x00, 0x9F, 0x10, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x5F, 0x1B, 0x1E, 0x02, 0xBF, 0x07, 0x75, 0x02, 0xBF, 0x06, 0x00,
0x02, 0xBF, 0x0F, 0x08, 0x0E, 0x00, 0x02, 0xBF, 0x07, 0x57, 0x00, 0x9E, 0x11, 0x11, 0x02, 0xBF,
0x07, 0x61, 0x0E, 0x00, 0x00, 0xFE, 0x03, 0x4E, 0x13, 0x05, 0x02, 0x9F, 0x07, 0xB2, 0x00, 0xDF,
0x03, 0x57, 0x00, 0xFF, 0x03, 0x45, 0x00, 0xDE, 0x03, 0x56, 0x1F, 0xFE, 0x03, 0x40, 0x00, 0xFF,
0x00, 0xFF, 0x03, 0x44, 0x14, 0x79, 0x02, 0x40, 0x00, 0x7E, 0x00, 0xFE, 0x03, 0x43, 0x02, 0x00,
0x00, 0x75, 0x1C, 0x1E, 0x17, 0x0F, 0x00, 0x92, 0x00, 0xFF, 0x0E, 0x04, 0x02, 0xBF, 0x07, 0x57,
0x00, 0xDE, 0x03, 0x56, 0x02, 0xBF, 0x07, 0x61, 0x02, 0x9F, 0x00, 0x2D, 0x12, 0x05, 0x02, 0xBF,
0x00, 0x57, 0x0E, 0x01, 0x02, 0xBF, 0x07, 0x57, 0x13, 0x05, 0x02, 0x9F, 0x00, 0x2D, 0x12, 0x02,
0x12, 0x03, 0x12, 0x04, 0x13, 0x06, 0x8E, 0x00, 0x8C, 0x00, 0x8B, 0x00, 0x00, 0x9E, 0xFF, 0xFF,
0x1D, 0x1E, 0x1D, 0x3E, 0x1D, 0x5E, 0x1D, 0x7E, 0x00, 0x92, 0x00, 0xFF, 0x02, 0xDF, 0x00, 0x81,
0x03, 0x58, 0x00, 0x90, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x7E, 0x00, 0x71, 0x19, 0x3E, 0x1B, 0x1E,
0x19, 0x3E, 0x1B, 0x1E, 0x02, 0xDF, 0x02, 0x9F, 0x00, 0x43, 0x02, 0x9F, 0x00, 0x43, 0x02, 0x9F,
0x00, 0x95, 0x02, 0x9F, 0x02, 0x92, 0x02, 0x9F, 0x00, 0x73, 0x02, 0x9F, 0x06, 0x6D, 0x02, 0x9F,
0x06, 0x7F, 0x02, 0x9F, 0x05, 0xA9, 0x02, 0x9F, 0x05, 0x5D, 0x02, 0x9F, 0x05, 0xC5, 0x02, 0x9F,
0x05, 0x8D, 0x02, 0x9F, 0x00, 0x43, 0x02, 0x9F, 0x00, 0x43, 0x02, 0x9F, 0x00, 0x43, 0x02, 0x9F,
0x00, 0xB2, 0x02, 0x9F, 0x00, 0x43, 0x02, 0x9F, 0x00, 0x43, 0x00, 0x80, 0x03, 0x80, 0x0E, 0x04,
0x02, 0xBF, 0x00, 0x67, 0x00, 0x81, 0x03, 0x82, 0x00, 0x9F, 0x00, 0x00, 0x00, 0x80, 0x02, 0x80,
0x02, 0xBF, 0x06, 0x10, 0x00, 0x81, 0x03, 0x84, 0x00, 0x9F, 0x03, 0x00, 0x00, 0x80, 0x00, 0x20,
0x02, 0xBF, 0x06, 0x10, 0x00, 0xDE, 0x03, 0x45, 0x00, 0xFE, 0x03, 0x42, 0x02, 0xBF, 0x0C, 0xD9,
0x02, 0x9F, 0x00, 0x43, 0x00, 0x80, 0x03, 0x74, 0x0E, 0x01, 0x00, 0xFE, 0x03, 0x77, 0x00, 0xFE,
0x03, 0x7C, 0x02, 0xBF, 0x00, 0x67, 0x00, 0xDE, 0x03, 0x45, 0x00, 0xFE, 0x03, 0x76, 0x02, 0x9F,
0x00, 0x43, 0x00, 0x81, 0x03, 0x4C, 0x00, 0x9F, 0x04, 0x00, 0x00, 0x80, 0x00, 0xC0, 0x02, 0xBF,
0x06, 0x10, 0x02, 0xDF, 0x00, 0x81, 0x03, 0x4C, 0x00, 0x9F, 0x04, 0x00, 0x00, 0x80, 0x00, 0x80,
0x00, 0x81, 0x03, 0x4C, 0x19, 0x3E, 0x19, 0x3C, 0x00, 0x98, 0x00, 0x00, 0x70, 0x00, 0x02, 0xBF,
0x06, 0x1F, 0x02, 0xDF, 0x19, 0x1E, 0x19, 0x1A, 0x00, 0x5F, 0x64, 0xA0, 0x1B, 0x7E, 0x1B, 0x7A,
0x02, 0xDF, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xE7, 0x19, 0x1E, 0x1B, 0x7E, 0x19, 0x1E, 0x1B, 0x7E,
0x00, 0x00, 0x02, 0xDF, 0x19, 0x1E, 0x19, 0x1A, 0x00, 0x7F, 0x00, 0xF1, 0x32, 0xB2, 0x65, 0xA0,
0x33, 0xBA, 0x64, 0xA1, 0x00, 0x00, 0x02, 0xDF, 0x8A, 0x00, 0x15, 0x7F, 0x1C, 0x20, 0x1C, 0x03,
0x19, 0x3A, 0x90, 0x51, 0x92, 0x5B, 0x00, 0x7F, 0x01, 0x00, 0x46, 0x51, 0x92, 0xB2, 0x46, 0x51,
0x92, 0xB2, 0x8B, 0x00, 0x02, 0xDF, 0x8A, 0x00, 0x19, 0x1A, 0x90, 0x50, 0x92, 0x50, 0x00, 0x5F,
0x92, 0xA0, 0x8B, 0x00, 0x02, 0xDF, 0x81, 0x00, 0x89, 0x00, 0x0E, 0x50, 0x00, 0x80, 0x0D, 0x00,
0x00, 0x5E, 0x1B, 0x1F, 0x00, 0x80, 0x0D, 0x60, 0x00, 0x5E, 0x1B, 0x1F, 0x00, 0xDA, 0x03, 0x74,
0x86, 0x00, 0x02, 0xB5, 0x0F, 0x33, 0x81, 0x00, 0x89, 0x00, 0x0E, 0x50, 0x00, 0x80, 0x0C, 0xA0,
0x00, 0x5E, 0x1B, 0x1F, 0x00, 0x80, 0x0F, 0x40, 0x00, 0x5E, 0x1B, 0x1F, 0x00, 0x80, 0x0F, 0xA0,
0x00, 0x5E, 0x1B, 0x1F, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x5E, 0x1B, 0x1F, 0x00, 0x80, 0x09, 0xA0,
0x00, 0x5E, 0x1B, 0x1F, 0x0F, 0x04, 0x00, 0x80, 0x0E, 0x10, 0x00, 0x83, 0x0D, 0xC0, 0x02, 0xBF,
0x00, 0xE1, 0x00, 0x80, 0x0E, 0x70, 0x00, 0x83, 0x0E, 0x20, 0x02, 0xBF, 0x00, 0xE1, 0x00, 0x80,
0x0E, 0xD0, 0x00, 0x83, 0x0E, 0x80, 0x02, 0xBF, 0x00, 0xE1, 0x00, 0x80, 0x0F, 0x30, 0x00, 0x83,
0x0E, 0xE0, 0x02, 0xBF, 0x00, 0xE1, 0x81, 0x00, 0x0E, 0x50, 0x89, 0x00, 0x00, 0x80, 0x0D, 0xC8,
0x00, 0x5E, 0x1B, 0x1F, 0x00, 0x80, 0x0E, 0x28, 0x00, 0x5E, 0x1B, 0x1F, 0x00, 0x80, 0x0E, 0x88,
0x00, 0x5E, 0x1B, 0x1F, 0x00, 0x80, 0x0E, 0xE8, 0x00, 0x5E, 0x1B, 0x1F, 0x02, 0xDF, 0x00, 0x9F,
0x05, 0x80, 0x00, 0x9B, 0x00, 0xA0, 0x00, 0x81, 0x03, 0x93, 0x18, 0xBC, 0xB8, 0x71, 0xBC, 0x00,
0x00, 0x80, 0x00, 0x50, 0x02, 0xBF, 0x06, 0x12, 0x02, 0xDF, 0x00, 0xDF, 0x03, 0xA1, 0x05, 0x08,
0x00, 0x80, 0x05, 0x80, 0x1C, 0x7F, 0x00, 0x98, 0x7F, 0xFF, 0x89, 0x00, 0x0F, 0x50, 0x02, 0xBF,
0x00, 0xF4, 0x02, 0xDF, 0x00, 0xC0, 0x03, 0xA0, 0x19, 0x1A, 0x02, 0xBF, 0x01, 0x5F, 0x02, 0xBF,
0x01, 0x6D, 0x81, 0x00, 0x89, 0x00, 0x00, 0xDE, 0x03, 0x90, 0x02, 0xA0, 0x00, 0x01, 0x02, 0x9D,
0x01, 0x90, 0x00, 0x80, 0x03, 0x98, 0x0E, 0x08, 0x00, 0xC1, 0x03, 0xA1, 0x02, 0xBF, 0x0C, 0x1B,
0x0F, 0x50, 0x00, 0xC0, 0x03, 0xA1, 0x00, 0xDA, 0x03, 0x94, 0x86, 0x00, 0x02, 0x95, 0x01, 0x9D,
0x1C, 0x7A, 0x00, 0xD8, 0x03, 0x95, 0x02, 0xBF, 0x00, 0xF4, 0x0F, 0x50, 0x00, 0xC0, 0x03, 0xA1,
0x00, 0xDA, 0x03, 0x96, 0x86, 0x00, 0x02, 0x95, 0x01, 0xAA, 0x1C, 0x7A, 0x00, 0xD8, 0x03, 0x97,
0x02, 0xBF, 0x00, 0xF4, 0x00, 0xDE, 0x03, 0x90, 0x02, 0xA0, 0x00, 0x02, 0x02, 0xDD, 0x00, 0x80,
0x03, 0x98, 0x0E, 0x08, 0x00, 0xC1, 0x03, 0xA1, 0x02, 0xBF, 0x0C, 0x1B, 0x02, 0xDF, 0x89, 0x00,
0x00, 0x9F, 0x0D, 0xC0, 0x00, 0xFF, 0x03, 0xA1, 0x00, 0x9F, 0x03, 0xA8, 0x00, 0xFF, 0x03, 0xA2,
0x00, 0x9F, 0x03, 0xA4, 0x00, 0xFF, 0x03, 0xA0, 0x11, 0x04, 0x01, 0xE4, 0x00, 0xC0, 0x03, 0xA2,
0x00, 0x83, 0x03, 0x90, 0x89, 0x00, 0x0F, 0x08, 0x02, 0xBF, 0x00, 0xE1, 0x00, 0xDA, 0x03, 0x90,
0x86, 0x00, 0x02, 0x95, 0x01, 0xD5, 0x02, 0xBF, 0x01, 0x7A, 0x81, 0x00, 0x00, 0xDE, 0x03, 0xA2,
0x04, 0x10, 0x00, 0xFE, 0x03, 0xA2, 0x00, 0xDE, 0x03, 0xA1, 0x04, 0x60, 0x00, 0xFE, 0x03, 0xA1,
0x00, 0xDE, 0x03, 0xA0, 0x74, 0x00, 0x00, 0xFE, 0x03, 0xA0, 0x00, 0xDA, 0x03, 0x74, 0x86, 0x00,
0x02, 0x94, 0x02, 0x0E, 0x0F, 0x50, 0x00, 0x80, 0x0B, 0xE0, 0x00, 0x83, 0x0E, 0x80, 0x00, 0x98,
0x7F, 0xFF, 0x02, 0xBF, 0x00, 0xF4, 0x0F, 0x50, 0x00, 0x80, 0x0B, 0xE0, 0x00, 0x83, 0x0E, 0xE0,
0x00, 0x98, 0xB8, 0x20, 0x02, 0xBF, 0x00, 0xF4, 0x0F, 0x28, 0x00, 0x80, 0x0C, 0x68, 0x00, 0x83,
0x0E, 0x80, 0x00, 0x98, 0xB8, 0x20, 0x02, 0xBF, 0x00, 0xF4, 0x0F, 0x28, 0x00, 0x80, 0x0C, 0x68,
0x00, 0x83, 0x0E, 0xE0, 0x00, 0x98, 0x7F, 0xFF, 0x02, 0xBF, 0x00, 0xF4, 0x81, 0x00, 0x89, 0x00,
0x0E, 0x50, 0x00, 0x80, 0x0B, 0xE0, 0x00, 0x5E, 0x1B, 0x1F, 0x00, 0x80, 0x0C, 0x40, 0x00, 0x5E,
0x1B, 0x1F, 0x02, 0xDF, 0x00, 0xC0, 0x03, 0xA0, 0x18, 0x1A, 0x81, 0x00, 0x18, 0x1E, 0x00, 0xDB,
0x03, 0x91, 0x74, 0x00, 0xD1, 0x00, 0x02, 0x70, 0x81, 0x00, 0x1B, 0x1E, 0x00, 0xDF, 0x03, 0xA1,
0x00, 0x9B, 0x00, 0xA0, 0x00, 0x81, 0x03, 0x93, 0x18, 0xBC, 0xB8, 0x71, 0xBC, 0x00, 0x00, 0x80,
0x00, 0x50, 0x02, 0xBF, 0x06, 0x1F, 0x02, 0xDF, 0x00, 0xDA, 0x03, 0x74, 0x86, 0x00, 0x02, 0x94,
0x02, 0x4D, 0x89, 0x00, 0x0F, 0x28, 0x00, 0x80, 0x0C, 0x40, 0x00, 0x83, 0x0E, 0xA8, 0x00, 0x98,
0xB8, 0x20, 0x02, 0xBF, 0x00, 0xF4, 0x89, 0x00, 0x0F, 0x28, 0x00, 0x80, 0x0C, 0x40, 0x00, 0x83,
0x0F, 0x08, 0x00, 0x98, 0x7F, 0xFF, 0x02, 0xBF, 0x00, 0xF4, 0x00, 0x9F, 0x0D, 0xC0, 0x00, 0xFF,
0x03, 0xA1, 0x00, 0x9F, 0x03, 0xA8, 0x00, 0xFF, 0x03, 0xA2, 0x00, 0x9F, 0x03, 0xA4, 0x00, 0xFF,
0x03, 0xA0, 0x11, 0x04, 0x02, 0x77, 0x00, 0xC0, 0x03, 0xA2, 0x00, 0x83, 0x03, 0x90, 0x0F, 0x08,
0x02, 0xBF, 0x00, 0xE1, 0x00, 0xDA, 0x03, 0x90, 0x86, 0x00, 0x02, 0x95, 0x02, 0x69, 0x02, 0xBF,
0x02, 0x1A, 0x00, 0xDE, 0x03, 0xA2, 0x04, 0x10, 0x00, 0xFE, 0x03, 0xA2, 0x00, 0xDE, 0x03, 0xA1,
0x04, 0x60, 0x00, 0xFE, 0x03, 0xA1, 0x00, 0xDE, 0x03, 0xA0, 0x74, 0x00, 0x00, 0xFE, 0x03, 0xA0,
0x02, 0xDF, 0x00, 0x81, 0x03, 0x86, 0x00, 0x9F, 0x03, 0xA8, 0x00, 0x80, 0x00, 0x40, 0x02, 0xBF,
0x06, 0x10, 0x02, 0xDF, 0x19, 0x1E, 0x18, 0x9C, 0x48, 0x00, 0x1B, 0x1E, 0x1B, 0x1C, 0x02, 0xDF,
0x81, 0x00, 0x89, 0x00, 0x00, 0xDF, 0x03, 0x54, 0x00, 0xDE, 0x03, 0x4E, 0x82, 0x00, 0x02, 0x93,
0x02, 0x88, 0x02, 0xDF, 0x00, 0x80, 0x03, 0x88, 0x00, 0x81, 0x00, 0x67, 0x0E, 0x02, 0x17, 0x3F,
0x02, 0xBF, 0x04, 0x74, 0x00, 0xDE, 0x03, 0x44, 0x00, 0xFE, 0x03, 0x41, 0x00, 0xDE, 0x03, 0x45,
0x00, 0xFE, 0x03, 0x8E, 0x81, 0x00, 0x00, 0xFE, 0x03, 0x55, 0x02, 0xBF, 0x02, 0x79, 0x02, 0xBF,
0x06, 0x91, 0x00, 0xDE, 0x03, 0x41, 0x00, 0x7E, 0x04, 0x6F, 0x02, 0xBF, 0x01, 0x0B, 0x02, 0xBF,
0x01, 0xB7, 0x02, 0xBF, 0x04, 0xE0, 0x02, 0xBF, 0x0A, 0x4C, 0x00, 0xDE, 0x03, 0x55, 0x74, 0x00,
0x00, 0xFE, 0x03, 0x55, 0x81, 0x00, 0x00, 0xFE, 0x03, 0x54, 0x00, 0xDE, 0x03, 0x42, 0x00, 0x7E,
0x04, 0x13, 0x02, 0xBF, 0x02, 0x88, 0x81, 0x00, 0x89, 0x00, 0x00, 0xDE, 0x03, 0x54, 0x14, 0x7C,
0x02, 0x00, 0x04, 0xFC, 0x1C, 0x1E, 0x18, 0x1F, 0x00, 0xDE, 0x03, 0x54, 0x02, 0x40, 0x00, 0x0F,
0x3D, 0x80, 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9C, 0x04, 0x0F, 0x00, 0xD8, 0x03, 0x54, 0x00, 0x9A,
0x01, 0x80, 0x81, 0x00, 0x00, 0xDE, 0x03, 0x80, 0x00, 0xDC, 0x03, 0x81, 0x90, 0x00, 0x94, 0x00,
0x00, 0xFE, 0x03, 0x4C, 0x00, 0xFC, 0x03, 0x4D, 0x02, 0xBF, 0x00, 0xC1, 0x00, 0xDA, 0x04, 0x00,
0x86, 0x00, 0x02, 0x95, 0x04, 0x0F, 0x00, 0xDA, 0x04, 0x01, 0x86, 0x00, 0x02, 0x94, 0x04, 0x0F,
0x00, 0xDA, 0x04, 0x33, 0x00, 0xFA, 0x03, 0xF8, 0x00, 0xDA, 0x04, 0x06, 0x86, 0x00, 0x02, 0x94,
0x0E, 0xF3, 0x81, 0x00, 0x00, 0xDE, 0x04, 0x80, 0x06, 0x09, 0x02, 0x95, 0x03, 0x10, 0x06, 0x05,
0x02, 0x95, 0x03, 0x10, 0x06, 0x08, 0x02, 0x95, 0x0A, 0x7C, 0x06, 0x10, 0x02, 0x95, 0x0B, 0x01,
0x06, 0x20, 0x02, 0x95, 0x0B, 0x87, 0x06, 0x21, 0x02, 0x95, 0x0B, 0x8F, 0x02, 0x9F, 0x09, 0x69,
0x00, 0xD8, 0x04, 0x02, 0x81, 0x00, 0x89, 0x00, 0x00, 0xDC, 0x04, 0x30, 0x8D, 0x00, 0x09, 0x50,
0xA0, 0x00, 0xA4, 0x00, 0x14, 0x04, 0x8C, 0x00, 0x1F, 0xFE, 0x00, 0x83, 0x05, 0x80, 0x02, 0xBF,
0x08, 0x2A, 0x02, 0x9F, 0x03, 0x23, 0x00, 0x80, 0x05, 0x80, 0x00, 0x81, 0x05, 0x20, 0x00, 0x99,
0x00, 0x00, 0x02, 0xBF, 0x0E, 0x73, 0x00, 0xDA, 0x04, 0xA8, 0x86, 0x00, 0x02, 0x95, 0x03, 0x34,
0x00, 0x80, 0x05, 0x20, 0x02, 0xBF, 0x0D, 0x71, 0x00, 0x9E, 0x05, 0x20, 0x00, 0xFE, 0x03, 0x8F,
0x89, 0x00, 0x00, 0xDF, 0x04, 0x84, 0x03, 0x40, 0x00, 0x1F, 0xB9, 0x00, 0x02, 0x95, 0x03, 0x64,
0x00, 0xDE, 0x03, 0x8F, 0x5C, 0x00, 0x00, 0xFE, 0x03, 0x8F, 0x1C, 0x7E, 0x00, 0x80, 0x04, 0x40,
0x05, 0xFE, 0x02, 0xBF, 0x00, 0xDA, 0x00, 0x80, 0x04, 0x90, 0x00, 0xC1, 0x03, 0x8F, 0x89, 0x00,
0x00, 0xDF, 0x04, 0x84, 0x03, 0x40, 0x00, 0x1F, 0x02, 0xBF, 0x0C, 0x3A, 0x00, 0xDE, 0x03, 0x8F,
0x04, 0x50, 0x1C, 0x1E, 0x00, 0x83, 0x04, 0x40, 0x89, 0x00, 0x00, 0xDF, 0x04, 0x84, 0x03, 0x40,
0x00, 0x1F, 0x05, 0xFE, 0x02, 0xBF, 0x00, 0xDA, 0x00, 0xDE, 0x04, 0x84, 0x02, 0x40, 0x00, 0x20,
0x02, 0x95, 0x03, 0x86, 0x00, 0x80, 0x04, 0xA4, 0x00, 0xC1, 0x03, 0x8F, 0x00, 0x82, 0x04, 0x54,
0x00, 0x83, 0x04, 0xA7, 0x18, 0xFA, 0x86, 0x00, 0x02, 0x94, 0x03, 0x84, 0x18, 0xFA, 0x86, 0x00,
0x02, 0x94, 0x03, 0x84, 0x18, 0xFA, 0x86, 0x00, 0x02, 0x94, 0x03, 0x84, 0x81, 0x00, 0x18, 0xFE,
0x02, 0x80, 0x7F, 0xFF, 0x02, 0x95, 0x03, 0x86, 0x02, 0xBF, 0x0C, 0x55, 0x81, 0x00, 0x00, 0xDE,
0x04, 0x2C, 0xB1, 0x00, 0x02, 0x95, 0x03, 0x90, 0x02, 0xBF, 0x0D, 0xC0, 0x02, 0x9F, 0x04, 0x05,
0x81, 0x00, 0x1C, 0x9E, 0x1C, 0xDE, 0x74, 0x00, 0x1C, 0xFE, 0x81, 0x00, 0x00, 0xDE, 0x04, 0x07,
0xB1, 0x00, 0x02, 0x95, 0x03, 0xA8, 0x00, 0xC3, 0x03, 0x8F, 0x00, 0x07, 0x00, 0x80, 0x04, 0x77,
0x00, 0x84, 0xFF, 0xFF, 0x00, 0x87, 0xFF, 0xFF, 0x19, 0x9A, 0x65, 0x54, 0x00, 0x5E, 0x65, 0xAD,
0x00, 0xDA, 0x04, 0x85, 0x86, 0x00, 0x02, 0x95, 0x03, 0xBE, 0x89, 0x00, 0x00, 0x86, 0x00, 0x05,
0x00, 0x82, 0x04, 0x0A, 0x11, 0x06, 0x03, 0xB6, 0x18, 0xDE, 0x14, 0x7F, 0x4D, 0x36, 0xB9, 0x00,
0x02, 0x94, 0x03, 0xBE, 0x00, 0x9A, 0x00, 0x01, 0x00, 0xFA, 0x04, 0x01, 0x8F, 0x00, 0x00, 0x86,
0x00, 0x02, 0x00, 0x82, 0x04, 0x08, 0x11, 0x06, 0x03, 0xEE, 0x81, 0x00, 0x19, 0x5E, 0x12, 0x00,
0xB1, 0x00, 0x02, 0x75, 0x13, 0x00, 0x1C, 0x7E, 0x19, 0x5E, 0x19, 0x5F, 0x5C, 0x00, 0x14, 0xFB,
0x1F, 0x5E, 0x1F, 0x1C, 0x18, 0x5E, 0x02, 0x40, 0x00, 0xFF, 0x1F, 0x7E, 0x18, 0x5E, 0x14, 0x78,
0x00, 0x9C, 0x00, 0x00, 0xD1, 0x00, 0x02, 0x95, 0x03, 0xE3, 0x18, 0x5E, 0x02, 0x72, 0x74, 0x00,
0x02, 0x71, 0x78, 0x00, 0x1A, 0x5E, 0x00, 0x06, 0x00, 0xDE, 0x03, 0x8F, 0x56, 0x00, 0x02, 0x9D,
0x03, 0xEC, 0x1C, 0x1E, 0x02, 0xBF, 0x0D, 0x96, 0x00, 0x00, 0x1B, 0x5F, 0x00, 0x0A, 0x8E, 0x00,
0x81, 0x00, 0x00, 0xDE, 0x04, 0x07, 0xB1, 0x00, 0x02, 0x95, 0x04, 0x05, 0x00, 0xC3, 0x03, 0x8F,
0x00, 0x87, 0x00, 0x4F, 0x00, 0x1F, 0x00, 0x80, 0x04, 0x77, 0x00, 0x84, 0xFF, 0xFF, 0x00, 0x87,
0xFF, 0xFF, 0x19, 0xFA, 0x65, 0x57, 0x00, 0x5E, 0x65, 0xAF, 0x00, 0xDA, 0x04, 0x06, 0x86, 0x00,
0x02, 0x94, 0x04, 0x0D, 0x81, 0x00, 0x00, 0xFE, 0x04, 0x04, 0x02, 0xBF, 0x00, 0xCA, 0x00, 0xDE,
0x03, 0x54, 0x74, 0x00, 0x00, 0xFE, 0x03, 0x54, 0x0E, 0x00, 0x00, 0xFE, 0x03, 0x4E, 0x0E, 0x04,
0x02, 0xBF, 0x07, 0x57, 0x00, 0xDE, 0x03, 0x55, 0x02, 0x60, 0xFF, 0x00, 0x02, 0xBF, 0x07, 0x61,
0x02, 0xBF, 0x0C, 0xF7, 0x02, 0xBF, 0x0D, 0x09, 0x02, 0xBF, 0x0D, 0x5E, 0x00, 0xDE, 0x03, 0x41,
0x78, 0x00, 0x00, 0xFE, 0x03, 0x41, 0x00, 0x80, 0x09, 0xA0, 0x00, 0x83, 0x0D, 0x00, 0x0F, 0x50,
0x00, 0x98, 0x5A, 0x82, 0x02, 0xBF, 0x00, 0xF4, 0x00, 0x80, 0x09, 0xA0, 0x00, 0x83, 0x0D, 0x60,
0x0F, 0x50, 0x02, 0xBF, 0x00, 0xF4, 0x00, 0x83, 0x0D, 0x00, 0x02, 0xBF, 0x0D, 0xAE, 0x00, 0x81,
0x03, 0x88, 0x00, 0x9F, 0x0D, 0x00, 0x00, 0x80, 0x00, 0x50, 0x02, 0xBF, 0x06, 0x1D, 0x00, 0x80,
0x0F, 0xA0, 0x00, 0x83, 0x0D, 0x60, 0x0F, 0x50, 0x00, 0x98, 0x80, 0x00, 0x02, 0xBF, 0x00, 0xF4,
0x00, 0x83, 0x0D, 0x60, 0x02, 0xBF, 0x0D, 0xAE, 0x00, 0x81, 0x03, 0x8A, 0x00, 0x9F, 0x0D, 0x60,
0x00, 0x80, 0x00, 0x50, 0x02, 0xBF, 0x06, 0x1D, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x98, 0x00, 0xA0,
0x00, 0x80, 0x03, 0x88, 0x02, 0xBF, 0x02, 0x82, 0x00, 0x80, 0x03, 0x8A, 0x02, 0xBF, 0x02, 0x82,
0x02, 0xBF, 0x02, 0x34, 0x02, 0xBF, 0x04, 0xAF, 0x02, 0xBF, 0x04, 0x86, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x2D, 0x02, 0x9F, 0x06, 0xF0, 0x00, 0x80, 0x03, 0x74, 0x0E, 0x02, 0x02, 0xBF,
0x00, 0x69, 0x00, 0xDE, 0x03, 0x74, 0x02, 0x40, 0x7F, 0xFF, 0x00, 0xFE, 0x03, 0x74, 0x00, 0xDE,
0x03, 0x76, 0x02, 0x40, 0x7F, 0xFF, 0x00, 0xFE, 0x03, 0x76, 0x02, 0xDF, 0x00, 0xDA, 0x03, 0x74,
0x86, 0x00, 0x02, 0xD5, 0x00, 0x83, 0x0F, 0x40, 0x02, 0xBF, 0x0D, 0xAE, 0x00, 0x83, 0x0C, 0xA0,
0x02, 0xBF, 0x0D, 0xAE, 0x00, 0x81, 0x03, 0x74, 0x00, 0x9F, 0x0F, 0x40, 0x00, 0x80, 0x00, 0x50,
0x02, 0xBF, 0x06, 0x1D, 0x00, 0x81, 0x03, 0x76, 0x00, 0x9F, 0x0C, 0xA0, 0x00, 0x80, 0x00, 0x50,
0x02, 0xBF, 0x06, 0x1D, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x98, 0x00, 0xA0, 0x00, 0x80, 0x03, 0x74,
0x02, 0xBF, 0x02, 0x82, 0x00, 0x80, 0x03, 0x76, 0x02, 0xBF, 0x02, 0x82, 0x02, 0xDF, 0x00, 0xDA,
0x03, 0x74, 0x86, 0x00, 0x02, 0xD5, 0x00, 0x9F, 0x0B, 0xE0, 0x00, 0xFF, 0x03, 0xA1, 0x00, 0xDF,
0x03, 0xCA, 0x00, 0xFF, 0x03, 0x92, 0x00, 0xDF, 0x03, 0xCB, 0x00, 0xFF, 0x03, 0x93, 0x00, 0x9F,
0x03, 0xA6, 0x00, 0xFF, 0x03, 0xA0, 0x00, 0xDF, 0x03, 0xC9, 0x00, 0xFF, 0x03, 0x91, 0x02, 0xBF,
0x02, 0x1A, 0x00, 0x9F, 0x0C, 0x40, 0x00, 0xFF, 0x03, 0xA1, 0x00, 0xDF, 0x03, 0xDA, 0x00, 0xFF,
0x03, 0x92, 0x00, 0xDF, 0x03, 0xDB, 0x00, 0xFF, 0x03, 0x93, 0x00, 0x9F, 0x03, 0xA7, 0x00, 0xFF,
0x03, 0xA0, 0x00, 0xDF, 0x03, 0xD9, 0x00, 0xFF, 0x03, 0x91, 0x02, 0xBF, 0x02, 0x1A, 0x02, 0xDF,
0x00, 0xDA, 0x03, 0x74, 0x86, 0x00, 0x02, 0xD5, 0x00, 0xDA, 0x03, 0xD8, 0x86, 0x00, 0x02, 0xD5,
0x00, 0x83, 0x0B, 0xE0, 0x00, 0x80, 0x0C, 0x30, 0x0F, 0x04, 0x02, 0xBF, 0x00, 0xE1, 0x00, 0x83,
0x0C, 0x40, 0x00, 0x80, 0x0C, 0x90, 0x0F, 0x04, 0x02, 0xBF, 0x00, 0xE1, 0x00, 0xDF, 0x03, 0xCA,
0x00, 0xFF, 0x03, 0x92, 0x00, 0xDF, 0x03, 0xCB, 0x00, 0xFF, 0x03, 0x93, 0x00, 0xDF, 0x03, 0xA6,
0x75, 0x00, 0x1F, 0x5F, 0x00, 0x9F, 0x0B, 0xE8, 0x02, 0xBF, 0x01, 0x61, 0x00, 0xDF, 0x03, 0xDA,
0x00, 0xFF, 0x03, 0x92, 0x00, 0xDF, 0x03, 0xDB, 0x00, 0xFF, 0x03, 0x93, 0x00, 0xDF, 0x03, 0xA7,
0x75, 0x00, 0x1F, 0x5F, 0x00, 0x9F, 0x0C, 0x48, 0x02, 0xBF, 0x01, 0x61, 0x00, 0xDE, 0x03, 0xC8,
0x02, 0xA0, 0x00, 0x01, 0x02, 0x9D, 0x05, 0x23, 0x00, 0x80, 0x03, 0xD0, 0x0E, 0x08, 0x00, 0x81,
0x0B, 0xE0, 0x02, 0xBF, 0x0C, 0x1B, 0x00, 0xDE, 0x03, 0xD8, 0x02, 0xA0, 0x00, 0x01, 0x02, 0x9D,
0x05, 0x30, 0x00, 0x80, 0x03, 0xE0, 0x0E, 0x08, 0x00, 0x81, 0x0C, 0x40, 0x02, 0xBF, 0x0C, 0x1B,
0x0F, 0x50, 0x00, 0x80, 0x0B, 0xE0, 0x00, 0x83, 0x0F, 0x40, 0x00, 0xD8, 0x03, 0xCD, 0x02, 0xBF,
0x00, 0xF4, 0x0F, 0x50, 0x00, 0x80, 0x0C, 0x40, 0x00, 0x83, 0x0C, 0xA0, 0x00, 0xD8, 0x03, 0xDF,
0x02, 0xBF, 0x00, 0xF4, 0x00, 0xDE, 0x03, 0xC8, 0x02, 0xA0, 0x00, 0x02, 0x02, 0x9D, 0x05, 0x4F,
0x00, 0x80, 0x03, 0xD0, 0x0E, 0x08, 0x00, 0x81, 0x0B, 0xE0, 0x02, 0xBF, 0x0C, 0x1B, 0x00, 0xDE,
0x03, 0xD8, 0x02, 0xA0, 0x00, 0x02, 0x02, 0x9D, 0x05, 0x5C, 0x00, 0x80, 0x03, 0xE0, 0x0E, 0x08,
0x00, 0x81, 0x0C, 0x40, 0x02, 0xBF, 0x0C, 0x1B, 0x02, 0xDF, 0x00, 0x80, 0x03, 0x46, 0x02, 0xBF,
0x00, 0x67, 0x02, 0xBF, 0x00, 0x67, 0x00, 0x81, 0x03, 0x46, 0x19, 0x3E, 0x19, 0x3C, 0x00, 0x9F,
0x04, 0x00, 0x00, 0xC0, 0x03, 0x45, 0x02, 0xBF, 0x06, 0x12, 0x00, 0x81, 0x03, 0x48, 0x19, 0x3E,
0x19, 0x3C, 0x00, 0x9F, 0x08, 0x00, 0x00, 0xC0, 0x03, 0x45, 0x02, 0xBF, 0x06, 0x12, 0x00, 0x81,
0x03, 0x46, 0x19, 0x3E, 0x19, 0x3C, 0x00, 0x9F, 0x08, 0x00, 0x00, 0xC0, 0x03, 0x45, 0x02, 0xBF,
0x06, 0x1F, 0x00, 0x81, 0x03, 0x48, 0x19, 0x3E, 0x19, 0x3C, 0x00, 0x9F, 0x04, 0x00, 0x00, 0xC0,
0x03, 0x45, 0x02, 0xBF, 0x06, 0x1F, 0x02, 0x9F, 0x00, 0x43, 0x00, 0x80, 0x03, 0x46, 0x02, 0xBF,
0x00, 0x67, 0x02, 0xBF, 0x00, 0x67, 0x00, 0x81, 0x03, 0x46, 0x19, 0x3E, 0x19, 0x3C, 0x00, 0x9F,
0x04, 0x00, 0x00, 0xC0, 0x03, 0x45, 0x02, 0xBF, 0x06, 0x12, 0x00, 0x81, 0x03, 0x48, 0x19, 0x3E,
0x19, 0x3C, 0x00, 0x9F, 0x04, 0x00, 0x00, 0xC0, 0x03, 0x45, 0x02, 0xBF, 0x06, 0x1F, 0x02, 0x9F,
0x00, 0x43, 0x00, 0x80, 0x03, 0x46, 0x02, 0xBF, 0x00, 0x67, 0x02, 0xBF, 0x00, 0x67, 0x00, 0x81,
0x03, 0x46, 0x19, 0x3E, 0x19, 0x3C, 0x00, 0x9F, 0x04, 0x00, 0x00, 0xC0, 0x03, 0x45, 0x02, 0xBF,
0x06, 0x42, 0x00, 0x81, 0x03, 0x48, 0x19, 0x3E, 0x19, 0x3C, 0x00, 0x9F, 0x04, 0x00, 0x00, 0xC0,
0x03, 0x45, 0x02, 0xBF, 0x06, 0x1F, 0x02, 0x9F, 0x00, 0x43, 0x00, 0x80, 0x03, 0x46, 0x02, 0xBF,
0x00, 0x67, 0x02, 0xBF, 0x00, 0x67, 0x00, 0x81, 0x03, 0x46, 0x19, 0x3E, 0x19, 0x3C, 0x00, 0x9F,
0x04, 0x00, 0x00, 0xC0, 0x03, 0x44, 0x02, 0xBF, 0x06, 0x12, 0x00, 0x81, 0x03, 0x48, 0x19, 0x3E,
0x19, 0x3C, 0x00, 0x9F, 0x08, 0x00, 0x00, 0xC0, 0x03, 0x44, 0x02, 0xBF, 0x06, 0x12, 0x00, 0x80,
0x04, 0x00, 0x00, 0x83, 0x08, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0xDA, 0x03, 0x45, 0x00, 0xDF,
0x03, 0x44, 0x8F, 0x00, 0x19, 0x7B, 0xB8, 0x00, 0x19, 0x7B, 0x00, 0x7F, 0x05, 0xF2, 0x19, 0x9E,
0xBC, 0x00, 0x80, 0xB2, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x81, 0x03, 0x46, 0x19, 0x3E, 0x19, 0x3C,
0x00, 0x9F, 0x04, 0x00, 0x00, 0xC0, 0x03, 0x44, 0x02, 0xBF, 0x06, 0x1F, 0x02, 0x9F, 0x00, 0x43,
0x00, 0x92, 0x00, 0xFF, 0x81, 0x00, 0x00, 0x80, 0x0B, 0x00, 0x10, 0xFF, 0x1B, 0x1E, 0x1B, 0x1E,
0x81, 0x00, 0x00, 0x9F, 0x0B, 0x00, 0x00, 0x80, 0x01, 0x00, 0x02, 0xBF, 0x06, 0x60, 0x02, 0xDF,
0x19, 0x3E, 0x19, 0x3C, 0x2F, 0xCD, 0x0F, 0x00, 0x2F, 0xC9, 0x2E, 0xCE, 0x2C, 0xCF, 0x1F, 0xE0,
0x15, 0x01, 0x2F, 0xCB, 0x02, 0xBF, 0x06, 0x23, 0x02, 0xDF, 0x19, 0x3E, 0x19, 0x3C, 0x2F, 0xCD,
0x0F, 0x01, 0x02, 0x9F, 0x06, 0x14, 0x26, 0xC9, 0x02, 0xA0, 0x00, 0x04, 0x02, 0x9C, 0x06, 0x23,
0x02, 0xDF, 0x19, 0x3E, 0x19, 0x3C, 0x00, 0xFF, 0xFF, 0xCD, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0xC9,
0x00, 0xFE, 0xFF, 0xCE, 0x00, 0xFC, 0xFF, 0xCF, 0x1F, 0xE0, 0x15, 0x01, 0x00, 0xFF, 0xFF, 0xCB,
0x02, 0xDF, 0x00, 0xDE, 0xFF, 0xC9, 0x02, 0xA0, 0x00, 0x04, 0x02, 0x9C, 0x06, 0x39, 0x02, 0xDF,
0x19, 0x3E, 0x19, 0x3C, 0x02, 0x40, 0x7F, 0xFF, 0x02, 0xBF, 0x06, 0x4E, 0x00, 0x7A, 0x06, 0x4C,
0x26, 0xD3, 0x1B, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xDF, 0x1C, 0x3F, 0x0F, 0x0A,
0x2F, 0xD1, 0x1F, 0x5E, 0x1F, 0x1C, 0x00, 0x9E, 0xFF, 0xFF, 0x2E, 0xD6, 0x2E, 0xD7, 0x1F, 0xDA,
0x1F, 0x98, 0x14, 0x7F, 0x2E, 0xD8, 0x2C, 0xD9, 0x1F, 0x40, 0x02, 0xDF, 0x19, 0x3E, 0x19, 0x3C,
0x00, 0x90, 0x00, 0x01, 0x02, 0xBF, 0x06, 0x4E, 0x00, 0x7A, 0x06, 0x6B, 0x19, 0x3E, 0x2E, 0xD3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xDF, 0x00, 0x80, 0x03, 0x46, 0x02, 0xBF,
0x00, 0x67, 0x02, 0xBF, 0x00, 0x67, 0x00, 0x81, 0x03, 0x46, 0x00, 0xDF, 0x03, 0x49, 0x03, 0x40,
0xFF, 0xFF, 0x00, 0xC0, 0x03, 0x45, 0x02, 0xBF, 0x06, 0x10, 0x02, 0x9F, 0x00, 0x43, 0x00, 0x80,
0x03, 0x46, 0x02, 0xBF, 0x00, 0x67, 0x02, 0xBF, 0x00, 0x67, 0x00, 0x81, 0x03, 0x46, 0x00, 0xDF,
0x03, 0x49, 0x03, 0x40, 0xFF, 0xFF, 0x00, 0xC0, 0x03, 0x45, 0x02, 0xBF, 0x06, 0x1D, 0x02, 0x9F,
0x00, 0x43, 0x00, 0x92, 0x00, 0xFF, 0x00, 0x9E, 0xFF, 0xFF, 0x2E, 0xD4, 0x2E, 0xD5, 0x2E, 0xD6,
0x2E, 0xD7, 0x02, 0xDF, 0x00, 0xFF, 0xFF, 0xD1, 0x03, 0x40, 0x00, 0x03, 0x79, 0x00, 0x02, 0xCA,
0x00, 0xFE, 0xFF, 0xD8, 0x00, 0xFC, 0xFF, 0xD9, 0x02, 0xDF, 0x12, 0x05, 0x8E, 0x00, 0x00, 0xF0,
0x03, 0xFD, 0x00, 0xFC, 0x03, 0xFF, 0xF4, 0x00, 0x00, 0xFC, 0x03, 0xFE, 0x00, 0xFA, 0x03, 0xFA,
0x81, 0x00, 0x00, 0xDE, 0xFF, 0xFE, 0x02, 0xC0, 0x80, 0x00, 0x02, 0x9C, 0x07, 0xA6, 0x00, 0xDA,
0xFF, 0xFF, 0x86, 0x00, 0x02, 0x94, 0x07, 0x7F, 0x00, 0xDE, 0xFF, 0xFE, 0x02, 0xC0, 0x80, 0x00,
0x02, 0x9C, 0x06, 0xBC, 0x02, 0x40, 0x00, 0x0F, 0x1F, 0x5E, 0x74, 0x00, 0x0C, 0x00, 0x14, 0x04,
0x00, 0xFE, 0x03, 0x4E, 0x1F, 0xDA, 0x1F, 0x40, 0x02, 0x00, 0x04, 0xFC, 0x1C, 0x1E, 0x00, 0xDE,
0xFF, 0xFF, 0x1A, 0x1E, 0x1C, 0x1A, 0x00, 0xDE, 0x03, 0xFE, 0x00, 0xDC, 0x03, 0xFF, 0x00, 0xD0,
0x03, 0xFD, 0x00, 0xDA, 0x03, 0xFA, 0x13, 0x05, 0x02, 0xFF, 0x00, 0x9A, 0x00, 0x02, 0x00, 0xFA,
0x03, 0xA3, 0x00, 0xE0, 0x03, 0xF9, 0x02, 0xBF, 0x07, 0x69, 0x16, 0xFC, 0xDC, 0xD1, 0x16, 0xFD,
0x00, 0x02, 0x16, 0xFB, 0x00, 0x01, 0x00, 0x21, 0x07, 0x04, 0x07, 0x05, 0x07, 0x45, 0x07, 0x48,
0x00, 0xE0, 0x03, 0xF9, 0x00, 0x9E, 0x00, 0x05, 0x02, 0xBF, 0x07, 0x57, 0x8E, 0x00, 0x81, 0x00,
0x89, 0x00, 0x02, 0xBF, 0x07, 0x4B, 0x27, 0xFF, 0x00, 0x9E, 0x06, 0xEC, 0x4C, 0x00, 0x1C, 0x7E,
0x03, 0x13, 0x1C, 0x7F, 0x17, 0x6F, 0x00, 0x21, 0x00, 0x21, 0x00, 0x9A, 0x00, 0x02, 0x00, 0xFA,
0x03, 0xA3, 0x81, 0x00, 0x89, 0x00, 0x02, 0xBF, 0x07, 0x4B, 0x24, 0xFF, 0x02, 0xBF, 0x07, 0x51,
0x25, 0xFF, 0x02, 0xBF, 0x07, 0x51, 0x27, 0xFF, 0x2E, 0xCE, 0x2C, 0xCF, 0x16, 0xC9, 0x00, 0x01,
0x2F, 0xCD, 0x2D, 0xCB, 0x81, 0x00, 0x89, 0x00, 0x02, 0xBF, 0x07, 0x4B, 0x24, 0xFF, 0x1C, 0x9E,
0x1C, 0xBC, 0x02, 0xBF, 0x07, 0x51, 0x25, 0xFF, 0x02, 0xBF, 0x07, 0x51, 0x27, 0xFF, 0x1C, 0xDF,
0x1C, 0xFD, 0x81, 0x00, 0x02, 0xBF, 0x07, 0x4B, 0x26, 0xFF, 0x1C, 0x1E, 0x89, 0x00, 0x02, 0xBF,
0x07, 0x51, 0x20, 0xFF, 0x1F, 0x5F, 0x02, 0xBF, 0x07, 0x4B, 0x21, 0xFF, 0x02, 0xBF, 0x07, 0x4B,
0x23, 0xFF, 0x26, 0xC9, 0x02, 0xA0, 0x00, 0x04, 0x02, 0x9C, 0x07, 0x39, 0x12, 0x06, 0x12, 0x03,
0x12, 0x04, 0x12, 0x05, 0x02, 0x9F, 0x80, 0xB5, 0x00, 0x21, 0x02, 0x9F, 0x80, 0x00, 0x00, 0x21,
0x00, 0xC0, 0x03, 0xF9, 0x17, 0x0F, 0x26, 0xFE, 0x02, 0xC0, 0x80, 0x00, 0x02, 0x9C, 0x07, 0x4B,
0x02, 0xDF, 0x27, 0xFE, 0x03, 0xC0, 0x80, 0x00, 0x02, 0x9C, 0x07, 0x51, 0x02, 0xDF, 0x02, 0xBF,
0x07, 0x6F, 0x16, 0xFC, 0xDC, 0xD1, 0x2E, 0xFD, 0x16, 0xFB, 0x00, 0x01, 0x02, 0xBF, 0x07, 0x6F,
0x02, 0xDF, 0x02, 0xBF, 0x07, 0x6F, 0x16, 0xFC, 0xF3, 0x55, 0x2E, 0xFD, 0x02, 0xBF, 0x07, 0x6F,
0x02, 0xDF, 0x26, 0xFC, 0x02, 0xC0, 0x80, 0x00, 0x02, 0x9D, 0x07, 0x69, 0x02, 0xDF, 0x27, 0xFC,
0x03, 0xC0, 0x80, 0x00, 0x02, 0x9D, 0x07, 0x6F, 0x02, 0xDF, 0x00, 0x9A, 0x02, 0x80, 0x00, 0xFA,
0x03, 0x50, 0x00, 0xFA, 0x03, 0x51, 0x0A, 0x00, 0x00, 0xFA, 0x03, 0x52, 0x02, 0xDF, 0x00, 0xE0,
0x03, 0xFB, 0x00, 0xE8, 0x03, 0xFC, 0x00, 0xC0, 0x03, 0x50, 0x00, 0x88, 0x00, 0x2F, 0x1B, 0x1A,
0x00, 0xDE, 0xFF, 0xFE, 0x02, 0xC0, 0x80, 0x00, 0x02, 0x9C, 0x07, 0x88, 0x00, 0xDC, 0xFF, 0xFF,
0x1B, 0x1E, 0x1B, 0x1C, 0x1F, 0xDA, 0x78, 0x00, 0x1F, 0x5E, 0x86, 0x00, 0x02, 0x94, 0x07, 0x88,
0x81, 0x00, 0x00, 0xDE, 0x03, 0x52, 0x74, 0x00, 0x00, 0xFE, 0x03, 0x52, 0x00, 0xE0, 0x03, 0x50,
0x00, 0xC0, 0x03, 0xFB, 0x00, 0xC8, 0x03, 0xFC, 0x02, 0x9F, 0x06, 0xD3, 0x00, 0xE0, 0x03, 0xFB,
0x00, 0xE8, 0x03, 0xFC, 0x00, 0xC0, 0x03, 0x50, 0x00, 0x88, 0x00, 0x2F, 0x0A, 0x00, 0x1B, 0x1A,
0x02, 0x9F, 0x07, 0x98, 0x00, 0xC0, 0x03, 0x51, 0x00, 0x88, 0x00, 0x2F, 0x00, 0xDA, 0x03, 0x52,
0x86, 0x00, 0x02, 0x95, 0x07, 0xDA, 0x12, 0x05, 0x00, 0xDA, 0x03, 0x52, 0x1F, 0xDA, 0x78, 0x00,
0x00, 0xFE, 0x03, 0x52, 0x13, 0x05, 0x00, 0x81, 0x03, 0x56, 0x19, 0x1E, 0x02, 0xC0, 0x80, 0x00,
0x02, 0x9D, 0x07, 0xDE, 0x1F, 0x5E, 0x86, 0x00, 0x02, 0x95, 0x07, 0xE2, 0x00, 0x7A, 0x07, 0xD3,
0x19, 0x1E, 0x1B, 0x3E, 0x19, 0x1E, 0x1B, 0x3E, 0x00, 0xE0, 0x03, 0x51, 0x00, 0x88, 0xFF, 0xFF,
0x02, 0x9F, 0x00, 0x2F, 0x00, 0x88, 0xFF, 0xFF, 0x02, 0x9F, 0x00, 0x2D, 0x00, 0xE0, 0x03, 0x51,
0x02, 0x9F, 0x07, 0xB6, 0x00, 0x80, 0x07, 0xB2, 0x02, 0x9F, 0x06, 0xDD, 0x81, 0x00, 0x0E, 0x10,
0x22, 0x32, 0x86, 0x00, 0x02, 0xD5, 0x54, 0x00, 0x02, 0x00, 0x04, 0x58, 0x1C, 0x1E, 0x1F, 0xDA,
0x04, 0xFE, 0x1F, 0x1E, 0x19, 0x1E, 0x02, 0x91, 0x07, 0xF9, 0x19, 0x1A, 0x00, 0x58, 0x64, 0xA0,
0x64, 0x33, 0x1B, 0x7E, 0x02, 0xDF, 0x02, 0xBF, 0x07, 0xE6, 0x81, 0x00, 0x26, 0x32, 0x5C, 0x00,
0x2E, 0x32, 0x00, 0x92, 0x00, 0xFF, 0x02, 0xDF, 0x00, 0xDE, 0x04, 0xFB, 0x74, 0x00, 0x00, 0xFE,
0x04, 0xFB, 0x81, 0x00, 0x2E, 0x32, 0x2E, 0x66, 0x2E, 0x67, 0x26, 0x8A, 0x24, 0x8B, 0x2E, 0x3A,
0x2C, 0x3B, 0x26, 0x8C, 0x24, 0x8D, 0x2E, 0x38, 0x2C, 0x39, 0x02, 0xDF, 0x81, 0x00, 0x26, 0x89,
0x02, 0x40, 0x00, 0x0F, 0x1F, 0x5E, 0x81, 0x00, 0x0E, 0x10, 0x54, 0x00, 0x2E, 0x32, 0x26, 0x8A,
0x24, 0x8B, 0x22, 0x88, 0x20, 0x89, 0x58, 0x00, 0x0A, 0x00, 0x20, 0x32, 0x58, 0x00, 0x2E, 0x3A,
0x2C, 0x3B, 0x02, 0xDF, 0x00, 0x92, 0x00, 0x04, 0x81, 0x00, 0x26, 0x04, 0xB1, 0x00, 0x02, 0xB4,
0x08, 0x04, 0x81, 0x00, 0x26, 0x01, 0xB1, 0x00, 0x02, 0x94, 0x08, 0xD2, 0x22, 0x32, 0xC9, 0x00,
0x02, 0x93, 0x07, 0xFB, 0x55, 0x00, 0x02, 0xBF, 0x07, 0xE6, 0x22, 0x3A, 0x86, 0x00, 0x02, 0x94,
0x08, 0x46, 0x81, 0x00, 0x26, 0x3B, 0x82, 0x00, 0x02, 0x91, 0x08, 0x98, 0x81, 0x00, 0x1F, 0xDF,
0x04, 0x0F, 0x14, 0x7C, 0x1F, 0x7E, 0x0C, 0x00, 0x14, 0x04, 0x1F, 0x1E, 0x0A, 0x00, 0x81, 0x00,
0x26, 0x3A, 0x24, 0x3B, 0x58, 0x00, 0x02, 0x90, 0x08, 0x5E, 0x81, 0x00, 0x26, 0x3B, 0x5C, 0x00,
0x2E, 0x32, 0x81, 0x00, 0x2E, 0x3A, 0x2E, 0x3B, 0x02, 0x9F, 0x08, 0x64, 0x2E, 0x3A, 0x2C, 0x3B,
0x0C, 0x00, 0x1F, 0xD8, 0x5C, 0x00, 0x2E, 0x32, 0x81, 0x00, 0x1F, 0xDB, 0x02, 0xBF, 0x08, 0xD8,
0x22, 0x32, 0x86, 0x00, 0x02, 0x95, 0x08, 0x95, 0x0A, 0x10, 0x81, 0x00, 0x1F, 0xC3, 0x54, 0x00,
0x1C, 0x7E, 0x00, 0x80, 0x04, 0x58, 0x19, 0x7E, 0x19, 0x7A, 0x10, 0x0E, 0x64, 0xA2, 0x1B, 0x1E,
0x1B, 0x1A, 0x81, 0x00, 0x26, 0x3A, 0x24, 0x3B, 0xB1, 0x00, 0x02, 0x94, 0x08, 0x95, 0x22, 0x32,
0x86, 0x00, 0x02, 0x95, 0x08, 0x95, 0x00, 0x80, 0x04, 0x67, 0x81, 0x00, 0x26, 0x8B, 0xB1, 0x00,
0x02, 0x95, 0x08, 0x95, 0x02, 0x00, 0x00, 0x0F, 0x02, 0x40, 0x00, 0x0F, 0x02, 0x00, 0x04, 0x58,
0x1C, 0x7E, 0x00, 0x7A, 0x08, 0x94, 0x18, 0xFE, 0x1A, 0x9E, 0x00, 0x92, 0x00, 0xFF, 0x02, 0xDF,
0xB1, 0x00, 0x02, 0x95, 0x08, 0xA8, 0x5D, 0x00, 0x04, 0x0F, 0x14, 0x7C, 0x0C, 0x00, 0x00, 0xE3,
0x03, 0x63, 0x02, 0xBF, 0x08, 0xD8, 0x00, 0xDE, 0x03, 0x63, 0x22, 0x3B, 0x44, 0x00, 0x1C, 0x7E,
0x81, 0x00, 0x26, 0x81, 0xB1, 0x00, 0x02, 0x95, 0x08, 0xD0, 0x23, 0x80, 0x26, 0x88, 0x24, 0x89,
0x14, 0x08, 0x14, 0xF4, 0x23, 0x80, 0x8D, 0x00, 0xC8, 0x10, 0xAE, 0x00, 0x8C, 0x00, 0xF0, 0x00,
0x4E, 0x00, 0x23, 0x8C, 0x21, 0x8D, 0x4A, 0x00, 0x2E, 0x38, 0x2C, 0x39, 0x26, 0x82, 0x2E, 0x67,
0x26, 0x83, 0x2E, 0x66, 0x00, 0xE3, 0x03, 0x63, 0x00, 0x83, 0x04, 0x58, 0x81, 0x00, 0x0E, 0x01,
0x02, 0xBF, 0x08, 0xD8, 0x00, 0xC3, 0x03, 0x63, 0x02, 0xBF, 0x08, 0x16, 0x02, 0x9F, 0x08, 0x36,
0x0E, 0x01, 0x2E, 0x01, 0x81, 0x00, 0x00, 0x5F, 0x1B, 0x7E, 0x00, 0x92, 0x00, 0xFF, 0x02, 0xDF,
0x00, 0xFF, 0x03, 0x60, 0x00, 0xFE, 0x03, 0x61, 0x26, 0x38, 0x24, 0x39, 0x0F, 0x05, 0x02, 0xBF,
0x06, 0x9A, 0x26, 0x38, 0x24, 0x39, 0x89, 0x00, 0x00, 0xDF, 0x03, 0x61, 0x22, 0x80, 0xD0, 0x00,
0x6F, 0x00, 0x4C, 0x00, 0x2E, 0x38, 0x2C, 0x39, 0x81, 0x00, 0x00, 0xDE, 0x03, 0x61, 0x00, 0x7E,
0x09, 0x58, 0x00, 0x80, 0xFF, 0xD3, 0x00, 0x84, 0x00, 0x00, 0x19, 0x9E, 0x89, 0x00, 0x1F, 0xFE,
0x14, 0x01, 0x02, 0x40, 0x00, 0x1E, 0x02, 0x00, 0x03, 0x00, 0x1C, 0x3E, 0x15, 0x7C, 0x03, 0x40,
0x00, 0x0F, 0x0A, 0x11, 0x55, 0x00, 0x81, 0x00, 0x26, 0x80, 0x06, 0x05, 0x02, 0x95, 0x09, 0x1F,
0x00, 0x9A, 0x00, 0xF0, 0x0B, 0x0F, 0x00, 0x82, 0x03, 0x64, 0x19, 0x98, 0x60, 0x00, 0x11, 0x07,
0x09, 0x16, 0x34, 0x00, 0x14, 0x08, 0x60, 0x32, 0x36, 0x44, 0x14, 0x0C, 0x60, 0x32, 0x34, 0x00,
0x14, 0x08, 0x60, 0x32, 0x36, 0x00, 0x14, 0x0C, 0x1B, 0x5E, 0x02, 0x9F, 0x09, 0x3F, 0x00, 0x9A,
0xC0, 0x00, 0x00, 0x82, 0x03, 0x64, 0x19, 0x98, 0x60, 0x00, 0x11, 0x03, 0x09, 0x32, 0x14, 0x08,
0x34, 0x00, 0x60, 0x32, 0x14, 0x0A, 0x34, 0x00, 0x60, 0x32, 0x14, 0x0C, 0x34, 0x00, 0x60, 0x32,
0x14, 0x0E, 0x34, 0x44, 0x60, 0x32, 0x14, 0x08, 0x34, 0x00, 0x60, 0x32, 0x14, 0x0A, 0x34, 0x00,
0x60, 0x32, 0x14, 0x0C, 0x34, 0x00, 0x60, 0x32, 0x14, 0x0E, 0x34, 0x00, 0x1B, 0x5E, 0x8F, 0x00,
0x1F, 0x7F, 0x20, 0x66, 0x27, 0x67, 0x19, 0x3A, 0x19, 0x39, 0x00, 0x80, 0x03, 0x64, 0x1C, 0x80,
0xA0, 0x00, 0xEA, 0x70, 0x11, 0x08, 0x09, 0x53, 0x3A, 0x93, 0xA4, 0x78, 0x14, 0x85, 0xE8, 0x33,
0x3B, 0x92, 0xA5, 0x70, 0x15, 0x85, 0xEA, 0x3B, 0x2F, 0x67, 0x8E, 0x00, 0x1F, 0xF8, 0x2F, 0x66,
0x89, 0x00, 0x00, 0xDF, 0x03, 0x60, 0x02, 0xDF, 0xB1, 0x00, 0x02, 0xD5, 0x04, 0xFE, 0x1F, 0x1E,
0x19, 0x1E, 0x02, 0x91, 0x09, 0x67, 0x19, 0x1A, 0x00, 0x58, 0x64, 0xA0, 0x64, 0x33, 0x1B, 0x7E,
0x02, 0xDF, 0x81, 0x00, 0x1F, 0x5E, 0x00, 0xD8, 0x04, 0x02, 0x00, 0xDC, 0x04, 0x30, 0x00, 0x80,
0x05, 0x20, 0x00, 0xDF, 0x04, 0x80, 0x15, 0x01, 0x03, 0x40, 0x00, 0x7E, 0x03, 0x00, 0x09, 0x7E,
0x1C, 0x5F, 0x17, 0x5F, 0x00, 0xFC, 0x04, 0x30, 0x02, 0x9F, 0x03, 0x2B, 0x02, 0x9F, 0x09, 0x9F,
0x02, 0x9F, 0x09, 0xDA, 0x02, 0x9F, 0x09, 0xC2, 0x02, 0x9F, 0x09, 0xAF, 0x02, 0x9F, 0x09, 0xE8,
0x02, 0x9F, 0x09, 0x9E, 0x02, 0x9F, 0x0A, 0x06, 0x02, 0x9F, 0x0A, 0x09, 0x02, 0x9F, 0x09, 0x9E,
0x02, 0x9F, 0x09, 0x9E, 0x02, 0x9F, 0x0A, 0x27, 0x02, 0x9F, 0x09, 0xE0, 0x02, 0x9F, 0x09, 0xE4,
0x02, 0x9F, 0x09, 0x9E, 0x02, 0x9F, 0x09, 0x9E, 0x02, 0x9F, 0x09, 0x9E, 0x02, 0xDF, 0x14, 0x01,
0x00, 0x9B, 0xC0, 0x00, 0x00, 0x99, 0x40, 0x00, 0x11, 0x50, 0x09, 0xAC, 0x02, 0xC0, 0x00, 0x01,
0x02, 0x7C, 0x1B, 0x1B, 0x02, 0x7D, 0x1B, 0x19, 0x48, 0x00, 0x14, 0x7F, 0x02, 0xDF, 0x14, 0x02,
0x89, 0x00, 0x1F, 0xB8, 0x15, 0x01, 0x00, 0x9B, 0xC0, 0x00, 0x00, 0x99, 0x40, 0x00, 0x11, 0x50,
0x09, 0xBF, 0x02, 0xC0, 0x00, 0x03, 0x02, 0x7C, 0x1B, 0x1B, 0x02, 0x7D, 0x1B, 0x19, 0x4C, 0x00,
0x14, 0x7E, 0x02, 0xDF, 0x14, 0x01, 0x00, 0x81, 0x0C, 0xA0, 0x00, 0x9B, 0xC0, 0x00, 0x00, 0x99,
0x40, 0x00, 0x89, 0x00, 0x00, 0x82, 0x00, 0x00, 0x11, 0x50, 0x09, 0xD7, 0x02, 0xC0, 0x00, 0x01,
0x02, 0x7C, 0x1B, 0x1B, 0x02, 0x7D, 0x1B, 0x19, 0x18, 0x3D, 0x49, 0x00, 0x1F, 0xE2, 0x4C, 0x39,
0x14, 0x7F, 0x02, 0xDF, 0x89, 0x00, 0x1F, 0xB8, 0x15, 0x7F, 0x10, 0x50, 0x4C, 0x20, 0x02, 0xDF,
0x00, 0x82, 0x01, 0x80, 0x02, 0x9F, 0x09, 0xEA, 0x00, 0x82, 0x01, 0xC0, 0x02, 0x9F, 0x09, 0xEA,
0x00, 0x82, 0x01, 0x40, 0x00, 0x8A, 0x00, 0x3F, 0x00, 0x86, 0x00, 0x00, 0x14, 0x06, 0x89, 0x00,
0x1F, 0xB8, 0x15, 0x05, 0x00, 0x9B, 0x00, 0x3F, 0x00, 0x9A, 0x00, 0x00, 0x36, 0x00, 0x1C, 0xDE,
0x00, 0x1A, 0x34, 0x00, 0x11, 0x50, 0x0A, 0x00, 0x4C, 0x4A, 0x36, 0x06, 0x1C, 0xDE, 0x34, 0x0E,
0x1B, 0x19, 0x1F, 0xC2, 0x14, 0x7A, 0x00, 0x8A, 0xFF, 0xFF, 0x02, 0xDF, 0x10, 0x50, 0x1B, 0x18,
0x02, 0xDF, 0x00, 0x82, 0x01, 0x00, 0x00, 0x8A, 0x00, 0x3F, 0x00, 0x86, 0x00, 0x00, 0x14, 0x06,
0x89, 0x00, 0x1F, 0xB8, 0x15, 0x05, 0x00, 0x9B, 0x00, 0x3F, 0x00, 0x9A, 0x00, 0x00, 0x36, 0x00,
0x1C, 0xDE, 0x00, 0x1A, 0x34, 0x00, 0x11, 0x50, 0x0A, 0x21, 0x4C, 0x4A, 0x36, 0x06, 0x1C, 0xDE,
0x34, 0x0E, 0x1B, 0x19, 0x1F, 0xC2, 0x14, 0x7A, 0x00, 0x8A, 0xFF, 0xFF, 0x02, 0xDF, 0x00, 0x82,
0x01, 0x00, 0x00, 0x8A, 0x00, 0x3F, 0x00, 0x86, 0x00, 0x00, 0x00, 0x81, 0x0C, 0xA0, 0x14, 0x06,
0x89, 0x00, 0x1F, 0xB8, 0x15, 0x05, 0x00, 0x9B, 0x00, 0x3F, 0x00, 0x9A, 0x00, 0x00, 0x36, 0x00,
0x1C, 0xDE, 0x00, 0x1A, 0x34, 0x00, 0x11, 0x50, 0x0A, 0x46, 0x19, 0x39, 0xA0, 0x00, 0x14, 0x0A,
0x4E, 0x00, 0x14, 0x76, 0x4C, 0x4A, 0x36, 0x06, 0x1C, 0xDE, 0x34, 0x0E, 0x1B, 0x19, 0x1F, 0xC2,
0x14, 0x7A, 0x00, 0x8A, 0xFF, 0xFF, 0x02, 0xDF, 0x00, 0x80, 0x01, 0xBE, 0x19, 0x18, 0x19, 0x1A,
0x00, 0x80, 0x01, 0x80, 0x00, 0x83, 0x01, 0x80, 0x90, 0x70, 0x1F, 0xFE, 0x11, 0x20, 0x0A, 0x5D,
0x7C, 0x00, 0xD4, 0x50, 0x65, 0x33, 0xC5, 0x50, 0x15, 0x01, 0x64, 0x3B, 0x00, 0x80, 0x01, 0xFE,
0x19, 0x1A, 0x19, 0x18, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x83, 0x01, 0xC0, 0x1F, 0xF8, 0x90, 0x70,
0xF8, 0x00, 0x02, 0x40, 0x01, 0xFF, 0x02, 0x60, 0x20, 0x00, 0x02, 0xBF, 0x0A, 0x70, 0x02, 0xDF,
0xB9, 0x00, 0x02, 0x72, 0x7C, 0x00, 0x1F, 0x7E, 0x47, 0x00, 0x11, 0x10, 0x0A, 0x7A, 0x47, 0x3B,
0x47, 0x3B, 0x47, 0x3B, 0x47, 0x3B, 0x02, 0xDF, 0x00, 0x92, 0x00, 0x04, 0x20, 0x02, 0x81, 0x00,
0x89, 0x00, 0x24, 0x30, 0x8D, 0x00, 0x09, 0x50, 0xA0, 0x00, 0xA4, 0x00, 0x14, 0x04, 0x8C, 0x00,
0x1F, 0xFE, 0x00, 0x83, 0x05, 0x80, 0x22, 0x01, 0x86, 0x00, 0x02, 0x94, 0x0A, 0x9E, 0x22, 0x04,
0x86, 0x00, 0x02, 0xB4, 0x0A, 0xE6, 0x81, 0x00, 0x26, 0x05, 0xB1, 0x00, 0x02, 0x95, 0x0A, 0xAB,
0x81, 0x00, 0x2E, 0x05, 0x22, 0x81, 0x86, 0x00, 0x02, 0x94, 0x0A, 0xA5, 0x81, 0x00, 0x00, 0x5F,
0x1B, 0x7E, 0x74, 0x00, 0x2E, 0x01, 0x02, 0x9F, 0x0A, 0xDF, 0x26, 0x88, 0x24, 0x89, 0x2E, 0x34,
0x2C, 0x35, 0x02, 0xBF, 0x0A, 0xE6, 0x00, 0xFF, 0x03, 0x60, 0x26, 0x38, 0x24, 0x39, 0x0F, 0x05,
0x02, 0xBF, 0x06, 0x9A, 0x00, 0xDF, 0x03, 0x60, 0x81, 0x00, 0x26, 0x3A, 0xB1, 0x00, 0x02, 0x94,
0x0A, 0xC6, 0x26, 0x3B, 0x5C, 0x00, 0x02, 0x90, 0x0A, 0xC6, 0x22, 0x3B, 0x02, 0xBF, 0x0A, 0xF7,
0x55, 0x00, 0x0A, 0x01, 0x00, 0xFA, 0x04, 0x05, 0x02, 0x9F, 0x0A, 0x98, 0x1F, 0x5F, 0x02, 0xBF,
0x0A, 0xF7, 0x00, 0xFA, 0x03, 0x62, 0x81, 0x00, 0x26, 0x3A, 0x24, 0x3B, 0x15, 0x70, 0x0A, 0x01,
0x00, 0x81, 0x04, 0x05, 0x5C, 0x00, 0xB1, 0x00, 0x02, 0x75, 0x1A, 0x3A, 0x2E, 0x3A, 0x2C, 0x3B,
0x26, 0x38, 0x24, 0x39, 0x00, 0xD8, 0x03, 0x62, 0x70, 0x00, 0x2C, 0x39, 0x2E, 0x38, 0x00, 0x92,
0x00, 0xFF, 0x02, 0x9F, 0x03, 0x23, 0x81, 0x00, 0x2E, 0x34, 0x2E, 0x35, 0x23, 0x34, 0x21, 0x35,
0x26, 0x8A, 0x24, 0x8B, 0x5A, 0x00, 0x2E, 0x3A, 0x2C, 0x3B, 0x26, 0x34, 0x24, 0x35, 0x23, 0x8C,
0x21, 0x8D, 0x4A, 0x00, 0x2E, 0x38, 0x2C, 0x39, 0x81, 0x00, 0x2E, 0x05, 0x02, 0xDF, 0x00, 0x80,
0xFF, 0xD3, 0x00, 0x84, 0x00, 0x00, 0x00, 0x7A, 0x0A, 0xFF, 0x19, 0x9E, 0x14, 0x88, 0x1B, 0x7E,
0x02, 0xDF, 0x00, 0x92, 0x00, 0x04, 0x20, 0x02, 0x81, 0x00, 0x89, 0x00, 0x24, 0x30, 0x8D, 0x00,
0x09, 0x50, 0xA0, 0x00, 0xA4, 0x00, 0x14, 0x04, 0x8C, 0x00, 0x1F, 0xFE, 0x00, 0x83, 0x05, 0x80,
0x22, 0x01, 0x86, 0x00, 0x02, 0x94, 0x0B, 0x23, 0x22, 0x04, 0x86, 0x00, 0x02, 0xB4, 0x0B, 0x6C,
0x81, 0x00, 0x26, 0x05, 0xB1, 0x00, 0x02, 0x95, 0x0B, 0x30, 0x81, 0x00, 0x2E, 0x05, 0x22, 0x81,
0x86, 0x00, 0x02, 0x94, 0x0B, 0x2A, 0x81, 0x00, 0x00, 0x5F, 0x1B, 0x7E, 0x74, 0x00, 0x2E, 0x01,
0x02, 0x9F, 0x0B, 0x65, 0x26, 0x88, 0x24, 0x89, 0x2E, 0x34, 0x2C, 0x35, 0x02, 0xBF, 0x0B, 0x6C,
0x00, 0xFF, 0x03, 0x60, 0x26, 0x38, 0x24, 0x39, 0x0F, 0x06, 0x02, 0xBF, 0x06, 0x9A, 0x00, 0xDF,
0x03, 0x60, 0x81, 0x00, 0x26, 0x3A, 0xB1, 0x00, 0x02, 0x94, 0x0B, 0x4B, 0x26, 0x3B, 0x5C, 0x00,
0x02, 0x90, 0x0B, 0x4B, 0x22, 0x3B, 0x02, 0xBF, 0x0B, 0x7E, 0x55, 0x00, 0x0A, 0x01, 0x00, 0xFA,
0x04, 0x05, 0x02, 0x9F, 0x0B, 0x1D, 0x1F, 0x5F, 0x02, 0xBF, 0x0B, 0x7E, 0x00, 0xFA, 0x03, 0x62,
0x81, 0x00, 0x26, 0x3A, 0x24, 0x3B, 0x15, 0x70, 0x0A, 0x01, 0x00, 0x81, 0x04, 0x05, 0x5C, 0x00,
0xB1, 0x00, 0x02, 0x75, 0x1A, 0x3A, 0x2E, 0x3A, 0x2C, 0x3B, 0x26, 0x38, 0x24, 0x39, 0x00, 0xD8,
0x03, 0x62, 0x70, 0x00, 0x70, 0x00, 0x2C, 0x39, 0x2E, 0x38, 0x00, 0x92, 0x00, 0xFF, 0x02, 0x9F,
0x03, 0x23, 0x81, 0x00, 0x2E, 0x34, 0x2E, 0x35, 0x23, 0x34, 0x21, 0x35, 0x26, 0x8A, 0x24, 0x8B,
0x5A, 0x00, 0x2E, 0x3A, 0x2C, 0x3B, 0x26, 0x34, 0x24, 0x35, 0x14, 0x01, 0x23, 0x8C, 0x21, 0x8D,
0x4A, 0x00, 0x2E, 0x38, 0x2C, 0x39, 0x81, 0x00, 0x2E, 0x05, 0x02, 0xDF, 0x00, 0x80, 0xFF, 0xD3,
0x00, 0x84, 0x00, 0x00, 0x00, 0x7A, 0x0B, 0x85, 0x19, 0x9E, 0x1B, 0x7E, 0x02, 0xDF, 0x89, 0x00,
0x0F, 0x50, 0x00, 0x83, 0x05, 0x20, 0x02, 0xBF, 0x0B, 0xA0, 0x02, 0x9F, 0x03, 0x2B, 0x00, 0xD8,
0x04, 0x02, 0x81, 0x00, 0x89, 0x00, 0x00, 0xDC, 0x04, 0x30, 0x0A, 0x50, 0x90, 0x00, 0x94, 0x00,
0x14, 0x04, 0x1F, 0xFE, 0x00, 0x83, 0x05, 0x80, 0x02, 0xBF, 0x0B, 0xA0, 0x02, 0x9F, 0x03, 0x23,
0x00, 0x92, 0x00, 0x04, 0x81, 0x00, 0x26, 0x3A, 0x24, 0x3B, 0x1F, 0x1F, 0x0A, 0x00, 0x58, 0x00,
0x02, 0x92, 0x0B, 0xBE, 0x89, 0x00, 0x00, 0xC0, 0x04, 0x3B, 0x02, 0xBF, 0x0B, 0xE3, 0x81, 0x00,
0x1F, 0xD8, 0x22, 0x3B, 0x54, 0x00, 0x00, 0x07, 0x19, 0x79, 0x00, 0x5E, 0x1B, 0x79, 0x0F, 0x01,
0x2F, 0x01, 0x89, 0x00, 0x2F, 0x3B, 0x00, 0x92, 0x00, 0xFF, 0x02, 0xDF, 0x2E, 0x3A, 0x2C, 0x3B,
0x81, 0x00, 0x89, 0x00, 0x26, 0x8A, 0x27, 0x34, 0x5C, 0x00, 0x2E, 0x36, 0x50, 0x00, 0x02, 0x90,
0x0B, 0xDD, 0x00, 0xC0, 0x04, 0x36, 0x02, 0xBF, 0x0B, 0xE3, 0x81, 0x00, 0x1F, 0xD8, 0x22, 0x36,
0x54, 0x00, 0x1C, 0x1E, 0x81, 0x00, 0x2E, 0x34, 0x26, 0x88, 0x24, 0x89, 0x2E, 0x8C, 0x2C, 0x8D,
0x02, 0xBF, 0x0B, 0xE3, 0x00, 0x92, 0x00, 0xFF, 0x02, 0xDF, 0x1C, 0x18, 0x02, 0xBF, 0x0B, 0xE3,
0x00, 0x92, 0x00, 0xFF, 0x02, 0xDF, 0x81, 0x00, 0x1F, 0xC0, 0xB1, 0x00, 0x02, 0xD5, 0x89, 0x00,
0x27, 0x34, 0x03, 0x40, 0x00, 0x01, 0x0B, 0x00, 0x1F, 0x3F, 0x26, 0x8C, 0x24, 0x8D, 0x89, 0x00,
0x25, 0x34, 0x15, 0x01, 0x4C, 0x00, 0x5A, 0x00, 0x5A, 0x00, 0x1C, 0x20, 0x1F, 0xE0, 0x05, 0x02,
0x1C, 0x1F, 0x00, 0x9F, 0x0B, 0x00, 0x00, 0x92, 0x00, 0xFF, 0x02, 0xBF, 0x06, 0x12, 0x00, 0x92,
0x00, 0x04, 0x27, 0x34, 0x1F, 0x61, 0x47, 0x00, 0x2F, 0x34, 0x00, 0x80, 0x0B, 0x00, 0x89, 0x00,
0x1F, 0xF9, 0xB9, 0x00, 0x02, 0x74, 0x00, 0x08, 0x89, 0x00, 0x1F, 0xE1, 0x19, 0x1E, 0x07, 0x01,
0x02, 0x93, 0x0C, 0x19, 0x19, 0x1A, 0x05, 0xFE, 0x00, 0x5F, 0x64, 0xA0, 0x1B, 0x7E, 0x1B, 0x7A,
0x02, 0xDF, 0x1B, 0x7E, 0x02, 0xDF, 0x00, 0x83, 0x03, 0xE8, 0x19, 0x1E, 0x19, 0x1A, 0x10, 0x06,
0x64, 0xA0, 0x1B, 0x7E, 0x1B, 0x7A, 0x00, 0x80, 0x03, 0xE8, 0x8A, 0x00, 0x00, 0x88, 0x00, 0x07,
0x11, 0x50, 0x0C, 0x35, 0x1C, 0x61, 0x84, 0xC3, 0xF2, 0xC3, 0xF2, 0xC3, 0xF2, 0xC3, 0xF2, 0xC3,
0xF2, 0xC3, 0xF2, 0xC3, 0xF2, 0xC3, 0xF2, 0x00, 0xFE, 0x00, 0x1B, 0x3E, 0x00, 0x88, 0xFF, 0xFF,
0x8B, 0x00, 0x02, 0xDF, 0x8A, 0x00, 0x05, 0xFE, 0x00, 0x83, 0x03, 0xE8, 0x19, 0x1E, 0x19, 0x1A,
0x00, 0x5F, 0x64, 0xA0, 0x1B, 0x7E, 0x1B, 0x7A, 0x00, 0x80, 0x03, 0xE8, 0x05, 0x01, 0x1D, 0x1F,
0x11, 0x50, 0x0C, 0x50, 0x1C, 0x61, 0x84, 0xC3, 0x00, 0x5F, 0xF2, 0xC3, 0xF2, 0x00, 0xFE, 0x00,
0x1B, 0x3E, 0x00, 0x88, 0xFF, 0xFF, 0x8B, 0x00, 0x02, 0xDF, 0x00, 0x83, 0x03, 0xE8, 0x19, 0x1E,
0x19, 0x1A, 0x64, 0xA0, 0x64, 0xA0, 0x1B, 0x7E, 0x1B, 0x7A, 0x00, 0x80, 0x03, 0xE8, 0x00, 0x88,
0x00, 0x03, 0x00, 0x85, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x1F, 0xC2, 0x19, 0x5B, 0x19, 0x59,
0x19, 0x5F, 0x19, 0x5A, 0x1C, 0x5E, 0x1F, 0xDA, 0x1C, 0x61, 0x8A, 0x00, 0x8F, 0x00, 0x19, 0x1A,
0xB8, 0x50, 0xE2, 0x50, 0xEA, 0x50, 0xE8, 0xE8, 0xB6, 0x50, 0x11, 0x27, 0x0C, 0x80, 0xE3, 0xA8,
0x19, 0x7E, 0xE8, 0x50, 0xEA, 0xF8, 0xBF, 0x50, 0xE2, 0xA9, 0x19, 0x7F, 0xEA, 0x50, 0xE8, 0xE8,
0xB6, 0x50, 0xE3, 0xA8, 0x19, 0x7E, 0xE8, 0x50, 0xEA, 0xF8, 0xBF, 0x00, 0x1B, 0xFF, 0x19, 0x7F,
0x8E, 0x00, 0x8B, 0x00, 0x00, 0x88, 0xFF, 0xFF, 0x1B, 0x5B, 0x1B, 0x59, 0x1B, 0x5F, 0x1B, 0x5E,
0x02, 0xDF, 0x00, 0x83, 0x03, 0xE8, 0x19, 0x1E, 0x19, 0x1A, 0x64, 0xA0, 0x64, 0xA0, 0x1B, 0x7E,
0x1B, 0x7A, 0x00, 0x80, 0x03, 0xE8, 0x00, 0x88, 0x00, 0x03, 0x00, 0x85, 0x00, 0x00, 0x00, 0x87,
0x00, 0x00, 0x1F, 0xC2, 0x19, 0x5B, 0x19, 0x59, 0x19, 0x5F, 0x19, 0x5A, 0x1C, 0x5E, 0x1F, 0xDA,
0x1C, 0x61, 0x8A, 0x00, 0x8F, 0x00, 0x19, 0x1A, 0xB8, 0x00, 0xE3, 0x50, 0xE2, 0x50, 0xEA, 0x00,
0xEA, 0x50, 0xE8, 0x77, 0xEC, 0xE8, 0xB2, 0x00, 0x11, 0x27, 0x0C, 0xC5, 0xE2, 0x50, 0xE3, 0xA8,
0x19, 0x7E, 0xE8, 0x00, 0xE8, 0x50, 0xEA, 0x7F, 0xEE, 0xF8, 0xBB, 0x00, 0xE3, 0x50, 0xE2, 0xA9,
0x19, 0x7F, 0xEA, 0x00, 0xEA, 0x50, 0xE8, 0x77, 0xEC, 0xE8, 0xB2, 0x00, 0xE2, 0x50, 0xE3, 0xA8,
0x19, 0x7E, 0xE8, 0x00, 0xE8, 0x50, 0xEA, 0x7F, 0xEE, 0xF8, 0xBB, 0x00, 0x1B, 0xFF, 0x19, 0x7F,
0x8E, 0x00, 0x8B, 0x00, 0x00, 0x88, 0xFF, 0xFF, 0x1B, 0x5B, 0x1B, 0x59, 0x1B, 0x5F, 0x1B, 0x5E,
0x02, 0xDF, 0x0E, 0xFF, 0x00, 0xFE, 0x03, 0xF2, 0x81, 0x00, 0x00, 0xFE, 0x03, 0xF0, 0x00, 0xFE,
0x03, 0xF6, 0x00, 0x9E, 0x01, 0x00, 0x00, 0xFE, 0x03, 0xF7, 0x00, 0xDA, 0x03, 0xF7, 0x00, 0x9E,
0x80, 0x00, 0x54, 0x00, 0x00, 0xFE, 0x03, 0xF5, 0x0E, 0x30, 0x00, 0xFE, 0x03, 0xF3, 0x0E, 0x10,
0x00, 0xFE, 0x03, 0xF4, 0x00, 0x9E, 0x00, 0x96, 0x00, 0xFE, 0x03, 0xF1, 0x02, 0xDF, 0x00, 0x80,
0x0A, 0x00, 0x81, 0x00, 0x00, 0xDE, 0x03, 0xF0, 0x89, 0x00, 0xB1, 0x00, 0x02, 0x75, 0x05, 0x50,
0x00, 0xFF, 0x03, 0xF0, 0x02, 0x00, 0x0A, 0x60, 0x1C, 0x7E, 0x0F, 0x4E, 0x02, 0xBF, 0x00, 0xDA,
0x02, 0xDF, 0x00, 0xDE, 0x03, 0xF1, 0x02, 0x00, 0x0A, 0x60, 0x1C, 0x7E, 0x81, 0x00, 0x89, 0x00,
0x00, 0x9F, 0x00, 0xA0, 0x00, 0xDE, 0x03, 0xF1, 0x5D, 0x00, 0x0E, 0x50, 0x07, 0x50, 0x02, 0x70,
0x5D, 0x00, 0x00, 0xDA, 0x03, 0xF2, 0x86, 0x00, 0x02, 0x90, 0x0D, 0x3A, 0x00, 0xDE, 0x03, 0xF3,
0x5C, 0x00, 0x02, 0x93, 0x0D, 0x25, 0x02, 0x9F, 0x0D, 0x3F, 0x00, 0xDB, 0x03, 0xF7, 0x00, 0x9E,
0x80, 0x00, 0x46, 0x00, 0x02, 0x9F, 0x0D, 0x31, 0x00, 0xDB, 0x03, 0xF7, 0x00, 0x9E, 0x80, 0x00,
0x56, 0x00, 0x00, 0xFE, 0x03, 0xF5, 0x1F, 0xDA, 0x7C, 0x00, 0x1F, 0x5E, 0x00, 0xFE, 0x03, 0xF2,
0x02, 0x9F, 0x0D, 0x3F, 0x00, 0xDE, 0x03, 0xF4, 0x5D, 0x00, 0x02, 0x93, 0x0D, 0x2C, 0x89, 0x00,
0x00, 0xDD, 0x03, 0xF5, 0x15, 0x01, 0x81, 0x00, 0x00, 0xDC, 0x03, 0xF6, 0x00, 0x8B, 0x00, 0x9F,
0x00, 0x80, 0x0A, 0x00, 0x09, 0x00, 0x11, 0x50, 0x0D, 0x52, 0x18, 0x78, 0x4C, 0x00, 0x1C, 0xFE,
0x00, 0x1F, 0x1F, 0xD9, 0x1B, 0x18, 0x00, 0x9F, 0x0A, 0x60, 0x1F, 0xC3, 0x5C, 0x00, 0x00, 0xFE,
0x03, 0xF1, 0x00, 0xFC, 0x03, 0xF6, 0x00, 0x8B, 0xFF, 0xFF, 0x02, 0xDF, 0x0F, 0x50, 0x00, 0x80,
0x0A, 0x00, 0x00, 0x83, 0x0D, 0x60, 0x00, 0x98, 0x3F, 0xFF, 0x02, 0xBF, 0x00, 0xF4, 0x0F, 0x50,
0x00, 0x80, 0x0A, 0x00, 0x00, 0x83, 0x0D, 0x00, 0x00, 0x98, 0x3F, 0xFF, 0x02, 0xBF, 0x00, 0xF4,
0x02, 0xDF, 0x8A, 0x00, 0x8F, 0x00, 0x81, 0x00, 0x00, 0xDE, 0x04, 0x04, 0xB1, 0x00, 0x02, 0x95,
0x0D, 0x7E, 0x81, 0x00, 0x00, 0xFE, 0x04, 0x78, 0x00, 0xFE, 0x04, 0x79, 0x00, 0xDF, 0x04, 0x79,
0x00, 0xDB, 0x04, 0x78, 0x09, 0x00, 0x00, 0x84, 0x00, 0x00, 0x11, 0x50, 0x0D, 0x8E, 0x19, 0x9E,
0x5C, 0x7C, 0xC0, 0x00, 0x6E, 0x00, 0x14, 0x88, 0x4A, 0x00, 0x1B, 0x1E, 0x1F, 0x7E, 0x00, 0xFB,
0x04, 0x78, 0x00, 0xFF, 0x04, 0x79, 0x8B, 0x00, 0x8E, 0x00, 0x02, 0xDF, 0xB9, 0x00, 0x02, 0x94,
0x0D, 0x9C, 0x68, 0x00, 0xB1, 0x00, 0x02, 0xD5, 0x1C, 0x23, 0x19, 0x7E, 0x19, 0x1B, 0xD8, 0x58,
0x11, 0x20, 0x0D, 0xA6, 0xDC, 0xD3, 0x62, 0x31, 0xDC, 0xD3, 0x62, 0x31, 0x49, 0x00, 0x11, 0x08,
0x0D, 0xAC, 0xDC, 0xD3, 0x62, 0x31, 0xDC, 0xD3, 0x62, 0x31, 0x02, 0xDF, 0x8F, 0x00, 0x8D, 0x00,
0x1C, 0x03, 0x00, 0xD9, 0x03, 0x8E, 0x0B, 0x04, 0x19, 0x7A, 0xB0, 0x53, 0xB6, 0x00, 0x11, 0x28,
0x0D, 0xBC, 0x3A, 0xD3, 0xB6, 0x30, 0x3A, 0xD3, 0xB6, 0x30, 0x8C, 0x00, 0x8E, 0x00, 0x02, 0xDF,
0x00, 0xDA, 0x04, 0x85, 0x86, 0x00, 0x02, 0x95, 0x0D, 0xD2, 0x81, 0x00, 0x00, 0xDE, 0x04, 0x2A,
0x14, 0x7F, 0x00, 0xFE, 0x04, 0x2B, 0xB1, 0x00, 0x02, 0x94, 0x0D, 0xD2, 0x00, 0x9A, 0x00, 0x01,
0x00, 0xFA, 0x04, 0x01, 0x8F, 0x00, 0x81, 0x00, 0x00, 0xDE, 0x04, 0x28, 0x14, 0x78, 0x00, 0xDF,
0x04, 0x28, 0x03, 0x40, 0x00, 0x7F, 0x1F, 0x1E, 0x1F, 0x5F, 0x02, 0x20, 0x00, 0x7F, 0x1F, 0x3E,
0x03, 0x20, 0x00, 0x7F, 0x1F, 0x7F, 0x81, 0x00, 0x89, 0x00, 0x00, 0x9F, 0x02, 0x00, 0x1F, 0xD8,
0x4C, 0x00, 0x1C, 0x1E, 0x18, 0x18, 0x1F, 0xDA, 0x4C, 0x00, 0x1C, 0x1E, 0x18, 0x1A, 0x1F, 0xD9,
0x4C, 0x00, 0x1C, 0x1E, 0x18, 0x19, 0x1F, 0xDB, 0x4C, 0x00, 0x1C, 0x1E, 0x18, 0x1B, 0x8A, 0x00,
0x00, 0x80, 0x0B, 0x00, 0x98, 0x00, 0xAE, 0x00, 0xB6, 0x30, 0x96, 0x30, 0x6E, 0x30, 0x1B, 0x1E,
0x8B, 0x00, 0x00, 0x80, 0x0B, 0x00, 0x00, 0x81, 0x0B, 0x04, 0x00, 0xDA, 0x04, 0x2A, 0x02, 0xBF,
0x0E, 0x52, 0x00, 0x81, 0x0B, 0x08, 0x00, 0x80, 0x0B, 0x00, 0x00, 0xDA, 0x04, 0x2A, 0x00, 0xDE,
0x04, 0x29, 0x8A, 0x00, 0xC0, 0x00, 0x8B, 0x00, 0x6E, 0x00, 0x1F, 0x5E, 0x02, 0xBF, 0x0E, 0x52,
0x00, 0x80, 0x0B, 0x00, 0x00, 0x81, 0x0B, 0x0C, 0x81, 0x00, 0x89, 0x00, 0x00, 0xDE, 0x04, 0x2B,
0x00, 0xDF, 0x04, 0x2A, 0x00, 0xFE, 0x04, 0x2A, 0x5C, 0x00, 0x1F, 0x5E, 0x02, 0xBF, 0x0E, 0x5D,
0x00, 0x80, 0x0B, 0x0C, 0x00, 0x81, 0x0B, 0x10, 0x00, 0xDA, 0x04, 0x29, 0x02, 0xBF, 0x0E, 0x52,
0x00, 0x81, 0x0B, 0x04, 0x00, 0x82, 0x0B, 0x0C, 0x00, 0x83, 0x0E, 0x6B, 0x11, 0x08, 0x0E, 0x4F,
0x19, 0x5F, 0x15, 0xFB, 0x1F, 0x1D, 0x1F, 0x5F, 0x19, 0x3F, 0x00, 0xE1, 0x0B, 0x24, 0x00, 0xE2,
0x0B, 0x25, 0x02, 0x1B, 0x00, 0xE3, 0x0B, 0x26, 0x1C, 0x7E, 0x00, 0xC0, 0x03, 0x8F, 0x02, 0xBF,
0x0D, 0x96, 0x00, 0xC1, 0x0B, 0x24, 0x00, 0xC2, 0x0B, 0x25, 0x00, 0xC3, 0x0B, 0x26, 0x00, 0x00,
0x8E, 0x00, 0x02, 0xDF, 0x8A, 0x00, 0x19, 0x1F, 0xD0, 0x78, 0xD6, 0x78, 0xD6, 0x31, 0x19, 0x1F,
0xD6, 0x31, 0x6E, 0x31, 0x1B, 0x3E, 0x8B, 0x00, 0x02, 0xDF, 0x8A, 0x00, 0x8D, 0x00, 0x1F, 0x7E,
0x19, 0x18, 0xA8, 0x40, 0xAE, 0x40, 0xAE, 0x31, 0x19, 0x18, 0xAE, 0x31, 0x6E, 0x31, 0x1B, 0x3E,
0x8C, 0x00, 0x8B, 0x00, 0x02, 0xDF, 0x0D, 0x00, 0x0D, 0x60, 0x0F, 0x40, 0x0C, 0xA0, 0x0E, 0x80,
0x0E, 0xE0, 0x0B, 0xE0, 0x0C, 0x40, 0x00, 0xF9, 0x03, 0x61, 0x1F, 0xC0, 0x02, 0x00, 0xFF, 0xFC,
0x1C, 0x1E, 0x1C, 0x5E, 0x00, 0x83, 0x04, 0x3C, 0x19, 0x7E, 0x19, 0x7F, 0x80, 0xA2, 0x64, 0xA3,
0x65, 0x30, 0x1B, 0x1F, 0x1C, 0x02, 0x81, 0x00, 0x00, 0xDE, 0x04, 0x02, 0x00, 0xFE, 0x03, 0x62,
0x14, 0x74, 0x1F, 0x7E, 0x1F, 0x3C, 0x89, 0x00, 0x00, 0xDD, 0x04, 0x30, 0x15, 0x04, 0x06, 0x04,
0x02, 0x90, 0x0E, 0xE7, 0x1F, 0xDD, 0x00, 0x82, 0x02, 0xB0, 0x10, 0x50, 0x4B, 0x2A, 0x1F, 0xBE,
0x00, 0xFE, 0x03, 0x60, 0x89, 0x00, 0x1F, 0xBE, 0x0A, 0xF8, 0x00, 0x9B, 0x00, 0xFC, 0x00, 0xD8,
0x03, 0x61, 0x00, 0x82, 0x02, 0xB0, 0x00, 0x83, 0x02, 0xB0, 0x19, 0x5E, 0x34, 0x80, 0x11, 0x28,
0x0E, 0xAC, 0x36, 0x7A, 0x35, 0xB3, 0x37, 0x72, 0x34, 0xBB, 0x8A, 0x00, 0x00, 0x82, 0x02, 0xB0,
0x00, 0xDD, 0x04, 0x30, 0x15, 0x04, 0x1F, 0xE0, 0x81, 0x00, 0x00, 0xDE, 0x03, 0x62, 0x14, 0x74,
0x1F, 0x7E, 0x1F, 0x3C, 0x8F, 0x00, 0x19, 0x43, 0x4B, 0xC3, 0x90, 0xC3, 0xF2, 0xC3, 0xF2, 0xC3,
0xF2, 0x00, 0xFE, 0x00, 0x1C, 0x1F, 0x19, 0x43, 0x4B, 0xC3, 0x90, 0xC3, 0x11, 0x4E, 0x0E, 0xCE,
0xF2, 0xC3, 0xF2, 0xC3, 0xF2, 0x31, 0x1C, 0x1F, 0x19, 0x43, 0x4B, 0xC3, 0x92, 0xC3, 0xF2, 0xC3,
0xF2, 0xC3, 0xF2, 0x31, 0xFE, 0x00, 0x1B, 0x3E, 0x8B, 0x00, 0x8E, 0x00, 0x00, 0xFE, 0x04, 0x33,
0x1C, 0x1F, 0x15, 0x0C, 0x03, 0x40, 0x0F, 0xFF, 0x00, 0xFF, 0x04, 0x30, 0x00, 0x83, 0x04, 0x3C,
0x19, 0x1E, 0x19, 0x1F, 0x80, 0xA0, 0x64, 0xA1, 0x65, 0x33, 0x1B, 0x7F, 0x02, 0xDF, 0x1F, 0xE0,
0x1C, 0x1F, 0x11, 0x28, 0x0E, 0xF0, 0x4B, 0x70, 0x1B, 0x3E, 0x1C, 0x1F, 0x4B, 0x70, 0x1B, 0x3E,
0x1C, 0x1F, 0x02, 0x9F, 0x0E, 0xD6, 0x00, 0x83, 0x05, 0x20, 0x00, 0xDE, 0x04, 0x33, 0x10, 0x50,
0x1B, 0x7E, 0x02, 0x9F, 0x03, 0x2B, 0x1C, 0x20, 0x18, 0x5F, 0x1F, 0x7F, 0x19, 0x3A, 0x64, 0x00,
0x00, 0x78, 0x0F, 0x05, 0x56, 0x59, 0x67, 0x30, 0x55, 0x51, 0x64, 0x38, 0x1A, 0x5B, 0x02, 0xDF,
0x00, 0x98, 0x82, 0x40, 0x00, 0xF8, 0x04, 0xE8, 0x00, 0x98, 0x7F, 0xFF, 0x00, 0xF8, 0x04, 0xE9,
0x00, 0x98, 0x7D, 0xBF, 0x00, 0xF8, 0x04, 0xEA, 0x00, 0x98, 0x84, 0x3F, 0x00, 0xF8, 0x04, 0xEB,
0x00, 0x98, 0xB2, 0x3B, 0x00, 0xF8, 0x04, 0xF0, 0x00, 0x98, 0x7F, 0xFF, 0x00, 0xF8, 0x04, 0xF1,
0x00, 0x98, 0x4D, 0xC4, 0x00, 0xF8, 0x04, 0xF2, 0x00, 0x98, 0xD8, 0x08, 0x00, 0xF8, 0x04, 0xF3,
0x00, 0x98, 0x00, 0x00, 0x00, 0x80, 0x04, 0xEC, 0x10, 0x04, 0x1B, 0x18, 0x00, 0x80, 0x04, 0xF4,
0x10, 0x04, 0x1B, 0x18, 0x02, 0xDF, 0x00, 0x80, 0x0F, 0x40, 0x00, 0x83, 0x0B, 0x00, 0x89, 0x00,
0x0F, 0x50, 0x00, 0x98, 0x67, 0x84, 0x02, 0xBF, 0x01, 0x03, 0x00, 0x80, 0x04, 0xE8, 0x00, 0x82,
0x04, 0xEC, 0x00, 0x81, 0x0B, 0x00, 0x89, 0x00, 0x0F, 0x50, 0x00, 0x80, 0x0B, 0x00, 0x00, 0x83,
0x0D, 0x00, 0x00, 0x98, 0x7F, 0xFF, 0x02, 0xBF, 0x00, 0xF4, 0x89, 0x00, 0x0F, 0x50, 0x00, 0x80,
0x0B, 0x00, 0x00, 0x83, 0x0D, 0x60, 0x00, 0x98, 0xB8, 0x20, 0x02, 0xBF, 0x00, 0xF4, 0x00, 0x80,
0x0C, 0xA0, 0x00, 0x83, 0x0B, 0x00, 0x89, 0x00, 0x0F, 0x50, 0x00, 0x98, 0x67, 0x84, 0x02, 0xBF,
0x01, 0x03, 0x00, 0x80, 0x04, 0xE8, 0x00, 0x82, 0x04, 0xF4, 0x00, 0x81, 0x0B, 0x00, 0x89, 0x00,
0x0F, 0x50, 0x00, 0x80, 0x0B, 0x00, 0x00, 0x83, 0x0D, 0x00, 0x00, 0x98, 0x47, 0xE0, 0x02, 0xBF,
0x00, 0xF4, 0x89, 0x00, 0x0F, 0x50, 0x00, 0x80, 0x0B, 0x00, 0x00, 0x83, 0x0D, 0x60, 0x00, 0x98,
0x80, 0x01, 0x02, 0xBF, 0x00, 0xF4, 0x02, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static DSPTaskInfo audio_task ATTRIBUTE_ALIGN(32);
static u8 AUDIO_YIELD_BUFFER[8192] ATTRIBUTE_ALIGN(32);
void DspBoot(void (*param_0)(void*)) {
DspInitWork();
OS_REPORT("Dsp をブートします\n");
audio_task.priority = 0xf0;
audio_task.iram_mmem_addr = (u16*)(jdsp + 0x80000000);
audio_task.iram_length = sizeof(jdsp);
audio_task.iram_addr = 0;
audio_task.dram_mmem_addr = (u16*)(AUDIO_YIELD_BUFFER + 0x80000000);
audio_task.dram_length = sizeof(AUDIO_YIELD_BUFFER);
audio_task.dram_addr = 0;
audio_task.dsp_init_vector = 0;
audio_task.dsp_resume_vector = 0x10;
audio_task.init_cb = DspHandShake;
audio_task.res_cb = NULL;
audio_task.done_cb = NULL;
audio_task.req_cb = param_0;
DSPInit();
DSPAddPriorTask(&audio_task);
OS_REPORT("Dspブートしました\n");
}
int DSPSendCommands2(u32* param_1, u32 param_2, void (*callBack)(u16)) {
s32 i;
BOOL interruptFlag;
s32 startWorkStatus;
while (Dsp_Running_Check() == 0) {
OS_REPORT("Warning:まだブートしてません\n");
};
interruptFlag = OSDisableInterrupts();
if (DSPCheckMailToDSP()) {
OS_REPORT("エラー::DSPがメッセージを受け取っていません\n");
OSRestoreInterrupts(interruptFlag);
return -1;
}
DSPSendMailToDSP(param_2);
DSPAssertInt();
while (DSPCheckMailToDSP() != 0);
if (param_2 == 0) {
param_2 = 1;
}
if (callBack != NULL) {
startWorkStatus = DspStartWork(param_1[0], callBack);
}
for (i = 0; i < param_2; i++) {
DSPSendMailToDSP(param_1[i]);
while (DSPCheckMailToDSP() != 0);
}
OSRestoreInterrupts(interruptFlag);
return startWorkStatus;
}
typedef struct {
u16 field_0x0;
u16 field_0x2;
void (*field_0x4)(u16);
} TaskWorkStruct;
static TaskWorkStruct taskwork[16];
static void DspInitWork() {
for (int i = 0; i < 16; i++) {
taskwork[i].field_0x4 = NULL;
}
}
static u32 taskreadp;
static u32 taskwritep;
static int DspStartWork(u32 param_0, void (*param_1)(u16)) {
u32 taskWritePrev = taskwritep;
u32 writeVal = ((taskWritePrev + 1) & 0xf);
if (writeVal == taskreadp) {
OS_REPORT("DSP-Task Buffer is full ( %d, %d)\n", taskwritep, taskreadp);
return 0;
}
taskwritep = writeVal;
taskwork[taskWritePrev].field_0x0 = param_0 >> 0x10;
taskwork[taskWritePrev].field_0x4 = param_1;
return taskWritePrev + 1;
}
void DspFinishWork(u16 param_0) {
if (param_0 != taskwork[taskreadp].field_0x0) {
OS_REPORT("Error:: Not finish task\n");
} else {
if (taskwork[taskreadp].field_0x4) {
taskwork[taskreadp].field_0x4(taskreadp);
}
taskreadp = (taskreadp + 1) & 0xf;
}
}
+36
View File
@@ -0,0 +1,36 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/osdsp.h"
#include "JSystem/JAudio2/osdsp_task.h"
#include <os.h>
#include <dsp.h>
extern "C" void __DSP_insert_task(DSPTaskInfo*);
extern "C" void __DSP_boot_task(DSPTaskInfo*);
DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) {
if (DSP_prior_task == NULL) {
OSReport("Prior Task is not inited\n");
return NULL;
}
BOOL status = OSDisableInterrupts();
__DSP_insert_task(task);
task->state = 0;
task->flags = 1;
OSRestoreInterrupts(status);
return task;
}
void DSPAddPriorTask(STRUCT_DSP_TASK* task) {
if (DSP_prior_task != NULL) {
OSReport("Already inited prior DSP task\n");
return;
}
BOOL status = OSDisableInterrupts();
DSP_prior_task = (DSPTaskInfo*)task;
task->state = 0;
task->flags = 1;
__DSP_boot_task((DSPTaskInfo*)task);
OSRestoreInterrupts(status);
}
+160
View File
@@ -0,0 +1,160 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JAudio2/osdsp_task.h"
#include "JSystem/JAudio2/dspproc.h"
#include <dsp.h>
#include <os.h>
extern DSPTaskInfo* __DSP_first_task;
extern DSPTaskInfo* __DSP_curr_task;
extern "C" void __DSP_exec_task(DSPTaskInfo*, DSPTaskInfo*);
extern "C" void __DSP_remove_task(DSPTaskInfo* task);
static void Dsp_Update_Request();
static vu8 struct_80451308;
static u8 struct_80451309;
DSPTaskInfo* DSP_prior_task;
extern "C" void __DSPHandler(__OSInterrupt interrupt, OSContext* context) {
OSContext funcContext;
__DSPRegs[5] = ((u16)(__DSPRegs[5]) & ~0x28) | 0x80;
OSClearContext(&funcContext);
OSSetCurrentContext(&funcContext);
if (struct_80451308 == 1 || struct_80451308 == 0) {
__DSP_curr_task = DSP_prior_task;
}
while (DSPCheckMailFromDSP() == 0);
u32 mail = DSPReadMailFromDSP();
if ((__DSP_curr_task->flags & 2) && mail == 0xDCD10002) {
mail = 0xDCD10003;
}
switch (mail) {
case 0xDCD10000:
__DSP_curr_task->state = 1;
if (__DSP_curr_task == DSP_prior_task) {
struct_80451308 = 1;
}
if (__DSP_curr_task->init_cb != NULL) {
__DSP_curr_task->init_cb(__DSP_curr_task);
}
break;
case 0xDCD10001:
__DSP_curr_task->state = 1;
if (__DSP_curr_task == DSP_prior_task) {
struct_80451308 = 1;
Dsp_Update_Request();
}
if (__DSP_curr_task->res_cb != NULL) {
__DSP_curr_task->res_cb(__DSP_curr_task);
}
break;
case 0xDCD10002:
DSPSendMailToDSP(0xCDD10001);
while (DSPCheckMailToDSP() != 0);
__DSP_curr_task->state = 2;
if (__DSP_curr_task->next == NULL && struct_80451309) {
__DSP_exec_task(__DSP_curr_task, DSP_prior_task);
struct_80451309 = 0;
__DSP_curr_task = DSP_prior_task;
} else {
__DSP_exec_task(__DSP_curr_task, __DSP_curr_task->next);
__DSP_curr_task = __DSP_curr_task->next;
}
break;
case 0xDCD10003:
if (__DSP_curr_task->done_cb != NULL) {
__DSP_curr_task->done_cb(__DSP_curr_task);
}
DSPSendMailToDSP(0xCDD10001);
while (DSPCheckMailToDSP() != 0);
__DSP_curr_task->state = 3;
if (__DSP_curr_task->next == NULL) {
__DSP_exec_task(NULL, DSP_prior_task);
__DSP_remove_task(__DSP_curr_task);
__DSP_curr_task = DSP_prior_task;
} else {
__DSP_exec_task(NULL, __DSP_curr_task->next);
__DSP_curr_task = __DSP_curr_task->next;
__DSP_remove_task(__DSP_curr_task->prev);
}
break;
case 0xDCD10004:
if (__DSP_curr_task->req_cb != NULL) {
__DSP_curr_task->req_cb(__DSP_curr_task);
}
break;
case 0xDCD10005:
if (__DSP_first_task == NULL || struct_80451309) {
DSPSendMailToDSP(0xCDD10003);
while (DSPCheckMailToDSP() != 0);
struct_80451309 = 0;
__DSP_curr_task = DSP_prior_task;
Dsp_Update_Request();
} else {
struct_80451308 = 3;
DSPSendMailToDSP(0xCDD10001);
while (DSPCheckMailToDSP() != 0);
__DSP_exec_task(DSP_prior_task, __DSP_first_task);
__DSP_curr_task = __DSP_first_task;
}
break;
}
OSClearContext(&funcContext);
OSSetCurrentContext(context);
}
static u32 sync_stack[5];
void DsyncFrame2(u32 param_0, u32 param_1, u32 param_2) {
if (struct_80451308 != 1) {
sync_stack[0] = param_0;
struct_80451309 = 1;
sync_stack[1] = param_1;
sync_stack[2] = param_2;
return;
}
DsyncFrame2ch(param_0, param_1, param_2);
struct_80451309 = 0;
}
static void DsyncFrame3(u32 param_0, u32 param_1, u32 param_2, u32 param_3, u32 param_4) {
if (struct_80451308 != 1) {
sync_stack[0] = param_0;
struct_80451309 = 2;
sync_stack[1] = param_1;
sync_stack[2] = param_2;
sync_stack[3] = param_3;
sync_stack[4] = param_4;
return;
}
DsyncFrame4ch(param_0, param_1, param_2, param_3, param_4);
struct_80451309 = 0;
}
static void Dsp_Update_Request() {
switch (struct_80451309) {
case 0:
break;
case 1:
DsyncFrame2(sync_stack[0], sync_stack[1], sync_stack[2]);
break;
case 2:
DsyncFrame3(sync_stack[0], sync_stack[1], sync_stack[2], sync_stack[3], sync_stack[4]);
break;
}
}
int Dsp_Running_Check() {
return struct_80451308 == 1 ? TRUE : FALSE;
}
void Dsp_Running_Start() {
struct_80451308 = 1;
}