Sheet Music Displays

I recently had an inquiry about creating an app to transpose and then display a MusicXML file on a mobile. The client was interested in it using the Open Sheet Music Display library which is a JavaScript library created using TypeScript.
http://opensheetmusicdisplay.org

Since I have a background in music composition and arranging the music part was trivial. I found MusicXML fairly straightforward too so the transposition part was easy.

What was a headache was getting the part XML to display once it had been transposed. Since the interest was in a mobile version I decided to develop with Xamarin and C# which I am very familiar with. The application uses the Xamarin FilePicker plugin to select a file from an Android folder, iCloud on iOS and the Documents folder on Windows 10 UWP. Though the picker is set for .xml and .musicxml file types for Android and UWP I could not find proper iOS UTType for those types so it just displays all the files available.

Once the file is selected it is read into memory as a string.

1
2
3
var stream = pickedFile.GetStream();
StreamReader streamReader = new StreamReader(stream);
string xml = await streamReader.ReadToEndAsync();

Then the XML is loaded into a new JavaScript XmlDocument:

1
2
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

Next the HTML file used for displaying the sheet music part is loaded into a Xamarin Forms Webview:

1
2
var src = LoadHTMLFileFromResource();
webview.Source = src;

The HTML file contains the short piece of JavaScript which will render the music:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<body>
<script src="opensheetmusicdisplay.min.js"></script>
<div id="osmdCanvas"></div>
<script type="text/javascript">
function render_osmd() {
var ret = "yes";
var osmd = new opensheetmusicdisplay.OpenSheetMusicDisplay("osmdCanvas");
if (osmd == null)
ret = "no";
else {
osmd.load(str).then(
function () {
osmd.render();
}
)
}
return ret;
}
</script>
</body>

When the HTML is loaded we must wait for it to be displayed. Unfortunately the Xamarin Webview does not let us know (to my knowledge) that the HTML has been loaded so the JavaScript can be invoked. So I added a 3 second thread delay which takes care of that problem:

1
2
3
4
5
6
7
8
9
10
await Task.Delay(3000); // let the page load -- needed longer for the x64
try
{
var js = "var str = '" + outerxml + "'; render_osmd(); ";
string result = await webview.EvaluateJavaScriptAsync(js);
if (result.Contains("yes"))
Debug.WriteLine("score rendered.");
else
Debug.WriteLine("score not rendered.");
} catch(Exception e)

Hopefully the part is then displayed in the webview. Much of this technique is described in the Xamarin Tutorial “Working With Webviews”:
http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/webview

Currently the Open Sheet Music Library is still beta. There were also two other open source sheet music display libraries, one in C++ and one in C# that was not complete for use in Xamarin.

Example source code:
https://github.com/brianjtools/xamosmd

Updating Part Two

If you were able to read last year’s post about updating this blog then you were lucky. I mentioned before that this site was unreachable for awhile do to a DNS mixup. Seems it happened again. So this time I decided to drop the old static site generator, Hugo, and am trying Gatsby. For one thing Hugo use Go as a language and I was not that familiar with it. Gatsby uses Javascript which I am familiar with. So here is the site in Gatsby.

Cross Platform Update: I finally did get a MacBook Air a little over a year ago and have been publishing iOS apps. Also planned is a Mac app too since there are very few in that app genre. This will also be the basis of another cross platform app with a different layout. The current Xamarin project has two sets of code: one for portrait (phones) and one for tablets and desktop in landscape.

Before I actually began that project I had played with responsive design in C#. But users seemed to want the tablet layout for Android similar to my smaller app except they didn’t buy, they just got the phone version instead since it works on both phone and tablets. I was also unaware that iPads are 4:3 aspect ratio not 16:9. There are Android tablets that are 4:3 but Android letterboxes if your layout is 16:9 and Apple doesn’t. Allowing iPads to use the portrait view presented a very unacceptable distorted layout unfortunately so the iPhone version is phone only. So some users were disappointed if they had to buy both versions if they wanted to run the app both on iPad and iPhone. Needless to say the new app will be responsive design and one set of code!

Software development continues to get crazier and crazier. Google told Android developers that we needed to support 64-bit. Actually 64-bit doesn’t exactly improve my app any, it just made the apk 5MB larger. Even working on a game for Android a 64-bit version wasn’t any faster but was actually slower (however that may be the inexpensive 64-bit tablet I’ve been testing on). The real benefit of 64-bit is larger addressing space but I doubt if Android phones are going to have mega terabyte drives anytime soon.