Too much microphone latency

Started by kafffee,

kafffee

Quotecontaining a very short pulse of sound (eg. sinewave) through it

Which would be the perfect length for the sinewave to do this in your opinion?

Ian @ un4seen

You could just have a single cycle (see the attached file). You want the sound to be shorter than the delay because then there'll be a gap between each pulse of sound, which makes it clear to see where each pulse begins.

kafffee

Not sure what I am diong wrong but all I get is what you see in the attachment. The track with the grey background is the file you attached and the orange one is the result of the recorded mixer channel. There is something happening, but doesn't look like one ore multiple sinewaves, looks more like the clicking?

This is my code:


MainModule.Mixer = BassMix.BASS_Mixer_StreamCreate(48000, 1, BASSFlag.BASS_MIXER_NONSTOP Or BASSFlag.BASS_STREAM_DECODE)
Bass.BASS_ChannelSetAttribute(MainModule.Mixer, BASSAttribute.BASS_ATTRIB_BUFFER, 0.0F)

If Recording.PlayBackStreamHandle <> 0 Then Bass.BASS_ChannelFree(Recording.PlayBackStreamHandle)

Dim filename As String

filename = "C:\Downloads\pulse.wav"

Recording.PlayBackStreamHandle = Bass.BASS_StreamCreateFile(filename, 0, 0, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_MIXER_END)

Recording.SplitOriginal = BassMix.BASS_Split_StreamCreate(Recording.PlayBackStreamHandle, BASSFlag.BASS_STREAM_DECODE, Nothing)

BassAsio.BASS_ASIO_ChannelEnableBASS(False, 0, MainModule.Mixer, True)
BassMix.BASS_Mixer_StreamAddChannel(MainModule.Mixer, Recording.SplitOriginal, BASSFlag.BASS_DEFAULT)

BassAsio.BASS_ASIO_Start(1536)

This is how I start it:

Private Sub AddWetHandle(sender As Object, e As ParallelBusWetHandle)
    If e.ParallelBusName = SuperiorTrack.TrackName Then
        Dim num As Integer = 1
        Dim flags As BASSFlag = BASSFlag.BASS_STREAM_DECODE
       
        Dim SplitForParBus As Integer = BassMix.BASS_Split_StreamCreate(PlayBackStreamHandle, BASSFlag.BASS_STREAM_DECODE, Nothing)
        Dim NewWetHandle As New ParallelBusWetHandle With {.ParallelBusName = e.ParallelBusName, .WetPushHandle = SplitForParBus, .WetTempoFXHandle = BassFx.BASS_FX_TempoCreate(SplitForParBus, BASSFlag.BASS_STREAM_DECODE)}
        TempoFXStreamHandleWet.Add(NewWetHandle)
        BassMix.BASS_Mixer_StreamAddChannel(MainModule.Mixer, NewWetHandle.WetTempoFXHandle, BASSFlag.BASS_DEFAULT)
        BassEnc.BASS_Encode_Start(MainModule.Mixer, "C:\Test\output.wav", BASSEncode.BASS_ENCODE_QUEUE Or BASSEncode.BASS_ENCODE_AUTOFREE Or BASSEncode.BASS_ENCODE_PCM, Nothing, IntPtr.Zero)
        Bass.BASS_ChannelPlay(MainModule.Mixer, False)
     
    End If
End Sub

I can't figure out what's wrong with my code.

Ian @ un4seen

You should start the WAV writer before starting the output (ie. before BASS_ASIO_Start), to make sure it doesn't miss anything. Similarly, you should add the "WetTempoFXHandle" handle to the mixer before starting, otherwise that may miss the short pulse of sound from the source. If you want to do longer tests, you could add some silence (eg. 1s or more) to the PULSE.WAV file and then set the BASS_SAMPLE_LOOP flag on it so that it plays repeatedly.

Please note the BASS_MIXER_END flag is only valid in BASS_Mixer_StreamCreate calls, so it should be removed from your BASS_StreamCreateFile call. There's also no need to call BASS_ChannelPlay on the mixer (that will be failing because it's a decoding channel) - the mixer processing will be started by BASS_ASIO_Start.

kafffee

#44
Okay thanks that helped a lot :-)

At first I tried to play the sinewave sample once. As you can see in the attachment, the ampltitude in the mixer is smaller than the one in the original (oddly enough), and the delay is 6 samples at the start, 1 sample at the end.

This is just the playback channel, I can't  really run the sinewave thru my mic of course...

_____________________________________


Then I tried to loop it up and play it five times, once per second.

The amplitudes, especially the one at 0 secs, vary, as I can see.



What does all this tell us?
__________________________________

PS: The audio settings are: 48000 Hz, 16 bits, mono. The screenshots are not all zoomed the same way, but you can see the amount of samples in the "timeline" at the top of the pictures. The pitch is set to 0.0 in all cases.

Ian @ un4seen

The first pulse looks like it's fading-in. Are you applying any fade-in, eg. using BASS_FX_VOLUME or BASS_ChannelSlideAttribute or BASS_Mixer_ChannelSetEnvelope? BASSmix will ramp-in sources by default in some cases, but that shouldn't apply to the PULSE.WAV file because it begins with a 0 sample. Still, you could try adding the BASS_MIXER_CHAN_NORAMPIN flag to your BASS_Mixer_StreamAddChannel calls. You could also try this latest BASSmix build to see if it makes any difference:

    www.un4seen.com/stuff/bassmix.zip

Anyway, it looks like there's no delay, as the later pulses appear to be 2x the original level (as expected if there's no delay). Are you still hearing a delay if you use a different audio file with the same code?

kafffee

QuoteThe first pulse looks like it's fading-in. Are you applying any fade-in, eg. using BASS_FX_VOLUME or BASS_ChannelSlideAttribute or BASS_Mixer_ChannelSetEnvelope?

Yes you're right, that really looks like it's fading in. But  I'm not applying any of these three.

QuoteStill, you could try adding the BASS_MIXER_CHAN_NORAMPIN flag to your BASS_Mixer_StreamAddChannel calls. You could also try this latest BASSmix build to see if it makes any difference:

Tried either, but no difference...

QuoteAnyway, it looks like there's no delay, as the later pulses appear to be 2x the original level (as expected if there's no delay).

Yes. When I said, that the playback channels sound richer/fuller in reply #38, that might be due to a twofold increase in volume. I'm not a sound engineer or something like that, so I was presuming, that when I add two identical signals to a mixer, that the output would just be the exact same because it would overlap. Did not know that this also increases the target volume.

QuoteAre you still hearing a delay if you use a different audio file with the same code?

I tried using a "normal" mp3 song, but I am not hearing anything with this code right now. The test wave file is being written though and has music in it.

________________________________________

I think the major issue is not the playback tracks, as we can see. When I apply the pitch effect (with value 0.0) to my ASIO input (USB mic (without USB hub, plugged directly into the mainboard!)) there's definitely an audible delay and not just an increase in volume. Is there a similar way to test this too? Maybe writing the source channel and and the mixer channel to two separate wav files? Or will there be  a delay anyways then I call BassEnc.BASS_Encode_Start after one another?

Ian @ un4seen

Quote from: kafffeeI tried using a "normal" mp3 song, but I am not hearing anything with this code right now. The test wave file is being written though and has music in it.

That seems strange. Are you hearing the sinewave pulses when using the PULSE.WAV file?

Quote from: kafffeeI think the major issue is not the playback tracks, as we can see. When I apply the pitch effect (with value 0.0) to my ASIO input (USB mic (without USB hub, plugged directly into the mainboard!)) there's definitely an audible delay and not just an increase in volume. Is there a similar way to test this too?

When the source is a live recording (ASIO input), you could try creating a short pulse of sound by tapping the microphone (and then check if it becomes 2 pulses in the written WAV file).

kafffee

QuoteThat seems strange. Are you hearing the sinewave pulses when using the PULSE.WAV file?

I found the mistake: I used to call BassAsio.BASS_ASIO_ChannelEnableBASS(False, 0, MainModule.Mixer, True) at the wrong spot.

QuoteWhen the source is a live recording (ASIO input), you could try creating a short pulse of sound by tapping the microphone (and then check if it becomes 2 pulses in the written WAV file).

Did that, you can actually hear two taps right after one another. I attached the wav file, its 44100 Hz, 16 Bit Stereo and I was able to hear the taps in my DAW, but not in the standard Windows 10 Media Player app, I can't tell why. Are you able to hear it?
I also attached the waveform from my DAW, I can't really tell two taps there, maybe you can? The units you can see at the top are in samples again.

What could I do to improve the situation?

Ian @ un4seen

It's a bit hard to tell from that waveform because the "pulse" sound is quite long and overlapping, but it looks like the delay was around 4000 samples, which seems high, especially as there was apparently no delay with a BASS_StreamCreateFile source. What code changes did you make when switching from BASS_StreamCreateFile to ASIO input?

kafffee

Quotebut it looks like the delay was around 4000 samples
Yes, at the position of about 24000 samples, there seems to be an irregular "bump" in the waveform.

In my code, I am doing this right now:

Preparing:

Private Sub PrepareMixerForASIO()
    If MainModule.Mixer = 0 Then
        NativeASIODevSampleRate = BassAsio.BASS_ASIO_GetRate
        BassAsio.BASS_ASIO_ChannelSetRate(True, 0, NativeASIODevSampleRate)
       
        BassAsio.BASS_ASIO_ChannelSetRate(False, 0, NativeASIODevSampleRate)
       
        BassAsio.BASS_ASIO_ChannelSetRate(True, 1, NativeASIODevSampleRate)
       
        BassAsio.BASS_ASIO_ChannelSetRate(False, 1, NativeASIODevSampleRate)
       
        MainModule.Mixer = BassMix.BASS_Mixer_StreamCreate(CInt(NativeASIODevSampleRate), MainModule.Song.NumberOfChannels, BASSFlag.BASS_MIXER_NONSTOP Or BASSFlag.BASS_STREAM_DECODE)
       
        Bass.BASS_ChannelSetAttribute(MainModule.Mixer, BASSAttribute.BASS_ATTRIB_BUFFER, 0.0F) ' disable playback buffering
       
        If Not System.IO.Directory.Exists("C:\Test") Then System.IO.Directory.CreateDirectory("C:\Test")
       
    End If

End Sub

Playback tracks:

PrepareMixerForASIO()

If Recording.PlayBackStreamHandle <> 0 Then Bass.BASS_ChannelFree(Recording.PlayBackStreamHandle)
' Recording.PlayBackStreamHandle = Bass.BASS_StreamCreate(MainModule.Song.SampleRate, MainModule.Song.NumberOfChannels, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_MIXER_END Or BASSFlag.BASS_SAMPLE_FLOAT, StreamProcedure, CType(handleGC, IntPtr)) ' final version (loading files from RAM)
Dim filename As String
If Recording.SuperiorTrack.TrackName = "Track 0" Then
    filename = "C:\pulse.wav"
End If
Recording.PlayBackStreamHandle = Bass.BASS_StreamCreateFile(filename, 0, 0, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_SAMPLE_FLOAT) 'test version (directly loading files)

Recording.SplitOriginal = BassMix.BASS_Split_StreamCreate(Recording.PlayBackStreamHandle, BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_SAMPLE_FLOAT, Nothing)

BassMix.BASS_Mixer_StreamAddChannel(MainModule.Mixer, Recording.SplitOriginal, BASSFlag.BASS_DEFAULT Or BASSFlag.BASS_MIXER_CHAN_NORAMPIN)

BassAsio.BASS_ASIO_ChannelEnableBASS(False, 0, MainModule.Mixer, True)

(Mic) recording tracks:

PrepareMixerForASIO()

If Recording.PushStreamHandleDry <> 0 Then Bass.BASS_ChannelFree(Recording.PushStreamHandleDry)

Recording.PushStreamHandleDry = Bass.BASS_StreamCreatePush(MainModule.Song.SampleRate, 1, BASSFlag.BASS_STREAM_DECODE, IntPtr.Zero)

Recording.SplitOriginal = BassMix.BASS_Split_StreamCreate(Recording.PushStreamHandleDry, BASSFlag.BASS_STREAM_DECODE, Nothing)

BassAsio.BASS_ASIO_ChannelEnableBASS(True, 0, Recording.PushStreamHandleDry, True)
BassMix.BASS_Mixer_StreamAddChannel(MainModule.Mixer, Recording.SplitOriginal, BASSFlag.BASS_DEFAULT)

Recording.EnqueueTimer.IsEnabled = True   'enqueue data for visualization (waveform)

BassAsio.BASS_ASIO_ChannelEnableBASS(False, 0, MainModule.Mixer, True)

Then applying the fx (please note the comments):

Private Sub AddWetHandle(sender As Object, e As ParallelBusWetHandle)
    If e.ParallelBusName = SuperiorTrack.TrackName Then
        Dim num As Integer
        Dim flags As BASSFlag = BASSFlag.BASS_STREAM_DECODE
        If IsRecording Then
            num = 1
        Else
            num = 2
            flags = flags Or BASSFlag.BASS_SAMPLE_FLOAT
        End If
       
        Dim SplitForParBus As Integer = BassMix.BASS_Split_StreamCreate(PushStreamHandleDry, BASSFlag.BASS_STREAM_DECODE, Nothing)  ' for the playback channels, 'PushStreamHandleDry' is replaced by 'PlayBackStreamHandle'
        Dim NewWetHandle As New ParallelBusWetHandle With {.ParallelBusName = e.ParallelBusName, .WetPushHandle = SplitForParBus, .WetTempoFXHandle = BassFx.BASS_FX_TempoCreate(SplitForParBus, BASSFlag.BASS_STREAM_DECODE)}
        TempoFXStreamHandleWet.Add(NewWetHandle)
        BassMix.BASS_Mixer_StreamAddChannel(MainModule.Mixer, NewWetHandle.WetTempoFXHandle, BASSFlag.BASS_DEFAULT Or BASSFlag.BASS_MIXER_CHAN_NORAMPIN)
        BassEnc.BASS_Encode_Start(MainModule.Mixer, "C:\Test\output.wav", BASSEncode.BASS_ENCODE_QUEUE Or BASSEncode.BASS_ENCODE_AUTOFREE Or BASSEncode.BASS_ENCODE_PCM, Nothing, IntPtr.Zero)
        BassAsio.BASS_ASIO_Start(64)  'tried '64' as well as '1536', there was no audible difference
       
    End If
End Sub

______

I tried doing multiple taps on the mic: When the wav file is a bit longer, you can actually hear the taps and their "echoes" with the standard windows audio player. See attached file.

Ian @ un4seen

Quote from: kafffee        BassAsio.BASS_ASIO_ChannelSetRate(True, 0, NativeASIODevSampleRate)
        BassAsio.BASS_ASIO_ChannelSetRate(False, 0, NativeASIODevSampleRate)
        BassAsio.BASS_ASIO_ChannelSetRate(True, 1, NativeASIODevSampleRate)
        BassAsio.BASS_ASIO_ChannelSetRate(False, 1, NativeASIODevSampleRate)

You can remove these calls because BASS_ASIO_ChannelEnableBASS will automatically set the ASIO channel rate according to the provided stream handle.

Quote from: kafffeeRecording.PushStreamHandleDry = Bass.BASS_StreamCreatePush(MainModule.Song.SampleRate, 1, BASSFlag.BASS_STREAM_DECODE, IntPtr.Zero)

The NativeASIODevSampleRate value (instead of MainModule.Song.SampleRate) should be used in this call to avoid resampling the recording.

Quote from: kafffeeRecording.EnqueueTimer.IsEnabled = True  'enqueue data for visualization (waveform)

Try removing this to see if it's causing the delay. I don't see any other reason for the ~4000 sample delay when recording. To confirm, there's no delay (duplicate pulses) when you use the "Playback tracks" code but there is when you use the "(Mic) recording tracks" code, and the rest of the code is the same in both cases? Are you using headphones or speakers? If you're using speakers, try headphones to make sure the mic isn't picking up the sound from the speakers.

kafffee

QuoteThe NativeASIODevSampleRate value (instead of MainModule.Song.SampleRate) should be used in this call to avoid resampling the recording.

Oh, MainModule.Song.SampleRate will also return BassAsio.BASS_ASIO_GetRate. The other stuff was just for testing purposes...

QuoteTry removing this to see if it's causing the delay.

Tried that, unfortunately it doesn't.

QuoteTo confirm, there's no delay (duplicate pulses) when you use the "Playback tracks" code but there is when you use the "(Mic) recording tracks" code, and the rest of the code is the same in both cases?

Yes exactly.

QuoteAre you using headphones or speakers?

Headphones.

_____________________________________________________________


The only thing I could try is to use a VST plugin to see if it does the job. But I doubt that. The mic is indeed not a real ASIO device, it's just being used with the ASIO4ALL driver... But: The weird thing about it is that the DAW of my choice does the job, with the same driver and the same mic! So a I asked an AI, and it said that my DAW does this job extraordinarily well with some tricks.

______________________________________________________________

The strange thing about it is that when I add this line:

Bass.BASS_ChannelSetAttribute(SplitForParBus, BASSAttribute.BASS_ATTRIB_VOL, 0.0F)
...before adding NewWetHandle.WetTempoFXHandle to the mixer, it still remains audible with the same volume. Is there an explanation to this or do you have a suspicion? Is there a way to list any stream that's plugged into a mixer?

Ian @ un4seen

Quote from: kafffeeThe strange thing about it is that when I add this line:

Bass.BASS_ChannelSetAttribute(SplitForParBus, BASSAttribute.BASS_ATTRIB_VOL, 0.0F)
...before adding NewWetHandle.WetTempoFXHandle to the mixer, it still remains audible with the same volume. Is there an explanation to this or do you have a suspicion? Is there a way to list any stream that's plugged into a mixer?

You would need to use the WetTempoFXHandle handle in that BASS_ChannelSetAttribute call, the same handle that's in the BASS_Mixer_StreamAddChannel call.

After thinking about it a bit, the delay is probably due to the tempo processing requiring blocks of data and producing no output when there's insufficient data available. That isn't an issue when the source is a file because it can just decode more data from the file, but it can't do that when the source is a live recording. So there's a delay while it waits for the required amount of data. It looks like the required amount of data is the sum of the BASS_ATTRIB_TEMPO_OPTION_SEQUENCE_MS and BASS_ATTRIB_TEMPO_OPTION_SEEKWINDOW_MS settings. So you could try lowering those, but that may reduce sound quality too.

You could also try using the BASS_FX_BFX_PITCHSHIFT effect instead of tempo processing. It'll have the same processing blocks issue but perhaps it'll work better with smaller blocks? I've never really used either myself, so can't comment on which is better.

kafffee

QuoteYou would need to use the WetTempoFXHandle handle in that BASS_ChannelSetAttribute call, the same handle that's in the BASS_Mixer_StreamAddChannel call.

Ah okay, yes that works :-)

___________________________________


QuoteYou could also try using the BASS_FX_BFX_PITCHSHIFT effect instead of tempo processing.

I tried this:

Dim SplitForParBus As Integer = BassMix.BASS_Split_StreamCreate(PushStreamHandleDry, BASSFlag.BASS_STREAM_DECODE, Nothing)
Dim NewWetHandle As New ParallelBusWetHandle With {.ParallelBusName = e.ParallelBusName, .WetPushHandle = SplitForParBus, .WetTempoFXHandle = Bass.BASS_ChannelSetFX(SplitForParBus, BASSFXType.BASS_FX_BFX_PITCHSHIFT, 0)}
Dim PitchEffect As New BASS_BFX_PITCHSHIFT With {
    .fPitchShift = 1,
    .fSemitones = 1,
    .lChannel = BASSFXChan.BASS_BFX_CHANALL,
    .lFFTsize = 2048,
    .lOsamp = 8
    }
Bass.BASS_FXSetParameters(NewWetHandle.WetTempoFXHandle, PitchEffect)

...But I get BASS_ERROR_ILLTYPE on the ChannelSetFX call for some reason. How come?

________________________________


I also tried a VST2 plugin (which is definitely 64 bits like my host app):

Dim SplitForParBus As Integer = BassMix.BASS_Split_StreamCreate(PushStreamHandleDry, BASSFlag.BASS_STREAM_DECODE, Nothing)
Dim NewWetHandle As New ParallelBusWetHandle With {.ParallelBusName = e.ParallelBusName, .WetPushHandle = SplitForParBus, .WetTempoFXHandle = BassVst.BASS_VST_ChannelSetDSP(SplitForParBus, "C:\MyEffect_x64.dll", BASSVSTDsp.BASS_VST_DEFAULT, 0)}
Dim vstwin = New Window
vstwin.Show()
BassVst.BASS_VST_EmbedEditor(NewWetHandle.WetTempoFXHandle, New System.Windows.Interop.WindowInteropHelper(vstwin).Handle)

I get no errors in any of the calls, but the embedded control panel does not appear to apply any effect on the sound when I change any setting and also does not display its visualizations of the signal, as if there were no audio data.

Can you see what's wrong with it?

________________________________

P.S.: I like the new dark mode of your website :-)

Ian @ un4seen

Quote from: kafffee...But I get BASS_ERROR_ILLTYPE on the ChannelSetFX call for some reason. How come?

That error usually means BASS_FX.DLL hasn't been loaded yet. You can call a function from it first to make sure it is loaded, eg. BASS_FX_GetVersion during initialization.

Quote from: kafffeeI also tried a VST2 plugin (which is definitely 64 bits like my host app):

Dim SplitForParBus As Integer = BassMix.BASS_Split_StreamCreate(PushStreamHandleDry, BASSFlag.BASS_STREAM_DECODE, Nothing)
Dim NewWetHandle As New ParallelBusWetHandle With {.ParallelBusName = e.ParallelBusName, .WetPushHandle = SplitForParBus, .WetTempoFXHandle = BassVst.BASS_VST_ChannelSetDSP(SplitForParBus, "C:\MyEffect_x64.dll", BASSVSTDsp.BASS_VST_DEFAULT, 0)}
Dim vstwin = New Window
vstwin.Show()
BassVst.BASS_VST_EmbedEditor(NewWetHandle.WetTempoFXHandle, New System.Windows.Interop.WindowInteropHelper(vstwin).Handle)

I get no errors in any of the calls, but the embedded control panel does not appear to apply any effect on the sound when I change any setting and also does not display its visualizations of the signal, as if there were no audio data.

Can you see what's wrong with it?

Are you playing the SplitForParBus stream? You can try monitoring its position with BASS_ChannelGetPosition to check if it's being processed, ie. is its position advancing?

Note that WetTempoFXHandle will be a DSP handle in this case (and the BASS_FX_BFX_PITCHSHIFT case), not a stream handle (as with BASS_FX_TempoCreate), so you can't play that.

Quote from: kafffeeP.S.: I like the new dark mode of your website :-)

Thanks :)

kafffee

QuoteYou can call a function from it first to make sure it is loaded, eg. BASS_FX_GetVersion during initialization.

Okay did that.

QuoteAre you playing the SplitForParBus stream?

Ah, I added WetTempoFXHandle to the mixer by mistake. Now, I added SplitForBarBus to the stream and I can hear something, but:

No the latency is even bigger. Not sure, but it seems like it's getting bigger the longer the recording has been running, i.e. when I start it, it's small (but still not instantly), and when it has been running a couple of seconds, the delay is already at a few entire seconds? This happens with the VST plugin as well as with BASS_FX_BFX_PITCHSHIFT.

This is how I apply the vst:

Dim SplitForParBus As Integer = BassMix.BASS_Split_StreamCreate(PushStreamHandleDry, BASSFlag.BASS_STREAM_DECODE, Nothing)

Dim NewWetHandle As New ParallelBusWetHandle With {.ParallelBusName = e.ParallelBusName, .WetPushHandle = SplitForParBus, .WetTempoFXHandle = BassVst.BASS_VST_ChannelSetDSP(SplitForParBus, "C:\MyVST-x64.dll", BASSVSTDsp.BASS_VST_DEFAULT, 1)}

Dim vstwin = New Window
vstwin.Show()
BassVst.BASS_VST_EmbedEditor(NewWetHandle.WetTempoFXHandle, New System.Windows.Interop.WindowInteropHelper(vstwin).Handle)

BassMix.BASS_Mixer_StreamAddChannel(MainModule.Mixer, NewWetHandle.WetPushHandle, BASSFlag.BASS_DEFAULT Or BASSFlag.BASS_MIXER_CHAN_NORAMPIN)

and the built-in effect:

Dim SplitForParBus As Integer = BassMix.BASS_Split_StreamCreate(PushStreamHandleDry, BASSFlag.BASS_STREAM_DECODE, Nothing)

Dim NewWetHandle As New ParallelBusWetHandle With {.ParallelBusName = e.ParallelBusName, .WetPushHandle = SplitForParBus, .WetTempoFXHandle = Bass.BASS_ChannelSetFX(SplitForParBus, BASSFXType.BASS_FX_BFX_PITCHSHIFT, 0)}

Dim PitchEffect As New BASS_BFX_PITCHSHIFT With {
     .fPitchShift = 1,
     .fSemitones = 1,
     .lChannel = BASSFXChan.BASS_BFX_CHANALL,
     .lFFTsize = 2048,
     .lOsamp = 8
     }

Bass.BASS_FXSetParameters(NewWetHandle.WetTempoFXHandle, PitchEffect)

BassMix.BASS_Mixer_StreamAddChannel(MainModule.Mixer, NewWetHandle.WetPushHandle, BASSFlag.BASS_DEFAULT Or BASSFlag.BASS_MIXER_CHAN_NORAMPIN)

The rest of the code should be the same.

Do you know what's happening here?

Ian @ un4seen

Quote from: kafffeeNo the latency is even bigger. Not sure, but it seems like it's getting bigger the longer the recording has been running, i.e. when I start it, it's small (but still not instantly), and when it has been running a couple of seconds, the delay is already at a few entire seconds? This happens with the VST plugin as well as with BASS_FX_BFX_PITCHSHIFT.

That sounds like there may be a build-up of data in the push stream or splitter. You can check that with BASS_StreamPutData(length=0) and BASS_Split_StreamGetAvailable, respectively.

Is the push stream still fed by an ASIO input channel, and played by an ASIO output channel? If so, there should be the same amount of data going in and out of the push stream, ie. no build-up. Are you setting the VST/DSP before calling BASS_ASIO_Start? If not, perhaps the splitter received data while you setup the VST/DSP on it. Try adding a BASS_Split_StreamReset call just before BASS_Mixer_StreamAddChannel to clear it. That won't help with the rising latency though.

Quote from: kafffee    .lFFTsize = 2048,

Lower "lFFTsize" settings will give lower latency, but I guess may also affect sound quality. You can check to find out.

kafffee

QuoteThat sounds like there may be a build-up of data in the push stream or splitter. You can check that with BASS_StreamPutData(length=0) and BASS_Split_StreamGetAvailable, respectively.

Okay, I did this, is this what you thought about?:

Dim SplitForParBus As Integer = BassMix.BASS_Split_StreamCreate(PushStreamHandleDry, BASSFlag.BASS_STREAM_DECODE, Nothing)

Dim NewWetHandle As New ParallelBusWetHandle With {.ParallelBusName = e.ParallelBusName, .WetPushHandle = SplitForParBus, .WetTempoFXHandle = Bass.BASS_ChannelSetFX(SplitForParBus, BASSFXType.BASS_FX_BFX_PITCHSHIFT, 0)}

Dim PitchEffect As New BASS_BFX_PITCHSHIFT With {
    .fPitchShift = 1,
    .fSemitones = 1,
    .lChannel = BASSFXChan.BASS_BFX_CHANALL,
    .lFFTsize = 2048,
    .lOsamp = 8
    }

Bass.BASS_FXSetParameters(NewWetHandle.WetTempoFXHandle, PitchEffect)

BassMix.BASS_Mixer_StreamAddChannel(MainModule.Mixer, NewWetHandle.WetPushHandle, BASSFlag.BASS_DEFAULT Or BASSFlag.BASS_MIXER_CHAN_NORAMPIN)

 BassEnc.BASS_Encode_Start(MainModule.Mixer, "C:\Test\output.wav", BASSEncode.BASS_ENCODE_QUEUE Or BASSEncode.BASS_ENCODE_AUTOFREE Or BASSEncode.BASS_ENCODE_PCM, Nothing, IntPtr.Zero)

Thread.Sleep(10000)  ' waiting a while
MessageBox.Show("push stream length: " & CStr(Bass.BASS_StreamPutData(PushStreamHandleDry, IntPtr.Zero, 0)) & "; split stream buffer length: " & CStr(BassMix.BASS_Split_StreamGetAvailable(SplitForParBus)))

I get these results:

-push stream length: 0
-split stream buffer length: 175376

Then I tried with the vst with the same code as mentioned in post #54, but added the last 3 lines as above.

First time I got exact the same result I think (0 for the push stream, 175376 for the split stream), then I tried another time and got:

-push stream length: 0
-split stream buffer length: 110592

The delay does not get endlessly bigger though: When I had the recording running for about a minute, the delay  stayed about the same (a few secs).

I also tried a 3rd time:

-push stream length: 0
-split stream buffer length: 126976

is this the build-up of data you were talking about? How can I avoid this?


QuoteIs the push stream still fed by an ASIO input channel, and played by an ASIO output channel?

It's fed by an ASIO input channel then plugged into the mixer. Then I create a split stream from it, which is also plugged into the mixer (with the applied fx). Then the mixer is played via ASIO output.

QuoteIf so, there should be the same amount of data going in and out of the push stream, ie. no build-up.


What do you mean by going in and out? As I measured with my code above, i.e. going in >> return value of StreamPutData and going out >> Split_StreamGetAvailable? Or is this something else?


QuoteAre you setting the VST/DSP before calling BASS_ASIO_Start?

No.

QuoteLower "lFFTsize" settings will give lower latency, but I guess may also affect sound quality. You can check to find out.

I will try that later. Weird thing: Now I get BASS_ERROR_ILLPARAM when I call Bass.BASS_FXSetParameters as above. Even though there's no value outside range (?) and I call GetVersion during initialization...
Important: I still hear a sound with that delay though... even though it failed

Ian @ un4seen

Quote from: kafffee-push stream length: 0
-split stream buffer length: 126976

is this the build-up of data you were talking about? How can I avoid this?

Yes. Because BASS_ASIO_Start has already been called, data may be received/buffered from the ASIO input while you're setting up the DSP/VST. Try calling BASS_Split_StreamReset just before BASS_Mixer_StreamAddChannel to skip that data:

BassMix.BASS_Split_StreamReset(SplitForParBus)
BassMix.BASS_Mixer_StreamAddChannel(MainModule.Mixer, NewWetHandle.WetPushHandle, BASSFlag.BASS_DEFAULT Or BASSFlag.BASS_MIXER_CHAN_NORAMPIN)

Quote from: kafffee
QuoteIf so, there should be the same amount of data going in and out of the push stream, ie. no build-up.

What do you mean by going in and out? As I measured with my code above, i.e. going in >> return value of StreamPutData and going out >> Split_StreamGetAvailable? Or is this something else?

I meant that if data is going in and out of the push stream (from ASIO input to ASIO output) at the same rate, then there will be no build-up of data in it. Your "push stream length: 0" confirms that.