how to generate parts, setting volume and export the parts by using a batch file (or plugin)?

• Nov 1, 2018 - 19:29

I would like to automatically
- open a MuseScore file (if using a batch file / using the active score in MuseScore if using a plugin)
- generate parts for all voices within this file
- then: for each part / voice in that file:
- - set the volume for this voice to eg 75%
- - set the volume for all other voices to eg 25%
- - generate a mp3 export for this voice
- and finally close the file without saving it

This is for a choir, and all the MuseScore files I use have only voices as "instruments".

Is there a way to accomplish this using a batch file / shell script? Or by using a plugin?
(I've read of the batch convert plugin, but guessing from the description is does not seem to be able to generate parts or set the volume automatically.)

I could try to create my own plugin, if someone could point me into the right direction (and if the methods needed to accomplish this are available).

Any help appreciated. Thanks.


Comments

Far easier to teach the choir members to use the score itself in MuseScore and operate thee mixer, then play.

Give a man a fish and he won't starve today. Teach him to fish and he'll never starve ;-)

Ok, I have found the plugin creator and its documentation, but I don't know where to start (besides creating a plugin skeleton)...

Rethinking my algorithm I need to
- iterate over all instruments/voices in the opened score
- - set the volume for the current voice to eg. 75%
- - set the volume for the other voices to eg. 25%
- - export as mp3

(So no need to create parts. So sad: I'd already found a property Part.volume...)

Is there some sample plugin or some other plugin which I can look into?

In reply to by msmb

I have just in the past week done what you want by hand for my church's choir with our music for the Christmas praise service. I am don't know anything about the plugin framework, but I am willing to start learning it with you and help you do this, because it would be a very handy plugin for me to have, too. ;-)

You can contact me via my personal contact form in by clicking on my username above this comment, then clicking on the Contact button. Looking forward to hear from you.

In reply to by Louis Cloete

Thanks for the message you sent me via my contact form. I can't, however, reply to you, because you didn't enable your contact form or sent me your email address in your message to me. I would need either to be able to reply to you personally. In the meantime, I am going to post the reply I wanted to send to you here, because @jeetee would also have interest in it. So here it is:

Hi ***!

I am starting to suspect you are trying to tackle this problem in a way MuseScore isn't designed to handle. I don't think the Mixer is the route you should follow. Fortunately, there is a better way. I will describe my manual method to you. I think (from my limited programming knowledge and what I have seen thus far by digging into the MuseScore source and Plugin documentation) that a plugin is indeed possible that would do what I did manually, automatically.

My procedure is as follows:

  1. Select all (ctrl [Mac: cmd] + a)
  2. Choose "Notes" in Inspector
  3. Ensure that the "Velocity Type" in the Note section of the Inspector is set to "Offset"
  4. Set "Velocity" (just below "Velocity Type") to -40
  5. For each voice, select it using selection filter and range selection*
  6. Set its "Velocity" to 20
  7. Export

*For example alto:

  1. Open selection filter (F6)
  2. Uncheck "Voice 1"
  3. Click the first note
  4. Press Ctrl + Shift + End
  5. Continue with Step 6 above

I think we should try using velocity properties of each voice rather than trying to use the Mixer. MuseScore's Mixer does not yet have the functionality we need, even if it were exposed through the plugin framework.

Louis

In reply to by Louis Cloete

This is a procedure for Close Score SATB, where S and A share one staff and T and B another.

Another method for this would be to use the attached template and 2 staff texts (one for each staff, attached to the very first chord or rest), switching voice 1 to Soprano respectively Tenor and voice 2 to Alto respective Bass via staff text properties and then use the 4 mixer channels.

Still won't help the OP though, as this doesn't work in any kind of batch mode

Attachment Size
04-SATB_Close_Score.mscx 16.54 KB

In reply to by Louis Cloete

Thanks for your reply and your suggestion. I'm not sure whether we're trying to reach the same goal. I'm currently taking the following manual approach:
1) opening a score, which has each voice in a separate staff (Soprano, Alto, Tenor, Bass etc.)
2) opening the mixer, setting volume to 100% for Soprano, to 50% for all other voices
3) export score to mp3
4) repeat steps 2 and 3 for all other voices, adjusting volume accordingly
By this I get one mp3 file for each staff, having the current voice at full volume and the other voices at a lower volume to have some orientation.
I'm looking for an automated approach to this - and, after some research during the last couple of days and with lots of help from this forum, am close to have one. (I'll post current state in a separate entry.) The last piece I'm missing is getting the current score's path - MuseScore 1.x had a property for it, MuseScore 2.x does not seem to have this anymore. So I'll make it a config item in the plugin for now.

P. S.: Contact form should be enabled as per my account settings (green check for "personal contact form").

In reply to by msmb

We are doing kind of the same thing. I just started from SATB closed score and changed each note's MIDI velocity to make one voice louder than the other instead of using SATB open score and using the mixer. There are other enhancements I have in mind for the process, like to write code dealing with splitting voices (e.g. Tenor I and Tenor II), first exporting Tenor I's notes louder and all other, incl. Tenor II's, notes softer, then exporting Tenor I softer and Tenor II louder.

That is not a dealbreaker if the plugin can't do that right now, however. You can just get it working for yourself doing what you want, and then I would probably be able to extend it to do the extra stuff I want as I get more fluent in QML and JavaScript.

In reply to by msmb

Current state is: I finally got a plugin skeleton to show up in the plugin manager AND to make the plugin manager show description and version information (the latter two did not show up at first, even after refreshing plugins or restarting MuseScore).

Now I need to
- retrieve the name of the current score => curScore.name?
- iterate over all staves => 0 .. curScore.nstaves-1?
- access and change the volume settings for each stave individually => how to?
- export current score as mp3 => writescore(curScore, "test", "mp3")?

The text after the "=>" is my guess. Are those guesses correct?
Where to find further documentation on creating a plugin?

How can I output some text or other information visible to the user? I've seen console.log() commands in some plugins. But where is this debug message printed to? Do I need additional software to make those debug messages visible?

In reply to by msmb

I installed sysinternals DebugView, which seems capable of capturing MuseScore's debug output.
Reloading plugins lead to a couple of debug messages, closing plugin manager as well.
But when running my basic plugin (which mainly consists of a console.log() statement, besides the skeleton) it only outputs:
[6236] QQmlComponent: Component is not ready
[6236] line -1: File not found

???


current plugin code is:

import QtQuick 2.0
import MuseScore 1.0
 
MuseScore {
      version:  "2.0"
      description: "This plugin exports all voices in active score as mp3 files"
      menuPath: "Plugins.Export voices as mp3"
 
      onRun: {
            console.log("begin plugin export_voices_mp3");
 
 
 
            console.log("end plugin export_voices_mp3");
 
 
            Qt.quit();
            }
      }

Save your efforts; the mixer isn't exposed to the plugin framework currently.

If you're any good in other scripting languages, you could save your scores as mscx and have script generate derived mscx files in which the volume levels have been adjusted, then batch-convert these to mp3's. But all of that needs to happen outside of MuseScore currently.

In reply to by jeetee

Thanks for your reply, I've filed a feature request already... :-)

As for the way you've suggested:
- I recognize that mscz files are ordinary zip files
- root file is named in file META-INF/container.xml <rootfile> tag
- and normally points to the mscx file in the root path of the mscz file, which is in xml format
- I'm fine with scripting xml & zip file manipulation

But: How can I influence the mixer volume settings in the mscx file - what are the attributes needed for this (or where can I find some documentation for the mscx xml-format)?

current state is the following plugin code:

//=============================================================================
//  Export voices as mp3
//  Copyright (2018) msmb
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License version 2.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
 
import QtQuick 2.0
import MuseScore 1.0
 
MuseScore {
      version:  "0.1"
      description: "This plugin exports all voices in active score as separate mp3 files, volume adjusted to highlight the active voice. Currently path has to be adjusted manually in the plugin's source code."
      menuPath: "Plugins.Export voices as mp3"
 
      onRun: {
        console.log("begin plugin export_voices_mp3");
 
        // --------------------------------------------------------------------
        // configuration section
        // --------------------------------------------------------------------
        var cPath = "c:/temp/";       // including trailing slash - how to get this dynamically? or the current score's path?
        var iVolumeActive = 100;
        var iVolumeBackground = 50;
        // --------------------------------------------------------------------
        // end configuration setting
        // --------------------------------------------------------------------
 
        if(typeof curScore === 'undefined') {
            console.log("no active score found");
        }
        else {
            console.log("current score: ", curScore.name);
 
            var numParts = curScore.parts.length;
            for(var p=0; p < numParts; p++) {
                console.log("working on part ", curScore.parts[p].partName, "...");
                for(var p2=0; p2 < numParts; p2++) {
                    curScore.parts[p2].volume = (p==p2 ? iVolumeActive : iVolumeBackground);
                    // console.log("part '", curScore.parts[p2].partName, "' volume set to ", curScore.parts[p2].volume);
                }
                var cFN = cPath + cleanupFilename(curScore.name) + "-" + cleanupFilename(curScore.parts[p].partName);
                console.log("writing ", cFN, "...");
                writeScore(curScore, cFN, "mp3");
            }
        }
 
        console.log("end plugin export_voices_mp3");
        Qt.quit();
    }
 
    // cleanupFileName
    // remove some special characters not allowed in filenames
    function cleanupFilename(fn) {
        fn = fn.trim()
        fn = fn.replace(/[\n\\\/:\*\?\"<>|]/g,"_")
        return fn
    }
}

To finish this old thread:
I've switched to direct manipulation of the score's xml (as proposed by @jeetee a while ago). That's proved to be much easier (for me) than trying to do the same with MuseScore's plugin interface.

By this I'm now able to:
- create different versions of the orginal score, like "training", "Karaoke" and "Solo" versions (= different combinations of volume per voice, eg: "training for Alto" => "Alto @100%, Soprano, Tenor, Basso @50%")
- replacing instruments (some would like to have "Grand Piano" as instrument instead of "Choir Aah"
and generating all the different variants in a few minutes with just a single program call per MuseScore file.

If someone's interested in this PHP script I can either post it here or send it via PM.

In reply to by msmb

I ended up with quite similar solution. Through, my script is implemented with powershell. It exports mp3 audio files for different parts with proper volume settings, previews (plays) them during the export process, and finally uploads the audio files to our choir's Dropbox score bank.

Today I also finished a MuseScore plugin that implements a simple GUI for the script. It starts the script with selected options and is capable of interacting with the script in run-time.

What a nice powershell, xml, rest api, oauth, qml, and musescore plugin api excercise.

Do you still have an unanswered question? Please log in first to post your question.