added multiple waveforms

This commit is contained in:
Jay Robson 2024-10-03 02:28:47 +10:00
parent 91b3d48139
commit 34f26ae46f
6 changed files with 64 additions and 41 deletions

View File

@ -7,11 +7,13 @@
#include <ostream>
#include <sstream>
#include <string>
#include <vector>
unsigned binary::process(std::ostream& dst, const char* path) {
smf::MidiFile midifile;
midifile.read(path);
midifile.doTimeAnalysis();
std::vector<packet::ToneType> track_modes(midifile.getNumTracks(), packet::ToneType::tt_sine);
midifile.joinTracks();
Scheduler scheduler(midifile.getTimeInSeconds(1));
@ -22,12 +24,35 @@ unsigned binary::process(std::ostream& dst, const char* path) {
for(int i = 0; i < track.size(); i++) {
smf::MidiEvent& note = track[i];
if(note.isTrackName()) {
std::string name = note.getMetaContent();
for(int i = 0; i < name.length(); i++) {
char c = name[i];
if(c >= 'A' && c <= 'Z') {
name[i] = c + 32;
}
}
if(name.find("saw") != std::string::npos) {
track_modes[note.track] = packet::ToneType::tt_saw;
}
else if(name.find("square") != std::string::npos || name.find("distortion") != std::string::npos || name.find("overdrive") != std::string::npos) {
track_modes[note.track] = packet::ToneType::tt_square;
}
else if(name.find("triangle") != std::string::npos) {
track_modes[note.track] = packet::ToneType::tt_triangle;
}
}
if(!note.isNote()) {
continue;
}
smf::MidiEvent& note_end = *note.getLinkedEvent();
scheduler.add_note(note.getKeyNumber(), note.tick, note.isNoteOn());
scheduler.add_note(note.getKeyNumber(), note.tick, note.isNoteOn(), track_modes[note.track]);
notes_added++;
}

View File

@ -21,7 +21,20 @@ Device::Device(const char* path) {
char buff[8];
read(buff, sizeof(buff));
fingerprint_valid = (std::memcmp(buff, "\x19\xc1\x6c\x19\x5b\x6f\xd2\x44", sizeof(buff)) == 0);
for(;;) {
fingerprint_valid = (std::memcmp(buff, "\x19\xc1\x6c\x19\x5b\x6f\xd2\x44", sizeof(buff)) == 0);
if(fingerprint_valid) {
break;
}
for(int i = 1; i < sizeof(buff); i++) {
buff[i - 1] = buff[i];
}
read(&buff[7], 1);
}
}
Device::~Device() {

View File

@ -19,8 +19,8 @@ void packet::Clear::finalise(std::ostream& dst) const {
void packet::ClearTS::finalise(std::ostream& dst) const {
uint64_t v = Type::clear_ts & bm(3);
v = (v << 5) | (index & bm(5));
v = (v << 20) | (ticks & bm(20));
v <<= 4;
v = (v << 18) | (ticks & bm(18));
v <<= 6;
output(dst, v, 4);
}
@ -28,15 +28,17 @@ void packet::Set::finalise(std::ostream& dst) const {
uint64_t v = Type::set & bm(3);
v = (v << 5) | (index & bm(5));
v = (v << 12) | (frequency & bm(12));
v <<= 4;
v = (v << 2) | (mode & bm(2));
v <<= 2;
output(dst, v, 3);
}
void packet::SetTS::finalise(std::ostream& dst) const {
uint64_t v = Type::set_ts & bm(3);
v = (v << 5) | (index & bm(5));
v = (v << 20) | (ticks & bm(20));
v = (v << 18) | (ticks & bm(18));
v = (v << 12) | (frequency & bm(12));
v = (v << 2) | (mode & bm(2));
output(dst, v, 5);
}
@ -49,14 +51,6 @@ void packet::Config::finalise(std::ostream& dst) const {
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 {
dst.put(Type::stop << 5);
}
@ -81,9 +75,6 @@ void packet::Generic::finalise(std::ostream& dst) const {
case Type::stop:
stop.finalise(dst);
break;
case Type::tempo:
tempo.finalise(dst);
break;
}
}

View File

@ -13,7 +13,13 @@ namespace packet {
set_ts = 3,
clear = 4,
clear_ts = 5,
tempo = 6,
};
enum ToneType : unsigned {
tt_sine = 0,
tt_saw = 1,
tt_square = 2,
tt_triangle = 3,
};
struct Stop {
@ -23,6 +29,7 @@ namespace packet {
struct Set {
unsigned index;
unsigned frequency;
ToneType mode;
void finalise(std::ostream& dst) const;
};
@ -31,6 +38,7 @@ namespace packet {
unsigned index;
unsigned ticks;
unsigned frequency;
ToneType mode;
void finalise(std::ostream& dst) const;
};
@ -56,13 +64,6 @@ namespace packet {
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:
@ -75,8 +76,6 @@ namespace packet {
return 5;
case Type::stop:
return 1;
case Type::tempo:
return 7;
case Type::config:
return 8;
}
@ -92,7 +91,6 @@ namespace packet {
Clear clear;
ClearTS clear_ts;
Config config;
Tempo tempo;
};
void finalise(std::ostream& dst) const;
constexpr std::size_t size() const {

View File

@ -7,10 +7,13 @@
#include <iostream>
#include <ostream>
Scheduler::Scheduler(double s_per_tick) : us_per_tick(s_per_tick * 1e6) {
Scheduler::Scheduler(double s_per_tick)
: us_per_tick(s_per_tick * 1e6) {
}
bool Scheduler::add_note(unsigned id, unsigned ticks, bool state) {
bool Scheduler::add_note(unsigned key_id, unsigned ticks, bool state, packet::ToneType mode) {
unsigned id = key_id * (mode + 1);
if(id >= keys.size()) {
keys.resize(id + 1);
@ -52,9 +55,9 @@ bool Scheduler::add_note(unsigned id, unsigned ticks, bool state) {
}
if(ticks_at >= ticks) {
packets.push_back({.type=packet::Type::set, .set={.index=channel_id, .frequency=key::get_freq(id)}});
packets.push_back({.type=packet::Type::set, .set={.index=channel_id, .frequency=key::get_freq(key_id), .mode=mode}});
} else {
packets.push_back({.type=packet::Type::set_ts, .set_ts={.index=channel_id, .ticks=ticks, .frequency=key::get_freq(id)}});
packets.push_back({.type=packet::Type::set_ts, .set_ts={.index=channel_id, .ticks=ticks, .frequency=key::get_freq(key_id), .mode=mode}});
ticks_at = ticks;
}
@ -69,11 +72,6 @@ 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);
@ -95,7 +93,7 @@ void Scheduler::display(std::ostream& os) const {
os << " + ";
for(int i = 0; i < keys.size(); i++) {
os << (keys[i].active ? '|' : ' ');
// os << (keys[i].active ? '|' : ' ');
}
os << " + ";

View File

@ -3,7 +3,6 @@
#include "packet.hpp"
#include <array>
#include <cstdint>
#include <ostream>
#include <vector>
@ -21,8 +20,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);
bool add_note(unsigned key, unsigned ticks, bool active, packet::ToneType mode);
void finalise(std::ostream& os) const;
void display(std::ostream& os) const;