bug-lilypond
[Top][All Lists]
Advanced

[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;
                       }
          }
  }








reply via email to

[Prev in Thread] Current Thread [Next in Thread]