improved build process
This commit is contained in:
parent
dff58483e6
commit
3bf8d3b91b
|
@ -1,3 +1,4 @@
|
|||
|
||||
/midi-parser
|
||||
/build
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
cmake_minimum_required(VERSION 3.30)
|
||||
|
||||
project(midi-parser)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 26)
|
||||
set(CMAKE_CXX_FLAGS "-g")
|
||||
|
||||
set(SRCS
|
||||
src/main.cpp
|
||||
src/device.cpp
|
||||
src/key.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(midifile)
|
||||
add_executable(midi-parser ${SRCS})
|
||||
|
||||
target_link_libraries(midi-parser PRIVATE midifile PUBLIC stdc++)
|
||||
|
6
build.sh
6
build.sh
|
@ -1,6 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd midifile && cmake . && make && cd ..
|
||||
|
||||
g++ src/main.cpp ./midifile/libmidifile.a -o midi-parser -g -O3
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
#include "device.hpp"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
Device::Device(const char* path) {
|
||||
fd = ::open(path, O_RDWR);
|
||||
}
|
||||
|
||||
Device::~Device() {
|
||||
::close(fd);
|
||||
}
|
||||
|
||||
Device::operator int() {
|
||||
return fd;
|
||||
}
|
||||
|
||||
void Device::print(const char* data) {
|
||||
for(size_t i = 0; data[i] != '\0'; i++) {
|
||||
::write(fd, &data[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Device::write(const char* data, size_t len) {
|
||||
::write(fd, data, len);
|
||||
}
|
||||
|
||||
void Device::read(char* data, size_t len) {
|
||||
::read(fd, data, len);
|
||||
}
|
||||
|
||||
void Device::read_until(char target) {
|
||||
char ch;
|
||||
read(&ch, 1);
|
||||
while(ch != target) {
|
||||
read(&ch, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
|
||||
struct Device {
|
||||
Device(const char* path);
|
||||
~Device();
|
||||
operator int();
|
||||
void print(const char* data);
|
||||
void write(const char* data, size_t len);
|
||||
void read(char* data, size_t len);
|
||||
void read_until(char target = '\n');
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private:
|
||||
int fd;
|
||||
};
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
#include "key.hpp"
|
||||
#include <cmath>
|
||||
#include <iterator>
|
||||
|
||||
const double KEYS[] = {16.35, 17.32, 18.35, 19.45, 20.6, 21.83, 23.12, 24.5, 25.96, 27.5, 29.14, 30.87};
|
||||
|
||||
int key::get_freq(int key) {
|
||||
int octave = key / std::size(KEYS);
|
||||
return (int)std::round(KEYS[key % std::size(KEYS)] * std::pow(2, octave));
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
namespace key {
|
||||
|
||||
int get_freq(int key);
|
||||
};
|
||||
|
62
src/main.cpp
62
src/main.cpp
|
@ -3,34 +3,14 @@
|
|||
#include <cmath>
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <ostream>
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
|
||||
const double KEYS[] = {16.35, 17.32, 18.35, 19.45, 20.6, 21.83, 23.12, 24.5, 25.96, 27.5, 29.14, 30.87};
|
||||
|
||||
double get_key_freq(int key) {
|
||||
int octave = key / std::size(KEYS);
|
||||
return KEYS[key % std::size(KEYS)] * std::pow(2, octave);
|
||||
}
|
||||
|
||||
volatile std::sig_atomic_t running = true;
|
||||
|
||||
void signal_handler(int id) {
|
||||
std::cout << "Quitting\n";
|
||||
running = false;
|
||||
}
|
||||
#include "device.hpp"
|
||||
#include "key.hpp"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
std::signal(SIGINT, signal_handler);
|
||||
|
||||
smf::MidiFile midifile;
|
||||
midifile.read(argv[2]);
|
||||
|
||||
|
@ -54,16 +34,14 @@ int main(int argc, char** argv) {
|
|||
midifile.doTimeAnalysis();
|
||||
midifile.joinTracks();
|
||||
|
||||
std::ofstream device {argv[1], std::ios::binary};
|
||||
device << ":c,";
|
||||
device.flush();
|
||||
Device device(argv[1]);
|
||||
|
||||
auto& track = midifile[0];
|
||||
int current_pressed_keys = 0;
|
||||
int max_pressed_keys = 0;
|
||||
double time_end = 0;
|
||||
|
||||
for(int i = 0; i < track.size() && running; i++) {
|
||||
for(int i = 0; i < track.size(); i++) {
|
||||
smf::MidiEvent& event = track[i];
|
||||
|
||||
if(!event.isNote()) {
|
||||
|
@ -89,11 +67,15 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
}
|
||||
|
||||
double amplitude = 1.0 / max_pressed_keys;
|
||||
int tones_total = 0;
|
||||
double amplitude = std::max(1.0 / max_pressed_keys, 1.0/16.0);
|
||||
std::vector<int> channel_key_nums(max_pressed_keys, -1);
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
|
||||
for(int i = 0; i < track.size() && running; i++) {
|
||||
std::cout << "Seconds per tick: " << midifile.getTimeInSeconds(1) << std::endl;
|
||||
|
||||
device.printf(":w,o,%f,%d,", amplitude, (int)(midifile.getTimeInSeconds(1) * 1000000));
|
||||
|
||||
for(int i = 0; i < track.size(); i++) {
|
||||
smf::MidiEvent& event = track[i];
|
||||
|
||||
if(!event.isNote()) {
|
||||
|
@ -134,18 +116,14 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
end:
|
||||
|
||||
double key_freq = get_key_freq(key);
|
||||
|
||||
std::this_thread::sleep_until(now + std::chrono::duration<double>(event.seconds));
|
||||
device << ":s," << channel << "," << key_freq << ',';
|
||||
int key_freq = key::get_freq(key);
|
||||
|
||||
device.read_until();
|
||||
if(event.isNoteOn()) {
|
||||
device << std::max(amplitude, 1.0/16.0);
|
||||
device.printf("s,%d,%d,%d,", event.tick, channel, key_freq);
|
||||
} else {
|
||||
device << '0';
|
||||
device.printf("c,%d,%d,", event.tick, channel);
|
||||
}
|
||||
device << ',';
|
||||
device.flush();
|
||||
|
||||
if(i < track.size() - 1 && event.seconds == track[i + 1].seconds) {
|
||||
continue;
|
||||
|
@ -169,13 +147,15 @@ end:
|
|||
}
|
||||
}
|
||||
|
||||
std::cout << " + " << event.seconds << "s / " << time_end << "s" << std::endl;
|
||||
std::cout << " + " << event.seconds << "s / " << time_end << 's' << std::endl;
|
||||
tones_total++;
|
||||
}
|
||||
|
||||
device << ":c,";
|
||||
device.flush();
|
||||
device.read_until();
|
||||
device.printf(";,:p,");
|
||||
|
||||
std::cout << "Sent " << tones_total << " tones\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue