public Pitch transpose(int semitonesUp) {
        int newValue = value + semitonesUp;
        int newOctave = octave;
        int newAccidental = accidental;

        while (newValue >= OCTAVE) {
            newValue -= OCTAVE;
            newOctave++;
        }

        while (newValue < 0) {
            newValue += OCTAVE;
            newOctave--;
        }

        if (!isValid(newValue)) {
            int interval = semitonesUp % OCTAVE;
            if (interval == 3
                    || interval == 5
                    || interval == 8
                    || interval == 10) {
                newValue++;
                newAccidental--;
            } else {
                newValue--;
                newAccidental++;
            }
        }

        return new Pitch(newValue, newAccidental, newOctave);
    }