Author Topic: Determining input and output latency for DirectSound and WASAPI devices  (Read 273 times)

rborsey

  • Posts: 8
Hi everybody. I am working on a type of software Looper box (for Windows) and for it to work correctly I need to know the input and output latency for the selected audio devices. I use these values to adjust the record start and stop points in a newly incoming audio stream.

Clearly the preferred approach is to use ASIO drivers and then I can directly query this from the driver using bass_asio_getlatency and this seems to be pretty accurate (I suppose the accuracy depends on the driver). For DS I have tried using the latency returned in the bass_info structure which is sort of fine for output latency. What I wondered is if there is a way to get or calculate accurately the input latency for DS and the input and output latency for WASAPI. I can clearly measure it in testing with a specific set of buffer sizes and refresh rates on a specific PC but I need to be able do this reliably based on a user's PC and configuration choices.

Anybody know the answer?

Thanks Richard

Ian @ un4seen

  • Administrator
  • Posts: 24331
WASAPI generally provides lower and more consistent latency recording than DirectSound, so I would recommend using that whenever possible (it is the default unless disabled via BASS_CONFIG_REC_WASAPI).

To get a recording latency value, you could try measuring how long it takes for data to start arriving from a recording. For example, something like this:

Code: [Select]
HRECORD record = BASS_RecordStart(freq, chans, 0, NULL, NULL); // create recording channel (no RECORDPROC)
DWORD start = timeGetTime(), avail;
while (!(avail = BASS_ChannelGetData(record, NULL, BASS_DATA_AVAILABLE))) Sleep(1); // wait for data to become available
double latency = (timeGetTime() - start) / 1000.0 - BASS_ChannelBytes2Seconds(record, avail); // calculate latency in seconds
BASS_ChannelFree(record); // free the recording

rborsey

  • Posts: 8
Hi Ian. Wow! Very clever . . . I'll give it a go . . .
Thanks
Richard

rborsey

  • Posts: 8
This is beginning to work better - for DS and WASAPI input latencies I do more or less what was suggested - start up a record and wait to see how long before data arrives - seems consistent. What I can't seem to fathom is how to get WASAPI output latency - I can do a calculation based on buffer size but for DS there is a device dependant figure from the info record . . . Any ideas?
Thanks everybody
Richard

Ian @ un4seen

  • Administrator
  • Posts: 24331
You can get an approximate/average output latency value from BASS_GetInfo (see the BASS_INFO "latency" value). Note the latency may be lower than usual when playing a file after a period of silence because the output buffer was empty. If you need to avoid any such inconsistencies, you can enable the BASS_CONFIG_DEV_NONSTOP option to keep the output active even when nothing is playing, like this:

Code: [Select]
BASS_SetConfig(BASS_CONFIG_DEV_NONSTOP, 1);

You should do that before calling BASS_Init. If you want, you can use BASS_Pause to manually stop the output when nothing is playing (and then BASS_Start to resume).

rborsey

  • Posts: 8
Thanks for that - but doesn't bass_getinfo take the currently initialised DS device, or if WASAPI is used by default then maybe I just need to BASS_Init for the device I want to explicitly use with WASAPI??
Cheers from sunny France
Richard

Ian @ un4seen

  • Administrator
  • Posts: 24331
BASS does indeed use WASAPI output by default (since BASS 2.4.13), and DirectSound is only used when WASAPI isn't available (on Windows XP and older) or the BASS_DEVICE_DSOUND flag is specified in the BASS_Init call. BASS_GetInfo can be used to get info on the output in either case.