Click here to Skip to main content
15,867,568 members
Articles / Web Development / Blazor

Music Notation in Blazor - Part 2

Rate me:
Please Sign up or sign in to vote.
2.87/5 (4 votes)
31 Jul 2018MIT2 min read 11.6K   64   2  
Music notation in Blazor - Part 2

Introduction

This is the second part of the series about implementing open source music notation library Manufaktura.Controls in Blazor. The first part about Blazor 0.4 can be found here. Article about Manufaktura.Controls library can be found here.

A few days ago, a new version 0.5.1 of Blazor was released so I decided to write a new article about how the issues described in part 1 have been resolved.

Upgrading the Project from Blazor 0.4 to 0.5

The process of upgrading project from Blazor 0.4 to 0.5 is described in this article.

Updated Blazor libraries are available on Nuget. After updating, you might have to manually edit your project file and change version number of Microsoft.AspNetCore.Blazor.Cli from 0.4. to 0.5.1:

XML
<DotNetCliToolReference Include="Microsoft.AspNetCore.Blazor.Cli" Version="0.5.1" />

The way of injecting Blazor into HTML has slightly changed:

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width">
    <title>BlazorApp1</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/site.css" rel="stylesheet" />
</head>
<body>
    <app>Loading...</app> 
    <script src="_framework/blazor.webassembly.js"></script>
</body>
</html>

There are also some changes in startup classes:

C#
public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
        BlazorWebAssemblyHost.CreateDefaultBuilder()
            .UseBlazorStartup<Startup>();
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IBlazorApplicationBuilder app)
    {
        app.AddComponent<App>("app");
    }
}

After applying these changes, the project created in part 1 should run without problems.

Changes in NoteViewer Component

Blazor 0.5 enables a programmer to insert raw HTML in Razor views:

Razor
@((MarkupString)RenderScore())

In part 1, I created a RawHtml component which is not needed anymore so we can remove it from the project as well as the dependency to HtmlAgilityPack. Now, NoteViewer component looks like this:

Razor
@using Manufaktura.Controls.Model
@using Manufaktura.Controls.Rendering.Implementations

@((MarkupString)RenderScore())

@functions {

[Parameter]
Score Score { get; set; }

[Parameter]
HtmlScoreRendererSettings Settings { get; set; }

private int canvasIdCount = 0;

public string RenderScore()
{
    IScore2HtmlBuilder builder;

    if (Settings.RenderSurface == HtmlScoreRendererSettings.HtmlRenderSurface.Canvas)
        builder = new Score2HtmlCanvasBuilder
                  (Score, string.Format("scoreCanvas{0}", canvasIdCount), Settings);
    else if (Settings.RenderSurface == HtmlScoreRendererSettings.HtmlRenderSurface.Svg)
        builder = new Score2HtmlSvgBuilder(Score, string.Format
                  ("scoreCanvas{0}", canvasIdCount), Settings);
    else throw new NotImplementedException("Unsupported rendering engine.");

    string html = builder.Build();

    canvasIdCount++;

    return html;
}
}

What Has Been Fixed

The first thing worth noticing is that updating SVG now works properly. When you click Add Note button, a note is added to the staff without problems. On Firefox browser, it is added almost instantly, however in other browsers like Chrome, there is a significant lag of about 1 second. This happens because all DOM manipulation is currently done with invokes so it’s slower compared to JavaScript DOM manipulation (vide this question on Stackoverflow). I hope that the performance will improve in future releases.

In the first part, I mentioned an exception that was thrown in Rebeam method. Now this method throws a different error:

Uncaught (in promise) Error: System.NullReferenceException: 
Object reference not set to an instance of an object.
  at System.Linq.Expressions.Interpreter.LightLambda.MakeRunDelegateCtor 
  (:59341/System.Type delegateType) <0x212c460 + 0x00294> in <d4b4182dc3854440a5ca922d80e29ea1>:0
  at System.Linq.Expressions.Interpreter.LightLambda.GetRunDelegateCtor 
  (:59341/System.Type delegateType) <0x212bde0 + 0x00048> in <d4b4182dc3854440a5ca922d80e29ea1>:0
  at System.Linq.Expressions.Interpreter.LightLambda.MakeDelegate 
  (:59341/System.Type delegateType) <0x212bc50 + 0x0000e> in <d4b4182dc3854440a5ca922d80e29ea1>:0
  at System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate 
  (:59341/System.Runtime.CompilerServices.IStrongBox[] closure) <0x212b3a8 + 
  0x00028> in <d4b4182dc3854440a5ca922d80e29ea1>:0
  at :59341/System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate () 
  <0x212b238 + 0x0000a> in <d4b4182dc3854440a5ca922d80e29ea1>:0
  at System.Linq.Expressions.LambdaExpression.Compile 
  (:59341/System.Boolean preferInterpretation) <0x2103b20 + 0x0001c> in 
  <d4b4182dc3854440a5ca922d80e29ea1>:0
  at :59341/System.Linq.Expressions.LambdaExpression.Compile () 
  <0x2103908 + 0x0000a> in <d4b4182dc3854440a5ca922d80e29ea1>:0
  at Manufaktura.Controls.Extensions.StaffBuilder+<>c.<Rebeam>b__13_1 
  (:59341/System.Reflection.TypeInfo t) [0x00000] in 
  C:\Development\manufakturalibraries\Manufaktura.Controls\Extensions\StaffBuilder.cs:229

I will inform you about further progress of implementing Manufaktura.Controls in Blazor when a new version is released.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Poland Poland
I graduated from Adam Mickiewicz University in Poznań where I completed a MA degree in computer science (MA thesis: Analysis of Sound of Viola da Gamba and Human Voice and an Attempt of Comparison of Their Timbres Using Various Techniques of Digital Signal Analysis) and a bachelor degree in musicology (BA thesis: Continuity and Transitions in European Music Theory Illustrated by the Example of 3rd part of Zarlino's Institutioni Harmoniche and Bernhard's Tractatus Compositionis Augmentatus). I also graduated from a solo singing class in Fryderyk Chopin Musical School in Poznań. I'm a self-taught composer and a member of informal international group Vox Saeculorum, gathering composers, which common goal is to revive the old (mainly baroque) styles and composing traditions in contemporary written music. I'm the annual participant of International Summer School of Early Music in Lidzbark Warmiński.

Comments and Discussions

 
-- There are no messages in this forum --