App-MusicTools
view release on metacpan or search on metacpan
print STDERR $stderr;
exit 1;
}
print STDERR $stderr if $Flag_Verbose;
if ($Flag_Show_Score) {
local $SIG{CHLD} = 'IGNORE';
my $pid = fork();
die "ly-fu: could not fork score reader: $!\n" unless defined $pid;
unless ($pid) {
# a vague effort at daemonization; may be necessary if the PDF
# view being open holds ly-fu open which then prevents a text
# editor from moving on
open( STDIN, '<', '/dev/null' );
open( STDOUT, '>', '/dev/null' );
( setsid() == -1 ) and die "ly-fu: setsid failed: $!\n";
open( STDERR, '>&', STDOUT );
exec( @Score_Reader, $score_filename )
or die "ly-fu: could not exec score reader '@Score_Reader': $!\n";
}
}
unless ($Flag_No_MIDI) {
if ($Flag_Generate_Score) {
# we're keeping the files, so there's nothing more this script
# needs to do
exec( @MIDI_Player, $midi_filename )
or die
"ly-fu: could not exec MIDI player '@MIDI_Player $midi_filename': $!\n";
} else {
system( @MIDI_Player, $midi_filename ) == 0
or die
"ly-fu: could not run MIDI player '@MIDI_Player $midi_filename': $!\n";
}
}
if ($Flag_Generate_Score) {
# the files might be shared, so open up the permissions
chmod 0644, $ly_filename, $midi_filename, $score_filename;
} else {
# Preview.app got increasingly slower to actually start over time,
# hence this kluge. Eventually I switched to mupdf, and eventually
# the 2009 macbook died in late 2022.
sleep $Flag_Sleep_Kluge if $Flag_Sleep_Kluge > 0;
unlink $ly_filename, $midi_filename, $score_filename;
}
########################################################################
#
# SUBROUTINES
sub emit_help {
warn <<"END_HELP";
Usage: $0 [options] "lilypond code ..."
The lilypond input will likely need to be quoted as lilypond input may
clash with various shell metacharacters.
--absolute Notation assumed to be absolute.
--instrument Set MIDI instrument (see lilypond docs).
--partial|p Lilypond fragment played once at beginning.
--relative|b Specify what note input is relative to.
--repeats|r How many times to repeat the lilypond input.
--tempo|t Set a tempo for the music.
--layout|l Save the MIDI and other various files.
--open Show the score in some sort of viewer.
--show-code Print the lilypond data to stdout and exit.
--silent|s Skip generating MIDI.
--sleep|S Sleep before unlink of various tmp files.
--verbose Show noise from lilypond, MIDI player.
END_HELP
exit 64;
}
__END__
=head1 NAME
ly-fu - play or display lilypond snippets
=head1 SYNOPSIS
Set the MIDI_EDITOR and SCORE_VIEWER environment variables to
suitable MIDI playing and PDF opening utilities, or adjust the source
to your liking.
$ export MIDI_EDITOR=timidity
$ export SCORE_VIEWER=xpdf
$ ly-fu --instrument=banjo c des ees c des bes c aes
$ ly-fu -i=trumpet --open "c8 g'4 c,8 g'4 c,8 g'2"
$ echo c e g | ly-fu -
Or, to instead save the generated lilypond somewhere:
$ ly-fu --show-code e e e c1 > masterpiece.ly
=head1 DESCRIPTION
Plays and possibly displays lilypond snippets entered at the command
line. The C<MIDI_EDITOR> environment variable should be set to a program
that can play MIDI files, and the C<SCORE_VIEWER> optionally set to a
PDF viewer. (Or edit the source code as necessary.)
L<https://www.lilypond.org/> and in particular the Learning and Notation
manuals should be consulted to understand the lilypond syntax.
=head1 OPTIONS
This program currently supports the following command line switches:
=over 4
=item B<--absolute>
Assume lilypond absolute notation.
=item B<--instrument>=I<instrument>
Set MIDI instrument (see lilypond docs and ZSH compdef script).
=item B<--language>=I<language>
Specify the lilypond language to use, by default the C<lilypond> default
of C<nederlands>. If using note names from L<Music::PitchNum::German>,
... | ly-fu --language=deutsch ...
may be of some use. "Note names in other languages" in the lilypond
notation reference contains the full list of supported languages.
=item B<--layout>
Save the MIDI and other various files (they are unlinked by default).
=item B<--open>
Show the score via the C<SCORE_VIEWER> program.
=item B<--partial>=I<lilypond fragment>
A lilypond fragment played once at the beginning.
=item B<--relative>=I<note>
Specify what note the input is relative to.
=item B<--repeats>=I<count>
How many times to repeat the (non-B<partial>) input.
=item B<--rhythmic-staff>
Make the staff a lilypond C<RhythmicStaff> instead of the usual one.
=item B<--show-code>
Prints the generated lilypond data to standard out, then exits the
program. The score is not shown, nor the music played.
=item B<--silent>
Do not play the MIDI.
=item B<--sleep>=I<seconds>
Kluge sleep before unlinking temporary files (might be handy if
C<SCORE_VIEWER> is slow to start).
=item B<--tempo>=I<tempo>
What the tempo is (in quarter notes, e.g. C<120> or the like).
=item B<--verbose>
Show output from lilypond and the MIDI player.
=back
=head1 FILES
NOTE This program makes heavy use of temporary files. On a shared
system, the lilypond generated output files might introduce /tmp
security problems (arbitrary file clobber or unlink against the user
running the code). These can be avoided by employing a private temporary
directory, for example by pointing the C<TMPDIR> environment variable to
such a directory.
A ZSH completion script is available in the C<zsh-compdef/> directory of
the L<App::MusicTools> distribution. Install this to a C<$fpath>
directory.
=head1 SEE ALSO
L<https://www.lilypond.org/>
=head1 COPYRIGHT
Copyright 2012 Jeremy Mates
This program is distributed under the (Revised) BSD License:
L<https://opensource.org/license/bsd-3-clause/>
( run in 2.883 seconds using v1.01-cache-2.11-cpan-b16cb0d3907 )