0 Comments Posted in:

I'm pleased to announce that NAudio 1.10 is available on NuGet. This version doesn't contain too many features, but the most notable change is that it now adds support for .NET Core 3 (thanks to a contribution from jwosty). This allows access to ASIO, WaveIn and WaveOut in .NET Core 3.0 applications that are running on Windows.

Here are the key changes in this version:

  • #574 Support ASIO and WaveIn/WaveOut in .NET Core 3.0
  • #441 recognise MP3 Xing headers with 'Info' magic
  • #584 Fixes to WasapiOut.GetPosition
  • #515 Switched from Fake to Cake build script

Part of the impetus for releasing this version of NAudio was that I heard that a well-known speaker recently complained at a conference that this particular PR hadn't been accepted yet. I can understand his frustration, but I let me take a moment to share a few reasons why I sometimes take a long time to accept pull requests (and sometimes don't accept them at all):

  • NAudio is just a spare time project, and I have many other commitments on my time. In practice this means that I only occasionally have time to work through the PR backlog.
  • It's surprisingly common for PRs to contain bugs and often not even build. One thing that has really helped on this front is hooking up an Azure DevOps Pipeline to automatically build every PR. This gives me immediate visibility of whether a PR is ready for inspection or not. Unfortunately in this particular case, the PR didn't build on the CI server or on my local machine, and it required a few hours of experimenting to work out why.
  • The nature of NAudio means that lots of functionality cannot meaningfully be tested with unit tests. I need to run on different operating systems, bit depths, and with different sound cards, and actually listen to the audio being produced to be confident that things are still working. That means I need time for manual testing before a new release.
  • Whenever I accept a new feature into NAudio, end users expect me to support it. It's very rare for the original PR author to hang around providing help, and usually they don't create any documentation either. So I need to understand the code well enough to document and support the feature going forwards before completing the PR.

With that said, I am very grateful to everyone who has submitted PRs, bug reports, and answered questions on GitHub and Stack Overflow, and please accept my apologies if I have been slow to respond to your contribution or question.

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.

0 Comments Posted in:

As you hopefully all know, it really is important that your website uses HTTPS. This used to involve a rather cumbersome process of buying and installing a custom SSL certificate. But with an Azure App Service hosted website with a custom domain, there are now a few free options available.

You can automate the process of getting a free certificate from Let's Encrypt, and there is also a very nice new preview feature of App Service that offers free auto-renewed SSL certificates (although unfortunately it doesn't support naked domains yet).

My favourite option at the moment however is to use Cloudflare which is remarkably easy to migrate to assuming you've already set up your domain name to point at your Azure Website. Instructions on how to do that are available here if you need help with that.

Cloudflare not only gives you a free SSL certificate, but keeps it auto-renewed, and also offers some added-value free services such as caching content to reduce the amount of traffic hitting your website.

I recently decided not to renew a paid-for SSL certificate for one of my Azure hosted sites and switch it over to the Cloudflare free offering. I ran into a couple of minor gotchas along the way, so I thought I'd take the opportunity to write up what learned.

The first step was straightforward - I onboarded the domain name at Cloudflare in the usual way, and it read my existing DNS entries, and gave me the new Cloudflare nameservers to configure for my custom domain.

However, things didn't go as smoothly as normal, with a nasty ERR_SSL_VERSION_OR_CIPHER_MISMATCH showing whenever I tried to access my site over HTTPS.

Gotcha 1 - verifying the domain name

My first attempt at fixing the issue was going to my Azure Website and removing my old certificate binding to my paid certificate. I then unbound the custom domain and attempted to rebind it to the website. However, I then ran into another issue - I couldn't verify the custom domain. The Azure Portal asks you to create a DNS entry that it uses to verify ownership of the domain. For example, it might ask you to create a CNAME with the value of mywebapp.azurewebsites.net.

It's quite simple to create the CNAME record in the Cloudflare control panel, but Azure App Service won't see it by default, if the "proxy status" is set to "Proxied". You need to set it to "DNS only", and then your ownership can be verified. You can set it back to "proxied" immediately after if you want.


I was able to resolve this issue thanks to this helpful answer at Stack Overflow.

Gotcha 2 - re-issue Cloudflare universal certificate

I still hadn't fixed the ERR_SSL_VERSION_OR_CIPHER_MISMATCH and that turned out to be due to my Cloudflare universal certificate not having been issued properly for some reason. Normally, in Cloudflare you will see something like this with a universal certificate for your domain name (skypevoicechanger.net in this example)


However, if you don't have any universal certificates showing here, then you need to go to this part of the Cloudflare control panel and select "Disable Universal SSL". Then after 10 minutes, re-enable it, and your universal certificate should get generated.


That got me up and running again and resolved the ERR_SSL_VERSION_OR_CIPHER_MISMATCH problem.

Getting to full (strict) encryption mode

The final step I wanted to take was to use the "Full (Strict)" encryption mode, rather than "Full".


Essentially what happens in "Full" mode is that traffic from Cloudfare to your host server is encrypted, but isn't too fussy about whatever certificate it receives on the host server. This works fine with App Service, because it does have an SSL certificate for mywebapp.azurewebsites.net, although obviously it doesn't have one for your custom domain.

To get the best possible security, you can ask Cloudflare to create a certificate for you (which has a long lifetime), and then install that manually on your Azure App Service Web App.

Creating the Cloudflare "Origin certificate" can be done from their control panel here:


By default this wwill create a certificate with a 15 year lifetime:


The certificate consists of two parts, one called the "PEM" and one called the key. You should copy these and save them each to a text file.


In theory now we should simply be able to install this certificate onto Azure App Service, but there is one final step we need to do, and that is convert it to pfx format. That's needed because that's the format Azure App Service expects the certificate in.

Gotcha 3 - creating a pfx

You can convert a PEM certificate to pfx using openssl, although if you are on Windows, that's a bit of a pain, because it's not available out of the box. However, the Windows Subsystem for Linux is ideal for this.

I opened up a Windows Terminal WSL tab, and changed directories to the folder I'd saved my PEM and key files in:

cd /mnt/c/Users/markh/Documents/

Next, I issued the following openssl command to convert from PEM to pfx. openssl is available out of the box in WSL.

openssl pkcs12 -inkey mykey.key -in mycert.pem -export -out mycert.pfx

This will prompt you for an "export passport" - so enter something secure that you'll remember.

Now we can install this certificate on our Azure Website. We go into "TLS/SSL certificates" and choose "Upload Certificate"


This lets us upload the pfx we just created. You'll need to enter the certificate password you just created.


Then in the "bindings" tab, we can add a binding for each domain name (I added both the naked domain, and the www subdomain)


With these bindings in place, we can now go back to Cloudflare and switch over to Full (strict) mode


And so now we have free SSL/TLS for our domain name with nothing additional to be done for the next 15 years (by which time hopefully the Azure App Service free certificates will be upgraded to support naked domains)!

By the way, while I was getting all this working, I found this very helpful tutorial that helped me through a few difficulties along the way. In it the author walks through many of the same steps, only using Win32OpenSSL instead of WSL.


Let me start by wishing you all a happy new year. It's that time once again (previous years: 2018, 2017, 2016, 2015, 2013 where I post a few reflections on the past year, and think about what's ahead.

Travel and conferences

2018 was memorable for speaking at my first ever conferences, and visiting the USA for the first time. And in 2019 I was able to do both again. I spoke on Azure Durable Functions at Ignite the Tour London in February, and on Technical Debt at Techorama Netherlands in October. I also went to my second Microsoft MVP Summit in March, and ended up making a second visit to Microsoft in Seattle a couple of months later for some business meetings related to my day job at NICE.

Another highlight was to attend the first ever Pluralsight Author Summit in Europe in May. Despite having been an author for them for many years, I had never been to a Pluralsight event, so it was amazing to meet lots of the staff and other authors for the first time.

Pluralsight courses

A lot of my effort this year went into the release of four Pluralsight courses. I started by completely re-recording my Azure Functions Fundamentals. This has been my most popular Pluralsight course by a long way, so I wanted to make sure it was as up to date as possible. I completed that in April, and then in July I released an update to my Microsoft Azure Developer: Deploying and Managing Containers course, which included a new module on container security. This course is part of a partnership with Microsoft Learn which means you can watch it for free even if you're not a Pluralsight subscriber.

Then later in the year, I worked on two courses for a new Microservices Architecture learning path at Pluralsight. First was Microservices Fundamentals released at the end of October, followed by Building Microservices completed in December. They kept me extremely busy over the past four months, so apologies for the reduced blogging output during that period.


Azure remains a huge focus for me at the moment. My day job as a cloud architect at NICE has given me a constant stream of interesting challenges and new technologies and practices to learn. There are a lot of exciting developments in the world of cloud native computing at the moment, but it can sometimes seem a bit overwhelming trying to keep up with it all.

Sadly, the continued focus on Azure meant that there was very little time to work on any audio related code, although I was able to release NAudio 1.9 back in May.

Plans for 2020

My calendar for the start of 2020 is already starting to fill up, as I've agreed to give two talks at Ignite the Tour London later this month, and I'll be at NDC London helping out on the Microsoft stand. I'd love to meet any of you who are at those events.

In March I'll be back in Seattle for the MVP Summit, and then attending the Pluralsight author summit in London. I'm also going to be producing updates to at least two of my Azure Pluralsight courses to keep things up to date.

I expect a lot of my content this year will continue to be focused on Azure. I'm currently doing a lot of prototyping with Cosmos DB and AKS, and I'm keeping a close eye on dapr.

But I also hope to keep doing bits and pieces of audio related programming, as well as trying to find more time for making music, which is one of my favourite hobbies. I've reorganized my home office this Christmas to keep my instruments close at hand, allowing me to mix a bit of fun in with work.

my desk

Finally, a huge thank you to everyone who has watched my courses, attended my talks and read my blog. I especially appreciate all the feedback you've given me. It's great to know that the content I am producing is proving helpful for people.