music.sing

music.sing(text='Mar-ry had a litt-le lamb', notes=(4, 2, 0, 2, 4, 4, 4), durs=(1, 1, 1, 1, 1, 1, 2), M='4/4', L='1/4', Q=120, K='C', reference=60, lang='en', transpose=-12, effect=None, backend='psola')[source]

Sing a line of text to a melody.

By default espeak-ng says each syllable, and Praat’s PSOLA holds it at its note’s pitch and length: see music.singing.psola. It needs espeak-ng and pip install 'music[singing]'. With backend="ecantorix", the melody is written as ABC notation, the eCantorix engine renders it through espeak, and the result is read back as samples; that needs the engine, which setup_engine() clones, and Perl, abc2midi and sox. Both sing MIDI reference + note + transpose for the same lengths, so the two can be compared.

Parameters:
textstr

The lyric, one syllable per note: syllables within a word joined by hyphens, words separated by spaces. A syllable espeak says without a vowel is sung with a schwa after it, as a singer sings the e that spoken French leaves silent: alone, the “ques” of “Jac-ques” is a bare /k/, and its note had nothing to sing.

notessequence of int

Each note’s pitch, in semitones above reference.

durssequence

Each note’s duration, in units of L: a number such as 2 or 0.5, a string of ABC such as "3/2", or a negative number -n for 1/n, which this has always accepted.

M, L, Q, Kstr or int

The ABC meter, unit note length, tempo and key. A number for Q is units of L a minute, as ABC reads a bare Q:; see unit_seconds(). Every note is written with its accidental, so the key changes none of them; E and B were written bare, and a key with flats sang them a semitone low. abc2midi accents the beats, and eCantorix sings the accented notes louder, by up to 2.3 dB; the psola backend accents the same notes as much, by accents(), and reads M for nothing else. It has no use for the key.

referenceint

The MIDI note that pitch zero refers to, which is the note the score is written at.

langstr

The espeak voice, which sets the language the text is sung in.

transposeint

Semitones added to every note as it is sung: the engine sings MIDI reference + note + transpose. The default, -12, sings an octave below the score, where every note used to be sung.

effectstr or None

One of the eCantorix engine’s extra voices, which both backends sing: "tremolo", a tremolo of 9 Hz and a reverberation, in stereo; "melt", the same with espeak’s female voice, its formants raised a quarter, and sinking with the pitch below 216 Hz, as tape played slower; and "flite" (also accepted as "flint", its earlier spelling here), which says each syllable with the flite synthesizer instead of espeak, so it needs flite installed, and bc too for eCantorix, and lang names one of flite’s voices, such as "rms" or "slt". None sings with the plain voice. The psola backend makes them with the package’s own tremolo, reverberation and resampling, set to what eCantorix’s sox gives.

backend{‘psola’, ‘ecantorix’}

Which singer. "psola", the default, needs espeak-ng and pip install 'music[singing]'. "ecantorix" is the engine this package sang with by default until PSOLA, kept as the reference it is compared with.

Returns:
ndarray

The sung line, normalized, at 44,100 Hz: mono, or (2, nsamples) for the tremolo and melt effects, which render in stereo and ring a second past the line. eCantorix’s used to come back as (nsamples, 2), as the file holds them, and be normalized as one channel.

Raises:
RuntimeError

If espeak-ng or praat-parselmouth is missing, or flite for its effect; or, with backend="ecantorix", if the engine is not installed (run music.singing.setup_engine()), cannot be built in the cache, or renders at a rate other than 44,100 Hz, or the flite effect is asked for without bc.

ValueError

If backend or effect is not one of those above, lang is not a voice name, or not one of flite’s voices for its effect, transpose is not a finite number, L or Q is not a length or tempo ABC can read (see unit_seconds()), there is not exactly one duration per note, a duration is zero, or a note falls outside MIDI 12 to 96. These are checked first, so a wrong one is reported whether or not the engine is installed. The voice and the transposition are written into a configuration the engine runs as Perl, so anything else there would be run as code.

Notes

Measured, a note of 0 at the defaults sings at 130.8 Hz, MIDI 48, and at transpose=0 at 261.6 Hz, middle C; eCantorix sings them at 130.3 Hz and 262.5 Hz.

Three things kept these parameters from reaching the engine. It loads the configuration with Perl’s do "achant.conf", which since Perl 5.26 no longer looks in the current directory, so lang, transpose and effect were never read and it sang at its own -24. The score was written an octave above reference, MIDI 60 as ABC’s c. And the effects load files from the engine’s examples, which were not in the cache. Together, every note was sung at reference + note - 12 in the default voice, whatever was asked; the default transposition, -12, keeps that.