//----------------------------------------------------------------------------//
// //
// A r t i c u l a t i o n //
// //
//----------------------------------------------------------------------------//
// <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.entity;
import omr.constant.ConstantSet;
import omr.glyph.Evaluation;
import omr.glyph.facets.Glyph;
import omr.score.visitor.ScoreVisitor;
import omr.sheet.Scale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.Point;
/**
* Class {@code Articulation} represents an articulation event, a
* special notation.
* This should apply to:
* <pre>
* accent standard
* strong-accent standard
* staccato standard
* tenuto standard
* detached-legato nyi
* staccatissimo standard
* spiccato nyi
* scoop nyi
* plop nyi
* doit nyi
* falloff nyi
* breath-mark nyi ???
* caesura nyi ???
* stress nyi
* unstress nyi
* other-articulation nyi
* </pre>
*
* @author Hervé Bitteur
*/
public class Articulation
extends AbstractNotation
{
//~ Static fields/initializers ---------------------------------------------
/** Specific application parameters */
private static final Constants constants = new Constants();
/** Usual logger utility */
private static final Logger logger = LoggerFactory.getLogger(
Articulation.class);
//~ Constructors -----------------------------------------------------------
//--------------//
// Articulation //
//--------------//
/**
* Creates a new instance of Articulation event
*
* @param measure measure that contains this mark
* @param point location of mark
* @param chord the chord related to the mark
* @param glyph the underlying glyph
*/
public Articulation (Measure measure,
Point point,
Chord chord,
Glyph glyph)
{
super(measure, point, chord, glyph);
}
//~ Methods ----------------------------------------------------------------
//--------//
// accept //
//--------//
@Override
public boolean accept (ScoreVisitor visitor)
{
return visitor.visit(this);
}
//----------//
// populate //
//----------//
/**
* Used by SystemTranslator
*
* @param glyph underlying glyph
* @param measure measure where the mark is located
* @param point location for the mark
*/
public static void populate (Glyph glyph,
Measure measure,
Point point)
{
if (glyph.isVip()) {
logger.info("Articulation. populate {}", glyph.idString());
}
// An Articulation relates to the note below or above on the same time slot
Chord chord = measure.getEventChord(point);
if (chord != null) {
// Check vertical distance between chord and articulation
Point head = chord.getHeadLocation();
Point tail = chord.getTailLocation();
int dy = Math.min(
Math.abs(head.y - point.y),
Math.abs(tail.y - point.y));
double normedDy = measure.getScale()
.pixelsToFrac(dy);
if (normedDy <= constants.maxArticulationDy.getValue()) {
glyph.setTranslation(
new Articulation(measure, point, chord, glyph));
if (glyph.isVip() || logger.isDebugEnabled()) {
logger.info("Translated articulation {}", glyph.idString());
}
return;
}
}
// Incorrect articulation
if (glyph.isVip() || logger.isDebugEnabled()) {
logger.info(
"No chord close enough to articulation {}",
glyph.idString());
}
glyph.setShape(null, Evaluation.ALGORITHM);
}
//~ Inner Classes ----------------------------------------------------------
//-----------//
// Constants //
//-----------//
private static final class Constants
extends ConstantSet
{
//~ Instance fields ----------------------------------------------------
/**
* Maximum dy between articulation and chord
*/
Scale.Fraction maxArticulationDy = new Scale.Fraction(
4,
"Maximum dy between articulation and chord");
}
}