[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: MIDI dynamics using velocity
From: |
darius |
Subject: |
Re: MIDI dynamics using velocity |
Date: |
Mon, 27 Dec 2004 20:53:08 +0100 |
User-agent: |
Internet Messaging Program (IMP) 3.2 |
Ok. This is not a milestone in the history of software engineering.
Please find below an ugly perl script that basically copies the volume
changes onto the velocity, and resets the volume to a standard value.
It's in Perl, not because I like it - I actually loathe it - but because
it is the only tool I could find which reads and writes MIDI files
fairly conveniently.
To be honest, even if I have a working solution, I still think that this
kind of basic feature should be part of Lilypond. Adding filters before
and after is not sustainable.
Cheers,
Darius.
Quoting David Raleigh Arnold <address@hidden>:
> On Monday 27 December 2004 05:01 am, Darius Blasband wrote:
> > Hi,
> >
> > I'm not a specialist about these issues, so please feel free to
> > contradict if I'm talking nonsense...
> >
> > I use the MIDI files generated by Lilypond to produce demos of my music;
> > I plug them into CUBASE
> > which, together with Sampletank, allows for an amazing level of realism
> > when rendering instruments.
> > This works, except for the fact that as it stands now, this scheme does
> > not take advantage of the sampling
> > in multiple velocities. Dynamics are represented by volume changes in
> > MIDI files as generated by
> > Lilypond, and while acceptable, it is kind of
> > a frustration to me because I'm convinced the result would be much
> > better if the samples in the various
> > velocities were used. \ff is not just an amplified, \pp, nor if \pp a
> > damped \ff. Depending on the instrument
> > (think of staccato violins, for instance) the sound is intrinsically
> > very different.The sampler supports this,
> > bu my MIDI files don't...
> >
> > Besides, using velocities would make stuff such as :
> >
> > <<
> > { a1 \f b c }
> > \\
> > { c8 \p d e f g h}
> >
> >
> > sound better as well.
> >
> > So I though, it should not be much of an issue, to use a single midi
> > event with velocity, rather than
> > two events, one for the note (with maximal velocity 127) followed by a
> > volume change. I checked the
> > source - not to correct it myself, but at least, to see how this would
> > be possible - and it soon appeared
> > that it would be a non-trivial task, as notes and dynamic changes are
> > just considered events, and the
> > fact that they ought to be connected together does not appear explicitly
> > - as far as I could gather....
> >
> > A sort of hack in the serialization procedure could do the job (keep the
> > last note in cache, and if followed
> > by a volume change, change the velocity instead...) but I'm not quite
> > sure of the implications...
> >
> > Any advice, idea, suggestion, welcome ....
>
> I really doubt if you are going to get anything like that in
> lilypond. There is zero interest in doing it. If I were you,
> I would take that midi file made by lilypond and convert it
> to a midge file. Midge is a GNU text-based midi program.
> The syntax is unfortunately not similar, but I'm
> sure that would give you all the control you can stand, and
> who knows, it may even be a decently efficient way of working.
> Let us know how it works out. daveA
>
>
> _______________________________________________
> bug-lilypond mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/bug-lilypond
>
>
>
use strict;
use MIDI::XML::MidiFile;
use MIDI::XML::Track;
use MIDI::XML::Parser;
use XML::Parser;
use MIDI::Opus;
use MIDI::Track;
use MIDI::Event;
unless (@ARGV) {
die "Usage: perl test.pl filename(s)\n";
}
my $one = "";
foreach $one (@ARGV) {
doFile($one)
}
sub doFile($)
{
my $file = shift;
my $opus = MIDI::Opus->new({ 'from_file' => "$file.mid"});
# $opus->write_to_file("$file.b.mid");
# saveXml($opus, "$file.1.xml");
my $midi=MIDI::XML::MidiFile->new({'from_opus' => $opus});
open XML,">","$file.1.xml";
print XML "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
print XML join("\n",$midi->as_MidiXML());
close XML;
print "$file.mid has ", scalar( $opus->tracks ) , " tracks\n";
my $tracks = $opus->tracks_r;
doTracks($tracks);
$opus->write_to_file("$file.p.mid");
# saveXml($opus, "$file.2.xml");
}
sub saveXml($)
{
my $opus = shift;
my $fname = shift;
my $midi=MIDI::XML::MidiFile->new({'from_opus' => $opus});
open XML,">","$fname.xml";
print XML "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
print XML join("\n",$midi->as_MidiXML());
close XML;
}
sub doTracks(@){
my $tracks = shift;
my $t;
foreach $t (@$tracks) {
doTrack($t)
}
}
sub doTrack($){
my $t = shift;
doEvents($t->events_r);
}
sub doEvents($) {
my $l = shift;
my $i;
# print scalar(@$l), " events\n";
my $r;
my $v = "99";
foreach $r (@$l) {
if ((@$r[0] eq "control_change")
&
(@$r[3] eq "7"))
{
$v = @$r[4];
@$r[4] = "90";
}
elsif (@$r[0] eq "note_on")
{
@$r[4] = $v;
}
}
}