Skip to content
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

Knife Tool for Sample Clips #4998

Merged
merged 20 commits into from
Jun 2, 2020
Merged

Knife Tool for Sample Clips #4998

merged 20 commits into from
Jun 2, 2020

Conversation

Spekular
Copy link
Member

@Spekular Spekular commented May 29, 2019

This PR builds off of #4973, so that one needs to be reviewed and merged first.

Needs to be updated with all the changes from #4973 before merge, somehow.

Mergeable once again!

Adds a knife tool for splitting sample clips, based on BaraMGB's work.

Preview of feature
Screeshot shows, from left to right: Unquantized cut, quantized cut before releasing mouse, cut quantized to clip boundaries (in this case, two bars left of the clip's end)

TODO:

  • Cursor for knife mode
  • Undo correctly
  • Short hang when cutting playing clip, according to @PhysSong. Still present in latest commit?

Usage:

  • Select knife mode.
  • Click and hold on a sample clip. A marker appears showing where the split will occur.
  • The mouse can be dragged around. Split position is quantized to song editor Q by default
  • Holding ctrl or alt disables quantization.
  • Holding shift snaps the cut position to a quantized offset from the clip's left or right edge, whichever is closer to the cursor. This means at least one of the new clips after the cut will have a quantized length (both, if the original length is a multiple of the current snap size).
  • On release, the clip will be split, unless the mouse was moved off to either side (or is exactly at the start/end position).

@Gabrielxd195
Copy link

friend, this also serves for tco or piano roll clips ?. is that this tool looks great.

@Spekular
Copy link
Member Author

This currently only works for sample clips.

@Spekular Spekular changed the title Knife Tool Knife Tool for Sample Clips May 31, 2019
@Spekular
Copy link
Member Author

I'd love it if git didn't completely destroy everything every time I tried to rebase. Fetched and pulled on snap branch, checked out knife branch, fetched and pulled again, "rebase spek SESnap", everything explodes.

@PhysSong
Copy link
Member

I can help you with rebasing commits.

@Spekular
Copy link
Member Author

It seems to have fixed itself once I fixed the merge "conflict" that there was an extra newline somewhere. For a while it was displaying changes as if I'd touched tens of files, even though the "changes" matched master exactly. I may have been trigger happy in my complaining, since last time was a huge timesink.

@PhysSong
Copy link
Member

I tried rebasing commits. Surprisingly, there were only 2 commits after rebasing. If you want a clean branch, I can push the rebased one.

@Spekular
Copy link
Member Author

Spekular commented Jul 27, 2019 via email

@PhysSong
Copy link
Member

Rebased. You can pull the branch with

git checkout Knife
git fetch spek Knife
git reset hard spek/Knife

@Spekular
Copy link
Member Author

Spekular commented Jul 27, 2019 via email

@Spekular
Copy link
Member Author

Fixing that "tiny issue" took a while. You'd think that the result from knifeMarkerPos( me ) could be converted back to a MidiTime and used for the actual cut itself, but for some reason the shift/default behavior ends up inverted if you do. Adding a boolean switch to flip the two still left some weirdness, so I moved the code that decides the position back into mouseReleaseEvent. After a ton of trial and error I think it's working, but I can't say I understand why it has to be the way it is.

@Spekular
Copy link
Member Author

With the icon added, I don't think there's anything left to add to this. Ready for code review and testing!

@LostRobotMusic
Copy link
Contributor

@Spekular If you right click while holding left click with the knife tool, the black marker line thing stays behind (even after switching tools). If you move the TCO with the black line left behind, then the mark will stay there permanently.

@Spekular
Copy link
Member Author

Spekular commented Jul 28, 2019 via email

@tresf tresf mentioned this pull request Jul 31, 2019
29 tasks
@Reflexe Reflexe added needs code review A functional code review is currently required for this PR needs style review A style review is currently required for this PR needs testing This pull request needs more testing labels Aug 17, 2019
Copy link
Contributor

@BaraMGB BaraMGB left a comment

Choose a reason for hiding this comment

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

There are a lot of spaces in braces. As far as I know, we decided to use the current coding convention if we write new code. Perhaps you look into it. I think I have not barked at every single point.

{
m_marker = e;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's remove the spaces inside the brackets in new code.

Copy link
Member Author

Choose a reason for hiding this comment

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

I thought policy was to match surrounding code until an autoformatter fixes this stuff.

Copy link
Member

Choose a reason for hiding this comment

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

match surrounding code

setIsPlaying() doesn't have spaces in the parentheses, but setSampleBuffer() does. Neither way will match the surrounding code perfectly.

Copy link
Member Author

Choose a reason for hiding this comment

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

The vast majority of the file uses spaces, but fair point.

src/core/Track.cpp Outdated Show resolved Hide resolved
src/core/Track.cpp Outdated Show resolved Hide resolved
src/core/Track.cpp Outdated Show resolved Hide resolved
src/core/Track.cpp Outdated Show resolved Hide resolved
src/core/Track.cpp Outdated Show resolved Hide resolved
src/core/Track.cpp Outdated Show resolved Hide resolved
src/core/Track.cpp Outdated Show resolved Hide resolved
src/core/Track.cpp Outdated Show resolved Hide resolved
src/core/Track.cpp Outdated Show resolved Hide resolved
@Spekular
Copy link
Member Author

Spekular commented May 5, 2020

@PhysSong I can't reproduce the hang. Does it still occur on the latest commt?

@Spekular Spekular added this to the 1.3 milestone May 6, 2020
@RebeccaDeField
Copy link
Contributor

RebeccaDeField commented May 6, 2020

I have found that both the default and classic them use odd sizes for the cursor which are different from each other. I will start with the knife tool cursor icons tomorrow with 32x32 and we can scale down to 16x16 if it seems too large. Might want to update the default cursor to match so that the size doesn't significantly jump and if it is more widely supported that may be an overall improvement.

@RebeccaDeField
Copy link
Contributor

A few options from what I have mocked up so far. The first one needs some final tweaking to get it just right.
Screenshot from 2020-05-07 18-38-17

I lean towards the razor icon because I am used to it from other programs. Scissors might look more obvious. Thoughts?

@Spekular
Copy link
Member Author

Spekular commented May 8, 2020

Between these I prefer the razor as well, but in general I'm partial to a knife/scalpel metaphor. One of my concerns with scissors is their association with cut as in cut/copy/paste. I've added a screenshot to the PR description where you can see what the icon for the button looks like, apologies for not having this up before :(

@RebeccaDeField
Copy link
Contributor

RebeccaDeField commented May 9, 2020

@Spekular no problem, my mistake for not checking the current icon.

One of my concerns with scissors is their association with cut as in cut/copy/paste.

Good point, I agree.

Between these I prefer the razor as well, but in general, I'm partial to a knife/scalpel metaphor.

I like this concept. I can refine the existing icon as well. Should the cursor match this icon, just in a 32x32 size w/ border?

@Spekular
Copy link
Member Author

I can refine the existing icon as well.

Feel free to, here's the .svg file.

Should the cursor match this icon, just in a 32x32 size w/ border?

Matching the orientation might look odd; the button icon has to aim 45 degrees down and left to match the pencil, whereas cursors usually range between pointing up/left and pointing straight up. Of course, if it doesn't look weird or out of place with the other cursors, I suppose it's not an issue.

Otherwise I think it's probably a good idea for them to match. I assume you're referring to the black outline/stroke around most cursors when you say "border"? My first thought was a square frame around the icon so I'm double checking, haha.

Zoomed in screenshot highlighting cursor outline

@RebeccaDeField
Copy link
Contributor

Matching the orientation might look odd; the button icon has to aim 45 degrees down and left to match the pencil, whereas cursors usually range between pointing up/left and pointing straight up. Of course, if it doesn't look weird or out of place with the other cursors, I suppose it's not an issue.

I think this is a great idea.

Otherwise I think it's probably a good idea for them to match. I assume you're referring to the black outline/stroke around most cursors when you say "border"?

Yep 👍

Okay, I have created a slightly tweaked version for hopefully added crispness (.5 aligned slanted shapes tend to stairstep better) and a cursor version. For the cursor, I took out the slant on the tip of the blade so that it's a little more precise and matching a regular cursor expectation. I can leave the icon version with the slant as it does help metaphorically. Or we can make this straight as well for consistency.

Screenshot from 2020-05-14 16-05-09

Screenshot from 2020-05-14 16-05-18

@Spekular

@Spekular
Copy link
Member Author

Looks awesome! I'm a fan of straight cursor + slanted button, so let's go with that unless you disagree? Once I have .pngs for the cursor and tweaked button I'll try to get the cursor implemented as soon as I can. (I might wait for #5489, though)

@RebeccaDeField
Copy link
Contributor

It's a little tricky to make these crisp due to the number of slanted lines. I'm attaching the best results for the icon I could get. Slanted lines should translate better at half pixel but I don't see much of a difference in this case.

knifeicons.zip

If the icon master himself (@Umcaruje) has time to look at this and notices any way to crisp it up any further...

But otherwise, let's just make sure to use a cairo export.

@PhysSong
Copy link
Member

PhysSong commented May 21, 2020

LMMS sometimes crashes on undoing cuts.

for( int i = 0; i < numOfTCOs(); ++i )
{
TrackContentObject * tco = getTCO( i );
SampleTCO * sTco = dynamic_cast<SampleTCO*>( tco );
if( _start >= sTco->startPosition() && _start < sTco->endPosition() )

It seems like getTCO(i) sometimes return null due to some multithread-unsafe code, and we don't check the return value.

The hang was fixed by not using copy() and paste(), but it caused an issue. SampleTCO and SamplePlayHandle assumes that no two TCOs share the same SampleBuffer instance, but your code breaks the assumption now. This makes the first TCO doesn't stop playing when it should.
I think the best solution is to copy the sample buffer without reloading the audio file, but it looks quite tricky with the current design of it.

@Spekular
Copy link
Member Author

Spekular commented May 21, 2020

It seems like getTCO(i) sometimes return null due to some multithread-unsafe code, and we don't check the return value

Does this multithread unsafeness need to be fixed in the areas I've touched, or elsewhere? Also, that loop never references i except to get TCOs, would replacing it with a range-based for loop help at all?

The hang was fixed by not using copy() and paste(), but it caused an issue. SampleTCO and SamplePlayHandle assumes that no two TCOs share the same SampleBuffer instance, but your code breaks the assumption now. This makes the first TCO doesn't stop playing when it should.
I think the best solution is to copy the sample buffer without reloading the audio file, but it looks quite tricky with the current design of it.

Ok, so how do we move forward? I believe I tried using a copy constructor for the SampleBuffer, but the compiler complained about it not existing even though a default one should exist.

@PhysSong
Copy link
Member

Does this multithread unsafeness need to be fixed in the areas I've touched, or elsewhere?

I think Track::loadSettings() is deleting TCOs in a thread-unsafe manner, I'll fix that on master.

Ok, so how do we move forward? I believe I tried using a copy constructor, but the compiler complained about it not existing even though a default one should exist.

There's no default copy constructor because the copy constructor of QReadWriteLock is deleted. Even if there's one, you shouldn't use it because it won't copy the memory block for samples.
You may use saveSettings() and loadSettings() from SerializingObject, but that will reintroduce the short hang. I'm okay with it because it's better than having a weird bug.

@Spekular
Copy link
Member Author

@PhysSong how does this look?

master...Spekular:ROT

Still seems to work from a quick test, the first TCO stops playing when it should. If this is good then I should also add a copy assignment to SampleBuffer and SampleTCO.

@PhysSong
Copy link
Member

That looks fine, but I think this will conflict with #4994. I want to hear @Reflexe's opinion for the final decision, but I'd say go ahead for now.

@Spekular Spekular merged commit 31b938d into LMMS:master Jun 2, 2020
@Spekular Spekular deleted the Knife branch August 10, 2020 15:24
@tresf tresf mentioned this pull request Feb 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs code review A functional code review is currently required for this PR needs style review A style review is currently required for this PR needs testing This pull request needs more testing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants