Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MU3] Fix #309371: Ambitus for transposing instruments doesn't update when toggling concert pitch #6494

Closed
wants to merge 1 commit into from

Conversation

Jojo-Schmitz
Copy link
Contributor

@Jojo-Schmitz Jojo-Schmitz commented Aug 25, 2020

@Jojo-Schmitz Jojo-Schmitz marked this pull request as draft August 25, 2020 16:59
@Jojo-Schmitz Jojo-Schmitz changed the title [WIP] fix #309371: Ambitus for transposing instruments doesn't update when toggling concert pitch [MU3] [WIP] Fix #309371: Ambitus for transposing instruments doesn't update when toggling concert pitch Oct 20, 2020
for (Element* e : segment->elist()) {
if (e->isAmbitus()) {
Ambitus* a = toAmbitus(e);
a->updateRange();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the wrong approach.

Ambiti may be hand-edited in inspector (which I often do if there’s an optional extra note that can be left out that is rather out of a normal range). Toggling concert pitch should not update the range from the score; it must rather transpose the top and bottom notes the same as it does to regular notes in that stave.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I see. But a) how to and b) how to get it to work for octave transposing instruments too?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is in the break after the a->updateRange();. Now the iterations stops at the first Ambitus found but the segment might contain more Ambitus's.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Segment, of course, more Ambiti in the same measure, but different staves! Bad thinko on my side I guess.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better the move the Ambitus loop outside the for (Staff* staff : _staves) loop since you end up doing the same thing nstaves() times.
This solves your first problem but still leaves the issue as mentioned by @mirabilos . I indeed do similar things, especially when newer instruments have a larger range (e.g. Baritone Saxophones, even Bb Clarinets which can be extended in the lower range)

Copy link
Contributor Author

@Jojo-Schmitz Jojo-Schmitz Nov 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still needs the check for whether the staff is transposing or not, at least as an optimization. Would solve (a good part of) @mirabilos' issue too, as there it is not about transposing instruments but human singing voices IIRC ;-).
So I added that check.
@mirabilos you can avoid the manual changes of the Ambitus by disabling "Play" for those extra notes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, bad, that change to skip non-transposing instruments/segments causes a crash :-(

@mirabilos
Copy link
Contributor

mirabilos commented Nov 2, 2020 via email

@njvdberg
Copy link
Contributor

njvdberg commented Nov 4, 2020

... except that it does not for octave transposing instruments, anyone any idea why?

I didn't check but that's related to "transposing" clefs? E.g. treble clef 8va bassa?

@Jojo-Schmitz
Copy link
Contributor Author

Jojo-Schmitz commented Nov 4, 2020

Yes (at least I think it is)

@njvdberg
Copy link
Contributor

njvdberg commented Nov 4, 2020

Did a quick check, it seems to works for the first staff only. My example uses a Bb Clarinet and a Bb Bass Clarinet. Now the Bb clarinet staff works fine but the Bass clarinet remains it originals ambitus. Next, switch the staves (in the Instrument Form). Now the Bass clarinet is fine but the the ambitus of the Bb Clarinet is wrong.

for (Element* e : segment->elist()) {
if (e->isAmbitus()) {
Ambitus* a = toAmbitus(e);
a->updateRange();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is in the break after the a->updateRange();. Now the iterations stops at the first Ambitus found but the segment might contain more Ambitus's.

libmscore/score.cpp Outdated Show resolved Hide resolved
@Jojo-Schmitz
Copy link
Contributor Author

BTW: attach here is my test score (rename the .zip away)
ambitus.mscz.zip

@Jojo-Schmitz Jojo-Schmitz marked this pull request as ready for review November 4, 2020 08:30
@Jojo-Schmitz
Copy link
Contributor Author

Jojo-Schmitz commented Nov 4, 2020

OK, left to do: check for and obey manually changed ambitus

@Jojo-Schmitz Jojo-Schmitz force-pushed the ambitus-transposing branch 6 times, most recently from 642fa14 to d4615e5 Compare November 4, 2020 16:23
int tpcTop = 0; // Initialized to prevent warning
int tpcBottom = 0; // Initialized to prevent warning
int pitchTop = SCHAR_MIN-1; // just outside Interval::{chromatic,diatonic}
int pitchBottom = SCHAR_MAX+1; // just outside Interval::{chromatic,diatonic}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better than some 'magic numbers' IMHO

int pitchTop = SCHAR_MIN-1; // just outside Interval::{chromatic,diatonic}
int pitchBottom = SCHAR_MAX+1; // just outside Interval::{chromatic,diatonic}
int tpcTop = Tpc::TPC_INVALID; // Initialized to prevent warning
int tpcBottom = Tpc::TPC_INVALID; // Initialized to prevent warning
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't really matter here, but looks cleaner to me

@@ -621,7 +621,8 @@ void Ambitus::updateRange()
segm = segm->nextCR();
}

if (pitchTop > -1000) { // if something has been found, update this
if (pitchTop > SCHAR_MIN-1/* || pitchBottom < SCHAR_MAX+1 || tpcTop != Tpc::TPC_INVALID || tpc_Bottom != Tpc::TPC_INVALID*/) {
Copy link
Contributor Author

@Jojo-Schmitz Jojo-Schmitz Nov 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting rid if the 'magic numbers'. Not sure whether to uncomment that commented part, or whether it matters at all, tcp_Top always gets changed along with pitchTop, tpc_Bottom along with pitchBottom, and I don't see how pitchBottom could ever get changed without also changing pitchTop or vice versa, so it seems save to assume that checking for one is sufficient.

for (Element* e : segment->elist()) {
if (e && e->isAmbitus()) {
Ambitus* a = toAmbitus(e);
a->updateRange(); // TODO: honor manually modified ambitus
Copy link
Contributor Author

@Jojo-Schmitz Jojo-Schmitz Nov 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here indeed we'd need to transpose rather than update to not loose 'hand-made' settings

@@ -2692,6 +2693,15 @@ void Score::cmdConcertPitchChanged(bool flag, bool /*useDoubleSharpsFlats*/)
{
undoChangeStyleVal(Sid::concertPitch, flag); // change style flag

for (Segment* segment = firstSegment(SegmentType::Ambitus); segment; segment = segment->next1(SegmentType::Ambitus)) {
Copy link
Contributor Author

@Jojo-Schmitz Jojo-Schmitz Nov 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather leave this loop early for all non-transposing instruments (including percussion), but attempts to do so, like using code similar to the one in the below loop, leads to crashes when calculating the Interval.
We'd get all that, if moving this block (back) into that loop, but at a cost: we'd now traverse the segments nstaves() times, which really doesn't make much sense. The upside is that we gather the interval, needed for transposing.
The problem with this is though, that while we can update multiple times, that'd just be a waste, we can't transpose multiple times...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just add two Note objects into the innards of an Ambitus object, recreated upon reading from MSCX or creating the ambitus (i.e. transient, not stored by themselves), and set their properties to the respective highest and lowest note’s on update, and then use the usual transposition functions (epitch(), ppitch(), tpc1(), tpc2(), etc.) internally in the Ambitus’ functions?

Copy link
Contributor Author

@Jojo-Schmitz Jojo-Schmitz Nov 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code sample?
I won't mind you to PR on top of mine ;-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wish I had any… but that’s going to be something major, and I’m behind on billable hours as is. Sorry.

libmscore/ambitus.cpp Outdated Show resolved Hide resolved
@Jojo-Schmitz Jojo-Schmitz changed the title [MU3] [WIP] Fix #309371: Ambitus for transposing instruments doesn't update when toggling concert pitch [MU3] Fix #309371: Ambitus for transposing instruments doesn't update when toggling concert pitch Jan 29, 2021
@Jojo-Schmitz Jojo-Schmitz marked this pull request as draft January 29, 2021 07:23
@RomanPudashkin
Copy link
Contributor

3.x is closed for any changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants