NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
snd_Channel.h
1#ifndef NW4R_SND_CHANNEL_H
2#define NW4R_SND_CHANNEL_H
3
4/*******************************************************************************
5 * headers
6 */
7
8#include <climits> // USHRT_MAX
9
10#include <types.h>
11
12#include "nw4r/snd/snd_EnvGenerator.h"
13#include "nw4r/snd/snd_InstancePool.h"
14#include "nw4r/snd/snd_global.h"
15#include "nw4r/snd/snd_Lfo.h"
16#include "nw4r/snd/snd_MoveValue.h"
17#include "nw4r/snd/snd_Voice.h"
18
19#include "nw4r/ut/ut_LinkList.h"
20
21#include "nw4r/NW4RAssert.hpp"
22
23/*******************************************************************************
24 * types
25 */
26
27// forward declarations
28namespace nw4r { namespace snd { namespace detail { class WaveDataLocationCallback; }}}
29namespace nw4r { namespace snd { namespace detail { struct WaveInfo; }}}
30
31/*******************************************************************************
32 * classes and functions
33 */
34
35namespace nw4r { namespace snd { namespace detail
36{
37 // [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2c353
38 // NOTE: different from ketteiban: no remote fields
39 class Channel
40 {
41 // enums
42 public:
43 // [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x290ad
44 enum ChannelCallbackStatus
45 {
46 CALLBACK_STATUS_STOPPED,
47 CALLBACK_STATUS_DROP,
48 CALLBACK_STATUS_FINISH,
49 CALLBACK_STATUS_CANCEL,
50 };
51
52 // [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2c2f1
53 enum LfoTarget
54 {
55 LFO_TARGET_PITCH,
56 LFO_TARGET_VOLUME,
57 LFO_TARGET_PAN,
58 };
59
60 // typedefs
61 public:
62 typedef void Callback(Channel *dropChannel,
63 ChannelCallbackStatus status,
64 ulong userData);
65
66 typedef ut::LinkList<Channel, 0xd8> LinkList;
67
68 // methods
69 public:
70 // instance managers
71 static Channel *AllocChannel(int voiceChannelCount, int voiceOutCount,
72 int priority, Callback *callback,
73 ulong callbackData);
74
75 static void FreeChannel(Channel *channel);
76
77 // methods
78 void InitParam(Callback *callback, ulong callbackData);
79 void Start(WaveInfo const &waveParam, int length, ulong startOffset);
80 void Pause(bool flag)
81 {
82 mPauseFlag = flag;
83 mVoice->Pause(flag);
84 }
85 void Stop();
86
87 bool IsRelease() const
88 {
89 return mEnvelope.GetStatus() == EnvGenerator::STATUS_RELEASE;
90 }
91 bool IsPause() const { return mPauseFlag != false; }
92 bool IsActive() const { return mActiveFlag; }
93 bool IsAutoUpdateSweep() const { return mAutoSweep; }
94 f32 GetSweepValue() const;
95 s32 GetLength() const { return mLength; }
96 int GetAlternateAssignId() const { return mAlternateAssign; }
97 Voice *GetVoice() const { return mVoice; }
98 Channel *GetNextTrackChannel() const { return mNextLink; }
99
100 void SetDecay(int decay) { mEnvelope.SetDecay(decay); }
101 void SetRelease(int release) { mEnvelope.SetRelease(release); }
102 void SetAttack(int attack) { mEnvelope.SetAttack(attack); }
103 void SetSustain(int sustain) { mEnvelope.SetSustain(sustain); }
104 void SetHold(int hold) { mEnvelope.SetHold(hold); }
105 void SetLfoParam(LfoParam const &param) { mLfo.SetParam(param); }
106 void SetLfoTarget(LfoTarget type) { mLfoTarget = type; }
107 void SetReleasePriorityFix(bool fix) { mReleasePriorityFixFlag = fix; }
108 void SetReleaseIgnore(bool ignore) { mReleaseIgnoreFlag = ignore; }
109 void SetBiquadFilter(int type, f32 value);
110 void SetRemoteFilter(int filter) { mRemoteFilter = filter; }
111 void SetUserVolume(f32 volume) { mUserVolume = volume; }
112 void SetUserPitchRatio(f32 pitchRatio) { mUserPitchRatio = pitchRatio; }
113 void SetUserPan(f32 pan) { mUserPan = pan; }
114 void SetUserSurroundPan(f32 surroundPan)
115 {
116 mUserSurroundPan = surroundPan;
117 }
118 void SetRemoteOutVolume(int channel, f32 volume)
119 {
120 mRemoteOutVolume[channel] = volume;
121 }
122 void SetUserLpfFreq(f32 lpfFreq) { mUserLpfFreq = lpfFreq; }
123 void SetOutputLine(int lineFlag) { mOutputLineFlag = lineFlag; }
124 void SetMainOutVolume(f32 volume) { mMainOutVolume = volume; }
125 void SetMainSend(f32 send) { mMainSend = send; }
126 void SetFxSend(AuxBus bus, f32 send) { mFxSend[bus] = send; }
127 void SetUserPitch(f32 pitch) { mUserPitch = pitch; }
128 void SetSweepParam(f32 sweepPitch, int sweepTime, bool autoUpdate);
129 void SetInitVolume(f32 volume) { mInitVolume = volume; }
130 void SetInitPan(f32 pan) { mInitPan = pan; }
131 void SetInitSurroundPan(f32 surroundPan)
132 {
133 mInitSurroundPan = surroundPan;
134 }
135 void SetTune(f32 tune) { mTune = tune; }
136 void SetSilence(bool silenceFlag, int fadeTimes)
137 {
138 NW4RAssertHeaderClampedLRValue_Line(138, fadeTimes, 0, USHRT_MAX);
139
140 mSilenceVolume.SetTarget(silenceFlag ? SILENCE_VOLUME_MIN
141 : SILENCE_VOLUME_MAX,
142 fadeTimes);
143 }
144 void SetKey(int key) { mKey = key; }
145 void SetOriginalKey(int key) { mOriginalKey = key; }
146 void SetLength(s32 length) { mLength = length; }
147 void SetPanMode(PanMode panMode) { mPanMode = panMode; }
148 void SetPanCurve(PanCurve panCurve) { mPanCurve = panCurve; }
149 void SetAlternateAssignId(int id) { mAlternateAssign = id; }
150 void SetWaveDataLocationCallback(WaveDataLocationCallback *callback,
151 WaveInfo const *waveInfo)
152 {
153 mWaveDataLocationCallback = callback;
154 mWaveInfo = waveInfo;
155 }
156 void SetVoiceOutParam(int index, VoiceOutParam const &param)
157 {
158 mVoice->SetVoiceOutParam(index, param);
159 }
160 void SetNextTrackChannel(Channel *channel) { mNextLink = channel; }
161
162 void Update(bool doPeriodicProc);
163 void UpdateSweep(int count);
164 void Release();
165 void NoteOff();
166
167 private:
168 // cdtors
169 Channel();
170 ~Channel();
171
172 // callbacks
173 static void VoiceCallbackFunc(Voice *voice,
174 Voice::VoiceCallbackStatus status,
175 void *arg);
176
177 // static members
178 public:
179 static u8 const SILENCE_VOLUME_MIN = 0;
180 static u8 const SILENCE_VOLUME_MAX = 255;
181
182 static int const ORIGINAL_KEY_INIT = 60;
183 static int const KEY_INIT = 60;
184
185 static int const PRIORITY_RELEASE = 1;
186
187 static int const CHANNEL_MAX = Voice::CHANNEL_MAX;
188 static int const CHANNEL_MIN = 1;
189 static int const CHANNEL_NUM;
190
191 // members
192 private:
193 EnvGenerator mEnvelope; // size 0x1c, offset 0x00
194 Lfo mLfo; // size 0x18, offset 0x1c
195 u8 mLfoTarget; // size 0x01, offset 0x34
196 bool mPauseFlag; // size 0x01, offset 0x35
197 bool mActiveFlag; // size 0x01, offset 0x36
198 bool mAllocFlag; // size 0x01, offset 0x37
199 bool mAutoSweep; // size 0x01, offset 0x38
200 bool mReleasePriorityFixFlag; // size 0x01, offset 0x39
201 u8 mReleaseIgnoreFlag; // size 0x01, offset 0x3a // not a bool?
202 u8 mBiquadType; // size 0x01, offset 0x3b
203 u8 mRemoteFilter; // size 0x01, offset 0x3c
204 /* 3 bytes padding */
205 f32 mUserVolume; // size 0x04, offset 0x40
206 f32 mUserPitchRatio; // size 0x04, offset 0x44
207 f32 mUserPan; // size 0x04, offset 0x48
208 f32 mUserSurroundPan; // size 0x04, offset 0x4c
209 f32 mUserLpfFreq; // size 0x04, offset 0x50
210 f32 mBiquadValue; // size 0x04, offset 0x54
211 int mOutputLineFlag; // size 0x04, offset 0x58
212 f32 mMainOutVolume; // size 0x04, offset 0x5c
213 f32 mMainSend; // size 0x04, offset 0x60
214 f32 mFxSend[AUX_BUS_NUM]; // size 0x0c, offset 0x64
215 f32 mRemoteOutVolume[4];
216 f32 mUserPitch; // size 0x04, offset 0x70
217 f32 mSweepPitch; // size 0x04, offset 0x74
218 s32 mSweepCounter; // size 0x04, offset 0x78
219 s32 mSweepLength; // size 0x04, offset 0x7c
220 f32 mInitVolume; // size 0x04, offset 0x80
221 f32 mInitPan; // size 0x04, offset 0x84
222 f32 mInitSurroundPan; // size 0x04, offset 0x88
223 f32 mTune; // size 0x04, offset 0x8c
224 MoveValue<u8, u16> mSilenceVolume; // size 0x06, offset 0x90
225 /* 2 bytes padding */
226 int mKey; // size 0x04, offset 0x98
227 int mOriginalKey; // size 0x04, offset 0x9c
228 s32 mLength; // size 0x04, offset 0xa0
229 PanMode mPanMode; // size 0x04, offset 0xa4
230 PanCurve mPanCurve; // size 0x04, offset 0xa8
231 int mAlternateAssign; // size 0x04, offset 0xac
232 Callback *mCallback; // size 0x04, offset 0xb0
233 ulong mCallbackData; // size 0x04, offset 0xb4
234 WaveDataLocationCallback *mWaveDataLocationCallback; // size 0x04, offset 0xb8
235 WaveInfo const *mWaveInfo; // size 0x04, offset 0xbc
236 Voice *mVoice; // size 0x04, offset 0xc0
237 Channel *mNextLink; // size 0x04, offset 0xc4
238 public:
239 ut::LinkListNode mLink; // size 0x08, offset 0xc8
240
241 // friends
242 private:
243 // for calling private constructor
244 template <class> friend class InstancePool;
245 }; // size 0xd0
246
247 // [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2b895c
248 class ChannelManager
249 {
250 public:
251 static const int VOICE_MARGIN = 1;
252 static const int VOICE_MAX = AX_VOICE_MAX + VOICE_MARGIN;
253 static const int WORK_SIZE_MAX = VOICE_MAX * sizeof(Channel);
254 // methods
255 public:
256 // instance accessors
257 static ChannelManager &GetInstance();
258
259 // methods
260 ulong GetRequiredMemSize(int channelCount);
261 void Setup(void *mem, ulong memSize);
262 void Shutdown();
263
264 Channel* Alloc();
265 void Free(Channel *channel);
266
267 void UpdateAllChannel();
268
269 private:
270 // cdtors
271 ChannelManager();
272
273 // members
274 private:
275 InstancePool<Channel> mPool; // size 0x04, offset 0x00
276 Channel::LinkList mChannelList; // size 0x0c, offset 0x04
277 bool mInitialized; // size 0x01, offset 0x10
278 /* 3 bytes padding */
279 ulong mChannelCount; // size 0x04, offset 0x14
280 void *mMem; // size 0x04, offset 0x18
281 ulong mMemSize; // size 0x04, offset 0x1c
282 }; // size 0x20
283}}} // namespace nw4r::snd::detail
284
285#endif // NW4R_SND_CHANNEL_H