Friday 23 October 2009

The “Unlegacy my Code” Kata

Daily TDD Kata

I’ve read a number of blog posts recommending doing a daily TDD ‘kata’ recently. For those unfamiliar with the concept, essentially you attempt to solve a simple programming task using TDD. The problems are often simple mathematical challenges, such as finding the prime factors of a number, or creating a calculator.

You limit yourself to 30 minutes to work on the problem. One of the goals of doing this is to speed up the way you work. For this reason, many people recommend doing the same kata many times, just like a musician would practice the same piece daily, gradually improving in speed, fluency and accuracy.

Benefits

There are several benefits to taking the time each day for a coding warm-up.

  • Learning the TDD way of working: red, green, refactor
  • Learning a unit testing or mocking framework
  • Stretching your brain to see if you can come up with an even more elegant solution than last time
  • Mouseless programming (learning to use keyboard shortcuts)
  • Solving a familiar problem in a new language
  • Learning how to apply a design pattern
A Possible Weakness?

While I think these benefits are great, I do think most of the kata examples I have seen suffer from a weakness. And that is that you are always testing something that is inherently easy to test. After all, what could be easier to write unit tests for than an Add method? This can mean that when you transition to attempting to write tests for your “real” code, you can fall at the first hurdle, as the “arrange” part of your test is horribly complicated, and you have no idea what to do for the “assert” part.

Introducing the “Unlegacy my code” Kata

Legacy code has been described as “code without tests”. Which means that unless your your development team is comprised of TDD champions, you likely have a lot of “legacy code”. Recently I decided I would try my own variation on a daily kata, that would go like this:

  1. Load up the source code of the application you are working on.
  2. Choose a class or method that is not covered by any existing unit tests (preferably something you are currently working on).
  3. Give yourself a maximum of 30 minutes to create a meaningful unit test.
  4. If it passes, check it in, and congratulations, you now have slightly less legacy code than before.
  5. If it fails, rollback and get on with your day’s work. Hopefully you learned something from the experience. You could write up a memo on what is wrong with the design of the class you tried to test. And you could always have another go at it tomorrow.
Problems you will run into

This kata will not necessarily be straightforward. Here’s the two main difficulties you will encounter:

1. Tight Coupling & Hidden Dependencies.

You may find that it is almost impossible to instantiate an instance of the class you want to test because of its dependencies (often hidden through the use of singletons). Sometimes your 30 minutes is up before you have even managed to successfully instantiate the class.

2. Multiple Responsibility Syndrome.

Classes that fail to adhere to the “Single Responsibility Principle” often fail spectacularly. They are responsible for everything from the printout of wage slips to the launching of nuclear warheads. They talk to the database, the file system, the network, the registry, and create a few background threads too. This means that they typically have dozens of dependencies unrelated to the behaviour you want to test. And when you call a single method you aren’t doing one thing, you are doing 100 additional things, one of which is bound to throw an exception. The best course of action is to extract a single, isolated responsibility and move it into its own testable class.

Give it a try

I’ve been doing this “unlegacy my code” kata for a couple of weeks now, and am (very) slowly seeing the unit test coverage rise. The fact that it is directly related to what you are working on also makes it much easier to justify the 30 minute daily investment to your manager.

Friday 16 October 2009

Merge-Friendly Code

If you are working a large application where you have to simultaneously support hotfixes, service packs and new features for customers running several different versions, while developing new versions of your software, chances are you have some kind of branching structure in your source control system.

And before too long, you will experience the joy of merging features from one branch into another. Here’s my top six tips for writing code that is easy to merge…

1. Little and Often

The first principle is that it is better to make many small, focused check-ins, and merge them early, rather than checking a vast collection of changes in one hit and attempting a gigantic merge after several months of development. Sadly, this is not always possible, as sometimes a major change has to be kept out of a branch for a long time.

2. Get Your Branch Strategy Right

It is worth spending some time making sure you choose the correct branching strategy. A lot could be said about this, but here’s just two things to consider.

Don’t put two major features into one branch unless you are willing to deploy them together. Although you can “cherry-pick” changesets to merge, the reality is that this only works if your changes are completely isolated from one another. In other words if changeset B depends on something that was in changeset A, then you can’t just merge changeset B into another branch, changeset A has to come along for the ride too.

Also, avoid getting into the situation where you need to merge between two branches that are not directly related. In TFS, these are called “baseless merges”, and they can result in deleted code getting re-inserted.

3. Check in Clean Code

Nothing messes up a merge more quickly than someone making widespread “cosmetic” changes – introducing or deleting whitespace, renaming things, moving methods to a different part of the file, etc. Sweeping changes like this have a high probability of conflicting with someone else’s change.

The solution is of course, to reduce the need for this kind of change by making sure that what you check in is formatted correctly, and follows the appropriate coding standards and naming conventions. Tools like StyleCop, Resharper, and FxCop are all able to help here.

4. Single Responsibility Principle (SRP)

Simply put, the Single Responsibility Principle dictates that every class should have one and only one responsibility. If it has two or more, you should extract functionality into additional classes. Similarly every method should perform one and only one task.

Adhering to this straightforward principle results in many classes, each composed of short methods. Very often merge conflicts are due to two people working on the same file or method, but changing it for very different reasons. But if a class or method has only “one reason to change”, then the chances of two developers working on different features needing to simultaneously change it are greatly reduced.

5. Open Closed Principle (OCP)

The Open Closed Principle states that classes should be open for extension but closed for modification. Or to say it another way, it should be possible to add new features and capabilities to your codebase simply by creating new classes, rather than having to mess with the internals of existing classes. And if you use technologies like MEF, it really is possible to add whole new features without touching a single line of your existing codebase.

Obviously, in any large real-world application, there will always be the need to make some changes to legacy code. But this should be the exception rather than the norm. In fact, the only real reasons to change the existing code are to fix bugs, and to make it more extensible.

If commits to source control of new features consist mostly of changes to existing files rather than the creation of new ones, maybe you need to do some research into how you can better design your classes to conform to OCP.

6. Unit Tests

After performing a merge, it is vital that you are able to determine as quickly as possible if you made any mistakes in the conflict resolution process. A unit test suite with good code coverage is invaluable in helping with this task. Obviously this may need to be complemented with further integration testing and manual testing, but the quicker you can identify problems with a merge, the better.

So those are my top recommendations for avoiding merging nightmares. Anyone got any other suggestions?

Saturday 10 October 2009

NAudio 1.3 Release Notes

It has been well over a year since I last released a version of NAudio, and since then there have been loads of new features and bugfixes added, so I have decided it is time for a new drop. Another reason for releasing now is that NAudio has been getting a lot more attention recently, mainly due to StackOverflow (and even got a mention on This Week on Channel 9).

As always, head to CodePlex to download the latest source code and binaries.

What’s New?

  • WaveOut has a new constructor (this is breaking change), which allows three options for waveOut callbacks. This is because there is no “one size fits all” solution, but if you are creating WaveOut on the GUI thread of a Winforms or WPF application, then the default constructor should work just fine. WaveOut also allows better flexibility over controlling the number of buffers and desired latency.
  • Mp3FileReader and WaveFileReader can have a stream as input, and WaveFileWriter can write to a stream. These features are useful to those wanting to stream data over networks.
  • The new IWaveProvider interface is like a lightweight WaveStream. It doesn’t support repositioning or length and current position reporting, making the implementation of synthesizers much simpler. The IWavePlayer interface takes an IWaveProvider rather than WaveStream. WaveStream implements IWaveProvider, so existing code continues to work just fine.
  • Added in LoopStream, WaveProvider32 and WaveProvider16 helper classes. Expect more to be built upon these in the future.
  • I have also started using the WaveBuffer class. This clever idea from Alexandre Mutel allows us to trick the .NET type system into letting us cast from byte[] to float[] or short[]. This improves performance by eliminating unnecessary copying and converting of data.
  • There have been many bugfixes including better support for VBR MP3 file playback.
  • The mixer API has had a lot of bugs fixed and improvements, though differences between Vista and XP continue to prove frustrating.
  • The demo project (NAudioDemo) has been improved and includes audio wave-form drawing sample code.
  • There is now a WPF demo as well (NAudioWpfDemo), which also shows how to draw wave-forms in WPF, and even includes some preliminary FFT drawing code.
  • The WaveIn support has been updated and enhanced. WaveInStream is now obsolete.
  • WASAPI audio capture is now supported.
  • NAudio should now work correctly on x64 operating systems (accomplished this by setting Visual Studio to compile for x86).

As usual, I welcome any feedback on this release. Do let me know if you use NAudio to build anything cool.

Friday 9 October 2009

Recording the Soundcard Output to WAV in NAudio

Suppose you want to not just play back some audio, but record what you are playing to a WAV file. This can be achieved in NAudio by creating an IWaveProvider whose read method reads from another IWaveProvider but also writes to disk as it goes. This is very easy to implement, and the WaveRecorder class I present here will be added to NAudio shortly. Our WaveRecorder also needs to be disposable, as we will want to close the WAV file when we are finished.
/// <summary>
/// Utility class to intercept audio from an IWaveProvider and
/// save it to disk
/// </summary>
public class WaveRecorder : IWaveProvider, IDisposable
{
    private WaveFileWriter writer;
    private IWaveProvider source;
 
    /// <summary>
    /// Constructs a new WaveRecorder
    /// </summary>
    /// <param name="destination">The location to write the WAV file to</param>
    /// <param name="source">The source Wave Provider</param>
    public WaveRecorder(IWaveProvider source, string destination)
    {
        this.source = source;
        this.writer = new WaveFileWriter(destination, source.WaveFormat);
    }
     
    /// <summary>
    /// Read simply returns what the source returns, but writes to disk along the way
    /// </summary>
    public int Read(byte[] buffer, int offset, int count)
    {
        int bytesRead = source.Read(buffer, offset, count);
        writer.WriteData(buffer, offset, bytesRead);
        return bytesRead;
    }
 
    /// <summary>
    /// The WaveFormat
    /// </summary>
    public WaveFormat WaveFormat
    {
        get { return source.WaveFormat; }
    }
 
    /// <summary>
    /// Closes the WAV file
    /// </summary>
    public void Dispose()
    {
        if (writer != null)
        {
            writer.Dispose();
            writer = null;
        }
    }
}

Now we have our WaveRecorder, we can insert it anywhere in the chain we like. The most obvious place is right at the end of the chain. So we wrap the WaveStream or WaveProvider we would normally pass to the Init method of our IWavePlayer with the WaveRecorder class. To demonstrate, I will extend the sine wave generating code I created recently, to save the sine wave you are playing to disk. Only three extra lines of code are required:
IWavePlayer waveOut;
WaveRecorder recorder; 

private void button1_Click(object sender, EventArgs e)
{
    StartStopSineWave();
}

void StartStopSineWave()
{
    if (waveOut == null)
    {
        var sineWaveProvider = new SineWaveProvider16();
        sineWaveProvider.SetWaveFormat(16000, 1); // 16kHz mono
        sineWaveProvider.Frequency = 500;
        sineWaveProvider.Amplitude = 0.1f;
        recorder = new WaveRecorder(sineWaveProvider, @"C:\Users\Mark\Documents\sine.wav");
        waveOut = new WaveOut();
        waveOut.Init(recorder);
        waveOut.Play();
    }
    else
    {
        waveOut.Stop();
        waveOut.Dispose();
        waveOut = null;
        recorder.Dispose();
        recorder = null;                
    }
}

Thursday 8 October 2009

Playback of Sine Wave in NAudio

In this post I will demonstrate how to create and play a sine wave using NAudio. To do this, we need to create a derived WaveStream, or more simply, a class that implements IWaveProvider.
One awkwardness of implementing IWaveProvider or WaveStream, is the need to provide the data into a byte array, when it would be much easier to write to an array of floats for 32 bit audio (or shorts for 16 bit). To help with this, I have created the WaveProvider32 class (likely to be committed into the source for NAudio 1.3), which uses the magic of the WaveBuffer class, to allow us to cast the target byte array into an array of floats.
public abstract class WaveProvider32 : IWaveProvider
{
    private WaveFormat waveFormat;
    
    public WaveProvider32()
        : this(44100, 1)
    {
    }

    public WaveProvider32(int sampleRate, int channels)
    {
        SetWaveFormat(sampleRate, channels);
    }

    public void SetWaveFormat(int sampleRate, int channels)
    {
        this.waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channels);
    }

    public int Read(byte[] buffer, int offset, int count)
    {
        WaveBuffer waveBuffer = new WaveBuffer(buffer);
        int samplesRequired = count / 4;
        int samplesRead = Read(waveBuffer.FloatBuffer, offset / 4, samplesRequired);
        return samplesRead * 4;
    }

    public abstract int Read(float[] buffer, int offset, int sampleCount);

    public WaveFormat WaveFormat
    {
        get { return waveFormat; }
    }
}

Now we can derive from WaveProvider32 to supply our actual sine wave data:
public class SineWaveProvider32 : WaveProvider32
{
    int sample;

    public SineWaveProvider32()
    {
        Frequency = 1000;
        Amplitude = 0.25f; // let's not hurt our ears            
    }

    public float Frequency { get; set; }
    public float Amplitude { get; set; }

    public override int Read(float[] buffer, int offset, int sampleCount)
    {
        int sampleRate = WaveFormat.SampleRate;
        for (int n = 0; n < sampleCount; n++)
        {
            buffer[n+offset] = (float)(Amplitude * Math.Sin((2 * Math.PI * sample * Frequency) / sampleRate));
            sample++;
            if (sample >= sampleRate) sample = 0;
        }
        return sampleCount;
    }
}

Using it is straightforward. We choose our output sample rate, the frequency of the sine wave and amplitude. You can even adjust them in real-time.
private WaveOut waveOut;

private void button1_Click(object sender, EventArgs e)
{
    StartStopSineWave();
}

private void StartStopSineWave()
{
    if (waveOut == null)
    {
        var sineWaveProvider = new SineWaveProvider32();
        sineWaveProvider.SetWaveFormat(16000, 1); // 16kHz mono
        sineWaveProvider.Frequency = 1000;
        sineWaveProvider.Amplitude = 0.25f;
        waveOut = new WaveOut();
        waveOut.Init(sineWaveProvider);
        waveOut.Play();
    }
    else
    {
        waveOut.Stop();
        waveOut.Dispose();
        waveOut = null;
    }
}

Please note, that you will need to be using the latest NAudio code from source control to use this (until 1.3 is released).

Wednesday 7 October 2009

Looped Playback in .NET with NAudio

In this post I will explain how to seamlessly loop audio with NAudio. The first task is to create a WaveStream derived class that will loop for us. This class takes a source WaveStream, and in the override Read method, will loop back to the beginning once the source stream stops returning data. Obviously this requires that the source stream you pass in does in fact stop returning data. Another option would be to use the Length property of the source stream, and go back to the beginning once we have sent Length bytes. Here’s my implementation of LoopStream. I might put this into NAudio for the next release: (Update: have fixed a bug in the Read method, thanks Neverbith for spotting it. I will also possibly add a configuration to allow you to use the Source’s Length property as well)

/// <summary>
/// Stream for looping playback
/// </summary>
public class LoopStream : WaveStream
{
    WaveStream sourceStream;

    /// <summary>
    /// Creates a new Loop stream
    /// </summary>
    /// <param name="sourceStream">The stream to read from. Note: the Read method of this stream should return 0 when it reaches the end
    /// or else we will not loop to the start again.</param>
    public LoopStream(WaveStream sourceStream)
    {
        this.sourceStream = sourceStream;
        this.EnableLooping = true;
    }

    /// <summary>
    /// Use this to turn looping on or off
    /// </summary>
    public bool EnableLooping { get; set; }

    /// <summary>
    /// Return source stream's wave format
    /// </summary>
    public override WaveFormat WaveFormat
    {
        get { return sourceStream.WaveFormat; }
    }

    /// <summary>
    /// LoopStream simply returns
    /// </summary>
    public override long Length
    {
        get { return sourceStream.Length; }
    }

    /// <summary>
    /// LoopStream simply passes on positioning to source stream
    /// </summary>
    public override long Position
    {
        get { return sourceStream.Position; }
        set { sourceStream.Position = value; }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        int totalBytesRead = 0;

        while (totalBytesRead < count)
        {
            int bytesRead = sourceStream.Read(buffer, offset + totalBytesRead, count - totalBytesRead);
            if (bytesRead == 0)
            {
                if (sourceStream.Position == 0 || !EnableLooping)
                {
                    // something wrong with the source stream
                    break;
                }
                // loop
                sourceStream.Position = 0;
            }
            totalBytesRead += bytesRead;
        }
        return totalBytesRead;
    }
}

Now using this to play a looping WAV file is trivial:

private WaveOut waveOut;

private void buttonStartStop_Click(object sender, EventArgs e)
{
    if (waveOut == null)
    {
        WaveFileReader reader = new WaveFileReader(@"C:\Music\Example.wav");
        LoopStream loop = new LoopStream(reader);
        waveOut = new WaveOut();
        waveOut.Init(loop);
        waveOut.Play();
     }
     else
     {
         waveOut.Stop();
         waveOut.Dispose();
         waveOut = null;
     }
}