Ticket #9952: 0001-MythMusic-Correct-the-visualisation-drawing.patch
| File 0001-MythMusic-Correct-the-visualisation-drawing.patch, 15.8 KB (added by , 14 years ago) |
|---|
-
mythplugins/mythmusic/mythmusic/mainvisual.cpp
From e16eae80099ce7bed38109e418c5e7011099a9da Mon Sep 17 00:00:00 2001 From: Lawrence Rust <lvr@softsystem.co.uk> Date: Thu, 28 Jul 2011 13:02:06 +0200 Subject: [PATCH] MythMusic: Correct the visualisation drawing 1. Fix a bug in MainVisual::timeout which results in an empty set of audio samples being passed onto the visualisation. 2. Conditionally exclude some code from the monscope and stereoscape visualisations that can't be reached. 3. Optimize drawing for monscope and stereoscape visualisations. Signed-off-by: Lawrence Rust <lvr@softsystem.co.uk> --- mythplugins/mythmusic/mythmusic/mainvisual.cpp | 309 +++++++++++------------- mythplugins/mythmusic/mythmusic/mainvisual.h | 6 +- 2 files changed, 150 insertions(+), 165 deletions(-) diff --git a/mythplugins/mythmusic/mythmusic/mainvisual.cpp b/mythplugins/mythmusic/mythmusic/mainvisual.cpp index bf6fec4..44b1128 100644
a b using namespace std; 21 21 #include <QCursor> 22 22 #include <QPixmap> 23 23 #include <QEvent> 24 #include <QMutexLocker> 24 25 25 26 // mythtv 26 27 #include <audiooutput.h> … … using namespace std; 40 41 VisFactory* VisFactory::g_pVisFactories = 0; 41 42 42 43 VisualBase::VisualBase(bool screensaverenable) 43 : xscreensaverenable(screensaverenable)44 : fps(20), xscreensaverenable(screensaverenable) 44 45 { 45 46 if (!xscreensaverenable) 46 47 GetMythUI()->DoDisableScreensaver(); … … void VisualBase::drawWarning(QPainter *p, const QColor &back, const QSize &size, 77 78 } 78 79 79 80 MainVisual::MainVisual(QWidget *parent, const char *name) 80 : QWidget(parent), vis(0), playing( FALSE), fps(20),81 : QWidget(parent), vis(0), playing(false), fps(20), 81 82 timer (0), bannerTimer(0), info_widget(0) 82 83 { 83 84 setObjectName(name); … … MainVisual::MainVisual(QWidget *parent, const char *name) 103 104 104 105 MainVisual::~MainVisual() 105 106 { 106 if (vis) 107 { 108 delete vis; 109 vis = 0; 110 } 111 107 delete vis; 112 108 delete info_widget; 113 info_widget = 0;114 115 109 delete timer; 116 timer = 0;117 118 110 delete bannerTimer; 119 bannerTimer = 0;120 111 121 112 while (!nodes.empty()) 122 { 123 delete nodes.back(); 124 nodes.pop_back(); 125 } 113 delete nodes.takeLast(); 126 114 } 127 115 128 116 void MainVisual::setVisual(const QString &name) … … void MainVisual::setVisual(const QString &name) 165 153 timer->start( 1000 / fps ); 166 154 } 167 155 156 // Caller holds mutex() lock 168 157 void MainVisual::prepare() 169 158 { 170 159 while (!nodes.empty()) … … void MainVisual::prepare() 174 163 } 175 164 } 176 165 166 // Caller holds mutex() lock 177 167 void MainVisual::add(uchar *b, unsigned long b_len, unsigned long w, int c, int p) 178 168 { 179 169 long len = b_len, cnt; … … void MainVisual::add(uchar *b, unsigned long b_len, unsigned long w, int c, int 182 172 len /= c; 183 173 len /= (p / 8); 184 174 185 if (len > 512) 186 len = 512; 175 #define SAMPLES 512 176 if (len > SAMPLES) 177 len = SAMPLES; 187 178 188 179 cnt = len; 189 180 … … void MainVisual::add(uchar *b, unsigned long b_len, unsigned long w, int c, int 214 205 215 206 void MainVisual::timeout() 216 207 { 217 bool process = true;218 208 if (parent() != GetMythMainWindow()->currentWidget()) 219 {220 process = false;221 209 return; 222 }223 210 224 VisualNode *node = NULL;211 VisualNode *node = 0; 225 212 if (playing && gPlayer->getOutput()) 226 213 { 227 long synctime = gPlayer->getOutput()->GetAudiotime(); 228 mutex()->lock(); 229 VisualNode *prev = NULL; 214 int64_t synctime = gPlayer->getOutput()->GetAudiotime(); 215 QMutexLocker locker(mutex()); 230 216 while (!nodes.empty()) 231 217 { 232 node= nodes.front();233 if (n ode->offset > synctime)218 VisualNode *n = nodes.front(); 219 if (n->offset > synctime) 234 220 break; 235 221 nodes.pop_front(); 236 222 237 if (prev) 238 delete prev; 239 prev = node; 223 delete node; 224 node = n; 240 225 } 241 mutex()->unlock();242 node = prev;226 if (node) 227 nodes.push_front(node); 243 228 } 244 229 245 bool stop = TRUE; 246 if (vis && process) 247 stop = vis->process(node); 248 if (node) 249 delete node; 250 251 if (vis && process) 230 bool stop = true; 231 if (vis) 252 232 { 233 stop = vis->process(node); 253 234 QPainter p(&pixmap); 254 235 if (vis->draw(&p, Qt::black)) 255 236 update(); … … void InfoWidget::paintEvent( QPaintEvent * ) 509 490 bitBlt(this, 0, 0, &info_pixmap); 510 491 } 511 492 512 StereoScope::StereoScope() 493 #define RUBBERBAND 0 494 #define TWOCOLOUR 0 495 StereoScope::StereoScope() : 496 startColor(Qt::green), targetColor(Qt::red), 497 rubberband(RUBBERBAND), falloff(1.0) 513 498 { 514 499 fps = 45; 515 rubberband = false;516 falloff = 1.0;517 518 startColor = Qt::green;519 targetColor = Qt::red;520 500 } 521 501 522 502 StereoScope::~StereoScope() … … void StereoScope::resize( const QSize &newsize ) 535 515 536 516 bool StereoScope::process( VisualNode *node ) 537 517 { 538 bool allZero = TRUE; 539 int i; 540 long s, indexTo; 541 double valL, valR, tmpL, tmpR; 542 double index, step = 512.0 / size.width(); 518 bool allZero = true; 543 519 544 520 if (node) { 545 index = 0; 546 for ( i = 0; i < size.width(); i++) { 547 indexTo = (int)(index + step); 548 if (indexTo == (int)(index)) 549 indexTo = (int)(index + 1); 550 551 if ( rubberband ) { 552 valL = magnitudes[ i ]; 553 valR = magnitudes[ i + size.width() ]; 554 if (valL < 0.) { 555 valL += falloff; 556 if ( valL > 0. ) 557 valL = 0.; 558 } else { 559 valL -= falloff; 560 if ( valL < 0. ) 561 valL = 0.; 562 } 563 if (valR < 0.) { 564 valR += falloff; 565 if ( valR > 0. ) 566 valR = 0.; 567 } else { 568 valR -= falloff; 569 if ( valR < 0. ) 570 valR = 0.; 571 } 572 } else 573 valL = valR = 0.; 574 575 for (s = (int)index; s < indexTo && s < node->length; s++) { 576 tmpL = ( ( node->left ? 577 double( node->left[s] ) : 0.) * 578 double( size.height() / 4 ) ) / 32768.; 579 tmpR = ( ( node->right ? 580 double( node->right[s]) : 0.) * 581 double( size.height() / 4 ) ) / 32768.; 582 if (tmpL > 0) 583 valL = (tmpL > valL) ? tmpL : valL; 584 else 585 valL = (tmpL < valL) ? tmpL : valL; 586 if (tmpR > 0) 587 valR = (tmpR > valR) ? tmpR : valR; 588 else 589 valR = (tmpR < valR) ? tmpR : valR; 590 } 521 double index = 0; 522 double const step = (double)SAMPLES / size.width(); 523 for ( int i = 0; i < size.width(); i++) { 524 unsigned long indexTo = (unsigned long)(index + step); 525 if (indexTo == (unsigned long)(index)) 526 indexTo = (unsigned long)(index + 1); 527 528 double valL = 0, valR = 0; 529 #if RUBBERBAND 530 if ( rubberband ) { 531 valL = magnitudes[ i ]; 532 valR = magnitudes[ i + size.width() ]; 533 if (valL < 0.) { 534 valL += falloff; 535 if ( valL > 0. ) 536 valL = 0.; 537 } else { 538 valL -= falloff; 539 if ( valL < 0. ) 540 valL = 0.; 541 } 542 if (valR < 0.) { 543 valR += falloff; 544 if ( valR > 0. ) 545 valR = 0.; 546 } else { 547 valR -= falloff; 548 if ( valR < 0. ) 549 valR = 0.; 550 } 551 } 552 #endif 553 for (unsigned long s = (unsigned long)index; s < indexTo && s < node->length; s++) { 554 double tmpL = ( ( node->left ? 555 double( node->left[s] ) : 0.) * 556 double( size.height() / 4 ) ) / 32768.; 557 double tmpR = ( ( node->right ? 558 double( node->right[s]) : 0.) * 559 double( size.height() / 4 ) ) / 32768.; 560 if (tmpL > 0) 561 valL = (tmpL > valL) ? tmpL : valL; 562 else 563 valL = (tmpL < valL) ? tmpL : valL; 564 if (tmpR > 0) 565 valR = (tmpR > valR) ? tmpR : valR; 566 else 567 valR = (tmpR < valR) ? tmpR : valR; 568 } 591 569 592 if (valL != 0. || valR != 0.)593 allZero = FALSE;570 if (valL != 0. || valR != 0.) 571 allZero = false; 594 572 595 magnitudes[ i ] = valL;596 magnitudes[ i + size.width() ] = valR;573 magnitudes[ i ] = valL; 574 magnitudes[ i + size.width() ] = valR; 597 575 598 index = index + step; 599 } 600 } else if (rubberband) { 601 for ( i = 0; i < size.width(); i++) { 602 valL = magnitudes[ i ]; 603 if (valL < 0) { 604 valL += 2; 605 if (valL > 0.) 606 valL = 0.; 607 } else { 608 valL -= 2; 609 if (valL < 0.) 610 valL = 0.; 576 index = index + step; 611 577 } 578 #if RUBBERBAND 579 } else if (rubberband) { 580 for ( int i = 0; i < size.width(); i++) { 581 double valL = magnitudes[ i ]; 582 if (valL < 0) { 583 valL += 2; 584 if (valL > 0.) 585 valL = 0.; 586 } else { 587 valL -= 2; 588 if (valL < 0.) 589 valL = 0.; 590 } 612 591 613 valR = magnitudes[ i + size.width() ];614 if (valR < 0.) {615 valR += falloff;616 if (valR > 0.)617 valR = 0.;618 } else {619 valR -= falloff;620 if (valR < 0.)621 valR = 0.;622 }592 double valR = magnitudes[ i + size.width() ]; 593 if (valR < 0.) { 594 valR += falloff; 595 if (valR > 0.) 596 valR = 0.; 597 } else { 598 valR -= falloff; 599 if (valR < 0.) 600 valR = 0.; 601 } 623 602 624 if (valL != 0. || valR != 0.)625 allZero = FALSE;603 if (valL != 0. || valR != 0.) 604 allZero = false; 626 605 627 magnitudes[ i ] = valL; 628 magnitudes[ i + size.width() ] = valR; 629 } 606 magnitudes[ i ] = valL; 607 magnitudes[ i + size.width() ] = valR; 608 } 609 #endif 630 610 } else { 631 for (i = 0; (unsigned) i < magnitudes.size(); i++ )632 magnitudes[ i ] = 0.;611 for ( int i = 0; (unsigned) i < magnitudes.size(); i++ ) 612 magnitudes[ i ] = 0.; 633 613 } 634 614 635 615 return allZero; … … bool StereoScope::process( VisualNode *node ) 637 617 638 618 bool StereoScope::draw( QPainter *p, const QColor &back ) 639 619 { 640 double r, g, b, per;641 642 620 p->fillRect(0, 0, size.width(), size.height(), back); 643 621 for ( int i = 1; i < size.width(); i++ ) { 622 #if TWOCOLOUR 623 double r, g, b, per; 624 644 625 // left 645 626 per = double( magnitudes[ i ] * 2 ) / 646 627 double( size.height() / 4 ); … … bool StereoScope::draw( QPainter *p, const QColor &back ) 674 655 b = 0; 675 656 676 657 p->setPen( QColor( int(r), int(g), int(b) ) ); 677 p->setPen(Qt::red); 658 #else 659 p->setPen(Qt::red); 660 #endif 678 661 p->drawLine( i - 1, (int)((size.height() / 4) + magnitudes[i - 1]), 679 662 i, (int)((size.height() / 4) + magnitudes[i])); 680 663 664 #if TWOCOLOUR 681 665 // right 682 666 per = double( magnitudes[ i + size.width() ] * 2 ) / 683 667 double( size.height() / 4 ); … … bool StereoScope::draw( QPainter *p, const QColor &back ) 711 695 b = 0; 712 696 713 697 p->setPen( QColor( int(r), int(g), int(b) ) ); 714 p->setPen(Qt::red); 698 #else 699 p->setPen(Qt::red); 700 #endif 715 701 p->drawLine( i - 1, (int)((size.height() * 3 / 4) + 716 702 magnitudes[i + size.width() - 1]), 717 703 i, (int)((size.height() * 3 / 4) + … … MonoScope::~MonoScope() 731 717 732 718 bool MonoScope::process( VisualNode *node ) 733 719 { 734 bool allZero = TRUE; 735 int i; 736 long s, indexTo; 737 double val, tmp; 738 739 double index, step = 512.0 / size.width(); 720 bool allZero = true; 740 721 741 722 if (node) 742 723 { 743 index = 0; 744 for ( i = 0; i < size.width(); i++) 724 double index = 0; 725 double const step = (double)SAMPLES / size.width(); 726 for (int i = 0; i < size.width(); i++) 745 727 { 746 indexTo = (int)(index + step);747 if (indexTo == ( int)index)748 indexTo = ( int)(index + 1);728 unsigned long indexTo = (unsigned long)(index + step); 729 if (indexTo == (unsigned long)index) 730 indexTo = (unsigned long)(index + 1); 749 731 732 double val = 0; 733 #if RUBBERBAND 750 734 if ( rubberband ) 751 735 { 752 736 val = magnitudes[ i ]; … … bool MonoScope::process( VisualNode *node ) 767 751 } 768 752 } 769 753 } 770 else 754 #endif 755 for (unsigned long s = (unsigned long)index; s < indexTo && s < node->length; s++) 771 756 { 772 val = 0.; 773 } 774 775 for (s = (int)index; s < indexTo && s < node->length; s++) 776 { 777 tmp = ( double( node->left[s] ) + 757 double tmp = ( double( node->left[s] ) + 778 758 (node->right ? double( node->right[s] ) : 0) * 779 759 double( size.height() / 2 ) ) / 65536.; 780 760 if (tmp > 0) … … bool MonoScope::process( VisualNode *node ) 789 769 790 770 if ( val != 0. ) 791 771 { 792 allZero = FALSE;772 allZero = false; 793 773 } 794 774 magnitudes[ i ] = val; 795 775 index = index + step; 796 776 } 797 777 } 778 #if RUBBERBAND 798 779 else if (rubberband) 799 780 { 800 for ( i = 0; i < size.width(); i++) {801 val = magnitudes[ i ];781 for (int i = 0; i < size.width(); i++) { 782 double val = magnitudes[ i ]; 802 783 if (val < 0) { 803 784 val += 2; 804 785 if (val > 0.) … … bool MonoScope::process( VisualNode *node ) 810 791 } 811 792 812 793 if ( val != 0. ) 813 allZero = FALSE;794 allZero = false; 814 795 magnitudes[ i ] = val; 815 796 } 816 797 } 798 #endif 817 799 else 818 800 { 819 for ( i = 0; i < size.width(); i++ )801 for (int i = 0; i < size.width(); i++ ) 820 802 magnitudes[ i ] = 0.; 821 803 } 822 804 … … bool MonoScope::process( VisualNode *node ) 825 807 826 808 bool MonoScope::draw( QPainter *p, const QColor &back ) 827 809 { 828 double r, g, b, per;829 830 810 p->fillRect( 0, 0, size.width(), size.height(), back ); 831 811 for ( int i = 1; i < size.width(); i++ ) { 812 #if TWOCOLOUR 813 double r, g, b, per; 814 832 815 per = double( magnitudes[ i ] ) / 833 816 double( size.height() / 4 ); 834 817 if (per < 0.0) … … bool MonoScope::draw( QPainter *p, const QColor &back ) 860 843 else if (b < 0.0) 861 844 b = 0; 862 845 846 p->setPen(QColor(int(r), int(g), int(b))); 847 #else 863 848 p->setPen(Qt::red); 864 //p->setPen(QColor(int(r), int(g), int(b))); 849 #endif 865 850 p->drawLine( i - 1, (int)(size.height() / 2 + magnitudes[ i - 1 ]), 866 851 i, (int)(size.height() / 2 + magnitudes[ i ] )); 867 852 } -
mythplugins/mythmusic/mythmusic/mainvisual.h
diff --git a/mythplugins/mythmusic/mythmusic/mainvisual.h b/mythplugins/mythmusic/mythmusic/mainvisual.h index 09c365b..fc60772 100644
a b public: 50 50 } 51 51 52 52 short *left, *right; 53 long length, offset;53 unsigned long length, offset; 54 54 55 55 }; 56 56 … … protected: 174 174 QColor startColor, targetColor; 175 175 vector<double> magnitudes; 176 176 QSize size; 177 bool rubberband;178 double falloff;177 bool const rubberband; 178 double const falloff; 179 179 }; 180 180 181 181 class MonoScope : public StereoScope
