Compare commits

...

9 Commits

Author SHA1 Message Date
Seymour Shlien
d73b3682e1 2023.01.08 2023-01-08 11:10:49 -05:00
Seymour Shlien
c981535a2a 2023.01.06 2023-01-06 14:22:28 -05:00
Seymour Shlien
7fae7302c3 2022.01.05 2023-01-05 15:53:13 -05:00
Seymour Shlien
166a28d182 2022.12.30 2022-12-30 11:08:38 -05:00
Seymour Shlien
cc1a30b3b4 2022.12.27 2022-12-27 15:22:18 -05:00
Seymour Shlien
2baecffc37 2022.12.22 2022-12-22 12:08:00 -05:00
Seymour Shlien
c24f1ffdc1 2022.12.09 2022-12-09 13:31:50 -05:00
Seymour Shlien
80e8dbf505 2022.12.07 2022-12-07 16:50:19 -05:00
Seymour Shlien
13b922827d 2022.09.01 2022-09-01 14:06:21 -04:00
20 changed files with 1602 additions and 818 deletions

View File

@@ -53,13 +53,13 @@ datadir = ${prefix}/share
docdir = ${prefix}/share/doc/abcmidi
mandir = ${prefix}/share/man/man1
binaries=abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch
binaries=abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch midistats
all : abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch
all : abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch midistats
OBJECTS_ABC2MIDI=parseabc.o store.o genmidi.o midifile.o queues.o parser2.o stresspat.o music_utils.o
abc2midi : $(OBJECTS_ABC2MIDI)
$(CC) $(CFLAGS) -o abc2midi $(OBJECTS_ABC2MIDI) $(LDFLAGS) -lm
$(CC) $(CFLAGS) -o abc2midi $(OBJECTS_ABC2MIDI) $(LDFLAGS)
$(OBJECTS_ABC2MIDI): abc.h parseabc.h config.h Makefile
OBJECTS_ABC2ABC=parseabc.o toabc.o music_utils.o
@@ -72,6 +72,11 @@ midi2abc : $(OBJECTS_MIDI2ABC)
$(CC) $(CFLAGS) -o midi2abc $(OBJECTS_MIDI2ABC) $(LDFLAGS)
$(OBJECTS_MIDI2ABC): abc.h midifile.h config.h Makefile
OBJECTS_MIDISTATS=midifile.o midistats.o
midistats : $(OBJECTS_MIDISTATS)
$(CC) $(CFLAGS) -o midistats $(OBJECTS_MIDISTATS) $(LDFLAGS)
$(OBJECTS_MIDISTATS): abc.h midifile.h config.h Makefile
OBJECTS_MFTEXT=midifile.o mftext.o crack.o
mftext : $(OBJECTS_MFTEXT)
$(CC) $(CFLAGS) -o mftext $(OBJECTS_MFTEXT) $(LDFLAGS)
@@ -114,6 +119,8 @@ midifile.o : midifile.c midifile.h
midi2abc.o : midi2abc.c midifile.h
midistats.o : midistats.c midifile.h
midicopy.o : midicopy.c midicopy.h
abcmatch.o: abcmatch.c abc.h
@@ -141,7 +148,7 @@ matchsup.o : matchsup.c abc.h parseabc.h parser2.h
clean :
rm *.o ${binaries}
install: abc2midi midi2abc abc2abc mftext midicopy yaps abcmatch
install: abc2midi midi2abc abc2abc mftext midicopy yaps abcmatch midistats
$(INSTALL) -d $(DESTDIR)$(bindir)
$(INSTALL) -m 755 ${binaries} $(DESTDIR)$(bindir)
@@ -164,6 +171,7 @@ uninstall:
rm -f $(DESTDIR)$(bindir)/abc2abc
rm -f $(DESTDIR)$(bindir)/yaps
rm -f $(DESTDIR)$(bindir)/midi2abc
rm -f $(DESTDIR)$(bindir)/midistats
rm -f $(DESTDIR)$(bindir)/mftext
rm -f $(DESTDIR)$(bindir)/abcmatch
rm -f $(DESTDIR)$(bindir)/midicopy

View File

@@ -53,13 +53,13 @@ datadir = @datarootdir@
docdir = @datarootdir@/doc/abcmidi
mandir = @datarootdir@/man/man1
binaries=abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch
binaries=abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch midistats
all : abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch
all : abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch midistats
OBJECTS_ABC2MIDI=parseabc.o store.o genmidi.o midifile.o queues.o parser2.o stresspat.o music_utils.o
abc2midi : $(OBJECTS_ABC2MIDI)
$(CC) $(CFLAGS) -o abc2midi $(OBJECTS_ABC2MIDI) $(LDFLAGS) -lm
$(CC) $(CFLAGS) -o abc2midi $(OBJECTS_ABC2MIDI) $(LDFLAGS)
$(OBJECTS_ABC2MIDI): abc.h parseabc.h config.h Makefile
OBJECTS_ABC2ABC=parseabc.o toabc.o music_utils.o
@@ -72,6 +72,11 @@ midi2abc : $(OBJECTS_MIDI2ABC)
$(CC) $(CFLAGS) -o midi2abc $(OBJECTS_MIDI2ABC) $(LDFLAGS)
$(OBJECTS_MIDI2ABC): abc.h midifile.h config.h Makefile
OBJECTS_MIDISTATS=midifile.o midistats.o
midistats : $(OBJECTS_MIDISTATS)
$(CC) $(CFLAGS) -o midistats $(OBJECTS_MIDISTATS) $(LDFLAGS)
$(OBJECTS_MIDISTATS): abc.h midifile.h config.h Makefile
OBJECTS_MFTEXT=midifile.o mftext.o crack.o
mftext : $(OBJECTS_MFTEXT)
$(CC) $(CFLAGS) -o mftext $(OBJECTS_MFTEXT) $(LDFLAGS)
@@ -114,6 +119,8 @@ midifile.o : midifile.c midifile.h
midi2abc.o : midi2abc.c midifile.h
midistats.o : midistats.c midifile.h
midicopy.o : midicopy.c midicopy.h
abcmatch.o: abcmatch.c abc.h
@@ -141,7 +148,7 @@ matchsup.o : matchsup.c abc.h parseabc.h parser2.h
clean :
rm *.o ${binaries}
install: abc2midi midi2abc abc2abc mftext midicopy yaps abcmatch
install: abc2midi midi2abc abc2abc mftext midicopy yaps abcmatch midistats
$(INSTALL) -d $(DESTDIR)$(bindir)
$(INSTALL) -m 755 ${binaries} $(DESTDIR)$(bindir)
@@ -164,6 +171,7 @@ uninstall:
rm -f $(DESTDIR)$(bindir)/abc2abc
rm -f $(DESTDIR)$(bindir)/yaps
rm -f $(DESTDIR)$(bindir)/midi2abc
rm -f $(DESTDIR)$(bindir)/midistats
rm -f $(DESTDIR)$(bindir)/mftext
rm -f $(DESTDIR)$(bindir)/abcmatch
rm -f $(DESTDIR)$(bindir)/midicopy

View File

@@ -1,2 +1,2 @@
August 24 2022
January 08 2023

View File

@@ -12,14 +12,14 @@ generated by GNU Autoconf 2.67. Invocation command line was
hostname = seymour-VirtualBox
uname -m = x86_64
uname -r = 5.4.0-51-generic
uname -r = 5.15.0-56-generic
uname -s = Linux
uname -v = #56-Ubuntu SMP Mon Oct 5 14:28:49 UTC 2020
uname -v = #62-Ubuntu SMP Tue Nov 22 19:54:14 UTC 2022
/usr/bin/uname -p = unknown
/usr/bin/uname -p = x86_64
/bin/uname -X = unknown
/bin/arch = unknown
/bin/arch = x86_64
/usr/bin/arch -k = unknown
/usr/convex/getsysinfo = unknown
/usr/bin/hostinfo = unknown
@@ -27,7 +27,6 @@ uname -v = #56-Ubuntu SMP Mon Oct 5 14:28:49 UTC 2020
/usr/bin/oslevel = unknown
/bin/universe = unknown
PATH: /home/seymour/bin
PATH: /usr/local/sbin
PATH: /usr/local/bin
PATH: /usr/sbin
@@ -37,9 +36,7 @@ PATH: /bin
PATH: /usr/games
PATH: /usr/local/games
PATH: /snap/bin
PATH: /usr/local/bin
PATH: /home/seymour/jdk1.6.0_02/bin
PATH: /home/seymour/bin
PATH: /home/seymour/humdrum-tools/humextra/bin
PATH: .
@@ -47,85 +44,87 @@ PATH: .
## Core tests. ##
## ----------- ##
configure:2174: checking for gcc
configure:2190: found /usr/bin/gcc
configure:2201: result: gcc
configure:2430: checking for C compiler version
configure:2439: gcc --version >&5
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
configure:2178: checking for gcc
configure:2194: found /usr/bin/gcc
configure:2205: result: gcc
configure:2434: checking for C compiler version
configure:2443: gcc --version >&5
gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
configure:2450: $? = 0
configure:2439: gcc -v >&5
configure:2454: $? = 0
configure:2443: gcc -v >&5
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.3.0-17ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-HskZEa/gcc-9-9.3.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.3.0-1ubuntu1~22.04' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-xKiWfi/gcc-11-11.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-xKiWfi/gcc-11-11.3.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)
configure:2450: $? = 0
configure:2439: gcc -V >&5
gcc: error: unrecognized command line option '-V'
Supported LTO compression algorithms: zlib zstd
gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04)
... rest of stderr output deleted ...
configure:2454: $? = 0
configure:2443: gcc -V >&5
gcc: error: unrecognized command-line option '-V'
gcc: fatal error: no input files
compilation terminated.
configure:2450: $? = 1
configure:2439: gcc -qversion >&5
gcc: error: unrecognized command line option '-qversion'; did you mean '--version'?
configure:2454: $? = 1
configure:2443: gcc -qversion >&5
gcc: error: unrecognized command-line option '-qversion'; did you mean '--version'?
gcc: fatal error: no input files
compilation terminated.
configure:2450: $? = 1
configure:2470: checking whether the C compiler works
configure:2492: gcc conftest.c >&5
configure:2496: $? = 0
configure:2544: result: yes
configure:2547: checking for C compiler default output file name
configure:2549: result: a.out
configure:2555: checking for suffix of executables
configure:2562: gcc -o conftest conftest.c >&5
configure:2566: $? = 0
configure:2588: result:
configure:2610: checking whether we are cross compiling
configure:2618: gcc -o conftest conftest.c >&5
configure:2622: $? = 0
configure:2629: ./conftest
configure:2633: $? = 0
configure:2621: result: no
configure:2626: checking for suffix of object files
configure:2648: gcc -c conftest.c >&5
configure:2652: $? = 0
configure:2673: result: o
configure:2677: checking whether we are using the GNU C compiler
configure:2696: gcc -c conftest.c >&5
configure:2696: $? = 0
configure:2705: result: yes
configure:2714: checking whether gcc accepts -g
configure:2734: gcc -c -g conftest.c >&5
configure:2734: $? = 0
configure:2775: result: yes
configure:2792: checking for gcc option to accept ISO C89
configure:2856: gcc -c -g -O2 conftest.c >&5
configure:2856: $? = 0
configure:2869: result: none needed
configure:2947: checking for a BSD-compatible install
configure:3015: result: /usr/bin/install -c
configure:3030: checking for main in -lm
configure:3049: gcc -o conftest -O2 conftest.c -lm >&5
configure:3049: $? = 0
configure:3058: result: yes
configure:3076: checking how to run the C preprocessor
configure:3107: gcc -E conftest.c
configure:3107: $? = 0
configure:3121: gcc -E conftest.c
configure:2454: $? = 1
configure:2474: checking whether the C compiler works
configure:2496: gcc conftest.c >&5
configure:2500: $? = 0
configure:2548: result: yes
configure:2551: checking for C compiler default output file name
configure:2553: result: a.out
configure:2559: checking for suffix of executables
configure:2566: gcc -o conftest conftest.c >&5
configure:2570: $? = 0
configure:2592: result:
configure:2614: checking whether we are cross compiling
configure:2622: gcc -o conftest conftest.c >&5
configure:2626: $? = 0
configure:2633: ./conftest
configure:2637: $? = 0
configure:2652: result: no
configure:2657: checking for suffix of object files
configure:2679: gcc -c conftest.c >&5
configure:2683: $? = 0
configure:2704: result: o
configure:2708: checking whether we are using the GNU C compiler
configure:2727: gcc -c conftest.c >&5
configure:2727: $? = 0
configure:2736: result: yes
configure:2745: checking whether gcc accepts -g
configure:2765: gcc -c -g conftest.c >&5
configure:2765: $? = 0
configure:2806: result: yes
configure:2823: checking for gcc option to accept ISO C89
configure:2887: gcc -c -g -O2 conftest.c >&5
configure:2887: $? = 0
configure:2900: result: none needed
configure:2978: checking for a BSD-compatible install
configure:3046: result: /usr/bin/install -c
configure:3061: checking for main in -lm
configure:3080: gcc -o conftest -O2 conftest.c -lm >&5
configure:3080: $? = 0
configure:3089: result: yes
configure:3107: checking how to run the C preprocessor
configure:3138: gcc -E conftest.c
configure:3138: $? = 0
configure:3152: gcc -E conftest.c
conftest.c:10:10: fatal error: ac_nonexistent.h: No such file or directory
10 | #include <ac_nonexistent.h>
| ^~~~~~~~~~~~~~~~~~
compilation terminated.
configure:3121: $? = 1
configure:3152: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "abcmidi"
@@ -137,15 +136,15 @@ configure: failed program was:
| #define HAVE_LIBM 1
| /* end confdefs.h. */
| #include <ac_nonexistent.h>
configure:3146: result: gcc -E
configure:3166: gcc -E conftest.c
configure:3166: $? = 0
configure:3180: gcc -E conftest.c
configure:3177: result: gcc -E
configure:3197: gcc -E conftest.c
configure:3197: $? = 0
configure:3211: gcc -E conftest.c
conftest.c:10:10: fatal error: ac_nonexistent.h: No such file or directory
10 | #include <ac_nonexistent.h>
| ^~~~~~~~~~~~~~~~~~
compilation terminated.
configure:3180: $? = 1
configure:3211: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "abcmidi"
@@ -157,67 +156,67 @@ configure: failed program was:
| #define HAVE_LIBM 1
| /* end confdefs.h. */
| #include <ac_nonexistent.h>
configure:3209: checking for grep that handles long lines and -e
configure:3267: result: /bin/grep
configure:3272: checking for egrep
configure:3334: result: /bin/grep -E
configure:3339: checking for ANSI C header files
configure:3359: gcc -c -O2 conftest.c >&5
configure:3359: $? = 0
configure:3432: gcc -o conftest -O2 conftest.c -lm >&5
configure:3432: $? = 0
configure:3432: ./conftest
configure:3432: $? = 0
configure:3443: result: yes
configure:3456: checking for sys/types.h
configure:3456: gcc -c -O2 conftest.c >&5
configure:3456: $? = 0
configure:3456: result: yes
configure:3456: checking for sys/stat.h
configure:3456: gcc -c -O2 conftest.c >&5
configure:3456: $? = 0
configure:3456: result: yes
configure:3456: checking for stdlib.h
configure:3456: gcc -c -O2 conftest.c >&5
configure:3456: $? = 0
configure:3456: result: yes
configure:3456: checking for string.h
configure:3456: gcc -c -O2 conftest.c >&5
configure:3456: $? = 0
configure:3456: result: yes
configure:3456: checking for memory.h
configure:3456: gcc -c -O2 conftest.c >&5
configure:3456: $? = 0
configure:3456: result: yes
configure:3456: checking for strings.h
configure:3456: gcc -c -O2 conftest.c >&5
configure:3456: $? = 0
configure:3456: result: yes
configure:3456: checking for inttypes.h
configure:3456: gcc -c -O2 conftest.c >&5
configure:3456: $? = 0
configure:3456: result: yes
configure:3456: checking for stdint.h
configure:3456: gcc -c -O2 conftest.c >&5
configure:3456: $? = 0
configure:3456: result: yes
configure:3456: checking for unistd.h
configure:3456: gcc -c -O2 conftest.c >&5
configure:3456: $? = 0
configure:3456: result: yes
configure:3471: checking for stdlib.h
configure:3471: result: yes
configure:3471: checking for string.h
configure:3471: result: yes
configure:3483: checking for size_t
configure:3483: gcc -c -O2 conftest.c >&5
configure:3483: $? = 0
configure:3483: gcc -c -O2 conftest.c >&5
configure:3240: checking for grep that handles long lines and -e
configure:3298: result: /usr/bin/grep
configure:3303: checking for egrep
configure:3365: result: /usr/bin/grep -E
configure:3370: checking for ANSI C header files
configure:3390: gcc -c -O2 conftest.c >&5
configure:3390: $? = 0
configure:3463: gcc -o conftest -O2 conftest.c -lm >&5
configure:3463: $? = 0
configure:3463: ./conftest
configure:3463: $? = 0
configure:3474: result: yes
configure:3487: checking for sys/types.h
configure:3487: gcc -c -O2 conftest.c >&5
configure:3487: $? = 0
configure:3487: result: yes
configure:3487: checking for sys/stat.h
configure:3487: gcc -c -O2 conftest.c >&5
configure:3487: $? = 0
configure:3487: result: yes
configure:3487: checking for stdlib.h
configure:3487: gcc -c -O2 conftest.c >&5
configure:3487: $? = 0
configure:3487: result: yes
configure:3487: checking for string.h
configure:3487: gcc -c -O2 conftest.c >&5
configure:3487: $? = 0
configure:3487: result: yes
configure:3487: checking for memory.h
configure:3487: gcc -c -O2 conftest.c >&5
configure:3487: $? = 0
configure:3487: result: yes
configure:3487: checking for strings.h
configure:3487: gcc -c -O2 conftest.c >&5
configure:3487: $? = 0
configure:3487: result: yes
configure:3487: checking for inttypes.h
configure:3487: gcc -c -O2 conftest.c >&5
configure:3487: $? = 0
configure:3487: result: yes
configure:3487: checking for stdint.h
configure:3487: gcc -c -O2 conftest.c >&5
configure:3487: $? = 0
configure:3487: result: yes
configure:3487: checking for unistd.h
configure:3487: gcc -c -O2 conftest.c >&5
configure:3487: $? = 0
configure:3487: result: yes
configure:3502: checking for stdlib.h
configure:3502: result: yes
configure:3502: checking for string.h
configure:3502: result: yes
configure:3514: checking for size_t
configure:3514: gcc -c -O2 conftest.c >&5
configure:3514: $? = 0
configure:3514: gcc -c -O2 conftest.c >&5
conftest.c: In function 'main':
conftest.c:58:21: error: expected expression before ')' token
58 | if (sizeof ((size_t)))
| ^
configure:3483: $? = 1
configure:3514: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "abcmidi"
@@ -281,37 +280,37 @@ configure: failed program was:
| ;
| return 0;
| }
configure:3483: result: yes
configure:3496: checking for error_at_line
configure:3512: gcc -o conftest -O2 conftest.c -lm >&5
configure:3512: $? = 0
configure:3520: result: yes
configure:3533: checking for stdlib.h
configure:3533: result: yes
configure:3543: checking for GNU libc compatible malloc
configure:3567: gcc -o conftest -O2 conftest.c -lm >&5
configure:3567: $? = 0
configure:3567: ./conftest
configure:3567: $? = 0
configure:3577: result: yes
configure:3601: checking for strcasecmp
configure:3601: gcc -o conftest -O2 conftest.c -lm >&5
configure:3514: result: yes
configure:3527: checking for error_at_line
configure:3543: gcc -o conftest -O2 conftest.c -lm >&5
configure:3543: $? = 0
configure:3551: result: yes
configure:3564: checking for stdlib.h
configure:3564: result: yes
configure:3574: checking for GNU libc compatible malloc
configure:3598: gcc -o conftest -O2 conftest.c -lm >&5
configure:3598: $? = 0
configure:3598: ./conftest
configure:3598: $? = 0
configure:3608: result: yes
configure:3632: checking for strcasecmp
configure:3632: gcc -o conftest -O2 conftest.c -lm >&5
conftest.c:47:6: warning: conflicting types for built-in function 'strcasecmp'; expected 'int(const char *, const char *)' [-Wbuiltin-declaration-mismatch]
47 | char strcasecmp ();
| ^~~~~~~~~~
configure:3601: $? = 0
configure:3601: result: yes
configure:3601: checking for strchr
configure:3601: gcc -o conftest -O2 conftest.c -lm >&5
configure:3632: $? = 0
configure:3632: result: yes
configure:3632: checking for strchr
configure:3632: gcc -o conftest -O2 conftest.c -lm >&5
conftest.c:48:6: warning: conflicting types for built-in function 'strchr'; expected 'char *(const char *, int)' [-Wbuiltin-declaration-mismatch]
48 | char strchr ();
| ^~~~~~
conftest.c:36:1: note: 'strchr' is declared in header '<string.h>'
35 | # include <limits.h>
36 | #else
configure:3601: $? = 0
configure:3601: result: yes
configure:3708: creating ./config.status
configure:3632: $? = 0
configure:3632: result: yes
configure:3739: creating ./config.status
## ---------------------- ##
## Running config.status. ##
@@ -328,8 +327,9 @@ generated by GNU Autoconf 2.67. Invocation command line was
on seymour-VirtualBox
config.status:813: creating Makefile
config.status:813: creating config.h
config.status:817: creating Makefile
config.status:817: creating config.h
config.status:991: config.h is unchanged
## ---------------- ##
## Cache variables. ##
@@ -370,8 +370,8 @@ ac_cv_header_unistd_h=yes
ac_cv_lib_error_at_line=yes
ac_cv_lib_m_main=yes
ac_cv_objext=o
ac_cv_path_EGREP='/bin/grep -E'
ac_cv_path_GREP=/bin/grep
ac_cv_path_EGREP='/usr/bin/grep -E'
ac_cv_path_GREP=/usr/bin/grep
ac_cv_path_install='/usr/bin/install -c'
ac_cv_prog_CPP='gcc -E'
ac_cv_prog_ac_ct_CC=gcc
@@ -391,9 +391,9 @@ DEFS='-DHAVE_CONFIG_H'
ECHO_C=''
ECHO_N='-n'
ECHO_T=''
EGREP='/bin/grep -E'
EGREP='/usr/bin/grep -E'
EXEEXT=''
GREP='/bin/grep'
GREP='/usr/bin/grep'
INSTALL_DATA='${INSTALL} -m 644'
INSTALL_PROGRAM='${INSTALL}'
INSTALL_SCRIPT='${INSTALL}'

View File

@@ -612,8 +612,8 @@ echo 'BEGIN {' >"$tmp/subs1.awk" &&
cat >>"$tmp/subs1.awk" <<\_ACAWK &&
S["LTLIBOBJS"]=""
S["LIBOBJS"]=""
S["EGREP"]="/bin/grep -E"
S["GREP"]="/bin/grep"
S["EGREP"]="/usr/bin/grep -E"
S["GREP"]="/usr/bin/grep"
S["CPP"]="gcc -E"
S["INSTALL_DATA"]="${INSTALL} -m 644"
S["INSTALL_SCRIPT"]="${INSTALL}"

View File

@@ -14853,7 +14853,183 @@ Fixed the abc parser so it does not report a malformed note
when it encounters a dotted bar line .| -- (in parsemusic() in parseabc.c).
The dotted bar line is treated as a regular bar line.
August 23 2022
midi2abc -midistats introducing channel spread.
August 23 2022, September 01 2022
midi2abc -midistats introducing quietTime.
December 5 2022
Midi2abc has been getting too big and it is time to split it into
separate applications. Midistats is a new application that will replace
the midi2abc -midistats option.
December 9 2022
Cleaning out -stats code in midi2abc.
December 21 2022
abc2midi:
Wnen <note1> equals <note2> in the instrument=<note1>/<note2> directive,
note2 should be treated as c (midi pitch 72). Fix: parsesound in
parseabc.c was modified to return a midi pitch of 72 when the two
notes are equal.
test file:
X:1
T: transpose
M: 4/4
L: 1/4
K: C instrument=F/F
FGAB|cdef|
produces a midi file which looks like
X: 1
T: from h1.mid
M: 4/4
L: 1/8
Q:1/4=120
K:C % 0 sharps
V:1
c2 d2 e2 ^f2| \
g2 a2 b2 c'2|
when it was translated back to abc using midi2abc.
Note that this change also applies to sound= and shift= even though
this may not be specified in the standard
http://abcnotation.com/wiki/abc:standard:v2.2#transposing_instrument_examples
December 22 2022
abcmidi: segementation fault. The following file produced a
segmentation fault.
X:1
T: transpose
M: 4/4
L: 1/4
K: C instrument=F
FGAB|cdef|
Analysis: there is an invisible space following F in the
line K: C instrument=F . As a result the function note2midi
called pitch2midi with an invalid note (a space). The line
p = (int) ((long) strchr(anoctave, note) - (long) anoctave);
returned a bad index into the scale array.
Fix: tested that p is in the range 0 to 7.
December 27 2022
abcmidi: The instrument=<note1>/<note2> is defined as a shorthand
for score=<note1><note2> sound=c<note2>. For instrument=,<note1>
indicates the key of the instrument and <note2> is either c or C.
The sound= directive specifies the note and how it is played.
For example, sound=c_B indicates that the note c is played as
_B on the instrument. Every note is transposed down by two semitones.
The problem is that, the notes in the instrument directive are
in the opposite order of the sound= and score= directives.
The function parsesound() in parseabc.c treats takes care of
the directives sound =, shift = and instrument =.
Unfortunately, all these directives are treated in the same
manner causing the instrument= directive to transpose
in the wrong direction.
Fix: for the special case, instrument=, transpose is set to
p1 - p2 instead of p2 - p1.
The '/' is only part of the instrument= syntax. Note2midi has
an extra parameter, word, indicating the type of directive.
It will issue a warning if it detects a '/' in the sound= or
shift= directives.
December 30 2022
abcmidi: The instrument=*/c is a special directive that suppresses
a transpose. For example:
X:2
T: transpose using instrument=_B/c
T: clarinet coded in concert pitch, displayed in Bb (as in player part)
M: 4/4
L: 1/4
K: C
V:1 nm="Flute"
CDEF|GABc|cBAG|FEDC|
V:2 instrument=_B/c nm="Clarinet\nin Bb"
CDEF|GABc|cBAG|FEDC|
The notes in V:2 are displayed up using score=_Bc, but they are still
played as written (sound=cc does nothing).
Fix: the code in the block
if (casecmp(word,"instrument") == 0 {
...
}
in parsesound() (parseabc.c) was rewritten.
January 05 2023
abc2midi: instrument =F/D transposes cdec up by 3 semitones instead of
down by 10 semitones in the following example.
X:5
T: wrong octave
M: 4/4
K:C
V:1 instrument=F/D
cdec z4
V:2
z4 c4
Fix: Hudson Lacerda supplied me with pseudo-code (doc/hudsonshift.txt)
which describes how all the transpose directives should work.
This code was implemented in parseSoundScore() which now replaces
parseSound(). It also fixes yaps.
January 06 2023
abcmidi ignores sound=cD in the following example.
X:2
T: sound + score
M: 4/4
K:C
V:1 sound=cD score=FD
cdec z4
V:2
z4 c4
Analysis: *transpose is set to -10 by parseSoundScore when it
processes sound=CD but when parseSoundScore is called again
with score=FD it sets *transpose to 0, the initialized value
of transp_sound. The last value of *transpose is used by
event_voice.
Fix: if parseSoundScore is called by the abc2midi executable,
then *transpose is not set to transp_sound when the score=
directive is processed. There is a similar issue when
parseSoundScore is called by yaps. We do not want to set
*transpose to transp_score when the sound= is processed.
January 08 2023
abc2abc should replicate the score=, shift=, sound=, and instrument=
directives but otherwise ignore them.
Fix: parseSoundScore() in parseabc.c does nothing if it is
called from abc2abc and return 0. The function parseother(),
which is called from parsevoice() or parsekey(), will output
all other directives in the K: or V: command.

57
doc/hudsonshift.txt Executable file
View File

@@ -0,0 +1,57 @@
init:
transp_sound = transp_score = 0;
ABC2MIDI: use transp_sound;
YAPS: use transp_score;
ABC2ABC: ignore and replicate instructions to output;
/******************************************/
if (p1==0) error();
sound:
if (p2==0)
error();
transp_sound = p2-p1;
/*
sound=<note1><note2> transposes the playback according to the
specified interval (the typeset score is not affected)
*/
score:
if (p2==0)
p2 = ( 72 );
transp_score = p2-p1;
/*
score=<note1><note2> transposes the typeset score according to the
specified interval (the playback is not affected); if the second note
is omitted it is assumed to be a c (see writing abc code for
transposing instruments)
*/
instrument:
if (p2==0)
p2 = p1;
transp_score = p2-p1;
transp_sound = p2-( 72 );
/*
instrument=<note1>/<note2> is defined as score=<note1><note2> sound=c<note2>
*/
shift:
if (p2==0)
error();
transp_score = transp_sound = p2-p1;
/*
shift=<note1><note2> transposes the typeset score and the playback
according to the specified interval
*/
/******************************************/

View File

@@ -1,106 +0,0 @@
The output of midi2abc with the -stats is used by
the midiexplorer application which can by found on
sourceforge.net. The output looks something like this
seymour@corsair:~/abc$ midi2abc summer.mid -stats
ntrks 10
ppqn 120
trk 1
timesig 4/4 0.00
keysig C 0 0 0.00
tempo 132.00 bpm
trk 2
metatext 3 Synth Bass 1
program 1 38
trkinfo 1 38 156 774 41022 50468
trk 3
metatext 3 Brass 1
program 2 61
trkinfo 2 61 102 0 6618 2982
trk 4
...
trk 10
metatext 3 Drums
program 10 17
trkinfo 10 17 1390 1158 108340 25777
npulses 58552
tempocmds 1
pitchbends 0
programcmd 0
progs 35 38 50 54 61 80 81 102
progsact 49460 50468 15426 3237 2982 22295 15938 4703
progcolor 0.00 0.00 0.00 0.00 0.00 1.71 0.00 0.26 0.06 0.05 0.00 0.00 0.00 0.65 0.00 0.08 0.00
drums 36 38 39 42 54
drumhits 548 287 128 1073 512
pitches 473 0 1267 216 20 344 36 717 0 321 364 0
pitchact 0.32 0.00 1.10 0.15 0.03 0.22 0.03 0.51 0.00 0.26 0.20 0.00
chnact 0.86 0.05 0.06 0.27 0.38 0.26 0.08 0.84 0.00 0.44 0.00 0.00 0.00 0.00 0.00 0.00
pitchentropy 2.567729
Here is a description of some of the values which are outputted.
timesig 4/4 beat number
is issued each time the time signature is redefined. The beat number
is a decimal number in quarter beats.
The same apples for keysig (key signature) and tempo redefinition.
For each channel, midi2abc prints a trkinfo vector which contains
the following information.
the channel number
the first program number assigned to the channel
the number of notes not appearing inside a chord
the number of notes appearing in a chord
the sum of all the MIDI pitches of the notes
the sum of all the note durations in pulses
Finally, midi2abc outputs the following data.
npulses -- the length of the longest track in pulses
tempocmds - the number of tempo commands encountered
pitchbends - the number of pitchbend commands encountered
programcmd - the number of times the program assignment is
reassigned
progs vector - list of all the MIDI programs used
progsact vector - the activity for each of the above MIDI programs. The
activity is the sum of the note durations in pulses for each of the
above programs.
progcolor - described below
drums - a list of all the MIDI percussion numbers used
drumhits - the number of note on commands for each of the above percussion
instruments.
pitches - the number of note on commands for each of the 12 pitch
classes (C, C#, D, D# ... B)
pitchact - duration in pulses of all notes grouped by pitch classes
chnact - duration in pulses of all notes grouped by channel
pitchentropy - entropy of the pitchact probability density function
progcolor: The 128 MIDI program numbers are mapped into 17 classes.
These classes group keyboard instruments, brass instruments, guitar
instruments etc into separate groups defined here.
static int progmapper[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 2,
3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 4, 4, 4, 4, 4, 2,
5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 2, 7, 10,
7, 7, 7, 7, 8, 8, 8, 8,
9, 9, 9, 9, 9, 9, 9, 9,
11, 11, 11, 11, 11, 11, 11, 11,
12, 12, 12, 12, 12, 12, 12, 12,
13, 13, 13, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15,
2, 2, 2, 2, 2, 12, 6, 12,
1, 1, 10, 10, 10, 10, 10, 1,
16, 16, 16, 16, 16, 16, 16, 16
};
The activity in each of these programs is measured, normalized to
a unit length vector and returned in the progcolor vector.

View File

@@ -172,23 +172,6 @@ the given string.
.B -origin \fistring\fP
Adds an O: field with the given string.
.TP
.B -stats
Extracts the characteristics of the given midi file. They include
ntrks - the number of tracks, ppqn - pulses per quarter note,
timesig - time signature, keysig - key signature, program - mapping
between channel number and midi program, npulses - length of the
midi file in pulses, tempocmd - number of times the tempo has
been specified, pitchbends - number of pitchbends, pitchbendin -
number of pitchbends in each of the channels, programcmd - number of
times the midi program has been revised, progs and progsact - the
programs used and the number of pulses these programs used, drums -
the drum numbers that were used, drumhits - the number of times
each of those drums were hit, pitches - the number of times the
11 pitch classes (C C# etc...) were activated and a few other
complex variables. These characteristics are used in other
applications such as midiexplorer. More details are available
in the file midi2abc-stats.txt included in the doc/ folder
of the abcmidi distribution package.
.SS FEATURES

87
doc/midistats.1 Normal file
View File

@@ -0,0 +1,87 @@
.TH MIDISTATS 1 "9 December 2022"
.SH NAME
\fBmidistats\fP \- program to summarize the statistical properties of a midi file
.SH SYNOPSIS
midistats \fIinfile\fP
.SH DESCRIPTION
\fImidistats\fP analyzes the contents of a midi file and outputs key
information and various statistical measures. Each line of output
starts with the name of the variable or variable array and the
associated values. The output is interpreted by the user interface
midiexplorer.tcl. Both programs are still being improved. Here
is an explanation of some of the output.
.PP
ntrks indicates the number of tracks in the midi file.
.PP
ppqn the number of midi pulses per quarter note.
.PP
keysig the key signature, followed by a major/minor flag, the number
of sharps (positive) or flats (negative) in the key, and the beat number
where the key signature was found.
.PP
trk is followed by the track number for which the following information
applies.
.PP
program is followed by the channel number and the General Midi Program
number.
.PP
trkinfo is an array of 8 numbers which indicates the statistical properties
of the track of interest. The following data is given:
the channel number,
the first program assigned to this channel,
the number of notes for this channel counting any chords as one note,
the total number of notes for this for this channel,
the sum of the MIDI pitches for all the notes,
the sum of the note durations in MIDI pulse units,
the number of control parameter messages,
the number of pressure messages.
and the number of distinct rhythm patterns for each channel
.PP
After processing all the individual tracks, the following information
applies to the entire midi file.
.PP
npulses is the length of the longest midi track in midi pulse units
.PP
tempocmds specifies the number of times the tempo is changed in this
file.
.PP
pitchbends specifies the total number of pitchbends in this file.
.PP
progs is a list of all the midi programs addressed
.PP
progsact the amount of activity for each of the above midi programs.
The activity is the sum of the note durations in midi pulse units.
.PP
progcolor: is a 17 dimensional vector where each component maps into
a specific group of MIDI programs. Some of these groups are, keyboard
instruments, brass instruments, wind instruments, and etc. More information
can be found in the midiexplorer documentation.
.PP
drums is a list of all the percussion instruments (channel 9) that were
used.
.PP
drumhits indicates the number of notes for each of the above percussion
instruments.
.PP
pitches is a histogram for the 11 pitch classes (C, C#, D ...B)
that occur in the midi file.
.PP
pitchact is a similar histogram but is weighted by the length of
the notes.
.PP
quietTime is used to compute the track/channel spread in midiexplorer.
It is computed by summing up all the midi pulses which occur
in gaps greater than 8 beats.
.PP
totalrhythmpatterns is the total number of bar rhythm patterns for
all channels except the percussion channel.
.PP
collisions. Midistats counts the bar rhythm patterns using a hashing
function. Presently collisions are ignored so occasionally two
distinct rhythm patterns are counted as one.
.SH AUTHOR
Seymour Shlien <fy733@ncf.ca>

View File

@@ -1,6 +0,0 @@
/abc2midi.txt/1.1.1.1/Thu Sep 28 18:17:04 2006//
/coding.txt/1.1.1.1/Thu Sep 28 18:17:04 2006//
/midi2abc.txt/1.1.1.1/Thu Sep 28 18:17:04 2006//
/split.abc/1.1.1.1/Thu Sep 28 18:17:04 2006//
/yaps.txt/1.1.1.1/Thu Sep 28 18:17:04 2006//
D

View File

@@ -1 +0,0 @@
abcmidi/doc/programming

View File

@@ -1 +0,0 @@
/home/seymour/CVSREPOS

View File

@@ -1,11 +1,12 @@
abcMIDI : abc <-> MIDI conversion utilities
midi2abc version 3.56 August 24 2022
abc2midi version 4.76 August 01 2022
abc2abc version 2.18 June 14 2022
yaps version 1.90 June 14 2022
midi2abc version 3.58 December 09 2022
abc2midi version 4.82 January 06 2023
abc2abc version 2.19 January 08 2023
yaps version 1.92 January 06 2023
abcmatch version 1.82 June 14 2022
midicopy version 1.38 May 06 2022
midistats version 0.58 December 09 2022
24th January 2002

View File

@@ -45,7 +45,7 @@
* based on public domain 'midifilelib' package.
*/
#define VERSION "3.56 August 24 2022 midi2abc"
#define VERSION "3.58 December 09 2022 midi2abc"
#include <limits.h>
/* Microsoft Visual C++ Version 6.0 or higher */
@@ -79,12 +79,9 @@ extern char* strchr();
#define MIDDLE 72
void initfuncs();
void setupkey(int);
void stats_finish();
int testtrack(int trackno, int barbeats, int anacrusis);
int open_note(int chan, int pitch, int vol);
int close_note(int chan, int pitch, int *initvol);
float histogram_entropy (int *histogram, int size);
void stats_noteoff(int chan,int pitch,int vol);
void reset_back_array (); /* [SS] 2019-05-08 */
@@ -251,67 +248,7 @@ void txt_trackstart_type0();
void txt_noteon_type0(int,int,int);
void txt_program_type0(int,int);
/* The following variables are used by the -stats option
* which is used by a separate application called midiexplorer.tcl.
* The channel numbers go from 1 to 16 instead of 0 to 15
*/
struct trkstat {
int notecount[17];
int chordcount[17];
int notemeanpitch[17];
int notelength[17];
int pitchbend[17];
int pressure[17];
int cntlparam[17];
int program[17];
int tempo[17];
int npulses[17];
int lastNoteOff[17];
int quietTime[17];
} trkdata;
/* The trkstat references the individual channels in the midi file.
* notecount is the number of notes or bass notes in the chord.
* chordcount is the number of notes not counting the bass notes.
* notemeanpitch is the average pitch for the channel.
* notelength is the average note length.
* pitchbend is the number of pitch bends for the channel.
* pressure is the number of control pressure commands.
* cntlparam is the number of control parameter commands.
* program is number of times there is a program command for the channel.
* tempo is the number of times there is a tempo command.
* npulses is the number of pulses.
*/
int progcolor[17]; /* used by stats_program */
int drumhistogram[82]; /* counts drum noteons */
int pitchhistogram[12]; /* pitch distribution for non drum notes */
int channel2prog[17]; /* maps channel to program */
int channel2nnotes[17]; /*maps channel to note count */
int chnactivity[17]; /* [SS] 2018-02-02 */
int progactivity[128]; /* [SS] 2018-02-02 */
int pitchclass_activity[12]; /* [SS] 2018-02-02 */
/* [SS] 2017-11-01 */
static int progmapper[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 2,
3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 4, 4, 4, 4, 4, 2,
5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 2, 7, 10,
7, 7, 7, 7, 8, 8, 8, 8,
9, 9, 9, 9, 9, 9, 9, 9,
11, 11, 11, 11, 11, 11, 11, 11,
12, 12, 12, 12, 12, 12, 12, 12,
13, 13, 13, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15,
2, 2, 2, 2, 2, 12, 6, 12,
1, 1, 10, 10, 10, 10, 10, 1,
16, 16, 16, 16, 16, 16, 16, 16
};
/* Stage 1. Parsing MIDI file */
@@ -609,15 +546,6 @@ char *s;
}
/* [SS] 2017-11-19 */
void stats_error(s)
char *s;
{
fprintf(stderr,"Error: %s\n",s);
fprintf(stderr,"activetrack %d\n",tracknum);
stats_finish();
}
void txt_header(xformat,ntrks,ldivision)
@@ -731,12 +659,6 @@ int chan, pitch, press;
{
}
void stats_pressure(chan,press)
int chan, press;
{
trkdata.pressure[0]++;
trkdata.pressure[chan+1]++; /* [SS] 2022.04.28 */
}
void txt_parameter(chan,control,value)
int chan, control, value;
@@ -1140,152 +1062,7 @@ void mftxt_header (int format, int ntrks, int ldivision)
}
void stats_header (int format, int ntrks, int ldivision)
{
int i;
division = ldivision;
quietLimit = ldivision*8;
printf("ntrks %d\n",ntrks);
printf("ppqn %d\n",ldivision);
chordthreshold = ldivision/16; /* [SS] 2018-01-21 */
trkdata.tempo[0] = 0;
trkdata.pressure[0] = 0;
trkdata.program[0] = 0;
for (i=0;i<17;i++) {
trkdata.npulses[i] = 0;
trkdata.pitchbend[i] = 0;
trkdata.cntlparam[i] = 0; /* [SS] 2022-03-04 */
trkdata.pressure[i] = 0; /* [SS] 2022-03-04 */
trkdata.quietTime[i] = 0; /* [SS] 2022-08-22 */
progcolor[i] = 0;
channel2prog[i] = -1;
channel2nnotes[i] = 0;
chnactivity[i] = 0; /* [SS] 2018-02-02 */
}
for (i=0;i<82;i++) drumhistogram[i] = 0;
for (i=0;i<12;i++) pitchhistogram[i] = 0; /* [SS] 2017-11-01 */
for (i=0;i<12;i++) pitchclass_activity[i] = 0; /* [SS] 2018-02-02 */
for (i=0;i<128;i++) progactivity[i] = 0; /* [SS] 2018-02-02 */
}
void determine_progcolor ()
{
int i;
for (i=0;i<17;i++) progcolor[i] =0;
for (i=0;i<128;i++) {
progcolor[progmapper[i]] += progactivity[i];
}
}
/* [SS] 2018-04-24 */
void output_progs_data () {
int i;
/* check that there is valid progactivity */
printf("progs ");
for (i=0;i<128;i++)
if(progactivity[i] > 0) printf(" %d",i);
printf("\nprogsact ");
for (i=0;i<128;i++)
if(progactivity[i] > 0) printf(" %d",progactivity[i]);
}
void stats_finish()
{
int i; /* [SDG] 2020-06-03 */
int npulses;
int nprogs;
double delta;
npulses = trkdata.npulses[0];
printf("npulses %d\n",trkdata.npulses[0]);
printf("tempocmds %d\n",trkdata.tempo[0]);
printf("pitchbends %d\n",trkdata.pitchbend[0]);
for (i=1;i<17;i++) {
if (trkdata.pitchbend[i] > 0) {
printf("pitchbendin %d %d\n",i,trkdata.pitchbend[i]); }
}
if (trkdata.pressure[0] > 0)
printf("pressure %d\n",trkdata.pressure[0]);
printf("programcmd %d\n",trkdata.program[0]);
nprogs = 0; /* [SS] 2018-04-24 */
for (i=1;i<128;i++)
if(progactivity[i] >0) nprogs++;
if (nprogs > 0) output_progs_data();
else {
for (i=0;i<17;i++)
if(chnactivity[i] > 0)
progactivity[channel2prog[i]] = chnactivity[i];
output_progs_data();
}
determine_progcolor();
printf("\nprogcolor ");
if (npulses > 0)
for (i=0;i<17;i++) printf("%5.2f ",progcolor[i]/(double) npulses);
else
for (i=0;i<17;i++) printf("%5.2f ",(double) progcolor[i]);
printf("\n");
printf("drums ");
for (i=35;i<82;i++) {
if (drumhistogram[i] > 0) printf("%d ",i);
}
printf("\ndrumhits ");
for (i=35;i<82;i++) {
if (drumhistogram[i] > 0) printf("%d ",drumhistogram[i]);
}
printf("\npitches "); /* [SS] 2017-11-01 */
for (i=0;i<12;i++) printf("%d ",pitchhistogram[i]);
printf("\npitchact "); /* [SS] 2018-02-02 */
if (npulses > 0)
for (i=0;i<12;i++) printf("%5.2f ",pitchclass_activity[i]/(double) npulses);
else
for (i=0;i<12;i++) printf("%5.2f ",(double) pitchclass_activity[i]);
printf("\nchnact "); /* [SS] 2018-02-08 */
if (npulses > 0)
for (i=1;i<17;i++) printf("%5.2f ",chnactivity[i]/(double) trkdata.npulses[0]);
else
for (i=0;i<17;i++) printf("%5.2f ",(double) chnactivity[i]);
printf("\nspread ");
for (i=1;i<17;i++) {
delta = trkdata.npulses[0] - trkdata.quietTime[i];
if (trkdata.quietTime[i] < quietLimit) delta = trkdata.npulses[0];
delta = delta / (double) trkdata.npulses[0];
printf (" %5.3f ", delta);
}
printf("\npitchentropy %f\n",histogram_entropy(pitchclass_activity,12));
printf("\n");
}
float histogram_entropy (int *histogram, int size)
{
int i;
int total;
float entropy;
float e,p;
total = 0;
entropy = 0.0;
for (i=0;i<size;i++) {
total += histogram[i];
}
for (i=0;i<size;i++) {
if (histogram[i] < 1) continue;
p = (float) histogram[i]/total;
e = p*log(p);
entropy = entropy + e;
}
return -entropy/log(2.0);
}
@@ -1298,68 +1075,9 @@ void mftxt_trackstart()
printf("Track %d contains %d bytes\n",tracknum,numbytes);
}
void output_count_trkdata(data_array,name)
int data_array[];
char *name;
{
int i,sum;
sum = 0;
for (i=1;i<17;i++) sum += data_array[i];
if (sum != 0) {
for (i=0;i<17;i++)
if(data_array[i]>0) {
printf("%s ",name);
printf("%d %d ",i,data_array[i]);
printf("\n");
}
}
}
void output_track_summary () {
int i;
/* find first channel containing data */
for (i=0;i<17;i++) {
if(trkdata.notecount[i] == 0 && trkdata.chordcount[i] == 0) continue;
printf("trkinfo ");
printf("%d %d ",i,trkdata.program[i]); /* channel number and program*/
printf("%d %d ",trkdata.notecount[i],trkdata.chordcount[i]);
printf("%d %d ",trkdata.notemeanpitch[i], trkdata.notelength[i]);
printf("%d %d ",trkdata.cntlparam[i],trkdata.pressure[i]); /* [SS] 2022-03-04 */
printf("\n");
channel2nnotes[i] += trkdata.notecount[i] + trkdata.chordcount[i];
}
}
void stats_trackstart()
{
int i;
tracknum++;
for (i=0;i<17;i++) {
trkdata.notecount[i] = 0;
trkdata.notemeanpitch[i] = 0;
trkdata.notelength[i] = 0;
trkdata.chordcount[i] = 0;
trkdata.cntlparam[i] = 0;
last_tick[i] = -1;
last_on_tick[i] = -1;
}
printf("trk %d \n",tracknum);
}
void stats_trackend()
{
trkdata.npulses[tracknum] = Mf_currtime;
if (trkdata.npulses[0] < Mf_currtime) trkdata.npulses[0] = Mf_currtime;
output_track_summary();
}
void mftxt_noteon(chan,pitch,vol)
int chan, pitch, vol;
{
@@ -1374,38 +1092,6 @@ int chan, pitch, vol;
printf("\n");
}
void stats_noteon(chan,pitch,vol)
int chan, pitch, vol;
{
int delta;
if (vol == 0) {
/* treat as noteoff */
stats_noteoff(chan,pitch,vol);
trkdata.lastNoteOff[chan+1] = Mf_currtime; /* [SS] 2022.08.22 */
return;
}
trkdata.notemeanpitch[chan+1] += pitch;
if (trkdata.lastNoteOff[chan+1] >= 0) {
delta = Mf_currtime - trkdata.lastNoteOff[chan+1];
trkdata.lastNoteOff[chan+1] = -1; /* in case of chord */
if (delta > quietLimit) {
trkdata.quietTime[chan+1] += delta;
}
}
if (abs(Mf_currtime - last_on_tick[chan+1]) < chordthreshold) trkdata.chordcount[chan+1]++;
else trkdata.notecount[chan+1]++; /* [SS] 2019-08-02 */
last_tick[chan+1] = Mf_currtime;
last_on_tick[chan+1] = Mf_currtime; /* [SS] 2019-08-02 */
/* last_on_tick not updated by stats_noteoff */
if (chan == 9) {
if (pitch < 0 || pitch > 81)
printf("****illegal drum value %d\n",pitch);
else drumhistogram[pitch]++;
}
else pitchhistogram[pitch % 12]++; /* [SS] 2017-11-01 */
}
void mftxt_noteoff(chan,pitch,vol)
int chan, pitch, vol;
@@ -1420,28 +1106,6 @@ int chan, pitch, vol;
}
void stats_noteoff(int chan,int pitch,int vol)
{
int length;
int program;
/* ignore if there was no noteon */
if (last_tick[chan+1] == -1) return;
length = Mf_currtime - last_tick[chan+1];
trkdata.notelength[chan+1] += length;
trkdata.lastNoteOff[chan+1] = Mf_currtime; /* [SS] 2022.08.22 */
chnactivity[chan+1] += length;
if (chan == 9) return; /* drum channel */
pitchclass_activity[pitch % 12] += length;
program = trkdata.program[chan+1];
progactivity[program] += length;
/* [SS] 2018-04-18 */
if(Mf_currtime > last_tick[chan+1]) last_tick[chan+1] = Mf_currtime;
}
void stats_eot () {
trkdata.lastNoteOff[0] = Mf_currtime; /* [SS] 2022.08.24 */
}
void mftxt_polypressure(chan,pitch,press)
@@ -1479,12 +1143,6 @@ int chan, lsb, msb;
printf("Pitchbend %2d %d cents = %6.3f (cents)\n",chan+1,pitchbend,cents);
}
void stats_pitchbend(chan,lsb,msb)
int chan, lsb, msb;
{
trkdata.pitchbend[0]++;
trkdata.pitchbend[chan+1]++;
}
void mftxt_program(chan,program)
int chan, program;
@@ -1541,23 +1199,6 @@ static char *patches[] = {
}
void stats_program(chan,program)
int chan, program;
{
int beatnumber;
if (program <0 || program > 127) return; /* [SS] 2018-03-06 */
if (trkdata.program[chan+1] != 0) {
beatnumber = Mf_currtime/division;
printf("cprogram %d %d %d\n",chan+1,program,beatnumber);
/* count number of times the program was modified for a channel */
trkdata.program[0] = trkdata.program[0]+1;
} else {
printf("program %d %d\n",chan+1,program);
trkdata.program[chan+1] = program;
}
if (channel2prog[chan+1]== -1) channel2prog[chan+1] = program;
}
void mftxt_parameter(chan,control,value)
int chan, control, value;
@@ -1636,15 +1277,6 @@ int chan, control, value;
printf("CntlParm %2d %s = %d\n",chan+1, ctype[control],value);
}
void stats_parameter(chan,control,value)
int chan, control, value;
{
/*if (control == 7) {
printf("cntrlvolume %d %d \n",chan+1,value);
}
*/
trkdata.cntlparam[chan+1]++;
}
void mftxt_metatext(type,leng,mess)
int type, leng;
@@ -1682,17 +1314,6 @@ char *mess;
}
void stats_metatext(type,leng,mess)
int type, leng;
char *mess;
{
int i;
if (type != 3) return;
printf("metatext %d ",type);
for (i=0;i<leng;i++) printf("%c",mess[i]);
printf("\n");
}
void mftxt_keysig(sf,mi)
int sf, mi;
@@ -1711,25 +1332,6 @@ int sf, mi;
}
/* [SS] 2018-01-02 */
void stats_keysig(sf,mi)
int sf, mi;
{
float beatnumber;
static char *major[] = {"Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F",
"C", "G", "D", "A", "E", "B", "F#", "C#"};
static char *minor[] = {"Abmin", "Ebmin", "Bbmin", "Fmin", "Cmin",
"Gmin", "Dmin", "Amin", "Emin", "Bmin", "F#min", "C#min", "G#min"};
int index;
beatnumber = Mf_currtime/division;
index = sf + 7;
if (index < 0 || index >12) return;
if (mi)
printf("keysig %s %d %d %6.2f\n",minor[index],sf,mi,beatnumber);
else
printf("keysig %s %d %d %6.2f\n",major[index],sf,mi,beatnumber);
}
void mftxt_tempo(ltempo)
long ltempo;
@@ -1739,17 +1341,6 @@ long ltempo;
printf("Metatext tempo = %6.2f bpm\n",60000000.0/tempo);
}
/* [SS] 2018-01-02 */
void stats_tempo(ltempo)
long ltempo;
{
float beatnumber;
tempo = ltempo;
beatnumber = Mf_currtime/division;
if (trkdata.tempo[0] == 0) printf("tempo %6.2f bpm\n",60000000.0/tempo);
else if (trkdata.tempo[0] < 10) printf("ctempo %6.2f %6.2f\n",60000000.0/tempo,beatnumber);
trkdata.tempo[0]++;
}
void mftxt_timesig(nn,dd,cc,bb)
int nn, dd, cc, bb;
@@ -1763,16 +1354,6 @@ int nn, dd, cc, bb;
32nd-notes/24-MIDI-clocks=%d\n", nn,denom,cc,bb); */
}
void stats_timesig(nn,dd,cc,bb)
int nn, dd, cc, bb;
{
float beatnumber;
int denom = 1;
beatnumber = Mf_currtime/division;
while ( dd-- > 0 )
denom *= 2;
printf("timesig %d/%d %6.2f\n",nn,denom,beatnumber);
}
void mftxt_smpte(hr,mn,se,fr,ff)
int hr, mn, se, fr, ff;
@@ -1841,31 +1422,6 @@ void initfunc_for_mftext()
Mf_arbitrary = no_op2;
}
void initfunc_for_stats()
{
Mf_error = stats_error; /* [SS] 2017-11-19 */
Mf_header = stats_header;
Mf_trackstart = stats_trackstart;
Mf_trackend = stats_trackend;
Mf_noteon = stats_noteon;
Mf_noteoff = stats_noteoff;
Mf_pressure = no_op3;
Mf_parameter = stats_parameter;
Mf_pitchbend = stats_pitchbend;
Mf_program = stats_program;
Mf_chanpressure = stats_pressure;
Mf_sysex = no_op2;
Mf_metamisc = no_op3;
Mf_seqnum = no_op1;
Mf_eot = stats_eot;
Mf_timesig = stats_timesig;
Mf_smpte = no_op5;
Mf_tempo = stats_tempo;
Mf_keysig = stats_keysig;
Mf_seqspecific = no_op3;
Mf_text = stats_metatext;
Mf_arbitrary = no_op2;
}
@@ -3667,7 +3223,8 @@ int argc;
arg = getarg("-stats",argc,argv);
if (arg != -1)
{
stats = 1;
printf("\nuse the new application midistats\n");
exit(1);
}
arg = getarg("-d",argc,argv);
@@ -3880,7 +3437,6 @@ int argc;
printf(" -mftext mftext output in beats\n");
printf(" -mftextpulses mftext output in midi pulses\n");
printf(" -mftext mftext output in seconds\n");
printf(" -stats summary and statistics output\n");
printf(" -ver version number\n");
printf(" -d <number> debug parameter\n");
printf(" None or only one of the options -aul -gu, -b, -Q -u should\n");
@@ -4129,17 +3685,6 @@ mfread();
}
void midistats(argc,argv)
char *argv[];
int argc;
{
initfunc_for_stats();
Mf_getc = filegetc;
mfread();
stats_finish();
}
int main(argc,argv)
char *argv[];
@@ -4151,7 +3696,6 @@ int argc;
arg = process_command_line_arguments(argc,argv);
if(midiprint ==1) { midigram(argc,argv);
} else if(midiprint ==2) { mftext(argc,argv);
} else if(stats == 1) { midistats(argc,argv);
} else midi2abc(argc,argv);
return 0;
}

970
midistats.c Normal file
View File

@@ -0,0 +1,970 @@
/* midistats - program to extract statistics from MIDI files
* Derived from midi2abc.c
* Copyright (C) 1998 James Allwright
* e-mail: J.R.Allwright@westminster.ac.uk
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VERSION "0.58 December 08 2022 midistats"
#include <limits.h>
/* Microsoft Visual C++ Version 6.0 or higher */
#ifdef _MSC_VER
#define snprintf _snprintf
#define ANSILIBS
#endif
#include <stdio.h>
#include <math.h>
#ifdef PCCFIX
#define stdout 1
#endif
/* define USE_INDEX if your C libraries have index() instead of strchr() */
#ifdef USE_INDEX
#define strchr index
#endif
#ifdef ANSILIBS
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#else
extern char* malloc();
extern char* strchr();
#endif
#include "midifile.h"
void initfuncs();
void stats_finish();
float histogram_entropy (int *histogram, int size);
void stats_noteoff(int chan,int pitch,int vol);
void stats_eot ();
/* Global variables and structures */
extern long Mf_toberead;
static FILE *F;
static FILE *outhandle; /* for producing the abc file */
int tracknum=0; /* track number */
int division; /* pulses per quarter note defined in MIDI header */
int quietLimit; /* minimum number of pulses with no activity */
long tempo = 500000; /* the default tempo is 120 quarter notes/minute */
long laston = 0; /* length of MIDI track in pulses or ticks */
int key[12];
int sharps;
int trackno;
int maintrack;
int format; /* MIDI file type */
int debug;
int chordthreshold; /* number of maximum number of pulses separating note */
int beatsPerBar = 4; /* 4/4 time */
int divisionsPerBar;
int unitDivision;
int tempocount=0; /* number of tempo indications in MIDI file */
int stats = 0; /* flag - gather and print statistics */
/* can cope with up to 64 track MIDI files */
int trackcount = 0;
int notechan[2048],notechanvol[2048]; /*for linking on and off midi
channel commands */
int last_tick[17]; /* for getting last pulse number in MIDI file */
int last_on_tick[17]; /* for detecting chords [SS] 2019-08-02 */
/* The following variables are used by the -stats option
* which is used by a separate application called midiexplorer.tcl.
* The channel numbers go from 1 to 16 instead of 0 to 15
*/
struct trkstat {
int notecount[17];
int chordcount[17];
int notemeanpitch[17];
int notelength[17];
int pitchbend[17];
int pressure[17];
int cntlparam[17];
int program[17];
int tempo[17];
int npulses[17];
int lastNoteOff[17];
int quietTime[17];
int rhythmpatterns[17];
} trkdata;
/* The trkstat references the individual channels in the midi file.
* notecount is the number of notes or bass notes in the chord.
* chordcount is the number of notes not counting the bass notes.
* notemeanpitch is the average pitch for the channel.
* notelength is the average note length.
* pitchbend is the number of pitch bends for the channel.
* pressure is the number of control pressure commands.
* cntlparam is the number of control parameter commands.
* program is number of times there is a program command for the channel.
* tempo is the number of times there is a tempo command.
* npulses is the number of pulses.
*/
int progcolor[17]; /* used by stats_program */
int drumhistogram[82]; /* counts drum noteons */
int pitchhistogram[12]; /* pitch distribution for non drum notes */
int channel2prog[17]; /* maps channel to program */
int channel2nnotes[17]; /*maps channel to note count */
int chnactivity[17]; /* [SS] 2018-02-02 */
int progactivity[128]; /* [SS] 2018-02-02 */
int pitchclass_activity[12]; /* [SS] 2018-02-02 */
/* [SS] 2017-11-01 */
static int progmapper[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 2,
3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 4, 4, 4, 4, 4, 2,
5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 2, 7, 10,
7, 7, 7, 7, 8, 8, 8, 8,
9, 9, 9, 9, 9, 9, 9, 9,
11, 11, 11, 11, 11, 11, 11, 11,
12, 12, 12, 12, 12, 12, 12, 12,
13, 13, 13, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15,
2, 2, 2, 2, 2, 12, 6, 12,
1, 1, 10, 10, 10, 10, 10, 1,
16, 16, 16, 16, 16, 16, 16, 16
};
struct barPattern {
int activeBarNumber;
int rhythmPattern;
} barChn[17];
#define HashSize 257
struct hashStruct {
int pattern[HashSize];
int count[HashSize];
} hasher[17] = {0};
int ncollisions = 0;
int nrpatterns = 0;
void handle_collision () {
ncollisions++;
}
void put_pattern (int chan, int pattern) {
int hashindex;
hashindex = pattern % HashSize;
if (hasher[chan].pattern[hashindex] == 0) {
hasher[chan].pattern[hashindex] = pattern;
nrpatterns++;
/*printf ("hasher[%d].pattern[%d] = %d\n",chan,hashindex,pattern);*/
} else if (hasher[chan].pattern[hashindex] != pattern) {
/* printf("collision\n"); */
handle_collision ();
} else {
hasher[chan].count[hashindex]++;
}
}
int count_patterns_for (int chan) {
int i;
int sum;
sum = 0;
for (i = 0; i<HashSize; i++) {
if (hasher[chan].pattern[i] > 0) sum++;
/* hasher[chan].pattern[i] = 0; reset hasher */
}
trkdata.rhythmpatterns[chan] = sum;
return sum;
}
void output_hasher_results () {
int i;
/* printf("rhythmPatterns ");*/
for (i = 0; i<17; i++) {
trkdata.rhythmpatterns[i] = count_patterns_for(i);
/* printf("%d ",count_patterns_for (i)); */
}
printf("\n");
}
int filegetc()
{
return(getc(F));
}
void fatal_error(s)
char* s;
/* fatal error encounterd - abort program */
{
fprintf(stderr, "%s\n", s);
exit(1);
}
void event_error(s)
char *s;
/* problem encountered but OK to continue */
{
char msg[256];
sprintf(msg, "Error: Time=%ld Track=%d %s\n", Mf_currtime, trackno, s);
printf("%s",msg);
}
int* checkmalloc(bytes)
/* malloc with error checking */
int bytes;
{
int *p;
p = (int*) malloc(bytes);
if (p == NULL) {
fatal_error("Out of memory error - cannot malloc!");
};
return (p);
}
FILE *
efopen(name,mode)
char *name;
char *mode;
{
FILE *f;
if ( (f=fopen(name,mode)) == NULL ) {
char msg[256];
sprintf(msg,"Error - Cannot open file %s",name);
fatal_error(msg);
}
return(f);
}
void error(s)
char *s;
{
fprintf(stderr,"Error: %s\n",s);
}
/* [SS] 2017-11-19 */
void stats_error(s)
char *s;
{
fprintf(stderr,"Error: %s\n",s);
fprintf(stderr,"activetrack %d\n",tracknum);
stats_finish();
}
/* Dummy functions for handling MIDI messages.
* */
void no_op0() {}
void no_op1(int dummy1) {}
void no_op2(int dummy1, int dummy2) {}
void no_op3(int dummy1, int dummy2, int dummy3) { }
void no_op4(int dummy1, int dummy2, int dummy3, int dummy4) { }
void no_op5(int dummy1, int dummy2, int dummy3, int dummy4, int dummy5) { }
/* In order to associate a channel note off message with its
* corresponding note on message, we maintain the information
* the notechan array. When a midi pitch (0-127) is switched
* on for a particular channel, we record the time that it
* was turned on in the notechan array. As there are 16 channels
* and 128 pitches, we initialize an array 128*16 = 2048 elements
* long.
**/
void init_notechan()
{
/* signal that there are no active notes */
int i;
for (i = 0; i < 2048; i++) notechan[i] = -1;
}
char * pitch2key(int note)
{
static char name[16]; /* [SDG] 2020-06-03 */
char* s = name;
switch(note % 12)
{
case 0: *s++ = 'c'; break;
case 1: *s++ = 'c'; *s++ = '#'; break;
case 2: *s++ = 'd'; break;
case 3: *s++ = 'd'; *s++ = '#'; break;
case 4: *s++ = 'e'; break;
case 5: *s++ = 'f'; break;
case 6: *s++ = 'f'; *s++ = '#'; break;
case 7: *s++ = 'g'; break;
case 8: *s++ = 'g'; *s++ = '#'; break;
case 9: *s++ = 'a'; break;
case 10: *s++ = 'a'; *s++ = '#'; break;
case 11: *s++ = 'b'; break;
}
sprintf(s, "%d", (note / 12)-1); /* octave (assuming Piano C4 is 60)*/
return name;
}
void pitch2drum(midipitch)
int midipitch;
{
static char *drumpatches[] = {
"Acoustic Bass Drum", "Bass Drum 1", "Side Stick", "Acoustic Snare",
"Hand Clap", "Electric Snare", "Low Floor Tom", "Closed Hi Hat",
"High Floor Tom", "Pedal Hi-Hat", "Low Tom", "Open Hi-Hat",
"Low-Mid Tom", "Hi Mid Tom", "Crash Cymbal 1", "High Tom",
"Ride Cymbal 1", "Chinese Cymbal", "Ride Bell", "Tambourine",
"Splash Cymbal", "Cowbell", "Crash Cymbal 2", "Vibraslap",
"Ride Cymbal 2", "Hi Bongo", "Low Bongo", "Mute Hi Conga",
"Open Hi Conga", "Low Conga", "High Timbale", "Low Timbale",
"High Agogo", "Low Agogo", "Cabasa", "Maracas",
"Short Whistle", "Long Whistle", "Short Guiro", "Long Guiro",
"Claves", "Hi Wood Block", "Low Wood Block", "Mute Cuica",
"Open Cuica", "Mute Triangle", "Open Triangle" };
if (midipitch >= 35 && midipitch <= 81) {
printf(" (%s)",drumpatches[midipitch-35]);
}
}
void stats_header (int format, int ntrks, int ldivision)
{
int i;
division = ldivision;
quietLimit = ldivision*8;
divisionsPerBar = division*beatsPerBar;
unitDivision = divisionsPerBar/24;
printf("ntrks %d\n",ntrks);
printf("ppqn %d\n",ldivision);
chordthreshold = ldivision/16; /* [SS] 2018-01-21 */
trkdata.tempo[0] = 0;
trkdata.pressure[0] = 0;
trkdata.program[0] = 0;
for (i=0;i<17;i++) {
trkdata.npulses[i] = 0;
trkdata.pitchbend[i] = 0;
trkdata.cntlparam[i] = 0; /* [SS] 2022-03-04 */
trkdata.pressure[i] = 0; /* [SS] 2022-03-04 */
trkdata.quietTime[i] = 0; /* [SS] 2022-08-22 */
progcolor[i] = 0;
channel2prog[i] = -1;
channel2nnotes[i] = 0;
chnactivity[i] = 0; /* [SS] 2018-02-02 */
}
for (i=0;i<82;i++) drumhistogram[i] = 0;
for (i=0;i<12;i++) pitchhistogram[i] = 0; /* [SS] 2017-11-01 */
for (i=0;i<12;i++) pitchclass_activity[i] = 0; /* [SS] 2018-02-02 */
for (i=0;i<128;i++) progactivity[i] = 0; /* [SS] 2018-02-02 */
}
void determine_progcolor ()
{
int i;
for (i=0;i<17;i++) progcolor[i] =0;
for (i=0;i<128;i++) {
progcolor[progmapper[i]] += progactivity[i];
}
}
/* [SS] 2018-04-24 */
void output_progs_data () {
int i;
/* check that there is valid progactivity */
printf("progs ");
for (i=0;i<128;i++)
if(progactivity[i] > 0) printf(" %d",i);
printf("\nprogsact ");
for (i=0;i<128;i++)
if(progactivity[i] > 0) printf(" %d",progactivity[i]);
}
void stats_finish()
{
int i; /* [SDG] 2020-06-03 */
int npulses;
int nprogs;
double delta;
npulses = trkdata.npulses[0];
printf("npulses %d\n",trkdata.npulses[0]);
printf("tempocmds %d\n",trkdata.tempo[0]);
printf("pitchbends %d\n",trkdata.pitchbend[0]);
for (i=1;i<17;i++) {
if (trkdata.pitchbend[i] > 0) {
printf("pitchbendin %d %d\n",i,trkdata.pitchbend[i]); }
}
if (trkdata.pressure[0] > 0)
printf("pressure %d\n",trkdata.pressure[0]);
printf("programcmd %d\n",trkdata.program[0]);
nprogs = 0; /* [SS] 2018-04-24 */
for (i=1;i<128;i++)
if(progactivity[i] >0) nprogs++;
if (nprogs > 0) output_progs_data();
else {
for (i=0;i<17;i++)
if(chnactivity[i] > 0)
progactivity[channel2prog[i]] = chnactivity[i];
output_progs_data();
}
determine_progcolor();
printf("\nprogcolor ");
if (npulses > 0)
for (i=0;i<17;i++) printf("%5.2f ",progcolor[i]/(double) npulses);
else
for (i=0;i<17;i++) printf("%5.2f ",(double) progcolor[i]);
printf("\n");
printf("drums ");
for (i=35;i<82;i++) {
if (drumhistogram[i] > 0) printf("%d ",i);
}
printf("\ndrumhits ");
for (i=35;i<82;i++) {
if (drumhistogram[i] > 0) printf("%d ",drumhistogram[i]);
}
printf("\npitches "); /* [SS] 2017-11-01 */
for (i=0;i<12;i++) printf("%d ",pitchhistogram[i]);
printf("\npitchact "); /* [SS] 2018-02-02 */
if (npulses > 0)
for (i=0;i<12;i++) printf("%5.2f ",pitchclass_activity[i]/(double) npulses);
else
for (i=0;i<12;i++) printf("%5.2f ",(double) pitchclass_activity[i]);
printf("\nchnact "); /* [SS] 2018-02-08 */
if (npulses > 0)
for (i=1;i<17;i++) printf("%5.2f ",chnactivity[i]/(double) trkdata.npulses[0]);
else
for (i=0;i<17;i++) printf("%5.2f ",(double) chnactivity[i]);
printf("\nquietTime ");
for (i=1;i<17;i++) {
delta = trkdata.npulses[0] - trkdata.quietTime[i];
if (trkdata.quietTime[i] < quietLimit) delta = 0;
delta = delta / (double) trkdata.npulses[0];
/* printf (" %5.3f ", delta); */
printf (" %d ", trkdata.quietTime[i]);
}
printf("\npitchentropy %f\n",histogram_entropy(pitchclass_activity,12));
printf("totalrhythmpatterns =%d\n",nrpatterns);
printf("collisions = %d\n",ncollisions);
printf("\n");
}
float histogram_entropy (int *histogram, int size)
{
int i;
int total;
float entropy;
float e,p;
total = 0;
entropy = 0.0;
for (i=0;i<size;i++) {
total += histogram[i];
}
for (i=0;i<size;i++) {
if (histogram[i] < 1) continue;
p = (float) histogram[i]/total;
e = p*log(p);
entropy = entropy + e;
}
return -entropy/log(2.0);
}
void output_count_trkdata(data_array,name)
int data_array[];
char *name;
{
int i,sum;
sum = 0;
for (i=1;i<17;i++) sum += data_array[i];
if (sum != 0) {
for (i=0;i<17;i++)
if(data_array[i]>0) {
printf("%s ",name);
printf("%d %d ",i,data_array[i]);
printf("\n");
}
}
}
void output_track_summary () {
int i;
/* find first channel containing data */
output_hasher_results();
for (i=1;i<17;i++) {
if(trkdata.notecount[i] == 0 && trkdata.chordcount[i] == 0) continue;
printf("trkinfo ");
printf("%d %d ",i,trkdata.program[i]); /* channel number and program*/
printf("%d %d ",trkdata.notecount[i],trkdata.chordcount[i]);
printf("%d %d ",trkdata.notemeanpitch[i], trkdata.notelength[i]);
printf("%d %d ",trkdata.cntlparam[i],trkdata.pressure[i]); /* [SS] 2022-03-04 */
printf("%d %d",trkdata.quietTime[i],trkdata.rhythmpatterns[i]);
trkdata.quietTime[i] = 0;
printf("\n");
channel2nnotes[i] += trkdata.notecount[i] + trkdata.chordcount[i];
}
}
void stats_trackstart()
{
int i;
tracknum++;
for (i=0;i<17;i++) {
trkdata.notecount[i] = 0;
trkdata.notemeanpitch[i] = 0;
trkdata.notelength[i] = 0;
trkdata.chordcount[i] = 0;
trkdata.cntlparam[i] = 0;
last_tick[i] = -1;
last_on_tick[i] = -1;
}
printf("trk %d \n",tracknum);
}
void stats_trackend()
{
trkdata.npulses[tracknum] = Mf_currtime;
if (trkdata.npulses[0] < Mf_currtime) trkdata.npulses[0] = Mf_currtime;
output_track_summary();
}
void stats_noteon(chan,pitch,vol)
int chan, pitch, vol;
{
int delta;
int barnum;
int unit;
if (vol == 0) {
/* treat as noteoff */
stats_noteoff(chan,pitch,vol);
trkdata.lastNoteOff[chan+1] = Mf_currtime; /* [SS] 2022.08.22 */
return;
}
trkdata.notemeanpitch[chan+1] += pitch;
if (trkdata.lastNoteOff[chan+1] >= 0) {
delta = Mf_currtime - trkdata.lastNoteOff[chan+1];
trkdata.lastNoteOff[chan+1] = -1; /* in case of chord */
if (delta > quietLimit) {
trkdata.quietTime[chan+1] += delta;
}
}
if (abs(Mf_currtime - last_on_tick[chan+1]) < chordthreshold) trkdata.chordcount[chan+1]++;
else trkdata.notecount[chan+1]++; /* [SS] 2019-08-02 */
last_tick[chan+1] = Mf_currtime;
last_on_tick[chan+1] = Mf_currtime; /* [SS] 2019-08-02 */
/* last_on_tick not updated by stats_noteoff */
if (chan != 9) {
barnum = Mf_currtime/divisionsPerBar;
if (barnum != barChn[chan].activeBarNumber) {
/*printf("%d %d %d\n",chan,barChn[chan].activeBarNumber,
barChn[chan].rhythmPattern); */
put_pattern (chan+1, barChn[chan].rhythmPattern);
barChn[chan].rhythmPattern = 0;
barChn[chan].activeBarNumber = barnum;
}
unit = (Mf_currtime % divisionsPerBar)/unitDivision;
//printf("unit = %d pattern = %d \n",unit,barChn[chan].rhythmPattern);
barChn[chan].rhythmPattern = barChn[chan].rhythmPattern |= (1UL << unit);
}
if (chan == 9) {
if (pitch < 0 || pitch > 81)
printf("****illegal drum value %d\n",pitch);
else drumhistogram[pitch]++;
}
else pitchhistogram[pitch % 12]++; /* [SS] 2017-11-01 */
}
void stats_eot () {
trkdata.lastNoteOff[0] = Mf_currtime; /* [SS] 2022.08.24 */
}
void stats_noteoff(int chan,int pitch,int vol)
{
int length;
int program;
/* ignore if there was no noteon */
if (last_tick[chan+1] == -1) return;
length = Mf_currtime - last_tick[chan+1];
trkdata.notelength[chan+1] += length;
trkdata.lastNoteOff[chan+1] = Mf_currtime; /* [SS] 2022.08.22 */
chnactivity[chan+1] += length;
if (chan == 9) return; /* drum channel */
pitchclass_activity[pitch % 12] += length;
program = trkdata.program[chan+1];
progactivity[program] += length;
/* [SS] 2018-04-18 */
if(Mf_currtime > last_tick[chan+1]) last_tick[chan+1] = Mf_currtime;
}
void stats_pitchbend(chan,lsb,msb)
int chan, lsb, msb;
{
trkdata.pitchbend[0]++;
trkdata.pitchbend[chan+1]++;
}
void stats_pressure(chan,press)
int chan, press;
{
trkdata.pressure[0]++;
trkdata.pressure[chan+1]++; /* [SS] 2022.04.28 */
}
void stats_program(chan,program)
int chan, program;
{
int beatnumber;
if (program <0 || program > 127) return; /* [SS] 2018-03-06 */
if (trkdata.program[chan+1] != 0) {
beatnumber = Mf_currtime/division;
printf("cprogram %d %d %d\n",chan+1,program,beatnumber);
/* count number of times the program was modified for a channel */
trkdata.program[0] = trkdata.program[0]+1;
} else {
printf("program %d %d\n",chan+1,program);
trkdata.program[chan+1] = program;
}
if (channel2prog[chan+1]== -1) channel2prog[chan+1] = program;
}
void stats_parameter(chan,control,value)
int chan, control, value;
{
/*if (control == 7) {
printf("cntrlvolume %d %d \n",chan+1,value);
}
*/
trkdata.cntlparam[chan+1]++;
}
void stats_metatext(type,leng,mess)
int type, leng;
char *mess;
{
int i;
if (type != 3) return;
printf("metatext %d ",type);
for (i=0;i<leng;i++) printf("%c",mess[i]);
printf("\n");
}
/* [SS] 2018-01-02 */
void stats_keysig(sf,mi)
int sf, mi;
{
float beatnumber;
static char *major[] = {"Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F",
"C", "G", "D", "A", "E", "B", "F#", "C#"};
static char *minor[] = {"Abmin", "Ebmin", "Bbmin", "Fmin", "Cmin",
"Gmin", "Dmin", "Amin", "Emin", "Bmin", "F#min", "C#min", "G#min"};
int index;
beatnumber = Mf_currtime/division;
index = sf + 7;
if (index < 0 || index >12) return;
if (mi)
printf("keysig %s %d %d %6.2f\n",minor[index],sf,mi,beatnumber);
else
printf("keysig %s %d %d %6.2f\n",major[index],sf,mi,beatnumber);
}
/* [SS] 2018-01-02 */
void stats_tempo(ltempo)
long ltempo;
{
float beatnumber;
tempo = ltempo;
beatnumber = Mf_currtime/division;
if (trkdata.tempo[0] == 0) printf("tempo %6.2f bpm\n",60000000.0/tempo);
else if (trkdata.tempo[0] < 10) printf("ctempo %6.2f %6.2f\n",60000000.0/tempo,beatnumber);
trkdata.tempo[0]++;
}
void stats_timesig(nn,dd,cc,bb)
int nn, dd, cc, bb;
{
float beatnumber;
int denom = 1;
beatnumber = Mf_currtime/division;
while ( dd-- > 0 )
denom *= 2;
printf("timesig %d/%d %6.2f\n",nn,denom,beatnumber);
}
void initfunc_for_stats()
{
Mf_error = stats_error; /* [SS] 2017-11-19 */
Mf_header = stats_header;
Mf_trackstart = stats_trackstart;
Mf_trackend = stats_trackend;
Mf_noteon = stats_noteon;
Mf_noteoff = stats_noteoff;
Mf_pressure = no_op3;
Mf_parameter = stats_parameter;
Mf_pitchbend = stats_pitchbend;
Mf_program = stats_program;
Mf_chanpressure = stats_pressure;
Mf_sysex = no_op2;
Mf_metamisc = no_op3;
Mf_seqnum = no_op1;
Mf_eot = stats_eot;
Mf_timesig = stats_timesig;
Mf_smpte = no_op5;
Mf_tempo = stats_tempo;
Mf_keysig = stats_keysig;
Mf_seqspecific = no_op3;
Mf_text = stats_metatext;
Mf_arbitrary = no_op2;
}
int readnum(num)
/* read a number from a string */
/* used for processing command line */
char *num;
{
int t;
char *p;
int neg;
t = 0;
neg = 1;
p = num;
if (*p == '-') {
p = p + 1;
neg = -1;
};
/* [JA] 2021-05-25 */
while (((int)*p >= '0') && ((int)*p <= '9') && (t < (INT_MAX-9)/10)) {
t = t * 10 + (int) *p - '0';
p = p + 1;
};
return neg*t;
}
int readnump(p)
/* read a number from a string (subtly different) */
/* used for processing command line */
char **p;
{
int t;
t = 0;
/* [JA] 2021-05-25 */
while (((int)**p >= '0') && ((int)**p <= '9') && (t < (INT_MAX-9)/10)) {
t = t * 10 + (int) **p - '0';
*p = *p + 1;
};
/* advance over any spurious extra digits */
while (isdigit(**p)) {
*p = *p + 1;
}
return t;
}
int getarg(option, argc, argv)
/* extract arguments from command line */
char *option;
char *argv[];
int argc;
{
int j, place;
place = -1;
for (j=0; j<argc; j++) {
if (strcmp(option, argv[j]) == 0) {
place = j + 1;
};
};
return (place);
}
int huntfilename(argc, argv)
/* look for filename argument if -f option is missing */
/* assumes filename does not begin with '-' */
char *argv[];
int argc;
{
int j, place;
place = -1;
j = 1;
while ((place == -1) && (j < argc)) {
if (strncmp("-", argv[j], 1) != 0) {
place = j;
}
else {
if (strchr("ambQkcou", *(argv[j]+1)) == NULL) {
j = j + 1;
}
else {
j = j + 2;
};
};
};
return(place);
}
int process_command_line_arguments(argc,argv)
char *argv[];
int argc;
{
int val;
int arg;
arg = getarg("-ver",argc,argv);
if (arg != -1) {printf("%s\n",VERSION); exit(0);}
stats = 1;
arg = getarg("-d",argc,argv);
if ((arg != -1) && (arg <argc)) {
debug = readnum(argv[arg]);
}
arg = getarg("-o",argc,argv);
if ((arg != -1) && (arg < argc)) {
outhandle = efopen(argv[arg],"w"); /* open output abc file */
}
else {
outhandle = stdout;
};
arg = getarg("-f", argc, argv);
if (arg == -1) {
arg = huntfilename(argc, argv);
};
if ((arg != -1) && (arg < argc)) {
F = efopen(argv[arg],"rb");
/* fprintf(outhandle,"%% input file %s\n", argv[arg]); */
}
else {
printf("midistats version %s\n usage :\n",VERSION);
printf("midistats filename <options>\n");
printf(" -ver version number\n");
printf(" -d <number> debug parameter\n");
printf(" The input filename is assumed to be any string not\n");
printf(" beginning with a - (hyphen). It may be placed anywhere.\n");
exit(0);
};
return arg;
}
void midistats(argc,argv)
char *argv[];
int argc;
{
initfunc_for_stats();
Mf_getc = filegetc;
mfread();
stats_finish();
}
int main(argc,argv)
char *argv[];
int argc;
{
FILE *efopen();
int arg;
arg = process_command_line_arguments(argc,argv);
if(stats == 1) midistats(argc,argv);
return 0;
}

View File

@@ -82,7 +82,7 @@ extern char *malloc ();
extern char *strchr ();
#endif
int note2midi (char** s);
int note2midi (char** s, char* word); /*[SS] 2022-12-27 added word */
int lineno;
int parsing_started = 0;
int parsing, slur;
@@ -942,7 +942,7 @@ int interpret_voice_label (char *s, int num, int *is_new)
}
/* The following four functions parseclefs, parsetranspose,
* parsesound, parseoctave are used to parse the K: field which not
* parseSoundScore, parseoctave are used to parse the K: field which not
* only specifies the key signature but also other descriptors
* used for producing a midi file or postscript file.
*
@@ -1021,49 +1021,105 @@ parsetranspose (s, word, gottranspose, transpose)
return 1;
};
/* [SS] 2021-10-11 */
int
parsesound (s, word, gottranspose, transpose)
/* parses string sound =
shift =
instrument = note1note2 or note1/note2
for parsekey() or parsevoice()
and returns the transpose value
*/
char **s;
char *word;
int *gottranspose;
int *transpose;
{
int p1,p2;
if (casecmp(word,"sound") != 0
&& casecmp(word,"shift") != 0
&& casecmp(word,"instrument") != 0
)
return 0;
skipspace (s);
if (**s != '=')
int parseSoundScore (char **s,
char *word,
int *gottranspose,
int *transpose
)
/* parses sound, score, instrument, and shift
* according to Hudson Lacerda's pseudo code file
* doc/hudsonshift.txt.
*/
{
int p1,p2;
int transp_sound;
int transp_score;
transp_sound = 0;
transp_score = 0;
if (casecmp(word,"sound") != 0
&& casecmp(word,"shift") != 0
&& casecmp(word,"instrument") != 0
&& casecmp(word,"score") != 0) return 0;
if ( fileprogram == ABC2ABC) {
return 0;
}
skipspace (s);
if (**s != '=')
{
event_error ("sound must be followed by '='");
event_error ("expecting '=' after sound, score, instrument or shift");
return 0;
} else {
*s = *s + 1;
skipspace (s);
p1 = note2midi (s);
/* printf("midi note = %d\n",p1); */
p2 = note2midi (s);
if (p2 == p1) {
*gottranspose = 0;
*transpose = 0;
} else {
/* printf("midi note = %d\n",p2); */
*transpose = p2 - p1; /* [SS] 2022.02.18 2022.04.27 */
/* printf("transpose = %d\n",*transpose); */
*gottranspose = 1;
}
p1 = note2midi (s,word);
p2 = note2midi (s,word);
if (p1 == 0) {
event_error ("<note1> missing. cannot do anything");
}
/* p2 = 0 implies that <note2> is not given */
if (casecmp(word,"sound") == 0) {
if (p2 == 0) event_error("sound = requires <note2>");
transp_sound = p2-p1;
/*
sound=<note1><note2> transposes the playback according to the
specified interval (the typeset score is not affected)
*/
}
if (casecmp(word,"score") == 0) {
if (p2 == 0) p2 = 72;
transp_score = p2 - p1;
/*
score=<note1><note2> transposes the typeset score according to the
specified interval (the playback is not affected); if the second note
is omitted it is assumed to be a c (see writing abc code for
transposing instruments)
*/
}
if (casecmp(word,"instrument") == 0) {
if (p2 == 0) p2 = p1;
transp_score = p2 - p1;
transp_sound = p2 - 72;
/*
instrument=<note1>/<note2> is defined as
score=<note1><note2> sound=c<note2>
*/
}
if (casecmp(word,"shift") == 0) {
if (p2 == 0) event_error("shift = requires <note2>");
transp_score = p2 - p1;
transp_sound = p2 - p1;
/*
shift=<note1><note2> transposes the typeset score and the playback
according to the specified interval
*/
}
*gottranspose = 1;
if (fileprogram == ABC2MIDI) {
/* [SS] 2023.01.06 */
if (casecmp(word,"score") != 0) *transpose = transp_sound;
}
if (fileprogram == YAPS) {
/* [SS] 2023.01.06 */
if (casecmp(word,"sound") != 0) *transpose = transp_score;
}
return(1);
}
return 1;
}
}
int
parseoctave (s, word, gotoctave, octave)
@@ -1410,7 +1466,7 @@ parsekey (str)
parsed = parseoctave (&s, word, &gotoctave, &octave);
if (!parsed)
parsed = parsesound (&s, word, &gottranspose, &transpose);
parsed = parseSoundScore (&s, word, &gottranspose, &transpose);
if ((parsed == 0) && (casecmp (word, "Hp") == 0))
{
@@ -1657,7 +1713,7 @@ parsevoice (s)
if (!parsed)
parsed = parseoctave (&s, word, &vparams.gotoctave, &vparams.octave);
if (!parsed)
parsed = parsesound (&s, word, &vparams.gottranspose, &vparams.transpose);
parsed = parseSoundScore (&s, word, &vparams.gottranspose, &vparams.transpose);
/* Code changed JA 20 May 2022 */
if ((!parsed) && (strcasecmp (word, "name") == 0)) {
parsed =
@@ -2618,6 +2674,7 @@ print_inputline ()
static void check_bar_repeats (int bar_type, char *replist)
{
voice_context_t *cv = &voicecode[voicenum];
char error_message[140];
switch (bar_type) {
case SINGLE_BAR:
@@ -2637,7 +2694,6 @@ static void check_bar_repeats (int bar_type, char *replist)
break;
case REP_BAR:
if (!cv->expect_repeat) {
char error_message[80];
if (cv->repeat_count == 0)
{
@@ -2736,6 +2792,10 @@ int mult, octave;
noteno = (int)note - 'a';
p = (int) ((long) strchr(anoctave, note) - (long) anoctave);
if (p < 0 || p > 6) { /* [SS] 2022-12-22 */
printf("illegal note %c\n",note);
return 72;
}
p = scale[p];
if (acc == '^') p = p + mul;
if (acc == '_') p = p - mul;
@@ -2746,8 +2806,7 @@ return p;
/* [SS] 2021-10-11 */
int
note2midi (char** s)
int note2midi (char** s, char *word)
{
/* for implementing sound=, shift= and instrument= key signature options */
@@ -2757,8 +2816,9 @@ char msg[80];
int octave;
int mult;
int pitch;
/*printf("note2midi: %c\n",**s); */
/*printf("note2midi: %c\n",**s);*/
if (**s == '\0') return 72;
note = **s;
mult = 1;
accidental = ' ';
switch (**s)
@@ -2813,6 +2873,10 @@ switch (**s)
/* skip / which occurs in instrument = command */
*s = *s + 1;
/* printf("note = %c accidental = %c mult = %d octave= %d \n",note,accidental,mult,octave); */
if (casecmp(word,"instrument") != 0) { /* [SS] 2022-12-27 */
event_warning("score and shift directives do not expect an embedded '/'");
}
pitch = pitch2midi(note, accidental, mult, octave);
return pitch;
}
@@ -2854,7 +2918,7 @@ switch (**s)
}
if (note == ' ')
{
event_error ("Malformed note : expecting a-g or A-G");
return 0;
}
pitch = pitch2midi(note, accidental, mult, octave);
return pitch;

View File

@@ -186,7 +186,7 @@ int main()
*/
#define VERSION "4.76 August 01 2022 abc2midi"
#define VERSION "4.82 January 06 2023 abc2midi"
/* enables reading V: indication in header */
#define XTEN1 1
@@ -3450,7 +3450,7 @@ static void brokenadjust()
};
};
if (failed) {
event_error("Cannot apply broken rhythm");
event_error("Cannot apply broken rhythm. Notes not equal durations");
} else {
/*
printf("Adjusting %d to %d and %d to %d\n",

View File

@@ -21,7 +21,7 @@
/* back-end for outputting (possibly modified) abc */
#define VERSION "2.18 June 14 2022 abc2abc"
#define VERSION "2.19 Jan 08 2022 abc2abc"
/* for Microsoft Visual C++ 6.0 or higher */
#ifdef _MSC_VER

View File

@@ -22,7 +22,7 @@
/* yapstree.c - back-end for abc parser. */
/* generates a data structure suitable for typeset music */
#define VERSION "1.90 June 14 2022 yaps"
#define VERSION "1.92 January 06 2023 yaps"
#include <stdio.h>
#ifdef USE_INDEX
#define strchr index