-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Add cache for SampleBuffer
#6703
Conversation
Test result on windows 10/64b, both mscv and mingw, loading a wav file into sample track (values are approximate)
On the other hand, reloading the file is practically immediate on the PR. This can be positive if intended or negative if memory is not released when deleting a sample clip. |
Yeah, the initial load of the samples should be similar to master, but subsequent loads of the same sample should be faster since it is likely to be in the cache. |
Then is working perfectly! |
Having an LRU cache was mostly a premature idea I had in mind. What I plan to do now is store the samples in an unbounded cache, and allowing the end user to manage the samples loaded into the project. Deleting a sample from the cache would then require it to be loaded from disk, and loading a sample already in the cache will be fast because it's already in memory. |
Hi @sakertooth, if you manage all samples/audio regions in one place you should also consider to watch each of them using QFileSystemWatcher and reload them on a change. This way users could adjust the audio data in other applications and have the updated data directly available in LMMS. Classes which use that data will of course have to be aware that changes might occur, e.g. that an audio file might become shorter, and behave accordingly. I think most DAWs, e.g. REAPER and Ardour, define regions (audio and MIDI) that can be placed along the project. These regions then only reference the data so that one audio file can then potentially be used by several regions. Changing the audio file, e.g. outside of the DAW, will result in all regions that reference it using the changed data. If I understand correctly LMMS makes use of virtual memory because it loads audio data directly into memory. This way the operating system will take care of memory blocks (pages) that have not been used for a while by swapping them out. One could also consider to implement some more direct form of memory management which also does not immediately load all the data into memory. I am not really an expert on that topic but I can imagine that memory mapped files would be loaded lazily into memory as the blocks are accessed. |
Wouldn't this be considered a downside? If the user were to load a file and it was in the sample cache, and then move that same file into another directory, why should the DAW also move/remove the sample? I tested this behavior in other DAWs like FL, and it doesn't respond to file path changes at all. In FL, once you load a file from disk, it stays there. Deleting it from disk after the fact doesn't change anything about what FL previously loaded. And if the same sample was now in another directory and then loaded in, it would just be considered a new file altogether. Unless you mean like a Refresh button of some kind, then that should be okay. However, I don't think this behavior should be automatic. |
My remark was not about the detection of removed/moved files but about the detection of changes within the files. The scenario is that a user keeps a file where it is but edits its content with an external audio editor. The basic premise is that an audio editor has more powerful tools to manipulate audio than a DAW. In REAPER I can change audio files with external editors and the changes are reflected immediately in the DAW. If a file is moved REAPER will show that the file is not available anymore. I think it all boils down to how LMMS organizes/wants to organize large sets of audio data. If you want to keep the data safe in cases where the source file is moved to another location then this also implies that you either have to write a new file to a known location when the project is saved or you will have to include the audio data in the save file itself. The latter might not be a good idea with audio heavy projects and with regards to performance. The latter question would also become relevant if audio recording is ever implemented in LMMS. |
Any progress on this ? |
I plan to continue with this PR soon. |
979f0d0
to
b731ee9
Compare
ede89b6
to
e8249d7
Compare
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.
Looks pretty good except for a few things
Good feature but I am having a few questions. Where are the sample caches getting stored? In the disk or in memory? Also, does this reduce duplication of samples? |
The buffers are cached in memory. Storing them on disk doesn't help at all because the file that we intend to cache after it has been loaded is on disk. This act of just caching the results after we loaded the sample only helps with speeding up loading said sample into the project. Any memory saving improvements are only made possible because of the kind of data we are caching. We are caching What is really wanted is the sharing of these buffers. This cache only speeds up data retrieval by itself, but there are added RAM improvements only because of what we are caching and how anybody that needs a sample (think AFP, sample tracks, etc) can have some global place to go and get it if it's already been loaded. This distinction I feel like hasn't been made and is now confusing this PR up by a lot. |
That being said, I have to go and fix this PR up. |
ecf1620
to
56e7f7d
Compare
Effectively unit testing this class without a file system dependency doesn't seem useful/possible.
This mimics the old behavior of the SampleLoader::create* functions. The error handling should be improved in a future PR, so that empty buffers don't signify failure.
Closing in favor of #7058. |
This PR adds a cache for the
SampleBuffer
class, giving us two main benefits:Entries are automatically added to a
QFileSystemWatcher
once added to the cache, and when a file changes, it will evict it from the cache.