0 Comments

Here’s a code sample I’ve been meaning to share on my blog for years. NAudio already has a built-in SignalGenerator class which can generate sine waves as well as various other waveforms. But what if you want to implement “portamento” to glide smoothly between frequencies?

One simple way to do this is to make use of a “wavetable”. Basically we store one cycle of a sine wave in a memory buffer, and then to work out what the next sample to be played is, we move forward a certain number of slots in that buffer and read out the value. If we go past the end of the buffer we simply start again.

If we call the current position in the waveform the “phase” and the number of steps in the wavetable we must move forward the “phase step”, then when the target frequency is changed, instead of immediately recalculating a new “phase step”, we slowly change the current phase step until it reaches the desired phase step.

It’s quite a simple technique, and the great thing is that it works for any waveform, so you could quite easily do the same with square or sawtooth waveforms.

Here’s a really basic implementation of this, which allows you to customise the portamento time. I meant for this setting to be in seconds, but I think I’ve got it slightly wrong as when you set it to 1.0 it seems to take longer than a second to reach the target frequency.

class SineWaveProvider : ISampleProvider
{
    private float[] waveTable;
    private double phase;
    private double currentPhaseStep;
    private double targetPhaseStep;
    private double frequency;
    private double phaseStepDelta;
    private bool seekFreq;

    public SineWaveProvider(int sampleRate = 44100)
    {
        WaveFormat = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, 1);
        waveTable = new float[sampleRate];
        for (int index = 0; index < sampleRate; ++index)
            waveTable[index] = (float)Math.Sin(2 * Math.PI * (double)index / sampleRate);
        // For sawtooth instead of sine: waveTable[index] = (float)index / sampleRate;
        Frequency = 1000f;
        Volume = 0.25f;
        PortamentoTime = 0.2; // thought this was in seconds, but glide seems to take a bit longer
    }

    public double PortamentoTime { get; set; }

    public double Frequency
    {
        get
        {
            return frequency;
        }
        set
        {
            frequency = value;
            seekFreq = true;
        }
    }

    public float Volume { get; set; }

    public WaveFormat WaveFormat { get; private set; }

    public int Read(float[] buffer, int offset, int count)
    {
        if (seekFreq) // process frequency change only once per call to Read
        {
            targetPhaseStep = waveTable.Length * (frequency / WaveFormat.SampleRate);

            phaseStepDelta = (targetPhaseStep - currentPhaseStep) / (WaveFormat.SampleRate * PortamentoTime);
            seekFreq = false;
        }
        var vol = Volume; // process volume change only once per call to Read
        for (int n = 0; n < count; ++n)
        {
            int waveTableIndex = (int)phase % waveTable.Length;
            buffer[n + offset] = this.waveTable[waveTableIndex] * vol;
            phase += currentPhaseStep;
            if (this.phase > (double)this.waveTable.Length)
                this.phase -= (double)this.waveTable.Length;
            if (currentPhaseStep != targetPhaseStep)
            {
                currentPhaseStep += phaseStepDelta;
                if (phaseStepDelta > 0.0 && currentPhaseStep > targetPhaseStep)
                    currentPhaseStep = targetPhaseStep;
                else if (phaseStepDelta < 0.0 && currentPhaseStep < targetPhaseStep)
                    currentPhaseStep = targetPhaseStep;
            }
        }
        return count;
    }
}

I’ve packaged this up into a very simple WPF application available on GitHub for you to try out. One word of warning, sine waves can be ear piercing so start off with the volume set very low before trying this out.

image

Please note, my wavetable code is extremely rudimentary. If you want to go into the science behind doing this properly, make sure to check out Nigel Redmon’s excellent wavetable series at Ear Level Engineering. This involves creating multiple wavetables to cover different frequency ranges and using linear interpolation (I just truncate the phase to the nearest array entry).

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

In this post I will demonstrate how you can implement varispeed playback with NAudio using the excellent SoundTouch library. To do so, I’ve prepared a very simple Windows Forms Application that lets you load an audio file and play it at varying speeds.

The key parts of the application are as follows. First of all, the SoundTouchInterop32.cs and SoundTouchInterop64.cs files include the necessary PInvoke signatures to call the x86 and x64 versions of SoundTouch respectively. These are SoundTouch.dll and SoundTouch_x64.dll. Make sure these DLLs are available in the path when running.

I’ve also created a wrapper class called SoundTouch which simplifies access to SoundTouch and calls the correct PInvoke method depending on whether the process is 64 bit or not.

The next part is VarispeedSampleProvider. This implements NAudio’s ISampleProvider interface so it can be easily inserted into a signal chain. It also exposes a PlaybackRate property which can be set to 1.0 for regular speed and 2.0 for 2x playback etc.

public VarispeedSampleProvider(ISampleProvider sourceProvider, 
    int readDurationMilliseconds, SoundTouchProfile soundTouchProfile)

The constructor for VarispeedSampleProvider takes a source provider, which is the input stream you want to speed up (in our example an audio file), the readDurationInMilliseconds, which allows control of how much will be read from the source provider in a single read. Obviously when you are speeding up or slowing down, the amount of audio you need to read from the source is different from the amount of time taken to play that audio. Something like 100ms will be fine to use here.

Finally, the SoundTouchProfile allows us to specify what SoundTouch options we want to use. There are a few switches you can experiment with which adjust quality and performance. The most significant is UseTempo. In tempo mode, SoundTouch will pitch compensate when you change speed, so the music will remain at the same pitch, just a different speed. This avoids the “chipmunk effect” when you play back at higher speeds. In the demo app I let you switch between modes while playback is stopped.

image

All that remains is to create an AudioFileReader, pass it into the VarispeedSampleProvider, and then pass that to the output device (WaveOutEvent in our example) to be played.

The one other thing worth mentioning in the demo project is that I allow you to reposition in the file, and when you do so, it’s a good idea to tell SoundTouch that a reposition has taken place so internal buffers can be flushed. This is done by calling Reposition on the VarispeedSampleProvider.

Want to see the code? You can access it on GitHub.

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

I had the privilege of speaking at a brand new Pluralsight Meet the Authors event in London last week, organized by Elton Stoneman. I decided to do a LINQ tips and tricks session based on my new Pluralsight course “More Effective LINQ”.

I had just enough time for seven tips, so here they are…

1. Use LINQPad

I’m a huge fan of LINQPad, and I’ve banged on about it enough on this blog before so I won’t say much more than buy yourself a license! You won’t regret it. A fantastic light-weight mini-IDE for all your code experiments.

2. Think in Patterns

Pretty much anywhere you are using a foreach loop is an opportunity to use LINQ. You just need to spot the patterns. For example this code snippet below:

string beginsWithJ = null;
foreach (var person in people)
{
    if (person.StartsWith("J"))
    {
        beginsWithJ = person;
        break;
    }
}

… can be replaced with a single line of LINQ …

string beginsWithJ = people.FirstOrDefault(p => p.StartsWith("J"));

In fact, if you’ve been using LINQ for a while, seeing these kind of transformations will start to come naturally to you. ReSharper is also very good at pointing out where you can refactor a foreach loop into a single LINQ statement, making your code much more succinct and expressing your intent more clearly.

3. Use Pipelines

Where LINQ really starts to shine is when you start to combine and “chain” together these LINQ extension methods to form what are sometimes called “pipelines”. To show off how powerful they can be, I solved one of my LINQ challenge problems. Why not try one of these yourself and compare your answers with mine?

4. Be Lazy

Take a look at this method, which does some processing on a bunch of filenames. Can you see a problem?

void SomeFunction(IEnumerable<string> fileNames)
{
    fileNames.ToArray()
    foreach (var s1 in fileNames)
    {        
        Console.WriteLine(File.ReadAllText(s1));
    }

    foreach (var s2 in fileNames)
    {
        Console.WriteLine($"{s2} is {new FileInfo(s2).Length} bytes long");
    }
    
    var longestFileName = fileNames.Max(s => s.Length);
    var shortestFileName = fileNames.Min(s => s.Length);
}

If you said “multiple enumeration”, you’re right! This method enumerates through the fileNames sequence four times. That might not be an issue, if filenames is for example a List<string>. But because of “deferred execution” we don’t know whether each time through we’ll get the same results. We also can’t be sure that it will enumerate quickly, because there could be disk IO going on when we enumerate. In this example, a quick fix would be to call ToList on fileNames to get it in memory, allowing us to safely and quickly enumerate through several times.

5. Extend LINQ

LINQ comes with a fantastic built in library of extension methods, but there are times when you need something that is missing. For example LINQ doesn’t have a MaxBy method, which you need for doing things like find the book with the most pages. Now it’s true that you can often find clever ways of combining existing LINQ operators, or use Aggregate, the Swiss Army knife of LINQ methods, but you can end up with poorly performing or hard to read code if you do that.

So it’s a great idea to learn how to create extension methods, as they can greatly benefit the readability of your code. The good news is that for LINQ, most of the extension methods you could ever want have already been created for you in the fantastic MoreLINQ library. If you haven’t tried it yet, I can highly recommend it. It turned out to be super helpful when I solved the Advent of Code challenges in December.

6. Optimize Performance

How fast is LINQ? If you need the fastest performance, is it better to abandon LINQ and just use for loops for the ultimate speed? In this demo I showed how there is a small performance penalty for using LINQ but it can be overcome by using libraries like LinqOptimizer or using Parallel LINQ (PLINQ). Check out this very simplistic performance test to get a feel for what kind of performance gains are possible.

7. Understand the Underlying SQL

In this tip I showed how although LINQ to Entities usually creates excellent SQL queries on your behalf, it is in fact quite easy to accidentally do things that result in dreadful performance. A classic blunder is to insert a ToList into the middle of a query because you did something that Entity Framework couldn’t translate to SQL. So in this dreadful example we end up retrieving the entire contents of the Albums table into memory, and then go on to perform numerous additional SQL queries in order to request the artist name for each album.

Albums
   .ToList()
   .Where(a => a.Artist.Name.Count(c => c == ' ') > 2)
   .OrderBy(a => a.Artist.Name)
   .Select(a => new { Artist = a.Artist.Name, a.Title })
   .Take(5)

The moral of the story is to understand what a Select N+1 problem is, and what can cause it, and to keep an eye on what SQL is actually being generated under the hood by Entity Framework (or LINQ to SQL).

Want More?

Obviously 40 minutes was nowhere near enough time to say all that needed to be said on these topics, so do check out my More Effective LINQ Pluralsight course if you want to go deeper.

Want to learn more about LINQ? Be sure to check out my Pluralsight course More Effective LINQ.

0 Comments

Its a little bit embarrassing to admit, but if you were to ask me what my favourite guitar solo of all time was, I’d probably opt for the two solos in the Carpenters’ 1972 hit Goodbye To Love. Certainly it was one of the ones I most wanted to master as a teenager learning the guitar.

So I set about seeing if I could transcribe it. I listened again and again and although I worked out most of the notes, there were two phrases in the solo that I simply couldn’t figure out. Whatever notes Tony Peluso was playing, didn’t seem to exist on my guitar.

Fast forward 20 years, and I stumbled across this video on youtube of someone playing along with the solo with a close-up of the fretboard. Suddenly everything fell into place. The mysterious techniques that eluded me all these years turned out to be relatively simple, and within the hour I was finally living my childhood dream and playing the solo the way it was meant to be played.

Now what’s this got to do with programming…? Well, one of the best ways to learn how to do something is to watch someone else doing it.

And the great news is, that just like musicians can type in the name of almost any song to YouTube and find a tutorial on how to play it, programmers have an unprecedented opportunity to be nosey and find out exactly what tricks and techniques our fellow developers are using to produce their own coding works of art.

In fact, I think if you want to improve as a programmer you should actively seek opportunities to read other people’s code and explore how their programs work.

Now admittedly when you do this, sometimes what you discover will barely make any sense to you at all, and other times what you discover will be disillusioning – it’s all just a horrible hack! But it’s worth doing it for those times that you pick up a real gem of an idea that stays with you for the rest of your career and finds its way into all your programs.

But how can you be nosey and find out what magical techniques your fellow programmers know about that you don’t? Well, there’s loads of ways.

First of all, use the F12 developer tools in your browser. The great thing about the web is that nothing is secret (hmm I didn’t phrase that very well did I?). You want to know how they got that cool visual effect? Right-click, inspect element, and the CSS secrets will be laid bare. Want to know how they implemented that awesome animated drag and drop effect? Well, even if the JavaScript has been minified and uglified, there are usually enough clues to point you to whatever JQuery plugin or JavaScript library was used.

Second, inspect the network traffic. Browser developer tools can help you out here too, as can tools like Fiddler and Wireshark. For example, I’ve had to learn how to secure web APIs with OAuth in the last year, and one of the things that helped the most was actually looking at the HTTP traffic and seeing for myself how the bearer tokens were being passed in the web requests.

Third, open source is a treasure trove of fresh ideas. Often if you are learning a new technology you can find a simple project that shows it being used in a real world scenario. For example, Shawn Wildermuth recently open sourced his new blog written in ASP.NET Core RC1.

Fourth, if you work with others, volunteer to code review. The benefits of code reviewing are well known in terms of finding bugs, but an important side benefit is that they expose the reviewer to new programming techniques or patterns they might not be familiar with.

And finally, of course, the thing I love most about Pluralsight courses and other similar software training video resources is that you get to see the code. I’ll quite often have Visual Studio open while I watch a course and pause the video so I can try it myself. Pretty much the same thing as I do when I’m learning to play a guitar solo from YouTube.

So why not decide to be a bit more nosey? Whose code have you learned the most from? Let me know in the comments.

0 Comments

So the day 13 Advent of Code challenge had a bit of a familiar feel to it – really it was day 9’s Travelling Santa Problem with a different spin on it. But it was still a fun challenge, and another chance in C# to use a whole host of MoreLinq methods.

Here’s my C# solution, using no less than five MoreLinq methods (Permutations, MaxBy, Prepend, Concat and Pairwise)

var realInput = File.ReadAllLines("day13.txt");
var rules = realInput
    .Select(s => Regex.Match(s, @"(\w+) would (lose|gain) (\d+) happiness units by sitting next to (\w+)\.").Groups.Cast<Group>().Skip(1).Select(g => g.Value).ToArray())
    .Select(p => new { A = p[0], B = p[3], Gain = int.Parse(p[2]) * (p[1] == "lose" ? -1 : 1) });
var people = rules.Select(r => r.A).Distinct().ToList();
var lookup = rules.ToDictionary(r => $"{r.A}-{r.B}", r => r.Gain);

// part B add me
people.ForEach(p => { lookup[$"Mark-{p}"] = 0; lookup[$"{p}-Mark"] = 0; });
people.Add("Mark");

people.Skip(1).Permutations()
    .Select(p => p.Prepend((people[0])).Concat(people[0]).Pairwise((a, b) => new { a, b }))
    .Select(p => new
        { Plan = p,
          Happiness = p.Sum(x => lookup[$"{x.a}-{x.b}"] + lookup[$"{x.b}-{x.a}"]) })
    .MaxBy(p => p.Happiness)
    .Dump(); // a = 664, b = 640

And in F# I had to make do without the power of MoreLinq, but I reused the permutations function I found from day 9, and the F# library already had everything else I needed.

let parseRule rule =
    let p = Regex.Match(rule, @"(\w+) would (lose|gain) (\d+) happiness units by sitting next to (\w+)\.")
                    .Groups
                    |> Seq.cast<Group>
                    |> Seq.skip 1
                    |> Seq.map (fun g -> g.Value)
                    |> Seq.toArray
    (p.[0],p.[3]), (int p.[2]) * (match p.[1] with | "lose" -> -1 | _ -> 1) 
    
let rules = "day13.txt" |> File.ReadAllLines
            |> Seq.map parseRule
            |> Seq.toList

// Jon Harrop F# for Scientists ( http://stackoverflow.com/a/3129136/7532
let rec distribute e = function
  | [] -> [[e]]
  | x::xs' as xs -> (e::xs)::[for xs in distribute e xs' -> x::xs]

let rec permute = function
  | [] -> [[]]
  | e::xs -> List.collect (distribute e) (permute xs)

let findHappiestSeatingPlan rules = 
    let people = rules |> Seq.map (fun ((a,b),g) -> a) |> Seq.distinct |> Seq.toList 
    let lookup = rules |> dict
    let getPairHappiness (a,b) =
        if lookup.ContainsKey (a,b) then lookup.[(a,b)] + lookup.[(b,a)] else 0

    let first = people.Head
    people.Tail
    |> permute
    |> List.map (fun p -> (first::p, seq { yield first; yield! p; yield first } 
                            |> Seq.pairwise |> Seq.sumBy getPairHappiness))
    |> Seq.maxBy snd

findHappiestSeatingPlan rules |> Dump // 664

findHappiestSeatingPlan ((("Mark",""),0)::rules) |> Dump // 640
Want to learn more about LINQ? Be sure to check out my Pluralsight course More Effective LINQ.