From bbbd6d0ecdfdfea2f57aaba47f34ce02472bbfc1 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Thu, 21 May 2020 15:30:24 +0200 Subject: [PATCH] Tuning library with RT fixes, no dynamic allocations --- src/external/tunings/include/Tunings.h | 7 +++--- src/external/tunings/src/Tunings.cpp | 31 ++++++++++++++++---------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/external/tunings/include/Tunings.h b/src/external/tunings/include/Tunings.h index c57a476e..a23daadc 100644 --- a/src/external/tunings/include/Tunings.h +++ b/src/external/tunings/include/Tunings.h @@ -32,7 +32,6 @@ #pragma once #include -#include #include #include @@ -40,6 +39,8 @@ namespace Tunings { static constexpr double MIDI_0_FREQ = 8.17579891564371; // or 440.0 * pow( 2.0, - (69.0/12.0 ) ) + static constexpr int MAX_CAPACITY = 64; // fixed capacity of note/key lists + /** * A Tone is a single entry in an SCL file. It is expressed either in cents or in * a ratio, as described in the SCL documentation. @@ -77,7 +78,7 @@ namespace Tunings { std::string description; // The description in the SCL file. Informational only int count = 0; // The number of tones. - std::vector tones; // The tones + Tone tones[MAX_CAPACITY]; // The tones }; /** @@ -96,7 +97,7 @@ namespace Tunings int tuningConstantNote = 60; double tuningFrequency = MIDI_0_FREQ * 32.0, tuningPitch = 32.0; // pitch = frequency / MIDI_0_FREQ int octaveDegrees = 12; - std::vector keys; // rather than an 'x' we use a '-1' for skipped keys + int keys[MAX_CAPACITY]; // rather than an 'x' we use a '-1' for skipped keys }; /** diff --git a/src/external/tunings/src/Tunings.cpp b/src/external/tunings/src/Tunings.cpp index 682cadfe..39704aa8 100644 --- a/src/external/tunings/src/Tunings.cpp +++ b/src/external/tunings/src/Tunings.cpp @@ -75,6 +75,7 @@ namespace Tunings std::string line; const int read_header = 0, read_count = 1, read_note = 2, trailing = 3; int state = read_header; + int tone_index = 0; Scale res; int lineno = 0; @@ -94,12 +95,15 @@ namespace Tunings break; case read_count: res.count = atoi(line.c_str()); - state = read_note; + if(res.count < 0 || res.count > MAX_CAPACITY) + { + throw TuningError( "Tone count invalid or too large in SCL file." ); + } + state = ( res.count > 0 ) ? read_note : trailing; break; case read_note: - auto t = toneFromString(line, lineno); - res.tones.push_back(t); - if( (int)res.tones.size() == res.count ) + res.tones[tone_index++] = toneFromString(line, lineno); + if( tone_index == res.count ) state = trailing; break; @@ -111,10 +115,10 @@ namespace Tunings throw TuningError( "Incomplete SCL file. Found no notes section in the file" ); } - if( (int)res.tones.size() != res.count ) + if( tone_index != res.count ) { std::string s = "Read fewer notes than count in file. Count=" + std::to_string( res.count ) - + " notes array size=" + std::to_string( res.tones.size() ); + + " notes array size=" + std::to_string( tone_index ); throw TuningError(s); } @@ -146,7 +150,6 @@ namespace Tunings { Scale res; res.count = 12; - res.tones.resize(12); for (int i = 0; i < 12; ++i) { Tone &t = res.tones[i]; t.type = Tone::kToneCents; @@ -185,7 +188,6 @@ namespace Tunings std::string line; KeyboardMapping res; - res.keys.clear(); enum parsePosition { map_size = 0, @@ -199,6 +201,7 @@ namespace Tunings trailing }; parsePosition state = map_size; + int key_index = 0; int lineno = 0; while (std::getline(inf, line)) @@ -238,6 +241,10 @@ namespace Tunings { case map_size: res.count = i; + if(res.count < 0 || res.count > MAX_CAPACITY) + { + throw TuningError( "Key count invalid or too large in KBM file." ); + } break; case first_midi: res.firstMidi = i; @@ -259,8 +266,8 @@ namespace Tunings res.octaveDegrees = i; break; case keys: - res.keys.push_back(i); - if( (int)res.keys.size() == res.count ) state = trailing; + res.keys[key_index++] = i; + if( key_index == res.count ) state = trailing; break; case trailing: break; @@ -275,10 +282,10 @@ namespace Tunings throw TuningError( "Incomplete KBM file. Ubable to get to keys section of file" ); } - if( (int)res.keys.size() != res.count ) + if( key_index != res.count ) { throw TuningError( "Different number of keys than mapping file indicates. Count is " - + std::to_string( res.count ) + " and we parsed " + std::to_string( res.keys.size() ) + " keys." ); + + std::to_string( res.count ) + " and we parsed " + std::to_string( key_index ) + " keys." ); } return res;