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

Sample editor instant feedback #1314

Open
wants to merge 3 commits into
base: development
Choose a base branch
from

Conversation

charbeljc
Copy link
Contributor

Update target wave display when loop, rubberband or envelope are edited.

Also should close #811
Also should close #1304

There are still strange things with rubberband, but we should be close to something usable.

@charbeljc charbeljc mentioned this pull request Jul 6, 2021
7 tasks
@charbeljc charbeljc force-pushed the sample_editor_instant_feedback branch from 5b3532a to c8d619a Compare July 6, 2021 14:41
@@ -51,18 +50,18 @@ static RubberBand::RubberBandStretcher::Options compute_rubberband_options( cons


/* EnvelopePoint */
EnvelopePoint::EnvelopePoint() : Object( EnvelopePoint::__class_name ), frame( 0 ), value( 0 )
Copy link
Contributor

Choose a reason for hiding this comment

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

How come you removed the H2Core::Object in here? It's used for debugging and shouldn't add too much weight.

Copy link
Contributor Author

@charbeljc charbeljc Jul 7, 2021

Choose a reason for hiding this comment

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

How come you removed the H2Core::Object in here? It's used for debugging and shouldn't add too much weight.

Hum, I was maybe a bit to quick with this. I think EnvelopePoint should go away in favor of a proper Envelope class.
Besides, I have a pending patch which removes the H2Core::Object's overhead...

My point was to get rid of the unique_ptr around EnvelopePoint in envelope, so I can access them from python. I don't remember the details right now, but pybind11 caused me some troubles with those std::shared_ptr<std::unique_ptr> ...

ihmo, EnvelopePoints should be plain dummy structs with copy semantics, and let the (to be written) Envelope let deal with them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @theGreatWhiteShark I just restored EnvelopePoint inheritance of H2Core::Object.
Regards

Copy link
Contributor

Choose a reason for hiding this comment

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

I think EnvelopePoint should go away in favor of a proper Envelope class.
Besides, I have a pending patch which removes the H2Core::Object's overhead...

Could you split off these changes and make a separate PR? Such fundamental changes in the code base require the consent of at least a majority of all maintainers. This will happen much faster if it's a concise one.

One thing to think about in advance (and I haven't done yet, so, there is a chance none of this makes sense): The envelope in the sample editor is quite similar to the automation path. Maybe there could be a common basis.

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 think EnvelopePoint should go away in favor of a proper Envelope class.
Besides, I have a pending patch which removes the H2Core::Object's overhead...

Could you split off these changes and make a separate PR? Such fundamental changes in the code base require the consent of at least a majority of all maintainers. This will happen much faster if it's a concise one.

Yes, I will do a separate PR on this.

One thing to think about in advance (and I haven't done yet, so, there is a chance none of this makes sense): The envelope in the sample editor is quite similar to the automation path. Maybe there could be a common basis.

I will have a look at those automation path. If we could factor out some code, it would be nice.

Copy link
Contributor Author

@charbeljc charbeljc Jul 9, 2021

Choose a reason for hiding this comment

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

Please see #1318 and #1319 (this one is extracted from #1313)

@charbeljc charbeljc force-pushed the sample_editor_instant_feedback branch from c8d619a to 6665f9e Compare July 7, 2021 20:51
@charbeljc charbeljc force-pushed the sample_editor_instant_feedback branch from 652edfb to 98ebd8f Compare July 15, 2021 21:31
@charbeljc charbeljc force-pushed the sample_editor_instant_feedback branch from 98ebd8f to 0ea0925 Compare July 15, 2021 21:42
Copy link
Contributor

@theGreatWhiteShark theGreatWhiteShark left a comment

Choose a reason for hiding this comment

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

I like this signal-based version for communicating changes in the envelope or sliders more.

However, some parts are now broken:

  • Looping doesn't seem to work anymore and if the loop count is set to a value higher than 0 there are visual artifacts in the DetailWaveDisplay
  • Pitch settings using Rubberband does not seem to take any effect either.
  • Previously, when hitting play the white slider indicating current playback position was visible in the TargetWaveDisplay too
  • (unrelated to this PR but I just noticed it) when increase the loop count to very large values, like 300, Hydrogen freezes. We probably should add some sanity checks in there



if (nInstr == -1) {
pInstrument = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

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

How about replacing this line by an ERRORLOG and a return statement? If for any reason nInstr == -1 is true, there will be a segfault later on.

@@ -197,22 +253,24 @@ void SampleEditor::getAllFrameInfos()
if ( pLayer ) {
pSample = pLayer->get_sample();
Copy link
Contributor

Choose a reason for hiding this comment

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

same here. An ERRORLOG and return might prevent a crash in some edge-cases.

pInstrument = pInstrList->get( nInstr );
//INFOLOG( "new instr: " + pInstrument->m_sName );
}

assert( pInstrument );

auto pCompo = pInstrument->get_component(0);
Copy link
Contributor

Choose a reason for hiding this comment

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

I just now realize that using the SampleEditor only the first InstrumentComponent can be edited. Well, since nobody seems to use this feature anyway, nobody complained so far (and I don't think it's worth adding support for it until someone asks for it)

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, while only the first component is painted and used to set the values of all the spinboxes, the previous version of on_PlayPushButton_clicked did respect the selected component. So, it was not displayed properly but you could listen to it. This does not feel right.

assert( pSample );

//this values are needed if we restore a sample from disk if a new song with sample changes will load
m_bSampleIsModified = pSample->get_is_modified();
m_nSamplerate = pSample->get_sample_rate();
__loops = pSample->get_loops();
__rubberband = pSample->get_rubberband();
qWarning() << "gafi rb use " << __rubberband.use
Copy link
Contributor

Choose a reason for hiding this comment

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

This debugging message probably did slipped through

pitchdoubleSpinBox->setValue( 0.0 );
}

if( __rubberband.divider == 1.0/64.0) {
setSamplelengthFrames();
qWarning() << "currentRatio: " << computeCurrentRatio();
Copy link
Contributor

Choose a reason for hiding this comment

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

this one slipped through too

setSamplelengthFrames();
qWarning() << "currentRatio: " << computeCurrentRatio();
if ( !__rubberband.use || (std::abs(computeCurrentRatio() - 1.0) < 0.0001) ) {
qWarning() << "Setting";
Copy link
Contributor

Choose a reason for hiding this comment

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

this one slipped through too

m_pTargetSampleView->move( 1, 1 );
m_pTargetSampleView->updateDisplay( sample, 1.0 );
Copy link
Contributor

Choose a reason for hiding this comment

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

AFAICS this function is only called in the constructor. Right afterwards getAllFrameInfo() is called which too calls m_pTargetSampleView->updateDisplay but with an InstrumentLayer. Next, doneEditing() is called which, again, calls m_pTargetSampleView->updateDisplay. This feels like the first two (including the line I comment on) are redundant.

@@ -73,11 +66,12 @@ class MainSampleWaveDisplay : public QWidget, public H2Core::Object
void testPosition( QMouseEvent *ev );
void chooseSlider( QMouseEvent *ev );
void mouseUpdateDone();


std::shared_ptr<H2Core::Sample> m_pEditedSample;
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the purpose of this member variable? It's never used.

m_pTargetSampleView->setEditMode( SampleEditor::EnvelopeType::VelocityEnvelope );
break;
case 1 ://
if ( m_pTargetSampleView ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This sanity check and the one below should already covered by the one in the beginning of the function


void TargetWaveDisplay::updateDisplay( std::shared_ptr<H2Core::Sample> sample, double gain )
{
// qWarning() << "TargetWaveDisplay::updateDisplay: sample:" << sample;
Copy link
Contributor

Choose a reason for hiding this comment

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

The original version of updateDisplay also included a check whether pLayer->get_sample() is a nullptr. Could you add it in here too just to be save?

@charbeljc
Copy link
Contributor Author

I like this signal-based version for communicating changes in the envelope or sliders more.

However, some parts are now broken:

* Looping doesn't seem to work anymore and if the loop count is set to a value higher than 0 there are visual artifacts in the `DetailWaveDisplay`

What a mess... I guess I did let this PR in the middle of nowhere... Thank you for your review, I'm finally back on track.

* Pitch settings using Rubberband does not seem to take any effect either.

Are your working with the cli version or the library one ?

* Previously, when hitting play the white slider indicating current playback position was visible in the TargetWaveDisplay too

This should be restored now.

* (unrelated to this PR but I just noticed it) when increase the loop count to very large values, like 300, Hydrogen freezes. We probably should add some sanity checks in there

Hum, this don't hang on my machine, but yes, this must be addressed.

@theGreatWhiteShark
Copy link
Contributor

Hey @charbeljc ,

Can you rebase this PR on master? It will be my next read.

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.

2 participants