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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
|
#ifndef NW4R_SND_CHANNEL_H
#define NW4R_SND_CHANNEL_H
/*******************************************************************************
* headers
*/
#include <climits> // USHRT_MAX
#include "common.h"
#include "nw4r/snd/snd_EnvGenerator.h"
#include "nw4r/snd/snd_InstancePool.h"
#include "nw4r/snd/snd_global.h"
#include "nw4r/snd/snd_Lfo.h"
#include "nw4r/snd/snd_MoveValue.h"
#include "nw4r/snd/snd_Voice.h"
#include "nw4r/ut/ut_LinkList.h"
#include "nw4r/NW4RAssert.hpp"
/*******************************************************************************
* types
*/
// forward declarations
namespace nw4r { namespace snd { namespace detail { class WaveDataLocationCallback; }}}
namespace nw4r { namespace snd { namespace detail { struct WaveInfo; }}}
/*******************************************************************************
* classes and functions
*/
namespace nw4r { namespace snd { namespace detail
{
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2c353
// NOTE: different from ketteiban: no remote fields
class Channel
{
// enums
public:
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x290ad
enum ChannelCallbackStatus
{
CALLBACK_STATUS_STOPPED,
CALLBACK_STATUS_DROP,
CALLBACK_STATUS_FINISH,
CALLBACK_STATUS_CANCEL,
};
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2c2f1
enum LfoTarget
{
LFO_TARGET_PITCH,
LFO_TARGET_VOLUME,
LFO_TARGET_PAN,
};
// typedefs
public:
typedef void Callback(Channel *dropChannel,
ChannelCallbackStatus status,
u32 userData);
typedef ut::LinkList<Channel, 0xd8> LinkList;
// methods
public:
// instance managers
static Channel *AllocChannel(int voiceChannelCount, int voiceOutCount,
int priority, Callback *callback,
u32 callbackData);
static void FreeChannel(Channel *channel);
// methods
void InitParam(Callback *callback, u32 callbackData);
void Start(WaveInfo const &waveParam, int length, u32 startOffset);
void Pause(bool flag)
{
mPauseFlag = flag;
mVoice->Pause(flag);
}
void Stop();
bool IsRelease() const
{
return mEnvelope.GetStatus() == EnvGenerator::STATUS_RELEASE;
}
bool IsPause() const { return mPauseFlag != false; }
bool IsActive() const { return mActiveFlag; }
bool IsAutoUpdateSweep() const { return mAutoSweep; }
f32 GetSweepValue() const;
s32 GetLength() const { return mLength; }
int GetAlternateAssignId() const { return mAlternateAssign; }
Voice *GetVoice() const { return mVoice; }
Channel *GetNextTrackChannel() const { return mNextLink; }
void SetDecay(int decay) { mEnvelope.SetDecay(decay); }
void SetRelease(int release) { mEnvelope.SetRelease(release); }
void SetAttack(int attack) { mEnvelope.SetAttack(attack); }
void SetSustain(int sustain) { mEnvelope.SetSustain(sustain); }
void SetHold(int hold) { mEnvelope.SetHold(hold); }
void SetLfoParam(LfoParam const ¶m) { mLfo.SetParam(param); }
void SetLfoTarget(LfoTarget type) { mLfoTarget = type; }
void SetReleasePriorityFix(bool fix) { mReleasePriorityFixFlag = fix; }
void SetReleaseIgnore(bool ignore) { mReleaseIgnoreFlag = ignore; }
void SetBiquadFilter(int type, f32 value);
void SetRemoteFilter(int filter) { mRemoteFilter = filter; }
void SetUserVolume(f32 volume) { mUserVolume = volume; }
void SetUserPitchRatio(f32 pitchRatio) { mUserPitchRatio = pitchRatio; }
void SetUserPan(f32 pan) { mUserPan = pan; }
void SetUserSurroundPan(f32 surroundPan)
{
mUserSurroundPan = surroundPan;
}
void SetRemoteOutVolume(int channel, f32 volume)
{
mRemoteOutVolume[channel] = volume;
}
void SetUserLpfFreq(f32 lpfFreq) { mUserLpfFreq = lpfFreq; }
void SetOutputLine(int lineFlag) { mOutputLineFlag = lineFlag; }
void SetMainOutVolume(f32 volume) { mMainOutVolume = volume; }
void SetMainSend(f32 send) { mMainSend = send; }
void SetFxSend(AuxBus bus, f32 send) { mFxSend[bus] = send; }
void SetUserPitch(f32 pitch) { mUserPitch = pitch; }
void SetSweepParam(f32 sweepPitch, int sweepTime, bool autoUpdate);
void SetInitVolume(f32 volume) { mInitVolume = volume; }
void SetInitPan(f32 pan) { mInitPan = pan; }
void SetInitSurroundPan(f32 surroundPan)
{
mInitSurroundPan = surroundPan;
}
void SetTune(f32 tune) { mTune = tune; }
void SetSilence(bool silenceFlag, int fadeTimes)
{
NW4RAssertHeaderClampedLRValue_Line(138, fadeTimes, 0, USHRT_MAX);
mSilenceVolume.SetTarget(silenceFlag ? SILENCE_VOLUME_MIN
: SILENCE_VOLUME_MAX,
fadeTimes);
}
void SetKey(int key) { mKey = key; }
void SetOriginalKey(int key) { mOriginalKey = key; }
void SetLength(s32 length) { mLength = length; }
void SetPanMode(PanMode panMode) { mPanMode = panMode; }
void SetPanCurve(PanCurve panCurve) { mPanCurve = panCurve; }
void SetAlternateAssignId(int id) { mAlternateAssign = id; }
void SetWaveDataLocationCallback(WaveDataLocationCallback *callback,
WaveInfo const *waveInfo)
{
mWaveDataLocationCallback = callback;
mWaveInfo = waveInfo;
}
void SetVoiceOutParam(int index, VoiceOutParam const ¶m)
{
mVoice->SetVoiceOutParam(index, param);
}
void SetNextTrackChannel(Channel *channel) { mNextLink = channel; }
void Update(bool doPeriodicProc);
void UpdateSweep(int count);
void Release();
void NoteOff();
private:
// cdtors
Channel();
~Channel();
// callbacks
static void VoiceCallbackFunc(Voice *voice,
Voice::VoiceCallbackStatus status,
void *arg);
// static members
public:
static u8 const SILENCE_VOLUME_MIN = 0;
static u8 const SILENCE_VOLUME_MAX = 255;
static int const ORIGINAL_KEY_INIT = 60;
static int const KEY_INIT = 60;
static int const PRIORITY_RELEASE = 1;
static int const CHANNEL_MAX = Voice::CHANNEL_MAX;
static int const CHANNEL_MIN = 1;
static int const CHANNEL_NUM;
// members
private:
EnvGenerator mEnvelope; // size 0x1c, offset 0x00
Lfo mLfo; // size 0x18, offset 0x1c
u8 mLfoTarget; // size 0x01, offset 0x34
bool mPauseFlag; // size 0x01, offset 0x35
bool mActiveFlag; // size 0x01, offset 0x36
bool mAllocFlag; // size 0x01, offset 0x37
bool mAutoSweep; // size 0x01, offset 0x38
bool mReleasePriorityFixFlag; // size 0x01, offset 0x39
u8 mReleaseIgnoreFlag; // size 0x01, offset 0x3a // not a bool?
u8 mBiquadType; // size 0x01, offset 0x3b
u8 mRemoteFilter; // size 0x01, offset 0x3c
/* 3 bytes padding */
f32 mUserVolume; // size 0x04, offset 0x40
f32 mUserPitchRatio; // size 0x04, offset 0x44
f32 mUserPan; // size 0x04, offset 0x48
f32 mUserSurroundPan; // size 0x04, offset 0x4c
f32 mUserLpfFreq; // size 0x04, offset 0x50
f32 mBiquadValue; // size 0x04, offset 0x54
int mOutputLineFlag; // size 0x04, offset 0x58
f32 mMainOutVolume; // size 0x04, offset 0x5c
f32 mMainSend; // size 0x04, offset 0x60
f32 mFxSend[AUX_BUS_NUM]; // size 0x0c, offset 0x64
f32 mRemoteOutVolume[4];
f32 mUserPitch; // size 0x04, offset 0x70
f32 mSweepPitch; // size 0x04, offset 0x74
s32 mSweepCounter; // size 0x04, offset 0x78
s32 mSweepLength; // size 0x04, offset 0x7c
f32 mInitVolume; // size 0x04, offset 0x80
f32 mInitPan; // size 0x04, offset 0x84
f32 mInitSurroundPan; // size 0x04, offset 0x88
f32 mTune; // size 0x04, offset 0x8c
MoveValue<u8, u16> mSilenceVolume; // size 0x06, offset 0x90
/* 2 bytes padding */
int mKey; // size 0x04, offset 0x98
int mOriginalKey; // size 0x04, offset 0x9c
s32 mLength; // size 0x04, offset 0xa0
PanMode mPanMode; // size 0x04, offset 0xa4
PanCurve mPanCurve; // size 0x04, offset 0xa8
int mAlternateAssign; // size 0x04, offset 0xac
Callback *mCallback; // size 0x04, offset 0xb0
u32 mCallbackData; // size 0x04, offset 0xb4
WaveDataLocationCallback *mWaveDataLocationCallback; // size 0x04, offset 0xb8
WaveInfo const *mWaveInfo; // size 0x04, offset 0xbc
Voice *mVoice; // size 0x04, offset 0xc0
Channel *mNextLink; // size 0x04, offset 0xc4
public:
ut::LinkListNode mLink; // size 0x08, offset 0xc8
// friends
private:
// for calling private constructor
template <class> friend class InstancePool;
}; // size 0xd0
// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2b895c
class ChannelManager
{
public:
static const int VOICE_MARGIN = 1;
static const int VOICE_MAX = AX_VOICE_MAX + VOICE_MARGIN;
static const int WORK_SIZE_MAX = VOICE_MAX * sizeof(Channel);
// methods
public:
// instance accessors
static ChannelManager &GetInstance();
// methods
u32 GetRequiredMemSize(int channelCount);
void Setup(void *mem, u32 memSize);
void Shutdown();
Channel* Alloc();
void Free(Channel *channel);
void UpdateAllChannel();
private:
// cdtors
ChannelManager();
// members
private:
InstancePool<Channel> mPool; // size 0x04, offset 0x00
Channel::LinkList mChannelList; // size 0x0c, offset 0x04
bool mInitialized; // size 0x01, offset 0x10
/* 3 bytes padding */
u32 mChannelCount; // size 0x04, offset 0x14
void *mMem; // size 0x04, offset 0x18
u32 mMemSize; // size 0x04, offset 0x1c
}; // size 0x20
}}} // namespace nw4r::snd::detail
#endif // NW4R_SND_CHANNEL_H
|