Search code examples
jfugue

Chord.setOctave(x) returns notes with wrong value in jFugue 5. what am I missing?


Here is the sample code:

public class TestNoteValue {
    public static void main(String[] args) {
        Chord c = new Chord("C5maj");
        DevLog.debug(MusicAnnotationUtil.reportChord(c));
        // ----------------
        c.setOctave(4);
        DevLog.debug(MusicAnnotationUtil.reportChord(c));
    }
}

Result output:

enter image description here

Result for the first time is right: Chord{Note{C5, 60}, Note{E5, 64}, Note{G5, 67}, }

C5's value indeed is 60. However after Chord.setOctave(4), it doesn't change the first note's expression, however changed its value. Resulting in a correctness-compromised note array: Chord{Note{C5, 48}, Note{E4, 52}, Note{G4, 55}, }

am I missing something here?

thanks for the help!


As David is helping look into the code, I'll post my temporary workaround. Hopefully it helps others.

    public static Chord setOctave(Chord c, byte octave) {
    DevLog.super_trace("setting octave for chord "+c+" to "+octave);
    c.setOctave(octave);
    Note[] nA = new Note[3];
    for(int i=0; i<c.getNotes().length; i++){
        nA[i] = new Note(c.getNotes()[i].getValue());
    }
    return Chord.fromNotes(nA);
}

Solution

  • I've added a new method to the Note class that updates the "original string" with which a note was created when the value of that note is changed.

    I'll release a new version after touching up some other issues. In the meantime, here's what has changed in Note.java:

    Updated method:

    public Note setValue(byte value) {
        this.value = value;
        this.updateOriginalString(); // New line that calls the method below
        return this;
    }
    

    New method:

    private void updateOriginalString() {
        if (this.getOriginalString() != null) {
            String oldOriginalString = this.getOriginalString();
            StringBuilder newOriginalString = new StringBuilder();
            newOriginalString.append(getToneString());
            if ((oldOriginalString.length() > 1) && (oldOriginalString.substring(oldOriginalString.length()-2, oldOriginalString.length()-1).matches("\\d"))) {
                newOriginalString.append(getOctave());
            }
            setOriginalString(newOriginalString.toString());
        }
    }
    

    And a new test in NoteTest.java:

    @Test
    public void testOriginalStringForNotes() {
        assertTrue(new Note("C").getOriginalString().equals("C"));
        assertTrue(new Note("C5").getOriginalString().equals("C5"));
        assertTrue(new Note("C").changeValue(+1).getOriginalString().equals("C#"));
        assertTrue(new Note("C5").changeValue(+1).getOriginalString().equals("C#5"));
        assertTrue(new Note("C").setValue((byte)48).getOriginalString().equals("C"));
        assertTrue(new Note("C5").setValue((byte)48).getOriginalString().equals("C4"));
    }