0 Comments

Every few months someone asks how you can “normalize” an audio file with NAudio. And I’m usually quite reluctant to answer, because often the person asking doesn’t understand the limitations of normalizing. They simply assume it is an automatic way to make a quiet audio file louder.

So what is normalizing an audio file? It’s simply amplifying every sample in the file by the largest amount possible without causing any clipping. That’s great if the entire file is quiet, but if there’s just one sample in there that already has the maximum value, then you’re stuck. Normalization won’t do anything.

But having acknowledged that it doesn’t help in every situation, how can we implement it for files it is suitable for? Well we start by examining every sample value and picking out the loudest. That’s most easily done by letting NAudio convert the samples into floating point in the range +/- 1.0, and the AudioFileReader class will do that automatically for us.

What we’ll do is read out batches of floating point samples using the Read method and find the largest value. We’ll use Math.Abs as the maximum peak might be a negative rather than a positive peak:

var inPath = @"E:\Audio\wav\input.wav";
float max = 0;

using (var reader = new AudioFileReader(inPath))
{
    // find the max peak
    float[] buffer = new float[reader.WaveFormat.SampleRate];
    int read;
    do
    {
        read = reader.Read(buffer, 0, buffer.Length);
        for (int n = 0; n < read; n++)
        {
            var abs = Math.Abs(buffer[n]);
            if (abs > max) max = abs;
        }
    } while (read > 0);
    Console.WriteLine($"Max sample value: {max}");
}

So that finds us the maximum value. How can we use that to normalize the file? Well, first of all if the max value is 0 or greater than or equal to 1, then normalization is not possible. But if it is between 0 and 1, then we can multiply each sample by (1 / max) to get the maximum possible amplification without clipping.

AudioFileReader has a handy Volume property that we can use to amplify the samples as they are read out, and since we’ve just read the whole way through, we need to jump back to the beginning by setting Position = 0. Then we can use the convenience method WaveFileWriter.CreateWaveFile16 to write the amplified audio back to a 16 bit WAV file.

Here’s the entire normalization example:

var inPath = @"E:\Audio\wav\input.wav";
var outPath = @"E:\Audio\wav\normalized.wav";
float max = 0;

using (var reader = new AudioFileReader(inPath))
{
    // find the max peak
    float[] buffer = new float[reader.WaveFormat.SampleRate];
    int read;
    do
    {
        read = reader.Read(buffer, 0, buffer.Length);
        for (int n = 0; n < read; n++)
        {
            var abs = Math.Abs(buffer[n]);
            if (abs > max) max = abs;
        }
    } while (read > 0);
    Console.WriteLine($"Max sample value: {max}");

    if (max == 0 || max > 1.0f)
        throw new InvalidOperationException("File cannot be normalized");

    // rewind and amplify
    reader.Position = 0;
    reader.Volume = 1.0f / max;

    // write out to a new WAV file
    WaveFileWriter.CreateWaveFile16(outPath, reader);
}

Now, as I said at the beginning, normalization is only good for files that are consistently quiet throughout. But what if your files do have the occasional loud bit? In that case, what you want is a compressor or limiter effect. Compression makes the loudest bits quieter, which means that afterwards you will be able to boost the whole file without clipping. It’s certainly possible to implement a compressor in NAudio, although there isn’t a built-in one, so I’ll cover how to make one in a future post.

Want to get up to speed with the the fundamentals principles of digital audio and how to got about writing audio applications with NAudio? Be sure to check out my Pluralsight courses, Digital Audio Fundamentals, and Audio Programming with NAudio.

Serverless computing may be a relatively new concept, but it is gaining a lot of momentum, with all the major cloud providers keen to become the best hosting option for serverless architectures. Just this week Microsoft blogged about “Why you should care about serverless computing” and launched a new page devoted to serverless computing in Azure.

So I’m very pleased to announce that my latest Pluralsight course, Building Serverless Applications in Azure is now live. In the course, I demonstrate the benefits of the serverless approach by building out a simple real-world application, taking advantage of several different Azure services that fit well within a serverless architecture.

The course covers:

Of course Azure Functions (which I also have a Pluralsight course on) is one of the core building blocks for serverless applications, but Azure offers even more options such as Logic Apps, and even the new Azure Container Instances offering, which can be thought of as serverless meets docker.

What’s really exciting is the pace of innovation in the serverless world at the moment. In the last week since the course was released Microsoft not only released a new Visual Studio update that brings greatly improved Azure Functions tooling, but have also announced the Azure Event Grid – another service that is built with serverless computing in mind.

So if you’ve not dipped your toes into serverless computing yet and are wondering what the big deal is, then why not check out my new course, and see how quick and easy it is to create and deploy a serverless application in Azure.

One of the great things about serverless is that its not an “all or nothing” proposition – you can benefit from it where it makes sense, and use more traditional web hosting platforms or Virtual Machines where you need the greater control that those can offer.

I hope you enjoy the course, and I’d love to hear your feedback as well as how you’re using serverless and Azure in your own applications.

Want to learn more about how to build serverless applications in Azure? Be sure to check out my Pluralsight course Building Serverless Applications in Azure.

0 Comments

A few months ago, Microsoft announced plans to shut down CodePlex. The site will be moving into read-only mode by October.

I was an early adopter of CodePlex and had 14 projects hosted there. It had been obvious for several years that CodePlex was slowly dying and it’s been over two years since I moved NAudio over to GitHub, a move that made a lot of sense.

But I needed to make a decision about the other projects I had on CodePlex. One of them, Skype Voice Changer, was in fact my greatest ever hit, having been downloaded over 3 million times (and went on to have an interesting journey of its own)! Many of my other projects were simple audio utilities or games, and I also made quite a few custom Silverlight controls. Obviously most of these projects are effectively obsolete now.

However, CodePlex kindly provided a way to easily import your projects into GitHub, and it wasn’t even too hard to bring along the documentation/wiki as well. So I’ve imported most of them into GitHub and turned the documentation into markdown files. Despite the fact that these are mostly dead/done projects, they do contain a bunch of XAML and audio related code snippets that may still be of benefit to someone in the future so I’m glad they can live on at GitHub.

So the only thing that remains is to say thank you to everyone who worked on CodePlex. The decision to shut it down makes sense, but I am grateful for the service it provided me over the past decade. A few things I’m thankful for…

  • When it launched, it was the best and easiest place to host .NET open source projects (I’d previously failed miserably to host an early version NAudio on sourceforge with CVS)
  • It introduced me to distributed version control thanks to adding Mercurial support
  • I made connections with several outstanding open source developers
  • The Developer Media ads were a small but welcome financial return on the time spent creating open source software
  • ClickOnce hosting and the ability to embed Silverlight apps in your docs were nice touches that other project hosting sites didn’t offer
  • Providing an easy mechanism to migrate my source code and docs away to GitHub (hopefully the discussion and issues will also be exportable soon too).

So goodbye CodePlex, and thanks for being part of my journey as an open source developer.

0 Comments

Azure App Service allows you to configure an external Git repository from which it can pull down code from. This works for both Web Sites and Function Apps, and can be configured as part of your ARM template.

But once you’ve configured the location of the external repository, simply pushing new commits to that external git repository won’t cause your website/function app to automatically update.

Instead you need to go into the Deployments section of the portal and click the Sync button:

image

When you click sync, it pulls down any new commits from the external git repository, and deploys them for you.

But how can we automate this process? We don’t want to have to manually go into the portal as part of our deployment. Here’s two ways I found…

Method 1 – PowerShell

The first technique uses Azure PowerShell. I’ll assume you’re already logged in and have the correct subscription selected. You can use these commands to do that if you’re new to Azure PowerShell.

Login-AzureRmAccount
Select-AzureRmSubscription –SubscriptionName "My Sub"

Now, so long as we know the name of our WebSite/Function app and the resource group it is in, we can request a sync with the following command (thanks to David Ebbo):

Invoke-AzureRmResourceAction -ResourceGroupName "MyResourceGroup" -ResourceType Microsoft.Web/sites -ResourceName "MyFuncApp" -Action sync -ApiVersion 2015-08-01 -Force –Verbose

Method 2 – Azure CLI

I’ve only just started using the Azure CLI, but I like what I’ve seen so far. Its nice and simple to work with and you can easily explore the available commands just by typing az.

Just like with PowerShell we do need to make sure we’re logged in and have the correct subscription selected, which we can do with:

az login
az account set –s "My Sub"

And now to request a sync, we can call the sync action for our deployment source. Here’s the syntax for a function app

az functionapp deployment source sync –g MyResGroup –n MyFunctionApp

If it was a webapp instead, it’s pretty much the same:

az webapp deployment source sync –g MyResGroup –n MyWebApp

Method 3 – App Service Continuous Deployment Alternatives

There are several other ways to tackle this problem, by integrating with VSTS, setting up web hooks, or using local git repositories but the techniques described above will be useful if you picked the external git repository option.

Want to learn more about how easy it is to get up and running with Azure Functions? Be sure to check out my Pluralsight course Azure Functions Fundamentals.

0 Comments

I’ve released an update to NAudio as it’s been a while since the last one. This one is mostly bug fixes and a few very minor features:

  • MidiFile can take an input stream
  • WaveOut device –1 can be selected allowing hot swapping between devices
  • AsioOut exposes FramesPerBuffer
Want to get up to speed with the the fundamentals principles of digital audio and how to got about writing audio applications with NAudio? Be sure to check out my Pluralsight courses, Digital Audio Fundamentals, and Audio Programming with NAudio.