LMMS / lmms

Cross-platform music production software
https://lmms.io
GNU General Public License v2.0
8.19k stars 1.01k forks source link

Allow adjusting file position of sample clips in sample tracks #6667

Open Haeleon opened 1 year ago

Haeleon commented 1 year ago

Enhancement Summary

This feature would work similarly to an Ableton feature that does the same thing. Using Ctrl+Shift would allow changing what section of audio is included in a sample track without changing its position or size in the sample track. This could be quantized and allow for an unused key combination using the Alt key for finer control. (Ctrl+Shift+Alt could work but it might be a lot of keys at once.)

This feature may be waiting on the completion of #6610 or similar.

Justification

This would be a workflow enhancement for anyone who usually chops up samples. If it was quantized, it could be used for things like drum loops to be chopped up and resequenced very quickly, and if time or pitch stretching was implemented in the future, then it could lead to extremely powerful techniques for reprocessing audio.

Mockup

sample_scrolling_mockup

musikBear commented 10 months ago

This is an important feature. It is very difficult to precisely synchronize sample-track to fi. a percussion-line I think some kind of 'automated' position-shifting in msecd precision is needed to achieve a perfect synchronisation. Manually moving with mouse is not precise enough. I fought that to desperation yesterday.... Use case: We have an Acapella-lead as a sound-file loaded in Sample-track Build in LMMS we have some percussion-line Project BPM 140. Task: Place the lead 100% synchronised with the percussion-line. First task would be to stretch the lead to the BPM in the project, for that we use audacity Would be be neat is it was an option in lmms, it isent. case closed. Second task Manually move the stretched sample to a synchronised position in the percussion. Very difficult- but LMMS could have a 'spread' of +/- ½ secd for fine-adjusting either the sample inside sample-track, or the container it self. This setup would mean that we need to manually mouse-place the sample with less then ½ secd margin of error. That is doable. From that manual placement position the sample should auto-move in steps of 1 msecd either left or right (R/L-arrows) simultaneously the percussion should re-play in a loop Current existing button image would be fine. 'Only' missing controller would be a button that would stop the movement of the sample/ sample-container, and freeze the position. An additional option for entering a manual value by text-input could be the final adjuster Is this ^ doable? Can it be designed better?

michaelgregorius commented 10 months ago

Can it be designed better?

REAPER has a dialog that allows you to "nudge", i.e. move, items with regards to different time units (samples, beats, seconds, etc.):

REAPERNudge

Here with the time options:

REAPERNudgeTimeOptions

Haeleon commented 10 months ago

I believe MusikBear is suggesting automatically aligning a sample inside a track, which is not the same as my suggestion, but would end up causing similar changes (being the sample shifts position inside its block). Such a function could fit in a menu such as the example from Reaper since it would probably allow for different options.

However, for my own use case, I’m not considering sample alignment, but rather freely sliding it inside its block. It would be wonderful to have the option to drag them with a modifier key held down to achieve the effect shown in the GIF, similar to how Ableton does it. Using a dialog box for that would be a clunkier and less intuitive workflow than dragging and resizing the entire sample block for the same effect.

That said, I’d love to see what other people think, especially because I’m unfortunately not experienced enough to help with adding such a feature myself.

michaelgregorius commented 10 months ago

In case someone wants to experiment with this, I have extended SampleClipView::mousePressEvent with the following first lines to test the feasibility of some approaches:

if(_me->button() == Qt::LeftButton && _me->modifiers() == Qt::ControlModifier)
{
    m_clip->setStartTimeOffset(m_clip->startTimeOffset() - 1);

    // auto sampleClip = dynamic_cast<SampleClip*>(getClip());
    // if (sampleClip)
    // {
    //  sampleClip->setSampleStartFrame(sampleClip->sample().startFrame() + 500);
    // }

    update();
    _me->accept();

    return;
}

This will adjust the start time offset of a sample clip by 1 tick to the left if the clip is left clicked with the Control modifier (this is obviously just a test implementation). This somewhat works but unfortunately tick granularity would be much too coarse. DefaultTicksPerBar is defined as 192 in TimePos.h. If my calculations are correct this means that at 120 BPM with a sample rate of 48 kHz a tick spans 500 samples, i.e. you could only move the samples in increments of 500 samples. This is too coarse if you want to adjust transients to the grid. It also means that the whole thing would be dependent on song tempo and sample rate.

The commented out code was a test if it is possible to adjust the clip with sample granularity but unfortunately it did not work. To experiment with this comment it back in and comment out the line with setStartTimeOffset. The start frame of the sample clip will be adjusted but this neither reflects during playback nor when the clip is painted.

musikBear commented 10 months ago

Can it be designed better?

REAPER has a dialog that allows you to "nudge", i.e. move, items with regards to different time units (samples, beats, seconds, etc.):

REAPERNudge

Here with the time options:

REAPERNudgeTimeOptions

That is interesting indeed, but will lmms get that ever? No doubt -That feature is top-shelf! Very clever -Very advanced. What i am thinking is that we perhaps not need to go top-shelf, but more in direction functional-shelf. But that nudge-feature is sexy (Know what i mean..

michaelgregorius commented 10 months ago

In theory such a feature wouldn't have to be top shelf. There are already methods in the code to move clips by TimePos units. So it shouldn't be too hard to write a dialog that opens for a clip that's in focus and to move the clip by the selected units. Unfortunately, the smallest of these units is a "tick" which is 1/192th of a bar. As noted above this is much too coarse to place samples accurately.

To make LMMS intuitively usable for working with samples that resolution would have to be increased to a resolution of individual samples. I don't know if other DAWs even support sub-sample accuracy but that would be computationally more expensive anyway. So individual samples would be a good start.

Edit: I have just checked in REAPER and it allows you to move for example clip starting points in between individual samples of another clip. Don't ask me if that's only a visual feature of if it in fact resamples the clips accordingly.

Haeleon commented 10 months ago

I’m not suggesting this feature for aligning sample transients; that’s a separate idea that would be better served with a dialog box offering finer control. I’m suggesting simply allowing samples to be dragged back and forth; coarse units will do just fine, as adjusting more precisely by hand quickly stops making much sense. The goal is just to make quickly changing slices of samples easier to do, for easily creating sequences of vocal chops or percussion in a sample track without having to repeatedly move samples out of position, change their ends independently, then line it back up.

musikBear commented 10 months ago

Unfortunately, the smallest of these units is a "tick" which is 1/192th of a bar

Exactly! I made a humanisation feature some y ago, but that was rejected at least partly because the method implementation was hampered by the 1/192 limitation. (still i liked that the implementation was WYSIWYG, in as much that the notes was visually moved as they were humanized. -tiswatitis