-
Notifications
You must be signed in to change notification settings - Fork 6
/
Int24.cs
137 lines (120 loc) · 4.01 KB
/
Int24.cs
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
using GotaSoundIO.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GotaSoundIO {
/// <summary>
/// Signed 24-bit integer.
/// </summary>
public struct Int24 : IReadable, IWriteable {
/// <summary>
/// Max value.
/// </summary>
public const int MaxValue = 8388607;
/// <summary>
/// Min value.
/// </summary>
public const int MinValue = -8388608;
/// <summary>
/// Data.
/// </summary>
private byte[] Data;
/// <summary>
/// Check for null.
/// </summary>
private void NullCheck() {
if (Data == null) {
Data = new byte[3];
}
}
/// <summary>
/// Get this as an int.
/// </summary>
/// <returns>This as an int.</returns>
private int GetInt() {
NullCheck();
int ret = 0;
ret |= Data[2];
ret |= (Data[1] << 8);
ret |= ((Data[0] & 0x7F) << 16);
if ((Data[0] & 0x80) > 0) { ret = MinValue + ret; }
return ret;
}
/// <summary>
/// Convert an into to an Int24.
/// </summary>
/// <param name="val">Value to convert.</param>
/// <returns>Value as an Int24.</returns>
private static Int24 FromInt(int val) {
Int24 ret = new Int24();
ret.NullCheck();
if (val > MaxValue) { val = MaxValue; }
if (val < MinValue) { val = MinValue; }
uint un = (uint)val;
if (val < 0) { un = (uint)(val - MinValue); }
ret.Data[2] = (byte)((un >> 0) & 0xFF);
ret.Data[1] = (byte)((un >> 8) & 0xFF);
ret.Data[0] = (byte)((un >> 16) & 0x7F);
if (val < 0) { ret.Data[0] |= 0x80; }
return ret;
}
/// <summary>
/// Get this as an int.
/// </summary>
/// <param name="val">Value.</param>
public static implicit operator int(Int24 val) => val.GetInt();
/// <summary>
/// Convert from an int.
/// </summary>
/// <param name="val">Value.</param>
public static explicit operator Int24(int val) => Int24.FromInt(val);
/// <summary>
/// Convert from a uint.
/// </summary>
/// <param name="val">Value.</param>
public static explicit operator Int24(uint val) => Int24.FromInt((int)val);
/// <summary>
/// Convert from a float.
/// </summary>
/// <param name="val">Value.</param>
public static explicit operator Int24(float val) => Int24.FromInt((int)val);
/// <summary>
/// Read the data.
/// </summary>
/// <param name="r">The reader.</param>
public void Read(FileReader r) {
NullCheck();
switch (r.ByteOrder) {
case ByteOrder.LittleEndian:
case ByteOrder.System:
Data[2] = r.ReadByte();
Data[1] = r.ReadByte();
Data[0] = r.ReadByte();
break;
case ByteOrder.BigEndian:
Data = r.ReadBytes(3);
break;
}
}
/// <summary>
/// Write the data.
/// </summary>
/// <param name="w">The writer.</param>
public void Write(FileWriter w) {
NullCheck();
switch (w.ByteOrder) {
case ByteOrder.LittleEndian:
case ByteOrder.System:
w.Write(Data[2]);
w.Write(Data[1]);
w.Write(Data[0]);
break;
case ByteOrder.BigEndian:
w.Write(Data);
break;
}
}
}
}