//----------------------------------------------------------------------------// // // // S c o r e R e d u c t o r // // // //----------------------------------------------------------------------------// // <editor-fold defaultstate="collapsed" desc="hdr"> // // Copyright © Hervé Bitteur and others 2000-2013. All rights reserved. // // This software is released under the GNU General Public License. // // Goto http://kenai.com/projects/audiveris to report bugs or suggestions. // //----------------------------------------------------------------------------// // </editor-fold> package omr.score; import omr.math.Rational; import omr.score.entity.Chord; import omr.score.entity.TimeSignature.InvalidTimeSignature; import omr.score.visitor.AbstractScoreVisitor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Arrays; import java.util.SortedSet; import java.util.TreeSet; /** * Class {@code ScoreReductor} can visit the score hierarchy to simplify * all duration values. * * @author Hervé Bitteur */ public class ScoreReductor extends AbstractScoreVisitor { //~ Static fields/initializers --------------------------------------------- /** Usual logger utility */ private static final Logger logger = LoggerFactory.getLogger(ScoreReductor.class); //~ Instance fields -------------------------------------------------------- /** Set of all different duration values */ private final SortedSet<Rational> durations = new TreeSet<>(); //~ Constructors ----------------------------------------------------------- //---------------// // ScoreReductor // //---------------// /** * Creates a new ScoreReductor object. */ public ScoreReductor () { } //~ Methods ---------------------------------------------------------------- //-------------// // visit Chord // //-------------// @Override public boolean visit (Chord chord) { Rational duration; try { // Special case for whole chords if (chord.isWholeDuration()) { duration = chord.getMeasure().getExpectedDuration(); } else { duration = chord.getDuration(); } if (duration != null) { durations.add(duration); } } catch (InvalidTimeSignature ex) { // Ignored here (TBC) } catch (Exception ex) { logger.warn( getClass().getSimpleName() + " Error visiting " + chord, ex); } return false; } //-------------// // visit Score // //-------------// @Override public boolean visit (Score score) { try { // Collect duration values for each part score.acceptChildren(this); // Compute and remember greatest duration divisor for the score score.setDurationDivisor(computeDurationDivisor()); } catch (Exception ex) { logger.warn( getClass().getSimpleName() + " Error visiting " + score, ex); } return false; } //------------------------// // computeDurationDivisor // //------------------------// private int computeDurationDivisor () { Rational[] durationArray = durations.toArray( new Rational[durations.size()]); Rational divisor = Rational.gcd(durationArray); logger.debug("durations={} divisor={}", Arrays.deepToString(durationArray), divisor); return divisor.den; } }