From 70fd2d85c1bd6fb8732e680e8fda9d36c317c732 Mon Sep 17 00:00:00 2001 From: Chris Xiong 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 -#include -#include -#include -#include "qmpmidiplay.hpp" -#ifdef _WIN32 -#include -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)*1000000getEvent(0)->time;tceptrgetEventCount();) - { - while(tcpaused)std::this_thread::sleep_for(std::chrono::milliseconds(100)); - while(!tcstop&&midiFile&&tceptrgetEventCount()&&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;eptrgetEventCount();) - { - while(eptrgetEventCount()&&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;eptrgetEventCount();) - { - while(eptrgetEventCount()&&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< -#include -#include -#include -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 -#include -#include -#include -#include -#include -#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->timetime:a->iidiid;} -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;c0)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;cchnklen) - { - 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(;byteread0;--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 +#include +#include +#include +#include "qmpmidiplay.hpp" +#ifdef _WIN32 +#include +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)*1000000getEvent(0)->time;tceptrgetEventCount();) + { + while(tcpaused)std::this_thread::sleep_for(std::chrono::milliseconds(100)); + while(!tcstop&&midiFile&&tceptrgetEventCount()&&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;eptrgetEventCount();) + { + while(eptrgetEventCount()&&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;eptrgetEventCount();) + { + while(eptrgetEventCount()&&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< +#include +#include +#include +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 +#include +#include +#include +#include +#include +#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->timetime:a->iidiid;} +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;c0)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;cchnklen) + { + 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(;byteread0;--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 Wed, 06 Apr 2016 16:45:02 +0800 + +qmidiplayer (0.7.0-5) UNRELEASED; urgency=low + + * New upstream release. + + -- chrisoft Wed, 06 Apr 2016 09:43:57 +0800 + +qmidiplayer (0.7.0-4) UNRELEASED; urgency=low + + * New upstream release. + + -- chrisoft Tue, 05 Apr 2016 22:17:31 +0800 + +qmidiplayer (0.7.0-3) UNRELEASED; urgency=low + + * New upstream release. + + -- chrisoft 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 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 . + */ +#include "qmpmainwindow.hpp" +#include +#include + +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 + + 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 +#include +#include +#include + +#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(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(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 + + 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 + +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 +#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 dials=findChildren(); + for(int i=0;isetStyle(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 +#include +#include +#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 @@ + + + qmpChannelEditor + + + + 0 + 0 + 422 + 300 + + + + + 422 + 300 + + + + + 422 + 300 + + + + Dialog + + + + + 10 + 10 + 21 + 21 + + + + < + + + + + + 30 + 10 + 21 + 20 + + + + 1 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 50 + 10 + 21 + 21 + + + + > + + + + + + 90 + 10 + 261 + 51 + + + + + 16 + + + + Yamaha Grand Piano + + + + + + 10 + 30 + 81 + 20 + + + + BK: 0 + + + + + + 10 + 50 + 81 + 20 + + + + PC: 0 + + + + + + 0 + 70 + 141 + 101 + + + + Filters + + + + + 70 + 80 + 66 + 20 + + + + Res. 64 + + + Qt::AlignCenter + + + + + + 80 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 10 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 0 + 80 + 71 + 20 + + + + Cut. 64 + + + Qt::AlignCenter + + + + + + + 140 + 70 + 141 + 101 + + + + Effects + + + + + 70 + 80 + 66 + 20 + + + + Chr. 64 + + + Qt::AlignCenter + + + + + + 80 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 10 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 0 + 80 + 71 + 20 + + + + Rev. 64 + + + Qt::AlignCenter + + + + + + + 0 + 170 + 211 + 101 + + + + Envelope + + + + + 70 + 80 + 66 + 20 + + + + Dec. 64 + + + Qt::AlignCenter + + + + + + 80 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 10 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 0 + 80 + 71 + 20 + + + + Atk. 64 + + + Qt::AlignCenter + + + + + + 150 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 140 + 80 + 66 + 20 + + + + Rel. 64 + + + Qt::AlignCenter + + + + + + + 210 + 170 + 211 + 101 + + + + Vibrato + + + + + 70 + 80 + 66 + 20 + + + + Dep. 64 + + + Qt::AlignCenter + + + + + + 80 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 10 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 0 + 80 + 71 + 20 + + + + Rate 64 + + + Qt::AlignCenter + + + + + + 150 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 140 + 80 + 66 + 20 + + + + Del. 64 + + + Qt::AlignCenter + + + + + + + 280 + 70 + 141 + 101 + + + + Mixer + + + + + 70 + 80 + 66 + 20 + + + + Pan. C + + + Qt::AlignCenter + + + + + + 80 + 30 + 50 + 51 + + + + 127 + + + 64 + + + true + + + + + + 0 + 80 + 66 + 20 + + + + Vol. 127 + + + Qt::AlignCenter + + + + + + 10 + 30 + 50 + 51 + + + + 127 + + + 127 + + + true + + + + + + + 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 +#include +#include +#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 +#include +#include +#include +#include +#include +#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 @@ + + + qmpChannelsWindow + + + + 0 + 0 + 580 + 410 + + + + + 580 + 410 + + + + + 580 + 16777215 + + + + Channels + + + + + + + + + 0 + 0 + + + + true + + + QAbstractItemView::NoSelection + + + false + + + 16 + + + 5 + + + + + + + + + + + + + + + + + + + + M + + + + + S + + + + + Device + + + + + Preset + + + + + ... + + + + + + + + + + + + + + + + + Save + + + + 16 + 16 + + + + + + + + Load + + + + + + + Unmute All + + + + + + + Unsolo All + + + + + + + + + + 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 +#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 dials=findChildren(); + for(int i=0;isetStyle(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 +#include +#include +#include + +#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 @@ + + + qmpEfxWindow + + + + 0 + 0 + 546 + 177 + + + + + 546 + 177 + + + + + 546 + 177 + + + + Effects + + + + + + Reverb + + + + + 80 + 4 + 21 + 24 + + + + + + + + + + 10 + 30 + 50 + 51 + + + + 120 + + + true + + + + + + 200 + 30 + 50 + 51 + + + + 100 + + + true + + + + + + 10 + 103 + 50 + 51 + + + + 100 + + + true + + + + + + 200 + 103 + 50 + 51 + + + + 100 + + + true + + + + + + 60 + 30 + 41 + 20 + + + + Room + + + + + + 60 + 50 + 51 + 21 + + + + 120 + + + + + + 140 + 30 + 51 + 20 + + + + Damp + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 140 + 50 + 56 + 21 + + + + 100 + + + + + + 60 + 100 + 51 + 20 + + + + Width + + + + + + 60 + 120 + 56 + 21 + + + + 100 + + + + + + 145 + 100 + 51 + 20 + + + + Level + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 140 + 120 + 56 + 21 + + + + 100 + + + + + + + + Chorus + + + + + 80 + 4 + 21 + 24 + + + + + + + + + + 10 + 30 + 50 + 51 + + + + 99 + + + true + + + + + + 200 + 30 + 50 + 51 + + + + 29 + + + 500 + + + 29 + + + true + + + + + + 10 + 103 + 50 + 51 + + + + 210 + + + true + + + + + + 200 + 103 + 50 + 51 + + + + 100 + + + true + + + + + + 60 + 30 + 71 + 20 + + + + Feedback + + + + + + 60 + 50 + 51 + 21 + + + + 99 + + + + + + 140 + 30 + 51 + 20 + + + + Rate + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 60 + 100 + 51 + 20 + + + + Depth + + + + + + 145 + 100 + 51 + 20 + + + + Level + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 140 + 120 + 56 + 21 + + + + 100 + + + + + + 137 + 50 + 61 + 21 + + + + 0.290000000000000 + + + 5.000000000000000 + + + 0.100000000000000 + + + + + + 35 + 77 + 41 + 20 + + + + LFO + + + + + + 70 + 77 + 61 + 20 + + + + Sine + + + + + + 145 + 77 + 91 + 20 + + + + Trian&gle + + + + + + 60 + 120 + 51 + 21 + + + + 1 + + + 21.000000000000000 + + + 0.100000000000000 + + + + + + + + + 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 +#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 +#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 @@ + + + qmpHelpWindow + + + + 0 + 0 + 640 + 360 + + + + + 640 + 360 + + + + Help + + + + + + true + + + + + + + + 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 +#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 + +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 @@ + + + qmpInfoWindow + + + + 0 + 0 + 400 + 142 + + + + + 400 + 142 + + + + File Information + + + + + + File name: + + + + + + + + + Tempo: + + + + + + + Key Sig.: + + + + + + + Time Sig.: + + + + + + + + + Title: + + + + + + + Copyright: + + + + + + + + + Note count: + + + + + + + File standard: + + + + + + + + + + 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 +#include +#include +#include +#include +#include "qmpmainwindow.hpp" +#include "ui_qmpmainwindow.h" +#include "../core/qmpmidiplay.hpp" +#ifdef _WIN32 +#include +#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;iemptyList();} + 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 l=event->mimeData()->urls(); + QStringList sl; + for(int i=0;iinsertItems(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 elapsed= + std::chrono::duration_cast>(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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 @@ + + + qmpMainWindow + + + + 0 + 0 + 435 + 245 + + + + + 435 + 245 + + + + + 435 + 245 + + + + true + + + QMidiPlayer + + + + :/img/qmidiplyr.png:/img/qmidiplyr.png + + + + + + 30 + 20 + 311 + 41 + + + + + 18 + + + + Qt::CustomContextMenu + + + somefile.mid + + + Qt::AlignCenter + + + + + + 20 + 90 + 321 + 20 + + + + 100 + + + 0 + + + Qt::Horizontal + + + + + + 20 + 110 + 61 + 36 + + + + + + + + :/img/play.png:/img/play.png + + + + 32 + 32 + + + + + + + 80 + 110 + 61 + 36 + + + + + + + + :/img/stop.png:/img/stop.png + + + + 32 + 32 + + + + + + + 140 + 110 + 61 + 36 + + + + + + + + :/img/prev.png:/img/prev.png + + + + 32 + 32 + + + + + + + 200 + 110 + 61 + 36 + + + + + + + + :/img/next.png:/img/next.png + + + + 32 + 32 + + + + + + + 280 + 110 + 61 + 36 + + + + + + + + :/img/settings.png:/img/settings.png + + + + 32 + 32 + + + + true + + + + + + 20 + 160 + 151 + 36 + + + + text-align:left + + + Channels + + + + :/img/channel.png:/img/channel.png + + + + 32 + 32 + + + + true + + + + + + 190 + 160 + 151 + 36 + + + + text-align:left + + + Playlist + + + + :/img/list.png:/img/list.png + + + + 32 + 32 + + + + true + + + false + + + false + + + + + + 20 + 200 + 151 + 36 + + + + text-align:left + + + Effects + + + + :/img/effects.png:/img/effects.png + + + + 32 + 32 + + + + true + + + + + + 190 + 200 + 151 + 36 + + + + text-align:left + + + Visualization + + + + :/img/visualization.png:/img/visualization.png + + + + 32 + 32 + + + + + + + 320 + 20 + 111 + 20 + + + + <html><head/><body><p>Poly: 0/0</p></body></html> + + + Qt::AlignCenter + + + + + + 370 + 50 + 20 + 160 + + + + 100 + + + 50 + + + Qt::Vertical + + + + + + 360 + 210 + 61 + 20 + + + + Master + + + + + + 20 + 70 + 66 + 20 + + + + 00:00 + + + + + + 270 + 70 + 66 + 20 + + + + 00:00 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 0 + 0 + 21 + 21 + + + + ? + + + + + + + + + + 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 +#include +#include +#include +#include +#include +#include +#include +#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;ilwFiles->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 l=event->mimeData()->urls(); + QStringList sl; + for(int i=0;imimeData()->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;ilwFiles->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 sl=ui->lwFiles->selectedItems(); + for(int i=0;ilwFiles->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;ilwFiles->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 +#include +#include +#include +#include +#include +#include + +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 @@ + + + qmpPlistWindow + + + + 0 + 0 + 530 + 321 + + + + + 530 + 321 + + + + + 530 + 321 + + + + true + + + Playlist + + + + + 10 + 280 + 121 + 36 + + + + text-align:left + + + Add + + + + :/img/add.png:/img/add.png + + + + 32 + 32 + + + + + + + 140 + 280 + 121 + 36 + + + + text-align:left + + + Add Folder + + + + :/img/addfolder.png:/img/addfolder.png + + + + 32 + 32 + + + + + + + 270 + 240 + 121 + 36 + + + + text-align:left + + + Repeat Off + + + + :/img/repeat-non.png:/img/repeat-non.png + + + + 32 + 32 + + + + + + + 400 + 240 + 121 + 36 + + + + text-align:left + + + Shuffle Off + + + + :/img/shuffle-off.png:/img/shuffle-off.png + + + + 32 + 32 + + + + + + + 10 + 240 + 121 + 36 + + + + text-align:left + + + Save + + + + :/img/save.png:/img/save.png + + + + 32 + 32 + + + + + + + 140 + 240 + 121 + 36 + + + + text-align:left + + + Load + + + + :/img/load.png:/img/load.png + + + + 32 + 32 + + + + + + + 270 + 280 + 121 + 36 + + + + text-align:left + + + Remove + + + + :/img/remove.png:/img/remove.png + + + + 32 + 32 + + + + + + + 400 + 280 + 121 + 36 + + + + text-align:left + + + Clear + + + + :/img/clear.png:/img/clear.png + + + + 32 + 32 + + + + + + + 10 + 10 + 511 + 221 + + + + false + + + true + + + QAbstractItemView::InternalMove + + + + + + + + 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 +#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;ilwBankSelect->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 +#include + +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 @@ + + + qmpPresetSelector + + + + 0 + 0 + 404 + 300 + + + + + 404 + 300 + + + + + 404 + 300 + + + + Preset Selection + + + true + + + + + 10 + 30 + 71 + 221 + + + + + + + 90 + 30 + 301 + 221 + + + + + + + 10 + 10 + 66 + 20 + + + + Bank + + + + + + 90 + 10 + 66 + 20 + + + + Preset + + + + + + 300 + 260 + 97 + 36 + + + + OK + + + + + + 190 + 260 + 97 + 36 + + + + Cancel + + + + + + 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 +#include +#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;icbEncoding->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;icbAudioDrv->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;icbBufSize->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;icbBufCnt->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;icbFormat->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;icbFrequency->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;icbBSMode->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;ilwSoundfont->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;ilwSoundfont->addItem(new QListWidgetItem(sl.at(i))); + } +} + +void qmpSettingsWindow::on_pbRemove_clicked() +{ + QList sl=ui->lwSoundfont->selectedItems(); + for(int i=0;ilwSoundfont->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 +#include +#include +#include + +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 @@ + + + qmpSettingsWindow + + + + 0 + 0 + 494 + 445 + + + + + 494 + 445 + + + + Settings + + + + + + 0 + + + + Midi + + + + + + + + + 0 + 0 + + + + Default Output Device + + + + + + + + 0 + 0 + + + + + Internal FluidSynth + + + + + + + + + + + 0 + 0 + + + + Disable Midi Mapping + + + + + + + + 0 + 0 + + + + Send SysEx + + + + + + + + 0 + 0 + + + + Wait for remaining voices before stopping + + + + + + + + + + 0 + 0 + + + + Text Encoding + + + + + + + + 0 + 0 + + + + + Unicode + + + + + Big5 + + + + + Big5-HKSCS + + + + + CP949 + + + + + EUC-JP + + + + + EUC-KR + + + + + GB18030 + + + + + KOI8-R + + + + + KOI8-U + + + + + Macintosh + + + + + Shift-JIS + + + + + + + + + + + Synth + + + + + + Audio Buffer Count + + + + + + + Audio Buffer Size + + + + + + + true + + + 1 + + + + 64 + + + + + 128 + + + + + 256 + + + + + 512 + + + + + 1024 + + + + + 2048 + + + + + 4096 + + + + + 8192 + + + + + + + + Audio Frequency + + + + + + + true + + + + 2 + + + + + 4 + + + + + 8 + + + + + 16 + + + + + 32 + + + + + 64 + + + + + + + + Audio Driver + + + + + + + + 16bits + + + + + float + + + + + + + + + + + 2 + + + + 22050 + + + + + 44100 + + + + + 48000 + + + + + 96000 + + + + + + + + Audio Format + + + + + + + 1 + + + 65535 + + + 2048 + + + + + + + Max Polyphony + + + + + + + Auto bank select mode + + + + + + + Bank select mode + + + + + + + 1 + + + + Ignored + + + + + CC#0 + + + + + CC#32 + + + + + CC#0*128+CC#32 + + + + + + + + CPU Cores + + + + + + + 1 + + + 256 + + + + + + + + Soundfonts + + + + + + QAbstractItemView::InternalMove + + + + + + + + + + + + + :/img/add.png:/img/add.png + + + + 24 + 24 + + + + + + + + + + + + :/img/remove.png:/img/remove.png + + + + 24 + 24 + + + + + + + + + + + + :/img/up.png:/img/up.png + + + + 24 + 24 + + + + + + + + + + + + :/img/down.png:/img/down.png + + + + 24 + 24 + + + + + + + + + + + Behavior + + + + + + Restore last playlist on startup + + + + + + + Load files in the same folder + + + + + + + Save dialog status + + + + + + + Save parameters in effects window + + + + + + + Persistent fluidsynth instance + + + + + + + + + Visualization Mode + + + + + + + + + + + + + + View distance + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 50 + 20 + + + + + + + + + 60 + 0 + + + + Qt::Horizontal + + + + + + + + + + + + + + Note stretch + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 60 + 20 + + + + + + + + + 60 + 0 + + + + Qt::Horizontal + + + + + + + + + + + + + + Fog Start + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 82 + 20 + + + + + + + + + 60 + 0 + + + + Qt::Horizontal + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + qmpSettingsWindow + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + qmpSettingsWindow + reject() + + + 316 + 260 + + + 286 + 274 + + + + + 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 @@ + + + ../img/add.png + ../img/list.png + ../img/addfolder.png + ../img/channel.png + ../img/prev.png + ../img/qmidiplyr.png + ../img/remove.png + ../img/clear.png + ../img/down.png + ../img/effects.png + ../img/repeat-all.png + ../img/repeat-base.png + ../img/repeat-non.png + ../img/load.png + ../img/next.png + ../img/repeat-one.png + ../img/save.png + ../img/settings.png + ../img/pause.png + ../img/play.png + ../img/shuffle-off.png + ../img/shuffle.png + ../img/stop.png + ../img/up.png + ../img/visualization.png + ../img/mainw.png + ../img/chanw.png + ../doc/index.html + ../doc/version.html + ../doc/license.html + ../doc/mainwindow.html + ../doc/channeldialog.html + + 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 +#include +#include +#include "qmpcorewrapper.hpp" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + qmlRegisterType("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 @@ + + + main.qml + + 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 +#include +#include +#include +#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 +#include +#include +#include +#include "qmpmidiplay.hpp" +#ifdef _WIN32 +#include +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)*1000000getEvent(0)->time;tceptrgetEventCount();) + { + while(tcpaused)std::this_thread::sleep_for(std::chrono::milliseconds(100)); + while(!tcstop&&midiFile&&tceptrgetEventCount()&&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;eptrgetEventCount();) + { + while(eptrgetEventCount()&&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;eptrgetEventCount();) + { + while(eptrgetEventCount()&&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< +#include +#include +#include +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 +#include +#include +#include +#include +#include +#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->timetime:a->iidiid;} +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;c0)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;cchnklen) + { + 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(;byteread0;--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. - */ -#include "qmpmainwindow.hpp" -#include -#include - -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 - - 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 -#include -#include -#include - -#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(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(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 - - 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 - -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 -#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 dials=findChildren(); - for(int i=0;isetStyle(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 -#include -#include -#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 @@ - - - qmpChannelEditor - - - - 0 - 0 - 422 - 300 - - - - - 422 - 300 - - - - - 422 - 300 - - - - Dialog - - - - - 10 - 10 - 21 - 21 - - - - < - - - - - - 30 - 10 - 21 - 20 - - - - 1 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 50 - 10 - 21 - 21 - - - - > - - - - - - 90 - 10 - 261 - 51 - - - - - 16 - - - - Yamaha Grand Piano - - - - - - 10 - 30 - 81 - 20 - - - - BK: 0 - - - - - - 10 - 50 - 81 - 20 - - - - PC: 0 - - - - - - 0 - 70 - 141 - 101 - - - - Filters - - - - - 70 - 80 - 66 - 20 - - - - Res. 64 - - - Qt::AlignCenter - - - - - - 80 - 30 - 50 - 51 - - - - 127 - - - 64 - - - true - - - - - - 10 - 30 - 50 - 51 - - - - 127 - - - 64 - - - true - - - - - - 0 - 80 - 71 - 20 - - - - Cut. 64 - - - Qt::AlignCenter - - - - - - - 140 - 70 - 141 - 101 - - - - Effects - - - - - 70 - 80 - 66 - 20 - - - - Chr. 64 - - - Qt::AlignCenter - - - - - - 80 - 30 - 50 - 51 - - - - 127 - - - 64 - - - true - - - - - - 10 - 30 - 50 - 51 - - - - 127 - - - 64 - - - true - - - - - - 0 - 80 - 71 - 20 - - - - Rev. 64 - - - Qt::AlignCenter - - - - - - - 0 - 170 - 211 - 101 - - - - Envelope - - - - - 70 - 80 - 66 - 20 - - - - Dec. 64 - - - Qt::AlignCenter - - - - - - 80 - 30 - 50 - 51 - - - - 127 - - - 64 - - - true - - - - - - 10 - 30 - 50 - 51 - - - - 127 - - - 64 - - - true - - - - - - 0 - 80 - 71 - 20 - - - - Atk. 64 - - - Qt::AlignCenter - - - - - - 150 - 30 - 50 - 51 - - - - 127 - - - 64 - - - true - - - - - - 140 - 80 - 66 - 20 - - - - Rel. 64 - - - Qt::AlignCenter - - - - - - - 210 - 170 - 211 - 101 - - - - Vibrato - - - - - 70 - 80 - 66 - 20 - - - - Dep. 64 - - - Qt::AlignCenter - - - - - - 80 - 30 - 50 - 51 - - - - 127 - - - 64 - - - true - - - - - - 10 - 30 - 50 - 51 - - - - 127 - - - 64 - - - true - - - - - - 0 - 80 - 71 - 20 - - - - Rate 64 - - - Qt::AlignCenter - - - - - - 150 - 30 - 50 - 51 - - - - 127 - - - 64 - - - true - - - - - - 140 - 80 - 66 - 20 - - - - Del. 64 - - - Qt::AlignCenter - - - - - - - 280 - 70 - 141 - 101 - - - - Mixer - - - - - 70 - 80 - 66 - 20 - - - - Pan. C - - - Qt::AlignCenter - - - - - - 80 - 30 - 50 - 51 - - - - 127 - - - 64 - - - true - - - - - - 0 - 80 - 66 - 20 - - - - Vol. 127 - - - Qt::AlignCenter - - - - - - 10 - 30 - 50 - 51 - - - - 127 - - - 127 - - - true - - - - - - - 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 -#include -#include -#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 -#include -#include -#include -#include -#include -#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 @@ - - - qmpChannelsWindow - - - - 0 - 0 - 580 - 410 - - - - - 580 - 410 - - - - - 580 - 16777215 - - - - Channels - - - - - - - - - 0 - 0 - - - - true - - - QAbstractItemView::NoSelection - - - false - - - 16 - - - 5 - - - - - - - - - - - - - - - - - - - - M - - - - - S - - - - - Device - - - - - Preset - - - - - ... - - - - - - - - - - - - - - - - - Save - - - - 16 - 16 - - - - - - - - Load - - - - - - - Unmute All - - - - - - - Unsolo All - - - - - - - - - - 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 -#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 dials=findChildren(); - for(int i=0;isetStyle(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 -#include -#include -#include - -#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 @@ - - - qmpEfxWindow - - - - 0 - 0 - 546 - 177 - - - - - 546 - 177 - - - - - 546 - 177 - - - - Effects - - - - - - Reverb - - - - - 80 - 4 - 21 - 24 - - - - - - - - - - 10 - 30 - 50 - 51 - - - - 120 - - - true - - - - - - 200 - 30 - 50 - 51 - - - - 100 - - - true - - - - - - 10 - 103 - 50 - 51 - - - - 100 - - - true - - - - - - 200 - 103 - 50 - 51 - - - - 100 - - - true - - - - - - 60 - 30 - 41 - 20 - - - - Room - - - - - - 60 - 50 - 51 - 21 - - - - 120 - - - - - - 140 - 30 - 51 - 20 - - - - Damp - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 140 - 50 - 56 - 21 - - - - 100 - - - - - - 60 - 100 - 51 - 20 - - - - Width - - - - - - 60 - 120 - 56 - 21 - - - - 100 - - - - - - 145 - 100 - 51 - 20 - - - - Level - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 140 - 120 - 56 - 21 - - - - 100 - - - - - - - - Chorus - - - - - 80 - 4 - 21 - 24 - - - - - - - - - - 10 - 30 - 50 - 51 - - - - 99 - - - true - - - - - - 200 - 30 - 50 - 51 - - - - 29 - - - 500 - - - 29 - - - true - - - - - - 10 - 103 - 50 - 51 - - - - 210 - - - true - - - - - - 200 - 103 - 50 - 51 - - - - 100 - - - true - - - - - - 60 - 30 - 71 - 20 - - - - Feedback - - - - - - 60 - 50 - 51 - 21 - - - - 99 - - - - - - 140 - 30 - 51 - 20 - - - - Rate - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 60 - 100 - 51 - 20 - - - - Depth - - - - - - 145 - 100 - 51 - 20 - - - - Level - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 140 - 120 - 56 - 21 - - - - 100 - - - - - - 137 - 50 - 61 - 21 - - - - 0.290000000000000 - - - 5.000000000000000 - - - 0.100000000000000 - - - - - - 35 - 77 - 41 - 20 - - - - LFO - - - - - - 70 - 77 - 61 - 20 - - - - Sine - - - - - - 145 - 77 - 91 - 20 - - - - Trian&gle - - - - - - 60 - 120 - 51 - 21 - - - - 1 - - - 21.000000000000000 - - - 0.100000000000000 - - - - - - - - - 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 -#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 -#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 @@ - - - qmpHelpWindow - - - - 0 - 0 - 640 - 360 - - - - - 640 - 360 - - - - Help - - - - - - true - - - - - - - - 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 -#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 - -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 @@ - - - qmpInfoWindow - - - - 0 - 0 - 400 - 142 - - - - - 400 - 142 - - - - File Information - - - - - - File name: - - - - - - - - - Tempo: - - - - - - - Key Sig.: - - - - - - - Time Sig.: - - - - - - - - - Title: - - - - - - - Copyright: - - - - - - - - - Note count: - - - - - - - File standard: - - - - - - - - - - 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 -#include -#include -#include -#include -#include "qmpmainwindow.hpp" -#include "ui_qmpmainwindow.h" -#include "../common/qmpmidiplay.hpp" -#ifdef _WIN32 -#include -#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;iemptyList();} - 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 l=event->mimeData()->urls(); - QStringList sl; - for(int i=0;iinsertItems(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 elapsed= - std::chrono::duration_cast>(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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 @@ - - - qmpMainWindow - - - - 0 - 0 - 435 - 245 - - - - - 435 - 245 - - - - - 435 - 245 - - - - true - - - QMidiPlayer - - - - :/img/qmidiplyr.png:/img/qmidiplyr.png - - - - - - 30 - 20 - 311 - 41 - - - - - 18 - - - - Qt::CustomContextMenu - - - somefile.mid - - - Qt::AlignCenter - - - - - - 20 - 90 - 321 - 20 - - - - 100 - - - 0 - - - Qt::Horizontal - - - - - - 20 - 110 - 61 - 36 - - - - - - - - :/img/play.png:/img/play.png - - - - 32 - 32 - - - - - - - 80 - 110 - 61 - 36 - - - - - - - - :/img/stop.png:/img/stop.png - - - - 32 - 32 - - - - - - - 140 - 110 - 61 - 36 - - - - - - - - :/img/prev.png:/img/prev.png - - - - 32 - 32 - - - - - - - 200 - 110 - 61 - 36 - - - - - - - - :/img/next.png:/img/next.png - - - - 32 - 32 - - - - - - - 280 - 110 - 61 - 36 - - - - - - - - :/img/settings.png:/img/settings.png - - - - 32 - 32 - - - - true - - - - - - 20 - 160 - 151 - 36 - - - - text-align:left - - - Channels - - - - :/img/channel.png:/img/channel.png - - - - 32 - 32 - - - - true - - - - - - 190 - 160 - 151 - 36 - - - - text-align:left - - - Playlist - - - - :/img/list.png:/img/list.png - - - - 32 - 32 - - - - true - - - false - - - false - - - - - - 20 - 200 - 151 - 36 - - - - text-align:left - - - Effects - - - - :/img/effects.png:/img/effects.png - - - - 32 - 32 - - - - true - - - - - - 190 - 200 - 151 - 36 - - - - text-align:left - - - Visualization - - - - :/img/visualization.png:/img/visualization.png - - - - 32 - 32 - - - - - - - 320 - 20 - 111 - 20 - - - - <html><head/><body><p>Poly: 0/0</p></body></html> - - - Qt::AlignCenter - - - - - - 370 - 50 - 20 - 160 - - - - 100 - - - 50 - - - Qt::Vertical - - - - - - 360 - 210 - 61 - 20 - - - - Master - - - - - - 20 - 70 - 66 - 20 - - - - 00:00 - - - - - - 270 - 70 - 66 - 20 - - - - 00:00 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 0 - 0 - 21 - 21 - - - - ? - - - - - - - - - - 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 -#include -#include -#include -#include -#include -#include -#include -#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;ilwFiles->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 l=event->mimeData()->urls(); - QStringList sl; - for(int i=0;imimeData()->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;ilwFiles->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 sl=ui->lwFiles->selectedItems(); - for(int i=0;ilwFiles->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;ilwFiles->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 -#include -#include -#include -#include -#include -#include - -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 @@ - - - qmpPlistWindow - - - - 0 - 0 - 530 - 321 - - - - - 530 - 321 - - - - - 530 - 321 - - - - true - - - Playlist - - - - - 10 - 280 - 121 - 36 - - - - text-align:left - - - Add - - - - :/img/add.png:/img/add.png - - - - 32 - 32 - - - - - - - 140 - 280 - 121 - 36 - - - - text-align:left - - - Add Folder - - - - :/img/addfolder.png:/img/addfolder.png - - - - 32 - 32 - - - - - - - 270 - 240 - 121 - 36 - - - - text-align:left - - - Repeat Off - - - - :/img/repeat-non.png:/img/repeat-non.png - - - - 32 - 32 - - - - - - - 400 - 240 - 121 - 36 - - - - text-align:left - - - Shuffle Off - - - - :/img/shuffle-off.png:/img/shuffle-off.png - - - - 32 - 32 - - - - - - - 10 - 240 - 121 - 36 - - - - text-align:left - - - Save - - - - :/img/save.png:/img/save.png - - - - 32 - 32 - - - - - - - 140 - 240 - 121 - 36 - - - - text-align:left - - - Load - - - - :/img/load.png:/img/load.png - - - - 32 - 32 - - - - - - - 270 - 280 - 121 - 36 - - - - text-align:left - - - Remove - - - - :/img/remove.png:/img/remove.png - - - - 32 - 32 - - - - - - - 400 - 280 - 121 - 36 - - - - text-align:left - - - Clear - - - - :/img/clear.png:/img/clear.png - - - - 32 - 32 - - - - - - - 10 - 10 - 511 - 221 - - - - false - - - true - - - QAbstractItemView::InternalMove - - - - - - - - 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 -#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;ilwBankSelect->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 -#include - -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 @@ - - - qmpPresetSelector - - - - 0 - 0 - 404 - 300 - - - - - 404 - 300 - - - - - 404 - 300 - - - - Preset Selection - - - true - - - - - 10 - 30 - 71 - 221 - - - - - - - 90 - 30 - 301 - 221 - - - - - - - 10 - 10 - 66 - 20 - - - - Bank - - - - - - 90 - 10 - 66 - 20 - - - - Preset - - - - - - 300 - 260 - 97 - 36 - - - - OK - - - - - - 190 - 260 - 97 - 36 - - - - Cancel - - - - - - 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 -#include -#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;icbEncoding->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;icbAudioDrv->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;icbBufSize->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;icbBufCnt->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;icbFormat->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;icbFrequency->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;icbBSMode->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;ilwSoundfont->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;ilwSoundfont->addItem(new QListWidgetItem(sl.at(i))); - } -} - -void qmpSettingsWindow::on_pbRemove_clicked() -{ - QList sl=ui->lwSoundfont->selectedItems(); - for(int i=0;ilwSoundfont->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 -#include -#include -#include - -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 @@ - - - qmpSettingsWindow - - - - 0 - 0 - 494 - 445 - - - - - 494 - 445 - - - - Settings - - - - - - 0 - - - - Midi - - - - - - - - - 0 - 0 - - - - Default Output Device - - - - - - - - 0 - 0 - - - - - Internal FluidSynth - - - - - - - - - - - 0 - 0 - - - - Disable Midi Mapping - - - - - - - - 0 - 0 - - - - Send SysEx - - - - - - - - 0 - 0 - - - - Wait for remaining voices before stopping - - - - - - - - - - 0 - 0 - - - - Text Encoding - - - - - - - - 0 - 0 - - - - - Unicode - - - - - Big5 - - - - - Big5-HKSCS - - - - - CP949 - - - - - EUC-JP - - - - - EUC-KR - - - - - GB18030 - - - - - KOI8-R - - - - - KOI8-U - - - - - Macintosh - - - - - Shift-JIS - - - - - - - - - - - Synth - - - - - - Audio Buffer Count - - - - - - - Audio Buffer Size - - - - - - - true - - - 1 - - - - 64 - - - - - 128 - - - - - 256 - - - - - 512 - - - - - 1024 - - - - - 2048 - - - - - 4096 - - - - - 8192 - - - - - - - - Audio Frequency - - - - - - - true - - - - 2 - - - - - 4 - - - - - 8 - - - - - 16 - - - - - 32 - - - - - 64 - - - - - - - - Audio Driver - - - - - - - - 16bits - - - - - float - - - - - - - - - - - 2 - - - - 22050 - - - - - 44100 - - - - - 48000 - - - - - 96000 - - - - - - - - Audio Format - - - - - - - 1 - - - 65535 - - - 2048 - - - - - - - Max Polyphony - - - - - - - Auto bank select mode - - - - - - - Bank select mode - - - - - - - 1 - - - - Ignored - - - - - CC#0 - - - - - CC#32 - - - - - CC#0*128+CC#32 - - - - - - - - CPU Cores - - - - - - - 1 - - - 256 - - - - - - - - Soundfonts - - - - - - QAbstractItemView::InternalMove - - - - - - - - - - - - - :/img/add.png:/img/add.png - - - - 24 - 24 - - - - - - - - - - - - :/img/remove.png:/img/remove.png - - - - 24 - 24 - - - - - - - - - - - - :/img/up.png:/img/up.png - - - - 24 - 24 - - - - - - - - - - - - :/img/down.png:/img/down.png - - - - 24 - 24 - - - - - - - - - - - Behavior - - - - - - Restore last playlist on startup - - - - - - - Load files in the same folder - - - - - - - Save dialog status - - - - - - - Save parameters in effects window - - - - - - - Persistent fluidsynth instance - - - - - - - - - Visualization Mode - - - - - - - - - - - - - - View distance - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 50 - 20 - - - - - - - - - 60 - 0 - - - - Qt::Horizontal - - - - - - - - - - - - - - Note stretch - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 60 - 20 - - - - - - - - - 60 - 0 - - - - Qt::Horizontal - - - - - - - - - - - - - - Fog Start - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 82 - 20 - - - - - - - - - 60 - 0 - - - - Qt::Horizontal - - - - - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - - buttonBox - accepted() - qmpSettingsWindow - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - qmpSettingsWindow - reject() - - - 316 - 260 - - - 286 - 274 - - - - - 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 @@ - - - ../img/add.png - ../img/list.png - ../img/addfolder.png - ../img/channel.png - ../img/prev.png - ../img/qmidiplyr.png - ../img/remove.png - ../img/clear.png - ../img/down.png - ../img/effects.png - ../img/repeat-all.png - ../img/repeat-base.png - ../img/repeat-non.png - ../img/load.png - ../img/next.png - ../img/repeat-one.png - ../img/save.png - ../img/settings.png - ../img/pause.png - ../img/play.png - ../img/shuffle-off.png - ../img/shuffle.png - ../img/stop.png - ../img/up.png - ../img/visualization.png - ../img/mainw.png - ../img/chanw.png - ../doc/index.html - ../doc/version.html - ../doc/license.html - ../doc/mainwindow.html - ../doc/channeldialog.html - - 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 -#include -#include -#include "qmpcorewrapper.hpp" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - qmlRegisterType("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 @@ - - - main.qml - - 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 -#include -#include -#include -#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 -#include -#include -#include -#include "qmpmidiplay.hpp" -#ifdef _WIN32 -#include -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)*1000000getEvent(0)->time;tceptrgetEventCount();) - { - while(tcpaused)std::this_thread::sleep_for(std::chrono::milliseconds(100)); - while(!tcstop&&midiFile&&tceptrgetEventCount()&&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;eptrgetEventCount();) - { - while(eptrgetEventCount()&&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;eptrgetEventCount();) - { - while(eptrgetEventCount()&&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< -#include -#include -#include -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 -#include -#include -#include -#include -#include -#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->timetime:a->iidiid;} -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;c0)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;cchnklen) - { - 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(;byteread0;--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