Several instances synt -> wonky


#1

So, this synt I’m workin on is comming together nicely.
Have a look

But, when I add another instance, in tracktion, the sound gets all choppy and sometimes all quiet.

I suspect that this is a case of something being global and shared between the instances, but I can’t figure out what.

There is nothing in global scope that I know about. I use arrays for parameters, but I allocate them myself so they should be ok, right?

I only have one static function that looks like so:

static bool setPreset(float * p,int index){ float * parameters = p; if (index==0){ parameters[0] = 0.562500; parameters[1] = 0.999000; parameters[2] = 0.000000; parameters[3] = 2.000000; etc,etc...
But since it takes a pointer to the array as a parameter it should be allright , right?

So, are there any “usual suspects” to look for in this sitch?
What would Elvis do?


#2

Hmm, So, I fixed it by making the parameter array private, which makes no fucking sense.

First of all, I pass a pointer to this array around like it’s a fatty. The voice objects need to read the parameters. Should they really be able to do that if the array is private?
Well, they are. Or I suppose it’s only the pointer that is private?

Secondly, why does the private/public thing confuse multiple instances? The memory is allocated in the constructor so every intance of the synth should have its own memory for the array, never mind that it’s public… or that the pointer is public anyway.

This is tremendously mysterious to me.


#3

I updated the file, in case anyone wants to give it a try. I think its pretty cool.
Linky

I would still appreciate if someone could shed some light on this behaviour though.


#4

public, private, etc… really has no sense once it is compiled, it is just for access control in the source code. Why it would effect the compile, no clue…


#5

Hm, ok, that explains half the mystery, but makes the other half all the more mysterious.

I have gone back and forth over this a few time and there is no two ways about it. If the array is public, it will conflict between instances. If it is private, there is no problem.
Perhaps I should mention that when I say array, I mean a malloc:ed chunk used as an array.

Thanks.


#6

Public or private doesn’t make sense on binary object.
However, what I suspect, is that you are experencing buffer overrun somewhere in your code.

Changing the variable from public to private moves it in memory (depending on compiler of course, but at least vc6 does this). So the faulty code don’t touch it if it is public (because it is then after the private data).

class A
{
private: int b, c, d;
public: double g, h;
protected: float i;
...
};
can have a memory like this :
  [ <= A memory block           => ]
  [ g h b c d i virtual_ptr_table  ]
while 
class A
{
private: int b, c, d; double h;
public: double g;
protected: float i;
...
};
will then appear like:
  [ <= A memory block           => ]
  [ g b c d h i virtual_ptr_table  ]

If your code access &h + 2 by error, in the first case it will point to "d i" while it will point to virtual_ptr_table in the second

Try to build in debug (if you were releasing it) with private variable, and the “bug” shouldn’t appear (because the compiler adds “safe” bytes in the arrays to check for under/over runs).

Attach Tracktion to the debugger, launch your component, once, twice or more, and then exit. Visual studio will report the “evil” memory access.


#7

That might be it.
The culprit is probably the buffer I use to assemble the output block, and moving the parameters array might cause it to shift in memory. Or something.
I’ll try the debug thing when I get home.

Cheers


#8

Well, I’m not getting any illegal memory access messages with the debug build either.
But I am pretty certain that that’s the problem. I noticed that setting it as private doesn’t really fix the problem, it just makes it so the wonk happend when I add the thid instance rather than the second.
Which supports X-Ryl669 theory about the memory layout.

But I can’t find any illegal uses of the arrays.

So, hints and suggenstions on how to track such problems down would be appreciated.
Are there any free tools around for that kind of checking?


#9

Hmm, I think I may need some Jules time here. Because, energyXT demo handles 8 instances of the synth without batting an eyelash. Tracktion does the wacky after two or three.

It sounds like they are overwriting eachothers buffers or something.


#10

Ok, nailed it down. There were two problems. One were related to the memory thing.

The other was apparently that if I dont clear the midibuffer, parts of it got passed on to the other instances. :shock:


#11

I’m having the same problem - what was the memory-related solution?

Does this mean I have to put every value in every array back to its original value? I use 3 tons of arrays (the effect has 3 bands per channel), and many values must persist, for interpolation purposes etc. (eg. lastRMS[Ch]).

Or would just using ** and *** in all cases create actual separate arrays instead of recycling memory or whatever it thinks its doing?

Just when I got it sounding good…

(host.getNumBugs (today) > me.getNumBugs (today)) == true;

Dave Heinemann.

VCExpress
Sonar 6.0.1 (VERY buggy for VST - kept the old version installed too)
Homemade PC P4 3.0 (only 1 core though, time to cook up a new one)
And one insanely complex plugin, extremely beta


#12

Hi, I don’t remember actually, but it was some kind of illegal memory access. I think I shifted from mallocs to “new” allocations and the debugger suddenly pointed out where I went out of bounds.

Clearing the midibuffer is what you’re supposed to do if your plug takes midi but does’nt send any.

But you don’t need to do anything special with arrays in general other than make sure they are not global, static or made by a singleton. Those are the three cases that causes plugs to share data.

In short, just make sure everything gets instantiated per instance so to speak, because the actual dll is likely only loaded once.


#13

Thanks - I guess it makes sense for efficiency to only load the dll once.

It might be cool to have effects communicate, but not through memory errors!

me.sendRegards(true);

Dave Heinemann


#14

For static arrays, does that also mean static pointers to arrays created with new? I have some of those, trying to work around host bugs (like sending a change message before initialise() is called).

Is static in effect the same as singleton if the dll is loaded only once? Useful for communication purposes (a global cpu meter showing 60-90% is more useful than 32 separate ones showing 2-3%, and tabbing multiple instances of a large GUI would be good), but not useful if per-instance statics are needed.

I’m not sure how good I feel about finding less bugs and hassles in MY code and more in hosts…

Dave Heinemann


#15

Yes, statics are shared between all instances of your plugin, but use them very carefully. You’re ok using them for things like global constants and read-only data, but not for components or anything like that.


#16