-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Improve waveform rendering performance #7366
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
Merged
Merged
Changes from all commits
Commits
Show all changes
87 commits
Select commit
Hold shift + click to select a range
5ad7845
Experimental sample thumbnail
khoidauminh 795ad7f
Rename some classes and type aliases. Make some type declarations exp…
khoidauminh 140006b
Use a combination of audioFile name and shared_ptrs to track samples;…
khoidauminh 14d1e91
That weird line at the end of the sample is now gone
khoidauminh 71284b0
Small changes to the code; Add comments
khoidauminh 4553283
Add missing word to comment; Fix typo
khoidauminh 7a6e2aa
Track `SharedSampleThumbnailList`s instead
khoidauminh f281961
Major refactor; implement thumbnailing for SlicerT, AFP and Automatio…
khoidauminh e03dacd
Code clean up, renames and documenting
khoidauminh 4a1689e
Merge branch 'LMMS:master' into sample-thumbnail
khoidauminh 82c51e0
Add the namespace lmms comments
khoidauminh 35589f9
More code updates and documentation
khoidauminh 92b9c15
Fix error in comment
khoidauminh fa24cfe
Comment out `qDebug`s
khoidauminh 101199e
Fix formatting
khoidauminh b903d9f
Use alternative initialization of `SampleThumbnailVisualizeParameters`
khoidauminh 7a393ef
Remove commented code
khoidauminh 4e39c16
Fix style and simplify code
sakertooth 9880d83
Use auto
sakertooth 69cc6ba
Draw lines using floating point
sakertooth d7f89ac
Merge the classes into one nested class
sakertooth 9605dec
Fix comparison of different signedness
sakertooth 7f3d43f
Include memory header
sakertooth 3c41384
Fix a logic error when selecting samples; Rename a const
khoidauminh 5f70d59
Fix more issues with signedness
sakertooth 4f9f353
Fix sample drawing error in `visualizeOriginal`
khoidauminh 12bc9cc
Only render regions in view of the sample
khoidauminh 0a210ee
Allow partial repaints of sample clips
khoidauminh d6a3638
Remove unused variable
khoidauminh 305baee
Limit most of the painting to the visible region
khoidauminh 9392493
Revert back to using rect() in some places
khoidauminh 4bc9dae
Partial rendering for AutomationEditor
khoidauminh 5cd947b
Don't redraw painted regions; allowHighResolution; remove `visualizeO…
khoidauminh daf45cc
Add s_sampleThumbnailCacheMap back for testing convenience
khoidauminh 2c2202f
Minor change to the way `thumbnailSizeDivisor` is calculated
khoidauminh 0317e80
Extend update region by an amount
khoidauminh bfb5367
forgot about this
khoidauminh 547e513
Merge branch 'LMMS:master' into sample-thumbnail
khoidauminh 834e861
Adapt to master; Redesign VisualizeParameters; Don't rely entirely on…
khoidauminh cfa35e6
Merge branch 'master' into sample-thumbnail
khoidauminh 0b8315c
Merge branch 'LMMS:master' into sample-thumbnail
khoidauminh 240696d
Don't try to preserve painted regions
khoidauminh b6cf4e3
Allow for a bit more thumbnails; Fix incorrect rendering when vertica…
khoidauminh ab3f0d1
Merge branch 'master' into sample-thumbnail
khoidauminh 58a98a4
Fix missing include statement
khoidauminh b9bd512
Merge branch 'master' into sample-thumbnail
khoidauminh 38cd04d
Remove the unused variable
khoidauminh 5414e34
Merge branch 'LMMS:master' into sample-thumbnail
khoidauminh 75ba820
Merge branch 'master' into sample-thumbnail
khoidauminh 186ca61
Code optimization; Remove RMS member from Bit; Rename viewRect to dra…
khoidauminh 309bc36
Merge branch 'master' into sample-thumbnail
khoidauminh 7a53536
More code optimizations
khoidauminh 5df559a
Fix formatting
sakertooth 26545b0
Use begin instead of cbegin
sakertooth f522e1a
Improve generation of thumbnails
sakertooth 55c55c8
Improve expressiveness of the draw code
sakertooth 2476ce1
Add support for reversing
sakertooth 3bc7f3b
Fix drawing code
sakertooth 2a81387
Fix draw code (part 2)
sakertooth 70a01b8
Apply more fixes and simplifications
sakertooth fea47be
Undo some out of scope changes
sakertooth ffe4915
Remove SampleWaveform
sakertooth a9f9194
Improve documentation
sakertooth 6f1becb
Use size_t for some counters
sakertooth b6eeccb
Change width parameter to be size_t
sakertooth 5a0ad5e
Remove temporary aggregated peak variable
sakertooth 3dd6217
Bump up AggregationPerZoomStep to 10
sakertooth ae44632
Zoom out only requested range of thumbnail instead of clipping it sep…
sakertooth dd5dac1
Rename targetSampleWidth to targetThumbnailWidth
sakertooth 3579edb
Handle reversing for AFP; Iterate in reverse instead of reversing the…
khoidauminh 5c9039d
Change names to be more accurate
sakertooth 7d5ba17
Improve implementation of sample thumbnail cache map
sakertooth 5378902
Move AggregationPerZoomStep back down to 2, do not cap smallest thumb…
sakertooth 5952123
Simplify sample thumbnail cache handling in constructor
sakertooth 313af1e
Call drawLines instead of drawLine in a loop
sakertooth 141a20d
Bump up AggregationPerZoomStep to 10 again
sakertooth f07897c
Fix off-by-one error when constructing Thumbnail from buffer
sakertooth 60400f1
Fix crash when viewport is not in bounds
sakertooth 57d17b6
Apply performance improvements
sakertooth c8cb378
Apply minor changes
sakertooth 745013d
Use C++20's designated initializers
sakertooth 874cbdd
Create param right before visualizing
sakertooth f8022b9
Fix regressions with reversing
sakertooth 2984f82
Fix incorrect rendering in AFP and SlicerT
khoidauminh 3c2a744
Move MaxSampleThumbnailCacheSize and AggregationPerZoomStep into impl…
sakertooth 67ccaf9
Remove static keyword
sakertooth d186e45
Remove getter and setter for peak data
sakertooth File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| /* | ||
| * SampleThumbnail.h | ||
| * | ||
| * Copyright (c) 2024 Khoi Dau <[email protected]> | ||
| * Copyright (c) 2024 Sotonye Atemie <[email protected]> | ||
| * | ||
| * This file is part of LMMS - https://lmms.io | ||
| * | ||
| * This program is free software; you can redistribute it and/or | ||
| * modify it under the terms of the GNU General Public | ||
| * License as published by the Free Software Foundation; either | ||
| * version 2 of the License, or (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public | ||
| * License along with this program (see COPYING); if not, write to the | ||
| * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
| * Boston, MA 02110-1301 USA. | ||
| * | ||
| */ | ||
|
|
||
| #ifndef LMMS_SAMPLE_THUMBNAIL_H | ||
| #define LMMS_SAMPLE_THUMBNAIL_H | ||
|
|
||
| #include <QDateTime> | ||
| #include <QPainter> | ||
| #include <QRect> | ||
| #include <memory> | ||
|
|
||
| #include "Sample.h" | ||
| #include "lmms_export.h" | ||
|
|
||
| namespace lmms { | ||
|
|
||
| /** | ||
| Allows for visualizing sample data. | ||
|
|
||
| On construction, thumbnails will be generated | ||
| at logarathmic intervals of downsampling. Those cached thumbnails will then be further downsampled on the fly and | ||
| transformed in various ways to create the desired waveform. | ||
|
|
||
| Given that we are dealing with far less data to generate | ||
| the visualization however (i.e., we are not reading from original sample data when drawing), this provides a | ||
| significant performance boost that wouldn't be possible otherwise. | ||
| */ | ||
| class LMMS_EXPORT SampleThumbnail | ||
| { | ||
| public: | ||
| struct VisualizeParameters | ||
| { | ||
| QRect sampleRect; //!< A rectangle that covers the entire range of samples. | ||
|
|
||
| QRect drawRect; //!< Specifies the location in `sampleRect` where the waveform will be drawn. Equals | ||
| //!< `sampleRect` when null. | ||
|
|
||
| QRect viewportRect; //!< Clips `drawRect`. Equals `drawRect` when null. | ||
|
|
||
| float amplification = 1.0f; //!< The amount of amplification to apply to the waveform. | ||
|
|
||
| float sampleStart = 0.0f; //!< Where the sample begins for drawing. | ||
|
|
||
| float sampleEnd = 1.0f; //!< Where the sample ends for drawing. | ||
|
|
||
| bool reversed = false; //!< Determines if the waveform is drawn in reverse or not. | ||
| }; | ||
|
|
||
| SampleThumbnail() = default; | ||
| SampleThumbnail(const Sample& sample); | ||
| void visualize(VisualizeParameters parameters, QPainter& painter) const; | ||
|
|
||
| private: | ||
| class Thumbnail | ||
| { | ||
| public: | ||
| struct Peak | ||
| { | ||
| Peak() = default; | ||
|
|
||
| Peak(float min, float max) | ||
| : min(min) | ||
| , max(max) | ||
| { | ||
| } | ||
|
|
||
| Peak(const SampleFrame& frame) | ||
| : min(std::min(frame.left(), frame.right())) | ||
| , max(std::max(frame.left(), frame.right())) | ||
| { | ||
| } | ||
|
|
||
| Peak operator+(const Peak& other) const { return Peak(std::min(min, other.min), std::max(max, other.max)); } | ||
| Peak operator+(const SampleFrame& frame) const { return *this + Peak{frame}; } | ||
|
|
||
| float min = std::numeric_limits<float>::max(); | ||
| float max = std::numeric_limits<float>::min(); | ||
| }; | ||
|
|
||
| Thumbnail() = default; | ||
| Thumbnail(std::vector<Peak> peaks, double samplesPerPeak); | ||
| Thumbnail(const float* buffer, size_t size, size_t width); | ||
|
|
||
| Thumbnail zoomOut(float factor) const; | ||
|
|
||
| Peak& operator[](size_t index) { return m_peaks[index]; } | ||
| const Peak& operator[](size_t index) const { return m_peaks[index]; } | ||
|
|
||
| int width() const { return m_peaks.size(); } | ||
| double samplesPerPeak() const { return m_samplesPerPeak; } | ||
|
|
||
| private: | ||
| std::vector<Peak> m_peaks; | ||
| double m_samplesPerPeak = 0.0; | ||
| }; | ||
|
|
||
| struct SampleThumbnailEntry | ||
| { | ||
| QString filePath; | ||
| QDateTime lastModified; | ||
|
|
||
| friend bool operator==(const SampleThumbnailEntry& first, const SampleThumbnailEntry& second) | ||
| { | ||
| return first.filePath == second.filePath && first.lastModified == second.lastModified; | ||
| } | ||
| }; | ||
|
|
||
| struct Hash | ||
| { | ||
| std::size_t operator()(const SampleThumbnailEntry& entry) const noexcept { return qHash(entry.filePath); } | ||
| }; | ||
|
|
||
| using ThumbnailCache = std::vector<Thumbnail>; | ||
| std::shared_ptr<ThumbnailCache> m_thumbnailCache = std::make_shared<ThumbnailCache>(); | ||
|
|
||
| inline static std::unordered_map<SampleThumbnailEntry, std::shared_ptr<ThumbnailCache>, Hash> s_sampleThumbnailCacheMap; | ||
sakertooth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| } // namespace lmms | ||
|
|
||
| #endif // LMMS_SAMPLE_THUMBNAIL_H | ||
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.