Audio Dropouts

Started by Chris Oakley,

Chris Oakley

We're having some real trouble with audio dropouts. I'll try to keep this as simple as I can and try to explain why we're doing certain things.

First off, before we do BASS_Init we set a config on the split buffer to set it to it's minimum:
Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_SPLIT_BUFFER, 100)
Next we create a mixer on the No Sound device which acts as one source of truth for processing everything else created that is a DECODE channel:
g_MixEngine = BassMix.BASS_Mixer_StreamCreate(48000, 2, BASSFlag.BASS_MIXER_NONSTOP)
Bass.BASS_ChannelSetAttribute(g_MixEngine, BASSAttribute.BASS_ATTRIB_BUFFER, 0F)
Bass.BASS_ChannelPlay(g_MixEngine, False)

We then set up the 16 mixers which are the endpoints for physical audio outputs, recording to a file, casting etc. The mixer is in a class, so we instance 16 of that class. This is the code that each mixer is setup with:
_NodeID = BassMix.BASS_Mixer_StreamCreate(_DeviceFrequency, 2, BASSFlag.BASS_STREAM_DECODE)
Bass.BASS_ChannelSetAttribute(_NodeID, BASSAttribute.BASS_ATTRIB_BUFFER, 0F)
m_SplitId = BassMix.BASS_Split_StreamCreate(_NodeID, BASSFlag.BASS_STREAM_DECODE, Nothing)
Bass.BASS_ChannelSetAttribute(m_SplitId, BASSAttribute.BASS_ATTRIB_BUFFER, 0F)
BassMix.BASS_Mixer_StreamAddChannel(g_MixEngine, m_SplitId, BASSFlag.BASS_DEFAULT)

You can see we make a split off this node mixer add it to the mix engine so it's processed since at this stage it's just a DECODE.

Probably irrelevant, but we also add a level meter to the mixer we just created so we can query the current level:
_VUMeter = New DSP_PeakLevelMeter(_NodeID, -1) With {
.CalcRMS = True,
.UpdateTime = 0.08
} 'Setup the DSP for VU
m_VuAdapter = New PeakMeterAdapter(_VUMeter)

Then we make sure that there is always data being pushed through the mixer. If we don't do this, if there is no data going through the mixer then it will stall. Whilst that is not a big issue outputting to a physical audio device, it's a problem if it's being used to cast to a stream or if it's recording audio because the silence isn't included in the recording:
m_NodeStreamProc = New STREAMPROC(AddressOf SilenceProc)
m_SilenceStreamId = Bass.BASS_StreamCreate(_DeviceFrequency, 2, BASSFlag.BASS_STREAM_DECODE, m_NodeStreamProc, IntPtr.Zero)
If m_SilenceStreamId <> 0 Then
BassMix.BASS_Mixer_StreamAddChannel(_NodeID, m_SilenceStreamId, BASSFlag.BASS_DEFAULT)
End If

Finally we route these 16 mixers to where they're configured to go. We set the Bass device to the index required, then split off the mixer to the physical device:
m_SplitPhysicalId = BassMix.BASS_Split_StreamCreate(_NodeID, BASSFlag.BASS_DEFAULT, Nothing)
Bass.BASS_ChannelSetSync(m_SplitPhysicalId, BASSSync.BASS_SYNC_DEV_FAIL Or BASSSync.BASS_SYNC_MIXTIME, 0, _DeviceOutFailSync, IntPtr.Zero)
Bass.BASS_ChannelSetAttribute(m_SplitPhysicalId, BASSAttribute.BASS_ATTRIB_BUFFER, 0.25)
Bass.BASS_ChannelPlay(m_SplitPhysicalId, False)

Every now and then, just random, we get an audio dropout, like in the audio attached in the ZIP. I've had a SYNC on the split to see if it stalls, but it doesn't. So we're a bit perplexed as to where this oddity is coming from. On the whole, it's fine, it's just every now and then, with no pattern. We have ruled out the audio device. It's happening on Audio Science cards and AXIA. It doesn't happen to everyone. At the moment it's just this one setup but across all their machines.

We've determined it's not upstream, because the recorded audio direct from one of the 16 mixers doesn't have the dropout in it and we split these recordings into 10 minute segments and their file sizes are always the same size. If there was missing audio they would show different sizes and lengths.

We're using the latest version of BASS.DLL (2.4.18.3) and BASS.NET (2.4.18.2) and BASSMIX.DLL (2.4.12.0)

Any ideas where we could look?

Ian @ un4seen

Quote from: Chris Oakley_NodeID = BassMix.BASS_Mixer_StreamCreate(_DeviceFrequency, 2, BASSFlag.BASS_STREAM_DECODE)
Bass.BASS_ChannelSetAttribute(_NodeID, BASSAttribute.BASS_ATTRIB_BUFFER, 0F)
m_SplitId = BassMix.BASS_Split_StreamCreate(_NodeID, BASSFlag.BASS_STREAM_DECODE, Nothing)
Bass.BASS_ChannelSetAttribute(m_SplitId, BASSAttribute.BASS_ATTRIB_BUFFER, 0F)

You can remove these BASS_ChannelSetAttribute calls, as they will be failing anyway. The BASS_ATTRIB_BUFFER option sets the playback buffer size, so it doesn't apply to decoding channels (BASS_STREAM_DECODE).

Quote from: Chris OakleyThen we make sure that there is always data being pushed through the mixer. If we don't do this, if there is no data going through the mixer then it will stall. Whilst that is not a big issue outputting to a physical audio device, it's a problem if it's being used to cast to a stream or if it's recording audio because the silence isn't included in the recording:
m_NodeStreamProc = New STREAMPROC(AddressOf SilenceProc)
m_SilenceStreamId = Bass.BASS_StreamCreate(_DeviceFrequency, 2, BASSFlag.BASS_STREAM_DECODE, m_NodeStreamProc, IntPtr.Zero)
If m_SilenceStreamId <> 0 Then
    BassMix.BASS_Mixer_StreamAddChannel(_NodeID, m_SilenceStreamId, BASSFlag.BASS_DEFAULT)
End If

Instead of that, you could set the BASS_MIXER_NONSTOP flag on the mixer (_NodeID). The end result should be the same but more efficiently done.

Quote from: Chris OakleyEvery now and then, just random, we get an audio dropout, like in the audio attached in the ZIP. I've had a SYNC on the split to see if it stalls, but it doesn't. So we're a bit perplexed as to where this oddity is coming from. On the whole, it's fine, it's just every now and then, with no pattern. We have ruled out the audio device. It's happening on Audio Science cards and AXIA. It doesn't happen to everyone. At the moment it's just this one setup but across all their machines.

That recording looks like there was silence inserted rather than data dropped. Perhaps the mixer's main source didn't have the required amount of data available but the "SilenceProc" provided silence? What is the main source? Try setting a BASS_SYNC_STALL sync on that (via BASS_Mixer_ChannelSetSync) and see if it gets triggered when the problem happens.

Quote from: Chris OakleyWe've determined it's not upstream, because the recorded audio direct from one of the 16 mixers doesn't have the dropout in it and we split these recordings into 10 minute segments and their file sizes are always the same size. If there was missing audio they would show different sizes and lengths.

Is the "recorded audio direct from one of the 16 mixers" from the mixer feeding the same device that the problem is heard from? If the recording is from a different mixer then it wouldn't necessarily contain the problem, eg. a mixer without a "SilenceProc" (nor BASS_MIXER_NONSTOP set) would wait for more data rather than insert silence.

Chris Oakley

Thanks Ian. A lot of questions here so forgive me if I miss something. I tried to keep the explanation simple to begin with, however there are few other things I can now mention.

QuoteInstead of that, you could set the BASS_MIXER_NONSTOP flag on the mixer (_NodeID). The end result should be the same but more efficiently done.

I would do that, but I've had trouble in the past with this because the 16 mixers can be further split and routed elsewhere. So for example you can split mixer 1 and add it to the mixer for 4 and 5 if you wanted. We have a routing matrix so users have a flexible means to get audio where they need it.

If I have mixer 1 on NONSTOP and mixers 4 and 5 on NONSTOP too, we found we would get audio pauses ingested on mixers. It's like they were all arguing with each other.

QuoteWhat is the main source? Try setting a BASS_SYNC_STALL sync on that (via BASS_Mixer_ChannelSetSync) and see if it gets triggered when the problem happens.

The main source for this is the _NodeID mixer which is the 1 to 16 mixers and they don't show any audio pauses in anything else that's sharing it. With the STALL I have done that, but I didn't get any stalls logged. I can check again and report back.

Basically everything else works fine, it's just when we split off to a physical output.

We also have a buffer compensator which monitors the output device split buffer and adjusts the frequency by tiny amounts to keep timings in check, as we know that the No Sound device and each physical output can have differing clock rates. This causes either a delay on the output or occasional drops like we hear - however, we know it's not the compensator because we also have the ability to turn it on and off, and when it was off we still had the same problem.

Chris Oakley

Okay we put a SYNC_STALL on the _NodeId mixer and on the physical m_SplitPhysicalId mixer which is the one that goes to the physical output device.

When we heard an audible pause we checked the logs and found that at that exact moment the m_SplitPhysicalId stalled and resumed pretty much instantly:
2026-06-25 11:38:07.786 (2026-06-25 07:38:07.786) : AudioNode Bus A Split Stalled: handle = -2147483337 : channel = 80000135
2026-06-25 11:38:07.786 (2026-06-25 07:38:07.786) : AudioNode Bus A Split Recovered: handle = -2147483337 : channel = 80000135

There is no logging for the _NodeId mixer stalling, just the split.

This is using an Audio Science card so we are able to rule out AoIP from AXIA.

Ian @ un4seen

Quote from: Chris Oakley
QuoteInstead of that, you could set the BASS_MIXER_NONSTOP flag on the mixer (_NodeID). The end result should be the same but more efficiently done.

I would do that, but I've had trouble in the past with this because the 16 mixers can be further split and routed elsewhere. So for example you can split mixer 1 and add it to the mixer for 4 and 5 if you wanted. We have a routing matrix so users have a flexible means to get audio where they need it.

If I have mixer 1 on NONSTOP and mixers 4 and 5 on NONSTOP too, we found we would get audio pauses ingested on mixers. It's like they were all arguing with each other.

There shouldn't be any audible difference between setting the BASS_MIXER_NONSTOP flag on the mixer and having a source feeding it silence. Is the issue that you need to be able to add and remove the silent source? If so, you can replicate that by setting/unsetting the BASS_MIXER_NONSTOP flag via BASS_ChannelFlags.

Quote from: Chris OakleyOkay we put a SYNC_STALL on the _NodeId mixer and on the physical m_SplitPhysicalId mixer which is the one that goes to the physical output device.

When we heard an audible pause we checked the logs and found that at that exact moment the m_SplitPhysicalId stalled and resumed pretty much instantly:
2026-06-25 11:38:07.786 (2026-06-25 07:38:07.786) : AudioNode Bus A Split Stalled: handle = -2147483337 : channel = 80000135
2026-06-25 11:38:07.786 (2026-06-25 07:38:07.786) : AudioNode Bus A Split Recovered: handle = -2147483337 : channel = 80000135

There is no logging for the _NodeId mixer stalling, just the split.

Yep, a BASS_SYNC_STALL sync is triggered when out of data to play, so it doesn't apply to decoding channels (like _NodeId), except when set on a mixer source via BASS_Mixer_ChannelSetSync.

So it looks like the mixer ran out of data to play from its source(s). What are its source(s)? Presumably, it doesn't have a SilenceProc source or BASS_MIXER_NONSTOP flag set?

Chris Oakley

Okay, we're going to give the NONSTOP another outing. Will report.

QuoteYep, a BASS_SYNC_STALL sync is triggered when out of data to play, so it doesn't apply to decoding channels (like _NodeId), except when set on a mixer source via BASS_Mixer_ChannelSetSync.
Got you. I forgot that.

QuoteSo it looks like the mixer ran out of data to play from its source(s). What are its source(s)? Presumably, it doesn't have a SilenceProc source or BASS_MIXER_NONSTOP flag set?
The sources for the _NodeID mixer is 8 other DECODE mixers set up like this:
_Mixer = BassMix.BASS_Mixer_StreamCreate(_DeviceFrequency, 2, BASSFlag.BASS_STREAM_DECODE)
They are added to the _NodeID. There is no slience proc here.

Then when a file plays it's loaded like this:
_Stream = Bass.BASS_StreamCreateFile(_Filename, 0, 0, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_ASYNCFILE)Then that is added into the _Mixer.

So there is no immediate obvious reason why anything should stop is there?

Ian @ un4seen

If the mixer's sources are files then a stall would be strange, as there should always be data available from files (if not ended). Is there a chance that BASS_StreamCreateFileUser or BASS_StreamCreateURL are used instead of BASS_StreamCreateFile in some cases? If BASS_StreamCreateFile is definitely being used in this case, please confirm what file format/decoder it is (check the "ctype" with BASS_ChannelGetInfo) and check if the problem doesn't happen when playing a different file format. You could also try removing the BASS_ASYNCFILE flag, to check if the problem may be related to that.

Chris Oakley

Before we make any further changes I just wanted to clarify a further point. Whilst we play from files, we also have a memory caching process which loads upcoming files into memory and then we play from there.
_Stream = Bass.BASS_StreamCreateFile(_MemoryStream.MemoryFile, 0L, _MemoryStream.Length, BASSFlag.BASS_STREAM_DECODE)This is what it's been doing so far during all our testing. It works fine and has for years, so I don't foresee any issues with this process, but I wonder if memory access could be the reason. If so, why would it stop on just the physical output and not any other output like the recorded audio or the streaming?!

I've stopped it doing this on one of the problem machines so now it's purely playing from the file.

Ian @ un4seen

I think that's very unlikely to be the cause of the problem. Was the file playing from memory when the problem happened then? That eliminates BASS_ASYNCFILE having anything to do with it, if so. Please do also check what the file format/decoder is.

Chris Oakley

Yes, but in the past it's happened if it was playing from a file or memory.

The file format for one of the most recent pauses was just a straightforward PCM WAV, 441000Hz, 16-bit, Stereo.

Chris Oakley

I don't want to get ahead of myself but we set one PC to play from memory and the other to just from the files. Since then the one playing from files hasn't stalled. The other did, so we've now disabled playing from memory on both to see if this is relevant in some way.

I did say we've tried this before, but that was using the DSP_StreamCopy - we're now using the proper BASS_Split.

Chris Oakley

Okay, so it can't be related to anything to do with playing audio from memory because we've just had another stall on a station playing the files directly and the file was halfway through. Nothing else was happening at the point it paused.

It's interesting as well that all mixers outputting to the physical device stall even though only one of them has the audio file being routed through it:
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus A Split Stalled: handle = -2147483405 : channel = 800000F1
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus A Split Recovered: handle = -2147483405 : channel = 800000F1
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus B Split Stalled: handle = -2147483402 : channel = 800000F4
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus B Split Recovered: handle = -2147483402 : channel = 800000F4
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus C Split Stalled: handle = -2147483399 : channel = 800000F7
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus C Split Recovered: handle = -2147483399 : channel = 800000F7
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus D Split Stalled: handle = -2147483396 : channel = 800000FA
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus D Split Recovered: handle = -2147483396 : channel = 800000FA
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus E Split Stalled: handle = -2147483591 : channel = 80000037
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus E Split Recovered: handle = -2147483591 : channel = 80000037
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus F Split Stalled: handle = -2147483580 : channel = 80000042
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus F Split Recovered: handle = -2147483580 : channel = 80000042
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus G Split Stalled: handle = -2147483569 : channel = 8000004D
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus G Split Recovered: handle = -2147483569 : channel = 8000004D
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus H Split Stalled: handle = -2147483558 : channel = 80000058
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus H Split Recovered: handle = -2147483558 : channel = 80000058
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus I Split Stalled: handle = -2147483547 : channel = 80000063
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus I Split Recovered: handle = -2147483547 : channel = 80000063
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus J Split Stalled: handle = -2147483536 : channel = 8000006E
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus J Split Recovered: handle = -2147483536 : channel = 8000006E
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus K Split Stalled: handle = -2147483393 : channel = 800000FD
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus K Split Recovered: handle = -2147483393 : channel = 800000FD
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus M Split Stalled: handle = -2147483503 : channel = 8000008F
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus M Split Recovered: handle = -2147483503 : channel = 8000008F
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus N Split Stalled: handle = -2147483492 : channel = 8000009A
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus N Split Recovered: handle = -2147483492 : channel = 8000009A

Any thoughts?

Ian @ un4seen

What are the other mixers playing? Is there a common source (via splitters) between all of them (including the one with the file)? If there's a live source (ie. not a file) that has the BASS_MIXER_CHAN_LIMIT flag set on it, then that could explain the stalling (when the live source has no data available).

Chris Oakley

No, we don't have anything using the BASS_MIXER_CHAN_LIMIT flag.

The other mixers are just the same, they are split off to the physical output device, and whilst there is no audio file data being sent through them, they still stall in the same way.

I'm not sure what you might be thinking of when you ask if there is a common source.

Ian @ un4seen

The "common source" question was to see if the mixers may be stalling at the same time because they have the same source that's run out of data.

The other mixers have no sources then, not even a SilenceProc stream? Does the file mixer have any other sources besides the file? If you're unsure, you can use BASS_Mixer_StreamGetChannels at any time (eg. in the BASS_SYNC_STALL callback) to check what sources a mixer has.

Chris Oakley

No, we got rid of the SilenceProc and are using the NONSTOP flag.

To my knowledge there would be no other sources. By source you mean an open file stream added to a mixer and in turn that mixer could be added to another mixer, eventually ending up at the main mixer where the split is to the physical device?

Chris Oakley

Just further to the above, we've checked the channel count as you asked and it shows that some of the mixers that stalled, like F for example, don't have any channels on them at all:
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus F Split Stalled: handle = -2147483580 : channel = 80000042
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus F Split Recovered: handle = -2147483580 : channel = 80000042

The BASS_Mixer_StreamGetChannels returns no channels, posing the question how can it stall?!

Ian @ un4seen

Quote from: Chris OakleyNo, we got rid of the SilenceProc and are using the NONSTOP flag.

OK, so the problem still happened after doing that? Even if it doesn't help with the problem, it will at least save a little CPU.

Quote from: Chris OakleyTo my knowledge there would be no other sources. By source you mean an open file stream added to a mixer and in turn that mixer could be added to another mixer, eventually ending up at the main mixer where the split is to the physical device?

A mixer source would be anything added to a mixer via BASS_Mixer_StreamAddChannel(Ex). It wouldn't necesarilly be only file streams, eg. your old SilenceProc streams.

Quote from: Chris OakleyJust further to the above, we've checked the channel count as you asked and it shows that some of the mixers that stalled, like F for example, don't have any channels on them at all:
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus F Split Stalled: handle = -2147483580 : channel = 80000042
2026-06-26 10:48:14.637 (2026-06-26 06:48:14.637) : AudioNode Bus F Split Recovered: handle = -2147483580 : channel = 80000042

The BASS_Mixer_StreamGetChannels returns no channels, posing the question how can it stall?!

Do you mean BASS_Mixer_StreamGetChannels returns 0 when called in the BASS_SYNC_STALL callback? Note it will need to be called on the mixer rather than the splitter. BASS_Split_StreamGetSource can be used in that:

mixer = BASS_Split_StreamGetSource(splitter); // get the mixer handle
numsources = BASS_Mixer_StreamGetChannels(mixer, NULL, 0); // get the number of sources

Anyway, if the BASS_MIXER_NONSTOP flag is set on the mixer then it shouldn't ever run out of data. One way that it could still stall (and trigger BASS_SYNC_STALL) is if a playback buffer update cycle takes too long (longer than the already buffered data), but that doesn't apply when playback buffering is disabled. Are you still setting BASS_ATTRIB_BUFFER=0 on the output splitters? If so, I think I will need to send you a debug BASS version to get more info. Please first confirm that the problem is happening with the latest BASS and BASSmix builds:

    www.un4seen.com/stuff/bass.zip
    www.un4seen.com/stuff/bassmix.zip

Chris Oakley

QuoteA mixer source would be anything added to a mixer via BASS_Mixer_StreamAddChannel(Ex). It wouldn't necesarilly be only file streams, eg. your old SilenceProc streams.
Ah okay, so it doesn't funnel down? So if I have a file added into a mixer, and then that mixeris added to another mixer, then I get the channels on the last mixer, I wouldn't see the file id added further down?

QuoteDo you mean BASS_Mixer_StreamGetChannels returns 0 when called in the BASS_SYNC_STALL callback?
We didn't check that, we just added a command to our app to return the data when we desired. I can get this information at stall time if needed.

We are definitely not using any form of StreamProc to keep things moving. It's BASS_MIXER_NONSTOP replacing that.

The BASS_ATTRIB_BUFFER is being set to 0.25 on the output splitters so 250ms.

You may be right, we might need to go to defcon 1 and put a debug bass and bassmix on the machine. We are using the latest BASS.DLL (2.4.18.3) and BASS.NET (2.4.18.2) and BASSMIX.DLL (2.4.12.0)

Ian @ un4seen

#19
Quote from: Chris OakleyAh okay, so it doesn't funnel down? So if I have a file added into a mixer, and then that mixeris added to another mixer, then I get the channels on the last mixer, I wouldn't see the file id added further down?

Correct. BASS_Mixer_StreamGetChannels only includes the direct sources of the specified mixer. It would need to be called again for any submixer.

Quote from: Chris OakleyThe BASS_ATTRIB_BUFFER is being set to 0.25 on the output splitters so 250ms.

Ah! That clears the mystery of the multiple stalling mixers then: there was a delay (longer than 250ms) within the processing of one of them, which also held up processing of the others, and the playback buffers became empty in the meantime, resulting in them all stalling. You can avoid a delayed playback channel affecting others by enabling multiple update threads via the BASS_CONFIG_UPDATETHREADS option.

Now you just need to find what's causing the delay. Do you have any encoders set on the mixers (or their sources) when the problem happens, and if so, do you have the BASS_ENCODE_QUEUE flag set on them? Also check if you have any callback functions (eg. SYNCPROC/DSPPROC/STREAMPROC) that need to wait for something, eg. a lock/mutex or UI updates.