> > I'll finish this tomorrow.

OK, a couple three days later.  I finally got a chance to go back and look at 
this.  The only thing required to get the exported LilyPond to work correctly 
is to change the "r2 r4" it inserts at the beginning of the second segment 
into "\skip 2 \skip 4" instead.

That's probably a subtle change that only requires a bit of logic at whatever 
point in the code wrote out the "r2 r4" in the first place.  I'm not sure 
where they came from.

There are no rests in the XML anywhere, and no time holes that would be 
plugged with formal rest events.  The exporter must be generating these rests 
in some attempt to deal with this segment starting in the middle of a bar's 
time span.

Here we are:

             // Add a skip for the duration until the start of the first
             // bar in the segment.  If the segment doesn't start on a bar
             // line, an additional skip will be written (in the form of
             // a series of rests) at the start of writeBar, below.
             //!!! This doesn't cope correctly yet with time signature changes
             // during this skipped section.

Nice job Heikki.  This is why comments are useful, and this is why trying to 
figure out so much of our code royally sucks.  Not enough comments!  Not 
remotely enough comments!

OK then, this comment already tells me where to look, and admits that the 
space will be filled up with a series of rests.  I think we have a really 
good case to make that using rests is wrong.  Rests don't exist in the 
incoming data stream for good reason, because there isn't supposed to be any 
time there (inside this particular segment we're iterating through at that 
point in the run) that could contain rests at all.

So let's just find that code and make it write \skip instead, shall we?

Turns out all I have to do is change the bool useRests from true to false in 
the call to writeSkip to bring about this change.  

Heikki?  Is there a problem with this approach?

OK, let's see.  After that change, the two superfluous rests at the start of 
the second segment are replaced with skips, but now the short bar padder that 
got resurrected when I built the latest SVN updates has added an extra rest 
to the end of segment A that should not be there.

Heikki?  You insist this serves some worthwhile purpose, and you put the code 
back and tried to tweak it to avoid this problem, but this is the kind of 
thing I was trying to avoid by commenting it out.

%% 5
                d'' 4 d'' d''
                % warning: bar too short, padding with rests
                % 15360 + 2880 < 19200  &&  3/4 < 4/4
                r4  |

Would it work correctly if Rosegarden had a smarter idea of where the barlines 
are?  It looks like that is the problem here.

I'm thinking so, yes, if Composition::getBarEnd() returned an accurate point 
in time for bar 5, which actually ends a beat short, then the short bar 
padder would probably be avoided.

That seems a bit tricky to do anything about, because getBarStart() and 
getBarEnd() will "appily return theoretical timings for bars before the start 
or beyond the end of composition."

It doesn't look like there's any way to relate this to actual segment 
boundaries without a serious think.

Chris?

Would this kind of think also have a positive impact on the garbage the 
notation editor is producing?  Maybe we need a smarter underlying idea of 
what a bar is.  I'm not sure if we want this to replace the current 
functionality, or something done in parallel.

We need to calculate the left and right points for the bar based on space 
that's within a segment, not just absolute theoretical space.

 4   |      5         |     6
  . (x) .   .  (z) . (y)  .   .   .
AAAAA|AAAAAAAAAA|BBBBB|BBBBBBBBBBB

We currently start off inside Segment A.  We call getBarStart(5) which returns 
time point x and getBarEnd(5) which returns time point y.

We move to Segment B.  getBarStart(5) again returns x and getBarEnd(5) returns 
y.

What should, in fact, happen is that for Segment A, getBarStart(5) should 
return x, because x is the correct time point for the start of bar number 5, 
and x is inside the segment.  getBarEnd(5) should return z, rather than y, 
because z is the closest point in time to y that falls *inside* the segment 
boundary.  For Segment B, getBarStart(5) should actually return z rather than 
x, and getBarEnd(5) should return y.

Or perhaps what is needed is some replacement for Composition::getBarStart() 
and ::getBarEnd() entirely.  I'm not sure how all of that would work.  
Perhaps making these existing methods smarter would fix the notation editor's 
problems, but it could well be the case we really need to leave them alone, 
and have some other getBar methods somewhere else in addition to these.  
Perhaps in Segment or something.

The LilyPond exporter could call these alternative methods, and perhaps the 
notation editor could make use of them too.  It might obviate the change I 
just committed too.  The best way to deal with space outside a segment 
needing to be filled up is to have a better understanding of what's going on 
in the first place, so there doesn't seem to be a hole that really doesn't 
exist.  The hole only exists because our internal concept of barlines is too 
rigid for the real world.  It isn't that the boundaries at x and y are wrong, 
but that in the real world there is actually a barline in the middle of bar 
5, at the segment boundary.

Of course, too, if the segments aren't placed perfectly, there is all kinds of 
room for this to go all to hell quickly.  It's very easy to be off by enough 
to matter very much when doing this kind of positioning by hand, and we could 
definitely wind up with ugly data and broken output.  This could all be 
corrected by adjusting the timings precisely though, and it's definitely 
possible, useful, and musically necessary to create such data in many 
real-world situations.

OK, that concludes my analysis and contemplation so far.  I invite Chris and 
Heikki to think about this and comment before I dig any further.

(My vacation didn't last very long, because it's now too cold outside for 
glue.  I should have started the shop project a month ago. Oh well.)
-- 
D. Michael McIntyre 

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Rosegarden-devel mailing list
[email protected] - use the link below to unsubscribe
https://lists.sourceforge.net/lists/listinfo/rosegarden-devel

Reply via email to