A custom synth can be written to run in either user mode or kernel mode. In general, software synths are easier to implement in user mode, but they frequently can achieve lower latency in kernel mode. Hardware components can be supported only in kernel mode. Good reasons exist, however, for beginning development in user mode even if the final implementation is to run in kernel mode.
Building software synthesizers (and synth sinks) is much simpler in user mode. The user-mode interfaces are easy to use, and debugging is simplified. Another benefit is that the resulting component is a Windows executable. Because this executable is a COM object, installing it is simply a matter of self-registering from the command line with regsvr32.exe. (The RegSvr32 system application calls your DLL's DllRegisterServer function. For more information, see the Platform SDK documentation.)
If a user-mode implementation is all you need, you can deliver your product with an application program instead of a driver. The user avoids a complicated driver-installation process, and no reboot is needed after installing. Your user-mode component can then be enumerated as one of the available ports, depending on whether you want other applications to be able to use it. For more information, see Registering Your Synthesizer.
The advantage of a kernel-mode software implementation is lower latency. With the advent of time-stamped messages, however, this advantage is not as great as it used to be. Legacy MIDI APIs had no time stamping, so when you played a note, that was exactly when it was queued to play. Time stamping makes it possible to queue notes to play at specified times in the future. Using time stamping means that the note plays at the correct time unless the advance warning is less than the latency inherent in the system.
Latency is only an issue when sounds are queued to play with little or no advance warning. Thus, kernel-mode implementations are recommended only when there is an undesirable limitation to a user-mode software implementation or when supporting hardware acceleration.
If you decide to do a kernel-mode implementation, the best approach is still to begin development in user mode. The source code for Microsoft's user-mode synth is provided in the Windows DDK, so you do not have to write a new synth from scratch. You can use the existing code to understand how the downloadable sounds (DLS) downloads are parsed. Then you can add any new functionality (such as parsing additional chunks) and debug this logic in user mode first, stubbing out the routines that access the hardware. (A stubbed-out routine can either do nothing or emulate the hardware function in software.) For more information on DLS, see the Platform SDK documentation.
When you have your implementation working in user mode, you can move it down to kernel mode and make it work there. After you have the software version working in kernel mode, your next step is to begin moving the functionality to your hardware. The user-mode and kernel-mode software synths serve as useful intermediate steps in the process of getting your hardware synth up and running.
To summarize the recommendations above: