mirror of
https://github.com/sshlien/abcmidi.git
synced 2026-05-30 20:09:29 +00:00
Implement basic testing infrastructure (#19)
* Add configuration for CMake build system alongside autoconf - Add a modern CMake build system (`CMakeLists.txt`, `CMakePresets.json`) that coexists with the legacy autoconf/Makefile build - Shared source files (`midifile.c`, `parseabc.c`, `music_utils.c`, `parser2.c`) are compiled once via OBJECT libraries and linked into the 8 binaries - Three presets: `default` (Release), `debug`, `sanitize` (ASan + UBSan) - Generates `compile_commands.json` for clangd/LSP editor support - Install rules match the legacy Makefile (binaries, doc files, man pages) - Pinned to `-std=gnu89` because the codebase mixes K&R `()` and ANSI typed prototypes — in C23/gnu23 (GCC 15+ default), `()` means `(void)`, making these a hard error. Note: **the existing autoconf build is also broken with GCC 15** for the same reason ```sh cmake --preset debug cmake --build --preset debug cmake --install build/debug --prefix /usr/local Documentation - README.md: added Building section with both autoconf and CMake instructions - doc/readme.txt: added build instructions in the existing preamble - doc/CHANGES: added changelog entry Test plan - All 3 presets configure and build with GCC 15 - Smoke test: abc2midi samples/coleraine.abc produces valid MIDI through mftext - Sanitizer build (--preset sanitize) runs clean on sample files - Install layout verified: 8 binaries, 10 doc files, 8 man pages in correct paths - Build on macOS (untested, should work with AppleClang) * Implement basic testing infrastructure The CMake build includes a test suite covering all 8 programs: - **Smoke tests** verify each binary runs cleanly with `-ver`. - **Golden-file tests** run each program on a sample input and compare the (normalized) output to a checked-in reference. Binary MIDI outputs are piped through `mftext` to produce diffable text. Volatile lines (version banners, dates, temporary paths) are stripped before comparison. ```sh ctest --preset debug ctest --preset debug -L golden ctest --preset debug -L smoke ``` To regenerate the golden files after an intentional behavioural change, review the diff, then commit: ```sh cmake --build build/debug --target update-golden git diff tests/golden/ ``` * Factorize more the test CMake code
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ midi2abc
|
|||||||
midicopy
|
midicopy
|
||||||
midistats
|
midistats
|
||||||
yaps
|
yaps
|
||||||
|
/build/
|
||||||
|
|||||||
149
CMakeLists.txt
Normal file
149
CMakeLists.txt
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
|
# Read version from the VERSION file, matching the existing convention
|
||||||
|
file(STRINGS VERSION ABCMIDI_VERSION_STRING LIMIT_COUNT 1)
|
||||||
|
|
||||||
|
project(abcmidi
|
||||||
|
VERSION 2026.02.24
|
||||||
|
DESCRIPTION "ABC music notation tools: converters between ABC, MIDI, and PostScript"
|
||||||
|
LANGUAGES C
|
||||||
|
)
|
||||||
|
|
||||||
|
# Modern CMake: export compile_commands.json for clangd/LSP
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
# Default to Release if not specified
|
||||||
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
|
||||||
|
set_property(CACHE CMAKE_BUILD_TYPE
|
||||||
|
PROPERTY STRINGS Debug Release RelWithDebInfo MinSizeRel)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# --- Options ---
|
||||||
|
|
||||||
|
option(ABCMIDI_SANITIZERS "Enable AddressSanitizer and UndefinedBehaviorSanitizer" OFF)
|
||||||
|
|
||||||
|
# --- Compiler configuration ---
|
||||||
|
|
||||||
|
# Common compile options applied to every target via an INTERFACE library
|
||||||
|
add_library(abcmidi_common INTERFACE)
|
||||||
|
|
||||||
|
target_compile_definitions(abcmidi_common INTERFACE
|
||||||
|
ANSILIBS
|
||||||
|
)
|
||||||
|
|
||||||
|
# The codebase mixes K&R empty-parens "()" (meaning unspecified args) with
|
||||||
|
# ANSI typed prototypes. In C23/gnu23 (GCC 15+ default), "()" means "(void)",
|
||||||
|
# making these a hard error. Pin to gnu89 until the ANSI migration is complete,
|
||||||
|
# then switch to c_std_11 or later.
|
||||||
|
target_compile_options(abcmidi_common INTERFACE
|
||||||
|
$<$<C_COMPILER_ID:GNU,Clang,AppleClang>:
|
||||||
|
-std=gnu89
|
||||||
|
-Wall
|
||||||
|
>
|
||||||
|
)
|
||||||
|
|
||||||
|
if(ABCMIDI_SANITIZERS)
|
||||||
|
target_compile_options(abcmidi_common INTERFACE
|
||||||
|
-fsanitize=address,undefined -fno-omit-frame-pointer)
|
||||||
|
target_link_options(abcmidi_common INTERFACE
|
||||||
|
-fsanitize=address,undefined)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# --- Shared object libraries (compiled once, linked into multiple binaries) ---
|
||||||
|
|
||||||
|
add_library(obj_midifile OBJECT midifile.c)
|
||||||
|
target_link_libraries(obj_midifile PUBLIC abcmidi_common)
|
||||||
|
|
||||||
|
add_library(obj_parseabc OBJECT parseabc.c music_utils.c)
|
||||||
|
target_link_libraries(obj_parseabc PUBLIC abcmidi_common)
|
||||||
|
|
||||||
|
add_library(obj_parser2 OBJECT parser2.c)
|
||||||
|
target_link_libraries(obj_parser2 PUBLIC abcmidi_common)
|
||||||
|
|
||||||
|
# --- Executables ---
|
||||||
|
|
||||||
|
# abc2midi: ABC notation → MIDI
|
||||||
|
add_executable(abc2midi
|
||||||
|
store.c genmidi.c queues.c stresspat.c
|
||||||
|
)
|
||||||
|
target_link_libraries(abc2midi PRIVATE
|
||||||
|
obj_parseabc obj_parser2 obj_midifile abcmidi_common m)
|
||||||
|
|
||||||
|
# abc2abc: ABC notation → ABC notation (transposition, reformatting)
|
||||||
|
add_executable(abc2abc toabc.c)
|
||||||
|
target_link_libraries(abc2abc PRIVATE obj_parseabc abcmidi_common m)
|
||||||
|
|
||||||
|
# midi2abc: MIDI → ABC notation
|
||||||
|
add_executable(midi2abc midi2abc.c)
|
||||||
|
target_link_libraries(midi2abc PRIVATE obj_midifile abcmidi_common m)
|
||||||
|
|
||||||
|
# midistats: MIDI file statistics
|
||||||
|
add_executable(midistats midistats.c)
|
||||||
|
target_link_libraries(midistats PRIVATE obj_midifile abcmidi_common m)
|
||||||
|
|
||||||
|
# mftext: MIDI → human-readable text
|
||||||
|
add_executable(mftext mftext.c crack.c)
|
||||||
|
target_link_libraries(mftext PRIVATE obj_midifile abcmidi_common m)
|
||||||
|
|
||||||
|
# yaps: ABC notation → PostScript
|
||||||
|
add_executable(yaps
|
||||||
|
yapstree.c drawtune.c debug.c pslib.c position.c
|
||||||
|
)
|
||||||
|
target_link_libraries(yaps PRIVATE
|
||||||
|
obj_parseabc obj_parser2 abcmidi_common m)
|
||||||
|
|
||||||
|
# midicopy: MIDI file filtering/extraction
|
||||||
|
add_executable(midicopy midicopy.c)
|
||||||
|
target_link_libraries(midicopy PRIVATE abcmidi_common m)
|
||||||
|
|
||||||
|
# abcmatch: ABC tune matching/comparison
|
||||||
|
add_executable(abcmatch abcmatch.c matchsup.c)
|
||||||
|
target_link_libraries(abcmatch PRIVATE obj_parseabc abcmidi_common m)
|
||||||
|
|
||||||
|
# --- Install ---
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
set(ABCMIDI_BINARIES abc2midi abc2abc midi2abc midistats mftext yaps midicopy abcmatch)
|
||||||
|
|
||||||
|
install(TARGETS ${ABCMIDI_BINARIES}
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Match the legacy Makefile: install only top-level doc files, not subdirectories
|
||||||
|
install(FILES
|
||||||
|
doc/abcguide.txt
|
||||||
|
doc/abcmatch.txt
|
||||||
|
doc/gpl.txt
|
||||||
|
doc/history.txt
|
||||||
|
doc/hudsonshift.txt
|
||||||
|
doc/readme.txt
|
||||||
|
doc/yapshelp.txt
|
||||||
|
doc/AUTHORS
|
||||||
|
doc/CHANGES
|
||||||
|
VERSION
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DOCDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
doc/abc2abc.1
|
||||||
|
doc/abc2midi.1
|
||||||
|
doc/abcmatch.1
|
||||||
|
doc/mftext.1
|
||||||
|
doc/midi2abc.1
|
||||||
|
doc/midicopy.1
|
||||||
|
doc/midistats.1
|
||||||
|
doc/yaps.1
|
||||||
|
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- Tests ---
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# TODO: install-validation test that verifies all binaries, doc files, and man
|
||||||
|
# pages are installed to the expected paths.
|
||||||
66
CMakePresets.json
Normal file
66
CMakePresets.json
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"version": 6,
|
||||||
|
"cmakeMinimumRequired": { "major": 3, "minor": 25, "patch": 0 },
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"displayName": "Default (Release)",
|
||||||
|
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Release"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug",
|
||||||
|
"displayName": "Debug",
|
||||||
|
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sanitize",
|
||||||
|
"displayName": "Debug + Sanitizers (ASan + UBSan)",
|
||||||
|
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"ABCMIDI_SANITIZERS": "ON"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildPresets": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"configurePreset": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug",
|
||||||
|
"configurePreset": "debug"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sanitize",
|
||||||
|
"configurePreset": "sanitize"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"testPresets": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"configurePreset": "default",
|
||||||
|
"output": { "outputOnFailure": true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug",
|
||||||
|
"configurePreset": "debug",
|
||||||
|
"output": { "outputOnFailure": true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sanitize",
|
||||||
|
"configurePreset": "sanitize",
|
||||||
|
"output": { "outputOnFailure": true },
|
||||||
|
"environment": {
|
||||||
|
"ASAN_OPTIONS": "abort_on_error=1:halt_on_error=1",
|
||||||
|
"UBSAN_OPTIONS": "abort_on_error=1:halt_on_error=1:print_stacktrace=1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
66
README.md
66
README.md
@@ -20,3 +20,69 @@ Components of the abcMIDI package are parts of numerous applications for creatin
|
|||||||
|
|
||||||
The latest version of the abcMIDI package supported by James Allwright can be found can be found [here](http://abc.sourceforge.net/abcMIDI/original/). More recent versions can be found on [sourceforge](https://sourceforge.net/projects/abc/) and on the [runabc](https://ifdo.ca/~seymour/runabc/top.html) web page.
|
The latest version of the abcMIDI package supported by James Allwright can be found can be found [here](http://abc.sourceforge.net/abcMIDI/original/). More recent versions can be found on [sourceforge](https://sourceforge.net/projects/abc/) and on the [runabc](https://ifdo.ca/~seymour/runabc/top.html) web page.
|
||||||
|
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
#### Autoconf (legacy)
|
||||||
|
|
||||||
|
The traditional build uses autoconf:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
#### CMake (modern)
|
||||||
|
|
||||||
|
A CMake build system is available alongside the legacy one, with
|
||||||
|
[presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html)
|
||||||
|
for common configurations:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Configure and build (pick a preset: default, debug, sanitize)
|
||||||
|
cmake --preset default
|
||||||
|
cmake --build --preset default
|
||||||
|
|
||||||
|
# Install
|
||||||
|
cmake --install build/default
|
||||||
|
```
|
||||||
|
|
||||||
|
Available presets:
|
||||||
|
|
||||||
|
| Preset | Build type | Description |
|
||||||
|
|------------|------------|----------------------------------------------|
|
||||||
|
| `default` | Release | Optimized build |
|
||||||
|
| `debug` | Debug | Debug symbols, no optimization |
|
||||||
|
| `sanitize` | Debug | Debug + AddressSanitizer + UndefinedBehaviorSanitizer |
|
||||||
|
|
||||||
|
The CMake build generates `compile_commands.json` for use with
|
||||||
|
clangd and other LSP-based editors.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
The CMake build includes a test suite covering all 8 programs:
|
||||||
|
|
||||||
|
- **Smoke tests** verify each binary runs cleanly with `-ver`.
|
||||||
|
- **Golden-file tests** run each program on a sample input and compare the
|
||||||
|
(normalized) output to a checked-in reference. Binary MIDI outputs are
|
||||||
|
piped through `mftext` to produce diffable text. Volatile lines (version
|
||||||
|
banners, dates, temporary paths) are stripped before comparison.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Run all tests
|
||||||
|
ctest --preset debug
|
||||||
|
|
||||||
|
# Run only golden-file tests / only smoke tests
|
||||||
|
ctest --preset debug -L golden
|
||||||
|
ctest --preset debug -L smoke
|
||||||
|
```
|
||||||
|
|
||||||
|
To regenerate the golden files after an intentional behavioural change,
|
||||||
|
review the diff, then commit:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cmake --build build/debug --target update-golden
|
||||||
|
git diff tests/golden/
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -15688,3 +15688,12 @@ it has been restructured. Changes in genmidi.c (PART case in writetrack,
|
|||||||
partmarkers global) and store.c (event_part, event_init for -PMAR flag).
|
partmarkers global) and store.c (event_part, event_init for -PMAR flag).
|
||||||
Man page updated in doc/abc2midi.1.
|
Man page updated in doc/abc2midi.1.
|
||||||
|
|
||||||
|
2026 April 01
|
||||||
|
build: added CMake build system (CMakeLists.txt, CMakePresets.json)
|
||||||
|
alongside the existing autoconf build. Three presets are provided:
|
||||||
|
default (Release), debug, and sanitize (ASan+UBSan). Shared source
|
||||||
|
files (midifile.c, parseabc.c, music_utils.c, parser2.c) are compiled
|
||||||
|
once via OBJECT libraries. The build exports compile_commands.json
|
||||||
|
for LSP/clangd support. Note: the codebase requires -std=gnu89 until
|
||||||
|
the K&R-to-ANSI prototype migration is completed.
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,22 @@ http://www.harmony-central.com/MIDI/midifilelib.tar.gz
|
|||||||
|
|
||||||
If you have the source distribution and intend to re-compile the code,
|
If you have the source distribution and intend to re-compile the code,
|
||||||
read the file coding.txt.
|
read the file coding.txt.
|
||||||
|
|
||||||
|
Building with autoconf (legacy):
|
||||||
|
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
|
|
||||||
|
Building with CMake (modern):
|
||||||
|
|
||||||
|
cmake --preset default
|
||||||
|
cmake --build --preset default
|
||||||
|
cmake --install build/default
|
||||||
|
|
||||||
|
Available CMake presets: default (Release), debug, sanitize (ASan+UBSan).
|
||||||
|
Run "cmake --list-presets" to see all available presets.
|
||||||
|
You can override settings in a personal CMakeUserPresets.json file.
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
midi2abc - program to convert MIDI format files to abc notation.
|
midi2abc - program to convert MIDI format files to abc notation.
|
||||||
|
|
||||||
|
|||||||
83
tests/CMakeLists.txt
Normal file
83
tests/CMakeLists.txt
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# abcmidi test suite
|
||||||
|
#
|
||||||
|
# Two layers of tests:
|
||||||
|
#
|
||||||
|
# 1. Smoke tests - every binary runs with -ver and exits cleanly.
|
||||||
|
# Catches link errors, missing libraries, trivial crashes.
|
||||||
|
#
|
||||||
|
# 2. Golden tests - each program is run on a sample input and its output
|
||||||
|
# is compared with a checked-in reference file. Binary
|
||||||
|
# MIDI outputs are first piped through mftext to produce
|
||||||
|
# diffable text. Volatile lines (version banners, dates,
|
||||||
|
# tmpdir paths) are stripped before comparison.
|
||||||
|
#
|
||||||
|
# To regenerate golden files after an intentional change:
|
||||||
|
#
|
||||||
|
# ABCMIDI_UPDATE_GOLDEN=1 ctest --preset debug
|
||||||
|
#
|
||||||
|
# Then review the diff and commit the updated tests/golden/*.txt files.
|
||||||
|
|
||||||
|
set(SAMPLES_DIR "${PROJECT_SOURCE_DIR}/samples")
|
||||||
|
set(GOLDEN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/golden")
|
||||||
|
set(TEST_TMPDIR "${CMAKE_CURRENT_BINARY_DIR}/tmp")
|
||||||
|
|
||||||
|
# --- Smoke tests: -ver on every binary ---
|
||||||
|
|
||||||
|
foreach(bin IN LISTS ABCMIDI_BINARIES)
|
||||||
|
add_test(NAME "smoke_${bin}_ver" COMMAND $<TARGET_FILE:${bin}> -ver)
|
||||||
|
set_tests_properties("smoke_${bin}_ver" PROPERTIES LABELS "smoke")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# --- Golden tests ---
|
||||||
|
|
||||||
|
# Build a list of "-D<BIN>=$<TARGET_FILE:bin>" args, one per binary, so that
|
||||||
|
# run_test.cmake receives all binary paths uniformly.
|
||||||
|
set(BINARY_DEFS)
|
||||||
|
foreach(bin IN LISTS ABCMIDI_BINARIES)
|
||||||
|
string(TOUPPER "${bin}" BIN_UPPER)
|
||||||
|
list(APPEND BINARY_DEFS "-D${BIN_UPPER}=$<TARGET_FILE:${bin}>")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Helper: register a golden test for one program against one sample
|
||||||
|
function(add_golden_test)
|
||||||
|
cmake_parse_arguments(T "" "TYPE;SAMPLE" "" ${ARGN})
|
||||||
|
|
||||||
|
get_filename_component(stem "${T_SAMPLE}" NAME_WE)
|
||||||
|
set(test_name "${T_TYPE}_${stem}")
|
||||||
|
|
||||||
|
add_test(
|
||||||
|
NAME "${test_name}"
|
||||||
|
COMMAND "${CMAKE_COMMAND}"
|
||||||
|
-DTYPE=${T_TYPE}
|
||||||
|
-DSAMPLE=${SAMPLES_DIR}/${T_SAMPLE}
|
||||||
|
-DGOLDEN=${GOLDEN_DIR}/${test_name}.txt
|
||||||
|
-DTMPDIR=${TEST_TMPDIR}
|
||||||
|
${BINARY_DEFS}
|
||||||
|
-P "${CMAKE_CURRENT_SOURCE_DIR}/run_test.cmake"
|
||||||
|
)
|
||||||
|
set_tests_properties("${test_name}" PROPERTIES LABELS "golden")
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# One golden test per program against coleraine.abc
|
||||||
|
foreach(type IN ITEMS abc2midi abc2abc midi2abc midistats mftext yaps midicopy abcmatch)
|
||||||
|
add_golden_test(TYPE ${type} SAMPLE coleraine.abc)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# A few extra coverage points on different samples
|
||||||
|
add_golden_test(TYPE abc2midi SAMPLE demo.abc)
|
||||||
|
add_golden_test(TYPE abc2abc SAMPLE demo.abc)
|
||||||
|
|
||||||
|
# --- Regenerate-golden convenience target ---
|
||||||
|
#
|
||||||
|
# Usage: cmake --build build/debug --target update-golden
|
||||||
|
#
|
||||||
|
# Equivalent to setting ABCMIDI_UPDATE_GOLDEN=1 and running ctest, but easier
|
||||||
|
# to discover via cmake --build --target.
|
||||||
|
|
||||||
|
add_custom_target(update-golden
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E env ABCMIDI_UPDATE_GOLDEN=1
|
||||||
|
${CMAKE_CTEST_COMMAND} -L golden --output-on-failure
|
||||||
|
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||||
|
COMMENT "Regenerating golden test references"
|
||||||
|
USES_TERMINAL
|
||||||
|
)
|
||||||
54
tests/golden/abc2abc_coleraine.txt
Normal file
54
tests/golden/abc2abc_coleraine.txt
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
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
|
||||||
|
%Error : Bar 1 is 1/8 not 6/8
|
||||||
|
| "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 :|
|
||||||
|
|
||||||
294
tests/golden/abc2abc_demo.txt
Normal file
294
tests/golden/abc2abc_demo.txt
Normal file
@@ -0,0 +1,294 @@
|
|||||||
|
% 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
|
||||||
|
%Error : Bar 1 is 1/8 not 6/8
|
||||||
|
|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
|
||||||
|
%Error : Bar 17 is 1/4 not 4/4
|
||||||
|
|\
|
||||||
|
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
|
||||||
|
%Error : Bar 34 is 1/4 not 4/4
|
||||||
|
|\
|
||||||
|
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
|
||||||
|
%Error : Bar 51 is 1/4 not 4/4
|
||||||
|
|\
|
||||||
|
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
|
||||||
|
%Error : Bar 1 is 1/4 not 4/4
|
||||||
|
|\
|
||||||
|
"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:1/4=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
|
||||||
|
%Error : Bar 1 is 5/2 not 4/4
|
||||||
|
|
|
||||||
|
FFF A2 G2 {F} EEE G2 F2 {E} DDDF2 E2
|
||||||
|
%Error : Bar 2 is 21/8 not 4/4
|
||||||
|
|
|
||||||
|
|
||||||
|
%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)|
|
||||||
|
%Warning : Missing repeat at start ? Unexpected :| found
|
||||||
|
"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)|
|
||||||
|
%Warning : Unexpected :| found
|
||||||
|
"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/2z/2 ^A2 |
|
||||||
|
V:2
|
||||||
|
%%MIDI program 16
|
||||||
|
G2 G2 | G3/2z/2 G2 |
|
||||||
|
V:3
|
||||||
|
%%MIDI program 16
|
||||||
|
(3E_E^D (3=DF_F | =E3/2z/2 E2 |
|
||||||
|
V:4
|
||||||
|
%%MIDI program 16
|
||||||
|
C2 G,2 | C3/2z/2 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
|
||||||
|
%Error : Bar 7 is 3/4 not 4/4
|
||||||
|
||
|
||||||
|
V:2
|
||||||
|
%%MIDI channel 10
|
||||||
|
%%MIDI chordattack 50
|
||||||
|
[^F,,E,,]/2[^F,,E,,]/2[D,,^F,,]/2[D,,^F,,]/2 ^F,,F,, z4|^F,,E,,E,,^F,,z4|\
|
||||||
|
[^F,,E,,]/2[^F,,E,,]/2[D,,^F,,]/2[D,,^F,,]/2 ^F,,F,, z4|D,,D,,D,,^F,,z4|
|
||||||
|
[^F,,E,,]/2[^F,,E,,]/2[D,,^F,,]/2[D,,^F,,]/2 ^F,,F,, z4|^F,,D,,D,,^F,,z4|\
|
||||||
|
[^F,,E,,]/2[^F,,E,,]/2[D,,^F,,]/2[D,,^F,,]/2 ^F,,E,, z4|E,,^F,,B,,,4
|
||||||
|
%Error : Bar 15 is 3/4 not 4/4
|
||||||
|
|
|
||||||
|
|
||||||
1706
tests/golden/abc2midi_coleraine.txt
Normal file
1706
tests/golden/abc2midi_coleraine.txt
Normal file
File diff suppressed because it is too large
Load Diff
389
tests/golden/abc2midi_demo.txt
Normal file
389
tests/golden/abc2midi_demo.txt
Normal file
@@ -0,0 +1,389 @@
|
|||||||
|
Header format=0 ntrks=1 division=480
|
||||||
|
Track start
|
||||||
|
Time=0 Meta Text, type=0x01 (Text Event) leng=10
|
||||||
|
Text = <note track>
|
||||||
|
Time=0 Tempo, microseconds-per-MIDI-quarter-note=472440
|
||||||
|
Time=0 Key signature, sharp/flats=1 minor=0
|
||||||
|
Time=0 Time signature=4/4 MIDI-clocks/click=48 32nd-notes/24-MIDI-clocks=8
|
||||||
|
Time=0 Meta Text, type=0x03 (Sequence/Track Name) leng=13
|
||||||
|
Text = <Horses Branle>
|
||||||
|
Time=1 Note on, chan=1 pitch=67 vol=105
|
||||||
|
Time=360 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=361 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=480 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=481 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=720 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=721 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=960 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=961 Note on, chan=1 pitch=72 vol=95
|
||||||
|
Time=1200 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=1201 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=1440 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=1441 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=1680 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=1681 Note on, chan=1 pitch=72 vol=80
|
||||||
|
Time=1920 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=1921 Note on, chan=1 pitch=71 vol=105
|
||||||
|
Time=2160 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=2161 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=2400 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=2401 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=2640 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=2641 Note on, chan=1 pitch=66 vol=80
|
||||||
|
Time=2880 Note off, chan=1 pitch=66 vol=0
|
||||||
|
Time=2881 Note on, chan=1 pitch=64 vol=95
|
||||||
|
Time=3360 Note off, chan=1 pitch=64 vol=0
|
||||||
|
Time=3361 Note on, chan=1 pitch=62 vol=80
|
||||||
|
Time=3840 Note off, chan=1 pitch=62 vol=0
|
||||||
|
Time=3841 Note on, chan=1 pitch=67 vol=105
|
||||||
|
Time=4200 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=4201 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=4320 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=4321 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=4560 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=4561 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=4800 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=4801 Note on, chan=1 pitch=72 vol=95
|
||||||
|
Time=5040 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=5041 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=5280 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=5281 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=5520 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=5521 Note on, chan=1 pitch=72 vol=80
|
||||||
|
Time=5760 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=5761 Note on, chan=1 pitch=71 vol=105
|
||||||
|
Time=6000 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=6001 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=6240 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=6241 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=6480 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=6481 Note on, chan=1 pitch=66 vol=80
|
||||||
|
Time=6720 Note off, chan=1 pitch=66 vol=0
|
||||||
|
Time=6721 Note on, chan=1 pitch=67 vol=95
|
||||||
|
Time=7200 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=7201 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=7680 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=7681 Note on, chan=1 pitch=67 vol=105
|
||||||
|
Time=8040 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=8041 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=8160 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=8161 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=8400 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=8401 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=8640 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=8641 Note on, chan=1 pitch=72 vol=95
|
||||||
|
Time=8880 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=8881 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=9120 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=9121 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=9360 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=9361 Note on, chan=1 pitch=72 vol=80
|
||||||
|
Time=9600 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=9601 Note on, chan=1 pitch=71 vol=105
|
||||||
|
Time=9840 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=9841 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=10080 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=10081 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=10320 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=10321 Note on, chan=1 pitch=66 vol=80
|
||||||
|
Time=10560 Note off, chan=1 pitch=66 vol=0
|
||||||
|
Time=10561 Note on, chan=1 pitch=64 vol=95
|
||||||
|
Time=11040 Note off, chan=1 pitch=64 vol=0
|
||||||
|
Time=11041 Note on, chan=1 pitch=62 vol=80
|
||||||
|
Time=11520 Note off, chan=1 pitch=62 vol=0
|
||||||
|
Time=11521 Note on, chan=1 pitch=67 vol=105
|
||||||
|
Time=11880 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=11881 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=12000 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=12001 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=12240 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=12241 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=12480 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=12481 Note on, chan=1 pitch=72 vol=95
|
||||||
|
Time=12720 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=12721 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=12960 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=12961 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=13200 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=13201 Note on, chan=1 pitch=72 vol=80
|
||||||
|
Time=13440 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=13441 Note on, chan=1 pitch=71 vol=105
|
||||||
|
Time=13680 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=13681 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=13920 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=13921 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=14160 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=14161 Note on, chan=1 pitch=66 vol=80
|
||||||
|
Time=14400 Note off, chan=1 pitch=66 vol=0
|
||||||
|
Time=14401 Note on, chan=1 pitch=67 vol=95
|
||||||
|
Time=14880 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=14881 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=15360 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=15361 Note on, chan=1 pitch=74 vol=105
|
||||||
|
Time=15600 Note off, chan=1 pitch=74 vol=0
|
||||||
|
Time=15601 Note on, chan=1 pitch=72 vol=80
|
||||||
|
Time=15720 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=15721 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=15840 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=15841 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=16080 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=16081 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=16320 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=16321 Note on, chan=1 pitch=72 vol=95
|
||||||
|
Time=16560 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=16561 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=16680 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=16681 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=16800 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=16801 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=17040 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=17041 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=17280 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=17281 Note on, chan=1 pitch=69 vol=105
|
||||||
|
Time=17520 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=17521 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=17760 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=17761 Note on, chan=1 pitch=66 vol=80
|
||||||
|
Time=18000 Note off, chan=1 pitch=66 vol=0
|
||||||
|
Time=18001 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=18240 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=18241 Note on, chan=1 pitch=69 vol=95
|
||||||
|
Time=18600 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=18601 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=18720 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=18721 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=19200 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=19201 Note on, chan=1 pitch=74 vol=105
|
||||||
|
Time=19440 Note off, chan=1 pitch=74 vol=0
|
||||||
|
Time=19441 Note on, chan=1 pitch=72 vol=80
|
||||||
|
Time=19560 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=19561 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=19680 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=19681 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=19920 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=19921 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=20160 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=20161 Note on, chan=1 pitch=72 vol=95
|
||||||
|
Time=20400 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=20401 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=20520 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=20521 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=20640 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=20641 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=20880 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=20881 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=21120 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=21121 Note on, chan=1 pitch=69 vol=105
|
||||||
|
Time=21360 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=21361 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=21600 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=21601 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=21840 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=21841 Note on, chan=1 pitch=66 vol=80
|
||||||
|
Time=22080 Note off, chan=1 pitch=66 vol=0
|
||||||
|
Time=22081 Note on, chan=1 pitch=67 vol=95
|
||||||
|
Time=22560 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=22561 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=23040 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=23041 Note on, chan=1 pitch=74 vol=105
|
||||||
|
Time=23280 Note off, chan=1 pitch=74 vol=0
|
||||||
|
Time=23281 Note on, chan=1 pitch=72 vol=80
|
||||||
|
Time=23400 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=23401 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=23520 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=23521 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=23760 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=23761 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=24000 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=24001 Note on, chan=1 pitch=72 vol=95
|
||||||
|
Time=24240 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=24241 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=24360 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=24361 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=24480 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=24481 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=24720 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=24721 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=24960 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=24961 Note on, chan=1 pitch=69 vol=105
|
||||||
|
Time=25200 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=25201 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=25440 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=25441 Note on, chan=1 pitch=66 vol=80
|
||||||
|
Time=25680 Note off, chan=1 pitch=66 vol=0
|
||||||
|
Time=25681 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=25920 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=25921 Note on, chan=1 pitch=69 vol=95
|
||||||
|
Time=26280 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=26281 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=26400 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=26401 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=26880 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=26881 Note on, chan=1 pitch=74 vol=105
|
||||||
|
Time=27120 Note off, chan=1 pitch=74 vol=0
|
||||||
|
Time=27121 Note on, chan=1 pitch=72 vol=80
|
||||||
|
Time=27240 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=27241 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=27360 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=27361 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=27600 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=27601 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=27840 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=27841 Note on, chan=1 pitch=72 vol=95
|
||||||
|
Time=28080 Note off, chan=1 pitch=72 vol=0
|
||||||
|
Time=28081 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=28200 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=28201 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=28320 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=28321 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=28560 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=28561 Note on, chan=1 pitch=71 vol=80
|
||||||
|
Time=28800 Note off, chan=1 pitch=71 vol=0
|
||||||
|
Time=28801 Note on, chan=1 pitch=69 vol=105
|
||||||
|
Time=29040 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=29041 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=29280 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=29281 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=29520 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=29521 Note on, chan=1 pitch=66 vol=80
|
||||||
|
Time=29760 Note off, chan=1 pitch=66 vol=0
|
||||||
|
Time=29761 Note on, chan=1 pitch=67 vol=95
|
||||||
|
Time=30240 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=30241 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=30720 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=30720 Key signature, sharp/flats=-1 minor=0
|
||||||
|
Time=30721 Note on, chan=1 pitch=70 vol=105
|
||||||
|
Time=30840 Note off, chan=1 pitch=70 vol=0
|
||||||
|
Time=30841 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=30960 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=30961 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=31200 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=31201 Note on, chan=1 pitch=70 vol=80
|
||||||
|
Time=31320 Note off, chan=1 pitch=70 vol=0
|
||||||
|
Time=31321 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=31440 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=31441 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=31680 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=31681 Note on, chan=1 pitch=65 vol=95
|
||||||
|
Time=31920 Note off, chan=1 pitch=65 vol=0
|
||||||
|
Time=31921 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=32160 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=32161 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=32640 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=32641 Note on, chan=1 pitch=62 vol=105
|
||||||
|
Time=32880 Note off, chan=1 pitch=62 vol=0
|
||||||
|
Time=32881 Note on, chan=1 pitch=64 vol=80
|
||||||
|
Time=33120 Note off, chan=1 pitch=64 vol=0
|
||||||
|
Time=33121 Note on, chan=1 pitch=65 vol=80
|
||||||
|
Time=33360 Note off, chan=1 pitch=65 vol=0
|
||||||
|
Time=33361 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=33600 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=33601 Note on, chan=1 pitch=69 vol=95
|
||||||
|
Time=33840 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=33841 Note on, chan=1 pitch=70 vol=80
|
||||||
|
Time=34080 Note off, chan=1 pitch=70 vol=0
|
||||||
|
Time=34081 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=34320 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=34321 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=34560 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=34561 Note on, chan=1 pitch=70 vol=105
|
||||||
|
Time=34680 Note off, chan=1 pitch=70 vol=0
|
||||||
|
Time=34681 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=34800 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=34801 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=35040 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=35041 Note on, chan=1 pitch=70 vol=80
|
||||||
|
Time=35160 Note off, chan=1 pitch=70 vol=0
|
||||||
|
Time=35161 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=35280 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=35281 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=35520 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=35521 Note on, chan=1 pitch=65 vol=95
|
||||||
|
Time=35760 Note off, chan=1 pitch=65 vol=0
|
||||||
|
Time=35761 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=36000 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=36001 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=36480 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=36481 Note on, chan=1 pitch=62 vol=105
|
||||||
|
Time=36720 Note off, chan=1 pitch=62 vol=0
|
||||||
|
Time=36721 Note on, chan=1 pitch=64 vol=80
|
||||||
|
Time=36960 Note off, chan=1 pitch=64 vol=0
|
||||||
|
Time=36961 Note on, chan=1 pitch=65 vol=80
|
||||||
|
Time=37200 Note off, chan=1 pitch=65 vol=0
|
||||||
|
Time=37201 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=37440 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=37441 Note on, chan=1 pitch=67 vol=95
|
||||||
|
Time=37680 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=37681 Note on, chan=1 pitch=65 vol=80
|
||||||
|
Time=37920 Note off, chan=1 pitch=65 vol=0
|
||||||
|
Time=37921 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=38400 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=38400 Key signature, sharp/flats=-1 minor=0
|
||||||
|
Time=38401 Note on, chan=1 pitch=70 vol=105
|
||||||
|
Time=38520 Note off, chan=1 pitch=70 vol=0
|
||||||
|
Time=38521 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=38640 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=38641 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=38880 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=38881 Note on, chan=1 pitch=70 vol=80
|
||||||
|
Time=39000 Note off, chan=1 pitch=70 vol=0
|
||||||
|
Time=39001 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=39120 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=39121 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=39360 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=39361 Note on, chan=1 pitch=65 vol=95
|
||||||
|
Time=39600 Note off, chan=1 pitch=65 vol=0
|
||||||
|
Time=39601 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=39840 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=39841 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=40320 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=40321 Note on, chan=1 pitch=62 vol=105
|
||||||
|
Time=40560 Note off, chan=1 pitch=62 vol=0
|
||||||
|
Time=40561 Note on, chan=1 pitch=64 vol=80
|
||||||
|
Time=40800 Note off, chan=1 pitch=64 vol=0
|
||||||
|
Time=40801 Note on, chan=1 pitch=65 vol=80
|
||||||
|
Time=41040 Note off, chan=1 pitch=65 vol=0
|
||||||
|
Time=41041 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=41280 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=41281 Note on, chan=1 pitch=69 vol=95
|
||||||
|
Time=41520 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=41521 Note on, chan=1 pitch=70 vol=80
|
||||||
|
Time=41760 Note off, chan=1 pitch=70 vol=0
|
||||||
|
Time=41761 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=42000 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=42001 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=42240 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=42241 Note on, chan=1 pitch=70 vol=105
|
||||||
|
Time=42360 Note off, chan=1 pitch=70 vol=0
|
||||||
|
Time=42361 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=42480 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=42481 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=42720 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=42721 Note on, chan=1 pitch=70 vol=80
|
||||||
|
Time=42840 Note off, chan=1 pitch=70 vol=0
|
||||||
|
Time=42841 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=42960 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=42961 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=43200 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=43201 Note on, chan=1 pitch=65 vol=95
|
||||||
|
Time=43440 Note off, chan=1 pitch=65 vol=0
|
||||||
|
Time=43441 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=43680 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=43681 Note on, chan=1 pitch=69 vol=80
|
||||||
|
Time=44160 Note off, chan=1 pitch=69 vol=0
|
||||||
|
Time=44161 Note on, chan=1 pitch=62 vol=105
|
||||||
|
Time=44400 Note off, chan=1 pitch=62 vol=0
|
||||||
|
Time=44401 Note on, chan=1 pitch=64 vol=80
|
||||||
|
Time=44640 Note off, chan=1 pitch=64 vol=0
|
||||||
|
Time=44641 Note on, chan=1 pitch=65 vol=80
|
||||||
|
Time=44880 Note off, chan=1 pitch=65 vol=0
|
||||||
|
Time=44881 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=45120 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=45121 Note on, chan=1 pitch=67 vol=95
|
||||||
|
Time=45360 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=45361 Note on, chan=1 pitch=65 vol=80
|
||||||
|
Time=45600 Note off, chan=1 pitch=65 vol=0
|
||||||
|
Time=45601 Note on, chan=1 pitch=67 vol=80
|
||||||
|
Time=46080 Note off, chan=1 pitch=67 vol=0
|
||||||
|
Time=46106 Meta event, end of track
|
||||||
|
Track end
|
||||||
15
tests/golden/abcmatch_coleraine.txt
Normal file
15
tests/golden/abcmatch_coleraine.txt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
pitch_histogram
|
||||||
|
43 51
|
||||||
|
45 42
|
||||||
|
64 9
|
||||||
|
66 1
|
||||||
|
68 7
|
||||||
|
69 19
|
||||||
|
71 16
|
||||||
|
72 12
|
||||||
|
74 7
|
||||||
|
76 9
|
||||||
|
77 1
|
||||||
|
79 2
|
||||||
|
80 1
|
||||||
|
81 1
|
||||||
1706
tests/golden/mftext_coleraine.txt
Normal file
1706
tests/golden/mftext_coleraine.txt
Normal file
File diff suppressed because it is too large
Load Diff
148
tests/golden/midi2abc_coleraine.txt
Normal file
148
tests/golden/midi2abc_coleraine.txt
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
calling midi2abc
|
||||||
|
X: 1
|
||||||
|
T: from midi2abc_coleraine.mid
|
||||||
|
M: 6/8
|
||||||
|
L: 1/8
|
||||||
|
Q:1/4=142
|
||||||
|
K:C % 0 sharps
|
||||||
|
V:1
|
||||||
|
%%MIDI program 26
|
||||||
|
%%MIDI program 72
|
||||||
|
EE>A AAB| \
|
||||||
|
cB>e ee2| \
|
||||||
|
dc>A AAB| \
|
||||||
|
cB^G EE2|
|
||||||
|
EE>A AAB| \
|
||||||
|
cB>e ee2| \
|
||||||
|
dc>B AB^G| \
|
||||||
|
EA4-A|
|
||||||
|
EE>A AAB| \
|
||||||
|
cB>e ee2| \
|
||||||
|
dc>A AAB| \
|
||||||
|
cB^G EE2|
|
||||||
|
EE>A AAB| \
|
||||||
|
cB>e ee2| \
|
||||||
|
dc>B AB^G| \
|
||||||
|
EA4-A|
|
||||||
|
Bc2 ccd| \
|
||||||
|
cBd gg2| \
|
||||||
|
^ga>e dcB| \
|
||||||
|
A^GB GE^F|
|
||||||
|
^GAG ABA| \
|
||||||
|
Bcd efe| \
|
||||||
|
dc>B AB^G| \
|
||||||
|
EA4-A|
|
||||||
|
Bc2 ccd| \
|
||||||
|
cBd gg2| \
|
||||||
|
^ga>e dcB| \
|
||||||
|
A^GB GE^F|
|
||||||
|
^GAG ABA| \
|
||||||
|
Bcd efe| \
|
||||||
|
dc>B AB^G| \
|
||||||
|
EA4-A|
|
||||||
|
V:2
|
||||||
|
%%MIDI program 3
|
||||||
|
%%MIDI program 3
|
||||||
|
E,,A,,z [ECA,]A,,z| \
|
||||||
|
[ECA,]E,,z [DB,^G,E,]E,,z| \
|
||||||
|
[DB,^G,E,]A,,z [ECA,]A,,z| \
|
||||||
|
[ECA,]E,,z [DB,^G,E,]E,,z|
|
||||||
|
[DB,^G,E,]A,,z [ECA,]A,,z| \
|
||||||
|
[ECA,]E,,z [DB,^G,E,]E,,z| \
|
||||||
|
[DB,^G,E,]A,,z [ECA,]E,,z| \
|
||||||
|
[DB,^G,E,]A,,z [ECA,]A,,z|
|
||||||
|
[DB,^G,E,]A,,z [ECA,]A,,z| \
|
||||||
|
[ECA,]E,,z [DB,^G,E,]E,,z| \
|
||||||
|
[DB,^G,E,]A,,z [ECA,]A,,z| \
|
||||||
|
[ECA,]E,,z [DB,^G,E,]E,,z|
|
||||||
|
[DB,^G,E,]A,,z [ECA,]A,,z| \
|
||||||
|
[ECA,]E,,z [DB,^G,E,]E,,z| \
|
||||||
|
[DB,^G,E,]A,,z [ECA,]E,,z| \
|
||||||
|
[DB,^G,E,]A,,z [ECA,]A,,z|
|
||||||
|
[FDB,G,]C,,z [G,E,C,]C,,z| \
|
||||||
|
[G,E,C,]G,,z [DB,G,]E,,z| \
|
||||||
|
[B,^G,E,]A,,z [ECA,]A,,z| \
|
||||||
|
[ECA,]E,,z [DB,^G,E,]E,,z|
|
||||||
|
[DB,^G,E,]A,,z [ECA,]E,,z| \
|
||||||
|
[DB,^G,E,]A,,z [ECA,]D,,z| \
|
||||||
|
[A,F,D,]A,,z [ECA,]E,,z| \
|
||||||
|
[DB,^G,E,]A,,z [ECA,]A,,z|
|
||||||
|
[FDB,G,]C,,z [G,E,C,]C,,z| \
|
||||||
|
[G,E,C,]G,,z [DB,G,]E,,z| \
|
||||||
|
[B,^G,E,]A,,z [ECA,]A,,z| \
|
||||||
|
[ECA,]E,,z [DB,^G,E,]E,,z|
|
||||||
|
[DB,^G,E,]A,,z [ECA,]E,,z| \
|
||||||
|
[DB,^G,E,]A,,z [ECA,]D,,z| \
|
||||||
|
[A,F,D,]A,,z [ECA,]E,,z| \
|
||||||
|
[DB,^G,E,]A,,z [ECA,]A,,
|
||||||
|
V:3
|
||||||
|
%%MIDI channel 10
|
||||||
|
%%clef bass
|
||||||
|
FFz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F|
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F|
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F|
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F|
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F|
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F|
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F|
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F| \
|
||||||
|
^F=Fz ^F/2F/2D,F|
|
||||||
|
V:4
|
||||||
|
%%MIDI channel 10
|
||||||
|
zG,,3/2A,,/2 G,,A,,/2G,,/2A,,| \
|
||||||
|
A,,G,,3/2A,,/2 G,,A,,G,,/2A,,/2| \
|
||||||
|
G,,G,,3/2A,,/2 G,,A,,/2G,,/2A,,| \
|
||||||
|
A,,G,,3/2A,,/2 G,,A,,G,,/2A,,/2|
|
||||||
|
G,,G,,3/2A,,/2 G,,A,,/2G,,/2A,,| \
|
||||||
|
A,,G,,3/2A,,/2 G,,A,,G,,/2A,,/2| \
|
||||||
|
G,,G,,3/2A,,/2 G,,A,,/2G,,/2A,,| \
|
||||||
|
A,,G,,3/2A,,/2 G,,A,,G,,/2A,,/2|
|
||||||
|
zG,,3/2A,,/2 G,,A,,/2G,,/2A,,| \
|
||||||
|
A,,G,,3/2A,,/2 G,,A,,G,,/2A,,/2| \
|
||||||
|
G,,G,,3/2A,,/2 G,,A,,/2G,,/2A,,| \
|
||||||
|
A,,G,,3/2A,,/2 G,,A,,G,,/2A,,/2|
|
||||||
|
G,,G,,3/2A,,/2 G,,A,,/2G,,/2A,,| \
|
||||||
|
A,,G,,3/2A,,/2 G,,A,,G,,/2A,,/2| \
|
||||||
|
G,,G,,3/2A,,/2 G,,A,,/2G,,/2A,,| \
|
||||||
|
A,,G,,3/2A,,/2 G,,A,,G,,/2A,,/2|
|
||||||
|
z
|
||||||
|
K:F# % 6 sharps
|
||||||
|
=G,,3/2=A,,/2 G,,A,,/2G,,/2A,,| \
|
||||||
|
=A,,=G,,3/2A,,/2 G,,A,,G,,/2A,,/2| \
|
||||||
|
=G,,G,,3/2=A,,/2 G,,A,,/2G,,/2A,,| \
|
||||||
|
=A,,=G,,3/2A,,/2 G,,A,,G,,/2A,,/2|
|
||||||
|
=G,,G,,G,, G,,z2| \
|
||||||
|
z=G,,G,, G,,z2| \
|
||||||
|
z=G,,G,, G,,z2| \
|
||||||
|
z=G,,3z2|
|
||||||
|
z=G,,3/2=A,,/2 G,,A,,/2G,,/2A,,| \
|
||||||
|
=A,,=G,,3/2A,,/2 G,,A,,G,,/2A,,/2| \
|
||||||
|
=G,,G,,3/2=A,,/2 G,,A,,/2G,,/2A,,| \
|
||||||
|
=A,,=G,,3/2A,,/2 G,,A,,G,,/2A,,/2|
|
||||||
|
=G,,G,,G,, G,,z2| \
|
||||||
|
z=G,,G,, G,,z2| \
|
||||||
|
z=G,,G,, G,,z2| \
|
||||||
|
z=G,,3
|
||||||
1706
tests/golden/midicopy_coleraine.txt
Normal file
1706
tests/golden/midicopy_coleraine.txt
Normal file
File diff suppressed because it is too large
Load Diff
56
tests/golden/midistats_coleraine.txt
Normal file
56
tests/golden/midistats_coleraine.txt
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
ntrks 5
|
||||||
|
ppqn 480
|
||||||
|
trk 1
|
||||||
|
tempo 142.00 bpm
|
||||||
|
keysig Amin 0 1 0.00
|
||||||
|
timesig 6/8 0.00
|
||||||
|
metatext 3 Coleraine
|
||||||
|
trk 2
|
||||||
|
program 1 26
|
||||||
|
metatext 3 Coleraine
|
||||||
|
cprogram 1 72 0
|
||||||
|
trkinfo 1 26 165 1 11778 45914 0 2 0 26 8 64 81 159 1199 0 5.665032 16 45 25 95 8
|
||||||
|
trk 3
|
||||||
|
program 3 3
|
||||||
|
program 2 3
|
||||||
|
trkinfo 2 3 64 1 2746 15535 0 0 0 266 4 36 45 239 239 0 3.010735 22 2 38 65 0
|
||||||
|
trkinfo 3 3 63 151 12443 51146 0 0 0 506 4 48 65 239 239 0 5.702527 18 33 10 64 0
|
||||||
|
trk 4
|
||||||
|
trkinfo 10 0 191 1 -1 0 0 0 0 26 0 -1 0
|
||||||
|
trk 5
|
||||||
|
timesig 6/8 0.00
|
||||||
|
trkinfo 10 0 186 0 -1 0 0 0 0 506 0 -1 0
|
||||||
|
npulses 46106
|
||||||
|
tempocmds 1
|
||||||
|
pitchbends 0
|
||||||
|
programcmd 1
|
||||||
|
ntimesig 2
|
||||||
|
progs 3 26
|
||||||
|
progsact 66681 45914
|
||||||
|
progcolor 1.45 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
|
||||||
|
drums 43 45 50 65 66
|
||||||
|
drumhits 102 84 32 33 127
|
||||||
|
pitches 60 0 45 0 118 6 2 14 41 98 0 61
|
||||||
|
key Amin 0 0.609575
|
||||||
|
rmaj 0.305 -0.394 0.316 -0.360 0.354 0.157 -0.476 0.264 -0.368 0.530 -0.225 -0.105
|
||||||
|
rmin -0.201 0.058 0.322 -0.480 0.522 -0.315 0.071 -0.111 -0.152 0.610 -0.469 0.144
|
||||||
|
pitchact 0.33 0.00 0.23 0.00 0.64 0.03 0.01 0.08 0.21 0.58 0.00 0.32
|
||||||
|
chanvol 115 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
chnact 0.996 0.337 1.109 0.000 0.000 0.000 0.000 0.000 0.000 1.689 0.000 0.000 0.000 0.000 0.000 0.000
|
||||||
|
trkact 0 0 166 279 192 186
|
||||||
|
pitchperplexity 6.420275
|
||||||
|
|
||||||
|
pitchentropy 2.682635
|
||||||
|
totalrhythmpatterns =16
|
||||||
|
collisions = 0
|
||||||
|
clean_quantization
|
||||||
|
|
||||||
|
programs: 26 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
cnotes: 332 130 428 0 0 0 0 0 0 756 0 0 0 0 0 0
|
||||||
|
nnotes: 87 63 63 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
nzeros: 16 22 18 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
nsteps: 45 2 33 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
njumps: 25 38 10 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
rpats: 8 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
pavg: 70 41 53 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
|
spread: 99 99 98 0 0 0 0 0 0 98 0 0 0 0 0 0
|
||||||
1780
tests/golden/yaps_coleraine.txt
Normal file
1780
tests/golden/yaps_coleraine.txt
Normal file
File diff suppressed because it is too large
Load Diff
177
tests/run_test.cmake
Normal file
177
tests/run_test.cmake
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
# Generic test runner for abcmidi golden-file tests.
|
||||||
|
#
|
||||||
|
# Required variables (passed via -D on the cmake command line):
|
||||||
|
# TYPE - one of: abc2midi, abc2abc, midi2abc, midistats, mftext,
|
||||||
|
# yaps, midicopy, abcmatch
|
||||||
|
# SAMPLE - path to the input ABC sample file
|
||||||
|
# GOLDEN - path to the golden reference file
|
||||||
|
# TMPDIR - working directory for temporary outputs
|
||||||
|
#
|
||||||
|
# ABC2MIDI, ABC2ABC, MIDI2ABC, MIDISTATS, MFTEXT, YAPS, MIDICOPY, ABCMATCH
|
||||||
|
# - absolute paths to the binaries (only those needed for TYPE)
|
||||||
|
#
|
||||||
|
# Behaviour:
|
||||||
|
# - Runs the requested binary (and any pipeline steps required to make the
|
||||||
|
# output diffable, e.g. mftext for binary MIDI output).
|
||||||
|
# - Strips non-deterministic lines (version banners, dates) from the output.
|
||||||
|
# - If the environment variable ABCMIDI_UPDATE_GOLDEN is set, the filtered
|
||||||
|
# output is written to GOLDEN (used to regenerate references after an
|
||||||
|
# intentional behavioural change).
|
||||||
|
# - Otherwise, the filtered output is compared with GOLDEN; on mismatch, a
|
||||||
|
# unified diff is printed and the test fails.
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
|
if(NOT TYPE OR NOT SAMPLE OR NOT GOLDEN OR NOT TMPDIR)
|
||||||
|
message(FATAL_ERROR "run_test.cmake: TYPE, SAMPLE, GOLDEN, TMPDIR are required")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(MAKE_DIRECTORY "${TMPDIR}")
|
||||||
|
get_filename_component(stem "${SAMPLE}" NAME_WE)
|
||||||
|
|
||||||
|
set(raw "${TMPDIR}/${TYPE}_${stem}.raw")
|
||||||
|
set(out "${TMPDIR}/${TYPE}_${stem}.out")
|
||||||
|
set(midfile "${TMPDIR}/${TYPE}_${stem}.mid")
|
||||||
|
|
||||||
|
# --- Command helpers ---------------------------------------------------------
|
||||||
|
|
||||||
|
# Run a command; abort with a detailed message on non-zero exit.
|
||||||
|
function(run_or_die)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${ARGN}
|
||||||
|
RESULT_VARIABLE rc
|
||||||
|
OUTPUT_VARIABLE captured_out
|
||||||
|
ERROR_VARIABLE captured_err
|
||||||
|
)
|
||||||
|
if(NOT rc EQUAL 0)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Command failed (rc=${rc}):\n ${ARGN}\n"
|
||||||
|
"--- stdout ---\n${captured_out}\n"
|
||||||
|
"--- stderr ---\n${captured_err}")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Run a command and capture its stdout into a file.
|
||||||
|
function(run_to_file outfile)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${ARGN}
|
||||||
|
OUTPUT_FILE "${outfile}"
|
||||||
|
RESULT_VARIABLE rc
|
||||||
|
ERROR_VARIABLE captured_err
|
||||||
|
)
|
||||||
|
if(NOT rc EQUAL 0)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Command failed (rc=${rc}):\n ${ARGN}\n--- stderr ---\n${captured_err}")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Convert ${SAMPLE} to MIDI, then run ${bin} on the resulting MIDI file and
|
||||||
|
# capture its stdout. Any extra arguments are inserted BEFORE the MIDI path
|
||||||
|
# (needed e.g. for "midi2abc -f <file>").
|
||||||
|
function(run_via_mid outfile bin)
|
||||||
|
run_or_die("${ABC2MIDI}" "${SAMPLE}" -o "${midfile}" -quiet -silent)
|
||||||
|
run_to_file("${outfile}" "${bin}" ${ARGN} "${midfile}")
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Run ${bin} directly on ${SAMPLE} and capture its stdout. Extra arguments
|
||||||
|
# are appended after the sample path.
|
||||||
|
function(run_on_sample outfile bin)
|
||||||
|
run_to_file("${outfile}" "${bin}" "${SAMPLE}" ${ARGN})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# --- Dispatch: populate ${raw} based on TYPE ---------------------------------
|
||||||
|
#
|
||||||
|
# The binary path is derived from TYPE via TOUPPER + double-dereference:
|
||||||
|
# for TYPE=midistats, ${bin} resolves to ${MIDISTATS}. The only exception is
|
||||||
|
# abc2midi, where we render the MIDI output through mftext for diffing — it
|
||||||
|
# is therefore an alias for the mftext test.
|
||||||
|
|
||||||
|
string(TOUPPER "${TYPE}" TYPE_UPPER)
|
||||||
|
if(TYPE STREQUAL "abc2midi")
|
||||||
|
set(bin "${MFTEXT}")
|
||||||
|
else()
|
||||||
|
set(bin "${${TYPE_UPPER}}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(TYPE MATCHES "^(abc2midi|mftext|midistats)$")
|
||||||
|
run_via_mid("${raw}" "${bin}")
|
||||||
|
|
||||||
|
elseif(TYPE STREQUAL "midi2abc")
|
||||||
|
run_via_mid("${raw}" "${bin}" -f)
|
||||||
|
|
||||||
|
elseif(TYPE STREQUAL "abc2abc")
|
||||||
|
run_on_sample("${raw}" "${bin}")
|
||||||
|
|
||||||
|
elseif(TYPE STREQUAL "abcmatch")
|
||||||
|
# -pitch_hist gives a short, deterministic, useful summary of the tune.
|
||||||
|
run_on_sample("${raw}" "${bin}" -pitch_hist)
|
||||||
|
|
||||||
|
elseif(TYPE STREQUAL "yaps")
|
||||||
|
set(psfile "${TMPDIR}/yaps_${stem}.ps")
|
||||||
|
run_or_die("${bin}" "${SAMPLE}" -o "${psfile}")
|
||||||
|
configure_file("${psfile}" "${raw}" COPYONLY)
|
||||||
|
|
||||||
|
elseif(TYPE STREQUAL "midicopy")
|
||||||
|
# ABC -> MIDI -> midicopy -> mftext
|
||||||
|
set(copied "${TMPDIR}/midicopy_${stem}_out.mid")
|
||||||
|
run_or_die("${ABC2MIDI}" "${SAMPLE}" -o "${midfile}" -quiet -silent)
|
||||||
|
run_or_die("${bin}" "${midfile}" "${copied}")
|
||||||
|
run_to_file("${raw}" "${MFTEXT}" "${copied}")
|
||||||
|
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unknown TYPE: ${TYPE}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# --- Normalize: strip non-deterministic lines --------------------------------
|
||||||
|
#
|
||||||
|
# Each program prints a version line as the first line of stdout. yaps
|
||||||
|
# PostScript output contains a CreationDate. Filenames embedded in output
|
||||||
|
# (e.g. yaps "%%Title: /tmp/...") are also volatile and stripped.
|
||||||
|
|
||||||
|
file(READ "${raw}" content)
|
||||||
|
|
||||||
|
# Strip program version banners (e.g. "5.02 February 16 2025 abc2midi")
|
||||||
|
string(REGEX REPLACE "[0-9]+\\.[0-9]+ +[A-Za-z]+ +[0-9]+ +[0-9]+ +[a-z2]+\n" "" content "${content}")
|
||||||
|
|
||||||
|
# Strip yaps PostScript volatile headers
|
||||||
|
string(REGEX REPLACE "%%Title:[^\n]*\n" "%%Title: <stripped>\n" content "${content}")
|
||||||
|
string(REGEX REPLACE "%%CreationDate:[^\n]*\n" "%%CreationDate: <stripped>\n" content "${content}")
|
||||||
|
|
||||||
|
# Strip absolute paths to TMPDIR (filenames embedded in some outputs)
|
||||||
|
string(REPLACE "${TMPDIR}/" "" content "${content}")
|
||||||
|
|
||||||
|
file(WRITE "${out}" "${content}")
|
||||||
|
|
||||||
|
# --- Update or compare -------------------------------------------------------
|
||||||
|
|
||||||
|
if(DEFINED ENV{ABCMIDI_UPDATE_GOLDEN})
|
||||||
|
get_filename_component(golden_dir "${GOLDEN}" DIRECTORY)
|
||||||
|
file(MAKE_DIRECTORY "${golden_dir}")
|
||||||
|
file(WRITE "${GOLDEN}" "${content}")
|
||||||
|
message(STATUS "Updated golden: ${GOLDEN}")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT EXISTS "${GOLDEN}")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Golden file does not exist: ${GOLDEN}\n"
|
||||||
|
"Run 'ABCMIDI_UPDATE_GOLDEN=1 ctest ...' to generate it.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E compare_files "${out}" "${GOLDEN}"
|
||||||
|
RESULT_VARIABLE diff_rc
|
||||||
|
OUTPUT_QUIET
|
||||||
|
ERROR_QUIET
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT diff_rc EQUAL 0)
|
||||||
|
execute_process(
|
||||||
|
COMMAND diff -u "${GOLDEN}" "${out}"
|
||||||
|
OUTPUT_VARIABLE diff_text
|
||||||
|
)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Output differs from golden ${GOLDEN}\n"
|
||||||
|
"To accept the new output: ABCMIDI_UPDATE_GOLDEN=1 ctest ...\n"
|
||||||
|
"${diff_text}")
|
||||||
|
endif()
|
||||||
Reference in New Issue
Block a user