[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    extragear/multimedia/kmid/win
From:       Pedro Lopez-Cabanillas <pedro.lopez.cabanillas () gmail ! com>
Date:       2010-10-31 10:28:10
Message-ID: 20101031102810.1EFB2AC89B () svn ! kde ! org
[Download RAW message or body]

SVN commit 1191538 by pedrol:

Windows backend. Fix for bug#255605: highlighted lyrics syllable randomly jumps when \
playing some songs having both Text and Lyric events. This bug hits all KMid \
backends.


 M  +25 -0     song.cpp  
 M  +4 -0      song.h  
 M  +38 -12    winmidiobject.cpp  
 M  +1 -0      winmidiobject.h  
 M  +0 -2      winmidioutput.cpp  


--- trunk/extragear/multimedia/kmid/win/song.cpp #1191537:1191538
@@ -98,6 +98,16 @@
         return m_packet.dwPacket;
     }
 
+    int SongEvent::getTag() const
+    {
+        return m_tag;
+    }
+
+    void SongEvent::setTag(int tag)
+    {
+        m_tag = tag;
+    }
+
     /* Song */
 
     static inline bool eventLessThan(const SongEvent* s1, const SongEvent* s2)
@@ -258,4 +268,19 @@
         return false;
     }
 
+    void Song::discardRedundantEvents(TextType type)
+    {
+        if (!m_text[Lyric].empty()) {
+            QMutableListIterator<SongEvent*> it(*this);
+            while (it.hasNext()) {
+                SongEvent *ev = it.next();
+                if ( ev->getType() == LYRIC_EVENT &&
+                     ev->getTag() != type ) {
+                    it.remove();
+                    delete ev;
 }
+            }
+        }
+    }
+
+}
--- trunk/extragear/multimedia/kmid/win/song.h #1191537:1191538
@@ -53,12 +53,15 @@
         int getDataLength() const;
         DWORD getPacket() const;
         void setTick(qint64 time);
+        int getTag() const;
+        void setTag(int tag);
 
     private:
         qint64 m_ticktime;
         SongEventType m_type;
         WinMIDIPacket m_packet;
         QByteArray m_data;
+        int m_tag;
     };
 
     class Song : public QList<SongEvent*>
@@ -105,6 +108,7 @@
         QTextCodec* getTextCodec() const { return m_codec; }
         QStringList getText(TextType type);
         QStringList getLyrics(qint64 time);
+        void discardRedundantEvents(TextType type);
 
     private:
         void appendStringToList(QStringList &list, QString &s, TextType type = \
                Text);
--- trunk/extragear/multimedia/kmid/win/winmidiobject.cpp #1191537:1191538
@@ -54,7 +54,9 @@
             m_beatCount(0),
             m_lowestMidiNote(127),
             m_highestMidiNote(0),
-            m_currentTicks(0)
+            m_currentTicks(0),
+            m_lyricsEventType(Song::Text),
+            m_lastLyrics(0)
         {
             m_dbgState[LoadingState]   = QLatin1String("Loading");
             m_dbgState[StoppedState]   = QLatin1String("Stopped");
@@ -95,7 +97,8 @@
         QMutex m_openMutex;
         QMap<uint,QByteArray> m_textUserEvents;
         QMap<State,QString> m_dbgState;
-
+        Song::TextType m_lyricsEventType;
+        qint64 m_lastLyrics;
     };
 
     WinMIDIObject::WinMIDIObject(QObject *parent) :
@@ -274,6 +277,8 @@
         d->m_highestMidiNote = 0;
         d->m_currentTicks = 0;
         d->m_textUserEvents.clear();
+        d->m_lyricsEventType = Song::Text;
+        d->m_lastLyrics = 0;
         for (int i=0; i<MIDI_CHANNELS; ++i) {
             d->m_channelUsed[i] = false;
             d->m_channelEvents[i] = 0;
@@ -299,8 +304,10 @@
         if ( !d->m_song.isEmpty() &&
              (d->m_state == PausedState || d->m_state == StoppedState) ) {
             d->m_out->setTimeDivision(d->m_song.getDivision());
-            if (currentTime() == 0)
+            if (currentTime() == 0) {
+                d->m_lastLyrics = 0;
                 d->m_out->setInitialTempo(d->m_initialTempo);
+            }
             d->m_out->sendResetMessage();
             d->m_out->resetControllers();
             sendInitialProgramChanges();
@@ -528,16 +535,13 @@
             d->m_song.addMetaData(static_cast<Song::TextType>(type), data, tick);
             switch ( type ) {
             case Song::Lyric:
+                d->m_lyricsEventType = Song::Lyric;
             case Song::Text:
                 if ((data.length() > 0) && (data[0] != '@') && (data[0] != '%') ) {
-                    if (d->m_textUserEvents.contains(tick))
-                        d->m_textUserEvents[tick] += data;
-                    else {
-                        SongEvent *ev = new SongEvent( LYRIC_EVENT );
+                    SongEvent *ev = new SongEvent( LYRIC_EVENT, data );
+                    ev->setTag(type);
                         appendEvent(ev);
-                        d->m_textUserEvents[tick] = data;
                     }
-                }
                 break;
             case Song::TrackName:
             case Song::InstrumentName:
@@ -631,7 +635,9 @@
                 d->m_engine->readFromFile(tmpFile);
                 if (!d->m_song.isEmpty()) {
                     addSongPadding();
+                    d->m_song.discardRedundantEvents(d->m_lyricsEventType);
                     d->m_song.sort();
+                    buildTextUserEventsMap();
                     if (d->m_initialTempo == 0) {
                         d->m_initialTempo = 500000;
                     }
@@ -718,7 +724,6 @@
     void WinMIDIObject::emitShortEvSignals(qint64 ticks, const WinMIDIPacket& \
packet)  {
         int value = 0;
-        QString txt;
         int type = MEVT_EVENTTYPE(packet.dwPacket);
         int parm = MEVT_EVENTPARM(packet.dwPacket);
         if ((type & MEVT_NOP) != 0) {
@@ -727,7 +732,8 @@
                 emit tick(ticks);
                 break;
             case 1:
-                if (d->m_textUserEvents.contains(ticks)) {
+                if (d->m_textUserEvents.contains(ticks) && ticks != d->m_lastLyrics) \
{ +                    QString txt;
                     if (d->m_codec == NULL)
                         txt = QString::fromAscii(d->m_textUserEvents[ticks]);
                     else
@@ -735,6 +741,7 @@
                     txt.remove(QRegExp("[/\\\\]+"));
                     txt.remove(QRegExp("[\r\n]+"));
                     emit midiText(Song::Lyric, txt);
+                    d->m_lastLyrics = ticks;
                 }
                 break;
             default:
@@ -811,12 +818,31 @@
 
     void WinMIDIObject::sendInitialProgramChanges()
     {
-        kDebug();
         for (int i = 0; i < MIDI_CHANNELS; ++i) {
             int patch(d->m_channelPatches[i]);
             d->m_out->sendInitialProgram(i, patch);
         }
     }
+
+    void WinMIDIObject::buildTextUserEventsMap()
+    {
+        d->m_textUserEvents.clear();
+        SongIterator it(d->m_song);
+        while (it.hasNext()) {
+            SongEvent *ev = it.next();
+            if (ev->getType() == LYRIC_EVENT &&
+                ev->getTag() == d->m_lyricsEventType) {
+                qint64 tick = ev->getTick();
+                QByteArray data = ev->getData();
+                if (data.isEmpty())
+                    continue;
+                if (d->m_textUserEvents.contains(tick))
+                    d->m_textUserEvents[tick] += data;
+                else
+                    d->m_textUserEvents[tick] = data;
 }
+        }
+    }
+}
 
 #include "winmidiobject.moc"
--- trunk/extragear/multimedia/kmid/win/winmidiobject.h #1191537:1191538
@@ -69,6 +69,7 @@
         QVariant channelProperty(int channel, const QString& key);
         void sendInitialProgramChanges();
         void emitShortEvSignals(qint64 ticks, const WinMIDIPacket& packet);
+        void buildTextUserEventsMap();
 
     public Q_SLOTS:
         void setTickInterval(qint32 interval);
--- trunk/extragear/multimedia/kmid/win/winmidioutput.cpp #1191537:1191538
@@ -607,7 +607,6 @@
                 d->m_locked[channel] = lock;
                 if (lock) {
                     d->m_lockedpgm[channel] = d->m_lastpgm[channel];
-                    kDebug() << channel << d->m_lastpgm[channel];
                 }
                 emit lockedChanged( channel, lock );
             }
@@ -900,7 +899,6 @@
     {
         int pgm(d->m_locked[chan] ? d->m_lockedpgm[chan] : program);
         if (pgm > -1) {
-            kDebug() << chan << pgm;
             WinMIDIPacket packet;
             packet.data[0] = MIDI_STATUS_PROGRAMCHANGE | (chan & MIDI_CHANNEL_MASK);
             packet.data[1] = pgm;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic