Skip to content

Implementation of Coefficients Components #1

Open
pasquale90 wants to merge 9 commits intomasterfrom
coefComponents
Open

Implementation of Coefficients Components #1
pasquale90 wants to merge 9 commits intomasterfrom
coefComponents

Conversation

@pasquale90
Copy link
Copy Markdown
Contributor

@pasquale90 pasquale90 commented Apr 6, 2026

The main features of this involve:

  • the implementation of an expandable UI named Coefficients in the left top sub-window, next to the Export option
  • the implementation of a table that displays the coefficients for the feedforward and the feedback polynomials (ordered by delay), by making use of the RootsToCoefficients::CalculatePolynomialCoefficientsFrom() function
  • Cells are editable restricting invalid user input
  • auto-refresh of the coefficient values upon creation/removal/drag of poles/zeros
  • tooltips on hover for the column names

Missing features:

  • calculation of roots based on coefficient edits and notification through the ValueTree::Listener
  • minor stuff mentioned in comments (TODO)

Main features include:

Registering to the value tree and updating the table of coefficients based on its updates (creating/deleting/dragging zeros/poles) by passing the roots of the filter to the RootsToCoefficients function

Implement editable label fields for allowing users to manually change the values of the coefficients. Updating the value tree based on those edits is missing implementation yet.

TODOs are mentioned in code, as a reference of future improvements
… filterState, and call syncListener function to update the coeffTable immediately upon initialization.

remove explicit destructor since there shouldn't be memory leaks from dynamic allocations of juce::labels in the refreshComponentForCell. See here: https://docs.juce.com/master/classjuce_1_1TableListBoxModel.html#a873b2b84429f026ea046528af1f4fe81

update comments && clean up
Copy link
Copy Markdown
Contributor

@justonem0reuser justonem0reuser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job, thank you.
Just one thing about RootsToCoefficients that I should have clarified earlier (I will add comments to this class later) is the coefficients order. I suggested the correction for it.

Comment thread src/CoeffComponents.cpp Outdated
processor->filterState->zeros);
fbcoeffs = RootsToCoefficients::CalculatePolynomialCoefficientsFrom(
processor->filterState->poles);

Copy link
Copy Markdown
Contributor

@justonem0reuser justonem0reuser Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing that is not obvious concerning CalculatePolynomialCoefficientsFrom method is that is works in terms of z and we would want to see coefficients in terms of 1/z. That's why we have to reverse the elements order to make the 0-th element be equal to 1.
Probably I should add reversing to CalculatePolynomialCoefficientsFrom method itself to avoid the proposed additional code.

Suggested change
std::reverse(ffcoeffs.begin(), ffcoeffs.end());
std::reverse(fbcoeffs.begin(), fbcoeffs.end());

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So doesn't that mean that the "Delay" indexes should be reversed as well, right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, if the number of zeros is less than the number of poles, then the first several coefficients of the numerator are equal to 0.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, great, but instead of reversing the order as a post-process step, shouldn't that be done in place within the CalculatePolynomialCoefficientsFrom method?

Copy link
Copy Markdown
Contributor

@justonem0reuser justonem0reuser Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly. I proposed to add reverse to CoeffComponent as a shortest fix for now to merge this PR. And a little bit later I'm going to change CalculatePolynomialCoefficientsFrom method and carefully modify the methods that call it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To keep things cleaner, afe2210 reverses the order of the coeffs in the CalculatePolynomialCoefficientsFrom method before returning them. So, in case of such a micro-optimization attempt in the future, I don t think there will be a need for modifications outside the scope of this function.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we cannot just add this to CalculatePolynomialCoefficientsFrom without changing code of each method that calls this method. Otherwise, it introduces bugs in other places.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see, ok, I have now overwritten the changes here in 8a2410a. Reversing the order is now taking place within CoefficientsComponent::updateCoeffTable function.

A brief comment on this - since this is spanning in other parts of the codebase, in case there s no particular need to reverse the order in the CalculatePolynomialCoefficientsFrom, we can also conform to this implementation without reversing the whole table (cause it now takes 2*O(n)) in each callback, and simply calculate the mirrored indexes to avoid the added overhead. To keep things maintainable, we can keep std::reverse for now and we can discuss this further at one of our next meetings.

Comment thread src/CoeffComponents.cpp Outdated
}

void CoefficientsComponent::updateCoeffTable(){

Copy link
Copy Markdown
Contributor

@justonem0reuser justonem0reuser Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove the next two lines (getting size)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, yes, thanks for noticing! They are now removed in 5666e50

Comment thread src/CoeffComponents.cpp
label->onTextChange = [this, row, col, label]{
double value = label->getText().getDoubleValue();
if (col == 2)
ffcoeffs[row] = value;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An exception is thrown here when attempting to change ffcoeffs from 0 to another value and its index is greater or equal than the poles number.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea, that 's a bug. Thanks for pointing out. And the reason is due to the size mismatch of the containers that hold the numerator and denominator coeffs. In such case we re now filling the rest of the cells in the visualization table with zeros. But these are editable. Therefore an additional check is now added here (9ed7f7c) to ensure that the row index is less than the table size.

…ting the list of coeffs for visualization purposes(due to a size mismatch between ff and fb), would case segmentation fault when writting back on the source vector
Comment thread src/CoeffComponents.cpp Outdated
tbComp.setStretchToFitActive(true); // expand columns to fill the entire width of the component
coeffTable.setVisible(isExpanded);

processor->filterState->treeRoot.addListener(this);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
processor->filterState->treeRoot.addListener(this);
processor->filterState->addListener(this);

Listen to the filter state, not the tree root. This is necessary for loading presets at runtime.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks, done! 3f6b78d

Comment thread src/CoeffComponents.cpp

void CoefficientsComponent::valueTreePropertyChanged (juce::ValueTree& node, const juce::Identifier& property)
{
if(property == IDs::ValueRe || property == IDs::ValueIm) // when dragging roots
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(property == IDs::ValueRe || property == IDs::ValueIm) // when dragging roots
if(property == IDs::Order)
{
int order = node.getProperty(IDs::Order);
if(order != 0)
{
updateCoeffTable();
}
}
else if(property == IDs::ValueRe || property == IDs::ValueIm) // when dragging roots

should also update when order changes (unless order is set to zero, in which case update will be handled in valueTreeChildRemoved()).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that s correct, thanks. Since this is mostly (excluding the case when filter order becomes zero) about later changes in code (that support manual changes of individual root order), and haven t rebased on them yet to maintain the history of the code review, so I 've tested on a local branch and finally updated this PR with (3f6b78d)

…redundant table updates when zeroing down order of roots in the valueTreePropertyChanged method since these are handled in the valueTreeChildRemoved method
pasquale90 and others added 3 commits April 19, 2026 09:58
… interpretation of the x,width and height values in CoefficientsComponent::resized method
…::CalculatePolynomialCoefficientsFrom method.
@justonem0reuser
Copy link
Copy Markdown
Contributor

I added reversing and setting minimal length to RootsToCoefficients.
I also removed some checks from CoefficientsComponent that I believe are not necessary anymore, but it would be better to review it.
If everything is OK then I think we can merge it.
I decided not to create an additional method and not to add another output value for now, but if we need it then it will be easy to implement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants