craigsapp / humlib

Humdrum data parsing library in C++
http://humlib.humdrum.org
BSD 2-Clause "Simplified" License
32 stars 8 forks source link
c-plus-plus humdrum kern

humlib

AppVeyor Build Status

The humlib repository consists of a set of C++ classes for parsing Humdrum data files, used for digital encodings of musical scores. In addition, Humlib includes command-line tools that also can be used via JavaScript in web applications. This is easiest done through the notation renderer verovio, and in particular with Humdrum Notation Plugin. Online use of most tools can be done when editing Humdrum files in Verovio Humdrum Viewer.

Using humlib as a C++ library

The library is designed to be portable with only two source-code files to copy into your project:

  1. An include file humlib.h
  2. And a source file humlib.cpp

Plus three Pugixml files used for parsing/writing data in the XML format:

  1. The pugixml include file pugixml.hpp
  2. The pugixml configuration file pugiconfig.hpp
  3. The pugixml source file pugixml.cpp

All of these files can be copied from the min directory into your project. For example, verovio include the humlib.cpp and humlib.h and independently uses the pugixml library for processing XML data (MusicXML and MEI).

Documentation

Documentation for humlib source code can be found at https://humlib.humdrum.org

Documentation for the tools can be found at https://doc.verovio.humdrum.org/filter

Download and compiling

To download humlib with git in a directory where you want to store humlib:

git clone https://github.org/craigsapp/humlib.git

To compile, run the command:

cd humlib
make

This will compile both the library and command-line tools found in cli. To compile only the library:

cd humlib
make library

To download updates of the humdrum repository, use the command:

make update

after which you can recompile the library and programs:

make

Minimal downloading

For minimal use of the library with your own project, you can download just the composite header and source files (and pugixml library). In a terminal you can download with wget (on linux):

wget https://raw.githubusercontent.com/craigsapp/humlib/master/min/humlib.h
wget https://raw.githubusercontent.com/craigsapp/humlib/master/min/humlib.cpp
wget https://raw.githubusercontent.com/craigsapp/humlib/master/min/pugixml.cpp
wget https://raw.githubusercontent.com/craigsapp/humlib/master/min/pugixml.hpp
wget https://raw.githubusercontent.com/craigsapp/humlib/master/min/pugiconfig.hpp

Or with curl (most common method downloading on the comnmand line in MacOS):

curl https://raw.githubusercontent.com/craigsapp/humlib/master/min/humlib.h -o humlib.h
curl https://raw.githubusercontent.com/craigsapp/humlib/master/min/humlib.cpp -o humlib.cpp
curl https://raw.githubusercontent.com/craigsapp/humlib/master/min/pugixml.hpp -o pugixml.hpp
curl https://raw.githubusercontent.com/craigsapp/humlib/master/min/pugixml.hpp -o pugixml.hpp
curl https://raw.githubusercontent.com/craigsapp/humlib/master/min/pugiconfig.cpp -o pugiconfig.cpp

The source code uses some C++11-specific features, so add the -stc=c++11 option when compiling with GNU g++ or the clang++ compiler. (See the humlib Makefile). In particular, include the -stdlib=libc++ option when compiling with clang. See the Makefile for compiling the library and Makefile.examples for compiling and linking executables for the command-line tools.

Example

Here is a short example program that uses the humlib library to convert a Humdrum file into a MIDI-like listing of notes.

#include "humlib.h"

using namespace std;
using namespace hum;

void printNoteInformation(HumdrumFile& infile, int line, int field, int tpq) {
    HTp token = infile.token(line, field);
   int starttime = infile[line].getDurationFromStart(tpq).getInteger();
   int duration  = token->getDuration(tpq).getInteger();
   cout << Convert::kernToSciPitch(*token)
        << '\t' << token->getTrackString()
        << '\t' << starttime << '\t' << duration << endl;
}

int main(int argc, char** argv) {
   if (argc != 2) {
      return 1;
   }
   HumdrumFile infile;
   if (!infile.read(argv[1])) {
      return 1;
   }
   int tpq = infile.tpq();
   cout << "TPQ: " << tpq << endl;
   cout << "PITCH\tTRACK\tSTART\tDURATION" << endl;

   for (int i=0; i<infile.getLineCount(); i++) {
      if (!infile[i].isData()) {
         continue;
      }
      for (int j=0; j<infile[i].getTokenCount(); j++) {
            HTp token = infile.token(i, j);
         if (token->isNull()) {
            continue;
         }
         if (token->isKern()) {
            printNoteInformation(infile, i, j, tpq);
         }
      }
   }
   return 0;
}

Test data for use with the above program:

Example input:
**kern  **kern
*M3/4   *M3/4
8C  12d
.   12e
8B  .
.   12f
*   *^
4A  2g  4d
4G  .   4c
*   *v  *v
=   =
*-  *-
Example output:
TPQ: 6
PITCH   TRACK   START   DURATION
C3      1       0       3
D4      2       0       2
E4      2       2       2
B3      1       3       3
F4      2       4       2
A3      1       6       6
G4      2.1     6       12
D4      2.2     6       6
G3      1       12      6
C4      2.2     12      6

Writing your own command-line tools with Humlib:

If you are using the humlib project directory to compile your own programs (or this test program), place them into the cli (Command-Line Interface) subdirectory.

Then to compile, go to the base directory of the humlib repository and type make myprogram if the program is called humlib/cli/myprogram.cpp. The compiled program will be created as bin/myprogram.

To run from the humlib directory type bin/myprogram file.krn, for example. You can also either copy your program to /usr/local/bin or set the $PATH variable to include humlib/bin in the executable search path.

See the Coding-examples documentation for more programming examples.