Kernel Streaming Output Plugin V3.6

Contents

1. Background
2. Features
3. Configuration
4. Known Issues
5. Please Note
6. Credits
7. Understanding the plugin and Adjusting Buffers
8. Revision History (2.0 onwards)



1. Background

Kernel Streaming is a method of sending digital audio data to an audio device that bypasses Windows' KMixer. KMixer takes audio feeds from any program attempting to output sound and mixes them together before outputting the mixed signal to the computers sound card. In order to simplify this process, the various streams of data get resampled to a single sample frequency, typically 48KHz before being passed on to the sound card. In general this process is acceptable, but for high fidelity applications modifying the signal is generally held to be undesirable. In these situations it is preferable to keep all signals in their original format throughout the chain and this is where Kernel Streaming comes in. Because Kernel Streaming bypasses KMixer, this stage of resampling is avoided and, assuming the sound card and driver are capable of handling it, the audio stream is passed through to the ouput (either DAC's or SPDIF) without modification.

It should be borne in mind that not all sound cards are capable of this and some will always internally resample audio to a specific frequency.

For my purposes, I wanted to be able to play HDCD tracks from my media PC and decode the HDCD data with my external HiFi processor. For this to work, the bitstream coming out of the PC must be a perfectly uncorrupted copy of the original data for the HDCD decoder to recognise that it is indeed dealing with HDCD data so I started using Chun-Yu's original WinAmp plugin with my M-Audio Audiophile 2496 cards SPDIF output. While this allowed me to get an uncorrupted bitstream through to the HDCD processor, it made my system very unstable resulting in some very unpleasant crashes. Fortunately, Chun-Yu had also posted his source code, so I was able to rewrite the core routines of the plugin to address these stability issues. Since then, various people have asked about other features and there have been things about the plugin that have personally annoyed me, which leads us to this release.

I believe I have now catered for most of the features that people requested and in my own testing stability no longer seems to be an issue.


2. Features

The plugin now has the following features;

Kernel streaming for 16 and 24 bit audio data - bypasses KMixer and allows unmodified output via DAC and SPDIF where hardware and drivers permit . The output device may be selected via the Config screen using friendly device names.

Optional volume control - the WinAmp volume control will now work with this plugin when playing 16 or 24 bit audio data. The code that attenuates the data is bypassed when the volume control is set to 100%, thereby maintaining an un-modified data stream.In addition, the volume control can be completely disabled in the Config screen to ensure it has no effect where it is not needed and a pure data stream is required. By default, the volume control is disabled. Note that activating the volume control may prevent HDCD data from being decoded by an external decoder. If you play a lot of HDCD and want to get the best from them, then I would recommend leaving this feature disabled. The volume control can operate in either a linear or a logarithmic mode (the latter being the default). Using the logarithmic mode will give you finer control of volume at lower levels and is ideal if you want to pass your sound cards output directly to a power amplifier without using a pre-amp. Note that digital attenuation - as used in this volume control implementation will reduce sound quality, particularly at low levels. Therefore an external analogue volume control is recommended as the preferred quality option.

The Audio Device is released at the end of tracks or when playback is stopped (but not when paused).

Adjustable Input and Output buffers to balance latency against immunity to audio breakup when the CPU is under heavy load. If you experience audio breakup when your computer is doing a lot of work, adjusting these settings may help, however, more or larger buffers will increase latency and therefore reduce the responsiveness of Winamps controls.

Gapless output mode - this is currently experimental and may produce unexpected results, use at your own risk. Essentially, this mode leaves the Kernel Streaming output open when WinAmp requests a stop (e.g. at the end of a track). As the system is fully buffered, if WinAmp then starts writing data to the plugin (e.g. when a new track begins) it will be output as a seamless stream and not contain an annoying break (assuning WinAmp begins writing the new track before the previous one has finished playing from the buffer). This is particularly noticable on albums where the tracks blend into one another. Note that albums ripped with WinAmp will still contain a break because WinAmp does not accurately rip the start and end of tracks. For best results use some other program such as EAC to rip your tracks.

Diagnostic logging is now provided. If you experience problems using the plugin, e.g. tracks don't play, enabling this logging feature may help to diagnose the issue. When enabled, a file called "kernel streaming log.txt" will be written to the folder where you installed Winamp (typically c:\program files\winamp) various useful information will be written into this file that may help to shed light on what is going wrong inside the plugin.


There is an optional status window. This can be activated from the Config screen and can be useful when adjusting the buffer sizes mentioned above. It shows the following information;

a) Player Thread status - this can be either;

"AWAKE" - this means it's filling buffers and dispatching them to the KS interface

"SLEEPING" - this means it's currently idle, this can either be because the input buffer is empty or Winamp has been paused.

b) Input Buffer size in bytes followed by the buffer duration in milliseconds (mS).

c) Input Buffer usage indicator. This indicates how full the input buffer is at any point indicating how well the system is smoothing out the communication between Winamp and the KS interface.

d) Output buffer size in bytes followed the the buffer duration in milliseconds (mS). Note that when calculating the total latency of the output buffers this figure should be multiplied by the number of buffers as there may be up to eight buffers in the current configuration.

e) Output buffer status for each buffer (0 to 7). This can be either;

IN USE - the buffer has been filled and dispatched to the KS interface

FREE - the buffer is idle and waiting data


3. Configuration

The plugin defaults to the following settings;

Output Device - first one in system list
Volume Control - disabled
Input Buffer - 64K
Output Buffer - 8K
Gapless Mode - Disabled

These can all be changed by entering the Config screen, making your selections then pressing "Ok". Pressing the "Default" button will restore these settings.


4. Known Issues

At present the plugin will keep hold of the audio device when paused, this means that the kind of issues mentioned above regarding other programs trying to generate sound still apply when paused. The plugin will only release the audio device when;

1. Winamp is closed.
2. When a track ends - it will re-acquire it when a new track begins.
3. When Stop is pressed.

Audio device enumeration can pick up some devices that are not suitable for output, the plug-in will pop up an "unable to create output pin" error when you select such a device and try to play. If this happens, simply select another device and try again. Note, that Winamp will attempt to play each track in your playlist when this kind of error happens, so it's best to try swapping output devices with just one track in the playlist.

The plugin does not check if sample sizes greater than 16 bit are supported, so attempting to play media of this type on hardware that does not support it will result in an error.

The timings sent back to Winamp for use with visualisation plugins do not sync correctly.

On some sound cards (certainly the M-Audio Audiophile 2496, possibly all cards) a mono feed from Winamp will be played back via one channel only.

In rare cases, if a buffer underrun occurs during a track change with gapless mode enabled, playback may stop. Adjusting the size of the input buffer may improve this.


5. Please Note

This plugin is supplied "as is", it is, to the best of my knowledge robust and reliable, but you use it entirely at your own risk.

For those who don't require buffered playback the un-buffered, low latency version (2.x) is still available here although I am no longer supporting it for updates etc.


6. Credits

Original Kernel Streaming Plugin developed and written by Chun-Yu Shei - Copyright 2002

Adapted and reworked for version 2.x by Steve Monks (December 2005)

Completely rewritten for version 3.0 by Steve Monks (January 2006) - Copyright Steve Monks 2006


7. Understanding the plugin and Adjusting Buffers

This plugin uses a series of buffers to smooth out CPU loading issues and prevent the audible disruption that is caused when Kernel Streaming (KS) is interrupted because the CPU cannot feed it with audio packets quickly enough. To manage these buffers an autonomous Player Thread has been added.

The plugin uses two types of buffer. The first is the input buffer - data from Winamp is copied here before being picked up by the Player thread. The second type of buffer is an output buffer. There may be up to eight output buffers and these are filled by the player thread with data from the input buffer (if there's any available). As each one is filled it is passed to the KS interface which keeps hold of it until it has finished using it.

Windows will swap the CPU between the Winamp and the Player thread many times per second so it is important that when the player thread takes its turn there is enough data in the input buffer to feed the available output buffers and maximise the time available to it. It is equally important that when Winamp is taking its turn and attempting to put data into
the input buffer it doesn't actually fill the buffer otherwise it will end up waiting for the player thread to empty it before it can continue.

If the output buffers are too small they may be affected by CPU load which will give rise to crackling or breaks in the sound when the CPU is otherwise engaged. How small they can be will vary from system to system. A lower powered system may require large output buffer to ensure it doesn't get disrupted by CPU load a more powerful system may be able to get away with smaller output buffers.

If the input buffer is regularly filling (because the output buffers are too big) you will experience slow, broken playback, so the aim when adjusting the buffers is to achieve a balance. The status window can be helpful here, aim for an input buffer usage that is generally somewhere between 50% and 75% when adjusting the buffers.

When choosing buffer values, start with the smallest values you can get away with. If you are getting pops and breaks when your CPU is under load (i.e. running other apps, compressing MP3s, maximising windows) increase the output buffer until this stops. If this causes the input buffer to underrun (indicated by the Player Thread sleeping a lot during playback or slow broken playback - increase the input buffer size until this stops).


8. Revision History

2.0

Initial revision. Fixed most stability issues and added a config screen to allow selection of output device.

2.1

Fixed crash on pause bug

2.2

Fixed confusion when paused - plugin could lose track of pause status requiring several presses of pause button to get it going again.
Fixed problem from original plugin where certain tracks would stop at the end rather than advancing to the next track in the play list.

2.3

Added a volume control for 8/16 bit audio.
Added option to release output device when stopped.
Changed config list box to use "friendly names" rather than device paths.

2.4

Fixed bug where all settings would disappear from the config screen if no tracks were playing and "Release Audio Device When Stopped" was checked.
Added experimental oversampler.

2.5

Fixed incompatibility with streaming media (e.g. internet radio).
Added support for 24 bit playback of 24 bit stereo media.

3.0

Rewritten from scratch to prevent audio breakup with low power CPU's when under heavy CPU load. Now uses an asynchronous playback thread that is fed from Winamp via an adjustable buffer.

3.1

Quick fix for heavy system load that occurs when playback is suspended. Player thread is now put to sleep.

3.2

Fixed problems with "Winamp Music" and .mod players skipping while playing.
Removed 2 second delay before sending player thread to sleep when it falls idle - seems okay in tests.

3.3

Fixed problems when playing .d00 files.
Changed available buffering options in config to now include 16,32,64 and 128K input plus 4,8,16 and 32K output.
Added protection to buffer selection to avoid buffer underruns.
Added Status window to aid problem diagnosis and buffer adjustment.

3.4

Removed 4K output buffer option as it was found to cause crashes on M-Audio Audiophile 2496.
Increased player thread priority to Time Critical to reduce susceptibility to heavy loading.
Added an option to change the number of output buffers.
Added "Gapless" mode.
Config screen now uses slider controls for buffer size adjustment.
Converted readme to html for improved readibilty/accessibility.

3.5

Fixed problem with Gapless playback when sample format changes (fixes various track change related issues usually resulting in a "Could Not Create Pin" message followed by Winamp crashing).
Fixed problem with Gapless playback when track was changed while paused (track would not play).

3.6

Added logarithmic volume control.
Added diagnostic logging system
Removed several annoying popup messages - now use diagnostic log to find out what's going wrong.
Fixed problem trying to play multi channel (e.g. 5.1) material, thanks to Leif for the tip off.
Fixed problem where playback would not be gapless if WAVEFORMATEX fallback was being used.

3.61

Fixed problem with log files getting created in different places depending on how Winamp was launched.
Log files should now always get created in the same folder as the Winamp executable itself.

3.62

Fixed timing discrepancy with certain file formats and certain sound drivers when playing back 24 bit files. This was caused by failing to adjust the average bytes per second value when adjusting the output format to allow for 24 bit being packed to 32 bits. An interesting observation while debugging this is that certain input plugins disregard the GetWrittenTime feedback from the output plugin, this was illustrated by my failure to identify the problem because I was using WavPacked files for test purposes. Switching to WAV files immediately highlighted the wrong data.

3.63

Fixed intermittent crash at start of track playback caused by WinAmp calling GetCurrentTime before playback initialisation had finished, this caused a divide by zero in GetCurrentTime.