0% found this document useful (0 votes)
64 views16 pages

GSoC Proposal - Plugin Manager

This document proposes an "App Store-like Plugin Manager" for MuseScore to allow users to easily discover, install, update, and manage plugins. It involves developing a plugin store interface and improving MuseScore's existing local plugin management facilities. The proposal provides details on the design, features, and implementation of these new components to automate the currently manual plugin installation and management process.

Uploaded by

Arya Bhardwaj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
64 views16 pages

GSoC Proposal - Plugin Manager

This document proposes an "App Store-like Plugin Manager" for MuseScore to allow users to easily discover, install, update, and manage plugins. It involves developing a plugin store interface and improving MuseScore's existing local plugin management facilities. The proposal provides details on the design, features, and implementation of these new components to automate the currently manual plugin installation and management process.

Uploaded by

Arya Bhardwaj
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

GSoC Proposal: App Store-like Plugin

Manager
Songchao Wang

Contents
Synopsis

Benefits to MuseScore

Design Overview(Deliverables)
Notes
Part I: Plugin Store
Part II: Improvements in facilities of local plugins management

Implementation Overview
Fetching from Web
Analyzing the plugin detail page and download link
From GitHub
From attachments
Determine whether to download from GitHub or attachments
Download
Extracting and Installing
Determine the file extension name
Get the file list and determine the files to be reserved
Check duplicated qml files
Extract the files selected and copy to the plugin directory
Maintaining Local Plugins and Plugin Packages
Permanent Storage
Runtime Data Structure
Compatibility Check
Try Converting the 2.x Plugin
Automatic Update

Full Feature List


Notes
Priority Tags

Project Schedule
May 7th-27th
May 28th-June 2nd
June 3rd-27th
June 28th-July 2nd
July 3rd-9th
July 10th-16th
July 17th-19th
July 20th-26th
July 27th-August 9th
August 10th-12th
August 13th-19th
August 20th-27th

Bio

Contact Info

Synopsis
MuseScore functionality can be extended by ​plugins​. Discovering the compatible plugins and
installing them however is currently a manual job​. ​You have to use a web browser to choose
and download plugins of the correct version from a plugin detail page, extract it using your file
archiver, copy qml files(and sometimes with translation files) to MuseScore plugin directory and
finally reload the plugins in MuseScore.
The whole process described above is possible to be fully automated, which is exactly the goal
of this project.
The project involves two parts:
● A plugin store from which the user is able to discover, (un)install and auto-update plugins
from the ​MuseScore plugin repository​ in an easy manner.
The user doesn’t need to care whether the plugin in the store is compatible, as the store
automatically hides incompatible plugins by default and will always try to download the
correct version.
● Improvements on the old plugin manager
The main change is integrating both plugins installed from the store and plugins installed
manually(i.e., not from the store) ​using a tree view​. (​here​ are some explanations and
discussions about why using a tree view.)
I have made an ​incomplete implementation​ demonstrating part of the above features. Though
the available features are limited at present, It already works with a lot of plugins now. The
following images are real screen captures from this implementation.
Therefore, future work should be to enrich the initial implementation according to the design.
Benefits to MuseScore
Quite a few friends in my university’s student orchestra use MuseScore heavily to transcript their
scores. Often lots of repeated work has to be done, such as exporting the full score and all the
parts to PDF files before printing. But nearly none of them know these can be done much faster
with related plugins like “Batch convert”.
In fact, ​they hardly know there’s a plugin repository online,​ because they never visit the
MuseScore website unless they need to download the software… And they just saw there was a
plugin manager in MuseScore, with a few demo plugins in them, and thought they were useless.
I believe the above problem is quite common among more users, which can be resolved by
making the app store-like plugin manager available.
With this facility, I believe users are much more likely to discover and try to use various online
plugins, because all their cost is just a few seconds to wait for the plugin to be downloaded
before they are able to try it out!

Design Overview(Deliverables)

Notes
● This chapter explains the overall design and usage. Intended readers are ​MuseScore
users and developers​.
● More internal workflow and implementation details explained for developers are in the
chapter “Implementation Overview”.
● This chapter just covers ​all​ possible features in details, but with no priority assigned to
them. There’s no guarantee that every feature will be implemented. The chapter “Full
Feature List” gives priorities over them.
● See ​https://musescore.org/en/node/286338​ for relevant discussions, from which many
design choices and features have been inspired.

The new plugin store and original facilities from the old plugin manager, could both reside in
“Resource Manager” in MuseScore, and in their own subtabs.

Part I: Plugin Store


See the picture in “Synopsis” for UI demo.
Possible features:
● When the resource manager shows, or the user switches to the plugin store tab, all
3.x-compatible plugins from the online plugin repository should be displayed in this table.
But maybe as an advanced mode, the user could force the manager to display 2.x plugin
packages and download them as usual. The manager may try to convert them afterward.
(The converting method is described in "Implementation" part.)
● You could search for new plugin packages and filter them by category labels.
● You could (un)install new plugin packages simply by clicking the corresponding button.
● The manager should be able to check whether each package has been installed, and
display "Install" or "Uninstall" buttons according to the info.
However, if qml files of one particular plugin package are installed by one user
manually(i.e., not from the manager), the manager wouldn‘t recognize them as part of
this package, because the names of qml files are known only if that plugin package is
downloaded. Therefore, one plugin package may still be marked as "Uninstalled" even if
qml files of that plugin package exist locally.
To address this problem and prevent duplicated qml files, the following feature is
proposed.
● After one plugin archive is downloaded, and before files in the archive are extracted and
copied, the manager will check if there exist local qml files that have the same name with
the ones in the archive, and if yes, offer following options:
○ use the original file as part of this plugin, and ignore the file in the archive
○ use the file in the archive as part of this plugin, and delete the original file
○ use the file in the archive as part of this plugin, but also reserve the original file
○ abort installing
● For installed plugin packages, an "Update" button will appear. The manager should
check whether they are up-to-date regularly in the background, and enable the "Update"
button for each package when an update is available.
● For each installed plugin package, check whether the package is broken(i.e., missing
some qml files) and offer the option to reinstall.

Part II: Improvements in facilities of local plugins management


See the picture in “Synopsis” for UI demo.
Possible features:
● To keep backward compatibility, you could still manually download the qml file yourself
or write your own plugin qmls locally, and copy them to plugin directory. Then they will
appear after reloading.
● If local plugins are checked to be incompatible, necessary prompts are nice to be added.
Maybe as an advanced mode, the manager could offer the attempt to convert 2.x plugins
to 3.x ones. (The converting method is described in "Implementation" part)
● All other facilities of the old plugin manager, including:
○ enabling/disabling each qml.
○ shortcut configuration.
○ displaying the name, path, version, and description.
● The list in the left should display both plugins installed from store and manually installed
plugins. However, there are several choices of displaying them:
○ As before, show all existing qml files, including those from the store, in a flattened
form.
○ Show each plugin package as an item and hide all qml files it has.
○ (Reflected in the UI image) Use a tree view, and show each plugin package as
the branch, and its qml files as leaves under that branch. Show manually
installed qml files as tree nodes with the same hierarchy level as plugin
packages.
The last choice is the most flexible and is currently my choice.

Implementation Overview
This chapter describes the internal workflow of a plugin’s installation procedure. Intended
readers are ​MuseScore developers​.

Fetching from the MuseScore Plugin Repository


When we launch the resource manager, the crawler should fetch a list of available plugin
packages from ​https://musescore.org/en/plugins?category=All&compatibility=some_version_id​.

The map between MuseScore version and `some_version_id` is:


MuseScore Version some_version_id

1.x 4311

2.x 4316

3.x 4321
Only 3.x plugin packages are fetched by default.
It's not hard to parse the raw HTML table using some libraries, though the parsing code would
be simpler if there were a JSON file.
Each entry of the plugin list should contain:
● Title(string)
The title here should use the title from the plugin detail page, not the name of qml files.
● API Compatibility(a tuple of bool indicating compatibilities for the 3 versions)
● URL of the plugin detail page(string)
● Categories(vector of enum object)
The class `PluginPackageMeta` in the ​draft implementation code​ reflects this structure.

Analyzing the plugin detail page and download link


Then when we click on the “Install” button of any entry of plugin, the crawler will fetch the plugin
detail page.
The plugin may be stored either from GitHub or attachments, both of which should be checked.
From GitHub
If GitHub repo links are found in the detail page’s HTML, further determine whether to download
from a release or from a branch,
Usually, GitHub releases are believed to be more reliable, so we should always choose the
release if there is one. ​Github Release APIs​ should be used to further fetch the direct download
address and the release ID.
We should also make sure that we are downloading the latest release of ​3.x version​. This
could be checked via the name of the repo branch from which the release is published. The info
is available in the "target_commitish" field in the returned JSON of GitHub APIs. See ​here​ for an
example of a returned JSON.
If GitHub releases don't exist, download from a suitable branch that corresponds to the latest
version. The process of determining the correct branch seems to be easy: many plugin repos
have branches named master, 2.x or 3.x. A plausible approach is to select a branch that
contains "3.x", or select "master" if there are not branches that contain “3.x”.

From attachments
Look for direct links in the plugin detail page or attachments from musescore.org.
The attachments in the page could have various names and various kinds of description around
them.
Therefore, this step would require sophisticated pattern recognizing algorithms to choose
download links of the correct version(2.x or 3.x, etc.), which is quite time-consuming and could
be further discussed and optimized later.

Determine whether to download from GitHub or attachments


Maybe GitHub repos are supposed to be more preferred since they keep version info like
commit history and release IDs, which could be used for checking update.
But sometimes for some plugins, we do need to download from musescore.org, since the
GitHub repo contains a wrong version(1.x or 2.x ones). See these plugin detail pages for
example:
https://musescore.org/en/project/check-parallel-fifths-and-octaves
https://musescore.org/en/project/check-harmony-rules
So the logic to select between GitHub or attachments should be added and refined later.

Finally, a structured description of this plugin package will be recorded, including:


● GitHub repo URL(if applicable).
● URLs that are recognized to be downloadable links for proper plugin archives or qml file.
● latest commit hash of the corresponding branch on GitHub if applicable, this field is used
for checking updates.
● latest release ID of GitHub releases if applicable, this field is used for checking updates.
The class `PluginPackageDescription` in the​ draft implementation code​ reflects this structure.
Download
Download via the link analyzed above.
When downloading files from musescore.org, `Last Modified` field from the HTTP response
should also be added to the description of the package, this field is used for checking updates.

Extracting and Installing

Determine the file extension name


First, we need to check whether we've downloaded a qml file or an archive.
If the file is downloaded from GitHub, we will always get an archive of that repository. If from
musescore.com, the extension could always be checked in the string suffix of the direct link.
The manager should extract the downloaded file if it's an archive, or directly install if it's a qml
file.

Get the file list and determine the files to be reserved


There are ​some code snippets​ in MuseScore’s codebase that are already used for unzipping
language packages, which could be used similarly for plugin packages.
Before the archive is extracted, we could use the class `​MQZipReader​` in MuseScore to read
the file list contained in the archive.
Following file types are necessary to reserve:
● Plugin files(*.qml)
● Translation related files(*.qm and *.ts)
The path of each qml file could be recorded in ​PluginPackageDescription​. It's helpful in checking
the plugin’s integrity.

Check duplicated qml files


Before copying, the chosen qml files are compared against each plugin in the ​_pluginList
variable in class​ ​PluginManager​. If a local plugin with the same name is found, ask the user for
options described in "Design Overview Part I".

Extract the files selected and copy to the plugin directory


Finally, the qml files and translation files are copied into a new folder under MuseScore’s plugin
directory. The name of the new folder could be the last URL slug of the plugin detail page. For
example: ​tunings-and-temperaments​ for
https://musescore.org/en/project/tunings-and-temperaments​.
Maintaining Local Plugins and Plugin Packages

Permanent Storage
Currently, MuseScore stores metadata for local plugins in plugins.xml(located in C:\[your
username]\AppData\Local\MuseScore\MuseScore3). The XML file only stores the qml file paths
and flags indicating whether each qml file is loaded. After MuseScore is launched, these items
will be read into QList<PluginDescription> _pluginList in class PluginManager. (See the process
here​)
Qml files of each plugin ​from store​ should also be added into plugins.xml. Those matters are
taken good care of by existing plugin related codes and don't need modification.

But beyond these, for each plugin package installed from the repository, additional metadata
should be maintained. Essentially, all members in ​PluginPackageDescription​, plus the plugin
detail page URL, should be serialized and stored.

● The plugin detail page’s URL is needed for the manager to mark the corresponding item
in the table as “Installed”. (We cannot tell that merely from installed qml files.)
● Other members in ​PluginPackageDescription​ are stored mainly for checking updates.
See the section "Automatic Update".

The above metadata could be saved in a separate xml file(currently saved as


pluginpackages.xml​ in the ​draft implementation​, in the same directory as plugins.xml).

Runtime Data Structure


Currently MuseScore uses ​QList<PluginDescription> PluginManager::_pluginList​ to maintain
local plugins. When MuseScore launches, it fills this QList with contents from ​plugins.xml​, loads
and registers plugins that are marked to load.
For plugins from the store, the following classes are added:

struct​ ​PluginPackageMeta​;

enum​ ​PluginPackageSource​;

struct​ ​PluginPackageDescription​;

The classes ​PluginPackageMeta​ and ​PluginPackageDescription​ are described in previous


chapters. And ​PluginPackageSource​ is just an enum class specifying the source is GitHub,
GitHub release or attachment.

In runtime, a ​PluginPackageMeta​ object is created for every plugin displayed in the table, even
if it hasn’t been installed; and a ​PluginPackageDescription​ object is created for each installed
plugin from the store.
The objects of ​PluginPackageDescription​ are deserialized from ​pluginpackages.xml​ when the
resource manager starts.

Compatibility Check
Each plugin has its API compatibility specified on its web page. Plugins of compatibility 1.x, 2.x
and 3.x can only be run on MuseScore 1.x, 2.x and 3.x respectively.
Compatibility check should happen in two cases:
● When installing plugins from the repository, before the download begins, compatibility list
specified in the plugin web page should be verified against current MuseScore version.
Normally 2.x plugin packages won't be shown in the list.
● When registering local plugins, check whether the plugin is registered successfully.
Currently, registrations of incompatible plugins will silently fail, and no menu buttons will
be displayed for those plugins. This could be improved by reporting whether the plugin is
compatible explicitly.
The result of registration is contained in the return value of QQmlComponent::create().
See ​example code​, where the errors() method contains related info.

Try Converting the 2.x Plugin


Some of 2.x plugins could be converted to 3.x ones with small code changes. The plugin
manager could try doing this job by applying the following two replacements in qml files:
● from ​import MuseScore 1.0​ to ​import MuseScore 3.0
● from ​import FileIO 1.0​ to ​import FileIO 3.0
The effect may be limited, but might works sometimes.
The conversion could take place if the plugin failed to be registered.

Automatic Update
Most plugins don't have their own version numbers currently.
However, there are other ways to check if a particular plugin package has been changed:
● If the download link has changed in the plugin detail page, it's reasonable to assume
there's an update.
● For plugin files stored in musescore.com, the ​Last Modified​ field of HTTP Response
header is available to check.
When checking updates, we could send HTTP HEAD requests to the direct download
links of those plugins, If newer ​Last Modified​ value is found in response, there's probably
an update.
● For plugins stored in GitHub, the commit history could be checked via​ Github Release
APIs​. If newer commit logs are found, there's probably an update.
Another stupid way is to download the whole plugin again and look for difference, which is not
likely to be adopted.
Full Feature List

Notes
The following list gives a summarization of Chapter “Design Overview” and “Implementation
Overview”. The features are broken down to smaller items here. So it’s easier to track and
schedule them.
Each item in the list just describes the function briefly. Please refer to the previous two chapters
to see their detailed meanings.

Priority Tags
Following table shows the tags used by each item and their meanings.
Completed This feature has already been implemented in the ​draft implementation​.

Basic Fundamental features. The project won’t be complete without those features.

Advanced “Nice to have” ones.

Difficult I haven’t thought about the implement approaches thoroughly yet and further
research needs to be done during the working period.
I’ll make sure every ​basic ​feature listed is implemented in the working period.
After that(those ​basic​ features are highly likely to be completed early enough), I’ll move on to
the ​advanced ​items and implement them in the late summer, or, after the coding period if
progress gets slow.

1. Plugin Package Store


1.1. Discovery and Management
1.1.1. (​Completed​) Fetch the list of 3.x packages and display them in the table
when the resource manager starts.
1.1.2. (​Advanced​) Display 2.x packages in the list and mark the difference.
1.1.3. (​Advanced​) Add link entries to the plugin detail page and the issue page
for each plugin package somewhere in the table.
1.1.4. (​Completed​) Check whether each package in the list has been installed.
1.1.5. (​Completed​) Install plugin packages via the buttons.
1.1.6. (​Basic​) Uninstall plugin packages via the buttons.
1.1.7. (​Basic​) Ability to check whether each installed plugin is up-to-date.
1.1.8. (​Advanced​) Run checking update regularly in the background.
1.1.9. (​Basic​) Searching and filtering facilities.
1.1.10. (​Advanced​) Check integrity of each installed plugin.
1.2. Locating of the download link & bookmarking info used to check update
1.2.1. (​Completed​) Ability to find GitHub repos within the plugin detail page.
1.2.2. (​Basic​) Ability to choose the correct branch of one GitHub repo.
1.2.3. (​Completed​) Ability to get the latest commit hash and download address
of one particular GitHub repo branch.
1.2.4. (​Basic​) Ability to get the release ID and download address of the latest 3.x
version release of one GitHub repo.
1.2.5. (​Basic​, ​Difficult​) Ability to choose a correct attachment link of the latest
plugin version within the plugin detail page from musescore.org.
1.2.6. (​Basic​, ​Difficult​) Determine whether to download from GitHub repos or
attachments if both exist.
1.2.7. (​Basic​) Ability to get timestamp of the downloaded file from
musescore.org.
1.2.8. (​Completed​) Report errors if there’re no download links or GitHub repos
found within the page.
1.3. Installing
1.3.1. (​Basic​) Check whether the downloaded file points to an archive or a qml.
1.3.2. (​Basic​) Scan the archive for files to be reserved(qml and
translation-related files).
1.3.3. (​Advanced​) Let the user select what qml files are to be reserved if the
package contains multiple qml files.​ (discarded)
1.3.4. (​Advanced​) Check if there are qml files in the archive that are duplicated
of local existing ones during installing and make corresponding actions.
1.3.5. (​Completed​) Extract and copy file(s) to be reserved into a subfolder in
MuseScore plugin dir.
1.3.6. (​Completed​) Maintain related data structure.
2. Local plugin management
2.1. Management of local standalone plugins(individual qml files)
2.1.1. (​Basic​) Original facilities from the old plugin manager. (They should be
ported to the “Installed plugins” tab)
2.2. Management of plugins from the store
2.2.1. (​Basic​) Original facilities from the old plugin manager for each qml file in
one plugin. (They should be ported to the “Installed plugins” tab)
2.2.2. (​Basic​) Show a tree view of all plugins, with each plugin name as the tree
node, and qml files as the node’s children.
2.3. Registering qml files
2.3.1. (​Advanced​) Report results of whether one qml file is successfully
registered or not.
2.3.2. (​Advanced​) If one 2.x qml file fails to be registered, try converting them to
the 3.x version.
Project Schedule
Since this project is well-defined in both requirements and design, and won’t involve much
modification to MuseScore’s core facilities(like the complex algorithms of arranging notes and
beams, delicate data model classes in libmscore, etc.), the to-do list is quite clear compared to

😉
other projects related to music notation.
IMHO, I can start coding right away once the developer team thinks it’s time(even from now ),
with no time needed for stuff like familiarizing with the code base… I’ve done that already, at
least for the scope this project may cover.

I’ll always be in UTC+8 in this summer, and will usually be online from UTC 01:00-16:00.
In May, I may spend a few days(less than a week) wrapping up my graduation thesis​(the thesis
project itself will be accomplished in April). Apart from that, I’ll try to do more coding in the
community bonding period.
In June, I will spend a few days(less than a week) ​preparing for my ​graduation thesis defense.
In August, I plan to go home and spend one or two weeks with my family. Working time may be
a little less than usual. But I’m still able to keep in contact in daytime.
In time other than these, I’ll have no other commitments, and be able to work in full time.

May 7th-27th
Implement the following ​basic​ items in the full feature list:
● 1.1.6, 1.1.7, 1.1.9;
● 1.2.4;
● 1.3.2
In other words, in this period, I’ll implement the whole download, install and update pipeline only
for plugins published on GitHub.
These features are definite in ways of implementation, and I’m confident to accomplish them
smoothly, so I put them in the first place.

May 28th-June 2nd


Test for plugins stored on GitHub
I’ll examine the whole install process for all 3.x plugins which contain a GitHub repo in their
pages, on ​MuseScore Plugin Repository​ and check if all of them are downloaded and installed
properly.
And fix the code if there are any plugins failed to be downloaded. (From my experience of
writing crawlers, these bugs are quite common and almost unavoidable without complete tests)
June 3rd-27th
Finish the period I evaluation​;
Implement the following ​basic​ items​, which are related to plugins stored as attachments in
musescore.org.
● 1.2.5, 1.2.6, 1.2.7
● 1.3.1
Those features, especially 1.2.5 and 1.2.6, may be much harder to correctly implement and
more time-consuming than imagined, because the attachments in the page could have various
names and various kinds of description around them. So I leave quite a long time for these
items.

June 28th-July 2nd


Test for plugins stored as musescore.org attachments
The test can be started even in the previous period, but this one should be more thorough.
I’ll examine the whole install process for all 3.x plugins which contain attachments or direct
download links in their pages. And check if all of them are downloaded and installed properly.
And fix the code if there are any plugins failed to be downloaded.

July 3rd-9th
Implement the following ​advanced ​items in the full feature list:
● 1.3.4;
This feature involves several options towards qml files(replacing, duplicating or using the
original file). The map between each plugin and its qml files need to be carefully maintained,
and the UI of dialog box is needed to be drawn. Therefore, long time is given.

July 10th-16th
Implement the following ​advanced ​items in the full feature list:
● 1.1.8
This feature involves multi-thread programming. And the main thread needs to receive signals
from other threads that check updates or do other stuffs. I have written parallel codes before,
but still, maybe some time is needed to familiarize Qt related thread utilities.

July 17th-19th
Implement the following ​advanced ​items in the full feature list:
● 1.1.2, 1.1.3
These features mainly involve locating links from web and UI changes, and should be easy.
However, the UI that reflects the difference of 2.x plugins from 3.x and the positions of links
could be further discussed with the community.
July 20th-26th
Finish the period II evaluation​;
Implement the following ​basic i​ tems in the full feature list:
● 2.1.1
● 2.2.1, 2.2.2
The 2.1.1 and 2.2.1 are just a matter of porting the UI and codes from the old plugin manager to
Resource Manager. The codes that use the old plugin manager, such as
`MuseScore::loadPlugins()`, should be adapted.
The 2.2.2 should be easy, as I’ve already figured out how to work with the Qt tree widget.

July 27th-August 9th


Investigate the design of the following ​advanced ​items:
● 2.3.1, 2.3.2
The 2.3.1 is not ​that ​important since registering plugins just fails silently currently, which is also
an acceptable behavior. And the 2.3.2 is somewhat experimental. So I put them at the last.

August 10th-12th
● Write documentation for the usage of the new plugin manager, which describes to users
how to install plugins from store and how to manage installed plugins.
● Write recommended rules for plugin developers, specifying the recommended format of
plugin description in plugin detail pages, structure of the archive, naming of GitHub repo
branches and so on, so that new plugins published in future would be properly
recognized and downloaded by our plugin manager.
These writings should be clear in my mind once I’ve gone through previous steps.

August 13th-19th
Buffer time reserved in case.

August 20th-27th
Submit PRs(some would probably have been submitted before), write project summaries and
the final evaluation.

Bio
My name is Songchao Wang, and I’m currently a 2015 grade undergraduate student studying
CS at University of Science and Technology of China.

I enjoy programming and do have some interesting codes on GitHub.


● I have written a lot of crawlers. For example, I have contributed to the ​iGem project
implementing the forum module and the crawler to fetch genes’ data, and ​my own
project​ which can fetch entries from the oxford dictionary website. Therefore I’m
confident in handling the crawling jobs involved in this project.
● Some other interesting codes in C/C++. The ​Qr-encoder​ implements the whole encoding
algorithm for qr code from scratch and generates an image in the end. And I’m now
working on ​a project of computer graphics rendering​(it has no deadline and won’t affect
GSoC). It uses CMake and is a more amature C++ project than I’ve written before.

Besides, I’m also a ​soprano ​saxophone player with grade 10, and a member of our university’s
student orchestra, serving as the role of Oboe(because their timbres are similar...the usual case
in an orchestra lacking expensive instruments). After 2 years of suffering from playing
saxophone while reading C-major scores of Oboe directly, I now have the ability of site-reading
C-major scores without transposition;)(The soprano saxophone is in B♭ major)

I always strongly believe, the most reliable power to keep one working on a particular thing, is
his interest and love for it and his eager expectation for what we will get in the end. For me, It’s
exactly the case with this project. I really hope to work on it regardless of whether I am selected
as a GSoC participant because I know the convenience it would bring to my friends in the
orchestra and other users around the world.
Meanwhile, I believe that I’m really the one that can do this particular project pretty well, since I
have investigated the design and implementation details deeply enough, and have already
come up with a basic working implementation, which proves the concept and possibility.

I look forward to contributing more exciting features, and making MuseScore better!

Contact Info
Full name: Songchao Wang
Tel: 86-18225833998
GitHub profile: ​https://github.com/songchaow
MuseScore user: songchao(​https://musescore.org/en/user/1941193​)
Email: ​[email protected]
Blog: ​https://www.songchaow.cn​ (Most content is in Chinese though)
Nickname: songchaow (appeared in Telegram, GitHub)

You might also like