From ad05a3d113088d11d8aeb0f5d970e5704b43dffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Bitteur?= Date: Wed, 31 Jan 2024 10:55:22 +0100 Subject: [PATCH] Deprecation of fermata-arc and fermata-dot in favor of a full fermata recognition --- .../omr/classifier/AnnotationsBuilder.java | 4 - src/main/org/audiveris/omr/glyph/Shape.java | 17 +- .../org/audiveris/omr/sheet/SystemInfo.java | 60 +++-- .../audiveris/omr/sheet/rhythm/Measure.java | 92 ++++---- .../omr/sheet/symbol/DotFactory.java | 69 ------ .../omr/sheet/symbol/InterFactory.java | 15 +- .../omr/sheet/symbol/SymbolsLinker.java | 30 +-- .../omr/sig/inter/AbstractInter.java | 40 ++-- .../omr/sig/inter/FermataArcInter.java | 62 +----- .../omr/sig/inter/FermataDotInter.java | 41 +--- .../audiveris/omr/sig/inter/FermataInter.java | 205 +++++++----------- .../audiveris/omr/sig/relation/Relations.java | 6 +- .../omr/ui/symbol/BravuraSymbols.java | 3 - .../omr/ui/symbol/FermataArcSymbol.java | 126 ----------- .../omr/ui/symbol/FinaleJazzSymbols.java | 3 - .../omr/ui/symbol/MusicalSymbols.java | 3 - .../org/audiveris/omr/ui/symbol/Symbols.java | 3 - 17 files changed, 191 insertions(+), 588 deletions(-) delete mode 100644 src/main/org/audiveris/omr/ui/symbol/FermataArcSymbol.java diff --git a/src/main/org/audiveris/omr/classifier/AnnotationsBuilder.java b/src/main/org/audiveris/omr/classifier/AnnotationsBuilder.java index c845b2515..097838012 100644 --- a/src/main/org/audiveris/omr/classifier/AnnotationsBuilder.java +++ b/src/main/org/audiveris/omr/classifier/AnnotationsBuilder.java @@ -39,8 +39,6 @@ import org.audiveris.omr.sig.inter.BracketConnectorInter; import org.audiveris.omr.sig.inter.BracketInter; import org.audiveris.omr.sig.inter.EndingInter; -import org.audiveris.omr.sig.inter.FermataArcInter; -import org.audiveris.omr.sig.inter.FermataDotInter; import org.audiveris.omr.sig.inter.HeadChordInter; import org.audiveris.omr.sig.inter.HeadInter; import org.audiveris.omr.sig.inter.Inter; @@ -108,8 +106,6 @@ public class AnnotationsBuilder excludedInterClasses.add(BracketConnectorInter.class); excludedInterClasses.add(BracketInter.class); // TODO: should be defined in OmrShape? excludedInterClasses.add(EndingInter.class); - excludedInterClasses.add(FermataArcInter.class); - excludedInterClasses.add(FermataDotInter.class); excludedInterClasses.add(KeyInter.class); excludedInterClasses.add(RepeatDotInter.class); // Processed via BarlineInter excludedInterClasses.add(SegmentInter.class); diff --git a/src/main/org/audiveris/omr/glyph/Shape.java b/src/main/org/audiveris/omr/glyph/Shape.java index ff4a7a63b..de6b172b9 100644 --- a/src/main/org/audiveris/omr/glyph/Shape.java +++ b/src/main/org/audiveris/omr/glyph/Shape.java @@ -55,7 +55,6 @@ *
  • an augmentation dot (first or second dot), *
  • a part of a repeat sign (upper or lower dot), *
  • a staccato sign, - *
  • a part of fermata sign, *
  • a dot of an ending indication, *
  • a simple text dot. * @@ -102,8 +101,8 @@ public enum Shape CODA("Closing section"), BREATH_MARK("Breath Mark"), CAESURA("Caesura"), - FERMATA_ARC("Fermata arc, without dot"), - FERMATA_ARC_BELOW("Fermata arc below, without dot"), + FERMATA("Fermata arc + dot"), + FERMATA_BELOW("Fermata below, arc + dot"), REPEAT_ONE_BAR("Repeat last bar"), REPEAT_TWO_BARS("Repeat last two bars"), REPEAT_FOUR_BARS("Repeat last four bars"), @@ -336,7 +335,6 @@ public enum Shape // REPEAT_DOT("Repeat dot", DOT_set), AUGMENTATION_DOT("Augmentation Dot", DOT_set), - FERMATA_DOT("Fermata Dot", DOT_set), STACCATO("Staccato dot", DOT_set), // @@ -469,12 +467,6 @@ public enum Shape STEM("Stem"), VERTICAL_SERIF("Vertical serif"), - // - // Full fermatas --- - // - FERMATA("Fermata with dot"), - FERMATA_BELOW("Fermata below with dot"), - // // Other stuff --- // @@ -495,7 +487,10 @@ public enum Shape FLAG_2_UP("OBSOLETE Double flag up"), FLAG_3_UP("OBSOLETE Triple flag up"), FLAG_4_UP("OBSOLETE Quadruple flag up"), - FLAG_5_UP("OBSOLETE Quintuple flag up"); + FLAG_5_UP("OBSOLETE Quintuple flag up"), + FERMATA_DOT("Fermata dot"), + FERMATA_ARC("Fermata arc, without dot"), + FERMATA_ARC_BELOW("Fermata arc below, without dot"); // ============================================================================================= // This is the end of shape enumeration diff --git a/src/main/org/audiveris/omr/sheet/SystemInfo.java b/src/main/org/audiveris/omr/sheet/SystemInfo.java index 479bcee7f..7d224a5de 100644 --- a/src/main/org/audiveris/omr/sheet/SystemInfo.java +++ b/src/main/org/audiveris/omr/sheet/SystemInfo.java @@ -40,6 +40,7 @@ import org.audiveris.omr.sheet.rhythm.MeasureStack; import org.audiveris.omr.sig.SIGraph; import org.audiveris.omr.sig.SigListener; +import org.audiveris.omr.sig.inter.FermataInter; import org.audiveris.omr.sig.inter.Inter; import org.audiveris.omr.sig.inter.LyricLineInter; import org.audiveris.omr.sig.inter.OctaveShiftInter; @@ -325,50 +326,45 @@ public void afterReload () // Process staves upfront, so that their notes have their staff assigned. // Doing so, measure chords can determine which staves they belong to. - for (Staff staff : staves) { - staff.afterReload(); - } + staves.forEach(staff -> staff.afterReload()); - { - // Support for OldStaffBarline - // (In part left PartBarline and in measures PartBarlines) - boolean upgraded = false; + parts.forEach(part -> part.afterReload()); - for (Part part : parts) { - final PartBarline lpb = part.getLeftPartBarline(); + stacks.forEach(stack -> stack.afterReload(this)); - if (lpb != null) { - upgraded |= lpb.upgradeOldStuff(); - } + sig.inters(SentenceInter.class).forEach(inter -> { + ((SentenceInter) inter).assignStaff(this, ((SentenceInter) inter).getLocation()); + }); - for (Measure measure : part.getMeasures()) { - for (PartBarline pb : measure.getContainedPartBarlines()) { - upgraded |= pb.upgradeOldStuff(); - } - } - } + sig.inters(OctaveShiftInter.class).forEach( + inter -> ((OctaveShiftInter) inter).afterReload(this)); - if (upgraded) { - sheet.getStub().setUpgraded(true); - } - } + boolean upgraded = false; + // Support for OldStaffBarline + // (In part left PartBarline and in measures PartBarlines) for (Part part : parts) { - part.afterReload(); - } + final PartBarline lpb = part.getLeftPartBarline(); + + if (lpb != null) { + upgraded |= lpb.upgradeOldStuff(); + } - for (MeasureStack stack : stacks) { - stack.afterReload(this); + for (Measure measure : part.getMeasures()) { + for (PartBarline pb : measure.getContainedPartBarlines()) { + upgraded |= pb.upgradeOldStuff(); + } + } } - for (Inter inter : sig.inters(SentenceInter.class)) { - SentenceInter sentence = (SentenceInter) inter; - sentence.assignStaff(this, sentence.getLocation()); + // Support for old fermata arc and dot + for (Inter inter : sig.inters(FermataInter.class)) { + final FermataInter fermata = (FermataInter) inter; + upgraded |= fermata.upgradeOldStuff(); } - for (Inter inter : sig.inters(OctaveShiftInter.class)) { - OctaveShiftInter os = (OctaveShiftInter) inter; - os.afterReload(this); + if (upgraded) { + sheet.getStub().setUpgraded(true); } // Listen to sig modifications diff --git a/src/main/org/audiveris/omr/sheet/rhythm/Measure.java b/src/main/org/audiveris/omr/sheet/rhythm/Measure.java index f97d11fca..a8991138e 100644 --- a/src/main/org/audiveris/omr/sheet/rhythm/Measure.java +++ b/src/main/org/audiveris/omr/sheet/rhythm/Measure.java @@ -273,6 +273,7 @@ public class Measure /** * No-arg constructor meant for JAXB. */ + @SuppressWarnings("unused") private Measure () { this.part = null; @@ -384,38 +385,34 @@ public void addInter (Inter inter) logger.info("VIP addInter {} into {}", inter, this); } - if (inter instanceof ClefInter clefInter) { - final ClefInter clef = clefInter; + switch (inter) { + case ClefInter clefInter -> { + final ClefInter clef = clefInter; - if (!clefs.contains(clef)) { - clefs.add(clef); + if (!clefs.contains(clef)) { + clefs.add(clef); - if ((clefs.size() > 1) && (clef.getCenter() != null)) { - Collections.sort(clefs, Inters.byFullCenterAbscissa); + if ((clefs.size() > 1) && (clef.getCenter() != null)) { + Collections.sort(clefs, Inters.byFullCenterAbscissa); + } } } - } else if (inter instanceof KeyInter keyInter) { - keys.add(keyInter); - } else if (inter instanceof AbstractTimeInter abstractTimeInter) { - timeSigs.add(abstractTimeInter); - } else if (inter instanceof AbstractChordInter chord) { - chord.setMeasure(this); - - if (chord instanceof HeadChordInter headChordInter) { - headChords.add(headChordInter); - } else if (chord instanceof RestChordInter restChordInter) { - restChords.add(restChordInter); + case KeyInter keyInter -> keys.add(keyInter); + case AbstractTimeInter abstractTimeInter -> timeSigs.add(abstractTimeInter); + case AbstractChordInter chord -> { + chord.setMeasure(this); + + switch (chord) { + case HeadChordInter headChordInter -> headChords.add(headChordInter); + case RestChordInter restChordInter -> restChords.add(restChordInter); + default -> {} + } } - } else if (inter instanceof FlagInter flagInter) { - flags.add(flagInter); - } else if (inter instanceof TupletInter tupletInter) { - tuplets.add(tupletInter); - } else if (inter instanceof AugmentationDotInter augmentationDotInter) { - augDots.add(augmentationDotInter); - } else if (inter instanceof MeasureRepeatInter measureRepeat) { - repeatSigns.add(measureRepeat); - } else { - logger.error("Attempt to use addInter() with {}", inter); + case FlagInter flagInter -> flags.add(flagInter); + case TupletInter tupletInter -> tuplets.add(tupletInter); + case AugmentationDotInter augmentationDotInter -> augDots.add(augmentationDotInter); + case MeasureRepeatInter measureRepeat -> repeatSigns.add(measureRepeat); + default -> logger.error("Attempt to use addInter() with {}", inter); } } @@ -623,7 +620,7 @@ public List filter (Collection inters) private Set filterByStaff (Set inters, Staff staff) { - Set found = new LinkedHashSet<>(); + final Set found = new LinkedHashSet<>(); for (Inter inter : inters) { if (inter.getStaff() == staff) { @@ -1809,28 +1806,23 @@ public void removeInter (Inter inter) logger.info("VIP removeInter {} from {}", inter, this); } - if (inter instanceof ClefInter clefInter) { - clefs.remove(clefInter); - } else if (inter instanceof KeyInter keyInter) { - keys.remove(keyInter); - } else if (inter instanceof AbstractTimeInter abstractTimeInter) { - timeSigs.remove(abstractTimeInter); - } else if (inter instanceof HeadChordInter headChordInter) { - headChords.remove(headChordInter); - removeVoiceChord(headChordInter); - } else if (inter instanceof RestChordInter restChordInter) { - restChords.remove(restChordInter); - removeVoiceChord(restChordInter); - } else if (inter instanceof FlagInter flagInter) { - flags.remove(flagInter); - } else if (inter instanceof TupletInter tupletInter) { - tuplets.remove(tupletInter); - } else if (inter instanceof AugmentationDotInter augmentationDotInter) { - augDots.remove(augmentationDotInter); - } else if (inter instanceof MeasureRepeatInter repeatSign) { - repeatSigns.remove(repeatSign); - } else { - logger.error("Attempt to use removeInter() with {}", inter); + switch (inter) { + case ClefInter clefInter -> clefs.remove(clefInter); + case KeyInter keyInter -> keys.remove(keyInter); + case AbstractTimeInter abstractTimeInter -> timeSigs.remove(abstractTimeInter); + case HeadChordInter headChordInter -> { + headChords.remove(headChordInter); + removeVoiceChord(headChordInter); + } + case RestChordInter restChordInter -> { + restChords.remove(restChordInter); + removeVoiceChord(restChordInter); + } + case FlagInter flagInter -> flags.remove(flagInter); + case TupletInter tupletInter -> tuplets.remove(tupletInter); + case AugmentationDotInter augmentationDotInter -> augDots.remove(augmentationDotInter); + case MeasureRepeatInter repeatSign -> repeatSigns.remove(repeatSign); + default -> logger.error("Attempt to use removeInter() with {}", inter); } } diff --git a/src/main/org/audiveris/omr/sheet/symbol/DotFactory.java b/src/main/org/audiveris/omr/sheet/symbol/DotFactory.java index 7ae690e51..90a9a5a5f 100644 --- a/src/main/org/audiveris/omr/sheet/symbol/DotFactory.java +++ b/src/main/org/audiveris/omr/sheet/symbol/DotFactory.java @@ -41,8 +41,6 @@ import org.audiveris.omr.sig.inter.ArticulationInter; import org.audiveris.omr.sig.inter.AugmentationDotInter; import org.audiveris.omr.sig.inter.BarlineInter; -import org.audiveris.omr.sig.inter.FermataArcInter; -import org.audiveris.omr.sig.inter.FermataDotInter; import org.audiveris.omr.sig.inter.HeadInter; import org.audiveris.omr.sig.inter.Inter; import org.audiveris.omr.sig.inter.Inters; @@ -50,7 +48,6 @@ import org.audiveris.omr.sig.inter.RepeatDotInter; import org.audiveris.omr.sig.inter.StaffBarlineInter; import org.audiveris.omr.sig.relation.AugmentationRelation; -import org.audiveris.omr.sig.relation.DotFermataRelation; import org.audiveris.omr.sig.relation.Link; import org.audiveris.omr.sig.relation.Relation; import org.audiveris.omr.sig.relation.RepeatDotBarRelation; @@ -83,7 +80,6 @@ *
  • a part of a repeat sign (upper or lower dot), *
  • a staccato sign, *
  • an augmentation dot (first or second dot), [TODO: Handle augmentation dot for mirrored notes] - *
  • a part of a fermata sign, *
  • a dot of an ending indication, [TODO: Handle dot in ending] *
  • a simple text dot. [TODO: Anything to be done here?] *
  • or just some stain... @@ -109,8 +105,6 @@ public class DotFactory private final SIGraph sig; - private final Scale scale; - /** Dot candidates. Sorted top down, then left to right. */ private final List dots = new ArrayList<>(); @@ -128,7 +122,6 @@ public DotFactory (InterFactory interFactory, this.interFactory = interFactory; this.system = system; sig = system.getSig(); - scale = system.getSheet().getScale(); } //~ Methods ------------------------------------------------------------------------------------ @@ -608,71 +601,9 @@ public void lateDotChecks () // Run all late checks lateAugmentationChecks(); // Note-Dot and Note-Dot-Dot configurations - lateFermataChecks(); // Dot as part of a fermata sign lateRepeatChecks(); // Dot as part of stack repeat (to say the last word) } - //-------------------// - // lateFermataChecks // - //-------------------// - /** - * Try to include the dot in a fermata symbol. - */ - private void lateFermataChecks () - { - final int profile = system.getProfile(); - - // Collection of fermata arc candidates in the system - List arcs = sig.inters(FermataArcInter.class); - - if (arcs.isEmpty()) { - return; - } - - for (Dot dot : dots) { - Glyph glyph = dot.getGlyph(); - - if (glyph == null) { - continue; - } - - Rectangle dotBox = dot.getBounds(); - FermataDotInter dotInter = null; - - for (Inter arc : arcs) { - // Box: use lower half for FERMATA_ARC and upper half for FERMATA_ARC_BELOW - Rectangle halfBox = arc.getBounds(); - halfBox.height /= 2; - - if (arc.getShape() == Shape.FERMATA_ARC) { - halfBox.y += halfBox.height; - } - - if (halfBox.intersects(dotBox)) { - final Point2D dotCenter = GeoUtil.center2D(dotBox); - double xGap = Math.abs(dotCenter.getX() - (halfBox.x + (halfBox.width / 2))); - double yTarget = (arc.getShape() == Shape.FERMATA_ARC_BELOW) ? (halfBox.y - + (halfBox.height * 0.25)) : (halfBox.y + (halfBox.height * 0.75)); - double yGap = Math.abs(dotCenter.getY() - yTarget); - DotFermataRelation rel = new DotFermataRelation(); - rel.setOutGaps(scale.pixelsToFrac(xGap), scale.pixelsToFrac(yGap), profile); - - if (rel.getGrade() >= rel.getMinGrade()) { - if (dotInter == null) { - double grade = Grades.intrinsicRatio * dot.getGrade(); - dotInter = new FermataDotInter(glyph, grade); - sig.addVertex(dotInter); - logger.debug("Created {}", dotInter); - } - - sig.addEdge(dotInter, arc, rel); - logger.debug("{} matches dot glyph#{}", arc, glyph.getId()); - } - } - } - } - } - //---------------------------// // lateNoteAugmentationCheck // //---------------------------// diff --git a/src/main/org/audiveris/omr/sheet/symbol/InterFactory.java b/src/main/org/audiveris/omr/sheet/symbol/InterFactory.java index 8e777b641..6946aa183 100644 --- a/src/main/org/audiveris/omr/sheet/symbol/InterFactory.java +++ b/src/main/org/audiveris/omr/sheet/symbol/InterFactory.java @@ -54,8 +54,6 @@ import org.audiveris.omr.sig.inter.CompoundNoteInter; import org.audiveris.omr.sig.inter.DynamicsInter; import org.audiveris.omr.sig.inter.EndingInter; -import org.audiveris.omr.sig.inter.FermataArcInter; -import org.audiveris.omr.sig.inter.FermataDotInter; import org.audiveris.omr.sig.inter.FermataInter; import org.audiveris.omr.sig.inter.FingeringInter; import org.audiveris.omr.sig.inter.FlagInter; @@ -231,7 +229,6 @@ public Inter create (Evaluation eval, *
  • Barline *
  • Beam, Beam_hook *
  • Head - *
  • Fermata, Fermata_below (not yet directly handled by OMR engine) *
  • Ledger *
  • Stem *
  • Curve @@ -267,7 +264,6 @@ private Inter doCreate (Evaluation eval, // All dots: // - REPEAT_DOT - // - FERMATA_DOT // - STACCATO_DOT // - AUGMENTATION_DOT case DOT_set: @@ -419,9 +415,9 @@ private Inter doCreate (Evaluation eval, } // Holds - case FERMATA_ARC: - case FERMATA_ARC_BELOW: - return FermataArcInter.create(glyph, shape, grade, system); + case FERMATA: + case FERMATA_BELOW: + return FermataInter.createValidAdded(glyph, shape, grade, system); // Pauses case CAESURA: @@ -1062,10 +1058,7 @@ private static Inter doCreateManual (Shape shape, // Holds case FERMATA: case FERMATA_BELOW: - return new FermataInter(shape, GRADE); // No visit - - case FERMATA_DOT: - return new FermataDotInter(null, GRADE); // No visit + return new FermataInter(null, shape, GRADE); // No visit // Pauses case BREATH_MARK: diff --git a/src/main/org/audiveris/omr/sheet/symbol/SymbolsLinker.java b/src/main/org/audiveris/omr/sheet/symbol/SymbolsLinker.java index 57054ad46..a5950fd19 100644 --- a/src/main/org/audiveris/omr/sheet/symbol/SymbolsLinker.java +++ b/src/main/org/audiveris/omr/sheet/symbol/SymbolsLinker.java @@ -32,8 +32,6 @@ import org.audiveris.omr.sig.inter.BeamGroupInter; import org.audiveris.omr.sig.inter.ChordNameInter; import org.audiveris.omr.sig.inter.DynamicsInter; -import org.audiveris.omr.sig.inter.FermataArcInter; -import org.audiveris.omr.sig.inter.FermataDotInter; import org.audiveris.omr.sig.inter.FermataInter; import org.audiveris.omr.sig.inter.HeadChordInter; import org.audiveris.omr.sig.inter.HeadInter; @@ -50,7 +48,6 @@ import org.audiveris.omr.sig.relation.ChordNameRelation; import org.audiveris.omr.sig.relation.ChordSentenceRelation; import org.audiveris.omr.sig.relation.ChordSyllableRelation; -import org.audiveris.omr.sig.relation.DotFermataRelation; import org.audiveris.omr.sig.relation.EndingSentenceRelation; import org.audiveris.omr.sig.relation.Link; import org.audiveris.omr.sig.relation.Relation; @@ -145,29 +142,12 @@ private void linkDynamics () private void linkFermatas () { final int profile = system.getProfile(); + final List fermatas = sig.inters(FermataInter.class); - // At this point a fermata arc exists only if it is related to a fermata dot - List arcs = sig.inters(FermataArcInter.class); - - for (Inter arcInter : arcs) { - FermataArcInter arc = (FermataArcInter) arcInter; - FermataDotInter dot = null; + for (Inter fInter : fermatas) { + final FermataInter fermata = (FermataInter) fInter; try { - for (Relation rel : sig.getRelations(arc, DotFermataRelation.class)) { - dot = (FermataDotInter) sig.getOppositeInter(arcInter, rel); - - break; - } - - if (dot == null) { - arc.remove(); - - continue; - } - - FermataInter fermata = FermataInter.createAdded(arc, dot, system); - if (fermata.isVip()) { logger.info("VIP linkFermatas on {}", fermata); } @@ -177,11 +157,11 @@ private void linkFermatas () // Look for a chord (head or rest) related to this fermata if (!fermata.linkWithChord(profile)) { // No link to barline, no link to chord, discard it - fermata.remove(); // Which also removes arc and dot members + fermata.remove(); } } } catch (Exception ex) { - logger.warn("Error in linkFermatas for {} {}", arc, ex.toString(), ex); + logger.warn("Error in linkFermatas for {} {}", fermata, ex.toString(), ex); } } } diff --git a/src/main/org/audiveris/omr/sig/inter/AbstractInter.java b/src/main/org/audiveris/omr/sig/inter/AbstractInter.java index b8792c716..5693d5cc0 100644 --- a/src/main/org/audiveris/omr/sig/inter/AbstractInter.java +++ b/src/main/org/audiveris/omr/sig/inter/AbstractInter.java @@ -1272,14 +1272,16 @@ public void remove (boolean extensive) if (sig != null) { // Extensive is true for non-manual removals only if (extensive) { - // Handle ensemble - member cases? - // Copy is needed to avoid concurrent modification exception - List relsCopy = new ArrayList<>(sig.incomingEdgesOf(this)); + // Handle the possible ensemble -> member cases + + // Is this a member of an ensemble? + // If so, delete the ensemble if this is the only remaining member + // NOTA: Copy is needed to avoid concurrent modification exception + final List relsCopy = new ArrayList<>(sig.incomingEdgesOf(this)); for (Relation rel : relsCopy) { - // A member may be contained by several ensembles (case of TimeNumberInter) if (rel instanceof Containment) { - InterEnsemble ens = (InterEnsemble) sig.getEdgeSource(rel); + final InterEnsemble ens = (InterEnsemble) sig.getEdgeSource(rel); if (ens.getMembers().size() == 1) { logger.debug("{} removing a dying ensemble {}", this, ens); @@ -1288,34 +1290,24 @@ public void remove (boolean extensive) } } + // Is this an ensemble of members? + // If so, delete all its members that are not part of another ensemble + // because a member may be contained by several ensembles (e.g. TimeNumberInter) if (this instanceof InterEnsemble ens) { - // Delete all its members that are not part of another ensemble for (Inter member : ens.getMembers()) { - Set ensembles = member.getAllEnsembles(); - - if (!ensembles.isEmpty()) { - ensembles.remove(this); + final Set ensembles = member.getAllEnsembles(); + ensembles.remove(this); - if (ensembles.isEmpty()) { - logger.debug("{} removing a member {}", this, member); - member.remove(false); - } + if (ensembles.isEmpty()) { + logger.debug("{} removing a member {}", this, member); + member.remove(false); } + } } } sig.removeVertex(this); - - // // Make sure the underlying glyph remains accessible - // if (glyph != null) { - // final SystemInfo system = sig.getSystem(); - // final OmrStep step = system.getSheet().getStub().getLatestStep(); - // - // if (step != null && step.compareTo(OmrStep.CURVES) >= 0) { - // system.addFreeGlyph(glyph); - // } - // } } } diff --git a/src/main/org/audiveris/omr/sig/inter/FermataArcInter.java b/src/main/org/audiveris/omr/sig/inter/FermataArcInter.java index fea340cde..dc59d0ef3 100644 --- a/src/main/org/audiveris/omr/sig/inter/FermataArcInter.java +++ b/src/main/org/audiveris/omr/sig/inter/FermataArcInter.java @@ -21,12 +21,7 @@ // package org.audiveris.omr.sig.inter; -import org.audiveris.omr.glyph.Glyph; -import org.audiveris.omr.glyph.Shape; -import org.audiveris.omr.sheet.Staff; -import org.audiveris.omr.sheet.SystemInfo; - -import java.awt.geom.Point2D; +import org.audiveris.omr.sheet.symbol.SymbolsBuilder; import javax.xml.bind.annotation.XmlRootElement; @@ -34,10 +29,14 @@ * Class FermataArcInter represents the arc part of a fermata, either upright or * inverted. *

    - * Combined with a FermataDotInter, it can lead to a (full) FermataInter. + * Combined with a FermataDotInter, it could lead to a (full) FermataInter. + *

    + * This class is now deprecated, since the full {@link FermataInter} can be directly recognized + * by the {@link SymbolsBuilder}. * * @author Hervé Bitteur */ +@Deprecated @XmlRootElement(name = "fermata-arc") public class FermataArcInter extends AbstractInter @@ -47,55 +46,8 @@ public class FermataArcInter /** * No-arg constructor meant for JAXB. */ + @SuppressWarnings("unused") private FermataArcInter () { } - - /** - * Creates a new FermataArcInter object. - * - * @param glyph the fermata arc glyph - * @param shape FERMATA_ARC or FERMATA_ARC_BELOW - * @param grade the interpretation quality - */ - private FermataArcInter (Glyph glyph, - Shape shape, - Double grade) - { - super(glyph, glyph.getBounds(), shape, grade); - } - - //~ Static Methods ----------------------------------------------------------------------------- - - //--------// - // create // - //--------// - /** - * (Try to) create a fermata arc inter. - * - * @param glyph the fermata arc glyph - * @param shape FERMATA_ARC or FERMATA_ARC_BELOW - * @param grade the interpretation quality - * @param system the related system - * @return the created fermata arc or null - */ - public static FermataArcInter create (Glyph glyph, - Shape shape, - double grade, - SystemInfo system) - { - // Look for proper staff - final Point2D center = glyph.getCenter2D(); - final Staff staff = (shape == Shape.FERMATA_ARC) ? system.getStaffAtOrBelow(center) - : system.getStaffAtOrAbove(center); - - if (staff == null) { - return null; - } - - final FermataArcInter arc = new FermataArcInter(glyph, shape, grade); - arc.setStaff(staff); - - return arc; - } } diff --git a/src/main/org/audiveris/omr/sig/inter/FermataDotInter.java b/src/main/org/audiveris/omr/sig/inter/FermataDotInter.java index e0225b34b..d5a0b19d7 100644 --- a/src/main/org/audiveris/omr/sig/inter/FermataDotInter.java +++ b/src/main/org/audiveris/omr/sig/inter/FermataDotInter.java @@ -21,9 +21,7 @@ // package org.audiveris.omr.sig.inter; -import org.audiveris.omr.glyph.Glyph; -import org.audiveris.omr.glyph.Shape; -import org.audiveris.omr.sheet.Staff; +import org.audiveris.omr.sheet.symbol.SymbolsBuilder; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -31,9 +29,13 @@ /** * Class FermataDotInter represents a dot in a fermata symbol. + *

    + * This class is now deprecated, since the full {@link FermataInter} can be directly recognized + * by the {@link SymbolsBuilder}. * * @author Hervé Bitteur */ +@Deprecated @XmlAccessorType(XmlAccessType.NONE) @XmlRootElement(name = "fermata-dot") public class FermataDotInter @@ -44,39 +46,8 @@ public class FermataDotInter /** * No-arg constructor meant for JAXB. */ + @SuppressWarnings("unused") private FermataDotInter () { } - - /** - * Creates a new FermataDotInter object. - * - * @param glyph underlying glyph - * @param grade evaluation value - */ - public FermataDotInter (Glyph glyph, - Double grade) - { - super(glyph, null, Shape.FERMATA_DOT, grade); - } - - //~ Methods ------------------------------------------------------------------------------------ - - //----------// - // getStaff // - //----------// - @Override - public Staff getStaff () - { - if (staff == null) { - // Use staff information of containing FermataInter ensemble - InterEnsemble ens = getEnsemble(); - - if (ens != null) { - staff = ens.getStaff(); - } - } - - return staff; - } } diff --git a/src/main/org/audiveris/omr/sig/inter/FermataInter.java b/src/main/org/audiveris/omr/sig/inter/FermataInter.java index 59857bec9..f24c1b804 100644 --- a/src/main/org/audiveris/omr/sig/inter/FermataInter.java +++ b/src/main/org/audiveris/omr/sig/inter/FermataInter.java @@ -22,26 +22,30 @@ package org.audiveris.omr.sig.inter; import org.audiveris.omr.constant.ConstantSet; +import org.audiveris.omr.glyph.Glyph; +import org.audiveris.omr.glyph.GlyphFactory; +import org.audiveris.omr.glyph.GlyphIndex; import org.audiveris.omr.glyph.Shape; import org.audiveris.omr.math.GeoUtil; import org.audiveris.omr.sheet.Scale; import org.audiveris.omr.sheet.Staff; import org.audiveris.omr.sheet.SystemInfo; import org.audiveris.omr.sheet.rhythm.MeasureStack; +import org.audiveris.omr.sheet.symbol.SymbolsBuilder; +import org.audiveris.omr.sig.relation.Containment; import org.audiveris.omr.sig.relation.FermataBarRelation; import org.audiveris.omr.sig.relation.FermataChordRelation; import org.audiveris.omr.sig.relation.Link; -import org.audiveris.omr.util.Entities; +import org.audiveris.omr.sig.relation.Relation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.awt.Point; -import java.awt.Rectangle; import java.awt.geom.Point2D; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.List; import javax.xml.bind.annotation.XmlRootElement; @@ -59,13 +63,16 @@ * A fermata may also refer to a single or double barline, to indicate the end of a phrase. *

    * Such reference is implemented via a Relation instance. + *

    + * Initially, the fermata arc and the fermata dot were kept as separated inters because they were + * often too distant to be grabbed by the {@link SymbolsBuilder}. + * Since the SymbolsBuilder now accepts larger gaps, there is no more need for these member inters. * * @author Hervé Bitteur */ @XmlRootElement(name = "fermata") public class FermataInter extends AbstractInter - implements InterEnsemble { //~ Static fields/initializers ----------------------------------------------------------------- @@ -73,16 +80,12 @@ public class FermataInter private static final Logger logger = LoggerFactory.getLogger(FermataInter.class); - // Arc then dot - private static Comparator byFermataOrder = (o1, - o2) -> (o1 instanceof FermataArcInter) ? (-1) - : (+1); - //~ Constructors ------------------------------------------------------------------------------- /** * No-arg constructor meant for JAXB. */ + @SuppressWarnings("unused") private FermataInter () { } @@ -90,117 +93,77 @@ private FermataInter () /** * Creates a new FermataInter object. * + * @param glyph the fermata glypg (arc + dot) * @param shape the fermata shape (FERMATA or FERMATA_BELOW) * @param grade the interpretation quality */ - public FermataInter (Shape shape, + public FermataInter (Glyph glyph, + Shape shape, Double grade) { - super(null, null, shape, grade); + super(glyph, glyph.getBounds(), shape, grade); } //~ Methods ------------------------------------------------------------------------------------ - //-----------// - // addMember // - //-----------// - @Override - public void addMember (Inter member) - { - if (member instanceof FermataArcInter) { - FermataArcInter arc = getArc(); - - if (arc != null) { - throw new IllegalStateException("Arc already defined"); - } - - EnsembleHelper.addMember(this, member); - } - - if (member instanceof FermataDotInter) { - FermataDotInter dot = getDot(); - - if (dot != null) { - throw new IllegalStateException("Dot already defined"); - } - - EnsembleHelper.addMember(this, member); - } - } - - //--------// - // getArc // - //--------// + //-----------------// + // upgradeOldStuff // + //-----------------// /** - * Report the arc part. + * Convert old fermata based on arc + dot ensemble. + *

    + * Since the (new) FermataInter is no longer an ensemble, we deal with Containment relations + * and former members directly. * - * @return the arc + * @return true if really upgraded */ - public FermataArcInter getArc () + @SuppressWarnings("deprecation") + public boolean upgradeOldStuff () { - final List members = getMembers(); - - for (Inter member : members) { - if (member instanceof FermataArcInter) { - return (FermataArcInter) member; + try { + Relation arcRel = null; + Relation dotRel = null; + FermataArcInter arc = null; + FermataDotInter dot = null; + + for (Relation rel : sig.getRelations(this, Containment.class)) { + if (sig.getEdgeSource(rel) == this) { + final Inter member = sig.getOppositeInter(this, rel); + switch (member) { + case FermataArcInter fermataArcInter -> { + arc = fermataArcInter; + arcRel = rel; + } + case FermataDotInter fermataDotInter -> { + dot = fermataDotInter; + dotRel = rel; + } + default -> {} + } + } } - } - return null; - } + if ((arc != null) && (dot != null)) { + final GlyphIndex index = sig.getSystem().getSheet().getGlyphIndex(); + glyph = index.registerOriginal( + GlyphFactory.buildGlyph(Arrays.asList(arc.getGlyph(), dot.getGlyph()))); + bounds = glyph.getBounds(); - //-----------// - // getBounds // - //-----------// - @Override - public Rectangle getBounds () - { - if (bounds == null) { - bounds = Entities.getBounds(getMembers()); - } + // Cut the containment relations to preserve fermata inter + sig.removeEdge(arcRel); + sig.removeEdge(dotRel); - return super.getBounds(); - } + // Remove the former members + arc.remove(); + dot.remove(); - //--------// - // getDot // - //--------// - /** - * Report the dot part. - * - * @return the dot - */ - public FermataDotInter getDot () - { - final List members = getMembers(); - - for (Inter member : members) { - if (member instanceof FermataDotInter) { - return (FermataDotInter) member; + return true; } + } catch (Exception ex) { + logger.warn("Error in " + getClass() + " upgradeOldStuff() " + ex, ex); } - return null; - } - - //------------// - // getMembers // - //------------// - @Override - public List getMembers () - { - return EnsembleHelper.getMembers(this, byFermataOrder); - } - - //-----------------// - // invalidateCache // - //-----------------// - @Override - public void invalidateCache () - { - bounds = null; - - setGrade(EnsembleHelper.computeMeanContextualGrade(this)); + return false; } //-----------------// @@ -362,20 +325,6 @@ private Link lookupChordLink (SystemInfo system, return new Link(chord, new FermataChordRelation(), true); } - //--------------// - // removeMember // - //--------------// - @Override - public void removeMember (Inter member) - { - if (!(member instanceof FermataArcInter) && !(member instanceof FermataDotInter)) { - throw new IllegalArgumentException( - "Only FermataArcInter or FermataDotInter can be removed from FermataInter"); - } - - EnsembleHelper.removeMember(this, member); - } - //-------------// // searchLinks // //-------------// @@ -405,37 +354,35 @@ public Collection searchUnlinks (SystemInfo system, //~ Static Methods ----------------------------------------------------------------------------- - //-------------// - // createAdded // - //-------------// + //------------------// + // createValidAdded // + //------------------// /** - * (Try to) create a fermata inter. + * (Try to) create and add a valid fermata inter. * - * @param arc the fermata arc (shape: FERMATA_ARC or FERMATA_ARC_BELOW) - * @param dot the fermata dot + * @param glyph the fermata glyph (arc + dot) + * @param shape FERMATA or FERMATA_BELOW + * @param grade the interpretation quality * @param system the related system * @return the created instance or null */ - public static FermataInter createAdded (FermataArcInter arc, - FermataDotInter dot, - SystemInfo system) + public static FermataInter createValidAdded (Glyph glyph, + Shape shape, + double grade, + SystemInfo system) { // Look for proper staff - final Point2D center = arc.getGlyph().getCenter2D(); - final Shape arcShape = arc.getShape(); - final Staff staff = (arcShape == Shape.FERMATA_ARC) ? system.getStaffAtOrBelow(center) + final Point2D center = glyph.getCenter2D(); + final Staff staff = (shape == Shape.FERMATA) ? system.getStaffAtOrBelow(center) : system.getStaffAtOrAbove(center); if (staff == null) { return null; } - final Shape shape = (arcShape == Shape.FERMATA_ARC) ? Shape.FERMATA : Shape.FERMATA_BELOW; - final FermataInter fermata = new FermataInter(shape, null); + final FermataInter fermata = new FermataInter(glyph, shape, grade); fermata.setStaff(staff); staff.getSystem().getSig().addVertex(fermata); - fermata.addMember(arc); - fermata.addMember(dot); return fermata; } diff --git a/src/main/org/audiveris/omr/sig/relation/Relations.java b/src/main/org/audiveris/omr/sig/relation/Relations.java index 431491396..9372af10f 100644 --- a/src/main/org/audiveris/omr/sig/relation/Relations.java +++ b/src/main/org/audiveris/omr/sig/relation/Relations.java @@ -25,6 +25,7 @@ import org.audiveris.omr.sig.inter.AbstractBeamInter; import org.audiveris.omr.sig.inter.AbstractChordInter; import org.audiveris.omr.sig.inter.AbstractNoteInter; +import org.audiveris.omr.sig.inter.AbstractPauseInter; import org.audiveris.omr.sig.inter.AlterInter; import org.audiveris.omr.sig.inter.ArpeggiatoInter; import org.audiveris.omr.sig.inter.ArticulationInter; @@ -34,8 +35,6 @@ import org.audiveris.omr.sig.inter.ChordNameInter; import org.audiveris.omr.sig.inter.DynamicsInter; import org.audiveris.omr.sig.inter.EndingInter; -import org.audiveris.omr.sig.inter.FermataArcInter; -import org.audiveris.omr.sig.inter.FermataDotInter; import org.audiveris.omr.sig.inter.FermataInter; import org.audiveris.omr.sig.inter.FingeringInter; import org.audiveris.omr.sig.inter.FlagInter; @@ -49,7 +48,6 @@ import org.audiveris.omr.sig.inter.MeasureRepeatInter; import org.audiveris.omr.sig.inter.MultipleRestInter; import org.audiveris.omr.sig.inter.OrnamentInter; -import org.audiveris.omr.sig.inter.AbstractPauseInter; import org.audiveris.omr.sig.inter.PedalInter; import org.audiveris.omr.sig.inter.PlayingInter; import org.audiveris.omr.sig.inter.PluckingInter; @@ -148,8 +146,6 @@ private static void buildMaps () map(EndingInter.class, EndingBarRelation.class, StaffBarlineInter.class); map(EndingInter.class, EndingSentenceRelation.class, SentenceInter.class); - map(FermataDotInter.class, DotFermataRelation.class, FermataArcInter.class); // Temporary! - map(FermataInter.class, FermataBarRelation.class, BarlineInter.class); // Old map(FermataInter.class, FermataBarRelation.class, StaffBarlineInter.class); map(FermataInter.class, FermataChordRelation.class, AbstractChordInter.class); diff --git a/src/main/org/audiveris/omr/ui/symbol/BravuraSymbols.java b/src/main/org/audiveris/omr/ui/symbol/BravuraSymbols.java index 35281f8bb..b23f4ab8d 100644 --- a/src/main/org/audiveris/omr/ui/symbol/BravuraSymbols.java +++ b/src/main/org/audiveris/omr/ui/symbol/BravuraSymbols.java @@ -102,10 +102,7 @@ public int[] getCode (Shape shape) case EIGHTH_REST -> ints(0xE4E6); case FERMATA -> ints(0xE4C0); - case FERMATA_ARC -> ints(0xE4C0); - case FERMATA_ARC_BELOW -> ints(0xE4C1); case FERMATA_BELOW -> ints(0xE4C1); - case FERMATA_DOT -> ints(0xE044); case FINAL_BARLINE -> ints(0xE032); case FLAG_1 -> ints(0xE240); case FLAG_1_DOWN -> ints(0xE241); diff --git a/src/main/org/audiveris/omr/ui/symbol/FermataArcSymbol.java b/src/main/org/audiveris/omr/ui/symbol/FermataArcSymbol.java deleted file mode 100644 index cc2112bf1..000000000 --- a/src/main/org/audiveris/omr/ui/symbol/FermataArcSymbol.java +++ /dev/null @@ -1,126 +0,0 @@ -//------------------------------------------------------------------------------------------------// -// // -// F e r m a t a A r c S y m b o l // -// // -//------------------------------------------------------------------------------------------------// -// -// -// Copyright © Audiveris 2024. All rights reserved. -// -// This program is free software: you can redistribute it and/or modify it under the terms of the -// GNU Affero General Public License as published by the Free Software Foundation, either version -// 3 of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -// See the GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License along with this -// program. If not, see . -//------------------------------------------------------------------------------------------------// -// -package org.audiveris.omr.ui.symbol; - -import org.audiveris.omr.glyph.Shape; -import static org.audiveris.omr.ui.symbol.Alignment.BOTTOM_CENTER; -import static org.audiveris.omr.ui.symbol.Alignment.TOP_CENTER; - -import java.awt.Color; -import java.awt.Composite; -import java.awt.Graphics2D; -import java.awt.font.TextLayout; -import java.awt.geom.Point2D; - -/** - * Class FermataArcSymbol implements Fermata Arc symbols with the related dot - * as decoration. - *

    - * Purpose of this symbol is to allow the glyph classifier to recognize fermata arc and fermata dot - * as two separate entities (they lie too far apart for the glyph classifier to be considered as - * a single symbol candidate). - * - * @author Hervé Bitteur - */ -public class FermataArcSymbol - extends DecorableSymbol -{ - //~ Constructors ------------------------------------------------------------------------------- - - /** - * Create a FermataArcSymbol standard size with no decoration. - * - * @param shape the precise shape - * @param family the musicFont family - */ - public FermataArcSymbol (Shape shape, - MusicFamily family) - { - super(shape, family); - } - - //~ Methods ------------------------------------------------------------------------------------ - - //-----------// - // getParams // - //-----------// - @Override - protected MyParams getParams (MusicFont font) - { - MyParams p = new MyParams(); - - // Full symbol (arc + dot) - p.layout = font.layoutShapeByCode(shape); - p.rect = p.layout.getBounds(); - - // Dot layout - p.dotLayout = font.layoutShapeByCode(Shape.DOT_set); - - return p; - } - - //-------// - // paint // - //-------// - @Override - protected void paint (Graphics2D g, - Params params, - Point2D location, - Alignment alignment) - { - // We paint the full fermata symbol first - // Then we paint a dot using white or decoComposite - MyParams p = (MyParams) params; - Alignment align = (shape == Shape.FERMATA_ARC) ? BOTTOM_CENTER : TOP_CENTER; - Point2D loc = alignment.translatedPoint(align, p.rect, location); - - MusicFont.paint(g, p.layout, loc, align); // Arc + Dot - - if (isDecorated) { - // Paint dot in gray - Composite oldComposite = g.getComposite(); - g.setComposite(decoComposite); - MusicFont.paint(g, p.dotLayout, loc, align); - g.setComposite(oldComposite); - } else { - // Erase dot using white color (?) - Color oldColor = g.getColor(); - g.setColor(Color.WHITE); - MusicFont.paint(g, p.dotLayout, loc, align); - g.setColor(oldColor); - } - } - - //~ Inner Classes ------------------------------------------------------------------------------ - - //--------// - // Params // - //--------// - protected static class MyParams - extends Params - { - - // layout for full fermata - // rect for full fermata - TextLayout dotLayout; // For the dot - } -} diff --git a/src/main/org/audiveris/omr/ui/symbol/FinaleJazzSymbols.java b/src/main/org/audiveris/omr/ui/symbol/FinaleJazzSymbols.java index ad2b36fb8..68f537d0e 100644 --- a/src/main/org/audiveris/omr/ui/symbol/FinaleJazzSymbols.java +++ b/src/main/org/audiveris/omr/ui/symbol/FinaleJazzSymbols.java @@ -110,10 +110,7 @@ public int[] getCode (Shape shape) case EIGHTH_REST -> ints(0xE4E6); case FERMATA -> ints(0xE4C0); - case FERMATA_ARC -> ints(0xE4C0); - case FERMATA_ARC_BELOW -> ints(0xE4C1); case FERMATA_BELOW -> ints(0xE4C1); - case FERMATA_DOT -> ints(0xE044); // ? useful ? ///case FINAL_BARLINE -> ints(0xE032); case FLAG_1 -> ints(0xE250); case FLAG_1_DOWN -> ints(0xE251); diff --git a/src/main/org/audiveris/omr/ui/symbol/MusicalSymbols.java b/src/main/org/audiveris/omr/ui/symbol/MusicalSymbols.java index dab98100f..ae1bf73ff 100644 --- a/src/main/org/audiveris/omr/ui/symbol/MusicalSymbols.java +++ b/src/main/org/audiveris/omr/ui/symbol/MusicalSymbols.java @@ -100,10 +100,7 @@ public int[] getCode (Shape shape) case EIGHTH_REST -> ints(0xF0E4); case FERMATA -> ints(0xF055); - case FERMATA_ARC -> ints(0xF055); - case FERMATA_ARC_BELOW -> ints(0xF075); case FERMATA_BELOW -> ints(0xF075); - case FERMATA_DOT -> ints(0xF02E); case FINAL_BARLINE -> ints(0xF0D3); case FLAG_1 -> ints(0xF06A); case FLAG_1_DOWN -> ints(0xF04A); diff --git a/src/main/org/audiveris/omr/ui/symbol/Symbols.java b/src/main/org/audiveris/omr/ui/symbol/Symbols.java index a1bf105bc..c3520c338 100644 --- a/src/main/org/audiveris/omr/ui/symbol/Symbols.java +++ b/src/main/org/audiveris/omr/ui/symbol/Symbols.java @@ -230,9 +230,6 @@ protected void populateSymbols () symbolMap.put(BEAM_SMALL, new SmallBeamSymbol(family())); symbolMap.put(BEAM_HOOK, new BeamHookSymbol(family())); - symbolMap.put(FERMATA_ARC, new FermataArcSymbol(FERMATA_ARC, family())); - symbolMap.put(FERMATA_ARC_BELOW, new FermataArcSymbol(FERMATA_ARC_BELOW, family())); - symbolMap.put(LEDGER, new LedgerSymbol(family())); symbolMap.put(OTTAVA, new OctaveShiftSymbol(OTTAVA, family()));