Author Topic: Performance regression in the latest version of BASSMIDI  (Read 1085 times)

bree

  • Posts: 230
Hello! It's been a while since I last made a post here.

I recently updated both the BASS and BASSMIDI libs, in my MIDI driver, from 2.4.14.27 to 2.4.15.59 and 2.4.12.10 to 2.4.13.17 respectively.
I noticed a noticeable performance degradation after updating the libraries, BASSMIDI seems to be missing a lot of notes compared to the previous version I had.

Here are videos of the two versions of the library, the original vs the latest version.
BASSMIDI 2.4.12.10: https://www.youtube.com/watch?v=Uu0zHrBWt90
BASSMIDI 2.4.13.17: https://www.youtube.com/watch?v=lj4ABrUBpPk

Ian @ un4seen

  • Administrator
  • Posts: 23890
From the "Active voices" displays in those videos, the number of voices looks the same in both, so the difference will be in which notes are being dropped to meet the voice limit. BASSMIDI drops the quietest note when the voice limit is exceeded but the issue with black MIDI files is that they may use multiple quiet notes instead of one louder note, eg. could be 100 duplicate notes with velocity=1 instead of 1 note with velocity=100. That makes it trickier to know which notes should be dropped.

Just calculating whether a note should play uses some CPU (even if the note isn't played at the end of that), which can cause the BASS_ATTRIB_MIDI_CPU setting to be exceeded with black MIDI files regardless of the voice limit. So BASSMIDI 2.4.13 added a tweak to prevent that by dropping all new notes in an update cycle once the voice limit is exceeded by a long way. I guess that's probably what's causing the difference here. If you upload the file from the videos, I'll have a look and see if things can be tweaked a bit more.

   ftp.un4seen.com/incoming/

bree

  • Posts: 230
From the "Active voices" displays in those videos, the number of voices looks the same in both, so the difference will be in which notes are being dropped to meet the voice limit. BASSMIDI drops the quietest note when the voice limit is exceeded but the issue with black MIDI files is that they may use multiple quiet notes instead of one louder note, eg. could be 100 duplicate notes with velocity=1 instead of 1 note with velocity=100. That makes it trickier to know which notes should be dropped.

Just calculating whether a note should play uses some CPU (even if the note isn't played at the end of that), which can cause the BASS_ATTRIB_MIDI_CPU setting to be exceeded with black MIDI files regardless of the voice limit. So BASSMIDI 2.4.13 added a tweak to prevent that by dropping all new notes in an update cycle once the voice limit is exceeded by a long way. I guess that's probably what's causing the difference here. If you upload the file from the videos, I'll have a look and see if things can be tweaked a bit more.

   ftp.un4seen.com/incoming/
Done, the file is Satori Maiden LOLEX Mode v3.0.zip.
It's 300MB, so I suggest either using BASSMIDI Test with 1000 voices or OmniMIDI with a very good MIDI player.

Zenxia

  • Posts: 132
Similar problem is that i say when send delays to note off, will be partially solves enabling "Only kill last noteoff event" but this causes some problems on common midis that need this option disabled because not mutes when need and keep note like cc#64 enabled.

I'm think that noteoff need kill note at same time that delay noteoff. I think that the "Only kill last noteoff event" kill notes before time. 10 ms can solve problem. you can try a test of this.

For test add the 10 ms delay. play a good midi with this option disabled, and solve the note shutdown. This bug can appear also when gets a minimal lagg in the playback.

The photo have one example.

This appear also sometimes if receive lagg on system in a ms.

  • Default midi = a 9 notes playback normally (~60 ms notes)
  • Midi beatnik mode = When Keepysoftsynth sets delay to noteoff a 10 ms, noteoff enter with conflict with overlapping and appears smetimes when "Only kill last noteoff event" option is disabled and this cause that this option doesn't work in 80% of all midis.
  • Midi beatnik mode original synth. same to bassmidi beatnik mode but the note kill's delayed  same as delay "10ms" with "Only kill last noteoff event"  disabled.




« Last Edit: 26 Jun '21 - 06:14 by MIDAPMI »

Ian @ un4seen

  • Administrator
  • Posts: 23890
Done, the file is Satori Maiden LOLEX Mode v3.0.zip.
It's 300MB, so I suggest either using BASSMIDI Test with 1000 voices or OmniMIDI with a very good MIDI player.

Thanks. Here's an update that I think gets that file sounding better:

   www.un4seen.com/stuff/bassmidi.zip

Let me know if do you still see a problem with that file or any other files.

Similar problem is that i say when send delays to note off, will be partially solves enabling "Only kill last noteoff event" but this causes some problems on common midis that need this option disabled because not mutes when need and keep note like cc#64 enabled.

I'm think that noteoff need kill note at same time that delay noteoff. I think that the "Only kill last noteoff event" kill notes before time. 10 ms can solve problem. you can try a test of this.

For test add the 10 ms delay. play a good midi with this option disabled, and solve the note shutdown. This bug can appear also when gets a minimal lagg in the playback.

The photo have one example.

This appear also sometimes if receive lagg on system in a ms.

  • Default midi = a 9 notes playback normally (~60 ms notes)
  • Midi beatnik mode = When Keepysoftsynth sets delay to noteoff a 10 ms, noteoff enter with conflict with overlapping and appears smetimes when "Only kill last noteoff event" option is disabled and this cause that this option doesn't work in 80% of all midis.
  • Midi beatnik mode original synth. same to bassmidi beatnik mode but the note kill's delayed  same as delay "10ms" with "Only kill last noteoff event"  disabled.

Sorry, but it isn't clear to me what you mean. Are you asking for something to be changed in BASSMIDI? If so, please clarify what that is.

bree

  • Posts: 230
Done, the file is Satori Maiden LOLEX Mode v3.0.zip.
It's 300MB, so I suggest either using BASSMIDI Test with 1000 voices or OmniMIDI with a very good MIDI player.

Thanks. Here's an update that I think gets that file sounding better:

   www.un4seen.com/stuff/bassmidi.zip

Let me know if do you still see a problem with that file or any other files.
That seems to have done it, at 1000 voices that is. ;D
But at 1500 it seems to still perform worse than older releases, missing notes here and there. ???

EDIT: Even at 1000 voices, the XAudio2 engine in my driver doesn't seem to hit the same amount of notes like it does with the old libraries. :'(
It's still a huge improvement compared to the old libraries though!

EDIT 2: Tested Satori Maiden with the XP-80 soundfont, which is notorious to be extremely tasking to render for BASS.
With 1000 voices and the new libraries it still can't play properly, while the old libraries can do it just fine.
If you need the soundfont for testing, I can send it over using FTP.
« Last Edit: 28 Jun '21 - 16:29 by bree »

Zenxia

  • Posts: 132
MIDAPMI is now Zenxia

Thanks Ian luck, Hopefully in any further update you add any cc like to att chorus and reverberation, every update bassmidi is better.

Btw, I have two question i can enable sine lfo via flag for full DLS emulation.
« Last Edit: 28 Jun '21 - 18:24 by Zenxia »

Ian @ un4seen

  • Administrator
  • Posts: 23890
That seems to have done it, at 1000 voices that is. ;D
But at 1500 it seems to still perform worse than older releases, missing notes here and there. ???

There will always be plenty of missing notes when playing black MIDI files. The aim is to make them the less important ones :)

Trying 1500 voices here (with a modified MIDITEST example), I don't notice any obviously dropped notes (using the CT2MGM soundfont), but it is sometimes taking too much CPU and so some voices get killed then. Perhaps the same is happening there? Is the voice count below 1500 when you notice a difference? If not, please give a position where the difference is most noticeable.

EDIT 2: Tested Satori Maiden with the XP-80 soundfont, which is notorious to be extremely tasking to render for BASS.
With 1000 voices and the new libraries it still can't play properly, while the old libraries can do it just fine.
If you need the soundfont for testing, I can send it over using FTP.

Please do upload the soundfont to have a look at. I suspect the difference will probably be that it's using multiple samples/layers per note, which means fewer notes can be played before hitting the voice limit.

bree

  • Posts: 230
That seems to have done it, at 1000 voices that is. ;D
But at 1500 it seems to still perform worse than older releases, missing notes here and there. ???

There will always be plenty of missing notes when playing black MIDI files. The aim is to make them the less important ones :)

Trying 1500 voices here (with a modified MIDITEST example), I don't notice any obviously dropped notes (using the CT2MGM soundfont), but it is sometimes taking too much CPU and so some voices get killed then. Perhaps the same is happening there? Is the voice count below 1500 when you notice a difference? If not, please give a position where the difference is most noticeable.

EDIT 2: Tested Satori Maiden with the XP-80 soundfont, which is notorious to be extremely tasking to render for BASS.
With 1000 voices and the new libraries it still can't play properly, while the old libraries can do it just fine.
If you need the soundfont for testing, I can send it over using FTP.

Please do upload the soundfont to have a look at. I suspect the difference will probably be that it's using multiple samples/layers per note, which means fewer notes can be played before hitting the voice limit.
Sent! It's a piano-only SoundFont, so it will not work with MIDIs using different instruments.

Ian @ un4seen

  • Administrator
  • Posts: 23890
Thanks. I tried comparing the latest BASSMIDI and 2.4.12.10 with that MIDI file and soundfont combination (using 1000 voices) but I couldn't notice any obvious differences. It was ear-bleedingly loud though, so perhaps I just missed them! Is there a position where a difference is particularly noticeable?

I'm comparing with the MIDITEST example, so please also try that there, to see if it's giving different results to your app.

bree

  • Posts: 230
Thanks. I tried comparing the latest BASSMIDI and 2.4.12.10 with that MIDI file and soundfont combination (using 1000 voices) but I couldn't notice any obvious differences. It was ear-bleedingly loud though, so perhaps I just missed them! Is there a position where a difference is particularly noticeable?

I'm comparing with the MIDITEST example, so please also try that there, to see if it's giving different results to your app.
I think the issue isn't as apparent in the BASSMIDI Test app because it's not really doing stuff in real-time (e.g. receiving the MIDI events in real-time through BASS_MIDI_StreamEvent/s).
This is why I recommended testing through my driver if possible, using a MIDI app that is able to push BASS to its limit.

My testing ground is OmniMIDI through Chikara, which directly sends the data to BASSMIDI using KDMAPI (SendCustomEvent, a function that wraps around BASS_MIDI_StreamEvent).

The "hottest" parts in the MIDI are at 1:34 and 2:49.

I also sent you my exact OmniMIDI settings (.reg file) in the FTP server, in case you want to test it yourself. They can be imported from the "Settings" tab in the configurator.
In case you want to test a freshly compiled library, you can place it in C:\Windows\SysWOW64\OmniMIDI for 32-bit, and C:\Windows\System32\OmniMIDI for 64-bit.

Ian @ un4seen

  • Administrator
  • Posts: 23890
OK. The "dropping all new notes in an update cycle once the voice limit is exceeded by a long way" tweak that I mentioned in my first reply (and the refinement of that in the 2.4.13.18 update posted above) actually only applies to notes that are played within a BASS/BASSMIDI update cycle, eg. during a MIDI file/sequence playback. It doesn't apply when you call BASS_MIDI_StreamEvent in your own thread, so it doesn't seem like it should affect your driver? Do you hear a difference between BASSMIDI 2.4.13.17 and the 2.4.13.18 update above when used with your driver?

bree

  • Posts: 230
OK. The "dropping all new notes in an update cycle once the voice limit is exceeded by a long way" tweak that I mentioned in my first reply (and the refinement of that in the 2.4.13.18 update posted above) actually only applies to notes that are played within a BASS/BASSMIDI update cycle, eg. during a MIDI file/sequence playback. It doesn't apply when you call BASS_MIDI_StreamEvent in your own thread, so it doesn't seem like it should affect your driver? Do you hear a difference between BASSMIDI 2.4.13.17 and the 2.4.13.18 update above when used with your driver?
Yeah, for some reason it seems to be able to score more notes.
Video: https://youtu.be/UUYIQhyvcQQ

Ian @ un4seen

  • Administrator
  • Posts: 23890
I tried your driver and confirmed that the BASS_MIDI_StreamEvent calls aren't in a BASS/BASSMIDI update cycle thread, so the tweak I mentioned isn't coming into play. So I guess it must be something else that changed between v2.4.13.17 to v2.4.13.18 that's making the difference for you, but I don't think anything else did change. I'll have another look. I wasn't using the Chikara player you mentioned (didn't have Vulkan on the test system), but I don't suppose the player affects where the BASS_MIDI_StreamEvent calls are?

bree

  • Posts: 230
I tried your driver and confirmed that the BASS_MIDI_StreamEvent calls aren't in a BASS/BASSMIDI update cycle thread, so the tweak I mentioned isn't coming into play. So I guess it must be something else that changed between v2.4.13.17 to v2.4.13.18 that's making the difference for you, but I don't think anything else did change. I'll have another look. I wasn't using the Chikara player you mentioned (didn't have Vulkan on the test system), but I don't suppose the player affects where the BASS_MIDI_StreamEvent calls are?
It depends on how the player sends the data. BASS_MIDI_StreamEvent can be either called by my driver's own events processer thread,

or by the developer by calling SendCustomEvent (which basically wraps around BASS_MIDI_StreamEvent).


If I recall correctly, Chikara uses the former (So I was wrong in the original message about it, oops! :-X)

Also, Chikara's dev apparently has encountered some heap corruptions with the new libs, which aren't present in the old "Black MIDI proof" versions of them.
« Last Edit: 1 Jul '21 - 18:00 by bree »

Zenxia

  • Posts: 132
I'm think that bassmidi noteoff is very quiet, i mean that if noteoff events cut off notes after ~10-15 ms will solve the lagg experience. This is the reason described above. You can test or add a test version at least. for skip problem with ghost on forums can make 10ms. I tested and fastest midis looks well at 10ms. but for keep perfomance in very fastly midi (aka blackmidi) can bassmidi auto disable this when maximum voices is reached.

When i playback midi on synthfont same midi in synthfont reach 38 voices peak (soundblaster mode), and in bassmidi 24 voices. I measured length of the decays in audacity and have same length

The decay slope is different when you says that try to add more release, this sound looks like any other synths,  but  this add pseudo-reverb effect + more voice usage instead noteoff.

The actually option (delay noteoff in [ ms ]) is nulled by noteoff and not allow the 10ms overlapping anyway.

Ian @ un4seen

  • Administrator
  • Posts: 23890
Also, Chikara's dev apparently has encountered some heap corruptions with the new libs, which aren't present in the old "Black MIDI proof" versions of them.

Do you know what function call that's happening in? If not, to narrow it down, please try combining the old BASS with the new BASSMIDI, and the new BASS with the old BASSMIDI, and see if the problem still happens in either case.

I've looked at the changes between BASSMIDI 2.4.13.17 and 2.4.13.18 again but I didn't see anything that should affect your driver's BASS_MIDI_StreamEvent calls, so it's puzzling that you're hearing a difference between them. I'm unable to run Chikara. Is there another MIDI player that you would recommend? I found one called Kiva. If you've tried that, do you hear the difference with it too? I noticed it does some preprocessing when loading a MIDI file, presumably to reduce the number of notes played, so that might change the results compared to other players.

bree

  • Posts: 230
Also, Chikara's dev apparently has encountered some heap corruptions with the new libs, which aren't present in the old "Black MIDI proof" versions of them.

Do you know what function call that's happening in? If not, to narrow it down, please try combining the old BASS with the new BASSMIDI, and the new BASS with the old BASSMIDI, and see if the problem still happens in either case.

I've looked at the changes between BASSMIDI 2.4.13.17 and 2.4.13.18 again but I didn't see anything that should affect your driver's BASS_MIDI_StreamEvent calls, so it's puzzling that you're hearing a difference between them. I'm unable to run Chikara. Is there another MIDI player that you would recommend? I found one called Kiva. If you've tried that, do you hear the difference with it too? I noticed it does some preprocessing when loading a MIDI file, presumably to reduce the number of notes played, so that might change the results compared to other players.
It seems to be happening randomly, and replacing BASS with the original "Black MIDI proof" version doesn't seem to fix it, so I guess it's something wrong inside BASSMIDI.

I could send you PFAviz, which is another MIDI player I use to test my driver with. Check the FTP server.
You need to stretch the piano roll to its max by using SHIFT+Down, to reduce the bottleneck caused by the render thread as much as possible, and patching the application using OmniMIDI's Windows Multimedia Wrapper is required on Windows 8.x+.

Zenxia

  • Posts: 132
I'm sure that Ian will adds all soundblaster modulator progressively. In the last two years bassmidi are added various improvements, npw the sound if very better than earlier versions. Now it's possible emulate any synths (exept by curves, due soundfont limitation).

Ian @ un4seen

  • Administrator
  • Posts: 23890
It seems to be happening randomly, and replacing BASS with the original "Black MIDI proof" version doesn't seem to fix it, so I guess it's something wrong inside BASSMIDI.

Just to be sure, are you referring to the sound/notes issue that you reported in this thread or the heap corruption that the Chikara dev reported? In either case, to narrow it down further, please try the BASSMIDI 2.4.13 release version and see if it happens with that too.

Regarding the sound issue, does it seem to be a CPU/time issue, eg. like events aren't processed quickly enough? If it doesn't happen with the MIDITEST example then you could try telling BASS/BASSMIDI that your event thread (where BASS_MIDI_StreamEvent is called) is an "update thread", which will enable BASSMIDI's note skipping stuff (to reduce processing). You can do that like this with the latest BASS (won't work with old versions):

Code: [Select]
#define BASS_CONFIG_INUPDATE 0x8001
BASS_SetConfig(BASS_CONFIG_INUPDATE, 4);

For example, you could do that at the start of the thread. If you want, you can later remove the "update thread" status by using 0 instead of 4 in the BASS_SetConfig call.

Another thing that might help a little is to use BASS_MIDI_StreamEvents (with BASS_MIDI_EVENTS_STRUCT) to process your buffered events in batches, instead of individually with BASS_MIDI_StreamEvent. I'm not sure that will make a massive difference but it should have slightly lower processing overheads.

Ian @ un4seen

  • Administrator
  • Posts: 23890
I've looked at the changes between BASSMIDI 2.4.13.17 and 2.4.13.18 again but I didn't see anything that should affect your driver's BASS_MIDI_StreamEvent calls...

I had another look and this time I did find a difference :)

Black MIDI files often have duplicate notes, so BASSMIDI 2.4.13 added a tweak to improve black MIDI file playback with lower voice limits by having duplicate notes share a voice, ie. just increasing the voice's volume for each duplicate. But checking for duplicate notes/voices is slower, particularly when the voice limit is high. That duplicate checking was tweaked in the 2.4.13.18 update above, so that explains why it's working better with your driver. This duplicate checking should mean that very high voice limits are unnecessary in most cases.

bree

  • Posts: 230
It seems to be happening randomly, and replacing BASS with the original "Black MIDI proof" version doesn't seem to fix it, so I guess it's something wrong inside BASSMIDI.

Just to be sure, are you referring to the sound/notes issue that you reported in this thread or the heap corruption that the Chikara dev reported? In either case, to narrow it down further, please try the BASSMIDI 2.4.13 release version and see if it happens with that too.
Yeah I was talking about the heap corruption issue, it does not happen with 2.4.13.

Regarding the sound issue, does it seem to be a CPU/time issue, eg. like events aren't processed quickly enough? If it doesn't happen with the MIDITEST example then you could try telling BASS/BASSMIDI that your event thread (where BASS_MIDI_StreamEvent is called) is an "update thread", which will enable BASSMIDI's note skipping stuff (to reduce processing). You can do that like this with the latest BASS (won't work with old versions):

Code: [Select]
#define BASS_CONFIG_INUPDATE 0x8001
BASS_SetConfig(BASS_CONFIG_INUPDATE, 4);

For example, you could do that at the start of the thread. If you want, you can later remove the "update thread" status by using 0 instead of 4 in the BASS_SetConfig call.

Another thing that might help a little is to use BASS_MIDI_StreamEvents (with BASS_MIDI_EVENTS_STRUCT) to process your buffered events in batches, instead of individually with BASS_MIDI_StreamEvent. I'm not sure that will make a massive difference but it should have slightly lower processing overheads.
I will try the config flag tomorrow, and I'll let you know if that improves the performance.

About the idea of processing the events in batch, I can't do that because that would reduce the precision of the notes and introduce "choppiness" (Like when you use a really high buffer size in ASIO, 1024+).
I want the notes to be played as fast as possible, one by one, and using StreamEvent is the only way to achieve that.

bree

  • Posts: 230
I tried the flag, and I hear no difference. ???

Ian @ un4seen

  • Administrator
  • Posts: 23890
Here's an update that should get the note event processing performance back to the same as in BASSMIDI 2.4.12 (perhaps even a bit faster) while still optimizing duplicates:

   www.un4seen.com/stuff/bassmidi.zip

Let me know if it still seems slower in your tests.

About the idea of processing the events in batch, I can't do that because that would reduce the precision of the notes and introduce "choppiness" (Like when you use a really high buffer size in ASIO, 1024+).
I want the notes to be played as fast as possible, one by one, and using StreamEvent is the only way to achieve that.

I don't think it should affect precision if you don't wait to fill a batch. For example, if you use a 16 element BASS_MIDI_EVENT array to batch the events, but you only have 4 events to play, then you would just send those 4 events instead of waiting for 12 more. It probably won't make a massive difference but could be worth trying if you're ever bored :)

bree

  • Posts: 230
Here's an update that should get the note event processing performance back to the same as in BASSMIDI 2.4.12 (perhaps even a bit faster) while still optimizing duplicates:

   www.un4seen.com/stuff/bassmidi.zip

Let me know if it still seems slower in your tests.

About the idea of processing the events in batch, I can't do that because that would reduce the precision of the notes and introduce "choppiness" (Like when you use a really high buffer size in ASIO, 1024+).
I want the notes to be played as fast as possible, one by one, and using StreamEvent is the only way to achieve that.

I don't think it should affect precision if you don't wait to fill a batch. For example, if you use a 16 element BASS_MIDI_EVENT array to batch the events, but you only have 4 events to play, then you would just send those 4 events instead of waiting for 12 more. It probably won't make a massive difference but could be worth trying if you're ever bored :)
It is still noticeably slower, yeah...

I added the temporary ability to OM to switch DLLs on the fly, to compare the two in real-time.
Here's the video: https://www.youtube.com/watch?v=-DNr4swsWeI