GSoC 2016 - Week 8 - Performance and Preferences

Posted 7 years ago

This was my eighth week working on note entry with MuseScore for Google Summer of Code. I made rapid progress implementing a working proof of concept early in the project. For the past couple of weeks I have been going back over my previous work, improving the structure and performance of the code, and giving users more control over note entry via additional options and preferences.

This week’s summary:

  • Improvements to Automatic Real-time note entry mode:
    • Improved performance
    • Auto-advance triggered when a note is pressed
  • New options in preferences:
    • Configurable input tempo/delay for Automatic Real-time
    • Set MIDI key/pedal for advancing in Manual Real-time mode
    • Choose whether to advance again when the key is released
  • Improved code structure

Still to do:

  • Configuration options for the metronome
  • New implementation of rhythm simplification and voice extraction

Automatic Real-time mode

This is supposed to be the mode where the user plays the piece at a constant tempo, but my initial implementation had a few performance issues that meant the tempo was not quite constant. Pressing lots of MIDI keys at once would cause the beat to arrive very slightly late, but enough for it to be noticeable and off-putting. My algorithm was supposed to account for the time needed to add the notes to the score, but it wasn’t particularly effective. My new algorithm is much simpler and does this more successfully.

function automaticRealtime() {
    int realtimeDelay = 750; // milliseconds
    while(true) {
        timer.start();
        advanceAndAddNote(); // This is an expensive function
        timer.stop();
        int delay = realtimeDelay - timer.elapsed(); // ensure loop always takes 750ms
        sleep(delay);
    }
}

It is also possible that my structural improvements have helped here too by reducing the overhead associated with adding notes, or perhaps another developer has made some improvements to efficiency elsewhere.

Simply entering automatic real-time mode does not cause the score to start advancing. Previously the advancement could only be triggered by pressing a special key or foot pedal - the same as is used in manual real-time. (The difference between the modes is that in manual real-time the key must be pressed repeatedly whereas in automatic real-time it only needs to be pressed once,) This system works well providing the user has a pedal or other suitable control. Since this is not always the case I have added a second way to trigger advancement. The new method is simply to start playing notes - automatic advancement will continue until the user stops playing notes. As a consequence of this it is not possible enter rests when using automatic real-time in this way, but it is still possible to add rests if the pedal is used.

Options made available in the preferences

I have added three new note entry options to the preferences to allow the user to adjust:

  • the delay in automatic Real-time mode
  • the MIDI key or pedal used to advance in both Real-time modes
  • whether releasing the advance key also triggers an advance in the same way that pressing it does. This is useful when entering quavers / eighth notes in a score that has a 4/4 time signiture (based on crotchets / quarter notes).

    Note input preferences.png


Comments

So, how is it actually supposed to work? I want to try it out. Plugged in MIDI controller, opened the MuseScore 3 compiled from your semi-realtime-midi branch, switched to "Real-time (automatic) mode", pressed N, pressed notes on keyboard. Nothing happened (well, notes sounded, but nothing was added to the score). Where's the missing step?

In reply to by Isaac Weiss

Sorry, I had forgotten to push the changes. It's done now so you can pull the changes and try it out again. It was a force push (changed history) so if you still have my branch you may need to delete it first or reset to before my first commit before you pull. Be aware that the rhythm simplification and voice extraction is not implemented in the PR because I have thought of a better way to do it that will make it possible to do these things:

  • enable/disable triplets
  • change quantisation level after recording
  • use the raw note on/off timings for playback
  • follow the user's tempo automatically (i.e. without needing a pedal)

I might not get all (or indeed any) of these done before the end of GSoC but I'll still be here GSoC has finished. The last one might require some help from machine learning people.

Also, I think you use a Mac. I have a question for Mac users... what is a good key to use for Real-time Advance? At the moment I have it set to "Enter" on the numeric keypad, but Mac's only have a "Return" button which is already assigned to Page Break. It's not a big problem because it is better to use a keyboard key instead (see the MIDI Remote), but let me know if you think of something suitable.

In reply to by shoogle

Any idea why the compilation might be failing?

The following build commands failed:
CompileC build.release/mscore/mscore.build/Release/mscore.build/Objects-normal/x86_64/musescore.o mscore/musescore.cpp normal x86_64 c++ com.apple.compilers.llvm.clang.1_0.compiler
(1 failure)
make: *** [release] Error 65

In reply to by shoogle

No, sorry. There might be some more useful information further up in the log though. Did you maybe try to apply my changes on top of the latest code in master? There might be conflicts so you probably don't want to do that. If you were following this guide try giving the --rebase option to git pull.

In reply to by shoogle

A few things, but at any rate, this worked.

So, now I'm checking it out. What's happening is, I press the first key, the metronome starts, and an endless series of tied quarter notes are entered. It does not stop when I release the key, or ever, and I can't add another note. Is the Enter key supposed to play a role here?

In reply to by Isaac Weiss

It should stop when you release the key - it does on my machine. What happens if you use MuseScore's on-screen piano keyboard instead of a physical MIDI keyboard?

If you want to see what Enter does then go into the shortcut preferences, search for "Real-time" and set it to something else temporarily. Press it once to start the metronome in automatic mode, or press it repeatedly to give each beat in manual mode.

In reply to by Isaac Weiss

To use a smaller division just pick a smaller duration from the note input toolbar as usual.

If the on-screen keyboard works then it sounds like your keyboard's NOTE_OFF event is being missed. Can you run MuseScore from within QtCreator and look out for debug messages on the Terminal when you press and release a MIDI key? You should see something like this:

...Ms::ScoreView::midiNoteReceived: midiNoteReceived 60 chord 0

If you don't see that message (or something like it) both when the key is pressed AND also when it is released then look for me on IRC and I'll try to help you get it working.