| 184 | } |
| 185 | |
| 186 | int |
| 187 | TuningMap::loadKeyMap (const std::string & filename) |
| 188 | { |
| 189 | std::ifstream file(filename.c_str()); |
| 190 | std::string line; |
| 191 | |
| 192 | int mapSize = -1; |
| 193 | int firstNote = -1; |
| 194 | int lastNote = -1; |
| 195 | int newZeroNote = -1; |
| 196 | int newRefNote = -1; |
| 197 | double newRefPitch = -1.; |
| 198 | int newMapRepeatInc = -1; |
| 199 | std::vector<int> newMapping; |
| 200 | |
| 201 | // It makes more sense to manipulate the ActiveRange array directly instead of creating |
| 202 | // a temporary container and pointing the actual array to it at the end because |
| 203 | // doing so would require dynamic memory allocation. |
| 204 | bool rangeDeclared = false; |
| 205 | for (int i = 0; i < 128; i++) |
| 206 | activeRange[i] = false; |
| 207 | |
| 208 | while (file.good()) |
| 209 | { |
| 210 | getline(file, line); |
| 211 | unsigned i = 0; |
| 212 | while (i < line.size() && isspace(line[i])) ++i; |
| 213 | if (i == line.size()) continue; // skip all-whitespace lines |
| 214 | if (line[i] == '!') continue; // skip comment lines |
| 215 | std::istringstream iss(line); |
| 216 | if (line [i] == '<') //An active range should be defined on this line. |
| 217 | { |
| 218 | std::string tag; |
| 219 | int min, max; |
| 220 | iss >> tag; |
| 221 | iss >> min; |
| 222 | if (iss.fail()) |
| 223 | return -1; |
| 224 | iss >> max; |
| 225 | if (iss.fail()) |
| 226 | return -1; |
| 227 | if ((min >= 0) && (max < 128) && (min <= max)) // No overlap is checked for; it wouldn't hurt anything if ranges overlapped. |
| 228 | { |
| 229 | rangeDeclared = true; |
| 230 | activateRange(min, max); |
| 231 | } |
| 232 | else |
| 233 | { |
| 234 | return -1; |
| 235 | } |
| 236 | } |
| 237 | else if (mapSize < 0) |
| 238 | { |
| 239 | iss >> mapSize; |
| 240 | if (iss.fail() || mapSize < 0) |
| 241 | return -1; |
| 242 | } |
| 243 | else if (firstNote < 0) |