overview of n/r/noop

[email protected] ("Sean M. Burke") Sun, 20 May 2001 18:20:55 -0600
Newsgroups perl.midi
Message-ID <[email protected]>
Two people asked me somewhat related questions at about the same time, so
I'll answer them in one message.

Here's the short story on n/r/noop:

If a call to n has any notes in it, those those notes (with current
settings of
$Time, $Channel, $Duration, $Octave, and $Volume) are pushed to the score;
if NO notes are in that call's parameter list, then we get the note(s)
(from @Notes, which is set by the most recent call to n/r/noop that had any
notes in it).  And then we move ahead $Time (the "time cursor") so that the
next notes are laid down after the current ones.
So each call to n lays down notes, always.
(Maybe @Notes should have been called @Chord, but that invites a whole
different set of misconstruals.)

A call to r acts the same, moving ahead $Time, except that no notes are
actually pushed to the score (because in MIDI guts, a rest is just an
absence of actual notes).

And a call to noop affects NEITHER $Time NOR the score.  It does nothing
but affect $Channel, $Duration, $Octave, and $Volume.


So:

At 12:32 PM 2001-05-20 +0100, Lee Goddard wrote to [email protected]:
>Sean - one question.  In the above page's section,
>_Using_"synch",_and_Some_Actual_Music_, I've played
>with &double_clap, and notice a difference in output
>if I change the line
>	$it->n(c9, ff, n38, sn); # sn = a 16th note
>to the lines
>	$it->n(c9);
>	$it->n( ff, n38, sn); # sn = a 16th note
>[...]

Yes, they mean (and do) different things.  The first block calls n once,
and so lays down one 16th note.  The other block calls n twice, and so lays
things down twice.  What exactly the first line of that second block,
"$it->n(c9);" does, depends on the current values for @Notes, $Duration,
and $Volume.


And at about the same time, Kevin MacLeod wrote to me:

>[...]I tried to get the following result:
>
>               +---A----+
>    +---G-----+
>    +---E---------------+
>    +---C---------------+
>
>using this:
>
>noop c1, F, o4;   # Setup
>r d96;            # Start with a quarter rest.
>noop d192, C, E;  # Insert 2 half notes WITHOUT advancing the clock.
>noop d96, G;      # Insert a concurrent quarter note (no clock advance).
>r d96;            # Advance the clock by a quarter note.
>noop d96, A;      # Insert a quarter note.
>r d192;           # Advance the clock some more.
[...and then says that that doesn't do what he expected it to, and he is
puzzled by this...]

Okay, you thought "noop" inserts notes without advancing $Time.
It actually does nothing at all -- except allowing a way to specify current
values for $Channel and/or $Volume and/or $Duration and/or @Notes, which
subsequent calls to n or r use.
So this:
   noop c5, n62, n67, o4, d96, v80;

is exactly the same as saying:
  $Channel = 1;
  @Notes = (62, 67);
  $Octave = 4;  # used only in interpreting relative note specs
  $Duration = 96;
  $Volume = 80;

If you want to see what the settings are for the "state variables", just
define this sub:
sub how_now {
  print " t$Time d$Duration v$Volume c$Channel o$Octave n(@Notes)\n";
}
and then call it (and possibly dump_score) at points in the program where
you're curious about things.


Kevin MacLeod continued, bringing up another topic:

>Doesn't matter, though - because I figured out I can do everything I 
>want by using the $Time variable.
>
>$Time = 96;
>n d192, C, E;
>$Time = 96;
>n d96, G;
>$Time = 192;
>n d96, A;

Yes, there's no single tidy way to do this:

   T96        T192
    |          |
               +---A----+
    +---G-----+
    +---E---------------+
    +---C---------------+

You could use synch(), but that's entirely overkill for this.

So yes, might as well just use the fiddling with $Time.

(In practice, you'd probably want to save values of $Time and
then call $Time = $saved_time, instead of hardcoding the
time vales to jump to.)


--
Sean M. Burke  [email protected]  http://www.spinn.net/~sburke/