From 5e5fa3c5862d8071a45ff46b8c4f3ba597a002c0 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Wed, 17 Mar 2021 13:57:03 -0400 Subject: [PATCH] 2021-03-17 Fred Gleason * Fixed a bug in 'RDMarkerView' that could cause marker positions to lose precision when sliding against a limit stop. Signed-off-by: Fred Gleason --- ChangeLog | 3 + lib/rdmarkerview.cpp | 137 ++++++++++++++++++++----------------------- lib/rdmarkerview.h | 21 +++---- 3 files changed, 79 insertions(+), 82 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4d8a9e0b..632b108c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21273,3 +21273,6 @@ * Implemented saving marker positions in 'RDMarkerDialog'. 2021-03-16 Fred Gleason * Implemented basic marker limit interlocking in 'RDMarkerView'. +2021-03-17 Fred Gleason + * Fixed a bug in 'RDMarkerView' that could cause marker positions + to lose precision when sliding against a limit stop. diff --git a/lib/rdmarkerview.cpp b/lib/rdmarkerview.cpp index 374e949f..0bbd10b3 100644 --- a/lib/rdmarkerview.cpp +++ b/lib/rdmarkerview.cpp @@ -37,8 +37,6 @@ RDMarkerHandle::RDMarkerHandle(RDMarkerHandle::PointerRole role, { setFlags(QGraphicsItem::ItemIsMovable); d_marker_view=mkrview; - d_minimum=0; - d_maximum=-1; QPolygonF triangle; @@ -72,34 +70,17 @@ RDMarkerHandle::PointerRole RDMarkerHandle::role() const } -int RDMarkerHandle::minimum() const +void RDMarkerHandle::setMinimum(int pos,int ptr) { - return d_minimum; + d_minimum_pos=pos; + d_minimum_ptr=ptr; } -void RDMarkerHandle::setMinimum(int pos) +void RDMarkerHandle::setMaximum(int pos,int ptr) { - d_minimum=pos; -} - - -int RDMarkerHandle::maximum() const -{ - return d_maximum; -} - - -void RDMarkerHandle::setMaximum(int pos) -{ - d_maximum=pos; -} - - -void RDMarkerHandle::setRange(int min,int max) -{ - d_minimum=min; - d_maximum=max; + d_maximum_pos=pos; + d_maximum_ptr=ptr; } @@ -135,31 +116,43 @@ void RDMarkerHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *e) // Check Limits // int corr=0; + int limit_ptr=0; int x=pos().x()-LEFT_MARGIN; - if((d_minimum>=0)&&(x=0)&&(x=0)&&(x>d_maximum)) { - corr=d_maximum-x; + if((d_maximum_pos>=0)&&(x>d_maximum_pos)) { + corr=d_maximum_pos-x; + limit_ptr=d_maximum_ptr; } } - // printf("x: %d d_minimum: %d corr: %d lastPos: %d\n",x,d_minimum,corr, - // e->lastPos().x()); - - // - // Update the Marker Graphics - // - int dx=e->pos().x()-e->lastPos().x()+corr; - for(int i=0;isetPos(peer->pos().x()+dx,peer->pos().y()); - } // // Send Position // - view->updatePosition(d_role,x+corr); + if(corr==0) { // Generate new pointer value + int dx=e->pos().x()-e->lastPos().x()+corr; + for(int i=0;isetPos(peer->pos().x()+dx,peer->pos().y()); + } + int64_t pframes=(int64_t)(1152*x*view->shrinkFactor()); + view->updatePosition(d_role,(int)((int64_t)1000*pframes/ + (int64_t)view->sampleRate())); + } + else { // We're against a limit stop, so use the pointer value of the stop + int x=LEFT_MARGIN+view->Frame(limit_ptr); + QGraphicsLineItem *line=static_cast(d_peers.at(2)); + line->setLine(line->line().x1()+x-d_peers.at(0)->pos().x(), + line->line().y1(), + line->line().x2()+x-d_peers.at(0)->pos().x(), + line->line().y2()); + d_peers.at(0)->setPos(x,d_peers.at(0)->pos().y()); + d_peers.at(1)->setPos(x,d_peers.at(1)->pos().y()); + view->updatePosition(d_role,limit_ptr); + } } @@ -376,6 +369,12 @@ int RDMarkerView::audioGain() const } +unsigned RDMarkerView::sampleRate() const +{ + return d_sample_rate; +} + + int RDMarkerView::shrinkFactor() const { return d_shrink_factor; @@ -416,6 +415,16 @@ void RDMarkerView::processRightClick(RDMarkerHandle::PointerRole role, } +void RDMarkerView::updatePosition(RDMarkerHandle::PointerRole role, int ptr) +{ + d_pointers[role]=ptr; + d_has_unsaved_changes=true; + + updateInterlocks(); + + emit pointerValueChanged(role,d_pointers[role]); +} +/* void RDMarkerView::updatePosition(RDMarkerHandle::PointerRole role, int offset) { // @@ -429,7 +438,7 @@ void RDMarkerView::updatePosition(RDMarkerHandle::PointerRole role, int offset) emit pointerValueChanged(role,d_pointers[role]); } - +*/ void RDMarkerView::setAudioGain(int lvl) { @@ -624,32 +633,16 @@ void RDMarkerView::deleteMarkerData() void RDMarkerView::updateInterlocks() { for(int i=0;i<2;i++) { - d_handles[RDMarkerHandle::CutStart][i]->setMinimum(0); + d_handles[RDMarkerHandle::CutStart][i]->setMinimum(0,0); d_handles[RDMarkerHandle::CutStart][i]-> - setMaximum(d_handles[RDMarkerHandle::CutEnd][i]->pos().x()-LEFT_MARGIN); + setMaximum(d_handles[RDMarkerHandle::CutEnd][i]->pos().x()-LEFT_MARGIN, + d_pointers[RDMarkerHandle::CutEnd]); d_handles[RDMarkerHandle::CutEnd][i]-> - setMinimum(d_handles[RDMarkerHandle::CutStart][i]->pos().x()-LEFT_MARGIN); + setMinimum(d_handles[RDMarkerHandle::CutStart][i]->pos().x()-LEFT_MARGIN, + d_pointers[RDMarkerHandle::CutStart]); d_handles[RDMarkerHandle::CutEnd][i]-> - setMaximum(d_right_margin-LEFT_MARGIN); - - /* - if(d_handles[RDMarkerHandle::TalkStart][i]!=NULL) { - d_handles[RDMarkerHandle::TalkStart][i]-> - setMinimum(d_handles[RDMarkerHandle::CutStart][i]-> - pos().x()-LEFT_MARGIN); - d_handles[RDMarkerHandle::TalkStart][i]-> - setMaximum(d_handles[RDMarkerHandle::TalkEnd][i]-> - pos().x()-LEFT_MARGIN); - - d_handles[RDMarkerHandle::TalkEnd][i]-> - setMinimum(d_handles[RDMarkerHandle::TalkStart][i]-> - pos().x()-LEFT_MARGIN); - d_handles[RDMarkerHandle::TalkEnd][i]-> - setMaximum(d_handles[RDMarkerHandle::CutEnd][i]-> - pos().x()-LEFT_MARGIN); - } - */ + setMaximum(d_right_margin-LEFT_MARGIN,Msec(d_wave_factory->energySize())); } InterlockMarkerPair(RDMarkerHandle::TalkStart); InterlockMarkerPair(RDMarkerHandle::SegueStart); @@ -666,16 +659,16 @@ void RDMarkerView::InterlockMarkerPair(RDMarkerHandle::PointerRole start_marker) if(d_handles[start_marker][i]!=NULL) { d_handles[start_marker][i]-> setMinimum(d_handles[RDMarkerHandle::CutStart][i]-> - pos().x()-LEFT_MARGIN); + pos().x()-LEFT_MARGIN,d_pointers[RDMarkerHandle::CutStart]); if(d_handles[start_marker+1][i]==NULL) { d_handles[start_marker][i]-> setMaximum(d_handles[RDMarkerHandle::CutEnd][i]-> - pos().x()-LEFT_MARGIN); + pos().x()-LEFT_MARGIN,d_pointers[RDMarkerHandle::CutEnd]); } else { d_handles[start_marker][i]-> setMaximum(d_handles[start_marker+1][i]-> - pos().x()-LEFT_MARGIN); + pos().x()-LEFT_MARGIN,d_pointers[start_marker+1]); } } @@ -683,16 +676,16 @@ void RDMarkerView::InterlockMarkerPair(RDMarkerHandle::PointerRole start_marker) if(d_handles[start_marker][i]==NULL) { d_handles[start_marker+1][i]-> setMinimum(d_handles[RDMarkerHandle::CutStart][i]-> - pos().x()-LEFT_MARGIN); + pos().x()-LEFT_MARGIN,d_pointers[RDMarkerHandle::CutStart]); } else { d_handles[start_marker+1][i]-> setMinimum(d_handles[start_marker][i]-> - pos().x()-LEFT_MARGIN); + pos().x()-LEFT_MARGIN,d_pointers[start_marker]); } d_handles[start_marker+1][i]-> setMaximum(d_handles[RDMarkerHandle::CutEnd][i]-> - pos().x()-LEFT_MARGIN); + pos().x()-LEFT_MARGIN,d_pointers[RDMarkerHandle::CutEnd]); } } } @@ -835,9 +828,9 @@ void RDMarkerView::DrawMarker(RDMarkerHandle::PointerType type, if(d_pointers[role]>=0) { l_item=d_scene->addLine(LEFT_MARGIN+Frame(d_pointers[role]),0, - LEFT_MARGIN+Frame(d_pointers[role]),d_height,QPen(RDMarkerHandle::pointerRoleColor(role))); + LEFT_MARGIN+Frame(d_pointers[role]),d_height, + QPen(RDMarkerHandle::pointerRoleColor(role))); l_item->setToolTip(RDMarkerHandle::pointerRoleTypeText(role)); - m_item=new RDMarkerHandle(role,type,this); d_scene->addItem(m_item); m_item->setPos(LEFT_MARGIN+Frame(d_pointers[role]),handle_pos-12); diff --git a/lib/rdmarkerview.h b/lib/rdmarkerview.h index 022a14cd..ef61ac3c 100644 --- a/lib/rdmarkerview.h +++ b/lib/rdmarkerview.h @@ -44,11 +44,8 @@ class RDMarkerHandle : public QGraphicsPolygonItem void *mkrview,QGraphicsItem *parent=nullptr); QString name() const; PointerRole role() const; - int minimum() const; - void setMinimum(int pos); - int maximum() const; - void setMaximum(int pos); - void setRange(int min,int max); + void setMinimum(int pos,int ptr); + void setMaximum(int pos,int ptr); static QString pointerRoleText(PointerRole role); static QString pointerRoleTypeText(PointerRole role); static QColor pointerRoleColor(PointerRole role); @@ -63,8 +60,10 @@ class RDMarkerHandle : public QGraphicsPolygonItem PointerRole d_role; QList d_peers; void *d_marker_view; - int d_minimum; - int d_maximum; + int d_minimum_pos; + int d_minimum_ptr; + int d_maximum_pos; + int d_maximum_ptr; }; @@ -77,13 +76,15 @@ class RDMarkerView : public QWidget QSize sizeHint() const; QSizePolicy sizePolicy() const; int audioGain() const; + unsigned sampleRate() const; int shrinkFactor() const; int pointerValue(RDMarkerHandle::PointerRole role); bool hasUnsavedChanges() const; void processRightClick(RDMarkerHandle::PointerRole role, const QPointF &pos); - void updatePosition(RDMarkerHandle::PointerRole role,int offset); + void updatePosition(RDMarkerHandle::PointerRole role,int ptr); + // void updatePosition(RDMarkerHandle::PointerRole role,int offset); public slots: void setAudioGain(int lvl); @@ -92,6 +93,8 @@ class RDMarkerView : public QWidget bool setCut(QString *err_msg,unsigned cartnum,int cutnum); void save(); void clear(); + int Frame(int msec) const; + int Msec(int frame) const; signals: void pointerValueChanged(RDMarkerHandle::PointerRole role,int msec); @@ -111,8 +114,6 @@ class RDMarkerView : public QWidget void mousePressEvent(QMouseEvent *e); private: - int Frame(int msec) const; - int Msec(int frame) const; void InterlockMarkerPair(RDMarkerHandle::PointerRole start_marker); bool LoadCutData(); void WriteWave();