Author Topic: ASIO Input on 2e Output channel  (Read 865 times)

Ed1966

  • Posts: 142
ASIO Input on 2e Output channel
« on: 21 Nov '19 - 05:43 »
Hi there,

The code below works as far as it goes, but I only hear sound on the first Output soundcard. How can I get sound on the 2nd output?
I don't quite understand.

Just started and wants to link ASIO input to my existing MasterMixer if that is possible. Required for e.g. broadcast live. Etc.

Thanks in advance.
Kind regards,
Eduard.

Code: [Select]
  // initialize BASS "no sound" device
  BASS_Init(0, 48000, 0, Application.Handle, nil);

  // initialize first available ASIO device
  BASS_ASIO_Stop();
  if not (BASS_ASIO_Init(0, BASS_ASIO_THREAD)) then
  begin
    BASS_Free();
    ShowMessage('Can''t initialize ASIO: ' + BASS_ASIO_ErrorGetCode.ToString);
  end;

  Rate := Trunc(BASS_ASIO_GetRate);

  fMixer := BASS_Mixer_StreamCreate(48000, 2, 0 or BASS_MIXER_NONSTOP or BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE);
  if (BASS_ErrorGetCode <> 0) then ShowMessage('BASS_Mixer_StreamCreate: ' + BASS_ErrorGetCode.ToString);

  // create a "push" stream to receive and process the input data
  fChan := BASS_StreamCreate(Rate, 2, BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE, STREAMPROC_PUSH, nil);
  if (BASS_ErrorGetCode <> 0) then ShowMessage('BASS_StreamCreate: ' + BASS_ErrorGetCode.ToString);

  if not BASS_Mixer_StreamAddChannel(fMixer, fChan, BASS_MIXER_DOWNMIX or BASS_MIXER_NORAMPIN) then
    ShowMessage('BASS_Mixer_StreamAddChannel: ' + BASS_ErrorGetCode.ToString);

  // enable ASIO channels (using same stream for input and output)
  BASS_ASIO_ChannelEnableBASS(TRUE, 0, fChan, TRUE);
  BASS_ASIO_ChannelEnableBASS(FALSE, 0, fMixer, TRUE);

  // start with output volume at 0 (in case of nasty feedback)
  BASS_ASIO_ChannelSetVolume(FALSE, 0, 0);
  BASS_ASIO_ChannelSetVolume(FALSE, 1, 0);

  // start the device using default buffer/latency
  if not (BASS_ASIO_Start(0, 0)) then
  begin
    BASS_ASIO_Free();
    BASS_Free();
    ShowMessage('Can''t initialize recording device: ' + BASS_ASIO_ErrorGetCode.ToString);
  end;

Ian @ un4seen

  • Administrator
  • Posts: 22829
Re: ASIO Input on 2e Output channel
« Reply #1 on: 21 Nov '19 - 14:08 »
Do you want to send the sound from "fChan" to another soundcard too? If so, you will first need to initialize the 2nd device (using BASS_ASIO_Init), and then use splitter streams to send "fChan" to both devices. The splitter setup could look something like this:

Code: [Select]
split1 = BASS_Split_StreamCreate(fChan, BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE, NULL); // create splitter on input stream for 1st device
BASS_Mixer_StreamAddChannel(mixer1, split1, BASS_MIXER_DOWNMIX | BASS_MIXER_NORAMPIN); // plug it into 1st output mixer

split2 = BASS_Split_StreamCreate(fChan, BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE, NULL); // create splitter on input stream for 2nd device
BASS_Mixer_StreamAddChannel(mixer2, split2, BASS_MIXER_DOWNMIX | BASS_MIXER_NORAMPIN); // plug it into 2nd output mixer

Note that when you have multiple devices initialized, you will need to use BASS_ASIO_SetDevice to set the device context before calling most other BASSASIO functions. For example:

Code: [Select]
BASS_ASIO_SetDevice(device1); // set context to 1st device
BASS_ASIO_ChannelEnableBASS(FALSE, 0, mixer1, TRUE); // enable the 1st mixer on it

BASS_ASIO_SetDevice(device2); // set context to 2nd device
BASS_ASIO_ChannelEnableBASS(FALSE, 0, mixer2, TRUE); // enable the 2nd mixer on it

Please see the documentation for details on the mentioned functions.

Ed1966

  • Posts: 142
Re: ASIO Input on 2e Output channel
« Reply #2 on: 2 Dec '19 - 07:10 »
Thank you Ian.

I now use WASAPI and before I want to switch to ASIO what is the average WASAPI latency?
ASIO line-in calculated 10ms at 256 samples.
The output is then added with 25ms and some buffers.

Does it have advantages to switch to ASIO because I also need the Mixers for DSP?

Lot of rewriting that's why I ask you.

Regards,
Eduard.

Ian @ un4seen

  • Administrator
  • Posts: 22829
Re: ASIO Input on 2e Output channel
« Reply #3 on: 2 Dec '19 - 16:16 »
I think the main advantage of ASIO is that the input and output channel processing (on the same device) is synchronized, which is good if you want to forward the sound from an input to an output. In either case (ASIO or exclusive mode WASAPI), the latency can be controlled via the buffer length that you request in the BASS_ASIO_Start or BASS_WASAPI_Init call.

Ed1966

  • Posts: 142
Re: ASIO Input on 2e Output channel
« Reply #4 on: 3 Dec '19 - 06:35 »
All Clear so far. Last question. I now want to send the input to two outputs.
The first direct ASIO output and the second broadcast through split / mixer, is that possible?
Here is a piece of source with explanation:

Code: [Select]
  // create a "push" stream to receive and process the input data
  fChan := BASS_StreamCreate(Rate, 2, BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE, STREAMPROC_PUSH, nil);
  if (BASS_ErrorGetCode <> 0) then ShowMessage('BASS_StreamCreate: ' + BASS_ErrorGetCode.ToString);

  // create splitter on input stream for 1st device
  fSplit := BASS_Split_StreamCreate(fChan, BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE, nil);
  if (BASS_ErrorGetCode <> 0) then ShowMessage('BASS_Split_StreamCreate: ' + BASS_ErrorGetCode.ToString);

  // plug it into 1st output mixer
  BASS_Mixer_StreamAddChannel(fMixer, fSplit, BASS_MIXER_DOWNMIX Or BASS_MIXER_NORAMPIN);
  if (BASS_ErrorGetCode <> 0) then ShowMessage('BASS_Mixer_StreamAddChannel: ' + BASS_ErrorGetCode.ToString);

  // This one for: BASS_Encode_Start(fMixer, ...
  BASS_ASIO_SetDevice(SelectedAsioDevice);
  BASS_ASIO_ChannelEnableBASS(TRUE,  0, fChan, TRUE); // enable new inputs
  BASS_ASIO_ChannelEnableBASS(FALSE, 0, [b]fMixer[/b], TRUE); // enable the 1st mixer on it (output)

  // And this one to listen to the line-in without delay ...
  BASS_ASIO_SetDevice(SelectedAsioDevice);
  BASS_ASIO_ChannelEnableBASS(TRUE,  2, fChan, TRUE); // enable new inputs
  BASS_ASIO_ChannelEnableBASS(FALSE, 2, [b]fChan[/b], TRUE); // enable output

  // Of course only the last one works now.

You can also listen to the mixer but that is delayed and I don't want that. How can I solve this with ASIO? Is there a trick?

The question is actually how can I send one input device to two different outputs, One of these must be a direct ASIO output.

Hope i explain it correctly.

Regards,
Eduard.

Ian @ un4seen

  • Administrator
  • Posts: 22829
Re: ASIO Input on 2e Output channel
« Reply #5 on: 3 Dec '19 - 16:35 »
You are enabling 2 inputs in that code (the "enable new inputs" lines). Is that intentional? If so, you will need a separate push stream for each of them rather than sharing the same "fChan".

If you actually only want 1 input then you should remove the 2nd "enable new inputs" line and create a 2nd splitter for the 2nd output. Note that when using splitters, all access to the source's data must be through a splitter, otherwise the splitters will miss some of the data. For example, you could do this:

Code: [Select]
  // create splitter on input stream for 2nd device
  fSplit2 := BASS_Split_StreamCreate(fChan, BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE, nil);
  if (BASS_ErrorGetCode <> 0) then ShowMessage('BASS_Split_StreamCreate: ' + BASS_ErrorGetCode.ToString);

  // And this one to listen to the line-in without delay ...
  BASS_ASIO_SetDevice(SelectedAsioDevice);
  BASS_ASIO_ChannelEnableBASS(FALSE, 2, fSplit2, TRUE); // enable output

Btw, if the inputs and outputs are all on the same ASIO device then you won't need the BASS_ASIO_SetDevice calls.

Ed1966

  • Posts: 142
Re: ASIO Input on 2e Output channel
« Reply #6 on: 5 Dec '19 - 06:32 »
Thanks for your help Ian. Everything becomes clearer.  :)

FOUND:
Problems with: Dynamic_BassASIO.pas
Old version and missing 'BASS_ASIO_ChannelEnableBASS'.
Change and add little bit myself but don't know all is corrected.
DLL seems to be allright.
??

Regards,
Eduard.
« Last Edit: 5 Dec '19 - 08:28 by Ed1966 »

Ian @ un4seen

  • Administrator
  • Posts: 22829
Re: ASIO Input on 2e Output channel
« Reply #7 on: 5 Dec '19 - 15:34 »
Yes, the "Delphi dynamic loading API" package hadn't been updated for BASSASIO 1.4 yet. I've put an updated Dynamic_BassASIO.pas file in there now.

Ed1966

  • Posts: 142
Re: ASIO Input on 2e Output channel
« Reply #8 on: 5 Dec '19 - 21:03 »
Thank you. Download it tomorrow.  ;)

Ed1966

  • Posts: 142
Re: ASIO Input on 2e Output channel
« Reply #9 on: 6 Dec '19 - 07:22 »
Oops,

This line is not correct:

@BASS_ASIO_SetDSD:= GetProcAddress(ASIO_Handle, PChar(''));

must be

@BASS_ASIO_SetDSD:= GetProcAddress(ASIO_Handle, PChar('BASS_ASIO_SetDSD'));

 ;D

Ian @ un4seen

  • Administrator
  • Posts: 22829
Re: ASIO Input on 2e Output channel
« Reply #10 on: 6 Dec '19 - 13:34 »
Thanks, that has been corrected now.

Ed1966

  • Posts: 142
Re: ASIO Input on 2e Output channel
« Reply #11 on: 9 Dec '19 - 07:39 »
Hi Ian,

I have another question regarding sound output with ASIO

BASS_ASIO_ChannelGetInfo and BASS_ASIO_GetDeviceInfo works fine. No problem.

BUT:
I want an overview of available ASIO outputs? Where can I do that?
Now I use BASS_GetDeviceInfo but then i see all my soundcards. I only want to see ASIO.

Maybe you can help me.

Regards,
Eduard.

Ian @ un4seen

  • Administrator
  • Posts: 22829
Re: ASIO Input on 2e Output channel
« Reply #12 on: 9 Dec '19 - 17:50 »
You need to first initialize the ASIO device/driver with BASS_ASIO_Init, and then you can get info from it with BASS_ASIO_GetInfo. A little demonstration can be found in the LIST.C example that's included in the BASSASIO package.