1
1
#pragma once
2
2
3
+ #include < iostream>
4
+
3
5
#include < cstdint>
4
6
#include < fstream>
5
7
#include < sstream>
11
13
namespace RhythmGameUtilities
12
14
{
13
15
14
- template <typename T> T ByteSwap (T value, int length = 8 )
16
+ template <typename T> inline auto ByteSwap (T value, int length = 8 ) -> T
15
17
{
16
18
return (value >> length) | (value << length);
17
19
}
18
20
19
21
template <typename T>
20
- T ReadChunk (std::istringstream &stream, int length = sizeof (T))
22
+ inline auto ReadChunk (std::istringstream &stream, int length = sizeof (T)) -> T
21
23
{
22
24
T chunk{};
23
25
stream.read (reinterpret_cast <char *>(&chunk), length);
24
26
return chunk;
25
27
}
26
28
27
- std::string ReadString (std::istringstream &stream, int length)
29
+ inline auto ReadString (std::istringstream &stream, int length) -> std::string
28
30
{
29
31
std::string chunk (length, ' \0 ' );
30
- stream.read (& chunk[ 0 ] , length);
32
+ stream.read (chunk. data () , length);
31
33
return stream.gcount () == length ? chunk : " " ;
32
34
}
33
35
34
- uint32_t ReadVarLen (std::istringstream &stream)
36
+ inline auto ReadVarLen (std::istringstream &stream) -> uint32_t
35
37
{
36
38
uint32_t value = 0 ;
37
39
uint8_t byte = 0 ;
38
40
do
39
41
{
40
42
byte = ReadChunk<uint8_t >(stream);
41
43
value = (value << 7 ) | (byte & 0x7F );
42
- } while (byte & 0x80 );
44
+ } while (( byte & 0x80 ) > 0 );
43
45
return value;
44
46
}
45
47
46
- auto STATUS_NOTE_EVENT = 0x90 ;
47
- auto STATUS_META_EVENT = 0xFF ;
48
- auto TYPE_END_OF_TRACK = 0x2F ;
48
+ const auto TYPE_END_OF_TRACK = 0x2F ;
49
+
50
+ const auto SYSTEM_COMMAND = 0xF0 ;
51
+ const auto NOTE_OFF_COMMAND = 0x80 ;
52
+ const auto NOTE_ON_COMMAND = 0x90 ;
53
+ const auto CONTROL_CHANGE_COMMAND = 0xB0 ;
54
+ const auto PROGRAM_CHANGE_COMMAND = 0xC0 ;
55
+ const auto CHANNEL_PRESSURE_COMMAND = 0xD0 ;
49
56
50
- std::vector<Note> ReadMidiData (const std::vector<uint8_t > &data)
57
+ inline auto ReadMidiData (const std::vector<uint8_t > &data) -> std::vector<Note>
51
58
{
52
59
std::istringstream stream (std::string (data.begin (), data.end ()),
53
60
std::ios::binary);
@@ -81,7 +88,7 @@ std::vector<Note> ReadMidiData(const std::vector<uint8_t> &data)
81
88
82
89
auto status = ReadChunk<uint8_t >(stream);
83
90
84
- if ((status & 0xF0 ) == STATUS_NOTE_EVENT )
91
+ if ((status & SYSTEM_COMMAND ) == NOTE_ON_COMMAND )
85
92
{
86
93
Note note{.Position = static_cast <int >(absoluteTick),
87
94
.HandPosition = ReadChunk<uint8_t >(stream)};
@@ -90,7 +97,7 @@ std::vector<Note> ReadMidiData(const std::vector<uint8_t> &data)
90
97
91
98
notes.push_back (note);
92
99
}
93
- else if (status == STATUS_META_EVENT )
100
+ else if (( status & SYSTEM_COMMAND) == SYSTEM_COMMAND )
94
101
{
95
102
auto type = ReadChunk<uint8_t >(stream);
96
103
@@ -103,7 +110,8 @@ std::vector<Note> ReadMidiData(const std::vector<uint8_t> &data)
103
110
break ;
104
111
}
105
112
}
106
- else if ((status & 0xF0 ) == 0xC0 || (status & 0xF0 ) == 0xD0 )
113
+ else if ((status & SYSTEM_COMMAND) == PROGRAM_CHANGE_COMMAND ||
114
+ (status & SYSTEM_COMMAND) == CHANNEL_PRESSURE_COMMAND)
107
115
{
108
116
stream.seekg (1 , std::ios::cur);
109
117
}
@@ -117,7 +125,7 @@ std::vector<Note> ReadMidiData(const std::vector<uint8_t> &data)
117
125
return notes;
118
126
}
119
127
120
- std::vector<Note> ReadMidiFile (const std::string &path)
128
+ auto ReadMidiFile (const std::string &path) -> std::vector<Note>
121
129
{
122
130
std::ifstream file (path, std::ios::binary | std::ios::ate);
123
131
0 commit comments