If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Trouble updating parameters between two classes

hey guys, great forum - very useful.

When using more than one class, i'm having troubles passing variables between them (ie updating paramets when they change). In a simple example (with only 1 variable) there are two classes - Fader and FaderEffect (in seperate files). the faderEffect class has a constructor in it which creates a new faderEffect

public FaderEffect(float volume){
volumeLevel = volume;
}

In the fader class, i have code which creates a new object:

FaderEffect fader = null; // setting it up

if (fader==null){
fader = new FaderEffect(volume);
}

Which is fine. In the fader class i also have code which automatically updates the volume parameter:

But the problem is that the volumeLevel variable in the faderEffect class doesn't get updated because it only gets updated when you create the new object... so how can i get the varaibles to update automatically? At the moment i have to re-create a new 'Fader' each time...

What you are looking to do is update the volumeLevel variable within your FaderEffect class, which itself is a variable of Fader.

Put "getter and setter" methods in your FaderEffect class. The term "getters and setters" implies the method names match the variable that they get or set. So in your case, you want to be able to get and set the volumeLevel variable, so add two methods, "getVolumeLevel()" and "setVolume(float aVolumeLevel)" to FaderEffect. Your new FaderEffect class can be:

This gets the values from a class called SingleDelay. However SingleDelayEffect extends a class called AudioEffect. You can see here that i have used super(value) to add the value of 'fowardMemSize' to the contructor of AudioEffect. This is fine, but what if the forwardMemSize changes? Ordinarily (for a variable like 'feedback')i can juse ues a method like:

to get the value of feedback from the SingleDelay class if this value changes. But because the value of forwardMemSize is calculated in SingleDelay, and passed over, it won't change. In the SingleDelay class, i'm making a new object each time:

I think I followed you. My response might be confusing too though. Your issue is...within SingleDelay, you might need to set some of the values of your SingleDelayEffect instance, single. So while you can call "single.setFeedback(feedback)", you don't have a "setForwardMemSize(forwardMemSize)" method in SingleDelayEffect to call.

That's fine, and is to be expected. Where I would expect to see the "setForwardMemSize" method is in the AudioEffect class. Each Class should take care of its own variables. And you know AudioEffect is what holds the forwardMemSize variable (or whatever it calls it) since it sets it in the constructor you activate with "super(forwardMemSize)".

I'm guessing AudioEffect is a class you wrote? If so, just go ahead and add the forwardMemSize getter and setter methods to the AudioEffect class. Because your SingleDelayEffect extends AudioEffect, those methods will be available on your "single" variable.

To sum up, if you add a "setForwardMemSize(forwardMemSize)" to AudioEffect, you can use "single.setForwardMemSize(forwardMemSize)". This is possible because of the beauty of Inheritance.

If AudioEffect is something you didn't code, it probably already has a getter and setter defined. At least it should. Let me know if it doesn't.

Side note, I'm assuming you just didn't include it here, but if your SingleDelayEffect class really does extend AudioEffect, you need the "extends AudioEffect" part:

it's kind of the other way around. The varaibles are set/changed in SingleDelay. SingleDelayEffect needs to know when the variables change as it perferms a process on the data with them. SingleDelayEffect extends AudioEffect (Audio effect is a class which deals with chunked data - this requires knowledge of forwardMemSize - which is the no. of samples to delay an audio signal by) and it does this after the class declaration.

Now th problem is that in SingleDelay there is a GUI component that allows the user to change the delay time In milliseconds. I've dealt with this using:

And it's important to note that forwardMemSize is a value calculated in SingleDelay which is ALREADY EQUAL to the initial delaySamples value. But what it means is that it won't ever be updated - although delaySamples will be!!!

I have two methods - one for dealing with chunks (array is streamed), and one which processes the entire array before passing it back to the SingleDelay class. The chunked one won't work if you change the delayInMs value, but the other works perfectly (because that one doesn't use audioeffect16bit!

AudioEffect does indeed deal with it's own variables. Let me throw some code at you:

Code:

public AudioEffect16Bit(int forwardMemSize) {
forwardMemory = new short[forwardMemSize];
}
public void initialiseForward(short val) {
for (int i = 0; i < forwardMemory.length; ++i){
forwardMemory[i] = val;
}
}
/**
* Initializes the forward values to the values specified. The array
* given must be the same size as the size of the previous memory array
* otherwise the memory will not be initialized and an exception will be thrown
*/
public void initialiseForward(short[] vals) throws IncompatibleSizeException {
if (vals.length != forwardMemory.length)
throw new IncompatibleSizeException("Given vals array incompatible size with forwardMemory array");
for (int i = 0; i < forwardMemory.length; ++i){
forwardMemory[i] = vals[i];
}
}

initialiseForward is set every time a chunk is processed in the process(short[] input) method in SingleDelay using: super.initialiseForward(forwardBuffer); where forwardBuffer is the length of delaySamples!!!

So you can see that these two need to match! If using chunks i pressplay with a certain delay size, it seems ok, then if i change it i get exceptions thrown. But i cant' seem to think of a way of getting the super(forwardMemSize) to change with delaySamples.....

So what forwardMemSize really does is change the size allocation for the forwardMemory array. The constructor takes forwardMemSize and uses that to set the size of forwardMemory, which gets done only once ever.

You want to be able to resize forwardMemory I think? That's pretty easy IF you can whipe out the existing forwardMemory data when you do that. If you have to keep the data, it's more of a trick. I'm going to go with assuming you can whipe out (completely redefine) forwardMemory when it changes length.

So we really want a method in AudioEffect16Bit that redefines forwardMemory to a length as defined by the passed in parameter.

Now the Constructor (aka super(value)) and the new method both do the same thing. And you can call the resetForwardMemory(int forwardMemSize) method on any instance of AudioEffect16Bit (and it's children).

WARNING: I need to repeat, calling resetForwardMemory(int forwardMemSize) will wipe out all data in your forwardMemory array. If that's OK for the way your app works, then great. If not, I guess we keep trying.

i think it is ok to get rid of forwardMemSize - i'm not storing it anywhere - it just sets the size of an array.

What's happening at the moment is this. I can set forwardMemSiez to be wahtever, and then while it's playing (in chunks of data, kinda like streaming) it's calling initialiseForward with the new size each time. This works fine and i can even change the delaySamples variable and hear an audible difference (ie it's working).

The problem arises when you try to play it again, and the size you have set last isn't the one which is stored in forwardMemSize.... so i think the answer to your question is YES

If i add this method, what else do i have to change... you've mentioned the modifications with audioeffect16bit but what about the constructor of the simple delay class Also, do you mean make an overloaded constructor in audioeffect16bit?