-
-
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
Let sample tracks play from any song position #3133
Conversation
Here's a video of the weird behaviour: https://youtu.be/Hh9at-DF7hI |
Click noises on resize and scrolling Song Editor should be fixed now. |
How well does this cope with time signature and/or tempo automation? |
Sorry, thats not implemented yet. Please let's do the things step by step. |
@Umcaruje the fourth point should be fixed now. You can now looping, change songposition per mouse and per left/right key. mute and unmute the track, solo and unsolo an other track, stop pause playing and all that stuff. It will be synced perfectly ( I hope 😄 ) |
Bloody amazing! |
@BaraMGB I'm still getting some pretty bad artifacts if the sample is extended past its length... (white noise, clicks) |
My plan is to limit the TCO length to sample length. I think this is the simplest way to avoid this. |
@tresf okay, I guess I fixed it. Can you test this again? |
Confirmed, the artifacts are gone. |
Do any artifacts occur when you add an empty tco, without any sample loaded? |
Awesome 👍 |
@Umcaruje @BaraMGB @softrabbit I think this is ready to merge. I understand time signature will break this however we have many bugs today with time signature and seeking ahead. I want this in 1.2.0-RC2 so that we get solid usage and feedback on it. |
The drawing sequence needs to be simplified so it won't produce such high cpu usage on redraws, though I guess that could be an issue for a seperate PR. I'm going to do some more thorough testing now. |
Works mighty well. Is it screaming hard to have this work in the Beat/Bassline Sample Track too? |
{ | ||
if( sTco->isPlaying() == false ) | ||
{ | ||
f_cnt_t sampleStart = ( _start * framesPerTick ) - ( sTco->startPosition() * framesPerTick ); |
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.
f_cnt_t sampleStart = framesPerTick * ( _start - sTco->startPosition() );
if( sTco->isPlaying() == false ) | ||
{ | ||
f_cnt_t sampleStart = ( _start * framesPerTick ) - ( sTco->startPosition() * framesPerTick ); | ||
f_cnt_t tcoFrameLength = ( sTco->endPosition() * framesPerTick ) - ( sTco->startPosition() * framesPerTick ); |
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.
f_cnt_t tcoFrameLength = framesPerTick * ( sTco->endPosition() - sTco->startPosition() );
@@ -394,10 +454,12 @@ void SampleTCOView::paintEvent( QPaintEvent * pe ) | |||
/ (float) m_tco->length().getTact() : | |||
pixelsPerTact(); | |||
|
|||
float nom = Engine::getSong()->getTimeSigModel().getNumerator(); | |||
float den = Engine::getSong()->getTimeSigModel().getDenominator(); | |||
float ticksPerTact = DefaultTicksPerTact * ( nom / den ); |
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.
float ticksPerTact = DefaultTicksPerTact * nom / den;
clicktrack.zip Edit: re-uploaded with correct samples... OK. I made a test project with two different length click tracks and they sync perfectly. However, every now and then the samples will cut out after the first click on one and sometimes both sides. I haven't seen this on export. |
Also, the glitchy tick on loop back, is that the first tick of the next bar before a loop? So the whole audio track is one tick off... but instrument tracks isn't? |
f_cnt_t sampleStart = ( _start * framesPerTick ) - ( sTco->startPosition() * framesPerTick ); | ||
f_cnt_t tcoFrameLength = ( sTco->endPosition() * framesPerTick ) - ( sTco->startPosition() * framesPerTick ); | ||
f_cnt_t sampleStart = framesPerTick * ( _start - sTco->startPosition() ); | ||
f_cnt_t tcoFrameLength = framesPerTick * ( sTco->endPosition() - sTco->startPosition() ); | ||
f_cnt_t sampleBufferLength = sTco->sampleBuffer()->frames(); | ||
//if the Tco smaller than the sample length we play only until Tco end | ||
//else we play the sample to the end but nothing more | ||
f_cnt_t samplePlayLength = tcoFrameLength > sampleBufferLength ? sampleBufferLength : tcoFrameLength; | ||
//we only play within the sampleBuffer limits | ||
if( sampleStart < sTco->sampleBuffer()->frames() ) |
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.
if( sampleStart < sampleBufferLength )
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.
Thank you, sometimes I'm a little bit blind. ;)
@zonkmachine edit: there's something fishy, but I don't see it. 😩 |
@zonkmachine : perhaps this is a stupid idea: |
if( m_playPos[m_playMode] == tl->loopEnd() - 1 ) | ||
{ | ||
emit updateSampleTracks(); | ||
} | ||
if( m_playPos[m_playMode] >= tl->loopEnd() ) | ||
{ | ||
m_playPos[m_playMode].setTicks( tl->loopBegin().getTicks() ); | ||
|
||
m_elapsedMilliSeconds = | ||
( ( tl->loopBegin().getTicks() ) * 60 * 1000 / 48 ) / |
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.
m_elapsedMilliSeconds = tl->loopBegin().getTicks() * 1250 / getTempo();
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.
And the same thing on lines 269, 326, 409, 574 and 643.
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.
No. This will make it harder to deduce where 1250 came from in the first place. The compiler does operations on real numbers for us.
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.
I don't want to change code I don't have to touch. I want to have this PR as clean as possible. We can make an extra PR with code cleaning stuff.
if( m_playPos[m_playMode] == tl->loopEnd() - 1 ) | ||
{ | ||
emit updateSampleTracks(); | ||
} | ||
if( m_playPos[m_playMode] >= tl->loopEnd() ) |
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.
else if( m_playPos[m_playMode] >= tl->loopEnd() )
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.
I would also switch them, as the second one is likely to be true more often.
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.
This is a great idea. I've changed this.
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.
I think you should just try and move the whole loop one tick earlier. (in if( checkLoop ) )
if( m_playPos[m_playMode] >= tl->loopEnd() )
{
m_playPos[m_playMode].setTicks( tl->loopBegin().getTicks() );
to something like (pseudocodeish...):
if( m_playPos[m_playMode] >= tl->loopEnd().getTicks() - 1 )
{
m_playPos[m_playMode].setTicks( tl->loopBegin().getTicks() - 1 );
@@ -298,7 +311,7 @@ void SampleTCOView::updateSample() | |||
// sample-tco contains | |||
ToolTip::add( this, ( m_tco->m_sampleBuffer->audioFile() != "" ) ? | |||
m_tco->m_sampleBuffer->audioFile() : | |||
tr( "double-click to select sample" ) ); | |||
tr( "double-click to select sample" ) ); |
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.
2 spaces added on accident
Ok so we went over this PR on Discord and both @BaraMGB and @zonkmachine agree on a merge. I'm going to merge this once Travis is done buidling, and we can make an RC2 🎉 There are a few quirks in the GUI drawing and also one minor bug when looping, and that can be adressed later. |
* play sampletracks from any song position * take care of TCO length * TCOs shouldn't be updated when SE window is resized * take care of zooming level * takes care on all song position changes and mute/solo tracks now * playes the sample only within the buffer limits * takes care of time signature changes * some minor code improvements (zapashcanon) * loopback one tick earlier * minor code changes * get rid off clicks by resize and scrolling song editor * removes playhandle by remove TCO * minor bugs on manipulating TCOs in Song Editor * update on add sample by playing * white spaces 1
The glitches are still there but not as prominent. I'm looking into it. |
Apparently libsndfile corrected some buffer overflow error in |
* play sampletracks from any song position * take care of TCO length * TCOs shouldn't be updated when SE window is resized * take care of zooming level * takes care on all song position changes and mute/solo tracks now * playes the sample only within the buffer limits * takes care of time signature changes * some minor code improvements (zapashcanon) * loopback one tick earlier * minor code changes * get rid off clicks by resize and scrolling song editor * removes playhandle by remove TCO * minor bugs on manipulating TCOs in Song Editor * update on add sample by playing * white spaces 1
Okay, let's test this. I hope I found a solution that works for all.