LineIn plugin for Winamp 2/5 Documentation - Performance
Up | Previous | Next | Down
Minimizing the delay
The problem
Winamp is a plugin based audio(/multimedia) program that works by forwarding audio data from intput plugins to VIS plugins, DSP plugins and output plugins, below is a picture of how it's done with my plugin (roughly, actually the DSP plugin returns the modified data to the input plugin):
As you can see a DSP plugin will introduce a delay because it is put between the output and input plugin. Unfortunately that's not the biggest problem, it's possible to hardly notice any difference (in delay) between using a DSP plugin and not using a DSP plugin. The main problem is the plugin architecture itself, because the input plugin first has to fill a buffer before it can forward it.
The solution
It will never be possible to eliminate the delay, but... you can minimize it.
Tuning the output plugin
Yes, this can actually have an effect on the delay, a very big effect even, most people don't realize it, but an untuned output plugin is one of the biggest causes of delays! In simple tests - I played a tone in an cooledit, sent it through Virtual Audio Cable and paused it when I heard the signal - I easily achieved 2 times as small a delay, 0.3 seconds instead of 0.7).
The output plugin can be tuned, this can be done by using the out(pre)buflen options of my plugin, or by tuning the plugin directly through its configuration dialog.
The out(pre)buflen options probably don't work with all output plugins, so you may want to try atleast both the waveOut and the DirectSound plugin (which is advisable anyhow). But if the options work they should specify the length of the buffer the output plugin uses and they should affect the maximum latency of the output plugin, in theory (I have no idea wether there are actually output plugins that support those options). The outprebuflen length must always be less than or equal to the outbuflen.
Configuring the output plugin through its configuration dialog is very plugin specific, but in general big buffers mean big delays.
NOTE: The waveOut API is usually preferable to the DirectSound API on Windows 9x/ME, for NT/2000/XP it's the other way around (in fact on my system the waveOut API always hangs my XP system). But this hugely depends on your drivers, so experiment a bit to see what works best on your system.
waveOut plugin
Try to lower the main buffer, the total number of buffers and the maximum and minimum sizes of buffers, but if you get undesired results, don't hesitate to play with the values until you like it (I'm not sure about which actions have the best effect).
DirectSound plugin
Try to lower the main buffer size, the Directsound polling delay and the Directsound block size. In this case it's also advisable to play with the settings until you get nice results (since I'm also in this case unsure about the precise effect of the different settings).
Some (recent) version of the DirectSound plugin has been reported by someone to provide much lower latencies than the waveOut equivalents, but "your mileage may vary".
Low-latency waveOut plugin
This is my own output plugin, created to work with my LineIn plugin, in order to minimize the delay as much as possible. The plugin works by forwarding a buffer to the driver as soon as it receives one. The plugin can be downloaded here.
ASIO output plugin
If your soundcard supports ASIO (usually only high-end cards) this will (at least theoretically) provide the lowest latency possible. The plugin can probably be found by searching on Google or in the HydrogenAudio forums.
NOTE: There is a driver available that will provide ASIO support for just about any soundcard, see http://michael.tippach.bei.t-online.de/asio4all/.
NOTE2: The ASIO Winamp plugin can be found at http://otachan.com/.
Nullsoft NULL Output plugin
If you don't need Winamp's output (if you're only using Winamp for visualizations for example) then you should consider using Nullsoft's NULL Output plugin. This output plugin doesn't do anything with the sound, which makes Winamp perform really well, and if you can get the sound to the speakers through some other means you may be able to get really good synchronization.
To get the sound to the speakers without going through Winamp you can either completely by-pass your computer or unmute your input device for playback (see the section about setting up your volume settings Basics).
Buffer sizes
The most obvious solution is simply to decrease the buffersize, that way the input plugin will be able to forward data sooner and thus create a smaller delay.
There is one straightforward option to control the buffersize and that is bufsize
. The bufsize option lets you specify the buffer size used by my plugin in bytes, this allows you to set the buffersize as low as 576 bytes (upto v1.42, after that even smaller sizes are possible), this size was based on a wrong assumption I once made, but experience has shown that it works. So to get you started:
Unfortunately this will probably cause a lot of skips, since the buffers will be filled very quickly and the plugin won't have time to catch up. That's where the option numbuffers comes in, this lets you specify how many buffers my plugin will use. So better would be (and often sufficient):
line://bufsize=576,numbuffers=100
The maximum number of buffers used to be 50, is 100 in v1.42 and 1000 for later versions.
This is about as far as you can go with tweaking the buffer size.
Some pointers on using the bufsize option:
- The value of 576 should really be 2304 for optimal VIS operation, this is because I once misinterpreted the SDK (somehow I read bytes instead of samples).
- You should never set bufsize to a value that's not on a sampleborder, this means that you should use the following formula for calculating the buffersize:
bufsize=numsamples * nch * (bps/8)
Or let the plugin do the math and use:
bufsize=snumsamples
, for example bufsize=s576
- Upto v1.42 of my plugin the bufsize option is pretty straightforward, but later versions have a more advanced (backwards compatible) bufsize option which also lets you specify the buffersize in seconds (and milliseconds) and in samples:
bufsize=t1.01
sets the buffersize to 1.01 seconds
bufsize=s576
sets the buffersize to 576 samples (normally this will result in a buffersize of 2304 bytes).
bufsize=576
sets the buffersize to 576 bytes (old way of doing things)
In those versions you can also set the buffersize lower than 576 bytes (currently it has a minimum of 16 bytes).
- Winamp does not like very small buffer sizes (lower than 576 bytes), I've even had crashes while I was testing the system, but this mostly happens when the buffersize is not a multiple of the samplesize (nch * (bps/8)).
Reducing the time contained in one buffer
A clever way to reduce the delay is to simply input the sound at a higher quality and thereby reducing the time contained in one buffer. Some pointers:
- The samplerate can be increased without problems, although a lot of soundcards don't go any higher than 48000 Hz. The option to do this is
srate
:
line://srate=48000
will open the input device with a samplerate of 48000 Hz
- It's possible to increase the number of bits per sample (bps), but this is not a very good option, since most soundcards don't support more than 16 bps and those that do usually support 24 bps (and possibly the 'unpacked' 32 bps format), which Winamp doesn't like much (in my experience, but that might change with newer versions of Winamp). Also you have to keep in mind that when you change the bps to 24 that the buffer size still has to be a multiple of the samplesize (which is nch * 3 at 24 bps). Example:
- The above usually doesn't help much, although it will probably work quite well if you can record at 96000 Hz, which is possible with programs like Virtual Audio Cable (only from one program to another) or with a very nice soundcard.
Evading the problem
Of course a delay is never welcome, but if you can't get it small enough it's often possible to evade the problem, by using Winamp's sound output as well as its VIS, those will be much better synchronised than the source and the VIS.
VIS performance
I can be quite short about this. If you have the delay minimized, then all you need to do is start your favourite VIS plugin.
The only problem is that your VIS plugin might not like the settings you specified while going for that extra 0.01 second delay reduction, so you might have to play a little with the settings before you find something that satisfies you.
The optimal buffer size for VIS plugins should be 576 * NCH * (BPS/8), which translates into 576 samples, which you can specify directly, with the option:
Or you can calculate it yourself and then you would use something like this:
Although 576 samples should be the optimal setting, nobody is telling you that you can't use a different setting, it just won't work (well) with all plugins.
Up | Previous | Next | Down
To contact me, please mail to: th.v.d.gronde@hccnet.nl
I hope you'll enjoy my program(s).