Rendering Chord symbols from musicxml

Hi I would like to show Chord symbols as used in Jazz lead sheets:


and color them interactively based on user-Input.

So far I have not found any open source library that would do the trick.
Has anyone experience doing so?
Another Idea would be to use a javascript library (if there is on) and render an svg on the fly and then use it. But so far I am not sure which way to go.
Ideas very welcome :slight_smile:

Edit: Like Ben pointed out, what I’m suggesting below is just rendering the text and not directly parsing chord from musicXML.

Here is a simple implmentation of a component label which can display a normal sized string and a smaller sized string just next to it. The number of words can vary for both strings and they will be left aligned.

You can customize according to your needs.

struct ChordSymbolDisplay : public juce::Component
{
    ChordSymbolDisplay() { setInterceptsMouseClicks(false, false); }

    String normal, smaller;
    GlyphArrangement normalGlyph, smallerGlyph;

    void setNormalString(String newString) { normal = newString; }
    void setSmallerString(String newString) { smaller = newString; }

    constexpr static float thisCompHeight = 21.f; //in pixels which was set in the parents bounds
    constexpr static float fontSize = 13.f / thisCompHeight;
    constexpr static float smallerTextSizeReducer = 0.8f;

    void paint(Graphics& g) override { drawText(g); }
    void resized() override {}

    void drawText(Graphics& g)
    {
        normalGlyph.clear();
        smallerGlyph.clear();

        Rectangle<int> area = getLocalBounds();
        Rectangle<float> bounds{ 0.f,0.f,0.f,0.f };
        PositionedGlyph last;       

        if (normal.isNotEmpty())
        {
            auto fontHeight = fontSize * getHeight();
            auto fontNew = Font(fontHeight);

            g.setColour(Colours::blueviolet);

            normalGlyph.addFittedText(fontNew, normal,
                (float)area.getX(), (float)area.getY(),
                (float)area.getHeight(), (float)area.getHeight(), Justification::bottomLeft,
                1,
                0);

            last = normalGlyph.getGlyph(normalGlyph.getNumGlyphs() - 1);
            bounds = last.getBounds();
            area.removeFromLeft((int)bounds.getX() + (int)bounds.getHeight());

            normalGlyph.draw(g);
            normalGlyph.clear();
        }

        if (smaller.isNotEmpty())
        {
            auto fontHeight = smallerTextSizeReducer * fontSize * getHeight();
            auto fontNew = Font(fontHeight);

            g.setColour(Colours::indianred);

            smallerGlyph.addFittedText(fontNew, smaller,
                (float)area.getX(), (float)area.getY(),
                (float)area.getHeight(), (float)area.getHeight(), Justification::bottomLeft,
                1,
                0);

            normalGlyph.addGlyphArrangement(smallerGlyph);

            last = normalGlyph.getGlyph(normalGlyph.getNumGlyphs() - 1);
            bounds = last.getBounds();

            area.removeFromLeft((int)bounds.getX() - area.getX() + (int)bounds.getHeight());

            normalGlyph.draw(g);
        }        
    }
};

image

1 Like

Since the title mentions MusicXML, it seems like there will need to be an analysis step before the rendering to actually identify the chords being played. This is far from a trivial task…

1 Like

Hi Ben hi bcsuganthan!
I am very very happy for your answers! Thanks that you even provided code!
Yes the parsing of the musicXml is the one part the rendering the other.
I was hoping to find a ready to be used library that would do both but couldn’t find one and will now go down the rabbit whole for a bit I guess.
In case anyone is interested starting something and making it open source I would be very happy to team up

How the JUCE application/plugin get the data from MusicXML?

Are you planning to import a musicXML into the JUCE application/plugin and let it identify the chords, etc or other means?

The Idea is to show the chord symbols of tags from musicxml as chords and play them as (midi). Acctually I just noticed that the patterngenerator demo goes into this direction.