Skip to content

Conversation

@szeli1
Copy link
Contributor

@szeli1 szeli1 commented Oct 9, 2024

closes #7452

This pull request aims to add a way and a place to store sample files for projects.

A new class is added called SampleFolder. It will store audio files in 2 ways: relative (Project Folder) and absolute (inside a folder that can store all audio files for multiple projects).

All sample loading and saving should be routed through SampleFolder. SampleFolder class will require 3 new folders for each project. A project folder and a "Used" and a "Unused" folder placed inside it. There will be an option to save the project inside a project folder in the main window menus. If the project file is inside a folder with the same name, SampleFolder will interpret it as a project folder. If this condition isn't true, a new global "everything" folder will be used as the current project folder. SampleFolder will scan for ".flac" samples inside ProjectFolder, ProjectFolder/Used and ProjectFolder/Unused and will load them if something is requesting a shared_ptr<SampleBuffer>. The "Used" and the "Unused" folder makes managing files for the users easy, If they wants to delete the unused files, they easily can.

A new class is added for exporting samples outside of the AudioEngine. This class is named LmmsExporterSample, this name isn't the best, so any better suggestion is appreciated! This class exports any SampleBuffer in a new thread as a ".flac" file.

How to test:

  1. Open a new project and start saving it. You should see an option called "Save project inside sample folder" in the save dialog. Make sure that option is on when saving. Once saved, a folder should appear in the selected location that contains the project file, and 2 other folders called "Used" and "Unused". Load a sample inside a sample clip. Open the context menu and click the new "save to sample folder" option. This should reexport the loaded sample to the "Used" folder. Save the project and reload lmms and reopen the project. The sample should be loaded as if nothing happened (to how the samples are handled). Delete the sample clip and save the project. The exported sample should have moved to the "Unused" folder.
  2. Open a new project. Load a sample inside a sample clip and open the context menu and click the "save to sample folder" option. The sample should be reexported to a new folder inside lmms/ (where the plugins folder is), this folder is called "lmms_recorded_samples" (should be renamed in my opinion). Save the project without the sample folder option and reload the project. The sample should be loaded in correctly.

this allows #5990 to be finished

@szeli1 szeli1 marked this pull request as draft October 9, 2024 21:37
@szeli1
Copy link
Contributor Author

szeli1 commented Oct 26, 2024

I'm no longer working on this feature.

@szeli1 szeli1 closed this Oct 26, 2024
@szeli1 szeli1 reopened this Dec 8, 2024
@sakertooth
Copy link
Contributor

This pull request aims to add a way and a place to store sample files for projects.

This has been brought up many times, but why are you convinced that hundreds of lines of code are necessary to add a way and a place to store sample files for projects?

@szeli1
Copy link
Contributor Author

szeli1 commented Dec 17, 2024

This has been brought up many times, but why are you convinced that hundreds of lines of code are necessary to add a way and a place to store sample files for projects?

I wouldn't say that I'm convinced or if this is the best way to do this. This PR has secondary goals that include:

  1. Option to store samples locally near the project file
  2. Option to store samples globally inside a designated path
  3. Better sample management (keeping track of all used and unused samples)
  4. Utility (unique name generation and keeping a list of available samples)
  5. Ability to rewrite this class to use UUIDs
  6. Ability for this class to manage all file name related tasks (so other classes don't have to store paths to samples in the future)

I believe these goals have been agreed to in a discussion about this feature by multiple users. There was an other discussion about this feature also. I believe you didn't object to these goals when those discussions happened.

I tried to follow most of these guidelines and I tried to implement most of these features. Some features have been left out (like the ability to export samples that are still being recorded, so in case of a crash the sample isn't lost)

I hope this comment clarifies the larger than expected code amount. If not, feel free to ask more questions!

@sakertooth
Copy link
Contributor

I wouldn't say that I'm convinced or if this is the best way to do this.

If you are not convinced that your work is necessary or a satisfactory solution to a problem, then this shows uncertainty. I applaud your effort, but if you are uncertain about it then I am too.

This PR has secondary goals that include:

A good practice for PRs is to keep them small and focused. It helps with reviewing them, minimizes regressions, and allows the team to have a better grasp of the PR and be more confident with knowing how and why the changes were made. However, it seems as if you have coupled many somewhat related things, and as a consequence the PR lacks direction. At the end of the day, the PR is still trying to do many things all at once. Stick to doing one thing please :)

I believe these goals have been agreed to in a discussion about this feature by multiple users. There was an other discussion about this feature also. I believe you didn't object to these goals when those discussions happened.

I have read the goals you have listed, and I get the feeling the goals we mentioned in our discussions are different than what you had in mind. This isn't your fault really, we definitely need to get better at specifying what exactly we want to do for the project and what our overall direction is. We did this very nicely with working towards the 1.3 release, but a lot of the secondary goals, especially relating to sample functionality and sample workflow, could be better explained clearly somewhere, and not just in discussions floating on Discord.

This "specifying of goals" is a team effort: no one developer can make all the decisions here. As small as the team size is, working on a project like this and making goals for it requires everyone to be considered. The community and developers alike.

I tried to follow most of these guidelines and I tried to implement most of these features.

I understand, but from my perspective, you are biting more than you can chew. I was like this once: I wanted to fix everything, rewrite the whole project, start from scratch. I still feel that way at times. However, I realized that it probably isn't as simple as that. A better, safer alternative is to take it one step at a time.

@szeli1
Copy link
Contributor Author

szeli1 commented Dec 17, 2024

If you are not convinced that your work is necessary or a satisfactory solution to a problem, then this shows uncertainty. I applaud your effort, but if you are uncertain about it then I am too.

Please ignore my feelings about this PR, it will lead nowhere

A good practice for PRs is to keep them small and focused.

My issue is that I can't build on unmerged features. My FFT filter effect is still on hold because it is waiting for #7158. Other developers have advised me to merge features into 1 pull request rather than to make multiple smaller ones because it will be approved faster that way. I believe only 1 of my features were merged after 1 year of work.

PR is still trying to do many things all at once

I would rather not change this with this PR, but I will keep this in mind in the future. I think this PR accomplishes the goals I believe were set.

it seems as if you have coupled many somewhat related things, and as a consequence the PR lacks direction

What direction should this PR aim for? I aim to completely implement and finish the folder component of "Sample folder" and exporting outside of AudioEngine. The UUID system will replace about half of the sample related functions inside SampleFolder, so I aim to enable this change to be as simple as possible.

This "specifying of goals" is a team effort: no one developer can make all the decisions here. As small as the team size is, working on a project like this and making goals for it requires everyone to be considered. The community and developers alike.

I agree with this. I usually feel unguided regarding the development direction. I usually try to communicate my ideas and sometimes nobody responds (this happened to the 1. discussion about this feature, where completely different goals were set). Edit: maybe I should take part in other discussions related to this project, so I can be a better contributor and take part in this team effort

you are biting more than you can chew

What do you mean by this in the scope of this PR? Could you explain it with some examples? What are you afraid of (or what feeling leads you to this conclusion)?

@sakertooth
Copy link
Contributor

Please ignore my feelings about this PR, it will lead nowhere

Sorry, but I refuse your request. You feel uncertain, and as such, I am uncertain. As a result of this, the conversation will amount to nothing, and not because the feelings about the PR are being ignored.

@szeli1
Copy link
Contributor Author

szeli1 commented Dec 17, 2024

Sorry, but I refuse your request. You feel uncertain, and as such, I am uncertain. As a result of this, the conversation will amount to nothing, and not because the feelings about the PR are being ignored.

How should one feel about a pull request? I don't feel certain. I don't feel uncertain. This is why I would rather avoid talking about this. I would like to focus on the facts, that sample track recording stage 1 needs audio exporting, an other fact is the code that accomplishes this (exists).

@sakertooth
Copy link
Contributor

I agree with this. I usually feel unguided regarding the development direction. I usually try to communicate my ideas and sometimes nobody responds (this happened to the 1. discussion about this feature, where completely different goals were set). Edit: maybe I should take part in other discussions related to this project, so I can be a better contributor and take part in this team effort

That's normal, you're not doing anything wrong. Partaking in the discussions is fine, but even for people that aren't in the Discord but still contribute here (michaelgregorius comes to mind), we still need to improve how we specify our goals for the project.

@sakertooth
Copy link
Contributor

I don't feel certain.

But you mentioned you were not convinced that your work was appropriate for the problems you were trying to solve?

@szeli1
Copy link
Contributor Author

szeli1 commented Dec 17, 2024

But you mentioned you were not convinced that your work was appropriate for the problems you were trying to solve?

Yes, because this PR will change as reviews are done. I said this: "I wouldn't say that I'm convinced or if this is the best way to do this." I think if more experienced developers review this pull request, they might find issues that need to be fixed.

@sakertooth
Copy link
Contributor

Yes, because this PR will change as reviews are done. I said this: "I wouldn't say that I'm convinced or if this is the best way to do this." I think if more experienced developers review this pull request, they might find issues that need to be fixed.

That's fair. However, my opinion is that the PR just doesn't seem really focused. It accomplishes too many things all at once and it is really hard to understand if the PR has validity (validity, meaning if the PR is logically sound in its reasoning and consists of changes we need). Put simply, I do not understand what the PR does exactly. There's not a single, clear defined goal that I can gather unfortunately, but many slightly vague goals which lack direction and clarity in my opinion.

I also mentioned before that I personally think the problem you are trying to solve, "to add a way and a place to store sample files for projects." has a far simpler solution. The way we create a place for users to store sample files is by giving them an option to specify a path to put sample files in. That's it. I don't really want to go into anything about this, because I really do think it is, in its simplest form, that rudimentary.

Choosing just one of those things to start off would be a good start, even though there are maybe other developers possibly working on that same problem. However, having just one singular idea makes it so much easier to understand the PR and your vision as the author.

@szeli1
Copy link
Contributor Author

szeli1 commented Dec 17, 2024

I also mentioned before that I personally think the problem you are trying to solve, "to add a way and a place to store sample files for projects." has a far simpler solution. The way we create a place for users to store sample files is by giving them an option to specify a path to put sample files in. That's it. I don't really want to go into anything about this, because I really do think it is, in its simplest form, that rudimentary.

You are right, it is simpler for that specific problem. I'm starting to understand your point about making more specific and clear Pull Requests. I guess I will make a new PR that includes the exporter and what you've described above.

Thanks for taking the time to get to this point with one of the contributors.

I still don't know what will happen to this PR once an other one exists with the same export code, I guess then I will rebase this branch.

@szeli1 szeli1 marked this pull request as ready for review December 19, 2024 20:00
@michaelgregorius
Copy link
Contributor

I agree with this. I usually feel unguided regarding the development direction. I usually try to communicate my ideas and sometimes nobody responds (this happened to the 1. discussion about this feature, where completely different goals were set). Edit: maybe I should take part in other discussions related to this project, so I can be a better contributor and take part in this team effort

That's normal, you're not doing anything wrong. Partaking in the discussions is fine, but even for people that aren't in the Discord but still contribute here (michaelgregorius comes to mind), we still need to improve how we specify our goals for the project.

As development is taking place here on GitHub to me it would be a logical step to also make the goals of the project transparent on GitHub so that people can contribute in a meaningful way even if they are not on the Discord.

My personal impression is that the project is lacking leadership, e.g. someone like Ton Roosendaal for Blender or Guido van Rossum for Python. However, it might only be my impression because I am not on Discord and therefore things are not transparent to me.

My personal goal is to help push LMMS more towards a "professional" direction and to make it more on par with other DAWs (see for example my PR for faders with a dB scale). If you compare LMMS to other DAWs you will find that it is lacking quite a lot. However, my time is sparse so unfortunately I cannot help with the real big tasks that would be necessary to do so (real-time safety, audio graph with latency compensation, more sophisticated features for audio drivers, e.g. multiple inputs and outputs, etc.). That's also the reason why I do not want to get too involved, e.g. via Discord.

I guess it might make sense to discuss this in a discussion thread which I might create.

@michaelgregorius
Copy link
Contributor

I have created the following discussion to not derail this PR: #7642.

Copy link
Member

@messmerd messmerd left a comment

Choose a reason for hiding this comment

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

Not a thorough review, but just a few things that stood out

Comment on lines +48 to +49
//! outputLocationAndName: should include path and name, could include ".flac"
void startExporting(const QString& outputLocationAndName, std::shared_ptr<const SampleBuffer> buffer);
Copy link
Member

Choose a reason for hiding this comment

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

Given how you use it, const std::filesystem::path& might be a better option for the type. And the name "outputLocationAndName" is very clunky, so you could shorten it to "output" or something. If it's a std::filesystem::path type, it'll be obvious that "output" is a file output path.

{
stopExporting();
m_isThreadRunning = true;
m_thread = new std::thread(&LmmsExporterSample::threadedExportFunction, this, &m_abortExport);
Copy link
Member

Choose a reason for hiding this comment

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

If you just need a null state, why not use std::optional<std::thread>?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I need a new thread. The thread is used until every job is finished, then it is joined.

}


void LmmsExporterSample::threadedExportFunction(LmmsExporterSample* thisExporter, volatile bool* abortExport)
Copy link
Member

Choose a reason for hiding this comment

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

Using volatile for cancellation makes me feel a bit uneasy. Maybe @sakertooth could weigh in here, since he's fairly knowledgeable about multi-threading.

Copy link
Contributor

@sakertooth sakertooth Jun 18, 2025

Choose a reason for hiding this comment

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

I basically never use volatile, and we could probably just use std::atomic_flag or even std::atomic<bool>.

Other thoughts:

  1. We should be using the ThreadPool class here to submit the export as a task to one of the threads.
  2. I believe you could just make this a member function, enqueued into the ThreadPool with a lambda
  3. threadExportFunction is kind of an odd name, runExport or something along those lines would be better and simpler IMO.


private:
Sample m_sample;
QString m_sampleFile;
Copy link
Member

Choose a reason for hiding this comment

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

This seems redundant since m_sample should already store the file path.


class Engine;

const QString COMMON_SAMPLE_FOLDER = "lmms_recorded_samples/";
Copy link
Member

Choose a reason for hiding this comment

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

Why "lmms_recorded_samples"? Isn't this meant to be in the "LMMS" folder alongside "projects/", "presets/", etc?

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreeing, LMMS is clear from the parent directory. Also, most Linux systems seem to prefer minuses over underscores:

$ ls -la /usr/share | grep -c _
9
$ ls -la /usr/share | grep -c -
340

thisExporter->m_isThreadRunning = false;
}

bool LmmsExporterSample::openFile(const QString& outputLocationAndName, std::shared_ptr<const SampleBuffer> buffer)
Copy link
Member

Choose a reason for hiding this comment

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

It seems like you're trying to reinvent the wheel here. SampleDecoder should be capable of reading .flac files.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is opening a file to export to.

@szeli1 szeli1 marked this pull request as draft June 18, 2025 20:15
@allejok96
Copy link
Contributor

After discussing this on Discord I found it best to gather all my thoughts here.

I agree with @sakertooth that this PR lacks a clear direction. Let's zoom out and talk about the problem this PR is actually trying to solve: we need a place to save recordings.

1. Store samples locally near the project file

I'm a fan of this idea. We already have a feature called "project bundle", that can be found in the save as dialog. I think that feature should be extended to handle recordings too. There is no reason to write a whole separate system for that.

2. Where do we place recordings if the user doesn't care?

You opted to place them in a global sample folder. I think this is a really, really bad idea.

Scenario: a user has been using the recording feature for some months and now there's 300+ samples in the global sample directory. This has become unbearable to the user and they want to organize it a bit better. But there's no way to do that now without breaking all projects.

Solution: just store everything close to the project by default, and there is no risk of clutter even if the user doesn't care how they save the project.

3. What if the user WANTED to share a sample between projects?

Easy. Let the user save it in the samples folder, like they can do today.

4. How do we keep track of which samples are used and not?

If a sample is stored together with the project, it's because it's used by that project. No need to track it. If a sample is in the samples folder, it's because the user put it there. They may organize it however they like. Let them keep track of it.

5. But what will happen to unused samples?

IMO if a sample is saved (by LMMS) to a project-local directory, and the clip is deleted from the project, it should be deleted from the file system too. Like @JohannesLorenz pointed out on Discord we don't keep deleted melody patterns or deleted instruments, why should we keep deleted samples?

6. "Deleting sound files off of users computers is a bad idea"

Scenario: a user records a sample in project A, then creates a new project B and opens the sample file from a project A's sample directory, then goes back to project A and deletes the sample clip... If LMMS deletes sound files from the filesystem it would break project B!

Solution: If deleting sound files is a bad idea, then don't use sound files. I mean save them as FLAC, but call them something like sample01.flac.data. That would prevent them being used as a normal sample, but it's still clear to a user doing some kind of recovery that this is a FLAC file. If the user wanted to use a sample in another project they would be forced to save it to their directory of choice from within LMMS, thus taking responsibility over how and when it is deleted.


I admit that point 5 and 6 is more related to the recording PR than this, but I think they are relevant to the problems this PR is trying to solve. You have put down a lot of good work here @szeli1 and I don't mean to ruin that. Even if you are eager to merge this, you are probably more eager to get going with the recording, and if we can get there using a simpler solution and the systems we already have in place, it will probably get done faster.

@szeli1
Copy link
Contributor Author

szeli1 commented Jun 25, 2025

I admit that point 5 and 6 is more related to the recording PR than this, but I think they are relevant to the problems this PR is trying to solve. You have put down a lot of good work here @szeli1 and I don't mean to ruin that. Even if you are eager to merge this, you are probably more eager to get going with the recording, and if we can get there using a simpler solution and the systems we already have in place, it will probably get done faster.

I don't want to merge this in the near future. It was voted to use #7627 for the time being.

You opted to place them in a global sample folder. I think this is a really, really bad idea.

Your argument builds upon this idea, to not use global sample folder.

I'm a fan of this idea. We already have a feature called "project bundle", that can be found in the save as dialog. I think that feature should be extended to handle recordings too. There is no reason to write a whole separate system for that.

If we are going with your idea, then this makes sense. If global sample folder is implemented along with project folders, better to use the same code for both if possible.

Scenario: a user has been using the recording feature for some months and now there's 300+ samples in the global sample directory. This has become unbearable to the user and they want to organize it a bit better. But there's no way to do that now without breaking all projects.

Save the project as a bundle / project folder. Name recordings project name + number + .flac
It was suggested for me to implement global sample folder. You can argue that only small amount of people would like to use global sample folders, this argument should be backed up with a poll.

we don't keep deleted melody patterns or deleted instruments

I tested project bundles and deleted sounds were not removed from a bundled project's folder. Newly imported sounds also weren't added to the project bundle. I see why would you like to use project bundle, but improvements are ought to be made to use it as a project folder. Thinking about it, I may be okay with the user explicitly telling lmms to delete the currently unused files. I still think the files that leave lmms's project file must be managed by the user. Using extensions like sample01.flac.data is not user friendly, why limit users instead of limiting lmms to not delete things?

I appreciate your comment @allejok96 even if it doesn't seem like it.

@allejok96
Copy link
Contributor

It was suggested for me to implement global sample folder

Fair enough. If we are going for a global sample folder, I agree we must have a management system. I still dislike it, but there is no point in discussing that since the idea is not yours. We need to find the people who wanted this and ask what their motivations were. Maybe they just want samples to be saved without having to select a location. Or maybe they want to easily share all samples from one project to another. There are simpler solutions for both cases. Just because they suggested a global sample folder doesn't mean they understand the implications or thought of alternative solutions.

@michaelgregorius
Copy link
Contributor

IMO a management system would be needed anyway.

First of all, the DAWs that I know (Reaper, Bitwig) provide functionality to save a project in such a way so that all samples that are referenced by the project and that come from outside of the project are saved close to the project. In Bitwig this is a menu option which is called something like "Collect and save..." (in German it's "Sammeln und sichern...").

Every time that LMMS deletes a sample this should be a result of an explicit user interaction. This might be implemented with a dialog which lists the samples which are used/referenced by the project. User can then for example select entries and delete them. It would also be helpful if such a dialog would indicated samples as "project samples", i.e. samples that are saved close to the project, and "external samples".

For external samples it is highly likely that they come from sample collections that users have collected over time. LMMS must not delete any samples from these locations without explicit user interactions. Imagine building such a library and using some drum samples that you like in a project. You then delete the sample clip from the project and only realize later in another project that LMMS has deleted it from you personal collection. I am pretty sure users would quickly stop using LMMS if it behaved like this. So do not delete any files without explicit user interactions!

Also do not delete sample files if a sample clip is deleted, even if it is stored close to the project. Users might want to go through the following scenario:

  • Record a sample clip.
  • Delete the sample clip.
  • Import the recorded sample clip later at another place.

I would not be happy if I recorded a sample clip only to find that it was delete because I removed a clip which should simply be a reference to the sample like in most other DAW software.

Most DAWs treat MIDI and samples differently, so the argument "we don't keep deleted melody patterns or deleted instruments, why should we keep deleted samples" does not work for me.

Also please do not invent things like sample01.flac.data. It will be a FLAC anyway, i.e. file sample01.flac.data will show it as FLAC due to the magic marker at the beginning of the file. LMMS should simply reference audio files that it can handle, be it WAV, FLAC, MP3 or whatever, in sample clips. The management of these references is a completely different problem.

It's always helpful to check how other DAWs solve these problems before inventing own things which might work worse than in the other applications.

@allejok96
Copy link
Contributor

allejok96 commented Jun 27, 2025

Thanks for the good insight in how other DAWs handle it @michaelgregorius ! So if you record a sound in reaper, save the project, delete the sound and re-save the project, the sound is still saved somewhere?

Import the recorded sample clip in another place.

This is only a problem as soon as we save the recording in a format and location that the user can easily access. From that point we can never delete the file. Or even suggest it is unused. Because no management system can know what the user does when LMMS is closed.

Where does Thunderbird save the email attachments when you receive an email? Idk. Somewhere in the application folder. If I want to use the attachment in another program I right click and save it. No one complains about that being a restriction. But if I delete the email I assume the attachment isn't left wasting space on my hard drive. Why should recorded sounds within a project be so different?


Sorry, I didn't want to start the whole deletion discussion on this PR... Please redirect to the appropriate place.

@michaelgregorius
Copy link
Contributor

Thanks for the good insight in how other DAWs handle it @michaelgregorius ! So if you record a sound in reaper, save the project, delete the sound and re-save the project, the sound is still saved somewhere?

Yes, that correct. There might be different possible configurations in REAPER. IIRC the default is to have one global folder where recorded sound files are stored. REAPER has a dialog that shows the content of that location and it can be used to manage/delete these files.

What's important to understand is that audio clips/regions are only references to files. To a certain degree they are not representations of the files themselves. So if I drag and drop the same file three times to different tracks in REAPER then it will create three audio clips/regions which will all reference the same file. If I change the content of that file outside of REAPER then the content of these regions will change as well. If I delete one of these clips then the file will still exist and the other two clips can still reference it. So the users do not delete files and their data but clips which only reference the files.

Import the recorded sample clip in another place.

This is only a problem as soon as we save the recording in a format and location that the user can easily access. From that point we can never delete the file. Or even suggest it is unused. Because no management system can know what the user does when LMMS is closed.

That's correct. But why shouldn't user be allowed to easily access their files? Perhaps they want to edit one or more files with a audio editor. Why should this be made hard for them?

The fact that no one knows what the user wants to do when LMMS is closed is also a good argument to not delete files without explicit user interactions.

All that LMMS can do is provide some good management tools which in part make use of LMMS internal knowledge. LMMS can for example know all audio files that are referenced in a project. It can know if they are saved in the project folder (or any other folder managed by LMMS) or if they are saved in external folders.

Where does Thunderbird save the email attachments when you receive an email? Idk. Somewhere in the application folder. If I want to use the attachment in another program I right click and save it. No one complains about that being a restriction. But if I delete the email I assume the attachment isn't left wasting space on my hard drive. Why should recorded sounds within a project be so different?

One thing to notice is that Thunderbird treats your mails and attachments very responsibly. I do not use Thunderbird but I assume that it also uses the concept of a trash can into which deleted items are moved before they can be deleted for good. Every final deletion, be it the full mail or only the attachment, is a conscious user interaction. If you bypass the thrash can you will likely need to use a special key combination which again is a conscious decision by the users.

Last but not least email software and audio software solve different problems so they cannot be easily compared.

Sorry, I didn't want to start the whole deletion discussion on this PR... Please redirect to the appropriate place.

I guess it should be a discussion in the discussion area.

@szeli1
Copy link
Contributor Author

szeli1 commented Jun 28, 2025

Because no management system can know what the user does when LMMS is closed.

The user is the management system. Display a dialog that lists unused samples (in the project folder) and the user can decide if they would like to keep or delete them. It would be nice if deleted samples would be sent to the "trash" and not immediately deleted.

@JohannesLorenz
Copy link
Contributor

After asking szeli that they are OK with continuing thread abuse to talk about sample deletion ... 😰

Imagine building such a library and using some drum samples that you like in a project. You then delete the sample clip from the project and only realize later in another project that LMMS has deleted it from you personal collection. I am pretty sure users would quickly stop using LMMS if it behaved like this. So do not delete any files without explicit user interactions!

The use case you mention here could simply be solved by letting LMMS parse all LMMS projects in the project folder and check if any of them references that sample. Which I would indeed prefer over any kind of management system. However, even if no project references the sample, it might sound a bit dangerous to delete it - the user may still want to keep it for later use. So I would rather say, let us implement a dialogue which can be opened from the settings, which lists all unused samples (not used by any of the LMMS projects) and allows you to delete them.

That being said, I see no reason to store the samples "close to the project" - This should IMO exactly be done if the user saves the project "with resources".

It would be nice if deleted samples would be sent to the "trash" and not immediately deleted.

We could do that, though I don't see much advantage, given my approach above. 1 Folder is easier to handle than 2 folders. Otherwise, users always need to check 2 folders when searching for a specific sample.

@michaelgregorius
Copy link
Contributor

Imagine building such a library and using some drum samples that you like in a project. You then delete the sample clip from the project and only realize later in another project that LMMS has deleted it from you personal collection. I am pretty sure users would quickly stop using LMMS if it behaved like this. So do not delete any files without explicit user interactions!

The use case you mention here could simply be solved by letting LMMS parse all LMMS projects in the project folder and check if any of them references that sample. Which I would indeed prefer over any kind of management system. However, even if no project references the sample, it might sound a bit dangerous to delete it - the user may still want to keep it for later use. So I would rather say, let us implement a dialogue which can be opened from the settings, which lists all unused samples (not used by any of the LMMS projects) and allows you to delete them.

IMO this opens just another can of worms. Some thoughts:

  • The same way that samples can be distributed all over the place so can LMMS projects. I don't think LMMS can have an overview of all the LMMS projects on the users computer which might use a sample.
  • Even if LMMS was able to do the above then users might still use other DAWs which reference the samples.

Therefore I'd propose to implement the dialog for the currently opened dialog as a first step and then to see if it can be improved. I guess that might already provide some challenges:

  • Is there already a place which manages all the samples used by sample clips.
  • What about samples that are used in plugins like AFP, SlicerT, etc.? Do they reference samples as well or do they store the buffers, i.e. do they use copies?
  • Removing a sample via the dialog would also have to remove all sample clips which reference them.

That being said, I see no reason to store the samples "close to the project" - This should IMO exactly be done if the user saves the project "with resources".

What does "with resources" mean? That they are stored as individual files "close to the project"? That they are embedded in the project as base64 or similar.

For the recording feature it would be best if the samples were stored as individual files on disk so that users can edit them with external editors.

It would be nice if deleted samples would be sent to the "trash" and not immediately deleted.

We could do that, though I don't see much advantage, given my approach above. 1 Folder is easier to handle than 2 folders. Otherwise, users always need to check 2 folders when searching for a specific sample.

The trash is simply an additional security mechanism which the operating system provides. I do not intend it to be another folder where users store their samples and search them all the time. 😅 I am not sure how easy it is to implement with Qt though.

@allejok96
Copy link
Contributor

allejok96 commented Jun 30, 2025

The problems with this discussion

  1. We are mixing up discussing end user experience and backend implementation

  2. We are assuming that there must only be one solution and shoehorning features into it

Let's instead identify features that an end user might want, and then how they might be designed.

Features people want

  1. Sharing samples in a sample library

Right click > Add to library. This would save the sample in the global sample dir for easy access and sharing.

  1. Editing of samples in another program

Right click > Open in another program. This is a common feature. Where the file is saved is irrelevant for this feature.

  1. Deletion of unused samples

If a sample is recorded and then deleted AND if the user does not intend to use it in any other project or software, it should be deleted from disk to not waste disk space.

The user shouldn't need to regularly check for and delete unused samples, like we are back in the days of CCleaner.

  1. Automatic saving of recordings

Don't require the user to enter a file name for each sample when saving the project.

Question relevant to this PR

Do we need to make all recorded samples easily accessible by default?

I propose we have a hidden sample storage and a public sample storage.

  1. With features 1 and 2 getting access to the files, if you wanted, would be easy.

  2. Trying to find an automatically named and numbered sample file when there are many samples in a project is not easy. Providing easy access to a directory of such files wouldn't be user friendly. There are better ways to find the sample you want.

  3. Having a public and a hidden storage of samples enables us to do easy auto deletion since we know which samples can be safely deleted and which the user wants to save. No complicated tracking system.


Lastly...

I see no reason to store the samples "close to the project"

I thought it might be nice because it makes it easy to track which projects use the most disk space. But there might be other strong reasons why that is a bad idea.


Forgive me for this wall of text. I hope by now I managed to communicate my thoughts. I will not make further comments.

@szeli1
Copy link
Contributor Author

szeli1 commented Jun 30, 2025

Sharing samples in a sample library

They didn't really say that they wanted this. They wanted global sample folders.

Editing of samples in another program

It is true that it is irrelevant where the file is saved, but it should be a .flac file.

If a sample is recorded and then deleted AND if the user does not intend to use it in any other project or software, it should be deleted from disk to not waste disk space.

Yes, you can't really detect if an other software uses the file any you can't detect the users intentions I think, so better let the user manage their files. Maybe provide some help.

Don't require the user to enter a file name for each sample when saving the project.

Agree.

I would like to propose this solution:

Currently the PR supports both global and local sample folders (= project folders). Keep it this way. Store saved audio with normal ".flac" extensions. Name new samples with project name + number. Add a dialog window that shows the unused samples either in the project folder or in the global sample folder. Add some buttons to delete some or all unused audio.

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.

6 participants