summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--AudioPlayer.cpp43
-rw-r--r--AudioPlayer.h22
-rw-r--r--MIDIPlayer.cpp41
-rw-r--r--MIDIPlayer.h6
-rw-r--r--Makefile3
-rw-r--r--midiplay.cpp7
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;
};
diff --git a/Makefile b/Makefile
index 2199c43..f841932 100644
--- a/Makefile
+++ b/Makefile
@@ -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) {