improvements

This commit is contained in:
Jay Robson 2024-09-30 23:24:48 +10:00
parent 575b03337e
commit 91b3d48139
8 changed files with 78 additions and 22 deletions

View File

@ -3,8 +3,10 @@
#include "packet.hpp"
#include "scheduler.hpp"
#include "../midifile/include/MidiFile.h"
#include <iostream>
#include <ostream>
#include <sstream>
#include <string>
unsigned binary::process(std::ostream& dst, const char* path) {
smf::MidiFile midifile;

View File

@ -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) {

View File

@ -3,6 +3,7 @@
#include <cstddef>
#include <cstdio>
#include <vector>
struct Device {
@ -25,9 +26,11 @@ struct Device {
template<typename... Args>
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<char> buff;
buff.resize(len);
len = std::snprintf(buff.data(), len, args...);
write(buff.data(), len);
}
bool fingerprint_valid;

View File

@ -45,7 +45,16 @@ void packet::Config::finalise(std::ostream& dst) const {
uint8_t* a_data = (uint8_t*)&amplitude;
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;
}
}

View File

@ -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);
}
};
};

View File

@ -5,7 +5,6 @@
#include <algorithm>
#include <cmath>
#include <iostream>
#include <iterator>
#include <ostream>
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);

View File

@ -3,6 +3,7 @@
#include "packet.hpp"
#include <array>
#include <cstdint>
#include <ostream>
#include <vector>
@ -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;

View File

@ -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<char> 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;