Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More

songs : Generate music scores using Lilypond

Adds database models and functionality to manage songs.

This document assumes you have read The songs plugin.

This page contains code snippets (lines starting with >>>), which are being tested during our development workflow. The following snippet initializes the demo project used throughout this page.

>>> from lino_book.projects.noi2.startup import *

Installation

If you want Lino to publish .wav files of your songs, you need to install the midi2audio Python package, which requires the fluidsynth system package (which in turn requires two soundfont packages):

$ sudo apt-get install fluidsynth fluid-soundfont-gs fluid-soundfont-gm
$ pip install midi2audio
$ mkdir ~/.fluidsynth$
$ ln -s /etc/alternatives/default-GM.sf2 ~/.fluidsynth$/default_sound_font.sf2

Demo data

The plugin adds some songs as demo data in order to demonstrate what it can do.

>>> rt.show('songs.Songs')
==== ====================================== ==========
 ID   Title                                  Language
---- -------------------------------------- ----------
 2    Ligidal on Jumal                       Estonian
 3    Dans sa maison                         French
 4    Põdral maja                            Estonian
 5    Wer nur den lieben Gott lässt walten   German
 6    Kes Jumalat nii laseb teha             Estonian
==== ====================================== ==========

Lyrics

The logic for multiple verses is implemented by the text2lyrics() function, which used in the *.jinja.ly templates.

Examples:

>>> from lino_xl.lib.songs.models import text2lyrics
>>> txt = """
... - # Si- nu sõ- na lamp on, lamp on,
... - * Sa- na si on lamp- pu, lamp- pu,
... """
>>> pprint(list(text2lyrics(txt)))
[('alt', None, 'Sa- na si on lamp- pu, lamp- pu,')]
>>> pprint(list(text2lyrics("""- first verse\n- second verse""")))
[('std', None, 'first verse\n'), ('std', None, 'second verse')]
>>> pprint(list(text2lyrics("""- main text\n- * alt text""")))
[('std', None, 'main text\n'), ('alt', None, 'alt text')]
>>> pprint(list(text2lyrics("""- main text\n- *+ alt text""")))
[('std', None, 'main text\n'), ('alt', 'SA', 'alt text')]

Reference

*.jinja.ly`

Template file used by Song.build_content() to make the input file for Lilypond.

class lino_xl.lib.songs.Song

Django model used to represent a song.

lyrics_soprano
lyrics_alto
lyrics_tenor
lyrics_bass
scores_soprano
scores_alto
scores_tenor
scores_bass
build_content(self)

Implements lino.modlib.publisher.Publishable.build_content() for a song.

Troubleshooting

How to see the Lilypond executable used by Lino:

$ go mysite
$ a
$ python
Python 3.11.2 (main, Nov 30 2024, 21:22:50) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from lilyponddist import lilypondbin
>>> lilypondbin()  #doctest: +ELLIPSIS
PosixPath('.../.local/share/lilyponddist/lilypond-.../bin/lilypond')

Lilypond uses the HOME directory for creating temporary files. When Lino calls Lilypond, it sets HOME to settings.SITE.site_dir / "tmp". The name tmp is currently hard-coded.