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
|
#ifndef NW4R_SND_REMOTE_SPEAKER_H
#define NW4R_SND_REMOTE_SPEAKER_H
#include "rvl/OS.h" // IWYU pragma: export
#include "rvl/WENC.h" // IWYU pragma: export
#include "rvl/WPAD.h" // IWYU pragma: export
namespace nw4r {
namespace snd {
class RemoteSpeaker {
public:
enum SpeakerState {
STATE_INVALID,
STATE_EXEC_SPEAKER_ON,
STATE_SPEAKER_ON,
STATE_EXEC_SPEAKER_PLAY,
STATE_SPEAKER_PLAY,
STATE_EXEC_SPEAKER_OFF,
STATE_SPEAKER_OFF
};
enum SpeakerCommand {
COMMAND_NONE,
COMMAND_SPEAKER_ON,
COMMAND_SPEAKER_PLAY,
COMMAND_SPEAKER_OFF
};
static const int SAMPLES_PER_AUDIO_PACKET = 40;
public:
RemoteSpeaker();
void InitParam();
bool Setup(WPADCallback pCallback);
void Shutdown(WPADCallback pCallback);
bool EnableOutput(bool enable);
bool IsEnabledOutput() const;
void Update();
void UpdateStreamData(const s16 *pRmtSamples);
bool IsAvailable() const {
return mState == STATE_SPEAKER_PLAY;
}
void SetChannelIndex(int index) {
mChannelIndex = index;
}
private:
static const int SAMPLES_PER_ENCODED_PACKET = (SAMPLES_PER_AUDIO_PACKET + 1) / 2;
static const int CONTINUOUS_PLAY_INTERVAL_MINUTES = 8;
private:
void ClearParam();
void ExecCommand(SpeakerCommand command);
bool IsAllSampleZero(const s16 *pRmtSamples);
void NotifyCallback(s32 chan, s32 result);
static void SpeakerOnCallback(s32 chan, s32 result);
static void SpeakerPlayCallback(s32 chan, s32 result);
static void SpeakerOffCallback(s32 chan, s32 result);
static void ContinueAlarmHandler(OSAlarm *pAlarm, OSContext *pCtx);
static void IntervalAlarmHandler(OSAlarm *pAlarm, OSContext *pCtx);
private:
bool mInitFlag; // at 0x0
bool mPlayFlag; // at 0x1
bool mEnableFlag; // at 0x2
bool mFirstEncodeFlag; // at 0x3
bool mValidCallbackFlag; // at 0x4
bool mCommandBusyFlag; // at 0x5
// TODO commenting out a random flag to make eggAudioRmtSpeakerMgr match
// TODO offsets are wrong as a result
// bool mForceResumeFlag; // at 0x6
bool mContinueFlag; // at 0x7
volatile bool mIntervalFlag; // at 0x8
SpeakerState mState; // at 0xC
SpeakerCommand mUserCommand; // at 0x10
SpeakerCommand mInternalCommand; // at 0x14
WENCInfo mEncodeInfo; // at 0x18
int mChannelIndex; // at 0x38
WPADCallback *mWpadCallback; // at 0x3C
OSAlarm mContinueAlarm; // at 0x40
OSAlarm mIntervalAlarm; // at 0x70
s64 mContinueBeginTime; // at 0xA0
};
} // namespace snd
} // namespace nw4r
#endif
|