Author Topic: Add Input Device (for instance microphone) to mix  (Read 647 times)

kafffee

  • Posts: 92
Hi everybody,

I want to add an input device (in this case a microphone, but I am planning to do this with any input device) to a mixer channel.

For now I got this (VB.NET):

Code: [Select]
Public Class Form1

Private MikroRecordingProc As RECORDPROC
Private MikroInput As Integer
Private MikroOutput As Integer

Private Sub Form1.Load(sender As Object, e As EventArgs) Handles MyBase.Load

Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, Me.Handle) 'Initialisiere Output Device

mixer = Un4seen.Bass.AddOn.Mix.BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_DEFAULT)
Bass.BASS_ChannelSetAttribute(mixer, BASSAttribute.BASS_ATTRIB_BUFFER, 0) ' disable playback buffering

Bass.BASS_RecordInit(-1)  'Initialisiere Mike
 
MikroRecordingProc = New RECORDPROC(AddressOf MikroRecordingCallback)

MikroOutput = Bass.BASS_StreamCreate(44100, 1, BASSFlag.BASS_DEFAULT, BASSStreamProc.STREAMPROC_PUSH)
MikroInput = Bass.BASS_RecordStart(44100, 1, BASSFlag.BASS_STREAM_DECODE, MikroRecordingProc, IntPtr.Zero)
BassMix.BASS_Mixer_StreamAddChannel(mixer, MikroOutput, BASSFlag.BASS_MIXER_NORAMPIN Or BASSFlag.BASS_STREAM_AUTOFREE)

Bass.BASS_ChannelPlay(mixer, False)
End Sub

Public Function MikroRecordingCallback(ByVal handle As Integer, ByVal buffer As IntPtr, ByVal length As Integer, ByVal user As IntPtr) As Boolean
Bass.BASS_StreamPutData(MikroOutput, buffer, length)
Bass.BASS_ChannelPlay(MikroOutput, False)
Return True
End Function
End Class

However, I get error 38 (The channel is a 'decoding channel') when I call BASS_Mixer_StreamAddChannel() for some reason. I already had this working, but I must have changed something accidentally, and I can't find what I'm doing wrong.

Further, I was told that I shouln't use BASS_ChannelPlay in a callback function and I am getting a microphone latency of about one second.

Is there any way to do this better?

Ian @ un4seen

  • Administrator
  • Posts: 24423
Re: Add Input Device (for instance microphone) to mix
« Reply #1 on: 2 May '22 - 12:59 »
When error code 38 (BASS_ERROR_DECODE) is from BASS_Mixer_StreamAddChannel, it actually indicates that the source is not a "decoding channel". A decoding channel is one that BASS_ChannelGetData is used to process. In the case of a recording channel, that means not using a RECORDPROC callback. So removing that from your BASS_RecordStart call should fix the problem.

kafffee

  • Posts: 92
Re: Add Input Device (for instance microphone) to mix
« Reply #2 on: 4 May '22 - 13:59 »
Now I got the following, the error is gone, but I wont hear anything... I guess its the proc argument in BASS_StreamCreate...

Code: [Select]
Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, Me.Handle) 'Initialisiere Output Device
mixer = Un4seen.Bass.AddOn.Mix.BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_DEFAULT)
Bass.BASS_ChannelSetAttribute(mixer, BASSAttribute.BASS_ATTRIB_BUFFER, 0) ' disable playback buffering

Bass.BASS_RecordInit(-1)  'Initialisiere Mike

MikroOutput = Bass.BASS_StreamCreate(44100, 1, BASSFlag.BASS_STREAM_DECODE, BASSStreamProc.STREAMPROC_PUSH)
MikroInput = Bass.BASS_RecordStart(44100, 1, Nothing, Nothing, IntPtr.Zero)

BassMix.BASS_Mixer_StreamAddChannel(mixer, MikroOutput, BASSFlag.BASS_MIXER_NORAMPIN Or BASSFlag.BASS_STREAM_AUTOFREE)
MessageBox.Show(CStr(Bass.BASS_ErrorGetCode))

Bass.BASS_ChannelPlay(mixer, False)
« Last Edit: 4 May '22 - 14:09 by kafffee »

Ian @ un4seen

  • Administrator
  • Posts: 24423
Re: Add Input Device (for instance microphone) to mix
« Reply #3 on: 4 May '22 - 16:52 »
If you're playing through a mixer then you don't need an intermediate stream. You can plug the recording directly into the mixer, ie. use the "MikroInput" handle in the BASS_Mixer_StreamAddChannel call.

kafffee

  • Posts: 92
Re: Add Input Device (for instance microphone) to mix
« Reply #4 on: 6 May '22 - 14:05 »
Ah cool it works now.  :) But is there any way to decrease latency? When I start talking into the microphone I will hear the output about one second later...

Ian @ un4seen

  • Administrator
  • Posts: 24423
Re: Add Input Device (for instance microphone) to mix
« Reply #5 on: 6 May '22 - 16:40 »
Are you starting the recording before the mixer? If so, there may be a build-up of data in the recording's buffer in the meantime, resulting in increased latency. To avoid that, you should start the mixer before or straight after the recording.

kafffee

  • Posts: 92
Re: Add Input Device (for instance microphone) to mix
« Reply #6 on: 7 May '22 - 11:32 »
I got this:

Code: [Select]
Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, Me.Handle) 'Initialisiere Output Device
 Bass.BASS_RecordInit(-1)  'Initialisiere Mike
 mixer = Un4seen.Bass.AddOn.Mix.BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_DEFAULT) '
 Bass.BASS_ChannelSetAttribute(mixer, BASSAttribute.BASS_ATTRIB_BUFFER, 0) ' disable playback buffering'
 MikroInput = Bass.BASS_RecordStart(44100, 1, BASSFlag.BASS_STREAM_DECODE, Nothing, IntPtr.Zero)
 BassMix.BASS_Mixer_StreamAddChannel(mixer, MikroInput, BASSFlag.BASS_MIXER_NORAMPIN Or
 BASSFlag.BASS_STREAM_AUTOFREE)
 Bass.BASS_ChannelPlay(mixer, False)

It should be working right?

Any other ideas on how to solve this?

Ian @ un4seen

  • Administrator
  • Posts: 24423
Re: Add Input Device (for instance microphone) to mix
« Reply #7 on: 9 May '22 - 17:09 »
Yes, that looks fine, but you could try moving the BASS_ChannelPlay call to before the BASS_RecordStart call. Also check that the BASS_ChannelSetAttribute call is reporting success.

kafffee

  • Posts: 92
Re: Add Input Device (for instance microphone) to mix
« Reply #8 on: 10 May '22 - 11:28 »
Okay did that. Also, _ChannelSetAttribute returns success. But it's still bot any better...

Maybe it's the driver? When I use my DAW there is no latency, no matter which microphone I am using...

Ian @ un4seen

  • Administrator
  • Posts: 24423
Re: Add Input Device (for instance microphone) to mix
« Reply #9 on: 10 May '22 - 17:36 »
Please try running the pre-compiled LIVEFX.EXE example from the BASS package (C\BIN folder) for comparison and see if you get the same latency with that.

kafffee

  • Posts: 92
Re: Add Input Device (for instance microphone) to mix
« Reply #10 on: 13 May '22 - 16:02 »
Tried that. It seems to be a little better with livefx.exe.

What to do now?

Chris

  • Posts: 2069
Re: Add Input Device (for instance microphone) to mix
« Reply #11 on: 15 May '22 - 13:25 »
I think your daw will working on a other way . it will record your mic and will playback directly the mic (on the playing mixer side) and not play backing the record.
(of Course the play backing of a record will have a Little latency. what you can prevent if you switching the mic on on the play backside .

kafffee

  • Posts: 92
Re: Add Input Device (for instance microphone) to mix
« Reply #12 on: 15 May '22 - 14:38 »
... switching the mic on on the play backside .

What do you mean by that? My settings look just the way they are on your screenshot...

Chris

  • Posts: 2069
Re: Add Input Device (for instance microphone) to mix
« Reply #13 on: 15 May '22 - 18:50 »
playing a channel ->  recording via (What you here / stereomix) put the mic on the playing side on .

Ian @ un4seen

  • Administrator
  • Posts: 24423
Re: Add Input Device (for instance microphone) to mix
« Reply #14 on: 16 May '22 - 13:39 »
Tried that. It seems to be a little better with livefx.exe.

How much better? What latency value does it display? There will always be a bit of latency, but it shouldn't really be anything like 1 second, so long as the recording doesn't start significantly before the playback.

kafffee

  • Posts: 92
Re: Add Input Device (for instance microphone) to mix
« Reply #15 on: 20 May '22 - 14:07 »
@Ian

It displays at about 20ms, so its significantly better....

What reasons can this have?

Ian @ un4seen

  • Administrator
  • Posts: 24423
Re: Add Input Device (for instance microphone) to mix
« Reply #16 on: 20 May '22 - 14:43 »
If you monitor the BASS_ChannelGetData(BASS_DATA_AVAILABLE) value on the recording and mixer handles in your app, what does that show?

kafffee

  • Posts: 92
Re: Add Input Device (for instance microphone) to mix
« Reply #17 on: 6 Jun '22 - 15:53 »
Mixer Channel (BASS_Mixer_StreamCreate): approximately 15000-18000
Recording Channel (BASS_RecordStart): approximately 3500-9000

Ian @ un4seen

  • Administrator
  • Posts: 24423
Re: Add Input Device (for instance microphone) to mix
« Reply #18 on: 6 Jun '22 - 18:08 »
Assuming the mixer is 44100Hz stereo 16-bit and the recording is 44100Hz mono 16-bit (as in the code posted above), those byte counts translate to 85-102ms and 39-102ms, respectively. The mixer amount is higher than I would expect to see with playback buffering disabled on it (BASS_ATTRIB_BUFFER=0). What BASS_ATTRIB_BUFFER value do you get back from BASS_ChannelGetAttribute? Also confirm what platform you're running this on.

kafffee

  • Posts: 92
Re: Add Input Device (for instance microphone) to mix
« Reply #19 on: 10 Jun '22 - 15:35 »
For mixer, BASS_ChannelGetAttribute returns 0,
For MikroInput, BASS_ChannelGetAttribute is not successful (so this might be the issue, why does it return unsuccessful?)

I am using Windows 10 Pro (64 bit) on a 64 bit machine with an Intel Core i5 Quadcore processor with 3.3 GHz and 16GB  RAM...

Ian @ un4seen

  • Administrator
  • Posts: 24423
Re: Add Input Device (for instance microphone) to mix
« Reply #20 on: 10 Jun '22 - 16:32 »
For mixer, BASS_ChannelGetAttribute returns 0,

That looks like playback buffering was successfully disabled, so the relatively high BASS_DATA_AVAILABLE level is a little strange. Perhaps the extra latency is in the soundcard/driver then. Can you try a different soundcard or system for comparison? Checking on a Windows 10 system here, I'm seeing around 8000 with one soundcard and 10000 with another (for a 44100Hz stereo 16-bit stream).

For MikroInput, BASS_ChannelGetAttribute is not successful (so this might be the issue, why does it return unsuccessful?)

BASS_ATTRIB_BUFFER controls playback buffering, so it doesn't apply to recording channels.

kafffee

  • Posts: 92
Re: Add Input Device (for instance microphone) to mix
« Reply #21 on: 10 Jun '22 - 18:32 »
Weird but good:

I added some functionality to my code: When I start to speak into the microphone, music volume is being faded out a bit, and when I stop speaking, fade in...

Looks like the following, it should be self-explaining:

Code: [Select]
Private Talking As Boolean = False

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim peak As Integer = Bass.BASS_ChannelGetLevel(MikroInput)
Dim left As Integer = Utils.LowWord32(peak)
If left > 150 Then
Timer1.Interval = 2000
If Talking = False Then
Bass.BASS_ChannelSlideAttribute(streamA, BASSAttribute.BASS_ATTRIB_VOL, 0.2, 300)
Talking = True
End If
Else
Timer1.Interval = 100
If Talking = True Then
Bass.BASS_ChannelSlideAttribute(streamA, BASSAttribute.BASS_ATTRIB_VOL, 1, 300)
Talking = False
End If
End If
End Sub

This has the positive side effect that there is no hearable microphone latency any more....

Do you have any idea why? Would be good to know for the future...

Ian @ un4seen

  • Administrator
  • Posts: 24423
Re: Add Input Device (for instance microphone) to mix
« Reply #22 on: 13 Jun '22 - 16:24 »
The BASS_ChannelGetLevel call there will be taking data out of the recording buffer (to measure the level of it), and that data will then not be seen by the mixer. That will indeed reduce latency if there was a build-up of data in the buffer but it will also cause a discontinuity in the played data. That won't be a problem if the data is just silence, but there will be a little audible skip otherwise.

Without the BASS_ChannelGetLevel call, is the recording's BASS_DATA_AVAILABLE value steadily rising or is it high from the start? If it's high from the start then it sounds like either the playback started after the recording or the recording is bursty, ie. the data is arriving in large blocks. The data should usually arrive in 10ms blocks on Windows, but can be less consistent when using DirectSound instead of WASAPI. What BASS version are you using (what does BASS_GetVersion say) and what is the BASS_CONFIG_REC_WASAPI config value (from BASS_GetConfig)?

If you would like to keep that level check without affecting playback then you can use BASS_ChannelGetLevelEx with the BASS_LEVEL_NOREMOVE flag instead of BASS_ChannelGetLevel.

kafffee

  • Posts: 92
Re: Add Input Device (for instance microphone) to mix
« Reply #23 on: 19 Jun '22 - 12:02 »
Without the BASS_ChannelGetLevelCall, the values are high from the start, but the playback is started before the recording:

Code: [Select]
Bass.BASS_ChannelPlay(mixer, False)
MikroInput = Bass.BASS_RecordStart(44100, 1, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_SAMPLE_FLOAT, Nothing, IntPtr.Zero)

I am using bass version 33820416. and there seems no BASS_CONFIG_REC_WASAPI being implemented:

Code: [Select]
Bass.BASS_GetConfig(BASSConfig.BASS_CONFIG_REC_WASAPI)
There seems to be no BASS_ChannelGetLevelEx implemented:

Quote
Dim peak As Integer = Bass.BASS_CHannelGetLevelEx(MikroInput)

Am I calling BASS_GetCOnfig and BASS_ChannelGetLevelEx the wrong way?
« Last Edit: 19 Jun '22 - 18:05 by kafffee »

Chris

  • Posts: 2069
Re: Add Input Device (for instance microphone) to mix
« Reply #24 on: 19 Jun '22 - 22:26 »
Bass_ChannelGetLevelEx is in the NetApi -- Bass_CHannelGetLevels


http://www.bass.radio42.com/help/html/ee4376c4-146b-e632-3ebb-6294db2e837d.htm