lenmus / lomse

A C++ library for rendering, editing and playing back music scores.
MIT License
120 stars 28 forks source link

Define API for score manipulation #208

Open cecilios opened 5 years ago

cecilios commented 5 years ago

I have added sample "drawlines" (in examples/samples). It is a simple program to display an score. In the menu there is an option to add colored marker lines to the score, and another option to remove them.

While coding this sample I've noticed that lomse does not have a suitable API for score manipulation, at least for the most common expected operations. For instance, it is complex to position the cursor on a given measure. Current Lomse API is only used by my application and it fulfills my needs, but I understand that it is not a suitable API for a general purpose library. Therefore, an urgent issue is to define this API so that it can be coded and documented as soon as posible.

I have opened this issue for defining this API. Any collaboration is welcome. Examples of use cases that you would like to be considered or ideas to outline the API would be of great help!

hugbug commented 4 years ago

Manipulate instruments

In my app I've recently implemented a function to show only certain instruments. The use case: when a song (midi-file) is loaded into piano the song often contains many instruments but the user plays only right hand and possibly left hand parts (usually defined as two instruments in the midi-file).

In previous version of my app the whole score with 10 or more instruments were displayed. Now only two instruments (for right hand and left hand) are shown.

To achieve this I manipulate score instruments collection.

First I remove all instruments from score and store them in my private vector:

    while (score->get_num_instruments() > 0)
    {
        ImoInstrument* instr = score->get_instrument(0);
        m_instruments.push_back(instr);
        score->get_instruments()->remove_child(instr);
    }

Then only needed instruments are added back to score:

    // add right hand part to score
    for (ImoInstrument* instr : m_instruments)
        if (MidiChannelOfInstrument(instr) == rightHandChannel)
            score->add_instrument(instr);

    // add left hand part to score
    for (ImoInstrument* instr : m_instruments)
        if (MidiChannelOfInstrument(instr) == leftHandChannel)
            score->add_instrument(instr);

That works just fine. I should take care of deletion of the instruments detached from score.

Possible API

What would help if there were a way to hide unneeded instruments. Another needed function is to change the order of the instruments. When displaying only right hand and left hand parts the right hand should be displayed first. That's why I have two loops - one to add right hand and another to add the left hand (in this order).

The approach I currently use works without issues. I'm not sure if a better API is really required here but I can imagine that other apps may find functions to hide/show/move instruments useful.

cecilios commented 4 years ago

Thanks for this feedback. The need for hiding and reordering instruments is clear and it is a common feature in any score editor. Therefore, methods for hiding and reordering instruments should definitely be added. Thanks for the suggestion.