Violin key inside chip Violin key inside chip

play-v6

Music compiler and other tools

How to add new music and create instruments

Technical, minimalist page

Spanner

This tools documentation is currently the bare minimum to get started.

Also, the tools do not have a friendly user interface: some skill with the command line, including executable paths and such, is required. If you use them often enough, you may want to define .bat files or shell scripts to avoid repetitive typing.

Linux / OS X note: the example commands are for Windows; for Linux and OS X use forward slashes ('/') instead of ('\').

Lua interpreter required

All play-v6 tools are written in the Lua language and are system-independent: I tested them under Windows, Linux and OS X. Please let me know if you encounter problems.

Lua language logo

You need a Lua 5.2 interpreter to run the tools. You can get it here (just download the executables).
The examples in this page assume that the Lua 5.2 interpreter is named lua52 and is in the executable path.

Tools included in the package

The following tools are in the distribution:

The music compiler

The music compiler takes a music source file (a text file) and compiles it into a music code file, a compact block of binary data ready to be sent to play-v6, as described in the playing music page.

To use the compiler, go into the music directory and type:

lua52 ..\tool\musicomp\musicomp.lua Greensleeves.txt Greensleeves.code

This will produce a greensleeves.code music code file (as noted above, lua52 should execute the Lua 5.2 interpreter; also remember to use '/' instead of '\' for Linux and OS X).

The source music syntax is quite versatile... and presently quite lightly documented. Please refer to the music samples, i.e. the .txt files in the music directory. Here are a few pointers to get started (have a look at greensleeves.txt):

# Greensleeves (traditional) [main]

These are global commands that must be present at the start of a section (they can also be used in the middle of a music piece); they act on all voices:

time:3/4 tempo:4=140 volume:f

The following lines are instaed per-voice settings, one line for each used voice; they too can be changed in mid-music:

instrument:violin mix:80% instrument:voice transpose:-12 mix:100% instrument:guitar transpose:-12 mix:65% release:off instrument:guitar transpose:-12 mix:65% release:off instrument:guitar transpose:-12 mix:65% release:off instrument:piano mix:100%

do5:2 re5:4 do5:2 re5:4 p:4 do4:4 do4:4 p:4 la4:4 la4:4 p:4 mi4:4 mi4:4 la2:2.

You may ask: why not just use a MIDI file and avoid all this trouble?

There are at least two good reasons: first, MIDI files are relatively large, while the RAM available for the current music is severely limited (1800 bytes). Second, interpreting a MIDI file would require much more CPU time, a very scarce resource in the tight playing loop (interpreting a MIDI bus stream could be more feasible). Of course, if you want to write a converter from MIDI files or from LilyPond files to play-v6 music source or music code, you are welcome :-)

Once you have successfully compiled some music, you can play it via remote control. To add it to the on-board Flash memory, see the music packer below.

The instrument generator

The instrument generator has many functions. To just list the available instruments, enter the tool directory and execute the program without any arguments:

lua52 instruments.lua

The first instrument (sine) is a pure sinusoidal sound that can be useful for tests, measurements and educational applications.

To modify an existing instrument or create a new one, open the source file instruments.lua and search for "instrument data". You will see a series of descriptive blocks, such as:

{ name = 'accordion', -21.5, -12.2, -33.2, -34.0, -31.8, -19.0, -31.1, -30.7, -44.0, -33.6, -47.7, -44.1, -47.8, -37.7, -46.6, -42.0, -74.3, -42.7, -52.5, -39.6, -54.9, -46.8, -61.5, -50.1, -59.6, attackDuration = 0.120, decayDuration = 0.8, sustainLevel = 0.5, releaseDuration = 0.120, testReleaseTime = 0.7, },

It is a good idea to copy an existing instrument block, paste it at the end of the list and change its name to something such as test, to avoid messing up existing instruments (even if you are working to replace one of those).

Test sound for accordion instrument on Audacity

A simple trick to choose harmonics levels for a given instrument is to record the sound of an actual instrument, perform a spectrum analysis (e.g. using Audacity), copy the measured values of the harmonics into the table and then listen to the test sound.

To generate a test sound for the new instrument, the SoX utility must be installed and must be in the executable path. It can be downloaded from the SoX site.

The test sound can then be produced by adding the instrument name by going into the tool directory and typing the command:

lua52 instruments.lua accordion

(you may get some warnings from SoX. I preferred to preserve compatibility with previous versions)

The resulting .wav file will contain five G / SOL note samples for the desired instrument, at different octaves; try changing testReleaseTime to see and hear the effect of different note durations (I know, this is a bit primitive, the instruments tool would deserve a real-time GUI).

Do not expect too much: an actual musical instrument has a very complex and rich sound that changes with time and is different for each note, while play-v6 can only reproduce a single waveform.

When you are satified with your instrument, it is time to add it to play-v6 in Flash memory. First, try this to be sure there are no errors in the instrument tables:

lua52 instruments.lua c

It should print out on the console a lot of C code, without stopping with an error message. If all is OK, it is time to update the instruments table of play-v6 source code with these two commands (be sure you are in the tool directory):

lua52 instruments.lua c >..\player\instrum.c

lua52 instruments.lua list >musicomp\instruments.list

If you have changed the name of existing instruments without altering their position in the list inside instruments.lua, any music source file using those instruments will have to be changed accordingly (music already in Flash memory will play correctly anyway, with no need to recompile play-v6).

If you have changed the position of existing instruments in the list inside instruments.lua, music files using those instruments will have to be recompiled and their new music code files must replace those already in Flash memory, using the music packer.

Lastly (after using the music packer, if needed) recompile play-v6 and send the program to the Arduino.

The music packer

The music packer is needed to store music into the Flash memory of the Arduino microcontroller, so that it could be played with no USB connection to a computer.

Go into the music directory and open the builtin.list file with a text editor. You will find something like this:

Greensleeves.code Yankee_Doodle.code Sor_op31n2.code

Change it to the list of music code files you would like have in the Flash memory, in the desired order, one file per line. To check that there are no problems (e.g. the name of a non-existing file) write:

lua52 ..\tool\musipack.lua builtin.list

It should print out on the console a lot of C code, without stopping with an error message. If all is OK, type this command to update the music code table of play-v6 source code (be sure you are in the music directory):

lua52 ..\tool\musipack.lua builtin.list >..\player\music.c

Then recompile play-v6 and send the program to the Arduino. If you run out of available Flash memory space, the compiler (actually, the linker) should complain; in this case, remove one or more music files from the list and reissue both the above commands.

The table generator

The table generator produces the note table that play-v6 uses to generate the correct pitch (frequency) for a given note; for example an A4 (LA4) note should have a frequency of 440 Hz. It also prouces the tempo table that controls, for each musical tempo setting (e.g. 120 quarter notes per minute), how long an 1/64 interval will last.

Usually there is no need to change these tables; I used this tool to produce the C tables and it is documented here for completeness. In any case, the command to update the note and tempo tables in play-v6 source code is, from the tool directory:

lua52 tables.lua >..\player\tables.c

A note about tuning: the table generator adds comments in player\tables.c indicating the pitch error for each note, assuming an accurate microcontroller clock. Unfortunately the Arduino Uno uses a cheap and imprecise ceramic resonator instead of the usual crystal. This could add a pitch error up to about 20 cents, but it does not affect the relative pitch between different notes, so unless you are a trained musician with an 'absolute ear' you will probably be unable to tell the difference.

 


  Updated 03/01/19 by Enrico Colombini (erix@erix.it)