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

List:       kde-commits
Subject:    extragear/multimedia/kmid
From:       Pedro Lopez-Cabanillas <pedro.lopez.cabanillas () gmail ! com>
Date:       2010-09-10 7:44:16
Message-ID: 20100910074416.A60A4AC884 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1173704 by pedrol:

Drumstick: sync to the latest 0.5 release. 
Removed unneeded headers and sources.
ALSA backend: Request realtime priority for the MIDI input thread, using the new drumstick API method.


 M  +3 -3      CMakeLists.txt  
 M  +1 -0      alsa/alsamidiobject.cpp  
 M  +2 -3      drumstick/CMakeLists.txt  
 M  +7 -28     drumstick/include/alsaclient.h  
 M  +5 -1      drumstick/include/alsaport.h  
 D             drumstick/include/drumstick.h  
 D             drumstick/include/qwrk.h  
 M  +164 -20   drumstick/src/alsaclient.cpp  
 M  +2 -1      drumstick/src/alsaqueue.cpp  
 M  +1 -0      drumstick/src/alsatimer.cpp  
 D             drumstick/src/qwrk.cpp  


--- trunk/extragear/multimedia/kmid/CMakeLists.txt #1173703:1173704
@@ -22,8 +22,8 @@
       set ( WITH_ALSA 1 )
       set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" )
       # Check for DRUMSTICK
-      pkg_check_modules(DRUMSTICK-FILE drumstick-file>=0.4)
-      pkg_check_modules(DRUMSTICK-ALSA drumstick-alsa>=0.4)
+      pkg_check_modules(DRUMSTICK-FILE drumstick-file>=0.5)
+      pkg_check_modules(DRUMSTICK-ALSA drumstick-alsa>=0.5)
       if (DRUMSTICK-ALSA_FOUND AND DRUMSTICK-FILE_FOUND)
         set ( DRUMSTICK_LIBRARIES
           ${DRUMSTICK-FILE_LIBRARIES}
@@ -63,7 +63,7 @@
   find_package (PkgConfig)
   if (PKG_CONFIG_FOUND)
     # Check for drumstick-file
-    pkg_check_modules(DRUMSTICK drumstick-file>=0.4)
+    pkg_check_modules(DRUMSTICK drumstick-file>=0.5)
   endif (PKG_CONFIG_FOUND)
   if (NOT DRUMSTICK_FOUND)
     add_definitions (-DDRUMSTICK_STATIC)
--- trunk/extragear/multimedia/kmid/alsa/alsamidiobject.cpp #1173703:1173704
@@ -184,6 +184,7 @@
         connect( d->m_player, SIGNAL(stopped()),
                  d->m_out, SLOT(allNotesOff()), Qt::QueuedConnection );
         d->m_client->setHandler(this);
+        d->m_client->setRealTimeInput(true);
         d->m_client->startSequencerInput();
     }
 
--- trunk/extragear/multimedia/kmid/drumstick/CMakeLists.txt #1173703:1173704
@@ -5,21 +5,20 @@
     ${CMAKE_CURRENT_SOURCE_DIR}/include
 )
 
+ADD_DEFINITIONS(-DRTKIT_SUPPORT)
+
 # drumstick-file library
 
 SET(drumstick-file_QTOBJ_SRCS
     include/qsmf.h
-    include/qwrk.h
 )
 
 SET(drumstick-file_HEADERS
     include/qsmf.h
-    include/qwrk.h
 )
 
 SET(drumstick-file_SRCS
     src/qsmf.cpp
-    src/qwrk.cpp
 )
 
 QT4_WRAP_CPP(drumstick-file_MOC_SRCS ${drumstick-file_QTOBJ_SRCS})
--- trunk/extragear/multimedia/kmid/drumstick/include/alsaclient.h #1173703:1173704
@@ -198,31 +198,7 @@
 class DRUMSTICK_EXPORT MidiClient : public QObject
 {
     Q_OBJECT
-
-private:
-    /**
-     * This class manages event input from the ALSA sequencer.
-     */
-    class SequencerInputThread: public QThread
-    {
     public:
-        SequencerInputThread(MidiClient *seq, int timeout)
-            : QThread(),
-            m_MidiClient(seq),
-            m_Wait(timeout),
-            m_Stopped(false) {}
-        virtual ~SequencerInputThread() {}
-        virtual void run();
-        bool stopped();
-        void stop();
-
-        MidiClient *m_MidiClient;
-        int m_Wait;
-        bool m_Stopped;
-        QReadWriteLock m_mutex;
-    };
-
-public:
     MidiClient( QObject* parent = 0 );
     virtual ~MidiClient();
 
@@ -313,6 +289,8 @@
     /** Sets a sequencer event handler enabling the callback delivery mode */
     void setHandler(SequencerEventHandler* handler)  { m_handler = handler; }
     bool parseAddress( const QString& straddr, snd_seq_addr& result );
+    void setRealTimeInput(bool enabled);
+    bool realTimeInputEnabled();
 
 signals:
     /** Signal emitted when an event is received */
@@ -344,6 +322,7 @@
     void disconnectTo(int myport, int client, int port);
 
 private:
+    class SequencerInputThread;
     bool m_eventsEnabled;
     bool m_BlockMode;
     bool m_NeedRefreshClientList;
@@ -365,11 +344,11 @@
 };
 
 #if SND_LIB_VERSION > 0x010004
-QString getRuntimeALSALibraryVersion();
-int getRuntimeALSALibraryNumber();
+DRUMSTICK_EXPORT QString getRuntimeALSALibraryVersion();
+DRUMSTICK_EXPORT int getRuntimeALSALibraryNumber();
 #endif
-QString getRuntimeALSADriverVersion();
-int getRuntimeALSADriverNumber();
+DRUMSTICK_EXPORT QString getRuntimeALSADriverVersion();
+DRUMSTICK_EXPORT int getRuntimeALSADriverNumber();
 
 } /* namespace drumstick */
 
--- trunk/extragear/multimedia/kmid/drumstick/include/alsaport.h #1173703:1173704
@@ -91,7 +91,11 @@
 protected:
     void readSubscribers(MidiClient* seq);
     void freeSubscribers();
-    /** Sets the client name. @see getClientName() */
+
+    /**
+     * Sets the client name. @see getClientName()
+     * @param name Client name
+     */
     void setClientName(QString name) { m_ClientName = name; }
 
 private:
--- trunk/extragear/multimedia/kmid/drumstick/src/alsaclient.cpp #1173703:1173704
@@ -25,8 +25,27 @@
 #include <QThread>
 #include <QReadLocker>
 #include <QWriteLocker>
+#if defined(RTKIT_SUPPORT)
+#include <QDBusConnection>
+#include <QDBusInterface>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <sys/resource.h>
+#endif
 #include <pthread.h>
 
+#ifndef RLIMIT_RTTIME
+#define RLIMIT_RTTIME 15
+#endif
+
+#ifndef SCHED_RESET_ON_FORK
+#define SCHED_RESET_ON_FORK 0x40000000
+#endif
+
+#ifndef DEFAULT_INPUT_TIMEOUT
+#define DEFAULT_INPUT_TIMEOUT 500
+#endif
+
 /**
  * @file alsaclient.cpp
  * Implementation of classes managing ALSA Sequencer clients
@@ -49,8 +68,8 @@
 /**
 @mainpage drumstick Documentation
 @author Copyright &copy; 2009-2010 Pedro López-Cabanillas &lt;plcl AT users.sf.net&gt;
-@date 2010-07-07
-@version 0.4.0
+@date 2010-09-09
+@version 0.5.0
 
 This document is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.
 To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/
@@ -164,6 +183,10 @@
 Cakewalk WRK file parse and print
 @include dumpwrk.h
 
+@example dumpove.cpp
+Overture OVE file parse and print
+@include dumpove.h
+
 @example metronome.cpp
 Simple command line MIDI metronome
 @include metronome.h
@@ -301,6 +324,31 @@
  */
 
 /**
+ * This class manages event input from the ALSA sequencer.
+ */
+class MidiClient::SequencerInputThread: public QThread
+{
+public:
+    SequencerInputThread(MidiClient *seq, int timeout)
+        : QThread(),
+        m_MidiClient(seq),
+        m_Wait(timeout),
+        m_Stopped(false),
+        m_RealTime(true) {}
+    virtual ~SequencerInputThread() {}
+    virtual void run();
+    bool stopped();
+    void stop();
+    void setRealtimePriority();
+
+    MidiClient *m_MidiClient;
+    int m_Wait;
+    bool m_Stopped;
+    bool m_RealTime;
+    QReadWriteLock m_mutex;
+};
+
+/**
  * Constructor.
  *
  * This constructor optionally gets a QObject parent. When you create a
@@ -346,6 +394,34 @@
 }
 
 /**
+ * Enables real-time priority for the MIDI input thread. The system needs either
+ * RLIMIT_RTPRIO or RealtimeKit. First RLIMIT_RTPRIO is tried, and if this
+ * method fails, RealtimeKit is used.
+ *
+ * @param enable real-time priority enabled
+ * @since 0.5.0
+ */
+void MidiClient::setRealTimeInput(bool enable)
+{
+    if (m_Thread == 0) {
+        m_Thread = new SequencerInputThread(this, DEFAULT_INPUT_TIMEOUT);
+        m_Thread->m_RealTime = enable;
+    }
+}
+
+/**
+ * Return the real-time priority setting for the MIDI input thread.
+ * @return true if the real-time priority is enabled
+ * @since 0.5.0
+ */
+bool MidiClient::realTimeInputEnabled()
+{
+    if (m_Thread == 0)
+        return true;
+    return m_Thread->m_RealTime;
+}
+
+/**
  * Open the sequencer device.
  *
  * When opening the MidiClient instance, several properties may optionally
@@ -677,10 +753,11 @@
 void
 MidiClient::startSequencerInput()
 {
-    if (m_Thread == NULL) {
-        m_Thread = new SequencerInputThread(this, 500);
-        m_Thread->start(QThread::TimeCriticalPriority);
+    if (m_Thread == 0) {
+        m_Thread = new SequencerInputThread(this, DEFAULT_INPUT_TIMEOUT);
     }
+    m_Thread->start( m_Thread->m_RealTime ?
+            QThread::TimeCriticalPriority : QThread::InheritPriority );
 }
 
 /**
@@ -690,7 +767,8 @@
 MidiClient::stopSequencerInput()
 {
     int counter = 0;
-    if (m_Thread != NULL) {
+    if (m_Thread != 0) {
+        if (m_Thread->isRunning()) {
         m_Thread->stop();
         while (!m_Thread->wait(500) && (counter < 10)) {
             counter++;
@@ -698,6 +776,7 @@
         if (!m_Thread->isFinished()) {
             m_Thread->terminate();
         }
+        }
         delete m_Thread;
     }
 }
@@ -1637,6 +1716,7 @@
  * @param straddr source text address representation
  * @param addr returned ALSA address record
  * @return true if the text address was successfully parsed
+ * @since 0.3.1
  */
 bool
 MidiClient::parseAddress( const QString& straddr, snd_seq_addr& addr )
@@ -1692,28 +1772,86 @@
     m_Stopped = true;
 }
 
-/**
- * Main input thread process loop.
- */
+#if defined(RTKIT_SUPPORT)
+static pid_t _gettid(void) {
+    return (pid_t) ::syscall(SYS_gettid);
+}
+#endif
+
 void
-MidiClient::SequencerInputThread::run()
+MidiClient::SequencerInputThread::setRealtimePriority()
 {
-    unsigned long npfd;
-    pollfd* pfd;
-    int rt;
     struct sched_param p;
-    Priority prio = priority();
+    int rt, policy = SCHED_RR | SCHED_RESET_ON_FORK;
+    quint32 priority = 6;
+#if defined(RTKIT_SUPPORT)
+    bool ok;
+    quint32 max_prio;
+    quint64 thread;
+    struct rlimit old_limit, new_limit;
+    long long max_rttime;
+#endif
 
-    if ( prio == TimeCriticalPriority ) {
         ::memset(&p, 0, sizeof(p));
-        p.sched_priority = 6;
-        rt = ::pthread_setschedparam(::pthread_self(), SCHED_FIFO, &p);
+    p.sched_priority = priority;
+    rt = ::pthread_setschedparam(::pthread_self(), policy, &p);
         if (rt != 0) {
-            qWarning() << "pthread_setschedparam(SCHED_FIFO) failed, err="
+#if defined(RTKIT_SUPPORT)
+        const QString rtkit_service =
+                QLatin1String("org.freedesktop.RealtimeKit1");
+        const QString rtkit_path =
+                QLatin1String("/org/freedesktop/RealtimeKit1");
+        const QString rtkit_iface = rtkit_service;
+        thread = _gettid();
+        QDBusConnection bus = QDBusConnection::systemBus();
+        QDBusInterface realtimeKit(rtkit_service, rtkit_path, rtkit_iface, bus);
+        QVariant maxRTPrio = realtimeKit.property("MaxRealtimePriority");
+        max_prio = maxRTPrio.toUInt(&ok);
+        if (!ok) {
+            qWarning() << "invalid property RealtimeKit.MaxRealtimePriority";
+            return;
+        }
+        if (priority > max_prio)
+            priority = max_prio;
+        QVariant maxRTNSec = realtimeKit.property("RTTimeNSecMax");
+        max_rttime = maxRTNSec.toLongLong(&ok);
+        if (!ok || max_rttime < 0) {
+            qWarning() << "invalid property RealtimeKit.RTTimeNSecMax";
+            return;
+        }
+        new_limit.rlim_cur = new_limit.rlim_max = max_rttime;
+        rt = ::getrlimit(RLIMIT_RTTIME, &old_limit);
+        if (rt < 0) {
+            qWarning() << "getrlimit() failed. err=" << rt << ::strerror(rt);
+            return;
+        }
+        rt = ::setrlimit(RLIMIT_RTTIME, &new_limit);
+        if ( rt < 0) {
+            qWarning() << "setrlimit() failed, err=" << rt << ::strerror(rt);
+            return;
+        }
+        QDBusMessage reply = realtimeKit.call("MakeThreadRealtime", thread, priority);
+        if (reply.type() == QDBusMessage::ErrorMessage )
+            qWarning() << "error returned by RealtimeKit.MakeThreadRealtime:"
+                        << reply.errorMessage();
+#else
+        qWarning() << "pthread_setschedparam() failed, err="
                        << rt << ::strerror(rt);
+#endif
         }
     }
 
+/**
+ * Main input thread process loop.
+ */
+void
+MidiClient::SequencerInputThread::run()
+{
+    unsigned long npfd;
+    pollfd* pfd;
+    if ( priority() == TimeCriticalPriority )
+        setRealtimePriority();
+
     if (m_MidiClient != NULL) {
         npfd = snd_seq_poll_descriptors_count(m_MidiClient->getHandle(), POLLIN);
         pfd = (pollfd *) alloca(npfd * sizeof(pollfd));
@@ -1722,7 +1860,7 @@
             snd_seq_poll_descriptors(m_MidiClient->getHandle(), pfd, npfd, POLLIN);
             while (!stopped() && (m_MidiClient != NULL))
             {
-                rt = poll(pfd, npfd, m_Wait);
+                int rt = poll(pfd, npfd, m_Wait);
                 if (rt > 0) {
                     m_MidiClient->doEvents();
                 }
@@ -2312,6 +2450,8 @@
 /**
  * Sets the output room size.
  * The output room is the minimum pool size for select/blocking mode.
+ *
+ * @param size Output room size
  */
 void
 PoolInfo::setOutputRoom(int size)
@@ -2333,6 +2473,7 @@
 /**
  * Gets the runtime ALSA library version string
  * @return string representing the runtime ALSA library version
+ * @since 0.3.0
  */
 QString
 getRuntimeALSALibraryVersion()
@@ -2343,6 +2484,7 @@
 /**
  * Gets the runtime ALSA library version number
  * @return integer representing the runtime ALSA library version
+ * @since 0.3.0
  */
 int
 getRuntimeALSALibraryNumber()
@@ -2362,11 +2504,12 @@
     }
     return result;
 }
-#endif
+#endif // SND_LIB_VERSION > 0x010004
 
 /**
  * Gets the runtime ALSA drivers version string
  * @return string representing the runtime ALSA drivers version
+ * @since 0.3.0
  */
 QString
 getRuntimeALSADriverVersion()
@@ -2385,6 +2528,7 @@
 /**
  * Gets the runtime ALSA drivers version number
  * @return integer representing the runtime ALSA drivers version
+ * @since 0.3.0
  */
 int
 getRuntimeALSADriverNumber()
--- trunk/extragear/multimedia/kmid/drumstick/src/alsaqueue.cpp #1173703:1173704
@@ -653,8 +653,9 @@
 }
 
 /**
- * Sets the timer identifier record
+ * Sets the timer identifier
  * @param id Timer identifier object
+ * @since 0.3.0
  */
 void QueueTimer::setId(const TimerId& id)
 {
--- trunk/extragear/multimedia/kmid/drumstick/src/alsatimer.cpp #1173703:1173704
@@ -1319,6 +1319,7 @@
  * Check and return the best available global TimerId in the system, meaning
  * the timer with higher frequency (or lesser period, resolution).
  * @return A TimerId object
+ * @since 0.3.0
  */
 TimerId
 Timer::bestGlobalTimerId()
[prev in list] [next in list] [prev in thread] [next in thread] 

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