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
+12 -9
View File
@@ -2,10 +2,11 @@
#define JASCALC_H
#include <dolphin/types.h>
#include <limits>
/**
* @ingroup jsystem-jaudio
*
*
*/
struct JASCalc {
static void imixcopy(const s16*, const s16*, s16*, u32);
@@ -15,15 +16,8 @@ struct JASCalc {
static void bzero(void* dest, u32 size);
static f32 pow2(f32);
// Could not make it work as inline - specialization is in JASCalc.cpp
template <typename A, typename B>
static A clamp(B x); /* {
if (std::numeric_limits<A>::min() >= x)
return std::numeric_limits<A>::min();
if (x >= std::numeric_limits<A>::max())
return std::numeric_limits<A>::max();
return x;
} */
static A clamp(B x);
static f32 clamp01(f32 i_value) {
if (i_value <= 0.0f) {
@@ -42,4 +36,13 @@ struct JASCalc {
static const s16 CUTOFF_TO_IIR_TABLE[128][4];
};
template <typename A, typename B>
A JASCalc::clamp(B x) {
if (x <= std::numeric_limits<A>::min())
return std::numeric_limits<A>::min();
if (x >= std::numeric_limits<A>::max())
return std::numeric_limits<A>::max();
return x;
}
#endif /* JASCALC_H */
+23
View File
@@ -0,0 +1,23 @@
#ifndef Z2AUDIOCS_SPKDATA_H
#define Z2AUDIOCS_SPKDATA_H
#include "Z2AudioCS/SpkTable.h"
#include "Z2AudioCS/SpkWave.h"
#include "JSystem/JKernel/JKRArchive.h"
class SpkData {
public:
SpkData(JKRArchive*);
void loadTable(u16 chan);
void loadWave(u16 chan);
BOOL isValid(void) const;
inline SpkTable& getTableMgr(void) { return mTableMgr; }
inline SpkWave& getWaveMgr(void) { return mWaveMgr; }
/* 0x00 */ SpkTable mTableMgr;
/* 0x10 */ SpkWave mWaveMgr;
/* 0x14 */ JKRArchive* mResArc;
};
#endif /* Z2AUDIOCS_SPKDATA_H */
+20
View File
@@ -0,0 +1,20 @@
#ifndef Z2AUDIOCS_SPKMIXINGBUFFER_H
#define Z2AUDIOCS_SPKMIXINGBUFFER_H
#include "JSystem/JKernel/JKRHeap.h"
static const s32 cSamplesPerAudioPacket = 40;
class SpkMixingBuffer {
public:
SpkMixingBuffer(JKRHeap* heap);
void mix(s32 chan, s16* src, s32 len, f32 weight, s32 offset);
s16* getSamples(s32 chan) const;
bool update(s32 chan);
void bzeroBuffer(s32 chan);
private:
/* 0x00 */ s16* mBuffer[4];
};
#endif /* Z2AUDIOCS_SPKMIXINGBUFFER_H */
+119
View File
@@ -0,0 +1,119 @@
#ifndef Z2AUDIOCS_SPKSOUND_H
#define Z2AUDIOCS_SPKSOUND_H
#include "Z2AudioCS/SpkTable.h"
#include "JSystem/JAudio2/JASGadget.h"
#include "JSystem/JAudio2/JASHeapCtrl.h"
#include "JSystem/JSupport/JSUList.h"
#include <revolution/types.h>
class SpkSound;
class SpkSoundHandle {
public:
SpkSoundHandle(void) : mSound(NULL) {}
~SpkSoundHandle(void) {
releaseSound();
}
void releaseSound(void);
inline bool isSoundAttached() const {
return mSound != NULL;
}
inline SpkSound* operator->(void) const {
JUT_ASSERT(62, mSound != NULL);
return mSound;
}
inline operator bool() const {
return isSoundAttached();
}
/* 0x00 */ SpkSound* mSound;
};
class SpkSoundVolume {
public:
SpkSoundVolume(void);
void setRelease(s32);
void setFadeOut(s32);
f32 calc(bool&);
void setTableVolume(f32);
/* 0x00 */ f32 field_0x00;
/* 0x04 */ f32 field_0x04;
/* 0x08 */ f32 field_0x08;
/* 0x0C */ f32 field_0x0c;
/* 0x10 */ f32 field_0x10;
/* 0x14 */ f32 field_0x14;
/* 0x18 */ f32 field_0x18;
/* 0x1C */ f32 mTableVolume;
};
class SpkSound : public JASPoolAllocObject<SpkSound>, public JSULink<SpkSound> {
public:
SpkSound(void);
~SpkSound(void);
void update(f32 vol);
void stop(s32 msec);
void startRelease(void);
bool isHandleAttached(void) const;
void attachHandle(SpkSoundHandle* handle);
void releaseHandle(void);
bool start(s32 chan, s32 soundNum);
void kill(void);
bool isStopping(void) const;
bool isDead(void) const;
bool isLocked(void) const;
void unlock(void);
s32 getLifeTime(void);
void setLifeTime(s32 lifeTime);
void updateLifeTime(void);
s32 convertMsecToFrames(s32 msec);
bool isLoopWave(void);
bool setWaveData(s32 soundNum);
inline s32 getPriority(void) const { return mPriority; }
inline void setPriority(s32 priority) { mPriority = priority; }
inline s32 getSoundNum(void) const { return mSoundNum; }
inline void setSoundNum(s32 soundNum) { mSoundNum = soundNum; }
/* 0x10 */ SpkSoundHandle* mHandle;
/* 0x14 */ s32 mSoundNum;
/* 0x18 */ s16* mWaveData;
/* 0x1C */ s32 mCurPos;
/* 0x20 */ u32 field_0x20;
/* 0x24 */ s32 mPriority;
/* 0x28 */ u32 field_0x28;
/* 0x2C */ s32 mWaveSize;
/* 0x30 */ s32 mWaveLoopStart;
/* 0x34 */ s32 mWaveLoopEnd;
/* 0x38 */ s32 mState;
/* 0x3C */ s32 mLifeTime;
/* 0x40 */ SpkSoundVolume mVolume;
};
class SpkSoundHolder : JASGlobalInstance<SpkSoundHolder> {
public:
SpkSoundHolder(void);
bool startSound(s32 chan, s32 soundNum, SpkSoundHandle* handle);
bool startLevelSound(s32 chan, s32 soundNum, SpkSoundHandle* handle);
void stopAll(s32 chan, s32 msec);
bool update(s32 chan);
bool updateEachSound(s32 chan);
void freeDeadSound(s32 chan);
void appendSound(s32 chan, SpkSound* sound);
void framework(void);
inline f32 getMasterVolume(void) const { return mMasterVolume; }
inline void setMasterVolume(f32 vol) { mMasterVolume = vol; }
inline s32 getConfigVolume(void) const { return mConfigVolume; }
inline void setConfigVolume(s32 vol) { mConfigVolume = vol; }
inline f32 getConfigVolumeF32(void) const { return (f32)mConfigVolume / 15.0f; }
/* 0x00 */ JSUList<SpkSound> mSoundList[WPAD_MAX_CONTROLLERS];
/* 0x30 */ f32 mSoundVolumes[WPAD_MAX_CONTROLLERS];
/* 0x40 */ f32 mMasterVolume;
/* 0x44 */ s32 mConfigVolume;
};
#endif /* Z2AUDIOCS_SPKSOUND_H */
+47
View File
@@ -0,0 +1,47 @@
#ifndef Z2AUDIOCS_SPKSPEAKERCTRL_H
#define Z2AUDIOCS_SPKSPEAKERCTRL_H
#include "Z2AudioCS/SpkMixingBuffer.h"
#include <revolution/os.h>
#include <revolution/types.h>
#include <revolution/wenc.h>
struct SpeakerInfo {
/* 0x00 */ bool mIsConnected;
/* 0x01 */ bool mIsPlaying;
/* 0x02 */ WENCInfo mEncInfo;
/* 0x22 */ bool field_0x22;
/* 0x23 */ bool mIsMuted;
#if VERSION != VERSION_WII_USA_R0
/* 0x24 */ s32 mState;
#endif
/* 0x28 */ s32 mRadioSensitivityTimer;
/* 0x2C */ s32 mExtensionTimer;
/* 0x30 */ u8 mVolume;
};
class SpkSpeakerCtrl {
public:
static void setMixingBuffer(SpkMixingBuffer*);
static void setup(void);
static void connect(s32 chan);
static void disconnect(s32 chan);
static void setSpeakerOn(s32 chan);
static void setSpeakerOnCallback(s32 chan, s32 param_1);
static void setSpeakerPlay(s32 chan);
static void startPlayCallback(s32 chan, s32 param_1);
static void setSpeakerOff(s32 chan);
static void retryConnection(s32 chan);
static void framework(void);
static void updateSpeaker(OSAlarm* alarm, OSContext* ctx);
static bool isEnable(s32 chan);
static void extensionProcess(s32 chan, s32 param_1);
static bool updateExtensionProcess(s32 chan);
static bool isSubmitPlayByExtensionConnect(s32 chan);
static bool checkRadioSensitivity(s32 chan);
static bool isSubmitPlayByRadioSensitivity(s32 chan);
private:
};
#endif /* Z2AUDIOCS_SPKSPEAKERCTRL_H */
+38
View File
@@ -0,0 +1,38 @@
#ifndef Z2AUDIOCS_SPKSYSTEM_H
#define Z2AUDIOCS_SPKSYSTEM_H
#include "Z2AudioCS/SpkData.h"
#include "Z2AudioCS/SpkMixingBuffer.h"
#include "Z2AudioCS/SpkSound.h"
#include "JSystem/JAudio2/JASGadget.h"
#include "JSystem/JKernel/JKRArchive.h"
#include "JSystem/JKernel/JKRHeap.h"
#include <revolution/types.h>
class SpkSystem : protected JASGlobalInstance<SpkSystem> {
public:
SpkSystem(JKRHeap* heap);
void setResource(JKRArchive* resArc, u16, u16);
void framework(void);
void startSound(s32 chan, s32 param_1, SpkSoundHandle* handle);
void startLevelSound(s32 chan, s32 param_1, SpkSoundHandle* handle);
void stopAll(s32 chan, s32 msec);
void setMasterVolume(f32 vol);
f32 getMasterVolume(void);
void setConfigVolume(s32 vol);
static void newSoundMemPool(s32 numOfSound);
static void connect(s32 chan);
static void disconnect(s32 chan);
static void extensionProcess(s32, s32);
inline SpkData* getData(void) const { return mData; }
inline SpkMixingBuffer* getMixingBuffer(void) const { return mMixingBuffer; }
private:
/* 0x00 */ JKRHeap* mHeap;
/* 0x04 */ SpkData* mData;
/* 0x08 */ SpkMixingBuffer* mMixingBuffer;
/* 0x0C */ SpkSoundHolder* mSoundHolder;
};
#endif /* Z2AUDIOCS_SPKSYSTEM_H */
+41
View File
@@ -0,0 +1,41 @@
#ifndef Z2AUDIOCS_SPKTABLE_H
#define Z2AUDIOCS_SPKTABLE_H
#include "JSystem/JUtility/JUTAssert.h"
#include <revolution/types.h>
#include <revolution/wpad.h>
struct SpkTableParams {
/* 0x00 */ u16 mWaveNum;
/* 0x02 */ u8 field_0x02;
/* 0x03 */ u8 mVolume;
/* 0x04 */ u16 mMsec;
/* 0x06 */ u8 pad_0x06[2];
};
class SpkTable {
public:
SpkTable(void);
void setResource(void* res);
inline s32 getName(s32 num) {
JUT_ASSERT(0x35, num >= 0);
JUT_ASSERT(0x36, num < mNumOfSound);
return *(mDataOffsets + num);
}
inline s32 getNumOfSound() const { return mNumOfSound; }
inline bool isValid(void) const { return mIsInitialized; }
inline SpkTableParams* getParams(s32 num) {
JUT_ASSERT(46, num >= 0);
JUT_ASSERT(47, num < mNumOfSound);
return (SpkTableParams*)mEntryOffset + num;
}
// private:
/* 0x00 */ bool mIsInitialized;
/* 0x04 */ s32 mNumOfSound;
/* 0x08 */ u32 mEntryOffset;
/* 0x0C */ s32* mDataOffsets;
};
#endif /* Z2AUDIOCS_SPKTABLE_H */
+32
View File
@@ -0,0 +1,32 @@
#ifndef Z2AUDIOCS_SPKWAVE_H
#define Z2AUDIOCS_SPKWAVE_H
#include <revolution/types.h>
struct WaveData {
s32 size;
u32 loopStartPos;
u32 loopEndPos;
s16 wave[0];
};
class SpkWave {
public:
SpkWave(void);
void setResource(void*);
s32 getNumOfWaves(void) const;
s32 getWaveSize(s32 num) const;
u32 getLoopStartPos(s32 num) const;
u32 getLoopEndPos(s32 num) const;
s16* getWave(s32 num) const;
WaveData* getWaveData(s32 num) const;
inline bool isValid(void) const { return mWaveData != NULL; }
inline const void* getResource(void) const { return mWaveData; }
inline void* getResource(void) { return mWaveData; }
private:
/* 0x00 */ void* mWaveData;
};
#endif /* Z2AUDIOCS_SPKWAVE_H */
+28
View File
@@ -0,0 +1,28 @@
#ifndef Z2AUDIOCS_H
#define Z2AUDIOCS_H
#include "Z2AudioCS/SpkTable.h"
#include "Z2AudioCS/SpkSound.h"
#include <dolphin/types.h>
class JKRHeap;
class JKRArchive;
class Z2AudioCS {
public:
static void newSpkSoundMemPool();
static int init(JKRHeap* heap, JKRArchive* res, s32 param_2, s32 param_3);
static void update();
static void connect(s32 chan);
static void disconnect(s32 chan);
static void extensionProcess(s32 chan, s32 param_1);
static SpkSoundHandle* getHandleSoundID(s32 soundNum);
static SpkSoundHandle* start(s32 id, s32 chan);
static SpkSoundHandle* startLevel(s32 id, s32 chan);
static s32 getName(s32 num);
static s32 getNumOfSound(void);
static void stopAll(s32 chan, s32 msec);
static void stop(s32 chan);
};
#endif /* Z2AUDIOCS_H */
-22
View File
@@ -1,22 +0,0 @@
#ifndef Z2AUDIOCS_H
#define Z2AUDIOCS_H
#include <dolphin/types.h>
class JKRHeap;
class JKRArchive;
class Z2AudioCS {
public:
static void newSpkSoundMemPool();
static int init(JKRHeap*, JKRArchive*, s32, s32);
static void update();
static void connect(s32);
static void disconnect(s32);
static void extensionProcess(s32, s32);
u32 getHandleSoundID(s32);
static void start(s32, s32);
static int startLevel(s32, s32);
};
#endif /* Z2AUDIOCS_H */