[SCM] libdrumstick/master: Imported Upstream version 1.0.2

alessio at users.alioth.debian.org alessio at users.alioth.debian.org
Tue Feb 16 10:36:58 UTC 2016


The following commit has been merged in the master branch:
commit 86e1f7fe4779efe0592b92862f92f561e27542af
Author: Alessio Treglia <alessio at debian.org>
Date:   Tue Feb 16 10:26:44 2016 +0000

    Imported Upstream version 1.0.2

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 930f9d5..38b9133 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
-# MIDI Sequencer C++ Library
-# Copyright (C) 2005-2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+# MIDI C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,187 +16,152 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA 02110-1301, USA
 
-# The name of our project is "DRUMSTICK". CMakeLists files in this project can
-# refer to the root source directory of the project as ${DRUMSTICK_SOURCE_DIR} 
-# and to the root binary directory of the project as ${DRUMSTICK_BINARY_DIR}
-PROJECT(DRUMSTICK)
-
-# CMake minimum version
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-IF(COMMAND CMAKE_POLICY)
-    CMAKE_POLICY(SET CMP0003 NEW)
-ENDIF(COMMAND CMAKE_POLICY)
-
-IF(CMAKE_SIZEOF_VOID_P MATCHES "8")
-    SET(_INIT_LIB_SUFFIX "64")
-ELSE(CMAKE_SIZEOF_VOID_P MATCHES "8")
-    SET(_INIT_LIB_SUFFIX "")
-ENDIF(CMAKE_SIZEOF_VOID_P MATCHES "8")
-SET(LIB_SUFFIX ${_INIT_LIB_SUFFIX} CACHE STRING "optional library install directory suffix: 32, 64, none")
-
-#Comment out if relative paths break the link scripts
-#SET(CMAKE_USE_RELATIVE_PATHS OFF)
-
-# Assorted settings
-SET(CMAKE_COLOR_MAKEFILE ON)
-SET(CMAKE_INCLUDE_CURRENT_DIR TRUE)
-#SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
-SET(CMAKE_SKIP_RULE_DEPENDENCY FALSE)
-SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
-SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
+cmake_minimum_required(VERSION 2.8.11)
+project(DRUMSTICK)
+
+if(CMAKE_SIZEOF_VOID_P MATCHES "8")
+    set(_INIT_LIB_SUFFIX "64")
+else()
+    set(_INIT_LIB_SUFFIX "")
+endif()
+set(LIB_SUFFIX ${_INIT_LIB_SUFFIX} CACHE STRING "optional library install directory suffix: 32, 64, none")
+
+set(CMAKE_COLOR_MAKEFILE ON)
+#set(CMAKE_VERBOSE_MAKEFILE ON)
+set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
+set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
+set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
 
 # Additional CMake modules for 3rd party library checks reside here
-SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_admin")
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_admin")
 
 # DRUMSTICK version string
-SET (VERSION_MAJOR "0")
-SET (VERSION_MINOR "5")
-SET (VERSION_PATCH "0")
-SET (VERSION_SUFFIX "")
-SET (VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX})
+set(VERSION_MAJOR "1")
+set(VERSION_MINOR "0")
+set(VERSION_PATCH "2")
+set(VERSION_SUFFIX "")
+set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${VERSION_SUFFIX})
+add_definitions(-DVERSION=${VERSION})
+
+message(STATUS "drumstick ${VERSION} prefix: ${CMAKE_INSTALL_PREFIX}")
 
-MESSAGE(STATUS "drumstick ${VERSION} prefix: ${CMAKE_INSTALL_PREFIX}")
+set(_DBUS_INIT OFF)
+if(${CMAKE_SYSTEM} MATCHES "Linux")
+	set(_DBUS_INIT ON)
+endif()
 
 # User options
-OPTION(STATIC_DRUMSTICK "Build static libraries instead of dynamic" OFF)
-OPTION(USE_DBUS "Include DBus support (required for RealtimeKit)" ON)
-
-MESSAGE(STATUS "Build configuration: ${CMAKE_BUILD_TYPE}")
-
-# LIBRARY BUILD TYPE
-IF(STATIC_DRUMSTICK)
-    SET(BUILD_SHARED_LIBS OFF)
-    add_definitions (-DDRUMSTICK_STATIC)
-    MESSAGE(STATUS "Building static libraries")
-ELSE(STATIC_DRUMSTICK)
-    SET(BUILD_SHARED_LIBS ON)
-    MESSAGE(STATUS "Building dynamic libraries")
-ENDIF(STATIC_DRUMSTICK)
-
-# Check for Qt
-SET(QT_MIN_VERSION "4.4.0")
-FIND_PACKAGE(Qt4 REQUIRED)
-IF(QT4_FOUND)
-    MESSAGE (STATUS "Found Qt4 ${QT_EDITION} version = ${QTVERSION}")
-    SET (QT_USE_QTSVG TRUE)
-    IF (USE_DBUS)
-        SET(QT_USE_QTDBUS TRUE)
-        ADD_DEFINITIONS(-DRTKIT_SUPPORT)
-    ENDIF (USE_DBUS)
-    INCLUDE (${QT_USE_FILE})
-    INCLUDE_DIRECTORIES (${QT_INCLUDES}) 
-    LINK_DIRECTORIES (${QT_LIBRARY_DIR})
-    LINK_LIBRARIES (${QT_LIBRARIES})
-    ADD_DEFINITIONS (-DQT_STRICT_ITERATORS)
-ELSE(QT4_FOUND)
-    MESSAGE(FATAL_ERROR "Qt4 not found")
-ENDIF(QT4_FOUND)
-
-# Check for PKG-CONFIG
-FIND_PACKAGE(PkgConfig REQUIRED)
-IF(PKG_CONFIG_FOUND)
-    MESSAGE(STATUS "Program pkg-config found (${PKG_CONFIG_EXECUTABLE})")
-ELSE(PKG_CONFIG_FOUND)
-    MESSAGE(FATAL_ERROR "Program pkg-config not found")
-ENDIF(PKG_CONFIG_FOUND)
-
-# Initialize some variables
-SET(HAVE_ALSA FALSE)
-
-# Check for ALSA 1.0.0
-PKG_CHECK_MODULES(ALSA alsa>=1.0.0)
-IF(ALSA_FOUND)
-    SET(HAVE_ALSA TRUE)
-    ADD_DEFINITIONS(-DHAVE_ALSA)
-    SET(ALSA_LIBS ${ALSA_LIBRARIES})
-    LIST(APPEND ALSA_LIB_DIR ${ALSA_LIBRARY_DIRS} ${ALSA_LIBDIR})
-    LIST(APPEND ALSA_INC_DIR ${ALSA_INCLUDE_DIRS} ${ALSA_INCLUDEDIR})
-ELSE(ALSA_FOUND)
-    MESSAGE(STATUS "Warning: ALSA library not found.")
-ENDIF(ALSA_FOUND)
-
-LINK_DIRECTORIES (
-    ${DRUMSTICK_BINARY_DIR}/lib
-    ${ALSA_LIB_DIR}
-)
-
-INCLUDE_DIRECTORIES ( BEFORE 
+option(STATIC_DRUMSTICK "Build static libraries instead of dynamic" OFF)
+option(USE_DBUS "Include DBus support (required for RealtimeKit)" ${_DBUS_INIT})
+
+message(STATUS "Build configuration: ${CMAKE_BUILD_TYPE}")
+
+if(STATIC_DRUMSTICK)
+    set(BUILD_SHARED_LIBS OFF)
+    add_definitions(-DDRUMSTICK_STATIC)
+    message(STATUS "Building static libraries")
+else()
+    set(BUILD_SHARED_LIBS ON)
+    message(STATUS "Building dynamic libraries")
+endif()
+
+find_package(Qt5Core REQUIRED)
+message(STATUS "Found Qt5 version = ${Qt5Core_VERSION_STRING}")
+
+if(USE_DBUS)
+    find_package(Qt5DBus REQUIRED)
+    add_definitions(-DRTKIT_SUPPORT)
+endif()
+
+find_package(PkgConfig REQUIRED)
+if(PKG_CONFIG_FOUND)
+    message(STATUS "Program pkg-config found (${PKG_CONFIG_EXECUTABLE})")
+else()
+    message(FATAL_ERROR "Program pkg-config not found")
+endif()
+
+if(${CMAKE_SYSTEM} MATCHES "Linux")
+    pkg_check_modules(ALSA alsa>=1.0.0)
+    if(ALSA_FOUND)
+        set(ALSA_LIBS ${ALSA_LIBRARIES})
+        list(APPEND ALSA_LIB_DIR ${ALSA_LIBRARY_DIRS} ${ALSA_LIBDIR})
+        list(APPEND ALSA_INC_DIR ${ALSA_INCLUDE_DIRS} ${ALSA_INCLUDEDIR})
+    else()
+        message(STATUS "Warning: ALSA library not found.")
+    endif()
+endif()
+
+link_directories(${DRUMSTICK_BINARY_DIR}/lib)
+include_directories( BEFORE
     ${DRUMSTICK_SOURCE_DIR}/library
-    ${DRUMSTICK_SOURCE_DIR}/library/include
-    ${ALSA_INC_DIR}
-)
-
-if (CMAKE_COMPILER_IS_GNUCXX)
-# exceptions are needed by this library, please don't try to disable them!
-  set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions -UQT_NO_EXCEPTIONS")
-  if (NOT WIN32)
-    include (CheckCXXCompilerFlag)
-    check_cxx_compiler_flag (-fvisibility=hidden _HAVE_GCC_VISIBILITY)
-    if (_HAVE_GCC_VISIBILITY)
-      set (CMAKE_CXX_FLAGS 
-           "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden")
-    endif (_HAVE_GCC_VISIBILITY)
-    set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
-  endif (NOT WIN32)
-endif (CMAKE_COMPILER_IS_GNUCXX)
-
-ADD_SUBDIRECTORY(library)
-ADD_SUBDIRECTORY(utils)
-ADD_SUBDIRECTORY(icons)
-IF(${CMAKE_SYSTEM} MATCHES "Linux")
-    FIND_PACKAGE(Doxygen)
-    IF(DOXYGEN_FOUND)
-        CONFIGURE_FILE(
+    ${DRUMSTICK_SOURCE_DIR}/library/include)
+
+add_subdirectory(library)
+add_subdirectory(utils)
+add_subdirectory(icons)
+
+if(${CMAKE_SYSTEM} MATCHES "Linux")
+    find_package(Doxygen)
+    if(DOXYGEN_FOUND)
+        configure_file(
             "${CMAKE_SOURCE_DIR}/Doxyfile.in"
             "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile"
             IMMEDIATE @ONLY)
-        ADD_CUSTOM_TARGET ( doxygen
+        add_custom_target(doxygen
             ${DOXYGEN} Doxyfile
-            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-        )
-    ENDIF(DOXYGEN_FOUND)
-    ADD_SUBDIRECTORY(doc)
-ENDIF(${CMAKE_SYSTEM} MATCHES "Linux")
-
-CONFIGURE_FILE(drumstick-alsa.pc.in drumstick-alsa.pc IMMEDIATE @ONLY)
-CONFIGURE_FILE(drumstick-file.pc.in drumstick-file.pc IMMEDIATE @ONLY)
-CONFIGURE_FILE(drumstick.spec.in drumstick.spec IMMEDIATE @ONLY)
-INSTALL( FILES 
+            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+    endif()
+    add_subdirectory(doc)
+    configure_file(drumstick-alsa.pc.in drumstick-alsa.pc IMMEDIATE @ONLY)
+    configure_file(drumstick.spec.in drumstick.spec IMMEDIATE @ONLY)
+    install(FILES
+	${CMAKE_CURRENT_BINARY_DIR}/drumstick-alsa.pc
+	DESTINATION lib${LIB_SUFFIX}/pkgconfig )
+    # XML mime types
+    set( SHARED_MIME_INFO_MINIMUM_VERSION "0.30" )
+    set( XDG_MIME_INSTALL_DIR "share/mime/packages" )
+    find_package( SharedMimeInfo )
+    if( SHARED_MIME_INFO_FOUND )
+        install( FILES drumstick.xml DESTINATION ${XDG_MIME_INSTALL_DIR} )
+        update_xdg_mimetypes( ${XDG_MIME_INSTALL_DIR} )
+    endif()
+endif()
+
+configure_file(drumstick-file.pc.in drumstick-file.pc IMMEDIATE @ONLY)
+install(FILES
     ${CMAKE_CURRENT_BINARY_DIR}/drumstick-file.pc
-    ${CMAKE_CURRENT_BINARY_DIR}/drumstick-alsa.pc
     DESTINATION lib${LIB_SUFFIX}/pkgconfig )
 
-# XML mime types
-set( SHARED_MIME_INFO_MINIMUM_VERSION "0.30" )
-set( XDG_MIME_INSTALL_DIR "share/mime/packages" ) 
-find_package( SharedMimeInfo )
-if( SHARED_MIME_INFO_FOUND )
-    install( FILES drumstick.xml DESTINATION ${XDG_MIME_INSTALL_DIR} ) 
-    update_xdg_mimetypes( ${XDG_MIME_INSTALL_DIR} )     
-endif( SHARED_MIME_INFO_FOUND )
+configure_file(drumstick-rt.pc.in drumstick-rt.pc IMMEDIATE @ONLY)
+install(FILES
+    ${CMAKE_CURRENT_BINARY_DIR}/drumstick-rt.pc
+    DESTINATION lib${LIB_SUFFIX}/pkgconfig )
 
 # uninstall custom target
-CONFIGURE_FILE(
+configure_file(
     "${CMAKE_SOURCE_DIR}/cmake_admin/cmake_uninstall.cmake.in"
     "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
     IMMEDIATE @ONLY)
 
-ADD_CUSTOM_TARGET ( uninstall
+add_custom_target( uninstall
     "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
 
-IF(${CMAKE_SYSTEM} MATCHES "Linux")
+if(${CMAKE_SYSTEM} MATCHES "Linux")
     # tarball target
-    ADD_CUSTOM_TARGET ( tarball
+    add_custom_target( tarball
         COMMAND mkdir -p drumstick-${VERSION}
         COMMAND cp -r cmake_admin drumstick-${VERSION}
         COMMAND cp -r library drumstick-${VERSION}
         COMMAND cp -r utils drumstick-${VERSION}
         COMMAND cp -r doc drumstick-${VERSION}
         COMMAND cp -r icons drumstick-${VERSION}
-        COMMAND cp CMakeLists.txt AUTHORS COPYING ChangeLog INSTALL NEWS README TODO drumstick*.in drumstick.pro drumstick.xml configure* Doxyfile.in link-drumstick chkcoverage drumstick-${VERSION}
+        COMMAND cp CMakeLists.txt AUTHORS COPYING ChangeLog INSTALL NEWS README TODO drumstick*.in drumstick.pro drumstick.xml configure* Doxyfile.in chkcoverage global.pri drumstick-${VERSION}
         COMMAND tar -cj --exclude=.[a-z]* -f drumstick-${VERSION}.tar.bz2 drumstick-${VERSION}
         COMMAND tar -cz --exclude=.[a-z]* -f drumstick-${VERSION}.tar.gz  drumstick-${VERSION}
+        COMMAND zip -qr drumstick-${VERSION}.zip drumstick-${VERSION} -x '.[a-z]*'
         COMMAND rm -rf drumstick-${VERSION}
         WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
     )
-ENDIF(${CMAKE_SYSTEM} MATCHES "Linux")
+endif()
diff --git a/ChangeLog b/ChangeLog
index 5336ab3..6bd43a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,48 @@
+2015-12-29
+    * release 1.0.2
+
+2015-10-10
+    * RT library: fixed ticket #6 - MIDI input connection on Mac OSX
+
+2015-08-20
+    * release 1.0.1
+
+2015-04-26
+    * RT library: fixed ticket #4: ALSA Midi Input not working
+
+2014-11-22
+    * RT library: fixed windows midi input
+
+2014-08-30
+    * release 1.0.0
+
+2014-08-02
+    * vpiano using RT library
+
+2014-07-26
+    * documentation updates
+
+2014-04-27
+    * RT library: OSS backend
+
+2014-04-13
+    * RT library: FluidSynth backend
+
+2014-03-30
+    * RT library: Windows backend
+
+2014-02-09
+    * RT library: Mac OSX backend
+
+2014-02-09
+    * RT library: Network and ALSA backends
+
+2013-12-31
+    * Qt5 compatibility
+
+2010-09-13
+    * fixed dumpove: file header text
+
 2010-09-08
     * documentation updated
     * release 0.5.0
diff --git a/Doxyfile.in b/Doxyfile.in
index 80a2e49..0ed408b 100644
--- a/Doxyfile.in
+++ b/Doxyfile.in
@@ -795,7 +795,8 @@ HTML_FOOTER =
 # the style sheet file to the HTML output directory, so don't put your own 
 # stylesheet in the HTML output directory as well, or it will be erased!
 
-HTML_STYLESHEET = @CMAKE_SOURCE_DIR@/doc/doxygen.css
+# HTML_STYLESHEET = @CMAKE_SOURCE_DIR@/doc/doxygen.css
+HTML_STYLESHEET =
 
 # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
 # files or namespaces will be aligned in HTML using tables. If set to 
diff --git a/INSTALL b/INSTALL
index 06087f8..f1183d9 100644
--- a/INSTALL
+++ b/INSTALL
@@ -25,8 +25,8 @@ Requirements
 
 Minimum supported versions:
 
-* CMake 2.6
-* Qt4 4.4
+* CMake 2.8.11
+* Qt5
 * For Linux: ALSA 1.0
 
 * shared-mime-info 0.30
diff --git a/cmake_admin/CreateManpages.cmake b/cmake_admin/CreateManpages.cmake
index 948875a..c5d3478 100644
--- a/cmake_admin/CreateManpages.cmake
+++ b/cmake_admin/CreateManpages.cmake
@@ -1,5 +1,5 @@
 # MIDI Sequencer C++ Library 
-# Copyright (C) 2008-2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+# Copyright (C) 2008-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/cmake_admin/FindPCHSupport.cmake b/cmake_admin/FindPCHSupport.cmake
index 8374768..4d11610 100644
--- a/cmake_admin/FindPCHSupport.cmake
+++ b/cmake_admin/FindPCHSupport.cmake
@@ -1,5 +1,5 @@
 # MIDI Sequencer C++ Library 
-# Copyright (C) 2008-2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+# Copyright (C) 2008-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 39c19ac..65b7576 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -1,5 +1,5 @@
 # MIDI Sequencer C++ Library 
-# Copyright (C) 2008-2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+# Copyright (C) 2008-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -37,10 +37,6 @@ IF(XSLTPROC_EXECUTABLE)
         ${CMAKE_CURRENT_BINARY_DIR}/drumstick-guiplayer.xml IMMEDIATE @ONLY)
     CONFIGURE_FILE(drumstick-sysinfo.xml.in 
         ${CMAKE_CURRENT_BINARY_DIR}/drumstick-sysinfo.xml IMMEDIATE @ONLY)
-    CONFIGURE_FILE(drumstick-testevents.xml.in 
-        ${CMAKE_CURRENT_BINARY_DIR}/drumstick-testevents.xml IMMEDIATE @ONLY)
-    CONFIGURE_FILE(drumstick-timertest.xml.in 
-        ${CMAKE_CURRENT_BINARY_DIR}/drumstick-timertest.xml IMMEDIATE @ONLY)
     CONFIGURE_FILE(drumstick-vpiano.xml.in 
         ${CMAKE_CURRENT_BINARY_DIR}/drumstick-vpiano.xml IMMEDIATE @ONLY)
     INCLUDE(CreateManpages)
@@ -55,8 +51,6 @@ IF(XSLTPROC_EXECUTABLE)
         ${CMAKE_CURRENT_BINARY_DIR}/drumstick-playsmf.xml
         ${CMAKE_CURRENT_BINARY_DIR}/drumstick-guiplayer.xml
         ${CMAKE_CURRENT_BINARY_DIR}/drumstick-sysinfo.xml
-        ${CMAKE_CURRENT_BINARY_DIR}/drumstick-testevents.xml
-        ${CMAKE_CURRENT_BINARY_DIR}/drumstick-timertest.xml
         ${CMAKE_CURRENT_BINARY_DIR}/drumstick-vpiano.xml 
     )
 ELSE(XSLTPROC_EXECUTABLE)
diff --git a/doc/doxygen.css b/doc/doxygen.css
deleted file mode 100644
index d58b7f6..0000000
--- a/doc/doxygen.css
+++ /dev/null
@@ -1,441 +0,0 @@
-body, table, div, p, dl {
-	font-family: Lucida, Verdana, Geneva, Arial, sans-serif;
-	/* font-size: 12px; */
-}
-
-/* @group Heading Levels */
-
-h1 {
-	text-align: center;
-	font-size: 150%;
-}
-
-h2 {
-	font-size: 120%;
-}
-
-h3 {
-	font-size: 100%;
-}
-
-/* @end */
-
-caption {
-	font-weight: bold;
-}
-
-div.qindex, div.navtab{
-	background-color: #e8eef2;
-	border: 1px solid #84b0c7;
-	text-align: center;
-	margin: 2px;
-	padding: 2px;
-}
-
-div.qindex, div.navpath {
-	width: 100%;
-	line-height: 140%;
-}
-
-div.navtab {
-	margin-right: 15px;
-}
-
-/* @group Link Styling */
-
-a {
-	color: #153788;
-	font-weight: normal;
-	text-decoration: none;
-}
-
-.contents a:visited {
-	color: #1b77c5;
-}
-
-a:hover {
-	text-decoration: underline;
-}
-
-a.qindex {
-	font-weight: bold;
-}
-
-a.qindexHL {
-	font-weight: bold;
-	background-color: #6666cc;
-	color: #ffffff;
-	border: 1px double #9295C2;
-}
-
-.contents a.qindexHL:visited {
-        color: #ffffff;
-}
-
-a.el {
-	font-weight: bold;
-}
-
-a.elRef {
-}
-
-a.code {
-}
-
-a.codeRef {
-}
-
-/* @end */
-
-dl.el {
-	margin-left: -1cm;
-}
-
-.fragment {
-	font-family: monospace, fixed;
-	font-size: 105%;
-}
-
-pre.fragment {
-	border: 1px solid #CCCCCC;
-	background-color: #f5f5f5;
-	padding: 4px 6px;
-	margin: 4px 8px 4px 2px;
-}
-
-div.ah {
-	background-color: black;
-	font-weight: bold;
-	color: #ffffff;
-	margin-bottom: 3px;
-	margin-top: 3px
-}
-
-div.groupHeader {
-	margin-left: 16px;
-	margin-top: 12px;
-	margin-bottom: 6px;
-	font-weight: bold;
-}
-
-div.groupText {
-	margin-left: 16px;
-	font-style: italic;
-}
-
-body {
-	background: white;
-	color: black;
-	margin-right: 20px;
-	margin-left: 20px;
-}
-
-td.indexkey {
-	background-color: #e8eef2;
-	font-weight: bold;
-	border: 1px solid #CCCCCC;
-	margin: 2px 0px 2px 0;
-	padding: 2px 10px;
-}
-
-td.indexvalue {
-	background-color: #e8eef2;
-	border: 1px solid #CCCCCC;
-	padding: 2px 10px;
-	margin: 2px 0px;
-}
-
-tr.memlist {
-	background-color: #f0f0f0;
-}
-
-p.formulaDsp {
-	text-align: center;
-}
-
-img.formulaDsp {
-	
-}
-
-img.formulaInl {
-	vertical-align: middle;
-}
-
-/* @group Code Colorization */
-
-span.keyword {
-	color: #008000
-}
-
-span.keywordtype {
-	color: #604020
-}
-
-span.keywordflow {
-	color: #e08000
-}
-
-span.comment {
-	color: #800000
-}
-
-span.preprocessor {
-	color: #806020
-}
-
-span.stringliteral {
-	color: #002080
-}
-
-span.charliteral {
-	color: #008080
-}
-
-span.vhdldigit { 
-	color: #ff00ff 
-}
-
-span.vhdlchar { 
-	color: #000000 
-}
-
-span.vhdlkeyword { 
-	color: #700070 
-}
-
-span.vhdllogic { 
-	color: #ff0000 
-}
-
-/* @end */
-
-.search {
-	color: #003399;
-	font-weight: bold;
-}
-
-form.search {
-	margin-bottom: 0px;
-	margin-top: 0px;
-}
-
-input.search {
-	font-size: 75%;
-	color: #000080;
-	font-weight: normal;
-	background-color: #e8eef2;
-}
-
-td.tiny {
-	font-size: 75%;
-}
-
-.dirtab {
-	padding: 4px;
-	border-collapse: collapse;
-	border: 1px solid #84b0c7;
-}
-
-th.dirtab {
-	background: #e8eef2;
-	font-weight: bold;
-}
-
-hr {
-	height: 0;
-	border: none;
-	border-top: 1px solid #666;
-}
-
-/* @group Member Descriptions */
-
-.mdescLeft, .mdescRight,
-.memItemLeft, .memItemRight,
-.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
-	background-color: #FAFAFA;
-	border: none;
-	margin: 4px;
-	padding: 1px 0 0 8px;
-}
-
-.mdescLeft, .mdescRight {
-	padding: 0px 8px 4px 8px;
-	color: #555;
-}
-
-.memItemLeft, .memItemRight, .memTemplParams {
-	border-top: 1px solid #ccc;
-}
-
-.memTemplParams {
-	color: #606060;
-}
-
-/* @end */
-
-/* @group Member Details */
-
-/* Styles for detailed member documentation */
-
-.memtemplate {
-	font-size: 80%;
-	color: #606060;
-	font-weight: normal;
-	margin-left: 3px;
-}
-
-.memnav {
-	background-color: #e8eef2;
-	border: 1px solid #84b0c7;
-	text-align: center;
-	margin: 2px;
-	margin-right: 15px;
-	padding: 2px;
-}
-
-.memitem {
-	padding: 0;
-}
-
-.memname {
-	white-space: nowrap;
-	font-weight: bold;
-}
-
-.memproto, .memdoc {
-	border: 1px solid #84b0c7;	
-}
-
-.memproto {
-	padding: 0;
-	background-color: #d5e1e8;
-	font-weight: bold;
-	-webkit-border-top-left-radius: 8px;
-	-webkit-border-top-right-radius: 8px;
-	-moz-border-radius-topleft: 8px;
-	-moz-border-radius-topright: 8px;
-}
-
-.memdoc {
-	padding: 2px 5px;
-	background-color: #eef3f5;
-	border-top-width: 0;
-	-webkit-border-bottom-left-radius: 8px;
-	-webkit-border-bottom-right-radius: 8px;
-	-moz-border-radius-bottomleft: 8px;
-	-moz-border-radius-bottomright: 8px;
-}
-
-.paramkey {
-	text-align: right;
-}
-
-.paramtype {
-	white-space: nowrap;
-}
-
-.paramname {
-	color: #602020;
-	white-space: nowrap;
-}
-.paramname em {
-	font-style: normal;
-}
-
-/* @end */
-
-/* @group Directory (tree) */
-
-/* for the tree view */
-
-.ftvtree {
-	font-family: sans-serif;
-	margin: 0.5em;
-}
-
-/* these are for tree view when used as main index */
-
-.directory {
-	font-size: 9pt;
-	font-weight: bold;
-}
-
-.directory h3 {
-	margin: 0px;
-	margin-top: 1em;
-	font-size: 11pt;
-}
-
-/*
-The following two styles can be used to replace the root node title
-with an image of your choice.  Simply uncomment the next two styles,
-specify the name of your image and be sure to set 'height' to the
-proper pixel height of your image.
-*/
-
-/*
-.directory h3.swap {
-	height: 61px;
-	background-repeat: no-repeat;
-	background-image: url("yourimage.gif");
-}
-.directory h3.swap span {
-	display: none;
-}
-*/
-
-.directory > h3 {
-	margin-top: 0;
-}
-
-.directory p {
-	margin: 0px;
-	white-space: nowrap;
-}
-
-.directory div {
-	display: none;
-	margin: 0px;
-}
-
-.directory img {
-	vertical-align: -30%;
-}
-
-/* these are for tree view when not used as main index */
-
-.directory-alt {
-	font-size: 100%;
-	font-weight: bold;
-}
-
-.directory-alt h3 {
-	margin: 0px;
-	margin-top: 1em;
-	font-size: 11pt;
-}
-
-.directory-alt > h3 {
-	margin-top: 0;
-}
-
-.directory-alt p {
-	margin: 0px;
-	white-space: nowrap;
-}
-
-.directory-alt div {
-	display: none;
-	margin: 0px;
-}
-
-.directory-alt img {
-	vertical-align: -30%;
-}
-
-/* @end */
-
-address {
-	font-style: normal;
-	color: #333;
-}
diff --git a/drumstick-alsa.pc.in b/drumstick-alsa.pc.in
index ee28a7e..e240a0d 100644
--- a/drumstick-alsa.pc.in
+++ b/drumstick-alsa.pc.in
@@ -1,12 +1,12 @@
 prefix=@CMAKE_INSTALL_PREFIX@
 exec_prefix=${prefix}
-libdir=${prefix}/@LIB@
-includedir=${prefix}/include/drumstick
+libdir=${prefix}/lib at LIB_SUFFIX@
+includedir=${prefix}/include
 
 Name: drumstick-alsa
 Version: @VERSION@
-Description: MIDI Sequencer C++ Library Bindings for ALSA and Qt4
+Description: MIDI Sequencer C++ Library Bindings for ALSA and Qt5
 URL: http://sourceforge.net/projects/drumstick
-Requires: alsa >= 1.0.0, QtCore >= 4.4.0, QtGui >= 4.4.0, QtDBus >= 4.4.0
-Libs: -L${libdir} -ldrumstick-alsa -lQtCore -lQtDBus
+Requires: alsa >= 1.0.0, Qt5Core >= 5.0, Qt5DBus >= 5.0
+Libs: -L${libdir} -ldrumstick-alsa
 Cflags: -I${includedir}
diff --git a/drumstick-file.pc.in b/drumstick-file.pc.in
index 6e5baae..fa32ccb 100644
--- a/drumstick-file.pc.in
+++ b/drumstick-file.pc.in
@@ -1,12 +1,11 @@
 prefix=@CMAKE_INSTALL_PREFIX@
 exec_prefix=${prefix}
-libdir=${prefix}/@LIB@
-includedir=${prefix}/include/drumstick
+libdir=${prefix}/lib at LIB_SUFFIX@
+includedir=${prefix}/include
 
 Name: drumstick-file
 Version: @VERSION@
-Description: MIDI Sequencer C++ Library Bindings for Qt4
+Description: MIDI Sequencer C++ Library Bindings for Qt5
 URL: http://sourceforge.net/projects/drumstick
-Requires: QtCore >= 4.4.0, QtGui >= 4.4.0 
-Libs: -L${libdir} -ldrumstick-file -lQtCore
+Libs: -L${libdir} -ldrumstick-file
 Cflags: -I${includedir}
diff --git a/drumstick-rt.pc.in b/drumstick-rt.pc.in
new file mode 100644
index 0000000..dfb64b7
--- /dev/null
+++ b/drumstick-rt.pc.in
@@ -0,0 +1,11 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${prefix}/lib at LIB_SUFFIX@
+includedir=${prefix}/include
+
+Name: drumstick-rt
+Version: @VERSION@
+Description: MIDI Realtime Library for Qt5
+URL: http://sourceforge.net/projects/drumstick
+Libs: -L${libdir} -ldrumstick-rt
+Cflags: -I${includedir}
diff --git a/drumstick.pro b/drumstick.pro
index 9fe098b..8616730 100644
--- a/drumstick.pro
+++ b/drumstick.pro
@@ -1,2 +1,7 @@
 TEMPLATE = subdirs
-SUBDIRS += library utils
+CONFIG += ordered
+SUBDIRS += library \
+           utils
+
+OTHER_FILES += \
+    drumstick-vpiano.supp
diff --git a/drumstick.spec.in b/drumstick.spec.in
index 8528426..782afa1 100644
--- a/drumstick.spec.in
+++ b/drumstick.spec.in
@@ -1,8 +1,7 @@
-#
 # spec file for package drumstick (Version @VERSION@)
 #
-# MIDI Sequencer C++ Library Bindings for Qt4 and ALSA
-# Copyright (C) 2005-2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+# MIDI Sequencer C++ Library Bindings for Qt5
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
 #
 # This file and all modifications and additions to the pristine
 # package are under the same license as the package itself.
@@ -20,15 +19,15 @@ URL:            http://drumstick.sourceforge.net
 Source:         %{name}-%{version}.tar.bz2
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 BuildRequires:  cmake
-BuildRequires:  alsa-devel
-BuildRequires:  libqt4-devel
+BuildRequires:  alsa-lib-devel
+BuildRequires:  qt5-qtbase-devel
+BuildRequires:  qt5-qtsvg-devel
 BuildRequires:  doxygen
 BuildRequires:  graphviz
-BuildRequires:  update-desktop-files
 BuildRequires:  libxslt
-BuildRequires:  docbook_4
-BuildRequires:  docbook-xsl-stylesheets
-PreReq:         shared-mime-info
+BuildRequires:  docbook-utils
+BuildRequires:  docbook-style-xsl
+Requires:       shared-mime-info
 
 %description
 This package includes test and example programs for drumstick libraries.
@@ -39,30 +38,43 @@ Authors:
     Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
 
 
-%package -n libdrumstick-file0
+%package -n libdrumstick-file1
 Summary:        MIDI Sequencer C++ Library
 Group:          System/Libraries
 
-%description -n libdrumstick-file0
-MIDI Sequencer C++ Library Bindings for Qt4 and ALSA.
+%description -n libdrumstick-file1
+MIDI Sequencer C++ Library Bindings for Qt5
 This library includes classes providing file input and output in formats 
 commonly used by MIDI programs. Currently, SMF (standard MIDI file) 
-read/write and WRK (Cakewalk) file read are supported. This library does not 
-depend on ALSA.
+read/write and WRK (Cakewalk) file read are supported.
 
 
 Authors:
 --------
     Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
 
-%package -n libdrumstick-alsa0
+%package -n libdrumstick-alsa1
 Summary:        MIDI Sequencer C++ Library
 Group:          System/Libraries
 
-%description -n libdrumstick-alsa0
-MIDI Sequencer C++ Library Bindings for Qt4 and ALSA.
+%description -n libdrumstick-alsa1
+MIDI Sequencer C++ Library Bindings for Qt5 and ALSA.
 This library includes the ALSA Sequencer library classes, providing MIDI 
-recording and playback functionality to C++/Qt4 programs.
+recording and playback functionality to C++/Qt5 programs.
+
+
+Authors:
+--------
+    Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+
+%package -n libdrumstick-rt1
+Summary:        MIDI Realtime IO C++ Library
+Group:          System/Libraries
+
+%description -n libdrumstick-rt1
+MIDI Realtime IO C++ Library for Qt5
+This library includes the RT library classes, providing MIDI 
+realtime IO functionality to C++/Qt5 programs.
 
 
 Authors:
@@ -72,9 +84,9 @@ Authors:
 %package -n libdrumstick-devel
 Summary:        Development package for the libdrumstick library
 Group:          Development/Libraries/C and C++
-Requires:       libdrumstick-file0 = %{version}
-Requires:       libdrumstick-alsa0 = %{version}
-Requires:       glibc-devel libstdc++-devel alsa-devel libqt4-devel
+Requires:       libdrumstick-file1 = %{version}
+Requires:       libdrumstick-alsa1 = %{version}
+Requires:       glibc-devel libstdc++-devel alsa-lib-devel qt5-qtbase-devel
 
 %description -n libdrumstick-devel
 This package contains the files needed to compile programs that use the
@@ -110,9 +122,6 @@ make doxygen
 
 %install
 make install DESTDIR=$RPM_BUILD_ROOT
-%suse_update_desktop_file -n drumstick-drumgrid Midi
-%suse_update_desktop_file -n drumstick-guiplayer Midi
-%suse_update_desktop_file -n drumstick-vpiano Midi
 
 %post 
 %{_bindir}/update-mime-database %{_datadir}/mime
@@ -120,13 +129,17 @@ make install DESTDIR=$RPM_BUILD_ROOT
 %postun
 %{_bindir}/update-mime-database %{_datadir}/mime
 
-%post -n libdrumstick-file0 -p /sbin/ldconfig
+%post -n libdrumstick-file1 -p /sbin/ldconfig
+
+%postun -n libdrumstick-file1 -p /sbin/ldconfig
 
-%postun -n libdrumstick-file0 -p /sbin/ldconfig
+%post -n libdrumstick-alsa1 -p /sbin/ldconfig
 
-%post -n libdrumstick-alsa0 -p /sbin/ldconfig
+%postun -n libdrumstick-alsa1 -p /sbin/ldconfig
 
-%postun -n libdrumstick-alsa0 -p /sbin/ldconfig
+%post -n libdrumstick-rt1 -p /sbin/ldconfig
+
+%postun -n libdrumstick-rt1 -p /sbin/ldconfig
 
 %clean
 rm -rf $RPM_BUILD_ROOT
@@ -139,20 +152,26 @@ rm -rf $RPM_BUILD_ROOT
 %{_datadir}/applications/*
 %{_bindir}/*
 
-%files -n libdrumstick-file0
+%files -n libdrumstick-file1
 %defattr(-,root,root)
 %{_libdir}/libdrumstick-file.so.*
 %{_datadir}/mime/packages/*
 
-%files -n libdrumstick-alsa0
+%files -n libdrumstick-alsa1
 %defattr(-,root,root)
 %{_libdir}/libdrumstick-alsa.so.*
 
+%files -n libdrumstick-rt1
+%defattr(-,root,root)
+%{_libdir}/libdrumstick-rt.so.*
+%{_libdir}/drumstick/*.so
+
 %files -n libdrumstick-devel
 %defattr(-, root, root)
 %dir %{_includedir}/drumstick
 %{_libdir}/libdrumstick-file.so
 %{_libdir}/libdrumstick-alsa.so
+%{_libdir}/libdrumstick-rt.so
 %{_includedir}/drumstick.h
 %{_includedir}/drumstick/*.h
 %{_libdir}/pkgconfig/*.pc
@@ -162,29 +181,8 @@ rm -rf $RPM_BUILD_ROOT
 %doc doc/html/*
 
 %changelog
-* Thu Sep 9 2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net> 0.5.0
-- New version
-
-* Tue Jul 13 2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net> 0.4.1
-- New version
-
-* Wed Jul 7 2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net> 0.4.0
-- New version
-
-* Thu Jun 10 2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net> 0.3.2
+* Sat Aug 30 2014 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net> 1.0.0
 - New version
 
-* Mon Apr 19 2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net> 0.3.1
-- New version  
-
-* Tue Mar 9 2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net> 0.3.0
-- New version
-
-* Sun Dec 27 2009 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net> 0.2.0
+* Thu Sep 9 2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net> 0.5.0
 - New version
-
-* Thu Dec 17 2009 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net> 0.1.0-2
-- tweaks
-
-* Thu Aug 27 2009 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net> 0.1.0
-- first public release
diff --git a/global.pri b/global.pri
new file mode 100644
index 0000000..1421fe4
--- /dev/null
+++ b/global.pri
@@ -0,0 +1,2 @@
+VERSION = 1.0.2
+DEFINES += VERSION=$$VERSION
diff --git a/icons/drumstick.icns b/icons/drumstick.icns
new file mode 100644
index 0000000..5cac0c7
Binary files /dev/null and b/icons/drumstick.icns differ
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index 3098212..0c14960 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -1,5 +1,5 @@
 # MIDI Sequencer C++ Library
-# Copyright (C) 2005-2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,149 +16,9 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA 02110-1301, USA
 
-#deprecated libtool
-#INCLUDE(CreateLibtoolFile)
-
-INCLUDE_DIRECTORIES(
-    ${CMAKE_CURRENT_BINARY_DIR}
-)
-
-# drumstick-file library
-
-SET(drumstick-file_QTOBJ_SRCS
-    include/qsmf.h
-    include/qwrk.h
-    include/qove.h
-)
-
-SET(drumstick-file_HEADERS
-    include/macros.h
-    include/qsmf.h
-    include/qwrk.h
-    include/qove.h
-)
-
-SET(drumstick-file_SRCS
-    src/qsmf.cpp
-    src/qwrk.cpp
-    src/qove.cpp
-)
-
-QT4_WRAP_CPP(drumstick-file_MOC_SRCS ${drumstick-file_QTOBJ_SRCS})
-
-ADD_LIBRARY(drumstick-file
-    ${drumstick-file_MOC_SRCS}
-    ${drumstick-file_SRCS} 
-    ${drumstick-file_HEADERS} 
-)
-
-TARGET_LINK_LIBRARIES(drumstick-file
-    ${QT_LIBRARIES}
-)
-
-IF(STATIC_DRUMSTICK)
-    SET_TARGET_PROPERTIES(drumstick-file PROPERTIES
-        STATIC_LIB "libdrumstick-file.a"
-    )
-    IF(NOT WIN32)
-        SET_TARGET_PROPERTIES(drumstick-file PROPERTIES
-        COMPILE_FLAGS -fPIC
-    )
-    ENDIF(NOT WIN32)
-ELSE(STATIC_DRUMSTICK)
-    SET_TARGET_PROPERTIES(drumstick-file PROPERTIES
-        VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
-        SOVERSION ${VERSION_MAJOR}
-#       OUTPUT_NAME drumstick-file-${VERSION_MAJOR}.${VERSION_MINOR}
-    )
-ENDIF(STATIC_DRUMSTICK)
-
-# drumstick-alsa library
-IF(ALSA_FOUND)
-
-    SET(drumstick-alsa_QTOBJ_SRCS
-        include/alsaclient.h
-        include/alsaevent.h
-        include/alsaport.h
-        include/alsaqueue.h
-        include/alsatimer.h
-        include/playthread.h
-    )
-    
-    SET(drumstick-alsa_HEADERS
-        include/alsaclient.h
-        include/alsaevent.h
-        include/alsaport.h
-        include/alsaqueue.h
-        include/alsatimer.h
-        include/drumstickcommon.h
-        include/playthread.h
-        include/subscription.h
-    )
-    
-    SET(drumstick-alsa_SRCS
-        src/alsaclient.cpp
-        src/alsaevent.cpp
-        src/alsaport.cpp
-        src/alsaqueue.cpp
-        src/alsatimer.cpp
-        src/playthread.cpp
-        src/subscription.cpp
-    )
-
-    QT4_WRAP_CPP(drumstick-alsa_MOC_SRCS ${drumstick-alsa_QTOBJ_SRCS})
-   
-    ADD_LIBRARY(drumstick-alsa 
-        ${drumstick-alsa_MOC_SRCS}
-        ${drumstick-alsa_SRCS} 
-        ${drumstick-alsa_HEADERS} 
-    )
-    
-    TARGET_LINK_LIBRARIES(drumstick-alsa
-        ${QT_LIBRARIES}
-        ${ALSA_LIBS}
-    )
-    
-    IF(STATIC_DRUMSTICK)
-        SET_TARGET_PROPERTIES(drumstick-alsa PROPERTIES
-             STATIC_LIB "libdrumstick-alsa.a"
-        )
-        IF(NOT WIN32)
-            SET_TARGET_PROPERTIES(drumstick-file PROPERTIES
-            COMPILE_FLAGS -fPIC
-        )
-        ENDIF(NOT WIN32)
-    ELSE(STATIC_DRUMSTICK)
-        SET_TARGET_PROPERTIES(drumstick-alsa PROPERTIES
-            VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
-            SOVERSION ${VERSION_MAJOR}
-#           OUTPUT_NAME drumstick-alsa-${VERSION_MAJOR}.${VERSION_MINOR}
-        )
-    ENDIF(STATIC_DRUMSTICK)
-
-#deprecated libtool 
-#SET_TARGET_PROPERTIES(drumstick-alsa PROPERTIES
-#    LT_DEPENDENCY_LIBS "-lasound -lQtCore"
-#    LT_VERSION_CURRENT ${VERSION_MAJOR}
-#    LT_VERSION_AGE ${VERSION_MINOR}
-#    LT_VERSION_REVISION ${VERSION_PATCH}
-#)
-#CREATE_LIBTOOL_FILE(drumstick-alsa lib${LIB_SUFFIX})
-
-    INSTALL(TARGETS drumstick-alsa 
-        RUNTIME DESTINATION bin
-        ARCHIVE DESTINATION lib${LIB_SUFFIX}
-        LIBRARY DESTINATION lib${LIB_SUFFIX})
-    INSTALL(FILES ${drumstick-alsa_HEADERS}
-            DESTINATION include/drumstick)
-    INSTALL(FILES include/drumstick.h
-            DESTINATION include)
-ENDIF(ALSA_FOUND)
-
-INSTALL(TARGETS drumstick-file
-	RUNTIME DESTINATION bin
-	ARCHIVE DESTINATION lib${LIB_SUFFIX}
-	LIBRARY DESTINATION lib${LIB_SUFFIX})
-
-INSTALL(FILES ${drumstick-file_HEADERS}
-        DESTINATION include/drumstick)
+if(ALSA_FOUND)
+    add_subdirectory(alsa)
+endif()
+add_subdirectory(file)
+add_subdirectory(rt)
+add_subdirectory(rt-backends)
diff --git a/library/alsa/CMakeLists.txt b/library/alsa/CMakeLists.txt
new file mode 100644
index 0000000..6095803
--- /dev/null
+++ b/library/alsa/CMakeLists.txt
@@ -0,0 +1,85 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+include_directories(${ALSA_INC_DIR})
+link_directories(${ALSA_LIB_DIR})
+
+set(drumstick-alsa_QTOBJ_SRCS
+    ../include/alsaclient.h
+    ../include/alsaevent.h
+    ../include/alsaport.h
+    ../include/alsaqueue.h
+    ../include/alsatimer.h
+    ../include/playthread.h
+)
+
+set(drumstick-alsa_HEADERS
+    ../include/alsaclient.h
+    ../include/alsaevent.h
+    ../include/alsaport.h
+    ../include/alsaqueue.h
+    ../include/alsatimer.h
+    ../include/drumstickcommon.h
+    ../include/playthread.h
+    ../include/subscription.h
+)
+
+SET(drumstick-alsa_SRCS
+    alsaclient.cpp
+    alsaevent.cpp
+    alsaport.cpp
+    alsaqueue.cpp
+    alsatimer.cpp
+    playthread.cpp
+    subscription.cpp
+)
+
+
+qt5_wrap_cpp(drumstick-alsa_MOC_SRCS ${drumstick-alsa_QTOBJ_SRCS})
+
+add_library(drumstick-alsa
+    ${drumstick-alsa_MOC_SRCS}
+    ${drumstick-alsa_SRCS}
+    ${drumstick-alsa_HEADERS}
+)
+
+target_link_libraries(drumstick-alsa
+    ${ALSA_LIBS}
+    Qt5::Core
+    Qt5::DBus
+)
+
+if(STATIC_DRUMSTICK)
+    set_target_properties(drumstick-alsa PROPERTIES
+         STATIC_LIB "libdrumstick-alsa")
+else()
+    set_target_properties(drumstick-alsa PROPERTIES
+        VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
+        SOVERSION ${VERSION_MAJOR}
+    )
+endif()
+
+install(TARGETS drumstick-alsa
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}
+        LIBRARY DESTINATION lib${LIB_SUFFIX})
+install(FILES ${drumstick-alsa_HEADERS}
+        DESTINATION include/drumstick)
+install(FILES ../include/drumstick.h
+        DESTINATION include)
diff --git a/library/alsa/alsa.pro b/library/alsa/alsa.pro
new file mode 100644
index 0000000..272cc12
--- /dev/null
+++ b/library/alsa/alsa.pro
@@ -0,0 +1,31 @@
+TEMPLATE = lib
+TARGET = $$qtLibraryTarget(drumstick-alsa)
+DESTDIR = ../../build/lib
+DEPENDPATH += . ../include
+INCLUDEPATH += . ../include
+include (../../global.pri)
+QT -= gui
+QT += dbus
+CONFIG += qt thread create_prl
+DEFINES += drumstick_alsa_EXPORTS RTKIT_SUPPORT
+QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_HIDESYMS
+# Input
+HEADERS += ../include/alsaclient.h \
+           ../include/alsaevent.h \
+           ../include/alsaport.h \
+           ../include/alsaqueue.h \
+           ../include/alsatimer.h \
+           ../include/drumstick.h \
+           ../include/drumstickcommon.h \
+           ../include/macros.h \
+           ../include/playthread.h \
+           ../include/subscription.h
+SOURCES += alsaclient.cpp \
+           alsaevent.cpp \
+           alsaport.cpp \
+           alsaqueue.cpp \
+           alsatimer.cpp \
+           playthread.cpp \
+           subscription.cpp
+
+LIBS += -lasound
diff --git a/library/src/alsaclient.cpp b/library/alsa/alsaclient.cpp
similarity index 83%
rename from library/src/alsaclient.cpp
rename to library/alsa/alsaclient.cpp
index 920a48f..eda88bb 100644
--- a/library/src/alsaclient.cpp
+++ b/library/alsa/alsaclient.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -54,35 +54,35 @@
 /**
  * @class QObject
  * The QObject class is the base class of all Qt objects.
- * @see   http://doc.trolltech.com/qobject.html
+ * @see   http://qt-project.org/doc/qt-5/qobject.html
  */
 
 /**
  * @class QThread
  * The QThread class provides platform-independent threads.
- * @see   http://doc.trolltech.com/qthread.html
+ * @see   http://qt-project.org/doc/qt-5/qthread.html
  */
 
 namespace drumstick {
 
 /**
 @mainpage drumstick Documentation
- at author Copyright © 2009-2010 Pedro López-Cabanillas <plcl AT users.sf.net>
- at date 2010-09-09
- at version 0.5.0
+ at author Copyright © 2009-2014 Pedro López-Cabanillas <plcl AT users.sf.net>
+ at date 2014-08-30
+ at version 1.0.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/
 
 @section Abstract
 
-This is the reference documentation for drumstick. This library is a C++ wrapper
-around the ALSA library sequencer interface, using Qt4 objects, idioms and style.
+This is the reference documentation for drumstick. This library is a set of C++ MIDI related classes,
+using Qt5 objects, idioms and style.
 ALSA sequencer provides software support for MIDI technology on Linux.
 
- at see http://doc.trolltech.com/index.html
+ at see http://qt-project.org/doc/qt-5/index.html
 @see http://www.alsa-project.org/alsa-doc/alsa-lib/seq.html
- at see http://cartan.cas.suffolk.edu/oopdocbook/opensource/index.html
+ at see http://www.ics.com/design-patterns
 @see http://www.midi.org/aboutmidi/tutorials.php
 
 @section Disclaimer
@@ -94,11 +94,10 @@ development. Please visit the drumstick web site to read the latest version.
 
 @section Introduction
 
-For an introduction to design and programming with C++ and Qt4, see the book
-"An Introduction to Design Patterns in C++ with Qt 4" by by Alan Ezust and Paul
+For an introduction to design and programming with C++ and Qt, see the book
+"An Introduction to Design Patterns in C++ with Qt" by by Alan Ezust and Paul
 Ezust. It is available published on dead trees, and also
-<a href="http://cartan.cas.suffolk.edu/oopdocbook/opensource/index.html">
-online</a>.
+<a href="http://www.ics.com/design-patterns"> online</a>.
 
 Here is how a simple program playing a note-on MIDI message using drumstick
 looks like:
@@ -115,7 +114,7 @@ int main(int argc, char **argv) {
     client->open();
     client->setClientName( "MyClient" );
 
-    // create the port
+    // create the port. Pointer is owned by the client instance
     drumstick::MidiPort *port = client->createPort();
     port->setPortName( "MyPort" );
     port->setCapability( SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ );
@@ -139,11 +138,12 @@ int main(int argc, char **argv) {
 @endcode
 
 There are more examples in the source tree, under the utils/ directory, and
-you can also see applications using this library, as kmetronome and kmidimon.
+you can also see applications using this library, like kmetronome and kmidimon.
 
 @see http://kmetronome.sourceforge.net
 @see http://kmidimon.sourceforge.net
 @see http://kmid2.sourceforge.net
+ at see http://vmpk.sourceforge.net
 
 @section Acknowledgments
 Parts of this documentation are copied from the ALSA library documentation,
@@ -282,14 +282,14 @@ A Virtual Piano Keyboard GUI application. See another one at http://vmpk.sf.net
  * is emitted. In any case, the event pointer must be deleted by the receiver
  * method.
  *
- * @see http://doc.trolltech.com/threads.html#qobject-reentrancy
+ * @see http://qt-project.org/doc/qt-5/threads-reentrancy.html
  *
  * @section EventOutput Output
  *
  * The methods to send a single event to the ALSA sequencer are:
  * <ul>
  * <li>MidiClient::output() using the library buffer, automatically flushed.</li>
- * <li>MidiClient::outputBuffer() using the library buffer. Not flushed.</li>
+ * <li>MidiClient::outputBuffer() using the library buffer. Not flushed automatically.</li>
  * <li>MidiClient::outputDirect() not using the library buffer.</li>
  * </ul>
  * The two first methods usually require a call to MidiClient::drainOutput() to
@@ -348,6 +348,41 @@ public:
     QReadWriteLock m_mutex;
 };
 
+class MidiClient::MidiClientPrivate
+{
+public:
+    MidiClientPrivate() :
+        m_eventsEnabled(false),
+        m_BlockMode(false),
+        m_NeedRefreshClientList(true),
+        m_OpenMode(SND_SEQ_OPEN_DUPLEX),
+        m_DeviceName("default"),
+        m_SeqHandle(0),
+        m_Thread(0),
+        m_Queue(0),
+        m_handler(0)
+    { }
+
+    bool m_eventsEnabled;
+    bool m_BlockMode;
+    bool m_NeedRefreshClientList;
+    int  m_OpenMode;
+    QString m_DeviceName;
+    snd_seq_t* m_SeqHandle;
+    QPointer<SequencerInputThread> m_Thread;
+    QPointer<MidiQueue> m_Queue;
+    SequencerEventHandler* m_handler;
+
+    ClientInfo m_Info;
+    ClientInfoList m_ClientList;
+    MidiPortList m_Ports;
+    PortInfoList m_OutputsAvail;
+    PortInfoList m_InputsAvail;
+    QObjectList m_listeners;
+    SystemInfo m_sysInfo;
+    PoolInfo m_poolInfo;
+};
+
 /**
  * Constructor.
  *
@@ -365,15 +400,7 @@ public:
  */
 MidiClient::MidiClient( QObject* parent ) :
     QObject(parent),
-    m_eventsEnabled(false),
-    m_BlockMode(false),
-    m_NeedRefreshClientList(true),
-    m_OpenMode(SND_SEQ_OPEN_DUPLEX),
-    m_DeviceName("default"),
-    m_SeqHandle(NULL),
-    m_Thread(NULL),
-    m_Queue(NULL),
-    m_handler(NULL)
+    d(new MidiClientPrivate)
 { }
 
 /**
@@ -385,14 +412,74 @@ MidiClient::~MidiClient()
 {
     stopSequencerInput();
     detachAllPorts();
-    if (m_Queue != NULL)
-        delete m_Queue;
+    if (d->m_Queue != 0)
+        delete d->m_Queue;
     close();
     freeClients();
-    if (m_Thread != NULL)
-        delete m_Thread;
+    if (d->m_Thread != 0)
+        delete d->m_Thread;
+    delete d;
 }
 
+
+/**
+ * Returns the sequencer handler managed by ALSA
+ */
+snd_seq_t*
+MidiClient::getHandle()
+{
+    return d->m_SeqHandle;
+}
+
+/**
+ * Returns true if the sequencer is opened
+ */
+bool MidiClient::isOpened()
+{
+    return (d->m_SeqHandle != NULL);
+}
+
+/**
+ * Returns the name of the sequencer device
+ */
+QString MidiClient::getDeviceName()
+{
+    return d->m_DeviceName;
+}
+
+/**
+ * Returns the last open mode used in open()
+ */
+int MidiClient::getOpenMode()
+{
+    return d->m_OpenMode;
+}
+
+/**
+ * Returns the last block mode used in open()
+ */
+bool MidiClient::getBlockMode()
+{
+    return d->m_BlockMode;
+}
+
+/**
+ * Returns true if the events mode of delivery has been enabled
+ */
+bool MidiClient::getEventsEnabled() const
+{
+    return d->m_eventsEnabled;
+}
+
+/**
+ * Sets a sequencer event handler enabling the callback delivery mode
+ */
+void MidiClient::setHandler(SequencerEventHandler* handler)
+{
+    d->m_handler = handler;
+}
+
+
 /**
  * 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
@@ -403,9 +490,9 @@ MidiClient::~MidiClient()
  */
 void MidiClient::setRealTimeInput(bool enable)
 {
-    if (m_Thread == 0) {
-        m_Thread = new SequencerInputThread(this, DEFAULT_INPUT_TIMEOUT);
-        m_Thread->m_RealTime = enable;
+    if (d->m_Thread == 0) {
+        d->m_Thread = new SequencerInputThread(this, DEFAULT_INPUT_TIMEOUT);
+        d->m_Thread->m_RealTime = enable;
     }
 }
 
@@ -416,9 +503,9 @@ void MidiClient::setRealTimeInput(bool enable)
  */
 bool MidiClient::realTimeInputEnabled()
 {
-    if (m_Thread == 0)
+    if (d->m_Thread == 0)
         return true;
-    return m_Thread->m_RealTime;
+    return d->m_Thread->m_RealTime;
 }
 
 /**
@@ -446,12 +533,12 @@ MidiClient::open( const QString deviceName,
                   const int openMode,
                   const bool blockMode)
 {
-    CHECK_ERROR( snd_seq_open( &m_SeqHandle, deviceName.toLocal8Bit().data(),
+    CHECK_ERROR( snd_seq_open( &d->m_SeqHandle, deviceName.toLocal8Bit().data(),
                               openMode, blockMode ? 0 : SND_SEQ_NONBLOCK ) );
-    CHECK_WARNING( snd_seq_get_client_info( m_SeqHandle, m_Info.m_Info ) );
-    m_DeviceName = deviceName;
-    m_OpenMode = openMode;
-    m_BlockMode = blockMode;
+    CHECK_WARNING( snd_seq_get_client_info( d->m_SeqHandle, d->m_Info.m_Info ) );
+    d->m_DeviceName = deviceName;
+    d->m_OpenMode = openMode;
+    d->m_BlockMode = blockMode;
 }
 
 /**
@@ -480,15 +567,15 @@ MidiClient::open( snd_config_t* conf,
                   const int openMode,
                   const bool blockMode )
 {
-    CHECK_ERROR( snd_seq_open_lconf( &m_SeqHandle,
+    CHECK_ERROR( snd_seq_open_lconf( &d->m_SeqHandle,
                                      deviceName.toLocal8Bit().data(),
                                      openMode,
                                      blockMode ? 0 : SND_SEQ_NONBLOCK,
                                      conf ));
-    CHECK_WARNING( snd_seq_get_client_info(m_SeqHandle, m_Info.m_Info));
-    m_DeviceName = deviceName;
-    m_OpenMode = openMode;
-    m_BlockMode = blockMode;
+    CHECK_WARNING( snd_seq_get_client_info(d->m_SeqHandle, d->m_Info.m_Info));
+    d->m_DeviceName = deviceName;
+    d->m_OpenMode = openMode;
+    d->m_BlockMode = blockMode;
 }
 
 /**
@@ -501,10 +588,10 @@ MidiClient::open( snd_config_t* conf,
 void
 MidiClient::close()
 {
-    if (m_SeqHandle != NULL) {
+    if (d->m_SeqHandle != NULL) {
         stopSequencerInput();
-        CHECK_WARNING(snd_seq_close(m_SeqHandle));
-        m_SeqHandle = NULL;
+        CHECK_WARNING(snd_seq_close(d->m_SeqHandle));
+        d->m_SeqHandle = NULL;
     }
 }
 
@@ -519,7 +606,7 @@ MidiClient::close()
 size_t
 MidiClient::getOutputBufferSize()
 {
-    return snd_seq_get_output_buffer_size(m_SeqHandle);
+    return snd_seq_get_output_buffer_size(d->m_SeqHandle);
 }
 
 /**
@@ -534,7 +621,7 @@ void
 MidiClient::setOutputBufferSize(size_t newSize)
 {
     if (getOutputBufferSize() != newSize) {
-        CHECK_WARNING(snd_seq_set_output_buffer_size(m_SeqHandle, newSize));
+        CHECK_WARNING(snd_seq_set_output_buffer_size(d->m_SeqHandle, newSize));
     }
 }
 
@@ -549,7 +636,7 @@ MidiClient::setOutputBufferSize(size_t newSize)
 size_t
 MidiClient::getInputBufferSize()
 {
-    return snd_seq_get_input_buffer_size(m_SeqHandle);
+    return snd_seq_get_input_buffer_size(d->m_SeqHandle);
 }
 
 /**
@@ -564,7 +651,7 @@ void
 MidiClient::setInputBufferSize(size_t newSize)
 {
     if (getInputBufferSize() != newSize) {
-        CHECK_WARNING(snd_seq_set_input_buffer_size(m_SeqHandle, newSize));
+        CHECK_WARNING(snd_seq_set_input_buffer_size(d->m_SeqHandle, newSize));
     }
 }
 
@@ -580,12 +667,12 @@ MidiClient::setInputBufferSize(size_t newSize)
 void
 MidiClient::setBlockMode(bool newValue)
 {
-    if (m_BlockMode != newValue)
+    if (d->m_BlockMode != newValue)
     {
-        m_BlockMode = newValue;
-        if (m_SeqHandle != NULL)
+        d->m_BlockMode = newValue;
+        if (d->m_SeqHandle != NULL)
         {
-            CHECK_WARNING(snd_seq_nonblock(m_SeqHandle, m_BlockMode ? 0 : 1));
+            CHECK_WARNING(snd_seq_nonblock(d->m_SeqHandle, d->m_BlockMode ? 0 : 1));
         }
     }
 }
@@ -601,7 +688,7 @@ MidiClient::setBlockMode(bool newValue)
 int
 MidiClient::getClientId()
 {
-    return CHECK_WARNING(snd_seq_client_id(m_SeqHandle));
+    return CHECK_WARNING(snd_seq_client_id(d->m_SeqHandle));
 }
 
 /**
@@ -611,7 +698,7 @@ MidiClient::getClientId()
 snd_seq_type_t
 MidiClient::getSequencerType()
 {
-    return snd_seq_type(m_SeqHandle);
+    return snd_seq_type(d->m_SeqHandle);
 }
 
 /**
@@ -641,7 +728,7 @@ MidiClient::doEvents()
         int err = 0;
         snd_seq_event_t* evp = NULL;
         SequencerEvent* event = NULL;
-        err = snd_seq_event_input(m_SeqHandle, &evp);
+        err = snd_seq_event_input(d->m_SeqHandle, &evp);
         if ((err >= 0) && (evp != NULL)) {
             switch (evp->type) {
 
@@ -693,14 +780,14 @@ MidiClient::doEvents()
             case SND_SEQ_EVENT_PORT_EXIT:
             case SND_SEQ_EVENT_PORT_START:
                 event = new PortEvent(evp);
-                m_NeedRefreshClientList = true;
+                d->m_NeedRefreshClientList = true;
                 break;
 
             case SND_SEQ_EVENT_CLIENT_CHANGE:
             case SND_SEQ_EVENT_CLIENT_EXIT:
             case SND_SEQ_EVENT_CLIENT_START:
                 event = new ClientEvent(evp);
-                m_NeedRefreshClientList = true;
+                d->m_NeedRefreshClientList = true;
                 break;
 
             case SND_SEQ_EVENT_SONGPOS:
@@ -726,15 +813,15 @@ MidiClient::doEvents()
                 break;
             }
             // first, process the callback (if any)
-            if (m_handler != NULL) {
-                m_handler->handleSequencerEvent(event->clone());
+            if (d->m_handler != NULL) {
+                d->m_handler->handleSequencerEvent(event->clone());
             } else {
                 // second, process the event listeners
-                if (m_eventsEnabled) {
+                if (d->m_eventsEnabled) {
                    QObjectList::Iterator it;
-                    for(it=m_listeners.begin(); it!=m_listeners.end(); ++it) {
+                    for(it=d->m_listeners.begin(); it!=d->m_listeners.end(); ++it) {
                         QObject* sub = (*it);
-                        QApplication::postEvent(sub, event->clone());
+                        QCoreApplication::postEvent(sub, event->clone());
                     }
                 } else {
                     // finally, process signals
@@ -744,7 +831,7 @@ MidiClient::doEvents()
             delete event;
         }
     }
-    while (snd_seq_event_input_pending(m_SeqHandle, 0) > 0);
+    while (snd_seq_event_input_pending(d->m_SeqHandle, 0) > 0);
 }
 
 /**
@@ -753,10 +840,10 @@ MidiClient::doEvents()
 void
 MidiClient::startSequencerInput()
 {
-    if (m_Thread == 0) {
-        m_Thread = new SequencerInputThread(this, DEFAULT_INPUT_TIMEOUT);
+    if (d->m_Thread == 0) {
+        d->m_Thread = new SequencerInputThread(this, DEFAULT_INPUT_TIMEOUT);
     }
-    m_Thread->start( m_Thread->m_RealTime ?
+    d->m_Thread->start( d->m_Thread->m_RealTime ?
             QThread::TimeCriticalPriority : QThread::InheritPriority );
 }
 
@@ -767,17 +854,17 @@ void
 MidiClient::stopSequencerInput()
 {
     int counter = 0;
-    if (m_Thread != 0) {
-        if (m_Thread->isRunning()) {
-            m_Thread->stop();
-            while (!m_Thread->wait(500) && (counter < 10)) {
+    if (d->m_Thread != 0) {
+        if (d->m_Thread->isRunning()) {
+            d->m_Thread->stop();
+            while (!d->m_Thread->wait(500) && (counter < 10)) {
                 counter++;
             }
-            if (!m_Thread->isFinished()) {
-                m_Thread->terminate();
+            if (!d->m_Thread->isFinished()) {
+                d->m_Thread->terminate();
             }
         }
-        delete m_Thread;
+        delete d->m_Thread;
     }
 }
 
@@ -790,11 +877,11 @@ MidiClient::readClients()
     ClientInfo cInfo;
     freeClients();
     cInfo.setClient(-1);
-    while (snd_seq_query_next_client(m_SeqHandle, cInfo.m_Info) >= 0) {
+    while (snd_seq_query_next_client(d->m_SeqHandle, cInfo.m_Info) >= 0) {
         cInfo.readPorts(this);
-        m_ClientList.append(cInfo);
+        d->m_ClientList.append(cInfo);
     }
-    m_NeedRefreshClientList = false;
+    d->m_NeedRefreshClientList = false;
 }
 
 /**
@@ -803,7 +890,7 @@ MidiClient::readClients()
 void
 MidiClient::freeClients()
 {
-    m_ClientList.clear();
+    d->m_ClientList.clear();
 }
 
 /**
@@ -813,9 +900,9 @@ MidiClient::freeClients()
 ClientInfoList
 MidiClient::getAvailableClients()
 {
-    if (m_NeedRefreshClientList)
+    if (d->m_NeedRefreshClientList)
         readClients();
-    ClientInfoList lst = m_ClientList; // copy
+    ClientInfoList lst = d->m_ClientList; // copy
     return lst;
 }
 
@@ -826,8 +913,8 @@ MidiClient::getAvailableClients()
 ClientInfo&
 MidiClient::getThisClientInfo()
 {
-    snd_seq_get_client_info(m_SeqHandle, m_Info.m_Info);
-    return m_Info;
+    snd_seq_get_client_info(d->m_SeqHandle, d->m_Info.m_Info);
+    return d->m_Info;
 }
 
 /**
@@ -840,8 +927,8 @@ MidiClient::getThisClientInfo()
 void
 MidiClient::setThisClientInfo(const ClientInfo& val)
 {
-    m_Info = val;
-    snd_seq_set_client_info(m_SeqHandle, m_Info.m_Info);
+    d->m_Info = val;
+    snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info);
 }
 
 /**
@@ -850,8 +937,8 @@ MidiClient::setThisClientInfo(const ClientInfo& val)
 void
 MidiClient::applyClientInfo()
 {
-    if (m_SeqHandle != NULL) {
-        snd_seq_set_client_info(m_SeqHandle, m_Info.m_Info);
+    if (d->m_SeqHandle != NULL) {
+        snd_seq_set_client_info(d->m_SeqHandle, d->m_Info.m_Info);
     }
 }
 
@@ -862,7 +949,7 @@ MidiClient::applyClientInfo()
 QString
 MidiClient::getClientName()
 {
-    return m_Info.getName();
+    return d->m_Info.getName();
 }
 
 /**
@@ -874,9 +961,9 @@ QString
 MidiClient::getClientName(const int clientId)
 {
     ClientInfoList::Iterator it;
-    if (m_NeedRefreshClientList)
+    if (d->m_NeedRefreshClientList)
         readClients();
-    for (it = m_ClientList.begin(); it != m_ClientList.end(); ++it) {
+    for (it = d->m_ClientList.begin(); it != d->m_ClientList.end(); ++it) {
         if ((*it).getClientId() == clientId) {
             return (*it).getName();
         }
@@ -891,8 +978,8 @@ MidiClient::getClientName(const int clientId)
 void
 MidiClient::setClientName(QString const& newName)
 {
-    if (newName != m_Info.getName()) {
-        m_Info.setName(newName);
+    if (newName != d->m_Info.getName()) {
+        d->m_Info.setName(newName);
         applyClientInfo();
     }
 }
@@ -904,7 +991,7 @@ MidiClient::setClientName(QString const& newName)
 MidiPortList
 MidiClient::getMidiPorts() const
 {
-    return m_Ports;
+    return d->m_Ports;
 }
 
 /**
@@ -926,9 +1013,9 @@ MidiClient::createPort()
 void
 MidiClient::portAttach(MidiPort* port)
 {
-    if (m_SeqHandle != NULL) {
-        CHECK_ERROR(snd_seq_create_port(m_SeqHandle, port->m_Info.m_Info));
-        m_Ports.push_back(port);
+    if (d->m_SeqHandle != NULL) {
+        CHECK_ERROR(snd_seq_create_port(d->m_SeqHandle, port->m_Info.m_Info));
+        d->m_Ports.push_back(port);
     }
 }
 
@@ -939,20 +1026,20 @@ MidiClient::portAttach(MidiPort* port)
 void
 MidiClient::portDetach(MidiPort* port)
 {
-    if (m_SeqHandle != NULL) {
+    if (d->m_SeqHandle != NULL) {
         if(port->getPortInfo()->getClient() == getClientId())
         {
             return;
         }
-        CHECK_ERROR(snd_seq_delete_port(m_SeqHandle, port->getPortInfo()->getPort()));
+        CHECK_ERROR(snd_seq_delete_port(d->m_SeqHandle, port->getPortInfo()->getPort()));
         port->setMidiClient(NULL);
 
         MidiPortList::iterator it;
-        for(it = m_Ports.begin(); it != m_Ports.end(); ++it)
+        for(it = d->m_Ports.begin(); it != d->m_Ports.end(); ++it)
         {
             if ((*it)->getPortInfo()->getPort() == port->getPortInfo()->getPort())
             {
-                m_Ports.erase(it);
+                d->m_Ports.erase(it);
                 break;
             }
         }
@@ -964,12 +1051,12 @@ MidiClient::portDetach(MidiPort* port)
  */
 void MidiClient::detachAllPorts()
 {
-    if (m_SeqHandle != NULL) {
+    if (d->m_SeqHandle != NULL) {
         MidiPortList::iterator it;
-        for (it = m_Ports.begin(); it != m_Ports.end(); ++it) {
-            CHECK_ERROR(snd_seq_delete_port(m_SeqHandle, (*it)->getPortInfo()->getPort()));
+        for (it = d->m_Ports.begin(); it != d->m_Ports.end(); ++it) {
+            CHECK_ERROR(snd_seq_delete_port(d->m_SeqHandle, (*it)->getPortInfo()->getPort()));
             (*it)->setMidiClient(NULL);
-            m_Ports.erase(it);
+            d->m_Ports.erase(it);
         }
     }
 }
@@ -981,7 +1068,7 @@ void MidiClient::detachAllPorts()
 void
 MidiClient::addEventFilter(int evtype)
 {
-    snd_seq_set_client_event_filter(m_SeqHandle, evtype);
+    snd_seq_set_client_event_filter(d->m_SeqHandle, evtype);
 }
 
 /**
@@ -992,7 +1079,7 @@ MidiClient::addEventFilter(int evtype)
 bool
 MidiClient::getBroadcastFilter()
 {
-    return m_Info.getBroadcastFilter();
+    return d->m_Info.getBroadcastFilter();
 }
 
 /**
@@ -1003,7 +1090,7 @@ MidiClient::getBroadcastFilter()
 void
 MidiClient::setBroadcastFilter(bool newValue)
 {
-    m_Info.setBroadcastFilter(newValue);
+    d->m_Info.setBroadcastFilter(newValue);
     applyClientInfo();
 }
 
@@ -1015,7 +1102,7 @@ MidiClient::setBroadcastFilter(bool newValue)
 bool
 MidiClient::getErrorBounce()
 {
-    return m_Info.getErrorBounce();
+    return d->m_Info.getErrorBounce();
 }
 
 /**
@@ -1026,7 +1113,7 @@ MidiClient::getErrorBounce()
 void
 MidiClient::setErrorBounce(bool newValue)
 {
-    m_Info.setErrorBounce(newValue);
+    d->m_Info.setErrorBounce(newValue);
     applyClientInfo();
 }
 
@@ -1047,12 +1134,12 @@ MidiClient::output(SequencerEvent* ev, bool async, int timeout)
     int npfds;
     pollfd* pfds;
     if (async) {
-        CHECK_WARNING(snd_seq_event_output(m_SeqHandle, ev->getHandle()));
+        CHECK_WARNING(snd_seq_event_output(d->m_SeqHandle, ev->getHandle()));
     } else {
-        npfds = snd_seq_poll_descriptors_count(m_SeqHandle, POLLOUT);
+        npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
         pfds = (pollfd*) alloca(npfds * sizeof(pollfd));
-        snd_seq_poll_descriptors(m_SeqHandle, pfds, npfds, POLLOUT);
-        while (snd_seq_event_output(m_SeqHandle, ev->getHandle()) < 0)
+        snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
+        while (snd_seq_event_output(d->m_SeqHandle, ev->getHandle()) < 0)
         {
             poll(pfds, npfds, timeout);
         }
@@ -1075,12 +1162,12 @@ void MidiClient::outputDirect(SequencerEvent* ev, bool async, int timeout)
     int npfds;
     pollfd* pfds;
     if (async) {
-        CHECK_WARNING(snd_seq_event_output_direct(m_SeqHandle, ev->getHandle()));
+        CHECK_WARNING(snd_seq_event_output_direct(d->m_SeqHandle, ev->getHandle()));
     } else {
-        npfds = snd_seq_poll_descriptors_count(m_SeqHandle, POLLOUT);
+        npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
         pfds = (pollfd*) alloca(npfds * sizeof(pollfd));
-        snd_seq_poll_descriptors(m_SeqHandle, pfds, npfds, POLLOUT);
-        while (snd_seq_event_output_direct(m_SeqHandle, ev->getHandle()) < 0)
+        snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
+        while (snd_seq_event_output_direct(d->m_SeqHandle, ev->getHandle()) < 0)
         {
             poll(pfds, npfds, timeout);
         }
@@ -1098,7 +1185,7 @@ void MidiClient::outputDirect(SequencerEvent* ev, bool async, int timeout)
 void
 MidiClient::outputBuffer(SequencerEvent* ev)
 {
-    CHECK_WARNING(snd_seq_event_output_buffer(m_SeqHandle, ev->getHandle()));
+    CHECK_WARNING(snd_seq_event_output_buffer(d->m_SeqHandle, ev->getHandle()));
 }
 
 /**
@@ -1117,12 +1204,12 @@ void MidiClient::drainOutput(bool async, int timeout)
     int npfds;
     pollfd* pfds;
     if (async) {
-        CHECK_WARNING(snd_seq_drain_output(m_SeqHandle));
+        CHECK_WARNING(snd_seq_drain_output(d->m_SeqHandle));
     } else {
-        npfds = snd_seq_poll_descriptors_count(m_SeqHandle, POLLOUT);
+        npfds = snd_seq_poll_descriptors_count(d->m_SeqHandle, POLLOUT);
         pfds = (pollfd*) alloca(npfds * sizeof(pollfd));
-        snd_seq_poll_descriptors(m_SeqHandle, pfds, npfds, POLLOUT);
-        while (snd_seq_drain_output(m_SeqHandle) < 0)
+        snd_seq_poll_descriptors(d->m_SeqHandle, pfds, npfds, POLLOUT);
+        while (snd_seq_drain_output(d->m_SeqHandle) < 0)
         {
             poll(pfds, npfds, timeout);
         }
@@ -1137,7 +1224,7 @@ void MidiClient::drainOutput(bool async, int timeout)
 void
 MidiClient::synchronizeOutput()
 {
-    snd_seq_sync_output_queue(m_SeqHandle);
+    snd_seq_sync_output_queue(d->m_SeqHandle);
 }
 
 /**
@@ -1148,10 +1235,10 @@ MidiClient::synchronizeOutput()
 MidiQueue*
 MidiClient::getQueue()
 {
-    if (m_Queue == NULL) {
+    if (d->m_Queue == NULL) {
         createQueue();
     }
-    return m_Queue;
+    return d->m_Queue;
 }
 
 /**
@@ -1161,11 +1248,11 @@ MidiClient::getQueue()
 MidiQueue*
 MidiClient::createQueue()
 {
-    if (m_Queue != NULL) {
-        delete m_Queue;
+    if (d->m_Queue != NULL) {
+        delete d->m_Queue;
     }
-    m_Queue = new MidiQueue(this, this);
-    return m_Queue;
+    d->m_Queue = new MidiQueue(this, this);
+    return d->m_Queue;
 }
 
 /**
@@ -1177,11 +1264,11 @@ MidiClient::createQueue()
 MidiQueue*
 MidiClient::createQueue(QString const& queueName )
 {
-    if (m_Queue != NULL) {
-        delete m_Queue;
+    if (d->m_Queue != NULL) {
+        delete d->m_Queue;
     }
-    m_Queue = new MidiQueue(this, queueName, this);
-    return m_Queue;
+    d->m_Queue = new MidiQueue(this, queueName, this);
+    return d->m_Queue;
 }
 
 /**
@@ -1194,11 +1281,11 @@ MidiClient::createQueue(QString const& queueName )
 MidiQueue*
 MidiClient::useQueue(int queue_id)
 {
-    if (m_Queue != NULL) {
-        delete m_Queue;
+    if (d->m_Queue != NULL) {
+        delete d->m_Queue;
     }
-    m_Queue = new MidiQueue(this, queue_id, this);
-    return m_Queue;
+    d->m_Queue = new MidiQueue(this, queue_id, this);
+    return d->m_Queue;
 }
 
 /**
@@ -1211,14 +1298,14 @@ MidiClient::useQueue(int queue_id)
 MidiQueue*
 MidiClient::useQueue(const QString& name)
 {
-    if (m_Queue != NULL) {
-        delete m_Queue;
+    if (d->m_Queue != NULL) {
+        delete d->m_Queue;
     }
     int queue_id = getQueueId(name);
     if ( queue_id >= 0) {
-       m_Queue = new MidiQueue(this, queue_id, this);
+       d->m_Queue = new MidiQueue(this, queue_id, this);
     }
-    return m_Queue;
+    return d->m_Queue;
 }
 
 /**
@@ -1230,12 +1317,12 @@ MidiClient::useQueue(const QString& name)
 MidiQueue*
 MidiClient::useQueue(MidiQueue* queue)
 {
-    if (m_Queue != NULL) {
-        delete m_Queue;
+    if (d->m_Queue != NULL) {
+        delete d->m_Queue;
     }
     queue->setParent(this);
-    m_Queue = queue;
-    return m_Queue;
+    d->m_Queue = queue;
+    return d->m_Queue;
 }
 
 /**
@@ -1251,7 +1338,7 @@ MidiClient::getAvailableQueues()
     snd_seq_queue_info_alloca(&qinfo);
     max = getSystemInfo().getMaxQueues();
     for ( q = 0; q < max; ++q ) {
-        err = snd_seq_get_queue_info(m_SeqHandle, q, qinfo);
+        err = snd_seq_get_queue_info(d->m_SeqHandle, q, qinfo);
         if (err == 0) {
             queues.append(q);
         }
@@ -1273,13 +1360,13 @@ MidiClient::filterPorts(unsigned int filter)
     ClientInfoList::ConstIterator itc;
     PortInfoList::ConstIterator itp;
 
-    if (m_NeedRefreshClientList)
+    if (d->m_NeedRefreshClientList)
         readClients();
 
-    for (itc = m_ClientList.constBegin(); itc != m_ClientList.constEnd(); ++itc) {
+    for (itc = d->m_ClientList.constBegin(); itc != d->m_ClientList.constEnd(); ++itc) {
         ClientInfo ci = (*itc);
         if ((ci.getClientId() == SND_SEQ_CLIENT_SYSTEM) ||
-            (ci.getClientId() == m_Info.getClientId()))
+            (ci.getClientId() == d->m_Info.getClientId()))
             continue;
         PortInfoList lstPorts = ci.getPorts();
         for(itp = lstPorts.constBegin(); itp != lstPorts.constEnd(); ++itp) {
@@ -1300,11 +1387,11 @@ MidiClient::filterPorts(unsigned int filter)
 void
 MidiClient::updateAvailablePorts()
 {
-    m_InputsAvail.clear();
-    m_OutputsAvail.clear();
-    m_InputsAvail = filterPorts( SND_SEQ_PORT_CAP_READ |
+    d->m_InputsAvail.clear();
+    d->m_OutputsAvail.clear();
+    d->m_InputsAvail = filterPorts( SND_SEQ_PORT_CAP_READ |
                                  SND_SEQ_PORT_CAP_SUBS_READ );
-    m_OutputsAvail = filterPorts( SND_SEQ_PORT_CAP_WRITE |
+    d->m_OutputsAvail = filterPorts( SND_SEQ_PORT_CAP_WRITE |
                                   SND_SEQ_PORT_CAP_SUBS_WRITE );
 }
 
@@ -1315,9 +1402,9 @@ MidiClient::updateAvailablePorts()
 PortInfoList
 MidiClient::getAvailableInputs()
 {
-    m_NeedRefreshClientList = true;
+    d->m_NeedRefreshClientList = true;
     updateAvailablePorts();
-    return m_InputsAvail;
+    return d->m_InputsAvail;
 }
 
 /**
@@ -1327,9 +1414,9 @@ MidiClient::getAvailableInputs()
 PortInfoList
 MidiClient::getAvailableOutputs()
 {
-    m_NeedRefreshClientList = true;
+    d->m_NeedRefreshClientList = true;
     updateAvailablePorts();
-    return m_OutputsAvail;
+    return d->m_OutputsAvail;
 }
 
 /**
@@ -1341,7 +1428,7 @@ MidiClient::getAvailableOutputs()
 void
 MidiClient::addListener(QObject* listener)
 {
-    m_listeners.append(listener);
+    d->m_listeners.append(listener);
 }
 
 /**
@@ -1352,7 +1439,7 @@ MidiClient::addListener(QObject* listener)
 void
 MidiClient::removeListener(QObject* listener)
 {
-    m_listeners.removeAll(listener);
+    d->m_listeners.removeAll(listener);
 }
 
 /**
@@ -1364,8 +1451,8 @@ MidiClient::removeListener(QObject* listener)
 void
 MidiClient::setEventsEnabled(bool bEnabled)
 {
-    if (bEnabled != m_eventsEnabled) {
-        m_eventsEnabled = bEnabled;
+    if (bEnabled != d->m_eventsEnabled) {
+        d->m_eventsEnabled = bEnabled;
     }
 }
 
@@ -1376,8 +1463,8 @@ MidiClient::setEventsEnabled(bool bEnabled)
 SystemInfo&
 MidiClient::getSystemInfo()
 {
-    snd_seq_system_info(m_SeqHandle, m_sysInfo.m_Info);
-    return m_sysInfo;
+    snd_seq_system_info(d->m_SeqHandle, d->m_sysInfo.m_Info);
+    return d->m_sysInfo;
 }
 
 /**
@@ -1387,8 +1474,8 @@ MidiClient::getSystemInfo()
 PoolInfo&
 MidiClient::getPoolInfo()
 {
-    snd_seq_get_client_pool(m_SeqHandle, m_poolInfo.m_Info);
-    return m_poolInfo;
+    snd_seq_get_client_pool(d->m_SeqHandle, d->m_poolInfo.m_Info);
+    return d->m_poolInfo;
 }
 
 /**
@@ -1398,8 +1485,8 @@ MidiClient::getPoolInfo()
 void
 MidiClient::setPoolInfo(const PoolInfo& info)
 {
-    m_poolInfo = info;
-    CHECK_WARNING(snd_seq_set_client_pool(m_SeqHandle, m_poolInfo.m_Info));
+    d->m_poolInfo = info;
+    CHECK_WARNING(snd_seq_set_client_pool(d->m_SeqHandle, d->m_poolInfo.m_Info));
 }
 
 /**
@@ -1409,7 +1496,7 @@ MidiClient::setPoolInfo(const PoolInfo& info)
 void
 MidiClient::resetPoolInput()
 {
-    CHECK_WARNING(snd_seq_reset_pool_input(m_SeqHandle));
+    CHECK_WARNING(snd_seq_reset_pool_input(d->m_SeqHandle));
 }
 
 /**
@@ -1419,7 +1506,7 @@ MidiClient::resetPoolInput()
 void
 MidiClient::resetPoolOutput()
 {
-    CHECK_WARNING(snd_seq_reset_pool_output(m_SeqHandle));
+    CHECK_WARNING(snd_seq_reset_pool_output(d->m_SeqHandle));
 }
 
 /**
@@ -1429,7 +1516,7 @@ MidiClient::resetPoolOutput()
 void
 MidiClient::setPoolInput(int size)
 {
-    CHECK_WARNING(snd_seq_set_client_pool_input(m_SeqHandle, size));
+    CHECK_WARNING(snd_seq_set_client_pool_input(d->m_SeqHandle, size));
 }
 
 /**
@@ -1439,7 +1526,7 @@ MidiClient::setPoolInput(int size)
 void
 MidiClient::setPoolOutput(int size)
 {
-    CHECK_WARNING(snd_seq_set_client_pool_output(m_SeqHandle, size));
+    CHECK_WARNING(snd_seq_set_client_pool_output(d->m_SeqHandle, size));
 }
 
 /**
@@ -1449,7 +1536,7 @@ MidiClient::setPoolOutput(int size)
 void
 MidiClient::setPoolOutputRoom(int size)
 {
-    CHECK_WARNING(snd_seq_set_client_pool_output_room(m_SeqHandle, size));
+    CHECK_WARNING(snd_seq_set_client_pool_output_room(d->m_SeqHandle, size));
 }
 
 /**
@@ -1459,7 +1546,7 @@ MidiClient::setPoolOutputRoom(int size)
 void
 MidiClient::dropInput()
 {
-    CHECK_WARNING(snd_seq_drop_input(m_SeqHandle));
+    CHECK_WARNING(snd_seq_drop_input(d->m_SeqHandle));
 }
 
 /**
@@ -1469,7 +1556,7 @@ MidiClient::dropInput()
 void
 MidiClient::dropInputBuffer()
 {
-    CHECK_WARNING(snd_seq_drop_input_buffer(m_SeqHandle));
+    CHECK_WARNING(snd_seq_drop_input_buffer(d->m_SeqHandle));
 }
 
 /**
@@ -1482,7 +1569,7 @@ MidiClient::dropInputBuffer()
 void
 MidiClient::dropOutput()
 {
-    CHECK_WARNING(snd_seq_drop_output(m_SeqHandle));
+    CHECK_WARNING(snd_seq_drop_output(d->m_SeqHandle));
 }
 
 /**
@@ -1495,7 +1582,7 @@ MidiClient::dropOutput()
 void
 MidiClient::dropOutputBuffer()
 {
-    CHECK_WARNING(snd_seq_drop_output_buffer(m_SeqHandle));
+    CHECK_WARNING(snd_seq_drop_output_buffer(d->m_SeqHandle));
 }
 
 /**
@@ -1507,7 +1594,7 @@ MidiClient::dropOutputBuffer()
 void
 MidiClient::removeEvents(const RemoveEvents* spec)
 {
-    CHECK_WARNING(snd_seq_remove_events(m_SeqHandle, spec->m_Info));
+    CHECK_WARNING(snd_seq_remove_events(d->m_SeqHandle, spec->m_Info));
 }
 
 /**
@@ -1518,7 +1605,7 @@ SequencerEvent*
 MidiClient::extractOutput()
 {
     snd_seq_event_t* ev;
-    if (CHECK_WARNING(snd_seq_extract_output(m_SeqHandle, &ev) == 0)) {
+    if (CHECK_WARNING(snd_seq_extract_output(d->m_SeqHandle, &ev) == 0)) {
         return new SequencerEvent(ev);
     }
     return NULL;
@@ -1532,7 +1619,7 @@ MidiClient::extractOutput()
 int
 MidiClient::outputPending()
 {
-    return snd_seq_event_output_pending(m_SeqHandle);
+    return snd_seq_event_output_pending(d->m_SeqHandle);
 }
 
 /**
@@ -1551,7 +1638,7 @@ MidiClient::outputPending()
 int
 MidiClient::inputPending(bool fetch)
 {
-    return snd_seq_event_input_pending(m_SeqHandle, fetch ? 1 : 0);
+    return snd_seq_event_input_pending(d->m_SeqHandle, fetch ? 1 : 0);
 }
 
 /**
@@ -1563,7 +1650,7 @@ MidiClient::inputPending(bool fetch)
 int
 MidiClient::getQueueId(const QString& name)
 {
-    return snd_seq_query_named_queue(m_SeqHandle, name.toLocal8Bit().data());
+    return snd_seq_query_named_queue(d->m_SeqHandle, name.toLocal8Bit().data());
 }
 
 /**
@@ -1574,7 +1661,7 @@ MidiClient::getQueueId(const QString& name)
 int
 MidiClient::getPollDescriptorsCount(short events)
 {
-    return snd_seq_poll_descriptors_count(m_SeqHandle, events);
+    return snd_seq_poll_descriptors_count(d->m_SeqHandle, events);
 }
 
 /**
@@ -1594,7 +1681,7 @@ int
 MidiClient::pollDescriptors( struct pollfd *pfds, unsigned int space,
                              short events )
 {
-    return snd_seq_poll_descriptors(m_SeqHandle, pfds, space, events);
+    return snd_seq_poll_descriptors(d->m_SeqHandle, pfds, space, events);
 }
 
 /**
@@ -1607,7 +1694,7 @@ unsigned short
 MidiClient::pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds)
 {
     unsigned short revents;
-    CHECK_WARNING( snd_seq_poll_descriptors_revents( m_SeqHandle,
+    CHECK_WARNING( snd_seq_poll_descriptors_revents( d->m_SeqHandle,
                                                      pfds, nfds,
                                                      &revents ));
     return revents;
@@ -1620,7 +1707,7 @@ MidiClient::pollDescriptorsRevents(struct pollfd *pfds, unsigned int nfds)
 const char *
 MidiClient::_getDeviceName()
 {
-    return snd_seq_name(m_SeqHandle);
+    return snd_seq_name(d->m_SeqHandle);
 }
 
 /**
@@ -1630,7 +1717,7 @@ MidiClient::_getDeviceName()
 void
 MidiClient::_setClientName(const char *name)
 {
-    CHECK_WARNING(snd_seq_set_client_name(m_SeqHandle, name));
+    CHECK_WARNING(snd_seq_set_client_name(d->m_SeqHandle, name));
 }
 
 /**
@@ -1645,7 +1732,7 @@ MidiClient::createSimplePort( const char *name,
                               unsigned int caps,
                               unsigned int type )
 {
-    return CHECK_WARNING( snd_seq_create_simple_port( m_SeqHandle,
+    return CHECK_WARNING( snd_seq_create_simple_port( d->m_SeqHandle,
                                                       name, caps, type ));
 }
 
@@ -1656,7 +1743,7 @@ MidiClient::createSimplePort( const char *name,
 void
 MidiClient::deleteSimplePort(int port)
 {
-    CHECK_WARNING( snd_seq_delete_simple_port( m_SeqHandle, port ));
+    CHECK_WARNING( snd_seq_delete_simple_port( d->m_SeqHandle, port ));
 }
 
 /**
@@ -1668,7 +1755,7 @@ MidiClient::deleteSimplePort(int port)
 void
 MidiClient::connectFrom(int myport, int client, int port)
 {
-    CHECK_WARNING( snd_seq_connect_from(m_SeqHandle, myport, client, port ));
+    CHECK_WARNING( snd_seq_connect_from(d->m_SeqHandle, myport, client, port ));
 }
 
 /**
@@ -1680,7 +1767,7 @@ MidiClient::connectFrom(int myport, int client, int port)
 void
 MidiClient::connectTo(int myport, int client, int port)
 {
-    CHECK_WARNING( snd_seq_connect_to(m_SeqHandle, myport, client, port ));
+    CHECK_WARNING( snd_seq_connect_to(d->m_SeqHandle, myport, client, port ));
 }
 
 /**
@@ -1692,7 +1779,7 @@ MidiClient::connectTo(int myport, int client, int port)
 void
 MidiClient::disconnectFrom(int myport, int client, int port)
 {
-    CHECK_WARNING( snd_seq_disconnect_from(m_SeqHandle, myport, client, port ));
+    CHECK_WARNING( snd_seq_disconnect_from(d->m_SeqHandle, myport, client, port ));
 }
 
 /**
@@ -1704,7 +1791,7 @@ MidiClient::disconnectFrom(int myport, int client, int port)
 void
 MidiClient::disconnectTo(int myport, int client, int port)
 {
-    CHECK_WARNING( snd_seq_disconnect_to(m_SeqHandle, myport, client, port ));
+    CHECK_WARNING( snd_seq_disconnect_to(d->m_SeqHandle, myport, client, port ));
 }
 
 /**
@@ -1736,10 +1823,10 @@ MidiClient::parseAddress( const QString& straddr, snd_seq_addr& addr )
     if (ok)
         addr.port = testPort.toInt(&ok);
     if (!ok) {
-        if (m_NeedRefreshClientList)
+        if (d->m_NeedRefreshClientList)
             readClients();
-        for ( cit = m_ClientList.constBegin();
-              cit != m_ClientList.constEnd(); ++cit ) {
+        for ( cit = d->m_ClientList.constBegin();
+              cit != d->m_ClientList.constEnd(); ++cit ) {
             ClientInfo ci = *cit;
             if (testClient.compare(ci.getName(), Qt::CaseInsensitive) == 0) {
                 addr.client = ci.getClientId();
@@ -1758,7 +1845,7 @@ MidiClient::parseAddress( const QString& straddr, snd_seq_addr& addr )
 bool
 MidiClient::SequencerInputThread::stopped()
 {
-	QReadLocker locker(&m_mutex);
+    QReadLocker locker(&m_mutex);
     return m_Stopped;
 }
 
@@ -1768,7 +1855,7 @@ MidiClient::SequencerInputThread::stopped()
 void
 MidiClient::SequencerInputThread::stop()
 {
-	QWriteLocker locker(&m_mutex);
+    QWriteLocker locker(&m_mutex);
     m_Stopped = true;
 }
 
@@ -2514,7 +2601,7 @@ getRuntimeALSALibraryNumber()
 QString
 getRuntimeALSADriverVersion()
 {
-    QRegExp rx(".*Driver Version ([\\d\\.]+).*");
+    QRegExp rx(".*Driver Version.*([\\d\\.]+).*");
     QString s;
     QFile f("/proc/asound/version");
     if (f.open(QFile::ReadOnly)) {
diff --git a/library/src/alsaevent.cpp b/library/alsa/alsaevent.cpp
similarity index 99%
rename from library/src/alsaevent.cpp
rename to library/alsa/alsaevent.cpp
index 1781c4f..b758607 100644
--- a/library/src/alsaevent.cpp
+++ b/library/alsa/alsaevent.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@
 /**
  * @class QEvent
  * The QEvent class is the base class of all event classes.
- * @see http://doc.trolltech.com/qevent.html
+ * @see http://qt-project.org/doc/qt-5/qevent.html
  */
 
 namespace drumstick {
diff --git a/library/src/alsaport.cpp b/library/alsa/alsaport.cpp
similarity index 99%
rename from library/src/alsaport.cpp
rename to library/alsa/alsaport.cpp
index 4a4d1c5..77c6d0d 100644
--- a/library/src/alsaport.cpp
+++ b/library/alsa/alsaport.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/src/alsaqueue.cpp b/library/alsa/alsaqueue.cpp
similarity index 99%
rename from library/src/alsaqueue.cpp
rename to library/alsa/alsaqueue.cpp
index eb8a503..52e0052 100644
--- a/library/src/alsaqueue.cpp
+++ b/library/alsa/alsaqueue.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
  
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/src/alsatimer.cpp b/library/alsa/alsatimer.cpp
similarity index 99%
rename from library/src/alsatimer.cpp
rename to library/alsa/alsatimer.cpp
index 5da3aa7..dd8ec43 100644
--- a/library/src/alsatimer.cpp
+++ b/library/alsa/alsatimer.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/src/playthread.cpp b/library/alsa/playthread.cpp
similarity index 98%
rename from library/src/playthread.cpp
rename to library/alsa/playthread.cpp
index 06bf9e4..5d29ea3 100644
--- a/library/src/playthread.cpp
+++ b/library/alsa/playthread.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/src/subscription.cpp b/library/alsa/subscription.cpp
similarity index 99%
rename from library/src/subscription.cpp
rename to library/alsa/subscription.cpp
index ef138a4..af59a85 100644
--- a/library/src/subscription.cpp
+++ b/library/alsa/subscription.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
  
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/drumstick-alsa.pro b/library/drumstick-alsa.pro
deleted file mode 100644
index 397603b..0000000
--- a/library/drumstick-alsa.pro
+++ /dev/null
@@ -1,30 +0,0 @@
-TEMPLATE = lib
-TARGET = drumstick-alsa
-DESTDIR = ../build/lib
-OBJECTS_DIR = ../build/obj
-MOC_DIR = ../build/moc
-DEPENDPATH += . include src
-INCLUDEPATH += . include
-include (../global.pri)
-QT += dbus
-CONFIG += qt thread 
-DEFINES += drumstick_alsa_EXPORTS RTKIT_SUPPORT
-QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_HIDESYMS
-# Input
-HEADERS += include/alsaclient.h \
-           include/alsaevent.h \
-           include/alsaport.h \
-           include/alsaqueue.h \
-           include/alsatimer.h \
-           include/drumstick.h \
-           include/drumstickcommon.h \
-           include/macros.h \
-           include/playthread.h \
-           include/subscription.h
-SOURCES += src/alsaclient.cpp \
-           src/alsaevent.cpp \
-           src/alsaport.cpp \
-           src/alsaqueue.cpp \
-           src/alsatimer.cpp \
-           src/playthread.cpp \
-           src/subscription.cpp
diff --git a/library/drumstick-file.pro b/library/drumstick-file.pro
deleted file mode 100644
index 66db0dc..0000000
--- a/library/drumstick-file.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-TEMPLATE = lib
-TARGET = drumstick-file
-DESTDIR = ../build/lib
-OBJECTS_DIR = ../build/obj
-MOC_DIR = ../build/moc
-DEPENDPATH += . include src
-INCLUDEPATH += . include
-include (../global.pri)
-CONFIG += qt
-DEFINES += drumstick_file_EXPORTS
-QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_HIDESYMS
-# Input
-HEADERS += include/macros.h \
-           include/qsmf.h \
-           include/qwrk.h \
-           include/qove.h
-SOURCES += src/qsmf.cpp \
-           src/qwrk.cpp \
-           src/qove.cpp
diff --git a/library/file/CMakeLists.txt b/library/file/CMakeLists.txt
new file mode 100644
index 0000000..4491a69
--- /dev/null
+++ b/library/file/CMakeLists.txt
@@ -0,0 +1,65 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(drumstick-file_QTOBJ_SRCS
+    ../include/qsmf.h
+    ../include/qwrk.h
+    ../include/qove.h
+)
+
+set(drumstick-file_HEADERS
+    ../include/macros.h
+    ../include/qsmf.h
+    ../include/qwrk.h
+    ../include/qove.h
+)
+
+set(drumstick-file_SRCS
+    qsmf.cpp
+    qwrk.cpp
+    qove.cpp
+)
+
+qt5_wrap_cpp(drumstick-file_MOC_SRCS ${drumstick-file_QTOBJ_SRCS})
+
+add_library(drumstick-file
+    ${drumstick-file_MOC_SRCS}
+    ${drumstick-file_SRCS} 
+    ${drumstick-file_HEADERS} 
+)
+
+target_link_libraries(drumstick-file Qt5::Core)
+
+if(STATIC_DRUMSTICK)
+    set_target_properties(drumstick-file PROPERTIES
+        STATIC_LIB "libdrumstick-file")
+else()
+    set_target_properties(drumstick-file PROPERTIES
+        VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
+        SOVERSION ${VERSION_MAJOR})
+endif()
+
+install(TARGETS drumstick-file
+	RUNTIME DESTINATION bin
+	ARCHIVE DESTINATION lib${LIB_SUFFIX}
+	LIBRARY DESTINATION lib${LIB_SUFFIX})
+
+install(FILES ${drumstick-file_HEADERS}
+        DESTINATION include/drumstick)
diff --git a/library/file/file.pro b/library/file/file.pro
new file mode 100644
index 0000000..8191d32
--- /dev/null
+++ b/library/file/file.pro
@@ -0,0 +1,36 @@
+TEMPLATE = lib
+TARGET = $$qtLibraryTarget(drumstick-file)
+DESTDIR = ../../build/lib
+DEPENDPATH += . ../include
+INCLUDEPATH += . ../include
+include (../../global.pri)
+CONFIG += qt #create_prl
+DEFINES += drumstick_file_EXPORTS
+QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_HIDESYMS
+QT -= gui
+# Input
+HEADERS += ../include/macros.h \
+           ../include/qsmf.h \
+           ../include/qwrk.h \
+           ../include/qove.h
+SOURCES += qsmf.cpp \
+           qwrk.cpp \
+           qove.cpp
+win32 {
+    TARGET_EXT = .dll
+}
+
+static {
+    DEFINES += DRUMSTICK_STATIC
+}
+
+macx {
+    TARGET = drumstick-file
+    CONFIG += lib_bundle
+    FRAMEWORK_HEADERS.version = Versions
+    FRAMEWORK_HEADERS.files = $$HEADERS
+    FRAMEWORK_HEADERS.path = Headers
+    QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS
+    #QMAKE_LFLAGS_SONAME = -Wl,-install_name, at executable_path/../Frameworks/
+    QMAKE_SONAME_PREFIX = @rpath
+}
diff --git a/library/src/qove.cpp b/library/file/qove.cpp
similarity index 99%
rename from library/src/qove.cpp
rename to library/file/qove.cpp
index 54f942c..516ebd7 100644
--- a/library/src/qove.cpp
+++ b/library/file/qove.cpp
@@ -1,6 +1,6 @@
 /*
     Overture OVE File component
-    Copyright (C) 2006-2010, Rui Fan <vanferry at gmail.com>
+    Copyright (C) 2006-2015, Rui Fan <vanferry at gmail.com>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/src/qsmf.cpp b/library/file/qsmf.cpp
similarity index 99%
rename from library/src/qsmf.cpp
rename to library/file/qsmf.cpp
index 5ab5404..edd3682 100644
--- a/library/src/qsmf.cpp
+++ b/library/file/qsmf.cpp
@@ -1,6 +1,6 @@
 /*
     Standard MIDI File component
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     Based on midifile.c by Tim Thompson, M.Czeiszperger and Greg Lee
 
diff --git a/library/src/qwrk.cpp b/library/file/qwrk.cpp
similarity index 99%
rename from library/src/qwrk.cpp
rename to library/file/qwrk.cpp
index e9e7a1e..562da66 100644
--- a/library/src/qwrk.cpp
+++ b/library/file/qwrk.cpp
@@ -1,6 +1,6 @@
 /*
     WRK File component
-    Copyright (C) 2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2010-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -857,7 +857,7 @@ void QWrk::processMeterChunk()
         readGap(4);
         int measure = read16bit();
         int  num = readByte();
-        int  den = pow(2, readByte());
+        int  den = pow(2.0, readByte());
         readGap(4);
         Q_EMIT signalWRKTimeSig(measure, num, den);
     }
@@ -869,7 +869,7 @@ void QWrk::processMeterKeyChunk()
     for (int i = 0; i < count; ++i) {
         int measure = read16bit();
         int  num = readByte();
-        int  den = pow(2, readByte());
+        int  den = pow(2.0, readByte());
         qint8 alt = readByte();
         Q_EMIT signalWRKTimeSig(measure, num, den);
         Q_EMIT signalWRKKeySig(measure, alt);
diff --git a/library/include/alsaclient.h b/library/include/alsaclient.h
index 5103b47..7b2c4aa 100644
--- a/library/include/alsaclient.h
+++ b/library/include/alsaclient.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -231,21 +231,16 @@ public:
 
     int getClientId();
     snd_seq_type_t getSequencerType();
-    /** Returns the sequencer handler managed by ALSA */
-    snd_seq_t* getHandle() { return m_SeqHandle; }
-    /** Returns true if the sequencer is opened */
-    bool isOpened() { return (m_SeqHandle != NULL); }
+    snd_seq_t* getHandle();
+    bool isOpened();
 
     size_t getOutputBufferSize();
     void setOutputBufferSize(size_t newSize);
     size_t getInputBufferSize();
     void setInputBufferSize(size_t newSize);
-    /** Returns the name of the sequencer device */
-    QString getDeviceName() { return m_DeviceName; }
-    /** Returns the last open mode used in open() */
-    int getOpenMode() { return m_OpenMode; }
-    /** Returns the last block mode used in open() */
-    bool getBlockMode() { return m_BlockMode; }
+    QString getDeviceName();
+    int getOpenMode();
+    bool getBlockMode();
     void setBlockMode(bool newValue);
     QString getClientName();
     QString getClientName(const int clientId);
@@ -284,10 +279,8 @@ public:
     void addListener(QObject* listener);
     void removeListener(QObject* listener);
     void setEventsEnabled(const bool bEnabled);
-    /** Returns true if the events mode of delivery has been enabled */
-    bool getEventsEnabled() const { return m_eventsEnabled; }
-    /** Sets a sequencer event handler enabling the callback delivery mode */
-    void setHandler(SequencerEventHandler* handler)  { m_handler = handler; }
+    bool getEventsEnabled() const;
+    void setHandler(SequencerEventHandler* handler);
     bool parseAddress( const QString& straddr, snd_seq_addr& result );
     void setRealTimeInput(bool enabled);
     bool realTimeInputEnabled();
@@ -323,24 +316,8 @@ protected:
 
 private:
     class SequencerInputThread;
-    bool m_eventsEnabled;
-    bool m_BlockMode;
-    bool m_NeedRefreshClientList;
-    int  m_OpenMode;
-    QString m_DeviceName;
-    snd_seq_t* m_SeqHandle;
-    QPointer<SequencerInputThread> m_Thread;
-    QPointer<MidiQueue> m_Queue;
-    SequencerEventHandler* m_handler;
-
-    ClientInfo m_Info;
-    ClientInfoList m_ClientList;
-    MidiPortList m_Ports;
-    PortInfoList m_OutputsAvail;
-    PortInfoList m_InputsAvail;
-    QObjectList m_listeners;
-    SystemInfo m_sysInfo;
-    PoolInfo m_poolInfo;
+    class MidiClientPrivate;
+    MidiClientPrivate *d;
 };
 
 #if SND_LIB_VERSION > 0x010004
diff --git a/library/include/alsaevent.h b/library/include/alsaevent.h
index e1a3943..6df8bca 100644
--- a/library/include/alsaevent.h
+++ b/library/include/alsaevent.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/include/alsaport.h b/library/include/alsaport.h
index 50ebfd4..0e2f840 100644
--- a/library/include/alsaport.h
+++ b/library/include/alsaport.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/include/alsaqueue.h b/library/include/alsaqueue.h
index 3a401be..2f923bf 100644
--- a/library/include/alsaqueue.h
+++ b/library/include/alsaqueue.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/include/alsatimer.h b/library/include/alsatimer.h
index ab0f4cf..999e20b 100644
--- a/library/include/alsatimer.h
+++ b/library/include/alsatimer.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
  
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/include/backendmanager.h b/library/include/backendmanager.h
new file mode 100644
index 0000000..7542053
--- /dev/null
+++ b/library/include/backendmanager.h
@@ -0,0 +1,96 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef BACKENDMANAGER_H
+#define BACKENDMANAGER_H
+
+#include <QObject>
+#include "macros.h"
+#include "rtmidiinput.h"
+#include "rtmidioutput.h"
+
+/**
+ * @file backendmanager.h
+ * Realtime MIDI input/output multiplatform classes
+ * @defgroup RT Realtime MIDI (I/O)
+ * @{
+ */
+
+namespace drumstick {
+namespace rt {
+
+    const QString QSTR_DRUMSTICK(QLatin1Literal("drumstick"));
+    const QString QSTR_DRUMSTICKRT(QLatin1Literal("DRUMSTICKRT"));
+    const QString QSTR_DRUMSTICKRT_GROUP(QLatin1Literal("DrumstickRT"));
+    const QString QSTR_DRUMSTICKRT_PUBLICNAMEIN(QLatin1Literal("PublicNameIN"));
+    const QString QSTR_DRUMSTICKRT_PUBLICNAMEOUT(QLatin1Literal("PublicNameOUT"));
+    const QString QSTR_DRUMSTICKRT_EXCLUDED(QLatin1Literal("ExcludedNames"));
+    const QString QSTR_DRUMSTICKRT_PATH(QLatin1Literal("BackendsPath"));
+
+    /**
+     * @brief The BackendManager class manages lists of dynamic and static
+     * backends for applications based on drumstick-rt
+     */
+    class DRUMSTICK_EXPORT BackendManager
+    {
+    public:
+        /**
+         * @brief BackendManager constructor
+         */
+        explicit BackendManager();
+
+        /**
+         * @brief ~BackendManager destructor
+         */
+        virtual ~BackendManager();
+
+        /**
+         * @brief refresh the list of backends
+         * @param settings Program settings
+         */
+        void refresh(QSettings* settings = 0);
+
+        /**
+         * @brief availableInputs
+         * @return list of available MIDI inputs
+         */
+        QList<MIDIInput*> availableInputs();
+
+        /**
+         * @brief availableOutputs
+         * @return list of available MIDI outputs
+         */
+        QList<MIDIOutput*> availableOutputs();
+
+        /**
+         * @brief defaultPaths
+         * @return list of paths for backends search
+         */
+        QStringList defaultPaths();
+
+    private:
+        class BackendManagerPrivate;
+        BackendManagerPrivate *d;
+    };
+
+}}
+
+/** @} */
+
+#endif // BACKENDMANAGER_H
diff --git a/library/include/drumstick.h b/library/include/drumstick.h
index 9f53e72..28bbfb1 100644
--- a/library/include/drumstick.h
+++ b/library/include/drumstick.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -19,12 +19,13 @@
 
 #ifndef DRUMSTICK_H
 #define DRUMSTICK_H
-
+#include <QtCore>
 /**
  * @file drumstick.h
- * The main header that a program can include to use all the drumstick features.
+ * The main header that a program can include to use all drumstick features.
  */
 
+#if defined(Q_OS_LINUX)
 // ALSA library interface
 #include <drumstick/alsaclient.h>
 #include <drumstick/alsaevent.h>
@@ -34,10 +35,16 @@
 #include <drumstick/drumstickcommon.h>
 #include <drumstick/playthread.h>
 #include <drumstick/subscription.h>
+#endif
 
 // File formats
 #include <drumstick/qsmf.h>
 #include <drumstick/qwrk.h>
 #include <drumstick/qove.h>
 
+// RealTime interfaces
+#include <drumstick/rtmidiinput.h>
+#include <drumstick/rtmidioutput.h>
+#include <drumstick/backendmanager.h>
+
 #endif /*DRUMSTICK_H*/
diff --git a/library/include/drumstickcommon.h b/library/include/drumstickcommon.h
index 444fa39..baada41 100644
--- a/library/include/drumstickcommon.h
+++ b/library/include/drumstickcommon.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
 #include "macros.h"
 #include <qglobal.h>
 #include <QString>
-#include <QApplication>
+#include <QCoreApplication>
 #include <QtDebug>
 
 extern "C" {
diff --git a/library/include/macros.h b/library/include/macros.h
index 148ad98..dc9bd7c 100644
--- a/library/include/macros.h
+++ b/library/include/macros.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -33,10 +33,10 @@
 #  if defined(DRUMSTICK_STATIC)
 #    define DRUMSTICK_EXPORT
 #  else
-#    if defined(drumstick_alsa_EXPORTS) || defined(drumstick_file_EXPORTS)
+#    if defined(drumstick_alsa_EXPORTS) || defined(drumstick_file_EXPORTS) || defined(drumstick_rt_EXPORTS)
 #      define DRUMSTICK_EXPORT Q_DECL_EXPORT
 #    else
-#      if defined(Q_WS_WIN)
+#      if defined(Q_OS_WIN)
 #        define DRUMSTICK_EXPORT Q_DECL_IMPORT
 #      else
 #        define DRUMSTICK_EXPORT Q_DECL_EXPORT
diff --git a/library/include/playthread.h b/library/include/playthread.h
index 433a43b..8addd66 100644
--- a/library/include/playthread.h
+++ b/library/include/playthread.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/include/qove.h b/library/include/qove.h
index 4553f55..1ac21f4 100644
--- a/library/include/qove.h
+++ b/library/include/qove.h
@@ -1,6 +1,6 @@
 /*
     Overture OVE File component
-    Copyright (C) 2006-2010, Rui Fan <vanferry at gmail.com>
+    Copyright (C) 2006-2015, Rui Fan <vanferry at gmail.com>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/include/qsmf.h b/library/include/qsmf.h
index 6dd18b9..631d2f6 100644
--- a/library/include/qsmf.h
+++ b/library/include/qsmf.h
@@ -1,6 +1,6 @@
 /*
     Standard MIDI File component
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     Based on midifile.c by Tim Thompson, M.Czeiszperger and Greg Lee
 
diff --git a/library/include/qwrk.h b/library/include/qwrk.h
index 5c983c8..7401e29 100644
--- a/library/include/qwrk.h
+++ b/library/include/qwrk.h
@@ -1,6 +1,6 @@
 /*
     WRK File component
-    Copyright (C) 2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2010-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/include/rtmidiinput.h b/library/include/rtmidiinput.h
new file mode 100644
index 0000000..04ac1ec
--- /dev/null
+++ b/library/include/rtmidiinput.h
@@ -0,0 +1,188 @@
+/*
+    Drumstick MIDI realtime input-output
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef MIDIINPUT_H
+#define MIDIINPUT_H
+
+#include <QObject>
+#include <QString>
+#include <QStringList>
+#include <QtPlugin>
+#include <QSettings>
+
+#include "rtmidioutput.h"
+
+namespace drumstick {
+namespace rt {
+
+    /**
+     * MIDI IN interface
+     */
+    class MIDIInput : public QObject
+    {
+        Q_OBJECT
+
+    public:
+        /**
+         * @brief MIDIInput constructor
+         * @param parent
+         */
+        explicit MIDIInput(QObject *parent = 0) : QObject(parent) {}
+        /**
+         * @brief ~MIDIInput destructor
+         */
+        virtual ~MIDIInput() {}
+        /**
+         * @brief initialize
+         * @param settings
+         */
+        virtual void initialize(QSettings* settings) = 0;
+        /**
+         * @brief backendName
+         * @return plugin name
+         */
+        virtual QString backendName() = 0;
+        /**
+         * @brief publicName
+         * @return MIDI port name
+         */
+        virtual QString publicName() = 0;
+        /**
+         * @brief setPublicName
+         * @param name MIDI port name
+         */
+        virtual void setPublicName(QString name) = 0;
+        /**
+         * @brief connections
+         * @return list of available MIDI ports
+         */
+        virtual QStringList connections(bool advanced = false) = 0;
+        /**
+         * @brief setExcludedConnections
+         * @param conns
+         */
+        virtual void setExcludedConnections(QStringList conns) = 0;
+        /**
+         * @brief open the MIDI port by name
+         * @param name
+         */
+        virtual void open(QString name) = 0;
+        /**
+         * @brief close the MIDI port
+         */
+        virtual void close() = 0;
+        /**
+         * @brief currentConnection
+         * @return name of the current connection if it is opened
+         */
+        virtual QString currentConnection() = 0;
+        /**
+         * @brief setMIDIThruDevice
+         * @param device
+         */
+        virtual void setMIDIThruDevice(MIDIOutput* device) = 0;
+        /**
+         * @brief enableMIDIThru
+         * @param enable
+         */
+        virtual void enableMIDIThru(bool enable) = 0;
+        /**
+         * @brief isEnabledMIDIThru
+         * @return
+         */
+        virtual bool isEnabledMIDIThru() = 0;
+
+    Q_SIGNALS:
+        /**
+         * @brief midiNoteOff 0x8
+         * @param chan
+         * @param note
+         * @param vel
+         */
+        void midiNoteOff(const int chan, const int note, const int vel);
+
+        /**
+         * @brief midiNoteOn 0x9
+         * @param chan
+         * @param note
+         * @param vel
+         */
+        void midiNoteOn(const int chan, const int note, const int vel);
+
+        /**
+         * @brief midiKeyPressure 0xA
+         * @param chan
+         * @param note
+         * @param value
+         */
+        void midiKeyPressure(const int chan, const int note, const int value);
+
+        /**
+         * @brief midiController 0xB
+         * @param chan
+         * @param control
+         * @param value
+         */
+        void midiController(const int chan, const int control, const int value);
+
+        /**
+         * @brief midiProgram 0xC
+         * @param chan
+         * @param program
+         */
+        void midiProgram(const int chan, const int program);
+
+        /**
+         * @brief midiChannelPressure 0xD
+         * @param chan
+         * @param value
+         */
+        void midiChannelPressure(const int chan, const int value);
+
+        /**
+         * @brief midiPitchBend 0xE
+         * @param chan
+         * @param value
+         */
+        void midiPitchBend(const int chan, const int value);
+
+        /**
+         * @brief midiSysex
+         * @param data 0xF0 ... 0xF7
+         */
+        void midiSysex(const QByteArray &data);
+
+        /**
+         * @brief midiSystemCommon
+         * @param status 0xF (1..6)
+         */
+        void midiSystemCommon(const int status);
+
+        /**
+         * @brief midiSystemRealtime
+         * @param status 0xF (8..F)
+         */
+        void midiSystemRealtime(const int status);
+    };
+}
+}
+
+Q_DECLARE_INTERFACE(drumstick::rt::MIDIInput, "net.sourceforge.drumstick.rt.MIDIInput/1.0")
+
+#endif // MIDIINPUT_H
diff --git a/library/include/rtmidioutput.h b/library/include/rtmidioutput.h
new file mode 100644
index 0000000..51a71a5
--- /dev/null
+++ b/library/include/rtmidioutput.h
@@ -0,0 +1,201 @@
+/*
+    Drumstick MIDI realtime input-output
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef MIDIOUTPUT_H
+#define MIDIOUTPUT_H
+
+#include <QObject>
+#include <QString>
+#include <QStringList>
+#include <QtPlugin>
+#include <QSettings>
+
+#define MIDI_CHANNELS               16
+#define MIDI_GM_DRUM_CHANNEL        (10-1)
+#define MIDI_CTL_MSB_MAIN_VOLUME    0x07
+#define MIDI_CTL_ALL_SOUNDS_OFF     0x78
+#define MIDI_CTL_ALL_NOTES_OFF      0x7b
+#define MIDI_CTL_RESET_CONTROLLERS  0x79
+
+#define MIDI_STATUS_NOTEOFF         0x80
+#define MIDI_STATUS_NOTEON          0x90
+#define MIDI_STATUS_KEYPRESURE      0xa0
+#define MIDI_STATUS_CONTROLCHANGE   0xb0
+#define MIDI_STATUS_PROGRAMCHANGE   0xc0
+#define MIDI_STATUS_CHANNELPRESSURE 0xd0
+#define MIDI_STATUS_PITCHBEND       0xe0
+#define MIDI_STATUS_SYSEX           0xf0
+#define MIDI_STATUS_ENDSYSEX        0xf7
+#define MIDI_STATUS_REALTIME        0xf8
+
+#define MIDI_STATUS_MASK            0xf0
+#define MIDI_CHANNEL_MASK           0x0f
+
+#define MIDI_COMMON_QTRFRAME        0xF1
+#define MIDI_COMMON_SONGPP          0xF2
+#define MIDI_COMMON_SONSELECT       0xF3
+#define MIDI_COMMON_TUNEREQ         0xF6
+
+#define MIDI_REALTIME_CLOCK         0xF8
+#define MIDI_REALTIME_START         0xFA
+#define MIDI_REALTIME_CONTINUE      0xFB
+#define MIDI_REALTIME_STOP          0xFC
+#define MIDI_REALTIME_SENSING       0xFE
+#define MIDI_REALTIME_RESET         0xFF
+
+#define MIDI_LSB(x) (x % 0x80)
+#define MIDI_MSB(x) (x / 0x80)
+
+namespace drumstick {
+namespace rt {
+
+    /**
+     * MIDI OUT interface
+     */
+    class MIDIOutput : public QObject
+    {
+        Q_OBJECT
+
+    public:
+        /**
+         * @brief MIDIOutput constructor
+         * @param parent
+         */
+        explicit MIDIOutput(QObject *parent = 0) : QObject(parent) {}
+        /**
+         * @brief ~MIDIOutput destructor
+         */
+        virtual ~MIDIOutput() {}
+        /**
+         * @brief initialize
+         * @param settings
+         */
+        virtual void initialize(QSettings* settings) = 0;
+        /**
+         * @brief backendName
+         * @return plugin name
+         */
+        virtual QString backendName() = 0;
+        /**
+         * @brief publicName
+         * @return MIDI port name
+         */
+        virtual QString publicName() = 0;
+        /**
+         * @brief setPublicName
+         * @param name MIDI port name
+         */
+        virtual void setPublicName(QString name) = 0;
+        /**
+         * @brief connections
+         * @return list of available MIDI ports
+         */
+        virtual QStringList connections(bool advanced = false) = 0;
+        /**
+         * @brief setExcludedConnections
+         * @param conns
+         */
+        virtual void setExcludedConnections(QStringList conns) = 0;
+        /**
+         * @brief open the MIDI port by name
+         * @param name
+         */
+        virtual void open(QString name) = 0;
+        /**
+         * @brief close the MIDI port
+         */
+        virtual void close() = 0;
+        /**
+         * @brief currentConnection
+         * @return name of the current connection if it is opened
+         */
+        virtual QString currentConnection() = 0;
+
+    public Q_SLOTS:
+        /**
+         * @brief sendNoteOff 0x8
+         * @param chan
+         * @param note
+         * @param vel
+         */
+        virtual void sendNoteOff(int chan, int note, int vel) = 0;
+
+        /**
+         * @brief sendNoteOn 0x9
+         * @param chan
+         * @param note
+         * @param vel
+         */
+        virtual void sendNoteOn(int chan, int note, int vel) = 0;
+
+        /**
+         * @brief sendKeyPressure 0xA
+         * @param chan
+         * @param note
+         * @param value
+         */
+        virtual void sendKeyPressure(int chan, int note, int value) = 0;
+
+        /**
+         * @brief sendController 0xB
+         * @param chan
+         * @param control
+         * @param value
+         */
+        virtual void sendController(int chan, int control, int value) = 0;
+
+        /**
+         * @brief sendProgram 0xC
+         * @param chan
+         * @param program
+         */
+        virtual void sendProgram(int chan, int program) = 0;
+
+        /**
+         * @brief sendChannelPressure 0xD
+         * @param chan
+         * @param value
+         */
+        virtual void sendChannelPressure(int chan, int value) = 0;
+
+        /**
+         * @brief sendPitchBend 0xE
+         * @param chan
+         * @param value
+         */
+        virtual void sendPitchBend(int chan, int value) = 0;
+
+        /**
+         * @brief sendSysex
+         * @param data 0xF0 ... 0xF7
+         */
+        virtual void sendSysex(const QByteArray& data) = 0;
+
+        /**
+         * @brief sendSystemMsg
+         * @param status 0xF
+         */
+        virtual void sendSystemMsg(const int status) = 0;
+    };
+}
+}
+
+Q_DECLARE_INTERFACE(drumstick::rt::MIDIOutput, "net.sourceforge.drumstick.rt.MIDIOutput/1.0")
+
+#endif /* MIDIOUTPUT_H */
diff --git a/library/include/subscription.h b/library/include/subscription.h
index 04a3e95..44fe4e9 100644
--- a/library/include/subscription.h
+++ b/library/include/subscription.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/library/library.pro b/library/library.pro
index d04f2f9..f8395ec 100644
--- a/library/library.pro
+++ b/library/library.pro
@@ -1,3 +1,8 @@
 TEMPLATE = subdirs
-SUBDIRS += drumstick-file.pro \
-           drumstick-alsa.pro
+CONFIG += ordered
+linux* {
+    SUBDIRS += alsa
+}
+SUBDIRS += file
+SUBDIRS += rt-backends
+SUBDIRS += rt
diff --git a/library/rt-backends/CMakeLists.txt b/library/rt-backends/CMakeLists.txt
new file mode 100644
index 0000000..3dc5ccc
--- /dev/null
+++ b/library/rt-backends/CMakeLists.txt
@@ -0,0 +1,51 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+#add_subdirectory(dummy-in)
+#add_subdirectory(dummy-out)
+
+if(ALSA_FOUND)
+    add_subdirectory(alsa-in)
+    add_subdirectory(alsa-out)
+endif()
+
+find_package(Qt5Network)
+if(Qt5Network_FOUND)
+    add_subdirectory(net-in)
+    add_subdirectory(net-out)
+endif()
+
+if(UNIX AND NOT APPLE)
+    add_subdirectory(oss-in)
+    add_subdirectory(oss-out)
+endif()
+
+if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+    add_subdirectory(mac-in)
+    add_subdirectory(mac-out)
+endif()
+
+if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+    add_subdirectory(win-in)
+    add_subdirectory(win-out)
+endif()
+
+pkg_check_modules(FLUIDSYNTH fluidsynth>=1.1.1)
+if(FLUIDSYNTH_FOUND)
+    add_subdirectory(synth)
+endif()
diff --git a/library/rt-backends/alsa-in/CMakeLists.txt b/library/rt-backends/alsa-in/CMakeLists.txt
new file mode 100644
index 0000000..effe102
--- /dev/null
+++ b/library/rt-backends/alsa-in/CMakeLists.txt
@@ -0,0 +1,58 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(drumstick-rt-alsa-in_QTOBJ_SRCS
+    ../../include/rtmidiinput.h
+    ../../include/rtmidioutput.h
+    alsamidiinput.h
+)
+
+set(drumstick-rt-alsa-in_SRCS
+    alsamidiinput.cpp
+)
+
+add_definitions(-DQT_PLUGIN)
+
+qt5_wrap_cpp(drumstick-rt-alsa-in_MOC_SRCS ${drumstick-rt-alsa-in_QTOBJ_SRCS})
+
+if(STATIC_DRUMSTICK)
+    add_definitions(-DQT_STATICPLUGIN)
+    add_library(drumstick-rt-alsa-in STATIC
+        ${drumstick-rt-alsa-in_MOC_SRCS}
+        ${drumstick-rt-alsa-in_SRCS})
+    set_target_properties(drumstick-rt-alsa-in PROPERTIES
+         STATIC_LIB "libdrumstick-rt-alsa-in")
+else()
+    add_library(drumstick-rt-alsa-in MODULE
+        ${drumstick-rt-alsa-in_MOC_SRCS}
+        ${drumstick-rt-alsa-in_SRCS})
+endif()
+
+target_link_libraries(drumstick-rt-alsa-in
+    drumstick-alsa
+    Qt5::Core)
+
+set_target_properties(drumstick-rt-alsa-in PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+install(TARGETS drumstick-rt-alsa-in
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/alsa-in/alsa-in.pro b/library/rt-backends/alsa-in/alsa-in.pro
new file mode 100644
index 0000000..593ba19
--- /dev/null
+++ b/library/rt-backends/alsa-in/alsa-in.pro
@@ -0,0 +1,20 @@
+TEMPLATE = lib
+CONFIG += plugin create_prl #static
+TARGET = $$qtLibraryTarget(drumstick-rt-alsa-in)
+DESTDIR = ../../../build/lib/drumstick
+DEPENDPATH += . ../../include
+INCLUDEPATH += . ../../include
+include (../../../global.pri)
+QT -= gui
+
+HEADERS += ../../include/rtmidiinput.h \
+           ../../include/rtmidioutput.h \
+           alsamidiinput.h
+SOURCES += alsamidiinput.cpp
+
+LIBS += -L../../../build/lib \
+        -l$$qtLibraryTarget(drumstick-alsa) \
+        -lasound
+
+#CONFIG += link_pkgconfig
+#PKGCONFIG += drumstick-alsa
diff --git a/library/rt-backends/alsa-in/alsamidiinput.cpp b/library/rt-backends/alsa-in/alsamidiinput.cpp
new file mode 100644
index 0000000..edc672c
--- /dev/null
+++ b/library/rt-backends/alsa-in/alsamidiinput.cpp
@@ -0,0 +1,316 @@
+/*
+    Drumstick RT Backend using the ALSA Sequencer
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QMutexLocker>
+#include <cmath>
+#include "alsaclient.h"
+#include "alsaport.h"
+#include "alsaevent.h"
+#include "alsamidiinput.h"
+#include "rtmidioutput.h"
+
+namespace drumstick {
+namespace rt {
+
+    static QString DEFAULT_PUBLIC_NAME(QLatin1String("MIDI In"));
+
+    class ALSAMIDIInput::ALSAMIDIInputPrivate : public SequencerEventHandler
+    {
+    public:
+        ALSAMIDIInput *m_inp;
+        MIDIOutput *m_out;
+        MidiClient *m_client;
+        MidiPort *m_port;
+        int m_portId;
+        int m_clientId;
+        bool m_thruEnabled;
+        bool m_clientFilter;
+        int m_runtimeAlsaNum;
+        QString m_publicName;
+        QString m_currentInput;
+        QStringList m_inputDevices;
+        QStringList m_excludedNames;
+        QMutex m_openMutex;
+
+        ALSAMIDIInputPrivate(ALSAMIDIInput *inp) :
+            m_inp(inp),
+            m_out(0),
+            m_client(0),
+            m_port(0),
+            m_portId(-1),
+            m_clientId(-1),
+            m_thruEnabled(false),
+            m_publicName(DEFAULT_PUBLIC_NAME)
+        {
+            m_runtimeAlsaNum = getRuntimeALSALibraryNumber();
+            m_client = new MidiClient(m_inp);
+            m_client->open();
+            m_client->setClientName(m_publicName);
+            m_port = m_client->createPort();
+            m_port->setPortName("in");
+            m_port->setCapability( SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE );
+            m_port->setPortType( SND_SEQ_PORT_TYPE_APPLICATION | SND_SEQ_PORT_TYPE_MIDI_GENERIC );
+            m_clientId = m_client->getClientId();
+            m_portId = m_port->getPortId();
+            m_port->setTimestamping(false);
+            m_port->setTimestampReal(false);
+            m_client->setHandler(this);
+        }
+
+        virtual ~ALSAMIDIInputPrivate()
+        {
+            if (m_client != NULL) {
+                clearSubscription();
+                if (m_port != NULL)
+                    m_port->detach();
+                m_client->close();
+                delete m_client;
+            }
+        }
+
+        bool clientIsAdvanced(int clientId)
+        {
+            // asking for runtime version instead of SND_LIB_VERSION
+            if (m_runtimeAlsaNum < 0x01000B)
+                // ALSA <= 1.0.10
+                return (clientId < 64);
+            else
+                // ALSA >= 1.0.11
+                return (clientId < 16);
+        }
+
+        void reloadDeviceList(bool advanced)
+        {
+            m_clientFilter = !advanced;
+            m_inputDevices.clear();
+            QListIterator<PortInfo> it(m_client->getAvailableInputs());
+            while(it.hasNext()) {
+                bool excluded = false;
+                PortInfo p = it.next();
+                QString name = QString("%1:%2").arg(p.getClientName()).arg(p.getPort());
+                if (m_clientFilter && clientIsAdvanced(p.getClient()))
+                    continue;
+                if ( m_clientFilter && name.startsWith(QLatin1String("Virtual Raw MIDI")) )
+                    continue;
+                if ( name.startsWith(m_publicName) )
+                    continue;
+                foreach(const QString& n, m_excludedNames) {
+                    if (name.startsWith(n)) {
+                        excluded = true;
+                        break;
+                    }
+                }
+                if (!excluded)
+                    m_inputDevices << name;
+            }
+            if (!m_currentInput.isEmpty() && !m_inputDevices.contains(m_currentInput)) {
+                m_currentInput.clear();
+            }
+        }
+
+        bool setSubscription(const QString &newDevice)
+        {
+            //qDebug() << Q_FUNC_INFO << newDevice;
+            if (m_inputDevices.contains(newDevice)) {
+                m_currentInput = newDevice;
+                m_port->unsubscribeAll();
+                m_port->subscribeFrom(newDevice);
+                m_client->startSequencerInput();
+                return true;
+            }
+            return false;
+        }
+
+        void clearSubscription()
+        {
+            if (!m_currentInput.isEmpty()) {
+                m_client->stopSequencerInput();
+                m_port->unsubscribeAll();
+                m_currentInput.clear();
+            }
+        }
+
+        void setPublicName(QString newName)
+        {
+            if (newName != m_publicName) {
+                m_client->setClientName(newName);
+                m_publicName = newName;
+            }
+        }
+
+        void handleSequencerEvent(SequencerEvent* ev)
+        {
+            if ( !SequencerEvent::isConnectionChange(ev) )
+                switch(ev->getSequencerType()) {
+                case SND_SEQ_EVENT_NOTEOFF: {
+                        const NoteOffEvent* n = static_cast<const NoteOffEvent*>(ev);
+                        if(m_out != 0 && m_thruEnabled) {
+                            m_out->sendNoteOff(n->getChannel(), n->getKey(), n->getVelocity());
+                        }
+                        emit m_inp->midiNoteOff(n->getChannel(), n->getKey(), n->getVelocity());
+                    }
+                    break;
+                case SND_SEQ_EVENT_NOTEON: {
+                        const NoteOnEvent* n = static_cast<const NoteOnEvent*>(ev);
+                        if(m_out != 0 && m_thruEnabled) {
+                            m_out->sendNoteOn(n->getChannel(), n->getKey(), n->getVelocity());
+                        }
+                        emit m_inp->midiNoteOn(n->getChannel(), n->getKey(), n->getVelocity());
+                    }
+                    break;
+                case SND_SEQ_EVENT_KEYPRESS: {
+                        const KeyPressEvent* n = static_cast<const KeyPressEvent*>(ev);
+                        if(m_out != 0 && m_thruEnabled) {
+                            m_out->sendKeyPressure(n->getChannel(), n->getKey(), n->getVelocity());
+                        }
+                        emit m_inp->midiKeyPressure(n->getChannel(), n->getKey(), n->getVelocity());
+                    }
+                    break;
+                case SND_SEQ_EVENT_CONTROLLER:
+                case SND_SEQ_EVENT_CONTROL14: {
+                        const ControllerEvent* n = static_cast<const ControllerEvent*>(ev);
+                        if(m_out != 0 && m_thruEnabled) {
+                            m_out->sendController(n->getChannel(), n->getParam(), n->getValue());
+                        }
+                        emit m_inp->midiController(n->getChannel(), n->getParam(), n->getValue());
+                    }
+                    break;
+                case SND_SEQ_EVENT_PGMCHANGE: {
+                        const ProgramChangeEvent* p = static_cast<const ProgramChangeEvent*>(ev);
+                        if(m_out != 0 && m_thruEnabled) {
+                            m_out->sendProgram(p->getChannel(), p->getValue());
+                        }
+                        emit m_inp->midiProgram(p->getChannel(), p->getValue());
+                    }
+                    break;
+                case SND_SEQ_EVENT_CHANPRESS: {
+                        const ChanPressEvent* n = static_cast<const ChanPressEvent*>(ev);
+                        if(m_out != 0 && m_thruEnabled) {
+                            m_out->sendChannelPressure(n->getChannel(), n->getValue());
+                        }
+                        emit m_inp->midiChannelPressure(n->getChannel(), n->getValue());
+                    }
+                    break;
+                case SND_SEQ_EVENT_PITCHBEND: {
+                        const PitchBendEvent* n = static_cast<const PitchBendEvent*>(ev);
+                        if(m_out != 0 && m_thruEnabled) {
+                            m_out->sendPitchBend(n->getChannel(), n->getValue());
+                        }
+                        emit m_inp->midiPitchBend(n->getChannel(), n->getValue());
+                    }
+                    break;
+                case SND_SEQ_EVENT_SYSEX: {
+                        const SysExEvent* n = static_cast<const SysExEvent*>(ev);
+                        QByteArray data(n->getData(), n->getLength());
+                        if(m_out != 0 && m_thruEnabled) {
+                            m_out->sendSysex(data);
+                        }
+                        emit m_inp->midiSysex(data);
+                    }
+                    break;
+                case SND_SEQ_EVENT_SYSTEM: {
+                        const SystemEvent* n = static_cast<const SystemEvent*>(ev);
+                        int status = (int) n->getRaw8(0);
+                        if(m_out != 0 && m_thruEnabled) {
+                            m_out->sendSystemMsg(status);
+                        }
+                        if (status < 0xF7)
+                            emit m_inp->midiSystemCommon(status);
+                        else if (status > 0xF7)
+                            emit m_inp->midiSystemRealtime(status);
+                    }
+                    break;
+                default:
+                    break;
+                }
+            delete ev;
+        }
+    };
+
+    ALSAMIDIInput::ALSAMIDIInput(QObject *parent) : MIDIInput(parent),
+        d(new ALSAMIDIInputPrivate(this))
+    { }
+
+    ALSAMIDIInput::~ALSAMIDIInput()
+    {
+        delete d;
+    }
+
+    void ALSAMIDIInput::initialize(QSettings* settings)
+    {
+        Q_UNUSED(settings)
+    }
+
+    QString ALSAMIDIInput::backendName()
+    {
+        return QLatin1String("ALSA");
+    }
+
+    QString ALSAMIDIInput::publicName()
+    {
+        return d->m_publicName;
+    }
+
+    void ALSAMIDIInput::setPublicName(QString name)
+    {
+        d->setPublicName(name);
+    }
+
+    QStringList ALSAMIDIInput::connections(bool advanced)
+    {
+        d->reloadDeviceList(advanced);
+        return d->m_inputDevices;
+    }
+
+    void ALSAMIDIInput::setExcludedConnections(QStringList conns)
+    {
+        d->m_excludedNames = conns;
+    }
+
+    void ALSAMIDIInput::open(QString name)
+    {
+        d->setSubscription(name);
+    }
+
+    void ALSAMIDIInput::close()
+    {
+        d->clearSubscription();
+    }
+
+    QString ALSAMIDIInput::currentConnection()
+    {
+        return d->m_currentInput;
+    }
+
+    void ALSAMIDIInput::setMIDIThruDevice(MIDIOutput *device)
+    {
+        d->m_out = device;
+    }
+
+    void ALSAMIDIInput::enableMIDIThru(bool enable)
+    {
+        d->m_thruEnabled = enable;
+    }
+
+    bool ALSAMIDIInput::isEnabledMIDIThru()
+    {
+        return d->m_thruEnabled && (d->m_out != 0);
+    }
+
+}}
diff --git a/library/rt-backends/alsa-in/alsamidiinput.h b/library/rt-backends/alsa-in/alsamidiinput.h
new file mode 100644
index 0000000..b4c9e54
--- /dev/null
+++ b/library/rt-backends/alsa-in/alsamidiinput.h
@@ -0,0 +1,64 @@
+/*
+    Drumstick RT Backend using the ALSA Sequencer
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef ALSAMIDIInput_H
+#define ALSAMIDIInput_H
+
+#include <QObject>
+#include <QtPlugin>
+#include "rtmidiinput.h"
+
+namespace drumstick {
+namespace rt {
+
+    class ALSAMIDIInput: public MIDIInput
+    {
+        Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIInput")
+#endif	
+        Q_INTERFACES(drumstick::rt::MIDIInput)
+
+    public:
+        ALSAMIDIInput(QObject *parent = 0);
+        virtual ~ALSAMIDIInput();
+
+        // MIDIInput interface
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+
+        virtual void setMIDIThruDevice(MIDIOutput *device);
+        virtual void enableMIDIThru(bool enable);
+        virtual bool isEnabledMIDIThru();
+
+    private:
+        class ALSAMIDIInputPrivate;
+        ALSAMIDIInputPrivate * const d;
+    };
+
+}}
+
+#endif /* ALSAMIDIInput_H */
diff --git a/library/rt-backends/alsa-out/CMakeLists.txt b/library/rt-backends/alsa-out/CMakeLists.txt
new file mode 100644
index 0000000..a9083ec
--- /dev/null
+++ b/library/rt-backends/alsa-out/CMakeLists.txt
@@ -0,0 +1,57 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(drumstick-rt-alsa-out_QTOBJ_SRCS
+    ../../include/rtmidioutput.h
+    alsamidioutput.h
+)
+
+set(drumstick-rt-alsa-out_SRCS
+    alsamidioutput.cpp
+)
+
+qt5_wrap_cpp(drumstick-rt-alsa-out_MOC_SRCS ${drumstick-rt-alsa-out_QTOBJ_SRCS})
+
+add_definitions(-DQT_PLUGIN)
+if(STATIC_DRUMSTICK)
+    add_definitions(-DQT_STATICPLUGIN)
+    add_library(drumstick-rt-alsa-out STATIC
+        ${drumstick-rt-alsa-out_MOC_SRCS}
+        ${drumstick-rt-alsa-out_SRCS})
+    set_target_properties(drumstick-rt-alsa-out PROPERTIES
+         STATIC_LIB "libdrumstick-rt-alsa-out")
+else()
+    add_library(drumstick-rt-alsa-out MODULE
+        ${drumstick-rt-alsa-out_MOC_SRCS}
+        ${drumstick-rt-alsa-out_SRCS}
+    )
+endif()
+
+target_link_libraries(drumstick-rt-alsa-out
+    drumstick-alsa
+    Qt5::Core)
+
+set_target_properties(drumstick-rt-alsa-out PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+install(TARGETS drumstick-rt-alsa-out
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/alsa-out/alsa-out.pro b/library/rt-backends/alsa-out/alsa-out.pro
new file mode 100644
index 0000000..09ae182
--- /dev/null
+++ b/library/rt-backends/alsa-out/alsa-out.pro
@@ -0,0 +1,19 @@
+TEMPLATE = lib
+CONFIG += plugin create_prl #static
+TARGET = $$qtLibraryTarget(drumstick-rt-alsa-out)
+DESTDIR = ../../../build/lib/drumstick
+DEPENDPATH += . ../../include
+INCLUDEPATH += . ../../include
+include (../../../global.pri)
+QT -= gui
+
+HEADERS += ../../include/rtmidioutput.h \
+           alsamidioutput.h
+SOURCES += alsamidioutput.cpp
+
+LIBS += -L../../../build/lib \
+        -l$$qtLibraryTarget(drumstick-alsa) \
+        -lasound
+
+#CONFIG += link_pkgconfig
+#PKGCONFIG += drumstick-alsa
diff --git a/library/rt-backends/alsa-out/alsamidioutput.cpp b/library/rt-backends/alsa-out/alsamidioutput.cpp
new file mode 100644
index 0000000..59b43f8
--- /dev/null
+++ b/library/rt-backends/alsa-out/alsamidioutput.cpp
@@ -0,0 +1,272 @@
+/*
+    Drumstick RT Backend using the ALSA Sequencer
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QString>
+#include <QStringList>
+#include <QMutex>
+#include <QMutexLocker>
+#include <qmath.h>
+#include "alsaclient.h"
+#include "alsaport.h"
+#include "alsaevent.h"
+#include "alsamidioutput.h"
+
+namespace drumstick {
+namespace rt {
+
+    static QString DEFAULT_PUBLIC_NAME(QLatin1String("MIDI Out"));
+
+    class ALSAMIDIOutput::ALSAMIDIOutputPrivate {
+    public:
+        ALSAMIDIOutput *m_out;
+        MidiClient *m_client;
+        MidiPort *m_port;
+        int m_portId;
+        bool m_clientFilter;
+        int m_runtimeAlsaNum;
+        QString m_publicName;
+        QString m_currentOutput;
+        QStringList m_outputDevices;
+        QStringList m_excludedNames;
+        QMutex m_outMutex;
+
+        ALSAMIDIOutputPrivate(ALSAMIDIOutput *q):
+            m_out(q),
+            m_client(0),
+            m_port(0),
+            m_portId(0),
+            m_clientFilter(true),
+            m_runtimeAlsaNum(0),
+            m_publicName(DEFAULT_PUBLIC_NAME)
+        {
+            m_runtimeAlsaNum = getRuntimeALSALibraryNumber();
+            m_client = new MidiClient(m_out);
+            m_client->open();
+            m_client->setClientName(m_publicName);
+            m_port = m_client->createPort();
+            m_port->setPortName("out");
+            m_port->setCapability( SND_SEQ_PORT_CAP_READ  | SND_SEQ_PORT_CAP_SUBS_READ );
+            m_port->setPortType( SND_SEQ_PORT_TYPE_APPLICATION | SND_SEQ_PORT_TYPE_MIDI_GENERIC );
+            m_portId = m_port->getPortId();
+        }
+
+        ~ALSAMIDIOutputPrivate()
+        {
+            if (m_client != NULL) {
+                clearSubscription();
+                if (m_port != NULL)
+                    m_port->detach();
+                m_client->close();
+                delete m_client;
+            }
+        }
+
+        bool clientIsAdvanced(int clientId)
+        {
+            // asking for runtime version instead of SND_LIB_VERSION
+            if (m_runtimeAlsaNum < 0x01000B)
+                // ALSA <= 1.0.10
+                return (clientId < 64);
+            else
+                // ALSA >= 1.0.11
+                return (clientId < 16);
+        }
+
+        void reloadDeviceList(bool advanced)
+        {
+            m_clientFilter = !advanced;
+            m_outputDevices.clear();
+            QListIterator<PortInfo> it(m_client->getAvailableOutputs());
+            while(it.hasNext()) {
+                bool excluded = false;
+                PortInfo p = it.next();
+                QString name = QString("%1:%2").arg(p.getClientName()).arg(p.getPort());
+                if (m_clientFilter && clientIsAdvanced(p.getClient()))
+                    continue;
+                if ( m_clientFilter && name.startsWith(QLatin1String("Virtual Raw MIDI")) )
+                    continue;
+                if ( name.startsWith(m_publicName) )
+                    continue;
+                foreach(const QString& n, m_excludedNames) {
+                    if ( name.startsWith(n) ) {
+                        excluded = true;
+                        break;
+                    }
+                }
+                if (!excluded)
+                    m_outputDevices << name;
+            }
+            if (!m_currentOutput.isEmpty() &&
+                !m_outputDevices.contains(m_currentOutput)) {
+                m_currentOutput.clear();
+            }
+        }
+
+        bool setSubscription(const QString &newOutputDevice)
+        {
+            //qDebug() << Q_FUNC_INFO << newOutputDevice;
+            if (m_outputDevices.contains(newOutputDevice)) {
+                m_currentOutput = newOutputDevice;
+                m_port->unsubscribeAll();
+                m_port->subscribeTo(newOutputDevice);
+                return true;
+            }
+            return false;
+        }
+
+        void clearSubscription()
+        {
+            if (!m_currentOutput.isEmpty()) {
+                m_port->unsubscribeAll();
+                m_currentOutput.clear();
+            }
+        }
+
+        void sendEvent(SequencerEvent *ev)
+        {
+            QMutexLocker locker(&m_outMutex);
+            ev->setSource(m_portId);
+            ev->setSubscribers();
+            ev->setDirect();
+            m_client->outputDirect(ev);
+        }
+
+        void setPublicName(QString newName)
+        {
+            if (newName != m_publicName) {
+                m_client->setClientName(newName);
+                m_publicName = newName;
+            }
+        }
+
+    };
+
+    ALSAMIDIOutput::ALSAMIDIOutput(QObject *parent) : MIDIOutput(parent),
+        d(new ALSAMIDIOutputPrivate(this))
+    { }
+
+    ALSAMIDIOutput::~ALSAMIDIOutput()
+    {
+        delete d;
+    }
+
+    void ALSAMIDIOutput::initialize(QSettings* settings)
+    {
+        Q_UNUSED(settings)
+    }
+
+    /* SLOTS */
+
+    void ALSAMIDIOutput::sendNoteOn(int chan, int note, int vel)
+    {
+        NoteOnEvent ev(chan, note, vel);
+        d->sendEvent(&ev);
+    }
+
+    void ALSAMIDIOutput::sendNoteOff(int chan, int note, int vel)
+    {
+        NoteOffEvent ev(chan, note, vel);
+        d->sendEvent(&ev);
+    }
+
+    void ALSAMIDIOutput::sendController(int chan, int control, int value)
+    {
+        ControllerEvent ev(chan, control, value);
+        d->sendEvent(&ev);
+    }
+
+    void ALSAMIDIOutput::sendKeyPressure(int chan, int note, int value)
+    {
+        KeyPressEvent ev(chan, note, value);
+        d->sendEvent(&ev);
+    }
+
+    void ALSAMIDIOutput::sendProgram(int chan, int program)
+    {
+        ProgramChangeEvent ev(chan, program);
+        d->sendEvent(&ev);
+    }
+
+    void ALSAMIDIOutput::sendChannelPressure(int chan, int value)
+    {
+        ChanPressEvent ev(chan, value);
+        d->sendEvent(&ev);
+    }
+
+    void ALSAMIDIOutput::sendPitchBend(int chan, int value)
+    {
+        PitchBendEvent ev(chan, value);
+        d->sendEvent(&ev);
+    }
+
+    void ALSAMIDIOutput::sendSysex(const QByteArray& data)
+    {
+        SysExEvent ev(data);
+        d->sendEvent(&ev);
+    }
+
+    void ALSAMIDIOutput::sendSystemMsg(const int status)
+    {
+        SystemEvent ev(status);
+        d->sendEvent(&ev);
+    }
+
+    QString ALSAMIDIOutput::backendName()
+    {
+        return "ALSA";
+    }
+
+    QString ALSAMIDIOutput::publicName()
+    {
+        return d->m_publicName;
+    }
+
+    void ALSAMIDIOutput::setPublicName(QString name)
+    {
+        d->setPublicName(name);
+    }
+
+    QStringList ALSAMIDIOutput::connections(bool advanced)
+    {
+        d->reloadDeviceList(advanced);
+        return d->m_outputDevices;
+    }
+
+    void ALSAMIDIOutput::setExcludedConnections(QStringList conns)
+    {
+        d->m_excludedNames = conns;
+    }
+
+    QString ALSAMIDIOutput::currentConnection()
+    {
+        return d->m_currentOutput;
+    }
+
+    void ALSAMIDIOutput::open(QString name)
+    {
+        d->setSubscription(name);
+    }
+
+    void ALSAMIDIOutput::close()
+    {
+        d->clearSubscription();
+    }
+
+}}
+
diff --git a/library/rt-backends/alsa-out/alsamidioutput.h b/library/rt-backends/alsa-out/alsamidioutput.h
new file mode 100644
index 0000000..10fb360
--- /dev/null
+++ b/library/rt-backends/alsa-out/alsamidioutput.h
@@ -0,0 +1,69 @@
+/*
+    Drumstick RT Backend using the ALSA Sequencer
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef ALSAMIDIOUTPUT_H
+#define ALSAMIDIOUTPUT_H
+
+#include <QObject>
+#include "rtmidioutput.h"
+
+namespace drumstick {
+namespace rt {
+
+    class ALSAMIDIOutput : public MIDIOutput
+    {
+        Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput")
+#endif
+        Q_INTERFACES(drumstick::rt::MIDIOutput)
+
+    public:
+        ALSAMIDIOutput(QObject *parent = 0);
+        virtual ~ALSAMIDIOutput();
+
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+
+    public slots:
+        virtual void sendNoteOn(int chan, int note, int vel);
+        virtual void sendNoteOff(int chan, int note, int vel);
+        virtual void sendController(int chan, int control, int value);
+        virtual void sendKeyPressure(int chan, int note, int value);
+        virtual void sendProgram(int chan, int program);
+        virtual void sendChannelPressure(int chan, int value);
+        virtual void sendPitchBend(int chan, int value);
+        virtual void sendSysex(const QByteArray& data);
+        virtual void sendSystemMsg(const int status);
+
+    private:
+        class ALSAMIDIOutputPrivate;
+        ALSAMIDIOutputPrivate *d;
+    };
+
+}}
+
+#endif /* ALSAMIDIOUTPUT_H */
diff --git a/library/rt-backends/common/maccommon.cpp b/library/rt-backends/common/maccommon.cpp
new file mode 100644
index 0000000..c79f64a
--- /dev/null
+++ b/library/rt-backends/common/maccommon.cpp
@@ -0,0 +1,110 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "maccommon.h"
+
+#if QT_VERSION < QT_VERSION_CHECK(5,2,0)
+    QString CFStringToQString(CFStringRef str)
+    {
+        if (!str)
+            return QString();
+        CFIndex length = CFStringGetLength(str);
+        const UniChar *chars = CFStringGetCharactersPtr(str);
+        if (chars)
+            return QString(reinterpret_cast<const QChar *>(chars), length);
+        QVarLengthArray<UniChar> buffer(length);
+        CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data());
+        return QString(reinterpret_cast<const QChar *>(buffer.constData()), length);
+    }
+#endif
+
+QString getEndpointName(MIDIEndpointRef endpoint)
+{
+    QString result;
+    CFStringRef str = 0;
+    MIDIObjectGetStringProperty (endpoint, kMIDIPropertyName, &str);
+    if (str != 0) {
+        result = QString::fromCFString(str);
+        CFRelease(str);
+        str = 0;
+    }
+    MIDIEntityRef entity = 0;
+    MIDIEndpointGetEntity(endpoint, &entity);
+    if (entity == 0)
+        return result;
+    if (result.isEmpty()) {
+        MIDIObjectGetStringProperty (entity, kMIDIPropertyName, &str);
+        if (str != 0) {
+            result = QString::fromCFString(str);
+            CFRelease(str);
+            str = 0;
+        }
+    }
+    MIDIDeviceRef device = 0;
+    MIDIEntityGetDevice (entity, &device);
+    if (device == 0)
+        return result;
+    MIDIObjectGetStringProperty (device, kMIDIPropertyName, &str);
+    if (str != 0) {
+        QString s = QString::fromCFString(str);
+        CFRelease (str);
+        str = 0;
+        if (!result.startsWith(s, Qt::CaseInsensitive) )
+            result = (s + ' ' + result).trimmed();
+    }
+    return result;
+}
+
+/* QString getEndpointName(MIDIEndpointRef endpoint)
+{
+    QString result;
+    CFStringRef str = 0;
+    MIDIObjectGetStringProperty (endpoint, kMIDIPropertyName, &str);
+    if (str != 0) {
+        result = QString::fromCFString(str);
+        CFRelease(str);
+        str = 0;
+    }
+    MIDIEntityRef entity = 0;
+    MIDIEndpointGetEntity(endpoint, &entity);
+    if (entity == 0)
+        return result;
+    if (result.isEmpty()) {
+        MIDIObjectGetStringProperty (entity, kMIDIPropertyName, &str);
+        if (str != 0) {
+            result = QString::fromCFString(str);
+            CFRelease(str);
+            str = 0;
+        }
+    }
+    MIDIDeviceRef device = 0;
+    MIDIEntityGetDevice (entity, &device);
+    if (device == 0)
+        return result;
+    MIDIObjectGetStringProperty (device, kMIDIPropertyName, &str);
+    if (str != 0) {
+        QString s =QString::fromCFString(str);
+        CFRelease (str);
+        str = 0;
+        if (!result.startsWith(s, Qt::CaseInsensitive) )
+            result = (s + ' ' + result).trimmed();
+    }
+    return result;
+}
+*/
diff --git a/utils/vpiano/vpianoabout.h b/library/rt-backends/common/maccommon.h
similarity index 64%
copy from utils/vpiano/vpianoabout.h
copy to library/rt-backends/common/maccommon.h
index 8601a0a..240dca4 100644
--- a/utils/vpiano/vpianoabout.h
+++ b/library/rt-backends/common/maccommon.h
@@ -1,6 +1,6 @@
 /*
-    Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -12,26 +12,21 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License along 
-    with this program; if not, write to the Free Software Foundation, Inc., 
-    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.    
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
-#ifndef ABOUT_H
-#define ABOUT_H
+#ifndef MACCOMMON_H
+#define MACCOMMON_H
 
-#include <QtGui/QDialog>
-#include "ui_vpianoabout.h"
+#include <QString>
+#include <CoreMIDI/CoreMIDI.h>
 
-class About : public QDialog
-{
-    Q_OBJECT
+#if QT_VERSION < QT_VERSION_CHECK(5,2,0)
+    QString CFStringToQString(CFStringRef str);
+#endif
 
-public:
-    About(QWidget *parent = 0);
+QString getEndpointName(MIDIEndpointRef endpoint);
 
-private:
-    Ui::AboutClass ui;
-};
-
-#endif // ABOUT_H
+#endif // MACCOMMON_H
diff --git a/library/rt-backends/common/midiparser.cpp b/library/rt-backends/common/midiparser.cpp
new file mode 100644
index 0000000..a449c24
--- /dev/null
+++ b/library/rt-backends/common/midiparser.cpp
@@ -0,0 +1,261 @@
+/*
+    Drumstick MIDI realtime input-output
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QDebug>
+#include "midiparser.h"
+#include "rtmidioutput.h"
+
+namespace drumstick {
+namespace rt {
+
+class MIDIParser::MIDIParserPrivate {
+public:
+    MIDIParserPrivate(): m_in(0), m_out(0), m_running_status(0) { }
+    MIDIInput *m_in;
+    MIDIOutput *m_out;
+    unsigned char m_running_status;
+    QByteArray m_buffer;
+
+    void processNoteOff(const int chan, const int note, const int vel)
+    {
+        //qDebug() << "NoteOff(" << hex << chan << "," << note << "," << vel << ")";
+        if (m_in != 0 && m_in->isEnabledMIDIThru() && m_out != 0) {
+            m_out->sendNoteOff(chan, note, vel);
+        }
+        if (m_in != 0) {
+            m_in->emit midiNoteOff(chan, note, vel);
+        }
+    }
+
+    void processNoteOn(const int chan, const int note, const int vel)
+    {
+        //qDebug() << "NoteOn(" << hex << chan << "," << note << "," << vel << ")";
+        if (m_in != 0 && m_in->isEnabledMIDIThru() && m_out != 0) {
+            m_out->sendNoteOn(chan, note, vel);
+        }
+        if (m_in != 0) {
+            m_in->emit midiNoteOn(chan, note, vel);
+        }
+    }
+
+    void processKeyPressure(const int chan, const int note, const int value)
+    {
+        //qDebug() << "KeyPressure(" << hex << chan << "," << note << "," << value << ")";
+        if (m_in != 0 && m_in->isEnabledMIDIThru() && m_out != 0) {
+            m_out->sendKeyPressure(chan, note, value);
+        }
+        if (m_in != 0) {
+            m_in->emit midiKeyPressure(chan, note, value);
+        }
+    }
+
+    void processController(const int chan, const int control, const int value)
+    {
+        //qDebug() << "Controller(" << chan << "," << control << "," << value << ")";
+        if (m_in != 0 && m_in->isEnabledMIDIThru() && m_out != 0) {
+            m_out->sendController(chan, control, value);
+        }
+        if (m_in != 0) {
+            m_in->emit midiController(chan, control, value);
+        }
+    }
+
+    void processProgram(const int chan, const int program)
+    {
+        //qDebug() << "Program(" << hex << chan << "," << program << ")";
+        if (m_in != 0 && m_in->isEnabledMIDIThru() && m_out != 0) {
+            m_out->sendProgram(chan, program);
+        }
+        if (m_in != 0) {
+            m_in->emit midiProgram(chan, program);
+        }
+    }
+
+    void processChannelPressure(const int chan, const int value)
+    {
+        //qDebug() << "ChannelPressure(" << chan << "," << value << ")";
+        if (m_in != 0 && m_in->isEnabledMIDIThru() && m_out != 0) {
+            m_out->sendChannelPressure(chan, value);
+        }
+        if (m_in != 0) {
+            m_in->emit midiChannelPressure(chan, value);
+        }
+    }
+
+    void processPitchBend(const int chan, const int value)
+    {
+        //qDebug() << "PitchBend(" << chan << "," << value << ")";
+        if (m_in != 0 && m_in->isEnabledMIDIThru() && m_out != 0) {
+            m_out->sendPitchBend(chan, value);
+        }
+        if (m_in != 0) {
+            m_in->emit midiPitchBend(chan, value);
+        }
+    }
+
+    void processSysex(const QByteArray &data)
+    {
+        //qDebug() << "Sysex(" << data.toHex() << ")";
+        if (m_in != 0 && m_in->isEnabledMIDIThru() && m_out != 0) {
+            m_out->sendSysex(data);
+        }
+        if (m_in != 0) {
+            m_in->emit midiSysex(data);
+        }
+    }
+
+    void processSystemCommon(const int status)
+    {
+        //qDebug() << "common SystemMsg(" << hex << status << ")";
+        if (m_in != 0 && m_in->isEnabledMIDIThru() && m_out != 0) {
+            m_out->sendSystemMsg(status);
+        }
+        if (m_in != 0) {
+            m_in->emit midiSystemCommon(status);
+
+        }
+    }
+
+    void processSystemRealtime(unsigned char byte)
+    {
+        //qDebug() << "realtime SystemMsg(" << hex << byte << ")";
+        if (m_in != 0 && m_in->isEnabledMIDIThru() && m_out != 0) {
+            m_out->sendSystemMsg(byte);
+        }
+        if (m_in != 0) {
+            m_in->emit midiSystemRealtime(byte);
+        }
+    }
+
+};
+
+MIDIParser::MIDIParser(MIDIInput *in, QObject *parent) :
+    QObject(parent),
+    d(new MIDIParser::MIDIParserPrivate)
+{
+    d->m_buffer.clear();
+    d->m_in = in;
+}
+
+MIDIParser::~MIDIParser()
+{
+    delete d;
+}
+
+void MIDIParser::setMIDIThruDevice(MIDIOutput *device)
+{
+    d->m_out = device;
+}
+
+void MIDIParser::parse(unsigned char byte)
+{
+    unsigned char status;
+    int chan, m1, m2, v;
+
+    if (byte >= MIDI_STATUS_REALTIME) { // system realtime
+        d->processSystemRealtime(byte);
+        return;
+    } else
+        d->m_buffer.append(byte);
+
+    while(d->m_buffer.length() > 0) {
+        status = static_cast<unsigned>(d->m_buffer.at(0));
+        if (status == MIDI_STATUS_SYSEX) { // system exclusive
+            if (byte == MIDI_STATUS_ENDSYSEX) {
+                d->processSysex(d->m_buffer);
+                d->m_buffer.clear();
+            } else
+                return;
+        } else
+        if (status > MIDI_STATUS_SYSEX &&
+            status < MIDI_STATUS_ENDSYSEX) { // system common
+            d->processSystemCommon(status);
+            d->m_buffer.clear();
+        } else
+        if (status < MIDI_STATUS_SYSEX &&
+            status >= MIDI_STATUS_NOTEOFF) { // channel message
+            d->m_running_status = status;
+            chan = status & MIDI_CHANNEL_MASK;
+            status = status & MIDI_STATUS_MASK;
+            switch(status) {
+            case MIDI_STATUS_NOTEOFF:
+                if (d->m_buffer.length() < 3)
+                    return;
+                m1 = static_cast<unsigned>(d->m_buffer.at(1));
+                m2 = static_cast<unsigned>(d->m_buffer.at(2));
+                d->processNoteOff(chan, m1, m2);
+                break;
+            case MIDI_STATUS_NOTEON:
+                if (d->m_buffer.length() < 3)
+                    return;
+                m1 = static_cast<unsigned>(d->m_buffer.at(1));
+                m2 = static_cast<unsigned>(d->m_buffer.at(2));
+                d->processNoteOn(chan, m1, m2);
+                break;
+            case MIDI_STATUS_KEYPRESURE:
+                if (d->m_buffer.length() < 3)
+                    return;
+                m1 = static_cast<unsigned>(d->m_buffer.at(1));
+                m2 = static_cast<unsigned>(d->m_buffer.at(2));
+                d->processKeyPressure(chan, m1, m2);
+                break;
+            case MIDI_STATUS_CONTROLCHANGE:
+                if (d->m_buffer.length() < 3)
+                    return;
+                m1 = static_cast<unsigned>(d->m_buffer.at(1));
+                m2 = static_cast<unsigned>(d->m_buffer.at(2));
+                d->processController(chan, m1, m2);
+                break;
+            case MIDI_STATUS_PROGRAMCHANGE:
+                if (d->m_buffer.length() < 2)
+                    return;
+                m1 = static_cast<unsigned>(d->m_buffer.at(1));
+                d->processProgram(chan, m1);
+                break;
+            case MIDI_STATUS_CHANNELPRESSURE:
+                if (d->m_buffer.length() < 2)
+                    return;
+                m1 = static_cast<unsigned>(d->m_buffer.at(1));
+                d->processChannelPressure(chan, m1);
+                break;
+            case MIDI_STATUS_PITCHBEND:
+                if (d->m_buffer.length() < 3)
+                    return;
+                m1 = static_cast<unsigned>(d->m_buffer.at(1));
+                m2 = static_cast<unsigned>(d->m_buffer.at(2));
+                v = m1 + m2 * 0x80 - 0x2000;
+                d->processPitchBend(chan, v);
+                break;
+            }
+            d->m_buffer.clear();
+        } else { // running status
+            d->m_buffer.insert(0, d->m_running_status);
+        }
+    }
+}
+
+void MIDIParser::parse(QByteArray bytes)
+{
+    foreach(unsigned char byte, bytes) {
+        parse(byte);
+    }
+}
+
+}}
+
diff --git a/utils/guiplayer/playerabout.h b/library/rt-backends/common/midiparser.h
similarity index 56%
copy from utils/guiplayer/playerabout.h
copy to library/rt-backends/common/midiparser.h
index 8809446..de7700f 100644
--- a/utils/guiplayer/playerabout.h
+++ b/library/rt-backends/common/midiparser.h
@@ -1,6 +1,6 @@
 /*
-    Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Drumstick MIDI realtime input-output
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -12,29 +12,37 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License along 
-    with this program; if not, write to the Free Software Foundation, Inc., 
-    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.    
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
-#ifndef ABOUT_H
-#define ABOUT_H
+#ifndef MIDIPARSER_H
+#define MIDIPARSER_H
 
-#include <QtGui/QDialog>
-#include "ui_playerabout.h"
+#include <QObject>
+#include "rtmidiinput.h"
 
-class About : public QDialog
+namespace drumstick {
+namespace rt {
+
+class MIDIParser : public QObject
 {
     Q_OBJECT
-
 public:
-    About(QWidget *parent = 0);
+    explicit MIDIParser(MIDIInput *in = 0, QObject *parent = 0);
+    virtual ~MIDIParser();
+    void setMIDIThruDevice(MIDIOutput* device);
 
 public slots:
-    void aboutQt();
+    void parse(unsigned char byte);
+    void parse(QByteArray bytes);
 
 private:
-    Ui::AboutClass ui;
+    class MIDIParserPrivate;
+    MIDIParserPrivate *d;
 };
 
-#endif // ABOUT_H
+}}
+
+#endif // MIDIPARSER_H
diff --git a/library/rt-backends/dummy-in/CMakeLists.txt b/library/rt-backends/dummy-in/CMakeLists.txt
new file mode 100644
index 0000000..ada706a
--- /dev/null
+++ b/library/rt-backends/dummy-in/CMakeLists.txt
@@ -0,0 +1,48 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(drumstick-rt-dummy-in_QTOBJ_SRCS
+    ../../include/rtmidiinput.h
+    ../../include/rtmidioutput.h
+    dummyinput.h
+)
+
+set(drumstick-rt-dummy-in_SRCS
+    dummyinput.cpp
+)
+
+add_definitions(-DQT_PLUGIN)
+
+qt5_wrap_cpp(drumstick-rt-dummy-in_MOC_SRCS ${drumstick-rt-dummy-in_QTOBJ_SRCS})
+
+add_library(drumstick-rt-dummy-in MODULE
+    ${drumstick-rt-dummy-in_MOC_SRCS}
+    ${drumstick-rt-dummy-in_SRCS}
+)
+
+target_link_libraries(drumstick-rt-dummy-in Qt5::Core)
+
+set_target_properties(drumstick-rt-dummy-in PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+
+install(TARGETS drumstick-rt-dummy-in
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/dummy-in/dummy-in.pro b/library/rt-backends/dummy-in/dummy-in.pro
new file mode 100644
index 0000000..a13078f
--- /dev/null
+++ b/library/rt-backends/dummy-in/dummy-in.pro
@@ -0,0 +1,15 @@
+TEMPLATE = lib
+TARGET = $$qtLibraryTarget(drumstick-rt-dummy-in)
+DESTDIR = ../../../build/lib/drumstick
+include (../../../global.pri)
+CONFIG += plugin create_prl #static
+DEPENDPATH += ../../include
+INCLUDEPATH += ../../include
+QT -= gui
+
+HEADERS += ../../include/rtmidiinput.h \
+           ../../include/rtmidioutput.h \
+           dummyinput.h
+
+SOURCES += dummyinput.cpp
+
diff --git a/library/rt-backends/dummy-in/dummyinput.cpp b/library/rt-backends/dummy-in/dummyinput.cpp
new file mode 100644
index 0000000..13dd7c3
--- /dev/null
+++ b/library/rt-backends/dummy-in/dummyinput.cpp
@@ -0,0 +1,86 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "dummyinput.h"
+
+namespace drumstick {
+namespace rt {
+
+void DummyInput::initialize(QSettings* settings)
+{
+    Q_UNUSED(settings)
+}
+
+QString DummyInput::backendName()
+{
+    return "DUMMY";
+}
+
+QString DummyInput::publicName()
+{
+    return QString();
+}
+
+void DummyInput::setPublicName(QString name)
+{
+    Q_UNUSED(name)
+}
+
+QStringList DummyInput::connections(bool advanced)
+{
+    Q_UNUSED(advanced)
+    return QStringList();
+}
+
+void DummyInput::setExcludedConnections(QStringList conns)
+{
+    Q_UNUSED(conns)
+}
+
+QString DummyInput::currentConnection()
+{
+    return QString();
+}
+
+void DummyInput::open(QString name)
+{
+    Q_UNUSED(name)
+}
+
+void DummyInput::close()
+{
+}
+
+void DummyInput::setMIDIThruDevice(MIDIOutput *device)
+{
+    Q_UNUSED(device)
+}
+
+void DummyInput::enableMIDIThru(bool enable)
+{
+    Q_UNUSED(enable)
+}
+
+bool DummyInput::isEnabledMIDIThru()
+{
+    return false;
+}
+
+
+}}
diff --git a/library/rt-backends/dummy-in/dummyinput.h b/library/rt-backends/dummy-in/dummyinput.h
new file mode 100644
index 0000000..f581172
--- /dev/null
+++ b/library/rt-backends/dummy-in/dummyinput.h
@@ -0,0 +1,60 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef DUMMYINPUT_H
+#define DUMMYINPUT_H
+
+#include <QObject>
+#include <QtPlugin>
+#include "rtmidiinput.h"
+
+namespace drumstick {
+namespace rt {
+
+    class DummyInput : public MIDIInput
+    {
+        Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIInput")
+#endif
+        Q_INTERFACES(drumstick::rt::MIDIInput)
+    public:
+        DummyInput(QObject *parent = 0) : MIDIInput(parent) {}
+        virtual ~DummyInput() {}
+
+        // MIDIInput interface
+    public:
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+
+        virtual void setMIDIThruDevice(MIDIOutput *device);
+        virtual void enableMIDIThru(bool enable);
+        virtual bool isEnabledMIDIThru();
+    };
+
+}}
+
+#endif // DUMMYINPUT_H
diff --git a/library/rt-backends/dummy-out/CMakeLists.txt b/library/rt-backends/dummy-out/CMakeLists.txt
new file mode 100644
index 0000000..9b2842a
--- /dev/null
+++ b/library/rt-backends/dummy-out/CMakeLists.txt
@@ -0,0 +1,30 @@
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(drumstick-rt-dummy-out_QTOBJ_SRCS
+    ../../include/rtmidioutput.h
+    dummyoutput.h
+)
+
+set(drumstick-rt-dummy-out_SRCS
+    dummyoutput.cpp
+)
+
+add_definitions(-DQT_PLUGIN)
+
+qt5_wrap_cpp(drumstick-rt-dummy-out_MOC_SRCS ${drumstick-rt-dummy-out_QTOBJ_SRCS})
+
+add_library(drumstick-rt-dummy-out MODULE
+    ${drumstick-rt-dummy-out_MOC_SRCS}
+    ${drumstick-rt-dummy-out_SRCS}
+)
+
+target_link_libraries(drumstick-rt-dummy-out Qt5::Core)
+
+set_target_properties(drumstick-rt-dummy-out PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+
+install(TARGETS drumstick-rt-dummy-out
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/dummy-out/dummy-out.pro b/library/rt-backends/dummy-out/dummy-out.pro
new file mode 100644
index 0000000..2bdb6b6
--- /dev/null
+++ b/library/rt-backends/dummy-out/dummy-out.pro
@@ -0,0 +1,19 @@
+TEMPLATE = lib
+TARGET = $$qtLibraryTarget(drumstick-rt-dummy-out)
+DESTDIR = ../../../build/lib/drumstick
+include (../../../global.pri)
+CONFIG += plugin create_prl #static
+DEPENDPATH += ../../include
+INCLUDEPATH += ../../include
+QT -= gui
+
+HEADERS += ../../include/rtmidiinput.h \
+           ../../include/rtmidioutput.h \
+           dummyoutput.h
+
+SOURCES += \
+           dummyoutput.cpp
+
+OTHER_FILES += \
+    CMakeLists.txt
+
diff --git a/library/rt-backends/dummy-out/dummyoutput.cpp b/library/rt-backends/dummy-out/dummyoutput.cpp
new file mode 100644
index 0000000..d75b0d8
--- /dev/null
+++ b/library/rt-backends/dummy-out/dummyoutput.cpp
@@ -0,0 +1,127 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "dummyoutput.h"
+
+namespace drumstick {
+namespace rt {
+
+void DummyOutput::initialize(QSettings* settings)
+{
+    Q_UNUSED(settings)
+}
+
+QString DummyOutput::backendName()
+{
+    return QLatin1String("DUMMY");
+}
+
+QString DummyOutput::publicName()
+{
+    return QString();
+}
+
+void DummyOutput::setPublicName(QString name)
+{
+    Q_UNUSED(name)
+}
+
+QStringList DummyOutput::connections(bool advanced)
+{
+    Q_UNUSED(advanced)
+    return QStringList();
+}
+
+void DummyOutput::setExcludedConnections(QStringList conns)
+{
+    Q_UNUSED(conns)
+}
+
+void DummyOutput::open(QString name)
+{
+    Q_UNUSED(name)
+}
+
+void DummyOutput::close()
+{
+}
+
+QString DummyOutput::currentConnection()
+{
+    return QString();
+}
+
+void DummyOutput::sendNoteOff(int chan, int note, int vel)
+{
+    Q_UNUSED(chan)
+    Q_UNUSED(note)
+    Q_UNUSED(vel)
+}
+
+void DummyOutput::sendNoteOn(int chan, int note, int vel)
+{
+    Q_UNUSED(chan)
+    Q_UNUSED(note)
+    Q_UNUSED(vel)
+}
+
+void DummyOutput::sendKeyPressure(int chan, int note, int value)
+{
+    Q_UNUSED(chan)
+    Q_UNUSED(note)
+    Q_UNUSED(value)
+}
+
+void DummyOutput::sendController(int chan, int control, int value)
+{
+    Q_UNUSED(chan)
+    Q_UNUSED(control)
+    Q_UNUSED(value)
+}
+
+void DummyOutput::sendProgram(int chan, int program)
+{
+    Q_UNUSED(chan)
+    Q_UNUSED(program)
+}
+
+void DummyOutput::sendChannelPressure(int chan, int value)
+{
+    Q_UNUSED(chan)
+    Q_UNUSED(value)
+}
+
+void DummyOutput::sendPitchBend(int chan, int value)
+{
+    Q_UNUSED(chan)
+    Q_UNUSED(value)
+}
+
+void DummyOutput::sendSysex(const QByteArray &data)
+{
+    Q_UNUSED(data)
+}
+
+void DummyOutput::sendSystemMsg(const int status)
+{
+    Q_UNUSED(status)
+}
+
+
+}}
diff --git a/library/rt-backends/dummy-out/dummyoutput.h b/library/rt-backends/dummy-out/dummyoutput.h
new file mode 100644
index 0000000..a0309bf
--- /dev/null
+++ b/library/rt-backends/dummy-out/dummyoutput.h
@@ -0,0 +1,67 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef DUMMYOUTPUT_H
+#define DUMMYOUTPUT_H
+
+#include <QObject>
+#include "rtmidioutput.h"
+
+namespace drumstick {
+namespace rt {
+
+    class DummyOutput : public MIDIOutput
+    {
+        Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput")
+#endif
+        Q_INTERFACES(drumstick::rt::MIDIOutput)
+
+    public:
+        DummyOutput(QObject *parent = 0) : MIDIOutput(parent) {}
+        virtual ~DummyOutput() {}
+
+        // MIDIOutput interface
+    public:
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+
+    public slots:
+        virtual void sendNoteOff(int chan, int note, int vel);
+        virtual void sendNoteOn(int chan, int note, int vel);
+        virtual void sendKeyPressure(int chan, int note, int value);
+        virtual void sendController(int chan, int control, int value);
+        virtual void sendProgram(int chan, int program);
+        virtual void sendChannelPressure(int chan, int value);
+        virtual void sendPitchBend(int chan, int value);
+        virtual void sendSysex(const QByteArray &data);
+        virtual void sendSystemMsg(const int status);
+    };
+
+}}
+
+#endif // DUMMYOUTPUT_H
diff --git a/library/rt-backends/mac-in/CMakeLists.txt b/library/rt-backends/mac-in/CMakeLists.txt
new file mode 100644
index 0000000..a7e47f7
--- /dev/null
+++ b/library/rt-backends/mac-in/CMakeLists.txt
@@ -0,0 +1,63 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+include_directories(../common)
+
+set(drumstick-rt-mac-in_QTOBJ_SRCS
+    ../../include/rtmidiinput.h
+    ../../include/rtmidioutput.h
+    macmidiinput.h
+)
+
+set(drumstick-rt-mac-in_SRCS
+    ../common/maccommon.h
+    ../common/maccommon.cpp
+    macmidiinput.cpp
+)
+
+add_definitions(-DQT_PLUGIN)
+
+qt5_wrap_cpp(drumstick-rt-mac-in_MOC_SRCS ${drumstick-rt-mac-in_QTOBJ_SRCS})
+
+if(STATIC_DRUMSTICK)
+    add_definitions(-DQT_STATICPLUGIN)
+    add_library(drumstick-rt-mac-in STATIC
+        ${drumstick-rt-mac-in_MOC_SRCS}
+        ${drumstick-rt-mac-in_SRCS})
+    set_target_properties(drumstick-rt-mac-in PROPERTIES
+         STATIC_LIB "libdrumstick-rt-mac-in")
+else()
+    add_library(drumstick-rt-mac-in MODULE
+        ${drumstick-rt-mac-in_MOC_SRCS}
+        ${drumstick-rt-mac-in_SRCS})
+endif()
+
+target_link_libraries(drumstick-rt-mac-in
+    Qt5::Core
+    "-framework CoreMidi -framework CoreFoundation"
+)
+
+set_target_properties(drumstick-rt-mac-in PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+install(TARGETS drumstick-rt-mac-in
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/mac-in/mac-in.pro b/library/rt-backends/mac-in/mac-in.pro
new file mode 100644
index 0000000..8ef0361
--- /dev/null
+++ b/library/rt-backends/mac-in/mac-in.pro
@@ -0,0 +1,20 @@
+TEMPLATE = lib
+CONFIG += plugin #create_prl #static
+TARGET = $$qtLibraryTarget(drumstick-rt-mac-in)
+DESTDIR = ../../../build/lib/drumstick
+DEPENDPATH += . ../../include ../common
+INCLUDEPATH += . ../../include ../common
+include (../../../global.pri)
+QT -= gui
+
+HEADERS += ../../include/rtmidiinput.h \
+           ../../include/rtmidioutput.h \
+           macmidiinput.h \
+           ../common/maccommon.h
+
+SOURCES += macmidiinput.cpp \
+           ../common/maccommon.cpp
+
+LIBS += -framework CoreMidi -framework CoreFoundation
+
+#-framework CoreAudio -framework AudioToolbox -framework AudioUnit
diff --git a/library/rt-backends/mac-in/macmidiinput.cpp b/library/rt-backends/mac-in/macmidiinput.cpp
new file mode 100644
index 0000000..da6faf8
--- /dev/null
+++ b/library/rt-backends/mac-in/macmidiinput.cpp
@@ -0,0 +1,343 @@
+/*
+    Drumstick RT Backend
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "macmidiinput.h"
+#include "rtmidioutput.h"
+#include "maccommon.h"
+
+#include <QDebug>
+#include <QStringList>
+#include <QMutex>
+#include <QTextCodec>
+#include <QObject>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreMIDI/CoreMIDI.h>
+
+namespace drumstick {
+namespace rt {
+
+    static CFStringRef DEFAULT_PUBLIC_NAME CFSTR("MIDI In");
+
+    void MacMIDIReadProc( const MIDIPacketList *pktlist,
+                          void *refCon, void *connRefCon );
+
+    class MacMIDIInputPrivate {
+    public:
+        MacMIDIInput *m_inp;
+        MIDIOutput *m_out;
+        MIDIClientRef m_client;
+        MIDIPortRef m_port;
+        MIDIEndpointRef m_endpoint;
+        MIDIEndpointRef m_source;
+        bool m_thruEnabled;
+        bool m_clientFilter;
+        QString m_publicName;
+        QString m_currentInput;
+        QStringList m_excludedNames;
+        QStringList m_inputDevices;
+
+        MacMIDIInputPrivate(MacMIDIInput *inp) :
+            m_inp(inp),
+            m_out(0),
+            m_client(0),
+            m_port(0),
+            m_endpoint(0),
+            m_source(0),
+            m_thruEnabled(false),
+            m_clientFilter(true),
+            m_publicName(QString::fromCFString(DEFAULT_PUBLIC_NAME))
+        {
+            internalCreate( DEFAULT_PUBLIC_NAME );
+        }
+
+        void internalCreate(CFStringRef name)
+        {
+            OSStatus result = noErr;
+            result = MIDIClientCreate( name , NULL, NULL, &m_client );
+            if (result != noErr) {
+                qDebug() << "MIDIClientCreate() err:" << result;
+                return;
+            }
+            result = MIDIDestinationCreate ( m_client, name, MacMIDIReadProc, (void*) this, &m_endpoint );
+            if (result != noErr) {
+                qDebug() << "MIDIDestinationCreate() err:" << result;
+                return;
+            }
+            result = MIDIInputPortCreate( m_client, name, MacMIDIReadProc, (void *) this,  &m_port );
+            if (result != noErr) {
+                qDebug() << "MIDIInputPortCreate() error:" << result;
+                return;
+            }
+            reloadDeviceList(true);
+        }
+
+        virtual ~MacMIDIInputPrivate()
+        {
+            internalDispose();
+        }
+
+        void internalDispose()
+        {
+            OSStatus result = noErr;
+            if (m_port != 0) {
+                result = MIDIPortDispose(m_port);
+                if (result != noErr) {
+                    qDebug() << "MIDIPortDispose() error:" << result;
+                    m_port = 0;
+                }
+            }
+            if (m_endpoint != 0) {
+                result = MIDIEndpointDispose(m_endpoint);
+                if (result != noErr) {
+                    qDebug() << "MIDIEndpointDispose() err:" << result;
+                    m_endpoint = 0;
+                }
+            }
+            if (m_client != 0) {
+                result = MIDIClientDispose(m_client);
+                if (result != noErr) {
+                    qDebug() << "MIDIClientDispose() err:" << result;
+                    m_client = 0;
+                }
+            }
+        }
+
+        void reloadDeviceList(bool advanced)
+        {
+            int num = MIDIGetNumberOfSources();
+            m_clientFilter = !advanced;
+            m_inputDevices.clear();
+            for (int i = 0; i < num; ++i) {
+                bool excluded = false;
+                MIDIEndpointRef dest = MIDIGetSource( i );
+                if (dest != 0) {
+                    QString name = getEndpointName(dest);
+                    if ( m_clientFilter &&
+                         name.contains(QLatin1String("IAC"), Qt::CaseSensitive) )
+                        continue;
+                    if ( name.contains(m_publicName))
+                        continue;
+                    foreach( const QString& n, m_excludedNames) {
+                        if (name.contains(n)) {
+                            excluded = true;
+                            break;
+                        }
+                    }
+                    if (!excluded)
+                        m_inputDevices << name;
+                }
+            }
+            if (!m_currentInput.isEmpty() && m_source != 0 &&
+                !m_inputDevices.contains(m_currentInput)) {
+                m_currentInput.clear();
+                m_source = 0;
+            }
+        }
+
+        void setPublicName(QString name)
+        {
+            if (m_publicName != name) {
+                internalDispose();
+                internalCreate(name.toCFString());
+                m_publicName = name;
+            }
+        }
+
+        void open(QString name)
+        {
+            int index = -1;
+            OSStatus result = noErr;
+            QStringList allInputDevices;
+            int num = MIDIGetNumberOfSources();
+            for (int i = 0; i < num; ++i) {
+                MIDIEndpointRef dest = MIDIGetSource( i );
+                if (dest != 0)
+                   allInputDevices << getEndpointName( dest );
+            }
+            index = allInputDevices.indexOf(name);
+            if (index < 0)
+                return;
+            m_source = MIDIGetSource( index );
+            result = MIDIPortConnectSource( m_port, m_source, NULL );
+            if (result != noErr) {
+                qDebug() << "MIDIPortConnectSource() error:" << result;
+                return;
+            }
+            m_currentInput = name;
+            return;
+        }
+
+        void close()
+        {
+            OSStatus result = noErr;
+            if (m_source != 0) {
+                result = MIDIPortDisconnectSource(m_port, m_source);
+                if (result != noErr)
+                    qDebug() << "MIDIPortDisconnectSource() error:" << result;
+                m_source = 0;
+                m_currentInput.clear();
+            }
+        }
+
+        void emitSignals(MIDIPacket* packet)
+        {
+            int value = 0;
+            int status = packet->data[0] & 0xf0;
+            int channel = packet->data[0] & 0x0f;
+            QByteArray data;
+            switch (status) {
+            case MIDI_STATUS_NOTEOFF:
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendNoteOff(channel, packet->data[1], packet->data[2]);
+                emit m_inp->midiNoteOff(channel, packet->data[1], packet->data[2]);
+                break;
+            case MIDI_STATUS_NOTEON:
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendNoteOn(channel, packet->data[1], packet->data[2]);
+                emit m_inp->midiNoteOn(channel, packet->data[1], packet->data[2]);
+                break;
+            case MIDI_STATUS_KEYPRESURE:
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendKeyPressure(channel, packet->data[1], packet->data[2]);
+                emit m_inp->midiKeyPressure(channel, packet->data[1], packet->data[2]);
+                break;
+            case MIDI_STATUS_CONTROLCHANGE:
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendController(channel, packet->data[1], packet->data[2]);
+                emit m_inp->midiController(channel, packet->data[1], packet->data[2]);
+                break;
+            case MIDI_STATUS_PROGRAMCHANGE:
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendProgram(channel, packet->data[1]);
+                emit m_inp->midiProgram(channel, packet->data[1]);
+                break;
+            case MIDI_STATUS_CHANNELPRESSURE:
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendChannelPressure(channel, packet->data[1]);
+                emit m_inp->midiChannelPressure(channel, packet->data[1]);
+                break;
+            case MIDI_STATUS_PITCHBEND:
+                value = (packet->data[1] + packet->data[2] * 0x80) - 8192;
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendPitchBend(channel, value);
+                emit m_inp->midiPitchBend(channel, value);
+                break;
+            case MIDI_STATUS_SYSEX:
+                data = QByteArray((const char *)packet->data, packet->length);
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendSysex(data);
+                emit m_inp->midiSysex(data);
+                break;
+            default:
+                qDebug() << "status?" << status;
+            }
+        }
+
+    };
+
+    void MacMIDIReadProc( const MIDIPacketList *pktlist,
+                          void *refCon, void *connRefCon )
+    {
+        Q_UNUSED(connRefCon)
+        MacMIDIInputPrivate  *obj = NULL;
+        if (refCon != NULL)
+            obj = static_cast<MacMIDIInputPrivate*>(refCon);
+
+        MIDIPacket *packet = (MIDIPacket *)pktlist->packet;
+        for (unsigned int i = 0; i < pktlist->numPackets; ++i) {
+            if (obj != NULL)
+               obj->emitSignals(packet);
+            packet = MIDIPacketNext(packet);
+        }
+    }
+
+    MacMIDIInput::MacMIDIInput(QObject *parent) :
+            MIDIInput(parent), d(new MacMIDIInputPrivate(this))
+    {
+    }
+
+    MacMIDIInput::~MacMIDIInput()
+    {
+        delete d;
+    }
+
+    void MacMIDIInput::initialize(QSettings *settings)
+    {
+        Q_UNUSED(settings)
+    }
+
+    QString MacMIDIInput::backendName()
+    {
+        return QLatin1Literal("CoreMIDI");
+    }
+
+    QString MacMIDIInput::publicName()
+    {
+        return d->m_publicName;
+    }
+
+    void MacMIDIInput::setPublicName(QString name)
+    {
+        d->setPublicName(name);
+    }
+
+    QStringList MacMIDIInput::connections(bool advanced)
+    {
+        d->reloadDeviceList(advanced);
+        return d->m_inputDevices;
+    }
+
+    void MacMIDIInput::setExcludedConnections(QStringList conns)
+    {
+        d->m_excludedNames = conns;
+    }
+
+    void MacMIDIInput::open(QString name)
+    {
+        d->open(name);
+    }
+
+    void MacMIDIInput::close()
+    {
+        d->close();
+    }
+
+    QString MacMIDIInput::currentConnection()
+    {
+        return d->m_currentInput;
+    }
+
+    void MacMIDIInput::setMIDIThruDevice(MIDIOutput *device)
+    {
+        d->m_out = device;
+    }
+
+    void MacMIDIInput::enableMIDIThru(bool enable)
+    {
+        d->m_thruEnabled = enable;
+    }
+
+    bool MacMIDIInput::isEnabledMIDIThru()
+    {
+        return d->m_thruEnabled && d->m_out != 0;
+    }
+
+}} // namespace drumstick::rt
+
diff --git a/library/rt-backends/mac-in/macmidiinput.h b/library/rt-backends/mac-in/macmidiinput.h
new file mode 100644
index 0000000..81351ab
--- /dev/null
+++ b/library/rt-backends/mac-in/macmidiinput.h
@@ -0,0 +1,64 @@
+/*
+    Drumstick RT Backend
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef MACMIDIOBJECT_H
+#define MACMIDIOBJECT_H
+
+#include "rtmidiinput.h"
+
+namespace drumstick {
+namespace rt {
+
+    class MIDIOutput;
+    class MacMIDIInputPrivate;
+
+    class MacMIDIInput : public MIDIInput
+    {
+        Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIInput")
+#endif
+        Q_INTERFACES(drumstick::rt::MIDIInput)
+    public:
+        explicit MacMIDIInput(QObject *parent = 0);
+        ~MacMIDIInput();
+
+        // MIDIInput interface
+    public:
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+
+        virtual void setMIDIThruDevice(MIDIOutput *device);
+        virtual void enableMIDIThru(bool enable);
+        virtual bool isEnabledMIDIThru();
+
+    private:
+        MacMIDIInputPrivate* const d;
+    };
+
+}}
+
+#endif // MACMIDIOBJECT_H
diff --git a/library/rt-backends/mac-out/CMakeLists.txt b/library/rt-backends/mac-out/CMakeLists.txt
new file mode 100644
index 0000000..d8140e4
--- /dev/null
+++ b/library/rt-backends/mac-out/CMakeLists.txt
@@ -0,0 +1,62 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+include_directories(../common)
+
+set(drumstick-rt-mac-out_QTOBJ_SRCS
+    ../../include/rtmidioutput.h
+    macmidioutput.h
+)
+
+set(drumstick-rt-mac-out_SRCS
+    ../common/maccommon.h
+    ../common/maccommon.cpp
+    macmidioutput.cpp
+)
+
+add_definitions(-DQT_PLUGIN)
+
+qt5_wrap_cpp(drumstick-rt-mac-out_MOC_SRCS ${drumstick-rt-mac-out_QTOBJ_SRCS})
+
+if(STATIC_DRUMSTICK)
+    add_definitions(-DQT_STATICPLUGIN)
+    add_library(drumstick-rt-mac-out STATIC
+        ${drumstick-rt-mac-out_MOC_SRCS}
+        ${drumstick-rt-mac-out_SRCS})
+    set_target_properties(drumstick-rt-mac-out PROPERTIES
+         STATIC_LIB "libdrumstick-rt-mac-out")
+else()
+    add_library(drumstick-rt-mac-out MODULE
+        ${drumstick-rt-mac-out_MOC_SRCS}
+        ${drumstick-rt-mac-out_SRCS})
+endif()
+
+target_link_libraries(drumstick-rt-mac-out
+    Qt5::Core
+    "-framework CoreMidi -framework CoreFoundation"
+)
+
+set_target_properties(drumstick-rt-mac-out PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+install(TARGETS drumstick-rt-mac-out
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/mac-out/mac-out.pro b/library/rt-backends/mac-out/mac-out.pro
new file mode 100644
index 0000000..8d1a709
--- /dev/null
+++ b/library/rt-backends/mac-out/mac-out.pro
@@ -0,0 +1,21 @@
+TEMPLATE = lib
+CONFIG += plugin #create_prl #static
+TARGET = $$qtLibraryTarget(drumstick-rt-mac-out)
+DESTDIR = ../../../build/lib/drumstick
+DEPENDPATH += . ../../include ../common
+INCLUDEPATH += . ../../include ../common
+include (../../../global.pri)
+QT -= gui
+
+HEADERS += ../../include/rtmidiinput.h \
+           ../../include/rtmidioutput.h \
+           macmidioutput.h \
+           ../common/maccommon.h
+
+SOURCES += \
+           macmidioutput.cpp \
+           ../common/maccommon.cpp
+
+LIBS += -framework CoreMidi -framework CoreFoundation
+
+#-framework CoreAudio -framework AudioToolbox -framework AudioUnit
diff --git a/library/rt-backends/mac-out/macmidioutput.cpp b/library/rt-backends/mac-out/macmidioutput.cpp
new file mode 100644
index 0000000..9e334e1
--- /dev/null
+++ b/library/rt-backends/mac-out/macmidioutput.cpp
@@ -0,0 +1,412 @@
+/*
+    Drumstick RT Backend
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "macmidioutput.h"
+#include "maccommon.h"
+
+#include <QObject>
+#include <QDebug>
+#include <QString>
+#include <QStringList>
+#include <QByteArray>
+#include <QVarLengthArray>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreMIDI/MIDIServices.h>
+
+namespace drumstick {
+namespace rt {
+
+    static CFStringRef DEFAULT_PUBLIC_NAME CFSTR("MIDI Out");
+
+    class MacMIDIOutput::MacMIDIOutputPrivate {
+    public:
+        MIDIClientRef m_client;
+        MIDIPortRef m_port;
+        MIDIEndpointRef m_endpoint;
+        MIDIEndpointRef m_destination;
+        bool m_clientFilter;
+
+        QString m_currentOutput;
+        QString m_publicName;
+        QStringList m_excludedNames;
+        QStringList m_outputDevices;
+
+        MacMIDIOutputPrivate():
+            m_client(0),
+            m_port(0),
+            m_endpoint(0),
+            m_destination(0),
+            m_clientFilter(true),
+            m_publicName(QString::fromCFString(DEFAULT_PUBLIC_NAME))
+        {
+            internalCreate(DEFAULT_PUBLIC_NAME);
+        }
+
+        void internalCreate(CFStringRef name)
+        {
+            OSStatus result = noErr;
+            result = MIDIClientCreate( name, NULL, NULL, &m_client );
+            if ( result != noErr ) {
+                qDebug() << "MIDIClientCreate() error:" << result;
+                return;
+            }
+            result = MIDISourceCreate( m_client, name, &m_endpoint );
+            if ( result != noErr ) {
+                qDebug() << "MIDISourceCreate() error:" << result;
+                return;
+            }
+            result = MIDIOutputPortCreate( m_client, name, &m_port );
+            if (result != noErr) {
+                qDebug() << "MIDIOutputPortCreate() error:" << result;
+                return;
+            }
+            reloadDeviceList(true);
+        }
+
+        virtual ~MacMIDIOutputPrivate()
+        {
+            internalDispose();
+        }
+
+        void internalDispose()
+        {
+            OSStatus result = noErr;
+            if (m_port != 0) {
+                result = MIDIPortDispose( m_port );
+                if (result != noErr) {
+                    qDebug() << "MIDIPortDispose() error:" << result;
+                    m_port = 0;
+                }
+            }
+            if (m_endpoint != 0) {
+                result = MIDIEndpointDispose( m_endpoint );
+                if (result != noErr) {
+                    qDebug() << "MIDIEndpointDispose() err:" << result;
+                    m_endpoint = 0;
+                }
+            }
+            if (m_client != 0) {
+                result = MIDIClientDispose( m_client );
+                if (result != noErr) {
+                    qDebug() << "MIDIClientDispose() error:" << result;
+                    m_client = 0;
+                }
+            }
+        }
+
+        void setPublicName(QString name)
+        {
+            if (m_publicName != name) {
+                internalDispose();
+                internalCreate(name.toCFString());
+                m_publicName = name;
+            }
+        }
+
+        void reloadDeviceList(bool advanced)
+        {
+            int num = MIDIGetNumberOfDestinations();
+            m_clientFilter = !advanced;
+            m_outputDevices.clear();
+            for (int i = 0; i < num; ++i) {
+                bool excluded = false;
+                MIDIEndpointRef dest = MIDIGetDestination( i );
+                if (dest != 0) {
+                    QString name = getEndpointName(dest);
+                    if ( m_clientFilter &&
+                         name.contains(QLatin1String("IAC"), Qt::CaseSensitive) )
+                        continue;
+                    if ( name.contains (m_publicName) )
+                        continue;
+                    foreach ( const QString& n, m_excludedNames ) {
+                        if ( name.contains(n) ) {
+                            excluded = true;
+                            break;
+                        }
+                    }
+                    if (!excluded)
+                        m_outputDevices << name;
+                }
+            }
+            if (!m_currentOutput.isEmpty() && m_destination != 0 &&
+                !m_outputDevices.contains(m_currentOutput)) {
+                m_currentOutput.clear();
+                m_destination = 0;
+            }
+        }
+
+        void sendEvents( const MIDIPacketList* events )
+        {
+            MIDIReceived(m_endpoint, events);
+            if (m_destination != 0)
+                MIDISend(m_port, m_destination, events);
+        }
+
+        bool open(const QString &name)
+        {
+            int index;
+            QStringList allOutputDevices;
+            int num = MIDIGetNumberOfDestinations();
+            for (int i = 0; i < num; ++i) {
+                MIDIEndpointRef dest = MIDIGetDestination( i );
+                if (dest != 0)
+                   allOutputDevices << getEndpointName( dest );
+            }
+            index = allOutputDevices.indexOf(name);
+            if (index < 0)
+                return false;
+            m_destination = MIDIGetDestination( index );
+            m_currentOutput = name;
+            return true;
+        }
+
+        void close()
+        {
+            m_destination = 0;
+            m_currentOutput.clear();
+        }
+    };
+
+    MacMIDIOutput::MacMIDIOutput(QObject *parent) :
+        MIDIOutput(parent), d(new MacMIDIOutputPrivate)
+    {
+    }
+
+    MacMIDIOutput::~MacMIDIOutput()
+    {
+        delete d;
+    }
+
+    void MacMIDIOutput::initialize(QSettings *settings)
+    {
+        Q_UNUSED(settings)
+    }
+
+    QString MacMIDIOutput::backendName()
+    {
+        return QLatin1Literal("CoreMIDI");
+    }
+
+    QString MacMIDIOutput::publicName()
+    {
+        return d->m_publicName;
+    }
+
+    void MacMIDIOutput::setPublicName(QString name)
+    {
+        d->setPublicName(name);
+    }
+
+    QStringList MacMIDIOutput::connections(bool advanced)
+    {
+        d->reloadDeviceList(advanced);
+        return d->m_outputDevices;
+    }
+
+    void MacMIDIOutput::setExcludedConnections(QStringList conns)
+    {
+        d->m_excludedNames = conns;
+    }
+
+    void MacMIDIOutput::open(QString name)
+    {
+        d->open(name);
+    }
+
+    void MacMIDIOutput::close()
+    {
+        d->close();
+    }
+
+    QString MacMIDIOutput::currentConnection()
+    {
+        return d->m_currentOutput;
+    }
+
+    /* Realtime MIDI slots */
+
+    /*void MacMIDIOutput::allNotesOff()
+    {
+        quint8 data[3];
+        quint8 buf[2048];
+        MIDIPacketList* pktlist = (MIDIPacketList*) &buf;
+        MIDIPacket* packet = MIDIPacketListInit(pktlist);
+        for(int chan = 0; chan < MIDI_CHANNELS && packet != NULL; ++chan) {
+            data[0] = MIDI_STATUS_CONTROLCHANGE | (chan & 0x0f);
+            data[1] = MIDI_CTL_ALL_NOTES_OFF;
+            data[2] = 0;
+            packet = MIDIPacketListAdd(pktlist, sizeof(buf), packet, 0,
+                      sizeof(data), data);
+            if (packet != NULL) {
+                data[1] = MIDI_CTL_ALL_SOUNDS_OFF;
+                packet = MIDIPacketListAdd(pktlist, sizeof(buf), packet, 0,
+                           sizeof(data), data);
+            }
+        }
+        if (packet != NULL)
+            d->sendEvents(pktlist);
+    }*/
+
+    /*void MacMIDIOutput::resetControllers()
+    {
+        quint8 data[3];
+        quint8 buf[2048];
+        MIDIPacketList* pktlist = (MIDIPacketList*) &buf;
+        MIDIPacket* packet = MIDIPacketListInit(pktlist);
+        for(int chan = 0; chan < MIDI_CHANNELS && packet != NULL; ++chan) {
+            data[0] = MIDI_STATUS_CONTROLCHANGE | (chan & 0x0f);
+            data[1] = MIDI_CTL_RESET_CONTROLLERS;
+            data[2] = 0;
+            packet = MIDIPacketListAdd(pktlist, sizeof(buf), packet, 0,
+                      sizeof(data), data);
+            if (packet != NULL) {
+                data[1] = MIDI_CTL_MSB_MAIN_VOLUME;
+                data[2] = 100;
+                packet = MIDIPacketListAdd(pktlist, sizeof(buf), packet, 0,
+                           sizeof(data), data);
+            }
+        }
+        if (packet != NULL)
+            d->sendEvents(pktlist);
+    }*/
+
+    void MacMIDIOutput::sendNoteOn(int chan, int note, int vel)
+    {
+        quint8 data[3];
+        MIDIPacketList pktlist ;
+        MIDIPacket* packet = MIDIPacketListInit(&pktlist);
+        data[0] = MIDI_STATUS_NOTEON | (chan & 0x0f);
+        data[1] = note;
+        data[2] = vel;
+        packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0,
+            sizeof(data), data);
+        if (packet != NULL)
+            d->sendEvents(&pktlist);
+    }
+
+    void MacMIDIOutput::sendNoteOff(int chan, int note, int vel)
+    {
+        quint8 data[3];
+        MIDIPacketList pktlist ;
+        MIDIPacket* packet = MIDIPacketListInit(&pktlist);
+        data[0] = MIDI_STATUS_NOTEOFF | (chan & 0x0f);
+        data[1] = note;
+        data[2] = vel;
+        packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0,
+            sizeof(data), data);
+        if (packet != NULL)
+            d->sendEvents(&pktlist);
+    }
+
+    void MacMIDIOutput::sendController(int chan, int control, int value)
+    {
+        quint8 data[3];
+        MIDIPacketList pktlist ;
+        MIDIPacket* packet = MIDIPacketListInit(&pktlist);
+        data[0] = MIDI_STATUS_CONTROLCHANGE | (chan & 0x0f);
+        data[1] = control;
+        data[2] = value;
+        packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0,
+            sizeof(data), data);
+        if (packet != NULL)
+            d->sendEvents(&pktlist);
+    }
+
+    void MacMIDIOutput::sendKeyPressure(int chan, int note, int value)
+    {
+        quint8 data[3];
+        MIDIPacketList pktlist ;
+        MIDIPacket* packet = MIDIPacketListInit(&pktlist);
+        data[0] = MIDI_STATUS_KEYPRESURE | (chan & 0x0f);
+        data[1] = note;
+        data[2] = value;
+        packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0,
+            sizeof(data), data);
+        if (packet != NULL)
+            d->sendEvents(&pktlist);
+    }
+
+    void MacMIDIOutput::sendProgram(int chan, int program)
+    {
+        quint8 data[2];
+        MIDIPacketList pktlist ;
+        MIDIPacket* packet = MIDIPacketListInit(&pktlist);
+        data[0] = MIDI_STATUS_PROGRAMCHANGE | (chan & 0x0f);
+        data[1] = program;
+        packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0,
+            sizeof(data), data);
+        if (packet != NULL)
+            d->sendEvents(&pktlist);
+    }
+
+    void MacMIDIOutput::sendChannelPressure(int chan, int value)
+    {
+        quint8 data[2];
+        MIDIPacketList pktlist ;
+        MIDIPacket* packet = MIDIPacketListInit(&pktlist);
+        data[0] = MIDI_STATUS_CHANNELPRESSURE | (chan & 0x0f);
+        data[1] = value;
+        packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0,
+            sizeof(data), data);
+        if (packet != NULL)
+            d->sendEvents(&pktlist);
+    }
+
+    void MacMIDIOutput::sendPitchBend(int chan, int value)
+    {
+        quint16 val = value + 8192; // value between -8192 and +8191
+        quint8 data[3];
+        MIDIPacketList pktlist ;
+        MIDIPacket* packet = MIDIPacketListInit(&pktlist);
+        data[0] = MIDI_STATUS_PITCHBEND | (chan & 0x0f);
+        data[1] = MIDI_LSB(val); // LSB
+        data[2] = MIDI_MSB(val); // MSB
+        packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0,
+            sizeof(data), data);
+        if (packet != NULL)
+            d->sendEvents(&pktlist);
+    }
+
+    void MacMIDIOutput::sendSysex(const QByteArray& data)
+    {
+        quint8 buf[4096];
+        if (data.size() > 4096)
+            return;
+        MIDIPacketList* pktlist = (MIDIPacketList*) &buf;
+        MIDIPacket* packet = MIDIPacketListInit(pktlist);
+        packet = MIDIPacketListAdd(pktlist, sizeof(buf), packet, 0,
+            data.size(), (const Byte*)data.data());
+        if (packet != NULL)
+            d->sendEvents(pktlist);
+    }
+
+    void MacMIDIOutput::sendSystemMsg(const int status)
+    {
+        quint8 data;
+        MIDIPacketList pktlist;
+        MIDIPacket* packet = MIDIPacketListInit(&pktlist);
+        data = status;
+        packet = MIDIPacketListAdd(&pktlist, sizeof(pktlist), packet, 0,
+            sizeof(data), &data);
+        if (packet != NULL)
+            d->sendEvents(&pktlist);
+    }
+
+}}
diff --git a/library/rt-backends/mac-out/macmidioutput.h b/library/rt-backends/mac-out/macmidioutput.h
new file mode 100644
index 0000000..fe7f874
--- /dev/null
+++ b/library/rt-backends/mac-out/macmidioutput.h
@@ -0,0 +1,68 @@
+/*
+    Drumstick RT Backend
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef MACMIDIOUTPUT_H
+#define MACMIDIOUTPUT_H
+
+#include "rtmidioutput.h"
+
+namespace drumstick {
+namespace rt {
+
+    class MacMIDIOutput : public MIDIOutput
+    {
+        Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput")
+#endif
+        Q_INTERFACES(drumstick::rt::MIDIOutput)
+
+    public:
+        explicit MacMIDIOutput(QObject *parent = 0);
+        virtual ~MacMIDIOutput();
+
+        // MIDIOutput interface
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+
+    public slots:
+        virtual void sendNoteOff(int chan, int note, int vel);
+        virtual void sendNoteOn(int chan, int note, int vel);
+        virtual void sendKeyPressure(int chan, int note, int value);
+        virtual void sendController(int chan, int control, int value);
+        virtual void sendProgram(int chan, int program);
+        virtual void sendChannelPressure(int chan, int value);
+        virtual void sendPitchBend(int chan, int value);
+        virtual void sendSysex(const QByteArray &data);
+        virtual void sendSystemMsg(const int status);
+
+    private:
+        class MacMIDIOutputPrivate;
+        MacMIDIOutputPrivate* const d;
+    };
+}}
+
+#endif // MACMIDIOUTPUT_H
diff --git a/library/rt-backends/net-in/CMakeLists.txt b/library/rt-backends/net-in/CMakeLists.txt
new file mode 100644
index 0000000..31e1917
--- /dev/null
+++ b/library/rt-backends/net-in/CMakeLists.txt
@@ -0,0 +1,65 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+find_package(Qt5Network REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+include_directories(../common)
+
+set(drumstick-rt-net-in_QTOBJ_SRCS
+    ../../include/rtmidiinput.h
+    ../../include/rtmidioutput.h
+    ../common/midiparser.h
+    netmidiinput_p.h
+    netmidiinput.h
+)
+
+set(drumstick-rt-net-in_SRCS
+    ../common/midiparser.cpp
+    netmidiinput_p.cpp
+    netmidiinput.cpp
+)
+
+add_definitions(-DQT_PLUGIN)
+
+qt5_wrap_cpp(drumstick-rt-net-in_MOC_SRCS ${drumstick-rt-net-in_QTOBJ_SRCS})
+
+if(STATIC_DRUMSTICK)
+    add_definitions(-DQT_STATICPLUGIN)
+    add_library(drumstick-rt-net-in STATIC
+        ${drumstick-rt-net-in_MOC_SRCS}
+        ${drumstick-rt-net-in_SRCS})
+    set_target_properties(drumstick-rt-net-in PROPERTIES
+         STATIC_LIB "libdrumstick-rt-net-in")
+else()
+    add_library(drumstick-rt-net-in MODULE
+        ${drumstick-rt-net-in_MOC_SRCS}
+        ${drumstick-rt-net-in_SRCS})
+endif()
+
+target_link_libraries(drumstick-rt-net-in
+    Qt5::Network)
+
+set_target_properties(drumstick-rt-net-in PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+install(TARGETS drumstick-rt-net-in
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/net-in/net-in.pro b/library/rt-backends/net-in/net-in.pro
new file mode 100644
index 0000000..5db28b7
--- /dev/null
+++ b/library/rt-backends/net-in/net-in.pro
@@ -0,0 +1,24 @@
+TEMPLATE = lib
+CONFIG += plugin #create_prl static
+TARGET = $$qtLibraryTarget(drumstick-rt-net-in)
+DESTDIR = ../../../build/lib/drumstick
+DEPENDPATH += . ../../include ../common
+INCLUDEPATH += . ../../include ../common
+include (../../../global.pri)
+QT -= gui
+
+HEADERS += ../../include/rtmidiinput.h \
+           ../../include/rtmidioutput.h \
+           ../common/midiparser.h \
+           netmidiinput.h \
+           netmidiinput_p.h
+
+SOURCES += netmidiinput.cpp \
+           netmidiinput_p.cpp \
+           ../common/midiparser.cpp
+
+QT += network
+
+win32 {
+    TARGET_EXT = .dll
+}
diff --git a/library/rt-backends/net-in/netmidiinput.cpp b/library/rt-backends/net-in/netmidiinput.cpp
new file mode 100644
index 0000000..2da0187
--- /dev/null
+++ b/library/rt-backends/net-in/netmidiinput.cpp
@@ -0,0 +1,94 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QUdpSocket>
+#include "netmidiinput.h"
+#include "netmidiinput_p.h"
+
+namespace drumstick {
+namespace rt {
+
+NetMIDIInput::NetMIDIInput(QObject *parent):
+    MIDIInput(parent),
+    d(new NetMIDIInputPrivate(this))
+{ }
+
+void NetMIDIInput::initialize(QSettings *settings)
+{
+    d->initialize(settings);
+}
+
+QString NetMIDIInput::backendName()
+{
+    return QLatin1String("Network");
+}
+
+QString NetMIDIInput::publicName()
+{
+    return d->m_publicName;
+}
+
+void NetMIDIInput::setPublicName(QString name)
+{
+    d->m_publicName = name;
+}
+
+QStringList NetMIDIInput::connections(bool advanced)
+{
+    Q_UNUSED(advanced)
+    return d->m_inputDevices;
+}
+
+void NetMIDIInput::setExcludedConnections(QStringList conns)
+{
+    d->m_excludedNames = conns;
+}
+
+void NetMIDIInput::open(QString name)
+{
+    d->open(name);
+}
+
+void NetMIDIInput::close()
+{
+    d->close();
+}
+
+QString NetMIDIInput::currentConnection()
+{
+    return d->m_currentInput;
+}
+
+void NetMIDIInput::setMIDIThruDevice(MIDIOutput *device)
+{
+    d->setMIDIThruDevice(device);
+}
+
+void NetMIDIInput::enableMIDIThru(bool enable)
+{
+    d->m_thruEnabled = enable;
+}
+
+bool NetMIDIInput::isEnabledMIDIThru()
+{
+    return d->m_thruEnabled && (d->m_out != 0);
+}
+
+}}
+
diff --git a/library/rt-backends/net-in/netmidiinput.h b/library/rt-backends/net-in/netmidiinput.h
new file mode 100644
index 0000000..174fd9d
--- /dev/null
+++ b/library/rt-backends/net-in/netmidiinput.h
@@ -0,0 +1,67 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef NETMIDIINPUT_H
+#define NETMIDIINPUT_H
+
+#include <QObject>
+#include <QHostAddress>
+#include <QtPlugin>
+#include "rtmidiinput.h"
+
+namespace drumstick {
+namespace rt {
+
+    const QString STR_ADDRESS(QLatin1Literal("225.0.0.37"));
+    const int MULTICAST_PORT(21928);
+    const int LAST_PORT(21948);
+
+    class NetMIDIInputPrivate;
+
+    class NetMIDIInput : public MIDIInput
+    {
+        Q_OBJECT
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIInput")
+        Q_INTERFACES(drumstick::rt::MIDIInput)
+
+    public:
+        explicit NetMIDIInput(QObject *parent = 0);
+
+        // MIDIInput interface
+    public:
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+        virtual void setMIDIThruDevice(MIDIOutput *device);
+        virtual void enableMIDIThru(bool enable);
+        virtual bool isEnabledMIDIThru();
+
+    private:
+        NetMIDIInputPrivate * const d;
+    };
+
+}}
+
+#endif // NETMIDIINPUT_H
diff --git a/library/rt-backends/net-in/netmidiinput_p.cpp b/library/rt-backends/net-in/netmidiinput_p.cpp
new file mode 100644
index 0000000..6d3550c
--- /dev/null
+++ b/library/rt-backends/net-in/netmidiinput_p.cpp
@@ -0,0 +1,113 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QObject>
+#include <QDebug>
+
+#include "netmidiinput_p.h"
+#include "netmidiinput.h"
+
+namespace drumstick {
+namespace rt {
+
+static QString DEFAULT_PUBLIC_NAME(QLatin1String("MIDI In"));
+
+NetMIDIInputPrivate::NetMIDIInputPrivate(QObject *parent) : QObject(parent),
+    m_inp(qobject_cast<NetMIDIInput *>(parent)),
+    m_out(0),
+    m_socket(0),
+    m_parser(0),
+    m_thruEnabled(false),
+    m_port(0),
+    m_publicName(DEFAULT_PUBLIC_NAME),
+    m_groupAddress(QHostAddress(STR_ADDRESS))
+{
+    for(int i=MULTICAST_PORT; i<LAST_PORT; ++i) {
+        m_inputDevices << QString::number(i);
+    }
+}
+
+void NetMIDIInputPrivate::open(QString portName)
+{
+    int p = m_inputDevices.indexOf(portName);
+    if (p > -1)
+    {
+        m_socket = new QUdpSocket();
+        m_parser = new MIDIParser(m_inp);
+        m_port = MULTICAST_PORT + p;
+        m_currentInput = portName;
+        m_socket->bind(QHostAddress::AnyIPv4, m_port, QUdpSocket::ShareAddress);
+        m_socket->setSocketOption(QAbstractSocket::MulticastLoopbackOption, 0);
+        m_socket->setSocketOption(QAbstractSocket::MulticastTtlOption, 1);
+        if (m_iface.isValid()) {
+            m_socket->joinMulticastGroup(m_groupAddress, m_iface);
+        } else {
+            m_socket->joinMulticastGroup(m_groupAddress);
+        }
+        connect(m_socket, SIGNAL(readyRead()), this, SLOT(processIncomingMessages()));
+        //qDebug() << Q_FUNC_INFO << portName;
+    }
+}
+
+void NetMIDIInputPrivate::close()
+{
+    delete m_socket;
+    delete m_parser;
+    m_socket = 0;
+    m_parser = 0;
+    m_currentInput.clear();
+}
+
+void NetMIDIInputPrivate::initialize(QSettings *settings)
+{
+    if (settings != 0) {
+        settings->beginGroup("Network");
+        QString ifaceName = settings->value("interface", QString()).toString();
+        QString address = settings->value("address", STR_ADDRESS).toString();
+        settings->endGroup();
+        if (!ifaceName.isEmpty()) {
+            m_iface = QNetworkInterface::interfaceFromName(ifaceName);
+        }
+        if (!address.isEmpty()) {
+            m_groupAddress.setAddress(address);
+        }
+    }
+}
+
+void NetMIDIInputPrivate::setMIDIThruDevice(MIDIOutput* device)
+{
+    m_out = device;
+    if (m_parser != 0) {
+        m_parser->setMIDIThruDevice(device);
+    }
+}
+
+void NetMIDIInputPrivate::processIncomingMessages()
+{
+    while (m_socket->hasPendingDatagrams()) {
+        QByteArray datagram;
+        datagram.resize(m_socket->pendingDatagramSize());
+        m_socket->readDatagram(datagram.data(), datagram.size());
+        if (m_parser != 0) {
+            m_parser->parse(datagram);
+        }
+    }
+}
+
+}}
diff --git a/library/rt-backends/net-in/netmidiinput_p.h b/library/rt-backends/net-in/netmidiinput_p.h
new file mode 100644
index 0000000..85d7146
--- /dev/null
+++ b/library/rt-backends/net-in/netmidiinput_p.h
@@ -0,0 +1,63 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef NETMIDIINPUT_P_H
+#define NETMIDIINPUT_P_H
+
+#include <QObject>
+#include <QUdpSocket>
+#include <QNetworkInterface>
+#include "midiparser.h"
+
+namespace drumstick {
+namespace rt {
+
+class MIDIOutput;
+class NetMIDIInput;
+
+class NetMIDIInputPrivate : public QObject
+{
+    Q_OBJECT
+public:
+    NetMIDIInput *m_inp;
+    MIDIOutput *m_out;
+    QUdpSocket *m_socket;
+    MIDIParser *m_parser;
+    int m_thruEnabled;
+    quint16 m_port;
+    QString m_publicName;
+    QHostAddress m_groupAddress;
+    QString m_currentInput;
+    QStringList m_inputDevices;
+    QStringList m_excludedNames;
+    QNetworkInterface m_iface;
+
+    NetMIDIInputPrivate(QObject *parent = 0);
+
+    void open(QString portName);
+    void close();
+    void initialize(QSettings* settings);
+    void setMIDIThruDevice(MIDIOutput* device);
+
+public slots:
+    void processIncomingMessages();
+};
+
+}}
+#endif // NETMIDIINPUT_P_H
diff --git a/library/rt-backends/net-out/CMakeLists.txt b/library/rt-backends/net-out/CMakeLists.txt
new file mode 100644
index 0000000..e88338e
--- /dev/null
+++ b/library/rt-backends/net-out/CMakeLists.txt
@@ -0,0 +1,58 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+find_package(Qt5Network REQUIRED)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(drumstick-rt-net-out_QTOBJ_SRCS
+    ../../include/rtmidioutput.h
+    netmidioutput.h
+)
+
+set(drumstick-rt-net-out_SRCS
+    netmidioutput.cpp
+)
+
+add_definitions(-DQT_PLUGIN)
+
+qt5_wrap_cpp(drumstick-rt-net-out_MOC_SRCS ${drumstick-rt-net-out_QTOBJ_SRCS})
+
+if(STATIC_DRUMSTICK)
+    add_definitions(-DQT_STATICPLUGIN)
+    add_library(drumstick-rt-net-out STATIC
+        ${drumstick-rt-net-out_MOC_SRCS}
+        ${drumstick-rt-net-out_SRCS})
+    set_target_properties(drumstick-rt-net-out PROPERTIES
+         STATIC_LIB "libdrumstick-rt-net-out")
+else()
+    add_library(drumstick-rt-net-out MODULE
+        ${drumstick-rt-net-out_MOC_SRCS}
+        ${drumstick-rt-net-out_SRCS})
+endif()
+
+target_link_libraries(drumstick-rt-net-out
+    Qt5::Network)
+
+set_target_properties(drumstick-rt-net-out PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+install(TARGETS drumstick-rt-net-out
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/net-out/net-out.pro b/library/rt-backends/net-out/net-out.pro
new file mode 100644
index 0000000..4092290
--- /dev/null
+++ b/library/rt-backends/net-out/net-out.pro
@@ -0,0 +1,22 @@
+TEMPLATE = lib
+CONFIG += plugin #create_prl static
+TARGET = $$qtLibraryTarget(drumstick-rt-net-out)
+DESTDIR = ../../../build/lib/drumstick
+DEPENDPATH += . ../../include
+INCLUDEPATH += . ../../include
+include (../../../global.pri)
+DEPENDPATH += ../../include
+INCLUDEPATH += ../../include
+QT -= gui
+
+HEADERS += ../../include/rtmidiinput.h \
+           ../../include/rtmidioutput.h \
+           netmidioutput.h
+SOURCES += \
+           netmidioutput.cpp
+
+QT += network
+
+win32 {
+    TARGET_EXT = .dll
+}
diff --git a/library/rt-backends/net-out/netmidioutput.cpp b/library/rt-backends/net-out/netmidioutput.cpp
new file mode 100644
index 0000000..0080205
--- /dev/null
+++ b/library/rt-backends/net-out/netmidioutput.cpp
@@ -0,0 +1,234 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QDebug>
+#include <QUdpSocket>
+#include <QNetworkInterface>
+#include <QSettings>
+#include "netmidioutput.h"
+
+namespace drumstick {
+namespace rt {
+
+static QString DEFAULT_PUBLIC_NAME(QLatin1String("MIDI Out"));
+
+class NetMIDIOutput::NetMIDIOutputPrivate
+{
+public:
+    QUdpSocket *m_socket;
+    quint16 m_port;
+    QString m_publicName;
+    QHostAddress m_groupAddress;
+    QString m_currentOutput;
+    QStringList m_outputDevices;
+    QStringList m_excludedNames;
+    QNetworkInterface m_iface;
+
+    NetMIDIOutputPrivate() :
+        m_socket(0),
+        m_port(0),
+        m_publicName(DEFAULT_PUBLIC_NAME),
+        m_groupAddress(QHostAddress(STR_ADDRESS))
+    {
+        for(int i=MULTICAST_PORT; i<LAST_PORT; ++i) {
+            m_outputDevices << QString::number(i);
+        }
+    }
+
+    ~NetMIDIOutputPrivate()
+    {
+        close();
+    }
+
+    void initialize(QSettings* settings)
+    {
+        if (settings != 0) {
+            settings->beginGroup("Network");
+            QString ifaceName = settings->value("interface", QString()).toString();
+            QString address = settings->value("address", STR_ADDRESS).toString();
+            settings->endGroup();
+            if (!ifaceName.isEmpty()) {
+                m_iface = QNetworkInterface::interfaceFromName(ifaceName);
+            }
+            if (!address.isEmpty()) {
+                m_groupAddress.setAddress(address);
+            }
+        }
+    }
+
+    void open(QString portName)
+    {
+        int p = m_outputDevices.indexOf(portName);
+        if (p > -1)
+        {
+            m_socket = new QUdpSocket();
+            m_port = MULTICAST_PORT + p;
+            m_currentOutput = portName;
+            if (m_iface.isValid()) {
+                m_socket->setMulticastInterface(m_iface);
+            }
+            //qDebug() << Q_FUNC_INFO << portName;
+        }
+    }
+
+    void close()
+    {
+        delete m_socket;
+        m_socket = 0;
+        m_currentOutput.clear();
+    }
+
+    void sendMessage(int m0)
+    {
+        QByteArray m;
+        m.resize(1);
+        m[0] = m0;
+        sendMessage(m);
+    }
+
+    void sendMessage(int m0, int m1)
+    {
+        QByteArray m;
+        m.resize(2);
+        m[0] = m0;
+        m[1] = m1;
+        sendMessage(m);
+    }
+
+    void sendMessage(int m0, int m1, int m2)
+    {
+        QByteArray m;
+        m.resize(3);
+        m[0] = m0;
+        m[1] = m1;
+        m[2] = m2;
+        sendMessage(m);
+    }
+
+    void sendMessage(const QByteArray& message )
+    {
+        if (m_socket == 0) {
+            qDebug() << "udp socket is null";
+            return;
+        }
+        m_socket->writeDatagram(message, m_groupAddress, m_port);
+    }
+};
+
+NetMIDIOutput::NetMIDIOutput(QObject *parent) : MIDIOutput(parent),
+  d(new NetMIDIOutputPrivate)
+{ }
+
+NetMIDIOutput::~NetMIDIOutput()
+{
+    delete d;
+}
+
+void NetMIDIOutput::initialize(QSettings *settings)
+{
+    d->initialize(settings);
+}
+
+QString NetMIDIOutput::backendName()
+{
+    return QLatin1String("Network");
+}
+
+QString NetMIDIOutput::publicName()
+{
+    return d->m_publicName;
+}
+
+void NetMIDIOutput::setPublicName(QString name)
+{
+    d->m_publicName = name;
+}
+
+QStringList NetMIDIOutput::connections(bool advanced)
+{
+    Q_UNUSED(advanced)
+    return d->m_outputDevices;
+}
+
+void NetMIDIOutput::setExcludedConnections(QStringList conns)
+{
+    Q_UNUSED(conns)
+}
+
+void NetMIDIOutput::open(QString name)
+{
+    d->open(name);
+}
+
+void NetMIDIOutput::close()
+{
+    d->close();
+}
+
+QString NetMIDIOutput::currentConnection()
+{
+    return d->m_currentOutput;
+}
+
+void NetMIDIOutput::sendNoteOff(int chan, int note, int vel)
+{
+    d->sendMessage(MIDI_STATUS_NOTEOFF + chan, note, vel);
+}
+
+void NetMIDIOutput::sendNoteOn(int chan, int note, int vel)
+{
+    d->sendMessage(MIDI_STATUS_NOTEON + chan, note, vel);
+}
+
+void NetMIDIOutput::sendKeyPressure(int chan, int note, int value)
+{
+    d->sendMessage(MIDI_STATUS_KEYPRESURE + chan, note, value);
+}
+
+void NetMIDIOutput::sendController(int chan, int control, int value)
+{
+    d->sendMessage(MIDI_STATUS_CONTROLCHANGE + chan, control, value);
+}
+
+void NetMIDIOutput::sendProgram(int chan, int program)
+{
+    d->sendMessage(MIDI_STATUS_PROGRAMCHANGE + chan, program);
+}
+
+void NetMIDIOutput::sendChannelPressure(int chan, int value)
+{
+    d->sendMessage(MIDI_STATUS_CHANNELPRESSURE + chan, value);
+}
+
+void NetMIDIOutput::sendPitchBend(int chan, int value)
+{
+    d->sendMessage(MIDI_STATUS_PITCHBEND + chan, MIDI_LSB(value), MIDI_MSB(value));
+}
+
+void NetMIDIOutput::sendSysex(const QByteArray &data)
+{
+    d->sendMessage(data);
+}
+
+void NetMIDIOutput::sendSystemMsg(const int status)
+{
+    d->sendMessage(status);
+}
+
+}}
diff --git a/library/rt-backends/net-out/netmidioutput.h b/library/rt-backends/net-out/netmidioutput.h
new file mode 100644
index 0000000..d05c15e
--- /dev/null
+++ b/library/rt-backends/net-out/netmidioutput.h
@@ -0,0 +1,73 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef NETMIDIOUTPUT_H
+#define NETMIDIOUTPUT_H
+
+#include <QObject>
+#include <QHostAddress>
+#include "rtmidioutput.h"
+
+namespace drumstick {
+namespace rt {
+
+    const QString STR_ADDRESS(QLatin1Literal("225.0.0.37"));
+    const int MULTICAST_PORT(21928);
+    const int LAST_PORT(21948);
+
+    class NetMIDIOutput : public MIDIOutput
+    {
+        Q_OBJECT
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput")
+        Q_INTERFACES(drumstick::rt::MIDIOutput)
+
+    public:
+        NetMIDIOutput(QObject *parent = 0);
+        virtual ~NetMIDIOutput();
+
+        // MIDIOutput interface
+    public:
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+
+    public slots:
+        virtual void sendNoteOff(int chan, int note, int vel);
+        virtual void sendNoteOn(int chan, int note, int vel);
+        virtual void sendKeyPressure(int chan, int note, int value);
+        virtual void sendController(int chan, int control, int value);
+        virtual void sendProgram(int chan, int program);
+        virtual void sendChannelPressure(int chan, int value);
+        virtual void sendPitchBend(int chan, int value);
+        virtual void sendSysex(const QByteArray &data);
+        virtual void sendSystemMsg(const int status);
+    private:
+        class NetMIDIOutputPrivate;
+        NetMIDIOutputPrivate * const d;
+    };
+
+}}
+
+#endif // NETMIDIOUTPUT_H
diff --git a/library/rt-backends/oss-in/CMakeLists.txt b/library/rt-backends/oss-in/CMakeLists.txt
new file mode 100644
index 0000000..53b0353
--- /dev/null
+++ b/library/rt-backends/oss-in/CMakeLists.txt
@@ -0,0 +1,63 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+include_directories(../common)
+
+set(drumstick-rt-oss-in_QTOBJ_SRCS
+    ../../include/rtmidiinput.h
+    ../../include/rtmidioutput.h
+    ../common/midiparser.h
+    ossinput_p.h
+    ossinput.h
+)
+
+set(drumstick-rt-oss-in_SRCS
+    ../common/midiparser.cpp
+    ossinput_p.cpp
+    ossinput.cpp
+)
+
+add_definitions(-DQT_PLUGIN)
+
+qt5_wrap_cpp(drumstick-rt-oss-in_MOC_SRCS ${drumstick-rt-oss-in_QTOBJ_SRCS})
+
+if(STATIC_DRUMSTICK)
+    add_definitions(-DQT_STATICPLUGIN)
+    add_library(drumstick-rt-oss-in STATIC
+        ${drumstick-rt-oss-in_MOC_SRCS}
+        ${drumstick-rt-oss-in_SRCS})
+    set_target_properties(drumstick-rt-oss-in PROPERTIES
+         STATIC_LIB "libdrumstick-rt-oss-in")
+else()
+    add_library(drumstick-rt-oss-in MODULE
+        ${drumstick-rt-oss-in_MOC_SRCS}
+        ${drumstick-rt-oss-in_SRCS})
+endif()
+
+target_link_libraries(drumstick-rt-oss-in
+    Qt5::Core)
+
+set_target_properties(drumstick-rt-oss-in PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+install(TARGETS drumstick-rt-oss-in
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/oss-in/oss-in.pro b/library/rt-backends/oss-in/oss-in.pro
new file mode 100644
index 0000000..8e00023
--- /dev/null
+++ b/library/rt-backends/oss-in/oss-in.pro
@@ -0,0 +1,20 @@
+TEMPLATE = lib
+TARGET = $$qtLibraryTarget(drumstick-rt-oss-in)
+DESTDIR = ../../../build/lib/drumstick
+include (../../../global.pri)
+CONFIG += plugin create_prl #static
+DEPENDPATH += ../../include ../common
+INCLUDEPATH += ../../include ../common
+QT -= gui
+
+HEADERS += ../../include/rtmidiinput.h \
+           ../../include/rtmidioutput.h \
+           ../common/midiparser.h \
+           ossinput_p.h \
+           ossinput.h
+
+SOURCES += ossinput.cpp \
+           ossinput_p.cpp \
+           ../common/midiparser.cpp
+
+
diff --git a/library/rt-backends/oss-in/ossinput.cpp b/library/rt-backends/oss-in/ossinput.cpp
new file mode 100644
index 0000000..7a9830d
--- /dev/null
+++ b/library/rt-backends/oss-in/ossinput.cpp
@@ -0,0 +1,96 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "ossinput.h"
+
+namespace drumstick {
+namespace rt {
+
+OSSInput::OSSInput(QObject *parent) : MIDIInput(parent),
+    d(new OSSInputPrivate(this))
+{ }
+
+OSSInput::~OSSInput()
+{
+    delete d;
+}
+
+void OSSInput::initialize(QSettings *settings)
+{
+    Q_UNUSED(settings)
+}
+
+QString OSSInput::backendName()
+{
+    return "OSS";
+}
+
+QString OSSInput::publicName()
+{
+    return d->m_publicName;
+}
+
+void OSSInput::setPublicName(QString name)
+{
+    d->m_publicName = name;
+}
+
+QStringList OSSInput::connections(bool advanced)
+{
+    d->reloadDeviceList(advanced);
+    return d->m_inputDevices;
+}
+
+void OSSInput::setExcludedConnections(QStringList conns)
+{
+    Q_UNUSED(conns)
+}
+
+QString OSSInput::currentConnection()
+{
+    return d->m_currentInput;
+}
+
+void OSSInput::open(QString name)
+{
+    d->open(name);
+}
+
+void OSSInput::close()
+{
+    d->close();
+}
+
+void OSSInput::setMIDIThruDevice(MIDIOutput *device)
+{
+    d->setMIDIThruDevice(device);
+    //d->m_out = device;
+}
+
+void OSSInput::enableMIDIThru(bool enable)
+{
+    d->m_thruEnabled = enable;
+}
+
+bool OSSInput::isEnabledMIDIThru()
+{
+    return d->m_thruEnabled && (d->m_out != 0);
+}
+
+}}
diff --git a/library/rt-backends/oss-in/ossinput.h b/library/rt-backends/oss-in/ossinput.h
new file mode 100644
index 0000000..6787138
--- /dev/null
+++ b/library/rt-backends/oss-in/ossinput.h
@@ -0,0 +1,63 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef ossINPUT_H
+#define ossINPUT_H
+
+#include <QObject>
+#include <QtPlugin>
+#include "ossinput_p.h"
+#include "rtmidiinput.h"
+
+namespace drumstick {
+namespace rt {
+
+    class OSSInput : public MIDIInput
+    {
+        Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIInput")
+#endif
+        Q_INTERFACES(drumstick::rt::MIDIInput)
+    public:
+        OSSInput(QObject *parent = 0);
+        virtual ~OSSInput();
+
+        // MIDIInput interface
+    public:
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+
+        virtual void setMIDIThruDevice(MIDIOutput *device);
+        virtual void enableMIDIThru(bool enable);
+        virtual bool isEnabledMIDIThru();
+    private:
+        OSSInputPrivate *d;
+    };
+
+}}
+
+#endif // ossINPUT_H
diff --git a/library/rt-backends/oss-in/ossinput_p.cpp b/library/rt-backends/oss-in/ossinput_p.cpp
new file mode 100644
index 0000000..d094803
--- /dev/null
+++ b/library/rt-backends/oss-in/ossinput_p.cpp
@@ -0,0 +1,109 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QObject>
+#include <QFile>
+#include <QDir>
+#include <QDebug>
+
+#include "ossinput_p.h"
+#include "ossinput.h"
+
+namespace drumstick {
+namespace rt {
+
+static QString DEFAULT_PUBLIC_NAME(QLatin1String("MIDI In"));
+
+OSSInputPrivate::OSSInputPrivate(QObject *parent) : QObject(parent),
+    m_inp(qobject_cast<OSSInput *>(parent)),
+    m_out(0),
+    m_device(0),
+    m_notifier(0),
+    m_parser(0),
+    m_thruEnabled(false),
+    m_advanced(false),
+    m_publicName(DEFAULT_PUBLIC_NAME)
+{
+    reloadDeviceList();
+}
+
+void OSSInputPrivate::reloadDeviceList(bool advanced)
+{
+    QDir dir("/dev");
+    QStringList filters;
+    m_advanced = advanced;
+    filters << "dmmidi*" << "admmidi*";
+    if (advanced) {
+        filters << "midi*" << "amidi*";
+    }
+    dir.setNameFilters(filters);
+    dir.setFilter(QDir::System);
+    dir.setSorting(QDir::Name);
+    m_inputDevices.clear();
+    QFileInfoList listInfo = dir.entryInfoList();
+    foreach(const QFileInfo &info, listInfo) {
+        m_inputDevices << info.absoluteFilePath();
+    }
+}
+
+void OSSInputPrivate::open(QString portName)
+{
+    QFile *f = new QFile(portName);
+    m_currentInput = portName;
+    m_device = f;
+    m_device->open( QIODevice::ReadOnly | QIODevice::Unbuffered );
+    m_notifier = new QSocketNotifier(f->handle(), QSocketNotifier::Read);
+    m_parser = new MIDIParser(m_inp);
+    m_buffer.clear();
+    connect(m_notifier, SIGNAL(activated(int)), this, SLOT(processIncomingMessages(int)));
+    //qDebug() << Q_FUNC_INFO << portName;
+}
+
+void OSSInputPrivate::close()
+{
+    if (m_device != 0) {
+        m_device->close();
+        delete m_notifier;
+        delete m_device;
+        delete m_parser;
+        m_device = 0;
+        m_parser = 0;
+    }
+    m_currentInput.clear();
+}
+
+void OSSInputPrivate::setMIDIThruDevice(MIDIOutput* device)
+{
+    m_out = device;
+    if (m_parser != 0) {
+        m_parser->setMIDIThruDevice(device);
+    }
+}
+
+void OSSInputPrivate::processIncomingMessages(int)
+{
+    char ch;
+    m_device->getChar(&ch);
+    if (m_parser != 0) {
+        uchar uch = static_cast<unsigned>(ch);
+        m_parser->parse(uch);
+    }
+}
+
+}}
diff --git a/library/rt-backends/oss-in/ossinput_p.h b/library/rt-backends/oss-in/ossinput_p.h
new file mode 100644
index 0000000..1982bf9
--- /dev/null
+++ b/library/rt-backends/oss-in/ossinput_p.h
@@ -0,0 +1,65 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef OSSINPUT_P_H
+#define OSSINPUT_P_H
+
+#include <QObject>
+#include <QIODevice>
+#include <QSocketNotifier>
+#include <QStringList>
+#include <QByteArray>
+#include "midiparser.h"
+
+namespace drumstick {
+namespace rt {
+
+class MIDIOutput;
+class OSSInput;
+
+class OSSInputPrivate : public QObject
+{
+    Q_OBJECT
+public:
+    OSSInput *m_inp;
+    MIDIOutput *m_out;
+    QIODevice *m_device;
+    QSocketNotifier *m_notifier;
+    MIDIParser *m_parser;
+    bool m_thruEnabled;
+    bool m_advanced;
+    QString m_publicName;
+    QString m_currentInput;
+    QStringList m_inputDevices;
+    QStringList m_excludedNames;
+    QByteArray m_buffer;
+
+    OSSInputPrivate(QObject *parent = 0);
+    void reloadDeviceList(bool advanced = false);
+    void open(QString portName);
+    void close();
+    //void parse();
+    void setMIDIThruDevice(MIDIOutput* device);
+
+public slots:
+    void processIncomingMessages(int);
+};
+
+}}
+#endif // OSSINPUT_P_H
diff --git a/library/rt-backends/oss-out/CMakeLists.txt b/library/rt-backends/oss-out/CMakeLists.txt
new file mode 100644
index 0000000..3efcc4a
--- /dev/null
+++ b/library/rt-backends/oss-out/CMakeLists.txt
@@ -0,0 +1,56 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(drumstick-rt-oss-out_QTOBJ_SRCS
+    ../../include/rtmidioutput.h
+    ossoutput.h
+)
+
+set(drumstick-rt-oss-out_SRCS
+    ossoutput.cpp
+)
+
+add_definitions(-DQT_PLUGIN)
+
+qt5_wrap_cpp(drumstick-rt-oss-out_MOC_SRCS ${drumstick-rt-oss-out_QTOBJ_SRCS})
+
+if(STATIC_DRUMSTICK)
+    add_definitions(-DQT_STATICPLUGIN)
+    add_library(drumstick-rt-oss-out STATIC
+        ${drumstick-rt-oss-out_MOC_SRCS}
+        ${drumstick-rt-oss-out_SRCS})
+    set_target_properties(drumstick-rt-oss-out PROPERTIES
+         STATIC_LIB "libdrumstick-rt-oss-out")
+else()
+    add_library(drumstick-rt-oss-out MODULE
+        ${drumstick-rt-oss-out_MOC_SRCS}
+        ${drumstick-rt-oss-out_SRCS})
+endif()
+
+target_link_libraries(drumstick-rt-oss-out
+    Qt5::Core)
+
+set_target_properties(drumstick-rt-oss-out PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+install(TARGETS drumstick-rt-oss-out
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/oss-out/oss-out.pro b/library/rt-backends/oss-out/oss-out.pro
new file mode 100644
index 0000000..cd30d43
--- /dev/null
+++ b/library/rt-backends/oss-out/oss-out.pro
@@ -0,0 +1,16 @@
+TEMPLATE = lib
+TARGET = $$qtLibraryTarget(drumstick-rt-oss-out)
+DESTDIR = ../../../build/lib/drumstick
+include (../../../global.pri)
+CONFIG += plugin create_prl #static
+DEPENDPATH += ../../include
+INCLUDEPATH += ../../include
+QT -= gui
+
+HEADERS += ../../include/rtmidiinput.h \
+           ../../include/rtmidioutput.h \
+           ossoutput.h
+
+SOURCES += \
+           ossoutput.cpp
+
diff --git a/library/rt-backends/oss-out/ossoutput.cpp b/library/rt-backends/oss-out/ossoutput.cpp
new file mode 100644
index 0000000..26ee868
--- /dev/null
+++ b/library/rt-backends/oss-out/ossoutput.cpp
@@ -0,0 +1,228 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QFile>
+#include <QDir>
+#include <QDebug>
+
+#include "ossoutput.h"
+
+namespace drumstick {
+namespace rt {
+
+static QString DEFAULT_PUBLIC_NAME(QLatin1String("MIDI Out"));
+
+class OSSOutput::OSSOutputPrivate
+{
+public:
+    bool m_advanced;
+    QIODevice *m_device;
+    QString m_publicName;
+    QString m_currentOutput;
+    QStringList m_outputDevices;
+    QStringList m_excludedNames;
+
+    OSSOutputPrivate() :
+        m_advanced(false),
+        m_device(0),
+        m_publicName(DEFAULT_PUBLIC_NAME)
+    {
+        reloadDeviceList();
+    }
+
+    ~OSSOutputPrivate()
+    {
+        close();
+    }
+
+    void reloadDeviceList(bool advanced = false)
+    {
+        QDir dir("/dev");
+        QStringList filters;
+        m_advanced = advanced;
+        filters << "dmmidi*" << "admmidi*";
+        if (advanced) {
+            filters << "midi*" << "amidi*";
+        }
+        dir.setNameFilters(filters);
+        dir.setFilter(QDir::System);
+        dir.setSorting(QDir::Name);
+        m_outputDevices.clear();
+        QFileInfoList listInfo = dir.entryInfoList();
+        foreach(const QFileInfo &info, listInfo) {
+            m_outputDevices << info.absoluteFilePath();
+        }
+    }
+
+    void open(QString portName)
+    {
+        //qDebug() << Q_FUNC_INFO << portName;
+        m_device = new QFile(portName);
+        m_device->open(QIODevice::WriteOnly | QIODevice::Unbuffered);
+        m_currentOutput = portName;
+    }
+
+    void close()
+    {
+        if (m_device != 0) {
+            m_device->close();
+            delete m_device;
+            m_device = 0;
+        }
+        m_currentOutput.clear();
+    }
+
+    void sendMessage(int m0)
+    {
+        QByteArray m;
+        m.resize(1);
+        m[0] = m0;
+        sendMessage(m);
+    }
+
+    void sendMessage(int m0, int m1)
+    {
+        QByteArray m;
+        m.resize(2);
+        m[0] = m0;
+        m[1] = m1;
+        sendMessage(m);
+    }
+
+    void sendMessage(int m0, int m1, int m2)
+    {
+        QByteArray m;
+        m.resize(3);
+        m[0] = m0;
+        m[1] = m1;
+        m[2] = m2;
+        sendMessage(m);
+    }
+
+    void sendMessage(const QByteArray& message )
+    {
+        if (m_device == 0) {
+            qDebug() << "qfile is null";
+            return;
+        }
+        m_device->write(message);
+        //m_device->flush();
+    }
+};
+
+OSSOutput::OSSOutput(QObject *parent) : MIDIOutput(parent),
+    d(new OSSOutputPrivate)
+{}
+
+OSSOutput::~OSSOutput()
+{
+    delete d;
+}
+
+void OSSOutput::initialize(QSettings *settings)
+{
+    Q_UNUSED(settings)
+}
+
+QString OSSOutput::backendName()
+{
+    return QLatin1String("OSS");
+}
+
+QString OSSOutput::publicName()
+{
+    return d->m_publicName;
+}
+
+void OSSOutput::setPublicName(QString name)
+{
+    d->m_publicName = name;
+}
+
+QStringList OSSOutput::connections(bool advanced)
+{
+    d->reloadDeviceList(advanced);
+    return d->m_outputDevices;
+}
+
+void OSSOutput::setExcludedConnections(QStringList conns)
+{
+    Q_UNUSED(conns)
+}
+
+void OSSOutput::open(QString name)
+{
+    d->open(name);
+}
+
+void OSSOutput::close()
+{
+    d->close();
+}
+
+QString OSSOutput::currentConnection()
+{
+    return d->m_currentOutput;
+}
+
+void OSSOutput::sendNoteOff(int chan, int note, int vel)
+{
+    d->sendMessage(MIDI_STATUS_NOTEOFF + chan, note, vel);}
+
+void OSSOutput::sendNoteOn(int chan, int note, int vel)
+{
+    d->sendMessage(MIDI_STATUS_NOTEON + chan, note, vel);
+}
+
+void OSSOutput::sendKeyPressure(int chan, int note, int value)
+{
+    d->sendMessage(MIDI_STATUS_KEYPRESURE + chan, note, value);
+}
+
+void OSSOutput::sendController(int chan, int control, int value)
+{
+    d->sendMessage(MIDI_STATUS_CONTROLCHANGE + chan, control, value);
+}
+
+void OSSOutput::sendProgram(int chan, int program)
+{
+    d->sendMessage(MIDI_STATUS_PROGRAMCHANGE + chan, program);
+}
+
+void OSSOutput::sendChannelPressure(int chan, int value)
+{
+    d->sendMessage(MIDI_STATUS_CHANNELPRESSURE + chan, value);
+}
+
+void OSSOutput::sendPitchBend(int chan, int value)
+{
+    d->sendMessage(MIDI_STATUS_PITCHBEND + chan, MIDI_LSB(value), MIDI_MSB(value));
+}
+
+void OSSOutput::sendSysex(const QByteArray &data)
+{
+    d->sendMessage(data);
+}
+
+void OSSOutput::sendSystemMsg(const int status)
+{
+    d->sendMessage(status);
+}
+
+}}
diff --git a/library/rt-backends/oss-out/ossoutput.h b/library/rt-backends/oss-out/ossoutput.h
new file mode 100644
index 0000000..cc1cce9
--- /dev/null
+++ b/library/rt-backends/oss-out/ossoutput.h
@@ -0,0 +1,70 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef ossOUTPUT_H
+#define ossOUTPUT_H
+
+#include <QObject>
+#include "rtmidioutput.h"
+
+namespace drumstick {
+namespace rt {
+
+    class OSSOutput : public MIDIOutput
+    {
+        Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput")
+#endif
+        Q_INTERFACES(drumstick::rt::MIDIOutput)
+
+    public:
+        OSSOutput(QObject *parent = 0);
+        virtual ~OSSOutput();
+
+        // MIDIOutput interface
+    public:
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+
+    public slots:
+        virtual void sendNoteOff(int chan, int note, int vel);
+        virtual void sendNoteOn(int chan, int note, int vel);
+        virtual void sendKeyPressure(int chan, int note, int value);
+        virtual void sendController(int chan, int control, int value);
+        virtual void sendProgram(int chan, int program);
+        virtual void sendChannelPressure(int chan, int value);
+        virtual void sendPitchBend(int chan, int value);
+        virtual void sendSysex(const QByteArray &data);
+        virtual void sendSystemMsg(const int status);
+    private:
+        class OSSOutputPrivate;
+        OSSOutputPrivate *d;
+    };
+
+}}
+
+#endif // ossOUTPUT_H
diff --git a/library/rt-backends/rt-backends.pro b/library/rt-backends/rt-backends.pro
new file mode 100644
index 0000000..17d4592
--- /dev/null
+++ b/library/rt-backends/rt-backends.pro
@@ -0,0 +1,24 @@
+TEMPLATE = subdirs
+
+dummy {
+    SUBDIRS += dummy-in dummy-out
+}
+
+linux* {
+    SUBDIRS += alsa-in alsa-out
+}
+
+unix:!macx {
+    SUBDIRS += oss-in oss-out
+}
+
+macx {
+    SUBDIRS += mac-in mac-out
+}
+
+win32 {
+    SUBDIRS += win-in win-out
+}
+
+SUBDIRS += net-in net-out
+SUBDIRS += synth
diff --git a/library/rt-backends/synth/CMakeLists.txt b/library/rt-backends/synth/CMakeLists.txt
new file mode 100644
index 0000000..92dab25
--- /dev/null
+++ b/library/rt-backends/synth/CMakeLists.txt
@@ -0,0 +1,63 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+pkg_check_modules(FLUIDSYNTH REQUIRED fluidsynth>=1.1.1)
+include_directories(${FLUIDSYNTH_INCLUDEDIR})
+link_directories(${FLUIDSYNTH_LIBDIR})
+
+set(drumstick-rt-synth_QTOBJ_SRCS
+    ../../include/rtmidioutput.h
+    synthengine.h
+    synthoutput.h
+)
+
+set(drumstick-rt-synth_SRCS
+    synthengine.cpp
+    synthoutput.cpp
+)
+
+add_definitions(-DQT_PLUGIN)
+
+qt5_wrap_cpp(drumstick-rt-synth_MOC_SRCS ${drumstick-rt-synth_QTOBJ_SRCS})
+
+if(STATIC_DRUMSTICK)
+    add_definitions(-DQT_STATICPLUGIN)
+    add_library(drumstick-rt-synth STATIC
+        ${drumstick-rt-synth_MOC_SRCS}
+        ${drumstick-rt-synth_SRCS})
+    set_target_properties(drumstick-rt-synth PROPERTIES
+         STATIC_LIB "libdrumstick-rt-synth")
+else()
+    add_library(drumstick-rt-synth MODULE
+        ${drumstick-rt-synth_MOC_SRCS}
+        ${drumstick-rt-synth_SRCS})
+endif()
+
+target_link_libraries(drumstick-rt-synth
+    Qt5::Core
+    ${FLUIDSYNTH_LIBRARIES})
+
+set_target_properties(drumstick-rt-synth PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+install(TARGETS drumstick-rt-synth
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/synth/synth.pro b/library/rt-backends/synth/synth.pro
new file mode 100644
index 0000000..25915f5
--- /dev/null
+++ b/library/rt-backends/synth/synth.pro
@@ -0,0 +1,29 @@
+TEMPLATE = lib
+TARGET = $$qtLibraryTarget(drumstick-rt-synth)
+DESTDIR = ../../../build/lib/drumstick
+include (../../../global.pri)
+CONFIG += plugin #create_prl static
+DEPENDPATH += ../../include
+INCLUDEPATH += ../../include
+QT -= gui
+
+HEADERS += ../../include/rtmidiinput.h \
+           ../../include/rtmidioutput.h \
+           synthengine.h \
+           synthoutput.h
+
+SOURCES += synthoutput.cpp synthengine.cpp
+
+macx {
+    INCLUDEPATH += /Library/Frameworks/FluidSynth.framework/Headers
+    QMAKE_LFLAGS += -F/Library/Frameworks
+    LIBS += -framework FluidSynth
+}
+else {
+    CONFIG += link_pkgconfig
+    PKGCONFIG += fluidsynth
+}
+
+win32 {
+    TARGET_EXT = .dll
+}
diff --git a/library/rt-backends/synth/synthengine.cpp b/library/rt-backends/synth/synthengine.cpp
new file mode 100644
index 0000000..85ab752
--- /dev/null
+++ b/library/rt-backends/synth/synthengine.cpp
@@ -0,0 +1,249 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <QDir>
+#include <QFileInfo>
+#include <QSettings>
+#include <QStandardPaths>
+#include <QCoreApplication>
+#include <QDebug>
+#include "synthengine.h"
+
+const QString QSTR_PREFERENCES("FluidSynth");
+const QString QSTR_INSTRUMENTSDEFINITION("InstrumentsDefinition");
+const QString QSTR_DATADIR("soundfonts");
+const QString QSTR_SOUNDFONT("default.sf2");
+
+const QString QSTR_AUDIODRIVER("AudioDriver");
+const QString QSTR_PERIODSIZE("PeriodSize");
+const QString QSTR_PERIODS("Periods");
+const QString QSTR_SAMPLERATE("SampleRate");
+const QString QSTR_CHORUS("Chorus");
+const QString QSTR_REVERB("Reverb");
+const QString QSTR_GAIN("Gain");
+const QString QSTR_POLYPHONY("Polyphony");
+
+const QString QSTR_DEFAULT_AUDIODRIVER =
+#if defined(Q_OS_LINUX)
+    QLatin1Literal("alsa");
+#elif defined(Q_OS_WIN)
+    QLatin1Literal("dsound");
+#elif defined(Q_OS_OSX)
+    QLatin1Literal("coreaudio");
+#else
+    QLatin1Literal("oss");
+#endif
+const int DEFAULT_PERIODS =
+#if defined(Q_OS_WIN)
+    4;
+#else
+    3;
+#endif
+const int DEFAULT_PERIODSIZE = 512;
+const double DEFAULT_SAMPLERATE = 48000.0;
+const int DEFAULT_CHORUS = 0;
+const int DEFAULT_REVERB = 0;
+const double DEFAULT_GAIN = .4;
+const int DEFAULT_POLYPHONY = 32;
+
+SynthEngine::SynthEngine(QObject *parent)
+    : QObject(parent),
+      m_settings(0),
+      m_synth(0),
+      m_driver(0)
+{ }
+
+SynthEngine::~SynthEngine()
+{
+    uninitialize();
+}
+
+void SynthEngine::uninitialize()
+{
+    if (m_driver != 0) {
+        ::delete_fluid_audio_driver(m_driver);
+        m_driver = 0;
+    }
+    if (m_synth != 0) {
+        ::delete_fluid_synth(m_synth);
+        m_synth = 0;
+    }
+    if (m_settings != 0) {
+        ::delete_fluid_settings(m_settings);
+        m_settings = 0;
+    }
+}
+
+void SynthEngine::initializeSynth(QSettings* settings)
+{
+    QString fs_audiodriver = QSTR_DEFAULT_AUDIODRIVER;
+    int fs_periodSize = DEFAULT_PERIODSIZE;
+    int fs_periods = DEFAULT_PERIODS;
+    double fs_sampleRate = DEFAULT_SAMPLERATE;
+    int fs_chorus = DEFAULT_CHORUS;
+    int fs_reverb = DEFAULT_REVERB;
+    double fs_gain = DEFAULT_GAIN;
+    int fs_polyphony = DEFAULT_POLYPHONY;
+    if (settings != 0) {
+        settings->beginGroup(QSTR_PREFERENCES);
+        fs_audiodriver = settings->value(QSTR_AUDIODRIVER, QSTR_DEFAULT_AUDIODRIVER).toString();
+        fs_periodSize = settings->value(QSTR_PERIODSIZE, DEFAULT_PERIODSIZE).toInt();
+        fs_periods = settings->value(QSTR_PERIODS, DEFAULT_PERIODS).toInt();
+        fs_sampleRate = settings->value(QSTR_SAMPLERATE, DEFAULT_SAMPLERATE).toDouble();
+        fs_chorus = settings->value(QSTR_CHORUS, DEFAULT_CHORUS).toInt();
+        fs_reverb = settings->value(QSTR_REVERB, DEFAULT_REVERB).toInt();
+        fs_gain = settings->value(QSTR_GAIN, DEFAULT_GAIN).toDouble();
+        fs_polyphony = settings->value(QSTR_POLYPHONY, DEFAULT_POLYPHONY).toInt();
+        settings->endGroup();
+    }
+    uninitialize();
+    m_settings = ::new_fluid_settings();
+    ::fluid_settings_setstr(m_settings, "audio.driver", qPrintable(fs_audiodriver));
+    ::fluid_settings_setint(m_settings, "audio.period-size", fs_periodSize);
+    ::fluid_settings_setint(m_settings, "audio.periods", fs_periods);
+    ::fluid_settings_setnum(m_settings, "synth.sample-rate", fs_sampleRate);
+    ::fluid_settings_setint(m_settings, "synth.chorus.active", fs_chorus);
+    ::fluid_settings_setint(m_settings, "synth.reverb.active", fs_reverb);
+    ::fluid_settings_setnum(m_settings, "synth.gain", fs_gain);
+    ::fluid_settings_setint(m_settings, "synth.polyphony", fs_polyphony);
+    m_synth = ::new_fluid_synth(m_settings);
+    m_driver = ::new_fluid_audio_driver(m_settings, m_synth);
+}
+
+void SynthEngine::setInstrument(int channel, int pgm)
+{
+    ::fluid_synth_program_change(m_synth, channel, pgm);
+}
+
+void SynthEngine::noteOn(int channel, int midiNote, int velocity)
+{
+    ::fluid_synth_noteon(m_synth, channel, midiNote, velocity);
+}
+
+void SynthEngine::noteOff(int channel, int midiNote, int /*velocity*/)
+{
+    ::fluid_synth_noteoff(m_synth, channel, midiNote);
+}
+
+void SynthEngine::loadSoundFont()
+{
+    if (m_sfid != -1) {
+        ::fluid_synth_sfunload(m_synth, unsigned(m_sfid), 1);
+    }
+    m_sfid = ::fluid_synth_sfload(m_synth, qPrintable(m_soundFont), 1);
+}
+
+void SynthEngine::initialize(QSettings *settings)
+{
+    initializeSynth(settings);
+    scanSoundFonts();
+    loadSoundFont();
+    if (m_sfid < 0) {
+        m_soundFont = m_defSoundFont;
+        loadSoundFont();
+    }
+}
+
+void SynthEngine::panic()
+{
+    ::fluid_synth_system_reset(m_synth);
+}
+
+void SynthEngine::controlChange(const int channel, const int midiCtl, const int value)
+{
+    ::fluid_synth_cc(m_synth, channel, midiCtl, value);
+}
+
+void SynthEngine::bender(const int channel, const int value)
+{
+    ::fluid_synth_pitch_bend(m_synth, channel, value + 8192);
+}
+
+void SynthEngine::setSoundFont(const QString &value)
+{
+    if (value != m_soundFont) {
+        m_soundFont = value;
+        loadSoundFont();
+    }
+}
+
+void SynthEngine::scanSoundFonts(const QDir &initialDir)
+{
+    QDir dir(initialDir);
+    dir.setFilter(QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot);
+    dir.setSorting(QDir::Name);
+    QStringList filters;
+    filters << "*.sf2" << "*.SF2";
+    QFileInfoList entries= dir.entryInfoList(filters);
+    foreach(const QFileInfo &info, entries) {
+        QString name = info.absoluteFilePath();
+        if (info.isFile()) {
+            m_soundFontsList << name;
+        } else if (info.isDir()){
+            scanSoundFonts(name);
+        }
+    }
+}
+
+void SynthEngine::scanSoundFonts()
+{
+    m_soundFontsList.clear();
+    QStringList paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
+#if defined(Q_OS_OSX)
+    paths << (QCoreApplication::applicationDirPath() + QLatin1Literal("../Resources"));
+#endif
+    foreach(const QString& p, paths) {
+       QDir d(p + QDir::separator() + QSTR_DATADIR);
+       if (d.exists()) {
+            scanSoundFonts(d);
+       }
+    }
+}
+
+void SynthEngine::readSettings(QSettings *settings)
+{
+    QDir dir;
+#if defined(Q_OS_OSX)
+    dir = QDir(QCoreApplication::applicationDirPath() + QLatin1Literal("/../Resources"));
+#elif defined(Q_OS_UNIX)
+    dir = QDir(QCoreApplication::applicationDirPath() + QLatin1Literal("/../share/soundfonts/"));
+#else
+    dir = QDir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR, QStandardPaths::LocateDirectory));
+#endif
+    QFileInfo sf2(dir, QSTR_SOUNDFONT);
+    if (sf2.exists()) {
+        m_defSoundFont = sf2.absoluteFilePath();
+    }
+    m_sfid = -1;
+    qDebug() << "defSoundFont:" << m_defSoundFont;
+    settings->beginGroup(QSTR_PREFERENCES);
+    m_soundFont = settings->value(QSTR_INSTRUMENTSDEFINITION, m_defSoundFont).toString();
+    settings->endGroup();
+}
+
+void SynthEngine::close()
+{
+    m_currentConnection.clear();
+    uninitialize();
+}
+
+void SynthEngine::open()
+{
+    m_currentConnection = QSTR_FLUIDSYNTH;
+}
+
diff --git a/library/rt-backends/synth/synthengine.h b/library/rt-backends/synth/synthengine.h
new file mode 100644
index 0000000..3a006e9
--- /dev/null
+++ b/library/rt-backends/synth/synthengine.h
@@ -0,0 +1,78 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SynthEngine_H
+#define SynthEngine_H
+
+#include <QObject>
+#include <QString>
+#include <QList>
+#include <QDir>
+#include <QSettings>
+#include <fluidsynth.h>
+
+#define cvtstr(s) #s
+#define stringify(s) cvtstr(s)
+
+const QString QSTR_FLUIDSYNTH(QLatin1String("FluidSynth"));
+
+class SynthEngine : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QString soundFont READ soundFont WRITE setSoundFont)
+
+public:
+    SynthEngine(QObject *parent = 0);
+    virtual ~SynthEngine();
+
+    QString soundFont() const { return m_soundFont; }
+    void setSoundFont(const QString &value);
+
+    Q_INVOKABLE void initialize(QSettings *settings);
+    Q_INVOKABLE void readSettings(QSettings *settings);
+    Q_INVOKABLE void scanSoundFonts();
+    Q_INVOKABLE void panic();
+    Q_INVOKABLE void setInstrument(const int channel, int i);
+    Q_INVOKABLE void noteOn(const int channel, const int midiNote, const int velocity);
+    Q_INVOKABLE void noteOff(const int channel, const int midiNote, const int velocity);
+    Q_INVOKABLE void controlChange(const int channel, const int ctl, const int value);
+    Q_INVOKABLE void bender(const int channel, const int value);
+    Q_INVOKABLE QString version() const { return stringify(VERSION); }
+
+    QString currentConnection() const { return m_currentConnection; }
+    void close();
+    void open();
+    void uninitialize();
+
+private:
+    void scanSoundFonts(const QDir &dir);
+    void initializeSynth(QSettings *settings = 0);
+    void loadSoundFont();
+
+    int m_sfid;
+    QString m_currentConnection;
+    QString m_soundFont;
+    QString m_defSoundFont;
+    fluid_settings_t* m_settings;
+    fluid_synth_t* m_synth;
+    fluid_audio_driver_t* m_driver;
+    QStringList m_soundFontsList;
+};
+
+#endif // SynthEngine_H
+
diff --git a/library/rt-backends/synth/synthoutput.cpp b/library/rt-backends/synth/synthoutput.cpp
new file mode 100644
index 0000000..f4ecb25
--- /dev/null
+++ b/library/rt-backends/synth/synthoutput.cpp
@@ -0,0 +1,128 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "synthoutput.h"
+
+namespace drumstick {
+namespace rt {
+
+SynthOutput::SynthOutput(QObject *parent) : MIDIOutput(parent),
+    m_synth(new SynthEngine(this))
+{ }
+
+SynthOutput::~SynthOutput()
+{ }
+
+void SynthOutput::initialize(QSettings *settings)
+{
+    m_synth->readSettings(settings);
+    m_synth->initialize(settings);
+}
+
+QString SynthOutput::backendName()
+{
+    return QSTR_FLUIDSYNTH;
+}
+
+QString SynthOutput::publicName()
+{
+    return QSTR_FLUIDSYNTH;
+}
+
+void SynthOutput::setPublicName(QString name)
+{
+    Q_UNUSED(name)
+}
+
+QStringList SynthOutput::connections(bool advanced)
+{
+    Q_UNUSED(advanced)
+    return QStringList(QSTR_FLUIDSYNTH);
+}
+
+void SynthOutput::setExcludedConnections(QStringList conns)
+{
+    Q_UNUSED(conns)
+}
+
+void SynthOutput::open(QString name)
+{
+    Q_UNUSED(name)
+    m_synth->open();
+}
+
+void SynthOutput::close()
+{
+    m_synth->close();
+}
+
+QString SynthOutput::currentConnection()
+{
+    return m_synth->currentConnection();
+}
+
+void SynthOutput::sendNoteOff(int chan, int note, int vel)
+{
+    m_synth->noteOff(chan, note, vel);
+}
+
+void SynthOutput::sendNoteOn(int chan, int note, int vel)
+{
+    m_synth->noteOn(chan, note, vel);
+}
+
+void SynthOutput::sendKeyPressure(int chan, int note, int value)
+{
+    Q_UNUSED(chan)
+    Q_UNUSED(note)
+    Q_UNUSED(value)
+}
+
+void SynthOutput::sendController(int chan, int control, int value)
+{
+    m_synth->controlChange(chan, control, value);
+}
+
+void SynthOutput::sendProgram(int chan, int program)
+{
+    m_synth->setInstrument(chan, program);
+}
+
+void SynthOutput::sendChannelPressure(int chan, int value)
+{
+    Q_UNUSED(chan)
+    Q_UNUSED(value)
+}
+
+void SynthOutput::sendPitchBend(int chan, int value)
+{
+    m_synth->bender(chan, value);
+}
+
+void SynthOutput::sendSysex(const QByteArray &data)
+{
+    Q_UNUSED(data)
+}
+
+void SynthOutput::sendSystemMsg(const int status)
+{
+    Q_UNUSED(status)
+}
+
+}}
diff --git a/library/rt-backends/synth/synthoutput.h b/library/rt-backends/synth/synthoutput.h
new file mode 100644
index 0000000..ab71e5a
--- /dev/null
+++ b/library/rt-backends/synth/synthoutput.h
@@ -0,0 +1,69 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef SynthOUTPUT_H
+#define SynthOUTPUT_H
+
+#include <QObject>
+#include "rtmidioutput.h"
+#include "synthengine.h"
+
+namespace drumstick {
+namespace rt {
+
+    class SynthOutput : public MIDIOutput
+    {
+        Q_OBJECT
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput")
+        Q_INTERFACES(drumstick::rt::MIDIOutput)
+
+    public:
+        SynthOutput(QObject *parent = 0);
+        virtual ~SynthOutput();
+
+        // MIDIOutput interface
+    public:
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+
+    public slots:
+        virtual void sendNoteOff(int chan, int note, int vel);
+        virtual void sendNoteOn(int chan, int note, int vel);
+        virtual void sendKeyPressure(int chan, int note, int value);
+        virtual void sendController(int chan, int control, int value);
+        virtual void sendProgram(int chan, int program);
+        virtual void sendChannelPressure(int chan, int value);
+        virtual void sendPitchBend(int chan, int value);
+        virtual void sendSysex(const QByteArray &data);
+        virtual void sendSystemMsg(const int status);
+
+    private:
+        SynthEngine *m_synth;
+    };
+
+}}
+
+#endif // SynthOUTPUT_H
diff --git a/library/rt-backends/win-in/CMakeLists.txt b/library/rt-backends/win-in/CMakeLists.txt
new file mode 100644
index 0000000..2566a5f
--- /dev/null
+++ b/library/rt-backends/win-in/CMakeLists.txt
@@ -0,0 +1,58 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(drumstick-rt-win-in_QTOBJ_SRCS
+    ../../include/rtmidiinput.h
+    ../../include/rtmidioutput.h
+    winmidiinput.h
+)
+
+set(drumstick-rt-win-in_SRCS
+    winmidiinput.cpp
+)
+
+add_definitions(-DQT_PLUGIN)
+
+qt5_wrap_cpp(drumstick-rt-win-in_MOC_SRCS ${drumstick-rt-win-in_QTOBJ_SRCS})
+
+if(STATIC_DRUMSTICK)
+    add_definitions(-DQT_STATICPLUGIN)
+    add_library(drumstick-rt-win-in STATIC
+        ${drumstick-rt-win-in_MOC_SRCS}
+        ${drumstick-rt-win-in_SRCS})
+    set_target_properties(drumstick-rt-win-in PROPERTIES
+         STATIC_LIB "libdrumstick-rt-win-in")
+else()
+    add_library(drumstick-rt-win-in MODULE
+        ${drumstick-rt-win-in_MOC_SRCS}
+        ${drumstick-rt-win-in_SRCS})
+endif()
+
+target_link_libraries(drumstick-rt-win-in
+    Qt5::Core
+    winmm)
+
+set_target_properties(drumstick-rt-win-in PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+install(TARGETS drumstick-rt-win-in
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/win-in/win-in.pro b/library/rt-backends/win-in/win-in.pro
new file mode 100644
index 0000000..9bf5f9f
--- /dev/null
+++ b/library/rt-backends/win-in/win-in.pro
@@ -0,0 +1,23 @@
+TEMPLATE = lib
+CONFIG += plugin #create_prl static
+TARGET = $$qtLibraryTarget(drumstick-rt-win-in)
+DESTDIR = ../../../build/lib/drumstick
+DEPENDPATH += . ../../include
+INCLUDEPATH += . ../../include
+include (../../../global.pri)
+DEPENDPATH += ../../include
+INCLUDEPATH += ../../include
+QT -= gui
+
+HEADERS += ../../include/rtmidiinput.h \
+           ../../include/rtmidioutput.h \
+           winmidiinput.h
+
+SOURCES += \
+           winmidiinput.cpp
+
+LIBS += -lwinmm
+
+win32 {
+    TARGET_EXT = .dll
+}
diff --git a/library/rt-backends/win-in/winmidiinput.cpp b/library/rt-backends/win-in/winmidiinput.cpp
new file mode 100644
index 0000000..58a11c3
--- /dev/null
+++ b/library/rt-backends/win-in/winmidiinput.cpp
@@ -0,0 +1,327 @@
+/*
+    Drumstick RT Windows Backend
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QString>
+#include <QMap>
+#include <QDebug>
+#include <windows.h>
+#include <mmsystem.h>
+
+#include "winmidiinput.h"
+
+namespace drumstick {
+namespace rt {
+
+    static QLatin1Literal DEFAULT_PUBLIC_NAME = QLatin1Literal("MIDI In");
+
+    void CALLBACK midiCallback( HMIDIIN hMidiIn,
+                                UINT wMsg,
+                                DWORD_PTR dwInstance,
+                                DWORD_PTR dwParam1,
+                                DWORD_PTR dwParam2 );
+
+
+    class WinMIDIInput::WinMIDIInputPrivate {
+    public:
+        WinMIDIInput *m_inp;
+        MIDIOutput *m_out;
+        bool m_thruEnabled;
+        bool m_clientFilter;
+        HMIDIIN m_handle;
+        QString m_publicName;
+        QString m_currentInput;
+        QStringList m_excludedNames;
+        QMap<int,QString> m_inputDevices;
+
+        WinMIDIInputPrivate(WinMIDIInput *inp):
+            m_inp(inp),
+            m_out(0),
+            m_thruEnabled(false),
+            m_clientFilter(true),
+            m_handle(0),
+            m_publicName(DEFAULT_PUBLIC_NAME)
+        {
+            reloadDeviceList(true);
+        }
+
+        int deviceIndex( const QString& newDevice )
+        {
+            int index = -1;
+            QMap<int,QString>::ConstIterator it;
+            for( it = m_inputDevices.constBegin();
+                 it != m_inputDevices.constEnd(); ++it ) {
+                if (it.value() == newDevice) {
+                    index = it.key();
+                    break;
+                }
+            }
+            return index;
+        }
+
+        void open(QString name) {
+            MMRESULT res;
+            if (name != m_currentInput) {
+                if (m_handle != 0)
+                    close();
+                reloadDeviceList(!m_clientFilter);
+                int dev = deviceIndex(name);
+                if (dev > -1) {
+                    res = midiInOpen(&m_handle, dev, (DWORD_PTR) midiCallback, (DWORD_PTR) this, CALLBACK_FUNCTION | MIDI_IO_STATUS );
+                    if (res != MMSYSERR_NOERROR)
+                        qDebug() << "midiInOpen() err:" << mmErrorString(res);
+                    res = midiInStart(m_handle);
+                    if (res != MMSYSERR_NOERROR)
+                        qDebug() << "midiInStart() err:" << mmErrorString(res);
+                    m_currentInput = name;
+                }
+            }
+        }
+
+        void close() {
+            MMRESULT res;
+            if (m_handle != 0) {
+                res = midiInStop(m_handle);
+                if (res != MMSYSERR_NOERROR)
+                    qDebug() << "midiInStop() err:" << mmErrorString(res);
+                res = midiInReset( m_handle );
+                if (res != MMSYSERR_NOERROR)
+                    qDebug() << "midiInReset() err:" << mmErrorString(res);
+                res = midiInClose( m_handle );
+                if (res != MMSYSERR_NOERROR)
+                    qDebug() << "midiInClose() err:" << mmErrorString(res);
+                m_handle = 0;
+            }
+            m_currentInput.clear();
+        }
+
+        void reloadDeviceList(bool advanced)
+        {
+            MMRESULT res;
+            MIDIINCAPS deviceCaps;
+            QString devName;
+            unsigned int dev, max = midiInGetNumDevs();
+            m_inputDevices.clear();
+            m_clientFilter = !advanced;
+
+            for ( dev = 0; dev < max; ++dev) {
+                bool excluded = false;
+                res = midiInGetDevCaps( dev, &deviceCaps, sizeof(MIDIINCAPS));
+                if (res != MMSYSERR_NOERROR)
+                    break;
+#if defined(UNICODE)
+                devName = QString::fromWCharArray(deviceCaps.szPname);
+#else
+                devName = QString::fromLocal8Bit(deviceCaps.szPname);
+#endif
+                foreach(const QString& n, m_excludedNames) {
+                    if (devName.startsWith(n)) {
+                        excluded = true;
+                        break;
+                    }
+                }
+                if (!excluded)
+                    m_inputDevices[dev] = devName;
+            }
+        }
+
+        void setPublicName(QString name)
+        {
+            if (m_publicName != name) {
+                m_publicName = name;
+            }
+        }
+
+        void emitSignals(int status, int channel, int data1, int data2)
+        {
+            switch (status) {
+            case MIDI_STATUS_NOTEOFF:
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendNoteOff(channel, data1, data2);
+                emit m_inp->midiNoteOff(channel, data1, data2);
+                break;
+            case MIDI_STATUS_NOTEON:
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendNoteOn(channel, data1, data2);
+                emit m_inp->midiNoteOn(channel, data1, data2);
+                break;
+            case MIDI_STATUS_KEYPRESURE:
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendKeyPressure(channel, data1, data2);
+                emit m_inp->midiKeyPressure(channel, data1, data2);
+                break;
+            case MIDI_STATUS_CONTROLCHANGE:
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendController(channel, data1, data2);
+                emit m_inp->midiController(channel, data1, data2);
+                break;
+            case MIDI_STATUS_PROGRAMCHANGE:
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendProgram(channel, data1);
+                emit m_inp->midiProgram(channel, data1);
+                break;
+            case MIDI_STATUS_CHANNELPRESSURE:
+                if(m_out != 0 && m_thruEnabled)
+                    m_out->sendChannelPressure(channel, data1);
+                emit m_inp->midiChannelPressure(channel, data1);
+                break;
+            case MIDI_STATUS_PITCHBEND: {
+                    int value = (data1 + data2 * 0x80) - 8192;
+                    if(m_out != 0 && m_thruEnabled)
+                        m_out->sendPitchBend(channel, value);
+                    emit m_inp->midiPitchBend(channel, value);
+                }
+                break;
+            default:
+                qDebug() << "MIDI in status?" << status;
+            }
+        }
+
+        void emitSysex(QByteArray data)
+        {
+            if(m_out != 0 && m_thruEnabled)
+                m_out->sendSysex(data);
+            emit m_inp->midiSysex(data);
+        }
+
+        QString mmErrorString(MMRESULT err)
+        {
+            QString errstr;
+    #ifdef UNICODE
+            WCHAR buffer[1024];
+            midiInGetErrorText(err, &buffer[0], sizeof(buffer));
+            errstr = QString::fromUtf16((const ushort*)buffer);
+    #else
+            char buffer[1024];
+            midiOutGetErrorText(err, &buffer[0], sizeof(buffer));
+            errstr = QString::fromLocal8Bit(buffer);
+    #endif
+            return errstr;
+        }
+
+    };
+
+    void CALLBACK midiCallback( HMIDIIN hMidiIn,
+                                UINT wMsg,
+                                DWORD_PTR dwInstance,
+                                DWORD_PTR dwParam1,
+                                DWORD_PTR dwParam2 )
+    {
+        //Q_UNUSED(hMidiIn)
+        Q_UNUSED(dwParam2)
+        WinMIDIInput::WinMIDIInputPrivate* object = (WinMIDIInput::WinMIDIInputPrivate*) dwInstance;
+        switch( wMsg ) {
+        case MIM_OPEN:
+            qDebug() << "Open input" << hMidiIn;
+            break;
+        case MIM_CLOSE:
+            qDebug() << "Close input" << hMidiIn;
+            break;
+        case MIM_ERROR:
+        case MIM_LONGERROR:
+            qDebug() << "Errors input";
+            break;
+        case MIM_LONGDATA:
+            qDebug() << "Sysex data input";
+            break;
+        case MIM_DATA:
+        case MIM_MOREDATA: {
+                int status = dwParam1 & 0xf0;
+                int channel = dwParam1 & 0x0f;
+                int data1 = (dwParam1 & 0x7f00) >> 8;
+                int data2 = (dwParam1 & 0x7f0000) >> 16;
+                object->emitSignals(status, channel, data1, data2);
+            }
+            break;
+        default:
+            qDebug() << "unknown input message:" << hex << wMsg;
+            break;
+        }
+    }
+
+    WinMIDIInput::WinMIDIInput(QObject *parent) :
+        MIDIInput(parent), d(new WinMIDIInputPrivate(this))
+    { }
+
+    WinMIDIInput::~WinMIDIInput()
+    {
+        delete d;
+    }
+
+    void WinMIDIInput::initialize(QSettings *settings)
+    {
+        Q_UNUSED(settings)
+    }
+
+    QString WinMIDIInput::backendName()
+    {
+        return QLatin1Literal("Windows MM");
+    }
+
+    QString WinMIDIInput::publicName()
+    {
+        return d->m_publicName;
+    }
+
+    void WinMIDIInput::setPublicName(QString name)
+    {
+        d->setPublicName(name);
+    }
+
+    QStringList WinMIDIInput::connections(bool advanced)
+    {
+        d->reloadDeviceList(advanced);
+        return d->m_inputDevices.values();
+    }
+
+    void WinMIDIInput::setExcludedConnections(QStringList conns)
+    {
+        d->m_excludedNames = conns;
+    }
+
+    void WinMIDIInput::open(QString name)
+    {
+        d->open(name);
+    }
+
+    void WinMIDIInput::close()
+    {
+        d->close();
+    }
+
+    QString WinMIDIInput::currentConnection()
+    {
+        return d->m_currentInput;
+    }
+
+    void WinMIDIInput::setMIDIThruDevice(MIDIOutput *device)
+    {
+        d->m_out = device;
+    }
+
+    void WinMIDIInput::enableMIDIThru(bool enable)
+    {
+        d->m_thruEnabled = enable;
+    }
+
+    bool WinMIDIInput::isEnabledMIDIThru()
+    {
+        return d->m_thruEnabled && d->m_out != 0;
+    }
+
+}} // namespace drumstick::rt
diff --git a/library/rt-backends/win-in/winmidiinput.h b/library/rt-backends/win-in/winmidiinput.h
new file mode 100644
index 0000000..e15701e
--- /dev/null
+++ b/library/rt-backends/win-in/winmidiinput.h
@@ -0,0 +1,64 @@
+/*
+    Drumstick RT Windows Backend
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef WINMIDIINPUT_H
+#define WINMIDIINPUT_H
+
+#include <QObject>
+#include <QtPlugin>
+#include "rtmidiinput.h"
+
+namespace drumstick {
+namespace rt {
+
+    class WinMIDIInput : public MIDIInput
+    {
+        Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIInput")
+#endif
+        Q_INTERFACES(drumstick::rt::MIDIInput)
+
+    public:
+        class WinMIDIInputPrivate;
+
+        explicit WinMIDIInput(QObject *parent = 0);
+        virtual ~WinMIDIInput();
+
+        // MIDIInput interface
+    public:
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+        virtual void setMIDIThruDevice(MIDIOutput *device);
+        virtual void enableMIDIThru(bool enable);
+        virtual bool isEnabledMIDIThru();
+
+    private:
+        WinMIDIInputPrivate * const d;
+    };
+
+}}
+#endif // WINMIDIINPUT_H
diff --git a/library/rt-backends/win-out/CMakeLists.txt b/library/rt-backends/win-out/CMakeLists.txt
new file mode 100644
index 0000000..6406b7a
--- /dev/null
+++ b/library/rt-backends/win-out/CMakeLists.txt
@@ -0,0 +1,57 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(drumstick-rt-win-out_QTOBJ_SRCS
+    ../../include/rtmidioutput.h
+    winmidioutput.h
+)
+
+set(drumstick-rt-win-out_SRCS
+    winmidioutput.cpp
+)
+
+add_definitions(-DQT_PLUGIN)
+
+qt5_wrap_cpp(drumstick-rt-win-out_MOC_SRCS ${drumstick-rt-win-out_QTOBJ_SRCS})
+
+if(STATIC_DRUMSTICK)
+    add_definitions(-DQT_STATICPLUGIN)
+    add_library(drumstick-rt-win-out STATIC
+        ${drumstick-rt-win-out_MOC_SRCS}
+        ${drumstick-rt-win-out_SRCS})
+    set_target_properties(drumstick-rt-win-out PROPERTIES
+         STATIC_LIB "libdrumstick-rt-win-out")
+else()
+    add_library(drumstick-rt-win-out MODULE
+        ${drumstick-rt-win-out_MOC_SRCS}
+        ${drumstick-rt-win-out_SRCS})
+endif()
+
+target_link_libraries(drumstick-rt-win-out
+    Qt5::Core
+    winmm)
+
+set_target_properties(drumstick-rt-win-out PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib/drumstick)
+
+install(TARGETS drumstick-rt-win-out
+        RUNTIME DESTINATION bin
+        ARCHIVE DESTINATION lib${LIB_SUFFIX}/drumstick
+        LIBRARY DESTINATION lib${LIB_SUFFIX}/drumstick)
diff --git a/library/rt-backends/win-out/win-out.pro b/library/rt-backends/win-out/win-out.pro
new file mode 100644
index 0000000..4784074
--- /dev/null
+++ b/library/rt-backends/win-out/win-out.pro
@@ -0,0 +1,22 @@
+TEMPLATE = lib
+CONFIG += plugin #create_prl static
+TARGET = $$qtLibraryTarget(drumstick-rt-win-out)
+DESTDIR = ../../../build/lib/drumstick
+DEPENDPATH += . ../../include
+INCLUDEPATH += . ../../include
+include (../../../global.pri)
+DEPENDPATH += ../../include
+INCLUDEPATH += ../../include
+QT -= gui
+
+HEADERS += ../../include/rtmidiinput.h \
+           ../../include/rtmidioutput.h \
+           winmidioutput.h
+
+SOURCES += winmidioutput.cpp
+
+LIBS += -lwinmm
+
+win32 {
+    TARGET_EXT = .dll
+}
diff --git a/library/rt-backends/win-out/winmidioutput.cpp b/library/rt-backends/win-out/winmidioutput.cpp
new file mode 100644
index 0000000..ae63140
--- /dev/null
+++ b/library/rt-backends/win-out/winmidioutput.cpp
@@ -0,0 +1,364 @@
+/*
+    Drumstick RT Windows Backend
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QDebug>
+#include <QStringList>
+#include <QByteArray>
+#include <QVarLengthArray>
+#include <qmath.h>
+#include <windows.h>
+#include <mmsystem.h>
+#include "winmidioutput.h"
+
+namespace drumstick {
+namespace rt {
+
+    union WinMIDIPacket {
+        WinMIDIPacket() : dwPacket(0) {}
+        DWORD dwPacket;
+        quint8 data[sizeof(DWORD)];
+    };
+
+    static QLatin1Literal DEFAULT_PUBLIC_NAME = QLatin1Literal("MIDI Out");
+
+    void CALLBACK midiCallback( HMIDIOUT hmo,
+                                UINT wMsg,
+                                DWORD_PTR dwInstance,
+                                DWORD_PTR dwParam1,
+                                DWORD_PTR dwParam2);
+
+    class WinMIDIOutput::WinMIDIOutputPrivate {
+    public:
+        HMIDIOUT m_handle;
+        bool m_clientFilter;
+        QString m_publicName;
+        QString m_currentOutput;
+        QMap<int,QString> m_outputDevices;
+        MIDIHDR m_midiSysexHdr;
+        QByteArray m_sysexBuffer;
+        QStringList m_excludedNames;
+
+        WinMIDIOutputPrivate():
+            m_handle(0),
+            m_clientFilter(true),
+            m_publicName(DEFAULT_PUBLIC_NAME)
+        {
+            reloadDeviceList(true);
+        }
+
+        void reloadDeviceList(bool advanced)
+        {
+            MMRESULT res;
+            MIDIOUTCAPS deviceCaps;
+            QString devName;
+            unsigned int dev, max = midiOutGetNumDevs();
+            m_outputDevices.clear();
+            m_clientFilter = !advanced;
+
+            for ( dev = 0; dev < max; ++dev) {
+                res = midiOutGetDevCaps( dev, &deviceCaps, sizeof(MIDIOUTCAPS));
+                if (res != MMSYSERR_NOERROR)
+                    break;
+                if (m_clientFilter && (deviceCaps.wTechnology == MOD_MAPPER))
+                    continue;
+    #if defined(UNICODE)
+                devName = QString::fromWCharArray(deviceCaps.szPname);
+    #else
+                devName = QString::fromLocal8Bit(deviceCaps.szPname);
+    #endif
+                m_outputDevices[dev] = devName;
+            }
+            if (!m_clientFilter) {
+                dev = MIDI_MAPPER;
+                res = midiOutGetDevCaps( dev, &deviceCaps, sizeof(MIDIOUTCAPS));
+                if (res == MMSYSERR_NOERROR) {
+    #if defined(UNICODE)
+                    devName = QString::fromWCharArray(deviceCaps.szPname);
+    #else
+                    devName = QString::fromLocal8Bit(deviceCaps.szPname);
+    #endif
+                    m_outputDevices[dev] = devName;
+                }
+            }
+        }
+
+        void setPublicName(QString name)
+        {
+            if (m_publicName != name) {
+                m_publicName = name;
+            }
+        }
+
+        int deviceIndex( const QString& newOutputDevice )
+        {
+            int index = -1;
+            QMap<int,QString>::ConstIterator it;
+            for( it = m_outputDevices.constBegin();
+                 it != m_outputDevices.constEnd(); ++it ) {
+                if (it.value() == newOutputDevice) {
+                    index = it.key();
+                    break;
+                }
+            }
+            return index;
+        }
+
+        void open(QString name)
+        {
+            MMRESULT res;
+            int dev = -1;
+
+            if (m_handle != 0)
+                close();
+            reloadDeviceList(!m_clientFilter);
+            dev = deviceIndex(name);
+            if (dev > -1) {
+                res = midiOutOpen( &m_handle, dev, (DWORD_PTR) midiCallback, (DWORD_PTR) this, CALLBACK_FUNCTION);
+                if (res == MMSYSERR_NOERROR)
+                    m_currentOutput = name;
+                else
+                    qDebug() << "midiStreamOpen() err:" << mmErrorString(res);
+            }
+        }
+
+        void close()
+        {
+            MMRESULT res;
+            if (m_handle != 0) {
+                res = midiOutReset( m_handle );
+                if (res != MMSYSERR_NOERROR)
+                    qDebug() << "midiOutReset() err:" << mmErrorString(res);
+                res = midiOutClose( m_handle );
+                if (res == MMSYSERR_NOERROR)
+                    m_currentOutput.clear();
+                else
+                    qDebug() << "midiStreamClose() err:" << mmErrorString(res);
+                m_handle = 0;
+            }
+        }
+
+        void doneHeader( LPMIDIHDR lpMidiHdr )
+        {
+            MMRESULT res;
+            res = midiOutUnprepareHeader( m_handle, lpMidiHdr, sizeof(MIDIHDR) );
+            if (res != MMSYSERR_NOERROR)
+                qDebug() << "midiOutUnprepareHeader() err:" << mmErrorString(res);
+            if ((lpMidiHdr->dwFlags & MHDR_ISSTRM) == 0)
+                return; // sysex header?
+        }
+
+        void sendShortMessage(WinMIDIPacket &packet)
+        {
+            MMRESULT res;
+            res = midiOutShortMsg( m_handle, packet.dwPacket );
+            if ( res != MMSYSERR_NOERROR )
+                qDebug() << "midiOutShortMsg() err:" << mmErrorString(res);
+        }
+
+        void sendSysexEvent(const QByteArray& data)
+        {
+            MMRESULT res;
+            m_sysexBuffer = data;
+            m_midiSysexHdr.lpData = (LPSTR) m_sysexBuffer.data();
+            m_midiSysexHdr.dwBufferLength = m_sysexBuffer.size();
+            m_midiSysexHdr.dwBytesRecorded = m_sysexBuffer.size();
+            m_midiSysexHdr.dwFlags = 0;
+            m_midiSysexHdr.dwUser = 0;
+            res = midiOutPrepareHeader( m_handle, &m_midiSysexHdr, sizeof(MIDIHDR) );
+            if (res != MMSYSERR_NOERROR)
+                qDebug() << "midiOutPrepareHeader() err:" << mmErrorString(res);
+            else {
+                res = midiOutLongMsg( m_handle, &m_midiSysexHdr, sizeof(MIDIHDR) );
+                if (res != MMSYSERR_NOERROR)
+                    qDebug() << "midiOutLongMsg() err:" << mmErrorString(res);
+            }
+        }
+
+        QString mmErrorString(MMRESULT err)
+        {
+            QString errstr;
+    #ifdef UNICODE
+            WCHAR buffer[1024];
+            midiOutGetErrorText(err, &buffer[0], sizeof(buffer));
+            errstr = QString::fromUtf16((const ushort*)buffer);
+    #else
+            char buffer[1024];
+            midiOutGetErrorText(err, &buffer[0], sizeof(buffer));
+            errstr = QString::fromLocal8Bit(buffer);
+    #endif
+            return errstr;
+        }
+    };
+
+
+    void CALLBACK midiCallback( HMIDIOUT hmo,
+                                UINT wMsg,
+                                DWORD_PTR dwInstance,
+                                DWORD_PTR dwParam1,
+                                DWORD_PTR dwParam2)
+    {
+        //Q_UNUSED(hmo)
+        Q_UNUSED(dwParam2)
+
+        WinMIDIOutput::WinMIDIOutputPrivate* obj = (WinMIDIOutput::WinMIDIOutputPrivate*) dwInstance;
+        switch( wMsg ) {
+        case MOM_DONE:
+            obj->doneHeader( (LPMIDIHDR) dwParam1 );
+            break;
+        case MOM_OPEN:
+            qDebug() << "Open output" << hmo;
+            break;
+        case MOM_CLOSE:
+            qDebug() << "Close output" << hmo;
+            break;
+        default:
+            qDebug() << "unknown output message:" << hex << wMsg;
+            break;
+        }
+    }
+
+    WinMIDIOutput::WinMIDIOutput(QObject *parent) :
+        MIDIOutput(parent), d(new WinMIDIOutputPrivate)
+    { }
+
+    WinMIDIOutput::~WinMIDIOutput()
+    {
+        delete d;
+    }
+
+    void WinMIDIOutput::initialize(QSettings *settings)
+    {
+        Q_UNUSED(settings)
+    }
+
+    QString WinMIDIOutput::backendName()
+    {
+        return "Windows MM";
+    }
+
+    QString WinMIDIOutput::publicName()
+    {
+        return d->m_publicName;
+    }
+
+    void WinMIDIOutput::setPublicName(QString name)
+    {
+        d->setPublicName(name);
+    }
+
+    QStringList WinMIDIOutput::connections(bool advanced)
+    {
+        d->reloadDeviceList(advanced);
+        return d->m_outputDevices.values();
+    }
+
+    void WinMIDIOutput::setExcludedConnections(QStringList conns)
+    {
+        d->m_excludedNames = conns;
+    }
+
+    void WinMIDIOutput::open(QString name)
+    {
+        d->open(name);
+    }
+
+    void WinMIDIOutput::close()
+    {
+        d->close();
+    }
+
+    QString WinMIDIOutput::currentConnection()
+    {
+        return d->m_currentOutput;
+    }
+
+    void WinMIDIOutput::sendNoteOn(int chan, int note, int vel)
+    {
+        WinMIDIPacket packet;
+        packet.data[0] = MIDI_STATUS_NOTEON | (chan & MIDI_CHANNEL_MASK);
+        packet.data[1] = note;
+        packet.data[2] = vel;
+        d->sendShortMessage(packet);
+    }
+
+    void WinMIDIOutput::sendNoteOff(int chan, int note, int vel)
+    {
+        WinMIDIPacket packet;
+        packet.data[0] = MIDI_STATUS_NOTEOFF | (chan & MIDI_CHANNEL_MASK);
+        packet.data[1] = note;
+        packet.data[2] = vel;
+        d->sendShortMessage(packet);
+    }
+
+    void WinMIDIOutput::sendController(int chan, int control, int value)
+    {
+        WinMIDIPacket packet;
+        packet.data[0] = MIDI_STATUS_CONTROLCHANGE | (chan & MIDI_CHANNEL_MASK);
+        packet.data[1] = control;
+        packet.data[2] = value;
+        d->sendShortMessage(packet);
+    }
+
+    void WinMIDIOutput::sendKeyPressure(int chan, int note, int value)
+    {
+        WinMIDIPacket packet;
+        packet.data[0] = MIDI_STATUS_KEYPRESURE | (chan & MIDI_CHANNEL_MASK);
+        packet.data[1] = note;
+        packet.data[2] = value;
+        d->sendShortMessage(packet);
+    }
+
+    void WinMIDIOutput::sendProgram(int chan, int program)
+    {
+        WinMIDIPacket packet;
+        packet.data[0] = MIDI_STATUS_PROGRAMCHANGE | (chan & MIDI_CHANNEL_MASK);
+        packet.data[1] = program;
+        d->sendShortMessage(packet);
+    }
+
+    void WinMIDIOutput::sendChannelPressure(int chan, int value)
+    {
+        WinMIDIPacket packet;
+        packet.data[0] = MIDI_STATUS_CHANNELPRESSURE | (chan & MIDI_CHANNEL_MASK);
+        packet.data[1] = value;
+        d->sendShortMessage(packet);
+    }
+
+    void WinMIDIOutput::sendPitchBend(int chan, int value)
+    {
+        WinMIDIPacket packet;
+        packet.data[0] = MIDI_STATUS_PITCHBEND | (chan & MIDI_CHANNEL_MASK);
+        packet.data[1] = MIDI_LSB(value);
+        packet.data[2] = MIDI_MSB(value);
+        d->sendShortMessage(packet);
+    }
+
+    void WinMIDIOutput::sendSystemMsg(const int status)
+    {
+        WinMIDIPacket packet;
+        packet.data[0] = status;
+        d->sendShortMessage(packet);
+    }
+
+    void WinMIDIOutput::sendSysex(const QByteArray &data)
+    {
+        d->sendSysexEvent(data);
+    }
+
+}}
diff --git a/library/rt-backends/win-out/winmidioutput.h b/library/rt-backends/win-out/winmidioutput.h
new file mode 100644
index 0000000..86aaaa6
--- /dev/null
+++ b/library/rt-backends/win-out/winmidioutput.h
@@ -0,0 +1,73 @@
+/*
+    Drumstick RT Windows Backend
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef WINMIDIOUTPUT_H
+#define WINMIDIOUTPUT_H
+
+#include <QObject>
+#include <windows.h>
+#include <mmsystem.h>
+#include "rtmidioutput.h"
+
+namespace drumstick {
+namespace rt {
+
+    class WinMIDIOutput : public MIDIOutput
+    {
+        Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+        Q_PLUGIN_METADATA(IID "net.sourceforge.drumstick.rt.MIDIOutput")
+#endif
+        Q_INTERFACES(drumstick::rt::MIDIOutput)
+
+    public:
+        class WinMIDIOutputPrivate;
+
+        explicit WinMIDIOutput(QObject *parent = 0);
+        virtual ~WinMIDIOutput();
+
+        // MIDIOutput interface
+        virtual void initialize(QSettings* settings);
+        virtual QString backendName();
+        virtual QString publicName();
+        virtual void setPublicName(QString name);
+        virtual QStringList connections(bool advanced);
+        virtual void setExcludedConnections(QStringList conns);
+        virtual void open(QString name);
+        virtual void close();
+        virtual QString currentConnection();
+
+    public slots:
+        virtual void sendNoteOff(int chan, int note, int vel);
+        virtual void sendNoteOn(int chan, int note, int vel);
+        virtual void sendKeyPressure(int chan, int note, int value);
+        virtual void sendController(int chan, int control, int value);
+        virtual void sendProgram(int chan, int program);
+        virtual void sendChannelPressure(int chan, int value);
+        virtual void sendPitchBend(int chan, int value);
+        virtual void sendSysex(const QByteArray &data);
+        virtual void sendSystemMsg(const int status);
+
+    private:
+        WinMIDIOutputPrivate * const d;
+    };
+
+}}
+
+#endif // WINMIDIOUTPUT_H
diff --git a/library/rt/CMakeLists.txt b/library/rt/CMakeLists.txt
new file mode 100644
index 0000000..2117fa8
--- /dev/null
+++ b/library/rt/CMakeLists.txt
@@ -0,0 +1,117 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(drumstick-rt_QOBJ_SRCS
+    ../include/rtmidiinput.h
+    ../include/rtmidioutput.h
+)
+
+set(drumstick-rt_HEADERS
+	../include/macros.h
+    ../include/rtmidiinput.h
+    ../include/rtmidioutput.h
+    ../include/backendmanager.h
+)
+
+set(drumstick-rt_SRCS
+    backendmanager.cpp
+)
+    
+qt5_wrap_cpp(drumstick-rt_MOC_SRCS ${drumstick-rt_QOBJ_SRCS})
+
+add_library(drumstick-rt
+    ${drumstick-rt_MOC_SRCS}
+    ${drumstick-rt_SRCS}
+    ${drumstick-rt_HEADERS}
+)
+
+target_link_libraries(drumstick-rt Qt5::Core)
+
+if(STATIC_DRUMSTICK)
+    set_target_properties(drumstick-rt PROPERTIES
+        STATIC_LIB "libdrumstick-rt")
+    #
+    #    add_definitions(-DDUMMY_BACKEND)
+    #    target_link_libraries(drumstick-rt-dummy-in)
+    #    target_link_libraries(drumstick-rt-dummy-out)
+    #
+
+    if(ALSA_FOUND)
+        add_definitions(-DALSA_BACKEND)
+        target_link_libraries(drumstick-rt
+            drumstick-rt-alsa-in
+            drumstick-rt-alsa-out
+            drumstick-alsa)
+    endif()
+
+    if(UNIX AND NOT APPLE)
+        add_definitions(-DOSS_BACKEND)
+        target_link_libraries(drumstick-rt
+            drumstick-rt-oss-in
+            drumstick-rt-oss-out)
+    endif()
+
+
+    if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+        add_definitions(-DMAC_BACKEND)
+        target_link_libraries(drumstick-rt
+            drumstick-rt-mac-in
+            drumstick-rt-mac-out
+            "-framework CoreMidi -framework CoreFoundation")
+    endif()
+
+
+    if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+        add_definitions(-DWIN_BACKEND)
+        target_link_libraries(drumstick-rt
+            drumstick-rt-win-in
+            drumstick-rt-win-out
+            winmm)
+    endif()
+
+
+    find_package(Qt5Network)
+    if(Qt5Network_FOUND)
+        add_definitions(-DNET_BACKEND)
+        target_link_libraries(drumstick-rt
+            drumstick-rt-net-in
+            drumstick-rt-net-out)
+    endif()
+
+    pkg_check_modules(FLUIDSYNTH fluidsynth>=1.1.1)
+    if(FLUIDSYNTH_FOUND)
+        add_definitions(-DSYNTH_BACKEND)
+        target_link_libraries(drumstick-rt drumstick-rt-synth)
+    endif()
+
+else() # STATIC_DRUMSTICK
+
+    set_target_properties(drumstick-rt PROPERTIES
+        VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
+        SOVERSION ${VERSION_MAJOR})
+endif()
+
+install(TARGETS drumstick-rt
+	RUNTIME DESTINATION bin
+	ARCHIVE DESTINATION lib${LIB_SUFFIX}
+	LIBRARY DESTINATION lib${LIB_SUFFIX})
+
+install(FILES ${drumstick-rt_HEADERS}
+        DESTINATION include/drumstick)
diff --git a/library/rt/backendmanager.cpp b/library/rt/backendmanager.cpp
new file mode 100644
index 0000000..0c8505d
--- /dev/null
+++ b/library/rt/backendmanager.cpp
@@ -0,0 +1,239 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QtGlobal>
+#include <QDir>
+#include <QPluginLoader>
+#include <QCoreApplication>
+#include <QLibraryInfo>
+#include "backendmanager.h"
+
+#if defined(ALSA_BACKEND)
+Q_IMPORT_PLUGIN(ALSAMIDIInput)
+Q_IMPORT_PLUGIN(ALSAMIDIOutput)
+#endif
+
+#if defined(MAC_BACKEND)
+Q_IMPORT_PLUGIN(MacMIDIInput)
+Q_IMPORT_PLUGIN(MacMIDIOutput)
+#endif
+
+#if defined(WIN_BACKEND)
+Q_IMPORT_PLUGIN(WinMIDIInput)
+Q_IMPORT_PLUGIN(WinMIDIOutput)
+#endif
+
+#if defined(NET_BACKEND)
+Q_IMPORT_PLUGIN(NetMIDIInput)
+Q_IMPORT_PLUGIN(NetMIDIOutput)
+#endif
+
+#if defined(DUMMY_BACKEND)
+Q_IMPORT_PLUGIN(DummyInput)
+Q_IMPORT_PLUGIN(DummyOutput)
+#endif
+
+#if defined(SYNTH_BACKEND)
+Q_IMPORT_PLUGIN(SynthOutput)
+#endif
+
+#if defined(OSS_BACKEND)
+Q_IMPORT_PLUGIN(OSSInput)
+Q_IMPORT_PLUGIN(OSSOutput)
+#endif
+
+/**
+ * @file backendmanager.cpp
+ * Implementation of a class managing realtime MIDI input/output backends
+ */
+
+namespace drumstick {
+namespace rt {
+
+
+/**
+ * @addtogroup RT
+ * @{
+ *
+ * BackendManager provides a mechanism to find and enumerate backends (plugins)
+ * to manage realtime MIDI input/output
+ *
+ * This class and plugins are multiplatform. The backends implement one of these
+ * interfaces:
+ *
+ * MIDIInput: for plugins that can receive MIDI events
+ *
+ * MIDIOutput: for plugings that can produce MIDI events
+ *
+ * @}
+ */
+
+    class BackendManager::BackendManagerPrivate {
+    public:
+        QList<MIDIInput*> m_inputsList;
+        QList<MIDIOutput*> m_outputsList;
+        ~BackendManagerPrivate()
+        {
+            clearLists();
+        }
+        void clearLists()
+        {
+            m_inputsList.clear();
+            m_outputsList.clear();
+        }
+        void appendDir(const QString& candidate, QStringList& result)
+        {
+            //qDebug() << "testing " << candidate;
+            QDir checked(candidate);
+            if (checked.exists() && !result.contains(checked.absolutePath())) {
+                result << checked.absolutePath();
+            }
+        }
+    };
+
+    /**
+     * @brief Constructor
+     */
+    BackendManager::BackendManager(): d(new BackendManagerPrivate)
+    {
+        refresh();
+    }
+
+    /**
+     * @brief Destructor
+     */
+    BackendManager::~BackendManager()
+    {
+        delete d;
+    }
+
+    /**
+     * @brief returns the paths where backends are searched
+     * @return list of paths
+     */
+    QStringList BackendManager::defaultPaths()
+    {
+        QStringList result;
+        QString appPath = QCoreApplication::applicationDirPath() + QDir::separator();
+    #if defined(Q_OS_WIN)
+        d->appendDir( appPath + QSTR_DRUMSTICK, result );
+    #elif defined(Q_OS_MAC)
+        d->appendDir( appPath + QStringLiteral("../PlugIns/") + QSTR_DRUMSTICK, result );
+    #else // Linux, Unix...
+        QStringList libs;
+        libs << "../lib/" << "../lib32/" << "../lib64/";
+        foreach(const QString& lib, libs) {
+            d->appendDir( appPath + lib + QSTR_DRUMSTICK, result );
+        }
+    #endif
+        d->appendDir( appPath + ".." + QDir::separator() + QSTR_DRUMSTICK, result );
+        QByteArray envdir = qgetenv(QSTR_DRUMSTICKRT.toLatin1());
+        if(!envdir.isEmpty()) {
+            d->appendDir(QString(envdir), result );
+        }
+        d->appendDir( QDir::homePath() + QDir::separator() + QSTR_DRUMSTICK, result );
+        d->appendDir( QLibraryInfo::location(QLibraryInfo::PluginsPath) + QDir::separator() + QSTR_DRUMSTICK, result );
+        foreach(const QString& path, QCoreApplication::libraryPaths()) {
+            d->appendDir( path + QDir::separator() + QSTR_DRUMSTICK, result );
+        }
+        return result;
+    }
+
+    /**
+     * @brief BackendManager::refresh finds the installed backends searching the list of paths
+     * provided by the function defaultPaths() applying the optional settings as well.
+     * @param settings (optional)
+     */
+    void BackendManager::refresh(QSettings *settings)
+    {
+        QString name_in;
+        QString name_out;
+        QStringList names;
+        QStringList paths;
+
+        if (settings != 0) {
+            settings->beginGroup(QSTR_DRUMSTICKRT_GROUP);
+            d->appendDir(settings->value(QSTR_DRUMSTICKRT_PATH).toString(), paths);
+            name_in = settings->value(QSTR_DRUMSTICKRT_PUBLICNAMEIN).toString();
+            name_out = settings->value(QSTR_DRUMSTICKRT_PUBLICNAMEOUT).toString();
+            names << settings->value(QSTR_DRUMSTICKRT_EXCLUDED).toStringList();
+            names << name_in;
+            names << name_out;
+            settings->endGroup();
+        }
+        paths << defaultPaths();
+        d->clearLists();
+
+        // Dynamic backends
+        foreach(const QString& dir, paths) {
+            QDir pluginsDir(dir);
+            foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
+                if (QLibrary::isLibrary(fileName)) {
+                    QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
+                    QObject *obj = loader.instance();
+                    if (obj != 0) {
+                        MIDIInput *input = qobject_cast<MIDIInput*>(obj);
+                        if (input != 0 && !d->m_inputsList.contains(input)) {
+                            input->setPublicName(name_in);
+                            input->setExcludedConnections(names);
+                            d->m_inputsList << input;
+                        } else {
+                            MIDIOutput *output = qobject_cast<MIDIOutput*>(obj);
+                            if (output != 0 && !d->m_outputsList.contains(output)) {
+                                output->setPublicName(name_out);
+                                output->setExcludedConnections(names);
+                                d->m_outputsList << output;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // Static backends
+        foreach(QObject* obj, QPluginLoader::staticInstances()) {
+            if (obj != 0) {
+                MIDIInput *input = qobject_cast<MIDIInput*>(obj);
+                if (input != 0 && !d->m_inputsList.contains(input)) {
+                    input->setPublicName(name_in);
+                    input->setExcludedConnections(names);
+                    d->m_inputsList << input;
+                } else {
+                    MIDIOutput *output = qobject_cast<MIDIOutput*>(obj);
+                    if (output != 0 && !d->m_outputsList.contains(output)) {
+                        output->setPublicName(name_out);
+                        output->setExcludedConnections(names);
+                        d->m_outputsList << output;
+                    }
+                }
+            }
+        }
+    }
+
+    QList<MIDIInput*> BackendManager::availableInputs()
+    {
+        return d->m_inputsList;
+    }
+
+    QList<MIDIOutput*> BackendManager::availableOutputs()
+    {
+        return d->m_outputsList;
+    }
+
+}}
diff --git a/library/rt/rt.pro b/library/rt/rt.pro
new file mode 100644
index 0000000..9cc1c0c
--- /dev/null
+++ b/library/rt/rt.pro
@@ -0,0 +1,84 @@
+TEMPLATE = lib
+TARGET = $$qtLibraryTarget(drumstick-rt)
+DESTDIR = ../../build/lib
+DEPENDPATH += . ../include
+INCLUDEPATH += . ../include
+include (../../global.pri)
+CONFIG += qt #create_prl
+DEFINES += drumstick_rt_EXPORTS
+QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_HIDESYMS
+QT -= gui
+# Input
+HEADERS += \
+    ../include/rtmidiinput.h \
+    ../include/rtmidioutput.h \
+    ../include/backendmanager.h \
+    ../include/macros.h
+
+SOURCES += \
+    backendmanager.cpp
+
+win32 {
+    TARGET_EXT = .dll
+}
+
+macx {
+    TARGET = drumstick-rt
+    CONFIG += lib_bundle
+    FRAMEWORK_HEADERS.version = Versions
+    FRAMEWORK_HEADERS.files = $$HEADERS
+    FRAMEWORK_HEADERS.path = Headers/drumstick
+    QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS
+    #QMAKE_LFLAGS_SONAME = -Wl,-install_name, at executable_path/../Frameworks/
+    QMAKE_SONAME_PREFIX = @rpath
+}
+
+static {
+    LIBS += -L$$OUT_PWD/../../build/lib/drumstick
+    LIBS += -L$$OUT_PWD/../../build/lib
+
+    #dummy {
+    #    DEFINES += DUMMY_BACKEND
+    #    LIBS += -l$$qtLibraryTarget(drumstick-rt-dummy-in) \
+    #            -l$$qtLibraryTarget(drumstick-rt-dummy-out)
+    #}
+
+    linux* {
+        DEFINES += ALSA_BACKEND
+        LIBS += -l$$qtLibraryTarget(drumstick-rt-alsa-in) \
+                -l$$qtLibraryTarget(drumstick-rt-alsa-out) \
+                -l$$qtLibraryTarget(drumstick-alsa) \
+                -lasound
+    }
+
+    unix:!macx {
+        DEFINES += OSS_BACKEND
+        LIBS += -l$$qtLibraryTarget(drumstick-rt-oss-in) \
+                -l$$qtLibraryTarget(drumstick-rt-oss-out)
+    }
+
+    macx {
+        DEFINES += MAC_BACKEND
+        LIBS += -l$$qtLibraryTarget(drumstick-rt-mac-in) \
+                -l$$qtLibraryTarget(drumstick-rt-mac-out) \
+                -framework CoreMidi \
+                -framework CoreFoundation
+    }
+
+    win32 {
+        DEFINES += WIN_BACKEND
+        LIBS += -l$$qtLibraryTarget(drumstick-rt-win-in) \
+                -l$$qtLibraryTarget(drumstick-rt-win-out) \
+                -lwinmm
+    }
+
+    DEFINES += NET_BACKEND
+    QT += network
+    LIBS += -l$$qtLibraryTarget(drumstick-rt-net-in) \
+            -l$$qtLibraryTarget(drumstick-rt-net-out)
+
+    DEFINES += SYNTH_BACKEND
+    CONFIG += link_pkgconfig
+    LIBS += -l$$qtLibraryTarget(drumstick-rt-synth)
+    PKGCONFIG += fluidsynth
+}
diff --git a/link-drumstick b/link-drumstick
deleted file mode 100755
index 5b457d7..0000000
--- a/link-drumstick
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/bin/bash
-if [ ! -d ../drumstick ]; then
-    echo "Error: the directory ../drumstick doesn's exists. Checkout drumstick first."
-    exit
-fi
-if [ -d drumstick ]; then
-    echo "Error: the local directory drumstick already exists."
-    exit
-fi
-
-mkdir -p drumstick/include
-pushd drumstick/include
-for F in ../../../drumstick/library/include/*.h; do
-    ln -s $F .
-done
-popd
-
-mkdir -p drumstick/src
-pushd drumstick/src
-for F in ../../../drumstick/library/src/*.cpp; do
-    ln -s  $F .
-done
-popd
-
-pushd drumstick
-cat >CMakeLists.txt <<EOF
-INCLUDE_DIRECTORIES(
-    \${CMAKE_CURRENT_BINARY_DIR}
-    \${CMAKE_CURRENT_SOURCE_DIR}/include
-)
-
-ADD_DEFINITIONS(-DRTKIT_SUPPORT)
-
-# drumstick-file library
-
-SET(drumstick-file_QTOBJ_SRCS
-    include/qsmf.h
-    include/qwrk.h
-    include/qove.h
-)
-
-SET(drumstick-file_HEADERS
-    include/qsmf.h
-    include/qwrk.h
-    include/qove.h
-)
-
-SET(drumstick-file_SRCS
-    src/qsmf.cpp
-    src/qwrk.cpp
-    src/qove.cpp
-)
-
-QT4_WRAP_CPP(drumstick-file_MOC_SRCS \${drumstick-file_QTOBJ_SRCS})
-
-ADD_LIBRARY(drumstick-file
-    \${drumstick-file_MOC_SRCS}
-    \${drumstick-file_SRCS} 
-    \${drumstick-file_HEADERS} 
-)
-
-SET_TARGET_PROPERTIES(drumstick-file PROPERTIES COMPILE_FLAGS -fPIC)
-
-TARGET_LINK_LIBRARIES(drumstick-file
-    \${QT_LIBRARIES}
-)
-
-# drumstick-alsa library
-
-SET(drumstick-alsa_QTOBJ_SRCS
-    include/alsaclient.h
-    include/alsaevent.h
-    include/alsaport.h
-    include/alsaqueue.h
-    include/alsatimer.h
-    include/playthread.h
-)
-
-SET(drumstick-alsa_HEADERS
-    include/macros.h
-    include/alsaclient.h
-    include/alsaevent.h
-    include/alsaport.h
-    include/alsaqueue.h
-    include/alsatimer.h
-    include/drumstickcommon.h
-    include/playthread.h
-    include/subscription.h
-)
-
-SET(drumstick-alsa_SRCS
-    src/alsaclient.cpp
-    src/alsaevent.cpp
-    src/alsaport.cpp
-    src/alsaqueue.cpp
-    src/alsatimer.cpp
-    src/playthread.cpp
-    src/subscription.cpp
-)
-
-QT4_WRAP_CPP(drumstick-alsa_MOC_SRCS \${drumstick-alsa_QTOBJ_SRCS})
-
-ADD_LIBRARY(drumstick-alsa 
-    \${drumstick-alsa_MOC_SRCS}
-    \${drumstick-alsa_SRCS} 
-    \${drumstick-alsa_HEADERS} 
-)
-
-SET_TARGET_PROPERTIES(drumstick-alsa PROPERTIES COMPILE_FLAGS -fPIC)
-
-TARGET_LINK_LIBRARIES(drumstick-alsa
-    \${QT_LIBRARIES}
-    \${ALSA_LIBS}
-)
-EOF
-popd
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index 0d9c3da..0965987 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -1,5 +1,5 @@
 # MIDI Sequencer C++ Library
-# Copyright (C) 2005-2010 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,32 +16,28 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA 02110-1301, USA
 
-# common settings
-
-INCLUDE_DIRECTORIES ( 
+include_directories(
     ${CMAKE_CURRENT_SOURCE_DIR}
     ${CMAKE_CURRENT_BINARY_DIR}
     ${CMAKE_CURRENT_SOURCE_DIR}/common
     ${CMAKE_CURRENT_BINARY_DIR}/common
 )
 
-FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/common/cmdversion.h
-     "const QString PGM_VERSION(\"${VERSION}\");\n")
-
-ADD_SUBDIRECTORY(common)
-ADD_SUBDIRECTORY(buildsmf)
-ADD_SUBDIRECTORY(dumpsmf)
-ADD_SUBDIRECTORY(dumpwrk)
-ADD_SUBDIRECTORY(dumpove)
+add_subdirectory(common)
+add_subdirectory(buildsmf)
+add_subdirectory(dumpsmf)
+add_subdirectory(dumpwrk)
+add_subdirectory(dumpove)
+add_subdirectory(test-rt)
+add_subdirectory(vpiano)
 
-IF(ALSA_FOUND)
-    ADD_SUBDIRECTORY(dumpmid)
-    ADD_SUBDIRECTORY(playsmf)
-    ADD_SUBDIRECTORY(guiplayer)
-    ADD_SUBDIRECTORY(sysinfo)
-    ADD_SUBDIRECTORY(testevents)
-    ADD_SUBDIRECTORY(timertest)
-    ADD_SUBDIRECTORY(vpiano)
-    ADD_SUBDIRECTORY(metronome)
-    ADD_SUBDIRECTORY(drumgrid)
-ENDIF(ALSA_FOUND)
+if(ALSA_FOUND)
+    add_subdirectory(dumpmid)
+    add_subdirectory(playsmf)
+    add_subdirectory(guiplayer)
+    add_subdirectory(sysinfo)
+    add_subdirectory(testevents)
+    add_subdirectory(timertest)
+    add_subdirectory(metronome)
+    add_subdirectory(drumgrid)
+endif()
diff --git a/utils/buildsmf/CMakeLists.txt b/utils/buildsmf/CMakeLists.txt
index f4447a9..8d8b5cc 100644
--- a/utils/buildsmf/CMakeLists.txt
+++ b/utils/buildsmf/CMakeLists.txt
@@ -1,3 +1,21 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
 SET(buildsmf_SRCS
     buildsmf.cpp
     buildsmf.h
@@ -7,7 +25,7 @@ SET(buildsmf_qtobject_SRCS
     buildsmf.h
 )
 
-QT4_WRAP_CPP(buildsmf_moc_SRCS ${buildsmf_qtobject_SRCS})
+QT5_WRAP_CPP(buildsmf_moc_SRCS ${buildsmf_qtobject_SRCS})
 
 ADD_EXECUTABLE(drumstick-buildsmf 
     ${buildsmf_moc_SRCS}
@@ -15,9 +33,9 @@ ADD_EXECUTABLE(drumstick-buildsmf
 )
 
 TARGET_LINK_LIBRARIES(drumstick-buildsmf
-    ${QT_LIBRARIES} 
     drumstick-common
     drumstick-file
+    Qt5::Core
 )
 
 INSTALL(TARGETS drumstick-buildsmf 
diff --git a/utils/buildsmf/buildsmf.cpp b/utils/buildsmf/buildsmf.cpp
index b1df587..4fa2bf3 100644
--- a/utils/buildsmf/buildsmf.cpp
+++ b/utils/buildsmf/buildsmf.cpp
@@ -1,6 +1,6 @@
 /*
     Standard MIDI File creation from scratch.
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
  
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 #include "buildsmf.h"
 #include "qsmf.h"
 #include "cmdlineargs.h"
-#include <QApplication>
+#include <QCoreApplication>
 #include <QDebug>
 #include <QTextCodec>
 
@@ -46,16 +46,16 @@ void QSMFBuilder::trackHandler(int )
 
     // Text event
     m_engine->writeMetaEvent(0, copyright_notice, 
-        QString::fromUtf8("Copyright (C) 2006-2010 Pedro López-Cabanillas"));
+        QString::fromUtf8("Copyright (C) 2006-2015 Pedro López-Cabanillas"));
 
     m_engine->writeBpmTempo(0, 100);                
     m_engine->writeTimeSignature(0, 3, 2, 36, 8);  // ts = 3/4
     m_engine->writeKeySignature(0, 2, major_mode); // D major (2 sharps)
 
     // system exclusive event
-    static char gsreset[] = { 0xf0, 0x41, 0x10, 0x42, 0x12, 
-                              0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7 };
-    m_engine->writeMidiEvent(0, system_exclusive, sizeof(gsreset), gsreset);
+    static unsigned char gsreset[] = { 0xf0, 0x41, 0x10, 0x42, 0x12,
+                                       0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7 };
+    m_engine->writeMidiEvent(0, system_exclusive, sizeof(gsreset), (char *) &gsreset);
 
     // some note events
     static char notes[] = { 60, 62, 64, 65, 67, 69, 71, 72 };
diff --git a/utils/buildsmf/buildsmf.h b/utils/buildsmf/buildsmf.h
index 94cd5d1..5cb4f4d 100644
--- a/utils/buildsmf/buildsmf.h
+++ b/utils/buildsmf/buildsmf.h
@@ -1,6 +1,6 @@
 /*
     Standard MIDI File creation from scratch.
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
  
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/buildsmf/buildsmf.pro b/utils/buildsmf/buildsmf.pro
index 2a98f20..df1a532 100644
--- a/utils/buildsmf/buildsmf.pro
+++ b/utils/buildsmf/buildsmf.pro
@@ -1,11 +1,20 @@
 TEMPLATE = app
 TARGET = drumstick-buildsmf
-CONFIG += qt console thread exceptions
+CONFIG += qt console thread exceptions link_prl
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-INCLUDEPATH += . ../../library/include ../common ../../build/common
-LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-file
+INCLUDEPATH += . ../../library/include ../common 
+include(../../global.pri)
 # Input
 HEADERS += buildsmf.h
 SOURCES += buildsmf.cpp
+
+macx {
+    QMAKE_LFLAGS += -L$$OUT_PWD/../../build/lib/ -F$$OUT_PWD/../../build/lib/
+    LIBS += -framework drumstick-file
+    LIBS += -l$$qtLibraryTarget(drumstick-common)
+}
+else {
+    LIBS = -L$$OUT_PWD/../../build/lib \
+        -l$$qtLibraryTarget(drumstick-common) \
+        -l$$qtLibraryTarget(drumstick-file)
+}
diff --git a/utils/common/CMakeLists.txt b/utils/common/CMakeLists.txt
index 25b0b89..95d8de4 100644
--- a/utils/common/CMakeLists.txt
+++ b/utils/common/CMakeLists.txt
@@ -1,18 +1,28 @@
-SET ( common_SRCS
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+set( common_SRCS
     cmdlineargs.cpp
     cmdlineargs.h
+    cmdversion.h
 )
 
-ADD_LIBRARY( drumstick-common STATIC
-    ${common_SRCS}
-)
-
-IF(NOT WIN32)
-    SET_TARGET_PROPERTIES( drumstick-common 
-        PROPERTIES COMPILE_FLAGS -fPIC
-	)
-ENDIF(NOT WIN32)
+add_library( drumstick-common STATIC
+    ${common_SRCS})
 
-TARGET_LINK_LIBRARIES( drumstick-common
-    ${QT_LIBRARIES}
-)
+target_link_libraries(drumstick-common Qt5::Core)
diff --git a/utils/common/cmdlineargs.cpp b/utils/common/cmdlineargs.cpp
index 6477d4d..a511d76 100644
--- a/utils/common/cmdlineargs.cpp
+++ b/utils/common/cmdlineargs.cpp
@@ -1,6 +1,6 @@
 /*
     Command line arguments parser
-    Copyright (C) 2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2010-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -111,6 +111,7 @@ CmdLineArgs::CmdLineArgs() :
 CmdLineArgs::~CmdLineArgs()
 {
     clear();
+    delete d;
 }
 
 QStringList CmdLineArgs::getArgumentIds()
@@ -303,7 +304,7 @@ CmdLineArgs::helpText(const QString & id)
         }
     }
     if (d->m_stdQtArgs)
-        out += QLatin1String("This program also accepts Qt4 standard options\n");
+        out += QLatin1String("This program also accepts Qt standard options\n");
     return out;
 }
 
diff --git a/utils/common/cmdlineargs.h b/utils/common/cmdlineargs.h
index 012eba7..3607202 100644
--- a/utils/common/cmdlineargs.h
+++ b/utils/common/cmdlineargs.h
@@ -1,6 +1,6 @@
 /*
     Command line arguments parser
-    Copyright (C) 2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2010-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -99,4 +99,5 @@ private:
     Private *d;
 };
 
+
 #endif /* CMDLINEARGS_H */
diff --git a/utils/common/cmdversion.h b/utils/common/cmdversion.h
new file mode 100644
index 0000000..a3a46ee
--- /dev/null
+++ b/utils/common/cmdversion.h
@@ -0,0 +1,8 @@
+#ifndef CMDVERSION_H
+#define CMDVERSION_H
+
+#define LITERAL(s) #s
+#define STRINGIFY(s) LITERAL(s)
+const QString PGM_VERSION(STRINGIFY(VERSION));
+
+#endif // CMDVERSION_H
diff --git a/utils/common/common.pro b/utils/common/common.pro
index 837e83c..32e3899 100644
--- a/utils/common/common.pro
+++ b/utils/common/common.pro
@@ -1,12 +1,11 @@
-TEMPLATE = lib
-TARGET = drumstick-common
-DESTDIR = ../../build/lib
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-DEPENDPATH += . ../include ../src
-INCLUDEPATH += . ../include ../../build/common
-include (../global.pri)
-CONFIG += qt staticlib
-# Input
-HEADERS += cmdlineargs.h
-SOURCES += cmdlineargs.cpp
+TEMPLATE = lib
+TARGET = $$qtLibraryTarget(drumstick-common)
+DESTDIR = ../../build/lib
+DEPENDPATH += . ../include ../src
+INCLUDEPATH += . ../include 
+include (../../global.pri)
+CONFIG += qt staticlib create_prl
+# Input
+HEADERS += cmdlineargs.h \
+           cmdversion.h
+SOURCES += cmdlineargs.cpp
diff --git a/utils/drumgrid/CMakeLists.txt b/utils/drumgrid/CMakeLists.txt
index 122fcef..44ce05e 100644
--- a/utils/drumgrid/CMakeLists.txt
+++ b/utils/drumgrid/CMakeLists.txt
@@ -1,9 +1,29 @@
-SET(drumgrid_forms_SRCS
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+find_package(Qt5Widgets REQUIRED)
+
+set(drumgrid_forms_SRCS
     drumgridabout.ui
     drumgrid.ui
 )
 
-SET(drumgrid_SRCS
+set(drumgrid_SRCS
     drumgridabout.cpp
     drumgridabout.h
     drumgrid.cpp
@@ -13,15 +33,15 @@ SET(drumgrid_SRCS
     drumgridmain.cpp
 )
 
-SET(drumgrid_qtobject_SRCS
+set(drumgrid_qtobject_SRCS
     drumgridabout.h
     drumgridmodel.h
     drumgrid.h
 )
 
-QT4_WRAP_UI(drumgrid_ui_SRCS ${drumgrid_forms_SRCS})
+QT5_WRAP_UI(drumgrid_ui_SRCS ${drumgrid_forms_SRCS})
 
-QT4_WRAP_CPP(drumgrid_moc_SRCS ${drumgrid_qtobject_SRCS})
+QT5_WRAP_CPP(drumgrid_moc_SRCS ${drumgrid_qtobject_SRCS})
 
 ADD_EXECUTABLE(drumstick-drumgrid
     ${drumgrid_ui_SRCS}
@@ -30,10 +50,10 @@ ADD_EXECUTABLE(drumstick-drumgrid
 )
 
 TARGET_LINK_LIBRARIES(drumstick-drumgrid
-    ${QT_LIBRARIES} 
     ${ALSA_LIBS} 
     drumstick-common
     drumstick-alsa
+    Qt5::Widgets
 )
 
 INSTALL(TARGETS drumstick-drumgrid 
@@ -41,4 +61,4 @@ INSTALL(TARGETS drumstick-drumgrid
 
 INSTALL(FILES drumstick-drumgrid.desktop
         DESTINATION share/applications)
-        
\ No newline at end of file
+        
diff --git a/utils/drumgrid/drumgrid.cpp b/utils/drumgrid/drumgrid.cpp
index 6eeab01..e543c9c 100644
--- a/utils/drumgrid/drumgrid.cpp
+++ b/utils/drumgrid/drumgrid.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -22,11 +22,11 @@
 #include "ui_drumgrid.h"
 #include "drumgridabout.h"
 
-#include <QtGui/QInputDialog>
-#include <QtGui/QShortcut>
-#include <QtGui/QToolTip>
-#include <QtCore/QSignalMapper>
-#include <QtCore/QSettings>
+#include <QInputDialog>
+#include <QShortcut>
+#include <QToolTip>
+#include <QSignalMapper>
+#include <QSettings>
 #include <qmath.h>
 #include "alsaclient.h"
 #include "alsaport.h"
diff --git a/utils/drumgrid/drumgrid.h b/utils/drumgrid/drumgrid.h
index beb553c..38918d0 100644
--- a/utils/drumgrid/drumgrid.h
+++ b/utils/drumgrid/drumgrid.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -22,10 +22,10 @@
 
 #include "drumgridabout.h"
 
-#include <QtGui/QMainWindow>
-#include <QtGui/QShortcut>
-#include <QtGui/QCloseEvent>
-#include <QtCore/QSignalMapper>
+#include <QMainWindow>
+#include <QShortcut>
+#include <QCloseEvent>
+#include <QSignalMapper>
 
 const QString QSTR_WINDOW("Window");
 const QString QSTR_GEOMETRY("Geometry");
diff --git a/utils/drumgrid/drumgrid.pro b/utils/drumgrid/drumgrid.pro
index 6c13dc8..a1274b3 100644
--- a/utils/drumgrid/drumgrid.pro
+++ b/utils/drumgrid/drumgrid.pro
@@ -1,13 +1,12 @@
 TEMPLATE = app
 TARGET = drumstick-drumgrid
-QT += dbus
-CONFIG += qt thread exceptions
+QT += gui widgets dbus
+CONFIG += qt thread exceptions link_prl
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-UI_DIR = ../../build/ui
-INCLUDEPATH += . ../../library/include ../common ../../build/common
+INCLUDEPATH += . ../../library/include ../common 
 LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-alsa -lasound
+PRE_TARGETDEPS += $$OUT_PWD/../../build/lib/libdrumstick-common.a
+include (../../global.pri)
 SOURCES += drumgridabout.cpp \
     drumgridmain.cpp \
     drumgrid.cpp \
diff --git a/utils/drumgrid/drumgridabout.cpp b/utils/drumgrid/drumgridabout.cpp
index d4736ca..744668b 100644
--- a/utils/drumgrid/drumgridabout.cpp
+++ b/utils/drumgrid/drumgridabout.cpp
@@ -1,6 +1,6 @@
 /*
     Drumgrid test using the MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/drumgrid/drumgridabout.h b/utils/drumgrid/drumgridabout.h
index 542b94b..901762b 100644
--- a/utils/drumgrid/drumgridabout.h
+++ b/utils/drumgrid/drumgridabout.h
@@ -1,6 +1,6 @@
 /*
     Drumgrid test using the MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 #ifndef ABOUT_H
 #define ABOUT_H
 
-#include <QtGui/QDialog>
+#include <QDialog>
 #include "ui_drumgridabout.h"
 
 class About : public QDialog
diff --git a/utils/drumgrid/drumgridabout.ui b/utils/drumgrid/drumgridabout.ui
index efee9ef..aa14137 100644
--- a/utils/drumgrid/drumgridabout.ui
+++ b/utils/drumgrid/drumgridabout.ui
@@ -26,17 +26,17 @@
       <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 <html><head><meta name="qrichtext" content="1" /><style type="text/css">
 p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;">
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick Drum Grid %VERSION%</span></p>
-<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2010, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl at users.sf.net"><span style=" text-decoration: underline; color:#0057ae;">plcl at users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along  with this program; if not, write to the Free Software Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. </span></p></body></html></string>
+</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16pt; font-weight:600;">Drumstick Drum Grid %VERSION%</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Sample application for the <a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2006-2015, Pedro Lopez-Cabanillas &lt;<a href="mailto:plcl at users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl at users.sf.net</span></a>&gt;</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> </span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> </span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">You should have received a copy of the GNU General Public License along  with this program; if not, write to the Free Software Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. </span></p></body></html></string>
      </property>
      <property name="openExternalLinks">
       <bool>true</bool>
diff --git a/utils/drumgrid/drumgridmain.cpp b/utils/drumgrid/drumgridmain.cpp
index 0edc91d..3e0bbae 100644
--- a/utils/drumgrid/drumgridmain.cpp
+++ b/utils/drumgrid/drumgridmain.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,8 +20,8 @@
 #include "drumgrid.h"
 #include "cmdlineargs.h"
 #include "drumstickcommon.h"
-#include <QtGui/QApplication>
-#include <QtGui/QMessageBox>
+#include <QApplication>
+#include <QMessageBox>
 
 const QString QSTR_APPNAME("DrumGrid");
 const QString QSTR_DOMAIN("drumstick.sourceforge.net");
@@ -40,7 +40,7 @@ int main(int argc, char *argv[])
     CmdLineArgs args;
     args.setStdQtArgs(true);
     args.setUsage("[options]");
-    args.parse(a.argc(), a.argv());
+    args.parse(argc, argv);
     try {
         DrumGrid w;
         w.show();
diff --git a/utils/drumgrid/drumgridmodel.cpp b/utils/drumgrid/drumgridmodel.cpp
index 496c8be..5d4c730 100644
--- a/utils/drumgrid/drumgridmodel.cpp
+++ b/utils/drumgrid/drumgridmodel.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -18,7 +18,11 @@
 */
 
 #include "drumgridmodel.h"
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+#include <QtWidgets>
+#else
 #include <QtGui>
+#endif
 
 const QString DEFVAL("f");
 
diff --git a/utils/drumgrid/drumgridmodel.h b/utils/drumgrid/drumgridmodel.h
index b0067e4..f8995da 100644
--- a/utils/drumgrid/drumgridmodel.h
+++ b/utils/drumgrid/drumgridmodel.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/dumpmid/CMakeLists.txt b/utils/dumpmid/CMakeLists.txt
index 3a6c8a7..6827730 100644
--- a/utils/dumpmid/CMakeLists.txt
+++ b/utils/dumpmid/CMakeLists.txt
@@ -1,3 +1,21 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
 SET(dumpmid_SRCS
     dumpmid.cpp
     dumpmid.h
@@ -7,7 +25,7 @@ SET(dumpmid_qtobject_SRCS
     dumpmid.h
 )
 
-QT4_WRAP_CPP(dumpmid_moc_SRCS ${dumpmid_qtobject_SRCS})
+QT5_WRAP_CPP(dumpmid_moc_SRCS ${dumpmid_qtobject_SRCS})
 
 ADD_EXECUTABLE(drumstick-dumpmid
     ${dumpmid_moc_SRCS}
@@ -15,10 +33,10 @@ ADD_EXECUTABLE(drumstick-dumpmid
 )
 
 TARGET_LINK_LIBRARIES(drumstick-dumpmid
-    ${QT_LIBRARIES} 
     ${ALSA_LIBS} 
     drumstick-common
     drumstick-alsa
+    Qt5::Core
 )
 
 # we should install some files...
diff --git a/utils/dumpmid/dumpmid.cpp b/utils/dumpmid/dumpmid.cpp
index 1b68960..8c5b14e 100644
--- a/utils/dumpmid/dumpmid.cpp
+++ b/utils/dumpmid/dumpmid.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
 #include <signal.h>
 #include <QObject>
 #include <QString>
-#include <QApplication>
+#include <QCoreApplication>
 #include <QTextStream>
 #include <QtDebug>
 #include <QReadLocker>
diff --git a/utils/dumpmid/dumpmid.h b/utils/dumpmid/dumpmid.h
index 8314798..9bc482e 100644
--- a/utils/dumpmid/dumpmid.h
+++ b/utils/dumpmid/dumpmid.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/dumpmid/dumpmid.pro b/utils/dumpmid/dumpmid.pro
index 93442dc..b56eda0 100644
--- a/utils/dumpmid/dumpmid.pro
+++ b/utils/dumpmid/dumpmid.pro
@@ -1,13 +1,17 @@
 TEMPLATE = app
 TARGET = drumstick-dumpmid
 QT += dbus
-CONFIG += qt console thread exceptions
+CONFIG += qt console thread exceptions link_prl link_pkgconfig
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-INCLUDEPATH += . ../../library/include ../common ../../build/common
+INCLUDEPATH += . ../../library/include ../common 
 DEPENDPATH += . ../../library ../../library/include
-LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-alsa  -lasound
+include (../../global.pri)
 # Input
 HEADERS += dumpmid.h
 SOURCES += dumpmid.cpp
+
+LIBS = -L$$OUT_PWD/../../build/lib \
+    -l$$qtLibraryTarget(drumstick-common) \
+    -l$$qtLibraryTarget(drumstick-alsa)
+
+PKGCONFIG += alsa
diff --git a/utils/dumpove/CMakeLists.txt b/utils/dumpove/CMakeLists.txt
index 82f7561..8b1dadc 100644
--- a/utils/dumpove/CMakeLists.txt
+++ b/utils/dumpove/CMakeLists.txt
@@ -1,3 +1,21 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
 SET(dumpove_SRCS
     dumpove.cpp
     dumpove.h
@@ -7,7 +25,7 @@ SET(dumpove_qtobject_SRCS
     dumpove.h
 )
 
-QT4_WRAP_CPP(dumpove_moc_SRCS ${dumpove_qtobject_SRCS})
+QT5_WRAP_CPP(dumpove_moc_SRCS ${dumpove_qtobject_SRCS})
 
 ADD_EXECUTABLE(drumstick-dumpove 
     ${dumpove_moc_SRCS}
@@ -15,9 +33,9 @@ ADD_EXECUTABLE(drumstick-dumpove
 )
 
 TARGET_LINK_LIBRARIES(drumstick-dumpove
-    ${QT_LIBRARIES} 
     drumstick-common
     drumstick-file
+    Qt5::Core
 )
 
 # we should install some files...
diff --git a/utils/dumpove/dumpove.cpp b/utils/dumpove/dumpove.cpp
index 0990b97..6723e4b 100644
--- a/utils/dumpove/dumpove.cpp
+++ b/utils/dumpove/dumpove.cpp
@@ -1,6 +1,6 @@
 /*
     Overture OVE file dump program
-    Copyright (C) 2006-2010, Fan Rui <vanferry at gmail.com>
+    Copyright (C) 2006-2015, Fan Rui <vanferry at gmail.com>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -173,9 +173,10 @@ void QSpyOve::errorHandler(const QString& errorStr)
     cout << "*** Warning! " << errorStr << endl;
 }
 
-void QSpyOve::fileHeader(int verh, int verl)
+void QSpyOve::fileHeader(int res, int tracks)
 {
-    dumpStr(0, "OVE File Version", QString("%1.%2").arg(verh).arg(verl));
+    dumpStr(0, "OVE File Header",
+            QString("Resolution=%1 Tracks=%2").arg(res).arg(tracks));
 }
 
 void QSpyOve::fileEnd()
diff --git a/utils/dumpove/dumpove.h b/utils/dumpove/dumpove.h
index fd35c41..53a34b5 100644
--- a/utils/dumpove/dumpove.h
+++ b/utils/dumpove/dumpove.h
@@ -1,6 +1,6 @@
 /*
     Overture OVE file dump program
-    Copyright (C) 2006-2010, Fan Rui <vanferry at gmail.com>
+    Copyright (C) 2006-2015, Fan Rui <vanferry at gmail.com>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/dumpove/dumpove.pro b/utils/dumpove/dumpove.pro
index 9a13c31..e6424a8 100644
--- a/utils/dumpove/dumpove.pro
+++ b/utils/dumpove/dumpove.pro
@@ -1,11 +1,20 @@
 TEMPLATE = app
 TARGET = drumstick-dumpove
-CONFIG += qt console
+CONFIG += qt console link_prl
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-INCLUDEPATH += . ../../library/include ../common ../../build/common
-LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-file
+INCLUDEPATH += . ../../library/include ../common 
+include (../../global.pri)
 # Input
 HEADERS += dumpove.h
 SOURCES += dumpove.cpp
+
+macx {
+    QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib
+    LIBS += -framework drumstick-file
+    LIBS += -l$$qtLibraryTarget(drumstick-common)
+}
+else {
+    LIBS = -L$$OUT_PWD/../../build/lib \
+        -l$$qtLibraryTarget(drumstick-common) \
+        -l$$qtLibraryTarget(drumstick-file)
+}
diff --git a/utils/dumpsmf/CMakeLists.txt b/utils/dumpsmf/CMakeLists.txt
index 64c0bbd..6bd14fe 100644
--- a/utils/dumpsmf/CMakeLists.txt
+++ b/utils/dumpsmf/CMakeLists.txt
@@ -1,3 +1,21 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
 SET(dumpsmf_SRCS
     dumpsmf.cpp
     dumpsmf.h
@@ -7,7 +25,7 @@ SET(dumpsmf_qtobject_SRCS
     dumpsmf.h
 )
 
-QT4_WRAP_CPP(dumpsmf_moc_SRCS ${dumpsmf_qtobject_SRCS})
+QT5_WRAP_CPP(dumpsmf_moc_SRCS ${dumpsmf_qtobject_SRCS})
 
 ADD_EXECUTABLE(drumstick-dumpsmf 
     ${dumpsmf_moc_SRCS}
@@ -15,9 +33,9 @@ ADD_EXECUTABLE(drumstick-dumpsmf
 )
 
 TARGET_LINK_LIBRARIES(drumstick-dumpsmf
-    ${QT_LIBRARIES} 
     drumstick-common
     drumstick-file
+    Qt5::Core
 )
 
 # we should install some files...
diff --git a/utils/dumpsmf/dumpsmf.cpp b/utils/dumpsmf/dumpsmf.cpp
index f668989..e91abe2 100644
--- a/utils/dumpsmf/dumpsmf.cpp
+++ b/utils/dumpsmf/dumpsmf.cpp
@@ -1,6 +1,6 @@
 /*
     Standard MIDI File dump program
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     Based on midifile.c by Tim Thompson, M.Czeiszperger and Greg Lee
 
@@ -26,7 +26,7 @@
 #include <cstdlib>
 #include <QObject>
 #include <QString>
-#include <QApplication>
+#include <QCoreApplication>
 #include <QTextStream>
 #include <QTextCodec>
 
diff --git a/utils/dumpsmf/dumpsmf.h b/utils/dumpsmf/dumpsmf.h
index fadb9fe..e4b7356 100644
--- a/utils/dumpsmf/dumpsmf.h
+++ b/utils/dumpsmf/dumpsmf.h
@@ -1,6 +1,6 @@
 /*
     Standard MIDI File dump program
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     Based on midifile.c by Tim Thompson, M.Czeiszperger and Greg Lee
 
diff --git a/utils/dumpsmf/dumpsmf.pro b/utils/dumpsmf/dumpsmf.pro
index 2969a46..b7a7d3c 100644
--- a/utils/dumpsmf/dumpsmf.pro
+++ b/utils/dumpsmf/dumpsmf.pro
@@ -1,11 +1,20 @@
 TEMPLATE = app
 TARGET = drumstick-dumpsmf
-CONFIG += qt console
+CONFIG += qt console link_prl
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-INCLUDEPATH += . ../../library/include ../common ../../build/common
-LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-file
+INCLUDEPATH += . ../../library/include ../common 
+include (../../global.pri)
 # Input
 HEADERS += dumpsmf.h
 SOURCES += dumpsmf.cpp
+
+macx {
+    QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib
+    LIBS += -framework drumstick-file
+    LIBS += -l$$qtLibraryTarget(drumstick-common)
+}
+else {
+    LIBS = -L$$OUT_PWD/../../build/lib \
+        -l$$qtLibraryTarget(drumstick-common) \
+        -l$$qtLibraryTarget(drumstick-file)
+}
diff --git a/utils/dumpwrk/CMakeLists.txt b/utils/dumpwrk/CMakeLists.txt
index b24f871..f423008 100644
--- a/utils/dumpwrk/CMakeLists.txt
+++ b/utils/dumpwrk/CMakeLists.txt
@@ -1,3 +1,21 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
 SET(dumpwrk_SRCS
     dumpwrk.cpp
     dumpwrk.h
@@ -7,7 +25,7 @@ SET(dumpwrk_qtobject_SRCS
     dumpwrk.h
 )
 
-QT4_WRAP_CPP(dumpwrk_moc_SRCS ${dumpwrk_qtobject_SRCS})
+QT5_WRAP_CPP(dumpwrk_moc_SRCS ${dumpwrk_qtobject_SRCS})
 
 ADD_EXECUTABLE(drumstick-dumpwrk 
     ${dumpwrk_moc_SRCS}
@@ -15,9 +33,9 @@ ADD_EXECUTABLE(drumstick-dumpwrk
 )
 
 TARGET_LINK_LIBRARIES(drumstick-dumpwrk
-    ${QT_LIBRARIES} 
     drumstick-common
     drumstick-file
+    Qt5::Core
 )
 
 # we should install some files...
diff --git a/utils/dumpwrk/dumpwrk.cpp b/utils/dumpwrk/dumpwrk.cpp
index a86ef72..60cfbbd 100644
--- a/utils/dumpwrk/dumpwrk.cpp
+++ b/utils/dumpwrk/dumpwrk.cpp
@@ -1,6 +1,6 @@
 /*
     Cakewalk WRK file dump program
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     Based on midifile.c by Tim Thompson, M.Czeiszperger and Greg Lee
 
diff --git a/utils/dumpwrk/dumpwrk.h b/utils/dumpwrk/dumpwrk.h
index 896c212..e91b21b 100644
--- a/utils/dumpwrk/dumpwrk.h
+++ b/utils/dumpwrk/dumpwrk.h
@@ -1,6 +1,6 @@
 /*
     Cakewalk WRK file dump program
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     Based on midifile.c by Tim Thompson, M.Czeiszperger and Greg Lee
 
diff --git a/utils/dumpwrk/dumpwrk.pro b/utils/dumpwrk/dumpwrk.pro
index b8f1cf4..b5c5fa6 100644
--- a/utils/dumpwrk/dumpwrk.pro
+++ b/utils/dumpwrk/dumpwrk.pro
@@ -1,11 +1,20 @@
 TEMPLATE = app
 TARGET = drumstick-dumpwrk
-CONFIG += qt console
+CONFIG += qt console link_prl
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-INCLUDEPATH += . ../../library/include ../common ../../build/common
-LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-file
+INCLUDEPATH += . ../../library/include ../common 
+include (../../global.pri)
 # Input
 HEADERS += dumpwrk.h
 SOURCES += dumpwrk.cpp
+
+macx {
+    QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib
+    LIBS += -framework drumstick-file
+    LIBS += -l$$qtLibraryTarget(drumstick-common)
+}
+else {
+    LIBS = -L$$OUT_PWD/../../build/lib \
+        -l$$qtLibraryTarget(drumstick-common) \
+        -l$$qtLibraryTarget(drumstick-file)
+}
diff --git a/utils/guiplayer/CMakeLists.txt b/utils/guiplayer/CMakeLists.txt
index 4d41abf..79a8a6d 100644
--- a/utils/guiplayer/CMakeLists.txt
+++ b/utils/guiplayer/CMakeLists.txt
@@ -1,3 +1,23 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+find_package(Qt5Widgets REQUIRED)
+
 SET(guiplayer_forms_SRCS
     guiplayer.ui
     playerabout.ui
@@ -21,11 +41,11 @@ SET(guiplayer_qtobject_SRCS
     guiplayer.h
 )
 
-QT4_WRAP_UI(guiplayer_ui_SRCS ${guiplayer_forms_SRCS})
+QT5_WRAP_UI(guiplayer_ui_SRCS ${guiplayer_forms_SRCS})
 
-QT4_WRAP_CPP(guiplayer_moc_SRCS ${guiplayer_qtobject_SRCS})
+QT5_WRAP_CPP(guiplayer_moc_SRCS ${guiplayer_qtobject_SRCS})
 
-QT4_ADD_RESOURCES(guiplayer_resources guiplayer.qrc)
+QT5_ADD_RESOURCES(guiplayer_resources guiplayer.qrc)
 
 ADD_EXECUTABLE(drumstick-guiplayer
     ${guiplayer_resources}
@@ -35,11 +55,11 @@ ADD_EXECUTABLE(drumstick-guiplayer
 )
 
 TARGET_LINK_LIBRARIES(drumstick-guiplayer
-    ${QT_LIBRARIES} 
     ${ALSA_LIBS} 
     drumstick-common
     drumstick-file
     drumstick-alsa
+    Qt5::Widgets
 )
 
 INSTALL(TARGETS drumstick-guiplayer
diff --git a/utils/guiplayer/drumstick-guiplayer.desktop b/utils/guiplayer/drumstick-guiplayer.desktop
old mode 100755
new mode 100644
diff --git a/utils/guiplayer/guiplayer.cpp b/utils/guiplayer/guiplayer.cpp
index fcb2116..6557d6a 100644
--- a/utils/guiplayer/guiplayer.cpp
+++ b/utils/guiplayer/guiplayer.cpp
@@ -1,6 +1,6 @@
 /*
     SMF GUI Player test using the MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -31,19 +31,20 @@
 #include "alsaqueue.h"
 #include "alsaport.h"
 
-#include <QtGui/QApplication>
-#include <QtGui/QFileDialog>
-#include <QtGui/QInputDialog>
-#include <QtGui/QDragEnterEvent>
-#include <QtGui/QDropEvent>
-#include <QtGui/QCloseEvent>
-#include <QtGui/QToolTip>
-#include <QtGui/QMessageBox>
-#include <QtGui/QStatusBar>
-#include <QtCore/QSettings>
-#include <QtCore/QUrl>
-#include <QtCore/QFileInfo>
-#include <QtCore/QTextCodec>
+#include <QApplication>
+#include <QFileDialog>
+#include <QInputDialog>
+#include <QDragEnterEvent>
+#include <QDropEvent>
+#include <QCloseEvent>
+#include <QToolTip>
+#include <QMessageBox>
+#include <QStatusBar>
+#include <QSettings>
+#include <QUrl>
+#include <QFileInfo>
+#include <QTextCodec>
+#include <QMimeData>
 #include <qmath.h>
 
 GUIPlayer::GUIPlayer(QWidget *parent, Qt::WindowFlags flags)
diff --git a/utils/guiplayer/guiplayer.h b/utils/guiplayer/guiplayer.h
index 48948ae..845cc12 100644
--- a/utils/guiplayer/guiplayer.h
+++ b/utils/guiplayer/guiplayer.h
@@ -1,6 +1,6 @@
 /*
     SMF GUI Player test using the MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,13 +20,13 @@
 #ifndef INCLUDED_GUIPLAYER_H
 #define INCLUDED_GUIPLAYER_H
 
-#include <QtGui/QMainWindow>
-#include <QtGui/QProgressDialog>
-#include <QtCore/QObject>
-#include <QtCore/QString>
-#include <QtCore/QList>
-#include <QtCore/QHash>
-#include <QtCore/QPointer>
+#include <QMainWindow>
+#include <QProgressDialog>
+#include <QObject>
+#include <QString>
+#include <QList>
+#include <QHash>
+#include <QPointer>
 
 namespace drumstick {
     class QSmf;
diff --git a/utils/guiplayer/guiplayer.pro b/utils/guiplayer/guiplayer.pro
index 5db0352..11cce15 100644
--- a/utils/guiplayer/guiplayer.pro
+++ b/utils/guiplayer/guiplayer.pro
@@ -1,14 +1,12 @@
 TEMPLATE = app
 TARGET = drumstick-guiplayer
-QT += dbus
-CONFIG += qt thread exceptions
+QT += gui widgets dbus
+CONFIG += qt thread exceptions link_prl
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-RCC_DIR = ../../build/rcc
-UI_DIR = ../../build/ui
-INCLUDEPATH += . ../../library/include ../common ../../build/common
+INCLUDEPATH += . ../../library/include ../common 
 LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-file -ldrumstick-alsa -lasound
+PRE_TARGETDEPS += $$OUT_PWD/../../build/lib/libdrumstick-common.a
+include (../../global.pri)
 # Input
 HEADERS += player.h guiplayer.h song.h playerabout.h
 FORMS += guiplayer.ui playerabout.ui
diff --git a/utils/guiplayer/player.cpp b/utils/guiplayer/player.cpp
index f94219e..2cf67cc 100644
--- a/utils/guiplayer/player.cpp
+++ b/utils/guiplayer/player.cpp
@@ -1,6 +1,6 @@
 /*
     SMF GUI Player test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/guiplayer/player.h b/utils/guiplayer/player.h
index e339280..8878707 100644
--- a/utils/guiplayer/player.h
+++ b/utils/guiplayer/player.h
@@ -1,6 +1,6 @@
 /*
     SMF GUI Player test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/guiplayer/playerabout.cpp b/utils/guiplayer/playerabout.cpp
index af13ac1..acb77a4 100644
--- a/utils/guiplayer/playerabout.cpp
+++ b/utils/guiplayer/playerabout.cpp
@@ -1,6 +1,6 @@
 /*
     Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/guiplayer/playerabout.h b/utils/guiplayer/playerabout.h
index 8809446..9b96002 100644
--- a/utils/guiplayer/playerabout.h
+++ b/utils/guiplayer/playerabout.h
@@ -1,6 +1,6 @@
 /*
     Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 #ifndef ABOUT_H
 #define ABOUT_H
 
-#include <QtGui/QDialog>
+#include <QDialog>
 #include "ui_playerabout.h"
 
 class About : public QDialog
diff --git a/utils/guiplayer/playerabout.ui b/utils/guiplayer/playerabout.ui
index 1c3689b..ec9e578 100644
--- a/utils/guiplayer/playerabout.ui
+++ b/utils/guiplayer/playerabout.ui
@@ -30,17 +30,17 @@
       <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 <html><head><meta name="qrichtext" content="1" /><style type="text/css">
 p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;">
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick MIDI Player %VERSION%</span></p>
-<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2010, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl at users.sf.net"><span style=" text-decoration: underline; color:#0057ae;">plcl at users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along  with this program; if not, write to the Free Software Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. </span></p></body></html></string>
+</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16pt; font-weight:600;">Drumstick MIDI Player %VERSION%</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Sample application for the <a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2006-2015, Pedro Lopez-Cabanillas &lt;<a href="mailto:plcl at users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl at users.sf.net</span></a>&gt;</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> </span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> </span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">You should have received a copy of the GNU General Public License along  with this program; if not, write to the Free Software Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. </span></p></body></html></string>
      </property>
      <property name="openExternalLinks">
       <bool>true</bool>
diff --git a/utils/guiplayer/playermain.cpp b/utils/guiplayer/playermain.cpp
index 51e950c..d1bf38e 100644
--- a/utils/guiplayer/playermain.cpp
+++ b/utils/guiplayer/playermain.cpp
@@ -1,6 +1,6 @@
 /*
     SMF GUI Player test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,8 +20,8 @@
 #include "guiplayer.h"
 #include "cmdlineargs.h"
 #include "drumstickcommon.h"
-#include <QtGui/QApplication>
-#include <QtGui/QMessageBox>
+#include <QApplication>
+#include <QMessageBox>
 
 const QString errorstr = "Fatal error from the ALSA sequencer. "
     "This usually happens when the kernel doesn't have ALSA support, "
@@ -39,7 +39,7 @@ int main(int argc, char *argv[])
     args.setStdQtArgs(true);
     args.setUsage("[options] [file]");
     args.addOptionalArgument("file", "Input SMF (mid/kar) or Cakewalk (wrk) file");
-    args.parse(a.argc(), a.argv());
+    args.parse(argc, argv);
     try {
         GUIPlayer w;
         w.setAttribute(Qt::WA_QuitOnClose);
diff --git a/utils/guiplayer/song.cpp b/utils/guiplayer/song.cpp
index fd741e5..8a32713 100644
--- a/utils/guiplayer/song.cpp
+++ b/utils/guiplayer/song.cpp
@@ -1,6 +1,6 @@
 /*
     SMF GUI Player test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/guiplayer/song.h b/utils/guiplayer/song.h
index bfb9398..4189dee 100644
--- a/utils/guiplayer/song.h
+++ b/utils/guiplayer/song.h
@@ -1,6 +1,6 @@
 /*
     SMF GUI Player test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 #ifndef INCLUDED_SONG_H
 #define INCLUDED_SONG_H
 
-#include <QtCore/QStringList>
+#include <QStringList>
 
 namespace drumstick {
     class SequencerEvent;
diff --git a/utils/metronome/CMakeLists.txt b/utils/metronome/CMakeLists.txt
index 9492769..dd3bc30 100644
--- a/utils/metronome/CMakeLists.txt
+++ b/utils/metronome/CMakeLists.txt
@@ -1,3 +1,21 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
 SET(metronome_SRCS
     metronome.cpp
     metronome.h
@@ -7,7 +25,7 @@ SET(metronome_qtobject_SRCS
     metronome.h
 )
 
-QT4_WRAP_CPP(metronome_moc_SRCS ${metronome_qtobject_SRCS})
+QT5_WRAP_CPP(metronome_moc_SRCS ${metronome_qtobject_SRCS})
 
 ADD_EXECUTABLE(drumstick-metronome
     ${metronome_moc_SRCS}
@@ -15,10 +33,10 @@ ADD_EXECUTABLE(drumstick-metronome
 )
 
 TARGET_LINK_LIBRARIES(drumstick-metronome
-    ${QT_LIBRARIES} 
     ${ALSA_LIBS} 
     drumstick-common
     drumstick-alsa
+    Qt5::Core
 )
 
 # we should install some files...
diff --git a/utils/metronome/metronome.cpp b/utils/metronome/metronome.cpp
index de1783d..22ace16 100644
--- a/utils/metronome/metronome.cpp
+++ b/utils/metronome/metronome.cpp
@@ -1,6 +1,6 @@
 /*
     Standard MIDI simple metronome
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
 #include "cmdlineargs.h"
 
 #include <signal.h>
-#include <QApplication>
+#include <QCoreApplication>
 #include <QTextStream>
 #include <QtAlgorithms>
 #include <QStringList>
diff --git a/utils/metronome/metronome.h b/utils/metronome/metronome.h
index 3b52319..9ff89e5 100644
--- a/utils/metronome/metronome.h
+++ b/utils/metronome/metronome.h
@@ -1,6 +1,6 @@
 /*
     Standard MIDI simple metronome
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
  
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/metronome/metronome.pro b/utils/metronome/metronome.pro
index ff36068..fa33b22 100644
--- a/utils/metronome/metronome.pro
+++ b/utils/metronome/metronome.pro
@@ -1,12 +1,12 @@
 TEMPLATE = app
 TARGET = drumstick-metronome
 QT += dbus
-CONFIG += qt console thread exceptions
+CONFIG += qt console thread exceptions link_prl
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-INCLUDEPATH += . ../../library/include ../common ../../build/common
+INCLUDEPATH += . ../../library/include ../common 
 LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-alsa -lasound
+PRE_TARGETDEPS += $$OUT_PWD/../../build/lib/libdrumstick-common.a
+include (../../global.pri)
 # Input
 HEADERS += metronome.h
 SOURCES += metronome.cpp
diff --git a/utils/playsmf/CMakeLists.txt b/utils/playsmf/CMakeLists.txt
index d2e8c6b..b60b8dc 100644
--- a/utils/playsmf/CMakeLists.txt
+++ b/utils/playsmf/CMakeLists.txt
@@ -1,3 +1,21 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
 SET(playsmf_SRCS
     playsmf.cpp
     playsmf.h
@@ -7,7 +25,7 @@ SET(playsmf_qtobject_SRCS
     playsmf.h
 )
 
-QT4_WRAP_CPP(playsmf_moc_SRCS ${playsmf_qtobject_SRCS})
+QT5_WRAP_CPP(playsmf_moc_SRCS ${playsmf_qtobject_SRCS})
 
 ADD_EXECUTABLE(drumstick-playsmf
     ${playsmf_moc_SRCS}
@@ -15,11 +33,11 @@ ADD_EXECUTABLE(drumstick-playsmf
 )
 
 TARGET_LINK_LIBRARIES(drumstick-playsmf
-    ${QT_LIBRARIES} 
     ${ALSA_LIBS} 
     drumstick-common
     drumstick-alsa
     drumstick-file
+    Qt5::Core
 )
 
 # we should install some files...
diff --git a/utils/playsmf/playsmf.cpp b/utils/playsmf/playsmf.cpp
index b4cdde5..c6292c1 100644
--- a/utils/playsmf/playsmf.cpp
+++ b/utils/playsmf/playsmf.cpp
@@ -1,6 +1,6 @@
 /*
     Standard MIDI File player program
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 #include "cmdlineargs.h"
 
 #include <signal.h>
-#include <QApplication>
+#include <QCoreApplication>
 #include <QTextStream>
 #include <QtAlgorithms>
 #include <QFileInfo>
diff --git a/utils/playsmf/playsmf.h b/utils/playsmf/playsmf.h
index 4abc7b4..5c3b66f 100644
--- a/utils/playsmf/playsmf.h
+++ b/utils/playsmf/playsmf.h
@@ -1,6 +1,6 @@
 /*
     Standard MIDI File player program 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
  
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/playsmf/playsmf.pro b/utils/playsmf/playsmf.pro
index 44f3c93..6db6a1e 100644
--- a/utils/playsmf/playsmf.pro
+++ b/utils/playsmf/playsmf.pro
@@ -1,12 +1,12 @@
 TEMPLATE = app
 TARGET = drumstick-playsmf
 QT += dbus
-CONFIG += qt console thread exceptions
+CONFIG += qt console thread exceptions link_prl
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-INCLUDEPATH += . ../../library/include ../common ../../build/common
+INCLUDEPATH += . ../../library/include ../common 
 LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-alsa -ldrumstick-file -lasound
+PRE_TARGETDEPS += $$OUT_PWD/../../build/lib/libdrumstick-common.a
+include (../../global.pri)
 # Input
 HEADERS += playsmf.h
 SOURCES += playsmf.cpp
diff --git a/utils/stableheaders.h b/utils/stableheaders.h
index b41bd19..5326287 100644
--- a/utils/stableheaders.h
+++ b/utils/stableheaders.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ Library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
  
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/sysinfo/CMakeLists.txt b/utils/sysinfo/CMakeLists.txt
index 37db03e..32b86ec 100644
--- a/utils/sysinfo/CMakeLists.txt
+++ b/utils/sysinfo/CMakeLists.txt
@@ -1,3 +1,21 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
 SET(sysinfo_SRCS
     sysinfo.cpp
 )
@@ -7,10 +25,10 @@ ADD_EXECUTABLE(drumstick-sysinfo
 )
 
 TARGET_LINK_LIBRARIES(drumstick-sysinfo
-    ${QT_LIBRARIES} 
     ${ALSA_LIBS} 
     drumstick-common
     drumstick-alsa
+    Qt5::Core
 )
 
 INSTALL(TARGETS drumstick-sysinfo 
diff --git a/utils/sysinfo/sysinfo.cpp b/utils/sysinfo/sysinfo.cpp
index b149c1b..13e4763 100644
--- a/utils/sysinfo/sysinfo.cpp
+++ b/utils/sysinfo/sysinfo.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/sysinfo/sysinfo.pro b/utils/sysinfo/sysinfo.pro
index cf9b756..7adef5b 100644
--- a/utils/sysinfo/sysinfo.pro
+++ b/utils/sysinfo/sysinfo.pro
@@ -1,12 +1,12 @@
 TEMPLATE = app
 TARGET = drumstick-sysinfo
 QT += dbus
-CONFIG += qt console thread exceptions
+CONFIG += qt console thread exceptions link_prl
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-INCLUDEPATH += . ../../library/include ../common ../../build/common
+INCLUDEPATH += . ../../library/include ../common 
 DEPENDPATH += . ../../library ../../library/include
 LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-alsa -lasound
+PRE_TARGETDEPS += $$OUT_PWD/../../build/lib/libdrumstick-common.a
+include (../../global.pri)
 # Input
 SOURCES += sysinfo.cpp
diff --git a/utils/test-rt/CMakeLists.txt b/utils/test-rt/CMakeLists.txt
new file mode 100644
index 0000000..c5b276e
--- /dev/null
+++ b/utils/test-rt/CMakeLists.txt
@@ -0,0 +1,41 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+if(STATIC_DRUMSTICK)
+  find_package(Qt5Network REQUIRED)
+  pkg_check_modules(FLUIDSYNTH REQUIRED fluidsynth>=1.1.1)
+  link_directories(${FLUIDSYNTH_LIBDIR})
+endif()
+
+set(SRCS
+    main.cpp
+)
+
+add_executable(drumstick-test-rt
+    ${SRCS}
+)
+
+target_link_libraries(drumstick-test-rt
+    drumstick-common
+    drumstick-rt
+    Qt5::Core
+)
+
+#not an utility, don't install
+#install(TARGETS drumstick-test-rt
+#        RUNTIME DESTINATION bin)
diff --git a/utils/test-rt/main.cpp b/utils/test-rt/main.cpp
new file mode 100644
index 0000000..6fcfe66
--- /dev/null
+++ b/utils/test-rt/main.cpp
@@ -0,0 +1,91 @@
+/*
+    Drumstick RT (realtime MIDI In/Out)
+    Copyright (C) 2009-2015 Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <cstdlib>
+#include <QCoreApplication>
+#include <QFileInfo>
+#include <QtPlugin>
+#include <QPluginLoader>
+#include <QString>
+#include <QStringList>
+#include <QTextStream>
+#include <QDir>
+
+#include "rtmidiinput.h"
+#include "rtmidioutput.h"
+#include "backendmanager.h"
+#include "cmdlineargs.h"
+
+using namespace drumstick::rt;
+
+QTextStream cout(stdout, QIODevice::WriteOnly);
+
+int main(int argc, char **argv)
+{
+    QCoreApplication::setOrganizationName("drumstick.sourceforge.net");
+    QCoreApplication::setOrganizationDomain("drumstick.sourceforge.net");
+    QCoreApplication::setApplicationName("drumstick-rt-test");
+    QCoreApplication app(argc, argv);
+    CmdLineArgs args;
+    args.setStdQtArgs(true);
+    args.parse(argc, argv);
+
+    QFileInfo exeInfo(app.applicationFilePath());
+    cout << "program=" << exeInfo.fileName();
+
+    QSettings settings;
+    settings.beginGroup(QSTR_DRUMSTICKRT_GROUP);
+    settings.setValue(QSTR_DRUMSTICKRT_PUBLICNAMEIN, QLatin1String("TEST MIDI IN"));
+    settings.setValue(QSTR_DRUMSTICKRT_PUBLICNAMEOUT, QLatin1String("TEST MIDI OUT"));
+    settings.endGroup();
+    settings.sync();
+
+    QList<MIDIInput*> inputsList;
+    QList<MIDIOutput*> outputsList;
+
+    BackendManager man;
+    man.refresh(&settings);
+    inputsList = man.availableInputs();
+    outputsList = man.availableOutputs();
+
+    foreach(MIDIInput* input, inputsList) {
+        cout << "Input Backend " << input->backendName() << endl;
+        cout << "public name " << input->publicName() << endl;
+        foreach(const QString& c, input->connections()) {
+            cout << "port " << c << endl;
+        }
+        foreach(const QString& c, input->connections(true)) {
+            cout << "advanced port " << c << endl;
+        }
+    }
+
+    foreach(MIDIOutput* output, outputsList) {
+        cout << "Output Backend " << output->backendName() << endl;
+        cout << "public name " << output->publicName() << endl;
+        foreach(const QString& c, output->connections()) {
+            cout << "port " << c << endl;
+        }
+        foreach(const QString& c, output->connections(true)) {
+            cout << "advanced port " << c << endl;
+        }
+    }
+
+    cout.flush();
+    return 0;
+}
diff --git a/utils/test-rt/test-rt.pro b/utils/test-rt/test-rt.pro
new file mode 100644
index 0000000..dd9bfdc
--- /dev/null
+++ b/utils/test-rt/test-rt.pro
@@ -0,0 +1,69 @@
+TEMPLATE = app
+TARGET = drumstick-rt-test
+CONFIG += qt console link_prl
+DESTDIR = ../../build/bin
+DEPENDPATH  += . ../../library/include
+INCLUDEPATH += . ../../library/include ../common
+
+SOURCES += main.cpp
+
+macx {
+    QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib
+    LIBS += -framework drumstick-rt
+    LIBS += -l$$qtLibraryTarget(drumstick-common)
+}
+else {
+    LIBS += -L$$OUT_PWD/../../build/lib \
+            -l$$qtLibraryTarget(drumstick-common) \
+            -l$$qtLibraryTarget(drumstick-rt)
+}
+
+static {
+
+LIBS += -L$$OUT_PWD/../../build/lib/drumstick
+
+#dummy {
+#    DEFINES += DUMMY_BACKEND
+#    LIBS += -l$$qtLibraryTarget(drumstick-rt-dummy-in) \
+#            -l$$qtLibraryTarget(drumstick-rt-dummy-out)
+#}
+
+linux* {
+    DEFINES += ALSA_BACKEND
+    LIBS += -l$$qtLibraryTarget(drumstick-rt-alsa-in) \
+            -l$$qtLibraryTarget(drumstick-rt-alsa-out) \
+            -l$$qtLibraryTarget(drumstick-alsa) \
+            -lasound
+}
+
+unix:!macx {
+    DEFINES += OSS_BACKEND
+    LIBS += -l$$qtLibraryTarget(drumstick-rt-oss-in) \
+            -l$$qtLibraryTarget(drumstick-rt-oss-out)
+}
+
+macx {
+    DEFINES += MAC_BACKEND
+    LIBS += -l$$qtLibraryTarget(drumstick-rt-mac-in) \
+            -l$$qtLibraryTarget(drumstick-rt-mac-out) \
+            -framework CoreMidi \
+            -framework CoreFoundation
+}
+
+win32 {
+    DEFINES += WIN_BACKEND
+    LIBS += -l$$qtLibraryTarget(drumstick-rt-win-in) \
+            -l$$qtLibraryTarget(drumstick-rt-win-out) \
+            -lwinmm
+}
+
+DEFINES += NET_BACKEND
+QT += network
+LIBS += -l$$qtLibraryTarget(drumstick-rt-net-in) \
+        -l$$qtLibraryTarget(drumstick-rt-net-out)
+
+DEFINES += SYNTH_BACKEND
+CONFIG += link_pkgconfig
+LIBS += -l$$qtLibraryTarget(drumstick-rt-synth)
+PKGCONFIG += fluidsynth
+}
diff --git a/utils/test-rt/test-rt.pro.user b/utils/test-rt/test-rt.pro.user
new file mode 100644
index 0000000..9777655
--- /dev/null
+++ b/utils/test-rt/test-rt.pro.user
@@ -0,0 +1,460 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 3.1.2, 2014-10-13T19:53:01. -->
+<qtcreator>
+ <data>
+  <variable>ProjectExplorer.Project.ActiveTarget</variable>
+  <value type="int">0</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.EditorSettings</variable>
+  <valuemap type="QVariantMap">
+   <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+   <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+   <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+    <value type="QString" key="language">Cpp</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+    </valuemap>
+   </valuemap>
+   <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+    <value type="QString" key="language">QmlJS</value>
+    <valuemap type="QVariantMap" key="value">
+     <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+    </valuemap>
+   </valuemap>
+   <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
+   <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+   <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+   <value type="int" key="EditorConfiguration.IndentSize">4</value>
+   <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+   <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+   <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+   <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+   <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+   <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+   <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+   <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+   <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+   <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+   <value type="int" key="EditorConfiguration.TabSize">8</value>
+   <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+   <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+   <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+   <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+   <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+   <value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.PluginSettings</variable>
+  <valuemap type="QVariantMap"/>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Target.0</variable>
+  <valuemap type="QVariantMap">
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.1.1 GCC 64bit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.1.1 GCC 64bit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.511.gcc_64.essentials_kit</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/pedro/Projects/drumstick/utils/build-test-rt-Desktop_Qt_5_1_1_GCC_64bit-Debug</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/pedro/Projects/drumstick/utils/build-test-rt-Desktop_Qt_5_1_1_GCC_64bit-Release</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">test-rt</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/pedro/Projects/drumstick/utils/test-rt/test-rt.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">test-rt.pro</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Target.1</variable>
+  <valuemap type="QVariantMap">
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.3 GCC 64bit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.3 GCC 64bit</value>
+   <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.53.gcc_64_kit</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+   <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/pedro/Projects/drumstick/utils/build-test-rt-Desktop_Qt_5_3_GCC_64bit-Debug</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+   </valuemap>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+    <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/pedro/Projects/drumstick/utils/build-test-rt-Desktop_Qt_5_3_GCC_64bit-Release</value>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
+      <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+      <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+     </valuemap>
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+    </valuemap>
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+     <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+      <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+      <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+      <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+       <value type="QString">-w</value>
+       <value type="QString">-r</value>
+      </valuelist>
+      <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+      <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+     </valuemap>
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+    <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+    <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+    <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+    <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+     <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+     <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+    </valuemap>
+    <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+   <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+    <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+    <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+    <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+    <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+    <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+    <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+    <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+    <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+    <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+    <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+    <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+     <value type="int">0</value>
+     <value type="int">1</value>
+     <value type="int">2</value>
+     <value type="int">3</value>
+     <value type="int">4</value>
+     <value type="int">5</value>
+     <value type="int">6</value>
+     <value type="int">7</value>
+     <value type="int">8</value>
+     <value type="int">9</value>
+     <value type="int">10</value>
+     <value type="int">11</value>
+     <value type="int">12</value>
+     <value type="int">13</value>
+     <value type="int">14</value>
+    </valuelist>
+    <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+    <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">test-rt</value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+    <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/pedro/Projects/drumstick/utils/test-rt/test-rt.pro</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">test-rt.pro</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
+    <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value>
+    <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+    <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+    <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+    <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+    <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+   </valuemap>
+   <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+  </valuemap>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.TargetCount</variable>
+  <value type="int">2</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
+  <value type="QByteArray">{209b2b12-da0f-42fc-865f-69f54ba8b64b}</value>
+ </data>
+ <data>
+  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+  <value type="int">15</value>
+ </data>
+</qtcreator>
diff --git a/utils/testevents/CMakeLists.txt b/utils/testevents/CMakeLists.txt
index f053124..80bb499 100644
--- a/utils/testevents/CMakeLists.txt
+++ b/utils/testevents/CMakeLists.txt
@@ -1,3 +1,21 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
 SET(testevents_SRCS
     testevents.cpp
     testevents.h
@@ -7,7 +25,7 @@ SET(testevents_qtobject_SRCS
     testevents.h
 )
 
-QT4_WRAP_CPP(testevents_moc_SRCS ${testevents_qtobject_SRCS})
+QT5_WRAP_CPP(testevents_moc_SRCS ${testevents_qtobject_SRCS})
 
 ADD_EXECUTABLE(drumstick-testevents
     ${testevents_moc_SRCS}
@@ -15,12 +33,12 @@ ADD_EXECUTABLE(drumstick-testevents
 )
 
 TARGET_LINK_LIBRARIES(drumstick-testevents
-    ${QT_LIBRARIES} 
     ${ALSA_LIBS} 
     drumstick-common
     drumstick-alsa
+    Qt5::Core
 )
 
-# we should install some files...
-INSTALL(TARGETS drumstick-testevents
-        RUNTIME DESTINATION bin)
+# not an utility
+#INSTALL(TARGETS drumstick-testevents
+#        RUNTIME DESTINATION bin)
diff --git a/utils/testevents/testevents.cpp b/utils/testevents/testevents.cpp
index b859e06..b980211 100644
--- a/utils/testevents/testevents.cpp
+++ b/utils/testevents/testevents.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 #include "cmdlineargs.h"
 #include <QObject>
 #include <QString>
-#include <QApplication>
+#include <QCoreApplication>
 #include <QTextStream>
 
 static QTextStream cout(stdout, QIODevice::WriteOnly);
diff --git a/utils/testevents/testevents.h b/utils/testevents/testevents.h
index a9e4a77..f440186 100644
--- a/utils/testevents/testevents.h
+++ b/utils/testevents/testevents.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/testevents/testevents.pro b/utils/testevents/testevents.pro
index d2f9a83..593b795 100644
--- a/utils/testevents/testevents.pro
+++ b/utils/testevents/testevents.pro
@@ -1,12 +1,12 @@
 TEMPLATE = app
 TARGET = drumstick-testevents
 QT += dbus
-CONFIG += qt console thread exceptions
+CONFIG += qt console thread exceptions link_prl
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-INCLUDEPATH += . ../../library/include ../common ../../build/common
+INCLUDEPATH += . ../../library/include ../common 
 LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-alsa -lasound
+PRE_TARGETDEPS += $$OUT_PWD/../../build/lib/libdrumstick-common.a
+include (../../global.pri)
 # Input
 HEADERS += testevents.h
 SOURCES += testevents.cpp
diff --git a/utils/timertest/CMakeLists.txt b/utils/timertest/CMakeLists.txt
index 95a5071..e7df309 100644
--- a/utils/timertest/CMakeLists.txt
+++ b/utils/timertest/CMakeLists.txt
@@ -1,3 +1,21 @@
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
 SET(timertest_SRCS
     timertest.cpp
     timertest.h
@@ -7,7 +25,7 @@ SET(timertest_qtobject_SRCS
     timertest.h
 )
 
-QT4_WRAP_CPP(timertest_moc_SRCS ${timertest_qtobject_SRCS})
+QT5_WRAP_CPP(timertest_moc_SRCS ${timertest_qtobject_SRCS})
 
 ADD_EXECUTABLE(drumstick-timertest
     ${timertest_SRCS}
@@ -15,12 +33,12 @@ ADD_EXECUTABLE(drumstick-timertest
 )
 
 TARGET_LINK_LIBRARIES(drumstick-timertest
-    ${QT_LIBRARIES} 
     ${ALSA_LIBS} 
     drumstick-common
     drumstick-alsa
+    Qt5::Core
 )
 
-# we should install some files...
-INSTALL(TARGETS drumstick-timertest 
-        RUNTIME DESTINATION bin)
+# not an utility
+#INSTALL(TARGETS drumstick-timertest
+#        RUNTIME DESTINATION bin)
diff --git a/utils/timertest/timertest.cpp b/utils/timertest/timertest.cpp
index 79986ad..a3f0bce 100644
--- a/utils/timertest/timertest.cpp
+++ b/utils/timertest/timertest.cpp
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/timertest/timertest.h b/utils/timertest/timertest.h
index 13a15e3..669c40c 100644
--- a/utils/timertest/timertest.h
+++ b/utils/timertest/timertest.h
@@ -1,6 +1,6 @@
 /*
     MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/timertest/timertest.pro b/utils/timertest/timertest.pro
index 08173ca..f8db632 100644
--- a/utils/timertest/timertest.pro
+++ b/utils/timertest/timertest.pro
@@ -1,13 +1,13 @@
 TEMPLATE = app
 TARGET = drumstick-timertest
 QT += dbus
-CONFIG += qt console thread exceptions
+CONFIG += qt console thread exceptions link_prl
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-INCLUDEPATH += . ../../library/include ../common ../../build/common
+INCLUDEPATH += . ../../library/include ../common 
 DEPENDPATH += . ../../library ../../library/include
 LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-alsa -lasound
+PRE_TARGETDEPS += $$OUT_PWD/../../build/lib/libdrumstick-common.a
+include (../../global.pri)
 # Input
 HEADERS = timertest.h
 SOURCES = timertest.cpp
diff --git a/utils/utils.pro b/utils/utils.pro
index 4efb07e..6d675c4 100644
--- a/utils/utils.pro
+++ b/utils/utils.pro
@@ -1,30 +1,24 @@
-DESTDIR = ../build/common
 TEMPLATE = subdirs
+CONFIG += ordered
 include (../global.pri)
-VERSIONH = $$sprintf(const QString PGM_VERSION(\"%1\");,$$VERSION)
-system($$QMAKE_MKDIR $$DESTDIR)
-win32 { 
-    system(echo $$VERSIONH > ../build/common/cmdversion.h)
-    SUBDIRS += common \ 
+DEFINES += VERSION=$$VERSION
+QMAKE_LFLAGS += -F../build/lib
+SUBDIRS += common \
            buildsmf \
            dumpove \
            dumpsmf \
-           dumpwrk
-}
-linux* { 
-    system(echo \'$$VERSIONH\' > ../build/common/cmdversion.h)
-    SUBDIRS += common \ 
-           buildsmf \
+           dumpwrk \
+           test-rt \
+           vpiano
+
+linux* {
+    SUBDIRS += \
            drumgrid \
            dumpmid \
-           dumpove \
-           dumpsmf \
-           dumpwrk \
            guiplayer \
            metronome \
            playsmf \
            sysinfo \
            testevents \
            timertest \
-           vpiano
 }
diff --git a/utils/vpiano/CMakeLists.txt b/utils/vpiano/CMakeLists.txt
index ff99efd..d4e5bcb 100644
--- a/utils/vpiano/CMakeLists.txt
+++ b/utils/vpiano/CMakeLists.txt
@@ -1,13 +1,42 @@
-SET(vpiano_forms_SRCS
+# MIDI Sequencer C++ Library
+# Copyright (C) 2005-2015 Pedro Lopez-Cabanillas <plcl at users.sourceforge.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA
+
+find_package(Qt5Widgets REQUIRED)
+find_package(Qt5Svg REQUIRED)
+find_package(Qt5Network REQUIRED)
+
+if(STATIC_DRUMSTICK)
+  pkg_check_modules(FLUIDSYNTH REQUIRED fluidsynth>=1.1.1)
+  link_directories(${FLUIDSYNTH_LIBDIR})
+endif()
+
+set(vpiano_forms_SRCS
+    networksettingsdialog.ui
+    fluidsettingsdialog.ui
     vpianoabout.ui
     connections.ui
     preferences.ui
     vpiano.ui
 )
 
-QT4_WRAP_UI(vpiano_ui_SRCS ${vpiano_forms_SRCS})
+qt5_wrap_ui(vpiano_ui_SRCS ${vpiano_forms_SRCS})
 
-SET(vpiano_SRCS
+set(vpiano_SRCS
     pianokey.cpp
     pianokey.h
     pianoscene.cpp
@@ -16,11 +45,8 @@ SET(vpiano_SRCS
     pianokeybd.h
     keylabel.cpp
     keylabel.h
-    rawkeybdapp.cpp
-    rawkeybdapp.h
     vpianoabout.cpp
     vpianoabout.h
-    connectionitem.h
     connections.cpp
     connections.h
     preferences.cpp
@@ -28,37 +54,43 @@ SET(vpiano_SRCS
     vpiano.cpp
     vpiano.h
     vpianomain.cpp
+    networksettingsdialog.cpp
+    fluidsettingsdialog.cpp
 )
 
-SET(vpiano_qtobject_SRCS
+set(vpiano_qtobject_SRCS
+#    ../../library/include/rtmidiinput.h
+#    ../../library/include/rtmidioutput.h
     pianoscene.h
     pianokeybd.h
     vpianoabout.h
     connections.h
     preferences.h
     vpiano.h
+    networksettingsdialog.h
+    fluidsettingsdialog.h
 )
 
-QT4_WRAP_CPP(vpiano_moc_SRCS ${vpiano_qtobject_SRCS})
+qt5_wrap_cpp(vpiano_moc_SRCS ${vpiano_qtobject_SRCS})
 
-QT4_ADD_RESOURCES(vpiano_SRCS pianokeybd.qrc)
+qt5_add_resources(vpiano_SRCS pianokeybd.qrc)
 
-ADD_EXECUTABLE(drumstick-vpiano
+add_executable(drumstick-vpiano
     ${vpiano_ui_SRCS}
     ${vpiano_moc_SRCS}
     ${vpiano_SRCS}
 )
 
-TARGET_LINK_LIBRARIES(drumstick-vpiano
-    ${QT_LIBRARIES} 
-    ${ALSA_LIBS} 
-    ${QT_X11_X11_LIBRARY}
+target_link_libraries(drumstick-vpiano
     drumstick-common
-    drumstick-alsa
+    drumstick-rt
+    Qt5::Widgets
+    Qt5::Svg
+    Qt5::Network
 )
 
-INSTALL(TARGETS drumstick-vpiano
+install(TARGETS drumstick-vpiano
         RUNTIME DESTINATION bin)
 
-INSTALL(FILES drumstick-vpiano.desktop
+install(FILES drumstick-vpiano.desktop
         DESTINATION share/applications)
diff --git a/utils/vpiano/connectionitem.h b/utils/vpiano/connectionitem.h
deleted file mode 100644
index 4ca8618..0000000
--- a/utils/vpiano/connectionitem.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef CONNECTIONITEM_H_
-#define CONNECTIONITEM_H_
-
-#include <QListWidgetItem>
-#include "alsaport.h"
-
-const int ConnectionItemType(QListWidgetItem::UserType + 1);
-
-using namespace drumstick;
-
-class ConnectionItem : public QListWidgetItem
-{
-public:
-	ConnectionItem( QListWidget *parent = 0 ) : 
-	    QListWidgetItem( parent, ConnectionItemType ) {}
-	ConnectionItem( const QString & text, QListWidget * parent = 0 ) :
-	    QListWidgetItem ( text, parent,  ConnectionItemType ) {}
-	virtual ~ConnectionItem() {}
-
-	void setPortInfo(PortInfo subs) { m_portInfo = subs; }
-	PortInfo getPortInfo() const { return m_portInfo; }
-
-private:
-    PortInfo m_portInfo;
-};
-
-#endif /*CONNECTIONITEM_H_*/
diff --git a/utils/vpiano/connections.cpp b/utils/vpiano/connections.cpp
index f9d09ff..cc532ae 100644
--- a/utils/vpiano/connections.cpp
+++ b/utils/vpiano/connections.cpp
@@ -1,6 +1,6 @@
 /*
     Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -18,73 +18,177 @@
 */
 
 #include "connections.h"
-#include "connectionitem.h"
+#include "networksettingsdialog.h"
+#include "fluidsettingsdialog.h"
 
 Connections::Connections(QWidget *parent)
-    : QDialog(parent)
+    : QDialog(parent),
+      m_advanced(false),
+      m_thru(false),
+      m_settingsChanged(false),
+      m_midiIn(0),
+      m_midiOut(0)
 {
     ui.setupUi(this);
+    connect(ui.m_advanced, SIGNAL(clicked(bool)), SLOT(clickedAdvanced(bool)));
+    connect(ui.m_inputBackends, SIGNAL(currentIndexChanged(QString)), SLOT(refreshInputs(QString)));
+    connect(ui.m_outputBackends, SIGNAL(currentIndexChanged(QString)), SLOT(refreshOutputs(QString)));
+    connect(ui.btnInputDriverCfg, &QToolButton::clicked, this, &Connections::configureInputDriver);
+    connect(ui.btnOutputDriverCfg, &QToolButton::clicked, this, &Connections::configureOutputDriver);
+    ui.m_advanced->setChecked(m_advanced);
+    ui.m_thru->setChecked(m_thru);
 }
 
-ConnectionItem* Connections::createConnectionItem(PortInfo& pi, PortInfoList& subs)
+void Connections::setInputs(QList<MIDIInput *> ins)
 {
-    ConnectionItem *itm = new ConnectionItem(QString("%1:%2").
-                                             arg(pi.getClientName()).
-                                             arg(pi.getPort()));
-    itm->setCheckState(Qt::Unchecked);
-    itm->setPortInfo(pi);
-    PortInfoList::ConstIterator it;
-    for( it = subs.constBegin(); it != subs.constEnd(); ++it ) {
-        PortInfo s = *it;
-        if ((s.getClient() == pi.getClient()) &&
-            (s.getPort() == pi.getPort())) {
-            itm->setCheckState(Qt::Checked);
-            break;
-        }
+    ui.m_inputBackends->disconnect();
+    ui.m_inputBackends->clear();
+    foreach(MIDIInput *i, ins) {
+        ui.m_inputBackends->addItem(i->backendName(), qVariantFromValue((void *) i));
+    }
+    connect(ui.m_inputBackends, SIGNAL(currentIndexChanged(QString)), SLOT(refreshInputs(QString)));
+}
+
+void Connections::setOutputs(QList<MIDIOutput *> outs)
+{
+    ui.m_outputBackends->disconnect();
+    foreach(MIDIOutput *o, outs) {
+        ui.m_outputBackends->addItem(o->backendName(), qVariantFromValue((void *) o));
     }
-    return itm;
+    connect(ui.m_outputBackends, SIGNAL(currentIndexChanged(QString)), SLOT(refreshOutputs(QString)));
 }
 
-void Connections::setInputs(PortInfoList inputs, PortInfoList subs)
+void Connections::accept()
 {
-    ui.m_listInputs->clear();
-    PortInfoList::Iterator it;
-    for( it = inputs.begin(); it != inputs.end(); ++it) {
-        ui.m_listInputs->addItem(createConnectionItem(*it, subs));
+    QString conn;
+    QSettings settings;
+    m_advanced = ui.m_advanced->isChecked();
+    m_thru = ui.m_thru->isChecked();
+    if (m_midiOut != 0) {
+        conn = ui.m_outputPorts->currentText();
+        if (conn != m_midiOut->currentConnection() || m_settingsChanged) {
+            m_midiOut->close();
+            if (!conn.isEmpty()) {
+                m_midiOut->initialize(&settings);
+                m_midiOut->open(conn);
+            }
+        }
+    }
+    if (m_midiIn != 0) {
+        conn = ui.m_inputPorts->currentText();
+        if (conn != m_midiIn->currentConnection() || m_settingsChanged) {
+            m_midiIn->close();
+            if (!conn.isEmpty()) {
+                m_midiIn->initialize(&settings);
+                m_midiIn->open(conn);
+            }
+        }
+        if (m_midiOut != 0) {
+            m_midiIn->setMIDIThruDevice(m_midiOut);
+            m_midiIn->enableMIDIThru(m_thru);
+        }
     }
+    m_settingsChanged = false;
+    QDialog::accept();
 }
 
-void Connections::setOutputs(PortInfoList outputs, PortInfoList subs)
+void Connections::refresh()
 {
-    ui.m_listOutputs->clear();
-    PortInfoList::Iterator it;
-    for( it = outputs.begin(); it != outputs.end(); ++it) {
-        ui.m_listOutputs->addItem(createConnectionItem(*it, subs));
+    m_advanced = ui.m_advanced->isChecked();
+    if (m_midiIn != 0) {
+        ui.m_inputBackends->setCurrentText(m_midiIn->backendName());
+        refreshInputs(m_midiIn->backendName());
+    }
+    if (m_midiOut != 0) {
+        ui.m_outputBackends->setCurrentText(m_midiOut->backendName());
+        refreshOutputs(m_midiOut->backendName());
     }
 }
 
-PortInfoList Connections::getSelectedInputPorts() const
+void Connections::refreshInputs(QString id)
 {
-    PortInfoList lst;
-    int row;
-    for ( row = 0; row < ui.m_listInputs->count(); ++row ) {
-        ConnectionItem *itm = dynamic_cast<ConnectionItem*>(ui.m_listInputs->item(row));
-        if ((itm != NULL) && (itm->checkState() == Qt::Checked)) {
-            lst << itm->getPortInfo();
+    ui.btnInputDriverCfg->setEnabled(id == "Network");
+    if (m_midiIn != 0 && m_midiIn->backendName() != id) {
+        m_midiIn->close();
+        int idx = ui.m_inputBackends->findText(id, Qt::MatchStartsWith);
+        if (idx > -1) {
+            m_midiIn = (MIDIInput *) ui.m_inputBackends->itemData(idx).value<void *>();
+        } else {
+            m_midiIn = 0;
         }
     }
-    return lst;
+    ui.m_inputPorts->clear();
+    if (m_midiIn != 0) {
+        ui.m_inputPorts->addItem(QString());
+        ui.m_inputPorts->addItems(m_midiIn->connections(m_advanced));
+        ui.m_inputPorts->setCurrentText(m_midiIn->currentConnection());
+    }
 }
 
-PortInfoList Connections::getSelectedOutputPorts() const
+void Connections::refreshOutputs(QString id)
 {
-    PortInfoList lst;
-    int row;
-    for ( row = 0; row < ui.m_listOutputs->count(); ++row ) {
-        ConnectionItem *itm = dynamic_cast<ConnectionItem*>(ui.m_listOutputs->item(row));
-        if ((itm != NULL) && (itm->checkState() == Qt::Checked)) {
-            lst << itm->getPortInfo();
+    ui.btnOutputDriverCfg->setEnabled(id == "Network" || id == "FluidSynth");
+    if (m_midiOut != 0 && m_midiOut->backendName() != id) {
+        m_midiOut->close();
+        int idx = ui.m_outputBackends->findText(id, Qt::MatchStartsWith);
+        if (idx > -1) {
+            m_midiOut = (MIDIOutput *) ui.m_outputBackends->itemData(idx).value<void *>();
+        } else {
+            m_midiOut = 0;
         }
     }
-    return lst;
+    ui.m_outputPorts->clear();
+    if (m_midiOut != 0) {
+        ui.m_outputPorts->addItems(m_midiOut->connections(m_advanced));
+        ui.m_outputPorts->setCurrentText(m_midiOut->currentConnection());
+    }
+}
+
+void Connections::setAdvanced(bool value)
+{
+    ui.m_advanced->setChecked(value);
+    refresh();
+}
+
+void Connections::clickedAdvanced(bool value)
+{
+    m_advanced = value;
+    refresh();
+}
+
+void Connections::setMidiThru(bool value)
+{
+    m_thru = value;
+    ui.m_thru->setChecked(value);
+}
+
+bool Connections::advanced()
+{
+    return ui.m_advanced->isChecked();
+}
+
+bool Connections::midiThru()
+{
+    return ui.m_thru->isChecked();
+}
+
+void Connections::configureInputDriver()
+{
+    QString driver = ui.m_inputBackends->currentText();
+    if (driver == "Network") {
+        NetworkSettingsDialog dlg(this);
+        m_settingsChanged |= (dlg.exec() == QDialog::Accepted);
+    }
+}
+
+void Connections::configureOutputDriver()
+{
+    QString driver = ui.m_outputBackends->currentText();
+    if (driver == "Network") {
+        NetworkSettingsDialog dlg(this);
+        m_settingsChanged |= (dlg.exec() == QDialog::Accepted);
+    } else if (driver == "FluidSynth") {
+        FluidSettingsDialog dlg(this);
+        m_settingsChanged |= (dlg.exec() == QDialog::Accepted);
+    }
 }
diff --git a/utils/vpiano/connections.h b/utils/vpiano/connections.h
index 2b56ef7..2c599aa 100644
--- a/utils/vpiano/connections.h
+++ b/utils/vpiano/connections.h
@@ -1,6 +1,6 @@
 /*
     Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,12 +20,14 @@
 #ifndef CONNECTIONS_H
 #define CONNECTIONS_H
 
+#include <QObject>
 #include <QDialog>
-#include "alsaport.h"
+#include <QShowEvent>
+#include "rtmidiinput.h"
+#include "rtmidioutput.h"
 #include "ui_connections.h"
-#include "connectionitem.h"
 
-using namespace drumstick;
+using namespace drumstick::rt;
 
 class Connections : public QDialog
 {
@@ -33,13 +35,32 @@ class Connections : public QDialog
 
 public:
     Connections(QWidget *parent = 0);
-    void setInputs(PortInfoList inputs, PortInfoList subs);
-    void setOutputs(PortInfoList outputs, PortInfoList subs);
-    PortInfoList getSelectedInputPorts() const;
-    PortInfoList getSelectedOutputPorts() const;
+    void setInput(MIDIInput *in) { m_midiIn = in; }
+    void setOutput(MIDIOutput *out) { m_midiOut = out; }
+    void setInputs(QList<MIDIInput *> ins);
+    void setOutputs(QList<MIDIOutput *> outs);
+    MIDIInput *getInput() { return m_midiIn; }
+    MIDIOutput *getOutput() { return m_midiOut; }
+    void setAdvanced(bool value);
+    bool advanced();
+    bool midiThru();
+
+public slots:
+    void configureInputDriver();
+    void configureOutputDriver();
+    void clickedAdvanced(bool value);
+    void setMidiThru(bool value);
+    void refreshInputs(QString id);
+    void refreshOutputs(QString id);
+    void refresh();
+    void accept();
 
 private:
-    ConnectionItem* createConnectionItem(PortInfo& pi, PortInfoList& subs);
+    bool m_advanced;
+    bool m_thru;
+    bool m_settingsChanged;
+    MIDIInput* m_midiIn;
+    MIDIOutput* m_midiOut;
     Ui::ConnectionsClass ui;
 };
 
diff --git a/utils/vpiano/connections.ui b/utils/vpiano/connections.ui
index 0d59c38..4d64d0c 100644
--- a/utils/vpiano/connections.ui
+++ b/utils/vpiano/connections.ui
@@ -1,58 +1,92 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>ConnectionsClass</class>
- <widget class="QDialog" name="ConnectionsClass" >
-  <property name="geometry" >
+ <widget class="QDialog" name="ConnectionsClass">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>272</width>
-    <height>302</height>
+    <width>289</width>
+    <height>244</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string>Connections</string>
   </property>
-  <layout class="QVBoxLayout" >
-   <item>
-    <widget class="QTabWidget" name="tabWidget" >
-     <property name="currentIndex" >
-      <number>0</number>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label_in">
+     <property name="text">
+      <string>MIDI IN</string>
      </property>
-     <widget class="QWidget" name="tabInput" >
-      <attribute name="title" >
-       <string>Input</string>
-      </attribute>
-      <layout class="QVBoxLayout" >
-       <item>
-        <widget class="QListWidget" name="m_listInputs" />
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tabOutput" >
-      <attribute name="title" >
-       <string>Output</string>
-      </attribute>
-      <layout class="QVBoxLayout" >
-       <item>
-        <widget class="QListWidget" name="m_listOutputs" />
-       </item>
-      </layout>
-     </widget>
     </widget>
    </item>
-   <item>
-    <widget class="QDialogButtonBox" name="buttonBox" >
-     <property name="orientation" >
+   <item row="1" column="0">
+    <widget class="QComboBox" name="m_inputBackends"/>
+   </item>
+   <item row="2" column="0" colspan="2">
+    <widget class="QComboBox" name="m_inputPorts"/>
+   </item>
+   <item row="3" column="0" colspan="2">
+    <widget class="QCheckBox" name="m_thru">
+     <property name="text">
+      <string>Enable MIDI THRU</string>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="0">
+    <widget class="QLabel" name="label_out">
+     <property name="text">
+      <string>MIDI OUT</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="0">
+    <widget class="QComboBox" name="m_outputBackends"/>
+   </item>
+   <item row="5" column="1">
+    <widget class="QToolButton" name="btnOutputDriverCfg">
+     <property name="enabled">
+      <bool>false</bool>
+     </property>
+     <property name="text">
+      <string>...</string>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="0" colspan="2">
+    <widget class="QComboBox" name="m_outputPorts"/>
+   </item>
+   <item row="7" column="0" colspan="2">
+    <widget class="QCheckBox" name="m_advanced">
+     <property name="text">
+      <string>Show advanced connections</string>
+     </property>
+    </widget>
+   </item>
+   <item row="8" column="0" colspan="2">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
-     <property name="standardButtons" >
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QToolButton" name="btnInputDriverCfg">
+     <property name="enabled">
+      <bool>false</bool>
+     </property>
+     <property name="text">
+      <string>...</string>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
- <layoutdefault spacing="6" margin="11" />
+ <layoutdefault spacing="6" margin="11"/>
  <resources/>
  <connections>
   <connection>
@@ -61,11 +95,11 @@
    <receiver>ConnectionsClass</receiver>
    <slot>accept()</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>264</x>
      <y>303</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>283</x>
      <y>112</y>
     </hint>
@@ -77,11 +111,11 @@
    <receiver>ConnectionsClass</receiver>
    <slot>reject()</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>65</x>
      <y>303</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>93</x>
      <y>74</y>
     </hint>
diff --git a/utils/vpiano/fluidsettingsdialog.cpp b/utils/vpiano/fluidsettingsdialog.cpp
new file mode 100644
index 0000000..b6e23ce
--- /dev/null
+++ b/utils/vpiano/fluidsettingsdialog.cpp
@@ -0,0 +1,196 @@
+/*
+    Virtual Piano test using the MIDI Sequencer C++ library
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QSettings>
+#include <QFileInfo>
+#include <QDir>
+#include <QStandardPaths>
+#include <QFileDialog>
+#include <QToolButton>
+#include <QPushButton>
+
+#include "fluidsettingsdialog.h"
+#include "ui_fluidsettingsdialog.h"
+
+const QString QSTR_PREFERENCES("FluidSynth");
+const QString QSTR_INSTRUMENTSDEFINITION("InstrumentsDefinition");
+const QString QSTR_DATADIR("soundfonts");
+const QString QSTR_SOUNDFONT("default.sf2");
+const QString QSTR_AUDIODRIVER("AudioDriver");
+const QString QSTR_PERIODSIZE("PeriodSize");
+const QString QSTR_PERIODS("Periods");
+const QString QSTR_SAMPLERATE("SampleRate");
+const QString QSTR_CHORUS("Chorus");
+const QString QSTR_REVERB("Reverb");
+const QString QSTR_GAIN("Gain");
+const QString QSTR_POLYPHONY("Polyphony");
+
+const int DEFAULT_PERIODSIZE = 512;
+const int DEFAULT_PERIODS = 3;
+const double DEFAULT_SAMPLERATE = 48000.0;
+const int DEFAULT_CHORUS = 0;
+const int DEFAULT_REVERB = 0;
+const double DEFAULT_GAIN = .4;
+const int DEFAULT_POLYPHONY = 32;
+
+FluidSettingsDialog::FluidSettingsDialog(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::FluidSettingsDialog)
+{
+    ui->setupUi(this);
+    connect(ui->btnFile, &QToolButton::clicked, this, &FluidSettingsDialog::showFileDialog);
+    connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked,
+            this, &FluidSettingsDialog::restoreDefaults);
+    ui->periodSize->setValidator(new QIntValidator(64, 8192, this));
+    ui->periods->setValidator(new QIntValidator(2, 64, this));
+    ui->sampleRate->setValidator(new QDoubleValidator(22050.0, 96000.0, 1, this));
+    ui->gain->setValidator(new QDoubleValidator(0.0, 10.0, 2, this));
+    ui->polyphony->setValidator(new QIntValidator(16, 4096, this));
+}
+
+FluidSettingsDialog::~FluidSettingsDialog()
+{
+    delete ui;
+}
+
+void FluidSettingsDialog::accept()
+{
+    writeSettings();
+    QDialog::accept();
+}
+
+void FluidSettingsDialog::showEvent(QShowEvent *event)
+{
+    readSettings();
+    event->accept();
+}
+
+QString FluidSettingsDialog::defaultAudioDriver() const
+{
+    const QString QSTR_DEFAULT_AUDIODRIVER =
+#if defined(Q_OS_LINUX)
+        QLatin1Literal("alsa");
+#elif defined(Q_OS_WIN)
+        QLatin1Literal("dsound");
+#elif defined(Q_OS_OSX)
+        QLatin1Literal("coreaudio");
+#else
+        QLatin1Literal("oss");
+#endif
+    return QSTR_DEFAULT_AUDIODRIVER;
+}
+
+void FluidSettingsDialog::readSettings()
+{
+    QSettings settings;
+    QStringList drivers;
+    QString fs_defSoundFont = QSTR_SOUNDFONT;
+#if defined(Q_OS_LINUX)
+    drivers << "alsa" << "pulseaudio" << "oss";
+#elif defined(Q_OS_WIN)
+    drivers << "dsound";
+#elif defined(Q_OS_OSX)
+    drivers << "coreaudio";
+#else
+    drivers << "oss";
+#endif
+
+    QDir dir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR, QStandardPaths::LocateDirectory));
+    QFileInfo sf2(dir, QSTR_SOUNDFONT);
+    if (sf2.exists()) {
+        fs_defSoundFont = sf2.absoluteFilePath();
+    }
+
+    ui->audioDriver->addItems(drivers);
+
+    settings.beginGroup(QSTR_PREFERENCES);
+    ui->audioDriver->setCurrentText( settings.value(QSTR_AUDIODRIVER, defaultAudioDriver()).toString() );
+    ui->periodSize->setText( settings.value(QSTR_PERIODSIZE, DEFAULT_PERIODSIZE).toString() );
+    ui->periods->setText( settings.value(QSTR_PERIODS, DEFAULT_PERIODS).toString() );
+    ui->sampleRate->setText( settings.value(QSTR_SAMPLERATE, DEFAULT_SAMPLERATE).toString() );
+    ui->chorus->setChecked( settings.value(QSTR_CHORUS, DEFAULT_CHORUS).toInt() != 0 );
+    ui->reverb->setChecked( settings.value(QSTR_REVERB, DEFAULT_REVERB).toInt() != 0 );
+    ui->gain->setText( settings.value(QSTR_GAIN, DEFAULT_GAIN).toString() );
+    ui->polyphony->setText( settings.value(QSTR_POLYPHONY, DEFAULT_POLYPHONY).toString() );
+    ui->soundFont->setText( settings.value(QSTR_INSTRUMENTSDEFINITION, fs_defSoundFont).toString() );
+    settings.endGroup();
+}
+
+void FluidSettingsDialog::writeSettings()
+{
+    QSettings settings;
+    QString audioDriver;
+    QString soundFont(QSTR_SOUNDFONT);
+    int     periodSize(DEFAULT_PERIODSIZE);
+    int     periods(DEFAULT_PERIODS);
+    double  sampleRate(DEFAULT_SAMPLERATE);
+    int     chorus(DEFAULT_CHORUS);
+    int     reverb(DEFAULT_REVERB);
+    double  gain(DEFAULT_GAIN);
+    int     polyphony(DEFAULT_POLYPHONY);
+
+    audioDriver = ui->audioDriver->currentText();
+    if (audioDriver.isEmpty()) {
+        audioDriver = defaultAudioDriver();
+    }
+    soundFont = ui->soundFont->text();
+    periodSize = ui->periodSize->text().toInt();
+    periods = ui->periods->text().toInt();
+    sampleRate = ui->sampleRate->text().toDouble();
+    chorus = (ui->chorus->isChecked() ? 1 : 0);
+    reverb = (ui->reverb->isChecked() ? 1 : 0);
+    gain = ui->gain->text().toDouble();
+    polyphony = ui->polyphony->text().toInt();
+
+    settings.beginGroup(QSTR_PREFERENCES);
+    settings.setValue(QSTR_INSTRUMENTSDEFINITION, soundFont);
+    settings.setValue(QSTR_AUDIODRIVER, audioDriver);
+    settings.setValue(QSTR_PERIODSIZE, periodSize);
+    settings.setValue(QSTR_PERIODS, periods);
+    settings.setValue(QSTR_SAMPLERATE, sampleRate);
+    settings.setValue(QSTR_CHORUS, chorus);
+    settings.setValue(QSTR_REVERB, reverb);
+    settings.setValue(QSTR_GAIN, gain);
+    settings.setValue(QSTR_POLYPHONY, polyphony);
+    settings.endGroup();
+
+    settings.sync();
+}
+
+void FluidSettingsDialog::restoreDefaults()
+{
+    ui->audioDriver->setCurrentText( defaultAudioDriver() );
+    ui->periodSize->setText( QString::number( DEFAULT_PERIODSIZE ));
+    ui->periods->setText( QString::number( DEFAULT_PERIODS ));
+    ui->sampleRate->setText( QString::number( DEFAULT_SAMPLERATE ));
+    ui->chorus->setChecked( DEFAULT_CHORUS != 0 );
+    ui->reverb->setChecked( DEFAULT_REVERB != 0 );
+    ui->gain->setText( QString::number( DEFAULT_GAIN ) );
+    ui->polyphony->setText( QString::number( DEFAULT_POLYPHONY ));
+    ui->soundFont->setText( QSTR_SOUNDFONT );
+}
+
+void FluidSettingsDialog::showFileDialog()
+{
+    QDir dir(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QSTR_DATADIR, QStandardPaths::LocateDirectory));
+    QString fileName = QFileDialog::getOpenFileName(this, tr("Select SoundFont"), dir.absolutePath(), tr("SoundFont Files (*.sf2)"));
+    if (!fileName.isEmpty()) {
+        ui->soundFont->setText(fileName);
+    }
+}
diff --git a/utils/guiplayer/playerabout.h b/utils/vpiano/fluidsettingsdialog.h
similarity index 52%
copy from utils/guiplayer/playerabout.h
copy to utils/vpiano/fluidsettingsdialog.h
index 8809446..0a154f2 100644
--- a/utils/guiplayer/playerabout.h
+++ b/utils/vpiano/fluidsettingsdialog.h
@@ -1,6 +1,6 @@
 /*
-    Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Virtual Piano test using the MIDI Sequencer C++ library
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -12,29 +12,40 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License along 
-    with this program; if not, write to the Free Software Foundation, Inc., 
-    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.    
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
-#ifndef ABOUT_H
-#define ABOUT_H
+#ifndef FLUIDSETTINGSDIALOG_H
+#define FLUIDSETTINGSDIALOG_H
 
-#include <QtGui/QDialog>
-#include "ui_playerabout.h"
+#include <QDialog>
+#include <QShowEvent>
 
-class About : public QDialog
+namespace Ui {
+    class FluidSettingsDialog;
+}
+
+class FluidSettingsDialog : public QDialog
 {
     Q_OBJECT
 
 public:
-    About(QWidget *parent = 0);
+    explicit FluidSettingsDialog(QWidget *parent = 0);
+    ~FluidSettingsDialog();
+    void readSettings();
+    void writeSettings();
 
 public slots:
-    void aboutQt();
+    void accept();
+    void showEvent(QShowEvent *event);
+    void restoreDefaults();
+    void showFileDialog();
 
 private:
-    Ui::AboutClass ui;
+    QString defaultAudioDriver() const;
+    Ui::FluidSettingsDialog *ui;
 };
 
-#endif // ABOUT_H
+#endif // FLUIDSETTINGSDIALOG_H
diff --git a/utils/vpiano/fluidsettingsdialog.ui b/utils/vpiano/fluidsettingsdialog.ui
new file mode 100644
index 0000000..4dea070
--- /dev/null
+++ b/utils/vpiano/fluidsettingsdialog.ui
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FluidSettingsDialog</class>
+ <widget class="QDialog" name="FluidSettingsDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>316</width>
+    <height>312</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>FluidSynth Driver Settings</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="2" column="0">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QFrame" name="frame">
+     <property name="frameShape">
+      <enum>QFrame::StyledPanel</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Raised</enum>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <item row="1" column="1">
+       <widget class="QLineEdit" name="periodSize"/>
+      </item>
+      <item row="8" column="1">
+       <widget class="QLineEdit" name="soundFont"/>
+      </item>
+      <item row="3" column="1">
+       <widget class="QLineEdit" name="sampleRate"/>
+      </item>
+      <item row="3" column="0">
+       <widget class="QLabel" name="lblSampleRate">
+        <property name="text">
+         <string>Sample Rate:</string>
+        </property>
+        <property name="buddy">
+         <cstring>sampleRate</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="lblPeriodSize">
+        <property name="text">
+         <string>Period Size:</string>
+        </property>
+        <property name="buddy">
+         <cstring>periodSize</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="7" column="1">
+       <widget class="QLineEdit" name="polyphony"/>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="lblPeriods">
+        <property name="text">
+         <string># of Periods:</string>
+        </property>
+        <property name="buddy">
+         <cstring>periods</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QComboBox" name="audioDriver"/>
+      </item>
+      <item row="0" column="0">
+       <widget class="QLabel" name="lblDriver">
+        <property name="text">
+         <string>Audio Driver:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="7" column="0">
+       <widget class="QLabel" name="lblPolyphony">
+        <property name="text">
+         <string>Polyphony:</string>
+        </property>
+        <property name="buddy">
+         <cstring>polyphony</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QLineEdit" name="periods"/>
+      </item>
+      <item row="8" column="0">
+       <widget class="QLabel" name="lblSoundFont">
+        <property name="text">
+         <string>Sound Font:</string>
+        </property>
+        <property name="buddy">
+         <cstring>soundFont</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="6" column="0">
+       <widget class="QLabel" name="lblGain">
+        <property name="text">
+         <string>Gain:</string>
+        </property>
+        <property name="buddy">
+         <cstring>gain</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="6" column="1">
+       <widget class="QLineEdit" name="gain"/>
+      </item>
+      <item row="8" column="2">
+       <widget class="QToolButton" name="btnFile">
+        <property name="text">
+         <string>...</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="0" colspan="2">
+       <widget class="QCheckBox" name="chorus">
+        <property name="text">
+         <string>Chorus</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0" colspan="2">
+       <widget class="QCheckBox" name="reverb">
+        <property name="text">
+         <string>Reverb</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>FluidSettingsDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>FluidSettingsDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/utils/vpiano/keyboardmap.h b/utils/vpiano/keyboardmap.h
index 4c4ad3a..93fb4a5 100644
--- a/utils/vpiano/keyboardmap.h
+++ b/utils/vpiano/keyboardmap.h
@@ -1,6 +1,6 @@
 /*
-    Virtual Piano Widget for Qt4
-    Copyright (C) 2008-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Virtual Piano Widget for Qt5
+    Copyright (C) 2008-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -21,4 +21,9 @@
 
 typedef QHash<int, int> KeyboardMap;
 
+const int DEFAULTSTARTINGKEY = 9;
+const int DEFAULTBASEOCTAVE = 1;
+const int DEFAULTNUMBEROFKEYS = 88;
+const int KEYLABELFONTSIZE = 7;
+
 #endif // KEYBOARDMAP_H
diff --git a/utils/vpiano/keylabel.cpp b/utils/vpiano/keylabel.cpp
index 9aa6f57..7d67537 100644
--- a/utils/vpiano/keylabel.cpp
+++ b/utils/vpiano/keylabel.cpp
@@ -1,10 +1,10 @@
 /*
-    Virtual Piano Widget for Qt4
-    Copyright (C) 2008-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Virtual Piano Widget for Qt5
+    Copyright (C) 2008-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
@@ -16,11 +16,19 @@
     with this program; If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include <QFont>
 #include "keylabel.h"
+#include "pianokey.h"
+#include <QFont>
 
 KeyLabel::KeyLabel(QGraphicsItem *parent) : QGraphicsTextItem(parent)
 {
     setAcceptedMouseButtons(Qt::NoButton);
-    rotate(270);
+    //rotate(270);
+    setRotation(rotation() + 270);
+}
+
+QRectF KeyLabel::boundingRect() const
+{
+    PianoKey* key = static_cast<PianoKey*>(parentItem());
+    return mapRectFromScene(key->rect());
 }
diff --git a/utils/vpiano/keylabel.h b/utils/vpiano/keylabel.h
index a01c176..511e584 100644
--- a/utils/vpiano/keylabel.h
+++ b/utils/vpiano/keylabel.h
@@ -1,10 +1,10 @@
 /*
-    Virtual Piano Widget for Qt4
-    Copyright (C) 2008-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Virtual Piano Widget for Qt5
+    Copyright (C) 2008-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
@@ -27,6 +27,7 @@ class VPIANO_EXPORT KeyLabel : public QGraphicsTextItem
 public:
     KeyLabel(QGraphicsItem *parent = 0);
     virtual ~KeyLabel() {}
+    virtual QRectF boundingRect() const;
 };
 
 #endif // KEYLABEL_H
diff --git a/utils/vpiano/networksettingsdialog.cpp b/utils/vpiano/networksettingsdialog.cpp
new file mode 100644
index 0000000..4c368e7
--- /dev/null
+++ b/utils/vpiano/networksettingsdialog.cpp
@@ -0,0 +1,99 @@
+/*
+    Virtual Piano test using the MIDI Sequencer C++ library
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include <QSettings>
+#include <QNetworkInterface>
+#include <QDialogButtonBox>
+#include <QPushButton>
+#include "networksettingsdialog.h"
+#include "ui_networksettingsdialog.h"
+
+const QString QSTR_ADDRESS(QLatin1Literal("225.0.0.37"));
+
+NetworkSettingsDialog::NetworkSettingsDialog(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::NetworkSettingsDialog)
+{
+    ui->setupUi(this);
+    connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::pressed,
+            this, &NetworkSettingsDialog::restoreDefaults);
+}
+
+NetworkSettingsDialog::~NetworkSettingsDialog()
+{
+    delete ui;
+}
+
+void NetworkSettingsDialog::accept()
+{
+    writeSettings();
+    QDialog::accept();
+}
+
+void NetworkSettingsDialog::showEvent(QShowEvent *event)
+{
+    readSettings();
+    event->accept();
+}
+
+void NetworkSettingsDialog::readSettings()
+{
+
+    QSettings settings;
+    settings.beginGroup("Network");
+    QString ifaceName = settings.value("interface", QString()).toString();
+    QString address = settings.value("address", QSTR_ADDRESS).toString();
+    settings.endGroup();
+
+    ui->txtAddress->setText(address);
+    ui->comboInterface->addItem("Any", "");
+    foreach( const QNetworkInterface& iface,  QNetworkInterface::allInterfaces() ) {
+        if ( iface.isValid() && ((iface.flags() & QNetworkInterface::IsLoopBack) == 0) ) {
+            QString name = iface.name();
+            QString text = iface.humanReadableName();
+            ui->comboInterface->addItem(text, name);
+            if (name == ifaceName) {
+                ui->comboInterface->setCurrentText(text);
+            }
+        }
+    }
+
+}
+
+void NetworkSettingsDialog::writeSettings()
+{
+    QSettings settings;
+    QString networkAddr = QSTR_ADDRESS;
+    QString networkIface;
+
+    networkAddr = ui->txtAddress->text();
+    networkIface = ui->comboInterface->currentText();
+
+    settings.beginGroup("Network");
+    settings.setValue("interface", networkIface);
+    settings.setValue("address", networkAddr);
+    settings.endGroup();
+    settings.sync();
+}
+
+void NetworkSettingsDialog::restoreDefaults()
+{
+    ui->txtAddress->setText(QSTR_ADDRESS);
+    ui->comboInterface->setCurrentText(tr("Any"));
+}
diff --git a/utils/guiplayer/playerabout.h b/utils/vpiano/networksettingsdialog.h
similarity index 54%
copy from utils/guiplayer/playerabout.h
copy to utils/vpiano/networksettingsdialog.h
index 8809446..c81c524 100644
--- a/utils/guiplayer/playerabout.h
+++ b/utils/vpiano/networksettingsdialog.h
@@ -1,6 +1,6 @@
 /*
-    Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Virtual Piano test using the MIDI Sequencer C++ library
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -12,29 +12,38 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License along 
-    with this program; if not, write to the Free Software Foundation, Inc., 
-    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.    
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
-#ifndef ABOUT_H
-#define ABOUT_H
+#ifndef NETWORKSETTINGSDIALOG_H
+#define NETWORKSETTINGSDIALOG_H
 
-#include <QtGui/QDialog>
-#include "ui_playerabout.h"
+#include <QDialog>
+#include <QShowEvent>
 
-class About : public QDialog
+namespace Ui {
+    class NetworkSettingsDialog;
+}
+
+class NetworkSettingsDialog : public QDialog
 {
     Q_OBJECT
 
 public:
-    About(QWidget *parent = 0);
+    explicit NetworkSettingsDialog(QWidget *parent = 0);
+    ~NetworkSettingsDialog();
+    void readSettings();
+    void writeSettings();
 
 public slots:
-    void aboutQt();
+    void accept();
+    void showEvent(QShowEvent *event);
+    void restoreDefaults();
 
 private:
-    Ui::AboutClass ui;
+    Ui::NetworkSettingsDialog *ui;
 };
 
-#endif // ABOUT_H
+#endif // NETWORKSETTINGSDIALOG_H
diff --git a/utils/vpiano/networksettingsdialog.ui b/utils/vpiano/networksettingsdialog.ui
new file mode 100644
index 0000000..911685f
--- /dev/null
+++ b/utils/vpiano/networksettingsdialog.ui
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>NetworkSettingsDialog</class>
+ <widget class="QDialog" name="NetworkSettingsDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>302</width>
+    <height>136</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Network Driver Settings</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLabel" name="lblInterface">
+     <property name="text">
+      <string>Network Interface:</string>
+     </property>
+     <property name="buddy">
+      <cstring>comboInterface</cstring>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QComboBox" name="comboInterface"/>
+   </item>
+   <item>
+    <widget class="QLabel" name="lblAddress">
+     <property name="text">
+      <string>Address</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLineEdit" name="txtAddress"/>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>NetworkSettingsDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>236</x>
+     <y>126</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>87</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>NetworkSettingsDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>292</x>
+     <y>126</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>87</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/utils/vpiano/pianodefs.h b/utils/vpiano/pianodefs.h
index 5e76f13..b563eed 100644
--- a/utils/vpiano/pianodefs.h
+++ b/utils/vpiano/pianodefs.h
@@ -1,6 +1,6 @@
 /*
-    Virtual Piano Widget for Qt4
-    Copyright (C) 2008-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Virtual Piano Widget for Qt5
+    Copyright (C) 2008-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -19,10 +19,12 @@
 #ifndef PIANODEFS_H
 #define PIANODEFS_H
 
-#if defined(VPIANO_PLUGIN)
-#define VPIANO_EXPORT Q_DECL_EXPORT
-#else
-#define VPIANO_EXPORT Q_DECL_IMPORT
-#endif
+//#if defined(VPIANO_PLUGIN)
+//#define VPIANO_EXPORT Q_DECL_EXPORT
+//#else
+//#define VPIANO_EXPORT Q_DECL_IMPORT
+//#endif
+
+#define VPIANO_EXPORT
 
 #endif // PIANODEFS_H
diff --git a/utils/vpiano/pianokey.cpp b/utils/vpiano/pianokey.cpp
index 0d00987..fa503ed 100644
--- a/utils/vpiano/pianokey.cpp
+++ b/utils/vpiano/pianokey.cpp
@@ -1,10 +1,10 @@
 /*
-    Virtual Piano Widget for Qt4 
-    Copyright (C) 2008-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Virtual Piano Widget for Qt5
+    Copyright (C) 2008-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
@@ -20,7 +20,7 @@
 #include <QApplication>
 #include <QPainter>
 #include <QPalette>
-#include <QSvgRenderer>
+#include <QtSvg/QSvgRenderer>
 
 static const QBrush blackBrush = QBrush(Qt::black);
 static const QBrush whiteBrush = QBrush(Qt::white);
@@ -81,3 +81,11 @@ void PianoKey::setPressed(bool p)
         update();
     }
 }
+
+void PianoKey::resetBrush()
+{
+    if (m_black)
+        m_brush = blackBrush;
+    else
+        m_brush = whiteBrush;
+}
diff --git a/utils/vpiano/pianokey.h b/utils/vpiano/pianokey.h
index ea3e632..3a8a4ce 100644
--- a/utils/vpiano/pianokey.h
+++ b/utils/vpiano/pianokey.h
@@ -1,10 +1,10 @@
 /*
-    Virtual Piano Widget for Qt4 
-    Copyright (C) 2008-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Virtual Piano Widget for Qt5
+    Copyright (C) 2008-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
@@ -32,9 +32,14 @@ public:
     PianoKey(const QRectF &rect, const bool black, const int note);
     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);
     int getNote() const { return m_note; }
+    void setBrush(const QBrush& b) { m_brush = b; }
     void setPressedBrush(const QBrush& b) { m_selectedBrush = b; }
+    void resetBrush();
     bool isPressed() const { return m_pressed; }
     void setPressed(bool p);
+    int getDegree() const { return m_note % 12; }
+    int getType() const { return (m_black ? 1 : 0); }
+
 private:
     bool m_pressed;
     QBrush m_selectedBrush;
diff --git a/utils/vpiano/pianokeybd.cpp b/utils/vpiano/pianokeybd.cpp
index 027672a..11e6e26 100644
--- a/utils/vpiano/pianokeybd.cpp
+++ b/utils/vpiano/pianokeybd.cpp
@@ -1,10 +1,10 @@
 /*
-    Virtual Piano Widget for Qt4 
-    Copyright (C) 2008-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Virtual Piano Widget for Qt5
+    Copyright (C) 2008-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
@@ -16,54 +16,52 @@
     with this program; If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <QApplication>
 #include "pianokeybd.h"
 
 PianoKeybd::PianoKeybd(QWidget *parent) 
     : QGraphicsView(parent), m_rotation(0), m_scene(NULL), m_rawMap(NULL)
 {
     initialize();
-    initScene(3, 5);
+    initScene(DEFAULTBASEOCTAVE, DEFAULTNUMBEROFKEYS, DEFAULTSTARTINGKEY);
 }
 
-PianoKeybd::PianoKeybd(const int baseOctave, const int numOctaves, QWidget *parent) 
+PianoKeybd::PianoKeybd(const int baseOctave, const int numKeys, const int startKey, QWidget *parent)
     : QGraphicsView(parent), m_rotation(0), m_scene(NULL), m_rawMap(NULL)
 {
     initialize();
-    initScene(baseOctave, numOctaves);
+    initScene(baseOctave, numKeys, startKey);
 }
 
 PianoKeybd::~PianoKeybd()
 {
-    setRawKeyboardMode(false);
-    setRawKeyboardMap(NULL);
+    m_scene->setRawKeyboardMode(false);
+    setRawKeyboardMap(0);
 }
 
-void PianoKeybd::initScene(int base, int num, const QColor& c)
+void PianoKeybd::initScene(int base, int num, int strt, const QColor& c)
 {
-    m_scene = new PianoScene(base, num, c, this);
+    m_scene = new PianoScene(base, num, strt, c, this);
     m_scene->setKeyboardMap(&m_defaultMap);
-    connect(m_scene, SIGNAL(noteOn(int)), SIGNAL(noteOn(int)));
-    connect(m_scene, SIGNAL(noteOff(int)), SIGNAL(noteOff(int)));
+    connect(m_scene, SIGNAL(noteOn(int,int)), SIGNAL(noteOn(int,int)));
+    connect(m_scene, SIGNAL(noteOff(int,int)), SIGNAL(noteOff(int,int)));
     setScene(m_scene);
 }
 
 void PianoKeybd::initialize()
 {
+    setAttribute(Qt::WA_AcceptTouchEvents);
     setAttribute(Qt::WA_InputMethodEnabled, false);
     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
     setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
     setCacheMode(CacheBackground);
     setViewportUpdateMode(MinimalViewportUpdate);
-    setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
+    setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing|QPainter::SmoothPixmapTransform);
     setOptimizationFlag(DontClipPainter, true);
     setOptimizationFlag(DontSavePainterState, true);
     setOptimizationFlag(DontAdjustForAntialiasing, true);
     setBackgroundBrush(QApplication::palette().background());
     initDefaultMap();
-    RawKeybdApp* rapp = dynamic_cast<RawKeybdApp*>(qApp);
-    if (rapp != NULL) {
-        rapp->setRawKbdHandler(this);
-    }
 }
 
 void PianoKeybd::resizeEvent(QResizeEvent *event)
@@ -72,16 +70,6 @@ void PianoKeybd::resizeEvent(QResizeEvent *event)
     fitInView(m_scene->sceneRect(), Qt::KeepAspectRatio);
 }
 
-void PianoKeybd::showNoteOn(int midiNote)
-{
-    m_scene->showNoteOn(midiNote);
-}
-
-void PianoKeybd::showNoteOff(int midiNote)
-{
-    m_scene->showNoteOff(midiNote);
-}
-
 void PianoKeybd::initDefaultMap()
 {
     // Default translated Keyboard Map
@@ -116,7 +104,7 @@ void PianoKeybd::initDefaultMap()
     m_defaultMap.insert(Qt::Key_P, 40);
 
     // Default Raw Keyboard Map
-#if defined(Q_WS_X11)
+#if defined(Q_OS_LINUX)
     m_defaultRawMap.insert(94, 11);
     m_defaultRawMap.insert(52, 12);
     m_defaultRawMap.insert(39, 13);
@@ -158,7 +146,7 @@ void PianoKeybd::initDefaultMap()
     m_defaultRawMap.insert(35, 48);
 #endif
 
-#if defined(Q_WS_WIN)
+#if defined(Q_OS_WIN)
     m_defaultRawMap.insert(86, 11);
     m_defaultRawMap.insert(44, 12);
     m_defaultRawMap.insert(31, 13);
@@ -200,7 +188,7 @@ void PianoKeybd::initDefaultMap()
     m_defaultRawMap.insert(27, 48);
 #endif
 
-#if defined(Q_WS_MAC)
+#if defined(Q_OS_MAC)
     m_defaultRawMap.insert(50, 11);
     m_defaultRawMap.insert(6, 12);
     m_defaultRawMap.insert(1, 13);
@@ -244,17 +232,24 @@ void PianoKeybd::initDefaultMap()
     m_rawMap = &m_defaultRawMap;
 }
 
-void PianoKeybd::setNumOctaves(const int numOctaves)
+void PianoKeybd::setNumKeys(const int numKeys, const int startKey)
 {
-    if (numOctaves != m_scene->numOctaves()) {
+    if ( numKeys != m_scene->numKeys() || startKey != m_scene->startKey() )
+    {
         int baseOctave = m_scene->baseOctave();
         QColor color = m_scene->getKeyPressedColor();
         PianoHandler* handler = m_scene->getPianoHandler();
         KeyboardMap* keyMap = m_scene->getKeyboardMap();
+        bool keyboardEnabled = m_scene->isKeyboardEnabled();
+        bool mouseEnabled = m_scene->isMouseEnabled();
+        bool touchEnabled = m_scene->isTouchEnabled();
         delete m_scene;
-        initScene(baseOctave, numOctaves, color);
+        initScene(baseOctave, numKeys, startKey, color);
         m_scene->setPianoHandler(handler);
         m_scene->setKeyboardMap(keyMap);
+        m_scene->setKeyboardEnabled(keyboardEnabled);
+        m_scene->setMouseEnabled(mouseEnabled);
+        m_scene->setTouchEnabled(touchEnabled);
         fitInView(m_scene->sceneRect(), Qt::KeepAspectRatio);
     }
 }
@@ -274,9 +269,10 @@ QSize PianoKeybd::sizeHint() const
     return mapFromScene(sceneRect()).boundingRect().size();
 }
 
+#if defined(RAWKBD_SUPPORT)
 bool PianoKeybd::handleKeyPressed(int keycode)
 {
-    if (m_rawMap != NULL && m_rawMap->contains(keycode)) {
+    if (m_scene->isKeyboardEnabled() && m_rawMap != NULL && m_rawMap->contains(keycode)) {
         m_scene->keyOn(m_rawMap->value(keycode));
         return true;
     }
@@ -285,9 +281,10 @@ bool PianoKeybd::handleKeyPressed(int keycode)
 
 bool PianoKeybd::handleKeyReleased(int keycode)
 {
-    if (m_rawMap != NULL && m_rawMap->contains(keycode)) {
+    if (m_scene->isKeyboardEnabled() && m_rawMap != NULL && m_rawMap->contains(keycode)) {
         m_scene->keyOff(m_rawMap->value(keycode));
         return true;
     }
     return false;
 }
+#endif
diff --git a/utils/vpiano/pianokeybd.h b/utils/vpiano/pianokeybd.h
index 01699c3..6ea8565 100644
--- a/utils/vpiano/pianokeybd.h
+++ b/utils/vpiano/pianokeybd.h
@@ -1,10 +1,10 @@
 /*
-    Virtual Piano Widget for Qt4 
-    Copyright (C) 2008-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Virtual Piano Widget for Qt5
+    Copyright (C) 2008-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
@@ -20,7 +20,9 @@
 #define PIANOKEYBD_H
 
 #include "pianoscene.h"
-#include "rawkeybdapp.h"
+#if defined(RAWKBD_SUPPORT)
+#include "nativefilter.h"
+#endif
 #include <QGraphicsView>
 
 #if defined(VPIANO_PLUGIN)
@@ -29,11 +31,14 @@
 #define QDESIGNER_WIDGET_EXPORT
 #endif
 
-class QDESIGNER_WIDGET_EXPORT PianoKeybd : public QGraphicsView, public RawKbdHandler
+class QDESIGNER_WIDGET_EXPORT PianoKeybd : public QGraphicsView
+#if defined(RAWKBD_SUPPORT)
+        , public RawKbdHandler
+#endif
 {
     Q_OBJECT
     Q_PROPERTY( int baseOctave READ baseOctave WRITE setBaseOctave )
-    Q_PROPERTY( int numOctaves READ numOctaves WRITE setNumOctaves )
+    Q_PROPERTY( int numKeys READ numKeys WRITE setNumKeys )
     Q_PROPERTY( int rotation READ getRotation WRITE setRotation )
     Q_PROPERTY( QColor keyPressedColor READ getKeyPressedColor WRITE setKeyPressedColor )
     Q_PROPERTY( bool showLabels READ showLabels WRITE setShowLabels )
@@ -42,59 +47,50 @@ class QDESIGNER_WIDGET_EXPORT PianoKeybd : public QGraphicsView, public RawKbdHa
 #if defined(VPIANO_PLUGIN)
     Q_CLASSINFO("Author", "Pedro Lopez-Cabanillas <plcl at users.sf.net>")
     Q_CLASSINFO("URL", "http://sourceforge.net/projects/vmpk")
-    Q_CLASSINFO("Version", "0.8")
+    Q_CLASSINFO("Version", "1.0")
 #endif
 public:
     PianoKeybd(QWidget *parent = 0);
-    PianoKeybd(const int baseOctave, const int numOctaves, QWidget *parent = 0);
+    PianoKeybd(const int baseOctave, const int numKeys, const int startKey, QWidget *parent = 0);
     virtual ~PianoKeybd();
-    void setKeyboardMap(KeyboardMap* m) { m_scene->setKeyboardMap(m); }
-    void resetKeyboardMap() { m_scene->setKeyboardMap(&m_defaultMap); }
-    KeyboardMap* getKeyboardMap() { return m_scene->getKeyboardMap(); }
-    void setRawKeyboardMap(KeyboardMap* m) { m_rawMap = m; }
-    KeyboardMap* getRawKeyboardMap() { return m_rawMap; }
-    void resetRawKeyboardMap() { m_rawMap = &m_defaultRawMap; }
 
     int baseOctave() const { return m_scene->baseOctave(); }
-    int numOctaves() const { return m_scene->numOctaves(); }
     void setBaseOctave(const int baseOctave) { m_scene->setBaseOctave(baseOctave); }
-    void setNumOctaves(const int numOctaves);
-    QSize sizeHint() const;
+    int numKeys() const { return m_scene->numKeys(); }
+    int startKey() const { return m_scene->startKey(); }
+    void setNumKeys(const int numKeys, const int startKey = DEFAULTSTARTINGKEY);
     int getRotation() const { return m_rotation; }
     void setRotation(int r);
     QColor getKeyPressedColor() const { return m_scene->getKeyPressedColor(); }
     void setKeyPressedColor(const QColor& c) { m_scene->setKeyPressedColor(c); }
-    void allKeysOff() { m_scene->allKeysOff(); }
-    void setPianoHandler(PianoHandler* handler) { m_scene->setPianoHandler(handler); }
-    int minNote() const { return m_scene->getMinNote(); }
-    void setMinNote(int n) { m_scene->setMinNote(n); }
-    int maxNote() const { return m_scene->getMaxNote(); }
-    void setMaxNote(int n) { m_scene->setMaxNote(n); }
-    int getTranspose() const { return m_scene->getTranspose(); }
-    void setTranspose(int t) { m_scene->setTranspose(t); }
     bool showLabels() const { return m_scene->showLabels(); }
     void setShowLabels(bool show) { m_scene->setShowLabels(show); }
     bool useFlats() const { return m_scene->useFlats(); }
     void setUseFlats(bool use) { m_scene->setUseFlats(use); }
-    bool getRawKeyboardMode() const { return m_scene->getRawKeyboardMode(); }
-    void setRawKeyboardMode(const bool b) { m_scene->setRawKeyboardMode(b); }
+    int getTranspose() const { return m_scene->getTranspose(); }
+    void setTranspose(int t) { m_scene->setTranspose(t); }
 
+    QSize sizeHint() const;
+    PianoScene* getPianoScene() { return m_scene; }
+    void setRawKeyboardMap(KeyboardMap* m) { m_rawMap = m; }
+    KeyboardMap* getRawKeyboardMap() { return m_rawMap; }
+    void resetRawKeyboardMap() { m_rawMap = &m_defaultRawMap; }
+    void resetKeyboardMap() { m_scene->setKeyboardMap(&m_defaultMap); }
+
+#if defined(RAWKBD_SUPPORT)
 // RawKbdHandler methods
     bool handleKeyPressed(int keycode);
     bool handleKeyReleased(int keycode);
-
-public slots:
-    void showNoteOn( int midiNote );
-    void showNoteOff( int midiNote );
+#endif
 
 signals:
-    void noteOn( int midiNote );
-    void noteOff( int midiNote );
+    void noteOn( int midiNote, int vel );
+    void noteOff( int midiNote, int vel );
 
 protected:
     void initialize();
     void initDefaultMap();
-    void initScene(int base, int num, const QColor& c = QColor());
+    void initScene(int base, int num, int ini, const QColor& c = QColor());
     void resizeEvent(QResizeEvent *event);
 
 private:
diff --git a/utils/vpiano/pianoscene.cpp b/utils/vpiano/pianoscene.cpp
index 76a38c1..19bf0ea 100644
--- a/utils/vpiano/pianoscene.cpp
+++ b/utils/vpiano/pianoscene.cpp
@@ -1,10 +1,10 @@
 /*
-    Virtual Piano Widget for Qt4 
-    Copyright (C) 2008-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Virtual Piano Widget for Qt5
+    Copyright (C) 2008-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
@@ -17,234 +17,406 @@
 */
 
 #include "pianoscene.h"
-#include "rawkeybdapp.h"
+#if defined(RAWKBD_SUPPORT)
+#include "nativefilter.h"
+#endif
 #include <QApplication>
 #include <QPalette>
 #include <QGraphicsSceneMouseEvent>
 #include <QKeyEvent>
+#include <qmath.h>
+#include <QDebug>
 
 #define KEYWIDTH  18
 #define KEYHEIGHT 72
 
-PianoScene::PianoScene ( const int baseOctave, 
-                         const int numOctaves, 
+static qreal sceneWidth(int keys) {
+    return KEYWIDTH * qCeil( keys * 7.0 / 12.0 );
+}
+
+PianoScene::PianoScene ( const int baseOctave,
+                         const int numKeys,
+                         const int startKey,
                          const QColor& keyPressedColor,
                          QObject * parent )
-    : QGraphicsScene( QRectF(0, 0, KEYWIDTH * numOctaves * 7, KEYHEIGHT), parent ),
+    : QGraphicsScene( QRectF(0, 0, sceneWidth(numKeys), KEYHEIGHT), parent ),
     m_baseOctave( baseOctave ),
-    m_numOctaves( numOctaves ),
+    m_numKeys( numKeys ),
+    m_startKey( startKey ),
     m_minNote( 0 ),
     m_maxNote( 127 ),
     m_transpose( 0 ),
     m_showLabels( false ),
     m_useFlats( false ),
     m_rawkbd( false ),
+    m_keyboardEnabled( true ),
+    m_mouseEnabled( true ),
+    m_touchEnabled( true ),
     m_keyPressedColor( keyPressedColor ),
     m_mousePressed( false ),
-    m_handler( NULL )
+    m_velocity( 100 ),
+    m_channel( 0 ),
+    m_velocityTint( true ),
+    m_handler( 0 )
+#if defined(PALETTE_SUPPORT)
+    ,m_showColorScale( false )
+    ,m_palette( 0 )
+    ,m_scalePalette( 0 )
+#endif
 {
-    //QBrush blackBrush(Qt::black);
-    //QBrush whiteBrush(Qt::white);
     QBrush hilightBrush(m_keyPressedColor.isValid() ? m_keyPressedColor : QApplication::palette().highlight());
     QFont lblFont(QApplication::font());
-    int i, numkeys = m_numOctaves * 12;
-    lblFont.setPointSize(7);
-    for(i = 0; i < numkeys; ++i)
+    lblFont.setPointSize(KEYLABELFONTSIZE);
+    int upperLimit = m_numKeys + m_startKey;
+    int adj = m_startKey % 12;
+    if (adj >= 5) adj++;
+    for(int i = m_startKey; i < upperLimit; ++i)
     {
         float x = 0;
         PianoKey* key = NULL;
         KeyLabel* lbl = NULL;
-        int octave = i / 12 * 7;
+        int ocs = i / 12 * 7;
         int j = i % 12;
         if (j >= 5) j++;
         if ((j % 2) == 0) {
-            x = (octave + j / 2) * KEYWIDTH;
+            x = (ocs + qFloor((j-adj) / 2.0)) * KEYWIDTH;
             key = new PianoKey( QRectF(x, 0, KEYWIDTH, KEYHEIGHT), false, i );
             lbl = new KeyLabel(key);
             lbl->setDefaultTextColor(Qt::black);
             lbl->setPos(x, KEYHEIGHT);
         } else {
-            x = (octave + j / 2) * KEYWIDTH + KEYWIDTH * 6/10 + 1;
+            x = (ocs + qFloor((j-adj) / 2.0)) * KEYWIDTH + KEYWIDTH * 6/10 + 1;
             key = new PianoKey( QRectF( x, 0, KEYWIDTH * 8/10 - 1, KEYHEIGHT * 6/10 ), true, i );
             key->setZValue( 1 );
             lbl = new KeyLabel(key);
             lbl->setDefaultTextColor(Qt::white);
             lbl->setPos(x - 3, KEYHEIGHT * 6/10 - 3);
         }
+        //qDebug() << "i=" << i << "ocs=" << ocs << "j=" << j << "x=" << x;
+        key->setAcceptTouchEvents(true);
         if (m_keyPressedColor.isValid())
             key->setPressedBrush(hilightBrush);
         m_keys.insert(i, key);
         addItem( key );
-        lbl->setHtml(noteName(i));
-        lbl->setVisible(m_showLabels);
         lbl->setFont(lblFont);
         m_labels.insert(i, lbl);
     }
     hideOrShowKeys();
+    retranslate();
 }
 
 QSize PianoScene::sizeHint() const
 {
-    return QSize(KEYWIDTH * m_numOctaves * 7, KEYHEIGHT);
+    return QSize(sceneWidth(m_numKeys), KEYHEIGHT);
+}
+
+void PianoScene::showKeyOn( PianoKey* key, QColor color, int vel )
+{
+    if (m_velocityTint && vel >= 0 && color.isValid() ) {
+        QBrush hilightBrush(color.lighter(200 - vel));
+        key->setPressedBrush(hilightBrush);
+    }
+    key->setPressed(true);
 }
 
-void PianoScene::showKeyOn( PianoKey* key )
+void PianoScene::showKeyOn( PianoKey* key, int vel )
 {
+    if (vel >= 0) {
+        if (m_velocityTint && m_keyPressedColor.isValid()) {
+            QBrush hilightBrush(m_keyPressedColor.lighter(200 - vel));
+            key->setPressedBrush(hilightBrush);
+        } else {
+            setColorFromPolicy(key, vel);
+        }
+    }
     key->setPressed(true);
 }
 
-void PianoScene::showKeyOff( PianoKey* key )
+void PianoScene::showKeyOff( PianoKey* key, int )
 {
     key->setPressed(false);
 }
 
-void PianoScene::showNoteOn( const int note )
+void PianoScene::showNoteOn( const int note, QColor color, int vel )
 {
     int n = note - m_baseOctave*12 - m_transpose;
-    if ((note >= m_minNote) && (note <= m_maxNote) &&
-        (n >= 0) && (n < m_keys.size()))
-        showKeyOn(m_keys[n]);
+    if ((note >= m_minNote) && (note <= m_maxNote) && m_keys.contains(n) && color.isValid())
+        showKeyOn(m_keys.value(n), color, vel);
 }
 
-void PianoScene::showNoteOff( const int note )
+void PianoScene::showNoteOn( const int note, int vel )
 {
     int n = note - m_baseOctave*12 - m_transpose;
-    if ((note >= m_minNote) && (note <= m_maxNote) &&
-        (n >= 0) && (n < m_keys.size()))
-        showKeyOff(m_keys[n]);
+    if ((note >= m_minNote) && (note <= m_maxNote) && m_keys.contains(n))
+        showKeyOn(m_keys.value(n), vel);
 }
 
-void PianoScene::keyOn( PianoKey* key )
+void PianoScene::showNoteOff( const int note, int vel )
 {
-    int n = m_baseOctave*12 + key->getNote() + m_transpose;
+    int n = note - m_baseOctave*12 - m_transpose;
+    if ((note >= m_minNote) && (note <= m_maxNote) && m_keys.contains(n))
+        showKeyOff(m_keys.value(n), vel);
+}
+
+void PianoScene::triggerNoteOn( const int note, const int vel )
+{
+    int n = m_baseOctave*12 + note + m_transpose;
     if ((n >= m_minNote) && (n <= m_maxNote)) {
         if (m_handler != NULL) {
-            m_handler->noteOn(n);
+            m_handler->noteOn(n, vel);
         } else {
-            emit noteOn(n);
+            emit noteOn(n, vel);
         }
-        showKeyOn(key);
     }
 }
 
-void PianoScene::keyOff( PianoKey* key )
+void PianoScene::triggerNoteOff( const int note, const int vel )
 {
-    int n = m_baseOctave*12 + key->getNote() + m_transpose;
+    int n = m_baseOctave*12 + note + m_transpose;
     if ((n >= m_minNote) && (n <= m_maxNote)) {
         if (m_handler != NULL) {
-            m_handler->noteOff(n);
+            m_handler->noteOff(n, vel);
         } else {
-            emit noteOff(n);
+            emit noteOff(n, vel);
         }
-        showKeyOff(key);
     }
 }
 
+void PianoScene::setColorFromPolicy(PianoKey* key, int vel)
+{
+    QColor c;
+#if defined(PALETTE_SUPPORT)
+    switch (m_palette->paletteId()) {
+    case PAL_SINGLE:
+        c = m_palette->getColor(0);
+        break;
+    case PAL_DOUBLE:
+        c = m_palette->getColor(key->getType());
+        break;
+    case PAL_CHANNELS:
+        c = m_palette->getColor(m_channel);
+        break;
+    case PAL_SCALE:
+        c = m_palette->getColor(key->getDegree());
+    }
+#else
+    c = QApplication::palette().highlight().color();
+#endif
+    if (m_velocityTint && c.isValid()) {
+        QBrush h(c.lighter(200 - vel));
+        key->setPressedBrush(h);
+    }
+}
+
+void PianoScene::keyOn( PianoKey* key )
+{
+    triggerNoteOn(key->getNote(), m_velocity);
+    showKeyOn(key, m_velocity);
+}
+
+void PianoScene::keyOff( PianoKey* key )
+{
+    triggerNoteOff(key->getNote(), 0);
+    showKeyOff(key, 0);
+}
+
+void PianoScene::keyOn( PianoKey* key, qreal pressure )
+{
+    int vel = m_velocity * pressure;
+    triggerNoteOn(key->getNote(), vel);
+    showKeyOn(key, vel);
+}
+
+void PianoScene::keyOff( PianoKey* key, qreal pressure )
+{
+    int vel = m_velocity * pressure;
+    triggerNoteOff(key->getNote(), vel);
+    showKeyOff(key, vel);
+}
+
 void PianoScene::keyOn(const int note)
 {
-    if (note >=0 && note < m_keys.size())
-        keyOn(m_keys[note]);
+    if (m_keys.contains(note))
+        keyOn(m_keys.value(note));
+    else
+        triggerNoteOn(note, m_velocity);
 }
 
 void PianoScene::keyOff(const int note)
 {
-    if (note >=0 && note < m_keys.size())
-        keyOff(m_keys[note]);
+    if (m_keys.contains(note))
+        keyOff(m_keys.value(note));
+    else
+        triggerNoteOff(note, m_velocity);
 }
 
 PianoKey* PianoScene::getKeyForPos( const QPointF& p ) const
 {
-    QGraphicsItem *itm = itemAt(p);
-    while (itm != NULL && itm->parentItem() != NULL)
-        itm = itm->parentItem();
-    if (itm != NULL) {
-        PianoKey* key = dynamic_cast<PianoKey*>(itm);
-        return key;
+    PianoKey* key = 0;
+    QList<QGraphicsItem *> ptitems = this->items(p, Qt::IntersectsItemShape, Qt::DescendingOrder);
+    foreach(QGraphicsItem *itm, ptitems) {
+        key = dynamic_cast<PianoKey*>(itm);
+        if (key != 0)
+            break;
     }
-    return NULL;
+    return key;
 }
 
 void PianoScene::mouseMoveEvent ( QGraphicsSceneMouseEvent * mouseEvent )
 {
-    if (m_mousePressed) {
-        PianoKey* key = getKeyForPos(mouseEvent->scenePos());
-        PianoKey* lastkey = getKeyForPos(mouseEvent->lastScenePos());
-        if ((lastkey != NULL) && (lastkey != key) && lastkey->isPressed()) {
-            keyOff(lastkey);
-        }
-        if ((key != NULL) && !key->isPressed()) { 
-            keyOn(key);
+    if (m_mouseEnabled) {
+        if (m_mousePressed) {
+            PianoKey* key = getKeyForPos(mouseEvent->scenePos());
+            PianoKey* lastkey = getKeyForPos(mouseEvent->lastScenePos());
+            if ((lastkey != NULL) && (lastkey != key) && lastkey->isPressed()) {
+                keyOff(lastkey);
+            }
+            if ((key != NULL) && !key->isPressed()) {
+                keyOn(key);
+            }
+            mouseEvent->accept();
+            return;
         }
-        mouseEvent->accept();
-        return;
     }
-    mouseEvent->ignore();
 }
 
 void PianoScene::mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent )
 {
-    PianoKey* key = getKeyForPos(mouseEvent->scenePos());
-    if (key != NULL) {
-        keyOn(key);
-        m_mousePressed = true;
-        mouseEvent->accept();
-        return;
+    if (m_mouseEnabled) {
+        PianoKey* key = getKeyForPos(mouseEvent->scenePos());
+        if (key != NULL && !key->isPressed()) {
+            keyOn(key);
+            m_mousePressed = true;
+            mouseEvent->accept();
+            return;
+        }
     }
-    mouseEvent->ignore();
 }
 
 void PianoScene::mouseReleaseEvent ( QGraphicsSceneMouseEvent * mouseEvent )
 {
-    m_mousePressed = false; 
-    PianoKey* key = getKeyForPos(mouseEvent->scenePos());
-    if (key != NULL) {
-        keyOff(key);
-        mouseEvent->accept();
-        return;
+    if (m_mouseEnabled) {
+        m_mousePressed = false;
+        PianoKey* key = getKeyForPos(mouseEvent->scenePos());
+        if (key != NULL && key->isPressed()) {
+            keyOff(key);
+            mouseEvent->accept();
+            return;
+        }
     }
-    mouseEvent->ignore();
 }
 
-PianoKey* PianoScene::getPianoKey( const int key ) const
+int PianoScene::getNoteFromKey( const int key ) const
 {
     if (m_keybdMap != NULL) {
         KeyboardMap::ConstIterator it = m_keybdMap->constFind(key);
         if ((it != m_keybdMap->constEnd()) && (it.key() == key)) {
             int note = it.value();
-            if (note < m_keys.size())
-                return m_keys[note];
+            return note;
         }
     }
+    return -1;
+}
+
+PianoKey* PianoScene::getPianoKey( const int key ) const
+{
+    int note = getNoteFromKey(key);
+    if (m_keys.contains(note))
+        return m_keys.value(note);
     return NULL;
 }
 
 void PianoScene::keyPressEvent ( QKeyEvent * keyEvent )
 {
-    if ( !m_rawkbd && !keyEvent->isAutoRepeat() ) { // ignore auto-repeats
-        PianoKey* key = getPianoKey(keyEvent->key());
-        if (key != NULL) {
-            keyOn(key);
+    if ( m_keyboardEnabled) {
+        if ( !m_rawkbd && !keyEvent->isAutoRepeat() ) { // ignore auto-repeats
+            int note = getNoteFromKey(keyEvent->key());
+            if (note > -1)
+                keyOn(note);
         }
+        keyEvent->accept();
+        return;
     }
-    keyEvent->accept();
+    keyEvent->ignore();
 }
 
 void PianoScene::keyReleaseEvent ( QKeyEvent * keyEvent )
 {
-    if ( !m_rawkbd && !keyEvent->isAutoRepeat() ) { // ignore auto-repeats
-        PianoKey* key = getPianoKey(keyEvent->key());
-        if (key != NULL) {
-            keyOff(key);
+    if (m_keyboardEnabled) {
+        if ( !m_rawkbd && !keyEvent->isAutoRepeat() ) { // ignore auto-repeats
+            int note = getNoteFromKey(keyEvent->key());
+            if (note > -1)
+                keyOff(note);
+        }
+        keyEvent->accept();
+        return;
+    }
+    keyEvent->ignore();
+}
+
+bool PianoScene::event(QEvent *event)
+{
+    switch(event->type()) {
+    case QEvent::TouchBegin:
+    case QEvent::TouchEnd:
+    case QEvent::TouchUpdate:
+    {
+        if (m_touchEnabled) {
+            QTouchEvent *touchEvent = static_cast<QTouchEvent*>(event);
+            QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
+            foreach(const QTouchEvent::TouchPoint& touchPoint, touchPoints) {
+                switch (touchPoint.state()) {
+                //case Qt::TouchPointPrimary:
+                case Qt::TouchPointStationary:
+                    continue;
+                case Qt::TouchPointReleased: {
+                        PianoKey* key = getKeyForPos(touchPoint.scenePos());
+                        if (key != NULL && key->isPressed()) {
+                            keyOff(key, touchPoint.pressure());
+                        }
+                        break;
+                    }
+                case Qt::TouchPointPressed: {
+                        PianoKey* key = getKeyForPos(touchPoint.scenePos());
+                        if (key != NULL && !key->isPressed()) {
+                            keyOn(key, touchPoint.pressure());
+                            key->ensureVisible();
+                        }
+                        break;
+                    }
+                case Qt::TouchPointMoved: {
+                        PianoKey* key = getKeyForPos(touchPoint.scenePos());
+                        PianoKey* lastkey = getKeyForPos(touchPoint.lastScenePos());
+                        if ((lastkey != NULL) && (lastkey != key) && lastkey->isPressed()) {
+                            keyOff(lastkey, touchPoint.pressure());
+                        }
+                        if ((key != NULL) && !key->isPressed()) {
+                            keyOn(key, touchPoint.pressure());
+                        }
+                        break;
+                    }
+                default:
+                    //qDebug() << "TouchPoint state: " << touchPoint.state();
+                    break;
+                }
+            }
+            //qDebug() << "accepted event: " << event;
+            event->accept();
+            return true;
         }
-    }   
-    keyEvent->accept();
+        break;
+    }
+    default:
+        break;
+    }
+    //qDebug() << "unprocessed event: " << event;
+    return QGraphicsScene::event(event);
 }
 
 void PianoScene::allKeysOff()
 {
-    QList<PianoKey*>::ConstIterator it; 
-    for(it = m_keys.constBegin(); it != m_keys.constEnd(); ++it) {
-        (*it)->setPressed(false);
+    foreach(PianoKey* key, m_keys) {
+        key->setPressed(false);
     }
 }
 
@@ -259,11 +431,17 @@ void PianoScene::setKeyPressedColor(const QColor& color)
     }
 }
 
+void PianoScene::resetKeyPressedColor()
+{
+    QBrush hilightBrush(m_keyPressedColor.isValid() ? m_keyPressedColor : QApplication::palette().highlight());
+    foreach(PianoKey* key, m_keys) {
+        key->setPressedBrush(hilightBrush);
+    }
+}
+
 void PianoScene::hideOrShowKeys()
 {
-    QListIterator<PianoKey*> it(m_keys);
-    while(it.hasNext()) {
-        PianoKey* key = it.next();
+    foreach(PianoKey* key, m_keys) {
         int n = m_baseOctave*12 + key->getNote() + m_transpose;
         bool b = !(n > m_maxNote) && !(n < m_minNote);
         key->setVisible(b);
@@ -297,23 +475,27 @@ void PianoScene::setBaseOctave(const int base)
 
 QString PianoScene::noteName(const int note)
 {
-    const QString m_names_s[] = {trUtf8("C"), trUtf8("C♯"), trUtf8("D"), trUtf8("D♯"), trUtf8("E"),
-                                 trUtf8("F"), trUtf8("F♯"), trUtf8("G"), trUtf8("G♯"),
-                                 trUtf8("A"), trUtf8("A♯"), trUtf8("B")};
-    const QString m_names_f[] = {trUtf8("C"), trUtf8("D♭"), trUtf8("D"), trUtf8("E♭"), trUtf8("E"),
-                                 trUtf8("F"), trUtf8("G♭"), trUtf8("G"), trUtf8("A♭"),
-                                 trUtf8("A"), trUtf8("B♭"), trUtf8("B")};
     int num = (note + m_transpose + 12) % 12;
-    int oct = m_baseOctave + ((note + m_transpose) / 12) - 1;
-    QString name = m_useFlats ? m_names_f[num] : m_names_s[num];
-    return QString("%1<span style='vertical-align:sub;'>%2</span>").arg(name).arg(oct);
+    int adj = (note + m_transpose < 0) ? 2 : 1;
+    int oct = m_baseOctave + ((note + m_transpose) / 12) - adj;
+    if (m_noteNames.isEmpty()) {
+        QString name;
+        if (!m_names_f.isEmpty() && !m_names_s.isEmpty())
+            name = m_useFlats ? m_names_f.value(num) : m_names_s.value(num);
+        return QString("%1<span style='vertical-align:sub;'>%2</span>").arg(name).arg(oct);
+    } else {
+        int noteIndex = note + m_transpose + 12*m_baseOctave;
+#if defined(SMALL_SCREEN)
+        return m_noteNames.value(noteIndex);
+#else
+        return QString("<span style='font-size:5pt;'>%1</span>").arg(m_noteNames.value(noteIndex));
+#endif
+    }
 }
 
 void PianoScene::refreshLabels()
 {
-    QListIterator<KeyLabel*> it(m_labels);
-    while(it.hasNext()) {
-        KeyLabel* lbl = it.next();
+    foreach(KeyLabel* lbl, m_labels) {
         PianoKey* key = dynamic_cast<PianoKey*>(lbl->parentItem());
         if(key != NULL) {
             lbl->setHtml(noteName(key->getNote()));
@@ -322,6 +504,21 @@ void PianoScene::refreshLabels()
     }
 }
 
+void PianoScene::refreshKeys()
+{
+    foreach(PianoKey* key, m_keys) {
+#if defined(PALETTE_SUPPORT)
+        if (m_showColorScale && m_scalePalette != 0) {
+            int degree = key->getNote() % 12;
+            key->setBrush(m_scalePalette->getColor(degree));
+        } else {
+            key->resetBrush();
+        }
+#endif
+        key->setPressed(false);
+    }
+}
+
 void PianoScene::setShowLabels(bool show)
 {
     if (m_showLabels != show) {
@@ -351,7 +548,87 @@ void PianoScene::setRawKeyboardMode(bool b)
 {
     if (m_rawkbd != b) {
         m_rawkbd = b;
-        RawKeybdApp* rapp = dynamic_cast<RawKeybdApp*>(qApp);
-        if (rapp != NULL) rapp->setRawKbdEnable(m_rawkbd);
     }
 }
+
+void PianoScene::useCustomNoteNames(const QStringList& names)
+{
+    m_noteNames = names;
+    refreshLabels();
+}
+
+void PianoScene::useStandardNoteNames()
+{
+    m_noteNames.clear();
+    refreshLabels();
+}
+
+void PianoScene::setKeyboardEnabled(const bool enable)
+{
+    if (enable != m_keyboardEnabled) {
+        m_keyboardEnabled = enable;
+    }
+}
+
+void PianoScene::setMouseEnabled(const bool enable)
+{
+    if (enable != m_mouseEnabled) {
+        m_mouseEnabled = enable;
+    }
+}
+
+void PianoScene::setTouchEnabled(const bool enable)
+{
+    if (enable != m_touchEnabled) {
+        m_touchEnabled = enable;
+    }
+}
+
+void PianoScene::retranslate()
+{
+    m_names_s.clear();
+    m_names_f.clear();
+    m_names_s << trUtf8("C")
+              << trUtf8("C♯")
+              << trUtf8("D")
+              << trUtf8("D♯")
+              << trUtf8("E")
+              << trUtf8("F")
+              << trUtf8("F♯")
+              << trUtf8("G")
+              << trUtf8("G♯")
+              << trUtf8("A")
+              << trUtf8("A♯")
+              << trUtf8("B");
+    m_names_f << trUtf8("C")
+              << trUtf8("D♭")
+              << trUtf8("D")
+              << trUtf8("E♭")
+              << trUtf8("E")
+              << trUtf8("F")
+              << trUtf8("G♭")
+              << trUtf8("G")
+              << trUtf8("A♭")
+              << trUtf8("A")
+              << trUtf8("B♭")
+              << trUtf8("B");
+    refreshLabels();
+}
+
+#if defined(PALETTE_SUPPORT)
+void PianoScene::setShowColorScale(const bool show)
+{
+    if (m_showColorScale != show && m_scalePalette != 0 ) {
+        m_showColorScale = show;
+        refreshKeys();
+        invalidate();
+    }
+}
+
+void PianoScene::setPianoPalette(PianoPalette *p)
+{
+    //qDebug() << Q_FUNC_INFO;
+    resetKeyPressedColor();
+    m_palette = p;
+}
+#endif
diff --git a/utils/vpiano/pianoscene.h b/utils/vpiano/pianoscene.h
index c1aab13..a1a5143 100644
--- a/utils/vpiano/pianoscene.h
+++ b/utils/vpiano/pianoscene.h
@@ -1,10 +1,10 @@
 /*
-    Virtual Piano Widget for Qt4 
-    Copyright (C) 2008-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Virtual Piano Widget for Qt5
+    Copyright (C) 2008-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
+    the Free Software Foundation; either version 3 of the License, or
     (at your option) any later version.
 
     This program is distributed in the hope that it will be useful,
@@ -22,6 +22,10 @@
 #include "pianokey.h"
 #include "keylabel.h"
 #include "keyboardmap.h"
+#if defined(PALETTE_SUPPORT)
+#include "pianopalette.h"
+#endif
+
 #include <QGraphicsScene>
 #include <QHash>
 
@@ -29,8 +33,8 @@ class PianoHandler
 {
 public:
     virtual ~PianoHandler() {}
-    virtual void noteOn( const int note ) = 0;
-    virtual void noteOff( const int note ) = 0;
+    virtual void noteOn( const int note, const int vel ) = 0;
+    virtual void noteOff( const int note, const int vel ) = 0;
 };
 
 class VPIANO_EXPORT PianoScene : public QGraphicsScene
@@ -39,7 +43,8 @@ class VPIANO_EXPORT PianoScene : public QGraphicsScene
     
 public:
     PianoScene ( const int baseOctave, 
-                 const int numOctaves,
+                 const int numKeys,
+                 const int startKey,
                  const QColor& keyPressedColor = QColor(),
                  QObject * parent = 0 );
     
@@ -48,8 +53,18 @@ public:
     KeyboardMap* getKeyboardMap() const { return m_keybdMap; }
     PianoHandler* getPianoHandler() const { return m_handler; }
     void setPianoHandler(PianoHandler* handler) { m_handler = handler; }
+
+#if defined(PALETTE_SUPPORT)
+    PianoPalette* getPianoPalette() const { return m_palette; }
+    void setPianoPalette( PianoPalette* p );
+    void setColorScalePalette( PianoPalette* p ) { m_scalePalette = p; }
+    bool showColorScale() const { return m_showColorScale; }
+    void setShowColorScale(const bool show);
+#endif
+
     QColor getKeyPressedColor() const { return m_keyPressedColor; }
     void setKeyPressedColor(const QColor& color);
+    void resetKeyPressedColor();
     int getMinNote() const { return m_minNote; } 
     void setMinNote(const int note);
     int getMaxNote() const { return m_maxNote; }
@@ -60,55 +75,96 @@ public:
     void setShowLabels(const bool show);
     bool useFlats() const { return m_useFlats; }
     void setUseFlats(const bool use);
+    bool isKeyboardEnabled() const { return m_keyboardEnabled; }
+    void setKeyboardEnabled( const bool enable );
+    bool isMouseEnabled() const { return m_mouseEnabled; }
+    void setMouseEnabled( const bool enable );
+    bool isTouchEnabled() const { return m_touchEnabled; }
+    void setTouchEnabled( const bool enable );
+    bool velocityTint() const { return m_velocityTint; }
+    void setVelocityTint( const bool enable ) { m_velocityTint = enable; }
 
-    void showNoteOn( const int note );
-    void showNoteOff( const int note );
+    void showNoteOn( const int note, QColor color, int vel = -1 );
+    void showNoteOn( const int note, int vel = -1 );
+    void showNoteOff( const int note, int vel = -1 );
     int baseOctave() const { return m_baseOctave; }
     void setBaseOctave( const int base );
-    int numOctaves() const { return m_numOctaves; }
+    int numKeys() const { return m_numKeys; }
+    int startKey() const { return m_startKey; }
     void allKeysOff();
     void keyOn( const int note );
     void keyOff( const int note );
     bool getRawKeyboardMode() const { return m_rawkbd; }
     void setRawKeyboardMode(const bool b);
+    void useCustomNoteNames(const QStringList& names);
+    void useStandardNoteNames();
+    int getVelocity() { return m_velocity; }
+    void setVelocity(const int velocity) { m_velocity = velocity; }
+    int getChannel() const { return m_channel; }
+    void setChannel(const int channel) { m_channel = channel; }
+    void retranslate();
+    QStringList noteNames() const { return m_names_s; }
 
 signals:
-    void noteOn(int n);
-    void noteOff(int n);
+    void noteOn(int n, int v);
+    void noteOff(int n, int v);
 
 protected:
-    void showKeyOn( PianoKey* key );
-    void showKeyOff( PianoKey* key );
+    void showKeyOn( PianoKey* key, QColor color, int vel );
+    void showKeyOn( PianoKey* key, int vel );
+    void showKeyOff( PianoKey* key, int vel );
     void keyOn( PianoKey* key );
     void keyOff( PianoKey* key );
+    void keyOn( PianoKey* key, qreal pressure );
+    void keyOff( PianoKey* key, qreal pressure );
     PianoKey* getKeyForPos( const QPointF& p ) const;
     PianoKey* getPianoKey( const int key ) const;
     QString noteName(const int note);
-
     void mouseMoveEvent ( QGraphicsSceneMouseEvent * mouseEvent );
     void mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent );
     void mouseReleaseEvent ( QGraphicsSceneMouseEvent * mouseEvent );
     void keyPressEvent ( QKeyEvent * keyEvent );
     void keyReleaseEvent ( QKeyEvent * keyEvent );
+    bool event(QEvent *event);
 
 private:
     void hideOrShowKeys();
     void refreshLabels();
-    
+    void refreshKeys();
+    void triggerNoteOn( const int note, const int vel );
+    void triggerNoteOff( const int note, const int vel );
+    int getNoteFromKey( const int key ) const;
+    void setColorFromPolicy(PianoKey* key, const int vel);
+
     int m_baseOctave;
-    int m_numOctaves;
+    int m_numKeys;
+    int m_startKey;
     int m_minNote;
     int m_maxNote;
     int m_transpose;
     bool m_showLabels;
     bool m_useFlats;
     bool m_rawkbd;
+    bool m_keyboardEnabled;
+    bool m_mouseEnabled;
+    bool m_touchEnabled;
     QColor m_keyPressedColor;
     bool m_mousePressed;
+    int m_velocity;
+    int m_channel;
+    bool m_velocityTint;
     PianoHandler* m_handler;
     KeyboardMap* m_keybdMap;
-    QList<PianoKey*> m_keys;
-    QList<KeyLabel*> m_labels;
+    QHash<int, PianoKey*> m_keys;
+    QMap<int, KeyLabel*> m_labels;
+    QStringList m_noteNames;
+    QStringList m_names_s;
+    QStringList m_names_f;
+#if defined(PALETTE_SUPPORT)
+    bool m_showColorScale;
+    PianoPalette* m_palette;
+    PianoPalette* m_scalePalette;
+#endif
 };
 
 #endif /*PIANOSCENE_H_*/
diff --git a/utils/vpiano/preferences.cpp b/utils/vpiano/preferences.cpp
index d5249ea..58ecd8e 100644
--- a/utils/vpiano/preferences.cpp
+++ b/utils/vpiano/preferences.cpp
@@ -1,6 +1,6 @@
 /*
     Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -26,8 +26,9 @@ Preferences::Preferences(QWidget *parent)
     m_inChannel(0),
     m_outChannel(0),
     m_velocity(100),
-    m_baseOctave(4),
-    m_numOctaves(5)
+    m_baseOctave(1),
+    m_numKeys(88),
+    m_startingKey(9)
 {
     ui.setupUi( this );
     connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), SLOT(slotButtonClicked(QAbstractButton*)));
@@ -47,7 +48,8 @@ void Preferences::showEvent ( QShowEvent *event )
         ui.spinOutChan->setValue( m_outChannel );
         ui.spinVelocity->setValue( m_velocity );
         ui.spinBaseOctave->setValue( m_baseOctave );
-        ui.spinNumOctaves->setValue( m_numOctaves );
+        ui.spinNumKeys->setValue( m_numKeys );
+        ui.comboNotes->setCurrentIndex( m_startingKey );
     }
 }
 
@@ -57,7 +59,8 @@ void Preferences::apply()
     m_outChannel = ui.spinOutChan->value();
     m_velocity = ui.spinVelocity->value();
     m_baseOctave = ui.spinBaseOctave->value();
-    m_numOctaves = ui.spinNumOctaves->value();
+    m_numKeys = ui.spinNumKeys->value();
+    m_startingKey = ui.comboNotes->currentIndex();
 }
 
 void Preferences::accept()
@@ -65,3 +68,39 @@ void Preferences::accept()
     apply();
     QDialog::accept();
 }
+
+void Preferences::setInChannel(const int chan)
+{
+    m_inChannel = chan;
+    ui.spinInChan->setValue(m_inChannel);
+}
+
+void Preferences::setOutChannel(const int chan)
+{
+    m_outChannel = chan;
+    ui.spinOutChan->setValue(m_outChannel);
+}
+
+void Preferences::setVelocity(const int vel)
+{
+    m_velocity = vel;
+    ui.spinVelocity->setValue(m_velocity);
+}
+
+void Preferences::setBaseOctave(const int octave)
+{
+    m_baseOctave = octave;
+    ui.spinBaseOctave->setValue(m_baseOctave);
+}
+
+void Preferences::setNumKeys(const int keys)
+{
+    m_numKeys = keys;
+    ui.spinNumKeys->setValue(m_numKeys);
+}
+
+void Preferences::setStartingKey(const int key)
+{
+    m_startingKey = key;
+    ui.comboNotes->setCurrentIndex(m_startingKey);
+}
diff --git a/utils/vpiano/preferences.h b/utils/vpiano/preferences.h
index b4fef8a..e764d0d 100644
--- a/utils/vpiano/preferences.h
+++ b/utils/vpiano/preferences.h
@@ -1,6 +1,6 @@
 /*
     Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This library is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 #ifndef PREFERENCES_H
 #define PREFERENCES_H
 
-#include <QtGui/QDialog>
+#include <QDialog>
 #include "ui_preferences.h"
 
 class Preferences : public QDialog
@@ -29,11 +29,21 @@ class Preferences : public QDialog
 
 public:
     Preferences(QWidget *parent = 0);
+
+    void setInChannel(const int chan);
+    void setOutChannel(const int chan);
+    void setVelocity(const int vel);
+    void setBaseOctave(const int octave);
+    void setNumKeys(const int keys);
+    void setStartingKey(const int key);
+
     int getInChannel() const { return m_inChannel; }
     int getOutChannel() const { return m_outChannel; }
     int getVelocity() const { return m_velocity; }
     int getBaseOctave() const { return m_baseOctave; }
-    int getNumOctaves() const { return m_numOctaves; }
+    int getNumKeys() const { return m_numKeys; }
+    int getStartingKey() const { return m_startingKey; }
+
     void apply();
 
 public slots:
@@ -49,7 +59,8 @@ private:
     int m_outChannel;
     int m_velocity;
     int m_baseOctave;
-    int m_numOctaves;
+    int m_numKeys;
+    int m_startingKey;
 };
 
 #endif // PREFERENCES_H
diff --git a/utils/vpiano/preferences.ui b/utils/vpiano/preferences.ui
index 325e776..9a04159 100644
--- a/utils/vpiano/preferences.ui
+++ b/utils/vpiano/preferences.ui
@@ -1,155 +1,248 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>PreferencesClass</class>
- <widget class="QDialog" name="PreferencesClass" >
-  <property name="geometry" >
+ <widget class="QDialog" name="PreferencesClass">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>270</width>
-    <height>242</height>
+    <height>213</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string>Preferences</string>
   </property>
-  <layout class="QGridLayout" >
-   <item row="0" column="0" colspan="2" >
-    <widget class="QLabel" name="lblInChan" >
-     <property name="sizePolicy" >
-      <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
+  <layout class="QGridLayout">
+   <item row="2" column="2">
+    <widget class="QSpinBox" name="spinVelocity">
+     <property name="maximum">
+      <number>127</number>
      </property>
-     <property name="text" >
-      <string>Input Channel</string>
-     </property>
-     <property name="buddy" >
-      <cstring>spinInChan</cstring>
+     <property name="value">
+      <number>100</number>
      </property>
     </widget>
    </item>
-   <item row="0" column="2" >
-    <widget class="QSpinBox" name="spinInChan" >
-     <property name="maximum" >
+   <item row="0" column="2">
+    <widget class="QSpinBox" name="spinInChan">
+     <property name="maximum">
       <number>15</number>
      </property>
     </widget>
    </item>
-   <item row="1" column="0" colspan="2" >
-    <widget class="QLabel" name="lblOutChan" >
-     <property name="sizePolicy" >
-      <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+   <item row="1" column="0" colspan="2">
+    <widget class="QLabel" name="lblOutChan">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
-     <property name="text" >
+     <property name="text">
       <string>Output Channel</string>
      </property>
-     <property name="buddy" >
+     <property name="buddy">
       <cstring>spinOutChan</cstring>
      </property>
     </widget>
    </item>
-   <item row="1" column="2" >
-    <widget class="QSpinBox" name="spinOutChan" >
-     <property name="maximum" >
-      <number>15</number>
+   <item row="3" column="2">
+    <widget class="QSpinBox" name="spinBaseOctave">
+     <property name="minimum">
+      <number>0</number>
+     </property>
+     <property name="maximum">
+      <number>9</number>
      </property>
     </widget>
    </item>
-   <item row="2" column="0" colspan="2" >
-    <widget class="QLabel" name="lblVelocity" >
-     <property name="sizePolicy" >
-      <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+   <item row="4" column="0" colspan="2">
+    <widget class="QLabel" name="lblNumKeys">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
-     <property name="text" >
+     <property name="text">
+      <string>Number of keys</string>
+     </property>
+     <property name="buddy">
+      <cstring>spinNumKeys</cstring>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0" colspan="2">
+    <widget class="QLabel" name="lblVelocity">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="text">
       <string>Velocity</string>
      </property>
-     <property name="buddy" >
+     <property name="buddy">
       <cstring>spinVelocity</cstring>
      </property>
     </widget>
    </item>
-   <item row="2" column="2" >
-    <widget class="QSpinBox" name="spinVelocity" >
-     <property name="maximum" >
-      <number>127</number>
+   <item row="0" column="0" colspan="2">
+    <widget class="QLabel" name="lblInChan">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="text">
+      <string>Input Channel</string>
+     </property>
+     <property name="buddy">
+      <cstring>spinInChan</cstring>
      </property>
     </widget>
    </item>
-   <item row="3" column="0" colspan="2" >
-    <widget class="QLabel" name="lblBaseOctave" >
-     <property name="sizePolicy" >
-      <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+   <item row="6" column="0" colspan="4">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="0" colspan="2">
+    <widget class="QLabel" name="lblBaseOctave">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
-     <property name="text" >
+     <property name="text">
       <string>Base octave</string>
      </property>
-     <property name="buddy" >
+     <property name="buddy">
       <cstring>spinBaseOctave</cstring>
      </property>
     </widget>
    </item>
-   <item row="3" column="2" >
-    <widget class="QSpinBox" name="spinBaseOctave" >
-     <property name="minimum" >
-      <number>0</number>
+   <item row="1" column="2">
+    <widget class="QSpinBox" name="spinOutChan">
+     <property name="maximum">
+      <number>15</number>
      </property>
-     <property name="maximum" >
-      <number>9</number>
+    </widget>
+   </item>
+   <item row="4" column="2">
+    <widget class="QSpinBox" name="spinNumKeys">
+     <property name="minimum">
+      <number>12</number>
+     </property>
+     <property name="maximum">
+      <number>120</number>
+     </property>
+     <property name="value">
+      <number>88</number>
      </property>
     </widget>
    </item>
-   <item row="4" column="0" colspan="2" >
-    <widget class="QLabel" name="lblNumOctaves" >
-     <property name="sizePolicy" >
-      <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+   <item row="5" column="0">
+    <widget class="QLabel" name="lblStartingKey">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
-     <property name="text" >
-      <string>Number of octaves</string>
+     <property name="text">
+      <string>Starting Key</string>
      </property>
-     <property name="buddy" >
-      <cstring>spinNumOctaves</cstring>
+     <property name="buddy">
+      <cstring>comboNotes</cstring>
      </property>
     </widget>
    </item>
-   <item row="4" column="2" >
-    <widget class="QSpinBox" name="spinNumOctaves" >
-     <property name="minimum" >
-      <number>1</number>
-     </property>
-     <property name="maximum" >
-      <number>9</number>
+   <item row="5" column="2">
+    <widget class="QComboBox" name="comboNotes">
+     <property name="currentIndex">
+      <number>5</number>
      </property>
-    </widget>
-   </item>
-   <item row="5" column="0" colspan="4" >
-    <widget class="QDialogButtonBox" name="buttonBox" >
-     <property name="standardButtons" >
-      <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+     <property name="maxVisibleItems">
+      <number>12</number>
      </property>
+     <item>
+      <property name="text">
+       <string>C</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>C#</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>D</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>D#</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>E</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>F</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>F#</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>G</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>G#</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>A</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>A#</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>B</string>
+      </property>
+     </item>
     </widget>
    </item>
   </layout>
  </widget>
- <layoutdefault spacing="6" margin="11" />
+ <layoutdefault spacing="6" margin="11"/>
  <tabstops>
   <tabstop>spinInChan</tabstop>
   <tabstop>spinOutChan</tabstop>
   <tabstop>spinVelocity</tabstop>
   <tabstop>spinBaseOctave</tabstop>
-  <tabstop>spinNumOctaves</tabstop>
+  <tabstop>spinNumKeys</tabstop>
   <tabstop>buttonBox</tabstop>
  </tabstops>
  <resources/>
@@ -160,11 +253,11 @@
    <receiver>PreferencesClass</receiver>
    <slot>accept()</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>228</x>
-     <y>185</y>
+    <hint type="sourcelabel">
+     <x>237</x>
+     <y>412</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>263</x>
      <y>11</y>
     </hint>
@@ -176,11 +269,11 @@
    <receiver>PreferencesClass</receiver>
    <slot>reject()</slot>
    <hints>
-    <hint type="sourcelabel" >
-     <x>118</x>
-     <y>179</y>
+    <hint type="sourcelabel">
+     <x>127</x>
+     <y>412</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>155</x>
      <y>14</y>
     </hint>
diff --git a/utils/vpiano/rawkeybdapp.cpp b/utils/vpiano/rawkeybdapp.cpp
deleted file mode 100644
index 7209d34..0000000
--- a/utils/vpiano/rawkeybdapp.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-    Virtual Piano Widget for Qt4
-    Copyright (C) 2008-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "rawkeybdapp.h"
-//#include <QDebug>
-
-#if defined(Q_WS_X11)
-#include <QX11Info>
-#include <X11/Xlib.h>
-struct qt_auto_repeat_data
-{
-    // match the window and keycode with timestamp delta of 10 ms
-    Window window;
-    KeyCode keycode;
-    Time timestamp;
-    // queue scanner state
-    bool release;
-    bool error;
-};
-
-#if defined(Q_C_CALLBACKS)
-extern "C" {
-#endif
-
-static Bool qt_keypress_scanner(Display *, XEvent *event, XPointer arg)
-{
-    if (event->type != KeyPress && event->type != KeyRelease)
-        return false;
-    qt_auto_repeat_data *data = (qt_auto_repeat_data *) arg;
-    if (data->error)
-        return false;
-    if (event->xkey.window  != data->window ||
-        event->xkey.keycode != data->keycode) {
-        // deal breakers: key events in a different window or an event
-        // with a different key code
-        data->error = true;
-        return false;
-    }
-    if (event->type == KeyPress) {
-        data->error = (! data->release || event->xkey.time - data->timestamp > 10);
-        return (! data->error);
-    }
-    // must be XKeyRelease event
-    if (data->release) {
-        // found a second release
-        data->error = true;
-        return false;
-    }
-    // found a single release
-    data->release = true;
-    data->timestamp = event->xkey.time;
-    return false;
-}
-
-#if defined(Q_C_CALLBACKS)
-}
-#endif
-
-bool RawKeybdApp::x11EventFilter ( XEvent * event )
-{
-    if ( m_enabled && m_handler != NULL && (event->type == KeyPress || event->type == KeyRelease )) {
-        bool autorepeat = false;
-        Display *dpy =  QX11Info::display();
-        // was this the last auto-repeater?
-        qt_auto_repeat_data auto_repeat_data;
-        auto_repeat_data.window = event->xkey.window;
-        auto_repeat_data.keycode = event->xkey.keycode;
-        auto_repeat_data.timestamp = event->xkey.time;
-        static uint curr_autorep = 0;
-        if (event->type == KeyPress) {
-            if (curr_autorep == event->xkey.keycode) {
-                autorepeat = true;
-                curr_autorep = 0;
-            }
-        } else {
-            // look ahead for auto-repeat
-            XEvent nextpress;
-            auto_repeat_data.release = true;
-            auto_repeat_data.error = false;
-            autorepeat = XCheckIfEvent( dpy, &nextpress, &qt_keypress_scanner,
-                                        (XPointer) &auto_repeat_data );
-            curr_autorep = autorepeat ? event->xkey.keycode : 0;
-        }
-        if (!autorepeat) {
-            if (event->type == KeyPress)
-                return m_handler->handleKeyPressed(event->xkey.keycode);
-            else
-                return m_handler->handleKeyReleased(event->xkey.keycode);
-        }
-        return true;
-    }
-    return false;
-}
-#endif
-
-#if defined(Q_WS_WIN)
-#include <windows.h>
-/* http://msdn.microsoft.com/en-us/library/ms646280(VS.85).aspx */
-bool RawKeybdApp::winEventFilter ( MSG * msg, long * result )
-{
-    if ( m_enabled && m_handler != NULL && (msg->message == WM_KEYDOWN || msg->message == WM_KEYUP )) {
-        int keycode = HIWORD(msg->lParam) & 0xff;
-        bool autorepeat = (msg->message == WM_KEYDOWN) &&
-                          ((HIWORD(msg->lParam) & 0x4000) != 0);
-        if (!autorepeat) {
-            if ( msg->message == WM_KEYDOWN )
-                return m_handler->handleKeyPressed(keycode);
-            else
-                return m_handler->handleKeyReleased(keycode);
-        }
-        return true;
-    }
-    return false;
-}
-#endif
-
-#if defined(Q_WS_MAC)
-#include <Carbon/Carbon.h>
-bool RawKeybdApp::macEventFilter( EventHandlerCallRef caller, EventRef event )
-{
-    if (m_enabled && m_handler != NULL && GetEventClass(event) == kEventClassKeyboard) {
-        UInt32 ekind = GetEventKind(event);
-        if (ekind == kEventRawKeyUp || ekind == kEventRawKeyDown) {
-            UInt32 keyCode = 0;
-            GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(keyCode), 0, &keyCode);
-            if ( ekind == kEventRawKeyDown )
-                return m_handler->handleKeyPressed(keyCode);
-            else
-                return m_handler->handleKeyReleased(keyCode);
-        }
-        return true;
-    }
-    return false;
-}
-#endif  // Q_WS_MAC
diff --git a/utils/vpiano/rawkeybdapp.h b/utils/vpiano/rawkeybdapp.h
deleted file mode 100644
index ec70c35..0000000
--- a/utils/vpiano/rawkeybdapp.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-    Virtual Piano Widget for Qt4
-    Copyright (C) 2008-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef RAWKEYBDAPP_H
-#define RAWKEYBDAPP_H
-
-#include "pianodefs.h"
-#include <QApplication>
-
-class RawKbdHandler {
-public:
-    virtual ~RawKbdHandler() {}
-    virtual bool handleKeyPressed(int keycode) = 0;
-    virtual bool handleKeyReleased(int keycode) = 0;
-};
-
-class VPIANO_EXPORT RawKeybdApp : public QApplication
-{
-public:
-    RawKeybdApp( int & argc, char ** argv ) : QApplication(argc, argv),
-        m_enabled(false), m_handler(NULL) {}
-    virtual ~RawKeybdApp() {}
-
-    RawKbdHandler *getRawKbdHandler() { return m_handler; }
-    void setRawKbdHandler(RawKbdHandler* h) { m_handler = h; }
-    bool getRawKbdEnable() { return m_enabled; }
-    void setRawKbdEnable(bool b) { m_enabled = b; }
-
-#if defined(Q_WS_X11)
-    bool x11EventFilter ( XEvent * event );
-#endif
-
-#if defined(Q_WS_MAC)
-    bool macEventFilter ( EventHandlerCallRef caller, EventRef event );
-#endif
-
-#if defined(Q_WS_WIN)
-    bool winEventFilter ( MSG * msg, long * result );
-#endif
-
-private:
-    bool m_enabled;
-    RawKbdHandler *m_handler;
-};
-
-#endif // RAWKEYBDAPP_H
diff --git a/utils/vpiano/vpiano.cpp b/utils/vpiano/vpiano.cpp
index 6f39bb1..1e1e190 100644
--- a/utils/vpiano/vpiano.cpp
+++ b/utils/vpiano/vpiano.cpp
@@ -1,6 +1,6 @@
 /*
     Virtual Piano test using the MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -19,139 +19,113 @@
 
 #include <QDebug>
 #include "vpiano.h"
+#include "backendmanager.h"
 
 VPiano::VPiano( QWidget * parent, Qt::WindowFlags flags )
     : QMainWindow(parent, flags),
-    m_portId(-1),
-    m_Client(0),
-    m_Port(0)
+    m_midiIn(0),
+    m_midiOut(0)
 {
+    QString nativeBackend;
+#if defined(Q_OS_LINUX)
+    nativeBackend = QLatin1Literal("ALSA");
+#elif defined(Q_OS_OSX)
+    nativeBackend = QLatin1Literal("CoreMIDI");
+#elif defined(Q_OS_WIN)
+    nativeBackend = QLatin1Literal("Windows MM");
+#else
+    nativeBackend = QLatin1Literal("Network");
+#endif
+
     ui.setupUi(this);
     ui.statusBar->hide();
-    ui.pianokeybd->setRawKeyboardMode(true);
 
-    m_Client = new MidiClient(this);
-    m_Client->open();
-    m_Client->setClientName("Virtual Piano");
+    readSettings();
 
-#ifdef USE_QEVENTS
-    m_Client->addListener(this);
-    m_Client->setEventsEnabled(true);
-#else // USE_QEVENTS (using signals instead)
-    connect( m_Client, SIGNAL(eventReceived(SequencerEvent*)),
-             SLOT(sequencerEvent(SequencerEvent*)), Qt::QueuedConnection );
-#endif // USE_QEVENTS
+    QSettings settings;
+    BackendManager man;
+    man.refresh(&settings);
+    QList<MIDIInput*> inputs = man.availableInputs();
+    QList<MIDIOutput*> outputs = man.availableOutputs();
 
-    m_Port = new MidiPort(this);
-    m_Port->attach( m_Client );
-    m_Port->setPortName("Virtual Piano");
-    m_Port->setCapability( SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ |
-                           SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE );
-    m_Port->setPortType( SND_SEQ_PORT_TYPE_APPLICATION );
+    findInput(m_lastInputBackend, inputs);
+    if (m_midiIn == 0) {
+        findInput(nativeBackend, inputs);
+    }
 
-    m_portId = m_Port->getPortId();
+    findOutput(m_lastOutputBackend, outputs);
+    if (m_midiOut == 0) {
+        findOutput(nativeBackend, outputs);
+    }
 
     connect(ui.actionExit, SIGNAL(triggered()), qApp, SLOT(quit()));
     connect(ui.actionAbout, SIGNAL(triggered()), SLOT(slotAbout()));
     connect(ui.actionAbout_Qt, SIGNAL(triggered()), SLOT(slotAboutQt()));
     connect(ui.actionConnections, SIGNAL(triggered()), SLOT(slotConnections()));
     connect(ui.actionPreferences, SIGNAL(triggered()), SLOT(slotPreferences()));
-    connect(ui.pianokeybd, SIGNAL(noteOn(int)), SLOT(slotNoteOn(int)));
-    connect(ui.pianokeybd, SIGNAL(noteOff(int)), SLOT(slotNoteOff(int)));
-    connect(m_Port, SIGNAL(subscribed(MidiPort*,Subscription*)), SLOT(slotSubscription(MidiPort*,Subscription*)));
+    connect(ui.pianokeybd, SIGNAL(noteOn(int,int)), SLOT(slotNoteOn(int,int)));
+    connect(ui.pianokeybd, SIGNAL(noteOff(int,int)), SLOT(slotNoteOff(int,int)));
+
+    dlgConnections.setInputs(inputs);
+    dlgConnections.setOutputs(outputs);
+    dlgConnections.setInput(m_midiIn);
+    dlgConnections.setOutput(m_midiOut);
+    dlgConnections.setMidiThru(m_midiThru);
+    dlgConnections.setAdvanced(m_advanced);
+
+    if (m_midiIn != 0) {
+        connect(m_midiIn, SIGNAL(midiNoteOn(int,int,int)), SLOT(slotNoteOn(int,int,int)));
+        connect(m_midiIn, SIGNAL(midiNoteOff(int,int,int)), SLOT(slotNoteOff(int,int,int)));
+        if (!m_lastInputConnection.isEmpty()) {
+            m_midiIn->initialize(&settings);
+            m_midiIn->open(m_lastInputConnection);
+        }
+    }
 
-    m_Port->subscribeFromAnnounce();
-    m_Client->setRealTimeInput(false);
-    m_Client->startSequencerInput();
+    if (m_midiOut != 0 && !m_lastOutputConnection.isEmpty()) {
+        m_midiOut->initialize(&settings);
+        m_midiOut->open(m_lastOutputConnection);
+        m_midiIn->setMIDIThruDevice(m_midiOut);
+        m_midiIn->enableMIDIThru(m_midiThru);
+    }
 }
 
 VPiano::~VPiano()
 {
-    m_Client->stopSequencerInput();
-    m_Port->detach();
-    m_Client->close();
+    m_midiIn->close();
+    m_midiOut->close();
     qDebug() << "Cheers!";
 }
 
-void VPiano::slotNoteOn(const int midiNote)
+void VPiano::slotNoteOn(const int midiNote, const int vel)
 {
     int chan = dlgPreferences.getOutChannel();
-    int vel = dlgPreferences.getVelocity();
-    NoteOnEvent ev(chan, midiNote, vel);
-    ev.setSource(m_portId);
-    ev.setSubscribers();
-    ev.setDirect();
-    m_Client->outputDirect(&ev);
+    m_midiOut->sendNoteOn(chan, midiNote, vel);
 }
 
-void VPiano::slotNoteOff(const int midiNote)
+void VPiano::slotNoteOff(const int midiNote, const int vel)
 {
     int chan = dlgPreferences.getOutChannel();
-    int vel = dlgPreferences.getVelocity();
-    NoteOffEvent ev(chan, midiNote, vel);
-    ev.setSource(m_portId);
-    ev.setSubscribers();
-    ev.setDirect();
-    m_Client->outputDirect(&ev);
+    m_midiOut->sendNoteOff(chan, midiNote, vel);
 }
 
-void VPiano::displayEvent(SequencerEvent *ev)
+void VPiano::slotNoteOn(const int chan, const int note, const int vel)
 {
-    try {
-        switch (ev->getSequencerType()) {
-        case SND_SEQ_EVENT_NOTEON: {
-            NoteOnEvent* e = static_cast<NoteOnEvent*>(ev);
-            if ((e != NULL) && (dlgPreferences.getInChannel() == e->getChannel())) {
-                int note = e->getKey();
-                if (e->getVelocity() == 0)
-                    ui.pianokeybd->showNoteOff(note);
-                else
-                    ui.pianokeybd->showNoteOn(note);
-                //qDebug() << "NoteOn" << note;
-            }
-            break;
-        }
-        case SND_SEQ_EVENT_NOTEOFF: {
-            NoteOffEvent* e = static_cast<NoteOffEvent*>(ev);
-            if ((e != NULL) && (dlgPreferences.getInChannel() == e->getChannel())) {
-                int note = e->getKey();
-                ui.pianokeybd->showNoteOff(note);
-                //qDebug() << "NoteOff" << note;
-            }
-            break;
-        }
-        default:
-            break;
-        }
-    } catch (SequencerError& err) {
-        qWarning() << "SequencerError exception. Error code: " << err.code()
-                   << " (" << err.qstrError() << ")";
-        qWarning() << "Location: " << err.location();
-        throw err;
+    //Q_UNUSED(vel)
+    if (dlgPreferences.getInChannel() == chan) {
+        if (vel > 0)
+            ui.pianokeybd->getPianoScene()->showNoteOn(note);
+        else
+            ui.pianokeybd->getPianoScene()->showNoteOff(note);
     }
 }
 
-#ifdef USE_QEVENTS
-void VPiano::customEvent(QEvent *ev)
-{
-    if ( (ev == 0) || (ev->type() != SequencerEventType) )
-        return;
-    SequencerEvent* sev = static_cast<SequencerEvent*>(ev);
-    displayEvent (sev);
-}
-#else
-void
-VPiano::sequencerEvent(SequencerEvent *ev)
-{
-    displayEvent (ev);
-    delete ev;
-}
-#endif
-
-void VPiano::slotSubscription(MidiPort*, Subscription* subs)
+void VPiano::slotNoteOff(const int chan, const int note, const int vel)
 {
-    qDebug() << "Subscription made with" << subs->getSender()->client
-             << ":" << subs->getSender()->port;
+    Q_UNUSED(vel)
+    if (dlgPreferences.getInChannel() == chan) {
+        ui.pianokeybd->getPianoScene()->showNoteOff(note);
+    }
 }
 
 void VPiano::slotAbout()
@@ -166,14 +140,22 @@ void VPiano::slotAboutQt()
 
 void VPiano::slotConnections()
 {
-    m_Port->updateSubscribers();
-    dlgConnections.setInputs(m_Client->getAvailableInputs(),
-                             m_Port->getWriteSubscribers());
-    dlgConnections.setOutputs(m_Client->getAvailableOutputs(),
-                              m_Port->getReadSubscribers());
+    dlgConnections.refresh();
     if (dlgConnections.exec() == QDialog::Accepted) {
-        m_Port->updateConnectionsFrom(dlgConnections.getSelectedInputPorts());
-        m_Port->updateConnectionsTo(dlgConnections.getSelectedOutputPorts());
+        if (m_midiIn != 0) {
+            m_midiIn->disconnect();
+        }
+        if (m_midiOut != 0) {
+            m_midiOut->disconnect();
+        }
+        m_midiIn = dlgConnections.getInput();
+        m_midiOut = dlgConnections.getOutput();
+        if (m_midiIn != 0) {
+            connect(m_midiIn, SIGNAL(midiNoteOn(int,int,int)), SLOT(slotNoteOn(int,int,int)));
+            connect(m_midiIn, SIGNAL(midiNoteOff(int,int,int)), SLOT(slotNoteOff(int,int,int)));
+        }
+        m_midiThru = dlgConnections.midiThru();
+        m_advanced = dlgConnections.advanced();
     }
 }
 
@@ -183,8 +165,97 @@ void VPiano::slotPreferences()
         if (ui.pianokeybd->baseOctave() != dlgPreferences.getBaseOctave()) {
             ui.pianokeybd->setBaseOctave(dlgPreferences.getBaseOctave());
         }
-        if (ui.pianokeybd->numOctaves() != dlgPreferences.getNumOctaves()) {
-            ui.pianokeybd->setNumOctaves(dlgPreferences.getNumOctaves());
+        if (ui.pianokeybd->numKeys() != dlgPreferences.getNumKeys()) {
+            ui.pianokeybd->setNumKeys(dlgPreferences.getNumKeys());
+        }
+        if (ui.pianokeybd->startKey() != dlgPreferences.getStartingKey()) {
+            ui.pianokeybd->setNumKeys(dlgPreferences.getNumKeys(), dlgPreferences.getStartingKey());
+        }
+    }
+}
+
+void VPiano::closeEvent(QCloseEvent *event)
+{
+    writeSettings();
+    event->accept();
+}
+
+void VPiano::writeSettings()
+{
+    QSettings settings;
+
+    settings.beginGroup("Window");
+    settings.setValue("Geometry", saveGeometry());
+    settings.setValue("State", saveState());
+    settings.endGroup();
+
+    settings.beginGroup("Connections");
+    settings.setValue("inputBackend", m_midiIn->backendName());
+    settings.setValue("outputBackend", m_midiOut->backendName());
+    settings.setValue("inputConenction", m_midiIn->currentConnection());
+    settings.setValue("outputConnection", m_midiOut->currentConnection());
+    settings.setValue("midiThru", m_midiThru);
+    settings.setValue("advanced", m_advanced);
+    settings.endGroup();
+
+    settings.beginGroup("Preferences");
+    settings.setValue("inputChannel", dlgPreferences.getInChannel());
+    settings.setValue("outputChannel",dlgPreferences.getOutChannel());
+    settings.setValue("velocity", dlgPreferences. getVelocity());
+    settings.setValue("baseOctave", dlgPreferences.getBaseOctave());
+    settings.setValue("numKeys", dlgPreferences.getNumKeys());
+    settings.setValue("startingKey", dlgPreferences.getStartingKey());
+    settings.endGroup();
+
+    settings.sync();
+}
+
+void VPiano::readSettings()
+{
+    QSettings settings;
+
+    settings.beginGroup("Window");
+    restoreGeometry(settings.value("Geometry").toByteArray());
+    restoreState(settings.value("State").toByteArray());
+    settings.endGroup();
+
+    settings.beginGroup("Connections");
+    m_lastInputBackend = settings.value("inputBackend").toString();
+    m_lastOutputBackend = settings.value("outputBackend").toString();
+    m_lastInputConnection = settings.value("inputConenction").toString();
+    m_lastOutputConnection = settings.value("outputConnection").toString();
+    m_midiThru = settings.value("midiThru", false).toBool();
+    m_advanced = settings.value("advanced", false).toBool();
+    settings.endGroup();
+
+    settings.beginGroup("Preferences");
+    dlgPreferences.setInChannel(settings.value("inputChannel", 0).toInt());
+    dlgPreferences.setOutChannel(settings.value("outputChannel", 0).toInt());
+    dlgPreferences.setVelocity(settings.value("velocity", 100).toInt());
+    dlgPreferences.setBaseOctave(settings.value("baseOctave", 1).toInt());
+    dlgPreferences.setNumKeys(settings.value("numKeys", 88).toInt());
+    dlgPreferences.setStartingKey(settings.value("startingKey", 9).toInt());
+    ui.pianokeybd->setBaseOctave(settings.value("baseOctave", 1).toInt());
+    ui.pianokeybd->setNumKeys(settings.value("numKeys", 88).toInt(), settings.value("startingKey", 9).toInt());
+    settings.endGroup();
+}
+
+void VPiano::findInput(QString name, QList<MIDIInput *> &inputs)
+{
+    foreach(MIDIInput* input, inputs) {
+        if (m_midiIn == 0 && (input->backendName() == name))  {
+            m_midiIn = input;
+            break;
+        }
+    }
+}
+
+void VPiano::findOutput(QString name, QList<MIDIOutput *> &outputs)
+{
+    foreach(MIDIOutput* output, outputs) {
+        if (m_midiOut == 0 && (output->backendName() == name))  {
+            m_midiOut = output;
+            break;
         }
     }
 }
diff --git a/utils/vpiano/vpiano.h b/utils/vpiano/vpiano.h
index 6ca695f..250b51b 100644
--- a/utils/vpiano/vpiano.h
+++ b/utils/vpiano/vpiano.h
@@ -1,6 +1,6 @@
 /*
     Virtual Piano test using the MIDI Sequencer C++ library
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -21,53 +21,51 @@
 #define VPIANO_H
 
 #include <QMainWindow>
+#include <QCloseEvent>
+
 #include "ui_vpiano.h"
 #include "vpianoabout.h"
 #include "connections.h"
 #include "preferences.h"
 
-#include "alsaevent.h"
-#include "alsaclient.h"
-#include "alsaport.h"
-#include "alsaqueue.h"
-
-using namespace drumstick;
+#include "rtmidiinput.h"
+#include "rtmidioutput.h"
 
-/* MidiClient can deliver SequencerEvents with only
- * signals or posting QEvents to the QApplication loop */
-#undef USE_QEVENTS
-//#define USE_QEVENTS
+using namespace drumstick::rt;
 
 class VPiano : public QMainWindow
 {
     Q_OBJECT
-
 public:
     VPiano( QWidget * parent = 0, Qt::WindowFlags flags = 0 );
     virtual ~VPiano();
+    void closeEvent(QCloseEvent *event);
+    void findInput(QString name, QList<MIDIInput*> &inputs);
+    void findOutput(QString name, QList<MIDIOutput*> &outputs);
 
 public slots:
+    void readSettings();
+    void writeSettings();
+
     void slotAbout();
     void slotAboutQt();
     void slotConnections();
     void slotPreferences();
-    void slotNoteOn(const int midiNote);
-    void slotNoteOff(const int midiNote);
-    void slotSubscription(MidiPort* port, Subscription* subs);
 
-#ifdef USE_QEVENTS
-protected:
-    virtual void customEvent( QEvent *ev );
-#else
-    void sequencerEvent( SequencerEvent* ev );
-#endif
+    void slotNoteOn(const int midiNote, const int vel);
+    void slotNoteOn(const int chan, const int note, const int vel);
+    void slotNoteOff(const int midiNote, const int vel);
+    void slotNoteOff(const int chan, const int note, const int vel);
 
 private:
-    void displayEvent( SequencerEvent* ev );
-
-    int m_portId;
-    MidiClient* m_Client;
-    MidiPort* m_Port;
+    MIDIInput * m_midiIn;
+    MIDIOutput* m_midiOut;
+    QString m_lastInputBackend;
+    QString m_lastOutputBackend;
+    QString m_lastInputConnection;
+    QString m_lastOutputConnection;
+    bool m_midiThru;
+    bool m_advanced;
     Ui::VPiano ui;
     About dlgAbout;
     Connections dlgConnections;
diff --git a/utils/vpiano/vpiano.pro b/utils/vpiano/vpiano.pro
index e5ea969..f5a5236 100644
--- a/utils/vpiano/vpiano.pro
+++ b/utils/vpiano/vpiano.pro
@@ -1,20 +1,67 @@
 TEMPLATE = app
 TARGET = drumstick-vpiano
-QT += svg dbus
-CONFIG += qt thread exceptions x11
+QT += gui widgets svg network
+CONFIG += qt thread exceptions link_prl
 DESTDIR = ../../build/bin
-OBJECTS_DIR = ../../build/obj
-MOC_DIR = ../../build/moc
-RCC_DIR = ../../build/rcc
-UI_DIR = ../../build/ui
-INCLUDEPATH += . ../../library/include ../common ../../build/common
-LIBS = -L../../build/lib -ldrumstick-common -ldrumstick-alsa -lasound -lX11
+include (../../global.pri)
+INCLUDEPATH += . ../../library/include ../common
+
 # Input
-FORMS += vpiano.ui connections.ui vpianoabout.ui preferences.ui
+FORMS += vpiano.ui connections.ui vpianoabout.ui preferences.ui fluidsettingsdialog.ui networksettingsdialog.ui
 HEADERS += pianokey.h pianokeybd.h pianoscene.h vpiano.h \
-           keyboardmap.h keylabel.h pianodefs.h rawkeybdapp.h \
-           connections.h connectionitem.h vpianoabout.h preferences.h
+           keyboardmap.h keylabel.h pianodefs.h \
+           connections.h vpianoabout.h preferences.h \
+           fluidsettingsdialog.h networksettingsdialog.h
 SOURCES += pianokey.cpp pianokeybd.cpp pianoscene.cpp vpiano.cpp \
-           keylabel.cpp rawkeybdapp.cpp \
-           connections.cpp vpianoabout.cpp preferences.cpp vpianomain.cpp
+           keylabel.cpp connections.cpp vpianoabout.cpp preferences.cpp vpianomain.cpp \
+           fluidsettingsdialog.cpp networksettingsdialog.cpp
 RESOURCES += pianokeybd.qrc
+
+# libs
+macx {
+    QMAKE_LFLAGS += -F$$OUT_PWD/../../build/lib -L$$OUT_PWD/../../build/lib
+    LIBS += -framework drumstick-rt
+    LIBS += -l$$qtLibraryTarget(drumstick-common)
+    ICON = ../../icons/drumstick.icns
+}
+else {
+    LIBS += -L$$OUT_PWD/../../build/lib/
+    LIBS += -l$$qtLibraryTarget(drumstick-common) \
+            -l$$qtLibraryTarget(drumstick-rt)
+}
+
+static {
+    LIBS += -L$$OUT_PWD/../../build/lib/drumstick/
+    LIBS += -l$$qtLibraryTarget(drumstick-rt-net-in) \
+            -l$$qtLibraryTarget(drumstick-rt-net-out)
+
+    DEFINES += SYNTH_BACKEND
+    CONFIG += link_pkgconfig
+    LIBS += -l$$qtLibraryTarget(drumstick-rt-synth)
+    PKGCONFIG += fluidsynth
+
+    linux* {
+        LIBS += -l$$qtLibraryTarget(drumstick-rt-alsa-in) \
+                -l$$qtLibraryTarget(drumstick-rt-alsa-out) \
+                -l$$qtLibraryTarget(drumstick-alsa) \
+                -lasound
+    }
+
+    unix:!macx {
+        LIBS += -l$$qtLibraryTarget(drumstick-rt-oss-in) \
+                -l$$qtLibraryTarget(drumstick-rt-oss-out)
+    }
+
+    macx {
+        LIBS += -l$$qtLibraryTarget(drumstick-rt-mac-in) \
+                -l$$qtLibraryTarget(drumstick-rt-mac-out) \
+                -framework CoreMIDI \
+                -framework CoreFoundation
+    }
+
+    win32 {
+        LIBS += -l$$qtLibraryTarget(drumstick-rt-win-in) \
+                -l$$qtLibraryTarget(drumstick-rt-win-out) \
+                -lwinmm
+    }
+}
diff --git a/utils/vpiano/vpiano.ui b/utils/vpiano/vpiano.ui
index 9caabc3..48aa8ba 100644
--- a/utils/vpiano/vpiano.ui
+++ b/utils/vpiano/vpiano.ui
@@ -16,11 +16,7 @@
   <widget class="QWidget" name="centralwidget">
    <layout class="QVBoxLayout">
     <item>
-     <widget class="PianoKeybd" name="pianokeybd">
-      <property name="numOctaves">
-       <number>5</number>
-      </property>
-     </widget>
+     <widget class="PianoKeybd" name="pianokeybd"/>
     </item>
    </layout>
   </widget>
@@ -30,7 +26,7 @@
      <x>0</x>
      <y>0</y>
      <width>664</width>
-     <height>25</height>
+     <height>19</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
diff --git a/utils/vpiano/vpianoabout.cpp b/utils/vpiano/vpianoabout.cpp
index 1a1a74c..adc201b 100644
--- a/utils/vpiano/vpianoabout.cpp
+++ b/utils/vpiano/vpianoabout.cpp
@@ -1,6 +1,6 @@
 /*
     Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/utils/vpiano/vpianoabout.h b/utils/vpiano/vpianoabout.h
index 8601a0a..9a261a1 100644
--- a/utils/vpiano/vpianoabout.h
+++ b/utils/vpiano/vpianoabout.h
@@ -1,6 +1,6 @@
 /*
     Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 #ifndef ABOUT_H
 #define ABOUT_H
 
-#include <QtGui/QDialog>
+#include <QDialog>
 #include "ui_vpianoabout.h"
 
 class About : public QDialog
diff --git a/utils/vpiano/vpianoabout.ui b/utils/vpiano/vpianoabout.ui
index 91cb8f6..09aee60 100644
--- a/utils/vpiano/vpianoabout.ui
+++ b/utils/vpiano/vpianoabout.ui
@@ -26,17 +26,17 @@
       <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 <html><head><meta name="qrichtext" content="1" /><style type="text/css">
 p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;">
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:16pt; font-weight:600;">Drumstick Virtual Piano %VERSION%</span></p>
-<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Sample application for the </span><a href="http://drumstick.sourceforge.net"><span style=" text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Copyright © 2006-2010, Pedro Lopez-Cabanillas &lt;</span><a href="mailto:plcl at users.sf.net"><span style=" text-decoration: underline; color:#0057ae;">plcl at users.sf.net</span></a><span style=" font-family:'Sans Serif';">&gt;</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> </span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.</span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;"> </span></p>
-<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:8pt;">You should have received a copy of the GNU General Public License along  with this program; if not, write to the Free Software Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. </span></p></body></html></string>
+</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16pt; font-weight:600;">Drumstick Virtual Piano %VERSION%</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:9pt;"><br /></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Sample application for the <a href="http://drumstick.sourceforge.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">Drumstick MIDI Sequencer C++ library</span></a></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2006-2015, Pedro Lopez-Cabanillas &lt;<a href="mailto:plcl at users.sf.net"><span style=" font-family:'DejaVu Sans'; text-decoration: underline; color:#0057ae;">plcl at users.sf.net</span></a>&gt;</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> </span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> </span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">You should have received a copy of the GNU General Public License along  with this program; if not, write to the Free Software Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. </span></p></body></html></string>
      </property>
      <property name="openExternalLinks">
       <bool>true</bool>
diff --git a/utils/vpiano/vpianomain.cpp b/utils/vpiano/vpianomain.cpp
index 7c45b4e..cdf7547 100644
--- a/utils/vpiano/vpianomain.cpp
+++ b/utils/vpiano/vpianomain.cpp
@@ -1,6 +1,6 @@
 /*
     Virtual Piano test using the MIDI Sequencer C++ library 
-    Copyright (C) 2006-2010, Pedro Lopez-Cabanillas <plcl at users.sf.net>
+    Copyright (C) 2006-2015, Pedro Lopez-Cabanillas <plcl at users.sf.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -17,36 +17,44 @@
     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.    
 */
 
-#include "vpiano.h"
-#include "rawkeybdapp.h"
+#include <QApplication>
+#include <QFileInfo>
+#include <QSettings>
+#include <QTextStream>
 #include "cmdlineargs.h"
-
-#include "drumstickcommon.h"
-#include <QtGui/QApplication>
-#include <QtGui/QMessageBox>
-
-const QString errorstr = "Fatal error from the ALSA sequencer. "
-    "This usually happens when the kernel doesn't have ALSA support, "
-    "or the device node (/dev/snd/seq) doesn't exists, "
-    "or the kernel module (snd_seq) is not loaded. "
-    "Please check your ALSA/MIDI configuration.";
+#include "vpiano.h"
+#include "backendmanager.h"
 
 int main(int argc, char *argv[])
 {
-    RawKeybdApp a(argc, argv);
+    QTextStream cout(stdout, QIODevice::WriteOnly);
+    QTextStream cerr(stderr, QIODevice::WriteOnly);
+    QCoreApplication::setOrganizationName("drumstick.sourceforge.net");
+    QCoreApplication::setOrganizationDomain("drumstick.sourceforge.net");
+    QCoreApplication::setApplicationName("VPiano");
+    QApplication app(argc, argv);
+
     CmdLineArgs args;
     args.setStdQtArgs(true);
-    args.setUsage("[options]");
-    args.parse(a.argc(), a.argv());
+    args.parse(argc, argv);
+
+    QFileInfo exeInfo(app.applicationFilePath());
+    cout << "program=" << exeInfo.fileName() << endl;
+
+    QSettings settings;
+    settings.beginGroup(QSTR_DRUMSTICKRT_GROUP);
+    settings.setValue(QSTR_DRUMSTICKRT_PUBLICNAMEIN, QLatin1String("Virtual Piano IN"));
+    settings.setValue(QSTR_DRUMSTICKRT_PUBLICNAMEOUT, QLatin1String("Virtual Piano OUT"));
+    //settings.setValue(QSTR_DRUMSTICKRT_PATH, backendir);
+    settings.endGroup();
+    settings.sync();
+
     try {
         VPiano w;
         w.show();
-        return a.exec();
-    } catch (const SequencerError& ex) {
-        QMessageBox::critical(0, "Error",
-            errorstr + " Returned error was: " + ex.qstrError() );
+        return app.exec();
     } catch (...) {
-        qWarning() << errorstr;
+        cerr << "Fatal error from a MIDI backend." << endl;
     }
     return 0;
 }

-- 
libdrumstick packaging



More information about the pkg-multimedia-commits mailing list