summaryrefslogtreecommitdiff
path: root/include/nw4r/snd/snd_Util.h
blob: a8db8f7da0fba5cde45912ad66ba13437ed0d909 (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
#ifndef NW4R_SND_UTIL_H
#define NW4R_SND_UTIL_H

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

#include "common.h"

#include "nw4r/NW4RAssert.hpp"

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

namespace nw4r { namespace snd { namespace detail
{
	// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2a4bc2
	class Util
	{
	public:
		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2a4932
		enum RefType
		{
			REFTYPE_ADDRESS,
			REFTYPE_OFFSET,
		};

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2a497b
		enum PanCurve
		{
			PAN_CURVE_SQRT,
			PAN_CURVE_SINCOS,
			PAN_CURVE_LINEAR,
		};

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x241fd, 0x242b9...
		template <typename, typename = void, typename = void, typename = void>
		struct DataRef
		{
			u8		refType;	// size 0x01, offset 0x00
			u8		dataType;	// size 0x01, offset 0x01
			u16		reserved;
			u32		value;		// size 0x04, offset 0x04
		}; // size 0x08

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x247c7, 0x249c5...
		template <typename T>
		struct Table
		{
			u32	count;		// size 0x04, offset 0x00
			T	item[1];	// size T,    offset 0x04
		}; // size 0x04 + T

		// [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x2a49db
		struct PanInfo
		{
			PanCurve	curve;			// size 0x04, offset 0x00
			bool		centerZeroFlag;	// size 0x01, offset 0x04
			bool		zeroClampFlag;	// size 0x01, offset 0x05
			/* 2 bytes padding */
		}; // size 0x08

		static f32 CalcPitchRatio(int pitch);
		static f32 CalcVolumeRatio(f32 dB);
		static f32 CalcPanRatio(f32 pan, PanInfo const &info);
		static f32 CalcSurroundPanRatio(f32 pan, PanInfo const &info);

		static u16 CalcLpfFreq(f32 scale);

		static void GetRemoteFilterCoefs(int filter, u16 *b0, u16 *b1, u16 *b2,
		                                 u16 *a1, u16 *a2);

		static u16 CalcRandom();

		static void const *GetDataRefAddressImpl(RefType refType, u32 value,
		                                         void const *baseAddress);

// The only way these asserts happen one line after the other is with macros
#define DEF_GET_DATA_REF_ADDRESS_(line_, index_)							\
	template <typename T0, typename T1, typename T2, typename T3>			\
	static inline T ## index_ const *GetDataRefAddress ## index_(			\
		Util::DataRef<T0, T1, T2, T3> const &ref, void const *baseAddress)	\
	{																		\
		/* specifically not the header variant */							\
		NW4RAssert_Line(line_, ref.dataType == index_);						\
																			\
		return static_cast<T ## index_ const *>(GetDataRefAddressImpl(		\
			static_cast<RefType>(ref.refType), ref.value, baseAddress));	\
	}																		\
	STATIC_ASSERT(true) // swallow semicolon

		DEF_GET_DATA_REF_ADDRESS_(141, 0);
		DEF_GET_DATA_REF_ADDRESS_(142, 1);
		DEF_GET_DATA_REF_ADDRESS_(143, 2);
		DEF_GET_DATA_REF_ADDRESS_(144, 3);

#undef DEF_GET_DATA_REF_ADDRESS_

		static inline u16 ReadBigEndian(u16 x)
		{
			return x;
		}

		static inline u32 ReadBigEndian(u32 x)
		{
			return x;
		}

		static f32 const CALC_LPF_FREQ_INTERCEPT;
		static int const CALC_LPF_FREQ_TABLE_SIZE = 3 * 8;
		static int const BIQUAD_COEF_COUNT = 5;
		static int const IIR_COEF_COUNT;
		static int const COEF_TABLE_SIZE = 128;
		static int const COEF_TABLE_MAX = 127;
		static int const COEF_TABLE_MIN = 0;
		static int const PAN_TABLE_SIZE = 256 + 1;
		static int const PAN_TABLE_CENTER = 128;
		static int const PAN_TABLE_MIN = 0;
		static int const PAN_TABLE_MAX = 256;
		static int const DECIBEL_SQUARE_TABLE_SIZE;
		static int const DECIBEL_TABLE_SIZE = 964 + 1;
		static int const VOLUME_TABLE_SIZE;
		static int const OCTAVE_DIVISION = 12; // ? makes sense to me
		static int const PAN_CURVE_NUM = 3;
		static int const CALC_DECIBEL_SCALE_MAX;
		static int const PITCH_DIVISION_RANGE = 256; // ? maybe makes sense?
		static int const PITCH_DIVISION_BIT;
		static int const PAN_CENTER;
		static int const PAN_MAX;
		static int const PAN_MIN;
		static int const VOLUME_DB_MAX = 60;
		static int const VOLUME_DB_MIN = -904;
		static u16 const VOLUME_MAX;
		static u16 const VOLUME_MIN;

		static u16 const CalcLpfFreqTable[CALC_LPF_FREQ_TABLE_SIZE];
		static u16 const RemoteFilterCoefTable[COEF_TABLE_SIZE][BIQUAD_COEF_COUNT];
		static f32 const Pan2RatioTableLinear[PAN_TABLE_SIZE];
		static f32 const Pan2RatioTableSinCos[PAN_TABLE_SIZE];
		static f32 const Pan2RatioTableSqrt[PAN_TABLE_SIZE];
		static f32 const *PanTableTable[PAN_CURVE_NUM];
		static f32 const Decibel2RatioTable[DECIBEL_TABLE_SIZE];
		static f32 const PitchTable[PITCH_DIVISION_RANGE];
		static f32 const NoteTable[OCTAVE_DIVISION];
	}; // "namespace" Util
}}} // namespace nw4r::snd::detail

#endif // NW4R_SND_UTIL_H