• Stars
    star
    138
  • Rank 258,882 (Top 6 %)
  • Language
    Shell
  • License
    Mozilla Public Li...
  • Created over 4 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Generate guitar tablatures using a constraint solver

TablaZinc

This is an experiment to generate tablatures for fretted string instruments -- such as the guitar, bass, mandolin, banjo, etc -- using a constraint solver.

The input is a melody, represented by an array of MIDI note numbers with no duration indication. The output is a tablature with fingering annotations for the fretting hand.

The src and data folders contain model files and data files written in the MiniZinc language.

Disclaimer

I have no prior experience with constraint programming in general, and MiniZinc in particular.

If you are a beginner in this field and are looking for well-written examples, this repository might not be the right place.

If you are an expert, your feedback will be welcome. Please open a new issue.

Usage

The following command outputs a tablature from two data files (an instrument definition file, and a melody file) using a set of constraints specified in a model file:

minizinc src/<model-file> data/<instrument-file> data/<melody-file>

Example

We provide the following data files:

  • data/guitar-std.dzn, instrument definition parameters for the guitar in standard tuning.
  • data/yardbird-suite.dzn, the first eight bars of the jazz standard Yardbird Suite by Charlie Parker, where consecutive notes with the same pitch have been merged.

Three model files are currently available:

  • src/tablazinc-satisfy.mzn generates a tablature with the correct notes, but with no concern for playability.
-8i--3i--5i--6i--4i--0---1i--3i--0---1i--0---1i--3i--0-----------0---1i--3i--5i--0---1i--3i-
---------------------------------------------------------1i--3i-----------------------------
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
  • src/tablazinc-fret-distance.mzn attempts to minimize the distance between consecutive notes on the fretboard. There is no constraint on which finger to use for each note.
-8i-----------------------------------------------------------------------------------------
-----8i-10i-11i--9i----------8i------------------8i--5i-------------------------------------
---------------------9i-10i------9i-10i--9i-10i----------5i--7i--9i-10i-12i-14i-------------
--------------------------------------------------------------------------------14i-15i-17i-
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
  • src/tablazinc-finger-distance.mzn attempts to minimize the distance between finger locations for consecutive notes. This version can take several minutes to complete with the default solver and optimization level, even for such a short melody.
-8i-----------------------------------------------------------------------------------------
-----8i-10r-11r--9i---------------------------------------------------------10m-------------
---------------------9i-10m-12p--9i-10m--9i-10m-12p--9i----------9i-10m-12p------9i-10m-12p-
--------------------------------------------------------10m-12p-----------------------------
--------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------

The fingering annotations use the letters i (index), m (middle), r (ring), and p (pinky). If you have a different number of fingers, or if you want to use other letters, you can change the parameter finger_ids in the instrument definition file guitar-std.dzn.

Performance

The tables below show the computation time, in seconds, of the following command with each model file and each supported optimization level. We are using the default solver Gecode with one or two threads.

minizinc -p <n> -O<m> --output-time src/<model-file> data/guitar-std.dzn data/yardbird-suite.dzn

Using one thread (-p 1):

Model file / Optimization -O1 -O2 -O3 -O4 -O5
tablazinc-satisfy.mzn 0.05 0.10 0.09 0.10 0.09
tablazinc-fret-distance.mzn 11.51 12.21 12.04 0.12 0.11
tablazinc-finger-distance.mzn 269.53 234.25 251.93 3.36 3.27

Using two threads (-p 2):

Model file / Optimization -O1 -O2 -O3 -O4 -O5
tablazinc-satisfy.mzn 0.04 0.09 0.09 0.10 0.09
tablazinc-fret-distance.mzn 6.64 7.06 7.05 0.14 0.13
tablazinc-finger-distance.mzn 123.26 106.84 140.68 20.13 17.64

Platform: computer with an Intel Core i5 CPU (2.7 GHz) running Ubuntu 18.04.

Optimization levels -O4 and -O5 show a huge improvement compared to the other levels. Using two threads usually result in longer solving times at the highest optimization levels, but the performance can vary a lot between runs for no obvious reasons.

For instance, I have run the model tablazinc-finger-distance.mzn with options -p 2 -O4 three times in a row and got: 0.76sec, 6.95sec, and 38.17sec.