diff --git a/Makefile.am b/Makefile.am index bf0f876..b6ca58a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,9 +5,10 @@ AM_CFLAGS = ACLOCAL_AMFLAGS = -I m4 # use custom macro's in ./m4 + # if we are building and linking to a nested copy of libcm if BUILD_LIBCM - SUBDIRS = src/libcm # causes recursive make into given sub-directories +# SUBDIRS = src/libcm # causes recursive make into given sub-directories AM_CPPFLAGS += -I$(srcdir)/src/libcm/src -I$(srcdir)/src/libcm/src/dsp -I$(srcdir)/src/libcm/src/vop -I$(srcdir)/src/libcm/src/app AM_LDFLAGS += -Lsrc/libcm/src endif diff --git a/README.md b/README.md index fd47f9f..990d7d0 100644 --- a/README.md +++ b/README.md @@ -219,6 +219,32 @@ index line loctn bar idx type pitch ETD Dynamic ``` +Score Merge +=========== + +Copy the manual edits from 'frag.txt' to the correct location, beginning with measure 284, in the blank edit file 'edit0.txt'. + +``` +cmootls --merge_edit -d edit0.txt -b 284 -k frag.txt -o temp.txt +``` + +All the events in 'frag.txt' may not be able to be located in 'edit0.txt'. Warning messages will be generated for +each of these events. + +``` +XScore warning: Sync error: meas:301 18 index:7 8 A#4 (midi:70) edit:!mp+ (RC:14) +XScore warning: Sync error: meas:322 39 index:32 33 C2 (midi:36) edit:!!PPP (RC:14) +XScore warning: Sync error: meas:335 52 index:15 16 D4 (midi:62) edit:!ppp (RC:14) +XScore warning: Sync error: meas:343 60 index:18 19 E5 (midi:76) edit:%%a !mf (RC:14) +XScore warning: Sync error: meas:343 60 index:18 20 D4 (midi:62) edit:!fff (RC:14) +XScore warning: Sync error: meas:343 60 index:18 21 F#4 (midi:66) edit:!fff (RC:14) +XScore warning: Sync error: meas:343 60 index:18 22 G1 (midi:31) edit:!mp (RC:14) +XScore warning: Sync error: meas:343 60 index:18 23 B1 (midi:35) edit:!ff (RC:14) +XScore warning: Sync error: meas:350 67 index:51 54 F4 (midi:65) edit:!mf+ (RC:14) +XScore warning: Sync error: meas:350 67 index:50 55 A#5 (midi:82) edit:!mf+ (RC:14) +``` + + MIDI File Reports ================= @@ -240,9 +266,8 @@ tlPrefix is the folder where data files for this timeline are stored. Score Follow Report =================== -``` -cmtool --score_follow -c round2.csv -i new_round2.mid -r report.txt -s report_svg.html - ``` + cmtool --score_follow -c round2.csv -i new_round2.mid -r report.txt -s report_svg.html + SVG Description --------------- diff --git a/build/linux/debug/build.sh b/build/linux/debug/build.sh index 2bd6942..b18ea96 100755 --- a/build/linux/debug/build.sh +++ b/build/linux/debug/build.sh @@ -12,14 +12,14 @@ cd ${curdir} # 2) Run the program. ./foo # 3) Run gprof /libtool --mode=execute gprof ./foo +# --enable-build_libcm - build libcm from local tree + ../../../configure --prefix=${curdir} \ - --enable-debug --enable-build_libcm \ + --enable-debug \ CFLAGS="-g -Wall" \ CXXFLAGS="-g -Wall" \ - LIBS= - -# CPPFLAGS="-I/home/kevin/src/libcm/build/linux/debug/include " \ -# LDFLAGS="-L/home/kevin/src/libcm/build/linux/debug/lib" \ - + CPPFLAGS="-I/home/kevin/src/libcm/build/linux/debug/include " \ + LDFLAGS="-L/home/kevin/src/libcm/build/linux/debug/lib" + LIBS= #make #make install diff --git a/configure.ac b/configure.ac index b205997..a5411eb 100644 --- a/configure.ac +++ b/configure.ac @@ -44,6 +44,9 @@ AC_FUNC_REALLOC AC_FUNC_STRTOD AC_CHECK_FUNCS([clock_gettime floor memmove memset mkdir pow rint select socket sqrt strcasecmp strchr strcspn strerror strspn strstr strtol]) +# check for he prerequisite libraries +AC_CHECK_LIB([fftw3],[fftw_malloc],[AC_MSG_RESULT([The 'FFTW' library was found.])],[AC_MSG_ERROR([The 'FFTW' library was not found.])]) +AC_CHECK_LIB([asound],[snd_asoundlib_version],[AC_MSG_RESULT([The 'ALSA' library was found.])],[AC_MSG_ERROR([The 'ALSA' library was not found.])]) # The following is a custom macro in ./m4/os_type.m4 # be sure to also set "ACLOCAL_AMFLAGS = -I m4" in ./Makefile.am @@ -69,15 +72,16 @@ AC_ARG_ENABLE([build_libcm], *) AC_MSG_ERROR([bad value ${enableval} for --enable-build_libcm]) ;; esac],[build_libcm=false]) -echo "build_libcm=${build_libcm}" # check if a nested copy of libcm exists in /src/libcm AC_CHECK_FILE([${srcdir}/src/libcm/src/cmGlobal.h],[local_libcm=true],[local_libcm=false]) echo "local_libcm=${local_libcm}" +echo "build_libcm=${build_libcm}" # set BUILD_LIBCM if a libcm build request was set and a nested copy of libcm exists AM_CONDITIONAL([BUILD_LIBCM], [test x$build_libcm = xtrue -a x$local_libcm = xtrue ]) +# enable debug AC_ARG_ENABLE([debug], [ --enable-debug Turn on debugging], [case "${enableval}" in @@ -94,6 +98,7 @@ if test x$debug = xfalse; then AC_DEFINE([NDEBUG], 1,[Debugging off.]) fi +# enable the use of Atlas library AC_ARG_ENABLE([vectop], [ --enable-vectop Turn on use of Lapack and Atlas vector/matrix operations. ], [case "${enableval}" in @@ -110,6 +115,7 @@ AC_DEFINE([CM_VECTOP], 1,[Use Lapack and Atlas.]) fi +# enable memory alignment AC_ARG_ENABLE([memalign], [ --enable-memalign Turn on memory alignment on dynamic memory allocations. ], [case "${enableval}" in @@ -125,6 +131,7 @@ if test x"$memalign" = xtrue; then AC_DEFINE([CM_MEMALIGN], 1,[Turn on dynamic memory alignment.]) fi +# enable sonic arts code inclusion AC_ARG_ENABLE([sonicart], [ --enable-sonicart Enable use of Sonic Arts proprietary code. ], [case "${enableval}" in @@ -146,7 +153,7 @@ AC_CONFIG_FILES([ Makefile ]) # if local nested libcm then do recursive configure into subdirs if test x$build_libcm = xtrue -a x$local_libcm = xtrue; then -AC_CONFIG_SUBDIRS([src/libcm]) + AC_CONFIG_SUBDIRS([src/libcm]) fi AC_OUTPUT diff --git a/doc/xscore_gen.md b/doc/xscore_gen.md index 532d7df..1eb0b93 100644 --- a/doc/xscore_gen.md +++ b/doc/xscore_gen.md @@ -45,6 +45,10 @@ run again to generate three output files: - MIDI file suitable for audio rendering - SVG piano roll file +``` +cmtools --score_gen -x GUTIM_20200803_utf8.xml -d edit0.txt -c score.csv -m score.mid -s score_svg.html -r report.txt +``` + As with step 2 this step may need to be iterated several times to clear syntactic errors in the decoration data. diff --git a/src/cmtools/cmtools.c b/src/cmtools/cmtools.c index ed1eca3..bc1d8bf 100644 --- a/src/cmtools/cmtools.c +++ b/src/cmtools/cmtools.c @@ -33,6 +33,7 @@ enum kNoActionIdSelectedCtRC, kMissingRequiredFileNameCtRC, kScoreGenFailedCtRC, + kScoreEditMergeFailedCtRC, kScoreFollowFailedCtRC, kMidiFileRptFailedCtRC, kTimeLineRptFailedCtRC, @@ -46,14 +47,14 @@ const cmChar_t poBegHelpStr[] = "\n" "USAGE:\n" "\n" - "Parse an XML score file and decoration file to produce a score file in CSV format.\n" + "Parse an XML score file and 'edit' file to produce a score file in CSV format.\n" "\n" - "cmtool --score_gen -x -d {-c } {-s } {-r report} {-b begMeasNumb} {t begTempoBPM}\n" + "cmtool --score_gen -x -d {-c } {-s } {-r report} {-b begMeasNumb} {t begTempoBPM}\n" "\n" "Notes:\n" - "1. If does not exist then a decoration template file will be generated based on the MusicXML file. \n" - "2. Along with the CSV score file MIDI and HTML/SVG files will also be produced based on the contents of the MusicXML and decoration file.\n" - "3. See README.md for a detailed description of the how to edit the decoration file.\n" + "1. If does not exist then a edit template file will be generated based on the MusicXML file. \n" + "2. Along with the CSV score file MIDI and HTML/SVG files will also be produced based on the contents of the MusicXML and edit file.\n" + "3. See README.md for a detailed description of the how to edit the edit file.\n" "\n" "\n" "Use the score follower to generate a timeline configuration file.\n" @@ -103,18 +104,39 @@ bool verify_non_null_filename( cmCtx_t* ctx, const cmChar_t* fn, const cmChar_t* return kOkCtRC; } -cmRC_t score_gen( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* decFn, const cmChar_t* csvOutFn, const cmChar_t* midiOutFn, const cmChar_t* svgOutFn, unsigned reportFl, int begMeasNumb, int begTempoBPM, bool svgStandAloneFl, bool svgPanZoomFl, bool damperRptFl ) +cmRC_t score_gen( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* editFn, const cmChar_t* csvOutFn, const cmChar_t* midiOutFn, const cmChar_t* svgOutFn, unsigned reportFl, int begMeasNumb, int begTempoBPM, bool svgStandAloneFl, bool svgPanZoomFl, bool damperRptFl ) { cmRC_t rc; if((rc = verify_file_exists(ctx,xmlFn,"XML file")) != kOkCtRC ) return rc; - if( cmXScoreTest( ctx, xmlFn, decFn, csvOutFn, midiOutFn, svgOutFn, reportFl, begMeasNumb, begTempoBPM, svgStandAloneFl, svgPanZoomFl, damperRptFl ) != kOkXsRC ) + if( cmXScoreTest( ctx, xmlFn, editFn, csvOutFn, midiOutFn, svgOutFn, reportFl, begMeasNumb, begTempoBPM, svgStandAloneFl, svgPanZoomFl, damperRptFl ) != kOkXsRC ) return cmErrMsg(&ctx->err,kScoreGenFailedCtRC,"score_gen failed."); return kOkCtRC; } +cmRC_t score_edit_merge( cmCtx_t* ctx, const cmChar_t* xmlFn, const cmChar_t* editFn, unsigned begMeasNumb, const cmChar_t* keyEditFn, unsigned keyMeasNumb, const cmChar_t* outFn ) +{ + cmRC_t rc; + + if((rc = verify_file_exists(ctx,xmlFn,"XML file")) != kOkCtRC ) + return rc; + + if((rc = verify_file_exists(ctx,editFn,"reference edit file")) != kOkCtRC ) + return rc; + + if((rc = verify_file_exists(ctx,editFn,"key edit file")) != kOkCtRC ) + return rc; + + if( cmXScoreMergeEditFiles( ctx, xmlFn, editFn, begMeasNumb, keyEditFn, keyMeasNumb, outFn ) != kOkXsRC ) + return cmErrMsg(&ctx->err,kScoreEditMergeFailedCtRC,"Score merge failed failed."); + + return kOkCtRC; +} + + + cmRC_t score_follow( cmCtx_t* ctx, const cmChar_t* csvScoreFn, const cmChar_t* midiInFn, const cmChar_t* matchRptOutFn, const cmChar_t* matchSvgOutFn, const cmChar_t* midiOutFn, const cmChar_t* timelineFn ) { cmRC_t rc; @@ -215,7 +237,10 @@ int main( int argc, char* argv[] ) kInvalidPoId = kBasePoId, kActionPoId, kXmlFileNamePoId, - kDecorateFileNamePoId, + kEditFileNamePoId, + kKeyEditFileNamePoId, + kKeyMeasNumbPoId, + kOutEditFileNamePoId, kCsvOutFileNamePoId, kPgmRsrcFileNamePoId, kMidiOutFileNamePoId, @@ -238,6 +263,7 @@ int main( int argc, char* argv[] ) enum { kNoSelId, kScoreGenSelId, + kScoreEditMergeSelId, kScoreFollowSelId, kMeasGenSelId, kScoreReportSelId, @@ -256,7 +282,9 @@ int main( int argc, char* argv[] ) const cmChar_t* appTitle = "cmtools"; cmCtx_t ctx; const cmChar_t* xmlFn = NULL; - const cmChar_t* decFn = NULL; + const cmChar_t* editFn = NULL; + const cmChar_t* keyEditFn = NULL; + const cmChar_t* outEditFn = NULL; const cmChar_t* pgmRsrcFn = NULL; const cmChar_t* csvScoreFn = NULL; const cmChar_t* midiOutFn = NULL; @@ -270,6 +298,7 @@ int main( int argc, char* argv[] ) unsigned svgStandAloneFl = 1; unsigned svgPanZoomFl = 1; int begMeasNumb = 0; + int keyMeasNumb = 0; int begTempoBPM = 60; unsigned damperRptFl = 0; unsigned begMidiUId = cmInvalidId; @@ -288,6 +317,9 @@ int main( int argc, char* argv[] ) cmPgmOptInstallEnum( poH, kActionPoId, 'S', "score_gen", 0, kScoreGenSelId, kNoSelId, &actionSelId, 1, "Run the score generation tool.","Action selector"); + + cmPgmOptInstallEnum( poH, kActionPoId, 'D', "merge_edit", 0, kScoreEditMergeSelId, kNoSelId, &actionSelId, 1, + "Synchronize and copy the edit information from one edit file into another.","Action selector"); cmPgmOptInstallEnum( poH, kActionPoId, 'F', "score_follow", 0, kScoreFollowSelId, kNoSelId, &actionSelId, 1, "Run the time line marker generation tool.",NULL); @@ -308,12 +340,22 @@ int main( int argc, char* argv[] ) "Generate an audio file report.",NULL); - cmPgmOptInstallStr( poH, kXmlFileNamePoId, 'x', "muisic_xml_fn",0, NULL, &xmlFn, 1, + cmPgmOptInstallStr( poH, kXmlFileNamePoId, 'x', "music_xml_fn",0, NULL, &xmlFn, 1, "Name of the input MusicXML file."); - cmPgmOptInstallStr( poH, kDecorateFileNamePoId, 'd', "dec_fn", 0, NULL, &decFn, 1, - "Name of a score decoration file."); + cmPgmOptInstallStr( poH, kEditFileNamePoId, 'd', "edit_fn", 0, NULL, &editFn, 1, + "Name of a score edit file."); + cmPgmOptInstallStr( poH, kKeyEditFileNamePoId, 'k', "key_edit_fn", 0, NULL, &keyEditFn, 1, + "Name of a score edit key file."); + + cmPgmOptInstallInt( poH, kKeyMeasNumbPoId, 'q', "key_meas", 0, 1, &keyMeasNumb, 1, + "Number of the first measure number to merge in the edit key filke (see --key_edit_fn)." ); + + + cmPgmOptInstallStr( poH, kOutEditFileNamePoId, 'o', "out_edit_fn", 0, NULL, &outEditFn, 1, + "Name of a score edit merge file."); + cmPgmOptInstallStr( poH, kCsvOutFileNamePoId, 'c', "score_csv_fn",0, NULL, &csvScoreFn, 1, "Name of a CSV score file."); @@ -376,7 +418,11 @@ int main( int argc, char* argv[] ) switch( actionSelId ) { case kScoreGenSelId: - rc = score_gen( &ctx, xmlFn, decFn, csvScoreFn, midiOutFn, svgOutFn, reportFl, begMeasNumb, begTempoBPM, svgStandAloneFl, svgPanZoomFl, damperRptFl ); + rc = score_gen( &ctx, xmlFn, editFn, csvScoreFn, midiOutFn, svgOutFn, reportFl, begMeasNumb, begTempoBPM, svgStandAloneFl, svgPanZoomFl, damperRptFl ); + break; + + case kScoreEditMergeSelId: + rc = score_edit_merge( &ctx, xmlFn, editFn, begMeasNumb, keyEditFn, keyMeasNumb, outEditFn ); break; case kScoreFollowSelId: