Integral Types

This commit is contained in:
khodowany
2026-09-12 10:11:50 -07:00
parent 693e232957
commit 44e100985a
15 changed files with 80 additions and 85 deletions
+1 -2
View File
@@ -11,8 +11,7 @@ struct touch_point {
std::int32_t y{};
};
class touch_controller {
public:
struct touch_controller {
auto init() -> void;
auto read(touch_point& point) -> std::bool_t;
};
+9 -20
View File
@@ -1,16 +1,16 @@
#include <vamp_pico/display.hpp>
#include <algorithm>
#include <array>
#include <cinttypes>
#include <cstdio>
#include <cstdint>
#include <cstring>
#include <vamp_style/font.hpp>
#include <hardware/gpio.h>
#include <hardware/spi.h>
#include <pico/stdlib.h>
#include "hardware/gpio.h"
#include "hardware/spi.h"
#include "pico/stdlib.h"
#include <vamp_pico/display.hpp>
#include <vamp_style/font.hpp>
namespace {
@@ -53,7 +53,6 @@ auto set_window(std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t
y0 = std::clamp(y0, std::int32_t{0}, vamp_pico::display_height - std::int32_t{1});
x1 = std::clamp(x1, std::int32_t{0}, vamp_pico::display_width - std::int32_t{1});
y1 = std::clamp(y1, std::int32_t{0}, vamp_pico::display_height - std::int32_t{1});
command(0x2a);
auto column = std::array<std::uchar_t, 4>{
static_cast<std::uchar_t>((x0 >> 8) & 0xff),
@@ -62,7 +61,6 @@ auto set_window(std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t
static_cast<std::uchar_t>(x1 & 0xff),
};
data(column.data(), column.size());
command(0x2b);
auto row = std::array<std::uchar_t, 4>{
static_cast<std::uchar_t>((y0 >> 8) & 0xff),
@@ -140,12 +138,10 @@ auto vamp_pico::display::init() -> void {
gpio_set_dir(pin_lcd_bl, GPIO_OUT);
deselect();
gpio_put(pin_lcd_bl, 1);
gpio_put(pin_lcd_rst, 0);
sleep_ms(50);
gpio_put(pin_lcd_rst, 1);
sleep_ms(120);
command(0x01);
sleep_ms(150);
command(0x11);
@@ -210,7 +206,7 @@ auto vamp_pico::display::draw_text(std::int32_t x, std::int32_t y, std::char_t c
cursor += vamp_style::ui_font_pair_adjust(previous, text[i]) * scale;
}
auto glyph = vamp_style::ui_font_glyph(text[i]);
for (auto row = 0; row < vamp_style::ui_font_height; ++row) {
for (auto row = std::int32_t{}; row < vamp_style::ui_font_height; ++row) {
auto col = std::int32_t{};
while (col < static_cast<std::int32_t>(glyph.width)) {
auto row_offset = static_cast<std::size_t>(row * vamp_style::ui_font_max_width);
@@ -255,13 +251,7 @@ auto vamp_pico::display::show_remote(vamp_style::color status, std::char_t const
auto const* title_text = title == nullptr ? "" : title;
auto const* part_text = part == nullptr ? "" : part;
auto status_changed = !remote_valid_ || !same_color(last_status_, status);
auto content_changed = !remote_valid_
|| last_active_ != active
|| !same_text(last_title_, title_text)
|| !same_text(last_part_, part_text)
|| last_page_ != page
|| last_pages_ != pages;
auto content_changed = !remote_valid_ || last_active_ != active || !same_text(last_title_, title_text) || !same_text(last_part_, part_text) || last_page_ != page || last_pages_ != pages;
if (!remote_valid_) {
fill(vamp_style::rgb565(vamp_style::background));
}
@@ -275,14 +265,13 @@ auto vamp_pico::display::show_remote(vamp_style::color status, std::char_t const
draw_centered_text(*this, 118, part_text, vamp_style::rgb565(vamp_style::muted), 1, vamp_pico::display_width - 24);
if (pages != 0U) {
auto page_text = std::array<std::char_t, 32>{};
auto written = std::snprintf(page_text.data(), page_text.size(), "PAGE %lu/%lu", static_cast<unsigned long>(page), static_cast<unsigned long>(pages));
auto written = std::snprintf(page_text.data(), page_text.size(), "PAGE %" PRIu32 "/%" PRIu32, page, pages);
if (written > 0) {
draw_centered_text(*this, 168, page_text.data(), vamp_style::rgb565(vamp_style::muted), 1, vamp_pico::display_width - 24);
}
}
}
}
last_status_ = status;
last_active_ = active;
copy_text(last_title_, title_text);
+2 -2
View File
@@ -139,12 +139,12 @@ auto run_request(std::char_t const* method, std::char_t const* path, std::char_t
written = std::snprintf(
state.request,
sizeof(state.request),
"%s %s HTTP/1.1\r\nHost: %s:%d\r\nContent-Length: %u\r\nContent-Type: application/json\r\nConnection: close\r\n\r\n%s",
"%s %s HTTP/1.1\r\nHost: %s:%d\r\nContent-Length: %zu\r\nContent-Type: application/json\r\nConnection: close\r\n\r\n%s",
method,
path,
VAMP_ZERO_HOST,
VAMP_ZERO_PORT,
static_cast<unsigned>(body_size),
body_size,
body
);
}
+1 -1
View File
@@ -126,7 +126,7 @@ auto main() -> int {
auto status = link_status::RETRYING;
auto gesture = gesture_state{};
auto last_poll = get_absolute_time();
auto poll_now = true;
auto poll_now = std::bool_t{true};
render(display, status, remote);
while (true) {
+6 -10
View File
@@ -1,13 +1,11 @@
#include <vamp_pico/touch.hpp>
#include <vamp_pico/display.hpp>
#include <array>
#include <cstdint>
#include "hardware/gpio.h"
#include "hardware/i2c.h"
#include "pico/stdlib.h"
#include <hardware/gpio.h>
#include <hardware/i2c.h>
#include <vamp_pico/display.hpp>
#include <vamp_pico/touch.hpp>
namespace {
@@ -25,14 +23,12 @@ auto vamp_pico::touch_controller::init() -> void {
gpio_set_function(pin_tp_scl, GPIO_FUNC_I2C);
gpio_pull_up(pin_tp_sda);
gpio_pull_up(pin_tp_scl);
gpio_init(pin_tp_rst);
gpio_set_dir(pin_tp_rst, GPIO_OUT);
gpio_put(pin_tp_rst, 0);
sleep_ms(10);
gpio_put(pin_tp_rst, 1);
sleep_ms(50);
gpio_init(pin_tp_int);
gpio_set_dir(pin_tp_int, GPIO_IN);
gpio_pull_up(pin_tp_int);
@@ -44,7 +40,7 @@ auto vamp_pico::touch_controller::read(vamp_pico::touch_point& point) -> std::bo
if (i2c_write_blocking(i2c1, cst816_address, &reg, 1, true) != 1) {
return false;
}
if (i2c_read_blocking(i2c1, cst816_address, data.data(), data.size(), false) != static_cast<int>(data.size())) {
if (i2c_read_blocking(i2c1, cst816_address, data.data(), data.size(), false) != static_cast<std::int32_t>(data.size())) {
return false;
}
auto fingers = data[0] & 0x0f;
+2 -2
View File
@@ -168,7 +168,7 @@ auto run_headless(vamp_zero::config const& config, vamp_zero::control_state& sta
return std::unexpected(heartbeat.error());
}
auto signals = boost::asio::signal_set{io, SIGINT, SIGTERM};
signals.async_wait([&](auto const&, int) {
signals.async_wait([&](auto const&, std::int32_t) {
server.stop();
io.stop();
});
@@ -226,7 +226,7 @@ auto run_display(vamp_zero::config const& config, vamp_zero::control_state& stat
};
schedule_connection_refresh();
auto signals = boost::asio::signal_set{io, SIGINT, SIGTERM};
signals.async_wait([&](auto const&, int) {
signals.async_wait([&](auto const&, std::int32_t) {
connection_timer.cancel();
server.stop();
ui.stop();
+1 -1
View File
@@ -32,7 +32,7 @@ auto human_label(std::string value) -> std::string {
if (value.empty()) {
return "Score";
}
auto capitalize_next = true;
auto capitalize_next = std::bool_t{true};
for (auto& ch : value) {
if (ch == '-' || ch == '_') {
ch = ' ';
+6 -5
View File
@@ -3,6 +3,7 @@
#include <algorithm>
#include <array>
#include <cmath>
#include <cstdint>
#include <filesystem>
#include <limits>
#include <map>
@@ -22,16 +23,16 @@ auto exact(vamp_zero::score_time t) -> exact_time { return {t.numerator, t.denom
constexpr auto types = std::array<std::string_view, 14>{"maxima", "long", "breve", "whole", "half", "quarter", "eighth", "16th", "32nd", "64th", "128th", "256th", "512th", "1024th"};
auto notation_error(std::string const& message) -> void { throw std::invalid_argument(message); }
auto text(object const& o, char const* key, std::string fallback = {}) -> std::string {
auto text(object const& o, std::char_t const* key, std::string fallback = {}) -> std::string {
auto p = o.if_contains(key);
return p == nullptr ? fallback : std::string{p->as_string()};
}
auto integer(value const& v) -> std::int64_t { return boost::json::value_to<std::int64_t>(v); }
auto integer(object const& o, char const* key, std::int64_t fallback = 0) -> std::int64_t {
auto integer(object const& o, std::char_t const* key, std::int64_t fallback = 0) -> std::int64_t {
auto p = o.if_contains(key);
return p == nullptr ? fallback : integer(*p);
}
auto boolean(object const& o, char const* key) -> bool {
auto boolean(object const& o, std::char_t const* key) -> std::bool_t {
auto p = o.if_contains(key);
return p != nullptr && p->as_bool();
}
@@ -246,7 +247,7 @@ auto measure(value const& v) -> vamp_zero::score_measure {
auto vamp_zero::written_quarters(score_written_duration const& written) -> double {
auto found = std::find(types.begin(), types.end(), written.type);
if (found == types.end()) return 0.0;
return std::ldexp(32.0, -static_cast<int>(std::distance(types.begin(), found))) * (2.0 - std::ldexp(1.0, -written.dots));
return std::ldexp(32.0, -static_cast<std::int32_t>(std::distance(types.begin(), found))) * (2.0 - std::ldexp(1.0, -written.dots));
}
auto vamp_zero::parse_notation_document(std::string_view json, std::string source_path) -> std::expected<score_document, modulus::error> {
@@ -290,7 +291,7 @@ auto vamp_zero::parse_notation_document(std::string_view json, std::string sourc
}
absolute += exact(m.duration);
}
constexpr auto natural = std::array<int,7>{0,2,4,5,7,9,11};
constexpr auto natural = std::array<std::int32_t,7>{0,2,4,5,7,9,11};
auto midi = [&](score_pitch const& p) { return 12*(p.octave+1)+natural[std::string_view{"cdefgab"}.find(p.letter)]+p.alteration.value_or(0); };
for (auto const& [id, ref] : tones) {
auto const& p = *ref.pitch;
+1 -1
View File
@@ -590,7 +590,7 @@ auto vamp_zero::remote_display_text(vamp_zero::app_state const& state) -> std::s
auto part = std::string{};
auto page = std::size_t{};
auto pages = std::size_t{};
auto active = false;
auto active = std::bool_t{false};
if (state.mode == vamp_zero::app_mode::PERFORMANCE_SCORE) {
if (auto const* selected = active_part(state); selected != nullptr) {
active = true;
+21 -21
View File
@@ -158,7 +158,7 @@ auto music_font(std::float32_t size) -> Font {
auto glyph_box(std::int32_t codepoint) -> smufl_box {
auto const& glyphs = vamp_zero::font_data::glyphs;
auto found = std::lower_bound(glyphs.begin(), glyphs.end(), codepoint, [](auto const& g, int value) { return g.codepoint < value; });
auto found = std::lower_bound(glyphs.begin(), glyphs.end(), codepoint, [](auto const& g, std::int32_t value) { return g.codepoint < value; });
if (found == glyphs.end() || found->codepoint != codepoint) return {};
return {found->bounds[0], found->bounds[1], found->bounds[2], found->bounds[3]};
}
@@ -444,8 +444,8 @@ auto duration_for(vamp_zero::score_written_duration const& written, double fallb
if (found != names.end()) return {.base = static_cast<duration_base>(found - names.begin()), .dots = written.dots};
// Directly constructed layout documents use the same exact written-value lookup.
for (auto index = std::size_t{}; index < names.size(); ++index)
for (auto dots = 0; dots <= 16; ++dots)
if (std::abs(fallback_ticks - std::ldexp(131072.0, -static_cast<int>(index)) * (2.0 - std::ldexp(1.0, -dots))) < 0.00001)
for (auto dots = std::int32_t{}; dots <= 16; ++dots)
if (std::abs(fallback_ticks - std::ldexp(131072.0, -static_cast<std::int32_t>(index)) * (2.0 - std::ldexp(1.0, -dots))) < 0.00001)
return {.base = static_cast<duration_base>(index), .dots = dots};
return {};
}
@@ -457,13 +457,13 @@ auto measure_ticks(vamp_zero::score_measure const& measure) -> double {
for (auto const& note : measure.notes) total += spacing_ticks(note);
return std::max(1.0, total);
}
auto has_stem(duration_shape duration) -> bool {
auto has_stem(duration_shape duration) -> std::bool_t {
return duration.base == duration_base::LONG || duration.base == duration_base::MAXIMA || duration.base >= duration_base::HALF;
}
auto flag_count(duration_shape duration) -> int {
return std::max(0, static_cast<int>(duration.base) - static_cast<int>(duration_base::QUARTER));
auto flag_count(duration_shape duration) -> std::int32_t {
return std::max(std::int32_t{}, static_cast<std::int32_t>(duration.base) - static_cast<std::int32_t>(duration_base::QUARTER));
}
auto has_flag(duration_shape duration) -> bool { return flag_count(duration) > 0; }
auto has_flag(duration_shape duration) -> std::bool_t { return flag_count(duration) > 0; }
auto letter_index(std::char_t letter) -> std::int32_t {
switch (letter) {
@@ -733,7 +733,7 @@ auto event_width(vamp_zero::score_note const& note) -> float {
auto attribute_width(vamp_zero::score_attribute const& a) -> float {
auto result = a.clef.empty() ? 0.0F : 45.0F;
if (a.key_alterations) result += 35.0F + 22.0F*std::count_if(a.key_alterations->begin(), a.key_alterations->end(), [](int v) { return v!=0; });
if (a.key_alterations) result += 35.0F + 22.0F*std::count_if(a.key_alterations->begin(), a.key_alterations->end(), [](std::int32_t v) { return v!=0; });
if (!a.time_signature.empty()) result += 50.0F;
return result;
}
@@ -811,7 +811,7 @@ auto metrics_for(vamp_zero::score_document const& score, vamp_zero::score_system
auto const& measure = score.measures[mi];
if (!measure.section_label.empty()) result.above = std::max(result.above, 9.0F);
auto end = range.first_note + std::min(range.note_count, measure.notes.size()-range.first_note);
auto depth = 0;
auto depth = std::int32_t{};
for (auto const& t : measure.tuplets) depth = std::max(depth, t.depth+1);
for (auto ni = range.first_note; ni < end; ++ni) {
auto const& n = measure.notes[ni];
@@ -1046,7 +1046,7 @@ auto layout_structured_key(vamp_zero::score_page_layout& layout, std::string_vie
std::array<std::int32_t, 7> const& alterations, std::float32_t x, std::float32_t top,
std::float32_t spacing, std::size_t system, std::array<std::int32_t, 7> const* previous = nullptr) -> std::float32_t {
auto start = x;
auto paint = [&](int letter, int alteration) {
auto paint = [&](std::int32_t letter, std::int32_t alteration) {
auto glyph = accidental_glyph(alteration_mark(alteration));
if (!glyph) return;
auto pitch = vamp_zero::score_pitch{.letter = "cdefgab"[letter], .octave = 4};
@@ -1056,9 +1056,9 @@ auto layout_structured_key(vamp_zero::score_page_layout& layout, std::string_vie
origin_for_left_baseline(*glyph, x, pitch_y(pitch, top, spacing, clef), spacing), spacing, score_ink(), system);
x += glyph_width(*glyph, spacing) + spacing * 0.15F;
};
if (previous) for (int i = 0; i < 7; ++i)
if (previous) for (auto i = std::int32_t{}; i < 7; ++i)
if ((*previous)[i] && (*previous)[i] != alterations[i]) paint(i, 0);
auto flats = std::any_of(alterations.begin(), alterations.end(), [](int a) { return a < 0; });
auto flats = std::any_of(alterations.begin(), alterations.end(), [](std::int32_t a) { return a < 0; });
for (auto letter : std::string_view{flats ? "beadgcf" : "fcgdaeb"}) {
auto index = letter_index(letter);
if (alterations[index]) paint(index, alterations[index]);
@@ -1375,9 +1375,9 @@ auto estimate_accidental_columns(note_layout const& note, std::float32_t spacing
return left.top < right.top;
});
for (auto const& candidate : candidates) {
auto placed = false;
auto placed = std::bool_t{false};
for (auto& column : columns) {
auto fits = true;
auto fits = std::bool_t{true};
for (auto const& range : column) {
if (candidate.top < range.bottom + spacing * 0.15F && candidate.bottom + spacing * 0.15F > range.top) {
fits = false;
@@ -1532,7 +1532,7 @@ auto build_note_layout(
auto displaced_by_pitch = std::vector<std::bool_t>(raw_heads.size(), false);
auto right_column_x = x + glyph_width(result.notehead, spacing) * 0.72F;
auto previous_y = std::optional<std::float32_t>{};
auto use_right_column = false;
auto use_right_column = std::bool_t{false};
for (auto const& head : ordered) {
if (previous_y && std::abs(*previous_y - head.center_y) <= spacing * 0.55F) {
use_right_column = !use_right_column;
@@ -1654,7 +1654,7 @@ auto update_beam_group_geometry(std::vector<note_layout>& notes, beam_group_layo
}
}
auto beam_type(note_layout const& note, int level) -> std::string_view {
auto beam_type(note_layout const& note, std::int32_t level) -> std::string_view {
for (auto const& beam : note.source->beams) if (beam.level == level) return beam.type;
return {};
}
@@ -1761,7 +1761,7 @@ auto accidental_layouts(note_layout const& note, std::float32_t spacing) -> std:
auto raw_bounds = glyph_bounds(glyph, {.x = 0.0F, .y = head.center_y}, spacing);
auto column_index = std::size_t{};
for (; column_index < column_ranges.size(); ++column_index) {
auto fits = true;
auto fits = std::bool_t{true};
for (auto const& range : column_ranges[column_index]) {
if (raw_bounds.y < range.y + range.height + spacing * 0.15F && raw_bounds.y + raw_bounds.height + spacing * 0.15F > range.y) {
fits = false;
@@ -1880,7 +1880,7 @@ auto layout_rest(
auto y = note.source->rest_position ? pitch_y(*note.source->rest_position, staff_top, spacing, note.source->clef) : rest_baseline_y(note.duration, staff_top, spacing);
auto origin = origin_for_centered_baseline(codepoint, note.x, y, spacing);
add_glyph(layout, vamp_zero::score_layout_item_role::REST, codepoint, origin, spacing, score_ink(), system_index, measure_index, note.note_index);
for (auto dot = 0; dot < note.duration.dots; ++dot) {
for (auto dot = std::int32_t{}; dot < note.duration.dots; ++dot) {
auto bounds = glyph_bounds(codepoint, origin, spacing);
add_glyph(
layout,
@@ -1929,7 +1929,7 @@ auto layout_note_symbols(
auto dot_x = note.visual_right - spacing * 0.65F;
for (auto const& head : note.heads) {
auto dots = note.source != nullptr && head.source_pitch_index < note.source->pitches.size() && !note.source->pitches[head.source_pitch_index].written.type.empty() ? note.source->pitches[head.source_pitch_index].written.dots : note.duration.dots;
for (auto dot = 0; dot < dots; ++dot) add_glyph(
for (auto dot = std::int32_t{}; dot < dots; ++dot) add_glyph(
layout,
vamp_zero::score_layout_item_role::DOT,
glyph_augmentation_dot,
@@ -2433,7 +2433,7 @@ auto layout_measure(
for (auto const& group : beam_groups) {
for (auto index = group.first_note; index <= group.last_note; ++index) {
auto const& n = notes[index];
for (int level = 2; level <= flag_count(n.duration); ++level) {
for (auto level = std::int32_t{2}; level <= flag_count(n.duration); ++level) {
auto type = beam_type(n, level);
auto next = index < group.last_note && flag_count(notes[index+1].duration) >= level;
auto previous = index > group.first_note && flag_count(notes[index-1].duration) >= level;
@@ -2468,7 +2468,7 @@ auto layout_measure(
auto x1 = partner == notes.end() ? n.stem_x+spacing*0.7F : partner->stem_x;
if (partner == notes.end() && n.source->tremolo_type == "start") x1 = notation_right_x;
if (n.source->tremolo_type == "stop") { x0 = notation_x; x1 = n.stem_x; }
for (int mark = 0; mark < n.source->tremolo_marks; ++mark) {
for (auto mark = std::int32_t{}; mark < n.source->tremolo_marks; ++mark) {
auto y = n.stem_tip_y + (n.stem_up ? 1.0F : -1.0F) * spacing * (1.0F + mark*0.8F);
add_stroke_line(layout, vamp_zero::score_layout_item_role::TREMOLO, {.x=x0,.y=y+spacing*0.3F},
{.x=x1,.y=y-spacing*0.3F}, spacing*0.45F, score_ink(), system_index, measure_index, n.note_index);
+3 -3
View File
@@ -445,7 +445,7 @@ auto vamp_zero::zero_ui::arm_pending_tap() -> void {
if (error) {
return;
}
auto send_next = false;
auto send_next = std::bool_t{false};
{
auto lock = std::scoped_lock{touch_mutex_};
send_next = pending_tap_;
@@ -462,9 +462,9 @@ auto vamp_zero::zero_ui::handle_touch(luma::touch_event const& event) -> std::bo
return false;
}
auto consumed = false;
auto consumed = std::bool_t{false};
auto commands = std::vector<vamp_protocol::page_command>{};
auto arm_tap = false;
auto arm_tap = std::bool_t{false};
{
auto lock = std::scoped_lock{touch_mutex_};
for (auto const& point : event.points) {
+5 -5
View File
@@ -12,7 +12,7 @@
namespace {
class score_view final : public luma::control {
public:
score_view(luma::application& app, vamp_zero::score_document score, std::string output, std::size_t page, bool& saved)
score_view(luma::application& app, vamp_zero::score_document score, std::string output, std::size_t page, std::bool_t& saved)
: app_{app}, score_{std::move(score)}, output_{std::move(output)}, page_{page}, saved_{saved} {}
auto measure(luma::draw_context&, luma::theme const&, luma::constraints) -> luma::size override { return {976,484}; }
auto draw(luma::draw_context& context, luma::theme const&) const -> void override {
@@ -28,18 +28,18 @@ private:
vamp_zero::score_document score_;
std::string output_;
std::size_t page_;
bool& saved_;
std::bool_t& saved_;
};
}
int main(int argc, char** argv) {
int main(int argc, std::char_t** argv) {
if (argc < 3) { std::cerr << "Usage: vamp-render-score input.json output.png [page]\n"; return 2; }
auto input = std::ifstream{argv[1]};
auto json = std::string{std::istreambuf_iterator<char>{input},std::istreambuf_iterator<char>{}};
auto json = std::string{std::istreambuf_iterator<std::char_t>{input},std::istreambuf_iterator<std::char_t>{}};
auto score = vamp_zero::parse_score_document(json,argv[1]);
if (!score) { std::cerr << score.error().describe() << '\n'; return 1; }
auto app = luma::application{{.title="Notation Regression",.display={.width=976,.height=484,.target_fps=30,.fullscreen=false}}};
auto saved = false;
auto saved = std::bool_t{false};
auto root = app.set_root(std::make_unique<score_view>(app,std::move(*score),argv[2],argc>3 ? std::stoul(argv[3]) : 0,saved));
if (!root) return 1;
auto ran = app.run();
+10 -10
View File
@@ -421,13 +421,13 @@ BOOST_AUTO_TEST_CASE(main_menu_toggles_audio_settings_and_edits_tempo) {
BOOST_TEST(state.selected_main_menu_index == 2U);
state = vamp_zero::apply_app_command(std::move(state), vamp_protocol::page_command::SELECT);
BOOST_TEST(state.audio.track_enabled);
BOOST_TEST(static_cast<int>(state.mode) == static_cast<int>(vamp_zero::app_mode::MAIN_MENU));
BOOST_TEST(static_cast<std::int32_t>(state.mode) == static_cast<std::int32_t>(vamp_zero::app_mode::MAIN_MENU));
state = vamp_zero::apply_app_command(std::move(state), vamp_protocol::page_command::NEXT);
BOOST_TEST(state.selected_main_menu_index == 3U);
state = vamp_zero::apply_app_command(std::move(state), vamp_protocol::page_command::SELECT);
BOOST_TEST(state.audio.metronome_enabled);
BOOST_TEST(static_cast<int>(state.mode) == static_cast<int>(vamp_zero::app_mode::MAIN_MENU));
BOOST_TEST(static_cast<std::int32_t>(state.mode) == static_cast<std::int32_t>(vamp_zero::app_mode::MAIN_MENU));
state = vamp_zero::apply_app_command(std::move(state), vamp_protocol::page_command::NEXT);
BOOST_TEST(state.selected_main_menu_index == 4U);
@@ -437,11 +437,11 @@ BOOST_AUTO_TEST_CASE(main_menu_toggles_audio_settings_and_edits_tempo) {
BOOST_TEST(state.audio.metronome_bpm == 125U);
state = vamp_zero::apply_app_command(std::move(state), vamp_protocol::page_command::PREVIOUS);
BOOST_TEST(state.audio.metronome_bpm == 120U);
for (auto index = 0; index < 40; ++index) {
for (auto index = std::int32_t{}; index < 40; ++index) {
state = vamp_zero::apply_app_command(std::move(state), vamp_protocol::page_command::PREVIOUS);
}
BOOST_TEST(state.audio.metronome_bpm == 40U);
for (auto index = 0; index < 80; ++index) {
for (auto index = std::int32_t{}; index < 80; ++index) {
state = vamp_zero::apply_app_command(std::move(state), vamp_protocol::page_command::NEXT);
}
BOOST_TEST(state.audio.metronome_bpm == 240U);
@@ -472,21 +472,21 @@ BOOST_AUTO_TEST_CASE(main_menu_metronome_setting_survives_score_selection) {
state.audio.metronome_enabled = true;
state = vamp_zero::apply_app_command(std::move(state), vamp_protocol::page_command::SELECT);
BOOST_TEST(static_cast<int>(state.mode) == static_cast<int>(vamp_zero::app_mode::PERFORMANCE_SONG_MENU));
BOOST_TEST(static_cast<std::int32_t>(state.mode) == static_cast<std::int32_t>(vamp_zero::app_mode::PERFORMANCE_SONG_MENU));
state = vamp_zero::apply_app_command(std::move(state), vamp_protocol::page_command::NEXT);
state = vamp_zero::apply_app_command(std::move(state), vamp_protocol::page_command::SELECT);
BOOST_TEST(static_cast<int>(state.mode) == static_cast<int>(vamp_zero::app_mode::PERFORMANCE_PART_MENU));
BOOST_TEST(static_cast<std::int32_t>(state.mode) == static_cast<std::int32_t>(vamp_zero::app_mode::PERFORMANCE_PART_MENU));
state = vamp_zero::apply_app_command(std::move(state), vamp_protocol::page_command::NEXT);
state = vamp_zero::apply_app_command(std::move(state), vamp_protocol::page_command::SELECT);
BOOST_TEST(static_cast<int>(state.mode) == static_cast<int>(vamp_zero::app_mode::PERFORMANCE_SCORE));
BOOST_TEST(static_cast<std::int32_t>(state.mode) == static_cast<std::int32_t>(vamp_zero::app_mode::PERFORMANCE_SCORE));
BOOST_TEST(state.audio.metronome_enabled);
BOOST_TEST(!state.audio.tempo_editing);
}
BOOST_AUTO_TEST_CASE(score_parser_preserves_notation_preamble) {
auto parsed = vamp_zero::parse_score_document(score_asset_json("Standard Tune", "Eb"), "standard-tune.json");
BOOST_REQUIRE(static_cast<bool>(parsed));
BOOST_REQUIRE(static_cast<std::bool_t>(parsed));
BOOST_TEST(parsed->title == "Standard Tune");
BOOST_TEST(parsed->composer == "Composer");
BOOST_TEST(parsed->key_signature == "Eb");
@@ -503,7 +503,7 @@ BOOST_AUTO_TEST_CASE(score_parser_loads_the_generated_catalogue) {
for (auto const& entry : std::filesystem::recursive_directory_iterator{VAMP_TEST_ASSETS_DIR}) {
if (entry.path().extension() != ".json") continue;
auto input = std::ifstream{entry.path()};
auto json = std::string{std::istreambuf_iterator<char>{input}, std::istreambuf_iterator<char>{}};
auto json = std::string{std::istreambuf_iterator<std::char_t>{input}, std::istreambuf_iterator<std::char_t>{}};
auto parsed = vamp_zero::parse_score_document(json, entry.path().string());
BOOST_TEST_CONTEXT(entry.path().string()) {
BOOST_REQUIRE(parsed.has_value());
@@ -558,7 +558,7 @@ BOOST_AUTO_TEST_CASE(score_layout_supports_all_written_durations_and_multiple_do
BOOST_AUTO_TEST_CASE(score_layout_paginates_dense_measures_without_losing_events) {
auto notes = std::vector<vamp_zero::score_note>{};
for (int i = 0; i < 128; ++i) {
for (auto i = std::int32_t{}; i < 128; ++i) {
auto n = note_with_ticks({pitch('c',"#",4)},128);
n.written = {.type="128th"};
n.duration = {1,32};
+10
View File
@@ -9,9 +9,19 @@ from pathlib import Path
from generator.__main__ import copy_runtime_fonts
from tools import generate_pico_font
from tools import generate_score_metrics
class FontAssetsTests(unittest.TestCase):
def test_score_metrics_use_fixed_width_codepoints(self):
root = Path(__file__).resolve().parents[1]
with tempfile.TemporaryDirectory() as directory:
output = Path(directory) / "generated/score_metrics.hpp"
generate_score_metrics.generate(root / "package/assets/fonts/petaluma/Petaluma.otf", output)
content = output.read_text(encoding="ascii")
self.assertIn("#include <cstdint>", content)
self.assertIn("std::int32_t codepoint", content)
def test_font_generator_requires_kerning_backend(self):
with unittest.mock.patch.object(generate_pico_font.features, "check_feature", return_value=False):
with self.assertRaisesRegex(RuntimeError, "Raqm"):
+2 -2
View File
@@ -24,8 +24,8 @@ def generate(font_path, output):
box = ', '.join(f'{v / units:.8f}F' for v in pen.bounds)
records.append(f' {{{codepoint}, {{{box}}}}},')
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text('#pragma once\n#include <array>\nnamespace vamp_zero::font_data {\n'
'struct glyph { int codepoint; std::array<float, 4> bounds; };\n'
output.write_text('#pragma once\n#include <array>\n#include <cstdint>\nnamespace vamp_zero::font_data {\n'
'struct glyph { std::int32_t codepoint; std::array<float, 4> bounds; };\n'
f'inline constexpr std::array<glyph, {len(records)}> glyphs = {{{{\n'
+ '\n'.join(records) + '\n}};\n}\n', encoding='ascii')