mirror of
https://github.com/sshlien/abcmidi.git
synced 2026-04-15 14:23:41 +00:00
abcMIDI-2020.07.06.zip
This commit is contained in:
174
Makefile
Normal file
174
Makefile
Normal file
@@ -0,0 +1,174 @@
|
||||
# Generic unix/gcc Makefile for abcMIDI package
|
||||
#
|
||||
#
|
||||
# compilation #ifdefs - you need to compile with these defined to get
|
||||
# the code to compile with PCC.
|
||||
#
|
||||
# NOFTELL in midifile.c and genmidi.c selects a version of the file-writing
|
||||
# code which doesn't use file seeking.
|
||||
#
|
||||
# PCCFIX in mftext.c midifile.c midi2abc.c
|
||||
# comments out various things that aren't available in PCC
|
||||
#
|
||||
# ANSILIBS includes some ANSI header files (which gcc can live without,
|
||||
# but other compilers may want).
|
||||
#
|
||||
# USE_INDEX causes index() to be used instead of strchr(). This is needed
|
||||
# by some pre-ANSI C compilers.
|
||||
#
|
||||
# ASCTIME causes asctime() to be used instead of strftime() in pslib.c.
|
||||
# If ANSILIBS is not set, neither routine is used.
|
||||
#
|
||||
# KANDR selects functions prototypes without argument prototypes.
|
||||
# currently yaps will only compile in ANSI mode.
|
||||
#
|
||||
#
|
||||
# On running make, you may get the mysterious message :
|
||||
#
|
||||
# ', needed by `parseabc.o'. Stop `abc.h
|
||||
#
|
||||
# This means you are using GNU make and this file is in DOS text format. To
|
||||
# cure the problem, change this file from using PC-style end-of-line (carriage
|
||||
# return and line feed) to unix style end-of-line (line feed).
|
||||
|
||||
VERSION = @VERSION@
|
||||
|
||||
CC = gcc
|
||||
INSTALL = /usr/bin/install -c
|
||||
INSTALL_DATA = ${INSTALL} -m 644
|
||||
INSTALL_PROGRAM = ${INSTALL}
|
||||
|
||||
CFLAGS = -DANSILIBS -O2
|
||||
CPPFLAGS = -DHAVE_CONFIG_H -I.
|
||||
LDFLAGS = -lm
|
||||
|
||||
prefix = /usr/local
|
||||
exec_prefix = ${prefix}
|
||||
|
||||
srcdir = .
|
||||
VPATH = .
|
||||
bindir = ${exec_prefix}/bin
|
||||
libdir = ${exec_prefix}/lib
|
||||
datadir = ${prefix}/share
|
||||
docdir = ${prefix}/share/doc/abcmidi
|
||||
mandir = ${prefix}/share/man/man1
|
||||
|
||||
binaries=abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch
|
||||
|
||||
all : abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch
|
||||
|
||||
OBJECTS_ABC2MIDI=parseabc.o store.o genmidi.o midifile.o queues.o parser2.o stresspat.o
|
||||
abc2midi : $(OBJECTS_ABC2MIDI)
|
||||
$(CC) $(CFLAGS) -o abc2midi $(OBJECTS_ABC2MIDI) $(LDFLAGS) -lm
|
||||
$(OBJECTS_ABC2MIDI): abc.h parseabc.h config.h Makefile
|
||||
|
||||
OBJECTS_ABC2ABC=parseabc.o toabc.o
|
||||
abc2abc : $(OBJECTS_ABC2ABC)
|
||||
$(CC) $(CFLAGS) -o abc2abc $(OBJECTS_ABC2ABC) $(LDFLAGS)
|
||||
$(OBJECTS_ABC2ABC): abc.h parseabc.h config.h Makefile
|
||||
|
||||
OBJECTS_MIDI2ABC=midifile.o midi2abc.o
|
||||
midi2abc : $(OBJECTS_MIDI2ABC)
|
||||
$(CC) $(CFLAGS) -o midi2abc $(OBJECTS_MIDI2ABC) $(LDFLAGS)
|
||||
$(OBJECTS_MIDI2ABC): 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)
|
||||
$(OBJECTS_MFTEXT): abc.h midifile.h config.h Makefile
|
||||
|
||||
OBJECTS_YAPS=parseabc.o yapstree.o drawtune.o debug.o pslib.o position.o parser2.o
|
||||
yaps : $(OBJECTS_YAPS)
|
||||
$(CC) $(CFLAGS) -o yaps $(OBJECTS_YAPS) $(LDFLAGS)
|
||||
$(OBJECTS_YAPS): abc.h midifile.h config.h Makefile
|
||||
|
||||
OBJECTS_MIDICOPY=midicopy.o
|
||||
midicopy : $(OBJECTS_MIDICOPY)
|
||||
$(CC) $(CFLAGS) -o midicopy $(OBJECTS_MIDICOPY) $(LDFLAGS)
|
||||
$(OBJECTS_MIDICOPY): abc.h midifile.h midicopy.h config.h Makefile
|
||||
|
||||
OBJECTS_ABCMATCH=abcmatch.o matchsup.o parseabc.o
|
||||
abcmatch : $(OBJECTS_ABCMATCH)
|
||||
$(CC) $(CFLAGS) -o abcmatch $(OBJECTS_ABCMATCH) $(LDFLAGS)
|
||||
$(OBJECTS_ABCMATCH): abc.h midifile.h config.h Makefile
|
||||
|
||||
parseabc.o : parseabc.c abc.h parseabc.h
|
||||
|
||||
parser2.o : parser2.c abc.h parseabc.h parser2.h
|
||||
|
||||
toabc.o : toabc.c abc.h parseabc.h
|
||||
|
||||
# could use -DNOFTELL here
|
||||
genmidi.o : genmidi.c abc.h midifile.h genmidi.h
|
||||
|
||||
stresspat.o : stresspat.c
|
||||
|
||||
store.o : store.c abc.h parseabc.h midifile.h genmidi.h
|
||||
|
||||
queues.o : queues.c genmidi.h
|
||||
|
||||
# could use -DNOFTELL here
|
||||
midifile.o : midifile.c midifile.h
|
||||
|
||||
midi2abc.o : midi2abc.c midifile.h
|
||||
|
||||
midicopy.o : midicopy.c midicopy.h
|
||||
|
||||
abcmatch.o: abcmatch.c abc.h
|
||||
|
||||
crack.o : crack.c
|
||||
|
||||
mftext.o : mftext.c midifile.h
|
||||
|
||||
# objects needed by yaps
|
||||
#
|
||||
yapstree.o: yapstree.c abc.h parseabc.h structs.h drawtune.h
|
||||
|
||||
drawtune.o: drawtune.c structs.h sizes.h abc.h drawtune.h
|
||||
|
||||
pslib.o: pslib.c drawtune.h
|
||||
|
||||
position.o: position.c abc.h structs.h sizes.h
|
||||
|
||||
debug.o: debug.c structs.h abc.h
|
||||
|
||||
#objects for abcmatch
|
||||
#
|
||||
matchsup.o : matchsup.c abc.h parseabc.h parser2.h
|
||||
|
||||
clean :
|
||||
rm *.o ${binaries}
|
||||
|
||||
install: abc2midi midi2abc abc2abc mftext midicopy yaps abcmatch
|
||||
$(INSTALL) -d $(DESTDIR)$(bindir)
|
||||
$(INSTALL) -m 755 ${binaries} $(DESTDIR)$(bindir)
|
||||
|
||||
# install documentation
|
||||
$(INSTALL) -d $(DESTDIR)${docdir}
|
||||
$(INSTALL) -m 644 doc/*.txt $(DESTDIR)$(docdir)
|
||||
$(INSTALL) -m 644 doc/AUTHORS $(DESTDIR)$(docdir)
|
||||
$(INSTALL) -m 644 doc/CHANGES $(DESTDIR)$(docdir)
|
||||
$(INSTALL) -m 644 VERSION $(DESTDIR)$(docdir)
|
||||
|
||||
# install manpages
|
||||
$(INSTALL) -d $(DESTDIR)${mandir}
|
||||
$(INSTALL) -m 644 doc/*.1 $(DESTDIR)$(mandir)
|
||||
|
||||
|
||||
uninstall:
|
||||
echo "uninstalling...";
|
||||
#rm -f $(DESTDIR)$(bindir)/$(binaries)
|
||||
rm -f $(DESTDIR)$(bindir)/abc2midi
|
||||
rm -f $(DESTDIR)$(bindir)/abc2abc
|
||||
rm -f $(DESTDIR)$(bindir)/yaps
|
||||
rm -f $(DESTDIR)$(bindir)/midi2abc
|
||||
rm -f $(DESTDIR)$(bindir)/mftext
|
||||
rm -f $(DESTDIR)$(bindir)/abcmatch
|
||||
rm -f $(DESTDIR)$(bindir)/midicopy
|
||||
rm -f $(DESTDIR)$(docdir)/*.txt
|
||||
rm -f $(DESTDIR)$(docdir)/AUTHORS
|
||||
rm -f $(DESTDIR)$(docdir)/CHANGES
|
||||
rm -f $(DESTDIR)$(docdir)/VERSION
|
||||
rm -f $(DESTDIR)$(mandir)/*.1
|
||||
rmdir $(DESTDIR)$(docdir)
|
||||
|
||||
174
Makefile.in
Normal file
174
Makefile.in
Normal file
@@ -0,0 +1,174 @@
|
||||
# Generic unix/gcc Makefile for abcMIDI package
|
||||
#
|
||||
#
|
||||
# compilation #ifdefs - you need to compile with these defined to get
|
||||
# the code to compile with PCC.
|
||||
#
|
||||
# NOFTELL in midifile.c and genmidi.c selects a version of the file-writing
|
||||
# code which doesn't use file seeking.
|
||||
#
|
||||
# PCCFIX in mftext.c midifile.c midi2abc.c
|
||||
# comments out various things that aren't available in PCC
|
||||
#
|
||||
# ANSILIBS includes some ANSI header files (which gcc can live without,
|
||||
# but other compilers may want).
|
||||
#
|
||||
# USE_INDEX causes index() to be used instead of strchr(). This is needed
|
||||
# by some pre-ANSI C compilers.
|
||||
#
|
||||
# ASCTIME causes asctime() to be used instead of strftime() in pslib.c.
|
||||
# If ANSILIBS is not set, neither routine is used.
|
||||
#
|
||||
# KANDR selects functions prototypes without argument prototypes.
|
||||
# currently yaps will only compile in ANSI mode.
|
||||
#
|
||||
#
|
||||
# On running make, you may get the mysterious message :
|
||||
#
|
||||
# ', needed by `parseabc.o'. Stop `abc.h
|
||||
#
|
||||
# This means you are using GNU make and this file is in DOS text format. To
|
||||
# cure the problem, change this file from using PC-style end-of-line (carriage
|
||||
# return and line feed) to unix style end-of-line (line feed).
|
||||
|
||||
VERSION = @VERSION@
|
||||
|
||||
CC = @CC@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
|
||||
CFLAGS = -DANSILIBS @CFLAGS@
|
||||
CPPFLAGS = @DEFS@ @CPPFLAGS@ -I.
|
||||
LDFLAGS = @LDFLAGS@ -lm
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
datadir = @datarootdir@
|
||||
docdir = @datarootdir@/doc/abcmidi
|
||||
mandir = @datarootdir@/man/man1
|
||||
|
||||
binaries=abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch
|
||||
|
||||
all : abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch
|
||||
|
||||
OBJECTS_ABC2MIDI=parseabc.o store.o genmidi.o midifile.o queues.o parser2.o stresspat.o
|
||||
abc2midi : $(OBJECTS_ABC2MIDI)
|
||||
$(CC) $(CFLAGS) -o abc2midi $(OBJECTS_ABC2MIDI) $(LDFLAGS) -lm
|
||||
$(OBJECTS_ABC2MIDI): abc.h parseabc.h config.h Makefile
|
||||
|
||||
OBJECTS_ABC2ABC=parseabc.o toabc.o
|
||||
abc2abc : $(OBJECTS_ABC2ABC)
|
||||
$(CC) $(CFLAGS) -o abc2abc $(OBJECTS_ABC2ABC) $(LDFLAGS)
|
||||
$(OBJECTS_ABC2ABC): abc.h parseabc.h config.h Makefile
|
||||
|
||||
OBJECTS_MIDI2ABC=midifile.o midi2abc.o
|
||||
midi2abc : $(OBJECTS_MIDI2ABC)
|
||||
$(CC) $(CFLAGS) -o midi2abc $(OBJECTS_MIDI2ABC) $(LDFLAGS)
|
||||
$(OBJECTS_MIDI2ABC): 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)
|
||||
$(OBJECTS_MFTEXT): abc.h midifile.h config.h Makefile
|
||||
|
||||
OBJECTS_YAPS=parseabc.o yapstree.o drawtune.o debug.o pslib.o position.o parser2.o
|
||||
yaps : $(OBJECTS_YAPS)
|
||||
$(CC) $(CFLAGS) -o yaps $(OBJECTS_YAPS) $(LDFLAGS)
|
||||
$(OBJECTS_YAPS): abc.h midifile.h config.h Makefile
|
||||
|
||||
OBJECTS_MIDICOPY=midicopy.o
|
||||
midicopy : $(OBJECTS_MIDICOPY)
|
||||
$(CC) $(CFLAGS) -o midicopy $(OBJECTS_MIDICOPY) $(LDFLAGS)
|
||||
$(OBJECTS_MIDICOPY): abc.h midifile.h midicopy.h config.h Makefile
|
||||
|
||||
OBJECTS_ABCMATCH=abcmatch.o matchsup.o parseabc.o
|
||||
abcmatch : $(OBJECTS_ABCMATCH)
|
||||
$(CC) $(CFLAGS) -o abcmatch $(OBJECTS_ABCMATCH) $(LDFLAGS)
|
||||
$(OBJECTS_ABCMATCH): abc.h midifile.h config.h Makefile
|
||||
|
||||
parseabc.o : parseabc.c abc.h parseabc.h
|
||||
|
||||
parser2.o : parser2.c abc.h parseabc.h parser2.h
|
||||
|
||||
toabc.o : toabc.c abc.h parseabc.h
|
||||
|
||||
# could use -DNOFTELL here
|
||||
genmidi.o : genmidi.c abc.h midifile.h genmidi.h
|
||||
|
||||
stresspat.o : stresspat.c
|
||||
|
||||
store.o : store.c abc.h parseabc.h midifile.h genmidi.h
|
||||
|
||||
queues.o : queues.c genmidi.h
|
||||
|
||||
# could use -DNOFTELL here
|
||||
midifile.o : midifile.c midifile.h
|
||||
|
||||
midi2abc.o : midi2abc.c midifile.h
|
||||
|
||||
midicopy.o : midicopy.c midicopy.h
|
||||
|
||||
abcmatch.o: abcmatch.c abc.h
|
||||
|
||||
crack.o : crack.c
|
||||
|
||||
mftext.o : mftext.c midifile.h
|
||||
|
||||
# objects needed by yaps
|
||||
#
|
||||
yapstree.o: yapstree.c abc.h parseabc.h structs.h drawtune.h
|
||||
|
||||
drawtune.o: drawtune.c structs.h sizes.h abc.h drawtune.h
|
||||
|
||||
pslib.o: pslib.c drawtune.h
|
||||
|
||||
position.o: position.c abc.h structs.h sizes.h
|
||||
|
||||
debug.o: debug.c structs.h abc.h
|
||||
|
||||
#objects for abcmatch
|
||||
#
|
||||
matchsup.o : matchsup.c abc.h parseabc.h parser2.h
|
||||
|
||||
clean :
|
||||
rm *.o ${binaries}
|
||||
|
||||
install: abc2midi midi2abc abc2abc mftext midicopy yaps abcmatch
|
||||
$(INSTALL) -d $(DESTDIR)$(bindir)
|
||||
$(INSTALL) -m 755 ${binaries} $(DESTDIR)$(bindir)
|
||||
|
||||
# install documentation
|
||||
$(INSTALL) -d $(DESTDIR)${docdir}
|
||||
$(INSTALL) -m 644 doc/*.txt $(DESTDIR)$(docdir)
|
||||
$(INSTALL) -m 644 doc/AUTHORS $(DESTDIR)$(docdir)
|
||||
$(INSTALL) -m 644 doc/CHANGES $(DESTDIR)$(docdir)
|
||||
$(INSTALL) -m 644 VERSION $(DESTDIR)$(docdir)
|
||||
|
||||
# install manpages
|
||||
$(INSTALL) -d $(DESTDIR)${mandir}
|
||||
$(INSTALL) -m 644 doc/*.1 $(DESTDIR)$(mandir)
|
||||
|
||||
|
||||
uninstall:
|
||||
echo "uninstalling...";
|
||||
#rm -f $(DESTDIR)$(bindir)/$(binaries)
|
||||
rm -f $(DESTDIR)$(bindir)/abc2midi
|
||||
rm -f $(DESTDIR)$(bindir)/abc2abc
|
||||
rm -f $(DESTDIR)$(bindir)/yaps
|
||||
rm -f $(DESTDIR)$(bindir)/midi2abc
|
||||
rm -f $(DESTDIR)$(bindir)/mftext
|
||||
rm -f $(DESTDIR)$(bindir)/abcmatch
|
||||
rm -f $(DESTDIR)$(bindir)/midicopy
|
||||
rm -f $(DESTDIR)$(docdir)/*.txt
|
||||
rm -f $(DESTDIR)$(docdir)/AUTHORS
|
||||
rm -f $(DESTDIR)$(docdir)/CHANGES
|
||||
rm -f $(DESTDIR)$(docdir)/VERSION
|
||||
rm -f $(DESTDIR)$(mandir)/*.1
|
||||
rmdir $(DESTDIR)$(docdir)
|
||||
|
||||
146
abc.h
Normal file
146
abc.h
Normal file
@@ -0,0 +1,146 @@
|
||||
/* abc.h - header file shared by abc2midi, abc2abc and yaps */
|
||||
/* Copyright James Allwright 2000 */
|
||||
/* may be copied under the terms of the GNU public license */
|
||||
|
||||
typedef enum {
|
||||
ABC2MIDI,
|
||||
ABC2ABC,
|
||||
YAPS,
|
||||
ABCMATCH} programname;
|
||||
|
||||
/* define types of abc object */
|
||||
typedef enum {
|
||||
/* types of bar sign */
|
||||
SINGLE_BAR,
|
||||
DOUBLE_BAR,
|
||||
DOTTED_BAR,
|
||||
BAR_REP,
|
||||
REP_BAR,
|
||||
PLAY_ON_REP,
|
||||
REP1,
|
||||
REP2,
|
||||
/* BAR1 = SINGLE_BAR + REP1 */
|
||||
/* REP_BAR2 = REP_BAR + REP2 */
|
||||
BAR1,
|
||||
REP_BAR2,
|
||||
DOUBLE_REP,
|
||||
THICK_THIN,
|
||||
THIN_THICK,
|
||||
/* other things */
|
||||
PART,
|
||||
TEMPO,
|
||||
TIME,
|
||||
KEY,
|
||||
REST,
|
||||
TUPLE,
|
||||
/* CHORD replaced by CHORDON and CHORDOFF */
|
||||
NOTE,
|
||||
NONOTE,
|
||||
OLDTIE,
|
||||
TEXT,
|
||||
SLUR_ON,
|
||||
SLUR_OFF,
|
||||
TIE,
|
||||
CLOSE_TIE,
|
||||
TITLE,
|
||||
CHANNEL,
|
||||
TRANSPOSE,
|
||||
RTRANSPOSE,
|
||||
GTRANSPOSE,
|
||||
GRACEON,
|
||||
GRACEOFF,
|
||||
SETGRACE,
|
||||
SETC,
|
||||
SETTRIM,
|
||||
EXPAND,
|
||||
GCHORD,
|
||||
GCHORDON,
|
||||
GCHORDOFF,
|
||||
VOICE,
|
||||
CHORDON,
|
||||
CHORDOFF,
|
||||
CHORDOFFEX,
|
||||
DRUMON,
|
||||
DRUMOFF,
|
||||
DRONEON,
|
||||
DRONEOFF,
|
||||
SLUR_TIE,
|
||||
TNOTE,
|
||||
/* broken rhythm */
|
||||
LT,
|
||||
GT,
|
||||
DYNAMIC,
|
||||
LINENUM,
|
||||
MUSICLINE,
|
||||
MUSICSTOP,
|
||||
WORDLINE,
|
||||
WORDSTOP,
|
||||
INSTRUCTION,
|
||||
NOBEAM,
|
||||
CHORDNOTE,
|
||||
CLEF,
|
||||
PRINTLINE,
|
||||
NEWPAGE,
|
||||
LEFT_TEXT,
|
||||
CENTRE_TEXT,
|
||||
VSKIP,
|
||||
COPYRIGHT,
|
||||
COMPOSER,
|
||||
ARPEGGIO,
|
||||
SPLITVOICE,
|
||||
META,
|
||||
PEDAL_ON,
|
||||
PEDAL_OFF,
|
||||
EFFECT
|
||||
} featuretype;
|
||||
|
||||
/* note decorations */
|
||||
#define DECSIZE 13
|
||||
extern char decorations[];
|
||||
#define STACCATO 0
|
||||
#define TENUTO 1
|
||||
#define LOUD 2
|
||||
#define ROLL 3
|
||||
#define FERMATA 4
|
||||
#define ORNAMENT 5
|
||||
#define TRILL 6
|
||||
#define BOWUP 7
|
||||
#define BOWDOWN 8
|
||||
#define BREATH 9
|
||||
#define CODA 10
|
||||
#define UPPERMORDENT 11
|
||||
#define SEGNO 12
|
||||
|
||||
/* The vstring routines provide a simple way to handle */
|
||||
/* arbitrary length strings */
|
||||
struct vstring {
|
||||
int len;
|
||||
int limit;
|
||||
char* st;
|
||||
};
|
||||
#ifndef KANDR
|
||||
/* vstring routines */
|
||||
extern void initvstring(struct vstring* s);
|
||||
extern void extendvstring(struct vstring* s);
|
||||
extern void addch(char ch, struct vstring* s);
|
||||
extern void addtext(char* text, struct vstring* s);
|
||||
extern void clearvstring(struct vstring* s);
|
||||
extern void freevstring(struct vstring* s);
|
||||
/* error-handling routines */
|
||||
extern void event_error(char *s);
|
||||
extern void event_fatal_error(char *s);
|
||||
extern void event_warning(char *s);
|
||||
#else
|
||||
/* vstring routines */
|
||||
extern void initvstring();
|
||||
extern void extendvstring();
|
||||
extern void addch();
|
||||
extern void addtext();
|
||||
extern void clearvstring();
|
||||
extern void freevstring();
|
||||
/* error-handling routines */
|
||||
extern void event_error();
|
||||
extern void event_fatal_error();
|
||||
extern void event_warning();
|
||||
#endif
|
||||
|
||||
1561
abcmatch.c
Normal file
1561
abcmatch.c
Normal file
File diff suppressed because it is too large
Load Diff
3
config.h.in
Normal file
3
config.h.in
Normal file
@@ -0,0 +1,3 @@
|
||||
/* config.h.in */
|
||||
|
||||
|
||||
42
configure.ac
Normal file
42
configure.ac
Normal file
@@ -0,0 +1,42 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([abcmidi], [2011-08-03], [seymour.shlien@crc.ca])
|
||||
AC_CONFIG_SRCDIR([abc.h])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
# Checks for programs.
|
||||
cflags_save="$CFLAGS"
|
||||
AC_PROG_CC
|
||||
CFLAGS="$cflags_save"
|
||||
|
||||
dnl This mechanism allows one to enable debug compilations...
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug Enable debugging information],
|
||||
USE_DEBUG="$enableval", USE_DEBUG="no")
|
||||
if test $USE_DEBUG = yes ; then
|
||||
CFLAGS="$CFLAGS -g"
|
||||
else
|
||||
CFLAGS="$CFLAGS -O2"
|
||||
fi
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
# Checks for libraries.
|
||||
# FIXME: Replace `main' with a function in `-lm':
|
||||
AC_CHECK_LIB([m], [main])
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([stdlib.h string.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_TYPE_SIZE_T
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_ERROR_AT_LINE
|
||||
AC_FUNC_MALLOC
|
||||
AC_CHECK_FUNCS([strcasecmp strchr])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
114
crack.c
Normal file
114
crack.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* crack - put the command line to the vice.
|
||||
*
|
||||
* This routine takes four arguments, the variables argc and argv from
|
||||
* the program's main procedure, a list of flags to recognize, and an
|
||||
* indication whether to ignore unknown flags or not.
|
||||
*
|
||||
* The action of crack is to read a command line laid out in the format:
|
||||
*
|
||||
* % command [flags]... [files]...
|
||||
*
|
||||
* where the flags are of the form -foption, that is, a minus, a character
|
||||
* and an optional argument, butted up to the character. No space may
|
||||
* appear between any flag and its option. The first command line
|
||||
* argument not preceded by '-' is taken as the end of the flags and the
|
||||
* beginning of file names.
|
||||
*
|
||||
* The flags argument to crack looks like this: "a|b|cd" for flags a b c
|
||||
* and d. In this example, a and b take (optional!) options, as specified
|
||||
* by the trailing colon, c and d do not. When crack scans a flag, it
|
||||
* returns the flag character after setting the external character pointer
|
||||
* arg_option to the option part. It also sets arg_index to the index of
|
||||
* the argv variable scanned. Crack returns NULL when it has scanned the
|
||||
* last flag. The value of arg_index then points at the first
|
||||
* argument after the last flag, which should be the first filename, if
|
||||
* any. If there are no arguments, or no more arguments after reading
|
||||
* the flags, arg_index == argc;
|
||||
*
|
||||
* Flags may be concatenated, for instance, using the flags argument
|
||||
* given above: -cd will treat c and d as
|
||||
* flags. -cdaoption also works. However, tacking what you think is
|
||||
* a flag after another flag that takes an option will cause the flag to
|
||||
* be lost. I.e., -ac will treat c as an option, not a flag.
|
||||
*
|
||||
* When the ignore flag is zero, flags scanned that are not in the flags
|
||||
* variable generate an error message and crack returns EOF. If ignore is
|
||||
* nonzero, unknown flags are suppressed, that is, no flag is returned.
|
||||
* The purpose of ignoring flags is so that more than one part of a
|
||||
* program can scan the command line without having to know about the
|
||||
* flags of all the other parts. For instance, where a program calculates
|
||||
* a sampling rate by one flag and a value in seconds in another, it must
|
||||
* search for the sampling rate first, then the time value. Two calls to
|
||||
* crack() would be required, one to scan just for the flag setting sampling
|
||||
* rate, another to ignore the rate flag, but to set the time value based
|
||||
* on the sampling rate.
|
||||
* NOTE: WHEN MAKING MORE THAN ONE CALL TO crack() IN A PROGRAM, IT
|
||||
* IS NECESSARY TO RESET arg_index TO 0 FIRST.
|
||||
*
|
||||
* When ignoring unknown flags, if an unknown flag has an option
|
||||
* associated with it, the option is also ignored. Care should be excercised
|
||||
* here because it may be possible that the associated "option" is really
|
||||
* more concatenated flags. These, if any, are lost. The rule is that,
|
||||
* when ignoring unknown flags, the first instance of an unknown flag
|
||||
* causes that flag and the rest of that argument to be discarded. For
|
||||
* instance, if flags is set to "a:b:cd", and a command line:
|
||||
* "-zcdaoption" is supplied, c d and a would be ignored because they come
|
||||
* after z in the same argument. The point is there is no way to disambiguate
|
||||
* flags from unknown options when ignoring flags, so concatenating options,
|
||||
* while nice, is problematical.
|
||||
*
|
||||
* FIX applied : index changed to index 6/9/96
|
||||
* FIX applied : crack returns char* instead of char 22/6/98
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* define USE_INDEX if your C libraries have index() instead of strchr() */
|
||||
#ifdef USE_INDEX
|
||||
#define strchr index
|
||||
#endif
|
||||
|
||||
int arg_index = 0;
|
||||
char *arg_option;
|
||||
char *pvcon = NULL;
|
||||
|
||||
char* crack(argc, argv, flags, ign)
|
||||
int argc; char **argv; char *flags; int ign;
|
||||
{
|
||||
char *pv, *flgp, *strchr();
|
||||
while ((arg_index) < argc)
|
||||
{
|
||||
if (pvcon != NULL)
|
||||
pv = pvcon;
|
||||
else
|
||||
{
|
||||
if (++arg_index >= argc) return(NULL);
|
||||
pv = argv[arg_index];
|
||||
if (*pv != '-')
|
||||
return(NULL);
|
||||
}
|
||||
pv++; /* skip '-' or prev. flag */
|
||||
if (pv != NULL)
|
||||
{
|
||||
if ((flgp=strchr(flags,*pv)) != NULL)
|
||||
{
|
||||
pvcon = pv;
|
||||
if (*(flgp+1) == '|') { arg_option = pv+1; pvcon = NULL; }
|
||||
return(pv);
|
||||
}
|
||||
else
|
||||
if (!ign)
|
||||
{
|
||||
fprintf(stderr, "%s: no such flag: %s\n", argv[0], pv);
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
pvcon = NULL;
|
||||
}
|
||||
pvcon = NULL;
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
252
debug.c
Normal file
252
debug.c
Normal file
@@ -0,0 +1,252 @@
|
||||
/* debug.c */
|
||||
/* part of yaps - abc to PostScript converter */
|
||||
/* print tune data structure to screen for debugging purposes only */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "abc.h"
|
||||
#include "structs.h"
|
||||
|
||||
void showfeature(struct feature *ft)
|
||||
{
|
||||
char* astring;
|
||||
struct fract* afract;
|
||||
struct key* akey;
|
||||
struct rest* arest;
|
||||
struct tuple* atuple;
|
||||
struct note* anote;
|
||||
struct aclef* theclef;
|
||||
switch (ft->type) {
|
||||
case SINGLE_BAR: printf("SINGLE_BAR\n");
|
||||
break;
|
||||
case DOUBLE_BAR: printf("DOUBLE_BAR\n");
|
||||
break;
|
||||
case BAR_REP: printf("BAR_REP\n");
|
||||
break;
|
||||
case REP_BAR: printf("REP_BAR\n");
|
||||
break;
|
||||
case REP1: printf("REP1\n");
|
||||
break;
|
||||
case REP2: printf("REP2\n");
|
||||
break;
|
||||
case PLAY_ON_REP:
|
||||
printf("PLAY_ON_REP %s\n", (char*)ft->item);
|
||||
break;
|
||||
case BAR1: printf("BAR1\n");
|
||||
break;
|
||||
case REP_BAR2: printf("REP_BAR2\n");
|
||||
break;
|
||||
case DOUBLE_REP: printf("DOUBLE_REP\n");
|
||||
break;
|
||||
case THICK_THIN: printf("THICK_THIN\n");
|
||||
break;
|
||||
case THIN_THICK: printf("THIN_THICK\n");
|
||||
break;
|
||||
case PART: printf("PART\n");
|
||||
astring = ft->item;
|
||||
break;
|
||||
case TEMPO: printf("TEMPO\n");
|
||||
break;
|
||||
case TIME:
|
||||
afract = ft->item;
|
||||
printf("TIME %d / %d\n", afract->num, afract->denom);
|
||||
break;
|
||||
case KEY: printf("KEY\n");
|
||||
akey = ft->item;
|
||||
break;
|
||||
case REST: printf("REST\n");
|
||||
arest = ft->item;
|
||||
break;
|
||||
case TUPLE: printf("TUPLE\n");
|
||||
atuple = ft->item;
|
||||
break;
|
||||
case NOTE:
|
||||
anote = ft->item;
|
||||
printf("NOTE %c%c %d / %d\n", anote->accidental, anote->pitch,
|
||||
anote->len.num, anote->len.denom);
|
||||
if (anote->gchords != NULL) {
|
||||
astring = firstitem(anote->gchords);
|
||||
while (astring != NULL) {
|
||||
printf("gchord: %s\n", astring);
|
||||
astring = nextitem(anote->gchords);
|
||||
};
|
||||
};
|
||||
if (anote->syllables != NULL) {
|
||||
astring = firstitem(anote->syllables);
|
||||
while (astring != NULL) {
|
||||
printf("syllable: %s\n", astring);
|
||||
astring = nextitem(anote->syllables);
|
||||
};
|
||||
};
|
||||
printf("stemup=%d beaming=%d base =%d base_exp=%d x=%.1f left=%.1f right=%.1f\n",
|
||||
anote->stemup, anote->beaming, anote->base, anote->base_exp,
|
||||
ft->x, ft->xleft, ft->xright);
|
||||
break;
|
||||
case CHORDNOTE:
|
||||
anote = ft->item;
|
||||
printf("CHORDNOTE %c%c %d / %d\n", anote->accidental, anote->pitch,
|
||||
anote->len.num, anote->len.denom);
|
||||
printf("stemup=%d beaming=%d base =%d base_exp=%d x=%.1f left=%.1f right=%.1f\n",
|
||||
anote->stemup, anote->beaming, anote->base, anote->base_exp,
|
||||
ft->x, ft->xleft, ft->xright);
|
||||
printf("x=%.1f\n", ft->x);
|
||||
break;
|
||||
case NONOTE: printf("NONOTE\n");
|
||||
break;
|
||||
case OLDTIE: printf("OLDTIE\n");
|
||||
break;
|
||||
case TEXT: printf("TEXT\n");
|
||||
break;
|
||||
case SLUR_ON: printf("SLUR_ON\n");
|
||||
break;
|
||||
case SLUR_OFF: printf("SLUR_OFF\n");
|
||||
break;
|
||||
case TIE: printf("TIE\n");
|
||||
break;
|
||||
case CLOSE_TIE: printf("CLOSE_TIE\n");
|
||||
break;
|
||||
case TITLE: printf("TITLE\n");
|
||||
break;
|
||||
case CHANNEL: printf("CHANNEL\n");
|
||||
break;
|
||||
case TRANSPOSE: printf("TRANSPOSE\n");
|
||||
break;
|
||||
case RTRANSPOSE: printf("RTRANSPOSE\n");
|
||||
break;
|
||||
case GRACEON: printf("GRACEON\n");
|
||||
break;
|
||||
case GRACEOFF: printf("GRACEOFF\n");
|
||||
break;
|
||||
case SETGRACE: printf("SETGRACE\n");
|
||||
break;
|
||||
case SETC: printf("SETC\n");
|
||||
break;
|
||||
case GCHORD: printf("GCHORD\n");
|
||||
break;
|
||||
case GCHORDON: printf("GCHORDON\n");
|
||||
break;
|
||||
case GCHORDOFF: printf("GCHORDOFF\n");
|
||||
break;
|
||||
case VOICE: printf("VOICE\n");
|
||||
break;
|
||||
case CHORDON: printf("CHORDON\n");
|
||||
break;
|
||||
case CHORDOFF: printf("CHORDOFF\n");
|
||||
break;
|
||||
case SLUR_TIE: printf("SLUR_TIE\n");
|
||||
break;
|
||||
case TNOTE: printf("TNOTE\n");
|
||||
break;
|
||||
case LT: printf("LT\n");
|
||||
break;
|
||||
case GT: printf("GT\n");
|
||||
break;
|
||||
case DYNAMIC: printf("DYNAMIC\n");
|
||||
break;
|
||||
case LINENUM:
|
||||
printf("LINENUM %p\n", (void *)(ft->item)); /* [SDG] 2020-06-03 */
|
||||
break;
|
||||
case MUSICLINE: printf("MUSICLINE\n");
|
||||
break;
|
||||
case PRINTLINE: printf("PRINTLINE\n");
|
||||
break;
|
||||
case MUSICSTOP: printf("MUSICSTOP\n");
|
||||
break;
|
||||
case WORDLINE: printf("WORDLINE\n");
|
||||
break;
|
||||
case WORDSTOP: printf("WORDSTOP\n");
|
||||
break;
|
||||
case INSTRUCTION: printf("INSTRUCTION\n");
|
||||
break;
|
||||
case NOBEAM: printf("NOBEAM\n");
|
||||
break;
|
||||
case CLEF: printf("CLEF\n");
|
||||
theclef = ft->item;
|
||||
break;
|
||||
case SPLITVOICE: printf("SPLITVOICE\n");
|
||||
default:
|
||||
printf("unknown type: %d\n", (int)ft->type);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
static int showline(v)
|
||||
struct voice* v;
|
||||
/* draws one line of music from specified voice */
|
||||
{
|
||||
struct feature* ft;
|
||||
/* struct note* anote;
|
||||
struct key* akey;
|
||||
char* astring;
|
||||
struct fract* afract;
|
||||
struct rest* arest;
|
||||
struct tuple* atuple;
|
||||
struct aclef* theclef;
|
||||
*/
|
||||
int sharps;
|
||||
struct chord* thischord;
|
||||
int chordcount;
|
||||
int printedline;
|
||||
|
||||
if (v->place == NULL) {
|
||||
return(0);
|
||||
};
|
||||
chordcount = 0;
|
||||
v->beamed_tuple_pending = 0;
|
||||
thischord = NULL;
|
||||
if (v->keysig == NULL) {
|
||||
event_error("Voice has no key signature");
|
||||
} else {
|
||||
sharps = v->keysig->sharps;
|
||||
};
|
||||
ft = v->place;
|
||||
printedline = 0;
|
||||
while ((ft != NULL) && (!printedline)) {
|
||||
/* printf("type = %d\n", ft->type); */
|
||||
showfeature(ft);
|
||||
ft = ft->next;
|
||||
};
|
||||
v->place = ft;
|
||||
return(1);
|
||||
}
|
||||
|
||||
void showtune(struct tune* t)
|
||||
/* print abc structure to the screen */
|
||||
{
|
||||
char* atitle;
|
||||
int notesdone;
|
||||
struct voice* thisvoice;
|
||||
|
||||
notesdone = 0;
|
||||
atitle = firstitem(&t->title);
|
||||
while (atitle != NULL) {
|
||||
printf("TITLE: %s\n", atitle);
|
||||
atitle = nextitem(&t->title);
|
||||
};
|
||||
if (t->composer != NULL) {
|
||||
printf("COMPOSER: %s\n", t->composer); /* [SDG] 2020-06-03 */
|
||||
};
|
||||
if (t->origin != NULL) {
|
||||
printf("ORIGIN: %s\n", t->origin);
|
||||
};
|
||||
if (t->parts != NULL) {
|
||||
printf("PARTS: %s\n", t->parts);
|
||||
};
|
||||
thisvoice = firstitem(&t->voices);
|
||||
while (thisvoice != NULL) {
|
||||
thisvoice->place = thisvoice->first;
|
||||
thisvoice = nextitem(&t->voices);
|
||||
};
|
||||
/*
|
||||
doneline = 1;
|
||||
while(doneline) {
|
||||
*/
|
||||
thisvoice = firstitem(&t->voices);
|
||||
while (thisvoice != NULL) {
|
||||
printf("-----------(voice %d)-------\n", thisvoice->voiceno);
|
||||
showline(thisvoice);
|
||||
thisvoice = nextitem(&t->voices);
|
||||
};
|
||||
/* }; */
|
||||
}
|
||||
|
||||
26
doc/AUTHORS
Normal file
26
doc/AUTHORS
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
This file contains additional documentation for the abcMIDI package :
|
||||
|
||||
Unix Man Pages
|
||||
--------------
|
||||
* abc2midi.1 man pages for abc2midi written by Christoph Dalitz.
|
||||
* midi2abc.1 man page for midi2abc written by Christoph Dalitz.
|
||||
* abc2abc.1 man page for abc2abc written by Anselm Lingnau.
|
||||
* mftext.1 man page for mftext written by Anselm Lingnau.
|
||||
|
||||
These man pages are now supported by Seymour Shlien
|
||||
|
||||
If you wish to preview these man pages use groff with the -man
|
||||
option. The output is normally in postscript format, but you
|
||||
can override this using the -a option. For example,
|
||||
groff -man -a abc2midi.1
|
||||
|
||||
|
||||
To install the man pages, copy them to appropriate directory (typically
|
||||
this will be /usr/man/man1). You may also need to run mandb after
|
||||
copying them across.
|
||||
|
||||
Code Documentation
|
||||
------------------
|
||||
* abc2midi.txt : notes on the abc2midi code written by Seymour Shlien.
|
||||
* midi2abc.txt : notes on the midi2abc code written by Seymour Shlien.
|
||||
13748
doc/CHANGES
Normal file
13748
doc/CHANGES
Normal file
File diff suppressed because it is too large
Load Diff
123
doc/abc2abc.1
Normal file
123
doc/abc2abc.1
Normal file
@@ -0,0 +1,123 @@
|
||||
.TH ABC2ABC 1 "07 June 2011"
|
||||
.SH NAME
|
||||
abc2abc \- a simple abc checker/re-formatter/transposer
|
||||
.SH SYNOPSIS
|
||||
\fBabc2abc\fP \fIfile\fP [ \fB-s\fP ] [ \fB-n\fP ] [ \fB-b\fP ]
|
||||
[ \fB-r\fP ] [ \fB-e\fP ] [ \fB-t \fP\fIsemitones\fP ] [ \fB-nda\fP ]
|
||||
[ \fB-u\fP ] [ \fB-d\fP ] [ \fB-v\fP ] [ \fB-V\fP\fIvoice number\fP]
|
||||
[\fB-P\fP\fivoice number\fp] [\fB-nokeys\fP]
|
||||
[ \fB-nokeyf\fP] [ \fB-usekey\fP\fI(sharps/flats)\fP]
|
||||
[\fB-useclef\fP\fI(treble/clef)\fP] [ \fB-OCC\fP ]
|
||||
.SH "DESCRIPTION"
|
||||
.PP
|
||||
.B abc2abc
|
||||
is a simple abc checker/re-formatter/transposer.
|
||||
It will check whether the \fIfile\fP given on the command line
|
||||
obeys basic abc syntax.
|
||||
.PP
|
||||
If you want to check an abc tune,
|
||||
it is recommended that you use
|
||||
.B abc2midi
|
||||
with the \fB-c\fP option.
|
||||
This performs extra checks that
|
||||
.B abc2abc
|
||||
does not do.
|
||||
.PP
|
||||
The output of
|
||||
.B abc2abc
|
||||
goes to standard output.
|
||||
Use redirection to save it to a file.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-s
|
||||
Rework spacing in the file (which affects how notes are beamed together
|
||||
when the music is printed out). This option does not appear to be working
|
||||
correctly.
|
||||
.TP
|
||||
.BI \-n " X"
|
||||
Reformats the abc file with line breaks every \fIX\fP bars.
|
||||
.TP
|
||||
.B \-b
|
||||
Don't do bar checking.
|
||||
.TP
|
||||
.B \-r
|
||||
Don't do repeat checking.
|
||||
.TP
|
||||
.B \-e
|
||||
Don't report errors.
|
||||
.TP
|
||||
.BI \-t " n"
|
||||
Transpose tune by \fIn\fP semitones. This function will also
|
||||
work with K: none or one of \-nokeys or \-nokeyf.
|
||||
If a voice is assigned to channel 10 (drum channel) using a
|
||||
%%MIDI channel 10
|
||||
command, then this voice is never transposed.
|
||||
|
||||
.TP
|
||||
.B \-nda
|
||||
Convert double accidentals in guitar chord to another chord though
|
||||
strictly not correct.
|
||||
.TP
|
||||
.B \-u
|
||||
Update notation; the older notation \fB+ +\fP for chords is replaced by
|
||||
\fB[]\fP and \fBs s\fP for slurs is replaced by \fB()\fP.
|
||||
.TP
|
||||
.B \-OCC
|
||||
Accept the old notation for chord. Normally this is turned off,
|
||||
since it conflicts with abc draft standard version 2.0 for
|
||||
decorations (eg. +crescendo(+).
|
||||
.TP
|
||||
.B \-d
|
||||
Re-notate the tune with all note lengths doubled. The unit length specified by the L: field
|
||||
command is halved (e.g. L:1/8 to L:1/16).
|
||||
.TP
|
||||
.B \-v
|
||||
Re-notate the tune with all note lengths halved. The unit length specified by the L: field
|
||||
command is doubled (e.g. L:1/8 to L:1/4).
|
||||
.TP
|
||||
.B \-ver
|
||||
Prints version number and exits.
|
||||
.TP
|
||||
.BI \-V " X[,Y...]"
|
||||
For multivoiced abc files (i.e. contains V: field commands), only voices \fIX[,Y,...]\fP are copied.
|
||||
.TP
|
||||
.BI \-P " X,[,Y...]"
|
||||
For multivoiced abc files (i.e. contains V: field commands), all voices except \fIX[,Y...]\fP remain the same. Voices X,Y... are modified according the other runtime parameters.
|
||||
.TP
|
||||
.BI \-X " n"
|
||||
For a file containing many tunes, the X: reference numbers are renumbered sequentially
|
||||
starting from number \fIn\fP.
|
||||
.TP
|
||||
.BI \-xref " n"
|
||||
Only the tune with X: n is processed.
|
||||
.TP
|
||||
.B \-nokeys
|
||||
No key signature will be assumed. Instead, sharps and naturals will
|
||||
be placed wherever they are needed.
|
||||
.TP
|
||||
.B \-nokeyf
|
||||
No key signature will be assumed. Instead, flats and naturals will
|
||||
be placed wherever they are needed.
|
||||
.TP
|
||||
.B \-usekey " sf
|
||||
This will force abc2abc to output the notes in the key signature
|
||||
keys[sf] where sf specifies the number of flats (\-negative) or
|
||||
sharps (+positive) in the key signature. It is a number between
|
||||
\-5 and +5 inclusive.
|
||||
.TP
|
||||
.B \-useclef
|
||||
This works with only the -t (transpose) and provided the abc
|
||||
file does not already have a clef command in the K: field. It
|
||||
does not support voices.
|
||||
.PP
|
||||
* Normally abc2abc will convert the deprecated notation for
|
||||
decorations (eg. !ppp!) to the abc version 2.0 draft standard (eg. +ppp+).
|
||||
If you do not wish to change to this standard include the \-OCC flag.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.IR abcmtex "(1), " abc2midi "(1), " midi2abc "(1), " mftext "(1)"
|
||||
.SH AUTHOR
|
||||
This manual page was written by Anselm Lingnau <lingnau@tm.informatik.uni-frankfurt.de> and is now supported by Seymour Shlien <fy733@ncf.ca>
|
||||
for the GNU/Linux system.
|
||||
.SH VERSION
|
||||
This man page describes abc2abc version 2.04 from January 22 2020.
|
||||
568
doc/abc2midi.1
Normal file
568
doc/abc2midi.1
Normal file
@@ -0,0 +1,568 @@
|
||||
.TH ABC2MIDI 1 "June 2017"
|
||||
.SH NAME
|
||||
\fBabc2midi\fP \- converts abc file to MIDI file(s)
|
||||
.SH SYNOPSIS
|
||||
abc2midi \fIinfile\fP [\fIrefnum\fP] [\-c] [\-v] [\-ver] [\-t] [\-n limit] [\-CS] [\-quiet] [\-silent] [\-Q tempo] [\-NFNP] [\-NFER] [\-NGRA] [\-NGUI] [\-STFW] [\-OCC] [\-NCOM] [\-HARP] [\-BF] [\-TT] [\-o outfile] \-CSM [filename]
|
||||
.SH DESCRIPTION
|
||||
The default action is to write a MIDI file for each abc tune
|
||||
with the filename <stem>N.mid, where <stem> is the filestem
|
||||
of the abc file and N is the tune reference number. If the \-o
|
||||
option is used, only one file is written. This is the tune
|
||||
specified by the reference number or, if no reference number
|
||||
is given, the first tune in the file.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \fIrefnum\fP
|
||||
process the tune with reference number \fIrefnum\fP
|
||||
.TP
|
||||
.B -c
|
||||
selects checking only
|
||||
.TP
|
||||
.B -v n
|
||||
selects verbose option where n is the level (optional)
|
||||
.TP
|
||||
.B -ver
|
||||
prints version number and exits
|
||||
.TP
|
||||
.B -t
|
||||
selects filenames derived from tune titles
|
||||
.TP
|
||||
.B -CS
|
||||
use 2:1 instead of 3:1 for broken rhythms
|
||||
.TP
|
||||
.B -quiet
|
||||
Suppresses some common warnings.
|
||||
.TP
|
||||
.B -silent
|
||||
Suppresses other messages.
|
||||
.TP
|
||||
.B -n \fI X\fP
|
||||
limits the length of the file name stem to X characters
|
||||
.TP
|
||||
.B -Q \fI tempo\fP
|
||||
sets the default tempo in quarter notes per minute if it was not
|
||||
specified in the abc header.
|
||||
.TP
|
||||
.B -NFNP
|
||||
Ignore any dynamic indications !f! !ff! etc.
|
||||
.TP
|
||||
.B -NFER
|
||||
Ignore any fermata indications (eg H or !fermata!).
|
||||
.TP
|
||||
.B -NGRA
|
||||
Ignore any grace notes.
|
||||
.TP
|
||||
.B -NGUI
|
||||
Ignore any guitar chords enclosed in double quotes.
|
||||
.TP
|
||||
.B -STFW
|
||||
Place lyric text in separate MIDI tracks.
|
||||
.TP
|
||||
.B -NCOM
|
||||
Suppress some comments in the output MIDI file.
|
||||
.TP
|
||||
.B -OCC
|
||||
Accept old chord convention (eg +D2G2+ instead of [DG]2).
|
||||
.TP
|
||||
.B -BF
|
||||
BarFly mode: invokes a stress model if possible.
|
||||
.TP
|
||||
.B -HARP
|
||||
Roll ornaments=roll are generated for the harpist (same pitch)
|
||||
.TP
|
||||
.B -TT
|
||||
Changes the tuning from A = 440 Hz.
|
||||
.TP
|
||||
.B -o \fIoutfile\fP
|
||||
write output to \fIoutfile\fP
|
||||
.TP
|
||||
.B -CSM \fIinfile\fP
|
||||
load a set of custom stress modes from a file
|
||||
.SH FEATURES
|
||||
.PP
|
||||
* Broken rhythms (>, <), chords, n-tuples, slurring, ties, staccatto notes,
|
||||
repeats, in-tune tempo/length/time signature changes are all supported.
|
||||
.PP
|
||||
* R:hornpipe or r:hornpipe is recognized and note timings are adjusted to
|
||||
give a broken rhythm (ab is converted to a>b).
|
||||
.PP
|
||||
* Most errors in the abc input will generate a suitable error message in
|
||||
the output and the converter keeps going.
|
||||
.PP
|
||||
* Comments and text fields in the abc source are converted to text events
|
||||
in the MIDI output
|
||||
.PP
|
||||
* If guitar chords are present, they are used to generate an accompaniment
|
||||
in the MIDI output.
|
||||
.PP
|
||||
* If there are mis-matched repeat signs in the abc, the program attempts to
|
||||
fix them. However, it will not attempt this if a multi-part tune
|
||||
description has been used or if multiple voices are in use.
|
||||
.PP
|
||||
* Karaoke MIDI files can be generated by using the w: field to include
|
||||
lyrics.
|
||||
.PP
|
||||
* Nonnumeric voice id's, eg. V: soprano, as proposed for the new
|
||||
abc standard is accepted.
|
||||
.PP
|
||||
* Invisible rests specified by x are treated the same way as
|
||||
normal rests (z).
|
||||
.PP
|
||||
* Decorations may be indicated using either the deprecated
|
||||
notation (eg. !fermata!) or the standard version 2.0 notation
|
||||
(eg. +fermata+).
|
||||
.PP
|
||||
.SH LIMITATIONS
|
||||
* No field is inherited from above the X: field of the tune.
|
||||
|
||||
|
||||
.SH "ABC SYNTAX EXTENSIONS"
|
||||
* There are some extensions to the abc syntax of the form
|
||||
.PP
|
||||
%%MIDI channel n
|
||||
.PP
|
||||
These control channel and program selection, transposing and various
|
||||
other features of abc2midi.
|
||||
.PP
|
||||
Each of these should appear on a line by itself. All of them are allowed
|
||||
within the abc tune body. By using these in combination with the part
|
||||
notation, one can, for example, play a part transposed or in a different key.
|
||||
.PP
|
||||
The idea behind this syntax is that other programs will treat it as a
|
||||
comment and ignore it.
|
||||
.PP
|
||||
%%MIDI channel n
|
||||
.PP
|
||||
selects melody channel n (in the range 1-16).
|
||||
.PP
|
||||
%%MIDI program [c] n
|
||||
.PP
|
||||
selects program n (in the range 0-127) on channel c. If c is not given, the
|
||||
program is selected on the current melody channel. Most modern tone
|
||||
generators follow the General MIDI standard which defines the instrument
|
||||
type for each program number.
|
||||
.PP
|
||||
%%MIDI beat a b c n
|
||||
.PP
|
||||
controls the way note velocities are selected. The first note in a bar has
|
||||
velocity a. Other "strong" notes have velocity b and all the rest have velocity
|
||||
c. a, b and c must be in the range 0-127. The parameter n determines which
|
||||
notes are "strong". If the time signature is x/y, then each note is given
|
||||
a position number k = 0, 1, 2 .. x-1 within each bar. Note that the units for
|
||||
n are not the unit note length. If k is a multiple of n, then the note is
|
||||
"strong". The volume specifiers !ppp! to !fff! are equivalent to the
|
||||
following :
|
||||
.P
|
||||
!ppp! = %%MIDI beat 30 20 10 1
|
||||
.br
|
||||
!pp! = %%MIDI beat 45 35 20 1
|
||||
.br
|
||||
!p! = %%MIDI beat 60 50 35 1
|
||||
.br
|
||||
!mp! = %%MIDI beat 75 65 50 1
|
||||
.br
|
||||
!mf! = %%MIDI beat 90 80 65 1
|
||||
.br
|
||||
!f! = %%MIDI beat 105 95 80 1
|
||||
.br
|
||||
!ff! = %%MIDI beat 120 110 95 1
|
||||
.br
|
||||
!fff! = %%MIDI beat 127 125 110 1
|
||||
|
||||
.PP
|
||||
%%MIDI beatmod n
|
||||
.PP
|
||||
Increments by n (or decrements if n is negative) the velocities a, b and
|
||||
c described above. The instructions !crescendo(! and !crescendo)!
|
||||
are equivalent to inserting a %%MIDI beatmod 15 wherever they
|
||||
occur. (Alternatively you can use !<(! and !<)!.) Similarly the
|
||||
instructions !diminuendo(! and !diminuendo)! are equivalent
|
||||
to %%MIDI beatmod \-15.
|
||||
|
||||
.PP
|
||||
%%MIDI deltaloudness n
|
||||
.PP
|
||||
where n is a small positive number. By default the crescendo and
|
||||
diminuendo instructions modify the beat variables a, b, and c by
|
||||
15 velocity units. This instruction allows you to set this default
|
||||
to value n.
|
||||
|
||||
.PP
|
||||
%%MIDI nobeataccents
|
||||
.PP
|
||||
For instruments such as church organ that have no greatly emphasized beat notes,
|
||||
using this will force use of the 'b' velocity (see %%MIDI beat)
|
||||
for every note irrespective of position in the bar. This allows dynamics
|
||||
(ff, f, etc) to be used in the normal way.
|
||||
.PP
|
||||
%%MIDI beataccents
|
||||
.PP
|
||||
Revert to emphasizing notes the the usual way. (default)
|
||||
|
||||
.PP
|
||||
%%MIDI beatstring <string of f, m and p>
|
||||
.PP
|
||||
This provides an alternative way of specifying where the strong and weak
|
||||
stresses fall within a bar. 'f' means velocity a (normally strong), 'm'
|
||||
means velocity b (medium velocity) and 'p' means velocity c (soft velocity).
|
||||
For example, if the time signature is 7/8 with stresses on the first, fourth
|
||||
and sixth notes in the bar, we could use the following
|
||||
.PP
|
||||
%%MIDI beatstring fppmpmp
|
||||
.PP
|
||||
%%MIDI transpose n
|
||||
.PP
|
||||
transposes the output by the specified number of semitones. n may be
|
||||
positive or negative.
|
||||
.PP
|
||||
%%MIDI rtranspose n
|
||||
.PP
|
||||
Relative transpose by the specified number of semitones. i.e.
|
||||
%%MIDI transpose a followed by %%MIDI rtranspose b results in a
|
||||
transposition of a+b. %%MIDI transpose b will result in a transposition
|
||||
of b semitones, regardless of any previous transposition.
|
||||
.PP
|
||||
%%MIDI c n
|
||||
.PP
|
||||
specifies the MIDI pitch which corresponds to c. The default is 60. This
|
||||
number should normally be a multiple of 12.
|
||||
.PP
|
||||
%%MIDI grace a/b
|
||||
.PP
|
||||
sets the fraction of the next note that grace notes will take up. a
|
||||
must be between 1 and b-1. The grace notes may not sound natural
|
||||
in this approach, since the length of the individual grace notes
|
||||
vary with the complexity of the grace and the length of the
|
||||
following note. A different approach (which is now the default)
|
||||
assumes that the grace notes always have a fixed duration.
|
||||
To use the other approach you would specify,
|
||||
|
||||
%%MIDI gracedivider b
|
||||
|
||||
where b specifies how many parts to divide the unit length
|
||||
specified by the L: field command. For example if b = 4 and
|
||||
L: = 1/8, then every grace note would be 1/(8*4) or a 32nd
|
||||
note. Time would be stolen from the note to which the grace
|
||||
notes are applied. If that note is not long enough to handle
|
||||
the grace then the grace notes would be assigned 0 duration.
|
||||
|
||||
|
||||
|
||||
.PP
|
||||
%%MIDI chordname name n1 n2 n3 n4 n5 n6
|
||||
.PP
|
||||
Defines how to play a guitar chord called "name". n1 is usually 0 and
|
||||
n2, n3 to n6 give the pitches of the other notes in semitones relative
|
||||
to the root note. There may be fewer than 6 notes in the chord, but not
|
||||
more.If "name" is already defined, this command re-defines it. Unlike
|
||||
most other commands, chordname definitions stay in effect from where they
|
||||
are defined to the end of the abc file. The following illustrates how
|
||||
m, 7, m7 and maj7 could be set up if they were not already defined.
|
||||
.PP
|
||||
%%MIDI chordname m 0 3 7
|
||||
.br
|
||||
%%MIDI chordname 7 0 4 7 10
|
||||
.br
|
||||
%%MIDI chordname m7 0 3 7 10
|
||||
.br
|
||||
%%MIDI chordname maj7 0 4 7 11
|
||||
.PP
|
||||
%%MIDI gchord string
|
||||
.PP
|
||||
sets up how guitar chords are generated. The string is a sequence made of
|
||||
of z's, c's f's and b's for rests, chords, fundamental and fundamental
|
||||
plus chord notes respectively. This specifies how each bar is to be played.
|
||||
An optional length is allowed to follow the z's, c's f's and b's e.g. czf2zf3.
|
||||
If the abc contains guitar chords, then abc2midi automatically adds chords and
|
||||
fundamentals after encountering the first guitar chord. It keeps using that
|
||||
chord until a new chord is specified in the abc. Whenever the M: field is
|
||||
encountered in the abc, an appropriate default string is set :
|
||||
.P
|
||||
For 2/4 or 4/4 time default is equivalent to :
|
||||
%%MIDI gchord fzczfzcz
|
||||
.P
|
||||
For 3/4 time default is equivalent to :
|
||||
%%MIDI gchord fzczcz
|
||||
.P
|
||||
For 6/8 time default is equivalent to :
|
||||
%%MIDI gchord fzcfzc
|
||||
.P
|
||||
For 9/8 time default is equivalent to :
|
||||
%%MIDI gchord fzcfzcfzc
|
||||
.P
|
||||
|
||||
The gchord command has been extended to allow you to play
|
||||
the individual notes comprising the guitar chord. This allows
|
||||
you to play broken chords or arpeggios. The new codes g,h,i,j,
|
||||
G,H,I,J reference the individual notes starting from the
|
||||
lowest note of the chord (not necessarily the root in the
|
||||
case of inversions). For example for the C major chord, g
|
||||
refers to C, h refers to E and i refers to G. For a gchord
|
||||
command such as,
|
||||
.P
|
||||
%%MIDI gchord ghih
|
||||
.P
|
||||
Abc2midi will arpeggiate the C major guitar chord to
|
||||
CEGE. The upper case letters G,H,I, and J refer to
|
||||
the same notes except they are transposed down one
|
||||
octave. Note for the first inversion of the C major
|
||||
chord (indicated by "C/E"), E would be the lowest
|
||||
note so g would reference the note E.
|
||||
.P
|
||||
Like other gchord codes, you may append a numeral indicating
|
||||
the duration of the note. The same rules apply as before.
|
||||
You can use any combination of the gchord codes,
|
||||
(fcbghijGHIJz).
|
||||
|
||||
|
||||
.PP
|
||||
%%MIDI chordprog n
|
||||
.PP
|
||||
Sets the MIDI instrument for the chords to be n. If the command
|
||||
includes the string octave=n where n is a number between \-2 and 2
|
||||
inclusive, then this will shift the pitch of the instrument by n
|
||||
octaves. For example %%MIDI chordprog 10 octave=1.)
|
||||
|
||||
.PP
|
||||
%%MIDI bassprog n
|
||||
.PP
|
||||
Sets the MIDI instrument for the bass notes to be n. If the command
|
||||
includes the string octave=n where n is a number between \-2 and 2
|
||||
inclusive, then this will shift the pitch of the instrument by n
|
||||
octaves. For example %%MIDI bassprog 10 octave=\-1.)
|
||||
.PP
|
||||
%%MIDI chordvol n
|
||||
.PP
|
||||
Sets the volume (velocity) of the chord notes at n.
|
||||
.PP
|
||||
%%MIDI bassvol n
|
||||
.PP
|
||||
Sets the volume (velocity) of the bass notes at n. There is no corresponding
|
||||
melodyvol command since there are 3 velocity values for melody, set using the
|
||||
beat command.
|
||||
.PP
|
||||
%%MIDI gchordon
|
||||
.PP
|
||||
Turns on guitar chords (they are turned on by default at the start of a
|
||||
tune).
|
||||
.PP
|
||||
%%MIDI gchordoff
|
||||
.PP
|
||||
Turns off guitar chords.
|
||||
.PP
|
||||
%%MIDI droneon
|
||||
.PP
|
||||
Turns on a continuous drone (used in bagpipe music) consisting
|
||||
of two notes. By default the notes are A, and A,, played
|
||||
on a bassoon at a velocity of 80. This can be configured
|
||||
by the %%MIDI drone command described below.
|
||||
.PP
|
||||
%%MIDI droneoff
|
||||
.PP
|
||||
Turns off the continuous drone.
|
||||
.PP
|
||||
%%MIDI drone n1 n2 n3 n4 n5
|
||||
.PP
|
||||
Sets the drone parameters where n1 is the MIDI program, n2 and
|
||||
n3 specify the MIDI pitches of the two notes in the chord, and n4
|
||||
and n5 specify the MIDI velocities of the two notes.
|
||||
If you do not set these parameters they are by default
|
||||
70 45 33 80 80. A value of zero or less indicates that
|
||||
the setting of this parameter should be left as it is.
|
||||
.PP
|
||||
%%MIDI drum string [drum programs] [drum velocities]
|
||||
.PP
|
||||
This sets up a drum pattern. The string determines when there is a drum beat
|
||||
and the drum program values determine what each drum strike sounds like.
|
||||
.PP
|
||||
e.g. %%MIDI drum d2zdd 35 38 38 100 50 50
|
||||
.PP
|
||||
The string may contain 'd' for a drum strike or 'z' for a rest. By default
|
||||
a voice starts with no drum pattern and '%%MIDI drumon' is
|
||||
needed to enable the drumming. The drum pattern is repeated during
|
||||
each bar until '%%MIDI drumoff' is encountered. The %%MIDI drum
|
||||
command may be used within a tune to change the drum pattern.
|
||||
This command places the drum sounds on channel 10 and
|
||||
assumes your tone generator complies with the General Midi standard - if
|
||||
it does not, then you may hear tones instead of drum sounds.
|
||||
.PP
|
||||
In both the gchord and drum commands, the standard note length of
|
||||
a single note f,c,z or d is not set by the L: command. Instead it
|
||||
is adjusted so that the entire gchord string or drum string fits
|
||||
exactly into one bar. In other words the duration of each note
|
||||
is divided by the total duration of the string. This means that,
|
||||
for example, the drum string "dd" is equivalent to drum string "d4d4".
|
||||
You cannot currently specify fractions directly (eg. C3/2)
|
||||
as done in the body of the music, but it is still possible to express
|
||||
complex rhythms. For example, to indicate a rhythm such as
|
||||
(3ddd d/d/d/d, you would write the string "d4d4d4d3d3d3d3".
|
||||
.PP
|
||||
%%MIDI drumbars n
|
||||
.PP
|
||||
The %%MIDI drum line can sound quite monotonous if it is repeated
|
||||
each bar. To circumvent this problem a new MIDI command
|
||||
%%MIDI drumbars n
|
||||
where n is a small number will spread out the drum string over
|
||||
n consecutive bars. By default drumbars is set to 1 maintaining
|
||||
compatibility with existing abc files. You should take
|
||||
care that the drumstring is evenly divisible between the
|
||||
drumbar bars. Also the time signature should not change
|
||||
between bars in a drumbar unit. (Sample abc file in doc/CHANGES
|
||||
June 24 2008.)
|
||||
.PP
|
||||
%%MIDI gchordbars n
|
||||
.PP
|
||||
This command spreads the gchord string over n consecutive bars
|
||||
just like drumbars (above). (A sample is found in doc/CHANGES
|
||||
March 17 2009.)
|
||||
|
||||
|
||||
|
||||
|
||||
.PP
|
||||
With version 1.54 Dec 4 2004 of abc2midi, notes in chords
|
||||
(eg. [FAc]) are not played in the same instant but offsetted
|
||||
and shortened by 10 MIDI time units. Thus the first note
|
||||
in the chord (eg. F) is played for the full indicated time,
|
||||
the second note (eg. A) starts 10 MIDI units later and is shortened
|
||||
by the same amount and the third note starts another 10 MIDI
|
||||
units later and is shortened by another 10 units. This introduces
|
||||
an "expressivo" option and avoids the heavy attack. (This
|
||||
does not apply to gchords or multivoiced chords.) The amount
|
||||
of the delay and shortening may be configured by the MIDI command
|
||||
|
||||
.PP
|
||||
%%MIDI chordattack n
|
||||
|
||||
.PP
|
||||
where n is a small number. If n is zero, then abc2midi should
|
||||
behave as in earlier versions. The delay n is in MIDI time units
|
||||
where there are 480 units in a quarter note beat. The program
|
||||
may not run correctly if n is too large and there are short
|
||||
chords.
|
||||
|
||||
.PP
|
||||
%%MIDI randomchordattack n
|
||||
.PP
|
||||
Like above except that the delay is a random variable uniformly
|
||||
distributed between 0 and n-1.
|
||||
|
||||
.PP
|
||||
%%MIDI trim x/y
|
||||
.PP
|
||||
where x and y are two numbers. This command controls the articulation
|
||||
of notes and chords by placing silent gaps between the notes. The length
|
||||
of these gaps is determined by x/y and the unit length specified by the L:
|
||||
command. These gaps are produced by shortening the notes by the same amount.
|
||||
If the note is already shorter than the specified gap, then the gap
|
||||
is set to half the length of the note. The fraction x/y indicates
|
||||
a note duration in the same manner as specified in the abc file.
|
||||
The actual duration is based on the unit length specified by the
|
||||
L: field command. It is recommended that x/y be a fraction close
|
||||
to zero. Note trimming is disabled inside slurs as specified by
|
||||
parentheses. You can turn off all note trimming by setting x to 0,
|
||||
eg 0/1. By default, note trimming is turned off at the beginning
|
||||
of a tune or voice command.
|
||||
|
||||
.PP
|
||||
%%MIDI expand x/y
|
||||
.PP
|
||||
where x and y are two numbers defining a fraction less than 1.
|
||||
This command controls the articulation of notes and chords in the
|
||||
reverse manner. The notes are lengthened by this fraction so they
|
||||
overlap the start of the next note.
|
||||
|
||||
|
||||
.PP
|
||||
%%MIDI drummap note midipitch
|
||||
.PP
|
||||
Please see abcguide.txt.
|
||||
.PP
|
||||
%%MIDI ptstress filename
|
||||
.PP
|
||||
This command loads file filename into abc2midi which contains
|
||||
the Phil Taylor stress parameters and puts abc2midi in the mode
|
||||
where it applies these stress parameters on every note. This
|
||||
model runs in opposition to the standard beat model, so the
|
||||
MIDI beat, beatstring, beatmod commands become ineffectual.
|
||||
This also means that the dynamic indications !f! !pp! etc.
|
||||
do not work any more.
|
||||
.PP
|
||||
There are two different implementations of the stress model.
|
||||
Model 1 modifies the note articulation and takes
|
||||
control of the MIDI trim parameters too. To revert back to
|
||||
the standard model, put the command %%MIDI beataccents.
|
||||
Model 2 modifies both the onset and ending of each note
|
||||
allowing a musical beat to expand or contract in time. However,
|
||||
the length of a musical measure should be preserved. Note
|
||||
if you using model 2, which the current default, you must
|
||||
include \-BF as one of the runtime parameters of abc2midi.
|
||||
.PP
|
||||
The model divides a bar into equal segments. For each segment,
|
||||
a loudness or MIDI velocity is specified and a duration multiplier
|
||||
is specified. If a note falls into a specific segment, it assumes
|
||||
the velocity of that segment and its duration is modified
|
||||
accordingly. If the note overlaps more than one segment, then
|
||||
the note assumes the average of those segment values.
|
||||
.PP
|
||||
The input file specifies the number of segments and the loudness
|
||||
and duration multipliers for each segment. The file has the
|
||||
following format. The first value is the number of segments and each line
|
||||
specifies the velocity and duration multiplier of the specific
|
||||
segment. The velocity is limited to 127 and the duration is a
|
||||
decimal number. The note durations is modified by varying the
|
||||
gap between notes, so it is not possible to extend a note. This
|
||||
preserves the regular tempo of the music. The program scales,
|
||||
the note duration indications by dividing it by the maximum
|
||||
value which here is 1.4.
|
||||
|
||||
.PP
|
||||
%%MIDI stressmodel n
|
||||
.PP
|
||||
|
||||
where n is either 1 or 2, selects the stress model implementation.
|
||||
|
||||
.PP
|
||||
other %%MIDI commands such as bendvelocity, bendstring,
|
||||
controlstring have been introduced recently and are described
|
||||
in the file abcguide.txt.
|
||||
|
||||
|
||||
|
||||
.SH "COMPATIBILITY WITH DRAFT STANDARD 2.0"
|
||||
|
||||
.PP
|
||||
The proposed standard introduces a new copyright field
|
||||
using the syntax
|
||||
|
||||
.PP
|
||||
%%abc-copyright (c) Copyright John Smith 2003
|
||||
|
||||
.PP
|
||||
Abc2midi now inserts this in the MIDI file in the form of a
|
||||
metatext copyright tag. Changes were made to the event_specific
|
||||
function in store.c to process the copyright information. It
|
||||
is also copied into the Karaoke track (if it is created) as
|
||||
as @T field.
|
||||
|
||||
.PP
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
abc2ps(1), midi2abc(1), yaps(1).
|
||||
.SH AUTHOR
|
||||
James Allwright <J.R.Allwright@westminster.ac.uk>
|
||||
.SH SUPPORTED
|
||||
by Seymour Shlien <fy733@ncf.ca>
|
||||
.SH VERSION
|
||||
This man page describes abc2midi version 2.27 June 25 2006.
|
||||
.SH COPYRIGHT
|
||||
Copyright 1999 James Allwright
|
||||
.PP
|
||||
abc2midi is supplied "as is" without any warranty. It
|
||||
is free software and can be used, copied, modified and
|
||||
distributed without fee under the terms of the GNU General
|
||||
Public License.
|
||||
.PP
|
||||
More complete documentation may be found in abcguide.txt
|
||||
which comes with the abcMIDI distribution.
|
||||
1693
doc/abcguide.txt
Normal file
1693
doc/abcguide.txt
Normal file
File diff suppressed because it is too large
Load Diff
120
doc/abcmatch.1
Normal file
120
doc/abcmatch.1
Normal file
@@ -0,0 +1,120 @@
|
||||
.TH ABCMATCH 1
|
||||
.SH NAME
|
||||
abcmatch \- Search for specific sequences of notes in an abc file composed of many tunes.
|
||||
.SH SYNOPSIS
|
||||
\fBabcmatch\fP \fiabc\ file\fP [\fB-c\fP] [\fB-v\fP] [\fB-r\fP] [\fB-con\fP]\
|
||||
[\fB-fixed nn\fP] [\fB-qnt\fP] [\fB-lev\fP] [\fB-a\fP] [\fB-ign\fP]\
|
||||
[\fB-br %d\fP] [\fB-tp abc reference file\fP] [\fB-ver\fP]\
|
||||
[\fB-pitch_hist\fP] [\fB-wpitch_hist\fP] [\fB-length_hist\fP]\
|
||||
[\fB-interval_hist\fP] [\fB-pitch_table\fP] [\fB-interval_table\fP]\
|
||||
\fireference\ number\fP
|
||||
.SH "DESCRIPTION"
|
||||
.PP
|
||||
.B abcmatch
|
||||
is used to search for specific sequences of notes in an abc file
|
||||
composed of many tunes. For example, if you know a few bars of a tune,
|
||||
you can use this program to find the tune having this sequence and perhaps
|
||||
identify the tune.
|
||||
At a minimum, abcmatch requires two files. A template file called
|
||||
match.abc which contains the bars that you are searching for and a large
|
||||
file consisting of a hundred or more abc tunes. The program automatically
|
||||
loads up the match.abc file and then scans every tune in the large file
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -v and -c
|
||||
mainly used for debugging when the program does not do what was expected.
|
||||
.TP
|
||||
.B -ver
|
||||
prints version number and then exits
|
||||
.TP
|
||||
.B --norhythm
|
||||
Causes the matching algorithm to ignore the length of notes in a bar,
|
||||
thus E3/2F/D GA2 would match EFD G2A. The option ignores \-r parameter
|
||||
since it is now irrelevant.
|
||||
.TP
|
||||
.B -pitch_table
|
||||
Used to produce a interval weighted pitch histogram for each tune in
|
||||
the file. If this is saved in an external file, that file could be used
|
||||
as a database for finding tunes with similar pitch probability density
|
||||
functions (pdf).
|
||||
.TP
|
||||
.B -r
|
||||
Controls how the matching criterion handles small rhythm variations in
|
||||
the melody. The \-r option must be followed by a number which specifies
|
||||
the temporal resolution for the match. When the number is zero, this
|
||||
indicates that a perfect match should be performed, meaning that the
|
||||
lengths of each note in the bar must match exactly in order to be
|
||||
reported. For larger values a looser match will be performed as
|
||||
described below. Note lengths are converted into temporal units where
|
||||
a quarter note normally is assigned a value of 24. Therefore an eight
|
||||
note has a value of 12, a sixteenth has a value of 6, a half note has
|
||||
a value of 48 and etc. If you specify a temporal resolution of 12, then
|
||||
the pitch values of the notes only need to match at time units which
|
||||
are multiples of an eighth note.
|
||||
.TP
|
||||
.B -fixed n
|
||||
Causes the program to disregard bar lines when does the matching. It
|
||||
allows matching of notes between tunes having different time signatures.
|
||||
n is a number which specifies the exact number of notes to match. For
|
||||
example if n is 4, the program could match
|
||||
|C E G E| .. with |C E|G E|
|
||||
Note the matcher still starts at a beginning of a given bar for both the
|
||||
tune and template.
|
||||
.TP
|
||||
.B -con
|
||||
Specifies contour matching. In this case, the program uses the key
|
||||
signature only to indicate accidentals. The pitch contour is computed
|
||||
from the pitch difference or interval between adjacent notes.
|
||||
.TP
|
||||
.B -qnt
|
||||
Uses the contour matching algorithm but also quantizes the intervals
|
||||
using the following table:
|
||||
|
||||
unison and semitone 0
|
||||
minor 2nd to major 2nd 1
|
||||
minor 3rd to major 3rd 2
|
||||
any larger interval 3
|
||||
|
||||
Negative numbers are descending intervals.
|
||||
.TP
|
||||
.B -tp file name, reference number
|
||||
Substitute any tune for the template match.abc. When using this
|
||||
feature, the entire tune is used as a template. Abcmatch does not match
|
||||
the template with itself, and only bars which match bars in other tunes
|
||||
are reported.
|
||||
.TP
|
||||
.B -br threshold
|
||||
Runs the program in a brief mode designed to identify groups of tunes
|
||||
sharing common bars. In this mode, the program counts the numbers of
|
||||
bars in the test tune which are also present in match.abc. If the
|
||||
number of common bars is larger or equal to the threshold then the
|
||||
program reports the tune and the number of common bars.
|
||||
The program scans all the tunes in the abc file and returns a list of
|
||||
all the tunes which have more than a specific number of bars in common
|
||||
with the template, match.abc. In actual use, the program is run
|
||||
repeatedly by a script. For each tune in a abc file, it creates a
|
||||
template file called match.abc and then executes abcmatch. The outputs
|
||||
are displayed on the screen in a form easy to interpret. The user has
|
||||
no control of the matching criterion. The rhythm must match exactly
|
||||
and the notes are transposed to suit the key signature. In other words
|
||||
the \-r parameter is independent of what is specified in the parameter
|
||||
list.
|
||||
.TP
|
||||
.B -pitch_hist or -length_hist
|
||||
Runs the program in another mode. It produces a histogram of the
|
||||
distribution of the notes in the abc file.
|
||||
The pitch is indicated in midi units. Thus middle C is 60 and the
|
||||
pitches go up in semitone units. Following the pitch is a count
|
||||
of the number of times that note occurred.
|
||||
.TP
|
||||
.B -pitch_table or -interval_table
|
||||
Used to create a database for a collection of tunes in a file for
|
||||
future analysis.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.PP
|
||||
.IR abc2abc "(1), " abc2midi "(1), " mftext "(1) ", midi2abc "(1) ", midicopy "(1) ", yaps "(1)"
|
||||
.SH AUTHOR
|
||||
This manual page was written by Ross Gammon based on abcmatch.txt by Seymour Shlien.
|
||||
.SH VERSION
|
||||
This man page describes abcmatch version 1.35 from January 15 2006.
|
||||
318
doc/abcmatch.txt
Normal file
318
doc/abcmatch.txt
Normal file
@@ -0,0 +1,318 @@
|
||||
abcmatch version 1.35 January 15 2006.
|
||||
|
||||
seymour shlien <fy733@ncf.ca>
|
||||
|
||||
Introduction:
|
||||
------------
|
||||
|
||||
The purpose of this program is to search for specific sequences of
|
||||
notes in an abc file composed of many tunes. For example, if you
|
||||
know a few bars of a tune, you can use this program to find the
|
||||
tune having this sequence and perhaps identify the tune.
|
||||
|
||||
At a minimum, abcmatch requires two files. A template file called
|
||||
match.abc which contains the bars that you are searching for and
|
||||
a large file consisting of a hundred or more abc tunes.
|
||||
The program automatically loads up the match.abc file and
|
||||
then scans every tune in the large file.
|
||||
|
||||
The match.abc file is a regularly formatted abc file containing
|
||||
the basic fields, X:, M:, L:, and K: and the body.
|
||||
Normally, this file is created by runabc.tcl.
|
||||
An example match.abc file is shown below.
|
||||
|
||||
|
||||
X:1
|
||||
M:6/8
|
||||
L:1/8
|
||||
K:E
|
||||
cff f2e|
|
||||
|
||||
As well as the sample bars, abcmatch needs to know the meter
|
||||
(given by M:) and the key signature (given by K:). The default note
|
||||
length L: should also be given if it is not 1/8. It is important
|
||||
that all bars be terminated with a bar line indicated by |
|
||||
(otherwise that bar may not be seen by the program).
|
||||
|
||||
Abcmatch uses the key signature to know the relative position
|
||||
of the notes in the scale. It also uses the key signature to
|
||||
determine all the assumed sharps and flats. Thus the program
|
||||
can find matching bars in a tune transposed to another key
|
||||
signature (assuming the key difference is not too large).
|
||||
When the program finds matches, they are returned in a list that
|
||||
looks like this.
|
||||
|
||||
abcmatch.exe scotjig.abc
|
||||
29 30 4
|
||||
30 31 4
|
||||
|
||||
|
||||
Each line indicates a particular match made by the program.
|
||||
The first number, (eg. 29) indicates the relative position of
|
||||
the tune in the abc file. Thus in this example, it indicates
|
||||
that a match was found for the 29 th tune in compilation file
|
||||
scotjib.abc. The next number is the X: reference number of
|
||||
that tune, and the last number is the bar number of the matching
|
||||
tune. Bar numbers are counted sequentially from the start of
|
||||
the tune, ignoring all V: and P: indications. Thus the bar
|
||||
numbers may not match the ones you get when you print the
|
||||
tune using one of the variants of abc2ps or yaps.
|
||||
|
||||
Though the program can be run stand alone, it is really meant to
|
||||
be run with a graphics user interface such as runabc.tcl (version
|
||||
1.59 or higher). Most of its output is rather cryptic.
|
||||
|
||||
In performing the match, the program ignores all guitar chords,
|
||||
karaoke, note decorations (eg. stacatto markings), grace notes
|
||||
and hornpipe rhythm indications in either the match.abc template
|
||||
file or in the target file. Furthermore if chords in the form
|
||||
of [G2c2] are embedded in the abc file, only the higher note
|
||||
c2 is matched. Any warnings and error messages that are normally
|
||||
returned by the parser are suppressed unless the run time
|
||||
parameter -c is included.
|
||||
|
||||
|
||||
Installation:
|
||||
------------
|
||||
|
||||
Unless you are running the program on Microsoft's windows
|
||||
operating system, it will be necessary for you to build the
|
||||
program from sources. For windows environment, I shall provide
|
||||
the executable. Here is how the makefile looks.
|
||||
|
||||
CFLAGS=-c
|
||||
abcmatch: parseabc.o matchsup.o abcmatch.o
|
||||
gcc parseabc.o matchsup.o abcmatch.o -o abcmatch.exe
|
||||
|
||||
parseabc.o : parseabc.c abc.h
|
||||
gcc $(CFLAGS) abcparse.c
|
||||
|
||||
matchsup.o : matchsup.c abc.h
|
||||
gcc $(CFLAGS) abcstore.c
|
||||
|
||||
abcmatch.o : abcmatch.c abc.h
|
||||
gcc $(CFLAGS) abcmatch.c
|
||||
|
||||
The program has been built using the gcc (GNU compiler) as well
|
||||
as Microsoft Visual C++ (with many warning messages).
|
||||
|
||||
|
||||
Operation:
|
||||
---------
|
||||
|
||||
Here is now an explanation of the program and its run time
|
||||
parameters. If you run abcmatch without any parameters you
|
||||
will see:
|
||||
|
||||
abcmatch version 1.55
|
||||
Usage : abcmatch <abc file> [-options]
|
||||
[reference number] selects a tune
|
||||
-c returns error and warning messages
|
||||
-v selects verbose option
|
||||
-r resolution for matching
|
||||
-con pitch contour match
|
||||
-fixed <n> fixed number of notes
|
||||
-qnt quantized pitch contour
|
||||
-lev use levenshtein distance
|
||||
-a report any matching bars (default all bars)
|
||||
-ign ignore simple bars
|
||||
-br %d only report number of matched bars when
|
||||
above given threshold
|
||||
-tp <abc file> [reference number]
|
||||
-ver returns version number
|
||||
-pitch_hist pitch histogram
|
||||
-wpitch_hist interval weighted pitch histogram
|
||||
-length_hist pitch histogram
|
||||
-interval_hist pitch interval histogram
|
||||
-pitch_table separate pitch pdfs for each tune
|
||||
-interval_table separate interval pdfs for each tune
|
||||
|
||||
|
||||
When running this program, you must provide the name of the abc file name
|
||||
containing the numerous tunes. The other parameters are optional and
|
||||
are explained below.
|
||||
|
||||
The -c and -v options are mainly used for debugging when the
|
||||
program does not do what was expected. The -ver option does
|
||||
nothing but return the version number of the program. (This
|
||||
is used to perform a sanity check when you are running it
|
||||
from runabc).
|
||||
|
||||
All the remaining parameters (-r -con -a -br) control the matching
|
||||
process.
|
||||
|
||||
The option -norhythm, causes the matching algorithm to ignore
|
||||
the length of notes in a bar, thus E3/2F/D GA2 would match
|
||||
EFD G2A. The option ignores -r parameter since it is now
|
||||
irrelevant.
|
||||
|
||||
The option -pitch_table is used to produce a interval weighted
|
||||
pitch histogram for each tune in the file. If this is saved
|
||||
in an external file, that file could be used as a database
|
||||
for finding tunes with similar pitch probability density functions
|
||||
(pdf).
|
||||
|
||||
The -r parameter controls how the matching criterion handles
|
||||
small rhythm variations in the melody. The -r option must be
|
||||
followed by a number which specifies the temporal resolution
|
||||
for the match. When the number is zero, this indicates that
|
||||
a perfect match should be performed, meaning that the lengths
|
||||
of each note in the bar must match exactly in order to be
|
||||
reported. For larger values a looser match will be performed
|
||||
as described below. Note lengths are converted into temporal
|
||||
units where a quarter note normally is assigned a value of
|
||||
24. Therefore an eight note has a value of 12, a sixteenth has
|
||||
a value of 6, a half note has a value of 48 and etc. If you
|
||||
specify a temporal resolution of 12, then the pitch values
|
||||
of the notes only need to match at time units which are multiples
|
||||
of an eighth note.
|
||||
|
||||
This means that the program would match the two bars
|
||||
C2 D2| and C C D D|.
|
||||
Similarly C2 D2| would also match C/D/C/D/D2|. By using
|
||||
a suitable value of the resolution, you can perform the
|
||||
matching only at the beginning of a measure or at the
|
||||
beginning of each beat.
|
||||
|
||||
The -fixed <n> option causes the program to disregard
|
||||
bar lines when does the matching. It allows matching
|
||||
of notes between tunes having different time signatures.
|
||||
n is a number which specifies the exact number of
|
||||
notes to match. For example if n is 4, the program
|
||||
could match
|
||||
|C E G E| .. with |C E|G E|
|
||||
Note the matcher still starts at a beginning
|
||||
of a given bar for both the tune and template.
|
||||
|
||||
Normally, when the program is presented with a sequence
|
||||
of several bars, the program will try it match it with
|
||||
a matching sequence. If abcmatch is run with the -a option,
|
||||
then the bars are matched individually in any sequence.
|
||||
In other words any matching bar found is reported.
|
||||
|
||||
The -con option specifies contour matching. In this case,
|
||||
the program uses the key signature only to indicate accidentals.
|
||||
The pitch contour is computed from the pitch difference
|
||||
or interval between adjacent notes.
|
||||
|
||||
Thus C2 DE| and c2 de| and G2 AB| all have the same pitch
|
||||
contour.
|
||||
|
||||
The -qnt option will use the contour matching algorithm
|
||||
but also quantize the intervals using the following table
|
||||
|
||||
unison and semitone 0
|
||||
minor 2nd to major 2nd 1
|
||||
minor 3rd to major 3rd 2
|
||||
any larger interval 3
|
||||
|
||||
negative numbers are descending intervals.
|
||||
|
||||
The -tp followed by a file name and reference number
|
||||
allows you to substitute any tune for the template match.abc.
|
||||
When using this feature, the entire tune is used as a
|
||||
template. Abcmatch does not match the template with itself,
|
||||
and only bars which match bars in other tunes are reported.
|
||||
|
||||
The -br followed by a threshold, runs the program in a brief
|
||||
mode designed to identify groups of tunes sharing common bars.
|
||||
(-br stands for brief mode; I cannot think of a better name
|
||||
right now.) In this mode, the program counts the numbers of bars
|
||||
in the test tune which are also present in match.abc. If the
|
||||
number of common bars is larger or equal to the threshold
|
||||
then the program reports the tune and the number of common bars.
|
||||
The program scans all the tunes in the abc file and returns
|
||||
a list of all the tunes which have more than a specific number
|
||||
of bars in common with the template, match.abc. In actual
|
||||
use, the program is run repeatedly by a script. For each
|
||||
tune in a abc file, it creates a template file called match.abc
|
||||
and then executes abcmatch. The outputs are displayed on the
|
||||
screen in a form easy to interpret. Currently, the user
|
||||
has no control of the matching criterion. The rhythm must
|
||||
match exactly and the notes are transposed to suit the key
|
||||
signature. In other words the -r parameter is zero independent
|
||||
of what is specified in the parameter list.
|
||||
|
||||
The -pitch_hist or -length_hist runs the program in another mode.
|
||||
It produces a histogram of the distribution of the notes in the
|
||||
abc file. Thus if you type
|
||||
abcmatch.exe scotjig.abc -pitch_hist
|
||||
|
||||
pitch_histogram
|
||||
64 2
|
||||
66 9
|
||||
67 11
|
||||
69 30
|
||||
71 18
|
||||
73 12
|
||||
74 14
|
||||
76 14
|
||||
78 14
|
||||
79 4
|
||||
81 4
|
||||
|
||||
The pitch is indicated in midi units. Thus middle C is 60 and the
|
||||
pitches go up in semitone units. Following the pitch is a count
|
||||
of the number of times that note occurred. If you type
|
||||
|
||||
abcmatch.exe scotjig.abc -length_hist
|
||||
|
||||
length histogram
|
||||
12 100
|
||||
24 20
|
||||
36 6
|
||||
48 2
|
||||
72 4
|
||||
|
||||
|
||||
The program quantizes a quarter note into 24 units. Thus eighth notes
|
||||
have a value of 12, dotted half notes 72, etc. The program does
|
||||
not require the match.abc file to be present if you are computing
|
||||
the histograms since it does not perform any matching.
|
||||
|
||||
|
||||
abcmatch.exe scotjig.abc -interval_hist
|
||||
|
||||
computes the histogram of the pitch interval in midi units
|
||||
between adjacent notes. The histogram is restricted between
|
||||
intervals -12 and 12 units.
|
||||
|
||||
eg.
|
||||
interval_histogram
|
||||
-5 2
|
||||
-4 3
|
||||
-3 10
|
||||
-2 17
|
||||
-1 3
|
||||
0 8
|
||||
1 3
|
||||
2 23
|
||||
3 11
|
||||
4 1
|
||||
5 4
|
||||
|
||||
For a collection of tunes in a file, you can use -pitch_table
|
||||
or -interval_table to create a database for future analysis.
|
||||
|
||||
|
||||
Limits of the program
|
||||
---------------------
|
||||
|
||||
The program has some limits. For example, the abc file must
|
||||
have bar lines. Tied notes cannot be longer than 8 quarter notes.
|
||||
Specifying a too small resolution (eg. -r 1) may causes some
|
||||
buffers to be exceeded. When there are differences of key
|
||||
signatures more than 5 semitones, the program may transpose
|
||||
the notes in the wrong direction.
|
||||
|
||||
Abc tunes with more than one key signature or time signature
|
||||
may not be processed correctly.
|
||||
|
||||
Comment:
|
||||
________
|
||||
|
||||
|
||||
This program is designed to be a research tool to find
|
||||
similarities between abc tunes. I have discovered a few
|
||||
problems with tied notes and double or triple bar lines.
|
||||
|
||||
340
doc/gpl.txt
Normal file
340
doc/gpl.txt
Normal file
@@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
525
doc/history.txt
Normal file
525
doc/history.txt
Normal file
@@ -0,0 +1,525 @@
|
||||
This file has not been updated since I have taken over
|
||||
the support of the abcMIDI package. To see the list
|
||||
of the latest versions see the readme.txt file. To see
|
||||
a log of all the changes I have made see the file CHANGES.
|
||||
The abcguide.txt and the unix (linux) man files (eg. abc2midi.1)
|
||||
contain the latest user guides. The abcguide.txt probably
|
||||
contains the most detail. The official version number
|
||||
of the abcMIDI package is given in the file VERSION.
|
||||
|
||||
Seymour Shlien 26 October 2003.
|
||||
-------------------------------------------------------------
|
||||
|
||||
|
||||
current versions :
|
||||
midi2abc version 2.4
|
||||
abc2midi version 1.24
|
||||
abc2abc version 1.19
|
||||
yaps version 1.12
|
||||
|
||||
Improvements made to abcMIDI package
|
||||
------------------------------------
|
||||
1. abc2midi was found not to handle comments at end of lines properly.
|
||||
This was fixed in the source code with release 1.2.1 of abc2midi.
|
||||
|
||||
2. midi2abc was generating %MIDI instead of %%MIDI for a program change.
|
||||
This was fixed in release 1.6.1
|
||||
|
||||
3. Release 1.2.2 of abc2midi introduced the -c checking only option and
|
||||
some new error checking, as well as code to deduce repeats.
|
||||
|
||||
4. abc2abc 1.0 was released on 25th July 1996
|
||||
|
||||
5. Release 1.2.3 of abc2midi allowed more flexible use of ::, :| and |:,
|
||||
improved handling of tuples and other minor improvements.
|
||||
|
||||
6. Added #ifdefs for Mac port.
|
||||
|
||||
7. Added -xm and -xl options to midi2abc plus a straight quantization
|
||||
algorithm for better handling of MIDI output by another package.
|
||||
|
||||
8. Added -Q option to midi2abc.
|
||||
|
||||
9. Removed the default heuristic algorithm and use a straight quantization
|
||||
algorithm by default, with code to find a good note length by brute-force
|
||||
trial - Original algorithm sometimes made mistakes in quantizing.
|
||||
|
||||
10. Added V: field to allow multi-track output from abc2midi in version 1.3
|
||||
|
||||
11. Changed Error messages to Warning messages for some error conditions in
|
||||
abc2midi.
|
||||
|
||||
12. Improved bar length checking to prevent errors being generated by the
|
||||
anacrusis in abc2midi.
|
||||
|
||||
13. Added checking for equal track lengths in abc2midi.
|
||||
|
||||
14. Made midi2abc fail cleanly when it runs out of memory for notes.
|
||||
|
||||
15. Fixed part-handling bug in abc2midi.
|
||||
|
||||
16. Improved handling of bar placement in midi2abc.
|
||||
|
||||
17. Fixed various type inconsistencies in midifile.c to improve portability.
|
||||
|
||||
18. abc2midi was not handling propagation of accidentals within a bar e.g.
|
||||
|^cdc|. This was fixed.
|
||||
|
||||
19. Added handling for the 7 key signature modes and re-wrote parsekey in
|
||||
the process.
|
||||
|
||||
20. Fixed bug in hornpipe handling routine (tomidi.c).
|
||||
|
||||
21. Fixed bug in default unit calculation (toabc.c).
|
||||
|
||||
22. Changed midi2abc to look at last note to decide between equally likely
|
||||
key signatures and suggest a mode for the tune if it does not appear
|
||||
to be major mode.
|
||||
|
||||
23. Changed strchr to index in mftext.c to aid portability.
|
||||
|
||||
24. Changed handling of grace notes to report more error conditions.
|
||||
|
||||
25. Changed midi2abc to generate voice fields for format 1 files and also
|
||||
to assume the same length anacrusis in each voice.
|
||||
|
||||
26. -xa option added to midi2abc to deduce anacrusis by looking for a strong
|
||||
beat.
|
||||
|
||||
27. Release 1.4 of abc2midi allows [ and ] for chords, ( ) for slurs and also
|
||||
introduced a queue mechanism for allowing general polyphony.
|
||||
|
||||
28. Release 1.4 of abc2midi appears to a fix a problem with chord generation.
|
||||
|
||||
29. Release 1.4 of abc2midi recognizes J, H, L and R as note decorations.
|
||||
|
||||
30. Fixed bug in hornpipe routine.
|
||||
|
||||
31. Fixed bug in note decoration recognition.
|
||||
|
||||
32. Added support for multiple fields in " " and ! ! separated by ; .
|
||||
|
||||
33. Fixed problem with grace notes before chords.
|
||||
|
||||
34. Added support for new K: field standard
|
||||
|
||||
35. Fixed bug that caused spurious ties from notes at the end of a slur
|
||||
field.
|
||||
|
||||
36. Release 1.4.2 of abc2midi made on 15th January 1997.
|
||||
|
||||
36. Correction to midi2abc quantization algorithm
|
||||
|
||||
37. abc2midi changed to allow TAB character instead of space.
|
||||
|
||||
38. -n option added to abc2midi (not the PC version, which already uses
|
||||
almost the maximum possible memory).
|
||||
|
||||
39. Support added for augmented and diminished chords.
|
||||
|
||||
40. Support added for repeats in part notation e.g. P:A(AB)6.
|
||||
|
||||
41. Added transpose option to abc2abc.
|
||||
|
||||
42. Release 1.4.3 of abc2midi made on 28th April 1997.
|
||||
|
||||
43. Added support for w: field in abc2midi
|
||||
|
||||
44. Fixed problem in chord handling in abc2abc
|
||||
|
||||
45. %%MIDI gchord allowed in mid-tune
|
||||
|
||||
46. added %%MIDI chordprog, bassprog, chordvol, bassvol
|
||||
|
||||
47. length specifiers allowed in %%MIDI gchord string
|
||||
|
||||
48. fixed bar-length checking in abc2abc to do chords and grace notes
|
||||
|
||||
49. Made the linebreaking option more intelligent in abc2abc.
|
||||
|
||||
50. Made abc2abc linebreak at P:
|
||||
|
||||
51. added -u option to abc2abc
|
||||
|
||||
52. added %%MIDI control command to abc2midi
|
||||
|
||||
53. added support for karaoke MIDI to abc2midi.
|
||||
|
||||
54. changed karaoke support to act line by line.
|
||||
|
||||
55. Minor bug fix to karaoke support in version 1.5.1
|
||||
|
||||
56. Fixed bug in part handling pointed out by Steve Allen.
|
||||
|
||||
58. Complete re-write of midi2abc to use dynamic data structures.
|
||||
version 2.0 (beta) released on 8th June 1998.
|
||||
|
||||
59. Added -k (specify key) and -ga (guess anacrusis) options to midi2abc.
|
||||
Fixed bug in printing rests.
|
||||
|
||||
60. version 2.0 of midi2abc released on 12th June 1998.
|
||||
|
||||
61. non-portable error diagnosis removed from mftext and midi2abc.
|
||||
|
||||
62. midi2abc fixed to always produce legimite length notes.
|
||||
|
||||
63. Parser changed to allow arbitrarily long lines.
|
||||
|
||||
64. midi2abc changed to recognize rests before each track.
|
||||
|
||||
65. midi2abc changed to used c = 72 (and undo abc2midi pitches).
|
||||
|
||||
66. Parser changed to allow decorations to be applied to chords.
|
||||
|
||||
67. abc2midi changed to allow broken rhythm between chords.
|
||||
|
||||
68. abc2midi changed to improve accuracy of reported line numbers.
|
||||
|
||||
69. abc2midi mallocs more space for notes or text when needed.
|
||||
|
||||
70. support for staccato notes in chord.
|
||||
|
||||
71. improved tie handling code.
|
||||
|
||||
72. fix to allow all channels to be used (suggested by De Clark).
|
||||
|
||||
73. Static limit on number of syllables in w: fields removed.
|
||||
|
||||
74. Allowed . in part specifier (P: field in header).
|
||||
|
||||
75. Used %%MIDI beat to implement !ppp! to !fff!.
|
||||
|
||||
76. Added -o option to abc2midi to specify filename.
|
||||
|
||||
77. Corrected problem with Voice/Part conflict reported by Brendan Macmillan.
|
||||
|
||||
78. Removed bug in line number generation for error reports.
|
||||
|
||||
79. Version 1.5.8 of abc2midi released on 21st Sept 1998.
|
||||
|
||||
80. Further bug fixing for Voice/Part problem.
|
||||
|
||||
81. Trap buffer overflow in NOFTELL version - problem reported by Richard
|
||||
Robinson
|
||||
|
||||
82. Clean up NOFTELL modifications to remove linker problems (pcc version).
|
||||
|
||||
83. New NOFTELL mechanism introduced - do a dummy write track to determine
|
||||
track length in abc2midi.
|
||||
|
||||
84. P:X in the header allowed to be a part marker in abc2midi.
|
||||
|
||||
85. Changed save_note() so that chord generation takes account of transpose
|
||||
- problem report and bug fix by Seymour Shlien
|
||||
|
||||
86. Tidied up note off queue handling in abc2midi. Fixes problem with PCC
|
||||
version NOFTELL fix.
|
||||
|
||||
87. Changed min to long in midi2abc guesslengths(). Fixes PCC divide by
|
||||
zero error.
|
||||
|
||||
88. Added rtranspose to abc2midi.
|
||||
|
||||
89. Cleaned up midi2abc and midifilelib code (no implicit declarations of
|
||||
parameter types).
|
||||
|
||||
90. Voices inherit global transpose, tempo and meter instead of values from
|
||||
previous track.
|
||||
|
||||
91. Removed spaces from after tie signs in midi2abc : abc spec. does not
|
||||
allow spaces in chords.
|
||||
|
||||
92. voicecontext structure introduced to make K: and L: fields local to
|
||||
their own voice in file parsing stage.
|
||||
|
||||
93. printf() fix: DJGPP seems to require %ld and not %Ld in printf to print
|
||||
longs.
|
||||
|
||||
94. exit value for all codes made 1 on error and 0 on normal termination.
|
||||
|
||||
95. re-write of karaoke code to integrate it into main mywritetrack() code.
|
||||
Also allows multiple verses and has better error-checking.
|
||||
|
||||
96. Added %%MIDI chordname and library of named chords to abc2midi
|
||||
|
||||
97. Fixed bug in | handling in abc2midi w: field.
|
||||
|
||||
98. Better checking for M: field in abc2midi
|
||||
|
||||
99. chord handling and broken rhythm handling moved to first pass of
|
||||
abc2midi.
|
||||
|
||||
100. Further bug fixes for abc2midi w: field.
|
||||
|
||||
101. %%MIDI nobarlines and %%MIDI barlines options added to abc2midi -
|
||||
based on changes suggested by Laura Conrad.
|
||||
|
||||
102. Added support for M:none.
|
||||
|
||||
103. Voice numbers changed from absolute voice numbers to numerical labels.
|
||||
|
||||
104. Accompaniment written to separate track by abc2midi.
|
||||
|
||||
105. Support put in the parser for abc2ps's [X: ] inline field notation.
|
||||
|
||||
106. Fix to stop bogus Q: fields crashing abc2midi.
|
||||
|
||||
107. Support for "_Ignored words" in abc2midi.
|
||||
|
||||
108. abc2midi allows voices after voice 1 to be missing in some parts.
|
||||
|
||||
109. Changed mf_sec2ticks() in midifile.c to get rid of rounding errors
|
||||
that were affecting the PCC version of midi2abc.
|
||||
|
||||
110. Fixed problem with tracks not starting at time=0 in abc2midi.
|
||||
|
||||
111. Fixed overflow problem with long H: fields in abc2midi.
|
||||
|
||||
112. [1 allowed to go mid-bar and [2 allowed to be separated from :|
|
||||
in abc2midi. More robust repeat-fixing algorithm to take account of |1 and
|
||||
:|2.
|
||||
|
||||
113. Fix to midifile.c suggested by Seymour Shlien to fix problem with
|
||||
porting to MS visual C++.
|
||||
|
||||
114. Added support for trills in abc2midi.
|
||||
|
||||
116. Fixed bug in midi2abc that caused it to crash if input MIDI file
|
||||
contained long metatext strings.
|
||||
|
||||
117. Added support for lyrics to tied notes in abc2midi.
|
||||
|
||||
118. Fixed bug that mangled %%MIDI lines in abc2abc and also stopped
|
||||
abc2abc filtering out comments outside tune.
|
||||
|
||||
119. Added support for clefs in K: field.
|
||||
|
||||
120. Replaced K:cclef with proper clefs; baritone, tenor, alto, mezzo
|
||||
and soprano.
|
||||
|
||||
121. Minor improvements to parseabc.c - recognizes multiple '/' in
|
||||
length specifier and warns about c, or C'.
|
||||
|
||||
122. Added support for the I: field to parseabc.c and changed abc2midi
|
||||
to recognize I:octave=X.
|
||||
|
||||
123. Added -d and -v options to abc2abc for changing unit note lengths.
|
||||
|
||||
124. Parser changed to report an error for \ * ** or ! in mid music line.
|
||||
|
||||
125. midi2abc changed to look for a filename if -f option is missing.
|
||||
|
||||
126. part-handling changed in abc2midi to handle an arbitrary number of
|
||||
parts.
|
||||
|
||||
127. Support for variant endings more complicated than [1 and [2. Also
|
||||
allow || to occur mid-bar.
|
||||
|
||||
128. Support for Mac-style text files (with \r as end of line).
|
||||
|
||||
129. -o and -sum options added to midi2abc by Seymour Shlien.
|
||||
|
||||
130. Fixed bug in Part/variant ending interaction in abc2midi.
|
||||
|
||||
131. Fixed bug in yaps' handling of in-tune M: fields.
|
||||
|
||||
132. Added font selection commands to yaps.
|
||||
|
||||
133. Added support for grace notes within broken rhythm to abc2midi.
|
||||
|
||||
134. Added page numbering to yaps.
|
||||
|
||||
135. Fixed bug in yaps which caused fonts to get lost after a newpage.
|
||||
|
||||
136. Added vskip command to yaps.
|
||||
|
||||
137. Added %% font and font-spacing commands to yaps.
|
||||
|
||||
138. Minor changes to support Pacific C compiler.
|
||||
|
||||
139. Added support in yaps for ties and slurs straddling 2 music lines.
|
||||
|
||||
140. Added -x (number tunes with number in X: field) to yaps.
|
||||
|
||||
150. Fix to yaps to handle guitar chords with characters in the
|
||||
range 128-255.
|
||||
|
||||
151. Added proper tuple support to yaps - uses half-brackets when notes
|
||||
in the tuple are not a beamed set.
|
||||
|
||||
152. Changed guitar chord transposition in abc2abc to handle A/B and A(B)
|
||||
as well as not transposing anything with a leading underscore or other
|
||||
special symbols.
|
||||
|
||||
153. Added support for flipping note heads and spacing out accidentals in
|
||||
yaps.
|
||||
|
||||
154. Fix for K: parsing code which was running past the end-of-line character
|
||||
in some cases and generating extra error messages in abc2midi.
|
||||
|
||||
155. Added support for treble-8, treble+8 and similar variants in yaps.
|
||||
|
||||
156. Fix for V: fields in header causing abc2midi to crash.
|
||||
|
||||
157. Changed K: field parser to accept clef=, octave= and transpose= .
|
||||
|
||||
160. Added support for %%staffsep to yaps.
|
||||
|
||||
161. Fix to make yaps bar-length checking cope with in-tune metre changes.
|
||||
|
||||
162. Changed yaps so that all tune spacing is calculated before output file
|
||||
is opened. This is used to generate encapsulated PostScript and to
|
||||
start a new page instead of breaking a tune across pages.
|
||||
|
||||
163. Added %%MIDI beatstring to abc2midi - using code by Martijn Versteegh.
|
||||
|
||||
164. Fixed BoundingBox generation in yaps.
|
||||
|
||||
165. Added explicit function type declarations and re-ordered some functions
|
||||
as well as adding genmidi.h and queues.h to make code compile under
|
||||
Pacific C and hopefully improve portability.
|
||||
|
||||
166. Added the %%MIDI drum command and !drum! and !nodrum! to abc2midi.
|
||||
|
||||
167. Added support for %%titleleft and %%titlecaps to yaps.
|
||||
|
||||
168. Fixed crash caused by !drum! with no %%MIDI drum statement.
|
||||
|
||||
169. Fixed obscure division by zero error in midi2abc.
|
||||
|
||||
170. Added landscape mode to yaps.
|
||||
|
||||
171. Shortened tempo note tail length in yaps so that it never collides
|
||||
with the title.
|
||||
|
||||
172. Corrected positioning of C clef in yaps.
|
||||
|
||||
177. Added support for -n X to give X bars per line in abc2abc, with
|
||||
correct handling of associated w: field.
|
||||
|
||||
178. Added support for dotted rests to yaps.
|
||||
|
||||
179. Fixed bug with broken rhythm in yaps.
|
||||
|
||||
180. Fixed bug causing abc2abc to crash with comments at end of w: field.
|
||||
(code is still not ideal).
|
||||
|
||||
181. Created parser2.c for common code between abc2midi and yaps.
|
||||
|
||||
182. Made erroneous note-off events a non-fatal error in midi2abc.
|
||||
|
||||
184. Added drum track detection to midi2abc, with output that selects
|
||||
channel 10 for drums.
|
||||
|
||||
185. Removed channel number from midi2abc %%MIDI program output, so that
|
||||
abc2midi matches instrument to the correct voice in midi2abc output.
|
||||
|
||||
186. Added -s option to midi2abc to retain very short notes.
|
||||
|
||||
187. Support for abc2midi to handle very long filenames (provided by
|
||||
Colin Watson).
|
||||
|
||||
188. Fix to allow abc2midi/abc2abc/yaps parser to handle space between
|
||||
key A-G and mode.
|
||||
|
||||
189. Fix for abc2midi handling of non-consecutive voice numbers.
|
||||
|
||||
190. More user-friendly error message when chord buffer overflows in
|
||||
abc2midi.
|
||||
|
||||
191. Support for w: line continuation characters in yaps.
|
||||
|
||||
192. Fixed problem with trill generation in abc2midi (was the wrong
|
||||
length).
|
||||
|
||||
193. Fixed inconsistency in midi2abc.c causing a one octave transpose
|
||||
if the -k switch was specified.
|
||||
|
||||
194. Changed abc2midi to support _, ^, <, > and @ in guitar chords.
|
||||
|
||||
195. Added support for /<inversion note> in abc2midi guitar chords.
|
||||
|
||||
196. Fix for Q:1/2=X in yaps.
|
||||
|
||||
197. Added support for breve notes and breve rests to yaps.
|
||||
|
||||
198. Changed yaps to accept rests in tuples.
|
||||
|
||||
199. Changed parser to accept tuples written as (n::r .
|
||||
|
||||
200. Fix for handling ties across chords in yaps.
|
||||
|
||||
201. Improved handling of M:none in yaps.
|
||||
|
||||
202. Fixes for bar-length checking in yaps.
|
||||
|
||||
203. Added %%MIDI ratio to abc2midi.
|
||||
|
||||
204. Applied fix supplied by Ingo Saitz for change of tempo not being
|
||||
handled properly by abc2midi in multi-voice music.
|
||||
|
||||
205. Further fix for bar-length checking in yaps.
|
||||
|
||||
206. Added code change by Seymour Shlien to midi2abc for -sr option to
|
||||
handle MIDI with gaps between notes that come out as rests.
|
||||
|
||||
207 Added %%chordsabove and %%chordsbelow to yaps.
|
||||
|
||||
208. Added handling for U: field (abbreviation) to parser.
|
||||
|
||||
209. Fix to abc2midi to stop accidentals in accompaniment chords from
|
||||
being applied elsewhere in the bar.
|
||||
|
||||
210. Changed K: field parsing so that it only starts a tune if it
|
||||
contains a key signature.
|
||||
|
||||
211. Trapped condition where double ties could cause segmentation faults
|
||||
- thanks to Seymour Shlien for tracing down this problem.
|
||||
|
||||
212. Added -t and -n options to abc2midi for better handling of filenames.
|
||||
|
||||
213. Made parser more robust when handling L: field - thanks to Seymour
|
||||
Shlien for telling me that this could cause division by zero errors.
|
||||
|
||||
214. Fix for problem reported by Ronan Keryell - gchord generation now
|
||||
works after a meter change in the tune.
|
||||
|
||||
215. Added %%MIDI pitchbend command using code supplied by Peter Spath.
|
||||
|
||||
216. Modified readstr() in abc2midi/yaps parser to avoid potential buffer
|
||||
overflow problem.
|
||||
|
||||
217. Added support for strings before and after Q: tempo field in yaps,
|
||||
abc2midi and abc2abc. Also added support for yaps to print mid-tune
|
||||
tempo change.
|
||||
|
||||
218. Added support for N: field to yaps.
|
||||
|
||||
219. Fixed problem with channel allocation in abc2midi following bug
|
||||
report from Ronan Keryell.
|
||||
|
||||
220. Fixed abc2midi problem with broken rhythm > applied to chords
|
||||
thanks to bug report by Ronan Keryell.
|
||||
|
||||
221. Added to support for multiple bar rests with Zn notation to
|
||||
abc2abc, abc2midi and yaps.
|
||||
|
||||
222. Fix to abc2abc guitar chord transposing thanks to bug report by
|
||||
Atte Jensen.
|
||||
|
||||
223. Fix to handling of reserved characters H-Z in abc2abc following
|
||||
bug report by Luis Pablo Gasparotto.
|
||||
|
||||
224. Tidied abc2abc code by creating emit_() routines.
|
||||
|
||||
225. Fixed bug with broken rhythm marker able to insert itself in tied
|
||||
notes. Thanks to Michel Chasseriau for reporting this.
|
||||
|
||||
226. Added support for voice filtering (-V option) to abc2abc. Many of
|
||||
of the code changes for this were made by Seymour Shlien.
|
||||
|
||||
227. Added warning message to abc2midi when T: is found outside a tune.
|
||||
|
||||
228. Added -nt option to midi2abc to ignore triplets and broken rhythm.
|
||||
|
||||
229. Added -X n option to abc2abc.
|
||||
20
doc/mftext.1
Normal file
20
doc/mftext.1
Normal file
@@ -0,0 +1,20 @@
|
||||
.TH MFTEXT 1
|
||||
.SH NAME
|
||||
mftext \- Dump a MIDI file as text
|
||||
.SH SYNOPSIS
|
||||
.BI mftext " file"
|
||||
.SH "DESCRIPTION"
|
||||
.PP
|
||||
.B mftext
|
||||
gives a verbose description of what is in a MIDI file.
|
||||
You may wish to use it to check the output from
|
||||
.BR abc2midi .
|
||||
It is part of the original midifilelib distribution
|
||||
available from
|
||||
.IR http://www.harmony-central.com/MIDI/midifilelib.tar.gz .
|
||||
.SH "SEE ALSO"
|
||||
.PP
|
||||
.IR abcmtex "(1), " abc2abc "(1), " abc2midi "(1), " midi2abc "(1)"
|
||||
.SH AUTHOR
|
||||
This manual page was written by Anselm Lingnau <lingnau@tm.informatik.uni-frankfurt.de>,
|
||||
for the Debian GNU/Linux system.
|
||||
106
doc/midi2abc-stats.txt
Normal file
106
doc/midi2abc-stats.txt
Normal file
@@ -0,0 +1,106 @@
|
||||
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.
|
||||
|
||||
|
||||
264
doc/midi2abc.1
Normal file
264
doc/midi2abc.1
Normal file
@@ -0,0 +1,264 @@
|
||||
.TH MIDI2ABC 1 "1 January 2017"
|
||||
.SH NAME
|
||||
\fBmidi2abc\fP \- program to convert MIDI format files to abc notation
|
||||
.SH SYNOPSIS
|
||||
midi2abc \-f \fIinfile\fP [\-xa] [\-ga]
|
||||
[\-a \fIacbeats\fP] [\-m \fItime signature\fP]
|
||||
[\-ppu \fiparts per unit\fP] [\-aul \fidenominator of unit length\fP]
|
||||
[\-gu] [\-b \fIbars\fP] [\-Q \fItempo\fP] [\-u \fipulses\fP]
|
||||
[\-k \fIkey\fP] [\-c \fIchannel\fP] [\-obpl] [\-bpl \fibars\fP] [\-bps \fPbars\fP]
|
||||
[\-o \fIfilename\fP] [\-s] [\-sr \fiunits\fP] [\-sum] [\-nb] [\-nt]
|
||||
[\-splitvoices] [\-midigram] [\-mftext] [-mftextpulses] [\-nogr] [\-title \fistring\fP]
|
||||
[\-origin \fistring\fP]
|
||||
|
||||
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fImidi2abc\fP takes a MIDI format file and converts it to something as close
|
||||
as possible to abc text format. The user then has to add text fields not
|
||||
present in the MIDI header and possibly tidy up the abc note output.
|
||||
.PP
|
||||
The output of midi2abc is printed to the screen. To save it to a file, use
|
||||
the redirection operator, (e.g. \fImidi2abc \-f file.mid > file.abc\fP) or
|
||||
specify the output file using the \-o option.
|
||||
.PP
|
||||
Use only one or none of the options \-u \-gu, \-b and \-Q. Midi2abc normally
|
||||
converts the MIDI time units into quantum units normally corresponding to the
|
||||
abc 1/16th note or 1/32nd note. If none of these is present, the
|
||||
program will use the PPQN information in the MIDI header to compute the suitable
|
||||
conversion factor. For most MIDI files on the web, it is recommended to rely on
|
||||
the MIDI header information and not use any of the options other than
|
||||
the formatting options.
|
||||
.PP
|
||||
The program will extract the time signature information from the MIDI file
|
||||
if it is present. Otherwise it will assume 4/4 or you could specify it with
|
||||
\-m. option.
|
||||
.PP
|
||||
If the tune has an anacrusis, you can use either the \-ga or \-xa option to estimate the its length. Alternatively, you can specify its value using the \-a
|
||||
option. The anacrusis is specified in half unit lengths, where the unit
|
||||
length is defined by the L: field. For example if L: 1/8, then a
|
||||
quarter note would be indicated by the value 4, (4 1/16 units).
|
||||
.SS OPTIONS
|
||||
.TP
|
||||
.B -a \fIacbeats\fP
|
||||
where acbeats specifies the anacrusis in half unit lengths.
|
||||
.TP
|
||||
.B -xa
|
||||
extract the anacrusis from file by finding the first strong note
|
||||
.TP
|
||||
.B -ga
|
||||
guess the anacrusis by minimizing the number of ties across bars
|
||||
.TP
|
||||
.B -m \fItime signature\fP
|
||||
time signature
|
||||
.TP
|
||||
.B -b \fIbars\fP
|
||||
number of bars wanted in output
|
||||
.TP
|
||||
.B -Q \fItempo\fP
|
||||
tempo in quarter\-notes per minute
|
||||
.TP
|
||||
.B -u \fipulses\fP
|
||||
Allows you to specify directly the number of midi pulses per
|
||||
abc time unit.
|
||||
.TP
|
||||
.B -ppu \fiparts per abc unit length\fP
|
||||
Normally, the smallest note unit that midi2abc can extract
|
||||
is half the L: unit length.This is called the quantum unit.
|
||||
Thus for L: 1/8, midi2abc can extract 1/16 notes but not 1/32 notes.
|
||||
You can change this by specifying \-ppu 4 for example. The number of parts
|
||||
should be a power of 2.
|
||||
.TP
|
||||
.B -aul \fidenominator of abc unit length\fP
|
||||
Normally midi2abc chooses a unit length of 1/8 or 1/16
|
||||
depending upon the time signature. For time signatures
|
||||
smaller than 3/4 the L: 1/16 is used and for larger time
|
||||
signatures L: 1/8 is used. You can specify the unit length
|
||||
to be used using this parameter. Thus \-aul 32 will cause
|
||||
midi2abc to use a unit length of 1/32 nd note.
|
||||
.TP
|
||||
.B -gu
|
||||
Tells midi2abc to estimate the number of midi pulses per abc
|
||||
time unit from the note duration or spacing in the MIDI file.
|
||||
.TP
|
||||
.B -gk
|
||||
Tells midi2abc to guess the key signature by minimizing
|
||||
the number of accidentals even if the key signature is
|
||||
already specified in the MIDI file. By default the key
|
||||
signature is the one specified in the MIDI file.
|
||||
If it is not specified, then the program guesses the
|
||||
key signature by minimizing accidentals.
|
||||
.TP
|
||||
.B -k \fIkey\fP
|
||||
key signature: \-6 to 6 sharps.
|
||||
.TP
|
||||
.B -c \fIchannel\fP
|
||||
select only this midi channel.
|
||||
.TP
|
||||
.B -f \fIinfile\fP
|
||||
input file in midi format
|
||||
.TP
|
||||
.B -o \fIoutput file\fP
|
||||
specifies the output abc file name.
|
||||
.TP
|
||||
.B -s
|
||||
do not discard very short notes.
|
||||
.TP
|
||||
.B -sr \fIquantum units\fP
|
||||
do not notate a short rest smaller than the specified size after a note. If the
|
||||
size (in quantum units) is zero, nothing is done. For larger values, the rest
|
||||
is absorbed into the preceding note. In other words, the preceding note
|
||||
is lengthened to include that rest.
|
||||
.TP
|
||||
.B -sum
|
||||
print a short summary of the input midi file.
|
||||
.TP
|
||||
.B -nb
|
||||
do not look for broken rhythms
|
||||
.TP
|
||||
.B -nt
|
||||
do not look for triplets
|
||||
.TP
|
||||
.B -obpl
|
||||
Print only one bar per line instead of 4. For complex music this
|
||||
improves the readability and avoids some problems with some abc
|
||||
to postscript converters. This option is deprecated.
|
||||
.TP
|
||||
.B -nogr
|
||||
(No note grouping.) Inserts a space between all notes. It makes
|
||||
a less pretty postscript file but it is easier to edit.
|
||||
.TP
|
||||
.B -bpl \finbars\fP
|
||||
Print nbars of music on every line followed by a backslash.
|
||||
.TP
|
||||
.B -bps \finbars\fP
|
||||
When nbars have been printed (including those lines joined by
|
||||
a backslash continuation) go to a new line (with no backslash).
|
||||
.TP
|
||||
.B -splitvoices
|
||||
This parameter handles polyphonic chords by
|
||||
splitting an entire voice into multiple voices. (A polyphonic
|
||||
chord is a chord composed of notes that do not start
|
||||
or end at the same time.) Normally, midi2abc joins the
|
||||
longer notes to the notes in the following chord using ties.
|
||||
Here is an example: [Bd-]d [Bd-]d|. This should
|
||||
be separated into two voices ideally Bz Bz and d2 d2. However,
|
||||
the separation is not unique. Bz d2 and d2 Bz are also ok.
|
||||
.TP
|
||||
.B -midigram
|
||||
When this option appears, all other options are ignored and
|
||||
no abc file is produced. Instead a list of all notes in the
|
||||
MIDI file are printed in a fixed format. Each line represents
|
||||
a pair of MIDI note on/off event. The line contains the
|
||||
on/off time of the note, its track number, channel number,
|
||||
midi pitch and midi velocity. The last record indicates
|
||||
the duration of the MIDI file in MIDI pulse units. The
|
||||
output is designed to go into a graphical user interface
|
||||
which will produce a graphical representation (piano roll).
|
||||
.TP
|
||||
.B -mftext
|
||||
When this option appears, all other options are ignored and
|
||||
no abc file is produced. Instead a list of all the MIDI
|
||||
commands are printed. The output is designed to go into
|
||||
a graphical user interface provided by runabc.tcl.
|
||||
.TP
|
||||
.B -mftextpulses
|
||||
Same as -mftext except the time units is in midi pulses.
|
||||
.TP
|
||||
.B -title \fistring\fP
|
||||
Replaces the default title field following T: with
|
||||
the given string.
|
||||
.TP
|
||||
.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
|
||||
* The key is chosen so as to minimize the number of accidentals.
|
||||
Alternatively, the user can specify the key numerically (a positive number
|
||||
is the number of sharps, a negative number is minus the number of flats).
|
||||
.PP
|
||||
* Note length can be set by specifying the total number of bars or the
|
||||
tempo of the piece. Alternatively the note length can be read from the file.
|
||||
However, by default it is deduced in a heuristic manner from the inter-note
|
||||
distances. This means that you do not have to use the MIDI clock as a
|
||||
metronome when playing in a tune from a keyboard.
|
||||
.PP
|
||||
* Barlines are automatically inserted. The user specifies the number of
|
||||
measures in the anacrusis before the first barline and the time signature.
|
||||
.PP
|
||||
* The program can guess how the length of the anacrusis,
|
||||
either by looking for the first strong note or minimizing the number of
|
||||
notes split by a tie across a barline.
|
||||
.PP
|
||||
* Where a note extends beyond a bar break, it is split into two tied notes.
|
||||
.PP
|
||||
* The output has 4 bars per line.
|
||||
.PP
|
||||
* Enough accidental signs are put in the music to ensure that no pitch
|
||||
errors occur if a barline is added or deleted.
|
||||
.PP
|
||||
* The program attempts to group notes sensibly in each bar.
|
||||
.PP
|
||||
* Triplets and broken rhythm (a>b) are supported.
|
||||
.PP
|
||||
* Chords are identified.
|
||||
.PP
|
||||
* Text information from the original MIDI file is included as comments.
|
||||
.PP
|
||||
* The \-c option can be used to select only 1 MIDI channel. Events on
|
||||
other channels are ignored.
|
||||
.SS LIMITATIONS
|
||||
midi2abc does not ...
|
||||
.PP
|
||||
* Supply tune title, composer or any other field apart from X: , K:, Q:, M:
|
||||
and L: - these must be added by hand afterwards, though they may have been
|
||||
included in the text of the MIDI file.
|
||||
.PP
|
||||
* Support duplets, quadruplets, other esoteric features.
|
||||
.PP
|
||||
* Support mid-tune key or time signature changes.
|
||||
.PP
|
||||
* Deduce repeats. The output is just the notes in the input file.
|
||||
.PP
|
||||
* Recover an abc tune as supplied to abc2midi. However, if you want to
|
||||
do this, "midi2abc \-xa \-f file.mid" comes close.
|
||||
.SH "SEE ALSO"
|
||||
abc2ps(1), abc2midi(1), abc2abc(1)
|
||||
.SH AUTHOR
|
||||
James Allwright <J.R.Allwright@westminster.ac.uk>
|
||||
.SH SUPPORTED
|
||||
Seymour Shlien <fy733@ncf.ca>
|
||||
.SH VERSION
|
||||
This man page describes midi2abc version 2.91 from March 09 2008.
|
||||
.SH COPYRIGHT
|
||||
Copyright 1999 James Allwright
|
||||
.PP
|
||||
midi2abc does not work correctly if lyrics are embedded in
|
||||
the same track as the notes. If you are producing the MIDI
|
||||
file using abc2midi, use the \-STFW option to ensure that the
|
||||
lyrics are put in a separate track.
|
||||
.PP
|
||||
midi2abc is supplied "as is" without any warranty. It
|
||||
is free software and can be used, copied, modified and
|
||||
distributed without fee under the terms of the GNU General
|
||||
Public License.
|
||||
|
||||
157
doc/midicopy.1
Normal file
157
doc/midicopy.1
Normal file
@@ -0,0 +1,157 @@
|
||||
.TH MIDICOPY 1
|
||||
.SH NAME
|
||||
midicopy \- Copy selected track, channel, time interval of a MIDI file to another MIDI file
|
||||
.SH SYNOPSIS
|
||||
\fBmidicopy\fP [\fB-ver\fP] [\fB-trks\fP \fIn1,n2,..\fP]\
|
||||
[\fB-xtrks\fP \fIn1,n2,..\fP]\
|
||||
[\fB-xchns\fP \fIn1,n2,..\fP]\
|
||||
[\fB-chans\fP \fIn1,n2,...\fP]\
|
||||
[\fB-from\fP \fIn (in midi ticks)\fP] [\fB-to\fP \fIn (in midi ticks)\fP]\
|
||||
[\fB-fromsec %f\fP \fIn (in seconds)\fP] [\fB-tosec\fP \fIn (in seconds)\fP]\
|
||||
[\fB-frombeat %f\fP \fIn (in beats)\fP] [\fB-tobeat\fP \fIn (in beats)\fP]\
|
||||
[\fB-replace\fP \fItrk,loc,val\fP] [\fB-tempo %n\fP] [\fB-speed %f\fP]\
|
||||
[\fB-drumfocus\fP \fIn \fIm\fP] [\fB-mutenodrum [%d]\fP]\
|
||||
[\fB-setdrumloudness\fP \fIn \fIm\fP]\
|
||||
[\fB-focusontrack\fP \fIn1,n2,... (from 1)\fP]\
|
||||
[\fB-focusonchannel\fP \fIn1,n2,... (from 1)\fP]\
|
||||
[\fB-attenuation\fP \fIn\fP]\
|
||||
[\fB-nobends\fP]\
|
||||
[\fB-indrums\fP \fIn1,n2,...\fP]\
|
||||
[\fB-xdrums\fP \fIn1,n2,...\fP]\
|
||||
[\fB-onlydrums\fP]\
|
||||
[\fB-nodrums\fP]\
|
||||
\fIinput.mid output.mid\fP
|
||||
.SH "DESCRIPTION"
|
||||
.PP
|
||||
.B midicopy
|
||||
is used to copy part of a MIDI file to another MIDI file. You can select
|
||||
a particular time interval, particular channels, and particular tracks
|
||||
or any combinations. If one or both of the run time parameters \-from or \-to
|
||||
are included, the program returns the playing time in seconds of the
|
||||
output file. Midicopy was developed by Seymour Shlien from the
|
||||
midifilelib distribution available from
|
||||
.IR http://www.harmony-central.com/MIDI/midifilelib.tar.gz .
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -ver
|
||||
prints version number and then exits
|
||||
.TP
|
||||
.B -trks n1,n2, etc
|
||||
Selects the tracks to be copied where the track numbers start
|
||||
from 1. If more than one track is specified, they should be separated by
|
||||
commas. You should always copy track 1 since by convention it contains
|
||||
information pertinent to all the other tracks. By default all tracks
|
||||
are copied unless you specify particular tracks using this run time
|
||||
parameter.
|
||||
.TP
|
||||
.B -xtrks n1,n2, etc
|
||||
Lists the tracks to exclude from copying. All other tracks are copied.
|
||||
This option does not work in combination with \-trks.
|
||||
.TP
|
||||
.B -xchns n1,n2, etc
|
||||
Lists the channels to exclude from copying. All other channels are copied.
|
||||
This option does not work in combination with \-chns.
|
||||
.TP
|
||||
.B -chns n
|
||||
Like above, it specifies the MIDI channels to be copied. By default
|
||||
all channels are copied. Channel numbers also start from 1.
|
||||
.TP
|
||||
.B -from n
|
||||
The program will copy all MIDI commands starting from midi pulse
|
||||
number n. By default it will start from time zero or the beginning
|
||||
of the MIDI file.
|
||||
.TP
|
||||
.B -to n
|
||||
Stops copying all events after midi pulse number n. By default
|
||||
the file is copied to the end.
|
||||
.TP
|
||||
.B -frombeat n
|
||||
The program will copy all MIDI commands starting from quarter beat
|
||||
number n. By default it will start from time zero or the beginning
|
||||
of the MIDI file.
|
||||
.TP
|
||||
.B -tobeat n
|
||||
Stops copying all events after quarter beat number n. By default
|
||||
the file is copied to the end.
|
||||
.TP
|
||||
.B -fromsec n
|
||||
The program will copy all MIDI commands starting from time n
|
||||
in seconds.
|
||||
.TP
|
||||
.B -tosec n
|
||||
Stops copying all events after time n in seconds. These two
|
||||
options (\-fromsec and \-tosec) do not work accurately if the
|
||||
MIDI file has more than one tempo command. Only the first
|
||||
one is used for converting seconds into MIDI pulse units.
|
||||
It is therefore preferable to use the \-from and \-to options.
|
||||
.TP
|
||||
.B -replace trk,loc,val
|
||||
This option should be used alone. Midicopy will copy the entire
|
||||
file verbatim except it will replace a byte by val, where the
|
||||
byte is located in the specified track (trk) and specified position
|
||||
(loc). Commonly this function is used for changing a particular
|
||||
MIDI program number (instrument) associated with a channel.
|
||||
You need to know the byte count in the track of that parameter
|
||||
in order to use this function,
|
||||
.TP
|
||||
.B -tempo quarter notes/minute
|
||||
All tempo indications in the midi file will be replaced with
|
||||
the above value.
|
||||
.TP
|
||||
.B -speed factor
|
||||
All tempo indications in the midi file will be multiplied with
|
||||
this factor. Values greater than 1.0 will speed up the music while
|
||||
lower values slow the music. The factor is a floating point value.
|
||||
.TP
|
||||
.B -drumfocus drum-code excluded_drum_velocities
|
||||
The selected drum line (specified by the drum-code pitch value) is
|
||||
highlighted by reducing the loudness of all other drum lines to
|
||||
the excluded_drum_velocities value. The drum-code value must
|
||||
be in the range of 35 to 81 inclusive.
|
||||
.TP
|
||||
.B -mutenodrum [level]
|
||||
All channels which are not 9 (drum channel) are attenuated to the
|
||||
given level. If level is not specified, it is assumed to be zero.
|
||||
.TP
|
||||
.B -setdrumloudness n m
|
||||
where n is between 35 to 81 inclusive and m is the loudness between
|
||||
0 and 127. The loudness of all instances of drum n are changed
|
||||
to m.
|
||||
.TP
|
||||
.B -focusontrack n1,n2,...
|
||||
The velocities of notes in all tracks except n are attenuated.
|
||||
.TP
|
||||
.B -focusonchannel n1,n2,...
|
||||
The velocities of notes in all channels except n are attenuated.
|
||||
.TP
|
||||
.B -attenuation n
|
||||
Specifies the amount the note velocities are reduced by either
|
||||
-focusontracks or -focusonchannels. Current default is 70.
|
||||
.TP
|
||||
.B -nobends
|
||||
Suppresses all channel pitchbend commands.
|
||||
.TP
|
||||
.B -indrums n1,n2,...
|
||||
Only allow percussions with codes n1,n2,...
|
||||
.TP
|
||||
.B -xdrums n1,n2,...
|
||||
Exclude the percussions with codes n1,n2,...
|
||||
.TP
|
||||
.B -onlydrums
|
||||
Only copy the percussion channel.
|
||||
.TP
|
||||
.B -nodrums
|
||||
Copy all channels except the percussion channel.
|
||||
|
||||
.SH EXAMPLE
|
||||
.B midicopy.exe -trks 1,5 -from 2669 -to 8634 uzicko.mid fragment.mid
|
||||
Midicopy will copy tracks 1 and 5 starting from midi pulse position
|
||||
2669 and ending at MIDI pulse position 8634.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.PP
|
||||
.IR abcmtex "(1), " abc2abc "(1), " abc2midi "(1), " midi2abc "(1) ", yaps "(1)"
|
||||
.SH AUTHOR
|
||||
This manual page was written by Seymour Shlien.
|
||||
.SH VERSION
|
||||
This man page describes midicopy version 1.33 from December 22 2019.
|
||||
420
doc/programming/abc2midi.txt
Normal file
420
doc/programming/abc2midi.txt
Normal file
@@ -0,0 +1,420 @@
|
||||
Some Notes on the abc2midi Code
|
||||
-------------------------------
|
||||
written by Seymour Shlien
|
||||
|
||||
|
||||
Abc2midi.txt - last updated 29 November 1999.
|
||||
|
||||
|
||||
This file provides an algorithmic description of the program
|
||||
abc2midi which converts an abc file into a midi file.
|
||||
|
||||
The sources of abc2midi now comprising of 6700 lines of C code are
|
||||
contained in the following five files.
|
||||
|
||||
parseabc.c is the front end which scans the abc file and invokes
|
||||
the appropriate event handler for each element it encounters
|
||||
(eg. bar lines, notes, chords etc.) It happens to be the
|
||||
front end for other programs such as abc2ps, yaps and
|
||||
abc2abc.
|
||||
store.c contains all the event handlers which are invoked from
|
||||
parseabc. It converts the abc file into an internal
|
||||
representation described later in this file.
|
||||
genmidi.c converts this internal representation in an output midi
|
||||
file.
|
||||
queues.c are some utilities needed by genmidi.
|
||||
midifile.c is a library of public domain routines to read and write
|
||||
midifiles.
|
||||
|
||||
In order to handle the multiple voices, parts, repeats and accompaniments
|
||||
which occur in abc files, the program performs multiple passes. The
|
||||
midi file stores the different voices, accompaniment and lyrics in
|
||||
individual tracks, so it is necessary to separates these parts prior
|
||||
to writing it to the midi file. If there are repeats in the music,
|
||||
something which appears only once in the abc file may be invoked twice
|
||||
when creating the output midi file.
|
||||
|
||||
Parseabc.c
|
||||
----------
|
||||
|
||||
The parser has been written so that it should be possible to write
|
||||
your own utility to handle the interpreted abc and link it with
|
||||
the parser code. This is very similar to the way that the midifilelib
|
||||
utilities work. The parser is designed so that it can write out
|
||||
almost exactly what it reads in. This means that in some cases
|
||||
the level of parsing is fairly primitive and it may be necessary to make
|
||||
use of routines in store.c which perform further processing on an item.
|
||||
|
||||
In the first phase of parsing, the abc file is read and when, say, a note
|
||||
is encountered, the routine event_note() is called. The code for event_note
|
||||
is in the file store.c. Encountering an X in the abc generally causes a
|
||||
routine called event_X() to be called. An internal representation of the tune
|
||||
is built up and when the end of an abc tune is reached, a little bit of
|
||||
processing is done on the internal representation before the routine
|
||||
mywritetrack() is called to actually write out the MIDI file.
|
||||
|
||||
The main program to abc2midi is contained in this file. Since this
|
||||
main program is used to start other programs such as yaps, it is
|
||||
fairly simple. It calls event_init defined in store.c which obtains
|
||||
all the user parameters (eg. input filename) and then executes the
|
||||
top level procedure, parsefile.
|
||||
|
||||
The procedure parsefile (filename), opens the specified file (or stdin)
|
||||
and processes it one character at a time. The characters fill a line
|
||||
buffer which is passed to the procedure parseline whenever a linebreak
|
||||
character (eg. linefeed) is encountered. By doing it in this fashion,
|
||||
abc2midi is able to eliminate the extra carriage return which occurs
|
||||
in DOS files.
|
||||
|
||||
The procedure parseline first checks for blank lines and comments. A
|
||||
blank line signals the end of the tune and the event_blankline is called
|
||||
to initiate the next stage in processing. If it is neither a comment or
|
||||
blank line, the procedure must decide whether the line is a a field line
|
||||
(eg."X:2") or part of a music body (eg. "|:C>DGz|..."). This is decided
|
||||
using the following rule. If the first letter begins with one of the field
|
||||
letter commands and is immediately followed by a ":", then it is treated
|
||||
as a field line and parsefield is called. Otherwise if a K: field line
|
||||
was already encountered (variable inbody set to 1), then it is treated
|
||||
as a line of music. If neither case is satisfied, then the line is
|
||||
intepreted as plain text.
|
||||
|
||||
The procedure parsefield identifies the particular field line type
|
||||
and invokes the appropriate support function or event handler. If the
|
||||
field command occurs after the first K: line, then only certain field
|
||||
lines are legal. (For example it is illegal to place a T: (title) line
|
||||
after the K: (key signature) line.)
|
||||
|
||||
The procedure parsemusic is the most complex procedure in the file and
|
||||
recognizes the musical notes, chords, guitar chord names, bar lines,
|
||||
repeats, slurs, ties, graces etc. Appropriate event handlers and
|
||||
support functions are called to complete the tasks of parsing the
|
||||
information. The parsenote function, for example, must check for
|
||||
decorations, accidentals, octave shifts as well as identifying the
|
||||
note and its determining its duration.
|
||||
|
||||
Unlike the other software modules, parseabc.c contains few global
|
||||
variables. The global variables linenum, inhead, inbody, parsing,
|
||||
slur, parserinchord indicate which lexical component of the abc
|
||||
tune is being processed.
|
||||
|
||||
|
||||
|
||||
|
||||
store.c
|
||||
-------
|
||||
|
||||
This is the most complex module consisting of almost 3000 lines
|
||||
of source code. This module contains all of the event handlers which
|
||||
may be invoked in the file parseabc.c. The main purpose of these
|
||||
handlers are to build up an internal representation of the abc file
|
||||
in the global memory arrays. This is a complete representation
|
||||
which allows the regeneration of the abc file (eg. abc2abc) or
|
||||
the creation of a midi file. The internal representation is used
|
||||
by the genmidi.c software to create the midi file.
|
||||
|
||||
|
||||
Global variables
|
||||
|
||||
The internal representation is stored in global variables defined
|
||||
at the beginning of the file. A description of the most important
|
||||
variables is given here.
|
||||
|
||||
The music is stored in the four arrays, feature, pitch, num, denom.
|
||||
These arrays contains a list of the lexical components in the order
|
||||
that they have been encountered or created.
|
||||
|
||||
The array "feature" identifies the type of component which can be one
|
||||
of the following enum features.
|
||||
|
||||
SINGLE_BAR, DOUBLE_BAR, BAR_REP, REP_BAR, REP1, REP2, BAR1,
|
||||
REP_BAR2, DOUBLE_REP, THICK_THIN, THIN_THICK, PART, TEMPO,
|
||||
TIME, KEY, REST, TUPLE, NOTE, NONOTE, OLDTIE, TEXT, SLUR_ON,
|
||||
SLUR_OFF, TIE, TITLE, CHANNEL, TRANSPOSE, RTRANSPOSE, GRACEON,
|
||||
GRACEOFF, SETGRACE, SETC, GCHORD, GCHORDON, GCHORDOFF, VOICE,
|
||||
CHORDON, CHORDOFF, SLUR_TIE, TNOTE, LT, GT, DYNAMIC, LINENUM,
|
||||
MUSICLINE, MUSICSTOP, WORDLINE, WORDSTOP
|
||||
|
||||
The array pitch[] mainly stores the pitch of a musical note,
|
||||
represented in the same manner as in a midi file. Thus middle
|
||||
C has a value of 60. The array has other uses, for example
|
||||
in a LINENUM feature it stores the line number relative to
|
||||
the X: reference command where the lexical feature has been
|
||||
detected. The LINENUM feature is useful when reporting warnings
|
||||
or errors in the input file. Duration of the notes are represented
|
||||
as a fraction, where the standard unit is defined by the L:
|
||||
command. If feature[n] is a NOTE, then num[n] and denom[n]
|
||||
contain the numerator and denominator of this fraction.
|
||||
|
||||
Here is an example of the contents of these arrays for the
|
||||
following small file in the same order that they are stored in
|
||||
these arrays.
|
||||
|
||||
X: 1
|
||||
T: sample
|
||||
M: 2/4
|
||||
L: 1/8
|
||||
K: G
|
||||
|: C>D[EF]G |C4:|
|
||||
|
||||
|
||||
Feature Pitch Num Denom
|
||||
LINENUM 2 0 0
|
||||
TITLE 0 0 0
|
||||
LINENUM 3 0 0
|
||||
LINENUM 4 0 0
|
||||
LINENUM 5 0 0
|
||||
DOUBLE_BAR 0 0 0
|
||||
LINENUM 6 0 0
|
||||
MUSICLINE 0 0 0
|
||||
BAR_REP 0 0 0
|
||||
NOTE 60 2 3
|
||||
NOTE 62 1 3
|
||||
CHORDON 0 0 0
|
||||
NOTE 64 1 2
|
||||
NOTE 66 1 2
|
||||
CHORDOFF 0 1 2
|
||||
NOTE 67 1 2
|
||||
SINGLE_BAR 0 0 0
|
||||
NOTE 60 2 1
|
||||
REP_BAR 0 0 0
|
||||
MUSIC_STOP 0 0 0
|
||||
LINENUM 7 0 0
|
||||
|
||||
|
||||
In order to support multivoice abc files in the form
|
||||
V:1
|
||||
| ...| ...|....
|
||||
V:2
|
||||
| ...| ...|....
|
||||
%
|
||||
V:1
|
||||
| ...| ...|....
|
||||
V:2
|
||||
| ...| ...|....
|
||||
etc.
|
||||
|
||||
abc2midi maintains a voicecontext structure for each voice.
|
||||
This allows each voice to define its own key signature, default
|
||||
note length using internal field commands. There is a head
|
||||
voicecontext which is used when no voice field commands are
|
||||
defined in the abc file. The v[] array maintains a set of
|
||||
all voices active in the abc file and voicecount keeps track
|
||||
of the number of voices.
|
||||
|
||||
Similarly, abcmidi maintains a list of all the part stored
|
||||
in the feature[], pitch[], num[] and denom[] arrays.
|
||||
|
||||
All text items (eg. title and some other fields) are stored
|
||||
in char atext[][] arrays, so that they can be included in
|
||||
the midi output file. The textual information is repeated
|
||||
in each track of the output midi file.
|
||||
|
||||
Following the conventions in the midi file, the program uses
|
||||
the quarter note as the standard unit of time instead of the
|
||||
whole note. In contrast, the standard length in the abc file
|
||||
is based on the whole note. For example in L:1/8, the fraction
|
||||
refers to a whole note. In order to convert time units to
|
||||
quarter notes, the numerator of the time specifications
|
||||
for note lengths is multiplied by 4 when it is added to
|
||||
the feature list.
|
||||
|
||||
Table of contents of procedures in store.c
|
||||
|
||||
getarg(option, argc, argv) - gets run time arguments.
|
||||
newvoice(n) - creates a new voice context.
|
||||
getvoicecontext() - finds or makes a voice context.
|
||||
clearvoicecontexts() - frees up the memory of the voice context
|
||||
|
||||
event_init() - called by main program
|
||||
event_text(s) - called when a line of text is encountered.
|
||||
event_reserved(p) - handles reserved character codes H-Z.
|
||||
event_tex(s) - called whenever a TeX command is encountered.
|
||||
event_linebreak() - called whenever a newline character is encountered.
|
||||
event_startmusicline() - called for each new music line.
|
||||
event_endmusicline() - called at the end of each music line.
|
||||
event_eof() - end of abc file encountered.
|
||||
event_fatal_error(s) - reports fatal error.
|
||||
event_error(s) - reports an error.
|
||||
event_warning(s) - reports a potential problem.
|
||||
event_comment(s) - called whenever a comment is encountered.
|
||||
event_specific(package, s) - recognizes %%package s.
|
||||
event_startinline() - beginning of an in-music field command.
|
||||
event_closeinline() - finishes an in-music field command.
|
||||
event_field(k,f) - for R:, T: and any other unprocessed field commands.
|
||||
event_words(p) - processes a w: field command.
|
||||
|
||||
char_out(list,out,ch) - for building up a parts list in a P: command.
|
||||
read_spec() - converts P:A(AB)3 to P:AABABAB etc.
|
||||
event_part(s) - handles a P: field.
|
||||
|
||||
char_break() - reports error for improper voice change.
|
||||
event_voice(n,s) - processes a V: field.
|
||||
event_length(n) - recognizes L: field
|
||||
event_blankline - starts finishfile() procedure.
|
||||
event_refno(n) - recognizes X:
|
||||
event_tempo(n, a, b, rel) - recognizes Q:
|
||||
event_timesig(n, m) - recognizes M:
|
||||
event_key(sharps, s, minor, modmap, modmul) - recognizes K:
|
||||
event_graceon() - start of grace notes, "{" encountered.
|
||||
event_graceoff() - end of grace notes, "}" encountered.
|
||||
event_rep1() - handles first repeat indicated by [1.
|
||||
event_rep2() - handles second repeat indicated by [2.
|
||||
event_slur(t) -called when s encountered in abc.
|
||||
event_sluron(t) called when "(" is encountered in abc.
|
||||
event_sluroff(t) called when ")" is encountered in abc.
|
||||
slurtotie() - converts slur into tied notes.
|
||||
event_tie() - handles tie indication "-".
|
||||
event_rest(n,m) - processes rest indication Z or z.
|
||||
event_bar(type) - processes various types of bar lines.
|
||||
event_space() - space character encountered. Ignored here.
|
||||
event_linend(ch,n) - handles line continuation at end of line (eg. \).
|
||||
event_broken(type, mult) - handles >, <, >> etc. in abc.
|
||||
event_tuple(n,q,r) - handles triplets and general tuplets.
|
||||
event_chord() - called whenever + is encountered.
|
||||
marknotestart() - remembers last few notes in voice context.
|
||||
marknoteend() - this is used to process broken rhythms (eg. >).
|
||||
marknote() - called for single note (as opposed to chord).
|
||||
event_chordon() - called whenever [ is encountered.
|
||||
event_chordoff() - called whenever ] is encountered.
|
||||
splitstring(s,sep,handler) - splits string with separator sep.
|
||||
event_instuction(s) - handles !...! event.
|
||||
getchordnumber(s) - searches known chords for chord s.
|
||||
addchordname(s, len, notes) - adds chord name to known chord list.
|
||||
event_gchord(s) - handles guitar chords.
|
||||
event_handle_gchord(s) - handler for guitar chords.
|
||||
event_handle_instruction(s) - handles dynamic indications (eg. !ppp!).
|
||||
event_finger(p) - handles 1,2,...5 in guitar chord field (does nothing).
|
||||
hornp(num,denom) - modifies rhythm to hornpipe.
|
||||
event_note(roll, staccato, updown, accidental, mult, note, octave, n, m)
|
||||
doroll(note,octave,n,m,pitch) - applies roll to note.
|
||||
dotrill(note,octave,n,m,pitch) - applies trill to note.
|
||||
pitchof(note,accidental,mult,octave) -finds MIDI pitch value
|
||||
setmap(sf,map,mult) - converts key signature to accidental map.
|
||||
altermap(v,modmap,modmul) - modifies accidental map.
|
||||
copymap(v) - sets up working accidental map at beginning of bar.
|
||||
|
||||
addfeature(f,p,n,d) - places feature in internal tables.
|
||||
autoextend(maxnotes) - increase memory limits for feature arrays.
|
||||
textextend(maxstrings, stringarray) - resize array pointers to strings.
|
||||
myputc(c) - workaround for problems with PCC compiler.
|
||||
tiefix() - connect up tied notes.
|
||||
dotie(j,xinchord) - called in preprocessing stage to handle ties.
|
||||
addfrac(xnum,xdenom,a,b) - add a/b to the number of units in bar.
|
||||
applybroken(place, type, n) - adjust length of broken notes.
|
||||
brokenadjust() -adjust length of broken notes.
|
||||
applygrace() - assign lengths to grace notes.
|
||||
dograce() - assign lengths to grace notes.
|
||||
lenmul(n, a, b) - multiply num(n),denom(n) by a/b.
|
||||
zerobar() - start a new count of beats in the bar.
|
||||
delendrep() - remove bogus repeat.
|
||||
placeendrep(j) - patch up missing repeat.
|
||||
placestartrep(j) - patch up missing repeat.
|
||||
fixreps() - find and correct missing repeats in music.
|
||||
startfile() - initialization performed after an event_refno.
|
||||
tempounits(t_num, t_denom) - interprets Q: field.
|
||||
setbeat() - sets default gchord command for time signature.
|
||||
headerprocess() - called after the first K: field in tune.
|
||||
finishfile() - starts next stage of processing when end of tune
|
||||
is encountered.
|
||||
|
||||
All the functions in this file respond to event calls from parseabc.
|
||||
Once the internal representation of the abc file is completed, the
|
||||
procedure finishfile is called to perform some clean up and create
|
||||
the midi file. An internal representation of the midi file is
|
||||
first created and then it is written onto the designated output file.
|
||||
As finishfile provides the link to the next module, genmidi.c, here
|
||||
is a brief description of what it does.
|
||||
|
||||
proc finishfile performs several passes through the internal
|
||||
representation to clean up the graces (dograce), the tied notes
|
||||
(tiefix) and any unbalanced repeats. It then calls writetrack(i)
|
||||
for each midi track to create the internal midi representation
|
||||
and finally the midi representation is recorded in the output
|
||||
file.
|
||||
|
||||
|
||||
|
||||
genmidi.c
|
||||
---------
|
||||
The procedure finishfile described above, creates each midi track
|
||||
by calling the function writetrack which is defined here. To create
|
||||
a track from the internal representation, the program must find all
|
||||
the parts and put them in order with all the repeats. In addition, if
|
||||
it contains karaoke text, this too must be placed in a separate track.
|
||||
Any chordal accompaniment is generated from the guitar chord indications
|
||||
and placed in another track. For multivoice and multipart music, a voice
|
||||
may be missing in a particular part. If the voice is missing, the
|
||||
procedure fillvoice ensures that all voices remain properly aligned when
|
||||
the voice reappears in another part.
|
||||
|
||||
Here is a simple road map to the important procedures included in this
|
||||
file.
|
||||
|
||||
dodeferred is here used to handle any dynamic indications (eg. !ppp!)
|
||||
which may be contained in the file. The %%MIDI messages are stored
|
||||
in a atext string which is pointed to by the contents of the pitch[]
|
||||
array.
|
||||
|
||||
checkbar is called each time a bar line is encountered and reports
|
||||
a warning if the wrong number of beats occur.
|
||||
|
||||
Transitions between parts are handled by the procedure partbreak.
|
||||
|
||||
There are a number of procedures for handling karoake text --
|
||||
karaokestarttrack(), findwline(startline), getword(place,w),
|
||||
write_syllable(place) and checksyllables().
|
||||
|
||||
For the first track, the meter, tempo and key signature are recorded
|
||||
using the functions set_meter(n,m), write_meter(n,m), write_keysig(sf,mi).
|
||||
|
||||
Chordal accompaniment is produced by the procedure dogchords(i).
|
||||
|
||||
|
||||
|
||||
queues.c
|
||||
--------
|
||||
|
||||
For each midi note, it is necessary to send a note-on and a note-off
|
||||
instruction. When polyphonic music is played on the same track, keeping
|
||||
track of the time to issue a note-off instruction may get complicated.
|
||||
The procedures in this file are used to maintain a linked list for the
|
||||
notes to be turned off. The notes are put into the list in the order
|
||||
that they are encountered but the order in which to issue note-off
|
||||
commands is maintained by the links. As many as 50 notes playing
|
||||
simultaneously can be handled by the list.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Addendum
|
||||
--------
|
||||
|
||||
The following section contains clarifications on various components
|
||||
of abc2midi.
|
||||
|
||||
29 June 2003
|
||||
|
||||
Treatment of octave shifts.
|
||||
|
||||
The key signature field command K: has provision for shifting
|
||||
a note using either transpose= or octave= subcommands. Both
|
||||
of these functions operate quite differently and deserve some
|
||||
description especially for multivoiced tunes.
|
||||
|
||||
The octave shift, is performed in event_note in store.c, using
|
||||
the cached value v.octaveshift which is stored in the global
|
||||
voicecontext structure, v. There is a structure for each voice
|
||||
in the abc file. Whenever a new V: command is encountered,
|
||||
event_voice (store.c) is invoked, which swaps the appropriate
|
||||
voices structure into the global v array using the function
|
||||
getvoicecontext(n). If getvoicecontext cannot find a cached
|
||||
structure for that voice, then a new voice structure is created
|
||||
and added to the linked list of voice structures. The v.octaveshift
|
||||
variable is updated by event_octave which is called by event_key
|
||||
(store.c) which is called by parsekey in parseabc.c
|
||||
(Comment: it is not too clear how an octave switch is
|
||||
handled in the middle of a repeat section. i.e. does the old
|
||||
value get restored when repeating.)
|
||||
|
||||
(Description of transpose shift is in CHANGES July 1 2003.)
|
||||
426
doc/programming/coding.txt
Normal file
426
doc/programming/coding.txt
Normal file
@@ -0,0 +1,426 @@
|
||||
Notes on the code
|
||||
-----------------
|
||||
|
||||
These notes are for anyone who wants to re-compile, re-write or re-use
|
||||
bits of the code. Additional information is available by downloading
|
||||
the file abcextra.zip. This includes :
|
||||
|
||||
* man pages for abc2midi and midi2abc.
|
||||
* A detailed description of the inner workings of abc2midi, written by
|
||||
Seymour Shlien.
|
||||
|
||||
Compilation
|
||||
-----------
|
||||
|
||||
The file midifile.c and the header file midifile.h are slightly changed from
|
||||
the midifilelib distribution. To see the program dependencies, examine the
|
||||
Makefile.
|
||||
|
||||
The code is written in K&R style C and should be fairly easy to compile
|
||||
on any system with a C compiler and a make utility. Makefiles are
|
||||
provided for gcc/unix, DJGPP/DOS and PCC/DOS. There are also some notes
|
||||
on using the GUI front-end to Pacific C/DOS. You may get warning
|
||||
messages if your compiler prefers ANSI C style function prototypes.
|
||||
|
||||
Choose the most suitable makefile; unix.mak, djgpp.mak or pcc.mak and
|
||||
rename it as 'makefile'. If you are not using any of the above compilers,
|
||||
you may have to edit the makefile so that it uses compilation flags
|
||||
suitable for your compiler.
|
||||
|
||||
To compile the code, type
|
||||
|
||||
make all
|
||||
|
||||
If the complete compilation does not work, you can try compiling the
|
||||
individual programs separately :
|
||||
|
||||
make midi2abc (or make midi2abc.exe)
|
||||
make abc2midi (or make abc2midi.exe)
|
||||
make abc2abc (or make abc2abc.exe)
|
||||
make mftext (or make mftext.exe)
|
||||
make yaps (or make yaps.exe)
|
||||
|
||||
Note that the make utility on some systems (e.g. GNU make) may require the
|
||||
Makefile to be a unix text file and not a DOS text file. The difference
|
||||
is that unix uses newline to mark the end of each line while DOS uses
|
||||
carriage return and newline.
|
||||
|
||||
Note, if you have difficulty compiling the package because you do not have
|
||||
snprintf see the note in doc/CHANGES dated January 08 2005 (and also
|
||||
December 17 2004).
|
||||
|
||||
|
||||
---------------------------------------------------------------------
|
||||
Calling abc2midi or midi2abc from a GUI.
|
||||
----------------------------------------
|
||||
|
||||
The programs should now have an exit value of 0 for normal termination
|
||||
and 1 for an error state. However, abc2midi will still exit with 0 if
|
||||
it finds non-fatal errors in the code, so the user should always have
|
||||
the option of looking at the program's text output (I don't want to
|
||||
get blamed when useful diagnostic output turns into the ubiquitous
|
||||
'OK' click-button).
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Man pages
|
||||
---------
|
||||
Files: abc2midi.1 and midi2abc.1
|
||||
|
||||
Christoph Dalitz has written some man pages for abc2midi and
|
||||
midi2abc. These should be installed in the sub-directory /man1
|
||||
of the directory given by the MANPATH environment variable.
|
||||
(The man command is usually only found on Unix variants).
|
||||
|
||||
The source distribution has been re-organized to contain only the
|
||||
source and a few text files. If you want these man pages, you need
|
||||
to download the file abcextra.zip.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
Code Layout and Indentation style
|
||||
---------------------------------
|
||||
If you want to add your own code and make it fit in with the existing
|
||||
coding style, you can use GNU indent. The following is a DOS batch file
|
||||
to invoke indent with the appropriate options.
|
||||
|
||||
indent -bad -bap -br -ce -cli0 -npcs -di1 -nbc -i2 -ts0 -psl -lp -ipo %1
|
||||
rem
|
||||
rem options for GNU indent to achieve my personal style
|
||||
rem
|
||||
rem -bad blank line after declaration block
|
||||
rem -bap blank line after procedure body
|
||||
rem -br brace on same line after if, struct and enum
|
||||
rem -ce cuddle else
|
||||
rem -cli0 case at same identation as switch
|
||||
rem -npcs no space between procedure name and following open bracket
|
||||
rem -di1 one space between variable type and variable name
|
||||
rem -nbc comma-separated variables on the same line
|
||||
rem -i2 indent 2 spaces
|
||||
rem -ts0 no tabs
|
||||
rem -npsl function type on same line as function name
|
||||
rem -lp continuations matched to left parenthesis
|
||||
rem -ip0 no indention of variables in K&R function headers
|
||||
rem -ncs no space after cast
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
Extensions to the abc Format
|
||||
----------------------------
|
||||
|
||||
1. The parser recognizes
|
||||
%%package <string>
|
||||
as some package-specific command and calls event_specific with the
|
||||
package name and the string that follows it.
|
||||
|
||||
2. The abc standard defines notation for 4 octaves :
|
||||
|
||||
C, - B,
|
||||
C - B
|
||||
c - b
|
||||
c' - b'
|
||||
|
||||
The parser recognizes each additional comma as meaning "going down
|
||||
an extra octave", giving
|
||||
|
||||
C,, - B,,
|
||||
C,,, - B,,,
|
||||
and so on.
|
||||
|
||||
Likewise, each additional prime symbols s interpreted as "go up an extra
|
||||
octave" :
|
||||
|
||||
c'' - b''
|
||||
c''' - b'''
|
||||
and so on.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
abc2midi
|
||||
--------
|
||||
abc2midi consists of the following C source files:
|
||||
|
||||
parseabc.c - parses the input text and calls a routine for
|
||||
every parsed element encountered.
|
||||
parser2.c - performs some additional parsing that may not be
|
||||
required.
|
||||
store.c - builds an internal representation of the abc tune.
|
||||
genmidi.c - uses the internal representation to generate
|
||||
the MIDI file, using calls to MIDI-specific routines
|
||||
in midifile.c
|
||||
queues.c - library of routines for handling 'queues', a data
|
||||
structure used internally by genmidi.c
|
||||
midifile.c - Thompson and Czeisperger's public domain library of
|
||||
MIDI file manipulation routines.
|
||||
|
||||
In the first phase of parsing, the abc file is read and when, say, a note
|
||||
is encountered, the routine event_note() is called. The code for event_note
|
||||
is in the file store.c. Encountering an X in the abc generally causes a
|
||||
routine called event_X() to be called. abc2midi builds up an internal
|
||||
representation of the tune. At the end of the abc tune, a little bit of
|
||||
processing is done on the internal representation before the routine
|
||||
writetrack() is called to actually write out the MIDI file. If there are
|
||||
repeats in the music, something that appears only once in the abc may be
|
||||
invoked twice by writetrack().
|
||||
|
||||
The internal representation uses the arrays feature[], pitch[], num[],
|
||||
and denom[]. feature[] holds a description of an object while the other
|
||||
arrays hold data relating to the object. The list of possible features
|
||||
can be found in the file abc.h . The main features are NOTE, a note of
|
||||
specified duration, REST, a pause of specified duration and TNOTE, a
|
||||
note of specified duration with no interval between when it starts and
|
||||
when the next item starts. This provides a simple way of representing
|
||||
chords. Ties, broken rhythm signs and grace note brackets are all
|
||||
deal with before writetrack() is called.
|
||||
|
||||
To add your own special features, you could define a new feature type.
|
||||
However, an easier option is to use the %%MIDI format. If the parser
|
||||
encounters "%%MIDI command", where command is not recognized by the
|
||||
routine event_specific(), the string following %%MIDI is stored away
|
||||
and passed to the routine dodeferred() by writetrack() when the MIDI
|
||||
file is being written.
|
||||
----------------------------------------------------------------------
|
||||
abc2abc
|
||||
-------
|
||||
abc2abc shares the parser with abc2midi, but instead of storing the
|
||||
abc code in an internal format, it is written almost straight out
|
||||
again. The components of abc2abc are:
|
||||
|
||||
parseabc.c - parser
|
||||
toabc.c - generates output abc.
|
||||
midifile.c - public domain MIDI library.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
YAPS
|
||||
----
|
||||
|
||||
YAPS is written mainly using ANSI C style function headers and
|
||||
compiled and tested using DJGPP (DOS/Windows port of gcc).
|
||||
|
||||
The code is composed of the following files:
|
||||
|
||||
parseabc.c - reads through the abc text file. When it recognizes an abc
|
||||
"unit" it calls a routine such as event_note() or event_key().
|
||||
|
||||
yapstree.c - creates a data structure to represent a tune.
|
||||
Generally, I have tried to use as small a number of passes through the
|
||||
data structure as possible. This means that things like applying a
|
||||
broken rhythm symbol > is done as the notes are read in, rather than
|
||||
using a second pass. This results in a lot of variables being needed in
|
||||
'struct voice' to keep track of what is going on as we read in the
|
||||
current symbols. Different sets of these variables are used on different
|
||||
passes through the data.
|
||||
|
||||
drawtune.c - responsible for creating the PostScript file. When a whole
|
||||
tune has been read in, this calculates the size of each individual
|
||||
element, works out spacing within each line, decides how to place the beam
|
||||
for a group of beamed notes, then finally generates the PostScript for
|
||||
the tune.
|
||||
|
||||
position.c - called by drawtune.c. This set of routines is responsible
|
||||
for spacing each line correctly. Where the input abc is multi-voice,
|
||||
elements played at the same time but in different voices are aligned.
|
||||
|
||||
pslib.c - a single routine to print out the entire library of PostScript
|
||||
functions used by yaps.
|
||||
|
||||
debug.c - routines to print to screen the contents of a tune data
|
||||
structure.
|
||||
|
||||
abc.h - header file defining abc element types.
|
||||
|
||||
structs.h - header file defining the data structures used by the program.
|
||||
The voice structure holds a lot of cuurent context information, used by
|
||||
the program as it does a pass through the voice.
|
||||
|
||||
sizes.h - header file containing macros to define sizes in points for all
|
||||
the graphic elements.
|
||||
|
||||
Dynamic Memory Management
|
||||
-------------------------
|
||||
abc2midi uses a system of re-sizable arrays in order to handle arbitrary
|
||||
size input. This scheme was a natural way to adapt the original fixed size
|
||||
arrays, and is not as flexible as it might be. Yaps instead uses linked
|
||||
lists. There is a tune data structure containing a linked list of voices
|
||||
and the notes and other elements are stored in a linked list in each tune.
|
||||
Some music elements contain their own linked lists; for example a note
|
||||
may have a linked list of lyric syllables. Adding a new data item to an
|
||||
element (e.g. a note) involves the following :
|
||||
|
||||
1. find 'struct note' in structs.h and add the element.
|
||||
2. Initialize it in newnote().
|
||||
3. If it is a pointer to a new data structure, make sure the new data
|
||||
structure is de-allocated in freevoice().
|
||||
|
||||
----------------------------------------------------------------------
|
||||
The abc parser
|
||||
--------------
|
||||
The parser (parseabc.c) has been written in such a way that it forms
|
||||
an independent unit which must be linked with routines to handle
|
||||
parsed units. This is very similar to the way that the
|
||||
midifilelib utilities work.
|
||||
|
||||
The abc is parsed line by line. Each line may be
|
||||
|
||||
* A comment
|
||||
* A package-specific command
|
||||
* A field (which may have a trailing comment)
|
||||
* A blank line
|
||||
* A TeX command
|
||||
|
||||
Having detected one of these, the parser calls an appropriate
|
||||
routine. If it is none of these, then within the tune body it is
|
||||
|
||||
* A line of music (which may have a trailing comment).
|
||||
|
||||
Which is parsed and individual elements recognized. Outside the tune
|
||||
body it is
|
||||
|
||||
* A line of arbitrary text.
|
||||
|
||||
and an appropriate routine is called.
|
||||
|
||||
Routines called by the parser
|
||||
-----------------------------
|
||||
These may be a bit out of date - look in the file parseabc.c for the actual
|
||||
interfaces.
|
||||
|
||||
event_init(argc, argv, filename)
|
||||
int argc;
|
||||
char* argv[];
|
||||
char** filename;
|
||||
- first routine called by the parser. Expects filename to be the name of the
|
||||
abc file to parse on return.
|
||||
|
||||
event_text(s)
|
||||
char *s;
|
||||
- called whenever a line of text is encountered.
|
||||
|
||||
event_tex(s)
|
||||
char *s;
|
||||
- called whenever a TeX command is encountered.
|
||||
|
||||
event_linebreak()
|
||||
- called whenever a newline character is encountered.
|
||||
|
||||
event_blankline()
|
||||
- called whenever a blank line is encountered.
|
||||
|
||||
event_eof()
|
||||
- called when the end of file is reached.
|
||||
|
||||
event_error(s)
|
||||
char *s;
|
||||
- called whenever an error condition is detected. Errors are
|
||||
generally not fatal within the parser.
|
||||
|
||||
event_warning(s)
|
||||
char *s;
|
||||
- called whenever a condition which is likely to be an error is
|
||||
detected.
|
||||
|
||||
event_comment(s)
|
||||
char *s;
|
||||
- called whenever a comment is encountered.
|
||||
|
||||
The following are calls are invoked by fields in the abc :
|
||||
|
||||
event_specific(package, s)
|
||||
char *package, *s;
|
||||
- recognizes %%package s
|
||||
|
||||
event_length(n)
|
||||
int n;
|
||||
- recognizes L:
|
||||
|
||||
event_refno(n)
|
||||
int n;
|
||||
- recognizes X:
|
||||
|
||||
event_tempo(n, a, b, rel)
|
||||
int n, a, b;
|
||||
int relative;
|
||||
- recognizes Q:
|
||||
|
||||
event_timesig(n, m)
|
||||
int n, m;
|
||||
- recognizes M:
|
||||
|
||||
event_key(sharps, s, minor)
|
||||
int sharps;
|
||||
char *s;
|
||||
int minor;
|
||||
- recognizes K:
|
||||
|
||||
event_part(s)
|
||||
char* s;
|
||||
- recognizes P:
|
||||
|
||||
When any other field is encountered in the abc :
|
||||
|
||||
event_field(k, f)
|
||||
char k;
|
||||
char *f;
|
||||
|
||||
If a line of music is encountered, the elements of that line each
|
||||
trigger a call to one of the following events, provided that parsing
|
||||
of music lines has been enabled :
|
||||
|
||||
event_graceon()
|
||||
|
||||
event_graceoff()
|
||||
|
||||
event_rep1()
|
||||
|
||||
event_rep2()
|
||||
|
||||
event_slur(t)
|
||||
int t;
|
||||
|
||||
event_tie()
|
||||
|
||||
event_rest(n,m)
|
||||
int n, m;
|
||||
|
||||
event_bar(type)
|
||||
int type;
|
||||
|
||||
event_space()
|
||||
|
||||
event_lineend(ch, n)
|
||||
char ch;
|
||||
int n;
|
||||
|
||||
event_broken(type, mult)
|
||||
int type, n;
|
||||
|
||||
event_tuple(p, q, r)
|
||||
int p, q, r;
|
||||
- general tuple: q and r are zero if not present
|
||||
|
||||
event_chord()
|
||||
- called whenever + is encountered.
|
||||
|
||||
event_chordon()
|
||||
- called whenever [ is encountered.
|
||||
|
||||
event_chordoff()
|
||||
- called whenever ] is encountered.
|
||||
|
||||
event_gchord(s)
|
||||
char* s;
|
||||
|
||||
event_reserved(p)
|
||||
char p;
|
||||
|
||||
event_note(roll, staccato, updown, accidental, mult, note, octave, n, m)
|
||||
int roll, staccato, mult;
|
||||
char updown, accidental, note;
|
||||
int octave, n, m;
|
||||
|
||||
In addition, there are 2 other routines :
|
||||
|
||||
int getline() - returns the line currently being parsed
|
||||
|
||||
parseron() - enable parsing of music lines.
|
||||
|
||||
parseroff() - disable parsing of music lines.
|
||||
|
||||
6
doc/programming/cvs/Entries
Normal file
6
doc/programming/cvs/Entries
Normal file
@@ -0,0 +1,6 @@
|
||||
/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
|
||||
1
doc/programming/cvs/Repository
Normal file
1
doc/programming/cvs/Repository
Normal file
@@ -0,0 +1 @@
|
||||
abcmidi/doc/programming
|
||||
1
doc/programming/cvs/Root
Normal file
1
doc/programming/cvs/Root
Normal file
@@ -0,0 +1 @@
|
||||
/home/seymour/CVSREPOS
|
||||
227
doc/programming/midi2abc.txt
Normal file
227
doc/programming/midi2abc.txt
Normal file
@@ -0,0 +1,227 @@
|
||||
Notes on the midi2abc code
|
||||
--------------------------
|
||||
written by Seymour Shlien
|
||||
|
||||
|
||||
midi2abc.txt - last updated December 5 1999
|
||||
|
||||
|
||||
Introduction
|
||||
|
||||
Midi2abc is a program for converting a midi files into an abc file.
|
||||
|
||||
A midi file merely consists of a list of commands to turn on
|
||||
and off a set of voices at specific times. The time units are
|
||||
expressed in pulses where the number of pulses per second can
|
||||
be deduced from the information in the midi file. Pitch is
|
||||
specified in semitone units ranging from 0 to 127 where middle C
|
||||
is assigned a value of 60.
|
||||
|
||||
There are two types of midi in general use. In type 0, all the
|
||||
voices are interleaved in time in one track. Each voice goes
|
||||
to a specific channel which is mapped to a particular musical
|
||||
instrument or program. There is a limit of 16 voices since only
|
||||
4 bits are assigned to indicate the channel number. In type 2,
|
||||
the voices are placed in separate tracks. This format allows
|
||||
handling more than 16 voices.
|
||||
|
||||
In order to create an abc file, midi2abc must determine the
|
||||
length of a musical unit (for example an eighth note) in terms
|
||||
of midi pulses, determine the key signature, and, finally map the
|
||||
midi commands into musical notes.
|
||||
|
||||
Though the midi file specifies the number of pulses per quarter note
|
||||
(PPQN) in the Mthd header chunk, this is not necessarily an
|
||||
accurate indication. It is primarily used together with the tempo
|
||||
indication to determine the number of pulses per second. Unless
|
||||
the midi file was created by a computer program, the actual length
|
||||
of a quarter note in midi pulses can depart from the nominal indication.
|
||||
Midi2abc tries to determine the length using its own heuristic
|
||||
algorithm.
|
||||
|
||||
The sources of the program are contained in two files: midi2abc.c and
|
||||
midifile.c. This document does not try to describe completely how
|
||||
this program works, but is more of a general road map to the software.
|
||||
|
||||
|
||||
Algorithmic Description
|
||||
|
||||
The conversion is done in multiple passes. In the first pass, the
|
||||
midi file is read and an internal representation of the file is
|
||||
created and stored in global dynamic memory. In each subsequent pass,
|
||||
other information is added to the internal representation and finally
|
||||
it is written to the output abc file.
|
||||
|
||||
After parsing the input run parameters and performing various
|
||||
initializations, the main program calls the procedure mfread
|
||||
which is found in the midifile.c module. Mfread parses the different
|
||||
midi components of the file and calls the appropriate functions
|
||||
midi2abc to process these components. These functions begin with
|
||||
the txt_ prefix, some of which are listed here.
|
||||
|
||||
txt_header midi header chunk
|
||||
txt_trackstart start of midi track
|
||||
txt_trackend end of midi track
|
||||
txt_noteon note on channel command
|
||||
txt_noteoff note off channel command
|
||||
txt_program midi program definition or change
|
||||
txt_metatext midi textual information
|
||||
txt_keysig midi key signature indication
|
||||
txt_tempo midi tempo indication
|
||||
|
||||
Many other functions such as txt_pressure and txt_parameter
|
||||
corresponding to other midi commands, do nothing here.
|
||||
|
||||
These functions build up an internal representation of the midi file
|
||||
in a global structure referenced through the track[64] structure.
|
||||
Up to 64 midi tracks can be stored in the internal representation.
|
||||
Each track structure (atrack structure) contains single and double
|
||||
linked lists of notes or text strings which are described below.
|
||||
In addition there are other linked lists (referenced by playinghead
|
||||
and chordhead), used for keeping track of notes currently playing
|
||||
and musical chords.
|
||||
|
||||
Each note is represented by an anote structure which stores various
|
||||
parameters of the note. The anote structure is allocated dynamically
|
||||
as the midi file is read. The first four entries of the structure
|
||||
are filled in while the structures are being created by mfread.
|
||||
These are entries are listed below.
|
||||
|
||||
anote.pitch pitch in midi units
|
||||
anote.chan midi channel number
|
||||
anote.vel midi velocity (corresponding to loudness)
|
||||
anote.time time in midi pulses.
|
||||
|
||||
The other entries in the anote structure are determined in later passes.
|
||||
The anote structures are linked together into a a listx structure which
|
||||
is included in the atrack structure. The head and tail of the list are
|
||||
contained in this structure to facilitate the construction of this list.
|
||||
In addition there is tlistx structure for storing all the textual
|
||||
information (for example words in a Karaoke midi file) which may be found
|
||||
in the track.
|
||||
|
||||
There is a doubly linked list structure of anotes (dlistx,
|
||||
*playinghead) which is used as a work space for matching the note off
|
||||
command with the corresponding note on command. This is needed in order
|
||||
to determine the length of time the note was turned on (called anote.tplay).
|
||||
|
||||
The internal representation is mainly constructed by the important
|
||||
functions txt_noteon and txt_noteoff called by mfread. These functions
|
||||
in turn call the functions addnote and notestop. The midi file contains
|
||||
separate commands for turning a note on or off so that in order to
|
||||
determine the length of time that a note has been on, it is necessary to
|
||||
match a note-off command with the corresponding note-on command.
|
||||
Every time a note is turned on, it is also added to the playhead (tail)
|
||||
structure. The procedure notestop finds the corresponding note-on
|
||||
command in the playhead structure, removes it, and records the
|
||||
duration of the note which was turned on.
|
||||
|
||||
At the end of the first pass, the number of tracks is counted and each
|
||||
track is processed by the function postprocess which computes the entry
|
||||
anote.dtnext for each anote structure. This entry contains the time
|
||||
interval between the current and the next note in the linked list of
|
||||
notes.
|
||||
|
||||
The abc time unit length is either 1/8 or 1/16 depending on the time
|
||||
signature. A time signature of 4/4 is assumed unless it is specified
|
||||
by the run time parameters (-m or -xm). (If -xm is specified, then the
|
||||
program uses the time signature given by the midi meta command if it
|
||||
exists in the file.)
|
||||
|
||||
The next step involves the quantization of the midi time units
|
||||
expressed in pulse counts into abc time units. It is first necessary
|
||||
to estimate the length of an abc time unit in terms of midi time
|
||||
units. This either is estimated using a heuristic algorithm,
|
||||
guesslength, or is determined from the run time parameters (-Q or -b).
|
||||
|
||||
The function guesslength makes an initial guess by dividing the
|
||||
total number of pulse counts in the track by the total number
|
||||
of notes. It then tries 100 different lengths in the neighbourhood
|
||||
of this initial guess and chooses the one which leads to the smallest
|
||||
quantization error. The quantization error is determined by the function
|
||||
quantizer which keeps track of the total deviation of the time
|
||||
a note starts (in pulse counts) from the expected time the note
|
||||
starts assuming the standard musical intervals. This deviation
|
||||
can either drift positively or negatively with time. The total
|
||||
error is determined by summing the absolute values of these
|
||||
deviations for each bar.
|
||||
|
||||
Once the unit length has been determined, all the notes in all
|
||||
tracks are quantized by the function quantizer. This function
|
||||
assigns values to the anote entries, anote.xnum, anote.playnum
|
||||
and anote.denom.
|
||||
|
||||
anote.xnum interval between the current note and following note
|
||||
also called the gap.
|
||||
anote.playnum note duration.
|
||||
anote.denom always has the value of 2.
|
||||
|
||||
A musical part does not necessarily begin at the start of a bar line,
|
||||
but may have some leading notes. This is called anacrusis.
|
||||
There are two methods to estimate the anacrusis. The function findana
|
||||
searches for the first upbeat by examining the velocities (loudness) of
|
||||
the notes. The function guessana, chooses the anacrusis which minimizes
|
||||
the number of tied notes across a bar line which is determined by the
|
||||
function testtrack.
|
||||
|
||||
At this point the key signature of the tune must be determined.
|
||||
The procedure findkey computes the frequency distribution of all the
|
||||
notes in the piece and stores it in the local array n[]. The key
|
||||
signature is determined by transposing the distribution by each
|
||||
of the 12 keys and counting the number of sharp or flat notes. The
|
||||
key signature is determined from the key which leads to the minimum
|
||||
number of black keys on the piano. The mode of the scale (major,
|
||||
minor, Dorian, etc.) is determined by looking at the final note of
|
||||
the piece.
|
||||
|
||||
Once the key signature is determined, the assumed flats or sharps
|
||||
are determined by the procedure setupkey. The program is now ready
|
||||
for its final pass where the musical parts (or voices) are printed
|
||||
in the output abc file.
|
||||
|
||||
The procedure printtrack processes the internal representation
|
||||
of each midi track producing a separate voice for each track.
|
||||
In order to handle chords which may be present in an individual
|
||||
track, printtrack maintains a structure referenced by chordhead
|
||||
by calling the support functions addchord(), advancechord(),
|
||||
removechord() and printchord(). These functions handle single
|
||||
notes as well as chords. Another function, dospecial(), handles
|
||||
the triplets and broken rhythms (eg. dotted notes followed by
|
||||
half sized note or vice versa) whenever they are detected. The
|
||||
printchord() function is supported by the functions printfraction()
|
||||
and printpitch().
|
||||
|
||||
After the track is printed, the memory allocated to the structures
|
||||
for the internal representation of the tracks is freed.
|
||||
|
||||
The option -splitvoice was introduced to handle polyphonic chords.
|
||||
Without this option polyphonic chords appear in the abc file
|
||||
like this.
|
||||
|
||||
[DF-A-][FA-]Az|
|
||||
|
||||
this will be represented by three voices
|
||||
|
||||
V: split1A
|
||||
D2 z6|
|
||||
V: split1B
|
||||
F4 z4|
|
||||
V: split1C
|
||||
A6 z2|
|
||||
|
||||
This option is implemented by the function printtrack_split_voice().
|
||||
The function label_split_voices() is called to assign all the notes
|
||||
in the track to their split voice. This assignment of each note is
|
||||
stored in note->splitnum. This is a complex function since it needs
|
||||
to try to match the onset and end of each note in the chord. If
|
||||
it is unable to do this for a particular note, then the note is
|
||||
assigned to a different split. At the end, nsplits were created.
|
||||
The notes in each split are printed in a separate voice by the
|
||||
function printtrack_split(). The function printtrack_split(splitnumber)
|
||||
was derived from printtrack(); however, it only processes the
|
||||
notes belonging to a particular splitnumber.
|
||||
|
||||
It was necessary to determine and store the offset of the first
|
||||
note in each split using the function set_first_gaps() prior
|
||||
to calling printtrack_split().
|
||||
|
||||
131
doc/programming/split.abc
Normal file
131
doc/programming/split.abc
Normal file
@@ -0,0 +1,131 @@
|
||||
X:1
|
||||
T: test split file 1
|
||||
M: 2/4
|
||||
L: 1/4
|
||||
K: G
|
||||
G & E & C|D|GA & EF|
|
||||
|
||||
|
||||
X:2
|
||||
T: test split file 2
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
%%MIDI program 20
|
||||
D|G & E|C|F|G & E|
|
||||
|
||||
X:3
|
||||
T: test split file 3
|
||||
M: 2/4
|
||||
L: 1/8
|
||||
Q: 50
|
||||
K: D
|
||||
CD |EF AB & CD FG| G2 | BD D2 & GB B2|
|
||||
|
||||
X:4
|
||||
T: test split file 4
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
V:1
|
||||
|:G |[1 D & B:|
|
||||
V:2
|
||||
|:g |[1 d & b:|
|
||||
V:1
|
||||
[2 F & A|
|
||||
V:2
|
||||
[2 f & a|
|
||||
|
||||
X:5
|
||||
T: test split file 5
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
G & E |D|
|
||||
|
||||
X:6
|
||||
T: test split file 6
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
D|G & E|
|
||||
|
||||
X:7
|
||||
T: test split file 7
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
D|G & E & C|F|
|
||||
|
||||
X:8
|
||||
T: test split file 8
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
G & E & C|D|
|
||||
|
||||
X:9
|
||||
T: test split file 9
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
G & E & C|D|F & A|
|
||||
|
||||
X:10
|
||||
T: test split file 10
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
V:1
|
||||
|:G |[1 D & B
|
||||
V:2
|
||||
|:g |[1 d & b
|
||||
V:1
|
||||
:|[2 F & A|
|
||||
V:2
|
||||
:|[2 f & a|
|
||||
|
||||
X:11
|
||||
T: test split file 11
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
|:G & E :|D|F & A|
|
||||
|
||||
X:12
|
||||
T: test split file 12
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
|:G & E |D:|F & A|
|
||||
|
||||
X:13
|
||||
T: test split file 13
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
|:G & E |[1 D:|[2 F & A|
|
||||
|
||||
X:14
|
||||
T: test split file 14
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
|:G |[1 D & B:|[2 F & A|
|
||||
|
||||
X:15
|
||||
T: splits with octave=1
|
||||
M: 4/4
|
||||
L: 1/4
|
||||
K: G octave=1
|
||||
G A B C & E F G A|
|
||||
|
||||
|
||||
X:16
|
||||
T: test split file 13
|
||||
M: 1/4
|
||||
L: 1/4
|
||||
K: G
|
||||
|:G & E |1 D:|2 F & A|
|
||||
|
||||
|
||||
134
doc/programming/yaps.txt
Normal file
134
doc/programming/yaps.txt
Normal file
@@ -0,0 +1,134 @@
|
||||
Some Notes on the yaps Code
|
||||
-------------------------------------------------------------
|
||||
written by Seymour Shlien November 21 2004
|
||||
|
||||
This file gives an algorithmic description of the
|
||||
yaps program which converts an abc file to a PostScript file.
|
||||
|
||||
The source consists of almost 10000 lines of C in the following
|
||||
files.
|
||||
|
||||
parseabc.c is the front end which scans the abc file and invokes
|
||||
the appropriate event handler for each element it encounters
|
||||
(eg. bar lines, notes, chords etc.) It happens to be the
|
||||
front end for other programs such as abc2midi, and
|
||||
abc2abc. More details are given in abc2midi.txt.
|
||||
|
||||
yapstree.c contains all the event handlers called by the parser.
|
||||
It produces a complex data structure called tune which
|
||||
references many other structures. When the parser completes
|
||||
processing the tune, event_blankline or event_eof calls
|
||||
printtune (in drawtree.c) which processes the tune structure
|
||||
producing a PostScript file. Unlike abc2midi, most of the
|
||||
layout including the detailed beaming is done in the first
|
||||
pass during the parsing stage. The information in this
|
||||
structure is then processed by drawtune.c in two more
|
||||
passes. An overview of these structures is provided here.
|
||||
More details on the tune structure is provided in this
|
||||
file.
|
||||
|
||||
drawtune.c contains the function printtune which turns the tune
|
||||
structure into an actual PostScript file. This is done
|
||||
in two passes. Before writing the PostScript file it
|
||||
is necessary to determine the boundingbox of the output
|
||||
image since this information is recorded in the header
|
||||
of the output file. This is determined in the first pass
|
||||
where functions monospace() or spacevoices() (in position.c)
|
||||
are called. During this pass the pixel positions
|
||||
of each object are recorded in the associated structures.
|
||||
In the second pass, the actual PostScript file is written.
|
||||
The function calls printlib() (in pslib.c) outputs
|
||||
all the PostScript boiler plate macro definitions required
|
||||
by yaps. The information in the tune structure is used
|
||||
to output the music notation in a PostScript file.
|
||||
|
||||
|
||||
position.c contains functions for determining the amount of space
|
||||
that is required for the different music objects drawn
|
||||
in the PostScript file.
|
||||
|
||||
parser2.c contains additional parsing functions missing in parseabc.
|
||||
They handle more recent features added to the abcmidi package.
|
||||
|
||||
pslib.c Definition of new PostScript commands (eg. notes, clefs,
|
||||
stems, tails, ...) which are copied to the PostScript
|
||||
file.
|
||||
|
||||
debug.c Functions which support the -d option in yaps. It prints
|
||||
some of the contents of the internal tune structure.
|
||||
|
||||
|
||||
Data Structures
|
||||
---------------
|
||||
|
||||
The data structures are defined in the include file structs.h.
|
||||
|
||||
The top level structure, tune is instantiated by init_tune which
|
||||
is called by event_init or event_refno. It stores all the
|
||||
information in the abc field commands (X: ,M:, L:, C:, O: and etc.).
|
||||
It contains a pointer to the voice structure and a list of voice
|
||||
pointers where most of the body information is recorded.
|
||||
|
||||
The voice structure is instantiated by the function newvoice
|
||||
which is called by setvoice(n) whenever the voice context
|
||||
switches in the abc file. Setvoice performs the voice switching
|
||||
(which occurs in voice interleaved files) and either creates
|
||||
a new voice or finds the matching voice structure already existing.
|
||||
The voice structure contains the feature structure which
|
||||
is somewhat similar in function to the one defined in store.c
|
||||
(for abc2midi).
|
||||
|
||||
The feature structure encodes all the detailed information in
|
||||
the body, using the same typedef enum featuretype defined
|
||||
in abc.h. Unlike store.c there is no num and denom arrays. Instead
|
||||
the feature struct contains a void* pointer called item which
|
||||
can point to anything and where additional information can be
|
||||
stored. If the feature type is a NOTE then a "note" struct
|
||||
is created which records a lot of detailed information related
|
||||
to the placement and visual representation of the note. They
|
||||
include:
|
||||
tail_type which specifies whether the note appears in
|
||||
isolation or is part of a beamed group
|
||||
base_exp whole, half, quarter, ... notes
|
||||
dots how many dots follow
|
||||
stemlength, stemup, fliphead, pitch, octave, accidentals, accents,...
|
||||
(see struct.h)
|
||||
Most of the information except actual positioning is determined
|
||||
by functions such as count_dots and beamitem in yapstree.c.
|
||||
You can view this information by running yaps.exe with the -d
|
||||
run time parameter.
|
||||
|
||||
The handling of the note positioning is quite complex as
|
||||
outlined below. It is therefore not easy to implement the
|
||||
splitvoice feature into yaps. Here is a description.
|
||||
|
||||
The positioning of notes is done by the function
|
||||
spacemultiline() which calls advance() unless one is printing
|
||||
the voices separately. The positioning is done on all the voices
|
||||
at the same time to ensure that they are lined up properly.
|
||||
Spacemultiline accesses all the active voices using the functions
|
||||
firstitem() and nextitem() which are used for handling any lists
|
||||
of objects. Each voice maintains its own pointer to the current
|
||||
feature being scanned (v->place). Each voice also maintains its
|
||||
own pointer to the relative time of the note being scanned
|
||||
in the variable v->time. (v->time contains both a numerator
|
||||
and denominator.) The advance() function updates v->place,
|
||||
v->time and interprets the voice features determining the
|
||||
amount of space that is needed to plot the next object (itemspace)
|
||||
and the number of plotable objects (items). The position to
|
||||
plot the next object (x) is maintained by spacemultiline and
|
||||
passed to advance. Advance() updates v->place->x with the position
|
||||
to plot the object based on its width. Spacemultiline()
|
||||
maintains a mastertime variable for maintaining synchrony
|
||||
between all voices.
|
||||
|
||||
At least two passes are made through the voice features.
|
||||
In the first pass provisional positions are computed for the
|
||||
notes. The amount of space left over in the music lines is
|
||||
computed and is used to determine the internote gaps.
|
||||
In the second pass, the notes are repositioned to use up
|
||||
the entire space in the staff line.
|
||||
|
||||
Spacemultiline is called for each staff line whose end is
|
||||
signaled by a linefeed feature in the voice.
|
||||
|
||||
546
doc/readme.txt
Normal file
546
doc/readme.txt
Normal file
@@ -0,0 +1,546 @@
|
||||
abcMIDI : abc <-> MIDI conversion utilities
|
||||
|
||||
midi2abc version 3.46 June 22 2020
|
||||
abc2midi version 4.38 July 05 2020
|
||||
abc2abc version 2.08 June 04 2020
|
||||
yaps version 1.77 June 04 2020
|
||||
abcmatch version 1.73 June 04 2020
|
||||
midicopy version 1.36 June 04 2019
|
||||
|
||||
24th January 2002
|
||||
|
||||
Copyright James Allwright
|
||||
J.R.Allwright@westminster.ac.uk
|
||||
University of Westminster,
|
||||
London, UK
|
||||
|
||||
February 2020
|
||||
|
||||
Seymour Shlien
|
||||
Ottawa, Canada
|
||||
fy733@ncf.ca
|
||||
|
||||
This is free software. You may copy and re-distribute it under the terms of
|
||||
the GNU General Public License version 2 or later, which is available from
|
||||
the Free Software Foundation (and elsewhere).
|
||||
|
||||
This package is to be found on the web at
|
||||
|
||||
http://abc.sourceforge.net/abcMIDI/
|
||||
(The latest versions for the time being is found on
|
||||
ifdo.ca/~seymour/runabc/top.html.)
|
||||
|
||||
Note, if you have difficulty compiling the package because you do not have
|
||||
snprintf see the note in doc/CHANGES dated January 08 2005 (and also
|
||||
December 17 2004).
|
||||
|
||||
These programs make use of the 'midifilelib' public domain MIDI file utilities,
|
||||
which was originally available from
|
||||
|
||||
http://www.harmony-central.com/MIDI/midifilelib.tar.gz
|
||||
|
||||
If you have the source distribution and intend to re-compile the code,
|
||||
read the file coding.txt.
|
||||
---------------------------------------------------------------------
|
||||
midi2abc - program to convert MIDI format files to abc notation.
|
||||
|
||||
This program takes a MIDI format file and converts it to something as close
|
||||
as possible to abc text format. The user then has to add text fields not
|
||||
present in the MIDI header and possibly tidy up the abc note output.
|
||||
|
||||
Features :
|
||||
|
||||
* The key is chosen so as to minimize the number of accidentals.
|
||||
Alternatively, the user can specify the key numerically (a positive number
|
||||
is the number of sharps, a negative number is minus the number of flats).
|
||||
* Note length can be set by specifying the total number of bars or the
|
||||
tempo of the piece. Alternatively the note length can be read from the file.
|
||||
However, by default it is deduced in a heuristic manner from the inter-note
|
||||
distances. This means that you do not have to use the MIDI clock as a
|
||||
metronome when playing in a tune from a keyboard.
|
||||
* Barlines are automatically inserted. The user specifies the number of
|
||||
measures in the anacrusis before the first barline and the time signature.
|
||||
* The program can guess how many beats there should be in the anacrusis,
|
||||
either by looking for the first strong note or minimizing the number of
|
||||
notes split by a tie across a barline.
|
||||
* Where a note extends beyond a bar break, it is split into two tied notes.
|
||||
* The output has 4 bars per line.
|
||||
* Enough accidental signs are put in the music to ensure that no pitch
|
||||
errors occur if a barline is added or deleted.
|
||||
* The program attempts to group notes sensibly in each bar.
|
||||
* Triplets and broken rhythm (a>b) are supported.
|
||||
* Chords are identified.
|
||||
* Text information from the original MIDI file is included as comments.
|
||||
* The -c option can be used to select only 1 MIDI channel. Events on
|
||||
other channels are ignored.
|
||||
|
||||
What midi2abc does not do :
|
||||
|
||||
* Supply tune title, composer or any other field apart from X: , K:, Q:, M:
|
||||
and L: - these must be added by hand afterwards, though they may have been
|
||||
included in the text of the MIDI file.
|
||||
* Support duplets, quadruplets, other esoteric features.
|
||||
* Support mid-tune key or meter changes.
|
||||
* Deduce repeats. The output is just the notes in the input file.
|
||||
* Recover an abc tune as supplied to abc2midi. However, if you want to
|
||||
do this, "midi2abc -xa -f file.mid" comes close.
|
||||
|
||||
midi2abc
|
||||
usage :
|
||||
midi2abc <options>
|
||||
-a <half L: units>
|
||||
-xa extract anacrusis from file (find first strong note)
|
||||
-ga guess anacrusis (minimize ties across bars)
|
||||
-gk guess key signature by minimizing accidentals
|
||||
-gu guess the number of midi pulses per note from note
|
||||
duration statistics in the MIDI file
|
||||
-m <time signature>
|
||||
-b <bars wanted in output>
|
||||
-Q <tempo in quarter-notes per minute>
|
||||
-k <key signature> -6 to 6 sharps
|
||||
-c <channel>
|
||||
[-f] <input file>
|
||||
-o <output file>
|
||||
-s do not discard very short notes
|
||||
-sr do not notate a short rest after a note
|
||||
-sum summary
|
||||
-nt do not look for triplets or broken rhythm
|
||||
-u number of midi pulses per abc time unit
|
||||
-ppu parts per abc unit length (power of 2 only)
|
||||
-aul denominator of abc unit length (power of 2 only)
|
||||
-obpl one bar per line (deprecated)
|
||||
-bpl <number> of bars per printed line
|
||||
-bps <number> of bars per staff line
|
||||
-nogr No note grouping. Space put between every note.
|
||||
-splitbars splits bars to avoid nonhomophonic chords.
|
||||
-splitvoices splits voices to avoid nonhomophonic chords.
|
||||
-midigram No abc file is created, but a list
|
||||
of all notes is produced. Other parameters
|
||||
are ignored.
|
||||
-mftext No abc file is created, but a list of all
|
||||
the midi commands (mftext like output) is
|
||||
produced. The output is best viewed with
|
||||
runabc.tcl
|
||||
-stats prints summary and statistics of the midi file
|
||||
which would be best viewed using an new application
|
||||
midiexplorer.tcl.
|
||||
-ver Prints version number and exits
|
||||
|
||||
Use only one of -u -gu -b and -Q or better none.
|
||||
If none of these is present, the program uses the PPQN header
|
||||
information in the MIDI file to determine the note length in
|
||||
MIDI pulses. This usually results in the best output.
|
||||
|
||||
The output of midi2abc is printed to the screen. To save it to a file, use
|
||||
the redirection operator or the -o option.
|
||||
|
||||
e.g.
|
||||
|
||||
midi2abc -f file.mid > file.abc
|
||||
or
|
||||
midi2abc -f file.mid -o file.abc
|
||||
|
||||
By default the program uses the key signature and time signature
|
||||
specified in the MIDI file. If the key signature is not specified,
|
||||
the program will automatically determine the key signature by
|
||||
minimizing the number of accidentals. If there is no time signature
|
||||
found, then 4/4 is assumed. You may also specify a time signature
|
||||
using the -m option. Allowable time signatures are C,
|
||||
4/4, 3/8, 2/4 and so on.
|
||||
|
||||
If the tune has an anacrusis, you should specify the number in quantum
|
||||
units lengths. By default a quantum unit length is one half of
|
||||
the unit length note specified by the L: command. (However, this
|
||||
can be changed using the -ppu runtime parameter.) For example,
|
||||
if the meter is 6/8 and L: is set to 1/8, a half unit length is
|
||||
1/16 note. An anacrusis of a quarter note would be specified as 4.
|
||||
|
||||
The -bpl and -bps control the formatting of the output. -bpl controls
|
||||
the number of bars put in every line. The lines are joined together
|
||||
with a backslash (\) until the desired number of bars per staff are
|
||||
printed. Since -bpl 1 is equivalent to -obpl, the latter parameter
|
||||
is being deprecated.
|
||||
|
||||
Midi2abc has evolved quite a lot since James Allwright has
|
||||
transferred support and development to me [SS]. Most of the
|
||||
MIDI files posted on the web site appear to have been generated
|
||||
from a music notation program and therefore convert cleanly
|
||||
to abc files using all the information built into the file.
|
||||
Therefore midi2abc no longer automatically estimates the number
|
||||
of MIDI pulses per note from the file statistics, but uses
|
||||
the indications embedded in the file. However, the user still
|
||||
has the option of calling these functions or changing this
|
||||
parameter by using the run time parameters Use only one of -u -gu
|
||||
-b and -Q or better none. The -u parameter, allows you
|
||||
to specify the number of MIDI pulses per unit length, assuming
|
||||
you know what it should be. To find out the value that
|
||||
midi2abc is using, run the program with the -sum parameter.
|
||||
|
||||
Midi2abc quantizes the note durations to a length of half
|
||||
the L: value. Thus if L: was set to 1/8, then the smallest
|
||||
note that midi2abc would extract would be a 1/16 th note.
|
||||
This is the basic quantum unit. The L: note length is set
|
||||
by midi2abc on the basis of the time signature. For time
|
||||
signatures less than 3/4 it uses an L: 1/16 and for others
|
||||
it uses a length of 1/8. This convention was probably chosen
|
||||
so that midi2abc does not quantize the notes to a too fine
|
||||
level producing outputs like C2-C/4 D2-D/8 etc which would
|
||||
be difficult to read. For some music, this may be too coarse
|
||||
and it may be preferable to allow the user take control of
|
||||
the L: value or allow the splitting of the L: value into
|
||||
smaller parts. Two new run time parameters were introduced:
|
||||
-ppu specifies the number of parts to split the L: note.
|
||||
It should be a power of 2 (eg. 1,2,4,8,16 ...) and by default
|
||||
it remains as 2 as before. The -aul specifies the L: value to use,
|
||||
for example, to get L: 1/32 you would put -aul 32.
|
||||
|
||||
|
||||
Keyboard and guitar music has a lot of chords which frequently
|
||||
poses a problem to midi2abc. If the notes in the chord do
|
||||
not share a common onset or end time, midi2abc uses ties to join
|
||||
the longer notes to other chords. This produces a mess looking
|
||||
somewhat like
|
||||
[AG-G-G-D-G,,,-][B/2-B/2-B/2-G/2G/2-G/2-D/2-G,,,/2-]...
|
||||
which does not convert into something easy to read when
|
||||
display in common music notation. Abcm2ps and abc2midi allow
|
||||
a bar to be split into separate voices using the & sign.
|
||||
Separating the notes which do not overlap exactly into
|
||||
individual voices provides some improvement. If you encountering
|
||||
this problem with your MIDI file, you may wish to try rerunning
|
||||
the file with either the -splitbars or -splitvoices parameter.
|
||||
This is a feature introduced in June 2005 (version 2.83).
|
||||
The algorithm which separates the notes in a voice into
|
||||
distinct voices (tracks) (label_split in midi2abc.c) is rather
|
||||
crude and needs improvement. I welcome any suggestions
|
||||
or improved code.
|
||||
|
||||
|
||||
The -midigram option runs midi2abc in a completely different
|
||||
mode. It does not produce any abc file but outputs a list
|
||||
of all the notes found in the MIDI file. Each line of output
|
||||
represents one note. For each line, the on and off time
|
||||
in MIDI time units, the track number, the channel number,
|
||||
midi pitch, and midi velocity are listed. The last line
|
||||
contains a single value equal to the duration of the file
|
||||
in MIDI pulses. The output is designed to eventually go into a
|
||||
graphical user interface (runabc) which will display these events
|
||||
in piano roll format.
|
||||
|
||||
Note: midi2abc does not work correctly if the lyrics are embedded
|
||||
in the same track as the notes. If you intend to run midi2abc on
|
||||
the MIDI file produced by abc2midi, you need to use the -STFW
|
||||
option if the tune contains lyrics.
|
||||
|
||||
eg. abc2midi lyric_tune.abc -STFW
|
||||
|
||||
Since February 01 2010, abc2midi by default places the lyrics in
|
||||
the same track as the notes. See doc/CHANGES.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
abc2midi - converts abc file to MIDI file(s).
|
||||
Usage : abc2midi <abc file> [reference number] [-c] [-v] [-o filename]
|
||||
[-t] [-n <value>] [-ver] [-NFNP] [-NFER] [-NGRA] [-STFW] [-NCOM] [-OCC]
|
||||
[reference number] selects a tune
|
||||
-c selects checking only
|
||||
-v <level> selects verbose option
|
||||
-o <filename> selects output filename
|
||||
-t selects filenames derived from tune titles
|
||||
-n <limit> set limit for length of filename stem
|
||||
-CS use 2:1 instead of 3:1 for broken rhythms
|
||||
-quiet suppress some common warnings
|
||||
-silent suppresses other messages
|
||||
-Q <tempo> in quarter notes/minute
|
||||
-NFNP ignore all dynamic indications (!f! !ff! !p! etc.)
|
||||
-NFER ignore fermata markings
|
||||
-NGRA ignore grace notes
|
||||
-STFW separate tracks for words (lyrics)
|
||||
-NCOM suppress comments
|
||||
-ver prints version number and exits
|
||||
-BF Barfly mode: invokes a stress model if possible
|
||||
-OCC old chord convention (eg. +CE+)
|
||||
-TT tune to A = <frequency>
|
||||
-CSM <filename> load custom stress models from file
|
||||
|
||||
The default action is to write a MIDI file for each abc tune
|
||||
with the filename <stem>N.mid, where <stem> is the filestem
|
||||
of the abc file and N is the tune reference number. If the -o
|
||||
option is used, only one file is written. This is the tune
|
||||
specified by the reference number or, if no reference number
|
||||
is given, the first tune in the file. The -Q parameter sets
|
||||
the default tempo in event the Q: command is not given in the
|
||||
abc header. The program accepts both the deprecated (eg.
|
||||
!trill!) and standard (+trill+) notation for decorations.
|
||||
Older versions of this program handled the defunct convention
|
||||
for chords (i.e +G2B2D2+ instead of [GBD]2). If you need to
|
||||
handle the older notation, include the -OCC flag; however the
|
||||
program will not accept the standard notation for decorations.
|
||||
Broken rhythms indicated by > or < (eg. A > B) assume a
|
||||
the hornpipe ratio of 3:1. To change it to the Celtic ratio
|
||||
3:1 include the -CS flag.
|
||||
|
||||
|
||||
Features :
|
||||
|
||||
* Broken rythms (>, <), chords, n-tuples, slurring, ties, staccatto notes,
|
||||
repeats, in-tune tempo/length/meter changes are all supported.
|
||||
|
||||
* R:hornpipe or r:hornpipe is recognized and note timings are adjusted to
|
||||
give a broken rhythm (ab is converted to a>b).
|
||||
|
||||
* Most errors in the abc input will generate a suitable error message in
|
||||
the output and the converter keeps going.
|
||||
|
||||
* Comments and text fields in the abc source are converted to text events
|
||||
in the MIDI output
|
||||
|
||||
* If guitar chords are present, they are used to generate an accompaniment
|
||||
in the MIDI output.
|
||||
|
||||
* If there are mis-matched repeat signs in the abc, the program attempts to
|
||||
fix them. However, it will not attempt this if a multi-part tune
|
||||
description has been used or if multiple voices are in use.
|
||||
|
||||
* Karaoke MIDI files can be generated by using the w: field to include
|
||||
lyrics.
|
||||
|
||||
* Nonnumeric voice ids, eg V: soprano, as described as proposed
|
||||
for the new abc standard is handled.
|
||||
|
||||
* Invisible rests specified as x, are treated as normal rests (z).
|
||||
|
||||
* There are some extensions to the abc syntax of the form
|
||||
|
||||
%%MIDI channel n
|
||||
|
||||
These control channel and program selection, transposing and various
|
||||
other features of abc2midi. See the file abcguide.txt for more
|
||||
details.
|
||||
|
||||
Bugs and Limitations :
|
||||
|
||||
* No field is inherited from above the X: field of the tune.
|
||||
|
||||
* Where an accidental is applied to a tied note that extends across
|
||||
a barline, abc2midi requires that the note beyond the barline must
|
||||
be explicitly given an accidental e.g.
|
||||
|
||||
^F- | F - will be reported as an error.
|
||||
^F- | ^F - will produce a tied ^F note.
|
||||
|
||||
It is common to see no accidental shown when this occurs in published
|
||||
printed music.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
abc2abc
|
||||
|
||||
Usage: abc2abc <filename> [-s] [-n X] [-b] [-r] [-e] [-t X]
|
||||
[-u] [-d] [-v] [-V X] [-ver] [-X n]
|
||||
-s for new spacing
|
||||
-n X to re-format the abc with a new linebreak every X bars
|
||||
-b to remove bar checking
|
||||
-r to remove repeat checking
|
||||
-e to remove all error reports
|
||||
-t X to transpose X semitones
|
||||
-nda No double accidentals in guitar chords
|
||||
-nokeys No key signature (i.e. K: none). Use sharps.
|
||||
-nokeyf No key signature (i.e. K: none). Use flats.
|
||||
-u to update notation ([] for chords and () for slurs)
|
||||
-usekey n Use key signature sf (sharps/flats)
|
||||
-useclef (treble or bass)
|
||||
-d to notate with doubled note lengths
|
||||
-v to notate with halved note lengths
|
||||
-V X[,Y...] to output only voice X,Y...
|
||||
-P X[,Y...] restricts action to voice X,Y... leaving other voices intact
|
||||
-ver prints version number and exits
|
||||
-X n renumber the all X: fields as n, n+1, ..
|
||||
-xref n output only the tune with X reference number n.
|
||||
-usekey sf Use key signature sf (flats/sharps)
|
||||
-OCC old chord convention (eg. +CE+)
|
||||
|
||||
A simple abc checker/re-formatter/transposer. If the -n option is selected,
|
||||
error checking is turned off.
|
||||
|
||||
If a voice is assigned to channel 10 (drum channel) using a
|
||||
%%MIDI channel 10
|
||||
command, then this voice is never transposed.
|
||||
|
||||
The -nokeys or -nokeyf option will set "K: none" and place accidentals on
|
||||
all notes that should have accidentals for the expected key signature.
|
||||
The first option will use only sharps; the second option will use
|
||||
only flats.
|
||||
|
||||
The -usekey option will force the key signature to be key[sf] where
|
||||
sf is a number between -5 and +5 inclusive.
|
||||
sf -5 -4 -3 -2 -1 0 1 2 3 4 5
|
||||
key Db Ab Eb Bb F C G D A E B
|
||||
Accidentals will be added to preserve the correct notes. This
|
||||
is useful for some music with many accidentals which does
|
||||
not fit in any specific key signature. If sf = 0, abc2abc
|
||||
use K:none.
|
||||
|
||||
If you want to check an abc tune, it is recommended that you use abc2midi
|
||||
with the -c option as this performs extra checks that abc2abc does not do.
|
||||
|
||||
When using the -P X option, it may be necessary to insert some
|
||||
field commands such as K: or L: following the voice X declaration,
|
||||
so that they will be converted and appear in the output.
|
||||
|
||||
The output of abc2abc is printed to the screen. To save it to a file, use
|
||||
the redirection operator.
|
||||
|
||||
e.g.
|
||||
|
||||
abc2abc file.abc -t 2 > newfile.abc
|
||||
|
||||
Known problems:
|
||||
* When using the -n option on a program with lyrics, a barline in a w:
|
||||
field may be carried forward to the next w: field.
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
mftext - MIDI file to text
|
||||
|
||||
This gives a verbose description of what is in a MIDI file. You may wish
|
||||
to use it to check the output from abc2midi. It is part of the original
|
||||
midifilelib distribution.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
YAPS
|
||||
----
|
||||
YAPS is an abc to PostScript converter which can be used as an alternative
|
||||
to abc2ps. See the file yaps.txt for a more detailed description of this
|
||||
program.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
midicopy is a stand alone application which copies a midi file or part
|
||||
of a midi file to a new midi file. If you run it with no parameters, a
|
||||
short description shown below will appear.
|
||||
|
||||
usage:
|
||||
midicopy <options> input.mid output.mid
|
||||
midicopy copies selected tracks, channels, time interval of the input midi file.options:
|
||||
-ver version information
|
||||
-trks n1,n2,..(starting from 1)
|
||||
-xtrks n1,n2,... (tracks to exclude)
|
||||
-xchns n1,n2,... (channels to exclude)
|
||||
-chns n1,n2,..(starting from 1)
|
||||
-from n (in midi ticks)
|
||||
-to n (in midi ticks)
|
||||
-fromsec %f (in seconds)
|
||||
-tosec %f (in seconds)
|
||||
-frombeat %f
|
||||
-tobeat %f
|
||||
-replace trk,loc,val
|
||||
-tempo n (in quarter notes/min)
|
||||
-speed %f (between 0.1 and 10.0)
|
||||
-drumfocus n (35 - 81) m (0 - 127)
|
||||
-mutenodrum [level]
|
||||
-setdrumloudness n (35-81) m (0 -127)
|
||||
-focusontrack n1,n2,...
|
||||
-focusonchannel n1,n2,...
|
||||
-attenuation n
|
||||
|
||||
|
||||
midicopy.exe -ver
|
||||
|
||||
will print out something like
|
||||
1.29 December 06 2017
|
||||
|
||||
|
||||
midicopy.exe input.mid output.mid
|
||||
does nothing interesting except copy the contents of input.mid to a
|
||||
new file output.mid.
|
||||
|
||||
|
||||
|
||||
If you include the -from parameter followed by a midi pulse number,
|
||||
then the program will select the appropriate data starting after the
|
||||
given midi pulse location so that will you play midi file it will start
|
||||
from that midi pulse number. In order to ensure that the right tempo,
|
||||
channel assignments are used, all of these commands prior to that
|
||||
pulse number are also copied.
|
||||
|
||||
If you include the -to command followed by a midi pulse number, the
|
||||
midi file is truncated beyond that point, so that when you play the file
|
||||
it will stop at this point. You can also specify the window using beats
|
||||
with the options -frombeats and -tobeats. The program will print out
|
||||
the estimated duration of the output midi file.
|
||||
|
||||
All the tracks will be copied unless you specify them in the list following
|
||||
keyword -trks. You start counting tracks from 1.
|
||||
|
||||
Similarly, all channels will be copied unless you specify them following
|
||||
keyword -chns. You start counting channels from 1.
|
||||
|
||||
The -xchns and -xtrk options will exclude the indicated channels or
|
||||
tracks from the output midi file. The -xchns does not work together
|
||||
with -chns and neither does -xtrks work with -trks. (Use one or the
|
||||
other.)
|
||||
|
||||
The option -replace allows you to overwrite a specific byte given its
|
||||
track number and offset loc, by the byte whose value is val. This is
|
||||
used for changing the program number associated with a channel. The byte
|
||||
is replaced in the output file. If you use the -replace option, all
|
||||
other options like -from, -to, -chns etc. are ignored.
|
||||
|
||||
The embedded tempo commands can be replaced using
|
||||
-tempo n
|
||||
in units beats/minute.
|
||||
|
||||
-speed f
|
||||
where f is a decimal number between 0.1 and 10.0 will multiply
|
||||
the current tempo by this factor.
|
||||
|
||||
-drumfocus will accentuate the specified drum (35 to 81) to level
|
||||
m (0 to 127).
|
||||
|
||||
-focusontracks will attenuate all tracks except those specified.
|
||||
|
||||
-focusonchannels will attenuate all channels except those specified.
|
||||
|
||||
-attenuation specifies the amount to reduce the note velocities
|
||||
for the focus options.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
abcmatch.exe - see abcmatch.txt
|
||||
|
||||
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
A Short Explanation of MIDI
|
||||
---------------------------
|
||||
MIDI stands for "Musical Instrument Digital Interface". MIDI was originally
|
||||
designed to connect a controller, such as a piano-style keyboard, to a
|
||||
synthesizer. A MIDI cable is similar to a serial RS232 cable but uses
|
||||
different voltage levels and an unusual baud rate (31250 baud). The MIDI
|
||||
standard also defines the meaning of the digital signals sent down the
|
||||
cable; pressing and releasing a key produces 2 of these signals, a
|
||||
"note on" followed by a "note off".
|
||||
|
||||
There is an additional standard for MIDI files, which describes how to
|
||||
record these signals together with the time when each signal was produced.
|
||||
This allows a complete performance to be recorded in a compact digital
|
||||
form. It is also possible for a computer to write a MIDI file which can
|
||||
be played back in exactly the same way as a MIDI file of a recorded
|
||||
performance. This is what abc2midi does.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
Note: DPMI server for DOS executables
|
||||
|
||||
If you have downloaded the executables compiled using DJGPP, you may get
|
||||
an error message saying that a DPMI (Dos Protected Mode Interface) server
|
||||
is needed. If you can run the programs from a DOS window within Windows,
|
||||
this may solve the problem. Alternatively, download the DPMI server
|
||||
recommended for DJGPP, called CWSDPMI.EXE. This needs to be on your path
|
||||
for the executables to run.
|
||||
-------------------------------------------------------------------------
|
||||
Bug reports
|
||||
|
||||
Please report any bugs you find in abc2midi, midi2abc, midicopy, or
|
||||
abcmatch, abc2abc to fy733@ncf.ca (preferably with
|
||||
an example so that I can replicate the problem). Better still, send
|
||||
me the repaired source files which fix the problem! If you add your
|
||||
own features to the code that other people might want to use then let
|
||||
me know. I may or may not want to add them to the official version.
|
||||
So far I have been maintaining the code, but I don't guarantee anything.
|
||||
201
doc/yaps.1
Normal file
201
doc/yaps.1
Normal file
@@ -0,0 +1,201 @@
|
||||
.TH YAPS 1 "13 August 2005"
|
||||
.SH NAME
|
||||
.B
|
||||
YAPS
|
||||
\- converts an abc file to a PostScript file
|
||||
.SH SYNOPSIS
|
||||
yaps \fiabc\ file\fP [\-d] [\-e\ <list>] [\-E] [\-l] [\-M \fiXXXxYYY\fP] \
|
||||
[\-N] [\-k nn] [\-o \fifile\ name\fP] [\-P \-\fiss\fP] [\-s \fiXX\fP] [\-V]\
|
||||
[\-ver] [\-x] [\-OCC]
|
||||
|
||||
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -d
|
||||
For debugging only. Displays the internal data structures used in the program.
|
||||
.TP
|
||||
.B -e \fi<list>\fP
|
||||
Draws tunes with reference numbers in a comma separated list. Spaces are
|
||||
not allowed but a range of reference numbers can be specified. For example,
|
||||
1,3,7-10.
|
||||
.TP
|
||||
.B -E
|
||||
Generates Encapsulated Postscript output.
|
||||
.TP
|
||||
.B -M \fiXXXxYYY\fb
|
||||
Set margin sizes in points where 28.3 points = 1cm and 72 points = 1 inch.
|
||||
.TP
|
||||
.B -N
|
||||
Adds page numbering.
|
||||
.TP
|
||||
.B -k [nn]
|
||||
Adds bar numbering. If number nn is included, then every nn'th bar
|
||||
is numbered. Otherwise all bars are numbered.
|
||||
.TP
|
||||
.B -o \fifilename\fP
|
||||
Specifies the output postscript file name.
|
||||
.TP
|
||||
.B -P \fiss\fP
|
||||
Specifies the paper size where 0 is A4 and 1 is US Letter
|
||||
or XXXxYYY sets the paper size in point units.
|
||||
units.
|
||||
.TP
|
||||
.B -s \fiXX\fP
|
||||
Specifies the scaling factor (default is 0.7)
|
||||
.TP
|
||||
.B -V
|
||||
Voices are printed out separately for a multi-voice tune. Otherwise they
|
||||
are interleaved.
|
||||
|
||||
.TP
|
||||
.B -ver
|
||||
Prints version number and exits.
|
||||
.TP
|
||||
.B -x
|
||||
Print tune number in X: field
|
||||
.TP
|
||||
.B -OCC
|
||||
Required if the tune uses the old convention for chords delineated
|
||||
with +..+ instead of [...].
|
||||
|
||||
.SH FEATURES
|
||||
|
||||
.PP
|
||||
* Uses the abc2midi parsing code, so hopefully compatibility with
|
||||
abc2midi will be good.
|
||||
.PP
|
||||
* Measures the width of lyric text for lyric typesetting.
|
||||
.PP
|
||||
* Uses dynamically extensible data structures in most places, so
|
||||
you should not be restricted by compiled-in limits.
|
||||
.PP
|
||||
* Multiple voices drawn with notes played at the same time aligned.
|
||||
.PP
|
||||
* Supports special characters using ISO latin 1 font. Special
|
||||
characters are created with a TeX-like code e.g. \'E or a 3 digit octal
|
||||
code e.g. \315 .
|
||||
.PP
|
||||
* Supports the following clefs : baritone, tenor, alto, mezzo, soprano,
|
||||
treble, bass. Recommended use is
|
||||
.PP
|
||||
* Invisible rests (x) are displayed like normal rests.
|
||||
.PP
|
||||
* Nonnumeric voice id's, eg. V: soprano are accepted.
|
||||
.PP
|
||||
I:clef=bass
|
||||
.PP
|
||||
To make it easier to enter tunes in clefs othan than treble clef,
|
||||
yaps supports I:octave=-1 to indicate that a C in the tune represents
|
||||
the note one octave below the pitch defined in the abc standard. These
|
||||
may be combined in one I: statement e.g.
|
||||
.PP
|
||||
I:clef=bass octave=-2
|
||||
.PP
|
||||
You can also use clefs that are one, two or three octaves higher or
|
||||
lower than normal using e.g. treble-8, treble+15, treble-22. The clef is
|
||||
drawn with a small 8, 15 or 22 above or below the clef symbol. The clef=
|
||||
and octave= commands may also go in the K: field e.g.
|
||||
.PP
|
||||
K:G clef=bass-8 octave=-3
|
||||
.PP
|
||||
Note that there is an incompatibility between the behaviour of yaps and
|
||||
the behaviour of abc2ps 1.3.3. abc2ps 1.3.3 does not support the
|
||||
I:octave=N command, but selecting certain clefs causes it to automatically
|
||||
transpose by several octaves. You can produce abc that works for both by
|
||||
following the clef change with an I:octave=N command to do the transpose
|
||||
that abc2ps does automatically.
|
||||
.PP
|
||||
* Produces boxed part labels.
|
||||
.PP
|
||||
* Supports the segno symbol with !segno! and coda with !coda! . Other
|
||||
musical instructions such as !fine! and !D.C.! come out as text.
|
||||
* Supports the U: field for abbreviating symbols to single characters. e.g.
|
||||
.PP
|
||||
U:S = !segno!
|
||||
.PP
|
||||
allows S to be used to produce the segno symbol. Currently this only
|
||||
allows new symbols to be defined and does not allow the existing
|
||||
pre-defined symbols M,L,R,H and T to be altered.
|
||||
.PP
|
||||
* Supports the !red! and !black! instructions for switching from
|
||||
black to red or vice-versa.
|
||||
.PP
|
||||
* Supports the following abc2ps extensions to abc :
|
||||
.PP
|
||||
%%newpage - start a new page,
|
||||
.br
|
||||
%%vskip N - adds vertical space of N points. If N is followed by
|
||||
'cm' or 'in' the units are taken as centimetres or
|
||||
inches instead of points e.g. 4cm.
|
||||
.br
|
||||
%%text - print text
|
||||
.br
|
||||
%%centre (or %%center for Americans) - print centred text.
|
||||
.br
|
||||
If %%text or %%centre appear in the header, the text appears above
|
||||
the tune.
|
||||
.PP
|
||||
%%staffsep SIZE - set the vertical blank space between 2 consecutive
|
||||
music staves.
|
||||
.PP
|
||||
%%titleleft N - select title placed to the left or centred. N = 1
|
||||
places the title on the left while N = 0 centres it.
|
||||
.br
|
||||
%%titlecaps - title is displayed in upper case (capital) letters.
|
||||
.br
|
||||
%%textfont NAME SIZE - select font called NAME and point size SIZE
|
||||
for text produced by %%text or %%centre. If only NAME is given, the
|
||||
font stays the same size. Likewise, if '-' is given as the NAME,
|
||||
only the font size changes.
|
||||
.br
|
||||
%%titlefont NAME SIZE - select font for title.
|
||||
.br
|
||||
%%subtitlefont NAME SIZE - select font for titles after the first
|
||||
title.
|
||||
.br
|
||||
%%composerfont NAME SIZE - select font for words in C: and O: fields
|
||||
and part specifier (P: in header).
|
||||
.br
|
||||
%%wordsfont NAME SIZE - select font for words in W: fields.
|
||||
.br
|
||||
%%partsfont NAME SIZE - select font for boxed parts and
|
||||
!instruction! .
|
||||
.br
|
||||
%%vocalfont NAME SIZE - select font for words in w: fields.
|
||||
.br
|
||||
%%gchordfont NAME SIZE - select font for guitar chords in the music.
|
||||
(It is advisable not to change the font name for the last two, since
|
||||
the program calculates the width of strings using default fonts)
|
||||
.br
|
||||
%%titlespace, %%subtitlespace, %%textspace, %%composerspace,
|
||||
%%wordsspace, %%partsspace, %%vocalspace and %%gchordspace
|
||||
determine the amount of space left above the relevant type
|
||||
of text. Each of these should be followed by a size in points
|
||||
or value in centrimetres or inches.
|
||||
.br
|
||||
e.g. %%composerfont 3
|
||||
%%titlefont 2cm
|
||||
.PP
|
||||
* Supports placing of accompaniment chords either above or below the
|
||||
stave.
|
||||
.PP
|
||||
%%chordsabove - places accompaniment chords above the stave
|
||||
(default).
|
||||
.br
|
||||
%%chordsbelow - places accompaniment chords below the stave.
|
||||
.PP
|
||||
* Supports optional text enclosed in quotes before and after the
|
||||
tempo specification in the Q: field. This extension comes from
|
||||
abc2ps.
|
||||
|
||||
.SH AUTHOR
|
||||
James Allwright <J.R.Allwright@westminster.ac.uk>
|
||||
.SH SUPPORTED
|
||||
Seymour Shlien <fy733@ncf.ca>
|
||||
.PP
|
||||
More complete documentation can be found in abcguide.txt which
|
||||
comes with the abcMIDI distribution package.
|
||||
.SH VERSION
|
||||
This man page describes version 1.39 August 13 2005.
|
||||
|
||||
211
doc/yapshelp.txt
Normal file
211
doc/yapshelp.txt
Normal file
@@ -0,0 +1,211 @@
|
||||
|
||||
YAPS - an abc to PostScript Converter
|
||||
|
||||
YAPS is Yet Another abc to PostScript converter.
|
||||
|
||||
The original converter was Michael Methfessel's abc2ps program. Another
|
||||
converter is abcm2ps, based on the abc2ps code. YAPS uses the library
|
||||
of PostScript routines from abc2ps, but the parser and other C code does
|
||||
not come from abc2ps.
|
||||
|
||||
What is PostScript ?
|
||||
--------------------
|
||||
This program is intended for converting an abc tune to high quality
|
||||
printed output. If yaps created an image file in, say, GIF
|
||||
or PNG format it would have to decide how many pixels wide and how
|
||||
many pixels high the final image would be. When the image was printed
|
||||
on a printer capable of much higher resolution, you would be able to
|
||||
see that the image was built up of lower resolution pixels. PostScript
|
||||
gets round this limitation by storing the image as a description of
|
||||
all the objects that will appear on the page. These descriptions are
|
||||
converted to pixels at the last moment, when the resolution of the
|
||||
printer is known. This way, you can make full use of the resolution
|
||||
available.
|
||||
|
||||
If you are lucky, you may have a PostScript printer, in which case
|
||||
you can send the output of yaps directly to the printer. If not,
|
||||
there are PostScript interpreter programs available, which will
|
||||
turn a PostScript image into other image formats. A popular freely
|
||||
available PostScript interpreter is called GhostScript. Another
|
||||
freely available program, GSView, provides a graphical interface
|
||||
to GhostScript and lets you view images on-screen.
|
||||
|
||||
For a full description of the PostScript language, see "PostScript
|
||||
Language Reference (third edition)" by Adobe Systems Inc.
|
||||
|
||||
----------------------------------------------------------------
|
||||
Executing yaps with no filename will give the yaps version and the
|
||||
following message:
|
||||
|
||||
Usage: yaps <abc file> [<options>]
|
||||
possible options are -
|
||||
-d : debug - display data structure
|
||||
-e <list> : draw tunes with reference numbers in list
|
||||
list is comma-separated and may contain ranges
|
||||
but no spaces e.g. 1,3,7-20
|
||||
-E : generate Encapsulated PostScript
|
||||
-l : landscape mode
|
||||
-M XXXxYYY : set margin sizes in points
|
||||
28.3 points = 1cm, 72 points = 1 inch
|
||||
-N : add page numbering
|
||||
-k [NN] : number every bar or every NN th bar
|
||||
-o <filename> : specify output file
|
||||
-P ss : paper size; 0 is A4, 1 is US Letter
|
||||
or XXXxYYY to set size in points
|
||||
-s XX : scaling factor (default is 0.7)
|
||||
-V : separate voices in multi-voice tune
|
||||
-x : print tune number in X: field
|
||||
Takes an abc music file and converts it to PostScript.
|
||||
If no output filename is given, then by default it is
|
||||
the input filename but with extension .ps .
|
||||
|
||||
YAPS features
|
||||
-------------
|
||||
|
||||
1. Uses the abc2midi parsing code, so hopefully compatibility with
|
||||
abc2midi will be good.
|
||||
|
||||
2. Measures the width of lyric text for lyric typesetting.
|
||||
|
||||
3. Uses dynamically extensible data structures in most places, so
|
||||
you should not be restricted by compiled-in limits.
|
||||
|
||||
4. Multiple voices drawn with notes played at the same time aligned.
|
||||
|
||||
5. Supports special characters using ISO latin 1 font. Special
|
||||
characters are created with a TeX-like code e.g. \'E or a 3 digit octal
|
||||
code e.g. \315 .
|
||||
|
||||
6. Supports the following clefs : baritone, tenor, alto, mezzo, soprano,
|
||||
treble, bass. Recommended use is
|
||||
|
||||
I:clef=bass
|
||||
|
||||
To make it easier to enter tunes in clefs othan than treble clef,
|
||||
yaps supports I:octave=-1 to indicate than a C in the tune represents
|
||||
the note one octave below the pitch defined in the abc standard. These
|
||||
may be combined in one I: statement e.g.
|
||||
|
||||
I:clef=bass octave=-2
|
||||
|
||||
You can also use clefs that are one, two or three octaves higher or
|
||||
lower than normal using e.g. treble-8, treble+15, treble-22. The clef is
|
||||
drawn with a small 8, 15 or 22 above or below the clef symbol. The clef=
|
||||
and octave= commands may also go in the K: field e.g.
|
||||
|
||||
K:G clef=bass-8 octave=-3
|
||||
|
||||
Note that there is an incompatibility between the behaviour of yaps and
|
||||
the behaviour of abc2ps 1.3.3. abc2ps 1.3.3 does not support the
|
||||
I:octave=N command, but selecting certain clefs causes it to automatically
|
||||
transpose by several octaves. You can produce abc that works for both by
|
||||
following the clef change with an I:octave=N command to do the transpose
|
||||
that abc2ps does automatically.
|
||||
|
||||
7. Produces boxed part labels.
|
||||
|
||||
8. Supports the segno symbol with !segno! and coda with !coda! . Other
|
||||
musical instructions such as !fine! and !D.C.! come out as text.
|
||||
|
||||
9. Supports the U: field for abbreviating symbols to single characters.
|
||||
e.g.
|
||||
|
||||
U:S = !segno!
|
||||
|
||||
allows S to be used to produce the segno symbol. Currently this only
|
||||
allows new symbols to be defined and does not allow the existing
|
||||
pre-defined symbols M,L,R,H and T to be altered.
|
||||
|
||||
10. Supports the following abc2ps extensions to abc :
|
||||
|
||||
%%newpage - start a new page,
|
||||
%%vskip N - adds vertical space of N points. If N is followed by
|
||||
'cm' or 'in' the units are taken as centimetres or inches
|
||||
instead of points e.g. 4cm.
|
||||
%%text - print text
|
||||
%%centre (or %%center for Americans) - print centred text.
|
||||
|
||||
If %%text or %%centre appear in the header, the text appears above the
|
||||
tune.
|
||||
|
||||
%%staffsep SIZE - set vertical blank space between 2 consecutive music
|
||||
staves.
|
||||
%%titleleft N - select title placed to the left or centred. N = 1 places
|
||||
the title on the left while N = 0 centres it.
|
||||
%%titlecaps - title is displayed in upper case (capital) letters.
|
||||
%%textfont NAME SIZE - select font called NAME and point size SIZE for
|
||||
text produced by %%text or %%centre. If only NAME is given, the font
|
||||
stays the same size. Likewise, if '-' is given as the NAME, only the
|
||||
font size changes.
|
||||
|
||||
%%titlefont NAME SIZE - select font for title.
|
||||
%%subtitlefont NAME SIZE - select font for titles after the first title.
|
||||
%%composerfont NAME SIZE - select font for words in C: and O: fields and
|
||||
part specifier (P: in header).
|
||||
%%wordsfont NAME SIZE - select font for words in W: fields.
|
||||
%%partsfont NAME SIZE - select font for boxed parts and !instruction! .
|
||||
%%vocalfont NAME SIZE - select font for words in w: fields.
|
||||
%%gchordfont NAME SIZE - select font for guitar chords in the music.
|
||||
(It is advisable not to change the font name for the last two, since
|
||||
the program calculates the width of strings using default fonts)
|
||||
|
||||
%%titlespace, %%subtitlespace, %%textspace, %%composerspace, %%wordsspace,
|
||||
%%partsspace, %%vocalspace and %%gchordspace determine the amount of
|
||||
space left above the relevant type of text. Each of these should be
|
||||
followed by a size in points or value in centrimetres or inches.
|
||||
|
||||
e.g. %%composerfont 3
|
||||
%%titlefont 2cm
|
||||
|
||||
11. Supports placing of accompaniment chords either above or below the
|
||||
stave.
|
||||
|
||||
%%chordsabove - places accompaniment chords above the stave (default).
|
||||
%%chordsbelow - places accompaniment chords below the stave.
|
||||
|
||||
12. Supports optional text enclosed in quotes before and after the
|
||||
tempo specification in the Q: field. This extension comes from abc2ps.
|
||||
|
||||
13. Allows highlighting notes by switching output from black to
|
||||
red and vice-versa using the !red! and !black! instructions.
|
||||
|
||||
Known bugs and Limitations
|
||||
--------------------------
|
||||
1. Overfull lines of music are not split over multiple lines.
|
||||
|
||||
WARNING - the -s option is now used for scaling. Selecting separate
|
||||
printing of each voice (which previously used -s) is now done with -V.
|
||||
|
||||
YAPS is still under development and missing a number of features. However,
|
||||
it should produce acceptable output most of the time. You may want to try
|
||||
abc2ps or abcm2ps if you find that YAPS will not do what you want.
|
||||
|
||||
Viewing PostScript Files from DOS
|
||||
---------------------------------
|
||||
Here is how I arranged things so that I can view PostScript from DOS :
|
||||
|
||||
1. Install Ghostscript 5.10 (compiled to run under DOS). This is not
|
||||
totally straightforward; you have to install the fonts separately and
|
||||
then set the environment variable GS_LIB to a path containing the
|
||||
GhostScript initialization files and the fonts.
|
||||
2. Install Pictview, a free image viewer.
|
||||
3. Create a small batch file ps.bat containing the following line:
|
||||
|
||||
c:\gs5.10\gs386 -r120 -sOutputFile=out.tif -sDEVICE=tiffg3 -sPAPERSIZE=a4 -dNOPAUSE -dBATCH %1
|
||||
|
||||
When you run this, it creates a TIFF file out.tif containing all
|
||||
pages in compressed format.
|
||||
|
||||
The following commands will show you the dots for an abc file:
|
||||
|
||||
yaps demo.abc
|
||||
ps demo.ps
|
||||
pictview out.tif
|
||||
|
||||
|
||||
Copyright (c) James Allwright 1999
|
||||
(parts of the code Copyright Michael Methfessel).
|
||||
This code may be freely re-distributed under the terms of the
|
||||
GNU public license. You are encouraged to modify and redistribute it,
|
||||
provided this copyright notice is retained.
|
||||
|
||||
3619
drawtune.c
Normal file
3619
drawtune.c
Normal file
File diff suppressed because it is too large
Load Diff
29
drawtune.h
Normal file
29
drawtune.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* drawtune.h - part of yaps */
|
||||
/* this file declares the routines in drawtune.c that are used elsewhere */
|
||||
|
||||
/* for Microsoft Visual C++ version 6.0 or higher */
|
||||
|
||||
extern int eps_out;
|
||||
/* bounding box for encapsulated PostScript */
|
||||
struct bbox {
|
||||
int llx, lly, urx, ury;
|
||||
};
|
||||
#ifdef ANSILIBS
|
||||
extern void setmargins(char* s);
|
||||
extern void setpagesize(char* s);
|
||||
extern void open_output_file(char* filename, struct bbox* boundingbox);
|
||||
extern void close_output_file(void);
|
||||
extern void newpage(void);
|
||||
extern void centretext(char* s);
|
||||
extern void lefttext(char* s);
|
||||
extern void vskip(double gap);
|
||||
#else
|
||||
extern void setmargins();
|
||||
extern void setpagesize();
|
||||
extern void open_output_file();
|
||||
extern void close_output_file();
|
||||
extern void newpage();
|
||||
extern void centretext();
|
||||
extern void lefttext();
|
||||
extern void vskip();
|
||||
#endif
|
||||
39
genmidi.h
Normal file
39
genmidi.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/* genmidi.h - part of abc2midi */
|
||||
/* function prototypes for functions in genmidi.c used elsewhere */
|
||||
|
||||
#ifndef KANDR
|
||||
/* functions required by store.c */
|
||||
extern void reduce(int* a, int* b);
|
||||
extern void set_meter(int a, int b);
|
||||
extern void set_gchords(char *s);
|
||||
extern void set_drums(char *s);
|
||||
extern void addunits(int a, int b);
|
||||
/* required by queues.c */
|
||||
extern void midi_noteoff(long delta_time, int pitch, int chan);
|
||||
extern void progress_sequence(int i);
|
||||
#else
|
||||
/* functions required by store.c */
|
||||
extern void reduce();
|
||||
extern void set_meter();
|
||||
extern void set_gchords();
|
||||
extern void addunits();
|
||||
extern void set_drums();
|
||||
/* required by queues.c */
|
||||
extern void midi_noteoff();
|
||||
extern void progress_sequence();
|
||||
#endif
|
||||
|
||||
|
||||
/* introduced 2010-02-01 (feb 01) [SS] */
|
||||
struct trackstruct {enum {NOTES, WORDS, NOTEWORDS, GCHORDS, DRUMS, DRONE} tracktype;
|
||||
int voicenum;
|
||||
int midichannel; /* [SS] 2015-03-24 */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* some definitions formerly in tomidi.c */
|
||||
#define DIV 480
|
||||
#define MAXPARTS 100
|
||||
#define MAXCHORDNAMES 80
|
||||
524
install-sh
Normal file
524
install-sh
Normal file
@@ -0,0 +1,524 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2010-02-06.18; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
nl='
|
||||
'
|
||||
IFS=" "" $nl"
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit=${DOITPROG-}
|
||||
if test -z "$doit"; then
|
||||
doit_exec=exec
|
||||
else
|
||||
doit_exec=$doit
|
||||
fi
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_glob='?'
|
||||
initialize_posix_glob='
|
||||
test "$posix_glob" != "?" || {
|
||||
if (set -f) 2>/dev/null; then
|
||||
posix_glob=
|
||||
else
|
||||
posix_glob=:
|
||||
fi
|
||||
}
|
||||
'
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
no_target_directory=
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *' '* | *'
|
||||
'* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t) dst_arg=$2
|
||||
shift;;
|
||||
|
||||
-T) no_target_directory=true;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names starting with `-'.
|
||||
case $src in
|
||||
-*) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dst=$dst_arg
|
||||
# Protect names starting with `-'.
|
||||
case $dst in
|
||||
-*) dst=./$dst;;
|
||||
esac
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test -n "$no_target_directory"; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dst=$dstdir/`basename "$src"`
|
||||
dstdir_status=0
|
||||
else
|
||||
# Prefer dirname, but fall back on a substitute if dirname fails.
|
||||
dstdir=`
|
||||
(dirname "$dst") 2>/dev/null ||
|
||||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
|
||||
X"$dst" : 'X\(//\)[^/]' \| \
|
||||
X"$dst" : 'X\(//\)$' \| \
|
||||
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
|
||||
echo X"$dst" |
|
||||
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)[^/].*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\/\)$/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
/^X\(\/\).*/{
|
||||
s//\1/
|
||||
q
|
||||
}
|
||||
s/.*/./; q'
|
||||
`
|
||||
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writeable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
-*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
eval "$initialize_posix_glob"
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
$posix_glob set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
$posix_glob set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test -z "$d" && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
|
||||
eval "$initialize_posix_glob" &&
|
||||
$posix_glob set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
$posix_glob set +f &&
|
||||
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
69
legacy_code/casecmp.c
Normal file
69
legacy_code/casecmp.c
Normal file
@@ -0,0 +1,69 @@
|
||||
static int casecmp(s1, s2)
|
||||
/* case-insensitive compare 2 strings */
|
||||
/* return 0 if equal */
|
||||
/* 1 if s1 > s2 */
|
||||
/* -1 if s1 > s2 */
|
||||
char s1[];
|
||||
char s2[];
|
||||
{
|
||||
int i, val, done;
|
||||
char c1, c2;
|
||||
|
||||
i = 0;
|
||||
done = 0;
|
||||
while (done == 0) {
|
||||
c1 = tolower(s1[i]);
|
||||
c2 = tolower(s2[i]);
|
||||
if (c1 > c2) {
|
||||
val = 1;
|
||||
done = 1;
|
||||
} else {
|
||||
if (c1 < c2) {
|
||||
val = -1;
|
||||
done = 1;
|
||||
} else {
|
||||
if (c1 == '\0') {
|
||||
val = 0;
|
||||
done = 1;
|
||||
} else {
|
||||
i = i + 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
return(val);
|
||||
}
|
||||
|
||||
static int stringcmp(s1, s2)
|
||||
/* case sensitive compare 2 strings */
|
||||
/* return 0 if equal */
|
||||
/* 1 if s1 > s2 */
|
||||
/* -1 if s1 > s2 */
|
||||
char s1[];
|
||||
char s2[];
|
||||
{
|
||||
int i, val, done;
|
||||
|
||||
i = 0;
|
||||
done = 0;
|
||||
while (done == 0) {
|
||||
if (s1[i] > s2[i]) {
|
||||
val = 1;
|
||||
done = 1;
|
||||
} else {
|
||||
if (s1[i] < s2[i]) {
|
||||
val = -1;
|
||||
done = 1;
|
||||
} else {
|
||||
if (s1[i] == '\0') {
|
||||
val = 0;
|
||||
done = 1;
|
||||
} else {
|
||||
i = i + 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
return(val);
|
||||
}
|
||||
|
||||
146
makefiles/djgpp.mak
Normal file
146
makefiles/djgpp.mak
Normal file
@@ -0,0 +1,146 @@
|
||||
# DJGPP (DOS port of gcc) Makefile for abcMIDI package
|
||||
#
|
||||
#
|
||||
# compilation #ifdefs - you may need to change these defined to get
|
||||
# the code to compile with a different C compiler.
|
||||
#
|
||||
# NOFTELL in midifile.c and genmidi.c selects a version of the file-writing
|
||||
# code which doesn't use file seeking.
|
||||
#
|
||||
# PCCFIX in mftext.c midifile.c midi2abc.c
|
||||
# comments out various things that aren't available in PCC
|
||||
#
|
||||
# USE_INDEX causes index() to be used instead of strchr(). This is needed
|
||||
# by some pre-ANSI C compilers.
|
||||
#
|
||||
# ASCTIME causes asctime() to be used instead of strftime() in pslib.c.
|
||||
# If ANSILIBS is not set, neither routine is used.
|
||||
#
|
||||
# ANSILIBS causes code to include some ANSI standard headers
|
||||
#
|
||||
# KANDR selects functions prototypes without argument prototypes.
|
||||
#
|
||||
# NO_SNPRINTF causes code to use printf instead of snprintf which
|
||||
# is less secure.
|
||||
CC=gcc
|
||||
CFLAGS=-c -ansi -DANSILIBS -DNO_SNPRINTF -Wformat -Wtraditional
|
||||
# -ansi forces ANSI compliance
|
||||
LNK=gcc
|
||||
|
||||
all : abc2midi.exe midi2abc.exe abc2abc.exe mftext.exe yaps.exe\
|
||||
midicopy.exe abcmatch.exe
|
||||
|
||||
abc2midi.exe : parseabc.o store.o genmidi.o queues.o midifile.o parser2.o
|
||||
$(LNK) -o abc2midi.exe parseabc.o genmidi.o store.o \
|
||||
queues.o midifile.o parser2.o stresspat.o -lm
|
||||
|
||||
abc2abc.exe : parseabc.o toabc.o
|
||||
$(LNK) -o abc2abc.exe parseabc.o toabc.o
|
||||
|
||||
midi2abc.exe : midifile.o midi2abc.o
|
||||
$(LNK) midifile.o midi2abc.o -o midi2abc.exe -lm
|
||||
|
||||
mftext.exe : midifile.o mftext.o crack.o
|
||||
$(LNK) midifile.o mftext.o crack.o -o mftext.exe
|
||||
|
||||
midicopy.exe : midicopy.o
|
||||
$(LNK) midicopy.o -o midicopy.exe
|
||||
|
||||
abcmatch.exe : abcmatch.o matchsup.o parseabc.o
|
||||
$(LNK) abcmatch.o matchsup.o parseabc.o -o abcmatch.exe
|
||||
|
||||
|
||||
|
||||
yaps.exe : parseabc.o yapstree.o drawtune.o debug.o pslib.o position.o parser2.o
|
||||
$(LNK) -o yaps.exe parseabc.o yapstree.o drawtune.o debug.o \
|
||||
position.o pslib.o parser2.o
|
||||
|
||||
# common parser object code
|
||||
#
|
||||
parseabc.o : parseabc.c abc.h parseabc.h
|
||||
$(CC) $(CFLAGS) parseabc.c
|
||||
|
||||
parser2.o : parser2.c parseabc.h parser2.h
|
||||
$(CC) $(CFLAGS) parser2.c
|
||||
|
||||
# objects needed by abc2abc
|
||||
#
|
||||
toabc.o : toabc.c abc.h parseabc.h
|
||||
$(CC) $(CFLAGS) toabc.c
|
||||
|
||||
# objects needed by abc2midi
|
||||
#
|
||||
store.o : store.c abc.h parseabc.h parser2.h genmidi.h
|
||||
$(CC) $(CFLAGS) store.c
|
||||
|
||||
genmidi.o : genmidi.c abc.h midifile.h genmidi.h
|
||||
$(CC) $(CFLAGS) genmidi.c
|
||||
|
||||
stresspat.o: stresspat.c
|
||||
$(CC) $(CFLAGS) stresspat.c
|
||||
|
||||
# could use -DNOFTELL here
|
||||
tomidi.o : tomidi.c abc.h midifile.h
|
||||
$(CC) $(CFLAGS) tomidi.c
|
||||
|
||||
queues.o: queues.c genmidi.h
|
||||
$(CC) $(CFLAGS) queues.c
|
||||
|
||||
midicopy.o: midicopy.c midicopy.h
|
||||
$(CC) $(CFLAGS) midicopy.c
|
||||
|
||||
abcmatch.o: abcmatch.c abc.h
|
||||
$(CC) $(CFLAGS) abcmatch.c
|
||||
|
||||
|
||||
|
||||
# common midifile library
|
||||
#
|
||||
# could use -DNOFTELL here
|
||||
midifile.o : midifile.c midifile.h
|
||||
$(CC) $(CFLAGS) midifile.c
|
||||
|
||||
# objects needed by yaps
|
||||
#
|
||||
yapstree.o: yapstree.c abc.h parseabc.h structs.h drawtune.h parser2.h
|
||||
$(CC) $(CFLAGS) yapstree.c
|
||||
|
||||
drawtune.o: drawtune.c structs.h sizes.h abc.h drawtune.h
|
||||
$(CC) $(CFLAGS) drawtune.c
|
||||
|
||||
pslib.o: pslib.c drawtune.h
|
||||
$(CC) $(CFLAGS) pslib.c
|
||||
|
||||
position.o: position.c abc.h structs.h sizes.h
|
||||
$(CC) $(CFLAGS) position.c
|
||||
|
||||
debug.o: debug.c structs.h abc.h
|
||||
$(CC) $(CFLAGS) debug.c
|
||||
|
||||
# objects needed by midi2abc
|
||||
#
|
||||
midi2abc.o : midi2abc.c midifile.h
|
||||
$(CC) $(CFLAGS) midi2abc.c
|
||||
|
||||
# objects for mftext
|
||||
#
|
||||
crack.o : crack.c
|
||||
$(CC) $(CFLAGS) crack.c
|
||||
|
||||
mftext.o : mftext.c midifile.h
|
||||
$(CC) $(CFLAGS) mftext.c
|
||||
|
||||
# objects for abcmatch
|
||||
#
|
||||
matchsup.o : matchsup.c abc.h parseabc.h parser2.h
|
||||
$(CC) $(CFLAGS) matchsup.c
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
del *.o
|
||||
del *.exe
|
||||
|
||||
zipfile: midi2abc.exe abc2midi.exe mftext.exe yaps.exe\
|
||||
abc2abc.exe midicopy.exe
|
||||
zip pcexe2.zip *.exe readme.txt abcguide.txt demo.abc yaps.txt
|
||||
143
makefiles/makefile.bcc
Normal file
143
makefiles/makefile.bcc
Normal file
@@ -0,0 +1,143 @@
|
||||
# Borland command line compiler bcc version 5.5 Makefile for abcMIDI package
|
||||
# Can also use mingw or gnu standard make program with this makefile.
|
||||
#
|
||||
#
|
||||
# compilation #ifdefs - you may need to change these defined to get
|
||||
# the code to compile with a different C compiler.
|
||||
#
|
||||
# NOFTELL in midifile.c and tomidi.c selects a version of the file-writing
|
||||
# code which doesn't use file seeking.
|
||||
#
|
||||
# PCCFIX in mftext.c midifile.c midi2abc.c
|
||||
# comments out various things that aren't available in PCC
|
||||
#
|
||||
# USE_INDEX causes index() to be used instead of strchr(). This is needed
|
||||
# by some pre-ANSI C compilers.
|
||||
#
|
||||
# ASCTIME causes asctime() to be used instead of strftime() in pslib.c.
|
||||
# If ANSILIBS is not set, neither routine is used.
|
||||
#
|
||||
# ANSILIBS causes code to include some ANSI standard headers
|
||||
#
|
||||
# KANDR selects functions prototypes without argument prototypes.
|
||||
#
|
||||
# If your Borland compiler is in another path, change the include
|
||||
# and library options below in CFLAGS and LDFLAGS.
|
||||
#
|
||||
CC=bcc32
|
||||
CFLAGS=-g0 -v -WC -c -I/bcc55/include
|
||||
LNK=ilink32
|
||||
LDFLAGS=/ap /L\bcc55\lib c0x32.obj
|
||||
LDFLAGS2=import32.lib cw32.lib
|
||||
|
||||
all : abc2midi.exe midi2abc.exe abc2abc.exe mftext.exe yaps.exe midicopy.exe abcmatch.exe
|
||||
|
||||
abc2midi.exe : parseabc.obj store.obj genmidi.obj queues.obj midifile.obj parser2.obj stresspat.obj -lm
|
||||
$(LNK) $(LDFLAGS) parseabc.obj genmidi.obj store.obj \
|
||||
queues.obj midifile.obj parser2.obj stresspat.obj, abc2midi.exe,, $(LDFLAGS2)
|
||||
|
||||
abc2abc.exe : parseabc.obj toabc.obj
|
||||
$(LNK) $(LDFLAGS) parseabc.obj toabc.obj, abc2abc.exe,, $(LDFLAGS2)
|
||||
|
||||
midi2abc.exe : midifile.obj midi2abc.obj
|
||||
$(LNK) $(LDFLAGS) midifile.obj midi2abc.obj, midi2abc.exe,, $(LDFLAGS2)
|
||||
|
||||
mftext.exe : midifile.obj mftext.obj crack.obj
|
||||
$(LNK) $(LDFLAGS) midifile.obj mftext.obj crack.obj, mftext.exe,, $(LDFLAGS2)
|
||||
|
||||
yaps.exe : parseabc.obj yapstree.obj drawtune.obj debug.obj pslib.obj position.obj parser2.obj
|
||||
$(LNK) $(LDFLAGS) parseabc.obj yapstree.obj drawtune.obj debug.obj \
|
||||
position.obj pslib.obj parser2.obj, yaps.exe,, $(LDFLAGS2)
|
||||
|
||||
midicopy.exe: midicopy.obj
|
||||
$(LNK) $(LDFLAGS) midicopy.obj, midicopy.exe,, $(LDFLAGS2)
|
||||
|
||||
abcmatch.exe : abcmatch.obj matchsup.obj parseabc.obj
|
||||
$(LNK) $(LDFLAGS) abcmatch.obj matchsup.obj parseabc.obj, abcmatch.exe,, $(LDFLAGS2)
|
||||
|
||||
|
||||
|
||||
# common parser object code
|
||||
#
|
||||
parseabc.obj : parseabc.c abc.h parseabc.h
|
||||
$(CC) $(CFLAGS) parseabc.c
|
||||
|
||||
parser2.obj : parser2.c parseabc.h parser2.h
|
||||
$(CC) $(CFLAGS) parser2.c
|
||||
|
||||
# objects needed by abc2abc
|
||||
#
|
||||
toabc.obj : toabc.c abc.h parseabc.h
|
||||
$(CC) $(CFLAGS) toabc.c
|
||||
|
||||
# objects needed by abc2midi
|
||||
#
|
||||
store.obj : store.c abc.h parseabc.h parser2.h genmidi.h
|
||||
$(CC) $(CFLAGS) store.c
|
||||
|
||||
genmidi.obj : genmidi.c abc.h midifile.h genmidi.h
|
||||
$(CC) $(CFLAGS) genmidi.c
|
||||
|
||||
stresspat.obj : stresspat.c
|
||||
$(CC) $(CFLAGS) stresspat.c
|
||||
|
||||
queues.obj: queues.c genmidi.h
|
||||
$(CC) $(CFLAGS) queues.c
|
||||
|
||||
# common midifile library
|
||||
#
|
||||
# could use -DNOFTELL here
|
||||
midifile.obj : midifile.c midifile.h
|
||||
$(CC) $(CFLAGS) midifile.c
|
||||
|
||||
# objects needed by yaps
|
||||
#
|
||||
yapstree.obj: yapstree.c abc.h parseabc.h structs.h drawtune.h parser2.h
|
||||
$(CC) $(CFLAGS) yapstree.c
|
||||
|
||||
drawtune.obj: drawtune.c structs.h sizes.h abc.h drawtune.h
|
||||
$(CC) $(CFLAGS) drawtune.c
|
||||
|
||||
pslib.obj: pslib.c drawtune.h
|
||||
$(CC) $(CFLAGS) pslib.c
|
||||
|
||||
position.obj: position.c abc.h structs.h sizes.h
|
||||
$(CC) $(CFLAGS) position.c
|
||||
|
||||
debug.obj: debug.c structs.h abc.h
|
||||
$(CC) $(CFLAGS) debug.c
|
||||
|
||||
# objects needed by midi2abc
|
||||
#
|
||||
midi2abc.obj : midi2abc.c midifile.h
|
||||
$(CC) $(CFLAGS) midi2abc.c
|
||||
|
||||
# objects for mftext
|
||||
#
|
||||
crack.obj : crack.c
|
||||
$(CC) $(CFLAGS) crack.c
|
||||
|
||||
mftext.obj : mftext.c midifile.h
|
||||
$(CC) $(CFLAGS) mftext.c
|
||||
|
||||
# objects for midicopy
|
||||
#
|
||||
midicopy.obj :midicopy.c midicopy.h
|
||||
$(CC) $(CFLAGS) midicopy.c
|
||||
|
||||
# objects for abcmatch
|
||||
#
|
||||
abcmatch.obj : abcmatch.c abc.h
|
||||
$(CC) $(CFLAGS) abcmatch.
|
||||
|
||||
matchsup.obj : matchsup.c abc.h parseabc.h parser2.h
|
||||
$(CC) $(CFLAGS) matchsup.c
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
rm *.obj
|
||||
rm *.exe
|
||||
|
||||
zipfile: midi2abc.exe abc2midi.exe mftext.exe yaps.exe abc2abc.exe midicopy.exe
|
||||
zip pcexe2.zip *.exe readme.txt abcguide.txt demo.abc yaps.txt
|
||||
136
makefiles/makefile.ming
Normal file
136
makefiles/makefile.ming
Normal file
@@ -0,0 +1,136 @@
|
||||
# Mingw Win32 Makefile for abcMIDI package
|
||||
#
|
||||
#
|
||||
# compilation #ifdefs - you may need to change these defined to get
|
||||
# the code to compile with a different C compiler.
|
||||
#
|
||||
# NOFTELL in midifile.c and tomidi.c selects a version of the file-writing
|
||||
# code which doesn't use file seeking.
|
||||
#
|
||||
# PCCFIX in mftext.c midifile.c midi2abc.c
|
||||
# comments out various things that aren't available in PCC
|
||||
#
|
||||
# USE_INDEX causes index() to be used instead of strchr(). This is needed
|
||||
# by some pre-ANSI C compilers.
|
||||
#
|
||||
# ASCTIME causes asctime() to be used instead of strftime() in pslib.c.
|
||||
# If ANSILIBS is not set, neither routine is used.
|
||||
#
|
||||
# ANSILIBS causes code to include some ANSI standard headers
|
||||
#
|
||||
# KANDR selects functions prototypes without argument prototypes.
|
||||
#
|
||||
# If your mingw compiler is in another path, change the include
|
||||
# options below in CFLAGS.
|
||||
#
|
||||
CC=gcc
|
||||
CFLAGS=-c -I/mingw/i386-mingw32/include
|
||||
LNK=gcc
|
||||
LDFLAGS=-o
|
||||
|
||||
all : abc2midi.exe midi2abc.exe abc2abc.exe mftext.exe yaps.exe \
|
||||
midicopy.exe abcmatch.exe
|
||||
|
||||
abc2midi.exe : parseabc.o store.o genmidi.o queues.o midifile.o parser2.o
|
||||
$(LNK) $(LDFLAGS) abc2midi.exe parseabc.o genmidi.o store.o \
|
||||
queues.o midifile.o parser2.o -stresspat.o -lm
|
||||
|
||||
abc2abc.exe : parseabc.o toabc.o
|
||||
$(LNK) $(LDFLAGS) abc2abc.exe parseabc.o toabc.o
|
||||
|
||||
midi2abc.exe : midifile.o midi2abc.o
|
||||
$(LNK) $(LDFLAGS) midi2abc.exe midifile.o midi2abc.o -lm
|
||||
|
||||
mftext.exe : midifile.o mftext.o crack.o
|
||||
$(LNK) $(LDFLAGS) mftext.exe midifile.o mftext.o crack.o
|
||||
|
||||
yaps.exe : parseabc.o yapstree.o drawtune.o debug.o pslib.o position.o parser2.o
|
||||
$(LNK) $(LDFLAGS) yaps.exe parseabc.o yapstree.o drawtune.o debug.o \
|
||||
position.o pslib.o parser2.o
|
||||
|
||||
midicopy.exe: midicopy.o
|
||||
$(LNK) $(LDFLAGS) midicopy.exe midicopy.o
|
||||
|
||||
abcmatch.exe : abcmatch.o matchsup.o parseabc.o
|
||||
$(LNK) abcmatch.o matchsup.o parseabc.o -o abcmatch.exe
|
||||
|
||||
|
||||
|
||||
# common parser object code
|
||||
#
|
||||
parseabc.o : parseabc.c abc.h parseabc.h
|
||||
$(CC) $(CFLAGS) parseabc.c
|
||||
|
||||
parser2.o : parser2.c parseabc.h parser2.h
|
||||
$(CC) $(CFLAGS) parser2.c
|
||||
|
||||
# objects needed by abc2abc
|
||||
#
|
||||
toabc.o : toabc.c abc.h parseabc.h
|
||||
$(CC) $(CFLAGS) toabc.c
|
||||
|
||||
# objects needed by abc2midi
|
||||
#
|
||||
store.o : store.c abc.h parseabc.h parser2.h genmidi.h
|
||||
$(CC) $(CFLAGS) store.c
|
||||
|
||||
genmidi.o : genmidi.c abc.h midifile.h genmidi.h
|
||||
$(CC) $(CFLAGS) genmidi.c
|
||||
|
||||
stresspat.o : stresspat.c
|
||||
$(CC) $(CFLAGS) stresspat.c
|
||||
|
||||
# could use -DNOFTELL here
|
||||
tomidi.o : tomidi.c abc.h midifile.h
|
||||
$(CC) $(CFLAGS) tomidi.c
|
||||
|
||||
queues.o: queues.c genmidi.h
|
||||
$(CC) $(CFLAGS) queues.c
|
||||
|
||||
# common midifile library
|
||||
#
|
||||
# could use -DNOFTELL here
|
||||
midifile.o : midifile.c midifile.h
|
||||
$(CC) $(CFLAGS) midifile.c
|
||||
|
||||
# objects needed by yaps
|
||||
#
|
||||
yapstree.o: yapstree.c abc.h parseabc.h structs.h drawtune.h parser2.h
|
||||
$(CC) $(CFLAGS) yapstree.c
|
||||
|
||||
drawtune.o: drawtune.c structs.h sizes.h abc.h drawtune.h
|
||||
$(CC) $(CFLAGS) drawtune.c
|
||||
|
||||
pslib.o: pslib.c drawtune.h
|
||||
$(CC) $(CFLAGS) pslib.c
|
||||
|
||||
position.o: position.c abc.h structs.h sizes.h
|
||||
$(CC) $(CFLAGS) position.c
|
||||
|
||||
debug.o: debug.c structs.h abc.h
|
||||
$(CC) $(CFLAGS) debug.c
|
||||
|
||||
# objects needed by midi2abc
|
||||
#
|
||||
midi2abc.o : midi2abc.c midifile.h
|
||||
$(CC) $(CFLAGS) midi2abc.c
|
||||
|
||||
# objects for mftext
|
||||
#
|
||||
crack.o : crack.c
|
||||
$(CC) $(CFLAGS) crack.c
|
||||
|
||||
mftext.o : mftext.c midifile.h
|
||||
$(CC) $(CFLAGS) mftext.c
|
||||
|
||||
# objects needed for midicopy
|
||||
#
|
||||
midicopy.o : midicopy.c
|
||||
$(CC) $(CFLAGS) midicopy.c
|
||||
|
||||
clean:
|
||||
rm *.o
|
||||
rm *.exe
|
||||
|
||||
zipfile: midi2abc.exe abc2midi.exe mftext.exe yaps.exe abc2abc.exe midicopy.exe
|
||||
zip pcexe2.zip *.exe readme.txt abcguide.txt demo.abc yaps.txt
|
||||
99
makefiles/makefile.w32
Executable file
99
makefiles/makefile.w32
Executable file
@@ -0,0 +1,99 @@
|
||||
|
||||
# tested with MS Visual C++ 2010 Express
|
||||
# build with:
|
||||
# nmake /F makefiles\makefile.w32 all
|
||||
|
||||
!include <win32.mak>
|
||||
|
||||
# $(cvars) static link
|
||||
# $(cvarsdll) dynamically link
|
||||
# add -O2 to end of line for speed optimization
|
||||
# add -O1 for size optimization
|
||||
#comp = $(cc) /wd4996 -D_CRT_SECURE_NO_WARNINGS $(cflags) $(cvars)
|
||||
comp = $(cc) /wd4996 -D_CRT_SECURE_NO_WARNINGS $(cflags) $(cvarsdll)
|
||||
|
||||
#all: abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch
|
||||
|
||||
all: abc2midi.exe midi2abc.exe abc2abc.exe mftext.exe yaps.exe midicopy.exe abcmatch.exe
|
||||
|
||||
|
||||
abc2midi.exe: parseabc.obj store.obj genmidi.obj midifile.obj queues.obj parser2.obj stresspat.obj
|
||||
$(link) $(conflags) -out:abc2midi.exe parseabc.obj store.obj genmidi.obj queues.obj parser2.obj midifile.obj stresspat.obj
|
||||
|
||||
abcmatch.exe: abcmatch.obj matchsup.obj parseabc.obj
|
||||
$(link) $(conflags) -out:abcmatch.exe abcmatch.obj matchsup.obj parseabc.obj
|
||||
|
||||
midi2abc.exe: midifile.obj midi2abc.obj
|
||||
$(link) $(conflags) -out:midi2abc.exe midifile.obj midi2abc.obj
|
||||
|
||||
abc2abc.exe: parseabc.obj toabc.obj
|
||||
$(link) $(conflags) -out:abc2abc.exe parseabc.obj toabc.obj
|
||||
|
||||
mftext.exe: midifile.obj mftext.obj crack.obj
|
||||
$(link) $(conflags) -out:mftext.exe midifile.obj mftext.obj crack.obj
|
||||
|
||||
midicopy.exe: midicopy.obj
|
||||
$(link) $(conflags) -out:midicopy.exe midicopy.obj
|
||||
|
||||
yaps.exe: parseabc.obj yapstree.obj drawtune.obj debug.obj pslib.obj position.obj parser2.obj
|
||||
$(link) $(conflags) -out:yaps.exe parseabc.obj yapstree.obj drawtune.obj debug.obj position.obj pslib.obj parser2.obj $(conlibs)
|
||||
|
||||
|
||||
abcmatch.obj: abcmatch.c abc.h
|
||||
$(comp) abcmatch.c
|
||||
|
||||
crack.obj: crack.c
|
||||
$(comp) crack.c
|
||||
|
||||
debug.obj: debug.c structs.h abc.h
|
||||
$(comp) debug.c
|
||||
|
||||
drawtune.obj: drawtune.c structs.h sizes.h abc.h drawtune.h
|
||||
$(comp) drawtune.c
|
||||
|
||||
genmidi.obj: genmidi.c abc.h midifile.h genmidi.h
|
||||
$(comp) genmidi.c
|
||||
|
||||
matchsup.obj: matchsup.c abc.h parseabc.h parser2.h
|
||||
$(comp) matchsup.c
|
||||
|
||||
mftext.obj: mftext.c midifile.h
|
||||
$(comp) mftext.c
|
||||
|
||||
midi2abc.obj: midi2abc.c midifile.h
|
||||
$(comp) midi2abc.c
|
||||
|
||||
midifile.obj: midifile.c midifile.h
|
||||
$(comp) midifile.c
|
||||
|
||||
parseabc.obj: parseabc.c abc.h parseabc.h
|
||||
$(comp) parseabc.c
|
||||
|
||||
parser2.obj: parser2.c abc.h parseabc.h parser2.h
|
||||
$(comp) parser2.c
|
||||
|
||||
position.obj: position.c abc.h structs.h sizes.h
|
||||
$(comp) position.c
|
||||
|
||||
pslib.obj: pslib.c drawtune.h
|
||||
$(comp) pslib.c
|
||||
|
||||
queues.obj: queues.c genmidi.h
|
||||
$(comp) queues.c
|
||||
|
||||
store.obj: store.c abc.h parseabc.h midifile.h genmidi.h
|
||||
$(comp) store.c
|
||||
|
||||
stresspat.obj: stresspat.c
|
||||
$(comp) stresspat.c
|
||||
|
||||
toabc.obj: toabc.c abc.h parseabc.h
|
||||
$(comp) toabc.c
|
||||
|
||||
yapstree.obj: yapstree.c abc.h parseabc.h structs.h drawtune.h
|
||||
$(comp) yapstree.c
|
||||
|
||||
|
||||
clean:
|
||||
del *.obj
|
||||
del *.exe
|
||||
141
makefiles/makefile.wat
Normal file
141
makefiles/makefile.wat
Normal file
@@ -0,0 +1,141 @@
|
||||
# Watcom Win32 Makefile for abcMIDI package
|
||||
# Use mingw or gnu standard make program with this makefile.
|
||||
#
|
||||
#
|
||||
# compilation #ifdefs - you may need to change these defined to get
|
||||
# the code to compile with a different C compiler.
|
||||
#
|
||||
# NOFTELL in midifile.c and genmidi.c selects a version of the file-writing
|
||||
# code which doesn't use file seeking.
|
||||
#
|
||||
# PCCFIX in mftext.c midifile.c midi2abc.c
|
||||
# comments out various things that aren't available in PCC
|
||||
#
|
||||
# USE_INDEX causes index() to be used instead of strchr(). This is needed
|
||||
# by some pre-ANSI C compilers.
|
||||
#
|
||||
# ASCTIME causes asctime() to be used instead of strftime() in pslib.c.
|
||||
# If ANSILIBS is not set, neither routine is used.
|
||||
#
|
||||
# ANSILIBS causes code to include some ANSI standard headers
|
||||
#
|
||||
# KANDR selects functions prototypes without argument prototypes.
|
||||
#
|
||||
CC=wcc386
|
||||
CFLAGS=-ic:\\watcom\\h;c:\\watcom\\h\\nt -w4 -e25 -zq -od -d2 -5r -bt=nt -mf -DANSILIBS
|
||||
LDFLAGS=sys nt name
|
||||
LDFLAGS2=d all op inc op st=200000 op maxe=25 op q op symf
|
||||
LNK=wlink
|
||||
|
||||
all : abc2midi.exe midi2abc.exe abc2abc.exe mftext.exe yaps.exe midicopy.exe abcmatch.exe
|
||||
|
||||
abc2midi.exe : parseabc.obj store.obj genmidi.obj queues.obj midifile.obj parser2.obj stresspat.obj -lm
|
||||
$(LNK) $(LDFLAGS) abc2midi.exe $(LDFLAGS2) FILE parseabc.obj FILE genmidi.obj FILE store.obj \
|
||||
FILE queues.obj FILE midifile.obj FILE parser2.obj FILE stresspat.obj
|
||||
|
||||
abc2abc.exe : parseabc.obj toabc.obj
|
||||
$(LNK) $(LDFLAGS) abc2abc.exe $(LDFLAGS2) FILE parseabc.obj FILE toabc.obj
|
||||
|
||||
midi2abc.exe : midifile.obj midi2abc.obj
|
||||
$(LNK) $(LDFLAGS) midi2abc.exe $(LDFLAGS2) FILE midifile.obj FILE midi2abc.obj
|
||||
|
||||
mftext.exe : midifile.obj mftext.obj crack.obj
|
||||
$(LNK) $(LDFLAGS) mftext.exe $(LDFLAGS2) FILE midifile.obj FILE mftext.obj FILE crack.obj
|
||||
|
||||
midicopy.exe : midicopy.obj
|
||||
$(LNK) $(LDFLAGS) midicopy.exe $(LDFLAGS2) FILE midicopy.obj
|
||||
|
||||
yaps.exe : parseabc.obj yapstree.obj drawtune.obj debug.obj pslib.obj position.obj parser2.obj
|
||||
$(LNK) $(LDFLAGS) yaps.exe $(LDFLAGS2) FILE parseabc.obj FILE yapstree.obj FILE drawtune.obj FILE debug.obj FILE position.obj FILE pslib.obj FILE parser2.obj
|
||||
|
||||
|
||||
abcmatch.exe : abcmatch.obj matchsup.obj parseabc.obj
|
||||
$(LNK) $(LDFLAGS) abcmatch.exe $(LDFLAGS2) FILE abcmatch.obj FILE matchsup.obj FILE parseabc.obj
|
||||
|
||||
|
||||
# common parser object code
|
||||
#
|
||||
parseabc.obj : parseabc.c abc.h parseabc.h
|
||||
$(CC) $(CFLAGS) parseabc.c
|
||||
|
||||
parser2.obj : parser2.c parseabc.h parser2.h
|
||||
$(CC) $(CFLAGS) parser2.c
|
||||
|
||||
# objects needed by abc2abc
|
||||
#
|
||||
toabc.obj : toabc.c abc.h parseabc.h
|
||||
$(CC) $(CFLAGS) toabc.c
|
||||
|
||||
# objects needed by abc2midi
|
||||
#
|
||||
store.obj : store.c abc.h parseabc.h parser2.h genmidi.h
|
||||
$(CC) $(CFLAGS) store.c
|
||||
|
||||
genmidi.obj : genmidi.c abc.h midifile.h genmidi.h
|
||||
$(CC) $(CFLAGS) genmidi.c
|
||||
|
||||
stresspat.obj : stresspat.c
|
||||
$(CC) $(CFLAGS) stresspat.c
|
||||
|
||||
# could use -DNOFTELL here
|
||||
tomidi.obj : tomidi.c abc.h midifile.h
|
||||
$(CC) $(CFLAGS) tomidi.c
|
||||
|
||||
queues.obj: queues.c genmidi.h
|
||||
$(CC) $(CFLAGS) queues.c
|
||||
|
||||
# common midifile library
|
||||
#
|
||||
# could use -DNOFTELL here
|
||||
midifile.obj : midifile.c midifile.h
|
||||
$(CC) $(CFLAGS) midifile.c
|
||||
|
||||
# objects needed by yaps
|
||||
#
|
||||
yapstree.obj: yapstree.c abc.h parseabc.h structs.h drawtune.h parser2.h
|
||||
$(CC) $(CFLAGS) yapstree.c
|
||||
|
||||
drawtune.obj: drawtune.c structs.h sizes.h abc.h drawtune.h
|
||||
$(CC) $(CFLAGS) drawtune.c
|
||||
|
||||
pslib.obj: pslib.c drawtune.h
|
||||
$(CC) $(CFLAGS) pslib.c
|
||||
|
||||
position.obj: position.c abc.h structs.h sizes.h
|
||||
$(CC) $(CFLAGS) position.c
|
||||
|
||||
debug.obj: debug.c structs.h abc.h
|
||||
$(CC) $(CFLAGS) debug.c
|
||||
|
||||
# objects needed by midi2abc
|
||||
#
|
||||
midi2abc.obj : midi2abc.c midifile.h
|
||||
$(CC) $(CFLAGS) midi2abc.c
|
||||
|
||||
# objects for mftext
|
||||
#
|
||||
crack.obj : crack.c
|
||||
$(CC) $(CFLAGS) crack.c
|
||||
|
||||
mftext.obj : mftext.c midifile.h
|
||||
$(CC) $(CFLAGS) mftext.c
|
||||
|
||||
# objects for midicopy
|
||||
#
|
||||
midicopy.obj : midicopy.c midicopy.h
|
||||
$(CC) $(CFLAGS) midicopy.c
|
||||
|
||||
#objects for abcmtch
|
||||
#
|
||||
abcmatch.obj : abcmatch.c abc.h
|
||||
$(CC) $(CFLAGS) abcmatch.c
|
||||
|
||||
matchsup.obj : matchsup.c abc.h parseabc.h parser2.h genmidi.h
|
||||
$(CC) $(CFLAGS) matchsup.c
|
||||
|
||||
clean:
|
||||
rm *.obj
|
||||
rm *.exe
|
||||
|
||||
zipfile: midi2abc.exe abc2midi.exe mftext.exe yaps.exe abc2abc.exe abcmatch.exe
|
||||
zip pcexe2.zip *.exe readme.txt abcguide.txt demo.abc yaps.txt
|
||||
139
makefiles/makefile.wd
Normal file
139
makefiles/makefile.wd
Normal file
@@ -0,0 +1,139 @@
|
||||
# Watcom DOS 32 bit Makefile for abcMIDI package
|
||||
# Use mingw or gnu standard make program with this makefile.
|
||||
#
|
||||
#
|
||||
# compilation #ifdefs - you may need to change these defined to get
|
||||
# the code to compile with a different C compiler.
|
||||
#
|
||||
# NOFTELL in midifile.c and genmidi.c selects a version of the file-writing
|
||||
# code which doesn't use file seeking.
|
||||
#
|
||||
# PCCFIX in mftext.c midifile.c midi2abc.c
|
||||
# comments out various things that aren't available in PCC
|
||||
#
|
||||
# USE_INDEX causes index() to be used instead of strchr(). This is needed
|
||||
# by some pre-ANSI C compilers.
|
||||
#
|
||||
# ASCTIME causes asctime() to be used instead of strftime() in pslib.c.
|
||||
# If ANSILIBS is not set, neither routine is used.
|
||||
#
|
||||
# ANSILIBS causes code to include some ANSI standard headers
|
||||
#
|
||||
# KANDR selects functions prototypes without argument prototypes.
|
||||
#
|
||||
CC=wcc386
|
||||
CFLAGS=-ic:\\watcom\\h -w4 -e25 -zq -od -d2 -5r -bt=dos -mf -DANSILIBS
|
||||
LDFLAGS=sys dos4g name
|
||||
LDFLAGS2=d all op inc op st=200000 op maxe=25 op q op symf
|
||||
LNK=wlink
|
||||
|
||||
all : abc2midi.exe midi2abc.exe abc2abc.exe mftext.exe yaps.exe midicopy.exe abcmatch.exe
|
||||
|
||||
abc2midi.exe : parseabc.obj store.obj genmidi.obj queues.obj midifile.obj parser2.obj -lm
|
||||
$(LNK) $(LDFLAGS) abc2midi.exe $(LDFLAGS2) FILE parseabc.obj FILE genmidi.obj FILE store.obj \
|
||||
FILE queues.obj FILE midifile.obj FILE parser2.obj FILE stresspat.obj
|
||||
|
||||
abc2abc.exe : parseabc.obj toabc.obj
|
||||
$(LNK) $(LDFLAGS) abc2abc.exe $(LDFLAGS2) FILE parseabc.obj FILE toabc.obj
|
||||
|
||||
midi2abc.exe : midifile.obj midi2abc.obj
|
||||
$(LNK) $(LDFLAGS) midi2abc.exe $(LDFLAGS2) FILE midifile.obj FILE midi2abc.obj
|
||||
|
||||
mftext.exe : midifile.obj mftext.obj crack.obj
|
||||
$(LNK) $(LDFLAGS) mftext.exe $(LDFLAGS2) FILE midifile.obj FILE mftext.obj FILE crack.obj
|
||||
|
||||
midicopy.exe: midicopy.obj
|
||||
$(LNK) $(LDFLAGS) midicopy.exe $(LDFLAGS2) FILE midicopy.obj
|
||||
|
||||
abcmatch.exe : abcmatch.obj matchsup.obj parseabc.obj
|
||||
$(LNK) $(LDFLAGS) abcmatch.exe $(LDFLAGS) FILE abcmatch.obj matchsup.obj parseabc.obj
|
||||
|
||||
|
||||
|
||||
yaps.exe : parseabc.obj yapstree.obj drawtune.obj debug.obj pslib.obj position.obj parser2.obj
|
||||
$(LNK) $(LDFLAGS) yaps.exe $(LDFLAGS2) FILE parseabc.obj FILE yapstree.obj FILE drawtune.obj FILE debug.obj FILE position.obj FILE pslib.obj FILE parser2.obj
|
||||
|
||||
# common parser object code
|
||||
#
|
||||
parseabc.obj : parseabc.c abc.h parseabc.h
|
||||
$(CC) $(CFLAGS) parseabc.c
|
||||
|
||||
parser2.obj : parser2.c parseabc.h parser2.h
|
||||
$(CC) $(CFLAGS) parser2.c
|
||||
|
||||
# objects needed by abc2abc
|
||||
#
|
||||
toabc.obj : toabc.c abc.h parseabc.h
|
||||
$(CC) $(CFLAGS) toabc.c
|
||||
|
||||
# objects needed by abc2midi
|
||||
#
|
||||
store.obj : store.c abc.h parseabc.h parser2.h genmidi.h
|
||||
$(CC) $(CFLAGS) store.c
|
||||
|
||||
genmidi.obj : genmidi.c abc.h midifile.h genmidi.h
|
||||
$(CC) $(CFLAGS) genmidi.c
|
||||
|
||||
stresspat.obj : stresspat.c
|
||||
$(CC) $(CFLAGS) stresspat.c
|
||||
|
||||
# could use -DNOFTELL here
|
||||
|
||||
queues.obj: queues.c genmidi.h
|
||||
$(CC) $(CFLAGS) queues.c
|
||||
|
||||
# common midifile library
|
||||
#
|
||||
# could use -DNOFTELL here
|
||||
midifile.obj : midifile.c midifile.h
|
||||
$(CC) $(CFLAGS) midifile.c
|
||||
|
||||
# objects needed by yaps
|
||||
#
|
||||
yapstree.obj: yapstree.c abc.h parseabc.h structs.h drawtune.h parser2.h
|
||||
$(CC) $(CFLAGS) yapstree.c
|
||||
|
||||
drawtune.obj: drawtune.c structs.h sizes.h abc.h drawtune.h
|
||||
$(CC) $(CFLAGS) drawtune.c
|
||||
|
||||
pslib.obj: pslib.c drawtune.h
|
||||
$(CC) $(CFLAGS) pslib.c
|
||||
|
||||
position.obj: position.c abc.h structs.h sizes.h
|
||||
$(CC) $(CFLAGS) position.c
|
||||
|
||||
debug.obj: debug.c structs.h abc.h
|
||||
$(CC) $(CFLAGS) debug.c
|
||||
|
||||
# objects needed by midi2abc
|
||||
#
|
||||
midi2abc.obj : midi2abc.c midifile.h
|
||||
$(CC) $(CFLAGS) midi2abc.c
|
||||
|
||||
# objects for mftext
|
||||
#
|
||||
crack.obj : crack.c
|
||||
$(CC) $(CFLAGS) crack.c
|
||||
|
||||
mftext.obj : mftext.c midifile.h
|
||||
$(CC) $(CFLAGS) mftext.c
|
||||
|
||||
# objects for midicopy
|
||||
#
|
||||
midicopy.obj :midicopy.c midicopy.h
|
||||
$(CC) $(CFLAGS) midicopy.c
|
||||
|
||||
# objects for abcmatch
|
||||
#
|
||||
abcmatch.obj :abcmatch.c abc.h
|
||||
$(CC) $(CFLAGS) abcmatch.c
|
||||
|
||||
matchsup.obj :matchsup.c abc.h parseabc.h parser2.h
|
||||
$(CC) $(CFLAGS) matchsup.c
|
||||
|
||||
clean:
|
||||
rm *.obj
|
||||
rm *.exe
|
||||
|
||||
zipfile: midi2abc.exe abc2midi.exe mftext.exe yaps.exe abc2abc.exe
|
||||
zip pcexe2.zip *.exe readme.txt abcguide.txt demo.abc yaps.txt
|
||||
89
makefiles/pcc.mak
Normal file
89
makefiles/pcc.mak
Normal file
@@ -0,0 +1,89 @@
|
||||
# PCC Makefile for abcMIDI package
|
||||
#
|
||||
#
|
||||
# compilation #ifdefs - you need to define some of these to get
|
||||
# the code to compile with PCC.
|
||||
#
|
||||
# NOFTELL in midifile.c and genmidi.c selects a version of the file-writing
|
||||
# code which doesn't use file seeking.
|
||||
#
|
||||
# PCCFIX in mftext.c midifile.c midi2abc.c
|
||||
# comments out various things that aren't available in PCC
|
||||
# and applies a fix needed for file writing
|
||||
#
|
||||
# ANSILIBS causes appropriate ANSI .h files to be #included.
|
||||
#
|
||||
# KANDR selects function prototypes with argument prototypes.
|
||||
#
|
||||
# USE_INDEX replaces calls to strchr() with calls to index().
|
||||
#
|
||||
|
||||
CC=pcc
|
||||
CFLAGS=-nPCCFIX -nNOFTELL -nUSE_INDEX -nKANDR
|
||||
LNK=pccl
|
||||
|
||||
all : abc2midi.exe midi2abc.exe abc2abc.exe mftext.exe yaps.exe midicopy.exe abcmatch.exe
|
||||
|
||||
abc2midi.exe : parseabc.o store.o genmidi.o queues.o midifile.o parser2.o stresspat.o -lm
|
||||
$(LNK) -Lc:\bin\pcc\ -Oabc2midi parseabc.o store.o genmidi.o queues.o midifile.o parser2.o stresspat.o
|
||||
|
||||
abc2abc.exe : parseabc.o toabc.o
|
||||
$(LNK) -Lc:\bin\pcc\ -Oabc2abc parseabc.o toabc.o
|
||||
|
||||
midi2abc.exe : midifile.o midi2abc.o
|
||||
$(LNK) -Lc:\bin\pcc\ midifile.o midi2abc.o -Omidi2abc
|
||||
|
||||
mftext.exe : midifile.o mftext.o crack.o
|
||||
$(LNK) -Lc:\bin\pcc\ midifile.o mftext.o crack.o -Omftext
|
||||
|
||||
midicopy.exe: midicopy.o
|
||||
$(LNK) -Lc:\bin\pcc\ midicopy.o -Omidicopy $(CFLAGS)
|
||||
|
||||
parseabc.o : parseabc.c abc.h parseabc.h
|
||||
$(CC) parseabc.c $(CFLAGS)
|
||||
|
||||
parser2.o : parser2.c abc.h parseabc.h parser2.h
|
||||
$(CC) parser2.c $(CFLAGS)
|
||||
|
||||
toabc.o : toabc.c abc.h parseabc.h
|
||||
$(CC) toabc.c $(CFLAGS)
|
||||
|
||||
genmidi.o : genmidi.c abc.h midifile.h parseabc.h genmidi.h
|
||||
$(CC) genmidi.c $(CFLAGS)
|
||||
|
||||
stresspat.o : stresspat.c
|
||||
$(CC) stresspat.c $(CFLAGS)
|
||||
|
||||
store.o : store.c abc.h midifile.h parseabc.h
|
||||
$(CC) store.c $(CFLAGS)
|
||||
|
||||
queues.o : queues.c genmidi.h
|
||||
$(CC) queues.c $(CFLAGS)
|
||||
|
||||
midifile.o : midifile.c midifile.h
|
||||
$(CC) midifile.c $(CFLAGS)
|
||||
|
||||
midi2abc.o : midi2abc.c midifile.h
|
||||
$(CC) midi2abc.c $(CFLAGS)
|
||||
|
||||
crack.o : crack.c
|
||||
$(CC) crack.c $(CFLAGS)
|
||||
|
||||
mftext.o : mftext.c midifile.h
|
||||
$(CC) mftext.c $(CFLAGS)
|
||||
|
||||
midicopy.o : midicopy.c
|
||||
$(CC) midicopy.c $(CFLAGS)
|
||||
|
||||
abcmatch.o : abcmatch.c
|
||||
$(CC) abcmatch.c $(CFLAGS)
|
||||
|
||||
matchsup.o : matchsup.c
|
||||
$(CC) matchsup.c $(CFLAGS)
|
||||
|
||||
clean:
|
||||
del *.exe
|
||||
del *.o
|
||||
|
||||
zipfile: abc2midi.exe midi2abc.exe abc2abc.exe mftext.exe midicopy.exe abcmatch.exe
|
||||
zip pcexe.zip *.exe readme.txt abcguide.txt demo.abc
|
||||
131
makefiles/unix.mak
Normal file
131
makefiles/unix.mak
Normal file
@@ -0,0 +1,131 @@
|
||||
# Generic unix/gcc Makefile for abcMIDI package
|
||||
#
|
||||
#
|
||||
# compilation #ifdefs - you need to compile with these defined to get
|
||||
# the code to compile with PCC.
|
||||
#
|
||||
# NOFTELL in midifile.c and genmidi.c selects a version of the file-writing
|
||||
# code which doesn't use file seeking.
|
||||
#
|
||||
# PCCFIX in mftext.c midifile.c midi2abc.c
|
||||
# comments out various things that aren't available in PCC
|
||||
#
|
||||
# ANSILIBS includes some ANSI header files (which gcc can live without,
|
||||
# but other compilers may want).
|
||||
#
|
||||
# USE_INDEX causes index() to be used instead of strchr(). This is needed
|
||||
# by some pre-ANSI C compilers.
|
||||
#
|
||||
# ASCTIME causes asctime() to be used instead of strftime() in pslib.c.
|
||||
# If ANSILIBS is not set, neither routine is used.
|
||||
#
|
||||
# KANDR selects functions prototypes without argument prototypes.
|
||||
# currently yaps will only compile in ANSI mode.
|
||||
#
|
||||
#
|
||||
# On running make, you may get the mysterious message :
|
||||
#
|
||||
# ', needed by `parseabc.o'. Stop `abc.h
|
||||
#
|
||||
# This means you are using GNU make and this file is in DOS text format. To
|
||||
# cure the problem, change this file from using PC-style end-of-line (carriage
|
||||
# return and line feed) to unix style end-of-line (line feed).
|
||||
|
||||
CC=gcc
|
||||
CFLAGS=-DANSILIBS -O2
|
||||
LNK=gcc
|
||||
INSTALL=install
|
||||
|
||||
prefix=/usr/local
|
||||
binaries=abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch
|
||||
|
||||
docdir=share/doc/abcmidi
|
||||
bindir=bin
|
||||
mandir=share/man/man1
|
||||
|
||||
all : abc2midi midi2abc abc2abc mftext yaps midicopy abcmatch
|
||||
|
||||
abc2midi : parseabc.o store.o genmidi.o midifile.o queues.o parser2.o stresspat.o -lm
|
||||
$(LNK) -o abc2midi parseabc.o store.o genmidi.o queues.o \
|
||||
parser2.o midifile.o stresspat.o
|
||||
|
||||
abc2abc : parseabc.o toabc.o
|
||||
$(LNK) -o abc2abc parseabc.o toabc.o
|
||||
|
||||
midi2abc : midifile.o midi2abc.o
|
||||
$(LNK) midifile.o midi2abc.o -o midi2abc -lm
|
||||
|
||||
mftext : midifile.o mftext.o crack.o
|
||||
$(LNK) midifile.o mftext.o crack.o -o mftext
|
||||
|
||||
yaps : parseabc.o yapstree.o drawtune.o debug.o pslib.o position.o parser2.o
|
||||
$(LNK) -o yaps parseabc.o yapstree.o drawtune.o debug.o \
|
||||
position.o pslib.o parser2.o -o yaps
|
||||
|
||||
midicopy : midicopy.o
|
||||
$(LNK) -o midicopy midicopy.o
|
||||
|
||||
abcmatch : abcmatch.o matchsup.o parseabc.o
|
||||
$(LNK) abcmatch.o matchsup.o parseabc.o -o abcmatch
|
||||
|
||||
parseabc.o : parseabc.c abc.h parseabc.h
|
||||
|
||||
parser2.o : parser2.c abc.h parseabc.h parser2.h
|
||||
|
||||
toabc.o : toabc.c abc.h parseabc.h
|
||||
|
||||
# could use -DNOFTELL here
|
||||
genmidi.o : genmidi.c abc.h midifile.h genmidi.h
|
||||
|
||||
stresspat.o : stresspat.c
|
||||
|
||||
store.o : store.c abc.h parseabc.h midifile.h genmidi.h
|
||||
|
||||
queues.o : queues.c genmidi.h
|
||||
|
||||
# could use -DNOFTELL here
|
||||
midifile.o : midifile.c midifile.h
|
||||
|
||||
midi2abc.o : midi2abc.c midifile.h
|
||||
|
||||
midicopy.o : midicopy.c midicopy.h
|
||||
|
||||
abcmatch.o: abcmatch.c abc.h
|
||||
|
||||
crack.o : crack.c
|
||||
|
||||
mftext.o : mftext.c midifile.h
|
||||
|
||||
# objects needed by yaps
|
||||
#
|
||||
yapstree.o: yapstree.c abc.h parseabc.h structs.h drawtune.h
|
||||
|
||||
drawtune.o: drawtune.c structs.h sizes.h abc.h drawtune.h
|
||||
|
||||
pslib.o: pslib.c drawtune.h
|
||||
|
||||
position.o: position.c abc.h structs.h sizes.h
|
||||
|
||||
debug.o: debug.c structs.h abc.h
|
||||
|
||||
#objects for abcmatch
|
||||
#
|
||||
matchsup.o : matchsup.c abc.h parseabc.h parser2.h
|
||||
|
||||
clean :
|
||||
rm *.o ${binaries}
|
||||
|
||||
install: abc2midi midi2abc abc2abc mftext midicopy yaps abcmatch
|
||||
$(INSTALL) -m 755 ${binaries} ${prefix}/${bindir}
|
||||
|
||||
# install documentation
|
||||
test -d ${PREFIX}/share/doc/abcmidi || mkdir -p ${prefix}/${docdir}
|
||||
$(INSTALL) -m 644 doc/*.txt ${prefix}/${docdir}
|
||||
$(INSTALL) -m 644 doc/AUTHORS ${prefix}/${docdir}
|
||||
$(INSTALL) -m 644 doc/CHANGES ${prefix}/${docdir}
|
||||
$(INSTALL) -m 644 VERSION ${prefix}/${docdir}
|
||||
|
||||
# install manpages
|
||||
test -d ${prefix}/${mandir} || mkdir -p ${prefix}/${mandir};
|
||||
$(INSTALL) -m 644 doc/*.1 ${prefix}/${mandir}
|
||||
|
||||
2026
matchsup.c
Normal file
2026
matchsup.c
Normal file
File diff suppressed because it is too large
Load Diff
291
mftext.c
Normal file
291
mftext.c
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* mftext
|
||||
*
|
||||
* Convert a MIDI file to verbose text.
|
||||
*
|
||||
* modified for portability 22/6/98 - error checking on file open failure
|
||||
* removed.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef ANSILIBS
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
#include "midifile.h"
|
||||
|
||||
void initfuncs();
|
||||
void midifile();
|
||||
|
||||
static FILE *F;
|
||||
int SECONDS; /* global that tells whether to display seconds or ticks */
|
||||
int division; /* from the file header */
|
||||
long tempo = 500000; /* the default tempo is 120 beats/minute */
|
||||
|
||||
int filegetc()
|
||||
{
|
||||
return(getc(F));
|
||||
}
|
||||
|
||||
/* for crack */
|
||||
extern int arg_index;
|
||||
|
||||
int main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
FILE *efopen();
|
||||
char *ch;
|
||||
char *crack();
|
||||
|
||||
SECONDS = 0;
|
||||
|
||||
while((ch = crack(argc,argv,"s",0)) != NULL){
|
||||
switch(*ch){
|
||||
case 's' : SECONDS = 1; break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((argc < 2 && !SECONDS) || (argc < 3 && SECONDS))
|
||||
F = stdin;
|
||||
else
|
||||
F = efopen(argv[arg_index],"rb");
|
||||
|
||||
initfuncs();
|
||||
Mf_getc = filegetc;
|
||||
midifile();
|
||||
fclose(F);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
FILE *
|
||||
efopen(name,mode)
|
||||
char *name;
|
||||
char *mode;
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
if ( (f=fopen(name,mode)) == NULL ) {
|
||||
fprintf(stderr,"Error - Cannot open file %s\n",name);
|
||||
exit(0);
|
||||
}
|
||||
return(f);
|
||||
}
|
||||
|
||||
void error(s)
|
||||
char *s;
|
||||
{
|
||||
fprintf(stderr,"Error: %s\n",s);
|
||||
}
|
||||
|
||||
void prtime()
|
||||
{
|
||||
if(SECONDS)
|
||||
printf("Time=%f ",mf_ticks2sec(Mf_currtime,division,tempo));
|
||||
else
|
||||
printf("Time=%ld ",Mf_currtime);
|
||||
}
|
||||
|
||||
void txt_header(format,ntrks,ldivision)
|
||||
int format, ntrks, ldivision;
|
||||
{
|
||||
division = ldivision;
|
||||
printf("Header format=%d ntrks=%d division=%d\n",format,ntrks,division);
|
||||
}
|
||||
|
||||
void txt_trackstart()
|
||||
{
|
||||
printf("Track start\n");
|
||||
}
|
||||
|
||||
void txt_trackend()
|
||||
{
|
||||
printf("Track end\n");
|
||||
}
|
||||
|
||||
void txt_noteon(chan,pitch,vol)
|
||||
int chan, pitch, vol;
|
||||
{
|
||||
prtime();
|
||||
printf("Note on, chan=%d pitch=%d vol=%d\n",chan+1,pitch,vol);
|
||||
}
|
||||
|
||||
void txt_noteoff(chan,pitch,vol)
|
||||
int chan, pitch, vol;
|
||||
{
|
||||
prtime();
|
||||
printf("Note off, chan=%d pitch=%d vol=%d\n",chan+1,pitch,vol);
|
||||
}
|
||||
|
||||
void txt_pressure(chan,pitch,press)
|
||||
int chan, pitch,press;
|
||||
{
|
||||
prtime();
|
||||
printf("Pressure, chan=%d pitch=%d press=%d\n",chan+1,pitch,press);
|
||||
}
|
||||
|
||||
void txt_parameter(chan,control,value)
|
||||
int chan, control, value;
|
||||
{
|
||||
prtime();
|
||||
printf("Parameter, chan=%d c1=%d c2=%d\n",chan+1,control,value);
|
||||
}
|
||||
|
||||
|
||||
/* [SS] 2017-11-16 submitted by Jonathan Hough (msb,lsb interchanged) */
|
||||
void txt_pitchbend(chan,lsb,msb)
|
||||
int chan, msb, lsb;
|
||||
{
|
||||
prtime();
|
||||
printf("Pitchbend, chan=%d lsb=%d msb=%d\n",chan+1,msb,lsb);
|
||||
}
|
||||
|
||||
void txt_program(chan,program)
|
||||
int chan, program;
|
||||
{
|
||||
prtime();
|
||||
printf("Program, chan=%d program=%d\n",chan+1,program);
|
||||
}
|
||||
|
||||
void txt_chanpressure(chan,press)
|
||||
int chan, press;
|
||||
{
|
||||
prtime();
|
||||
printf("Channel pressure, chan=%d pressure=%d\n",chan+1,press);
|
||||
}
|
||||
|
||||
void txt_sysex(leng,mess)
|
||||
int leng;
|
||||
char *mess;
|
||||
{
|
||||
prtime();
|
||||
printf("Sysex, leng=%d\n",leng);
|
||||
}
|
||||
|
||||
void txt_metamisc(type,leng,mess)
|
||||
int type, leng;
|
||||
char *mess;
|
||||
{
|
||||
prtime();
|
||||
printf("Meta event, unrecognized, type=0x%02x leng=%d\n",type,leng);
|
||||
}
|
||||
|
||||
void txt_metaspecial(type,leng,mess)
|
||||
int type, leng;
|
||||
char *mess;
|
||||
{
|
||||
prtime();
|
||||
printf("Meta event, sequencer-specific, type=0x%02x leng=%d\n",type,leng);
|
||||
}
|
||||
|
||||
void txt_metatext(type,leng,mess)
|
||||
int type, leng;
|
||||
char *mess;
|
||||
{
|
||||
static char *ttype[] = {
|
||||
NULL,
|
||||
"Text Event", /* type=0x01 */
|
||||
"Copyright Notice", /* type=0x02 */
|
||||
"Sequence/Track Name",
|
||||
"Instrument Name", /* ... */
|
||||
"Lyric",
|
||||
"Marker",
|
||||
"Cue Point", /* type=0x07 */
|
||||
"Unrecognized"
|
||||
};
|
||||
int unrecognized = (sizeof(ttype)/sizeof(char *)) - 1;
|
||||
register int n, c;
|
||||
register char *p = mess;
|
||||
|
||||
if ( type < 1 || type > unrecognized )
|
||||
type = unrecognized;
|
||||
prtime();
|
||||
printf("Meta Text, type=0x%02x (%s) leng=%d\n",type,ttype[type],leng);
|
||||
printf(" Text = <");
|
||||
for ( n=0; n<leng; n++ ) {
|
||||
c = (*p++) & 0xff;
|
||||
printf( (isprint(c)||isspace(c)) ? "%c" : "\\0x%02x" , c);
|
||||
}
|
||||
printf(">\n");
|
||||
}
|
||||
|
||||
void txt_metaseq(num)
|
||||
int num;
|
||||
{
|
||||
prtime();
|
||||
printf("Meta event, sequence number = %d\n",num);
|
||||
}
|
||||
|
||||
void txt_metaeot()
|
||||
{
|
||||
prtime();
|
||||
printf("Meta event, end of track\n");
|
||||
}
|
||||
|
||||
void txt_keysig(sf,mi)
|
||||
int sf,mi;
|
||||
{
|
||||
prtime();
|
||||
printf("Key signature, sharp/flats=%d minor=%d\n",sf,mi);
|
||||
}
|
||||
|
||||
void txt_tempo(ltempo)
|
||||
long ltempo;
|
||||
{
|
||||
tempo = ltempo;
|
||||
prtime();
|
||||
printf("Tempo, microseconds-per-MIDI-quarter-note=%ld\n",tempo);
|
||||
}
|
||||
|
||||
void txt_timesig(nn,dd,cc,bb)
|
||||
int nn, dd, cc, bb;
|
||||
{
|
||||
int denom = 1;
|
||||
while ( dd-- > 0 )
|
||||
denom *= 2;
|
||||
prtime();
|
||||
printf("Time signature=%d/%d MIDI-clocks/click=%d 32nd-notes/24-MIDI-clocks=%d\n",
|
||||
nn,denom,cc,bb);
|
||||
}
|
||||
|
||||
void txt_smpte(hr,mn,se,fr,ff)
|
||||
int hr, mn, se, fr, ff;
|
||||
{
|
||||
prtime();
|
||||
printf("SMPTE, hour=%d minute=%d second=%d frame=%d fract-frame=%d\n",
|
||||
hr,mn,se,fr,ff);
|
||||
}
|
||||
|
||||
void txt_arbitrary(leng,mess)
|
||||
int leng; /* [SDE] 2020-06-03 */
|
||||
char *mess;
|
||||
{
|
||||
prtime();
|
||||
printf("Arbitrary bytes, leng=%d\n",leng);
|
||||
}
|
||||
|
||||
void initfuncs()
|
||||
{
|
||||
Mf_error = error;
|
||||
Mf_header = txt_header;
|
||||
Mf_trackstart = txt_trackstart;
|
||||
Mf_trackend = txt_trackend;
|
||||
Mf_noteon = txt_noteon;
|
||||
Mf_noteoff = txt_noteoff;
|
||||
Mf_pressure = txt_pressure;
|
||||
Mf_parameter = txt_parameter;
|
||||
Mf_pitchbend = txt_pitchbend;
|
||||
Mf_program = txt_program;
|
||||
Mf_chanpressure = txt_chanpressure;
|
||||
Mf_sysex = txt_sysex;
|
||||
Mf_metamisc = txt_metamisc;
|
||||
Mf_seqnum = txt_metaseq;
|
||||
Mf_eot = txt_metaeot;
|
||||
Mf_timesig = txt_timesig;
|
||||
Mf_smpte = txt_smpte;
|
||||
Mf_tempo = txt_tempo;
|
||||
Mf_keysig = txt_keysig;
|
||||
Mf_seqspecific = txt_metaspecial;
|
||||
Mf_text = txt_metatext;
|
||||
Mf_arbitrary = txt_arbitrary;
|
||||
}
|
||||
4100
midi2abc.c
Normal file
4100
midi2abc.c
Normal file
File diff suppressed because it is too large
Load Diff
2232
midicopy.c
Normal file
2232
midicopy.c
Normal file
File diff suppressed because it is too large
Load Diff
80
midicopy.h
Normal file
80
midicopy.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* definitions for MIDI file writing code */
|
||||
float mf_ticks2sec();
|
||||
long mf_sec2ticks();
|
||||
void mfwrite();
|
||||
void mfread();
|
||||
|
||||
/* MIDI status commands most significant bit is 1 */
|
||||
#define note_off 0x80
|
||||
#define note_on 0x90
|
||||
#define poly_aftertouch 0xa0
|
||||
#define control_change 0xb0
|
||||
#define program_chng 0xc0
|
||||
#define channel_aftertouch 0xd0
|
||||
#define pitch_wheel 0xe0
|
||||
#define system_exclusive 0xf0
|
||||
#define delay_packet (1111)
|
||||
|
||||
/* 7 bit controllers */
|
||||
#define damper_pedal 0x40
|
||||
#define portamento 0x41
|
||||
#define sostenuto 0x42
|
||||
#define soft_pedal 0x43
|
||||
#define general_4 0x44
|
||||
#define hold_2 0x45
|
||||
#define general_5 0x50
|
||||
#define general_6 0x51
|
||||
#define general_7 0x52
|
||||
#define general_8 0x53
|
||||
#define tremolo_depth 0x5c
|
||||
#define chorus_depth 0x5d
|
||||
#define detune 0x5e
|
||||
#define phaser_depth 0x5f
|
||||
|
||||
/* parameter values */
|
||||
#define data_inc 0x60
|
||||
#define data_dec 0x61
|
||||
|
||||
/* parameter selection */
|
||||
#define non_reg_lsb 0x62
|
||||
#define non_reg_msb 0x63
|
||||
#define reg_lsb 0x64
|
||||
#define reg_msb 0x65
|
||||
|
||||
/* Standard MIDI Files meta event definitions */
|
||||
#define meta_event 0xFF
|
||||
#define sequence_number 0x00
|
||||
#define text_event 0x01
|
||||
#define copyright_notice 0x02
|
||||
#define sequence_name 0x03
|
||||
#define instrument_name 0x04
|
||||
#define lyric 0x05
|
||||
#define marker 0x06
|
||||
#define cue_point 0x07
|
||||
#define channel_prefix 0x20
|
||||
#define end_of_track 0x2f
|
||||
#define set_tempo 0x51
|
||||
#define smpte_offset 0x54
|
||||
#define time_signature 0x58
|
||||
#define key_signature 0x59
|
||||
#define sequencer_specific 0x74
|
||||
|
||||
/* Manufacturer's ID number */
|
||||
#define Seq_Circuits (0x01) /* Sequential Circuits Inc. */
|
||||
#define Big_Briar (0x02) /* Big Briar Inc. */
|
||||
#define Octave (0x03) /* Octave/Plateau */
|
||||
#define Moog (0x04) /* Moog Music */
|
||||
#define Passport (0x05) /* Passport Designs */
|
||||
#define Lexicon (0x06) /* Lexicon */
|
||||
#define Tempi (0x20) /* Bon Tempi */
|
||||
#define Siel (0x21) /* S.I.E.L. */
|
||||
#define Kawai (0x41)
|
||||
#define Roland (0x42)
|
||||
#define Korg (0x42)
|
||||
#define Yamaha (0x43)
|
||||
|
||||
/* miscellaneous definitions */
|
||||
#define MThd 0x4d546864
|
||||
#define MTrk 0x4d54726b
|
||||
#define lowerbyte(x) ((unsigned char)(x & 0xff))
|
||||
#define upperbyte(x) ((unsigned char)((x & 0xff00)>>8))
|
||||
1133
midifile.c
Normal file
1133
midifile.c
Normal file
File diff suppressed because it is too large
Load Diff
115
midifile.h
Normal file
115
midifile.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/* definitions for MIDI file parsing code */
|
||||
#include <stdio.h>
|
||||
extern int (*Mf_getc)();
|
||||
extern void (*Mf_header)();
|
||||
extern void (*Mf_trackstart)();
|
||||
extern void (*Mf_trackend)();
|
||||
extern void (*Mf_noteon)();
|
||||
extern void (*Mf_noteoff)();
|
||||
extern void (*Mf_pressure)();
|
||||
extern void (*Mf_parameter)();
|
||||
extern void (*Mf_pitchbend)();
|
||||
extern void (*Mf_program)();
|
||||
extern void (*Mf_chanpressure)();
|
||||
extern void (*Mf_sysex)();
|
||||
extern void (*Mf_metamisc)();
|
||||
extern void (*Mf_seqspecific)();
|
||||
extern void (*Mf_seqnum)();
|
||||
extern void (*Mf_text)();
|
||||
extern void (*Mf_eot)();
|
||||
extern void (*Mf_timesig)();
|
||||
extern void (*Mf_smpte)();
|
||||
extern void (*Mf_tempo)();
|
||||
extern void (*Mf_keysig)();
|
||||
extern void (*Mf_arbitrary)();
|
||||
extern void (*Mf_error)();
|
||||
extern long Mf_currtime;
|
||||
extern int Mf_nomerge;
|
||||
|
||||
/* definitions for MIDI file writing code */
|
||||
extern int (*Mf_putc)();
|
||||
extern long (*Mf_writetrack)();
|
||||
extern int (*Mf_writetempotrack)();
|
||||
float mf_ticks2sec();
|
||||
long mf_sec2ticks();
|
||||
void mfwrite();
|
||||
void mfread();
|
||||
int mf_write_meta_event();
|
||||
int mf_write_midi_event();
|
||||
void mf_write_tempo();
|
||||
void mferror();
|
||||
|
||||
/* MIDI status commands most significant bit is 1 */
|
||||
#define note_off 0x80
|
||||
#define note_on 0x90
|
||||
#define poly_aftertouch 0xa0
|
||||
#define control_change 0xb0
|
||||
#define program_chng 0xc0
|
||||
#define channel_aftertouch 0xd0
|
||||
#define pitch_wheel 0xe0
|
||||
#define system_exclusive 0xf0
|
||||
#define delay_packet (1111)
|
||||
|
||||
/* 7 bit controllers */
|
||||
#define damper_pedal 0x40
|
||||
#define portamento 0x41
|
||||
#define sostenuto 0x42
|
||||
#define soft_pedal 0x43
|
||||
#define general_4 0x44
|
||||
#define hold_2 0x45
|
||||
#define general_5 0x50
|
||||
#define general_6 0x51
|
||||
#define general_7 0x52
|
||||
#define general_8 0x53
|
||||
#define tremolo_depth 0x5c
|
||||
#define chorus_depth 0x5d
|
||||
#define detune 0x5e
|
||||
#define phaser_depth 0x5f
|
||||
|
||||
/* parameter values */
|
||||
#define data_inc 0x60
|
||||
#define data_dec 0x61
|
||||
|
||||
/* parameter selection */
|
||||
#define non_reg_lsb 0x62
|
||||
#define non_reg_msb 0x63
|
||||
#define reg_lsb 0x64
|
||||
#define reg_msb 0x65
|
||||
|
||||
/* Standard MIDI Files meta event definitions */
|
||||
#define meta_event 0xFF
|
||||
#define sequence_number 0x00
|
||||
#define text_event 0x01
|
||||
#define copyright_notice 0x02
|
||||
#define sequence_name 0x03
|
||||
#define instrument_name 0x04
|
||||
#define lyric 0x05
|
||||
#define marker 0x06
|
||||
#define cue_point 0x07
|
||||
#define channel_prefix 0x20
|
||||
#define end_of_track 0x2f
|
||||
#define set_tempo 0x51
|
||||
#define smpte_offset 0x54
|
||||
#define time_signature 0x58
|
||||
#define key_signature 0x59
|
||||
#define sequencer_specific 0x74
|
||||
|
||||
/* Manufacturer's ID number */
|
||||
#define Seq_Circuits (0x01) /* Sequential Circuits Inc. */
|
||||
#define Big_Briar (0x02) /* Big Briar Inc. */
|
||||
#define Octave (0x03) /* Octave/Plateau */
|
||||
#define Moog (0x04) /* Moog Music */
|
||||
#define Passport (0x05) /* Passport Designs */
|
||||
#define Lexicon (0x06) /* Lexicon */
|
||||
#define Tempi (0x20) /* Bon Tempi */
|
||||
#define Siel (0x21) /* S.I.E.L. */
|
||||
#define Kawai (0x41)
|
||||
#define Roland (0x42)
|
||||
#define Korg (0x42)
|
||||
#define Yamaha (0x43)
|
||||
|
||||
/* miscellaneous definitions */
|
||||
#define MThd 0x4d546864
|
||||
#define MTrk 0x4d54726b
|
||||
#define lowerbyte(x) ((unsigned char)(x & 0xff))
|
||||
#define upperbyte(x) ((unsigned char)((x & 0xff00)>>8))
|
||||
3174
parseabc.c
Normal file
3174
parseabc.c
Normal file
File diff suppressed because it is too large
Load Diff
212
parseabc.h
Normal file
212
parseabc.h
Normal file
@@ -0,0 +1,212 @@
|
||||
/* parseabc.h - interface file for abc parser */
|
||||
/* used by abc2midi, abc2abc and yaps */
|
||||
|
||||
/* abc.h must be #included before this file */
|
||||
/* functions and variables provided by parseabc.c */
|
||||
|
||||
/* for Microsoft Visual C++ 6 */
|
||||
#ifdef _MSC_VER
|
||||
#define KANDR
|
||||
#endif
|
||||
|
||||
/* the arg list to event_voice keeps growing; if we put the args into a structure
|
||||
and pass that around, routines that don't need the new ones need not be altered.
|
||||
NB. event_voice is *called* from parseabc.c, the actual procedure is linked
|
||||
in from the program-specific file */
|
||||
/* added middle= stuff */
|
||||
#define V_STRLEN 256 /* [SS] 2017-10-11 increase from 64 */
|
||||
struct voice_params {
|
||||
int gotclef;
|
||||
int gotoctave;
|
||||
int gottranspose;
|
||||
int gotname;
|
||||
int gotsname;
|
||||
int gotmiddle;
|
||||
int gotother; /* [SS] 2011-04-18 */
|
||||
int octave;
|
||||
int transpose;
|
||||
char clefname[V_STRLEN+1];
|
||||
char namestring[V_STRLEN+1];
|
||||
char snamestring[V_STRLEN+1];
|
||||
char middlestring[V_STRLEN+1];
|
||||
char other[V_STRLEN+1]; /* [SS] 2011-04-18 */
|
||||
};
|
||||
|
||||
/* holds a fraction */
|
||||
struct fraction {
|
||||
int num;
|
||||
int denom;
|
||||
};
|
||||
|
||||
|
||||
#ifndef KANDR
|
||||
extern int readnump(char **p);
|
||||
extern int readsnump(char **p);
|
||||
extern int readnumf(char *num);
|
||||
extern void skipspace(char **p);
|
||||
extern int readsnumf(char *s);
|
||||
extern void readstr(char out[], char **in, int limit);
|
||||
extern int getarg(char *option, int argc, char *argv[]);
|
||||
extern int *checkmalloc(int size);
|
||||
extern char *addstring(char *s);
|
||||
extern char *concatenatestring(char *s1, char *s2);
|
||||
extern char *lookup_abbreviation(char symbol);
|
||||
extern int ismicrotone(char **p, int dir);
|
||||
extern void event_normal_tone(void);
|
||||
extern void print_inputline(void);
|
||||
extern void print_inputline_nolinefeed(void);
|
||||
#else
|
||||
extern int readnump();
|
||||
extern int readsnump();
|
||||
extern int readnumf();
|
||||
extern void skipspace();
|
||||
extern int readsnumf();
|
||||
extern void readstr();
|
||||
extern int getarg();
|
||||
extern int *checkmalloc();
|
||||
extern char *addstring();
|
||||
extern char *concatenatestring();
|
||||
extern char *lookup_abbreviation();
|
||||
extern int ismicrotone();
|
||||
extern void event_normal_tone();
|
||||
extern void print_inputline_nolinefeed();
|
||||
#endif
|
||||
extern void parseron();
|
||||
extern void parseroff();
|
||||
|
||||
extern int lineno;
|
||||
|
||||
/* event_X() routines - these are called from parseabc.c */
|
||||
/* the program that uses the parser must supply these routines */
|
||||
#ifndef KANDR
|
||||
extern void event_init(int argc, char *argv[], char **filename);
|
||||
extern void event_text(char *s);
|
||||
extern void event_reserved(char p);
|
||||
extern void event_tex(char *s);
|
||||
extern void event_linebreak(void);
|
||||
extern void event_startmusicline(void);
|
||||
extern void event_endmusicline(char endchar);
|
||||
extern void event_eof(void);
|
||||
extern void event_comment(char *s);
|
||||
extern void event_specific(char *package, char *s);
|
||||
extern void event_specific_in_header(char *package, char *s);
|
||||
extern void event_startinline(void);
|
||||
extern void event_closeinline(void);
|
||||
extern void event_field(char k, char *f);
|
||||
extern void event_words(char *p, int continuation);
|
||||
extern void event_part(char *s);
|
||||
|
||||
|
||||
extern void event_voice(int n, char *s, struct voice_params *params);
|
||||
extern void event_length(int n);
|
||||
extern void event_blankline(void);
|
||||
extern void event_refno(int n);
|
||||
extern void event_tempo(int n, int a, int b, int rel, char *pre, char *post);
|
||||
extern void event_timesig(int n, int m, int dochecking);
|
||||
extern void event_octave(int num, int local);
|
||||
extern void event_info_key(char *key, char *value);
|
||||
extern void event_info(char *s);
|
||||
extern void event_key(int sharps, char *s, int modeindex,
|
||||
char modmap[7], int modmul[7], struct fraction modmicro[7],
|
||||
int gotkey, int gotclef, char *clefname,
|
||||
int octave, int transpose, int gotoctave, int gottranspose,
|
||||
int explict);
|
||||
extern void event_microtone(int dir, int a, int b);
|
||||
extern void event_graceon(void);
|
||||
extern void event_graceoff(void);
|
||||
extern void event_rep1(void);
|
||||
extern void event_rep2(void);
|
||||
extern void event_playonrep(char *s);
|
||||
extern void event_tie(void);
|
||||
extern void event_slur(int t);
|
||||
extern void event_sluron(int t);
|
||||
extern void event_sluroff(int t);
|
||||
extern void event_rest(int decorators[DECSIZE],int n,int m,int type);
|
||||
extern void event_mrest(int n,int m,char c);
|
||||
extern void event_spacing(int n, int m);
|
||||
extern void event_bar(int type, char *replist);
|
||||
extern void event_space(void);
|
||||
extern void event_lineend(char ch, int n);
|
||||
extern void event_broken(int type, int mult);
|
||||
extern void event_tuple(int n, int q, int r);
|
||||
extern void event_chord(void);
|
||||
extern void event_chordon(int chorddecorators[DECSIZE]);
|
||||
extern void event_chordoff(int, int);
|
||||
extern void event_instruction(char *s);
|
||||
extern void event_gchord(char *s);
|
||||
extern void event_note(int decorators[DECSIZE], char accidental, int mult,
|
||||
char note, int xoctave, int n, int m);
|
||||
extern void event_abbreviation(char symbol, char *string, char container);
|
||||
extern void event_acciaccatura();
|
||||
extern void event_start_extended_overlay();
|
||||
extern void event_stop_extended_overlay();
|
||||
extern void event_split_voice();
|
||||
extern void event_temperament();
|
||||
extern void print_voicecodes(void);
|
||||
extern void init_abbreviations();
|
||||
extern void free_abbreviations();
|
||||
extern void parsefile();
|
||||
extern int parsetune();
|
||||
#else
|
||||
extern void event_init();
|
||||
extern void event_text();
|
||||
extern void event_reserved();
|
||||
extern void event_tex();
|
||||
extern void event_linebreak();
|
||||
extern void event_startmusicline();
|
||||
extern void event_endmusicline();
|
||||
extern void event_eof();
|
||||
extern void event_comment();
|
||||
extern void event_specific();
|
||||
extern void event_specific_in_header();
|
||||
extern void event_startinline();
|
||||
extern void event_closeinline();
|
||||
extern void event_field();
|
||||
extern void event_words();
|
||||
extern void event_part();
|
||||
extern void event_voice();
|
||||
extern void event_length();
|
||||
extern void event_blankline();
|
||||
extern void event_refno();
|
||||
extern void event_tempo();
|
||||
extern void event_timesig();
|
||||
extern void event_octave();
|
||||
extern void event_info_key();
|
||||
extern void event_info();
|
||||
extern void event_key();
|
||||
extern void event_microtone();
|
||||
extern void event_graceon();
|
||||
extern void event_graceoff();
|
||||
extern void event_rep1();
|
||||
extern void event_rep2();
|
||||
extern void event_playonrep();
|
||||
extern void event_tie();
|
||||
extern void event_slur();
|
||||
extern void event_sluron();
|
||||
extern void event_sluroff();
|
||||
extern void event_rest();
|
||||
extern void event_mrest();
|
||||
extern void event_spacing();
|
||||
extern void event_bar();
|
||||
extern void event_space();
|
||||
extern void event_lineend();
|
||||
extern void event_broken();
|
||||
extern void event_tuple();
|
||||
extern void event_chord();
|
||||
extern void event_chordon();
|
||||
extern void event_chordoff();
|
||||
extern void event_instruction();
|
||||
extern void event_gchord();
|
||||
extern void event_note();
|
||||
extern void event_ignore();
|
||||
extern void event_abbreviation();
|
||||
extern void event_acciaccatura();
|
||||
extern void event_start_extended_overlay();
|
||||
extern void event_stop_extended_overlay();
|
||||
extern void event_split_voice();
|
||||
extern void print_voicecodes();
|
||||
extern void init_abbreviations();
|
||||
extern void free_abbreviations();
|
||||
extern void parsefile();
|
||||
extern int parsetune();
|
||||
#endif
|
||||
160
parser2.c
Normal file
160
parser2.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/* parser2.c - further parsing */
|
||||
/* part of abc2midi and yaps */
|
||||
/* implements event_info, event_instruction, event_gchord and event_slur */
|
||||
/* also implements event_reserved */
|
||||
/* parser2 requires parseabc, but parseabc does not need parser2 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "abc.h"
|
||||
#include "parseabc.h"
|
||||
#include "parser2.h"
|
||||
|
||||
void event_info(s)
|
||||
char* s;
|
||||
/* An I: field has been encountered. This routine scans the following
|
||||
text to extract items of the form key=value. The equal sign is optional
|
||||
if only one key (eg MIDI, octave, vol, etc.) occurs in the I: field.
|
||||
Otherwise we need to follow each key with an equal sign so that we
|
||||
know that the preceding item was a key.
|
||||
*/
|
||||
{
|
||||
char* key;
|
||||
char* endkey;
|
||||
char* value;
|
||||
char* endvalue;
|
||||
char* lastendvalue;
|
||||
char* newword;
|
||||
char* lastnewword;
|
||||
char* ptr;
|
||||
int doval;
|
||||
|
||||
ptr = s;
|
||||
doval = 0;
|
||||
while (*ptr != '\0') {
|
||||
if (doval == 0) {
|
||||
/* look for key */
|
||||
skipspace(&ptr);
|
||||
key = ptr;
|
||||
while ((*ptr != '\0') && (*ptr != ' ') && (*ptr != '=')) {
|
||||
ptr = ptr + 1;
|
||||
};
|
||||
endkey = ptr;
|
||||
skipspace(&ptr);
|
||||
if (*ptr == '=') {
|
||||
doval = 1;
|
||||
ptr = ptr + 1;
|
||||
skipspace(&ptr);
|
||||
value = ptr;
|
||||
newword = ptr;
|
||||
endvalue = NULL;
|
||||
lastendvalue = NULL;
|
||||
} else {
|
||||
/* [SS] 2015-09-08 */
|
||||
/* assume only one I: key occurs; grab the rest in value */
|
||||
*endkey = '\0'; /* end the key ptr */
|
||||
value = ptr; /* start the value ptr here */
|
||||
event_info_key(key,value);
|
||||
return;
|
||||
};
|
||||
} else {
|
||||
/* look for value */
|
||||
skipspace(&ptr);
|
||||
while ((*ptr != '\0') && (*ptr != ' ') && (*ptr != '=')) {
|
||||
ptr = ptr + 1;
|
||||
};
|
||||
lastendvalue = endvalue;
|
||||
endvalue = ptr;
|
||||
skipspace(&ptr);
|
||||
lastnewword = newword;
|
||||
newword = ptr;
|
||||
if (*ptr == '\0') {
|
||||
*endkey = '\0';
|
||||
*endvalue = '\0';
|
||||
event_info_key(key, value);
|
||||
} else {
|
||||
if (*ptr == '=') {
|
||||
*endkey = '\0';
|
||||
if (lastendvalue == NULL) {
|
||||
event_error("missing key or value in I: field");
|
||||
} else {
|
||||
*lastendvalue = '\0';
|
||||
event_info_key(key, value);
|
||||
};
|
||||
key = lastnewword;
|
||||
endkey = endvalue;
|
||||
doval = 1;
|
||||
ptr = ptr + 1;
|
||||
skipspace(&ptr);
|
||||
value = ptr;
|
||||
endvalue = NULL;
|
||||
lastendvalue = NULL;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
static void splitstring(s, sep, handler)
|
||||
/* breaks up string into fields with sep as the field separator */
|
||||
/* and calls handler() for each sub-string */
|
||||
char* s;
|
||||
char sep;
|
||||
void (*handler)();
|
||||
{
|
||||
char* out;
|
||||
char* p;
|
||||
int fieldcoming;
|
||||
|
||||
p = s;
|
||||
fieldcoming = 1;
|
||||
while (fieldcoming) {
|
||||
out = p;
|
||||
while ((*p != '\0') && (*p != sep)) p = p + 1;
|
||||
if (*p == sep) {
|
||||
*p = '\0';
|
||||
p = p + 1;
|
||||
} else {
|
||||
fieldcoming = 0;
|
||||
};
|
||||
(*handler)(out);
|
||||
};
|
||||
}
|
||||
|
||||
void event_gchord(s)
|
||||
/* handles guitar chords " ... " */
|
||||
char* s;
|
||||
{
|
||||
splitstring(s, ';', event_handle_gchord);
|
||||
}
|
||||
|
||||
void event_instruction(s)
|
||||
/* handles a ! ... ! event in the abc */
|
||||
char* s;
|
||||
{
|
||||
splitstring(s, ';', event_handle_instruction);
|
||||
}
|
||||
|
||||
void event_slur(t)
|
||||
int t;
|
||||
/* handles old 's' notation for slur on/slur off */
|
||||
{
|
||||
if (t) {
|
||||
event_sluron(1);
|
||||
} else {
|
||||
event_sluroff(0);
|
||||
};
|
||||
}
|
||||
|
||||
void event_reserved(char s)
|
||||
/* handles H - Z encountered in abc */
|
||||
{
|
||||
char *expansion;
|
||||
|
||||
expansion = lookup_abbreviation(s);
|
||||
if (expansion != NULL) {
|
||||
event_handle_instruction(expansion);
|
||||
} else {
|
||||
event_x_reserved(s);
|
||||
};
|
||||
}
|
||||
16
parser2.h
Normal file
16
parser2.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/* parser2.h */
|
||||
/* part of abc2midi and yaps */
|
||||
/* provides further parsing of I: info field */
|
||||
/* and multiple instruction and gchord fields */
|
||||
|
||||
#ifndef KANDR
|
||||
extern void event_info_key(char *key, char *value);
|
||||
extern void event_handle_gchord(char *s);
|
||||
extern void event_handle_instruction(char *s);
|
||||
extern void event_x_reserved(char s);
|
||||
#else
|
||||
extern void event_info_key();
|
||||
extern void event_handle_gchord();
|
||||
extern void event_handle_instruction();
|
||||
extern void event_x_reserved();
|
||||
#endif
|
||||
495
position.c
Normal file
495
position.c
Normal file
@@ -0,0 +1,495 @@
|
||||
/*
|
||||
* yaps - program to convert abc files to PostScript.
|
||||
* Copyright (C) 1999 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
|
||||
*
|
||||
*/
|
||||
|
||||
/* position.c */
|
||||
/* part of YAPS - abc to PostScript converter */
|
||||
/* This file contains routines to calculate symbol positions within */
|
||||
/* a line of music. */
|
||||
|
||||
/* for Microsoft Visual C++ 6.0 and higher */
|
||||
#ifdef _MSC_VER
|
||||
#define ANSILIBS
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef ANSILIBS
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include "abc.h"
|
||||
#include "structs.h"
|
||||
#include "sizes.h"
|
||||
|
||||
extern struct tune thetune;
|
||||
extern double scaledwidth;
|
||||
|
||||
static void addfract(f, n, m)
|
||||
struct fract* f;
|
||||
int n, m;
|
||||
/* add n/m to fraction pointed to by f */
|
||||
/* like addunits(), but does not use unitlength */
|
||||
{
|
||||
f->num = n*f->denom + m*f->num;
|
||||
f->denom = m*f->denom;
|
||||
reducef(f);
|
||||
}
|
||||
|
||||
static void mulfract(f, n, m)
|
||||
struct fract* f;
|
||||
int n, m;
|
||||
/* multiply n/m to fraction pointed to by f */
|
||||
/* like addunits(), but does not use unitlength */
|
||||
{
|
||||
f->num = n*f->num;
|
||||
f->denom = m*f->denom;
|
||||
reducef(f);
|
||||
}
|
||||
|
||||
static void advance(struct voice* v, int phase, int* items, double* itemspace, double x)
|
||||
/* move on one symbol in the specified voice */
|
||||
{
|
||||
struct feature* p;
|
||||
struct rest* arest;
|
||||
struct note* anote;
|
||||
struct fract tuplefactor, notelen;
|
||||
int done;
|
||||
int stepon;
|
||||
int zerotime, newline;
|
||||
|
||||
switch(phase) {
|
||||
case 1:
|
||||
zerotime = 1;
|
||||
newline=0;
|
||||
break;
|
||||
case 2:
|
||||
zerotime = 0;
|
||||
newline=0;
|
||||
break;
|
||||
case 3:
|
||||
zerotime = 0;
|
||||
newline=1;
|
||||
break;
|
||||
default:
|
||||
printf("Internal error: phase = %d\n", phase);
|
||||
exit(1);
|
||||
break;
|
||||
};
|
||||
|
||||
*itemspace = 0.0;
|
||||
*items = 0;
|
||||
p = v->place;
|
||||
if (p == NULL) {
|
||||
v->atlineend = 1;
|
||||
};
|
||||
done = 0;
|
||||
while ((p != NULL) && (done==0)) {
|
||||
p->x = (float) (x + p->xleft);
|
||||
stepon = 1;
|
||||
switch(p->type) {
|
||||
case MUSICLINE:
|
||||
v->inmusic = 1;
|
||||
break;
|
||||
case PRINTLINE:
|
||||
v->inmusic = 0;
|
||||
done = 1;
|
||||
if (!newline) {
|
||||
v->atlineend = 1;
|
||||
stepon = 0;
|
||||
};
|
||||
break;
|
||||
case CLEF:
|
||||
case KEY:
|
||||
case TIME:
|
||||
if (!v->inmusic) {
|
||||
break;
|
||||
};
|
||||
case SINGLE_BAR:
|
||||
case DOUBLE_BAR:
|
||||
case BAR_REP:
|
||||
case REP_BAR:
|
||||
case BAR1:
|
||||
case REP_BAR2:
|
||||
case DOUBLE_REP:
|
||||
case THICK_THIN:
|
||||
case THIN_THICK:
|
||||
*itemspace = *itemspace + p->xleft + p->xright;
|
||||
*items = *items + 1;
|
||||
if (!newline) {
|
||||
done = 1;
|
||||
};
|
||||
break;
|
||||
case REST:
|
||||
case NOTE:
|
||||
tuplefactor = v->tuplefactor;
|
||||
if ((zerotime==1) && (!v->ingrace)) {
|
||||
done = 1;
|
||||
stepon = 0;
|
||||
} else {
|
||||
if ((!v->inchord)&&(!newline)) {
|
||||
done = 1;
|
||||
};
|
||||
*itemspace = *itemspace + p->xleft + p->xright;
|
||||
*items = *items + 1;
|
||||
if (p->type == REST) {
|
||||
arest = p->item;
|
||||
addfract(&v->time, arest->len.num, arest->len.denom);
|
||||
};
|
||||
if ((p->type == NOTE) && (!v->ingrace)) {
|
||||
anote = p->item;
|
||||
notelen = anote->len;
|
||||
|
||||
if (anote->tuplenotes >0) {
|
||||
mulfract(¬elen,tuplefactor.num,tuplefactor.denom);
|
||||
}
|
||||
|
||||
|
||||
addfract(&v->time, notelen.num, notelen.denom);
|
||||
/* printf("%c %d/%d %d/%d\n",anote->pitch,notelen.num,notelen.denom,
|
||||
v->time.num,v->time.denom);
|
||||
*/
|
||||
};
|
||||
};
|
||||
break;
|
||||
case CHORDON:
|
||||
if ((zerotime==1)&&(!v->ingrace)) {
|
||||
done = 1;
|
||||
stepon = 0;
|
||||
} else {
|
||||
v->inchord = 1;
|
||||
};
|
||||
break;
|
||||
case CHORDOFF:
|
||||
if (v->inchord == 1) {
|
||||
v->inchord = 0;
|
||||
if ((!v->ingrace)&&(!newline)) {
|
||||
done = 1;
|
||||
};
|
||||
};
|
||||
break;
|
||||
case GRACEON:
|
||||
v->ingrace = 1;
|
||||
break;
|
||||
case GRACEOFF:
|
||||
v->ingrace = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
if (stepon) {
|
||||
p = p->next;
|
||||
} else {
|
||||
done = 1;
|
||||
};
|
||||
};
|
||||
v->place = p;
|
||||
if (p == NULL) {
|
||||
v->atlineend = 1;
|
||||
};
|
||||
}
|
||||
|
||||
static int gefract(struct fract* a, struct fract* b)
|
||||
/* compare two fractions a greater than or equal to b */
|
||||
/* returns (a >= b) */
|
||||
{
|
||||
if ((a->num*b->denom) >= (b->num*a->denom)) {
|
||||
return(1);
|
||||
} else {
|
||||
return(0);
|
||||
};
|
||||
}
|
||||
|
||||
static int gtfract(struct fract* a, struct fract* b)
|
||||
/* compare two fractions a greater than b */
|
||||
/* returns (a > b) */
|
||||
{
|
||||
if ((a->num*b->denom) > (b->num*a->denom)) {
|
||||
return(1);
|
||||
} else {
|
||||
return(0);
|
||||
};
|
||||
}
|
||||
|
||||
static int spacemultiline(struct fract* mastertime, struct tune* t)
|
||||
/* calculate spacing for one line (but possibly multiple voices) */
|
||||
{
|
||||
int i;
|
||||
int items, thisitems, maxitems;
|
||||
int totalitems;
|
||||
double thiswidth, maxwidth;
|
||||
double totalwidth;
|
||||
double x, gap;
|
||||
int done;
|
||||
struct voice* v;
|
||||
struct fract minlen;
|
||||
|
||||
/* two passes - on the second pass, inter-symbol spacing is */
|
||||
/* known so elements can be given their correct x position */
|
||||
gap = 0.0;
|
||||
for (i=0; i<2; i++) {
|
||||
setfract(mastertime, 0, 1);
|
||||
v = firstitem(&t->voices);
|
||||
while (v != NULL) {
|
||||
v->place = v->lineplace;
|
||||
v->ingrace = 0;
|
||||
v->atlineend = 0;
|
||||
setfract(&v->time, 0, 1);
|
||||
v = nextitem(&t->voices);
|
||||
};
|
||||
done = 0;
|
||||
items = 0;
|
||||
x = 0.0;
|
||||
totalitems = 0;
|
||||
totalwidth = 0.0;
|
||||
/* count up items in a line */
|
||||
while (done == 0) {
|
||||
maxitems = 0;
|
||||
maxwidth = 0.0;
|
||||
/* first do zero-time symbols */
|
||||
v = firstitem(&t->voices);
|
||||
while (v != NULL) {
|
||||
if ((!v->atlineend)&&(gefract(mastertime, &v->time))) {
|
||||
advance(v, 1, &thisitems, &thiswidth, x);
|
||||
if (thisitems > maxitems) {
|
||||
maxitems = thisitems;
|
||||
};
|
||||
if (thiswidth > maxwidth) {
|
||||
maxwidth = thiswidth;
|
||||
};
|
||||
};
|
||||
v = nextitem(&t->voices);
|
||||
};
|
||||
if (maxitems == 0) {
|
||||
/* now try moving forward in time */
|
||||
/* advance all voices at or before mastertime */
|
||||
v = firstitem(&t->voices);
|
||||
while (v != NULL) {
|
||||
if ((!v->atlineend)&&(gefract(mastertime, &v->time))) {
|
||||
advance(v, 2, &thisitems, &thiswidth, x);
|
||||
if (thisitems > maxitems) {
|
||||
maxitems = thisitems;
|
||||
};
|
||||
if (thiswidth > maxwidth) {
|
||||
maxwidth = thiswidth;
|
||||
};
|
||||
};
|
||||
v = nextitem(&t->voices);
|
||||
};
|
||||
/* calculate new mastertime */
|
||||
v = firstitem(&t->voices);
|
||||
setfract(&minlen, 0, 1);
|
||||
done = 1;
|
||||
while (v != NULL) {
|
||||
if (!v->atlineend) {
|
||||
done = 0;
|
||||
if (minlen.num == 0) {
|
||||
setfract(&minlen, v->time.num, v->time.denom);
|
||||
} else {
|
||||
if (gtfract(&minlen, &v->time)) {
|
||||
setfract(&minlen, v->time.num, v->time.denom);
|
||||
};
|
||||
};
|
||||
};
|
||||
v = nextitem(&t->voices);
|
||||
};
|
||||
setfract(mastertime, minlen.num, minlen.denom);
|
||||
};
|
||||
totalitems = totalitems + maxitems;
|
||||
totalwidth = totalwidth + maxwidth;
|
||||
if (maxitems > 0) {
|
||||
x = x + maxwidth + gap;
|
||||
};
|
||||
};
|
||||
/* now calculate inter-symbol gap */
|
||||
if (totalitems > 1) {
|
||||
gap = (scaledwidth - totalwidth)/(totalitems-1);
|
||||
} else {
|
||||
gap = 1.0;
|
||||
};
|
||||
if (gap < 0.0) {
|
||||
event_error("Overfull music line");
|
||||
};
|
||||
if (gap > MAXGAP) {
|
||||
event_error("Underfull music line");
|
||||
gap = MAXGAP;
|
||||
};
|
||||
};
|
||||
if (totalitems == 0) {
|
||||
return(1);
|
||||
} else {
|
||||
return(0);
|
||||
};
|
||||
}
|
||||
|
||||
void spacevoices(struct tune* t)
|
||||
{
|
||||
struct fract mastertime;
|
||||
int donelines;
|
||||
struct voice* v;
|
||||
int items;
|
||||
double x1;
|
||||
|
||||
/* initialize voices */
|
||||
v = firstitem(&t->voices);
|
||||
while (v != NULL) {
|
||||
v->lineplace = v->first;
|
||||
v->inmusic=0;
|
||||
v = nextitem(&t->voices);
|
||||
};
|
||||
donelines = 0;
|
||||
while(donelines == 0) {
|
||||
donelines = spacemultiline(&mastertime, t);
|
||||
v = firstitem(&t->voices);
|
||||
while (v != NULL) {
|
||||
v->lineplace = v->place;
|
||||
advance(v, 3, &items, &x1, 0.0);
|
||||
v->lineplace = v->place;
|
||||
v = nextitem(&t->voices);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
static int spaceline(struct voice* v)
|
||||
/* allocate spare space across the width of a single stave line */
|
||||
/* thereby fixing the x position of all notes and other elements */
|
||||
/* returns 0 when the end of the voice is reached, 1 otherwise */
|
||||
{
|
||||
struct feature* p;
|
||||
double x, lastx = 0.0; /* [SDG] 2020-06-03 */
|
||||
int inmusic, items;
|
||||
double itemspace;
|
||||
double gap;
|
||||
|
||||
itemspace = 0.0;
|
||||
items = 0;
|
||||
inmusic = 0;
|
||||
p = v->place;
|
||||
while ((p != NULL) && (p->type != PRINTLINE)) {
|
||||
switch(p->type) {
|
||||
case MUSICLINE:
|
||||
inmusic = 1;
|
||||
break;
|
||||
case PRINTLINE:
|
||||
inmusic = 0;
|
||||
break;
|
||||
case CLEF:
|
||||
case KEY:
|
||||
case TIME:
|
||||
if (!inmusic) {
|
||||
break;
|
||||
};
|
||||
case SINGLE_BAR:
|
||||
case DOUBLE_BAR:
|
||||
case BAR_REP:
|
||||
case REP_BAR:
|
||||
case BAR1:
|
||||
case REP_BAR2:
|
||||
case DOUBLE_REP:
|
||||
case THICK_THIN:
|
||||
case THIN_THICK:
|
||||
case REST:
|
||||
case NOTE:
|
||||
itemspace = itemspace + p->xleft + p->xright;
|
||||
items = items + 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
p = p->next;
|
||||
};
|
||||
if (items > 1) {
|
||||
gap = (scaledwidth - itemspace)/((double)(items-1));
|
||||
} else {
|
||||
gap = 1.0;
|
||||
};
|
||||
if (gap < 0.0) {
|
||||
event_error("Overfull music line");
|
||||
};
|
||||
if (gap > MAXGAP) {
|
||||
event_error("Underfull music line");
|
||||
gap = MAXGAP;
|
||||
};
|
||||
/* now assign positions */
|
||||
x = 0.0;
|
||||
p = v->place;
|
||||
inmusic = 0;
|
||||
while ((p != NULL) && (p->type != PRINTLINE)) {
|
||||
switch(p->type) {
|
||||
case MUSICLINE:
|
||||
inmusic = 1;
|
||||
break;
|
||||
case PRINTLINE:
|
||||
inmusic = 0;
|
||||
break;
|
||||
case CHORDNOTE:
|
||||
p->x = (float) lastx;
|
||||
break;
|
||||
case CLEF:
|
||||
case KEY:
|
||||
case TIME:
|
||||
if (!inmusic) {
|
||||
break;
|
||||
};
|
||||
case SINGLE_BAR:
|
||||
case DOUBLE_BAR:
|
||||
case BAR_REP:
|
||||
case REP_BAR:
|
||||
case BAR1:
|
||||
case REP_BAR2:
|
||||
case DOUBLE_REP:
|
||||
case THICK_THIN:
|
||||
case THIN_THICK:
|
||||
case REST:
|
||||
case NOTE:
|
||||
x = x + p->xleft;
|
||||
p->x = (float) x;
|
||||
lastx = x;
|
||||
x = x + p->xright + gap;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
p = p->next;
|
||||
};
|
||||
while ((p!=NULL)&&((p->type == PRINTLINE)||(p->type==LINENUM))) {
|
||||
p = p->next;
|
||||
};
|
||||
v->place = p;
|
||||
if (p == NULL) {
|
||||
return(0);
|
||||
} else {
|
||||
return(1);
|
||||
};
|
||||
}
|
||||
|
||||
void monospace(struct tune* t)
|
||||
{
|
||||
int doneline;
|
||||
struct voice* v;
|
||||
|
||||
v = firstitem(&t->voices);
|
||||
while (v != NULL) {
|
||||
doneline = 1;
|
||||
v->place = v->first;
|
||||
while (doneline == 1) {
|
||||
doneline = spaceline(v);
|
||||
};
|
||||
v = nextitem(&t->voices);
|
||||
};
|
||||
}
|
||||
18
pt/customstress.txt
Normal file
18
pt/customstress.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
March
|
||||
6/8
|
||||
6 3
|
||||
110 1.2
|
||||
80 0.9
|
||||
80 0.9
|
||||
|
||||
Lesnoto
|
||||
7/8
|
||||
7 7
|
||||
110 1.3
|
||||
90 1.0
|
||||
80 0.7
|
||||
100 1.2
|
||||
90 0.8
|
||||
100 1.2
|
||||
90 0.8
|
||||
|
||||
224
pt/default_stress.txt
Normal file
224
pt/default_stress.txt
Normal file
@@ -0,0 +1,224 @@
|
||||
Hornpipe
|
||||
4/4
|
||||
8 2
|
||||
110 1.40
|
||||
90 0.60
|
||||
|
||||
Hornpipe
|
||||
C|
|
||||
8 2
|
||||
110 1.40
|
||||
90 0.60
|
||||
|
||||
Hornpipe
|
||||
2/4
|
||||
8 2
|
||||
110 1.40
|
||||
90 0.60
|
||||
|
||||
Hornpipe
|
||||
9/4
|
||||
9 3
|
||||
110 1.40
|
||||
80 0.60
|
||||
100 1.00
|
||||
|
||||
Hornpipe
|
||||
3/2
|
||||
12 2
|
||||
110 1.40
|
||||
90 0.60
|
||||
|
||||
Hornpipe
|
||||
12/8
|
||||
12 3
|
||||
110 1.40
|
||||
80 0.60
|
||||
100 1.00
|
||||
|
||||
Double hornpipe
|
||||
6/2
|
||||
12 6
|
||||
110 1.20
|
||||
80 0.90
|
||||
80 0.90
|
||||
105 1.20
|
||||
80 0.90
|
||||
80 0.90
|
||||
|
||||
Reel
|
||||
4/4
|
||||
8 2
|
||||
120 1.10
|
||||
60 0.90
|
||||
|
||||
Reel
|
||||
C|
|
||||
8 8
|
||||
80 1.10
|
||||
60 0.90
|
||||
120 1.10
|
||||
60 0.90
|
||||
80 1.10
|
||||
60 0.90
|
||||
120 1.10
|
||||
60 0.90
|
||||
|
||||
Reel
|
||||
2/4
|
||||
8 2
|
||||
120 1.10
|
||||
60 0.90
|
||||
|
||||
Slip Jig
|
||||
9/8
|
||||
9 3
|
||||
110 1.40
|
||||
70 0.50
|
||||
80 1.10
|
||||
|
||||
Double Jig
|
||||
6/8
|
||||
6 3
|
||||
110 1.20
|
||||
70 0.70
|
||||
80 1.10
|
||||
|
||||
Single Jig
|
||||
6/8
|
||||
6 3
|
||||
110 1.20
|
||||
80 0.70
|
||||
90 1.10
|
||||
|
||||
Slide
|
||||
6/8
|
||||
6 3
|
||||
110 1.30
|
||||
80 0.80
|
||||
90 0.90
|
||||
|
||||
Jig
|
||||
6/8
|
||||
6 3
|
||||
110 1.20
|
||||
80 0.70
|
||||
90 1.10
|
||||
|
||||
Ragtime
|
||||
12/8
|
||||
12 3
|
||||
110 1.40
|
||||
70 0.60
|
||||
90 1.00
|
||||
|
||||
Strathspey
|
||||
C
|
||||
8 2
|
||||
120 1.00
|
||||
80 1.00
|
||||
|
||||
Fling
|
||||
C
|
||||
8 2
|
||||
110 1.40
|
||||
90 0.60
|
||||
|
||||
Set Dance
|
||||
4/4
|
||||
8 2
|
||||
110 1.40
|
||||
90 0.60
|
||||
|
||||
Set Dance
|
||||
C|
|
||||
8 2
|
||||
110 1.40
|
||||
90 0.60
|
||||
|
||||
Waltz
|
||||
3/4
|
||||
3 3
|
||||
110 1.04
|
||||
70 0.98
|
||||
70 0.98
|
||||
|
||||
Slow March
|
||||
C|
|
||||
8 3
|
||||
115 1.10
|
||||
85 0.90
|
||||
100 1.10
|
||||
|
||||
Slow March
|
||||
C
|
||||
8 3
|
||||
115 1.10
|
||||
85 0.90
|
||||
100 1.10
|
||||
|
||||
March
|
||||
C|
|
||||
8 2
|
||||
115 1.10
|
||||
85 0.90
|
||||
|
||||
March
|
||||
C
|
||||
8 4
|
||||
115 1.10
|
||||
85 0.90
|
||||
100 1.10
|
||||
85 0.90
|
||||
|
||||
March
|
||||
6/8
|
||||
6 3
|
||||
110 1.10
|
||||
70 0.95
|
||||
80 0.95
|
||||
|
||||
March
|
||||
2/4
|
||||
8 2
|
||||
115 1.10
|
||||
85 0.90
|
||||
|
||||
Polka k1
|
||||
3/4
|
||||
3 3
|
||||
90 0.75
|
||||
110 1.25
|
||||
100 1.00
|
||||
|
||||
Polka
|
||||
4/4
|
||||
8 2
|
||||
110 1.40
|
||||
90 0.60
|
||||
|
||||
saucy
|
||||
3/4
|
||||
6 6
|
||||
115 1.20
|
||||
85 0.80
|
||||
120 1.30
|
||||
85 0.70
|
||||
115 1.10
|
||||
85 0.90
|
||||
|
||||
Slip jig
|
||||
3/4
|
||||
9 3
|
||||
110 1.30
|
||||
80 0.70
|
||||
100 1.00
|
||||
|
||||
Tango
|
||||
2/4
|
||||
8 4
|
||||
110 1.60
|
||||
90 0.80
|
||||
90 0.80
|
||||
100 0.80
|
||||
|
||||
8
pt/doublejig.txt
Normal file
8
pt/doublejig.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
6
|
||||
110 1.2
|
||||
70 0.7
|
||||
80 1.1
|
||||
110 1.2
|
||||
70 0.7
|
||||
80 1.1
|
||||
|
||||
10
pt/hornpipe.txt
Normal file
10
pt/hornpipe.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
8
|
||||
110 1.4
|
||||
90 0.6
|
||||
110 1.4
|
||||
90 0.6
|
||||
110 1.4
|
||||
90 0.6
|
||||
110 1.4
|
||||
90 0.6
|
||||
|
||||
10
pt/reel.txt
Normal file
10
pt/reel.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
8
|
||||
120 1.1
|
||||
60 0.9
|
||||
120 1.1
|
||||
60 0.9
|
||||
120 1.1
|
||||
60 0.9
|
||||
120 1.1
|
||||
60 0.9
|
||||
|
||||
628
queues.c
Normal file
628
queues.c
Normal file
@@ -0,0 +1,628 @@
|
||||
/*
|
||||
* abc2midi - program to convert abc files to MIDI files.
|
||||
* Copyright (C) 1999 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
|
||||
*
|
||||
*/
|
||||
|
||||
/* queues.c
|
||||
* This file is part of the code for abc2midi.
|
||||
* Notes due to finish in the future are held in a queue (linked list)
|
||||
* in time order. Qhead points to the head of the list and addtoQ()
|
||||
* adds a note to the list. The unused elements of array Q are held
|
||||
* in another linked list pointed to by freehead. The tail is pointed
|
||||
* to by freetail. removefromQ() removes an element (always from the
|
||||
* head of the list) and adds it to the free list. Qinit() initializes
|
||||
* the queue and clearQ() outputs all the remaining notes at the end
|
||||
* of a track.
|
||||
* Qcheck() and PrintQ() are diagnostic routines.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "queues.h"
|
||||
#include "abc.h"
|
||||
#include "genmidi.h"
|
||||
#include "midifile.h"
|
||||
|
||||
void write_event_with_delay(int delta,int event_type,int channel,char* data,int n);
|
||||
|
||||
/* queue for notes waiting to end */
|
||||
/* allows us to do general polyphony */
|
||||
#define QSIZE 50
|
||||
struct Qitem {
|
||||
int delay;
|
||||
int pitch;
|
||||
int chan;
|
||||
int effect; /* [SS] 2012-12-11 */
|
||||
int next;
|
||||
};
|
||||
struct Qitem Q[QSIZE+1];
|
||||
int Qhead, freehead, freetail;
|
||||
extern int totalnotedelay; /* from genmidi.c [SS] */
|
||||
extern int notedelay; /* from genmidi.c [SS] */
|
||||
extern int bendvelocity; /* from genmidi.c [SS] */
|
||||
extern int bendacceleration; /* from genmidi.c [SS] */
|
||||
extern int bendstate; /* from genmidi.c [SS] */
|
||||
/* [SS] 2014-09-10 */
|
||||
extern int benddata[256]; /* from genmidi.c [SS] 2015-09-10 2015-10-03 */
|
||||
extern int bendnvals;
|
||||
extern int controldata[3][256]; /* extended to 256 2015-10-03 */
|
||||
extern int controlnvals[2];
|
||||
extern int controldefaults[128]; /* [SS] 2015-08-10 */
|
||||
extern int nlayers; /* [SS] 2015-08-20 */
|
||||
|
||||
void set_control_defaults() {
|
||||
int i;
|
||||
for (i=0;i<128;i++) controldefaults[i] = 0;
|
||||
controldefaults[7] = 96; /* volume coarse */
|
||||
controldefaults[8] = 64; /* balance coarse */
|
||||
controldefaults[11] = 127; /* expression */
|
||||
controldefaults[10] = 64; /* pan position coarse */
|
||||
}
|
||||
|
||||
/* routines to handle note queue */
|
||||
|
||||
/* genmidi.c communicates with queues.c mainly through the */
|
||||
/* functions addtoQ and timestep. The complexity comes in the */
|
||||
/* handling of chords. When another note in a chord is passed,*/
|
||||
/* addtoQ detemines whether other notes in the Q structure */
|
||||
/* overlap in time with this chord and modifies the delay item*/
|
||||
/* of the note which finish later so that it is relative to the*/
|
||||
/* end of the earlier note. Normally all notes in the chord end*/
|
||||
/* at the same as specifiedy abc standard, so the delay of the*/
|
||||
/* other notes cached in the Q structure should be set to zero.*/
|
||||
|
||||
void addtoQ(num, denom, pitch, chan, effect, d)
|
||||
int num, denom, pitch, chan, d;
|
||||
int effect; /* [SS] 2012-12-11 */
|
||||
{
|
||||
int i, done;
|
||||
int wait;
|
||||
int *ptr;
|
||||
|
||||
/*printf("addtoQ: %d %d %d %d %d\n",num,denom,pitch,chan,d); */
|
||||
|
||||
wait = ((div_factor*num)/denom) + d;
|
||||
/* find free space */
|
||||
if (freehead == -1) {
|
||||
/* printQ(); */
|
||||
event_error("Too many notes in chord - probably missing ']' or '+'");
|
||||
return;
|
||||
} else {
|
||||
i = freehead;
|
||||
freehead = Q[freehead].next;
|
||||
};
|
||||
Q[i].pitch = pitch;
|
||||
Q[i].chan = chan;
|
||||
Q[i].effect = effect; /* [SS] 2012-12-11 */
|
||||
/* find place in queue */
|
||||
ptr = &Qhead;
|
||||
done = 0;
|
||||
while (!done) {
|
||||
if (*ptr == -1) {
|
||||
*ptr = i;
|
||||
Q[i].next = -1;
|
||||
Q[i].delay = wait;
|
||||
done = 1;
|
||||
} else {
|
||||
if (Q[*ptr].delay > wait) {
|
||||
Q[*ptr].delay = Q[*ptr].delay - wait -notedelay;
|
||||
if (Q[*ptr].delay < 0) Q[*ptr].delay = 0;
|
||||
Q[i].next = *ptr;
|
||||
Q[i].delay = wait;
|
||||
*ptr = i;
|
||||
done = 1;
|
||||
} else {
|
||||
wait = wait - Q[*ptr].delay;
|
||||
ptr = &Q[*ptr].next;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
void removefromQ(i)
|
||||
int i;
|
||||
{
|
||||
if (i == -1) {
|
||||
printQ();
|
||||
event_fatal_error("Internal error - nothing to remove from queue");
|
||||
} else {
|
||||
if (Q[Qhead].delay != 0) {
|
||||
printQ();
|
||||
event_fatal_error("Internal error - queue head has non-zero time");
|
||||
};
|
||||
Qhead = Q[i].next;
|
||||
Q[i].next = freehead;
|
||||
freehead = i;
|
||||
};
|
||||
}
|
||||
|
||||
void clearQ()
|
||||
{
|
||||
int time;
|
||||
int i;
|
||||
|
||||
/* remove gchord requests */
|
||||
time = 0;
|
||||
while ((Qhead != -1) && (Q[Qhead].pitch == -1)) {
|
||||
time = time + Q[Qhead].delay;
|
||||
i = Qhead;
|
||||
Qhead = Q[i].next;
|
||||
Q[i].next = freehead;
|
||||
freehead = i;
|
||||
};
|
||||
if (Qhead != -1) {
|
||||
timestep(time, 1);
|
||||
};
|
||||
/* do any remaining note offs, but don't do chord request */
|
||||
while (Qhead != -1) {
|
||||
event_error("Sustained notes beyond end of track");
|
||||
timestep(Q[Qhead].delay+1, 1);
|
||||
};
|
||||
timestep(25,0); /* to avoid transient artefacts at end of track */
|
||||
}
|
||||
|
||||
void printQ()
|
||||
{
|
||||
int t;
|
||||
|
||||
printf("Qhead = %d freehead = %d freetail = %d\n",
|
||||
Qhead, freehead, freetail);
|
||||
t = Qhead;
|
||||
printf("Q:");
|
||||
while (t != -1) {
|
||||
printf("p(%d)-%d->", Q[t].pitch, Q[t].delay);
|
||||
t = Q[t].next;
|
||||
};
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void advanceQ(t)
|
||||
int t;
|
||||
{
|
||||
if (Qhead == -1) {
|
||||
event_error("Internal error - empty queue");
|
||||
} else {
|
||||
Q[Qhead].delay = Q[Qhead].delay - t;
|
||||
};
|
||||
}
|
||||
|
||||
void Qinit()
|
||||
{
|
||||
int i;
|
||||
|
||||
/* initialize queue of notes waiting to finish */
|
||||
Qhead = -1;
|
||||
freehead = 0;
|
||||
for (i=0; i<QSIZE-1; i++) {
|
||||
Q[i].next = i + 1;
|
||||
};
|
||||
Q[QSIZE-1].next = -1;
|
||||
freetail = QSIZE-1;
|
||||
}
|
||||
|
||||
void Qcheck()
|
||||
{
|
||||
int qfree, qused;
|
||||
int nextitem;
|
||||
int used[QSIZE];
|
||||
int i;
|
||||
int failed;
|
||||
|
||||
failed = 0;
|
||||
for (i=0; i<QSIZE; i++) {
|
||||
used[i] = 0;
|
||||
};
|
||||
qused = 0;
|
||||
nextitem = Qhead;
|
||||
while (nextitem != -1) {
|
||||
qused = qused + 1;
|
||||
used[nextitem] = 1;
|
||||
nextitem = Q[nextitem].next;
|
||||
if ((nextitem < -1) || (nextitem >= QSIZE)) {
|
||||
failed = 1;
|
||||
printf("Queue corrupted Q[].next = %d\n", nextitem);
|
||||
};
|
||||
};
|
||||
qfree = 0;
|
||||
nextitem = freehead;
|
||||
while (nextitem != -1) {
|
||||
qfree = qfree + 1;
|
||||
used[nextitem] = 1;
|
||||
nextitem = Q[nextitem].next;
|
||||
if ((nextitem < -1) || (nextitem >= QSIZE)) {
|
||||
failed = 1;
|
||||
printf("Free Queue corrupted Q[].next = %d\n", nextitem);
|
||||
};
|
||||
};
|
||||
if (qfree + qused < QSIZE) {
|
||||
failed = 1;
|
||||
printf("qfree = %d qused = %d\n", qused, qfree);
|
||||
};
|
||||
for (i=0; i<QSIZE; i++) {
|
||||
if (used[i] == 0) {
|
||||
printf("Not used element %d\n", i);
|
||||
failed = 1;
|
||||
};
|
||||
};
|
||||
if (Q[freetail].next != -1) {
|
||||
printf("freetail = %d, Q[freetail].next = %d\n", freetail,
|
||||
Q[freetail].next);
|
||||
};
|
||||
if (failed == 1) {
|
||||
printQ();
|
||||
event_fatal_error("Qcheck failed");
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/* [SS] 2012-12-11 */
|
||||
void note_effect() {
|
||||
/* note_effect is used only if !bend! is called without
|
||||
calling %%MIDI bendstring or %%MIDI bendvelocity [SS] 2015-08-11 */
|
||||
/* Bends a note along the shape of a parabola. The note is
|
||||
split into 8 segments. Given the bendacceleration and
|
||||
initial bend velocity, the new pitch bend is computed
|
||||
for each time segment.
|
||||
*/
|
||||
int delta8;
|
||||
int pitchbend;
|
||||
char data[2];
|
||||
int i;
|
||||
int velocity;
|
||||
delta8 = delta_time/8;
|
||||
pitchbend = bendstate; /* [SS] 2014-09-09 */
|
||||
velocity = bendvelocity;
|
||||
for (i=0;i<8;i++) {
|
||||
pitchbend = pitchbend + velocity;
|
||||
velocity = velocity + bendacceleration;
|
||||
if (pitchbend > 16383) pitchbend = 16383;
|
||||
if (pitchbend < 0) pitchbend = 0;
|
||||
|
||||
data[0] = (char) (pitchbend&0x7f);
|
||||
data[1] = (char) ((pitchbend>>7)&0x7f);
|
||||
mf_write_midi_event(delta8,pitch_wheel,Q[Qhead].chan,data,2);
|
||||
delta_time -= delta8;
|
||||
}
|
||||
midi_noteoff(delta_time, Q[Qhead].pitch, Q[Qhead].chan);
|
||||
pitchbend = bendstate; /* [SS] 2014-09-22 */
|
||||
data[0] = (char) (pitchbend&0x7f);
|
||||
data[1] = (char) ((pitchbend>>7)&0x7f);
|
||||
mf_write_midi_event(delta_time,pitch_wheel,Q[Qhead].chan,data,2);
|
||||
}
|
||||
|
||||
/* [SS] 2014-09-11 */
|
||||
void note_effect2() {
|
||||
/* implements %%MIDI bendstring command. The note is split
|
||||
into n segments where n is the number of pitch shift values
|
||||
supplied in bendstring. For every segment, the pitchbend
|
||||
is shifted by the next pitch shift value.
|
||||
*/
|
||||
int delta;
|
||||
int pitchbend;
|
||||
char data[2];
|
||||
int i;
|
||||
delta = delta_time/bendnvals;
|
||||
pitchbend = bendstate; /* [SS] 2014-09-09 */
|
||||
for (i=0;i<bendnvals;i++) {
|
||||
pitchbend = pitchbend + benddata[i];
|
||||
if (pitchbend > 16383) pitchbend = 16383;
|
||||
if (pitchbend < 0) pitchbend = 0;
|
||||
|
||||
data[0] = (char) (pitchbend&0x7f);
|
||||
data[1] = (char) ((pitchbend>>7)&0x7f);
|
||||
if (i == 0) /* [SS] 2014-09-24 */
|
||||
mf_write_midi_event(0,pitch_wheel,Q[Qhead].chan,data,2);
|
||||
else {
|
||||
mf_write_midi_event(delta,pitch_wheel,Q[Qhead].chan,data,2);
|
||||
delta_time -= delta;
|
||||
}
|
||||
}
|
||||
midi_noteoff(delta_time, Q[Qhead].pitch, Q[Qhead].chan);
|
||||
delta_time = 0; /* [SS] 2014-09-24 */
|
||||
pitchbend = bendstate; /* [SS] 2014-09-09 */
|
||||
data[0] = (char) (pitchbend&0x7f);
|
||||
data[1] = (char) ((pitchbend>>7)&0x7f);
|
||||
mf_write_midi_event(delta_time,pitch_wheel,Q[Qhead].chan,data,2);
|
||||
}
|
||||
|
||||
/* [SS] 2014-09-22 */
|
||||
void note_effect3() {
|
||||
/* handles the %%MIDI bendstring command when only one pitch
|
||||
shift is given.
|
||||
*/
|
||||
int delta;
|
||||
int pitchbend;
|
||||
char data[2];
|
||||
delta =0;
|
||||
pitchbend = bendstate;
|
||||
pitchbend = pitchbend + benddata[0];
|
||||
if (pitchbend > 16383) pitchbend = 16383;
|
||||
if (pitchbend < 0) pitchbend = 0;
|
||||
data[0] = (char) (pitchbend&0x7f);
|
||||
data[1] = (char) ((pitchbend>>7)&0x7f);
|
||||
mf_write_midi_event(delta,pitch_wheel,Q[Qhead].chan,data,2);
|
||||
midi_noteoff(delta_time, Q[Qhead].pitch, Q[Qhead].chan);
|
||||
pitchbend = bendstate;
|
||||
data[0] = (char) (pitchbend&0x7f);
|
||||
data[1] = (char) ((pitchbend>>7)&0x7f);
|
||||
mf_write_midi_event(delta,pitch_wheel,Q[Qhead].chan,data,2); /* [SS] 2014-09-23 */
|
||||
}
|
||||
|
||||
/* [SS] 2015-07-26 */
|
||||
void note_effect4(chan)
|
||||
int chan;
|
||||
{
|
||||
/* Like %%MIDI bendstring, this procedure handles %%MIDI controlstring
|
||||
command. The first value of controlstring indicates the controller
|
||||
to modify. The following values are the values to send to the
|
||||
controller for each note segment.
|
||||
|
||||
This procedure is no longer used. Presently note_effect5()
|
||||
has taken over this operation.
|
||||
*/
|
||||
int delta;
|
||||
char data[2];
|
||||
int controltype,controlval;
|
||||
int i;
|
||||
if (controlnvals[0] <= 1) {
|
||||
event_error("missing %%MIDI controlstring ...");
|
||||
return;
|
||||
}
|
||||
delta = delta_time/(controlnvals[0]-1);
|
||||
controltype = controldata[0][0];
|
||||
if (controltype > 127 || controltype < 0) {
|
||||
event_error("control code muste be in range 0 to 127");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 1;i<controlnvals[0];i++)
|
||||
{
|
||||
controlval = controldata[0][i];
|
||||
if (controlval >127 || controlval < 0) {
|
||||
event_error("control code muste be in range 0 to 127");
|
||||
controlval = 0;
|
||||
}
|
||||
data[0] = controltype;
|
||||
data[1] = controlval;
|
||||
write_event_with_delay(delta,control_change,chan,data,2);
|
||||
delta_time -= delta;
|
||||
}
|
||||
midi_noteoff(delta_time, Q[Qhead].pitch, Q[Qhead].chan);
|
||||
}
|
||||
|
||||
|
||||
/* [SS] 2015-07-30 */
|
||||
struct eventstruc {int time;
|
||||
char cmd;
|
||||
char data1;
|
||||
char data2;};
|
||||
|
||||
int int_compare_events(const void *a, const void *b) {
|
||||
struct eventstruc *ia = (struct eventstruc *)a;
|
||||
struct eventstruc *ib = (struct eventstruc *)b;
|
||||
if (ib->time > ia->time)
|
||||
return -1;
|
||||
else if (ia ->time > ib->time)
|
||||
return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
void print_eventlist(struct eventstruc *list, int nsize) {
|
||||
int i;
|
||||
for (i = 0; i<nsize; i++)
|
||||
printf("%d %d %d %d\n",list[i].time,list[i].cmd,list[i].data1,list[i].data2);
|
||||
}
|
||||
|
||||
/* [SS] 2015-08-03 */
|
||||
void output_eventlist (struct eventstruc *list, int nsize, int chan) {
|
||||
int i;
|
||||
int delta;
|
||||
char cmd,data[2];
|
||||
int miditime;
|
||||
miditime = 0;
|
||||
for (i = 0; i<nsize; i++) {
|
||||
delta = list[i].time - miditime;
|
||||
miditime = list[i].time;
|
||||
data[0] = list[i].data1;
|
||||
data[1] = list[i].data2;
|
||||
cmd = list[i].cmd;
|
||||
if (cmd == -80) write_event_with_delay(delta,control_change,chan,data,2);
|
||||
if (cmd == -32) mf_write_midi_event(delta,pitch_wheel,Q[Qhead].chan,data,2);
|
||||
}
|
||||
}
|
||||
|
||||
/* [SS] 2015-08-01 */
|
||||
void note_effect5(chan)
|
||||
int chan;
|
||||
{
|
||||
/* This procedure merges the controlstring with the
|
||||
bendstring and uses it to shape the note. The control
|
||||
commands are prepared and stored in the eventstruc
|
||||
eventlist[] array, sorted chronologically and sent
|
||||
to the MIDI file.
|
||||
*/
|
||||
struct eventstruc eventlist[1024]; /* extended to 1000 2015-10-03 */
|
||||
int delta=0,notetime,pitchbend; /* [SDG] 2020-06-03 */
|
||||
int last_delta; /* [SS] 2017-06-10 */
|
||||
int initial_bend; /* [SS] 2015-08-25 */
|
||||
int i,j;
|
||||
int layer;
|
||||
int controltype,controlval;
|
||||
char data[2];
|
||||
|
||||
j = 0;
|
||||
pitchbend = bendstate;
|
||||
initial_bend = bendstate;
|
||||
if (bendnvals > 0) {
|
||||
delta = delta_time/bendnvals;
|
||||
notetime = 0;
|
||||
for (i = 0; i <bendnvals; i++) {
|
||||
pitchbend = benddata[i] + pitchbend;
|
||||
if (pitchbend > 16383) {
|
||||
event_error("pitchbend exceeds 16383");
|
||||
pitchbend = 16383;
|
||||
}
|
||||
if (pitchbend < 0) {
|
||||
event_error("pitchbend is less than 0");
|
||||
pitchbend = 0;
|
||||
}
|
||||
eventlist[j].time = notetime;
|
||||
eventlist[j].cmd = pitch_wheel;
|
||||
eventlist[j].data1 = pitchbend & 0x7f;
|
||||
eventlist[j].data2 = (pitchbend >> 7) & 0x7f;
|
||||
notetime += delta;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
for (layer=0;layer <= nlayers;layer++) {
|
||||
if (controlnvals[layer] > 1) {
|
||||
delta = delta_time/(controlnvals[layer] -1);
|
||||
notetime = 0;
|
||||
controltype = controldata[layer][0];
|
||||
if (controltype > 127 || controltype < 0) {
|
||||
event_error("controller must be in range 0 to 127");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 1; i <controlnvals[layer]; i++) {
|
||||
controlval = controldata[layer][i];
|
||||
if (controlval < 0) {
|
||||
event_error("control data must be zero or greater");
|
||||
controlval = 0;
|
||||
}
|
||||
if (controlval > 127) {
|
||||
event_error("control data must be less or equal to 127");
|
||||
controlval = 127;
|
||||
}
|
||||
eventlist[j].time = notetime;
|
||||
eventlist[j].cmd = control_change;
|
||||
eventlist[j].data1 = controltype;
|
||||
eventlist[j].data2 = controlval;
|
||||
notetime += delta;
|
||||
if (j < 1023) j++; /* [SS] increased to 999 2015-10-04 */
|
||||
else event_error("eventlist too complex");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* [SS] 2015-08-23 */
|
||||
if (j > 1) {
|
||||
qsort(eventlist,j,sizeof(struct eventstruc),int_compare_events);
|
||||
/*print_eventlist(eventlist,j); */
|
||||
}
|
||||
output_eventlist(eventlist,j,chan);
|
||||
|
||||
/* [SS] 2015-08-28 */
|
||||
last_delta = delta - eventlist[j-1].time; /* [SS] 2017-06-10 */
|
||||
midi_noteoff(last_delta, Q[Qhead].pitch, Q[Qhead].chan);
|
||||
|
||||
for (layer=0;layer <= nlayers;layer++) {
|
||||
controltype = controldata[layer][0];
|
||||
data[0] = (char) controltype;
|
||||
data[1] = (char) controldefaults[controltype];
|
||||
write_event_with_delay(0,control_change,chan,data,2);
|
||||
}
|
||||
if (bendnvals > 0) {
|
||||
/* restore pitchbend to its original state */
|
||||
pitchbend = initial_bend; /* [SS] 2014-09-25 */
|
||||
data[0] = (char) (pitchbend&0x7f);
|
||||
data[1] = (char) ((pitchbend>>7)&0x7f);
|
||||
write_event_with_delay(0,pitch_wheel,chan,data,2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* timestep is called by delay() in genmidi.c typically at the */
|
||||
/* end of a note, chord or rest. It is also called by clearQ in*/
|
||||
/* this file. Timestep, is not only responsible for sending the*/
|
||||
/* midi_noteoff command for any expired notes in the Q structure*/
|
||||
/* but also maintains the delta_time global variable which is */
|
||||
/* shared with genmidi.c. Timestep also calls advanceQ() in */
|
||||
/* this file which updates all the delay variables for the items */
|
||||
/* in the Q structure to reflect the current MIDI time. Timestep */
|
||||
/* also calls removefromQ in this file which cleans out expired */
|
||||
/* notes from the Q structure. To make things even more complicated*/
|
||||
/* timestep runs the dogchords and the dodrums for bass/chordal */
|
||||
/* and drum accompaniments by calling the function progress_sequence.*/
|
||||
/* Dogchords and dodrums may also call addtoQ changing the contents*/
|
||||
/* of the Q structure array. The tracklen variable in MIDI time */
|
||||
/* units is also maintained here. */
|
||||
|
||||
/* new: delta_time_track0 is declared in queues.h like delta_time */
|
||||
|
||||
void timestep(t, atend)
|
||||
int t;
|
||||
int atend;
|
||||
{
|
||||
int time;
|
||||
int headtime;
|
||||
|
||||
time = t;
|
||||
/* process any notes waiting to finish */
|
||||
while ((Qhead != -1) && (Q[Qhead].delay < time)) {
|
||||
headtime = Q[Qhead].delay;
|
||||
delta_time = delta_time + (long) headtime;
|
||||
delta_time_track0 = delta_time_track0 + (long) headtime; /* [SS] 2010-06-27*/
|
||||
time = time - headtime;
|
||||
advanceQ(headtime);
|
||||
if (Q[Qhead].pitch == -1) {
|
||||
if (!atend) {
|
||||
progress_sequence(Q[Qhead].chan);
|
||||
};
|
||||
} else {
|
||||
if (Q[Qhead].effect == 0) {
|
||||
midi_noteoff(delta_time, Q[Qhead].pitch, Q[Qhead].chan);
|
||||
tracklen = tracklen + delta_time;
|
||||
delta_time = 0L;}
|
||||
else {
|
||||
tracklen = tracklen + delta_time; /* [SS] 2015-06-08 */
|
||||
switch (Q[Qhead].effect) { /* [SS] 2014-09-22 */
|
||||
case 1:
|
||||
note_effect();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
note_effect2();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
note_effect3();
|
||||
break;
|
||||
|
||||
case 10:
|
||||
/*note_effect4(Q[Qhead].chan);*/
|
||||
note_effect5(Q[Qhead].chan);
|
||||
break;
|
||||
}
|
||||
delta_time = 0L;}
|
||||
};
|
||||
|
||||
removefromQ(Qhead);
|
||||
};
|
||||
if (Qhead != -1) {
|
||||
advanceQ(time);
|
||||
};
|
||||
delta_time = delta_time + (long)time - totalnotedelay;
|
||||
delta_time_track0 = delta_time_track0 + (long)time - totalnotedelay; /* [SS] 2010-06-27*/
|
||||
}
|
||||
|
||||
41
queues.h
Normal file
41
queues.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* queues.h - part of abc2midi
|
||||
*/
|
||||
|
||||
/* Notes due to finish in the future are held in a queue (linked list)
|
||||
* in time order. Qhead points to the head of the list and addtoQ()
|
||||
* adds a note to the list. The unused elements of array Q are held
|
||||
* in another linked list pointed to by freehead. The tail is pointed
|
||||
* to by freetail. removefromQ() removes an element (always from the
|
||||
* head of the list) and adds it to the free list. Qinit() initializes
|
||||
* the queue and clearQ() outputs all the remaining notes at the end
|
||||
* of a track.
|
||||
* Qcheck() and PrintQ() are diagnostic routines.
|
||||
*/
|
||||
|
||||
/* queue for notes waiting to end */
|
||||
/* allows us to do general polyphony */
|
||||
extern long delta_time, tracklen;
|
||||
extern long delta_time_track0; /* [SS] 2010-06-27 */
|
||||
extern int div_factor;
|
||||
|
||||
/* routines to handle note queue */
|
||||
#ifndef KANDR
|
||||
void addtoQ(int num, int denom, int pitch, int chan, int effect, int d);
|
||||
void removefromQ(int i);
|
||||
void clearQ(void);
|
||||
void printQ(void);
|
||||
void advanceQ(int t);
|
||||
void Qinit(void);
|
||||
/* void Qcheck(); */
|
||||
void timestep(int t, int atend);
|
||||
#else
|
||||
void addtoQ();
|
||||
void removefromQ();
|
||||
void clearQ();
|
||||
void printQ();
|
||||
void advanceQ();
|
||||
void Qinit();
|
||||
/* void Qcheck(); */
|
||||
void timestep();
|
||||
#endif
|
||||
31
samples/araber.abc
Normal file
31
samples/araber.abc
Normal file
@@ -0,0 +1,31 @@
|
||||
X: 47
|
||||
%%MIDI channel 1
|
||||
%%MIDI chordprog 32
|
||||
%%MIDI bassprog 0
|
||||
%%MIDI program 25
|
||||
%%MIDI beat 110 100 90 4
|
||||
%%MIDI ratio 2 1
|
||||
%%MIDI chordvol 95
|
||||
%%MIDI bassvol 97
|
||||
%%MIDI transpose 0
|
||||
%%MIDI gracedivider 4
|
||||
Q:1/4 = 144
|
||||
T: Araber tants [D]
|
||||
R: Terkish
|
||||
S: handwritten MS of unknown origin labelled "III-2"
|
||||
Z: 2009 John Chambers <jc:trillian.mit.edu>
|
||||
M: C
|
||||
L: 1/8
|
||||
K: Dphr ^F
|
||||
%%MIDI drum d2zdd2d2 65 50 50 50 90 90 90 90
|
||||
%%MIDI drumon
|
||||
D2 \
|
||||
| "D"FGA2 A2A2 | "Gm"B6 AG | "D"^FGA2 "Eb"BAGA | "D"GF3 z2D2 |
|
||||
| "D"FGA2 A2A2 | "Cm"c4- cBAG | "D"FGA2 "Eb"BAGA | "D"GF3 z4 |
|
||||
| "D7"Dd2^c d2A2 | "Gm"B3c d2c/B/A/G/ | "Cm"FG3- GFEF | "D"ED3 zD (3BAG |]
|
||||
|: "D7"F8 | "Gm"G8 | "D"FGAF- FD"Cm"EC | "D"DEFG AdAG |
|
||||
| "D7"F8 | "Gm"G4 zD (3BAG | "D"FGAF- FD"Cm"EC |1 "D"D4 zD (3BAG :|2 "D"D4 zd "Cm"c/B/A/G/ ||
|
||||
|: "D"FGAF- FD "Cm"E/D/E/C/ | "D"DEFG Ad "Cm"c/B/A/G/ \
|
||||
| "D"FGAF- FD"Cm"EC |1 "D"DD2A, DA,D2 :|2 "D"D6 |]
|
||||
|
||||
|
||||
59
samples/baym_rebin.abc
Normal file
59
samples/baym_rebin.abc
Normal file
@@ -0,0 +1,59 @@
|
||||
X: 63
|
||||
T: Baym Rebin's Sude
|
||||
T: At the Rabbi's Table
|
||||
Z: John Chambers <jc:trillian.mit.edu>
|
||||
M: 2/4
|
||||
L: 1/16
|
||||
K: C^f^c^a
|
||||
Q:1/4=80
|
||||
V:1
|
||||
%%MIDI program 65 %alto sax
|
||||
FE \
|
||||
|: "F#"^DEF2 F2F2 | F8 | ABc2 "Em"BAG2 | "F#"F8 \
|
||||
| A4 "Bm"B4 | "F#"c4 "Bm"B4 | "F#"A6 G2 | A2G2 F2E2 |
|
||||
| "F#"^DEF2 F2F2 | F8 | FGA2 "Em"GFE2 | E8 \
|
||||
| e2d2 c2B2 | A2E2 F2G2 | "F#"F8- | F4 z4 :|
|
||||
|: "Bm"F2B2 A2B2 | "F#7"c2d2 c2F2 | "Bm"B6 cd | B8 \
|
||||
| "Em"e4 "F#7"f4 | "Em"e4 "Bm"d4 | "F#"c6 B2 | c2B2 A4 |
|
||||
| "F#"A4 "Bm"B4 | "F#"c4 "Bm"B4 | "F#"A6 G2 | A2G2 F2E2 \
|
||||
| "Em"A2B2 B2B2 | AcBA GFEG | "F#"F4- FAcA | F8 :|
|
||||
|: "Bm"dcdc dcB2 | "Em"BABA BAG2 | "F#"FGA2 "Em"GFE2 | E8 \
|
||||
| A2B2 B2B2 | AcB2 A2B2 | "F#"c4- cBAG | F8 |
|
||||
| "Bm"dcdc dcB2 | "Em"BABA BAG2 | "F#"FGA2 "Em"GFE2 | E8 \
|
||||
| "Em"e2d2 c2B2 | A2E2 F2G2 | "F#"F8- | F8 :|
|
||||
V: drum
|
||||
%%MIDI channel 10
|
||||
zz |: D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,D,,D,, D,D,,D,, ^G,,^G,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,D,,D,, D,D,,D,, ^G,,^G,, |
|
||||
D,D,,D,, D,D,,D,, D,^G,, |
|
||||
|D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,D,,D,, D,D,,D,, ^G,,^G,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,D,,D,, D,D,,D,, ^G,,^G,, |
|
||||
D,D,,D,, D,D,,D,, D,^G,, :|
|
||||
%
|
||||
|: D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,D,,D,, D,D,,D,, ^G,,^G,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,D,,D,, D,D,,D,, ^G,,^G,, |
|
||||
D,D,,D,, D,D,,D,, D,^G,, |
|
||||
|D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,D,,D,, D,D,,D,, ^G,,^G,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,^G,,^G,, D,D,,D,, ^G,,D,, |
|
||||
D,D,,D,, D,D,,D,, ^G,,^G,, |
|
||||
D,D,,D,, D,D,,D,, D,^G,, :|
|
||||
|
||||
39
samples/boys.abc
Normal file
39
samples/boys.abc
Normal file
@@ -0,0 +1,39 @@
|
||||
X: 3
|
||||
T: The Boys of Carrigallen
|
||||
B: O'Neill's 210
|
||||
N: "Cheerful"
|
||||
N: "Collected by J.O'Neill"
|
||||
Z: 1997 by John Chambers <jc@eddie.mit.edu> http://eddie.mit.edu/~jc/music/abc/
|
||||
M: 6/8
|
||||
L: 1/8
|
||||
K: Am
|
||||
V:1
|
||||
|:E \
|
||||
| A2E A>(Bc/d/) | e>de (A2B/A/) | G2D G>(AB/c/) | d>cd G2B |
|
||||
| A2E ABd | e2^f g>fg | edc Bcd | ecA A2 :|
|
||||
|: a \
|
||||
| :a^ga A2a | a^ga A2g | g^fg G2=g | g^fg G2B |
|
||||
| c2c d2d | e^fg a3 | edc Bcd | ecA A2 :|
|
||||
V: drum
|
||||
M: 6/8
|
||||
L: 1/16
|
||||
%%MIDI channel 10
|
||||
|: z2|F4FF ^F2F2^F2 |
|
||||
F4^F2 ^F4^F2 |
|
||||
F4FF ^F2F2^F2 |
|
||||
F4^F2 ^F4^F2 |
|
||||
F4FF ^F2F2^F2 |
|
||||
F4^F2 ^F4^F2 |
|
||||
F4FF ^F2F2^F2 |
|
||||
F2^F2F2 F4 :|
|
||||
|: z2|F4FF ^F2F2^F2 |
|
||||
F4^F2 ^F4^F2 |
|
||||
F4FF ^F2F2^F2 |
|
||||
F4^F2 ^F4^F2 |
|
||||
F4FF ^F2F2^F2 |
|
||||
F4^F2 ^F4^F2 |
|
||||
F4FF ^F2F2^F2 |
|
||||
F2^F2F2 F4 :|
|
||||
|
||||
|
||||
|
||||
53
samples/coleraine.abc
Normal file
53
samples/coleraine.abc
Normal file
@@ -0,0 +1,53 @@
|
||||
X: 8
|
||||
%%MIDI channel 1
|
||||
%%MIDI chordprog 3
|
||||
%%MIDI bassprog 3
|
||||
%%MIDI program 26
|
||||
%%MIDI beat 110 100 90 4
|
||||
%%MIDI ratio 2 1
|
||||
%%MIDI chordvol 64
|
||||
%%MIDI bassvol 65
|
||||
%%MIDI transpose 0
|
||||
%%MIDI gracedivider 4
|
||||
Q:1/4 = 142
|
||||
T: Coleraine
|
||||
B: Kerr's Violin IV
|
||||
Z: John Chambers <jc@eddie.mit.edu> http://eddie.mit.edu/~jc/music/
|
||||
R: jig
|
||||
M: 6/8
|
||||
L: 1/8
|
||||
K: Am
|
||||
%%MIDI drum d2z2ddd2d2d2 65 66 66 50 66 66 90 70 70 90 70 70
|
||||
%%MIDI drumon
|
||||
V:1
|
||||
%%MIDI program 72
|
||||
%%MIDI control 7 115
|
||||
%%MIDI control 10 67
|
||||
%%MIDI beat 110 100 90 4
|
||||
|: "E7"E | "Am"E>AA ABc | "E7"B>ee e2d | "Am"c>AA ABc | "E7"B^GE E2E | \
|
||||
| "Am"E>AA ABc | "E7"B>ee e2d | "Am"c>BA "E7"B^GE | "Am"A3- A2 :|
|
||||
|: "G7"B | "C"c2c cdc | "G"Bdg "(E)"g2^g | "Am"a>ed cBA | "E7"^GBG E^FG | \
|
||||
| "Am"A^GA "E7"BAB | "Am"cde "Dm"fed | "Am"c>BA "E7"B^GE | "Am"A3- A2 :|
|
||||
V: drum
|
||||
M: 6/8
|
||||
L: 1/16
|
||||
%%MIDI channel 10
|
||||
|: z2|G,,3A,,G,,2 A,,G,,A,,2A,,2 |
|
||||
G,,3A,,G,,2 A,,2G,,A,,G,,2 |
|
||||
G,,3A,,G,,2 A,,G,,A,,2A,,2 |
|
||||
G,,3A,,G,,2 A,,2G,,A,,G,,2 |
|
||||
G,,3A,,G,,2 A,,G,,A,,2A,,2 |
|
||||
G,,3A,,G,,2 A,,2G,,A,,G,,2 |
|
||||
G,,3A,,G,,2 A,,G,,A,,2A,,2 |
|
||||
G,,3A,,G,,2 A,,2G,,A,, :|
|
||||
%
|
||||
|:z2| G,,3A,,G,,2 A,,G,,A,,2A,,2 |
|
||||
G,,3A,,G,,2 A,,2G,,A,,G,,2 |
|
||||
G,,3A,,G,,2 A,,G,,A,,2A,,2 |
|
||||
G,,3A,,G,,2 A,,2G,,A,,G,,2 |
|
||||
G,,2G,,2G,,2 z6 |
|
||||
G,,2G,,2G,,2 z6 |
|
||||
G,,2G,,2G,,2 z6 |
|
||||
G,,6 z4 :|
|
||||
|
||||
|
||||
13
samples/daramud.abc
Normal file
13
samples/daramud.abc
Normal file
@@ -0,0 +1,13 @@
|
||||
X:1
|
||||
T:Daramad of Shur
|
||||
L:1/8
|
||||
% adapted from http://anamnese.online.fr/iran/persianm.abc
|
||||
% see http://anamnese.online.fr/iran/persian_music.html for more info
|
||||
Q:1/4=135
|
||||
M:4/4
|
||||
K:C
|
||||
%%MIDI program 111
|
||||
d _/e g f _/e d c _B A G A d2 {c}_B2 {A}G2 |
|
||||
G A c _B A G F _/E D _/E F G A c {_B} A2 {G} F4 |
|
||||
FFF A2 G2 {F} _/E_/E_/E G2 F2 {_/E} DDDF2 _/E2|
|
||||
|
||||
280
samples/demo.abc
Normal file
280
samples/demo.abc
Normal file
@@ -0,0 +1,280 @@
|
||||
% Example tunes for abc2midi.
|
||||
% Illustrating various aspects of the abc notation language
|
||||
%
|
||||
%
|
||||
|
||||
% A French tune using an in-body key change
|
||||
%
|
||||
X: 1
|
||||
T:Horses Branle
|
||||
M:4/4
|
||||
L:1/8
|
||||
Q:1/4=127
|
||||
C:Trad
|
||||
K:G
|
||||
P:A
|
||||
|: G>A BB cBAc|BAGF E2D2|G>A BB cBAc|BGAF G2 G2
|
||||
P:B
|
||||
:: d c/2B/2 AB c B/2A/2 GB|AGFG A>B A2|\
|
||||
d c/2B/2 AB c B/2A/2 GB|AGGF G2 G2 ::
|
||||
P:C
|
||||
K:F
|
||||
B/2A/2 G B/2A/2 G FG A2|DEFG ABAG | \
|
||||
B/2A/2 G B/2A/2 G FG A2|DEFG GF G2 :|
|
||||
|
||||
% A hornpipe using triplets, accidentals and broken rhythm
|
||||
%
|
||||
X: 2
|
||||
T:Trumpet Hornpipe
|
||||
T:Captain Pugwash Theme
|
||||
C: Trad
|
||||
M:4/4
|
||||
L:1/8
|
||||
Q:1/4=140
|
||||
R:hornpipe
|
||||
K:G
|
||||
|: (3GGG G2 (3GGG G>d|B>GB>d g>dB>G|\
|
||||
(3DDD D2 (3DDD D>A|F>DF>A c>AF>A|
|
||||
(3GGG G2 (3GGG G>d|B>G B>d g2 g2|\
|
||||
f>ag>f e>gf>e |1 d>^cd>e d>=cB>A :|2 d>^cd>e d2 B>=c |:
|
||||
(3ddd d2 (3ddd d2|e>fg>f e>dc>B|\
|
||||
c>de>d c>BA>G|F>GA>G F>DE>F|
|
||||
(3GGG G2 (3=FFF F2|(3EEE E2 (3^DDD D2| \
|
||||
=D>gf>e d>cB>A|1 G2B2G2 B>c :|2 G2B2G4 ||
|
||||
|
||||
% Using ties to create non-standard length notes.
|
||||
%
|
||||
X:3
|
||||
T:Smash the Windows
|
||||
T:Roaring Jelly
|
||||
S:One Thousand English Country Dance Tunes, Michael Raven
|
||||
C:Trad
|
||||
M:6/8
|
||||
L:1/8
|
||||
Q:1/8=400
|
||||
K:D
|
||||
|:A|DED F2A|d2f ecA|G2B F2A|E2F GFE|DED F2A|d2f ecA|Bgf edc|d3-d2:|
|
||||
a|a2f d2f|A2a agf|g2e c2e|A2g gfe|f2d g2e|a2f bag|fed edc|d3-d2a|
|
||||
agf fed|Adf agf|gfe ecA|Ace gfe|fed gfe|agf bag|fed edc|d3-d2z||
|
||||
|
||||
% Four-part arrangement using V: for multiple voices
|
||||
%
|
||||
X: 4
|
||||
T: Candlemas Eve
|
||||
S: Hymn 126 Arr. R. Herrick from an old church-gallery book
|
||||
M:4/4
|
||||
L:1/8
|
||||
Q:1/8=400
|
||||
N:from an old church-gallery book
|
||||
H:The old church-gallery book was discovered by the Rev. L.J.T. Darwall.
|
||||
H:The source has a 4-part harmony.
|
||||
O:English
|
||||
R:Reel
|
||||
K:G
|
||||
V: 1
|
||||
% soprano
|
||||
D2 |\
|
||||
G2 G2 B2 G2 | E2 F2 G2 Bd | c2 B2 A2 G2 | A6 Bc |
|
||||
d2 B2 G2 AB | c2 A2 F2 GA | B2 G2 E2 F2 | G6 Bc |
|
||||
d2 d2 d2 B2 | e2 c2 A2 Bd | c2 B2 A2 G2 | d6 B2 |
|
||||
e2 d2 c2 B2 | A2 G2 F2 GA | B2 G2 E2 F2 | G6 z2 ||
|
||||
V: 2
|
||||
% alto
|
||||
D2 |\
|
||||
D2 C2 B,2 D2 | C2 C2 D2 D2 | G2 G2 E2 E2 | F6 G2 |
|
||||
G2 F2 E2 D2 | C2 E2 D2 E2 | D2 D2 C2 C2 | D6 G2 |
|
||||
G2 G2 G2 G2 | G2 G2 F2 D2 | G2 G2 E2 G2 | F6 D2 |
|
||||
C2 D2 EF G2 | E2 E2 D2 E2 | D2 B,2 C2 D2 | D6 z2 ||
|
||||
V: 3
|
||||
% tenor
|
||||
D,2 |\
|
||||
G,2 G,2 G,2 G,2 | G,2 A,2 B,2 B,2 | E2 D2 C2 B,2 | D6 D2 |
|
||||
D2 D2 B,2 G,2 | E,2 A,2 A,2 C2 | G,2 G,2 G,2 A,2 | B,6 DC |
|
||||
B,2 D2 B,2 D2 | C2 E2 D2 B,2 | C2 D2 C2 G,2 | A,6 G,2 |
|
||||
G,2 G,2 C2 D2 | CD CB, A,2 C2 | G,2 G,2 A,2 A,2 | B,6 z2 ||
|
||||
V: 4
|
||||
% bass up one octave
|
||||
D2 |\
|
||||
B,2 A,2 G,2 B,2 | C2 A,2 G,2 G2 | E2 G2 A2 E2 | D6 GA |
|
||||
B,2 D2 E2 E2 | A,2 C2 D2 C2 | B,2 A,B, C2 A,2 | G,6 G,2 |
|
||||
G2 B2 G2 G2 | c2 C2 D2 G2 | E2 G2 C2 E2 | D6 G2 |
|
||||
C2 B,2 A,2 G,2 | A,2 C2 D2 C2 | B,2 E2 A,2 D2 | G,6 z2 ||
|
||||
|
||||
% Using the w: field and part notation to create a karaoke file.
|
||||
% There are a lot more verses to this song than the 3 shown here.
|
||||
%
|
||||
X: 5
|
||||
T: Oh You New York Girls
|
||||
C:Trad
|
||||
M: 4/4
|
||||
L: 1/8
|
||||
Q:1/4=200
|
||||
P:(AB)3
|
||||
K:C % 0 sharps
|
||||
%%MIDI gchord fz
|
||||
%%MIDI chordvol 90
|
||||
P:A
|
||||
g2|e2g2g3g|f2a2a3a|g2g2f2g2|e6
|
||||
w:As I walked out on So-uth Street, a fair maid I did meet
|
||||
w:I said, "My dear young la-dy, I'm a stran-ger here in town
|
||||
w:I took her out to Tiff-an-y's, I spared her no ex-pense
|
||||
g2|c'3c'c'2g2|b2 a2a3a|g3 gf2d2|c4
|
||||
w:Who asked me please to see her home, she lived on Blee-cker Street
|
||||
w:I left my ship just yes-ter-day, from Liver-pool I was bound."
|
||||
w:I bought her two gold ea-r-rings, they cost me fif-teen cents.
|
||||
P:B
|
||||
e2f2|g6e2|f2 a6|b4 a4|a2g4 z2|
|
||||
w:And a-way, you John-ny, my dear hon-ey
|
||||
c'6b2|b2a2 a4|g3g f2B2|d2c4
|
||||
w:Oh you New York girls, can you dance the pol-ka?
|
||||
|
||||
% Using "guitar chords" to generate an accompaniment.
|
||||
% Also uses R:hornpipe to generate broken rhythm.
|
||||
%
|
||||
X:6
|
||||
T:The Friendly Visit
|
||||
R:hornpipe
|
||||
S:Nottingham Music Database
|
||||
M:4/4
|
||||
L:1/8
|
||||
Q:1/4=200
|
||||
K:G
|
||||
|: BA|\
|
||||
"G"(3GFG DG BGBd|"C"(3cBc AB "D7"cdef|"G"g2df "C"ecAG|"Am"FGAB "D7"cAFD|
|
||||
"G"(3GFG DG BGBd|"C"(3cBc AB "D7"cdef|"G"gdBG "D7"FAdc|"G"B2G2 G2::
|
||||
(3GBd|\
|
||||
"G"g2dB GBdg|"Am"e2cA FGAg|"D"f2ed "A7"^cdeg|"D7"(3fgf (3efe dcBA|
|
||||
"G"(3GFG DG BGBd|"C"(3cBc AB "D7"cdef|"G"gdBG "D7"FAdc|"G"B2G2 G2:|z2||
|
||||
|
||||
% Using drone commands for bagpipe music
|
||||
X: 7
|
||||
T:The First Slip "Arranged by Terry Tully"
|
||||
M:C
|
||||
L:1/8
|
||||
Q:80
|
||||
C:Traditional Irish
|
||||
S:Reel
|
||||
Z: The Brussels Caledonian Corneymusers Pipe Band
|
||||
Z: http://membres.lycos.fr/corneymusers/Tunes.html
|
||||
K:HP
|
||||
%%MIDI program 109
|
||||
%%MIDI drone 70 45 33 90 90
|
||||
%%MIDI droneon
|
||||
|: {g}eA{gAGAG}A2{gef}e2{g}dB|
|
||||
{g}eA{gAGAG}A2{g}GB{gBeBG}B2|
|
||||
{g}eA{gAGAG}A2{gef}e2{g}fa| !
|
||||
ge{gde}dB{G}ABcd:| |:
|
||||
{g}ea{g}ag{ef}e2{A}ef|
|
||||
{g}dB{gBeBG}B2{g}GB{gBeBG}B2| !
|
||||
{g}ea{g}ag{ef}e2{A}ef|
|
||||
{a}ge{gde}dB{G}ABcd:|
|
||||
%%MIDI droneoff
|
||||
|
||||
% Using extended gchord codes for playing arpeggios
|
||||
X: 8
|
||||
T:Roddy McCawley
|
||||
% Nottingham Music Database
|
||||
S:Saen Smith, via PR
|
||||
M:4/4
|
||||
L:1/4
|
||||
K:G
|
||||
%%MIDI program 73
|
||||
%%MIDI chordprog 0
|
||||
%%MIDI bassprog 1
|
||||
%%MIDI gchord ghhi
|
||||
GA |B2 AB|D2 GA|"G"B3/2c/2 BA|G2 D2|"C"E2 G2|G2 A2|"G"G4-|
|
||||
B2 Bc|"G"d2 d2|d2 Bd|"C"e2 e2|"G"d2 BA|"Em"G2 E2|"Am"c2 B2|"D"A4-|
|
||||
A2 Bc|"G"d2 d2|d2 Bd|"C"e2 e2|"G"d2 BA|"Em"G2 E2|"Am"c2 B2|"D"A4-|A2 GA|
|
||||
"G"B2 AB|D2 GA|"G"B3/2c/2 BA|G2 D2|"C"E2 G2|G2 A2|"G"G4-|G4||
|
||||
|
||||
% uses microtones
|
||||
X:9
|
||||
T:Daramad of Shur
|
||||
L:1/8
|
||||
% adapted from http://anamnese.online.fr/iran/persianm.abc
|
||||
% see http://anamnese.online.fr/iran/persian_music.html for more info
|
||||
Q:1/4=135
|
||||
M:4/4
|
||||
K:C
|
||||
%%MIDI program 111
|
||||
d _/e g f _/e d c _B A G A d2 {c}_B2 {A}G2 |
|
||||
G A c _B A G F _/E D _/E F G A c {_B} A2 {G} F4 |
|
||||
FFF A2 G2 {F} _/E_/E_/E G2 F2 {_/E} DDDF2 _/E2|
|
||||
|
||||
|
||||
%using the %%MIDI trim command to distinguish slurs
|
||||
X:10
|
||||
T:Heights of Alma
|
||||
% Nottingham Music Database
|
||||
S:KCC p3, via EF
|
||||
M:4/4
|
||||
L:1/4
|
||||
K:A
|
||||
%%MIDI trim 1/5
|
||||
%%MIDI program 74
|
||||
%%MIDI beat 89 79 69 4
|
||||
%%MIDI chordprog 45
|
||||
%%MIDI bassprog 45
|
||||
%%MIDI chordvol 77
|
||||
%%MIDI bassvol 73
|
||||
P:A
|
||||
(e/2d/2)|"A"cA AE|"A"(A/2B/2c/2d/2) e2|"A"(f/2e/2d/2c/2) eA|\
|
||||
"G"(d/2=c/2B/2A/2) =Ge/2d/2|
|
||||
"A"cA AE|"A"A/2B/2c/2d/2 e2|"A"(f/2e/2d/2c/2) "E7"(e/2f/2e/2d/2)|"A"cA A:|
|
||||
P:B
|
||||
c/2d/2|"A"ea ca|"A"e/2f/2e/2c/2 AB/2=c/2|"G"d=g Bg|"G"d/2e/2d/2B/2 =Gc/2d/2|
|
||||
"A"ea ca|"A"e/2f/2e/2c/2 AB/2c/2|"E7"(d/2c/2B/2A/2) (G/2B/2e/2d/2)|"A"cA A:|
|
||||
|
||||
|
||||
|
||||
X:11
|
||||
T:Linear Temperament
|
||||
M:4/4
|
||||
L:1/4
|
||||
Q:1/4=35
|
||||
% %MIDI temperamentlinear 1200.0 694.736842 % 19-EDO
|
||||
% %MIDI temperamentlinear 1200.0 709.090909 % 22-EDO
|
||||
% %MIDI temperamentlinear 1200.0 696.774194 % 31-EDO
|
||||
% %MIDI temperamentlinear 1200.0 698.0 % fifth=698 cents
|
||||
% %MIDI temperamentlinear 1200.0 696.57843 % 1/4-comma meantone
|
||||
%%MIDI temperamentlinear 1200.0 701.955001 % Pythagorean
|
||||
% %MIDI temperamentnormal % 12-EDO
|
||||
K:C
|
||||
V:1
|
||||
%%MIDI program 16
|
||||
c2 B2 | c3/z/ ^A2 |
|
||||
V:2
|
||||
%%MIDI program 16
|
||||
G2 G2 | G3/z/ G2 |
|
||||
V:3
|
||||
%%MIDI program 16
|
||||
(3E_E^D (3=DF_F | =E3/z/ E2 |
|
||||
V:4
|
||||
%%MIDI program 16
|
||||
C2 G,2 | C3/z/ C2 |
|
||||
|
||||
|
||||
X: 12
|
||||
T:Cuckoo's Nest
|
||||
% Nottingham Music Database
|
||||
% drum line added by Seymour
|
||||
S:Song
|
||||
M:4/4
|
||||
L:1/8
|
||||
R:Hornpipe
|
||||
Q:1/4=144
|
||||
K:Dm
|
||||
V:1
|
||||
"Dm"D2DE DCA,C|"Dm"DCDE F2"C7"FA|"F"c2cd A2GF|"C"ECCC C2"A7"FE|
|
||||
"Dm"D2DE DCA,C|"Dm"DCDE F2"C7"FG|"F"ABcA "A7"GFEF|"Dm"E2"Gm"D2 "Dm"D2||
|
||||
V:2
|
||||
%%MIDI channel 10
|
||||
%%MIDI chordattack 50
|
||||
[^F,,E,,]/[^F,,E,,]/[D,,^F,,]/[D,,^F,,]/ ^F,,F,, z4|^F,,E,,E,,^F,,z4|\
|
||||
[^F,,E,,]/[^F,,E,,]/[D,,^F,,]/[D,,^F,,]/ ^F,,F,, z4|D,,D,,D,,^F,,z4|
|
||||
[^F,,E,,]/[^F,,E,,]/[D,,^F,,]/[D,,^F,,]/ ^F,,F,, z4|^F,,D,,D,,^F,,z4|\
|
||||
[^F,,E,,]/[^F,,E,,]/[D,,^F,,]/[D,,^F,,]/ ^F,,E,, z4|E,,^F,,B,,,4|
|
||||
|
||||
|
||||
|
||||
|
||||
35
samples/dergasn.abc
Normal file
35
samples/dergasn.abc
Normal file
@@ -0,0 +1,35 @@
|
||||
X: 145
|
||||
%%MIDI channel 1
|
||||
%%MIDI chordprog 3
|
||||
%%MIDI bassprog 3
|
||||
%%MIDI program 26
|
||||
%%MIDI beat 110 100 90 4
|
||||
%%MIDI ratio 2 1
|
||||
%%MIDI chordvol 64
|
||||
%%MIDI bassvol 65
|
||||
%%MIDI transpose 0
|
||||
%%MIDI gracedivider 4
|
||||
Q:1/4 = 110
|
||||
T: der Gasn Nigun
|
||||
T: the Street Tune
|
||||
R: horra
|
||||
B: The Compleat Klezmer p.47
|
||||
M: 3/8
|
||||
L: 1/16
|
||||
%Q: 3/8=60
|
||||
K: Dm
|
||||
%%MIDI drum dzd 65 50 90 90
|
||||
%%MIDI drumon
|
||||
%%MIDI gchord fcc
|
||||
|: zF2 \
|
||||
| "Gm"FG3 G2 | TG4 F2 | "Dm"FD- D4- | D2z2 F2 \
|
||||
| "Gm"FG3 G2 | "C7"TG3F AG | "F"F3C AC | F2z2 C2 |
|
||||
| "Fm"C3F EF | G3_A =Bc | "G"d3_e dc | T=B3_A GF \
|
||||
| "Dm"F3E "Gm"GE | "Dm"F3D "Cm"(3_EDC | "Dm"D3d AF | D2z :|
|
||||
|: A,DF \
|
||||
| "Dm"A6- | A3A (3c=BA | ^G=B A4- | A3D FA \
|
||||
| "Dm"c3=B (3cBA | c3=B (3cBA | ^G=B A4- | A3 A,DF |
|
||||
| "Dm"A3^G (3AGF | A3^G (3AGF | E=G F4- | F3 A,DE \
|
||||
| "Dm"F3E (3FED | F3E (3FED | ^CE D4- | D2z :|
|
||||
|
||||
|
||||
46
samples/detune.abc
Normal file
46
samples/detune.abc
Normal file
@@ -0,0 +1,46 @@
|
||||
X:1
|
||||
T:temperament command
|
||||
M: 4/4
|
||||
L: 1/8
|
||||
K:C
|
||||
%%temperament +00 -06 -04 -02 -08 +02 -08 -02 -04 -06 10 0
|
||||
c d e f g a b c' |
|
||||
K:C#
|
||||
c d e f g a b c' |
|
||||
K:Cb
|
||||
c d e f g a b c' |
|
||||
M:12/8
|
||||
L:1/8
|
||||
K:C
|
||||
c ^c d ^d e f ^f g ^g a ^a b |
|
||||
M:13/8
|
||||
L:1/8
|
||||
c _d =d _e =e f _g =g _a =a _b =b c' |
|
||||
|
||||
|
||||
X:2
|
||||
T:temperament command
|
||||
T:from https://chiselapp.com/user/moinejf/repository/abc2svg/artifact/9b9730a7decefc8f
|
||||
L:1/2
|
||||
M:6/2
|
||||
K:C
|
||||
%%MIDI program 16
|
||||
%%MIDI makechordchannels 2
|
||||
% pythagore (~500 B.C)
|
||||
%%temperament +00 +14 +04 -06 +08 -02 +12 +02 +16 +06 -04 +10
|
||||
[CEG]2z [C_EG]2z | [^F^A^c]2z [^F=A^c]2z |
|
||||
% just intonation
|
||||
%%temperament +00 -08 -18 -06 -14 -02 -10 +02 -08 -16 -04 -12
|
||||
[CEG]2z [C_EG]2z | [^F^A^c]2z [^F=A^c]2z |
|
||||
% meantone (Pietro Aaron 1523)
|
||||
%%temperament +00 -24 -07 +10 -14 +03 -21 -03 -27 +10 +07 -17
|
||||
[CEG]2z [C_EG]2z | [^F^A^c]2z [^F=A^c]2z |
|
||||
% Andreas Werckmeister III (1681)
|
||||
%%temperament +00 -04 +04 +00 -04 +04 +00 +02 -08 +00 +02 -02
|
||||
[CEG]2z [C_EG]2z | [^F^A^c]2z [^F=A^c]2z |
|
||||
% well temperament (F.A. Vallotti 1754)
|
||||
%%temperament +00 -06 -04 -02 -08 +02 -08 -02 -04 -06 +00 -10
|
||||
[CEG]2z [C_EG]2z | [^F^A^c]2z [^F=A^c]2z |
|
||||
% 12-tone equal temperament
|
||||
%%MIDI temperamentnormal
|
||||
[CEG]2z [C_EG]2z | [^F^A^c]2z [^F=A^c]2z |
|
||||
31
samples/drums.abc
Normal file
31
samples/drums.abc
Normal file
@@ -0,0 +1,31 @@
|
||||
X:1
|
||||
T: drums
|
||||
M: 2/4
|
||||
L:1/8
|
||||
K: C
|
||||
%%MIDI drum dddd 35 36 37 38
|
||||
%%MIDI drumon
|
||||
z4|
|
||||
%%MIDI drum dddd 39 40 41 42
|
||||
z4|
|
||||
%%MIDI drum dddd 43 44 45 46
|
||||
z4|
|
||||
%%MIDI drum dddd 47 48 49 50
|
||||
z4|
|
||||
%%MIDI drum dddd 51 52 53 54
|
||||
z4|
|
||||
%%MIDI drum dddd 55 56 57 58
|
||||
z4|
|
||||
%%MIDI drum dddd 59 60 61 62
|
||||
z4|
|
||||
%%MIDI drum dddd 63 64 65 66
|
||||
z4|
|
||||
%%MIDI drum dddd 67 68 69 70
|
||||
z4|
|
||||
%%MIDI drum dddd 71 72 73 74
|
||||
z4|
|
||||
%%MIDI drum dddd 75 76 77 78
|
||||
z4|
|
||||
%%MIDI drum dddd 79 80 81 82
|
||||
z4|
|
||||
|
||||
147
samples/temperament.abc
Normal file
147
samples/temperament.abc
Normal file
@@ -0,0 +1,147 @@
|
||||
%%splittune
|
||||
%%textfont Helvetica 14
|
||||
%%scale .9
|
||||
|
||||
|
||||
%%begintext obeylines
|
||||
=================
|
||||
temperamentlinear
|
||||
=================
|
||||
%%endtext
|
||||
%%begintext justify
|
||||
Microtone accidentals can be used along with temperamentlinear.
|
||||
|
||||
In that case, the accidental ratio is based on the new chromatic semitone size,
|
||||
defined as 7 fifths minus 4 octaves. (Run abc2midi with the verbose
|
||||
option (-v) to see the temperament values.)
|
||||
|
||||
As an exception, the microtonal deviation in cents can be represented
|
||||
by using denominator=100 in the accidentals. Example:
|
||||
%%endtext
|
||||
|
||||
X:1
|
||||
T:\%\%MIDI temperamentlinear - microtone accidentals in cents
|
||||
%%postscript /ft5475{M -3 3 RM 6 -6 RL 2 SLW stroke}def
|
||||
%%postscript /ft35939{2 copy ft0 M -7.5 -3 RM 12 F3 (7) show}def
|
||||
M:none
|
||||
K:C
|
||||
%%scale 1.3
|
||||
V:1
|
||||
%%MIDI program 17
|
||||
%%MIDI temperamentlinear 1200 702 %% Pythagorian tunings
|
||||
%%MIDI makechordchannels 3
|
||||
"^Pure;major;chord"\
|
||||
[C_22/100EG]8 y |\
|
||||
"^Pythagorian;major;chord"\
|
||||
[CEG]8 y ||\
|
||||
"^Pure;4:5:6:7;chord"\
|
||||
[C_22/100EG_141/100B]8 y |\
|
||||
"^Pythagorean;7-chord"\
|
||||
[CEG_B]8 y ||
|
||||
|
||||
%%newpage
|
||||
|
||||
%%begintext obeylines
|
||||
================
|
||||
temperamentequal
|
||||
================
|
||||
%%endtext
|
||||
%%begintext justify
|
||||
New command.
|
||||
|
||||
\%\%MIDI temperamentequal <ndiv> [octave_cents] [fifth_steps] [sharp_steps]
|
||||
|
||||
This commans sets a tempered scale defined by 'ndiv' equal divisions
|
||||
of 'octave_cents' (default is the octave = 1200 cents).
|
||||
|
||||
The optional parameter 'fifth_steps', if provided, is an integer that
|
||||
defines the size of the fifth in steps of the temperament.
|
||||
This sets where is the note G in the temperament.
|
||||
|
||||
When 'fifth_steps' is omited or 0 (zero), the program computes it
|
||||
as an approximation of the frequency ratio 3/1, minus the
|
||||
(possibly tempered) octave.
|
||||
|
||||
The optional 'sharp_steps' defines the meaning of the accidentals.
|
||||
'sharp_steps' is the number of steps between a natural note and
|
||||
a sharpened note (e.g. between =C and ^C).
|
||||
|
||||
By default, the size of a sharp/flat deviation is based on the
|
||||
size of the chromatic semitone in the specified temperament: 7 fifths minus
|
||||
4 octaves. The values in use in the temperament can be viewed
|
||||
by running abc2midi with the command-line option -v (verbose).
|
||||
|
||||
With temperamentequal (as with temperamentlinear), microtone accidentals
|
||||
are interpreted as fractions of the sharp size in the
|
||||
specified temperament, except if they use denominator=100, which
|
||||
defines microtonal deviations in cents.
|
||||
|
||||
The conventional temperament can be reset with the command temperamentnormal.
|
||||
|
||||
|
||||
See also: temperamentlinear, temperamentnormal, makechordchannels
|
||||
|
||||
|
||||
Example:
|
||||
%%endtext
|
||||
|
||||
X:2
|
||||
T:\%\%MIDI temperamentequal
|
||||
%%stretchlast 1
|
||||
M:none
|
||||
L:1/2
|
||||
K:C
|
||||
V:1
|
||||
%%MIDI program 44
|
||||
%%MIDI makechordchannels 3
|
||||
%
|
||||
%%text \%\%MIDI temperamentequal 7 1200 4 \% N.B.: fifth = 4 steps
|
||||
%%MIDI temperamentequal 7 1200 4 % N.B.: fifth = 4 steps
|
||||
"^Octave divided in 7 equal parts"\
|
||||
c d e f g a b c' & [I:MIDI=program 44] C8 | [CEGc]2 z |
|
||||
%
|
||||
%%text \%\%MIDI temperamentequal 17
|
||||
%%MIDI temperamentequal 17
|
||||
"^Octave divided in 17 equal parts"\
|
||||
=c ^/c ^c =d _/d _d =c & C7 | [CEGc]2 z |
|
||||
%
|
||||
%%text \%\%MIDI temperamentequal 22 \% N.B.: 1/3-sharps
|
||||
%%postscript /sh2{M 0 -5 RM 14 F3 (/) show}bind def
|
||||
%%postscript /sh258{2 copy M -7.5 -5 RM 14 F3 (\\) show sh0}bind def
|
||||
%%postscript /ft2{M 0 -5 RM 14 F3 (\\) show}bind def
|
||||
%%postscript /ft258{2 copy M -7.5 -5 RM 14 F3 (/) show ft0}bind def
|
||||
%%MIDI temperamentequal 22 % N.B.: 1/3-sharps
|
||||
"^Octave divided in 22 equal parts"\
|
||||
=c ^1/3c ^2/3c ^c =d _1/3d _2/3d _d =c & C8-C | [C_1/3EGc]2 z |
|
||||
%
|
||||
%%text \%\%MIDI temperamentequal 31
|
||||
%%MIDI temperamentequal 31
|
||||
"^Octave divided in 31 equal parts"\
|
||||
=c ^/c ^c ^3/c ^^c =d _/d _d _3/d __d =c2 & C12 | [CEGc]2 z |
|
||||
%
|
||||
%%text \%\%MIDI temperamentequal 19
|
||||
%%MIDI temperamentequal 19
|
||||
"^Octave divided in 19 equal parts"\
|
||||
=c ^c ^^c =d _d __d =c & C7 | [CEGc]2 z |
|
||||
%
|
||||
%%text \%\%MIDI temperamentequal 19 1205
|
||||
%%MIDI temperamentequal 19 1205
|
||||
"^Streched octave (1205 cents) divided in 19 equal parts"\
|
||||
=c ^c ^^c =d _d __d =c & C7 | [CEGc]2 z |
|
||||
%
|
||||
%%text \%\%MIDI temperamentequal 11 1200 7 1
|
||||
%%MIDI temperamentequal 11 1200 7 1
|
||||
"^Octave divided in 11 equal parts"\
|
||||
c __d _d =d ^d ^^d =e =g ^g ^^g =a =c' & C12 |
|
||||
%
|
||||
%%tex \%\%MIDI temperamentnormal
|
||||
%%MIDI temperamentnormal
|
||||
"^Conventional temperament: octave divided in 12 equal parts"\
|
||||
c _d =d ^d =e =f ^f =g ^g =a _b =b =c'2 & C14 |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
110
sizes.h
Normal file
110
sizes.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/* sizes.h */
|
||||
/* part of YAPS - abc to PostScript converter */
|
||||
/* defines sizes for musical symbols */
|
||||
/* Copyright James Allwright 2000 */
|
||||
/* May be copied under the terms of the GNU public license */
|
||||
|
||||
/* full region in points (1/72 inch) */
|
||||
/* A4 is 8.25 x 11.75 inches */
|
||||
#define A4_PAGEWIDTH 594
|
||||
#define A4_PAGELEN 846
|
||||
/* U.S. Letter is 8.5 x 11 inches */
|
||||
#define US_LETTER_PAGEWIDTH 612
|
||||
#define US_LETTER_PAGELEN 792
|
||||
/* margins are not printed in */
|
||||
#define XMARGIN 40
|
||||
#define YMARGIN 50
|
||||
|
||||
#define TUNE_SCALING 0.7
|
||||
|
||||
/* maximum acceptable horizontal gap between notes */
|
||||
/* if spacing is too great, notes are not spread out to fill stave */
|
||||
#define MAXGAP 40
|
||||
|
||||
/* note spacing on stave - half the gap between 2 consecutive stave lines */
|
||||
#define TONE_HT 3
|
||||
|
||||
/* X offset of accidental (double)sharp/(double)flat/natural */
|
||||
/* relative to note */
|
||||
#define ACC_OFFSET 9.6
|
||||
#define ACC_OFFSET2 7.1
|
||||
/* height of accidental symbols */
|
||||
#define NAT_UP 8
|
||||
#define NAT_DOWN 8
|
||||
#define FLT_UP 9
|
||||
#define FLT_DOWN 4
|
||||
#define SH_UP 8
|
||||
#define SH_DOWN 9
|
||||
/* X offset of note stem relative to centre of dot head */
|
||||
#define HALF_HEAD 3.5
|
||||
#define GRACE_HALF_HEAD 2.45
|
||||
#define HALF_BREVE 6.0
|
||||
/* X width of tail for 1/8th, 1/16th, 1/32th note */
|
||||
#define TAILWIDTH 5.0
|
||||
/* X offset of dots relative to each other and from note head */
|
||||
#define DOT_SPACE 4.0
|
||||
/* default note stem length */
|
||||
#define STEMLEN 20.0
|
||||
#define GRACE_STEMLEN 14.0
|
||||
#define TEMPO_STEMLEN 14.0
|
||||
|
||||
/* Y offsets for placing of tuples above and below beams */
|
||||
#define TUPLE_UP 5
|
||||
#define TUPLE_DOWN -14
|
||||
/* Y space requirement for tuple drawn with half-brackets */
|
||||
#define HTUPLE_HT 10
|
||||
|
||||
/* Decorator spacings */
|
||||
#define SMALL_DEC_HT 6
|
||||
#define BIG_DEC_HT 13
|
||||
/* Offset values define y=0 for the decorators */
|
||||
#define STC_OFF 0
|
||||
#define HLD_OFF 1
|
||||
#define GRM_OFF 4
|
||||
#define CPU_OFF 0
|
||||
#define CPD_OFF 0
|
||||
#define UPB_OFF 0
|
||||
#define DNB_OFF 0
|
||||
#define EMB_OFF 1
|
||||
#define TRL_OFF 2
|
||||
|
||||
/* Height of various fonts used */
|
||||
#define TITLE1_HT 20
|
||||
#define TITLE2_HT 20
|
||||
#define TEXT_HT 16
|
||||
#define COMP_HT 16
|
||||
#define LYRIC_HT 13
|
||||
#define CHORDNAME_HT 12
|
||||
#define INSTRUCT_HT 12
|
||||
#define WORDS_HT 12
|
||||
|
||||
/* height of 1st and 2nd ending markers */
|
||||
#define END_HT 9.0
|
||||
|
||||
/* vertical spacing between consecutive lines of music */
|
||||
#define VERT_GAP 10
|
||||
|
||||
/* Note tails for 1/8, 1/16, 1/32 notes */
|
||||
/* Defines width of tail and spacing between 2 consecutive tails */
|
||||
#define TAIL_WIDTH 2.6
|
||||
#define TAIL_SEP 5.3
|
||||
|
||||
/* width of a clef symbols */
|
||||
#define TREBLE_LEFT 15
|
||||
#define TREBLE_RIGHT 10
|
||||
#define CCLEF_LEFT 6
|
||||
#define CCLEF_RIGHT 10
|
||||
#define BASS_LEFT 15
|
||||
#define BASS_RIGHT 10
|
||||
#define TREBLE_UP 33
|
||||
#define TREBLE_DOWN 9
|
||||
#define CLEFNUM_HT 10
|
||||
|
||||
struct font {
|
||||
int pointsize;
|
||||
int space;
|
||||
int default_num;
|
||||
int special_num;
|
||||
char* name;
|
||||
int defined;
|
||||
};
|
||||
566
stresspat.c
Normal file
566
stresspat.c
Normal file
@@ -0,0 +1,566 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define ANSILIBS
|
||||
#define casecmp stricmp
|
||||
#else
|
||||
#define casecmp strcasecmp
|
||||
#endif
|
||||
|
||||
int nmodels = 32;
|
||||
|
||||
struct stressdef
|
||||
{
|
||||
char *name; /* rhythm designator */
|
||||
char *meter;
|
||||
int nseg; /* number of segments; */
|
||||
int nval; /* number of values; */
|
||||
int vel[16]; /* segment velocities */
|
||||
float expcoef[16]; /* segment expander coefficient */
|
||||
} stresspat[48];
|
||||
|
||||
|
||||
/* most of these externals link to variables in genmidi.c */
|
||||
extern int segnum, segden, nseg;
|
||||
extern float fdursum[32], fdur[32];
|
||||
extern int ngain[32];
|
||||
extern float maxdur;
|
||||
extern int time_num, time_denom;
|
||||
extern int verbose;
|
||||
extern int beatmodel, stressmodel;
|
||||
extern char timesigstring[16]; /* from parseabc.c */
|
||||
extern int *checkmalloc(int size);
|
||||
|
||||
void reduce (int *, int *);
|
||||
|
||||
void
|
||||
init_stresspat ()
|
||||
{
|
||||
if ( stresspat[0].name != NULL) { /* [SDG] 2020-06-03 */
|
||||
printf("stresspat already initialized\n");
|
||||
return;
|
||||
}
|
||||
stresspat[0].name = "Hornpipe";
|
||||
stresspat[0].meter = "4/4";
|
||||
stresspat[0].nseg = 8;
|
||||
stresspat[0].nval = 2;
|
||||
stresspat[0].vel[0] = 110;
|
||||
stresspat[0].vel[1] = 90;
|
||||
stresspat[0].expcoef[0] = (float) 1.4;
|
||||
stresspat[0].expcoef[1] = (float) 0.6;
|
||||
|
||||
stresspat[1].name = "Hornpipe";
|
||||
stresspat[1].meter = "C|";
|
||||
stresspat[1].nseg = 8;
|
||||
stresspat[1].nval = 2;
|
||||
stresspat[1].vel[0] = 110;
|
||||
stresspat[1].vel[1] = 90;
|
||||
stresspat[1].expcoef[0] = (float) 1.4;
|
||||
stresspat[1].expcoef[1] = (float) 0.6;
|
||||
|
||||
stresspat[2].name = "Hornpipe";
|
||||
stresspat[2].meter = "2/4";
|
||||
stresspat[2].nseg = 8;
|
||||
stresspat[2].nval = 2;
|
||||
stresspat[2].vel[0] = 110;
|
||||
stresspat[2].vel[1] = 90;
|
||||
stresspat[2].expcoef[0] = (float) 1.4;
|
||||
stresspat[2].expcoef[1] = (float) 0.6;
|
||||
|
||||
stresspat[3].name = "Hornpipe";
|
||||
stresspat[3].meter = "9/4";
|
||||
stresspat[3].nseg = 9;
|
||||
stresspat[3].nval = 3;
|
||||
stresspat[3].vel[0] = 110;
|
||||
stresspat[3].vel[1] = 80;
|
||||
stresspat[3].vel[2] = 100;
|
||||
stresspat[3].expcoef[0] = (float) 1.4;
|
||||
stresspat[3].expcoef[1] = (float) 0.6;
|
||||
stresspat[3].expcoef[2] = (float) 1.0;
|
||||
|
||||
stresspat[4].name = "Hornpipe";
|
||||
stresspat[4].meter = "3/2";
|
||||
stresspat[4].nseg = 12;
|
||||
stresspat[4].nval = 2;
|
||||
stresspat[4].vel[0] = 110;
|
||||
stresspat[4].vel[1] = 90;
|
||||
stresspat[4].expcoef[0] = (float) 1.4;
|
||||
stresspat[4].expcoef[1] = (float) 0.6;
|
||||
|
||||
stresspat[5].name = "Hornpipe";
|
||||
stresspat[5].meter = "12/8";
|
||||
stresspat[5].nseg = 12;
|
||||
stresspat[5].nval = 3;
|
||||
stresspat[5].vel[0] = 110;
|
||||
stresspat[5].vel[1] = 80;
|
||||
stresspat[5].vel[2] = 100;
|
||||
stresspat[5].expcoef[0] = (float) 1.4;
|
||||
stresspat[5].expcoef[1] = (float) 0.6;
|
||||
stresspat[5].expcoef[2] = (float) 1.0;
|
||||
|
||||
stresspat[6].name = "Double hornpipe";
|
||||
stresspat[6].meter = "6/2";
|
||||
stresspat[6].nseg = 12;
|
||||
stresspat[6].nval = 6;
|
||||
stresspat[6].vel[0] = 110;
|
||||
stresspat[6].vel[1] = 80;
|
||||
stresspat[6].vel[2] = 80;
|
||||
stresspat[6].vel[3] = 105;
|
||||
stresspat[6].vel[4] = 80;
|
||||
stresspat[6].vel[5] = 80;
|
||||
stresspat[6].expcoef[0] = (float) 1.2;
|
||||
stresspat[6].expcoef[1] = (float) 0.9;
|
||||
stresspat[6].expcoef[2] = (float) 0.9;
|
||||
stresspat[6].expcoef[3] = (float) 1.2;
|
||||
stresspat[6].expcoef[4] = (float) 0.9;
|
||||
stresspat[6].expcoef[5] = (float) 0.9;
|
||||
|
||||
stresspat[7].name = "Reel";
|
||||
stresspat[7].meter = "4/4";
|
||||
stresspat[7].nseg = 8;
|
||||
stresspat[7].nval = 2;
|
||||
stresspat[7].vel[0] = 120;
|
||||
stresspat[7].vel[1] = 60;
|
||||
stresspat[7].expcoef[0] = (float) 1.1;
|
||||
stresspat[7].expcoef[1] = (float) 0.9;
|
||||
|
||||
stresspat[8].name = "Reel";
|
||||
stresspat[8].meter = "C|";
|
||||
stresspat[8].nseg = 8;
|
||||
stresspat[8].nval = 8;
|
||||
stresspat[8].vel[0] = 80;
|
||||
stresspat[8].vel[1] = 60;
|
||||
stresspat[8].vel[2] = 120;
|
||||
stresspat[8].vel[3] = 60;
|
||||
stresspat[8].vel[4] = 80;
|
||||
stresspat[8].vel[5] = 60;
|
||||
stresspat[8].vel[6] = 120;
|
||||
stresspat[8].vel[7] = 60;
|
||||
stresspat[8].expcoef[0] = (float) 1.1;
|
||||
stresspat[8].expcoef[1] = (float) 0.9;
|
||||
stresspat[8].expcoef[2] = (float) 1.1;
|
||||
stresspat[8].expcoef[3] = (float) 0.9;
|
||||
stresspat[8].expcoef[4] = (float) 1.1;
|
||||
stresspat[8].expcoef[5] = (float) 0.9;
|
||||
stresspat[8].expcoef[6] = (float) 1.1;
|
||||
stresspat[8].expcoef[7] = (float) 0.9;
|
||||
|
||||
stresspat[9].name = "Reel";
|
||||
stresspat[9].meter = "2/4";
|
||||
stresspat[9].nseg = 8;
|
||||
stresspat[9].nval = 2;
|
||||
stresspat[9].vel[0] = 120;
|
||||
stresspat[9].vel[1] = 60;
|
||||
stresspat[9].expcoef[0] = (float) 1.1;
|
||||
stresspat[9].expcoef[1] = (float) 0.9;
|
||||
|
||||
stresspat[10].name = "Slip Jig";
|
||||
stresspat[10].meter = "9/8";
|
||||
stresspat[10].nseg = 9;
|
||||
stresspat[10].nval = 3;
|
||||
stresspat[10].vel[0] = 110;
|
||||
stresspat[10].vel[1] = 70;
|
||||
stresspat[10].vel[2] = 80;
|
||||
stresspat[10].expcoef[0] = (float) 1.4;
|
||||
stresspat[10].expcoef[1] = (float) 0.5;
|
||||
stresspat[10].expcoef[2] = (float) 1.1;
|
||||
|
||||
stresspat[11].name = "Double Jig";
|
||||
stresspat[11].meter = "6/8";
|
||||
stresspat[11].nseg = 6;
|
||||
stresspat[11].nval = 3;
|
||||
stresspat[11].vel[0] = 110;
|
||||
stresspat[11].vel[1] = 70;
|
||||
stresspat[11].vel[2] = 80;
|
||||
stresspat[11].expcoef[0] = (float) 1.2;
|
||||
stresspat[11].expcoef[1] = (float) 0.7;
|
||||
stresspat[11].expcoef[2] = (float) 1.1;
|
||||
|
||||
stresspat[12].name = "Single Jig";
|
||||
stresspat[12].meter = "6/8";
|
||||
stresspat[12].nseg = 6;
|
||||
stresspat[12].nval = 3;
|
||||
stresspat[12].vel[0] = 110;
|
||||
stresspat[12].vel[1] = 80;
|
||||
stresspat[12].vel[2] = 90;
|
||||
stresspat[12].expcoef[0] = (float) 1.2;
|
||||
stresspat[12].expcoef[1] = (float) 0.7;
|
||||
stresspat[12].expcoef[2] = (float) 1.1;
|
||||
|
||||
stresspat[13].name = "Slide";
|
||||
stresspat[13].meter = "6/8";
|
||||
stresspat[13].nseg = 6;
|
||||
stresspat[13].nval = 3;
|
||||
stresspat[13].vel[0] = 110;
|
||||
stresspat[13].vel[1] = 80;
|
||||
stresspat[13].vel[2] = 90;
|
||||
stresspat[13].expcoef[0] = (float) 1.3;
|
||||
stresspat[13].expcoef[1] = (float) 0.8;
|
||||
stresspat[13].expcoef[2] = (float) 0.9;
|
||||
|
||||
stresspat[14].name = "Jig";
|
||||
stresspat[14].meter = "6/8";
|
||||
stresspat[14].nseg = 6;
|
||||
stresspat[14].nval = 3;
|
||||
stresspat[14].vel[0] = 110;
|
||||
stresspat[14].vel[1] = 80;
|
||||
stresspat[14].vel[2] = 90;
|
||||
stresspat[14].expcoef[0] = (float) 1.2;
|
||||
stresspat[14].expcoef[1] = (float) 0.7;
|
||||
stresspat[14].expcoef[2] = (float) 1.1;
|
||||
|
||||
stresspat[15].name = "Ragtime";
|
||||
stresspat[15].meter = "12/8";
|
||||
stresspat[15].nseg = 12;
|
||||
stresspat[15].nval = 3;
|
||||
stresspat[15].vel[0] = 110;
|
||||
stresspat[15].vel[1] = 70;
|
||||
stresspat[15].vel[2] = 90;
|
||||
stresspat[15].expcoef[0] = (float) 1.4;
|
||||
stresspat[15].expcoef[1] = (float) 0.6;
|
||||
stresspat[15].expcoef[2] = (float) 1.0;
|
||||
|
||||
stresspat[16].name = "Strathspey";
|
||||
stresspat[16].meter = "C";
|
||||
stresspat[16].nseg = 8;
|
||||
stresspat[16].nval = 2;
|
||||
stresspat[16].vel[0] = 120;
|
||||
stresspat[16].vel[1] = 80;
|
||||
stresspat[16].expcoef[0] = (float) 1.0;
|
||||
stresspat[16].expcoef[1] = (float) 1.0;
|
||||
|
||||
stresspat[17].name = "Fling";
|
||||
stresspat[17].meter = "C";
|
||||
stresspat[17].nseg = 8;
|
||||
stresspat[17].nval = 2;
|
||||
stresspat[17].vel[0] = 110;
|
||||
stresspat[17].vel[1] = 90;
|
||||
stresspat[17].expcoef[0] = (float) 1.4;
|
||||
stresspat[17].expcoef[1] = (float) 0.6;
|
||||
|
||||
stresspat[18].name = "Set Dance";
|
||||
stresspat[18].meter = "4/4";
|
||||
stresspat[18].nseg = 8;
|
||||
stresspat[18].nval = 2;
|
||||
stresspat[18].vel[0] = 110;
|
||||
stresspat[18].vel[1] = 90;
|
||||
stresspat[18].expcoef[0] = (float) 1.4;
|
||||
stresspat[18].expcoef[1] = (float) 0.6;
|
||||
|
||||
stresspat[19].name = "Set Dance";
|
||||
stresspat[19].meter = "C|";
|
||||
stresspat[19].nseg = 8;
|
||||
stresspat[19].nval = 2;
|
||||
stresspat[19].vel[0] = 110;
|
||||
stresspat[19].vel[1] = 90;
|
||||
stresspat[19].expcoef[0] = (float) 1.4;
|
||||
stresspat[19].expcoef[1] = (float) 0.6;
|
||||
|
||||
stresspat[20].name = "Waltz";
|
||||
stresspat[20].meter = "3/4";
|
||||
stresspat[20].nseg = 3;
|
||||
stresspat[20].nval = 3;
|
||||
stresspat[20].vel[0] = 110;
|
||||
stresspat[20].vel[1] = 70;
|
||||
stresspat[20].vel[2] = 70;
|
||||
stresspat[20].expcoef[0] = (float) 1.04;
|
||||
stresspat[20].expcoef[1] = (float) 0.98;
|
||||
stresspat[20].expcoef[2] = (float) 0.98;
|
||||
|
||||
stresspat[21].name = "Slow March";
|
||||
stresspat[21].meter = "C|";
|
||||
stresspat[21].nseg = 8;
|
||||
stresspat[21].nval = 3;
|
||||
stresspat[21].vel[0] = 115;
|
||||
stresspat[21].vel[1] = 85;
|
||||
stresspat[21].vel[2] = 100;
|
||||
stresspat[21].vel[3] = 85;
|
||||
stresspat[21].expcoef[0] = (float) 1.1;
|
||||
stresspat[21].expcoef[1] = (float) 0.9;
|
||||
stresspat[21].expcoef[2] = (float) 1.1;
|
||||
stresspat[21].expcoef[3] = (float) 0.9;
|
||||
|
||||
stresspat[22].name = "Slow March";
|
||||
stresspat[22].meter = "C";
|
||||
stresspat[22].nseg = 8;
|
||||
stresspat[22].nval = 3;
|
||||
stresspat[22].vel[0] = 115;
|
||||
stresspat[22].vel[1] = 85;
|
||||
stresspat[22].vel[2] = 100;
|
||||
stresspat[22].vel[3] = 85;
|
||||
stresspat[22].expcoef[0] = (float) 1.1;
|
||||
stresspat[22].expcoef[1] = (float) 0.9;
|
||||
stresspat[22].expcoef[2] = (float) 1.1;
|
||||
stresspat[22].expcoef[3] = (float) 0.9;
|
||||
|
||||
stresspat[23].name = "March";
|
||||
stresspat[23].meter = "C|";
|
||||
stresspat[23].nseg = 8;
|
||||
stresspat[23].nval = 2;
|
||||
stresspat[23].vel[0] = 115;
|
||||
stresspat[23].vel[1] = 85;
|
||||
stresspat[23].expcoef[0] = (float) 1.1;
|
||||
stresspat[23].expcoef[1] = (float) 0.9;
|
||||
|
||||
stresspat[24].name = "March";
|
||||
stresspat[24].meter = "C";
|
||||
stresspat[24].nseg = 8;
|
||||
stresspat[24].nval = 4;
|
||||
stresspat[24].vel[0] = 115;
|
||||
stresspat[24].vel[1] = 85;
|
||||
stresspat[24].vel[2] = 100;
|
||||
stresspat[24].vel[3] = 85;
|
||||
stresspat[24].expcoef[0] = (float) 1.1;
|
||||
stresspat[24].expcoef[1] = (float) 0.9;
|
||||
stresspat[24].expcoef[2] = (float) 1.1;
|
||||
stresspat[24].expcoef[3] = (float) 0.9;
|
||||
|
||||
stresspat[25].name = "March";
|
||||
stresspat[25].meter = "6/8";
|
||||
stresspat[25].nseg = 8;
|
||||
stresspat[25].nval = 3;
|
||||
stresspat[25].vel[0] = 110;
|
||||
stresspat[25].vel[1] = 70;
|
||||
stresspat[25].vel[2] = 80;
|
||||
stresspat[25].expcoef[0] = (float) 1.1;
|
||||
stresspat[25].expcoef[1] = (float) 0.95;
|
||||
stresspat[25].expcoef[2] = (float) 0.95;
|
||||
|
||||
stresspat[26].name = "March";
|
||||
stresspat[26].meter = "2/4";
|
||||
stresspat[26].nseg = 8;
|
||||
stresspat[26].nval = 2;
|
||||
stresspat[26].vel[0] = 115;
|
||||
stresspat[26].vel[1] = 85;
|
||||
stresspat[26].expcoef[0] = (float) 1.1;
|
||||
stresspat[26].expcoef[1] = (float) 0.9;
|
||||
|
||||
stresspat[27].name = "Polka k1";
|
||||
stresspat[27].meter = "3/4";
|
||||
stresspat[27].nseg = 3;
|
||||
stresspat[27].nval = 3;
|
||||
stresspat[27].vel[0] = 90;
|
||||
stresspat[27].vel[1] = 110;
|
||||
stresspat[27].vel[2] = 100;
|
||||
stresspat[27].expcoef[0] = (float) 0.75;
|
||||
stresspat[27].expcoef[1] = (float) 1.25;
|
||||
stresspat[27].expcoef[2] = (float) 1.00;
|
||||
|
||||
stresspat[28].name = "Polka";
|
||||
stresspat[28].meter = "4/4";
|
||||
stresspat[28].nseg = 8;
|
||||
stresspat[28].nval = 2;
|
||||
stresspat[28].vel[0] = 110;
|
||||
stresspat[28].vel[1] = 90;
|
||||
stresspat[28].expcoef[0] = (float) 1.4;
|
||||
stresspat[28].expcoef[1] = (float) 0.6;
|
||||
|
||||
stresspat[29].name = "saucy";
|
||||
stresspat[29].meter = "3/4";
|
||||
stresspat[29].nseg = 6;
|
||||
stresspat[29].nval = 6;
|
||||
stresspat[29].vel[0] = 115;
|
||||
stresspat[29].vel[1] = 85;
|
||||
stresspat[29].vel[2] = 120;
|
||||
stresspat[29].vel[3] = 85;
|
||||
stresspat[29].vel[4] = 115;
|
||||
stresspat[29].vel[5] = 85;
|
||||
stresspat[29].expcoef[0] = (float) 1.2;
|
||||
stresspat[29].expcoef[1] = (float) 0.8;
|
||||
stresspat[29].expcoef[2] = (float) 1.3;
|
||||
stresspat[29].expcoef[3] = (float) 0.7;
|
||||
stresspat[29].expcoef[4] = (float) 1.1;
|
||||
stresspat[29].expcoef[5] = (float) 0.9;
|
||||
|
||||
stresspat[30].name = "Slip jig";
|
||||
stresspat[30].meter = "3/4";
|
||||
stresspat[30].nseg = 9;
|
||||
stresspat[30].nval = 3;
|
||||
stresspat[30].vel[0] = 110;
|
||||
stresspat[30].vel[1] = 80;
|
||||
stresspat[30].vel[2] = 100;
|
||||
stresspat[30].expcoef[0] = (float) 1.3;
|
||||
stresspat[30].expcoef[1] = (float) 0.7;
|
||||
stresspat[30].expcoef[2] = (float) 1.0;
|
||||
|
||||
stresspat[31].name = "Tango";
|
||||
stresspat[31].meter = "2/4";
|
||||
stresspat[31].nseg = 8;
|
||||
stresspat[31].nval = 4;
|
||||
stresspat[31].vel[0] = 110;
|
||||
stresspat[31].vel[1] = 90;
|
||||
stresspat[31].vel[2] = 90;
|
||||
stresspat[31].vel[3] = 100;
|
||||
stresspat[31].expcoef[0] = (float) 1.6;
|
||||
stresspat[31].expcoef[1] = (float) 0.8;
|
||||
stresspat[31].expcoef[2] = (float) 0.8;
|
||||
stresspat[31].expcoef[3] = (float) 0.8;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
stress_locator (char *rhythmdesignator, char *timesigstring)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nmodels; i++)
|
||||
{
|
||||
if (casecmp (rhythmdesignator, stresspat[i].name) == 0 &&
|
||||
casecmp (timesigstring, stresspat[i].meter) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* [SS] 2015-12-31 load_stress_parameters returns 0 or -1 */
|
||||
int
|
||||
load_stress_parameters (char *rhythmdesignator)
|
||||
{
|
||||
int n, i, index, nval;
|
||||
int qnotenum, qnoteden;
|
||||
maxdur = 0;
|
||||
for (n = 0; n < 32; n++)
|
||||
{
|
||||
fdur[n] = 0.0;
|
||||
ngain[n] = 0;
|
||||
}
|
||||
fdursum[0] = fdur[0];
|
||||
if (strlen (rhythmdesignator) < 2)
|
||||
{
|
||||
beatmodel = 0;
|
||||
return -1;
|
||||
}
|
||||
index = stress_locator (rhythmdesignator, timesigstring);
|
||||
if (index == -1)
|
||||
{
|
||||
printf ("**warning** rhythm designator %s %s is not one of\n",
|
||||
rhythmdesignator, timesigstring);
|
||||
for (i = 0; i < nmodels; i++)
|
||||
{
|
||||
printf ("%s %s ", stresspat[i].name, stresspat[i].meter);
|
||||
if (i % 5 == 4)
|
||||
printf ("\n");
|
||||
}
|
||||
printf ("\n");
|
||||
beatmodel = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stressmodel == 0)
|
||||
beatmodel = 2;
|
||||
else
|
||||
beatmodel = stressmodel;
|
||||
|
||||
nseg = stresspat[index].nseg;
|
||||
nval = stresspat[index].nval;
|
||||
|
||||
segnum = time_num;
|
||||
segden = time_denom * nseg;
|
||||
reduce (&segnum, &segden);
|
||||
/* compute number of segments in quarter note */
|
||||
qnotenum = segden;
|
||||
qnoteden = segnum * 4;
|
||||
reduce (&qnotenum, &qnoteden);
|
||||
|
||||
for (n = 0; n < nseg + 1; n++)
|
||||
{
|
||||
i = n % nval;
|
||||
ngain[n] = stresspat[index].vel[i];
|
||||
fdur[n] = stresspat[index].expcoef[i];
|
||||
if (verbose)
|
||||
printf ("%d %f\n", ngain[n], fdur[n]);
|
||||
maxdur = MAX (maxdur, fdur[n]);
|
||||
if (n > 0)
|
||||
fdursum[n] =
|
||||
fdursum[n - 1] + fdur[n - 1] * (float) qnoteden / (float) qnotenum;
|
||||
/* num[],denom[] use quarter note units = 1/1, segment units are usually
|
||||
half that size, so we divide by 2.0
|
||||
*/
|
||||
}
|
||||
/*printf("maxdur = %f\n",maxdur);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* [SS] 2013-04-10 */
|
||||
void
|
||||
read_custom_stress_file (char *filename)
|
||||
{
|
||||
FILE *inhandle;
|
||||
char name[32];
|
||||
char meter[6];
|
||||
char str[4];
|
||||
int index;
|
||||
int nseg, nval;
|
||||
int gain;
|
||||
float expand;
|
||||
int i, j;
|
||||
init_stresspat ();
|
||||
inhandle = fopen (filename, "r");
|
||||
if (inhandle == NULL)
|
||||
{
|
||||
printf ("Failed to open file %s\n", filename);
|
||||
exit (1);
|
||||
}
|
||||
if (verbose > 0) printf("reading %s\n",filename);
|
||||
while (!feof (inhandle))
|
||||
{
|
||||
if (feof (inhandle))
|
||||
break;
|
||||
j = fscanf (inhandle, "%31s", name); /* [SDG] 2020-06-03 */
|
||||
if (j == -1)
|
||||
break;
|
||||
j = fscanf (inhandle, "%5s", meter); /* [SDG] 2020-06-03 */
|
||||
index = stress_locator (&name[0], &meter[0]);
|
||||
if (verbose > 1) printf ("%s %s index = %d\n",name,meter,index);
|
||||
|
||||
j = fscanf (inhandle, "%d %d", &nseg, &nval);
|
||||
if (verbose > 2) printf ("j = %d nseg = %d nval = %d\n", j, nseg, nval);
|
||||
if (j != 2) exit(-1);
|
||||
|
||||
if (nval > 16) {
|
||||
printf("stresspat.c: nval = %d is too large for structure %s\n",nval,name);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* copy model to stresspat[] */
|
||||
if (index <0) {
|
||||
/*creating new model, must include name and meter */
|
||||
index = nmodels;
|
||||
if (index > 47)
|
||||
{
|
||||
printf ("used up all available space for stress models\n");
|
||||
return;
|
||||
}
|
||||
nmodels++;
|
||||
stresspat[index].name =
|
||||
(char *) checkmalloc ((strlen (name) + 1) * sizeof (char));
|
||||
stresspat[index].meter =
|
||||
(char *) checkmalloc ((strlen (meter) + 1) * sizeof (char));
|
||||
strcpy(stresspat[index].name, name); /* [RZ] 2013-12-25 */
|
||||
strcpy(stresspat[index].meter, meter); /* [RZ] 2013-12-25 */
|
||||
}
|
||||
|
||||
stresspat[index].nseg = nseg;
|
||||
stresspat[index].nval = nval;
|
||||
for (i = 0; i < nval; i++)
|
||||
{
|
||||
j = fscanf (inhandle, "%d %f", &gain, &expand);
|
||||
if(verbose > 2) printf ("%d %f\n", gain, expand);
|
||||
if (j != 2) exit(1);
|
||||
if (feof (inhandle))
|
||||
break;
|
||||
stresspat[index].vel[i] = gain; /* [RZ] 2013-12-25 */
|
||||
stresspat[index].expcoef[i] = expand; /* [RZ] 2013-12-25 */
|
||||
}
|
||||
if (fgets (str, 3, inhandle) == NULL) break; /* [SDG] 2020-06-03 */
|
||||
}
|
||||
}
|
||||
240
structs.h
Normal file
240
structs.h
Normal file
@@ -0,0 +1,240 @@
|
||||
/* structs.h */
|
||||
/* Part of YAPS - abc to PostScript converter */
|
||||
/* Copyright James Allwright 2000 */
|
||||
/* May be copied under the terms of the GNU public license */
|
||||
|
||||
/* definitions of structures used to hold abc tune data */
|
||||
/* The voice data structure also holds various state variables */
|
||||
/* to allow processing of voice data as it is read in */
|
||||
|
||||
enum tail_type {nostem, single, startbeam, midbeam, endbeam};
|
||||
|
||||
/* holds a fraction */
|
||||
struct fract {
|
||||
int num;
|
||||
int denom;
|
||||
};
|
||||
extern void reducef(struct fract *f);
|
||||
extern void setfract(struct fract *f, int a, int b);
|
||||
|
||||
/* holds a key signature */
|
||||
struct key {
|
||||
char* name;
|
||||
int sharps;
|
||||
char map[7];
|
||||
int mult[7];
|
||||
};
|
||||
|
||||
/* holds a tempo specifier */
|
||||
struct atempo {
|
||||
int count;
|
||||
struct fract basenote;
|
||||
int relative;
|
||||
char *pre;
|
||||
char *post;
|
||||
};
|
||||
|
||||
/* holds a general tuple specifier */
|
||||
struct tuple {
|
||||
int n;
|
||||
int q;
|
||||
int r;
|
||||
int label;
|
||||
int beamed;
|
||||
float height;
|
||||
};
|
||||
|
||||
/* data relating to a chord */
|
||||
struct chord {
|
||||
int ytop;
|
||||
int ybot;
|
||||
enum tail_type beaming;
|
||||
float stemlength;
|
||||
int stemup;
|
||||
int base;
|
||||
int base_exp;
|
||||
};
|
||||
|
||||
/* elemental unit of a linked list */
|
||||
struct el {
|
||||
struct el* next;
|
||||
void* datum;
|
||||
};
|
||||
|
||||
/* high-level structure for linked list */
|
||||
struct llist {
|
||||
struct el* first;
|
||||
struct el* last;
|
||||
struct el* place;
|
||||
};
|
||||
|
||||
/* all information relating to a note */
|
||||
struct note {
|
||||
char* accents;
|
||||
char accidental;
|
||||
int fliphead;
|
||||
int acc_offset;
|
||||
int mult;
|
||||
int octave;
|
||||
char pitch;
|
||||
int tuplenotes;
|
||||
int y;
|
||||
int base_exp;
|
||||
int base;
|
||||
int dots;
|
||||
int stemup;
|
||||
enum tail_type beaming;
|
||||
struct llist* syllables;
|
||||
struct llist* gchords;
|
||||
struct llist* instructions;
|
||||
struct fract len;
|
||||
float stemlength;
|
||||
};
|
||||
|
||||
struct dynamic {
|
||||
char color;
|
||||
};
|
||||
|
||||
/* elemental unit of a voice list */
|
||||
/* item points to a note, bar-line or other feature */
|
||||
struct feature {
|
||||
struct feature* next;
|
||||
featuretype type;
|
||||
float xleft, xright, ydown, yup;
|
||||
float x;
|
||||
void* item;
|
||||
};
|
||||
|
||||
/* structure used by both slurs and ties */
|
||||
struct slurtie {
|
||||
struct feature* begin;
|
||||
struct feature* end;
|
||||
int crossline;
|
||||
};
|
||||
|
||||
enum cleftype {noclef, treble, soprano, mezzo, alto, tenor, baritone, bass};
|
||||
enum linestate {header, midline, newline};
|
||||
|
||||
struct aclef {
|
||||
enum cleftype type;
|
||||
int octave;
|
||||
};
|
||||
|
||||
/* holds calculated vertical spacing for one stave line */
|
||||
/* associated with PRINTLINE */
|
||||
struct vertspacing {
|
||||
float height;
|
||||
float descender;
|
||||
float yend;
|
||||
float yinstruct;
|
||||
float ygchord;
|
||||
float ywords;
|
||||
};
|
||||
|
||||
/* all variables relating to one voice */
|
||||
#define MAX_TIES 20
|
||||
#define MAX_SLURS 20
|
||||
struct voice {
|
||||
struct feature* first;
|
||||
struct feature* last;
|
||||
int voiceno;
|
||||
int octaveshift;
|
||||
int changetime;
|
||||
struct fract unitlen;
|
||||
struct fract tuplefactor;
|
||||
int tuplenotes;
|
||||
struct tuple* thistuple;
|
||||
int inslur, ingrace;
|
||||
int inchord, chordcount;
|
||||
struct fract chord;
|
||||
struct fract barlen;
|
||||
struct fract barcount;
|
||||
int barno;
|
||||
int barchecking;
|
||||
int expect_repeat;
|
||||
int brokentype, brokenmult, brokenpending;
|
||||
int tiespending;
|
||||
struct feature* tie_place[MAX_TIES];
|
||||
int tie_status[MAX_TIES];
|
||||
int slurpending;
|
||||
int slurcount;
|
||||
struct slurtie* slur_place[MAX_SLURS];
|
||||
struct feature* lastnote;
|
||||
struct feature* laststart;
|
||||
struct feature* lastend;
|
||||
int more_lyrics;
|
||||
int lyric_errors;
|
||||
struct feature* thisstart;
|
||||
struct feature* thisend;
|
||||
struct llist* gchords_pending;
|
||||
struct llist* instructions_pending;
|
||||
/* variables to handle tuples */
|
||||
int beamed_tuple_pending;
|
||||
int tuple_count;
|
||||
int tuplelabel;
|
||||
float tuple_xstart;
|
||||
float tuple_xend;
|
||||
float tuple_height;
|
||||
/* variables for assigning syllables to notes */
|
||||
struct feature* linestart;
|
||||
struct feature* lineend;
|
||||
struct chord* thischord;
|
||||
struct feature* chordplace;
|
||||
enum linestate line;
|
||||
/* following fields are initially inherited from tune */
|
||||
struct aclef* clef;
|
||||
struct key* keysig;
|
||||
struct fract meter;
|
||||
struct atempo* tempo;
|
||||
/* place used while printing to keep track of progress through voice */
|
||||
struct feature* lineplace;
|
||||
int atlineend;
|
||||
struct feature* place;
|
||||
int inmusic;
|
||||
struct fract time;
|
||||
/* following are used to determine stem direction of beamed set */
|
||||
struct feature* beamroot;
|
||||
struct feature* beamend;
|
||||
struct feature* gracebeamroot;
|
||||
struct feature* gracebeamend;
|
||||
int beammin, beammax;
|
||||
};
|
||||
|
||||
/* structure for the entire tune */
|
||||
struct tune {
|
||||
int no; /* from X: field */
|
||||
int octaveshift;
|
||||
struct llist title;
|
||||
char* composer;
|
||||
char* origin;
|
||||
char* parts;
|
||||
struct llist notes;
|
||||
struct fract meter;
|
||||
int barchecking;
|
||||
struct key* keysig;
|
||||
struct atempo* tempo;
|
||||
struct llist voices;
|
||||
struct voice* cv;
|
||||
struct fract unitlen;
|
||||
struct aclef clef;
|
||||
struct llist words;
|
||||
};
|
||||
|
||||
/* structure for a rest */
|
||||
struct rest {
|
||||
struct fract len;
|
||||
int base_exp;
|
||||
int base;
|
||||
int dots;
|
||||
int multibar; /* 0 indicates normal rest */
|
||||
struct llist* gchords;
|
||||
struct llist* instructions;
|
||||
};
|
||||
|
||||
/* list manipulation functions */
|
||||
void init_llist(struct llist* l);
|
||||
struct llist* newlist();
|
||||
void addtolist(struct llist* p, void* item);
|
||||
void* firstitem(struct llist* p);
|
||||
void* nextitem(struct llist* p);
|
||||
void freellist(struct llist* l);
|
||||
3019
yapstree.c
Normal file
3019
yapstree.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user