From 3ba3096ad57644d2dc45ba86e98c07f68bcfe52e Mon Sep 17 00:00:00 2001 From: Chris Ahlstrom Date: Thu, 14 Dec 2023 14:33:33 -0500 Subject: [PATCH] Wrestling with oddities in Dixie04.mid. --- README.md | 4 +-- Seq66cli/Makefile.am | 9 ++++-- Seq66cli/Makefile.in | 9 ++++-- Seq66qt5/Makefile.am | 6 ++-- Seq66qt5/Makefile.in | 6 ++-- TODO | 1 + configure | 12 ++++++-- configure.ac | 25 ++++++++--------- contrib/midi/README | 11 ++++++-- doc/latex/tex/midi_formats.tex | 44 ++++++++++++++++++++++++------ doc/latex/tex/references.tex | 7 ++++- include/config.h.in | 3 ++ libseq66/include/midi/event.hpp | 4 +-- libseq66/include/midi/midifile.hpp | 4 +-- libseq66/src/midi/midifile.cpp | 40 +++++++++++++++++++++++---- 15 files changed, 134 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 997ac18e..b1aab8f3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# README for Seq66 0.99.12 2023-12-06 +# README for Seq66 0.99.12 2023-12-12 __Seq66__ MIDI sequencer/live-looper with a hardware-sampler grid interface; pattern banks, triggers, and playlists for song management; scale and chord @@ -20,7 +20,7 @@ Support sites (still in progress): The release now includes an installer for the 64-bit Windows version of Seq66. -![Alt text](doc/latex/images/main-window/main-windows.png?raw=true "Seq66") +![Alt text](doc/latex/images/main-window/main-windows-perstfic.png?raw=true "Seq66") # Major Features diff --git a/Seq66cli/Makefile.am b/Seq66cli/Makefile.am index 564c1c13..904adc21 100644 --- a/Seq66cli/Makefile.am +++ b/Seq66cli/Makefile.am @@ -6,7 +6,7 @@ # \library seq66cli application # \author Chris Ahlstrom # \date 2017-04-07 -# \update 2023-12-11 +# \update 2023-12-13 # \version $Revision$ # \license $XPC_SUITE_GPL_LICENSE$ # @@ -167,16 +167,19 @@ bin_PROGRAMS = $(MIDIAPP) #****************************************************************************** # seq66cli +# +# seq66cli_LDFLAGS = -Wl,--copy-dt-needed-entries +# #---------------------------------------------------------------------------- seq66cli_SOURCES = seq66rtcli.cpp seq66cli_DEPENDENCIES = $(NSM_DEPS) $(dependencies) -seq66cli_LDFLAGS = -Wl,--copy-dt-needed-entries +seq66cli_LDFLAGS = $(LINKER_FLAGS_ADD) seq66cli_LDADD = $(NSM_LIBS) $(libraries) $(LIBLO_LIBS) $(ALSA_LIBS) $(JACK_LIBS) $(AM_LDFLAGS) seq66clip_SOURCES = seq66rtcli.cpp seq66clip_DEPENDENCIES = $(NSM_DEPS) $(dependencies) -seq66clip_LDFLAGS = -Wl,--copy-dt-needed-entries +seq66clip_LDFLAGS = $(LINKER_FLAGS_ADD) seq66clip_LDADD = $(NSM_LIBS) $(libraries) $(LIBLO_LIBS) $(ALSA_LIBS) $(JACK_LIBS) $(AM_LDFLAGS) #****************************************************************************** diff --git a/Seq66cli/Makefile.in b/Seq66cli/Makefile.in index 38e944c9..01542340 100644 --- a/Seq66cli/Makefile.in +++ b/Seq66cli/Makefile.in @@ -21,7 +21,7 @@ # \library seq66cli application # \author Chris Ahlstrom # \date 2017-04-07 -# \update 2023-12-11 +# \update 2023-12-13 # \version $Revision$ # \license $XPC_SUITE_GPL_LICENSE$ # @@ -517,14 +517,17 @@ dependencies = \ #****************************************************************************** # seq66cli +# +# seq66cli_LDFLAGS = -Wl,--copy-dt-needed-entries +# #---------------------------------------------------------------------------- seq66cli_SOURCES = seq66rtcli.cpp seq66cli_DEPENDENCIES = $(NSM_DEPS) $(dependencies) -seq66cli_LDFLAGS = -Wl,--copy-dt-needed-entries +seq66cli_LDFLAGS = $(LINKER_FLAGS_ADD) seq66cli_LDADD = $(NSM_LIBS) $(libraries) $(LIBLO_LIBS) $(ALSA_LIBS) $(JACK_LIBS) $(AM_LDFLAGS) seq66clip_SOURCES = seq66rtcli.cpp seq66clip_DEPENDENCIES = $(NSM_DEPS) $(dependencies) -seq66clip_LDFLAGS = -Wl,--copy-dt-needed-entries +seq66clip_LDFLAGS = $(LINKER_FLAGS_ADD) seq66clip_LDADD = $(NSM_LIBS) $(libraries) $(LIBLO_LIBS) $(ALSA_LIBS) $(JACK_LIBS) $(AM_LDFLAGS) all: all-am diff --git a/Seq66qt5/Makefile.am b/Seq66qt5/Makefile.am index 431f9437..91790308 100644 --- a/Seq66qt5/Makefile.am +++ b/Seq66qt5/Makefile.am @@ -6,7 +6,7 @@ # \library seq66qt5 application # \author Chris Ahlstrom # \date 2017-09-05 -# \update 2023-12-08 +# \update 2023-12-13 # \version $Revision$ # \license $XPC_SUITE_GPL_LICENSE$ # @@ -206,12 +206,12 @@ bin_PROGRAMS = $(MIDIAPP) qseq66_SOURCES = seq66qt5.cpp qseq66_DEPENDENCIES = $(NSM_DEPS) $(dependencies) -qseq66_LDFLAGS = -Wl,--copy-dt-needed-entries +qseq66_LDFLAGS = $(LINKER_FLAGS_ADD) qseq66_LDADD = $(NSM_LIBS) $(libraries) $(LIBLO_LIBS) $(QT_LIBS) $(ALSA_LIBS) $(JACK_LIBS) $(AM_LDFLAGS) qpseq66_SOURCES = seq66qt5.cpp qpseq66_DEPENDENCIES = $(NSM_DEPS) $(dependencies) -qpseq66_LDFLAGS = -Wl,--copy-dt-needed-entries +qpseq66_LDFLAGS = $(LINKER_FLAGS_ADD) qpseq66_LDADD = $(NSM_LIBS) $(libraries) $(LIBLO_LIBS) $(QT_LIBS) $(ALSA_LIBS) $(JACK_LIBS) $(AM_LDFLAGS) #****************************************************************************** diff --git a/Seq66qt5/Makefile.in b/Seq66qt5/Makefile.in index f11a3930..ee9b740c 100644 --- a/Seq66qt5/Makefile.in +++ b/Seq66qt5/Makefile.in @@ -21,7 +21,7 @@ # \library seq66qt5 application # \author Chris Ahlstrom # \date 2017-09-05 -# \update 2023-12-08 +# \update 2023-12-13 # \version $Revision$ # \license $XPC_SUITE_GPL_LICENSE$ # @@ -555,11 +555,11 @@ dependencies = \ #---------------------------------------------------------------------------- qseq66_SOURCES = seq66qt5.cpp qseq66_DEPENDENCIES = $(NSM_DEPS) $(dependencies) -qseq66_LDFLAGS = -Wl,--copy-dt-needed-entries +qseq66_LDFLAGS = $(LINKER_FLAGS_ADD) qseq66_LDADD = $(NSM_LIBS) $(libraries) $(LIBLO_LIBS) $(QT_LIBS) $(ALSA_LIBS) $(JACK_LIBS) $(AM_LDFLAGS) qpseq66_SOURCES = seq66qt5.cpp qpseq66_DEPENDENCIES = $(NSM_DEPS) $(dependencies) -qpseq66_LDFLAGS = -Wl,--copy-dt-needed-entries +qpseq66_LDFLAGS = $(LINKER_FLAGS_ADD) qpseq66_LDADD = $(NSM_LIBS) $(libraries) $(LIBLO_LIBS) $(QT_LIBS) $(ALSA_LIBS) $(JACK_LIBS) $(AM_LDFLAGS) all: all-am diff --git a/TODO b/TODO index dc32d075..9c86d1ce 100644 --- a/TODO +++ b/TODO @@ -4,6 +4,7 @@ Chris Ahlstrom Misc: + - Do not parse files twice if no options given on command line. - Clang-16: - CLANG and LO_TT_IMMEDIATE: warning: compound literals are a C99-specific feature [-Wc99-extensions]. See diff --git a/configure b/configure index 2565af20..318bae1a 100755 --- a/configure +++ b/configure @@ -4705,10 +4705,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +LINKER_FLAGS_ADD = "-Wl,--copy-dt-needed-entries" + if test "$CXX" = "clang++" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether clang works" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether clang works" >&5 $as_echo_n "checking whether clang works... " >&6; } - ac_ext=cpp + ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' @@ -4735,9 +4737,13 @@ main () _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } +$as_echo "#define CLANG_SUPPORT 1" >>confdefs.h + + LINKER_FLAGS_ADD = "" + else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 diff --git a/configure.ac b/configure.ac index 7b07566c..3c9823de 100644 --- a/configure.ac +++ b/configure.ac @@ -37,13 +37,6 @@ AX_PREFIX_CONFIG_H([include/seq66-config.h], [seq66]) dnl gcc/g++ configuration. -dnl AC_PROG_CC([gcc]) -dnl AC_PROG_CXX([g++]) -dnl AC_PROG_CXXCPP([cpp]) -dnl -dnl AC_PROG_CC -dnl AC_PROG_CXX -dnl AC_PROG_CXXCPP dnl AC_PROG_INSTALL dnl AC_PROG_LN_S dnl AC_PROG_MKDIR_P @@ -62,12 +55,15 @@ dnl dnl If CXX is Clang, check that it can find and parse C++ standard library dnl headers. Note that space between 'include' and '(' is required. dnl There's a broken regex in aclocal that otherwise will think that we call -dnl m4's include dnl builtin. +dnl m4's include builtin. The linker flags are used with gcc, but not +dnl clang. + +LINKER_FLAGS_ADD = "-Wl,--copy-dt-needed-entries" if test "$CXX" = "clang++" ; then - AC_MSG_CHECKING([whether clang works]) - AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + AC_MSG_CHECKING([whether clang works]) + AC_LANG_PUSH([C++]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #if __has_include () #include #endif @@ -76,7 +72,9 @@ if test "$CXX" = "clang++" ; then #endif ]])], [ - AC_MSG_RESULT([yes]) + AC_MSG_RESULT([yes]) + AC_DEFINE(CLANG_SUPPORT, 1, [Define if CLANG is active]) + LINKER_FLAGS_ADD = "" ], [ AC_MSG_RESULT([no]) @@ -289,7 +287,8 @@ AC_ARG_ENABLE(jack, [jack=yes]) dnl JACK session support is now deprecated (circa 2020-10-26), but still the -dnl default for this option is 'no'. JACK recommends using NSM instead! +dnl default for this option is 'yes'. JACK recommends using NSM instead! But +dnl Seq66 will support it for awhile yet. AC_ARG_ENABLE(jack-session, [AS_HELP_STRING(--disable-jack-session, [Disable JACK session support])], diff --git a/contrib/midi/README b/contrib/midi/README index 153a4979..eb13517d 100644 --- a/contrib/midi/README +++ b/contrib/midi/README @@ -1,6 +1,6 @@ MIDI Sample and Test Files Chris Ahlstrom -2015-09-11 to 2023-12-11 +2015-09-11 to 2023-12-14 This directory contains contributed MIDI files for examples and testing. Also see the test files from the midicvt as described in @@ -55,7 +55,14 @@ the "example1" file. events. SysEx messages start with F0 and end with F7. Universal Real Time SysEx messages start with F0, followed by 7F, then include other fields before the terminating F7. More importantly, it appears - to have an unterminated SysEx event starting at 0x53DF. + to have an unterminated SysEx event starting at 0x53DF. Also, the + MThd header specifies 14 tracks, but there are only 4 MTrk chunks + according to midicvt. This is wrong; a binary edit shows 14 MTrks. + Seq66 (and QTractor) loads only 12 tracks. Another peculiarity of this + file is that the sequence 9D 7D (F0 7F 00) x 5 occurs 10 times, and + there are many other F0 F7 nn sequences followed immediately by an + F0! We can ignore these without storing them, but is that the best + way to handle them? What do they mean? mutes-long.midi: diff --git a/doc/latex/tex/midi_formats.tex b/doc/latex/tex/midi_formats.tex index 96fede0f..b3d10c16 100644 --- a/doc/latex/tex/midi_formats.tex +++ b/doc/latex/tex/midi_formats.tex @@ -6,7 +6,7 @@ % \library Documents % \author Chris Ahlstrom % \date 2015-09-03 -% \update 2023-12-12 +% \update 2023-12-14 % \version $Revision$ % \license $XPC_GPL_LICENSE$ % @@ -1115,9 +1115,9 @@ \subsubsection{SysEx Event (0xF0)} \item \textbf{0x7F}. Represents a non-realtime system exclusive message. All MIDI devices can respond to it, immediately. - \textsl{Seq66} uses the SysEx real-time message to support - SeqSpecs. - See \sectionref{paragraph:midi_format_seq66_seqspecs}. +% WRONZg \textsl{Seq66} uses the SysEx real-time message to support +% SeqSpecs. +% See \sectionref{paragraph:midi_format_seq66_seqspecs}. \end{itemize} For more information on these events, see @@ -1196,7 +1196,7 @@ \subsubsection{SysEx Event (0xF0)} \label{paragraph:patterns_escape_sequence} An escape sequence is not SysEx, but it does use the F7 byte. - It is used for encoding arbitrary bytes for message such as Song Select. + It is used for encoding arbitrary bytes for messages such as Song Select. The first line shows such a message, and the second how it would be encoded. \begin{verbatim} @@ -1229,10 +1229,26 @@ \subsubsection{Universal SysEx Events (0xF0 0x7E and 0xF0 0x7F)} wild-card for "all devices"). \begin{verbatim} - F7 7E channel subid data bytes F7 - F7 7F channel subid data bytes F7 + F7 7E channel subid data bytes F7 (non-realtime) + F7 7F channel subid data bytes F7 (realtime) \end{verbatim} + If \texttt{channel} is F7, this is a global broadcast that all devices + should heed. + The \texttt{subid} could be something like "01 00" for a long-form + (full frame) time-code message. + +% F0 7E id 01 Channel Pressure (Aftertouch) +% F0 7E id 01 or Sample Dump Header??? +% F0 7E id 02 Polyphonic Key Pressure (Aftertouch) +% F0 7E id 02 or Sample Data Packet??? +% F0 7E id 03 Controller (Control Change) +% F0 7E id 03 or Sample Dump Request??? +% F0 7E id 09 nn F7 GM System Enable / Disable (01 / 00) +% F0 7F 00 ??? +% F0 7F id 01 01 hh mm ss ff F7 MIDI Full Frame +% F0 7F id 04 01 mm nn F7 MIDI Master Volume (vs Controller Volume) + A detailed description is beyond the scope of this document. Some messages supported by these messages are the \textsl{MIDI Master Volume}, @@ -1240,6 +1256,15 @@ \subsubsection{Universal SysEx Events (0xF0 0x7E and 0xF0 0x7F)} and the \textsl{General MIDI System Enable/Disable} messages. + An interesting subset of these messages is \textsl{MIDI Show Control} + (MSC): + + \begin{verbatim} + F7 7F deviceid 02 commandformat command data F7 (MSC) + \end{verbatim} + + See \cite{msc}. + Some simple controls can be included in the 'ctrl' file's set of macros. \paragraph{Seq66 SysEx Handling} \label{paragraph:midi_format_seq66_sysex_handling} @@ -1260,7 +1285,10 @@ \subsubsection{Universal SysEx Events (0xF0 0x7E and 0xF0 0x7F)} \end{verbatim} The "manid" is a manufacturer's identifier. 0x41 is Roland, 0x24 is - Hohner. The "devid" is the device identifier (e.g. 0x10 for Roland devices). + Hohner. 0x00 is used for adding two more codes to greatly expand the ID + list. 0x7E is used to denote a non-realtime message, and 0x7F denotes + a realtime message. + The "devid" is the device identifier (e.g. 0x10 for Roland devices). The "devid" indicates which devices will accept the SysEx message. The "modelid" is the model identifier (0x42 for most GS synths). The "direction" is 0x12 for sending information or 0x11 for requesting diff --git a/doc/latex/tex/references.tex b/doc/latex/tex/references.tex index 8888faf7..119eaf8f 100644 --- a/doc/latex/tex/references.tex +++ b/doc/latex/tex/references.tex @@ -6,7 +6,7 @@ % \library Documents % \author Chris Ahlstrom % \date 2015-08-31 -% \update 2023-09-20 +% \update 2023-12-14 % \version $Revision$ % \license $XPC_GPL_LICENSE$ % @@ -155,6 +155,11 @@ \section{References} \url{https://github.com/ahlstromcj/midicvt}. 2015-2016. + \bibitem{msc} + \emph{Digital Sound and Music: MIDI Show Control.} + \url{https://digitalsoundandmusic.com/6-2-5-non-musical-applications-for-midi/}. + 2023. + \bibitem{nanobasket} Roy Vegard. \emph{Configurator software for the Korg nanoSERIES of MIDI controllers.} diff --git a/include/config.h.in b/include/config.h.in index 9e54dbf5..c019db43 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -27,6 +27,9 @@ /* Name of the UI of the application */ #undef APP_TYPE +/* Define if CLANG is active */ +#undef CLANG_SUPPORT + /* "Name to display as client/port" */ #undef CLIENT_NAME diff --git a/libseq66/include/midi/event.hpp b/libseq66/include/midi/event.hpp index f6e0907f..51e19a72 100644 --- a/libseq66/include/midi/event.hpp +++ b/libseq66/include/midi/event.hpp @@ -28,7 +28,7 @@ * \library seq66 application * \author Chris Ahlstrom * \date 2015-07-24 - * \updates 2023-12-11 + * \updates 2023-12-12 * \license GNU GPLv2 or above * * This module also declares/defines the various constants, status-byte @@ -773,7 +773,7 @@ class event static bool is_sysex_msg (midibyte m) { return m == EVENT_MIDI_SYSEX || - EVENT_MIDI_SYSEX_CONTINUE; /* 0xF7 as SysEx Continue */ + m == EVENT_MIDI_SYSEX_CONTINUE; /* 0xF7 as SysEx Continue */ } /** diff --git a/libseq66/include/midi/midifile.hpp b/libseq66/include/midi/midifile.hpp index 18499a31..0d721942 100644 --- a/libseq66/include/midi/midifile.hpp +++ b/libseq66/include/midi/midifile.hpp @@ -27,7 +27,7 @@ * \library seq66 application * \author Chris Ahlstrom * \date 2015-07-24 - * \updates 2023-12-11 + * \updates 2023-12-14 * \license GNU GPLv2 or above * * The Seq24 MIDI file is a standard, Format 1 MIDI file, with some extra @@ -373,7 +373,7 @@ class midifile bool read_byte_array (midistring & b, size_t len); bool read_string (std::string & b, size_t len); bool read_meta_data (sequence & s, event & e, midibyte metatype, size_t len); - int read_sysex_data + bool read_sysex_data ( sequence & s, event & e, size_t len, bool continuation = false diff --git a/libseq66/src/midi/midifile.cpp b/libseq66/src/midi/midifile.cpp index a0fcb64f..5c2e06db 100644 --- a/libseq66/src/midi/midifile.cpp +++ b/libseq66/src/midi/midifile.cpp @@ -24,7 +24,7 @@ * \library seq66 application * \author Chris Ahlstrom * \date 2015-07-24 - * \updates 2023-12-11 + * \updates 2023-12-14 * \license GNU GPLv2 or above * * For a quick guide to the MIDI format, see, for example: @@ -503,16 +503,25 @@ midifile::read_meta_data (sequence & s, event & e, midibyte metatype, size_t len * * We now check for unterminated SysEx messages as found in Dixie04.mid. * We handle F7 as continuation, but not yet escape values. + * + * F0: In Dixie04.mid, we find ten instances of the sequence + * + * 9D 7D (F0 7F 00) x 5 repeats + * + * As an EXPERIMENT, we peek ahead for an F0 and abort if we find one. + * The result does not change the patterns, but does strip out sequences + * like F0 7F nn that have a following F0. */ -int +bool midifile::read_sysex_data ( - sequence & s, event & e, size_t len, bool continuation + sequence & s, event & e, + size_t len, bool continuation ) { - int result = 0; - if (len > 0) + bool result = len > 0; + if (result) { e.reset_sysex(); /* clear m_sysex */ @@ -531,9 +540,28 @@ midifile::read_sysex_data } else { + /* + * See the "F0" note in the banner. + */ + +#if defined USE_EXPERIMENTAL_CODE + midibyte p = peek(); + if (p != EVENT_MIDI_SYSEX) + { + midibyte b = read_byte(); + if (! e.append_sysex_byte(b)) /* not F7? */ + break; + } + else + { + result = false; + break; + } +#else midibyte b = read_byte(); if (! e.append_sysex_byte(b)) /* not F7? */ break; +#endif } } if (result) @@ -1633,7 +1661,7 @@ midifile::parse_smf_1 (performer & p, int screenset, bool is_smf0) else if (status == EVENT_MIDI_SYSEX_END) /* 0xF7 contin */ { len = read_varinum(); - if (read_sysex_data(s, e, len)) + if (read_sysex_data(s, e, len, true)) ++evcount; } else