Author Topic: Intermediate VST Mixer causing UI performance hit on macOS  (Read 872 times)

BaseHead

  • Posts: 144

Hey Ian and gang!
Sooo.....I popped in an intermediate mixer for just VST streams on our macOS version just like I did in our .NET one and notice a huge performance hit graphically.
The time counters and playhead are moving chunky slow now.
instead of like 30 fps they look more like 10-15fps

the rough old code was like this

Code: [Select]
                    int stream0 = BASS_StreamCreateFile(FALSE, [aPath UTF8String], 0, 0, BASS_STREAM_DECODE);
                    int mixer = BASS_Mixer_StreamCreate(bass_info.freq, speakers, BASS_MIXER_NONSTOP);
                    BASS_Mixer_StreamAddChannel(mixer, stream0, BASS_SPEAKER_N(2) |BASS_MIXER_MATRIX);

 

and the new way is just adding this new 8 channel mixer in the middle

Code: [Select]
                    int stream0 = BASS_StreamCreateFile(FALSE, [aPath UTF8String], 0, 0, BASS_STREAM_DECODE);
                    mixer = BASS_Mixer_StreamCreate(bass_info.freq, speakers, BASS_MIXER_BUFFER);
                    mixerVST = BASS_Mixer_StreamCreate(bass_info.freq, 8, BASS_STREAM_DECODE  | BASS_MIXER_NONSTOP);
                    BASS_Mixer_StreamAddChannel(mixerVST, stream0, BASS_SPEAKER_FRONT);
                    BASS_Mixer_StreamAddChannel(mixer, mixerVST, BASS_MIXER_MATRIX);



Anyone have an idea (or tips how to fix) why adding a basic 8 channel mixer in the middle seems to be soaking the UI refresh rate so bad?
I should NOTE: Everything is working and playing correct.  It's just not looking like the buttery smooth application I had before this was added.  8(

thank for any tips!

Steve
               

Ian @ un4seen

  • Administrator
  • Posts: 21012
Is there an actual performance hit (eg. CPU usage increase indicated by BASS_GetCPU) or is it just that the reported position isn't as precise/granular as before? If it's the latter, please confirm which handle you are getting the position of, and how.

BaseHead

  • Posts: 144
Yeah it looks like if I change getting the position from steam0 to mixerVST it fixes the graphic chunky monkey issues and back to silky smooth.
Of course it just broke 20 other transport things....hahaha
i have a long day ahead of me repairing this, but I think I'll be alright now.  8)

Thx Ian!

BaseHead

  • Posts: 144
Hey Ian,
back on this...
Like I said before, if I change the handle to the new intermediate VST only mixer stream that caused this in the first place (mixerVST) it refreshes smooth as butter again BUT way too much gets broken to repair so I'm hoping you have another idea to try.. ;)

I'm just getting the position like this currently inside a NSTimer timerFireMethod
position = BASS_Mixer_ChannelGetPosition(stream[0], BASS_POS_BYTE);

if I change it to this,. it refreshes smooth again but breaks too many other things to stomach to change...haha
position = BASS_Mixer_ChannelGetPosition(mixerVST, BASS_POS_BYTE);

any parameters that I need to change maybe?


FYI....I did do a BASS_CPU test and no difference between both modes.
Thx for any tips man!

Steve



Ian @ un4seen

  • Administrator
  • Posts: 21012
It looks like the mixer was played directly in the old smooth case, while it isn't in the new non-smooth case, ie. it's using the BASS_STREAM_DECODE flag now. In that case, the mixer won't know what the output's latency is any more. To get around that, you can tell the mixer what the latency is via its BASS_ATTRIB_MIXER_LATENCY setting. For example, you could do something like this:

Code: [Select]
DWORD buffered = BASS_ChannelGetData(mixer, NULL, BASS_DATA_AVAILABLE); // get buffered data from output mixer
float latency = BASS_ChannelBytes2Seconds(mixer, buffered); // translate to seconds
BASS_ChannelSetAttribute(mixerVST, BASS_ATTRIB_MIXER_LATENCY, latency); // tell the intermediate mixer
sourcepos = BASS_Mixer_ChannelGetPosition(stream0, BASS_POS_BYTE); // get the source position

BaseHead

  • Posts: 144
thx for the reply man!

but...
BASS_ChannelSetAttribute(mixerVST, latency); needs an extra argument.
and
BASS_ChannelSetAttribute(mixerVST, BASS_ATTRIB_MIXER_LATENCY, latency); doesn't work cuz BASS_ATTRIB_MIXER_LATENCY doesn't seem to exist in BASS for Obj-C. and all the forum posts I see mention in on the forum are for WASAPI only.
Is it available on macOS?


Chris

  • Posts: 1850
if the BASS_ATTRIB_MIXER_LATENCY doesnt exists then just add it.

Code: [Select]
#define BASS_ATTRIB_MIXER_LATENCY 0x15000
BASS_ChannelSetAttribute(mixerVST, BASS_ATTRIB_MIXER_LATENCY, latency);
« Last Edit: 31 Mar '18 - 04:40 by Chris »

BaseHead

  • Posts: 144
Thx for the tip Chris!
that seemed to fix that issue. 

Unfortunately Ian, my position and Spectrum Meter refresh rate is still slow chunky monkey speeds instead of smooth as butter like before  :'(

Ian @ un4seen

  • Administrator
  • Posts: 21012
Are you repeating the BASS_ChannelGetData(BASS_DATA_AVAILABLE) and BASS_ChannelSetAttribute steps before every BASS_Mixer_ChannelGetPosition call? If not, try that, so that the mixer has the latest latency information each time. If you're using BASS_Mixer_ChannelGetData/Level, you should do the same before them too.

BaseHead

  • Posts: 144
I tried both ways.  Just calling it each time a new file is loaded and also inside the timer firing XX times a second.
I also tried removed anything else using BASS_Mixer_ChannelGetData/Level like Spectrum Meters and Stereo Meters and didn't help.

Anything else to try you can think of?
Are we sure that manually adding #define BASS_ATTRIB_MIXER_LATENCY   0x15000 to my header, that Chris kindly suggested,  was the correct move?
Strange that that parameter wasn't there out the gate.

It's definitely getting the latency cuz I see that in the logs  XX times a second when in the timer and the value is slightly different each time

Our .NET version didn't get this problem when the same mixer was added, but the code is very different

thx man!


Ian @ un4seen

  • Administrator
  • Posts: 21012
If BASS_ATTRIB_MIXER_LATENCY wasn't already defined, then perhaps you are using an old version of BASSmix? You can use BASS_Mixer_GetVersion to check that. Also check the return value of the BASS_ChannelSetAttribute call, to confirm whether it was successful.

BaseHead

  • Posts: 144
My BassMix was up to date but not the header file for it.  Fixed that and no change still....darn

here is my current code

Code: [Select]
- (void)timerFireMethod:(NSTimer*)theTimer
{
    DWORD buffered = BASS_ChannelGetData(mixer, NULL, BASS_DATA_AVAILABLE); // get buffered data from output mixer
    float latency = BASS_ChannelBytes2Seconds(mixer, buffered); // translate to seconds
   
    if (BASS_ChannelSetAttribute(mixerVST, BASS_ATTRIB_MIXER_LATENCY, latency));  // tell the intermediate mixer
        DBGLog(@"Latency Set True: %f", latency);
 
    position = BASS_Mixer_ChannelGetPosition(stream[0], BASS_POS_BYTE); // get the source position

and you can see it returning TRUE to the Attribute setting and showing the latency it's sending in the timer in the log in the attached png

Here's also a video to see the difference also with and without the intermediate mixer  8)
https://www.dropbox.com/s/b2cg683wmf1w7o3/VID_20180418_012726.mp4?dl=0

hopefully you got another theory  8)


   

Ian @ un4seen

  • Administrator
  • Posts: 21012
Ah, I forgot to say that you will need to set the BASS_MIXER_POSEX flag on the mixer to enable the BASS_ATTRIB_MIXER_LATENCY option. The strange thing is the BASS_ChannelSetAttribute call should fail if it hasn't been enabled; is that call definitely succeeding? Perhaps you have already added the BASS_MIXER_POSEX flag to the "mixerVST" BASS_Mixer_StreamCreate call? If not, give that a try and and see if it changes things.

BaseHead

  • Posts: 144
Yes!!!  Ding ding ding! We have a winner!    ;D
POSEX did the trick.

thx so much man! such a lifesaver cuz it was totally killing me....hehe
It was one of my last big hurdles before I can post the first Public Beta of version 5.x

Thx brother!

Steve