New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Waveform Rendering #2635
Waveform Rendering #2635
Conversation
@@ -0,0 +1,30 @@ | |||
#[[ | |||
A library responsible for custom rendering in Audacity | |||
]]# |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trailing # isn't needed to bracket a long comment
@@ -0,0 +1,130 @@ | |||
/* SPDX-License-Identifier: GPL-2.0-or-later */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a comment convention we should do in all files?
There should be more regularity but I'm not sure what exactly it should be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a standardized approach, so yes, I would like it see more of it!
@@ -0,0 +1,130 @@ | |||
/* SPDX-License-Identifier: GPL-2.0-or-later */ | |||
/********************************************************************** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Start with /*!
so Doxygen properly sees it
|
||
FrameStatistics.h | ||
|
||
Dmitry Vedenko |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again /*!
and use @file
before the file name, and add at least a @brief
line about the purpose of the header.
Much more Doxygenation might be added but that much is the minimum I would like so there is some summary on pages like this one https://doxy.audacityteam.org/dir_68267d1309a1af8e8297ef4c3efbcdba.html
I'm less concerned to add @file
to .cpp files, because they are not interfaces. It's generally understood that they implement whatever the companion .h file is about.
@@ -502,6 +503,7 @@ static void QuitAudacity(bool bForce) | |||
// termination when exiting is requested | |||
#if !defined(__WXMAC__) | |||
LogWindow::Destroy(); | |||
FrameStatisticsDialog::Destroy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the FrameStatisticsDialog is a per-application non-modal dialog (not per-project)?
@@ -0,0 +1,149 @@ | |||
/* SPDX-License-Identifier: GPL-2.0-or-later */ | |||
/********************************************************************** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto doxygen
std::chrono::steady_clock::time_point mLastUpdate; | ||
}; | ||
|
||
Destroy_ptr<Dialog> sDialog; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wish to deprecate Destroy_ptr in favor of: https://docs.wxwidgets.org/3.0/classwx_window_ptr_3_01_t_01_4.html
I didn't know of that when I reinvented Destroy_ptr.
explicit operator bool() const noexcept; | ||
}; | ||
// GCC 9.3.0 fails horribly if you do not initialize variant explicitly here | ||
std::variant<LinearMapper, CustomMapper> mMapper { LinearMapper {} }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The commit that introduces this variant didn't compile for me with clang either. I fixed it for myself by initializing with one argument std::in_place_type<LinearMapper>
. I expect the build fix-ups will be squashed with interactive rebasing in a future version of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see a commit "Fixes GCC build" adding this line but followed by another that fixes Clang again.
Using in_place_type
instead is enough to fix Clang in the first commit, without including SampleCount.h.
If you are curious about why the incomlete type was a problem... I looked a bit at the error-novel for clang and I think there is a metaprogram deducing the correct alternative of the variant to initialize from the constructor arguments, which leads to the expansion of a conditional noexcept
specifier, and somehow the operator () of this type is used in an unevaluated context.
But use in_place_type
instead and that metaprogram isn't needed to resolve the overloaded constructor.
So, avoiding one more #include inside a header is nice if you can do it, plus there is in-place construction instead of a copy of a LinearMapper. Small gains.
libraries/lib-utility/MemoryX.h
Outdated
|
||
const auto result = numerator / denominator; | ||
|
||
return result * denominator == numerator ? result : result + 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://en.cppreference.com/w/cpp/language/operator_arithmetic
If the denominator is zero, there is UB not an exception, so noexcept
is strictly speaking correct.
If one value is negative and the other is not, what should happen? (Division must truncate toward zero in C++11 and later; so if this case matters, then it is already "rounded up" and adding 1 is wrong.)
If those cases aren't supposed to happen, add a doxygen @pre
that numerator is nonnegative and denominator is positive. (Precondition means "it is the caller's responsibility to exclude those cases, not mine to handle them")
Ignoring the sign question, I would simplify:
return (numerator + denominator - 1) / denominator;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch, thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your version is faster, but does not consider the possible integer overflow. I think I will just add Unsafe to the function name, though :-)
// A multiplier used to control the cache size | ||
int32_t mCacheSizeMultiplier { 4 }; | ||
|
||
template <typename CacheElementType> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get a clang build error:
GraphicsDataCache.h:213:23: error: declaration of 'CacheElementType' shadows template parameter
template <typename CacheElementType>
Easily fixed just by omitting the template parameter name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build errors are fixed in later commits. Given that I have to build on 3 different systems I will postpone force pushes to the much later times
PRIVATE | ||
lib-math-interface | ||
lib-screen-geometry-interface | ||
wxwidgets::base |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the later commit that adds more dependencies, I would simplify:
set( LIBRARIES
lib-math-interface
lib-screen-geometry-interface
PRIVATE
wxwidgets::base
)
The transitive dependency on lib-utility-interface is now implied, so the generated graph of dependencies can have one less arc. Consistently with other libraries, only the dependency on wxBase should be private. Libraries that depend on lib-graphics could themselves simplify their CMakeLists.txt by using transitive dependency on lib-math and lib-screen-geometry.
if (section < SectionID::Count) | ||
{ | ||
GetInstance().mSections[size_t(section)].AddEvent(duration); | ||
GetInstance().mUpdatePublisher.Invoke(section); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does not provide noexcept
guarantees
{ | ||
if (!mInitializer(key, *element)) | ||
{ | ||
DisposeElement(element); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No noexcept
guarantees
d2eebd6
to
b9f3eab
Compare
1d51e77
to
1b71e23
Compare
d3fe397
to
b79a6f8
Compare
There was an issue with how is selection handled, for example. And there is still lots of stuff to be fixed in that domain.
Well, that is something we will have to investigate later. Too bad I have no HDR display available |
84525c4
to
fd7e68c
Compare
On-demand blocks were removed in 3.0
Resolves: #2531
The goals of this PR are to separate waveform rendering logic into a library and to provide a base for the protentional hardware accelerated approach.
Approach to data caching
Data is cached in blocks with 256 columns each. Each block is identified by a pair of
(zoomLevel, firstSample)
. Each clip has its own set of caches.Dividing data into blocks helps to avoid unnecessary copying of data, which is expensive on the high-resolution displays. On top of that, we can have hierarchies of caches.
Recommended: