Fixes newly added tracks in BB having wrong size #2883

Merged
merged 1 commit into from Jul 5, 2016

Projects

None yet

5 participants

@Stephen-Seo
Contributor

This PR is technically a continuation of #2880 , with better fixes made as suggested by @jasp00 .

This bug is mentioned in issue #2476 .

@jasp00 jasp00 commented on an outdated diff Jul 1, 2016
src/tracks/Pattern.cpp
@@ -125,6 +125,55 @@ void Pattern::init()
changeLength( length() );
restoreJournallingState();
@jasp00
jasp00 Jul 1, 2016 Member

init() is also run for the copy constructor, which is correctly initialized. This code should only run for the other constructor and before ensureBeatNotes(), thus before init().

@jasp00 jasp00 commented on an outdated diff Jul 1, 2016
src/tracks/Pattern.cpp
@@ -125,6 +125,55 @@ void Pattern::init()
changeLength( length() );
restoreJournallingState();
+
+
+ // Resize this track to be the same size as existing tracks in the BB
+
+ TrackContainer * currentTrackContainer = m_instrumentTrack->trackContainer();
+
+ // Only resize if there actually exists another track in the BB
+ if(currentTrackContainer->tracks().size() > 1)
+ {
+ // Do this per BB for the current Track
+ for(unsigned int tcoIndex = 0; tcoIndex < m_instrumentTrack->getTCOs().size();
+ ++tcoIndex)
@jasp00
jasp00 Jul 1, 2016 Member

This should be done only for the TCO the pattern belongs to. You can get the tcoIndex with getTCOs().indexOf(this).

@jasp00 jasp00 commented on an outdated diff Jul 1, 2016
src/tracks/Pattern.cpp
+ TrackContainer * currentTrackContainer = m_instrumentTrack->trackContainer();
+
+ // Only resize if there actually exists another track in the BB
+ if(currentTrackContainer->tracks().size() > 1)
+ {
+ // Do this per BB for the current Track
+ for(unsigned int tcoIndex = 0; tcoIndex < m_instrumentTrack->getTCOs().size();
+ ++tcoIndex)
+ {
+ // First, get the size of another track
+
+ int steps = MidiTime::stepsPerTact();
+ // Get one other track in the currentTrackContainer
+ for(unsigned int trackIndex = 0;
+ trackIndex < currentTrackContainer->tracks().size();
+ ++trackIndex)
@jasp00
jasp00 Jul 1, 2016 Member

Track 0 is supposed to have good patterns. New tracks are appended to the end.

@jasp00
jasp00 Jul 1, 2016 Member

Rather than track 0, the first track that is an instrument track.

@jasp00 jasp00 commented on an outdated diff Jul 1, 2016
src/tracks/Pattern.cpp
+ Track * track = currentTrackContainer->tracks().at(trackIndex);
+
+ // Do not get size of the current Track/Pattern
+ if(track == static_cast<Track *>(m_instrumentTrack))
+ {
+ continue;
+ }
+
+ // If another BB was added, the last TCO may not exist,
+ // thus this is necessary
+ if(tcoIndex >= currentTrackContainer->tracks().at(trackIndex)->numOfTCOs())
+ {
+ continue;
+ }
+
+ Pattern * pattern = dynamic_cast<Pattern *>(currentTrackContainer->tracks().at(trackIndex)->getTCO(tcoIndex));
@jasp00
jasp00 Jul 1, 2016 Member

You may use a static_cast if the track is an instrument track.

@jasp00 jasp00 commented on an outdated diff Jul 1, 2016
src/tracks/Pattern.cpp
+ // thus this is necessary
+ if(tcoIndex >= currentTrackContainer->tracks().at(trackIndex)->numOfTCOs())
+ {
+ continue;
+ }
+
+ Pattern * pattern = dynamic_cast<Pattern *>(currentTrackContainer->tracks().at(trackIndex)->getTCO(tcoIndex));
+ steps = pattern->m_steps;
+
+ // Got the size of another track, so break out of track loop
+ break;
+ }
+
+ Pattern * currentPattern = dynamic_cast<Pattern *>(m_instrumentTrack->getTCO(tcoIndex));
+
+ currentPattern->m_steps = steps;
@jasp00
jasp00 Jul 1, 2016 Member

In the end, only one pattern should be fixed, the one running the code.

@Stephen-Seo
Contributor

OK, I've taken the notices from jasp00 and made a fix that should be correct in execution and design. Hopefully this will be the last revision but I am still open to notices and flaws about the code. Many thanks, jasp00!

@jasp00 jasp00 commented on an outdated diff Jul 2, 2016
src/tracks/Pattern.cpp
@@ -65,6 +65,39 @@ Pattern::Pattern( InstrumentTrack * _instrument_track ) :
m_steps( MidiTime::stepsPerTact() )
{
setName( _instrument_track->name() );
+
+ // Resize this track to be the same as existing tracks in the BB
+ // Only if there already exists at least another track in the BB
+ const TrackContainer::TrackList & tracks = m_instrumentTrack->trackContainer()->tracks();
@jasp00
jasp00 Jul 2, 2016 Member

Try to limit line lengths to 80 characters (coding conventions).

@jasp00 jasp00 commented on an outdated diff Jul 2, 2016
src/tracks/Pattern.cpp
@@ -65,6 +65,39 @@ Pattern::Pattern( InstrumentTrack * _instrument_track ) :
m_steps( MidiTime::stepsPerTact() )
{
setName( _instrument_track->name() );
+
+ // Resize this track to be the same as existing tracks in the BB
+ // Only if there already exists at least another track in the BB
+ const TrackContainer::TrackList & tracks = m_instrumentTrack->trackContainer()->tracks();
+ if(tracks.size() > 1)
@jasp00
jasp00 Jul 2, 2016 Member

You should remove this check. It will make the algorithm simpler and faster for normal projects.

@jasp00 jasp00 commented on an outdated diff Jul 2, 2016
src/tracks/Pattern.cpp
@@ -65,6 +65,39 @@ Pattern::Pattern( InstrumentTrack * _instrument_track ) :
m_steps( MidiTime::stepsPerTact() )
{
setName( _instrument_track->name() );
+
+ // Resize this track to be the same as existing tracks in the BB
+ // Only if there already exists at least another track in the BB
+ const TrackContainer::TrackList & tracks = m_instrumentTrack->trackContainer()->tracks();
+ if(tracks.size() > 1)
+ {
+ // Get currentTCO index (current BB)
+ int currentTCO = m_instrumentTrack->getTCOs().indexOf(this);
+ // Get first InstrumentTrack
+ unsigned int trackID = 0;
+ for(; trackID < tracks.size(); ++trackID)
+ {
+ // skip track that is the same as the current Pattern
+ if(tracks.at(trackID) == static_cast<Track *>(m_instrumentTrack))
@jasp00
jasp00 Jul 2, 2016 Member

When you hit this condition, there are no more instrument tracks. You should simply check that the track is an instrument track; then if the track is different from m_instrumentTrack, m_steps is updated.

@jasp00 jasp00 commented on an outdated diff Jul 2, 2016
src/tracks/Pattern.cpp
+ if(tracks.size() > 1)
+ {
+ // Get currentTCO index (current BB)
+ int currentTCO = m_instrumentTrack->getTCOs().indexOf(this);
+ // Get first InstrumentTrack
+ unsigned int trackID = 0;
+ for(; trackID < tracks.size(); ++trackID)
+ {
+ // skip track that is the same as the current Pattern
+ if(tracks.at(trackID) == static_cast<Track *>(m_instrumentTrack))
+ {
+ continue;
+ }
+ // Found existing InstrumentTrack, thus break
+ else if(tracks.at(trackID)->type() == Track::InstrumentTrack)
+ {
@jasp00
jasp00 Jul 2, 2016 Member

If you update m_steps here, it is true that trackID < tracks.size().

@jasp00 jasp00 commented on an outdated diff Jul 2, 2016
src/tracks/Pattern.cpp
+ {
+ // skip track that is the same as the current Pattern
+ if(tracks.at(trackID) == static_cast<Track *>(m_instrumentTrack))
+ {
+ continue;
+ }
+ // Found existing InstrumentTrack, thus break
+ else if(tracks.at(trackID)->type() == Track::InstrumentTrack)
+ {
+ break;
+ }
+ }
+ // If trackID is out of bounds, then there is no valid InstrumentTrack
+ // If currentTCO is out of bounds, then a new BB was created and should
+ // have default size
+ if(trackID < tracks.size() && currentTCO < tracks.at(trackID)->numOfTCOs())
@jasp00
jasp00 Jul 2, 2016 Member

currentTCO will be in bounds since the reference track comes before and is already initialized.

@jasp00 jasp00 commented on an outdated diff Jul 2, 2016
src/tracks/Pattern.cpp
+ // skip track that is the same as the current Pattern
+ if(tracks.at(trackID) == static_cast<Track *>(m_instrumentTrack))
+ {
+ continue;
+ }
+ // Found existing InstrumentTrack, thus break
+ else if(tracks.at(trackID)->type() == Track::InstrumentTrack)
+ {
+ break;
+ }
+ }
+ // If trackID is out of bounds, then there is no valid InstrumentTrack
+ // If currentTCO is out of bounds, then a new BB was created and should
+ // have default size
+ if(trackID < tracks.size() && currentTCO < tracks.at(trackID)->numOfTCOs())
+ {
@jasp00
jasp00 Jul 2, 2016 Member

Then, currentTCO's initialization should be here.

@jasp00
Member
jasp00 commented Jul 2, 2016

Do not spend too much time with commit messages because you should squash commit history later.

@Stephen-Seo
Contributor

The reason why I check if "currentTCO" is in bounds, is that when another BB is added, the TCO for that BB doesn't yet exist for the tracks during execution of Pattern's constructor. Since the newly added BB will always have the default length, it is better to check if the "currentTCO" is in bounds and not change "m_steps" if it isn't.

@Stephen-Seo
Contributor

If I ignore bounds checking for "currentTCO", I get a "called Track::getTCO( 3 ), but TCO 3 doesn't exist"

@Stephen-Seo
Contributor

If you are satisfied with the current changes, then I will sqash commit history, but until then I will keep on refactoring.

@jasp00 jasp00 commented on an outdated diff Jul 2, 2016
src/tracks/Pattern.cpp
@@ -65,6 +65,26 @@ Pattern::Pattern( InstrumentTrack * _instrument_track ) :
m_steps( MidiTime::stepsPerTact() )
{
setName( _instrument_track->name() );
+
+ // Resize this track to be the same as existing tracks in the BB
+ const TrackContainer::TrackList & tracks =
+ m_instrumentTrack->trackContainer()->tracks();
+ for(unsigned int trackID = 0; trackID < tracks.size(); ++trackID)
+ {
+ if(tracks.at(trackID)->type() == Track::InstrumentTrack &&
@jasp00
jasp00 Jul 2, 2016 Member

You should break on this condition. The reference track should be before the current track, not after. Then, you can remove the bounds check for currentTCO. It should look like:

if(type)
  if(not same track)
    update steps
  break
@jasp00 jasp00 commented on an outdated diff Jul 2, 2016
src/tracks/Pattern.cpp
@@ -65,6 +65,26 @@ Pattern::Pattern( InstrumentTrack * _instrument_track ) :
m_steps( MidiTime::stepsPerTact() )
{
setName( _instrument_track->name() );
+
+ // Resize this track to be the same as existing tracks in the BB
+ const TrackContainer::TrackList & tracks =
+ m_instrumentTrack->trackContainer()->tracks();
+ for(unsigned int trackID = 0; trackID < tracks.size(); ++trackID)
+ {
+ if(tracks.at(trackID)->type() == Track::InstrumentTrack &&
+ tracks.at(trackID) != m_instrumentTrack)
+ {
+ int currentTCO = m_instrumentTrack->getTCOs().indexOf(this);
@jasp00
jasp00 Jul 2, 2016 Member

When limiting the line to 80 characters, remember that one tab equals to 8 spaces.

@jasp00 jasp00 commented on an outdated diff Jul 2, 2016
src/tracks/Pattern.cpp
+
+ // Resize this track to be the same as existing tracks in the BB
+ const TrackContainer::TrackList & tracks =
+ m_instrumentTrack->trackContainer()->tracks();
+ for(unsigned int trackID = 0; trackID < tracks.size(); ++trackID)
+ {
+ if(tracks.at(trackID)->type() == Track::InstrumentTrack &&
+ tracks.at(trackID) != m_instrumentTrack)
+ {
+ int currentTCO = m_instrumentTrack->getTCOs().indexOf(this);
+ if(currentTCO >= tracks.at(trackID)->numOfTCOs())
+ {
+ break;
+ }
+ m_steps = static_cast<Pattern *>
+ (tracks.at(trackID)->getTCO(currentTCO))->m_steps;
@jasp00
jasp00 Jul 2, 2016 Member

80 characters.

@tresf
Member
tresf commented Jul 2, 2016

Let's please stop with the 80 character requirement. It just makes the code ugly. I realize the wiki offers it as a recommendation, but there's very little benefit in enforcing it anymore.

@Stephen-Seo
Contributor
Stephen-Seo commented Jul 3, 2016 edited

I usually had used "set expandtab", "set tabstop=4" and "set shiftwidth=4" in my vim config.
I knew to disable "set expandtab" to avoid mistabbing things but didn't realize that they count for 8 spaces. The fix should be good now?

Also, is it safe to squelch commits into one commit within the bb_bugfix branch or will I need to do it in a new branch and a new PR? (I won't be doing it until it's truely fixed.)

@jasp00
Member
jasp00 commented Jul 3, 2016

The fix is good. You can squash commits within the bb_bugfix branch. Try git rebase -i HEAD~10 (10 commits).

@tresf
Member
tresf commented Jul 3, 2016 edited

The fix is good. You can squash commits within the bb_bugfix branch. Try git rebase -i HEAD~10 (10 commits).

FYI, @jasp00 GitHub provides a "Squash and merge" button now.

screen shot 2016-07-03 at 11 36 30 am

@Umcaruje
Member
Umcaruje commented Jul 5, 2016

Tested this out, works beautifully.
The only thing is that the new track is always the same size as the first track. Now, you can edit out the first track's length using the context menu, and every new track would have that new length, despite all the other tracks having a different length.

But I don't see this is as an issue, and also making the new track adding system more "intelligent" probably isn't worth it, and in most cases this fix works like a charm. So this gets a 👍 from me for a merge.

@tresf tresf merged commit 652aa5e into LMMS:master Jul 5, 2016

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
@jasp00
Member
jasp00 commented Jul 6, 2016

TBH @Umcaruje, I did not notice patterns could be changed individually. In this case, the default number of steps could be saved in BB tracks, as suggested by @Stephen-Seo.

@Spekular
Contributor
Spekular commented Jul 6, 2016

I don't really think it's necessary to have different lengths for different samples, so maybe the context menu action should be removed or changed to affect all samples

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment