Author Topic: WASAPI, two microphones capture.  (Read 172 times)

Sergzh

  • Posts: 8
WASAPI, two microphones capture.
« on: 8 Apr '18 - 08:55 »
Hello!
I'm trying to get streams from two microphones. But it does not work.
If I comment out the "Init Microphone 2 WASAPI device", then it works.
Please help how to capture several WASAPI devices?
Code: [Select]
    Dim _process_mic_1 = New WASAPIPROC(AddressOf ProcessMic1)
    Dim _process_mic_2 = New WASAPIPROC(AddressOf ProcessMic2)

    Dim MicStream1
    Dim MicStream2

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim Mic_1_device = 6
        Dim Mic_2_device = 1
        Dim Result

        'Init BASS
        Bass.BASS_Init(0, 0, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero)

        'Init Microphone 1 WASAPI device
        Result = BassWasapi.BASS_WASAPI_Init(Mic_1_device, 44100, 2, BASSWASAPIInit.BASS_WASAPI_BUFFER, 1, 0.1, _process_mic_1, Me.Handle)
        If Result = False Then
            MsgBox("Error BASS_WASAPI_Init Mic_1 - " + Bass.BASS_ErrorGetCode().ToString)
        End If

        'Init Microphone 2 WASAPI device
        Result = BassWasapi.BASS_WASAPI_Init(Mic_2_device, 44100, 2, BASSWASAPIInit.BASS_WASAPI_BUFFER, 1, 0.1, _process_mic_2, Me.Handle)
        If Result = False Then
            MsgBox("Error BASS_WASAPI_Init Mic_2 - " + Bass.BASS_ErrorGetCode().ToString)
        End If

        'Start WASAPI
        BassWasapi.BASS_WASAPI_Start()

        'Init Output
        If Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero) = False Then
            MsgBox("Error Bass.BASS_Init Output - " + Bass.BASS_ErrorGetCode().ToString)
        End If

        'Microphone 1 Stream
        MicStream1 = Bass.BASS_StreamCreatePush(44100, 2, BASSFlag.BASS_SAMPLE_FLOAT, IntPtr.Zero)
        If MicStream1 = 0 Then
            MsgBox("Error MicStream1 - " + Bass.BASS_ErrorGetCode().ToString)
        End If

        'Microphone 2 Stream
        MicStream2 = Bass.BASS_StreamCreatePush(44100, 2, BASSFlag.BASS_SAMPLE_FLOAT, IntPtr.Zero)
        If MicStream2 = 0 Then
            MsgBox("Error MicStream2 - " + Bass.BASS_ErrorGetCode().ToString)
        End If

        'Play
        Bass.BASS_ChannelPlay(MicStream1, False)
        Bass.BASS_ChannelPlay(MicStream2, False)

    End Sub

    Function ProcessMic1(ByVal buffer As System.IntPtr, ByVal length As Integer, ByVal user As System.IntPtr)
        Bass.BASS_StreamPutData(MicStream1, buffer, length)
        Return length
    End Function

    Function ProcessMic2(ByVal buffer As System.IntPtr, ByVal length As Integer, ByVal user As System.IntPtr)
        Bass.BASS_StreamPutData(MicStream2, buffer, length)
        Return length
    End Function


Sergzh

  • Posts: 8
Re: WASAPI, two microphones capture.
« Reply #1 on: 8 Apr '18 - 11:47 »
Excuse me.
I found a mistake.
Both devices must be started and then it works.
Code: [Select]
        'Start WASAPI
        BassWasapi.BASS_WASAPI_SetDevice(Mic_1_device)
        BassWasapi.BASS_WASAPI_Start()

        BassWasapi.BASS_WASAPI_SetDevice(Mic_2_device)
        BassWasapi.BASS_WASAPI_Start()

Sergzh

  • Posts: 8
Re: WASAPI, two microphones capture.
« Reply #2 on: 8 Apr '18 - 13:47 »
But there is the following problem.
Now I want to merge the streams for writing to a file using BASS_Mixer_StreamCreate.
Code: [Select]
        Dim mixer As Integer = BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_SAMPLE_FLOAT)

        Result = BassMix.BASS_Mixer_StreamAddChannel(mixer, MicStream1, BASSFlag.BASS_SAMPLE_FLOAT)
        If Result = False Then MsgBox("Error BASS_Mixer_StreamAddChannel 1 " + Bass.BASS_ErrorGetCode().ToString)

        Dim okB As Boolean = BassMix.BASS_Mixer_StreamAddChannel(mixer, MicStream2, BASSFlag.BASS_SAMPLE_FLOAT)
        If Result = False Then MsgBox("Error BASS_Mixer_StreamAddChannel 2 " + Bass.BASS_ErrorGetCode().ToString)
I get errors BASS_ERROR_DECODE at BASS_Mixer_StreamAddChannel.
I tried all possible flags.
If I apply the BASS_STREAM_DECODE flag to BASS_StreamCreatePush, the errors disappear, but the sound also disappears.
Please, help.

Ian @ un4seen

  • Administrator
  • Posts: 20719
Re: WASAPI, two microphones capture.
« Reply #3 on: 9 Apr '18 - 13:36 »
Adding the BASS_STREAM_DECODE flag to the BASS_StreamCreatePush calls is the correct thing to do, to allow the streams to be plugged into the mixer. Regarding there being no sound, check that you're calling BASS_ChannelPlay on the mixer to start it. You may also want to set the mixer's BASS_ATTRIB_NOBUFFER setting to 0 (via BASS_ChannelSetAttribute) to disable buffering and minimize latency. You should also use the BASS_ENCODE_QUEUE flag in the file writing (assuming that you're using the BASSenc add-on to do that).

You should also remove the BASS_SAMPLE_FLOAT flag from the BASS_Mixer_StreamAddChannel calls, as it isn't a valid flag for that function. It won't make a difference in this case but it can do if the invalid flag happens to have the same value as a valid flag. A list of valid flags can be found in each function's documentation.

Sergzh

  • Posts: 8
Re: WASAPI, two microphones capture.
« Reply #4 on: 9 Apr '18 - 19:03 »
Adding the BASS_STREAM_DECODE flag to the BASS_StreamCreatePush calls is the correct thing to do, to allow the streams to be plugged into the mixer. Regarding there being no sound, check that you're calling BASS_ChannelPlay on the mixer to start it. You may also want to set the mixer's BASS_ATTRIB_NOBUFFER setting to 0 (via BASS_ChannelSetAttribute) to disable buffering and minimize latency. You should also use the BASS_ENCODE_QUEUE flag in the file writing (assuming that you're using the BASSenc add-on to do that).

You should also remove the BASS_SAMPLE_FLOAT flag from the BASS_Mixer_StreamAddChannel calls, as it isn't a valid flag for that function. It won't make a difference in this case but it can do if the invalid flag happens to have the same value as a valid flag. A list of valid flags can be found in each function's documentation.

Thanks for the answer!
I followed all your advice. It does not work yet, but I understood the reason.
The reason is not in BASS_Mixer_StreamCreate or BASS_Mixer_StreamAddChannel.
This does not work because of BASS_StreamCreatePush.
When I use BASS_StreamCreatePush with the BASS_SAMPLE_FLOAT flag, stream works.
But if i use the flag (BASS_STREAM_DECODE or BASS_SAMPLE_FLOAT) or just BASS_STREAM_DECODE, it does not work, I hear only: ts ... ts ... ts ... sometimes.
These mutually exclusive conditions: BASS_Mixer_StreamAddChannel needs BASS_STREAM_DECODE, but BASS_StreamCreatePush does not work with this flag.
Maybe I'll try to use the math byte: mix = (mic1 + mic2) / 2 if there is no other solution.

Chris

  • Posts: 1824
Re: WASAPI, two microphones capture.
« Reply #5 on: 9 Apr '18 - 22:02 »
by the way do you have change the Bass_ChannelPlay Stuff ??
it must be now BASS_ChannelPlay(mixer,false);

Sergzh

  • Posts: 8
Re: WASAPI, two microphones capture.
« Reply #6 on: 10 Apr '18 - 06:46 »
by the way do you have change the Bass_ChannelPlay Stuff ??
it must be now BASS_ChannelPlay(mixer,false);
Yes of course, I used BASS_ChannelPlay (mixer, false).
But as I said above, even if I exclude BASS_Mixer_StreamCreate and BASS_Mixer_StreamAddChannel, and even if I use only 1 microphone, BASS_StreamCreatePush does not work with the BASS_STREAM_DECODE flag or a combination of this flag.

Ian @ un4seen

  • Administrator
  • Posts: 20719
Re: WASAPI, two microphones capture.
« Reply #7 on: 10 Apr '18 - 16:30 »
That sounds strange. BASS_StreamCreatePush does support the BASS_STREAM_DECODE flag. It isn't a valid flag for BASS_Mixer_StreamAddChannel though, so you shouldn't use it in that call.

Another thing to note is that shared mode WASAPI only supports a single sample format (set in the Sound control panel), and BASS_WASAPI_Init will fail if a different format is requested. So it's generally best to set the "freq" and "chans" parameters to 0, and then use BASS_WASAPI_GetInfo to get the sample format, which you can use in the BASS_StreamCreatePush call, something like this:

Code: [Select]
        Result = BassWasapi.BASS_WASAPI_Init(Mic_1_device, 0, 0, BASSWASAPIInit.BASS_WASAPI_BUFFER, 1, 0.1, _process_mic_1, Me.Handle)
        Dim info As BASS_WASAPI_INFO = BassWasapi.BASS_WASAPI_GetInfo()
        MicStream1 = Bass.BASS_StreamCreatePush(info.freq, info.chans, BASSFlag.BASS_SAMPLE_FLOAT or BASSFlag.BASS_STREAM_DECODE, IntPtr.Zero)

Sergzh

  • Posts: 8
Re: WASAPI, two microphones capture.
« Reply #8 on: 13 Apr '18 - 10:41 »
That sounds strange. BASS_StreamCreatePush does support the BASS_STREAM_DECODE flag. It isn't a valid flag for BASS_Mixer_StreamAddChannel though, so you shouldn't use it in that call.

Another thing to note is that shared mode WASAPI only supports a single sample format (set in the Sound control panel), and BASS_WASAPI_Init will fail if a different format is requested. So it's generally best to set the "freq" and "chans" parameters to 0, and then use BASS_WASAPI_GetInfo to get the sample format, which you can use in the BASS_StreamCreatePush call, something like this:

Code: [Select]
        Result = BassWasapi.BASS_WASAPI_Init(Mic_1_device, 0, 0, BASSWASAPIInit.BASS_WASAPI_BUFFER, 1, 0.1, _process_mic_1, Me.Handle)
        Dim info As BASS_WASAPI_INFO = BassWasapi.BASS_WASAPI_GetInfo()
        MicStream1 = Bass.BASS_StreamCreatePush(info.freq, info.chans, BASSFlag.BASS_SAMPLE_FLOAT or BASSFlag.BASS_STREAM_DECODE, IntPtr.Zero)
Thank you!
It works.