Skip to content

Commit bd7808b

Browse files
committed
Clefs: BARITONE is based on F_CLEF rather than C_CLEF. Handbook updated with Clef editor section
1 parent 17483d7 commit bd7808b

File tree

9 files changed

+199
-83
lines changed

9 files changed

+199
-83
lines changed

app/src/main/java/org/audiveris/omr/sig/inter/AbstractPitchedInter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ private static class Constants
321321
extends ConstantSet
322322
{
323323
private final Constant.Boolean printPitchOffsets = new Constant.Boolean(
324-
true,
324+
false,
325325
"Should we print all pitch offsets");
326326
}
327327
}

app/src/main/java/org/audiveris/omr/sig/inter/ClefInter.java

Lines changed: 125 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@
5656
* <p>
5757
* Pitch of NoteStep line of the clef:
5858
* <ul>
59-
* <li>-4 for top line (Baritone)
59+
* <li>-4 for top line (old Baritone)
6060
* <li>-2 for Bass and Tenor
61-
* <li>0 for Alto
61+
* <li>0 for Alto and Baritone
6262
* <li>+2 for Treble and Mezzo-Soprano
6363
* <li>+4 for bottom line (Soprano)
6464
* </ul>
@@ -149,8 +149,8 @@ private int absolutePitchOf (int intPitch)
149149
case G_CLEF, G_CLEF_SMALL -> 34 - intPitch;
150150
case G_CLEF_8VA -> (34 + 7) - intPitch;
151151
case G_CLEF_8VB -> (34 - 7) - intPitch;
152-
case C_CLEF -> 28 - (int) Math.rint(this.pitch) - intPitch;
153-
case F_CLEF, F_CLEF_SMALL -> 22 - intPitch;
152+
case C_CLEF -> (28 - (int) Math.rint(this.pitch)) - intPitch;
153+
case F_CLEF, F_CLEF_SMALL -> (20 - (int) Math.rint(this.pitch)) - intPitch;
154154
case F_CLEF_8VA -> (22 + 7) - intPitch;
155155
case F_CLEF_8VB -> (22 - 7) - intPitch;
156156
case PERCUSSION_CLEF -> 0;
@@ -179,7 +179,7 @@ public void added ()
179179
{
180180
super.added();
181181

182-
// Add it to containing measure stack
182+
// Add it to the containing measure stack
183183
MeasureStack stack = sig.getSystem().getStackAt(getCenter());
184184

185185
if (stack != null) {
@@ -210,21 +210,21 @@ public boolean deriveFrom (ShapeSymbol symbol,
210210
return false;
211211
}
212212

213-
// We snap ordinate to lines, according to the clef shape
213+
// We snap ordinate to specific lines, according to the clef shape
214214
boolean modified = false;
215215
final Point center = getCenter();
216216
final Integer targetPitch = getTargetPitch(symbol.getShape(), center, staff);
217217

218218
if (targetPitch != null) {
219-
// Adjust ordinate
219+
// Adjust the ordinate
220220
final double pitchOffset = getAreaPitchOffset(shape);
221221
dropLocation.y = (int) Math.rint(
222222
staff.pitchToOrdinate(center.x, targetPitch - pitchOffset));
223223

224224
modified = true;
225225

226-
if (shape == Shape.C_CLEF) {
227-
// Adjust C clef kind
226+
if (kindIsMutable(shape)) {
227+
// Precise the clef kind
228228
center.y = dropLocation.y;
229229
kind = kindOf(center, shape, staff);
230230
}
@@ -254,7 +254,7 @@ public InterEditor getEditor ()
254254
/**
255255
* Report the current kind of the clef.
256256
* <p>
257-
* NOTA: The kind changes if a C_CLEF is moved up or down
257+
* NOTA: The kind changes if a C_CLEF / F_CLEF / F_CLEF_SMALL is moved up or down
258258
*
259259
* @return the kind
260260
*/
@@ -282,6 +282,15 @@ public Point2D getRelationCenter ()
282282
center.getY() + (0.5 * il * getAreaPitchOffset(shape)));
283283
}
284284

285+
//----------------//
286+
// getShapeString //
287+
//----------------//
288+
@Override
289+
public String getShapeString ()
290+
{
291+
return kind + " " + shape;
292+
}
293+
285294
//-------------------------//
286295
// imposeWithinStaffLimits //
287296
//-------------------------//
@@ -319,7 +328,10 @@ private HeadInter.NoteStep noteStepOf (int pitch)
319328
case C_CLEF ->
320329
HeadInter.NoteStep.values()[((72 + (int) Math.rint(this.pitch)) - pitch) % 7];
321330

322-
case F_CLEF, F_CLEF_SMALL, F_CLEF_8VA, F_CLEF_8VB -> //
331+
case F_CLEF, F_CLEF_SMALL -> //
332+
HeadInter.NoteStep.values()[((75 + (int) Math.rint(this.pitch)) - pitch) % 7];
333+
334+
case F_CLEF_8VA, F_CLEF_8VB -> //
323335
HeadInter.NoteStep.values()[(73 - pitch) % 7];
324336

325337
default -> {
@@ -348,7 +360,7 @@ private int octaveOf (double pitchPosition)
348360
case G_CLEF_8VA -> ((34 - intPitch) / 7) + 1;
349361
case G_CLEF_8VB -> ((34 - intPitch) / 7) - 1;
350362
case C_CLEF -> ((28 + (int) Math.rint(this.pitch)) - intPitch) / 7;
351-
case F_CLEF, F_CLEF_SMALL -> (22 - intPitch) / 7;
363+
case F_CLEF, F_CLEF_SMALL -> ((24 + (int) Math.rint(this.pitch)) - intPitch) / 7;
352364
case F_CLEF_8VA -> ((22 - intPitch) / 7) + 1;
353365
case F_CLEF_8VB -> ((22 - intPitch) / 7) - 1;
354366

@@ -429,6 +441,26 @@ public static int absolutePitchOf (ClefInter clef,
429441
}
430442
}
431443

444+
//---------//
445+
// cKindOf //
446+
//---------//
447+
/**
448+
* Report the precise ClefKind for a C_CLEF shape at the provided pitch.
449+
*
450+
* @param pitch the provided pitch (rounded to multiple of 2)
451+
* @return the corresponding ClefKind
452+
*/
453+
public static ClefKind cKindOf (int pitch)
454+
{
455+
return switch (pitch) {
456+
case -2 -> ClefKind.TENOR;
457+
case 0 -> ClefKind.ALTO;
458+
case 2 -> ClefKind.MEZZO_SOPRANO;
459+
case 4 -> ClefKind.SOPRANO;
460+
default -> null;
461+
};
462+
}
463+
432464
//-------------//
433465
// createValid //
434466
//-------------//
@@ -456,35 +488,44 @@ public static ClefInter createValid (Glyph glyph,
456488
case G_CLEF, G_CLEF_SMALL, G_CLEF_8VA, G_CLEF_8VB -> //
457489
new ClefInter(glyph, shape, grade, staff, 2.0, ClefKind.TREBLE);
458490

459-
case C_CLEF -> {
491+
case C_CLEF, F_CLEF, F_CLEF_SMALL -> {
460492
final Point2D center = glyph.getCenter2D();
461493
final ClefKind kind = kindOf(center,shape,staff);
462-
final int roundedPitch = getTargetPitch(shape, center, staff);
494+
final int roundedPitch = ClefInter.getTargetPitch(shape, center, staff);
463495
yield new ClefInter(glyph, shape, grade, staff, (double) roundedPitch, kind);
464496
}
465497

466-
case F_CLEF, F_CLEF_SMALL, F_CLEF_8VA, F_CLEF_8VB -> //
498+
case F_CLEF_8VA, F_CLEF_8VB -> //
467499
new ClefInter(glyph, shape, grade, staff, -2.0, ClefKind.BASS);
468500

469501
case PERCUSSION_CLEF -> //
470502
new ClefInter(glyph, shape, grade, staff, 0.0, ClefKind.PERCUSSION);
471503
};
472504
}
473505

474-
//----------------//
475-
// getShapeString //
476-
//----------------//
477-
@Override
478-
public String getShapeString ()
506+
//---------//
507+
// fKindOf //
508+
//---------//
509+
/**
510+
* Report the precise ClefKind for a F_CLEF / F_CLEF_SMALL shape at the provided pitch.
511+
*
512+
* @param pitch the provided pitch (rounded to multiple of 2)
513+
* @return the corresponding ClefKind
514+
*/
515+
public static ClefKind fKindOf (int pitch)
479516
{
480-
return kind + " " + shape;
517+
return switch (pitch) {
518+
case -2 -> ClefKind.BASS;
519+
case 0 -> ClefKind.BARITONE;
520+
default -> null;
521+
};
481522
}
482523

483524
//----------------//
484525
// getTargetPitch //
485526
//----------------//
486527
/**
487-
* Report the theoretical pitch of clef center when correctly aligned with
528+
* Report the theoretical pitch of clef reference line when correctly aligned with
488529
* possible staff lines.
489530
*
490531
* @param shape clef shape
@@ -501,29 +542,63 @@ public static Integer getTargetPitch (Shape shape,
501542
}
502543

503544
return switch (shape) {
504-
case C_CLEF -> {
505-
final double pitchModuloTwo = staff.pitchPositionOf(center) / 2.0;
506-
int target = 2 * (int) Math.rint(pitchModuloTwo);
507-
target = Math.min(target, 4);
508-
target = Math.max(target, -4);
509-
yield target;
510-
}
511-
512-
case F_CLEF, F_CLEF_SMALL, F_CLEF_8VA, F_CLEF_8VB -> -2;
513-
545+
case C_CLEF -> getTargetPitch(shape, center, staff, -2, 4);
546+
case F_CLEF, F_CLEF_SMALL -> getTargetPitch(shape, center, staff, -2, 0);
547+
case F_CLEF_8VA, F_CLEF_8VB -> -2;
514548
case G_CLEF, G_CLEF_SMALL, G_CLEF_8VA, G_CLEF_8VB -> 2;
515-
516549
case PERCUSSION_CLEF -> 0;
517-
518-
default -> null;
550+
default -> {
551+
logger.error("{} is not a valid shape for a clef", shape);
552+
yield null;}
519553
};
520554
}
521555

556+
//----------------//
557+
// getTargetPitch //
558+
//----------------//
559+
/**
560+
* Report the closest theoretical reference pitch for clef.
561+
*
562+
* @param shape clef shape
563+
* @param center current clef area center
564+
* @param staff underlying staff
565+
* @param min minimum pitch value
566+
* @param max maximum pitch value
567+
* @return the most suitable reference pitch value
568+
*/
569+
private static int getTargetPitch (Shape shape,
570+
Point2D center,
571+
Staff staff,
572+
int min,
573+
int max)
574+
{
575+
// Pitch even target value
576+
final double centerPitch = staff.pitchPositionOf(center);
577+
final double pitchOffset = getAreaPitchOffset(shape); // Area center -> Clef reference point
578+
final int evenPitchTarget = 2 * (int) Math.rint((centerPitch + pitchOffset) / 2.0);
579+
580+
return Math.min(max, Math.max(min, evenPitchTarget));
581+
}
582+
583+
//---------------//
584+
// kindIsMutable //
585+
//---------------//
586+
/**
587+
* Report whether the clef kind can change, based on the vertical location of the shape.
588+
*
589+
* @param shape the clef shape
590+
* @return true if so
591+
*/
592+
private static boolean kindIsMutable (Shape shape)
593+
{
594+
return (shape == Shape.C_CLEF) || (shape == Shape.F_CLEF) || (shape == Shape.F_CLEF_SMALL);
595+
}
596+
522597
//--------//
523598
// kindOf //
524599
//--------//
525600
/**
526-
* Report the ClefKind for a provided OmrShape
601+
* Report the ClefKind for a provided OmrShape.
527602
*
528603
* @param omrShape provided OmrShape
529604
* @return related ClefKind
@@ -562,12 +637,10 @@ public static ClefKind kindOf (Point2D center,
562637

563638
return switch (shape) {
564639
case G_CLEF, G_CLEF_SMALL, G_CLEF_8VA, G_CLEF_8VB -> ClefKind.TREBLE;
565-
case C_CLEF -> {
566-
// Disambiguate between all C-clef possibilities
567-
final int roundedPitch = getTargetPitch(shape, center, staff);
568-
yield CKindOf(roundedPitch);
569-
}
570-
case F_CLEF, F_CLEF_SMALL, F_CLEF_8VA, F_CLEF_8VB -> ClefKind.BASS;
640+
case C_CLEF -> cKindOf(ClefInter.getTargetPitch(shape, center, staff));
641+
case F_CLEF, F_CLEF_SMALL -> fKindOf(ClefInter.getTargetPitch(shape, center, staff));
642+
case F_CLEF_8VA, F_CLEF_8VB -> ClefKind.BASS;
643+
571644
case PERCUSSION_CLEF -> ClefKind.PERCUSSION;
572645
default -> null;
573646
};
@@ -616,29 +689,11 @@ public static int octaveOf (ClefInter clef,
616689
}
617690
}
618691

619-
//---------//
620-
// CKindOf //
621-
//---------//
622-
/**
623-
* Report the precise ClefKind for a C_CLEF shape at the provided pitch
624-
*
625-
* @param pitch the provided pitch (rounded to multiple of 2)
626-
* @return the corresponding ClefKind
627-
*/
628-
public static ClefKind CKindOf (int pitch)
629-
{
630-
return switch (pitch) {
631-
case -4 -> ClefKind.BARITONE;
632-
case -2 -> ClefKind.TENOR;
633-
case 0 -> ClefKind.ALTO;
634-
case 2 -> ClefKind.MEZZO_SOPRANO;
635-
case 4 -> ClefKind.SOPRANO;
636-
default -> null;
637-
};
638-
}
639-
640-
//~ Enumerations -------------------------------------------------------------------------------
692+
//~ Inner Classes ------------------------------------------------------------------------------
641693

694+
//----------//
695+
// ClefKind //
696+
//----------//
642697
/**
643698
* Clef kind, based on shape and pitch.
644699
*/
@@ -647,8 +702,8 @@ public static enum ClefKind
647702
TREBLE(Shape.G_CLEF, 2),
648703

649704
BASS(Shape.F_CLEF, -2),
705+
BARITONE(Shape.F_CLEF, 0),
650706

651-
BARITONE(Shape.C_CLEF, -4),
652707
TENOR(Shape.C_CLEF, -2),
653708
ALTO(Shape.C_CLEF, 0),
654709
MEZZO_SOPRANO(Shape.C_CLEF, 2),
@@ -678,7 +733,8 @@ public static enum ClefKind
678733
* <p>
679734
* For a clef, we provide only one handle:
680735
* <ul>
681-
* <li>Middle handle, moving vertically only for C_CLEF, and horizontally fur all shapes.
736+
* <li>Middle handle, moving vertically only for C_CLEF / F_CLEF / F_CLEF_SMALL,
737+
* and horizontally for all shapes.
682738
* </ul>
683739
*/
684740
private static class Editor
@@ -709,7 +765,7 @@ public Editor (final ClefInter clef)
709765
public boolean move (int dx,
710766
int dy)
711767
{
712-
if (shape != Shape.C_CLEF) {
768+
if (!kindIsMutable(shape)) {
713769
dy = 0;
714770
}
715771

@@ -732,8 +788,8 @@ public boolean move (int dx,
732788
latestBounds.y = (int) Math.rint(newCenterY - halfHeight);
733789
clef.setBounds(latestBounds);
734790

735-
if (clef.shape == Shape.C_CLEF) {
736-
// Adjust C_CLEF precise kind
791+
if (kindIsMutable(shape)) {
792+
// Adjust precise kind
737793
final Point2D newCenter = new Point2D.Double(center.getX(), newCenterY);
738794
final ClefKind oldKind = clef.kind;
739795
clef.kind = kindOf(newCenter, clef.shape, staff);

0 commit comments

Comments
 (0)