22 int stat = 0, value = 0, code = 0;
23 const char *cur = b.data();
24 const char *end = b.data() + b.size();
25 auto [ptr_value, e] = std::from_chars(cur, end, stat);
26 if(e != std::errc{}) {
27 std::cerr <<
"failed to parse status bytesn\n";
31 while(cur != end && *cur ==
' ') {
35 auto [ptr_value2, e2] = std::from_chars(cur, end, code);
36 if(e2 != std::errc{}) {
37 std::cerr <<
"Failed to parse code\n";
41 while(cur != end && *cur ==
' ') {
44 auto [ptr3, e3] = std::from_chars(cur, end, value);
45 if(e3 != std::errc{}) {
46 std::cerr <<
"Error failed to pasre value\n";
50 std::cout <<
"Status: " << stat <<
" CC: " << code <<
" Value: " << value <<
"\n";
57 std::ifstream mapping_input(filename);
59 throw std::runtime_error(
"could not open MIDI map file: " + filename);
62 std::vector<MidiMapping> mappings;
64 std::size_t line_number = 0;
70 const std::size_t first = line.find_first_not_of(
" \t\r");
71 if (first == std::string::npos || line[first] ==
'#') {
75 throw std::runtime_error(
76 "MIDI map file contains too many mappings");
81 std::istringstream stream(line);
82 std::string action_pair;
88 if (!(stream >> action_pair >> open_brace >> status >> data1 >> data2 >>
90 open_brace !=
'{' || close_brace !=
'}') {
91 throw std::runtime_error(
92 "invalid MIDI map entry at " + filename +
':' +
93 std::to_string(line_number));
97 throw std::runtime_error(
98 "unexpected text in MIDI map at " + filename +
':' +
99 std::to_string(line_number));
102 const std::size_t colon = action_pair.find(
':');
103 if (colon == std::string::npos || colon == 0 ||
104 colon + 1 >= action_pair.size() ||
105 action_pair.find(
':', colon + 1) != std::string::npos) {
106 throw std::runtime_error(
107 "invalid MIDI action pair at " + filename +
':' +
108 std::to_string(line_number));
111 std::size_t primary_parsed = 0;
112 std::size_t secondary_parsed = 0;
116 primary = std::stoi(action_pair.substr(0, colon),
118 secondary = std::stoi(action_pair.substr(colon + 1),
120 }
catch (
const std::exception &) {
121 throw std::runtime_error(
122 "invalid MIDI action code at " + filename +
':' +
123 std::to_string(line_number));
125 if (primary_parsed != colon ||
126 secondary_parsed != action_pair.size() - colon - 1 ||
127 primary <= 0 || primary > 65535 || secondary < 0 ||
128 secondary > 65535 || status < 0 || status > 255 ||
129 data1 < 0 || data1 > 255 || data2 < 0 || data2 > 255) {
130 throw std::runtime_error(
131 "MIDI map value outside its valid range at " + filename +
132 ':' + std::to_string(line_number));
136 {primary, secondary,
static_cast<unsigned char>(status),
137 static_cast<unsigned char>(data1),
138 static_cast<unsigned char>(data2)});