Implement Z2AudioCS (#3103)

This commit is contained in:
Max Roncace
2026-02-20 05:53:27 -05:00
committed by GitHub
parent 0558bde1e6
commit 803bc041c7
42 changed files with 1728 additions and 137 deletions
+37
View File
@@ -0,0 +1,37 @@
#include "Z2AudioCS/SpkData.h"
#include "JSystem/JUtility/JUTAssert.h"
SpkData::SpkData(JKRArchive* resArc) {
mResArc = resArc;
JUT_ASSERT(21, resArc);
}
void SpkData::loadTable(u16 chan) {
JUT_ASSERT(32, mResArc);
void* res = mResArc->getResource(chan);
JUT_ASSERT(35, res);
mTableMgr.setResource(res);
}
void SpkData::loadWave(u16 chan) {
JUT_ASSERT(48, mResArc);
void* res = mResArc->getResource(chan);
JUT_ASSERT(51, res);
mWaveMgr.setResource(res);
}
BOOL SpkData::isValid(void) const {
return mTableMgr.isValid() && mWaveMgr.isValid();
}
static void dummy(SpkWave* wave, SpkTable* table) {
if (wave->isValid() && table->isValid()) {
table->getParams(0);
table->getNumOfSound();
}
}
+51
View File
@@ -0,0 +1,51 @@
#include "Z2AudioCS/SpkMixingBuffer.h"
#include "Z2AudioCS/SpkSound.h"
#include "JSystem/JAudio2/JASCalc.h"
#include "JSystem/JAudio2/JASGadget.h"
#include "JSystem/JAudio2/JASHeapCtrl.h"
SpkMixingBuffer::SpkMixingBuffer(JKRHeap* heap) {
JUT_ASSERT(25, heap);
for (s32 chan = 0; chan < ARRAY_SIZE(mBuffer); chan++) {
mBuffer[chan] = new (heap, 0) s16[cSamplesPerAudioPacket];
JUT_ASSERT(29, mBuffer[chan]);
bzeroBuffer(chan);
}
}
void SpkMixingBuffer::mix(s32 chan, s16* src, s32 len, f32 weight,
s32 offset) {
JUT_ASSERT(61, chan < 4);
JUT_ASSERT(62, mBuffer[chan]);
JUT_ASSERT(63, src);
JUT_ASSERT(64, offset >= 0);
JUT_ASSERT(65, (offset+len) <= cSamplesPerAudioPacket);
for (s32 i = 0; i < len; i++) {
s32 sample = mBuffer[chan][i + offset];
s16 srcSample = src[i];
sample += (s32)(srcSample * weight);
mBuffer[chan][i + offset] = JASCalc::clamp<s16, s32>(sample);
}
}
s16* SpkMixingBuffer::getSamples(s32 chan) const {
JUT_ASSERT(97, chan < 4);
JUT_ASSERT(98, mBuffer[chan]);
return mBuffer[chan];
}
bool SpkMixingBuffer::update(s32 chan) {
bzeroBuffer(chan);
SpkSoundHolder* sound_holder = JASGlobalInstance<SpkSoundHolder>::getInstance();
JUT_ASSERT(121, sound_holder);
bool result = sound_holder->update(chan);
return result;
}
void SpkMixingBuffer::bzeroBuffer(s32 chan) {
JUT_ASSERT(143, chan < 4);
JUT_ASSERT(144, mBuffer[chan]);
JASCalc::bzero(mBuffer[chan], cSamplesPerAudioPacket * sizeof(s16));
}
+450
View File
@@ -0,0 +1,450 @@
#include "Z2AudioCS/SpkSound.h"
#include "Z2AudioCS/SpkSpeakerCtrl.h"
#include "Z2AudioCS/SpkSystem.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
#include "JSystem/JAudio2/JASHeapCtrl.h"
#define SPK_SOUND_MIX_STEP 40
enum SpkSoundState {
SpkSoundState_STARTING_e,
SpkSoundState_LOCKED_e,
SpkSoundState_UNLOCKED_e,
SpkSoundState_STOPPING_e,
SpkSoundState_DEAD_e,
};
void SpkSoundHandle::releaseSound() {
if (!mSound) {
return;
}
mSound->mHandle = NULL;
mSound = NULL;
}
SpkSoundVolume::SpkSoundVolume() {
field_0x00 = 1.0f;
field_0x04 = 0.0f;
field_0x08 = 1.0f;
field_0x0c = 0.0f;
field_0x10 = 1.0f;
field_0x14 = 1.0f;
field_0x18 = 0.0f;
mTableVolume = 1.0f;
}
void SpkSoundVolume::setRelease(s32 release) {
if (release > 0) {
field_0x04 = 1.0f / release;
} else {
field_0x04 = 1.0f;
}
field_0x00 = 1.0f;
}
void SpkSoundVolume::setFadeOut(s32 fadeOut) {
JASCriticalSection cs;
if (fadeOut > 0) {
field_0x0c = 1.0f / fadeOut;
} else {
field_0x0c = 1.0f;
}
field_0x08 = 1.0f;
}
f32 SpkSoundVolume::calc(bool& param_0) {
param_0 = false;
if (field_0x04 != 0.0f) {
field_0x00 -= field_0x04;
if (field_0x00 <= 0.0f) {
field_0x00 = 0.0f;
field_0x04 = 0.0f;
param_0 = true;
}
}
if (field_0x0c != 0.0f) {
field_0x08 -= field_0x0c;
if (field_0x08 <= 0.0f) {
field_0x08 = 0.0f;
field_0x0c = 0.0f;
param_0 = true;
}
}
if (field_0x18 != 0.0f) {
field_0x10 += field_0x18;
if (field_0x18 >= 0.0f) {
if (field_0x10 >= field_0x14) {
field_0x10 = field_0x14;
field_0x18 = 0.0f;
}
} else if (field_0x10 <= field_0x14) {
field_0x10 = field_0x14;
field_0x18 = 0.0f;
}
}
f32 result = mTableVolume * (field_0x10 * (field_0x08 * (field_0x00 * field_0x00)));
return result;
}
void SpkSoundVolume::setTableVolume(f32 vol) {
mTableVolume = vol;
}
SpkSound::SpkSound() : JSULink<SpkSound>(this),
mHandle(NULL), mSoundNum(-1), mWaveData(0), mCurPos(0),
field_0x20(0), mPriority(100), field_0x28(0), mWaveSize(0),
mWaveLoopStart(-1), mWaveLoopEnd(-1), mState(SpkSoundState_STARTING_e),
mLifeTime(-1) {
}
SpkSound::~SpkSound() {
releaseHandle();
}
void SpkSound::update(f32 param_0) {
if (!((SpkSoundState)mState != SpkSoundState_UNLOCKED_e &&
(SpkSoundState)mState != SpkSoundState_STOPPING_e)) {
SpkSystem* system = JASGlobalInstance<SpkSystem>::getInstance();
JUT_ASSERT(227, system);
SpkMixingBuffer* mixing_buffer = system->getMixingBuffer();
JUT_ASSERT(230, mixing_buffer);
bool calc_flag = false;
f32 weight = mVolume.calc(calc_flag);
if (calc_flag) {
mState = SpkSoundState_DEAD_e;
}
weight *= param_0;
if (!isLoopWave()) {
s32 len = SPK_SOUND_MIX_STEP;
if (mCurPos + len >= mWaveSize) {
len = mWaveSize - mCurPos;
}
mixing_buffer->mix(field_0x20, mWaveData + mCurPos, len, weight, 0);
mCurPos += SPK_SOUND_MIX_STEP;
if (mCurPos >= mWaveSize) {
mState = SpkSoundState_DEAD_e;
}
return;
}
s32 len = 0;
s32 processedBytes = 0;
s32 remainingBytes = SPK_SOUND_MIX_STEP;
if (mWaveLoopEnd - mCurPos >= SPK_SOUND_MIX_STEP) {
len = SPK_SOUND_MIX_STEP;
mixing_buffer->mix(field_0x20, mWaveData + mCurPos, len, weight, 0);
mCurPos += SPK_SOUND_MIX_STEP;
if (mCurPos >= mWaveLoopEnd) {
mCurPos = mWaveLoopStart;
}
} else {
while (remainingBytes > 0) {
len = mWaveLoopEnd - mCurPos;
if (len >= remainingBytes) {
len = remainingBytes;
}
remainingBytes -= len;
mixing_buffer->mix(field_0x20, mWaveData + mCurPos, len, weight,
processedBytes);
processedBytes += len;
mCurPos += len;
if (mCurPos >= mWaveLoopEnd) {
mCurPos = mWaveLoopStart;
}
}
}
}
}
void SpkSound::stop(s32 msec) {
mState = SpkSoundState_STOPPING_e;
s32 fade = convertMsecToFrames(msec);
if (fade) {
mVolume.setFadeOut(fade);
} else {
startRelease();
}
}
void SpkSound::startRelease(void) {
mVolume.setRelease(field_0x28);
}
void SpkSound::attachHandle(SpkSoundHandle* handle) {
JUT_ASSERT(338, handle);
if (isHandleAttached()) {
releaseHandle();
}
mHandle = handle;
mHandle->mSound = this;
}
bool SpkSound::isHandleAttached(void) const {
return mHandle != NULL;
}
void SpkSound::releaseHandle() {
if (!mHandle) {
return;
}
mHandle->mSound = NULL;
mHandle = NULL;
}
bool SpkSound::start(s32 param_0, s32 soundNum) {
field_0x20 = param_0;
bool setResult = setWaveData(soundNum);
if (!setResult) {
return false;
}
mState = SpkSoundState_LOCKED_e;
return true;
}
void SpkSound::kill(void) {
mState = SpkSoundState_DEAD_e;
}
bool SpkSound::isStopping(void) const {
return mState == SpkSoundState_STOPPING_e;
}
bool SpkSound::isDead(void) const {
return mState == SpkSoundState_DEAD_e;
}
bool SpkSound::isLocked(void) const {
return mState == SpkSoundState_LOCKED_e;
}
void SpkSound::unlock() {
if (mState != SpkSoundState_LOCKED_e) {
return;
}
mState = SpkSoundState_UNLOCKED_e;
}
s32 SpkSound::getLifeTime(void) {
return mLifeTime;
}
void SpkSound::setLifeTime(s32 lifeTime) {
mLifeTime = lifeTime;
}
void SpkSound::updateLifeTime() {
mLifeTime--;
}
s32 SpkSound::convertMsecToFrames(s32 msec) {
return 6 * msec / 40;
}
inline bool SpkSound::isLoopWave(void) {
return mWaveLoopStart >= 0 && mWaveLoopEnd > mWaveLoopStart;
}
bool SpkSound::setWaveData(s32 soundNum) {
SpkSystem* system = JASGlobalInstance<SpkSystem>::getInstance();
JUT_ASSERT(432, system);
SpkData* data = system->getData();
JUT_ASSERT(435, data);
if (data->isValid() == 0) {
JUT_WARN(438, "%s", "Speaker data is not valid\n");
return false;
}
SpkTable& table = data->getTableMgr();
JUT_ASSERT(444, soundNum < table.getNumOfSound());
mSoundNum = soundNum;
s32 waveNum = table.getParams(soundNum)->mWaveNum;
mPriority = table.getParams(soundNum)->field_0x02;
mVolume.setTableVolume(table.getParams(soundNum)->mVolume / 127.0f);
field_0x28 = convertMsecToFrames(table.getParams(soundNum)->mMsec);
SpkWave& wave = data->getWaveMgr();
JUT_ASSERT(457, mSoundNum < wave.getNumOfWaves());
mWaveData = wave.getWave(waveNum);
mCurPos = 0;
mWaveSize = wave.getWaveSize(waveNum) / 2;
mWaveLoopStart = wave.getLoopStartPos(waveNum);
mWaveLoopEnd = wave.getLoopEndPos(waveNum);
JUT_ASSERT(466, mWaveLoopEnd <= mWaveSize);
return true;
}
SpkSoundHolder::SpkSoundHolder() : JASGlobalInstance(true) {
mMasterVolume = 1.0f;
mConfigVolume = 10;
for (int i = 0; i < ARRAY_SIZE(mSoundVolumes); i++) {
mSoundVolumes[i] = 1.0f;
}
}
bool SpkSoundHolder::startSound(s32 chan, s32 soundNum, SpkSoundHandle* handle) {
if (!SpkSpeakerCtrl::isEnable(chan)) {
return false;
}
if (soundNum < 0) {
return false;
}
if (handle != NULL) {
if (*handle) {
if ((*handle)->isLocked()) {
(*handle)->kill();
} else {
(*handle)->stop(0);
}
}
}
SpkSound* new_sound_p = new SpkSound();
if (new_sound_p == NULL) {
JUT_WARN(520, "%s", "cannot new SpkSound\n");
return false;
}
if (handle != NULL) {
new_sound_p->attachHandle(handle);
}
bool startResult = new_sound_p->start(chan, soundNum);
if (!startResult) {
JUT_WARN(532, "%s", "cannot start SpkSound\n");
delete new_sound_p;
return false;
}
{
JASCriticalSection cs;
appendSound(chan, new_sound_p);
}
return true;
}
void SpkSoundHolder::appendSound(s32 chan, SpkSound* sound) {
mSoundList[chan].append(sound);
}
bool SpkSoundHolder::startLevelSound(s32 chan, s32 soundNum, SpkSoundHandle* handle) {
if (handle == NULL) {
JUT_WARN(558, "%s", "Spk : No Handle for Level Sound");
return false;
}
if (*handle) {
if (!(*handle)->isStopping() && !(*handle)->isDead()) {
(*handle)->setLifeTime(2);
}
return true;
} else {
bool startResult = startSound(chan, soundNum, handle);
if (!startResult) {
return false;
}
if (*handle) {
(*handle)->setLifeTime(2);
return true;
}
return false;
}
}
void SpkSoundHolder::stopAll(s32 chan, s32 msec) {
JASCriticalSection cs;
for (JSULink<SpkSound>* it = mSoundList[chan].getFirst(); it != NULL; it = it->getNext()) {
if (it->getObject() != NULL) {
it->getObject()->stop(msec);
}
}
}
bool SpkSoundHolder::update(s32 chan) {
JASCriticalSection cs;
bool ret = updateEachSound(chan);
return ret;
}
bool SpkSoundHolder::updateEachSound(s32 chan) {
bool retval = false;
f32 volume = getMasterVolume() * getConfigVolumeF32();
for (JSULink<SpkSound>* it = mSoundList[chan].getFirst(); it != NULL; it = it->getNext()) {
it->getObject()->update(volume * mSoundVolumes[chan]);
retval = true;
}
return retval;
}
void SpkSoundHolder::freeDeadSound(s32 chan) {
JSULink<SpkSound>* it = mSoundList[chan].getFirst();
while (it != NULL) {
JSULink<SpkSound>* next = it->getNext();
if (it->getObject()->isDead()) {
mSoundList[chan].remove(it);
delete it->getObject();
}
it = next;
}
}
void SpkSoundHolder::framework(void) {
JASCriticalSection cs;
for (int i = 0; i < ARRAY_SIZE(mSoundList); i++) {
for (JSULink<SpkSound>* it = mSoundList[i].getFirst(); it != NULL; it = it->getNext()) {
if (it->getObject() != NULL) {
if (it->getObject()->isLocked()) {
it->getObject()->unlock();
} else if (it->getObject()->getLifeTime() >= 0) {
it->getObject()->updateLifeTime();
if (it->getObject()->getLifeTime() <= 0) {
it->getObject()->stop(0);
it->getObject()->setLifeTime(-1);
}
}
}
}
freeDeadSound(i);
}
}
+314
View File
@@ -0,0 +1,314 @@
#include "Z2AudioCS/SpkSpeakerCtrl.h"
#include "Z2AudioCS/SpkMixingBuffer.h"
#include "Z2AudioCS/SpkSound.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
#include <revolution/os.h>
#include <revolution/wpad.h>
OSAlarm sSpeakerAlarm;
SpeakerInfo sSpeakerInfo[WPAD_MAX_CONTROLLERS];
SpkSoundHandle sAdjustSoundHandle[WPAD_MAX_CONTROLLERS];
SpkMixingBuffer* sMixingBuffer;
#if VERSION == VERSION_WII_USA_R0
#define SPKSPEAKERCTRL_SET_STATE(s) (void)0
#else
#define SPKSPEAKERCTRL_SET_STATE(s) mState = s
#endif
void SpkSpeakerCtrl::setMixingBuffer(SpkMixingBuffer* pMixingBuffer) {
JASCriticalSection cs;
sMixingBuffer = pMixingBuffer;
}
void SpkSpeakerCtrl::setup(void) {
for (s32 i = 0; i < WPAD_MAX_CONTROLLERS; i++) {
sSpeakerInfo[i].mIsConnected = false;
sSpeakerInfo[i].mIsPlaying = false;
sSpeakerInfo[i].field_0x22 = true;
sSpeakerInfo[i].mIsMuted = false;
#if VERSION != VERSION_WII_USA_R0
sSpeakerInfo[i].mState = 0;
#endif
sSpeakerInfo[i].mVolume = 64;
sSpeakerInfo[i].mRadioSensitivityTimer = 0;
sSpeakerInfo[i].mExtensionTimer = 0;
memset(sSpeakerInfo[i].mEncInfo.data, 0, sizeof(sSpeakerInfo[i].mEncInfo));
}
OSCreateAlarm(&sSpeakerAlarm);
OSSetPeriodicAlarm(&sSpeakerAlarm, OSGetTime(), OSNanosecondsToTicks(6666667), updateSpeaker);
}
void SpkSpeakerCtrl::connect(s32 chan) {
JASCriticalSection cs;
sSpeakerInfo[chan].mIsConnected = true;
sSpeakerInfo[chan].mIsPlaying = false;
#if VERSION != VERSION_WII_USA_R0
sSpeakerInfo[chan].mState = 0;
#endif
setSpeakerOn(chan);
}
void SpkSpeakerCtrl::disconnect(s32 chan) {
JASCriticalSection cs;
sSpeakerInfo[chan].mIsConnected = false;
sSpeakerInfo[chan].mIsPlaying = false;
#if VERSION != VERSION_WII_USA_R0
sSpeakerInfo[chan].mState = 0;
#endif
setSpeakerOff(chan);
}
void SpkSpeakerCtrl::setSpeakerOn(s32 chan) {
#if VERSION != VERSION_WII_USA_R0
JASCriticalSection cs;
#endif
s32 val = WPADControlSpeaker(chan, 1, setSpeakerOnCallback);
#if VERSION != VERSION_WII_USA_R0
if (val == -2) {
sSpeakerInfo[chan].mState = 1;
} else {
sSpeakerInfo[chan].mState = 0;
}
#endif
}
void SpkSpeakerCtrl::setSpeakerOnCallback(s32 chan, s32 param_1) {
#if VERSION == VERSION_WII_USA_R0
if (param_1 == 0) {
setSpeakerPlay(chan);
}
#else
JASCriticalSection cs;
if (param_1 == 0) {
sSpeakerInfo[chan].mState = 0;
setSpeakerPlay(chan);
} else {
if (param_1 == -3) {
sSpeakerInfo[chan].mState = 1;
}
}
#endif
}
void SpkSpeakerCtrl::setSpeakerPlay(s32 chan) {
#if VERSION != VERSION_WII_USA_R0
JASCriticalSection cs;
#endif
s32 val = WPADControlSpeaker(chan, 4, startPlayCallback);
#if VERSION != VERSION_WII_USA_R0
if (val == -2) {
sSpeakerInfo[chan].mState = 2;
} else {
sSpeakerInfo[chan].mState = 0;
}
#endif
}
void SpkSpeakerCtrl::startPlayCallback(s32 chan, s32 param_1) {
#if VERSION != VERSION_WII_USA_R0
JASCriticalSection cs;
#endif
if (param_1 == 0) {
sSpeakerInfo[chan].mIsPlaying = true;
sSpeakerInfo[chan].field_0x22 = true;
#if VERSION != VERSION_WII_USA_R0
sSpeakerInfo[chan].mState = 0;
#endif
memset(&sSpeakerInfo[chan].mEncInfo, 0, 0x20);
} else if (param_1 == -3) {
#if VERSION != VERSION_WII_USA_R0
sSpeakerInfo[chan].mState = 2;
#endif
}
}
void SpkSpeakerCtrl::setSpeakerOff(s32 chan) {
sSpeakerInfo[chan].mIsPlaying = false;
#if VERSION != VERSION_WII_USA_R0
sSpeakerInfo[chan].mState = 0;
#endif
WPADControlSpeaker(chan, 0, 0);
}
#if VERSION != VERSION_WII_USA_R0
void SpkSpeakerCtrl::retryConnection(s32 chan) {
switch (sSpeakerInfo[chan].mState) {
case 0:
case 3:
break;
case 1:
setSpeakerOn(chan);
break;
case 2:
setSpeakerPlay(chan);
break;
}
}
#endif
void SpkSpeakerCtrl::framework() {
for (s32 i = 0; i < WPAD_MAX_CONTROLLERS; i++) {
retryConnection(i);
}
}
void SpkSpeakerCtrl::updateSpeaker(OSAlarm*, OSContext*) {
for (s32 i = 0; i < WPAD_MAX_CONTROLLERS; i++) {
if (sMixingBuffer != NULL) {
BOOL isBusy = FALSE;
if (!checkRadioSensitivity(i)) {
isBusy = TRUE;
}
if (!updateExtensionProcess(i)) {
isBusy = TRUE;
}
if (sSpeakerInfo[i].mIsMuted) {
continue;
}
bool updateResult = sMixingBuffer->update(i);
if (isBusy) {
continue;
}
if (!sSpeakerInfo[i].mIsPlaying) {
continue;
}
if (updateResult) {
bool var_r28 = true;
if (sSpeakerInfo[i].mIsPlaying && sMixingBuffer != NULL) {
if (sSpeakerInfo[i].field_0x22) {
var_r28 = false;
sSpeakerInfo[i].field_0x22 = false;
}
u8 data[24];
WENCGetEncodeData(&sSpeakerInfo[i].mEncInfo, var_r28,
sMixingBuffer->getSamples(i), 0x28, data);
WPADSendStreamData(i, data, 0x14);
}
} else {
sSpeakerInfo[i].field_0x22 = true;
}
}
}
}
bool SpkSpeakerCtrl::isEnable(s32 chan) {
return WPADIsSpeakerEnabled(chan) &&
sSpeakerInfo[chan].mIsPlaying &&
!isSubmitPlayByRadioSensitivity(chan) &&
!isSubmitPlayByExtensionConnect(chan) &&
sMixingBuffer != NULL;
}
void SpkSpeakerCtrl::extensionProcess(s32 chan, s32 param_1) {
if (!sSpeakerInfo[chan].mIsConnected) {
return;
}
sSpeakerInfo[chan].mExtensionTimer = 49;
sSpeakerInfo[chan].field_0x22 = true;
if (param_1 == 0xFF) {
sSpeakerInfo[chan].mExtensionTimer = 50;
}
if (sSpeakerInfo[chan].mIsPlaying == 0) {
return;
}
setSpeakerOff(chan);
}
bool SpkSpeakerCtrl::updateExtensionProcess(s32 chan) {
if (sSpeakerInfo[chan].mIsConnected == 0) {
return false;
}
if (sSpeakerInfo[chan].mExtensionTimer < 50) {
if (sSpeakerInfo[chan].mExtensionTimer > 0) {
if (sSpeakerInfo[chan].mExtensionTimer == 1 && !sSpeakerInfo[chan].mIsPlaying) {
setSpeakerOn(chan);
}
sSpeakerInfo[chan].mExtensionTimer--;
} else {
sSpeakerInfo[chan].mExtensionTimer = 0;
}
}
bool retval;
if (sSpeakerInfo[chan].mExtensionTimer == 0) {
retval = true;
} else {
retval = false;
}
return retval;
}
bool SpkSpeakerCtrl::isSubmitPlayByExtensionConnect(s32 chan) {
if (sSpeakerInfo[chan].mExtensionTimer > 0) {
return true;
} else {
return false;
}
}
bool SpkSpeakerCtrl::checkRadioSensitivity(s32 chan) {
if (sSpeakerInfo[chan].mIsConnected == 0) {
return false;
}
if (WPADGetRadioSensitivity(chan) < 60) {
if (sSpeakerInfo[chan].mIsPlaying == 1) {
setSpeakerOff(chan);
}
sSpeakerInfo[chan].mRadioSensitivityTimer = 200;
sSpeakerInfo[chan].field_0x22 = true;
} else {
if (sSpeakerInfo[chan].mRadioSensitivityTimer > 0) {
if (sSpeakerInfo[chan].mRadioSensitivityTimer == 1) {
if (!sSpeakerInfo[chan].mIsPlaying) {
setSpeakerOn(chan);
}
}
sSpeakerInfo[chan].mRadioSensitivityTimer--;
} else {
sSpeakerInfo[chan].mRadioSensitivityTimer = 0;
}
}
bool retval;
if (sSpeakerInfo[chan].mRadioSensitivityTimer == 0) {
retval = true;
} else {
retval = false;
}
return retval;
}
bool SpkSpeakerCtrl::isSubmitPlayByRadioSensitivity(s32 chan) {
if (sSpeakerInfo[chan].mRadioSensitivityTimer > 0) {
return true;
} else {
return false;
}
}
+111
View File
@@ -0,0 +1,111 @@
#include "Z2AudioCS/SpkSystem.h"
#include "Z2AudioCS/SpkMixingBuffer.h"
#include "Z2AudioCS/SpkSound.h"
#include "Z2AudioCS/SpkSpeakerCtrl.h"
#include "JSystem/JAudio2/JASGadget.h"
#include "JSystem/JAudio2/JASHeapCtrl.h"
#include "JSystem/JKernel/JKRHeap.h"
template<> SpkSystem* JASGlobalInstance<SpkSystem>::sInstance;
template<> SpkSoundHolder* JASGlobalInstance<SpkSoundHolder>::sInstance;
const static s32 cConfigVolumeMax = 15;
SpkSystem::SpkSystem(JKRHeap* heap) : JASGlobalInstance(true) {
mData = NULL;
if (!heap) {
heap = JKRGetCurrentHeap();
}
mHeap = heap;
mMixingBuffer = new (heap, 0) SpkMixingBuffer(heap);
JUT_ASSERT(35, mMixingBuffer);
mSoundHolder = new (heap, 0) SpkSoundHolder();
JUT_ASSERT(38, mSoundHolder);
SpkSpeakerCtrl::setup();
SpkSpeakerCtrl::setMixingBuffer(mMixingBuffer);
}
void SpkSystem::setResource(JKRArchive* resArc, u16 param_1, u16 param_2) {
JUT_ASSERT(71, mHeap);
JUT_ASSERT(72, resArc);
mData = new (mHeap, 0) SpkData(resArc);
JUT_ASSERT(75, mData);
mData->loadTable(param_1);
mData->loadWave(param_2);
}
void SpkSystem::framework() {
JUT_ASSERT(89, mSoundHolder);
#if VERSION != VERSION_WII_USA_R0
SpkSpeakerCtrl::framework();
#endif
mSoundHolder->framework();
}
void SpkSystem::startSound(s32 chan, s32 param_1, SpkSoundHandle* handle) {
JUT_ASSERT(108, chan >= 0);
JUT_ASSERT(109, chan < 4);
JUT_ASSERT(110, mSoundHolder);
mSoundHolder->startSound(chan, param_1, handle);
}
void SpkSystem::startLevelSound(s32 chan, s32 param_1, SpkSoundHandle* handle) {
JUT_ASSERT(128, chan >= 0);
JUT_ASSERT(129, chan < 4);
JUT_ASSERT(130, mSoundHolder);
JUT_ASSERT(131, handle);
mSoundHolder->startLevelSound(chan, param_1, handle);
}
void SpkSystem::setMasterVolume(f32 vol) {
JUT_ASSERT(146, mSoundHolder);
JUT_ASSERT(147, vol >= 0.f);
JUT_ASSERT(148, vol <= 1.f);
mSoundHolder->setMasterVolume(vol);
}
f32 SpkSystem::getMasterVolume(void) {
return mSoundHolder->getMasterVolume();
}
void SpkSystem::stopAll(s32 chan, s32 msec) {
JUT_ASSERT(269, mSoundHolder);
JUT_ASSERT(270, chan < 4);
JUT_ASSERT(271, msec >= 0);
if (chan < 0) {
for (s32 i = 0; i < 4; i++) {
mSoundHolder->stopAll(i, msec);
}
} else {
mSoundHolder->stopAll(chan, msec);
}
}
void SpkSystem::setConfigVolume(s32 vol) {
JUT_ASSERT(307, mSoundHolder);
JUT_ASSERT(308, vol >= 0);
JUT_ASSERT(309, vol <= cConfigVolumeMax);
mSoundHolder->setConfigVolume(vol);
}
void SpkSystem::newSoundMemPool(s32 numOfSound) {
JUT_ASSERT(351, numOfSound >= 0);
JASPoolAllocObject<SpkSound>::newMemPool(numOfSound);
}
void SpkSystem::connect(s32 chan) {
SpkSpeakerCtrl::connect(chan);
}
void SpkSystem::disconnect(s32 chan) {
SpkSpeakerCtrl::disconnect(chan);
}
void SpkSystem::extensionProcess(s32 chan, s32 param_1) {
SpkSpeakerCtrl::extensionProcess(chan, param_1);
}
+44
View File
@@ -0,0 +1,44 @@
#include "Z2AudioCS/SpkTable.h"
SpkTable::SpkTable(void) {
mIsInitialized = false;
mNumOfSound = 0;
mEntryOffset = 0;
mDataOffsets = 0;
}
struct SpkTableHeader {
s32 resourceCount;
s32 entryOff;
s32 dataOffsetsStartOff;
BOOL isDataOffsetsInitialized;
};
void SpkTable::setResource(void* res) {
mIsInitialized = false;
s32* cursor = (s32*)res;
s32 resourceCount = *cursor++;
s32 entryOff = *cursor++;
s32 dataOffsetsStartOff = *cursor++;
s32* pIsDataOffsetsInitialized = cursor;
BOOL isDataOffsetsInitialized = *cursor++;
mNumOfSound = resourceCount;
s32 entryOffset = (s32)res + entryOff;
mEntryOffset = entryOffset;
s32* dataOffsets = (s32*)((s32)res + dataOffsetsStartOff);
if (!isDataOffsetsInitialized) {
for (s32 i = 0; i < mNumOfSound; i++) {
dataOffsets[i] += (s32)res;
}
}
s32* dataOffsetsCopy = dataOffsets;
mDataOffsets = dataOffsetsCopy;
*pIsDataOffsetsInitialized = TRUE;
mIsInitialized = true;
}
+83
View File
@@ -0,0 +1,83 @@
#include "Z2AudioCS/SpkWave.h"
#include "JSystem/JAudio2/JASCriticalSection.h"
#include "JSystem/JUtility/JUTAssert.h"
#include <revolution/os.h>
#include <revolution/types.h>
SpkWave::SpkWave(void) {
mWaveData = NULL;
}
void SpkWave::setResource(void* res) {
JUT_ASSERT(30, res);
JASCriticalSection cs;
mWaveData = res;
}
s32 SpkWave::getNumOfWaves(void) const {
if (mWaveData == NULL) {
return 0;
}
return ((s32*)mWaveData)[1];
}
s32 SpkWave::getWaveSize(s32 num) const {
JUT_ASSERT(57, num >= 0);
if (!mWaveData) {
return 0;
}
JUT_ASSERT(60, num < getNumOfWaves());
WaveData* data = getWaveData(num);
JUT_ASSERT(63, data);
return data->size;
}
u32 SpkWave::getLoopStartPos(s32 num) const {
JUT_ASSERT(76, num >= 0);
if (!mWaveData) {
return 0;
}
JUT_ASSERT(79, num < getNumOfWaves());
WaveData* data = getWaveData(num);
JUT_ASSERT(82, data);
return data->loopStartPos;
}
u32 SpkWave::getLoopEndPos(s32 num) const {
JUT_ASSERT(95, num >= 0);
if (!mWaveData) {
return 0;
}
JUT_ASSERT(98, num < getNumOfWaves());
WaveData* data = getWaveData(num);
JUT_ASSERT(101, data);
return data->loopEndPos;
}
s16* SpkWave::getWave(s32 num) const {
JUT_ASSERT(114, num >= 0);
if (!mWaveData) {
return 0;
}
JUT_ASSERT(117, num < getNumOfWaves());
WaveData* data = getWaveData(num);
JUT_ASSERT(120, data);
return data->wave;
}
WaveData* SpkWave::getWaveData(s32 num) const {
JUT_ASSERT(138, num >= 0);
JUT_ASSERT(139, mWaveData);
JUT_ASSERT(140, num < getNumOfWaves());
WaveData* data = (WaveData*)((u32)mWaveData + *(u32*)((u32)mWaveData + num * 4 + 8));
return data;
}
+162
View File
@@ -0,0 +1,162 @@
#include "Z2AudioCS/Z2AudioCS.h"
#include "Z2AudioCS/SpkSystem.h"
#include "JSystem/JKernel/JKRHeap.h"
#include <revolution/types.h>
#include <revolution/wpad.h>
#define HANDLES_MAX 0x30
static SpkSoundHandle* sSpkHandles;
static u8 l_spkVolume;
void Z2AudioCS::newSpkSoundMemPool() {
SpkSystem::newSoundMemPool(HANDLES_MAX);
}
int Z2AudioCS::init(JKRHeap* heap, JKRArchive* res, s32 param_2, s32 param_3) {
JUT_ASSERT(59, heap);
JUT_ASSERT(60, res);
SpkSystem* spkSys = new(heap, 0) SpkSystem(heap);
JUT_ASSERT(67, spkSys);
sSpkHandles = new (heap, 0) SpkSoundHandle[HANDLES_MAX];
JUT_ASSERT(71, sSpkHandles);
spkSys->setResource(res, 2, 3);
spkSys->setMasterVolume(1.0f);
spkSys->setConfigVolume(15);
}
void Z2AudioCS::update() {
if (JASGlobalInstance<SpkSystem>::getInstance() != NULL) {
JASGlobalInstance<SpkSystem>::getInstance()->framework();
}
}
void Z2AudioCS::connect(s32 chan) {
SpkSystem::connect(chan);
l_spkVolume = WPADGetSpeakerVolume();
}
void Z2AudioCS::disconnect(s32 chan) {
SpkSystem::disconnect(chan);
}
void Z2AudioCS::extensionProcess(s32 chan, s32 param_1) {
SpkSystem::extensionProcess(chan, param_1);
}
static SpkSoundHandle* getFreeSpkHandle(void) {
JUT_ASSERT(125, JASGlobalInstance<SpkSystem>::getInstance());
JUT_ASSERT(126, sSpkHandles);
SpkSoundHandle* highestPriorityHandle = NULL;
s32 highestPriority = 255;
for (s32 i = 0; i < HANDLES_MAX; i++) {
if (!sSpkHandles[i].isSoundAttached()) {
return &sSpkHandles[i];
}
if (sSpkHandles[i]->getPriority() < highestPriority) {
highestPriorityHandle = &sSpkHandles[i];
highestPriority = sSpkHandles[i]->getPriority();
}
}
return highestPriorityHandle;
}
SpkSoundHandle* Z2AudioCS::getHandleSoundID(s32 soundNum) {
JUT_ASSERT(145, JASGlobalInstance<SpkSystem>::getInstance());
JUT_ASSERT(146, sSpkHandles);
for (s32 i = 0; i < HANDLES_MAX; i++) {
if (!sSpkHandles[i].isSoundAttached()) {
continue;
}
if (sSpkHandles[i]->getSoundNum() == soundNum) {
return &sSpkHandles[i];
}
}
return NULL;
}
SpkSoundHandle* Z2AudioCS::start(s32 id, s32 chan) {
if (JASGlobalInstance<SpkSystem>::getInstance() == NULL) {
return NULL;
}
if (sSpkHandles == NULL) {
return NULL;
}
if (l_spkVolume == 0) {
return NULL;
}
OS_REPORT("[Z2AudioCS::start] id:%d ch:%d\n", id, chan);
SpkSoundHandle* handle = getFreeSpkHandle();
JUT_ASSERT(172, handle);
JASGlobalInstance<SpkSystem>::getInstance()->startSound(chan, id, handle);
return handle;
}
SpkSoundHandle* Z2AudioCS::startLevel(s32 id, s32 chan) {
if (JASGlobalInstance<SpkSystem>::getInstance() == NULL) {
return NULL;
}
if (sSpkHandles == NULL) {
return NULL;
}
if (l_spkVolume == 0) {
return NULL;
}
OS_REPORT("[Z2AudioCS::startLevel] id:%d ch:%d\n", id, chan);
SpkSoundHandle* handle = getHandleSoundID(id);
if (handle == NULL) {
handle = getFreeSpkHandle();
}
JUT_ASSERT(191, handle);
JASGlobalInstance<SpkSystem>::getInstance()->startLevelSound(chan, id, handle);
return handle;
}
s32 Z2AudioCS::getName(s32 num) {
if (JASGlobalInstance<SpkSystem>::getInstance() == NULL) {
return 0;
}
if (JASGlobalInstance<SpkSystem>::getInstance()->getData() == NULL) {
return 0;
}
return JASGlobalInstance<SpkSystem>::getInstance()->getData()->getTableMgr().getName(num);
}
s32 Z2AudioCS::getNumOfSound(void) {
if (JASGlobalInstance<SpkSystem>::getInstance() == NULL) {
return 0;
}
if (JASGlobalInstance<SpkSystem>::getInstance()->getData() == NULL) {
return 0;
}
return JASGlobalInstance<SpkSystem>::getInstance()->getData()->getTableMgr().getNumOfSound();
}
void Z2AudioCS::stopAll(s32 chan, s32 msec) {
if (JASGlobalInstance<SpkSystem>::getInstance() == NULL) {
return;
}
JASGlobalInstance<SpkSystem>::getInstance()->stopAll(chan, msec);
}
void Z2AudioCS::stop(s32 chan) {
stopAll(chan, 0);
}