From 172cc05cb1f3d2b69b15cfe94c792e042a41b274 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Tue, 2 Feb 2021 19:14:09 +0100 Subject: Add alsamidi iput engine. --- configure.ac | 14 ++++++ drumgizmo/Makefile.am | 5 ++ drumgizmo/drumgizmoc.cc | 3 +- drumgizmo/enginefactory.cc | 9 ++++ drumgizmo/enginefactory.h | 9 +++- drumgizmo/input/alsamidi.cc | 111 ++++++++++++++++++++++++++++++++++++++++++++ drumgizmo/input/alsamidi.h | 57 +++++++++++++++++++++++ 7 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 drumgizmo/input/alsamidi.cc create mode 100644 drumgizmo/input/alsamidi.h diff --git a/configure.ac b/configure.ac index ee53a72..5a7ceb0 100644 --- a/configure.ac +++ b/configure.ac @@ -417,6 +417,19 @@ AS_IF( have_input_jackmidi=no] ) + dnl *** alsamidi + AC_ARG_ENABLE([input_alsamidi], + AS_HELP_STRING([--disable-input-alsamidi], [Disable input alsamidi plugin [default=enabled]]),, + [enable_input_alsamidi="yes"]) + + AS_IF( + [test "x$enable_input_alsamidi" = "xyes"], + [have_input_alsamidi=yes], + + [AC_MSG_RESULT([*** input alsamidi plugin disabled per user request ***]) + have_input_alsamidi=no] + ) + dnl *** Midifile AC_ARG_ENABLE([input_midifile], AS_HELP_STRING([--disable-input-midifile], [Disable input midifile plugin [default=enabled]]),, @@ -593,6 +606,7 @@ AM_CONDITIONAL([ENABLE_CLI], [test "x$enable_cli" == "xyes"]) AM_CONDITIONAL([HAVE_INPUT_DUMMY], [test "x$have_input_dummy" = "xyes"]) AM_CONDITIONAL([HAVE_INPUT_TEST], [test "x$have_input_test" = "xyes"]) AM_CONDITIONAL([HAVE_INPUT_JACKMIDI], [test "x$have_input_jackmidi" = "xyes"]) +AM_CONDITIONAL([HAVE_INPUT_ALSAMIDI], [test "x$have_input_alsamidi" = "xyes"]) AM_CONDITIONAL([HAVE_INPUT_OSSMIDI], [test "x$have_input_ossmidi" = "xyes"]) AM_CONDITIONAL([HAVE_INPUT_MIDIFILE], [test "x$have_input_midifile" = "xyes"]) AM_CONDITIONAL([HAVE_OUTPUT_DUMMY], [test "x$have_output_dummy" = "xyes"]) diff --git a/drumgizmo/Makefile.am b/drumgizmo/Makefile.am index b3bca32..7702b2e 100644 --- a/drumgizmo/Makefile.am +++ b/drumgizmo/Makefile.am @@ -77,6 +77,10 @@ drumgizmo_SOURCES += input/ossmidi.cc drumgizmo_CXXFLAGS += -DHAVE_INPUT_OSSMIDI endif # HAVE_INPUT_OSSMIDI +if HAVE_INPUT_ALSAMIDI +drumgizmo_SOURCES += input/alsamidi.cc +drumgizmo_CXXFLAGS += -DHAVE_INPUT_ALSAMIDI +endif # HAVE_INPUT_ALSAMIDI # Only compile jackclient.cc if at least one of the jack modules are included. if HAVE_OUTPUT_JACKAUDIO @@ -93,6 +97,7 @@ EXTRA_DIST = \ input/inputdummy.h \ input/test.h \ input/jackmidi.h \ + input/alsamidi.h \ input/midifile.h \ input/ossmidi.h \ output/alsa.h \ diff --git a/drumgizmo/drumgizmoc.cc b/drumgizmo/drumgizmoc.cc index 159c533..8a5774f 100644 --- a/drumgizmo/drumgizmoc.cc +++ b/drumgizmo/drumgizmoc.cc @@ -94,6 +94,7 @@ static std::string arguments() output << "Input engine parameters:\n" " jackmidi: midimap=\n" + " alsamidi: midimap=\n" " midifile: file=, speed= (default 1.0),\n" " track= (default -1, all tracks)\n" " midimap=, loop=\n" @@ -261,7 +262,7 @@ int main(int argc, char* argv[]) }); opt.add("inputengine", required_argument, 'i', - "dummy|test|jackmidi|midifile Use said event input engine.", + "dummy|test|jackmidi|alsamidi|midifile Use said event input engine.", [&]() { std::string engine = optarg; diff --git a/drumgizmo/enginefactory.cc b/drumgizmo/enginefactory.cc index c93607e..6d267c3 100644 --- a/drumgizmo/enginefactory.cc +++ b/drumgizmo/enginefactory.cc @@ -49,6 +49,9 @@ EngineFactory::EngineFactory() #ifdef HAVE_INPUT_JACKMIDI input.push_back("jackmidi"); #endif +#ifdef HAVE_INPUT_ALSAMIDI + input.push_back("alsamidi"); +#endif #ifdef HAVE_INPUT_OSS input.push_back("oss"); #endif @@ -118,6 +121,12 @@ std::unique_ptr EngineFactory::createInput(const std::string& return std::make_unique(*jack); } #endif +#ifdef HAVE_INPUT_ALSAMIDI + if(name == "alsamidi") + { + return std::make_unique(); + } +#endif #ifdef HAVE_INPUT_OSSMIDI if(name == "ossmidi") { diff --git a/drumgizmo/enginefactory.h b/drumgizmo/enginefactory.h index 0b37c6e..7dbc9b3 100644 --- a/drumgizmo/enginefactory.h +++ b/drumgizmo/enginefactory.h @@ -53,6 +53,10 @@ #include "input/jackmidi.h" #endif +#ifdef HAVE_INPUT_ALSAMIDI +#include "input/alsamidi.h" +#endif + #ifdef HAVE_INPUT_OSS #include "input/ossmidi.h" #endif @@ -77,11 +81,14 @@ #include "output/oss.h" #endif - #ifdef HAVE_INPUT_OSSMIDI #include "input/ossmidi.h" #endif +#ifdef HAVE_INPUT_ALSAMIDI +#include "input/alsamidi.h" +#endif + //! Factory for various input- and output engines class EngineFactory diff --git a/drumgizmo/input/alsamidi.cc b/drumgizmo/input/alsamidi.cc new file mode 100644 index 0000000..3547563 --- /dev/null +++ b/drumgizmo/input/alsamidi.cc @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * alsamidi.cc + * + * Copyright 2021 corrados + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DrumGizmo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include +#include + +#include "cpp11fix.h" // required for c++11 +#include "alsamidi.h" + +AlsaMidiInputEngine::AlsaMidiInputEngine() + : AudioInputEngineMidi{} + , in_port(0) + , seq_handle{nullptr} + , pos{0u} + , events{} +{ +} + +AlsaMidiInputEngine::~AlsaMidiInputEngine() +{ +} + +bool AlsaMidiInputEngine::init(const Instruments& instruments) +{ + if(!loadMidiMap(midimap_file, instruments)) + { + std::cerr << "[MidifileInputEngine] Failed to parse midimap '" + << midimap_file << "'\n"; + return false; + } + + snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0); + + snd_seq_set_client_name(seq_handle, "Midi Listener"); + + in_port = + snd_seq_create_simple_port(seq_handle, "listen:in", + SND_SEQ_PORT_CAP_WRITE | + SND_SEQ_PORT_CAP_SUBS_WRITE, + SND_SEQ_PORT_TYPE_APPLICATION); + + return true; +} + +void AlsaMidiInputEngine::setParm(const std::string& parm, const std::string& value) +{ + if(parm == "midimap") + { + // apply midimap filename + midimap_file = value; + } + else + { + std::cerr << "[AlsaMidiInputEngine] Unsupported parameter '" << parm + << "'\n"; + } +} + +bool AlsaMidiInputEngine::start() +{ + return true; +} + +void AlsaMidiInputEngine::stop() +{ +} + +void AlsaMidiInputEngine::pre() +{ +} + +void AlsaMidiInputEngine::run(size_t pos, size_t len, + std::vector& events) +{ + assert(events.empty()); + + snd_seq_event_t* ev = nullptr; + snd_seq_event_input(seq_handle, &ev); + + processNote(ev->data.raw8.d, 12, ev->data.time.tick, events); +} + +void AlsaMidiInputEngine::post() +{ +} + +bool AlsaMidiInputEngine::isFreewheeling() const +{ + return true; +} diff --git a/drumgizmo/input/alsamidi.h b/drumgizmo/input/alsamidi.h new file mode 100644 index 0000000..64d207b --- /dev/null +++ b/drumgizmo/input/alsamidi.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * alsamidi.h + * + * Copyright 2021 corrados + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DrumGizmo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#pragma once +#include +#include + +#include "audioinputenginemidi.h" +#include "midimapper.h" +#include "midimapparser.h" + +class AlsaMidiInputEngine + : public AudioInputEngineMidi +{ +public: + AlsaMidiInputEngine(); + ~AlsaMidiInputEngine(); + + // based on AudioInputEngineMidi + bool init(const Instruments& instruments) override; + void setParm(const std::string& parm, const std::string& value) override; + bool start() override; + void stop() override; + void pre() override; + void run(size_t pos, size_t len, std::vector& events) override; + void post() override; + bool isFreewheeling() const override; + +private: + int in_port; + snd_seq_t* seq_handle; + + std::string midimap_file; + std::size_t pos; + std::vector events; +}; -- cgit v1.2.3