From 70fd2d85c1bd6fb8732e680e8fda9d36c317c732 Mon Sep 17 00:00:00 2001
From: Chris Xiong <chirs241097@gmail.com>
Date: Wed, 6 Apr 2016 16:54:29 +0800
Subject: Too young too simple.

---
 README.md                                   |   5 +
 common/qmpmidiplay.cpp                      | 404 ---------------
 common/qmpmidiplay.hpp                      | 137 -----
 common/qmpmidiread.cpp                      | 239 ---------
 core/qmpmidiplay.cpp                        | 404 +++++++++++++++
 core/qmpmidiplay.hpp                        | 137 +++++
 core/qmpmidiread.cpp                        | 239 +++++++++
 debian/changelog                            |  24 +
 debian/control                              |  13 +-
 debian/qmidiplayer-lite.install             |   1 +
 debian/qmidiplayer.install                  |   1 +
 debian/rules                                |   2 +-
 qmidiplayer-desktop/main.cpp                |  29 ++
 qmidiplayer-desktop/qdialskulpturestyle.cpp | 437 ++++++++++++++++
 qmidiplayer-desktop/qdialskulpturestyle.hpp |  39 ++
 qmidiplayer-desktop/qmidiplayer-desktop.pro |  64 +++
 qmidiplayer-desktop/qmpchanneleditor.cpp    | 193 +++++++
 qmidiplayer-desktop/qmpchanneleditor.hpp    |  42 ++
 qmidiplayer-desktop/qmpchanneleditor.ui     | 602 ++++++++++++++++++++++
 qmidiplayer-desktop/qmpchannelswindow.cpp   | 132 +++++
 qmidiplayer-desktop/qmpchannelswindow.hpp   |  71 +++
 qmidiplayer-desktop/qmpchannelswindow.ui    | 146 ++++++
 qmidiplayer-desktop/qmpefxwindow.cpp        | 198 ++++++++
 qmidiplayer-desktop/qmpefxwindow.hpp        |  62 +++
 qmidiplayer-desktop/qmpefxwindow.ui         | 478 +++++++++++++++++
 qmidiplayer-desktop/qmphelpwindow.cpp       |  31 ++
 qmidiplayer-desktop/qmphelpwindow.hpp       |  26 +
 qmidiplayer-desktop/qmphelpwindow.ui        |  34 ++
 qmidiplayer-desktop/qmpimidimapper.hpp      |  16 +
 qmidiplayer-desktop/qmpinfowindow.cpp       |  57 +++
 qmidiplayer-desktop/qmpinfowindow.hpp       |  24 +
 qmidiplayer-desktop/qmpinfowindow.ui        |  91 ++++
 qmidiplayer-desktop/qmpmainwindow.cpp       | 510 +++++++++++++++++++
 qmidiplayer-desktop/qmpmainwindow.hpp       |  90 ++++
 qmidiplayer-desktop/qmpmainwindow.ui        | 413 +++++++++++++++
 qmidiplayer-desktop/qmpplistwindow.cpp      | 308 +++++++++++
 qmidiplayer-desktop/qmpplistwindow.hpp      |  57 +++
 qmidiplayer-desktop/qmpplistwindow.ui       | 263 ++++++++++
 qmidiplayer-desktop/qmppresetselect.cpp     |  99 ++++
 qmidiplayer-desktop/qmppresetselect.hpp     |  36 ++
 qmidiplayer-desktop/qmppresetselect.ui      | 106 ++++
 qmidiplayer-desktop/qmpsettingswindow.cpp   | 289 +++++++++++
 qmidiplayer-desktop/qmpsettingswindow.hpp   |  47 ++
 qmidiplayer-desktop/qmpsettingswindow.ui    | 761 ++++++++++++++++++++++++++++
 qmidiplayer-desktop/resources.qrc           |  36 ++
 qmidiplayer-lite/deployment.pri             |  13 +
 qmidiplayer-lite/main.cpp                   |  15 +
 qmidiplayer-lite/main.qml                   | 144 ++++++
 qmidiplayer-lite/qmidiplayer-lite.pro       |  24 +
 qmidiplayer-lite/qml.qrc                    |   5 +
 qmidiplayer-lite/qmpcorewrapper.hpp         |  58 +++
 qmidiplayer-lite/qmpmidiplay.cpp            | 406 +++++++++++++++
 qmidiplayer-lite/qmpmidiplay.hpp            | 137 +++++
 qmidiplayer-lite/qmpmidiread.cpp            | 240 +++++++++
 qmidiplayer.pro                             |  67 +--
 qmidiplayer.src.d/main.cpp                  |  29 --
 qmidiplayer.src.d/qdialskulpturestyle.cpp   | 437 ----------------
 qmidiplayer.src.d/qdialskulpturestyle.hpp   |  39 --
 qmidiplayer.src.d/qmpchanneleditor.cpp      | 193 -------
 qmidiplayer.src.d/qmpchanneleditor.hpp      |  42 --
 qmidiplayer.src.d/qmpchanneleditor.ui       | 602 ----------------------
 qmidiplayer.src.d/qmpchannelswindow.cpp     | 132 -----
 qmidiplayer.src.d/qmpchannelswindow.hpp     |  71 ---
 qmidiplayer.src.d/qmpchannelswindow.ui      | 146 ------
 qmidiplayer.src.d/qmpefxwindow.cpp          | 198 --------
 qmidiplayer.src.d/qmpefxwindow.hpp          |  62 ---
 qmidiplayer.src.d/qmpefxwindow.ui           | 478 -----------------
 qmidiplayer.src.d/qmphelpwindow.cpp         |  31 --
 qmidiplayer.src.d/qmphelpwindow.hpp         |  26 -
 qmidiplayer.src.d/qmphelpwindow.ui          |  34 --
 qmidiplayer.src.d/qmpimidimapper.hpp        |  16 -
 qmidiplayer.src.d/qmpinfowindow.cpp         |  57 ---
 qmidiplayer.src.d/qmpinfowindow.hpp         |  24 -
 qmidiplayer.src.d/qmpinfowindow.ui          |  91 ----
 qmidiplayer.src.d/qmpmainwindow.cpp         | 510 -------------------
 qmidiplayer.src.d/qmpmainwindow.hpp         |  90 ----
 qmidiplayer.src.d/qmpmainwindow.ui          | 413 ---------------
 qmidiplayer.src.d/qmpplistwindow.cpp        | 308 -----------
 qmidiplayer.src.d/qmpplistwindow.hpp        |  57 ---
 qmidiplayer.src.d/qmpplistwindow.ui         | 263 ----------
 qmidiplayer.src.d/qmppresetselect.cpp       |  99 ----
 qmidiplayer.src.d/qmppresetselect.hpp       |  36 --
 qmidiplayer.src.d/qmppresetselect.ui        | 106 ----
 qmidiplayer.src.d/qmpsettingswindow.cpp     | 289 -----------
 qmidiplayer.src.d/qmpsettingswindow.hpp     |  47 --
 qmidiplayer.src.d/qmpsettingswindow.ui      | 761 ----------------------------
 qmidiplayer.src.d/resources.qrc             |  36 --
 qmidiplayerlite.pro                         |  24 -
 qmidiplayerlite.src.d/deployment.pri        |  13 -
 qmidiplayerlite.src.d/main.cpp              |  15 -
 qmidiplayerlite.src.d/main.qml              | 144 ------
 qmidiplayerlite.src.d/qml.qrc               |   5 -
 qmidiplayerlite.src.d/qmpcorewrapper.hpp    |  58 ---
 qmidiplayerlite.src.d/qmpmidiplay.cpp       | 406 ---------------
 qmidiplayerlite.src.d/qmpmidiplay.hpp       | 137 -----
 qmidiplayerlite.src.d/qmpmidiread.cpp       | 240 ---------
 96 files changed, 7656 insertions(+), 7611 deletions(-)
 delete mode 100644 common/qmpmidiplay.cpp
 delete mode 100644 common/qmpmidiplay.hpp
 delete mode 100644 common/qmpmidiread.cpp
 create mode 100644 core/qmpmidiplay.cpp
 create mode 100644 core/qmpmidiplay.hpp
 create mode 100644 core/qmpmidiread.cpp
 create mode 100644 debian/qmidiplayer-lite.install
 create mode 100644 debian/qmidiplayer.install
 create mode 100644 qmidiplayer-desktop/main.cpp
 create mode 100644 qmidiplayer-desktop/qdialskulpturestyle.cpp
 create mode 100644 qmidiplayer-desktop/qdialskulpturestyle.hpp
 create mode 100644 qmidiplayer-desktop/qmidiplayer-desktop.pro
 create mode 100644 qmidiplayer-desktop/qmpchanneleditor.cpp
 create mode 100644 qmidiplayer-desktop/qmpchanneleditor.hpp
 create mode 100644 qmidiplayer-desktop/qmpchanneleditor.ui
 create mode 100644 qmidiplayer-desktop/qmpchannelswindow.cpp
 create mode 100644 qmidiplayer-desktop/qmpchannelswindow.hpp
 create mode 100644 qmidiplayer-desktop/qmpchannelswindow.ui
 create mode 100644 qmidiplayer-desktop/qmpefxwindow.cpp
 create mode 100644 qmidiplayer-desktop/qmpefxwindow.hpp
 create mode 100644 qmidiplayer-desktop/qmpefxwindow.ui
 create mode 100644 qmidiplayer-desktop/qmphelpwindow.cpp
 create mode 100644 qmidiplayer-desktop/qmphelpwindow.hpp
 create mode 100644 qmidiplayer-desktop/qmphelpwindow.ui
 create mode 100644 qmidiplayer-desktop/qmpimidimapper.hpp
 create mode 100644 qmidiplayer-desktop/qmpinfowindow.cpp
 create mode 100644 qmidiplayer-desktop/qmpinfowindow.hpp
 create mode 100644 qmidiplayer-desktop/qmpinfowindow.ui
 create mode 100644 qmidiplayer-desktop/qmpmainwindow.cpp
 create mode 100644 qmidiplayer-desktop/qmpmainwindow.hpp
 create mode 100644 qmidiplayer-desktop/qmpmainwindow.ui
 create mode 100644 qmidiplayer-desktop/qmpplistwindow.cpp
 create mode 100644 qmidiplayer-desktop/qmpplistwindow.hpp
 create mode 100644 qmidiplayer-desktop/qmpplistwindow.ui
 create mode 100644 qmidiplayer-desktop/qmppresetselect.cpp
 create mode 100644 qmidiplayer-desktop/qmppresetselect.hpp
 create mode 100644 qmidiplayer-desktop/qmppresetselect.ui
 create mode 100644 qmidiplayer-desktop/qmpsettingswindow.cpp
 create mode 100644 qmidiplayer-desktop/qmpsettingswindow.hpp
 create mode 100644 qmidiplayer-desktop/qmpsettingswindow.ui
 create mode 100644 qmidiplayer-desktop/resources.qrc
 create mode 100644 qmidiplayer-lite/deployment.pri
 create mode 100644 qmidiplayer-lite/main.cpp
 create mode 100644 qmidiplayer-lite/main.qml
 create mode 100644 qmidiplayer-lite/qmidiplayer-lite.pro
 create mode 100644 qmidiplayer-lite/qml.qrc
 create mode 100644 qmidiplayer-lite/qmpcorewrapper.hpp
 create mode 100644 qmidiplayer-lite/qmpmidiplay.cpp
 create mode 100644 qmidiplayer-lite/qmpmidiplay.hpp
 create mode 100644 qmidiplayer-lite/qmpmidiread.cpp
 delete mode 100644 qmidiplayer.src.d/main.cpp
 delete mode 100644 qmidiplayer.src.d/qdialskulpturestyle.cpp
 delete mode 100644 qmidiplayer.src.d/qdialskulpturestyle.hpp
 delete mode 100644 qmidiplayer.src.d/qmpchanneleditor.cpp
 delete mode 100644 qmidiplayer.src.d/qmpchanneleditor.hpp
 delete mode 100644 qmidiplayer.src.d/qmpchanneleditor.ui
 delete mode 100644 qmidiplayer.src.d/qmpchannelswindow.cpp
 delete mode 100644 qmidiplayer.src.d/qmpchannelswindow.hpp
 delete mode 100644 qmidiplayer.src.d/qmpchannelswindow.ui
 delete mode 100644 qmidiplayer.src.d/qmpefxwindow.cpp
 delete mode 100644 qmidiplayer.src.d/qmpefxwindow.hpp
 delete mode 100644 qmidiplayer.src.d/qmpefxwindow.ui
 delete mode 100644 qmidiplayer.src.d/qmphelpwindow.cpp
 delete mode 100644 qmidiplayer.src.d/qmphelpwindow.hpp
 delete mode 100644 qmidiplayer.src.d/qmphelpwindow.ui
 delete mode 100644 qmidiplayer.src.d/qmpimidimapper.hpp
 delete mode 100644 qmidiplayer.src.d/qmpinfowindow.cpp
 delete mode 100644 qmidiplayer.src.d/qmpinfowindow.hpp
 delete mode 100644 qmidiplayer.src.d/qmpinfowindow.ui
 delete mode 100644 qmidiplayer.src.d/qmpmainwindow.cpp
 delete mode 100644 qmidiplayer.src.d/qmpmainwindow.hpp
 delete mode 100644 qmidiplayer.src.d/qmpmainwindow.ui
 delete mode 100644 qmidiplayer.src.d/qmpplistwindow.cpp
 delete mode 100644 qmidiplayer.src.d/qmpplistwindow.hpp
 delete mode 100644 qmidiplayer.src.d/qmpplistwindow.ui
 delete mode 100644 qmidiplayer.src.d/qmppresetselect.cpp
 delete mode 100644 qmidiplayer.src.d/qmppresetselect.hpp
 delete mode 100644 qmidiplayer.src.d/qmppresetselect.ui
 delete mode 100644 qmidiplayer.src.d/qmpsettingswindow.cpp
 delete mode 100644 qmidiplayer.src.d/qmpsettingswindow.hpp
 delete mode 100644 qmidiplayer.src.d/qmpsettingswindow.ui
 delete mode 100644 qmidiplayer.src.d/resources.qrc
 delete mode 100644 qmidiplayerlite.pro
 delete mode 100644 qmidiplayerlite.src.d/deployment.pri
 delete mode 100644 qmidiplayerlite.src.d/main.cpp
 delete mode 100644 qmidiplayerlite.src.d/main.qml
 delete mode 100644 qmidiplayerlite.src.d/qml.qrc
 delete mode 100644 qmidiplayerlite.src.d/qmpcorewrapper.hpp
 delete mode 100644 qmidiplayerlite.src.d/qmpmidiplay.cpp
 delete mode 100644 qmidiplayerlite.src.d/qmpmidiplay.hpp
 delete mode 100644 qmidiplayerlite.src.d/qmpmidiread.cpp

diff --git a/README.md b/README.md
index 758bb43..1d8319c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
 # QMidiPlayer
 A cross-platform midi file player based on libfluidsynth and Qt.
 
+[Project homepage](https://chrisoft.org/QMidiPlayer/)
+
 Now it's in beta stage. Crashes and hangs may still occur, run with gdb attatched if you could.
 
 Features:
@@ -10,5 +12,8 @@ Features:
 * Editing synthesizer effects
 * Rendering midi to wave file
 * Visualization using SMELT (not implemented)
+* MIDI mapping (not implemented)
 
 Tested on Debian sid and Windows Vista~10.
+
+A QML version is now in construction. The whole project is now being overhauled...
diff --git a/common/qmpmidiplay.cpp b/common/qmpmidiplay.cpp
deleted file mode 100644
index 6f69e33..0000000
--- a/common/qmpmidiplay.cpp
+++ /dev/null
@@ -1,404 +0,0 @@
-#include <cstdio>
-#include <chrono>
-#include <thread>
-#include <fluidsynth.h>
-#include "qmpmidiplay.hpp"
-#ifdef _WIN32
-#include <windows.h>
-uint64_t pf;
-#endif
-void CMidiPlayer::fluidPreInitialize()
-{
-	settings=new_fluid_settings();
-}
-void CMidiPlayer::fluidInitialize()
-{
-	synth=new_fluid_synth(settings);
-	adriver=new_fluid_audio_driver(settings,synth);
-	fluid_synth_set_chorus(synth,FLUID_CHORUS_DEFAULT_N,FLUID_CHORUS_DEFAULT_LEVEL,
-						   FLUID_CHORUS_DEFAULT_SPEED,FLUID_CHORUS_DEFAULT_DEPTH,
-						   FLUID_CHORUS_DEFAULT_TYPE);
-#ifndef _WIN32
-	if(!singleInstance)
-	{
-		if(midiFile->getStandard()==4)
-		fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_MELODIC);
-		else if(midiFile->getStandard()==1)
-			fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_DRUM);
-		else
-		{
-			fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_DRUM);
-			fluid_synth_bank_select(synth,9,128);
-		}
-	}
-#endif
-}
-void CMidiPlayer::fluidDeinitialize()
-{
-	if(!synth||!adriver||!settings)return;
-	delete_fluid_settings(settings);
-	delete_fluid_audio_driver(adriver);
-	delete_fluid_synth(synth);
-	settings=NULL;synth=NULL;adriver=NULL;
-}
-void CMidiPlayer::processEvent(const SEvent *e)
-{
-	switch(e->type&0xF0)
-	{
-		case 0x80://Note off
-			fluid_synth_noteoff(synth,e->type&0x0F,e->p1);
-		break;
-		case 0x90://Note on
-			if((mute>>(e->type&0x0F))&1)break;//muted
-			if(solo&&!((solo>>(e->type&0x0F))&1))break;
-			fluid_synth_noteon(synth,e->type&0x0F,e->p1,e->p2);
-		break;
-		case 0xB0://CC
-			if(e->p1==100)rpnid=e->p2;
-			if(e->p1==6)rpnval=e->p2;
-			if(~rpnid&&~rpnval)
-			{
-				if(rpnid==0)fluid_synth_pitch_wheel_sens(synth,e->type&0x0F,rpnval);
-				rpnid=rpnval=-1;
-			}
-			fluid_synth_cc(synth,e->type&0x0F,e->p1,e->p2);
-		break;
-		case 0xC0://PC
-			fluid_synth_program_change(synth,e->type&0x0F,e->p1);
-		break;
-		case 0xE0://PW
-			fluid_synth_pitch_bend(synth,e->type&0x0F,e->p1);
-		break;
-		case 0xF0://Meta/SysEx
-			if((e->type&0x0F)==0x0F)
-			{
-				switch(e->p1)
-				{
-					case 0x51:
-						ctempo=e->p2;dpt=ctempo*1000/divs;
-					break;
-					case 0x58:
-						ctsn=e->p2>>24;
-						ctsd=1<<((e->p2>>16)&0xFF);
-					break;
-					case 0x59:
-						cks=e->p2;
-					break;
-					case 0x01:case 0x02:case 0x03:
-					case 0x04:case 0x05:case 0x06:
-					case 0x07:
-						//if(e->str)puts(e->str);
-					break;
-				}
-			}
-			if((e->type&0x0F)==0x00||(e->type&0x0F)==07)
-			{
-				int io=0;
-				if(sendSysEx)fluid_synth_sysex(synth,e->str,e->p1,NULL,&io,NULL,0);
-			}
-		break;
-	}
-}
-void CMidiPlayer::processEventStub(const SEvent *e)
-{
-	switch(e->type&0xF0)
-	{
-		case 0xB0://CC
-			if(e->p1==100)rpnid=e->p2;
-			if(e->p1==6)rpnval=e->p2;
-			if(~rpnid&&~rpnval)
-			{
-				if(rpnid==0)ccc[e->type&0x0F][134]=rpnval;
-				rpnid=rpnval=-1;
-			}
-			ccc[e->type&0x0F][e->p1]=e->p2;
-		break;
-		case 0xC0://PC
-			ccc[e->type&0x0F][128]=e->p1;
-		break;
-		case 0xD0://CP
-			ccc[e->type&0x0F][129]=e->p1;
-		break;
-		case 0xE0://PW
-			ccc[e->type&0x0F][130]=e->p1;
-		break;
-		case 0xF0://Meta/SysEx
-			if((e->type&0x0F)==0x0F)
-			{
-				switch(e->p1)
-				{
-					case 0x51:
-						ctempo=e->p2;dpt=ctempo*1000/divs;
-						ccc[0][131]=dpt;
-					break;
-					case 0x58:
-						ccc[0][132]=e->p2;
-					break;
-					case 0x59:
-						ccc[0][133]=e->p2;
-					break;
-				}
-			}
-		break;
-	}
-}
-#ifdef _WIN32
-void w32usleep(uint64_t t)
-{
-	uint64_t st=0,ct=0;
-	timeBeginPeriod(1);
-	QueryPerformanceCounter((LARGE_INTEGER*)&st);
-	do{
-		if(t>10000+(ct-st)*1000000/pf)Sleep((t-(ct-st)*1000000/pf)/2000);
-		else if(t>5000+(ct-st)*1000000/pf)Sleep(1);
-		else std::this_thread::yield();
-		QueryPerformanceCounter((LARGE_INTEGER*)&ct);
-	}while((ct-st)*1000000<t*pf);
-	timeEndPeriod(1);
-}
-#endif
-void CMidiPlayer::playEvents()
-{
-	for(uint32_t ct=midiFile->getEvent(0)->time;tceptr<midiFile->getEventCount();)
-	{
-		while(tcpaused)std::this_thread::sleep_for(std::chrono::milliseconds(100));
-		while(!tcstop&&midiFile&&tceptr<midiFile->getEventCount()&&ct==midiFile->getEvent(tceptr)->time)
-			processEvent(midiFile->getEvent(tceptr++));
-		if(tcstop||!midiFile||tceptr>=midiFile->getEventCount())break;
-		if(resumed)resumed=false;
-		else
-#if 0
-		w32usleep((midiFile->getEvent(tceptr)->time-ct)*(dpt/1000));
-#else
-		std::this_thread::sleep_for(std::chrono::nanoseconds(midiFile->getEvent(tceptr)->time-ct)*dpt);
-#endif
-		if(tcstop||!midiFile)break;
-		ct=midiFile->getEvent(tceptr)->time;
-	}
-	while(!tcstop&&synth&&(waitvoice&&fluid_synth_get_active_voice_count(synth)>0))std::this_thread::sleep_for(std::chrono::milliseconds(2));
-	finished=1;
-}
-void CMidiPlayer::fileTimer1Pass()
-{
-	ftime=.0;ctempo=0x7A120;dpt=ctempo*1000/divs;
-	for(uint32_t eptr=0,ct=midiFile->getEvent(0)->time;eptr<midiFile->getEventCount();)
-	{
-		while(eptr<midiFile->getEventCount()&&ct==midiFile->getEvent(eptr)->time)
-			processEventStub(midiFile->getEvent(eptr++));
-		if(eptr>=midiFile->getEventCount())break;
-		ftime+=(midiFile->getEvent(eptr)->time-ct)*dpt/1e9;
-		ct=midiFile->getEvent(eptr)->time;
-	}
-}
-void CMidiPlayer::fileTimer2Pass()
-{
-	double ctime=.0;uint32_t c=1;ctempo=0x7A120;dpt=ctempo*1000/divs;
-	memset(stamps,0,sizeof(stamps));memset(ccstamps,0,sizeof(ccstamps));
-	memset(ccc,0,sizeof(ccc));rpnid=rpnval=-1;for(int i=0;i<16;++i)
-	{
-		ccc[i][7]=100;ccc[i][10]=64;ccc[i][11]=127;
-		ccc[i][11]=127;ccc[i][71]=64;ccc[i][72]=64;
-		ccc[i][73]=64;ccc[i][74]=64;ccc[i][75]=64;
-		ccc[i][76]=64;ccc[i][77]=64;ccc[i][78]=64;
-		ccc[0][131]=dpt;ccc[0][132]=0x04021808;
-		ccc[0][133]=0;ccc[0][134]=2;
-	}if(midiFile->getStandard()!=4)ccc[9][0]=128;
-	for(int i=0;i<16;++i)for(int j=0;j<135;++j)
-		ccstamps[0][i][j]=ccc[i][j];
-	for(uint32_t eptr=0,ct=midiFile->getEvent(0)->time;eptr<midiFile->getEventCount();)
-	{
-		while(eptr<midiFile->getEventCount()&&ct==midiFile->getEvent(eptr)->time)
-			processEventStub(midiFile->getEvent(eptr++));
-		if(eptr>=midiFile->getEventCount())break;
-		ctime+=(midiFile->getEvent(eptr)->time-ct)*dpt/1e9;
-		while(ctime>ftime*c/100.)
-		{
-			for(int i=0;i<16;++i)for(int j=0;j<135;++j)
-				ccstamps[c][i][j]=ccc[i][j];
-			stamps[c++]=eptr;
-			if(c>100)break;
-		}
-		ct=midiFile->getEvent(eptr)->time;
-	}
-	while(c<101)
-	{
-		for(int i=0;i<16;++i)for(int j=0;j<135;++j)
-			ccstamps[c][i][j]=ccc[i][j];
-		stamps[c++]=midiFile->getEventCount();
-	}
-}
-CMidiPlayer::CMidiPlayer(bool singleInst)
-{
-	midiFile=NULL;resumed=false;singleInstance=singleInst;
-	settings=NULL;synth=NULL;adriver=NULL;waitvoice=true;
-#ifdef _WIN32
-	QueryPerformanceFrequency((LARGE_INTEGER*)&pf);
-#endif
-}
-CMidiPlayer::~CMidiPlayer()
-{
-	if(singleInstance)fluidDeinitialize();
-}
-void CMidiPlayer::playerPanic(bool reset)
-{
-	if(reset)for(int i=0;i<16;++i)
-	{
-		fluid_synth_pitch_bend(synth,i,8192);
-		fluid_synth_cc(synth,i,7,100);
-		fluid_synth_cc(synth,i,10,64);
-		fluid_synth_cc(synth,i,11,127);
-	}
-	for(int i=0;i<16;++i)fluid_synth_all_notes_off(synth,i);
-}
-bool CMidiPlayer::playerLoadFile(const char* fn)
-{
-	midiFile=new CMidiFile(fn);
-	if(!midiFile->isValid())return false;
-	divs=midiFile->getDivision();
-	fileTimer1Pass();
-	fileTimer2Pass();
-	return true;
-}
-void CMidiPlayer::playerInit()
-{
-	ctempo=0x7A120;ctsn=4;ctsd=4;cks=0;dpt=ctempo*1000/divs;
-	tceptr=0;tcstop=0;tcpaused=0;finished=0;mute=solo=0;
-	sendSysEx=true;rpnid=rpnval=-1;
-	if(!singleInstance)fluidPreInitialize();
-}
-void CMidiPlayer::playerDeinit()
-{
-	tceptr=0;tcstop=1;tcpaused=0;
-	delete midiFile;midiFile=NULL;
-	if(!singleInstance)fluidDeinitialize();
-}
-void CMidiPlayer::playerThread()
-{
-	playEvents();
-}
-
-void CMidiPlayer::rendererLoadFile(const char* ofn)
-{
-	settings=new_fluid_settings();
-	fluid_settings_setstr(settings,"audio.file.name",ofn);
-}
-void CMidiPlayer::rendererInit(const char* fn)
-{
-	finished=0;
-	synth=new_fluid_synth(settings);
-	player=new_fluid_player(synth);
-	fluid_player_add(player,fn);
-}
-void CMidiPlayer::rendererThread()
-{
-	fluid_file_renderer_t* renderer=new_fluid_file_renderer(synth);
-	fluid_player_play(player);
-	while(fluid_player_get_status(player)==FLUID_PLAYER_PLAYING)
-		if(fluid_file_renderer_process_block(renderer)!=FLUID_OK)break;
-	delete_fluid_file_renderer(renderer);
-	finished=1;
-}
-void CMidiPlayer::rendererDeinit()
-{
-	delete_fluid_player(player);
-	delete_fluid_synth(synth);
-	delete_fluid_settings(settings);
-	player=NULL;synth=NULL;settings=NULL;
-}
-
-void CMidiPlayer::sendSysX(bool send){sendSysEx=send;}
-uint32_t CMidiPlayer::getStamp(int id){return stamps[id];}
-uint32_t CMidiPlayer::getTCeptr(){return tceptr;}
-void CMidiPlayer::setTCeptr(uint32_t ep,uint32_t st)
-{
-	resumed=true;
-	if(ep==midiFile->getEventCount())tcstop=1;else tceptr=ep;
-	for(int i=0;i<16;++i)
-	{
-		for(int j=0;j<120;++j)fluid_synth_cc(synth,i,j,ccstamps[st][i][j]);
-		fluid_synth_program_change(synth,i,ccstamps[st][i][128]);
-		//fluid_synth_pitch_bend(synth,i,ccstamps[st][i][130]);
-		dpt=ccstamps[st][0][131];ctempo=dpt*divs/1000;
-		ctsn=ccstamps[st][0][132]>>24;ctsd=1<<((ccstamps[st][0][132]>>16)&0xFF);
-		cks=ccstamps[st][0][133];
-	}
-}
-double CMidiPlayer::getFtime(){return ftime;}
-void CMidiPlayer::getCurrentTimeSignature(int *n,int *d){*n=ctsn;*d=ctsd;}
-void CMidiPlayer::getCurrentKeySignature(int *ks){*ks=cks;}
-uint32_t CMidiPlayer::getFileNoteCount(){return midiFile?midiFile->getNoteCount():0;}
-uint32_t CMidiPlayer::getFileStandard(){return midiFile?midiFile->getStandard():0;}
-const char* CMidiPlayer::getTitle(){return midiFile?midiFile->getTitle():"";}
-const char* CMidiPlayer::getCopyright(){return midiFile?midiFile->getCopyright():"";}
-double CMidiPlayer::getTempo(){return 60./(ctempo/1e6)/**ctsd/4.*/;}
-uint32_t CMidiPlayer::getTCpaused(){return tcpaused;}
-void CMidiPlayer::setTCpaused(uint32_t ps){tcpaused=ps;}
-uint32_t CMidiPlayer::isFinished(){return finished;}
-void CMidiPlayer::setResumed(){resumed=true;}
-void CMidiPlayer::setWaitVoice(bool wv){waitvoice=wv;}
-void CMidiPlayer::setGain(double gain){if(settings)fluid_settings_setnum(settings,"synth.gain",gain);}
-int CMidiPlayer::getPolyphone(){return synth?fluid_synth_get_active_voice_count(synth):0;}
-int CMidiPlayer::getMaxPolyphone(){return synth?fluid_synth_get_polyphony(synth):0;}
-void CMidiPlayer::setMaxPolyphone(int p){if(synth)fluid_synth_set_polyphony(synth,p);}
-
-void CMidiPlayer::getChannelPreset(int ch,int *b,int *p,char *name)
-{
-	if(!synth)return(void)(b=0,p=0,strcpy(name,""));
-	fluid_synth_channel_info_t info;
-	fluid_synth_get_channel_info(synth,ch,&info);
-	*b=info.bank;*p=info.program;
-	strcpy(name,info.name);
-}
-void CMidiPlayer::setChannelPreset(int ch,int b,int p)
-{
-	if(!synth)return;
-	fluid_synth_bank_select(synth,ch,b);
-	fluid_synth_program_change(synth,ch,p);
-}
-//16MSB..LSB1
-void CMidiPlayer::setBit(uint16_t &n, uint16_t bn, uint16_t b)
-{n^=(-b^n)&(1<<bn);}
-void CMidiPlayer::setMute(int ch,bool m)
-{setBit(mute,ch,m?1:0);}
-void CMidiPlayer::setSolo(int ch,bool s)
-{setBit(solo,ch,s?1:0);}
-int CMidiPlayer::getCC(int ch, int id)
-{int ret=0;synth?fluid_synth_get_cc(synth,ch,id,&ret):0;return ret;}
-void CMidiPlayer::setCC(int ch, int id, int val)
-{synth?fluid_synth_cc(synth,ch,id,val):0;}
-void CMidiPlayer::getReverbPara(double *r,double *d,double *w,double *l)
-{
-	if(!synth)return;
-	*r=fluid_synth_get_reverb_roomsize(synth);
-	*d=fluid_synth_get_reverb_damp(synth);
-	*w=fluid_synth_get_reverb_width(synth);
-	*l=fluid_synth_get_reverb_level(synth);
-}
-void CMidiPlayer::setReverbPara(int e,double r,double d,double w,double l)
-{
-	if(!synth)return;
-	fluid_synth_set_reverb_on(synth,e);
-	fluid_synth_set_reverb(synth,r,d,w,l);
-}
-void CMidiPlayer::getChorusPara(int *fb,double *l,double *r,double *d,int *type)
-{
-	if(!synth)return;
-	*fb=fluid_synth_get_chorus_nr(synth);
-	*l=fluid_synth_get_chorus_level(synth);
-	*r=fluid_synth_get_chorus_speed_Hz(synth);
-	*d=fluid_synth_get_chorus_depth_ms(synth);
-	*type=fluid_synth_get_chorus_type(synth);
-}
-void CMidiPlayer::setChorusPara(int e,int fb,double l,double r,double d,int type)
-{
-	if(!synth)return;
-	fluid_synth_set_chorus_on(synth,e);
-	fluid_synth_set_chorus(synth,fb,l,r,d,type);
-}
-fluid_settings_t* CMidiPlayer::getFluidSettings(){return settings;}
-void CMidiPlayer::pushSoundFont(const char *sf)
-{fluid_synth_sfload(synth,sf,1);}
-int CMidiPlayer::getSFCount()
-{return synth?fluid_synth_sfcount(synth):0;}
-fluid_sfont_t* CMidiPlayer::getSFPtr(int sfid)
-{return synth&&sfid<getSFCount()?fluid_synth_get_sfont(synth,sfid):NULL;}
diff --git a/common/qmpmidiplay.hpp b/common/qmpmidiplay.hpp
deleted file mode 100644
index fafd677..0000000
--- a/common/qmpmidiplay.hpp
+++ /dev/null
@@ -1,137 +0,0 @@
-//sorry for the stupid C-like code...
-#ifndef QMPMIDIPLAY_H
-#define QMPMIDIPLAY_H
-#include <cstring>
-#include <cstdint>
-#include <cstdlib>
-#include <fluidsynth.h>
-struct SEvent
-{
-	uint32_t iid,time,p1,p2;
-	uint8_t type;
-	char *str;
-	SEvent(){time=p1=p2=0;type=0;str=NULL;}
-	SEvent(uint32_t _iid,uint32_t _t,char _tp,uint32_t _p1,uint32_t _p2,const char* s=NULL)
-	{
-		iid=_iid;time=_t;type=_tp;
-		p1=_p1;p2=_p2;
-		if(s){str=new char[strlen(s)+2];strcpy(str,s);}else str=NULL;
-	}
-};
-class CMidiFile
-{
-	private:
-		SEvent *eventList[10000000];
-		char *title,*copyright;
-		uint32_t eventc,std;//standard 0=? 1=GM 2=GM2 3=GS 4=XG
-		uint32_t fmt,trk,divs;
-		FILE *f;
-		int byteread,valid;
-		uint32_t notes,curt,curid;
-
-		void error(int fatal,const char* format,...);
-		uint32_t readSW();
-		uint32_t readDW();
-		uint32_t readVL();
-		int eventReader();
-		void trackChunkReader();
-		void headerChunkReader();
-		int chunkReader(int hdrXp);
-	public:
-		CMidiFile(const char* fn);
-		~CMidiFile();
-		const SEvent* getEvent(uint32_t id);
-		uint32_t getEventCount();
-		uint32_t getDivision();
-		uint32_t getNoteCount();
-		uint32_t getStandard();
-		const char* getTitle();
-		const char* getCopyright();
-		bool isValid();
-};
-class CMidiPlayer
-{
-	private:
-		CMidiFile *midiFile;
-		uint32_t stamps[101];
-		uint32_t ccstamps[101][16][135],ccc[16][135];
-		//0..127:cc 128:pc 129:cp 130:pb 131:tempo 132:ts 133:ks 134:pbr
-		int32_t rpnid,rpnval;
-		uint16_t mute,solo;
-		double ftime;
-		bool sendSysEx,singleInstance,waitvoice;
-		fluid_settings_t* settings;
-		fluid_synth_t* synth;
-		fluid_audio_driver_t* adriver;
-		fluid_player_t* player;
-		uint32_t ctempo,ctsn,ctsd,dpt,divs,cks;
-		//raw tempo, timesig num., timesig den., delay per tick, division, keysig
-		//thread control
-		uint32_t tceptr,tcpaused,tcstop;
-		uint32_t finished,resumed;
-
-		void setBit(uint16_t &n,uint16_t bn,uint16_t b);
-		void processEvent(const SEvent *e);
-		void processEventStub(const SEvent *e);
-		void playEvents();
-		void fileTimer1Pass();
-		void fileTimer2Pass();
-	public:
-		CMidiPlayer(bool singleInst=false);
-		~CMidiPlayer();
-		bool playerLoadFile(const char* fn);
-		void playerInit();
-		void fluidPreInitialize();
-		void fluidInitialize();
-		void fluidDeinitialize();
-		void playerDeinit();
-		void playerThread();
-		void playerPanic(bool reset=false);
-
-		void rendererLoadFile(const char* ofn);
-		void rendererInit(const char *fn);
-		void rendererThread();
-		void rendererDeinit();
-
-		//playing control methods
-		uint32_t getStamp(int id);
-		uint32_t getTCeptr();
-		void setTCeptr(uint32_t ep,uint32_t st);
-		uint32_t getTCpaused();
-		void setTCpaused(uint32_t ps);
-		uint32_t isFinished();
-		void setResumed();
-		void setWaitVoice(bool wv);
-
-		double getFtime();
-		void getCurrentTimeSignature(int *n,int *d);
-		void getCurrentKeySignature(int *ks);
-		uint32_t getFileNoteCount();
-		uint32_t getFileStandard();
-		double getTempo();
-		const char* getTitle();
-		const char* getCopyright();
-
-		void setGain(double gain);
-		void sendSysX(bool send);
-		int getPolyphone();
-		int getMaxPolyphone();
-		void setMaxPolyphone(int p);
-
-		void setChannelPreset(int ch,int b,int p);
-		void getChannelPreset(int ch,int *b,int *p,char *name);
-		void setMute(int ch,bool m);
-		void setSolo(int ch,bool s);
-		int getCC(int ch,int id);
-		void setCC(int ch,int id,int val);
-		void getReverbPara(double *r,double *d,double *w,double *l);
-		void setReverbPara(int e,double r,double d,double w,double l);
-		void getChorusPara(int *fb,double *l,double *r,double *d,int *type);
-		void setChorusPara(int e,int fb,double l,double r,double d,int type);
-
-		fluid_settings_t* getFluidSettings();
-		void pushSoundFont(const char* sf);
-		int getSFCount();
-		fluid_sfont_t* getSFPtr(int sfid);
-};
-#endif
diff --git a/common/qmpmidiread.cpp b/common/qmpmidiread.cpp
deleted file mode 100644
index fd2e0d9..0000000
--- a/common/qmpmidiread.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-//CLI Midi file player based on libfluidsynth
-//Midi file reading module
-//Written by Chris Xiong, 2015
-#include <cstdio>
-#include <cstring>
-#include <cstdlib>
-#include <cstdint>
-#include <cstdarg>
-#include <algorithm>
-#include "qmpmidiplay.hpp"
-const char* GM1SysX={"\xF0\x7E\x7F\x09\x01\xF7"};
-const char* GM2SysX={"\xF0\x7E\x7F\x09\x03\xF7"};
-const char* GSSysEx={"\xF0\x41\x10\x42\x12\x40\x00\x7F\x00\x41\xF7"};
-const char* XGSysEx={"\xF0\x43\x10\x4C\x00\x00\x7E\x00\xF7"};
-bool cmp(SEvent *a,SEvent *b){return a->time-b->time?a->time<b->time:a->iid<b->iid;}
-void CMidiFile::error(int fatal,const char* format,...)
-{
-	va_list ap;
-	va_start(ap,format);vfprintf(stderr,format,ap);va_end(ap);
-	fprintf(stderr," at %#lx\n",ftell(f));
-	if(fatal)throw 2;
-}
-uint32_t CMidiFile::readSW()
-{
-	byteread+=2;
-	uint32_t ret=0;
-	for(int i=0;i<2;++i){ret<<=8;ret|=((uint32_t)fgetc(f))&0xFF;}
-	return ret;
-}
-uint32_t CMidiFile::readDW()
-{
-	byteread+=4;
-	uint32_t ret=0;
-	for(int i=0;i<4;++i){ret<<=8;ret|=((uint32_t)fgetc(f))&0xFF;}
-	return ret;
-}
-uint32_t CMidiFile::readVL()
-{
-	uint32_t ret=0,t,c=0;
-	do
-	{
-		t=fgetc(f);
-		if(++c>4)error(1,"E: Variable length type overflow.");
-		ret<<=7;ret|=(t&0x7F);
-	}while(t&0x80);
-	byteread+=c;
-	return ret;
-}
-int CMidiFile::eventReader()//returns 0 if End of Track encountered
-{
-	uint32_t delta=readVL();curt+=delta;
-	char type=fgetc(f);++byteread;uint32_t p1,p2;
-	static char lasttype;
-retry:
-	switch(type&0xF0)
-	{
-		case 0x80://Note Off
-			p1=fgetc(f);p2=fgetc(f);byteread+=2;
-			eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
-		break;
-		case 0x90://Note On
-			p1=fgetc(f);p2=fgetc(f);byteread+=2;
-			if(p2)
-			{
-				++notes;
-				eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
-			}
-			else
-				eventList[eventc++]=new SEvent(curid,curt,(type&0x0F)|0x80,p1,p2);
-		break;
-		case 0xA0://Note Aftertouch
-			p1=fgetc(f);p2=fgetc(f);byteread+=2;
-			eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
-		break;
-		case 0xB0://Controller Change
-			p1=fgetc(f);p2=fgetc(f);byteread+=2;
-			eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
-		break;
-		case 0xC0://Patch Change
-			p1=fgetc(f);++byteread;
-			eventList[eventc++]=new SEvent(curid,curt,type,p1,0);
-		break;
-		case 0xD0://Channel Aftertouch
-			p1=fgetc(f);++byteread;
-			eventList[eventc++]=new SEvent(curid,curt,type,p1,0);
-		break;
-		case 0xE0://Pitch wheel
-			p1=fgetc(f);p2=fgetc(f);byteread+=2;
-			eventList[eventc++]=new SEvent(curid,curt,type,(p1|(p2<<7))&0x3FFF,0);
-		break;
-		case 0xF0:
-			if((type&0x0F)==0x0F)//Meta Event
-			{
-				char metatype=fgetc(f);++byteread;
-				switch(metatype)
-				{
-					case 0x00://Sequence Number
-						fgetc(f);fgetc(f);fgetc(f);
-						byteread+=3;
-					break;
-					case 0x20://Channel Prefix
-						fgetc(f);fgetc(f);byteread+=2;
-					break;
-					case 0x2F://End of Track
-						fgetc(f);++byteread;
-						return 0;
-					break;
-					case 0x51://Set Tempo
-						p1=readDW();p1&=0x00FFFFFF;
-						eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1);
-					break;
-					case 0x54://SMTPE offset, not handled.
-						fgetc(f);fgetc(f);fgetc(f);
-						fgetc(f);fgetc(f);fgetc(f);
-						byteread+=6;
-					break;
-					case 0x58://Time signature
-						fgetc(f);++byteread;
-						p1=readDW();
-						eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1);
-					break;
-					case 0x59://Key signature
-						fgetc(f);++byteread;
-						p1=readSW();
-						eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1);
-					break;
-					case 0x01:case 0x02:case 0x03:
-					case 0x04:case 0x05:case 0x06:
-					case 0x07:case 0x7F:default://text-like meta
-					{
-						uint32_t len=readVL(),c;char* str=NULL;
-						if(len<=1024&&len>0)str=new char[len+8];
-						for(c=0;c<len;++c)
-						{
-							++byteread;if(str)str[c]=fgetc(f);else fgetc(f);
-						}
-						if(str)str[c]='\0';eventList[eventc++]=new SEvent(curid,curt,type,metatype,0,str);
-						if(str&&metatype==0x03&&!title)
-						{
-							title=new char[len+8];
-							strcpy(title,str);
-						}
-						if(str&&metatype==0x02&&!copyright)
-						{
-							copyright=new char[len+8];
-							strcpy(copyright,str);
-						}
-						if(len<=1024&&len>0)delete[] str;
-					}
-				}
-			}
-			else if((type&0x0F)==0x00||(type&0x0F)==0x07)//SysEx
-			{
-				uint32_t len=readVL(),c;char* str=NULL;
-				str=new char[len+8];
-				if((type&0x0F)==0x00)
-				{
-					str[0]=0xF0;++len;
-					for(c=1;c<len;++c){++byteread;str[c]=fgetc(f);}
-				}
-				else for(c=0;c<len;++c){++byteread;str[c]=fgetc(f);}
-				eventList[eventc++]=new SEvent(curid,curt,type,len,0,str);
-				if(!strcmp(str,GM1SysX))std=1;
-				if(!strcmp(str,GM2SysX))std=2;
-				if(!strcmp(str,GSSysEx))std=3;
-				if(!strcmp(str,XGSysEx))std=4;
-			}
-			else error(0,"W: Unknown event type %#x",type);
-		break;
-		default:
-			fseek(f,-1,SEEK_CUR);--byteread;type=lasttype;goto retry;
-	}
-	lasttype=type;++curid;
-	return 1;
-}
-void CMidiFile::trackChunkReader()
-{
-	int chnklen=readDW();byteread=0;curt=0;curid=0;
-	while(/*byteread<chnklen&&*/eventReader());
-	if(byteread<chnklen)
-	{
-		error(0,"W: Extra bytes after EOT event.");
-		while(byteread<chnklen){fgetc(f);++byteread;}
-	}
-	/*if(byteread>chnklen)
-	{
-		error(1,"E: Read past end of track.");
-	}*/
-}
-void CMidiFile::headerChunkReader()
-{
-	int chnklen=readDW();byteread=0;
-	if(chnklen<6)error(1,"E: Header chunk too short.");
-	if(chnklen>6)error(0,"W: Header chunk length longer than expected. Ignoring extra bytes.");
-	fmt=readSW();trk=readSW();divs=readSW();
-	if(divs&0x8000)error(1,"E: SMTPE format is not supported.");
-	for(;byteread<chnklen;++byteread){fgetc(f);}
-}
-int CMidiFile::chunkReader(int hdrXp)
-{
-	char hdr[6];
-	if(!fgets(hdr,5,f))error(1,"E: Unexpected EOF.");
-	if(hdrXp)
-		if(strncmp(hdr,"MThd",4)){error(1,"E: Wrong MIDI header.");throw;}
-		else return headerChunkReader(),0;
-	else
-		if(strncmp(hdr,"MTrk",4))
-		{
-			error(0,"W: Wrong track chunk header. Ignoring the whole chunk.");
-			for(int chnklen=readDW();chnklen>0;--chnklen)fgetc(f);return 0;
-		}
-		else return trackChunkReader(),1;
-}
-CMidiFile::CMidiFile(const char* fn)
-{
-	title=copyright=NULL;notes=eventc=0;std=0;valid=1;
-	try
-	{
-		if(!(f=fopen(fn,"rb")))throw (fprintf(stderr,"E: file %s doesn't exist!\n",fn),2);
-		chunkReader(1);
-		for(uint32_t i=0;i<trk;i+=chunkReader(0));
-		fclose(f);
-		std::sort(eventList,eventList+eventc,cmp);
-	}
-	catch(int){fprintf(stderr,"E: %s is not a supported file.\n",fn);valid=0;}
-}
-CMidiFile::~CMidiFile()
-{
-	for(uint32_t i=0;i<eventc;++i)delete eventList[i];
-	if(title)delete[] title;if(copyright)delete[] copyright;
-}
-const SEvent* CMidiFile::getEvent(uint32_t id){return id<eventc?eventList[id]:NULL;}
-uint32_t CMidiFile::getEventCount(){return eventc;}
-uint32_t CMidiFile::getDivision(){return divs;}
-uint32_t CMidiFile::getNoteCount(){return notes;}
-uint32_t CMidiFile::getStandard(){return std;}
-bool CMidiFile::isValid(){return valid;}
-const char* CMidiFile::getTitle(){return title;}
-const char* CMidiFile::getCopyright(){return copyright;}
diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp
new file mode 100644
index 0000000..6f69e33
--- /dev/null
+++ b/core/qmpmidiplay.cpp
@@ -0,0 +1,404 @@
+#include <cstdio>
+#include <chrono>
+#include <thread>
+#include <fluidsynth.h>
+#include "qmpmidiplay.hpp"
+#ifdef _WIN32
+#include <windows.h>
+uint64_t pf;
+#endif
+void CMidiPlayer::fluidPreInitialize()
+{
+	settings=new_fluid_settings();
+}
+void CMidiPlayer::fluidInitialize()
+{
+	synth=new_fluid_synth(settings);
+	adriver=new_fluid_audio_driver(settings,synth);
+	fluid_synth_set_chorus(synth,FLUID_CHORUS_DEFAULT_N,FLUID_CHORUS_DEFAULT_LEVEL,
+						   FLUID_CHORUS_DEFAULT_SPEED,FLUID_CHORUS_DEFAULT_DEPTH,
+						   FLUID_CHORUS_DEFAULT_TYPE);
+#ifndef _WIN32
+	if(!singleInstance)
+	{
+		if(midiFile->getStandard()==4)
+		fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_MELODIC);
+		else if(midiFile->getStandard()==1)
+			fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_DRUM);
+		else
+		{
+			fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_DRUM);
+			fluid_synth_bank_select(synth,9,128);
+		}
+	}
+#endif
+}
+void CMidiPlayer::fluidDeinitialize()
+{
+	if(!synth||!adriver||!settings)return;
+	delete_fluid_settings(settings);
+	delete_fluid_audio_driver(adriver);
+	delete_fluid_synth(synth);
+	settings=NULL;synth=NULL;adriver=NULL;
+}
+void CMidiPlayer::processEvent(const SEvent *e)
+{
+	switch(e->type&0xF0)
+	{
+		case 0x80://Note off
+			fluid_synth_noteoff(synth,e->type&0x0F,e->p1);
+		break;
+		case 0x90://Note on
+			if((mute>>(e->type&0x0F))&1)break;//muted
+			if(solo&&!((solo>>(e->type&0x0F))&1))break;
+			fluid_synth_noteon(synth,e->type&0x0F,e->p1,e->p2);
+		break;
+		case 0xB0://CC
+			if(e->p1==100)rpnid=e->p2;
+			if(e->p1==6)rpnval=e->p2;
+			if(~rpnid&&~rpnval)
+			{
+				if(rpnid==0)fluid_synth_pitch_wheel_sens(synth,e->type&0x0F,rpnval);
+				rpnid=rpnval=-1;
+			}
+			fluid_synth_cc(synth,e->type&0x0F,e->p1,e->p2);
+		break;
+		case 0xC0://PC
+			fluid_synth_program_change(synth,e->type&0x0F,e->p1);
+		break;
+		case 0xE0://PW
+			fluid_synth_pitch_bend(synth,e->type&0x0F,e->p1);
+		break;
+		case 0xF0://Meta/SysEx
+			if((e->type&0x0F)==0x0F)
+			{
+				switch(e->p1)
+				{
+					case 0x51:
+						ctempo=e->p2;dpt=ctempo*1000/divs;
+					break;
+					case 0x58:
+						ctsn=e->p2>>24;
+						ctsd=1<<((e->p2>>16)&0xFF);
+					break;
+					case 0x59:
+						cks=e->p2;
+					break;
+					case 0x01:case 0x02:case 0x03:
+					case 0x04:case 0x05:case 0x06:
+					case 0x07:
+						//if(e->str)puts(e->str);
+					break;
+				}
+			}
+			if((e->type&0x0F)==0x00||(e->type&0x0F)==07)
+			{
+				int io=0;
+				if(sendSysEx)fluid_synth_sysex(synth,e->str,e->p1,NULL,&io,NULL,0);
+			}
+		break;
+	}
+}
+void CMidiPlayer::processEventStub(const SEvent *e)
+{
+	switch(e->type&0xF0)
+	{
+		case 0xB0://CC
+			if(e->p1==100)rpnid=e->p2;
+			if(e->p1==6)rpnval=e->p2;
+			if(~rpnid&&~rpnval)
+			{
+				if(rpnid==0)ccc[e->type&0x0F][134]=rpnval;
+				rpnid=rpnval=-1;
+			}
+			ccc[e->type&0x0F][e->p1]=e->p2;
+		break;
+		case 0xC0://PC
+			ccc[e->type&0x0F][128]=e->p1;
+		break;
+		case 0xD0://CP
+			ccc[e->type&0x0F][129]=e->p1;
+		break;
+		case 0xE0://PW
+			ccc[e->type&0x0F][130]=e->p1;
+		break;
+		case 0xF0://Meta/SysEx
+			if((e->type&0x0F)==0x0F)
+			{
+				switch(e->p1)
+				{
+					case 0x51:
+						ctempo=e->p2;dpt=ctempo*1000/divs;
+						ccc[0][131]=dpt;
+					break;
+					case 0x58:
+						ccc[0][132]=e->p2;
+					break;
+					case 0x59:
+						ccc[0][133]=e->p2;
+					break;
+				}
+			}
+		break;
+	}
+}
+#ifdef _WIN32
+void w32usleep(uint64_t t)
+{
+	uint64_t st=0,ct=0;
+	timeBeginPeriod(1);
+	QueryPerformanceCounter((LARGE_INTEGER*)&st);
+	do{
+		if(t>10000+(ct-st)*1000000/pf)Sleep((t-(ct-st)*1000000/pf)/2000);
+		else if(t>5000+(ct-st)*1000000/pf)Sleep(1);
+		else std::this_thread::yield();
+		QueryPerformanceCounter((LARGE_INTEGER*)&ct);
+	}while((ct-st)*1000000<t*pf);
+	timeEndPeriod(1);
+}
+#endif
+void CMidiPlayer::playEvents()
+{
+	for(uint32_t ct=midiFile->getEvent(0)->time;tceptr<midiFile->getEventCount();)
+	{
+		while(tcpaused)std::this_thread::sleep_for(std::chrono::milliseconds(100));
+		while(!tcstop&&midiFile&&tceptr<midiFile->getEventCount()&&ct==midiFile->getEvent(tceptr)->time)
+			processEvent(midiFile->getEvent(tceptr++));
+		if(tcstop||!midiFile||tceptr>=midiFile->getEventCount())break;
+		if(resumed)resumed=false;
+		else
+#if 0
+		w32usleep((midiFile->getEvent(tceptr)->time-ct)*(dpt/1000));
+#else
+		std::this_thread::sleep_for(std::chrono::nanoseconds(midiFile->getEvent(tceptr)->time-ct)*dpt);
+#endif
+		if(tcstop||!midiFile)break;
+		ct=midiFile->getEvent(tceptr)->time;
+	}
+	while(!tcstop&&synth&&(waitvoice&&fluid_synth_get_active_voice_count(synth)>0))std::this_thread::sleep_for(std::chrono::milliseconds(2));
+	finished=1;
+}
+void CMidiPlayer::fileTimer1Pass()
+{
+	ftime=.0;ctempo=0x7A120;dpt=ctempo*1000/divs;
+	for(uint32_t eptr=0,ct=midiFile->getEvent(0)->time;eptr<midiFile->getEventCount();)
+	{
+		while(eptr<midiFile->getEventCount()&&ct==midiFile->getEvent(eptr)->time)
+			processEventStub(midiFile->getEvent(eptr++));
+		if(eptr>=midiFile->getEventCount())break;
+		ftime+=(midiFile->getEvent(eptr)->time-ct)*dpt/1e9;
+		ct=midiFile->getEvent(eptr)->time;
+	}
+}
+void CMidiPlayer::fileTimer2Pass()
+{
+	double ctime=.0;uint32_t c=1;ctempo=0x7A120;dpt=ctempo*1000/divs;
+	memset(stamps,0,sizeof(stamps));memset(ccstamps,0,sizeof(ccstamps));
+	memset(ccc,0,sizeof(ccc));rpnid=rpnval=-1;for(int i=0;i<16;++i)
+	{
+		ccc[i][7]=100;ccc[i][10]=64;ccc[i][11]=127;
+		ccc[i][11]=127;ccc[i][71]=64;ccc[i][72]=64;
+		ccc[i][73]=64;ccc[i][74]=64;ccc[i][75]=64;
+		ccc[i][76]=64;ccc[i][77]=64;ccc[i][78]=64;
+		ccc[0][131]=dpt;ccc[0][132]=0x04021808;
+		ccc[0][133]=0;ccc[0][134]=2;
+	}if(midiFile->getStandard()!=4)ccc[9][0]=128;
+	for(int i=0;i<16;++i)for(int j=0;j<135;++j)
+		ccstamps[0][i][j]=ccc[i][j];
+	for(uint32_t eptr=0,ct=midiFile->getEvent(0)->time;eptr<midiFile->getEventCount();)
+	{
+		while(eptr<midiFile->getEventCount()&&ct==midiFile->getEvent(eptr)->time)
+			processEventStub(midiFile->getEvent(eptr++));
+		if(eptr>=midiFile->getEventCount())break;
+		ctime+=(midiFile->getEvent(eptr)->time-ct)*dpt/1e9;
+		while(ctime>ftime*c/100.)
+		{
+			for(int i=0;i<16;++i)for(int j=0;j<135;++j)
+				ccstamps[c][i][j]=ccc[i][j];
+			stamps[c++]=eptr;
+			if(c>100)break;
+		}
+		ct=midiFile->getEvent(eptr)->time;
+	}
+	while(c<101)
+	{
+		for(int i=0;i<16;++i)for(int j=0;j<135;++j)
+			ccstamps[c][i][j]=ccc[i][j];
+		stamps[c++]=midiFile->getEventCount();
+	}
+}
+CMidiPlayer::CMidiPlayer(bool singleInst)
+{
+	midiFile=NULL;resumed=false;singleInstance=singleInst;
+	settings=NULL;synth=NULL;adriver=NULL;waitvoice=true;
+#ifdef _WIN32
+	QueryPerformanceFrequency((LARGE_INTEGER*)&pf);
+#endif
+}
+CMidiPlayer::~CMidiPlayer()
+{
+	if(singleInstance)fluidDeinitialize();
+}
+void CMidiPlayer::playerPanic(bool reset)
+{
+	if(reset)for(int i=0;i<16;++i)
+	{
+		fluid_synth_pitch_bend(synth,i,8192);
+		fluid_synth_cc(synth,i,7,100);
+		fluid_synth_cc(synth,i,10,64);
+		fluid_synth_cc(synth,i,11,127);
+	}
+	for(int i=0;i<16;++i)fluid_synth_all_notes_off(synth,i);
+}
+bool CMidiPlayer::playerLoadFile(const char* fn)
+{
+	midiFile=new CMidiFile(fn);
+	if(!midiFile->isValid())return false;
+	divs=midiFile->getDivision();
+	fileTimer1Pass();
+	fileTimer2Pass();
+	return true;
+}
+void CMidiPlayer::playerInit()
+{
+	ctempo=0x7A120;ctsn=4;ctsd=4;cks=0;dpt=ctempo*1000/divs;
+	tceptr=0;tcstop=0;tcpaused=0;finished=0;mute=solo=0;
+	sendSysEx=true;rpnid=rpnval=-1;
+	if(!singleInstance)fluidPreInitialize();
+}
+void CMidiPlayer::playerDeinit()
+{
+	tceptr=0;tcstop=1;tcpaused=0;
+	delete midiFile;midiFile=NULL;
+	if(!singleInstance)fluidDeinitialize();
+}
+void CMidiPlayer::playerThread()
+{
+	playEvents();
+}
+
+void CMidiPlayer::rendererLoadFile(const char* ofn)
+{
+	settings=new_fluid_settings();
+	fluid_settings_setstr(settings,"audio.file.name",ofn);
+}
+void CMidiPlayer::rendererInit(const char* fn)
+{
+	finished=0;
+	synth=new_fluid_synth(settings);
+	player=new_fluid_player(synth);
+	fluid_player_add(player,fn);
+}
+void CMidiPlayer::rendererThread()
+{
+	fluid_file_renderer_t* renderer=new_fluid_file_renderer(synth);
+	fluid_player_play(player);
+	while(fluid_player_get_status(player)==FLUID_PLAYER_PLAYING)
+		if(fluid_file_renderer_process_block(renderer)!=FLUID_OK)break;
+	delete_fluid_file_renderer(renderer);
+	finished=1;
+}
+void CMidiPlayer::rendererDeinit()
+{
+	delete_fluid_player(player);
+	delete_fluid_synth(synth);
+	delete_fluid_settings(settings);
+	player=NULL;synth=NULL;settings=NULL;
+}
+
+void CMidiPlayer::sendSysX(bool send){sendSysEx=send;}
+uint32_t CMidiPlayer::getStamp(int id){return stamps[id];}
+uint32_t CMidiPlayer::getTCeptr(){return tceptr;}
+void CMidiPlayer::setTCeptr(uint32_t ep,uint32_t st)
+{
+	resumed=true;
+	if(ep==midiFile->getEventCount())tcstop=1;else tceptr=ep;
+	for(int i=0;i<16;++i)
+	{
+		for(int j=0;j<120;++j)fluid_synth_cc(synth,i,j,ccstamps[st][i][j]);
+		fluid_synth_program_change(synth,i,ccstamps[st][i][128]);
+		//fluid_synth_pitch_bend(synth,i,ccstamps[st][i][130]);
+		dpt=ccstamps[st][0][131];ctempo=dpt*divs/1000;
+		ctsn=ccstamps[st][0][132]>>24;ctsd=1<<((ccstamps[st][0][132]>>16)&0xFF);
+		cks=ccstamps[st][0][133];
+	}
+}
+double CMidiPlayer::getFtime(){return ftime;}
+void CMidiPlayer::getCurrentTimeSignature(int *n,int *d){*n=ctsn;*d=ctsd;}
+void CMidiPlayer::getCurrentKeySignature(int *ks){*ks=cks;}
+uint32_t CMidiPlayer::getFileNoteCount(){return midiFile?midiFile->getNoteCount():0;}
+uint32_t CMidiPlayer::getFileStandard(){return midiFile?midiFile->getStandard():0;}
+const char* CMidiPlayer::getTitle(){return midiFile?midiFile->getTitle():"";}
+const char* CMidiPlayer::getCopyright(){return midiFile?midiFile->getCopyright():"";}
+double CMidiPlayer::getTempo(){return 60./(ctempo/1e6)/**ctsd/4.*/;}
+uint32_t CMidiPlayer::getTCpaused(){return tcpaused;}
+void CMidiPlayer::setTCpaused(uint32_t ps){tcpaused=ps;}
+uint32_t CMidiPlayer::isFinished(){return finished;}
+void CMidiPlayer::setResumed(){resumed=true;}
+void CMidiPlayer::setWaitVoice(bool wv){waitvoice=wv;}
+void CMidiPlayer::setGain(double gain){if(settings)fluid_settings_setnum(settings,"synth.gain",gain);}
+int CMidiPlayer::getPolyphone(){return synth?fluid_synth_get_active_voice_count(synth):0;}
+int CMidiPlayer::getMaxPolyphone(){return synth?fluid_synth_get_polyphony(synth):0;}
+void CMidiPlayer::setMaxPolyphone(int p){if(synth)fluid_synth_set_polyphony(synth,p);}
+
+void CMidiPlayer::getChannelPreset(int ch,int *b,int *p,char *name)
+{
+	if(!synth)return(void)(b=0,p=0,strcpy(name,""));
+	fluid_synth_channel_info_t info;
+	fluid_synth_get_channel_info(synth,ch,&info);
+	*b=info.bank;*p=info.program;
+	strcpy(name,info.name);
+}
+void CMidiPlayer::setChannelPreset(int ch,int b,int p)
+{
+	if(!synth)return;
+	fluid_synth_bank_select(synth,ch,b);
+	fluid_synth_program_change(synth,ch,p);
+}
+//16MSB..LSB1
+void CMidiPlayer::setBit(uint16_t &n, uint16_t bn, uint16_t b)
+{n^=(-b^n)&(1<<bn);}
+void CMidiPlayer::setMute(int ch,bool m)
+{setBit(mute,ch,m?1:0);}
+void CMidiPlayer::setSolo(int ch,bool s)
+{setBit(solo,ch,s?1:0);}
+int CMidiPlayer::getCC(int ch, int id)
+{int ret=0;synth?fluid_synth_get_cc(synth,ch,id,&ret):0;return ret;}
+void CMidiPlayer::setCC(int ch, int id, int val)
+{synth?fluid_synth_cc(synth,ch,id,val):0;}
+void CMidiPlayer::getReverbPara(double *r,double *d,double *w,double *l)
+{
+	if(!synth)return;
+	*r=fluid_synth_get_reverb_roomsize(synth);
+	*d=fluid_synth_get_reverb_damp(synth);
+	*w=fluid_synth_get_reverb_width(synth);
+	*l=fluid_synth_get_reverb_level(synth);
+}
+void CMidiPlayer::setReverbPara(int e,double r,double d,double w,double l)
+{
+	if(!synth)return;
+	fluid_synth_set_reverb_on(synth,e);
+	fluid_synth_set_reverb(synth,r,d,w,l);
+}
+void CMidiPlayer::getChorusPara(int *fb,double *l,double *r,double *d,int *type)
+{
+	if(!synth)return;
+	*fb=fluid_synth_get_chorus_nr(synth);
+	*l=fluid_synth_get_chorus_level(synth);
+	*r=fluid_synth_get_chorus_speed_Hz(synth);
+	*d=fluid_synth_get_chorus_depth_ms(synth);
+	*type=fluid_synth_get_chorus_type(synth);
+}
+void CMidiPlayer::setChorusPara(int e,int fb,double l,double r,double d,int type)
+{
+	if(!synth)return;
+	fluid_synth_set_chorus_on(synth,e);
+	fluid_synth_set_chorus(synth,fb,l,r,d,type);
+}
+fluid_settings_t* CMidiPlayer::getFluidSettings(){return settings;}
+void CMidiPlayer::pushSoundFont(const char *sf)
+{fluid_synth_sfload(synth,sf,1);}
+int CMidiPlayer::getSFCount()
+{return synth?fluid_synth_sfcount(synth):0;}
+fluid_sfont_t* CMidiPlayer::getSFPtr(int sfid)
+{return synth&&sfid<getSFCount()?fluid_synth_get_sfont(synth,sfid):NULL;}
diff --git a/core/qmpmidiplay.hpp b/core/qmpmidiplay.hpp
new file mode 100644
index 0000000..fafd677
--- /dev/null
+++ b/core/qmpmidiplay.hpp
@@ -0,0 +1,137 @@
+//sorry for the stupid C-like code...
+#ifndef QMPMIDIPLAY_H
+#define QMPMIDIPLAY_H
+#include <cstring>
+#include <cstdint>
+#include <cstdlib>
+#include <fluidsynth.h>
+struct SEvent
+{
+	uint32_t iid,time,p1,p2;
+	uint8_t type;
+	char *str;
+	SEvent(){time=p1=p2=0;type=0;str=NULL;}
+	SEvent(uint32_t _iid,uint32_t _t,char _tp,uint32_t _p1,uint32_t _p2,const char* s=NULL)
+	{
+		iid=_iid;time=_t;type=_tp;
+		p1=_p1;p2=_p2;
+		if(s){str=new char[strlen(s)+2];strcpy(str,s);}else str=NULL;
+	}
+};
+class CMidiFile
+{
+	private:
+		SEvent *eventList[10000000];
+		char *title,*copyright;
+		uint32_t eventc,std;//standard 0=? 1=GM 2=GM2 3=GS 4=XG
+		uint32_t fmt,trk,divs;
+		FILE *f;
+		int byteread,valid;
+		uint32_t notes,curt,curid;
+
+		void error(int fatal,const char* format,...);
+		uint32_t readSW();
+		uint32_t readDW();
+		uint32_t readVL();
+		int eventReader();
+		void trackChunkReader();
+		void headerChunkReader();
+		int chunkReader(int hdrXp);
+	public:
+		CMidiFile(const char* fn);
+		~CMidiFile();
+		const SEvent* getEvent(uint32_t id);
+		uint32_t getEventCount();
+		uint32_t getDivision();
+		uint32_t getNoteCount();
+		uint32_t getStandard();
+		const char* getTitle();
+		const char* getCopyright();
+		bool isValid();
+};
+class CMidiPlayer
+{
+	private:
+		CMidiFile *midiFile;
+		uint32_t stamps[101];
+		uint32_t ccstamps[101][16][135],ccc[16][135];
+		//0..127:cc 128:pc 129:cp 130:pb 131:tempo 132:ts 133:ks 134:pbr
+		int32_t rpnid,rpnval;
+		uint16_t mute,solo;
+		double ftime;
+		bool sendSysEx,singleInstance,waitvoice;
+		fluid_settings_t* settings;
+		fluid_synth_t* synth;
+		fluid_audio_driver_t* adriver;
+		fluid_player_t* player;
+		uint32_t ctempo,ctsn,ctsd,dpt,divs,cks;
+		//raw tempo, timesig num., timesig den., delay per tick, division, keysig
+		//thread control
+		uint32_t tceptr,tcpaused,tcstop;
+		uint32_t finished,resumed;
+
+		void setBit(uint16_t &n,uint16_t bn,uint16_t b);
+		void processEvent(const SEvent *e);
+		void processEventStub(const SEvent *e);
+		void playEvents();
+		void fileTimer1Pass();
+		void fileTimer2Pass();
+	public:
+		CMidiPlayer(bool singleInst=false);
+		~CMidiPlayer();
+		bool playerLoadFile(const char* fn);
+		void playerInit();
+		void fluidPreInitialize();
+		void fluidInitialize();
+		void fluidDeinitialize();
+		void playerDeinit();
+		void playerThread();
+		void playerPanic(bool reset=false);
+
+		void rendererLoadFile(const char* ofn);
+		void rendererInit(const char *fn);
+		void rendererThread();
+		void rendererDeinit();
+
+		//playing control methods
+		uint32_t getStamp(int id);
+		uint32_t getTCeptr();
+		void setTCeptr(uint32_t ep,uint32_t st);
+		uint32_t getTCpaused();
+		void setTCpaused(uint32_t ps);
+		uint32_t isFinished();
+		void setResumed();
+		void setWaitVoice(bool wv);
+
+		double getFtime();
+		void getCurrentTimeSignature(int *n,int *d);
+		void getCurrentKeySignature(int *ks);
+		uint32_t getFileNoteCount();
+		uint32_t getFileStandard();
+		double getTempo();
+		const char* getTitle();
+		const char* getCopyright();
+
+		void setGain(double gain);
+		void sendSysX(bool send);
+		int getPolyphone();
+		int getMaxPolyphone();
+		void setMaxPolyphone(int p);
+
+		void setChannelPreset(int ch,int b,int p);
+		void getChannelPreset(int ch,int *b,int *p,char *name);
+		void setMute(int ch,bool m);
+		void setSolo(int ch,bool s);
+		int getCC(int ch,int id);
+		void setCC(int ch,int id,int val);
+		void getReverbPara(double *r,double *d,double *w,double *l);
+		void setReverbPara(int e,double r,double d,double w,double l);
+		void getChorusPara(int *fb,double *l,double *r,double *d,int *type);
+		void setChorusPara(int e,int fb,double l,double r,double d,int type);
+
+		fluid_settings_t* getFluidSettings();
+		void pushSoundFont(const char* sf);
+		int getSFCount();
+		fluid_sfont_t* getSFPtr(int sfid);
+};
+#endif
diff --git a/core/qmpmidiread.cpp b/core/qmpmidiread.cpp
new file mode 100644
index 0000000..fd2e0d9
--- /dev/null
+++ b/core/qmpmidiread.cpp
@@ -0,0 +1,239 @@
+//CLI Midi file player based on libfluidsynth
+//Midi file reading module
+//Written by Chris Xiong, 2015
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <cstdint>
+#include <cstdarg>
+#include <algorithm>
+#include "qmpmidiplay.hpp"
+const char* GM1SysX={"\xF0\x7E\x7F\x09\x01\xF7"};
+const char* GM2SysX={"\xF0\x7E\x7F\x09\x03\xF7"};
+const char* GSSysEx={"\xF0\x41\x10\x42\x12\x40\x00\x7F\x00\x41\xF7"};
+const char* XGSysEx={"\xF0\x43\x10\x4C\x00\x00\x7E\x00\xF7"};
+bool cmp(SEvent *a,SEvent *b){return a->time-b->time?a->time<b->time:a->iid<b->iid;}
+void CMidiFile::error(int fatal,const char* format,...)
+{
+	va_list ap;
+	va_start(ap,format);vfprintf(stderr,format,ap);va_end(ap);
+	fprintf(stderr," at %#lx\n",ftell(f));
+	if(fatal)throw 2;
+}
+uint32_t CMidiFile::readSW()
+{
+	byteread+=2;
+	uint32_t ret=0;
+	for(int i=0;i<2;++i){ret<<=8;ret|=((uint32_t)fgetc(f))&0xFF;}
+	return ret;
+}
+uint32_t CMidiFile::readDW()
+{
+	byteread+=4;
+	uint32_t ret=0;
+	for(int i=0;i<4;++i){ret<<=8;ret|=((uint32_t)fgetc(f))&0xFF;}
+	return ret;
+}
+uint32_t CMidiFile::readVL()
+{
+	uint32_t ret=0,t,c=0;
+	do
+	{
+		t=fgetc(f);
+		if(++c>4)error(1,"E: Variable length type overflow.");
+		ret<<=7;ret|=(t&0x7F);
+	}while(t&0x80);
+	byteread+=c;
+	return ret;
+}
+int CMidiFile::eventReader()//returns 0 if End of Track encountered
+{
+	uint32_t delta=readVL();curt+=delta;
+	char type=fgetc(f);++byteread;uint32_t p1,p2;
+	static char lasttype;
+retry:
+	switch(type&0xF0)
+	{
+		case 0x80://Note Off
+			p1=fgetc(f);p2=fgetc(f);byteread+=2;
+			eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
+		break;
+		case 0x90://Note On
+			p1=fgetc(f);p2=fgetc(f);byteread+=2;
+			if(p2)
+			{
+				++notes;
+				eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
+			}
+			else
+				eventList[eventc++]=new SEvent(curid,curt,(type&0x0F)|0x80,p1,p2);
+		break;
+		case 0xA0://Note Aftertouch
+			p1=fgetc(f);p2=fgetc(f);byteread+=2;
+			eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
+		break;
+		case 0xB0://Controller Change
+			p1=fgetc(f);p2=fgetc(f);byteread+=2;
+			eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
+		break;
+		case 0xC0://Patch Change
+			p1=fgetc(f);++byteread;
+			eventList[eventc++]=new SEvent(curid,curt,type,p1,0);
+		break;
+		case 0xD0://Channel Aftertouch
+			p1=fgetc(f);++byteread;
+			eventList[eventc++]=new SEvent(curid,curt,type,p1,0);
+		break;
+		case 0xE0://Pitch wheel
+			p1=fgetc(f);p2=fgetc(f);byteread+=2;
+			eventList[eventc++]=new SEvent(curid,curt,type,(p1|(p2<<7))&0x3FFF,0);
+		break;
+		case 0xF0:
+			if((type&0x0F)==0x0F)//Meta Event
+			{
+				char metatype=fgetc(f);++byteread;
+				switch(metatype)
+				{
+					case 0x00://Sequence Number
+						fgetc(f);fgetc(f);fgetc(f);
+						byteread+=3;
+					break;
+					case 0x20://Channel Prefix
+						fgetc(f);fgetc(f);byteread+=2;
+					break;
+					case 0x2F://End of Track
+						fgetc(f);++byteread;
+						return 0;
+					break;
+					case 0x51://Set Tempo
+						p1=readDW();p1&=0x00FFFFFF;
+						eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1);
+					break;
+					case 0x54://SMTPE offset, not handled.
+						fgetc(f);fgetc(f);fgetc(f);
+						fgetc(f);fgetc(f);fgetc(f);
+						byteread+=6;
+					break;
+					case 0x58://Time signature
+						fgetc(f);++byteread;
+						p1=readDW();
+						eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1);
+					break;
+					case 0x59://Key signature
+						fgetc(f);++byteread;
+						p1=readSW();
+						eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1);
+					break;
+					case 0x01:case 0x02:case 0x03:
+					case 0x04:case 0x05:case 0x06:
+					case 0x07:case 0x7F:default://text-like meta
+					{
+						uint32_t len=readVL(),c;char* str=NULL;
+						if(len<=1024&&len>0)str=new char[len+8];
+						for(c=0;c<len;++c)
+						{
+							++byteread;if(str)str[c]=fgetc(f);else fgetc(f);
+						}
+						if(str)str[c]='\0';eventList[eventc++]=new SEvent(curid,curt,type,metatype,0,str);
+						if(str&&metatype==0x03&&!title)
+						{
+							title=new char[len+8];
+							strcpy(title,str);
+						}
+						if(str&&metatype==0x02&&!copyright)
+						{
+							copyright=new char[len+8];
+							strcpy(copyright,str);
+						}
+						if(len<=1024&&len>0)delete[] str;
+					}
+				}
+			}
+			else if((type&0x0F)==0x00||(type&0x0F)==0x07)//SysEx
+			{
+				uint32_t len=readVL(),c;char* str=NULL;
+				str=new char[len+8];
+				if((type&0x0F)==0x00)
+				{
+					str[0]=0xF0;++len;
+					for(c=1;c<len;++c){++byteread;str[c]=fgetc(f);}
+				}
+				else for(c=0;c<len;++c){++byteread;str[c]=fgetc(f);}
+				eventList[eventc++]=new SEvent(curid,curt,type,len,0,str);
+				if(!strcmp(str,GM1SysX))std=1;
+				if(!strcmp(str,GM2SysX))std=2;
+				if(!strcmp(str,GSSysEx))std=3;
+				if(!strcmp(str,XGSysEx))std=4;
+			}
+			else error(0,"W: Unknown event type %#x",type);
+		break;
+		default:
+			fseek(f,-1,SEEK_CUR);--byteread;type=lasttype;goto retry;
+	}
+	lasttype=type;++curid;
+	return 1;
+}
+void CMidiFile::trackChunkReader()
+{
+	int chnklen=readDW();byteread=0;curt=0;curid=0;
+	while(/*byteread<chnklen&&*/eventReader());
+	if(byteread<chnklen)
+	{
+		error(0,"W: Extra bytes after EOT event.");
+		while(byteread<chnklen){fgetc(f);++byteread;}
+	}
+	/*if(byteread>chnklen)
+	{
+		error(1,"E: Read past end of track.");
+	}*/
+}
+void CMidiFile::headerChunkReader()
+{
+	int chnklen=readDW();byteread=0;
+	if(chnklen<6)error(1,"E: Header chunk too short.");
+	if(chnklen>6)error(0,"W: Header chunk length longer than expected. Ignoring extra bytes.");
+	fmt=readSW();trk=readSW();divs=readSW();
+	if(divs&0x8000)error(1,"E: SMTPE format is not supported.");
+	for(;byteread<chnklen;++byteread){fgetc(f);}
+}
+int CMidiFile::chunkReader(int hdrXp)
+{
+	char hdr[6];
+	if(!fgets(hdr,5,f))error(1,"E: Unexpected EOF.");
+	if(hdrXp)
+		if(strncmp(hdr,"MThd",4)){error(1,"E: Wrong MIDI header.");throw;}
+		else return headerChunkReader(),0;
+	else
+		if(strncmp(hdr,"MTrk",4))
+		{
+			error(0,"W: Wrong track chunk header. Ignoring the whole chunk.");
+			for(int chnklen=readDW();chnklen>0;--chnklen)fgetc(f);return 0;
+		}
+		else return trackChunkReader(),1;
+}
+CMidiFile::CMidiFile(const char* fn)
+{
+	title=copyright=NULL;notes=eventc=0;std=0;valid=1;
+	try
+	{
+		if(!(f=fopen(fn,"rb")))throw (fprintf(stderr,"E: file %s doesn't exist!\n",fn),2);
+		chunkReader(1);
+		for(uint32_t i=0;i<trk;i+=chunkReader(0));
+		fclose(f);
+		std::sort(eventList,eventList+eventc,cmp);
+	}
+	catch(int){fprintf(stderr,"E: %s is not a supported file.\n",fn);valid=0;}
+}
+CMidiFile::~CMidiFile()
+{
+	for(uint32_t i=0;i<eventc;++i)delete eventList[i];
+	if(title)delete[] title;if(copyright)delete[] copyright;
+}
+const SEvent* CMidiFile::getEvent(uint32_t id){return id<eventc?eventList[id]:NULL;}
+uint32_t CMidiFile::getEventCount(){return eventc;}
+uint32_t CMidiFile::getDivision(){return divs;}
+uint32_t CMidiFile::getNoteCount(){return notes;}
+uint32_t CMidiFile::getStandard(){return std;}
+bool CMidiFile::isValid(){return valid;}
+const char* CMidiFile::getTitle(){return title;}
+const char* CMidiFile::getCopyright(){return copyright;}
diff --git a/debian/changelog b/debian/changelog
index 6437ab1..a57c578 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,27 @@
+qmidiplayer (0.7.0-6) UNRELEASED; urgency=low
+
+  * Package qmidiplayer-lite.
+
+ -- chrisoft <chirs241097@gmail.com>  Wed, 06 Apr 2016 16:45:02 +0800
+
+qmidiplayer (0.7.0-5) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- chrisoft <chirs241097@gmail.com>  Wed, 06 Apr 2016 09:43:57 +0800
+
+qmidiplayer (0.7.0-4) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- chrisoft <chirs241097@gmail.com>  Tue, 05 Apr 2016 22:17:31 +0800
+
+qmidiplayer (0.7.0-3) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- chrisoft <chirs241097@gmail.com>  Wed, 23 Mar 2016 15:41:15 +0800
+
 qmidiplayer (0.7.0-2) UNRELEASED; urgency=low
 
   * New upstream release.
diff --git a/debian/control b/debian/control
index c686b55..44eeaae 100644
--- a/debian/control
+++ b/debian/control
@@ -3,9 +3,18 @@ Maintainer: Chris Xiong <chirs241097@gmail.com>
 Section: sound
 Priority: optional
 Standards-Version: 3.9.2
-Build-Depends: debhelper (>= 9), qtbase5-dev, qt5-qmake, libfluidsynth-dev
+Build-Depends: debhelper (>= 9), qtbase5-dev, qt5-qmake, libfluidsynth-dev, 
+	qml-module-qtquick-controls,
+	qml-module-qtquick-window2,
+	qml-module-qtquick2,
+	libqt5qml5
 
 Package: qmidiplayer
 Architecture: any
 Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: Midi player based on Qt and fluidsynth.
\ No newline at end of file
+Description: Midi player based on Qt and fluidsynth.
+
+Package: qmidiplayer-lite
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Midi player based on Qt and fluidsynth (Lite version).
diff --git a/debian/qmidiplayer-lite.install b/debian/qmidiplayer-lite.install
new file mode 100644
index 0000000..ece593e
--- /dev/null
+++ b/debian/qmidiplayer-lite.install
@@ -0,0 +1 @@
+usr/bin/qmidiplayer-lite
diff --git a/debian/qmidiplayer.install b/debian/qmidiplayer.install
new file mode 100644
index 0000000..ed86d84
--- /dev/null
+++ b/debian/qmidiplayer.install
@@ -0,0 +1 @@
+usr/bin/qmidiplayer
diff --git a/debian/rules b/debian/rules
index 589a09a..f88b391 100755
--- a/debian/rules
+++ b/debian/rules
@@ -2,4 +2,4 @@
 %:
 	dh $@ --parallel
 override_dh_auto_install:
-	$(MAKE) INSTALL_ROOT=$$(pwd)/debian/qmidiplayer prefix=/usr install
\ No newline at end of file
+	$(MAKE) INSTALL_ROOT=$$(pwd)/debian/tmp prefix=/usr install
\ No newline at end of file
diff --git a/qmidiplayer-desktop/main.cpp b/qmidiplayer-desktop/main.cpp
new file mode 100644
index 0000000..c9f3b42
--- /dev/null
+++ b/qmidiplayer-desktop/main.cpp
@@ -0,0 +1,29 @@
+/*
+ *QMidiPlayer, a cross-platform player for midi files.
+ *Copyright (C) 2015  Chris Xiong
+ *
+ *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 "qmpmainwindow.hpp"
+#include <QApplication>
+#include <QStyle>
+
+int main(int argc,char **argv)
+{
+	QApplication a(argc,argv);
+	qmpMainWindow w;
+	if(w.pharseArgs(argc,argv)==1)return 0;
+
+	return a.exec();
+}
diff --git a/qmidiplayer-desktop/qdialskulpturestyle.cpp b/qmidiplayer-desktop/qdialskulpturestyle.cpp
new file mode 100644
index 0000000..7c181a0
--- /dev/null
+++ b/qmidiplayer-desktop/qdialskulpturestyle.cpp
@@ -0,0 +1,437 @@
+/******************************************************************************
+
+   Skulpture - Classical Three-Dimensional Artwork for Qt 4
+
+   Copyright (c) 2007-2009 Christoph Feck <christoph@maxiom.de>
+
+   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 <cmath>
+#include <QStyleOptionSlider>
+#include <QPixmapCache>
+#include <QPainter>
+
+#include "qdialskulpturestyle.hpp"
+
+#ifndef M_PI
+#define M_PI 3.141592653589793f
+#endif
+
+static const bool UsePixmapCache = true;
+
+static void
+paintIndicatorCached(QPainter *painter, const QStyleOption *option, void (*paintIndicator)(QPainter *painter, const QStyleOption *option), bool useCache, const QString &pixmapName)
+{
+	QPixmap pixmap;
+
+	if (!useCache || !QPixmapCache::find(pixmapName, pixmap)) {
+		pixmap =  QPixmap(option->rect.size());
+#if 1
+		pixmap.fill(Qt::transparent);
+	//  pixmap.fill(Qt::red);
+#else
+		pixmap.fill(option->palette.color(QPalette::Window));
+#endif
+		QPainter p(&pixmap);
+		QStyleOption opt = *option;
+		opt.rect = QRect(QPoint(0, 0), option->rect.size());
+	//  p.setCompositionMode(QPainter::CompositionMode_Clear);
+	//  p.setCompositionMode(QPainter::CompositionMode_Source);
+	//  p.fillRect(opt.rect, Qt::transparent);
+	//  p.setCompositionMode(QPainter::CompositionMode_SourceOver);
+		p.setFont(painter->font());
+		p.setRenderHint(QPainter::Antialiasing, true);
+		paintIndicator(&p, &opt);
+		p.end();
+		if (useCache) {
+			QPixmapCache::insert(pixmapName, pixmap);
+		//  qDebug() << "inserted into cache:" << pixmapName;
+		}
+	}
+	painter->drawPixmap(option->rect, pixmap);
+}
+
+void
+paintDialBase(QPainter *painter, const QStyleOption *option)
+{
+//  painter->fillRect(option->rect, Qt::red);
+//  painter->save();
+//  painter->setRenderHint(QPainter::Antialiasing, true);
+	int d = qMin(option->rect.width(), option->rect.height());
+/*  if (d > 20 && option->notchTarget > 0) {
+		d += -1;
+	}
+*/  QRectF r((option->rect.width() - d) / 2.0, (option->rect.height() - d) / 2.0, d, d);
+	const qreal angle = option->direction == Qt::LeftToRight ? 135.0 : 45.0;
+//  const qreal angle = 90;
+
+	painter->setPen(Qt::NoPen);
+	QColor border_color = option->palette.color(QPalette::Window);
+#if 0
+	{
+		QRadialGradient depth_gradient(r.center(), d / 2);
+//      depth_gradient.setColorAt(0.0, QColor(0, 0, 0, 255));
+		depth_gradient.setColorAt(0.5, QColor(0, 0, 0, 255));
+		depth_gradient.setColorAt(1.0, QColor(0, 0, 0, 0));
+		painter->setBrush(depth_gradient);
+		painter->drawEllipse(r);
+	}
+#endif
+#if 1
+	if (option->state & QStyle::State_HasFocus && option->state & QStyle::State_KeyboardFocusChange) {
+		painter->setBrush(option->palette.color(QPalette::Highlight).darker(180));
+		r.adjust(1, 1, -1, -1);
+		painter->drawEllipse(r);
+		painter->setBrush(border_color);
+		r.adjust(1, 1, -1, -1);
+		painter->drawEllipse(r);
+		r.adjust(1, 1, -1, -1);
+	} else {
+		painter->setBrush(border_color);
+		r.adjust(1, 1, -1, -1);
+		painter->drawEllipse(r);
+		r.adjust(1, 1, -1, -1);
+		QConicalGradient border_gradient(r.center(), angle);
+		if (!(option->state & QStyle::State_Enabled)) {
+			border_color = border_color.lighter(120);
+		}
+		border_gradient.setColorAt(0.0, border_color.darker(180));
+		border_gradient.setColorAt(0.3, border_color.darker(130));
+		border_gradient.setColorAt(0.5, border_color.darker(170));
+		border_gradient.setColorAt(0.7, border_color.darker(130));
+		border_gradient.setColorAt(1.0, border_color.darker(180));
+		painter->setBrush(border_gradient);
+//      painter->setBrush(Qt::blue);
+		painter->drawEllipse(r);
+		r.adjust(1, 1, -1, -1);
+	}
+	d -= 6;
+
+	QColor dial_color;
+	if (option->state & QStyle::State_Enabled) {
+		dial_color = option->palette.color(QPalette::Button).lighter(101);
+		if (option->state & QStyle::State_MouseOver) {
+			dial_color = dial_color.lighter(103);
+		}
+	} else {
+		dial_color = option->palette.color(QPalette::Window);
+	}
+	qreal t = option->state & QStyle::State_Enabled ? 2.0 : 1.5;
+	if (1) {
+		// ###: work around Qt 4.3.0 bug? (this works for 4.3.1)
+		QConicalGradient border_gradient(r.center(), angle);
+		border_gradient.setColorAt(0.0, dial_color.lighter(120));
+		border_gradient.setColorAt(0.2, dial_color);
+		border_gradient.setColorAt(0.5, dial_color.darker(130));
+		border_gradient.setColorAt(0.8, dial_color);
+		border_gradient.setColorAt(1.0, dial_color.lighter(120));
+		painter->setPen(QPen(border_gradient, t));
+	} else {
+		painter->setPen(QPen(Qt::red, t));
+	}
+#if 0
+	QLinearGradient dial_gradient(r.topLeft(), r.bottomLeft());
+	dial_gradient.setColorAt(0.0, dial_color.darker(105));
+	dial_gradient.setColorAt(0.5, dial_color.lighter(102));
+	dial_gradient.setColorAt(1.0, dial_color.lighter(105));
+#elif 1
+			  QLinearGradient dial_gradient(option->direction == Qt::LeftToRight ? r.topLeft() : r.topRight(), option->direction == Qt::LeftToRight ? r.bottomRight() : r.bottomLeft());
+//  QLinearGradient dial_gradient(r.topLeft(), r.bottomLeft());
+	if (true || option->state & QStyle::State_Enabled) {
+#if 1
+		dial_gradient.setColorAt(0.0, dial_color.darker(106));
+		dial_gradient.setColorAt(1.0, dial_color.lighter(104));
+#else
+		dial_gradient.setColorAt(0.0, dial_color.lighter(101));
+		dial_gradient.setColorAt(0.5, dial_color.darker(103));
+		dial_gradient.setColorAt(1.0, dial_color.lighter(104));
+#endif
+	} else {
+		dial_gradient.setColorAt(0.0, dial_color);
+		dial_gradient.setColorAt(1.0, dial_color);
+	}
+#elif 0
+	QConicalGradient dial_gradient(r.center(), angle);
+	dial_gradient.setColorAt(0.0, dial_color.lighter(102));
+	dial_gradient.setColorAt(0.5, dial_color.darker(103));
+	dial_gradient.setColorAt(1.0, dial_color.lighter(102));
+#else
+	QBrush dial_gradient(dial_color);
+#endif
+	painter->setBrush(dial_gradient);
+	t = t / 2;
+	painter->drawEllipse(r.adjusted(t, t, -t, -t));
+
+//  painter->setPen(Qt::NoPen);
+//  painter->setBrush(dial_color);
+//  painter->drawEllipse(r.adjusted(d / 4, d / 4, - d / 4, - d / 4));
+
+#if 0
+	QLinearGradient border2_gradient(r.topLeft(), r.bottomRight());
+	border2_gradient.setColorAt(1.0, dial_color.darker(425));
+	border2_gradient.setColorAt(0.9, dial_color);
+	border2_gradient.setColorAt(0.0, dial_color.darker(400));
+	painter->setPen(QPen(border2_gradient, 1.3));
+	painter->setBrush(Qt::NoBrush);
+	painter->drawEllipse(r.adjusted(0.3, 0.3, -0.3, -0.3));
+#endif
+//  painter->restore();
+#endif
+}
+
+void
+paintCachedDialBase(QPainter *painter, const QStyleOptionSlider *option)
+{
+	bool useCache = UsePixmapCache;
+	QString pixmapName;
+	QRect r = option->rect;
+	int d = qMin(r.width(), r.height());
+
+	if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ d > 128) {
+		useCache = false;
+	}
+	if (useCache) {
+		uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_KeyboardFocusChange | QStyle::State_HasFocus);
+		if (!(state & QStyle::State_Enabled)) {
+			state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus | QStyle::State_KeyboardFocusChange);
+		}
+	//  state &= ~(QStyle::State_HasFocus);
+		pixmapName.sprintf("scp-qdb-%x-%x-%llx-%x", state, option->direction, option->palette.cacheKey(), d);
+	}
+	paintIndicatorCached(painter, option, paintDialBase, useCache, pixmapName);
+}
+
+void
+paintIndicatorDial(QPainter *painter, const QStyleOptionSlider *option)
+{
+	int d = qMin(option->rect.width(), option->rect.height());
+	QRect rect(option->rect.center() - QPoint((d - 1) / 2, (d - 1) / 2), QSize(d, d));
+	QStyleOptionSlider opt;
+	opt.QStyleOption::operator=(*option);
+	opt.rect = rect;
+	paintCachedDialBase(painter, &opt);
+}
+
+QColor
+shaded_color(const QColor &color, int shade)
+{
+#if 1
+	const qreal contrast = 1.0;
+	int r, g, b;
+	color.getRgb(&r, &g, &b);
+	int gray = qGray(r, g, b);
+	gray = qMax(r, qMax(g, b));
+	gray = (r + b + g + 3 * gray) / 6;
+	if (shade < 0) {
+		qreal k = 220.0 / 255.0 * shade;
+		k *= contrast;
+		int a = 255;
+		if (gray > 0) {
+			a = int(k * 255 / (0 - gray));
+			if (a < 0) a = 0;
+			if (a > 255) a = 255;
+		}
+		return QColor(0, 0, 0, a);
+	} else {
+		qreal k = (255 - 220.0) / (255.0) * shade;
+		k *= contrast;
+		int a = 255;
+		if (gray < 255) {
+			a = int(k * 255 / (255 - gray));
+			if (a < 0) a = 0;
+			if (a > 255) a = 255;
+		}
+		return QColor(255, 255, 255, a);
+	}
+#else
+	if (shade < 0) {
+		return QColor(0, 0, 0, -shade);
+	} else {
+		return QColor(255, 255, 255, shade);
+	}
+#endif
+}
+
+static void
+paintGrip(QPainter *painter, const QStyleOption *option)
+{
+//  painter->fillRect(option->rect, Qt::red);
+	int d = qMin(option->rect.width(), option->rect.height());
+	// good values are 3 (very small), 4 (small), 5 (good), 7 (large), 9 (huge)
+	// int d = 5;
+	QRectF rect(QRectF(option->rect).center() - QPointF(d / 2.0, d / 2.0), QSizeF(d, d));
+	const qreal angle = option->direction == Qt::LeftToRight ? 135.0 : 45.0;
+//  const qreal angle = 90;
+	QColor color;
+		qreal opacity = 0.9;
+
+	painter->save();
+	painter->setPen(Qt::NoPen);
+	if (option->state & QStyle::State_Enabled) {
+		if (option->state & QStyle::State_Sunken) {
+			color = option->palette.color(QPalette::Highlight).darker(110);
+		} else {
+			color = option->palette.color(QPalette::Button);
+		}
+	} else {
+		color = option->palette.color(QPalette::Button);
+		opacity = 0.5;
+	}
+
+	QConicalGradient gradient1(rect.center(), angle);
+	gradient1.setColorAt(0.0, shaded_color(color, -110));
+	gradient1.setColorAt(0.25, shaded_color(color, -30));
+	gradient1.setColorAt(0.5, shaded_color(color, 180));
+	gradient1.setColorAt(0.75, shaded_color(color, -30));
+	gradient1.setColorAt(1.0, shaded_color(color, -110));
+	painter->setBrush(color);
+	painter->drawEllipse(rect);
+	painter->setBrush(gradient1);
+#if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0))
+		// ### merge opacity into color
+		painter->setOpacity(opacity);
+#endif
+	painter->drawEllipse(rect);
+#if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0))
+		painter->setOpacity(1.0);
+	if (d > 2) {
+		QConicalGradient gradient2(rect.center(), angle);
+		gradient2.setColorAt(0.0, shaded_color(color, -40));
+		gradient2.setColorAt(0.25, shaded_color(color, 0));
+		gradient2.setColorAt(0.5, shaded_color(color, 210));
+		gradient2.setColorAt(0.75, shaded_color(color, 0));
+		gradient2.setColorAt(1.0, shaded_color(color, -40));
+		rect.adjust(1, 1, -1, -1);
+		painter->setBrush(color);
+		painter->drawEllipse(rect);
+		painter->setBrush(gradient2);
+		painter->setOpacity(opacity);
+		painter->drawEllipse(rect);
+		painter->setOpacity(1.0);
+		if (d > 8) {
+			QConicalGradient gradient3(rect.center(), angle);
+			gradient3.setColorAt(0.0, shaded_color(color, -10));
+			gradient3.setColorAt(0.25, shaded_color(color, 0));
+			gradient3.setColorAt(0.5, shaded_color(color, 180));
+			gradient3.setColorAt(0.75, shaded_color(color, 0));
+			gradient3.setColorAt(1.0, shaded_color(color, -10));
+			rect.adjust(2, 2, -2, -2);
+			painter->setBrush(color);
+			painter->drawEllipse(rect);
+			painter->setBrush(gradient3);
+			painter->setOpacity(opacity);
+			painter->drawEllipse(rect);
+			painter->setOpacity(1.0);
+		}
+	}
+#endif
+	painter->restore();
+}
+
+void
+paintCachedGrip(QPainter *painter, const QStyleOption *option, QPalette::ColorRole /*bgrole*/)
+{
+	bool useCache = UsePixmapCache;
+	QString pixmapName;
+
+	if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ option->rect.width() * option->rect.height() > 4096) {
+		useCache = false;
+	}
+	if (useCache) {
+		uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_Sunken | QStyle::State_HasFocus);
+		if (!(state & QStyle::State_Enabled)) {
+			state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus);
+		}
+		state &= ~(QStyle::State_HasFocus);
+				QByteArray colorName = option->palette.color(QPalette::Button).name().toLatin1();
+				pixmapName.sprintf("scp-isg-%x-%x-%s-%x-%x", state, option->direction, colorName.constData(), option->rect.width(), option->rect.height());
+	}
+	paintIndicatorCached(painter, option, paintGrip, useCache, pixmapName);
+}
+
+void
+QDialSkulptureStyle::drawComplexControl( ComplexControl cc,
+											  const QStyleOptionComplex *optc,
+											  QPainter *painter,
+											  const QWidget *widget) const
+{
+
+	if (cc != QStyle::CC_Dial) {
+		QCommonStyle::drawComplexControl(cc, optc, painter, widget);
+		return;
+	}
+
+	const QStyleOptionSlider *option = qstyleoption_cast<const QStyleOptionSlider *>(optc);
+	if (option == NULL)
+		return;
+
+	int d = qMin(option->rect.width() & ~1, option->rect.height() & ~1);
+	QStyleOptionSlider opt = *option;
+	const QAbstractSlider *slider = NULL;
+	// always highlight knob if pressed (even if mouse is not over knob)
+	if ((option->state & QStyle::State_HasFocus) && (slider = qobject_cast<const QAbstractSlider *>(widget))) {
+		if (slider->isSliderDown()) {
+			opt.state |= QStyle::State_MouseOver;
+		}
+	}
+
+	// tickmarks
+	opt.palette.setColor(QPalette::Inactive, QPalette::WindowText, QColor(80, 80, 80, 255));
+	opt.palette.setColor(QPalette::Active, QPalette::WindowText, QColor(80, 80, 80, 255));
+	opt.state &= ~QStyle::State_HasFocus;
+	opt.rect.setWidth(opt.rect.width() & ~1);
+	opt.rect.setHeight(opt.rect.height() & ~1);
+	//((QCommonStyle *) this)->
+	QCommonStyle::drawComplexControl(QStyle::CC_Dial, &opt, painter, widget);
+
+	// focus rectangle
+	if (option->state & QStyle::State_HasFocus) {
+		QStyleOptionFocusRect focus;
+		opt.state |= QStyle::State_HasFocus;
+		focus.QStyleOption::operator=(opt);
+		focus.rect.adjust(-1, -1, 1, 1);
+		//drawPrimitive(QStyle::PE_FrameFocusRect, &focus, painter, widget);
+	}
+	opt.palette = option->palette;
+
+	// dial base
+	if (d <= 256) {
+		paintIndicatorDial(painter, &opt);
+	} else {
+		// large dials are slow to render, do not render them
+	}
+
+	// dial knob
+	d -= 6;
+	int gripSize = (option->fontMetrics.height() / 4) * 2 - 1;
+	opt.rect.setSize(QSize(gripSize, gripSize));
+	opt.rect.moveCenter(option->rect.center());
+	// angle calculation from qcommonstyle.cpp (c) Trolltech 1992-2007, ASA.
+	qreal angle;
+	int sliderPosition = option->upsideDown ? option->sliderPosition : (option->maximum - option->sliderPosition);
+	int range = option->maximum - option->minimum;
+	if (!range) {
+		angle = M_PI / 2;
+	} else if (option->dialWrapping) {
+		angle = M_PI * 1.5 - (sliderPosition - option->minimum) * 2 * M_PI / range;
+	} else {
+		angle = (M_PI * 8 - (sliderPosition - option->minimum) * 10 * M_PI / range) / 6;
+	}
+
+	qreal rr = d / 2.0 - gripSize - 2;
+	opt.rect.translate(int(0.5 + rr * cos(angle)), int(0.5 - rr * sin(angle)));
+	paintCachedGrip(painter, &opt, option->state & QStyle::State_Enabled ? QPalette::Button : QPalette::Window);
+}
diff --git a/qmidiplayer-desktop/qdialskulpturestyle.hpp b/qmidiplayer-desktop/qdialskulpturestyle.hpp
new file mode 100644
index 0000000..2f3ba04
--- /dev/null
+++ b/qmidiplayer-desktop/qdialskulpturestyle.hpp
@@ -0,0 +1,39 @@
+/******************************************************************************
+
+   Skulpture - Classical Three-Dimensional Artwork for Qt 4
+
+   Copyright (c) 2007-2009 Christoph Feck <christoph@maxiom.de>
+
+   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 QDIALSKULPTURESTYLE_H
+#define QDIALSKULPTURESTYLE_H
+
+#include <QCommonStyle>
+
+class QDialSkulptureStyle:public QCommonStyle
+{
+public:
+	QDialSkulptureStyle(){}
+	virtual ~QDialSkulptureStyle(){}
+
+	virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+									const QWidget *widget=0) const;
+
+};
+
+#endif // QDIALSKULPTURESTYLE_H
diff --git a/qmidiplayer-desktop/qmidiplayer-desktop.pro b/qmidiplayer-desktop/qmidiplayer-desktop.pro
new file mode 100644
index 0000000..328af5d
--- /dev/null
+++ b/qmidiplayer-desktop/qmidiplayer-desktop.pro
@@ -0,0 +1,64 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2015-12-25T20:24:49
+#
+#-------------------------------------------------
+
+QT       += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = qmidiplayer
+TEMPLATE = app
+
+
+SOURCES += main.cpp\
+	qmpmainwindow.cpp \
+	../core/qmpmidiplay.cpp \
+	../core/qmpmidiread.cpp \
+	qmpplistwindow.cpp \
+	qmpchannelswindow.cpp \
+	qmppresetselect.cpp \
+	qmpchanneleditor.cpp \
+	qmpefxwindow.cpp \
+	qmpinfowindow.cpp \
+	qmpsettingswindow.cpp \
+	qmphelpwindow.cpp \
+	qdialskulpturestyle.cpp
+
+HEADERS  += qmpmainwindow.hpp \
+	../core/qmpmidiplay.hpp \
+	qmpplistwindow.hpp \
+	qmpchannelswindow.hpp \
+	qmppresetselect.hpp \
+	qmpchanneleditor.hpp \
+	qmpefxwindow.hpp \
+	qmpinfowindow.hpp \
+	qmpsettingswindow.hpp \
+	qmphelpwindow.hpp \
+	qdialskulpturestyle.hpp \
+	qmpimidimapper.hpp
+
+FORMS    += qmpmainwindow.ui \
+	qmpplistwindow.ui \
+	qmpchannelswindow.ui \
+	qmppresetselect.ui \
+	qmpchanneleditor.ui \
+	qmpefxwindow.ui \
+	qmpinfowindow.ui \
+	qmpsettingswindow.ui \
+	qmphelpwindow.ui
+
+unix{
+	isEmpty(PREFIX) {
+		PREFIX = /usr/local
+	}
+	BINDIR = $$PREFIX/bin
+	target.path = $$BINDIR
+	INSTALLS += target
+	QMAKE_CXXFLAGS += -std=c++11 -Wall
+	LIBS += -lfluidsynth
+}
+win32:LIBS += e:/libs/fluidsynth/fluidsynth.lib winmm.lib #You have to change these
+win32:INCLUDEPATH += e:/libs/fluidsynth/include           #before building...
+RESOURCES     = resources.qrc
diff --git a/qmidiplayer-desktop/qmpchanneleditor.cpp b/qmidiplayer-desktop/qmpchanneleditor.cpp
new file mode 100644
index 0000000..f1d4e5e
--- /dev/null
+++ b/qmidiplayer-desktop/qmpchanneleditor.cpp
@@ -0,0 +1,193 @@
+#include <cstdio>
+#include "qmpchanneleditor.hpp"
+#include "ui_qmpchanneleditor.h"
+#include "qmpmainwindow.hpp"
+
+qmpChannelEditor::qmpChannelEditor(QWidget *parent) :
+	QDialog(parent),
+	ui(new Ui::qmpChannelEditor)
+{
+	ui->setupUi(this);
+	styl=new QDialSkulptureStyle();
+	QList<QDial*> dials=findChildren<QDial*>();
+	for(int i=0;i<dials.count();++i)
+		dials.at(i)->setStyle(styl);
+}
+
+qmpChannelEditor::~qmpChannelEditor()
+{
+	delete styl;
+	delete ui;
+}
+
+void qmpChannelEditor::setupWindow(int chid)
+{
+	char str[256];if(~chid)ch=chid;
+	sprintf(str,"Channel Parameter Editor - Channel #%d",ch+1);
+	setWindowTitle(str);
+	CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
+	int b,p;
+	player->getChannelPreset(ch,&b,&p,str);
+	ui->lbPresetName->setText(str);
+	sprintf(str,"BK: %d",b);ui->lbBank->setText(str);
+	sprintf(str,"PC: %d",p);ui->lbPreset->setText(str);
+	ui->lbChannelNumber->setText(QString::number(ch+1));
+#define setupControl(ccid,lb,d,ccname)\
+	b=player->getCC(ch,ccid);\
+	sprintf(str,"%s %d",ccname,b);\
+	ui->lb->setText(str);\
+	ui->d->setValue(b);
+	setupControl(7,lbVol,dVol,"Vol.");
+	setupControl(91,lbReverb,dReverb,"Rev.");
+	setupControl(93,lbChorus,dChorus,"Chr.");
+	setupControl(71,lbReso,dReso,"Res.");
+	setupControl(74,lbCut,dCut,"Cut.");
+	setupControl(73,lbAttack,dAttack,"Atk.");
+	setupControl(75,lbDecay,dDecay,"Dec.");
+	setupControl(72,lbRelease,dRelease,"Rel.");
+	setupControl(76,lbRate,dRate,"Rate");
+	setupControl(77,lbDepth,dDepth,"Dep.");
+	setupControl(78,lbDelay,dDelay,"Del.");
+	b=player->getCC(ch,10);
+	if(b==64)strcpy(str,"Pan. C");
+	else if(b<64)sprintf(str,"Pan. L%d",64-b);else sprintf(str,"Pan. R%d",b-64);
+	ui->lbPan->setText(str);
+	ui->dPan->setValue(b);
+}
+
+void qmpChannelEditor::sendCC()
+{
+	CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
+	player->setCC(ch,7,ui->dVol->value());
+	player->setCC(ch,10,ui->dPan->value());
+	player->setCC(ch,91,ui->dReverb->value());
+	player->setCC(ch,93,ui->dChorus->value());
+	player->setCC(ch,71,ui->dReso->value());
+	player->setCC(ch,74,ui->dCut->value());
+	player->setCC(ch,73,ui->dAttack->value());
+	player->setCC(ch,75,ui->dDecay->value());
+	player->setCC(ch,72,ui->dRelease->value());
+	player->setCC(ch,76,ui->dRate->value());
+	player->setCC(ch,77,ui->dDepth->value());
+	player->setCC(ch,78,ui->dDelay->value());
+}
+
+void qmpChannelEditor::showEvent(QShowEvent *e)
+{
+	knobpressed=0;
+	setupWindow();
+	connectSlots();
+	connect(qmpMainWindow::getInstance()->getTimer(),SIGNAL(timeout()),this,SLOT(setupWindow()));
+	e->accept();
+}
+void qmpChannelEditor::closeEvent(QCloseEvent *e)
+{
+	disconnectSlots();
+	disconnect(qmpMainWindow::getInstance()->getTimer(),SIGNAL(timeout()),this,SLOT(setupWindow()));
+	e->accept();
+}
+
+void qmpChannelEditor::on_pbChLeft_clicked()
+{
+	disconnectSlots();
+	if(ch>0)--ch;else ch=15;setupWindow();
+	connectSlots();
+}
+
+void qmpChannelEditor::on_pbChRight_clicked()
+{
+	disconnectSlots();
+	if(ch<15)++ch;else ch=0;setupWindow();
+	connectSlots();
+}
+
+void qmpChannelEditor::commonPressed()
+{disconnect(qmpMainWindow::getInstance()->getTimer(),SIGNAL(timeout()),this,SLOT(setupWindow()));knobpressed=1;}
+void qmpChannelEditor::commonReleased()
+{connect(qmpMainWindow::getInstance()->getTimer(),SIGNAL(timeout()),this,SLOT(setupWindow()));sendCC();knobpressed=0;}
+void qmpChannelEditor::commonChanged()
+{if(knobpressed){sendCC();setupWindow();}}
+
+void qmpChannelEditor::connectSlots()
+{
+	connect(ui->dCut,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	connect(ui->dReso,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	connect(ui->dReverb,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	connect(ui->dChorus,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	connect(ui->dVol,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	connect(ui->dPan,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	connect(ui->dAttack,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	connect(ui->dDecay,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	connect(ui->dRelease,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	connect(ui->dRate,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	connect(ui->dDepth,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	connect(ui->dDelay,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+
+	connect(ui->dCut,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	connect(ui->dReso,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	connect(ui->dReverb,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	connect(ui->dChorus,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	connect(ui->dVol,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	connect(ui->dPan,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	connect(ui->dAttack,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	connect(ui->dDecay,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	connect(ui->dRelease,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	connect(ui->dRate,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	connect(ui->dDepth,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	connect(ui->dDelay,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+
+	connect(ui->dCut,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	connect(ui->dReso,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	connect(ui->dReverb,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	connect(ui->dChorus,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	connect(ui->dVol,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	connect(ui->dPan,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	connect(ui->dAttack,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	connect(ui->dDecay,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	connect(ui->dRelease,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	connect(ui->dRate,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	connect(ui->dDepth,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	connect(ui->dDelay,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+}
+
+void qmpChannelEditor::disconnectSlots()
+{
+	disconnect(ui->dCut,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	disconnect(ui->dReso,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	disconnect(ui->dReverb,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	disconnect(ui->dChorus,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	disconnect(ui->dVol,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	disconnect(ui->dPan,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	disconnect(ui->dAttack,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	disconnect(ui->dDecay,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	disconnect(ui->dRelease,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	disconnect(ui->dRate,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	disconnect(ui->dDepth,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+	disconnect(ui->dDelay,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
+
+	disconnect(ui->dCut,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	disconnect(ui->dReso,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	disconnect(ui->dReverb,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	disconnect(ui->dChorus,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	disconnect(ui->dVol,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	disconnect(ui->dPan,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	disconnect(ui->dAttack,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	disconnect(ui->dDecay,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	disconnect(ui->dRelease,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	disconnect(ui->dRate,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	disconnect(ui->dDepth,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+	disconnect(ui->dDelay,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
+
+	disconnect(ui->dCut,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	disconnect(ui->dReso,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	disconnect(ui->dReverb,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	disconnect(ui->dChorus,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	disconnect(ui->dVol,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	disconnect(ui->dPan,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	disconnect(ui->dAttack,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	disconnect(ui->dDecay,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	disconnect(ui->dRelease,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	disconnect(ui->dRate,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	disconnect(ui->dDepth,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+	disconnect(ui->dDelay,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
+}
diff --git a/qmidiplayer-desktop/qmpchanneleditor.hpp b/qmidiplayer-desktop/qmpchanneleditor.hpp
new file mode 100644
index 0000000..0653af5
--- /dev/null
+++ b/qmidiplayer-desktop/qmpchanneleditor.hpp
@@ -0,0 +1,42 @@
+#ifndef QMPCHANNELEDITOR_H
+#define QMPCHANNELEDITOR_H
+
+#include <QDialog>
+#include <QShowEvent>
+#include <QCloseEvent>
+#include "qdialskulpturestyle.hpp"
+
+namespace Ui {
+	class qmpChannelEditor;
+}
+
+class qmpChannelEditor:public QDialog
+{
+	Q_OBJECT
+
+	public:
+		explicit qmpChannelEditor(QWidget *parent=0);
+		~qmpChannelEditor();
+	protected:
+		void showEvent(QShowEvent *e);
+		void closeEvent(QCloseEvent *e);
+	public slots:
+		void setupWindow(int chid=-1);
+
+	private slots:
+		void commonPressed();
+		void commonReleased();
+		void commonChanged();
+		void on_pbChLeft_clicked();
+		void on_pbChRight_clicked();
+
+	private:
+		Ui::qmpChannelEditor *ui;
+		int ch,knobpressed;
+		void sendCC();
+		void connectSlots();
+		void disconnectSlots();
+		QCommonStyle* styl;
+};
+
+#endif // QMPCHANNELEDITOR_H
diff --git a/qmidiplayer-desktop/qmpchanneleditor.ui b/qmidiplayer-desktop/qmpchanneleditor.ui
new file mode 100644
index 0000000..49e8c8e
--- /dev/null
+++ b/qmidiplayer-desktop/qmpchanneleditor.ui
@@ -0,0 +1,602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpChannelEditor</class>
+ <widget class="QDialog" name="qmpChannelEditor">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>422</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>422</width>
+    <height>300</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>422</width>
+    <height>300</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QPushButton" name="pbChLeft">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>10</y>
+     <width>21</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>&lt;</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="lbChannelNumber">
+   <property name="geometry">
+    <rect>
+     <x>30</x>
+     <y>10</y>
+     <width>21</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>1</string>
+   </property>
+   <property name="alignment">
+    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pbChRight">
+   <property name="geometry">
+    <rect>
+     <x>50</x>
+     <y>10</y>
+     <width>21</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>&gt;</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="lbPresetName">
+   <property name="geometry">
+    <rect>
+     <x>90</x>
+     <y>10</y>
+     <width>261</width>
+     <height>51</height>
+    </rect>
+   </property>
+   <property name="font">
+    <font>
+     <pointsize>16</pointsize>
+    </font>
+   </property>
+   <property name="text">
+    <string>Yamaha Grand Piano</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="lbBank">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>30</y>
+     <width>81</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>BK: 0</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="lbPreset">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>50</y>
+     <width>81</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>PC: 0</string>
+   </property>
+  </widget>
+  <widget class="QGroupBox" name="gFilters">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>70</y>
+     <width>141</width>
+     <height>101</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>Filters</string>
+   </property>
+   <widget class="QLabel" name="lbReso">
+    <property name="geometry">
+     <rect>
+      <x>70</x>
+      <y>80</y>
+      <width>66</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Res. 64</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QDial" name="dReso">
+    <property name="geometry">
+     <rect>
+      <x>80</x>
+      <y>30</y>
+      <width>50</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>127</number>
+    </property>
+    <property name="value">
+     <number>64</number>
+    </property>
+    <property name="notchesVisible">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QDial" name="dCut">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>30</y>
+      <width>50</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>127</number>
+    </property>
+    <property name="value">
+     <number>64</number>
+    </property>
+    <property name="notchesVisible">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QLabel" name="lbCut">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>80</y>
+      <width>71</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Cut.  64</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QGroupBox" name="gEffects">
+   <property name="geometry">
+    <rect>
+     <x>140</x>
+     <y>70</y>
+     <width>141</width>
+     <height>101</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>Effects</string>
+   </property>
+   <widget class="QLabel" name="lbChorus">
+    <property name="geometry">
+     <rect>
+      <x>70</x>
+      <y>80</y>
+      <width>66</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Chr. 64</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QDial" name="dChorus">
+    <property name="geometry">
+     <rect>
+      <x>80</x>
+      <y>30</y>
+      <width>50</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>127</number>
+    </property>
+    <property name="value">
+     <number>64</number>
+    </property>
+    <property name="notchesVisible">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QDial" name="dReverb">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>30</y>
+      <width>50</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>127</number>
+    </property>
+    <property name="value">
+     <number>64</number>
+    </property>
+    <property name="notchesVisible">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QLabel" name="lbReverb">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>80</y>
+      <width>71</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Rev.  64</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QGroupBox" name="gEnvelope">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>170</y>
+     <width>211</width>
+     <height>101</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>Envelope</string>
+   </property>
+   <widget class="QLabel" name="lbDecay">
+    <property name="geometry">
+     <rect>
+      <x>70</x>
+      <y>80</y>
+      <width>66</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Dec. 64</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QDial" name="dDecay">
+    <property name="geometry">
+     <rect>
+      <x>80</x>
+      <y>30</y>
+      <width>50</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>127</number>
+    </property>
+    <property name="value">
+     <number>64</number>
+    </property>
+    <property name="notchesVisible">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QDial" name="dAttack">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>30</y>
+      <width>50</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>127</number>
+    </property>
+    <property name="value">
+     <number>64</number>
+    </property>
+    <property name="notchesVisible">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QLabel" name="lbAttack">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>80</y>
+      <width>71</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Atk.  64</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QDial" name="dRelease">
+    <property name="geometry">
+     <rect>
+      <x>150</x>
+      <y>30</y>
+      <width>50</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>127</number>
+    </property>
+    <property name="value">
+     <number>64</number>
+    </property>
+    <property name="notchesVisible">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QLabel" name="lbRelease">
+    <property name="geometry">
+     <rect>
+      <x>140</x>
+      <y>80</y>
+      <width>66</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Rel. 64</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QGroupBox" name="gVibrato">
+   <property name="geometry">
+    <rect>
+     <x>210</x>
+     <y>170</y>
+     <width>211</width>
+     <height>101</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>Vibrato</string>
+   </property>
+   <widget class="QLabel" name="lbDepth">
+    <property name="geometry">
+     <rect>
+      <x>70</x>
+      <y>80</y>
+      <width>66</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Dep. 64</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QDial" name="dDepth">
+    <property name="geometry">
+     <rect>
+      <x>80</x>
+      <y>30</y>
+      <width>50</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>127</number>
+    </property>
+    <property name="value">
+     <number>64</number>
+    </property>
+    <property name="notchesVisible">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QDial" name="dRate">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>30</y>
+      <width>50</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>127</number>
+    </property>
+    <property name="value">
+     <number>64</number>
+    </property>
+    <property name="notchesVisible">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QLabel" name="lbRate">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>80</y>
+      <width>71</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Rate  64</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QDial" name="dDelay">
+    <property name="geometry">
+     <rect>
+      <x>150</x>
+      <y>30</y>
+      <width>50</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>127</number>
+    </property>
+    <property name="value">
+     <number>64</number>
+    </property>
+    <property name="notchesVisible">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QLabel" name="lbDelay">
+    <property name="geometry">
+     <rect>
+      <x>140</x>
+      <y>80</y>
+      <width>66</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Del. 64</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QGroupBox" name="gMixer">
+   <property name="geometry">
+    <rect>
+     <x>280</x>
+     <y>70</y>
+     <width>141</width>
+     <height>101</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>Mixer</string>
+   </property>
+   <widget class="QLabel" name="lbPan">
+    <property name="geometry">
+     <rect>
+      <x>70</x>
+      <y>80</y>
+      <width>66</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Pan.  C</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QDial" name="dPan">
+    <property name="geometry">
+     <rect>
+      <x>80</x>
+      <y>30</y>
+      <width>50</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>127</number>
+    </property>
+    <property name="value">
+     <number>64</number>
+    </property>
+    <property name="notchesVisible">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QLabel" name="lbVol">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>80</y>
+      <width>66</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Vol.  127</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QDial" name="dVol">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>30</y>
+      <width>50</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>127</number>
+    </property>
+    <property name="value">
+     <number>127</number>
+    </property>
+    <property name="notchesVisible">
+     <bool>true</bool>
+    </property>
+   </widget>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmpchannelswindow.cpp b/qmidiplayer-desktop/qmpchannelswindow.cpp
new file mode 100644
index 0000000..a9cf60e
--- /dev/null
+++ b/qmidiplayer-desktop/qmpchannelswindow.cpp
@@ -0,0 +1,132 @@
+#include <QCheckBox>
+#include <QPushButton>
+#include <QComboBox>
+#include "qmpchannelswindow.hpp"
+#include "ui_qmpchannelswindow.h"
+#include "qmpmainwindow.hpp"
+
+qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) :
+	QDialog(parent),
+	ui(new Ui::qmpChannelsWindow)
+{
+	ui->setupUi(this);
+	pselectw=new qmpPresetSelector(this);
+	ceditw=new qmpChannelEditor(this);
+	connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed()));
+	for(int i=0;i<16;++i)
+	{
+		ui->twChannels->setCellWidget(i,0,new QCheckBox(""));
+		connect(ui->twChannels->cellWidget(i,0),SIGNAL(stateChanged(int)),this,SLOT(channelMSChanged()));
+		ui->twChannels->setCellWidget(i,1,new QCheckBox(""));
+		connect(ui->twChannels->cellWidget(i,1),SIGNAL(stateChanged(int)),this,SLOT(channelMSChanged()));
+		ui->twChannels->setCellWidget(i,2,new QComboBox());
+		QComboBox *cb=(QComboBox*)ui->twChannels->cellWidget(i,2);
+		//stub
+		cb->addItem("Internal FluidSynth");
+		ui->twChannels->setCellWidget(i,3,new QDCLabel(""));
+		((QDCLabel*)ui->twChannels->cellWidget(i,3))->setID(i);
+		connect(ui->twChannels->cellWidget(i,3),SIGNAL(onDoubleClick(int)),this,SLOT(showPresetWindow(int)));
+		ui->twChannels->setCellWidget(i,4,new QDCPushButton("..."));
+		((QDCLabel*)ui->twChannels->cellWidget(i,4))->setID(i);
+		connect(ui->twChannels->cellWidget(i,4),SIGNAL(onClick(int)),this,SLOT(showChannelEditorWindow(int)));
+	}
+	ui->twChannels->setColumnWidth(0,32);
+	ui->twChannels->setColumnWidth(1,32);
+	ui->twChannels->setColumnWidth(2,192);
+	ui->twChannels->setColumnWidth(3,192);
+	ui->twChannels->setColumnWidth(4,32);
+}
+
+void qmpChannelsWindow::showEvent(QShowEvent *event)
+{
+	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+	{
+		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlWShown",1);
+	}
+	event->accept();
+}
+
+void qmpChannelsWindow::closeEvent(QCloseEvent *event)
+{
+	setVisible(false);
+	if(!qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+	{
+		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlWShown",0);
+	}
+	emit dialogClosing();
+	event->accept();
+}
+
+void qmpChannelsWindow::moveEvent(QMoveEvent *event)
+{
+	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+	{
+		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlW",event->pos());
+	}
+}
+
+void qmpChannelsWindow::channelWindowsUpdate()
+{
+	if(qmpMainWindow::getInstance()->getPlayer()->isFinished())
+	{
+		for(int i=0;i<16;++i)
+			((QLabel*)ui->twChannels->cellWidget(i,3))->setText("");
+		return;
+	}
+	for(int i=0;i<16;++i)
+	{
+		char data[128],nm[24];
+		int b,p;
+		qmpMainWindow::getInstance()->getPlayer()->getChannelPreset(i,&b,&p,nm);
+		sprintf(data,"%d:%d %s",b,p,nm);
+		((QLabel*)ui->twChannels->cellWidget(i,3))->setText(data);
+	}
+}
+
+void qmpChannelsWindow::channelMSChanged()
+{
+	for(int i=0;i<16;++i)
+	{
+		QCheckBox *m,*s;
+		m=(QCheckBox*)ui->twChannels->cellWidget(i,0);
+		s=(QCheckBox*)ui->twChannels->cellWidget(i,1);
+		if(m->isChecked()&&s->isChecked())s->setChecked(false);
+		qmpMainWindow::getInstance()->getPlayer()->setMute(i,m->isChecked());
+		qmpMainWindow::getInstance()->getPlayer()->setSolo(i,s->isChecked());
+	}
+}
+
+qmpChannelsWindow::~qmpChannelsWindow()
+{
+	delete ui;
+}
+
+void qmpChannelsWindow::on_pbUnmute_clicked()
+{
+	for(int i=0;i<16;++i)
+	{
+		((QCheckBox*)ui->twChannels->cellWidget(i,0))->setChecked(false);
+		qmpMainWindow::getInstance()->getPlayer()->setMute(i,false);
+	}
+}
+
+void qmpChannelsWindow::on_pbUnsolo_clicked()
+{
+	for(int i=0;i<16;++i)
+	{
+		((QCheckBox*)ui->twChannels->cellWidget(i,1))->setChecked(false);
+		qmpMainWindow::getInstance()->getPlayer()->setSolo(i,false);
+	}
+}
+
+void qmpChannelsWindow::showPresetWindow(int chid)
+{
+	pselectw->show();
+	pselectw->setupWindow(chid);
+}
+
+void qmpChannelsWindow::showChannelEditorWindow(int chid)
+{
+	ceditw->show();
+	ceditw->setupWindow(chid);
+}
diff --git a/qmidiplayer-desktop/qmpchannelswindow.hpp b/qmidiplayer-desktop/qmpchannelswindow.hpp
new file mode 100644
index 0000000..f0591b6
--- /dev/null
+++ b/qmidiplayer-desktop/qmpchannelswindow.hpp
@@ -0,0 +1,71 @@
+#ifndef QMPCHANNELSWINDOW_H
+#define QMPCHANNELSWINDOW_H
+
+#include <QLabel>
+#include <QPushButton>
+#include <QDialog>
+#include <QShowEvent>
+#include <QCloseEvent>
+#include <QMoveEvent>
+#include "qmppresetselect.hpp"
+#include "qmpchanneleditor.hpp"
+
+namespace Ui {
+	class qmpChannelsWindow;
+}
+
+class QDCLabel:public QLabel
+{
+	Q_OBJECT
+	private:
+		int id;
+	protected:
+		void mouseDoubleClickEvent(QMouseEvent *event){event->accept();emit onDoubleClick(id);}
+	public:
+		QDCLabel(QString s):QLabel(s){id=-1;}
+		void setID(int _id){id=_id;}
+	signals:
+		void onDoubleClick(int id);
+};
+
+class QDCPushButton:public QPushButton
+{
+	Q_OBJECT
+	private:
+		int id;
+	protected:
+		void mousePressEvent(QMouseEvent *event){QPushButton::mousePressEvent(event);emit onClick(id);}
+	public:
+		QDCPushButton(QString s):QPushButton(s){id=-1;}
+		void setID(int _id){id=_id;}
+	signals:
+		void onClick(int id);
+};
+
+class qmpChannelsWindow:public QDialog
+{
+	Q_OBJECT
+
+	public:
+		explicit qmpChannelsWindow(QWidget *parent = 0);
+		~qmpChannelsWindow();
+		void showEvent(QShowEvent *event);
+		void closeEvent(QCloseEvent *event);
+		void moveEvent(QMoveEvent *event);
+	signals:
+		void dialogClosing();
+	public slots:
+		void channelWindowsUpdate();
+		void channelMSChanged();
+		void showPresetWindow(int chid);
+		void showChannelEditorWindow(int chid);
+		void on_pbUnmute_clicked();
+		void on_pbUnsolo_clicked();
+
+	private:
+		Ui::qmpChannelsWindow *ui;
+		qmpPresetSelector *pselectw;
+		qmpChannelEditor *ceditw;
+};
+
+#endif // QMPCHANNELSWINDOW_H
diff --git a/qmidiplayer-desktop/qmpchannelswindow.ui b/qmidiplayer-desktop/qmpchannelswindow.ui
new file mode 100644
index 0000000..a8b43cb
--- /dev/null
+++ b/qmidiplayer-desktop/qmpchannelswindow.ui
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpChannelsWindow</class>
+ <widget class="QDialog" name="qmpChannelsWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>580</width>
+    <height>410</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>580</width>
+    <height>410</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>580</width>
+    <height>16777215</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Channels</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_4">
+   <item>
+    <layout class="QVBoxLayout" name="verticalLayout_1">
+     <item>
+      <widget class="QTableWidget" name="twChannels">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="alternatingRowColors">
+        <bool>true</bool>
+       </property>
+       <property name="selectionMode">
+        <enum>QAbstractItemView::NoSelection</enum>
+       </property>
+       <property name="cornerButtonEnabled">
+        <bool>false</bool>
+       </property>
+       <property name="rowCount">
+        <number>16</number>
+       </property>
+       <property name="columnCount">
+        <number>5</number>
+       </property>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <row/>
+       <column>
+        <property name="text">
+         <string>M</string>
+        </property>
+       </column>
+       <column>
+        <property name="text">
+         <string>S</string>
+        </property>
+       </column>
+       <column>
+        <property name="text">
+         <string>Device</string>
+        </property>
+       </column>
+       <column>
+        <property name="text">
+         <string>Preset</string>
+        </property>
+       </column>
+       <column>
+        <property name="text">
+         <string>...</string>
+        </property>
+       </column>
+       <item row="0" column="0">
+        <property name="text">
+         <string/>
+        </property>
+       </item>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QPushButton" name="pbSave">
+       <property name="text">
+        <string>Save</string>
+       </property>
+       <property name="iconSize">
+        <size>
+         <width>16</width>
+         <height>16</height>
+        </size>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pbLoad">
+       <property name="text">
+        <string>Load</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pbUnmute">
+       <property name="text">
+        <string>Unmute All</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pbUnsolo">
+       <property name="text">
+        <string>Unsolo All</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmpefxwindow.cpp b/qmidiplayer-desktop/qmpefxwindow.cpp
new file mode 100644
index 0000000..7d9c08e
--- /dev/null
+++ b/qmidiplayer-desktop/qmpefxwindow.cpp
@@ -0,0 +1,198 @@
+#include <cmath>
+#include "qmpefxwindow.hpp"
+#include "ui_qmpefxwindow.h"
+#include "qmpmainwindow.hpp"
+
+qmpEfxWindow::qmpEfxWindow(QWidget *parent) :
+	QDialog(parent),
+	ui(new Ui::qmpEfxWindow)
+{
+	ui->setupUi(this);initialized=false;
+	styl=new QDialSkulptureStyle();
+	QList<QDial*> dials=findChildren<QDial*>();
+	for(int i=0;i<dials.count();++i)
+		dials.at(i)->setStyle(styl);
+	connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed()));
+	//stub. read these from settings after the setting module is implemented
+	QSettings *settings=qmpSettingsWindow::getSettingsIntf();
+	ui->cbEnabledC->setChecked(settings->value("Effects/ChorusEnabled",1).toInt());
+	ui->cbEnabledR->setChecked(settings->value("Effects/ReverbEnabled",1).toInt());
+	rr=settings->value("Effects/ReverbRoom",FLUID_REVERB_DEFAULT_ROOMSIZE).toDouble();
+	rd=settings->value("Effects/ReverbDamp",FLUID_REVERB_DEFAULT_DAMP).toDouble();
+	rw=settings->value("Effects/ReverbWidth",FLUID_REVERB_DEFAULT_WIDTH).toDouble();
+	rl=settings->value("Effects/ReverbLevel",FLUID_REVERB_DEFAULT_LEVEL).toDouble();
+
+	cfb=settings->value("Effects/ChorusFeedbk",FLUID_CHORUS_DEFAULT_N).toInt();
+	cl=settings->value("Effects/ChorusLevel",FLUID_CHORUS_DEFAULT_LEVEL).toDouble();
+	cr=settings->value("Effects/ChorusRate",FLUID_CHORUS_DEFAULT_SPEED).toDouble();
+	cd=settings->value("Effects/ChorusDepth",FLUID_CHORUS_DEFAULT_DEPTH).toDouble();
+	ct=settings->value("Effects/ChorusType",FLUID_CHORUS_DEFAULT_TYPE).toInt();
+}
+
+qmpEfxWindow::~qmpEfxWindow()
+{
+	delete styl;
+	delete ui;
+}
+
+void qmpEfxWindow::closeEvent(QCloseEvent *event)
+{
+	setVisible(false);
+	if(!qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+	{
+		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxWShown",0);
+	}
+	emit dialogClosing();
+	event->accept();
+}
+
+void qmpEfxWindow::showEvent(QShowEvent *event)
+{
+	//CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
+	//These parameters will never be modified outside this window...
+	/*if(initialized)
+	{
+		player->getReverbPara(&rr,&rd,&rw,&rl);
+		player->getChorusPara(&cfb,&cl,&cr,&cd,&ct);
+	}*/
+	ui->sbRoom->setValue((int)round(rr*100));ui->dRoom->setValue((int)round(rr*100));
+	ui->sbDamp->setValue((int)round(rd*100));ui->dDamp->setValue((int)round(rd*100));
+	ui->sbWidth->setValue((int)round(rw*100));ui->dWidth->setValue((int)round(rw*100));
+	ui->sbLevelR->setValue((int)round(rl*100));ui->dLevelR->setValue((int)round(rl*100));
+
+	ui->sbFeedBack->setValue(cfb);ui->dFeedBack->setValue(cfb);
+	ui->sbRate->setValue(cr);ui->dRate->setValue((int)round(cr*100));
+	ui->sbDepth->setValue(cd);ui->dDepth->setValue((int)round(cd*10));
+	ui->sbLevelC->setValue((int)round(cl*100));ui->dLevelC->setValue((int)round(cl*100));
+	if(ct==FLUID_CHORUS_MOD_SINE)ui->rbSine->setChecked(true),ui->rbTriangle->setChecked(false);
+	if(ct==FLUID_CHORUS_MOD_TRIANGLE)ui->rbSine->setChecked(false),ui->rbTriangle->setChecked(true);
+	initialized=true;
+	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+	{
+		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxWShown",1);
+	}
+	event->accept();
+}
+
+void qmpEfxWindow::moveEvent(QMoveEvent *event)
+{
+	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+	{
+		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxW",event->pos());
+	}
+}
+
+void qmpEfxWindow::sendEfxChange()
+{
+	if(!qmpMainWindow::getInstance()||!initialized)return;
+	rr=ui->sbRoom->value()/100.;rd=ui->sbDamp->value()/100.;
+	rw=ui->sbWidth->value()/100.;rl=ui->sbLevelR->value()/100.;
+	ct=ui->rbSine->isChecked()?FLUID_CHORUS_MOD_SINE:FLUID_CHORUS_MOD_TRIANGLE;
+	cfb=ui->sbFeedBack->value();cl=ui->sbLevelC->value()/100.;
+	cr=ui->sbRate->value();cd=ui->sbDepth->value();
+	CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
+	player->setReverbPara(ui->cbEnabledR->isChecked()?1:0,rr,rd,rw,rl);
+	player->setChorusPara(ui->cbEnabledC->isChecked()?1:0,cfb,cl,cr,cd,ct);
+
+	QSettings *settings=qmpSettingsWindow::getSettingsIntf();
+	settings->setValue("Effects/ChorusEnabled",ui->cbEnabledC->isChecked()?1:0);
+	settings->setValue("Effects/ReverbEnabled",ui->cbEnabledR->isChecked()?1:0);
+	settings->setValue("Effects/ReverbRoom",rr);
+	settings->setValue("Effects/ReverbDamp",rd);
+	settings->setValue("Effects/ReverbWidth",rw);
+	settings->setValue("Effects/ReverbLevel",rl);
+
+	settings->setValue("Effects/ChorusFeedbk",cfb);
+	settings->setValue("Effects/ChorusLevel",cl);
+	settings->setValue("Effects/ChorusRate",cr);
+	settings->setValue("Effects/ChorusDepth",cd);
+	settings->setValue("Effects/ChorusType",ct);
+}
+
+void qmpEfxWindow::dailValueChange()
+{
+	if(!initialized)return;
+	ui->sbRoom->setValue(ui->dRoom->value());
+	ui->sbDamp->setValue(ui->dDamp->value());
+	ui->sbWidth->setValue(ui->dWidth->value());
+	ui->sbLevelR->setValue(ui->dLevelR->value());
+	ui->sbFeedBack->setValue(ui->dFeedBack->value());
+	ui->sbRate->setValue(ui->dRate->value()/100.);
+	ui->sbDepth->setValue(ui->dDepth->value()/10.);
+	ui->sbLevelC->setValue(ui->dLevelC->value());
+	sendEfxChange();
+}
+
+void qmpEfxWindow::spinValueChange()
+{
+	if(!initialized)return;
+	ui->dRoom->setValue(ui->sbRoom->value());
+	ui->dDamp->setValue(ui->sbDamp->value());
+	ui->dWidth->setValue(ui->sbWidth->value());
+	ui->dLevelR->setValue(ui->sbLevelR->value());
+	ui->dFeedBack->setValue(ui->sbFeedBack->value());
+	ui->dRate->setValue((int)(ui->sbRate->value()*100));
+	ui->dDepth->setValue((int)(ui->sbDepth->value()*10));
+	ui->dLevelC->setValue(ui->sbLevelC->value());
+	sendEfxChange();
+}
+
+void qmpEfxWindow::on_dRoom_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dDamp_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dWidth_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dLevelR_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dFeedBack_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dRate_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dDepth_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_dLevelC_valueChanged()
+{dailValueChange();}
+
+void qmpEfxWindow::on_sbRoom_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbDamp_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbWidth_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbLevelR_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbFeedBack_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbRate_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbDepth_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_sbLevelC_valueChanged(QString s)
+{s=QString();spinValueChange();}
+
+void qmpEfxWindow::on_cbEnabledC_stateChanged()
+{sendEfxChange();}
+
+void qmpEfxWindow::on_cbEnabledR_stateChanged()
+{sendEfxChange();}
+
+void qmpEfxWindow::on_rbSine_toggled()
+{sendEfxChange();}
+
+void qmpEfxWindow::on_rbTriangle_toggled()
+{sendEfxChange();}
diff --git a/qmidiplayer-desktop/qmpefxwindow.hpp b/qmidiplayer-desktop/qmpefxwindow.hpp
new file mode 100644
index 0000000..2a080f0
--- /dev/null
+++ b/qmidiplayer-desktop/qmpefxwindow.hpp
@@ -0,0 +1,62 @@
+#ifndef QMPEFXWINDOW_HPP
+#define QMPEFXWINDOW_HPP
+
+#include <QDialog>
+#include <QCloseEvent>
+#include <QShowEvent>
+#include <QMoveEvent>
+
+#include "qdialskulpturestyle.hpp"
+
+namespace Ui {
+	class qmpEfxWindow;
+}
+
+class qmpEfxWindow : public QDialog
+{
+	Q_OBJECT
+
+	public:
+		explicit qmpEfxWindow(QWidget *parent=0);
+		~qmpEfxWindow();
+		void closeEvent(QCloseEvent *event);
+		void showEvent(QShowEvent *event);
+		void moveEvent(QMoveEvent *event);
+		void sendEfxChange();
+
+	signals:
+		void dialogClosing();
+
+	private slots:
+		void on_dRoom_valueChanged();
+		void on_dDamp_valueChanged();
+		void on_dWidth_valueChanged();
+		void on_dLevelR_valueChanged();
+		void on_dFeedBack_valueChanged();
+		void on_dRate_valueChanged();
+		void on_dDepth_valueChanged();
+		void on_dLevelC_valueChanged();
+		void on_sbRoom_valueChanged(QString s);
+		void on_sbDamp_valueChanged(QString s);
+		void on_sbWidth_valueChanged(QString s);
+		void on_sbLevelR_valueChanged(QString s);
+		void on_sbFeedBack_valueChanged(QString s);
+		void on_sbRate_valueChanged(QString s);
+		void on_sbDepth_valueChanged(QString s);
+		void on_sbLevelC_valueChanged(QString s);
+		void on_cbEnabledC_stateChanged();
+		void on_cbEnabledR_stateChanged();
+		void on_rbSine_toggled();
+		void on_rbTriangle_toggled();
+
+	private:
+		void dailValueChange();
+		void spinValueChange();
+		Ui::qmpEfxWindow *ui;
+		double rr,rd,rw,rl;
+		int cfb,ct,initialized;
+		double cl,cr,cd;
+		QCommonStyle* styl;
+};
+
+#endif // QMPEFXWINDOW_HPP
diff --git a/qmidiplayer-desktop/qmpefxwindow.ui b/qmidiplayer-desktop/qmpefxwindow.ui
new file mode 100644
index 0000000..4a1e0c6
--- /dev/null
+++ b/qmidiplayer-desktop/qmpefxwindow.ui
@@ -0,0 +1,478 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpEfxWindow</class>
+ <widget class="QDialog" name="qmpEfxWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>546</width>
+    <height>177</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>546</width>
+    <height>177</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>546</width>
+    <height>177</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Effects</string>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <item>
+    <widget class="QGroupBox" name="gReverb">
+     <property name="title">
+      <string>Reverb</string>
+     </property>
+     <widget class="QCheckBox" name="cbEnabledR">
+      <property name="geometry">
+       <rect>
+        <x>80</x>
+        <y>4</y>
+        <width>21</width>
+        <height>24</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string/>
+      </property>
+     </widget>
+     <widget class="QDial" name="dRoom">
+      <property name="geometry">
+       <rect>
+        <x>10</x>
+        <y>30</y>
+        <width>50</width>
+        <height>51</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>120</number>
+      </property>
+      <property name="notchesVisible">
+       <bool>true</bool>
+      </property>
+     </widget>
+     <widget class="QDial" name="dDamp">
+      <property name="geometry">
+       <rect>
+        <x>200</x>
+        <y>30</y>
+        <width>50</width>
+        <height>51</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>100</number>
+      </property>
+      <property name="notchesVisible">
+       <bool>true</bool>
+      </property>
+     </widget>
+     <widget class="QDial" name="dWidth">
+      <property name="geometry">
+       <rect>
+        <x>10</x>
+        <y>103</y>
+        <width>50</width>
+        <height>51</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>100</number>
+      </property>
+      <property name="notchesVisible">
+       <bool>true</bool>
+      </property>
+     </widget>
+     <widget class="QDial" name="dLevelR">
+      <property name="geometry">
+       <rect>
+        <x>200</x>
+        <y>103</y>
+        <width>50</width>
+        <height>51</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>100</number>
+      </property>
+      <property name="notchesVisible">
+       <bool>true</bool>
+      </property>
+     </widget>
+     <widget class="QLabel" name="lbRoom">
+      <property name="geometry">
+       <rect>
+        <x>60</x>
+        <y>30</y>
+        <width>41</width>
+        <height>20</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Room</string>
+      </property>
+     </widget>
+     <widget class="QSpinBox" name="sbRoom">
+      <property name="geometry">
+       <rect>
+        <x>60</x>
+        <y>50</y>
+        <width>51</width>
+        <height>21</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>120</number>
+      </property>
+     </widget>
+     <widget class="QLabel" name="lbDamp">
+      <property name="geometry">
+       <rect>
+        <x>140</x>
+        <y>30</y>
+        <width>51</width>
+        <height>20</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Damp</string>
+      </property>
+      <property name="alignment">
+       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+      </property>
+     </widget>
+     <widget class="QSpinBox" name="sbDamp">
+      <property name="geometry">
+       <rect>
+        <x>140</x>
+        <y>50</y>
+        <width>56</width>
+        <height>21</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>100</number>
+      </property>
+     </widget>
+     <widget class="QLabel" name="lbWidth">
+      <property name="geometry">
+       <rect>
+        <x>60</x>
+        <y>100</y>
+        <width>51</width>
+        <height>20</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Width</string>
+      </property>
+     </widget>
+     <widget class="QSpinBox" name="sbWidth">
+      <property name="geometry">
+       <rect>
+        <x>60</x>
+        <y>120</y>
+        <width>56</width>
+        <height>21</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>100</number>
+      </property>
+     </widget>
+     <widget class="QLabel" name="lbLevelR">
+      <property name="geometry">
+       <rect>
+        <x>145</x>
+        <y>100</y>
+        <width>51</width>
+        <height>20</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Level</string>
+      </property>
+      <property name="alignment">
+       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+      </property>
+     </widget>
+     <widget class="QSpinBox" name="sbLevelR">
+      <property name="geometry">
+       <rect>
+        <x>140</x>
+        <y>120</y>
+        <width>56</width>
+        <height>21</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>100</number>
+      </property>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="gChorus">
+     <property name="title">
+      <string>Chorus</string>
+     </property>
+     <widget class="QCheckBox" name="cbEnabledC">
+      <property name="geometry">
+       <rect>
+        <x>80</x>
+        <y>4</y>
+        <width>21</width>
+        <height>24</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string/>
+      </property>
+     </widget>
+     <widget class="QDial" name="dFeedBack">
+      <property name="geometry">
+       <rect>
+        <x>10</x>
+        <y>30</y>
+        <width>50</width>
+        <height>51</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>99</number>
+      </property>
+      <property name="notchesVisible">
+       <bool>true</bool>
+      </property>
+     </widget>
+     <widget class="QDial" name="dRate">
+      <property name="geometry">
+       <rect>
+        <x>200</x>
+        <y>30</y>
+        <width>50</width>
+        <height>51</height>
+       </rect>
+      </property>
+      <property name="minimum">
+       <number>29</number>
+      </property>
+      <property name="maximum">
+       <number>500</number>
+      </property>
+      <property name="value">
+       <number>29</number>
+      </property>
+      <property name="notchesVisible">
+       <bool>true</bool>
+      </property>
+     </widget>
+     <widget class="QDial" name="dDepth">
+      <property name="geometry">
+       <rect>
+        <x>10</x>
+        <y>103</y>
+        <width>50</width>
+        <height>51</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>210</number>
+      </property>
+      <property name="notchesVisible">
+       <bool>true</bool>
+      </property>
+     </widget>
+     <widget class="QDial" name="dLevelC">
+      <property name="geometry">
+       <rect>
+        <x>200</x>
+        <y>103</y>
+        <width>50</width>
+        <height>51</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>100</number>
+      </property>
+      <property name="notchesVisible">
+       <bool>true</bool>
+      </property>
+     </widget>
+     <widget class="QLabel" name="lbFeedBack">
+      <property name="geometry">
+       <rect>
+        <x>60</x>
+        <y>30</y>
+        <width>71</width>
+        <height>20</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Feedback</string>
+      </property>
+     </widget>
+     <widget class="QSpinBox" name="sbFeedBack">
+      <property name="geometry">
+       <rect>
+        <x>60</x>
+        <y>50</y>
+        <width>51</width>
+        <height>21</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>99</number>
+      </property>
+     </widget>
+     <widget class="QLabel" name="lbRate">
+      <property name="geometry">
+       <rect>
+        <x>140</x>
+        <y>30</y>
+        <width>51</width>
+        <height>20</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Rate</string>
+      </property>
+      <property name="alignment">
+       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+      </property>
+     </widget>
+     <widget class="QLabel" name="lbDepth">
+      <property name="geometry">
+       <rect>
+        <x>60</x>
+        <y>100</y>
+        <width>51</width>
+        <height>20</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Depth</string>
+      </property>
+     </widget>
+     <widget class="QLabel" name="lbLevelC">
+      <property name="geometry">
+       <rect>
+        <x>145</x>
+        <y>100</y>
+        <width>51</width>
+        <height>20</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Level</string>
+      </property>
+      <property name="alignment">
+       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+      </property>
+     </widget>
+     <widget class="QSpinBox" name="sbLevelC">
+      <property name="geometry">
+       <rect>
+        <x>140</x>
+        <y>120</y>
+        <width>56</width>
+        <height>21</height>
+       </rect>
+      </property>
+      <property name="maximum">
+       <number>100</number>
+      </property>
+     </widget>
+     <widget class="QDoubleSpinBox" name="sbRate">
+      <property name="geometry">
+       <rect>
+        <x>137</x>
+        <y>50</y>
+        <width>61</width>
+        <height>21</height>
+       </rect>
+      </property>
+      <property name="minimum">
+       <double>0.290000000000000</double>
+      </property>
+      <property name="maximum">
+       <double>5.000000000000000</double>
+      </property>
+      <property name="singleStep">
+       <double>0.100000000000000</double>
+      </property>
+     </widget>
+     <widget class="QLabel" name="lbLFO">
+      <property name="geometry">
+       <rect>
+        <x>35</x>
+        <y>77</y>
+        <width>41</width>
+        <height>20</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>LFO</string>
+      </property>
+     </widget>
+     <widget class="QRadioButton" name="rbSine">
+      <property name="geometry">
+       <rect>
+        <x>70</x>
+        <y>77</y>
+        <width>61</width>
+        <height>20</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Sine</string>
+      </property>
+     </widget>
+     <widget class="QRadioButton" name="rbTriangle">
+      <property name="geometry">
+       <rect>
+        <x>145</x>
+        <y>77</y>
+        <width>91</width>
+        <height>20</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string>Trian&amp;gle</string>
+      </property>
+     </widget>
+     <widget class="QDoubleSpinBox" name="sbDepth">
+      <property name="geometry">
+       <rect>
+        <x>60</x>
+        <y>120</y>
+        <width>51</width>
+        <height>21</height>
+       </rect>
+      </property>
+      <property name="decimals">
+       <number>1</number>
+      </property>
+      <property name="maximum">
+       <double>21.000000000000000</double>
+      </property>
+      <property name="singleStep">
+       <double>0.100000000000000</double>
+      </property>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmphelpwindow.cpp b/qmidiplayer-desktop/qmphelpwindow.cpp
new file mode 100644
index 0000000..10cf083
--- /dev/null
+++ b/qmidiplayer-desktop/qmphelpwindow.cpp
@@ -0,0 +1,31 @@
+#include <fluidsynth.h>
+#include "qmphelpwindow.hpp"
+#include "ui_qmphelpwindow.h"
+
+qmpHelpWindow::qmpHelpWindow(QWidget *parent) :
+	QDialog(parent),
+	ui(new Ui::qmpHelpWindow)
+{
+	ui->setupUi(this);
+	ui->textBrowser->setSearchPaths(QStringList(QString(":/doc"))+QStringList(QString(":/img")));
+	ui->textBrowser->setSource(QUrl("qrc:///doc/index.html"));
+}
+
+qmpHelpWindow::~qmpHelpWindow()
+{
+	delete ui;
+}
+
+void qmpHelpWindow::on_textBrowser_sourceChanged(const QUrl &src)
+{
+	if(src.fileName()==QString("version.html"))
+	{
+		QString s=ui->textBrowser->toHtml();
+		s.replace("CT_QT_VERSION_STR",QT_VERSION_STR);
+		s.replace("RT_QT_VERSION_STR",qVersion());
+		s.replace("CT_FLUIDSYNTH_VERSION",FLUIDSYNTH_VERSION);
+		s.replace("RT_FLUIDSYNTH_VERSION",fluid_version_str());
+		s.replace("APP_VERSION",APP_VERSION);
+		ui->textBrowser->setHtml(s);
+	}
+}
diff --git a/qmidiplayer-desktop/qmphelpwindow.hpp b/qmidiplayer-desktop/qmphelpwindow.hpp
new file mode 100644
index 0000000..c2052b2
--- /dev/null
+++ b/qmidiplayer-desktop/qmphelpwindow.hpp
@@ -0,0 +1,26 @@
+#ifndef QMPHELPWINDOW_H
+#define QMPHELPWINDOW_H
+
+#include <QDialog>
+#define APP_VERSION "0.7.0"
+
+namespace Ui {
+	class qmpHelpWindow;
+}
+
+class qmpHelpWindow : public QDialog
+{
+	Q_OBJECT
+
+	public:
+	explicit qmpHelpWindow(QWidget *parent = 0);
+	~qmpHelpWindow();
+
+	private slots:
+	void on_textBrowser_sourceChanged(const QUrl &src);
+
+	private:
+	Ui::qmpHelpWindow *ui;
+};
+
+#endif // QMPHELPWINDOW_H
diff --git a/qmidiplayer-desktop/qmphelpwindow.ui b/qmidiplayer-desktop/qmphelpwindow.ui
new file mode 100644
index 0000000..fd21b5f
--- /dev/null
+++ b/qmidiplayer-desktop/qmphelpwindow.ui
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpHelpWindow</class>
+ <widget class="QDialog" name="qmpHelpWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>640</width>
+    <height>360</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>640</width>
+    <height>360</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Help</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTextBrowser" name="textBrowser">
+     <property name="openExternalLinks">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmpimidimapper.hpp b/qmidiplayer-desktop/qmpimidimapper.hpp
new file mode 100644
index 0000000..d35dbb9
--- /dev/null
+++ b/qmidiplayer-desktop/qmpimidimapper.hpp
@@ -0,0 +1,16 @@
+#ifndef QMPIMIDIMAPPER_H
+#define QMPIMIDIMAPPER_H
+class qmpIMidiMapper
+{
+	virtual void deviceInit(int id)=0;
+	virtual void deviceDeinit(int id)=0;
+	virtual void noteOn(int ch,int key,int vel)=0;
+	virtual void noteOff(int ch,int key)=0;
+	virtual void ctrlChange(int ch,int cc,int val)=0;
+	virtual void progChange(int ch,int val)=0;
+	virtual void pitchBend(int ch,int val)=0;
+	virtual void sysEx(int length,const char* data)=0;
+	virtual static int enumDevices()=0;
+	virtual static char* deviceName(int id)=0;
+};
+#endif // QMPIMIDIMAPPER_H
diff --git a/qmidiplayer-desktop/qmpinfowindow.cpp b/qmidiplayer-desktop/qmpinfowindow.cpp
new file mode 100644
index 0000000..689a756
--- /dev/null
+++ b/qmidiplayer-desktop/qmpinfowindow.cpp
@@ -0,0 +1,57 @@
+#include <QTextCodec>
+#include "qmpinfowindow.hpp"
+#include "ui_qmpinfowindow.h"
+#include "qmpmainwindow.hpp"
+#include "qmpsettingswindow.hpp"
+
+const char* minors="abebbbf c g d a e b f#c#g#d#a#";
+const char* majors="CbGbDbAbEbBbF C G D A E B F#C#";
+const char* standards="?  GM GM2GS XG ";
+
+qmpInfoWindow::qmpInfoWindow(QWidget *parent) :
+	QDialog(parent),
+	ui(new Ui::qmpInfoWindow)
+{
+	ui->setupUi(this);
+}
+
+qmpInfoWindow::~qmpInfoWindow()
+{
+	delete ui;
+}
+
+void qmpInfoWindow::updateInfo()
+{
+	char str[256];
+	CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
+	QSettings* settings=qmpSettingsWindow::getSettingsIntf();
+	ui->lbFileName->setText(QString("File name: ")+qmpMainWindow::getInstance()->getFileName());
+	if(player->getTitle())
+	{
+		if(settings->value("Midi/TextEncoding","").toString()!="Unicode")
+		ui->lbTitle->setText(QString("Title: ")+
+		QTextCodec::codecForName(settings->value("Midi/TextEncoding","").toString().toStdString().c_str())->toUnicode(player->getTitle()));
+		else
+		ui->lbTitle->setText(QString("Title: ")+player->getTitle());
+	}
+	else ui->lbTitle->setText(QString("Title: "));
+	if(player->getCopyright())
+	{
+		if(settings->value("Midi/TextEncoding","").toString()!="Unicode")
+		ui->lbCopyright->setText(QString("Copyright: ")+
+		QTextCodec::codecForName(settings->value("Midi/TextEncoding","").toString().toStdString().c_str())->toUnicode(player->getCopyright()));
+		else
+		ui->lbCopyright->setText(QString("Copyright: ")+player->getCopyright());
+	}
+	else ui->lbCopyright->setText(QString("Copyright: "));
+	ui->lbTempo->setText(QString("Tempo: ")+QString::number(player->getTempo(),'g',5));
+	int t,r;player->getCurrentKeySignature(&t);r=(int8_t)((t>>8)&0xFF)+7;
+	strncpy(str,t&0xFF?minors+2*r:majors+2*r,2);str[2]='\0';
+	ui->lbKeySig->setText(QString("Key Sig.: ")+str);
+	player->getCurrentTimeSignature(&t,&r);sprintf(str,"Time Sig.: %d/%d",t,r);
+	ui->lbTimeSig->setText(str);
+	sprintf(str,"Note count: %u",player->getFileNoteCount());
+	ui->lbNoteCount->setText(str);
+	strncpy(str,standards+player->getFileStandard()*3,3);str[3]='\0';
+	ui->lbFileStandard->setText(QString("File standard: ")+str);
+}
diff --git a/qmidiplayer-desktop/qmpinfowindow.hpp b/qmidiplayer-desktop/qmpinfowindow.hpp
new file mode 100644
index 0000000..9a1e389
--- /dev/null
+++ b/qmidiplayer-desktop/qmpinfowindow.hpp
@@ -0,0 +1,24 @@
+#ifndef QMPINFOWINDOW_HPP
+#define QMPINFOWINDOW_HPP
+
+#include <QDialog>
+
+namespace Ui {
+	class qmpInfoWindow;
+}
+
+class qmpInfoWindow : public QDialog
+{
+	Q_OBJECT
+
+	public:
+		explicit qmpInfoWindow(QWidget *parent = 0);
+		~qmpInfoWindow();
+	public slots:
+		void updateInfo();
+
+	private:
+		Ui::qmpInfoWindow *ui;
+};
+
+#endif // QMPINFOWINDOW_HPP
diff --git a/qmidiplayer-desktop/qmpinfowindow.ui b/qmidiplayer-desktop/qmpinfowindow.ui
new file mode 100644
index 0000000..664531a
--- /dev/null
+++ b/qmidiplayer-desktop/qmpinfowindow.ui
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpInfoWindow</class>
+ <widget class="QDialog" name="qmpInfoWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>142</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>400</width>
+    <height>142</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>File Information</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLabel" name="lbFileName">
+     <property name="text">
+      <string>File name: </string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="lbTempo">
+       <property name="text">
+        <string>Tempo: </string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="lbKeySig">
+       <property name="text">
+        <string>Key Sig.: </string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="lbTimeSig">
+       <property name="text">
+        <string>Time Sig.:</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QLabel" name="lbTitle">
+     <property name="text">
+      <string>Title: </string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLabel" name="lbCopyright">
+     <property name="text">
+      <string>Copyright: </string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QLabel" name="lbNoteCount">
+       <property name="text">
+        <string>Note count: </string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="lbFileStandard">
+       <property name="text">
+        <string>File standard: </string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp
new file mode 100644
index 0000000..58caea1
--- /dev/null
+++ b/qmidiplayer-desktop/qmpmainwindow.cpp
@@ -0,0 +1,510 @@
+#include <cstdio>
+#include <QUrl>
+#include <QMimeData>
+#include <QDirIterator>
+#include <QDesktopWidget>
+#include "qmpmainwindow.hpp"
+#include "ui_qmpmainwindow.h"
+#include "../core/qmpmidiplay.hpp"
+#ifdef _WIN32
+#include <Windows.h>
+#endif
+
+qmpMainWindow* qmpMainWindow::ref=NULL;
+
+qmpMainWindow::qmpMainWindow(QWidget *parent) :
+	QMainWindow(parent),
+	ui(new Ui::qmpMainWindow)
+{
+	ui->setupUi(this);
+	ui->lbFileName->setText("");ref=this;
+	playing=false;stopped=true;dragging=false;
+	settingsw=new qmpSettingsWindow(this);
+	plistw=new qmpPlistWindow(this);
+	chnlw=new qmpChannelsWindow(this);
+	efxw=new qmpEfxWindow(this);
+	infow=new qmpInfoWindow(this);
+	helpw=new qmpHelpWindow(this);
+	timer=new QTimer(this);
+	fnA1=new QAction("File Information",ui->lbFileName);
+	fnA2=new QAction("Render to Wave",ui->lbFileName);
+	ui->lbFileName->addAction(fnA1);
+	ui->lbFileName->addAction(fnA2);
+	singleFS=qmpSettingsWindow::getSettingsIntf()->value("Behavior/SingleInstance",0).toInt();
+	player=new CMidiPlayer(singleFS);
+	if(singleFS){player->fluidPreInitialize();playerSetup();player->fluidInitialize();
+		for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+			player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
+	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus",0).toInt())
+	{
+		QRect g=geometry();
+		g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/MainW",QPoint(-999,-999)).toPoint());
+		if(g.topLeft()!=QPoint(-999,-999))setGeometry(g);
+		else setGeometry(QStyle::alignedRect(
+							 Qt::LeftToRight,Qt::AlignCenter,size(),
+							 qApp->desktop()->availableGeometry()));
+	}show();
+	if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListWShown",0).toInt())
+	{ui->pbPList->setChecked(true);on_pbPList_clicked();}
+	if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlWShown",0).toInt())
+	{ui->pbChannels->setChecked(true);on_pbChannels_clicked();}
+	if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxWShown",0).toInt())
+	{ui->pbEfx->setChecked(true);on_pbEfx_clicked();}
+	ui->vsMasterVol->setValue(qmpSettingsWindow::getSettingsIntf()->value("Audio/Gain",50).toInt());
+	connect(fnA1,SIGNAL(triggered()),this,SLOT(onfnA1()));
+	connect(fnA2,SIGNAL(triggered()),this,SLOT(onfnA2()));
+	connect(timer,SIGNAL(timeout()),this,SLOT(updateWidgets()));
+	connect(timer,SIGNAL(timeout()),chnlw,SLOT(channelWindowsUpdate()));
+	connect(timer,SIGNAL(timeout()),infow,SLOT(updateInfo()));
+}
+
+qmpMainWindow::~qmpMainWindow()
+{
+	delete player;
+	delete timer;
+	delete ui;
+}
+
+int qmpMainWindow::pharseArgs(int argc,char** argv)
+{
+	bool havemidi=false,loadfolder=false;
+	for(int i=1;i<argc;++i)
+	{
+		if(argv[i][0]=='-')
+		{
+			if(!strcmp(argv[i],"--help"))
+			{
+				printf("Usage: %s [Options] [Midi Files]\n",argv[0]);
+				printf("Possible options are: \n");
+				printf("-l, --load-all-files  Load all files from the same folder.\n");
+				printf("--help                Show this help and exit.\n");
+				printf("--version             Show this version information and exit.\n");
+				return 1;
+			}
+			if(!strcmp(argv[i],"--version"))
+			{
+				printf("QMidiPlayer %s\n",APP_VERSION);
+				return 1;
+			}
+			if(!strcmp(argv[i],"-l")||!strcmp(argv[i],"--load-all-files"))
+				loadfolder=true;
+		}
+		else
+		if(fluid_is_midifile(argv[i]))
+		{
+			if(!havemidi){havemidi=true;plistw->emptyList();}
+			if(loadfolder||qmpSettingsWindow::getSettingsIntf()->value("Behavior/LoadFolder",0).toInt())
+			{
+				QDirIterator di(QUrl(argv[i]).adjusted(QUrl::RemoveFilename).toString());
+				while(di.hasNext())
+				{
+					QString c=di.next();
+					if((c.endsWith(".mid")||c.endsWith(".midi"))&&fluid_is_midifile(c.toStdString().c_str()))
+					plistw->insertItem(c.toStdString().c_str());
+				}
+			}
+			else
+			plistw->insertItem(argv[i]);
+		}
+	}
+	if(havemidi)on_pbPlayPause_clicked();
+	return 0;
+}
+
+void qmpMainWindow::closeEvent(QCloseEvent *event)
+{
+	on_pbStop_clicked();fin=true;
+	efxw->close();chnlw->close();
+	plistw->close();infow->close();
+	settingsw->close();
+	delete helpw;helpw=NULL;
+	delete efxw;efxw=NULL;
+	delete chnlw;chnlw=NULL;
+	delete plistw;plistw=NULL;
+	delete infow;infow=NULL;
+	delete settingsw;settingsw=NULL;
+	event->accept();
+}
+
+void qmpMainWindow::moveEvent(QMoveEvent *event)
+{
+	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+	{
+		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/MainW",event->pos());
+	}
+}
+void qmpMainWindow::dropEvent(QDropEvent *event)
+{
+	QList<QUrl> l=event->mimeData()->urls();
+	QStringList sl;
+	for(int i=0;i<l.size();++i)
+		sl.push_back(l.at(i).toLocalFile());
+	plistw->insertItems(sl);
+}
+void qmpMainWindow::dragEnterEvent(QDragEnterEvent *event)
+{
+	//if(event->mimeData()->hasFormat("application/x-midi"))
+	event->acceptProposedAction();
+}
+
+void qmpMainWindow::updateWidgets()
+{
+	fnA2->setEnabled(stopped);
+	if(player->isFinished()&&playerTh)
+	{
+		if(!plistw->getRepeat())
+		{
+			timer->stop();stopped=true;playing=false;
+			fnA2->setEnabled(stopped);
+			player->playerDeinit();playerTh->join();
+			delete playerTh;playerTh=NULL;
+			if(singleFS)player->playerPanic(true);
+			chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
+			ui->pbPlayPause->setIcon(QIcon(":/img/play.png"));
+			ui->hsTimer->setValue(0);
+			ui->lbPolyphone->setText("Poly: 0/0");
+			ui->lbCurTime->setText("00:00");
+		}
+		else
+		{
+			timer->stop();player->playerDeinit();playerTh->join();
+			delete playerTh;playerTh=NULL;
+			ui->hsTimer->setValue(0);
+			if(singleFS)player->playerPanic(true);
+			chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
+			QString fns=plistw->getNextItem();
+			ui->lbFileName->setText(QUrl(fns).fileName());
+			if(!player->playerLoadFile(fns.toStdString().c_str()))return;
+			char ts[100];
+			sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
+			ui->lbFinTime->setText(ts);
+			player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
+			for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+				player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
+			player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
+			player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
+			playerTh=new std::thread(&CMidiPlayer::playerThread,player);
+#ifdef _WIN32
+			SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+			st=std::chrono::steady_clock::now();offset=0;
+			timer->start(100);
+		}
+	}
+	if(renderTh)
+	{
+		if(player->isFinished())
+		{
+			renderTh->join();timer->stop();
+			ui->centralWidget->setEnabled(true);
+			delete renderTh;renderTh=NULL;
+			player->rendererDeinit();
+			if(singleFS){player->fluidPreInitialize();playerSetup();player->fluidInitialize();}
+		}
+	}
+	while(!player->isFinished()&&player->getTCeptr()>player->getStamp(ui->hsTimer->value())
+		  &&ui->hsTimer->value()<=100&&!dragging)
+		ui->hsTimer->setValue(ui->hsTimer->value()+1);
+	if(playing)
+	{
+		std::chrono::duration<double> elapsed=
+				std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now()-st);
+		char ts[100];
+		sprintf(ts,"%02d:%02d",(int)(elapsed.count()+offset)/60,(int)(elapsed.count()+offset)%60);
+		ui->lbCurTime->setText(ts);
+		sprintf(ts,"Poly: %d/%d",player->getPolyphone(),player->getMaxPolyphone());
+		ui->lbPolyphone->setText(ts);
+	}
+}
+
+QString qmpMainWindow::getFileName(){return ui->lbFileName->text();}
+
+void qmpMainWindow::playerSetup()
+{
+	fluid_settings_t* fsettings=player->getFluidSettings();
+	QSettings* settings=qmpSettingsWindow::getSettingsIntf();
+	fluid_settings_setstr(fsettings,"audio.driver",settings->value("Audio/Driver","").toString().toStdString().c_str());
+	fluid_settings_setint(fsettings,"audio.period-size",settings->value("Audio/BufSize","").toInt());
+	fluid_settings_setint(fsettings,"audio.periods",settings->value("Audio/BufCnt","").toInt());
+	fluid_settings_setstr(fsettings,"audio.sample-format",settings->value("Audio/Format","").toString().toStdString().c_str());
+	fluid_settings_setint(fsettings,"synth.sample-rate",settings->value("Audio/Frequency","").toInt());
+	fluid_settings_setint(fsettings,"synth.polyphony",settings->value("Audio/Polyphony","").toInt());
+	fluid_settings_setint(fsettings,"synth.cpu-cores",settings->value("Audio/Threads","").toInt());
+	char bsmode[4];
+	if(!singleFS&&settings->value("Audio/AutoBS",1).toInt()&&player->getFileStandard())
+		switch(player->getFileStandard())
+		{
+			case 1:strcpy(bsmode,"gm");break;
+			case 2:strcpy(bsmode,"mma");break;
+			case 3:strcpy(bsmode,"gs");break;
+			case 4:strcpy(bsmode,"xg");break;
+		}
+	else
+	{
+		if(settings->value("Audio/BankSelect","CC#0").toString()==QString("Ignored"))
+			strcpy(bsmode,"gm");
+		if(settings->value("Audio/BankSelect","CC#0").toString()==QString("CC#0"))
+			strcpy(bsmode,"gs");
+		if(settings->value("Audio/BankSelect","CC#0").toString()==QString("CC#32"))
+			strcpy(bsmode,"xg");
+		if(settings->value("Audio/BankSelect","CC#0").toString()==QString("CC#0*128+CC#32"))
+			strcpy(bsmode,"mma");
+	}
+	fluid_settings_setstr(fsettings,"synth.midi-bank-select",bsmode);
+	player->sendSysX(settings->value("Midi/SendSysEx",1).toInt());
+}
+
+void qmpMainWindow::on_pbPlayPause_clicked()
+{
+	playing=!playing;
+	if(stopped)
+	{
+		QString fns=plistw->getFirstItem();
+		if(!fns.length())
+		{
+			plistw->on_pbAdd_clicked();
+			fns=plistw->getFirstItem();
+			if(!fns.length())return(void)(playing=false);
+		}
+		ui->lbFileName->setText(QUrl(fns).fileName());
+		if(!player->playerLoadFile(fns.toStdString().c_str()))return;
+		char ts[100];
+		sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
+		ui->lbFinTime->setText(ts);
+		player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
+		for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+			player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
+		player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
+		player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
+		playerTh=new std::thread(&CMidiPlayer::playerThread,player);
+#ifdef _WIN32
+			SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+		st=std::chrono::steady_clock::now();offset=0;
+		timer->start(100);
+		stopped=false;
+	}
+	else
+	{
+		if(!playing)
+		{
+			player->playerPanic();
+			offset=ui->hsTimer->value()/100.*player->getFtime();
+		}
+		else
+		{
+			st=std::chrono::steady_clock::now();
+			player->setResumed();
+		}
+		player->setTCpaused(!playing);
+	}
+	ui->pbPlayPause->setIcon(QIcon(playing?":/img/pause.png":":/img/play.png"));
+}
+
+void qmpMainWindow::on_hsTimer_sliderPressed()
+{
+	dragging=true;
+}
+
+void qmpMainWindow::on_hsTimer_sliderReleased()
+{
+	dragging=false;
+	if(playing)
+	{
+		if(ui->hsTimer->value()==100){on_pbNext_clicked();return;}
+		player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value());
+		player->playerPanic();
+		offset=ui->hsTimer->value()/100.*player->getFtime();
+		st=std::chrono::steady_clock::now();
+	}
+	else
+	{
+		player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value());
+		offset=ui->hsTimer->value()/100.*player->getFtime();
+		char ts[100];
+		sprintf(ts,"%02d:%02d",(int)(offset)/60,(int)(offset)%60);
+		ui->lbCurTime->setText(ts);
+	}
+}
+
+void qmpMainWindow::on_vsMasterVol_valueChanged()
+{
+	if(!stopped)player->setGain(ui->vsMasterVol->value()/250.);
+	qmpSettingsWindow::getSettingsIntf()->setValue("Audio/Gain",ui->vsMasterVol->value());
+}
+
+void qmpMainWindow::on_pbStop_clicked()
+{
+	if(!stopped)
+	{
+		timer->stop();stopped=true;playing=false;
+		player->playerDeinit();fnA2->setEnabled(stopped);
+		if(singleFS)player->playerPanic(true);
+		if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
+		chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
+		ui->pbPlayPause->setIcon(QIcon(":/img/play.png"));
+		ui->hsTimer->setValue(0);
+		ui->lbPolyphone->setText("Poly: 0/0");
+		ui->lbCurTime->setText("00:00");
+	}
+}
+
+void qmpMainWindow::dialogClosed()
+{
+	if(!plistw->isVisible())ui->pbPList->setChecked(false);
+	if(!chnlw->isVisible())ui->pbChannels->setChecked(false);
+	if(!efxw->isVisible())ui->pbEfx->setChecked(false);
+	if(!settingsw->isVisible())ui->pbSettings->setChecked(false);
+}
+
+void qmpMainWindow::on_pbPList_clicked()
+{
+	if(ui->pbPList->isChecked())
+	{
+		QRect g=plistw->geometry();
+		g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListW",QPoint(-999,-999)).toPoint());
+		if(g.topLeft()==QPoint(-999,-999))
+			g.setTopLeft(window()->mapToGlobal(window()->rect().center())-plistw->rect().center());
+		plistw->setGeometry(g);
+		plistw->show();
+	}else plistw->close();
+}
+
+void qmpMainWindow::on_pbChannels_clicked()
+{
+	if(ui->pbChannels->isChecked())
+	{
+		QRect g=chnlw->geometry();
+		g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlW",QPoint(-999,-999)).toPoint());
+		if(g.topLeft()==QPoint(-999,-999))
+			g.setTopLeft(window()->mapToGlobal(window()->rect().center())-chnlw->rect().center());
+		chnlw->setGeometry(g);
+		chnlw->show();
+	}else chnlw->close();
+}
+
+void qmpMainWindow::on_pbPrev_clicked()
+{
+	timer->stop();player->playerDeinit();
+	if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
+	if(singleFS)player->playerPanic(true);
+	ui->hsTimer->setValue(0);chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
+	QString fns=plistw->getPrevItem();if(fns.length()==0)return on_pbStop_clicked();
+	ui->lbFileName->setText(QUrl(fns).fileName());
+	if(!player->playerLoadFile(fns.toStdString().c_str()))return;
+	char ts[100];
+	sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
+	ui->lbFinTime->setText(ts);
+	player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
+	for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+		player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
+	player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
+	player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
+	playerTh=new std::thread(&CMidiPlayer::playerThread,player);
+#ifdef _WIN32
+			SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+	st=std::chrono::steady_clock::now();offset=0;
+	timer->start(100);
+}
+
+void qmpMainWindow::on_pbNext_clicked()
+{
+	timer->stop();player->playerDeinit();
+	if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
+	if(singleFS)player->playerPanic(true);
+	ui->hsTimer->setValue(0);chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
+	QString fns=plistw->getNextItem();if(fns.length()==0)return on_pbStop_clicked();
+	ui->lbFileName->setText(QUrl(fns).fileName());
+	if(!player->playerLoadFile(fns.toStdString().c_str()))return;
+	char ts[100];
+	sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
+	ui->lbFinTime->setText(ts);
+	player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
+	for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+		player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
+	player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
+	player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
+	playerTh=new std::thread(&CMidiPlayer::playerThread,player);
+#ifdef _WIN32
+			SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+	st=std::chrono::steady_clock::now();offset=0;
+	timer->start(100);
+}
+
+void qmpMainWindow::selectionChanged()
+{
+	stopped=false;playing=true;
+	ui->pbPlayPause->setIcon(QIcon(":/img/pause.png"));
+	timer->stop();player->playerDeinit();
+	if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
+	if(singleFS)player->playerPanic(true);
+	ui->hsTimer->setValue(0);
+	chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
+	QString fns=plistw->getSelectedItem();
+	ui->lbFileName->setText(QUrl(fns).fileName());
+	if(!player->playerLoadFile(fns.toStdString().c_str()))return;
+	char ts[100];
+	sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
+	ui->lbFinTime->setText(ts);
+	player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
+	for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+		player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
+	player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
+	player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
+	playerTh=new std::thread(&CMidiPlayer::playerThread,player);
+#ifdef _WIN32
+			SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
+#endif
+	st=std::chrono::steady_clock::now();offset=0;
+	timer->start(100);
+}
+
+void qmpMainWindow::on_pbEfx_clicked()
+{
+	if(ui->pbEfx->isChecked())
+	{
+		QRect g=efxw->geometry();
+		g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxW",QPoint(-999,-999)).toPoint());
+		if(g.topLeft()==QPoint(-999,-999))
+			g.setTopLeft(window()->mapToGlobal(window()->rect().center())-efxw->rect().center());
+		efxw->setGeometry(g);
+		efxw->show();
+	}
+	else efxw->close();
+}
+
+void qmpMainWindow::on_lbFileName_customContextMenuRequested(const QPoint &pos)
+{
+	QMenu menu(ui->lbFileName);
+	menu.addActions(ui->lbFileName->actions());
+	menu.exec(this->pos()+ui->lbFileName->pos()+pos);
+}
+
+void qmpMainWindow::onfnA1()
+{
+	infow->show();
+}
+
+void qmpMainWindow::onfnA2()
+{
+	if(singleFS)player->fluidDeinitialize();
+	player->rendererLoadFile((plistw->getSelectedItem()+QString(".wav")).toStdString().c_str());
+	playerSetup();player->rendererInit(plistw->getSelectedItem().toStdString().c_str());
+	ui->centralWidget->setEnabled(false);
+	for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
+		player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());
+	player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();timer->start(100);
+	renderTh=new std::thread(&CMidiPlayer::rendererThread,player);
+}
+
+void qmpMainWindow::on_pbSettings_clicked()
+{
+	if(ui->pbSettings->isChecked())settingsw->show();else settingsw->close();
+}
+
+void qmpMainWindow::on_pushButton_clicked()
+{
+	helpw->show();
+}
diff --git a/qmidiplayer-desktop/qmpmainwindow.hpp b/qmidiplayer-desktop/qmpmainwindow.hpp
new file mode 100644
index 0000000..a409d2e
--- /dev/null
+++ b/qmidiplayer-desktop/qmpmainwindow.hpp
@@ -0,0 +1,90 @@
+#ifndef QMPMAINWINDOW_H
+#define QMPMAINWINDOW_H
+
+#include <QMainWindow>
+#include <QTimer>
+#include <QCloseEvent>
+#include <QMoveEvent>
+#include <QDropEvent>
+#include <QDragEnterEvent>
+#include <QAction>
+#include <QMenu>
+#include <thread>
+#include <chrono>
+#include "../core/qmpmidiplay.hpp"
+#include "qmpplistwindow.hpp"
+#include "qmpchannelswindow.hpp"
+#include "qmpefxwindow.hpp"
+#include "qmpinfowindow.hpp"
+#include "qmpsettingswindow.hpp"
+#include "qmphelpwindow.hpp"
+
+namespace Ui {
+	class qmpMainWindow;
+}
+
+class qmpMainWindow:public QMainWindow
+{
+	Q_OBJECT
+
+	public:
+		explicit qmpMainWindow(QWidget *parent = 0);
+		void closeEvent(QCloseEvent *event);
+		void moveEvent(QMoveEvent *event);
+		void dropEvent(QDropEvent *event);
+		void dragEnterEvent(QDragEnterEvent *event);
+		~qmpMainWindow();
+		CMidiPlayer* getPlayer(){return player;}
+		QTimer* getTimer(){return timer;}
+		bool isFinalizing(){return fin;}
+		QString getFileName();
+		int pharseArgs(int argc,char** argv);
+
+	private slots:
+		void on_pbPlayPause_clicked();
+		void updateWidgets();
+		void on_hsTimer_sliderPressed();
+		void on_hsTimer_sliderReleased();
+		void on_vsMasterVol_valueChanged();
+		void on_pbStop_clicked();
+		void on_pbPList_clicked();
+		void on_pbPrev_clicked();
+		void on_pbNext_clicked();
+		void on_pbChannels_clicked();
+		void on_pbEfx_clicked();
+		void on_lbFileName_customContextMenuRequested(const QPoint &pos);
+		void on_pbSettings_clicked();
+		void onfnA1();
+		void onfnA2();
+
+		void on_pushButton_clicked();
+
+	public slots:
+		void dialogClosed();
+		void selectionChanged();
+
+	private:
+		Ui::qmpMainWindow *ui;
+		QTimer *timer;
+		bool playing,stopped,dragging,fin,singleFS;
+		std::thread *playerTh=NULL;
+		std::thread *renderTh=NULL;
+		std::chrono::steady_clock::time_point st;
+		double offset;
+		CMidiPlayer *player;
+		qmpPlistWindow *plistw;
+		qmpChannelsWindow *chnlw;
+		qmpEfxWindow *efxw;
+		qmpInfoWindow *infow;
+		qmpSettingsWindow *settingsw;
+		qmpHelpWindow *helpw;
+
+		QAction *fnA1,*fnA2;
+		void playerSetup();
+
+	private:
+		static qmpMainWindow* ref;
+	public: static qmpMainWindow* getInstance(){return ref;}
+};
+
+#endif // QMPMAINWINDOW_H
diff --git a/qmidiplayer-desktop/qmpmainwindow.ui b/qmidiplayer-desktop/qmpmainwindow.ui
new file mode 100644
index 0000000..0764e09
--- /dev/null
+++ b/qmidiplayer-desktop/qmpmainwindow.ui
@@ -0,0 +1,413 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpMainWindow</class>
+ <widget class="QMainWindow" name="qmpMainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>435</width>
+    <height>245</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>435</width>
+    <height>245</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>435</width>
+    <height>245</height>
+   </size>
+  </property>
+  <property name="acceptDrops">
+   <bool>true</bool>
+  </property>
+  <property name="windowTitle">
+   <string>QMidiPlayer</string>
+  </property>
+  <property name="windowIcon">
+   <iconset resource="resources.qrc">
+    <normaloff>:/img/qmidiplyr.png</normaloff>:/img/qmidiplyr.png</iconset>
+  </property>
+  <widget class="QWidget" name="centralWidget">
+   <widget class="QLabel" name="lbFileName">
+    <property name="geometry">
+     <rect>
+      <x>30</x>
+      <y>20</y>
+      <width>311</width>
+      <height>41</height>
+     </rect>
+    </property>
+    <property name="font">
+     <font>
+      <pointsize>18</pointsize>
+     </font>
+    </property>
+    <property name="contextMenuPolicy">
+     <enum>Qt::CustomContextMenu</enum>
+    </property>
+    <property name="text">
+     <string>somefile.mid</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QSlider" name="hsTimer">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>90</y>
+      <width>321</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>100</number>
+    </property>
+    <property name="pageStep">
+     <number>0</number>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Horizontal</enum>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pbPlayPause">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>110</y>
+      <width>61</width>
+      <height>36</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string/>
+    </property>
+    <property name="icon">
+     <iconset resource="resources.qrc">
+      <normaloff>:/img/play.png</normaloff>:/img/play.png</iconset>
+    </property>
+    <property name="iconSize">
+     <size>
+      <width>32</width>
+      <height>32</height>
+     </size>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pbStop">
+    <property name="geometry">
+     <rect>
+      <x>80</x>
+      <y>110</y>
+      <width>61</width>
+      <height>36</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string/>
+    </property>
+    <property name="icon">
+     <iconset resource="resources.qrc">
+      <normaloff>:/img/stop.png</normaloff>:/img/stop.png</iconset>
+    </property>
+    <property name="iconSize">
+     <size>
+      <width>32</width>
+      <height>32</height>
+     </size>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pbPrev">
+    <property name="geometry">
+     <rect>
+      <x>140</x>
+      <y>110</y>
+      <width>61</width>
+      <height>36</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string/>
+    </property>
+    <property name="icon">
+     <iconset resource="resources.qrc">
+      <normaloff>:/img/prev.png</normaloff>:/img/prev.png</iconset>
+    </property>
+    <property name="iconSize">
+     <size>
+      <width>32</width>
+      <height>32</height>
+     </size>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pbNext">
+    <property name="geometry">
+     <rect>
+      <x>200</x>
+      <y>110</y>
+      <width>61</width>
+      <height>36</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string/>
+    </property>
+    <property name="icon">
+     <iconset resource="resources.qrc">
+      <normaloff>:/img/next.png</normaloff>:/img/next.png</iconset>
+    </property>
+    <property name="iconSize">
+     <size>
+      <width>32</width>
+      <height>32</height>
+     </size>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pbSettings">
+    <property name="geometry">
+     <rect>
+      <x>280</x>
+      <y>110</y>
+      <width>61</width>
+      <height>36</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string/>
+    </property>
+    <property name="icon">
+     <iconset resource="resources.qrc">
+      <normaloff>:/img/settings.png</normaloff>:/img/settings.png</iconset>
+    </property>
+    <property name="iconSize">
+     <size>
+      <width>32</width>
+      <height>32</height>
+     </size>
+    </property>
+    <property name="checkable">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pbChannels">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>160</y>
+      <width>151</width>
+      <height>36</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">text-align:left</string>
+    </property>
+    <property name="text">
+     <string>Channels</string>
+    </property>
+    <property name="icon">
+     <iconset resource="resources.qrc">
+      <normaloff>:/img/channel.png</normaloff>:/img/channel.png</iconset>
+    </property>
+    <property name="iconSize">
+     <size>
+      <width>32</width>
+      <height>32</height>
+     </size>
+    </property>
+    <property name="checkable">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pbPList">
+    <property name="geometry">
+     <rect>
+      <x>190</x>
+      <y>160</y>
+      <width>151</width>
+      <height>36</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">text-align:left</string>
+    </property>
+    <property name="text">
+     <string>Playlist</string>
+    </property>
+    <property name="icon">
+     <iconset resource="resources.qrc">
+      <normaloff>:/img/list.png</normaloff>:/img/list.png</iconset>
+    </property>
+    <property name="iconSize">
+     <size>
+      <width>32</width>
+      <height>32</height>
+     </size>
+    </property>
+    <property name="checkable">
+     <bool>true</bool>
+    </property>
+    <property name="checked">
+     <bool>false</bool>
+    </property>
+    <property name="flat">
+     <bool>false</bool>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pbEfx">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>200</y>
+      <width>151</width>
+      <height>36</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">text-align:left</string>
+    </property>
+    <property name="text">
+     <string>Effects</string>
+    </property>
+    <property name="icon">
+     <iconset resource="resources.qrc">
+      <normaloff>:/img/effects.png</normaloff>:/img/effects.png</iconset>
+    </property>
+    <property name="iconSize">
+     <size>
+      <width>32</width>
+      <height>32</height>
+     </size>
+    </property>
+    <property name="checkable">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pbVisualization">
+    <property name="geometry">
+     <rect>
+      <x>190</x>
+      <y>200</y>
+      <width>151</width>
+      <height>36</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">text-align:left</string>
+    </property>
+    <property name="text">
+     <string>Visualization</string>
+    </property>
+    <property name="icon">
+     <iconset resource="resources.qrc">
+      <normaloff>:/img/visualization.png</normaloff>:/img/visualization.png</iconset>
+    </property>
+    <property name="iconSize">
+     <size>
+      <width>32</width>
+      <height>32</height>
+     </size>
+    </property>
+   </widget>
+   <widget class="QLabel" name="lbPolyphone">
+    <property name="geometry">
+     <rect>
+      <x>320</x>
+      <y>20</y>
+      <width>111</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Poly: 0/0&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QSlider" name="vsMasterVol">
+    <property name="geometry">
+     <rect>
+      <x>370</x>
+      <y>50</y>
+      <width>20</width>
+      <height>160</height>
+     </rect>
+    </property>
+    <property name="maximum">
+     <number>100</number>
+    </property>
+    <property name="value">
+     <number>50</number>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Vertical</enum>
+    </property>
+   </widget>
+   <widget class="QLabel" name="lbMasterVol">
+    <property name="geometry">
+     <rect>
+      <x>360</x>
+      <y>210</y>
+      <width>61</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Master</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="lbCurTime">
+    <property name="geometry">
+     <rect>
+      <x>20</x>
+      <y>70</y>
+      <width>66</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>00:00</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="lbFinTime">
+    <property name="geometry">
+     <rect>
+      <x>270</x>
+      <y>70</y>
+      <width>66</width>
+      <height>20</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>00:00</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="pushButton">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>0</y>
+      <width>21</width>
+      <height>21</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>?</string>
+    </property>
+   </widget>
+  </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources>
+  <include location="resources.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmpplistwindow.cpp b/qmidiplayer-desktop/qmpplistwindow.cpp
new file mode 100644
index 0000000..8f04fc1
--- /dev/null
+++ b/qmidiplayer-desktop/qmpplistwindow.cpp
@@ -0,0 +1,308 @@
+#include <cstdlib>
+#include <ctime>
+#include <QFileDialog>
+#include <QDir>
+#include <QDirIterator>
+#include <QSettings>
+#include <QUrl>
+#include <QMimeData>
+#include "qmpplistwindow.hpp"
+#include "ui_qmpplistwindow.h"
+#include "qmpmainwindow.hpp"
+
+qmpPlistWindow::qmpPlistWindow(QWidget *parent) :
+	QDialog(parent),
+	ui(new Ui::qmpPlistWindow)
+{
+	ui->setupUi(this);
+	connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed()));
+	connect(this,SIGNAL(selectionChanging()),parent,SLOT(selectionChanged()));
+	repeat=0;shuffle=0;
+	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/RestorePlaylist","").toInt())
+	{
+		QSettings* plist=new QSettings(QDir::homePath()+QString("/.config/qmpplist"),
+									   QSettings::IniFormat);
+		int fc=plist->value("Playlist/FileCount",0).toInt();
+		ui->lwFiles->clear();for(int i=1;i<=fc;++i)
+		ui->lwFiles->addItem(plist->value("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),"").toString());
+		repeat=plist->value("Playlist/Repeat",0).toInt();
+		shuffle=plist->value("Playlist/Shuffle",0).toInt();
+		switch(shuffle)
+		{
+			case 1:
+				ui->pbShuffle->setIcon(QIcon(":/img/shuffle.png"));
+				ui->pbShuffle->setText("Shuffle On");
+			break;
+			case 0:
+			default:
+				ui->pbShuffle->setIcon(QIcon(":/img/shuffle-off.png"));
+				ui->pbShuffle->setText("Shuffle Off");
+			break;
+		}
+		switch(repeat)
+		{
+			case 0:
+				ui->pbRepeat->setIcon(QIcon(":/img/repeat-non.png"));
+				ui->pbRepeat->setText("Repeat Off");
+			break;
+			case 1:
+				ui->pbRepeat->setIcon(QIcon(":/img/repeat-one.png"));
+				ui->pbRepeat->setText("Repeat One");
+			break;
+			case 2:
+				ui->pbRepeat->setIcon(QIcon(":/img/repeat-all.png"));
+				ui->pbRepeat->setText("Repeat All");
+			break;
+		}
+		delete plist;
+	}
+}
+
+qmpPlistWindow::~qmpPlistWindow()
+{
+	delete ui;
+}
+
+void qmpPlistWindow::showEvent(QShowEvent *event)
+{
+	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+	{
+		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListWShown",1);
+	}
+	event->accept();
+}
+
+void qmpPlistWindow::closeEvent(QCloseEvent *event)
+{
+	setVisible(false);
+	if(!qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+	{
+		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListWShown",0);
+	}
+	if(qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/RestorePlaylist","").toInt())
+	{
+		QSettings* plist=new QSettings(QDir::homePath()+QString("/.config/qmpplist"),
+									   QSettings::IniFormat);
+		plist->setValue("Playlist/FileCount",ui->lwFiles->count());
+		for(int i=0;i<ui->lwFiles->count();++i)
+		plist->setValue("Playlist/File"+QString("%1").arg(i+1,5,10,QChar('0')),ui->lwFiles->item(i)->text());
+		plist->setValue("Playlist/Repeat",repeat);
+		plist->setValue("Playlist/Shuffle",shuffle);
+		plist->sync();
+		delete plist;
+	}
+	emit dialogClosing();
+	event->accept();
+}
+
+void qmpPlistWindow::moveEvent(QMoveEvent *event)
+{
+	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+	{
+		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListW",event->pos());
+	}
+}
+
+void qmpPlistWindow::dropEvent(QDropEvent *event)
+{
+	QList<QUrl> l=event->mimeData()->urls();
+	QStringList sl;
+	for(int i=0;i<l.size();++i)
+		sl.push_back(l.at(i).toLocalFile());
+	insertItems(sl);
+}
+void qmpPlistWindow::dragEnterEvent(QDragEnterEvent *event)
+{
+	//if(event->mimeData()->hasFormat("application/x-midi"))
+	event->acceptProposedAction();
+}
+
+void qmpPlistWindow::emptyList()
+{
+	ui->lwFiles->clear();
+}
+void qmpPlistWindow::insertItem(QString i)
+{
+	ui->lwFiles->addItem(new QListWidgetItem(i));
+}
+void qmpPlistWindow::insertItems(QStringList il)
+{
+	ui->lwFiles->addItems(il);
+}
+
+void qmpPlistWindow::on_pbAdd_clicked()
+{
+	QStringList sl;
+	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+		sl=QFileDialog::getOpenFileNames(this,"Add File",qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/FileDialogPath","").toString(),"Midi files (*.mid *.midi)");
+	else
+		sl=QFileDialog::getOpenFileNames(this,"Add File","","Midi files (*.mid *.midi)");
+	if(sl.empty())return;
+	for(int i=0;i<sl.size();++i)
+	{
+		ui->lwFiles->addItem(new QListWidgetItem(sl.at(i)));
+	}
+	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
+		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/FileDialogPath",
+		QUrl(sl.at(0)).toString(QUrl::RemoveFilename));
+}
+
+void qmpPlistWindow::on_pbAddFolder_clicked()
+{
+	QDirIterator di(QFileDialog::getExistingDirectory(this,"Add Folder"));
+	while(di.hasNext())
+	{
+		QString c=di.next();
+		if((c.endsWith(".mid")||c.endsWith(".midi"))&&fluid_is_midifile(c.toStdString().c_str()))
+		ui->lwFiles->addItem(new QListWidgetItem(c));
+	}
+}
+
+void qmpPlistWindow::on_pbRemove_clicked()
+{
+	QList<QListWidgetItem*> sl=ui->lwFiles->selectedItems();
+	for(int i=0;i<sl.size();++i)
+	{
+		ui->lwFiles->removeItemWidget(sl.at(i));
+		delete sl.at(i);
+	}
+}
+
+void qmpPlistWindow::on_pbClear_clicked()
+{
+	while(ui->lwFiles->count()>0)
+	{
+		QListWidgetItem *d=ui->lwFiles->item(0);
+		ui->lwFiles->removeItemWidget(d);
+		delete d;
+	}
+}
+
+void qmpPlistWindow::on_pbRepeat_clicked()
+{
+	++repeat;repeat%=3;
+	switch(repeat)
+	{
+		case 0:
+			ui->pbRepeat->setIcon(QIcon(":/img/repeat-non.png"));
+			ui->pbRepeat->setText("Repeat Off");
+		break;
+		case 1:
+			ui->pbRepeat->setIcon(QIcon(":/img/repeat-one.png"));
+			ui->pbRepeat->setText("Repeat One");
+		break;
+		case 2:
+			ui->pbRepeat->setIcon(QIcon(":/img/repeat-all.png"));
+			ui->pbRepeat->setText("Repeat All");
+		break;
+	}
+}
+
+void qmpPlistWindow::on_pbShuffle_clicked()
+{
+	shuffle=1-shuffle;
+	switch(shuffle)
+	{
+		case 1:
+			ui->pbShuffle->setIcon(QIcon(":/img/shuffle.png"));
+			ui->pbShuffle->setText("Shuffle On");
+		break;
+		case 0:
+		default:
+			ui->pbShuffle->setIcon(QIcon(":/img/shuffle-off.png"));
+			ui->pbShuffle->setText("Shuffle Off");
+		break;
+	}
+}
+
+QString qmpPlistWindow::getFirstItem()
+{
+	if(ui->lwFiles->count()==0)return QString();
+	int id=0;
+	if(shuffle)id=rand()%ui->lwFiles->count();
+	ui->lwFiles->setCurrentRow(id);
+	return ui->lwFiles->item(id)->text();
+}
+QString qmpPlistWindow::getNextItem()
+{
+	if(ui->lwFiles->count()==0)return QString();
+	if(repeat==1)return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
+	int id=ui->lwFiles->currentRow();++id;id%=ui->lwFiles->count();
+	if(shuffle)id=rand()%ui->lwFiles->count();
+	ui->lwFiles->setCurrentRow(id);
+	return ui->lwFiles->item(id)->text();
+}
+QString qmpPlistWindow::getPrevItem()
+{
+	if(ui->lwFiles->count()==0)return QString();
+	if(repeat==1)return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
+	int id=ui->lwFiles->currentRow();--id;
+	id<0?id+=ui->lwFiles->count():0;
+	if(shuffle)id=rand()%ui->lwFiles->count();
+	ui->lwFiles->setCurrentRow(id);
+	return ui->lwFiles->item(id)->text();
+}
+QString qmpPlistWindow::getSelectedItem()
+{
+	if(ui->lwFiles->count()==0)return QString();
+	return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
+}
+int qmpPlistWindow::getRepeat(){return repeat;}
+
+void qmpPlistWindow::on_lwFiles_itemDoubleClicked()
+{
+	emit selectionChanging();
+}
+
+void qmpPlistWindow::on_pbSave_clicked()
+{
+	QSettings* plist=new QSettings(QFileDialog::getSaveFileName(this,"Save playlist",""),
+								   QSettings::IniFormat);
+	plist->setValue("Playlist/FileCount",ui->lwFiles->count());
+	for(int i=0;i<ui->lwFiles->count();++i)
+	plist->setValue("Playlist/File"+QString("%1").arg(i+1,5,10,QChar('0')),ui->lwFiles->item(i)->text());
+	plist->setValue("Playlist/Repeat",repeat);
+	plist->setValue("Playlist/Shuffle",shuffle);
+	plist->sync();
+	delete plist;
+}
+
+void qmpPlistWindow::on_pbLoad_clicked()
+{
+	QSettings* plist=new QSettings(QFileDialog::getOpenFileName(this,"Load playlist",""),
+								   QSettings::IniFormat);
+	int fc=plist->value("Playlist/FileCount",0).toInt();
+	if(!fc)return;
+	ui->lwFiles->clear();for(int i=1;i<=fc;++i)
+	ui->lwFiles->addItem(plist->value("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),"").toString());
+	repeat=plist->value("Playlist/Repeat",0).toInt();
+	shuffle=plist->value("Playlist/Shuffle",0).toInt();
+	switch(shuffle)
+	{
+		case 1:
+			ui->pbShuffle->setIcon(QIcon(":/img/shuffle.png"));
+			ui->pbShuffle->setText("Shuffle On");
+		break;
+		case 0:
+		default:
+			ui->pbShuffle->setIcon(QIcon(":/img/shuffle-off.png"));
+			ui->pbShuffle->setText("Shuffle Off");
+		break;
+	}
+	switch(repeat)
+	{
+		case 0:
+			ui->pbRepeat->setIcon(QIcon(":/img/repeat-non.png"));
+			ui->pbRepeat->setText("Repeat Off");
+		break;
+		case 1:
+			ui->pbRepeat->setIcon(QIcon(":/img/repeat-one.png"));
+			ui->pbRepeat->setText("Repeat One");
+		break;
+		case 2:
+			ui->pbRepeat->setIcon(QIcon(":/img/repeat-all.png"));
+			ui->pbRepeat->setText("Repeat All");
+		break;
+	}
+	delete plist;
+}
diff --git a/qmidiplayer-desktop/qmpplistwindow.hpp b/qmidiplayer-desktop/qmpplistwindow.hpp
new file mode 100644
index 0000000..6ceeb60
--- /dev/null
+++ b/qmidiplayer-desktop/qmpplistwindow.hpp
@@ -0,0 +1,57 @@
+#ifndef QMPPLISTWINDOW_H
+#define QMPPLISTWINDOW_H
+
+#include <QDialog>
+#include <QShowEvent>
+#include <QCloseEvent>
+#include <QMoveEvent>
+#include <QDropEvent>
+#include <QDragEnterEvent>
+#include <QListWidgetItem>
+
+namespace Ui {
+	class qmpPlistWindow;
+}
+
+class qmpPlistWindow : public QDialog
+{
+	Q_OBJECT
+
+	public:
+		explicit qmpPlistWindow(QWidget *parent=0);
+		~qmpPlistWindow();
+		void showEvent(QShowEvent *event);
+		void closeEvent(QCloseEvent *event);
+		void moveEvent(QMoveEvent *event);
+		void dropEvent(QDropEvent *event);
+		void dragEnterEvent(QDragEnterEvent *event);
+		int getRepeat();
+		QString getFirstItem();
+		QString getNextItem();
+		QString getPrevItem();
+		QString getSelectedItem();
+		void emptyList();
+		void insertItem(QString i);
+		void insertItems(QStringList il);
+	signals:
+		void dialogClosing();
+		void selectionChanging();
+
+	public slots:
+		void on_pbAdd_clicked();
+	private slots:
+		void on_pbAddFolder_clicked();
+		void on_pbRemove_clicked();
+		void on_pbClear_clicked();
+		void on_pbRepeat_clicked();
+		void on_pbShuffle_clicked();
+		void on_lwFiles_itemDoubleClicked();
+		void on_pbSave_clicked();
+		void on_pbLoad_clicked();
+
+	private:
+		Ui::qmpPlistWindow *ui;
+		int shuffle,repeat;//rep 0=off 1=one 2=all
+};
+
+#endif // QMPPLISTWINDOW_H
diff --git a/qmidiplayer-desktop/qmpplistwindow.ui b/qmidiplayer-desktop/qmpplistwindow.ui
new file mode 100644
index 0000000..99124df
--- /dev/null
+++ b/qmidiplayer-desktop/qmpplistwindow.ui
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpPlistWindow</class>
+ <widget class="QDialog" name="qmpPlistWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>530</width>
+    <height>321</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>530</width>
+    <height>321</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>530</width>
+    <height>321</height>
+   </size>
+  </property>
+  <property name="acceptDrops">
+   <bool>true</bool>
+  </property>
+  <property name="windowTitle">
+   <string>Playlist</string>
+  </property>
+  <widget class="QPushButton" name="pbAdd">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>280</y>
+     <width>121</width>
+     <height>36</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">text-align:left</string>
+   </property>
+   <property name="text">
+    <string>Add</string>
+   </property>
+   <property name="icon">
+    <iconset resource="resources.qrc">
+     <normaloff>:/img/add.png</normaloff>:/img/add.png</iconset>
+   </property>
+   <property name="iconSize">
+    <size>
+     <width>32</width>
+     <height>32</height>
+    </size>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pbAddFolder">
+   <property name="geometry">
+    <rect>
+     <x>140</x>
+     <y>280</y>
+     <width>121</width>
+     <height>36</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">text-align:left</string>
+   </property>
+   <property name="text">
+    <string>Add Folder</string>
+   </property>
+   <property name="icon">
+    <iconset resource="resources.qrc">
+     <normaloff>:/img/addfolder.png</normaloff>:/img/addfolder.png</iconset>
+   </property>
+   <property name="iconSize">
+    <size>
+     <width>32</width>
+     <height>32</height>
+    </size>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pbRepeat">
+   <property name="geometry">
+    <rect>
+     <x>270</x>
+     <y>240</y>
+     <width>121</width>
+     <height>36</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">text-align:left</string>
+   </property>
+   <property name="text">
+    <string>Repeat Off</string>
+   </property>
+   <property name="icon">
+    <iconset resource="resources.qrc">
+     <normaloff>:/img/repeat-non.png</normaloff>:/img/repeat-non.png</iconset>
+   </property>
+   <property name="iconSize">
+    <size>
+     <width>32</width>
+     <height>32</height>
+    </size>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pbShuffle">
+   <property name="geometry">
+    <rect>
+     <x>400</x>
+     <y>240</y>
+     <width>121</width>
+     <height>36</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">text-align:left</string>
+   </property>
+   <property name="text">
+    <string>Shuffle Off</string>
+   </property>
+   <property name="icon">
+    <iconset resource="resources.qrc">
+     <normaloff>:/img/shuffle-off.png</normaloff>:/img/shuffle-off.png</iconset>
+   </property>
+   <property name="iconSize">
+    <size>
+     <width>32</width>
+     <height>32</height>
+    </size>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pbSave">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>240</y>
+     <width>121</width>
+     <height>36</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">text-align:left</string>
+   </property>
+   <property name="text">
+    <string>Save</string>
+   </property>
+   <property name="icon">
+    <iconset resource="resources.qrc">
+     <normaloff>:/img/save.png</normaloff>:/img/save.png</iconset>
+   </property>
+   <property name="iconSize">
+    <size>
+     <width>32</width>
+     <height>32</height>
+    </size>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pbLoad">
+   <property name="geometry">
+    <rect>
+     <x>140</x>
+     <y>240</y>
+     <width>121</width>
+     <height>36</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">text-align:left</string>
+   </property>
+   <property name="text">
+    <string>Load</string>
+   </property>
+   <property name="icon">
+    <iconset resource="resources.qrc">
+     <normaloff>:/img/load.png</normaloff>:/img/load.png</iconset>
+   </property>
+   <property name="iconSize">
+    <size>
+     <width>32</width>
+     <height>32</height>
+    </size>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pbRemove">
+   <property name="geometry">
+    <rect>
+     <x>270</x>
+     <y>280</y>
+     <width>121</width>
+     <height>36</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">text-align:left</string>
+   </property>
+   <property name="text">
+    <string>Remove</string>
+   </property>
+   <property name="icon">
+    <iconset resource="resources.qrc">
+     <normaloff>:/img/remove.png</normaloff>:/img/remove.png</iconset>
+   </property>
+   <property name="iconSize">
+    <size>
+     <width>32</width>
+     <height>32</height>
+    </size>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pbClear">
+   <property name="geometry">
+    <rect>
+     <x>400</x>
+     <y>280</y>
+     <width>121</width>
+     <height>36</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">text-align:left</string>
+   </property>
+   <property name="text">
+    <string>Clear</string>
+   </property>
+   <property name="icon">
+    <iconset resource="resources.qrc">
+     <normaloff>:/img/clear.png</normaloff>:/img/clear.png</iconset>
+   </property>
+   <property name="iconSize">
+    <size>
+     <width>32</width>
+     <height>32</height>
+    </size>
+   </property>
+  </widget>
+  <widget class="QListWidget" name="lwFiles">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>10</y>
+     <width>511</width>
+     <height>221</height>
+    </rect>
+   </property>
+   <property name="acceptDrops">
+    <bool>false</bool>
+   </property>
+   <property name="dragEnabled">
+    <bool>true</bool>
+   </property>
+   <property name="dragDropMode">
+    <enum>QAbstractItemView::InternalMove</enum>
+   </property>
+  </widget>
+ </widget>
+ <resources>
+  <include location="resources.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmppresetselect.cpp b/qmidiplayer-desktop/qmppresetselect.cpp
new file mode 100644
index 0000000..be589c5
--- /dev/null
+++ b/qmidiplayer-desktop/qmppresetselect.cpp
@@ -0,0 +1,99 @@
+#include <cstdio>
+#include "qmppresetselect.hpp"
+#include "ui_qmppresetselect.h"
+#include "qmpmainwindow.hpp"
+
+qmpPresetSelector::qmpPresetSelector(QWidget *parent) :
+	QDialog(parent),
+	ui(new Ui::qmpPresetSelector)
+{
+	ui->setupUi(this);
+}
+
+qmpPresetSelector::~qmpPresetSelector()
+{
+	delete ui;
+}
+
+void qmpPresetSelector::showEvent(QShowEvent *e)
+{
+	memset(presets,0,sizeof(presets));
+	CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
+	if(!plyr->getSFCount())return e->ignore();
+	int sfc=plyr->getSFCount();
+	for(int i=sfc-1;i>=0;--i)
+	{
+		fluid_sfont_t* psf=plyr->getSFPtr(i);
+		fluid_preset_t preset;
+		psf->iteration_start(psf);
+		while(psf->iteration_next(psf,&preset))
+			strcpy(presets[preset.get_banknum(&preset)][preset.get_num(&preset)],preset.get_name(&preset));
+	}
+	ui->lwBankSelect->clear();
+	ui->lwPresetSelect->clear();
+	for(int i=0;i<=128;++i)
+	{
+		int b=0;
+		for(int j=0;j<128;++j)if(strlen(presets[i][j])){b=1;break;}
+		if(b)ui->lwBankSelect->addItem(QString::number(i));
+	}
+	e->accept();
+}
+void qmpPresetSelector::setupWindow(int chid)
+{
+	CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
+	if(!plyr->getSFCount())return;
+	ch=chid;int b=0,p=0,r;char name[64];
+	sprintf(name,"Preset Selection - Channel #%d",ch+1);
+	setWindowTitle(name);
+	plyr->getChannelPreset(chid,&b,&p,name);
+	for(int i=0;i<ui->lwBankSelect->count();++i)
+	{
+		sscanf(ui->lwBankSelect->item(i)->text().toStdString().c_str(),"%d",&r);
+		if(r==b){ui->lwBankSelect->setCurrentRow(i);break;}
+	}
+	r=0;
+	ui->lwPresetSelect->clear();
+	for(int i=0,cr=0;i<128;++i)
+	if(strlen(presets[b][i]))
+	{
+		sprintf(name,"%d %s",i,presets[b][i]);
+		if(i==p)r=cr;
+		ui->lwPresetSelect->addItem(name);
+		cr++;
+	}
+	ui->lwPresetSelect->setCurrentRow(r);
+}
+
+void qmpPresetSelector::on_pbCancel_clicked()
+{
+	close();
+}
+
+void qmpPresetSelector::on_pbOk_clicked()
+{
+	CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
+	int b,p;sscanf(ui->lwBankSelect->currentItem()->text().toStdString().c_str(),"%d",&b);
+	sscanf(ui->lwPresetSelect->currentItem()->text().toStdString().c_str(),"%d",&p);
+	plyr->setChannelPreset(ch,b,p);
+	close();
+}
+
+void qmpPresetSelector::on_lwPresetSelect_itemDoubleClicked()
+{
+	on_pbOk_clicked();
+}
+
+void qmpPresetSelector::on_lwBankSelect_currentRowChanged()
+{
+	ui->lwPresetSelect->clear();
+	if(!ui->lwBankSelect->currentItem())return;
+	char name[30];int b;
+	sscanf(ui->lwBankSelect->currentItem()->text().toStdString().c_str(),"%d",&b);
+	for(int i=0;i<128;++i)
+	if(strlen(presets[b][i]))
+	{
+		sprintf(name,"%d %s",i,presets[b][i]);
+		ui->lwPresetSelect->addItem(name);
+	}
+}
diff --git a/qmidiplayer-desktop/qmppresetselect.hpp b/qmidiplayer-desktop/qmppresetselect.hpp
new file mode 100644
index 0000000..54f5764
--- /dev/null
+++ b/qmidiplayer-desktop/qmppresetselect.hpp
@@ -0,0 +1,36 @@
+#ifndef QMPPRESETSELECT_H
+#define QMPPRESETSELECT_H
+
+#include <QDialog>
+#include <QShowEvent>
+
+namespace Ui {
+	class qmpPresetSelector;
+}
+
+class qmpPresetSelector:public QDialog
+{
+	Q_OBJECT
+
+	public:
+		explicit qmpPresetSelector(QWidget *parent = 0);
+		~qmpPresetSelector();
+		void showEvent(QShowEvent* e);
+		void setupWindow(int chid);
+
+	private slots:
+		void on_pbCancel_clicked();
+
+		void on_pbOk_clicked();
+
+		void on_lwBankSelect_currentRowChanged();
+
+		void on_lwPresetSelect_itemDoubleClicked();
+
+	private:
+		Ui::qmpPresetSelector *ui;
+		char presets[129][128][24];
+		int ch;
+};
+
+#endif // QMPPRESETSELECT_H
diff --git a/qmidiplayer-desktop/qmppresetselect.ui b/qmidiplayer-desktop/qmppresetselect.ui
new file mode 100644
index 0000000..f18600d
--- /dev/null
+++ b/qmidiplayer-desktop/qmppresetselect.ui
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpPresetSelector</class>
+ <widget class="QDialog" name="qmpPresetSelector">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>404</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>404</width>
+    <height>300</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>404</width>
+    <height>300</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Preset Selection</string>
+  </property>
+  <property name="modal">
+   <bool>true</bool>
+  </property>
+  <widget class="QListWidget" name="lwBankSelect">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>30</y>
+     <width>71</width>
+     <height>221</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QListWidget" name="lwPresetSelect">
+   <property name="geometry">
+    <rect>
+     <x>90</x>
+     <y>30</y>
+     <width>301</width>
+     <height>221</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="lbBnk">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>10</y>
+     <width>66</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Bank</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="lbPst">
+   <property name="geometry">
+    <rect>
+     <x>90</x>
+     <y>10</y>
+     <width>66</width>
+     <height>20</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Preset</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pbOk">
+   <property name="geometry">
+    <rect>
+     <x>300</x>
+     <y>260</y>
+     <width>97</width>
+     <height>36</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>OK</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="pbCancel">
+   <property name="geometry">
+    <rect>
+     <x>190</x>
+     <y>260</y>
+     <width>97</width>
+     <height>36</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Cancel</string>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/qmidiplayer-desktop/qmpsettingswindow.cpp b/qmidiplayer-desktop/qmpsettingswindow.cpp
new file mode 100644
index 0000000..c2e31a2
--- /dev/null
+++ b/qmidiplayer-desktop/qmpsettingswindow.cpp
@@ -0,0 +1,289 @@
+#include <QFileDialog>
+#include <QDir>
+#include "qmpsettingswindow.hpp"
+#include "ui_qmpsettingswindow.h"
+#include "qmpmainwindow.hpp"
+
+QSettings *qmpSettingsWindow::settings=NULL;
+
+void qmpFluidForEachOpt(void* data,char* /*name*/,char* option)
+{
+	QComboBox *pcb=(QComboBox*)data;
+	pcb->addItem(option);
+}
+
+qmpSettingsWindow::qmpSettingsWindow(QWidget *parent) :
+	QDialog(parent),
+	ui(new Ui::qmpSettingsWindow)
+{
+	ui->setupUi(this);
+	connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed()));
+	settings=new QSettings(QDir::homePath()+QString("/.config/qmprc"),QSettings::IniFormat);
+	settingsInit();
+}
+
+qmpSettingsWindow::~qmpSettingsWindow()
+{
+	delete settings;
+	delete ui;
+}
+
+void qmpSettingsWindow::closeEvent(QCloseEvent *event)
+{
+	setVisible(false);
+	settings->sync();
+	emit dialogClosing();
+	event->accept();
+}
+
+QListWidget* qmpSettingsWindow::getSFWidget(){return ui->lwSoundfont;}
+
+void qmpSettingsWindow::on_buttonBox_accepted()
+{
+	settingsUpdate();
+	emit dialogClosing();
+}
+
+void qmpSettingsWindow::on_buttonBox_rejected()
+{
+	settingsInit();
+	emit dialogClosing();
+}
+
+void qmpSettingsWindow::settingsInit()
+{
+	fluid_settings_t *fsettings=new_fluid_settings();
+
+	settings->setValue("Midi/DefaultOutput",settings->value("Midi/DefaultOutput","Internal FluidSynth"));
+	//this item is still a stub...
+
+	settings->setValue("Midi/DisableMapping",settings->value("Midi/DisableMapping",0));
+	ui->cbDisableMapping->setChecked(settings->value("Midi/DisableMapping",0).toInt());
+
+	settings->setValue("Midi/SendSysEx",settings->value("Midi/SendSysEx",1));
+	ui->cbSendSysx->setChecked(settings->value("Midi/SendSysEx",1).toInt());
+
+	settings->setValue("Midi/WaitVoice",settings->value("Midi/WaitVoice",1));
+	ui->cbWaitVoice->setChecked(settings->value("Midi/WaitVoice",1).toInt());
+
+	int selected=-1;
+	for(int i=0;i<ui->cbEncoding->count();++i)
+	if(ui->cbEncoding->itemText(i)==settings->value("Midi/TextEncoding","Unicode").toString())
+	{selected=i;break;}
+	if(~selected)ui->cbEncoding->setCurrentIndex(selected);
+	settings->setValue("Midi/TextEncoding",ui->cbEncoding->currentText());
+
+	fluid_settings_foreach_option(fsettings,"audio.driver",(void*)ui->cbAudioDrv,qmpFluidForEachOpt);
+	selected=-1;
+	for(int i=0;i<ui->cbAudioDrv->count();++i)
+	if(ui->cbAudioDrv->itemText(i)==settings->value("Audio/Driver","pulseaudio").toString())
+	{selected=i;break;}
+	if(~selected)ui->cbAudioDrv->setCurrentIndex(selected);
+	settings->setValue("Audio/Driver",ui->cbAudioDrv->currentText());
+
+#ifdef _WIN32
+#define DefBufSize 8192
+#else
+#define DefBufSize 128
+#endif
+	selected=-1;
+	for(int i=0;i<ui->cbBufSize->count();++i)
+	if(ui->cbBufSize->itemText(i).toInt()==settings->value("Audio/BufSize",DefBufSize).toInt())
+	{selected=i;break;}
+	if(~selected)ui->cbBufSize->setCurrentIndex(selected);
+	else if(settings->value("Audio/BufSize",DefBufSize).toInt()>=64&&settings->value("Audio/BufSize",DefBufSize).toInt()<=8192)
+		ui->cbBufSize->setCurrentText(settings->value("Audio/BufSize",DefBufSize).toString());
+	else ui->cbBufSize->setCurrentText(QString::number(DefBufSize));
+	settings->setValue("Audio/BufSize",ui->cbBufSize->currentText().toInt());
+#undef DefBufSize
+
+	selected=-1;
+	for(int i=0;i<ui->cbBufCnt->count();++i)
+	if(ui->cbBufCnt->itemText(i).toInt()==settings->value("Audio/BufCnt",2).toInt())
+	{selected=i;break;}
+	if(~selected)ui->cbBufCnt->setCurrentIndex(selected);
+	else if(settings->value("Audio/BufCnt",2).toInt()>=2&&settings->value("Audio/BufCnt",2).toInt()<=64)
+		ui->cbBufCnt->setCurrentText(settings->value("Audio/BufCnt",2).toString());
+	else ui->cbBufCnt->setCurrentText("2");
+	settings->setValue("Audio/BufCnt",ui->cbBufCnt->currentText().toInt());
+
+	selected=-1;
+	for(int i=0;i<ui->cbFormat->count();++i)
+	if(ui->cbFormat->itemText(i)==settings->value("Audio/Format","16bits").toString())
+	{selected=i;break;}
+	if(~selected)ui->cbFormat->setCurrentIndex(selected);
+	settings->setValue("Audio/Format",ui->cbFormat->currentText());
+
+	selected=-1;
+	for(int i=0;i<ui->cbFrequency->count();++i)
+	if(ui->cbFormat->itemText(i).toInt()==settings->value("Audio/Frequency",48000).toInt())
+	{selected=i;break;}
+	if(~selected)ui->cbFrequency->setCurrentIndex(selected);
+	settings->setValue("Audio/Frequency",ui->cbFrequency->currentText());
+
+	ui->sbPolyphony->setValue(settings->value("Audio/Polyphony",2048).toInt());
+	if(ui->sbPolyphony->value()<1||ui->sbPolyphony->value()>65535)ui->sbPolyphony->setValue(2048);
+	settings->setValue("Audio/Polyphony",ui->sbPolyphony->value());
+
+	ui->sbCPUCores->setValue(settings->value("Audio/Threads",1).toInt());
+	if(ui->sbCPUCores->value()<1||ui->sbCPUCores->value()>256)ui->sbCPUCores->setValue(1);
+	settings->setValue("Audio/Threads",ui->sbCPUCores->value());
+
+	settings->setValue("Audio/AutoBS",settings->value("Audio/AutoBS",1));
+	ui->cbAutoBS->setChecked(settings->value("Audio/AutoBS",1).toInt());
+	ui->lbBSMode->setText(ui->cbAutoBS->isChecked()?"Fallback bank select mode":"Bank select mode");
+
+	selected=-1;
+	for(int i=0;i<ui->cbBSMode->count();++i)
+	if(ui->cbBSMode->itemText(i)==settings->value("Audio/BankSelect","GS").toString())
+	{selected=i;break;}
+	if(~selected)ui->cbBSMode->setCurrentIndex(selected);
+	settings->setValue("Audio/BankSelect",ui->cbBSMode->currentText());
+	settings->setValue("Audio/Gain",settings->value("Audio/Gain",50));
+
+	int sfc=settings->value("SoundFonts/SFCount",0).toInt();
+	ui->lwSoundfont->clear();for(int i=1;i<=sfc;++i)
+	ui->lwSoundfont->addItem(settings->value("SoundFonts/SF"+QString::number(i),"").toString());
+	settings->setValue("SoundFonts/SFCount",sfc);
+
+	settings->setValue("Behavior/RestorePlaylist",settings->value("Behavior/RestorePlaylist",0));
+	ui->cbRestorePlaylist->setChecked(settings->value("Behavior/RestorePlaylist",0).toInt());
+
+	settings->setValue("Behavior/LoadFolder",settings->value("Behavior/LoadFolder",0));
+	ui->cbLoadFolder->setChecked(settings->value("Behavior/LoadFolder",0).toInt());
+
+	settings->setValue("Behavior/DialogStatus",settings->value("Behavior/DialogStatus",1));
+	ui->cbDialogStatus->setChecked(settings->value("Behavior/DialogStatus",1).toInt());
+
+	settings->setValue("Behavior/SaveEfxParam",settings->value("Behavior/SaveEfxParam",1));
+	ui->cbSaveEfxParam->setChecked(settings->value("Behavior/SaveEfxParam",1).toInt());
+
+	settings->setValue("Behavior/SingleInstance",settings->value("Behavior/SingleInstance",0));
+	ui->cbPersistentfs->setChecked(settings->value("Behavior/SingleInstance",0).toInt());
+
+	settings->sync();
+	delete_fluid_settings(fsettings);
+}
+
+void qmpSettingsWindow::settingsUpdate()
+{
+	settings->setValue("Midi/DefaultOutput",settings->value("Midi/DefaultOutput","Internal FluidSynth"));
+	//this item is still a stub...
+
+	settings->setValue("Midi/DisableMapping",ui->cbDisableMapping->isChecked()?1:0);
+
+	settings->setValue("Midi/SendSysEx",ui->cbSendSysx->isChecked()?1:0);
+
+	settings->setValue("Midi/WaitVoice",ui->cbWaitVoice->isChecked()?1:0);
+
+	settings->setValue("Midi/TextEncoding",ui->cbEncoding->currentText());
+
+	settings->setValue("Audio/Driver",ui->cbAudioDrv->currentText());
+
+	settings->setValue("Audio/BufSize",ui->cbBufSize->currentText().toInt());
+
+	settings->setValue("Audio/BufCnt",ui->cbBufCnt->currentText().toInt());
+
+	settings->setValue("Audio/Format",ui->cbFormat->currentText());
+
+	settings->setValue("Audio/Frequency",ui->cbFrequency->currentText());
+
+	settings->setValue("Audio/Polyphony",ui->sbPolyphony->value());
+
+	settings->setValue("Audio/Threads",ui->sbCPUCores->value());
+
+	settings->setValue("Audio/AutoBS",ui->cbAutoBS->isChecked()?1:0);
+
+	settings->setValue("Audio/BankSelect",ui->cbBSMode->currentText());
+
+	settings->setValue("SoundFonts/SFCount",ui->lwSoundfont->count());
+	for(int i=0;i<ui->lwSoundfont->count();++i)
+	settings->setValue("SoundFonts/SF"+QString::number(i+1),ui->lwSoundfont->item(i)->text());
+
+	settings->setValue("Behavior/RestorePlaylist",ui->cbRestorePlaylist->isChecked()?1:0);
+
+	settings->setValue("Behavior/LoadFolder",ui->cbLoadFolder->isChecked()?1:0);
+
+	settings->setValue("Behavior/DialogStatus",ui->cbDialogStatus->isChecked()?1:0);
+	if(!ui->cbDialogStatus->isChecked())
+	{
+		settings->remove("DialogStatus/MainW");
+		settings->remove("DialogStatus/PListW");
+		settings->remove("DialogStatus/PListWShown");
+		settings->remove("DialogStatus/ChnlW");
+		settings->remove("DialogStatus/ChnlWShown");
+		settings->remove("DialogStatus/EfxW");
+		settings->remove("DialogStatus/EfxWShown");
+		settings->remove("DialogStatus/FileDialogPath");
+	}
+
+	settings->setValue("Behavior/SaveEfxParam",ui->cbSaveEfxParam->isChecked()?1:0);
+	if(!ui->cbSaveEfxParam->isChecked())
+	{
+		settings->remove("Effects/ChorusEnabled");
+		settings->remove("Effects/ReverbEnabled");
+		settings->remove("Effects/ReverbRoom");
+		settings->remove("Effects/ReverbDamp");
+		settings->remove("Effects/ReverbWidth");
+		settings->remove("Effects/ReverbLevel");
+
+		settings->remove("Effects/ChorusFeedbk");
+		settings->remove("Effects/ChorusLevel");
+		settings->remove("Effects/ChorusRate");
+		settings->remove("Effects/ChorusDepth");
+		settings->remove("Effects/ChorusType");
+	}
+
+	settings->setValue("Behavior/SingleInstance",ui->cbPersistentfs->isChecked()?1:0);
+	settings->sync();
+}
+
+void qmpSettingsWindow::on_cbBufSize_currentTextChanged(const QString &s)
+{
+	if(s.toInt()<64||s.toInt()>8192)ui->cbBufSize->setCurrentIndex(1);
+}
+
+void qmpSettingsWindow::on_cbBufCnt_currentTextChanged(const QString &s)
+{
+	if(s.toInt()<2||s.toInt()>64)ui->cbBufCnt->setCurrentIndex(1);
+}
+
+void qmpSettingsWindow::on_pbAdd_clicked()
+{
+	QStringList sl=QFileDialog::getOpenFileNames(this,"Add File","","SoundFont files (*.sf2)");
+	for(int i=0;i<sl.size();++i)
+	{
+		ui->lwSoundfont->addItem(new QListWidgetItem(sl.at(i)));
+	}
+}
+
+void qmpSettingsWindow::on_pbRemove_clicked()
+{
+	QList<QListWidgetItem*> sl=ui->lwSoundfont->selectedItems();
+	for(int i=0;i<sl.size();++i)
+	{
+		ui->lwSoundfont->removeItemWidget(sl.at(i));
+		delete sl.at(i);
+	}
+}
+
+void qmpSettingsWindow::on_pbUp_clicked()
+{
+	int cid=ui->lwSoundfont->currentRow();
+	QListWidgetItem *ci=ui->lwSoundfont->takeItem(cid);
+	ui->lwSoundfont->insertItem(cid-1,ci);
+	ui->lwSoundfont->setCurrentRow(cid-1);
+}
+
+void qmpSettingsWindow::on_pbDown_clicked()
+{
+	int cid=ui->lwSoundfont->currentRow();
+	QListWidgetItem *ci=ui->lwSoundfont->takeItem(cid);
+	ui->lwSoundfont->insertItem(cid+1,ci);
+	ui->lwSoundfont->setCurrentRow(cid+1);
+}
+
+void qmpSettingsWindow::on_cbAutoBS_stateChanged()
+{
+	ui->lbBSMode->setText(ui->cbAutoBS->isChecked()?"Fallback bank select mode":"Bank select mode");
+}
diff --git a/qmidiplayer-desktop/qmpsettingswindow.hpp b/qmidiplayer-desktop/qmpsettingswindow.hpp
new file mode 100644
index 0000000..c506de4
--- /dev/null
+++ b/qmidiplayer-desktop/qmpsettingswindow.hpp
@@ -0,0 +1,47 @@
+#ifndef QMPSETTINGSWINDOW_H
+#define QMPSETTINGSWINDOW_H
+
+#include <QDialog>
+#include <QCloseEvent>
+#include <QSettings>
+#include <QListWidget>
+
+namespace Ui {
+	class qmpSettingsWindow;
+}
+
+class qmpSettingsWindow:public QDialog
+{
+	Q_OBJECT
+
+	public:
+		explicit qmpSettingsWindow(QWidget *parent=0);
+		~qmpSettingsWindow();
+		void closeEvent(QCloseEvent *event);
+		void settingsInit();
+		QListWidget* getSFWidget();
+	signals:
+		void dialogClosing();
+
+	private slots:
+		void on_buttonBox_accepted();
+		void on_buttonBox_rejected();
+
+		void on_cbBufSize_currentTextChanged(const QString &s);
+		void on_cbBufCnt_currentTextChanged(const QString &s);
+
+		void on_pbAdd_clicked();
+		void on_pbRemove_clicked();
+		void on_pbUp_clicked();
+		void on_pbDown_clicked();
+
+		void on_cbAutoBS_stateChanged();
+
+		private:
+		Ui::qmpSettingsWindow *ui;
+		void settingsUpdate();
+		static QSettings *settings;
+	public: static QSettings* getSettingsIntf(){return settings;}
+};
+
+#endif // QMPSETTINGSWINDOW_H
diff --git a/qmidiplayer-desktop/qmpsettingswindow.ui b/qmidiplayer-desktop/qmpsettingswindow.ui
new file mode 100644
index 0000000..330afa2
--- /dev/null
+++ b/qmidiplayer-desktop/qmpsettingswindow.ui
@@ -0,0 +1,761 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>qmpSettingsWindow</class>
+ <widget class="QDialog" name="qmpSettingsWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>494</width>
+    <height>445</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>494</width>
+    <height>445</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Settings</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTabWidget" name="tabWidget">
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="tab">
+      <attribute name="title">
+       <string>Midi</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_4">
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_6">
+         <item>
+          <widget class="QLabel" name="lbOutputDevice">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="text">
+            <string>Default Output Device</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="cbOutputDevice">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <item>
+            <property name="text">
+             <string>Internal FluidSynth</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="cbDisableMapping">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text">
+          <string>Disable Midi Mapping</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="cbSendSysx">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text">
+          <string>Send SysEx</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="cbWaitVoice">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text">
+          <string>Wait for remaining voices before stopping</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_7">
+         <item>
+          <widget class="QLabel" name="lbEncoding">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="text">
+            <string>Text Encoding</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="cbEncoding">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <item>
+            <property name="text">
+             <string>Unicode</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>Big5</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>Big5-HKSCS</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>CP949</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>EUC-JP</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>EUC-KR</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>GB18030</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>KOI8-R</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>KOI8-U</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>Macintosh</string>
+            </property>
+           </item>
+           <item>
+            <property name="text">
+             <string>Shift-JIS</string>
+            </property>
+           </item>
+          </widget>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab_2">
+      <attribute name="title">
+       <string>Synth</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_2">
+       <item row="2" column="0">
+        <widget class="QLabel" name="lbBufCnt">
+         <property name="text">
+          <string>Audio Buffer Count</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="0">
+        <widget class="QLabel" name="lbBufSize">
+         <property name="text">
+          <string>Audio Buffer Size</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1">
+        <widget class="QComboBox" name="cbBufSize">
+         <property name="editable">
+          <bool>true</bool>
+         </property>
+         <property name="currentIndex">
+          <number>1</number>
+         </property>
+         <item>
+          <property name="text">
+           <string>64</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>128</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>256</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>512</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>1024</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>2048</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>4096</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>8192</string>
+          </property>
+         </item>
+        </widget>
+       </item>
+       <item row="4" column="0">
+        <widget class="QLabel" name="lbFrequency">
+         <property name="text">
+          <string>Audio Frequency</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="1">
+        <widget class="QComboBox" name="cbBufCnt">
+         <property name="editable">
+          <bool>true</bool>
+         </property>
+         <item>
+          <property name="text">
+           <string>2</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>4</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>8</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>16</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>32</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>64</string>
+          </property>
+         </item>
+        </widget>
+       </item>
+       <item row="0" column="0">
+        <widget class="QLabel" name="lbAudioDrv">
+         <property name="text">
+          <string>Audio Driver</string>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="1">
+        <widget class="QComboBox" name="cbFormat">
+         <item>
+          <property name="text">
+           <string>16bits</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>float</string>
+          </property>
+         </item>
+        </widget>
+       </item>
+       <item row="0" column="1">
+        <widget class="QComboBox" name="cbAudioDrv"/>
+       </item>
+       <item row="4" column="1">
+        <widget class="QComboBox" name="cbFrequency">
+         <property name="currentIndex">
+          <number>2</number>
+         </property>
+         <item>
+          <property name="text">
+           <string>22050</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>44100</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>48000</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>96000</string>
+          </property>
+         </item>
+        </widget>
+       </item>
+       <item row="3" column="0">
+        <widget class="QLabel" name="lbFormat">
+         <property name="text">
+          <string>Audio Format</string>
+         </property>
+        </widget>
+       </item>
+       <item row="5" column="1">
+        <widget class="QSpinBox" name="sbPolyphony">
+         <property name="minimum">
+          <number>1</number>
+         </property>
+         <property name="maximum">
+          <number>65535</number>
+         </property>
+         <property name="value">
+          <number>2048</number>
+         </property>
+        </widget>
+       </item>
+       <item row="5" column="0">
+        <widget class="QLabel" name="lbPolyphony">
+         <property name="text">
+          <string>Max Polyphony</string>
+         </property>
+        </widget>
+       </item>
+       <item row="7" column="0">
+        <widget class="QCheckBox" name="cbAutoBS">
+         <property name="text">
+          <string>Auto bank select mode</string>
+         </property>
+        </widget>
+       </item>
+       <item row="8" column="0">
+        <widget class="QLabel" name="lbBSMode">
+         <property name="text">
+          <string>Bank select mode</string>
+         </property>
+        </widget>
+       </item>
+       <item row="8" column="1">
+        <widget class="QComboBox" name="cbBSMode">
+         <property name="currentIndex">
+          <number>1</number>
+         </property>
+         <item>
+          <property name="text">
+           <string>Ignored</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>CC#0</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>CC#32</string>
+          </property>
+         </item>
+         <item>
+          <property name="text">
+           <string>CC#0*128+CC#32</string>
+          </property>
+         </item>
+        </widget>
+       </item>
+       <item row="6" column="0">
+        <widget class="QLabel" name="lbCPUCores">
+         <property name="text">
+          <string>CPU Cores</string>
+         </property>
+        </widget>
+       </item>
+       <item row="6" column="1">
+        <widget class="QSpinBox" name="sbCPUCores">
+         <property name="minimum">
+          <number>1</number>
+         </property>
+         <property name="maximum">
+          <number>256</number>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab_3">
+      <attribute name="title">
+       <string>Soundfonts</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_2">
+       <item>
+        <widget class="QListWidget" name="lwSoundfont">
+         <property name="dragDropMode">
+          <enum>QAbstractItemView::InternalMove</enum>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout">
+         <item>
+          <widget class="QPushButton" name="pbAdd">
+           <property name="text">
+            <string/>
+           </property>
+           <property name="icon">
+            <iconset resource="resources.qrc">
+             <normaloff>:/img/add.png</normaloff>:/img/add.png</iconset>
+           </property>
+           <property name="iconSize">
+            <size>
+             <width>24</width>
+             <height>24</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="pbRemove">
+           <property name="text">
+            <string/>
+           </property>
+           <property name="icon">
+            <iconset resource="resources.qrc">
+             <normaloff>:/img/remove.png</normaloff>:/img/remove.png</iconset>
+           </property>
+           <property name="iconSize">
+            <size>
+             <width>24</width>
+             <height>24</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="pbUp">
+           <property name="text">
+            <string/>
+           </property>
+           <property name="icon">
+            <iconset resource="resources.qrc">
+             <normaloff>:/img/up.png</normaloff>:/img/up.png</iconset>
+           </property>
+           <property name="iconSize">
+            <size>
+             <width>24</width>
+             <height>24</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="pbDown">
+           <property name="text">
+            <string/>
+           </property>
+           <property name="icon">
+            <iconset resource="resources.qrc">
+             <normaloff>:/img/down.png</normaloff>:/img/down.png</iconset>
+           </property>
+           <property name="iconSize">
+            <size>
+             <width>24</width>
+             <height>24</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab_4">
+      <attribute name="title">
+       <string>Behavior</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_3">
+       <item>
+        <widget class="QCheckBox" name="cbRestorePlaylist">
+         <property name="text">
+          <string>Restore last playlist on startup</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="cbLoadFolder">
+         <property name="text">
+          <string>Load files in the same folder</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="cbDialogStatus">
+         <property name="text">
+          <string>Save dialog status</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="cbSaveEfxParam">
+         <property name="text">
+          <string>Save parameters in effects window</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="cbPersistentfs">
+         <property name="text">
+          <string>Persistent fluidsynth instance</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_2">
+         <item>
+          <widget class="QLabel" name="lbVisualMode">
+           <property name="text">
+            <string>Visualization Mode</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="cbVisualMode"/>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_3">
+         <item>
+          <widget class="QLabel" name="lbViewDist">
+           <property name="text">
+            <string>View distance</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeType">
+            <enum>QSizePolicy::Expanding</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>50</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QSlider" name="hsViewDist">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+             <horstretch>60</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QSpinBox" name="sbViewDist"/>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_4">
+         <item>
+          <widget class="QLabel" name="lbNoteStretch">
+           <property name="text">
+            <string>Note stretch</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_2">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeType">
+            <enum>QSizePolicy::Expanding</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>60</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QSlider" name="hsNoteStretch">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+             <horstretch>60</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QSpinBox" name="sbNoteStretch"/>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_5">
+         <item>
+          <widget class="QLabel" name="lbFog">
+           <property name="text">
+            <string>Fog Start</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_3">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeType">
+            <enum>QSizePolicy::Expanding</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>82</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item>
+          <widget class="QSlider" name="hsFog">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+             <horstretch>60</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QSpinBox" name="sbFog"/>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources>
+  <include location="resources.qrc"/>
+ </resources>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>qmpSettingsWindow</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>qmpSettingsWindow</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/qmidiplayer-desktop/resources.qrc b/qmidiplayer-desktop/resources.qrc
new file mode 100644
index 0000000..351d2fa
--- /dev/null
+++ b/qmidiplayer-desktop/resources.qrc
@@ -0,0 +1,36 @@
+<RCC>
+    <qresource prefix="/">
+        <file>../img/add.png</file>
+        <file>../img/list.png</file>
+        <file>../img/addfolder.png</file>
+        <file>../img/channel.png</file>
+        <file>../img/prev.png</file>
+        <file>../img/qmidiplyr.png</file>
+        <file>../img/remove.png</file>
+        <file>../img/clear.png</file>
+        <file>../img/down.png</file>
+        <file>../img/effects.png</file>
+        <file>../img/repeat-all.png</file>
+        <file>../img/repeat-base.png</file>
+        <file>../img/repeat-non.png</file>
+        <file>../img/load.png</file>
+        <file>../img/next.png</file>
+        <file>../img/repeat-one.png</file>
+        <file>../img/save.png</file>
+        <file>../img/settings.png</file>
+        <file>../img/pause.png</file>
+        <file>../img/play.png</file>
+        <file>../img/shuffle-off.png</file>
+        <file>../img/shuffle.png</file>
+        <file>../img/stop.png</file>
+        <file>../img/up.png</file>
+        <file>../img/visualization.png</file>
+        <file>../img/mainw.png</file>
+        <file>../img/chanw.png</file>
+        <file>../doc/index.html</file>
+        <file>../doc/version.html</file>
+        <file>../doc/license.html</file>
+        <file>../doc/mainwindow.html</file>
+        <file>../doc/channeldialog.html</file>
+    </qresource>
+</RCC>
diff --git a/qmidiplayer-lite/deployment.pri b/qmidiplayer-lite/deployment.pri
new file mode 100644
index 0000000..57bdd3a
--- /dev/null
+++ b/qmidiplayer-lite/deployment.pri
@@ -0,0 +1,13 @@
+unix:!android {
+    isEmpty(target.path) {
+        qnx {
+            target.path = /tmp/$${TARGET}/bin
+        } else {
+            target.path = /usr/bin
+        }
+        export(target.path)
+    }
+    INSTALLS += target
+}
+
+export(INSTALLS)
diff --git a/qmidiplayer-lite/main.cpp b/qmidiplayer-lite/main.cpp
new file mode 100644
index 0000000..1a87b33
--- /dev/null
+++ b/qmidiplayer-lite/main.cpp
@@ -0,0 +1,15 @@
+#include <QApplication>
+#include <QtQml>
+#include <QQmlApplicationEngine>
+#include "qmpcorewrapper.hpp"
+
+int main(int argc, char *argv[])
+{
+	QApplication app(argc, argv);
+	qmlRegisterType<CQMPCoreWrapper>("org.chrisoft.qmpcore",1,0,"CQMPCoreWrapper");
+
+	QQmlApplicationEngine engine;
+	engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+
+	return app.exec();
+}
diff --git a/qmidiplayer-lite/main.qml b/qmidiplayer-lite/main.qml
new file mode 100644
index 0000000..0ec0975
--- /dev/null
+++ b/qmidiplayer-lite/main.qml
@@ -0,0 +1,144 @@
+import QtQuick 2.3
+import QtQuick.Window 2.2
+import QtQuick.Controls 1.0
+import QtQuick.Dialogs 1.0
+import org.chrisoft.qmpcore 1.0
+
+Window {
+	id: window1
+	width: 420
+	height: 240
+	title: "QMidiPlayer Lite"
+	visible: true
+	property bool playing
+	playing: false
+
+	MouseArea {
+		id: mouseArea1
+		anchors.rightMargin: 0
+		anchors.bottomMargin: 0
+		anchors.leftMargin: 0
+		anchors.topMargin: 0
+		anchors.fill: parent
+		onClicked: {
+			//Qt.quit();
+		}
+
+		Button {
+			id: button2
+			x: 170
+			text: qsTr("Play")
+			anchors.top: parent.top
+			anchors.topMargin: 172
+			anchors.horizontalCenter: parent.horizontalCenter
+			onClicked: {
+				if(!playing)
+				{
+					qmpcore.loadFile(fileName.text);
+					qmpcore.initFluidSynth();
+					qmpcore.playFile();
+					playing=true;
+					uiTimer.start();
+					text="Stop";
+				}
+				else
+				{
+					qmpcore.stop();
+					playing=false;
+					text="Play";
+					hsTimer.value=0;uiTimer.stop();
+				}
+			}
+		}
+
+		Slider {
+			id: hsTimer
+			y: 210
+			height: 22
+			anchors.right: parent.right
+			anchors.rightMargin: 8
+			anchors.left: parent.left
+			anchors.leftMargin: 8
+			anchors.bottom: parent.bottom
+			anchors.bottomMargin: 8
+			tickmarksEnabled: false
+			stepSize: 1
+			maximumValue: 100
+			property bool autovalchange: false
+			onValueChanged: {
+				if(autovalchange||pressed)return;
+				if(playing){qmpcore.setTCeptr(value);qmpcore.panic();}
+			}
+			onPressedChanged: {
+				if(!pressed)
+				{
+					/*if(playing)
+					{
+						if(ui->hsTimer->value()==100){on_pbNext_clicked();return;}
+						player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value());
+						player->playerPanic();
+						offset=ui->hsTimer->value()/100.*player->getFtime();
+						st=std::chrono::steady_clock::now();
+					}
+					else
+					{
+						player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value());
+						offset=ui->hsTimer->value()/100.*player->getFtime();
+						char ts[100];
+						sprintf(ts,"%02d:%02d",(int)(offset)/60,(int)(offset)%60);
+						ui->lbCurTime->setText(ts);
+					}*/
+					if(playing){qmpcore.setTCeptr(value);qmpcore.panic();}
+				}
+			}
+		}
+	}
+
+	CQMPCoreWrapper {
+		id: qmpcore
+	}
+	Timer {
+		id: uiTimer
+		interval: 100
+		running: false
+		repeat: true
+		onTriggered: {
+			if(!hsTimer.pressed)
+			{
+				hsTimer.autovalchange=true;
+				hsTimer.value=qmpcore.getProgress();
+				hsTimer.autovalchange=false;
+			}
+		}
+	}
+
+	Text {
+		id: fileName
+		text: qsTr("...")
+		anchors.centerIn: parent
+	}
+
+	Button {
+		id: button1
+		x: 170
+		width: 80
+		height: 27
+		text: qsTr("Open")
+		anchors.top: parent.top
+		anchors.topMargin: 142
+		anchors.horizontalCenter: parent.horizontalCenter
+		onClicked: {
+			fileDialog.open();
+		}
+	}
+
+	FileDialog {
+		id: fileDialog
+		title: qsTr("Select midi file")
+		nameFilters: ["MIDI Files (*.mid *.midi)"]
+		onAccepted: {
+			fileName.text=fileUrl;
+		}
+	}
+}
+
diff --git a/qmidiplayer-lite/qmidiplayer-lite.pro b/qmidiplayer-lite/qmidiplayer-lite.pro
new file mode 100644
index 0000000..9fb8712
--- /dev/null
+++ b/qmidiplayer-lite/qmidiplayer-lite.pro
@@ -0,0 +1,24 @@
+TEMPLATE = app
+
+QT += qml quick
+unix:QT += widgets
+win32:QT += widgets
+CONFIG += c++11
+
+SOURCES += main.cpp \
+	../core/qmpmidiplay.cpp \
+	../core/qmpmidiread.cpp
+
+RESOURCES += qml.qrc
+
+# Additional import path used to resolve QML modules in Qt Creator's code model
+QML_IMPORT_PATH =
+
+# Default rules for deployment.
+include(deployment.pri)
+
+HEADERS += \
+	../core/qmpmidiplay.hpp \
+	qmpcorewrapper.hpp
+
+LIBS += -lfluidsynth
diff --git a/qmidiplayer-lite/qml.qrc b/qmidiplayer-lite/qml.qrc
new file mode 100644
index 0000000..5f6483a
--- /dev/null
+++ b/qmidiplayer-lite/qml.qrc
@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/">
+        <file>main.qml</file>
+    </qresource>
+</RCC>
diff --git a/qmidiplayer-lite/qmpcorewrapper.hpp b/qmidiplayer-lite/qmpcorewrapper.hpp
new file mode 100644
index 0000000..ed024df
--- /dev/null
+++ b/qmidiplayer-lite/qmpcorewrapper.hpp
@@ -0,0 +1,58 @@
+#ifndef QMPCOREWRAPPER_H
+#define QMPCOREWRAPPER_H
+#include <QObject>
+#include <QUrl>
+#include <thread>
+#include <fluidsynth.h>
+#include "../core/qmpmidiplay.hpp"
+class CQMPCoreWrapper:public QObject
+{
+	Q_OBJECT
+private:
+	CMidiPlayer *mp;
+	std::thread *playerTh;
+	int curprog;
+public:
+	explicit CQMPCoreWrapper(QObject* parent=0):QObject(parent)
+	{
+		mp=new CMidiPlayer(false);
+	}
+	~CQMPCoreWrapper(){delete mp;}
+	Q_INVOKABLE void initFluidSynth()
+	{
+		fluid_settings_t *fsettings=mp->getFluidSettings();
+		fluid_settings_setstr(fsettings,"audio.driver","pulseaudio");
+		mp->fluidInitialize();
+		mp->pushSoundFont("/media/Files/FluidR3_Ext.sf2");
+	}
+	Q_INVOKABLE void deinitFluidSynth()
+	{
+		mp->fluidDeinitialize();
+	}
+	Q_INVOKABLE void loadFile(QUrl file)
+	{
+		mp->playerLoadFile(file.toLocalFile().toStdString().c_str());
+		mp->playerInit();curprog=0;
+	}
+	Q_INVOKABLE void playFile()
+	{
+		playerTh=new std::thread(&CMidiPlayer::playerThread,mp);
+	}
+	Q_INVOKABLE void stop()
+	{
+		mp->playerDeinit();playerTh->join();delete playerTh;
+	}
+	Q_INVOKABLE int getProgress()
+	{
+		while(!mp->isFinished()&&mp->getTCeptr()>mp->getStamp(curprog)
+			  &&curprog<=100)
+			++curprog;
+		return curprog;
+	}
+	Q_INVOKABLE void panic(){mp->playerPanic();}
+	Q_INVOKABLE void setTCeptr(int perct)
+	{
+		mp->setTCeptr(mp->getStamp(perct),perct);curprog=perct;
+	}
+};
+#endif // QMPCOREWRAPPER_H
diff --git a/qmidiplayer-lite/qmpmidiplay.cpp b/qmidiplayer-lite/qmpmidiplay.cpp
new file mode 100644
index 0000000..baec9a2
--- /dev/null
+++ b/qmidiplayer-lite/qmpmidiplay.cpp
@@ -0,0 +1,406 @@
+#include <cstdio>
+#include <chrono>
+#include <thread>
+#include <fluidsynth.h>
+#include "qmpmidiplay.hpp"
+#ifdef _WIN32
+#include <windows.h>
+uint64_t pf;
+#endif
+void CMidiPlayer::fluidPreInitialize()
+{
+	settings=new_fluid_settings();
+}
+void CMidiPlayer::fluidInitialize()
+{
+	synth=new_fluid_synth(settings);
+	adriver=new_fluid_audio_driver(settings,synth);
+	fluid_synth_set_chorus(synth,FLUID_CHORUS_DEFAULT_N,FLUID_CHORUS_DEFAULT_LEVEL,
+						   FLUID_CHORUS_DEFAULT_SPEED,FLUID_CHORUS_DEFAULT_DEPTH,
+						   FLUID_CHORUS_DEFAULT_TYPE);
+#ifndef _WIN32
+	if(!singleInstance)
+	{
+		if(midiFile->getStandard()==4)
+		fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_MELODIC);
+		else if(midiFile->getStandard()==1)
+			fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_DRUM);
+		else
+		{
+			fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_DRUM);
+			fluid_synth_bank_select(synth,9,128);
+		}
+	}
+#endif
+}
+void CMidiPlayer::fluidDeinitialize()
+{
+	if(!synth||!adriver||!settings)return;
+	delete_fluid_settings(settings);
+	delete_fluid_audio_driver(adriver);
+	delete_fluid_synth(synth);
+	settings=NULL;synth=NULL;adriver=NULL;
+}
+void CMidiPlayer::processEvent(const SEvent *e)
+{
+	switch(e->type&0xF0)
+	{
+		case 0x80://Note off
+			fluid_synth_noteoff(synth,e->type&0x0F,e->p1);
+		break;
+		case 0x90://Note on
+			if((mute>>(e->type&0x0F))&1)break;//muted
+			if(solo&&!((solo>>(e->type&0x0F))&1))break;
+			fluid_synth_noteon(synth,e->type&0x0F,e->p1,e->p2);
+		break;
+		case 0xB0://CC
+			if(e->p1==100)rpnid=e->p2;
+			if(e->p1==6)rpnval=e->p2;
+			if(~rpnid&&~rpnval)
+			{
+				if(rpnid==0)fluid_synth_pitch_wheel_sens(synth,e->type&0x0F,rpnval);
+				rpnid=rpnval=-1;
+			}
+			fluid_synth_cc(synth,e->type&0x0F,e->p1,e->p2);
+		break;
+		case 0xC0://PC
+			fluid_synth_program_change(synth,e->type&0x0F,e->p1);
+		break;
+		case 0xE0://PW
+			fluid_synth_pitch_bend(synth,e->type&0x0F,e->p1);
+		break;
+		case 0xF0://Meta/SysEx
+			if((e->type&0x0F)==0x0F)
+			{
+				switch(e->p1)
+				{
+					case 0x51:
+						ctempo=e->p2;dpt=ctempo*1000/divs;
+					break;
+					case 0x58:
+						ctsn=e->p2>>24;
+						ctsd=1<<((e->p2>>16)&0xFF);
+					break;
+					case 0x59:
+						cks=e->p2;
+					break;
+					case 0x01:case 0x02:case 0x03:
+					case 0x04:case 0x05:case 0x06:
+					case 0x07:
+						if(e->str)puts(e->str);
+					break;
+				}
+			}
+			if((e->type&0x0F)==0x00||(e->type&0x0F)==07)
+			{
+				int io=0;
+				if(sendSysEx)fluid_synth_sysex(synth,e->str,e->p1,NULL,&io,NULL,0);
+			}
+		break;
+	}
+}
+void CMidiPlayer::processEventStub(const SEvent *e)
+{
+	switch(e->type&0xF0)
+	{
+		case 0xB0://CC
+			if(e->p1==100)rpnid=e->p2;
+			if(e->p1==6)rpnval=e->p2;
+			if(~rpnid&&~rpnval)
+			{
+				if(rpnid==0)ccc[e->type&0x0F][134]=rpnval;
+				rpnid=rpnval=-1;
+			}
+			ccc[e->type&0x0F][e->p1]=e->p2;
+		break;
+		case 0xC0://PC
+			ccc[e->type&0x0F][128]=e->p1;
+		break;
+		case 0xD0://CP
+			ccc[e->type&0x0F][129]=e->p1;
+		break;
+		case 0xE0://PW
+			ccc[e->type&0x0F][130]=e->p1;
+		break;
+		case 0xF0://Meta/SysEx
+			if((e->type&0x0F)==0x0F)
+			{
+				switch(e->p1)
+				{
+					case 0x51:
+						ctempo=e->p2;dpt=ctempo*1000/divs;
+						ccc[0][131]=dpt;
+					break;
+					case 0x58:
+						ccc[0][132]=e->p2;
+					break;
+					case 0x59:
+						ccc[0][133]=e->p2;
+					break;
+				}
+			}
+		break;
+	}
+}
+#ifdef _WIN32
+void w32usleep(uint64_t t)
+{
+	uint64_t st=0,ct=0;
+	QueryPerformanceCounter((LARGE_INTEGER*)&st);
+	do{
+		if(t>10000+(ct-st)*1000000/pf)Sleep((t-(ct-st)*1000000/pf)/2000);
+		else if(t>5000+(ct-st)*1000000/pf)Sleep(1);
+		else std::this_thread::yield();
+		QueryPerformanceCounter((LARGE_INTEGER*)&ct);
+	}while((ct-st)*1000000<t*pf);
+}
+#endif
+void CMidiPlayer::playEvents()
+{
+	for(uint32_t ct=midiFile->getEvent(0)->time;tceptr<midiFile->getEventCount();)
+	{
+		while(tcpaused)std::this_thread::sleep_for(std::chrono::milliseconds(100));
+		while(!tcstop&&midiFile&&tceptr<midiFile->getEventCount()&&ct==midiFile->getEvent(tceptr)->time)
+			processEvent(midiFile->getEvent(tceptr++));
+		if(tcstop||!midiFile||tceptr>=midiFile->getEventCount())break;
+		if(resumed)resumed=false;
+		else
+#ifdef _WIN32
+		w32usleep((midiFile->getEvent(tceptr)->time-ct)*(dpt/1000));
+#else
+		std::this_thread::sleep_for(std::chrono::nanoseconds(midiFile->getEvent(tceptr)->time-ct)*dpt);
+#endif
+		if(tcstop||!midiFile)break;
+		ct=midiFile->getEvent(tceptr)->time;
+	}
+	while(!tcstop&&synth&&(waitvoice&&fluid_synth_get_active_voice_count(synth)>0))std::this_thread::sleep_for(std::chrono::milliseconds(2));
+	finished=1;
+}
+void CMidiPlayer::fileTimer1Pass()
+{
+	ftime=.0;ctempo=0x7A120;dpt=ctempo*1000/divs;
+	for(uint32_t eptr=0,ct=midiFile->getEvent(0)->time;eptr<midiFile->getEventCount();)
+	{
+		while(eptr<midiFile->getEventCount()&&ct==midiFile->getEvent(eptr)->time)
+			processEventStub(midiFile->getEvent(eptr++));
+		if(eptr>=midiFile->getEventCount())break;
+		ftime+=(midiFile->getEvent(eptr)->time-ct)*dpt/1e9;
+		ct=midiFile->getEvent(eptr)->time;
+	}
+}
+void CMidiPlayer::fileTimer2Pass()
+{
+	double ctime=.0;uint32_t c=1;ctempo=0x7A120;dpt=ctempo*1000/divs;
+	memset(stamps,0,sizeof(stamps));memset(ccstamps,0,sizeof(ccstamps));
+	memset(ccc,0,sizeof(ccc));rpnid=rpnval=-1;for(int i=0;i<16;++i)
+	{
+		ccc[i][7]=100;ccc[i][10]=64;ccc[i][11]=127;
+		ccc[i][11]=127;ccc[i][71]=64;ccc[i][72]=64;
+		ccc[i][73]=64;ccc[i][74]=64;ccc[i][75]=64;
+		ccc[i][76]=64;ccc[i][77]=64;ccc[i][78]=64;
+		ccc[0][131]=dpt;ccc[0][132]=0x04021808;
+		ccc[0][133]=0;ccc[0][134]=2;
+	}if(midiFile->getStandard()!=4)ccc[9][0]=128;
+	for(int i=0;i<16;++i)for(int j=0;j<135;++j)
+		ccstamps[0][i][j]=ccc[i][j];
+	for(uint32_t eptr=0,ct=midiFile->getEvent(0)->time;eptr<midiFile->getEventCount();)
+	{
+		while(eptr<midiFile->getEventCount()&&ct==midiFile->getEvent(eptr)->time)
+			processEventStub(midiFile->getEvent(eptr++));
+		if(eptr>=midiFile->getEventCount())break;
+		ctime+=(midiFile->getEvent(eptr)->time-ct)*dpt/1e9;
+		while(ctime>ftime*c/100.)
+		{
+			for(int i=0;i<16;++i)for(int j=0;j<135;++j)
+				ccstamps[c][i][j]=ccc[i][j];
+			stamps[c++]=eptr;
+			if(c>100)break;
+		}
+		ct=midiFile->getEvent(eptr)->time;
+	}
+	while(c<101)
+	{
+		for(int i=0;i<16;++i)for(int j=0;j<135;++j)
+			ccstamps[c][i][j]=ccc[i][j];
+		stamps[c++]=midiFile->getEventCount();
+	}
+}
+CMidiPlayer::CMidiPlayer(bool singleInst)
+{
+	midiFile=NULL;resumed=false;singleInstance=singleInst;
+	settings=NULL;synth=NULL;adriver=NULL;waitvoice=true;
+#ifdef _WIN32
+	QueryPerformanceFrequency((LARGE_INTEGER*)&pf);
+	timeBeginPeriod(1);
+#endif
+}
+CMidiPlayer::~CMidiPlayer()
+{
+	if(singleInstance)fluidDeinitialize();
+#ifdef _WIN32
+	timeEndPeriod(1);
+#endif
+}
+void CMidiPlayer::playerPanic(bool reset)
+{
+	if(reset)for(int i=0;i<16;++i)
+	{
+		fluid_synth_pitch_bend(synth,i,8192);
+		fluid_synth_cc(synth,i,7,100);
+		fluid_synth_cc(synth,i,10,64);
+		fluid_synth_cc(synth,i,11,127);
+	}
+	for(int i=0;i<16;++i)fluid_synth_all_notes_off(synth,i);
+}
+bool CMidiPlayer::playerLoadFile(const char* fn)
+{
+	midiFile=new CMidiFile(fn);
+	if(!midiFile->isValid())return false;
+	divs=midiFile->getDivision();
+	fileTimer1Pass();
+	fileTimer2Pass();
+	return true;
+}
+void CMidiPlayer::playerInit()
+{
+	ctempo=0x7A120;ctsn=4;ctsd=4;cks=0;dpt=ctempo*1000/divs;
+	tceptr=0;tcstop=0;tcpaused=0;finished=0;mute=solo=0;
+	sendSysEx=true;rpnid=rpnval=-1;
+	if(!singleInstance)fluidPreInitialize();
+}
+void CMidiPlayer::playerDeinit()
+{
+	tceptr=0;tcstop=1;tcpaused=0;
+	delete midiFile;midiFile=NULL;
+	if(!singleInstance)fluidDeinitialize();
+}
+void CMidiPlayer::playerThread()
+{
+	playEvents();
+}
+
+void CMidiPlayer::rendererLoadFile(const char* ofn)
+{
+	settings=new_fluid_settings();
+	fluid_settings_setstr(settings,"audio.file.name",ofn);
+}
+void CMidiPlayer::rendererInit(const char* fn)
+{
+	finished=0;
+	synth=new_fluid_synth(settings);
+	player=new_fluid_player(synth);
+	fluid_player_add(player,fn);
+}
+void CMidiPlayer::rendererThread()
+{
+	fluid_file_renderer_t* renderer=new_fluid_file_renderer(synth);
+	fluid_player_play(player);
+	while(fluid_player_get_status(player)==FLUID_PLAYER_PLAYING)
+		if(fluid_file_renderer_process_block(renderer)!=FLUID_OK)break;
+	delete_fluid_file_renderer(renderer);
+	finished=1;
+}
+void CMidiPlayer::rendererDeinit()
+{
+	delete_fluid_player(player);
+	delete_fluid_synth(synth);
+	delete_fluid_settings(settings);
+	player=NULL;synth=NULL;settings=NULL;
+}
+
+void CMidiPlayer::sendSysX(bool send){sendSysEx=send;}
+uint32_t CMidiPlayer::getStamp(int id){return stamps[id];}
+uint32_t CMidiPlayer::getTCeptr(){return tceptr;}
+void CMidiPlayer::setTCeptr(uint32_t ep,uint32_t st)
+{
+	resumed=true;
+	if(ep==midiFile->getEventCount())tcstop=1;else tceptr=ep;
+	for(int i=0;i<16;++i)
+	{
+		for(int j=0;j<120;++j)fluid_synth_cc(synth,i,j,ccstamps[st][i][j]);
+		fluid_synth_program_change(synth,i,ccstamps[st][i][128]);
+		//fluid_synth_pitch_bend(synth,i,ccstamps[st][i][130]);
+		dpt=ccstamps[st][0][131];ctempo=dpt*divs/1000;
+		ctsn=ccstamps[st][0][132]>>24;ctsd=1<<((ccstamps[st][0][132]>>16)&0xFF);
+		cks=ccstamps[st][0][133];
+	}
+}
+double CMidiPlayer::getFtime(){return ftime;}
+void CMidiPlayer::getCurrentTimeSignature(int *n,int *d){*n=ctsn;*d=ctsd;}
+void CMidiPlayer::getCurrentKeySignature(int *ks){*ks=cks;}
+uint32_t CMidiPlayer::getFileNoteCount(){return midiFile?midiFile->getNoteCount():0;}
+uint32_t CMidiPlayer::getFileStandard(){return midiFile?midiFile->getStandard():0;}
+const char* CMidiPlayer::getTitle(){return midiFile?midiFile->getTitle():"";}
+const char* CMidiPlayer::getCopyright(){return midiFile?midiFile->getCopyright():"";}
+double CMidiPlayer::getTempo(){return 60./(ctempo/1e6)/**ctsd/4.*/;}
+uint32_t CMidiPlayer::getTCpaused(){return tcpaused;}
+void CMidiPlayer::setTCpaused(uint32_t ps){tcpaused=ps;}
+uint32_t CMidiPlayer::isFinished(){return finished;}
+void CMidiPlayer::setResumed(){resumed=true;}
+void CMidiPlayer::setWaitVoice(bool wv){waitvoice=wv;}
+void CMidiPlayer::setGain(double gain){if(settings)fluid_settings_setnum(settings,"synth.gain",gain);}
+int CMidiPlayer::getPolyphone(){return synth?fluid_synth_get_active_voice_count(synth):0;}
+int CMidiPlayer::getMaxPolyphone(){return synth?fluid_synth_get_polyphony(synth):0;}
+void CMidiPlayer::setMaxPolyphone(int p){if(synth)fluid_synth_set_polyphony(synth,p);}
+
+void CMidiPlayer::getChannelPreset(int ch,int *b,int *p,char *name)
+{
+	if(!synth)return(void)(b=0,p=0,strcpy(name,""));
+	fluid_synth_channel_info_t info;
+	fluid_synth_get_channel_info(synth,ch,&info);
+	*b=info.bank;*p=info.program;
+	strcpy(name,info.name);
+}
+void CMidiPlayer::setChannelPreset(int ch,int b,int p)
+{
+	if(!synth)return;
+	fluid_synth_bank_select(synth,ch,b);
+	fluid_synth_program_change(synth,ch,p);
+}
+//16MSB..LSB1
+void CMidiPlayer::setBit(uint16_t &n, uint16_t bn, uint16_t b)
+{n^=(-b^n)&(1<<bn);}
+void CMidiPlayer::setMute(int ch,bool m)
+{setBit(mute,ch,m?1:0);}
+void CMidiPlayer::setSolo(int ch,bool s)
+{setBit(solo,ch,s?1:0);}
+int CMidiPlayer::getCC(int ch, int id)
+{int ret=0;synth?fluid_synth_get_cc(synth,ch,id,&ret):0;return ret;}
+void CMidiPlayer::setCC(int ch, int id, int val)
+{synth?fluid_synth_cc(synth,ch,id,val):0;}
+void CMidiPlayer::getReverbPara(double *r,double *d,double *w,double *l)
+{
+	if(!synth)return;
+	*r=fluid_synth_get_reverb_roomsize(synth);
+	*d=fluid_synth_get_reverb_damp(synth);
+	*w=fluid_synth_get_reverb_width(synth);
+	*l=fluid_synth_get_reverb_level(synth);
+}
+void CMidiPlayer::setReverbPara(int e,double r,double d,double w,double l)
+{
+	if(!synth)return;
+	fluid_synth_set_reverb_on(synth,e);
+	fluid_synth_set_reverb(synth,r,d,w,l);
+}
+void CMidiPlayer::getChorusPara(int *fb,double *l,double *r,double *d,int *type)
+{
+	if(!synth)return;
+	*fb=fluid_synth_get_chorus_nr(synth);
+	*l=fluid_synth_get_chorus_level(synth);
+	*r=fluid_synth_get_chorus_speed_Hz(synth);
+	*d=fluid_synth_get_chorus_depth_ms(synth);
+	*type=fluid_synth_get_chorus_type(synth);
+}
+void CMidiPlayer::setChorusPara(int e,int fb,double l,double r,double d,int type)
+{
+	if(!synth)return;
+	fluid_synth_set_chorus_on(synth,e);
+	fluid_synth_set_chorus(synth,fb,l,r,d,type);
+}
+fluid_settings_t* CMidiPlayer::getFluidSettings(){return settings;}
+void CMidiPlayer::pushSoundFont(const char *sf)
+{fluid_synth_sfload(synth,sf,1);}
+int CMidiPlayer::getSFCount()
+{return synth?fluid_synth_sfcount(synth):0;}
+fluid_sfont_t* CMidiPlayer::getSFPtr(int sfid)
+{return synth&&sfid<getSFCount()?fluid_synth_get_sfont(synth,sfid):NULL;}
diff --git a/qmidiplayer-lite/qmpmidiplay.hpp b/qmidiplayer-lite/qmpmidiplay.hpp
new file mode 100644
index 0000000..fafd677
--- /dev/null
+++ b/qmidiplayer-lite/qmpmidiplay.hpp
@@ -0,0 +1,137 @@
+//sorry for the stupid C-like code...
+#ifndef QMPMIDIPLAY_H
+#define QMPMIDIPLAY_H
+#include <cstring>
+#include <cstdint>
+#include <cstdlib>
+#include <fluidsynth.h>
+struct SEvent
+{
+	uint32_t iid,time,p1,p2;
+	uint8_t type;
+	char *str;
+	SEvent(){time=p1=p2=0;type=0;str=NULL;}
+	SEvent(uint32_t _iid,uint32_t _t,char _tp,uint32_t _p1,uint32_t _p2,const char* s=NULL)
+	{
+		iid=_iid;time=_t;type=_tp;
+		p1=_p1;p2=_p2;
+		if(s){str=new char[strlen(s)+2];strcpy(str,s);}else str=NULL;
+	}
+};
+class CMidiFile
+{
+	private:
+		SEvent *eventList[10000000];
+		char *title,*copyright;
+		uint32_t eventc,std;//standard 0=? 1=GM 2=GM2 3=GS 4=XG
+		uint32_t fmt,trk,divs;
+		FILE *f;
+		int byteread,valid;
+		uint32_t notes,curt,curid;
+
+		void error(int fatal,const char* format,...);
+		uint32_t readSW();
+		uint32_t readDW();
+		uint32_t readVL();
+		int eventReader();
+		void trackChunkReader();
+		void headerChunkReader();
+		int chunkReader(int hdrXp);
+	public:
+		CMidiFile(const char* fn);
+		~CMidiFile();
+		const SEvent* getEvent(uint32_t id);
+		uint32_t getEventCount();
+		uint32_t getDivision();
+		uint32_t getNoteCount();
+		uint32_t getStandard();
+		const char* getTitle();
+		const char* getCopyright();
+		bool isValid();
+};
+class CMidiPlayer
+{
+	private:
+		CMidiFile *midiFile;
+		uint32_t stamps[101];
+		uint32_t ccstamps[101][16][135],ccc[16][135];
+		//0..127:cc 128:pc 129:cp 130:pb 131:tempo 132:ts 133:ks 134:pbr
+		int32_t rpnid,rpnval;
+		uint16_t mute,solo;
+		double ftime;
+		bool sendSysEx,singleInstance,waitvoice;
+		fluid_settings_t* settings;
+		fluid_synth_t* synth;
+		fluid_audio_driver_t* adriver;
+		fluid_player_t* player;
+		uint32_t ctempo,ctsn,ctsd,dpt,divs,cks;
+		//raw tempo, timesig num., timesig den., delay per tick, division, keysig
+		//thread control
+		uint32_t tceptr,tcpaused,tcstop;
+		uint32_t finished,resumed;
+
+		void setBit(uint16_t &n,uint16_t bn,uint16_t b);
+		void processEvent(const SEvent *e);
+		void processEventStub(const SEvent *e);
+		void playEvents();
+		void fileTimer1Pass();
+		void fileTimer2Pass();
+	public:
+		CMidiPlayer(bool singleInst=false);
+		~CMidiPlayer();
+		bool playerLoadFile(const char* fn);
+		void playerInit();
+		void fluidPreInitialize();
+		void fluidInitialize();
+		void fluidDeinitialize();
+		void playerDeinit();
+		void playerThread();
+		void playerPanic(bool reset=false);
+
+		void rendererLoadFile(const char* ofn);
+		void rendererInit(const char *fn);
+		void rendererThread();
+		void rendererDeinit();
+
+		//playing control methods
+		uint32_t getStamp(int id);
+		uint32_t getTCeptr();
+		void setTCeptr(uint32_t ep,uint32_t st);
+		uint32_t getTCpaused();
+		void setTCpaused(uint32_t ps);
+		uint32_t isFinished();
+		void setResumed();
+		void setWaitVoice(bool wv);
+
+		double getFtime();
+		void getCurrentTimeSignature(int *n,int *d);
+		void getCurrentKeySignature(int *ks);
+		uint32_t getFileNoteCount();
+		uint32_t getFileStandard();
+		double getTempo();
+		const char* getTitle();
+		const char* getCopyright();
+
+		void setGain(double gain);
+		void sendSysX(bool send);
+		int getPolyphone();
+		int getMaxPolyphone();
+		void setMaxPolyphone(int p);
+
+		void setChannelPreset(int ch,int b,int p);
+		void getChannelPreset(int ch,int *b,int *p,char *name);
+		void setMute(int ch,bool m);
+		void setSolo(int ch,bool s);
+		int getCC(int ch,int id);
+		void setCC(int ch,int id,int val);
+		void getReverbPara(double *r,double *d,double *w,double *l);
+		void setReverbPara(int e,double r,double d,double w,double l);
+		void getChorusPara(int *fb,double *l,double *r,double *d,int *type);
+		void setChorusPara(int e,int fb,double l,double r,double d,int type);
+
+		fluid_settings_t* getFluidSettings();
+		void pushSoundFont(const char* sf);
+		int getSFCount();
+		fluid_sfont_t* getSFPtr(int sfid);
+};
+#endif
diff --git a/qmidiplayer-lite/qmpmidiread.cpp b/qmidiplayer-lite/qmpmidiread.cpp
new file mode 100644
index 0000000..0bcf597
--- /dev/null
+++ b/qmidiplayer-lite/qmpmidiread.cpp
@@ -0,0 +1,240 @@
+//CLI Midi file player based on libfluidsynth
+//Midi file reading module
+//Written by Chris Xiong, 2015
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <cstdint>
+#include <cstdarg>
+#include <algorithm>
+#include "qmpmidiplay.hpp"
+const char* GM1SysX={"\xF0\x7E\x7F\x09\x01\xF7"};
+const char* GM2SysX={"\xF0\x7E\x7F\x09\x03\xF7"};
+const char* GSSysEx={"\xF0\x41\x10\x42\x12\x40\x00\x7F\x00\x41\xF7"};
+const char* XGSysEx={"\xF0\x43\x10\x4C\x00\x00\x7E\x00\xF7"};
+bool cmp(SEvent *a,SEvent *b){return a->time-b->time?a->time<b->time:a->iid<b->iid;}
+void CMidiFile::error(int fatal,const char* format,...)
+{
+	va_list ap;
+	va_start(ap,format);vfprintf(stderr,format,ap);va_end(ap);
+	fprintf(stderr," at %#lx\n",ftell(f));
+	if(fatal)throw 2;
+}
+uint32_t CMidiFile::readSW()
+{
+	byteread+=2;
+	uint32_t ret=0;
+	for(int i=0;i<2;++i){ret<<=8;ret|=((uint32_t)fgetc(f))&0xFF;}
+	return ret;
+}
+uint32_t CMidiFile::readDW()
+{
+	byteread+=4;
+	uint32_t ret=0;
+	for(int i=0;i<4;++i){ret<<=8;ret|=((uint32_t)fgetc(f))&0xFF;}
+	return ret;
+}
+uint32_t CMidiFile::readVL()
+{
+	uint32_t ret=0,t,c=0;
+	do
+	{
+		t=fgetc(f);
+		if(++c>4)error(1,"E: Variable length type overflow.");
+		ret<<=7;ret|=(t&0x7F);
+	}while(t&0x80);
+	byteread+=c;
+	return ret;
+}
+int CMidiFile::eventReader()//returns 0 if End of Track encountered
+{
+	uint32_t delta=readVL();curt+=delta;
+	char type=fgetc(f);++byteread;uint32_t p1,p2;
+	static char lasttype;
+retry:
+	switch(type&0xF0)
+	{
+		case 0x80://Note Off
+			p1=fgetc(f);p2=fgetc(f);byteread+=2;
+			eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
+		break;
+		case 0x90://Note On
+			p1=fgetc(f);p2=fgetc(f);byteread+=2;
+			if(p2)
+			{
+				++notes;
+				eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
+			}
+			else
+				eventList[eventc++]=new SEvent(curid,curt,(type&0x0F)|0x80,p1,p2);
+		break;
+		case 0xA0://Note Aftertouch
+			p1=fgetc(f);p2=fgetc(f);byteread+=2;
+			eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
+		break;
+		case 0xB0://Controller Change
+			p1=fgetc(f);p2=fgetc(f);byteread+=2;
+			eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
+		break;
+		case 0xC0://Patch Change
+			p1=fgetc(f);++byteread;
+			eventList[eventc++]=new SEvent(curid,curt,type,p1,0);
+		break;
+		case 0xD0://Channel Aftertouch
+			p1=fgetc(f);++byteread;
+			eventList[eventc++]=new SEvent(curid,curt,type,p1,0);
+		break;
+		case 0xE0://Pitch wheel
+			p1=fgetc(f);p2=fgetc(f);byteread+=2;
+			eventList[eventc++]=new SEvent(curid,curt,type,(p1|(p2<<7))&0x3FFF,0);
+		break;
+		case 0xF0:
+			if((type&0x0F)==0x0F)//Meta Event
+			{
+				char metatype=fgetc(f);++byteread;
+				switch(metatype)
+				{
+					case 0x00://Sequence Number
+						fgetc(f);fgetc(f);fgetc(f);
+						byteread+=3;
+					break;
+					case 0x20://Channel Prefix
+						fgetc(f);fgetc(f);byteread+=2;
+					break;
+					case 0x2F://End of Track
+						fgetc(f);++byteread;
+						return 0;
+					break;
+					case 0x51://Set Tempo
+						p1=readDW();p1&=0x00FFFFFF;
+						eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1);
+					break;
+					case 0x54://SMTPE offset, not handled.
+						fgetc(f);fgetc(f);fgetc(f);
+						fgetc(f);fgetc(f);fgetc(f);
+						byteread+=6;
+					break;
+					case 0x58://Time signature
+						fgetc(f);++byteread;
+						p1=readDW();
+						eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1);
+					break;
+					case 0x59://Key signature
+						fgetc(f);++byteread;
+						p1=readSW();
+						eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1);
+					break;
+					case 0x01:case 0x02:case 0x03:
+					case 0x04:case 0x05:case 0x06:
+					case 0x07:case 0x7F:default://text-like meta
+					{
+						uint32_t len=readVL(),c;char* str=NULL;
+						if(len<=1024&&len>0)str=new char[len+8];
+						for(c=0;c<len;++c)
+						{
+							++byteread;if(str)str[c]=fgetc(f);else fgetc(f);
+						}
+						if(str)str[c]='\0';eventList[eventc++]=new SEvent(curid,curt,type,metatype,0,str);
+						if(str&&metatype==0x03&&!title)
+						{
+							title=new char[len+8];
+							strcpy(title,str);
+						}
+						if(str&&metatype==0x02&&!copyright)
+						{
+							copyright=new char[len+8];
+							strcpy(copyright,str);
+						}
+						if(len<=1024&&len>0)delete[] str;
+					}
+				}
+			}
+			else if((type&0x0F)==0x00||(type&0x0F)==0x07)//SysEx
+			{
+				uint32_t len=readVL(),c;char* str=NULL;
+				str=new char[len+8];
+				if((type&0x0F)==0x00)
+				{
+					str[0]=0xF0;++len;
+					for(c=1;c<len;++c){++byteread;str[c]=fgetc(f);}
+				}
+				else for(c=0;c<len;++c){++byteread;str[c]=fgetc(f);}
+				eventList[eventc++]=new SEvent(curid,curt,type,len,0,str);
+				if(!strcmp(str,GM1SysX))std=1;
+				if(!strcmp(str,GM2SysX))std=2;
+				if(!strcmp(str,GSSysEx))std=3;
+				if(!strcmp(str,XGSysEx))std=4;
+			}
+			else error(0,"W: Unknown event type %#x",type);
+		break;
+		default:
+			fseek(f,-1,SEEK_CUR);--byteread;type=lasttype;goto retry;
+	}
+	lasttype=type;++curid;
+	return 1;
+}
+void CMidiFile::trackChunkReader()
+{
+	int chnklen=readDW();byteread=0;curt=0;curid=0;
+	while(/*byteread<chnklen&&*/eventReader());
+	if(byteread<chnklen)
+	{
+		error(0,"W: Extra bytes after EOT event.");
+		while(byteread<chnklen){fgetc(f);++byteread;}
+	}
+	/*if(byteread>chnklen)
+	{
+		error(1,"E: Read past end of track.");
+	}*/
+}
+void CMidiFile::headerChunkReader()
+{
+	int chnklen=readDW();byteread=0;
+	if(chnklen<6)error(1,"E: Header chunk too short.");
+	if(chnklen>6)error(0,"W: Header chunk length longer than expected. Ignoring extra bytes.");
+	fmt=readSW();trk=readSW();divs=readSW();
+	if(divs&0x8000)error(1,"E: SMTPE format is not supported.");
+	for(;byteread<chnklen;++byteread){fgetc(f);}
+}
+int CMidiFile::chunkReader(int hdrXp)
+{
+	char hdr[6];
+	if(!fgets(hdr,5,f))error(1,"E: Unexpected EOF.");
+	if(hdrXp)
+		if(strncmp(hdr,"MThd",4)){error(1,"E: Wrong MIDI header.");throw;}
+		else return headerChunkReader(),0;
+	else
+		if(strncmp(hdr,"MTrk",4))
+		{
+			error(0,"W: Wrong track chunk header. Ignoring the whole chunk.");
+			for(int chnklen=readDW();chnklen>0;--chnklen)fgetc(f);return 0;
+		}
+		else return trackChunkReader(),1;
+}
+CMidiFile::CMidiFile(const char* fn)
+{
+	title=copyright=NULL;notes=eventc=0;std=0;valid=1;
+	try
+	{
+		if(!(f=fopen(fn,"rb")))throw (fprintf(stderr,"E: file %s doesn't exist!\n",fn),2);
+		chunkReader(1);
+		for(uint32_t i=0;i<trk;i+=chunkReader(0));
+		printf("%d note(s)\n",notes);
+		fclose(f);
+		std::sort(eventList,eventList+eventc,cmp);
+	}
+	catch(int){fprintf(stderr,"E: %s is not a supported file.\n",fn);valid=0;}
+}
+CMidiFile::~CMidiFile()
+{
+	for(uint32_t i=0;i<eventc;++i)delete eventList[i];
+	if(title)delete[] title;if(copyright)delete[] copyright;
+}
+const SEvent* CMidiFile::getEvent(uint32_t id){return id<eventc?eventList[id]:NULL;}
+uint32_t CMidiFile::getEventCount(){return eventc;}
+uint32_t CMidiFile::getDivision(){return divs;}
+uint32_t CMidiFile::getNoteCount(){return notes;}
+uint32_t CMidiFile::getStandard(){return std;}
+bool CMidiFile::isValid(){return valid;}
+const char* CMidiFile::getTitle(){return title;}
+const char* CMidiFile::getCopyright(){return copyright;}
diff --git a/qmidiplayer.pro b/qmidiplayer.pro
index 63e20b6..da362f3 100644
--- a/qmidiplayer.pro
+++ b/qmidiplayer.pro
@@ -1,64 +1,5 @@
-#-------------------------------------------------
-#
-# Project created by QtCreator 2015-12-25T20:24:49
-#
-#-------------------------------------------------
+TEMPLATE = subdirs
 
-QT       += core gui
-
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
-
-TARGET = qmidiplayer
-TEMPLATE = app
-
-
-SOURCES += ./qmidiplayer.src.d/main.cpp\
-	./qmidiplayer.src.d/qmpmainwindow.cpp \
-	./common/qmpmidiplay.cpp \
-	./common/qmpmidiread.cpp \
-	./qmidiplayer.src.d/qmpplistwindow.cpp \
-	./qmidiplayer.src.d/qmpchannelswindow.cpp \
-	./qmidiplayer.src.d/qmppresetselect.cpp \
-	./qmidiplayer.src.d/qmpchanneleditor.cpp \
-	./qmidiplayer.src.d/qmpefxwindow.cpp \
-	./qmidiplayer.src.d/qmpinfowindow.cpp \
-	./qmidiplayer.src.d/qmpsettingswindow.cpp \
-	./qmidiplayer.src.d/qmphelpwindow.cpp \
-	./qmidiplayer.src.d/qdialskulpturestyle.cpp
-
-HEADERS  += ./qmidiplayer.src.d/qmpmainwindow.hpp \
-	./common/qmpmidiplay.hpp \
-	./qmidiplayer.src.d/qmpplistwindow.hpp \
-	./qmidiplayer.src.d/qmpchannelswindow.hpp \
-	./qmidiplayer.src.d/qmppresetselect.hpp \
-	./qmidiplayer.src.d/qmpchanneleditor.hpp \
-	./qmidiplayer.src.d/qmpefxwindow.hpp \
-	./qmidiplayer.src.d/qmpinfowindow.hpp \
-	./qmidiplayer.src.d/qmpsettingswindow.hpp \
-	./qmidiplayer.src.d/qmphelpwindow.hpp \
-	./qmidiplayer.src.d/qdialskulpturestyle.hpp \
-	./qmidiplayer.src.d/qmpimidimapper.hpp
-
-FORMS    += ./qmidiplayer.src.d/qmpmainwindow.ui \
-	./qmidiplayer.src.d/qmpplistwindow.ui \
-	./qmidiplayer.src.d/qmpchannelswindow.ui \
-	./qmidiplayer.src.d/qmppresetselect.ui \
-	./qmidiplayer.src.d/qmpchanneleditor.ui \
-	./qmidiplayer.src.d/qmpefxwindow.ui \
-	./qmidiplayer.src.d/qmpinfowindow.ui \
-	./qmidiplayer.src.d/qmpsettingswindow.ui \
-	./qmidiplayer.src.d/qmphelpwindow.ui
-
-unix{
-	isEmpty(PREFIX) {
-		PREFIX = /usr/local
-	}
-	BINDIR = $$PREFIX/bin
-	target.path = $$BINDIR
-	INSTALLS += target
-	QMAKE_CXXFLAGS += -std=c++11 -Wall
-	LIBS += -lfluidsynth
-}
-win32:LIBS += e:/libs/fluidsynth/fluidsynth.lib winmm.lib #You have to change these
-win32:INCLUDEPATH += e:/libs/fluidsynth/include           #before building...
-RESOURCES     = ./qmidiplayer.src.d/resources.qrc
+SUBDIRS = \
+    qmidiplayer-desktop \
+    qmidiplayer-lite
diff --git a/qmidiplayer.src.d/main.cpp b/qmidiplayer.src.d/main.cpp
deleted file mode 100644
index c9f3b42..0000000
--- a/qmidiplayer.src.d/main.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *QMidiPlayer, a cross-platform player for midi files.
- *Copyright (C) 2015  Chris Xiong
- *
- *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 "qmpmainwindow.hpp"
-#include <QApplication>
-#include <QStyle>
-
-int main(int argc,char **argv)
-{
-	QApplication a(argc,argv);
-	qmpMainWindow w;
-	if(w.pharseArgs(argc,argv)==1)return 0;
-
-	return a.exec();
-}
diff --git a/qmidiplayer.src.d/qdialskulpturestyle.cpp b/qmidiplayer.src.d/qdialskulpturestyle.cpp
deleted file mode 100644
index 7c181a0..0000000
--- a/qmidiplayer.src.d/qdialskulpturestyle.cpp
+++ /dev/null
@@ -1,437 +0,0 @@
-/******************************************************************************
-
-   Skulpture - Classical Three-Dimensional Artwork for Qt 4
-
-   Copyright (c) 2007-2009 Christoph Feck <christoph@maxiom.de>
-
-   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 <cmath>
-#include <QStyleOptionSlider>
-#include <QPixmapCache>
-#include <QPainter>
-
-#include "qdialskulpturestyle.hpp"
-
-#ifndef M_PI
-#define M_PI 3.141592653589793f
-#endif
-
-static const bool UsePixmapCache = true;
-
-static void
-paintIndicatorCached(QPainter *painter, const QStyleOption *option, void (*paintIndicator)(QPainter *painter, const QStyleOption *option), bool useCache, const QString &pixmapName)
-{
-	QPixmap pixmap;
-
-	if (!useCache || !QPixmapCache::find(pixmapName, pixmap)) {
-		pixmap =  QPixmap(option->rect.size());
-#if 1
-		pixmap.fill(Qt::transparent);
-	//  pixmap.fill(Qt::red);
-#else
-		pixmap.fill(option->palette.color(QPalette::Window));
-#endif
-		QPainter p(&pixmap);
-		QStyleOption opt = *option;
-		opt.rect = QRect(QPoint(0, 0), option->rect.size());
-	//  p.setCompositionMode(QPainter::CompositionMode_Clear);
-	//  p.setCompositionMode(QPainter::CompositionMode_Source);
-	//  p.fillRect(opt.rect, Qt::transparent);
-	//  p.setCompositionMode(QPainter::CompositionMode_SourceOver);
-		p.setFont(painter->font());
-		p.setRenderHint(QPainter::Antialiasing, true);
-		paintIndicator(&p, &opt);
-		p.end();
-		if (useCache) {
-			QPixmapCache::insert(pixmapName, pixmap);
-		//  qDebug() << "inserted into cache:" << pixmapName;
-		}
-	}
-	painter->drawPixmap(option->rect, pixmap);
-}
-
-void
-paintDialBase(QPainter *painter, const QStyleOption *option)
-{
-//  painter->fillRect(option->rect, Qt::red);
-//  painter->save();
-//  painter->setRenderHint(QPainter::Antialiasing, true);
-	int d = qMin(option->rect.width(), option->rect.height());
-/*  if (d > 20 && option->notchTarget > 0) {
-		d += -1;
-	}
-*/  QRectF r((option->rect.width() - d) / 2.0, (option->rect.height() - d) / 2.0, d, d);
-	const qreal angle = option->direction == Qt::LeftToRight ? 135.0 : 45.0;
-//  const qreal angle = 90;
-
-	painter->setPen(Qt::NoPen);
-	QColor border_color = option->palette.color(QPalette::Window);
-#if 0
-	{
-		QRadialGradient depth_gradient(r.center(), d / 2);
-//      depth_gradient.setColorAt(0.0, QColor(0, 0, 0, 255));
-		depth_gradient.setColorAt(0.5, QColor(0, 0, 0, 255));
-		depth_gradient.setColorAt(1.0, QColor(0, 0, 0, 0));
-		painter->setBrush(depth_gradient);
-		painter->drawEllipse(r);
-	}
-#endif
-#if 1
-	if (option->state & QStyle::State_HasFocus && option->state & QStyle::State_KeyboardFocusChange) {
-		painter->setBrush(option->palette.color(QPalette::Highlight).darker(180));
-		r.adjust(1, 1, -1, -1);
-		painter->drawEllipse(r);
-		painter->setBrush(border_color);
-		r.adjust(1, 1, -1, -1);
-		painter->drawEllipse(r);
-		r.adjust(1, 1, -1, -1);
-	} else {
-		painter->setBrush(border_color);
-		r.adjust(1, 1, -1, -1);
-		painter->drawEllipse(r);
-		r.adjust(1, 1, -1, -1);
-		QConicalGradient border_gradient(r.center(), angle);
-		if (!(option->state & QStyle::State_Enabled)) {
-			border_color = border_color.lighter(120);
-		}
-		border_gradient.setColorAt(0.0, border_color.darker(180));
-		border_gradient.setColorAt(0.3, border_color.darker(130));
-		border_gradient.setColorAt(0.5, border_color.darker(170));
-		border_gradient.setColorAt(0.7, border_color.darker(130));
-		border_gradient.setColorAt(1.0, border_color.darker(180));
-		painter->setBrush(border_gradient);
-//      painter->setBrush(Qt::blue);
-		painter->drawEllipse(r);
-		r.adjust(1, 1, -1, -1);
-	}
-	d -= 6;
-
-	QColor dial_color;
-	if (option->state & QStyle::State_Enabled) {
-		dial_color = option->palette.color(QPalette::Button).lighter(101);
-		if (option->state & QStyle::State_MouseOver) {
-			dial_color = dial_color.lighter(103);
-		}
-	} else {
-		dial_color = option->palette.color(QPalette::Window);
-	}
-	qreal t = option->state & QStyle::State_Enabled ? 2.0 : 1.5;
-	if (1) {
-		// ###: work around Qt 4.3.0 bug? (this works for 4.3.1)
-		QConicalGradient border_gradient(r.center(), angle);
-		border_gradient.setColorAt(0.0, dial_color.lighter(120));
-		border_gradient.setColorAt(0.2, dial_color);
-		border_gradient.setColorAt(0.5, dial_color.darker(130));
-		border_gradient.setColorAt(0.8, dial_color);
-		border_gradient.setColorAt(1.0, dial_color.lighter(120));
-		painter->setPen(QPen(border_gradient, t));
-	} else {
-		painter->setPen(QPen(Qt::red, t));
-	}
-#if 0
-	QLinearGradient dial_gradient(r.topLeft(), r.bottomLeft());
-	dial_gradient.setColorAt(0.0, dial_color.darker(105));
-	dial_gradient.setColorAt(0.5, dial_color.lighter(102));
-	dial_gradient.setColorAt(1.0, dial_color.lighter(105));
-#elif 1
-			  QLinearGradient dial_gradient(option->direction == Qt::LeftToRight ? r.topLeft() : r.topRight(), option->direction == Qt::LeftToRight ? r.bottomRight() : r.bottomLeft());
-//  QLinearGradient dial_gradient(r.topLeft(), r.bottomLeft());
-	if (true || option->state & QStyle::State_Enabled) {
-#if 1
-		dial_gradient.setColorAt(0.0, dial_color.darker(106));
-		dial_gradient.setColorAt(1.0, dial_color.lighter(104));
-#else
-		dial_gradient.setColorAt(0.0, dial_color.lighter(101));
-		dial_gradient.setColorAt(0.5, dial_color.darker(103));
-		dial_gradient.setColorAt(1.0, dial_color.lighter(104));
-#endif
-	} else {
-		dial_gradient.setColorAt(0.0, dial_color);
-		dial_gradient.setColorAt(1.0, dial_color);
-	}
-#elif 0
-	QConicalGradient dial_gradient(r.center(), angle);
-	dial_gradient.setColorAt(0.0, dial_color.lighter(102));
-	dial_gradient.setColorAt(0.5, dial_color.darker(103));
-	dial_gradient.setColorAt(1.0, dial_color.lighter(102));
-#else
-	QBrush dial_gradient(dial_color);
-#endif
-	painter->setBrush(dial_gradient);
-	t = t / 2;
-	painter->drawEllipse(r.adjusted(t, t, -t, -t));
-
-//  painter->setPen(Qt::NoPen);
-//  painter->setBrush(dial_color);
-//  painter->drawEllipse(r.adjusted(d / 4, d / 4, - d / 4, - d / 4));
-
-#if 0
-	QLinearGradient border2_gradient(r.topLeft(), r.bottomRight());
-	border2_gradient.setColorAt(1.0, dial_color.darker(425));
-	border2_gradient.setColorAt(0.9, dial_color);
-	border2_gradient.setColorAt(0.0, dial_color.darker(400));
-	painter->setPen(QPen(border2_gradient, 1.3));
-	painter->setBrush(Qt::NoBrush);
-	painter->drawEllipse(r.adjusted(0.3, 0.3, -0.3, -0.3));
-#endif
-//  painter->restore();
-#endif
-}
-
-void
-paintCachedDialBase(QPainter *painter, const QStyleOptionSlider *option)
-{
-	bool useCache = UsePixmapCache;
-	QString pixmapName;
-	QRect r = option->rect;
-	int d = qMin(r.width(), r.height());
-
-	if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ d > 128) {
-		useCache = false;
-	}
-	if (useCache) {
-		uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_KeyboardFocusChange | QStyle::State_HasFocus);
-		if (!(state & QStyle::State_Enabled)) {
-			state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus | QStyle::State_KeyboardFocusChange);
-		}
-	//  state &= ~(QStyle::State_HasFocus);
-		pixmapName.sprintf("scp-qdb-%x-%x-%llx-%x", state, option->direction, option->palette.cacheKey(), d);
-	}
-	paintIndicatorCached(painter, option, paintDialBase, useCache, pixmapName);
-}
-
-void
-paintIndicatorDial(QPainter *painter, const QStyleOptionSlider *option)
-{
-	int d = qMin(option->rect.width(), option->rect.height());
-	QRect rect(option->rect.center() - QPoint((d - 1) / 2, (d - 1) / 2), QSize(d, d));
-	QStyleOptionSlider opt;
-	opt.QStyleOption::operator=(*option);
-	opt.rect = rect;
-	paintCachedDialBase(painter, &opt);
-}
-
-QColor
-shaded_color(const QColor &color, int shade)
-{
-#if 1
-	const qreal contrast = 1.0;
-	int r, g, b;
-	color.getRgb(&r, &g, &b);
-	int gray = qGray(r, g, b);
-	gray = qMax(r, qMax(g, b));
-	gray = (r + b + g + 3 * gray) / 6;
-	if (shade < 0) {
-		qreal k = 220.0 / 255.0 * shade;
-		k *= contrast;
-		int a = 255;
-		if (gray > 0) {
-			a = int(k * 255 / (0 - gray));
-			if (a < 0) a = 0;
-			if (a > 255) a = 255;
-		}
-		return QColor(0, 0, 0, a);
-	} else {
-		qreal k = (255 - 220.0) / (255.0) * shade;
-		k *= contrast;
-		int a = 255;
-		if (gray < 255) {
-			a = int(k * 255 / (255 - gray));
-			if (a < 0) a = 0;
-			if (a > 255) a = 255;
-		}
-		return QColor(255, 255, 255, a);
-	}
-#else
-	if (shade < 0) {
-		return QColor(0, 0, 0, -shade);
-	} else {
-		return QColor(255, 255, 255, shade);
-	}
-#endif
-}
-
-static void
-paintGrip(QPainter *painter, const QStyleOption *option)
-{
-//  painter->fillRect(option->rect, Qt::red);
-	int d = qMin(option->rect.width(), option->rect.height());
-	// good values are 3 (very small), 4 (small), 5 (good), 7 (large), 9 (huge)
-	// int d = 5;
-	QRectF rect(QRectF(option->rect).center() - QPointF(d / 2.0, d / 2.0), QSizeF(d, d));
-	const qreal angle = option->direction == Qt::LeftToRight ? 135.0 : 45.0;
-//  const qreal angle = 90;
-	QColor color;
-		qreal opacity = 0.9;
-
-	painter->save();
-	painter->setPen(Qt::NoPen);
-	if (option->state & QStyle::State_Enabled) {
-		if (option->state & QStyle::State_Sunken) {
-			color = option->palette.color(QPalette::Highlight).darker(110);
-		} else {
-			color = option->palette.color(QPalette::Button);
-		}
-	} else {
-		color = option->palette.color(QPalette::Button);
-		opacity = 0.5;
-	}
-
-	QConicalGradient gradient1(rect.center(), angle);
-	gradient1.setColorAt(0.0, shaded_color(color, -110));
-	gradient1.setColorAt(0.25, shaded_color(color, -30));
-	gradient1.setColorAt(0.5, shaded_color(color, 180));
-	gradient1.setColorAt(0.75, shaded_color(color, -30));
-	gradient1.setColorAt(1.0, shaded_color(color, -110));
-	painter->setBrush(color);
-	painter->drawEllipse(rect);
-	painter->setBrush(gradient1);
-#if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0))
-		// ### merge opacity into color
-		painter->setOpacity(opacity);
-#endif
-	painter->drawEllipse(rect);
-#if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0))
-		painter->setOpacity(1.0);
-	if (d > 2) {
-		QConicalGradient gradient2(rect.center(), angle);
-		gradient2.setColorAt(0.0, shaded_color(color, -40));
-		gradient2.setColorAt(0.25, shaded_color(color, 0));
-		gradient2.setColorAt(0.5, shaded_color(color, 210));
-		gradient2.setColorAt(0.75, shaded_color(color, 0));
-		gradient2.setColorAt(1.0, shaded_color(color, -40));
-		rect.adjust(1, 1, -1, -1);
-		painter->setBrush(color);
-		painter->drawEllipse(rect);
-		painter->setBrush(gradient2);
-		painter->setOpacity(opacity);
-		painter->drawEllipse(rect);
-		painter->setOpacity(1.0);
-		if (d > 8) {
-			QConicalGradient gradient3(rect.center(), angle);
-			gradient3.setColorAt(0.0, shaded_color(color, -10));
-			gradient3.setColorAt(0.25, shaded_color(color, 0));
-			gradient3.setColorAt(0.5, shaded_color(color, 180));
-			gradient3.setColorAt(0.75, shaded_color(color, 0));
-			gradient3.setColorAt(1.0, shaded_color(color, -10));
-			rect.adjust(2, 2, -2, -2);
-			painter->setBrush(color);
-			painter->drawEllipse(rect);
-			painter->setBrush(gradient3);
-			painter->setOpacity(opacity);
-			painter->drawEllipse(rect);
-			painter->setOpacity(1.0);
-		}
-	}
-#endif
-	painter->restore();
-}
-
-void
-paintCachedGrip(QPainter *painter, const QStyleOption *option, QPalette::ColorRole /*bgrole*/)
-{
-	bool useCache = UsePixmapCache;
-	QString pixmapName;
-
-	if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ option->rect.width() * option->rect.height() > 4096) {
-		useCache = false;
-	}
-	if (useCache) {
-		uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_Sunken | QStyle::State_HasFocus);
-		if (!(state & QStyle::State_Enabled)) {
-			state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus);
-		}
-		state &= ~(QStyle::State_HasFocus);
-				QByteArray colorName = option->palette.color(QPalette::Button).name().toLatin1();
-				pixmapName.sprintf("scp-isg-%x-%x-%s-%x-%x", state, option->direction, colorName.constData(), option->rect.width(), option->rect.height());
-	}
-	paintIndicatorCached(painter, option, paintGrip, useCache, pixmapName);
-}
-
-void
-QDialSkulptureStyle::drawComplexControl( ComplexControl cc,
-											  const QStyleOptionComplex *optc,
-											  QPainter *painter,
-											  const QWidget *widget) const
-{
-
-	if (cc != QStyle::CC_Dial) {
-		QCommonStyle::drawComplexControl(cc, optc, painter, widget);
-		return;
-	}
-
-	const QStyleOptionSlider *option = qstyleoption_cast<const QStyleOptionSlider *>(optc);
-	if (option == NULL)
-		return;
-
-	int d = qMin(option->rect.width() & ~1, option->rect.height() & ~1);
-	QStyleOptionSlider opt = *option;
-	const QAbstractSlider *slider = NULL;
-	// always highlight knob if pressed (even if mouse is not over knob)
-	if ((option->state & QStyle::State_HasFocus) && (slider = qobject_cast<const QAbstractSlider *>(widget))) {
-		if (slider->isSliderDown()) {
-			opt.state |= QStyle::State_MouseOver;
-		}
-	}
-
-	// tickmarks
-	opt.palette.setColor(QPalette::Inactive, QPalette::WindowText, QColor(80, 80, 80, 255));
-	opt.palette.setColor(QPalette::Active, QPalette::WindowText, QColor(80, 80, 80, 255));
-	opt.state &= ~QStyle::State_HasFocus;
-	opt.rect.setWidth(opt.rect.width() & ~1);
-	opt.rect.setHeight(opt.rect.height() & ~1);
-	//((QCommonStyle *) this)->
-	QCommonStyle::drawComplexControl(QStyle::CC_Dial, &opt, painter, widget);
-
-	// focus rectangle
-	if (option->state & QStyle::State_HasFocus) {
-		QStyleOptionFocusRect focus;
-		opt.state |= QStyle::State_HasFocus;
-		focus.QStyleOption::operator=(opt);
-		focus.rect.adjust(-1, -1, 1, 1);
-		//drawPrimitive(QStyle::PE_FrameFocusRect, &focus, painter, widget);
-	}
-	opt.palette = option->palette;
-
-	// dial base
-	if (d <= 256) {
-		paintIndicatorDial(painter, &opt);
-	} else {
-		// large dials are slow to render, do not render them
-	}
-
-	// dial knob
-	d -= 6;
-	int gripSize = (option->fontMetrics.height() / 4) * 2 - 1;
-	opt.rect.setSize(QSize(gripSize, gripSize));
-	opt.rect.moveCenter(option->rect.center());
-	// angle calculation from qcommonstyle.cpp (c) Trolltech 1992-2007, ASA.
-	qreal angle;
-	int sliderPosition = option->upsideDown ? option->sliderPosition : (option->maximum - option->sliderPosition);
-	int range = option->maximum - option->minimum;
-	if (!range) {
-		angle = M_PI / 2;
-	} else if (option->dialWrapping) {
-		angle = M_PI * 1.5 - (sliderPosition - option->minimum) * 2 * M_PI / range;
-	} else {
-		angle = (M_PI * 8 - (sliderPosition - option->minimum) * 10 * M_PI / range) / 6;
-	}
-
-	qreal rr = d / 2.0 - gripSize - 2;
-	opt.rect.translate(int(0.5 + rr * cos(angle)), int(0.5 - rr * sin(angle)));
-	paintCachedGrip(painter, &opt, option->state & QStyle::State_Enabled ? QPalette::Button : QPalette::Window);
-}
diff --git a/qmidiplayer.src.d/qdialskulpturestyle.hpp b/qmidiplayer.src.d/qdialskulpturestyle.hpp
deleted file mode 100644
index 2f3ba04..0000000
--- a/qmidiplayer.src.d/qdialskulpturestyle.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/******************************************************************************
-
-   Skulpture - Classical Three-Dimensional Artwork for Qt 4
-
-   Copyright (c) 2007-2009 Christoph Feck <christoph@maxiom.de>
-
-   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 QDIALSKULPTURESTYLE_H
-#define QDIALSKULPTURESTYLE_H
-
-#include <QCommonStyle>
-
-class QDialSkulptureStyle:public QCommonStyle
-{
-public:
-	QDialSkulptureStyle(){}
-	virtual ~QDialSkulptureStyle(){}
-
-	virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
-									const QWidget *widget=0) const;
-
-};
-
-#endif // QDIALSKULPTURESTYLE_H
diff --git a/qmidiplayer.src.d/qmpchanneleditor.cpp b/qmidiplayer.src.d/qmpchanneleditor.cpp
deleted file mode 100644
index f1d4e5e..0000000
--- a/qmidiplayer.src.d/qmpchanneleditor.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-#include <cstdio>
-#include "qmpchanneleditor.hpp"
-#include "ui_qmpchanneleditor.h"
-#include "qmpmainwindow.hpp"
-
-qmpChannelEditor::qmpChannelEditor(QWidget *parent) :
-	QDialog(parent),
-	ui(new Ui::qmpChannelEditor)
-{
-	ui->setupUi(this);
-	styl=new QDialSkulptureStyle();
-	QList<QDial*> dials=findChildren<QDial*>();
-	for(int i=0;i<dials.count();++i)
-		dials.at(i)->setStyle(styl);
-}
-
-qmpChannelEditor::~qmpChannelEditor()
-{
-	delete styl;
-	delete ui;
-}
-
-void qmpChannelEditor::setupWindow(int chid)
-{
-	char str[256];if(~chid)ch=chid;
-	sprintf(str,"Channel Parameter Editor - Channel #%d",ch+1);
-	setWindowTitle(str);
-	CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
-	int b,p;
-	player->getChannelPreset(ch,&b,&p,str);
-	ui->lbPresetName->setText(str);
-	sprintf(str,"BK: %d",b);ui->lbBank->setText(str);
-	sprintf(str,"PC: %d",p);ui->lbPreset->setText(str);
-	ui->lbChannelNumber->setText(QString::number(ch+1));
-#define setupControl(ccid,lb,d,ccname)\
-	b=player->getCC(ch,ccid);\
-	sprintf(str,"%s %d",ccname,b);\
-	ui->lb->setText(str);\
-	ui->d->setValue(b);
-	setupControl(7,lbVol,dVol,"Vol.");
-	setupControl(91,lbReverb,dReverb,"Rev.");
-	setupControl(93,lbChorus,dChorus,"Chr.");
-	setupControl(71,lbReso,dReso,"Res.");
-	setupControl(74,lbCut,dCut,"Cut.");
-	setupControl(73,lbAttack,dAttack,"Atk.");
-	setupControl(75,lbDecay,dDecay,"Dec.");
-	setupControl(72,lbRelease,dRelease,"Rel.");
-	setupControl(76,lbRate,dRate,"Rate");
-	setupControl(77,lbDepth,dDepth,"Dep.");
-	setupControl(78,lbDelay,dDelay,"Del.");
-	b=player->getCC(ch,10);
-	if(b==64)strcpy(str,"Pan. C");
-	else if(b<64)sprintf(str,"Pan. L%d",64-b);else sprintf(str,"Pan. R%d",b-64);
-	ui->lbPan->setText(str);
-	ui->dPan->setValue(b);
-}
-
-void qmpChannelEditor::sendCC()
-{
-	CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
-	player->setCC(ch,7,ui->dVol->value());
-	player->setCC(ch,10,ui->dPan->value());
-	player->setCC(ch,91,ui->dReverb->value());
-	player->setCC(ch,93,ui->dChorus->value());
-	player->setCC(ch,71,ui->dReso->value());
-	player->setCC(ch,74,ui->dCut->value());
-	player->setCC(ch,73,ui->dAttack->value());
-	player->setCC(ch,75,ui->dDecay->value());
-	player->setCC(ch,72,ui->dRelease->value());
-	player->setCC(ch,76,ui->dRate->value());
-	player->setCC(ch,77,ui->dDepth->value());
-	player->setCC(ch,78,ui->dDelay->value());
-}
-
-void qmpChannelEditor::showEvent(QShowEvent *e)
-{
-	knobpressed=0;
-	setupWindow();
-	connectSlots();
-	connect(qmpMainWindow::getInstance()->getTimer(),SIGNAL(timeout()),this,SLOT(setupWindow()));
-	e->accept();
-}
-void qmpChannelEditor::closeEvent(QCloseEvent *e)
-{
-	disconnectSlots();
-	disconnect(qmpMainWindow::getInstance()->getTimer(),SIGNAL(timeout()),this,SLOT(setupWindow()));
-	e->accept();
-}
-
-void qmpChannelEditor::on_pbChLeft_clicked()
-{
-	disconnectSlots();
-	if(ch>0)--ch;else ch=15;setupWindow();
-	connectSlots();
-}
-
-void qmpChannelEditor::on_pbChRight_clicked()
-{
-	disconnectSlots();
-	if(ch<15)++ch;else ch=0;setupWindow();
-	connectSlots();
-}
-
-void qmpChannelEditor::commonPressed()
-{disconnect(qmpMainWindow::getInstance()->getTimer(),SIGNAL(timeout()),this,SLOT(setupWindow()));knobpressed=1;}
-void qmpChannelEditor::commonReleased()
-{connect(qmpMainWindow::getInstance()->getTimer(),SIGNAL(timeout()),this,SLOT(setupWindow()));sendCC();knobpressed=0;}
-void qmpChannelEditor::commonChanged()
-{if(knobpressed){sendCC();setupWindow();}}
-
-void qmpChannelEditor::connectSlots()
-{
-	connect(ui->dCut,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	connect(ui->dReso,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	connect(ui->dReverb,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	connect(ui->dChorus,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	connect(ui->dVol,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	connect(ui->dPan,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	connect(ui->dAttack,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	connect(ui->dDecay,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	connect(ui->dRelease,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	connect(ui->dRate,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	connect(ui->dDepth,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	connect(ui->dDelay,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-
-	connect(ui->dCut,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	connect(ui->dReso,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	connect(ui->dReverb,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	connect(ui->dChorus,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	connect(ui->dVol,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	connect(ui->dPan,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	connect(ui->dAttack,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	connect(ui->dDecay,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	connect(ui->dRelease,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	connect(ui->dRate,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	connect(ui->dDepth,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	connect(ui->dDelay,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-
-	connect(ui->dCut,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	connect(ui->dReso,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	connect(ui->dReverb,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	connect(ui->dChorus,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	connect(ui->dVol,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	connect(ui->dPan,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	connect(ui->dAttack,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	connect(ui->dDecay,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	connect(ui->dRelease,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	connect(ui->dRate,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	connect(ui->dDepth,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	connect(ui->dDelay,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-}
-
-void qmpChannelEditor::disconnectSlots()
-{
-	disconnect(ui->dCut,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	disconnect(ui->dReso,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	disconnect(ui->dReverb,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	disconnect(ui->dChorus,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	disconnect(ui->dVol,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	disconnect(ui->dPan,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	disconnect(ui->dAttack,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	disconnect(ui->dDecay,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	disconnect(ui->dRelease,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	disconnect(ui->dRate,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	disconnect(ui->dDepth,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-	disconnect(ui->dDelay,SIGNAL(sliderPressed()),this,SLOT(commonPressed()));
-
-	disconnect(ui->dCut,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	disconnect(ui->dReso,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	disconnect(ui->dReverb,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	disconnect(ui->dChorus,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	disconnect(ui->dVol,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	disconnect(ui->dPan,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	disconnect(ui->dAttack,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	disconnect(ui->dDecay,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	disconnect(ui->dRelease,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	disconnect(ui->dRate,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	disconnect(ui->dDepth,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-	disconnect(ui->dDelay,SIGNAL(sliderReleased()),this,SLOT(commonReleased()));
-
-	disconnect(ui->dCut,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	disconnect(ui->dReso,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	disconnect(ui->dReverb,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	disconnect(ui->dChorus,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	disconnect(ui->dVol,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	disconnect(ui->dPan,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	disconnect(ui->dAttack,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	disconnect(ui->dDecay,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	disconnect(ui->dRelease,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	disconnect(ui->dRate,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	disconnect(ui->dDepth,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-	disconnect(ui->dDelay,SIGNAL(valueChanged(int)),this,SLOT(commonChanged()));
-}
diff --git a/qmidiplayer.src.d/qmpchanneleditor.hpp b/qmidiplayer.src.d/qmpchanneleditor.hpp
deleted file mode 100644
index 0653af5..0000000
--- a/qmidiplayer.src.d/qmpchanneleditor.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef QMPCHANNELEDITOR_H
-#define QMPCHANNELEDITOR_H
-
-#include <QDialog>
-#include <QShowEvent>
-#include <QCloseEvent>
-#include "qdialskulpturestyle.hpp"
-
-namespace Ui {
-	class qmpChannelEditor;
-}
-
-class qmpChannelEditor:public QDialog
-{
-	Q_OBJECT
-
-	public:
-		explicit qmpChannelEditor(QWidget *parent=0);
-		~qmpChannelEditor();
-	protected:
-		void showEvent(QShowEvent *e);
-		void closeEvent(QCloseEvent *e);
-	public slots:
-		void setupWindow(int chid=-1);
-
-	private slots:
-		void commonPressed();
-		void commonReleased();
-		void commonChanged();
-		void on_pbChLeft_clicked();
-		void on_pbChRight_clicked();
-
-	private:
-		Ui::qmpChannelEditor *ui;
-		int ch,knobpressed;
-		void sendCC();
-		void connectSlots();
-		void disconnectSlots();
-		QCommonStyle* styl;
-};
-
-#endif // QMPCHANNELEDITOR_H
diff --git a/qmidiplayer.src.d/qmpchanneleditor.ui b/qmidiplayer.src.d/qmpchanneleditor.ui
deleted file mode 100644
index 49e8c8e..0000000
--- a/qmidiplayer.src.d/qmpchanneleditor.ui
+++ /dev/null
@@ -1,602 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>qmpChannelEditor</class>
- <widget class="QDialog" name="qmpChannelEditor">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>422</width>
-    <height>300</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>422</width>
-    <height>300</height>
-   </size>
-  </property>
-  <property name="maximumSize">
-   <size>
-    <width>422</width>
-    <height>300</height>
-   </size>
-  </property>
-  <property name="windowTitle">
-   <string>Dialog</string>
-  </property>
-  <widget class="QPushButton" name="pbChLeft">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>10</y>
-     <width>21</width>
-     <height>21</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>&lt;</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="lbChannelNumber">
-   <property name="geometry">
-    <rect>
-     <x>30</x>
-     <y>10</y>
-     <width>21</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>1</string>
-   </property>
-   <property name="alignment">
-    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="pbChRight">
-   <property name="geometry">
-    <rect>
-     <x>50</x>
-     <y>10</y>
-     <width>21</width>
-     <height>21</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>&gt;</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="lbPresetName">
-   <property name="geometry">
-    <rect>
-     <x>90</x>
-     <y>10</y>
-     <width>261</width>
-     <height>51</height>
-    </rect>
-   </property>
-   <property name="font">
-    <font>
-     <pointsize>16</pointsize>
-    </font>
-   </property>
-   <property name="text">
-    <string>Yamaha Grand Piano</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="lbBank">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>30</y>
-     <width>81</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>BK: 0</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="lbPreset">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>50</y>
-     <width>81</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>PC: 0</string>
-   </property>
-  </widget>
-  <widget class="QGroupBox" name="gFilters">
-   <property name="geometry">
-    <rect>
-     <x>0</x>
-     <y>70</y>
-     <width>141</width>
-     <height>101</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>Filters</string>
-   </property>
-   <widget class="QLabel" name="lbReso">
-    <property name="geometry">
-     <rect>
-      <x>70</x>
-      <y>80</y>
-      <width>66</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Res. 64</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-   <widget class="QDial" name="dReso">
-    <property name="geometry">
-     <rect>
-      <x>80</x>
-      <y>30</y>
-      <width>50</width>
-      <height>51</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>127</number>
-    </property>
-    <property name="value">
-     <number>64</number>
-    </property>
-    <property name="notchesVisible">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QDial" name="dCut">
-    <property name="geometry">
-     <rect>
-      <x>10</x>
-      <y>30</y>
-      <width>50</width>
-      <height>51</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>127</number>
-    </property>
-    <property name="value">
-     <number>64</number>
-    </property>
-    <property name="notchesVisible">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QLabel" name="lbCut">
-    <property name="geometry">
-     <rect>
-      <x>0</x>
-      <y>80</y>
-      <width>71</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Cut.  64</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-  </widget>
-  <widget class="QGroupBox" name="gEffects">
-   <property name="geometry">
-    <rect>
-     <x>140</x>
-     <y>70</y>
-     <width>141</width>
-     <height>101</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>Effects</string>
-   </property>
-   <widget class="QLabel" name="lbChorus">
-    <property name="geometry">
-     <rect>
-      <x>70</x>
-      <y>80</y>
-      <width>66</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Chr. 64</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-   <widget class="QDial" name="dChorus">
-    <property name="geometry">
-     <rect>
-      <x>80</x>
-      <y>30</y>
-      <width>50</width>
-      <height>51</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>127</number>
-    </property>
-    <property name="value">
-     <number>64</number>
-    </property>
-    <property name="notchesVisible">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QDial" name="dReverb">
-    <property name="geometry">
-     <rect>
-      <x>10</x>
-      <y>30</y>
-      <width>50</width>
-      <height>51</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>127</number>
-    </property>
-    <property name="value">
-     <number>64</number>
-    </property>
-    <property name="notchesVisible">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QLabel" name="lbReverb">
-    <property name="geometry">
-     <rect>
-      <x>0</x>
-      <y>80</y>
-      <width>71</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Rev.  64</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-  </widget>
-  <widget class="QGroupBox" name="gEnvelope">
-   <property name="geometry">
-    <rect>
-     <x>0</x>
-     <y>170</y>
-     <width>211</width>
-     <height>101</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>Envelope</string>
-   </property>
-   <widget class="QLabel" name="lbDecay">
-    <property name="geometry">
-     <rect>
-      <x>70</x>
-      <y>80</y>
-      <width>66</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Dec. 64</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-   <widget class="QDial" name="dDecay">
-    <property name="geometry">
-     <rect>
-      <x>80</x>
-      <y>30</y>
-      <width>50</width>
-      <height>51</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>127</number>
-    </property>
-    <property name="value">
-     <number>64</number>
-    </property>
-    <property name="notchesVisible">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QDial" name="dAttack">
-    <property name="geometry">
-     <rect>
-      <x>10</x>
-      <y>30</y>
-      <width>50</width>
-      <height>51</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>127</number>
-    </property>
-    <property name="value">
-     <number>64</number>
-    </property>
-    <property name="notchesVisible">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QLabel" name="lbAttack">
-    <property name="geometry">
-     <rect>
-      <x>0</x>
-      <y>80</y>
-      <width>71</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Atk.  64</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-   <widget class="QDial" name="dRelease">
-    <property name="geometry">
-     <rect>
-      <x>150</x>
-      <y>30</y>
-      <width>50</width>
-      <height>51</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>127</number>
-    </property>
-    <property name="value">
-     <number>64</number>
-    </property>
-    <property name="notchesVisible">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QLabel" name="lbRelease">
-    <property name="geometry">
-     <rect>
-      <x>140</x>
-      <y>80</y>
-      <width>66</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Rel. 64</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-  </widget>
-  <widget class="QGroupBox" name="gVibrato">
-   <property name="geometry">
-    <rect>
-     <x>210</x>
-     <y>170</y>
-     <width>211</width>
-     <height>101</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>Vibrato</string>
-   </property>
-   <widget class="QLabel" name="lbDepth">
-    <property name="geometry">
-     <rect>
-      <x>70</x>
-      <y>80</y>
-      <width>66</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Dep. 64</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-   <widget class="QDial" name="dDepth">
-    <property name="geometry">
-     <rect>
-      <x>80</x>
-      <y>30</y>
-      <width>50</width>
-      <height>51</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>127</number>
-    </property>
-    <property name="value">
-     <number>64</number>
-    </property>
-    <property name="notchesVisible">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QDial" name="dRate">
-    <property name="geometry">
-     <rect>
-      <x>10</x>
-      <y>30</y>
-      <width>50</width>
-      <height>51</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>127</number>
-    </property>
-    <property name="value">
-     <number>64</number>
-    </property>
-    <property name="notchesVisible">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QLabel" name="lbRate">
-    <property name="geometry">
-     <rect>
-      <x>0</x>
-      <y>80</y>
-      <width>71</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Rate  64</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-   <widget class="QDial" name="dDelay">
-    <property name="geometry">
-     <rect>
-      <x>150</x>
-      <y>30</y>
-      <width>50</width>
-      <height>51</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>127</number>
-    </property>
-    <property name="value">
-     <number>64</number>
-    </property>
-    <property name="notchesVisible">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QLabel" name="lbDelay">
-    <property name="geometry">
-     <rect>
-      <x>140</x>
-      <y>80</y>
-      <width>66</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Del. 64</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-  </widget>
-  <widget class="QGroupBox" name="gMixer">
-   <property name="geometry">
-    <rect>
-     <x>280</x>
-     <y>70</y>
-     <width>141</width>
-     <height>101</height>
-    </rect>
-   </property>
-   <property name="title">
-    <string>Mixer</string>
-   </property>
-   <widget class="QLabel" name="lbPan">
-    <property name="geometry">
-     <rect>
-      <x>70</x>
-      <y>80</y>
-      <width>66</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Pan.  C</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-   <widget class="QDial" name="dPan">
-    <property name="geometry">
-     <rect>
-      <x>80</x>
-      <y>30</y>
-      <width>50</width>
-      <height>51</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>127</number>
-    </property>
-    <property name="value">
-     <number>64</number>
-    </property>
-    <property name="notchesVisible">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QLabel" name="lbVol">
-    <property name="geometry">
-     <rect>
-      <x>0</x>
-      <y>80</y>
-      <width>66</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Vol.  127</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-   <widget class="QDial" name="dVol">
-    <property name="geometry">
-     <rect>
-      <x>10</x>
-      <y>30</y>
-      <width>50</width>
-      <height>51</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>127</number>
-    </property>
-    <property name="value">
-     <number>127</number>
-    </property>
-    <property name="notchesVisible">
-     <bool>true</bool>
-    </property>
-   </widget>
-  </widget>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/qmidiplayer.src.d/qmpchannelswindow.cpp b/qmidiplayer.src.d/qmpchannelswindow.cpp
deleted file mode 100644
index a9cf60e..0000000
--- a/qmidiplayer.src.d/qmpchannelswindow.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-#include <QCheckBox>
-#include <QPushButton>
-#include <QComboBox>
-#include "qmpchannelswindow.hpp"
-#include "ui_qmpchannelswindow.h"
-#include "qmpmainwindow.hpp"
-
-qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) :
-	QDialog(parent),
-	ui(new Ui::qmpChannelsWindow)
-{
-	ui->setupUi(this);
-	pselectw=new qmpPresetSelector(this);
-	ceditw=new qmpChannelEditor(this);
-	connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed()));
-	for(int i=0;i<16;++i)
-	{
-		ui->twChannels->setCellWidget(i,0,new QCheckBox(""));
-		connect(ui->twChannels->cellWidget(i,0),SIGNAL(stateChanged(int)),this,SLOT(channelMSChanged()));
-		ui->twChannels->setCellWidget(i,1,new QCheckBox(""));
-		connect(ui->twChannels->cellWidget(i,1),SIGNAL(stateChanged(int)),this,SLOT(channelMSChanged()));
-		ui->twChannels->setCellWidget(i,2,new QComboBox());
-		QComboBox *cb=(QComboBox*)ui->twChannels->cellWidget(i,2);
-		//stub
-		cb->addItem("Internal FluidSynth");
-		ui->twChannels->setCellWidget(i,3,new QDCLabel(""));
-		((QDCLabel*)ui->twChannels->cellWidget(i,3))->setID(i);
-		connect(ui->twChannels->cellWidget(i,3),SIGNAL(onDoubleClick(int)),this,SLOT(showPresetWindow(int)));
-		ui->twChannels->setCellWidget(i,4,new QDCPushButton("..."));
-		((QDCLabel*)ui->twChannels->cellWidget(i,4))->setID(i);
-		connect(ui->twChannels->cellWidget(i,4),SIGNAL(onClick(int)),this,SLOT(showChannelEditorWindow(int)));
-	}
-	ui->twChannels->setColumnWidth(0,32);
-	ui->twChannels->setColumnWidth(1,32);
-	ui->twChannels->setColumnWidth(2,192);
-	ui->twChannels->setColumnWidth(3,192);
-	ui->twChannels->setColumnWidth(4,32);
-}
-
-void qmpChannelsWindow::showEvent(QShowEvent *event)
-{
-	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
-	{
-		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlWShown",1);
-	}
-	event->accept();
-}
-
-void qmpChannelsWindow::closeEvent(QCloseEvent *event)
-{
-	setVisible(false);
-	if(!qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
-	{
-		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlWShown",0);
-	}
-	emit dialogClosing();
-	event->accept();
-}
-
-void qmpChannelsWindow::moveEvent(QMoveEvent *event)
-{
-	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
-	{
-		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/ChnlW",event->pos());
-	}
-}
-
-void qmpChannelsWindow::channelWindowsUpdate()
-{
-	if(qmpMainWindow::getInstance()->getPlayer()->isFinished())
-	{
-		for(int i=0;i<16;++i)
-			((QLabel*)ui->twChannels->cellWidget(i,3))->setText("");
-		return;
-	}
-	for(int i=0;i<16;++i)
-	{
-		char data[128],nm[24];
-		int b,p;
-		qmpMainWindow::getInstance()->getPlayer()->getChannelPreset(i,&b,&p,nm);
-		sprintf(data,"%d:%d %s",b,p,nm);
-		((QLabel*)ui->twChannels->cellWidget(i,3))->setText(data);
-	}
-}
-
-void qmpChannelsWindow::channelMSChanged()
-{
-	for(int i=0;i<16;++i)
-	{
-		QCheckBox *m,*s;
-		m=(QCheckBox*)ui->twChannels->cellWidget(i,0);
-		s=(QCheckBox*)ui->twChannels->cellWidget(i,1);
-		if(m->isChecked()&&s->isChecked())s->setChecked(false);
-		qmpMainWindow::getInstance()->getPlayer()->setMute(i,m->isChecked());
-		qmpMainWindow::getInstance()->getPlayer()->setSolo(i,s->isChecked());
-	}
-}
-
-qmpChannelsWindow::~qmpChannelsWindow()
-{
-	delete ui;
-}
-
-void qmpChannelsWindow::on_pbUnmute_clicked()
-{
-	for(int i=0;i<16;++i)
-	{
-		((QCheckBox*)ui->twChannels->cellWidget(i,0))->setChecked(false);
-		qmpMainWindow::getInstance()->getPlayer()->setMute(i,false);
-	}
-}
-
-void qmpChannelsWindow::on_pbUnsolo_clicked()
-{
-	for(int i=0;i<16;++i)
-	{
-		((QCheckBox*)ui->twChannels->cellWidget(i,1))->setChecked(false);
-		qmpMainWindow::getInstance()->getPlayer()->setSolo(i,false);
-	}
-}
-
-void qmpChannelsWindow::showPresetWindow(int chid)
-{
-	pselectw->show();
-	pselectw->setupWindow(chid);
-}
-
-void qmpChannelsWindow::showChannelEditorWindow(int chid)
-{
-	ceditw->show();
-	ceditw->setupWindow(chid);
-}
diff --git a/qmidiplayer.src.d/qmpchannelswindow.hpp b/qmidiplayer.src.d/qmpchannelswindow.hpp
deleted file mode 100644
index f0591b6..0000000
--- a/qmidiplayer.src.d/qmpchannelswindow.hpp
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef QMPCHANNELSWINDOW_H
-#define QMPCHANNELSWINDOW_H
-
-#include <QLabel>
-#include <QPushButton>
-#include <QDialog>
-#include <QShowEvent>
-#include <QCloseEvent>
-#include <QMoveEvent>
-#include "qmppresetselect.hpp"
-#include "qmpchanneleditor.hpp"
-
-namespace Ui {
-	class qmpChannelsWindow;
-}
-
-class QDCLabel:public QLabel
-{
-	Q_OBJECT
-	private:
-		int id;
-	protected:
-		void mouseDoubleClickEvent(QMouseEvent *event){event->accept();emit onDoubleClick(id);}
-	public:
-		QDCLabel(QString s):QLabel(s){id=-1;}
-		void setID(int _id){id=_id;}
-	signals:
-		void onDoubleClick(int id);
-};
-
-class QDCPushButton:public QPushButton
-{
-	Q_OBJECT
-	private:
-		int id;
-	protected:
-		void mousePressEvent(QMouseEvent *event){QPushButton::mousePressEvent(event);emit onClick(id);}
-	public:
-		QDCPushButton(QString s):QPushButton(s){id=-1;}
-		void setID(int _id){id=_id;}
-	signals:
-		void onClick(int id);
-};
-
-class qmpChannelsWindow:public QDialog
-{
-	Q_OBJECT
-
-	public:
-		explicit qmpChannelsWindow(QWidget *parent = 0);
-		~qmpChannelsWindow();
-		void showEvent(QShowEvent *event);
-		void closeEvent(QCloseEvent *event);
-		void moveEvent(QMoveEvent *event);
-	signals:
-		void dialogClosing();
-	public slots:
-		void channelWindowsUpdate();
-		void channelMSChanged();
-		void showPresetWindow(int chid);
-		void showChannelEditorWindow(int chid);
-		void on_pbUnmute_clicked();
-		void on_pbUnsolo_clicked();
-
-	private:
-		Ui::qmpChannelsWindow *ui;
-		qmpPresetSelector *pselectw;
-		qmpChannelEditor *ceditw;
-};
-
-#endif // QMPCHANNELSWINDOW_H
diff --git a/qmidiplayer.src.d/qmpchannelswindow.ui b/qmidiplayer.src.d/qmpchannelswindow.ui
deleted file mode 100644
index a8b43cb..0000000
--- a/qmidiplayer.src.d/qmpchannelswindow.ui
+++ /dev/null
@@ -1,146 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>qmpChannelsWindow</class>
- <widget class="QDialog" name="qmpChannelsWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>580</width>
-    <height>410</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>580</width>
-    <height>410</height>
-   </size>
-  </property>
-  <property name="maximumSize">
-   <size>
-    <width>580</width>
-    <height>16777215</height>
-   </size>
-  </property>
-  <property name="windowTitle">
-   <string>Channels</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout_4">
-   <item>
-    <layout class="QVBoxLayout" name="verticalLayout_1">
-     <item>
-      <widget class="QTableWidget" name="twChannels">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="alternatingRowColors">
-        <bool>true</bool>
-       </property>
-       <property name="selectionMode">
-        <enum>QAbstractItemView::NoSelection</enum>
-       </property>
-       <property name="cornerButtonEnabled">
-        <bool>false</bool>
-       </property>
-       <property name="rowCount">
-        <number>16</number>
-       </property>
-       <property name="columnCount">
-        <number>5</number>
-       </property>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <row/>
-       <column>
-        <property name="text">
-         <string>M</string>
-        </property>
-       </column>
-       <column>
-        <property name="text">
-         <string>S</string>
-        </property>
-       </column>
-       <column>
-        <property name="text">
-         <string>Device</string>
-        </property>
-       </column>
-       <column>
-        <property name="text">
-         <string>Preset</string>
-        </property>
-       </column>
-       <column>
-        <property name="text">
-         <string>...</string>
-        </property>
-       </column>
-       <item row="0" column="0">
-        <property name="text">
-         <string/>
-        </property>
-       </item>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QPushButton" name="pbSave">
-       <property name="text">
-        <string>Save</string>
-       </property>
-       <property name="iconSize">
-        <size>
-         <width>16</width>
-         <height>16</height>
-        </size>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="pbLoad">
-       <property name="text">
-        <string>Load</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="pbUnmute">
-       <property name="text">
-        <string>Unmute All</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="pbUnsolo">
-       <property name="text">
-        <string>Unsolo All</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/qmidiplayer.src.d/qmpefxwindow.cpp b/qmidiplayer.src.d/qmpefxwindow.cpp
deleted file mode 100644
index 7d9c08e..0000000
--- a/qmidiplayer.src.d/qmpefxwindow.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-#include <cmath>
-#include "qmpefxwindow.hpp"
-#include "ui_qmpefxwindow.h"
-#include "qmpmainwindow.hpp"
-
-qmpEfxWindow::qmpEfxWindow(QWidget *parent) :
-	QDialog(parent),
-	ui(new Ui::qmpEfxWindow)
-{
-	ui->setupUi(this);initialized=false;
-	styl=new QDialSkulptureStyle();
-	QList<QDial*> dials=findChildren<QDial*>();
-	for(int i=0;i<dials.count();++i)
-		dials.at(i)->setStyle(styl);
-	connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed()));
-	//stub. read these from settings after the setting module is implemented
-	QSettings *settings=qmpSettingsWindow::getSettingsIntf();
-	ui->cbEnabledC->setChecked(settings->value("Effects/ChorusEnabled",1).toInt());
-	ui->cbEnabledR->setChecked(settings->value("Effects/ReverbEnabled",1).toInt());
-	rr=settings->value("Effects/ReverbRoom",FLUID_REVERB_DEFAULT_ROOMSIZE).toDouble();
-	rd=settings->value("Effects/ReverbDamp",FLUID_REVERB_DEFAULT_DAMP).toDouble();
-	rw=settings->value("Effects/ReverbWidth",FLUID_REVERB_DEFAULT_WIDTH).toDouble();
-	rl=settings->value("Effects/ReverbLevel",FLUID_REVERB_DEFAULT_LEVEL).toDouble();
-
-	cfb=settings->value("Effects/ChorusFeedbk",FLUID_CHORUS_DEFAULT_N).toInt();
-	cl=settings->value("Effects/ChorusLevel",FLUID_CHORUS_DEFAULT_LEVEL).toDouble();
-	cr=settings->value("Effects/ChorusRate",FLUID_CHORUS_DEFAULT_SPEED).toDouble();
-	cd=settings->value("Effects/ChorusDepth",FLUID_CHORUS_DEFAULT_DEPTH).toDouble();
-	ct=settings->value("Effects/ChorusType",FLUID_CHORUS_DEFAULT_TYPE).toInt();
-}
-
-qmpEfxWindow::~qmpEfxWindow()
-{
-	delete styl;
-	delete ui;
-}
-
-void qmpEfxWindow::closeEvent(QCloseEvent *event)
-{
-	setVisible(false);
-	if(!qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
-	{
-		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxWShown",0);
-	}
-	emit dialogClosing();
-	event->accept();
-}
-
-void qmpEfxWindow::showEvent(QShowEvent *event)
-{
-	//CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
-	//These parameters will never be modified outside this window...
-	/*if(initialized)
-	{
-		player->getReverbPara(&rr,&rd,&rw,&rl);
-		player->getChorusPara(&cfb,&cl,&cr,&cd,&ct);
-	}*/
-	ui->sbRoom->setValue((int)round(rr*100));ui->dRoom->setValue((int)round(rr*100));
-	ui->sbDamp->setValue((int)round(rd*100));ui->dDamp->setValue((int)round(rd*100));
-	ui->sbWidth->setValue((int)round(rw*100));ui->dWidth->setValue((int)round(rw*100));
-	ui->sbLevelR->setValue((int)round(rl*100));ui->dLevelR->setValue((int)round(rl*100));
-
-	ui->sbFeedBack->setValue(cfb);ui->dFeedBack->setValue(cfb);
-	ui->sbRate->setValue(cr);ui->dRate->setValue((int)round(cr*100));
-	ui->sbDepth->setValue(cd);ui->dDepth->setValue((int)round(cd*10));
-	ui->sbLevelC->setValue((int)round(cl*100));ui->dLevelC->setValue((int)round(cl*100));
-	if(ct==FLUID_CHORUS_MOD_SINE)ui->rbSine->setChecked(true),ui->rbTriangle->setChecked(false);
-	if(ct==FLUID_CHORUS_MOD_TRIANGLE)ui->rbSine->setChecked(false),ui->rbTriangle->setChecked(true);
-	initialized=true;
-	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
-	{
-		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxWShown",1);
-	}
-	event->accept();
-}
-
-void qmpEfxWindow::moveEvent(QMoveEvent *event)
-{
-	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
-	{
-		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/EfxW",event->pos());
-	}
-}
-
-void qmpEfxWindow::sendEfxChange()
-{
-	if(!qmpMainWindow::getInstance()||!initialized)return;
-	rr=ui->sbRoom->value()/100.;rd=ui->sbDamp->value()/100.;
-	rw=ui->sbWidth->value()/100.;rl=ui->sbLevelR->value()/100.;
-	ct=ui->rbSine->isChecked()?FLUID_CHORUS_MOD_SINE:FLUID_CHORUS_MOD_TRIANGLE;
-	cfb=ui->sbFeedBack->value();cl=ui->sbLevelC->value()/100.;
-	cr=ui->sbRate->value();cd=ui->sbDepth->value();
-	CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
-	player->setReverbPara(ui->cbEnabledR->isChecked()?1:0,rr,rd,rw,rl);
-	player->setChorusPara(ui->cbEnabledC->isChecked()?1:0,cfb,cl,cr,cd,ct);
-
-	QSettings *settings=qmpSettingsWindow::getSettingsIntf();
-	settings->setValue("Effects/ChorusEnabled",ui->cbEnabledC->isChecked()?1:0);
-	settings->setValue("Effects/ReverbEnabled",ui->cbEnabledR->isChecked()?1:0);
-	settings->setValue("Effects/ReverbRoom",rr);
-	settings->setValue("Effects/ReverbDamp",rd);
-	settings->setValue("Effects/ReverbWidth",rw);
-	settings->setValue("Effects/ReverbLevel",rl);
-
-	settings->setValue("Effects/ChorusFeedbk",cfb);
-	settings->setValue("Effects/ChorusLevel",cl);
-	settings->setValue("Effects/ChorusRate",cr);
-	settings->setValue("Effects/ChorusDepth",cd);
-	settings->setValue("Effects/ChorusType",ct);
-}
-
-void qmpEfxWindow::dailValueChange()
-{
-	if(!initialized)return;
-	ui->sbRoom->setValue(ui->dRoom->value());
-	ui->sbDamp->setValue(ui->dDamp->value());
-	ui->sbWidth->setValue(ui->dWidth->value());
-	ui->sbLevelR->setValue(ui->dLevelR->value());
-	ui->sbFeedBack->setValue(ui->dFeedBack->value());
-	ui->sbRate->setValue(ui->dRate->value()/100.);
-	ui->sbDepth->setValue(ui->dDepth->value()/10.);
-	ui->sbLevelC->setValue(ui->dLevelC->value());
-	sendEfxChange();
-}
-
-void qmpEfxWindow::spinValueChange()
-{
-	if(!initialized)return;
-	ui->dRoom->setValue(ui->sbRoom->value());
-	ui->dDamp->setValue(ui->sbDamp->value());
-	ui->dWidth->setValue(ui->sbWidth->value());
-	ui->dLevelR->setValue(ui->sbLevelR->value());
-	ui->dFeedBack->setValue(ui->sbFeedBack->value());
-	ui->dRate->setValue((int)(ui->sbRate->value()*100));
-	ui->dDepth->setValue((int)(ui->sbDepth->value()*10));
-	ui->dLevelC->setValue(ui->sbLevelC->value());
-	sendEfxChange();
-}
-
-void qmpEfxWindow::on_dRoom_valueChanged()
-{dailValueChange();}
-
-void qmpEfxWindow::on_dDamp_valueChanged()
-{dailValueChange();}
-
-void qmpEfxWindow::on_dWidth_valueChanged()
-{dailValueChange();}
-
-void qmpEfxWindow::on_dLevelR_valueChanged()
-{dailValueChange();}
-
-void qmpEfxWindow::on_dFeedBack_valueChanged()
-{dailValueChange();}
-
-void qmpEfxWindow::on_dRate_valueChanged()
-{dailValueChange();}
-
-void qmpEfxWindow::on_dDepth_valueChanged()
-{dailValueChange();}
-
-void qmpEfxWindow::on_dLevelC_valueChanged()
-{dailValueChange();}
-
-void qmpEfxWindow::on_sbRoom_valueChanged(QString s)
-{s=QString();spinValueChange();}
-
-void qmpEfxWindow::on_sbDamp_valueChanged(QString s)
-{s=QString();spinValueChange();}
-
-void qmpEfxWindow::on_sbWidth_valueChanged(QString s)
-{s=QString();spinValueChange();}
-
-void qmpEfxWindow::on_sbLevelR_valueChanged(QString s)
-{s=QString();spinValueChange();}
-
-void qmpEfxWindow::on_sbFeedBack_valueChanged(QString s)
-{s=QString();spinValueChange();}
-
-void qmpEfxWindow::on_sbRate_valueChanged(QString s)
-{s=QString();spinValueChange();}
-
-void qmpEfxWindow::on_sbDepth_valueChanged(QString s)
-{s=QString();spinValueChange();}
-
-void qmpEfxWindow::on_sbLevelC_valueChanged(QString s)
-{s=QString();spinValueChange();}
-
-void qmpEfxWindow::on_cbEnabledC_stateChanged()
-{sendEfxChange();}
-
-void qmpEfxWindow::on_cbEnabledR_stateChanged()
-{sendEfxChange();}
-
-void qmpEfxWindow::on_rbSine_toggled()
-{sendEfxChange();}
-
-void qmpEfxWindow::on_rbTriangle_toggled()
-{sendEfxChange();}
diff --git a/qmidiplayer.src.d/qmpefxwindow.hpp b/qmidiplayer.src.d/qmpefxwindow.hpp
deleted file mode 100644
index 2a080f0..0000000
--- a/qmidiplayer.src.d/qmpefxwindow.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef QMPEFXWINDOW_HPP
-#define QMPEFXWINDOW_HPP
-
-#include <QDialog>
-#include <QCloseEvent>
-#include <QShowEvent>
-#include <QMoveEvent>
-
-#include "qdialskulpturestyle.hpp"
-
-namespace Ui {
-	class qmpEfxWindow;
-}
-
-class qmpEfxWindow : public QDialog
-{
-	Q_OBJECT
-
-	public:
-		explicit qmpEfxWindow(QWidget *parent=0);
-		~qmpEfxWindow();
-		void closeEvent(QCloseEvent *event);
-		void showEvent(QShowEvent *event);
-		void moveEvent(QMoveEvent *event);
-		void sendEfxChange();
-
-	signals:
-		void dialogClosing();
-
-	private slots:
-		void on_dRoom_valueChanged();
-		void on_dDamp_valueChanged();
-		void on_dWidth_valueChanged();
-		void on_dLevelR_valueChanged();
-		void on_dFeedBack_valueChanged();
-		void on_dRate_valueChanged();
-		void on_dDepth_valueChanged();
-		void on_dLevelC_valueChanged();
-		void on_sbRoom_valueChanged(QString s);
-		void on_sbDamp_valueChanged(QString s);
-		void on_sbWidth_valueChanged(QString s);
-		void on_sbLevelR_valueChanged(QString s);
-		void on_sbFeedBack_valueChanged(QString s);
-		void on_sbRate_valueChanged(QString s);
-		void on_sbDepth_valueChanged(QString s);
-		void on_sbLevelC_valueChanged(QString s);
-		void on_cbEnabledC_stateChanged();
-		void on_cbEnabledR_stateChanged();
-		void on_rbSine_toggled();
-		void on_rbTriangle_toggled();
-
-	private:
-		void dailValueChange();
-		void spinValueChange();
-		Ui::qmpEfxWindow *ui;
-		double rr,rd,rw,rl;
-		int cfb,ct,initialized;
-		double cl,cr,cd;
-		QCommonStyle* styl;
-};
-
-#endif // QMPEFXWINDOW_HPP
diff --git a/qmidiplayer.src.d/qmpefxwindow.ui b/qmidiplayer.src.d/qmpefxwindow.ui
deleted file mode 100644
index 4a1e0c6..0000000
--- a/qmidiplayer.src.d/qmpefxwindow.ui
+++ /dev/null
@@ -1,478 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>qmpEfxWindow</class>
- <widget class="QDialog" name="qmpEfxWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>546</width>
-    <height>177</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>546</width>
-    <height>177</height>
-   </size>
-  </property>
-  <property name="maximumSize">
-   <size>
-    <width>546</width>
-    <height>177</height>
-   </size>
-  </property>
-  <property name="windowTitle">
-   <string>Effects</string>
-  </property>
-  <layout class="QHBoxLayout" name="horizontalLayout">
-   <item>
-    <widget class="QGroupBox" name="gReverb">
-     <property name="title">
-      <string>Reverb</string>
-     </property>
-     <widget class="QCheckBox" name="cbEnabledR">
-      <property name="geometry">
-       <rect>
-        <x>80</x>
-        <y>4</y>
-        <width>21</width>
-        <height>24</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string/>
-      </property>
-     </widget>
-     <widget class="QDial" name="dRoom">
-      <property name="geometry">
-       <rect>
-        <x>10</x>
-        <y>30</y>
-        <width>50</width>
-        <height>51</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>120</number>
-      </property>
-      <property name="notchesVisible">
-       <bool>true</bool>
-      </property>
-     </widget>
-     <widget class="QDial" name="dDamp">
-      <property name="geometry">
-       <rect>
-        <x>200</x>
-        <y>30</y>
-        <width>50</width>
-        <height>51</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>100</number>
-      </property>
-      <property name="notchesVisible">
-       <bool>true</bool>
-      </property>
-     </widget>
-     <widget class="QDial" name="dWidth">
-      <property name="geometry">
-       <rect>
-        <x>10</x>
-        <y>103</y>
-        <width>50</width>
-        <height>51</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>100</number>
-      </property>
-      <property name="notchesVisible">
-       <bool>true</bool>
-      </property>
-     </widget>
-     <widget class="QDial" name="dLevelR">
-      <property name="geometry">
-       <rect>
-        <x>200</x>
-        <y>103</y>
-        <width>50</width>
-        <height>51</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>100</number>
-      </property>
-      <property name="notchesVisible">
-       <bool>true</bool>
-      </property>
-     </widget>
-     <widget class="QLabel" name="lbRoom">
-      <property name="geometry">
-       <rect>
-        <x>60</x>
-        <y>30</y>
-        <width>41</width>
-        <height>20</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string>Room</string>
-      </property>
-     </widget>
-     <widget class="QSpinBox" name="sbRoom">
-      <property name="geometry">
-       <rect>
-        <x>60</x>
-        <y>50</y>
-        <width>51</width>
-        <height>21</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>120</number>
-      </property>
-     </widget>
-     <widget class="QLabel" name="lbDamp">
-      <property name="geometry">
-       <rect>
-        <x>140</x>
-        <y>30</y>
-        <width>51</width>
-        <height>20</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string>Damp</string>
-      </property>
-      <property name="alignment">
-       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-      </property>
-     </widget>
-     <widget class="QSpinBox" name="sbDamp">
-      <property name="geometry">
-       <rect>
-        <x>140</x>
-        <y>50</y>
-        <width>56</width>
-        <height>21</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>100</number>
-      </property>
-     </widget>
-     <widget class="QLabel" name="lbWidth">
-      <property name="geometry">
-       <rect>
-        <x>60</x>
-        <y>100</y>
-        <width>51</width>
-        <height>20</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string>Width</string>
-      </property>
-     </widget>
-     <widget class="QSpinBox" name="sbWidth">
-      <property name="geometry">
-       <rect>
-        <x>60</x>
-        <y>120</y>
-        <width>56</width>
-        <height>21</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>100</number>
-      </property>
-     </widget>
-     <widget class="QLabel" name="lbLevelR">
-      <property name="geometry">
-       <rect>
-        <x>145</x>
-        <y>100</y>
-        <width>51</width>
-        <height>20</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string>Level</string>
-      </property>
-      <property name="alignment">
-       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-      </property>
-     </widget>
-     <widget class="QSpinBox" name="sbLevelR">
-      <property name="geometry">
-       <rect>
-        <x>140</x>
-        <y>120</y>
-        <width>56</width>
-        <height>21</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>100</number>
-      </property>
-     </widget>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="gChorus">
-     <property name="title">
-      <string>Chorus</string>
-     </property>
-     <widget class="QCheckBox" name="cbEnabledC">
-      <property name="geometry">
-       <rect>
-        <x>80</x>
-        <y>4</y>
-        <width>21</width>
-        <height>24</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string/>
-      </property>
-     </widget>
-     <widget class="QDial" name="dFeedBack">
-      <property name="geometry">
-       <rect>
-        <x>10</x>
-        <y>30</y>
-        <width>50</width>
-        <height>51</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>99</number>
-      </property>
-      <property name="notchesVisible">
-       <bool>true</bool>
-      </property>
-     </widget>
-     <widget class="QDial" name="dRate">
-      <property name="geometry">
-       <rect>
-        <x>200</x>
-        <y>30</y>
-        <width>50</width>
-        <height>51</height>
-       </rect>
-      </property>
-      <property name="minimum">
-       <number>29</number>
-      </property>
-      <property name="maximum">
-       <number>500</number>
-      </property>
-      <property name="value">
-       <number>29</number>
-      </property>
-      <property name="notchesVisible">
-       <bool>true</bool>
-      </property>
-     </widget>
-     <widget class="QDial" name="dDepth">
-      <property name="geometry">
-       <rect>
-        <x>10</x>
-        <y>103</y>
-        <width>50</width>
-        <height>51</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>210</number>
-      </property>
-      <property name="notchesVisible">
-       <bool>true</bool>
-      </property>
-     </widget>
-     <widget class="QDial" name="dLevelC">
-      <property name="geometry">
-       <rect>
-        <x>200</x>
-        <y>103</y>
-        <width>50</width>
-        <height>51</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>100</number>
-      </property>
-      <property name="notchesVisible">
-       <bool>true</bool>
-      </property>
-     </widget>
-     <widget class="QLabel" name="lbFeedBack">
-      <property name="geometry">
-       <rect>
-        <x>60</x>
-        <y>30</y>
-        <width>71</width>
-        <height>20</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string>Feedback</string>
-      </property>
-     </widget>
-     <widget class="QSpinBox" name="sbFeedBack">
-      <property name="geometry">
-       <rect>
-        <x>60</x>
-        <y>50</y>
-        <width>51</width>
-        <height>21</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>99</number>
-      </property>
-     </widget>
-     <widget class="QLabel" name="lbRate">
-      <property name="geometry">
-       <rect>
-        <x>140</x>
-        <y>30</y>
-        <width>51</width>
-        <height>20</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string>Rate</string>
-      </property>
-      <property name="alignment">
-       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-      </property>
-     </widget>
-     <widget class="QLabel" name="lbDepth">
-      <property name="geometry">
-       <rect>
-        <x>60</x>
-        <y>100</y>
-        <width>51</width>
-        <height>20</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string>Depth</string>
-      </property>
-     </widget>
-     <widget class="QLabel" name="lbLevelC">
-      <property name="geometry">
-       <rect>
-        <x>145</x>
-        <y>100</y>
-        <width>51</width>
-        <height>20</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string>Level</string>
-      </property>
-      <property name="alignment">
-       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-      </property>
-     </widget>
-     <widget class="QSpinBox" name="sbLevelC">
-      <property name="geometry">
-       <rect>
-        <x>140</x>
-        <y>120</y>
-        <width>56</width>
-        <height>21</height>
-       </rect>
-      </property>
-      <property name="maximum">
-       <number>100</number>
-      </property>
-     </widget>
-     <widget class="QDoubleSpinBox" name="sbRate">
-      <property name="geometry">
-       <rect>
-        <x>137</x>
-        <y>50</y>
-        <width>61</width>
-        <height>21</height>
-       </rect>
-      </property>
-      <property name="minimum">
-       <double>0.290000000000000</double>
-      </property>
-      <property name="maximum">
-       <double>5.000000000000000</double>
-      </property>
-      <property name="singleStep">
-       <double>0.100000000000000</double>
-      </property>
-     </widget>
-     <widget class="QLabel" name="lbLFO">
-      <property name="geometry">
-       <rect>
-        <x>35</x>
-        <y>77</y>
-        <width>41</width>
-        <height>20</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string>LFO</string>
-      </property>
-     </widget>
-     <widget class="QRadioButton" name="rbSine">
-      <property name="geometry">
-       <rect>
-        <x>70</x>
-        <y>77</y>
-        <width>61</width>
-        <height>20</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string>Sine</string>
-      </property>
-     </widget>
-     <widget class="QRadioButton" name="rbTriangle">
-      <property name="geometry">
-       <rect>
-        <x>145</x>
-        <y>77</y>
-        <width>91</width>
-        <height>20</height>
-       </rect>
-      </property>
-      <property name="text">
-       <string>Trian&amp;gle</string>
-      </property>
-     </widget>
-     <widget class="QDoubleSpinBox" name="sbDepth">
-      <property name="geometry">
-       <rect>
-        <x>60</x>
-        <y>120</y>
-        <width>51</width>
-        <height>21</height>
-       </rect>
-      </property>
-      <property name="decimals">
-       <number>1</number>
-      </property>
-      <property name="maximum">
-       <double>21.000000000000000</double>
-      </property>
-      <property name="singleStep">
-       <double>0.100000000000000</double>
-      </property>
-     </widget>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/qmidiplayer.src.d/qmphelpwindow.cpp b/qmidiplayer.src.d/qmphelpwindow.cpp
deleted file mode 100644
index 10cf083..0000000
--- a/qmidiplayer.src.d/qmphelpwindow.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <fluidsynth.h>
-#include "qmphelpwindow.hpp"
-#include "ui_qmphelpwindow.h"
-
-qmpHelpWindow::qmpHelpWindow(QWidget *parent) :
-	QDialog(parent),
-	ui(new Ui::qmpHelpWindow)
-{
-	ui->setupUi(this);
-	ui->textBrowser->setSearchPaths(QStringList(QString(":/doc"))+QStringList(QString(":/img")));
-	ui->textBrowser->setSource(QUrl("qrc:///doc/index.html"));
-}
-
-qmpHelpWindow::~qmpHelpWindow()
-{
-	delete ui;
-}
-
-void qmpHelpWindow::on_textBrowser_sourceChanged(const QUrl &src)
-{
-	if(src.fileName()==QString("version.html"))
-	{
-		QString s=ui->textBrowser->toHtml();
-		s.replace("CT_QT_VERSION_STR",QT_VERSION_STR);
-		s.replace("RT_QT_VERSION_STR",qVersion());
-		s.replace("CT_FLUIDSYNTH_VERSION",FLUIDSYNTH_VERSION);
-		s.replace("RT_FLUIDSYNTH_VERSION",fluid_version_str());
-		s.replace("APP_VERSION",APP_VERSION);
-		ui->textBrowser->setHtml(s);
-	}
-}
diff --git a/qmidiplayer.src.d/qmphelpwindow.hpp b/qmidiplayer.src.d/qmphelpwindow.hpp
deleted file mode 100644
index c2052b2..0000000
--- a/qmidiplayer.src.d/qmphelpwindow.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef QMPHELPWINDOW_H
-#define QMPHELPWINDOW_H
-
-#include <QDialog>
-#define APP_VERSION "0.7.0"
-
-namespace Ui {
-	class qmpHelpWindow;
-}
-
-class qmpHelpWindow : public QDialog
-{
-	Q_OBJECT
-
-	public:
-	explicit qmpHelpWindow(QWidget *parent = 0);
-	~qmpHelpWindow();
-
-	private slots:
-	void on_textBrowser_sourceChanged(const QUrl &src);
-
-	private:
-	Ui::qmpHelpWindow *ui;
-};
-
-#endif // QMPHELPWINDOW_H
diff --git a/qmidiplayer.src.d/qmphelpwindow.ui b/qmidiplayer.src.d/qmphelpwindow.ui
deleted file mode 100644
index fd21b5f..0000000
--- a/qmidiplayer.src.d/qmphelpwindow.ui
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>qmpHelpWindow</class>
- <widget class="QDialog" name="qmpHelpWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>640</width>
-    <height>360</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>640</width>
-    <height>360</height>
-   </size>
-  </property>
-  <property name="windowTitle">
-   <string>Help</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <widget class="QTextBrowser" name="textBrowser">
-     <property name="openExternalLinks">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/qmidiplayer.src.d/qmpimidimapper.hpp b/qmidiplayer.src.d/qmpimidimapper.hpp
deleted file mode 100644
index d35dbb9..0000000
--- a/qmidiplayer.src.d/qmpimidimapper.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef QMPIMIDIMAPPER_H
-#define QMPIMIDIMAPPER_H
-class qmpIMidiMapper
-{
-	virtual void deviceInit(int id)=0;
-	virtual void deviceDeinit(int id)=0;
-	virtual void noteOn(int ch,int key,int vel)=0;
-	virtual void noteOff(int ch,int key)=0;
-	virtual void ctrlChange(int ch,int cc,int val)=0;
-	virtual void progChange(int ch,int val)=0;
-	virtual void pitchBend(int ch,int val)=0;
-	virtual void sysEx(int length,const char* data)=0;
-	virtual static int enumDevices()=0;
-	virtual static char* deviceName(int id)=0;
-};
-#endif // QMPIMIDIMAPPER_H
diff --git a/qmidiplayer.src.d/qmpinfowindow.cpp b/qmidiplayer.src.d/qmpinfowindow.cpp
deleted file mode 100644
index 689a756..0000000
--- a/qmidiplayer.src.d/qmpinfowindow.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <QTextCodec>
-#include "qmpinfowindow.hpp"
-#include "ui_qmpinfowindow.h"
-#include "qmpmainwindow.hpp"
-#include "qmpsettingswindow.hpp"
-
-const char* minors="abebbbf c g d a e b f#c#g#d#a#";
-const char* majors="CbGbDbAbEbBbF C G D A E B F#C#";
-const char* standards="?  GM GM2GS XG ";
-
-qmpInfoWindow::qmpInfoWindow(QWidget *parent) :
-	QDialog(parent),
-	ui(new Ui::qmpInfoWindow)
-{
-	ui->setupUi(this);
-}
-
-qmpInfoWindow::~qmpInfoWindow()
-{
-	delete ui;
-}
-
-void qmpInfoWindow::updateInfo()
-{
-	char str[256];
-	CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
-	QSettings* settings=qmpSettingsWindow::getSettingsIntf();
-	ui->lbFileName->setText(QString("File name: ")+qmpMainWindow::getInstance()->getFileName());
-	if(player->getTitle())
-	{
-		if(settings->value("Midi/TextEncoding","").toString()!="Unicode")
-		ui->lbTitle->setText(QString("Title: ")+
-		QTextCodec::codecForName(settings->value("Midi/TextEncoding","").toString().toStdString().c_str())->toUnicode(player->getTitle()));
-		else
-		ui->lbTitle->setText(QString("Title: ")+player->getTitle());
-	}
-	else ui->lbTitle->setText(QString("Title: "));
-	if(player->getCopyright())
-	{
-		if(settings->value("Midi/TextEncoding","").toString()!="Unicode")
-		ui->lbCopyright->setText(QString("Copyright: ")+
-		QTextCodec::codecForName(settings->value("Midi/TextEncoding","").toString().toStdString().c_str())->toUnicode(player->getCopyright()));
-		else
-		ui->lbCopyright->setText(QString("Copyright: ")+player->getCopyright());
-	}
-	else ui->lbCopyright->setText(QString("Copyright: "));
-	ui->lbTempo->setText(QString("Tempo: ")+QString::number(player->getTempo(),'g',5));
-	int t,r;player->getCurrentKeySignature(&t);r=(int8_t)((t>>8)&0xFF)+7;
-	strncpy(str,t&0xFF?minors+2*r:majors+2*r,2);str[2]='\0';
-	ui->lbKeySig->setText(QString("Key Sig.: ")+str);
-	player->getCurrentTimeSignature(&t,&r);sprintf(str,"Time Sig.: %d/%d",t,r);
-	ui->lbTimeSig->setText(str);
-	sprintf(str,"Note count: %u",player->getFileNoteCount());
-	ui->lbNoteCount->setText(str);
-	strncpy(str,standards+player->getFileStandard()*3,3);str[3]='\0';
-	ui->lbFileStandard->setText(QString("File standard: ")+str);
-}
diff --git a/qmidiplayer.src.d/qmpinfowindow.hpp b/qmidiplayer.src.d/qmpinfowindow.hpp
deleted file mode 100644
index 9a1e389..0000000
--- a/qmidiplayer.src.d/qmpinfowindow.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef QMPINFOWINDOW_HPP
-#define QMPINFOWINDOW_HPP
-
-#include <QDialog>
-
-namespace Ui {
-	class qmpInfoWindow;
-}
-
-class qmpInfoWindow : public QDialog
-{
-	Q_OBJECT
-
-	public:
-		explicit qmpInfoWindow(QWidget *parent = 0);
-		~qmpInfoWindow();
-	public slots:
-		void updateInfo();
-
-	private:
-		Ui::qmpInfoWindow *ui;
-};
-
-#endif // QMPINFOWINDOW_HPP
diff --git a/qmidiplayer.src.d/qmpinfowindow.ui b/qmidiplayer.src.d/qmpinfowindow.ui
deleted file mode 100644
index 664531a..0000000
--- a/qmidiplayer.src.d/qmpinfowindow.ui
+++ /dev/null
@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>qmpInfoWindow</class>
- <widget class="QDialog" name="qmpInfoWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>400</width>
-    <height>142</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>400</width>
-    <height>142</height>
-   </size>
-  </property>
-  <property name="windowTitle">
-   <string>File Information</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <widget class="QLabel" name="lbFileName">
-     <property name="text">
-      <string>File name: </string>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLabel" name="lbTempo">
-       <property name="text">
-        <string>Tempo: </string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QLabel" name="lbKeySig">
-       <property name="text">
-        <string>Key Sig.: </string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QLabel" name="lbTimeSig">
-       <property name="text">
-        <string>Time Sig.:</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <widget class="QLabel" name="lbTitle">
-     <property name="text">
-      <string>Title: </string>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QLabel" name="lbCopyright">
-     <property name="text">
-      <string>Copyright: </string>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout_2">
-     <item>
-      <widget class="QLabel" name="lbNoteCount">
-       <property name="text">
-        <string>Note count: </string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QLabel" name="lbFileStandard">
-       <property name="text">
-        <string>File standard: </string>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/qmidiplayer.src.d/qmpmainwindow.cpp b/qmidiplayer.src.d/qmpmainwindow.cpp
deleted file mode 100644
index 453bd01..0000000
--- a/qmidiplayer.src.d/qmpmainwindow.cpp
+++ /dev/null
@@ -1,510 +0,0 @@
-#include <cstdio>
-#include <QUrl>
-#include <QMimeData>
-#include <QDirIterator>
-#include <QDesktopWidget>
-#include "qmpmainwindow.hpp"
-#include "ui_qmpmainwindow.h"
-#include "../common/qmpmidiplay.hpp"
-#ifdef _WIN32
-#include <Windows.h>
-#endif
-
-qmpMainWindow* qmpMainWindow::ref=NULL;
-
-qmpMainWindow::qmpMainWindow(QWidget *parent) :
-	QMainWindow(parent),
-	ui(new Ui::qmpMainWindow)
-{
-	ui->setupUi(this);
-	ui->lbFileName->setText("");ref=this;
-	playing=false;stopped=true;dragging=false;
-	settingsw=new qmpSettingsWindow(this);
-	plistw=new qmpPlistWindow(this);
-	chnlw=new qmpChannelsWindow(this);
-	efxw=new qmpEfxWindow(this);
-	infow=new qmpInfoWindow(this);
-	helpw=new qmpHelpWindow(this);
-	timer=new QTimer(this);
-	fnA1=new QAction("File Information",ui->lbFileName);
-	fnA2=new QAction("Render to Wave",ui->lbFileName);
-	ui->lbFileName->addAction(fnA1);
-	ui->lbFileName->addAction(fnA2);
-	singleFS=qmpSettingsWindow::getSettingsIntf()->value("Behavior/SingleInstance",0).toInt();
-	player=new CMidiPlayer(singleFS);
-	if(singleFS){player->fluidPreInitialize();playerSetup();player->fluidInitialize();
-		for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
-			player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
-	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus",0).toInt())
-	{
-		QRect g=geometry();
-		g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/MainW",QPoint(-999,-999)).toPoint());
-		if(g.topLeft()!=QPoint(-999,-999))setGeometry(g);
-		else setGeometry(QStyle::alignedRect(
-							 Qt::LeftToRight,Qt::AlignCenter,size(),
-							 qApp->desktop()->availableGeometry()));
-	}show();
-	if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListWShown",0).toInt())
-	{ui->pbPList->setChecked(true);on_pbPList_clicked();}
-	if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlWShown",0).toInt())
-	{ui->pbChannels->setChecked(true);on_pbChannels_clicked();}
-	if(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxWShown",0).toInt())
-	{ui->pbEfx->setChecked(true);on_pbEfx_clicked();}
-	ui->vsMasterVol->setValue(qmpSettingsWindow::getSettingsIntf()->value("Audio/Gain",50).toInt());
-	connect(fnA1,SIGNAL(triggered()),this,SLOT(onfnA1()));
-	connect(fnA2,SIGNAL(triggered()),this,SLOT(onfnA2()));
-	connect(timer,SIGNAL(timeout()),this,SLOT(updateWidgets()));
-	connect(timer,SIGNAL(timeout()),chnlw,SLOT(channelWindowsUpdate()));
-	connect(timer,SIGNAL(timeout()),infow,SLOT(updateInfo()));
-}
-
-qmpMainWindow::~qmpMainWindow()
-{
-	delete player;
-	delete timer;
-	delete ui;
-}
-
-int qmpMainWindow::pharseArgs(int argc,char** argv)
-{
-	bool havemidi=false,loadfolder=false;
-	for(int i=1;i<argc;++i)
-	{
-		if(argv[i][0]=='-')
-		{
-			if(!strcmp(argv[i],"--help"))
-			{
-				printf("Usage: %s [Options] [Midi Files]\n",argv[0]);
-				printf("Possible options are: \n");
-				printf("-l, --load-all-files  Load all files from the same folder.\n");
-				printf("--help                Show this help and exit.\n");
-				printf("--version             Show this version information and exit.\n");
-				return 1;
-			}
-			if(!strcmp(argv[i],"--version"))
-			{
-				printf("QMidiPlayer %s\n",APP_VERSION);
-				return 1;
-			}
-			if(!strcmp(argv[i],"-l")||!strcmp(argv[i],"--load-all-files"))
-				loadfolder=true;
-		}
-		else
-		if(fluid_is_midifile(argv[i]))
-		{
-			if(!havemidi){havemidi=true;plistw->emptyList();}
-			if(loadfolder||qmpSettingsWindow::getSettingsIntf()->value("Behavior/LoadFolder",0).toInt())
-			{
-				QDirIterator di(QUrl(argv[i]).adjusted(QUrl::RemoveFilename).toString());
-				while(di.hasNext())
-				{
-					QString c=di.next();
-					if((c.endsWith(".mid")||c.endsWith(".midi"))&&fluid_is_midifile(c.toStdString().c_str()))
-					plistw->insertItem(c.toStdString().c_str());
-				}
-			}
-			else
-			plistw->insertItem(argv[i]);
-		}
-	}
-	if(havemidi)on_pbPlayPause_clicked();
-	return 0;
-}
-
-void qmpMainWindow::closeEvent(QCloseEvent *event)
-{
-	on_pbStop_clicked();fin=true;
-	efxw->close();chnlw->close();
-	plistw->close();infow->close();
-	settingsw->close();
-	delete helpw;helpw=NULL;
-	delete efxw;efxw=NULL;
-	delete chnlw;chnlw=NULL;
-	delete plistw;plistw=NULL;
-	delete infow;infow=NULL;
-	delete settingsw;settingsw=NULL;
-	event->accept();
-}
-
-void qmpMainWindow::moveEvent(QMoveEvent *event)
-{
-	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
-	{
-		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/MainW",event->pos());
-	}
-}
-void qmpMainWindow::dropEvent(QDropEvent *event)
-{
-	QList<QUrl> l=event->mimeData()->urls();
-	QStringList sl;
-	for(int i=0;i<l.size();++i)
-		sl.push_back(l.at(i).toLocalFile());
-	plistw->insertItems(sl);
-}
-void qmpMainWindow::dragEnterEvent(QDragEnterEvent *event)
-{
-	//if(event->mimeData()->hasFormat("application/x-midi"))
-	event->acceptProposedAction();
-}
-
-void qmpMainWindow::updateWidgets()
-{
-	fnA2->setEnabled(stopped);
-	if(player->isFinished()&&playerTh)
-	{
-		if(!plistw->getRepeat())
-		{
-			timer->stop();stopped=true;playing=false;
-			fnA2->setEnabled(stopped);
-			player->playerDeinit();playerTh->join();
-			delete playerTh;playerTh=NULL;
-			if(singleFS)player->playerPanic(true);
-			chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
-			ui->pbPlayPause->setIcon(QIcon(":/img/play.png"));
-			ui->hsTimer->setValue(0);
-			ui->lbPolyphone->setText("Poly: 0/0");
-			ui->lbCurTime->setText("00:00");
-		}
-		else
-		{
-			timer->stop();player->playerDeinit();playerTh->join();
-			delete playerTh;playerTh=NULL;
-			ui->hsTimer->setValue(0);
-			if(singleFS)player->playerPanic(true);
-			chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
-			QString fns=plistw->getNextItem();
-			ui->lbFileName->setText(QUrl(fns).fileName());
-			if(!player->playerLoadFile(fns.toStdString().c_str()))return;
-			char ts[100];
-			sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
-			ui->lbFinTime->setText(ts);
-			player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
-			for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
-				player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
-			player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
-			player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
-			playerTh=new std::thread(&CMidiPlayer::playerThread,player);
-#ifdef _WIN32
-			SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
-#endif
-			st=std::chrono::steady_clock::now();offset=0;
-			timer->start(100);
-		}
-	}
-	if(renderTh)
-	{
-		if(player->isFinished())
-		{
-			renderTh->join();timer->stop();
-			ui->centralWidget->setEnabled(true);
-			delete renderTh;renderTh=NULL;
-			player->rendererDeinit();
-			if(singleFS){player->fluidPreInitialize();playerSetup();player->fluidInitialize();}
-		}
-	}
-	while(!player->isFinished()&&player->getTCeptr()>player->getStamp(ui->hsTimer->value())
-		  &&ui->hsTimer->value()<=100&&!dragging)
-		ui->hsTimer->setValue(ui->hsTimer->value()+1);
-	if(playing)
-	{
-		std::chrono::duration<double> elapsed=
-				std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now()-st);
-		char ts[100];
-		sprintf(ts,"%02d:%02d",(int)(elapsed.count()+offset)/60,(int)(elapsed.count()+offset)%60);
-		ui->lbCurTime->setText(ts);
-		sprintf(ts,"Poly: %d/%d",player->getPolyphone(),player->getMaxPolyphone());
-		ui->lbPolyphone->setText(ts);
-	}
-}
-
-QString qmpMainWindow::getFileName(){return ui->lbFileName->text();}
-
-void qmpMainWindow::playerSetup()
-{
-	fluid_settings_t* fsettings=player->getFluidSettings();
-	QSettings* settings=qmpSettingsWindow::getSettingsIntf();
-	fluid_settings_setstr(fsettings,"audio.driver",settings->value("Audio/Driver","").toString().toStdString().c_str());
-	fluid_settings_setint(fsettings,"audio.period-size",settings->value("Audio/BufSize","").toInt());
-	fluid_settings_setint(fsettings,"audio.periods",settings->value("Audio/BufCnt","").toInt());
-	fluid_settings_setstr(fsettings,"audio.sample-format",settings->value("Audio/Format","").toString().toStdString().c_str());
-	fluid_settings_setint(fsettings,"synth.sample-rate",settings->value("Audio/Frequency","").toInt());
-	fluid_settings_setint(fsettings,"synth.polyphony",settings->value("Audio/Polyphony","").toInt());
-	fluid_settings_setint(fsettings,"synth.cpu-cores",settings->value("Audio/Threads","").toInt());
-	char bsmode[4];
-	if(!singleFS&&settings->value("Audio/AutoBS",1).toInt()&&player->getFileStandard())
-		switch(player->getFileStandard())
-		{
-			case 1:strcpy(bsmode,"gm");break;
-			case 2:strcpy(bsmode,"mma");break;
-			case 3:strcpy(bsmode,"gs");break;
-			case 4:strcpy(bsmode,"xg");break;
-		}
-	else
-	{
-		if(settings->value("Audio/BankSelect","CC#0").toString()==QString("Ignored"))
-			strcpy(bsmode,"gm");
-		if(settings->value("Audio/BankSelect","CC#0").toString()==QString("CC#0"))
-			strcpy(bsmode,"gs");
-		if(settings->value("Audio/BankSelect","CC#0").toString()==QString("CC#32"))
-			strcpy(bsmode,"xg");
-		if(settings->value("Audio/BankSelect","CC#0").toString()==QString("CC#0*128+CC#32"))
-			strcpy(bsmode,"mma");
-	}
-	fluid_settings_setstr(fsettings,"synth.midi-bank-select",bsmode);
-	player->sendSysX(settings->value("Midi/SendSysEx",1).toInt());
-}
-
-void qmpMainWindow::on_pbPlayPause_clicked()
-{
-	playing=!playing;
-	if(stopped)
-	{
-		QString fns=plistw->getFirstItem();
-		if(!fns.length())
-		{
-			plistw->on_pbAdd_clicked();
-			fns=plistw->getFirstItem();
-			if(!fns.length())return(void)(playing=false);
-		}
-		ui->lbFileName->setText(QUrl(fns).fileName());
-		if(!player->playerLoadFile(fns.toStdString().c_str()))return;
-		char ts[100];
-		sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
-		ui->lbFinTime->setText(ts);
-		player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
-		for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
-			player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
-		player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
-		player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
-		playerTh=new std::thread(&CMidiPlayer::playerThread,player);
-#ifdef _WIN32
-			SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
-#endif
-		st=std::chrono::steady_clock::now();offset=0;
-		timer->start(100);
-		stopped=false;
-	}
-	else
-	{
-		if(!playing)
-		{
-			player->playerPanic();
-			offset=ui->hsTimer->value()/100.*player->getFtime();
-		}
-		else
-		{
-			st=std::chrono::steady_clock::now();
-			player->setResumed();
-		}
-		player->setTCpaused(!playing);
-	}
-	ui->pbPlayPause->setIcon(QIcon(playing?":/img/pause.png":":/img/play.png"));
-}
-
-void qmpMainWindow::on_hsTimer_sliderPressed()
-{
-	dragging=true;
-}
-
-void qmpMainWindow::on_hsTimer_sliderReleased()
-{
-	dragging=false;
-	if(playing)
-	{
-		if(ui->hsTimer->value()==100){on_pbNext_clicked();return;}
-		player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value());
-		player->playerPanic();
-		offset=ui->hsTimer->value()/100.*player->getFtime();
-		st=std::chrono::steady_clock::now();
-	}
-	else
-	{
-		player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value());
-		offset=ui->hsTimer->value()/100.*player->getFtime();
-		char ts[100];
-		sprintf(ts,"%02d:%02d",(int)(offset)/60,(int)(offset)%60);
-		ui->lbCurTime->setText(ts);
-	}
-}
-
-void qmpMainWindow::on_vsMasterVol_valueChanged()
-{
-	if(!stopped)player->setGain(ui->vsMasterVol->value()/250.);
-	qmpSettingsWindow::getSettingsIntf()->setValue("Audio/Gain",ui->vsMasterVol->value());
-}
-
-void qmpMainWindow::on_pbStop_clicked()
-{
-	if(!stopped)
-	{
-		timer->stop();stopped=true;playing=false;
-		player->playerDeinit();fnA2->setEnabled(stopped);
-		if(singleFS)player->playerPanic(true);
-		if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
-		chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
-		ui->pbPlayPause->setIcon(QIcon(":/img/play.png"));
-		ui->hsTimer->setValue(0);
-		ui->lbPolyphone->setText("Poly: 0/0");
-		ui->lbCurTime->setText("00:00");
-	}
-}
-
-void qmpMainWindow::dialogClosed()
-{
-	if(!plistw->isVisible())ui->pbPList->setChecked(false);
-	if(!chnlw->isVisible())ui->pbChannels->setChecked(false);
-	if(!efxw->isVisible())ui->pbEfx->setChecked(false);
-	if(!settingsw->isVisible())ui->pbSettings->setChecked(false);
-}
-
-void qmpMainWindow::on_pbPList_clicked()
-{
-	if(ui->pbPList->isChecked())
-	{
-		QRect g=plistw->geometry();
-		g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/PListW",QPoint(-999,-999)).toPoint());
-		if(g.topLeft()==QPoint(-999,-999))
-			g.setTopLeft(window()->mapToGlobal(window()->rect().center())-plistw->rect().center());
-		plistw->setGeometry(g);
-		plistw->show();
-	}else plistw->close();
-}
-
-void qmpMainWindow::on_pbChannels_clicked()
-{
-	if(ui->pbChannels->isChecked())
-	{
-		QRect g=chnlw->geometry();
-		g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/ChnlW",QPoint(-999,-999)).toPoint());
-		if(g.topLeft()==QPoint(-999,-999))
-			g.setTopLeft(window()->mapToGlobal(window()->rect().center())-chnlw->rect().center());
-		chnlw->setGeometry(g);
-		chnlw->show();
-	}else chnlw->close();
-}
-
-void qmpMainWindow::on_pbPrev_clicked()
-{
-	timer->stop();player->playerDeinit();
-	if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
-	if(singleFS)player->playerPanic(true);
-	ui->hsTimer->setValue(0);chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
-	QString fns=plistw->getPrevItem();if(fns.length()==0)return on_pbStop_clicked();
-	ui->lbFileName->setText(QUrl(fns).fileName());
-	if(!player->playerLoadFile(fns.toStdString().c_str()))return;
-	char ts[100];
-	sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
-	ui->lbFinTime->setText(ts);
-	player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
-	for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
-		player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
-	player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
-	player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
-	playerTh=new std::thread(&CMidiPlayer::playerThread,player);
-#ifdef _WIN32
-			SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
-#endif
-	st=std::chrono::steady_clock::now();offset=0;
-	timer->start(100);
-}
-
-void qmpMainWindow::on_pbNext_clicked()
-{
-	timer->stop();player->playerDeinit();
-	if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
-	if(singleFS)player->playerPanic(true);
-	ui->hsTimer->setValue(0);chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
-	QString fns=plistw->getNextItem();if(fns.length()==0)return on_pbStop_clicked();
-	ui->lbFileName->setText(QUrl(fns).fileName());
-	if(!player->playerLoadFile(fns.toStdString().c_str()))return;
-	char ts[100];
-	sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
-	ui->lbFinTime->setText(ts);
-	player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
-	for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
-		player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
-	player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
-	player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
-	playerTh=new std::thread(&CMidiPlayer::playerThread,player);
-#ifdef _WIN32
-			SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
-#endif
-	st=std::chrono::steady_clock::now();offset=0;
-	timer->start(100);
-}
-
-void qmpMainWindow::selectionChanged()
-{
-	stopped=false;playing=true;
-	ui->pbPlayPause->setIcon(QIcon(":/img/pause.png"));
-	timer->stop();player->playerDeinit();
-	if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;}
-	if(singleFS)player->playerPanic(true);
-	ui->hsTimer->setValue(0);
-	chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
-	QString fns=plistw->getSelectedItem();
-	ui->lbFileName->setText(QUrl(fns).fileName());
-	if(!player->playerLoadFile(fns.toStdString().c_str()))return;
-	char ts[100];
-	sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
-	ui->lbFinTime->setText(ts);
-	player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize();
-	for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
-		player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());}
-	player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
-	player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt());
-	playerTh=new std::thread(&CMidiPlayer::playerThread,player);
-#ifdef _WIN32
-			SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
-#endif
-	st=std::chrono::steady_clock::now();offset=0;
-	timer->start(100);
-}
-
-void qmpMainWindow::on_pbEfx_clicked()
-{
-	if(ui->pbEfx->isChecked())
-	{
-		QRect g=efxw->geometry();
-		g.setTopLeft(qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/EfxW",QPoint(-999,-999)).toPoint());
-		if(g.topLeft()==QPoint(-999,-999))
-			g.setTopLeft(window()->mapToGlobal(window()->rect().center())-efxw->rect().center());
-		efxw->setGeometry(g);
-		efxw->show();
-	}
-	else efxw->close();
-}
-
-void qmpMainWindow::on_lbFileName_customContextMenuRequested(const QPoint &pos)
-{
-	QMenu menu(ui->lbFileName);
-	menu.addActions(ui->lbFileName->actions());
-	menu.exec(this->pos()+ui->lbFileName->pos()+pos);
-}
-
-void qmpMainWindow::onfnA1()
-{
-	infow->show();
-}
-
-void qmpMainWindow::onfnA2()
-{
-	if(singleFS)player->fluidDeinitialize();
-	player->rendererLoadFile((plistw->getSelectedItem()+QString(".wav")).toStdString().c_str());
-	playerSetup();player->rendererInit(plistw->getSelectedItem().toStdString().c_str());
-	ui->centralWidget->setEnabled(false);
-	for(int i=settingsw->getSFWidget()->count()-1;i>=0;--i)
-		player->pushSoundFont(settingsw->getSFWidget()->item(i)->text().toStdString().c_str());
-	player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();timer->start(100);
-	renderTh=new std::thread(&CMidiPlayer::rendererThread,player);
-}
-
-void qmpMainWindow::on_pbSettings_clicked()
-{
-	if(ui->pbSettings->isChecked())settingsw->show();else settingsw->close();
-}
-
-void qmpMainWindow::on_pushButton_clicked()
-{
-	helpw->show();
-}
diff --git a/qmidiplayer.src.d/qmpmainwindow.hpp b/qmidiplayer.src.d/qmpmainwindow.hpp
deleted file mode 100644
index 517f792..0000000
--- a/qmidiplayer.src.d/qmpmainwindow.hpp
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef QMPMAINWINDOW_H
-#define QMPMAINWINDOW_H
-
-#include <QMainWindow>
-#include <QTimer>
-#include <QCloseEvent>
-#include <QMoveEvent>
-#include <QDropEvent>
-#include <QDragEnterEvent>
-#include <QAction>
-#include <QMenu>
-#include <thread>
-#include <chrono>
-#include "../common/qmpmidiplay.hpp"
-#include "qmpplistwindow.hpp"
-#include "qmpchannelswindow.hpp"
-#include "qmpefxwindow.hpp"
-#include "qmpinfowindow.hpp"
-#include "qmpsettingswindow.hpp"
-#include "qmphelpwindow.hpp"
-
-namespace Ui {
-	class qmpMainWindow;
-}
-
-class qmpMainWindow:public QMainWindow
-{
-	Q_OBJECT
-
-	public:
-		explicit qmpMainWindow(QWidget *parent = 0);
-		void closeEvent(QCloseEvent *event);
-		void moveEvent(QMoveEvent *event);
-		void dropEvent(QDropEvent *event);
-		void dragEnterEvent(QDragEnterEvent *event);
-		~qmpMainWindow();
-		CMidiPlayer* getPlayer(){return player;}
-		QTimer* getTimer(){return timer;}
-		bool isFinalizing(){return fin;}
-		QString getFileName();
-		int pharseArgs(int argc,char** argv);
-
-	private slots:
-		void on_pbPlayPause_clicked();
-		void updateWidgets();
-		void on_hsTimer_sliderPressed();
-		void on_hsTimer_sliderReleased();
-		void on_vsMasterVol_valueChanged();
-		void on_pbStop_clicked();
-		void on_pbPList_clicked();
-		void on_pbPrev_clicked();
-		void on_pbNext_clicked();
-		void on_pbChannels_clicked();
-		void on_pbEfx_clicked();
-		void on_lbFileName_customContextMenuRequested(const QPoint &pos);
-		void on_pbSettings_clicked();
-		void onfnA1();
-		void onfnA2();
-
-		void on_pushButton_clicked();
-
-	public slots:
-		void dialogClosed();
-		void selectionChanged();
-
-	private:
-		Ui::qmpMainWindow *ui;
-		QTimer *timer;
-		bool playing,stopped,dragging,fin,singleFS;
-		std::thread *playerTh=NULL;
-		std::thread *renderTh=NULL;
-		std::chrono::steady_clock::time_point st;
-		double offset;
-		CMidiPlayer *player;
-		qmpPlistWindow *plistw;
-		qmpChannelsWindow *chnlw;
-		qmpEfxWindow *efxw;
-		qmpInfoWindow *infow;
-		qmpSettingsWindow *settingsw;
-		qmpHelpWindow *helpw;
-
-		QAction *fnA1,*fnA2;
-		void playerSetup();
-
-	private:
-		static qmpMainWindow* ref;
-	public: static qmpMainWindow* getInstance(){return ref;}
-};
-
-#endif // QMPMAINWINDOW_H
diff --git a/qmidiplayer.src.d/qmpmainwindow.ui b/qmidiplayer.src.d/qmpmainwindow.ui
deleted file mode 100644
index 0764e09..0000000
--- a/qmidiplayer.src.d/qmpmainwindow.ui
+++ /dev/null
@@ -1,413 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>qmpMainWindow</class>
- <widget class="QMainWindow" name="qmpMainWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>435</width>
-    <height>245</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>435</width>
-    <height>245</height>
-   </size>
-  </property>
-  <property name="maximumSize">
-   <size>
-    <width>435</width>
-    <height>245</height>
-   </size>
-  </property>
-  <property name="acceptDrops">
-   <bool>true</bool>
-  </property>
-  <property name="windowTitle">
-   <string>QMidiPlayer</string>
-  </property>
-  <property name="windowIcon">
-   <iconset resource="resources.qrc">
-    <normaloff>:/img/qmidiplyr.png</normaloff>:/img/qmidiplyr.png</iconset>
-  </property>
-  <widget class="QWidget" name="centralWidget">
-   <widget class="QLabel" name="lbFileName">
-    <property name="geometry">
-     <rect>
-      <x>30</x>
-      <y>20</y>
-      <width>311</width>
-      <height>41</height>
-     </rect>
-    </property>
-    <property name="font">
-     <font>
-      <pointsize>18</pointsize>
-     </font>
-    </property>
-    <property name="contextMenuPolicy">
-     <enum>Qt::CustomContextMenu</enum>
-    </property>
-    <property name="text">
-     <string>somefile.mid</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-   <widget class="QSlider" name="hsTimer">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>90</y>
-      <width>321</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>100</number>
-    </property>
-    <property name="pageStep">
-     <number>0</number>
-    </property>
-    <property name="orientation">
-     <enum>Qt::Horizontal</enum>
-    </property>
-   </widget>
-   <widget class="QPushButton" name="pbPlayPause">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>110</y>
-      <width>61</width>
-      <height>36</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string/>
-    </property>
-    <property name="icon">
-     <iconset resource="resources.qrc">
-      <normaloff>:/img/play.png</normaloff>:/img/play.png</iconset>
-    </property>
-    <property name="iconSize">
-     <size>
-      <width>32</width>
-      <height>32</height>
-     </size>
-    </property>
-   </widget>
-   <widget class="QPushButton" name="pbStop">
-    <property name="geometry">
-     <rect>
-      <x>80</x>
-      <y>110</y>
-      <width>61</width>
-      <height>36</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string/>
-    </property>
-    <property name="icon">
-     <iconset resource="resources.qrc">
-      <normaloff>:/img/stop.png</normaloff>:/img/stop.png</iconset>
-    </property>
-    <property name="iconSize">
-     <size>
-      <width>32</width>
-      <height>32</height>
-     </size>
-    </property>
-   </widget>
-   <widget class="QPushButton" name="pbPrev">
-    <property name="geometry">
-     <rect>
-      <x>140</x>
-      <y>110</y>
-      <width>61</width>
-      <height>36</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string/>
-    </property>
-    <property name="icon">
-     <iconset resource="resources.qrc">
-      <normaloff>:/img/prev.png</normaloff>:/img/prev.png</iconset>
-    </property>
-    <property name="iconSize">
-     <size>
-      <width>32</width>
-      <height>32</height>
-     </size>
-    </property>
-   </widget>
-   <widget class="QPushButton" name="pbNext">
-    <property name="geometry">
-     <rect>
-      <x>200</x>
-      <y>110</y>
-      <width>61</width>
-      <height>36</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string/>
-    </property>
-    <property name="icon">
-     <iconset resource="resources.qrc">
-      <normaloff>:/img/next.png</normaloff>:/img/next.png</iconset>
-    </property>
-    <property name="iconSize">
-     <size>
-      <width>32</width>
-      <height>32</height>
-     </size>
-    </property>
-   </widget>
-   <widget class="QPushButton" name="pbSettings">
-    <property name="geometry">
-     <rect>
-      <x>280</x>
-      <y>110</y>
-      <width>61</width>
-      <height>36</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string/>
-    </property>
-    <property name="icon">
-     <iconset resource="resources.qrc">
-      <normaloff>:/img/settings.png</normaloff>:/img/settings.png</iconset>
-    </property>
-    <property name="iconSize">
-     <size>
-      <width>32</width>
-      <height>32</height>
-     </size>
-    </property>
-    <property name="checkable">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QPushButton" name="pbChannels">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>160</y>
-      <width>151</width>
-      <height>36</height>
-     </rect>
-    </property>
-    <property name="styleSheet">
-     <string notr="true">text-align:left</string>
-    </property>
-    <property name="text">
-     <string>Channels</string>
-    </property>
-    <property name="icon">
-     <iconset resource="resources.qrc">
-      <normaloff>:/img/channel.png</normaloff>:/img/channel.png</iconset>
-    </property>
-    <property name="iconSize">
-     <size>
-      <width>32</width>
-      <height>32</height>
-     </size>
-    </property>
-    <property name="checkable">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QPushButton" name="pbPList">
-    <property name="geometry">
-     <rect>
-      <x>190</x>
-      <y>160</y>
-      <width>151</width>
-      <height>36</height>
-     </rect>
-    </property>
-    <property name="styleSheet">
-     <string notr="true">text-align:left</string>
-    </property>
-    <property name="text">
-     <string>Playlist</string>
-    </property>
-    <property name="icon">
-     <iconset resource="resources.qrc">
-      <normaloff>:/img/list.png</normaloff>:/img/list.png</iconset>
-    </property>
-    <property name="iconSize">
-     <size>
-      <width>32</width>
-      <height>32</height>
-     </size>
-    </property>
-    <property name="checkable">
-     <bool>true</bool>
-    </property>
-    <property name="checked">
-     <bool>false</bool>
-    </property>
-    <property name="flat">
-     <bool>false</bool>
-    </property>
-   </widget>
-   <widget class="QPushButton" name="pbEfx">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>200</y>
-      <width>151</width>
-      <height>36</height>
-     </rect>
-    </property>
-    <property name="styleSheet">
-     <string notr="true">text-align:left</string>
-    </property>
-    <property name="text">
-     <string>Effects</string>
-    </property>
-    <property name="icon">
-     <iconset resource="resources.qrc">
-      <normaloff>:/img/effects.png</normaloff>:/img/effects.png</iconset>
-    </property>
-    <property name="iconSize">
-     <size>
-      <width>32</width>
-      <height>32</height>
-     </size>
-    </property>
-    <property name="checkable">
-     <bool>true</bool>
-    </property>
-   </widget>
-   <widget class="QPushButton" name="pbVisualization">
-    <property name="geometry">
-     <rect>
-      <x>190</x>
-      <y>200</y>
-      <width>151</width>
-      <height>36</height>
-     </rect>
-    </property>
-    <property name="styleSheet">
-     <string notr="true">text-align:left</string>
-    </property>
-    <property name="text">
-     <string>Visualization</string>
-    </property>
-    <property name="icon">
-     <iconset resource="resources.qrc">
-      <normaloff>:/img/visualization.png</normaloff>:/img/visualization.png</iconset>
-    </property>
-    <property name="iconSize">
-     <size>
-      <width>32</width>
-      <height>32</height>
-     </size>
-    </property>
-   </widget>
-   <widget class="QLabel" name="lbPolyphone">
-    <property name="geometry">
-     <rect>
-      <x>320</x>
-      <y>20</y>
-      <width>111</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Poly: 0/0&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignCenter</set>
-    </property>
-   </widget>
-   <widget class="QSlider" name="vsMasterVol">
-    <property name="geometry">
-     <rect>
-      <x>370</x>
-      <y>50</y>
-      <width>20</width>
-      <height>160</height>
-     </rect>
-    </property>
-    <property name="maximum">
-     <number>100</number>
-    </property>
-    <property name="value">
-     <number>50</number>
-    </property>
-    <property name="orientation">
-     <enum>Qt::Vertical</enum>
-    </property>
-   </widget>
-   <widget class="QLabel" name="lbMasterVol">
-    <property name="geometry">
-     <rect>
-      <x>360</x>
-      <y>210</y>
-      <width>61</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>Master</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="lbCurTime">
-    <property name="geometry">
-     <rect>
-      <x>20</x>
-      <y>70</y>
-      <width>66</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>00:00</string>
-    </property>
-   </widget>
-   <widget class="QLabel" name="lbFinTime">
-    <property name="geometry">
-     <rect>
-      <x>270</x>
-      <y>70</y>
-      <width>66</width>
-      <height>20</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>00:00</string>
-    </property>
-    <property name="alignment">
-     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-    </property>
-   </widget>
-   <widget class="QPushButton" name="pushButton">
-    <property name="geometry">
-     <rect>
-      <x>0</x>
-      <y>0</y>
-      <width>21</width>
-      <height>21</height>
-     </rect>
-    </property>
-    <property name="text">
-     <string>?</string>
-    </property>
-   </widget>
-  </widget>
- </widget>
- <layoutdefault spacing="6" margin="11"/>
- <resources>
-  <include location="resources.qrc"/>
- </resources>
- <connections/>
-</ui>
diff --git a/qmidiplayer.src.d/qmpplistwindow.cpp b/qmidiplayer.src.d/qmpplistwindow.cpp
deleted file mode 100644
index 8f04fc1..0000000
--- a/qmidiplayer.src.d/qmpplistwindow.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-#include <cstdlib>
-#include <ctime>
-#include <QFileDialog>
-#include <QDir>
-#include <QDirIterator>
-#include <QSettings>
-#include <QUrl>
-#include <QMimeData>
-#include "qmpplistwindow.hpp"
-#include "ui_qmpplistwindow.h"
-#include "qmpmainwindow.hpp"
-
-qmpPlistWindow::qmpPlistWindow(QWidget *parent) :
-	QDialog(parent),
-	ui(new Ui::qmpPlistWindow)
-{
-	ui->setupUi(this);
-	connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed()));
-	connect(this,SIGNAL(selectionChanging()),parent,SLOT(selectionChanged()));
-	repeat=0;shuffle=0;
-	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/RestorePlaylist","").toInt())
-	{
-		QSettings* plist=new QSettings(QDir::homePath()+QString("/.config/qmpplist"),
-									   QSettings::IniFormat);
-		int fc=plist->value("Playlist/FileCount",0).toInt();
-		ui->lwFiles->clear();for(int i=1;i<=fc;++i)
-		ui->lwFiles->addItem(plist->value("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),"").toString());
-		repeat=plist->value("Playlist/Repeat",0).toInt();
-		shuffle=plist->value("Playlist/Shuffle",0).toInt();
-		switch(shuffle)
-		{
-			case 1:
-				ui->pbShuffle->setIcon(QIcon(":/img/shuffle.png"));
-				ui->pbShuffle->setText("Shuffle On");
-			break;
-			case 0:
-			default:
-				ui->pbShuffle->setIcon(QIcon(":/img/shuffle-off.png"));
-				ui->pbShuffle->setText("Shuffle Off");
-			break;
-		}
-		switch(repeat)
-		{
-			case 0:
-				ui->pbRepeat->setIcon(QIcon(":/img/repeat-non.png"));
-				ui->pbRepeat->setText("Repeat Off");
-			break;
-			case 1:
-				ui->pbRepeat->setIcon(QIcon(":/img/repeat-one.png"));
-				ui->pbRepeat->setText("Repeat One");
-			break;
-			case 2:
-				ui->pbRepeat->setIcon(QIcon(":/img/repeat-all.png"));
-				ui->pbRepeat->setText("Repeat All");
-			break;
-		}
-		delete plist;
-	}
-}
-
-qmpPlistWindow::~qmpPlistWindow()
-{
-	delete ui;
-}
-
-void qmpPlistWindow::showEvent(QShowEvent *event)
-{
-	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
-	{
-		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListWShown",1);
-	}
-	event->accept();
-}
-
-void qmpPlistWindow::closeEvent(QCloseEvent *event)
-{
-	setVisible(false);
-	if(!qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
-	{
-		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListWShown",0);
-	}
-	if(qmpMainWindow::getInstance()->isFinalizing()&&qmpSettingsWindow::getSettingsIntf()->value("Behavior/RestorePlaylist","").toInt())
-	{
-		QSettings* plist=new QSettings(QDir::homePath()+QString("/.config/qmpplist"),
-									   QSettings::IniFormat);
-		plist->setValue("Playlist/FileCount",ui->lwFiles->count());
-		for(int i=0;i<ui->lwFiles->count();++i)
-		plist->setValue("Playlist/File"+QString("%1").arg(i+1,5,10,QChar('0')),ui->lwFiles->item(i)->text());
-		plist->setValue("Playlist/Repeat",repeat);
-		plist->setValue("Playlist/Shuffle",shuffle);
-		plist->sync();
-		delete plist;
-	}
-	emit dialogClosing();
-	event->accept();
-}
-
-void qmpPlistWindow::moveEvent(QMoveEvent *event)
-{
-	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
-	{
-		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/PListW",event->pos());
-	}
-}
-
-void qmpPlistWindow::dropEvent(QDropEvent *event)
-{
-	QList<QUrl> l=event->mimeData()->urls();
-	QStringList sl;
-	for(int i=0;i<l.size();++i)
-		sl.push_back(l.at(i).toLocalFile());
-	insertItems(sl);
-}
-void qmpPlistWindow::dragEnterEvent(QDragEnterEvent *event)
-{
-	//if(event->mimeData()->hasFormat("application/x-midi"))
-	event->acceptProposedAction();
-}
-
-void qmpPlistWindow::emptyList()
-{
-	ui->lwFiles->clear();
-}
-void qmpPlistWindow::insertItem(QString i)
-{
-	ui->lwFiles->addItem(new QListWidgetItem(i));
-}
-void qmpPlistWindow::insertItems(QStringList il)
-{
-	ui->lwFiles->addItems(il);
-}
-
-void qmpPlistWindow::on_pbAdd_clicked()
-{
-	QStringList sl;
-	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
-		sl=QFileDialog::getOpenFileNames(this,"Add File",qmpSettingsWindow::getSettingsIntf()->value("DialogStatus/FileDialogPath","").toString(),"Midi files (*.mid *.midi)");
-	else
-		sl=QFileDialog::getOpenFileNames(this,"Add File","","Midi files (*.mid *.midi)");
-	if(sl.empty())return;
-	for(int i=0;i<sl.size();++i)
-	{
-		ui->lwFiles->addItem(new QListWidgetItem(sl.at(i)));
-	}
-	if(qmpSettingsWindow::getSettingsIntf()->value("Behavior/DialogStatus","").toInt())
-		qmpSettingsWindow::getSettingsIntf()->setValue("DialogStatus/FileDialogPath",
-		QUrl(sl.at(0)).toString(QUrl::RemoveFilename));
-}
-
-void qmpPlistWindow::on_pbAddFolder_clicked()
-{
-	QDirIterator di(QFileDialog::getExistingDirectory(this,"Add Folder"));
-	while(di.hasNext())
-	{
-		QString c=di.next();
-		if((c.endsWith(".mid")||c.endsWith(".midi"))&&fluid_is_midifile(c.toStdString().c_str()))
-		ui->lwFiles->addItem(new QListWidgetItem(c));
-	}
-}
-
-void qmpPlistWindow::on_pbRemove_clicked()
-{
-	QList<QListWidgetItem*> sl=ui->lwFiles->selectedItems();
-	for(int i=0;i<sl.size();++i)
-	{
-		ui->lwFiles->removeItemWidget(sl.at(i));
-		delete sl.at(i);
-	}
-}
-
-void qmpPlistWindow::on_pbClear_clicked()
-{
-	while(ui->lwFiles->count()>0)
-	{
-		QListWidgetItem *d=ui->lwFiles->item(0);
-		ui->lwFiles->removeItemWidget(d);
-		delete d;
-	}
-}
-
-void qmpPlistWindow::on_pbRepeat_clicked()
-{
-	++repeat;repeat%=3;
-	switch(repeat)
-	{
-		case 0:
-			ui->pbRepeat->setIcon(QIcon(":/img/repeat-non.png"));
-			ui->pbRepeat->setText("Repeat Off");
-		break;
-		case 1:
-			ui->pbRepeat->setIcon(QIcon(":/img/repeat-one.png"));
-			ui->pbRepeat->setText("Repeat One");
-		break;
-		case 2:
-			ui->pbRepeat->setIcon(QIcon(":/img/repeat-all.png"));
-			ui->pbRepeat->setText("Repeat All");
-		break;
-	}
-}
-
-void qmpPlistWindow::on_pbShuffle_clicked()
-{
-	shuffle=1-shuffle;
-	switch(shuffle)
-	{
-		case 1:
-			ui->pbShuffle->setIcon(QIcon(":/img/shuffle.png"));
-			ui->pbShuffle->setText("Shuffle On");
-		break;
-		case 0:
-		default:
-			ui->pbShuffle->setIcon(QIcon(":/img/shuffle-off.png"));
-			ui->pbShuffle->setText("Shuffle Off");
-		break;
-	}
-}
-
-QString qmpPlistWindow::getFirstItem()
-{
-	if(ui->lwFiles->count()==0)return QString();
-	int id=0;
-	if(shuffle)id=rand()%ui->lwFiles->count();
-	ui->lwFiles->setCurrentRow(id);
-	return ui->lwFiles->item(id)->text();
-}
-QString qmpPlistWindow::getNextItem()
-{
-	if(ui->lwFiles->count()==0)return QString();
-	if(repeat==1)return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
-	int id=ui->lwFiles->currentRow();++id;id%=ui->lwFiles->count();
-	if(shuffle)id=rand()%ui->lwFiles->count();
-	ui->lwFiles->setCurrentRow(id);
-	return ui->lwFiles->item(id)->text();
-}
-QString qmpPlistWindow::getPrevItem()
-{
-	if(ui->lwFiles->count()==0)return QString();
-	if(repeat==1)return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
-	int id=ui->lwFiles->currentRow();--id;
-	id<0?id+=ui->lwFiles->count():0;
-	if(shuffle)id=rand()%ui->lwFiles->count();
-	ui->lwFiles->setCurrentRow(id);
-	return ui->lwFiles->item(id)->text();
-}
-QString qmpPlistWindow::getSelectedItem()
-{
-	if(ui->lwFiles->count()==0)return QString();
-	return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
-}
-int qmpPlistWindow::getRepeat(){return repeat;}
-
-void qmpPlistWindow::on_lwFiles_itemDoubleClicked()
-{
-	emit selectionChanging();
-}
-
-void qmpPlistWindow::on_pbSave_clicked()
-{
-	QSettings* plist=new QSettings(QFileDialog::getSaveFileName(this,"Save playlist",""),
-								   QSettings::IniFormat);
-	plist->setValue("Playlist/FileCount",ui->lwFiles->count());
-	for(int i=0;i<ui->lwFiles->count();++i)
-	plist->setValue("Playlist/File"+QString("%1").arg(i+1,5,10,QChar('0')),ui->lwFiles->item(i)->text());
-	plist->setValue("Playlist/Repeat",repeat);
-	plist->setValue("Playlist/Shuffle",shuffle);
-	plist->sync();
-	delete plist;
-}
-
-void qmpPlistWindow::on_pbLoad_clicked()
-{
-	QSettings* plist=new QSettings(QFileDialog::getOpenFileName(this,"Load playlist",""),
-								   QSettings::IniFormat);
-	int fc=plist->value("Playlist/FileCount",0).toInt();
-	if(!fc)return;
-	ui->lwFiles->clear();for(int i=1;i<=fc;++i)
-	ui->lwFiles->addItem(plist->value("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),"").toString());
-	repeat=plist->value("Playlist/Repeat",0).toInt();
-	shuffle=plist->value("Playlist/Shuffle",0).toInt();
-	switch(shuffle)
-	{
-		case 1:
-			ui->pbShuffle->setIcon(QIcon(":/img/shuffle.png"));
-			ui->pbShuffle->setText("Shuffle On");
-		break;
-		case 0:
-		default:
-			ui->pbShuffle->setIcon(QIcon(":/img/shuffle-off.png"));
-			ui->pbShuffle->setText("Shuffle Off");
-		break;
-	}
-	switch(repeat)
-	{
-		case 0:
-			ui->pbRepeat->setIcon(QIcon(":/img/repeat-non.png"));
-			ui->pbRepeat->setText("Repeat Off");
-		break;
-		case 1:
-			ui->pbRepeat->setIcon(QIcon(":/img/repeat-one.png"));
-			ui->pbRepeat->setText("Repeat One");
-		break;
-		case 2:
-			ui->pbRepeat->setIcon(QIcon(":/img/repeat-all.png"));
-			ui->pbRepeat->setText("Repeat All");
-		break;
-	}
-	delete plist;
-}
diff --git a/qmidiplayer.src.d/qmpplistwindow.hpp b/qmidiplayer.src.d/qmpplistwindow.hpp
deleted file mode 100644
index 6ceeb60..0000000
--- a/qmidiplayer.src.d/qmpplistwindow.hpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef QMPPLISTWINDOW_H
-#define QMPPLISTWINDOW_H
-
-#include <QDialog>
-#include <QShowEvent>
-#include <QCloseEvent>
-#include <QMoveEvent>
-#include <QDropEvent>
-#include <QDragEnterEvent>
-#include <QListWidgetItem>
-
-namespace Ui {
-	class qmpPlistWindow;
-}
-
-class qmpPlistWindow : public QDialog
-{
-	Q_OBJECT
-
-	public:
-		explicit qmpPlistWindow(QWidget *parent=0);
-		~qmpPlistWindow();
-		void showEvent(QShowEvent *event);
-		void closeEvent(QCloseEvent *event);
-		void moveEvent(QMoveEvent *event);
-		void dropEvent(QDropEvent *event);
-		void dragEnterEvent(QDragEnterEvent *event);
-		int getRepeat();
-		QString getFirstItem();
-		QString getNextItem();
-		QString getPrevItem();
-		QString getSelectedItem();
-		void emptyList();
-		void insertItem(QString i);
-		void insertItems(QStringList il);
-	signals:
-		void dialogClosing();
-		void selectionChanging();
-
-	public slots:
-		void on_pbAdd_clicked();
-	private slots:
-		void on_pbAddFolder_clicked();
-		void on_pbRemove_clicked();
-		void on_pbClear_clicked();
-		void on_pbRepeat_clicked();
-		void on_pbShuffle_clicked();
-		void on_lwFiles_itemDoubleClicked();
-		void on_pbSave_clicked();
-		void on_pbLoad_clicked();
-
-	private:
-		Ui::qmpPlistWindow *ui;
-		int shuffle,repeat;//rep 0=off 1=one 2=all
-};
-
-#endif // QMPPLISTWINDOW_H
diff --git a/qmidiplayer.src.d/qmpplistwindow.ui b/qmidiplayer.src.d/qmpplistwindow.ui
deleted file mode 100644
index 99124df..0000000
--- a/qmidiplayer.src.d/qmpplistwindow.ui
+++ /dev/null
@@ -1,263 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>qmpPlistWindow</class>
- <widget class="QDialog" name="qmpPlistWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>530</width>
-    <height>321</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>530</width>
-    <height>321</height>
-   </size>
-  </property>
-  <property name="maximumSize">
-   <size>
-    <width>530</width>
-    <height>321</height>
-   </size>
-  </property>
-  <property name="acceptDrops">
-   <bool>true</bool>
-  </property>
-  <property name="windowTitle">
-   <string>Playlist</string>
-  </property>
-  <widget class="QPushButton" name="pbAdd">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>280</y>
-     <width>121</width>
-     <height>36</height>
-    </rect>
-   </property>
-   <property name="styleSheet">
-    <string notr="true">text-align:left</string>
-   </property>
-   <property name="text">
-    <string>Add</string>
-   </property>
-   <property name="icon">
-    <iconset resource="resources.qrc">
-     <normaloff>:/img/add.png</normaloff>:/img/add.png</iconset>
-   </property>
-   <property name="iconSize">
-    <size>
-     <width>32</width>
-     <height>32</height>
-    </size>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="pbAddFolder">
-   <property name="geometry">
-    <rect>
-     <x>140</x>
-     <y>280</y>
-     <width>121</width>
-     <height>36</height>
-    </rect>
-   </property>
-   <property name="styleSheet">
-    <string notr="true">text-align:left</string>
-   </property>
-   <property name="text">
-    <string>Add Folder</string>
-   </property>
-   <property name="icon">
-    <iconset resource="resources.qrc">
-     <normaloff>:/img/addfolder.png</normaloff>:/img/addfolder.png</iconset>
-   </property>
-   <property name="iconSize">
-    <size>
-     <width>32</width>
-     <height>32</height>
-    </size>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="pbRepeat">
-   <property name="geometry">
-    <rect>
-     <x>270</x>
-     <y>240</y>
-     <width>121</width>
-     <height>36</height>
-    </rect>
-   </property>
-   <property name="styleSheet">
-    <string notr="true">text-align:left</string>
-   </property>
-   <property name="text">
-    <string>Repeat Off</string>
-   </property>
-   <property name="icon">
-    <iconset resource="resources.qrc">
-     <normaloff>:/img/repeat-non.png</normaloff>:/img/repeat-non.png</iconset>
-   </property>
-   <property name="iconSize">
-    <size>
-     <width>32</width>
-     <height>32</height>
-    </size>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="pbShuffle">
-   <property name="geometry">
-    <rect>
-     <x>400</x>
-     <y>240</y>
-     <width>121</width>
-     <height>36</height>
-    </rect>
-   </property>
-   <property name="styleSheet">
-    <string notr="true">text-align:left</string>
-   </property>
-   <property name="text">
-    <string>Shuffle Off</string>
-   </property>
-   <property name="icon">
-    <iconset resource="resources.qrc">
-     <normaloff>:/img/shuffle-off.png</normaloff>:/img/shuffle-off.png</iconset>
-   </property>
-   <property name="iconSize">
-    <size>
-     <width>32</width>
-     <height>32</height>
-    </size>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="pbSave">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>240</y>
-     <width>121</width>
-     <height>36</height>
-    </rect>
-   </property>
-   <property name="styleSheet">
-    <string notr="true">text-align:left</string>
-   </property>
-   <property name="text">
-    <string>Save</string>
-   </property>
-   <property name="icon">
-    <iconset resource="resources.qrc">
-     <normaloff>:/img/save.png</normaloff>:/img/save.png</iconset>
-   </property>
-   <property name="iconSize">
-    <size>
-     <width>32</width>
-     <height>32</height>
-    </size>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="pbLoad">
-   <property name="geometry">
-    <rect>
-     <x>140</x>
-     <y>240</y>
-     <width>121</width>
-     <height>36</height>
-    </rect>
-   </property>
-   <property name="styleSheet">
-    <string notr="true">text-align:left</string>
-   </property>
-   <property name="text">
-    <string>Load</string>
-   </property>
-   <property name="icon">
-    <iconset resource="resources.qrc">
-     <normaloff>:/img/load.png</normaloff>:/img/load.png</iconset>
-   </property>
-   <property name="iconSize">
-    <size>
-     <width>32</width>
-     <height>32</height>
-    </size>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="pbRemove">
-   <property name="geometry">
-    <rect>
-     <x>270</x>
-     <y>280</y>
-     <width>121</width>
-     <height>36</height>
-    </rect>
-   </property>
-   <property name="styleSheet">
-    <string notr="true">text-align:left</string>
-   </property>
-   <property name="text">
-    <string>Remove</string>
-   </property>
-   <property name="icon">
-    <iconset resource="resources.qrc">
-     <normaloff>:/img/remove.png</normaloff>:/img/remove.png</iconset>
-   </property>
-   <property name="iconSize">
-    <size>
-     <width>32</width>
-     <height>32</height>
-    </size>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="pbClear">
-   <property name="geometry">
-    <rect>
-     <x>400</x>
-     <y>280</y>
-     <width>121</width>
-     <height>36</height>
-    </rect>
-   </property>
-   <property name="styleSheet">
-    <string notr="true">text-align:left</string>
-   </property>
-   <property name="text">
-    <string>Clear</string>
-   </property>
-   <property name="icon">
-    <iconset resource="resources.qrc">
-     <normaloff>:/img/clear.png</normaloff>:/img/clear.png</iconset>
-   </property>
-   <property name="iconSize">
-    <size>
-     <width>32</width>
-     <height>32</height>
-    </size>
-   </property>
-  </widget>
-  <widget class="QListWidget" name="lwFiles">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>10</y>
-     <width>511</width>
-     <height>221</height>
-    </rect>
-   </property>
-   <property name="acceptDrops">
-    <bool>false</bool>
-   </property>
-   <property name="dragEnabled">
-    <bool>true</bool>
-   </property>
-   <property name="dragDropMode">
-    <enum>QAbstractItemView::InternalMove</enum>
-   </property>
-  </widget>
- </widget>
- <resources>
-  <include location="resources.qrc"/>
- </resources>
- <connections/>
-</ui>
diff --git a/qmidiplayer.src.d/qmppresetselect.cpp b/qmidiplayer.src.d/qmppresetselect.cpp
deleted file mode 100644
index be589c5..0000000
--- a/qmidiplayer.src.d/qmppresetselect.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-#include <cstdio>
-#include "qmppresetselect.hpp"
-#include "ui_qmppresetselect.h"
-#include "qmpmainwindow.hpp"
-
-qmpPresetSelector::qmpPresetSelector(QWidget *parent) :
-	QDialog(parent),
-	ui(new Ui::qmpPresetSelector)
-{
-	ui->setupUi(this);
-}
-
-qmpPresetSelector::~qmpPresetSelector()
-{
-	delete ui;
-}
-
-void qmpPresetSelector::showEvent(QShowEvent *e)
-{
-	memset(presets,0,sizeof(presets));
-	CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
-	if(!plyr->getSFCount())return e->ignore();
-	int sfc=plyr->getSFCount();
-	for(int i=sfc-1;i>=0;--i)
-	{
-		fluid_sfont_t* psf=plyr->getSFPtr(i);
-		fluid_preset_t preset;
-		psf->iteration_start(psf);
-		while(psf->iteration_next(psf,&preset))
-			strcpy(presets[preset.get_banknum(&preset)][preset.get_num(&preset)],preset.get_name(&preset));
-	}
-	ui->lwBankSelect->clear();
-	ui->lwPresetSelect->clear();
-	for(int i=0;i<=128;++i)
-	{
-		int b=0;
-		for(int j=0;j<128;++j)if(strlen(presets[i][j])){b=1;break;}
-		if(b)ui->lwBankSelect->addItem(QString::number(i));
-	}
-	e->accept();
-}
-void qmpPresetSelector::setupWindow(int chid)
-{
-	CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
-	if(!plyr->getSFCount())return;
-	ch=chid;int b=0,p=0,r;char name[64];
-	sprintf(name,"Preset Selection - Channel #%d",ch+1);
-	setWindowTitle(name);
-	plyr->getChannelPreset(chid,&b,&p,name);
-	for(int i=0;i<ui->lwBankSelect->count();++i)
-	{
-		sscanf(ui->lwBankSelect->item(i)->text().toStdString().c_str(),"%d",&r);
-		if(r==b){ui->lwBankSelect->setCurrentRow(i);break;}
-	}
-	r=0;
-	ui->lwPresetSelect->clear();
-	for(int i=0,cr=0;i<128;++i)
-	if(strlen(presets[b][i]))
-	{
-		sprintf(name,"%d %s",i,presets[b][i]);
-		if(i==p)r=cr;
-		ui->lwPresetSelect->addItem(name);
-		cr++;
-	}
-	ui->lwPresetSelect->setCurrentRow(r);
-}
-
-void qmpPresetSelector::on_pbCancel_clicked()
-{
-	close();
-}
-
-void qmpPresetSelector::on_pbOk_clicked()
-{
-	CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
-	int b,p;sscanf(ui->lwBankSelect->currentItem()->text().toStdString().c_str(),"%d",&b);
-	sscanf(ui->lwPresetSelect->currentItem()->text().toStdString().c_str(),"%d",&p);
-	plyr->setChannelPreset(ch,b,p);
-	close();
-}
-
-void qmpPresetSelector::on_lwPresetSelect_itemDoubleClicked()
-{
-	on_pbOk_clicked();
-}
-
-void qmpPresetSelector::on_lwBankSelect_currentRowChanged()
-{
-	ui->lwPresetSelect->clear();
-	if(!ui->lwBankSelect->currentItem())return;
-	char name[30];int b;
-	sscanf(ui->lwBankSelect->currentItem()->text().toStdString().c_str(),"%d",&b);
-	for(int i=0;i<128;++i)
-	if(strlen(presets[b][i]))
-	{
-		sprintf(name,"%d %s",i,presets[b][i]);
-		ui->lwPresetSelect->addItem(name);
-	}
-}
diff --git a/qmidiplayer.src.d/qmppresetselect.hpp b/qmidiplayer.src.d/qmppresetselect.hpp
deleted file mode 100644
index 54f5764..0000000
--- a/qmidiplayer.src.d/qmppresetselect.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef QMPPRESETSELECT_H
-#define QMPPRESETSELECT_H
-
-#include <QDialog>
-#include <QShowEvent>
-
-namespace Ui {
-	class qmpPresetSelector;
-}
-
-class qmpPresetSelector:public QDialog
-{
-	Q_OBJECT
-
-	public:
-		explicit qmpPresetSelector(QWidget *parent = 0);
-		~qmpPresetSelector();
-		void showEvent(QShowEvent* e);
-		void setupWindow(int chid);
-
-	private slots:
-		void on_pbCancel_clicked();
-
-		void on_pbOk_clicked();
-
-		void on_lwBankSelect_currentRowChanged();
-
-		void on_lwPresetSelect_itemDoubleClicked();
-
-	private:
-		Ui::qmpPresetSelector *ui;
-		char presets[129][128][24];
-		int ch;
-};
-
-#endif // QMPPRESETSELECT_H
diff --git a/qmidiplayer.src.d/qmppresetselect.ui b/qmidiplayer.src.d/qmppresetselect.ui
deleted file mode 100644
index f18600d..0000000
--- a/qmidiplayer.src.d/qmppresetselect.ui
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>qmpPresetSelector</class>
- <widget class="QDialog" name="qmpPresetSelector">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>404</width>
-    <height>300</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>404</width>
-    <height>300</height>
-   </size>
-  </property>
-  <property name="maximumSize">
-   <size>
-    <width>404</width>
-    <height>300</height>
-   </size>
-  </property>
-  <property name="windowTitle">
-   <string>Preset Selection</string>
-  </property>
-  <property name="modal">
-   <bool>true</bool>
-  </property>
-  <widget class="QListWidget" name="lwBankSelect">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>30</y>
-     <width>71</width>
-     <height>221</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QListWidget" name="lwPresetSelect">
-   <property name="geometry">
-    <rect>
-     <x>90</x>
-     <y>30</y>
-     <width>301</width>
-     <height>221</height>
-    </rect>
-   </property>
-  </widget>
-  <widget class="QLabel" name="lbBnk">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>10</y>
-     <width>66</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Bank</string>
-   </property>
-  </widget>
-  <widget class="QLabel" name="lbPst">
-   <property name="geometry">
-    <rect>
-     <x>90</x>
-     <y>10</y>
-     <width>66</width>
-     <height>20</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Preset</string>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="pbOk">
-   <property name="geometry">
-    <rect>
-     <x>300</x>
-     <y>260</y>
-     <width>97</width>
-     <height>36</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>OK</string>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="pbCancel">
-   <property name="geometry">
-    <rect>
-     <x>190</x>
-     <y>260</y>
-     <width>97</width>
-     <height>36</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Cancel</string>
-   </property>
-  </widget>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/qmidiplayer.src.d/qmpsettingswindow.cpp b/qmidiplayer.src.d/qmpsettingswindow.cpp
deleted file mode 100644
index c2e31a2..0000000
--- a/qmidiplayer.src.d/qmpsettingswindow.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-#include <QFileDialog>
-#include <QDir>
-#include "qmpsettingswindow.hpp"
-#include "ui_qmpsettingswindow.h"
-#include "qmpmainwindow.hpp"
-
-QSettings *qmpSettingsWindow::settings=NULL;
-
-void qmpFluidForEachOpt(void* data,char* /*name*/,char* option)
-{
-	QComboBox *pcb=(QComboBox*)data;
-	pcb->addItem(option);
-}
-
-qmpSettingsWindow::qmpSettingsWindow(QWidget *parent) :
-	QDialog(parent),
-	ui(new Ui::qmpSettingsWindow)
-{
-	ui->setupUi(this);
-	connect(this,SIGNAL(dialogClosing()),parent,SLOT(dialogClosed()));
-	settings=new QSettings(QDir::homePath()+QString("/.config/qmprc"),QSettings::IniFormat);
-	settingsInit();
-}
-
-qmpSettingsWindow::~qmpSettingsWindow()
-{
-	delete settings;
-	delete ui;
-}
-
-void qmpSettingsWindow::closeEvent(QCloseEvent *event)
-{
-	setVisible(false);
-	settings->sync();
-	emit dialogClosing();
-	event->accept();
-}
-
-QListWidget* qmpSettingsWindow::getSFWidget(){return ui->lwSoundfont;}
-
-void qmpSettingsWindow::on_buttonBox_accepted()
-{
-	settingsUpdate();
-	emit dialogClosing();
-}
-
-void qmpSettingsWindow::on_buttonBox_rejected()
-{
-	settingsInit();
-	emit dialogClosing();
-}
-
-void qmpSettingsWindow::settingsInit()
-{
-	fluid_settings_t *fsettings=new_fluid_settings();
-
-	settings->setValue("Midi/DefaultOutput",settings->value("Midi/DefaultOutput","Internal FluidSynth"));
-	//this item is still a stub...
-
-	settings->setValue("Midi/DisableMapping",settings->value("Midi/DisableMapping",0));
-	ui->cbDisableMapping->setChecked(settings->value("Midi/DisableMapping",0).toInt());
-
-	settings->setValue("Midi/SendSysEx",settings->value("Midi/SendSysEx",1));
-	ui->cbSendSysx->setChecked(settings->value("Midi/SendSysEx",1).toInt());
-
-	settings->setValue("Midi/WaitVoice",settings->value("Midi/WaitVoice",1));
-	ui->cbWaitVoice->setChecked(settings->value("Midi/WaitVoice",1).toInt());
-
-	int selected=-1;
-	for(int i=0;i<ui->cbEncoding->count();++i)
-	if(ui->cbEncoding->itemText(i)==settings->value("Midi/TextEncoding","Unicode").toString())
-	{selected=i;break;}
-	if(~selected)ui->cbEncoding->setCurrentIndex(selected);
-	settings->setValue("Midi/TextEncoding",ui->cbEncoding->currentText());
-
-	fluid_settings_foreach_option(fsettings,"audio.driver",(void*)ui->cbAudioDrv,qmpFluidForEachOpt);
-	selected=-1;
-	for(int i=0;i<ui->cbAudioDrv->count();++i)
-	if(ui->cbAudioDrv->itemText(i)==settings->value("Audio/Driver","pulseaudio").toString())
-	{selected=i;break;}
-	if(~selected)ui->cbAudioDrv->setCurrentIndex(selected);
-	settings->setValue("Audio/Driver",ui->cbAudioDrv->currentText());
-
-#ifdef _WIN32
-#define DefBufSize 8192
-#else
-#define DefBufSize 128
-#endif
-	selected=-1;
-	for(int i=0;i<ui->cbBufSize->count();++i)
-	if(ui->cbBufSize->itemText(i).toInt()==settings->value("Audio/BufSize",DefBufSize).toInt())
-	{selected=i;break;}
-	if(~selected)ui->cbBufSize->setCurrentIndex(selected);
-	else if(settings->value("Audio/BufSize",DefBufSize).toInt()>=64&&settings->value("Audio/BufSize",DefBufSize).toInt()<=8192)
-		ui->cbBufSize->setCurrentText(settings->value("Audio/BufSize",DefBufSize).toString());
-	else ui->cbBufSize->setCurrentText(QString::number(DefBufSize));
-	settings->setValue("Audio/BufSize",ui->cbBufSize->currentText().toInt());
-#undef DefBufSize
-
-	selected=-1;
-	for(int i=0;i<ui->cbBufCnt->count();++i)
-	if(ui->cbBufCnt->itemText(i).toInt()==settings->value("Audio/BufCnt",2).toInt())
-	{selected=i;break;}
-	if(~selected)ui->cbBufCnt->setCurrentIndex(selected);
-	else if(settings->value("Audio/BufCnt",2).toInt()>=2&&settings->value("Audio/BufCnt",2).toInt()<=64)
-		ui->cbBufCnt->setCurrentText(settings->value("Audio/BufCnt",2).toString());
-	else ui->cbBufCnt->setCurrentText("2");
-	settings->setValue("Audio/BufCnt",ui->cbBufCnt->currentText().toInt());
-
-	selected=-1;
-	for(int i=0;i<ui->cbFormat->count();++i)
-	if(ui->cbFormat->itemText(i)==settings->value("Audio/Format","16bits").toString())
-	{selected=i;break;}
-	if(~selected)ui->cbFormat->setCurrentIndex(selected);
-	settings->setValue("Audio/Format",ui->cbFormat->currentText());
-
-	selected=-1;
-	for(int i=0;i<ui->cbFrequency->count();++i)
-	if(ui->cbFormat->itemText(i).toInt()==settings->value("Audio/Frequency",48000).toInt())
-	{selected=i;break;}
-	if(~selected)ui->cbFrequency->setCurrentIndex(selected);
-	settings->setValue("Audio/Frequency",ui->cbFrequency->currentText());
-
-	ui->sbPolyphony->setValue(settings->value("Audio/Polyphony",2048).toInt());
-	if(ui->sbPolyphony->value()<1||ui->sbPolyphony->value()>65535)ui->sbPolyphony->setValue(2048);
-	settings->setValue("Audio/Polyphony",ui->sbPolyphony->value());
-
-	ui->sbCPUCores->setValue(settings->value("Audio/Threads",1).toInt());
-	if(ui->sbCPUCores->value()<1||ui->sbCPUCores->value()>256)ui->sbCPUCores->setValue(1);
-	settings->setValue("Audio/Threads",ui->sbCPUCores->value());
-
-	settings->setValue("Audio/AutoBS",settings->value("Audio/AutoBS",1));
-	ui->cbAutoBS->setChecked(settings->value("Audio/AutoBS",1).toInt());
-	ui->lbBSMode->setText(ui->cbAutoBS->isChecked()?"Fallback bank select mode":"Bank select mode");
-
-	selected=-1;
-	for(int i=0;i<ui->cbBSMode->count();++i)
-	if(ui->cbBSMode->itemText(i)==settings->value("Audio/BankSelect","GS").toString())
-	{selected=i;break;}
-	if(~selected)ui->cbBSMode->setCurrentIndex(selected);
-	settings->setValue("Audio/BankSelect",ui->cbBSMode->currentText());
-	settings->setValue("Audio/Gain",settings->value("Audio/Gain",50));
-
-	int sfc=settings->value("SoundFonts/SFCount",0).toInt();
-	ui->lwSoundfont->clear();for(int i=1;i<=sfc;++i)
-	ui->lwSoundfont->addItem(settings->value("SoundFonts/SF"+QString::number(i),"").toString());
-	settings->setValue("SoundFonts/SFCount",sfc);
-
-	settings->setValue("Behavior/RestorePlaylist",settings->value("Behavior/RestorePlaylist",0));
-	ui->cbRestorePlaylist->setChecked(settings->value("Behavior/RestorePlaylist",0).toInt());
-
-	settings->setValue("Behavior/LoadFolder",settings->value("Behavior/LoadFolder",0));
-	ui->cbLoadFolder->setChecked(settings->value("Behavior/LoadFolder",0).toInt());
-
-	settings->setValue("Behavior/DialogStatus",settings->value("Behavior/DialogStatus",1));
-	ui->cbDialogStatus->setChecked(settings->value("Behavior/DialogStatus",1).toInt());
-
-	settings->setValue("Behavior/SaveEfxParam",settings->value("Behavior/SaveEfxParam",1));
-	ui->cbSaveEfxParam->setChecked(settings->value("Behavior/SaveEfxParam",1).toInt());
-
-	settings->setValue("Behavior/SingleInstance",settings->value("Behavior/SingleInstance",0));
-	ui->cbPersistentfs->setChecked(settings->value("Behavior/SingleInstance",0).toInt());
-
-	settings->sync();
-	delete_fluid_settings(fsettings);
-}
-
-void qmpSettingsWindow::settingsUpdate()
-{
-	settings->setValue("Midi/DefaultOutput",settings->value("Midi/DefaultOutput","Internal FluidSynth"));
-	//this item is still a stub...
-
-	settings->setValue("Midi/DisableMapping",ui->cbDisableMapping->isChecked()?1:0);
-
-	settings->setValue("Midi/SendSysEx",ui->cbSendSysx->isChecked()?1:0);
-
-	settings->setValue("Midi/WaitVoice",ui->cbWaitVoice->isChecked()?1:0);
-
-	settings->setValue("Midi/TextEncoding",ui->cbEncoding->currentText());
-
-	settings->setValue("Audio/Driver",ui->cbAudioDrv->currentText());
-
-	settings->setValue("Audio/BufSize",ui->cbBufSize->currentText().toInt());
-
-	settings->setValue("Audio/BufCnt",ui->cbBufCnt->currentText().toInt());
-
-	settings->setValue("Audio/Format",ui->cbFormat->currentText());
-
-	settings->setValue("Audio/Frequency",ui->cbFrequency->currentText());
-
-	settings->setValue("Audio/Polyphony",ui->sbPolyphony->value());
-
-	settings->setValue("Audio/Threads",ui->sbCPUCores->value());
-
-	settings->setValue("Audio/AutoBS",ui->cbAutoBS->isChecked()?1:0);
-
-	settings->setValue("Audio/BankSelect",ui->cbBSMode->currentText());
-
-	settings->setValue("SoundFonts/SFCount",ui->lwSoundfont->count());
-	for(int i=0;i<ui->lwSoundfont->count();++i)
-	settings->setValue("SoundFonts/SF"+QString::number(i+1),ui->lwSoundfont->item(i)->text());
-
-	settings->setValue("Behavior/RestorePlaylist",ui->cbRestorePlaylist->isChecked()?1:0);
-
-	settings->setValue("Behavior/LoadFolder",ui->cbLoadFolder->isChecked()?1:0);
-
-	settings->setValue("Behavior/DialogStatus",ui->cbDialogStatus->isChecked()?1:0);
-	if(!ui->cbDialogStatus->isChecked())
-	{
-		settings->remove("DialogStatus/MainW");
-		settings->remove("DialogStatus/PListW");
-		settings->remove("DialogStatus/PListWShown");
-		settings->remove("DialogStatus/ChnlW");
-		settings->remove("DialogStatus/ChnlWShown");
-		settings->remove("DialogStatus/EfxW");
-		settings->remove("DialogStatus/EfxWShown");
-		settings->remove("DialogStatus/FileDialogPath");
-	}
-
-	settings->setValue("Behavior/SaveEfxParam",ui->cbSaveEfxParam->isChecked()?1:0);
-	if(!ui->cbSaveEfxParam->isChecked())
-	{
-		settings->remove("Effects/ChorusEnabled");
-		settings->remove("Effects/ReverbEnabled");
-		settings->remove("Effects/ReverbRoom");
-		settings->remove("Effects/ReverbDamp");
-		settings->remove("Effects/ReverbWidth");
-		settings->remove("Effects/ReverbLevel");
-
-		settings->remove("Effects/ChorusFeedbk");
-		settings->remove("Effects/ChorusLevel");
-		settings->remove("Effects/ChorusRate");
-		settings->remove("Effects/ChorusDepth");
-		settings->remove("Effects/ChorusType");
-	}
-
-	settings->setValue("Behavior/SingleInstance",ui->cbPersistentfs->isChecked()?1:0);
-	settings->sync();
-}
-
-void qmpSettingsWindow::on_cbBufSize_currentTextChanged(const QString &s)
-{
-	if(s.toInt()<64||s.toInt()>8192)ui->cbBufSize->setCurrentIndex(1);
-}
-
-void qmpSettingsWindow::on_cbBufCnt_currentTextChanged(const QString &s)
-{
-	if(s.toInt()<2||s.toInt()>64)ui->cbBufCnt->setCurrentIndex(1);
-}
-
-void qmpSettingsWindow::on_pbAdd_clicked()
-{
-	QStringList sl=QFileDialog::getOpenFileNames(this,"Add File","","SoundFont files (*.sf2)");
-	for(int i=0;i<sl.size();++i)
-	{
-		ui->lwSoundfont->addItem(new QListWidgetItem(sl.at(i)));
-	}
-}
-
-void qmpSettingsWindow::on_pbRemove_clicked()
-{
-	QList<QListWidgetItem*> sl=ui->lwSoundfont->selectedItems();
-	for(int i=0;i<sl.size();++i)
-	{
-		ui->lwSoundfont->removeItemWidget(sl.at(i));
-		delete sl.at(i);
-	}
-}
-
-void qmpSettingsWindow::on_pbUp_clicked()
-{
-	int cid=ui->lwSoundfont->currentRow();
-	QListWidgetItem *ci=ui->lwSoundfont->takeItem(cid);
-	ui->lwSoundfont->insertItem(cid-1,ci);
-	ui->lwSoundfont->setCurrentRow(cid-1);
-}
-
-void qmpSettingsWindow::on_pbDown_clicked()
-{
-	int cid=ui->lwSoundfont->currentRow();
-	QListWidgetItem *ci=ui->lwSoundfont->takeItem(cid);
-	ui->lwSoundfont->insertItem(cid+1,ci);
-	ui->lwSoundfont->setCurrentRow(cid+1);
-}
-
-void qmpSettingsWindow::on_cbAutoBS_stateChanged()
-{
-	ui->lbBSMode->setText(ui->cbAutoBS->isChecked()?"Fallback bank select mode":"Bank select mode");
-}
diff --git a/qmidiplayer.src.d/qmpsettingswindow.hpp b/qmidiplayer.src.d/qmpsettingswindow.hpp
deleted file mode 100644
index c506de4..0000000
--- a/qmidiplayer.src.d/qmpsettingswindow.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef QMPSETTINGSWINDOW_H
-#define QMPSETTINGSWINDOW_H
-
-#include <QDialog>
-#include <QCloseEvent>
-#include <QSettings>
-#include <QListWidget>
-
-namespace Ui {
-	class qmpSettingsWindow;
-}
-
-class qmpSettingsWindow:public QDialog
-{
-	Q_OBJECT
-
-	public:
-		explicit qmpSettingsWindow(QWidget *parent=0);
-		~qmpSettingsWindow();
-		void closeEvent(QCloseEvent *event);
-		void settingsInit();
-		QListWidget* getSFWidget();
-	signals:
-		void dialogClosing();
-
-	private slots:
-		void on_buttonBox_accepted();
-		void on_buttonBox_rejected();
-
-		void on_cbBufSize_currentTextChanged(const QString &s);
-		void on_cbBufCnt_currentTextChanged(const QString &s);
-
-		void on_pbAdd_clicked();
-		void on_pbRemove_clicked();
-		void on_pbUp_clicked();
-		void on_pbDown_clicked();
-
-		void on_cbAutoBS_stateChanged();
-
-		private:
-		Ui::qmpSettingsWindow *ui;
-		void settingsUpdate();
-		static QSettings *settings;
-	public: static QSettings* getSettingsIntf(){return settings;}
-};
-
-#endif // QMPSETTINGSWINDOW_H
diff --git a/qmidiplayer.src.d/qmpsettingswindow.ui b/qmidiplayer.src.d/qmpsettingswindow.ui
deleted file mode 100644
index 330afa2..0000000
--- a/qmidiplayer.src.d/qmpsettingswindow.ui
+++ /dev/null
@@ -1,761 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>qmpSettingsWindow</class>
- <widget class="QDialog" name="qmpSettingsWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>494</width>
-    <height>445</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>494</width>
-    <height>445</height>
-   </size>
-  </property>
-  <property name="windowTitle">
-   <string>Settings</string>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <widget class="QTabWidget" name="tabWidget">
-     <property name="currentIndex">
-      <number>0</number>
-     </property>
-     <widget class="QWidget" name="tab">
-      <attribute name="title">
-       <string>Midi</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_4">
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_6">
-         <item>
-          <widget class="QLabel" name="lbOutputDevice">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Default Output Device</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QComboBox" name="cbOutputDevice">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <item>
-            <property name="text">
-             <string>Internal FluidSynth</string>
-            </property>
-           </item>
-          </widget>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <widget class="QCheckBox" name="cbDisableMapping">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="text">
-          <string>Disable Midi Mapping</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QCheckBox" name="cbSendSysx">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="text">
-          <string>Send SysEx</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QCheckBox" name="cbWaitVoice">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="text">
-          <string>Wait for remaining voices before stopping</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_7">
-         <item>
-          <widget class="QLabel" name="lbEncoding">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="text">
-            <string>Text Encoding</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QComboBox" name="cbEncoding">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <item>
-            <property name="text">
-             <string>Unicode</string>
-            </property>
-           </item>
-           <item>
-            <property name="text">
-             <string>Big5</string>
-            </property>
-           </item>
-           <item>
-            <property name="text">
-             <string>Big5-HKSCS</string>
-            </property>
-           </item>
-           <item>
-            <property name="text">
-             <string>CP949</string>
-            </property>
-           </item>
-           <item>
-            <property name="text">
-             <string>EUC-JP</string>
-            </property>
-           </item>
-           <item>
-            <property name="text">
-             <string>EUC-KR</string>
-            </property>
-           </item>
-           <item>
-            <property name="text">
-             <string>GB18030</string>
-            </property>
-           </item>
-           <item>
-            <property name="text">
-             <string>KOI8-R</string>
-            </property>
-           </item>
-           <item>
-            <property name="text">
-             <string>KOI8-U</string>
-            </property>
-           </item>
-           <item>
-            <property name="text">
-             <string>Macintosh</string>
-            </property>
-           </item>
-           <item>
-            <property name="text">
-             <string>Shift-JIS</string>
-            </property>
-           </item>
-          </widget>
-         </item>
-        </layout>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tab_2">
-      <attribute name="title">
-       <string>Synth</string>
-      </attribute>
-      <layout class="QGridLayout" name="gridLayout_2">
-       <item row="2" column="0">
-        <widget class="QLabel" name="lbBufCnt">
-         <property name="text">
-          <string>Audio Buffer Count</string>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="0">
-        <widget class="QLabel" name="lbBufSize">
-         <property name="text">
-          <string>Audio Buffer Size</string>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="1">
-        <widget class="QComboBox" name="cbBufSize">
-         <property name="editable">
-          <bool>true</bool>
-         </property>
-         <property name="currentIndex">
-          <number>1</number>
-         </property>
-         <item>
-          <property name="text">
-           <string>64</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>128</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>256</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>512</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>1024</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>2048</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>4096</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>8192</string>
-          </property>
-         </item>
-        </widget>
-       </item>
-       <item row="4" column="0">
-        <widget class="QLabel" name="lbFrequency">
-         <property name="text">
-          <string>Audio Frequency</string>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="1">
-        <widget class="QComboBox" name="cbBufCnt">
-         <property name="editable">
-          <bool>true</bool>
-         </property>
-         <item>
-          <property name="text">
-           <string>2</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>4</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>8</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>16</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>32</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>64</string>
-          </property>
-         </item>
-        </widget>
-       </item>
-       <item row="0" column="0">
-        <widget class="QLabel" name="lbAudioDrv">
-         <property name="text">
-          <string>Audio Driver</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="1">
-        <widget class="QComboBox" name="cbFormat">
-         <item>
-          <property name="text">
-           <string>16bits</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>float</string>
-          </property>
-         </item>
-        </widget>
-       </item>
-       <item row="0" column="1">
-        <widget class="QComboBox" name="cbAudioDrv"/>
-       </item>
-       <item row="4" column="1">
-        <widget class="QComboBox" name="cbFrequency">
-         <property name="currentIndex">
-          <number>2</number>
-         </property>
-         <item>
-          <property name="text">
-           <string>22050</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>44100</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>48000</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>96000</string>
-          </property>
-         </item>
-        </widget>
-       </item>
-       <item row="3" column="0">
-        <widget class="QLabel" name="lbFormat">
-         <property name="text">
-          <string>Audio Format</string>
-         </property>
-        </widget>
-       </item>
-       <item row="5" column="1">
-        <widget class="QSpinBox" name="sbPolyphony">
-         <property name="minimum">
-          <number>1</number>
-         </property>
-         <property name="maximum">
-          <number>65535</number>
-         </property>
-         <property name="value">
-          <number>2048</number>
-         </property>
-        </widget>
-       </item>
-       <item row="5" column="0">
-        <widget class="QLabel" name="lbPolyphony">
-         <property name="text">
-          <string>Max Polyphony</string>
-         </property>
-        </widget>
-       </item>
-       <item row="7" column="0">
-        <widget class="QCheckBox" name="cbAutoBS">
-         <property name="text">
-          <string>Auto bank select mode</string>
-         </property>
-        </widget>
-       </item>
-       <item row="8" column="0">
-        <widget class="QLabel" name="lbBSMode">
-         <property name="text">
-          <string>Bank select mode</string>
-         </property>
-        </widget>
-       </item>
-       <item row="8" column="1">
-        <widget class="QComboBox" name="cbBSMode">
-         <property name="currentIndex">
-          <number>1</number>
-         </property>
-         <item>
-          <property name="text">
-           <string>Ignored</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>CC#0</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>CC#32</string>
-          </property>
-         </item>
-         <item>
-          <property name="text">
-           <string>CC#0*128+CC#32</string>
-          </property>
-         </item>
-        </widget>
-       </item>
-       <item row="6" column="0">
-        <widget class="QLabel" name="lbCPUCores">
-         <property name="text">
-          <string>CPU Cores</string>
-         </property>
-        </widget>
-       </item>
-       <item row="6" column="1">
-        <widget class="QSpinBox" name="sbCPUCores">
-         <property name="minimum">
-          <number>1</number>
-         </property>
-         <property name="maximum">
-          <number>256</number>
-         </property>
-        </widget>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tab_3">
-      <attribute name="title">
-       <string>Soundfonts</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_2">
-       <item>
-        <widget class="QListWidget" name="lwSoundfont">
-         <property name="dragDropMode">
-          <enum>QAbstractItemView::InternalMove</enum>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout">
-         <item>
-          <widget class="QPushButton" name="pbAdd">
-           <property name="text">
-            <string/>
-           </property>
-           <property name="icon">
-            <iconset resource="resources.qrc">
-             <normaloff>:/img/add.png</normaloff>:/img/add.png</iconset>
-           </property>
-           <property name="iconSize">
-            <size>
-             <width>24</width>
-             <height>24</height>
-            </size>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QPushButton" name="pbRemove">
-           <property name="text">
-            <string/>
-           </property>
-           <property name="icon">
-            <iconset resource="resources.qrc">
-             <normaloff>:/img/remove.png</normaloff>:/img/remove.png</iconset>
-           </property>
-           <property name="iconSize">
-            <size>
-             <width>24</width>
-             <height>24</height>
-            </size>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QPushButton" name="pbUp">
-           <property name="text">
-            <string/>
-           </property>
-           <property name="icon">
-            <iconset resource="resources.qrc">
-             <normaloff>:/img/up.png</normaloff>:/img/up.png</iconset>
-           </property>
-           <property name="iconSize">
-            <size>
-             <width>24</width>
-             <height>24</height>
-            </size>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QPushButton" name="pbDown">
-           <property name="text">
-            <string/>
-           </property>
-           <property name="icon">
-            <iconset resource="resources.qrc">
-             <normaloff>:/img/down.png</normaloff>:/img/down.png</iconset>
-           </property>
-           <property name="iconSize">
-            <size>
-             <width>24</width>
-             <height>24</height>
-            </size>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="tab_4">
-      <attribute name="title">
-       <string>Behavior</string>
-      </attribute>
-      <layout class="QVBoxLayout" name="verticalLayout_3">
-       <item>
-        <widget class="QCheckBox" name="cbRestorePlaylist">
-         <property name="text">
-          <string>Restore last playlist on startup</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QCheckBox" name="cbLoadFolder">
-         <property name="text">
-          <string>Load files in the same folder</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QCheckBox" name="cbDialogStatus">
-         <property name="text">
-          <string>Save dialog status</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QCheckBox" name="cbSaveEfxParam">
-         <property name="text">
-          <string>Save parameters in effects window</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QCheckBox" name="cbPersistentfs">
-         <property name="text">
-          <string>Persistent fluidsynth instance</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_2">
-         <item>
-          <widget class="QLabel" name="lbVisualMode">
-           <property name="text">
-            <string>Visualization Mode</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QComboBox" name="cbVisualMode"/>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_3">
-         <item>
-          <widget class="QLabel" name="lbViewDist">
-           <property name="text">
-            <string>View distance</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer name="horizontalSpacer">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>50</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-         <item>
-          <widget class="QSlider" name="hsViewDist">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
-             <horstretch>60</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QSpinBox" name="sbViewDist"/>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_4">
-         <item>
-          <widget class="QLabel" name="lbNoteStretch">
-           <property name="text">
-            <string>Note stretch</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer name="horizontalSpacer_2">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>60</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-         <item>
-          <widget class="QSlider" name="hsNoteStretch">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
-             <horstretch>60</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QSpinBox" name="sbNoteStretch"/>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_5">
-         <item>
-          <widget class="QLabel" name="lbFog">
-           <property name="text">
-            <string>Fog Start</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer name="horizontalSpacer_3">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeType">
-            <enum>QSizePolicy::Expanding</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>82</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-         <item>
-          <widget class="QSlider" name="hsFog">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
-             <horstretch>60</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QSpinBox" name="sbFog"/>
-         </item>
-        </layout>
-       </item>
-      </layout>
-     </widget>
-    </widget>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <resources>
-  <include location="resources.qrc"/>
- </resources>
- <connections>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>qmpSettingsWindow</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>qmpSettingsWindow</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/qmidiplayer.src.d/resources.qrc b/qmidiplayer.src.d/resources.qrc
deleted file mode 100644
index 351d2fa..0000000
--- a/qmidiplayer.src.d/resources.qrc
+++ /dev/null
@@ -1,36 +0,0 @@
-<RCC>
-    <qresource prefix="/">
-        <file>../img/add.png</file>
-        <file>../img/list.png</file>
-        <file>../img/addfolder.png</file>
-        <file>../img/channel.png</file>
-        <file>../img/prev.png</file>
-        <file>../img/qmidiplyr.png</file>
-        <file>../img/remove.png</file>
-        <file>../img/clear.png</file>
-        <file>../img/down.png</file>
-        <file>../img/effects.png</file>
-        <file>../img/repeat-all.png</file>
-        <file>../img/repeat-base.png</file>
-        <file>../img/repeat-non.png</file>
-        <file>../img/load.png</file>
-        <file>../img/next.png</file>
-        <file>../img/repeat-one.png</file>
-        <file>../img/save.png</file>
-        <file>../img/settings.png</file>
-        <file>../img/pause.png</file>
-        <file>../img/play.png</file>
-        <file>../img/shuffle-off.png</file>
-        <file>../img/shuffle.png</file>
-        <file>../img/stop.png</file>
-        <file>../img/up.png</file>
-        <file>../img/visualization.png</file>
-        <file>../img/mainw.png</file>
-        <file>../img/chanw.png</file>
-        <file>../doc/index.html</file>
-        <file>../doc/version.html</file>
-        <file>../doc/license.html</file>
-        <file>../doc/mainwindow.html</file>
-        <file>../doc/channeldialog.html</file>
-    </qresource>
-</RCC>
diff --git a/qmidiplayerlite.pro b/qmidiplayerlite.pro
deleted file mode 100644
index be7679d..0000000
--- a/qmidiplayerlite.pro
+++ /dev/null
@@ -1,24 +0,0 @@
-TEMPLATE = app
-
-QT += qml quick
-unix:QT += widgets
-win32:QT += widgets
-CONFIG += c++11
-
-SOURCES += ./qmidiplayerlite.src.d/main.cpp \
-	./common/qmpmidiplay.cpp \
-	./common/qmpmidiread.cpp
-
-RESOURCES += ./qmidiplayerlite.src.d/qml.qrc
-
-# Additional import path used to resolve QML modules in Qt Creator's code model
-QML_IMPORT_PATH =
-
-# Default rules for deployment.
-include(./qmidiplayerlite.src.d/deployment.pri)
-
-HEADERS += \
-	./common/qmpmidiplay.hpp \
-	./qmidiplayerlite.src.d/qmpcorewrapper.hpp
-
-LIBS += -lfluidsynth
diff --git a/qmidiplayerlite.src.d/deployment.pri b/qmidiplayerlite.src.d/deployment.pri
deleted file mode 100644
index 265ce71..0000000
--- a/qmidiplayerlite.src.d/deployment.pri
+++ /dev/null
@@ -1,13 +0,0 @@
-unix:!android {
-    isEmpty(target.path) {
-        qnx {
-            target.path = /tmp/$${TARGET}/bin
-        } else {
-            target.path = /opt/$${TARGET}/bin
-        }
-        export(target.path)
-    }
-    INSTALLS += target
-}
-
-export(INSTALLS)
diff --git a/qmidiplayerlite.src.d/main.cpp b/qmidiplayerlite.src.d/main.cpp
deleted file mode 100644
index 1a87b33..0000000
--- a/qmidiplayerlite.src.d/main.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <QApplication>
-#include <QtQml>
-#include <QQmlApplicationEngine>
-#include "qmpcorewrapper.hpp"
-
-int main(int argc, char *argv[])
-{
-	QApplication app(argc, argv);
-	qmlRegisterType<CQMPCoreWrapper>("org.chrisoft.qmpcore",1,0,"CQMPCoreWrapper");
-
-	QQmlApplicationEngine engine;
-	engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
-
-	return app.exec();
-}
diff --git a/qmidiplayerlite.src.d/main.qml b/qmidiplayerlite.src.d/main.qml
deleted file mode 100644
index 0ec0975..0000000
--- a/qmidiplayerlite.src.d/main.qml
+++ /dev/null
@@ -1,144 +0,0 @@
-import QtQuick 2.3
-import QtQuick.Window 2.2
-import QtQuick.Controls 1.0
-import QtQuick.Dialogs 1.0
-import org.chrisoft.qmpcore 1.0
-
-Window {
-	id: window1
-	width: 420
-	height: 240
-	title: "QMidiPlayer Lite"
-	visible: true
-	property bool playing
-	playing: false
-
-	MouseArea {
-		id: mouseArea1
-		anchors.rightMargin: 0
-		anchors.bottomMargin: 0
-		anchors.leftMargin: 0
-		anchors.topMargin: 0
-		anchors.fill: parent
-		onClicked: {
-			//Qt.quit();
-		}
-
-		Button {
-			id: button2
-			x: 170
-			text: qsTr("Play")
-			anchors.top: parent.top
-			anchors.topMargin: 172
-			anchors.horizontalCenter: parent.horizontalCenter
-			onClicked: {
-				if(!playing)
-				{
-					qmpcore.loadFile(fileName.text);
-					qmpcore.initFluidSynth();
-					qmpcore.playFile();
-					playing=true;
-					uiTimer.start();
-					text="Stop";
-				}
-				else
-				{
-					qmpcore.stop();
-					playing=false;
-					text="Play";
-					hsTimer.value=0;uiTimer.stop();
-				}
-			}
-		}
-
-		Slider {
-			id: hsTimer
-			y: 210
-			height: 22
-			anchors.right: parent.right
-			anchors.rightMargin: 8
-			anchors.left: parent.left
-			anchors.leftMargin: 8
-			anchors.bottom: parent.bottom
-			anchors.bottomMargin: 8
-			tickmarksEnabled: false
-			stepSize: 1
-			maximumValue: 100
-			property bool autovalchange: false
-			onValueChanged: {
-				if(autovalchange||pressed)return;
-				if(playing){qmpcore.setTCeptr(value);qmpcore.panic();}
-			}
-			onPressedChanged: {
-				if(!pressed)
-				{
-					/*if(playing)
-					{
-						if(ui->hsTimer->value()==100){on_pbNext_clicked();return;}
-						player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value());
-						player->playerPanic();
-						offset=ui->hsTimer->value()/100.*player->getFtime();
-						st=std::chrono::steady_clock::now();
-					}
-					else
-					{
-						player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value());
-						offset=ui->hsTimer->value()/100.*player->getFtime();
-						char ts[100];
-						sprintf(ts,"%02d:%02d",(int)(offset)/60,(int)(offset)%60);
-						ui->lbCurTime->setText(ts);
-					}*/
-					if(playing){qmpcore.setTCeptr(value);qmpcore.panic();}
-				}
-			}
-		}
-	}
-
-	CQMPCoreWrapper {
-		id: qmpcore
-	}
-	Timer {
-		id: uiTimer
-		interval: 100
-		running: false
-		repeat: true
-		onTriggered: {
-			if(!hsTimer.pressed)
-			{
-				hsTimer.autovalchange=true;
-				hsTimer.value=qmpcore.getProgress();
-				hsTimer.autovalchange=false;
-			}
-		}
-	}
-
-	Text {
-		id: fileName
-		text: qsTr("...")
-		anchors.centerIn: parent
-	}
-
-	Button {
-		id: button1
-		x: 170
-		width: 80
-		height: 27
-		text: qsTr("Open")
-		anchors.top: parent.top
-		anchors.topMargin: 142
-		anchors.horizontalCenter: parent.horizontalCenter
-		onClicked: {
-			fileDialog.open();
-		}
-	}
-
-	FileDialog {
-		id: fileDialog
-		title: qsTr("Select midi file")
-		nameFilters: ["MIDI Files (*.mid *.midi)"]
-		onAccepted: {
-			fileName.text=fileUrl;
-		}
-	}
-}
-
diff --git a/qmidiplayerlite.src.d/qml.qrc b/qmidiplayerlite.src.d/qml.qrc
deleted file mode 100644
index 5f6483a..0000000
--- a/qmidiplayerlite.src.d/qml.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
-    <qresource prefix="/">
-        <file>main.qml</file>
-    </qresource>
-</RCC>
diff --git a/qmidiplayerlite.src.d/qmpcorewrapper.hpp b/qmidiplayerlite.src.d/qmpcorewrapper.hpp
deleted file mode 100644
index 558ed74..0000000
--- a/qmidiplayerlite.src.d/qmpcorewrapper.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef QMPCOREWRAPPER_H
-#define QMPCOREWRAPPER_H
-#include <QObject>
-#include <QUrl>
-#include <thread>
-#include <fluidsynth.h>
-#include "../common/qmpmidiplay.hpp"
-class CQMPCoreWrapper:public QObject
-{
-	Q_OBJECT
-private:
-	CMidiPlayer *mp;
-	std::thread *playerTh;
-	int curprog;
-public:
-	explicit CQMPCoreWrapper(QObject* parent=0):QObject(parent)
-	{
-		mp=new CMidiPlayer(false);
-	}
-	~CQMPCoreWrapper(){delete mp;}
-	Q_INVOKABLE void initFluidSynth()
-	{
-		fluid_settings_t *fsettings=mp->getFluidSettings();
-		fluid_settings_setstr(fsettings,"audio.driver","pulseaudio");
-		mp->fluidInitialize();
-		mp->pushSoundFont("/media/Files/FluidR3_Ext.sf2");
-	}
-	Q_INVOKABLE void deinitFluidSynth()
-	{
-		mp->fluidDeinitialize();
-	}
-	Q_INVOKABLE void loadFile(QUrl file)
-	{
-		mp->playerLoadFile(file.toLocalFile().toStdString().c_str());
-		mp->playerInit();curprog=0;
-	}
-	Q_INVOKABLE void playFile()
-	{
-		playerTh=new std::thread(&CMidiPlayer::playerThread,mp);
-	}
-	Q_INVOKABLE void stop()
-	{
-		mp->playerDeinit();playerTh->join();delete playerTh;
-	}
-	Q_INVOKABLE int getProgress()
-	{
-		while(!mp->isFinished()&&mp->getTCeptr()>mp->getStamp(curprog)
-			  &&curprog<=100)
-			++curprog;
-		return curprog;
-	}
-	Q_INVOKABLE void panic(){mp->playerPanic();}
-	Q_INVOKABLE void setTCeptr(int perct)
-	{
-		mp->setTCeptr(mp->getStamp(perct),perct);curprog=perct;
-	}
-};
-#endif // QMPCOREWRAPPER_H
diff --git a/qmidiplayerlite.src.d/qmpmidiplay.cpp b/qmidiplayerlite.src.d/qmpmidiplay.cpp
deleted file mode 100644
index baec9a2..0000000
--- a/qmidiplayerlite.src.d/qmpmidiplay.cpp
+++ /dev/null
@@ -1,406 +0,0 @@
-#include <cstdio>
-#include <chrono>
-#include <thread>
-#include <fluidsynth.h>
-#include "qmpmidiplay.hpp"
-#ifdef _WIN32
-#include <windows.h>
-uint64_t pf;
-#endif
-void CMidiPlayer::fluidPreInitialize()
-{
-	settings=new_fluid_settings();
-}
-void CMidiPlayer::fluidInitialize()
-{
-	synth=new_fluid_synth(settings);
-	adriver=new_fluid_audio_driver(settings,synth);
-	fluid_synth_set_chorus(synth,FLUID_CHORUS_DEFAULT_N,FLUID_CHORUS_DEFAULT_LEVEL,
-						   FLUID_CHORUS_DEFAULT_SPEED,FLUID_CHORUS_DEFAULT_DEPTH,
-						   FLUID_CHORUS_DEFAULT_TYPE);
-#ifndef _WIN32
-	if(!singleInstance)
-	{
-		if(midiFile->getStandard()==4)
-		fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_MELODIC);
-		else if(midiFile->getStandard()==1)
-			fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_DRUM);
-		else
-		{
-			fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_DRUM);
-			fluid_synth_bank_select(synth,9,128);
-		}
-	}
-#endif
-}
-void CMidiPlayer::fluidDeinitialize()
-{
-	if(!synth||!adriver||!settings)return;
-	delete_fluid_settings(settings);
-	delete_fluid_audio_driver(adriver);
-	delete_fluid_synth(synth);
-	settings=NULL;synth=NULL;adriver=NULL;
-}
-void CMidiPlayer::processEvent(const SEvent *e)
-{
-	switch(e->type&0xF0)
-	{
-		case 0x80://Note off
-			fluid_synth_noteoff(synth,e->type&0x0F,e->p1);
-		break;
-		case 0x90://Note on
-			if((mute>>(e->type&0x0F))&1)break;//muted
-			if(solo&&!((solo>>(e->type&0x0F))&1))break;
-			fluid_synth_noteon(synth,e->type&0x0F,e->p1,e->p2);
-		break;
-		case 0xB0://CC
-			if(e->p1==100)rpnid=e->p2;
-			if(e->p1==6)rpnval=e->p2;
-			if(~rpnid&&~rpnval)
-			{
-				if(rpnid==0)fluid_synth_pitch_wheel_sens(synth,e->type&0x0F,rpnval);
-				rpnid=rpnval=-1;
-			}
-			fluid_synth_cc(synth,e->type&0x0F,e->p1,e->p2);
-		break;
-		case 0xC0://PC
-			fluid_synth_program_change(synth,e->type&0x0F,e->p1);
-		break;
-		case 0xE0://PW
-			fluid_synth_pitch_bend(synth,e->type&0x0F,e->p1);
-		break;
-		case 0xF0://Meta/SysEx
-			if((e->type&0x0F)==0x0F)
-			{
-				switch(e->p1)
-				{
-					case 0x51:
-						ctempo=e->p2;dpt=ctempo*1000/divs;
-					break;
-					case 0x58:
-						ctsn=e->p2>>24;
-						ctsd=1<<((e->p2>>16)&0xFF);
-					break;
-					case 0x59:
-						cks=e->p2;
-					break;
-					case 0x01:case 0x02:case 0x03:
-					case 0x04:case 0x05:case 0x06:
-					case 0x07:
-						if(e->str)puts(e->str);
-					break;
-				}
-			}
-			if((e->type&0x0F)==0x00||(e->type&0x0F)==07)
-			{
-				int io=0;
-				if(sendSysEx)fluid_synth_sysex(synth,e->str,e->p1,NULL,&io,NULL,0);
-			}
-		break;
-	}
-}
-void CMidiPlayer::processEventStub(const SEvent *e)
-{
-	switch(e->type&0xF0)
-	{
-		case 0xB0://CC
-			if(e->p1==100)rpnid=e->p2;
-			if(e->p1==6)rpnval=e->p2;
-			if(~rpnid&&~rpnval)
-			{
-				if(rpnid==0)ccc[e->type&0x0F][134]=rpnval;
-				rpnid=rpnval=-1;
-			}
-			ccc[e->type&0x0F][e->p1]=e->p2;
-		break;
-		case 0xC0://PC
-			ccc[e->type&0x0F][128]=e->p1;
-		break;
-		case 0xD0://CP
-			ccc[e->type&0x0F][129]=e->p1;
-		break;
-		case 0xE0://PW
-			ccc[e->type&0x0F][130]=e->p1;
-		break;
-		case 0xF0://Meta/SysEx
-			if((e->type&0x0F)==0x0F)
-			{
-				switch(e->p1)
-				{
-					case 0x51:
-						ctempo=e->p2;dpt=ctempo*1000/divs;
-						ccc[0][131]=dpt;
-					break;
-					case 0x58:
-						ccc[0][132]=e->p2;
-					break;
-					case 0x59:
-						ccc[0][133]=e->p2;
-					break;
-				}
-			}
-		break;
-	}
-}
-#ifdef _WIN32
-void w32usleep(uint64_t t)
-{
-	uint64_t st=0,ct=0;
-	QueryPerformanceCounter((LARGE_INTEGER*)&st);
-	do{
-		if(t>10000+(ct-st)*1000000/pf)Sleep((t-(ct-st)*1000000/pf)/2000);
-		else if(t>5000+(ct-st)*1000000/pf)Sleep(1);
-		else std::this_thread::yield();
-		QueryPerformanceCounter((LARGE_INTEGER*)&ct);
-	}while((ct-st)*1000000<t*pf);
-}
-#endif
-void CMidiPlayer::playEvents()
-{
-	for(uint32_t ct=midiFile->getEvent(0)->time;tceptr<midiFile->getEventCount();)
-	{
-		while(tcpaused)std::this_thread::sleep_for(std::chrono::milliseconds(100));
-		while(!tcstop&&midiFile&&tceptr<midiFile->getEventCount()&&ct==midiFile->getEvent(tceptr)->time)
-			processEvent(midiFile->getEvent(tceptr++));
-		if(tcstop||!midiFile||tceptr>=midiFile->getEventCount())break;
-		if(resumed)resumed=false;
-		else
-#ifdef _WIN32
-		w32usleep((midiFile->getEvent(tceptr)->time-ct)*(dpt/1000));
-#else
-		std::this_thread::sleep_for(std::chrono::nanoseconds(midiFile->getEvent(tceptr)->time-ct)*dpt);
-#endif
-		if(tcstop||!midiFile)break;
-		ct=midiFile->getEvent(tceptr)->time;
-	}
-	while(!tcstop&&synth&&(waitvoice&&fluid_synth_get_active_voice_count(synth)>0))std::this_thread::sleep_for(std::chrono::milliseconds(2));
-	finished=1;
-}
-void CMidiPlayer::fileTimer1Pass()
-{
-	ftime=.0;ctempo=0x7A120;dpt=ctempo*1000/divs;
-	for(uint32_t eptr=0,ct=midiFile->getEvent(0)->time;eptr<midiFile->getEventCount();)
-	{
-		while(eptr<midiFile->getEventCount()&&ct==midiFile->getEvent(eptr)->time)
-			processEventStub(midiFile->getEvent(eptr++));
-		if(eptr>=midiFile->getEventCount())break;
-		ftime+=(midiFile->getEvent(eptr)->time-ct)*dpt/1e9;
-		ct=midiFile->getEvent(eptr)->time;
-	}
-}
-void CMidiPlayer::fileTimer2Pass()
-{
-	double ctime=.0;uint32_t c=1;ctempo=0x7A120;dpt=ctempo*1000/divs;
-	memset(stamps,0,sizeof(stamps));memset(ccstamps,0,sizeof(ccstamps));
-	memset(ccc,0,sizeof(ccc));rpnid=rpnval=-1;for(int i=0;i<16;++i)
-	{
-		ccc[i][7]=100;ccc[i][10]=64;ccc[i][11]=127;
-		ccc[i][11]=127;ccc[i][71]=64;ccc[i][72]=64;
-		ccc[i][73]=64;ccc[i][74]=64;ccc[i][75]=64;
-		ccc[i][76]=64;ccc[i][77]=64;ccc[i][78]=64;
-		ccc[0][131]=dpt;ccc[0][132]=0x04021808;
-		ccc[0][133]=0;ccc[0][134]=2;
-	}if(midiFile->getStandard()!=4)ccc[9][0]=128;
-	for(int i=0;i<16;++i)for(int j=0;j<135;++j)
-		ccstamps[0][i][j]=ccc[i][j];
-	for(uint32_t eptr=0,ct=midiFile->getEvent(0)->time;eptr<midiFile->getEventCount();)
-	{
-		while(eptr<midiFile->getEventCount()&&ct==midiFile->getEvent(eptr)->time)
-			processEventStub(midiFile->getEvent(eptr++));
-		if(eptr>=midiFile->getEventCount())break;
-		ctime+=(midiFile->getEvent(eptr)->time-ct)*dpt/1e9;
-		while(ctime>ftime*c/100.)
-		{
-			for(int i=0;i<16;++i)for(int j=0;j<135;++j)
-				ccstamps[c][i][j]=ccc[i][j];
-			stamps[c++]=eptr;
-			if(c>100)break;
-		}
-		ct=midiFile->getEvent(eptr)->time;
-	}
-	while(c<101)
-	{
-		for(int i=0;i<16;++i)for(int j=0;j<135;++j)
-			ccstamps[c][i][j]=ccc[i][j];
-		stamps[c++]=midiFile->getEventCount();
-	}
-}
-CMidiPlayer::CMidiPlayer(bool singleInst)
-{
-	midiFile=NULL;resumed=false;singleInstance=singleInst;
-	settings=NULL;synth=NULL;adriver=NULL;waitvoice=true;
-#ifdef _WIN32
-	QueryPerformanceFrequency((LARGE_INTEGER*)&pf);
-	timeBeginPeriod(1);
-#endif
-}
-CMidiPlayer::~CMidiPlayer()
-{
-	if(singleInstance)fluidDeinitialize();
-#ifdef _WIN32
-	timeEndPeriod(1);
-#endif
-}
-void CMidiPlayer::playerPanic(bool reset)
-{
-	if(reset)for(int i=0;i<16;++i)
-	{
-		fluid_synth_pitch_bend(synth,i,8192);
-		fluid_synth_cc(synth,i,7,100);
-		fluid_synth_cc(synth,i,10,64);
-		fluid_synth_cc(synth,i,11,127);
-	}
-	for(int i=0;i<16;++i)fluid_synth_all_notes_off(synth,i);
-}
-bool CMidiPlayer::playerLoadFile(const char* fn)
-{
-	midiFile=new CMidiFile(fn);
-	if(!midiFile->isValid())return false;
-	divs=midiFile->getDivision();
-	fileTimer1Pass();
-	fileTimer2Pass();
-	return true;
-}
-void CMidiPlayer::playerInit()
-{
-	ctempo=0x7A120;ctsn=4;ctsd=4;cks=0;dpt=ctempo*1000/divs;
-	tceptr=0;tcstop=0;tcpaused=0;finished=0;mute=solo=0;
-	sendSysEx=true;rpnid=rpnval=-1;
-	if(!singleInstance)fluidPreInitialize();
-}
-void CMidiPlayer::playerDeinit()
-{
-	tceptr=0;tcstop=1;tcpaused=0;
-	delete midiFile;midiFile=NULL;
-	if(!singleInstance)fluidDeinitialize();
-}
-void CMidiPlayer::playerThread()
-{
-	playEvents();
-}
-
-void CMidiPlayer::rendererLoadFile(const char* ofn)
-{
-	settings=new_fluid_settings();
-	fluid_settings_setstr(settings,"audio.file.name",ofn);
-}
-void CMidiPlayer::rendererInit(const char* fn)
-{
-	finished=0;
-	synth=new_fluid_synth(settings);
-	player=new_fluid_player(synth);
-	fluid_player_add(player,fn);
-}
-void CMidiPlayer::rendererThread()
-{
-	fluid_file_renderer_t* renderer=new_fluid_file_renderer(synth);
-	fluid_player_play(player);
-	while(fluid_player_get_status(player)==FLUID_PLAYER_PLAYING)
-		if(fluid_file_renderer_process_block(renderer)!=FLUID_OK)break;
-	delete_fluid_file_renderer(renderer);
-	finished=1;
-}
-void CMidiPlayer::rendererDeinit()
-{
-	delete_fluid_player(player);
-	delete_fluid_synth(synth);
-	delete_fluid_settings(settings);
-	player=NULL;synth=NULL;settings=NULL;
-}
-
-void CMidiPlayer::sendSysX(bool send){sendSysEx=send;}
-uint32_t CMidiPlayer::getStamp(int id){return stamps[id];}
-uint32_t CMidiPlayer::getTCeptr(){return tceptr;}
-void CMidiPlayer::setTCeptr(uint32_t ep,uint32_t st)
-{
-	resumed=true;
-	if(ep==midiFile->getEventCount())tcstop=1;else tceptr=ep;
-	for(int i=0;i<16;++i)
-	{
-		for(int j=0;j<120;++j)fluid_synth_cc(synth,i,j,ccstamps[st][i][j]);
-		fluid_synth_program_change(synth,i,ccstamps[st][i][128]);
-		//fluid_synth_pitch_bend(synth,i,ccstamps[st][i][130]);
-		dpt=ccstamps[st][0][131];ctempo=dpt*divs/1000;
-		ctsn=ccstamps[st][0][132]>>24;ctsd=1<<((ccstamps[st][0][132]>>16)&0xFF);
-		cks=ccstamps[st][0][133];
-	}
-}
-double CMidiPlayer::getFtime(){return ftime;}
-void CMidiPlayer::getCurrentTimeSignature(int *n,int *d){*n=ctsn;*d=ctsd;}
-void CMidiPlayer::getCurrentKeySignature(int *ks){*ks=cks;}
-uint32_t CMidiPlayer::getFileNoteCount(){return midiFile?midiFile->getNoteCount():0;}
-uint32_t CMidiPlayer::getFileStandard(){return midiFile?midiFile->getStandard():0;}
-const char* CMidiPlayer::getTitle(){return midiFile?midiFile->getTitle():"";}
-const char* CMidiPlayer::getCopyright(){return midiFile?midiFile->getCopyright():"";}
-double CMidiPlayer::getTempo(){return 60./(ctempo/1e6)/**ctsd/4.*/;}
-uint32_t CMidiPlayer::getTCpaused(){return tcpaused;}
-void CMidiPlayer::setTCpaused(uint32_t ps){tcpaused=ps;}
-uint32_t CMidiPlayer::isFinished(){return finished;}
-void CMidiPlayer::setResumed(){resumed=true;}
-void CMidiPlayer::setWaitVoice(bool wv){waitvoice=wv;}
-void CMidiPlayer::setGain(double gain){if(settings)fluid_settings_setnum(settings,"synth.gain",gain);}
-int CMidiPlayer::getPolyphone(){return synth?fluid_synth_get_active_voice_count(synth):0;}
-int CMidiPlayer::getMaxPolyphone(){return synth?fluid_synth_get_polyphony(synth):0;}
-void CMidiPlayer::setMaxPolyphone(int p){if(synth)fluid_synth_set_polyphony(synth,p);}
-
-void CMidiPlayer::getChannelPreset(int ch,int *b,int *p,char *name)
-{
-	if(!synth)return(void)(b=0,p=0,strcpy(name,""));
-	fluid_synth_channel_info_t info;
-	fluid_synth_get_channel_info(synth,ch,&info);
-	*b=info.bank;*p=info.program;
-	strcpy(name,info.name);
-}
-void CMidiPlayer::setChannelPreset(int ch,int b,int p)
-{
-	if(!synth)return;
-	fluid_synth_bank_select(synth,ch,b);
-	fluid_synth_program_change(synth,ch,p);
-}
-//16MSB..LSB1
-void CMidiPlayer::setBit(uint16_t &n, uint16_t bn, uint16_t b)
-{n^=(-b^n)&(1<<bn);}
-void CMidiPlayer::setMute(int ch,bool m)
-{setBit(mute,ch,m?1:0);}
-void CMidiPlayer::setSolo(int ch,bool s)
-{setBit(solo,ch,s?1:0);}
-int CMidiPlayer::getCC(int ch, int id)
-{int ret=0;synth?fluid_synth_get_cc(synth,ch,id,&ret):0;return ret;}
-void CMidiPlayer::setCC(int ch, int id, int val)
-{synth?fluid_synth_cc(synth,ch,id,val):0;}
-void CMidiPlayer::getReverbPara(double *r,double *d,double *w,double *l)
-{
-	if(!synth)return;
-	*r=fluid_synth_get_reverb_roomsize(synth);
-	*d=fluid_synth_get_reverb_damp(synth);
-	*w=fluid_synth_get_reverb_width(synth);
-	*l=fluid_synth_get_reverb_level(synth);
-}
-void CMidiPlayer::setReverbPara(int e,double r,double d,double w,double l)
-{
-	if(!synth)return;
-	fluid_synth_set_reverb_on(synth,e);
-	fluid_synth_set_reverb(synth,r,d,w,l);
-}
-void CMidiPlayer::getChorusPara(int *fb,double *l,double *r,double *d,int *type)
-{
-	if(!synth)return;
-	*fb=fluid_synth_get_chorus_nr(synth);
-	*l=fluid_synth_get_chorus_level(synth);
-	*r=fluid_synth_get_chorus_speed_Hz(synth);
-	*d=fluid_synth_get_chorus_depth_ms(synth);
-	*type=fluid_synth_get_chorus_type(synth);
-}
-void CMidiPlayer::setChorusPara(int e,int fb,double l,double r,double d,int type)
-{
-	if(!synth)return;
-	fluid_synth_set_chorus_on(synth,e);
-	fluid_synth_set_chorus(synth,fb,l,r,d,type);
-}
-fluid_settings_t* CMidiPlayer::getFluidSettings(){return settings;}
-void CMidiPlayer::pushSoundFont(const char *sf)
-{fluid_synth_sfload(synth,sf,1);}
-int CMidiPlayer::getSFCount()
-{return synth?fluid_synth_sfcount(synth):0;}
-fluid_sfont_t* CMidiPlayer::getSFPtr(int sfid)
-{return synth&&sfid<getSFCount()?fluid_synth_get_sfont(synth,sfid):NULL;}
diff --git a/qmidiplayerlite.src.d/qmpmidiplay.hpp b/qmidiplayerlite.src.d/qmpmidiplay.hpp
deleted file mode 100644
index fafd677..0000000
--- a/qmidiplayerlite.src.d/qmpmidiplay.hpp
+++ /dev/null
@@ -1,137 +0,0 @@
-//sorry for the stupid C-like code...
-#ifndef QMPMIDIPLAY_H
-#define QMPMIDIPLAY_H
-#include <cstring>
-#include <cstdint>
-#include <cstdlib>
-#include <fluidsynth.h>
-struct SEvent
-{
-	uint32_t iid,time,p1,p2;
-	uint8_t type;
-	char *str;
-	SEvent(){time=p1=p2=0;type=0;str=NULL;}
-	SEvent(uint32_t _iid,uint32_t _t,char _tp,uint32_t _p1,uint32_t _p2,const char* s=NULL)
-	{
-		iid=_iid;time=_t;type=_tp;
-		p1=_p1;p2=_p2;
-		if(s){str=new char[strlen(s)+2];strcpy(str,s);}else str=NULL;
-	}
-};
-class CMidiFile
-{
-	private:
-		SEvent *eventList[10000000];
-		char *title,*copyright;
-		uint32_t eventc,std;//standard 0=? 1=GM 2=GM2 3=GS 4=XG
-		uint32_t fmt,trk,divs;
-		FILE *f;
-		int byteread,valid;
-		uint32_t notes,curt,curid;
-
-		void error(int fatal,const char* format,...);
-		uint32_t readSW();
-		uint32_t readDW();
-		uint32_t readVL();
-		int eventReader();
-		void trackChunkReader();
-		void headerChunkReader();
-		int chunkReader(int hdrXp);
-	public:
-		CMidiFile(const char* fn);
-		~CMidiFile();
-		const SEvent* getEvent(uint32_t id);
-		uint32_t getEventCount();
-		uint32_t getDivision();
-		uint32_t getNoteCount();
-		uint32_t getStandard();
-		const char* getTitle();
-		const char* getCopyright();
-		bool isValid();
-};
-class CMidiPlayer
-{
-	private:
-		CMidiFile *midiFile;
-		uint32_t stamps[101];
-		uint32_t ccstamps[101][16][135],ccc[16][135];
-		//0..127:cc 128:pc 129:cp 130:pb 131:tempo 132:ts 133:ks 134:pbr
-		int32_t rpnid,rpnval;
-		uint16_t mute,solo;
-		double ftime;
-		bool sendSysEx,singleInstance,waitvoice;
-		fluid_settings_t* settings;
-		fluid_synth_t* synth;
-		fluid_audio_driver_t* adriver;
-		fluid_player_t* player;
-		uint32_t ctempo,ctsn,ctsd,dpt,divs,cks;
-		//raw tempo, timesig num., timesig den., delay per tick, division, keysig
-		//thread control
-		uint32_t tceptr,tcpaused,tcstop;
-		uint32_t finished,resumed;
-
-		void setBit(uint16_t &n,uint16_t bn,uint16_t b);
-		void processEvent(const SEvent *e);
-		void processEventStub(const SEvent *e);
-		void playEvents();
-		void fileTimer1Pass();
-		void fileTimer2Pass();
-	public:
-		CMidiPlayer(bool singleInst=false);
-		~CMidiPlayer();
-		bool playerLoadFile(const char* fn);
-		void playerInit();
-		void fluidPreInitialize();
-		void fluidInitialize();
-		void fluidDeinitialize();
-		void playerDeinit();
-		void playerThread();
-		void playerPanic(bool reset=false);
-
-		void rendererLoadFile(const char* ofn);
-		void rendererInit(const char *fn);
-		void rendererThread();
-		void rendererDeinit();
-
-		//playing control methods
-		uint32_t getStamp(int id);
-		uint32_t getTCeptr();
-		void setTCeptr(uint32_t ep,uint32_t st);
-		uint32_t getTCpaused();
-		void setTCpaused(uint32_t ps);
-		uint32_t isFinished();
-		void setResumed();
-		void setWaitVoice(bool wv);
-
-		double getFtime();
-		void getCurrentTimeSignature(int *n,int *d);
-		void getCurrentKeySignature(int *ks);
-		uint32_t getFileNoteCount();
-		uint32_t getFileStandard();
-		double getTempo();
-		const char* getTitle();
-		const char* getCopyright();
-
-		void setGain(double gain);
-		void sendSysX(bool send);
-		int getPolyphone();
-		int getMaxPolyphone();
-		void setMaxPolyphone(int p);
-
-		void setChannelPreset(int ch,int b,int p);
-		void getChannelPreset(int ch,int *b,int *p,char *name);
-		void setMute(int ch,bool m);
-		void setSolo(int ch,bool s);
-		int getCC(int ch,int id);
-		void setCC(int ch,int id,int val);
-		void getReverbPara(double *r,double *d,double *w,double *l);
-		void setReverbPara(int e,double r,double d,double w,double l);
-		void getChorusPara(int *fb,double *l,double *r,double *d,int *type);
-		void setChorusPara(int e,int fb,double l,double r,double d,int type);
-
-		fluid_settings_t* getFluidSettings();
-		void pushSoundFont(const char* sf);
-		int getSFCount();
-		fluid_sfont_t* getSFPtr(int sfid);
-};
-#endif
diff --git a/qmidiplayerlite.src.d/qmpmidiread.cpp b/qmidiplayerlite.src.d/qmpmidiread.cpp
deleted file mode 100644
index 0bcf597..0000000
--- a/qmidiplayerlite.src.d/qmpmidiread.cpp
+++ /dev/null
@@ -1,240 +0,0 @@
-//CLI Midi file player based on libfluidsynth
-//Midi file reading module
-//Written by Chris Xiong, 2015
-#include <cstdio>
-#include <cstring>
-#include <cstdlib>
-#include <cstdint>
-#include <cstdarg>
-#include <algorithm>
-#include "qmpmidiplay.hpp"
-const char* GM1SysX={"\xF0\x7E\x7F\x09\x01\xF7"};
-const char* GM2SysX={"\xF0\x7E\x7F\x09\x03\xF7"};
-const char* GSSysEx={"\xF0\x41\x10\x42\x12\x40\x00\x7F\x00\x41\xF7"};
-const char* XGSysEx={"\xF0\x43\x10\x4C\x00\x00\x7E\x00\xF7"};
-bool cmp(SEvent *a,SEvent *b){return a->time-b->time?a->time<b->time:a->iid<b->iid;}
-void CMidiFile::error(int fatal,const char* format,...)
-{
-	va_list ap;
-	va_start(ap,format);vfprintf(stderr,format,ap);va_end(ap);
-	fprintf(stderr," at %#lx\n",ftell(f));
-	if(fatal)throw 2;
-}
-uint32_t CMidiFile::readSW()
-{
-	byteread+=2;
-	uint32_t ret=0;
-	for(int i=0;i<2;++i){ret<<=8;ret|=((uint32_t)fgetc(f))&0xFF;}
-	return ret;
-}
-uint32_t CMidiFile::readDW()
-{
-	byteread+=4;
-	uint32_t ret=0;
-	for(int i=0;i<4;++i){ret<<=8;ret|=((uint32_t)fgetc(f))&0xFF;}
-	return ret;
-}
-uint32_t CMidiFile::readVL()
-{
-	uint32_t ret=0,t,c=0;
-	do
-	{
-		t=fgetc(f);
-		if(++c>4)error(1,"E: Variable length type overflow.");
-		ret<<=7;ret|=(t&0x7F);
-	}while(t&0x80);
-	byteread+=c;
-	return ret;
-}
-int CMidiFile::eventReader()//returns 0 if End of Track encountered
-{
-	uint32_t delta=readVL();curt+=delta;
-	char type=fgetc(f);++byteread;uint32_t p1,p2;
-	static char lasttype;
-retry:
-	switch(type&0xF0)
-	{
-		case 0x80://Note Off
-			p1=fgetc(f);p2=fgetc(f);byteread+=2;
-			eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
-		break;
-		case 0x90://Note On
-			p1=fgetc(f);p2=fgetc(f);byteread+=2;
-			if(p2)
-			{
-				++notes;
-				eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
-			}
-			else
-				eventList[eventc++]=new SEvent(curid,curt,(type&0x0F)|0x80,p1,p2);
-		break;
-		case 0xA0://Note Aftertouch
-			p1=fgetc(f);p2=fgetc(f);byteread+=2;
-			eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
-		break;
-		case 0xB0://Controller Change
-			p1=fgetc(f);p2=fgetc(f);byteread+=2;
-			eventList[eventc++]=new SEvent(curid,curt,type,p1,p2);
-		break;
-		case 0xC0://Patch Change
-			p1=fgetc(f);++byteread;
-			eventList[eventc++]=new SEvent(curid,curt,type,p1,0);
-		break;
-		case 0xD0://Channel Aftertouch
-			p1=fgetc(f);++byteread;
-			eventList[eventc++]=new SEvent(curid,curt,type,p1,0);
-		break;
-		case 0xE0://Pitch wheel
-			p1=fgetc(f);p2=fgetc(f);byteread+=2;
-			eventList[eventc++]=new SEvent(curid,curt,type,(p1|(p2<<7))&0x3FFF,0);
-		break;
-		case 0xF0:
-			if((type&0x0F)==0x0F)//Meta Event
-			{
-				char metatype=fgetc(f);++byteread;
-				switch(metatype)
-				{
-					case 0x00://Sequence Number
-						fgetc(f);fgetc(f);fgetc(f);
-						byteread+=3;
-					break;
-					case 0x20://Channel Prefix
-						fgetc(f);fgetc(f);byteread+=2;
-					break;
-					case 0x2F://End of Track
-						fgetc(f);++byteread;
-						return 0;
-					break;
-					case 0x51://Set Tempo
-						p1=readDW();p1&=0x00FFFFFF;
-						eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1);
-					break;
-					case 0x54://SMTPE offset, not handled.
-						fgetc(f);fgetc(f);fgetc(f);
-						fgetc(f);fgetc(f);fgetc(f);
-						byteread+=6;
-					break;
-					case 0x58://Time signature
-						fgetc(f);++byteread;
-						p1=readDW();
-						eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1);
-					break;
-					case 0x59://Key signature
-						fgetc(f);++byteread;
-						p1=readSW();
-						eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1);
-					break;
-					case 0x01:case 0x02:case 0x03:
-					case 0x04:case 0x05:case 0x06:
-					case 0x07:case 0x7F:default://text-like meta
-					{
-						uint32_t len=readVL(),c;char* str=NULL;
-						if(len<=1024&&len>0)str=new char[len+8];
-						for(c=0;c<len;++c)
-						{
-							++byteread;if(str)str[c]=fgetc(f);else fgetc(f);
-						}
-						if(str)str[c]='\0';eventList[eventc++]=new SEvent(curid,curt,type,metatype,0,str);
-						if(str&&metatype==0x03&&!title)
-						{
-							title=new char[len+8];
-							strcpy(title,str);
-						}
-						if(str&&metatype==0x02&&!copyright)
-						{
-							copyright=new char[len+8];
-							strcpy(copyright,str);
-						}
-						if(len<=1024&&len>0)delete[] str;
-					}
-				}
-			}
-			else if((type&0x0F)==0x00||(type&0x0F)==0x07)//SysEx
-			{
-				uint32_t len=readVL(),c;char* str=NULL;
-				str=new char[len+8];
-				if((type&0x0F)==0x00)
-				{
-					str[0]=0xF0;++len;
-					for(c=1;c<len;++c){++byteread;str[c]=fgetc(f);}
-				}
-				else for(c=0;c<len;++c){++byteread;str[c]=fgetc(f);}
-				eventList[eventc++]=new SEvent(curid,curt,type,len,0,str);
-				if(!strcmp(str,GM1SysX))std=1;
-				if(!strcmp(str,GM2SysX))std=2;
-				if(!strcmp(str,GSSysEx))std=3;
-				if(!strcmp(str,XGSysEx))std=4;
-			}
-			else error(0,"W: Unknown event type %#x",type);
-		break;
-		default:
-			fseek(f,-1,SEEK_CUR);--byteread;type=lasttype;goto retry;
-	}
-	lasttype=type;++curid;
-	return 1;
-}
-void CMidiFile::trackChunkReader()
-{
-	int chnklen=readDW();byteread=0;curt=0;curid=0;
-	while(/*byteread<chnklen&&*/eventReader());
-	if(byteread<chnklen)
-	{
-		error(0,"W: Extra bytes after EOT event.");
-		while(byteread<chnklen){fgetc(f);++byteread;}
-	}
-	/*if(byteread>chnklen)
-	{
-		error(1,"E: Read past end of track.");
-	}*/
-}
-void CMidiFile::headerChunkReader()
-{
-	int chnklen=readDW();byteread=0;
-	if(chnklen<6)error(1,"E: Header chunk too short.");
-	if(chnklen>6)error(0,"W: Header chunk length longer than expected. Ignoring extra bytes.");
-	fmt=readSW();trk=readSW();divs=readSW();
-	if(divs&0x8000)error(1,"E: SMTPE format is not supported.");
-	for(;byteread<chnklen;++byteread){fgetc(f);}
-}
-int CMidiFile::chunkReader(int hdrXp)
-{
-	char hdr[6];
-	if(!fgets(hdr,5,f))error(1,"E: Unexpected EOF.");
-	if(hdrXp)
-		if(strncmp(hdr,"MThd",4)){error(1,"E: Wrong MIDI header.");throw;}
-		else return headerChunkReader(),0;
-	else
-		if(strncmp(hdr,"MTrk",4))
-		{
-			error(0,"W: Wrong track chunk header. Ignoring the whole chunk.");
-			for(int chnklen=readDW();chnklen>0;--chnklen)fgetc(f);return 0;
-		}
-		else return trackChunkReader(),1;
-}
-CMidiFile::CMidiFile(const char* fn)
-{
-	title=copyright=NULL;notes=eventc=0;std=0;valid=1;
-	try
-	{
-		if(!(f=fopen(fn,"rb")))throw (fprintf(stderr,"E: file %s doesn't exist!\n",fn),2);
-		chunkReader(1);
-		for(uint32_t i=0;i<trk;i+=chunkReader(0));
-		printf("%d note(s)\n",notes);
-		fclose(f);
-		std::sort(eventList,eventList+eventc,cmp);
-	}
-	catch(int){fprintf(stderr,"E: %s is not a supported file.\n",fn);valid=0;}
-}
-CMidiFile::~CMidiFile()
-{
-	for(uint32_t i=0;i<eventc;++i)delete eventList[i];
-	if(title)delete[] title;if(copyright)delete[] copyright;
-}
-const SEvent* CMidiFile::getEvent(uint32_t id){return id<eventc?eventList[id]:NULL;}
-uint32_t CMidiFile::getEventCount(){return eventc;}
-uint32_t CMidiFile::getDivision(){return divs;}
-uint32_t CMidiFile::getNoteCount(){return notes;}
-uint32_t CMidiFile::getStandard(){return std;}
-bool CMidiFile::isValid(){return valid;}
-const char* CMidiFile::getTitle(){return title;}
-const char* CMidiFile::getCopyright(){return copyright;}
-- 
cgit v1.2.3