#include "MIDIPlayer.h" #include #include #include #include #include #include namespace bp = boost::process; namespace fs = std::filesystem; using namespace std::chrono_literals; MIDIPlayer::MIDIPlayer(const std::filesystem::path& path): m_child{}, m_dir{path}, m_file{} { std::vector list = get_filelist(); if (list.size() > 0) { m_file = list[0]; } } void MIDIPlayer::start() { if (m_child.valid() && m_child.running()) { stop(); } else { m_child = bp::child(fmt::format("aplaymidi -p24 \"{}\"", m_file).c_str());//, bp::std_out > bp::null); } } void MIDIPlayer::stop() { // note:: m_child.terminate() would kill via SIGKILL, preventing note offs if (m_child.valid()) { int result = kill(m_child.native_handle(), SIGTERM); if (result < 0) { std::cerr << "Error in MIDIPlayer::stop(): kill() unsuccessful\n"; } } } bool MIDIPlayer::is_playing() { if (!m_child.valid()) { return false; } return m_child.running(); } void MIDIPlayer::set_file(const std::string& filename) { m_file = filename; if (is_playing()) { stop(); std::this_thread::sleep_for(100ms); start(); } } std::string MIDIPlayer::get_file() { return m_file; } std::vector MIDIPlayer::get_filelist() { std::vector result; for (auto const& dir_entry: fs::directory_iterator{m_dir}) { fs::path entry{dir_entry.path()}; fs::path extension = entry.extension(); if (extension == ".midi" || extension == ".mid") { result.push_back(entry.filename()); } if (result.size() == 99) { break; } } std::sort(result.begin(), result.end()); return result; }