Author Topic: Issue with default WASAPI implementation of the newest BASS library.  (Read 405 times)

KaleidonKep99

  • Posts: 173
I recently started having issues with streams, with the latest version of the BASS library (2.4.13.11).
If too many notes are being played at once, the streams ends abruptly.
Playing normal MIDIs does not trigger this behavior.

This only happens when playing a MIDI directly through BASSMIDI (BASS_MIDI_StreamCreateFile then BASS_ChannelPlay) using WASAPI (No BASS_DEVICE_DSOUND in BASS_Init).
DirectSound does not have this issue, and I also had no issues when using BASSWASAPI with the stream from BASS/BASSMIDI in decoding mode.
Real-time playback through MIDI synthesizers (E.g. VirtualMIDISynth and Keppy's Synthesizer) is not affected by this issue.

Here's a video:
https://www.youtube.com/watch?v=syIdVtH0Bbs&feature=youtu.be

Ian @ un4seen

  • Administrator
  • Posts: 21136
To perhaps help narrow down what/where the problem is, please see if you can reproduce it with the pre-compiled MIDITEST.EXE example included in the BASSMIDI package (C\BIN folder).

KaleidonKep99

  • Posts: 173
Apparently, it doesn't.

But I noticed something odd about this, when it happens on KMC.
The converter thinks the preview is done, and the check happens in this piece of code:
Code: [Select]
                            while (Bass.BASS_ChannelIsActive((MainWindow.KMCGlobals.vstIInfo.isInstrument ? MainWindow.VSTs._VSTHandles[0] : MainWindow.KMCGlobals._recHandle)) == BASSActive.BASS_ACTIVE_PLAYING) <<<<<< If it isn't playing, abort
                            {
                                if (MainWindow.KMCGlobals.CancellationPendingValue != 1) notes = BASSControl.BASSPlayBackEngine(notes, length, pos);
                                else if (MainWindow.KMCGlobals.CancellationPendingValue == 1) break;
                            }
                            if (MainWindow.KMCGlobals.CancellationPendingValue == 1)
                            {
                                BASSControl.BASSCloseStream(Languages.Parse("PlaybackAborted"), Languages.Parse("PlaybackAborted"), 0);
                                BASSControl.ReleaseResources(false);
                                KeepLooping = false;
                                break;
                            }
                            else
                            {
                                BASSControl.ReleaseResources(true);
                                KeepLooping = false;
                                continue;
                            }

If I replace:
Code: [Select]
                            while (Bass.BASS_ChannelIsActive((MainWindow.KMCGlobals.vstIInfo.isInstrument ? MainWindow.VSTs._VSTHandles[0] : MainWindow.KMCGlobals._recHandle)) == BASSActive.BASS_ACTIVE_PLAYING)
With:
Code: [Select]
                            while (true)
It seems to work just fine.

Does WASAPI make BASS return BASS_ACTIVE_STALLED, when there is no enough sample data? DirectSound never behaved like this, so I'm not sure.
I haven't seen any warning about this in the help file.

Ian @ un4seen

  • Administrator
  • Posts: 21136
Yes, I think that explains it. When using WASAPI output, BASS will stall playback if it runs out of data to play because the MIDI stream is taking too long to produce more data. When using DirectSound output, old buffered data would be repeated in that case. BASS will also stall playback on all other platforms in that case (only DirectSound output repeats buffered data).

Instead of checking for "==BASSActive.BASS_ACTIVE_PLAYING", you could check for "!=BASSActive.BASS_ACTIVE_STOPPED".

KaleidonKep99

  • Posts: 173
Yes, I think that explains it. When using WASAPI output, BASS will stall playback if it runs out of data to play because the MIDI stream is taking too long to produce more data. When using DirectSound output, old buffered data would be repeated in that case. BASS will also stall playback on all other platforms in that case (only DirectSound output repeats buffered data).

Instead of checking for "==BASSActive.BASS_ACTIVE_PLAYING", you could check for "!=BASSActive.BASS_ACTIVE_STOPPED".
I will replace it with "!=BASSActive.BASS_ACTIVE_STOPPED" then, thanks.

But still, I don't understand why it works just fine when using BASSWASAPI, while it doesn't with the built-in WASAPI system from the BASS library.

Ian @ un4seen

  • Administrator
  • Posts: 21136
The stalled state only applies when BASS is playing the stream, ie. it's when BASS has stalled playback. When using BASSWASAPI output, your MIDI stream will be a "decoding channel" (BASS_STREAM_DECODE set) and BASS_ChannelIsActive just tells whether it has ended.

KaleidonKep99

  • Posts: 173
The stalled state only applies when BASS is playing the stream, ie. it's when BASS has stalled playback. When using BASSWASAPI output, your MIDI stream will be a "decoding channel" (BASS_STREAM_DECODE set) and BASS_ChannelIsActive just tells whether it has ended.
Oooooh, that makes sense! Thank you for clearing this stuff out, I was really confused at first. :o