Subject: [AVT] Comments (2) on draft-ietf-avt-mwpp-midi-rtp-02.txt

From: Dominique Fober <[email-masked]>
Date: Wed, 6 Mar 2002 20:31:02 +0100

Hi,

And here are my comments on draft-ietf-avt-mwpp-midi-rtp-02.txt appendix.
You can read comments about the core draft in my previous message.
Best,
----------------------------------------------
Dominique Fober               <[email-masked]>
----------------------------------------------
GRAME - Centre National de Creation Musicale -
9 rue du Garet  69001 Lyon France
tel:+33 (0)4 720 737 06 fax:+33 (0)4 720 737 01
http://www.grame.fr/

>Appendix A.1. Chapter P: MIDI Program Change

I would like some more details about the chapter P:
imagine the following stream (where BS is Bank Select and PC Program Change):
	... BS a ... PC n ... BS b ... PC m
	 		 |t1      |t2      |t3
how should the stream history be coded in the recovery journal 
at times t1 to t3 ?
I guess the following:
at time t1: "BS a" is to be coded in chapter C
at time t2: "BS a + PC n" are to be coded in chapter P
at time t3: "BS a + PC n" are to be coded in chapter P 
             and "BS b" is to be coded in chapter C
is it right ? as bank select (Control Change 0) may be coded both in 
chapter C and P, don't you think that additionnal rules may be added 
to remove the ambiguity ?

[ a general remark about the LENGTH field across the different chapters ]
when present, the LENGTH field is used in a non homogeneous way:
chapter N: allow an empty note list (empty bitfield is also allowed)
chapter A: doesn't allow an empty note log
chapter C: doesn't allow an empty controler log
chapter M: allow an empty log list
wouldn't it be more coherent to let LENGTH be the number of log entries 
for chapter A and C (and not the number of log entries minus 1).
Then an empty log lists is allowed for each chapter and the journal may be
parsed in a more homogeneous way.

>Appendix A.7. Chapter M: MIDI Parameter System
...

>The M flag is 1 if another KEY octet follows the DATA octet(s). 

I don't understand why successive KEY octets would be needed.
Let's take an example with the following stream:
RPN 0, Ctrl6 (coarse), Ctrl38 (fine) ... RPN 0, Ctrl96 (data increment)...
if I'm not wrong, it may be coded in the journal as follow:

      param number     key octet   data 1   data 2   data 3 
    |        0      |S|0|01|02|03| coarse |  fine  |    1   |

following data entries should replace the values above and clear the IN3 
field, and following data increment (or decrement) should only modify the 
third data octet.

I also don't understand why IN1 = IN2 = IN3 = 0 is a valid key. Sure that 
you could write the previous example as 
    |        0      |S|1|00|00|00|S|0|01|02|03| coarse |  fine  |    1   |
which makes use of the M flag but it makes no sense for me.

At all, my overall feeling is that it may be simplified: instead of using 
6 bits to code the presence of controlers 6, 38, 96 and 97, you may use only
a 3-bits field as follow:
    |C|F|I|
where C indicates the presence of a data entry coarse value
      F indicates the presence of a data entry fine value
  and I indicates the presence of cumulative effect of data increment 
        or decrement
with the values following in the order of their declaration.

But again, maybe I miss some problem. It's a naive point of view and I've
certainly think about the problem less than you.

Otherwise, I've tried to evaluate the recovery journal expected size in
a reasonnable context ie containing 1 program change, 1 pitch wheel,
20 note on and 20 note off (using 5 bitfield bytes), 20 poly aftertouch
and 10 control change, all of these on 4 different channels:
the resulting size should be 471 bytes which is both a big and a small
value. Big: because it represents certainly a good part of the bandwith
use. Small: because the same information encoded as MIDI would represent
nearly 900 bytes.
Have you tried to measure the recovery journal cost on real world 
situations ? playing different MIDI files for example.

_______________________________________________
Audio/Video Transport Working Group
[email-masked]
https://www1.ietf.org/mailman/listinfo/avt

---

From: John Lazzaro <[email-masked]>
Date: Sat, 9 Mar 2002 19:44:56 -0800

> Dominique Fober writes:

Part 2 comments inline below ... thanks again for your comments ...

------

> Dominique Fober writes:
>	     |t0       |t1      |t2      |t3

No, it should be (assuming the checkpoint packet isn't moved within
the entire time period):

at t0: Chapter C codes "BS a"
at t1: Chapter P codes "BS a + PC n", Chapter C codes "BS a"
at t2: Chapter P codes "BS a + PC n", Chapter C codes "BS b"
at t3: Chapter P codes "BS b + PC m", Chapter C codes "BS b"

So, the basic idea is, Chapter P needs to have these BS fields,
because you need to remember the current Bank Select values at the
time the PC command occurs -- even if a new Chapter C value has
happened in the interim. This reflects the underlying semantics of
what happened in the MIDI stream -- the PC command executes using the
current BS value at that time. I've read over the text for Chapter P,
and I believe it accurately states the semantics above, let me know if
you think the text doesn't state these semantics.

So, this is why Chapter P updates at t1 and t3, but not at t2.

> Dominique Fober writes:
> chapter C and P, don't you think that additional rules may be added 

The dual coding is needed; consider:

   packet 1:  MIDI Command section holds Bank Select command
   packet 2:  MIDI Command section holds Program Change command;
              Chapter C holds BS command from MIDI Command of packet 1.
   packet 3:  Empty MIDI Command section; a new Bank Select command recovery
              journal has both Chapter C and Chapter P

What if we lose packet 1, but packet 2 arrives? We would be able to
examine the recovery journal, learn about the lost Bank Select
command, and then execute the Program Change command with the correct
Bank. If we didn't have a Chapter C element for Bank Select, we'd be
out of luck.

Also, note that there's no ambiguity in having a Chapter P and Chapter
C with different Bank Select values; Chapter P's BS command in the one
that was in effect when the PC happened, Chapter C's is the current
Bank Select value, which may have changed (in preparation for a new PC
command, perhaps).

Remember, Chapter P and the Chapter C Bank Select in practice will
have a minimal effect on recovery journal bandwidth, because they
happen rarely: as the checkpoint packet moves past them they disappear
from the journal. The costly recovery journal fields are the ones that
represent ongoing gestural movements, because they never drop out as
the checkpoint packet advances.

-----

> Dominique Fober writes:

This is a good point, thanks for pointing it out ... what gives me
pause is that we lose some representational power: Chapters C and A
have the "log entry - 1" encoding so that the (rare but legal) all 128
controller/polytouch messages active condition is
encodable. Admittedly, Chapter N's coding method lacks this
"worst-case" representational power too, but efficiency really
demanded it: the "no notes depressed" case is quite common, and so we
needed a way to code the LENGTH == 0 concept, but there were no free
bits around to code it as a special case.

So, its a tradeoff: orthogonality, at the expense of losing a bit of
very rarely used representational power ...

----------

> Dominique Fober writes:

This situation (guard packets 2 and 3 not shown):

 Ctrl6 (coarse=10) Ctrl38 (fine=0) Ctrl96 Ctrl6 (coarse=9) || Ctrl38 (fine=127)
                                                           ||
  <------------in packet #1 (MIDI Command section)------>  ||  in packet #4

In the current scheme, the recovery journal for packets 2 and 3 hold:

 |  key octet |  data 1 |  data 2 |  data 3 |   key octet |  data 1  | 
 |S|1|01|02|03|   10    |    0    |    1    |S|0|01|00|00 |    9     |

If 1 is lost but 2 arrives, the receiver sees that a complete
coarse-fine update happened, followed by an increment, and that
one-half of the next coarse-fine update is underway.  It can handle
this however it usually does, probably by waiting for the next fine to
show up (eventually, in packet #4) before executing the last
coarse-fine pair.

A scheme that doesn't code a series of commands can't easily
communicate these sort of unusual conditions. I tried for a few days
to come up with a more compact version before deciding to code Chapter
M in the most literal way.

A complicating issue is, some Parameters are 7-bit, and so only Cntrl
6 (coarse)s are sent, and data entry buttons increment a 7-bit value;
other parameters are 14-bit, use both Cntrl 6 (coarse) and Cntrl 38
(fine), and the data entry buttons increment the 14 bit value. Without
knowing the type of parameter (impossible with NRPNs -- only the
device may know for sure), you can't simply emulate the receiver and
send those values along in a nice compressed recovery journal format.
This factor also led me to go the enumeration route ...

> Dominique Fober writes:
>
> I also don't understand why IN1 = IN2 = IN3 = 0 is a valid key.

Note that in Figure A.7.2:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |S|T|       PARAM-NUMBER        |     KEY       |  DATA   ...   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   ...         |      KEY      |   DATA ...                    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

There's no LENGTH field in the header, not even a spare bit to code
the "empty list" state. However, the "empty list" codes important
information: it lets us code that (98,99) or (100,101) commands have
occurred to "open up" PARAM-NUMBER for changing, but that the no
(6,38,96,97) commands have be sent that make changes. So, we use the M
= IN1 = IN2 = IN3 = 0 KEY octet to code the "empty" list. This is also
why we mandate at least one KEY octet -- even if there are no
6/38/96/97 commands to code, we need to code the termination of the
(empty) list.

Note this "empty list" only codes useful information in conjunction
with setting the P or N bit in the top-level Chapter M header:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |S|P|N|R|R|R|      LENGTH       |  Parameter log list ...       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

When the P or N bit is set, it says "the first P or N parameter in the
list is the currently open one."

Yes, there's a bug here (just saw it as I wrote this ...) -- if you
send a packet with just 98 but no 99, or send a packet with just a 100
and no 101, you can't code a Chapter M as it currently exists to
express this. There's a few alternatives here ... the Chapter C logs
for 98/99/100/101 might be given special semantics to code this case,
for example. I'll think about it for the next revision ...

-------

> Dominique Fober writes:

Yes, I'm able set up to stream MIDI files through the older version of
MWPP that sfront uses, and collect the stream statistics, this is how
I got the bandwidth statistics in Table 4 in the MWPP paper (although
that wasn't a file, it was real-time playing).

It might be best to wait until the MIDI Systems MWPP definitions are
finished to do a comprehensive MIDI file bandwidth test, so I can
update sfront with the updated formats in the memo. We can then
collect from MIDI files from the net, take statistics, and see what
needs optimization ...

Finally, bote that the bandwidth numbers you get can change pretty
radically based on how persistent controllers and aftertouch are
throughout the piece -- the checkpoint packet mechanism acts to flush
rarely-used MIDI commands out of the system quickly.

-------------------------------------------------------------------------
John Lazzaro -- Research Specialist -- CS Division -- EECS -- UC Berkeley
lazzaro [at] cs [dot] berkeley [dot] edu     www.cs.berkeley.edu/~lazzaro
-------------------------------------------------------------------------