Author Topic: ASIO Problem  (Read 2303 times)

udo

  • Posts: 49
ASIO Problem
« on: 31 Aug '18 - 20:02 »
Hi,

we have a strange problem with ASIO.
At some computers playing sounds like a jumping laser. Soundfile here(recorded with phone): https://tinyurl.com/y7c9yrzy
This happen very rare, mostly after a short time its ok again but also it can happen that a stop is needed.
Asio get data like this:

Code: [Select]
private int AsioOutProc(bool input, int channel, IntPtr buffer, int length, IntPtr user)
{
int c = Bass.BASS_ChannelGetData(user.ToInt32(), buffer, length);

if (c == -1)
{
c = 0; // an error, no data
}   

return c;
}

With Wasapi this never happened, data are handled same like Asio.
XM-Player dont have this problem at same mashines.
Why this can happen?  How to find the reason?

thanks for any hint.
« Last Edit: 1 Sep '18 - 08:53 by udo »

Ian @ un4seen

  • Administrator
  • Posts: 21533
Re: ASIO Problem
« Reply #1 on: 3 Sep '18 - 15:55 »
That sounds like buffered sound being repeated. That can happen with DirectSound output when a looping DirectSound buffer isn't being updated. I haven't personally heard the same when using ASIO output but it's possible that an ASIO driver could have a looping circular buffer too. In that case, the problem could be caused by the ASIOPROC being blocked. If it's only temporary (ie. not a deadlock), it could perhaps be an I/O delay. Are you playing files? If so, and you aren't already, you could try using the BASS_ASYNCFILE flag on the streams. If that isn't it, please try logging the entry and exit (and time between) of the ASIOPROC, and see if there is a large time between entry and exit when the problem happens.

udo

  • Posts: 49
Re: ASIO Problem
« Reply #2 on: 3 Sep '18 - 16:09 »
I play it not directly fom file. The file is loaded before completly in memory.
Code: [Select]
FileStream fs = File.OpenRead(fn);
long length = fs.Length;
byte[] buffer = new byte[length];               
fs.Read(buffer, 0, (int)length);
fs.Close();
GCHandle hGCFile = GCHandle.Alloc(buffer, GCHandleType.Pinned);
//......
int stream = Bass.BASS_StreamCreateFile(entry.hGCFile.AddrOfPinnedObject(), 0, entry.length, BASSFlag.BASS_STREAM_DECODE);

Sometimes it seems to be a deadlock(stopp is needed), mostly its temporary.
Is BASS_ASYNCFILE also an option if not playing from file directly?
I will check the time at ASIOPROC.

Is it possible that calling BassAsio.BASS_ASIO_ChannelGetLevel at a timer routine make this problem?
« Last Edit: 3 Sep '18 - 16:14 by udo »

Ian @ un4seen

  • Administrator
  • Posts: 21533
Re: ASIO Problem
« Reply #3 on: 3 Sep '18 - 17:26 »
Ah. As you're using .Net, perhaps it is garbage collection delaying your ASIOPROC?

BASS_ASYNCFILE won't have any effect when playing a file from memory, so you don't need to bother trying that.

udo

  • Posts: 49
Re: ASIO Problem
« Reply #4 on: 3 Sep '18 - 19:54 »
Ah. As you're using .Net, perhaps it is garbage collection delaying your ASIOPROC?

Hmmm. But why should this happen only with Asio and never with Wasapi?

radio42

  • Posts: 4643
Re: ASIO Problem
« Reply #5 on: 4 Sep '18 - 07:15 »
The only difference between ASIO and WASAPI is, that ASIO might be called more often, but I agree, it should happen to WASAPI as well at some time.
Maybe your PC or network introduces some latency spikes to your system, which cause the issue.
Have you tried increasing your AISO buffer to see, if the issues disappears?
« Last Edit: 4 Sep '18 - 07:20 by radio42 »

udo

  • Posts: 49
Re: ASIO Problem
« Reply #6 on: 4 Sep '18 - 07:51 »
Have you tried increasing your AISO buffer to see, if the issues disappears?

Increasing the USB- and ASIO- buffer at Soundcard doesnt help.
At bassAsio its the perefered buffer size(like at XM-Player where it not happened).

Is Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_BUFFER... also important at Asio?
« Last Edit: 4 Sep '18 - 08:11 by udo »

Ian @ un4seen

  • Administrator
  • Posts: 21533
Re: ASIO Problem
« Reply #7 on: 4 Sep '18 - 15:39 »
The BASS_CONFIG_BUFFER setting won't affect ASIO output.

Here's a BASSASIO update for you to try:

   www.un4seen.com/stuff/bassasio.zip

It adds a new BASS_ASIO_ChannelEnableBASS function:

Code: [Select]
BOOL BASS_ASIO_ChannelEnableBASS(DWORD channel, DWORD handle, BOOL join);

It allows you to play a BASS decoding channel without providing an ASIOPROC, so that .Net doesn't get involved in the ASIO thread(s). It will also set the ASIO channel format and rate, and optionally handle channel joining too. "channel" is the first ASIO output channel, "handle" is a BASS channel handle. Obviously, it isn't in BASS.Net yet, but I think you can still use it directly via DllImport? Let me know whether it prevents the problem happening.

udo

  • Posts: 49
Re: ASIO Problem
« Reply #8 on: 4 Sep '18 - 16:21 »
Thanks.
I can import it directly, but it needs some days to get a feedback from users.
At my computers i never had this problem.

rv

  • Posts: 255
Re: ASIO Problem
« Reply #9 on: 4 Sep '18 - 23:36 »
Oh nice ! I will try this too.
I actually myself set the ASIO channel format and rate use this before the BASS_ASIO_ChannelEnable

My actual code is :

Code: [Select]
    BASS_ASIO_SetRate(44100)
    BASS_ASIO_ChannelSetRate(False, FirstChannelNumber, 44100)
 Dim flg As UInt32 = BASS_ASIO_FORMAT_FLOAT Or BASS_ASIO_FORMAT_DITHER
            BASS_ASIO_ChannelSetFormat(False, FirstChannelNumber, flg) ' set the source format (float)
 BASS_ASIO_ChannelEnable(False, FirstChannelNumber, _myAsioProc, 0) 'enable the 1st channel...
            BASS_ASIO_ChannelJoin(False, FirstChannelNumber + 1, FirstChannelNumber) ' ...and join the next

is it still possible to set the rate and format myself? before or  after the new EnableBASS?   
The join argument is a BOOL, so the TRUE value will cause joining FirstChannelNumber + 1 with FirstChannelNumber ?


Maybe you can provide the same for the WASAPI ? as we really have some penalties with the .net managed stack going back and forth every few ms , and the garbage collector can stop the process for few ms too

Maybe a special value for the WASAPI_PROC in the BASS_WASAPI_Init ?

radio42

  • Posts: 4643
Re: ASIO Problem
« Reply #10 on: 5 Sep '18 - 08:35 »
If it is a GC issue, another option to overcome this issue was already discussed many years ago...
One way for sure is to use a so called mixed mode assembly, meaning making sure, that your ASIOPROC does not 'live' in the managed .Net domain, but only in unmanaged code.
A sample of how to code a mixed-mode assembly with BASS/Bass.Net is given here:
http://www.un4seen.com/forum/?topic=4932.msg60399#msg60399

Note, that in this case Ian delivers a certain default ASIOPROC, he might need to provide different ones for Input and Output; plus the same for WASAPIPROC.
Certainly these 'default' provided ones would have certain limits.

In addition, if you want to deal with any DSPPROC, RECORDPROC etc. you might face the same issue.
As such, I guess the only reliable solution is effectively to look at the above proposed mixed-mode assembly solution.

rv

  • Posts: 255
Re: ASIO Problem
« Reply #11 on: 5 Sep '18 - 10:35 »
Yes, however Mixed mode assembly does not exists with VB.net that I use

yes, Input should be provided too. Maybe with a BOOL like the  BASS_ASIO_ChannelEnable


My actual ASIO and WASAPI proc are simple, to send a mixer stream to the output buffer, or send the input buffer to a mixer stream.
If this few lines of code can be done in the BASS part, I would probably sleep better :)

Code: [Select]
    Private Function On_AsioCallback(ByVal input As Boolean, ByVal channel As UInt32, ByVal buffer As IntPtr, ByVal length As UInt32, ByVal user As IntPtr) As UInt32
        Dim c As Integer = BASS_ChannelGetData(_AudioStream, buffer, length)
        If c = -1 Then Return 0 Else Return c
End Function

    Private Function On_AsioCallbackIn(ByVal input As Boolean, ByVal channel As UInt32, ByVal buffer As IntPtr, ByVal length As UInt32, ByVal user As IntPtr) As UInt32
        If BASS_Mixer_ChannelGetMixer(_InputStream) Then '// the push stream is in a mixer
            Dim iA As UInt32
            iA = BASS_StreamPutData(_InputStream, buffer, length) ' // pass the data to it
        End If
    End Function

Ian @ un4seen

  • Administrator
  • Posts: 21533
Re: ASIO Problem
« Reply #12 on: 5 Sep '18 - 17:42 »
is it still possible to set the rate and format myself? before or  after the new EnableBASS?   

Yes, you can change the rate and format after calling BASS_ASIO_ChannelEnableBASS, using BASS_ASIO_ChannelSetRate/Format.

The join argument is a BOOL, so the TRUE value will cause joining FirstChannelNumber + 1 with FirstChannelNumber ?

Yes, when join=true, BASS_ASIO_ChannelEnableBASS will join the next ASIO channels (depending on how many channels the provided BASS stream has) to the first one. This is optional in case the BASS_ASIO_JOINORDER option is used.

Maybe you can provide the same for the WASAPI ? as we really have some penalties with the .net managed stack going back and forth every few ms , and the garbage collector can stop the process for few ms too

Maybe a special value for the WASAPI_PROC in the BASS_WASAPI_Init ?

That is the plan :)

yes, Input should be provided too. Maybe with a BOOL like the  BASS_ASIO_ChannelEnable

Here's another update for you to try, which adds an "input" parameter to the BASS_ASIO_ChannelEnableBASS function:

   www.un4seen.com/stuff/bassasio.zip

When input=true, the provided BASS handle must be a "push" stream, ie. using STREAMPROC_PUSH.

rv

  • Posts: 255
Re: ASIO Problem
« Reply #13 on: 6 Sep '18 - 14:43 »
Oh yes, I have tested and this is very good  !

I have still some problems with the INPUT the first time or when I change from ASIO to WASAPI etc.... there is no sound at all on output from other stream too (not sure if input is processed too). I am not sure if my code is OK
Are you sure all is well released with a simple call of
BASS_ASIO_Stop()
BASS_ASIO_Free() ?

Also, when trying the INPUT in MONO mode (not joined)  and the push stream has only one channel , the audio is still stereo and joined on the output. Not sure if it is a problem with ASIO4ALL


I am ready to test  WASAPI too.
How can we select a mono wasapi input, as they seems to be only stereo?
on ASIO, all single inputs are separate but not on WASAPI

Ian @ un4seen

  • Administrator
  • Posts: 21533
Re: ASIO Problem
« Reply #14 on: 6 Sep '18 - 16:34 »
I have still some problems with the INPUT the first time or when I change from ASIO to WASAPI etc.... there is no sound at all on output from other stream too (not sure if input is processed too). I am not sure if my code is OK
Are you sure all is well released with a simple call of
BASS_ASIO_Stop()
BASS_ASIO_Free() ?

Is this problem only with the BASSASIO update or with the release version too? BASS_ASIO_Free will release and unload the ASIO driver. Does delaying the subsequent BASS_WASAPI_Init call make any difference? Also, are you using shared or exclusive mode WASAPI, and does that make a difference?

Also, when trying the INPUT in MONO mode (not joined)  and the push stream has only one channel , the audio is still stereo and joined on the output. Not sure if it is a problem with ASIO4ALL

Are you playing the push stream directly on the ASIO output, or is it going through a mixer? If the latter, is the mixer mono to stereo? If it's stereo, you can use the BASS_SPEAKER_FRONTLEFT/RIGHT flag when adding the push stream to the mix, to play it on only the left/right channel. Another option is to use the BASS_ATTRIB_PAN setting.

rv

  • Posts: 255
Re: ASIO Problem
« Reply #15 on: 6 Sep '18 - 23:55 »
I have tried the new ASIO with a pro audio card, and it seems to work for now.
Can you do the WASAPI version of it? :)

What I want, is for example , to take the 6th microphone input of the audio card, and send it to a mono push stream, connected to a stereo mixer, connected to the audio out

With ASIO, this is working great as all channels are singles on ASIO
How to do this with WASAPI? Actually it displays many stereo devices 1-2     3-4   5-6
So how to init only the 6th input

Ian @ un4seen

  • Administrator
  • Posts: 21533
Re: ASIO Problem
« Reply #16 on: 7 Sep '18 - 14:32 »
In that case, you would need to initialize the 5-6 device and then discard the first channel in the captured data. You could do that by feeding the data to a stereo push stream, and setting a splitter stream on that with chanmap = [1, -1].

Here's the BASSWASAPI update with the new BASS channel option, like the earlier BASSASIO update:

   www.un4seen.com/stuff/basswasapi.zip

It adds a WASAPIPROC_BASS option, which can be used in the "proc" parameter of a BASS_WASAPI_Init call with the "user" parameter set to the BASS channel handle. The BASS channel must be floating-point (BASS_SAMPLE_FLOAT) and have a sample format supported by the WASAPI device, eg. the mix format (available from BASS_WASAPI_GetDeviceInfo).

rv

  • Posts: 255
Re: ASIO Problem
« Reply #17 on: 7 Sep '18 - 15:57 »
wow ! it is working very great and it is more robust now
thank you very much !
i will try then on low cpu machines like atom.... that were too much limit before

udo

  • Posts: 49
Re: ASIO Problem
« Reply #18 on: 15 Oct '18 - 14:19 »
The BASS_CONFIG_BUFFER setting won't affect ASIO output.

Here's a BASSASIO update for you to try:

   www.un4seen.com/stuff/bassasio.zip

It adds a new BASS_ASIO_ChannelEnableBASS function:

Code: [Select]
BOOL BASS_ASIO_ChannelEnableBASS(DWORD channel, DWORD handle, BOOL join);

It allows you to play a BASS decoding channel without providing an ASIOPROC, so that .Net doesn't get involved in the ASIO thread(s). It will also set the ASIO channel format and rate, and optionally handle channel joining too. "channel" is the first ASIO output channel, "handle" is a BASS channel handle. Obviously, it isn't in BASS.Net yet, but I think you can still use it directly via DllImport? Let me know whether it prevents the problem happening.

The problem is fixed without the ASIOPROC, there are no more customer complaints.
What i dont understand is why sometimes it's never corrected and a stop was needed.

For what ist this ASIOPROC usefull?

Ian @ un4seen

  • Administrator
  • Posts: 21533
Re: ASIO Problem
« Reply #19 on: 15 Oct '18 - 15:30 »
Good to hear that the new option seems to have helped. I guess that confirms that the problem was caused by .Net garbage collection.

An ASIOPROC is useful if you want to generate the sample data yourself, not simply play a BASS channel. BASSASIO can actually be used without BASS at all.

radio42

  • Posts: 4643
Re: ASIO Problem
« Reply #20 on: 15 Oct '18 - 15:36 »
Another example is, where you want to copy the 'recorded' sample data of an ASIO input device to an ASIO output device e.g. by using an internal push stream or by using your own full-duplex buffer.

rv

  • Posts: 255
Re: ASIO Problem
« Reply #21 on: 30 Oct '18 - 20:25 »
Hello Ian,

I have a problem with this new WASAPIPROC_BASS  value for the proc
It works great with the 64 bit version of the basswasapi.dll stuff, but with the 32 bit version, i get an overflow error


Not usre if it is a .net problem
I have tried values of -1 when proc is Integer or 4294967295UI when proc is UInteger

It is possible there is something wrong with the 32 bit version?

Ian @ un4seen

  • Administrator
  • Posts: 21533
Re: ASIO Problem
« Reply #22 on: 31 Oct '18 - 16:27 »
If I recall correctly, you are importing the BASS functions yourself rather than using BASS.Net? If so, how have you defined the BASS_WASAPI_Init "proc" and "user" parameters? To make it work on both 32-bit and 64-bit, they should be "IntPtr", so that they're the same size as a pointer.

rv

  • Posts: 255
Re: ASIO Problem
« Reply #23 on: 31 Oct '18 - 17:14 »
Even if I put IntPtr it is causing an overflow message, even if I put 0 for the proc value
The code simply work with 64 bit version, but not with 32 bit version.

my code

Flg = BASS_WASAPI_EXCLUSIVE Or BASS_WASAPI_SAMPLES Or BASS_WASAPI_EVENT


BASS_WASAPI_Init(DeviceNumber, 44100, 2, Flg, 256, 0.005, 4294967295UI, _AudioStream)

Can you check again your code with the WASAPIPROC_BASS   with 32 bit dll?  or generate again the dll? maybe a compiling mistake?




Ian @ un4seen

  • Administrator
  • Posts: 21533
Re: ASIO Problem
« Reply #24 on: 31 Oct '18 - 17:52 »
It is working in C/C++ code here. Where/when are you seeing the overflow error that you mention? Is it a .Net thing?