diff options
-rw-r--r-- | AudioPlayer.cpp | 43 | ||||
-rw-r--r-- | AudioPlayer.h | 22 | ||||
-rw-r--r-- | MIDIPlayer.cpp | 41 | ||||
-rw-r--r-- | MIDIPlayer.h | 6 | ||||
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | midiplay.cpp | 7 |
6 files changed, 103 insertions, 19 deletions
diff --git a/AudioPlayer.cpp b/AudioPlayer.cpp new file mode 100644 index 0000000..e60ae1d --- /dev/null +++ b/AudioPlayer.cpp @@ -0,0 +1,43 @@ +#include "AudioPlayer.h" + +#include <iostream> + +#include <fmt/format.h> + +namespace bp = boost::process; +namespace fs = std::filesystem; + +AudioPlayer::AudioPlayer(const fs::path& dir, const std::string& filename): m_dir(dir), m_file(filename) +{ +} + +void AudioPlayer::start() +{ + if (m_child_audioplayer.valid() && m_child_audioplayer.running()) { + stop(); + } + if (!m_file.empty()) { + m_child_audioplayer = bp::child(fmt::format("aplay \"{}\"", (m_dir / m_file).string()).c_str());//, bp::std_out > bp::null); + if (!m_child_audioplayer.valid() || !m_child_audioplayer.running()) { + throw std::runtime_error("aplay not started"); + } + } +} + +void AudioPlayer::stop() +{ + // note:: m_child_audioplayer.terminate() would kill via SIGKILL + + if (m_child_audioplayer.valid()) { + int result = kill(m_child_audioplayer.native_handle(), SIGTERM); + if (result < 0) { + std::cerr << "Error in AudioPlayer::stop(): kill() unsuccessful\n"; + } + } +} + +void AudioPlayer::set_file(const std::string& filename) +{ + m_file = filename; +} + diff --git a/AudioPlayer.h b/AudioPlayer.h new file mode 100644 index 0000000..7f9c180 --- /dev/null +++ b/AudioPlayer.h @@ -0,0 +1,22 @@ +#pragma once + +#include <boost/process.hpp> + +#include <filesystem> + +class AudioPlayer +{ +public: + AudioPlayer(const std::filesystem::path& dir, const std::string& filename); + + void start(); + + void stop(); + + void set_file(const std::string& filename); + +private: + std::filesystem::path m_dir; + std::string m_file; + boost::process::child m_child_audioplayer; +}; diff --git a/MIDIPlayer.cpp b/MIDIPlayer.cpp index cb6a6bf..6b07105 100644 --- a/MIDIPlayer.cpp +++ b/MIDIPlayer.cpp @@ -20,13 +20,23 @@ using namespace std::chrono_literals; namespace { std::unordered_set<std::string> supported_devices{"AudioBox 22 VSL", "CH345", "M2"}; + + fs::path wav_from_midi(const fs::path& midipath) + { + fs::path result{midipath}; + + result.replace_extension("wav"); + + return result; + } } MIDIPlayer::MIDIPlayer(Config& config): m_config(config), - m_child{}, + m_child_midiplayer{}, m_dir{m_config.get_file_path()}, - m_file{} + m_file{}, + m_audio_player{m_dir, m_file} { std::vector<std::string> list = get_filelist(); @@ -41,34 +51,37 @@ MIDIPlayer::MIDIPlayer(Config& config): void MIDIPlayer::start() { - if (m_child.valid() && m_child.running()) { + if (m_child_midiplayer.valid() && m_child_midiplayer.running()) { stop(); - } else { - m_child = bp::child(fmt::format("aplaymidi-mp -c -p{} \"{}\"", m_client, (m_dir / m_file).string()).c_str());//, bp::std_out > bp::null); - if (!m_child.valid() || !m_child.running()) { - throw std::runtime_error("aplaymidi not started"); - } } + m_child_midiplayer = bp::child(fmt::format("aplaymidi-mp -c -p{} \"{}\"", m_client, (m_dir / m_file).string()).c_str());//, bp::std_out > bp::null); + if (!m_child_midiplayer.valid() || !m_child_midiplayer.running()) { + throw std::runtime_error("aplaymidi not started"); + } + + m_audio_player.start(); } void MIDIPlayer::stop() { - // note:: m_child.terminate() would kill via SIGKILL, preventing note offs + // note:: m_child_midiplayer.terminate() would kill via SIGKILL - if (m_child.valid()) { - int result = kill(m_child.native_handle(), SIGTERM); + if (m_child_midiplayer.valid()) { + int result = kill(m_child_midiplayer.native_handle(), SIGTERM); if (result < 0) { std::cerr << "Error in MIDIPlayer::stop(): kill() unsuccessful\n"; } } + + m_audio_player.stop(); } bool MIDIPlayer::is_playing() { - if (!m_child.valid()) { + if (!m_child_midiplayer.valid()) { return false; } - return m_child.running(); + return m_child_midiplayer.running(); } void MIDIPlayer::set_file(const std::string& filename) @@ -80,6 +93,8 @@ void MIDIPlayer::set_file(const std::string& filename) std::this_thread::sleep_for(100ms); start(); } + + m_audio_player.set_file(wav_from_midi(filename)); } std::string MIDIPlayer::get_file() diff --git a/MIDIPlayer.h b/MIDIPlayer.h index 8009029..2b3e994 100644 --- a/MIDIPlayer.h +++ b/MIDIPlayer.h @@ -1,5 +1,7 @@ #pragma once +#include "AudioPlayer.h" + #include <string> #include <vector> @@ -35,11 +37,13 @@ private: void iterate_ports(void); Config& m_config; - boost::process::child m_child; + boost::process::child m_child_midiplayer; std::filesystem::path m_dir; std::string m_file; snd_seq_t* m_seq; int m_client; + + AudioPlayer m_audio_player; }; @@ -3,6 +3,7 @@ TARGET=midiplay-fcgi SRCS=\ midiplay.cpp \ MIDIPlayer.cpp \ + AudioPlayer.cpp \ config.cpp \ OBJS=$(SRCS:.cpp=.o) @@ -19,7 +20,7 @@ CFLAGS=-Wall -g -O2 -fPIC CFLAGS+=-gdwarf-4 CLIBS=-lasound -all: $(TARGET) aplaymidi-mp +all: $(TARGET) #aplaymidi-mp run-fcgi: spawn-fcgi -a 127.0.0.1 -p 9090 -n -- ./midiplay-fcgi diff --git a/midiplay.cpp b/midiplay.cpp index 36b732e..534508f 100644 --- a/midiplay.cpp +++ b/midiplay.cpp @@ -103,10 +103,10 @@ int main(int argc, char* argv[]) { while (FCGX_Accept_r(&request) == 0) { std::string method = FCGX_GetParam("REQUEST_METHOD", request.envp); + FCGX_PutS("Content-Type: text/xml\r\n\r\n", request.out); + try { if (method == "POST") { - FCGX_PutS("Content-Type: text/xml\r\n\r\n", request.out); - PostData data{request}; std::string command {getCommand(request)}; if (command == "start") { @@ -128,8 +128,7 @@ int main(int argc, char* argv[]) { throw std::runtime_error(fmt::format("Bad request method: POST expected, got {}", method).c_str()); } } catch (const std::exception& ex) { - FCGX_PutS("Content-Type: text/xml\r\n\r\n", request.out); - FCGX_PutS(("<data><status>error</status><message>"s + ex.what() + "</message></data>").c_str(), request.out); + FCGX_PutS(("<data><status>error</status><message>Error: "s + ex.what() + "</message></data>").c_str(), request.out); } } } catch (const std::exception& ex) { |