Ticket #9952: 0001-MythMusic-Correct-the-visualisation-drawing.patch

File 0001-MythMusic-Correct-the-visualisation-drawing.patch, 15.8 KB (added by Lawrence Rust <lvr@…>, 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;  
    2121#include <QCursor>
    2222#include <QPixmap>
    2323#include <QEvent>
     24#include <QMutexLocker>
    2425
    2526// mythtv
    2627#include <audiooutput.h>
    using namespace std;  
    4041VisFactory* VisFactory::g_pVisFactories = 0;
    4142
    4243VisualBase::VisualBase(bool screensaverenable)
    43     : xscreensaverenable(screensaverenable)
     44    : fps(20), xscreensaverenable(screensaverenable)
    4445{
    4546    if (!xscreensaverenable)
    4647        GetMythUI()->DoDisableScreensaver();
    void VisualBase::drawWarning(QPainter *p, const QColor &back, const QSize &size,  
    7778}
    7879
    7980MainVisual::MainVisual(QWidget *parent, const char *name)
    80     : QWidget(parent), vis(0), playing(FALSE), fps(20),
     81    : QWidget(parent), vis(0), playing(false), fps(20),
    8182      timer (0), bannerTimer(0), info_widget(0)
    8283{
    8384    setObjectName(name);
    MainVisual::MainVisual(QWidget *parent, const char *name)  
    103104
    104105MainVisual::~MainVisual()
    105106{
    106     if (vis)
    107     {
    108         delete vis;
    109         vis = 0;
    110     }
    111 
     107    delete vis;
    112108    delete info_widget;
    113     info_widget = 0;
    114 
    115109    delete timer;
    116     timer = 0;
    117 
    118110    delete bannerTimer;
    119     bannerTimer = 0;
    120111
    121112    while (!nodes.empty())
    122     {
    123         delete nodes.back();
    124         nodes.pop_back();
    125     }
     113        delete nodes.takeLast();
    126114}
    127115
    128116void MainVisual::setVisual(const QString &name)
    void MainVisual::setVisual(const QString &name)  
    165153    timer->start( 1000 / fps );
    166154}
    167155
     156// Caller holds mutex() lock
    168157void MainVisual::prepare()
    169158{
    170159    while (!nodes.empty())
    void MainVisual::prepare()  
    174163    }
    175164}
    176165
     166// Caller holds mutex() lock
    177167void MainVisual::add(uchar *b, unsigned long b_len, unsigned long w, int c, int p)
    178168{
    179169    long len = b_len, cnt;
    void MainVisual::add(uchar *b, unsigned long b_len, unsigned long w, int c, int  
    182172    len /= c;
    183173    len /= (p / 8);
    184174
    185     if (len > 512)
    186         len = 512;
     175#define SAMPLES 512
     176    if (len > SAMPLES)
     177        len = SAMPLES;
    187178
    188179    cnt = len;
    189180
    void MainVisual::add(uchar *b, unsigned long b_len, unsigned long w, int c, int  
    214205
    215206void MainVisual::timeout()
    216207{
    217     bool process = true;
    218208    if (parent() != GetMythMainWindow()->currentWidget())
    219     {
    220         process = false;
    221209        return;
    222     }
    223210
    224     VisualNode *node = NULL;
     211    VisualNode *node = 0;
    225212    if (playing && gPlayer->getOutput())
    226213    {
    227         long synctime = gPlayer->getOutput()->GetAudiotime();
    228         mutex()->lock();
    229         VisualNode *prev = NULL;
     214        int64_t synctime = gPlayer->getOutput()->GetAudiotime();
     215        QMutexLocker locker(mutex());
    230216        while (!nodes.empty())
    231217        {
    232             node = nodes.front();
    233             if (node->offset > synctime)
     218            VisualNode *n = nodes.front();
     219            if (n->offset > synctime)
    234220                break;
    235221            nodes.pop_front();
    236222
    237             if (prev)
    238                 delete prev;
    239             prev = node;
     223            delete node;
     224            node = n;
    240225        }
    241         mutex()->unlock();
    242         node = prev;
     226        if (node)
     227            nodes.push_front(node);
    243228    }
    244229
    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)
    252232    {
     233        stop = vis->process(node);
    253234        QPainter p(&pixmap);
    254235        if (vis->draw(&p, Qt::black))
    255236            update();
    void InfoWidget::paintEvent( QPaintEvent * )  
    509490    bitBlt(this, 0, 0, &info_pixmap);
    510491}
    511492
    512 StereoScope::StereoScope()
     493#define RUBBERBAND 0
     494#define TWOCOLOUR 0
     495StereoScope::StereoScope() :
     496    startColor(Qt::green), targetColor(Qt::red),
     497    rubberband(RUBBERBAND), falloff(1.0)
    513498{
    514499    fps = 45;
    515     rubberband = false;
    516     falloff = 1.0;
    517 
    518     startColor = Qt::green;
    519     targetColor = Qt::red;
    520500}
    521501
    522502StereoScope::~StereoScope()
    void StereoScope::resize( const QSize &newsize )  
    535515
    536516bool StereoScope::process( VisualNode *node )
    537517{
    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;
    543519
    544520    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            }
    591569
    592         if (valL != 0. || valR != 0.)
    593         allZero = FALSE;
     570            if (valL != 0. || valR != 0.)
     571                allZero = false;
    594572
    595         magnitudes[ i ] = valL;
    596         magnitudes[ i + size.width() ] = valR;
     573            magnitudes[ i ] = valL;
     574            magnitudes[ i + size.width() ] = valR;
    597575
    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;
    611577        }
     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            }
    612591
    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            }
    623602
    624         if (valL != 0. || valR != 0.)
    625         allZero = FALSE;
     603            if (valL != 0. || valR != 0.)
     604                allZero = false;
    626605
    627         magnitudes[ i ] = valL;
    628         magnitudes[ i + size.width() ] = valR;
    629     }
     606            magnitudes[ i ] = valL;
     607            magnitudes[ i + size.width() ] = valR;
     608        }
     609#endif
    630610    } 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.;
    633613    }
    634614
    635615    return allZero;
    bool StereoScope::process( VisualNode *node )  
    637617
    638618bool StereoScope::draw( QPainter *p, const QColor &back )
    639619{
    640     double r, g, b, per;
    641 
    642620    p->fillRect(0, 0, size.width(), size.height(), back);
    643621    for ( int i = 1; i < size.width(); i++ ) {
     622#if TWOCOLOUR
     623    double r, g, b, per;
     624
    644625    // left
    645626    per = double( magnitudes[ i ] * 2 ) /
    646627          double( size.height() / 4 );
    bool StereoScope::draw( QPainter *p, const QColor &back )  
    674655        b = 0;
    675656
    676657    p->setPen( QColor( int(r), int(g), int(b) ) );
    677         p->setPen(Qt::red);
     658#else
     659    p->setPen(Qt::red);
     660#endif
    678661    p->drawLine( i - 1, (int)((size.height() / 4) + magnitudes[i - 1]),
    679662             i, (int)((size.height() / 4) + magnitudes[i]));
    680663
     664#if TWOCOLOUR
    681665    // right
    682666    per = double( magnitudes[ i + size.width() ] * 2 ) /
    683667          double( size.height() / 4 );
    bool StereoScope::draw( QPainter *p, const QColor &back )  
    711695        b = 0;
    712696
    713697    p->setPen( QColor( int(r), int(g), int(b) ) );
    714         p->setPen(Qt::red);
     698#else
     699    p->setPen(Qt::red);
     700#endif
    715701    p->drawLine( i - 1, (int)((size.height() * 3 / 4) +
    716702             magnitudes[i + size.width() - 1]),
    717703             i, (int)((size.height() * 3 / 4) +
    MonoScope::~MonoScope()  
    731717
    732718bool MonoScope::process( VisualNode *node )
    733719{
    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;
    740721
    741722    if (node)
    742723    {
    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++)
    745727        {
    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);
    749731
     732            double val = 0;
     733#if RUBBERBAND
    750734            if ( rubberband )
    751735            {
    752736                val = magnitudes[ i ];
    bool MonoScope::process( VisualNode *node )  
    767751                    }
    768752                }
    769753            }
    770             else
     754#endif
     755            for (unsigned long s = (unsigned long)index; s < indexTo && s < node->length; s++)
    771756            {
    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] ) +
    778758                        (node->right ? double( node->right[s] ) : 0) *
    779759                        double( size.height() / 2 ) ) / 65536.;
    780760                if (tmp > 0)
    bool MonoScope::process( VisualNode *node )  
    789769
    790770            if ( val != 0. )
    791771            {
    792                 allZero = FALSE;
     772                allZero = false;
    793773            }
    794774            magnitudes[ i ] = val;
    795775            index = index + step;
    796776        }
    797777    }
     778#if RUBBERBAND
    798779    else if (rubberband)
    799780    {
    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 ];
    802783            if (val < 0) {
    803784                val += 2;
    804785                if (val > 0.)
    bool MonoScope::process( VisualNode *node )  
    810791            }
    811792
    812793            if ( val != 0. )
    813                 allZero = FALSE;
     794                allZero = false;
    814795            magnitudes[ i ] = val;
    815796        }
    816797    }
     798#endif
    817799    else
    818800    {
    819         for ( i = 0; i < size.width(); i++ )
     801        for (int i = 0; i < size.width(); i++ )
    820802            magnitudes[ i ] = 0.;
    821803    }
    822804
    bool MonoScope::process( VisualNode *node )  
    825807
    826808bool MonoScope::draw( QPainter *p, const QColor &back )
    827809{
    828     double r, g, b, per;
    829 
    830810    p->fillRect( 0, 0, size.width(), size.height(), back );
    831811    for ( int i = 1; i < size.width(); i++ ) {
     812#if TWOCOLOUR
     813        double r, g, b, per;
     814
    832815        per = double( magnitudes[ i ] ) /
    833816              double( size.height() / 4 );
    834817        if (per < 0.0)
    bool MonoScope::draw( QPainter *p, const QColor &back )  
    860843        else if (b < 0.0)
    861844            b = 0;
    862845
     846        p->setPen(QColor(int(r), int(g), int(b)));
     847#else
    863848        p->setPen(Qt::red);
    864         //p->setPen(QColor(int(r), int(g), int(b)));
     849#endif
    865850        p->drawLine( i - 1, (int)(size.height() / 2 + magnitudes[ i - 1 ]),
    866851                     i, (int)(size.height() / 2 + magnitudes[ i ] ));
    867852    }
  • 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:  
    5050    }
    5151
    5252    short *left, *right;
    53     long length, offset;
     53    unsigned long length, offset;
    5454
    5555};
    5656
    protected:  
    174174    QColor startColor, targetColor;
    175175    vector<double> magnitudes;
    176176    QSize size;
    177     bool rubberband;
    178     double falloff;
     177    bool const rubberband;
     178    double const falloff;
    179179};
    180180
    181181class MonoScope : public StereoScope