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