Clone "mixed" stream to another output device ?

Started by Couin,

Couin

Hi Ian :)

I tried these solution, looks OK if changing channels while nothing is playing, but I get bad result is something is playing while I change channels: on the old channels I get stuttering last part of audio. If I come back on old channels, the stuttering diseappear and the sound plays fine.

I attach a zip file including a recording of channels 5+6 ("Right deck" output of Rane SL3).
@10 seconds, I change for channels "1+2" (AUX Output)
@16 seconds, I change back for channels 5+6 (Right Deck)

Of course "1+2" or "5+6" is to match with ASIO panel, but BASS ASIO channels are 0+1 , and 4+5.

The dropdown list (cmbASIOChanOut) allows to choose between these possibilities:
1+2
2+3
3+4
4+5
5+6

Here is the code:
Call BASS_ASIO_Stop
Call BASS_ASIO_ChannelEnable(BASSFALSE, ASIOChanOut, 0, 0) 'disable old channels
ASIOChanOut = cmbASIOChanOut.ListIndex
Call BASS_ASIO_ChannelEnableBASS(0, ASIOChanOut, SplitOutDev(0), BASSTRUE)
Call BASS_ASIO_Start(0, 0)

I tried to place BASS_ASIO_ChannelReset but change nothing.

If I remove BASS_ASIO_Stop call, it's ok, but I don't know if it's a clean procedure.


Ian @ un4seen

That's strange. Sounds like the ASIO driver isn't clearing and/or ignoring the disabled channel buffers. Here's a BASSASIO update for you to try, which will clear the buffers in BASS_ASIO_Stop.

   www.un4seen.com/stuff/bassasio.zip

Let me know whether it helps.

Couin

Hi Ian,

Thanks for the dll, but it did not changed the behavior.

Objectively, I think that not putting BASS_ASIO_Stop is a real problem, given that we don't change channels regularly but just at the hardware configuration.
Also, knowing that I want to use ASIO inputs, BASS_ASIO_Stop could stop the inputs (?)

But I noticed another problem (I did not saw it before, because I plugged only one stereo cable on 5+6):
If I change the channels, sound stops on old channel, but I get no sound on new selecte channels.

The only way to get sound back is re-selecting initial channels, or restart the software.

Couin

Hi,

I read in the documentation that no more channel can be enabled if device has not been stopped before, that should explain why I get no sound on new selected channels.

So must use BASS_ASIO_Stop but I get stuttering , even if I stop all streams before.

Ian @ un4seen

Yes, the ASIO device does need to be stopped before enabling new ASIO channels (output or input), and BASS_ASIO_ChannelEnable/etc will otherwise fail with BASS_ERROR_START. It is possible to disable and then re-enable the same channels (ie. not new ones) without stopping the device, so if even a slight pause to enable channels would be a problem then you could pre-enable all channels.

But first, I think it would be best to get to the bottom of the stuttering sound issue. To narrow it down, please try using a plain file stream (eg. from BASS_StreamCreateFile) instead of a splitter in the BASS_ASIO_ChannelEnableBASS calls and see if the problem is still present then.

Couin

Hi Ian,

That what I was thinkng  (testing without split) -> Same result

Tested with a minimal project, without mixer -> Same result

Added a button that calls Bass_ASIo_Stop and I notice one repeat of last audio part (around few 200 ms I think).


The code of project (1 button "btStop", 1 button "btExit", 1 dropdown list (Combo) "cmbASIOChanOut", 1 label "lblfeedback"):

Option Explicit

Dim AudioStream As Long
Dim ASIODevOut As Integer
Dim ASIOChanOutCount As Integer
Dim ASIOChanOut As Integer

Private Sub btExit_Click()
Unload Me
End Sub

Private Sub btStop_Click()
    Call BASS_ASIO_Stop
End Sub

Public Sub cmbASIOChanOut_Click()
    Dim i As Integer

    Call BASS_ASIO_Stop   'stop ASIO processing
    Call BASS_ASIO_ChannelEnable(0, ASIOChanOut, 0, 0) 'disable old inputs
    ASIOChanOut = cmbASIOChanOut.ListIndex
    Debug.Print ASIOChanOut
    Call BASS_ASIO_ChannelEnableBASS(0, ASIOChanOut, AudioStream, BASSTRUE) 'enable new inputs
    Call BASS_ASIO_Start(0, 0) 'resume ASIO processing
   
End Sub

Private Sub Form_Load()
    ' change and set the current path, to prevent from VB not finding BASS.DLL
    ChDrive App.Path
    ChDir App.Path
   
    Call BASS_Init(0, 44100, 0, 0, 0)
   
    ASIODevOut = 2
    ASIOChanOut = 4
    Call BASS_ASIO_Init(ASIODevOut, 0)
    ListChanOutASIO
   
    AudioStream = BASS_StreamCreateFile(BASSFALSE, StrPtr("track.mp3"), 0, 0, BASS_STREAM_DECODE)
    lblfeedback.Caption = AudioStream
   
    Dim i As BASS_CHANNELINFO
   
    Call BASS_ASIO_ChannelEnableBASS(0, ASIOChanOut, AudioStream, BASSTRUE)
    Call BASS_ASIO_SetRate(i.freq) 'try to set the device rate to avoid resampling

    'start it using default buffer size
    If (BASS_ASIO_Start(0, 0) = 0) Then
        Call BASS_ASIO_Free
        Call BASS_Free
        MsgBox "Can't initialize device " & ASIODevOut
    End If
   
End Sub

Public Sub ListChanOutASIO()

    Dim info As BASS_ASIO_INFO
    Call BASS_ASIO_GetInfo(info)
    ASIOChanOutCount = info.outputs
 
    Dim o As Integer
    cmbASIOChanOut.Clear
    For o = 1 To ASIOChanOutCount - 1
        cmbASIOChanOut.AddItem o & "+" & o + 1
    Next o
    cmbASIOChanOut.ListIndex = ASIOChanOut
   
End Sub

Private Sub Form_Unload(Cancel As Integer)
        Call BASS_ASIO_Free
        Call BASS_Free
End Sub

Ian @ un4seen

The problem doesn't seem to be happening here (not using your VB code above but something very similar in C), so I suspect it may be driver-specific. To confirm that, does it happen for you when using a different ASIO device/driver? If you don't currently have another one to try, you could try ASIO4ALL.

Couin

Hi,

With ASIO4ALL, I can't reproduce, but perhaps because not a real ASIO device (?).
I have no other ASIO device (hardware) ellse to test for the moment, Rane SL 1 ASIO drivers seems not Win10 compatible :(

Ian @ un4seen

OK. Just to be sure VB6 isn't interfering somehow, here's a modified version of BASSASIO's CONTEST.C example for you to try. When you press the spacebar, it'll switch to the next stereo output pair. Do you hear the problem when doing that?

Couin

Hi Ian,

Thanks for test app :)

I had to uninstall ASIO4ALL because it was taking the first device number (perhaps in an eventual next test file, adding a parameter to set the device number in the command line, like "asiotest.exe 0 test.mp3", where 0 is the device number ?).

I get the same result than VB6 app, on channel changing.

I made a small video to show you what I exactly get. At the end, I stop the player with CTRL C in the DOS window.
https://youtu.be/4Tt3nr4MTxc

Thanks :)


Ian @ un4seen

That sounds like the ASIO driver is playing/repeating the first channel's most recent data even after it's been disabled. Do you have speakers plugged into the other channels? If not, please try that and see if the proper sound is heard on them or if they're always silent.

Btw, you can use the "-l" option to list available ASIO devices, and "-d <device>" to choose the one to use.

Couin

Hi Ian

The sound you ear is the sound of channel 0 (and 1 of course).
When I hit the spacebar (you can ear the hit too), it switches to 2 (and 3) but the speakers still plugged to 0 + 1, so you can ear that the output repeats the last recent datas in loop.

The sound on 2 + 3 is good (tested by moving Cinch connectors fro 0 +1 to 2 + 3 ).

If I hit again the spacebar, the song plays well on 4 + 5, and I get the same loop problem on 2 + 3 .

Hitting again spacebar, the track goes back to 0 + 1, it plays good, the previous stuttering on 0 +1 gone. 4 + 5 makes the same loop.

In fact, each time I leave from channels, they loop on last datas.
If I send again the song on a stuttering channel, the song plays correctly.

Ian @ un4seen

Here's an update with a new option that I think should help:

   www.un4seen.com/stuff/bassasio.zip

This is the new option:

#define BASS_ASIO_ALLOUTPUTS 16 // pre-enable all output channels

When that's used with BASS_ASIO_Init, the ASIO driver will be told to enable all output channels (including unused ones), so that you can switch them after BASS_ASIO_Start without having to call BASS_ASIO_Stop first. As well as avoiding the repeating sound problem with your device (hopefully), it'll also avoid any gap when switching outputs. An updated ASIOTEST.EXE is included for you to try.

For completeness, there's also an option to do the same for input channels:

#define BASS_ASIO_ALLINPUTS 8 // pre-enable all input channels

Note these options can't be used together with the BASS_ASIO_JOINORDER option.

Couin

Hi Ian ,

Thanks for help :)

It looks running as expected, changing channel (with spacebar) no longer makes stuttering sound of last used channels :=)

I will try to adapt to the project, but before, 2 minor questions about the exe you made:
- I get stuttering sound on breaking program (with CTRL C in the DOS window), I think it it because of breaking program without stopping stream and freeing cleanly the device, can you confirm?
- On channel change, the VU meters does not measure the audio output sif channel is not 0 (see below), is it due to VU meter still "connected" to channel 0(+1)?

QuoteC:\c>asiotest.exe test.mp3
BASS+ASIO simple console player
-------------------------------
ctype: 10005
format: 44100 Hz, 2 chan
length: 3:50 (10147439 samples)
 0:16 (00731144) | L -************ ************- R - cpu 0.20%
output 2
 0:24 (01063708) | L ------------- ------------- R - cpu 0.19%
output 4
 0:25 (01133429) | L ------------- ------------- R - cpu 0.19%
output 0
 0:26 (01187108) | L -************ ************- R - cpu 0.19%
output 2
 0:27 (01219809) | L ------------- ------------- R - cpu 0.19%
output 4
 0:28 (01242638) | L ------------- ------------- R - cpu 0.19%

About inputs, not tested anything yet, as well as I'm searching how to catch ASIO input and send it to a splitter (to send splitted streams to each mixers). ASIO input is a little confusing for me.

Thanks :)

Ian @ un4seen

Yeah, the example's VU will still be showing channel 0+1 levels, because I didn't bother to update the BASS_ASIO_ChannelGetLevel calls :)

The stuttering sound upon Ctrl+C sounds like it could be the same issue that you had when disabling channels. Perhaps that device doesn't get reset properly unless its ASIO driver is unloaded properly, eg. BASS_ASIO_Free called. Do you have the problem if you try another ASIO driver, eg. ASIO4ALL? By the way, you can quit the example gracefully by pressing any other key (not spacebar).

Couin

Hi Ian,

Thanks for precisions :)

So, with SL3 : CTRL C gives 5 or 6 repeats of last datas. Any key (excepted Spacebar), gives me only one repeat of last playing data.
No repeat with ASIO4ALL.

I have to integrate he DLL and option in the app to see if it will repeat the last sound data (even if playback is finished) or not.

Couin

Hi again,

I added the option in the .bas file, like this:

' BASS_ASIO_Init flags
Global Const BASS_ASIO_THREAD = 1 ' host driver in dedicated thread
Global Const BASS_ASIO_JOINORDER = 2 ' order joined channels by when they were joined
Global Const BASS_ASIO_ALLOUTPUTS = 16  ' pre-enable all output channels
Global Const BASS_ASIO_ALLINPUTS = 8  ' pre-enable all input channels
and replaced the .dll by your last provided.

Here is the code in the dropdown list (ComboBox) :
Call BASS_ASIO_ChannelEnable(BASSFALSE, ASIOChanOut, 0, 0) 'disable old channels
ASIOChanOut = cmbASIOChanOut.ListIndex
Call BASS_ASIO_ChannelEnableBASS(BASSFALSE, ASIOChanOut, MixerMain, BASSTRUE)

It's OK when I open the dropdown list and click on channels I want, but if I scroll with the mousewheel, I sometimes get speed stuttering on "old channels". SO I tested with adding a small pause:
Call BASS_ASIO_ChannelEnable(BASSFALSE, ASIOChanOut, 0, 0) 'disable old channels
hb_sleep (50)
ASIOChanOut = cmbASIOChanOut.ListIndex
Call BASS_ASIO_ChannelEnableBASS(BASSFALSE, ASIOChanOut, MixerMain, BASSTRUE)
and it looks no more stuttering  :P

I also added the disable old channels and hb_sleep line before freeing the device on exit software, and it does not repeat the last data if audio was playing.

Now, I have to manage ASIO inputs, I would send the input to a splitter (and splitted streams to each Main and Aux mixers). I'm digging in the examples but I did not foudn what I search yet lol

Ian @ un4seen

Quote from: CouinIt's OK when I open the dropdown list and click on channels I want, but if I scroll with the mousewheel, I sometimes get speed stuttering on "old channels". SO I tested with adding a small pause:
Call BASS_ASIO_ChannelEnable(BASSFALSE, ASIOChanOut, 0, 0) 'disable old channels
hb_sleep (50)
ASIOChanOut = cmbASIOChanOut.ListIndex
Call BASS_ASIO_ChannelEnableBASS(BASSFALSE, ASIOChanOut, MixerMain, BASSTRUE)
and it looks no more stuttering  :P

Are you getting constant stuttering like before, or is it just briefly while switching channels? Seems strange that the sleep would help with the former, but I guess it might help with the latter by just slowing down how quickly you can change channels. Does moving the sleep to after (instead of before) BASS_ASIO_ChannelEnableBASS have the same effect?

Quote from: CouinNow, I have to manage ASIO inputs, I would send the input to a splitter (and splitted streams to each Main and Aux mixers). I'm digging in the examples but I did not foudn what I search yet lol

If you would like to use BASS_ASIO_ChannelEnableBASS with ASIO input channel(s), then the BASS channel in that call will need to be a "push" stream created with BASS_StreamCreate (proc=STREAMPROC_PUSH), which will receive the data from the ASIO channel(s).

Couin

Hi Ian,

Without the hb_sleep(50) call, it was stuttering faster than previous DLL (that has not ALLOUTPUTS flag). I recorded with my phone, what id does when changing channel while playing, then back to previous channels (playing again normaly) and changed again), you could hear the amount of repeated datas is smaller so repeat is faster.

Thanks for STREAMPROC_PUSH method, I have to see how it works, I tried to use it be no input sound is sent to mixer lol