From 91b3d481393703b8532fe7b8be15f01182ae6136 Mon Sep 17 00:00:00 2001 From: Jay Robson Date: Mon, 30 Sep 2024 23:24:48 +1000 Subject: [PATCH] improvements --- src/binary.cpp | 2 ++ src/device.cpp | 5 ++++- src/device.hpp | 9 ++++++--- src/packet.cpp | 14 +++++++++++++- src/packet.hpp | 29 ++++++++++++++++++++++------- src/scheduler.cpp | 30 ++++++++++++++++++++---------- src/scheduler.hpp | 2 ++ src/streamer.cpp | 9 +++++++++ 8 files changed, 78 insertions(+), 22 deletions(-) diff --git a/src/binary.cpp b/src/binary.cpp index d24415b..374f0f5 100644 --- a/src/binary.cpp +++ b/src/binary.cpp @@ -3,8 +3,10 @@ #include "packet.hpp" #include "scheduler.hpp" #include "../midifile/include/MidiFile.h" +#include #include #include +#include unsigned binary::process(std::ostream& dst, const char* path) { smf::MidiFile midifile; diff --git a/src/device.cpp b/src/device.cpp index 3149b0c..373a602 100644 --- a/src/device.cpp +++ b/src/device.cpp @@ -43,7 +43,10 @@ void Device::write(const char* data, size_t len) { } void Device::read(char* data, size_t len) { - ::read(fd, data, len); + size_t recorded = 0; + while(recorded < len) { + recorded += ::read(fd, &data[recorded], len - recorded); + } } void Device::put(char ch) { diff --git a/src/device.hpp b/src/device.hpp index 1b301de..16ac8f3 100644 --- a/src/device.hpp +++ b/src/device.hpp @@ -3,6 +3,7 @@ #include #include +#include struct Device { @@ -25,9 +26,11 @@ struct Device { template void printf(const char* format, Args... args) { - char buff[1024]; - size_t len = std::snprintf(buff, sizeof(buff), format, args...); - write(buff, len); + size_t len = std::snprintf(nullptr, 0, format, args...) + 1; + static std::vector buff; + buff.resize(len); + len = std::snprintf(buff.data(), len, args...); + write(buff.data(), len); } bool fingerprint_valid; diff --git a/src/packet.cpp b/src/packet.cpp index 88ff896..423c2e3 100644 --- a/src/packet.cpp +++ b/src/packet.cpp @@ -45,7 +45,16 @@ void packet::Config::finalise(std::ostream& dst) const { uint8_t* a_data = (uint8_t*)&litude; v = (v << 29) | (us_per_tick & bm(29)); v = (v << 8) | (amplitude & bm(8)); - output(dst, v, 5); + v = (v << 24) | (size & bm(24)); + output(dst, v, 8); +} + +void packet::Tempo::finalise(std::ostream& dst) const { + uint64_t v = Type::tempo & bm(3); + v = (v << 29) | (us_per_tick & bm(29)); + v = (v << 20) | (ticks & bm(20)); + v <<= 4; + output(dst, v, 7); } void packet::Stop::finalise(std::ostream& dst) const { @@ -72,6 +81,9 @@ void packet::Generic::finalise(std::ostream& dst) const { case Type::stop: stop.finalise(dst); break; + case Type::tempo: + tempo.finalise(dst); + break; } } diff --git a/src/packet.hpp b/src/packet.hpp index fad1242..eaf51dc 100644 --- a/src/packet.hpp +++ b/src/packet.hpp @@ -7,12 +7,13 @@ namespace packet { enum Type : unsigned { - stop, - config, - set, - set_ts, - clear, - clear_ts, + stop = 0, + config = 1, + set = 2, + set_ts = 3, + clear = 4, + clear_ts = 5, + tempo = 6, }; struct Stop { @@ -50,10 +51,18 @@ namespace packet { struct Config { unsigned us_per_tick; unsigned amplitude; + unsigned size; void finalise(std::ostream& dst) const; }; + struct Tempo { + unsigned us_per_tick; + unsigned ticks; + + void finalise(std::ostream& dst) const; + }; + constexpr std::size_t get_size(Type type) { switch(type) { case Type::clear: @@ -66,8 +75,10 @@ namespace packet { return 5; case Type::stop: return 1; + case Type::tempo: + return 7; case Type::config: - return 5; + return 8; } return 1; } @@ -81,8 +92,12 @@ namespace packet { Clear clear; ClearTS clear_ts; Config config; + Tempo tempo; }; void finalise(std::ostream& dst) const; + constexpr std::size_t size() const { + return get_size(type); + } }; }; diff --git a/src/scheduler.cpp b/src/scheduler.cpp index 938e18e..00a0ba7 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include Scheduler::Scheduler(double s_per_tick) : us_per_tick(s_per_tick * 1e6) { @@ -16,7 +15,7 @@ bool Scheduler::add_note(unsigned id, unsigned ticks, bool state) { if(id >= keys.size()) { keys.resize(id + 1); } - + if(!state) { unsigned channel = keys[id].channel; if(!keys[id].active) { @@ -35,22 +34,23 @@ bool Scheduler::add_note(unsigned id, unsigned ticks, bool state) { return true; } - unsigned channel_id = -1; - if(keys[id].active) { return false; } + + unsigned channel_id = -1; - for(unsigned i = 0;; i++) { - if(i >= std::size(channels)) { - return false; - } + for(unsigned i = 0; i < channels.size(); i++) { if(!channels[i].active) { channel_id = i; break; } } + if(channel_id == -1) { + return false; + } + if(ticks_at >= ticks) { packets.push_back({.type=packet::Type::set, .set={.index=channel_id, .frequency=key::get_freq(id)}}); } else { @@ -69,11 +69,21 @@ bool Scheduler::add_note(unsigned id, unsigned ticks, bool state) { return true; } +void Scheduler::add_tempo_change(uint32_t tempo, unsigned ticks) { + packets.push_back({.type=packet::Type::tempo, .tempo={.us_per_tick=tempo, .ticks=ticks}}); + std::cerr << "Tempo change! " << tempo << " : " << ticks << std::endl; +} + void Scheduler::finalise(std::ostream& dst) const { unsigned amplitude = std::round(std::max(1.f / channels_in_use_max, 1.f/8.f) * 255); - packet::Generic packet_start {.type=packet::Type::config, .config={.us_per_tick=us_per_tick, .amplitude=amplitude}}; - packet_start.finalise(dst); + unsigned size = 0; + + for(const packet::Generic& packet : packets) { + size += packet.size(); + } + + packet::Generic {.type=packet::Type::config, .config={.us_per_tick=us_per_tick, .amplitude=amplitude, .size=size}}.finalise(dst); for(const packet::Generic& packet : packets) { packet.finalise(dst); diff --git a/src/scheduler.hpp b/src/scheduler.hpp index 3780c3e..915b9aa 100644 --- a/src/scheduler.hpp +++ b/src/scheduler.hpp @@ -3,6 +3,7 @@ #include "packet.hpp" #include +#include #include #include @@ -21,6 +22,7 @@ struct Scheduler { Scheduler(double s_per_tick); bool add_note(unsigned key, unsigned ticks, bool active); + void add_tempo_change(std::uint32_t tempo, unsigned ticks); void finalise(std::ostream& os) const; void display(std::ostream& os) const; diff --git a/src/streamer.cpp b/src/streamer.cpp index 6350cb8..1993d3d 100644 --- a/src/streamer.cpp +++ b/src/streamer.cpp @@ -22,6 +22,10 @@ static void display_progress(unsigned long at, unsigned long size) { unsigned long screen_at = at * cols / size; unsigned percent_at = (at * 100 / size); + std::vector bytes_str(std::snprintf(nullptr, 0, " %lu B / %lu B ", at, size) + 1); + std::snprintf(bytes_str.data(), bytes_str.size(), " %lu B / %lu B ", at, size); + unsigned bytes_str_pos = cols / 2 - bytes_str.size() / 2; + if(screen_at == screen_at_last && percent_at == percent_at_last) { return; } @@ -41,6 +45,11 @@ static void display_progress(unsigned long at, unsigned long size) { ch = '='; } std::cout << ch; + + if(i == bytes_str_pos) { + std::cout.write(bytes_str.data(), bytes_str.size()); + i += bytes_str.size(); + } } std::cout << "] " << percent_at << "%\r" << std::flush;