Tuplet logic

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Tuplet logic

jorgk3
Hello,

I have a question, that most likely Werner can answer best.

When I select a note, either via shift select or lasso select, a range is selected.

The selection looks like this:
class Selection {
...
      Segment* _startSegment;
      Segment* _endSegment;         // next segment after selection
...

The _endSegment is really populated with the next segment containing a note (so not the segment with the barline if the last note in a bar is selected).

First question: Why? How do we know where the selection ends?

Now look at the triplet checking logic:
bool Selection::canCopy() const
      {
      if (_state != SEL_RANGE)
            return true;

      for (int staffIdx = _staffStart; staffIdx != _staffEnd; ++staffIdx) {
            if (isInMiddleOfTuplet(_startSegment->element(staffIdx)))
                  return false;
            if (_endSegment && isInMiddleOfTuplet(_endSegment->element(staffIdx)))
                  return false;
            }
      return true;
      }

This checks that start segment is not in the middle of a tuplet and that the end segment is not in the middle of a tuplet.

Take the example of triplets: Say we have 2/4 time and 1/8 triplets, so:
(1 2 3) (4 5 6).

If I shift select 1, start segment will be 1, end segment 2, the test fails, since 2 is in the middle.
If I shift select 2, start segment will be 2, end segment 3, the test fails, since 3 is in the middle.
But now:
If I shift select 3, start segment will be 3, end segment 4, the test does NOT fail, so the logic detects a valid selection to copy. However, the copy causes corruption as can be seen in http://musescore.org/en/node/14648.

(Note: of course the triplets are chords, so shift select makes sense ;-))

So obviously the test is wrong. But how to fix it? Test the start segment and the real last segment of the selection, not the end segment?

Same logic in branch and trunk (select.cpp). So it needs to be fixed in both places.

Having said that, of course it would be nice if the test would allow a single segment to be copied, but that's further down the track. First we need to understand what's going on here.

Or perhaps Werner can implement his solution in the trunk and I'll port it back if possible.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Tuplet logic

Werner Schweer
Hi,
answer to first question is obvious: bc. i found it convenient to do it
this way. I dont understand the second
part of the question. The interval is startSegment <= segment <=
endSegment, so whats wrong with endSegment?

The check in canCopy() is wrong. There has to be a check for begin
selection crossing an tuplet and an different
check for end of selection. A selection can start at the beginning of an
tuplet (and not in middle or end) and
end at the last element of an tuplet (or outside of an tuplet of course).
To select parts of an tuplet the nesting level of nested tuplets must be
considered. Additional code is needed to
transform chord/rest values.

/Werner

On 02/10/2012 08:42 PM, jorgk3 wrote:

> Hello,
>
> I have a question, that most likely Werner can answer best.
>
> When I select a note, either via shift select or lasso select, a range is
> selected.
>
> The selection looks like this:
> class Selection {
> ...
>        Segment* _startSegment;
>        Segment* _endSegment;         // next segment after selection
> ...
>
> The _endSegment is really populated with the next segment containing a note
> (so not the segment with the barline if the last note in a bar is selected).
>
> First question: Why? How do we know where the selection ends?
>
> Now look at the triplet checking logic:
> bool Selection::canCopy() const
>        {
>        if (_state != SEL_RANGE)
>              return true;
>
>        for (int staffIdx = _staffStart; staffIdx != _staffEnd; ++staffIdx) {
>              if (isInMiddleOfTuplet(_startSegment->element(staffIdx)))
>                    return false;
>              if (_endSegment&&
> isInMiddleOfTuplet(_endSegment->element(staffIdx)))
>                    return false;
>              }
>        return true;
>        }
>
> This checks that start segment is not in the middle of a tuplet and that the
> end segment is not in the middle of a tuplet.
>
> Take the example of triplets: Say we have 2/4 time and 1/8 triplets, so:
> (1 2 3) (4 5 6).
>
> If I shift select 1, start segment will be 1, end segment 2, the test fails,
> since 2 is in the middle.
> If I shift select 2, start segment will be 2, end segment 3, the test fails,
> since 3 is in the middle.
> But now:
> If I shift select 3, start segment will be 3, end segment 4, the test does
> NOT fail, so the logic detects a valid selection to copy. However, the copy
> causes corruption as can be seen in http://musescore.org/en/node/14648.
>
> (Note: of course the triplets are chords, so shift select makes sense ;-))
>
> So obviously the test is wrong. But how to fix it? Test the start segment
> and the real last segment of the selection, not the end segment?
>
> Same logic in branch and trunk (select.cpp). So it needs to be fixed in both
> places.
>
> Having said that, of course it would be nice if the test would allow a
> single segment to be copied, but that's further down the track. First we
> need to understand what's going on here.
>
> Or perhaps Werner can implement his solution in the trunk and I'll port it
> back if possible.
>
>
> --
> View this message in context: http://musescore-developer.685061.n2.nabble.com/Tuplet-logic-tp7273953p7273953.html
> Sent from the MuseScore Developer mailing list archive at Nabble.com.
>
> ------------------------------------------------------------------------------
> Virtualization&  Cloud Management Using Capacity Planning
> Cloud computing makes use of virtualization - but cloud computing
> also focuses on allowing computing to be delivered as a service.
> http://www.accelacomm.com/jaw/sfnl/114/51521223/
> _______________________________________________
> Mscore-developer mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/mscore-developer
>


------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
Mscore-developer mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mscore-developer
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Tuplet logic

jorgk3
Hi Werner,

thank you for the quick reply.

You meant: startSegment <= segment < endSegment.

Since you are the guru, would you like to fix it in the trunk and I copy it into the branch?

I'd really like to see the ability to copy simple chords from a tuplet to a rest of the same length, so an 1/8 triplet chord to an 1/8 triplet rest, or ideally, to an 1/8 (non triplet) rest.

Ideally, everything that works now for a single note when copied should work for a chord as well. If you copy a single 1/8 triplet note, it can be pasted anywhere, into the same or another tuplet bracket, or onto a rest. In the latter case it copies as at its face value. This was fixed in http://musescore.org/en/node/3482.

No one wants to copy "partial" tuplets, all we need is the ability to copy a single chord (and of course, a range containing one or more complete tuplets - but that works now).

Kind regards,
Jörg.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Tuplet logic

jorgk3
Sorry, I hadn't noticed that you have already checked in a fix for the test.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Tuplet logic

jorgk3
Werner, can you please correct [trunk] select.cpp. What you checked in is not correct.

As I pointed out, _endSegment points to segment **after** the selection. Therefore it makes no sense, to use it in a test.

Please consider my example given above:
(1 2 3) (4 5 6).

If I now lasso select 1 and 2, end segment is 3.

The test succeeds, as 1 is at the start of the tuplet, 3 is at the end. But 3 is not part of the selection. When you go ahead with the copy, corruptions is the result.

Your change also broke the facility to copy the whole tuplet. If you lasso select (1 2 3) then the test fails on the end segment being 4, and that's not at the end of a tuplet.

That's why I questioned the usefulness of _endSegment pointing to somewhere outside the selection. In any case, in my humble opinion, it's badly named, since it confuses.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Tuplet logic

jorgk3
Patch for Werner's change was proposed in http://musescore.org/en/node/3482
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Tuplet logic

jorgk3
Sorry, I got this wrong:
Patch for Werner's change was proposed in http://musescore.org/en/node/14648
Loading...