Search in sources :

Example 16 with Chord

use of com.xenoage.zong.core.music.chord.Chord in project Zong by Xenoage.

the class ChordStamper method stampCore.

/**
 * Draws the given chord, including noteheads, stem, flags, accidentals, dots,
 * articulations and leger lines.
 */
public ChordStampings stampCore(ChordNotation chord, float chordXMm, StamperContext context) {
    val staff = context.getCurrentStaffStamping();
    Chord element = chord.element;
    boolean grace = element.isGrace();
    LayoutSettings settings = context.getSettings();
    float scaling = (grace ? settings.scalingGrace : 1);
    ChordWidths chordWidths = (grace ? settings.graceChordWidths : settings.chordWidths);
    float leftNoteXMm = getLeftNoteXMm(chordXMm, chord.notes, staff.is);
    // stem
    StemStamping stem = stampStem(chord, leftNoteXMm, context);
    // type of notehead
    CommonSymbol noteheadSymbol = CommonSymbol.NoteWhole;
    Duration.Type symbolType = Duration.INSTANCE.getNoteheadSymbolType(element.getDisplayedDuration());
    if (symbolType == Duration.INSTANCE.Type.Half)
        noteheadSymbol = CommonSymbol.NoteHalf;
    else if (symbolType == Duration.INSTANCE.Type.Quarter)
        noteheadSymbol = CommonSymbol.NoteQuarter;
    // noteheads
    NotesNotation notes = chord.notes;
    NoteheadStamping[] noteheads = new NoteheadStamping[notes.getNotesCount()];
    for (int iNote : range(noteheads)) {
        NoteDisplacement note = notes.getNote(iNote);
        Symbol noteSymbol = context.getSymbol(noteheadSymbol);
        float noteXMm = getNoteheadXMm(leftNoteXMm + note.xIs * staff.is, scaling, staff, noteSymbol);
        NoteheadStamping noteSt = new NoteheadStamping(chord, iNote, noteSymbol, Color.Companion.getBlack(), staff, sp(noteXMm, note.lp), scaling);
        noteheads[iNote] = noteSt;
    }
    // flags (only drawn if there is no beam)
    int flagsCount = Duration.INSTANCE.getFlagsCount(element.getDisplayedDuration());
    Beam beam = element.getBeam();
    StemDirection stemDir = chord.stemDirection;
    FlagsStamping flags = null;
    if (beam == null && flagsCount > 0 && chord.stem != null) /* can happen when no stem is used */
    {
        FlagsStamping.FlagsDirection flag = (stemDir == StemDirection.Up ? FlagsStamping.FlagsDirection.Down : FlagsStamping.FlagsDirection.Up);
        Symbol flagSymbol = context.getSymbol(CommonSymbol.NoteFlag);
        flags = new FlagsStamping(chord, staff, flag, flagsCount, flagSymbol, scaling, sp(leftNoteXMm + notes.stemOffsetIs * staff.is, chord.stem.endSlp.lp));
    }
    // accidentals
    AccidentalsNotation accs = chord.accidentals;
    AccidentalStamping[] accsSt = new AccidentalStamping[0];
    if (accs != null) {
        accsSt = new AccidentalStamping[accs.accidentals.length];
        for (int iAcc : range(accsSt)) {
            AccidentalDisplacement acc = accs.accidentals[iAcc];
            AccidentalStamping accSt = new AccidentalStamping(chord, iAcc, staff, sp(chordXMm + (acc.xIs - chord.width.frontGap + 0.5f) * staff.is, acc.yLp), 1, context.getSymbol(CommonSymbol.getAccidental(acc.accidental)));
            accsSt[iAcc] = accSt;
        }
    }
    // dots
    int[] dotPositions = notes.dotsLp;
    int dotsPerNote = notes.getDotsPerNoteCount();
    ProlongationDotStamping[] dots = new ProlongationDotStamping[dotPositions.length * dotsPerNote];
    Symbol dotSymbol = context.getSymbol(CommonSymbol.NoteDot);
    for (int iNote : range(dotPositions)) {
        for (int iDot : range(dotsPerNote)) {
            ProlongationDotStamping dotSt = new ProlongationDotStamping(chord, staff, dotSymbol, sp(leftNoteXMm + notes.getDotsOffsetIs(iDot) * staff.is, dotPositions[iNote]));
            dots[iNote * dotsPerNote + iDot] = dotSt;
        }
    }
    // articulations
    ArticulationsNotation arts = chord.articulations;
    ArticulationStamping[] artsSt = new ArticulationStamping[0];
    if (arts != null) {
        artsSt = new ArticulationStamping[arts.articulations.length];
        float noteheadWidth = chordWidths.get(element.getDuration());
        for (int iArt : range(artsSt)) {
            ArticulationDisplacement art = arts.articulations[iArt];
            ArticulationStamping artSt = new ArticulationStamping(chord, iArt, staff, sp(leftNoteXMm + (art.xIs + (noteheadWidth / 2)) * staff.is, art.yLp), 1, context.getSymbol(CommonSymbol.getArticulation(art.articulation)));
            artsSt[iArt] = artSt;
        }
    }
    // leger lines
    LegerLineStamping[] legerLines = legerLinesStamper.stamp(chord, chordXMm, staff);
    return new ChordStampings(element, chordXMm, staff, noteheads, dots, accsSt, legerLines, artsSt, flags, stem);
}
Also used : LayoutSettings(com.xenoage.zong.musiclayout.settings.LayoutSettings) CommonSymbol(com.xenoage.zong.symbols.common.CommonSymbol) Symbol(com.xenoage.zong.symbols.Symbol) Beam(com.xenoage.zong.core.music.beam.Beam) Chord(com.xenoage.zong.core.music.chord.Chord) CommonSymbol(com.xenoage.zong.symbols.common.CommonSymbol) StemDirection(com.xenoage.zong.core.music.chord.StemDirection) ChordStampings(com.xenoage.zong.musiclayout.layouter.scoreframelayout.util.ChordStampings) lombok.val(lombok.val) Duration(com.xenoage.zong.core.music.util.Duration) SlurWaypoint(com.xenoage.zong.core.music.slur.SlurWaypoint) ChordWidths(com.xenoage.zong.musiclayout.settings.ChordWidths)

Example 17 with Chord

use of com.xenoage.zong.core.music.chord.Chord in project Zong by Xenoage.

the class DirectionStamper method stampForChord.

/**
 * Creates the {@link StaffTextStamping}s for the {@link Direction}s of
 * the given {@link ChordStampings}.
 */
public List<StaffTextStamping> stampForChord(ChordStampings chordStampings, SymbolPool symbolPool) {
    Chord chord = chordStampings.chord;
    int directionsCount = chord.getDirections().size();
    if (directionsCount == 0)
        return emptyList();
    List<StaffTextStamping> ret = alist();
    for (Direction direction : chord.getDirections()) {
        if (direction instanceof Dynamic) {
            ret.add(createDynamics((Dynamic) direction, chord, chordStampings, symbolPool));
        }
    // TODO: support more directions
    }
    return ret;
}
Also used : StaffTextStamping(com.xenoage.zong.musiclayout.stampings.StaffTextStamping) Chord(com.xenoage.zong.core.music.chord.Chord)

Example 18 with Chord

use of com.xenoage.zong.core.music.chord.Chord in project Zong by Xenoage.

the class MidiConverter method writeVoice.

/**
 * Writes the given voice into the MIDI sequence.
 * @param voiceMp         the staff, measure and voice index
 * @param repetition      the index of the current {@link Repetition}
 */
private void writeVoice(MP voiceMp, int repetition) {
    val voice = score.getVoice(voiceMp);
    for (VoiceElement element : voice.getElements()) {
        // ignore rests. only chords are played
        if (false == MusicElementType.Chord.is(element))
            continue;
        val chord = (Chord) element;
        // grace chords are not supported yet - TODO: ZONG-104: Play grace chords
        if (chord.isGrace())
            continue;
        // start beat of the element
        Fraction duration = chord.getDuration();
        val startBeat = voice.getBeat(chord);
        val rep = repetitions.get(repetition);
        if (false == rep.contains(Companion.time(voiceMp.measure, startBeat)))
            // start beat out of range: ignore element
            continue;
        // MIDI ticks
        val startMidiTime = timeMap.getByRepTime(repetition, Companion.time(voiceMp.measure, startBeat));
        long startTick = startMidiTime.tick;
        long endTick = startTick + durationToTick(duration, resolution);
        long stopTick = endTick;
        if (false == options.midiSettings.durationFactor.equals(Companion.get_1())) {
            // custom duration factor
            stopTick = startTick + round((endTick - startTick) * options.midiSettings.durationFactor.toFloat());
        }
        // play note
        if (startTick < stopTick) {
            float volume = dynamics.getVolumeAt(voiceMp.withBeat(startBeat), repetition);
            int midiVelocity = round(midiMaxValue * volume);
            for (Note note : chord.getNotes()) {
                addNoteToTrack(note.getPitch(), voiceMp.staff, startTick, stopTick, midiVelocity, 0);
            }
        }
    // TODO Timidity doesn't like the following midi events
    /*MetaMessage m = null;
			if (musicelement instanceof Clef)
			{
				Clef c = (Clef) musicelement;
				m = createMidiEvent(c, tracknumber);
			}
			else if (musicelement instanceof NormalTime)
			{
				NormalTime t = (NormalTime) musicelement;
				m = createMidiEvent(t, resolution, tracknumber);
			}
			else if (musicelement instanceof Key)
			{
				Key k = (Key) musicelement;
				m = createMidiEvent(k, tracknumber);
			}
			else if (musicelement instanceof Tempo)
			{
				Tempo tempo = (Tempo)musicelement;
				m = MidiTempoConverter.createMetaMessage(tempo);
			}
			if (m != null)
			{
				MidiEvent event = new MidiEvent(m, starttick);
				track.add(event);
			}*-/
			currenttickinvoice = endtick;
		}*/
    }
}
Also used : lombok.val(lombok.val) Note(com.xenoage.zong.core.music.chord.Note) Fraction(com.xenoage.utils.math.Fraction) Chord(com.xenoage.zong.core.music.chord.Chord)

Example 19 with Chord

use of com.xenoage.zong.core.music.chord.Chord in project Zong by Xenoage.

the class VoiceStamper method stampVoice.

public List<Stamping> stampVoice(VoiceSpacing voice, float voiceXMm, StaffStampings staffStampings, boolean stampLeadingRests, StamperContext context, // TODO:
FormattedTextStyle defaultLyricStyle, Map<Beam, BeamSpacing> beams, OpenSlursCache openCurvedLinesCache, OpenLyricsCache openLyricsCache, LastLyrics lastLyrics, OpenTupletsCache openTupletsCache) {
    List<Stamping> ret = alist();
    // create the voice elements
    boolean onlyRestsSoFar = true;
    for (ElementSpacing spacingElement : voice.elements) {
        MusicElement element = spacingElement.getElement();
        if (element != null) /* TODO && (stampRests || !(element instanceof Rest)) */
        {
            Notation notation = context.getNotation(element);
            float xMm = voiceXMm + spacingElement.xIs * voice.interlineSpace;
            if (element instanceof Chord) {
                // chord
                onlyRestsSoFar = false;
                Chord chord = (Chord) element;
                BeamSpacing beam = beams.get(chord.getBeam());
                ret.addAll(chordStamper.stampAll((ChordNotation) spacingElement.getNotation(), xMm, beam, staffStampings, context, defaultLyricStyle, openCurvedLinesCache, openLyricsCache, lastLyrics, openTupletsCache));
            } else if (spacingElement instanceof RestSpacing) {
                // rest
                if (false == onlyRestsSoFar || stampLeadingRests) {
                    // not a leading rest, or a leading rest which should be stamped
                    ret.add(elementStamper.createRestStamping((RestSpacing) spacingElement, xMm, context));
                }
            } else {
                throw new IllegalArgumentException("Notation not supported: " + notation);
            }
        }
    }
    return ret;
}
Also used : ElementSpacing(com.xenoage.zong.musiclayout.spacing.ElementSpacing) Stamping(com.xenoage.zong.musiclayout.stampings.Stamping) BeamSpacing(com.xenoage.zong.musiclayout.spacing.BeamSpacing) ChordNotation(com.xenoage.zong.musiclayout.notation.ChordNotation) MusicElement(com.xenoage.zong.core.music.MusicElement) RestSpacing(com.xenoage.zong.musiclayout.spacing.RestSpacing) Notation(com.xenoage.zong.musiclayout.notation.Notation) ChordNotation(com.xenoage.zong.musiclayout.notation.ChordNotation) Chord(com.xenoage.zong.core.music.chord.Chord)

Example 20 with Chord

use of com.xenoage.zong.core.music.chord.Chord in project Zong by Xenoage.

the class VoiceElementWriteTest method createTestScoreEighths.

/**
 * Creates a score with a single staff, a single measure,
 * two voices with each 8 quarter notes which are beamed.
 */
private Score createTestScoreEighths() {
    Score score = ScoreFactory.create1Staff();
    new VoiceAdd(score.getMeasure(atMeasure(0, 0)), 1).execute();
    for (int iVoice : range(2)) {
        Voice voice = score.getVoice(atVoice(0, 0, iVoice));
        List<Chord> beamChords = new ArrayList<>();
        for (int i = 0; i < 8; i++) {
            Chord chord = new Chord(new Note(Companion.pi(0, 0, 4)), Companion.fr(1, 8));
            // add elements by hand, since the corresonding command is tested itself in this class
            chord.setParent(voice);
            voice.getElements().add(chord);
            beamChords.add(chord);
        }
        // create beam
        Companion.beamFromChords(beamChords);
    }
    // ensure that assert method works correctly. if not, fail now
    assertTestScoreEighthsOriginalState(score);
    return score;
}
Also used : Score(com.xenoage.zong.core.Score) Note(com.xenoage.zong.core.music.chord.Note) ArrayList(java.util.ArrayList) Voice(com.xenoage.zong.core.music.Voice) Chord(com.xenoage.zong.core.music.chord.Chord)

Aggregations

Chord (com.xenoage.zong.core.music.chord.Chord)63 Test (org.junit.Test)34 MP (com.xenoage.zong.core.position.MP)16 Pitch (com.xenoage.zong.core.music.Pitch)12 Score (com.xenoage.zong.core.Score)11 Voice (com.xenoage.zong.core.music.Voice)10 NotesNotation (com.xenoage.zong.musiclayout.notation.chord.NotesNotation)10 VoiceElement (com.xenoage.zong.core.music.VoiceElement)8 Note (com.xenoage.zong.core.music.chord.Note)6 Rest (com.xenoage.zong.core.music.rest.Rest)6 ChordTest (musicxmltestsuite.tests.utils.ChordTest)6 Fraction (com.xenoage.utils.math.Fraction)5 Staff (com.xenoage.zong.core.music.Staff)4 Beam (com.xenoage.zong.core.music.beam.Beam)4 Grace (com.xenoage.zong.core.music.chord.Grace)4 StemDirection (com.xenoage.zong.core.music.chord.StemDirection)4 Dynamic (com.xenoage.zong.core.music.direction.Dynamic)4 SlurWaypoint (com.xenoage.zong.core.music.slur.SlurWaypoint)4 ChordNotation (com.xenoage.zong.musiclayout.notation.ChordNotation)4 NoteDisplacement (com.xenoage.zong.musiclayout.notation.chord.NoteDisplacement)4