summaryrefslogtreecommitdiff
path: root/include/nw4r/snd/snd_AxManager.h
blob: 1aad4de5fd49ab31ac1ac30f22d7e9519bdca73e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#ifndef NW4R_SND_AX_MANAGER_H
#define NW4R_SND_AX_MANAGER_H

/*******************************************************************************
 * headers
 */

#include "common.h"

#include "nw4r/snd/snd_AxVoice.h"
#include "nw4r/snd/snd_global.h"

#include "nw4r/snd/snd_FxBase.h"
#include "nw4r/snd/snd_MoveValue.h"

#include "nw4r/ut/ut_LinkList.h"

#include <rvl/AI/ai.h> // AIDMACallback
#include <rvl/AX/AX.h>
#include <rvl/AX/AXCL.h> // AX_MAX_VOLUME
#include <rvl/AX/AXAux.h> // AXAuxCallback
#include <rvl/AX/AXOut.h> // AXFrameCallback

#include "nw4r/NW4RAssert.hpp"

/*******************************************************************************
 * types
 */

// forward declarations
namespace nw4r { namespace snd { namespace detail { class BiquadFilterLpf; }}}
namespace nw4r { namespace snd { namespace detail { class BiquadFilterHpf; }}}
namespace nw4r { namespace snd { namespace detail { class BiquadFilterBpf512; }}}
namespace nw4r { namespace snd { namespace detail { class BiquadFilterBpf1024; }}}
namespace nw4r { namespace snd { namespace detail { class BiquadFilterBpf2048; }}}
namespace nw4r { namespace snd { class BiquadFilterCallback; }}

/*******************************************************************************
 * classes and functions
 */

namespace nw4r { namespace snd { namespace detail
{
	// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2a5afe
	class AxManager
	{
	// nested types
	public:
		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2a6808
		struct CallbackListNode
		{
		// typedefs
		public:
			typedef ut::LinkList<CallbackListNode, 0x00> LinkList;

		// members
		public:
			ut::LinkListNode	node;		// size 0x08, offset 0x00
			AXFrameCallback		*callback;	// size 0x04, offset 0x08
		}; // size 0x0c

	// methods
	public:
		// instance accessors
		static AxManager &GetInstance();

		// methods
		void Init();
		void Update();
		void Shutdown();

		OutputMode GetOutputMode();
		void const *GetZeroBufferAddress();
		bool CheckInit() { return mInitialized; }
		f32 GetOutputVolume() const;
		FxBase::LinkList &GetEffectList(AuxBus bus)
		{
			NW4RAssertHeaderClampedLValue_Line(173, bus, AUX_A, AUX_BUS_NUM);

			return mFxList[bus];
		}
		BiquadFilterCallback const *GetBiquadFilterCallback(int index)
		{
			return sBiquadFilterCallbackTable[static_cast<u8>(index)];
		}

		void SetOutputMode(OutputMode mode);
		void SetMainOutVolume(f32 volume, int frames);
		void SetBiquadFilterCallback(int type,
		                             BiquadFilterCallback const *callback);

		void RegisterCallback(CallbackListNode *node,
		                      AXFrameCallback *callback);
		void UnregisterCallback(CallbackListNode *node);

		bool AppendEffect(AuxBus bus, FxBase *pFx);
		void ClearEffect(AuxBus bus, int frame);
		void ShutdownEffect(AuxBus bus);

		f32 GetMasterVolume() const {
			return mMasterVolume.GetValue();
		}
		void SetMasterVolume(f32 volume, int frame);
		void PrepareReset();

		bool IsResetReady() const {
			return mResetReadyCounter == 0;
		}

		AxVoice::SrcType GetSrcType() const {
			return mSrcType;
		}

	private:
		// cdtors
		AxManager();

		// callbacks
		static void AxCallbackFunc();
		static void AuxCallbackFunc(void* pChans, void* pContext);
		static void AiDmaCallbackFunc();

	// static members
	private:
		static u8 const AUX_CALLBACK_WAIT_FRAME = 6;
		static u16 const AUX_RETURN_VOLUME_MAX = AX_MAX_VOLUME;
		static int const FX_SAMPLE_RATE = 32000;
		static SampleFormat const FX_SAMPLE_FORMAT = SAMPLE_FORMAT_PCM_S32;
		static int const FX_BUFFER_SIZE = 0x180;
		static int const ZERO_BUFFER_SIZE = 256;
		static int const SAMPLES_PAR_AUDIO_FRAME;
		static int const AUDIO_FRAME_INTERVAL;

		static byte_t sZeroBuffer[ZERO_BUFFER_SIZE];
		static BiquadFilterCallback const *sBiquadFilterCallbackTable[128];
		static BiquadFilterLpf sBiquadFilterLpf;
		static BiquadFilterHpf sBiquadFilterHpf;
		static BiquadFilterBpf512 sBiquadFilterBpf512;
		static BiquadFilterBpf1024 sBiquadFilterBpf1024;
		static BiquadFilterBpf2048 sBiquadFilterBpf2048;

	// members
	private:
		OutputMode					mOutputMode;							// size 0x04, offset 0x00
		void						*mZeroBufferAddress;					// size 0x04, offset 0x04
		CallbackListNode::LinkList	mCallbackList;							// size 0x0c, offset 0x08
		AXFrameCallback				*mNextAxRegisterCallback;				// size 0x04, offset 0x14
		bool						mInitialized;							// size 0x01, offset 0x18
		bool						mUpdateVoicePrioFlag;					// size 0x01, offset 0x19
		/* 2 bytes padding */
		MoveValue<f32, int>			mMasterVolume;							// size 0x10, offset 0x1c
		MoveValue<f32, int>			mMainOutVolume;							// size 0x10, offset 0x2c
		MoveValue<f32, int>			mVolumeForReset;						// size 0x10, offset 0x3c
		AIDMACallback				mOldAidCallback;						// size 0x04, offset 0x4c
		volatile s32				mResetReadyCounter;						// size 0x04, offset 0x50
		MoveValue<f32, int>			mAuxFadeVolume[AUX_BUS_NUM];			// size 0x30, offset 0x54
		MoveValue<f32, int>			mAuxUserVolume[AUX_BUS_NUM];			// size 0x30, offset 0x84
		FxBase::LinkList			mFxList[AUX_BUS_NUM];					// size 0x24, offset 0xb4
		AXAuxCallback				mAuxCallback[AUX_BUS_NUM];				// size 0x0c, offset 0xd8
		void						*mAuxCallbackContext[AUX_BUS_NUM];		// size 0x0c, offset 0xe4
		u8							mAuxCallbackWaitCounter[AUX_BUS_NUM];	// size 0x03, offset 0xf0
		/* 1 byte padding */
		u32							mEffectProcessTick[AUX_BUS_NUM];		// size 0x0c, offset 0xf4
		AxVoice::SrcType			mSrcType;
	}; // size 0x104
}}} // namespace nw4r::snd::detail

#endif // NW4R_SND_AX_MANAGER_H